UNPKG

yuang-framework-ui-pc

Version:

yuang-framework-ui-pc Library

284 lines (283 loc) 10.5 kB
import { defineComponent, ref, onMounted, nextTick, openBlock, createElementBlock, createElementVNode, createTextVNode, createVNode, unref, normalizeStyle, normalizeClass, createCommentVNode, toDisplayString, createBlock } from "vue"; import { http } from "yuang-framework-ui-common/lib/config/httpConfig"; import { RefreshRight, CircleClose } from "@element-plus/icons-vue"; import { SliderArrowStatic, SliderArrowSlide } from "../icons"; const _hoisted_1 = { class: "yu-slider-captcha-container" }; const _hoisted_2 = { class: "yu-slider-captcha-title" }; const _hoisted_3 = ["width", "height"]; const _hoisted_4 = { class: "slider-hint" }; const _sfc_main = /* @__PURE__ */ 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 = ref(null); const block = ref(null); const isVerifyActive = ref(false); const isVerifySuccess = ref(false); const isVerifyFail = ref(false); ref(null); ref(null); ref(props.blockLength * 2); ref(void 0); ref(void 0); const originX = ref(void 0); const originY = ref(void 0); const dragDistanceList = ref([]); const sliderBoxWidth = ref(0); const sliderButtonLeft = ref(0); const isMouseDown = ref(false); const isLoading = ref(true); const timestamp = ref(null); const successHint = ref(""); const key = ref(void 0); const isSliderSlide = ref(false); onMounted(() => { init(); }); const init = () => { initDom(); bindEvents(); }; const initDom = () => { getCaptcha(); }; const getCaptcha = () => { http.get("/sso-api/standard/framework-captcha/getSliderCaptcha", { params: {} }).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 params = { key: key.value, captcha: moveLength }; http.get("/sso-api/standard/framework-captcha/validateSliderCaptcha", { params }).then((res) => { verifySuccessEvent(); setTimeout(() => { emit("success", { key: key.value, value: moveLength }); }, 500); }).catch(() => { verifyFailEvent(); }); } } 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; nextTick(() => { getCaptcha(); }); }; const close = () => { emit("close"); }; const calcSum = (x, y) => { return x + y; }; const calcSquare = (x) => { return x * x; }; return (_ctx, _cache) => { return openBlock(), createElementBlock("div", _hoisted_1, [ createElementVNode("div", _hoisted_2, [ createTextVNode(" 完成拼图验证 "), createElementVNode("div", { onClick: refresh, class: "yu-slider-captcha-refresh-icon" }, [ createVNode(unref(RefreshRight)) ]), createElementVNode("div", { onClick: close, class: "yu-slider-captcha-close-icon" }, [ createVNode(unref(CircleClose)) ]) ]), createElementVNode("div", { class: "yu-slider-captcha", style: normalizeStyle({ width: _ctx.canvasWidth + "px" }), onselectstart: "return false;" }, [ isLoading.value ? (openBlock(), createElementBlock("div", { key: 0, class: normalizeClass({ "yu-slider-captcha-img-loading": isLoading.value }), style: normalizeStyle({ height: _ctx.canvasHeight + "px" }) }, null, 6)) : createCommentVNode("", true), isVerifySuccess.value ? (openBlock(), createElementBlock("div", { key: 1, class: "success-hint", style: normalizeStyle({ height: _ctx.canvasHeight + "px" }) }, toDisplayString(successHint.value), 5)) : createCommentVNode("", true), createElementVNode("img", { ref_key: "canvas", ref: canvas, class: "yu-slider-captcha-canvas", width: _ctx.canvasWidth, height: _ctx.canvasHeight }, null, 8, _hoisted_3), createElementVNode("img", { ref_key: "block", ref: block, class: normalizeClass(["yu-slider-captcha-block", { "is-verify-fail": isVerifyFail.value }]) }, null, 2), createElementVNode("div", { class: normalizeClass(["yu-slider-captcha-slider", { "is-verify-active": isVerifyActive.value, "is-verify-success": isVerifySuccess.value, "is-verify-fail": isVerifyFail.value }]) }, [ createElementVNode("div", { class: "yu-slider-captcha-slider-box", style: normalizeStyle({ width: sliderBoxWidth.value + "px" }) }, [ createElementVNode("div", { class: "yu-slider-captcha-slider-button", id: "slider-button", style: normalizeStyle({ left: sliderButtonLeft.value + "px" }) }, [ !isSliderSlide.value ? (openBlock(), createBlock(unref(SliderArrowStatic), { key: 0, class: "yu-slider-captcha-slider-button-icon yu-color-primary" })) : (openBlock(), createBlock(unref(SliderArrowSlide), { key: 1, class: "yu-slider-captcha-slider-button-icon yu-color-primary" })) ], 4) ], 4), createElementVNode("span", _hoisted_4, toDisplayString(_ctx.sliderHint), 1) ], 2) ], 4) ]); }; } }); export { _sfc_main as default };