| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553 |
- <template>
- <view style="position: relative">
- <view class="verify-image-out" v-show="showImage">
- <view class="verify-image-panel" :style="{'width': imgSize.width,
- 'height': imgSize.height,
- 'margin-bottom': vSpace + 'px'}">
- <view class="verify-refresh" style="z-index:3" @click="refresh" v-show="showRefresh">
- <text class="iconfont icon-refresh"></text>
- </view>
- <image :src="pointBackImgBase?('data:image/png;base64,'+pointBackImgBase):defaultImg" id="image"
- ref="canvas" style="width:100%;height:100%;display:block"
- @click=" bindingClick? canvasClick($event): undefined"></image>
- <view 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}}
- </view>
- </view>
- </view>
- <!-- 'height': this.barSize.height, -->
- <view class="verify-bar-area" :style="{'width': imgSize.width,
- 'color': barAreaColor,
- 'border-color': barAreaBorderColor,
- 'line-height':'40px'}">
- <text class="verify-msg">{{text}}</text>
- </view>
- </view>
- </template>
- <script type="text/babel">
- // +----------------------------------------------------------------------
- // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
- // +----------------------------------------------------------------------
- // | Copyright (c) 2016~2024 https://www.crmeb.com All rights reserved.
- // +----------------------------------------------------------------------
- // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
- // +----------------------------------------------------------------------
- // | Author: CRMEB Team <admin@crmeb.com>
- // +----------------------------------------------------------------------
- /**
- * VerifyPoints
- * @description 点选
- * */
- import {aesEncrypt} from "./../utils/ase.js"
- import {getAjcaptcha,ajcaptchaCheck} from '@/api/api.js';
-
- 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:'', //后端返回的加密秘钥 字段
- checkNum:3, //
- fontPos: [], // 选中的坐标信息
- checkPosArr: [], //用户点击的坐标
- num: 1, //点击的记数
- pointBackImgBase:'', //后端获取到的背景图片
- poinTextList:[], //后端返回的点击字体顺序
- backToken:'', //后端返回的token值
- imgRand: 0, //随机的背景图片
- setSize: {
- imgHeight: 0,
- imgWidth: 0,
- barHeight: 0,
- barWidth: 0
- },
- showImage: true,
- tempPoints: [],
- text: '',
- barAreaColor: '#fff',
- barAreaBorderColor: "#fff",
- showRefresh: true,
- bindingClick: true,
- imgLeft:'' ,
- imgTop:'',
- }
- },
- methods: {
- init() {
- //加载页面
- this.fontPos.splice(0, this.fontPos.length)
- this.checkPosArr.splice(0, this.checkPosArr.length)
- this.num = 1
- this.$nextTick(() => {
- this.refresh();
- this.$parent.$emit('ready', this)
- })
- },
- canvasClick(e) {
- const query = uni.createSelectorQuery().in(this);
- query.select('#image').boundingClientRect(data => {
- this.imgLeft =Math.ceil(data.left)
- this.imgTop =Math.ceil(data.top)
- 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.imgSize);
- //等创建坐标执行完
- setTimeout(() => {
- //发送后端请求
- var captchaVerification =this.secretKey? aesEncrypt(this.backToken+'---'+JSON.stringify(this.checkPosArr),this.secretKey):this.backToken+'---'+JSON.stringify(this.checkPosArr)
- let data = {
- captchaType:this.captchaType,
- "pointJson":this.secretKey? aesEncrypt(JSON.stringify(this.checkPosArr),this.secretKey):JSON.stringify(this.checkPosArr),
- "token":this.backToken
- }
- ajcaptchaCheck(data).then(result => {
- let res = result.data
- this.barAreaColor = '#4cae4c'
- this.barAreaBorderColor = '#5cb85c'
- this.text = '验证成功'
- this.bindingClick = false
- setTimeout(()=>{
- if (this.mode=='pop') {
- this.$parent.clickShow = false;
- }
- this.refresh();
- },1500)
- this.$parent.$emit('success', {captchaVerification})
- }).catch(res=>{
- 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));
- }
- }).exec();
- },
- //获取坐标
- getMousePos: function (obj, e) {
- let position = {
- x:Math.ceil(e.detail.x)-this.imgLeft,
- y:Math.ceil(e.detail.y)-this.imgTop,
- }
- return position
- },
- //创建坐标点
- 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(){
- let data = {
- captchaType:this.captchaType,
- clientUid: uni.getStorageSync('point'),
- ts: Date.now(), // 现在的时间戳
- }
- getAjcaptcha(data).then((result) => {
- let res = result.data
- this.pointBackImgBase = res.originalImageBase64
- this.backToken = res.token
- this.secretKey = res.secretKey
- this.poinTextList = res.wordList
- this.text = '请依次点击【' + this.poinTextList.join(",") + '】'
- }).catch(()=>{
- this.pointBackImgBase = null
- })
- },
- //坐标转换函数
- pointTransfrom(pointArr,imgSize){
- var newPointArr = pointArr.map(p=>{
- let x = Math.round(310 * p.x/parseInt(imgSize.width))
- let y =Math.round(155 * p.y/parseInt(imgSize.height))
- return {x,y}
- })
- // console.log(newPointArr,"newPointArr");
- return newPointArr
- },
- },
- watch: {
- // type变化则全面刷新
- type: {
- immediate: true,
- handler() {
- this.init()
- }
- }
- },
- mounted() {
- console.log(this.defaultImg)
- }
- }
- </script>
- <style scoped>
- .verifybox {
- position: relative;
- box-sizing: border-box;
- border-radius: 2px;
- border: 1px solid #e4e7eb;
- background-color: #fff;
- box-shadow: 0 0 10px rgba(0, 0, 0, .3);
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
- }
- .verifybox-top {
- padding: 0 15px;
- height: 50px;
- line-height: 50px;
- text-align: left;
- font-size: 16px;
- color: #45494c;
- border-bottom: 1px solid #e4e7eb;
- box-sizing: border-box;
- }
- .verifybox-bottom {
- /* padding: 15px; */
- box-sizing: border-box;
- }
- .verifybox-close {
- position: absolute;
- top: 13px;
- right: 9px;
- width: 24px;
- height: 24px;
- text-align: center;
- cursor: pointer;
- }
- .mask {
- position: fixed;
- top: 0;
- left: 0;
- z-index: 1001;
- width: 100%;
- height: 100vh;
- background: rgba(0, 0, 0, .3);
- /* display: none; */
- transition: all .5s;
- }
- .verify-tips {
- position: absolute;
- left: 0px;
- bottom: 0px;
- width: 100%;
- height: 30px;
- background-color: rgb(231, 27, 27, .5);
- line-height: 30px;
- color: #fff;
- }
- .tips-enter,
- .tips-leave-to {
- bottom: -30px;
- }
- .tips-enter-active,
- .tips-leave-active {
- transition: bottom .5s;
- }
- /* ---------------------------- */
- /*常规验证码*/
- .verify-code {
- font-size: 20px;
- text-align: center;
- cursor: pointer;
- margin-bottom: 5px;
- border: 1px solid #ddd;
- }
- .cerify-code-panel {
- height: 100%;
- overflow: hidden;
- }
- .verify-code-area {
- float: left;
- }
- .verify-input-area {
- float: left;
- width: 60%;
- padding-right: 10px;
- }
- .verify-change-area {
- line-height: 30px;
- float: left;
- }
- .varify-input-code {
- display: inline-block;
- width: 100%;
- height: 25px;
- }
- .verify-change-code {
- color: #337AB7;
- cursor: pointer;
- }
- .verify-btn {
- width: 200px;
- height: 30px;
- background-color: #337AB7;
- color: #FFFFFF;
- border: none;
- margin-top: 10px;
- }
- /*滑动验证码*/
- .verify-bar-area {
- position: relative;
- background: #FFFFFF;
- text-align: center;
- -webkit-box-sizing: content-box;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
- border: 1px solid #ddd;
- -webkit-border-radius: 4px;
- }
- .verify-bar-area .verify-move-block {
- position: absolute;
- top: 0px;
- left: 0;
- background: #fff;
- cursor: pointer;
- -webkit-box-sizing: content-box;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
- box-shadow: 0 0 2px #888888;
- -webkit-border-radius: 1px;
- }
- .verify-bar-area .verify-move-block:hover {
- background-color: #337ab7;
- color: #FFFFFF;
- }
- .verify-bar-area .verify-left-bar {
- position: absolute;
- top: -1px;
- left: -1px;
- background: #f0fff0;
- cursor: pointer;
- -webkit-box-sizing: content-box;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
- border: 1px solid #ddd;
- }
- .verify-image-panel {
- margin: 0;
- -webkit-box-sizing: content-box;
- -moz-box-sizing: content-box;
- box-sizing: content-box;
- border-top: 1px solid #ddd;
- border-bottom: 1px solid #ddd;
- border-radius: 3px;
- position: relative;
- }
- .verify-image-panel .verify-refresh {
- width: 25px;
- height: 25px;
- text-align: center;
- padding: 5px;
- cursor: pointer;
- position: absolute;
- top: 0;
- right: 0;
- z-index: 2;
- }
- .verify-image-panel .icon-refresh {
- font-size: 20px;
- color: #fff;
- }
- .verify-image-panel .verify-gap {
- background-color: #fff;
- position: relative;
- z-index: 2;
- border: 1px solid #fff;
- }
- .verify-bar-area .verify-move-block .verify-sub-block {
- position: absolute;
- text-align: center;
- z-index: 3;
- /* border: 1px solid #fff; */
- }
- .verify-bar-area .verify-move-block .verify-icon {
- width: 80rpx;
- height: 80rpx;
- font-size: 18px;
- }
- .verify-bar-area .verify-msg {
- z-index: 3;
- }
- /*字体图标的css*/
- /*@font-face {font-family: "iconfont";*/
- /*src: url('../fonts/iconfont.eot?t=1508229193188'); !* IE9*!*/
- /*src: url('../fonts/iconfont.eot?t=1508229193188#iefix') format('embedded-opentype'), !* IE6-IE8 *!*/
- /*url('data:application/x-font-woff;charset=utf-8;base64,d09GRgABAAAAAAaAAAsAAAAACUwAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABHU1VCAAABCAAAADMAAABCsP6z7U9TLzIAAAE8AAAARAAAAFZW7kiSY21hcAAAAYAAAAB3AAABuM+qBlRnbHlmAAAB+AAAAnQAAALYnrUwT2hlYWQAAARsAAAALwAAADYPNwajaGhlYQAABJwAAAAcAAAAJAfeA4dobXR4AAAEuAAAABMAAAAYF+kAAGxvY2EAAATMAAAADgAAAA4CvAGsbWF4cAAABNwAAAAfAAAAIAEVAF1uYW1lAAAE/AAAAUUAAAJtPlT+fXBvc3QAAAZEAAAAPAAAAE3oPPXPeJxjYGRgYOBikGPQYWB0cfMJYeBgYGGAAJAMY05meiJQDMoDyrGAaQ4gZoOIAgCKIwNPAHicY2Bk/sM4gYGVgYOpk+kMAwNDP4RmfM1gxMjBwMDEwMrMgBUEpLmmMDgwVDxbwtzwv4EhhrmBoQEozAiSAwAw1A0UeJzFkcENgCAMRX8RjCGO4gTe9eQcnhzAfXC2rqG/hYsT8MmD9gdS0gJIAAaykAjIBYHppCvuD8juR6zMJ67A89Zdn/f1aNPikUn8RvYo8G20CjKim6Rf6b9m34+WWd/vBr+oW8V6q3vF5qKlYrPRp4L0Ad5nGL8AeJxFUc9rE0EYnTezu8lMsrvtbrqb3TRt0rS7bdOmdI0JbWmCtiItIv5oi14qevCk9SQVLFiQgqAF8Q9QLKIHLx48FkHo3ZNnFUXwD5C2B6dO6sFhmI83w7z3fe8RnZCjb2yX5YlLhskkmScXCIFRxYBFiyjH9Rqtoqes9/g5i8WVuJyqDNTYLPwBI+cljXrkGynDhoU+nCgnjbhGY5yst+gMEq8IBIXwsjPU67CnEPm4b0su0h309Fd67da4XBhr55KSm17POk7gOE/Shq6nKdVsC7d9j+tcGPKVboc9u/0jtB/ZIA7PXTVLBef6o/paccjnwOYm3ELJetPuDrvV3gg91wlSXWY6H5qVwRzWf2TybrYYfSdqoXOwh/Qa8RWIjBTiSI3h614/vKSNRhONOrsnQi6Xf4nQFQDTmJE1NKbhI6crHEJO/+S5QPxhYJRRyvBFBP+5T9EPpEAIVzzRQIrjmJ6jY1WTo+NXTMchuBsKuS8PRZATSMl9oTA4uNLkeIA0V1UeqOoGQh7IAxGo+7T83fn3T+voqCNPPAUazUYUI7LgKSV1Jk2oUeghYGhZ+cKOe2FjVu5ZKEY2VkE13AK1+jI4r1KLbPlZfrKiPhOXKPRj7q9sj9XJ7LFHNmrKJS3VCdhXGSdKrtmoQaWeMjQVt0KD6sGPOx0oH2fgtzoNROxtNq8F3tzYM/n+TjKSX5qf2jx941276TIr9FjXxKr8eX/6bK4yuopwo9py1sw8F9kdw4AmurRpLUM3tYx5ZnKpfHPi8dzz19vJ6MjyxYUrpqeb1uLs3eGV6vr21pSqpeWkqonAN9oUyIiXpv8XvlN5e3icY2BkYGAA4n0vN4fG89t8ZeBmYQCBa9wPPRH0/wcsDMwmQC4HAxNIFABAfAqaAHicY2BkYGBu+N/AEMPCAAJAkpEBFbABAEcMAm94nGNhYGBgfsnAwMKAigESnwEBAAAAAAAAdgCkANoBCAFsAAB4nGNgZGBgYGMIZGBlAAEmIOYCQgaG/2A+AwARSAFzAHicZY9NTsMwEIVf+gekEqqoYIfkBWIBKP0Rq25YVGr3XXTfpk6bKokjx63UA3AejsAJOALcgDvwSCebNpbH37x5Y08A3OAHHo7fLfeRPVwyO3INF7gXrlN/EG6QX4SbaONVuEX9TdjHM6bCbXRheYPXuGL2hHdhDx18CNdwjU/hOvUv4Qb5W7iJO/wKt9Dx6sI+5l5XuI1HL/bHVi+cXqnlQcWhySKTOb+CmV7vkoWt0uqca1vEJlODoF9JU51pW91T7NdD5yIVWZOqCas6SYzKrdnq0AUb5/JRrxeJHoQm5Vhj/rbGAo5xBYUlDowxQhhkiMro6DtVZvSvsUPCXntWPc3ndFsU1P9zhQEC9M9cU7qy0nk6T4E9XxtSdXQrbsuelDSRXs1JErJCXta2VELqATZlV44RelzRiT8oZ0j/AAlabsgAAAB4nGNgYoAALgbsgI2RiZGZkYWRlZGNkZ2BsYI1OSM1OZs1OSe/OJW1KDM9o4S9KDWtKLU4g4EBAJ79CeQ=') format('woff'),*/
- /*url('../fonts/iconfont.ttf?t=1508229193188') format('truetype'), !* chrome, firefox, opera, Safari, Android, iOS 4.2+*!*/
- /*url('../fonts/iconfont.svg?t=1508229193188#iconfont') format('svg'); !* iOS 4.1- *!*/
- /*}*/
- .iconfont {
- font-family: "iconfont" !important;
- font-size: 16px;
- font-style: normal;
- -webkit-font-smoothing: antialiased;
- -moz-osx-font-smoothing: grayscale;
- }
- .icon-check:before {
- content: " ";
- display: block;
- width: 16px;
- height: 16px;
- position: absolute;
- margin: auto;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- z-index: 9999;
- background-image: url("@/static/images/arrow-good.png");
- background-size: contain;
- }
- .icon-close:before {
- content: " ";
- display: block;
- width: 16px;
- height: 16px;
- position: absolute;
- margin: auto;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- z-index: 9999;
- background-image: url("@/static/images/arrow-close.png");
- background-size: contain;
- }
- .icon-right:before {
- content: " ";
- display: block;
- width: 16px;
- height: 16px;
- position: absolute;
- margin: auto;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- background-size: cover;
- z-index: 9999;
- background-image: url("@/static/images/arrow-right.png");
- background-size: contain;
- }
- .icon-refresh:before {
- content: " ";
- display: block;
- width: 16px;
- height: 16px;
- position: absolute;
- margin: auto;
- left: 0;
- right: 0;
- top: 0;
- bottom: 0;
- z-index: 9999;
- background-image: url("@/static/images/refresh.png");
- background-size: contain;
- }
- </style>
|