smart-admin-web 10.20.0 → 10.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/dist/api/index.d.ts +19 -1
  2. package/dist/api/index.js +85 -66
  3. package/dist/api/index.js.map +1 -1
  4. package/dist/api/schema.d.ts +448 -1
  5. package/dist/assets/icons/ph-subset.json.js +1 -1
  6. package/dist/components/FormContainer/index.vue.js +87 -75
  7. package/dist/components/FormContainer/index.vue.js.map +1 -1
  8. package/dist/components/UserPicker/UserAvatar.vue.d.ts +8 -0
  9. package/dist/components/UserPicker/UserAvatar.vue.js +8 -0
  10. package/dist/components/UserPicker/UserAvatar.vue.js.map +1 -0
  11. package/dist/components/UserPicker/UserAvatar2.vue.js +38 -0
  12. package/dist/components/UserPicker/UserAvatar2.vue.js.map +1 -0
  13. package/dist/components/UserPicker/index.vue.js +1 -1
  14. package/dist/components/UserPicker/index2.vue.js +328 -186
  15. package/dist/components/UserPicker/index2.vue.js.map +1 -1
  16. package/dist/index.js +248 -246
  17. package/dist/layouts/NoticeBell.vue.js +2 -2
  18. package/dist/layouts/NoticeBell2.vue.js +18 -17
  19. package/dist/layouts/NoticeBell2.vue.js.map +1 -1
  20. package/dist/lib/runtime.js +1 -1
  21. package/dist/lib/watermark.d.ts +1 -1
  22. package/dist/locales/en-US.d.ts +62 -3
  23. package/dist/locales/en-US.js +66 -7
  24. package/dist/locales/en-US.js.map +1 -1
  25. package/dist/locales/kernelMenuTitles.js +2 -1
  26. package/dist/locales/kernelMenuTitles.js.map +1 -1
  27. package/dist/locales/zh-CN.d.ts +62 -3
  28. package/dist/locales/zh-CN.js +66 -7
  29. package/dist/locales/zh-CN.js.map +1 -1
  30. package/dist/router/viewRegistry.js +6 -6
  31. package/dist/router/viewRegistry.js.map +1 -1
  32. package/dist/style.css +1 -1
  33. package/dist/theme/naive-theme.js +72 -67
  34. package/dist/theme/naive-theme.js.map +1 -1
  35. package/dist/types/api.d.ts +91 -0
  36. package/dist/types/api.js +17 -15
  37. package/dist/types/api.js.map +1 -1
  38. package/dist/utils/shake.d.ts +1 -0
  39. package/dist/utils/shake.js +30 -0
  40. package/dist/utils/shake.js.map +1 -0
  41. package/dist/views/login/LoginForm.vue.js +2 -2
  42. package/dist/views/login/LoginForm2.vue.js +135 -135
  43. package/dist/views/login/LoginForm2.vue.js.map +1 -1
  44. package/dist/views/login/components/LoginDesk.vue.js +1 -1
  45. package/dist/views/login/components/LoginDesk2.vue.js +59 -47
  46. package/dist/views/login/components/LoginDesk2.vue.js.map +1 -1
  47. package/dist/views/personal/notice2.vue.js +1 -1
  48. package/dist/views/personal/notice2.vue.js.map +1 -1
  49. package/dist/views/personal/sessions.vue.js +2 -2
  50. package/dist/views/personal/sessions2.vue.js +41 -40
  51. package/dist/views/personal/sessions2.vue.js.map +1 -1
  52. package/dist/views/system/ai-usage/index.vue.js +3 -3
  53. package/dist/views/system/ai-usage/index2.vue.js +13 -12
  54. package/dist/views/system/ai-usage/index2.vue.js.map +1 -1
  55. package/dist/views/system/config/components/AdvancedSection.vue.js +3 -3
  56. package/dist/views/system/config/components/AdvancedSection2.vue.js +2 -1
  57. package/dist/views/system/config/components/AdvancedSection2.vue.js.map +1 -1
  58. package/dist/views/system/dict/index.vue.js +2 -2
  59. package/dist/views/system/dict/index2.vue.js +12 -1
  60. package/dist/views/system/dict/index2.vue.js.map +1 -1
  61. package/dist/views/system/file/index2.vue.js +1 -0
  62. package/dist/views/system/file/index2.vue.js.map +1 -1
  63. package/dist/views/system/job/index.vue.js +3 -3
  64. package/dist/views/system/job/index2.vue.js +182 -181
  65. package/dist/views/system/job/index2.vue.js.map +1 -1
  66. package/dist/views/system/job-log/components/AttemptTable2.vue.js +8 -3
  67. package/dist/views/system/job-log/components/AttemptTable2.vue.js.map +1 -1
  68. package/dist/views/system/job-log/index.vue.js +1 -1
  69. package/dist/views/system/job-log/index2.vue.js +5 -5
  70. package/dist/views/system/job-log/index2.vue.js.map +1 -1
  71. package/dist/views/system/log/exception/index.vue.js +2 -2
  72. package/dist/views/system/log/exception/index2.vue.js +8 -5
  73. package/dist/views/system/log/exception/index2.vue.js.map +1 -1
  74. package/dist/views/system/log/login/index2.vue.js +21 -12
  75. package/dist/views/system/log/login/index2.vue.js.map +1 -1
  76. package/dist/views/system/log/op/index.vue.js +2 -2
  77. package/dist/views/system/log/op/index2.vue.js +50 -40
  78. package/dist/views/system/log/op/index2.vue.js.map +1 -1
  79. package/dist/views/system/menu/components/ButtonManager.vue.js +2 -2
  80. package/dist/views/system/menu/components/ButtonManager2.vue.js +45 -36
  81. package/dist/views/system/menu/components/ButtonManager2.vue.js.map +1 -1
  82. package/dist/views/system/menu/index.vue.js +2 -2
  83. package/dist/views/system/menu/index2.vue.js +11 -11
  84. package/dist/views/system/menu/index2.vue.js.map +1 -1
  85. package/dist/views/system/module/index.vue.js +1 -1
  86. package/dist/views/system/module/index2.vue.js +171 -117
  87. package/dist/views/system/module/index2.vue.js.map +1 -1
  88. package/dist/views/system/notice/index.vue.js +3 -3
  89. package/dist/views/system/notice/index2.vue.js +1 -0
  90. package/dist/views/system/notice/index2.vue.js.map +1 -1
  91. package/dist/views/system/org/index.vue.js +2 -2
  92. package/dist/views/system/org/index2.vue.js +70 -67
  93. package/dist/views/system/org/index2.vue.js.map +1 -1
  94. package/dist/views/system/position/index.vue.js +2 -2
  95. package/dist/views/system/position/index2.vue.js +57 -48
  96. package/dist/views/system/position/index2.vue.js.map +1 -1
  97. package/dist/views/system/recycle/index.vue.js +1 -1
  98. package/dist/views/system/recycle/index2.vue.js +3 -1
  99. package/dist/views/system/recycle/index2.vue.js.map +1 -1
  100. package/dist/views/system/role/components/GrantMenuSheet.vue.d.ts +2 -0
  101. package/dist/views/system/role/components/GrantMenuSheet.vue.js +2 -2
  102. package/dist/views/system/role/components/GrantMenuSheet2.vue.js +54 -49
  103. package/dist/views/system/role/components/GrantMenuSheet2.vue.js.map +1 -1
  104. package/dist/views/system/role/components/GrantMenuTable.vue.js +1 -1
  105. package/dist/views/system/role/components/GrantMenuTable2.vue.js +159 -195
  106. package/dist/views/system/role/components/GrantMenuTable2.vue.js.map +1 -1
  107. package/dist/views/system/role/components/grantMenuGroups.d.ts +54 -0
  108. package/dist/views/system/role/components/grantMenuGroups.js +116 -76
  109. package/dist/views/system/role/components/grantMenuGroups.js.map +1 -1
  110. package/dist/views/system/role/index.vue.js +2 -2
  111. package/dist/views/system/role/index2.vue.js +152 -145
  112. package/dist/views/system/role/index2.vue.js.map +1 -1
  113. package/dist/views/system/session/index2.vue.js +39 -35
  114. package/dist/views/system/session/index2.vue.js.map +1 -1
  115. package/dist/views/system/user/components/UserGrantEffectiveTable.vue.d.ts +10 -0
  116. package/dist/views/system/user/components/UserGrantEffectiveTable.vue.js +5 -0
  117. package/dist/views/system/user/components/UserGrantEffectiveTable.vue.js.map +1 -0
  118. package/dist/views/system/user/components/UserGrantEffectiveTable2.vue.js +96 -0
  119. package/dist/views/system/user/components/UserGrantEffectiveTable2.vue.js.map +1 -0
  120. package/dist/views/system/user/components/UserGrantMenuSheet.vue.d.ts +13 -0
  121. package/dist/views/system/user/components/UserGrantMenuSheet.vue.js +8 -0
  122. package/dist/views/system/user/components/UserGrantMenuSheet.vue.js.map +1 -0
  123. package/dist/views/system/user/components/UserGrantMenuSheet2.vue.js +216 -0
  124. package/dist/views/system/user/components/UserGrantMenuSheet2.vue.js.map +1 -0
  125. package/dist/views/system/user/components/UserGrantMenuTable.vue.d.ts +13 -0
  126. package/dist/views/system/user/components/UserGrantMenuTable.vue.js +8 -0
  127. package/dist/views/system/user/components/UserGrantMenuTable.vue.js.map +1 -0
  128. package/dist/views/system/user/components/UserGrantMenuTable2.vue.js +186 -0
  129. package/dist/views/system/user/components/UserGrantMenuTable2.vue.js.map +1 -0
  130. package/dist/views/system/user/components/UserGrantNodeRow.vue.d.ts +31 -0
  131. package/dist/views/system/user/components/UserGrantNodeRow.vue.js +8 -0
  132. package/dist/views/system/user/components/UserGrantNodeRow.vue.js.map +1 -0
  133. package/dist/views/system/user/components/UserGrantNodeRow2.vue.js +171 -0
  134. package/dist/views/system/user/components/UserGrantNodeRow2.vue.js.map +1 -0
  135. package/dist/views/system/user/components/UserGrantOverviewDrawer.vue.d.ts +21 -0
  136. package/dist/views/system/user/components/UserGrantOverviewDrawer.vue.js +5 -0
  137. package/dist/views/system/user/components/UserGrantOverviewDrawer.vue.js.map +1 -0
  138. package/dist/views/system/user/components/UserGrantOverviewDrawer2.vue.js +178 -0
  139. package/dist/views/system/user/components/UserGrantOverviewDrawer2.vue.js.map +1 -0
  140. package/dist/views/system/user/components/userGrantState.d.ts +64 -0
  141. package/dist/views/system/user/components/userGrantState.js +117 -0
  142. package/dist/views/system/user/components/userGrantState.js.map +1 -0
  143. package/dist/views/system/user/index.vue.js +2 -2
  144. package/dist/views/system/user/index2.vue.js +250 -207
  145. package/dist/views/system/user/index2.vue.js.map +1 -1
  146. package/package.json +3 -3
