smart-admin-web 10.12.1 → 10.13.0

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.
Files changed (50) hide show
  1. package/dist/api/index.d.ts +28 -1
  2. package/dist/api/index.js +65 -38
  3. package/dist/api/index.js.map +1 -1
  4. package/dist/api/schema.d.ts +769 -3
  5. package/dist/assets/icons/ph-subset.json.js +1 -1
  6. package/dist/composables/useModule.js +35 -27
  7. package/dist/composables/useModule.js.map +1 -1
  8. package/dist/index.js +250 -249
  9. package/dist/layouts/AppHeader.vue.js +1 -1
  10. package/dist/layouts/AppHeader2.vue.js +306 -292
  11. package/dist/layouts/AppHeader2.vue.js.map +1 -1
  12. package/dist/lib/runtime.js +1 -1
  13. package/dist/locales/en-US.d.ts +49 -1
  14. package/dist/locales/en-US.js +50 -2
  15. package/dist/locales/en-US.js.map +1 -1
  16. package/dist/locales/zh-CN.d.ts +49 -1
  17. package/dist/locales/zh-CN.js +50 -2
  18. package/dist/locales/zh-CN.js.map +1 -1
  19. package/dist/router/index.js +18 -13
  20. package/dist/router/index.js.map +1 -1
  21. package/dist/router/viewRegistry.js +1 -1
  22. package/dist/router/viewRegistry.js.map +1 -1
  23. package/dist/stores/user.d.ts +6 -1
  24. package/dist/stores/user.js.map +1 -1
  25. package/dist/style.css +1 -1
  26. package/dist/types/api.d.ts +59 -0
  27. package/dist/types/api.js.map +1 -1
  28. package/dist/views/dashboard/ShortcutPicker.vue.d.ts +16 -0
  29. package/dist/views/dashboard/ShortcutPicker.vue.js +8 -0
  30. package/dist/views/dashboard/ShortcutPicker.vue.js.map +1 -0
  31. package/dist/views/dashboard/ShortcutPicker2.vue.js +86 -0
  32. package/dist/views/dashboard/ShortcutPicker2.vue.js.map +1 -0
  33. package/dist/views/dashboard/biz.vue.js +2 -2
  34. package/dist/views/dashboard/biz2.vue.js +265 -93
  35. package/dist/views/dashboard/biz2.vue.js.map +1 -1
  36. package/dist/views/dashboard/onlineDuration.d.ts +5 -0
  37. package/dist/views/dashboard/onlineDuration.js +8 -0
  38. package/dist/views/dashboard/onlineDuration.js.map +1 -0
  39. package/dist/views/dashboard/shortcutGroups.d.ts +18 -0
  40. package/dist/views/dashboard/shortcutGroups.js +19 -0
  41. package/dist/views/dashboard/shortcutGroups.js.map +1 -0
  42. package/dist/views/system/tenant/index.vue.d.ts +3 -0
  43. package/dist/views/system/tenant/index.vue.js +8 -0
  44. package/dist/views/system/tenant/index.vue.js.map +1 -0
  45. package/dist/views/system/tenant/index2.vue.js +366 -0
  46. package/dist/views/system/tenant/index2.vue.js.map +1 -0
  47. package/dist/views/system/user/index.vue.js +2 -2
  48. package/dist/views/system/user/index2.vue.js +281 -211
  49. package/dist/views/system/user/index2.vue.js.map +1 -1
  50. package/package.json +1 -1
