Ver Fonte

feat: 实现用户第一次登录时跳转修改密码功能

zhouyuhao há 11 meses atrás
pai
commit
c61dec4035

+ 10 - 2
src/stores/modules/user.ts

@@ -2,16 +2,22 @@ import { defineStore } from 'pinia'
 
 interface UserState {
   username: string
+  isFirstLogin: boolean
 }
 export const useUserStore = defineStore('user', {
   state: (): UserState => ({
-    username: localStorage.getItem('username') || ''
+    username: localStorage.getItem('username') || '',
+    isFirstLogin: localStorage.getItem('isFirstLogin')
+      ? JSON.parse(localStorage.getItem('isFirstLogin'))
+      : false
   }),
   getters: {},
   actions: {
-    setUsername(username: any) {
+    setUsername(username: any, isFirstLogin?: boolean) {
       localStorage.setItem('username', username)
       this.username = username
+      this.isFirstLogin = isFirstLogin
+      localStorage.setItem('isFirstLogin', JSON.stringify(isFirstLogin))
     },
     async logout(isNeedLogout: boolean = true) {
       if (isNeedLogout) {
@@ -19,6 +25,8 @@ export const useUserStore = defineStore('user', {
       }
       localStorage.removeItem('username')
       this.username = ''
+      localStorage.removeItem('isFirstLogin')
+      this.isFirstLogin = false
     }
   }
 })

+ 3 - 3
src/views/Layout/src/components/Header/HeaderView.vue

@@ -183,13 +183,13 @@ const handleLogin = () => {
           </div>
         </div>
         <template #reference>
-          <div class="header-avatar" v-if="userStore.username">
+          <div class="header-avatar" v-if="userStore.username && userStore.isFirstLogin !== true">
             <span style="">{{ userStore.username?.slice(0, 1) }}</span>
           </div>
         </template>
       </el-popover>
       <el-button
-        v-if="!userStore.username"
+        v-if="!userStore.username || (userStore.username && userStore.isFirstLogin === true)"
         class="el-button--main"
         style="padding: 8px 10px"
         plain
@@ -199,7 +199,7 @@ const handleLogin = () => {
         Download KLN Portal
       </el-button>
       <el-button
-        v-if="!userStore.username"
+        v-if="!userStore.username || (userStore.username && userStore.isFirstLogin === true)"
         class="el-button--main"
         style="margin-left: -10px"
         @click="handleLogin"

+ 15 - 2
src/views/Login/src/components/ChangePasswordCard.vue

@@ -1,7 +1,16 @@
 <script setup lang="ts">
-import { useRouter } from 'vue-router'
+import { useRouter, useRoute } from 'vue-router'
+import { useUserStore } from '@/stores/modules/user'
 
+const userStore = useUserStore()
 const router = useRouter()
+const route = useRoute()
+
+const tips = ref('Please change your password for security.')
+
+if (route.query.firstLogin === 't') {
+  tips.value = 'First login, please change your password.'
+}
 const loginForm = ref({
   username: '',
   oldPassword: '',
@@ -109,6 +118,10 @@ const checkPassword = () => {
   // 检测长度是否符合要求
   isValidLength.value = pwd.length >= 12 && pwd.length <= 20
 }
+
+onUnmounted(() => {
+  userStore.logout(false)
+})
 </script>
 
 <template>
@@ -116,7 +129,7 @@ const checkPassword = () => {
     <el-card class="login-card">
       <div class="title">
         <span class="welcome">Change Password</span>
-        <span class="tips">Password expired, please change your password.</span>
+        <span class="tips">{{ tips }}</span>
       </div>
 
       <div class="login-form">

+ 68 - 0
src/views/Login/src/components/FirstLoginTips.vue

@@ -0,0 +1,68 @@
+<script setup lang="ts">
+import { useRouter } from 'vue-router'
+const dialogVisible = ref(false)
+const router = useRouter()
+
+const openDialog = () => {
+  dialogVisible.value = true
+}
+const handleChangePassword = () => {
+  dialogVisible.value = false
+  router.push({
+    name: 'Reset Password',
+    query: {
+      firstLogin: 't'
+    }
+  })
+}
+defineExpose({
+  openDialog
+})
+</script>
+
+<template>
+  <el-dialog v-model="dialogVisible" top="25vh" :width="480" class="error-tips" :center="true">
+    <img style="margin-bottom: 18px" src="../image/first-login-tips-icon.png" alt="" />
+    <p class="blod-tips">Update your password</p>
+    <p>
+      To make your account secure, please create a new password to replace the temporary password
+      you were given in the email.
+    </p>
+    <template #footer>
+      <el-button
+        class="el-button--dark"
+        @click="handleChangePassword"
+        style="height: 40px; padding: 8px 30px"
+        >Change Password</el-button
+      >
+    </template>
+  </el-dialog>
+</template>
+
+<style lang="scss">
+.error-tips {
+  text-align: center;
+  .el-dialog__header {
+    display: none;
+  }
+  .el-dialog__body {
+    padding: 32px 32px 24px;
+    text-align: center;
+  }
+  .blod-tips {
+    font-size: 18px;
+    font-weight: 700;
+    margin-bottom: 8px;
+  }
+  p {
+    & > a {
+      text-decoration: underline;
+      color: var(--color-theme);
+      cursor: pointer;
+    }
+  }
+  &.el-dialog--center .el-dialog__footer {
+    padding-right: 0;
+  }
+}
+</style>

BIN
src/views/Login/src/image/first-login-tips-icon.png


+ 13 - 6
src/views/Login/src/loginView.vue

@@ -1,6 +1,7 @@
 <script setup lang="ts">
 import { useRouter, useRoute } from 'vue-router'
 import ErrorTips from './components/ErrorTips.vue'
+import FirstLoginTips from './components/FirstLoginTips.vue'
 import { useUserStore } from '@/stores/modules/user'
 import ScoringSystem from '@/views/Dashboard/src/components/ScoringSystem.vue'
 import CryptoJS from 'crypto-js'
@@ -261,15 +262,19 @@ const handleLoginAfterVerify = () => {
         } else if (data.msg === 'error_times') {
           errorTipsRef.value.openDialog()
         } else if (data.msg === 'passwordExpires') {
-          ElMessageBox.alert('Password expired, please change your password', 'Prompt', {
-            confirmButtonText: 'OK',
+          ElMessageBox.alert('Please change your password for security.', 'Prompt', {
+            confirmButtonText: 'Change Password',
             type: 'warning',
             confirmButtonClass: 'el-button--dark'
+          }).then(() => {
+            userStore.setUsername(res.data.uname)
+            router.push({
+              name: 'Reset Password'
+            })
           })
-          userStore.setUsername(res.data.uname || '')
-          router.push({
-            name: 'Reset Password'
-          })
+        } else if (data.msg === 'First login, please change your password') {
+          userStore.setUsername(res.data.uname, true)
+          firstLoginTipsRef.value.openDialog()
         }
       }
     })
@@ -337,6 +342,7 @@ const handleDeleteEmailTips = (type?: any) => {
 }
 
 const errorTipsRef = ref()
+const firstLoginTipsRef = ref()
 </script>
 
 <template>
@@ -472,6 +478,7 @@ const errorTipsRef = ref()
       ref="sliderVerificationRef"
     ></VSliderVerification>
     <ErrorTips ref="errorTipsRef" @forget-password="status = 'reset'"></ErrorTips>
+    <FirstLoginTips ref="firstLoginTipsRef" @forget-password="status = 'reset'"></FirstLoginTips>
   </div>
 </template>