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.
Files changed (165) 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/composables/authMenuRoute.d.ts +10 -0
  17. package/dist/composables/authMenuRoute.js +39 -23
  18. package/dist/composables/authMenuRoute.js.map +1 -1
  19. package/dist/composables/useModule.d.ts +3 -1
  20. package/dist/composables/useModule.js +44 -32
  21. package/dist/composables/useModule.js.map +1 -1
  22. package/dist/index.js +246 -242
  23. package/dist/layouts/components/SideNav.vue.js +2 -2
  24. package/dist/layouts/components/SideNav2.vue.js.map +1 -1
  25. package/dist/lib/runtime.js +1 -1
  26. package/dist/lib/watermark.d.ts +1 -1
  27. package/dist/locales/en-US.d.ts +68 -3
  28. package/dist/locales/en-US.js +74 -8
  29. package/dist/locales/en-US.js.map +1 -1
  30. package/dist/locales/kernelMenuTitles.js +1 -0
  31. package/dist/locales/kernelMenuTitles.js.map +1 -1
  32. package/dist/locales/zh-CN.d.ts +68 -3
  33. package/dist/locales/zh-CN.js +74 -8
  34. package/dist/locales/zh-CN.js.map +1 -1
  35. package/dist/router/viewRegistry.js +6 -6
  36. package/dist/router/viewRegistry.js.map +1 -1
  37. package/dist/style.css +1 -1
  38. package/dist/theme/naive-theme.js +80 -77
  39. package/dist/theme/naive-theme.js.map +1 -1
  40. package/dist/types/api.d.ts +91 -0
  41. package/dist/types/api.js +17 -15
  42. package/dist/types/api.js.map +1 -1
  43. package/dist/utils/shake.d.ts +1 -0
  44. package/dist/utils/shake.js +30 -0
  45. package/dist/utils/shake.js.map +1 -0
  46. package/dist/utils/tree.d.ts +15 -0
  47. package/dist/utils/tree.js +43 -29
  48. package/dist/utils/tree.js.map +1 -1
  49. package/dist/utils/treeCard.d.ts +6 -0
  50. package/dist/utils/treeCard.js +9 -0
  51. package/dist/utils/treeCard.js.map +1 -0
  52. package/dist/views/error/404.vue.js +2 -2
  53. package/dist/views/error/4042.vue.js +81 -24
  54. package/dist/views/error/4042.vue.js.map +1 -1
  55. package/dist/views/login/LoginForm.vue.js +2 -2
  56. package/dist/views/login/LoginForm2.vue.js +135 -135
  57. package/dist/views/login/LoginForm2.vue.js.map +1 -1
  58. package/dist/views/login/components/LoginDesk.vue.js +2 -2
  59. package/dist/views/login/components/LoginDesk2.vue.js +59 -47
  60. package/dist/views/login/components/LoginDesk2.vue.js.map +1 -1
  61. package/dist/views/login/components/LoginHeroPanel.vue.js +2 -2
  62. package/dist/views/login/components/LoginHeroPanel2.vue.js.map +1 -1
  63. package/dist/views/personal/notice2.vue.js +1 -1
  64. package/dist/views/personal/notice2.vue.js.map +1 -1
  65. package/dist/views/personal/sessions.vue.js +2 -2
  66. package/dist/views/personal/sessions2.vue.js +41 -40
  67. package/dist/views/personal/sessions2.vue.js.map +1 -1
  68. package/dist/views/system/ai-usage/index.vue.js +3 -3
  69. package/dist/views/system/ai-usage/index2.vue.js +13 -12
  70. package/dist/views/system/ai-usage/index2.vue.js.map +1 -1
  71. package/dist/views/system/config/components/AdvancedSection.vue.js +3 -3
  72. package/dist/views/system/config/components/AdvancedSection2.vue.js +2 -1
  73. package/dist/views/system/config/components/AdvancedSection2.vue.js.map +1 -1
  74. package/dist/views/system/dict/index.vue.js +2 -2
  75. package/dist/views/system/dict/index2.vue.js +12 -1
  76. package/dist/views/system/dict/index2.vue.js.map +1 -1
  77. package/dist/views/system/file/index2.vue.js +1 -0
  78. package/dist/views/system/file/index2.vue.js.map +1 -1
  79. package/dist/views/system/job/index.vue.js +3 -3
  80. package/dist/views/system/job/index2.vue.js +182 -181
  81. package/dist/views/system/job/index2.vue.js.map +1 -1
  82. package/dist/views/system/job-log/components/AttemptTable2.vue.js +8 -3
  83. package/dist/views/system/job-log/components/AttemptTable2.vue.js.map +1 -1
  84. package/dist/views/system/job-log/index.vue.js +1 -1
  85. package/dist/views/system/job-log/index2.vue.js +5 -5
  86. package/dist/views/system/job-log/index2.vue.js.map +1 -1
  87. package/dist/views/system/job-monitor/index.vue.js +2 -2
  88. package/dist/views/system/job-monitor/index2.vue.js +46 -46
  89. package/dist/views/system/job-monitor/index2.vue.js.map +1 -1
  90. package/dist/views/system/log/exception/index.vue.js +2 -2
  91. package/dist/views/system/log/exception/index2.vue.js +8 -5
  92. package/dist/views/system/log/exception/index2.vue.js.map +1 -1
  93. package/dist/views/system/log/login/index2.vue.js +21 -12
  94. package/dist/views/system/log/login/index2.vue.js.map +1 -1
  95. package/dist/views/system/log/op/index.vue.js +2 -2
  96. package/dist/views/system/log/op/index2.vue.js +50 -40
  97. package/dist/views/system/log/op/index2.vue.js.map +1 -1
  98. package/dist/views/system/menu/components/ButtonManager.vue.js +2 -2
  99. package/dist/views/system/menu/components/ButtonManager2.vue.js +45 -36
  100. package/dist/views/system/menu/components/ButtonManager2.vue.js.map +1 -1
  101. package/dist/views/system/menu/index.vue.js +1 -1
  102. package/dist/views/system/menu/index2.vue.js +162 -151
  103. package/dist/views/system/menu/index2.vue.js.map +1 -1
  104. package/dist/views/system/module/index.vue.js +1 -1
  105. package/dist/views/system/module/index2.vue.js +171 -117
  106. package/dist/views/system/module/index2.vue.js.map +1 -1
  107. package/dist/views/system/notice/index.vue.js +3 -3
  108. package/dist/views/system/notice/index2.vue.js +1 -0
  109. package/dist/views/system/notice/index2.vue.js.map +1 -1
  110. package/dist/views/system/org/index.vue.js +2 -2
  111. package/dist/views/system/org/index2.vue.js +204 -195
  112. package/dist/views/system/org/index2.vue.js.map +1 -1
  113. package/dist/views/system/position/index.vue.js +2 -2
  114. package/dist/views/system/position/index2.vue.js +57 -48
  115. package/dist/views/system/position/index2.vue.js.map +1 -1
  116. package/dist/views/system/recycle/index.vue.js +1 -1
  117. package/dist/views/system/recycle/index2.vue.js +3 -1
  118. package/dist/views/system/recycle/index2.vue.js.map +1 -1
  119. package/dist/views/system/role/components/GrantMenuSheet.vue.d.ts +2 -0
  120. package/dist/views/system/role/components/GrantMenuSheet.vue.js +2 -2
  121. package/dist/views/system/role/components/GrantMenuSheet2.vue.js +54 -49
  122. package/dist/views/system/role/components/GrantMenuSheet2.vue.js.map +1 -1
  123. package/dist/views/system/role/components/GrantMenuTable.vue.js +1 -1
  124. package/dist/views/system/role/components/GrantMenuTable2.vue.js +159 -195
  125. package/dist/views/system/role/components/GrantMenuTable2.vue.js.map +1 -1
  126. package/dist/views/system/role/components/grantMenuGroups.d.ts +54 -0
  127. package/dist/views/system/role/components/grantMenuGroups.js +116 -76
  128. package/dist/views/system/role/components/grantMenuGroups.js.map +1 -1
  129. package/dist/views/system/role/index.vue.js +2 -2
  130. package/dist/views/system/role/index2.vue.js +152 -145
  131. package/dist/views/system/role/index2.vue.js.map +1 -1
  132. package/dist/views/system/session/index2.vue.js +39 -35
  133. package/dist/views/system/session/index2.vue.js.map +1 -1
  134. package/dist/views/system/user/components/UserGrantEffectiveTable.vue.d.ts +10 -0
  135. package/dist/views/system/user/components/UserGrantEffectiveTable.vue.js +5 -0
  136. package/dist/views/system/user/components/UserGrantEffectiveTable.vue.js.map +1 -0
  137. package/dist/views/system/user/components/UserGrantEffectiveTable2.vue.js +96 -0
  138. package/dist/views/system/user/components/UserGrantEffectiveTable2.vue.js.map +1 -0
  139. package/dist/views/system/user/components/UserGrantMenuSheet.vue.d.ts +13 -0
  140. package/dist/views/system/user/components/UserGrantMenuSheet.vue.js +8 -0
  141. package/dist/views/system/user/components/UserGrantMenuSheet.vue.js.map +1 -0
  142. package/dist/views/system/user/components/UserGrantMenuSheet2.vue.js +216 -0
  143. package/dist/views/system/user/components/UserGrantMenuSheet2.vue.js.map +1 -0
  144. package/dist/views/system/user/components/UserGrantMenuTable.vue.d.ts +13 -0
  145. package/dist/views/system/user/components/UserGrantMenuTable.vue.js +8 -0
  146. package/dist/views/system/user/components/UserGrantMenuTable.vue.js.map +1 -0
  147. package/dist/views/system/user/components/UserGrantMenuTable2.vue.js +186 -0
  148. package/dist/views/system/user/components/UserGrantMenuTable2.vue.js.map +1 -0
  149. package/dist/views/system/user/components/UserGrantNodeRow.vue.d.ts +31 -0
  150. package/dist/views/system/user/components/UserGrantNodeRow.vue.js +8 -0
  151. package/dist/views/system/user/components/UserGrantNodeRow.vue.js.map +1 -0
  152. package/dist/views/system/user/components/UserGrantNodeRow2.vue.js +171 -0
  153. package/dist/views/system/user/components/UserGrantNodeRow2.vue.js.map +1 -0
  154. package/dist/views/system/user/components/UserGrantOverviewDrawer.vue.d.ts +21 -0
  155. package/dist/views/system/user/components/UserGrantOverviewDrawer.vue.js +5 -0
  156. package/dist/views/system/user/components/UserGrantOverviewDrawer.vue.js.map +1 -0
  157. package/dist/views/system/user/components/UserGrantOverviewDrawer2.vue.js +178 -0
  158. package/dist/views/system/user/components/UserGrantOverviewDrawer2.vue.js.map +1 -0
  159. package/dist/views/system/user/components/userGrantState.d.ts +64 -0
  160. package/dist/views/system/user/components/userGrantState.js +117 -0
  161. package/dist/views/system/user/components/userGrantState.js.map +1 -0
  162. package/dist/views/system/user/index.vue.js +2 -2
  163. package/dist/views/system/user/index2.vue.js +369 -295
  164. package/dist/views/system/user/index2.vue.js.map +1 -1
  165. package/package.json +3 -3
