inleft
2022-02-09 9bcb19959eeb9da9bde2561e7278f6d0a55eb151
commit | author | age
9bcb19 1 /* eslint-disable no-unused-vars */
I 2 <template>
3   <div
4     style="position: relative"
5   >
6     <div class="verify-img-out">
7       <div
8         :style="{'width': setSize.imgWidth,
9                  'height': setSize.imgHeight,
10                  'background-size' : setSize.imgWidth + ' '+ setSize.imgHeight,
11                  'margin-bottom': vSpace + 'px'}"
12         class="verify-img-panel"
13       >
14         <div @click="refresh" class="verify-refresh" style="z-index:3" v-show="showRefresh">
15           <i class="iconfont icon-refresh"></i>
16         </div>
17         <img
18           :src="'data:image/png;base64,'+pointBackImgBase"
19           @click="bindingClick?canvasClick($event):undefined"
20           alt=""
21           ref="canvas"
22           style="width:100%;height:100%;display:block">
23
24         <div
25           :key="index"
26           :style="{
27             'background-color':'#1abd6c',
28             color:'#fff',
29             'z-index':9999,
30             width:'20px',
31             height:'20px',
32             'text-align':'center',
33             'line-height':'20px',
34             'border-radius': '50%',
35             position:'absolute',
36             top:parseInt(tempPoint.y-10) + 'px',
37             left:parseInt(tempPoint.x-10) + 'px'
38           }"
39           class="point-area"
40           v-for="(tempPoint, index) in tempPoints">
41           {{ index + 1 }}
42         </div>
43       </div>
44     </div>
45     <!-- 'height': this.barSize.height, -->
46     <div
47       :style="{'width': setSize.imgWidth,
48                'color': this.barAreaColor,
49                'border-color': this.barAreaBorderColor,
50                'line-height':this.barSize.height}"
51       class="verify-bar-area">
52       <span class="verify-msg">{{ text }}</span>
53     </div>
54   </div>
55 </template>
56 <script type="text/babel">
57     /**
58      * VerifyPoints
59      * @description 点选
60      * */
61     import { resetSize } from './../utils/util'
62     import { aesEncrypt } from './../utils/ase'
63     import { reqGet, reqCheck } from '@/api/modular/system/loginManage'
64
65     export default {
66         name: 'VerifyPoints',
67         props: {
68             // 弹出式pop,固定fixed
69             mode: {
70                 type: String,
71                 default: 'fixed'
72             },
73             // eslint-disable-next-line vue/require-default-prop
74             captchaType: {
75                 type: String
76             },
77             // 间隔
78             vSpace: {
79                 type: Number,
80                 default: 5
81             },
82             imgSize: {
83                 type: Object,
84                 default() {
85                     return {
86                         width: '310px',
87                         height: '155px'
88                     }
89                 }
90             },
91             barSize: {
92                 type: Object,
93                 default() {
94                     return {
95                         width: '310px',
96                         height: '40px'
97                     }
98                 }
99             }
100         },
101         data() {
102             return {
103                 secretKey: '', // 后端返回的ase加密秘钥
104                 checkNum: 3, // 默认需要点击的字数
105                 fontPos: [], // 选中的坐标信息
106                 checkPosArr: [], // 用户点击的坐标
107                 num: 1, // 点击的记数
108                 pointBackImgBase: '', // 后端获取到的背景图片
109                 poinTextList: [], // 后端返回的点击字体顺序
110                 backToken: '', // 后端返回的token值
111                 setSize: {
112                     imgHeight: 0,
113                     imgWidth: 0,
114                     barHeight: 0,
115                     barWidth: 0
116                 },
117                 tempPoints: [],
118                 text: '',
119                 barAreaColor: undefined,
120                 barAreaBorderColor: undefined,
121                 showRefresh: true,
122                 bindingClick: true
123             }
124         },
125         computed: {
126             resetSize() {
127                 return resetSize
128             }
129         },
130         methods: {
131             init() {
132                 // 加载页面
133                 this.fontPos.splice(0, this.fontPos.length)
134                 this.checkPosArr.splice(0, this.checkPosArr.length)
135                 this.num = 1
136                 this.getPictrue()
137                 this.$nextTick(() => {
138                     this.setSize = this.resetSize(this)    // 重新设置宽度高度
139                     this.$parent.$emit('ready', this)
140                 })
141             },
142             canvasClick(e) {
143                 this.checkPosArr.push(this.getMousePos(this.$refs.canvas, e))
144                 // eslint-disable-next-line eqeqeq
145                 if (this.num == this.checkNum) {
146                     this.num = this.createPoint(this.getMousePos(this.$refs.canvas, e))
147                     // 按比例转换坐标值
148                     this.checkPosArr = this.pointTransfrom(this.checkPosArr, this.setSize)
149                     // 等创建坐标执行完
150                     setTimeout(() => {
151                         // var flag = this.comparePos(this.fontPos, this.checkPosArr);
152                         // 发送后端请求
153                         var captchaVerification = this.secretKey ? aesEncrypt(this.backToken + '---' + JSON.stringify(this.checkPosArr), this.secretKey) : this.backToken + '---' + JSON.stringify(this.checkPosArr)
154                         const data = {
155                             captchaType: this.captchaType,
156                             'pointJson': this.secretKey ? aesEncrypt(JSON.stringify(this.checkPosArr), this.secretKey) : JSON.stringify(this.checkPosArr),
157                             'token': this.backToken
158                         }
159                         reqCheck(data).then(res => {
160                             // eslint-disable-next-line eqeqeq
161                             if (res.repCode == '0000') {
162                                 this.barAreaColor = '#4cae4c'
163                                 this.barAreaBorderColor = '#5cb85c'
164                                 this.text = '验证成功'
165                                 this.bindingClick = false
166                                 // eslint-disable-next-line eqeqeq
167                                 if (this.mode == 'pop') {
168                                     setTimeout(() => {
169                                         this.$parent.clickShow = false
170                                         this.refresh()
171                                     }, 1500)
172                                 }
173                                 this.$parent.$emit('success', { captchaVerification })
174                             } else {
175                                 this.$parent.$emit('error', this)
176                                 this.barAreaColor = '#d9534f'
177                                 this.barAreaBorderColor = '#d9534f'
178                                 this.text = '验证失败'
179                                 setTimeout(() => {
180                                     this.refresh()
181                                 }, 700)
182                             }
183                         })
184                     }, 400)
185                 }
186                 if (this.num < this.checkNum) {
187                     this.num = this.createPoint(this.getMousePos(this.$refs.canvas, e))
188                 }
189             },
190
191             // 获取坐标
192             getMousePos: function (obj, e) {
193                 var x = e.offsetX
194                 var y = e.offsetY
195                 return { x, y }
196             },
197             // 创建坐标点
198             createPoint: function (pos) {
199                 this.tempPoints.push(Object.assign({}, pos))
200                 return ++this.num
201             },
202             refresh: function () {
203                 this.tempPoints.splice(0, this.tempPoints.length)
204                 this.barAreaColor = '#000'
205                 this.barAreaBorderColor = '#ddd'
206                 this.bindingClick = true
207                 this.fontPos.splice(0, this.fontPos.length)
208                 this.checkPosArr.splice(0, this.checkPosArr.length)
209                 this.num = 1
210                 this.getPictrue()
211                 this.text = '验证失败'
212                 this.showRefresh = true
213             },
214
215             // 请求背景图片和验证图片
216             getPictrue() {
217                 const data = {
218                     captchaType: this.captchaType
219                 }
220                 reqGet(data).then(res => {
221                     // eslint-disable-next-line eqeqeq
222                     if (res.repCode == '0000') {
223                         this.pointBackImgBase = res.repData.originalImageBase64
224                         this.backToken = res.repData.token
225                         this.secretKey = res.repData.secretKey
226                         this.poinTextList = res.repData.wordList
227                         this.text = '请依次点击【' + this.poinTextList.join(',') + '】'
228                     } else {
229                         this.text = res.repMsg
230                     }
231                 })
232             },
233             // 坐标转换函数
234             pointTransfrom(pointArr, imgSize) {
235                 var newPointArr = pointArr.map(p => {
236                     const x = Math.round(310 * p.x / parseInt(imgSize.imgWidth))
237                     const y = Math.round(155 * p.y / parseInt(imgSize.imgHeight))
238                     return { x, y }
239                 })
240                 // console.log(newPointArr,"newPointArr");
241                 return newPointArr
242             }
243         },
244         watch: {
245             // type变化则全面刷新
246             type: {
247                 immediate: true,
248                 handler() {
249                     this.init()
250                 }
251             }
252         },
253         mounted() {
254             // 禁止拖拽
255             this.$el.onselectstart = function () {
256                 return false
257             }
258         }
259     }
260 </script>