@@ -1,136 +1,308 @@
1
- import { defineComponent as B, computed as b, ref as T, onMounted as V, openBlock as o, createElementBlock as u, createElementVNode as s, normalizeStyle as $, createVNode as d, unref as e, toDisplayString as a, withCtx as r, Fragment as z, renderList as N, createBlock as p, createTextVNode as _, createCommentVNode as E } from "vue";
2
- import { NCard as g, NButton as w, NEmpty as C, NList as L, NListItem as R } from "naive-ui";
3
- import { Icon as D } from "@iconify/vue";
4
- import { useI18n as M } from "vue-i18n";
5
- import { useRoute as F, useRouter as G } from "vue-router";
6
- import { useUserStore as U } from "../../stores/user.js";
7
- import { useAuthStore as j } from "../../stores/auth.js";
8
- import { useAppStore as H } from "../../stores/app.js";
9
- import { btnGrad as J } from "../../theme/mix.js";
10
- import { noticeApi as K } from "../../api/index.js";
11
- import O from "../../components/AppIcon.vue.js";
12
- import { fmtDateTime as P } from "../../utils/format.js";
13
- const Q = { class: "view" }, W = { class: "banner" }, X = { class: "hi" }, Y = { class: "tip" }, Z = {
1
+ import { defineComponent as W, computed as b, ref as h, onMounted as X, onUnmounted as Y, openBlock as o, createElementBlock as s, createElementVNode as n, normalizeStyle as Z, createVNode as c, unref as t, toDisplayString as l, createCommentVNode as r, createSlots as tt, withCtx as d, Fragment as C, renderList as q, createBlock as y, createTextVNode as R, withModifiers as F } from "vue";
2
+ import { NCard as D, NEmpty as I, NTag as et, NButton as ot, NList as it, NListItem as st } from "naive-ui";
3
+ import { Icon as S } from "@iconify/vue";
4
+ import { useI18n as nt } from "vue-i18n";
5
+ import { useRoute as at, useRouter as lt } from "vue-router";
6
+ import { useUserStore as ut } from "../../stores/user.js";
7
+ import { useAppStore as ct } from "../../stores/app.js";
8
+ import { btnGrad as rt } from "../../theme/mix.js";
9
+ import { personalApi as _, noticeApi as dt } from "../../api/index.js";
10
+ import { useMenuFlat as pt } from "../../composables/useMenuFlat.js";
11
+ import { translateMenuTitle as G } from "../../locales/menuTitle.js";
12
+ import { onlineDurationParts as vt } from "./onlineDuration.js";
13
+ import { buildShortcutGroups as mt } from "./shortcutGroups.js";
14
+ import ht from "./ShortcutPicker.vue.js";
15
+ import j from "../../components/AppIcon.vue.js";
16
+ import { fmtDateTime as E } from "../../utils/format.js";
17
+ import { uaSummary as _t } from "../../utils/ua.js";
18
+ const kt = { class: "view" }, ft = { class: "banner" }, bt = { class: "banner-body" }, yt = { class: "hi" }, gt = { class: "tip" }, wt = {
14
19
  key: 0,
15
- class: "quick"
16
- }, ee = { class: "notice-title" }, te = {
20
+ class: "meta-row"
21
+ }, zt = { key: 0 }, Ct = {
22
+ key: 1,
23
+ class: "meta-dot"
24
+ }, qt = { class: "row" }, St = {
25
+ key: 0,
26
+ class: "todo-list"
27
+ }, $t = ["onClick"], Tt = { class: "todo-main" }, xt = { class: "todo-title" }, Nt = {
28
+ key: 0,
29
+ class: "todo-sub"
30
+ }, Lt = { class: "todo-time" }, Pt = { key: 0 }, Dt = {
31
+ key: 0,
32
+ class: "quick-group-label"
33
+ }, It = {
34
+ key: 1,
35
+ class: "quick-grid"
36
+ }, Et = ["aria-label", "onClick"], Mt = ["onClick"], At = { class: "quick-name" }, Bt = {
37
+ key: 2,
38
+ class: "quick-group-label"
39
+ }, Ut = {
40
+ key: 3,
41
+ class: "quick-grid"
42
+ }, Vt = ["aria-label", "onClick"], Rt = ["onClick"], Ft = { class: "quick-name" }, Gt = { class: "notice-title" }, jt = {
17
43
  key: 0,
18
44
  class: "dot"
19
- }, oe = { class: "notice-time" }, _e = /* @__PURE__ */ B({
45
+ }, Ht = { class: "notice-time" }, re = /* @__PURE__ */ W({
20
46
  __name: "biz",
21
- setup(ie) {
22
- const { t: c } = M(), v = U(), S = j(), x = H(), I = F(), f = G(), q = b(() => ({ background: J(x.accent) }));
23
- function k(m) {
24
- var l;
25
- const i = [];
26
- for (const n of m)
27
- n.visible && ((l = n.children) != null && l.length ? i.push(...k(n.children)) : n.path && i.push(n));
28
- return i;
47
+ setup(Jt) {
48
+ const { t: a } = nt(), M = ut(), H = ct(), A = at(), g = lt(), J = pt(), K = b(() => ({ background: rt(H.accent) })), $ = h(null), m = h(null), B = h(/* @__PURE__ */ new Date());
49
+ let T;
50
+ const w = b(() => {
51
+ if (!$.value) return "";
52
+ const { hours: i, minutes: u } = vt($.value, B.value);
53
+ return i > 0 ? a("biz.onlineDuration", { hours: i, minutes: u }) : a("biz.onlineDurationShort", { minutes: u });
54
+ }), x = b(() => {
55
+ if (!m.value) return a("biz.firstLogin");
56
+ const i = _t(m.value.userAgent), u = m.value.ip ? ` · ${m.value.ip}` : "";
57
+ return `${a("biz.lastLogin", { time: E(m.value.time, { seconds: !1 }) })}${u}${i ? ` · ${i}` : ""}`;
58
+ }), p = h(null), z = h([]), N = h(!1), v = b(
59
+ () => mt(
60
+ z.value.filter((i) => i.menuPath !== A.path),
61
+ J.value
62
+ )
63
+ ), O = b(() => z.value.filter((i) => i.pinned).map((i) => i.menuPath));
64
+ async function L() {
65
+ try {
66
+ z.value = await _.shortcuts();
67
+ } catch {
68
+ z.value = [];
69
+ }
29
70
  }
30
- const y = b(() => k(S.menuTree).filter((m) => m.path !== I.path)), h = T([]);
31
- return V(async () => {
71
+ async function U(i) {
72
+ await _.pinShortcut(i), await L();
73
+ }
74
+ async function Q(i) {
75
+ await _.unpinShortcut(i), await L();
76
+ }
77
+ const P = h([]);
78
+ return X(async () => {
79
+ var i;
80
+ T = setInterval(() => {
81
+ B.value = /* @__PURE__ */ new Date();
82
+ }, 6e4);
83
+ try {
84
+ const u = await _.sessions();
85
+ $.value = ((i = u.find((k) => k.isCurrent)) == null ? void 0 : i.loginTime) ?? null;
86
+ } catch {
87
+ }
32
88
  try {
33
- h.value = (await K.mine({ page: 1, pageSize: 5 })).items;
89
+ m.value = await _.lastLogin();
34
90
  } catch {
91
+ m.value = null;
35
92
  }
36
- }), (m, i) => {
37
- var l, n;
38
- return o(), u("div", Q, [
39
- s("div", W, [
40
- s("div", {
93
+ try {
94
+ p.value = await _.workbenchTodo();
95
+ } catch {
96
+ p.value = null;
97
+ }
98
+ await L();
99
+ try {
100
+ P.value = (await dt.mine({ page: 1, pageSize: 5 })).items;
101
+ } catch {
102
+ }
103
+ }), Y(() => {
104
+ T && clearInterval(T);
105
+ }), (i, u) => {
106
+ var k, V;
107
+ return o(), s("div", kt, [
108
+ n("div", ft, [
109
+ n("div", {
41
110
  class: "avatar",
42
- style: $(q.value)
111
+ style: Z(K.value)
43
112
  }, [
44
- d(e(D), {
113
+ c(t(S), {
45
114
  icon: "ph:user",
46
115
  width: 26,
47
116
  color: "#fff"
48
117
  })
49
118
  ], 4),
50
- s("div", null, [
51
- s("div", X, a(e(c)("biz.welcome", { name: ((l = e(v).userInfo) == null ? void 0 : l.name) ?? ((n = e(v).userInfo) == null ? void 0 : n.account) ?? "" })), 1),
52
- s("div", Y, a(e(c)("biz.subtitle")), 1)
119
+ n("div", bt, [
120
+ n("div", yt, l(t(a)("biz.welcome", { name: ((k = t(M).userInfo) == null ? void 0 : k.name) ?? ((V = t(M).userInfo) == null ? void 0 : V.account) ?? "" })), 1),
121
+ n("div", gt, l(t(a)("biz.subtitle")), 1),
122
+ w.value || x.value ? (o(), s("div", wt, [
123
+ w.value ? (o(), s("span", zt, l(w.value), 1)) : r("", !0),
124
+ w.value && x.value ? (o(), s("span", Ct)) : r("", !0),
125
+ n("span", null, l(x.value), 1)
126
+ ])) : r("", !0)
53
127
  ])
54
128
  ]),
55
- d(e(g), {
56
- title: e(c)("biz.quick"),
57
- bordered: !0
58
- }, {
59
- default: r(() => [
60
- y.value.length ? (o(), u("div", Z, [
61
- (o(!0), u(z, null, N(y.value, (t) => (o(), p(e(w), {
62
- key: t.id,
63
- secondary: "",
64
- onClick: (A) => e(f).push(t.path)
129
+ n("div", qt, [
130
+ c(t(D), {
131
+ title: t(a)("biz.todo"),
132
+ bordered: !0
133
+ }, tt({
134
+ default: d(() => [
135
+ p.value && p.value.items.length ? (o(), s("div", St, [
136
+ (o(!0), s(C, null, q(p.value.items, (e) => (o(), s("div", {
137
+ key: e.id,
138
+ class: "todo-row",
139
+ onClick: (f) => e.url && t(g).push(e.url)
140
+ }, [
141
+ n("div", Tt, [
142
+ n("div", xt, l(e.title), 1),
143
+ e.description ? (o(), s("div", Nt, l(e.description), 1)) : r("", !0)
144
+ ]),
145
+ n("span", Lt, l(t(E)(e.createTime, { seconds: !1 })), 1)
146
+ ], 8, $t))), 128))
147
+ ])) : (o(), y(t(I), {
148
+ key: 1,
149
+ description: t(a)("biz.todoEmpty")
150
+ }, null, 8, ["description"]))
151
+ ]),
152
+ _: 2
153
+ }, [
154
+ p.value && p.value.totalCount > 0 ? {
155
+ name: "header-extra",
156
+ fn: d(() => [
157
+ c(t(et), {
158
+ type: "error",
159
+ round: "",
160
+ size: "small"
161
+ }, {
162
+ default: d(() => [
163
+ R(l(p.value.totalCount), 1)
164
+ ]),
165
+ _: 1
166
+ })
167
+ ]),
168
+ key: "0"
169
+ } : void 0
170
+ ]), 1032, ["title"]),
171
+ c(t(D), {
172
+ title: t(a)("biz.quick"),
173
+ bordered: !0
174
+ }, {
175
+ "header-extra": d(() => [
176
+ c(t(ot), {
177
+ size: "small",
178
+ quaternary: "",
179
+ circle: "",
180
+ onClick: u[0] || (u[0] = (e) => N.value = !0)
65
181
  }, {
66
- icon: r(() => [
67
- d(O, {
68
- icon: t.icon || "ph:squares-four",
69
- size: 16
70
- }, null, 8, ["icon"])
71
- ]),
72
- default: r(() => [
73
- _(" " + a(t.title), 1)
182
+ icon: d(() => [
183
+ c(t(S), {
184
+ icon: "ph:plus",
185
+ width: 16
186
+ })
74
187
  ]),
75
- _: 2
76
- }, 1032, ["onClick"]))), 128))
77
- ])) : (o(), p(e(C), {
78
- key: 1,
79
- description: e(c)("biz.noMenus")
80
- }, null, 8, ["description"]))
81
- ]),
82
- _: 1
83
- }, 8, ["title"]),
84
- d(e(g), {
85
- title: e(c)("biz.notices"),
188
+ _: 1
189
+ })
190
+ ]),
191
+ default: d(() => [
192
+ v.value.pinned.length || v.value.suggested.length ? (o(), s("div", Pt, [
193
+ v.value.pinned.length ? (o(), s("div", Dt, l(t(a)("biz.quickPinned")), 1)) : r("", !0),
194
+ v.value.pinned.length ? (o(), s("div", It, [
195
+ (o(!0), s(C, null, q(v.value.pinned, (e) => (o(), s("div", {
196
+ key: e.path,
197
+ class: "quick-item"
198
+ }, [
199
+ n("button", {
200
+ class: "quick-star active",
201
+ type: "button",
202
+ "aria-label": t(a)("biz.quickUnpin"),
203
+ onClick: F((f) => Q(e.path), ["stop"])
204
+ }, [
205
+ c(t(S), {
206
+ icon: "ph:star-fill",
207
+ width: 12
208
+ })
209
+ ], 8, Et),
210
+ n("div", {
211
+ class: "quick-body",
212
+ onClick: (f) => t(g).push(e.path)
213
+ }, [
214
+ c(j, {
215
+ icon: e.icon,
216
+ size: 17
217
+ }, null, 8, ["icon"]),
218
+ n("span", At, l(t(G)(e.title)), 1)
219
+ ], 8, Mt)
220
+ ]))), 128))
221
+ ])) : r("", !0),
222
+ v.value.suggested.length ? (o(), s("div", Bt, l(t(a)("biz.quickSuggested")), 1)) : r("", !0),
223
+ v.value.suggested.length ? (o(), s("div", Ut, [
224
+ (o(!0), s(C, null, q(v.value.suggested, (e) => (o(), s("div", {
225
+ key: e.path,
226
+ class: "quick-item suggested"
227
+ }, [
228
+ n("button", {
229
+ class: "quick-star",
230
+ type: "button",
231
+ "aria-label": t(a)("biz.quickPin"),
232
+ onClick: F((f) => U(e.path), ["stop"])
233
+ }, [
234
+ c(t(S), {
235
+ icon: "ph:star",
236
+ width: 12
237
+ })
238
+ ], 8, Vt),
239
+ n("div", {
240
+ class: "quick-body",
241
+ onClick: (f) => t(g).push(e.path)
242
+ }, [
243
+ c(j, {
244
+ icon: e.icon,
245
+ size: 17
246
+ }, null, 8, ["icon"]),
247
+ n("span", Ft, l(t(G)(e.title)), 1)
248
+ ], 8, Rt)
249
+ ]))), 128))
250
+ ])) : r("", !0)
251
+ ])) : (o(), y(t(I), {
252
+ key: 1,
253
+ description: t(a)("biz.noMenus")
254
+ }, null, 8, ["description"]))
255
+ ]),
256
+ _: 1
257
+ }, 8, ["title"])
258
+ ]),
259
+ c(t(D), {
260
+ title: t(a)("biz.notices"),
86
261
  bordered: !0
87
262
  }, {
88
- "header-extra": r(() => [
89
- d(e(w), {
90
- text: "",
91
- type: "primary",
92
- onClick: i[0] || (i[0] = (t) => e(f).push("/personal/notice"))
93
- }, {
94
- default: r(() => [
95
- _(a(e(c)("biz.viewAll")), 1)
96
- ]),
97
- _: 1
98
- })
99
- ]),
100
- default: r(() => [
101
- h.value.length ? (o(), p(e(L), {
263
+ default: d(() => [
264
+ P.value.length ? (o(), y(t(it), {
102
265
  key: 0,
103
266
  "show-divider": !1
104
267
  }, {
105
- default: r(() => [
106
- (o(!0), u(z, null, N(h.value, (t) => (o(), p(e(R), {
107
- key: t.id
268
+ default: d(() => [
269
+ (o(!0), s(C, null, q(P.value, (e) => (o(), y(t(st), {
270
+ key: e.id
108
271
  }, {
109
- default: r(() => [
110
- s("div", {
272
+ default: d(() => [
273
+ n("div", {
111
274
  class: "notice-row",
112
- onClick: i[1] || (i[1] = (A) => e(f).push("/personal/notice"))
275
+ onClick: u[1] || (u[1] = (f) => t(g).push("/personal/notice"))
113
276
  }, [
114
- s("span", ee, [
115
- t.isRead ? E("", !0) : (o(), u("span", te)),
116
- _(" " + a(t.title), 1)
277
+ n("span", Gt, [
278
+ e.isRead ? r("", !0) : (o(), s("span", jt)),
279
+ R(" " + l(e.title), 1)
117
280
  ]),
118
- s("span", oe, a(e(P)(t.publishTime, { seconds: !1 })), 1)
281
+ n("span", Ht, l(t(E)(e.publishTime, { seconds: !1 })), 1)
119
282
  ])
120
283
  ]),
121
284
  _: 2
122
285
  }, 1024))), 128))
123
286
  ]),
124
287
  _: 1
125
- })) : (o(), p(e(C), { key: 1 }))
288
+ })) : (o(), y(t(I), {
289
+ key: 1,
290
+ description: t(a)("biz.noticesEmpty")
291
+ }, null, 8, ["description"]))
126
292
  ]),
127
293
  _: 1
128
- }, 8, ["title"])
294
+ }, 8, ["title"]),
295
+ c(ht, {
296
+ show: N.value,
297
+ "onUpdate:show": u[2] || (u[2] = (e) => N.value = e),
298
+ "exclude-paths": [...O.value, t(A).path],
299
+ onPick: U
300
+ }, null, 8, ["show", "exclude-paths"])
129
301
  ]);
130
302
  };
131
303
  }
132
304
  });
133
305
  export {
134
- _e as default
306
+ re as default
135
307
  };
136
308
  //# sourceMappingURL=biz2.vue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"biz2.vue.js","sources":["../../../src/views/dashboard/biz.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 业务系统的工作台。每个应用一个首页组件——这里和 dashboard/workbench.vue 是两个独立页面,\n// 由各自应用的「工作台」菜单(component 字段)指向,切应用即换首页。\n// 全部真数据拼装:欢迎卡(user store)+ 快捷入口(当前应用菜单树的可见叶子)+ 我的通知(notice/mine)。\n// 应用要换成自己的业务统计,在自己的 views/ 下放同 key(dashboard/biz)的页面覆盖本页;别造写死的假数字。\nimport { computed, onMounted, ref } from 'vue'\nimport { NCard, NButton, NList, NListItem, NEmpty } from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useI18n } from 'vue-i18n'\nimport { useRoute, useRouter } from 'vue-router'\nimport { useUserStore } from '#/stores/user'\nimport { useAuthStore } from '#/stores/auth'\nimport { useAppStore } from '#/stores/app'\nimport { btnGrad } from '#/theme/mix'\nimport { noticeApi } from '#/api'\nimport type { NoticeMineItem } from '#/types/api'\nimport type { MenuNode } from '#/types/menu'\nimport AppIcon from '#/components/AppIcon.vue'\nimport { fmtDateTime } from '#/utils/format'\n\nconst { t } = useI18n()\nconst user = useUserStore()\nconst auth = useAuthStore()\nconst app = useAppStore()\nconst route = useRoute()\nconst router = useRouter()\n\nconst avatarStyle = computed(() => ({ background: btnGrad(app.accent) }))\n\n/** 当前应用菜单树的可见叶子(带 path)= 快捷入口;排除本页自身。 */\nfunction leaves(tree: MenuNode[]): MenuNode[] {\n const out: MenuNode[] = []\n for (const n of tree) {\n if (!n.visible) continue\n if (n.children?.length) out.push(...leaves(n.children))\n else if (n.path) out.push(n)\n }\n return out\n}\nconst quick = computed(() => leaves(auth.menuTree).filter(n => n.path !== route.path))\n\nconst notices = ref<NoticeMineItem[]>([])\nonMounted(async () => {\n try {\n notices.value = (await noticeApi.mine({ page: 1, pageSize: 5 })).items\n } catch {\n // 首页不因一张卡挂了糊用户一脸红(同 workbench):通知取不到就空态,其余照常可用。\n }\n})\n</script>\n\n<template>\n <div class=\"view\">\n <!-- 欢迎横幅(与 workbench 同语法:btnGrad 头像 + 主副标题) -->\n <div class=\"banner\">\n <div class=\"avatar\" :style=\"avatarStyle\">\n <Icon icon=\"ph:user\" :width=\"26\" color=\"#fff\" />\n </div>\n <div>\n <div class=\"hi\">\n {{ t('biz.welcome', { name: user.userInfo?.name ?? user.userInfo?.account ?? '' }) }}\n </div>\n <div class=\"tip\">{{ t('biz.subtitle') }}</div>\n </div>\n </div>\n\n <n-card :title=\"t('biz.quick')\" :bordered=\"true\">\n <div v-if=\"quick.length\" class=\"quick\">\n <n-button v-for=\"m in quick\" :key=\"m.id\" secondary @click=\"router.push(m.path!)\">\n <template #icon><AppIcon :icon=\"m.icon || 'ph:squares-four'\" :size=\"16\" /></template>\n {{ m.title }}\n </n-button>\n </div>\n <n-empty v-else :description=\"t('biz.noMenus')\" />\n </n-card>\n\n <n-card :title=\"t('biz.notices')\" :bordered=\"true\">\n <template #header-extra>\n <n-button text type=\"primary\" @click=\"router.push('/personal/notice')\">\n {{ t('biz.viewAll') }}\n </n-button>\n </template>\n <n-list v-if=\"notices.length\" :show-divider=\"false\">\n <n-list-item v-for=\"n in notices\" :key=\"n.id\">\n <div class=\"notice-row\" @click=\"router.push('/personal/notice')\">\n <span class=\"notice-title\">\n <span v-if=\"!n.isRead\" class=\"dot\" />\n {{ n.title }}\n </span>\n <span class=\"notice-time\">{{ fmtDateTime(n.publishTime, { seconds: false }) }}</span>\n </div>\n </n-list-item>\n </n-list>\n <n-empty v-else />\n </n-card>\n </div>\n</template>\n\n<style scoped>\n.view {\n display: flex;\n flex-direction: column;\n gap: var(--gap-card);\n}\n.banner {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 24px;\n border-radius: var(--radius-lg);\n background: var(--color-primary-light);\n}\n.avatar {\n width: 52px;\n height: 52px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.hi {\n font-size: var(--font-size-lg);\n font-weight: 600;\n color: var(--color-text-primary);\n}\n.tip {\n color: var(--color-text-secondary);\n margin-top: 4px;\n}\n.quick {\n display: flex;\n flex-wrap: wrap;\n gap: 12px;\n}\n.notice-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n cursor: pointer;\n}\n.notice-title {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--color-text-primary);\n}\n.dot {\n flex-shrink: 0;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--color-primary);\n}\n.notice-time {\n flex-shrink: 0;\n color: var(--color-text-secondary);\n font-size: 12px;\n}\n</style>\n"],"names":["t","useI18n","user","useUserStore","auth","useAuthStore","app","useAppStore","route","useRoute","router","useRouter","avatarStyle","computed","btnGrad","leaves","tree","out","_a","quick","n","notices","ref","onMounted","noticeApi","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_createVNode","_unref","Icon","_hoisted_3","_toDisplayString","_hoisted_4","NCard","_hoisted_5","_Fragment","_renderList","m","_createBlock","NButton","AppIcon","NEmpty","_cache","$event","NList","NListItem","_hoisted_6","_hoisted_7","_hoisted_8"],"mappings":"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"}
1
+ {"version":3,"file":"biz2.vue.js","sources":["../../../src/views/dashboard/biz.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 业务系统的工作台。每个应用一个首页组件——这里和 dashboard/workbench.vue 是两个独立页面,\n// 由各自应用的「工作台」菜单(component 字段)指向,切应用即换首页。\n// 全部真数据拼装:欢迎横幅(user store + sessions + last-login)+ 待办事项(工作台待办扩展点,\n// 内核默认空)+ 快捷方式(手动置顶 + 高频自动补位)+ 我的通知(notice/mine)。\n// 应用要换成自己的业务统计,在自己的 views/ 下放同 key(dashboard/biz)的页面覆盖本页;别造写死的假数字。\nimport { computed, onMounted, onUnmounted, ref } from 'vue'\nimport { NCard, NButton, NList, NListItem, NEmpty, NTag } from 'naive-ui'\nimport { Icon } from '@iconify/vue'\nimport { useI18n } from 'vue-i18n'\nimport { useRoute, useRouter } from 'vue-router'\nimport { useUserStore } from '#/stores/user'\nimport { useAppStore } from '#/stores/app'\nimport { btnGrad } from '#/theme/mix'\nimport { noticeApi, personalApi } from '#/api'\nimport type {\n NoticeMineItem,\n LastLoginInfo,\n WorkbenchTodoSummary,\n UserShortcutItem,\n} from '#/types/api'\nimport { useMenuFlat } from '#/composables/useMenuFlat'\nimport { translateMenuTitle } from '#/locales/menuTitle'\nimport { onlineDurationParts } from './onlineDuration'\nimport { buildShortcutGroups } from './shortcutGroups'\nimport ShortcutPicker from './ShortcutPicker.vue'\nimport AppIcon from '#/components/AppIcon.vue'\nimport { fmtDateTime } from '#/utils/format'\nimport { uaSummary } from '#/utils/ua'\n\nconst { t } = useI18n()\nconst user = useUserStore()\nconst app = useAppStore()\nconst route = useRoute()\nconst router = useRouter()\nconst leaves = useMenuFlat()\n\nconst avatarStyle = computed(() => ({ background: btnGrad(app.accent) }))\n\n// ── 在线时长 + 上次登录 ─────────────────────────────────────\nconst currentLoginTime = ref<string | null>(null)\nconst lastLogin = ref<LastLoginInfo | null>(null)\nconst now = ref(new Date())\nlet tickTimer: ReturnType<typeof setInterval> | undefined\n\nconst onlineText = computed(() => {\n if (!currentLoginTime.value) return ''\n const { hours, minutes } = onlineDurationParts(currentLoginTime.value, now.value)\n return hours > 0\n ? t('biz.onlineDuration', { hours, minutes })\n : t('biz.onlineDurationShort', { minutes })\n})\nconst lastLoginText = computed(() => {\n if (!lastLogin.value) return t('biz.firstLogin')\n const device = uaSummary(lastLogin.value.userAgent)\n const ip = lastLogin.value.ip ? ` · ${lastLogin.value.ip}` : ''\n const base = t('biz.lastLogin', { time: fmtDateTime(lastLogin.value.time, { seconds: false }) })\n return `${base}${ip}${device ? ` · ${device}` : ''}`\n})\n\n// ── 待办事项:内核默认空,消费方接入真实审批/工单系统后有内容 ──────────\nconst todo = ref<WorkbenchTodoSummary | null>(null)\n\n// ── 快捷方式 ─────────────────────────────────────────────\nconst shortcuts = ref<UserShortcutItem[]>([])\nconst pickerShow = ref(false)\n// 排除本页自身:工作台自己也是菜单树里的一条,不该出现在\"去哪儿\"的快捷方式里\nconst groups = computed(() =>\n buildShortcutGroups(\n shortcuts.value.filter(s => s.menuPath !== route.path),\n leaves.value,\n ),\n)\nconst pinnedPaths = computed(() => shortcuts.value.filter(s => s.pinned).map(s => s.menuPath))\n\nasync function loadShortcuts() {\n try {\n shortcuts.value = await personalApi.shortcuts()\n } catch {\n shortcuts.value = []\n }\n}\nasync function pin(path: string) {\n await personalApi.pinShortcut(path)\n await loadShortcuts()\n}\nasync function unpin(path: string) {\n await personalApi.unpinShortcut(path)\n await loadShortcuts()\n}\n\n// ── 通知 ────────────────────────────────────────────────\nconst notices = ref<NoticeMineItem[]>([])\n\nonMounted(async () => {\n tickTimer = setInterval(() => {\n now.value = new Date()\n }, 60_000)\n\n try {\n const sessions = await personalApi.sessions()\n currentLoginTime.value = sessions.find(s => s.isCurrent)?.loginTime ?? null\n } catch {\n // 在线时长拿不到就不显示这一段,不影响页面其余部分\n }\n try {\n lastLogin.value = await personalApi.lastLogin()\n } catch {\n lastLogin.value = null\n }\n try {\n todo.value = await personalApi.workbenchTodo()\n } catch {\n todo.value = null\n }\n await loadShortcuts()\n try {\n notices.value = (await noticeApi.mine({ page: 1, pageSize: 5 })).items\n } catch {\n // 首页不因一张卡挂了糊用户一脸红:通知取不到就空态,其余照常可用。\n }\n})\nonUnmounted(() => {\n if (tickTimer) clearInterval(tickTimer)\n})\n</script>\n\n<template>\n <div class=\"view\">\n <!-- 欢迎横幅:身份 + 在线状态,一行说完 -->\n <div class=\"banner\">\n <div class=\"avatar\" :style=\"avatarStyle\">\n <Icon icon=\"ph:user\" :width=\"26\" color=\"#fff\" />\n </div>\n <div class=\"banner-body\">\n <div class=\"hi\">\n {{ t('biz.welcome', { name: user.userInfo?.name ?? user.userInfo?.account ?? '' }) }}\n </div>\n <div class=\"tip\">{{ t('biz.subtitle') }}</div>\n <div v-if=\"onlineText || lastLoginText\" class=\"meta-row\">\n <span v-if=\"onlineText\">{{ onlineText }}</span>\n <span v-if=\"onlineText && lastLoginText\" class=\"meta-dot\" />\n <span>{{ lastLoginText }}</span>\n </div>\n </div>\n </div>\n\n <div class=\"row\">\n <!-- 待办事项:内核默认空,消费方接入真实审批/工单系统后有内容 -->\n <n-card :title=\"t('biz.todo')\" :bordered=\"true\">\n <template v-if=\"todo && todo.totalCount > 0\" #header-extra>\n <n-tag type=\"error\" round size=\"small\">{{ todo.totalCount }}</n-tag>\n </template>\n <div v-if=\"todo && todo.items.length\" class=\"todo-list\">\n <div\n v-for=\"i in todo.items\"\n :key=\"i.id\"\n class=\"todo-row\"\n @click=\"i.url && router.push(i.url)\"\n >\n <div class=\"todo-main\">\n <div class=\"todo-title\">{{ i.title }}</div>\n <div v-if=\"i.description\" class=\"todo-sub\">{{ i.description }}</div>\n </div>\n <span class=\"todo-time\">{{ fmtDateTime(i.createTime, { seconds: false }) }}</span>\n </div>\n </div>\n <n-empty v-else :description=\"t('biz.todoEmpty')\" />\n </n-card>\n\n <!-- 快捷方式:实心星=手动置顶(可移除),虚线框+空心星=高频访问自动推荐(点固定即置顶) -->\n <n-card :title=\"t('biz.quick')\" :bordered=\"true\">\n <template #header-extra>\n <n-button size=\"small\" quaternary circle @click=\"pickerShow = true\">\n <template #icon><Icon icon=\"ph:plus\" :width=\"16\" /></template>\n </n-button>\n </template>\n <div v-if=\"groups.pinned.length || groups.suggested.length\">\n <div v-if=\"groups.pinned.length\" class=\"quick-group-label\">\n {{ t('biz.quickPinned') }}\n </div>\n <div v-if=\"groups.pinned.length\" class=\"quick-grid\">\n <div v-for=\"s in groups.pinned\" :key=\"s.path\" class=\"quick-item\">\n <button\n class=\"quick-star active\"\n type=\"button\"\n :aria-label=\"t('biz.quickUnpin')\"\n @click.stop=\"unpin(s.path)\"\n >\n <Icon icon=\"ph:star-fill\" :width=\"12\" />\n </button>\n <div class=\"quick-body\" @click=\"router.push(s.path)\">\n <AppIcon :icon=\"s.icon\" :size=\"17\" />\n <span class=\"quick-name\">{{ translateMenuTitle(s.title) }}</span>\n </div>\n </div>\n </div>\n <div v-if=\"groups.suggested.length\" class=\"quick-group-label\">\n {{ t('biz.quickSuggested') }}\n </div>\n <div v-if=\"groups.suggested.length\" class=\"quick-grid\">\n <div v-for=\"s in groups.suggested\" :key=\"s.path\" class=\"quick-item suggested\">\n <button\n class=\"quick-star\"\n type=\"button\"\n :aria-label=\"t('biz.quickPin')\"\n @click.stop=\"pin(s.path)\"\n >\n <Icon icon=\"ph:star\" :width=\"12\" />\n </button>\n <div class=\"quick-body\" @click=\"router.push(s.path)\">\n <AppIcon :icon=\"s.icon\" :size=\"17\" />\n <span class=\"quick-name\">{{ translateMenuTitle(s.title) }}</span>\n </div>\n </div>\n </div>\n </div>\n <n-empty v-else :description=\"t('biz.noMenus')\" />\n </n-card>\n </div>\n\n <!-- 通知:没有\"查看全部\"——卡片本身就是完整内容 -->\n <n-card :title=\"t('biz.notices')\" :bordered=\"true\">\n <n-list v-if=\"notices.length\" :show-divider=\"false\">\n <n-list-item v-for=\"n in notices\" :key=\"n.id\">\n <div class=\"notice-row\" @click=\"router.push('/personal/notice')\">\n <span class=\"notice-title\">\n <span v-if=\"!n.isRead\" class=\"dot\" />\n {{ n.title }}\n </span>\n <span class=\"notice-time\">{{ fmtDateTime(n.publishTime, { seconds: false }) }}</span>\n </div>\n </n-list-item>\n </n-list>\n <n-empty v-else :description=\"t('biz.noticesEmpty')\" />\n </n-card>\n\n <ShortcutPicker\n v-model:show=\"pickerShow\"\n :exclude-paths=\"[...pinnedPaths, route.path]\"\n @pick=\"pin\"\n />\n </div>\n</template>\n\n<style scoped>\n.view {\n display: flex;\n flex-direction: column;\n gap: var(--gap-card);\n}\n.banner {\n display: flex;\n align-items: center;\n gap: 16px;\n padding: 24px;\n border-radius: var(--radius-lg);\n background: var(--color-primary-light);\n}\n.avatar {\n flex-shrink: 0;\n width: 52px;\n height: 52px;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n}\n.banner-body {\n min-width: 0;\n}\n.hi {\n font-size: var(--font-size-lg);\n font-weight: 600;\n color: var(--color-text-primary);\n}\n.tip {\n color: var(--color-text-secondary);\n margin-top: 4px;\n}\n.meta-row {\n margin-top: 8px;\n display: flex;\n align-items: center;\n gap: 10px;\n font-size: 13px;\n color: var(--color-text-tertiary);\n font-variant-numeric: tabular-nums;\n}\n.meta-dot {\n width: 3px;\n height: 3px;\n border-radius: 50%;\n background: var(--color-text-disabled);\n flex-shrink: 0;\n}\n.row {\n display: grid;\n grid-template-columns: 1.35fr 1fr;\n gap: var(--gap-card);\n align-items: start;\n}\n@media (max-width: 760px) {\n .row {\n grid-template-columns: 1fr;\n }\n}\n.todo-list {\n display: flex;\n flex-direction: column;\n}\n.todo-row {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n padding: 10px 0;\n border-bottom: 1px solid var(--color-border);\n cursor: pointer;\n}\n.todo-row:last-child {\n border-bottom: none;\n}\n.todo-title {\n color: var(--color-text-primary);\n font-weight: 500;\n}\n.todo-sub {\n margin-top: 2px;\n font-size: 12px;\n color: var(--color-text-tertiary);\n}\n.todo-time {\n flex-shrink: 0;\n font-size: 12px;\n color: var(--color-text-tertiary);\n}\n.quick-group-label {\n font-size: 12px;\n color: var(--color-text-tertiary);\n margin: 4px 0 8px;\n}\n.quick-grid {\n display: flex;\n flex-wrap: wrap;\n gap: 10px;\n margin-bottom: 4px;\n}\n.quick-item {\n position: relative;\n border: 1px solid var(--color-border);\n border-radius: var(--radius-md);\n}\n.quick-item.suggested {\n border-style: dashed;\n}\n.quick-body {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 14px 8px 10px;\n cursor: pointer;\n}\n.quick-name {\n font-size: 13px;\n color: var(--color-text-secondary);\n}\n.quick-star {\n position: absolute;\n top: -6px;\n right: -6px;\n width: 18px;\n height: 18px;\n border-radius: 50%;\n border: 1px solid var(--color-border);\n background: var(--color-bg-elevated);\n color: var(--color-text-disabled);\n display: flex;\n align-items: center;\n justify-content: center;\n cursor: pointer;\n}\n.quick-star.active {\n color: var(--color-warning);\n}\n.notice-row {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 12px;\n cursor: pointer;\n}\n.notice-title {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n color: var(--color-text-primary);\n}\n.dot {\n flex-shrink: 0;\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--color-primary);\n}\n.notice-time {\n flex-shrink: 0;\n color: var(--color-text-secondary);\n font-size: 12px;\n}\n</style>\n"],"names":["t","useI18n","user","useUserStore","app","useAppStore","route","useRoute","router","useRouter","leaves","useMenuFlat","avatarStyle","computed","btnGrad","currentLoginTime","ref","lastLogin","now","tickTimer","onlineText","hours","minutes","onlineDurationParts","lastLoginText","device","uaSummary","ip","fmtDateTime","todo","shortcuts","pickerShow","groups","buildShortcutGroups","s","pinnedPaths","loadShortcuts","personalApi","pin","path","unpin","notices","onMounted","sessions","_a","noticeApi","onUnmounted","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_createVNode","_unref","Icon","_hoisted_3","_hoisted_4","_toDisplayString","_hoisted_5","_hoisted_6","_hoisted_8","_hoisted_9","NCard","_hoisted_10","_Fragment","_renderList","i","$event","_hoisted_12","_hoisted_13","_hoisted_14","_hoisted_15","_createBlock","NEmpty","NTag","_createTextVNode","NButton","_hoisted_16","_hoisted_17","_hoisted_18","_withModifiers","AppIcon","_hoisted_21","_hoisted_22","_hoisted_23","_hoisted_26","NList","n","NListItem","_cache","_hoisted_27","_hoisted_28","_hoisted_29","ShortcutPicker"],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** 在线时长拆成小时/分钟,供 i18n 模板插值;不做负数(时钟回拨/服务器时间误差时钳到 0)。 */
2
+ export declare function onlineDurationParts(loginTime: string, now?: Date): {
3
+ hours: number;
4
+ minutes: number;
5
+ };
@@ -0,0 +1,8 @@
1
+ function r(e, n = /* @__PURE__ */ new Date()) {
2
+ const o = new Date(e), a = Math.max(0, n.getTime() - o.getTime()), t = Math.floor(a / 6e4);
3
+ return { hours: Math.floor(t / 60), minutes: t % 60 };
4
+ }
5
+ export {
6
+ r as onlineDurationParts
7
+ };
8
+ //# sourceMappingURL=onlineDuration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"onlineDuration.js","sources":["../../../src/views/dashboard/onlineDuration.ts"],"sourcesContent":["/** 在线时长拆成小时/分钟,供 i18n 模板插值;不做负数(时钟回拨/服务器时间误差时钳到 0)。 */\nexport function onlineDurationParts(\n loginTime: string,\n now: Date = new Date(),\n): { hours: number; minutes: number } {\n const start = new Date(loginTime)\n const ms = Math.max(0, now.getTime() - start.getTime())\n const totalMinutes = Math.floor(ms / 60000)\n return { hours: Math.floor(totalMinutes / 60), minutes: totalMinutes % 60 }\n}\n"],"names":["onlineDurationParts","loginTime","now","start","ms","totalMinutes"],"mappings":"AACO,SAASA,EACdC,GACAC,IAAY,oBAAI,QACoB;AACpC,QAAMC,IAAQ,IAAI,KAAKF,CAAS,GAC1BG,IAAK,KAAK,IAAI,GAAGF,EAAI,QAAA,IAAYC,EAAM,SAAS,GAChDE,IAAe,KAAK,MAAMD,IAAK,GAAK;AAC1C,SAAO,EAAE,OAAO,KAAK,MAAMC,IAAe,EAAE,GAAG,SAASA,IAAe,GAAA;AACzE;"}
@@ -0,0 +1,18 @@
1
+ import { UserShortcutItem } from '../../types/api';
2
+ import { MenuLeaf } from '../../composables/useMenuFlat';
3
+ export interface ShortcutDisplayItem {
4
+ path: string;
5
+ /** i18n key 或原文,口径与 MenuLeaf.title 一致——渲染时要经 translateMenuTitle(title),不能直接展示。 */
6
+ title: string;
7
+ icon: string;
8
+ pinned: boolean;
9
+ }
10
+ /**
11
+ * 后端 personalApi.shortcuts() 已经按"置顶优先 + 高频补位"排好序、按 cap 截断,这里只做两件事:
12
+ * 按 pinned 拆成两组、用当前应用可见的菜单叶子重新取标题/图标(而不是信后端 title——那是数据库原文,
13
+ * 不带 i18n;菜单被禁用/删除/无权限后不在 menuLeaves 里,对应快捷方式自动消失,不用后端联动清理)。
14
+ */
15
+ export declare function buildShortcutGroups(shortcuts: UserShortcutItem[], menuLeaves: MenuLeaf[]): {
16
+ pinned: ShortcutDisplayItem[];
17
+ suggested: ShortcutDisplayItem[];
18
+ };
@@ -0,0 +1,19 @@
1
+ function r(e, p) {
2
+ const a = new Map(p.map((n) => [n.path, n])), l = (n) => {
3
+ const t = a.get(n.menuPath);
4
+ return t ? {
5
+ path: n.menuPath,
6
+ title: t.title,
7
+ icon: t.icon || "ph:squares-four",
8
+ pinned: n.pinned
9
+ } : null;
10
+ }, i = (n) => n.map(l).filter((t) => t !== null);
11
+ return {
12
+ pinned: i(e.filter((n) => n.pinned)),
13
+ suggested: i(e.filter((n) => !n.pinned))
14
+ };
15
+ }
16
+ export {
17
+ r as buildShortcutGroups
18
+ };
19
+ //# sourceMappingURL=shortcutGroups.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shortcutGroups.js","sources":["../../../src/views/dashboard/shortcutGroups.ts"],"sourcesContent":["import type { UserShortcutItem } from '#/types/api'\nimport type { MenuLeaf } from '#/composables/useMenuFlat'\n\nexport interface ShortcutDisplayItem {\n path: string\n /** i18n key 或原文,口径与 MenuLeaf.title 一致——渲染时要经 translateMenuTitle(title),不能直接展示。 */\n title: string\n icon: string\n pinned: boolean\n}\n\n/**\n * 后端 personalApi.shortcuts() 已经按\"置顶优先 + 高频补位\"排好序、按 cap 截断,这里只做两件事:\n * 按 pinned 拆成两组、用当前应用可见的菜单叶子重新取标题/图标(而不是信后端 title——那是数据库原文,\n * 不带 i18n;菜单被禁用/删除/无权限后不在 menuLeaves 里,对应快捷方式自动消失,不用后端联动清理)。\n */\nexport function buildShortcutGroups(\n shortcuts: UserShortcutItem[],\n menuLeaves: MenuLeaf[],\n): { pinned: ShortcutDisplayItem[]; suggested: ShortcutDisplayItem[] } {\n const leafByPath = new Map(menuLeaves.map(l => [l.path, l]))\n const toDisplay = (s: UserShortcutItem): ShortcutDisplayItem | null => {\n const leaf = leafByPath.get(s.menuPath)\n if (!leaf) return null\n return {\n path: s.menuPath,\n title: leaf.title,\n icon: leaf.icon || 'ph:squares-four',\n pinned: s.pinned,\n }\n }\n const display = (list: UserShortcutItem[]) =>\n list.map(toDisplay).filter((x): x is ShortcutDisplayItem => x !== null)\n return {\n pinned: display(shortcuts.filter(s => s.pinned)),\n suggested: display(shortcuts.filter(s => !s.pinned)),\n }\n}\n"],"names":["buildShortcutGroups","shortcuts","menuLeaves","leafByPath","l","toDisplay","s","leaf","display","list","x"],"mappings":"AAgBO,SAASA,EACdC,GACAC,GACqE;AACrE,QAAMC,IAAa,IAAI,IAAID,EAAW,IAAI,CAAAE,MAAK,CAACA,EAAE,MAAMA,CAAC,CAAC,CAAC,GACrDC,IAAY,CAACC,MAAoD;AACrE,UAAMC,IAAOJ,EAAW,IAAIG,EAAE,QAAQ;AACtC,WAAKC,IACE;AAAA,MACL,MAAMD,EAAE;AAAA,MACR,OAAOC,EAAK;AAAA,MACZ,MAAMA,EAAK,QAAQ;AAAA,MACnB,QAAQD,EAAE;AAAA,IAAA,IALM;AAAA,EAOpB,GACME,IAAU,CAACC,MACfA,EAAK,IAAIJ,CAAS,EAAE,OAAO,CAACK,MAAgCA,MAAM,IAAI;AACxE,SAAO;AAAA,IACL,QAAQF,EAAQP,EAAU,OAAO,CAAAK,MAAKA,EAAE,MAAM,CAAC;AAAA,IAC/C,WAAWE,EAAQP,EAAU,OAAO,OAAK,CAACK,EAAE,MAAM,CAAC;AAAA,EAAA;AAEvD;"}
@@ -0,0 +1,3 @@
1
+ declare const __VLS_export: import('vue').DefineComponent<{}, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
2
+ declare const _default: typeof __VLS_export;
3
+ export default _default;
@@ -0,0 +1,8 @@
1
+ import o from "./index2.vue.js";
2
+ /* empty css */
3
+ import t from "../../../_virtual/_plugin-vue_export-helper.js";
4
+ const m = /* @__PURE__ */ t(o, [["__scopeId", "data-v-95f59a57"]]);
5
+ export {
6
+ m as default
7
+ };
8
+ //# sourceMappingURL=index.vue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}