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,29 +1,29 @@
1
- import { defineComponent as j, ref as m, computed as b, h as d, resolveDirective as K, openBlock as f, createElementBlock as z, Fragment as Q, createVNode as r, unref as t, withCtx as a, withDirectives as X, createBlock as _, createTextVNode as k, toDisplayString as i, normalizeStyle as Y, normalizeClass as Z, createElementVNode as c, createCommentVNode as O } from "vue";
1
+ import { defineComponent as j, ref as m, computed as b, h as d, resolveDirective as K, openBlock as h, createElementBlock as z, Fragment as Q, createVNode as r, unref as t, withCtx as a, withDirectives as X, createBlock as _, createTextVNode as w, toDisplayString as i, normalizeStyle as Y, normalizeClass as Z, createElementVNode as c, createCommentVNode as O } from "vue";
2
2
  import { useElementSize as ee } from "@vueuse/core";
3
3
  import { useMessage as te, NButton as D, NDrawer as le, NDrawerContent as oe, NDescriptions as ae, NDescriptionsItem as n, NTag as re } from "naive-ui";
4
4
  import { useI18n as se } from "vue-i18n";
5
5
  import { SmartTable as ie } from "smart-naive-table";
6
6
  import ne from "../../../../components/AppIcon.vue.js";
7
7
  import ce from "../../../../components/CodeBlock/index.vue.js";
8
- import ue from "../../../../components/ExportColumnsModal/index.vue.js";
9
- import { useConfirm as pe } from "../../../../composables/useConfirm.js";
8
+ import pe from "../../../../components/ExportColumnsModal/index.vue.js";
9
+ import { useConfirm as ue } from "../../../../composables/useConfirm.js";
10
10
  import { logApi as C, userApi as me } from "../../../../api/index.js";
11
11
  import { useAuthStore as de } from "../../../../stores/auth.js";
12
12
  import { translateError as I } from "../../../../utils/error.js";
13
- import { createFlatFilterSerializer as fe, SEARCH_ACTIONS as g, deriveHeaderFilters as he, flatSearchOf as ge, loadWithinServerMax as ve } from "../../../../utils/tableFilter.js";
13
+ import { createFlatFilterSerializer as he, SEARCH_ACTIONS as g, deriveHeaderFilters as fe, flatSearchOf as ge, loadWithinServerMax as ve } from "../../../../utils/tableFilter.js";
14
14
  import { TABLE_TOOLBAR as ye, TABLE_MIN_ROW_HEIGHT as be } from "../../../../utils/tableToolbar.js";
15
15
  import _e from "../../../../components/TableTotal/index.vue.js";
16
16
  import { operatorText as A, fmtDateTime as B } from "../../../../utils/format.js";
17
- import { triggerBlobDownload as ke } from "../../../../utils/download.js";
18
- const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num" }, Ce = { class: "exception" }, Ne = { class: "num" }, Ee = { class: "mono" }, Se = { class: "muted break" }, Me = { class: "num" }, ze = { key: 1 }, Ke = /* @__PURE__ */ j({
17
+ import { triggerBlobDownload as we } from "../../../../utils/download.js";
18
+ const ke = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num" }, Ce = { class: "exception" }, Ne = { class: "num" }, Ee = { class: "mono" }, Se = { class: "muted break" }, Me = { class: "num" }, ze = { key: 1 }, Ke = /* @__PURE__ */ j({
19
19
  __name: "index",
