forget-password.vue 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. <template>
  2. <view class="auth-container">
  3. <!-- 顶部 -->
  4. <Header />
  5. <!-- 表单区域 -->
  6. <view class="form-container">
  7. <TenantPicker ref="tenantPickerRef" />
  8. <view class="input-item">
  9. <wd-icon name="phone" size="20px" color="#1890ff" />
  10. <wd-input
  11. v-model="formData.mobile"
  12. placeholder="请输入手机号"
  13. clearable
  14. clear-trigger="focus"
  15. no-border
  16. type="number"
  17. :maxlength="11"
  18. />
  19. </view>
  20. <CodeInput
  21. v-model="formData.code"
  22. :mobile="formData.mobile"
  23. :scene="23"
  24. :before-send="validateBeforeSend"
  25. />
  26. <view class="input-item">
  27. <wd-icon name="lock-on" size="20px" color="#1890ff" />
  28. <wd-input
  29. v-model="formData.password"
  30. placeholder="请输入新密码"
  31. clearable
  32. clear-trigger="focus"
  33. show-password
  34. no-border
  35. />
  36. </view>
  37. <view class="input-item">
  38. <wd-icon name="lock-on" size="20px" color="#1890ff" />
  39. <wd-input
  40. v-model="formData.confirmPassword"
  41. placeholder="请确认新密码"
  42. clearable
  43. clear-trigger="focus"
  44. show-password
  45. no-border
  46. />
  47. </view>
  48. <!-- 重置密码按钮 -->
  49. <wd-button
  50. block
  51. :loading="loading"
  52. type="primary"
  53. @click="handleResetPassword"
  54. >
  55. 重置密码
  56. </wd-button>
  57. <wd-button class="mt-2" block type="info" @click="goToLogin">
  58. 返回登录
  59. </wd-button>
  60. </view>
  61. </view>
  62. </template>
  63. <script lang="ts" setup>
  64. import { reactive, ref } from "vue";
  65. import { useToast } from "wot-design-uni";
  66. import { smsResetPassword } from "@/api/login";
  67. import { LOGIN_PAGE } from "@/router/config";
  68. import { isMobile } from "@/utils/validator";
  69. import CodeInput from "./components/code-input.vue";
  70. import Header from "./components/header.vue";
  71. import TenantPicker from "./components/tenant-picker.vue";
  72. defineOptions({
  73. name: "ForgetPasswordPage",
  74. });
  75. definePage({
  76. style: {
  77. navigationStyle: "custom",
  78. },
  79. excludeLoginPath: true,
  80. });
  81. const toast = useToast();
  82. const loading = ref(false); // 加载状态
  83. const tenantPickerRef = ref<InstanceType<typeof TenantPicker>>(); // 租户选择器引用
  84. const formData = reactive({
  85. mobile: "",
  86. code: "",
  87. password: "",
  88. confirmPassword: "",
  89. }); // 表单数据
  90. /** 发送验证码前的校验 */
  91. function validateBeforeSend(): boolean {
  92. return tenantPickerRef.value?.validate() ?? false;
  93. }
  94. /** 重置密码处理 */
  95. async function handleResetPassword() {
  96. // 校验租户
  97. if (!tenantPickerRef.value?.validate()) {
  98. return;
  99. }
  100. if (!formData.mobile) {
  101. toast.warning("请输入手机号");
  102. return;
  103. }
  104. if (!isMobile(formData.mobile)) {
  105. toast.warning("请输入正确的手机号");
  106. return;
  107. }
  108. if (!formData.code) {
  109. toast.warning("请输入验证码");
  110. return;
  111. }
  112. if (!formData.password) {
  113. toast.warning("请输入新密码");
  114. return;
  115. }
  116. if (!formData.confirmPassword) {
  117. toast.warning("请确认新密码");
  118. return;
  119. }
  120. if (formData.password !== formData.confirmPassword) {
  121. toast.warning("两次输入的密码不一致");
  122. return;
  123. }
  124. loading.value = true;
  125. try {
  126. // 调用重置密码接口
  127. await smsResetPassword({
  128. mobile: formData.mobile,
  129. code: formData.code,
  130. password: formData.password,
  131. });
  132. toast.success("密码重置成功");
  133. // 跳转到登录页
  134. setTimeout(() => {
  135. goToLogin();
  136. }, 500);
  137. } finally {
  138. loading.value = false;
  139. }
  140. }
  141. /** 跳转到登录页面 */
  142. function goToLogin() {
  143. uni.navigateTo({ url: LOGIN_PAGE });
  144. }
  145. </script>
  146. <style lang="scss" scoped>
  147. @import "./styles/auth.scss";
  148. </style>