2021-01-22 00:38:54 +08:00

262 lines
9.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/* eslint-disable no-unused-vars */
<template>
<div
style="position: relative"
>
<div class="verify-img-out">
<div
:style="{'width': setSize.imgWidth,
'height': setSize.imgHeight,
'background-size' : setSize.imgWidth + ' '+ setSize.imgHeight,
'margin-bottom': vSpace + 'px'}"
class="verify-img-panel"
>
<div @click="refresh" class="verify-refresh" style="z-index:3" v-show="showRefresh">
<i class="iconfont icon-refresh"></i>
</div>
<img
:src="'data:image/png;base64,'+pointBackImgBase"
@click="bindingClick?canvasClick($event):undefined"
alt=""
ref="canvas"
style="width:100%;height:100%;display:block">
<div
:key="index"
: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'
}"
class="point-area"
v-for="(tempPoint, index) in tempPoints">
{{ index + 1 }}
</div>
</div>
</div>
<!-- 'height': this.barSize.height, -->
<div
:style="{'width': setSize.imgWidth,
'color': this.barAreaColor,
'border-color': this.barAreaBorderColor,
'line-height':this.barSize.height}"
class="verify-bar-area">
<span class="verify-msg">{{ text }}</span>
</div>
</div>
</template>
<script type="text/babel">
/**
* VerifyPoints
* @description 点选
* */
// _code_chars, _code_color1, _code_color2
import { resetSize } 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'
},
// eslint-disable-next-line vue/require-default-prop
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'
}
}
}
},
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
}
},
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))
// eslint-disable-next-line eqeqeq
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 => {
// eslint-disable-next-line eqeqeq
if (res.repCode == '0000') {
this.barAreaColor = '#4cae4c'
this.barAreaBorderColor = '#5cb85c'
this.text = '验证成功'
this.bindingClick = false
// eslint-disable-next-line eqeqeq
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
}
reqGet(data).then(res => {
// eslint-disable-next-line eqeqeq
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
}
})
},
// 坐标转换函数
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
}
},
watch: {
// type变化则全面刷新
type: {
immediate: true,
handler() {
this.init()
}
}
},
mounted() {
// 禁止拖拽
this.$el.onselectstart = function () {
return false
}
}
}
</script>