UNPKG

yuang-framework-ui-pc

Version:

yuang-framework-ui-pc Library

284 lines (283 loc) 10.8 kB
"use strict"; const vue = require("vue"); const httpConfig = require("yuang-framework-ui-common/lib/config/httpConfig"); const iconsVue = require("@element-plus/icons-vue"); const icons = require("../../icons"); const _hoisted_1 = { class: "yu-framework-slider-captcha" }; const _hoisted_2 = { class: "yu-framework-slider-captcha-title" }; const _hoisted_3 = ["width", "height"]; const _hoisted_4 = { class: "slider-hint" }; const _sfc_main = /* @__PURE__ */ vue.defineComponent({ ...{ name: "SliderCaptcha" }, __name: "SliderCaptcha", props: { blockLength: { default: 42 }, blockRadius: { default: 10 }, canvasWidth: { default: 320 }, canvasHeight: { default: 155 }, sliderHint: { default: "向右滑动" }, accuracy: { default: 3 }, imageList: { default: [] } }, emits: ["success", "fail", "close"], setup(__props, { emit: __emit }) { const props = __props; const emit = __emit; const canvas = vue.ref(null); const block = vue.ref(null); const isVerifyActive = vue.ref(false); const isVerifySuccess = vue.ref(false); const isVerifyFail = vue.ref(false); vue.ref(null); vue.ref(null); vue.ref(props.blockLength * 2); vue.ref(void 0); vue.ref(void 0); const originX = vue.ref(void 0); const originY = vue.ref(void 0); const dragDistanceList = vue.ref([]); const sliderBoxWidth = vue.ref(0); const sliderButtonLeft = vue.ref(0); const isMouseDown = vue.ref(false); const isLoading = vue.ref(true); const timestamp = vue.ref(null); const successHint = vue.ref(""); const key = vue.ref(void 0); const isSliderSlide = vue.ref(false); vue.onMounted(() => { init(); }); const init = () => { initDom(); bindEvents(); }; const initDom = () => { getCaptcha(); }; const getCaptcha = () => { httpConfig.http.post(`/framework-api/core/framework-captcha/createSliderCaptcha`, {}).then((res) => { key.value = res.data.data.key; block.value.src = res.data.data.blockSrc; block.value.style.top = res.data.data.blockY + "px"; canvas.value.src = res.data.data.canvasSrc; setTimeout(() => { isLoading.value = false; }, 200); }); }; const bindEvents = () => { var _a, _b, _c; (_a = document.getElementById("slider-button")) == null ? void 0 : _a.addEventListener("mousedown", (event) => { startEvent(event.clientX, event.clientY); updateSliderButtonImage("slide"); }); document.addEventListener("mousemove", (event) => { moveEvent(event.clientX, event.clientY); }); document.addEventListener("mouseup", (event) => { endEvent(event.clientX); }); (_b = document.getElementById("slider-button")) == null ? void 0 : _b.addEventListener("click", (event) => { updateSliderButtonImage("init"); }); (_c = document.getElementById("slider-button")) == null ? void 0 : _c.addEventListener("touchstart", (event) => { startEvent(event.changedTouches[0].pageX, event.changedTouches[0].pageY); }); document.addEventListener("touchmove", (event) => { moveEvent(event.changedTouches[0].pageX, event.changedTouches[0].pageY); }); document.addEventListener("touchend", (event) => { endEvent(event.changedTouches[0].pageX); }); }; const updateSliderButtonImage = (type) => { if (type == "init") { isSliderSlide.value = false; } else if (type == "slide") { isSliderSlide.value = true; } }; const checkImgSrc = () => { return !!canvas.value.src; }; const startEvent = (clientX, clientY) => { if (!checkImgSrc() || isLoading.value || isVerifySuccess.value) { return; } originX.value = clientX; originY.value = clientY; isMouseDown.value = true; timestamp.value = +/* @__PURE__ */ new Date(); updateSliderButtonImage("slide"); }; const moveEvent = (clientX, clientY) => { if (!isMouseDown.value) { return false; } const moveX = clientX - originX.value; const moveY = clientY - originY.value; if (moveX < 0 || moveX + 40 >= props.canvasWidth) { return false; } sliderButtonLeft.value = moveX > props.canvasWidth - 56 ? props.canvasWidth - 56 : moveX; let blockLeft = (props.canvasWidth - 40 - 20) / (props.canvasWidth - 40) * moveX; block.value.style.left = (blockLeft > props.canvasWidth - 56 - 18 - 7 ? props.canvasWidth - 56 - 18 - 7 : blockLeft) + "px"; isVerifyActive.value = true; sliderBoxWidth.value = moveX + 28; dragDistanceList.value.push(moveY); }; const endEvent = (clientX) => { if (!isMouseDown.value) { return false; } isMouseDown.value = false; if (clientX === originX.value) { return false; } isLoading.value = true; isVerifyActive.value = false; timestamp.value = +/* @__PURE__ */ new Date() - timestamp.value; const moveLength = parseInt(block.value.style.left); if (timestamp.value > 1e4) { verifyFailEvent(); } else { if (!turingTest()) { verifyFailEvent(); } else { let data = { key: key.value, captcha: moveLength }; httpConfig.http.post(`/framework-api/core/framework-captcha/validateSliderCaptcha`, data).then((res) => { verifySuccessEvent(); setTimeout(() => { emit("success", { key: key.value, value: moveLength }); }, 500); }).catch((ex) => { verifyFailEvent(); console.error(ex); }); } } updateSliderButtonImage("init"); }; const turingTest = () => { const arr = dragDistanceList.value; const average = arr.reduce(calcSum) / arr.length; const deviations = arr.map((x) => x - average); const stdDev = Math.sqrt(deviations.map(calcSquare).reduce(calcSum) / arr.length); return average !== stdDev; }; const verifySuccessEvent = () => { isLoading.value = false; isVerifySuccess.value = true; const elapsedTime = (timestamp.value / 1e3).toFixed(1); if (elapsedTime < 1) { successHint.value = `仅仅${elapsedTime}S,你的速度快如闪电`; } else if (elapsedTime < 2) { successHint.value = `只用了${elapsedTime}S,这速度简直完美`; } else { successHint.value = `耗时${elapsedTime}S,争取下次再快一点`; } }; const verifyFailEvent = () => { isVerifyFail.value = true; emit("fail", {}); refresh(); }; const refresh = () => { setTimeout(() => { isVerifyFail.value = false; }, 300); isLoading.value = true; isVerifyActive.value = false; isVerifySuccess.value = false; block.value.style.left = 0; sliderBoxWidth.value = 0; sliderButtonLeft.value = 0; vue.nextTick(() => { getCaptcha(); }); }; const close = () => { emit("close"); }; const calcSum = (x, y) => { return x + y; }; const calcSquare = (x) => { return x * x; }; return (_ctx, _cache) => { return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [ vue.createElementVNode("div", _hoisted_2, [ _cache[0] || (_cache[0] = vue.createTextVNode(" 完成拼图验证 ")), vue.createElementVNode("div", { onClick: refresh, class: "yu-framework-slider-captcha-refresh-icon" }, [ vue.createVNode(vue.unref(iconsVue.RefreshRight)) ]), vue.createElementVNode("div", { onClick: close, class: "yu-framework-slider-captcha-close-icon" }, [ vue.createVNode(vue.unref(iconsVue.CircleClose)) ]) ]), vue.createElementVNode("div", { class: "yu-framework-slider-captcha", style: vue.normalizeStyle({ width: _ctx.canvasWidth + "px" }), onselectstart: "return false;" }, [ isLoading.value ? (vue.openBlock(), vue.createElementBlock("div", { key: 0, class: vue.normalizeClass({ "yu-framework-slider-captcha-img-loading": isLoading.value }), style: vue.normalizeStyle({ height: _ctx.canvasHeight + "px" }) }, null, 6)) : vue.createCommentVNode("", true), isVerifySuccess.value ? (vue.openBlock(), vue.createElementBlock("div", { key: 1, class: "success-hint", style: vue.normalizeStyle({ height: _ctx.canvasHeight + "px" }) }, vue.toDisplayString(successHint.value), 5)) : vue.createCommentVNode("", true), vue.createElementVNode("img", { ref_key: "canvas", ref: canvas, class: "yu-framework-slider-captcha-canvas", width: _ctx.canvasWidth, height: _ctx.canvasHeight }, null, 8, _hoisted_3), vue.createElementVNode("img", { ref_key: "block", ref: block, class: vue.normalizeClass(["yu-framework-slider-captcha-block", { "is-verify-fail": isVerifyFail.value }]) }, null, 2), vue.createElementVNode("div", { class: vue.normalizeClass(["yu-framework-slider-captcha-slider", { "is-verify-active": isVerifyActive.value, "is-verify-success": isVerifySuccess.value, "is-verify-fail": isVerifyFail.value }]) }, [ vue.createElementVNode("div", { class: "yu-framework-slider-captcha-slider-box", style: vue.normalizeStyle({ width: sliderBoxWidth.value + "px" }) }, [ vue.createElementVNode("div", { class: "yu-framework-slider-captcha-slider-button", id: "slider-button", style: vue.normalizeStyle({ left: sliderButtonLeft.value + "px" }) }, [ !isSliderSlide.value ? (vue.openBlock(), vue.createBlock(vue.unref(icons.SliderArrowStatic), { key: 0, class: "yu-framework-slider-captcha-slider-button-icon yu-color-primary" })) : (vue.openBlock(), vue.createBlock(vue.unref(icons.SliderArrowSlide), { key: 1, class: "yu-framework-slider-captcha-slider-button-icon yu-color-primary" })) ], 4) ], 4), vue.createElementVNode("span", _hoisted_4, vue.toDisplayString(_ctx.sliderHint), 1) ], 2) ], 4) ]); }; } }); module.exports = _sfc_main;