You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

269 lines
7.6 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<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: {
// popfixed
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>