|
1 | 1 | <template> |
2 | | - <login-layout> |
3 | | - <LoginContainer :subTitle="$t('theme.defaultSlogan')"> |
4 | | - <h2 class="mb-24">{{ $t('views.login.resetPassword') }}</h2> |
| 2 | + <login-layout v-if="!loading" v-loading="loading || sendLoading"> |
| 3 | + <LoginContainer |
| 4 | + :subTitle=" |
| 5 | + user.themeInfo?.slogan ? user.themeInfo?.slogan : $t('views.system.theme.defaultSlogan') |
| 6 | + " |
| 7 | + > |
| 8 | + <h2 class="mb-24">{{ $t('views.login.forgotPassword') }}</h2> |
5 | 9 | <el-form |
6 | | - class="reset-password-form" |
| 10 | + class="register-form" |
7 | 11 | ref="resetPasswordFormRef" |
8 | | - :model="resetPasswordForm" |
| 12 | + :model="CheckEmailForm" |
9 | 13 | :rules="rules" |
10 | 14 | > |
11 | 15 | <div class="mb-24"> |
12 | | - <el-form-item prop="password"> |
| 16 | + <el-form-item prop="email"> |
13 | 17 | <el-input |
14 | | - type="password" |
15 | 18 | size="large" |
16 | 19 | class="input-item" |
17 | | - v-model="resetPasswordForm.password" |
18 | | - :placeholder="$t('views.login.loginForm.password.placeholder')" |
19 | | - show-password |
| 20 | + v-model="CheckEmailForm.email" |
| 21 | + :placeholder="$t('views.login.loginForm.email.placeholder')" |
20 | 22 | > |
21 | 23 | </el-input> |
22 | 24 | </el-form-item> |
23 | 25 | </div> |
24 | 26 | <div class="mb-24"> |
25 | | - <el-form-item prop="re_password"> |
26 | | - <el-input |
27 | | - type="password" |
28 | | - size="large" |
29 | | - class="input-item" |
30 | | - v-model="resetPasswordForm.re_password" |
31 | | - :placeholder="$t('views.login.loginForm.re_password.placeholder')" |
32 | | - show-password |
33 | | - > |
34 | | - </el-input> |
| 27 | + <el-form-item prop="code"> |
| 28 | + <div class="flex-between w-full"> |
| 29 | + <el-input |
| 30 | + size="large" |
| 31 | + class="code-input" |
| 32 | + v-model="CheckEmailForm.code" |
| 33 | + :placeholder="$t('views.login.verificationCode.placeholder')" |
| 34 | + > |
| 35 | + </el-input> |
| 36 | + |
| 37 | + <el-button |
| 38 | + :disabled="isDisabled" |
| 39 | + size="large" |
| 40 | + class="send-email-button ml-12" |
| 41 | + @click="sendEmail" |
| 42 | + :loading="loading" |
| 43 | + > |
| 44 | + {{ |
| 45 | + isDisabled |
| 46 | + ? `${$t('views.login.verificationCode.resend')}(${time}s)` |
| 47 | + : $t('views.login.verificationCode.getVerificationCode') |
| 48 | + }} |
| 49 | + </el-button> |
| 50 | + </div> |
35 | 51 | </el-form-item> |
36 | 52 | </div> |
37 | 53 | </el-form> |
38 | | - <el-button size="large" type="primary" class="w-full" @click="resetPassword">{{ |
39 | | - $t('common.confirm') |
40 | | - }}</el-button> |
| 54 | + <el-button size="large" type="primary" class="w-full" @click="checkCode" |
| 55 | + >{{ $t('views.login.buttons.checkCode') }} |
| 56 | + </el-button> |
41 | 57 | <div class="operate-container mt-12"> |
42 | 58 | <el-button |
43 | | - size="large" |
44 | 59 | class="register" |
45 | 60 | @click="router.push('/login')" |
46 | 61 | link |
|
54 | 69 | </login-layout> |
55 | 70 | </template> |
56 | 71 | <script setup lang="ts"> |
57 | | -import { ref, onMounted } from 'vue' |
| 72 | +import { onBeforeMount, ref } from 'vue' |
58 | 73 | import LoginContainer from '@/layout/login-layout/LoginContainer.vue' |
59 | 74 | import LoginLayout from '@/layout/login-layout/LoginLayout.vue' |
60 | | -import type { ResetPasswordRequest } from '@/api/type/user' |
61 | | -import { useRouter, useRoute } from 'vue-router' |
62 | | -import { MsgSuccess } from '@/utils/message' |
| 75 | +import type { CheckCodeRequest } from '@/api/type/user' |
| 76 | +import { useRouter } from 'vue-router' |
63 | 77 | import type { FormInstance, FormRules } from 'element-plus' |
64 | | -import UserApi from '@/api/user/user' |
| 78 | +import UserApi from '@/api/user/user-manage' |
| 79 | +import { MsgSuccess } from '@/utils/message' |
65 | 80 | import { t } from '@/locales' |
| 81 | +import useStore from '@/stores' |
| 82 | +
|
66 | 83 | const router = useRouter() |
67 | | -const route = useRoute() |
68 | | -const { |
69 | | - params: { code, email } |
70 | | -} = route |
71 | | -const resetPasswordForm = ref<ResetPasswordRequest>({ |
72 | | - password: '', |
73 | | - re_password: '', |
74 | | - email: '', |
75 | | - code: '' |
76 | | -}) |
| 84 | +const { user } = useStore() |
77 | 85 |
|
78 | | -onMounted(() => { |
79 | | - if (code && email) { |
80 | | - resetPasswordForm.value.code = code as string |
81 | | - resetPasswordForm.value.email = email as string |
82 | | - } else { |
83 | | - router.push('forgot_password') |
84 | | - } |
| 86 | +const CheckEmailForm = ref<CheckCodeRequest>({ |
| 87 | + email: '', |
| 88 | + code: '', |
| 89 | + type: 'reset_password' |
85 | 90 | }) |
86 | 91 |
|
87 | | -const rules = ref<FormRules<ResetPasswordRequest>>({ |
88 | | - password: [ |
89 | | - { |
90 | | - required: true, |
91 | | - message: t('views.login.loginForm.re_password.requiredMessage'), |
92 | | - trigger: 'blur' |
93 | | - }, |
94 | | - { |
95 | | - min: 6, |
96 | | - max: 20, |
97 | | - message: t('views.login.loginForm.password.lengthMessage'), |
98 | | - trigger: 'blur' |
99 | | - } |
100 | | - ], |
101 | | - re_password: [ |
| 92 | +const resetPasswordFormRef = ref<FormInstance>() |
| 93 | +const rules = ref<FormRules<CheckCodeRequest>>({ |
| 94 | + email: [ |
102 | 95 | { |
103 | 96 | required: true, |
104 | | - message: t('views.login.loginForm.re_password.requiredMessage'), |
105 | | - trigger: 'blur' |
106 | | - }, |
107 | | - { |
108 | | - min: 6, |
109 | | - max: 20, |
110 | | - message: t('views.login.loginForm.password.lengthMessage'), |
| 97 | + message: t('views.login.loginForm.email.requiredMessage'), |
111 | 98 | trigger: 'blur' |
112 | 99 | }, |
113 | 100 | { |
114 | 101 | validator: (rule, value, callback) => { |
115 | | - if (resetPasswordForm.value.password != resetPasswordForm.value.re_password) { |
116 | | - callback(new Error(t('views.login.loginForm.re_password.validatorMessage'))) |
| 102 | + const emailRegExp = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/ |
| 103 | + if (!emailRegExp.test(value) && value != '') { |
| 104 | + callback(new Error(t('views.login.loginForm.email.validatorEmail'))) |
117 | 105 | } else { |
118 | 106 | callback() |
119 | 107 | } |
120 | 108 | }, |
121 | 109 | trigger: 'blur' |
122 | 110 | } |
123 | | - ] |
| 111 | + ], |
| 112 | + code: [{ required: true, message: t('views.login.verificationCode.placeholder') }] |
124 | 113 | }) |
125 | | -const resetPasswordFormRef = ref<FormInstance>() |
126 | 114 | const loading = ref<boolean>(false) |
127 | | -const resetPassword = () => { |
| 115 | +const isDisabled = ref<boolean>(false) |
| 116 | +const time = ref<number>(60) |
| 117 | +const sendLoading = ref<boolean>(false) |
| 118 | +const checkCode = () => { |
128 | 119 | resetPasswordFormRef.value |
129 | 120 | ?.validate() |
130 | | - .then(() => UserApi.resetPassword(resetPasswordForm.value, loading)) |
131 | | - .then(() => { |
132 | | - MsgSuccess(t('common.modifySuccess')) |
133 | | - router.push({ name: 'login' }) |
134 | | - }) |
| 121 | + .then(() => UserApi.checkCode(CheckEmailForm.value, sendLoading)) |
| 122 | + .then(() => router.push({ name: 'reset_password', params: CheckEmailForm.value })) |
| 123 | +} |
| 124 | +/** |
| 125 | + * 发送验证码 |
| 126 | + */ |
| 127 | +const sendEmail = () => { |
| 128 | + resetPasswordFormRef.value?.validateField('email', (v: boolean) => { |
| 129 | + if (v) { |
| 130 | + UserApi.sendEmit(CheckEmailForm.value.email, 'reset_password', sendLoading).then(() => { |
| 131 | + MsgSuccess(t('views.login.verificationCode.successMessage')) |
| 132 | + isDisabled.value = true |
| 133 | + handleTimeChange() |
| 134 | + }) |
| 135 | + } |
| 136 | + }) |
135 | 137 | } |
| 138 | +const handleTimeChange = () => { |
| 139 | + if (time.value <= 0) { |
| 140 | + isDisabled.value = false |
| 141 | + time.value = 60 |
| 142 | + } else { |
| 143 | + setTimeout(() => { |
| 144 | + time.value-- |
| 145 | + handleTimeChange() |
| 146 | + }, 1000) |
| 147 | + } |
| 148 | +} |
| 149 | +onBeforeMount(() => { |
| 150 | + loading.value = true |
| 151 | + user.asyncGetProfile().then(() => { |
| 152 | + loading.value = false |
| 153 | + }) |
| 154 | +}) |
136 | 155 | </script> |
137 | 156 | <style lang="scss" scoped></style> |
0 commit comments