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
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
import { defineComponent as le, ref as g, shallowRef as G, reactive as ne, computed as d, openBlock as m, createBlock as M, unref as a, normalizeStyle as se, withCtx as o, createVNode as f, createElementBlock as O, createElementVNode as h, createTextVNode as N, toDisplayString as v, createCommentVNode as w, normalizeClass as oe } from "vue";
|
|
2
|
+
import { useMessage as re, NModal as ue, NSpin as ie, NAlert as B, NTabs as ce, NTabPane as U, NButton as V } from "naive-ui";
|
|
3
|
+
import { useI18n as de } from "vue-i18n";
|
|
4
|
+
import { useWindowSize as fe } from "@vueuse/core";
|
|
5
|
+
import { menuApi as ve, userApi as D } from "../../../../api/index.js";
|
|
6
|
+
import { useAuthStore as me } from "../../../../stores/auth.js";
|
|
7
|
+
import { translateError as z } from "../../../../utils/error.js";
|
|
8
|
+
import pe from "./UserGrantMenuTable.vue.js";
|
|
9
|
+
import ye from "./UserGrantEffectiveTable2.vue.js";
|
|
10
|
+
import { expiryLimit as ge, countDraft as he, diffDraft as I, READONLY_REASON_KEYS as we, draftFromGrants as P, invalidExpiry as _e } from "./userGrantState.js";
|
|
11
|
+
const be = {
|
|
12
|
+
key: 0,
|
|
13
|
+
class: "ugs"
|
|
14
|
+
}, xe = { class: "ugs-notes" }, Ge = { class: "ugs-hint" }, Me = { class: "ugs-summary" }, Ne = {
|
|
15
|
+
key: 0,
|
|
16
|
+
class: "ugs-dirty"
|
|
17
|
+
}, ke = 640, ze = /* @__PURE__ */ le({
|
|
18
|
+
__name: "UserGrantMenuSheet",
|
|
19
|
+
emits: ["saved"],
|
|
20
|
+
setup(Ee, { expose: q, emit: L }) {
|
|
21
|
+
const W = L, { t: n } = de(), _ = re(), Y = me(), u = g(!1), k = g(!1), i = g(!1), E = g("grant"), p = g(null), b = G([]), S = G([]), s = G(null), y = G(/* @__PURE__ */ new Map()), c = ne(/* @__PURE__ */ new Map());
|
|
22
|
+
let x = 0;
|
|
23
|
+
const { width: $ } = fe(), R = d(() => $.value <= ke), F = d(
|
|
24
|
+
() => R.value ? { width: "calc(100vw - 16px)", height: "calc(100dvh - 16px)" } : { width: "min(1040px, calc(100vw - 48px))", height: "min(780px, calc(100dvh - 48px))" }
|
|
25
|
+
), H = {
|
|
26
|
+
display: "flex",
|
|
27
|
+
flexDirection: "column",
|
|
28
|
+
flex: "1 1 0",
|
|
29
|
+
minHeight: "0",
|
|
30
|
+
padding: "0",
|
|
31
|
+
overflow: "hidden"
|
|
32
|
+
}, K = { padding: "0" }, A = d(() => ge(s.value, /* @__PURE__ */ new Date())), j = d(() => he(c)), J = d(() => {
|
|
33
|
+
const t = I(y.value, c);
|
|
34
|
+
return t.upserts.length + t.removes.length > 0;
|
|
35
|
+
}), T = d(() => {
|
|
36
|
+
const t = s.value;
|
|
37
|
+
if (!t || t.targetEditable) return "";
|
|
38
|
+
const e = t.readOnlyReason != null ? we[t.readOnlyReason] : void 0;
|
|
39
|
+
return e ? n("userGrant.readonly", { reason: n(e) }) : n("userGrant.readonlyNoReason");
|
|
40
|
+
}), Q = d(() => {
|
|
41
|
+
var l, r;
|
|
42
|
+
const t = ((l = s.value) == null ? void 0 : l.modules) ?? [], e = Y.currentModuleId;
|
|
43
|
+
return e != null && t.some((C) => C.id === e) ? e : ((r = t[0]) == null ? void 0 : r.id) ?? 0;
|
|
44
|
+
});
|
|
45
|
+
function X() {
|
|
46
|
+
b.value = [], S.value = [], y.value = /* @__PURE__ */ new Map(), c.clear(), s.value = null;
|
|
47
|
+
}
|
|
48
|
+
async function Z(t) {
|
|
49
|
+
const e = ++x;
|
|
50
|
+
p.value = t, E.value = "grant", X(), u.value = !0, k.value = !0;
|
|
51
|
+
try {
|
|
52
|
+
const [l, r, C] = await Promise.all([
|
|
53
|
+
ve.tree(),
|
|
54
|
+
D.getMenuGrants(t.id),
|
|
55
|
+
D.getEffectiveMenus(t.id)
|
|
56
|
+
]);
|
|
57
|
+
if (e !== x) return;
|
|
58
|
+
b.value = l, S.value = r, y.value = P(r);
|
|
59
|
+
for (const [te, ae] of P(r)) c.set(te, ae);
|
|
60
|
+
s.value = C;
|
|
61
|
+
} catch (l) {
|
|
62
|
+
if (e !== x) return;
|
|
63
|
+
_.error(z(l)), u.value = !1;
|
|
64
|
+
} finally {
|
|
65
|
+
e === x && (k.value = !1);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
async function ee() {
|
|
69
|
+
if (i.value || !p.value) return;
|
|
70
|
+
const t = _e(y.value, c, A.value, /* @__PURE__ */ new Date());
|
|
71
|
+
if (t.length) {
|
|
72
|
+
_.warning(n("userGrant.invalidExpiry", { count: t.length }));
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const { upserts: e, removes: l } = I(y.value, c);
|
|
76
|
+
if (!e.length && !l.length) {
|
|
77
|
+
u.value = !1;
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
i.value = !0;
|
|
81
|
+
try {
|
|
82
|
+
await D.setMenuGrants(p.value.id, e, l), _.success(n("userGrant.saved")), u.value = !1, W("saved");
|
|
83
|
+
} catch (r) {
|
|
84
|
+
_.error(z(r));
|
|
85
|
+
} finally {
|
|
86
|
+
i.value = !1;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return q({ open: Z }), (t, e) => (m(), M(a(ue), {
|
|
90
|
+
show: u.value,
|
|
91
|
+
"onUpdate:show": e[2] || (e[2] = (l) => u.value = l),
|
|
92
|
+
preset: "card",
|
|
93
|
+
title: p.value ? a(n)("userGrant.title", { name: p.value.name }) : "",
|
|
94
|
+
closable: !i.value,
|
|
95
|
+
"close-on-esc": !i.value,
|
|
96
|
+
"mask-closable": !1,
|
|
97
|
+
"auto-focus": !1,
|
|
98
|
+
style: se(F.value),
|
|
99
|
+
"content-style": H,
|
|
100
|
+
"footer-style": K
|
|
101
|
+
}, {
|
|
102
|
+
footer: o(() => {
|
|
103
|
+
var l;
|
|
104
|
+
return [
|
|
105
|
+
h("footer", {
|
|
106
|
+
class: oe(["ugs-foot", { "is-narrow": R.value }])
|
|
107
|
+
}, [
|
|
108
|
+
h("div", Me, [
|
|
109
|
+
h("span", null, v(a(n)("userGrant.summary", j.value)), 1),
|
|
110
|
+
J.value ? (m(), O("span", Ne, v(a(n)("userGrant.unsaved")), 1)) : w("", !0)
|
|
111
|
+
]),
|
|
112
|
+
f(a(V), {
|
|
113
|
+
disabled: i.value,
|
|
114
|
+
onClick: e[1] || (e[1] = (r) => u.value = !1)
|
|
115
|
+
}, {
|
|
116
|
+
default: o(() => [
|
|
117
|
+
N(v(a(n)("common.cancel")), 1)
|
|
118
|
+
]),
|
|
119
|
+
_: 1
|
|
120
|
+
}, 8, ["disabled"]),
|
|
121
|
+
(l = s.value) != null && l.targetEditable ? (m(), M(a(V), {
|
|
122
|
+
key: 0,
|
|
123
|
+
type: "primary",
|
|
124
|
+
loading: i.value,
|
|
125
|
+
onClick: ee
|
|
126
|
+
}, {
|
|
127
|
+
default: o(() => [
|
|
128
|
+
N(v(a(n)("common.save")), 1)
|
|
129
|
+
]),
|
|
130
|
+
_: 1
|
|
131
|
+
}, 8, ["loading"])) : w("", !0)
|
|
132
|
+
], 2)
|
|
133
|
+
];
|
|
134
|
+
}),
|
|
135
|
+
default: o(() => [
|
|
136
|
+
f(a(ie), {
|
|
137
|
+
show: k.value,
|
|
138
|
+
class: "ugs-spin"
|
|
139
|
+
}, {
|
|
140
|
+
default: o(() => [
|
|
141
|
+
s.value ? (m(), O("div", be, [
|
|
142
|
+
h("div", xe, [
|
|
143
|
+
T.value ? (m(), M(a(B), {
|
|
144
|
+
key: 0,
|
|
145
|
+
type: "warning",
|
|
146
|
+
bordered: !1
|
|
147
|
+
}, {
|
|
148
|
+
default: o(() => [
|
|
149
|
+
N(v(T.value), 1)
|
|
150
|
+
]),
|
|
151
|
+
_: 1
|
|
152
|
+
})) : w("", !0),
|
|
153
|
+
s.value.hasRoles ? w("", !0) : (m(), M(a(B), {
|
|
154
|
+
key: 1,
|
|
155
|
+
type: "info",
|
|
156
|
+
bordered: !1
|
|
157
|
+
}, {
|
|
158
|
+
default: o(() => [
|
|
159
|
+
N(v(a(n)("userGrant.noRoles")), 1)
|
|
160
|
+
]),
|
|
161
|
+
_: 1
|
|
162
|
+
})),
|
|
163
|
+
h("p", Ge, v(a(n)("userGrant.hint")), 1)
|
|
164
|
+
]),
|
|
165
|
+
f(a(ce), {
|
|
166
|
+
value: E.value,
|
|
167
|
+
"onUpdate:value": e[0] || (e[0] = (l) => E.value = l),
|
|
168
|
+
type: "line",
|
|
169
|
+
class: "ugs-tabs"
|
|
170
|
+
}, {
|
|
171
|
+
default: o(() => [
|
|
172
|
+
f(a(U), {
|
|
173
|
+
name: "grant",
|
|
174
|
+
"display-directive": "show",
|
|
175
|
+
tab: a(n)("userGrant.tabGrant")
|
|
176
|
+
}, {
|
|
177
|
+
default: o(() => [
|
|
178
|
+
f(pe, {
|
|
179
|
+
tree: b.value,
|
|
180
|
+
effective: s.value,
|
|
181
|
+
draft: c,
|
|
182
|
+
"default-module-id": Q.value,
|
|
183
|
+
"max-date": A.value
|
|
184
|
+
}, null, 8, ["tree", "effective", "draft", "default-module-id", "max-date"])
|
|
185
|
+
]),
|
|
186
|
+
_: 1
|
|
187
|
+
}, 8, ["tab"]),
|
|
188
|
+
f(a(U), {
|
|
189
|
+
name: "effective",
|
|
190
|
+
tab: a(n)("userGrant.tabEffective")
|
|
191
|
+
}, {
|
|
192
|
+
default: o(() => [
|
|
193
|
+
f(ye, {
|
|
194
|
+
tree: b.value,
|
|
195
|
+
effective: s.value,
|
|
196
|
+
grants: S.value
|
|
197
|
+
}, null, 8, ["tree", "effective", "grants"])
|
|
198
|
+
]),
|
|
199
|
+
_: 1
|
|
200
|
+
}, 8, ["tab"])
|
|
201
|
+
]),
|
|
202
|
+
_: 1
|
|
203
|
+
}, 8, ["value"])
|
|
204
|
+
])) : w("", !0)
|
|
205
|
+
]),
|
|
206
|
+
_: 1
|
|
207
|
+
}, 8, ["show"])
|
|
208
|
+
]),
|
|
209
|
+
_: 1
|
|
210
|
+
}, 8, ["show", "title", "closable", "close-on-esc", "style"]));
|
|
211
|
+
}
|
|
212
|
+
});
|
|
213
|
+
export {
|
|
214
|
+
ze as default
|
|
215
|
+
};
|
|
216
|
+
//# sourceMappingURL=UserGrantMenuSheet2.vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserGrantMenuSheet2.vue.js","sources":["../../../../../src/views/system/user/components/UserGrantMenuSheet.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 用户「授权菜单」弹窗:壳的尺寸与底栏照角色页 GrantMenuSheet(定高、只有列表滚动、底栏常驻),\n// 内容是两个页签——「单独授权」三态列表与「有效权限」只读表。打开时一次拉齐菜单树、授权记录与有效权限;\n// 保存只提交变更集(与打开时的快照比)。目标用户不可编辑(自己 / 超管 / 范围外 / 对方是管理员)时整体只读并说明原因。\nimport { computed, reactive, ref, shallowRef, type CSSProperties } from 'vue'\nimport { NAlert, NButton, NModal, NSpin, NTabPane, NTabs, useMessage } from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport { useWindowSize } from '@vueuse/core'\nimport { menuApi, userApi } from '#/api'\nimport { useAuthStore } from '#/stores/auth'\nimport { translateError } from '#/utils/error'\nimport type { MenuTreeNode } from '#/types/menu'\nimport type { UserMenuEffective, UserMenuGrantItem } from '#/types/api'\nimport UserGrantMenuTable from './UserGrantMenuTable.vue'\nimport UserGrantEffectiveTable from './UserGrantEffectiveTable.vue'\nimport {\n READONLY_REASON_KEYS,\n countDraft,\n diffDraft,\n draftFromGrants,\n invalidExpiry,\n expiryLimit,\n type Draft,\n} from './userGrantState'\n\nconst emit = defineEmits<{ (e: 'saved'): void }>()\nconst { t } = useI18n()\nconst message = useMessage()\nconst auth = useAuthStore()\n\nconst show = ref(false)\nconst loading = ref(false)\nconst saving = ref(false)\nconst tab = ref<'grant' | 'effective'>('grant')\nconst user = ref<{ id: number; name: string } | null>(null)\nconst tree = shallowRef<MenuTreeNode[]>([])\nconst grants = shallowRef<UserMenuGrantItem[]>([])\nconst effective = shallowRef<UserMenuEffective | null>(null)\n/** 打开时的快照;草稿另建一份,免得两边共用同一批对象、改一处两处都变。每次换一份新 Map,依赖它的计算属性才会重算。 */\nconst baseline = shallowRef<Draft>(new Map())\nconst draft = reactive<Draft>(new Map())\n/** 打开请求的序号:慢的旧响应回来时序号已变,不许再写任何状态。 */\nlet openSeq = 0\n\n/** 窄于此宽度弹窗几乎铺满视口(同角色页)。 */\nconst COMPACT = 640\nconst { width: winW } = useWindowSize()\nconst compact = computed(() => winW.value <= COMPACT)\nconst modalStyle = computed(() =>\n compact.value\n ? { width: 'calc(100vw - 16px)', height: 'calc(100dvh - 16px)' }\n : { width: 'min(1040px, calc(100vw - 48px))', height: 'min(780px, calc(100dvh - 48px))' },\n)\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\nconst maxDate = computed(() => expiryLimit(effective.value, new Date()))\nconst counts = computed(() => countDraft(draft))\nconst dirty = computed(() => {\n const d = diffDraft(baseline.value, draft)\n return d.upserts.length + d.removes.length > 0\n})\nconst readonlyText = computed(() => {\n const e = effective.value\n if (!e || e.targetEditable) return ''\n const key = e.readOnlyReason != null ? READONLY_REASON_KEYS[e.readOnlyReason] : undefined\n return key ? t('userGrant.readonly', { reason: t(key) }) : t('userGrant.readonlyNoReason')\n})\n/** 默认停在当前所在的应用;不在清单里(如已被去掉)就落到第一个。 */\nconst defaultModuleId = computed(() => {\n const modules = effective.value?.modules ?? []\n const current = auth.currentModuleId\n return current != null && modules.some(m => m.id === current) ? current : (modules[0]?.id ?? 0)\n})\n\n/** 清掉上一个用户留下的全部数据,加载期间底栏不会显示别人的数字。 */\nfunction reset() {\n tree.value = []\n grants.value = []\n baseline.value = new Map()\n draft.clear()\n effective.value = null\n}\n\nasync function open(target: { id: number; name: string }) {\n const seq = ++openSeq\n user.value = target\n tab.value = 'grant'\n reset()\n show.value = true\n loading.value = true\n try {\n const [menuTree, records, eff] = await Promise.all([\n menuApi.tree(),\n userApi.getMenuGrants(target.id),\n userApi.getEffectiveMenus(target.id),\n ])\n if (seq !== openSeq) return\n tree.value = menuTree\n grants.value = records\n baseline.value = draftFromGrants(records)\n for (const [id, entry] of draftFromGrants(records)) draft.set(id, entry)\n effective.value = eff\n } catch (e) {\n if (seq !== openSeq) return\n message.error(translateError(e))\n show.value = false\n } finally {\n if (seq === openSeq) loading.value = false\n }\n}\n\nasync function save() {\n if (saving.value || !user.value) return\n const bad = invalidExpiry(baseline.value, draft, maxDate.value, new Date())\n if (bad.length) {\n message.warning(t('userGrant.invalidExpiry', { count: bad.length }))\n return\n }\n const { upserts, removes } = diffDraft(baseline.value, draft)\n if (!upserts.length && !removes.length) {\n show.value = false\n return\n }\n saving.value = true\n try {\n await userApi.setMenuGrants(user.value.id, upserts, removes)\n message.success(t('userGrant.saved'))\n show.value = false\n emit('saved')\n } catch (e) {\n message.error(translateError(e))\n } finally {\n saving.value = false\n }\n}\n\ndefineExpose({ open })\n</script>\n\n<template>\n <n-modal\n v-model:show=\"show\"\n preset=\"card\"\n :title=\"user ? t('userGrant.title', { name: user.name }) : ''\"\n :closable=\"!saving\"\n :close-on-esc=\"!saving\"\n :mask-closable=\"false\"\n :auto-focus=\"false\"\n :style=\"modalStyle\"\n :content-style=\"contentStyle\"\n :footer-style=\"footerStyle\"\n >\n <n-spin :show=\"loading\" class=\"ugs-spin\">\n <div v-if=\"effective\" class=\"ugs\">\n <div class=\"ugs-notes\">\n <n-alert v-if=\"readonlyText\" type=\"warning\" :bordered=\"false\">{{ readonlyText }}</n-alert>\n <n-alert v-if=\"!effective.hasRoles\" type=\"info\" :bordered=\"false\">\n {{ t('userGrant.noRoles') }}\n </n-alert>\n <p class=\"ugs-hint\">{{ t('userGrant.hint') }}</p>\n </div>\n <n-tabs v-model:value=\"tab\" type=\"line\" class=\"ugs-tabs\">\n <!-- 单独授权页签切走时保留挂载:应用选择、搜索词、折叠状态不丢 -->\n <n-tab-pane name=\"grant\" display-directive=\"show\" :tab=\"t('userGrant.tabGrant')\">\n <UserGrantMenuTable\n :tree=\"tree\"\n :effective=\"effective\"\n :draft=\"draft\"\n :default-module-id=\"defaultModuleId\"\n :max-date=\"maxDate\"\n />\n </n-tab-pane>\n <n-tab-pane name=\"effective\" :tab=\"t('userGrant.tabEffective')\">\n <UserGrantEffectiveTable :tree=\"tree\" :effective=\"effective\" :grants=\"grants\" />\n </n-tab-pane>\n </n-tabs>\n </div>\n </n-spin>\n\n <template #footer>\n <footer class=\"ugs-foot\" :class=\"{ 'is-narrow': compact }\">\n <div class=\"ugs-summary\">\n <span>{{ t('userGrant.summary', counts) }}</span>\n <span v-if=\"dirty\" class=\"ugs-dirty\">{{ t('userGrant.unsaved') }}</span>\n </div>\n <n-button :disabled=\"saving\" @click=\"show = false\">{{ t('common.cancel') }}</n-button>\n <n-button v-if=\"effective?.targetEditable\" type=\"primary\" :loading=\"saving\" @click=\"save\">\n {{ t('common.save') }}\n </n-button>\n </footer>\n </template>\n </n-modal>\n</template>\n\n<style scoped>\n.ugs-spin,\n.ugs-spin :deep(.n-spin-content),\n.ugs,\n.ugs-tabs {\n display: flex;\n flex-direction: column;\n flex: 1 1 0;\n min-height: 0;\n}\n.ugs-notes {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 10px 20px 0;\n}\n.ugs-hint {\n margin: 0;\n font-size: 13px;\n color: var(--text-2);\n}\n.ugs-tabs :deep(.n-tabs-nav) {\n padding: 0 20px;\n}\n.ugs-tabs :deep(.n-tab-pane),\n.ugs-tabs :deep(.n-tabs-pane-wrapper) {\n display: flex;\n flex-direction: column;\n flex: 1 1 0;\n min-height: 0;\n padding: 0;\n}\n.ugs-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.ugs-summary {\n flex: 1;\n min-width: 0;\n display: flex;\n flex-wrap: wrap;\n gap: 4px 12px;\n font-size: 13px;\n color: var(--text-2);\n}\n.ugs-dirty {\n color: var(--warn);\n}\n.ugs-foot.is-narrow {\n flex-wrap: wrap;\n}\n.ugs-foot.is-narrow .ugs-summary {\n flex: 1 1 100%;\n}\n</style>\n"],"names":["COMPACT","emit","__emit","t","useI18n","message","useMessage","auth","useAuthStore","show","ref","loading","saving","tab","user","tree","shallowRef","grants","effective","baseline","draft","reactive","openSeq","winW","useWindowSize","compact","computed","modalStyle","contentStyle","footerStyle","maxDate","expiryLimit","counts","countDraft","dirty","d","diffDraft","readonlyText","e","key","READONLY_REASON_KEYS","defaultModuleId","modules","_a","current","m","_b","reset","open","target","seq","menuTree","records","eff","menuApi","userApi","draftFromGrants","id","entry","translateError","save","bad","invalidExpiry","upserts","removes","__expose","_createBlock","_unref","NModal","$event","_createElementVNode","_normalizeClass","_hoisted_4","_toDisplayString","_createElementBlock","_hoisted_5","_createVNode","NButton","NSpin","_openBlock","_hoisted_1","_hoisted_2","NAlert","_hoisted_3","NTabs","NTabPane","UserGrantMenuTable","UserGrantEffectiveTable"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { MenuTreeNode } from '../../../../types/menu';
|
|
2
|
+
import { UserMenuEffective } from '../../../../types/api';
|
|
3
|
+
import { Draft } from './userGrantState';
|
|
4
|
+
type __VLS_Props = {
|
|
5
|
+
tree: MenuTreeNode[];
|
|
6
|
+
effective: UserMenuEffective;
|
|
7
|
+
draft: Draft;
|
|
8
|
+
defaultModuleId: number;
|
|
9
|
+
maxDate: string | null;
|
|
10
|
+
};
|
|
11
|
+
declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
12
|
+
declare const _default: typeof __VLS_export;
|
|
13
|
+
export default _default;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import o from "./UserGrantMenuTable2.vue.js";
|
|
2
|
+
/* empty css */
|
|
3
|
+
import r from "../../../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
+
const m = /* @__PURE__ */ r(o, [["__scopeId", "data-v-438bbbc2"]]);
|
|
5
|
+
export {
|
|
6
|
+
m as default
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=UserGrantMenuTable.vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserGrantMenuTable.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
import { defineComponent as Q, ref as B, computed as i, watch as W, reactive as X, openBlock as l, createElementBlock as s, createElementVNode as g, createVNode as c, unref as d, withCtx as R, Fragment as h, renderList as S, toDisplayString as D, createBlock as I, mergeProps as M, createCommentVNode as V, withDirectives as Y, vShow as Z } from "vue";
|
|
2
|
+
import { NSelect as ee, NInput as te, NButton as oe } from "naive-ui";
|
|
3
|
+
import { useI18n as ae } from "vue-i18n";
|
|
4
|
+
import $ from "../../../../components/AppIcon.vue.js";
|
|
5
|
+
import { translateMenuTitle as z } from "../../../../locales/menuTitle.js";
|
|
6
|
+
import { pruneSuperAdminOnly as ne, buildGroups as re } from "../../role/components/grantMenuGroups.js";
|
|
7
|
+
import N from "./UserGrantNodeRow.vue.js";
|
|
8
|
+
import { triStateOf as le, leakedCodes as se, setTriState as ie } from "./userGrantState.js";
|
|
9
|
+
const ue = { class: "ut" }, de = { class: "ut-toolbar" }, pe = { class: "ut-scroll" }, ce = {
|
|
10
|
+
key: 0,
|
|
11
|
+
class: "ut-head"
|
|
12
|
+
}, fe = {
|
|
13
|
+
key: 0,
|
|
14
|
+
class: "ut-head-title"
|
|
15
|
+
}, me = {
|
|
16
|
+
key: 0,
|
|
17
|
+
class: "ut-anchor"
|
|
18
|
+
}, ge = { class: "ut-tag" }, he = {
|
|
19
|
+
key: 0,
|
|
20
|
+
class: "ut-empty"
|
|
21
|
+
}, v = 0, Se = /* @__PURE__ */ Q({
|
|
22
|
+
__name: "UserGrantMenuTable",
|
|
23
|
+
props: {
|
|
24
|
+
tree: {},
|
|
25
|
+
effective: {},
|
|
26
|
+
draft: {},
|
|
27
|
+
defaultModuleId: {},
|
|
28
|
+
maxDate: {}
|
|
29
|
+
},
|
|
30
|
+
setup(A) {
|
|
31
|
+
const n = A, { t: p } = ae(), k = B(""), _ = i(() => k.value.trim().toLowerCase()), f = B(n.defaultModuleId);
|
|
32
|
+
W(
|
|
33
|
+
() => n.defaultModuleId,
|
|
34
|
+
(e) => f.value = e
|
|
35
|
+
);
|
|
36
|
+
const C = i(() => ne(n.tree)), O = i(() => re(C.value, /* @__PURE__ */ new Set(), p("role.apiOnlyRow"))), P = i(() => new Map(n.effective.nodes.map((e) => [e.menuId, e]))), j = i(
|
|
37
|
+
() => new Set(n.effective.nodes.filter((e) => e.effective).map((e) => e.menuId))
|
|
38
|
+
), q = i(() => {
|
|
39
|
+
const e = /* @__PURE__ */ new Map(), a = (t) => {
|
|
40
|
+
for (const o of t)
|
|
41
|
+
e.set(o.id, z(o.title, o.path || void 0)), a(o.children);
|
|
42
|
+
};
|
|
43
|
+
return a(n.tree), e;
|
|
44
|
+
}), F = i(
|
|
45
|
+
() => new Map(C.value.map((e) => [e.id, e.moduleId ?? v]))
|
|
46
|
+
), E = (e) => F.value.get(e.id) ?? v, H = i(() => {
|
|
47
|
+
const e = n.effective.modules.map((a) => ({
|
|
48
|
+
label: z(a.title),
|
|
49
|
+
value: a.id
|
|
50
|
+
}));
|
|
51
|
+
return O.value.some((a) => E(a) === v) && e.push({ label: p("menu.moduleUnassigned"), value: v }), e;
|
|
52
|
+
}), J = (e, a) => e.title.toLowerCase().includes(a) || e.buttons.some((t) => t.title.toLowerCase().includes(a)), G = i(() => {
|
|
53
|
+
const e = _.value, a = [];
|
|
54
|
+
for (const t of O.value) {
|
|
55
|
+
if (E(t) !== f.value) continue;
|
|
56
|
+
if (!e || t.title.toLowerCase().includes(e)) {
|
|
57
|
+
a.push({ group: t, menus: t.menus });
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
const o = t.menus.filter((r) => J(r, e));
|
|
61
|
+
o.length && a.push({ group: t, menus: o });
|
|
62
|
+
}
|
|
63
|
+
return a;
|
|
64
|
+
}), m = X(/* @__PURE__ */ new Set()), U = (e) => !!_.value || !m.has(e);
|
|
65
|
+
function K(e) {
|
|
66
|
+
m.has(e) ? m.delete(e) : m.add(e);
|
|
67
|
+
}
|
|
68
|
+
function w(e, a, t) {
|
|
69
|
+
const o = P.value.get(e), r = (o == null ? void 0 : o.grantable) ?? !1, u = le(n.draft, e);
|
|
70
|
+
return {
|
|
71
|
+
title: a,
|
|
72
|
+
path: t,
|
|
73
|
+
node: o,
|
|
74
|
+
state: u,
|
|
75
|
+
entry: n.draft.get(e),
|
|
76
|
+
editable: n.effective.targetEditable && r,
|
|
77
|
+
notGrantable: n.effective.targetEditable && !r,
|
|
78
|
+
maxDate: n.maxDate,
|
|
79
|
+
leaked: u === "deny" ? se(n.tree, j.value, e).map((L) => ({
|
|
80
|
+
code: L.code,
|
|
81
|
+
from: L.carriers.map((T) => q.value.get(T) ?? String(T)).join("、")
|
|
82
|
+
})) : []
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
const y = (e, a) => ie(n.draft, e, a, n.maxDate);
|
|
86
|
+
function x(e, a) {
|
|
87
|
+
const t = n.draft.get(e);
|
|
88
|
+
t && (t.expireDate = a);
|
|
89
|
+
}
|
|
90
|
+
function b(e, a) {
|
|
91
|
+
const t = n.draft.get(e);
|
|
92
|
+
t && (t.remark = a);
|
|
93
|
+
}
|
|
94
|
+
return (e, a) => (l(), s("div", ue, [
|
|
95
|
+
g("div", de, [
|
|
96
|
+
c(d(ee), {
|
|
97
|
+
value: f.value,
|
|
98
|
+
"onUpdate:value": a[0] || (a[0] = (t) => f.value = t),
|
|
99
|
+
class: "ut-module",
|
|
100
|
+
options: H.value,
|
|
101
|
+
"aria-label": d(p)("menu.module")
|
|
102
|
+
}, null, 8, ["value", "options", "aria-label"]),
|
|
103
|
+
c(d(te), {
|
|
104
|
+
value: k.value,
|
|
105
|
+
"onUpdate:value": a[1] || (a[1] = (t) => k.value = t),
|
|
106
|
+
clearable: "",
|
|
107
|
+
placeholder: d(p)("role.grantSearch"),
|
|
108
|
+
"input-props": { "aria-label": d(p)("role.grantSearch"), autocomplete: "off" },
|
|
109
|
+
style: { flex: "1", "min-width": "0" }
|
|
110
|
+
}, {
|
|
111
|
+
prefix: R(() => [
|
|
112
|
+
c($, {
|
|
113
|
+
class: "faint",
|
|
114
|
+
icon: "ph:magnifying-glass",
|
|
115
|
+
size: 15
|
|
116
|
+
})
|
|
117
|
+
]),
|
|
118
|
+
_: 1
|
|
119
|
+
}, 8, ["value", "placeholder", "input-props"])
|
|
120
|
+
]),
|
|
121
|
+
g("div", pe, [
|
|
122
|
+
(l(!0), s(h, null, S(G.value, (t) => (l(), s("section", {
|
|
123
|
+
key: t.group.id,
|
|
124
|
+
class: "ut-group"
|
|
125
|
+
}, [
|
|
126
|
+
t.group.standalone ? V("", !0) : (l(), s("header", ce, [
|
|
127
|
+
c(d(oe), {
|
|
128
|
+
text: "",
|
|
129
|
+
class: "ut-fold",
|
|
130
|
+
"aria-expanded": U(t.group.id),
|
|
131
|
+
"aria-label": t.group.title,
|
|
132
|
+
onClick: (o) => K(t.group.id)
|
|
133
|
+
}, {
|
|
134
|
+
default: R(() => [
|
|
135
|
+
c($, {
|
|
136
|
+
icon: U(t.group.id) ? "ph:caret-down" : "ph:caret-right",
|
|
137
|
+
size: 14
|
|
138
|
+
}, null, 8, ["icon"])
|
|
139
|
+
]),
|
|
140
|
+
_: 2
|
|
141
|
+
}, 1032, ["aria-expanded", "aria-label", "onClick"]),
|
|
142
|
+
t.group.synthetic ? (l(), s("span", fe, D(t.group.title), 1)) : (l(), I(N, M({
|
|
143
|
+
key: 1,
|
|
144
|
+
level: "catalog"
|
|
145
|
+
}, { ref_for: !0 }, w(t.group.id, t.group.title), {
|
|
146
|
+
"onUpdate:state": (o) => y(t.group.id, o),
|
|
147
|
+
"onUpdate:expireDate": (o) => x(t.group.id, o),
|
|
148
|
+
"onUpdate:remark": (o) => b(t.group.id, o)
|
|
149
|
+
}), null, 16, ["onUpdate:state", "onUpdate:expireDate", "onUpdate:remark"]))
|
|
150
|
+
])),
|
|
151
|
+
Y(g("div", null, [
|
|
152
|
+
(l(!0), s(h, null, S(t.menus, (o) => (l(), s(h, {
|
|
153
|
+
key: o.anchor ? `anchor-${o.id}` : o.id
|
|
154
|
+
}, [
|
|
155
|
+
o.anchor ? (l(), s("div", me, [
|
|
156
|
+
g("span", ge, D(o.title), 1)
|
|
157
|
+
])) : (l(), I(N, M({
|
|
158
|
+
key: 1,
|
|
159
|
+
level: "page"
|
|
160
|
+
}, { ref_for: !0 }, w(o.id, o.title, o.path), {
|
|
161
|
+
"onUpdate:state": (r) => y(o.id, r),
|
|
162
|
+
"onUpdate:expireDate": (r) => x(o.id, r),
|
|
163
|
+
"onUpdate:remark": (r) => b(o.id, r)
|
|
164
|
+
}), null, 16, ["onUpdate:state", "onUpdate:expireDate", "onUpdate:remark"])),
|
|
165
|
+
(l(!0), s(h, null, S(o.buttons, (r) => (l(), I(N, M({
|
|
166
|
+
key: r.id,
|
|
167
|
+
level: "button"
|
|
168
|
+
}, { ref_for: !0 }, w(r.id, r.title), {
|
|
169
|
+
"onUpdate:state": (u) => y(r.id, u),
|
|
170
|
+
"onUpdate:expireDate": (u) => x(r.id, u),
|
|
171
|
+
"onUpdate:remark": (u) => b(r.id, u)
|
|
172
|
+
}), null, 16, ["onUpdate:state", "onUpdate:expireDate", "onUpdate:remark"]))), 128))
|
|
173
|
+
], 64))), 128))
|
|
174
|
+
], 512), [
|
|
175
|
+
[Z, U(t.group.id)]
|
|
176
|
+
])
|
|
177
|
+
]))), 128)),
|
|
178
|
+
G.value.length ? V("", !0) : (l(), s("div", he, D(_.value ? d(p)("role.grantNoMatch") : d(p)("role.grantNoMenus")), 1))
|
|
179
|
+
])
|
|
180
|
+
]));
|
|
181
|
+
}
|
|
182
|
+
});
|
|
183
|
+
export {
|
|
184
|
+
Se as default
|
|
185
|
+
};
|
|
186
|
+
//# sourceMappingURL=UserGrantMenuTable2.vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserGrantMenuTable2.vue.js","sources":["../../../../../src/views/system/user/components/UserGrantMenuTable.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 用户授权弹窗的节点列表:应用切换 + 搜索 + 目录卡片(目录 → 页面 → 按钮,每个节点一行三态)。\n// 分组复用角色页 grantMenuGroups.buildGroups 的结构(不用它的勾选态),角色页的 GrantMenuTable 不动。\n// 草稿在父组件(reactive Map),这里只经 userGrantState 的纯函数改它。嵌套目录与角色页一样展平成带前缀的行。\nimport { computed, reactive, ref, watch } from 'vue'\nimport { NButton, NInput, NSelect } from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport AppIcon from '#/components/AppIcon.vue'\nimport { translateMenuTitle } from '#/locales/menuTitle'\nimport type { MenuTreeNode } from '#/types/menu'\nimport type { UserMenuEffective } from '#/types/api'\nimport {\n buildGroups,\n pruneSuperAdminOnly,\n type CatalogGroup,\n type MenuRow,\n} from '../../role/components/grantMenuGroups'\nimport UserGrantNodeRow from './UserGrantNodeRow.vue'\nimport { leakedCodes, setTriState, triStateOf, type Draft, type TriState } from './userGrantState'\n\nconst UNASSIGNED = 0\n\nconst props = defineProps<{\n tree: MenuTreeNode[]\n effective: UserMenuEffective\n draft: Draft\n defaultModuleId: number\n maxDate: string | null\n}>()\n\nconst { t } = useI18n()\nconst search = ref('')\nconst query = computed(() => search.value.trim().toLowerCase())\nconst moduleId = ref(props.defaultModuleId)\nwatch(\n () => props.defaultModuleId,\n v => (moduleId.value = v),\n)\n\n// 单独授权的目标从来不是超管:系统菜单里除用户管理、角色管理外只属于超管与内置角色,这里不列出来。\n// 只收窄列表;防漏提示(leakedCodes)与「有效权限」页签仍按完整的树算,隐藏的节点照样是它们的数据来源。\nconst visibleTree = computed(() => pruneSuperAdminOnly(props.tree))\nconst groups = computed(() => buildGroups(visibleTree.value, new Set(), t('role.apiOnlyRow')))\nconst nodeMap = computed(() => new Map(props.effective.nodes.map(n => [n.menuId, n])))\nconst effectiveIds = computed(\n () => new Set(props.effective.nodes.filter(n => n.effective).map(n => n.menuId)),\n)\nconst titles = computed(() => {\n const map = new Map<number, string>()\n const walk = (nodes: MenuTreeNode[]) => {\n for (const n of nodes) {\n map.set(n.id, translateMenuTitle(n.title, n.path || undefined))\n walk(n.children)\n }\n }\n walk(props.tree)\n return map\n})\n\n// ── 应用切换:同角色页,按顶级节点的 moduleId 分 ──\nconst moduleOfTop = computed(\n () => new Map(visibleTree.value.map(n => [n.id, n.moduleId ?? UNASSIGNED])),\n)\nconst moduleOf = (g: CatalogGroup) => moduleOfTop.value.get(g.id) ?? UNASSIGNED\nconst moduleOptions = computed(() => {\n const options = props.effective.modules.map(m => ({\n label: translateMenuTitle(m.title),\n value: m.id,\n }))\n if (groups.value.some(g => moduleOf(g) === UNASSIGNED))\n options.push({ label: t('menu.moduleUnassigned'), value: UNASSIGNED })\n return options\n})\n\n// ── 搜索:目录名命中 → 整组;否则只留页面名 / 按钮名命中的行 ──\nconst matchesRow = (m: MenuRow, q: string) =>\n m.title.toLowerCase().includes(q) || m.buttons.some(b => b.title.toLowerCase().includes(q))\nconst views = computed(() => {\n const q = query.value\n const out: { group: CatalogGroup; menus: MenuRow[] }[] = []\n for (const g of groups.value) {\n if (moduleOf(g) !== moduleId.value) continue\n if (!q || g.title.toLowerCase().includes(q)) {\n out.push({ group: g, menus: g.menus })\n continue\n }\n const menus = g.menus.filter(m => matchesRow(m, q))\n if (menus.length) out.push({ group: g, menus })\n }\n return out\n})\n\n// ── 折叠(搜索时一律展开,免得命中项藏在折叠里) ──\nconst collapsed = reactive(new Set<number>())\nconst isOpen = (id: number) => !!query.value || !collapsed.has(id)\nfunction toggle(id: number) {\n if (collapsed.has(id)) collapsed.delete(id)\n else collapsed.add(id)\n}\n\n// ── 行属性与改动 ──\nfunction rowProps(id: number, title: string, path?: string) {\n const node = nodeMap.value.get(id)\n const grantable = node?.grantable ?? false\n const state = triStateOf(props.draft, id)\n return {\n title,\n path,\n node,\n state,\n entry: props.draft.get(id),\n editable: props.effective.targetEditable && grantable,\n notGrantable: props.effective.targetEditable && !grantable,\n maxDate: props.maxDate,\n leaked:\n state === 'deny'\n ? leakedCodes(props.tree, effectiveIds.value, id).map(l => ({\n code: l.code,\n from: l.carriers.map(c => titles.value.get(c) ?? String(c)).join('、'),\n }))\n : [],\n }\n}\nconst onState = (id: number, next: TriState) => setTriState(props.draft, id, next, props.maxDate)\nfunction onExpire(id: number, v: string | null) {\n const entry = props.draft.get(id)\n if (entry) entry.expireDate = v\n}\nfunction onRemark(id: number, v: string) {\n const entry = props.draft.get(id)\n if (entry) entry.remark = v\n}\n</script>\n\n<template>\n <div class=\"ut\">\n <div class=\"ut-toolbar\">\n <n-select\n v-model:value=\"moduleId\"\n class=\"ut-module\"\n :options=\"moduleOptions\"\n :aria-label=\"t('menu.module')\"\n />\n <n-input\n v-model:value=\"search\"\n clearable\n :placeholder=\"t('role.grantSearch')\"\n :input-props=\"{ 'aria-label': t('role.grantSearch'), autocomplete: 'off' }\"\n style=\"flex: 1; min-width: 0\"\n >\n <template #prefix><AppIcon class=\"faint\" icon=\"ph:magnifying-glass\" :size=\"15\" /></template>\n </n-input>\n </div>\n\n <div class=\"ut-scroll\">\n <section v-for=\"v in views\" :key=\"v.group.id\" class=\"ut-group\">\n <header v-if=\"!v.group.standalone\" class=\"ut-head\">\n <n-button\n text\n class=\"ut-fold\"\n :aria-expanded=\"isOpen(v.group.id)\"\n :aria-label=\"v.group.title\"\n @click=\"toggle(v.group.id)\"\n >\n <AppIcon :icon=\"isOpen(v.group.id) ? 'ph:caret-down' : 'ph:caret-right'\" :size=\"14\" />\n </n-button>\n <span v-if=\"v.group.synthetic\" class=\"ut-head-title\">{{ v.group.title }}</span>\n <UserGrantNodeRow\n v-else\n level=\"catalog\"\n v-bind=\"rowProps(v.group.id, v.group.title)\"\n @update:state=\"s => onState(v.group.id, s)\"\n @update:expire-date=\"d => onExpire(v.group.id, d)\"\n @update:remark=\"r => onRemark(v.group.id, r)\"\n />\n </header>\n <div v-show=\"isOpen(v.group.id)\">\n <template v-for=\"m in v.menus\" :key=\"m.anchor ? `anchor-${m.id}` : m.id\">\n <div v-if=\"m.anchor\" class=\"ut-anchor\">\n <span class=\"ut-tag\">{{ m.title }}</span>\n </div>\n <UserGrantNodeRow\n v-else\n level=\"page\"\n v-bind=\"rowProps(m.id, m.title, m.path)\"\n @update:state=\"s => onState(m.id, s)\"\n @update:expire-date=\"d => onExpire(m.id, d)\"\n @update:remark=\"r => onRemark(m.id, r)\"\n />\n <UserGrantNodeRow\n v-for=\"b in m.buttons\"\n :key=\"b.id\"\n level=\"button\"\n v-bind=\"rowProps(b.id, b.title)\"\n @update:state=\"s => onState(b.id, s)\"\n @update:expire-date=\"d => onExpire(b.id, d)\"\n @update:remark=\"r => onRemark(b.id, r)\"\n />\n </template>\n </div>\n </section>\n\n <div v-if=\"!views.length\" class=\"ut-empty\">\n {{ query ? t('role.grantNoMatch') : t('role.grantNoMenus') }}\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n.ut {\n flex: 1;\n min-height: 0;\n display: flex;\n flex-direction: column;\n}\n.ut-toolbar {\n flex: none;\n display: flex;\n flex-wrap: wrap;\n gap: 8px;\n align-items: center;\n padding: 10px 20px 12px;\n}\n.ut-module {\n flex: none;\n width: 180px;\n}\n.ut-scroll {\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n overscroll-behavior: contain;\n padding: 4px 20px 20px;\n scrollbar-width: thin;\n}\n.ut-group {\n border: 1px solid var(--hairline);\n border-radius: 14px;\n margin-bottom: 12px;\n overflow: hidden;\n}\n.ut-head {\n display: flex;\n align-items: center;\n gap: 10px;\n min-height: 46px;\n padding: 6px 16px;\n}\n.ut-head-title {\n font-size: 15px;\n font-weight: 600;\n}\n.ut-fold {\n flex: none;\n}\n.ut-anchor {\n padding: 8px 16px;\n border-top: 1px solid var(--hairline);\n}\n.ut-tag {\n display: inline-block;\n padding: 1px 8px;\n border-radius: 6px;\n background: var(--fill);\n color: var(--text-2);\n font-size: 13px;\n font-weight: 500;\n}\n.ut-empty {\n padding: 64px 24px;\n text-align: center;\n color: var(--text-2);\n}\n@media (max-width: 640px) {\n .ut-module {\n width: 100%;\n }\n}\n</style>\n"],"names":["UNASSIGNED","props","__props","t","useI18n","search","ref","query","computed","moduleId","watch","v","visibleTree","pruneSuperAdminOnly","groups","buildGroups","nodeMap","n","effectiveIds","titles","map","walk","nodes","translateMenuTitle","moduleOfTop","moduleOf","g","moduleOptions","options","m","matchesRow","q","b","views","out","menus","collapsed","reactive","isOpen","id","toggle","rowProps","title","path","node","grantable","state","triStateOf","leakedCodes","l","c","onState","next","setTriState","onExpire","entry","onRemark","_openBlock","_createElementBlock","_hoisted_1","_createElementVNode","_hoisted_2","_createVNode","_unref","NSelect","$event","NInput","AppIcon","_hoisted_3","_Fragment","_renderList","_hoisted_4","NButton","_hoisted_5","_toDisplayString","_createBlock","UserGrantNodeRow","_mergeProps","s","d","r","_hoisted_6","_hoisted_7","_vShow","_hoisted_8"],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { UserMenuEffectiveNode } from '../../../../types/api';
|
|
2
|
+
import { DraftEntry, TriState } from './userGrantState';
|
|
3
|
+
type __VLS_Props = {
|
|
4
|
+
title: string;
|
|
5
|
+
path?: string;
|
|
6
|
+
level: 'catalog' | 'page' | 'button';
|
|
7
|
+
node?: UserMenuEffectiveNode;
|
|
8
|
+
state: TriState;
|
|
9
|
+
entry?: DraftEntry;
|
|
10
|
+
/** 目标用户可编辑且这个节点所属模块可授 */
|
|
11
|
+
editable: boolean;
|
|
12
|
+
/** 只因模块不可转授而不能改(悬浮说明) */
|
|
13
|
+
notGrantable: boolean;
|
|
14
|
+
/** 到期日上限 yyyy-MM-dd;null = 不限 */
|
|
15
|
+
maxDate: string | null;
|
|
16
|
+
leaked: {
|
|
17
|
+
code: string;
|
|
18
|
+
from: string;
|
|
19
|
+
}[];
|
|
20
|
+
};
|
|
21
|
+
declare const __VLS_export: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
|
|
22
|
+
"update:state": (v: TriState) => any;
|
|
23
|
+
"update:expireDate": (v: string | null) => any;
|
|
24
|
+
"update:remark": (v: string) => any;
|
|
25
|
+
}, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
|
|
26
|
+
"onUpdate:state"?: ((v: TriState) => any) | undefined;
|
|
27
|
+
"onUpdate:expireDate"?: ((v: string | null) => any) | undefined;
|
|
28
|
+
"onUpdate:remark"?: ((v: string) => any) | undefined;
|
|
29
|
+
}>, {}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
|
|
30
|
+
declare const _default: typeof __VLS_export;
|
|
31
|
+
export default _default;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import o from "./UserGrantNodeRow2.vue.js";
|
|
2
|
+
/* empty css */
|
|
3
|
+
import r from "../../../../_virtual/_plugin-vue_export-helper.js";
|
|
4
|
+
const f = /* @__PURE__ */ r(o, [["__scopeId", "data-v-665d8f94"]]);
|
|
5
|
+
export {
|
|
6
|
+
f as default
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=UserGrantNodeRow.vue.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"UserGrantNodeRow.vue.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
|