@@ -1,92 +1,96 @@
1
- import { defineComponent as V, useModel as I, computed as c, shallowRef as T, ref as w, watch as U, openBlock as S, createBlock as D, unref as e, normalizeStyle as E, withCtx as m, createElementVNode as r, normalizeClass as x, createVNode as v, toDisplayString as i, createElementBlock as G, createCommentVNode as W, createTextVNode as M, mergeModels as A } from "vue";
2
- import { NModal as F, NButton as b } from "naive-ui";
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 = { class: "gs-summary" }, $ = {
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
- }, j = 640, X = /* @__PURE__ */ V({
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(l) {
23
- const s = I(l, "show"), p = l, { t: a } = H(), { width: k } = O(), u = c(() => k.value <= j), C = c(
24
- () => u.value ? { width: "calc(100vw - 16px)", height: "calc(100dvh - 16px)" } : { width: "min(960px, calc(100vw - 48px))", height: "min(760px, calc(100dvh - 48px))" }
25
- ), g = c(() => u.value ? "large" : "medium"), z = {
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
- }, N = { padding: "0" }, f = T([]), o = w({ on: 0, total: 0, pages: 0, buttons: 0, dirty: !1 });
33
- U(
34
- s,
35
- (h) => {
36
- h && (f.value = p.granted);
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 d = w(!1), y = c(() => !d.value);
41
- async function B() {
42
- d.value = !0;
44
+ const i = S(!1), y = c(() => !i.value);
45
+ async function I() {
46
+ i.value = !0;
43
47
  try {
44
- await p.onSave(f.value) !== !1 && (s.value = !1);
48
+ await g.onSave(f.value) !== !1 && (u.value = !1);
45
49
  } catch {
46
50
  } finally {
47
- d.value = !1;
51
+ i.value = !1;
48
52
  }
49
53
  }
50
- return (h, t) => (S(), D(e(F), {
51
- show: s.value,
52
- "onUpdate:show": t[3] || (t[3] = (n) => s.value = n),
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: E(C.value),
60
- "content-style": z,
61
- "footer-style": N
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": u.value }])
69
+ class: x(["gs-foot", { "is-narrow": d.value }])
66
70
  }, [
67
- r("div", R, [
68
- r("span", null, i(e(a)("role.grantSummary", { on: o.value.on, total: o.value.total })), 1),
69
- r("span", null, i(e(a)("role.grantSummarySplit", { pages: o.value.pages, buttons: o.value.buttons })), 1),
70
- o.value.dirty ? (S(), G("span", $, i(e(a)("role.grantUnsaved")), 1)) : W("", !0)
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
- v(e(b), {
73
- size: g.value,
74
- disabled: d.value,
75
- onClick: t[2] || (t[2] = (n) => s.value = !1)
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
- M(i(e(a)("common.cancel")), 1)
82
+ b(s(e(a)("common.cancel")), 1)
79
83
  ]),
80
84
  _: 1
81
85
  }, 8, ["size", "disabled"]),
82
- v(e(b), {
86
+ p(e(C), {
83
87
  type: "primary",
84
- size: g.value,
85
- loading: d.value,
86
- onClick: B
88
+ size: h.value,
89
+ loading: i.value,
90
+ onClick: I
87
91
  }, {
88
92
  default: m(() => [
89
- M(i(e(a)("common.save")), 1)
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": u.value }])
101
+ class: x(["gs", { "is-narrow": d.value }])
98
102
  }, [
99
- v(P, {
100
- tree: l.tree,
101
- granted: l.granted,
102
- modules: l.modules,
103
- "default-module-id": l.defaultModuleId,
104
- compact: u.value,
105
- "onUpdate:checked": t[0] || (t[0] = (n) => f.value = n),
106
- onSummary: t[1] || (t[1] = (n) => o.value = n)
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
- X as default
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","_hoisted_1","_toDisplayString","_createElementBlock","_hoisted_2","_createVNode","NButton","GrantMenuTable","_cache"],"mappings":"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"}
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":";;;;;;;;;;;GA6BMA,IAAU;;;;;;;;;;;;;;;AAfhB,UAAMC,IAAOC,EAAoBC,GAAC,MAA0B,GAEtDC,IAAQD,GAUR,EAAE,GAAAE,EAAA,IAAMC,EAAA,GAIR,EAAE,OAAOC,EAAA,IAASC,EAAA,GAClBC,IAAUC,EAAS,MAAMH,EAAK,SAASP,CAAO,GAE9CW,IAAaD;AAAA,MAAS,MAC1BD,EAAQ,QACJ,EAAE,OAAO,sBAAsB,QAAQ,sBAAA,IACvC,EAAE,OAAO,kCAAkC,QAAQ,kCAAA;AAAA,IAAkC,GAGrFG,IAAUF,EAAS,MAAOD,EAAQ,QAAQ,UAAU,QAAS,GAC7DI,IAA8B;AAAA,MAClC,SAAS;AAAA,MACT,eAAe;AAAA,MACf,MAAM;AAAA,MACN,WAAW;AAAA,MACX,SAAS;AAAA,MACT,UAAU;AAAA,IAAA,GAENC,IAAc,EAAE,SAAS,IAAA,GAGzBC,IAAUC,EAAqB,EAAE,GACjCC,IAAUC,EAAkB,EAAE,IAAI,GAAG,OAAO,GAAG,OAAO,GAAG,SAAS,GAAG,OAAO,IAAO;AACzF,IAAAC;AAAA,MACElB;AAAA,MACA,CAAAmB,MAAK;AACH,QAAIA,MAAGL,EAAQ,QAAQX,EAAM;AAAA,MAC/B;AAAA,MACA,EAAE,WAAW,GAAA;AAAA,IAAK;AAGpB,UAAMiB,IAASH,EAAI,EAAK,GAElBI,IAAWZ,EAAS,MAAM,CAACW,EAAO,KAAK;AAE7C,mBAAeE,IAAa;AAC1B,MAAAF,EAAO,QAAQ;AACf,UAAI;AACF,QAAK,MAAMjB,EAAM,OAAOW,EAAQ,KAAK,MAAO,SAAY,QAAQ;AAAA,MAClE,QAAQ;AAAA,MAER,UAAA;AACE,QAAAM,EAAO,QAAQ;AAAA,MACjB;AAAA,IACF;2BAIEG,EA0CUC,EAAAC,CAAA,GAAA;AAAA,MAzCA,MAAMzB,EAAA;AAAA,8CAAAA,EAAI,QAAA0B;AAAA,MAClB,QAAO;AAAA,MACN,OAAOF,EAAApB,CAAA,EAAC,iBAAA;AAAA,MACR,UAAUiB,EAAA;AAAA,MACV,gBAAcA,EAAA;AAAA,MACd,iBAAe;AAAA,MACf,cAAY;AAAA,MACZ,SAAOX,EAAA,KAAU;AAAA,MACjB,iBAAeE;AAAA,MACf,gBAAcC;AAAA,IAAA;MAeJ,UACT,MAcS;AAAA,QAdTc,EAcS,UAAA;AAAA,UAdD,OAAKC,EAAA,CAAC,WAAS,EAAA,aAAwBpB,EAAA,OAAO,CAAA;AAAA,QAAA;UACpDmB,EAMM,OANNE,GAMM;AAAA,YALJF,EAAmF,QAAA,MAAAG,EAA1EN,KAAC,qBAAA,EAAA,IAA4BR,EAAA,MAAQ,IAAE,OAASA,EAAA,MAAQ,OAAK,CAAA,GAAA,CAAA;AAAA,YACtEW,EAEO,QAAA,MAAAG,EADFN,KAAC,0BAAA,EAAA,OAAoCR,EAAA,MAAQ,OAAK,SAAWA,EAAA,MAAQ,SAAO,CAAA,GAAA,CAAA;AAAA,YAErEA,EAAA,MAAQ,cAApBe,EAA+E,QAA/EC,GAA+EF,EAAhCN,EAAApB,CAAA,EAAC,mBAAA,CAAA,GAAA,CAAA;;UAElD6B,EAEWT,EAAAU,CAAA,GAAA;AAAA,YAFA,MAAMvB,EAAA;AAAA,YAAU,UAAUS,EAAA;AAAA,YAAS,gCAAOpB,EAAA,QAAI;AAAA,UAAA;uBACvD,MAAwB;AAAA,kBAArBwB,EAAApB,CAAA,EAAC,eAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;;UAEN6B,EAEWT,EAAAU,CAAA,GAAA;AAAA,YAFD,MAAK;AAAA,YAAW,MAAMvB,EAAA;AAAA,YAAU,SAASS,EAAA;AAAA,YAAS,SAAOE;AAAA,UAAA;uBACjE,MAAsB;AAAA,kBAAnBE,EAAApB,CAAA,EAAC,aAAA,CAAA,GAAA,CAAA;AAAA,YAAA;;;;;iBA1BV,MAWM;AAAA,QAXNuB,EAWM,OAAA;AAAA,UAXD,OAAKC,EAAA,CAAC,MAAI,EAAA,aAAwBpB,EAAA,OAAO,CAAA;AAAA,QAAA;UACnCN,EAAA,aAAT6B,EAA6C,KAA7CI,GAA6CL,EAAX5B,EAAA,IAAI,GAAA,CAAA;UACtC+B,EAQEG,GAAA;AAAA,YAPC,MAAMlC,EAAA;AAAA,YACN,SAASA,EAAA;AAAA,YACT,SAASA,EAAA;AAAA,YACT,qBAAmBA,EAAA;AAAA,YACnB,SAASM,EAAA;AAAA,YACT,oBAAc6B,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAX,MAAEZ,EAAA,QAAUY;AAAA,YAC1B,WAAOW,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAA,CAAAX,MAAEV,EAAA,QAAUU;AAAA,UAAA;;;;;;;"}
@@ -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-4bf1bdcb"]]);
4
+ const f = /* @__PURE__ */ t(o, [["__scopeId", "data-v-594886fc"]]);
5
5
  export {
6
6
  f as default
7
7
  };