2024-12-31 10:58:07 +08:00
|
|
|
|
<route lang="json5">
|
|
|
|
|
|
{
|
|
|
|
|
|
style: {
|
|
|
|
|
|
navigationStyle: 'custom',
|
|
|
|
|
|
disableScroll: true
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
</route>
|
|
|
|
|
|
<template>
|
|
|
|
|
|
<view>
|
|
|
|
|
|
<TopNavigation></TopNavigation>
|
2025-01-03 11:41:37 +08:00
|
|
|
|
<view class="text-6 ml-4 pt-7 custom-color-black font-bold">设置新密码</view>
|
|
|
|
|
|
<view class="text-3.5 ml-4 mt-2 mb-2 custom-color-grey">
|
|
|
|
|
|
<view>已发送验证码至{{ maskedPhone }}</view>
|
|
|
|
|
|
</view>
|
2024-12-31 10:58:07 +08:00
|
|
|
|
<view class="p-5">
|
2025-01-03 11:41:37 +08:00
|
|
|
|
<wd-input
|
|
|
|
|
|
v-model="code"
|
|
|
|
|
|
:maxlength="6"
|
|
|
|
|
|
class="mt-6"
|
|
|
|
|
|
type="number"
|
|
|
|
|
|
placeholder="请输入验证码"
|
|
|
|
|
|
placeholderClass="text-4 custom-color-grey"
|
|
|
|
|
|
size="large"
|
|
|
|
|
|
@change="codeChange"
|
|
|
|
|
|
use-suffix-slot
|
|
|
|
|
|
>
|
|
|
|
|
|
<template #suffix>
|
|
|
|
|
|
<view v-if="countDown > 0" class="text-4 custom-color-grey">
|
|
|
|
|
|
{{ countDown }}s后重新获取
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view v-else class="text-4 custom-color-blue" @click="getCode">重新获取</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
</wd-input>
|
2024-12-31 10:58:07 +08:00
|
|
|
|
<wd-input
|
|
|
|
|
|
v-model="password"
|
|
|
|
|
|
:maxlength="20"
|
|
|
|
|
|
class="mt-6"
|
|
|
|
|
|
clearable
|
|
|
|
|
|
placeholder="请输入新密码"
|
|
|
|
|
|
placeholderClass="text-4 custom-color-grey"
|
|
|
|
|
|
show-password
|
|
|
|
|
|
size="large"
|
|
|
|
|
|
@change="passwordChange"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<wd-input
|
|
|
|
|
|
v-model="confirmPassword"
|
|
|
|
|
|
:maxlength="20"
|
|
|
|
|
|
class="mt-6"
|
|
|
|
|
|
clearable
|
|
|
|
|
|
placeholder="再次输入新密码"
|
|
|
|
|
|
placeholderClass="text-4 custom-color-grey"
|
|
|
|
|
|
show-password
|
|
|
|
|
|
size="large"
|
|
|
|
|
|
@change="confirmPasswordChange"
|
|
|
|
|
|
/>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="bg-[#eeeff4] p-2 mx-5 rounded-2">
|
|
|
|
|
|
<view class="p-2">
|
|
|
|
|
|
<view class="text-3 color-[#525458]">密码为8-20位,至少含数字/字母/字符中的2种</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
<view class="p-5">
|
|
|
|
|
|
<wd-button
|
|
|
|
|
|
:block="true"
|
|
|
|
|
|
:disabled="!(passwordPass && confirmPasswordPass && password === confirmPassword)"
|
|
|
|
|
|
:round="false"
|
|
|
|
|
|
size="large"
|
2025-01-02 19:26:12 +08:00
|
|
|
|
@click="resetPassword"
|
2024-12-31 10:58:07 +08:00
|
|
|
|
>
|
|
|
|
|
|
提交
|
|
|
|
|
|
</wd-button>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</view>
|
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
2025-01-03 11:41:37 +08:00
|
|
|
|
import { codeRegExp, passwordRegExp } from '@/constants/regular-expressions'
|
|
|
|
|
|
import { getCodeApi, resetPasswordApi, UserGetCodeRequest } from '@/service/user'
|
2025-01-02 19:26:12 +08:00
|
|
|
|
import { Result } from '@/constants/result'
|
2025-01-03 11:41:37 +08:00
|
|
|
|
import { AccountChannel, CodeType, IResData } from '@/typings'
|
2025-01-02 19:26:12 +08:00
|
|
|
|
|
|
|
|
|
|
const phone = ref<string>('')
|
|
|
|
|
|
const code = ref<string>('')
|
2024-12-31 10:58:07 +08:00
|
|
|
|
|
|
|
|
|
|
const password = ref<string>('')
|
|
|
|
|
|
const confirmPassword = ref<string>('')
|
2025-01-03 11:41:37 +08:00
|
|
|
|
const countDown = ref<number>(60)
|
2024-12-31 10:58:07 +08:00
|
|
|
|
|
2025-01-03 11:41:37 +08:00
|
|
|
|
const maskedPhone = computed(() => {
|
|
|
|
|
|
if (phone.value.length === 11) {
|
|
|
|
|
|
return phone.value.slice(0, 3) + '****' + phone.value.slice(7)
|
|
|
|
|
|
}
|
|
|
|
|
|
return phone.value
|
|
|
|
|
|
})
|
|
|
|
|
|
const codePass = computed(() => codeRegExp.test(code.value))
|
2024-12-31 10:58:07 +08:00
|
|
|
|
const passwordPass = computed(() => passwordRegExp.test(password.value))
|
|
|
|
|
|
const confirmPasswordPass = computed(() => password.value === confirmPassword.value)
|
|
|
|
|
|
|
2025-01-02 19:26:12 +08:00
|
|
|
|
onLoad(options => {
|
|
|
|
|
|
phone.value = options.phone
|
2025-01-03 11:41:37 +08:00
|
|
|
|
startCounting()
|
2025-01-02 19:26:12 +08:00
|
|
|
|
})
|
|
|
|
|
|
|
2025-01-03 11:41:37 +08:00
|
|
|
|
const getCode = async () => {
|
|
|
|
|
|
await uni.showLoading({
|
|
|
|
|
|
title: '加载中',
|
|
|
|
|
|
mask: true
|
|
|
|
|
|
})
|
|
|
|
|
|
try {
|
|
|
|
|
|
const result: IResData = await getCodeApi<UserGetCodeRequest>({
|
|
|
|
|
|
account: phone.value,
|
|
|
|
|
|
channel: AccountChannel.phone,
|
|
|
|
|
|
codeType: CodeType.reset
|
|
|
|
|
|
})
|
|
|
|
|
|
uni.hideLoading()
|
|
|
|
|
|
if (result.errorCode === Result.Success.code) {
|
|
|
|
|
|
await uni.showToast({
|
|
|
|
|
|
title: '验证码已发送',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
} else {
|
|
|
|
|
|
await uni.showToast({
|
|
|
|
|
|
title: result.errorMsg,
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
console.log(err)
|
|
|
|
|
|
uni.hideLoading()
|
|
|
|
|
|
await uni.showToast({
|
|
|
|
|
|
title: '获取验证码失败,请稍后再试',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const startCounting = () => {
|
|
|
|
|
|
const timestamp: number = new Date().getTime()
|
|
|
|
|
|
countDown.value = 60
|
|
|
|
|
|
const countDownTimer = setInterval(() => {
|
|
|
|
|
|
if (countDown.value > 0) {
|
|
|
|
|
|
countDown.value = 60 - Math.floor((new Date().getTime() - timestamp) / 1000)
|
|
|
|
|
|
} else {
|
|
|
|
|
|
clearInterval(countDownTimer)
|
|
|
|
|
|
}
|
|
|
|
|
|
}, 1000)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2025-01-02 19:26:12 +08:00
|
|
|
|
const resetPassword = async () => {
|
2025-01-03 11:41:37 +08:00
|
|
|
|
if (code.value === '') {
|
|
|
|
|
|
await uni.showToast({
|
|
|
|
|
|
title: '验证码不能为空',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
} else if (!codePass.value) {
|
|
|
|
|
|
await uni.showToast({
|
|
|
|
|
|
title: '验证码格式不正确',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
} else if (password.value === '' || confirmPassword.value === '') {
|
|
|
|
|
|
await uni.showToast({
|
2025-01-02 19:26:12 +08:00
|
|
|
|
title: '密码不能为空',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
} else if (!passwordPass.value || !confirmPasswordPass.value) {
|
2025-01-03 11:41:37 +08:00
|
|
|
|
await uni.showToast({
|
2025-01-02 19:26:12 +08:00
|
|
|
|
title: '密码格式不正确',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
2025-01-03 11:41:37 +08:00
|
|
|
|
} else if (password.value !== confirmPassword.value) {
|
|
|
|
|
|
await uni.showToast({
|
2025-01-02 19:26:12 +08:00
|
|
|
|
title: '两次密码不一致',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
return
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
await uni.showLoading({
|
|
|
|
|
|
title: '修改中'
|
|
|
|
|
|
})
|
|
|
|
|
|
try {
|
|
|
|
|
|
const resetPasswordApiResult = await resetPasswordApi({
|
|
|
|
|
|
newPassword: password.value,
|
|
|
|
|
|
account: phone.value,
|
|
|
|
|
|
verificationCode: code.value
|
|
|
|
|
|
})
|
|
|
|
|
|
uni.hideLoading()
|
|
|
|
|
|
if (resetPasswordApiResult.errorCode === Result.Success.code) {
|
|
|
|
|
|
await uni.navigateBack({ delta: 2 })
|
|
|
|
|
|
await uni.showToast({
|
|
|
|
|
|
title: '密码重置成功',
|
2025-01-03 11:41:37 +08:00
|
|
|
|
icon: 'none'
|
2025-01-02 19:26:12 +08:00
|
|
|
|
})
|
|
|
|
|
|
} else {
|
|
|
|
|
|
await uni.showToast({
|
|
|
|
|
|
title: resetPasswordApiResult.errorMsg,
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
} catch (err) {
|
|
|
|
|
|
console.log(err)
|
|
|
|
|
|
uni.hideLoading()
|
|
|
|
|
|
await uni.showToast({
|
|
|
|
|
|
title: '密码重置失败,请稍后再试',
|
|
|
|
|
|
icon: 'none'
|
|
|
|
|
|
})
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2024-12-31 10:58:07 +08:00
|
|
|
|
const passwordChange = (value: string) => {
|
|
|
|
|
|
password.value = value
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const confirmPasswordChange = (value: string) => {
|
|
|
|
|
|
confirmPassword.value = value
|
|
|
|
|
|
}
|
2025-01-03 11:41:37 +08:00
|
|
|
|
|
|
|
|
|
|
const codeChange = (value: string) => {
|
|
|
|
|
|
code.value = value
|
|
|
|
|
|
}
|
2024-12-31 10:58:07 +08:00
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
|
|
<style scoped lang="scss"></style>
|