From 089bf5d2378b3c4a61d795b2a92bede2c193b771 Mon Sep 17 00:00:00 2001
From: admin <344137771@qq.com>
Date: Tue, 06 Jan 2026 11:22:58 +0800
Subject: [PATCH] 1
---
src/components/verifition/Verify/VerifyPoints.vue | 268 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 268 insertions(+), 0 deletions(-)
diff --git a/src/components/verifition/Verify/VerifyPoints.vue b/src/components/verifition/Verify/VerifyPoints.vue
new file mode 100644
index 0000000..71cecd3
--- /dev/null
+++ b/src/components/verifition/Verify/VerifyPoints.vue
@@ -0,0 +1,268 @@
+<template>
+ <div
+ style="position: relative"
+ >
+ <div class="verify-img-out">
+ <div
+ class="verify-img-panel"
+ :style="{'width': setSize.imgWidth,
+ 'height': setSize.imgHeight,
+ 'background-size' : setSize.imgWidth + ' '+ setSize.imgHeight,
+ 'margin-bottom': vSpace + 'px'}"
+ >
+ <div v-show="showRefresh" class="verify-refresh" style="z-index:3" @click="refresh">
+ <i class="iconfont icon-refresh" />
+ </div>
+ <img
+ ref="canvas"
+ :src="pointBackImgBase?('data:image/png;base64,'+pointBackImgBase):defaultImg"
+ alt=""
+ style="width:100%;height:100%;display:block"
+ @click="bindingClick?canvasClick($event):undefined"
+ >
+
+ <div
+ v-for="(tempPoint, index) in tempPoints"
+ :key="index"
+ class="point-area"
+ :style="{
+ 'background-color':'#1abd6c',
+ color:'#fff',
+ 'z-index':9999,
+ width:'20px',
+ height:'20px',
+ 'text-align':'center',
+ 'line-height':'20px',
+ 'border-radius': '50%',
+ position:'absolute',
+ top:parseInt(tempPoint.y-10) + 'px',
+ left:parseInt(tempPoint.x-10) + 'px'
+ }"
+ >
+ {{ index + 1 }}
+ </div>
+ </div>
+ </div>
+ <!-- 'height': this.barSize.height, -->
+ <div
+ class="verify-bar-area"
+ :style="{'width': setSize.imgWidth,
+ 'color': this.barAreaColor,
+ 'border-color': this.barAreaBorderColor,
+ 'line-height':this.barSize.height}"
+ >
+ <span class="verify-msg">{{ text }}</span>
+ </div>
+ </div>
+</template>
+<script type="text/babel">
+/**
+ * VerifyPoints
+ * @description 点选
+ * */
+import { resetSize, _code_chars, _code_color1, _code_color2 } from './../utils/util'
+import { aesEncrypt } from './../utils/ase'
+import { reqGet, reqCheck } from './../api/index'
+
+export default {
+ name: 'VerifyPoints',
+ props: {
+ // 弹出式pop,固定fixed
+ mode: {
+ type: String,
+ default: 'fixed'
+ },
+ captchaType: {
+ type: String,
+ },
+ // 间隔
+ vSpace: {
+ type: Number,
+ default: 5
+ },
+ imgSize: {
+ type: Object,
+ default() {
+ return {
+ width: '310px',
+ height: '155px'
+ }
+ }
+ },
+ barSize: {
+ type: Object,
+ default() {
+ return {
+ width: '310px',
+ height: '40px'
+ }
+ }
+ },
+ defaultImg: {
+ type: String,
+ default: ''
+ }
+ },
+ data() {
+ return {
+ secretKey: '', // 后端返回的ase加密秘钥
+ checkNum: 3, // 默认需要点击的字数
+ fontPos: [], // 选中的坐标信息
+ checkPosArr: [], // 用户点击的坐标
+ num: 1, // 点击的记数
+ pointBackImgBase: '', // 后端获取到的背景图片
+ poinTextList: [], // 后端返回的点击字体顺序
+ backToken: '', // 后端返回的token值
+ setSize: {
+ imgHeight: 0,
+ imgWidth: 0,
+ barHeight: 0,
+ barWidth: 0
+ },
+ tempPoints: [],
+ text: '',
+ barAreaColor: undefined,
+ barAreaBorderColor: undefined,
+ showRefresh: true,
+ bindingClick: true
+ }
+ },
+ computed: {
+ resetSize() {
+ return resetSize
+ }
+ },
+ watch: {
+ // type变化则全面刷新
+ type: {
+ immediate: true,
+ handler() {
+ this.init()
+ }
+ }
+ },
+ mounted() {
+ // 禁止拖拽
+ this.$el.onselectstart = function() {
+ return false
+ }
+ },
+ methods: {
+ init() {
+ // 加载页面
+ this.fontPos.splice(0, this.fontPos.length)
+ this.checkPosArr.splice(0, this.checkPosArr.length)
+ this.num = 1
+ this.getPictrue()
+ this.$nextTick(() => {
+ this.setSize = this.resetSize(this) // 重新设置宽度高度
+ this.$parent.$emit('ready', this)
+ })
+ },
+ canvasClick(e) {
+ this.checkPosArr.push(this.getMousePos(this.$refs.canvas, e))
+ if (this.num == this.checkNum) {
+ this.num = this.createPoint(this.getMousePos(this.$refs.canvas, e))
+ // 按比例转换坐标值
+ this.checkPosArr = this.pointTransfrom(this.checkPosArr, this.setSize)
+ // 等创建坐标执行完
+ setTimeout(() => {
+ // var flag = this.comparePos(this.fontPos, this.checkPosArr);
+ // 发送后端请求
+ var captchaVerification = this.secretKey ? aesEncrypt(this.backToken + '---' + JSON.stringify(this.checkPosArr), this.secretKey) : this.backToken + '---' + JSON.stringify(this.checkPosArr)
+ const data = {
+ captchaType: this.captchaType,
+ 'pointJson': this.secretKey ? aesEncrypt(JSON.stringify(this.checkPosArr), this.secretKey) : JSON.stringify(this.checkPosArr),
+ 'token': this.backToken
+ }
+ reqCheck(data).then(res => {
+ if (res.repCode == '0000') {
+ this.barAreaColor = '#4cae4c'
+ this.barAreaBorderColor = '#5cb85c'
+ this.text = '验证成功'
+ this.bindingClick = false
+ if (this.mode == 'pop') {
+ setTimeout(() => {
+ this.$parent.clickShow = false
+ this.refresh()
+ }, 1500)
+ }
+ this.$parent.$emit('success', { captchaVerification })
+ } else {
+ this.$parent.$emit('error', this)
+ this.barAreaColor = '#d9534f'
+ this.barAreaBorderColor = '#d9534f'
+ this.text = '验证失败'
+ setTimeout(() => {
+ this.refresh()
+ }, 700)
+ }
+ })
+ }, 400)
+ }
+ if (this.num < this.checkNum) {
+ this.num = this.createPoint(this.getMousePos(this.$refs.canvas, e))
+ }
+ },
+
+ // 获取坐标
+ getMousePos: function(obj, e) {
+ var x = e.offsetX
+ var y = e.offsetY
+ return { x, y }
+ },
+ // 创建坐标点
+ createPoint: function(pos) {
+ this.tempPoints.push(Object.assign({}, pos))
+ return ++this.num
+ },
+ refresh: function() {
+ this.tempPoints.splice(0, this.tempPoints.length)
+ this.barAreaColor = '#000'
+ this.barAreaBorderColor = '#ddd'
+ this.bindingClick = true
+ this.fontPos.splice(0, this.fontPos.length)
+ this.checkPosArr.splice(0, this.checkPosArr.length)
+ this.num = 1
+ this.getPictrue()
+ this.text = '验证失败'
+ this.showRefresh = true
+ },
+
+ // 请求背景图片和验证图片
+ getPictrue() {
+ const data = {
+ captchaType: this.captchaType,
+ clientUid: localStorage.getItem('point'),
+ ts: Date.now(), // 现在的时间戳
+ }
+ reqGet(data).then(res => {
+ if (res.repCode == '0000') {
+ this.pointBackImgBase = res.repData.originalImageBase64
+ this.backToken = res.repData.token
+ this.secretKey = res.repData.secretKey
+ this.poinTextList = res.repData.wordList
+ this.text = '请依次点击【' + this.poinTextList.join(',') + '】'
+ } else {
+ this.text = res.repMsg
+ }
+
+ // 判断接口请求次数是否失效
+ if (res.repCode == '6201') {
+ this.pointBackImgBase = null
+ }
+ })
+ },
+ // 坐标转换函数
+ pointTransfrom(pointArr, imgSize) {
+ var newPointArr = pointArr.map(p => {
+ const x = Math.round(310 * p.x / parseInt(imgSize.imgWidth))
+ const y = Math.round(155 * p.y / parseInt(imgSize.imgHeight))
+ return { x, y }
+ })
+ // console.log(newPointArr,"newPointArr");
+ return newPointArr
+ }
+ },
+}
+</script>
--
Gitblit v1.9.3