This commit is contained in:
wangdan-fit2cloud 2025-06-16 21:14:12 +08:00
parent 863e08120a
commit d6a301c184
12 changed files with 130 additions and 107 deletions

View File

@ -30,6 +30,12 @@ export default {
requiredMessage: 'Please enter confirm password', requiredMessage: 'Please enter confirm password',
validatorMessage: 'Password does not match', validatorMessage: 'Password does not match',
}, },
email: {
label: 'Email',
placeholder: 'Please enter email',
requiredMessage: 'Please enter email',
validatorEmail: 'Please enter a valid email format!',
},
}, },
jump_tip: 'You will be redirected to the authentication source page for authentication', jump_tip: 'You will be redirected to the authentication source page for authentication',
jump: 'Redirect', jump: 'Redirect',

View File

@ -26,11 +26,6 @@ export default {
label: 'Name', label: 'Name',
placeholder: 'Please enter name', placeholder: 'Please enter name',
}, },
email: {
label: 'Email',
placeholder: 'Please enter email',
requiredMessage: 'Please enter email',
},
phone: { phone: {
label: 'Phone', label: 'Phone',
placeholder: 'Please enter phone', placeholder: 'Please enter phone',

View File

@ -30,6 +30,12 @@ export default {
requiredMessage: '请输入确认密码', requiredMessage: '请输入确认密码',
validatorMessage: '密码不一致', validatorMessage: '密码不一致',
}, },
email: {
label: '邮箱',
placeholder: '请输入邮箱',
requiredMessage: '请输入邮箱',
validatorEmail: '请输入有效邮箱格式!',
},
}, },
jump_tip: '即将跳转至认证源页面进行认证', jump_tip: '即将跳转至认证源页面进行认证',
jump: '跳转', jump: '跳转',

View File

@ -23,12 +23,7 @@ export default {
label: '姓名', label: '姓名',
placeholder: '请输入姓名', placeholder: '请输入姓名',
}, },
email: {
label: '邮箱',
placeholder: '请输入邮箱',
requiredMessage: '请输入邮箱',
validatorEmail: '请输入有效邮箱格式!',
},
phone: { phone: {
label: '手机号', label: '手机号',
placeholder: '请输入手机号', placeholder: '请输入手机号',

View File

@ -30,6 +30,12 @@ export default {
requiredMessage: '請輸入確認密碼', requiredMessage: '請輸入確認密碼',
validatorMessage: '密碼不一致', validatorMessage: '密碼不一致',
}, },
email: {
label: '電子信箱',
placeholder: '請輸入電子信箱',
requiredMessage: '請輸入電子信箱',
validatorEmail: '請輸入有效電子信箱格式!',
},
}, },
jump_tip: '即將跳轉至認證源頁面進行認證', jump_tip: '即將跳轉至認證源頁面進行認證',
jump: '跳轉', jump: '跳轉',

View File

