Explorar o código

feat: 新增验证随机图片,登录删除验证码相关功能

zhouyuhao hai 1 ano
pai
achega
5db5b5828a

+ 10 - 4
src/views/Login/src/components/SliderVerification.vue

@@ -1,6 +1,9 @@
 <script lang="ts" setup>
 //滑动图片验证码部分
-import Img01 from '../image/verification-img.png'
+import Img01 from '../image/verification-img-1.png'
+import Img02 from '../image/verification-img-2.png'
+import Img03 from '../image/verification-img-3.png'
+import Img04 from '../image/verification-img-4.png'
 import { ref } from 'vue'
 //引入'vue3-puzzle-vcode'插件
 import Vcode from 'vue3-puzzle-vcode'
@@ -142,7 +145,7 @@ defineExpose({
     successText="Verification successful"
     failText="Verification failed"
     :range="5"
-    :imgs="[Img01]"
+    :imgs="[Img01, Img02, Img03, Img04]"
   ></Vcode>
 </template>
 <style lang="scss" scoped>
@@ -208,8 +211,11 @@ div.vue-puzzle-vcode {
   background: #c7353f;
 }
 
-// 滑轨
-.vue-auth-box_ .auth-control_ .range-box div.range-slider {
+.vue-auth-box_ .auth-control_ .range-box .range-slider {
+  border-radius: 6px;
+}
+
+.vue-auth-box_ .auth-control_ div.range-box {
   border-radius: 6px;
 }
 // 滑块

+ 0 - 0
src/views/Login/src/image/verification-img.png → src/views/Login/src/image/verification-img-1.png


BIN=BIN
src/views/Login/src/image/verification-img-2.png


+ 42 - 90
src/views/Login/src/loginView.vue

@@ -4,6 +4,7 @@ import ErrorTips from './components/ErrorTips.vue'
 import { useUserStore } from '@/stores/modules/user'
 import ScoringSystem from '@/views/Dashboard/src/components/ScoringSystem.vue'
 import CryptoJS from 'crypto-js'
+import dayjs from 'dayjs'
 import SliderVerification from './components/SliderVerification.vue'
 
 const router = useRouter()
@@ -12,8 +13,7 @@ const route = useRoute()
 const loginForm = ref({
   username: '',
   password: '',
-  email: '',
-  code: ''
+  email: ''
 })
 
 const isRememerPwd = ref(false)
@@ -82,48 +82,21 @@ watch(status, () => {
   loginForm.value = {
     username: '',
     password: '',
-    email: '',
-    code: ''
+    email: ''
   }
   loginError.value = {
     username: false,
     password: false,
-    email: false,
-    code: false
+    email: false
   }
   isRememerPwd.value = false
   isUserNameExit.value = false
-  verificationCode.value = ''
-  getCode()
 })
 
 const loginError: any = ref({
   username: false,
   password: false,
-  email: false,
-  code: false
-})
-const verificationCode = ref()
-const loading = ref(false)
-// 获取验证码
-const getCode = () => {
-  if (loading.value) return
-  loading.value = true
-  $api
-    .getVerifcationCode()
-    .then((res: any) => {
-      if (res.code === 200) {
-        verificationCode.value = `data:image/png;base64,${res.data.imagePngBase64}`
-      } else {
-        verificationCode.value = ''
-      }
-    })
-    .finally(() => {
-      loading.value = false
-    })
-}
-onMounted(() => {
-  getCode()
+  email: false
 })
 
 const userStore = useUserStore()
@@ -137,8 +110,20 @@ const sliderVerificationFn = () => {
 }
 const isShowSliderVerification = ref(false)
 
+const confirmVerifyStatus = ref('')
+const secretVerificationKey = 'fT5!R1k$7Mv@4Q9X'
+const fixedIv = '1234567890123456' // 固定的初始化向量,长度为16字符
+// 判断用户是否完成验证,完成后生成一个密文传给后端
+// AES 加密函数
+const encryptVerificationPwd = (password) => {
+  const key = CryptoJS.enc.Utf8.parse(secretVerificationKey) // 解析密钥
+  const iv = CryptoJS.enc.Utf8.parse(fixedIv) // 解析IV
+  const encrypted = CryptoJS.AES.encrypt(CryptoJS.enc.Utf8.parse(password), key, { iv: iv })
+  return encrypted.toString()
+}
+
 // 点击登录按钮
-const handleLogin = () => {
+const handleVerification = () => {
   if (!isUserNameExit.value || !loginForm.value.username) {
     return
   }
@@ -146,14 +131,29 @@ const handleLogin = () => {
   // 这里是登录逻辑
   // handleLoginAfterVerify()
 }
+// 验证结束后通过status值判断调登录还是忘记密码接口
+const confirmVerification = () => {
+  // 生成验证成功的密文
+  const pwd = dayjs().unix()
+  confirmVerifyStatus.value = encryptVerificationPwd(pwd)
+  isShowSliderVerification.value = false
+
+  if (status.value === 'login') {
+    handleLoginAfterVerify()
+    console.log('login', confirmVerifyStatus.value)
+  } else {
+    handleSendPassword()
+    console.log('reset', confirmVerifyStatus.value)
+  }
+}
+
 // 验证结束后调用登录接口
 const handleLoginAfterVerify = () => {
-  isShowSliderVerification.value = false
   $api
     .login({
       uname: loginForm.value.username,
       psw: loginForm.value.password,
-      verifcation_code: loginForm.value.code
+      verifcation_code: confirmVerifyStatus.value
     })
     .then((res: any) => {
       if (res.code === 200) {
@@ -184,11 +184,8 @@ const handleLoginAfterVerify = () => {
         router.push('/')
       } else if (res.code === 400) {
         const { data } = res
-        // 验证码错误
         if (data.msg === 'password_error') {
           loginError.value.password = true
-        } else if (data.msg === 'verifcation_error') {
-          loginError.value.code = true
         } else if (data.msg === 'error_times') {
           errorTipsRef.value.openDialog()
         } else if (data.msg === 'passwordExpires') {
@@ -229,7 +226,7 @@ const handleForgot = () => {
   handleDeleteEmailTips()
 }
 const handleSendPassword = () => {
-  if (!isUserNameExit.value || !loginForm.value.username || !loginForm.value.email) {
+  if (!isUserNameExit.value || !loginForm.value.username) {
     return
   }
   // 这里是发送密码逻辑
@@ -237,22 +234,13 @@ const handleSendPassword = () => {
     .forgotPassword({
       login: loginForm.value.username,
       email: loginForm.value.email,
-      verifcation_code: loginForm.value.code
+      verifcation_code: confirmVerifyStatus.value
     })
     .then((res: any) => {
       if (res.code === 200) {
         backLogin(true)
-      } else if (res.code === 400) {
-        const { data } = res
-        if (data.msg === 'verifcation_error') {
-          loginError.value.code = true
-        }
-        getCode()
       }
     })
-    .catch(() => {
-      getCode()
-    })
 }
 
 const isEmailTips = ref(false)
@@ -336,33 +324,14 @@ const errorTipsRef = ref()
           </template>
         </el-input>
         <div class="error" v-if="loginError.password">Incorrect password. Please try again.</div>
-        <el-input
-          ref="codeRef"
-          :class="{ 'is-error': loginError.code }"
-          class="verification-code"
-          v-model="loginForm.code"
-          placeholder="Verification Code"
-          @focus="handleDeleteEmailTips('code')"
-          @keyup.enter="handleLogin"
-        >
-          <template #append>
-            <img
-              v-vloading="loading"
-              @click="getCode"
-              class="verification-code-img"
-              :src="verificationCode"
-              alt=""
-            />
-          </template>
-        </el-input>
-        <div class="error" v-if="loginError.code">Incorrect verification code.</div>
+
         <el-checkbox
           class="remember-password"
           v-model="isRememerPwd"
           label="Remember Password"
           size="large"
         />
-        <el-button @click="handleLogin" class="el-button--dark login-btn">Login</el-button>
+        <el-button @click="handleVerification" class="el-button--dark login-btn">Login</el-button>
       </div>
       <template #footer>
         <div class="license">
@@ -411,25 +380,8 @@ const errorTipsRef = ref()
           </template>
         </el-input>
         <div class="error" v-if="loginError.email">Incorrect email. Please try again.</div>
-        <el-input
-          ref="codeRef"
-          :class="{ 'is-error': loginError.code }"
-          class="verification-code"
-          v-model="loginForm.code"
-          placeholder="Verification Code"
-          @focus="handleDeleteEmailTips('code')"
-          @keyup.enter="handleSendPassword"
-          ><template #append>
-            <img
-              v-vloading="loading"
-              class="verification-code-img"
-              :src="verificationCode"
-              @click="getCode"
-              alt=""
-            /> </template
-        ></el-input>
-        <div class="error" v-if="loginError.code">Incorrect verification code.</div>
-        <el-button @click="handleSendPassword" class="el-button--dark login-btn"
+
+        <el-button @click="handleVerification" class="el-button--dark login-btn"
           >Send Password</el-button
         >
         <div @click="backLogin(false)" class="back-text">
@@ -446,7 +398,7 @@ const errorTipsRef = ref()
     </el-card>
     <SliderVerification
       v-if="isShowSliderVerification"
-      @close="handleLoginAfterVerify"
+      @close="confirmVerification"
       ref="sliderVerificationRef"
     ></SliderVerification>
     <ErrorTips ref="errorTipsRef" @forget-password="status = 'reset'"></ErrorTips>