From 673d58023f4c0fe8633a107238ec8b577496717a Mon Sep 17 00:00:00 2001
From: Crunchy <3114200645@qq.com>
Date: 星期四, 07 十一月 2024 10:28:30 +0800
Subject: [PATCH] 添加登录验证码

---
 src/page/login/LoginCode.vue |  131 +++++++++++++++++++++++++++++++++++++++++++
 src/page/login/userlogin.vue |   49 ++++++++++++++-
 2 files changed, 175 insertions(+), 5 deletions(-)

diff --git a/src/page/login/LoginCode.vue b/src/page/login/LoginCode.vue
new file mode 100644
index 0000000..e2b4d40
--- /dev/null
+++ b/src/page/login/LoginCode.vue
@@ -0,0 +1,131 @@
+<template>
+  <div class="s-canvas" @click="$emit('refresh')">
+    <canvas id="s-canvas" :width="contentWidth" :height="contentHeight"></canvas>
+  </div>
+</template>
+<script>
+export default {
+  name: 'LoginCode',
+  props: {
+    identifyCode: {
+      // 榛樿娉ㄥ唽鐮�
+      type: String,
+      default: '1234',
+    },
+    fontSizeMin: {
+      // 瀛椾綋鏈�灏忓��
+      type: Number,
+      default: 25,
+    },
+    fontSizeMax: {
+      // 瀛椾綋鏈�澶у��
+      type: Number,
+      default: 35,
+    },
+    backgroundColorMin: {
+      // 楠岃瘉鐮佸浘鐗囪儗鏅壊鏈�灏忓��
+      type: Number,
+      default: 200,
+    },
+    backgroundColorMax: {
+      // 楠岃瘉鐮佸浘鐗囪儗鏅壊鏈�澶у��
+      type: Number,
+      default: 220,
+    },
+    dotColorMin: {
+      // 鑳屾櫙骞叉壈鐐规渶灏忓��
+      type: Number,
+      default: 60,
+    },
+    dotColorMax: {
+      // 鑳屾櫙骞叉壈鐐规渶澶у��
+      type: Number,
+      default: 120,
+    },
+    contentWidth: {
+      // 瀹瑰櫒瀹藉害
+      type: Number,
+      default: 90,
+    },
+    contentHeight: {
+      // 瀹瑰櫒楂樺害
+      type: Number,
+      default: 38,
+    },
+  },
+  methods: {
+    // 鐢熸垚涓�涓殢鏈烘暟
+    randomNum(min, max) {
+      return Math.floor(Math.random() * (max - min) + min)
+    },
+
+    // 鐢熸垚涓�涓殢鏈虹殑棰滆壊
+    randomColor(min, max) {
+      const r = this.randomNum(min, max)
+      const g = this.randomNum(min, max)
+      const b = this.randomNum(min, max)
+      return 'rgb(' + r + ',' + g + ',' + b + ')'
+    },
+    // 鐢诲浘
+    drawPic() {
+      const canvas = document.getElementById('s-canvas')
+      // 鍒涘缓涓�涓�2D瀵硅薄浣滀负涓婁笅鏂囥��
+      const ctx = canvas.getContext('2d')
+      ctx.textBaseline = 'bottom'
+      // 缁樺埗鑳屾櫙
+      ctx.fillStyle = '#e6ecfd'
+      ctx.fillRect(0, 0, this.contentWidth, this.contentHeight)
+      // 缁樺埗鏂囧瓧
+      for (let i = 0; i < this.identifyCode.length; i++) {
+        this.drawText(ctx, this.identifyCode[i], i)
+      }
+      this.drawLine(ctx)
+      this.drawDot(ctx)
+    },
+    // 鍦ㄧ敾甯冧笂鏄剧ず鏁版嵁
+    drawText(ctx, txt, i) {
+      ctx.fillStyle = this.randomColor(50, 160) // 闅忔満鐢熸垚瀛椾綋棰滆壊
+      ctx.font = this.randomNum(this.fontSizeMin, this.fontSizeMax) + 'px SimHei' // 闅忔満鐢熸垚瀛椾綋澶у皬
+      const x = (i + 1) * (this.contentWidth / (this.identifyCode.length + 1))
+      const y = this.randomNum(this.fontSizeMax, this.contentHeight - 5)
+      var deg = this.randomNum(-30, 30)
+      // 淇敼鍧愭爣鍘熺偣鍜屾棆杞搴�
+      ctx.translate(x, y)
+      ctx.rotate((deg * Math.PI) / 180)
+      ctx.fillText(txt, 0, 0)
+      // 鎭㈠鍧愭爣鍘熺偣鍜屾棆杞搴�
+      ctx.rotate((-deg * Math.PI) / 180)
+      ctx.translate(-x, -y)
+    },
+
+    // 缁樺埗骞叉壈绾�
+    drawLine(ctx) {
+      for (let i = 0; i < 4; i++) {
+        ctx.strokeStyle = this.randomColor(100, 200)
+        ctx.beginPath()
+        ctx.moveTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
+        ctx.lineTo(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight))
+        ctx.stroke()
+      }
+    },
+
+    // 缁樺埗骞叉壈鐐�
+    drawDot(ctx) {
+      for (let i = 0; i < 30; i++) {
+        ctx.fillStyle = this.randomColor(0, 255)
+        ctx.beginPath()
+        ctx.arc(this.randomNum(0, this.contentWidth), this.randomNum(0, this.contentHeight), 1, 0, 2 * Math.PI)
+        ctx.fill()
+      }
+    },
+  },
+  watch: {
+    identifyCode() {
+      this.drawPic()
+    },
+  },
+  mounted() {
+    this.drawPic()
+  },
+}
+</script>
diff --git a/src/page/login/userlogin.vue b/src/page/login/userlogin.vue
index 179116e..928a509 100644
--- a/src/page/login/userlogin.vue
+++ b/src/page/login/userlogin.vue
@@ -35,6 +35,25 @@
         <i slot="prefix" class="iconfont icon-mima"></i>
       </el-input>
     </el-form-item>
