yh-client 2.0.20 → 2.0.21

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 CHANGED
@@ -1,40 +1,69 @@
1
+ import { ElMessage as C } from "element-plus";
1
2
  import T from "axios";
2
3
  import L from "qs";
3
- import { merge as g, get as M, set as U, cloneDeep as j, isEqual as H, assign as q } from "lodash-es";
4
- import { reactive as R, ref as y } from "vue";
5
- import { MD5 as A } from "crypto-js";
6
- import { ElMessage as O } from "element-plus";
7
- import { defineStore as N } from "pinia";
8
- import K from "crypto-js/md5";
9
- import { httpRequest as $ } from "yh-client";
4
+ import { merge as p, get as j, set as H, cloneDeep as R, isEqual as q, assign as A } from "lodash-es";
5
+ import { reactive as D, ref as y } from "vue";
6
+ import { MD5 as N } from "crypto-js";
7
+ import { defineStore as K } from "pinia";
8
+ import $ from "crypto-js/md5";
9
+ import { httpRequest as _ } from "yh-client";
10
+ const O = "__yhMessageDedupe", P = 1e3;
10
11
  function B(s) {
12
+ return typeof s == "string" ? s : s && typeof s == "object" && typeof s.message == "string" ? s.message : null;
13
+ }
14
+ function J(s = C, e = {}) {
15
+ const n = s, o = n[O];
16
+ if (o) {
17
+ o.windowMs = e.windowMs ?? P;
18
+ return;
19
+ }
20
+ if (typeof n.error != "function") return;
21
+ const t = {
22
+ windowMs: e.windowMs ?? P,
23
+ seen: /* @__PURE__ */ new Map(),
24
+ original: n.error.bind(n)
25
+ };
26
+ n.error = (...r) => {
27
+ const c = B(r[0]);
28
+ if (c !== null) {
29
+ const l = Date.now(), h = t.seen.get(c);
30
+ if (h !== void 0 && l - h < t.windowMs)
31
+ return;
32
+ if (t.seen.set(c, l), t.seen.size > 100)
33
+ for (const [d, g] of t.seen)
34
+ l - g >= t.windowMs && t.seen.delete(d);
35
+ }
36
+ return t.original(...r);
37
+ }, n[O] = t;
38
+ }
39
+ function F(s) {
11
40
  const e = new TextEncoder().encode(s), n = Array.from(e, (o) => String.fromCharCode(o)).join("");
12
41
  return btoa(n);
13
42
  }
