Dining_Hall/pages/mine/me/phoneCode.vue

324 lines
6.8 KiB
Vue

<template>
<view class="container">
<!-- 顶部导航栏 -->
<!-- <view class="header">-->
<!-- <view class="back-icon" @click="goBack">-->
<!-- <image class="icon" :src="require('@/static/images/icons/back.png')" mode="aspectFit"></image>-->
<!-- </view>-->
<!-- </view>-->
<!-- 主要内容区域 -->
<view class="content">
<view class="title-section">
<text class="title">输入6位验证码</text>
<text class="subtitle">验证码已发至 {{ formatPhone(phone) }}</text>
</view>
<!-- 验证码输入框 -->
<view class="code-input-wrapper">
<input
v-for="(digit, index) in 6"
:key="index"
:ref="`codeInput${index}`"
v-model="verificationCode[index]"
type="number"
maxlength="1"
class="code-input"
:class="{ active: currentFocus === index }"
@input="handleInput($event, index)"
@focus="currentFocus = index"
/>
</view>
<!-- 重新获取验证码 -->
<view class="resend-wrapper" v-if="!showSuccessModal">
<text v-if="resendCountdown > 0" class="countdown">重新获取 {{ resendCountdown }}s</text>
<text v-else class="resend-btn" @click="handleResendCode">重新获取</text>
</view>
<!-- 完成按钮 -->
<button
class="submit-btn"
:disabled="!isComplete"
@click="handleSubmit"
>
完成
</button>
</view>
<!-- 成功弹窗 -->
<view class="modal" v-if="showSuccessModal">
<view class="modal-content">
<view class="success-icon">
<image class="icon" :src="require('@/static/images/my/success.png')" mode="aspectFit"></image>
</view>
<text class="success-title">手机号更新成功</text>
<text class="success-subtitle">{{ redirectCountdown }}秒后自动返回界面</text>
<text class="relogin-btn" @click="handleRelogin">重新登录</text>
</view>
</view>
</view>
</template>
<script>
export default {
data() {
return {
phone: '',
verificationCode: ['', '', '', '', '', ''],
currentFocus: 0,
resendCountdown: 68,
redirectCountdown: 5,
resendTimer: null,
redirectTimer: null,
showSuccessModal: false
}
},
computed: {
isComplete() {
return this.verificationCode.every(digit => digit !== '')
}
},
onLoad(options) {
this.phone = options.phone || ''
this.startResendCountdown()
},
onUnload() {
this.clearTimers()
},
methods: {
formatPhone(phone) {
if (!phone) return ''
return phone.replace(/(\d{3})(\d{4})(\d{4})/, '$1 $2 $3')
},
goBack() {
uni.navigateBack()
},
handleInput(event, index) {
const value = event.detail.value
// Ensure the input is a single digit
this.verificationCode[index] = value.slice(0, 1)
// Move to next input if a digit was entered and it's not the last input
if (value && index < 5) {
this.$nextTick(() => {
// Focus the next input
const nextInput = this.$refs[`codeInput${index + 1}`][0]
if (nextInput && typeof nextInput.focus === 'function') {
nextInput.focus()
}
})
}
},
startResendCountdown() {
this.clearTimers()
this.resendTimer = setInterval(() => {
if (this.resendCountdown > 0) {
this.resendCountdown--
} else {
clearInterval(this.resendTimer)
this.resendTimer = null
}
}, 1000)
},
startRedirectCountdown() {
this.redirectTimer = setInterval(() => {
if (this.redirectCountdown > 0) {
this.redirectCountdown--
} else {
clearInterval(this.redirectTimer)
this.redirectTimer = null
this.handleRelogin()
}
}, 1000)
},
clearTimers() {
if (this.resendTimer) {
clearInterval(this.resendTimer)
this.resendTimer = null
}
if (this.redirectTimer) {
clearInterval(this.redirectTimer)
this.redirectTimer = null
}
},
handleResendCode() {
if (this.resendCountdown > 0) return
this.resendCountdown = 68
this.startResendCountdown()
// 这里添加重新发送验证码的逻辑
},
handleSubmit() {
if (!this.isComplete) return
// 显示成功弹窗并开始重定向倒计时
this.showSuccessModal = true
this.redirectCountdown = 5
this.startRedirectCountdown()
},
handleRelogin() {
// 这里添加重新登录的逻辑
uni.reLaunch({
url: '/pages/login'
})
}
}
}
</script>
<style lang="scss">
.container {
min-height: 100vh;
background-color: #fff;
}
.header {
padding: 44px 32rpx 0;
height: 88rpx;
display: flex;
align-items: center;
.back-icon {
padding: 20rpx;
margin-left: -20rpx;
.icon {
width: 40rpx;
height: 40rpx;
}
}
}
.content {
padding: 32rpx;
}
.title-section {
margin-bottom: 48rpx;
.title {
font-size: 40rpx;
font-weight: 500;
color: #333;
margin-bottom: 16rpx;
display: block;
}
.subtitle {
font-size: 28rpx;
color: #999;
}
}
.code-input-wrapper {
display: flex;
justify-content: space-between;
margin-bottom: 32rpx;
.code-input {
width: 80rpx;
height: 80rpx;
background: #F5F5F5;
border-radius: 16rpx;
text-align: center;
font-size: 40rpx;
color: #333;
&.active {
background: #fff;
border: 2rpx solid #FF8126;
}
}
}
.resend-wrapper {
text-align: center;
margin-bottom: 48rpx;
.countdown {
font-size: 28rpx;
color: #999;
}
.resend-btn {
font-size: 28rpx;
color: #FF8126;
}
}
.submit-btn {
width: 100%;
height: 88rpx;
background: #FF8126;
color: #fff;
font-size: 32rpx;
font-weight: 500;
border-radius: 44rpx;
display: flex;
align-items: center;
justify-content: center;
border: none;
&:disabled {
opacity: 0.5;
}
&:active {
opacity: 0.9;
}
}
.modal {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.5);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
.modal-content {
width: 560rpx;
background: #fff;
border-radius: 24rpx;
padding: 48rpx;
display: flex;
flex-direction: column;
align-items: center;
.success-icon {
width: 120rpx;
height: 120rpx;
margin-bottom: 32rpx;
.icon {
width: 100%;
height: 100%;
}
}
.success-title {
font-size: 32rpx;
font-weight: 500;
color: #333;
margin-bottom: 16rpx;
}
.success-subtitle {
font-size: 28rpx;
color: #999;
margin-bottom: 32rpx;
}
.relogin-btn {
font-size: 28rpx;
color: #FF8126;
}
}
}
</style>