+    <el-form-item prop="loginCode">
+      <el-col :span="16">
+        <el-input
+          v-model="loginCode"
+          size="small"
+          auto-complete="off"
+          placeholder="璇疯緭鍏ラ獙璇佺爜"
+          @keyup.enter.native="handleLogin"
+        >
+        </el-input>
+      </el-col>
+      <el-col :span="6" :offset="2">
+        <login-code
+          :key="refreshKey"
+          :identifyCode="loginCodeValue"
+          @refresh="refreshLoginValueCode"
+        />
+      </el-col>
+    </el-form-item>
     <el-form-item>
       <el-button
         type="primary"
@@ -51,16 +70,14 @@
 </template>
 
 <script>
-import { randomLenNum } from '@/util/util'
 import { mapGetters } from 'vuex'
-import { getCode } from '@/api/code'
-import Verify from '@/components/verifition/Verify'
 import { getSsoAuthUrl } from '@/api/login'
+import LoginCode from '@/page/login/LoginCode.vue'
 
 export default {
   name: 'Userlogin',
   components: {
-    Verify
+    LoginCode
   },
   data() {
     return {
@@ -89,7 +106,12 @@
         ]
       },
       passwordType: 'password',
-      SSO: window.location.hash
+      SSO: window.location.hash,
+      loginCode: null,
+      loginCodeValue: Math.random()
+        .toString(36)
+        .substr(2, 4),
+      refreshKey: 0
     }
   },
   created() {
@@ -112,11 +134,21 @@
         : (this.passwordType = '')
     },
     handleLogin() {
+      if (!this.loginCode) {
+        this.$message.error('璇疯緭鍏ラ獙璇佺爜')
+        return
+      }
+      if (this.loginCode.toLowerCase() !== this.loginCodeValue) {
+        this.$message.error('楠岃瘉鐮佷笉姝g‘')
+        return
+      }
       this.$refs.loginForm.validate((valid) => {
         if (valid) {
           this.$store.dispatch('LoginByUsername', this.loginForm).then(() => {
             this.$router.push({ path: this.tagWel.value })
           })
+        } else {
+          this.refreshLoginValueCode()
         }
       })
     },
@@ -127,6 +159,13 @@
           this.$router.push({ path: this.tagWel.value })
         })
       }
+    },
+    // 鍒锋柊楠岃瘉鐮�
+    refreshLoginValueCode() {
+      this.loginCodeValue = Math.random()
+        .toString(36)
+        .substr(2, 4)
+      this.refreshKey++
     }
   }
 }

--
Gitblit v1.9.3