@ -24,11 +24,7 @@ export default {
label: '姓名', label: '姓名',
placeholder: '請輸入姓名', placeholder: '請輸入姓名',
}, },
email: {
label: '電子信箱',
placeholder: '請輸入電子信箱',
requiredMessage: '請輸入電子信箱',
},
phone: { phone: {
label: '手機號碼', label: '手機號碼',
placeholder: '請輸入手機號碼', placeholder: '請輸入手機號碼',

View File

@ -24,7 +24,7 @@
<el-card shadow="never" :class="item.id === selectKnowledge ? 'active' : ''"> <el-card shadow="never" :class="item.id === selectKnowledge ? 'active' : ''">
<el-radio :value="item.id" size="large"> <el-radio :value="item.id" size="large">
<div class="flex align-center"> <div class="flex align-center">
<KnowledgeIcon :type="item.type" /> <KnowledgeIcon :type="item.type" class="mr-12" />
<span class="ellipsis" :title="item.name"> <span class="ellipsis" :title="item.name">
{{ item.name }} {{ item.name }}

View File

@ -1,46 +1,61 @@
<template> <template>
<login-layout> <login-layout v-if="!loading" v-loading="loading || sendLoading">
<LoginContainer :subTitle="$t('theme.defaultSlogan')"> <LoginContainer
<h2 class="mb-24">{{ $t('views.login.resetPassword') }}</h2> :subTitle="
user.themeInfo?.slogan ? user.themeInfo?.slogan : $t('views.system.theme.defaultSlogan')
"
>
<h2 class="mb-24">{{ $t('views.login.forgotPassword') }}</h2>
<el-form <el-form
class="reset-password-form" class="register-form"
ref="resetPasswordFormRef" ref="resetPasswordFormRef"
:model="resetPasswordForm" :model="CheckEmailForm"
:rules="rules" :rules="rules"
> >
<div class="mb-24"> <div class="mb-24">
<el-form-item prop="password"> <el-form-item prop="email">
<el-input <el-input
type="password"
size="large" size="large"
class="input-item" class="input-item"
v-model="resetPasswordForm.password" v-model="CheckEmailForm.email"
:placeholder="$t('views.login.loginForm.password.placeholder')" :placeholder="$t('views.login.loginForm.email.placeholder')"
show-password
> >
</el-input> </el-input>
</el-form-item> </el-form-item>
</div> </div>
<div class="mb-24"> <div class="mb-24">
<el-form-item prop="re_password"> <el-form-item prop="code">
<el-input <div class="flex-between w-full">
type="password" <el-input
size="large" size="large"
class="input-item" class="code-input"
v-model="resetPasswordForm.re_password" v-model="CheckEmailForm.code"
:placeholder="$t('views.login.loginForm.re_password.placeholder')" :placeholder="$t('views.login.verificationCode.placeholder')"
show-password >
> </el-input>
</el-input>
<el-button
:disabled="isDisabled"
size="large"
class="send-email-button ml-12"
@click="sendEmail"
:loading="loading"
>
{{
isDisabled
? `${$t('views.login.verificationCode.resend')}${time}s`
: $t('views.login.verificationCode.getVerificationCode')
}}
</el-button>
</div>
</el-form-item> </el-form-item>
</div> </div>
</el-form> </el-form>
<el-button size="large" type="primary" class="w-full" @click="resetPassword">{{ <el-button size="large" type="primary" class="w-full" @click="checkCode"
$t('common.confirm') >{{ $t('views.login.buttons.checkCode') }}
}}</el-button> </el-button>
<div class="operate-container mt-12"> <div class="operate-container mt-12">
<el-button <el-button
size="large"
class="register" class="register"
@click="router.push('/login')" @click="router.push('/login')"
link link
@ -54,84 +69,88 @@
</login-layout> </login-layout>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, onMounted } from 'vue' import { onBeforeMount, ref } from 'vue'
import LoginContainer from '@/layout/login-layout/LoginContainer.vue' import LoginContainer from '@/layout/login-layout/LoginContainer.vue'
import LoginLayout from '@/layout/login-layout/LoginLayout.vue' import LoginLayout from '@/layout/login-layout/LoginLayout.vue'
import type { ResetPasswordRequest } from '@/api/type/user' import type { CheckCodeRequest } from '@/api/type/user'
import { useRouter, useRoute } from 'vue-router' import { useRouter } from 'vue-router'
import { MsgSuccess } from '@/utils/message'
import type { FormInstance, FormRules } from 'element-plus' import type { FormInstance, FormRules } from 'element-plus'
import UserApi from '@/api/user/user' import UserApi from '@/api/user/user-manage'
import { MsgSuccess } from '@/utils/message'
import { t } from '@/locales' import { t } from '@/locales'
import useStore from '@/stores'
const router = useRouter() const router = useRouter()
const route = useRoute() const { user } = useStore()
const {
params: { code, email } const CheckEmailForm = ref<CheckCodeRequest>({
} = route
const resetPasswordForm = ref<ResetPasswordRequest>({
password: '',
re_password: '',
email: '', email: '',
code: '' code: '',
type: 'reset_password'
}) })
onMounted(() => { const resetPasswordFormRef = ref<FormInstance>()
if (code && email) { const rules = ref<FormRules<CheckCodeRequest>>({
resetPasswordForm.value.code = code as string email: [
resetPasswordForm.value.email = email as string
} else {
router.push('forgot_password')
}
})
const rules = ref<FormRules<ResetPasswordRequest>>({
password: [
{ {
required: true, required: true,
message: t('views.login.loginForm.re_password.requiredMessage'), message: t('views.login.loginForm.email.requiredMessage'),
trigger: 'blur'
},
{
min: 6,
max: 20,
message: t('views.login.loginForm.password.lengthMessage'),
trigger: 'blur'
}
],
re_password: [
{
required: true,
message: t('views.login.loginForm.re_password.requiredMessage'),
trigger: 'blur'
},
{
min: 6,
max: 20,
message: t('views.login.loginForm.password.lengthMessage'),
trigger: 'blur' trigger: 'blur'
}, },
{ {
validator: (rule, value, callback) => { validator: (rule, value, callback) => {
if (resetPasswordForm.value.password != resetPasswordForm.value.re_password) { const emailRegExp = /^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)*\.[a-zA-Z0-9]{2,6}$/
callback(new Error(t('views.login.loginForm.re_password.validatorMessage'))) if (!emailRegExp.test(value) && value != '') {
callback(new Error(t('views.login.loginForm.email.validatorEmail')))
} else { } else {
callback() callback()
} }
}, },
trigger: 'blur' trigger: 'blur'
} }
] ],
code: [{ required: true, message: t('views.login.verificationCode.placeholder') }]
}) })
const resetPasswordFormRef = ref<FormInstance>()
const loading = ref<boolean>(false) const loading = ref<boolean>(false)
const resetPassword = () => { const isDisabled = ref<boolean>(false)
const time = ref<number>(60)
const sendLoading = ref<boolean>(false)
const checkCode = () => {
resetPasswordFormRef.value resetPasswordFormRef.value
?.validate() ?.validate()
.then(() => UserApi.resetPassword(resetPasswordForm.value, loading)) .then(() => UserApi.checkCode(CheckEmailForm.value, sendLoading))
.then(() => { .then(() => router.push({ name: 'reset_password', params: CheckEmailForm.value }))
MsgSuccess(t('common.modifySuccess'))
router.push({ name: 'login' })
})
} }
/**
* 发送验证码
*/
const sendEmail = () => {
resetPasswordFormRef.value?.validateField('email', (v: boolean) => {
if (v) {
UserApi.sendEmit(CheckEmailForm.value.email, 'reset_password', sendLoading).then(() => {
MsgSuccess(t('views.login.verificationCode.successMessage'))
isDisabled.value = true
handleTimeChange()
})
}
})
}
const handleTimeChange = () => {
if (time.value <= 0) {
isDisabled.value = false
time.value = 60
} else {
setTimeout(() => {
time.value--
handleTimeChange()
}, 1000)
}
}
onBeforeMount(() => {
loading.value = true
user.asyncGetProfile().then(() => {
loading.value = false
})
})
</script> </script>
<style lang="scss" scoped></style> <style lang="scss" scoped></style>