20
20
  setup(Oe) {
21
- const { t: e } = se(), w = te(), { confirm: R } = pe(), H = de(), v = m(), y = m(!1), x = m(!1), L = b(
21
+ const { t: e } = se(), k = te(), { confirm: R } = ue(), H = de(), v = m(), y = m(!1), x = m(!1), L = b(
22
22
  () => {
23
23
  var l;
24
24
  return (l = v.value) == null ? void 0 : l.$el;
25
25
  }
26
- ), { width: N } = ee(L), p = b(() => N.value > 0 && N.value < 600), $ = b(
26
+ ), { width: N } = ee(L), u = b(() => N.value > 0 && N.value < 600), $ = b(
27
27
  () => H.hasPerm("GET:/api/v1/sys/log/op/export") ? [{ label: e("export.button"), key: "export" }] : []
28
28
  ), F = b(() => ({ ...ye, more: $.value }));
29
29
  function J(l) {
@@ -45,7 +45,7 @@ const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num"
45
45
  const o = ge(v.value, E);
46
46
  x.value = !0;
47
47
  try {
48
- const h = await C.opExport({
48
+ const f = await C.opExport({
49
49
  title: o.title || void 0,
50
50
  success: o.success,
51
51
  operatorId: o.operatorId != null ? Number(o.operatorId) : void 0,
@@ -53,14 +53,14 @@ const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num"
53
53
  createTime: o.createTime ?? null,
54
54
  columns: l.join(",")
55
55
  });
56
- ke(h, e("logOp.fileName")), y.value = !1, w.success(e("export.done"));
57
- } catch (h) {
58
- w.error(I(h));
56
+ we(f, e("logOp.fileName")), y.value = !1, k.success(e("export.done"));
57
+ } catch (f) {
58
+ k.error(I(f));
59
59
  } finally {
60
60
  x.value = !1;
61
61
  }
62
62
  }
63
- const E = fe({ ranges: ["createTime"] }), S = m([]);
63
+ const E = he({ ranges: ["createTime"] }), S = m([]);
64
64
  async function W() {
65
65
  try {
66
66
  const { items: l } = await ve(me.page, 1e3);
@@ -71,7 +71,13 @@ const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num"
71
71
  W();
72
72
  const M = [
73
73
  { type: "index", title: () => e("common.rowNo"), width: 64, align: "center" },
74
- { key: "title", title: () => e("log.opName"), search: { actions: g.fuzzy } },
74
+ {
75
+ key: "title",
76
+ width: 220,
77
+ ellipsis: { tooltip: !0 },
78
+ title: () => e("log.opName"),
79
+ search: { actions: g.fuzzy }
80
+ },
75
81
  { key: "httpMethod", title: () => e("log.method"), width: 90 },
76
82
  {
77
83
  key: "path",
@@ -82,6 +88,7 @@ const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num"
82
88
  },
83
89
  {
84
90
  key: "success",
91
+ width: 90,
85
92
  title: () => e("log.result"),
86
93
  tag: !0,
87
94
  search: { actions: g.exact },
@@ -120,6 +127,8 @@ const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num"
120
127
  },
121
128
  {
122
129
  key: "ip",
130
+ width: 140,
131
+ ellipsis: { tooltip: !0 },
123
132
  title: () => e("log.ip"),
124
133
  render: (l) => d("span", { class: "mono muted" }, l.ip || "—")
125
134
  },
@@ -127,6 +136,7 @@ const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num"
127
136
  // api 层拆成 StartTime/EndTime 并把结束日补到 23:59:59。
128
137
  {
129
138
  key: "createTime",
139
+ width: 170,
130
140
  title: () => e("common.createTime"),
131
141
  render: (l) => d("span", { class: "num muted", style: "white-space: nowrap" }, B(l.createTime)),
132
142
  search: { type: "daterange", actions: g.dayRange }
@@ -144,7 +154,7 @@ const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num"
144
154
  )
145
155
  }
146
156
  ];
147
- he(M);
157
+ fe(M);
148
158
  const T = m(!1), s = m(null);
149
159
  function G(l) {
150
160
  s.value = l, T.value = !0;
@@ -168,8 +178,8 @@ const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num"
168
178
  });
169
179
  }
170
180
  return (l, o) => {
171
- const h = K("auth");
172
- return f(), z(Q, null, [
181
+ const f = K("auth");
182
+ return h(), z(Q, null, [
173
183
  r(t(ie), {
174
184
  ref_key: "tableRef",
175
185
  ref: v,
@@ -183,13 +193,13 @@ const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num"
183
193
  "card-on-narrow": "",
184
194
  "storage-key": "sys-log-op",
185
195
  onMoreSelect: J,
186
- onError: o[0] || (o[0] = (u) => t(w).error(t(I)(u)))
196
+ onError: o[0] || (o[0] = (p) => t(k).error(t(I)(p)))
187
197
  }, {
188
- "pagination-prefix": a(({ itemCount: u }) => [
189
- r(_e, { count: u }, null, 8, ["count"])
198
+ "pagination-prefix": a(({ itemCount: p }) => [
199
+ r(_e, { count: p }, null, 8, ["count"])
190
200
  ]),
191
201
  "toolbar-right": a(() => [
192
- X((f(), _(t(D), {
202
+ X((h(), _(t(D), {
193
203
  type: "error",
194
204
  secondary: "",
195
205
  onClick: q
@@ -201,39 +211,39 @@ const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num"
201
211
  })
202
212
  ]),
203
213
  default: a(() => [
204
- k(" " + i(t(e)("log.clear")), 1)
214
+ w(" " + i(t(e)("log.clear")), 1)
205
215
  ]),
206
216
  _: 1
207
217
  })), [
208
- [h, "DELETE:/api/v1/sys/log/op"]
218
+ [f, "DELETE:/api/v1/sys/log/op"]
209
219
  ])
210
220
  ]),
211
221
  _: 1
212
222
  }, 8, ["fetcher", "filter-serializer", "toolbar", "min-row-height"]),
213
- r(ue, {
223
+ r(pe, {
214
224
  show: y.value,
215
- "onUpdate:show": o[1] || (o[1] = (u) => y.value = u),
225
+ "onUpdate:show": o[1] || (o[1] = (p) => y.value = p),
216
226
  columns: P,
217
227
  loading: x.value,
218
228
  onConfirm: V
219
229
  }, null, 8, ["show", "loading"]),
220
230
  r(t(le), {
221
231
  show: T.value,
222
- "onUpdate:show": o[2] || (o[2] = (u) => T.value = u),
223
- placement: p.value ? "bottom" : "right",
224
- width: p.value ? void 0 : "min(560px, 100vw)",
225
- height: p.value ? "auto" : void 0,
226
- class: Z(p.value ? "st-sheet" : ""),
227
- style: Y(p.value ? "max-height: 85vh" : "")
232
+ "onUpdate:show": o[2] || (o[2] = (p) => T.value = p),
233
+ placement: u.value ? "bottom" : "right",
234
+ width: u.value ? void 0 : "min(560px, 100vw)",
235
+ height: u.value ? "auto" : void 0,
236
+ class: Z(u.value ? "st-sheet" : ""),
237
+ style: Y(u.value ? "max-height: 85vh" : "")
228
238
  }, {
229
239
  default: a(() => [
230
240
  r(t(oe), {
231
241
  title: t(e)("log.detail"),
232
242
  closable: "",
233
- "native-scrollbar": p.value
243
+ "native-scrollbar": u.value
234
244
  }, {
235
245
  default: a(() => [
236
- s.value ? (f(), _(t(ae), {
246
+ s.value ? (h(), _(t(ae), {
237
247
  key: 0,
238
248
  "label-placement": "left",
239
249
  column: 1,
@@ -246,7 +256,7 @@ const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num"
246
256
  label: t(e)("log.opName")
247
257
  }, {
248
258
  default: a(() => [
249
- c("span", we, i(s.value.title), 1)
259
+ c("span", ke, i(s.value.title), 1)
250
260
  ]),
251
261
  _: 1
252
262
  }, 8, ["label"]),
@@ -254,7 +264,7 @@ const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num"
254
264
  label: t(e)("log.method")
255
265
  }, {
256
266
  default: a(() => [
257
- k(i(s.value.httpMethod), 1)
267
+ w(i(s.value.httpMethod), 1)
258
268
  ]),
259
269
  _: 1
260
270
  }, 8, ["label"]),
@@ -276,7 +286,7 @@ const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num"
276
286
  bordered: !1
277
287
  }, {
278
288
  default: a(() => [
279
- k(i(s.value.success ? t(e)("log.success") : t(e)("log.failed")), 1)
289
+ w(i(s.value.success ? t(e)("log.success") : t(e)("log.failed")), 1)
280
290
  ]),
281
291
  _: 1
282
292
  }, 8, ["type"])
@@ -291,7 +301,7 @@ const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num"
291
301
  ]),
292
302
  _: 1
293
303
  }, 8, ["label"]),
294
- s.value.exceptionMessage ? (f(), _(t(n), {
304
+ s.value.exceptionMessage ? (h(), _(t(n), {
295
305
  key: 0,
296
306
  label: t(e)("log.exception")
297
307
  }, {
@@ -312,7 +322,7 @@ const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num"
312
322
  label: t(e)("log.operator")
313
323
  }, {
314
324
  default: a(() => [
315
- k(i(t(A)(s.value)), 1)
325
+ w(i(t(A)(s.value)), 1)
316
326
  ]),
317
327
  _: 1
318
328
  }, 8, ["label"]),
@@ -344,10 +354,10 @@ const we = { class: "break" }, xe = { class: "mono break" }, Te = { class: "num"
344
354
  label: t(e)("log.param")
345
355
  }, {
346
356
  default: a(() => [
347
- s.value.paramJson ? (f(), _(ce, {
357
+ s.value.paramJson ? (h(), _(ce, {
348
358
  key: 0,
349
359
  code: U(s.value.paramJson)
350
- }, null, 8, ["code"])) : (f(), z("span", ze, "—"))
360
+ }, null, 8, ["code"])) : (h(), z("span", ze, "—"))
351
361
  ]),
352
362
  _: 1
353
363
  }, 8, ["label"])
@@ -1 +1 @@
1
- {"version":3,"file":"index2.vue.js","sources":["../../../../../src/views/system/log/op/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 操作日志 = 只读 SmartTable + 详情抽屉。后端无 op/{id},分页项已含全字段 → 抽屉直接用行数据。\n// 搜索区要能答审计的三个问题:谁(操作人)、什么时候(时间范围)、干了什么(操作名/路径/成败)。\n// paramJson 走 CodeBlock(json 高亮 + 复制;美化是 parse→stringify,失败原样);异常堆栈保持危险色 <pre>——堆栈非代码,高亮无意义。\n// 导出:ExportColumnsModal 选列 + 当前筛选条件。\nimport { computed, h, ref } from 'vue'\nimport { useElementSize } from '@vueuse/core'\nimport {\n NButton,\n NTag,\n NDrawer,\n NDrawerContent,\n NDescriptions,\n NDescriptionsItem,\n useMessage,\n} from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport { SmartTable, type SmartTableColumn, type SmartTableInst } from 'smart-naive-table'\nimport AppIcon from '#/components/AppIcon.vue'\nimport CodeBlock from '#/components/CodeBlock/index.vue'\nimport ExportColumnsModal from '#/components/ExportColumnsModal/index.vue'\nimport { useConfirm } from '#/composables/useConfirm'\nimport { logApi, userApi } from '#/api'\nimport { useAuthStore } from '#/stores/auth'\nimport { translateError } from '#/utils/error'\nimport {\n SEARCH_ACTIONS,\n createFlatFilterSerializer,\n flatSearchOf,\n loadWithinServerMax,\n deriveHeaderFilters,\n} from '#/utils/tableFilter'\nimport { TABLE_MIN_ROW_HEIGHT, TABLE_TOOLBAR } from '#/utils/tableToolbar'\nimport TableTotal from '#/components/TableTotal/index.vue'\nimport { fmtDateTime, operatorText } from '#/utils/format'\nimport { triggerBlobDownload } from '#/utils/download'\nimport type { ExportColumnDef, SysOpLog } from '#/types/api'\n\nconst { t } = useI18n()\nconst message = useMessage()\nconst { confirm } = useConfirm()\nconst authStore = useAuthStore()\nconst tableRef = ref<SmartTableInst<SysOpLog>>()\n\nconst exportShow = ref(false)\nconst exporting = ref(false)\n\n// 详情抽屉的窄档判据:直接读表格根节点的宽度,与库的窄档(容器 < 600,卡片列表)同源同值,\n// 不用视口近似。窄档详情从底部抽屉弹出(宽档右侧抽屉)。未量到宽度(0)时按宽档处理。\nconst tableEl = computed(\n () => (tableRef.value as unknown as { $el?: HTMLElement } | undefined)?.$el,\n)\nconst { width: tableWidth } = useElementSize(tableEl)\nconst isNarrow = computed(() => tableWidth.value > 0 && tableWidth.value < 600)\n\n// 导出收进表格内置的「更多」菜单;没有导出权限时 more 为空数组,按钮不出现。\nconst toolbarMore = computed(() =>\n authStore.hasPerm('GET:/api/v1/sys/log/op/export')\n ? [{ label: t('export.button'), key: 'export' }]\n : [],\n)\n// 引用稳定的 toolbar 配置:不要把 `{ ...TABLE_TOOLBAR, more }` 直接写进模板,那样每次重渲染都会新建一个对象\nconst toolbar = computed(() => ({ ...TABLE_TOOLBAR, more: toolbarMore.value }))\nfunction onMoreSelect(key: string | number) {\n if (key === 'export') exportShow.value = true\n}\n\n/** 与后端 OpLogExportProfile.Columns 对齐。 */\nconst opExportColumns: ExportColumnDef[] = [\n { key: 'Title', title: t('log.opName') },\n { key: 'HttpMethod', title: t('log.method') },\n { key: 'Path', title: t('log.path') },\n { key: 'ResultCode', title: t('log.resultCode') },\n { key: 'Success', title: t('log.success') },\n { key: 'OperatorName', title: t('log.operator') },\n { key: 'Ip', title: t('log.ip') },\n { key: 'ElapsedMs', title: t('log.elapsed') },\n { key: 'CreateTime', title: t('common.createTime') },\n { key: 'ExceptionMessage', title: t('log.exceptionMessage'), defaultSelected: false },\n]\n\nasync function onExport(keys: string[]) {\n // 搜索值在过滤态里,flatSearchOf 用同一个序列化器还原成与列表请求一致的扁平键\n const p = flatSearchOf(tableRef.value, filterSerializer)\n exporting.value = true\n try {\n const blob = await logApi.opExport({\n title: p.title || undefined,\n success: p.success,\n operatorId: p.operatorId != null ? Number(p.operatorId) : undefined,\n path: p.path || undefined,\n createTime: p.createTime ?? null,\n columns: keys.join(','),\n })\n triggerBlobDownload(blob, t('logOp.fileName'))\n exportShow.value = false\n message.success(t('export.done'))\n } catch (e) {\n message.error(translateError(e))\n } finally {\n exporting.value = false\n }\n}\n\n// 日期区间:条件构造器里是同一字段的两行(大于等于 + 小于等于),序列化器合并成 [起, 止],\n// api 层 splitRange 再拆成 StartTime/EndTime 并给结束日补 23:59:59。\nconst filterSerializer = createFlatFilterSerializer({ ranges: ['createTime'] })\n\n// 操作人下拉的选项源:取前 1000 个用户。\n// 用选项列而不是 UserSelect(远程搜索):条件构造器放不下自定义控件。\n// 当前限制:用户超过 1000 时,排在后面的人在这里选不到。\nconst operatorOptions = ref<{ label: string; value: number }[]>([])\nasync function loadOperatorOptions() {\n try {\n // 应用把 MaxPageSize 调到 1000 以下时,loadWithinServerMax 按后端回的上限重取一次\n const { items } = await loadWithinServerMax(userApi.page, 1000)\n operatorOptions.value = items.map(u => ({ label: `${u.name}(${u.account})`, value: u.id }))\n } catch {\n // 静默:人员下拉是筛选辅助,拉取失败不打断列表\n }\n}\nvoid loadOperatorOptions()\n\nconst columns: SmartTableColumn<SysOpLog>[] = [\n { type: 'index', title: () => t('common.rowNo'), width: 64, align: 'center' },\n { key: 'title', title: () => t('log.opName'), search: { actions: SEARCH_ACTIONS.fuzzy } },\n { key: 'httpMethod', title: () => t('log.method'), width: 90 },\n {\n key: 'path',\n title: () => t('log.path'),\n ellipsis: { tooltip: true },\n search: { actions: SEARCH_ACTIONS.fuzzy },\n render: r => h('span', { class: 'mono muted' }, r.path),\n },\n {\n key: 'success',\n title: () => t('log.result'),\n tag: true,\n search: { actions: SEARCH_ACTIONS.exact },\n options: [\n { label: () => t('log.success'), value: true, tagType: 'success' },\n { label: () => t('log.failed'), value: false, tagType: 'error' },\n ],\n },\n {\n key: 'resultCode',\n title: () => t('log.resultCode'),\n width: 100,\n render: r => h('span', { class: 'num' }, String(r.resultCode)),\n },\n {\n key: 'operator',\n title: () => t('log.operator'),\n width: 120,\n ellipsis: { tooltip: true },\n render: r => operatorText(r),\n },\n // 操作人搜索项:日志只存 OperatorId(姓名是读取时回填的),按人筛必须是精确 Id(后端 OperatorId ==)。\n // 只作搜索项,不进表格也不进列设置;展示列是上面的 operator。\n {\n key: 'operatorId',\n title: () => t('log.operator'),\n hideInTable: true,\n options: operatorOptions,\n search: { actions: SEARCH_ACTIONS.exact, props: { clearable: true, filterable: true } },\n },\n {\n key: 'elapsedMs',\n title: () => t('log.elapsed'),\n width: 100,\n render: r => h('span', { class: 'num' }, `${r.elapsedMs} ms`),\n },\n {\n key: 'ip',\n title: () => t('log.ip'),\n render: r => h('span', { class: 'mono muted' }, r.ip || '—'),\n },\n // 时间范围是审计最常用的一刀(\"上周三下午谁删了那批数据\");daterange 回传 ['YYYY-MM-DD','YYYY-MM-DD'],\n // api 层拆成 StartTime/EndTime 并把结束日补到 23:59:59。\n {\n key: 'createTime',\n title: () => t('common.createTime'),\n render: r =>\n h('span', { class: 'num muted', style: 'white-space: nowrap' }, fmtDateTime(r.createTime)),\n search: { type: 'daterange', actions: SEARCH_ACTIONS.dayRange },\n },\n {\n key: 'op',\n title: () => t('common.operation'),\n width: 90,\n fixed: 'right',\n hideInSetting: true,\n render: r =>\n h(\n NButton,\n { size: 'small', quaternary: true, type: 'primary', onClick: () => openDetail(r) },\n () => t('log.detail'),\n ),\n },\n]\nderiveHeaderFilters(columns)\n\n// ── 详情抽屉(只读,行数据直填)──\nconst showDetail = ref(false)\nconst detailRow = ref<SysOpLog | null>(null)\nfunction openDetail(r: SysOpLog) {\n detailRow.value = r\n showDetail.value = true\n}\n/** paramJson 美化:parse→stringify(2);非法 JSON 原样返回。空值占位由模板判空。 */\nfunction prettyParam(json: string) {\n try {\n return JSON.stringify(JSON.parse(json), null, 2)\n } catch {\n return json\n }\n}\n\nfunction clearLogs() {\n confirm({\n type: 'error',\n content: t('log.clearOpConfirm'),\n action: () => logApi.opClear(),\n successMsg: t('log.cleared'),\n }).then(ok => {\n if (ok) tableRef.value?.refresh()\n })\n}\n</script>\n\n<template>\n <SmartTable\n ref=\"tableRef\"\n :columns=\"columns\"\n :fetcher=\"logApi.opPage\"\n :search=\"{ container: 'table' }\"\n :filter-serializer=\"filterSerializer\"\n :toolbar=\"toolbar\"\n fill-height\n :min-row-height=\"TABLE_MIN_ROW_HEIGHT\"\n card-on-narrow\n storage-key=\"sys-log-op\"\n @more-select=\"onMoreSelect\"\n @error=\"e => message.error(translateError(e))\"\n >\n <template #pagination-prefix=\"{ itemCount }\">\n <TableTotal :count=\"itemCount\" />\n </template>\n <template #toolbar-right>\n <n-button v-auth=\"'DELETE:/api/v1/sys/log/op'\" type=\"error\" secondary @click=\"clearLogs\">\n <template #icon><AppIcon icon=\"ph:trash\" :size=\"16\" /></template>\n {{ t('log.clear') }}\n </n-button>\n </template>\n </SmartTable>\n\n <ExportColumnsModal\n v-model:show=\"exportShow\"\n :columns=\"opExportColumns\"\n :loading=\"exporting\"\n @confirm=\"onExport\"\n />\n\n <!-- 详情抽屉:宽档右侧 560,窄档底部抽屉(.st-sheet 由全局样式补圆角与滚动链);没有响应体,只有脱敏后的入参 -->\n <n-drawer\n v-model:show=\"showDetail\"\n :placement=\"isNarrow ? 'bottom' : 'right'\"\n :width=\"isNarrow ? undefined : 'min(560px, 100vw)'\"\n :height=\"isNarrow ? 'auto' : undefined\"\n :class=\"isNarrow ? 'st-sheet' : ''\"\n :style=\"isNarrow ? 'max-height: 85vh' : ''\"\n >\n <n-drawer-content :title=\"t('log.detail')\" closable :native-scrollbar=\"isNarrow\">\n <n-descriptions\n v-if=\"detailRow\"\n label-placement=\"left\"\n :column=\"1\"\n bordered\n size=\"small\"\n label-style=\"width: 96px\"\n >\n <n-descriptions-item :label=\"t('log.opName')\">\n <span class=\"break\">{{ detailRow.title }}</span>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.method')\">\n {{ detailRow.httpMethod }}\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.path')\">\n <span class=\"mono break\">{{ detailRow.path }}</span>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.result')\">\n <n-tag :type=\"detailRow.success ? 'success' : 'error'\" size=\"small\" :bordered=\"false\">\n {{ detailRow.success ? t('log.success') : t('log.failed') }}\n </n-tag>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.resultCode')\">\n <span class=\"num\">{{ detailRow.resultCode }}</span>\n </n-descriptions-item>\n <n-descriptions-item v-if=\"detailRow.exceptionMessage\" :label=\"t('log.exception')\">\n <pre class=\"exception\">{{ detailRow.exceptionMessage }}</pre>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.elapsed')\">\n <span class=\"num\">{{ detailRow.elapsedMs }} ms</span>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.operator')\">\n {{ operatorText(detailRow) }}\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.ip')\">\n <span class=\"mono\">{{ detailRow.ip || '—' }}</span>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.userAgent')\">\n <span class=\"muted break\">{{ detailRow.userAgent || '—' }}</span>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('common.createTime')\">\n <span class=\"num\">{{ fmtDateTime(detailRow.createTime) }}</span>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.param')\">\n <CodeBlock v-if=\"detailRow.paramJson\" :code=\"prettyParam(detailRow.paramJson)\" />\n <span v-else>—</span>\n </n-descriptions-item>\n </n-descriptions>\n </n-drawer-content>\n </n-drawer>\n</template>\n\n<style scoped>\n.break {\n word-break: break-all;\n}\n.exception {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-all;\n font-family: var(--font-mono, ui-monospace, monospace);\n font-size: 13px;\n line-height: 1.5;\n color: var(--err, var(--color-danger));\n}\n</style>\n"],"names":["t","useI18n","message","useMessage","confirm","useConfirm","authStore","useAuthStore","tableRef","ref","exportShow","exporting","tableEl","computed","_a","tableWidth","useElementSize","isNarrow","toolbarMore","toolbar","TABLE_TOOLBAR","onMoreSelect","key","opExportColumns","onExport","keys","p","flatSearchOf","filterSerializer","blob","logApi","triggerBlobDownload","e","translateError","createFlatFilterSerializer","operatorOptions","loadOperatorOptions","items","loadWithinServerMax","userApi","u","columns","SEARCH_ACTIONS","h","r","operatorText","fmtDateTime","NButton","openDetail","deriveHeaderFilters","showDetail","detailRow","prettyParam","json","clearLogs","ok","_createVNode","_unref","SmartTable","TABLE_MIN_ROW_HEIGHT","_cache","_withCtx","itemCount","TableTotal","_createBlock","AppIcon","_createTextVNode","ExportColumnsModal","$event","NDrawer","NDrawerContent","NDescriptions","NDescriptionsItem","_createElementVNode","_hoisted_1","_toDisplayString","_hoisted_2","NTag","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","CodeBlock","_openBlock","_createElementBlock"],"mappings":"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"}
1
+ {"version":3,"file":"index2.vue.js","sources":["../../../../../src/views/system/log/op/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 操作日志 = 只读 SmartTable + 详情抽屉。后端无 op/{id},分页项已含全字段 → 抽屉直接用行数据。\n// 搜索区要能答审计的三个问题:谁(操作人)、什么时候(时间范围)、干了什么(操作名/路径/成败)。\n// paramJson 走 CodeBlock(json 高亮 + 复制;美化是 parse→stringify,失败原样);异常堆栈保持危险色 <pre>——堆栈非代码,高亮无意义。\n// 导出:ExportColumnsModal 选列 + 当前筛选条件。\nimport { computed, h, ref } from 'vue'\nimport { useElementSize } from '@vueuse/core'\nimport {\n NButton,\n NTag,\n NDrawer,\n NDrawerContent,\n NDescriptions,\n NDescriptionsItem,\n useMessage,\n} from 'naive-ui'\nimport { useI18n } from 'vue-i18n'\nimport { SmartTable, type SmartTableColumn, type SmartTableInst } from 'smart-naive-table'\nimport AppIcon from '#/components/AppIcon.vue'\nimport CodeBlock from '#/components/CodeBlock/index.vue'\nimport ExportColumnsModal from '#/components/ExportColumnsModal/index.vue'\nimport { useConfirm } from '#/composables/useConfirm'\nimport { logApi, userApi } from '#/api'\nimport { useAuthStore } from '#/stores/auth'\nimport { translateError } from '#/utils/error'\nimport {\n SEARCH_ACTIONS,\n createFlatFilterSerializer,\n flatSearchOf,\n loadWithinServerMax,\n deriveHeaderFilters,\n} from '#/utils/tableFilter'\nimport { TABLE_MIN_ROW_HEIGHT, TABLE_TOOLBAR } from '#/utils/tableToolbar'\nimport TableTotal from '#/components/TableTotal/index.vue'\nimport { fmtDateTime, operatorText } from '#/utils/format'\nimport { triggerBlobDownload } from '#/utils/download'\nimport type { ExportColumnDef, SysOpLog } from '#/types/api'\n\nconst { t } = useI18n()\nconst message = useMessage()\nconst { confirm } = useConfirm()\nconst authStore = useAuthStore()\nconst tableRef = ref<SmartTableInst<SysOpLog>>()\n\nconst exportShow = ref(false)\nconst exporting = ref(false)\n\n// 详情抽屉的窄档判据:直接读表格根节点的宽度,与库的窄档(容器 < 600,卡片列表)同源同值,\n// 不用视口近似。窄档详情从底部抽屉弹出(宽档右侧抽屉)。未量到宽度(0)时按宽档处理。\nconst tableEl = computed(\n () => (tableRef.value as unknown as { $el?: HTMLElement } | undefined)?.$el,\n)\nconst { width: tableWidth } = useElementSize(tableEl)\nconst isNarrow = computed(() => tableWidth.value > 0 && tableWidth.value < 600)\n\n// 导出收进表格内置的「更多」菜单;没有导出权限时 more 为空数组,按钮不出现。\nconst toolbarMore = computed(() =>\n authStore.hasPerm('GET:/api/v1/sys/log/op/export')\n ? [{ label: t('export.button'), key: 'export' }]\n : [],\n)\n// 引用稳定的 toolbar 配置:不要把 `{ ...TABLE_TOOLBAR, more }` 直接写进模板,那样每次重渲染都会新建一个对象\nconst toolbar = computed(() => ({ ...TABLE_TOOLBAR, more: toolbarMore.value }))\nfunction onMoreSelect(key: string | number) {\n if (key === 'export') exportShow.value = true\n}\n\n/** 与后端 OpLogExportProfile.Columns 对齐。 */\nconst opExportColumns: ExportColumnDef[] = [\n { key: 'Title', title: t('log.opName') },\n { key: 'HttpMethod', title: t('log.method') },\n { key: 'Path', title: t('log.path') },\n { key: 'ResultCode', title: t('log.resultCode') },\n { key: 'Success', title: t('log.success') },\n { key: 'OperatorName', title: t('log.operator') },\n { key: 'Ip', title: t('log.ip') },\n { key: 'ElapsedMs', title: t('log.elapsed') },\n { key: 'CreateTime', title: t('common.createTime') },\n { key: 'ExceptionMessage', title: t('log.exceptionMessage'), defaultSelected: false },\n]\n\nasync function onExport(keys: string[]) {\n // 搜索值在过滤态里,flatSearchOf 用同一个序列化器还原成与列表请求一致的扁平键\n const p = flatSearchOf(tableRef.value, filterSerializer)\n exporting.value = true\n try {\n const blob = await logApi.opExport({\n title: p.title || undefined,\n success: p.success,\n operatorId: p.operatorId != null ? Number(p.operatorId) : undefined,\n path: p.path || undefined,\n createTime: p.createTime ?? null,\n columns: keys.join(','),\n })\n triggerBlobDownload(blob, t('logOp.fileName'))\n exportShow.value = false\n message.success(t('export.done'))\n } catch (e) {\n message.error(translateError(e))\n } finally {\n exporting.value = false\n }\n}\n\n// 日期区间:条件构造器里是同一字段的两行(大于等于 + 小于等于),序列化器合并成 [起, 止],\n// api 层 splitRange 再拆成 StartTime/EndTime 并给结束日补 23:59:59。\nconst filterSerializer = createFlatFilterSerializer({ ranges: ['createTime'] })\n\n// 操作人下拉的选项源:取前 1000 个用户。\n// 用选项列而不是 UserSelect(远程搜索):条件构造器放不下自定义控件。\n// 当前限制:用户超过 1000 时,排在后面的人在这里选不到。\nconst operatorOptions = ref<{ label: string; value: number }[]>([])\nasync function loadOperatorOptions() {\n try {\n // 应用把 MaxPageSize 调到 1000 以下时,loadWithinServerMax 按后端回的上限重取一次\n const { items } = await loadWithinServerMax(userApi.page, 1000)\n operatorOptions.value = items.map(u => ({ label: `${u.name}(${u.account})`, value: u.id }))\n } catch {\n // 静默:人员下拉是筛选辅助,拉取失败不打断列表\n }\n}\nvoid loadOperatorOptions()\n\nconst columns: SmartTableColumn<SysOpLog>[] = [\n { type: 'index', title: () => t('common.rowNo'), width: 64, align: 'center' },\n {\n key: 'title',\n width: 220,\n ellipsis: { tooltip: true },\n title: () => t('log.opName'),\n search: { actions: SEARCH_ACTIONS.fuzzy },\n },\n { key: 'httpMethod', title: () => t('log.method'), width: 90 },\n {\n key: 'path',\n title: () => t('log.path'),\n ellipsis: { tooltip: true },\n search: { actions: SEARCH_ACTIONS.fuzzy },\n render: r => h('span', { class: 'mono muted' }, r.path),\n },\n {\n key: 'success',\n width: 90,\n title: () => t('log.result'),\n tag: true,\n search: { actions: SEARCH_ACTIONS.exact },\n options: [\n { label: () => t('log.success'), value: true, tagType: 'success' },\n { label: () => t('log.failed'), value: false, tagType: 'error' },\n ],\n },\n {\n key: 'resultCode',\n title: () => t('log.resultCode'),\n width: 100,\n render: r => h('span', { class: 'num' }, String(r.resultCode)),\n },\n {\n key: 'operator',\n title: () => t('log.operator'),\n width: 120,\n ellipsis: { tooltip: true },\n render: r => operatorText(r),\n },\n // 操作人搜索项:日志只存 OperatorId(姓名是读取时回填的),按人筛必须是精确 Id(后端 OperatorId ==)。\n // 只作搜索项,不进表格也不进列设置;展示列是上面的 operator。\n {\n key: 'operatorId',\n title: () => t('log.operator'),\n hideInTable: true,\n options: operatorOptions,\n search: { actions: SEARCH_ACTIONS.exact, props: { clearable: true, filterable: true } },\n },\n {\n key: 'elapsedMs',\n title: () => t('log.elapsed'),\n width: 100,\n render: r => h('span', { class: 'num' }, `${r.elapsedMs} ms`),\n },\n {\n key: 'ip',\n width: 140,\n ellipsis: { tooltip: true },\n title: () => t('log.ip'),\n render: r => h('span', { class: 'mono muted' }, r.ip || '—'),\n },\n // 时间范围是审计最常用的一刀(\"上周三下午谁删了那批数据\");daterange 回传 ['YYYY-MM-DD','YYYY-MM-DD'],\n // api 层拆成 StartTime/EndTime 并把结束日补到 23:59:59。\n {\n key: 'createTime',\n width: 170,\n title: () => t('common.createTime'),\n render: r =>\n h('span', { class: 'num muted', style: 'white-space: nowrap' }, fmtDateTime(r.createTime)),\n search: { type: 'daterange', actions: SEARCH_ACTIONS.dayRange },\n },\n {\n key: 'op',\n title: () => t('common.operation'),\n width: 90,\n fixed: 'right',\n hideInSetting: true,\n render: r =>\n h(\n NButton,\n { size: 'small', quaternary: true, type: 'primary', onClick: () => openDetail(r) },\n () => t('log.detail'),\n ),\n },\n]\nderiveHeaderFilters(columns)\n\n// ── 详情抽屉(只读,行数据直填)──\nconst showDetail = ref(false)\nconst detailRow = ref<SysOpLog | null>(null)\nfunction openDetail(r: SysOpLog) {\n detailRow.value = r\n showDetail.value = true\n}\n/** paramJson 美化:parse→stringify(2);非法 JSON 原样返回。空值占位由模板判空。 */\nfunction prettyParam(json: string) {\n try {\n return JSON.stringify(JSON.parse(json), null, 2)\n } catch {\n return json\n }\n}\n\nfunction clearLogs() {\n confirm({\n type: 'error',\n content: t('log.clearOpConfirm'),\n action: () => logApi.opClear(),\n successMsg: t('log.cleared'),\n }).then(ok => {\n if (ok) tableRef.value?.refresh()\n })\n}\n</script>\n\n<template>\n <SmartTable\n ref=\"tableRef\"\n :columns=\"columns\"\n :fetcher=\"logApi.opPage\"\n :search=\"{ container: 'table' }\"\n :filter-serializer=\"filterSerializer\"\n :toolbar=\"toolbar\"\n fill-height\n :min-row-height=\"TABLE_MIN_ROW_HEIGHT\"\n card-on-narrow\n storage-key=\"sys-log-op\"\n @more-select=\"onMoreSelect\"\n @error=\"e => message.error(translateError(e))\"\n >\n <template #pagination-prefix=\"{ itemCount }\">\n <TableTotal :count=\"itemCount\" />\n </template>\n <template #toolbar-right>\n <n-button v-auth=\"'DELETE:/api/v1/sys/log/op'\" type=\"error\" secondary @click=\"clearLogs\">\n <template #icon><AppIcon icon=\"ph:trash\" :size=\"16\" /></template>\n {{ t('log.clear') }}\n </n-button>\n </template>\n </SmartTable>\n\n <ExportColumnsModal\n v-model:show=\"exportShow\"\n :columns=\"opExportColumns\"\n :loading=\"exporting\"\n @confirm=\"onExport\"\n />\n\n <!-- 详情抽屉:宽档右侧 560,窄档底部抽屉(.st-sheet 由全局样式补圆角与滚动链);没有响应体,只有脱敏后的入参 -->\n <n-drawer\n v-model:show=\"showDetail\"\n :placement=\"isNarrow ? 'bottom' : 'right'\"\n :width=\"isNarrow ? undefined : 'min(560px, 100vw)'\"\n :height=\"isNarrow ? 'auto' : undefined\"\n :class=\"isNarrow ? 'st-sheet' : ''\"\n :style=\"isNarrow ? 'max-height: 85vh' : ''\"\n >\n <n-drawer-content :title=\"t('log.detail')\" closable :native-scrollbar=\"isNarrow\">\n <n-descriptions\n v-if=\"detailRow\"\n label-placement=\"left\"\n :column=\"1\"\n bordered\n size=\"small\"\n label-style=\"width: 96px\"\n >\n <n-descriptions-item :label=\"t('log.opName')\">\n <span class=\"break\">{{ detailRow.title }}</span>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.method')\">\n {{ detailRow.httpMethod }}\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.path')\">\n <span class=\"mono break\">{{ detailRow.path }}</span>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.result')\">\n <n-tag :type=\"detailRow.success ? 'success' : 'error'\" size=\"small\" :bordered=\"false\">\n {{ detailRow.success ? t('log.success') : t('log.failed') }}\n </n-tag>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.resultCode')\">\n <span class=\"num\">{{ detailRow.resultCode }}</span>\n </n-descriptions-item>\n <n-descriptions-item v-if=\"detailRow.exceptionMessage\" :label=\"t('log.exception')\">\n <pre class=\"exception\">{{ detailRow.exceptionMessage }}</pre>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.elapsed')\">\n <span class=\"num\">{{ detailRow.elapsedMs }} ms</span>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.operator')\">\n {{ operatorText(detailRow) }}\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.ip')\">\n <span class=\"mono\">{{ detailRow.ip || '—' }}</span>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.userAgent')\">\n <span class=\"muted break\">{{ detailRow.userAgent || '—' }}</span>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('common.createTime')\">\n <span class=\"num\">{{ fmtDateTime(detailRow.createTime) }}</span>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.param')\">\n <CodeBlock v-if=\"detailRow.paramJson\" :code=\"prettyParam(detailRow.paramJson)\" />\n <span v-else>—</span>\n </n-descriptions-item>\n </n-descriptions>\n </n-drawer-content>\n </n-drawer>\n</template>\n\n<style scoped>\n.break {\n word-break: break-all;\n}\n.exception {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-all;\n font-family: var(--font-mono, ui-monospace, monospace);\n font-size: 13px;\n line-height: 1.5;\n color: var(--err, var(--color-danger));\n}\n</style>\n"],"names":["t","useI18n","message","useMessage","confirm","useConfirm","authStore","useAuthStore","tableRef","ref","exportShow","exporting","tableEl","computed","_a","tableWidth","useElementSize","isNarrow","toolbarMore","toolbar","TABLE_TOOLBAR","onMoreSelect","key","opExportColumns","onExport","keys","p","flatSearchOf","filterSerializer","blob","logApi","triggerBlobDownload","e","translateError","createFlatFilterSerializer","operatorOptions","loadOperatorOptions","items","loadWithinServerMax","userApi","u","columns","SEARCH_ACTIONS","h","r","operatorText","fmtDateTime","NButton","openDetail","deriveHeaderFilters","showDetail","detailRow","prettyParam","json","clearLogs","ok","_createVNode","_unref","SmartTable","TABLE_MIN_ROW_HEIGHT","_cache","_withCtx","itemCount","TableTotal","_createBlock","AppIcon","_createTextVNode","ExportColumnsModal","$event","NDrawer","NDrawerContent","NDescriptions","NDescriptionsItem","_createElementVNode","_hoisted_1","_toDisplayString","_hoisted_2","NTag","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8","CodeBlock","_openBlock","_createElementBlock"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import o from "./ButtonManager2.vue.js";
2
2
  /* empty css */
3
3
  import t from "../../../../_virtual/_plugin-vue_export-helper.js";
4
- const c = /* @__PURE__ */ t(o, [["__scopeId", "data-v-22eeccb0"]]);
4
+ const m = /* @__PURE__ */ t(o, [["__scopeId", "data-v-f2d7d871"]]);
5
5
  export {
6
- c as default
6
+ m as default
7
7
  };
8
8
  //# sourceMappingURL=ButtonManager.vue.js.map
@@ -22,15 +22,15 @@ const He = { class: "perm-hint" }, Qe = { class: "batch-route mono muted" }, mt
22
22
  appPrefix: {}
23
23
  },
24
24
  emits: ["changed"],
25
- setup(se, { expose: ie, emit: re }) {
26
- const f = se, T = re, { t: o } = je(), U = Se(), { run: de } = Fe(), $ = Ve(), G = r(() => $.hasPerm("POST:/api/v1/sys/menu/add")), me = r(() => $.hasPerm("PUT:/api/v1/sys/menu/{id}")), ce = r(() => $.hasPerm("DELETE:/api/v1/sys/menu/{id}")), pe = Ee("(max-width: 640px)"), fe = r(
25
+ setup(ie, { expose: se, emit: re }) {
26
+ const f = ie, T = re, { t: o } = je(), U = Se(), { run: de } = Fe(), $ = Ve(), G = r(() => $.hasPerm("POST:/api/v1/sys/menu/add")), me = r(() => $.hasPerm("PUT:/api/v1/sys/menu/{id}")), ce = r(() => $.hasPerm("DELETE:/api/v1/sys/menu/{id}")), pe = Ee("(max-width: 640px)"), fe = r(
27
27
  () => pe.value ? { labelPlacement: "top", labelWidth: void 0 } : { labelPlacement: "left", labelWidth: 80 }
28
28
  ), _ = d(!1), y = d(null), W = d("");
29
29
  function H(e, t) {
30
30
  for (const n of e) {
31
31
  if (n.id === t) return n;
32
- const s = H(n.children, t);
33
- if (s) return s;
32
+ const i = H(n.children, t);
33
+ if (i) return i;
34
34
  }
35
35
  return null;
36
36
  }
@@ -45,27 +45,27 @@ const He = { class: "perm-hint" }, Qe = { class: "batch-route mono muted" }, mt
45
45
  () => B.value !== "" && f.routes.some((e) => !A(e.path))
46
46
  ), c = d(!1), E = (e) => ({ label: `${e.method} ${e.path}`, value: e.code }), he = r(() => {
47
47
  if (!B.value) return f.routes.map(E);
48
- const t = f.routes.filter((s) => A(s.path));
48
+ const t = f.routes.filter((i) => A(i.path));
49
49
  if (!c.value) return t.map(E);
50
- const n = f.routes.filter((s) => !A(s.path));
50
+ const n = f.routes.filter((i) => !A(i.path));
51
51
  return [
52
52
  { type: "group", key: "__inApp", label: o("menu.routesInApp"), children: t.map(E) },
53
53
  { type: "group", key: "__other", label: o("menu.routesOther"), children: n.map(E) }
54
54
  ];
55
55
  }), be = r(() => {
56
- const e = [], t = (n, s) => {
57
- for (const w of n)
58
- w.type !== P.Button && (e.push({
59
- label: `${" ".repeat(s)}${ae(w.title, w.path || void 0)}`,
60
- value: w.id
61
- }), t(w.children, s + 1));
56
+ const e = [], t = (n, i) => {
57
+ for (const k of n)
58
+ k.type !== P.Button && (e.push({
59
+ label: `${" ".repeat(i)}${ae(k.title, k.path || void 0)}`,
60
+ value: k.id
61
+ }), t(k.children, i + 1));
62
62
  };
63
63
  return t(f.tree, 0), e;
64
64
  });
65
65
  function ye(e) {
66
66
  y.value = e.id, W.value = ae(e.title), _.value = !0;
67
67
  }
68
- ie({ open: ye });
68
+ se({ open: ye });
69
69
  const S = d(!1), g = d(null), J = d(null), ge = {
70
70
  title: {
71
71
  required: !0,
@@ -85,7 +85,7 @@ const He = { class: "perm-hint" }, Qe = { class: "batch-route mono muted" }, mt
85
85
  component: "",
86
86
  icon: "",
87
87
  visible: !0
88
- }), i = _e(X()), k = d([]), Y = (e) => ({
88
+ }), s = _e(X()), w = d([]), Y = (e) => ({
89
89
  parentId: e.parentId,
90
90
  type: e.type,
91
91
  title: e.title,
@@ -98,19 +98,19 @@ const He = { class: "perm-hint" }, Qe = { class: "batch-route mono muted" }, mt
98
98
  icon: e.icon ?? "",
99
99
  visible: e.visible
100
100
  });
101
- function ke() {
102
- g.value = null, c.value = !1, Object.assign(i, X()), k.value = [], S.value = !0;
101
+ function we() {
102
+ g.value = null, c.value = !1, Object.assign(s, X()), w.value = [], S.value = !0;
103
103
  }
104
- function we(e) {
105
- g.value = e.id, c.value = !0, Object.assign(i, Y(e)), k.value = V(e.permission), S.value = !0;
104
+ function ke(e) {
105
+ g.value = e.id, c.value = !0, Object.assign(s, Y(e)), w.value = V(e.permission), S.value = !0;
106
106
  }
107
107
  async function xe() {
108
108
  var e;
109
109
  await ((e = J.value) == null ? void 0 : e.validate());
110
110
  try {
111
111
  const t = {
112
- ...i,
113
- permission: We(k.value),
112
+ ...s,
113
+ permission: We(w.value),
114
114
  type: P.Button,
115
115
  moduleId: null
116
116
  };
@@ -165,10 +165,19 @@ const He = { class: "perm-hint" }, Qe = { class: "batch-route mono muted" }, mt
165
165
  }
166
166
  const Te = [
167
167
  { type: "index", title: () => o("common.rowNo"), width: 64, align: "center" },
168
- { title: () => o("menu.title"), key: "title", align: "left", search: {} },
168
+ {
169
+ title: () => o("menu.title"),
170
+ key: "title",
171
+ ellipsis: { tooltip: !0 },
172
+ align: "left",
173
+ search: {}
174
+ },
169
175
  {
170
176
  title: () => o("menu.permission"),
171
177
  key: "permission",
178
+ // 权限码是 `METHOD:/api/...` 的整条路由,单个 tag 就比默认列宽长,所以给足宽度,放不下的一律省略 + 悬浮提示
179
+ width: 360,
180
+ ellipsis: { tooltip: !0 },
172
181
  // 多码按钮逐条成 tag,一眼看出「查询」挂了哪几条路由
173
182
  render: (e) => {
174
183
  const t = V(e.permission);
@@ -204,7 +213,7 @@ const He = { class: "perm-hint" }, Qe = { class: "batch-route mono muted" }, mt
204
213
  render: (e) => p(b, { size: 2, justify: "end", wrapItem: !1 }, () => [
205
214
  me.value ? p(
206
215
  C,
207
- { size: "small", quaternary: !0, type: "primary", onClick: () => we(e) },
216
+ { size: "small", quaternary: !0, type: "primary", onClick: () => ke(e) },
208
217
  () => o("common.edit")
209
218
  ) : null,
210
219
  ce.value ? p(
@@ -279,7 +288,7 @@ const He = { class: "perm-hint" }, Qe = { class: "batch-route mono muted" }, mt
279
288
  G.value ? (m(), v(l(C), {
280
289
  key: 1,
281
290
  type: "primary",
282
- onClick: ke
291
+ onClick: we
283
292
  }, {
284
293
  icon: u(() => [
285
294
  a(D, {
@@ -310,7 +319,7 @@ const He = { class: "perm-hint" }, Qe = { class: "batch-route mono muted" }, mt
310
319
  a(l(ze), Be({
311
320
  ref_key: "formRef",
312
321
  ref: J,
313
- model: i,
322
+ model: s,
314
323
  rules: ge,
315
324
  "require-mark-placement": "left"
316
325
  }, fe.value), {
@@ -326,8 +335,8 @@ const He = { class: "perm-hint" }, Qe = { class: "batch-route mono muted" }, mt
326
335
  }, {
327
336
  default: u(() => [
328
337
  a(l(q), {
329
- value: i.title,
330
- "onUpdate:value": t[2] || (t[2] = (n) => i.title = n),
338
+ value: s.title,
339
+ "onUpdate:value": t[2] || (t[2] = (n) => s.title = n),
331
340
  placeholder: l(o)("menu.title")
332
341
  }, null, 8, ["value", "placeholder"])
333
342
  ]),
@@ -338,8 +347,8 @@ const He = { class: "perm-hint" }, Qe = { class: "batch-route mono muted" }, mt
338
347
  }, {
339
348
  default: u(() => [
340
349
  a(l(ne), {
341
- value: i.parentId,
342
- "onUpdate:value": t[3] || (t[3] = (n) => i.parentId = n),
350
+ value: s.parentId,
351
+ "onUpdate:value": t[3] || (t[3] = (n) => s.parentId = n),
343
352
  options: be.value,
344
353
  filterable: ""
345
354
  }, null, 8, ["value", "options"])
@@ -357,8 +366,8 @@ const He = { class: "perm-hint" }, Qe = { class: "batch-route mono muted" }, mt
357
366
  }, {
358
367
  default: u(() => [
359
368
  a(l(ne), {
360
- value: k.value,
361
- "onUpdate:value": t[4] || (t[4] = (n) => k.value = n),
369
+ value: w.value,
370
+ "onUpdate:value": t[4] || (t[4] = (n) => w.value = n),
362
371
  options: he.value,
363
372
  multiple: "",
364
373
  filterable: "",
@@ -389,8 +398,8 @@ const He = { class: "perm-hint" }, Qe = { class: "batch-route mono muted" }, mt
389
398
  }, {
390
399
  default: u(() => [
391
400
  a(l(Le), {
392
- value: i.sort,
393
- "onUpdate:value": t[6] || (t[6] = (n) => i.sort = n),
401
+ value: s.sort,
402
+ "onUpdate:value": t[6] || (t[6] = (n) => s.sort = n),
394
403
  min: 0,
395
404
  style: { width: "100%" }
396
405
  }, null, 8, ["value"])
@@ -402,8 +411,8 @@ const He = { class: "perm-hint" }, Qe = { class: "batch-route mono muted" }, mt
402
411
  }, {
403
412
  default: u(() => [
404
413
  a(l(Oe), {
405
- value: i.enabled,
406
- "onUpdate:value": t[7] || (t[7] = (n) => i.enabled = n)
414
+ value: s.enabled,
415
+ "onUpdate:value": t[7] || (t[7] = (n) => s.enabled = n)
407
416
  }, null, 8, ["value"])
408
417
  ]),
409
418
  _: 1
@@ -478,12 +487,12 @@ const He = { class: "perm-hint" }, Qe = { class: "batch-route mono muted" }, mt
478
487
  }, [
479
488
  a(l(j), {
480
489
  checked: n.checked,
481
- "onUpdate:checked": (s) => n.checked = s
490
+ "onUpdate:checked": (i) => n.checked = i
482
491
  }, null, 8, ["checked", "onUpdate:checked"]),
483
492
  le("span", Qe, h(n.method) + " " + h(n.path), 1),
484
493
  a(l(q), {
485
494
  value: n.title,
486
- "onUpdate:value": (s) => n.title = s,
495
+ "onUpdate:value": (i) => n.title = i,
487
496
  disabled: !n.checked,
488
497
  class: "batch-title"
489
498
  }, null, 8, ["value", "onUpdate:value", "disabled"])