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
|
@@ -1,92 +1,96 @@
|
|
|
1
|
-
import { defineComponent as
|
|
2
|
-
import { NModal as F, NButton as
|
|
1
|
+
import { defineComponent as T, useModel as U, computed as c, shallowRef as D, ref as S, watch as E, openBlock as v, createBlock as G, unref as e, normalizeStyle as W, withCtx as m, createElementVNode as r, normalizeClass as x, createElementBlock as k, toDisplayString as s, createCommentVNode as M, createVNode as p, createTextVNode as b, mergeModels as A } from "vue";
|
|
2
|
+
import { NModal as F, NButton as C } from "naive-ui";
|
|
3
3
|
import { useI18n as H } from "vue-i18n";
|
|
4
4
|
import { useWindowSize as O } from "@vueuse/core";
|
|
5
5
|
import P from "./GrantMenuTable.vue.js";
|
|
6
|
-
const R = {
|
|
6
|
+
const R = {
|
|
7
|
+
key: 0,
|
|
8
|
+
class: "gs-hint"
|
|
9
|
+
}, $ = { class: "gs-summary" }, j = {
|
|
7
10
|
key: 0,
|
|
8
11
|
class: "gs-dirty"
|
|
9
|
-
},
|
|
12
|
+
}, q = 640, Y = /* @__PURE__ */ T({
|
|
10
13
|
__name: "GrantMenuSheet",
|
|
11
14
|
props: /* @__PURE__ */ A({
|
|
12
15
|
tree: {},
|
|
13
16
|
granted: {},
|
|
14
17
|
modules: {},
|
|
15
18
|
defaultModuleId: {},
|
|
19
|
+
hint: {},
|
|
16
20
|
onSave: { type: Function }
|
|
17
21
|
}, {
|
|
18
22
|
show: { type: Boolean, default: !1 },
|
|
19
23
|
showModifiers: {}
|
|
20
24
|
}),
|
|
21
25
|
emits: ["update:show"],
|
|
22
|
-
setup(
|
|
23
|
-
const
|
|
24
|
-
() =>
|
|
25
|
-
),
|
|
26
|
+
setup(t) {
|
|
27
|
+
const u = U(t, "show"), g = t, { t: a } = H(), { width: z } = O(), d = c(() => z.value <= q), N = c(
|
|
28
|
+
() => d.value ? { width: "calc(100vw - 16px)", height: "calc(100dvh - 16px)" } : { width: "min(960px, calc(100vw - 48px))", height: "min(760px, calc(100dvh - 48px))" }
|
|
29
|
+
), h = c(() => d.value ? "large" : "medium"), B = {
|
|
26
30
|
display: "flex",
|
|
27
31
|
flexDirection: "column",
|
|
28
32
|
flex: "1 1 0",
|
|
29
33
|
minHeight: "0",
|
|
30
34
|
padding: "0",
|
|
31
35
|
overflow: "hidden"
|
|
32
|
-
},
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
(
|
|
36
|
-
|
|
36
|
+
}, V = { padding: "0" }, f = D([]), o = S({ on: 0, total: 0, pages: 0, buttons: 0, dirty: !1 });
|
|
37
|
+
E(
|
|
38
|
+
u,
|
|
39
|
+
(w) => {
|
|
40
|
+
w && (f.value = g.granted);
|
|
37
41
|
},
|
|
38
42
|
{ immediate: !0 }
|
|
39
43
|
);
|
|
40
|
-
const
|
|
41
|
-
async function
|
|
42
|
-
|
|
44
|
+
const i = S(!1), y = c(() => !i.value);
|
|
45
|
+
async function I() {
|
|
46
|
+
i.value = !0;
|
|
43
47
|
try {
|
|
44
|
-
await
|
|
48
|
+
await g.onSave(f.value) !== !1 && (u.value = !1);
|
|
45
49
|
} catch {
|
|
46
50
|
} finally {
|
|
47
|
-
|
|
51
|
+
i.value = !1;
|
|
48
52
|
}
|
|
49
53
|
}
|
|
50
|
-
return (
|
|
51
|
-
show:
|
|
52
|
-
"onUpdate:show":
|
|
54
|
+
return (w, l) => (v(), G(e(F), {
|
|
55
|
+
show: u.value,
|
|
56
|
+
"onUpdate:show": l[3] || (l[3] = (n) => u.value = n),
|
|
53
57
|
preset: "card",
|
|
54
58
|
title: e(a)("role.grantMenus"),
|
|
55
59
|
closable: y.value,
|
|
56
60
|
"close-on-esc": y.value,
|
|
57
61
|
"mask-closable": !1,
|
|
58
62
|
"auto-focus": !1,
|
|
59
|
-
style:
|
|
60
|
-
"content-style":
|
|
61
|
-
"footer-style":
|
|
63
|
+
style: W(N.value),
|
|
64
|
+
"content-style": B,
|
|
65
|
+
"footer-style": V
|
|
62
66
|
}, {
|
|
63
67
|
footer: m(() => [
|
|
64
68
|
r("footer", {
|
|
65
|
-
class: x(["gs-foot", { "is-narrow":
|
|
69
|
+
class: x(["gs-foot", { "is-narrow": d.value }])
|
|
66
70
|
}, [
|
|
67
|
-
r("div",
|
|
68
|
-
r("span", null,
|
|
69
|
-
r("span", null,
|
|
70
|
-
o.value.dirty ? (
|
|
71
|
+
r("div", $, [
|
|
72
|
+
r("span", null, s(e(a)("role.grantSummary", { on: o.value.on, total: o.value.total })), 1),
|
|
73
|
+
r("span", null, s(e(a)("role.grantSummarySplit", { pages: o.value.pages, buttons: o.value.buttons })), 1),
|
|
74
|
+
o.value.dirty ? (v(), k("span", j, s(e(a)("role.grantUnsaved")), 1)) : M("", !0)
|
|
71
75
|
]),
|
|
72
|
-
|
|
73
|
-
size:
|
|
74
|
-
disabled:
|
|
75
|
-
onClick:
|
|
76
|
+
p(e(C), {
|
|
77
|
+
size: h.value,
|
|
78
|
+
disabled: i.value,
|
|
79
|
+
onClick: l[2] || (l[2] = (n) => u.value = !1)
|
|
76
80
|
}, {
|
|
77
81
|
default: m(() => [
|
|
78
|
-
|
|
82
|
+
b(s(e(a)("common.cancel")), 1)
|
|
79
83
|
]),
|
|
80
84
|
_: 1
|
|
81
85
|
}, 8, ["size", "disabled"]),
|
|
82
|
-
|
|
86
|
+
p(e(C), {
|
|
83
87
|
type: "primary",
|
|
84
|
-
size:
|
|
85
|
-
loading:
|
|
86
|
-
onClick:
|
|
88
|
+
size: h.value,
|
|
89
|
+
loading: i.value,
|
|
90
|
+
onClick: I
|
|
87
91
|
}, {
|
|
88
92
|
default: m(() => [
|
|
89
|
-
|
|
93
|
+
b(s(e(a)("common.save")), 1)
|
|
90
94
|
]),
|
|
91
95
|
_: 1
|
|
92
96
|
}, 8, ["size", "loading"])
|
|
@@ -94,16 +98,17 @@ const R = { class: "gs-summary" }, $ = {
|
|
|
94
98
|
]),
|
|
95
99
|
default: m(() => [
|
|
96
100
|
r("div", {
|
|
97
|
-
class: x(["gs", { "is-narrow":
|
|
101
|
+
class: x(["gs", { "is-narrow": d.value }])
|
|
98
102
|
}, [
|
|
99
|
-
v(
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
103
|
+
t.hint ? (v(), k("p", R, s(t.hint), 1)) : M("", !0),
|
|
104
|
+
p(P, {
|
|
105
|
+
tree: t.tree,
|
|
106
|
+
granted: t.granted,
|
|
107
|
+
modules: t.modules,
|
|
108
|
+
"default-module-id": t.defaultModuleId,
|
|
109
|
+
compact: d.value,
|
|
110
|
+
"onUpdate:checked": l[0] || (l[0] = (n) => f.value = n),
|
|
111
|
+
onSummary: l[1] || (l[1] = (n) => o.value = n)
|
|
107
112
|
}, null, 8, ["tree", "granted", "modules", "default-module-id", "compact"])
|
|
108
113
|
], 2)
|
|
109
114
|
]),
|
|
@@ -112,6 +117,6 @@ const R = { class: "gs-summary" }, $ = {
|
|
|
112
117
|
}
|
|
113
118
|
});
|
|
114
119
|
export {
|
|
115
|
-
|
|
120
|
+
Y as default
|
|
116
121
|
};
|
|
117
122
|
//# sourceMappingURL=GrantMenuSheet2.vue.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GrantMenuSheet2.vue.js","sources":["../../../../../src/views/system/role/components/GrantMenuSheet.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 授权菜单弹窗:居中卡片(窄屏近乎铺满),标题 / 工具区 / 列表 / 底栏四段。只有列表纵向滚动,\n// 底栏(已授权统计 + 取消/保存)永远在视野里 —— 不复用 FormContainer,因为它在 modal 形态下会随内容撑高,\n// 长列表会把保存钮顶出视口。弹窗定高、内容区 flex 吃满,滚动只发生在列表里。\n// onSave 协议同 FormContainer.onConfirm:返回 false 或抛错 → 不关闭;其余情况自动关。\nimport { computed, ref, shallowRef, watch, type CSSProperties } from 'vue'\nimport { NButton, NModal } from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport { useWindowSize } from '@vueuse/core'\nimport type { MenuTreeNode } from '#/types/menu'\nimport type { ModuleRow } from '#/types/api'\nimport GrantMenuTable from './GrantMenuTable.vue'\nimport type { GrantSummary } from './grantMenuGroups'\n\nconst show = defineModel<boolean>('show', { default: false })\n\nconst props = defineProps<{\n tree: MenuTreeNode[]\n granted: number[]\n modules: ModuleRow[]\n defaultModuleId: number\n onSave: (ids: number[]) => unknown | Promise<unknown>\n}>()\n\nconst { t } = useI18n()\n\n/** 窄于此宽度弹窗几乎铺满视口、控件放大一档。 */\nconst COMPACT = 640\nconst { width: winW } = useWindowSize()\nconst compact = computed(() => winW.value <= COMPACT)\n// 定高:列表再长弹窗也不超过视口;卡片是 flex 列,内容区吃剩余高度,滚动只在列表里\nconst modalStyle = computed(() =>\n compact.value\n ? { width: 'calc(100vw - 16px)', height: 'calc(100dvh - 16px)' }\n : { width: 'min(960px, calc(100vw - 48px))', height: 'min(760px, calc(100dvh - 48px))' },\n)\n// 窄屏是触屏:控件放大一档\nconst ctlSize = computed(() => (compact.value ? 'large' : 'medium'))\nconst contentStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n flex: '1 1 0',\n minHeight: '0',\n padding: '0',\n overflow: 'hidden',\n}\nconst footerStyle = { padding: '0' }\n\n// 勾选态在列表自己的 reactive 里,这里只收结果:打开时先是服务端现状,用户一改就跟着列表走\nconst checked = shallowRef<number[]>([])\nconst summary = ref<GrantSummary>({ on: 0, total: 0, pages: 0, buttons: 0, dirty: false })\nwatch(\n show,\n v => {\n if (v) checked.value = props.granted\n },\n { immediate: true },\n)\n\nconst saving = ref(false)\n// 提交中禁止任何途径关闭,防提交中途关闭导致状态错乱\nconst canClose = computed(() => !saving.value)\n\nasync function handleSave() {\n saving.value = true\n try {\n if ((await props.onSave(checked.value)) !== false) show.value = false\n } catch {\n // 静默:错误 toast 由业务 onSave 内负责\n } finally {\n saving.value = false\n }\n}\n</script>\n\n<template>\n <n-modal\n v-model:show=\"show\"\n preset=\"card\"\n :title=\"t('role.grantMenus')\"\n :closable=\"canClose\"\n :close-on-esc=\"canClose\"\n :mask-closable=\"false\"\n :auto-focus=\"false\"\n :style=\"modalStyle\"\n :content-style=\"contentStyle\"\n :footer-style=\"footerStyle\"\n >\n <div class=\"gs\" :class=\"{ 'is-narrow': compact }\">\n <GrantMenuTable\n :tree=\"tree\"\n :granted=\"granted\"\n :modules=\"modules\"\n :default-module-id=\"defaultModuleId\"\n :compact=\"compact\"\n @update:checked=\"checked = $event\"\n @summary=\"summary = $event\"\n />\n </div>\n\n <template #footer>\n <footer class=\"gs-foot\" :class=\"{ 'is-narrow': compact }\">\n <div class=\"gs-summary\">\n <span>{{ t('role.grantSummary', { on: summary.on, total: summary.total }) }}</span>\n <span>\n {{ t('role.grantSummarySplit', { pages: summary.pages, buttons: summary.buttons }) }}\n </span>\n <span v-if=\"summary.dirty\" class=\"gs-dirty\">{{ t('role.grantUnsaved') }}</span>\n </div>\n <n-button :size=\"ctlSize\" :disabled=\"saving\" @click=\"show = false\">\n {{ t('common.cancel') }}\n </n-button>\n <n-button type=\"primary\" :size=\"ctlSize\" :loading=\"saving\" @click=\"handleSave\">\n {{ t('common.save') }}\n </n-button>\n </footer>\n </template>\n </n-modal>\n</template>\n\n<style scoped>\n.gs {\n display: flex;\n flex: 1 1 0;\n flex-direction: column;\n min-height: 0;\n color: var(--text-1);\n}\n\n/* 底栏:永远可见,与列表之间一条发丝线 */\n.gs-foot {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 20px 14px;\n border-top: 1px solid var(--hairline);\n}\n.gs-summary {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 4px 12px;\n font-size: 13px;\n color: var(--text-2);\n font-variant-numeric: tabular-nums;\n}\n.gs-dirty {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: var(--warn);\n}\n.gs-dirty::before {\n content: '';\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--warn);\n}\n\n/* 窄屏:统计行独占一行,按钮等分 */\n.gs-foot.is-narrow {\n flex-wrap: wrap;\n padding: 10px 16px 14px;\n}\n.gs-foot.is-narrow .gs-summary {\n flex: 1 1 100%;\n}\n.gs-foot.is-narrow .n-button {\n flex: 1;\n}\n</style>\n"],"names":["COMPACT","show","_useModel","__props","props","t","useI18n","winW","useWindowSize","compact","computed","modalStyle","ctlSize","contentStyle","footerStyle","checked","shallowRef","summary","ref","watch","v","saving","canClose","handleSave","_createBlock","_unref","NModal","$event","_createElementVNode","_normalizeClass","
|
|
1
|
+
{"version":3,"file":"GrantMenuSheet2.vue.js","sources":["../../../../../src/views/system/role/components/GrantMenuSheet.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 授权菜单弹窗:居中卡片(窄屏近乎铺满),标题 / 工具区 / 列表 / 底栏四段。只有列表纵向滚动,\n// 底栏(已授权统计 + 取消/保存)永远在视野里 —— 不复用 FormContainer,因为它在 modal 形态下会随内容撑高,\n// 长列表会把保存钮顶出视口。弹窗定高、内容区 flex 吃满,滚动只发生在列表里。\n// onSave 协议同 FormContainer.onConfirm:返回 false 或抛错 → 不关闭;其余情况自动关。\nimport { computed, ref, shallowRef, watch, type CSSProperties } from 'vue'\nimport { NButton, NModal } from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport { useWindowSize } from '@vueuse/core'\nimport type { MenuTreeNode } from '#/types/menu'\nimport type { ModuleRow } from '#/types/api'\nimport GrantMenuTable from './GrantMenuTable.vue'\nimport type { GrantSummary } from './grantMenuGroups'\n\nconst show = defineModel<boolean>('show', { default: false })\n\nconst props = defineProps<{\n tree: MenuTreeNode[]\n granted: number[]\n modules: ModuleRow[]\n defaultModuleId: number\n /** 列表上方的一行说明(如范围限制);不给不显示 */\n hint?: string\n onSave: (ids: number[]) => unknown | Promise<unknown>\n}>()\n\nconst { t } = useI18n()\n\n/** 窄于此宽度弹窗几乎铺满视口、控件放大一档。 */\nconst COMPACT = 640\nconst { width: winW } = useWindowSize()\nconst compact = computed(() => winW.value <= COMPACT)\n// 定高:列表再长弹窗也不超过视口;卡片是 flex 列,内容区吃剩余高度,滚动只在列表里\nconst modalStyle = computed(() =>\n compact.value\n ? { width: 'calc(100vw - 16px)', height: 'calc(100dvh - 16px)' }\n : { width: 'min(960px, calc(100vw - 48px))', height: 'min(760px, calc(100dvh - 48px))' },\n)\n// 窄屏是触屏:控件放大一档\nconst ctlSize = computed(() => (compact.value ? 'large' : 'medium'))\nconst contentStyle: CSSProperties = {\n display: 'flex',\n flexDirection: 'column',\n flex: '1 1 0',\n minHeight: '0',\n padding: '0',\n overflow: 'hidden',\n}\nconst footerStyle = { padding: '0' }\n\n// 勾选态在列表自己的 reactive 里,这里只收结果:打开时先是服务端现状,用户一改就跟着列表走\nconst checked = shallowRef<number[]>([])\nconst summary = ref<GrantSummary>({ on: 0, total: 0, pages: 0, buttons: 0, dirty: false })\nwatch(\n show,\n v => {\n if (v) checked.value = props.granted\n },\n { immediate: true },\n)\n\nconst saving = ref(false)\n// 提交中禁止任何途径关闭,防提交中途关闭导致状态错乱\nconst canClose = computed(() => !saving.value)\n\nasync function handleSave() {\n saving.value = true\n try {\n if ((await props.onSave(checked.value)) !== false) show.value = false\n } catch {\n // 静默:错误 toast 由业务 onSave 内负责\n } finally {\n saving.value = false\n }\n}\n</script>\n\n<template>\n <n-modal\n v-model:show=\"show\"\n preset=\"card\"\n :title=\"t('role.grantMenus')\"\n :closable=\"canClose\"\n :close-on-esc=\"canClose\"\n :mask-closable=\"false\"\n :auto-focus=\"false\"\n :style=\"modalStyle\"\n :content-style=\"contentStyle\"\n :footer-style=\"footerStyle\"\n >\n <div class=\"gs\" :class=\"{ 'is-narrow': compact }\">\n <p v-if=\"hint\" class=\"gs-hint\">{{ hint }}</p>\n <GrantMenuTable\n :tree=\"tree\"\n :granted=\"granted\"\n :modules=\"modules\"\n :default-module-id=\"defaultModuleId\"\n :compact=\"compact\"\n @update:checked=\"checked = $event\"\n @summary=\"summary = $event\"\n />\n </div>\n\n <template #footer>\n <footer class=\"gs-foot\" :class=\"{ 'is-narrow': compact }\">\n <div class=\"gs-summary\">\n <span>{{ t('role.grantSummary', { on: summary.on, total: summary.total }) }}</span>\n <span>\n {{ t('role.grantSummarySplit', { pages: summary.pages, buttons: summary.buttons }) }}\n </span>\n <span v-if=\"summary.dirty\" class=\"gs-dirty\">{{ t('role.grantUnsaved') }}</span>\n </div>\n <n-button :size=\"ctlSize\" :disabled=\"saving\" @click=\"show = false\">\n {{ t('common.cancel') }}\n </n-button>\n <n-button type=\"primary\" :size=\"ctlSize\" :loading=\"saving\" @click=\"handleSave\">\n {{ t('common.save') }}\n </n-button>\n </footer>\n </template>\n </n-modal>\n</template>\n\n<style scoped>\n.gs {\n display: flex;\n flex: 1 1 0;\n flex-direction: column;\n min-height: 0;\n color: var(--text-1);\n}\n\n.gs-hint {\n margin: 10px 20px 0;\n font-size: 13px;\n color: var(--text-2);\n}\n\n/* 底栏:永远可见,与列表之间一条发丝线 */\n.gs-foot {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 12px 20px 14px;\n border-top: 1px solid var(--hairline);\n}\n.gs-summary {\n flex: 1;\n min-width: 0;\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n gap: 4px 12px;\n font-size: 13px;\n color: var(--text-2);\n font-variant-numeric: tabular-nums;\n}\n.gs-dirty {\n display: inline-flex;\n align-items: center;\n gap: 6px;\n color: var(--warn);\n}\n.gs-dirty::before {\n content: '';\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--warn);\n}\n\n/* 窄屏:统计行独占一行,按钮等分 */\n.gs-foot.is-narrow {\n flex-wrap: wrap;\n padding: 10px 16px 14px;\n}\n.gs-foot.is-narrow .gs-summary {\n flex: 1 1 100%;\n}\n.gs-foot.is-narrow .n-button {\n flex: 1;\n}\n</style>\n"],"names":["COMPACT","show","_useModel","__props","props","t","useI18n","winW","useWindowSize","compact","computed","modalStyle","ctlSize","contentStyle","footerStyle","checked","shallowRef","summary","ref","watch","v","saving","canClose","handleSave","_createBlock","_unref","NModal","$event","_createElementVNode","_normalizeClass","_hoisted_2","_toDisplayString","_createElementBlock","_hoisted_3","_createVNode","NButton","_hoisted_1","GrantMenuTable","_cache"],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import o from "./GrantMenuTable2.vue.js";
|
|
2
2
|
/* empty css */
|
|
3
3
|
import t from "../../../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
-
const f = /* @__PURE__ */ t(o, [["__scopeId", "data-v-
|
|
4
|
+
const f = /* @__PURE__ */ t(o, [["__scopeId", "data-v-594886fc"]]);
|
|
5
5
|
export {
|
|
6
6
|
f as default
|
|
7
7
|
};
|