View File

@ -36,11 +36,11 @@
> >
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item :label="$t('views.userManage.userForm.email.label')" prop="email"> <el-form-item :label="$t('views.login.loginForm.email.label')" prop="email">
<el-input <el-input
type="email" type="email"
v-model="userForm.email" v-model="userForm.email"
:placeholder="$t('views.userManage.userForm.email.placeholder')" :placeholder="$t('views.login.loginForm.email.placeholder')"
> >
</el-input> </el-input>
</el-form-item> </el-form-item>
@ -99,33 +99,33 @@ const rules = reactive({
username: [ username: [
{ {
required: true, required: true,
message: t('views.userManage.form.username.requiredMessage'), message: t('views.login.loginForm.username.requiredMessage'),
trigger: 'blur', trigger: 'blur',
}, },
{ {
min: 6, min: 6,
max: 20, max: 20,
message: t('views.userManage.form.username.lengthMessage'), message: t('views.login.loginForm.username.lengthMessage'),
trigger: 'blur', trigger: 'blur',
}, },
], ],
email: [ email: [
{ {
required: true, required: true,
message: t('views.userManage.form.email.requiredMessage'), message: t('views.login.loginForm.email.requiredMessage'),
trigger: 'blur', trigger: 'blur',
}, },
], ],
password: [ password: [
{ {
required: true, required: true,
message: t('views.userManage.form.password.requiredMessage'), message: t('views.login.loginForm.password.requiredMessage'),
trigger: 'blur', trigger: 'blur',
}, },
{ {
min: 6, min: 6,
max: 20, max: 20,
message: t('views.userManage.form.password.lengthMessage'), message: t('views.login.loginForm.password.lengthMessage'),
trigger: 'blur', trigger: 'blur',
}, },
], ],

View File

@ -59,7 +59,7 @@
<el-table-column <el-table-column
prop="email" prop="email"
:label="$t('views.userManage.userForm.email.label')" :label="$t('views.login.loginForm.email.label')"
show-overflow-tooltip show-overflow-tooltip
> >
<template #default="{ row }"> <template #default="{ row }">

View File

@ -36,11 +36,11 @@
> >
</el-input> </el-input>
</el-form-item> </el-form-item>
<el-form-item :label="$t('views.userManage.userForm.email.label')" prop="email"> <el-form-item :label="$t('views.login.loginForm.email.label')" prop="email">
<el-input <el-input
type="email" type="email"
v-model="userForm.email" v-model="userForm.email"
:placeholder="$t('views.userManage.userForm.email.placeholder')" :placeholder="$t('views.login.loginForm.email.placeholder')"
> >
</el-input> </el-input>
</el-form-item> </el-form-item>
@ -102,7 +102,7 @@ const rules = reactive({
email: [ email: [
{ {
required: true, required: true,
message: t('views.userManage.form.email.requiredMessage'), message: t('views.login.loginForm.email.requiredMessage'),
trigger: 'blur', trigger: 'blur',
}, },
], ],

View File

@ -56,7 +56,7 @@
<el-table-column <el-table-column
prop="email" prop="email"
:label="$t('views.userManage.userForm.email.label')" :label="$t('views.login.loginForm.email.label')"
show-overflow-tooltip show-overflow-tooltip
> >
<template #default="{ row }"> <template #default="{ row }">