14
- function D(s) {
43
+ function G(s) {
15
44
  const e = atob(s), n = Uint8Array.from(e, (o) => o.charCodeAt(0));
16
45
  return new TextDecoder().decode(n);
17
46
  }
18
- function J(s) {
47
+ function W(s) {
19
48
  try {
20
- return B(s).split("").reverse().join("");
49
+ return F(s).split("").reverse().join("");
21
50
  } catch {
22
51
  return s;
23
52
  }
24
53
  }
25
- function _(s) {
54
+ function V(s) {
26
55
  try {
27
56
  let e = s.split("").reverse().join("");
28
- return D(e);
57
+ return G(e);
29
58
  } catch {
30
59
  return s;
31
60
  }
32
61
  }
33
- const m = (s) => {
62
+ const k = (s) => {
34
63
  const e = localStorage.getItem(s);
35
64
  if (e !== null)
36
65
  try {
37
- const n = _(e);
66
+ const n = V(e);
38
67
  try {
39
68
  return JSON.parse(n);
40
69
  } catch {
@@ -52,25 +81,25 @@ const m = (s) => {
52
81
  let n;
53
82
  typeof e == "object" ? n = JSON.stringify(e) : n = String(e);
54
83
  try {
55
- const o = J(String(n));
84
+ const o = W(String(n));
56
85
  localStorage.setItem(s, o);
57
86
  } catch {
58
87
  localStorage.setItem(s, String(n));
59
88
  }
60
- }, C = (s) => {
89
+ }, E = (s) => {
61
90
  localStorage.removeItem(s);
62
- }, G = () => {
91
+ }, Y = () => {
63
92
  localStorage.clear(), sessionStorage.clear();
64
93
  };
65
- class F {
94
+ class z {
66
95
  constructor() {
67
- this.builtinLayer = {}, this.hostLayer = {}, this.codeLayer = {}, this.serverLayer = {}, this.snapshot = R({});
96
+ this.builtinLayer = {}, this.hostLayer = {}, this.codeLayer = {}, this.serverLayer = {}, this.snapshot = D({});
68
97
  }
69
98
  /**
70
99
  * 重算合并视图:保持同一 reactive 代理对象,属性级依赖追踪不失效
71
100
  */
72
101
  rebuild() {
73
- const e = g({}, this.builtinLayer, this.hostLayer, this.codeLayer, this.serverLayer);
102
+ const e = p({}, this.builtinLayer, this.hostLayer, this.codeLayer, this.serverLayer);
74
103
  for (const n of Object.keys(this.snapshot))
75
104
  delete this.snapshot[n];
76
105
  Object.assign(this.snapshot, e);
@@ -79,25 +108,25 @@ class F {
79
108
  * 获取配置值(从生效视图读取,无 path 时返回整个视图对象)
80
109
  */
81
110
  get(e, n) {
82
- return e ? M(this.snapshot, e, n) : this.snapshot;
111
+ return e ? j(this.snapshot, e, n) : this.snapshot;
83
112
  }
84
113
  /**
85
114
  * 设置配置值(写入代码层)
86
115
  */
87
116
  set(e, n) {
88
- U(this.codeLayer, e, n), this.rebuild();
117
+ H(this.codeLayer, e, n), this.rebuild();
89
118
  }
90
119
  /**
91
120
  * 合并宿主配置
92
121
  */
93
122
  merge(e) {
94
- g(this.hostLayer, e), this.rebuild();
123
+ p(this.hostLayer, e), this.rebuild();
95
124
  }
96
125
  /**
97
126
  * 合并包内内置默认(优先级最低,不会覆盖宿主/代码设置)
98
127
  */
99
128
  mergeBuiltin(e) {
100
- g(this.builtinLayer, e), this.rebuild();
129
+ p(this.builtinLayer, e), this.rebuild();
101
130
  }
102
131
  /**
103
132
  * 整层替换服务端参数(禁用/删除的参数随替换回落到低层值)
@@ -139,29 +168,29 @@ class F {
139
168
  this.set("storageKey", e);
140
169
  }
141
170
  }
142
- const a = new F();
143
- function pe(s, e) {
171
+ const a = new z();
172
+ function ke(s, e) {
144
173
  return a.get(s, e);
145
174
  }
146
- function ye(s, e) {
175
+ function me(s, e) {
147
176
  a.set(s, e);
148
177
  }
149
- function Te(s) {
178
+ function xe(s) {
150
179
  a.merge(s);
151
180
  }
152
- function we(s) {
181
+ function ve(s) {
153
182
  a.mergeBuiltin(s);
154
183
  }
155
- function me(s) {
184
+ function be(s) {
156
185
  a.replaceServer(s);
157
186
  }
158
- function ke(s) {
187
+ function Le(s) {
159
188
  a.init(s);
160
189
  }
161
- async function ve(s) {
162
- return A(s).toString();
190
+ async function Ce(s) {
191
+ return N(s).toString();
163
192
  }
164
- function xe(s) {
193
+ function Ee(s) {
165
194
  let e = 0;
166
195
  for (let n = 0; n < s.length; n++) {
167
196
  const o = s.charCodeAt(n);
@@ -169,25 +198,25 @@ function xe(s) {
169
198
  }
170
199
  return Math.abs(e).toString(36);
171
200
  }
172
- const be = (s) => s.replace(/\_(\w)/g, function(e, n) {
201
+ const Ie = (s) => s.replace(/\_(\w)/g, function(e, n) {
173
202
  return n.toUpperCase();
174
- }), Le = () => {
203
+ }), Me = () => {
175
204
  const s = (/* @__PURE__ */ new Date()).getTime();
176
205
  return "xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx".replace(/[xy]/g, function(n) {
177
206
  const o = (s + Math.random() * 16) % 16 | 0;
178
207
  return (n === "x" ? o : o & 3 | 8).toString(16);
179
208
  }).toUpperCase();
180
209
  };
181
- function k(s, e, n = window) {
210
+ function m(s, e, n = window) {
182
211
  const o = new CustomEvent(s, { detail: e });
183
212
  n.dispatchEvent(o);
184
213
  }
185
- function V(s, e, n = window) {
214
+ function Q(s, e, n = window) {
186
215
  const o = (t) => e(t.detail);
187
216
  return n.addEventListener(s, o), () => n.removeEventListener(s, o);
188
217
  }
189
- function Ce(s, e, n = window) {
190
- const o = V(
218
+ function Se(s, e, n = window) {
219
+ const o = Q(
191
220
  s,
192
221
  (t) => {
193
222
  e(t), o();
@@ -196,12 +225,12 @@ function Ce(s, e, n = window) {
196
225
  );
197
226
  return o;
198
227
  }
199
- function Ie(s, e, n = window) {
228
+ function Oe(s, e, n = window) {
200
229
  const o = (t) => e(t.detail);
201
230
  n.removeEventListener(s, o);
202
231
  }
203
- const Ee = j, Se = H, Oe = q;
204
- class W {
232
+ const Pe = R, Ue = q, je = A;
233
+ class X {
205
234
  constructor(e = "") {
206
235
  this.timeout = 12e4, this.baseUrl = e, this.queue = {};
207
236
  }
@@ -247,15 +276,15 @@ class W {
247
276
  (t) => (console.error("[HTTP] 请求错误:", t), Promise.reject(t))
248
277
  ), e.interceptors.response.use(
249
278
  (t) => {
250
- const { data: r, status: c, headers: h } = t;
251
- if (this.destroy(n), k("yh:http:status", c), r.result || r.result === void 0)
252
- return { data: r, status: c, headers: h };
279
+ const { data: r, status: c, headers: l } = t;
280
+ if (this.destroy(n), m("yh:http:status", c), r.result || r.result === void 0)
281
+ return { data: r, status: c, headers: l };
253
282
  {
254
- const { msg: f } = r;
255
- return this.handleError(f, n, o), { data: r, status: c, headers: h };
283
+ const { msg: h } = r;
284
+ return this.handleError(h, n, o), { data: r, status: c, headers: l };
256
285
  }
257
286
  },
258
- (t) => (this.destroy(n), t.response ? (k("yh:http:status", t.response.status), this.handleHttpError(t, n, o)) : (k("yh:http:status", 0), console.error("[HTTP] 未处理的网络错误", t), o || this.showMessage("请联系管理员,并查看控制台日志"), Promise.reject(t)))
287
+ (t) => (this.destroy(n), t.response ? (m("yh:http:status", t.response.status), this.handleHttpError(t, n, o)) : (m("yh:http:status", 0), console.error("[HTTP] 未处理的网络错误", t), o || this.showMessage("请联系管理员,并查看控制台日志"), Promise.reject(t)))
259
288
  );
260
289
  }
261
290
  /**
@@ -287,7 +316,7 @@ class W {
287
316
  * 处理 HTTP 错误
288
317
  */
289
318
  handleHttpError(e, n, o) {
290
- var c, h, f;
319
+ var c, l, h;
291
320
  const { response: t } = e;
292
321
  if (!t)
293
322
  return Promise.reject(e);
@@ -305,11 +334,11 @@ class W {
305
334
  break;
306
335
  case 400:
307
336
  console.error("[HTTP] HTTP 400", t);
308
- const d = (h = t.data) == null ? void 0 : h.msg;
337
+ const d = (l = t.data) == null ? void 0 : l.msg;
309
338
  d && !o && this.showMessage(d);
310
339
  break;
311
340
  case 404:
312
- console.error("[HTTP] HTTP 404", t), o || this.showMessage(`${(f = e.config) == null ? void 0 : f.url},资源不存在,请联系管理员`);
341
+ console.error("[HTTP] HTTP 404", t), o || this.showMessage(`${(h = e.config) == null ? void 0 : h.url},资源不存在,请联系管理员`);
313
342
  break;
314
343
  case 500:
315
344
  console.error("[HTTP] HTTP 500", t), o || this.showMessage("服务器错误,请联系管理员");
@@ -330,14 +359,14 @@ class W {
330
359
  * 登录失效跳转:优先宿主钩子,否则触发 to:login 事件
331
360
  */
332
361
  redirectLogin() {
333
- this.onLoginRedirect ? this.onLoginRedirect() : k("to:login");
362
+ this.onLoginRedirect ? this.onLoginRedirect() : m("to:login");
334
363
  }
335
364
  /**
336
365
  * 显示消息(需要 Element Plus)
337
366
  */
338
367
  showMessage(e) {
339
368
  try {
340
- O ? O.error(e) : console.error("[HTTP]", e);
369
+ C ? C.error(e) : console.error("[HTTP]", e);
341
370
  } catch {
342
371
  console.error("[HTTP]", e);
343
372
  }
@@ -348,7 +377,7 @@ class W {
348
377
  request(e) {
349
378
  let n = e.data;
350
379
  e.type !== "json" && n && typeof n == "object" && (n = L.stringify(n)), e.type === "json" && (e.headers || (e.headers = {}), e.headers["Content-Type"] = "application/json");
351
- const o = T.create(), t = g(this.getInsideConfig(), {
380
+ const o = T.create(), t = p(this.getInsideConfig(), {
352
381
  url: e.url,
353
382
  method: e.method || "GET",
354
383
  data: n,
@@ -375,7 +404,7 @@ class W {
375
404
  * POST JSON 请求
376
405
  */
377
406
  postJson(e, n) {
378
- const o = T.create(), t = g(this.getInsideConfig(), {
407
+ const o = T.create(), t = p(this.getInsideConfig(), {
379
408
  url: e,
380
409
  method: "POST",
381
410
  data: n,
@@ -389,7 +418,7 @@ class W {
389
418
  * 上传文件
390
419
  */
391
420
  upload(e, n) {
392
- const o = T.create(), t = g(this.getInsideConfig(), {
421
+ const o = T.create(), t = p(this.getInsideConfig(), {
393
422
  url: e,
394
423
  method: "POST",
395
424
  data: n,
@@ -403,7 +432,7 @@ class W {
403
432
  * 下载文件(POST)
404
433
  */
405
434
  download(e, n, o) {
406
- const t = T.create(), r = g(this.getInsideConfig(), {
435
+ const t = T.create(), r = p(this.getInsideConfig(), {
407
436
  url: e,
408
437
  method: "POST",
409
438
  responseType: "blob",
@@ -415,10 +444,10 @@ class W {
415
444
  this.showMessage("导出文件异常: " + c.data.msg);
416
445
  return;
417
446
  }
418
- const h = (c.headers["content-disposition"] || `filename=文件-${Date.now()}`).split("filename=")[1], f = new Blob([c.data]), d = document.createElement("a"), p = window.URL.createObjectURL(f);
419
- d.href = p, d.download = decodeURIComponent(this.resolveFileName(h, o)), document.body.appendChild(d), d.click(), document.body.removeChild(d), window.URL.revokeObjectURL(p);
420
- const { data: u, status: i, headers: l } = c;
421
- return { data: u, status: i, headers: l };
447
+ const l = (c.headers["content-disposition"] || `filename=文件-${Date.now()}`).split("filename=")[1], h = new Blob([c.data]), d = document.createElement("a"), g = window.URL.createObjectURL(h);
448
+ d.href = g, d.download = decodeURIComponent(this.resolveFileName(l, o)), document.body.appendChild(d), d.click(), document.body.removeChild(d), window.URL.revokeObjectURL(g);
449
+ const { data: u, status: i, headers: f } = c;
450
+ return { data: u, status: i, headers: f };
422
451
  }
423
452
  ), t(r);
424
453
  }
@@ -426,7 +455,7 @@ class W {
426
455
  * 导出文件(GET)
427
456
  */
428
457
  export(e, n, o) {
429
- const t = T.create(), r = g(this.getInsideConfig(), {
458
+ const t = T.create(), r = p(this.getInsideConfig(), {
430
459
  url: e,
431
460
  method: "GET",
432
461
  responseType: "blob",
@@ -434,10 +463,10 @@ class W {
434
463
  });
435
464
  return this.interceptors(t, e), t.interceptors.response.use(
436
465
  (c) => {
437
- const h = (c.headers["content-disposition"] || `filename=文件-${Date.now()}`).split("filename=")[1], f = new Blob([c.data]), d = document.createElement("a"), p = window.URL.createObjectURL(f);
438
- d.href = p, d.download = decodeURIComponent(this.resolveFileName(h, o)), document.body.appendChild(d), d.click(), document.body.removeChild(d), window.URL.revokeObjectURL(p);
439
- const { data: u, status: i, headers: l } = c;
440
- return { data: u, status: i, headers: l };
466
+ const l = (c.headers["content-disposition"] || `filename=文件-${Date.now()}`).split("filename=")[1], h = new Blob([c.data]), d = document.createElement("a"), g = window.URL.createObjectURL(h);
467
+ d.href = g, d.download = decodeURIComponent(this.resolveFileName(l, o)), document.body.appendChild(d), d.click(), document.body.removeChild(d), window.URL.revokeObjectURL(g);
468
+ const { data: u, status: i, headers: f } = c;
469
+ return { data: u, status: i, headers: f };
441
470
  }
442
471
  ), t(r);
443
472
  }
@@ -454,41 +483,41 @@ class W {
454
483
  return n;
455
484
  }
456
485
  }
457
- const v = new W(), x = "SATOKEN", b = "login-token";
458
- function P(s) {
486
+ const x = new X(), v = "SATOKEN", b = "login-token";
487
+ function U(s) {
459
488
  return /^[\x20-\x7E]*$/.test(s);
460
489
  }
461
- function Pe() {
462
- const s = m(b);
463
- s && P(s) ? a.token = s : (a.token = "", C(b));
464
- const e = m(x);
465
- e && P(e) ? a.saToken = e : (a.saToken = "", C(x));
490
+ function He() {
491
+ const s = k(b);
492
+ s && U(s) ? a.token = s : (a.token = "", E(b));
493
+ const e = k(v);
494
+ e && U(e) ? a.saToken = e : (a.saToken = "", E(v));
466
495
  }
467
- function Y(s) {
496
+ function Z(s) {
468
497
  I(b, s), a.token = s;
469
498
  }
470
- function z() {
499
+ function ee() {
471
500
  if (a.token !== void 0)
472
501
  return a.token;
473
- const s = m(b);
502
+ const s = k(b);
474
503
  return a.token = s || "", a.token;
475
504
  }
476
- function Q(s) {
477
- I(x, s), a.saToken = s;
505
+ function te(s) {
506
+ I(v, s), a.saToken = s;
478
507
  }
479
- function X() {
508
+ function ne() {
480
509
  if (a.saToken !== void 0)
481
510
  return a.saToken;
482
- const s = m(x);
511
+ const s = k(v);
483
512
  return a.saToken = s || "", a.saToken;
484
513
  }
485
- function Z() {
486
- a.token = "", a.saToken = "", G();
514
+ function se() {
515
+ a.token = "", a.saToken = "", Y();
487
516
  }
488
- function ee() {
489
- Z();
517
+ function oe() {
518
+ se();
490
519
  }
491
- function te(s) {
520
+ function re(s) {
492
521
  const e = [], n = {}, o = {};
493
522
  return s = JSON.parse(JSON.stringify(s)), s.forEach(function(t) {
494
523
  t.parentId && t.parentId !== "0" && (o[t.parentId] || (o[t.parentId] = []), o[t.parentId].push(t)), t.children && t.children.length > 0 && t.children.forEach((r) => {
@@ -500,8 +529,8 @@ function te(s) {
500
529
  });
501
530
  }), e;
502
531
  }
503
- function Me(s, e = !1) {
504
- const n = te(s);
532
+ function Re(s, e = !1) {
533
+ const n = re(s);
505
534
  function o(t) {
506
535
  if (["SUBPAGE", "JOIN", "APP"].includes(t.menuType || ""))
507
536
  return !1;
@@ -511,21 +540,21 @@ function Me(s, e = !1) {
511
540
  id: t.id,
512
541
  sysModuleId: t.sysModuleId
513
542
  };
514
- if (t.url && ["WINDOW", "LINK"].includes(t.menuType || ""))
543
+ if (t.url && ["WINDOW", "LINK", "REPORT"].includes(t.menuType || ""))
515
544
  if (e && t.url.indexOf("sys/index") > -1)
516
545
  r.id = `/admin/sys/window/${t.windowId || t.id}`;
517
546
  else if (t.url.indexOf("sys/index") > -1)
518
547
  r.id = `/sys/window/${t.windowId || t.id}`;
519
548
  else if (t.url.indexOf("http") > -1) {
520
549
  const c = "";
521
- r.id = `/iframe/${K(t.url)}?url=${encodeURIComponent(t.url)}&_keepAlive=${c}`;
550
+ r.id = `/iframe/${$(t.url)}?url=${encodeURIComponent(t.url)}&_keepAlive=${c}`;
522
551
  } else
523
552
  t.url.indexOf("/") !== 0 && (t.url = `/${t.url}`), r.id = t.url;
524
553
  return t.children && (r.hasChildren = !0, r.children = t.children.map(o).filter((c) => !!c)), r;
525
554
  }
526
555
  return n.map(o).filter((t) => !!t);
527
556
  }
528
- function Ue(s, e) {
557
+ function qe(s, e) {
529
558
  const n = [];
530
559
  for (const o of s) {
531
560
  if (!o.url)
@@ -535,35 +564,35 @@ function Ue(s, e) {
535
564
  }
536
565
  return n;
537
566
  }
538
- const E = "yh-menu-cache";
567
+ const M = "yh-menu-cache";
539
568
  let w = null;
540
- function ne() {
569
+ function ie() {
541
570
  if (w)
542
571
  return w;
543
- const s = m(E);
572
+ const s = k(M);
544
573
  return s ? (w = s, s) : null;
545
574
  }
546
- function se(s) {
547
- w = s, I(E, s);
575
+ function ae(s) {
576
+ w = s, I(M, s);
548
577
  }
549
- function oe() {
550
- w = null, C(E);
578
+ function ce() {
579
+ w = null, E(M);
551
580
  }
552
- async function je(s = !1) {
553
- const e = ne();
581
+ async function Ae(s = !1) {
582
+ const e = ie();
554
583
  if (e)
555
584
  return e;
556
- const o = (await $.post(
585
+ const o = (await _.post(
557
586
  s ? "loginController/getPdaMenus" : "loginController/getMenus",
558
587
  {}
559
588
  )).data.data;
560
- return se(o), o;
589
+ return ae(o), o;
561
590
  }
562
- function re() {
563
- oe();
591
+ function de() {
592
+ ce();
564
593
  }
565
- const He = N("clientStore", () => {
566
- z(), X();
594
+ const De = K("clientStore", () => {
595
+ ee(), ne();
567
596
  const s = y(""), e = y(""), n = y(""), o = y(""), t = y(!!a.token || !!a.saToken), r = y(!!a.saToken);
568
597
  return {
569
598
  // 用户信息
@@ -575,76 +604,78 @@ const He = N("clientStore", () => {
575
604
  isAdmin: r,
576
605
  // 方法
577
606
  login: async (u) => {
578
- var l;
579
- const i = await v.post(
607
+ var f;
608
+ const i = await x.post(
580
609
  "loginController/login",
581
610
  u,
582
611
  "json"
583
612
  );
584
- return (l = i.data) != null && l.token && (Y(i.data.token), t.value = !0, r.value = !1), i;
613
+ return (f = i.data) != null && f.token && (Z(i.data.token), t.value = !0, r.value = !1), i;
585
614
  },
586
615
  logout: async () => {
587
- ee(), re(), t.value = !1, r.value = !1, s.value = "", e.value = "", o.value = "";
616
+ oe(), de(), t.value = !1, r.value = !1, s.value = "", e.value = "", o.value = "";
588
617
  },
589
618
  getUserInfo: async () => {
590
- const u = await v.post("loginController/getUserInfo", {}, "json"), i = u.data;
619
+ const u = await x.post("loginController/getUserInfo", {}, "json"), i = u.data;
591
620
  if ((i == null ? void 0 : i.result) === !1)
592
621
  throw new Error(i.msg || "获取用户信息失败");
593
622
  return i && (s.value = i.userId || "", e.value = i.userName || "", n.value = i.name || "", o.value = "", i.defaultLanguage && a.set("defaultLanguage", i.defaultLanguage), i.homePath && a.set("homePath", i.homePath)), u;
594
623
  },
595
624
  saLogin: async (u) => {
596
- var l;
597
- const i = await v.post("admin/login", u, "json");
598
- return (l = i.data) != null && l.token && (Q(i.data.token), t.value = !0, r.value = !0), i;
625
+ var f;
626
+ const i = await x.post("admin/login", u, "json");
627
+ return (f = i.data) != null && f.token && (te(i.data.token), t.value = !0, r.value = !0), i;
599
628
  },
600
629
  getSaUserInfo: async () => {
601
- var l, S;
602
- const u = await v.post("admin/getSaUserInfo", {}, "json");
603
- if (((l = u.data) == null ? void 0 : l.result) === !1)
630
+ var f, S;
631
+ const u = await x.post("admin/getSaUserInfo", {}, "json");
632
+ if (((f = u.data) == null ? void 0 : f.result) === !1)
604
633
  throw new Error(u.data.msg || "获取管理员信息失败");
605
634
  const i = (S = u.data) == null ? void 0 : S.saUser;
606
635
  return i && (s.value = i.id || "", e.value = i.username || "", n.value = i.name || "", o.value = "", i.language && a.set("defaultLanguage", i.language), i.mainPage && a.set("homePath", i.mainPage)), u;
607
636
  }
608
637
  };
609
638
  });
639
+ J();
610
640
  export {
611
641
  a as Config,
612
- W as HttpRequest,
613
- x as SA_TOKEN,
642
+ X as HttpRequest,
643
+ v as SA_TOKEN,
614
644
  b as TOKEN_KEY,
615
- ee as clearAllTokens,
616
- re as clearMenu,
617
- G as clearStorage,
618
- Z as clearTokens,
619
- Ee as deepClone,
620
- C as delStorage,
621
- Le as generateId,
622
- ve as generateMd5Hash,
623
- xe as generateSimpleHash,
624
- pe as getConfig,
625
- je as getMenus,
626
- Ue as getRoutes,
627
- X as getSaToken,
628
- m as getStorage,
629
- z as getToken,
630
- v as httpRequest,
631
- ke as initConfig,
632
- Pe as initTokens,
633
- Se as isEqual,
634
- Me as menusToAside,
635
- we as mergeBuiltinConfig,
636
- Te as mergeConfig,
637
- Ie as off,
638
- V as on,
639
- Ce as once,
640
- Oe as overwriteObj,
641
- me as replaceServerConfig,
642
- ye as setConfig,
643
- Q as setSaToken,
645
+ oe as clearAllTokens,
646
+ de as clearMenu,
647
+ Y as clearStorage,
648
+ se as clearTokens,
649
+ Pe as deepClone,
650
+ E as delStorage,
651
+ Me as generateId,
652
+ Ce as generateMd5Hash,
653
+ Ee as generateSimpleHash,
654
+ ke as getConfig,
655
+ Ae as getMenus,
656
+ qe as getRoutes,
657
+ ne as getSaToken,
658
+ k as getStorage,
659
+ ee as getToken,
660
+ x as httpRequest,
661
+ Le as initConfig,
662
+ He as initTokens,
663
+ J as installMessageDedupe,
664
+ Ue as isEqual,
665
+ Re as menusToAside,
666
+ ve as mergeBuiltinConfig,
667
+ xe as mergeConfig,
668
+ Oe as off,
669
+ Q as on,
670
+ Se as once,
671
+ je as overwriteObj,
672
+ be as replaceServerConfig,
673
+ me as setConfig,
674
+ te as setSaToken,
644
675
  I as setStorage,
645
- Y as setToken,
646
- be as toHump,
647
- k as trigger,
648
- He as useClientStore
676
+ Z as setToken,
677
+ Ie as toHump,
678
+ m as trigger,
679
+ De as useClientStore
649
680
  };
650
681
  //# 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';\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, silentError?: boolean): 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 // 完成响应广播(含 4xx——能回响应即链路可达):宿主应用的健康探测订阅它,\n // 用真实业务流量替代常驻轮询探针,避免健康检查在控制台刷 401 噪音\n trigger('yh:http:status', status);\n if (data.result || data.result === void 0) {\n return {data, status, headers};\n } else {\n const {msg} = data;\n this.handleError(msg, url, silentError);\n return {data, status, headers};\n }\n },\n (error: AxiosError): any => {\n this.destroy(url);\n // 错误处理\n if (error.response) {\n trigger('yh:http:status', error.response.status);\n return this.handleHttpError(error, url, silentError);\n } else {\n trigger('yh:http:status', 0); // 网络层失败(无响应)\n console.error('[HTTP] 未处理的网络错误', error);\n // 静默模式:网络错误不弹提示,拒绝后由调用方处理\n if (!silentError) {\n this.showMessage('请联系管理员,并查看控制台日志');\n }\n return Promise.reject(error);\n }\n }\n );\n }\n\n /**\n * 处理业务错误\n */\n private handleError(msg: string | undefined, url: string, silentError?: boolean): 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 (this.isLoginTimeout(msg)) {\n if (!silentError) {\n this.showMessage('登录状态已超时');\n }\n this.redirectLogin();\n return;\n }\n\n // 静默模式:业务错误不弹提示,调用方(如 AI 工具链)从响应体取 msg 自行处理\n if (silentError) {\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, silentError?: boolean): 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 // 后端将登录超时包装为非 401 状态返回(如 HTTP 500 + body status:500)时,等同 401 登录失效处理\n const msg = (response.data as any)?.msg;\n if (typeof msg === 'string' && this.isLoginTimeout(msg)) {\n this.redirectLogin();\n return response as HttpResponse;\n }\n\n switch (response.status) {\n case 401:\n this.redirectLogin();\n break;\n case 400:\n console.error('[HTTP] HTTP 400', response);\n const msg400 = (response.data as any)?.msg;\n if (msg400 && !silentError) this.showMessage(msg400);\n break;\n case 404:\n console.error('[HTTP] HTTP 404', response);\n if (!silentError) this.showMessage(`${error.config?.url},资源不存在,请联系管理员`);\n break;\n case 500:\n console.error('[HTTP] HTTP 500', response);\n if (!silentError) this.showMessage('服务器错误,请联系管理员');\n break;\n default:\n console.error('[HTTP] Error', response);\n if (!silentError) this.showMessage('请求遇到问题,请联系管理员协助');\n break;\n }\n\n return response as HttpResponse;\n }\n\n /**\n * 判断是否登录超时消息\n */\n private isLoginTimeout(msg: string): boolean {\n return msg.indexOf('Login Timeout') > -1 || msg.indexOf('Timeout') > -1 || msg.indexOf('登录超时!') > -1;\n }\n\n /**\n * 登录失效跳转:优先宿主钩子,否则触发 to:login 事件\n */\n private redirectLogin(): void {\n if (this.onLoginRedirect) {\n this.onLoginRedirect();\n } else {\n trigger('to:login');\n }\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, options.silentError);\n return instance(config) as Promise<HttpResponse<T>>;\n }\n\n /**\n * GET 请求\n */\n get<T = any>(\n url: string,\n params?: Record<string, any>,\n options?: {silentError?: boolean}\n ): Promise<HttpResponse<T>> {\n return this.request<T>({url, method: 'GET', params, ...options});\n }\n\n /**\n * POST 请求\n */\n post<T = any>(\n url: string,\n data?: any,\n type?: 'json' | 'form',\n options?: {silentError?: boolean}\n ): Promise<HttpResponse<T>> {\n return this.request<T>({url, method: 'POST', data, type: type || 'form', ...options});\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)}&_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 /** 密码加密密钥标识(信创国密 SM2 加密传输时随行) */\n keyId?: 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 // 登录失效等业务失败(Message 包装 result:false):抛错交由 init 任务统一清凭证并跳登录\n if ((data as any)?.result === false) {\n throw new Error((data as any).msg || '获取用户信息失败');\n }\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 /** 密码加密密钥标识(信创国密 SM2 加密传输时随行) */\n keyId?: 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 if ((response.data as any)?.result === false) {\n throw new Error((response.data as any).msg || '获取管理员信息失败');\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","silentError","error","res","status","headers","msg","reg","match","errMsg","response","result","msg400","_b","_c","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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"}
1
+ {"version":3,"file":"index.es.js","sources":["../utils/message.ts","../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","../index.ts"],"sourcesContent":["import {ElMessage} from 'element-plus';\n\n/**\n * 可去重包装的消息 API 形状\n */\nexport interface MessageLike {\n error: (message: any) => any;\n}\n\nexport interface MessageDedupeOptions {\n /** 同文案去重时间窗口(毫秒),默认 1000 */\n windowMs?: number;\n}\n\ninterface DedupeState {\n windowMs: number;\n seen: Map<string, number>;\n original: MessageLike['error'];\n}\n\n// 已包装标记(挂在消息 API 上,保证重复安装幂等)\nconst DEDUPE_FLAG = '__yhMessageDedupe';\n\nconst DEFAULT_WINDOW_MS = 1000;\n\n/**\n * 从消息参数中提取去重文案:\n * 字符串直接用;{message: string} 取 message;其余(VNode 等)不参与去重\n */\nfunction extractText(message: any): string | null {\n if (typeof message === 'string') return message;\n if (message && typeof message === 'object' && typeof message.message === 'string') {\n return message.message;\n }\n return null;\n}\n\n/**\n * 包装消息 API 的 error 方法:同文案在时间窗口内只提示一次。\n *\n * 背景:请求层(httpRequest)对业务/HTTP 错误已弹一次提示,宿主页面拿到响应后\n * 常在 then/catch 里对同一文案再弹一次。请求层无法预知调用方是否处理,\n * 在消息出口统一去重可让调用方零改动消除重复提示,谁先弹谁生效。\n *\n * @param api 消息 API,默认 element-plus 的 ElMessage\n * @example installMessageDedupe(ElMessage, {windowMs: 1500})\n */\nexport function installMessageDedupe(\n api: MessageLike = ElMessage as unknown as MessageLike,\n options: MessageDedupeOptions = {}\n): void {\n const target = api as MessageLike & Record<string, any>;\n\n // 已包装过:仅更新窗口\n const existing: DedupeState | undefined = target[DEDUPE_FLAG];\n if (existing) {\n existing.windowMs = options.windowMs ?? DEFAULT_WINDOW_MS;\n return;\n }\n\n if (typeof target.error !== 'function') return;\n\n const state: DedupeState = {\n windowMs: options.windowMs ?? DEFAULT_WINDOW_MS,\n seen: new Map(),\n original: target.error.bind(target),\n };\n\n target.error = (...args: any[]) => {\n const text = extractText(args[0]);\n if (text !== null) {\n const now = Date.now();\n const last = state.seen.get(text);\n if (last !== undefined && now - last < state.windowMs) {\n return undefined;\n }\n state.seen.set(text, now);\n // 防止记录长期驻留\n if (state.seen.size > 100) {\n for (const [key, time] of state.seen) {\n if (now - time >= state.windowMs) state.seen.delete(key);\n }\n }\n }\n return (state.original as (...a: any[]) => any)(...args);\n };\n\n target[DEDUPE_FLAG] = state;\n}\n","/**\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, silentError?: boolean): 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 // 完成响应广播(含 4xx——能回响应即链路可达):宿主应用的健康探测订阅它,\n // 用真实业务流量替代常驻轮询探针,避免健康检查在控制台刷 401 噪音\n trigger('yh:http:status', status);\n if (data.result || data.result === void 0) {\n return {data, status, headers};\n } else {\n const {msg} = data;\n this.handleError(msg, url, silentError);\n return {data, status, headers};\n }\n },\n (error: AxiosError): any => {\n this.destroy(url);\n // 错误处理\n if (error.response) {\n trigger('yh:http:status', error.response.status);\n return this.handleHttpError(error, url, silentError);\n } else {\n trigger('yh:http:status', 0); // 网络层失败(无响应)\n console.error('[HTTP] 未处理的网络错误', error);\n // 静默模式:网络错误不弹提示,拒绝后由调用方处理\n if (!silentError) {\n this.showMessage('请联系管理员,并查看控制台日志');\n }\n return Promise.reject(error);\n }\n }\n );\n }\n\n /**\n * 处理业务错误\n */\n private handleError(msg: string | undefined, url: string, silentError?: boolean): 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 (this.isLoginTimeout(msg)) {\n if (!silentError) {\n this.showMessage('登录状态已超时');\n }\n this.redirectLogin();\n return;\n }\n\n // 静默模式:业务错误不弹提示,调用方(如 AI 工具链)从响应体取 msg 自行处理\n if (silentError) {\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, silentError?: boolean): 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 // 后端将登录超时包装为非 401 状态返回(如 HTTP 500 + body status:500)时,等同 401 登录失效处理\n const msg = (response.data as any)?.msg;\n if (typeof msg === 'string' && this.isLoginTimeout(msg)) {\n this.redirectLogin();\n return response as HttpResponse;\n }\n\n switch (response.status) {\n case 401:\n this.redirectLogin();\n break;\n case 400:\n console.error('[HTTP] HTTP 400', response);\n const msg400 = (response.data as any)?.msg;\n if (msg400 && !silentError) this.showMessage(msg400);\n break;\n case 404:\n console.error('[HTTP] HTTP 404', response);\n if (!silentError) this.showMessage(`${error.config?.url},资源不存在,请联系管理员`);\n break;\n case 500:\n console.error('[HTTP] HTTP 500', response);\n if (!silentError) this.showMessage('服务器错误,请联系管理员');\n break;\n default:\n console.error('[HTTP] Error', response);\n if (!silentError) this.showMessage('请求遇到问题,请联系管理员协助');\n break;\n }\n\n return response as HttpResponse;\n }\n\n /**\n * 判断是否登录超时消息\n */\n private isLoginTimeout(msg: string): boolean {\n return msg.indexOf('Login Timeout') > -1 || msg.indexOf('Timeout') > -1 || msg.indexOf('登录超时!') > -1;\n }\n\n /**\n * 登录失效跳转:优先宿主钩子,否则触发 to:login 事件\n */\n private redirectLogin(): void {\n if (this.onLoginRedirect) {\n this.onLoginRedirect();\n } else {\n trigger('to:login');\n }\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, options.silentError);\n return instance(config) as Promise<HttpResponse<T>>;\n }\n\n /**\n * GET 请求\n */\n get<T = any>(\n url: string,\n params?: Record<string, any>,\n options?: {silentError?: boolean}\n ): Promise<HttpResponse<T>> {\n return this.request<T>({url, method: 'GET', params, ...options});\n }\n\n /**\n * POST 请求\n */\n post<T = any>(\n url: string,\n data?: any,\n type?: 'json' | 'form',\n options?: {silentError?: boolean}\n ): Promise<HttpResponse<T>> {\n return this.request<T>({url, method: 'POST', data, type: type || 'form', ...options});\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', 'REPORT'].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)}&_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 /** 密码加密密钥标识(信创国密 SM2 加密传输时随行) */\n keyId?: 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 // 登录失效等业务失败(Message 包装 result:false):抛错交由 init 任务统一清凭证并跳登录\n if ((data as any)?.result === false) {\n throw new Error((data as any).msg || '获取用户信息失败');\n }\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 /** 密码加密密钥标识(信创国密 SM2 加密传输时随行) */\n keyId?: 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 if ((response.data as any)?.result === false) {\n throw new Error((response.data as any).msg || '获取管理员信息失败');\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","import {installMessageDedupe} from './utils/message';\n\n// 全局错误提示去重:请求层已提示过的同文案错误,宿主页面再次 ElMessage.error 时不重复弹\ninstallMessageDedupe();\nexport {installMessageDedupe} from './utils/message';\nexport type {MessageLike, MessageDedupeOptions} from './utils/message';\n\nexport {HttpRequest, httpRequest} from './api';\nexport type {RequestOptions, HttpResponse} from './types';\n\nexport {\n SA_TOKEN,\n TOKEN_KEY,\n initTokens,\n setToken,\n getToken,\n setSaToken,\n getSaToken,\n clearTokens,\n clearAllTokens,\n} from './auth';\n\nexport {useClientStore} from './store/client';\n\nexport {\n getStorage,\n setStorage,\n delStorage,\n clearStorage,\n deepClone,\n isEqual,\n overwriteObj,\n Config,\n getConfig,\n setConfig,\n mergeConfig,\n mergeBuiltinConfig,\n replaceServerConfig,\n initConfig,\n generateMd5Hash,\n generateId,\n generateSimpleHash,\n toHump,\n} from './utils';\nexport type {AppConfig} from './utils';\n\nexport {trigger, on, once, off} from './utils/event';\nexport type {EventData, EventCallback} from './utils/event';\n\nexport type {ApiResponse, UserInfo, LoginParams, PaginationParams, PaginationData} from './types';\n\nexport {getRoutes, getMenus, clearMenu, menusToAside} from './menu';\n\nexport type {MenuData, MenuItem, RouteConfig, RouteHandler, RouteHandlerConfig} from './menu';\n"],"names":["DEDUPE_FLAG","DEFAULT_WINDOW_MS","extractText","message","installMessageDedupe","api","ElMessage","options","target","existing","state","args","text","now","last","key","time","base64Encode","data","bytes","binString","byte","base64Decode","base64","char","encode","decode","reversed","getStorage","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","event","on","callback","handler","e","once","cleanup","off","deepClone","cloneDeep","isEqual","lodashIsEqual","overwriteObj","assign","HttpRequest","baseUrl","url","token","saToken","config","_a","instance","silentError","error","res","status","headers","msg","reg","match","errMsg","response","result","msg400","_b","_c","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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "yh-client",
3
- "version": "2.0.20",
3
+ "version": "2.0.21",
4
4
  "description": "元海客户端基础库 - HTTP请求、认证授权、用户管理",
5
5
  "main": "./index.es.js",
6
6
  "exports": {