|
@@ -0,0 +1,256 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <div class="login-container">
|
|
|
|
|
+ <div class="login-form">
|
|
|
|
|
+ <img :src="exitIcon" alt="关闭" class="exit-icon" @click="emit('close')" />
|
|
|
|
|
+ <header class="login-form__header">
|
|
|
|
|
+ <span>修改密码</span>
|
|
|
|
|
+ </header>
|
|
|
|
|
+ <main class="login-form__main">
|
|
|
|
|
+ <el-form
|
|
|
|
|
+ ref="formRef"
|
|
|
|
|
+ :model="formValue"
|
|
|
|
|
+ :rules="rules"
|
|
|
|
|
+ label-width="auto"
|
|
|
|
|
+ class="login-form__form"
|
|
|
|
|
+ @keydown.enter="confirmUpdatePwd"
|
|
|
|
|
+ >
|
|
|
|
|
+ <el-form-item prop="oldPwd">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ placeholder="请输入原密码"
|
|
|
|
|
+ v-model="formValue.oldPwd"
|
|
|
|
|
+ type="password"
|
|
|
|
|
+ autocomplete="off"
|
|
|
|
|
+ show-password
|
|
|
|
|
+ clearable
|
|
|
|
|
+ class="el-input--default"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ <el-form-item prop="newPwd">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ placeholder="新密码(至少6位)"
|
|
|
|
|
+ v-model="formValue.newPwd"
|
|
|
|
|
+ type="password"
|
|
|
|
|
+ autocomplete="off"
|
|
|
|
|
+ show-password
|
|
|
|
|
+ clearable
|
|
|
|
|
+ class="el-input--default"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+
|
|
|
|
|
+ <el-form-item prop="confirmPwd">
|
|
|
|
|
+ <el-input
|
|
|
|
|
+ placeholder="确认密码(至少6位)"
|
|
|
|
|
+ v-model="formValue.confirmPwd"
|
|
|
|
|
+ type="password"
|
|
|
|
|
+ autocomplete="off"
|
|
|
|
|
+ show-password
|
|
|
|
|
+ clearable
|
|
|
|
|
+ class="el-input--default"
|
|
|
|
|
+ />
|
|
|
|
|
+ </el-form-item>
|
|
|
|
|
+ </el-form>
|
|
|
|
|
+ </main>
|
|
|
|
|
+ <footer class="login-form__footer">
|
|
|
|
|
+ <el-button class="login-form__button" @click="confirmUpdatePwd">确定修改</el-button>
|
|
|
|
|
+ </footer>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <div v-if="showOverlay" class="overlay">
|
|
|
|
|
+ <div class="loading-text">{{ loadingText }}</div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script lang="ts" setup>
|
|
|
|
|
+ import { ref, reactive, nextTick } from 'vue';
|
|
|
|
|
+ import { ElMessage, ElLoading } from 'element-plus';
|
|
|
|
|
+ import type { FormInstance } from 'element-plus';
|
|
|
|
|
+ import exitIcon from 'assets/svg/exit.svg';
|
|
|
|
|
+ import { useUserStore } from '@/store/modules/user';
|
|
|
|
|
+ import router from '@/router';
|
|
|
|
|
+
|
|
|
|
|
+ const userStore = useUserStore();
|
|
|
|
|
+
|
|
|
|
|
+ const emit = defineEmits(['close']);
|
|
|
|
|
+
|
|
|
|
|
+ const formValue = reactive({
|
|
|
|
|
+ oldPwd: '',
|
|
|
|
|
+ newPwd: '',
|
|
|
|
|
+ confirmPwd: '',
|
|
|
|
|
+ });
|
|
|
|
|
+ const formRef = ref<FormInstance>();
|
|
|
|
|
+ const showOverlay = ref(false);
|
|
|
|
|
+ const loadingBaseText = '密码修改成功,正在退出登录';
|
|
|
|
|
+ const loadingText = ref(loadingBaseText + '.');
|
|
|
|
|
+ let dotCount = 1;
|
|
|
|
|
+ let intervalId: number | null = null;
|
|
|
|
|
+
|
|
|
|
|
+ // 启动省略号动画
|
|
|
|
|
+ const startLoadingAnimation = async () => {
|
|
|
|
|
+ showOverlay.value = true;
|
|
|
|
|
+ intervalId = window.setInterval(() => {
|
|
|
|
|
+ dotCount = (dotCount % 3) + 1;
|
|
|
|
|
+ loadingText.value = loadingBaseText + '.'.repeat(dotCount);
|
|
|
|
|
+ }, 200);
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ // 停止动画并跳转
|
|
|
|
|
+ const stopLoadingAndRedirect = () => {
|
|
|
|
|
+ if (intervalId !== null) {
|
|
|
|
|
+ clearInterval(intervalId);
|
|
|
|
|
+ intervalId = null;
|
|
|
|
|
+ }
|
|
|
|
|
+ showOverlay.value = false;
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const validateConfirmPassword = (rule: any, value: string, callback: any) => {
|
|
|
|
|
+ if (value !== formValue.newPwd) {
|
|
|
|
|
+ callback(new Error('两次输入密码不一致'));
|
|
|
|
|
+ } else {
|
|
|
|
|
+ callback();
|
|
|
|
|
+ }
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const rules = {
|
|
|
|
|
+ oldPwd: [{ required: true, message: '原密码不能为空', trigger: 'blur' }],
|
|
|
|
|
+ newPwd: [
|
|
|
|
|
+ { required: true, message: '新密码不能为空', trigger: 'blur' },
|
|
|
|
|
+ { min: 6, message: '密码长度不能小于6位', trigger: 'blur' },
|
|
|
|
|
+ ],
|
|
|
|
|
+ confirmPwd: [
|
|
|
|
|
+ { required: true, message: '请确认新密码', trigger: 'blur' },
|
|
|
|
|
+ { validator: validateConfirmPassword, trigger: 'blur' },
|
|
|
|
|
+ ],
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ const confirmUpdatePwd = () => {
|
|
|
|
|
+ if (!formRef.value) return;
|
|
|
|
|
+ formRef.value.validate((valid: boolean, ...rest) => {
|
|
|
|
|
+ if (valid) {
|
|
|
|
|
+ startLoadingAnimation();
|
|
|
|
|
+ userStore
|
|
|
|
|
+ .changePassword(formValue)
|
|
|
|
|
+ .then(() => {
|
|
|
|
|
+ emit('close');
|
|
|
|
|
+ setTimeout(() => {
|
|
|
|
|
+ stopLoadingAndRedirect();
|
|
|
|
|
+ }, 20000);
|
|
|
|
|
+ userStore.logout();
|
|
|
|
|
+ router.push({ path: '/home' });
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch(() => {
|
|
|
|
|
+ ElMessage.error('修改密码失败');
|
|
|
|
|
+ stopLoadingAndRedirect();
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ };
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style lang="scss" scoped>
|
|
|
|
|
+ .login-container {
|
|
|
|
|
+ @include flex-center;
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ width: 100vw;
|
|
|
|
|
+ height: 100vh;
|
|
|
|
|
+ background-color: rgba(0, 0, 0, 0.42);
|
|
|
|
|
+ z-index: 1000;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .login-form {
|
|
|
|
|
+ position: relative;
|
|
|
|
|
+ width: 700cpx;
|
|
|
|
|
+ padding: 0 33cpx;
|
|
|
|
|
+ background: $white-color;
|
|
|
|
|
+ border-radius: 24cpx;
|
|
|
|
|
+
|
|
|
|
|
+ &__header {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100cpx;
|
|
|
|
|
+ font-size: 28cpx;
|
|
|
|
|
+ font-weight: 550;
|
|
|
|
|
+ color: #333;
|
|
|
|
|
+ text-align: center;
|
|
|
|
|
+ line-height: 100cpx;
|
|
|
|
|
+ letter-spacing: 5cpx;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &__main {
|
|
|
|
|
+ @include flex-center;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 20cpx;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &__code {
|
|
|
|
|
+ @include flex-center;
|
|
|
|
|
+ justify-content: space-between;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 72cpx;
|
|
|
|
|
+ .el-input--default {
|
|
|
|
|
+ width: 50%;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ &__footer {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100cpx;
|
|
|
|
|
+ margin-top: 18cpx;
|
|
|
|
|
+
|
|
|
|
|
+ .login-form__button {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 74cpx;
|
|
|
|
|
+ font-size: 24cpx;
|
|
|
|
|
+ color: $white-color;
|
|
|
|
|
+ background-color: $primary-color;
|
|
|
|
|
+ border-radius: 8cpx;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .exit-icon {
|
|
|
|
|
+ position: absolute;
|
|
|
|
|
+ top: 15cpx;
|
|
|
|
|
+ right: 16cpx;
|
|
|
|
|
+ width: 40cpx;
|
|
|
|
|
+ height: 40cpx;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .login-form__form {
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ flex-direction: column;
|
|
|
|
|
+ gap: 2cpx;
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .el-input--default {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 72cpx;
|
|
|
|
|
+
|
|
|
|
|
+ :deep(.el-input__inner) {
|
|
|
|
|
+ font-size: 20cpx;
|
|
|
|
|
+ color: #999;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .overlay {
|
|
|
|
|
+ position: fixed;
|
|
|
|
|
+ top: 0;
|
|
|
|
|
+ left: 0;
|
|
|
|
|
+ width: 100vw;
|
|
|
|
|
+ height: 100vh;
|
|
|
|
|
+ background-color: rgba(0, 0, 0, 0.6);
|
|
|
|
|
+ display: flex;
|
|
|
|
|
+ justify-content: center;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ z-index: 9999;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ .loading-text {
|
|
|
|
|
+ color: white;
|
|
|
|
|
+ font-size: 20px;
|
|
|
|
|
+ font-weight: bold;
|
|
|
|
|
+ }
|
|
|
|
|
+</style>
|