smart-admin-web 10.20.1 → 10.22.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.
- package/dist/api/index.d.ts +19 -1
- package/dist/api/index.js +85 -66
- package/dist/api/index.js.map +1 -1
- package/dist/api/schema.d.ts +448 -1
- package/dist/assets/icons/ph-subset.json.js +1 -1
- package/dist/components/FormContainer/index.vue.js +87 -75
- package/dist/components/FormContainer/index.vue.js.map +1 -1
- package/dist/components/UserPicker/UserAvatar.vue.d.ts +8 -0
- package/dist/components/UserPicker/UserAvatar.vue.js +8 -0
- package/dist/components/UserPicker/UserAvatar.vue.js.map +1 -0
- package/dist/components/UserPicker/UserAvatar2.vue.js +38 -0
- package/dist/components/UserPicker/UserAvatar2.vue.js.map +1 -0
- package/dist/components/UserPicker/index.vue.js +1 -1
- package/dist/components/UserPicker/index2.vue.js +328 -186
- package/dist/components/UserPicker/index2.vue.js.map +1 -1
- package/dist/composables/authMenuRoute.d.ts +10 -0
- package/dist/composables/authMenuRoute.js +39 -23
- package/dist/composables/authMenuRoute.js.map +1 -1
- package/dist/composables/useModule.d.ts +3 -1
- package/dist/composables/useModule.js +44 -32
- package/dist/composables/useModule.js.map +1 -1
- package/dist/index.js +246 -242
- package/dist/layouts/components/SideNav.vue.js +2 -2
- package/dist/layouts/components/SideNav2.vue.js.map +1 -1
- package/dist/lib/runtime.js +1 -1
- package/dist/lib/watermark.d.ts +1 -1
- package/dist/locales/en-US.d.ts +68 -3
- package/dist/locales/en-US.js +74 -8
- package/dist/locales/en-US.js.map +1 -1
- package/dist/locales/kernelMenuTitles.js +1 -0
- package/dist/locales/kernelMenuTitles.js.map +1 -1
- package/dist/locales/zh-CN.d.ts +68 -3
- package/dist/locales/zh-CN.js +74 -8
- package/dist/locales/zh-CN.js.map +1 -1
- package/dist/router/viewRegistry.js +6 -6
- package/dist/router/viewRegistry.js.map +1 -1
- package/dist/style.css +1 -1
- package/dist/theme/naive-theme.js +80 -77
- package/dist/theme/naive-theme.js.map +1 -1
- package/dist/types/api.d.ts +91 -0
- package/dist/types/api.js +17 -15
- package/dist/types/api.js.map +1 -1
- package/dist/utils/shake.d.ts +1 -0
- package/dist/utils/shake.js +30 -0
- package/dist/utils/shake.js.map +1 -0
- package/dist/utils/tree.d.ts +15 -0
- package/dist/utils/tree.js +43 -29
- package/dist/utils/tree.js.map +1 -1
- package/dist/utils/treeCard.d.ts +6 -0
- package/dist/utils/treeCard.js +9 -0
- package/dist/utils/treeCard.js.map +1 -0
- package/dist/views/error/404.vue.js +2 -2
- package/dist/views/error/4042.vue.js +81 -24
- package/dist/views/error/4042.vue.js.map +1 -1
- package/dist/views/login/LoginForm.vue.js +2 -2
- package/dist/views/login/LoginForm2.vue.js +135 -135
- package/dist/views/login/LoginForm2.vue.js.map +1 -1
- package/dist/views/login/components/LoginDesk.vue.js +2 -2
- package/dist/views/login/components/LoginDesk2.vue.js +59 -47
- package/dist/views/login/components/LoginDesk2.vue.js.map +1 -1
- package/dist/views/login/components/LoginHeroPanel.vue.js +2 -2
- package/dist/views/login/components/LoginHeroPanel2.vue.js.map +1 -1
- package/dist/views/personal/notice2.vue.js +1 -1
- package/dist/views/personal/notice2.vue.js.map +1 -1
- package/dist/views/personal/sessions.vue.js +2 -2
- package/dist/views/personal/sessions2.vue.js +41 -40
- package/dist/views/personal/sessions2.vue.js.map +1 -1
- package/dist/views/system/ai-usage/index.vue.js +3 -3
- package/dist/views/system/ai-usage/index2.vue.js +13 -12
- package/dist/views/system/ai-usage/index2.vue.js.map +1 -1
- package/dist/views/system/config/components/AdvancedSection.vue.js +3 -3
- package/dist/views/system/config/components/AdvancedSection2.vue.js +2 -1
- package/dist/views/system/config/components/AdvancedSection2.vue.js.map +1 -1
- package/dist/views/system/dict/index.vue.js +2 -2
- package/dist/views/system/dict/index2.vue.js +12 -1
- package/dist/views/system/dict/index2.vue.js.map +1 -1
- package/dist/views/system/file/index2.vue.js +1 -0
- package/dist/views/system/file/index2.vue.js.map +1 -1
- package/dist/views/system/job/index.vue.js +3 -3
- package/dist/views/system/job/index2.vue.js +182 -181
- package/dist/views/system/job/index2.vue.js.map +1 -1
- package/dist/views/system/job-log/components/AttemptTable2.vue.js +8 -3
- package/dist/views/system/job-log/components/AttemptTable2.vue.js.map +1 -1
- package/dist/views/system/job-log/index.vue.js +1 -1
- package/dist/views/system/job-log/index2.vue.js +5 -5
- package/dist/views/system/job-log/index2.vue.js.map +1 -1
- package/dist/views/system/job-monitor/index.vue.js +2 -2
- package/dist/views/system/job-monitor/index2.vue.js +46 -46
- package/dist/views/system/job-monitor/index2.vue.js.map +1 -1
- package/dist/views/system/log/exception/index.vue.js +2 -2
- package/dist/views/system/log/exception/index2.vue.js +8 -5
- package/dist/views/system/log/exception/index2.vue.js.map +1 -1
- package/dist/views/system/log/login/index2.vue.js +21 -12
- package/dist/views/system/log/login/index2.vue.js.map +1 -1
- package/dist/views/system/log/op/index.vue.js +2 -2
- package/dist/views/system/log/op/index2.vue.js +50 -40
- package/dist/views/system/log/op/index2.vue.js.map +1 -1
- package/dist/views/system/menu/components/ButtonManager.vue.js +2 -2
- package/dist/views/system/menu/components/ButtonManager2.vue.js +45 -36
- package/dist/views/system/menu/components/ButtonManager2.vue.js.map +1 -1
- package/dist/views/system/menu/index.vue.js +1 -1
- package/dist/views/system/menu/index2.vue.js +162 -151
- package/dist/views/system/menu/index2.vue.js.map +1 -1
- package/dist/views/system/module/index.vue.js +1 -1
- package/dist/views/system/module/index2.vue.js +171 -117
- package/dist/views/system/module/index2.vue.js.map +1 -1
- package/dist/views/system/notice/index.vue.js +3 -3
- package/dist/views/system/notice/index2.vue.js +1 -0
- package/dist/views/system/notice/index2.vue.js.map +1 -1
- package/dist/views/system/org/index.vue.js +2 -2
- package/dist/views/system/org/index2.vue.js +204 -195
- package/dist/views/system/org/index2.vue.js.map +1 -1
- package/dist/views/system/position/index.vue.js +2 -2
- package/dist/views/system/position/index2.vue.js +57 -48
- package/dist/views/system/position/index2.vue.js.map +1 -1
- package/dist/views/system/recycle/index.vue.js +1 -1
- package/dist/views/system/recycle/index2.vue.js +3 -1
- package/dist/views/system/recycle/index2.vue.js.map +1 -1
- package/dist/views/system/role/components/GrantMenuSheet.vue.d.ts +2 -0
- package/dist/views/system/role/components/GrantMenuSheet.vue.js +2 -2
- package/dist/views/system/role/components/GrantMenuSheet2.vue.js +54 -49
- package/dist/views/system/role/components/GrantMenuSheet2.vue.js.map +1 -1
- package/dist/views/system/role/components/GrantMenuTable.vue.js +1 -1
- package/dist/views/system/role/components/GrantMenuTable2.vue.js +159 -195
- package/dist/views/system/role/components/GrantMenuTable2.vue.js.map +1 -1
- package/dist/views/system/role/components/grantMenuGroups.d.ts +54 -0
- package/dist/views/system/role/components/grantMenuGroups.js +116 -76
- package/dist/views/system/role/components/grantMenuGroups.js.map +1 -1
- package/dist/views/system/role/index.vue.js +2 -2
- package/dist/views/system/role/index2.vue.js +152 -145
- package/dist/views/system/role/index2.vue.js.map +1 -1
- package/dist/views/system/session/index2.vue.js +39 -35
- package/dist/views/system/session/index2.vue.js.map +1 -1
- package/dist/views/system/user/components/UserGrantEffectiveTable.vue.d.ts +10 -0
- package/dist/views/system/user/components/UserGrantEffectiveTable.vue.js +5 -0
- package/dist/views/system/user/components/UserGrantEffectiveTable.vue.js.map +1 -0
- package/dist/views/system/user/components/UserGrantEffectiveTable2.vue.js +96 -0
- package/dist/views/system/user/components/UserGrantEffectiveTable2.vue.js.map +1 -0
- package/dist/views/system/user/components/UserGrantMenuSheet.vue.d.ts +13 -0
- package/dist/views/system/user/components/UserGrantMenuSheet.vue.js +8 -0
- package/dist/views/system/user/components/UserGrantMenuSheet.vue.js.map +1 -0
- package/dist/views/system/user/components/UserGrantMenuSheet2.vue.js +216 -0
- package/dist/views/system/user/components/UserGrantMenuSheet2.vue.js.map +1 -0
- package/dist/views/system/user/components/UserGrantMenuTable.vue.d.ts +13 -0
- package/dist/views/system/user/components/UserGrantMenuTable.vue.js +8 -0
- package/dist/views/system/user/components/UserGrantMenuTable.vue.js.map +1 -0
- package/dist/views/system/user/components/UserGrantMenuTable2.vue.js +186 -0
- package/dist/views/system/user/components/UserGrantMenuTable2.vue.js.map +1 -0
- package/dist/views/system/user/components/UserGrantNodeRow.vue.d.ts +31 -0
- package/dist/views/system/user/components/UserGrantNodeRow.vue.js +8 -0
- package/dist/views/system/user/components/UserGrantNodeRow.vue.js.map +1 -0
- package/dist/views/system/user/components/UserGrantNodeRow2.vue.js +171 -0
- package/dist/views/system/user/components/UserGrantNodeRow2.vue.js.map +1 -0
- package/dist/views/system/user/components/UserGrantOverviewDrawer.vue.d.ts +21 -0
- package/dist/views/system/user/components/UserGrantOverviewDrawer.vue.js +5 -0
- package/dist/views/system/user/components/UserGrantOverviewDrawer.vue.js.map +1 -0
- package/dist/views/system/user/components/UserGrantOverviewDrawer2.vue.js +178 -0
- package/dist/views/system/user/components/UserGrantOverviewDrawer2.vue.js.map +1 -0
- package/dist/views/system/user/components/userGrantState.d.ts +64 -0
- package/dist/views/system/user/components/userGrantState.js +117 -0
- package/dist/views/system/user/components/userGrantState.js.map +1 -0
- package/dist/views/system/user/index.vue.js +2 -2
- package/dist/views/system/user/index2.vue.js +369 -295
- package/dist/views/system/user/index2.vue.js.map +1 -1
- package/package.json +3 -3
|
@@ -65,3 +65,57 @@ export declare function countGrants(groups: CatalogGroup[]): GrantCounts;
|
|
|
65
65
|
export declare function buildGroups(tree: MenuTreeNode[], grantedSet: Set<number>, anchorTitle: string): CatalogGroup[];
|
|
66
66
|
/** 勾选态 → 要提交的菜单 id:目录(全勾或半勾)、页面、按钮;anchor 行与合成组自身不算节点。 */
|
|
67
67
|
export declare function collectChecked(groups: CatalogGroup[]): number[];
|
|
68
|
+
/** 内置 system 模块的 Id(与后端 DefaultModuleSeed.BUILTIN_MODULE_ID 一致)。 */
|
|
69
|
+
export declare const SYSTEM_MODULE_ID = 1;
|
|
70
|
+
/** 内核种子菜单 Id 的上界(与后端 SmartSeedIds.KernelMax 一致):根目录 Id 超过它,就是消费者自建的。 */
|
|
71
|
+
export declare const KERNEL_MAX_ID = 999;
|
|
72
|
+
/**
|
|
73
|
+
* 是不是内置角色。只有后端明确给 false 才算非内置:字段缺省(后端版本落后)时不做任何过滤,
|
|
74
|
+
* 否则保存是全量替换,被隐藏的系统菜单 id 会从提交里消失,等于静默撤销内置角色的授权。
|
|
75
|
+
*/
|
|
76
|
+
export declare const isBuiltinRole: (role: {
|
|
77
|
+
isBuiltin?: boolean | null;
|
|
78
|
+
}) => boolean;
|
|
79
|
+
/** 放开的两个系统页面:用户管理、角色管理(与后端 DefaultMenuSeed.USER_PAGE_ID / ROLE_PAGE_ID 一致)。 */
|
|
80
|
+
export declare const USER_PAGE_ID = 230;
|
|
81
|
+
export declare const ROLE_PAGE_ID = 240;
|
|
82
|
+
/**
|
|
83
|
+
* 去掉超管专属的系统菜单:内核系统菜单里只留「用户管理」「角色管理」两个页面(整棵子树,含按钮)
|
|
84
|
+
* 和承载它们的目录(组织管理),其余一概去掉(后端同样拒绝,见 MenuTree.IsSuperAdminOnlyMenu)。
|
|
85
|
+
* 只处理内核的系统根节点;业务应用的、消费者在系统应用下自建的目录(Id 超过 KERNEL_MAX_ID)不是系统菜单,原样保留。
|
|
86
|
+
* 内核目录下不在那两个页面之下的节点(机构、岗位、直挂按钮、消费者自己加的页面)去掉,目录里一个都没剩就整个去掉;
|
|
87
|
+
* 目录节点返回新对象,不改传入的树。
|
|
88
|
+
*/
|
|
89
|
+
export declare function pruneSuperAdminOnly(tree: MenuTreeNode[]): MenuTreeNode[];
|
|
90
|
+
/**
|
|
91
|
+
* 系统菜单里除用户管理、角色管理外只能授给内置角色:非内置角色的树里去掉其余的系统菜单(后端同样拒绝)。
|
|
92
|
+
* 消费者在系统应用下自建的目录(Id 超过 KERNEL_MAX_ID)不是系统菜单,保留。
|
|
93
|
+
*/
|
|
94
|
+
export declare const treeForRole: (tree: MenuTreeNode[], builtinRole: boolean) => MenuTreeNode[];
|
|
95
|
+
/**
|
|
96
|
+
* 同上:应用下拉里去掉系统应用。visibleTree 是 treeForRole 过滤后的树,
|
|
97
|
+
* 里面还有系统应用的节点(用户管理 / 角色管理所在的目录,或消费者自建的目录)时保留系统应用,否则那些节点没有入口。
|
|
98
|
+
*/
|
|
99
|
+
export declare const modulesForRole: <T extends {
|
|
100
|
+
id: number;
|
|
101
|
+
}>(modules: T[], builtinRole: boolean, visibleTree: MenuTreeNode[]) => T[];
|
|
102
|
+
/**
|
|
103
|
+
* 已授权 id 里出现在树(含全部子孙)中的那部分,保持原顺序。
|
|
104
|
+
* 非内置角色的弹窗看不到系统自带的目录,角色身上若还留着那些授权(升级清理失败、关了种子、滚动升级窗口、
|
|
105
|
+
* 菜单被挪到内核目录下),它们不在树里;保存是全量替换,把它们原样提交会被后端以 41009 拒绝。
|
|
106
|
+
* 打开弹窗时先求交,保存提交的就只有看得见的授权,看不见的系统菜单随之收回。
|
|
107
|
+
*/
|
|
108
|
+
export declare function grantedInTree(granted: number[], tree: MenuTreeNode[]): number[];
|
|
109
|
+
/**
|
|
110
|
+
* 打开某个角色的授权弹窗时,弹窗该展示的树、应用与已授权 id。
|
|
111
|
+
* 三者必须同口径(树隐藏了系统菜单,应用下拉与已授权也要跟着收),收在一处,页面只管调用。
|
|
112
|
+
*/
|
|
113
|
+
export declare function grantScopeForRole<M extends {
|
|
114
|
+
id: number;
|
|
115
|
+
}>(role: {
|
|
116
|
+
isBuiltin?: boolean | null;
|
|
117
|
+
}, tree: MenuTreeNode[], modules: M[], granted: number[]): {
|
|
118
|
+
tree: MenuTreeNode[];
|
|
119
|
+
modules: M[];
|
|
120
|
+
granted: number[];
|
|
121
|
+
};
|
|
@@ -1,138 +1,178 @@
|
|
|
1
|
-
import { translateMenuTitle as
|
|
1
|
+
import { translateMenuTitle as l } from "../../../../locales/menuTitle.js";
|
|
2
2
|
import { MenuType as u } from "../../../../types/menu.js";
|
|
3
|
-
function f(
|
|
4
|
-
return
|
|
5
|
-
id:
|
|
6
|
-
title:
|
|
7
|
-
checked: t.has(
|
|
8
|
-
permission:
|
|
3
|
+
function f(n, t) {
|
|
4
|
+
return n.filter((e) => e.type === u.Button).map((e) => ({
|
|
5
|
+
id: e.id,
|
|
6
|
+
title: l(e.title),
|
|
7
|
+
checked: t.has(e.id),
|
|
8
|
+
permission: e.permission || void 0
|
|
9
9
|
}));
|
|
10
10
|
}
|
|
11
|
-
function
|
|
11
|
+
function a(n, t, e = "") {
|
|
12
12
|
return {
|
|
13
|
-
id:
|
|
14
|
-
title:
|
|
15
|
-
checked: t.has(
|
|
16
|
-
buttons: f(
|
|
17
|
-
path:
|
|
13
|
+
id: n.id,
|
|
14
|
+
title: e + l(n.title, n.path || void 0),
|
|
15
|
+
checked: t.has(n.id),
|
|
16
|
+
buttons: f(n.children, t),
|
|
17
|
+
path: n.path || void 0
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
-
function
|
|
20
|
+
function k(n, t, e, o = "") {
|
|
21
21
|
return {
|
|
22
|
-
id:
|
|
23
|
-
title: o +
|
|
22
|
+
id: n,
|
|
23
|
+
title: o + e,
|
|
24
24
|
checked: t.length > 0 && t.every((c) => c.checked),
|
|
25
25
|
buttons: t,
|
|
26
26
|
anchor: !0
|
|
27
27
|
};
|
|
28
28
|
}
|
|
29
|
-
function
|
|
30
|
-
const c = [], i = f(
|
|
31
|
-
i.length && c.push(
|
|
32
|
-
for (const s of
|
|
33
|
-
s.type === u.Menu ? c.push(
|
|
34
|
-
...
|
|
29
|
+
function m(n, t, e, o = "") {
|
|
30
|
+
const c = [], i = f(n.children, t);
|
|
31
|
+
i.length && c.push(k(n.id, i, e, o));
|
|
32
|
+
for (const s of n.children)
|
|
33
|
+
s.type === u.Menu ? c.push(a(s, t, o)) : s.type === u.Catalog && c.push(
|
|
34
|
+
...m(
|
|
35
35
|
s,
|
|
36
36
|
t,
|
|
37
|
-
|
|
38
|
-
`${o}${
|
|
37
|
+
e,
|
|
38
|
+
`${o}${l(s.title)} / `
|
|
39
39
|
)
|
|
40
40
|
);
|
|
41
41
|
return c;
|
|
42
42
|
}
|
|
43
|
-
function
|
|
44
|
-
return
|
|
43
|
+
function h(n) {
|
|
44
|
+
return n.flatMap((t) => t.anchor ? t.buttons : [t, ...t.buttons]);
|
|
45
45
|
}
|
|
46
|
-
function
|
|
47
|
-
const t =
|
|
46
|
+
function g(n) {
|
|
47
|
+
const t = h(n), e = t.filter((o) => o.checked).length;
|
|
48
48
|
return {
|
|
49
|
-
checked:
|
|
50
|
-
indeterminate:
|
|
49
|
+
checked: e > 0 && e === t.length,
|
|
50
|
+
indeterminate: e > 0 && e < t.length
|
|
51
51
|
};
|
|
52
52
|
}
|
|
53
|
-
function
|
|
54
|
-
Object.assign(
|
|
53
|
+
function r(n) {
|
|
54
|
+
Object.assign(n, g(n.menus));
|
|
55
55
|
}
|
|
56
|
-
function
|
|
57
|
-
for (const o of
|
|
56
|
+
function D(n, t, e = n.menus) {
|
|
57
|
+
for (const o of e) {
|
|
58
58
|
o.checked = t;
|
|
59
59
|
for (const c of o.buttons) c.checked = t;
|
|
60
60
|
}
|
|
61
|
-
|
|
61
|
+
r(n);
|
|
62
62
|
}
|
|
63
|
-
function
|
|
64
|
-
t.checked =
|
|
65
|
-
for (const o of t.buttons) o.checked =
|
|
66
|
-
|
|
63
|
+
function v(n, t, e) {
|
|
64
|
+
t.checked = e;
|
|
65
|
+
for (const o of t.buttons) o.checked = e;
|
|
66
|
+
r(n);
|
|
67
67
|
}
|
|
68
|
-
function
|
|
69
|
-
|
|
68
|
+
function A(n, t, e, o) {
|
|
69
|
+
e.checked = o;
|
|
70
70
|
const c = t.buttons.length > 0 && t.buttons.every((i) => i.checked);
|
|
71
|
-
(c || t.anchor) && (t.checked = c),
|
|
71
|
+
(c || t.anchor) && (t.checked = c), r(n);
|
|
72
72
|
}
|
|
73
|
-
function
|
|
74
|
-
const t =
|
|
75
|
-
return { on: t.filter((
|
|
73
|
+
function O(n) {
|
|
74
|
+
const t = h(n.menus);
|
|
75
|
+
return { on: t.filter((e) => e.checked).length, total: t.length };
|
|
76
76
|
}
|
|
77
|
-
function
|
|
78
|
-
return { on:
|
|
77
|
+
function P(n) {
|
|
78
|
+
return { on: n.buttons.filter((t) => t.checked).length, total: n.buttons.length };
|
|
79
79
|
}
|
|
80
|
-
function
|
|
81
|
-
let t = 0,
|
|
82
|
-
for (const i of
|
|
83
|
-
for (const s of
|
|
84
|
-
|
|
85
|
-
return { on: t, total:
|
|
80
|
+
function F(n) {
|
|
81
|
+
let t = 0, e = 0, o = 0, c = 0;
|
|
82
|
+
for (const i of n)
|
|
83
|
+
for (const s of h(i.menus))
|
|
84
|
+
e++, s.checked && (t++, "buttons" in s ? o++ : c++);
|
|
85
|
+
return { on: t, total: e, pages: o, buttons: c };
|
|
86
86
|
}
|
|
87
|
-
function
|
|
87
|
+
function L(n, t, e) {
|
|
88
88
|
const o = [];
|
|
89
|
-
for (const i of
|
|
89
|
+
for (const i of n) {
|
|
90
90
|
if (i.type === u.Button) continue;
|
|
91
|
-
const s = i.type === u.Menu ? [
|
|
91
|
+
const s = i.type === u.Menu ? [a(i, t)] : m(i, t, e), p = {
|
|
92
92
|
id: i.id,
|
|
93
|
-
title:
|
|
93
|
+
title: l(i.title, i.path || void 0),
|
|
94
94
|
checked: t.has(i.id),
|
|
95
95
|
indeterminate: !1,
|
|
96
96
|
menus: s,
|
|
97
97
|
standalone: i.type === u.Menu
|
|
98
98
|
};
|
|
99
|
-
|
|
99
|
+
r(p), o.push(p);
|
|
100
100
|
}
|
|
101
|
-
const c = f(
|
|
101
|
+
const c = f(n, t);
|
|
102
102
|
if (c.length) {
|
|
103
103
|
const i = {
|
|
104
104
|
id: 0,
|
|
105
|
-
title:
|
|
105
|
+
title: e,
|
|
106
106
|
checked: !1,
|
|
107
107
|
indeterminate: !1,
|
|
108
|
-
menus: [
|
|
108
|
+
menus: [k(0, c, e)],
|
|
109
109
|
synthetic: !0
|
|
110
110
|
};
|
|
111
|
-
|
|
111
|
+
r(i), o.push(i);
|
|
112
112
|
}
|
|
113
113
|
return o;
|
|
114
114
|
}
|
|
115
|
-
function
|
|
115
|
+
function T(n) {
|
|
116
116
|
const t = [];
|
|
117
|
-
for (const
|
|
118
|
-
!
|
|
119
|
-
for (const o of
|
|
117
|
+
for (const e of n) {
|
|
118
|
+
!e.synthetic && (e.checked || e.indeterminate) && t.push(e.id);
|
|
119
|
+
for (const o of e.menus) {
|
|
120
120
|
!o.anchor && o.checked && t.push(o.id);
|
|
121
121
|
for (const c of o.buttons) c.checked && t.push(c.id);
|
|
122
122
|
}
|
|
123
123
|
}
|
|
124
124
|
return t;
|
|
125
125
|
}
|
|
126
|
+
const d = 1, b = 999, y = (n) => n.isBuiltin !== !1, M = 230, C = 240, E = [M, C];
|
|
127
|
+
function R(n) {
|
|
128
|
+
const t = (e) => {
|
|
129
|
+
if (E.includes(e.id)) return e;
|
|
130
|
+
if (e.type !== u.Catalog) return null;
|
|
131
|
+
const o = e.children.map(t).filter((c) => c !== null);
|
|
132
|
+
return o.length ? { ...e, children: o } : null;
|
|
133
|
+
};
|
|
134
|
+
return n.flatMap((e) => {
|
|
135
|
+
if (e.moduleId !== d || e.id > b) return [e];
|
|
136
|
+
const o = t(e);
|
|
137
|
+
return o ? [o] : [];
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
const _ = (n, t) => t ? n : R(n), I = (n, t, e) => t || e.some((o) => o.moduleId === d) ? n : n.filter((o) => o.id !== d);
|
|
141
|
+
function B(n, t) {
|
|
142
|
+
const e = /* @__PURE__ */ new Set(), o = (c) => {
|
|
143
|
+
for (const i of c)
|
|
144
|
+
e.add(i.id), o(i.children);
|
|
145
|
+
};
|
|
146
|
+
return o(t), n.filter((c) => e.has(c));
|
|
147
|
+
}
|
|
148
|
+
function N(n, t, e, o) {
|
|
149
|
+
const c = y(n), i = _(t, c);
|
|
150
|
+
return {
|
|
151
|
+
tree: i,
|
|
152
|
+
modules: I(e, c, i),
|
|
153
|
+
granted: c ? o : B(o, i)
|
|
154
|
+
};
|
|
155
|
+
}
|
|
126
156
|
export {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
157
|
+
b as KERNEL_MAX_ID,
|
|
158
|
+
C as ROLE_PAGE_ID,
|
|
159
|
+
d as SYSTEM_MODULE_ID,
|
|
160
|
+
M as USER_PAGE_ID,
|
|
161
|
+
L as buildGroups,
|
|
162
|
+
T as collectChecked,
|
|
163
|
+
F as countGrants,
|
|
164
|
+
N as grantScopeForRole,
|
|
165
|
+
B as grantedInTree,
|
|
166
|
+
O as groupCount,
|
|
167
|
+
y as isBuiltinRole,
|
|
168
|
+
P as menuButtonCount,
|
|
169
|
+
g as menusState,
|
|
170
|
+
I as modulesForRole,
|
|
171
|
+
R as pruneSuperAdminOnly,
|
|
172
|
+
r as recomputeGroup,
|
|
173
|
+
A as setButtonChecked,
|
|
174
|
+
D as setGroupChecked,
|
|
175
|
+
v as setMenuChecked,
|
|
176
|
+
_ as treeForRole
|
|
137
177
|
};
|
|
138
178
|
//# sourceMappingURL=grantMenuGroups.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"grantMenuGroups.js","sources":["../../../../../src/views/system/role/components/grantMenuGroups.ts"],"sourcesContent":["// 角色授权列表的分组与勾选联动逻辑(纯函数,GrantMenuTable.vue 只管渲染)。\n// 三层:目录 → 页面 → 按钮。按钮正常挂在页面下;直接挂在目录下的按钮是\"无页面权限项\"\n//(只给移动端 / 第三方调的接口,没有对应页面),渲染成该目录组里的一行 anchor 行,否则它们勾不到。\nimport { translateMenuTitle } from '#/locales/menuTitle'\nimport { MenuType, type MenuTreeNode } from '#/types/menu'\n\nexport interface ButtonItem {\n id: number\n title: string\n checked: boolean\n /** 权限码(多条以 ; 连接),只作悬停提示,不参与勾选与提交。 */\n permission?: string\n}\nexport interface MenuRow {\n id: number\n title: string\n checked: boolean\n buttons: ButtonItem[]\n /** 页面路由,只作副标题;anchor 行没有。 */\n path?: string\n /** 无页面权限项行:承载目录直属按钮。id 是所属目录的 id,只作 key,不进 collectChecked。 */\n anchor?: boolean\n}\nexport interface CatalogGroup {\n id: number\n title: string\n checked: boolean\n indeterminate: boolean\n menus: MenuRow[]\n /** 根级直挂按钮的合成分组(id=0),自身不是可授权节点,不进 collectChecked。 */\n synthetic?: boolean\n /** 顶级页面(如工作台)自成的一组:界面上不画目录头,直接是一行。 */\n standalone?: boolean\n}\n\nfunction toButtons(nodes: MenuTreeNode[], grantedSet: Set<number>): ButtonItem[] {\n return nodes\n .filter(b => b.type === MenuType.Button)\n .map(b => ({\n id: b.id,\n title: translateMenuTitle(b.title),\n checked: grantedSet.has(b.id),\n permission: b.permission || undefined,\n }))\n}\n\nfunction toMenuRow(m: MenuTreeNode, grantedSet: Set<number>, prefix = ''): MenuRow {\n return {\n id: m.id,\n title: prefix + translateMenuTitle(m.title, m.path || undefined),\n checked: grantedSet.has(m.id),\n buttons: toButtons(m.children, grantedSet),\n path: m.path || undefined,\n }\n}\n\nfunction anchorRow(\n ownerId: number,\n buttons: ButtonItem[],\n anchorTitle: string,\n prefix = '',\n): MenuRow {\n return {\n id: ownerId,\n title: prefix + anchorTitle,\n checked: buttons.length > 0 && buttons.every(b => b.checked),\n buttons,\n anchor: true,\n }\n}\n\n/**\n * 一个目录的全部行:直属按钮 → anchor 行(有才出);直属页面 → 各一行;嵌套目录 → 递归,标题带上父目录前缀。\n */\nfunction catalogRows(\n node: MenuTreeNode,\n grantedSet: Set<number>,\n anchorTitle: string,\n prefix = '',\n): MenuRow[] {\n const rows: MenuRow[] = []\n const buttons = toButtons(node.children, grantedSet)\n if (buttons.length) rows.push(anchorRow(node.id, buttons, anchorTitle, prefix))\n for (const child of node.children) {\n if (child.type === MenuType.Menu) rows.push(toMenuRow(child, grantedSet, prefix))\n else if (child.type === MenuType.Catalog)\n rows.push(\n ...catalogRows(\n child,\n grantedSet,\n anchorTitle,\n `${prefix}${translateMenuTitle(child.title)} / `,\n ),\n )\n }\n return rows\n}\n\n/** 一个目录下的可勾选条目:页面 + 按钮;anchor 行自身不是节点,只数它的按钮。 */\nfunction rowItems(menus: MenuRow[]): (MenuRow | ButtonItem)[] {\n return menus.flatMap(m => (m.anchor ? m.buttons : [m, ...m.buttons]))\n}\n\n/** 一组行的勾选态(全勾 / 半勾)。搜索时目录头按可见行算,落库的目录状态按全部行算。 */\nexport function menusState(menus: MenuRow[]): { checked: boolean; indeterminate: boolean } {\n const items = rowItems(menus)\n const checkedCount = items.filter(x => x.checked).length\n return {\n checked: checkedCount > 0 && checkedCount === items.length,\n indeterminate: checkedCount > 0 && checkedCount < items.length,\n }\n}\n\nexport function recomputeGroup(group: CatalogGroup) {\n Object.assign(group, menusState(group.menus))\n}\n\n// ── 勾选联动 ──\n\n/** 勾/取消整个目录:其下页面与按钮一并跟随。搜索过滤时 rows 传可见行,不动被过滤掉的行。 */\nexport function setGroupChecked(group: CatalogGroup, val: boolean, rows: MenuRow[] = group.menus) {\n for (const m of rows) {\n m.checked = val\n for (const b of m.buttons) b.checked = val\n }\n recomputeGroup(group)\n}\n\n/** 勾/取消一个页面(或 anchor 行):其按钮一并跟随。 */\nexport function setMenuChecked(group: CatalogGroup, menu: MenuRow, val: boolean) {\n menu.checked = val\n for (const b of menu.buttons) b.checked = val\n recomputeGroup(group)\n}\n\n/**\n * 勾/取消一个按钮。按钮全勾时顺手把页面勾上;页面已勾时取消单个按钮不回收页面权限\n * (页面权限与按钮权限各自授予)。anchor 行自身不是节点,勾选态就等于「按钮是否全勾」。\n */\nexport function setButtonChecked(\n group: CatalogGroup,\n menu: MenuRow,\n button: ButtonItem,\n val: boolean,\n) {\n button.checked = val\n const allChecked = menu.buttons.length > 0 && menu.buttons.every(b => b.checked)\n if (allChecked || menu.anchor) menu.checked = allChecked\n recomputeGroup(group)\n}\n\n// ── 计数(仅用于展示) ──\n\nexport interface Count {\n on: number\n total: number\n}\n\nexport function groupCount(group: Pick<CatalogGroup, 'menus'>): Count {\n const items = rowItems(group.menus)\n return { on: items.filter(x => x.checked).length, total: items.length }\n}\n\nexport function menuButtonCount(menu: MenuRow): Count {\n return { on: menu.buttons.filter(b => b.checked).length, total: menu.buttons.length }\n}\n\n/** 全部分组的授权概况:on / total 含页面与按钮;pages / buttons 是已授权的两类各多少。 */\nexport type GrantCounts = Count & { pages: number; buttons: number }\n\n/** 授权列表对外汇报的概况:计数 + 相对打开时是否有未保存的改动。 */\nexport type GrantSummary = GrantCounts & { dirty: boolean }\n\nexport function countGrants(groups: CatalogGroup[]): GrantCounts {\n let on = 0\n let total = 0\n let pages = 0\n let buttons = 0\n for (const g of groups) {\n for (const item of rowItems(g.menus)) {\n total++\n if (!item.checked) continue\n on++\n if ('buttons' in item) pages++\n else buttons++\n }\n }\n return { on, total, pages, buttons }\n}\n\n/**\n * 顶层节点 → 分组。顶级页面(如工作台)自成一组;顶级目录一组;根级直挂按钮并进一个合成组。\n * @param anchorTitle 无页面权限项行的显示文案(i18n 由调用方给)\n */\nexport function buildGroups(\n tree: MenuTreeNode[],\n grantedSet: Set<number>,\n anchorTitle: string,\n): CatalogGroup[] {\n const groups: CatalogGroup[] = []\n for (const node of tree) {\n if (node.type === MenuType.Button) continue\n const menus =\n node.type === MenuType.Menu\n ? [toMenuRow(node, grantedSet)]\n : catalogRows(node, grantedSet, anchorTitle)\n const group: CatalogGroup = {\n id: node.id,\n title: translateMenuTitle(node.title, node.path || undefined),\n checked: grantedSet.has(node.id),\n indeterminate: false,\n menus,\n standalone: node.type === MenuType.Menu,\n }\n recomputeGroup(group)\n groups.push(group)\n }\n const rootButtons = toButtons(tree, grantedSet)\n if (rootButtons.length) {\n const group: CatalogGroup = {\n id: 0,\n title: anchorTitle,\n checked: false,\n indeterminate: false,\n menus: [anchorRow(0, rootButtons, anchorTitle)],\n synthetic: true,\n }\n recomputeGroup(group)\n groups.push(group)\n }\n return groups\n}\n\n/** 勾选态 → 要提交的菜单 id:目录(全勾或半勾)、页面、按钮;anchor 行与合成组自身不算节点。 */\nexport function collectChecked(groups: CatalogGroup[]): number[] {\n const ids: number[] = []\n for (const g of groups) {\n if (!g.synthetic && (g.checked || g.indeterminate)) ids.push(g.id)\n for (const m of g.menus) {\n if (!m.anchor && m.checked) ids.push(m.id)\n for (const b of m.buttons) if (b.checked) ids.push(b.id)\n }\n }\n return ids\n}\n"],"names":["toButtons","nodes","grantedSet","b","MenuType","translateMenuTitle","toMenuRow","m","prefix","anchorRow","ownerId","buttons","anchorTitle","catalogRows","node","rows","child","rowItems","menus","menusState","items","checkedCount","x","recomputeGroup","group","setGroupChecked","val","setMenuChecked","menu","setButtonChecked","button","allChecked","groupCount","menuButtonCount","countGrants","groups","on","total","pages","g","item","buildGroups","tree","rootButtons","collectChecked","ids"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"grantMenuGroups.js","sources":["../../../../../src/views/system/role/components/grantMenuGroups.ts"],"sourcesContent":["// 角色授权列表的分组与勾选联动逻辑(纯函数,GrantMenuTable.vue 只管渲染)。\n// 三层:目录 → 页面 → 按钮。按钮正常挂在页面下;直接挂在目录下的按钮是\"无页面权限项\"\n//(只给移动端 / 第三方调的接口,没有对应页面),渲染成该目录组里的一行 anchor 行,否则它们勾不到。\nimport { translateMenuTitle } from '#/locales/menuTitle'\nimport { MenuType, type MenuTreeNode } from '#/types/menu'\n\nexport interface ButtonItem {\n id: number\n title: string\n checked: boolean\n /** 权限码(多条以 ; 连接),只作悬停提示,不参与勾选与提交。 */\n permission?: string\n}\nexport interface MenuRow {\n id: number\n title: string\n checked: boolean\n buttons: ButtonItem[]\n /** 页面路由,只作副标题;anchor 行没有。 */\n path?: string\n /** 无页面权限项行:承载目录直属按钮。id 是所属目录的 id,只作 key,不进 collectChecked。 */\n anchor?: boolean\n}\nexport interface CatalogGroup {\n id: number\n title: string\n checked: boolean\n indeterminate: boolean\n menus: MenuRow[]\n /** 根级直挂按钮的合成分组(id=0),自身不是可授权节点,不进 collectChecked。 */\n synthetic?: boolean\n /** 顶级页面(如工作台)自成的一组:界面上不画目录头,直接是一行。 */\n standalone?: boolean\n}\n\nfunction toButtons(nodes: MenuTreeNode[], grantedSet: Set<number>): ButtonItem[] {\n return nodes\n .filter(b => b.type === MenuType.Button)\n .map(b => ({\n id: b.id,\n title: translateMenuTitle(b.title),\n checked: grantedSet.has(b.id),\n permission: b.permission || undefined,\n }))\n}\n\nfunction toMenuRow(m: MenuTreeNode, grantedSet: Set<number>, prefix = ''): MenuRow {\n return {\n id: m.id,\n title: prefix + translateMenuTitle(m.title, m.path || undefined),\n checked: grantedSet.has(m.id),\n buttons: toButtons(m.children, grantedSet),\n path: m.path || undefined,\n }\n}\n\nfunction anchorRow(\n ownerId: number,\n buttons: ButtonItem[],\n anchorTitle: string,\n prefix = '',\n): MenuRow {\n return {\n id: ownerId,\n title: prefix + anchorTitle,\n checked: buttons.length > 0 && buttons.every(b => b.checked),\n buttons,\n anchor: true,\n }\n}\n\n/**\n * 一个目录的全部行:直属按钮 → anchor 行(有才出);直属页面 → 各一行;嵌套目录 → 递归,标题带上父目录前缀。\n */\nfunction catalogRows(\n node: MenuTreeNode,\n grantedSet: Set<number>,\n anchorTitle: string,\n prefix = '',\n): MenuRow[] {\n const rows: MenuRow[] = []\n const buttons = toButtons(node.children, grantedSet)\n if (buttons.length) rows.push(anchorRow(node.id, buttons, anchorTitle, prefix))\n for (const child of node.children) {\n if (child.type === MenuType.Menu) rows.push(toMenuRow(child, grantedSet, prefix))\n else if (child.type === MenuType.Catalog)\n rows.push(\n ...catalogRows(\n child,\n grantedSet,\n anchorTitle,\n `${prefix}${translateMenuTitle(child.title)} / `,\n ),\n )\n }\n return rows\n}\n\n/** 一个目录下的可勾选条目:页面 + 按钮;anchor 行自身不是节点,只数它的按钮。 */\nfunction rowItems(menus: MenuRow[]): (MenuRow | ButtonItem)[] {\n return menus.flatMap(m => (m.anchor ? m.buttons : [m, ...m.buttons]))\n}\n\n/** 一组行的勾选态(全勾 / 半勾)。搜索时目录头按可见行算,落库的目录状态按全部行算。 */\nexport function menusState(menus: MenuRow[]): { checked: boolean; indeterminate: boolean } {\n const items = rowItems(menus)\n const checkedCount = items.filter(x => x.checked).length\n return {\n checked: checkedCount > 0 && checkedCount === items.length,\n indeterminate: checkedCount > 0 && checkedCount < items.length,\n }\n}\n\nexport function recomputeGroup(group: CatalogGroup) {\n Object.assign(group, menusState(group.menus))\n}\n\n// ── 勾选联动 ──\n\n/** 勾/取消整个目录:其下页面与按钮一并跟随。搜索过滤时 rows 传可见行,不动被过滤掉的行。 */\nexport function setGroupChecked(group: CatalogGroup, val: boolean, rows: MenuRow[] = group.menus) {\n for (const m of rows) {\n m.checked = val\n for (const b of m.buttons) b.checked = val\n }\n recomputeGroup(group)\n}\n\n/** 勾/取消一个页面(或 anchor 行):其按钮一并跟随。 */\nexport function setMenuChecked(group: CatalogGroup, menu: MenuRow, val: boolean) {\n menu.checked = val\n for (const b of menu.buttons) b.checked = val\n recomputeGroup(group)\n}\n\n/**\n * 勾/取消一个按钮。按钮全勾时顺手把页面勾上;页面已勾时取消单个按钮不回收页面权限\n * (页面权限与按钮权限各自授予)。anchor 行自身不是节点,勾选态就等于「按钮是否全勾」。\n */\nexport function setButtonChecked(\n group: CatalogGroup,\n menu: MenuRow,\n button: ButtonItem,\n val: boolean,\n) {\n button.checked = val\n const allChecked = menu.buttons.length > 0 && menu.buttons.every(b => b.checked)\n if (allChecked || menu.anchor) menu.checked = allChecked\n recomputeGroup(group)\n}\n\n// ── 计数(仅用于展示) ──\n\nexport interface Count {\n on: number\n total: number\n}\n\nexport function groupCount(group: Pick<CatalogGroup, 'menus'>): Count {\n const items = rowItems(group.menus)\n return { on: items.filter(x => x.checked).length, total: items.length }\n}\n\nexport function menuButtonCount(menu: MenuRow): Count {\n return { on: menu.buttons.filter(b => b.checked).length, total: menu.buttons.length }\n}\n\n/** 全部分组的授权概况:on / total 含页面与按钮;pages / buttons 是已授权的两类各多少。 */\nexport type GrantCounts = Count & { pages: number; buttons: number }\n\n/** 授权列表对外汇报的概况:计数 + 相对打开时是否有未保存的改动。 */\nexport type GrantSummary = GrantCounts & { dirty: boolean }\n\nexport function countGrants(groups: CatalogGroup[]): GrantCounts {\n let on = 0\n let total = 0\n let pages = 0\n let buttons = 0\n for (const g of groups) {\n for (const item of rowItems(g.menus)) {\n total++\n if (!item.checked) continue\n on++\n if ('buttons' in item) pages++\n else buttons++\n }\n }\n return { on, total, pages, buttons }\n}\n\n/**\n * 顶层节点 → 分组。顶级页面(如工作台)自成一组;顶级目录一组;根级直挂按钮并进一个合成组。\n * @param anchorTitle 无页面权限项行的显示文案(i18n 由调用方给)\n */\nexport function buildGroups(\n tree: MenuTreeNode[],\n grantedSet: Set<number>,\n anchorTitle: string,\n): CatalogGroup[] {\n const groups: CatalogGroup[] = []\n for (const node of tree) {\n if (node.type === MenuType.Button) continue\n const menus =\n node.type === MenuType.Menu\n ? [toMenuRow(node, grantedSet)]\n : catalogRows(node, grantedSet, anchorTitle)\n const group: CatalogGroup = {\n id: node.id,\n title: translateMenuTitle(node.title, node.path || undefined),\n checked: grantedSet.has(node.id),\n indeterminate: false,\n menus,\n standalone: node.type === MenuType.Menu,\n }\n recomputeGroup(group)\n groups.push(group)\n }\n const rootButtons = toButtons(tree, grantedSet)\n if (rootButtons.length) {\n const group: CatalogGroup = {\n id: 0,\n title: anchorTitle,\n checked: false,\n indeterminate: false,\n menus: [anchorRow(0, rootButtons, anchorTitle)],\n synthetic: true,\n }\n recomputeGroup(group)\n groups.push(group)\n }\n return groups\n}\n\n/** 勾选态 → 要提交的菜单 id:目录(全勾或半勾)、页面、按钮;anchor 行与合成组自身不算节点。 */\nexport function collectChecked(groups: CatalogGroup[]): number[] {\n const ids: number[] = []\n for (const g of groups) {\n if (!g.synthetic && (g.checked || g.indeterminate)) ids.push(g.id)\n for (const m of g.menus) {\n if (!m.anchor && m.checked) ids.push(m.id)\n for (const b of m.buttons) if (b.checked) ids.push(b.id)\n }\n }\n return ids\n}\n\n// ── 角色授权范围 ──\n\n/** 内置 system 模块的 Id(与后端 DefaultModuleSeed.BUILTIN_MODULE_ID 一致)。 */\nexport const SYSTEM_MODULE_ID = 1\n\n/** 内核种子菜单 Id 的上界(与后端 SmartSeedIds.KernelMax 一致):根目录 Id 超过它,就是消费者自建的。 */\nexport const KERNEL_MAX_ID = 999\n\n/**\n * 是不是内置角色。只有后端明确给 false 才算非内置:字段缺省(后端版本落后)时不做任何过滤,\n * 否则保存是全量替换,被隐藏的系统菜单 id 会从提交里消失,等于静默撤销内置角色的授权。\n */\nexport const isBuiltinRole = (role: { isBuiltin?: boolean | null }): boolean =>\n role.isBuiltin !== false\n\n/** 放开的两个系统页面:用户管理、角色管理(与后端 DefaultMenuSeed.USER_PAGE_ID / ROLE_PAGE_ID 一致)。 */\nexport const USER_PAGE_ID = 230\nexport const ROLE_PAGE_ID = 240\nconst OPEN_PAGE_IDS: readonly number[] = [USER_PAGE_ID, ROLE_PAGE_ID]\n\n/**\n * 去掉超管专属的系统菜单:内核系统菜单里只留「用户管理」「角色管理」两个页面(整棵子树,含按钮)\n * 和承载它们的目录(组织管理),其余一概去掉(后端同样拒绝,见 MenuTree.IsSuperAdminOnlyMenu)。\n * 只处理内核的系统根节点;业务应用的、消费者在系统应用下自建的目录(Id 超过 KERNEL_MAX_ID)不是系统菜单,原样保留。\n * 内核目录下不在那两个页面之下的节点(机构、岗位、直挂按钮、消费者自己加的页面)去掉,目录里一个都没剩就整个去掉;\n * 目录节点返回新对象,不改传入的树。\n */\nexport function pruneSuperAdminOnly(tree: MenuTreeNode[]): MenuTreeNode[] {\n const keep = (n: MenuTreeNode): MenuTreeNode | null => {\n if (OPEN_PAGE_IDS.includes(n.id)) return n\n if (n.type !== MenuType.Catalog) return null\n const children = n.children.map(keep).filter((c): c is MenuTreeNode => c !== null)\n return children.length ? { ...n, children } : null\n }\n return tree.flatMap(n => {\n if (n.moduleId !== SYSTEM_MODULE_ID || n.id > KERNEL_MAX_ID) return [n]\n const kept = keep(n)\n return kept ? [kept] : []\n })\n}\n\n/**\n * 系统菜单里除用户管理、角色管理外只能授给内置角色:非内置角色的树里去掉其余的系统菜单(后端同样拒绝)。\n * 消费者在系统应用下自建的目录(Id 超过 KERNEL_MAX_ID)不是系统菜单,保留。\n */\nexport const treeForRole = (tree: MenuTreeNode[], builtinRole: boolean): MenuTreeNode[] =>\n builtinRole ? tree : pruneSuperAdminOnly(tree)\n\n/**\n * 同上:应用下拉里去掉系统应用。visibleTree 是 treeForRole 过滤后的树,\n * 里面还有系统应用的节点(用户管理 / 角色管理所在的目录,或消费者自建的目录)时保留系统应用,否则那些节点没有入口。\n */\nexport const modulesForRole = <T extends { id: number }>(\n modules: T[],\n builtinRole: boolean,\n visibleTree: MenuTreeNode[],\n): T[] =>\n builtinRole || visibleTree.some(n => n.moduleId === SYSTEM_MODULE_ID)\n ? modules\n : modules.filter(m => m.id !== SYSTEM_MODULE_ID)\n\n/**\n * 已授权 id 里出现在树(含全部子孙)中的那部分,保持原顺序。\n * 非内置角色的弹窗看不到系统自带的目录,角色身上若还留着那些授权(升级清理失败、关了种子、滚动升级窗口、\n * 菜单被挪到内核目录下),它们不在树里;保存是全量替换,把它们原样提交会被后端以 41009 拒绝。\n * 打开弹窗时先求交,保存提交的就只有看得见的授权,看不见的系统菜单随之收回。\n */\nexport function grantedInTree(granted: number[], tree: MenuTreeNode[]): number[] {\n const inTree = new Set<number>()\n const walk = (nodes: MenuTreeNode[]) => {\n for (const n of nodes) {\n inTree.add(n.id)\n walk(n.children)\n }\n }\n walk(tree)\n return granted.filter(id => inTree.has(id))\n}\n\n/**\n * 打开某个角色的授权弹窗时,弹窗该展示的树、应用与已授权 id。\n * 三者必须同口径(树隐藏了系统菜单,应用下拉与已授权也要跟着收),收在一处,页面只管调用。\n */\nexport function grantScopeForRole<M extends { id: number }>(\n role: { isBuiltin?: boolean | null },\n tree: MenuTreeNode[],\n modules: M[],\n granted: number[],\n): { tree: MenuTreeNode[]; modules: M[]; granted: number[] } {\n const builtin = isBuiltinRole(role)\n const visibleTree = treeForRole(tree, builtin)\n return {\n tree: visibleTree,\n modules: modulesForRole(modules, builtin, visibleTree),\n granted: builtin ? granted : grantedInTree(granted, visibleTree),\n }\n}\n"],"names":["toButtons","nodes","grantedSet","b","MenuType","translateMenuTitle","toMenuRow","m","prefix","anchorRow","ownerId","buttons","anchorTitle","catalogRows","node","rows","child","rowItems","menus","menusState","items","checkedCount","x","recomputeGroup","group","setGroupChecked","val","setMenuChecked","menu","setButtonChecked","button","allChecked","groupCount","menuButtonCount","countGrants","groups","on","total","pages","g","item","buildGroups","tree","rootButtons","collectChecked","ids","SYSTEM_MODULE_ID","KERNEL_MAX_ID","isBuiltinRole","role","USER_PAGE_ID","ROLE_PAGE_ID","OPEN_PAGE_IDS","pruneSuperAdminOnly","keep","n","children","kept","treeForRole","builtinRole","modulesForRole","modules","visibleTree","grantedInTree","granted","inTree","walk","id","grantScopeForRole","builtin"],"mappings":"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"}
|
|
@@ -1,8 +1,8 @@
|
|
|
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
|
|
4
|
+
const _ = /* @__PURE__ */ t(o, [["__scopeId", "data-v-66223499"]]);
|
|
5
5
|
export {
|
|
6
|
-
|
|
6
|
+
_ as default
|
|
7
7
|
};
|
|
8
8
|
//# sourceMappingURL=index.vue.js.map
|