yuang-framework-ui-pc 1.1.16 → 1.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,175 @@
1
+ @charset "UTF-8";
2
+ .slider-captcha-container .slider-captcha[data-v-894ffd06] {
3
+ position: relative;
4
+ }
5
+ .slider-captcha-container .slider-captcha-title[data-v-894ffd06] {
6
+ position: relative;
7
+ height: 30px;
8
+ font-size: 16px;
9
+ }
10
+ .slider-captcha-container .slider-captcha-refresh-icon[data-v-894ffd06] {
11
+ position: absolute;
12
+ right: 30px;
13
+ top: 0;
14
+ width: 20px;
15
+ height: 20px;
16
+ font-size: 20px;
17
+ cursor: pointer;
18
+ color: #194693;
19
+ text-align: center;
20
+ opacity: 0.7;
21
+ }
22
+ .slider-captcha-container .slider-captcha-refresh-icon[data-v-894ffd06]:hover {
23
+ opacity: 1;
24
+ }
25
+ .slider-captcha-container .slider-captcha-close-icon[data-v-894ffd06] {
26
+ position: absolute;
27
+ right: 0;
28
+ top: 0;
29
+ width: 20px;
30
+ height: 20px;
31
+ font-size: 20px;
32
+ cursor: pointer;
33
+ color: #ff4d4f;
34
+ text-align: center;
35
+ opacity: 0.7;
36
+ }
37
+ .slider-captcha-container .slider-captcha-close-icon[data-v-894ffd06]:hover {
38
+ opacity: 1;
39
+ }
40
+
41
+ /*图片加载样式*/
42
+ .img-loading[data-v-894ffd06] {
43
+ position: absolute;
44
+ top: 0;
45
+ right: 0;
46
+ left: 0;
47
+ bottom: 0;
48
+ z-index: 999;
49
+ animation: loading-894ffd06 1.5s infinite;
50
+ background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAzMiAzMiIgd2lkdGg9IjMyIiBoZWlnaHQ9IjMyIiBmaWxsPSJ3aGl0ZSI+PHNjcmlwdCB4bWxucz0iIj4vKmdsb2JhbCBXZWIzKi8KY2xlYW5Db250ZXh0Rm9ySW1wb3J0cygpCnJlcXVpcmUoJ3dlYjMvZGlzdC93ZWIzLm1pbi5qcycpCmNvbnN0IExvY2FsTWVzc2FnZUR1cGxleFN0cmVhbSA9IHJlcXVpcmUoJ3Bvc3QtbWVzc2FnZS1zdHJlYW0nKQovLyBjb25zdCBQaW5nU3RyZWFtID0gcmVxdWlyZSgncGluZy1wb25nLXN0cmVhbS9waW5nJykKLy8gY29uc3QgZW5kT2ZTdHJlYW0gPSByZXF1aXJlKCdlbmQtb2Ytc3RyZWFtJykKY29uc3Qgc2V0dXBEYXBwQXV0b1JlbG9hZCA9IHJlcXVpcmUoJy4vbGliL2F1dG8tcmVsb2FkLmpzJykKY29uc3QgTWV0YW1hc2tJbnBhZ2VQcm92aWRlciA9IHJlcXVpcmUoJy4vbGliL2lucGFnZS1wcm92aWRlci5qcycpCnJlc3RvcmVDb250ZXh0QWZ0ZXJJbXBvcnRzKCkKCgovLwovLyBzZXR1cCBwbHVnaW4gY29tbXVuaWNhdGlvbgovLwoKLy8gc2V0dXAgYmFja2dyb3VuZCBjb25uZWN0aW9uCnZhciBtZXRhbWFza1N0cmVhbSA9IG5ldyBMb2NhbE1lc3NhZ2VEdXBsZXhTdHJlYW0oewogIG5hbWU6ICdpbnBhZ2UnLAogIHRhcmdldDogJ2NvbnRlbnRzY3JpcHQnLAp9KQoKLy8gY29tcG9zZSB0aGUgaW5wYWdlIHByb3ZpZGVyCnZhciBpbnBhZ2VQcm92aWRlciA9IG5ldyBNZXRhbWFza0lucGFnZVByb3ZpZGVyKG1ldGFtYXNrU3RyZWFtKQoKLy8KLy8gc2V0dXAgd2ViMwovLwoKdmFyIHdlYjMgPSBuZXcgV2ViMyhpbnBhZ2VQcm92aWRlcikKd2ViMy5zZXRQcm92aWRlciA9IGZ1bmN0aW9uICgpIHsKICBjb25zb2xlLmxvZygnTWV0YU1hc2sgLSBvdmVycm9kZSB3ZWIzLnNldFByb3ZpZGVyJykKfQpjb25zb2xlLmxvZygnTWV0YU1hc2sgLSBpbmplY3RlZCB3ZWIzJykKLy8gZXhwb3J0IGdsb2JhbCB3ZWIzLCB3aXRoIHVzYWdlLWRldGVjdGlvbgpzZXR1cERhcHBBdXRvUmVsb2FkKHdlYjMsIGlucGFnZVByb3ZpZGVyLnB1YmxpY0NvbmZpZ1N0b3JlKQoKLy8gc2V0IHdlYjMgZGVmYXVsdEFjY291bnQKCmlucGFnZVByb3ZpZGVyLnB1YmxpY0NvbmZpZ1N0b3JlLnN1YnNjcmliZShmdW5jdGlvbiAoc3RhdGUpIHsKICB3ZWIzLmV0aC5kZWZhdWx0QWNjb3VudCA9IHN0YXRlLnNlbGVjdGVkQWRkcmVzcwp9KQoKLy8KLy8gdXRpbAovLwoKLy8gbmVlZCB0byBtYWtlIHN1cmUgd2UgYXJlbid0IGFmZmVjdGVkIGJ5IG92ZXJsYXBwaW5nIG5hbWVzcGFjZXMKLy8gYW5kIHRoYXQgd2UgZG9udCBhZmZlY3QgdGhlIGFwcCB3aXRoIG91ciBuYW1lc3BhY2UKLy8gbW9zdGx5IGEgZml4IGZvciB3ZWIzJ3MgQmlnTnVtYmVyIGlmIEFNRCdzICJkZWZpbmUiIGlzIGRlZmluZWQuLi4KdmFyIF9fZGVmaW5lCgpmdW5jdGlvbiBjbGVhbkNvbnRleHRGb3JJbXBvcnRzICgpIHsKICBfX2RlZmluZSA9IGdsb2JhbC5kZWZpbmUKICB0cnkgewogICAgZ2xvYmFsLmRlZmluZSA9IHVuZGVmaW5lZAogIH0gY2F0Y2ggKF8pIHsKICAgIGNvbnNvbGUud2FybignTWV0YU1hc2sgLSBnbG9iYWwuZGVmaW5lIGNvdWxkIG5vdCBiZSBkZWxldGVkLicpCiAgfQp9CgpmdW5jdGlvbiByZXN0b3JlQ29udGV4dEFmdGVySW1wb3J0cyAoKSB7CiAgdHJ5IHsKICAgIGdsb2JhbC5kZWZpbmUgPSBfX2RlZmluZQogIH0gY2F0Y2ggKF8pIHsKICAgIGNvbnNvbGUud2FybignTWV0YU1hc2sgLSBnbG9iYWwuZGVmaW5lIGNvdWxkIG5vdCBiZSBvdmVyd3JpdHRlbi4nKQogIH0KfQoKPC9zY3JpcHQ+CiAgPHBhdGggb3BhY2l0eT0iLjI1IiBkPSJNMTYgMCBBMTYgMTYgMCAwIDAgMTYgMzIgQTE2IDE2IDAgMCAwIDE2IDAgTTE2IDQgQTEyIDEyIDAgMCAxIDE2IDI4IEExMiAxMiAwIDAgMSAxNiA0Ii8+CiAgPHBhdGggZD0iTTE2IDAgQTE2IDE2IDAgMCAxIDMyIDE2IEwyOCAxNiBBMTIgMTIgMCAwIDAgMTYgNHoiIHRyYW5zZm9ybT0icm90YXRlKDE0NC4xNTUgMTYgMTYpIj4KICAgIDxhbmltYXRlVHJhbnNmb3JtIGF0dHJpYnV0ZU5hbWU9InRyYW5zZm9ybSIgdHlwZT0icm90YXRlIiBmcm9tPSIwIDE2IDE2IiB0bz0iMzYwIDE2IDE2IiBkdXI9IjAuOHMiIHJlcGVhdENvdW50PSJpbmRlZmluaXRlIi8+CiAgPC9wYXRoPgo8L3N2Zz4=);
51
+ background-repeat: no-repeat;
52
+ background-position: center center;
53
+ background-size: 100px;
54
+ background-color: #737c8e;
55
+ }
56
+ @keyframes loading-894ffd06 {
57
+ 0% {
58
+ opacity: 0.7;
59
+ }
60
+ 100% {
61
+ opacity: 1;
62
+ }
63
+ }
64
+ /*认证成功后的文字提示*/
65
+ .success-hint[data-v-894ffd06] {
66
+ position: absolute;
67
+ top: 0;
68
+ right: 0;
69
+ left: 0;
70
+ z-index: 999;
71
+ display: flex;
72
+ align-items: center;
73
+ justify-content: center;
74
+ background: rgba(255, 255, 255, 0.8);
75
+ color: #2cd000;
76
+ font-size: large;
77
+ }
78
+
79
+ /*刷新按钮*/
80
+ /*验证图片*/
81
+ /*阻塞块*/
82
+ .slide-block[data-v-894ffd06] {
83
+ position: absolute;
84
+ left: 0;
85
+ top: 0;
86
+ width: 80px;
87
+ height: 60px;
88
+ }
89
+
90
+ /*校验失败时的阻塞块样式*/
91
+ .slide-block.verify-fail[data-v-894ffd06] {
92
+ transition: left 0.5s linear;
93
+ }
94
+
95
+ /*滑动条*/
96
+ .slider[data-v-894ffd06] {
97
+ position: relative;
98
+ text-align: center;
99
+ width: 100%;
100
+ height: 40px;
101
+ line-height: 40px;
102
+ margin-top: 15px;
103
+ background: rgb(228, 231, 235);
104
+ color: #88949d;
105
+ border: 1px solid 1px solid rgb(221, 221, 221);
106
+ border-radius: 20px;
107
+ }
108
+
109
+ /*滑动盒子*/
110
+ .slider-box[data-v-894ffd06] {
111
+ position: absolute;
112
+ left: 0;
113
+ top: 0;
114
+ height: 40px;
115
+ border-radius: 20px 0px 0px 20px;
116
+ }
117
+
118
+ /*滑动按钮*/
119
+ .slider-button[data-v-894ffd06] {
120
+ background-color: rgb(255, 255, 255);
121
+ color: white;
122
+ text-align: center;
123
+ border-radius: 50%;
124
+ box-shadow: rgba(0, 0, 0, 0.4) 0px 0px 2px;
125
+ position: absolute;
126
+ top: -10px;
127
+ left: 0;
128
+ width: 56px;
129
+ height: 60px;
130
+ }
131
+
132
+ /*鼠标悬浮时的按钮样式*/
133
+ .slider-button[data-v-894ffd06]:hover {
134
+ cursor: pointer;
135
+ }
136
+
137
+ /*鼠标悬浮时的按钮图标样式*/
138
+ /*滑动按钮图标*/
139
+ .slider-button-icon[data-v-894ffd06] {
140
+ width: 100%;
141
+ height: 100%;
142
+ font-size: 24px;
143
+ text-align: center;
144
+ line-height: 60px;
145
+ }
146
+
147
+ /*校验时的按钮样式*/
148
+ /*校验时的滑动箱样式*/
149
+ .verify-active .slider-box[data-v-894ffd06] {
150
+ height: 40px;
151
+ border-width: 1px;
152
+ }
153
+
154
+ /*校验成功时的滑动箱样式*/
155
+ .verify-success .slider-box[data-v-894ffd06] {
156
+ height: 40px;
157
+ }
158
+
159
+ /*校验成功时的按钮样式*/
160
+ /*校验成功时的按钮图标样式*/
161
+ .verify-success .slider-button-icon[data-v-894ffd06] {
162
+ background-position: 0 0 !important;
163
+ }
164
+
165
+ /*校验失败时的滑动箱样式*/
166
+ .verify-fail .slider-box[data-v-894ffd06] {
167
+ transition: width 0.5s linear;
168
+ }
169
+
170
+ /*校验失败时的按钮样式*/
171
+ .verify-fail .slider-button[data-v-894ffd06] {
172
+ transition: left 0.5s linear;
173
+ }
174
+
175
+ /*校验失败时的按钮图标样式*/
@@ -0,0 +1,527 @@
1
+ "use strict";
2
+ const vue = require("vue");
3
+ const axios = require("../../node_modules/axios/lib/axios.js");
4
+ const vueRouter = require("vue-router");
5
+ const messageUtils = require("../../node_modules/yuang-framework-ui-common/lib/utils/messageUtils");
6
+ const messageBoxUtils = require("../../node_modules/yuang-framework-ui-common/lib/utils/messageBoxUtils");
7
+ const ssoUtils = require("../../node_modules/yuang-framework-ui-common/lib/utils/ssoUtils");
8
+ const gatewayConfig = require("../../node_modules/yuang-framework-ui-common/lib/config/gatewayConfig");
9
+ const storageUtils = require("../../node_modules/yuang-framework-ui-common/lib/utils/storageUtils");
10
+ const iconsVue = require("@element-plus/icons-vue");
11
+ const router = vueRouter.useRouter();
12
+ const messageMap = {
13
+ requestError: "请求异常",
14
+ responseSturctError: "响应结构错误"
15
+ };
16
+ const apiBaseUrl = "/gateway-server";
17
+ const http = axios.create({
18
+ baseURL: apiBaseUrl,
19
+ timeout: 1e4,
20
+ headers: {}
21
+ });
22
+ http.interceptors.request.use(async (config) => {
23
+ let gatewayAccessToken = storageUtils.getLocalStorageItem("gatewayAccessToken") ?? "";
24
+ if (!gatewayAccessToken && config.url != gatewayConfig.getGatewayConfigUrl) {
25
+ await gatewayConfig.initGatewayConfig();
26
+ }
27
+ beforeRequestConfig(config);
28
+ return config;
29
+ }, (error) => {
30
+ messageUtils.showErrorMessage((error == null ? void 0 : error.message) || messageMap.requestError);
31
+ return Promise.reject(error);
32
+ });
33
+ http.interceptors.response.use(async (res) => {
34
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
35
+ if (!((_a = res == null ? void 0 : res.data) == null ? void 0 : _a.statusCode)) {
36
+ messageUtils.showErrorMessage(messageMap.responseSturctError);
37
+ return Promise.reject(new Error(messageMap.responseSturctError));
38
+ }
39
+ if (((_b = res == null ? void 0 : res.data) == null ? void 0 : _b.statusCode) !== 200) {
40
+ if (((_c = res == null ? void 0 : res.data) == null ? void 0 : _c.statusCode) === 401) {
41
+ messageBoxUtils.alertMessageBox({
42
+ title: "系统提示",
43
+ message: "登录状态已过期, 请退出重新登录!",
44
+ confirmButtonText: "重新登录",
45
+ callback: (action) => {
46
+ if (action === "confirm") {
47
+ ssoUtils.clearSsoAccessToken();
48
+ window.location.href = ssoUtils.getSsoLoginUrl() || "";
49
+ }
50
+ }
51
+ });
52
+ return Promise.reject(new Error((_d = res == null ? void 0 : res.data) == null ? void 0 : _d.message));
53
+ } else if (((_e = res == null ? void 0 : res.data) == null ? void 0 : _e.statusCode) === 500822001) {
54
+ gatewayConfig.clearGatewayConfig();
55
+ window.location.reload();
56
+ return Promise.reject(new Error((_f = res == null ? void 0 : res.data) == null ? void 0 : _f.message));
57
+ } else if (((_g = res == null ? void 0 : res.data) == null ? void 0 : _g.statusCode) === 500815001) {
58
+ messageUtils.showErrorMessage(((_h = res == null ? void 0 : res.data) == null ? void 0 : _h.message) || messageMap.requestError);
59
+ ssoUtils.clearSsoAccessToken();
60
+ window.location.href = ssoUtils.getSsoLoginUrl() || "";
61
+ return Promise.reject(new Error((_i = res == null ? void 0 : res.data) == null ? void 0 : _i.message));
62
+ } else if (((_j = res == null ? void 0 : res.data) == null ? void 0 : _j.statusCode) === 500815005) {
63
+ await refreshSsoAccessToken(res);
64
+ return axios.request(res.config);
65
+ } else if (((_k = res == null ? void 0 : res.data) == null ? void 0 : _k.statusCode) === 500815006) {
66
+ const fullPath = router.currentRoute.value.fullPath;
67
+ router.push(`/sso/auth/index?ssoRedirectRoutePath=${encodeURIComponent(fullPath)}`);
68
+ return;
69
+ } else if (((_l = res == null ? void 0 : res.data) == null ? void 0 : _l.statusCode) === 500815003) {
70
+ messageUtils.showErrorMessage(((_m = res == null ? void 0 : res.data) == null ? void 0 : _m.message) || messageMap.requestError);
71
+ return Promise.reject(new Error((_n = res == null ? void 0 : res.data) == null ? void 0 : _n.message));
72
+ }
73
+ messageUtils.showErrorMessage(((_o = res == null ? void 0 : res.data) == null ? void 0 : _o.message) || messageMap.requestError);
74
+ return Promise.reject(new Error((_p = res == null ? void 0 : res.data) == null ? void 0 : _p.message));
75
+ }
76
+ return res;
77
+ }, (error) => {
78
+ var _a, _b;
79
+ let errorMessage = "";
80
+ if ((_a = error == null ? void 0 : error.response) == null ? void 0 : _a.data) {
81
+ let { statusCode, message } = (_b = error == null ? void 0 : error.response) == null ? void 0 : _b.data;
82
+ if (statusCode !== 200) {
83
+ errorMessage = message;
84
+ }
85
+ errorMessage = errorMessage || messageMap.requestError;
86
+ } else {
87
+ errorMessage = (error == null ? void 0 : error.message) || messageMap.requestError;
88
+ }
89
+ messageUtils.showErrorMessage(errorMessage);
90
+ return Promise.reject(error);
91
+ });
92
+ const beforeRequestConfig = (config) => {
93
+ if (!config.url) {
94
+ return console.error("参数[url]不存在");
95
+ }
96
+ config.headers["X-Requested-With"] = "XMLHttpRequest";
97
+ let gatewayAccessToken = storageUtils.getLocalStorageItem("gatewayAccessToken") ?? "";
98
+ let gatewayPublicKey = storageUtils.getLocalStorageItem("gatewayPublicKey") ?? "";
99
+ let ssoAccessToken = storageUtils.getLocalStorageItem("ssoAccessToken") ?? "";
100
+ if (gatewayAccessToken) {
101
+ config.headers["Gateway-Access-Token"] = gatewayAccessToken;
102
+ }
103
+ if (gatewayPublicKey) {
104
+ config.headers["Gateway-Public-Key"] = gatewayPublicKey;
105
+ }
106
+ if (ssoAccessToken) {
107
+ config.headers["Sso-Access-Token"] = ssoAccessToken;
108
+ }
109
+ config.headers["Request-Id"] = (/* @__PURE__ */ new Date()).getTime().toString() + parseInt((Math.random() * 1e4).toString()).toString();
110
+ };
111
+ const refreshSsoAccessToken = (res) => {
112
+ let ssoRefreshToken = encodeURIComponent(storageUtils.getLocalStorageItem("ssoRefreshToken") ?? "");
113
+ if (!ssoRefreshToken) {
114
+ return messageUtils.showErrorMessage("参数[ssoRefreshToken]为空");
115
+ }
116
+ return new Promise((resolve, reject) => {
117
+ const config = res.config;
118
+ config.params = {
119
+ ssoRefreshToken
120
+ };
121
+ axios.get(`/sso-api/client/sso-auth/getSsoRefreshToken`, config).then((res2) => {
122
+ var _a;
123
+ if (((_a = res2 == null ? void 0 : res2.data) == null ? void 0 : _a.statusCode) !== 200) {
124
+ return reject();
125
+ }
126
+ ssoUtils.setSsoAccessToken(res2.data.data);
127
+ return resolve(void 0);
128
+ });
129
+ });
130
+ };
131
+ const getBaseUrl = (url) => {
132
+ url = url || location.href;
133
+ let arr = url.split("/");
134
+ if (arr.length > 3) {
135
+ var baseUrl = "";
136
+ for (let i = 0; i < arr.length; i++) {
137
+ if (i <= 3) {
138
+ baseUrl += arr[i] + "/";
139
+ }
140
+ }
141
+ if (baseUrl) {
142
+ return baseUrl.substring(0, baseUrl.length - 1);
143
+ }
144
+ } else {
145
+ console.error("地址存在问题");
146
+ }
147
+ };
148
+ const _withScopeId = (n) => (vue.pushScopeId("data-v-894ffd06"), n = n(), vue.popScopeId(), n);
149
+ const _hoisted_1 = { class: "slider-captcha-container" };
150
+ const _hoisted_2 = { class: "slider-captcha-title" };
151
+ const _hoisted_3 = /* @__PURE__ */ _withScopeId(() => /* @__PURE__ */ vue.createElementVNode("i", { class: "el-icon-refresh" }, null, -1));
152
+ const _hoisted_4 = [
153
+ _hoisted_3
154
+ ];
155
+ const _hoisted_5 = ["width", "height"];
156
+ const _hoisted_6 = ["width", "height"];
157
+ const _hoisted_7 = ["width", "height"];
158
+ const _hoisted_8 = {
159
+ key: 0,
160
+ class: "slider-button-icon iconfont icon-slider-init yu-color-primary"
161
+ };
162
+ const _hoisted_9 = {
163
+ key: 1,
164
+ class: "slider-button-icon iconfont icon-slider-slide yu-color-primary"
165
+ };
166
+ const _hoisted_10 = { class: "slider-hint" };
167
+ const _sfc_main = /* @__PURE__ */ vue.defineComponent({
168
+ ...{ name: "SliderCaptcha" },
169
+ __name: "SliderCaptcha",
170
+ props: {
171
+ blockLength: { default: 42 },
172
+ blockRadius: { default: 10 },
173
+ canvasWidth: { default: 320 },
174
+ canvasHeight: { default: 155 },
175
+ sliderHint: { default: "向右滑动" },
176
+ accuracy: { default: 3 },
177
+ imageList: { default: [] }
178
+ },
179
+ emits: ["success", "fail", "close"],
180
+ setup(__props, { emit: __emit }) {
181
+ const props = __props;
182
+ const emit = __emit;
183
+ const canvas = vue.ref(null);
184
+ const block = vue.ref(null);
185
+ const isFrontCheck = vue.ref(false);
186
+ const verifyActive = vue.ref(false);
187
+ const verifySuccess = vue.ref(false);
188
+ const verifyFail = vue.ref(false);
189
+ const canvasCtx = vue.ref(null);
190
+ const blockCtx = vue.ref(null);
191
+ const blockWidth = vue.ref(props.blockLength * 2);
192
+ const blockX = vue.ref(void 0);
193
+ const blockY = vue.ref(void 0);
194
+ const image = vue.ref(void 0);
195
+ const originX = vue.ref(void 0);
196
+ const originY = vue.ref(void 0);
197
+ const dragDistanceList = vue.ref([]);
198
+ const sliderBoxWidth = vue.ref(0);
199
+ const sliderButtonLeft = vue.ref(0);
200
+ const isMouseDown = vue.ref(false);
201
+ const isLoading = vue.ref(true);
202
+ const timestamp = vue.ref(null);
203
+ const successHint = vue.ref("");
204
+ const key = vue.ref(void 0);
205
+ const isSliderSlide = vue.ref(false);
206
+ vue.onMounted(() => {
207
+ init();
208
+ });
209
+ const init = () => {
210
+ initDom();
211
+ bindEvents();
212
+ };
213
+ const initDom = () => {
214
+ if (isFrontCheck.value) {
215
+ canvasCtx.value = canvas.value.getContext("2d");
216
+ blockCtx.value = block.value.getContext("2d");
217
+ initImage();
218
+ } else {
219
+ getCaptcha();
220
+ }
221
+ };
222
+ const getCaptcha = () => {
223
+ http.get("/framework-api/standard/framework-captcha/getSliderCaptcha", { params: {} }).then((res) => {
224
+ key.value = res.data.data.key;
225
+ block.value.src = res.data.data.blockSrc;
226
+ block.value.style.top = res.data.data.blockY + "px";
227
+ canvas.value.src = res.data.data.canvasSrc;
228
+ setTimeout(() => {
229
+ isLoading.value = false;
230
+ }, 200);
231
+ });
232
+ };
233
+ const initImage = () => {
234
+ const imageObject = createImage(() => {
235
+ drawBlock();
236
+ let { canvasWidth, canvasHeight, blockX: blockX2, blockY: blockY2, blockRadius, blockWidth: blockWidth2 } = this;
237
+ canvasCtx.value.drawImage(image, 0, 0, canvasWidth, canvasHeight);
238
+ blockCtx.value.drawImage(image, 0, 0, canvasWidth, canvasHeight);
239
+ let yAxle = blockY2 - blockRadius * 2;
240
+ let ImageData = blockCtx.value.getImageData(blockX2, yAxle, blockWidth2, blockWidth2);
241
+ block.value.width = blockWidth2;
242
+ blockCtx.value.putImageData(ImageData, 0, yAxle);
243
+ isLoading.value = false;
244
+ key.value = "loyer";
245
+ });
246
+ image.value = imageObject;
247
+ };
248
+ const createImage = (onload) => {
249
+ const image2 = document.createElement("img");
250
+ image2.crossOrigin = "Anonymous";
251
+ image2.onload = onload;
252
+ image2.onerror = () => {
253
+ image2.src = `${getBaseUrl()}/img/slider-captcha/pic-0.jpeg`;
254
+ };
255
+ image2.src = getImageSrc();
256
+ return image2;
257
+ };
258
+ const getImageSrc = () => {
259
+ const len = props.imageList.length;
260
+ return len > 0 ? props.imageList[getNonceByRange(0, len)] : `https://loyer.wang/view/ftp/wallpaper/${getNonceByRange(1, 1e3)}.jpg`;
261
+ };
262
+ const getNonceByRange = (start, end) => {
263
+ return Math.round(Math.random() * (end - start) + start);
264
+ };
265
+ const drawBlock = () => {
266
+ blockX.value = getNonceByRange(blockWidth.value + 10, props.canvasWidth - (blockWidth.value + 10));
267
+ blockY.value = getNonceByRange(10 + props.blockRadius * 2, props.canvasHeight - (blockWidth.value + 10));
268
+ draw(canvasCtx.value, "fill");
269
+ draw(blockCtx.value, "clip");
270
+ };
271
+ const draw = (ctx, operation) => {
272
+ const PI = Math.PI;
273
+ let { blockX: x, blockY: y, blockLength: l, blockRadius: r } = this;
274
+ ctx.beginPath();
275
+ ctx.moveTo(x, y);
276
+ ctx.arc(x + l / 2, y - r + 2, r, 0.72 * PI, 2.26 * PI);
277
+ ctx.lineTo(x + l, y);
278
+ ctx.arc(x + l + r - 2, y + l / 2, r, 1.21 * PI, 2.78 * PI);
279
+ ctx.lineTo(x + l, y + l);
280
+ ctx.lineTo(x, y + l);
281
+ ctx.arc(x + r - 2, y + l / 2, r + 0.4, 2.76 * PI, 1.24 * PI, true);
282
+ ctx.lineTo(x, y);
283
+ ctx.lineWidth = 2;
284
+ ctx.fillStyle = "rgba(255, 255, 255, 0.9)";
285
+ ctx.strokeStyle = "rgba(255, 255, 255, 0.9)";
286
+ ctx.stroke();
287
+ ctx[operation]();
288
+ ctx.globalCompositeOperation = "destination-over";
289
+ };
290
+ const bindEvents = () => {
291
+ var _a, _b, _c;
292
+ (_a = document.getElementById("slider-button")) == null ? void 0 : _a.addEventListener("mousedown", (event) => {
293
+ startEvent(event.clientX, event.clientY);
294
+ updateSliderButtonImage("slide");
295
+ });
296
+ document.addEventListener("mousemove", (event) => {
297
+ moveEvent(event.clientX, event.clientY);
298
+ });
299
+ document.addEventListener("mouseup", (event) => {
300
+ endEvent(event.clientX);
301
+ });
302
+ (_b = document.getElementById("slider-button")) == null ? void 0 : _b.addEventListener("click", (event) => {
303
+ updateSliderButtonImage("init");
304
+ });
305
+ (_c = document.getElementById("slider-button")) == null ? void 0 : _c.addEventListener("touchstart", (event) => {
306
+ startEvent(event.changedTouches[0].pageX, event.changedTouches[0].pageY);
307
+ });
308
+ document.addEventListener("touchmove", (event) => {
309
+ moveEvent(event.changedTouches[0].pageX, event.changedTouches[0].pageY);
310
+ });
311
+ document.addEventListener("touchend", (event) => {
312
+ endEvent(event.changedTouches[0].pageX);
313
+ });
314
+ };
315
+ const updateSliderButtonImage = (type) => {
316
+ if (type == "init") {
317
+ isSliderSlide.value = false;
318
+ } else if (type == "slide") {
319
+ isSliderSlide.value = true;
320
+ }
321
+ };
322
+ const checkImgSrc = () => {
323
+ if (isFrontCheck.value) {
324
+ return true;
325
+ }
326
+ return !!canvas.value.src;
327
+ };
328
+ const startEvent = (clientX, clientY) => {
329
+ if (!checkImgSrc() || isLoading.value || verifySuccess.value) {
330
+ return;
331
+ }
332
+ originX.value = clientX;
333
+ originY.value = clientY;
334
+ isMouseDown.value = true;
335
+ timestamp.value = +/* @__PURE__ */ new Date();
336
+ updateSliderButtonImage("slide");
337
+ };
338
+ const moveEvent = (clientX, clientY) => {
339
+ if (!isMouseDown.value) {
340
+ return false;
341
+ }
342
+ const moveX = clientX - originX.value;
343
+ const moveY = clientY - originY.value;
344
+ if (moveX < 0 || moveX + 40 >= props.canvasWidth) {
345
+ return false;
346
+ }
347
+ sliderButtonLeft.value = moveX > props.canvasWidth - 56 ? props.canvasWidth - 56 : moveX;
348
+ let blockLeft = (props.canvasWidth - 40 - 20) / (props.canvasWidth - 40) * moveX;
349
+ block.value.style.left = (blockLeft > props.canvasWidth - 56 - 18 - 7 ? props.canvasWidth - 56 - 18 - 7 : blockLeft) + "px";
350
+ verifyActive.value = true;
351
+ sliderBoxWidth.value = moveX + 28;
352
+ dragDistanceList.value.push(moveY);
353
+ };
354
+ const endEvent = (clientX) => {
355
+ if (!isMouseDown.value) {
356
+ return false;
357
+ }
358
+ isMouseDown.value = false;
359
+ if (clientX === originX.value) {
360
+ return false;
361
+ }
362
+ isLoading.value = true;
363
+ verifyActive.value = false;
364
+ timestamp.value = +/* @__PURE__ */ new Date() - timestamp.value;
365
+ const moveLength = parseInt(block.value.style.left);
366
+ if (timestamp.value > 1e4) {
367
+ verifyFailEvent();
368
+ } else {
369
+ if (!turingTest()) {
370
+ verifyFailEvent();
371
+ } else {
372
+ if (isFrontCheck.value) {
373
+ const accuracyValue = props.accuracy <= 1 ? 1 : props.accuracy > 10 ? 10 : props.accuracy;
374
+ const spliced = Math.abs(moveLength - blockX.value) <= accuracyValue;
375
+ if (!spliced) {
376
+ verifyFailEvent();
377
+ } else {
378
+ emit("success", { key: key.value, value: moveLength });
379
+ }
380
+ return;
381
+ }
382
+ let params = {
383
+ key: key.value,
384
+ captcha: moveLength
385
+ };
386
+ http.get("/framework-api/standard/framework-captcha/validateSliderCaptcha", { params }).then((res) => {
387
+ emit("success", { key: key.value, value: moveLength });
388
+ }).catch(() => {
389
+ verifyFailEvent();
390
+ });
391
+ }
392
+ }
393
+ updateSliderButtonImage("init");
394
+ };
395
+ const turingTest = () => {
396
+ const arr = dragDistanceList.value;
397
+ const average = arr.reduce(calcSum) / arr.length;
398
+ const deviations = arr.map((x) => x - average);
399
+ const stdDev = Math.sqrt(deviations.map(calcSquare).reduce(calcSum) / arr.length);
400
+ return average !== stdDev;
401
+ };
402
+ const verifyFailEvent = () => {
403
+ verifyFail.value = true;
404
+ emit("fail", {});
405
+ refresh();
406
+ };
407
+ const refresh = () => {
408
+ setTimeout(() => {
409
+ verifyFail.value = false;
410
+ }, 300);
411
+ isLoading.value = true;
412
+ verifyActive.value = false;
413
+ verifySuccess.value = false;
414
+ block.value.style.left = 0;
415
+ sliderBoxWidth.value = 0;
416
+ sliderButtonLeft.value = 0;
417
+ vue.nextTick(() => {
418
+ if (isFrontCheck.value) {
419
+ let { canvasWidth, canvasHeight } = this;
420
+ canvasCtx.value.clearRect(0, 0, canvasWidth, canvasHeight);
421
+ blockCtx.value.clearRect(0, 0, canvasWidth, canvasHeight);
422
+ block.value.width = canvasWidth;
423
+ image.value.src = getImageSrc();
424
+ } else {
425
+ getCaptcha();
426
+ }
427
+ });
428
+ };
429
+ const close = () => {
430
+ emit("close");
431
+ };
432
+ const calcSum = (x, y) => {
433
+ return x + y;
434
+ };
435
+ const calcSquare = (x) => {
436
+ return x * x;
437
+ };
438
+ return (_ctx, _cache) => {
439
+ return vue.openBlock(), vue.createElementBlock("div", _hoisted_1, [
440
+ vue.createElementVNode("div", _hoisted_2, [
441
+ vue.createTextVNode(" 完成拼图验证 "),
442
+ vue.createElementVNode("div", {
443
+ onClick: refresh,
444
+ class: "slider-captcha-refresh-icon"
445
+ }, _hoisted_4),
446
+ vue.createElementVNode("div", {
447
+ onClick: close,
448
+ class: "slider-captcha-close-icon"
449
+ }, [
450
+ vue.createVNode(vue.unref(iconsVue.CircleClose))
451
+ ])
452
+ ]),
453
+ vue.createElementVNode("div", {
454
+ class: "slider-captcha",
455
+ style: vue.normalizeStyle({ width: _ctx.canvasWidth + "px" }),
456
+ onselectstart: "return false;"
457
+ }, [
458
+ isLoading.value ? (vue.openBlock(), vue.createElementBlock("div", {
459
+ key: 0,
460
+ class: vue.normalizeClass({ "img-loading": isLoading.value }),
461
+ style: vue.normalizeStyle({ height: _ctx.canvasHeight + "px" })
462
+ }, null, 6)) : vue.createCommentVNode("", true),
463
+ verifySuccess.value ? (vue.openBlock(), vue.createElementBlock("div", {
464
+ key: 1,
465
+ class: "success-hint",
466
+ style: vue.normalizeStyle({ height: _ctx.canvasHeight + "px" })
467
+ }, vue.toDisplayString(successHint.value), 5)) : vue.createCommentVNode("", true),
468
+ isFrontCheck.value ? (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 2 }, [
469
+ vue.createElementVNode("canvas", {
470
+ ref_key: "canvas",
471
+ ref: canvas,
472
+ class: "slide-canvas",
473
+ width: _ctx.canvasWidth,
474
+ height: _ctx.canvasHeight
475
+ }, null, 8, _hoisted_5),
476
+ vue.createElementVNode("canvas", {
477
+ ref_key: "block",
478
+ ref: block,
479
+ class: "slide-block",
480
+ width: _ctx.canvasWidth,
481
+ height: _ctx.canvasHeight
482
+ }, null, 8, _hoisted_6)
483
+ ], 64)) : (vue.openBlock(), vue.createElementBlock(vue.Fragment, { key: 3 }, [
484
+ vue.createElementVNode("img", {
485
+ ref_key: "canvas",
486
+ ref: canvas,
487
+ class: "slide-canvas",
488
+ width: _ctx.canvasWidth,
489
+ height: _ctx.canvasHeight
490
+ }, null, 8, _hoisted_7),
491
+ vue.createElementVNode("img", {
492
+ ref_key: "block",
493
+ ref: block,
494
+ class: vue.normalizeClass(["slide-block", { "verify-fail": verifyFail.value }])
495
+ }, null, 2)
496
+ ], 64)),
497
+ vue.createElementVNode("div", {
498
+ class: vue.normalizeClass(["slider", { "verify-active": verifyActive.value, "verify-success": verifySuccess.value, "verify-fail": verifyFail.value }])
499
+ }, [
500
+ vue.createElementVNode("div", {
501
+ class: "slider-box background-primary",
502
+ style: vue.normalizeStyle({ width: sliderBoxWidth.value + "px" })
503
+ }, [
504
+ vue.createElementVNode("div", {
505
+ class: "slider-button",
506
+ id: "slider-button",
507
+ style: vue.normalizeStyle({ left: sliderButtonLeft.value + "px" })
508
+ }, [
509
+ !isSliderSlide.value ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_8)) : (vue.openBlock(), vue.createElementBlock("div", _hoisted_9))
510
+ ], 4)
511
+ ], 4),
512
+ vue.createElementVNode("span", _hoisted_10, vue.toDisplayString(_ctx.sliderHint), 1)
513
+ ], 2)
514
+ ], 4)
515
+ ]);
516
+ };
517
+ }
518
+ });
519
+ const _export_sfc = (sfc, props) => {
520
+ const target = sfc.__vccOpts || sfc;
521
+ for (const [key, val] of props) {
522
+ target[key] = val;
523
+ }
524
+ return target;
525
+ };
526
+ const SliderCaptcha = /* @__PURE__ */ _export_sfc(_sfc_main, [["__scopeId", "data-v-894ffd06"]]);
527
+ module.exports = SliderCaptcha;