123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293 |
- <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';
- 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,
- };
- this.$axios.$post('activity/captcha/check', 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(), // 现在的时间戳
- };
- this.$axios.$post('/captcha/get', data).then((res) => {
- console.log(res);
- if (res.repCode == '0000') {
- console.log(123456);
- 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>
|