smart-admin-web 10.23.0 → 10.23.1
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/dist/lib/runtime.js +1 -1
- package/dist/style.css +1 -1
- package/dist/utils/tree.d.ts +1 -2
- package/dist/utils/tree.js.map +1 -1
- package/dist/views/system/menu/index.vue.js +1 -1
- package/dist/views/system/menu/index2.vue.js +151 -161
- package/dist/views/system/menu/index2.vue.js.map +1 -1
- package/dist/views/system/org/index.vue.js +2 -2
- package/dist/views/system/org/index2.vue.js +176 -182
- package/dist/views/system/org/index2.vue.js.map +1 -1
- package/package.json +3 -3
- package/dist/utils/treeCard.d.ts +0 -6
- package/dist/utils/treeCard.js +0 -9
- package/dist/utils/treeCard.js.map +0 -1
package/dist/utils/tree.d.ts
CHANGED
|
@@ -33,8 +33,7 @@ export declare function rootExpandableIds<T extends {
|
|
|
33
33
|
}>(nodes: T[]): number[];
|
|
34
34
|
/**
|
|
35
35
|
* 树 → 深度优先平铺行(父在前、子紧随其后),每行带 depth(根 = 0),children 置空。
|
|
36
|
-
*
|
|
37
|
-
* 树表在手机上要想看到子节点,就得由页面自己把整棵树摊成一列。行是浅拷贝,不改入参。
|
|
36
|
+
* 行是浅拷贝,不改入参。
|
|
38
37
|
*/
|
|
39
38
|
export declare function flattenTree<T extends {
|
|
40
39
|
children?: T[];
|
package/dist/utils/tree.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tree.js","sources":["../../src/utils/tree.ts"],"sourcesContent":["/** 平铺列表 → 树。按 parentId 挂到父的 children;根 = parentId 不在集合内(含 0)。\n * 原序保留(输入通常已按 sort、id 排好);孤儿(父不存在)兜底当根,不丢数据。\n * 两个消费点:OrgTreeSelect、机构管理页。 */\nexport type Tree<T> = T & { children?: Tree<T>[] }\n\nexport function buildTree<T extends { id: number; parentId: number }>(flat: T[]): Tree<T>[] {\n const map = new Map<number, Tree<T>>()\n for (const item of flat) map.set(item.id, { ...item })\n const roots: Tree<T>[] = []\n for (const item of flat) {\n const node = map.get(item.id)!\n const parent = map.get(item.parentId)\n if (parent) (parent.children ??= []).push(node)\n else roots.push(node)\n }\n return roots\n}\n\n/**\n * 按谓词剪枝:命中的节点保留(连同它的整棵子树——搜到一个目录,自然想看它下面有什么),\n * 未命中但有后代命中的节点作为**祖先链**保留(否则命中的节点在树里无处安放,只剩一堆没有上下文的叶子)。\n *\n * 命中节点返回的是**原对象引用**(零拷贝);只有\"仅因后代命中而保留\"的祖先才是浅拷贝(children 换成剪过的分支)。\n * 因此在搜索态下,直接往行对象上写值(`r.enabled = v`)对这些祖先行不会回写到源树 ——\n * 调用方要么改从源树写,要么变更后重拉(机构页选了后者,与它其余所有变更的做法一致)。\n *\n * 两个消费点:菜单管理页、机构管理页。\n */\nexport function filterTree<T extends { children?: T[] }>(\n nodes: T[],\n match: (node: T) => boolean,\n): T[] {\n const out: T[] = []\n for (const node of nodes) {\n if (match(node)) {\n out.push(node)\n continue\n }\n const kids = filterTree(node.children ?? [], match)\n if (kids.length) out.push({ ...node, children: kids })\n }\n return out\n}\n\n/** 收集树中所有\"可展开\"节点(有子节点)的 id —— 受控展开时用它播种\"全部展开\"。 */\nexport function expandableIds<T extends { id: number; children?: T[] }>(nodes: T[]): number[] {\n const ids: number[] = []\n const walk = (list: T[]) => {\n for (const n of list) {\n if (n.children?.length) {\n ids.push(n.id)\n walk(n.children)\n }\n }\n }\n walk(nodes)\n return ids\n}\n\n/** 有子节点的根的 id —— 受控展开时用它播种\"只展开一级\":根展开、露出第二层,更深的层级仍收起。 */\nexport function rootExpandableIds<T extends { id: number; children?: T[] }>(nodes: T[]): number[] {\n return nodes.filter(n => n.children?.length).map(n => n.id)\n}\n\n/**\n * 树 → 深度优先平铺行(父在前、子紧随其后),每行带 depth(根 = 0),children 置空。\n *
|
|
1
|
+
{"version":3,"file":"tree.js","sources":["../../src/utils/tree.ts"],"sourcesContent":["/** 平铺列表 → 树。按 parentId 挂到父的 children;根 = parentId 不在集合内(含 0)。\n * 原序保留(输入通常已按 sort、id 排好);孤儿(父不存在)兜底当根,不丢数据。\n * 两个消费点:OrgTreeSelect、机构管理页。 */\nexport type Tree<T> = T & { children?: Tree<T>[] }\n\nexport function buildTree<T extends { id: number; parentId: number }>(flat: T[]): Tree<T>[] {\n const map = new Map<number, Tree<T>>()\n for (const item of flat) map.set(item.id, { ...item })\n const roots: Tree<T>[] = []\n for (const item of flat) {\n const node = map.get(item.id)!\n const parent = map.get(item.parentId)\n if (parent) (parent.children ??= []).push(node)\n else roots.push(node)\n }\n return roots\n}\n\n/**\n * 按谓词剪枝:命中的节点保留(连同它的整棵子树——搜到一个目录,自然想看它下面有什么),\n * 未命中但有后代命中的节点作为**祖先链**保留(否则命中的节点在树里无处安放,只剩一堆没有上下文的叶子)。\n *\n * 命中节点返回的是**原对象引用**(零拷贝);只有\"仅因后代命中而保留\"的祖先才是浅拷贝(children 换成剪过的分支)。\n * 因此在搜索态下,直接往行对象上写值(`r.enabled = v`)对这些祖先行不会回写到源树 ——\n * 调用方要么改从源树写,要么变更后重拉(机构页选了后者,与它其余所有变更的做法一致)。\n *\n * 两个消费点:菜单管理页、机构管理页。\n */\nexport function filterTree<T extends { children?: T[] }>(\n nodes: T[],\n match: (node: T) => boolean,\n): T[] {\n const out: T[] = []\n for (const node of nodes) {\n if (match(node)) {\n out.push(node)\n continue\n }\n const kids = filterTree(node.children ?? [], match)\n if (kids.length) out.push({ ...node, children: kids })\n }\n return out\n}\n\n/** 收集树中所有\"可展开\"节点(有子节点)的 id —— 受控展开时用它播种\"全部展开\"。 */\nexport function expandableIds<T extends { id: number; children?: T[] }>(nodes: T[]): number[] {\n const ids: number[] = []\n const walk = (list: T[]) => {\n for (const n of list) {\n if (n.children?.length) {\n ids.push(n.id)\n walk(n.children)\n }\n }\n }\n walk(nodes)\n return ids\n}\n\n/** 有子节点的根的 id —— 受控展开时用它播种\"只展开一级\":根展开、露出第二层,更深的层级仍收起。 */\nexport function rootExpandableIds<T extends { id: number; children?: T[] }>(nodes: T[]): number[] {\n return nodes.filter(n => n.children?.length).map(n => n.id)\n}\n\n/**\n * 树 → 深度优先平铺行(父在前、子紧随其后),每行带 depth(根 = 0),children 置空。\n * 行是浅拷贝,不改入参。\n */\nexport function flattenTree<T extends { children?: T[] }>(\n nodes: T[],\n depth = 0,\n): Array<T & { depth: number }> {\n return nodes.flatMap(node => [\n { ...node, children: [], depth } as T & { depth: number },\n ...flattenTree(node.children ?? [], depth + 1),\n ])\n}\n\n/** 收集 rootId 及其全部后代 id(平铺数组上按 parentId 迭代到不动点)。编辑机构选上级时剪自身子树防成环。 */\nexport function collectSubtreeIds<T extends { id: number; parentId: number }>(\n flat: T[],\n rootId: number,\n): Set<number> {\n const ids = new Set<number>([rootId])\n let grew = true\n while (grew) {\n grew = false\n for (const item of flat) {\n if (!ids.has(item.id) && ids.has(item.parentId)) {\n ids.add(item.id)\n grew = true\n }\n }\n }\n return ids\n}\n"],"names":["buildTree","flat","map","item","roots","node","parent","filterTree","nodes","match","out","kids","expandableIds","ids","walk","list","_a","n","rootExpandableIds","flattenTree","depth","collectSubtreeIds","rootId","grew"],"mappings":"AAKO,SAASA,EAAsDC,GAAsB;AAC1F,QAAMC,wBAAU,IAAA;AAChB,aAAWC,KAAQF,EAAM,CAAAC,EAAI,IAAIC,EAAK,IAAI,EAAE,GAAGA,GAAM;AACrD,QAAMC,IAAmB,CAAA;AACzB,aAAWD,KAAQF,GAAM;AACvB,UAAMI,IAAOH,EAAI,IAAIC,EAAK,EAAE,GACtBG,IAASJ,EAAI,IAAIC,EAAK,QAAQ;AACpC,IAAIG,KAASA,EAAO,aAAPA,EAAO,WAAa,CAAA,IAAI,KAAKD,CAAI,IACzCD,EAAM,KAAKC,CAAI;AAAA,EACtB;AACA,SAAOD;AACT;AAYO,SAASG,EACdC,GACAC,GACK;AACL,QAAMC,IAAW,CAAA;AACjB,aAAWL,KAAQG,GAAO;AACxB,QAAIC,EAAMJ,CAAI,GAAG;AACf,MAAAK,EAAI,KAAKL,CAAI;AACb;AAAA,IACF;AACA,UAAMM,IAAOJ,EAAWF,EAAK,YAAY,CAAA,GAAII,CAAK;AAClD,IAAIE,EAAK,UAAQD,EAAI,KAAK,EAAE,GAAGL,GAAM,UAAUM,GAAM;AAAA,EACvD;AACA,SAAOD;AACT;AAGO,SAASE,EAAwDJ,GAAsB;AAC5F,QAAMK,IAAgB,CAAA,GAChBC,IAAO,CAACC,MAAc;AA1CvB,QAAAC;AA2CH,eAAWC,KAAKF;AACd,OAAIC,IAAAC,EAAE,aAAF,QAAAD,EAAY,WACdH,EAAI,KAAKI,EAAE,EAAE,GACbH,EAAKG,EAAE,QAAQ;AAAA,EAGrB;AACA,SAAAH,EAAKN,CAAK,GACHK;AACT;AAGO,SAASK,EAA4DV,GAAsB;AAChG,SAAOA,EAAM,OAAO,CAAAS,MAAA;AAxDf,QAAAD;AAwDoB,YAAAA,IAAAC,EAAE,aAAF,gBAAAD,EAAY;AAAA,GAAM,EAAE,IAAI,CAAAC,MAAKA,EAAE,EAAE;AAC5D;AAMO,SAASE,EACdX,GACAY,IAAQ,GACsB;AAC9B,SAAOZ,EAAM,QAAQ,CAAAH,MAAQ;AAAA,IAC3B,EAAE,GAAGA,GAAM,UAAU,CAAA,GAAI,OAAAe,EAAA;AAAA,IACzB,GAAGD,EAAYd,EAAK,YAAY,CAAA,GAAIe,IAAQ,CAAC;AAAA,EAAA,CAC9C;AACH;AAGO,SAASC,EACdpB,GACAqB,GACa;AACb,QAAMT,IAAM,oBAAI,IAAY,CAACS,CAAM,CAAC;AACpC,MAAIC,IAAO;AACX,SAAOA,KAAM;AACX,IAAAA,IAAO;AACP,eAAWpB,KAAQF;AACjB,MAAI,CAACY,EAAI,IAAIV,EAAK,EAAE,KAAKU,EAAI,IAAIV,EAAK,QAAQ,MAC5CU,EAAI,IAAIV,EAAK,EAAE,GACfoB,IAAO;AAAA,EAGb;AACA,SAAOV;AACT;"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import o from "./index2.vue.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import t from "../../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const p = /* @__PURE__ */ t(o, [["__scopeId", "data-v-
|
|
4
|
+
const p = /* @__PURE__ */ t(o, [["__scopeId", "data-v-bc3b33f7"]]);
|
|
5
5
|
export {
|
|
6
6
|
p as default
|
|
7
7
|
};
|
|
@@ -1,141 +1,137 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { useMessage as
|
|
3
|
-
import { SmartTable as
|
|
4
|
-
import { useI18n as
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import { useConfirm as
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
19
|
-
import {
|
|
20
|
-
import {
|
|
21
|
-
|
|
22
|
-
import { translateMenuTitle as R } from "../../../locales/menuTitle.js";
|
|
23
|
-
const We = { class: "view fill-page" }, b = 0, te = -1, gt = /* @__PURE__ */ ye({
|
|
1
|
+
import { defineComponent as pe, ref as p, shallowRef as A, onMounted as fe, computed as f, watch as ve, h as o, resolveDirective as he, openBlock as K, createElementBlock as ye, createVNode as v, unref as s, withCtx as h, createTextVNode as V, toDisplayString as W, withDirectives as ge, createBlock as we, toRaw as ke } from "vue";
|
|
2
|
+
import { useMessage as be, NSpace as J, NTag as Q, NButton as w, NDropdown as _e, NSelect as xe } from "naive-ui";
|
|
3
|
+
import { SmartTable as Te } from "smart-naive-table";
|
|
4
|
+
import { useI18n as Ie } from "vue-i18n";
|
|
5
|
+
import c from "../../../components/AppIcon.vue.js";
|
|
6
|
+
import Me from "../../../components/StatusSwitch/index.vue.js";
|
|
7
|
+
import Ce from "./components/ButtonManager.vue.js";
|
|
8
|
+
import ze from "./components/MenuFormModal.vue.js";
|
|
9
|
+
import { useConfirm as Se } from "../../../composables/useConfirm.js";
|
|
10
|
+
import { buildRoutesForModule as Ae } from "../../../composables/useAuthMenu.js";
|
|
11
|
+
import { useAuthStore as Ee } from "../../../stores/auth.js";
|
|
12
|
+
import { moduleApi as Pe, menuApi as x } from "../../../api/index.js";
|
|
13
|
+
import { translateError as Be } from "../../../utils/error.js";
|
|
14
|
+
import { SEARCH_ACTIONS as E, deriveHeaderFilters as Re } from "../../../utils/tableFilter.js";
|
|
15
|
+
import { TABLE_MIN_ROW_HEIGHT as Ne, TABLE_TOOLBAR as Oe } from "../../../utils/tableToolbar.js";
|
|
16
|
+
import { expandableIds as X } from "../../../utils/tree.js";
|
|
17
|
+
import { filterTreeByParams as De, hasTreeCondition as Le } from "../../../utils/treeFilter.js";
|
|
18
|
+
import { toMenuInput as Fe, MenuType as k, splitPermission as Ue } from "../../../types/menu.js";
|
|
19
|
+
import { lineIcon as $e } from "../../../utils/menuIcon.js";
|
|
20
|
+
import { translateMenuTitle as P } from "../../../locales/menuTitle.js";
|
|
21
|
+
const He = { class: "view fill-page" }, b = 0, Y = -1, dt = /* @__PURE__ */ pe({
|
|
24
22
|
__name: "index",
|
|
25
|
-
setup(
|
|
26
|
-
const { t: n } =
|
|
27
|
-
async function
|
|
28
|
-
|
|
23
|
+
setup(qe) {
|
|
24
|
+
const { t: n } = Ie(), Z = be(), { confirm: ee } = Se(), d = Ee(), T = p(!1), y = A([]), g = A([]), a = p(d.currentModuleId ?? b), B = p([]);
|
|
25
|
+
async function te() {
|
|
26
|
+
T.value = !0;
|
|
29
27
|
try {
|
|
30
28
|
y.value = await x.tree();
|
|
31
29
|
} catch (e) {
|
|
32
|
-
|
|
30
|
+
Z.error(Be(e));
|
|
33
31
|
} finally {
|
|
34
|
-
|
|
32
|
+
T.value = !1;
|
|
35
33
|
}
|
|
36
34
|
}
|
|
37
|
-
async function
|
|
35
|
+
async function R() {
|
|
38
36
|
if (d.currentModuleId)
|
|
39
37
|
try {
|
|
40
|
-
await
|
|
38
|
+
await Ae(d.currentModuleId);
|
|
41
39
|
} catch {
|
|
42
40
|
}
|
|
43
41
|
}
|
|
44
|
-
|
|
42
|
+
fe(async () => {
|
|
45
43
|
var e;
|
|
46
44
|
try {
|
|
47
|
-
g.value = await
|
|
45
|
+
g.value = await Pe.list(), N.value.some((t) => t.value === a.value) || (a.value = ((e = g.value[0]) == null ? void 0 : e.id) ?? b);
|
|
48
46
|
} catch {
|
|
49
47
|
}
|
|
50
48
|
try {
|
|
51
|
-
|
|
49
|
+
B.value = await x.routes();
|
|
52
50
|
} catch {
|
|
53
51
|
}
|
|
54
52
|
});
|
|
55
|
-
const
|
|
56
|
-
() => g.value.map((e) => ({ label:
|
|
57
|
-
),
|
|
58
|
-
{ label: n("menu.moduleAll"), value:
|
|
59
|
-
...
|
|
53
|
+
const ne = (e) => e === k.Catalog ? n("menu.typeCatalog") : e === k.Menu ? n("menu.typeMenu") : n("menu.typeButton"), oe = (e) => e === k.Catalog ? "info" : "success", le = f(
|
|
54
|
+
() => g.value.map((e) => ({ label: P(e.title), value: e.id }))
|
|
55
|
+
), N = f(() => [
|
|
56
|
+
{ label: n("menu.moduleAll"), value: Y },
|
|
57
|
+
...le.value,
|
|
60
58
|
{ label: n("menu.moduleUnassigned"), value: b }
|
|
61
59
|
]);
|
|
62
|
-
function
|
|
63
|
-
return e.filter((t) => t.type !== k.Button).map((t) => ({ ...t, children:
|
|
60
|
+
function O(e) {
|
|
61
|
+
return e.filter((t) => t.type !== k.Button).map((t) => ({ ...t, children: O(t.children) }));
|
|
64
62
|
}
|
|
65
|
-
const
|
|
66
|
-
() =>
|
|
63
|
+
const D = f(
|
|
64
|
+
() => O(
|
|
67
65
|
y.value.filter(
|
|
68
|
-
(e) => a.value ===
|
|
66
|
+
(e) => a.value === Y ? !0 : a.value === b ? e.moduleId == null : e.moduleId === a.value
|
|
69
67
|
)
|
|
70
68
|
)
|
|
71
|
-
),
|
|
69
|
+
), L = f(() => {
|
|
72
70
|
const e = /* @__PURE__ */ new Map(), t = (l) => {
|
|
73
|
-
for (const
|
|
74
|
-
const
|
|
75
|
-
e.set(
|
|
76
|
-
count:
|
|
77
|
-
perms:
|
|
78
|
-
}), t(
|
|
71
|
+
for (const i of l) {
|
|
72
|
+
const r = i.children.filter((u) => u.type === k.Button);
|
|
73
|
+
e.set(i.id, {
|
|
74
|
+
count: r.length,
|
|
75
|
+
perms: r.flatMap((u) => Ue(u.permission)).join(" ").toLowerCase()
|
|
76
|
+
}), t(i.children);
|
|
79
77
|
}
|
|
80
78
|
};
|
|
81
79
|
return t(y.value), e;
|
|
82
|
-
}),
|
|
80
|
+
}), F = p(), I = () => {
|
|
83
81
|
var e;
|
|
84
|
-
return (e =
|
|
85
|
-
},
|
|
82
|
+
return (e = F.value) == null ? void 0 : e.refresh();
|
|
83
|
+
}, U = {
|
|
86
84
|
// 英文界面下表里显示的是译名,搜索要两边都认(库里存的中文原文 + 当前语言的显示名)。
|
|
87
|
-
title: (e) => `${e.title} ${
|
|
85
|
+
title: (e) => `${e.title} ${P(e.title, e.path || void 0)}`,
|
|
88
86
|
path: (e) => e.path,
|
|
89
87
|
permission: (e) => {
|
|
90
88
|
var t;
|
|
91
|
-
return (t =
|
|
89
|
+
return (t = L.value.get(e.id)) == null ? void 0 : t.perms;
|
|
92
90
|
}
|
|
93
|
-
},
|
|
94
|
-
await
|
|
95
|
-
const t =
|
|
96
|
-
return
|
|
97
|
-
};
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
let z = !1;
|
|
101
|
-
function de(e) {
|
|
91
|
+
}, $ = /* @__PURE__ */ new WeakMap(), ie = async (e) => {
|
|
92
|
+
await te();
|
|
93
|
+
const t = De(D.value, e, U);
|
|
94
|
+
return $.set(t, Le(e, U)), { items: t, total: t.length };
|
|
95
|
+
}, m = p([]), M = A([]);
|
|
96
|
+
let C = !1;
|
|
97
|
+
function re(e) {
|
|
102
98
|
M.value = e;
|
|
103
|
-
const t =
|
|
104
|
-
t ?
|
|
99
|
+
const t = $.get(ke(e)) ?? !1;
|
|
100
|
+
t ? m.value = X(e) : C && (m.value = []), C = t;
|
|
105
101
|
}
|
|
106
|
-
|
|
107
|
-
|
|
102
|
+
ve(a, () => {
|
|
103
|
+
C || (m.value = []), I();
|
|
108
104
|
});
|
|
109
|
-
const
|
|
105
|
+
const z = f(() => m.value.length > 0), ae = () => m.value = z.value ? [] : X(M.value), se = f(
|
|
110
106
|
() => {
|
|
111
107
|
var e;
|
|
112
108
|
return a.value === b ? void 0 : ((e = g.value.find((t) => t.id === a.value)) == null ? void 0 : e.apiPrefix) ?? void 0;
|
|
113
109
|
}
|
|
114
|
-
),
|
|
110
|
+
), _ = p(null), H = p(null), ue = (e) => {
|
|
115
111
|
var t;
|
|
116
|
-
return (t =
|
|
117
|
-
},
|
|
112
|
+
return (t = H.value) == null ? void 0 : t.open({ id: e.id, title: e.title });
|
|
113
|
+
}, S = () => Promise.all([I(), R()]), de = (e) => ee({
|
|
118
114
|
content: n("menu.deleteConfirm", { title: e.title }),
|
|
119
115
|
type: "error",
|
|
120
116
|
action: () => x.remove(e.id),
|
|
121
117
|
successMsg: n("menu.deleted")
|
|
122
118
|
}).then((t) => {
|
|
123
|
-
t &&
|
|
124
|
-
}),
|
|
119
|
+
t && S();
|
|
120
|
+
}), ce = ({ expanded: e }) => o(
|
|
125
121
|
"span",
|
|
126
122
|
{
|
|
127
123
|
style: `display:inline-flex;transition:transform .2s var(--ease);transform:rotate(${e ? 90 : 0}deg)`
|
|
128
124
|
},
|
|
129
|
-
o(
|
|
130
|
-
),
|
|
131
|
-
const e = /* @__PURE__ */ new Map(), t = (l,
|
|
132
|
-
l.forEach((
|
|
133
|
-
const
|
|
134
|
-
e.set(
|
|
125
|
+
o(c, { icon: "ph:caret-right", size: 14 })
|
|
126
|
+
), me = f(() => {
|
|
127
|
+
const e = /* @__PURE__ */ new Map(), t = (l, i) => {
|
|
128
|
+
l.forEach((r, u) => {
|
|
129
|
+
const G = i ? `${i}.${u + 1}` : String(u + 1);
|
|
130
|
+
e.set(r.id, G), t(r.children, G);
|
|
135
131
|
});
|
|
136
132
|
};
|
|
137
133
|
return t(M.value, ""), e;
|
|
138
|
-
}),
|
|
134
|
+
}), q = (e) => e ? o("span", { class: "mono muted" }, e) : o("span", { class: "faint" }, "—"), j = [
|
|
139
135
|
// 序号列是渲染 rowNoById 层级号的普通数据列,fixed:'left' 与标题列同锚 ——
|
|
140
136
|
// 不锚定的话,横向滚动时会滑到 fixed 的标题列底下,「这是哪一行」照样丢。
|
|
141
137
|
{
|
|
@@ -149,7 +145,7 @@ const We = { class: "view fill-page" }, b = 0, te = -1, gt = /* @__PURE__ */ ye(
|
|
|
149
145
|
card: !1,
|
|
150
146
|
// 窄档卡片以标题为首,层级号不进卡片(默认会顶替标题成为卡片首行)
|
|
151
147
|
render: (e) => {
|
|
152
|
-
const t =
|
|
148
|
+
const t = me.value.get(e.id);
|
|
153
149
|
if (!t) return null;
|
|
154
150
|
const l = t.lastIndexOf(".") + 1;
|
|
155
151
|
return o("span", { class: "row-no" }, [
|
|
@@ -161,7 +157,7 @@ const We = { class: "view fill-page" }, b = 0, te = -1, gt = /* @__PURE__ */ ye(
|
|
|
161
157
|
{
|
|
162
158
|
title: () => n("menu.title"),
|
|
163
159
|
key: "title",
|
|
164
|
-
search: { actions:
|
|
160
|
+
search: { actions: E.fuzzy },
|
|
165
161
|
align: "left",
|
|
166
162
|
// 树列左对齐,展开缩进才好读
|
|
167
163
|
// 展开箭头与每层 26px 缩进钉死在这一列。默认会落到「首个无 type 的列」= 序号列,
|
|
@@ -171,17 +167,12 @@ const We = { class: "view fill-page" }, b = 0, te = -1, gt = /* @__PURE__ */ ye(
|
|
|
171
167
|
// 让出让给缩进的宽度
|
|
172
168
|
fixed: "left",
|
|
173
169
|
// 横向滚动时不能丢失「这是哪一行」
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
// 「隐藏」是罕见状态(种子里的目录/页面全是显示),只在为真时才占视觉 —— 省掉一整列同一个词。
|
|
181
|
-
e.visible ? null : o(Z, { size: "tiny", bordered: !1, type: "warning" }, () => n("common.hidden"))
|
|
182
|
-
])
|
|
183
|
-
)
|
|
184
|
-
)
|
|
170
|
+
// inline:必须行内 —— naive 的展开箭头是 inline-flex,默认块级 NSpace 会被挤到第二行。
|
|
171
|
+
render: (e) => o(J, { inline: !0, align: "center", size: 6, wrapItem: !1 }, () => [
|
|
172
|
+
P(e.title, e.path || void 0),
|
|
173
|
+
// 「隐藏」是罕见状态(种子里的目录/页面全是显示),只在为真时才占视觉 —— 省掉一整列同一个词。
|
|
174
|
+
e.visible ? null : o(Q, { size: "tiny", bordered: !1, type: "warning" }, () => n("common.hidden"))
|
|
175
|
+
])
|
|
185
176
|
},
|
|
186
177
|
// 图标独占一列:留在标题列会和树形展开箭头 + 缩进挤在一起撑破首列换行。
|
|
187
178
|
{
|
|
@@ -189,7 +180,7 @@ const We = { class: "view fill-page" }, b = 0, te = -1, gt = /* @__PURE__ */ ye(
|
|
|
189
180
|
key: "icon",
|
|
190
181
|
width: 64,
|
|
191
182
|
align: "center",
|
|
192
|
-
render: (e) => e.icon ? o(
|
|
183
|
+
render: (e) => e.icon ? o(c, { icon: $e(e.icon), size: 18 }) : null
|
|
193
184
|
},
|
|
194
185
|
// 类型独占一列,不塞在标题里。按类型着色,目录/页面一眼可辨。
|
|
195
186
|
{
|
|
@@ -197,9 +188,9 @@ const We = { class: "view fill-page" }, b = 0, te = -1, gt = /* @__PURE__ */ ye(
|
|
|
197
188
|
key: "type",
|
|
198
189
|
width: 90,
|
|
199
190
|
render: (e) => o(
|
|
200
|
-
|
|
201
|
-
{ size: "small", bordered: !1, type:
|
|
202
|
-
() =>
|
|
191
|
+
Q,
|
|
192
|
+
{ size: "small", bordered: !1, type: oe(e.type) },
|
|
193
|
+
() => ne(e.type)
|
|
203
194
|
)
|
|
204
195
|
},
|
|
205
196
|
// 路由/组件路径:管理员核对菜单时真正要看的东西,直接列出,不必点开编辑弹窗。
|
|
@@ -211,8 +202,8 @@ const We = { class: "view fill-page" }, b = 0, te = -1, gt = /* @__PURE__ */ ye(
|
|
|
211
202
|
align: "left",
|
|
212
203
|
width: 160,
|
|
213
204
|
ellipsis: { tooltip: !0 },
|
|
214
|
-
render: (e) =>
|
|
215
|
-
search: { actions:
|
|
205
|
+
render: (e) => q(e.path),
|
|
206
|
+
search: { actions: E.fuzzy }
|
|
216
207
|
},
|
|
217
208
|
// 权限码只作搜索项:表格里不设这一列(见上),但「这个权限码归哪个页面」得能搜到 ——
|
|
218
209
|
// 取值与匹配见 SEARCH_FIELDS.permission(查该节点按钮子节点的码)。
|
|
@@ -220,7 +211,7 @@ const We = { class: "view fill-page" }, b = 0, te = -1, gt = /* @__PURE__ */ ye(
|
|
|
220
211
|
key: "permission",
|
|
221
212
|
title: () => n("menu.permission"),
|
|
222
213
|
hideInTable: !0,
|
|
223
|
-
search: { actions:
|
|
214
|
+
search: { actions: E.fuzzy }
|
|
224
215
|
},
|
|
225
216
|
{
|
|
226
217
|
title: () => n("menu.component"),
|
|
@@ -228,7 +219,7 @@ const We = { class: "view fill-page" }, b = 0, te = -1, gt = /* @__PURE__ */ ye(
|
|
|
228
219
|
align: "left",
|
|
229
220
|
width: 180,
|
|
230
221
|
ellipsis: { tooltip: !0 },
|
|
231
|
-
render: (e) =>
|
|
222
|
+
render: (e) => q(e.component)
|
|
232
223
|
},
|
|
233
224
|
{
|
|
234
225
|
title: () => n("menu.buttons"),
|
|
@@ -236,17 +227,17 @@ const We = { class: "view fill-page" }, b = 0, te = -1, gt = /* @__PURE__ */ ye(
|
|
|
236
227
|
width: 140,
|
|
237
228
|
render: (e) => {
|
|
238
229
|
var l;
|
|
239
|
-
const t = ((l =
|
|
230
|
+
const t = ((l = L.value.get(e.id)) == null ? void 0 : l.count) ?? 0;
|
|
240
231
|
return d.hasPerm("POST:/api/v1/sys/menu/add") ? o(
|
|
241
232
|
w,
|
|
242
233
|
{
|
|
243
234
|
size: "small",
|
|
244
235
|
quaternary: !0,
|
|
245
236
|
type: t > 0 ? "primary" : void 0,
|
|
246
|
-
onClick: () =>
|
|
237
|
+
onClick: () => ue(e)
|
|
247
238
|
},
|
|
248
239
|
{
|
|
249
|
-
icon: () => o(
|
|
240
|
+
icon: () => o(c, { icon: "ph:shield-check", size: 15 }),
|
|
250
241
|
default: () => n("menu.configPerms", { n: t })
|
|
251
242
|
}
|
|
252
243
|
) : null;
|
|
@@ -262,17 +253,17 @@ const We = { class: "view fill-page" }, b = 0, te = -1, gt = /* @__PURE__ */ ye(
|
|
|
262
253
|
title: () => n("common.status"),
|
|
263
254
|
key: "enabled",
|
|
264
255
|
width: 84,
|
|
265
|
-
render: (e) => o(
|
|
256
|
+
render: (e) => o(Me, {
|
|
266
257
|
value: e.enabled,
|
|
267
258
|
disabled: !d.hasPerm("PUT:/api/v1/sys/menu/{id}"),
|
|
268
259
|
// 启停走全量 update,无更新权限则置灰
|
|
269
260
|
// 停用是一键隐藏整棵子树的重操作,先确认;启用无副作用,跳过确认(返回 null)。
|
|
270
261
|
confirm: (t) => t ? null : n("menu.disableConfirm", { title: e.title }),
|
|
271
|
-
request: (t) => x.update(e.id, { ...
|
|
262
|
+
request: (t) => x.update(e.id, { ...Fe(e), enabled: t }),
|
|
272
263
|
// 重拉而非往行对象上写:搜索态下的祖先行是 filterTree 的浅拷贝,写它不会回到源树(开关会弹回去)。
|
|
273
264
|
// StatusSwitch 是悲观更新(请求成功才 emit),重拉一次就是最终态。
|
|
274
265
|
"onUpdate:value": () => {
|
|
275
|
-
|
|
266
|
+
I(), R();
|
|
276
267
|
}
|
|
277
268
|
})
|
|
278
269
|
},
|
|
@@ -283,19 +274,19 @@ const We = { class: "view fill-page" }, b = 0, te = -1, gt = /* @__PURE__ */ ye(
|
|
|
283
274
|
key: "op",
|
|
284
275
|
width: 150,
|
|
285
276
|
fixed: "right",
|
|
286
|
-
render: (e) => o(
|
|
287
|
-
const t = d.hasPerm("POST:/api/v1/sys/menu/add"), l = d.hasPerm("DELETE:/api/v1/sys/menu/{id}"),
|
|
277
|
+
render: (e) => o(J, { size: 2, wrapItem: !1, justify: "center" }, () => {
|
|
278
|
+
const t = d.hasPerm("POST:/api/v1/sys/menu/add"), l = d.hasPerm("DELETE:/api/v1/sys/menu/{id}"), i = [
|
|
288
279
|
t && {
|
|
289
280
|
key: "addChild",
|
|
290
281
|
label: n("menu.addChild"),
|
|
291
|
-
icon: () => o(
|
|
282
|
+
icon: () => o(c, { icon: "ph:plus", size: 16 })
|
|
292
283
|
},
|
|
293
284
|
// 新增与删除之间一条分隔线;只剩一项时不画
|
|
294
285
|
t && l && { type: "divider", key: "divider" },
|
|
295
286
|
l && {
|
|
296
287
|
key: "delete",
|
|
297
288
|
label: n("common.delete"),
|
|
298
|
-
icon: () => o(
|
|
289
|
+
icon: () => o(c, { icon: "ph:trash", size: 16 }),
|
|
299
290
|
props: { style: "color: var(--err)" }
|
|
300
291
|
}
|
|
301
292
|
].filter(Boolean);
|
|
@@ -307,20 +298,20 @@ const We = { class: "view fill-page" }, b = 0, te = -1, gt = /* @__PURE__ */ ye(
|
|
|
307
298
|
quaternary: !0,
|
|
308
299
|
type: "primary",
|
|
309
300
|
onClick: () => {
|
|
310
|
-
var
|
|
311
|
-
return (
|
|
301
|
+
var r;
|
|
302
|
+
return (r = _.value) == null ? void 0 : r.openEdit(e);
|
|
312
303
|
}
|
|
313
304
|
},
|
|
314
305
|
() => n("common.edit")
|
|
315
306
|
) : null,
|
|
316
|
-
|
|
317
|
-
|
|
307
|
+
i.length ? o(
|
|
308
|
+
_e,
|
|
318
309
|
{
|
|
319
310
|
trigger: "click",
|
|
320
|
-
options:
|
|
321
|
-
onSelect: (
|
|
311
|
+
options: i,
|
|
312
|
+
onSelect: (r) => {
|
|
322
313
|
var u;
|
|
323
|
-
return
|
|
314
|
+
return r === "addChild" ? (u = _.value) == null ? void 0 : u.openAdd(e.id) : de(e);
|
|
324
315
|
}
|
|
325
316
|
},
|
|
326
317
|
() => o(
|
|
@@ -328,7 +319,7 @@ const We = { class: "view fill-page" }, b = 0, te = -1, gt = /* @__PURE__ */ ye(
|
|
|
328
319
|
{ size: "small", quaternary: !0, type: "primary", iconPlacement: "right" },
|
|
329
320
|
{
|
|
330
321
|
default: () => n("common.more"),
|
|
331
|
-
icon: () => o(
|
|
322
|
+
icon: () => o(c, { icon: "ph:caret-down", size: 12 })
|
|
332
323
|
}
|
|
333
324
|
)
|
|
334
325
|
) : null
|
|
@@ -336,70 +327,69 @@ const We = { class: "view fill-page" }, b = 0, te = -1, gt = /* @__PURE__ */ ye(
|
|
|
336
327
|
})
|
|
337
328
|
}
|
|
338
329
|
];
|
|
339
|
-
return
|
|
340
|
-
const l =
|
|
341
|
-
return
|
|
342
|
-
v(s(
|
|
330
|
+
return Re(j), (e, t) => {
|
|
331
|
+
const l = he("auth");
|
|
332
|
+
return K(), ye("div", He, [
|
|
333
|
+
v(s(Te), {
|
|
343
334
|
ref_key: "tableRef",
|
|
344
|
-
ref:
|
|
345
|
-
columns:
|
|
346
|
-
fetcher:
|
|
347
|
-
loading:
|
|
335
|
+
ref: F,
|
|
336
|
+
columns: j,
|
|
337
|
+
fetcher: ie,
|
|
338
|
+
loading: T.value,
|
|
348
339
|
"row-key": "id",
|
|
349
340
|
pagination: !1,
|
|
350
341
|
search: { container: "table" },
|
|
351
|
-
toolbar: s(
|
|
342
|
+
toolbar: s(Oe),
|
|
352
343
|
"storage-key": "sys-menu",
|
|
353
344
|
indent: 26,
|
|
354
345
|
"fill-height": "",
|
|
355
|
-
"min-row-height": s(
|
|
346
|
+
"min-row-height": s(Ne),
|
|
356
347
|
"card-on-narrow": "",
|
|
357
|
-
"render-expand-icon":
|
|
358
|
-
"expanded-row-keys":
|
|
359
|
-
"onUpdate:expandedRowKeys": t[2] || (t[2] = (
|
|
360
|
-
onLoaded:
|
|
348
|
+
"render-expand-icon": ce,
|
|
349
|
+
"expanded-row-keys": m.value,
|
|
350
|
+
"onUpdate:expandedRowKeys": t[2] || (t[2] = (i) => m.value = i),
|
|
351
|
+
onLoaded: re
|
|
361
352
|
}, {
|
|
362
353
|
toolbar: h(() => [
|
|
363
|
-
v(s(
|
|
354
|
+
v(s(xe), {
|
|
364
355
|
value: a.value,
|
|
365
|
-
"onUpdate:value": t[0] || (t[0] = (
|
|
366
|
-
options:
|
|
356
|
+
"onUpdate:value": t[0] || (t[0] = (i) => a.value = i),
|
|
357
|
+
options: N.value,
|
|
367
358
|
style: { width: "200px" },
|
|
368
359
|
placeholder: s(n)("menu.module")
|
|
369
360
|
}, null, 8, ["value", "options", "placeholder"])
|
|
370
361
|
]),
|
|
371
362
|
"toolbar-right": h(() => [
|
|
372
|
-
|
|
373
|
-
key: 0,
|
|
363
|
+
v(s(w), {
|
|
374
364
|
secondary: "",
|
|
375
|
-
onClick:
|
|
365
|
+
onClick: ae
|
|
376
366
|
}, {
|
|
377
367
|
icon: h(() => [
|
|
378
|
-
v(
|
|
379
|
-
icon:
|
|
368
|
+
v(c, {
|
|
369
|
+
icon: z.value ? "ph:arrows-in-line-vertical" : "ph:arrows-out-line-vertical",
|
|
380
370
|
size: 16
|
|
381
371
|
}, null, 8, ["icon"])
|
|
382
372
|
]),
|
|
383
373
|
default: h(() => [
|
|
384
|
-
|
|
374
|
+
V(" " + W(z.value ? s(n)("common.collapseAll") : s(n)("common.expandAll")), 1)
|
|
385
375
|
]),
|
|
386
376
|
_: 1
|
|
387
|
-
})
|
|
388
|
-
|
|
377
|
+
}),
|
|
378
|
+
ge((K(), we(s(w), {
|
|
389
379
|
type: "primary",
|
|
390
|
-
onClick: t[1] || (t[1] = (
|
|
391
|
-
var
|
|
392
|
-
return (
|
|
380
|
+
onClick: t[1] || (t[1] = (i) => {
|
|
381
|
+
var r;
|
|
382
|
+
return (r = _.value) == null ? void 0 : r.openAdd(0);
|
|
393
383
|
})
|
|
394
384
|
}, {
|
|
395
385
|
icon: h(() => [
|
|
396
|
-
v(
|
|
386
|
+
v(c, {
|
|
397
387
|
icon: "ph:plus",
|
|
398
388
|
size: 16
|
|
399
389
|
})
|
|
400
390
|
]),
|
|
401
391
|
default: h(() => [
|
|
402
|
-
|
|
392
|
+
V(" " + W(s(n)("common.add")), 1)
|
|
403
393
|
]),
|
|
404
394
|
_: 1
|
|
405
395
|
})), [
|
|
@@ -408,28 +398,28 @@ const We = { class: "view fill-page" }, b = 0, te = -1, gt = /* @__PURE__ */ ye(
|
|
|
408
398
|
]),
|
|
409
399
|
_: 1
|
|
410
400
|
}, 8, ["loading", "toolbar", "min-row-height", "expanded-row-keys"]),
|
|
411
|
-
v(
|
|
401
|
+
v(ze, {
|
|
412
402
|
ref_key: "menuFormRef",
|
|
413
|
-
ref:
|
|
403
|
+
ref: _,
|
|
414
404
|
modules: g.value,
|
|
415
405
|
tree: y.value,
|
|
416
|
-
"filtered-tree":
|
|
406
|
+
"filtered-tree": D.value,
|
|
417
407
|
"module-filter": a.value,
|
|
418
|
-
onSaved:
|
|
408
|
+
onSaved: S
|
|
419
409
|
}, null, 8, ["modules", "tree", "filtered-tree", "module-filter"]),
|
|
420
|
-
v(
|
|
410
|
+
v(Ce, {
|
|
421
411
|
ref_key: "buttonMgrRef",
|
|
422
|
-
ref:
|
|
412
|
+
ref: H,
|
|
423
413
|
tree: y.value,
|
|
424
|
-
routes:
|
|
425
|
-
"app-prefix":
|
|
426
|
-
onChanged:
|
|
414
|
+
routes: B.value,
|
|
415
|
+
"app-prefix": se.value,
|
|
416
|
+
onChanged: S
|
|
427
417
|
}, null, 8, ["tree", "routes", "app-prefix"])
|
|
428
418
|
]);
|
|
429
419
|
};
|
|
430
420
|
}
|
|
431
421
|
});
|
|
432
422
|
export {
|
|
433
|
-
|
|
423
|
+
dt as default
|
|
434
424
|
};
|
|
435
425
|
//# sourceMappingURL=index2.vue.js.map
|