Răsfoiți Sursa

修改密码

zhongxiaoyu 2 ani în urmă
părinte
comite
e9045d43b9

+ 1 - 1
src/components/dialog/index.vue

@@ -13,7 +13,7 @@
       :width="props.width"
       :show-close="props.showFlag"
     >
-      <div class="dialog-content">
+      <div class="dialog-wrapper">
         <template v-if="props.type == 'del'">
           <div class="airportInfoDialog">
             <div class="title del-title">{{ props.msgTitle }}</div>

+ 127 - 0
src/layout/components/ChangePassword/index.vue

@@ -0,0 +1,127 @@
+<template>
+  <Dialog
+    :flag="passwordDialogVisible"
+    width="496px"
+    msg-title="修改密码"
+    @submit-form="submitHandler"
+    @reset-form="togglePasswordDialog(false)"
+  >
+    <div class="dialog-content">
+      <div class="ruleDesc">
+        特殊字符:`、!、@、#、$、%、^、&、*、(、)、_、+、{、}、"、:、?、>、&lt;、`、,、.、/、'、;、[、]、=、-、\、|
+      </div>
+      <div class="ruleDesc">
+        密码规则:长度为8-20个字符,并且必须包含数字、大写字母、小写字母、特殊字符
+      </div>
+      <el-form
+        ref="formRef"
+        :model="formData"
+        :rules="formRules"
+        label-position="top"
+        class="password-form"
+      >
+        <el-form-item label="旧密码" prop="old">
+          <el-input
+            v-model="formData.old"
+            autocomplete="off"
+            size="default"
+            placeholder="请输入旧密码"
+            show-password
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="新密码" prop="new">
+          <el-input
+            v-model="formData.new"
+            size="default"
+            placeholder="请输入新密码"
+            show-password
+          ></el-input>
+        </el-form-item>
+        <el-form-item label="再次确认新密码" prop="repeat">
+          <el-input
+            v-model="formData.repeat"
+            size="default"
+            placeholder="请再次确认新密码"
+            show-password
+          ></el-input>
+        </el-form-item>
+      </el-form>
+    </div>
+  </Dialog>
+</template>
+
+<script setup lang="ts">
+import { changePassword } from '@/api/newLogin'
+import Dialog from '@/components/dialog/index.vue'
+import { useUserStore } from '@/store/user'
+import { ElMessage, FormInstance } from 'element-plus'
+import MD5 from 'blueimp-md5'
+
+const emit = defineEmits(['logout'])
+
+const userStore = useUserStore()
+const { passwordDialogVisible, UserId } = storeToRefs(userStore)
+const { togglePasswordDialog } = userStore
+
+const formRef = ref<FormInstance | null>(null)
+const formData = reactive({
+  old: '',
+  new: '',
+  repeat: '',
+})
+const repeatValidator = (rule: any, value: any, callback: any) => {
+  if (value !== formData.new) {
+    return callback(new Error('两次输入的密码不一致,请重新输入'))
+  }
+  return callback()
+}
+// 表单验证
+const formRules = {
+  old: [{ required: true, message: '请输入旧密码', trigger: 'blur' }],
+  new: [{ required: true, message: '请输入新密码', trigger: 'blur' }],
+  repeat: [
+    { required: true, message: '请再次确认新密码', trigger: 'blur' },
+    { validator: repeatValidator, trigger: 'blur' },
+  ],
+}
+const submitHandler = () => {
+  formRef.value?.validate(valid => {
+    if (valid) {
+      submitNewPassword()
+    } else {
+      return false
+    }
+  })
+}
+const submitNewPassword = async () => {
+  try {
+    const { code, message }: any = await changePassword({
+      userId: UserId.value,
+      originPassword: MD5(formData.old),
+      newPassword: formData.new,
+    })
+    if (Number(code) !== 0) {
+      throw new Error('修改失败')
+    }
+    ElMessage.success('修改成功')
+    togglePasswordDialog(false)
+    setTimeout(() => {
+      ElMessage.info('请重新登录')
+      emit('logout')
+    }, 2000)
+  } catch (error: any) {
+    ElMessage.error(error.message ?? '修改失败')
+  }
+}
+</script>
+
+<style lang="scss" scoped>
+.dialog-content {
+  margin-left: 20px;
+  .ruleDesc {
+    line-height: 2;
+    margin-bottom: 22px;
+    color: #101611;
+  }
+}
+</style>

+ 10 - 6
src/layout/components/NavBarTop/index.vue

@@ -21,31 +21,31 @@
               <router-link to="/">
                 <el-dropdown-item>首页</el-dropdown-item>
               </router-link>
+              <el-dropdown-item divided @click="changePassword">修改密码</el-dropdown-item>
               <el-dropdown-item divided @click="loginOut">退出登录</el-dropdown-item>
             </el-dropdown-menu>
           </template>
         </el-dropdown>
       </div>
     </div>
+    <ChangePassword @logout="loginOut" />
   </div>
 </template>
 
 <script setup lang="ts">
-import { ref } from "vue";
 import { ElMessage } from "element-plus";
 import { ArrowDownBold } from "@element-plus/icons-vue";
 import { useUserStore } from "@/store/user";
 import imgUrl from "../../../assets/home/pic_logo.png";
-const store = useUserStore();
-const name = store.$state.username;
+import ChangePassword from '@/layout/components/ChangePassword/index.vue'
+const userStore = useUserStore();
+const { username: name } = storeToRefs(userStore);
 const errorHandler = () => true;
 /*
  * 退出登录
  * */
 const router = useRouter();
-const route = useRoute();
 const loginOut = async () => {
-  const userStore = useUserStore();
   const result: any = await userStore.logout();
   if (result.code == 0) {
     ElMessage({
@@ -53,7 +53,7 @@ const loginOut = async () => {
       type: "success",
       duration: 2 * 1000,
       onClose: () => {
-        useUserStore().resetState();
+        userStore.resetState();
         router.push(`/login`);
         location.reload();
       },
@@ -62,6 +62,10 @@ const loginOut = async () => {
     ElMessage.error(result.message);
   }
 };
+
+const changePassword = () => {
+  userStore.togglePasswordDialog(true);
+};
 </script>
 
 <style lang="scss" scoped>

+ 6 - 0
src/store/user.ts

@@ -39,6 +39,7 @@ export const useUserStore = defineStore('user', {
       userPoewrList: sessionStorage.getItem('userAuthList')
         ? JSON.parse(sessionStorage.getItem('userAuthList'))
         : [],
+      passwordDialogVisible: false
     }
   },
 
@@ -195,5 +196,10 @@ export const useUserStore = defineStore('user', {
       const tagsViewStore = useTagsViewStore()
       tagsViewStore.delAllViews()
     },
+    togglePasswordDialog(visible: boolean) {
+      this.$patch(state => {
+        state.passwordDialogVisible = visible
+      })
+    }
   },
 })

+ 1 - 1
src/styles/index.scss

@@ -121,7 +121,7 @@
         margin: 0 8px;
       }
     }
-    .dialog-content .el-form {
+    .dialog-wrapper .el-form {
       padding-right: 24px;
     }
     .el-form-item__label {