@@ -1,4 +1,4 @@
1
- import { defineComponent as _, ref as b, h as c, resolveDirective as v, openBlock as m, createBlock as u, unref as t, withCtx as a, withDirectives as k, createTextVNode as w, toDisplayString as C, createVNode as p } from "vue";
1
+ import { defineComponent as _, ref as b, h as c, resolveDirective as v, openBlock as u, createBlock as p, unref as t, withCtx as a, withDirectives as w, createTextVNode as k, toDisplayString as C, createVNode as m } from "vue";
2
2
  import { useMessage as E, NButton as x } from "naive-ui";
3
3
  import { useI18n as z } from "vue-i18n";
4
4
  import { SmartTable as A } from "smart-naive-table";
@@ -14,11 +14,17 @@ import { uaSummary as F } from "../../../../utils/ua.js";
14
14
  const Z = /* @__PURE__ */ _({
15
15
  __name: "index",
16
16
  setup(M) {
17
- const { t: e } = z(), f = E(), { confirm: d } = S(), n = b(), h = N({ ranges: ["createTime"] }), s = [
17
+ const { t: e } = z(), f = E(), { confirm: d } = S(), s = b(), h = N({ ranges: ["createTime"] }), n = [
18
18
  { type: "index", title: () => e("common.rowNo"), width: 64, align: "center" },
19
- { key: "account", title: () => e("log.account"), search: { actions: l.fuzzy } },
19
+ {
20
+ key: "account",
21
+ ellipsis: { tooltip: !0 },
22
+ title: () => e("log.account"),
23
+ search: { actions: l.fuzzy }
24
+ },
20
25
  {
21
26
  key: "success",
27
+ width: 90,
22
28
  title: () => e("log.result"),
23
29
  tag: !0,
24
30
  search: { actions: l.exact },
@@ -54,6 +60,8 @@ const Z = /* @__PURE__ */ _({
54
60
  // IP 与时间用等宽 / 弱化色(.mono .muted .num 是全局工具类)
55
61
  {
56
62
  key: "ip",
63
+ width: 140,
64
+ ellipsis: { tooltip: !0 },
57
65
  title: () => e("log.ip"),
58
66
  render: (r) => c("span", { class: "mono muted" }, r.ip || "—")
59
67
  },
@@ -67,12 +75,13 @@ const Z = /* @__PURE__ */ _({
67
75
  // 时间范围:"上周谁登录失败了"是登录日志最主要的用法
68
76
  {
69
77
  key: "createTime",
78
+ width: 170,
70
79
  title: () => e("common.createTime"),
71
80
  render: (r) => c("span", { class: "num muted", style: "white-space: nowrap" }, D(r.createTime)),
72
81
  search: { type: "daterange", actions: l.dayRange }
73
82
  }
74
83
  ];
75
- R(s);
84
+ R(n);
76
85
  function y() {
77
86
  d({
78
87
  type: "error",
@@ -81,15 +90,15 @@ const Z = /* @__PURE__ */ _({
81
90
  successMsg: e("log.cleared")
82
91
  }).then((r) => {
83
92
  var o;
84
- r && ((o = n.value) == null || o.refresh());
93
+ r && ((o = s.value) == null || o.refresh());
85
94
  });
86
95
  }
87
96
  return (r, o) => {
88
97
  const T = v("auth");
89
- return m(), u(t(A), {
98
+ return u(), p(t(A), {
90
99
  ref_key: "tableRef",
91
- ref: n,
92
- columns: s,
100
+ ref: s,
101
+ columns: n,
93
102
  fetcher: t(g).loginPage,
94
103
  search: { container: "table" },
95
104
  "filter-serializer": t(h),
@@ -101,22 +110,22 @@ const Z = /* @__PURE__ */ _({
101
110
  onError: o[0] || (o[0] = (i) => t(f).error(t(B)(i)))
102
111
  }, {
103
112
  "pagination-prefix": a(({ itemCount: i }) => [
104
- p(O, { count: i }, null, 8, ["count"])
113
+ m(O, { count: i }, null, 8, ["count"])
105
114
  ]),
106
115
  "toolbar-right": a(() => [
107
- k((m(), u(t(x), {
116
+ w((u(), p(t(x), {
108
117
  type: "error",
109
118
  secondary: "",
110
119
  onClick: y
111
120
  }, {
112
121
  icon: a(() => [
113
- p(L, {
122
+ m(L, {
114
123
  icon: "ph:trash",
115
124
  size: 16
116
125
  })
117
126
  ]),
118
127
  default: a(() => [
119
- w(" " + C(t(e)("log.clear")), 1)
128
+ k(" " + C(t(e)("log.clear")), 1)
120
129
  ]),
121
130
  _: 1
122
131
  })), [
@@ -1 +1 @@
1
- {"version":3,"file":"index2.vue.js","sources":["../../../../../src/views/system/log/login/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 登录日志 = 只读 SmartTable:列驱动搜索(账号/结果)+ 分页;success 列显式红/绿 typeMap 保证「失败=红」。\n// 工具栏一枚「清空」(硬删,不可恢复)走 useConfirm 二次确认(对齐 simpleadmin 日志页)。\nimport { h, ref } from 'vue'\nimport { NButton, useMessage } 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 { useConfirm } from '#/composables/useConfirm'\nimport { logApi } from '#/api'\nimport { translateError } from '#/utils/error'\nimport { fmtDateTime } from '#/utils/format'\nimport {\n SEARCH_ACTIONS,\n createFlatFilterSerializer,\n deriveHeaderFilters,\n} from '#/utils/tableFilter'\nimport { TABLE_MIN_ROW_HEIGHT, TABLE_TOOLBAR } from '#/utils/tableToolbar'\nimport TableTotal from '#/components/TableTotal/index.vue'\nimport { uaSummary } from '#/utils/ua'\nimport type { SysLoginLog } from '#/types/api'\n\nconst { t } = useI18n()\nconst message = useMessage()\nconst { confirm } = useConfirm()\nconst tableRef = ref<SmartTableInst<SysLoginLog>>()\n\n// 日期区间:条件构造器里是同一字段的两行(大于等于 + 小于等于),序列化器合并成 [起, 止],\n// api 层 splitRange 再拆成 StartTime/EndTime 并给结束日补 23:59:59。\nconst filterSerializer = createFlatFilterSerializer({ ranges: ['createTime'] })\n\nconst columns: SmartTableColumn<SysLoginLog>[] = [\n { type: 'index', title: () => t('common.rowNo'), width: 64, align: 'center' },\n { key: 'account', title: () => t('log.account'), search: { actions: SEARCH_ACTIONS.fuzzy } },\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 // 失败原因:裸渲染的 40004 对排查毫无用处——密码错/被锁/被停用三种情况的处置动作完全不同(改密/解锁/启用)。\n // 复用同列的 tag+options 机制翻成人话,文案直接指向已有的 error.auth.* 键(与登录页弹的提示同源)。\n // AuthService 实际只会落 0 与 40001–40005 这几个码;未命中的码由 SmartTable 回落成原始数字。\n {\n key: 'resultCode',\n title: () => t('log.resultCode'),\n width: 175,\n tag: true,\n options: [\n { label: () => t('log.success'), value: 0, tagType: 'success' },\n { label: () => t('error.auth.passwordWrong'), value: 40001, tagType: 'error' },\n { label: () => t('error.auth.captchaExpired'), value: 40002, tagType: 'error' },\n { label: () => t('error.auth.captchaWrong'), value: 40003, tagType: 'error' },\n { label: () => t('error.auth.accountLocked'), value: 40004, tagType: 'error' },\n { label: () => t('error.auth.accountDisabled'), value: 40005, tagType: 'error' },\n ],\n },\n // 姓名:后端按 userId 回填;登录失败/账号不存在的行无姓名 → 回落账号\n {\n key: 'name',\n title: () => t('log.name'),\n ellipsis: { tooltip: true },\n render: r => r.name || r.account || '—',\n },\n // IP 与时间用等宽 / 弱化色(.mono .muted .num 是全局工具类)\n {\n key: 'ip',\n title: () => t('log.ip'),\n render: r => h('span', { class: 'mono muted' }, r.ip || '—'),\n },\n // 设备:UA 解析成「浏览器 · 系统」(全未识别回落原始串);过长截断 + tooltip\n {\n key: 'device',\n title: () => t('log.device'),\n ellipsis: { tooltip: true },\n render: r => uaSummary(r.userAgent),\n },\n // 时间范围:\"上周谁登录失败了\"是登录日志最主要的用法\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]\nderiveHeaderFilters(columns)\n\nfunction clearLogs() {\n confirm({\n type: 'error',\n content: t('log.clearLoginConfirm'),\n action: () => logApi.loginClear(),\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.loginPage\"\n :search=\"{ container: 'table' }\"\n :filter-serializer=\"filterSerializer\"\n :toolbar=\"TABLE_TOOLBAR\"\n fill-height\n :min-row-height=\"TABLE_MIN_ROW_HEIGHT\"\n card-on-narrow\n storage-key=\"sys-log-login\"\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/login'\" 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</template>\n"],"names":["t","useI18n","message","useMessage","confirm","useConfirm","tableRef","ref","filterSerializer","createFlatFilterSerializer","columns","SEARCH_ACTIONS","h","uaSummary","fmtDateTime","deriveHeaderFilters","clearLogs","logApi","ok","_a","_createBlock","_unref","SmartTable","TABLE_TOOLBAR","TABLE_MIN_ROW_HEIGHT","_cache","e","translateError","_withCtx","itemCount","_createVNode","TableTotal","NButton","AppIcon","_createTextVNode"],"mappings":"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"}
1
+ {"version":3,"file":"index2.vue.js","sources":["../../../../../src/views/system/log/login/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 登录日志 = 只读 SmartTable:列驱动搜索(账号/结果)+ 分页;success 列显式红/绿 typeMap 保证「失败=红」。\n// 工具栏一枚「清空」(硬删,不可恢复)走 useConfirm 二次确认(对齐 simpleadmin 日志页)。\nimport { h, ref } from 'vue'\nimport { NButton, useMessage } 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 { useConfirm } from '#/composables/useConfirm'\nimport { logApi } from '#/api'\nimport { translateError } from '#/utils/error'\nimport { fmtDateTime } from '#/utils/format'\nimport {\n SEARCH_ACTIONS,\n createFlatFilterSerializer,\n deriveHeaderFilters,\n} from '#/utils/tableFilter'\nimport { TABLE_MIN_ROW_HEIGHT, TABLE_TOOLBAR } from '#/utils/tableToolbar'\nimport TableTotal from '#/components/TableTotal/index.vue'\nimport { uaSummary } from '#/utils/ua'\nimport type { SysLoginLog } from '#/types/api'\n\nconst { t } = useI18n()\nconst message = useMessage()\nconst { confirm } = useConfirm()\nconst tableRef = ref<SmartTableInst<SysLoginLog>>()\n\n// 日期区间:条件构造器里是同一字段的两行(大于等于 + 小于等于),序列化器合并成 [起, 止],\n// api 层 splitRange 再拆成 StartTime/EndTime 并给结束日补 23:59:59。\nconst filterSerializer = createFlatFilterSerializer({ ranges: ['createTime'] })\n\nconst columns: SmartTableColumn<SysLoginLog>[] = [\n { type: 'index', title: () => t('common.rowNo'), width: 64, align: 'center' },\n {\n key: 'account',\n ellipsis: { tooltip: true },\n title: () => t('log.account'),\n search: { actions: SEARCH_ACTIONS.fuzzy },\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 // 失败原因:裸渲染的 40004 对排查毫无用处——密码错/被锁/被停用三种情况的处置动作完全不同(改密/解锁/启用)。\n // 复用同列的 tag+options 机制翻成人话,文案直接指向已有的 error.auth.* 键(与登录页弹的提示同源)。\n // AuthService 实际只会落 0 与 40001–40005 这几个码;未命中的码由 SmartTable 回落成原始数字。\n {\n key: 'resultCode',\n title: () => t('log.resultCode'),\n width: 175,\n tag: true,\n options: [\n { label: () => t('log.success'), value: 0, tagType: 'success' },\n { label: () => t('error.auth.passwordWrong'), value: 40001, tagType: 'error' },\n { label: () => t('error.auth.captchaExpired'), value: 40002, tagType: 'error' },\n { label: () => t('error.auth.captchaWrong'), value: 40003, tagType: 'error' },\n { label: () => t('error.auth.accountLocked'), value: 40004, tagType: 'error' },\n { label: () => t('error.auth.accountDisabled'), value: 40005, tagType: 'error' },\n ],\n },\n // 姓名:后端按 userId 回填;登录失败/账号不存在的行无姓名 → 回落账号\n {\n key: 'name',\n title: () => t('log.name'),\n ellipsis: { tooltip: true },\n render: r => r.name || r.account || '—',\n },\n // IP 与时间用等宽 / 弱化色(.mono .muted .num 是全局工具类)\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 // 设备:UA 解析成「浏览器 · 系统」(全未识别回落原始串);过长截断 + tooltip\n {\n key: 'device',\n title: () => t('log.device'),\n ellipsis: { tooltip: true },\n render: r => uaSummary(r.userAgent),\n },\n // 时间范围:\"上周谁登录失败了\"是登录日志最主要的用法\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]\nderiveHeaderFilters(columns)\n\nfunction clearLogs() {\n confirm({\n type: 'error',\n content: t('log.clearLoginConfirm'),\n action: () => logApi.loginClear(),\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.loginPage\"\n :search=\"{ container: 'table' }\"\n :filter-serializer=\"filterSerializer\"\n :toolbar=\"TABLE_TOOLBAR\"\n fill-height\n :min-row-height=\"TABLE_MIN_ROW_HEIGHT\"\n card-on-narrow\n storage-key=\"sys-log-login\"\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/login'\" 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</template>\n"],"names":["t","useI18n","message","useMessage","confirm","useConfirm","tableRef","ref","filterSerializer","createFlatFilterSerializer","columns","SEARCH_ACTIONS","h","uaSummary","fmtDateTime","deriveHeaderFilters","clearLogs","logApi","ok","_a","_createBlock","_unref","SmartTable","TABLE_TOOLBAR","TABLE_MIN_ROW_HEIGHT","_cache","e","translateError","_withCtx","itemCount","_createVNode","TableTotal","NButton","AppIcon","_createTextVNode"],"mappings":"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"}
@@ -1,8 +1,8 @@
1
1
  import o from "./index2.vue.js";
2
2
  /* empty css */
3
3
  import t from "../../../../_virtual/_plugin-vue_export-helper.js";
4
- const _ = /* @__PURE__ */ t(o, [["__scopeId", "data-v-8bb5b6c8"]]);
4
+ const p = /* @__PURE__ */ t(o, [["__scopeId", "data-v-008b50a0"]]);
5
5
  export {
6
- _ as default
6
+ p as default
7
7
  };
8
8
  //# sourceMappingURL=index.vue.js.map
@@ -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