Files
integral-shop/single_uniapp22miao/pages/sub-pages/login/reset-account.vue

297 lines
6.3 KiB
Vue
Raw Normal View History

<template>
<view class="reset-page">
<view class="header">
<view class="title">重置密码</view>
<view class="subtitle">请输入您的手机号我们将发送验证码</view>
</view>
<view class="form-container">
<!-- 手机号 -->
<view class="form-item">
<input
v-model="formData.mobile"
type="number"
maxlength="11"
placeholder="请输入手机号"
class="form-input"
/>
</view>
<!-- 验证码 -->
<view class="form-item">
<view class="code-wrapper">
<input
v-model="formData.code"
type="number"
maxlength="6"
placeholder="请输入验证码"
class="form-input"
/>
<button
class="code-btn"
:disabled="countdown > 0"
@click="sendCode"
>
{{ countdown > 0 ? `${countdown}s` : '获取验证码' }}
</button>
</view>
</view>
<!-- 新密码 -->
<view class="form-item">
<input
v-model="formData.password"
:password="!showPassword"
placeholder="请输入新密码6-20位"
class="form-input"
/>
<view class="eye-icon" @click="togglePassword">
<text>{{ showPassword ? '👁️' : '👁️‍🗨️' }}</text>
</view>
</view>
<!-- 确认密码 -->
<view class="form-item">
<input
v-model="formData.confirmPassword"
:password="!showConfirmPassword"
placeholder="请再次输入新密码"
class="form-input"
/>
<view class="eye-icon" @click="toggleConfirmPassword">
<text>{{ showConfirmPassword ? '👁️' : '👁️‍🗨️' }}</text>
</view>
</view>
<!-- 提交按钮 -->
<button
class="submit-btn"
:disabled="!canSubmit"
:loading="submitting"
@click="handleSubmit"
>
确定
</button>
</view>
</view>
</template>
<script>
import { resetPassword, sendSms } from '@/api/miao.js';
export default {
data() {
return {
formData: {
mobile: '',
code: '',
password: '',
confirmPassword: ''
},
showPassword: false,
showConfirmPassword: false,
countdown: 0,
submitting: false,
timer: null
}
},
computed: {
canSubmit() {
return this.formData.mobile.length === 11 &&
this.formData.code.length === 6 &&
this.formData.password.length >= 6 &&
this.formData.confirmPassword === this.formData.password;
}
},
onUnload() {
if (this.timer) {
clearInterval(this.timer);
}
},
methods: {
togglePassword() {
this.showPassword = !this.showPassword;
},
toggleConfirmPassword() {
this.showConfirmPassword = !this.showConfirmPassword;
},
// 发送验证码
async sendCode() {
if (!/^1[3-9]\d{9}$/.test(this.formData.mobile)) {
uni.showToast({
title: '请输入正确的手机号',
icon: 'none'
});
return;
}
try {
const res = await sendSms({
mobile: this.formData.mobile,
event: 'resetpwd'
});
if (res.code === 0) {
uni.showToast({
title: '验证码已发送',
icon: 'success'
});
this.countdown = 60;
this.timer = setInterval(() => {
this.countdown--;
if (this.countdown <= 0) {
clearInterval(this.timer);
}
}, 1000);
}
} catch (error) {
uni.showToast({
title: error.msg || '发送失败',
icon: 'none'
});
}
},
// 提交
async handleSubmit() {
if (this.formData.password !== this.formData.confirmPassword) {
uni.showToast({
title: '两次密码不一致',
icon: 'none'
});
return;
}
this.submitting = true;
try {
const res = await resetPassword({
mobile: this.formData.mobile,
code: this.formData.code,
password: this.formData.password
});
if (res.code === 0) {
uni.showToast({
title: '密码重置成功',
icon: 'success'
});
setTimeout(() => {
uni.navigateBack();
}, 1500);
}
} catch (error) {
uni.showToast({
title: error.msg || '重置失败',
icon: 'none'
});
} finally {
this.submitting = false;
}
}
}
}
</script>
<style lang="scss" scoped>
.reset-page {
min-height: 100vh;
background-color: #f5f5f5;
padding: 40rpx 30rpx;
}
.header {
margin-bottom: 60rpx;
.title {
font-size: 48rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
}
.subtitle {
font-size: 26rpx;
color: #666;
}
}
.form-container {
background-color: #fff;
border-radius: 20rpx;
padding: 40rpx 30rpx;
.form-item {
position: relative;
margin-bottom: 30rpx;
.form-input {
width: 100%;
height: 90rpx;
padding: 0 20rpx;
background-color: #f5f5f5;
border-radius: 45rpx;
font-size: 28rpx;
}
.code-wrapper {
display: flex;
align-items: center;
.form-input {
flex: 1;
margin-right: 15rpx;
}
.code-btn {
width: 180rpx;
height: 90rpx;
line-height: 90rpx;
background-color: #FF4757;
color: #fff;
border-radius: 45rpx;
font-size: 24rpx;
border: none;
&[disabled] {
background-color: #ccc;
}
}
}
.eye-icon {
position: absolute;
right: 30rpx;
top: 50%;
transform: translateY(-50%);
font-size: 32rpx;
}
}
.submit-btn {
width: 100%;
height: 90rpx;
line-height: 90rpx;
background: linear-gradient(90deg, #FF6B6B, #FF4757);
color: #fff;
border-radius: 45rpx;
font-size: 32rpx;
font-weight: bold;
border: none;
margin-top: 40rpx;
&[disabled] {
opacity: 0.6;
}
}
}
</style>