Эх сурвалжийг харах

feat: 忘记密码接口调试

liangan 3 долоо хоног өмнө
parent
commit
d918df660b

+ 5 - 3
src/api/login.ts

@@ -2,10 +2,11 @@ import { http } from '@/utils/http'
 
 
 /**
 /**
  * 获取验证码
  * 获取验证码
+ * @param phone 手机号
  * @returns ICaptcha 验证码
  * @returns ICaptcha 验证码
  */
  */
-export function getCode() {
-  return http.get<any>('/user/getCode')
+export function getCode(phoneNo?: string) {
+  return http.get<any>('/cif/api/user/getCode', { phoneNo })
 }
 }
 
 
 /**
 /**
@@ -46,9 +47,10 @@ export function updateInfo(data: any) {
 
 
 /**
 /**
  * 修改用户密码
  * 修改用户密码
+ *  入参{newPwd:string,verifyCode:string}
  */
  */
 export function updateUserPassword(data: any) {
 export function updateUserPassword(data: any) {
-  return http.post('/user/updatePassword', data)
+  return http.get('/cif/api/user/resetPwdByCode', data)
 }
 }
 
 
 /**
 /**

+ 142 - 104
src/pages/forgotPassword/forgotPassword.vue

@@ -8,9 +8,9 @@
 </route>
 </route>
 
 
 <script lang="ts" setup>
 <script lang="ts" setup>
-// 必须导入需要用到的页面生命周期(即使在当前页面上没有直接使用到)
-// eslint-disable-next-line unused-imports/no-unused-imports
-import { onPageScroll, onReachBottom } from '@dcloudio/uni-app'
+import { getCode, updateUserPassword } from '@/api/login'
+import { goBack as goBackUtil, toPage } from '@/utils/page'
+import { toast } from '@/utils/toast'
 
 
 defineOptions({
 defineOptions({
   name: 'ForgotPassword', // 忘记密码
   name: 'ForgotPassword', // 忘记密码
@@ -25,121 +25,159 @@ const step = ref(1)
 
 
 // 表单数据
 // 表单数据
 const formData = ref({
 const formData = ref({
-  mobile: '',
-  verificationCode: '',
-  newPassword: '',
-  confirmPassword: '',
+  phone: '',
+  verifyCode: '',
+  newPwd: '',
+  confirmPwd: '',
 })
 })
 
 
 // 验证码倒计时
 // 验证码倒计时
 const countdown = ref(0)
 const countdown = ref(0)
-const countdownTimer = ref<NodeJS.Timeout | null>(null)
-
-// 表单验证规则
-const rules = {
-  mobile: [
-    { required: true, message: 'Please enter mobile number' },
-    { pattern: /^1[3-9]\d{9}$/, message: 'Please enter valid mobile number' },
-  ],
-  verificationCode: [
-    { required: true, message: 'Please enter verification code' },
-  ],
-  newPassword: [
-    { required: true, message: 'Please enter new password' },
-    { min: 6, max: 20, message: 'Password should be 6-20 characters' },
-  ],
-  confirmPassword: [
-    { required: true, message: 'Please confirm password' },
-    {
-      validator: (value: string) => {
-        return value === formData.value.newPassword
-      },
-      message: 'Passwords do not match',
-    },
-  ],
-}
+const countdownTimer = ref<any>(null)
 
 
 // 获取验证码
 // 获取验证码
-function getVerificationCode() {
-  if (!formData.value.mobile) {
-    uni.showToast({
-      title: 'Please enter mobile number first',
-      icon: 'none',
-    })
+async function getVerificationCode() {
+  // 验证手机号
+  if (!formData.value.phone.trim()) {
+    toast.error('Please enter phone number first')
     return
     return
   }
   }
 
 
-  // TODO: 实现获取验证码逻辑
-  console.log('Get verification code for:', formData.value.mobile)
+  // 验证手机号格式
+  const phoneRegex = /^1[3-9]\d{9}$/
+  if (!phoneRegex.test(formData.value.phone)) {
+    toast.error('Please enter valid phone number')
+    return
+  }
 
 
-  // 开始倒计时
-  countdown.value = 60
-  countdownTimer.value = setInterval(() => {
-    countdown.value--
-    if (countdown.value <= 0) {
-      clearInterval(countdownTimer.value!)
-      countdownTimer.value = null
-    }
-  }, 1000)
+  // 防止重复点击
+  if (countdown.value > 0) {
+    return
+  }
+
+  try {
+    // 显示加载状态
+    uni.showLoading({
+      title: 'Sending...',
+      mask: true,
+    })
+
+    // 调用获取验证码接口
+    await getCode(formData.value.phone)
+
+    uni.hideLoading()
+    toast.success('Verification code sent successfully')
+
+    // 开始倒计时
+    countdown.value = 60
+    countdownTimer.value = setInterval(() => {
+      countdown.value--
+      if (countdown.value <= 0) {
+        clearInterval(countdownTimer.value!)
+        countdownTimer.value = null
+      }
+    }, 1000)
+  }
+  catch (error) {
+    uni.hideLoading()
+    toast.error(error.message || 'Failed to send verification code')
+  }
 }
 }
 
 
 // 第一步:验证手机号
 // 第一步:验证手机号
 function handleStep1() {
 function handleStep1() {
-  if (!formData.value.mobile) {
-    uni.showToast({
-      title: 'Please enter mobile number',
-      icon: 'none',
-    })
+  // 验证手机号
+  if (!formData.value.phone.trim()) {
+    toast.error('Please enter phone number')
     return
     return
   }
   }
 
 
-  // TODO: 验证手机号逻辑
-  console.log('Verify mobile:', formData.value.mobile)
+  // 验证手机号格式
+  const phoneRegex = /^1[3-9]\d{9}$/
+  if (!phoneRegex.test(formData.value.phone)) {
+    toast.error('Please enter valid phone number')
+    return
+  }
 
 
   // 跳转到第二步
   // 跳转到第二步
   step.value = 2
   step.value = 2
-  // 预填手机号
-  formData.value.mobile = '88016266123'
 }
 }
 
 
 // 第二步:重置密码
 // 第二步:重置密码
-function handleResetPassword() {
-  if (!formData.value.verificationCode || !formData.value.newPassword || !formData.value.confirmPassword) {
-    uni.showToast({
-      title: 'Please fill in all fields',
-      icon: 'none',
+async function handleResetPassword() {
+  try {
+    // 表单验证
+    const isValid = await validateResetForm()
+    if (!isValid)
+      return
+
+    // 显示加载状态
+    uni.showLoading({
+      title: 'Resetting password...',
+      mask: true,
     })
     })
-    return
-  }
 
 
-  if (formData.value.newPassword !== formData.value.confirmPassword) {
-    uni.showToast({
-      title: 'Passwords do not match',
-      icon: 'none',
-    })
-    return
-  }
+    // 调用重置密码接口
+    const resetData = {
+      newPwd: formData.value.newPwd,
+      verifyCode: formData.value.verifyCode,
+    }
 
 
-  // TODO: 实现重置密码逻辑
-  console.log('Reset password:', formData.value)
+    await updateUserPassword(resetData)
 
 
-  uni.showToast({
-    title: 'Password reset successfully',
-    icon: 'success',
-  })
+    uni.hideLoading()
+    toast.success('Password reset successfully')
 
 
-  // 跳转到登录页
-  setTimeout(() => {
-    uni.redirectTo({
-      url: '/pages/login/login',
-    })
-  }, 1500)
+    // 跳转到登录页
+    setTimeout(() => {
+      toPage('/pages/login/login', {}, true)
+    }, 1500)
+  }
+  catch (error) {
+    uni.hideLoading()
+    toast.error(error.message || 'Failed to reset password')
+  }
 }
 }
 
 
-// 跳转登录页
-function toLogin() {
-  uni.navigateTo({
-    url: '/pages/login/login',
+// 重置密码表单验证
+function validateResetForm() {
+  return new Promise((resolve) => {
+    // 验证验证码
+    if (!formData.value.verifyCode.trim()) {
+      toast.error('Please enter verification code')
+      resolve(false)
+      return
+    }
+
+    // 验证新密码
+    if (!formData.value.newPwd.trim()) {
+      toast.error('Please enter new password')
+      resolve(false)
+      return
+    }
+
+    // 验证密码长度
+    if (formData.value.newPwd.length < 6 || formData.value.newPwd.length > 20) {
+      toast.error('Password should be 6-20 characters')
+      resolve(false)
+      return
+    }
+
+    // 验证确认密码
+    if (!formData.value.confirmPwd.trim()) {
+      toast.error('Please confirm your password')
+      resolve(false)
+      return
+    }
+
+    // 验证两次密码是否一致
+    if (formData.value.newPwd !== formData.value.confirmPwd) {
+      toast.error('Passwords do not match')
+      resolve(false)
+      return
+    }
+
+    resolve(true)
   })
   })
 }
 }
 
 
@@ -149,7 +187,7 @@ function goBack() {
     step.value = 1
     step.value = 1
   }
   }
   else {
   else {
-    uni.navigateBack()
+    goBackUtil()
   }
   }
 }
 }
 
 
@@ -186,11 +224,11 @@ onUnmounted(() => {
 
 
       <!-- 第一步:输入手机号 -->
       <!-- 第一步:输入手机号 -->
       <view v-if="step === 1">
       <view v-if="step === 1">
-        <wd-form ref="form" :model="formData" :rules="rules">
+        <wd-form ref="form" :model="formData">
           <view class="mb-60rpx">
           <view class="mb-60rpx">
             <wd-input
             <wd-input
-              v-model="formData.mobile"
-              prop="mobile"
+              v-model="formData.phone"
+              prop="phone"
               placeholder="+88 Mobile number"
               placeholder="+88 Mobile number"
               no-border
               no-border
               custom-class="bandhu-auth-input-field"
               custom-class="bandhu-auth-input-field"
@@ -211,19 +249,19 @@ onUnmounted(() => {
 
 
       <!-- 第二步:重置密码 -->
       <!-- 第二步:重置密码 -->
       <view v-else>
       <view v-else>
-        <wd-form ref="form" :model="formData" :rules="rules">
+        <wd-form ref="form" :model="formData">
           <view class="mb-40rpx space-y-32rpx">
           <view class="mb-40rpx space-y-32rpx">
             <wd-input
             <wd-input
-              v-model="formData.mobile"
-              prop="mobile"
-
-              no-border disabled
+              v-model="formData.phone"
+              prop="phone"
+              no-border
+              readonly
               custom-class="bandhu-auth-input-field"
               custom-class="bandhu-auth-input-field"
             />
             />
             <view class="flex items-center gap-20rpx">
             <view class="flex items-center gap-20rpx">
               <wd-input
               <wd-input
-                v-model="formData.verificationCode"
-                prop="verificationCode"
+                v-model="formData.verifyCode"
+                prop="verifyCode"
                 placeholder="Verification Code"
                 placeholder="Verification Code"
                 no-border
                 no-border
                 custom-class="flex-1 bandhu-auth-input-field"
                 custom-class="flex-1 bandhu-auth-input-field"
@@ -239,16 +277,16 @@ onUnmounted(() => {
               </wd-button>
               </wd-button>
             </view>
             </view>
             <wd-input
             <wd-input
-              v-model="formData.newPassword"
-              prop="newPassword"
+              v-model="formData.newPwd"
+              prop="newPwd"
 
 
               placeholder="New Password 6-20 characters"
               placeholder="New Password 6-20 characters"
               no-border show-password
               no-border show-password
               custom-class="bandhu-auth-input-field"
               custom-class="bandhu-auth-input-field"
             />
             />
             <wd-input
             <wd-input
-              v-model="formData.confirmPassword"
-              prop="confirmPassword"
+              v-model="formData.confirmPwd"
+              prop="confirmPwd"
               show-password
               show-password
               placeholder="Confirm password"
               placeholder="Confirm password"
               no-border
               no-border
@@ -278,7 +316,7 @@ onUnmounted(() => {
         <text class="text-28rpx text-#666">
         <text class="text-28rpx text-#666">
           Already have account?
           Already have account?
         </text>
         </text>
-        <text class="text-28rpx text-[var(--wot-color-theme)]" @click="toLogin">
+        <text class="text-28rpx text-[var(--wot-color-theme)]" @click="toPage('/pages/login/login')">
           Login Now
           Login Now
         </text>
         </text>
       </view>
       </view>

+ 60 - 45
src/pages/register/register.vue

@@ -8,7 +8,8 @@
 </route>
 </route>
 
 
 <script lang="ts" setup>
 <script lang="ts" setup>
-import { register } from '@/api/login'
+import { getCode, register } from '@/api/login'
+import { goBack, toPage } from '@/utils/page'
 import { toast } from '@/utils/toast'
 import { toast } from '@/utils/toast'
 
 
 defineOptions({
 defineOptions({
@@ -23,7 +24,7 @@ const safeAreaInsets = systemInfo.safeAreaInsets
 const formData = ref({
 const formData = ref({
   name: '',
   name: '',
   phone: '',
   phone: '',
-  verificationCode: '',
+  verifyCode: '',
   pwd: '',
   pwd: '',
   code: '',
   code: '',
 })
 })
@@ -33,27 +34,52 @@ const countdown = ref(0)
 const countdownTimer = ref<any>(null)
 const countdownTimer = ref<any>(null)
 
 
 // 获取验证码
 // 获取验证码
-function getVerificationCode() {
-  if (!formData.value.phone) {
-    uni.showToast({
-      title: 'Please enter phone number first',
-      icon: 'none',
-    })
+async function getVerificationCode() {
+  // 验证手机号
+  if (!formData.value.phone.trim()) {
+    toast.error('Please enter phone number first')
     return
     return
   }
   }
 
 
-  // TODO: 实现获取验证码逻辑
-  console.log('Get verification code for:', formData.value.phone)
+  // 验证手机号格式
+  const phoneRegex = /^1[3-9]\d{9}$/
+  if (!phoneRegex.test(formData.value.phone)) {
+    toast.error('Please enter valid phone number')
+    return
+  }
 
 
-  // 开始倒计时
-  countdown.value = 60
-  countdownTimer.value = setInterval(() => {
-    countdown.value--
-    if (countdown.value <= 0) {
-      clearInterval(countdownTimer.value!)
-      countdownTimer.value = null
-    }
-  }, 1000)
+  // 防止重复点击
+  if (countdown.value > 0) {
+    return
+  }
+
+  try {
+    // 显示加载状态
+    uni.showLoading({
+      title: 'Sending...',
+      mask: true,
+    })
+
+    // 调用获取验证码接口
+    await getCode(formData.value.phone)
+
+    uni.hideLoading()
+    toast.success('Verification code sent successfully')
+
+    // 开始倒计时
+    countdown.value = 60
+    countdownTimer.value = setInterval(() => {
+      countdown.value--
+      if (countdown.value <= 0) {
+        clearInterval(countdownTimer.value!)
+        countdownTimer.value = null
+      }
+    }, 1000)
+  }
+  catch (error) {
+    uni.hideLoading()
+    toast.error(error.message || 'Failed to send verification code')
+  }
 }
 }
 
 
 // 注册处理
 // 注册处理
@@ -74,7 +100,7 @@ async function handleRegister() {
     const registerData = {
     const registerData = {
       name: formData.value.name,
       name: formData.value.name,
       phone: formData.value.phone,
       phone: formData.value.phone,
-      verificationCode: formData.value.verificationCode,
+      verifyCode: formData.value.verifyCode,
       pwd: formData.value.pwd,
       pwd: formData.value.pwd,
       code: formData.value.code,
       code: formData.value.code,
     }
     }
@@ -83,9 +109,9 @@ async function handleRegister() {
 
 
     uni.hideLoading()
     uni.hideLoading()
     // 注册成功
     // 注册成功
-    toast.info('Registration successful!')
+    toast.success('Registration successful!')
     setTimeout(() => {
     setTimeout(() => {
-      uni.navigateTo({ url: '/pages/login/login' })
+      toPage('/pages/login/login', {}, true)
     }, 1500)
     }, 1500)
   }
   }
   catch (error) {
   catch (error) {
@@ -99,39 +125,40 @@ function validateForm() {
   return new Promise((resolve) => {
   return new Promise((resolve) => {
     // 验证必填字段
     // 验证必填字段
     if (!formData.value.name.trim()) {
     if (!formData.value.name.trim()) {
-      toast.info('Please enter name')
+      toast.error('Please enter name')
       resolve(false)
       resolve(false)
       return
       return
     }
     }
 
 
     if (!formData.value.phone.trim()) {
     if (!formData.value.phone.trim()) {
-      toast.info('Please enter phone number')
+      toast.error('Please enter phone number')
       resolve(false)
       resolve(false)
       return
       return
     }
     }
 
 
     // 验证手机号格式
     // 验证手机号格式
-    if (!formData.value.phone.trim()) {
-      toast.info('Please enter valid phone number')
+    const phoneRegex = /^1[3-9]\d{9}$/
+    if (!phoneRegex.test(formData.value.phone)) {
+      toast.error('Please enter valid phone number')
       resolve(false)
       resolve(false)
       return
       return
     }
     }
 
 
-    if (!formData.value.verificationCode.trim()) {
-      toast.info('Please enter verification code')
+    if (!formData.value.verifyCode.trim()) {
+      toast.error('Please enter verification code')
       resolve(false)
       resolve(false)
       return
       return
     }
     }
 
 
     if (!formData.value.pwd.trim()) {
     if (!formData.value.pwd.trim()) {
-      toast.info('Please enter password')
+      toast.error('Please enter password')
       resolve(false)
       resolve(false)
       return
       return
     }
     }
 
 
     // 验证密码长度
     // 验证密码长度
     if (formData.value.pwd.length < 6 || formData.value.pwd.length > 20) {
     if (formData.value.pwd.length < 6 || formData.value.pwd.length > 20) {
-      toast.info('Password should be 6-20 characters')
+      toast.error('Password should be 6-20 characters')
       resolve(false)
       resolve(false)
       return
       return
     }
     }
@@ -140,18 +167,6 @@ function validateForm() {
   })
   })
 }
 }
 
 
-// 跳转登录页
-function toLogin() {
-  uni.navigateTo({
-    url: '/pages/login/login',
-  })
-}
-
-// 返回上一页
-function goBack() {
-  uni.navigateBack()
-}
-
 // 页面卸载时清理定时器
 // 页面卸载时清理定时器
 onUnmounted(() => {
 onUnmounted(() => {
   if (countdownTimer.value) {
   if (countdownTimer.value) {
@@ -202,8 +217,8 @@ onUnmounted(() => {
           />
           />
           <view class="flex items-center gap-20rpx">
           <view class="flex items-center gap-20rpx">
             <wd-input
             <wd-input
-              v-model="formData.verificationCode"
-              prop="verificationCode"
+              v-model="formData.verifyCode"
+              prop="verifyCode"
               placeholder="Verification Code"
               placeholder="Verification Code"
               no-border
               no-border
               custom-class="flex-1 bandhu-auth-input-field"
               custom-class="flex-1 bandhu-auth-input-field"
@@ -250,7 +265,7 @@ onUnmounted(() => {
         <text class="text-28rpx text-#666">
         <text class="text-28rpx text-#666">
           Already have account?
           Already have account?
         </text>
         </text>
-        <text class="ml-10rpx text-28rpx text-[var(--wot-color-theme)]" @click="toLogin">
+        <text class="ml-10rpx text-28rpx text-[var(--wot-color-theme)]" @click="toPage('/pages/login/login')">
           Login Now
           Login Now
         </text>
         </text>
       </view>
       </view>