/*! Verify&admin MIT License by anji-plus*/ /*! J2eeFAST 优化兼容IE浏览器*/ (function ($, window, document, undefined) { // 初始话 uuid uuid(); function uuid() { var s = []; var hexDigits = "0123456789abcdef"; for (var i = 0; i < 36; i++) { s[i] = hexDigits.substr(Math.floor(Math.random() * 0x10), 1); } s[14] = "4"; // bits 12-15 of the time_hi_and_version field to 0010 s[19] = hexDigits.substr((s[19] & 0x3) | 0x8, 1); // bits 6-7 of the clock_seq_hi_and_reserved to 01 s[8] = s[13] = s[18] = s[23] = "-"; var slider = "slider" + "-" + s.join(""); var point = "point" + "-" + s.join(""); var uid = "uid" + "-" + s.join(""); // 判断下是否存在 slider point uid if (!localStorage.getItem("slider")) { localStorage.setItem("slider", slider); } if (!localStorage.getItem("point")) { localStorage.setItem("point", point); } if (!localStorage.getItem("uid")) { localStorage.setItem("uid", uid); } } var startX, startY; document.addEventListener("touchstart", function (e) { startX = e.targetTouches[0].pageX; startY = e.targetTouches[0].pageY; }); document.addEventListener( "touchmove", function (e) { var moveX = e.targetTouches[0].pageX; var moveY = e.targetTouches[0].pageY; if (Math.abs(moveX - startX) > Math.abs(moveY - startY)) { // e.preventDefault(); } }, { passive: false } ); //请求图片get事件 function getPictrue(data, baseUrl, resolve, reject) { $.ajax({ type: "post", contentType: "application/json;charset=UTF-8", url: baseUrl + "/captcha/get", data: JSON.stringify(data), cache: false, crossDomain: true == !document.all, success: function (res) { resolve(res); }, fail: function (err) { reject(err); }, }); } //验证图片check事件 function checkPictrue(data, baseUrl, resolve, reject) { $.ajax({ type: "post", contentType: "application/json;charset=UTF-8", url: baseUrl + "/captcha/check", data: JSON.stringify(data), cache: false, crossDomain: true == !document.all, success: function (res) { resolve(res); }, fail: function (err) { reject(err); }, }); } //定义Slide的构造函数 var Slide = function (ele, opt) { (this.$element = ele), (this.backToken = null), (this.moveLeftDistance = 0), (this.secretKey = ""), (this.defaults = { baseUrl: "https://captcha.anji-plus.com/captcha-api", containerId: "", captchaType: "blockPuzzle", mode: "fixed", //弹出式pop,固定fixed vOffset: 5, vSpace: 5, explain: "向右滑动完成验证", imgSize: { width: "310px", height: "155px", }, blockSize: { width: "50px", height: "50px", }, circleRadius: "10px", barSize: { width: "310px", height: "50px", }, beforeCheck: function () { return true; }, ready: function () {}, success: function () {}, error: function () {}, }), (this.options = $.extend({}, this.defaults, opt)); }; //定义Slide的方法 Slide.prototype = { init: function () { var _this = this; //加载页面 this.loadDom(); _this.refresh(); this.options.ready(); this.$element[0].onselectstart = document.body.ondrag = function () { return false; }; if (this.options.mode == "pop") { _this.$element.find(".verifybox-close").on("click", function () { _this.$element.find(".mask").css("display", "none"); _this.refresh(); }); var clickBtn = document.getElementById(this.options.containerId); clickBtn && (clickBtn.onclick = function () { if (_this.options.beforeCheck()) { _this.$element.find(".mask").css("display", "block"); } }); } //按下 this.htmlDoms.move_block.on("touchstart", function (e) { _this.start(e); }); this.htmlDoms.move_block.on("mousedown", function (e) { _this.start(e); }); this.htmlDoms.sub_block.on("mousedown", function (e) { e.stopPropagation(); }); //拖动 window.addEventListener("touchmove", function (e) { _this.move(e); }); window.addEventListener("mousemove", function (e) { _this.move(e); }); //鼠标松开 window.addEventListener("touchend", function () { _this.end(); }); window.addEventListener("mouseup", function () { _this.end(); }); //刷新 _this.$element.find(".verify-refresh").on("click", function () { _this.refresh(); }); }, //初始化加载 loadDom: function () { this.status = false; //鼠标状态 this.isEnd = false; //是够验证完成 this.setSize = this.resetSize(this); //重新设置宽度高度 this.plusWidth = 0; this.plusHeight = 0; this.x = 0; this.y = 0; var panelHtml = ""; var wrapHtml = ""; this.lengthPercent = (parseInt(this.setSize.img_width) - parseInt(this.setSize.block_width) - parseInt(this.setSize.circle_radius) - parseInt(this.setSize.circle_radius) * 0.8) / (parseInt(this.setSize.img_width) - parseInt(this.setSize.bar_height)); wrapStartHtml = '
' + '
' + '
' + "请完成安全验证" + '' + '' + "" + "
" + '
' + '
'; if (this.options.mode == "pop") { panelHtml = wrapStartHtml; } panelHtml += '
' + '
' + '
' + '' + "
" + '' + '' + "
" + "
"; this.plusWidth = parseInt(this.setSize.block_width) + parseInt(this.setSize.circle_radius) * 2 - parseInt(this.setSize.circle_radius) * 0.2; this.plusHeight = parseInt(this.setSize.block_height) + parseInt(this.setSize.circle_radius) * 2 - parseInt(this.setSize.circle_radius) * 0.2; panelHtml += '
' + '' + this.options.explain + "" + '
' + '' + '
' + '' + '
' + '' + "
" + "
" + "
" + "
"; wrapEndHtml = "
"; if (this.options.mode == "pop") { panelHtml += wrapEndHtml; } this.$element.append(panelHtml); this.htmlDoms = { tips: this.$element.find(".verify-tips"), sub_block: this.$element.find(".verify-sub-block"), out_panel: this.$element.find(".verify-img-out"), img_panel: this.$element.find(".verify-img-panel"), img_canvas: this.$element.find(".verify-img-canvas"), bar_area: this.$element.find(".verify-bar-area"), move_block: this.$element.find(".verify-move-block"), left_bar: this.$element.find(".verify-left-bar"), msg: this.$element.find(".verify-msg"), icon: this.$element.find(".verify-icon"), refresh: this.$element.find(".verify-refresh"), }; this.$element.css("position", "relative"); this.htmlDoms.sub_block.css({ height: this.setSize.img_height, width: Math.floor((parseInt(this.setSize.img_width) * 47) / 310) + "px", top: -(parseInt(this.setSize.img_height) + this.options.vSpace) + "px", }); this.htmlDoms.out_panel.css("height", parseInt(this.setSize.img_height) + this.options.vSpace + "px"); this.htmlDoms.img_panel.css({ width: this.setSize.img_width, height: this.setSize.img_height }); this.htmlDoms.bar_area.css({ width: this.setSize.img_width, height: this.setSize.bar_height, "line-height": this.setSize.bar_height }); this.htmlDoms.move_block.css({ width: this.setSize.bar_height, height: this.setSize.bar_height }); this.htmlDoms.left_bar.css({ width: this.setSize.bar_height, height: this.setSize.bar_height }); }, //鼠标按下 start: function (e) { if (!e.originalEvent.targetTouches) { //兼容移动端 var x = e.clientX; } else { //兼容PC端 var x = e.originalEvent.targetTouches[0].pageX; } // if(!e.touches) { //兼容移动端 // var x = e.clientX; // }else { //兼容PC端 // var x = e.touches[0].pageX; // } this.startLeft = Math.floor(x - this.htmlDoms.bar_area[0].getBoundingClientRect().left); this.startMoveTime = new Date().getTime(); if (this.isEnd == false) { this.htmlDoms.msg.text(""); this.htmlDoms.move_block.css("background-color", "#337ab7"); this.htmlDoms.left_bar.css("border-color", "#337AB7"); this.htmlDoms.icon.css("color", "#fff"); e.stopPropagation(); this.status = true; } }, //鼠标移动 move: function (e) { if (this.status && this.isEnd == false) { if (!e.touches) { //兼容移动端 var x = e.clientX; } else { //兼容PC端 var x = e.touches[0].pageX; } var bar_area_left = this.htmlDoms.bar_area[0].getBoundingClientRect().left; var move_block_left = x - bar_area_left; //小方块相对于父元素的left值 if (move_block_left >= this.htmlDoms.bar_area[0].offsetWidth - parseInt(this.setSize.bar_height) + parseInt(parseInt(this.setSize.block_width) / 2) - 2) { move_block_left = this.htmlDoms.bar_area[0].offsetWidth - parseInt(this.setSize.bar_height) + parseInt(parseInt(this.setSize.block_width) / 2) - 2; } if (move_block_left <= parseInt(parseInt(this.setSize.block_width) / 2)) { move_block_left = parseInt(parseInt(this.setSize.block_width) / 2); } //拖动后小方块的left值 this.htmlDoms.move_block.css("left", move_block_left - this.startLeft + "px"); this.htmlDoms.left_bar.css("width", move_block_left - this.startLeft + "px"); this.htmlDoms.sub_block.css("left", "0px"); this.moveLeftDistance = move_block_left - this.startLeft; } }, //鼠标松开 end: function () { this.endMovetime = new Date().getTime(); var _this = this; //判断是否重合 if (this.status && this.isEnd == false) { var vOffset = parseInt(this.options.vOffset); this.moveLeftDistance = (this.moveLeftDistance * 310) / parseInt(this.setSize.img_width); //图片滑动 var data = { captchaType: this.options.captchaType, pointJson: this.secretKey ? aesEncrypt(JSON.stringify({ x: this.moveLeftDistance, y: 5.0 }), this.secretKey) : JSON.stringify({ x: this.moveLeftDistance, y: 5.0 }), token: this.backToken, clientUid: localStorage.getItem("slider"), ts: Date.now(), }; var captchaVerification = this.secretKey ? aesEncrypt(this.backToken + "---" + JSON.stringify({ x: this.moveLeftDistance, y: 5.0 }), this.secretKey) : this.backToken + "---" + JSON.stringify({ x: this.moveLeftDistance, y: 5.0 }); checkPictrue(data, this.options.baseUrl, function (res) { // 请求反正成功的判断 if (res.repCode == "0000") { _this.htmlDoms.move_block.css("background-color", "#5cb85c"); _this.htmlDoms.left_bar.css({ "border-color": "#5cb85c", "background-color": "#fff" }); _this.htmlDoms.icon.css("color", "#fff"); _this.htmlDoms.icon.removeClass("icon-right"); _this.htmlDoms.icon.addClass("icon-check"); //提示框 _this.htmlDoms.tips.addClass("suc-bg").removeClass("err-bg"); // _this.htmlDoms.tips.css({"display":"block",animation:"move 1s cubic-bezier(0, 0, 0.39, 1.01)"}); _this.htmlDoms.tips.animate({ bottom: "0px" }); _this.htmlDoms.tips.text(((_this.endMovetime - _this.startMoveTime) / 1000).toFixed(2) + "s验证成功"); _this.isEnd = true; setTimeout(function () { _this.$element.find(".mask").css("display", "none"); // _this.htmlDoms.tips.css({"display":"none",animation:"none"}); _this.htmlDoms.tips.animate({ bottom: "-35px" }); _this.refresh(); }, 1000); _this.options.success({ captchaVerification: captchaVerification }); } else { _this.htmlDoms.move_block.css("background-color", "#d9534f"); _this.htmlDoms.left_bar.css("border-color", "#d9534f"); _this.htmlDoms.icon.css("color", "#fff"); _this.htmlDoms.icon.removeClass("icon-right"); _this.htmlDoms.icon.addClass("icon-close"); _this.htmlDoms.tips.addClass("err-bg").removeClass("suc-bg"); // _this.htmlDoms.tips.css({"display":"block",animation:"move 1.3s cubic-bezier(0, 0, 0.39, 1.01)"}); _this.htmlDoms.tips.animate({ bottom: "0px" }); _this.htmlDoms.tips.text(res.repMsg); setTimeout(function () { _this.refresh(); _this.htmlDoms.tips.animate({ bottom: "-35px" }); }, 1000); // setTimeout(function () { // // _this.htmlDoms.tips.css({"display":"none",animation:"none"}); // },1300) _this.options.error(this); } }); this.status = false; } }, resetSize: function (obj) { var img_width, img_height, bar_width, bar_height, block_width, block_height, circle_radius; //图片的宽度、高度,移动条的宽度、高度 var parentWidth = obj.$element.parent().width() || $(window).width(); var parentHeight = obj.$element.parent().height() || $(window).height(); if (obj.options.imgSize.width.indexOf("%") != -1) { img_width = (parseInt(obj.options.imgSize.width) / 100) * parentWidth + "px"; } else { img_width = obj.options.imgSize.width; } if (obj.options.imgSize.height.indexOf("%") != -1) { img_height = (parseInt(obj.options.imgSize.height) / 100) * parentHeight + "px"; } else { img_height = obj.options.imgSize.height; } if (obj.options.barSize.width.indexOf("%") != -1) { bar_width = (parseInt(obj.options.barSize.width) / 100) * parentWidth + "px"; } else { bar_width = obj.options.barSize.width; } if (obj.options.barSize.height.indexOf("%") != -1) { bar_height = (parseInt(obj.options.barSize.height) / 100) * parentHeight + "px"; } else { bar_height = obj.options.barSize.height; } if (obj.options.blockSize) { if (obj.options.blockSize.width.indexOf("%") != -1) { block_width = (parseInt(obj.options.blockSize.width) / 100) * parentWidth + "px"; } else { block_width = obj.options.blockSize.width; } if (obj.options.blockSize.height.indexOf("%") != -1) { block_height = (parseInt(obj.options.blockSize.height) / 100) * parentHeight + "px"; } else { block_height = obj.options.blockSize.height; } } if (obj.options.circleRadius) { if (obj.options.circleRadius.indexOf("%") != -1) { circle_radius = (parseInt(obj.options.circleRadius) / 100) * parentHeight + "px"; } else { circle_radius = obj.options.circleRadius; } } return { img_width: img_width, img_height: img_height, bar_width: bar_width, bar_height: bar_height, block_width: block_width, block_height: block_height, circle_radius: circle_radius, }; }, //刷新 refresh: function () { var _this = this; this.htmlDoms.refresh.show(); this.$element.find(".verify-msg:eq(1)").text(""); this.$element.find(".verify-msg:eq(1)").css("color", "#000"); this.htmlDoms.move_block.animate({ left: "0px" }, "fast"); this.htmlDoms.left_bar.animate({ width: parseInt(this.setSize.bar_height) }, "fast"); this.htmlDoms.left_bar.css({ "border-color": "#ddd" }); this.htmlDoms.move_block.css("background-color", "#fff"); this.htmlDoms.icon.css("color", "#000"); this.htmlDoms.icon.removeClass("icon-close"); this.htmlDoms.icon.addClass("icon-right"); this.$element.find(".verify-msg:eq(0)").text(this.options.explain); this.isEnd = false; getPictrue({ captchaType: "blockPuzzle", clientUid: localStorage.getItem("slider"), ts: Date.now() }, this.options.baseUrl, function (res) { if (res.repCode == "0000") { _this.$element.find(".backImg")[0].src = "data:image/png;base64," + res.repData.originalImageBase64; _this.$element.find(".bock-backImg")[0].src = "data:image/png;base64," + res.repData.jigsawImageBase64; _this.secretKey = res.repData.secretKey; _this.backToken = res.repData.token; } else { _this.$element.find(".backImg")[0].src = "images/default.jpg"; _this.$element.find(".bock-backImg")[0].src = ""; _this.htmlDoms.tips.addClass("err-bg").removeClass("suc-bg"); _this.htmlDoms.tips.animate({ bottom: "0px" }); _this.htmlDoms.tips.text(res.repMsg); setTimeout(function () { _this.htmlDoms.tips.animate({ bottom: "-35px" }); }, 1000); } }); this.htmlDoms.sub_block.css("left", "0px"); }, }; //定义Points的构造函数 var Points = function (ele, opt) { (this.$element = ele), (this.backToken = null), (this.secretKey = ""), (this.defaults = { baseUrl: "https://captcha.anji-plus.com/captcha-api", captchaType: "clickWord", containerId: "", mode: "fixed", //弹出式pop,固定fixed checkNum: 3, //校对的文字数量 vSpace: 5, //间隔 imgSize: { width: "310px", height: "155px", }, barSize: { width: "310px", height: "50px", }, beforeCheck: function () { return true; }, ready: function () {}, success: function () {}, error: function () {}, }), (this.options = $.extend({}, this.defaults, opt)); }; //定义Points的方法 Points.prototype = { init: function () { var _this = this; //加载页面 _this.loadDom(); _this.refresh(); _this.options.ready(); this.$element[0].onselectstart = document.body.ondrag = function () { return false; }; if (this.options.mode == "pop") { _this.$element.find(".verifybox-close").on("click", function () { _this.$element.find(".mask").css("display", "none"); }); var clickBtn = document.getElementById(this.options.containerId); clickBtn && (clickBtn.onclick = function () { if (_this.options.beforeCheck()) { _this.$element.find(".mask").css("display", "block"); } }); } // 注册点击验证事件 _this.$element.find(".back-img").on("click", function (e) { _this.checkPosArr.push(_this.getMousePos(this, e)); if (_this.num == _this.options.checkNum) { _this.num = _this.createPoint(_this.getMousePos(this, e)); //按比例转换坐标值 _this.checkPosArr = _this.pointTransfrom(_this.checkPosArr, _this.setSize); setTimeout(function () { var data = { captchaType: _this.options.captchaType, pointJson: _this.secretKey ? aesEncrypt(JSON.stringify(_this.checkPosArr), _this.secretKey) : JSON.stringify(_this.checkPosArr), token: _this.backToken, clientUid: localStorage.getItem("point"), ts: Date.now(), }; var captchaVerification = _this.secretKey ? aesEncrypt(_this.backToken + "---" + JSON.stringify(_this.checkPosArr), _this.secretKey) : _this.backToken + "---" + JSON.stringify(_this.checkPosArr); checkPictrue(data, _this.options.baseUrl, function (res) { if (res.repCode == "0000") { _this.$element.find(".verify-bar-area").css({ color: "#4cae4c", "border-color": "#5cb85c" }); _this.$element.find(".verify-msg").text("验证成功"); // _this.$element.find('.verify-refresh').hide(); _this.$element.find(".verify-img-panel").unbind("click"); setTimeout(function () { _this.$element.find(".mask").css("display", "none"); _this.refresh(); }, 1000); _this.options.success({ captchaVerification: captchaVerification }); } else { _this.options.error(_this); _this.$element.find(".verify-bar-area").css({ color: "#d9534f", "border-color": "#d9534f" }); _this.$element.find(".verify-msg").text("验证失败"); setTimeout(function () { _this.$element.find(".verify-bar-area").css({ color: "#000", "border-color": "#ddd" }); _this.refresh(); }, 400); } }); }, 400); } if (_this.num < _this.options.checkNum) { _this.num = _this.createPoint(_this.getMousePos(this, e)); } }); //刷新 _this.$element.find(".verify-refresh").on("click", function () { _this.refresh(); }); }, //加载页面 loadDom: function () { this.fontPos = []; //选中的坐标信息 this.checkPosArr = []; //用户点击的坐标 this.num = 1; //点击的记数 var panelHtml = ""; var wrapStartHtml = ""; this.setSize = Slide.prototype.resetSize(this); //重新设置宽度高度 wrapStartHtml = '
' + '
' + '
' + "请完成安全验证" + '' + '' + "" + "
" + '
' + '
'; if (this.options.mode == "pop") { panelHtml = wrapStartHtml; } panelHtml += '
' + '
' + '
' + '' + "
" + '' + "
" + "
" + '
' + '' + "
"; wrapEndHtml = "
"; if (this.options.mode == "pop") { panelHtml += wrapEndHtml; } this.$element.append(panelHtml); this.htmlDoms = { back_img: this.$element.find(".back-img"), out_panel: this.$element.find(".verify-img-out"), img_panel: this.$element.find(".verify-img-panel"), bar_area: this.$element.find(".verify-bar-area"), msg: this.$element.find(".verify-msg"), }; this.$element.css("position", "relative"); this.htmlDoms.out_panel.css("height", parseInt(this.setSize.img_height) + this.options.vSpace + "px"); this.htmlDoms.img_panel.css({ width: this.setSize.img_width, height: this.setSize.img_height, "background-size": this.setSize.img_width + " " + this.setSize.img_height, "margin-bottom": this.options.vSpace + "px", }); this.htmlDoms.bar_area.css({ width: this.setSize.img_width, height: this.setSize.bar_height, "line-height": this.setSize.bar_height }); }, //获取坐标 getMousePos: function (obj, event) { var e = event || window.event; var scrollX = document.documentElement.scrollLeft || document.body.scrollLeft; var scrollY = document.documentElement.scrollTop || document.body.scrollTop; var x = e.clientX - ($(obj).offset().left - $(window).scrollLeft()); var y = e.clientY - ($(obj).offset().top - $(window).scrollTop()); return { x: x, y: y }; }, //创建坐标点 createPoint: function (pos) { this.htmlDoms.img_panel.append( '
' + this.num + "
" ); return ++this.num; }, //刷新 refresh: function () { var _this = this; this.$element.find(".point-area").remove(); this.fontPos = []; this.checkPosArr = []; this.num = 1; getPictrue({ captchaType: "clickWord", clientUid: localStorage.getItem("point"), ts: Date.now() }, _this.options.baseUrl, function (res) { if (res.repCode == "0000") { _this.htmlDoms.back_img[0].src = "data:image/png;base64," + res.repData.originalImageBase64; _this.backToken = res.repData.token; _this.secretKey = res.repData.secretKey; var text = "请依次点击【" + res.repData.wordList.join(",") + "】"; _this.$element.find(".verify-msg").text(text); } else { _this.htmlDoms.back_img[0].src = "images/default.jpg"; _this.$element.find(".verify-msg").text(res.repMsg); } }); }, pointTransfrom: function (pointArr, imgSize) { var newPointArr = pointArr.map(function (p) { var x = Math.round((310 * p.x) / parseInt(imgSize.img_width)); var y = Math.round((155 * p.y) / parseInt(imgSize.img_height)); return { x: x, y: y }; }); return newPointArr; }, }; //在插件中使用slideVerify对象 初始化与是否弹出无关 ,不应该耦合 $.fn.slideVerify = function (options, callbacks) { var slide = new Slide(this, options); if (slide.options.mode == "pop") { slide.init(); } else if (slide.options.mode == "fixed") { slide.init(); } }; //在插件中使用clickVerify对象 $.fn.pointsVerify = function (options, callbacks) { var points = new Points(this, options); if (points.options.mode == "pop") { points.init(); } else if (points.options.mode == "fixed") { points.init(); } }; })(jQuery, window, document);