yh-client 2.0.15 → 2.0.16
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.
- package/index.es.js +273 -244
- package/index.es.js.map +1 -1
- package/package.json +1 -1
package/index.es.js
CHANGED
|
@@ -1,44 +1,44 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import { httpRequest as
|
|
10
|
-
function
|
|
11
|
-
const e = new TextEncoder().encode(
|
|
12
|
-
return btoa(
|
|
13
|
-
}
|
|
14
|
-
function
|
|
15
|
-
const e = atob(
|
|
16
|
-
return new TextDecoder().decode(
|
|
17
|
-
}
|
|
18
|
-
function D(
|
|
1
|
+
import y from "axios";
|
|
2
|
+
import b from "qs";
|
|
3
|
+
import { merge as h, get as M, set as U, cloneDeep as P, isEqual as j, assign as R } from "lodash-es";
|
|
4
|
+
import { reactive as q, ref as p } from "vue";
|
|
5
|
+
import { MD5 as H } from "crypto-js";
|
|
6
|
+
import { ElMessage as L } from "element-plus";
|
|
7
|
+
import { defineStore as A } from "pinia";
|
|
8
|
+
import N from "crypto-js/md5";
|
|
9
|
+
import { httpRequest as $ } from "yh-client";
|
|
10
|
+
function K(o) {
|
|
11
|
+
const e = new TextEncoder().encode(o), s = Array.from(e, (n) => String.fromCharCode(n)).join("");
|
|
12
|
+
return btoa(s);
|
|
13
|
+
}
|
|
14
|
+
function B(o) {
|
|
15
|
+
const e = atob(o), s = Uint8Array.from(e, (n) => n.charCodeAt(0));
|
|
16
|
+
return new TextDecoder().decode(s);
|
|
17
|
+
}
|
|
18
|
+
function D(o) {
|
|
19
19
|
try {
|
|
20
|
-
return
|
|
20
|
+
return K(o).split("").reverse().join("");
|
|
21
21
|
} catch {
|
|
22
|
-
return
|
|
22
|
+
return o;
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
|
-
function J(
|
|
25
|
+
function J(o) {
|
|
26
26
|
try {
|
|
27
|
-
let e =
|
|
28
|
-
return
|
|
27
|
+
let e = o.split("").reverse().join("");
|
|
28
|
+
return B(e);
|
|
29
29
|
} catch {
|
|
30
|
-
return
|
|
30
|
+
return o;
|
|
31
31
|
}
|
|
32
32
|
}
|
|
33
|
-
const
|
|
34
|
-
const e = localStorage.getItem(
|
|
33
|
+
const k = (o) => {
|
|
34
|
+
const e = localStorage.getItem(o);
|
|
35
35
|
if (e !== null)
|
|
36
36
|
try {
|
|
37
|
-
const
|
|
37
|
+
const s = J(e);
|
|
38
38
|
try {
|
|
39
|
-
return JSON.parse(
|
|
39
|
+
return JSON.parse(s);
|
|
40
40
|
} catch {
|
|
41
|
-
return
|
|
41
|
+
return s;
|
|
42
42
|
}
|
|
43
43
|
} catch {
|
|
44
44
|
try {
|
|
@@ -48,133 +48,160 @@ const w = (s) => {
|
|
|
48
48
|
}
|
|
49
49
|
}
|
|
50
50
|
return null;
|
|
51
|
-
},
|
|
52
|
-
let
|
|
53
|
-
typeof e == "object" ?
|
|
51
|
+
}, E = (o, e) => {
|
|
52
|
+
let s;
|
|
53
|
+
typeof e == "object" ? s = JSON.stringify(e) : s = String(e);
|
|
54
54
|
try {
|
|
55
|
-
const n = D(String(
|
|
56
|
-
localStorage.setItem(
|
|
55
|
+
const n = D(String(s));
|
|
56
|
+
localStorage.setItem(o, n);
|
|
57
57
|
} catch {
|
|
58
|
-
localStorage.setItem(
|
|
58
|
+
localStorage.setItem(o, String(s));
|
|
59
59
|
}
|
|
60
|
-
},
|
|
61
|
-
localStorage.removeItem(
|
|
62
|
-
},
|
|
60
|
+
}, C = (o) => {
|
|
61
|
+
localStorage.removeItem(o);
|
|
62
|
+
}, _ = () => {
|
|
63
63
|
localStorage.clear(), sessionStorage.clear();
|
|
64
64
|
};
|
|
65
|
-
class
|
|
65
|
+
class G {
|
|
66
66
|
constructor() {
|
|
67
|
-
this.
|
|
67
|
+
this.builtinLayer = {}, this.hostLayer = {}, this.codeLayer = {}, this.serverLayer = {}, this.snapshot = q({});
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 重算合并视图:保持同一 reactive 代理对象,属性级依赖追踪不失效
|
|
71
|
+
*/
|
|
72
|
+
rebuild() {
|
|
73
|
+
const e = h({}, this.builtinLayer, this.hostLayer, this.codeLayer, this.serverLayer);
|
|
74
|
+
for (const s of Object.keys(this.snapshot))
|
|
75
|
+
delete this.snapshot[s];
|
|
76
|
+
Object.assign(this.snapshot, e);
|
|
68
77
|
}
|
|
69
78
|
/**
|
|
70
|
-
*
|
|
79
|
+
* 获取配置值(从生效视图读取,无 path 时返回整个视图对象)
|
|
71
80
|
*/
|
|
72
|
-
get(e,
|
|
73
|
-
return e ?
|
|
81
|
+
get(e, s) {
|
|
82
|
+
return e ? M(this.snapshot, e, s) : this.snapshot;
|
|
74
83
|
}
|
|
75
84
|
/**
|
|
76
|
-
*
|
|
85
|
+
* 设置配置值(写入代码层)
|
|
77
86
|
*/
|
|
78
|
-
set(e,
|
|
79
|
-
|
|
87
|
+
set(e, s) {
|
|
88
|
+
U(this.codeLayer, e, s), this.rebuild();
|
|
80
89
|
}
|
|
81
90
|
/**
|
|
82
|
-
*
|
|
91
|
+
* 合并宿主配置
|
|
83
92
|
*/
|
|
84
93
|
merge(e) {
|
|
85
|
-
|
|
94
|
+
h(this.hostLayer, e), this.rebuild();
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* 合并包内内置默认(优先级最低,不会覆盖宿主/代码设置)
|
|
98
|
+
*/
|
|
99
|
+
mergeBuiltin(e) {
|
|
100
|
+
h(this.builtinLayer, e), this.rebuild();
|
|
86
101
|
}
|
|
87
102
|
/**
|
|
88
|
-
*
|
|
103
|
+
* 整层替换服务端参数(禁用/删除的参数随替换回落到低层值)
|
|
104
|
+
*/
|
|
105
|
+
replaceServer(e) {
|
|
106
|
+
this.serverLayer = e, this.rebuild();
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* 初始化配置(重置宿主层,清空代码/服务端层,保留内置默认)
|
|
89
110
|
*/
|
|
90
111
|
init(e) {
|
|
91
|
-
this.
|
|
112
|
+
this.hostLayer = { ...e }, this.codeLayer = {}, this.serverLayer = {}, this.rebuild();
|
|
92
113
|
}
|
|
93
114
|
/**
|
|
94
115
|
* Token 快捷访问
|
|
95
116
|
*/
|
|
96
117
|
get token() {
|
|
97
|
-
return this.
|
|
118
|
+
return this.get("token");
|
|
98
119
|
}
|
|
99
120
|
set token(e) {
|
|
100
|
-
this.
|
|
121
|
+
this.set("token", e);
|
|
101
122
|
}
|
|
102
123
|
/**
|
|
103
124
|
* SaToken 快捷访问
|
|
104
125
|
*/
|
|
105
126
|
get saToken() {
|
|
106
|
-
return this.
|
|
127
|
+
return this.get("saToken");
|
|
107
128
|
}
|
|
108
129
|
set saToken(e) {
|
|
109
|
-
this.
|
|
130
|
+
this.set("saToken", e);
|
|
110
131
|
}
|
|
111
132
|
/**
|
|
112
133
|
* StorageKey 快捷访问
|
|
113
134
|
*/
|
|
114
135
|
get storageKey() {
|
|
115
|
-
return this.
|
|
136
|
+
return this.get("storageKey") || "yh-client-storage-key";
|
|
116
137
|
}
|
|
117
138
|
set storageKey(e) {
|
|
118
|
-
this.
|
|
139
|
+
this.set("storageKey", e);
|
|
119
140
|
}
|
|
120
141
|
}
|
|
121
|
-
const
|
|
122
|
-
function
|
|
123
|
-
return
|
|
142
|
+
const i = new G();
|
|
143
|
+
function ge(o, e) {
|
|
144
|
+
return i.get(o, e);
|
|
145
|
+
}
|
|
146
|
+
function pe(o, e) {
|
|
147
|
+
i.set(o, e);
|
|
148
|
+
}
|
|
149
|
+
function ye(o) {
|
|
150
|
+
i.merge(o);
|
|
124
151
|
}
|
|
125
|
-
function
|
|
126
|
-
|
|
152
|
+
function Te(o) {
|
|
153
|
+
i.mergeBuiltin(o);
|
|
127
154
|
}
|
|
128
|
-
function
|
|
129
|
-
|
|
155
|
+
function ke(o) {
|
|
156
|
+
i.replaceServer(o);
|
|
130
157
|
}
|
|
131
|
-
function
|
|
132
|
-
|
|
158
|
+
function we(o) {
|
|
159
|
+
i.init(o);
|
|
133
160
|
}
|
|
134
|
-
async function
|
|
135
|
-
return
|
|
161
|
+
async function me(o) {
|
|
162
|
+
return H(o).toString();
|
|
136
163
|
}
|
|
137
|
-
function
|
|
164
|
+
function ve(o) {
|
|
138
165
|
let e = 0;
|
|
139
|
-
for (let
|
|
140
|
-
const n =
|
|
166
|
+
for (let s = 0; s < o.length; s++) {
|
|
167
|
+
const n = o.charCodeAt(s);
|
|
141
168
|
e = (e << 5) - e + n, e = e & e;
|
|
142
169
|
}
|
|
143
170
|
return Math.abs(e).toString(36);
|
|
144
171
|
}
|
|
145
|
-
const
|
|
146
|
-
return
|
|
147
|
-
}),
|
|
148
|
-
const
|
|
149
|
-
return "xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g, function(
|
|
150
|
-
const n = (
|
|
151
|
-
return (
|
|
172
|
+
const xe = (o) => o.replace(/\_(\w)/g, function(e, s) {
|
|
173
|
+
return s.toUpperCase();
|
|
174
|
+
}), be = () => {
|
|
175
|
+
const o = (/* @__PURE__ */ new Date()).getTime();
|
|
176
|
+
return "xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g, function(s) {
|
|
177
|
+
const n = (o + Math.random() * 16) % 16 | 0;
|
|
178
|
+
return (s === "x" ? n : n & 3 | 8).toString(16);
|
|
152
179
|
}).toUpperCase();
|
|
153
180
|
};
|
|
154
|
-
function
|
|
155
|
-
const n = new CustomEvent(
|
|
156
|
-
|
|
181
|
+
function S(o, e, s = window) {
|
|
182
|
+
const n = new CustomEvent(o, { detail: e });
|
|
183
|
+
s.dispatchEvent(n);
|
|
157
184
|
}
|
|
158
|
-
function
|
|
185
|
+
function F(o, e, s = window) {
|
|
159
186
|
const n = (t) => e(t.detail);
|
|
160
|
-
return
|
|
187
|
+
return s.addEventListener(o, n), () => s.removeEventListener(o, n);
|
|
161
188
|
}
|
|
162
|
-
function
|
|
163
|
-
const n =
|
|
164
|
-
|
|
189
|
+
function Ce(o, e, s = window) {
|
|
190
|
+
const n = F(
|
|
191
|
+
o,
|
|
165
192
|
(t) => {
|
|
166
193
|
e(t), n();
|
|
167
194
|
},
|
|
168
|
-
|
|
195
|
+
s
|
|
169
196
|
);
|
|
170
197
|
return n;
|
|
171
198
|
}
|
|
172
|
-
function
|
|
199
|
+
function Ee(o, e, s = window) {
|
|
173
200
|
const n = (t) => e(t.detail);
|
|
174
|
-
|
|
201
|
+
s.removeEventListener(o, n);
|
|
175
202
|
}
|
|
176
|
-
const
|
|
177
|
-
class
|
|
203
|
+
const Ie = P, Le = j, Se = R;
|
|
204
|
+
class V {
|
|
178
205
|
constructor(e = "") {
|
|
179
206
|
this.timeout = 12e4, this.baseUrl = e, this.queue = {};
|
|
180
207
|
}
|
|
@@ -188,7 +215,7 @@ class F {
|
|
|
188
215
|
* 获取内部配置
|
|
189
216
|
*/
|
|
190
217
|
getInsideConfig() {
|
|
191
|
-
const e =
|
|
218
|
+
const e = i.token, s = i.saToken, n = {
|
|
192
219
|
baseURL: this.baseUrl,
|
|
193
220
|
timeout: this.timeout,
|
|
194
221
|
headers: {}
|
|
@@ -196,48 +223,48 @@ class F {
|
|
|
196
223
|
return e && (n.headers = {
|
|
197
224
|
...n.headers,
|
|
198
225
|
TOKEN: e
|
|
199
|
-
}),
|
|
226
|
+
}), s && (n.headers = {
|
|
200
227
|
...n.headers,
|
|
201
|
-
saToken:
|
|
228
|
+
saToken: s
|
|
202
229
|
}), n;
|
|
203
230
|
}
|
|
204
231
|
/**
|
|
205
232
|
* 销毁加载状态
|
|
206
233
|
*/
|
|
207
234
|
destroy(e) {
|
|
208
|
-
var
|
|
209
|
-
delete this.queue[e], Object.keys(this.queue).length || (
|
|
235
|
+
var s;
|
|
236
|
+
delete this.queue[e], Object.keys(this.queue).length || (s = this.onRequestEnd) == null || s.call(this);
|
|
210
237
|
}
|
|
211
238
|
/**
|
|
212
239
|
* 设置拦截器
|
|
213
240
|
*/
|
|
214
|
-
interceptors(e,
|
|
241
|
+
interceptors(e, s) {
|
|
215
242
|
e.interceptors.request.use(
|
|
216
243
|
(n) => {
|
|
217
244
|
var t;
|
|
218
|
-
return this.queue[
|
|
245
|
+
return this.queue[s] = !0, Object.keys(this.queue).length === 1 && ((t = this.onRequestStart) == null || t.call(this)), n;
|
|
219
246
|
},
|
|
220
247
|
(n) => (console.error("[HTTP] 请求错误:", n), Promise.reject(n))
|
|
221
248
|
), e.interceptors.response.use(
|
|
222
249
|
(n) => {
|
|
223
250
|
const { data: t, status: r, headers: c } = n;
|
|
224
|
-
if (this.destroy(
|
|
251
|
+
if (this.destroy(s), t.result || t.result === void 0)
|
|
225
252
|
return { data: t, status: r, headers: c };
|
|
226
253
|
{
|
|
227
254
|
const { msg: f } = t;
|
|
228
|
-
return this.handleError(f,
|
|
255
|
+
return this.handleError(f, s), { data: t, status: r, headers: c };
|
|
229
256
|
}
|
|
230
257
|
},
|
|
231
|
-
(n) => (this.destroy(
|
|
258
|
+
(n) => (this.destroy(s), n.response ? this.handleHttpError(n, s) : (console.error("[HTTP] 未处理的网络错误", n), this.showMessage("请联系管理员,并查看控制台日志"), Promise.reject(n)))
|
|
232
259
|
);
|
|
233
260
|
}
|
|
234
261
|
/**
|
|
235
262
|
* 处理业务错误
|
|
236
263
|
*/
|
|
237
|
-
handleError(e,
|
|
264
|
+
handleError(e, s) {
|
|
238
265
|
if (e && e !== "无数据" && !(this.onBusinessError && this.onBusinessError(e))) {
|
|
239
266
|
if (e.indexOf("Login Timeout") > -1 || e.indexOf("Timeout") > -1 || e.indexOf("登录超时!") > -1) {
|
|
240
|
-
this.showMessage("登录状态已超时"), this.onLoginRedirect ? this.onLoginRedirect() :
|
|
267
|
+
this.showMessage("登录状态已超时"), this.onLoginRedirect ? this.onLoginRedirect() : S("to:login");
|
|
241
268
|
return;
|
|
242
269
|
}
|
|
243
270
|
if (e.indexOf("violates unique constraint") > -1) {
|
|
@@ -257,19 +284,19 @@ class F {
|
|
|
257
284
|
/**
|
|
258
285
|
* 处理 HTTP 错误
|
|
259
286
|
*/
|
|
260
|
-
handleHttpError(e,
|
|
287
|
+
handleHttpError(e, s) {
|
|
261
288
|
var t, r;
|
|
262
289
|
const { response: n } = e;
|
|
263
290
|
if (!n)
|
|
264
291
|
return Promise.reject(e);
|
|
265
292
|
if (this.onHttpError) {
|
|
266
|
-
const c = this.onHttpError(e,
|
|
293
|
+
const c = this.onHttpError(e, s);
|
|
267
294
|
if (c !== void 0)
|
|
268
295
|
return c;
|
|
269
296
|
}
|
|
270
297
|
switch (n.status) {
|
|
271
298
|
case 401:
|
|
272
|
-
this.onLoginRedirect ? this.onLoginRedirect() :
|
|
299
|
+
this.onLoginRedirect ? this.onLoginRedirect() : S("to:login");
|
|
273
300
|
break;
|
|
274
301
|
case 400:
|
|
275
302
|
console.error("[HTTP] HTTP 400", n);
|
|
@@ -293,7 +320,7 @@ class F {
|
|
|
293
320
|
*/
|
|
294
321
|
showMessage(e) {
|
|
295
322
|
try {
|
|
296
|
-
|
|
323
|
+
L ? L.error(e) : console.error("[HTTP]", e);
|
|
297
324
|
} catch {
|
|
298
325
|
console.error("[HTTP]", e);
|
|
299
326
|
}
|
|
@@ -302,12 +329,12 @@ class F {
|
|
|
302
329
|
* 通用请求
|
|
303
330
|
*/
|
|
304
331
|
request(e) {
|
|
305
|
-
let
|
|
306
|
-
e.type !== "json" &&
|
|
307
|
-
const n =
|
|
332
|
+
let s = e.data;
|
|
333
|
+
e.type !== "json" && s && typeof s == "object" && (s = b.stringify(s)), e.type === "json" && (e.headers || (e.headers = {}), e.headers["Content-Type"] = "application/json");
|
|
334
|
+
const n = y.create(), t = h(this.getInsideConfig(), {
|
|
308
335
|
url: e.url,
|
|
309
336
|
method: e.method || "GET",
|
|
310
|
-
data:
|
|
337
|
+
data: s,
|
|
311
338
|
params: e.params,
|
|
312
339
|
headers: e.headers,
|
|
313
340
|
timeout: e.timeout,
|
|
@@ -318,23 +345,23 @@ class F {
|
|
|
318
345
|
/**
|
|
319
346
|
* GET 请求
|
|
320
347
|
*/
|
|
321
|
-
get(e,
|
|
322
|
-
return this.request({ url: e, method: "GET", params:
|
|
348
|
+
get(e, s) {
|
|
349
|
+
return this.request({ url: e, method: "GET", params: s });
|
|
323
350
|
}
|
|
324
351
|
/**
|
|
325
352
|
* POST 请求
|
|
326
353
|
*/
|
|
327
|
-
post(e,
|
|
328
|
-
return this.request({ url: e, method: "POST", data:
|
|
354
|
+
post(e, s, n) {
|
|
355
|
+
return this.request({ url: e, method: "POST", data: s, type: n || "form" });
|
|
329
356
|
}
|
|
330
357
|
/**
|
|
331
358
|
* POST JSON 请求
|
|
332
359
|
*/
|
|
333
|
-
postJson(e,
|
|
334
|
-
const n =
|
|
360
|
+
postJson(e, s) {
|
|
361
|
+
const n = y.create(), t = h(this.getInsideConfig(), {
|
|
335
362
|
url: e,
|
|
336
363
|
method: "POST",
|
|
337
|
-
data:
|
|
364
|
+
data: s,
|
|
338
365
|
headers: {
|
|
339
366
|
"Content-Type": "application/json"
|
|
340
367
|
}
|
|
@@ -344,11 +371,11 @@ class F {
|
|
|
344
371
|
/**
|
|
345
372
|
* 上传文件
|
|
346
373
|
*/
|
|
347
|
-
upload(e,
|
|
348
|
-
const n =
|
|
374
|
+
upload(e, s) {
|
|
375
|
+
const n = y.create(), t = h(this.getInsideConfig(), {
|
|
349
376
|
url: e,
|
|
350
377
|
method: "POST",
|
|
351
|
-
data:
|
|
378
|
+
data: s,
|
|
352
379
|
headers: {
|
|
353
380
|
"Content-Type": "multipart/form-data"
|
|
354
381
|
}
|
|
@@ -358,12 +385,12 @@ class F {
|
|
|
358
385
|
/**
|
|
359
386
|
* 下载文件(POST)
|
|
360
387
|
*/
|
|
361
|
-
download(e,
|
|
362
|
-
const t =
|
|
388
|
+
download(e, s, n) {
|
|
389
|
+
const t = y.create(), r = h(this.getInsideConfig(), {
|
|
363
390
|
url: e,
|
|
364
391
|
method: "POST",
|
|
365
392
|
responseType: "blob",
|
|
366
|
-
data:
|
|
393
|
+
data: s ? b.stringify(s) : void 0
|
|
367
394
|
});
|
|
368
395
|
return this.interceptors(t, e), t.interceptors.response.use(
|
|
369
396
|
(c) => {
|
|
@@ -371,29 +398,29 @@ class F {
|
|
|
371
398
|
this.showMessage("导出文件异常: " + c.data.msg);
|
|
372
399
|
return;
|
|
373
400
|
}
|
|
374
|
-
const f = (c.headers["content-disposition"] || `filename=文件-${Date.now()}`).split("filename=")[1],
|
|
375
|
-
l.href =
|
|
376
|
-
const { data: d, status:
|
|
377
|
-
return { data: d, status:
|
|
401
|
+
const f = (c.headers["content-disposition"] || `filename=文件-${Date.now()}`).split("filename=")[1], w = new Blob([c.data]), l = document.createElement("a"), g = window.URL.createObjectURL(w);
|
|
402
|
+
l.href = g, l.download = decodeURIComponent(this.resolveFileName(f, n)), document.body.appendChild(l), l.click(), document.body.removeChild(l), window.URL.revokeObjectURL(g);
|
|
403
|
+
const { data: d, status: a, headers: u } = c;
|
|
404
|
+
return { data: d, status: a, headers: u };
|
|
378
405
|
}
|
|
379
406
|
), t(r);
|
|
380
407
|
}
|
|
381
408
|
/**
|
|
382
409
|
* 导出文件(GET)
|
|
383
410
|
*/
|
|
384
|
-
export(e,
|
|
385
|
-
const t =
|
|
411
|
+
export(e, s, n) {
|
|
412
|
+
const t = y.create(), r = h(this.getInsideConfig(), {
|
|
386
413
|
url: e,
|
|
387
414
|
method: "GET",
|
|
388
415
|
responseType: "blob",
|
|
389
|
-
data:
|
|
416
|
+
data: s ? b.stringify(s) : void 0
|
|
390
417
|
});
|
|
391
418
|
return this.interceptors(t, e), t.interceptors.response.use(
|
|
392
419
|
(c) => {
|
|
393
|
-
const f = (c.headers["content-disposition"] || `filename=文件-${Date.now()}`).split("filename=")[1],
|
|
394
|
-
l.href =
|
|
395
|
-
const { data: d, status:
|
|
396
|
-
return { data: d, status:
|
|
420
|
+
const f = (c.headers["content-disposition"] || `filename=文件-${Date.now()}`).split("filename=")[1], w = new Blob([c.data]), l = document.createElement("a"), g = window.URL.createObjectURL(w);
|
|
421
|
+
l.href = g, l.download = decodeURIComponent(this.resolveFileName(f, n)), document.body.appendChild(l), l.click(), document.body.removeChild(l), window.URL.revokeObjectURL(g);
|
|
422
|
+
const { data: d, status: a, headers: u } = c;
|
|
423
|
+
return { data: d, status: a, headers: u };
|
|
397
424
|
}
|
|
398
425
|
), t(r);
|
|
399
426
|
}
|
|
@@ -401,63 +428,63 @@ class F {
|
|
|
401
428
|
* 解析下载文件名
|
|
402
429
|
* fileName 含 . 时追加服务器文件名的扩展名
|
|
403
430
|
*/
|
|
404
|
-
resolveFileName(e,
|
|
405
|
-
if (!
|
|
406
|
-
if (
|
|
431
|
+
resolveFileName(e, s) {
|
|
432
|
+
if (!s) return e || "";
|
|
433
|
+
if (s.indexOf(".") > -1) {
|
|
407
434
|
const n = (e || "").split(".")[1];
|
|
408
|
-
return n ?
|
|
435
|
+
return n ? s + "." + n : s;
|
|
409
436
|
}
|
|
410
|
-
return
|
|
437
|
+
return s;
|
|
411
438
|
}
|
|
412
439
|
}
|
|
413
|
-
const
|
|
414
|
-
function
|
|
415
|
-
return /^[\x20-\x7E]*$/.test(
|
|
440
|
+
const m = new V(), v = "SATOKEN", x = "login-token";
|
|
441
|
+
function O(o) {
|
|
442
|
+
return /^[\x20-\x7E]*$/.test(o);
|
|
416
443
|
}
|
|
417
|
-
function
|
|
418
|
-
const
|
|
419
|
-
|
|
420
|
-
const e =
|
|
421
|
-
e &&
|
|
444
|
+
function Oe() {
|
|
445
|
+
const o = k(x);
|
|
446
|
+
o && O(o) ? i.token = o : (i.token = "", C(x));
|
|
447
|
+
const e = k(v);
|
|
448
|
+
e && O(e) ? i.saToken = e : (i.saToken = "", C(v));
|
|
422
449
|
}
|
|
423
|
-
function
|
|
424
|
-
|
|
450
|
+
function W(o) {
|
|
451
|
+
E(x, o), i.token = o;
|
|
425
452
|
}
|
|
426
|
-
function
|
|
427
|
-
if (
|
|
428
|
-
return
|
|
429
|
-
const
|
|
430
|
-
return
|
|
453
|
+
function Y() {
|
|
454
|
+
if (i.token !== void 0)
|
|
455
|
+
return i.token;
|
|
456
|
+
const o = k(x);
|
|
457
|
+
return i.token = o || "", i.token;
|
|
431
458
|
}
|
|
432
|
-
function
|
|
433
|
-
|
|
434
|
-
}
|
|
435
|
-
function z() {
|
|
436
|
-
if (a.saToken !== void 0)
|
|
437
|
-
return a.saToken;
|
|
438
|
-
const s = w(m);
|
|
439
|
-
return a.saToken = s || "", a.saToken;
|
|
459
|
+
function z(o) {
|
|
460
|
+
E(v, o), i.saToken = o;
|
|
440
461
|
}
|
|
441
462
|
function Q() {
|
|
442
|
-
|
|
463
|
+
if (i.saToken !== void 0)
|
|
464
|
+
return i.saToken;
|
|
465
|
+
const o = k(v);
|
|
466
|
+
return i.saToken = o || "", i.saToken;
|
|
443
467
|
}
|
|
444
468
|
function X() {
|
|
445
|
-
|
|
469
|
+
i.token = "", i.saToken = "", _();
|
|
470
|
+
}
|
|
471
|
+
function Z() {
|
|
472
|
+
X();
|
|
446
473
|
}
|
|
447
|
-
function
|
|
448
|
-
const e = [],
|
|
449
|
-
return
|
|
474
|
+
function ee(o) {
|
|
475
|
+
const e = [], s = {}, n = {};
|
|
476
|
+
return o = JSON.parse(JSON.stringify(o)), o.forEach(function(t) {
|
|
450
477
|
t.parentId && t.parentId !== "0" && (n[t.parentId] || (n[t.parentId] = []), n[t.parentId].push(t)), t.children && t.children.length > 0 && t.children.forEach((r) => {
|
|
451
478
|
r.parentId && (n[r.parentId] || (n[r.parentId] = []), n[r.parentId].push(r));
|
|
452
479
|
});
|
|
453
|
-
}),
|
|
454
|
-
|
|
455
|
-
|
|
480
|
+
}), o.forEach(function(t) {
|
|
481
|
+
s[t.id] = t, t.parentId && n[t.parentId] || (n[t.id] && (s[t.id].children = n[t.id]), e.push(s[t.id])), t.children && t.children.length > 0 && t.children.forEach((r) => {
|
|
482
|
+
s[r.id] = r, n[r.id] && (s[r.id].children = n[r.id]);
|
|
456
483
|
});
|
|
457
484
|
}), e;
|
|
458
485
|
}
|
|
459
|
-
function
|
|
460
|
-
const
|
|
486
|
+
function Me(o, e = !1) {
|
|
487
|
+
const s = ee(o);
|
|
461
488
|
function n(t) {
|
|
462
489
|
if (["SUBPAGE", "JOIN", "APP"].includes(t.menuType || ""))
|
|
463
490
|
return !1;
|
|
@@ -474,56 +501,56 @@ function be(s, e = !1) {
|
|
|
474
501
|
r.id = `/sys/window/${t.windowId || t.id}`;
|
|
475
502
|
else if (t.url.indexOf("http") > -1) {
|
|
476
503
|
const c = "";
|
|
477
|
-
r.id = `/iframe/${
|
|
504
|
+
r.id = `/iframe/${N(t.url)}?url=${encodeURIComponent(t.url)}&title=${t.name}&_keepAlive=${c}`;
|
|
478
505
|
} else
|
|
479
506
|
t.url.indexOf("/") !== 0 && (t.url = `/${t.url}`), r.id = t.url;
|
|
480
507
|
return t.children && (r.hasChildren = !0, r.children = t.children.map(n).filter((c) => !!c)), r;
|
|
481
508
|
}
|
|
482
|
-
return
|
|
509
|
+
return s.map(n).filter((t) => !!t);
|
|
483
510
|
}
|
|
484
|
-
function
|
|
485
|
-
const
|
|
486
|
-
for (const n of
|
|
511
|
+
function Ue(o, e) {
|
|
512
|
+
const s = [];
|
|
513
|
+
for (const n of o) {
|
|
487
514
|
if (!n.url)
|
|
488
515
|
continue;
|
|
489
516
|
let t = null;
|
|
490
|
-
t = e(n), t &&
|
|
517
|
+
t = e(n), t && s.push(t);
|
|
491
518
|
}
|
|
492
|
-
return
|
|
519
|
+
return s;
|
|
493
520
|
}
|
|
494
|
-
const
|
|
495
|
-
let
|
|
496
|
-
function
|
|
497
|
-
if (
|
|
498
|
-
return
|
|
499
|
-
const
|
|
500
|
-
return
|
|
521
|
+
const I = "yh-menu-cache";
|
|
522
|
+
let T = null;
|
|
523
|
+
function te() {
|
|
524
|
+
if (T)
|
|
525
|
+
return T;
|
|
526
|
+
const o = k(I);
|
|
527
|
+
return o ? (T = o, o) : null;
|
|
501
528
|
}
|
|
502
|
-
function
|
|
503
|
-
|
|
529
|
+
function ne(o) {
|
|
530
|
+
T = o, E(I, o);
|
|
504
531
|
}
|
|
505
|
-
function
|
|
506
|
-
|
|
532
|
+
function se() {
|
|
533
|
+
T = null, C(I);
|
|
507
534
|
}
|
|
508
|
-
async function
|
|
509
|
-
const e =
|
|
535
|
+
async function Pe(o = !1) {
|
|
536
|
+
const e = te();
|
|
510
537
|
if (e)
|
|
511
538
|
return e;
|
|
512
|
-
const n = (await
|
|
513
|
-
|
|
539
|
+
const n = (await $.post(
|
|
540
|
+
o ? "loginController/getPdaMenus" : "loginController/getMenus",
|
|
514
541
|
{}
|
|
515
542
|
)).data.data;
|
|
516
|
-
return
|
|
543
|
+
return ne(n), n;
|
|
517
544
|
}
|
|
518
545
|
function oe() {
|
|
519
|
-
|
|
546
|
+
se();
|
|
520
547
|
}
|
|
521
|
-
const
|
|
522
|
-
|
|
523
|
-
const
|
|
548
|
+
const je = A("clientStore", () => {
|
|
549
|
+
Y(), Q();
|
|
550
|
+
const o = p(""), e = p(""), s = p(""), n = p(""), t = p(!!i.token || !!i.saToken), r = p(!!i.saToken);
|
|
524
551
|
return {
|
|
525
552
|
// 用户信息
|
|
526
|
-
userId:
|
|
553
|
+
userId: o,
|
|
527
554
|
userName: e,
|
|
528
555
|
avatar: n,
|
|
529
556
|
// 计算属性
|
|
@@ -532,68 +559,70 @@ const Ue = H("clientStore", () => {
|
|
|
532
559
|
// 方法
|
|
533
560
|
login: async (d) => {
|
|
534
561
|
var u;
|
|
535
|
-
const
|
|
562
|
+
const a = await m.post(
|
|
536
563
|
"loginController/login",
|
|
537
564
|
d,
|
|
538
565
|
"json"
|
|
539
566
|
);
|
|
540
|
-
return (u =
|
|
567
|
+
return (u = a.data) != null && u.token && (W(a.data.token), t.value = !0, r.value = !1), a;
|
|
541
568
|
},
|
|
542
569
|
logout: async () => {
|
|
543
|
-
|
|
570
|
+
Z(), oe(), t.value = !1, r.value = !1, o.value = "", e.value = "", n.value = "";
|
|
544
571
|
},
|
|
545
572
|
getUserInfo: async () => {
|
|
546
|
-
const d = await
|
|
547
|
-
return
|
|
573
|
+
const d = await m.post("loginController/getUserInfo", {}, "json"), a = d.data;
|
|
574
|
+
return a && (o.value = a.userId || "", e.value = a.userName || "", s.value = a.name || "", n.value = "", a.defaultLanguage && i.set("defaultLanguage", a.defaultLanguage), a.homePath && i.set("homePath", a.homePath)), d;
|
|
548
575
|
},
|
|
549
576
|
saLogin: async (d) => {
|
|
550
577
|
var u;
|
|
551
|
-
const
|
|
552
|
-
return (u =
|
|
578
|
+
const a = await m.post("admin/login", d, "json");
|
|
579
|
+
return (u = a.data) != null && u.token && (z(a.data.token), t.value = !0, r.value = !0), a;
|
|
553
580
|
},
|
|
554
581
|
getSaUserInfo: async () => {
|
|
555
582
|
var u;
|
|
556
|
-
const d = await
|
|
557
|
-
return
|
|
583
|
+
const d = await m.post("admin/getSaUserInfo", {}, "json"), a = (u = d.data) == null ? void 0 : u.saUser;
|
|
584
|
+
return a && (o.value = a.id || "", e.value = a.username || "", s.value = a.name || "", n.value = "", a.language && i.set("defaultLanguage", a.language), a.mainPage && i.set("homePath", a.mainPage)), d;
|
|
558
585
|
}
|
|
559
586
|
};
|
|
560
587
|
});
|
|
561
588
|
export {
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
589
|
+
i as Config,
|
|
590
|
+
V as HttpRequest,
|
|
591
|
+
v as SA_TOKEN,
|
|
592
|
+
x as TOKEN_KEY,
|
|
593
|
+
Z as clearAllTokens,
|
|
567
594
|
oe as clearMenu,
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
595
|
+
_ as clearStorage,
|
|
596
|
+
X as clearTokens,
|
|
597
|
+
Ie as deepClone,
|
|
598
|
+
C as delStorage,
|
|
599
|
+
be as generateId,
|
|
600
|
+
me as generateMd5Hash,
|
|
601
|
+
ve as generateSimpleHash,
|
|
602
|
+
ge as getConfig,
|
|
603
|
+
Pe as getMenus,
|
|
604
|
+
Ue as getRoutes,
|
|
605
|
+
Q as getSaToken,
|
|
606
|
+
k as getStorage,
|
|
607
|
+
Y as getToken,
|
|
608
|
+
m as httpRequest,
|
|
609
|
+
we as initConfig,
|
|
610
|
+
Oe as initTokens,
|
|
611
|
+
Le as isEqual,
|
|
612
|
+
Me as menusToAside,
|
|
613
|
+
Te as mergeBuiltinConfig,
|
|
614
|
+
ye as mergeConfig,
|
|
615
|
+
Ee as off,
|
|
616
|
+
F as on,
|
|
617
|
+
Ce as once,
|
|
618
|
+
Se as overwriteObj,
|
|
619
|
+
ke as replaceServerConfig,
|
|
620
|
+
pe as setConfig,
|
|
621
|
+
z as setSaToken,
|
|
622
|
+
E as setStorage,
|
|
623
|
+
W as setToken,
|
|
624
|
+
xe as toHump,
|
|
625
|
+
S as trigger,
|
|
626
|
+
je as useClientStore
|
|
598
627
|
};
|
|
599
628
|
//# sourceMappingURL=index.es.js.map
|
package/index.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.es.js","sources":["../utils/storage.ts","../utils/config.ts","../utils/tools.ts","../utils/event.ts","../utils/index.ts","../api/http.ts","../auth/token.ts","../menu/converter.ts","../menu/cache.ts","../menu/service.ts","../store/client.ts"],"sourcesContent":["/**\n * Base64 编码(支持 Unicode)\n */\nfunction base64Encode(data: string): string {\n const bytes = new TextEncoder().encode(data);\n const binString = Array.from(bytes, (byte) => String.fromCharCode(byte)).join('');\n return btoa(binString);\n}\n\n/**\n * Base64 解码(支持 Unicode)\n */\nfunction base64Decode(base64: string): string {\n const binString = atob(base64);\n const bytes = Uint8Array.from(binString, (char) => char.charCodeAt(0));\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * 简单混淆编码\n * 使用 Base64 + 字符串反转\n */\nfunction encode(data: string): string {\n try {\n // 先 Base64\n let encoded = base64Encode(data);\n // 简单混淆:反转字符串\n return encoded.split('').reverse().join('');\n } catch {\n return data;\n }\n}\n\n/**\n * 简单混淆解码\n */\nfunction decode(data: string): string {\n try {\n // 反混淆:反转回来\n let reversed = data.split('').reverse().join('');\n // Base64 解码\n return base64Decode(reversed);\n } catch {\n return data;\n }\n}\n\n/**\n * 获取存储数据\n */\nexport const getStorage = <T = any>(key: string): T | null => {\n const objectStr = localStorage.getItem(key);\n if (objectStr !== null) {\n try {\n const decrypted = decode(objectStr);\n try {\n return JSON.parse(decrypted) as T;\n } catch {\n return decrypted as T;\n }\n } catch {\n // 解码失败,尝试直接解析原始数据\n try {\n return JSON.parse(objectStr) as T;\n } catch {\n return objectStr as T;\n }\n }\n }\n return null;\n};\n\n/**\n * 设置存储数据\n */\nexport const setStorage = <T>(key: string, value: T): void => {\n let data: string;\n if (typeof value === 'object') {\n data = JSON.stringify(value);\n } else {\n data = String(value);\n }\n try {\n const encrypted = encode(String(data));\n localStorage.setItem(key, encrypted);\n } catch (e) {\n // 混淆失败,直接存储\n localStorage.setItem(key, String(data));\n }\n};\n\n/**\n * 删除存储数据\n */\nexport const delStorage = (key: string): void => {\n localStorage.removeItem(key);\n};\n\n/**\n * 清空所有存储\n */\nexport const clearStorage = (): void => {\n localStorage.clear();\n sessionStorage.clear();\n};\n","import {get, set as lodashSet, merge} from 'lodash-es';\n\n/**\n * 全局配置对象\n */\ninterface AppConfig {\n token?: string;\n saToken?: string;\n storageKey?: string;\n [key: string]: any;\n}\n\nclass ConfigManager {\n private config: AppConfig = {};\n\n /**\n * 获取配置值\n */\n get<T = any>(path?: string, defaultValue?: T): T {\n if (!path) {\n return this.config as T;\n }\n return get(this.config, path, defaultValue);\n }\n\n /**\n * 设置配置值\n */\n set(path: string, value: any): void {\n lodashSet(this.config, path, value);\n }\n\n /**\n * 合并配置\n */\n merge(newConfig: AppConfig): void {\n this.config = merge(this.config, newConfig);\n }\n\n /**\n * 初始化配置(完全替换)\n */\n init(newConfig: AppConfig): void {\n this.config = {...newConfig};\n }\n\n /**\n * Token 快捷访问\n */\n get token(): string | undefined {\n return this.config.token;\n }\n\n set token(value: string | undefined) {\n this.config.token = value;\n }\n\n /**\n * SaToken 快捷访问\n */\n get saToken(): string | undefined {\n return this.config.saToken;\n }\n\n set saToken(value: string | undefined) {\n this.config.saToken = value;\n }\n\n /**\n * StorageKey 快捷访问\n */\n get storageKey(): string {\n return this.config.storageKey || 'yh-client-storage-key';\n }\n\n set storageKey(value: string) {\n this.config.storageKey = value;\n }\n}\n\n/**\n * 全局配置单例\n */\nexport const Config = new ConfigManager();\n\n/**\n * 获取配置值\n */\nexport function getConfig<T = any>(path?: string, defaultValue?: T): T {\n return Config.get(path, defaultValue);\n}\n\n/**\n * 设置配置值\n */\nexport function setConfig(path: string, value: any): void {\n Config.set(path, value);\n}\n\n/**\n * 合并配置\n */\nexport function mergeConfig(newConfig: AppConfig): void {\n Config.merge(newConfig);\n}\n\n/**\n * 初始化配置\n */\nexport function initConfig(newConfig: AppConfig): void {\n Config.init(newConfig);\n}\n\nexport type {AppConfig};\n","import {MD5} from 'crypto-js';\n\n/**\n * 生成 MD5 哈希值\n * @param input - 要哈希的输入字符串\n * @returns MD5 哈希值的十六进制字符串\n */\nexport async function generateMd5Hash(input: string): Promise<string> {\n return MD5(input).toString();\n}\n\n/**\n * 生成简单的哈希值\n * 使用位运算生成一个简短的哈希值,适用于不需要高安全性的场景\n * @param input - 要哈希的输入字符串\n * @returns 36 进制的哈希字符串\n */\nexport function generateSimpleHash(input: string): string {\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n const char = input.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(36);\n}\n\n/**\n * 下划线命名转换为驼峰命名\n * 将字符串中的下划线后面的字母转换为大写,并移除下划线\n * @param name - 包含下划线的字符串,如 user_name\n * @returns 转换后的驼峰命名字符串,如 userName\n */\nexport const toHump = (name: string): string => {\n return name.replace(/\\_(\\w)/g, function (all, letter) {\n return letter.toUpperCase();\n });\n};\n\n/**\n * 生成 UUID 格式的随机 ID\n * 生成一个类似 UUID 的字符串,其中第 15 位是 4(UUID 版本位)\n * @returns 大写的 UUID 字符串,如 12345678-1234-4123-8123-1234567890AB\n */\nexport const generateId = (): string => {\n const d = new Date().getTime();\n const uuid = 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n const r = ((d + Math.random() * 16) % 16) | 0;\n const newD = Math.floor(d / 16);\n return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);\n });\n return uuid.toUpperCase();\n};\n","type EventData = Record<string, any>;\ntype EventCallback<T = any> = (data: T) => void;\n\n/**\n * 触发自定义事件\n * @param eventName 事件名称\n * @param data 事件数据\n * @param target 目标对象,默认为 window\n */\nexport function trigger<T>(eventName: string, data?: T, target = window): void {\n const event = new CustomEvent(eventName, {detail: data});\n target.dispatchEvent(event);\n}\n\n/**\n * 监听自定义事件\n * @param eventName 事件名称\n * @param callback 回调函数\n * @param target 目标对象,默认为 window\n * @returns 清理函数\n */\nexport function on<T>(eventName: string, callback: EventCallback<T>, target = window): () => void {\n const handler = (e: Event) => callback((e as CustomEvent<T>).detail);\n target.addEventListener(eventName, handler);\n return () => target.removeEventListener(eventName, handler);\n}\n\n/**\n * 监听自定义事件(仅触发一次)\n * @param eventName 事件名称\n * @param callback 回调函数\n * @param target 目标对象,默认为 window\n * @returns 清理函数\n */\nexport function once<T>(\n eventName: string,\n callback: EventCallback<T>,\n target = window\n): () => void {\n const cleanup = on(\n eventName,\n (data: T) => {\n callback(data);\n cleanup();\n },\n target\n );\n return cleanup;\n}\n\n/**\n * 移除事件监听(已废弃,建议使用 on 返回的清理函数)\n * @deprecated 使用 on 返回的清理函数代替\n */\nexport function off<T>(eventName: string, callback: EventCallback<T>, target = window): void {\n const handler = (e: Event) => callback((e as CustomEvent<T>).detail);\n target.removeEventListener(eventName, handler);\n}\n\nexport type {EventData, EventCallback};\n","import {cloneDeep, isEqual as lodashIsEqual, assign} from 'lodash-es';\nexport const deepClone = cloneDeep;\nexport const isEqual = lodashIsEqual;\nexport const overwriteObj = assign;\n\nexport {getStorage, setStorage, delStorage, clearStorage} from './storage';\n\nexport {Config, getConfig, setConfig, mergeConfig, initConfig} from './config';\nexport type {AppConfig} from './config';\n\nexport {generateMd5Hash, generateId, generateSimpleHash, toHump} from './tools';\n\nexport {trigger, on, off, once} from './event';\n","import axios, {\n AxiosInstance,\n AxiosResponse,\n AxiosError,\n InternalAxiosRequestConfig,\n AxiosRequestConfig,\n} from 'axios';\nimport qs from 'qs';\nimport {merge} from 'lodash-es';\nimport type {RequestOptions, HttpResponse} from '../types';\nimport {Config, trigger} from '../utils';\nimport {ElMessage} from 'element-plus';\n\n/**\n * HTTP 请求队列\n */\ninterface RequestQueue {\n [url: string]: boolean;\n}\n\n/**\n * HTTP 请求类\n */\nexport class HttpRequest {\n private baseUrl: string;\n private queue: RequestQueue;\n private timeout: number = 120000; // 2分钟\n\n // 宿主项目可配置的钩子\n public onBusinessError?: (msg: string) => boolean;\n public onHttpError?: (error: AxiosError, url: string) => any;\n public onLoginRedirect?: () => void;\n public onRequestStart?: () => void;\n public onRequestEnd?: () => void;\n\n constructor(baseUrl: string = '') {\n this.baseUrl = baseUrl;\n this.queue = {};\n }\n\n /**\n * 设置基础 URL\n */\n setBaseUrl(url: string): void {\n this.baseUrl = url;\n }\n\n /**\n * 获取内部配置\n */\n private getInsideConfig(): AxiosRequestConfig {\n const token = Config.token;\n const saToken = Config.saToken;\n\n const config: AxiosRequestConfig = {\n baseURL: this.baseUrl,\n timeout: this.timeout,\n headers: {},\n };\n\n if (token) {\n config.headers = {\n ...config.headers,\n TOKEN: token,\n };\n }\n\n if (saToken) {\n config.headers = {\n ...config.headers,\n saToken: saToken,\n };\n }\n\n return config;\n }\n\n /**\n * 销毁加载状态\n */\n private destroy(url: string): void {\n delete this.queue[url];\n if (!Object.keys(this.queue).length) {\n this.onRequestEnd?.();\n }\n }\n\n /**\n * 设置拦截器\n */\n private interceptors(instance: AxiosInstance, url: string): void {\n // 请求拦截\n instance.interceptors.request.use(\n (config: InternalAxiosRequestConfig) => {\n this.queue[url] = true;\n if (Object.keys(this.queue).length === 1) {\n this.onRequestStart?.();\n }\n return config;\n },\n (error: AxiosError) => {\n console.error('[HTTP] 请求错误:', error);\n return Promise.reject(error);\n }\n );\n\n // 响应拦截\n instance.interceptors.response.use(\n (res: AxiosResponse): any => {\n const {data, status, headers} = res;\n this.destroy(url);\n if (data.result || data.result === void 0) {\n return {data, status, headers};\n } else {\n const {msg} = data;\n this.handleError(msg, url);\n return {data, status, headers};\n }\n },\n (error: AxiosError): any => {\n this.destroy(url);\n // 错误处理\n if (error.response) {\n return this.handleHttpError(error, url);\n } else {\n console.error('[HTTP] 未处理的网络错误', error);\n this.showMessage('请联系管理员,并查看控制台日志');\n return Promise.reject(error);\n }\n }\n );\n }\n\n /**\n * 处理业务错误\n */\n private handleError(msg: string | undefined, url: string): void {\n if (!msg) return;\n\n // 特殊消息:无数据时不显示错误提示\n if (msg === '无数据') {\n return;\n }\n\n // 钩子:宿主项目可先处理自定义错误逻辑\n if (this.onBusinessError) {\n const handled = this.onBusinessError(msg);\n if (handled) return;\n }\n\n // 登录超时\n if (msg.indexOf('Login Timeout') > -1 || msg.indexOf('Timeout') > -1 || msg.indexOf('登录超时!') > -1) {\n this.showMessage('登录状态已超时');\n if (this.onLoginRedirect) {\n this.onLoginRedirect();\n } else {\n trigger('to:login');\n }\n return;\n }\n\n // 违反唯一约束\n if (msg.indexOf('violates unique constraint') > -1) {\n console.warn('[HTTP] 违反唯一约束错误消息:', msg);\n const reg = /Key \\(([\\s|\\S]+)\\)=\\(([\\s|\\S]+)\\) already exists/;\n const match = msg.match(reg);\n let errMsg = msg;\n if (match !== null && match.length >= 3) {\n errMsg = `操作失败:数据[${match[2]}]已经存在!`;\n }\n this.showMessage(errMsg);\n return;\n }\n\n // 违反外键约束\n if (msg.indexOf('violates foreign key constraint') > -1) {\n console.warn('[HTTP] 违反外键约束错误消息:', msg);\n this.showMessage('操作失败:此条数据在其他地方使用!');\n return;\n }\n\n // 其他错误\n this.showMessage(msg);\n }\n\n /**\n * 处理 HTTP 错误\n */\n private handleHttpError(error: AxiosError, url: string): any {\n const {response} = error;\n if (!response) {\n return Promise.reject(error);\n }\n\n // 钩子:宿主项目可先处理 HTTP 错误\n if (this.onHttpError) {\n const result = this.onHttpError(error, url);\n if (result !== undefined) {\n return result;\n }\n }\n\n switch (response.status) {\n case 401:\n if (this.onLoginRedirect) {\n this.onLoginRedirect();\n } else {\n trigger('to:login');\n }\n break;\n case 400:\n console.error('[HTTP] HTTP 400', response);\n const msg400 = (response.data as any)?.msg;\n if (msg400) this.showMessage(msg400);\n break;\n case 404:\n this.showMessage(`${error.config?.url},资源不存在,请联系管理员`);\n break;\n case 500:\n this.showMessage('服务器错误,请联系管理员');\n break;\n default:\n console.error('[HTTP] Error', response);\n this.showMessage('请求遇到问题,请联系管理员协助');\n break;\n }\n\n return response as HttpResponse;\n }\n\n /**\n * 显示消息(需要 Element Plus)\n */\n private showMessage(message: string): void {\n // 动态导入 Element Plus,避免强依赖\n try {\n // 如果项目中有 ElMessage,使用它\n if (ElMessage) {\n ElMessage.error(message);\n } else {\n console.error('[HTTP]', message);\n }\n } catch (error) {\n console.error('[HTTP]', message);\n }\n }\n\n /**\n * 通用请求\n */\n request<T = any>(options: RequestOptions): Promise<HttpResponse<T>> {\n // 请求数据格式化\n let requestData = options.data;\n if (options.type !== 'json' && requestData && typeof requestData === 'object') {\n requestData = qs.stringify(requestData);\n }\n\n if (options.type === 'json') {\n if (!options.headers) {\n options.headers = {};\n }\n options.headers['Content-Type'] = 'application/json';\n }\n\n const instance = axios.create();\n const config: AxiosRequestConfig = merge(this.getInsideConfig(), {\n url: options.url,\n method: options.method || 'GET',\n data: requestData,\n params: options.params,\n headers: options.headers,\n timeout: options.timeout,\n responseType: options.responseType,\n });\n\n this.interceptors(instance, options.url);\n return instance(config) as Promise<HttpResponse<T>>;\n }\n\n /**\n * GET 请求\n */\n get<T = any>(url: string, params?: Record<string, any>): Promise<HttpResponse<T>> {\n return this.request<T>({url, method: 'GET', params});\n }\n\n /**\n * POST 请求\n */\n post<T = any>(url: string, data?: any, type?: 'json' | 'form'): Promise<HttpResponse<T>> {\n return this.request<T>({url, method: 'POST', data, type: type || 'form'});\n }\n\n /**\n * POST JSON 请求\n */\n postJson<T = any>(url: string, data?: any): Promise<HttpResponse<T>> {\n const instance = axios.create();\n const config: AxiosRequestConfig = merge(this.getInsideConfig(), {\n url,\n method: 'POST',\n data,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n this.interceptors(instance, url);\n return instance(config) as Promise<HttpResponse<T>>;\n }\n\n /**\n * 上传文件\n */\n upload<T = any>(url: string, data: any): Promise<HttpResponse<T>> {\n const instance = axios.create();\n const config: AxiosRequestConfig = merge(this.getInsideConfig(), {\n url,\n method: 'POST',\n data,\n headers: {\n 'Content-Type': 'multipart/form-data',\n },\n });\n\n this.interceptors(instance, url);\n return instance(config) as Promise<HttpResponse<T>>;\n }\n\n /**\n * 下载文件(POST)\n */\n download(url: string, data?: any, fileName?: string): Promise<HttpResponse> {\n const instance = axios.create();\n const config: AxiosRequestConfig = merge(this.getInsideConfig(), {\n url,\n method: 'POST',\n responseType: 'blob',\n data: data ? qs.stringify(data) : undefined,\n });\n\n // 注册基础拦截器(包含 destroy 调用)\n this.interceptors(instance, url);\n\n // 添加文件下载特定的处理\n instance.interceptors.response.use(\n (res: AxiosResponse): any => {\n if (res.data.result === false) {\n this.showMessage('导出文件异常: ' + res.data.msg);\n return;\n }\n const serverName = (res.headers['content-disposition'] || `filename=文件-${Date.now()}`).split('filename=')[1];\n const blob = new Blob([res.data]);\n const downloadElement = document.createElement('a');\n const href = window.URL.createObjectURL(blob);\n downloadElement.href = href;\n downloadElement.download = decodeURIComponent(this.resolveFileName(serverName, fileName));\n document.body.appendChild(downloadElement);\n downloadElement.click();\n document.body.removeChild(downloadElement);\n window.URL.revokeObjectURL(href);\n const {data, status, headers} = res;\n return {data, status, headers};\n }\n );\n\n return instance(config) as Promise<HttpResponse>;\n }\n\n /**\n * 导出文件(GET)\n */\n export(url: string, data?: any, fileName?: string): Promise<HttpResponse> {\n const instance = axios.create();\n const config: AxiosRequestConfig = merge(this.getInsideConfig(), {\n url,\n method: 'GET',\n responseType: 'blob',\n data: data ? qs.stringify(data) : undefined,\n });\n\n // 注册基础拦截器(包含 destroy 调用)\n this.interceptors(instance, url);\n\n // 添加文件导出特定的处理\n instance.interceptors.response.use(\n (res: AxiosResponse): any => {\n const serverName = (res.headers['content-disposition'] || `filename=文件-${Date.now()}`).split('filename=')[1];\n const blob = new Blob([res.data]);\n const downloadElement = document.createElement('a');\n const href = window.URL.createObjectURL(blob);\n downloadElement.href = href;\n downloadElement.download = decodeURIComponent(this.resolveFileName(serverName, fileName));\n document.body.appendChild(downloadElement);\n downloadElement.click();\n document.body.removeChild(downloadElement);\n window.URL.revokeObjectURL(href);\n const {data, status, headers} = res;\n return {data, status, headers};\n }\n );\n\n return instance(config) as Promise<HttpResponse>;\n }\n\n /**\n * 解析下载文件名\n * fileName 含 . 时追加服务器文件名的扩展名\n */\n private resolveFileName(serverName: string, fileName?: string): string {\n if (!fileName) return serverName || '';\n if (fileName.indexOf('.') > -1) {\n const ext = (serverName || '').split('.')[1];\n return ext ? fileName + '.' + ext : fileName;\n }\n return fileName;\n }\n}\n\n// 创建默认实例\nconst defaultInstance = new HttpRequest();\n\n// 导出类和默认实例\nexport default defaultInstance;\n","/**\n * Token 管理\n * 从 yh-pub 迁移并增强\n */\n\nimport {setStorage, getStorage, delStorage, clearStorage} from '../utils/storage';\nimport {Config} from '../utils/config';\n\nexport const SA_TOKEN = 'SATOKEN';\nexport const TOKEN_KEY = 'login-token';\n\n/**\n * 判断值是否只包含可打印 ASCII 字符(合法的 HTTP header 值)\n */\nfunction isValidHeaderValue(value: string): boolean {\n return /^[\\x20-\\x7E]*$/.test(value);\n}\n\n/**\n * 初始化Token(从存储加载到Config)\n */\nexport function initTokens(): void {\n const token = getStorage<string>(TOKEN_KEY);\n if (token && isValidHeaderValue(token)) {\n Config.token = token;\n } else {\n Config.token = '';\n delStorage(TOKEN_KEY);\n }\n\n const saToken = getStorage<string>(SA_TOKEN);\n if (saToken && isValidHeaderValue(saToken)) {\n Config.saToken = saToken;\n } else {\n Config.saToken = '';\n delStorage(SA_TOKEN);\n }\n}\n\n/**\n * 存储Token并同步到Config\n */\nexport function setToken(token: string): void {\n setStorage(TOKEN_KEY, token);\n Config.token = token;\n}\n\n/**\n * 获取Token(优先从Config获取)\n */\nexport function getToken(): string {\n if (Config.token !== undefined) {\n return Config.token;\n }\n const token = getStorage<string>(TOKEN_KEY);\n Config.token = token || '';\n return Config.token as string;\n}\n\n/**\n * 存储SAToken并同步到Config\n */\nexport function setSaToken(token: string): void {\n setStorage(SA_TOKEN, token);\n Config.saToken = token;\n}\n\n/**\n * 获取SaToken(优先从Config获取)\n */\nexport function getSaToken(): string {\n if (Config.saToken !== undefined) {\n return Config.saToken;\n }\n const token = getStorage<string>(SA_TOKEN);\n Config.saToken = token || '';\n return Config.saToken as string;\n}\n\n/**\n * 清除Token(清空Config中的值)\n */\nexport function clearTokens(): void {\n Config.token = '';\n Config.saToken = '';\n clearStorage();\n}\n\n/**\n * 清除所有Token和存储\n */\nexport function clearAllTokens(): void {\n clearTokens();\n}\n","export interface MenuData {\n id: string;\n parentId?: string;\n name: string;\n iconPath?: string;\n url?: string;\n menuType?: string;\n windowId?: string;\n sysModuleId?: string;\n children?: MenuData[];\n}\n\nexport interface MenuItem {\n title: string;\n icon?: string;\n id: string;\n hasChildren?: boolean;\n sysModuleId?: string;\n children?: MenuItem[];\n}\n\nexport interface RouteConfig {\n path: string;\n id: string;\n name: string;\n component: any;\n meta: {\n id: string;\n title: string;\n icon?: string;\n isWhite?: boolean;\n keepAlive?: boolean;\n isIframe?: boolean;\n url?: string;\n };\n}\n\nexport type RouteHandler = (menu: MenuData) => RouteConfig | null;\n\nexport interface RouteHandlerConfig {\n match: (url: string) => boolean;\n handler: RouteHandler;\n priority?: number;\n}\n\nimport md5 from 'crypto-js/md5';\n\nlet routeHandlers: RouteHandlerConfig[] = [];\n\nexport function registerRouteHandler(config: RouteHandlerConfig) {\n routeHandlers.push(config);\n routeHandlers.sort((a, b) => (b.priority || 0) - (a.priority || 0));\n}\n\nexport function clearRouteHandlers() {\n routeHandlers = [];\n}\n\nexport function toTree(data: MenuData[]): MenuData[] {\n const nodes: MenuData[] = [];\n const map: Record<string, MenuData> = {};\n const menuMap: Record<string, MenuData[]> = {};\n data = JSON.parse(JSON.stringify(data));\n\n data.forEach(function (item) {\n if (item.parentId && item.parentId !== '0') {\n if (!menuMap[item.parentId]) {\n menuMap[item.parentId] = [];\n }\n menuMap[item.parentId].push(item);\n }\n if (item.children && item.children.length > 0) {\n item.children.forEach((itemSub) => {\n if (itemSub.parentId) {\n if (!menuMap[itemSub.parentId]) {\n menuMap[itemSub.parentId] = [];\n }\n menuMap[itemSub.parentId].push(itemSub);\n }\n });\n }\n });\n\n data.forEach(function (item) {\n map[item.id] = item;\n if (item.parentId) {\n if (!menuMap[item.parentId]) {\n if (menuMap[item.id]) {\n map[item.id].children = menuMap[item.id];\n }\n nodes.push(map[item.id]);\n }\n } else {\n // 没有 parentId 的是顶级菜单,直接添加\n if (menuMap[item.id]) {\n map[item.id].children = menuMap[item.id];\n }\n nodes.push(map[item.id]);\n }\n if (item.children && item.children.length > 0) {\n item.children.forEach((itemSub) => {\n map[itemSub.id] = itemSub;\n if (menuMap[itemSub.id]) {\n map[itemSub.id].children = menuMap[itemSub.id];\n }\n });\n }\n });\n\n return nodes;\n}\n\nexport function menusToAside(data: MenuData[], isAdmin: boolean = false): MenuItem[] {\n const menus = toTree(data);\n\n function mtoa(menu: MenuData): MenuItem | false {\n if (['SUBPAGE', 'JOIN', 'APP'].includes(menu.menuType || '')) {\n return false;\n }\n\n const newMenu: MenuItem = {\n title: menu.name,\n icon: menu.iconPath,\n id: menu.id,\n sysModuleId: menu.sysModuleId,\n };\n\n if (menu.url && ['WINDOW', 'LINK'].includes(menu.menuType || '')) {\n if (isAdmin && menu.url.indexOf('sys/index') > -1) {\n newMenu.id = `/admin/sys/window/${menu.windowId || menu.id}`;\n } else if (menu.url.indexOf('sys/index') > -1) {\n newMenu.id = `/sys/window/${menu.windowId || menu.id}`;\n } else if (menu.url.indexOf('http') > -1) {\n const keepAlive = '';\n newMenu.id = `/iframe/${md5(menu.url)}?url=${encodeURIComponent(menu.url)}&title=${menu.name}&_keepAlive=${keepAlive}`;\n } else {\n if (menu.url.indexOf('/') !== 0) {\n menu.url = `/${menu.url}`;\n }\n newMenu.id = menu.url;\n }\n }\n\n if (menu.children) {\n newMenu.hasChildren = true;\n newMenu.children = menu.children.map(mtoa).filter((item): item is MenuItem => !!item);\n }\n\n return newMenu;\n }\n\n return menus.map(mtoa).filter((item): item is MenuItem => !!item);\n}\n\nexport function getRoutes(\n menus: MenuData[],\n defaultRouteHandler: (menu: MenuData) => RouteConfig | null\n): RouteConfig[] {\n const items: RouteConfig[] = [];\n\n for (const menu of menus) {\n if (!menu.url) {\n continue;\n }\n\n let route: RouteConfig | null = null;\n\n route = defaultRouteHandler(menu);\n\n if (route) {\n items.push(route);\n }\n }\n\n return items;\n}\n","import type {MenuData} from './converter';\nimport {getStorage, setStorage, delStorage} from '../utils';\n\nconst MENU_CACHE_KEY = 'yh-menu-cache';\n\n/**\n * 内存缓存\n */\nlet memoryCache: MenuData[] | null = null;\n\n/**\n * 获取菜单缓存(优先从内存获取)\n */\nexport function getMenuCache(): MenuData[] | null {\n // 1. 从内存获取\n if (memoryCache) {\n return memoryCache;\n }\n\n // 2. 从 LocalStorage 获取\n const cached = getStorage<MenuData[]>(MENU_CACHE_KEY);\n if (cached) {\n memoryCache = cached;\n return cached;\n }\n\n return null;\n}\n\n/**\n * 设置菜单缓存(同时更新内存和 LocalStorage)\n */\nexport function setMenuCache(menus: MenuData[]): void {\n memoryCache = menus;\n setStorage(MENU_CACHE_KEY, menus);\n}\n\n/**\n * 清除菜单缓存(同时清除内存和 LocalStorage)\n */\nexport function clearMenuCache(): void {\n memoryCache = null;\n delStorage(MENU_CACHE_KEY);\n}\n\n/**\n * 获取内存缓存\n */\nexport function getMemoryMenuCache(): MenuData[] | null {\n return memoryCache;\n}\n\n/**\n * 设置内存缓存\n */\nexport function setMemoryMenuCache(menus: MenuData[]): void {\n memoryCache = menus;\n}\n","import type {MenuData} from './converter';\nimport {getMenuCache, setMenuCache, clearMenuCache} from './cache';\nimport {httpRequest} from 'yh-client';\n\nexport async function getMenus(isPad: boolean = false): Promise<MenuData[]> {\n const cached = getMenuCache();\n if (cached) {\n return cached;\n }\n\n const res = await httpRequest.post<any>(\n isPad ? 'loginController/getPdaMenus' : 'loginController/getMenus',\n {}\n );\n const menu = res.data.data;\n setMenuCache(menu);\n return menu;\n}\n\nexport function clearMenu(): void {\n clearMenuCache();\n}\n\nexport function setCustomMenus(menus: MenuData[]): void {\n setMenuCache(menus);\n}\n","import {defineStore} from 'pinia';\nimport {ref} from 'vue';\nimport {default as httpRequest} from '../api/http';\nimport {setToken, setSaToken, clearAllTokens, getToken, getSaToken} from '../auth/token';\nimport type {HttpResponse, UserInfo} from '../types';\nimport {Config} from '../utils';\nimport { clearMenu } from '../menu';\n\n/**\n * 客户端 Store\n */\nexport const useClientStore = defineStore('clientStore', () => {\n getToken();\n getSaToken();\n\n const userId = ref<string>('');\n const userName = ref<string>('');\n const name = ref<string>('');\n const avatar = ref<string>('');\n const isLoggedIn = ref<boolean>(!!Config.token || !!Config.saToken);\n const isAdmin = ref<boolean>(!!Config.saToken);\n\n const login = async (params: {\n username: string;\n password: string;\n }): Promise<HttpResponse<{token: string}>> => {\n const response = await httpRequest.post<{token: string}>(\n 'loginController/login',\n params,\n 'json'\n );\n\n if (response.data?.token) {\n setToken(response.data.token);\n isLoggedIn.value = true;\n isAdmin.value = false;\n }\n\n return response;\n };\n\n /**\n * 获取用户信息\n */\n const getUserInfo = async (): Promise<HttpResponse<UserInfo>> => {\n const response = await httpRequest.post<UserInfo>('loginController/getUserInfo', {}, 'json');\n\n const data = response.data as UserInfo;\n if (data) {\n userId.value = data.userId || '';\n userName.value = data.userName || '';\n name.value = data.name || '';\n avatar.value = '';\n\n if (data.defaultLanguage) {\n Config.set('defaultLanguage', data.defaultLanguage);\n }\n if (data.homePath) {\n Config.set('homePath', data.homePath);\n }\n }\n\n return response;\n };\n\n /**\n * 管理员登录\n */\n const saLogin = async (params: {\n username: string;\n password: string;\n }): Promise<HttpResponse<{token: string}>> => {\n const response = await httpRequest.post<{token: string}>('admin/login', params, 'json');\n\n // 更新 saToken\n if (response.data?.token) {\n setSaToken(response.data.token);\n isLoggedIn.value = true;\n isAdmin.value = true;\n }\n\n return response;\n };\n\n /**\n * 获取管理员用户信息\n */\n const getSaUserInfo = async (): Promise<HttpResponse<any>> => {\n const response = await httpRequest.post<{saUser: any}>('admin/getSaUserInfo', {}, 'json');\n\n const saUser = response.data?.saUser;\n if (saUser) {\n userId.value = saUser.id || '';\n userName.value = saUser.username || '';\n name.value = saUser.name || '';\n avatar.value = '';\n\n if (saUser.language) {\n Config.set('defaultLanguage', saUser.language);\n }\n if (saUser.mainPage) {\n Config.set('homePath', saUser.mainPage);\n }\n }\n\n return response;\n };\n\n /**\n * 登出\n */\n const logout = async (): Promise<void> => {\n // 清除所有 token 和存储\n clearAllTokens();\n clearMenu();\n isLoggedIn.value = false;\n isAdmin.value = false;\n userId.value = '';\n userName.value = '';\n avatar.value = '';\n };\n\n return {\n // 用户信息\n userId,\n userName,\n avatar,\n\n // 计算属性\n isLoggedIn,\n isAdmin,\n\n // 方法\n login,\n logout,\n getUserInfo,\n saLogin,\n getSaUserInfo,\n };\n});\n"],"names":["base64Encode","data","bytes","binString","byte","base64Decode","base64","char","encode","decode","reversed","getStorage","key","objectStr","decrypted","setStorage","value","encrypted","delStorage","clearStorage","ConfigManager","path","defaultValue","get","lodashSet","newConfig","merge","Config","getConfig","setConfig","mergeConfig","initConfig","generateMd5Hash","input","MD5","generateSimpleHash","hash","i","toHump","name","all","letter","generateId","d","c","r","trigger","eventName","target","event","on","callback","handler","e","once","cleanup","off","deepClone","cloneDeep","isEqual","lodashIsEqual","overwriteObj","assign","HttpRequest","baseUrl","url","token","saToken","config","_a","instance","error","res","status","headers","msg","reg","match","errMsg","response","result","msg400","_b","message","ElMessage","options","requestData","qs","axios","params","type","fileName","serverName","blob","downloadElement","href","ext","defaultInstance","SA_TOKEN","TOKEN_KEY","isValidHeaderValue","initTokens","setToken","getToken","setSaToken","getSaToken","clearTokens","clearAllTokens","toTree","nodes","map","menuMap","item","itemSub","menusToAside","isAdmin","menus","mtoa","menu","newMenu","keepAlive","md5","getRoutes","defaultRouteHandler","items","route","MENU_CACHE_KEY","memoryCache","getMenuCache","cached","setMenuCache","clearMenuCache","getMenus","isPad","httpRequest","clearMenu","useClientStore","defineStore","userId","ref","userName","avatar","isLoggedIn","saUser"],"mappings":";;;;;;;;;AAGA,SAASA,EAAaC,GAAsB;AAC1C,QAAMC,IAAQ,IAAI,cAAc,OAAOD,CAAI,GACrCE,IAAY,MAAM,KAAKD,GAAO,CAACE,MAAS,OAAO,aAAaA,CAAI,CAAC,EAAE,KAAK,EAAE;AAChF,SAAO,KAAKD,CAAS;AACvB;AAKA,SAASE,EAAaC,GAAwB;AAC5C,QAAMH,IAAY,KAAKG,CAAM,GACvBJ,IAAQ,WAAW,KAAKC,GAAW,CAACI,MAASA,EAAK,WAAW,CAAC,CAAC;AACrE,SAAO,IAAI,YAAA,EAAc,OAAOL,CAAK;AACvC;AAMA,SAASM,EAAOP,GAAsB;AACpC,MAAI;AAIF,WAFcD,EAAaC,CAAI,EAEhB,MAAM,EAAE,EAAE,QAAA,EAAU,KAAK,EAAE;AAAA,EAC5C,QAAQ;AACN,WAAOA;AAAA,EACT;AACF;AAKA,SAASQ,EAAOR,GAAsB;AACpC,MAAI;AAEF,QAAIS,IAAWT,EAAK,MAAM,EAAE,EAAE,QAAA,EAAU,KAAK,EAAE;AAE/C,WAAOI,EAAaK,CAAQ;AAAA,EAC9B,QAAQ;AACN,WAAOT;AAAA,EACT;AACF;AAKO,MAAMU,IAAa,CAAUC,MAA0B;AAC5D,QAAMC,IAAY,aAAa,QAAQD,CAAG;AAC1C,MAAIC,MAAc;AAChB,QAAI;AACF,YAAMC,IAAYL,EAAOI,CAAS;AAClC,UAAI;AACF,eAAO,KAAK,MAAMC,CAAS;AAAA,MAC7B,QAAQ;AACN,eAAOA;AAAA,MACT;AAAA,IACF,QAAQ;AAEN,UAAI;AACF,eAAO,KAAK,MAAMD,CAAS;AAAA,MAC7B,QAAQ;AACN,eAAOA;AAAA,MACT;AAAA,IACF;AAEF,SAAO;AACT,GAKaE,IAAa,CAAIH,GAAaI,MAAmB;AAC5D,MAAIf;AACJ,EAAI,OAAOe,KAAU,WACnBf,IAAO,KAAK,UAAUe,CAAK,IAE3Bf,IAAO,OAAOe,CAAK;AAErB,MAAI;AACF,UAAMC,IAAYT,EAAO,OAAOP,CAAI,CAAC;AACrC,iBAAa,QAAQW,GAAKK,CAAS;AAAA,EACrC,QAAY;AAEV,iBAAa,QAAQL,GAAK,OAAOX,CAAI,CAAC;AAAA,EACxC;AACF,GAKaiB,IAAa,CAACN,MAAsB;AAC/C,eAAa,WAAWA,CAAG;AAC7B,GAKaO,IAAe,MAAY;AACtC,eAAa,MAAA,GACb,eAAe,MAAA;AACjB;AC5FA,MAAMC,EAAc;AAAA,EAApB,cAAA;AACE,SAAQ,SAAoB,CAAA;AAAA,EAAC;AAAA;AAAA;AAAA;AAAA,EAK7B,IAAaC,GAAeC,GAAqB;AAC/C,WAAKD,IAGEE,EAAI,KAAK,QAAQF,GAAMC,CAAY,IAFjC,KAAK;AAAA,EAGhB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAID,GAAcL,GAAkB;AAClCQ,IAAAA,EAAU,KAAK,QAAQH,GAAML,CAAK;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAMS,GAA4B;AAChC,SAAK,SAASC,EAAM,KAAK,QAAQD,CAAS;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA,EAKA,KAAKA,GAA4B;AAC/B,SAAK,SAAS,EAAC,GAAGA,EAAA;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,QAA4B;AAC9B,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,IAAI,MAAMT,GAA2B;AACnC,SAAK,OAAO,QAAQA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,UAA8B;AAChC,WAAO,KAAK,OAAO;AAAA,EACrB;AAAA,EAEA,IAAI,QAAQA,GAA2B;AACrC,SAAK,OAAO,UAAUA;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,aAAqB;AACvB,WAAO,KAAK,OAAO,cAAc;AAAA,EACnC;AAAA,EAEA,IAAI,WAAWA,GAAe;AAC5B,SAAK,OAAO,aAAaA;AAAA,EAC3B;AACF;AAKO,MAAMW,IAAS,IAAIP,EAAA;AAKnB,SAASQ,GAAmBP,GAAeC,GAAqB;AACrE,SAAOK,EAAO,IAAIN,GAAMC,CAAY;AACtC;AAKO,SAASO,GAAUR,GAAcL,GAAkB;AACxD,EAAAW,EAAO,IAAIN,GAAML,CAAK;AACxB;AAKO,SAASc,GAAYL,GAA4B;AACtD,EAAAE,EAAO,MAAMF,CAAS;AACxB;AAKO,SAASM,GAAWN,GAA4B;AACrD,EAAAE,EAAO,KAAKF,CAAS;AACvB;ACxGA,eAAsBO,GAAgBC,GAAgC;AACpE,SAAOC,EAAID,CAAK,EAAE,SAAA;AACpB;AAQO,SAASE,GAAmBF,GAAuB;AACxD,MAAIG,IAAO;AACX,WAASC,IAAI,GAAGA,IAAIJ,EAAM,QAAQI,KAAK;AACrC,UAAM9B,IAAO0B,EAAM,WAAWI,CAAC;AAC/B,IAAAD,KAAQA,KAAQ,KAAKA,IAAO7B,GAC5B6B,IAAOA,IAAOA;AAAA,EAChB;AACA,SAAO,KAAK,IAAIA,CAAI,EAAE,SAAS,EAAE;AACnC;AAQO,MAAME,KAAS,CAACC,MACdA,EAAK,QAAQ,WAAW,SAAUC,GAAKC,GAAQ;AACpD,SAAOA,EAAO,YAAA;AAChB,CAAC,GAQUC,KAAa,MAAc;AACtC,QAAMC,KAAI,oBAAI,KAAA,GAAO,QAAA;AAMrB,SALa,mCAAmC,QAAQ,SAAS,SAAUC,GAAG;AAC5E,UAAMC,KAAMF,IAAI,KAAK,WAAW,MAAM,KAAM;AAE5C,YAAQC,MAAM,MAAMC,IAAKA,IAAI,IAAO,GAAK,SAAS,EAAE;AAAA,EACtD,CAAC,EACW,YAAA;AACd;AC3CO,SAASC,EAAWC,GAAmB9C,GAAU+C,IAAS,QAAc;AAC7E,QAAMC,IAAQ,IAAI,YAAYF,GAAW,EAAC,QAAQ9C,GAAK;AACvD,EAAA+C,EAAO,cAAcC,CAAK;AAC5B;AASO,SAASC,EAAMH,GAAmBI,GAA4BH,IAAS,QAAoB;AAChG,QAAMI,IAAU,CAACC,MAAaF,EAAUE,EAAqB,MAAM;AACnE,SAAAL,EAAO,iBAAiBD,GAAWK,CAAO,GACnC,MAAMJ,EAAO,oBAAoBD,GAAWK,CAAO;AAC5D;AASO,SAASE,GACdP,GACAI,GACAH,IAAS,QACG;AACZ,QAAMO,IAAUL;AAAA,IACdH;AAAA,IACA,CAAC9C,MAAY;AACX,MAAAkD,EAASlD,CAAI,GACbsD,EAAA;AAAA,IACF;AAAA,IACAP;AAAA,EAAA;AAEF,SAAOO;AACT;AAMO,SAASC,GAAOT,GAAmBI,GAA4BH,IAAS,QAAc;AAC3F,QAAMI,IAAU,CAACC,MAAaF,EAAUE,EAAqB,MAAM;AACnE,EAAAL,EAAO,oBAAoBD,GAAWK,CAAO;AAC/C;ACxDO,MAAMK,KAAYC,GACZC,KAAUC,GACVC,KAAeC;ACoBrB,MAAMC,EAAY;AAAA,EAYvB,YAAYC,IAAkB,IAAI;AATlC,SAAQ,UAAkB,MAUxB,KAAK,UAAUA,GACf,KAAK,QAAQ,CAAA;AAAA,EACf;AAAA;AAAA;AAAA;AAAA,EAKA,WAAWC,GAAmB;AAC5B,SAAK,UAAUA;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKQ,kBAAsC;AAC5C,UAAMC,IAAQvC,EAAO,OACfwC,IAAUxC,EAAO,SAEjByC,IAA6B;AAAA,MACjC,SAAS,KAAK;AAAA,MACd,SAAS,KAAK;AAAA,MACd,SAAS,CAAA;AAAA,IAAC;AAGZ,WAAIF,MACFE,EAAO,UAAU;AAAA,MACf,GAAGA,EAAO;AAAA,MACV,OAAOF;AAAA,IAAA,IAIPC,MACFC,EAAO,UAAU;AAAA,MACf,GAAGA,EAAO;AAAA,MACV,SAAAD;AAAA,IAAA,IAIGC;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,QAAQH,GAAmB;;AACjC,WAAO,KAAK,MAAMA,CAAG,GAChB,OAAO,KAAK,KAAK,KAAK,EAAE,WAC3BI,IAAA,KAAK,iBAAL,QAAAA,EAAA;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA,EAKQ,aAAaC,GAAyBL,GAAmB;AAE/D,IAAAK,EAAS,aAAa,QAAQ;AAAA,MAC5B,CAACF,MAAuC;;AACtC,oBAAK,MAAMH,CAAG,IAAI,IACd,OAAO,KAAK,KAAK,KAAK,EAAE,WAAW,OACrCI,IAAA,KAAK,mBAAL,QAAAA,EAAA,aAEKD;AAAA,MACT;AAAA,MACA,CAACG,OACC,QAAQ,MAAM,gBAAgBA,CAAK,GAC5B,QAAQ,OAAOA,CAAK;AAAA,IAC7B,GAIFD,EAAS,aAAa,SAAS;AAAA,MAC7B,CAACE,MAA4B;AAC3B,cAAM,EAAC,MAAAvE,GAAM,QAAAwE,GAAQ,SAAAC,EAAA,IAAWF;AAEhC,YADA,KAAK,QAAQP,CAAG,GACZhE,EAAK,UAAUA,EAAK,WAAW;AACjC,iBAAO,EAAC,MAAAA,GAAM,QAAAwE,GAAQ,SAAAC,EAAA;AACjB;AACL,gBAAM,EAAC,KAAAC,MAAO1E;AACd,sBAAK,YAAY0E,GAAKV,CAAG,GAClB,EAAC,MAAAhE,GAAM,QAAAwE,GAAQ,SAAAC,EAAA;AAAA,QACxB;AAAA,MACF;AAAA,MACA,CAACH,OACC,KAAK,QAAQN,CAAG,GAEZM,EAAM,WACD,KAAK,gBAAgBA,GAAON,CAAG,KAEtC,QAAQ,MAAM,mBAAmBM,CAAK,GACtC,KAAK,YAAY,iBAAiB,GAC3B,QAAQ,OAAOA,CAAK;AAAA,IAE/B;AAAA,EAEJ;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAYI,GAAyBV,GAAmB;AAC9D,QAAKU,KAGDA,MAAQ,SAKR,OAAK,mBACS,KAAK,gBAAgBA,CAAG,IAK1C;AAAA,UAAIA,EAAI,QAAQ,eAAe,IAAI,MAAMA,EAAI,QAAQ,SAAS,IAAI,MAAMA,EAAI,QAAQ,OAAO,IAAI,IAAI;AACjG,aAAK,YAAY,SAAS,GACtB,KAAK,kBACP,KAAK,gBAAA,IAEL7B,EAAQ,UAAU;AAEpB;AAAA,MACF;AAGA,UAAI6B,EAAI,QAAQ,4BAA4B,IAAI,IAAI;AAClD,gBAAQ,KAAK,sBAAsBA,CAAG;AACtC,cAAMC,IAAM,oDACNC,IAAQF,EAAI,MAAMC,CAAG;AAC3B,YAAIE,IAASH;AACb,QAAIE,MAAU,QAAQA,EAAM,UAAU,MACpCC,IAAS,WAAWD,EAAM,CAAC,CAAC,WAE9B,KAAK,YAAYC,CAAM;AACvB;AAAA,MACF;AAGA,UAAIH,EAAI,QAAQ,iCAAiC,IAAI,IAAI;AACvD,gBAAQ,KAAK,sBAAsBA,CAAG,GACtC,KAAK,YAAY,mBAAmB;AACpC;AAAA,MACF;AAGA,WAAK,YAAYA,CAAG;AAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKQ,gBAAgBJ,GAAmBN,GAAkB;;AAC3D,UAAM,EAAC,UAAAc,MAAYR;AACnB,QAAI,CAACQ;AACH,aAAO,QAAQ,OAAOR,CAAK;AAI7B,QAAI,KAAK,aAAa;AACpB,YAAMS,IAAS,KAAK,YAAYT,GAAON,CAAG;AAC1C,UAAIe,MAAW;AACb,eAAOA;AAAA,IAEX;AAEA,YAAQD,EAAS,QAAA;AAAA,MACf,KAAK;AACH,QAAI,KAAK,kBACP,KAAK,gBAAA,IAELjC,EAAQ,UAAU;AAEpB;AAAA,MACF,KAAK;AACH,gBAAQ,MAAM,mBAAmBiC,CAAQ;AACzC,cAAME,KAAUZ,IAAAU,EAAS,SAAT,gBAAAV,EAAuB;AACvC,QAAIY,KAAQ,KAAK,YAAYA,CAAM;AACnC;AAAA,MACF,KAAK;AACH,aAAK,YAAY,IAAGC,IAAAX,EAAM,WAAN,gBAAAW,EAAc,GAAG,eAAe;AACpD;AAAA,MACF,KAAK;AACH,aAAK,YAAY,cAAc;AAC/B;AAAA,MACF;AACE,gBAAQ,MAAM,gBAAgBH,CAAQ,GACtC,KAAK,YAAY,iBAAiB;AAClC;AAAA,IAAA;AAGJ,WAAOA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKQ,YAAYI,GAAuB;AAEzC,QAAI;AAEF,MAAIC,IACFA,EAAU,MAAMD,CAAO,IAEvB,QAAQ,MAAM,UAAUA,CAAO;AAAA,IAEnC,QAAgB;AACd,cAAQ,MAAM,UAAUA,CAAO;AAAA,IACjC;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAiBE,GAAmD;AAElE,QAAIC,IAAcD,EAAQ;AAC1B,IAAIA,EAAQ,SAAS,UAAUC,KAAe,OAAOA,KAAgB,aACnEA,IAAcC,EAAG,UAAUD,CAAW,IAGpCD,EAAQ,SAAS,WACdA,EAAQ,YACXA,EAAQ,UAAU,CAAA,IAEpBA,EAAQ,QAAQ,cAAc,IAAI;AAGpC,UAAMf,IAAWkB,EAAM,OAAA,GACjBpB,IAA6B1C,EAAM,KAAK,gBAAA,GAAmB;AAAA,MAC/D,KAAK2D,EAAQ;AAAA,MACb,QAAQA,EAAQ,UAAU;AAAA,MAC1B,MAAMC;AAAA,MACN,QAAQD,EAAQ;AAAA,MAChB,SAASA,EAAQ;AAAA,MACjB,SAASA,EAAQ;AAAA,MACjB,cAAcA,EAAQ;AAAA,IAAA,CACvB;AAED,gBAAK,aAAaf,GAAUe,EAAQ,GAAG,GAChCf,EAASF,CAAM;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAaH,GAAawB,GAAwD;AAChF,WAAO,KAAK,QAAW,EAAC,KAAAxB,GAAK,QAAQ,OAAO,QAAAwB,GAAO;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA,EAKA,KAAcxB,GAAahE,GAAYyF,GAAkD;AACvF,WAAO,KAAK,QAAW,EAAC,KAAAzB,GAAK,QAAQ,QAAQ,MAAAhE,GAAM,MAAMyF,KAAQ,QAAO;AAAA,EAC1E;AAAA;AAAA;AAAA;AAAA,EAKA,SAAkBzB,GAAahE,GAAsC;AACnE,UAAMqE,IAAWkB,EAAM,OAAA,GACjBpB,IAA6B1C,EAAM,KAAK,gBAAA,GAAmB;AAAA,MAC/D,KAAAuC;AAAA,MACA,QAAQ;AAAA,MACR,MAAAhE;AAAA,MACA,SAAS;AAAA,QACP,gBAAgB;AAAA,MAAA;AAAA,IAClB,CACD;AAED,gBAAK,aAAaqE,GAAUL,CAAG,GACxBK,EAASF,CAAM;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAgBH,GAAahE,GAAqC;AAChE,UAAMqE,IAAWkB,EAAM,OAAA,GACjBpB,IAA6B1C,EAAM,KAAK,gBAAA,GAAmB;AAAA,MAC/D,KAAAuC;AAAA,MACA,QAAQ;AAAA,MACR,MAAAhE;AAAA,MACA,SAAS;AAAA,QACP,gBAAgB;AAAA,MAAA;AAAA,IAClB,CACD;AAED,gBAAK,aAAaqE,GAAUL,CAAG,GACxBK,EAASF,CAAM;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,SAASH,GAAahE,GAAY0F,GAA0C;AAC1E,UAAMrB,IAAWkB,EAAM,OAAA,GACjBpB,IAA6B1C,EAAM,KAAK,gBAAA,GAAmB;AAAA,MAC/D,KAAAuC;AAAA,MACA,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,MAAMhE,IAAOsF,EAAG,UAAUtF,CAAI,IAAI;AAAA,IAAA,CACnC;AAGD,gBAAK,aAAaqE,GAAUL,CAAG,GAG/BK,EAAS,aAAa,SAAS;AAAA,MAC7B,CAACE,MAA4B;AAC3B,YAAIA,EAAI,KAAK,WAAW,IAAO;AAC7B,eAAK,YAAY,aAAaA,EAAI,KAAK,GAAG;AAC1C;AAAA,QACF;AACA,cAAMoB,KAAcpB,EAAI,QAAQ,qBAAqB,KAAK,eAAe,KAAK,IAAA,CAAK,IAAI,MAAM,WAAW,EAAE,CAAC,GACrGqB,IAAO,IAAI,KAAK,CAACrB,EAAI,IAAI,CAAC,GAC1BsB,IAAkB,SAAS,cAAc,GAAG,GAC5CC,IAAO,OAAO,IAAI,gBAAgBF,CAAI;AAC5C,QAAAC,EAAgB,OAAOC,GACvBD,EAAgB,WAAW,mBAAmB,KAAK,gBAAgBF,GAAYD,CAAQ,CAAC,GACxF,SAAS,KAAK,YAAYG,CAAe,GACzCA,EAAgB,MAAA,GAChB,SAAS,KAAK,YAAYA,CAAe,GACzC,OAAO,IAAI,gBAAgBC,CAAI;AAC/B,cAAM,EAAC,MAAA9F,GAAM,QAAAwE,GAAQ,SAAAC,MAAWF;AAChC,eAAO,EAAC,MAAAvE,GAAM,QAAAwE,GAAQ,SAAAC,EAAA;AAAA,MACxB;AAAA,IAAA,GAGKJ,EAASF,CAAM;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAOH,GAAahE,GAAY0F,GAA0C;AACxE,UAAMrB,IAAWkB,EAAM,OAAA,GACjBpB,IAA6B1C,EAAM,KAAK,gBAAA,GAAmB;AAAA,MAC/D,KAAAuC;AAAA,MACA,QAAQ;AAAA,MACR,cAAc;AAAA,MACd,MAAMhE,IAAOsF,EAAG,UAAUtF,CAAI,IAAI;AAAA,IAAA,CACnC;AAGD,gBAAK,aAAaqE,GAAUL,CAAG,GAG/BK,EAAS,aAAa,SAAS;AAAA,MAC7B,CAACE,MAA4B;AAC3B,cAAMoB,KAAcpB,EAAI,QAAQ,qBAAqB,KAAK,eAAe,KAAK,IAAA,CAAK,IAAI,MAAM,WAAW,EAAE,CAAC,GACrGqB,IAAO,IAAI,KAAK,CAACrB,EAAI,IAAI,CAAC,GAC1BsB,IAAkB,SAAS,cAAc,GAAG,GAC5CC,IAAO,OAAO,IAAI,gBAAgBF,CAAI;AAC5C,QAAAC,EAAgB,OAAOC,GACvBD,EAAgB,WAAW,mBAAmB,KAAK,gBAAgBF,GAAYD,CAAQ,CAAC,GACxF,SAAS,KAAK,YAAYG,CAAe,GACzCA,EAAgB,MAAA,GAChB,SAAS,KAAK,YAAYA,CAAe,GACzC,OAAO,IAAI,gBAAgBC,CAAI;AAC/B,cAAM,EAAC,MAAA9F,GAAM,QAAAwE,GAAQ,SAAAC,MAAWF;AAChC,eAAO,EAAC,MAAAvE,GAAM,QAAAwE,GAAQ,SAAAC,EAAA;AAAA,MACxB;AAAA,IAAA,GAGKJ,EAASF,CAAM;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMQ,gBAAgBwB,GAAoBD,GAA2B;AACrE,QAAI,CAACA,EAAU,QAAOC,KAAc;AACpC,QAAID,EAAS,QAAQ,GAAG,IAAI,IAAI;AAC9B,YAAMK,KAAOJ,KAAc,IAAI,MAAM,GAAG,EAAE,CAAC;AAC3C,aAAOI,IAAML,IAAW,MAAMK,IAAML;AAAA,IACtC;AACA,WAAOA;AAAA,EACT;AACF;AAGA,MAAMM,IAAkB,IAAIlC,EAAA,GC5ZfmC,IAAW,WACXC,IAAY;AAKzB,SAASC,EAAmBpF,GAAwB;AAClD,SAAO,iBAAiB,KAAKA,CAAK;AACpC;AAKO,SAASqF,KAAmB;AACjC,QAAMnC,IAAQvD,EAAmBwF,CAAS;AAC1C,EAAIjC,KAASkC,EAAmBlC,CAAK,IACnCvC,EAAO,QAAQuC,KAEfvC,EAAO,QAAQ,IACfT,EAAWiF,CAAS;AAGtB,QAAMhC,IAAUxD,EAAmBuF,CAAQ;AAC3C,EAAI/B,KAAWiC,EAAmBjC,CAAO,IACvCxC,EAAO,UAAUwC,KAEjBxC,EAAO,UAAU,IACjBT,EAAWgF,CAAQ;AAEvB;AAKO,SAASI,EAASpC,GAAqB;AAC5C,EAAAnD,EAAWoF,GAAWjC,CAAK,GAC3BvC,EAAO,QAAQuC;AACjB;AAKO,SAASqC,IAAmB;AACjC,MAAI5E,EAAO,UAAU;AACnB,WAAOA,EAAO;AAEhB,QAAMuC,IAAQvD,EAAmBwF,CAAS;AAC1C,SAAAxE,EAAO,QAAQuC,KAAS,IACjBvC,EAAO;AAChB;AAKO,SAAS6E,EAAWtC,GAAqB;AAC9C,EAAAnD,EAAWmF,GAAUhC,CAAK,GAC1BvC,EAAO,UAAUuC;AACnB;AAKO,SAASuC,IAAqB;AACnC,MAAI9E,EAAO,YAAY;AACrB,WAAOA,EAAO;AAEhB,QAAMuC,IAAQvD,EAAmBuF,CAAQ;AACzC,SAAAvE,EAAO,UAAUuC,KAAS,IACnBvC,EAAO;AAChB;AAKO,SAAS+E,IAAoB;AAClC,EAAA/E,EAAO,QAAQ,IACfA,EAAO,UAAU,IACjBR,EAAA;AACF;AAKO,SAASwF,IAAuB;AACrC,EAAAD,EAAA;AACF;ACnCO,SAASE,EAAO3G,GAA8B;AACnD,QAAM4G,IAAoB,CAAA,GACpBC,IAAgC,CAAA,GAChCC,IAAsC,CAAA;AAC5C,SAAA9G,IAAO,KAAK,MAAM,KAAK,UAAUA,CAAI,CAAC,GAEtCA,EAAK,QAAQ,SAAU+G,GAAM;AAC3B,IAAIA,EAAK,YAAYA,EAAK,aAAa,QAChCD,EAAQC,EAAK,QAAQ,MACxBD,EAAQC,EAAK,QAAQ,IAAI,CAAA,IAE3BD,EAAQC,EAAK,QAAQ,EAAE,KAAKA,CAAI,IAE9BA,EAAK,YAAYA,EAAK,SAAS,SAAS,KAC1CA,EAAK,SAAS,QAAQ,CAACC,MAAY;AACjC,MAAIA,EAAQ,aACLF,EAAQE,EAAQ,QAAQ,MAC3BF,EAAQE,EAAQ,QAAQ,IAAI,CAAA,IAE9BF,EAAQE,EAAQ,QAAQ,EAAE,KAAKA,CAAO;AAAA,IAE1C,CAAC;AAAA,EAEL,CAAC,GAEDhH,EAAK,QAAQ,SAAU+G,GAAM;AAC3B,IAAAF,EAAIE,EAAK,EAAE,IAAIA,GACXA,EAAK,YACFD,EAAQC,EAAK,QAAQ,MACpBD,EAAQC,EAAK,EAAE,MACjBF,EAAIE,EAAK,EAAE,EAAE,WAAWD,EAAQC,EAAK,EAAE,IAEzCH,EAAM,KAAKC,EAAIE,EAAK,EAAE,CAAC,IASvBA,EAAK,YAAYA,EAAK,SAAS,SAAS,KAC1CA,EAAK,SAAS,QAAQ,CAACC,MAAY;AACjC,MAAAH,EAAIG,EAAQ,EAAE,IAAIA,GACdF,EAAQE,EAAQ,EAAE,MACpBH,EAAIG,EAAQ,EAAE,EAAE,WAAWF,EAAQE,EAAQ,EAAE;AAAA,IAEjD,CAAC;AAAA,EAEL,CAAC,GAEMJ;AACT;AAEO,SAASK,GAAajH,GAAkBkH,IAAmB,IAAmB;AACnF,QAAMC,IAAQR,EAAO3G,CAAI;AAEzB,WAASoH,EAAKC,GAAkC;AAC9C,QAAI,CAAC,WAAW,QAAQ,KAAK,EAAE,SAASA,EAAK,YAAY,EAAE;AACzD,aAAO;AAGT,UAAMC,IAAoB;AAAA,MACxB,OAAOD,EAAK;AAAA,MACZ,MAAMA,EAAK;AAAA,MACX,IAAIA,EAAK;AAAA,MACT,aAAaA,EAAK;AAAA,IAAA;AAGpB,QAAIA,EAAK,OAAO,CAAC,UAAU,MAAM,EAAE,SAASA,EAAK,YAAY,EAAE;AAC7D,UAAIH,KAAWG,EAAK,IAAI,QAAQ,WAAW,IAAI;AAC7C,QAAAC,EAAQ,KAAK,qBAAqBD,EAAK,YAAYA,EAAK,EAAE;AAAA,eACjDA,EAAK,IAAI,QAAQ,WAAW,IAAI;AACzC,QAAAC,EAAQ,KAAK,eAAeD,EAAK,YAAYA,EAAK,EAAE;AAAA,eAC3CA,EAAK,IAAI,QAAQ,MAAM,IAAI,IAAI;AACxC,cAAME,IAAY;AAClB,QAAAD,EAAQ,KAAK,WAAWE,EAAIH,EAAK,GAAG,CAAC,QAAQ,mBAAmBA,EAAK,GAAG,CAAC,UAAUA,EAAK,IAAI,eAAeE,CAAS;AAAA,MACtH;AACE,QAAIF,EAAK,IAAI,QAAQ,GAAG,MAAM,MAC5BA,EAAK,MAAM,IAAIA,EAAK,GAAG,KAEzBC,EAAQ,KAAKD,EAAK;AAItB,WAAIA,EAAK,aACPC,EAAQ,cAAc,IACtBA,EAAQ,WAAWD,EAAK,SAAS,IAAID,CAAI,EAAE,OAAO,CAACL,MAA2B,CAAC,CAACA,CAAI,IAG/EO;AAAA,EACT;AAEA,SAAOH,EAAM,IAAIC,CAAI,EAAE,OAAO,CAACL,MAA2B,CAAC,CAACA,CAAI;AAClE;AAEO,SAASU,GACdN,GACAO,GACe;AACf,QAAMC,IAAuB,CAAA;AAE7B,aAAWN,KAAQF,GAAO;AACxB,QAAI,CAACE,EAAK;AACR;AAGF,QAAIO,IAA4B;AAEhC,IAAAA,IAAQF,EAAoBL,CAAI,GAE5BO,KACFD,EAAM,KAAKC,CAAK;AAAA,EAEpB;AAEA,SAAOD;AACT;AC5KA,MAAME,IAAiB;AAKvB,IAAIC,IAAiC;AAK9B,SAASC,KAAkC;AAEhD,MAAID;AACF,WAAOA;AAIT,QAAME,IAAStH,EAAuBmH,CAAc;AACpD,SAAIG,KACFF,IAAcE,GACPA,KAGF;AACT;AAKO,SAASC,GAAad,GAAyB;AACpD,EAAAW,IAAcX,GACdrG,EAAW+G,GAAgBV,CAAK;AAClC;AAKO,SAASe,KAAuB;AACrC,EAAAJ,IAAc,MACd7G,EAAW4G,CAAc;AAC3B;ACvCA,eAAsBM,GAASC,IAAiB,IAA4B;AAC1E,QAAMJ,IAASD,GAAA;AACf,MAAIC;AACF,WAAOA;AAOT,QAAMX,KAJM,MAAMgB,EAAY;AAAA,IAC5BD,IAAQ,gCAAgC;AAAA,IACxC,CAAA;AAAA,EAAC,GAEc,KAAK;AACtB,SAAAH,GAAaZ,CAAI,GACVA;AACT;AAEO,SAASiB,KAAkB;AAChC,EAAAJ,GAAA;AACF;ACVO,MAAMK,KAAiBC,EAAY,eAAe,MAAM;AAC7D,EAAAlC,EAAA,GACAE,EAAA;AAEA,QAAMiC,IAASC,EAAY,EAAE,GACvBC,IAAWD,EAAY,EAAE,GACzBpG,IAAOoG,EAAY,EAAE,GACrBE,IAASF,EAAY,EAAE,GACvBG,IAAaH,EAAa,CAAC,CAAChH,EAAO,SAAS,CAAC,CAACA,EAAO,OAAO,GAC5DwF,IAAUwB,EAAa,CAAC,CAAChH,EAAO,OAAO;AAsG7C,SAAO;AAAA;AAAA,IAEL,QAAA+G;AAAA,IACA,UAAAE;AAAA,IACA,QAAAC;AAAA;AAAA,IAGA,YAAAC;AAAA,IACA,SAAA3B;AAAA;AAAA,IAGA,OA/GY,OAAO1B,MAGyB;;AAC5C,YAAMV,IAAW,MAAMuD,EAAY;AAAA,QACjC;AAAA,QACA7C;AAAA,QACA;AAAA,MAAA;AAGF,cAAIpB,IAAAU,EAAS,SAAT,QAAAV,EAAe,UACjBiC,EAASvB,EAAS,KAAK,KAAK,GAC5B+D,EAAW,QAAQ,IACnB3B,EAAQ,QAAQ,KAGXpC;AAAA,IACT;AAAA,IA+FE,QAvBa,YAA2B;AAExC,MAAA4B,EAAA,GACA4B,GAAA,GACAO,EAAW,QAAQ,IACnB3B,EAAQ,QAAQ,IAChBuB,EAAO,QAAQ,IACfE,EAAS,QAAQ,IACjBC,EAAO,QAAQ;AAAA,IACjB;AAAA,IAeE,aA3FkB,YAA6C;AAC/D,YAAM9D,IAAW,MAAMuD,EAAY,KAAe,+BAA+B,CAAA,GAAI,MAAM,GAErFrI,IAAO8E,EAAS;AACtB,aAAI9E,MACFyI,EAAO,QAAQzI,EAAK,UAAU,IAC9B2I,EAAS,QAAQ3I,EAAK,YAAY,IAClCsC,EAAK,QAAQtC,EAAK,QAAQ,IAC1B4I,EAAO,QAAQ,IAEX5I,EAAK,mBACP0B,EAAO,IAAI,mBAAmB1B,EAAK,eAAe,GAEhDA,EAAK,YACP0B,EAAO,IAAI,YAAY1B,EAAK,QAAQ,IAIjC8E;AAAA,IACT;AAAA,IAyEE,SApEc,OAAOU,MAGuB;;AAC5C,YAAMV,IAAW,MAAMuD,EAAY,KAAsB,eAAe7C,GAAQ,MAAM;AAGtF,cAAIpB,IAAAU,EAAS,SAAT,QAAAV,EAAe,UACjBmC,EAAWzB,EAAS,KAAK,KAAK,GAC9B+D,EAAW,QAAQ,IACnB3B,EAAQ,QAAQ,KAGXpC;AAAA,IACT;AAAA,IAuDE,eAlDoB,YAAwC;;AAC5D,YAAMA,IAAW,MAAMuD,EAAY,KAAoB,uBAAuB,CAAA,GAAI,MAAM,GAElFS,KAAS1E,IAAAU,EAAS,SAAT,gBAAAV,EAAe;AAC9B,aAAI0E,MACFL,EAAO,QAAQK,EAAO,MAAM,IAC5BH,EAAS,QAAQG,EAAO,YAAY,IACpCxG,EAAK,QAAQwG,EAAO,QAAQ,IAC5BF,EAAO,QAAQ,IAEXE,EAAO,YACTpH,EAAO,IAAI,mBAAmBoH,EAAO,QAAQ,GAE3CA,EAAO,YACTpH,EAAO,IAAI,YAAYoH,EAAO,QAAQ,IAInChE;AAAA,IACT;AAAA,EA+BE;AAEJ,CAAC;"}
|
|
1
|
+
{"version":3,"file":"index.es.js","sources":["../utils/storage.ts","../utils/config.ts","../utils/tools.ts","../utils/event.ts","../utils/index.ts","../api/http.ts","../auth/token.ts","../menu/converter.ts","../menu/cache.ts","../menu/service.ts","../store/client.ts"],"sourcesContent":["/**\n * Base64 编码(支持 Unicode)\n */\nfunction base64Encode(data: string): string {\n const bytes = new TextEncoder().encode(data);\n const binString = Array.from(bytes, (byte) => String.fromCharCode(byte)).join('');\n return btoa(binString);\n}\n\n/**\n * Base64 解码(支持 Unicode)\n */\nfunction base64Decode(base64: string): string {\n const binString = atob(base64);\n const bytes = Uint8Array.from(binString, (char) => char.charCodeAt(0));\n return new TextDecoder().decode(bytes);\n}\n\n/**\n * 简单混淆编码\n * 使用 Base64 + 字符串反转\n */\nfunction encode(data: string): string {\n try {\n // 先 Base64\n let encoded = base64Encode(data);\n // 简单混淆:反转字符串\n return encoded.split('').reverse().join('');\n } catch {\n return data;\n }\n}\n\n/**\n * 简单混淆解码\n */\nfunction decode(data: string): string {\n try {\n // 反混淆:反转回来\n let reversed = data.split('').reverse().join('');\n // Base64 解码\n return base64Decode(reversed);\n } catch {\n return data;\n }\n}\n\n/**\n * 获取存储数据\n */\nexport const getStorage = <T = any>(key: string): T | null => {\n const objectStr = localStorage.getItem(key);\n if (objectStr !== null) {\n try {\n const decrypted = decode(objectStr);\n try {\n return JSON.parse(decrypted) as T;\n } catch {\n return decrypted as T;\n }\n } catch {\n // 解码失败,尝试直接解析原始数据\n try {\n return JSON.parse(objectStr) as T;\n } catch {\n return objectStr as T;\n }\n }\n }\n return null;\n};\n\n/**\n * 设置存储数据\n */\nexport const setStorage = <T>(key: string, value: T): void => {\n let data: string;\n if (typeof value === 'object') {\n data = JSON.stringify(value);\n } else {\n data = String(value);\n }\n try {\n const encrypted = encode(String(data));\n localStorage.setItem(key, encrypted);\n } catch (e) {\n // 混淆失败,直接存储\n localStorage.setItem(key, String(data));\n }\n};\n\n/**\n * 删除存储数据\n */\nexport const delStorage = (key: string): void => {\n localStorage.removeItem(key);\n};\n\n/**\n * 清空所有存储\n */\nexport const clearStorage = (): void => {\n localStorage.clear();\n sessionStorage.clear();\n};\n","import {get, set as lodashSet, merge} from 'lodash-es';\nimport {reactive} from 'vue';\n\n/**\n * 全局配置对象\n */\ninterface AppConfig {\n token?: string;\n saToken?: string;\n storageKey?: string;\n [key: string]: any;\n}\n\n/**\n * 配置分层(优先级从高到低):server > code > host > builtin\n * - server:服务端参数(parameter 接口),整层替换\n * - code:代码点设置(setConfig / token / 用户数据)\n * - host:宿主配置文件(mergeConfig 批量注入)\n * - builtin:包内内置默认(mergeBuiltinConfig)\n */\nclass ConfigManager {\n private builtinLayer: AppConfig = {};\n private hostLayer: AppConfig = {};\n private codeLayer: AppConfig = {};\n private serverLayer: AppConfig = {};\n\n /**\n * 各层合并后的生效视图(响应式):组件中以 computed(() => getConfig(path))\n *读取即可自动随任意层变更更新\n */\n private snapshot = reactive<AppConfig>({});\n\n /**\n * 重算合并视图:保持同一 reactive 代理对象,属性级依赖追踪不失效\n */\n private rebuild(): void {\n const merged = merge({}, this.builtinLayer, this.hostLayer, this.codeLayer, this.serverLayer);\n for (const key of Object.keys(this.snapshot)) {\n delete this.snapshot[key];\n }\n Object.assign(this.snapshot, merged);\n }\n\n /**\n * 获取配置值(从生效视图读取,无 path 时返回整个视图对象)\n */\n get<T = any>(path?: string, defaultValue?: T): T {\n if (!path) {\n return this.snapshot as T;\n }\n return get(this.snapshot, path, defaultValue);\n }\n\n /**\n * 设置配置值(写入代码层)\n */\n set(path: string, value: any): void {\n lodashSet(this.codeLayer, path, value);\n this.rebuild();\n }\n\n /**\n * 合并宿主配置\n */\n merge(newConfig: AppConfig): void {\n merge(this.hostLayer, newConfig);\n this.rebuild();\n }\n\n /**\n * 合并包内内置默认(优先级最低,不会覆盖宿主/代码设置)\n */\n mergeBuiltin(newConfig: AppConfig): void {\n merge(this.builtinLayer, newConfig);\n this.rebuild();\n }\n\n /**\n * 整层替换服务端参数(禁用/删除的参数随替换回落到低层值)\n */\n replaceServer(newConfig: AppConfig): void {\n this.serverLayer = newConfig;\n this.rebuild();\n }\n\n /**\n * 初始化配置(重置宿主层,清空代码/服务端层,保留内置默认)\n */\n init(newConfig: AppConfig): void {\n this.hostLayer = {...newConfig};\n this.codeLayer = {};\n this.serverLayer = {};\n this.rebuild();\n }\n\n /**\n * Token 快捷访问\n */\n get token(): string | undefined {\n return this.get('token');\n }\n\n set token(value: string | undefined) {\n this.set('token', value);\n }\n\n /**\n * SaToken 快捷访问\n */\n get saToken(): string | undefined {\n return this.get('saToken');\n }\n\n set saToken(value: string | undefined) {\n this.set('saToken', value);\n }\n\n /**\n * StorageKey 快捷访问\n */\n get storageKey(): string {\n return this.get('storageKey') || 'yh-client-storage-key';\n }\n\n set storageKey(value: string) {\n this.set('storageKey', value);\n }\n}\n\n/**\n * 全局配置单例\n */\nexport const Config = new ConfigManager();\n\n/**\n * 获取配置值\n */\nexport function getConfig<T = any>(path?: string, defaultValue?: T): T {\n return Config.get(path, defaultValue);\n}\n\n/**\n * 设置配置值\n */\nexport function setConfig(path: string, value: any): void {\n Config.set(path, value);\n}\n\n/**\n * 合并宿主配置\n */\nexport function mergeConfig(newConfig: AppConfig): void {\n Config.merge(newConfig);\n}\n\n/**\n * 合并包内内置默认配置\n */\nexport function mergeBuiltinConfig(newConfig: AppConfig): void {\n Config.mergeBuiltin(newConfig);\n}\n\n/**\n * 整层替换服务端参数配置\n */\nexport function replaceServerConfig(newConfig: AppConfig): void {\n Config.replaceServer(newConfig);\n}\n\n/**\n * 初始化配置\n */\nexport function initConfig(newConfig: AppConfig): void {\n Config.init(newConfig);\n}\n\nexport type {AppConfig};\n","import {MD5} from 'crypto-js';\n\n/**\n * 生成 MD5 哈希值\n * @param input - 要哈希的输入字符串\n * @returns MD5 哈希值的十六进制字符串\n */\nexport async function generateMd5Hash(input: string): Promise<string> {\n return MD5(input).toString();\n}\n\n/**\n * 生成简单的哈希值\n * 使用位运算生成一个简短的哈希值,适用于不需要高安全性的场景\n * @param input - 要哈希的输入字符串\n * @returns 36 进制的哈希字符串\n */\nexport function generateSimpleHash(input: string): string {\n let hash = 0;\n for (let i = 0; i < input.length; i++) {\n const char = input.charCodeAt(i);\n hash = (hash << 5) - hash + char;\n hash = hash & hash;\n }\n return Math.abs(hash).toString(36);\n}\n\n/**\n * 下划线命名转换为驼峰命名\n * 将字符串中的下划线后面的字母转换为大写,并移除下划线\n * @param name - 包含下划线的字符串,如 user_name\n * @returns 转换后的驼峰命名字符串,如 userName\n */\nexport const toHump = (name: string): string => {\n return name.replace(/\\_(\\w)/g, function (all, letter) {\n return letter.toUpperCase();\n });\n};\n\n/**\n * 生成 UUID 格式的随机 ID\n * 生成一个类似 UUID 的字符串,其中第 15 位是 4(UUID 版本位)\n * @returns 大写的 UUID 字符串,如 12345678-1234-4123-8123-1234567890AB\n */\nexport const generateId = (): string => {\n const d = new Date().getTime();\n const uuid = 'xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx'.replace(/[xy]/g, function (c) {\n const r = ((d + Math.random() * 16) % 16) | 0;\n const newD = Math.floor(d / 16);\n return (c === 'x' ? r : (r & 0x3) | 0x8).toString(16);\n });\n return uuid.toUpperCase();\n};\n","type EventData = Record<string, any>;\ntype EventCallback<T = any> = (data: T) => void;\n\n/**\n * 触发自定义事件\n * @param eventName 事件名称\n * @param data 事件数据\n * @param target 目标对象,默认为 window\n */\nexport function trigger<T>(eventName: string, data?: T, target = window): void {\n const event = new CustomEvent(eventName, {detail: data});\n target.dispatchEvent(event);\n}\n\n/**\n * 监听自定义事件\n * @param eventName 事件名称\n * @param callback 回调函数\n * @param target 目标对象,默认为 window\n * @returns 清理函数\n */\nexport function on<T>(eventName: string, callback: EventCallback<T>, target = window): () => void {\n const handler = (e: Event) => callback((e as CustomEvent<T>).detail);\n target.addEventListener(eventName, handler);\n return () => target.removeEventListener(eventName, handler);\n}\n\n/**\n * 监听自定义事件(仅触发一次)\n * @param eventName 事件名称\n * @param callback 回调函数\n * @param target 目标对象,默认为 window\n * @returns 清理函数\n */\nexport function once<T>(\n eventName: string,\n callback: EventCallback<T>,\n target = window\n): () => void {\n const cleanup = on(\n eventName,\n (data: T) => {\n callback(data);\n cleanup();\n },\n target\n );\n return cleanup;\n}\n\n/**\n * 移除事件监听(已废弃,建议使用 on 返回的清理函数)\n * @deprecated 使用 on 返回的清理函数代替\n */\nexport function off<T>(eventName: string, callback: EventCallback<T>, target = window): void {\n const handler = (e: Event) => callback((e as CustomEvent<T>).detail);\n target.removeEventListener(eventName, handler);\n}\n\nexport type {EventData, EventCallback};\n","import {cloneDeep, isEqual as lodashIsEqual, assign} from 'lodash-es';\nexport const deepClone = cloneDeep;\nexport const isEqual = lodashIsEqual;\nexport const overwriteObj = assign;\n\nexport {getStorage, setStorage, delStorage, clearStorage} from './storage';\n\nexport {\n Config,\n getConfig,\n setConfig,\n mergeConfig,\n mergeBuiltinConfig,\n replaceServerConfig,\n initConfig,\n} from './config';\nexport type {AppConfig} from './config';\n\nexport {generateMd5Hash, generateId, generateSimpleHash, toHump} from './tools';\n\nexport {trigger, on, off, once} from './event';\n","import axios, {\n AxiosInstance,\n AxiosResponse,\n AxiosError,\n InternalAxiosRequestConfig,\n AxiosRequestConfig,\n} from 'axios';\nimport qs from 'qs';\nimport {merge} from 'lodash-es';\nimport type {RequestOptions, HttpResponse} from '../types';\nimport {Config, trigger} from '../utils';\nimport {ElMessage} from 'element-plus';\n\n/**\n * HTTP 请求队列\n */\ninterface RequestQueue {\n [url: string]: boolean;\n}\n\n/**\n * HTTP 请求类\n */\nexport class HttpRequest {\n private baseUrl: string;\n private queue: RequestQueue;\n private timeout: number = 120000; // 2分钟\n\n // 宿主项目可配置的钩子\n public onBusinessError?: (msg: string) => boolean;\n public onHttpError?: (error: AxiosError, url: string) => any;\n public onLoginRedirect?: () => void;\n public onRequestStart?: () => void;\n public onRequestEnd?: () => void;\n\n constructor(baseUrl: string = '') {\n this.baseUrl = baseUrl;\n this.queue = {};\n }\n\n /**\n * 设置基础 URL\n */\n setBaseUrl(url: string): void {\n this.baseUrl = url;\n }\n\n /**\n * 获取内部配置\n */\n private getInsideConfig(): AxiosRequestConfig {\n const token = Config.token;\n const saToken = Config.saToken;\n\n const config: AxiosRequestConfig = {\n baseURL: this.baseUrl,\n timeout: this.timeout,\n headers: {},\n };\n\n if (token) {\n config.headers = {\n ...config.headers,\n TOKEN: token,\n };\n }\n\n if (saToken) {\n config.headers = {\n ...config.headers,\n saToken: saToken,\n };\n }\n\n return config;\n }\n\n /**\n * 销毁加载状态\n */\n private destroy(url: string): void {\n delete this.queue[url];\n if (!Object.keys(this.queue).length) {\n this.onRequestEnd?.();\n }\n }\n\n /**\n * 设置拦截器\n */\n private interceptors(instance: AxiosInstance, url: string): void {\n // 请求拦截\n instance.interceptors.request.use(\n (config: InternalAxiosRequestConfig) => {\n this.queue[url] = true;\n if (Object.keys(this.queue).length === 1) {\n this.onRequestStart?.();\n }\n return config;\n },\n (error: AxiosError) => {\n console.error('[HTTP] 请求错误:', error);\n return Promise.reject(error);\n }\n );\n\n // 响应拦截\n instance.interceptors.response.use(\n (res: AxiosResponse): any => {\n const {data, status, headers} = res;\n this.destroy(url);\n if (data.result || data.result === void 0) {\n return {data, status, headers};\n } else {\n const {msg} = data;\n this.handleError(msg, url);\n return {data, status, headers};\n }\n },\n (error: AxiosError): any => {\n this.destroy(url);\n // 错误处理\n if (error.response) {\n return this.handleHttpError(error, url);\n } else {\n console.error('[HTTP] 未处理的网络错误', error);\n this.showMessage('请联系管理员,并查看控制台日志');\n return Promise.reject(error);\n }\n }\n );\n }\n\n /**\n * 处理业务错误\n */\n private handleError(msg: string | undefined, url: string): void {\n if (!msg) return;\n\n // 特殊消息:无数据时不显示错误提示\n if (msg === '无数据') {\n return;\n }\n\n // 钩子:宿主项目可先处理自定义错误逻辑\n if (this.onBusinessError) {\n const handled = this.onBusinessError(msg);\n if (handled) return;\n }\n\n // 登录超时\n if (msg.indexOf('Login Timeout') > -1 || msg.indexOf('Timeout') > -1 || msg.indexOf('登录超时!') > -1) {\n this.showMessage('登录状态已超时');\n if (this.onLoginRedirect) {\n this.onLoginRedirect();\n } else {\n trigger('to:login');\n }\n return;\n }\n\n // 违反唯一约束\n if (msg.indexOf('violates unique constraint') > -1) {\n console.warn('[HTTP] 违反唯一约束错误消息:', msg);\n const reg = /Key \\(([\\s|\\S]+)\\)=\\(([\\s|\\S]+)\\) already exists/;\n const match = msg.match(reg);\n let errMsg = msg;\n if (match !== null && match.length >= 3) {\n errMsg = `操作失败:数据[${match[2]}]已经存在!`;\n }\n this.showMessage(errMsg);\n return;\n }\n\n // 违反外键约束\n if (msg.indexOf('violates foreign key constraint') > -1) {\n console.warn('[HTTP] 违反外键约束错误消息:', msg);\n this.showMessage('操作失败:此条数据在其他地方使用!');\n return;\n }\n\n // 其他错误\n this.showMessage(msg);\n }\n\n /**\n * 处理 HTTP 错误\n */\n private handleHttpError(error: AxiosError, url: string): any {\n const {response} = error;\n if (!response) {\n return Promise.reject(error);\n }\n\n // 钩子:宿主项目可先处理 HTTP 错误\n if (this.onHttpError) {\n const result = this.onHttpError(error, url);\n if (result !== undefined) {\n return result;\n }\n }\n\n switch (response.status) {\n case 401:\n if (this.onLoginRedirect) {\n this.onLoginRedirect();\n } else {\n trigger('to:login');\n }\n break;\n case 400:\n console.error('[HTTP] HTTP 400', response);\n const msg400 = (response.data as any)?.msg;\n if (msg400) this.showMessage(msg400);\n break;\n case 404:\n this.showMessage(`${error.config?.url},资源不存在,请联系管理员`);\n break;\n case 500:\n this.showMessage('服务器错误,请联系管理员');\n break;\n default:\n console.error('[HTTP] Error', response);\n this.showMessage('请求遇到问题,请联系管理员协助');\n break;\n }\n\n return response as HttpResponse;\n }\n\n /**\n * 显示消息(需要 Element Plus)\n */\n private showMessage(message: string): void {\n // 动态导入 Element Plus,避免强依赖\n try {\n // 如果项目中有 ElMessage,使用它\n if (ElMessage) {\n ElMessage.error(message);\n } else {\n console.error('[HTTP]', message);\n }\n } catch (error) {\n console.error('[HTTP]', message);\n }\n }\n\n /**\n * 通用请求\n */\n request<T = any>(options: RequestOptions): Promise<HttpResponse<T>> {\n // 请求数据格式化\n let requestData = options.data;\n if (options.type !== 'json' && requestData && typeof requestData === 'object') {\n requestData = qs.stringify(requestData);\n }\n\n if (options.type === 'json') {\n if (!options.headers) {\n options.headers = {};\n }\n options.headers['Content-Type'] = 'application/json';\n }\n\n const instance = axios.create();\n const config: AxiosRequestConfig = merge(this.getInsideConfig(), {\n url: options.url,\n method: options.method || 'GET',\n data: requestData,\n params: options.params,\n headers: options.headers,\n timeout: options.timeout,\n responseType: options.responseType,\n });\n\n this.interceptors(instance, options.url);\n return instance(config) as Promise<HttpResponse<T>>;\n }\n\n /**\n * GET 请求\n */\n get<T = any>(url: string, params?: Record<string, any>): Promise<HttpResponse<T>> {\n return this.request<T>({url, method: 'GET', params});\n }\n\n /**\n * POST 请求\n */\n post<T = any>(url: string, data?: any, type?: 'json' | 'form'): Promise<HttpResponse<T>> {\n return this.request<T>({url, method: 'POST', data, type: type || 'form'});\n }\n\n /**\n * POST JSON 请求\n */\n postJson<T = any>(url: string, data?: any): Promise<HttpResponse<T>> {\n const instance = axios.create();\n const config: AxiosRequestConfig = merge(this.getInsideConfig(), {\n url,\n method: 'POST',\n data,\n headers: {\n 'Content-Type': 'application/json',\n },\n });\n\n this.interceptors(instance, url);\n return instance(config) as Promise<HttpResponse<T>>;\n }\n\n /**\n * 上传文件\n */\n upload<T = any>(url: string, data: any): Promise<HttpResponse<T>> {\n const instance = axios.create();\n const config: AxiosRequestConfig = merge(this.getInsideConfig(), {\n url,\n method: 'POST',\n data,\n headers: {\n 'Content-Type': 'multipart/form-data',\n },\n });\n\n this.interceptors(instance, url);\n return instance(config) as Promise<HttpResponse<T>>;\n }\n\n /**\n * 下载文件(POST)\n */\n download(url: string, data?: any, fileName?: string): Promise<HttpResponse> {\n const instance = axios.create();\n const config: AxiosRequestConfig = merge(this.getInsideConfig(), {\n url,\n method: 'POST',\n responseType: 'blob',\n data: data ? qs.stringify(data) : undefined,\n });\n\n // 注册基础拦截器(包含 destroy 调用)\n this.interceptors(instance, url);\n\n // 添加文件下载特定的处理\n instance.interceptors.response.use(\n (res: AxiosResponse): any => {\n if (res.data.result === false) {\n this.showMessage('导出文件异常: ' + res.data.msg);\n return;\n }\n const serverName = (res.headers['content-disposition'] || `filename=文件-${Date.now()}`).split('filename=')[1];\n const blob = new Blob([res.data]);\n const downloadElement = document.createElement('a');\n const href = window.URL.createObjectURL(blob);\n downloadElement.href = href;\n downloadElement.download = decodeURIComponent(this.resolveFileName(serverName, fileName));\n document.body.appendChild(downloadElement);\n downloadElement.click();\n document.body.removeChild(downloadElement);\n window.URL.revokeObjectURL(href);\n const {data, status, headers} = res;\n return {data, status, headers};\n }\n );\n\n return instance(config) as Promise<HttpResponse>;\n }\n\n /**\n * 导出文件(GET)\n */\n export(url: string, data?: any, fileName?: string): Promise<HttpResponse> {\n const instance = axios.create();\n const config: AxiosRequestConfig = merge(this.getInsideConfig(), {\n url,\n method: 'GET',\n responseType: 'blob',\n data: data ? qs.stringify(data) : undefined,\n });\n\n // 注册基础拦截器(包含 destroy 调用)\n this.interceptors(instance, url);\n\n // 添加文件导出特定的处理\n instance.interceptors.response.use(\n (res: AxiosResponse): any => {\n const serverName = (res.headers['content-disposition'] || `filename=文件-${Date.now()}`).split('filename=')[1];\n const blob = new Blob([res.data]);\n const downloadElement = document.createElement('a');\n const href = window.URL.createObjectURL(blob);\n downloadElement.href = href;\n downloadElement.download = decodeURIComponent(this.resolveFileName(serverName, fileName));\n document.body.appendChild(downloadElement);\n downloadElement.click();\n document.body.removeChild(downloadElement);\n window.URL.revokeObjectURL(href);\n const {data, status, headers} = res;\n return {data, status, headers};\n }\n );\n\n return instance(config) as Promise<HttpResponse>;\n }\n\n /**\n * 解析下载文件名\n * fileName 含 . 时追加服务器文件名的扩展名\n */\n private resolveFileName(serverName: string, fileName?: string): string {\n if (!fileName) return serverName || '';\n if (fileName.indexOf('.') > -1) {\n const ext = (serverName || '').split('.')[1];\n return ext ? fileName + '.' + ext : fileName;\n }\n return fileName;\n }\n}\n\n// 创建默认实例\nconst defaultInstance = new HttpRequest();\n\n// 导出类和默认实例\nexport default defaultInstance;\n","/**\n * Token 管理\n * 从 yh-pub 迁移并增强\n */\n\nimport {setStorage, getStorage, delStorage, clearStorage} from '../utils/storage';\nimport {Config} from '../utils/config';\n\nexport const SA_TOKEN = 'SATOKEN';\nexport const TOKEN_KEY = 'login-token';\n\n/**\n * 判断值是否只包含可打印 ASCII 字符(合法的 HTTP header 值)\n */\nfunction isValidHeaderValue(value: string): boolean {\n return /^[\\x20-\\x7E]*$/.test(value);\n}\n\n/**\n * 初始化Token(从存储加载到Config)\n */\nexport function initTokens(): void {\n const token = getStorage<string>(TOKEN_KEY);\n if (token && isValidHeaderValue(token)) {\n Config.token = token;\n } else {\n Config.token = '';\n delStorage(TOKEN_KEY);\n }\n\n const saToken = getStorage<string>(SA_TOKEN);\n if (saToken && isValidHeaderValue(saToken)) {\n Config.saToken = saToken;\n } else {\n Config.saToken = '';\n delStorage(SA_TOKEN);\n }\n}\n\n/**\n * 存储Token并同步到Config\n */\nexport function setToken(token: string): void {\n setStorage(TOKEN_KEY, token);\n Config.token = token;\n}\n\n/**\n * 获取Token(优先从Config获取)\n */\nexport function getToken(): string {\n if (Config.token !== undefined) {\n return Config.token;\n }\n const token = getStorage<string>(TOKEN_KEY);\n Config.token = token || '';\n return Config.token as string;\n}\n\n/**\n * 存储SAToken并同步到Config\n */\nexport function setSaToken(token: string): void {\n setStorage(SA_TOKEN, token);\n Config.saToken = token;\n}\n\n/**\n * 获取SaToken(优先从Config获取)\n */\nexport function getSaToken(): string {\n if (Config.saToken !== undefined) {\n return Config.saToken;\n }\n const token = getStorage<string>(SA_TOKEN);\n Config.saToken = token || '';\n return Config.saToken as string;\n}\n\n/**\n * 清除Token(清空Config中的值)\n */\nexport function clearTokens(): void {\n Config.token = '';\n Config.saToken = '';\n clearStorage();\n}\n\n/**\n * 清除所有Token和存储\n */\nexport function clearAllTokens(): void {\n clearTokens();\n}\n","export interface MenuData {\n id: string;\n parentId?: string;\n name: string;\n iconPath?: string;\n url?: string;\n menuType?: string;\n windowId?: string;\n sysModuleId?: string;\n children?: MenuData[];\n}\n\nexport interface MenuItem {\n title: string;\n icon?: string;\n id: string;\n hasChildren?: boolean;\n sysModuleId?: string;\n children?: MenuItem[];\n}\n\nexport interface RouteConfig {\n path: string;\n id: string;\n name: string;\n component: any;\n meta: {\n id: string;\n title: string;\n icon?: string;\n isWhite?: boolean;\n keepAlive?: boolean;\n isIframe?: boolean;\n url?: string;\n };\n}\n\nexport type RouteHandler = (menu: MenuData) => RouteConfig | null;\n\nexport interface RouteHandlerConfig {\n match: (url: string) => boolean;\n handler: RouteHandler;\n priority?: number;\n}\n\nimport md5 from 'crypto-js/md5';\n\nlet routeHandlers: RouteHandlerConfig[] = [];\n\nexport function registerRouteHandler(config: RouteHandlerConfig) {\n routeHandlers.push(config);\n routeHandlers.sort((a, b) => (b.priority || 0) - (a.priority || 0));\n}\n\nexport function clearRouteHandlers() {\n routeHandlers = [];\n}\n\nexport function toTree(data: MenuData[]): MenuData[] {\n const nodes: MenuData[] = [];\n const map: Record<string, MenuData> = {};\n const menuMap: Record<string, MenuData[]> = {};\n data = JSON.parse(JSON.stringify(data));\n\n data.forEach(function (item) {\n if (item.parentId && item.parentId !== '0') {\n if (!menuMap[item.parentId]) {\n menuMap[item.parentId] = [];\n }\n menuMap[item.parentId].push(item);\n }\n if (item.children && item.children.length > 0) {\n item.children.forEach((itemSub) => {\n if (itemSub.parentId) {\n if (!menuMap[itemSub.parentId]) {\n menuMap[itemSub.parentId] = [];\n }\n menuMap[itemSub.parentId].push(itemSub);\n }\n });\n }\n });\n\n data.forEach(function (item) {\n map[item.id] = item;\n if (item.parentId) {\n if (!menuMap[item.parentId]) {\n if (menuMap[item.id]) {\n map[item.id].children = menuMap[item.id];\n }\n nodes.push(map[item.id]);\n }\n } else {\n // 没有 parentId 的是顶级菜单,直接添加\n if (menuMap[item.id]) {\n map[item.id].children = menuMap[item.id];\n }\n nodes.push(map[item.id]);\n }\n if (item.children && item.children.length > 0) {\n item.children.forEach((itemSub) => {\n map[itemSub.id] = itemSub;\n if (menuMap[itemSub.id]) {\n map[itemSub.id].children = menuMap[itemSub.id];\n }\n });\n }\n });\n\n return nodes;\n}\n\nexport function menusToAside(data: MenuData[], isAdmin: boolean = false): MenuItem[] {\n const menus = toTree(data);\n\n function mtoa(menu: MenuData): MenuItem | false {\n if (['SUBPAGE', 'JOIN', 'APP'].includes(menu.menuType || '')) {\n return false;\n }\n\n const newMenu: MenuItem = {\n title: menu.name,\n icon: menu.iconPath,\n id: menu.id,\n sysModuleId: menu.sysModuleId,\n };\n\n if (menu.url && ['WINDOW', 'LINK'].includes(menu.menuType || '')) {\n if (isAdmin && menu.url.indexOf('sys/index') > -1) {\n newMenu.id = `/admin/sys/window/${menu.windowId || menu.id}`;\n } else if (menu.url.indexOf('sys/index') > -1) {\n newMenu.id = `/sys/window/${menu.windowId || menu.id}`;\n } else if (menu.url.indexOf('http') > -1) {\n const keepAlive = '';\n newMenu.id = `/iframe/${md5(menu.url)}?url=${encodeURIComponent(menu.url)}&title=${menu.name}&_keepAlive=${keepAlive}`;\n } else {\n if (menu.url.indexOf('/') !== 0) {\n menu.url = `/${menu.url}`;\n }\n newMenu.id = menu.url;\n }\n }\n\n if (menu.children) {\n newMenu.hasChildren = true;\n newMenu.children = menu.children.map(mtoa).filter((item): item is MenuItem => !!item);\n }\n\n return newMenu;\n }\n\n return menus.map(mtoa).filter((item): item is MenuItem => !!item);\n}\n\nexport function getRoutes(\n menus: MenuData[],\n defaultRouteHandler: (menu: MenuData) => RouteConfig | null\n): RouteConfig[] {\n const items: RouteConfig[] = [];\n\n for (const menu of menus) {\n if (!menu.url) {\n continue;\n }\n\n let route: RouteConfig | null = null;\n\n route = defaultRouteHandler(menu);\n\n if (route) {\n items.push(route);\n }\n }\n\n return items;\n}\n","import type {MenuData} from './converter';\nimport {getStorage, setStorage, delStorage} from '../utils';\n\nconst MENU_CACHE_KEY = 'yh-menu-cache';\n\n/**\n * 内存缓存\n */\nlet memoryCache: MenuData[] | null = null;\n\n/**\n * 获取菜单缓存(优先从内存获取)\n */\nexport function getMenuCache(): MenuData[] | null {\n // 1. 从内存获取\n if (memoryCache) {\n return memoryCache;\n }\n\n // 2. 从 LocalStorage 获取\n const cached = getStorage<MenuData[]>(MENU_CACHE_KEY);\n if (cached) {\n memoryCache = cached;\n return cached;\n }\n\n return null;\n}\n\n/**\n * 设置菜单缓存(同时更新内存和 LocalStorage)\n */\nexport function setMenuCache(menus: MenuData[]): void {\n memoryCache = menus;\n setStorage(MENU_CACHE_KEY, menus);\n}\n\n/**\n * 清除菜单缓存(同时清除内存和 LocalStorage)\n */\nexport function clearMenuCache(): void {\n memoryCache = null;\n delStorage(MENU_CACHE_KEY);\n}\n\n/**\n * 获取内存缓存\n */\nexport function getMemoryMenuCache(): MenuData[] | null {\n return memoryCache;\n}\n\n/**\n * 设置内存缓存\n */\nexport function setMemoryMenuCache(menus: MenuData[]): void {\n memoryCache = menus;\n}\n","import type {MenuData} from './converter';\nimport {getMenuCache, setMenuCache, clearMenuCache} from './cache';\nimport {httpRequest} from 'yh-client';\n\nexport async function getMenus(isPad: boolean = false): Promise<MenuData[]> {\n const cached = getMenuCache();\n if (cached) {\n return cached;\n }\n\n const res = await httpRequest.post<any>(\n isPad ? 'loginController/getPdaMenus' : 'loginController/getMenus',\n {}\n );\n const menu = res.data.data;\n setMenuCache(menu);\n return menu;\n}\n\nexport function clearMenu(): void {\n clearMenuCache();\n}\n\nexport function setCustomMenus(menus: MenuData[]): void {\n setMenuCache(menus);\n}\n","import {defineStore} from 'pinia';\nimport {ref} from 'vue';\nimport {default as httpRequest} from '../api/http';\nimport {setToken, setSaToken, clearAllTokens, getToken, getSaToken} from '../auth/token';\nimport type {HttpResponse, UserInfo} from '../types';\nimport {Config} from '../utils';\nimport { clearMenu } from '../menu';\n\n/**\n * 客户端 Store\n */\nexport const useClientStore = defineStore('clientStore', () => {\n getToken();\n getSaToken();\n\n const userId = ref<string>('');\n const userName = ref<string>('');\n const name = ref<string>('');\n const avatar = ref<string>('');\n const isLoggedIn = ref<boolean>(!!Config.token || !!Config.saToken);\n const isAdmin = ref<boolean>(!!Config.saToken);\n\n const login = async (params: {\n username: string;\n password: string;\n }): Promise<HttpResponse<{token: string}>> => {\n const response = await httpRequest.post<{token: string}>(\n 'loginController/login',\n params,\n 'json'\n );\n\n if (response.data?.token) {\n setToken(response.data.token);\n isLoggedIn.value = true;\n isAdmin.value = false;\n }\n\n return response;\n };\n\n /**\n * 获取用户信息\n */\n const getUserInfo = async (): Promise<HttpResponse<UserInfo>> => {\n const response = await httpRequest.post<UserInfo>('loginController/getUserInfo', {}, 'json');\n\n const data = response.data as UserInfo;\n if (data) {\n userId.value = data.userId || '';\n userName.value = data.userName || '';\n name.value = data.name || '';\n avatar.value = '';\n\n if (data.defaultLanguage) {\n Config.set('defaultLanguage', data.defaultLanguage);\n }\n if (data.homePath) {\n Config.set('homePath', data.homePath);\n }\n }\n\n return response;\n };\n\n /**\n * 管理员登录\n */\n const saLogin = async (params: {\n username: string;\n password: string;\n }): Promise<HttpResponse<{token: string}>> => {\n const response = await httpRequest.post<{token: string}>('admin/login', params, 'json');\n\n // 更新 saToken\n if (response.data?.token) {\n setSaToken(response.data.token);\n isLoggedIn.value = true;\n isAdmin.value = true;\n }\n\n return response;\n };\n\n /**\n * 获取管理员用户信息\n */\n const getSaUserInfo = async (): Promise<HttpResponse<any>> => {\n const response = await httpRequest.post<{saUser: any}>('admin/getSaUserInfo', {}, 'json');\n\n const saUser = response.data?.saUser;\n if (saUser) {\n userId.value = saUser.id || '';\n userName.value = saUser.username || '';\n name.value = saUser.name || '';\n avatar.value = '';\n\n if (saUser.language) {\n Config.set('defaultLanguage', saUser.language);\n }\n if (saUser.mainPage) {\n Config.set('homePath', saUser.mainPage);\n }\n }\n\n return response;\n };\n\n /**\n * 登出\n */\n const logout = async (): Promise<void> => {\n // 清除所有 token 和存储\n clearAllTokens();\n clearMenu();\n isLoggedIn.value = false;\n isAdmin.value = false;\n userId.value = '';\n userName.value = '';\n avatar.value = '';\n };\n\n return {\n // 用户信息\n userId,\n userName,\n avatar,\n\n // 计算属性\n isLoggedIn,\n isAdmin,\n\n // 方法\n login,\n logout,\n getUserInfo,\n saLogin,\n getSaUserInfo,\n };\n});\n"],"names":["base64Encode","data","bytes","binString","byte","base64Decode","base64","char","encode","decode","reversed","getStorage","key","objectStr","decrypted","setStorage","value","encrypted","delStorage","clearStorage","ConfigManager","reactive","merged","merge","path","defaultValue","get","lodashSet","newConfig","Config","getConfig","setConfig","mergeConfig","mergeBuiltinConfig","replaceServerConfig","initConfig","generateMd5Hash","input","MD5","generateSimpleHash","hash","i","toHump","name","all","letter","generateId","d","c","r","trigger","eventName","target","event","on","callback","handler","e","once","cleanup","off","deepClone","cloneDeep","isEqual","lodashIsEqual","overwriteObj","assign","HttpRequest","baseUrl","url","token","saToken","config","_a","instance","error","res","status","headers","msg","reg","match","errMsg","response","result","msg400","_b","message","ElMessage","options","requestData","qs","axios","params","type","fileName","serverName","blob","downloadElement","href","ext","defaultInstance","SA_TOKEN","TOKEN_KEY","isValidHeaderValue","initTokens","setToken","getToken","setSaToken","getSaToken","clearTokens","clearAllTokens","toTree","nodes","map","menuMap","item","itemSub","menusToAside","isAdmin","menus","mtoa","menu","newMenu","keepAlive","md5","getRoutes","defaultRouteHandler","items","route","MENU_CACHE_KEY","memoryCache","getMenuCache","cached","setMenuCache","clearMenuCache","getMenus","isPad","httpRequest","clearMenu","useClientStore","defineStore","userId","ref","userName","avatar","isLoggedIn","saUser"],"mappings":"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"}
|