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 +1 @@
1
- {"version":3,"file":"index2.vue.js","sources":["../../../../src/views/system/job-log/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 执行记录 = 只读 SmartTable + 详情抽屉 + 终止/清空两个动作。\n// 「运行中」没有独立状态字段,判据是 endTime 为空(任务无 Running 态,全靠未闭合记录推导);\n// 终止是跨节点写旗标,目标节点最迟 KillPollSeconds 后停——所以文案说\"已请求终止\"而非\"已终止\"。\n// 详情抽屉里带同 fireInstanceId 的各次尝试列表:走后端的 fireInstanceId 查询参数直取,\n// 不按 jobId 拉一页再前端过滤——翻到老触发时那一页里根本没有它的兄弟行,列表会静默缺项。\nimport { computed, h, ref, watch } from 'vue'\nimport { useShellBreakpoint } from '#/composables/useShellBreakpoint'\nimport {\n NButton,\n NTag,\n NSelect,\n NSpace,\n NDrawer,\n NDrawerContent,\n NDescriptions,\n NDescriptionsItem,\n NForm,\n NFormItem,\n useMessage,\n} from 'naive-ui'\nimport { useRoute } from 'vue-router'\nimport { useI18n } from 'vue-i18n'\nimport { SmartTable, type SmartTableColumn, type SmartTableInst } from 'smart-naive-table'\nimport AppIcon from '#/components/AppIcon.vue'\nimport FormContainer from '#/components/FormContainer/index.vue'\nimport { useConfirm } from '#/composables/useConfirm'\nimport { useAuthStore } from '#/stores/auth'\nimport { jobApi } from '#/api'\nimport { translateError } from '#/utils/error'\nimport {\n SEARCH_ACTIONS,\n createFlatFilterSerializer,\n presetEqualFilter,\n deriveHeaderFilters,\n} from '#/utils/tableFilter'\nimport { TABLE_MIN_ROW_HEIGHT, TABLE_TOOLBAR } from '#/utils/tableToolbar'\nimport TableTotal from '#/components/TableTotal/index.vue'\nimport AttemptTable from './components/AttemptTable.vue'\nimport { isAlive, runStatusLabel, runStatusTagType } from './runStatus'\nimport { fmtDateTime } from '#/utils/format'\nimport { JobFireMode, JobRunStatus, type SysJobLog } from '#/types/api'\n\nconst { t } = useI18n()\nconst message = useMessage()\nconst { confirm } = useConfirm()\nconst authStore = useAuthStore()\nconst tableRef = ref<SmartTableInst<SysJobLog>>()\n// 壳层窄档(内容区 < 600,与表格卡片列表同阈值):详情抽屉改底部抽屉,尝试子表改卡片列表\nconst { bp } = useShellBreakpoint()\nconst narrow = computed(() => bp.value === 'narrow')\n\n// 任务下拉(筛选用):拉一页足量。ponytail: 200 覆盖绝大多数系统,真超再上远程搜索\nconst jobOptions = ref<{ label: string; value: number }[]>([])\nasync function loadJobOptions() {\n try {\n const { items } = await jobApi.page({ page: 1, pageSize: 200 })\n jobOptions.value = items.map(j => ({ label: j.name, value: j.id }))\n } catch {\n // 静默:任务下拉是筛选辅助,拉取失败不打断列表\n }\n}\nvoid loadJobOptions()\n\nconst fireModeOptions = [\n {\n label: () => t('job.log.fireModeSchedule'),\n value: JobFireMode.Schedule,\n tagType: 'default' as const,\n },\n { label: () => t('job.log.fireModeManual'), value: JobFireMode.Manual, tagType: 'info' as const },\n {\n label: () => t('job.log.fireModeBackfill'),\n value: JobFireMode.Misfire,\n tagType: 'warning' as const,\n },\n {\n label: () => t('job.log.fireModeMisfireSkip'),\n value: JobFireMode.MissedSkipped,\n tagType: 'default' as const,\n },\n]\nconst runStatusOptions = [\n { label: () => t('job.log.running'), value: JobRunStatus.Running, tagType: 'info' as const },\n { label: () => t('job.log.success'), value: JobRunStatus.Success, tagType: 'success' as const },\n { label: () => t('job.log.failed'), value: JobRunStatus.Failed, tagType: 'error' as const },\n { label: () => t('job.log.timeout'), value: JobRunStatus.Timeout, tagType: 'warning' as const },\n {\n label: () => t('job.log.cancelled'),\n value: JobRunStatus.Cancelled,\n tagType: 'default' as const,\n },\n { label: () => t('job.log.skipped'), value: JobRunStatus.Skipped, tagType: 'default' as const },\n]\n\n// 条件构造器下 search.key 被忽略,过滤键就是列 key;后端参数叫 startRange(api 层 logPage 再拆成 StartFrom/StartTo 并补秒),\n// 所以 startTime 要改名,并按日期区间字段处理(同字段的 gte + lte 合并成 [起, 止])。\nconst filterSerializer = createFlatFilterSerializer({\n ranges: ['startTime'],\n rename: { startTime: 'startRange' },\n})\n\nconst columns: SmartTableColumn<SysJobLog>[] = [\n { type: 'index', title: () => t('common.rowNo'), width: 64, align: 'center' },\n {\n key: 'jobId',\n title: () => t('job.log.job'),\n hideInTable: true, // 只作搜索项:表格里已有任务名快照列\n options: jobOptions,\n search: { actions: SEARCH_ACTIONS.exact, props: { clearable: true, filterable: true } },\n },\n {\n key: 'jobName',\n title: () => t('job.log.job'),\n minWidth: 140,\n ellipsis: { tooltip: true },\n card: 'title',\n },\n {\n key: 'fireMode',\n title: () => t('job.log.fireMode'),\n width: 100,\n tag: true,\n options: fireModeOptions,\n },\n { key: 'scheduledTime', title: () => t('job.log.scheduledTime'), width: 160, format: 'datetime' },\n {\n key: 'startTime',\n title: () => t('job.log.startTime'),\n width: 160,\n format: 'datetime',\n // 时间范围筛选:条件构造器里是同一字段的两行(大于等于 + 小于等于),序列化器合并成 [起, 止],\n // api 层再拆成 StartFrom/StartTo 并补秒\n search: { type: 'daterange', actions: SEARCH_ACTIONS.dayRange },\n },\n {\n key: 'elapsedMs',\n title: () => t('job.log.elapsed'),\n width: 110,\n render: r =>\n isAlive(r)\n ? h(NTag, { size: 'small', type: 'info', bordered: false }, () => t('job.log.running'))\n : h('span', { class: 'tabular' }, `${r.elapsedMs} ms`),\n },\n {\n key: 'runStatus',\n title: () => t('job.log.runStatus'),\n width: 100,\n tag: true,\n search: { actions: SEARCH_ACTIONS.exact },\n options: runStatusOptions,\n },\n {\n key: 'retryIndex',\n title: () => t('job.log.retryIndex'),\n width: 90,\n align: 'center',\n render: r => (r.retryIndex > 0 ? r.retryIndex : '—'),\n },\n { key: 'nodeName', title: () => t('job.log.node'), width: 140, ellipsis: { tooltip: true } },\n {\n key: 'op',\n title: () => t('common.operation'),\n width: 130,\n fixed: 'right',\n hideInSetting: true,\n render: r =>\n h(NSpace, { size: 4, wrapItem: false }, () => [\n h(\n NButton,\n { size: 'small', quaternary: true, type: 'primary', onClick: () => openDetail(r) },\n () => t('common.detail'),\n ),\n isAlive(r) && authStore.hasPerm('POST:/api/v1/sys/job/log/{id}/kill')\n ? h(\n NButton,\n { size: 'small', quaternary: true, type: 'error', onClick: () => killRun(r) },\n () => t('job.log.kill'),\n )\n : null,\n ]),\n },\n]\nderiveHeaderFilters(columns)\n\n// 从任务页「记录」跳来时带 ?jobId=,自动带上筛选。\n// watch 而非 onMounted:页面被 keep-alive,标签开着时再跳一次只换 query,onMounted 不会再触发;\n// tableRef 一起纳入监听源,冷启动时实例就绪后补上筛选(immediate 在 setup 期 ref 还是空)。\nconst route = useRoute()\nwatch(\n [tableRef, () => route.query.jobId],\n ([inst, jobId]) => {\n if (!inst) return\n // route 是全局的:切到别的页面时 query.jobId 变 undefined,本页被 keep-alive 着的 watcher 照样会响。\n // 不守卫就等于「离开本页 = 清掉筛选并后台发一次没人看的请求」,切回来筛选还没了。\n if (route.path !== '/system/job-log') return\n // 值没变 presetEqualFilter 不写;远程模式下 setFilter 自己会回第 1 页重查\n presetEqualFilter(inst, 'jobId', jobId == null ? undefined : Number(jobId))\n },\n { immediate: true },\n)\n\n// ── 详情抽屉(行数据直填 + 同 fireInstanceId 的各次尝试) ──\nconst showDetail = ref(false)\nconst detailRow = ref<SysJobLog | null>(null)\nconst attempts = ref<SysJobLog[]>([])\nconst attemptsLoading = ref(false)\n\nconst runStatusText = (s: JobRunStatus) => runStatusLabel(t, s)\n\nasync function openDetail(r: SysJobLog) {\n detailRow.value = r\n showDetail.value = true\n attempts.value = []\n attemptsLoading.value = true\n try {\n const { items } = await jobApi.logPage({\n page: 1,\n pageSize: 100,\n fireInstanceId: r.fireInstanceId,\n })\n attempts.value = items.toSorted((a, b) => a.retryIndex - b.retryIndex)\n } catch {\n // 静默:尝试列表是详情的补充信息,拉不到不挡主体\n } finally {\n attemptsLoading.value = false\n }\n}\n\nfunction killRun(r: SysJobLog) {\n confirm({\n type: 'error',\n content: t('job.log.killConfirm', { name: r.jobName }),\n action: () => jobApi.kill(r.id),\n successMsg: t('job.log.killed'),\n }).then(ok => {\n if (ok) tableRef.value?.refresh()\n })\n}\n\n// ── 清空(弹窗选 beforeDays;0 = 全部) ──\nconst clearShow = ref(false)\nconst clearBeforeDays = ref(0)\n// computed:切语言时选项文案即时生效\nconst clearOptions = computed(() => [\n { label: t('job.log.clearAll'), value: 0 },\n ...[7, 30, 90].map(n => ({ label: t('job.log.beforeDays', { n }), value: n })),\n])\n\nasync function doClear() {\n try {\n const n = await jobApi.logClear({\n beforeDays: clearBeforeDays.value === 0 ? null : clearBeforeDays.value,\n })\n message.success(t('job.log.cleared', { n }))\n await tableRef.value?.refresh()\n } catch (e) {\n message.error(translateError(e))\n return false\n }\n}\n</script>\n\n<template>\n <SmartTable\n :toolbar=\"TABLE_TOOLBAR\"\n ref=\"tableRef\"\n :columns=\"columns\"\n :fetcher=\"jobApi.logPage\"\n :search=\"{ container: 'table' }\"\n :filter-serializer=\"filterSerializer\"\n fill-height\n :min-row-height=\"TABLE_MIN_ROW_HEIGHT\"\n card-on-narrow\n storage-key=\"sys-job-log\"\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\n v-auth=\"'POST:/api/v1/sys/job/log/clear'\"\n type=\"error\"\n secondary\n @click=\"clearShow = true\"\n >\n <template #icon><AppIcon icon=\"ph:trash\" :size=\"16\" /></template>\n {{ t('job.log.clear') }}\n </n-button>\n </template>\n </SmartTable>\n\n <!-- 清空:选范围后执行,回报删除行数 -->\n <FormContainer\n v-model:show=\"clearShow\"\n :title=\"t('job.log.clearTitle')\"\n :width=\"420\"\n :on-confirm=\"doClear\"\n :confirm-text=\"t('common.confirm')\"\n >\n <n-form label-placement=\"left\" :label-width=\"60\" require-mark-placement=\"left\">\n <n-form-item :label=\"t('job.log.clearRange')\" required>\n <n-select v-model:value=\"clearBeforeDays\" :options=\"clearOptions\" />\n </n-form-item>\n <div class=\"clear-hint\">{{ t('job.log.clearHint') }}</div>\n </n-form>\n </FormContainer>\n\n <!-- 详情抽屉:右侧 600 宽;窄档改底部抽屉(上圆角,最高 85vh) -->\n <n-drawer\n v-model:show=\"showDetail\"\n :placement=\"narrow ? 'bottom' : 'right'\"\n :width=\"narrow ? undefined : 'min(600px, 100vw)'\"\n :height=\"narrow ? 'auto' : undefined\"\n :class=\"{ 'st-sheet': narrow }\"\n :style=\"narrow ? 'max-height: 85vh' : undefined\"\n >\n <n-drawer-content :title=\"t('common.detail')\" closable :native-scrollbar=\"narrow\">\n <template v-if=\"detailRow\">\n <n-descriptions\n label-placement=\"left\"\n :column=\"1\"\n bordered\n size=\"small\"\n label-style=\"width: 100px\"\n >\n <n-descriptions-item :label=\"t('job.log.job')\">\n {{ detailRow.jobName }}\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('job.log.fireMode')\">\n {{\n detailRow.fireMode === JobFireMode.Manual\n ? t('job.log.fireModeManual')\n : detailRow.fireMode === JobFireMode.Misfire\n ? t('job.log.fireModeBackfill')\n : detailRow.fireMode === JobFireMode.MissedSkipped\n ? t('job.log.fireModeMisfireSkip')\n : t('job.log.fireModeSchedule')\n }}\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('job.log.runStatus')\">\n <n-tag size=\"small\" :bordered=\"false\" :type=\"runStatusTagType[detailRow.runStatus]\">\n {{ runStatusText(detailRow.runStatus) }}\n </n-tag>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('job.log.scheduledTime')\">\n {{ fmtDateTime(detailRow.scheduledTime) }}\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('job.log.startTime')\">\n {{ fmtDateTime(detailRow.startTime) }}\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('job.log.elapsed')\">\n {{ detailRow.endTime == null ? t('job.log.running') : `${detailRow.elapsedMs} ms` }}\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('job.log.node')\">\n {{ detailRow.nodeName || '—' }}\n </n-descriptions-item>\n <n-descriptions-item v-if=\"detailRow.messageText\" :label=\"t('job.log.message')\">\n <pre class=\"log-output\">{{ detailRow.messageText }}</pre>\n </n-descriptions-item>\n <n-descriptions-item v-if=\"detailRow.errorText\" :label=\"t('job.log.error')\">\n <pre class=\"log-output log-error\">{{ detailRow.errorText }}</pre>\n </n-descriptions-item>\n </n-descriptions>\n\n <div class=\"attempts-title\">{{ t('job.log.attempts') }}</div>\n <AttemptTable :rows=\"attempts\" :loading=\"attemptsLoading\" />\n </template>\n </n-drawer-content>\n </n-drawer>\n</template>\n\n<style scoped>\n.clear-hint {\n font-size: 13px;\n line-height: 1.6;\n color: var(--text-3);\n}\n/* 小标题:同描述列表拉开距离 */\n.attempts-title {\n margin: 16px 0 6px 2px;\n font-size: 13px;\n font-weight: 500;\n letter-spacing: -0.01em;\n color: var(--text-3);\n}\n.log-output {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-all;\n font-family: var(--font-mono, ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace);\n font-size: 12px;\n line-height: 1.55;\n}\n.log-error {\n color: var(--err);\n}\n\n/* 窄档:底部抽屉 */\n.st-sheet {\n display: flex;\n flex-direction: column;\n border-radius: var(--radius-xl) var(--radius-xl) 0 0;\n}\n.st-sheet :deep(.n-drawer-content-wrapper) {\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n</style>\n"],"names":["t","useI18n","message","useMessage","confirm","useConfirm","authStore","useAuthStore","tableRef","ref","bp","useShellBreakpoint","narrow","computed","jobOptions","loadJobOptions","items","jobApi","j","fireModeOptions","JobFireMode","runStatusOptions","JobRunStatus","filterSerializer","createFlatFilterSerializer","columns","SEARCH_ACTIONS","r","isAlive","h","NTag","NSpace","NButton","openDetail","killRun","deriveHeaderFilters","route","useRoute","watch","inst","jobId","presetEqualFilter","showDetail","detailRow","attempts","attemptsLoading","runStatusText","s","runStatusLabel","a","b","ok","_a","clearShow","clearBeforeDays","clearOptions","n","doClear","e","translateError","_createVNode","_unref","SmartTable","TABLE_TOOLBAR","TABLE_MIN_ROW_HEIGHT","_cache","_withCtx","itemCount","TableTotal","_createBlock","AppIcon","_createTextVNode","FormContainer","$event","NForm","NFormItem","NSelect","_createElementVNode","_hoisted_1","_toDisplayString","NDrawer","_normalizeStyle","NDrawerContent","_createElementBlock","_Fragment","NDescriptions","NDescriptionsItem","runStatusTagType","fmtDateTime","_hoisted_2","_hoisted_3","_hoisted_4","AttemptTable"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA2CA,UAAM,EAAE,GAAAA,EAAA,IAAMC,GAAA,GACRC,IAAUC,GAAA,GACV,EAAE,SAAAC,EAAA,IAAYC,GAAA,GACdC,IAAYC,GAAA,GACZC,IAAWC,EAAA,GAEX,EAAE,IAAAC,EAAA,IAAOC,GAAA,GACTC,IAASC,EAAS,MAAMH,EAAG,UAAU,QAAQ,GAG7CI,IAAaL,EAAwC,EAAE;AAC7D,mBAAeM,IAAiB;AAC9B,UAAI;AACF,cAAM,EAAE,OAAAC,MAAU,MAAMC,EAAO,KAAK,EAAE,MAAM,GAAG,UAAU,KAAK;AAC9D,QAAAH,EAAW,QAAQE,EAAM,IAAI,CAAAE,OAAM,EAAE,OAAOA,EAAE,MAAM,OAAOA,EAAE,GAAA,EAAK;AAAA,MACpE,QAAQ;AAAA,MAER;AAAA,IACF;AACA,IAAKH,EAAA;AAEL,UAAMI,IAAkB;AAAA,MACtB;AAAA,QACE,OAAO,MAAMnB,EAAE,0BAA0B;AAAA,QACzC,OAAOoB,EAAY;AAAA,QACnB,SAAS;AAAA,MAAA;AAAA,MAEX,EAAE,OAAO,MAAMpB,EAAE,wBAAwB,GAAG,OAAOoB,EAAY,QAAQ,SAAS,OAAA;AAAA,MAChF;AAAA,QACE,OAAO,MAAMpB,EAAE,0BAA0B;AAAA,QACzC,OAAOoB,EAAY;AAAA,QACnB,SAAS;AAAA,MAAA;AAAA,MAEX;AAAA,QACE,OAAO,MAAMpB,EAAE,6BAA6B;AAAA,QAC5C,OAAOoB,EAAY;AAAA,QACnB,SAAS;AAAA,MAAA;AAAA,IACX,GAEIC,IAAmB;AAAA,MACvB,EAAE,OAAO,MAAMrB,EAAE,iBAAiB,GAAG,OAAOsB,EAAa,SAAS,SAAS,OAAA;AAAA,MAC3E,EAAE,OAAO,MAAMtB,EAAE,iBAAiB,GAAG,OAAOsB,EAAa,SAAS,SAAS,UAAA;AAAA,MAC3E,EAAE,OAAO,MAAMtB,EAAE,gBAAgB,GAAG,OAAOsB,EAAa,QAAQ,SAAS,QAAA;AAAA,MACzE,EAAE,OAAO,MAAMtB,EAAE,iBAAiB,GAAG,OAAOsB,EAAa,SAAS,SAAS,UAAA;AAAA,MAC3E;AAAA,QACE,OAAO,MAAMtB,EAAE,mBAAmB;AAAA,QAClC,OAAOsB,EAAa;AAAA,QACpB,SAAS;AAAA,MAAA;AAAA,MAEX,EAAE,OAAO,MAAMtB,EAAE,iBAAiB,GAAG,OAAOsB,EAAa,SAAS,SAAS,UAAA;AAAA,IAAmB,GAK1FC,IAAmBC,GAA2B;AAAA,MAClD,QAAQ,CAAC,WAAW;AAAA,MACpB,QAAQ,EAAE,WAAW,aAAA;AAAA,IAAa,CACnC,GAEKC,IAAyC;AAAA,MAC7C,EAAE,MAAM,SAAS,OAAO,MAAMzB,EAAE,cAAc,GAAG,OAAO,IAAI,OAAO,SAAA;AAAA,MACnE;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAMA,EAAE,aAAa;AAAA,QAC5B,aAAa;AAAA;AAAA,QACb,SAASc;AAAA,QACT,QAAQ,EAAE,SAASY,EAAe,OAAO,OAAO,EAAE,WAAW,IAAM,YAAY,GAAA,EAAK;AAAA,MAAE;AAAA,MAExF;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAM1B,EAAE,aAAa;AAAA,QAC5B,UAAU;AAAA,QACV,UAAU,EAAE,SAAS,GAAA;AAAA,QACrB,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAMA,EAAE,kBAAkB;AAAA,QACjC,OAAO;AAAA,QACP,KAAK;AAAA,QACL,SAASmB;AAAA,MAAA;AAAA,MAEX,EAAE,KAAK,iBAAiB,OAAO,MAAMnB,EAAE,uBAAuB,GAAG,OAAO,KAAK,QAAQ,WAAA;AAAA,MACrF;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAMA,EAAE,mBAAmB;AAAA,QAClC,OAAO;AAAA,QACP,QAAQ;AAAA;AAAA;AAAA,QAGR,QAAQ,EAAE,MAAM,aAAa,SAAS0B,EAAe,SAAA;AAAA,MAAS;AAAA,MAEhE;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAM1B,EAAE,iBAAiB;AAAA,QAChC,OAAO;AAAA,QACP,QAAQ,CAAA2B,MACNC,EAAQD,CAAC,IACLE,EAAEC,GAAM,EAAE,MAAM,SAAS,MAAM,QAAQ,UAAU,MAAS,MAAM9B,EAAE,iBAAiB,CAAC,IACpF6B,EAAE,QAAQ,EAAE,OAAO,UAAA,GAAa,GAAGF,EAAE,SAAS,KAAK;AAAA,MAAA;AAAA,MAE3D;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAM3B,EAAE,mBAAmB;AAAA,QAClC,OAAO;AAAA,QACP,KAAK;AAAA,QACL,QAAQ,EAAE,SAAS0B,EAAe,MAAA;AAAA,QAClC,SAASL;AAAA,MAAA;AAAA,MAEX;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAMrB,EAAE,oBAAoB;AAAA,QACnC,OAAO;AAAA,QACP,OAAO;AAAA,QACP,QAAQ,CAAA2B,MAAMA,EAAE,aAAa,IAAIA,EAAE,aAAa;AAAA,MAAA;AAAA,MAElD,EAAE,KAAK,YAAY,OAAO,MAAM3B,EAAE,cAAc,GAAG,OAAO,KAAK,UAAU,EAAE,SAAS,KAAK;AAAA,MACzF;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAMA,EAAE,kBAAkB;AAAA,QACjC,OAAO;AAAA,QACP,OAAO;AAAA,QACP,eAAe;AAAA,QACf,QAAQ,CAAA2B,MACNE,EAAEE,IAAQ,EAAE,MAAM,GAAG,UAAU,GAAA,GAAS,MAAM;AAAA,UAC5CF;AAAA,YACEG;AAAA,YACA,EAAE,MAAM,SAAS,YAAY,IAAM,MAAM,WAAW,SAAS,MAAMC,EAAWN,CAAC,EAAA;AAAA,YAC/E,MAAM3B,EAAE,eAAe;AAAA,UAAA;AAAA,UAEzB4B,EAAQD,CAAC,KAAKrB,EAAU,QAAQ,oCAAoC,IAChEuB;AAAA,YACEG;AAAA,YACA,EAAE,MAAM,SAAS,YAAY,IAAM,MAAM,SAAS,SAAS,MAAME,EAAQP,CAAC,EAAA;AAAA,YAC1E,MAAM3B,EAAE,cAAc;AAAA,UAAA,IAExB;AAAA,QAAA,CACL;AAAA,MAAA;AAAA,IACL;AAEF,IAAAmC,GAAoBV,CAAO;AAK3B,UAAMW,IAAQC,GAAA;AACd,IAAAC;AAAA,MACE,CAAC9B,GAAU,MAAM4B,EAAM,MAAM,KAAK;AAAA,MAClC,CAAC,CAACG,GAAMC,CAAK,MAAM;AACjB,QAAKD,KAGDH,EAAM,SAAS,qBAEnBK,GAAkBF,GAAM,SAASC,KAAS,OAAO,SAAY,OAAOA,CAAK,CAAC;AAAA,MAC5E;AAAA,MACA,EAAE,WAAW,GAAA;AAAA,IAAK;AAIpB,UAAME,IAAajC,EAAI,EAAK,GACtBkC,IAAYlC,EAAsB,IAAI,GACtCmC,IAAWnC,EAAiB,EAAE,GAC9BoC,IAAkBpC,EAAI,EAAK,GAE3BqC,IAAgB,CAACC,MAAoBC,GAAehD,GAAG+C,CAAC;AAE9D,mBAAed,EAAWN,GAAc;AACtC,MAAAgB,EAAU,QAAQhB,GAClBe,EAAW,QAAQ,IACnBE,EAAS,QAAQ,CAAA,GACjBC,EAAgB,QAAQ;AACxB,UAAI;AACF,cAAM,EAAE,OAAA7B,EAAA,IAAU,MAAMC,EAAO,QAAQ;AAAA,UACrC,MAAM;AAAA,UACN,UAAU;AAAA,UACV,gBAAgBU,EAAE;AAAA,QAAA,CACnB;AACD,QAAAiB,EAAS,QAAQ5B,EAAM,SAAS,CAACiC,GAAGC,MAAMD,EAAE,aAAaC,EAAE,UAAU;AAAA,MACvE,QAAQ;AAAA,MAER,UAAA;AACE,QAAAL,EAAgB,QAAQ;AAAA,MAC1B;AAAA,IACF;AAEA,aAASX,EAAQP,GAAc;AAC7B,MAAAvB,EAAQ;AAAA,QACN,MAAM;AAAA,QACN,SAASJ,EAAE,uBAAuB,EAAE,MAAM2B,EAAE,SAAS;AAAA,QACrD,QAAQ,MAAMV,EAAO,KAAKU,EAAE,EAAE;AAAA,QAC9B,YAAY3B,EAAE,gBAAgB;AAAA,MAAA,CAC/B,EAAE,KAAK,CAAAmD,MAAM;;AACZ,QAAIA,OAAIC,IAAA5C,EAAS,UAAT,QAAA4C,EAAgB;AAAA,MAC1B,CAAC;AAAA,IACH;AAGA,UAAMC,IAAY5C,EAAI,EAAK,GACrB6C,IAAkB7C,EAAI,CAAC,GAEvB8C,IAAe1C,EAAS,MAAM;AAAA,MAClC,EAAE,OAAOb,EAAE,kBAAkB,GAAG,OAAO,EAAA;AAAA,MACvC,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,CAAAwD,OAAM,EAAE,OAAOxD,EAAE,sBAAsB,EAAE,GAAAwD,EAAA,CAAG,GAAG,OAAOA,IAAI;AAAA,IAAA,CAC9E;AAED,mBAAeC,IAAU;;AACvB,UAAI;AACF,cAAMD,IAAI,MAAMvC,EAAO,SAAS;AAAA,UAC9B,YAAYqC,EAAgB,UAAU,IAAI,OAAOA,EAAgB;AAAA,QAAA,CAClE;AACD,QAAApD,EAAQ,QAAQF,EAAE,mBAAmB,EAAE,GAAAwD,EAAA,CAAG,CAAC,GAC3C,QAAMJ,IAAA5C,EAAS,UAAT,gBAAA4C,EAAgB;AAAA,MACxB,SAASM,GAAG;AACV,eAAAxD,EAAQ,MAAMyD,EAAeD,CAAC,CAAC,GACxB;AAAA,MACT;AAAA,IACF;;;;QAIEE,EA2BaC,EAAAC,EAAA,GAAA;AAAA,UA1BV,SAASD,EAAAE,EAAA;AAAA,mBACN;AAAA,UAAJ,KAAIvD;AAAA,UACH,SAAAiB;AAAA,UACA,SAASoC,EAAA5C,CAAA,EAAO;AAAA,UAChB,QAAQ,EAAA,WAAA,QAAA;AAAA,UACR,qBAAmB4C,EAAAtC,CAAA;AAAA,UACpB,eAAA;AAAA,UACC,kBAAgBsC,EAAAG,EAAA;AAAA,UACjB,kBAAA;AAAA,UACA,eAAY;AAAA,UACX,SAAKC,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAE,CAAAP,MAAKG,EAAA3D,CAAA,EAAQ,MAAM2D,EAAAF,CAAA,EAAeD,CAAC,CAAA;AAAA,QAAA;UAEhC,qBAAiBQ,EAC1B,CAAiC,EADH,WAAAC,QAAS;AAAA,YACvCP,EAAiCQ,IAAA,EAApB,OAAOD,EAAA,GAAS,MAAA,GAAA,CAAA,OAAA,CAAA;AAAA,UAAA;UAEpB,mBACT,MAQW;AAAA,qBARXE,EAQWR,EAAA7B,CAAA,GAAA;AAAA,cANT,MAAK;AAAA,cACL,WAAA;AAAA,cACC,gCAAOqB,EAAA,QAAS;AAAA,YAAA;cAEN,QAAK,MAAsC;AAAA,gBAAtCO,EAAsCU,IAAA;AAAA,kBAA7B,MAAK;AAAA,kBAAY,MAAM;AAAA,gBAAA;;yBAAiB,MACjE;AAAA,gBADiEC,EAAA,QAC9DV,EAAA7D,CAAA,EAAC,eAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;kBANI,gCAAgC;AAAA,YAAA;;;;QAY9C4D,EAagBY,IAAA;AAAA,UAZN,MAAMnB,EAAA;AAAA,kDAAAA,EAAS,QAAAoB;AAAA,UACtB,OAAOZ,EAAA7D,CAAA,EAAC,oBAAA;AAAA,UACR,OAAO;AAAA,UACP,cAAYyD;AAAA,UACZ,gBAAcI,EAAA7D,CAAA,EAAC,gBAAA;AAAA,QAAA;qBAEhB,MAKS;AAAA,YALT4D,EAKSC,EAAAa,EAAA,GAAA;AAAA,cALD,mBAAgB;AAAA,cAAQ,eAAa;AAAA,cAAI,0BAAuB;AAAA,YAAA;yBACtE,MAEc;AAAA,gBAFdd,EAEcC,EAAAc,EAAA,GAAA;AAAA,kBAFA,OAAOd,EAAA7D,CAAA,EAAC,oBAAA;AAAA,kBAAwB,UAAA;AAAA,gBAAA;6BAC5C,MAAoE;AAAA,oBAApE4D,EAAoEC,EAAAe,EAAA,GAAA;AAAA,sBAAlD,OAAOtB,EAAA;AAAA,+DAAAA,EAAe,QAAAmB;AAAA,sBAAG,SAASlB,EAAA;AAAA,oBAAA;;;;gBAEtDsB,EAA0D,OAA1DC,IAA0DC,EAA/BlB,EAAA7D,CAAA,EAAC,mBAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;;;;QAKhC4D,EA4DWC,EAAAmB,EAAA,GAAA;AAAA,UA3DD,MAAMtC,EAAA;AAAA,kDAAAA,EAAU,QAAA+B;AAAA,UACvB,WAAW7D,EAAA,QAAM,WAAA;AAAA,UACjB,OAAOA,EAAA,QAAS,SAAS;AAAA,UACzB,QAAQA,EAAA,QAAM,SAAY;AAAA,UAC1B,wBAAqBA,EAAA,OAAM;AAAA,UAC3B,OAAKqE,GAAErE,EAAA,QAAM,qBAAwB,MAAS;AAAA,QAAA;qBAE/C,MAmDmB;AAAA,YAnDnBgD,EAmDmBC,EAAAqB,EAAA,GAAA;AAAA,cAnDA,OAAOrB,EAAA7D,CAAA,EAAC,eAAA;AAAA,cAAmB,UAAA;AAAA,cAAU,oBAAkBY,EAAA;AAAA,YAAA;yBACxE,MAiDW;AAAA,gBAjDK+B,EAAA,cAAhBwC,EAiDWC,GAAA,EAAA,KAAA,KAAA;AAAA,kBAhDTxB,EA4CiBC,EAAAwB,EAAA,GAAA;AAAA,oBA3Cf,mBAAgB;AAAA,oBACf,QAAQ;AAAA,oBACT,UAAA;AAAA,oBACA,MAAK;AAAA,oBACL,eAAY;AAAA,kBAAA;+BAEZ,MAEsB;AAAA,sBAFtBzB,EAEsBC,EAAAyB,CAAA,GAAA;AAAA,wBAFA,OAAOzB,EAAA7D,CAAA,EAAC,aAAA;AAAA,sBAAA;mCAC5B,MAAuB;AAAA,0BAApBuE,EAAAQ,EAAApC,EAAA,MAAU,OAAO,GAAA,CAAA;AAAA,wBAAA;;;sBAEtBiB,EAUsBC,EAAAyB,CAAA,GAAA;AAAA,wBAVA,OAAOzB,EAAA7D,CAAA,EAAC,kBAAA;AAAA,sBAAA;mCAC5B,MAQE;AAAA,0BAPAuE,EAAAQ,EAAApC,EAAA,MAAU,aAAakB,EAAAzC,CAAA,EAAY,SAAyByC,EAAA7D,CAAA,EAAC,wBAAA,IAA6C2C,EAAA,MAAU,aAAakB,EAAAzC,CAAA,EAAY,UAA4ByC,EAAA7D,CAAA,EAAC,0BAAA,IAAiD2C,EAAA,MAAU,aAAakB,EAAAzC,CAAA,EAAY,gBAAoCyC,EAAA7D,CAAA,EAAC,6BAAA,IAAsD6D,EAAA7D,CAAA,EAAC,0BAAA,CAAA,GAAA,CAAA;AAAA,wBAAA;;;sBAS9V4D,EAIsBC,EAAAyB,CAAA,GAAA;AAAA,wBAJA,OAAOzB,EAAA7D,CAAA,EAAC,mBAAA;AAAA,sBAAA;mCAC5B,MAEQ;AAAA,0BAFR4D,EAEQC,EAAA/B,CAAA,GAAA;AAAA,4BAFD,MAAK;AAAA,4BAAS,UAAU;AAAA,4BAAQ,MAAM+B,EAAA0B,EAAA,EAAiB5C,EAAA,MAAU,SAAS;AAAA,0BAAA;uCAC/E,MAAwC;AAAA,kCAArCG,EAAcH,EAAA,MAAU,SAAS,CAAA,GAAA,CAAA;AAAA,4BAAA;;;;;;sBAGxCiB,EAEsBC,EAAAyB,CAAA,GAAA;AAAA,wBAFA,OAAOzB,EAAA7D,CAAA,EAAC,uBAAA;AAAA,sBAAA;mCAC5B,MAA0C;AAAA,8BAAvC6D,EAAA2B,CAAA,EAAY7C,EAAA,MAAU,aAAa,CAAA,GAAA,CAAA;AAAA,wBAAA;;;sBAExCiB,EAEsBC,EAAAyB,CAAA,GAAA;AAAA,wBAFA,OAAOzB,EAAA7D,CAAA,EAAC,mBAAA;AAAA,sBAAA;mCAC5B,MAAsC;AAAA,8BAAnC6D,EAAA2B,CAAA,EAAY7C,EAAA,MAAU,SAAS,CAAA,GAAA,CAAA;AAAA,wBAAA;;;sBAEpCiB,EAEsBC,EAAAyB,CAAA,GAAA;AAAA,wBAFA,OAAOzB,EAAA7D,CAAA,EAAC,iBAAA;AAAA,sBAAA;mCAC5B,MAAoF;AAAA,0BAAjFuE,EAAAQ,EAAApC,EAAA,MAAU,WAAO,OAAWkB,KAAC,iBAAA,IAAA,GAAyBlB,EAAA,MAAU,SAAS,KAAA,GAAA,CAAA;AAAA,wBAAA;;;sBAE9EiB,EAEsBC,EAAAyB,CAAA,GAAA;AAAA,wBAFA,OAAOzB,EAAA7D,CAAA,EAAC,cAAA;AAAA,sBAAA;mCAC5B,MAA+B;AAAA,0BAA5BuE,EAAAQ,EAAApC,EAAA,MAAU,YAAQ,GAAA,GAAA,CAAA;AAAA,wBAAA;;;sBAEIA,EAAA,MAAU,oBAArC0B,EAEsBR,EAAAyB,CAAA,GAAA;AAAA;wBAF6B,OAAOzB,EAAA7D,CAAA,EAAC,iBAAA;AAAA,sBAAA;mCACzD,MAAyD;AAAA,0BAAzD6E,EAAyD,OAAzDY,IAAyDV,EAA9BpC,EAAA,MAAU,WAAW,GAAA,CAAA;AAAA,wBAAA;;;sBAEvBA,EAAA,MAAU,kBAArC0B,EAEsBR,EAAAyB,CAAA,GAAA;AAAA;wBAF2B,OAAOzB,EAAA7D,CAAA,EAAC,eAAA;AAAA,sBAAA;mCACvD,MAAiE;AAAA,0BAAjE6E,EAAiE,OAAjEa,IAAiEX,EAA5BpC,EAAA,MAAU,SAAS,GAAA,CAAA;AAAA,wBAAA;;;;;;kBAI5DkC,EAA6D,OAA7Dc,IAA6DZ,EAA9BlB,EAAA7D,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,kBAChC4D,EAA4DgC,IAAA;AAAA,oBAA7C,MAAMhD,EAAA;AAAA,oBAAW,SAASC,EAAA;AAAA,kBAAA;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index2.vue.js","sources":["../../../../src/views/system/job-log/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 执行记录 = 只读 SmartTable + 详情抽屉 + 终止/清空两个动作。\n// 「运行中」没有独立状态字段,判据是 endTime 为空(任务无 Running 态,全靠未闭合记录推导);\n// 终止是跨节点写旗标,目标节点最迟 KillPollSeconds 后停——所以文案说\"已请求终止\"而非\"已终止\"。\n// 详情抽屉里带同 fireInstanceId 的各次尝试列表:走后端的 fireInstanceId 查询参数直取,\n// 不按 jobId 拉一页再前端过滤——翻到老触发时那一页里根本没有它的兄弟行,列表会静默缺项。\nimport { computed, h, ref, watch } from 'vue'\nimport { useShellBreakpoint } from '#/composables/useShellBreakpoint'\nimport {\n NButton,\n NTag,\n NSelect,\n NSpace,\n NDrawer,\n NDrawerContent,\n NDescriptions,\n NDescriptionsItem,\n NForm,\n NFormItem,\n useMessage,\n} from 'naive-ui'\nimport { useRoute } from 'vue-router'\nimport { useI18n } from 'vue-i18n'\nimport { SmartTable, type SmartTableColumn, type SmartTableInst } from 'smart-naive-table'\nimport AppIcon from '#/components/AppIcon.vue'\nimport FormContainer from '#/components/FormContainer/index.vue'\nimport { useConfirm } from '#/composables/useConfirm'\nimport { useAuthStore } from '#/stores/auth'\nimport { jobApi } from '#/api'\nimport { translateError } from '#/utils/error'\nimport {\n SEARCH_ACTIONS,\n createFlatFilterSerializer,\n presetEqualFilter,\n deriveHeaderFilters,\n} from '#/utils/tableFilter'\nimport { TABLE_MIN_ROW_HEIGHT, TABLE_TOOLBAR } from '#/utils/tableToolbar'\nimport TableTotal from '#/components/TableTotal/index.vue'\nimport AttemptTable from './components/AttemptTable.vue'\nimport { isAlive, runStatusLabel, runStatusTagType } from './runStatus'\nimport { fmtDateTime } from '#/utils/format'\nimport { JobFireMode, JobRunStatus, type SysJobLog } from '#/types/api'\n\nconst { t } = useI18n()\nconst message = useMessage()\nconst { confirm } = useConfirm()\nconst authStore = useAuthStore()\nconst tableRef = ref<SmartTableInst<SysJobLog>>()\n// 壳层窄档(内容区 < 600,与表格卡片列表同阈值):详情抽屉改底部抽屉,尝试子表改卡片列表\nconst { bp } = useShellBreakpoint()\nconst narrow = computed(() => bp.value === 'narrow')\n\n// 任务下拉(筛选用):拉一页足量。ponytail: 200 覆盖绝大多数系统,真超再上远程搜索\nconst jobOptions = ref<{ label: string; value: number }[]>([])\nasync function loadJobOptions() {\n try {\n const { items } = await jobApi.page({ page: 1, pageSize: 200 })\n jobOptions.value = items.map(j => ({ label: j.name, value: j.id }))\n } catch {\n // 静默:任务下拉是筛选辅助,拉取失败不打断列表\n }\n}\nvoid loadJobOptions()\n\nconst fireModeOptions = [\n {\n label: () => t('job.log.fireModeSchedule'),\n value: JobFireMode.Schedule,\n tagType: 'default' as const,\n },\n { label: () => t('job.log.fireModeManual'), value: JobFireMode.Manual, tagType: 'info' as const },\n {\n label: () => t('job.log.fireModeBackfill'),\n value: JobFireMode.Misfire,\n tagType: 'warning' as const,\n },\n {\n label: () => t('job.log.fireModeMisfireSkip'),\n value: JobFireMode.MissedSkipped,\n tagType: 'default' as const,\n },\n]\nconst runStatusOptions = [\n { label: () => t('job.log.running'), value: JobRunStatus.Running, tagType: 'info' as const },\n { label: () => t('job.log.success'), value: JobRunStatus.Success, tagType: 'success' as const },\n { label: () => t('job.log.failed'), value: JobRunStatus.Failed, tagType: 'error' as const },\n { label: () => t('job.log.timeout'), value: JobRunStatus.Timeout, tagType: 'warning' as const },\n {\n label: () => t('job.log.cancelled'),\n value: JobRunStatus.Cancelled,\n tagType: 'default' as const,\n },\n { label: () => t('job.log.skipped'), value: JobRunStatus.Skipped, tagType: 'default' as const },\n]\n\n// 条件构造器下 search.key 被忽略,过滤键就是列 key;后端参数叫 startRange(api 层 logPage 再拆成 StartFrom/StartTo 并补秒),\n// 所以 startTime 要改名,并按日期区间字段处理(同字段的 gte + lte 合并成 [起, 止])。\nconst filterSerializer = createFlatFilterSerializer({\n ranges: ['startTime'],\n rename: { startTime: 'startRange' },\n})\n\nconst columns: SmartTableColumn<SysJobLog>[] = [\n { type: 'index', title: () => t('common.rowNo'), width: 64, align: 'center' },\n {\n key: 'jobId',\n title: () => t('job.log.job'),\n hideInTable: true, // 只作搜索项:表格里已有任务名快照列\n options: jobOptions,\n search: { actions: SEARCH_ACTIONS.exact, props: { clearable: true, filterable: true } },\n },\n {\n key: 'jobName',\n title: () => t('job.log.job'),\n width: 160,\n ellipsis: { tooltip: true },\n card: 'title',\n },\n {\n key: 'fireMode',\n title: () => t('job.log.fireMode'),\n width: 100,\n tag: true,\n options: fireModeOptions,\n },\n { key: 'scheduledTime', title: () => t('job.log.scheduledTime'), width: 160, format: 'datetime' },\n {\n key: 'startTime',\n title: () => t('job.log.startTime'),\n width: 160,\n format: 'datetime',\n // 时间范围筛选:条件构造器里是同一字段的两行(大于等于 + 小于等于),序列化器合并成 [起, 止],\n // api 层再拆成 StartFrom/StartTo 并补秒\n search: { type: 'daterange', actions: SEARCH_ACTIONS.dayRange },\n },\n {\n key: 'elapsedMs',\n title: () => t('job.log.elapsed'),\n width: 110,\n render: r =>\n isAlive(r)\n ? h(NTag, { size: 'small', type: 'info', bordered: false }, () => t('job.log.running'))\n : h('span', { class: 'tabular' }, `${r.elapsedMs} ms`),\n },\n {\n key: 'runStatus',\n title: () => t('job.log.runStatus'),\n width: 100,\n tag: true,\n search: { actions: SEARCH_ACTIONS.exact },\n options: runStatusOptions,\n },\n {\n key: 'retryIndex',\n title: () => t('job.log.retryIndex'),\n width: 90,\n align: 'center',\n render: r => (r.retryIndex > 0 ? r.retryIndex : '—'),\n },\n { key: 'nodeName', title: () => t('job.log.node'), width: 140, ellipsis: { tooltip: true } },\n {\n key: 'op',\n title: () => t('common.operation'),\n width: 130,\n fixed: 'right',\n hideInSetting: true,\n render: r =>\n h(NSpace, { size: 4, wrapItem: false }, () => [\n h(\n NButton,\n { size: 'small', quaternary: true, type: 'primary', onClick: () => openDetail(r) },\n () => t('common.detail'),\n ),\n isAlive(r) && authStore.hasPerm('POST:/api/v1/sys/job/log/{id}/kill')\n ? h(\n NButton,\n { size: 'small', quaternary: true, type: 'error', onClick: () => killRun(r) },\n () => t('job.log.kill'),\n )\n : null,\n ]),\n },\n]\nderiveHeaderFilters(columns)\n\n// 从任务页「记录」跳来时带 ?jobId=,自动带上筛选。\n// watch 而非 onMounted:页面被 keep-alive,标签开着时再跳一次只换 query,onMounted 不会再触发;\n// tableRef 一起纳入监听源,冷启动时实例就绪后补上筛选(immediate 在 setup 期 ref 还是空)。\nconst route = useRoute()\nwatch(\n [tableRef, () => route.query.jobId],\n ([inst, jobId]) => {\n if (!inst) return\n // route 是全局的:切到别的页面时 query.jobId 变 undefined,本页被 keep-alive 着的 watcher 照样会响。\n // 不守卫就等于「离开本页 = 清掉筛选并后台发一次没人看的请求」,切回来筛选还没了。\n if (route.path !== '/system/job-log') return\n // 值没变 presetEqualFilter 不写;远程模式下 setFilter 自己会回第 1 页重查\n presetEqualFilter(inst, 'jobId', jobId == null ? undefined : Number(jobId))\n },\n { immediate: true },\n)\n\n// ── 详情抽屉(行数据直填 + 同 fireInstanceId 的各次尝试) ──\nconst showDetail = ref(false)\nconst detailRow = ref<SysJobLog | null>(null)\nconst attempts = ref<SysJobLog[]>([])\nconst attemptsLoading = ref(false)\n\nconst runStatusText = (s: JobRunStatus) => runStatusLabel(t, s)\n\nasync function openDetail(r: SysJobLog) {\n detailRow.value = r\n showDetail.value = true\n attempts.value = []\n attemptsLoading.value = true\n try {\n const { items } = await jobApi.logPage({\n page: 1,\n pageSize: 100,\n fireInstanceId: r.fireInstanceId,\n })\n attempts.value = items.toSorted((a, b) => a.retryIndex - b.retryIndex)\n } catch {\n // 静默:尝试列表是详情的补充信息,拉不到不挡主体\n } finally {\n attemptsLoading.value = false\n }\n}\n\nfunction killRun(r: SysJobLog) {\n confirm({\n type: 'error',\n content: t('job.log.killConfirm', { name: r.jobName }),\n action: () => jobApi.kill(r.id),\n successMsg: t('job.log.killed'),\n }).then(ok => {\n if (ok) tableRef.value?.refresh()\n })\n}\n\n// ── 清空(弹窗选 beforeDays;0 = 全部) ──\nconst clearShow = ref(false)\nconst clearBeforeDays = ref(0)\n// computed:切语言时选项文案即时生效\nconst clearOptions = computed(() => [\n { label: t('job.log.clearAll'), value: 0 },\n ...[7, 30, 90].map(n => ({ label: t('job.log.beforeDays', { n }), value: n })),\n])\n\nasync function doClear() {\n try {\n const n = await jobApi.logClear({\n beforeDays: clearBeforeDays.value === 0 ? null : clearBeforeDays.value,\n })\n message.success(t('job.log.cleared', { n }))\n await tableRef.value?.refresh()\n } catch (e) {\n message.error(translateError(e))\n return false\n }\n}\n</script>\n\n<template>\n <SmartTable\n :toolbar=\"TABLE_TOOLBAR\"\n ref=\"tableRef\"\n :columns=\"columns\"\n :fetcher=\"jobApi.logPage\"\n :search=\"{ container: 'table' }\"\n :filter-serializer=\"filterSerializer\"\n fill-height\n :min-row-height=\"TABLE_MIN_ROW_HEIGHT\"\n card-on-narrow\n storage-key=\"sys-job-log\"\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\n v-auth=\"'POST:/api/v1/sys/job/log/clear'\"\n type=\"error\"\n secondary\n @click=\"clearShow = true\"\n >\n <template #icon><AppIcon icon=\"ph:trash\" :size=\"16\" /></template>\n {{ t('job.log.clear') }}\n </n-button>\n </template>\n </SmartTable>\n\n <!-- 清空:选范围后执行,回报删除行数 -->\n <FormContainer\n v-model:show=\"clearShow\"\n :title=\"t('job.log.clearTitle')\"\n :width=\"420\"\n :on-confirm=\"doClear\"\n :confirm-text=\"t('common.confirm')\"\n >\n <n-form label-placement=\"left\" :label-width=\"60\" require-mark-placement=\"left\">\n <n-form-item :label=\"t('job.log.clearRange')\" required>\n <n-select v-model:value=\"clearBeforeDays\" :options=\"clearOptions\" />\n </n-form-item>\n <div class=\"clear-hint\">{{ t('job.log.clearHint') }}</div>\n </n-form>\n </FormContainer>\n\n <!-- 详情抽屉:右侧 600 宽;窄档改底部抽屉(上圆角,最高 85vh) -->\n <n-drawer\n v-model:show=\"showDetail\"\n :placement=\"narrow ? 'bottom' : 'right'\"\n :width=\"narrow ? undefined : 'min(600px, 100vw)'\"\n :height=\"narrow ? 'auto' : undefined\"\n :class=\"{ 'st-sheet': narrow }\"\n :style=\"narrow ? 'max-height: 85vh' : undefined\"\n >\n <n-drawer-content :title=\"t('common.detail')\" closable :native-scrollbar=\"narrow\">\n <template v-if=\"detailRow\">\n <n-descriptions\n label-placement=\"left\"\n :column=\"1\"\n bordered\n size=\"small\"\n label-style=\"width: 100px\"\n >\n <n-descriptions-item :label=\"t('job.log.job')\">\n {{ detailRow.jobName }}\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('job.log.fireMode')\">\n {{\n detailRow.fireMode === JobFireMode.Manual\n ? t('job.log.fireModeManual')\n : detailRow.fireMode === JobFireMode.Misfire\n ? t('job.log.fireModeBackfill')\n : detailRow.fireMode === JobFireMode.MissedSkipped\n ? t('job.log.fireModeMisfireSkip')\n : t('job.log.fireModeSchedule')\n }}\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('job.log.runStatus')\">\n <n-tag size=\"small\" :bordered=\"false\" :type=\"runStatusTagType[detailRow.runStatus]\">\n {{ runStatusText(detailRow.runStatus) }}\n </n-tag>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('job.log.scheduledTime')\">\n {{ fmtDateTime(detailRow.scheduledTime) }}\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('job.log.startTime')\">\n {{ fmtDateTime(detailRow.startTime) }}\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('job.log.elapsed')\">\n {{ detailRow.endTime == null ? t('job.log.running') : `${detailRow.elapsedMs} ms` }}\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('job.log.node')\">\n {{ detailRow.nodeName || '—' }}\n </n-descriptions-item>\n <n-descriptions-item v-if=\"detailRow.messageText\" :label=\"t('job.log.message')\">\n <pre class=\"log-output\">{{ detailRow.messageText }}</pre>\n </n-descriptions-item>\n <n-descriptions-item v-if=\"detailRow.errorText\" :label=\"t('job.log.error')\">\n <pre class=\"log-output log-error\">{{ detailRow.errorText }}</pre>\n </n-descriptions-item>\n </n-descriptions>\n\n <div class=\"attempts-title\">{{ t('job.log.attempts') }}</div>\n <AttemptTable :rows=\"attempts\" :loading=\"attemptsLoading\" />\n </template>\n </n-drawer-content>\n </n-drawer>\n</template>\n\n<style scoped>\n.clear-hint {\n font-size: 13px;\n line-height: 1.6;\n color: var(--text-3);\n}\n/* 小标题:同描述列表拉开距离 */\n.attempts-title {\n margin: 16px 0 6px 2px;\n font-size: 13px;\n font-weight: 500;\n letter-spacing: -0.01em;\n color: var(--text-3);\n}\n.log-output {\n margin: 0;\n white-space: pre-wrap;\n word-break: break-all;\n font-family: var(--font-mono, ui-monospace, 'SFMono-Regular', Menlo, Consolas, monospace);\n font-size: 12px;\n line-height: 1.55;\n}\n.log-error {\n color: var(--err);\n}\n\n/* 窄档:底部抽屉 */\n.st-sheet {\n display: flex;\n flex-direction: column;\n border-radius: var(--radius-xl) var(--radius-xl) 0 0;\n}\n.st-sheet :deep(.n-drawer-content-wrapper) {\n display: flex;\n flex-direction: column;\n min-height: 0;\n}\n</style>\n"],"names":["t","useI18n","message","useMessage","confirm","useConfirm","authStore","useAuthStore","tableRef","ref","bp","useShellBreakpoint","narrow","computed","jobOptions","loadJobOptions","items","jobApi","j","fireModeOptions","JobFireMode","runStatusOptions","JobRunStatus","filterSerializer","createFlatFilterSerializer","columns","SEARCH_ACTIONS","r","isAlive","h","NTag","NSpace","NButton","openDetail","killRun","deriveHeaderFilters","route","useRoute","watch","inst","jobId","presetEqualFilter","showDetail","detailRow","attempts","attemptsLoading","runStatusText","s","runStatusLabel","a","b","ok","_a","clearShow","clearBeforeDays","clearOptions","n","doClear","e","translateError","_createVNode","_unref","SmartTable","TABLE_TOOLBAR","TABLE_MIN_ROW_HEIGHT","_cache","_withCtx","itemCount","TableTotal","_createBlock","AppIcon","_createTextVNode","FormContainer","$event","NForm","NFormItem","NSelect","_createElementVNode","_hoisted_1","_toDisplayString","NDrawer","_normalizeStyle","NDrawerContent","_createElementBlock","_Fragment","NDescriptions","NDescriptionsItem","runStatusTagType","fmtDateTime","_hoisted_2","_hoisted_3","_hoisted_4","AttemptTable"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AA2CA,UAAM,EAAE,GAAAA,EAAA,IAAMC,GAAA,GACRC,IAAUC,GAAA,GACV,EAAE,SAAAC,EAAA,IAAYC,GAAA,GACdC,IAAYC,GAAA,GACZC,IAAWC,EAAA,GAEX,EAAE,IAAAC,EAAA,IAAOC,GAAA,GACTC,IAASC,EAAS,MAAMH,EAAG,UAAU,QAAQ,GAG7CI,IAAaL,EAAwC,EAAE;AAC7D,mBAAeM,IAAiB;AAC9B,UAAI;AACF,cAAM,EAAE,OAAAC,MAAU,MAAMC,EAAO,KAAK,EAAE,MAAM,GAAG,UAAU,KAAK;AAC9D,QAAAH,EAAW,QAAQE,EAAM,IAAI,CAAAE,OAAM,EAAE,OAAOA,EAAE,MAAM,OAAOA,EAAE,GAAA,EAAK;AAAA,MACpE,QAAQ;AAAA,MAER;AAAA,IACF;AACA,IAAKH,EAAA;AAEL,UAAMI,IAAkB;AAAA,MACtB;AAAA,QACE,OAAO,MAAMnB,EAAE,0BAA0B;AAAA,QACzC,OAAOoB,EAAY;AAAA,QACnB,SAAS;AAAA,MAAA;AAAA,MAEX,EAAE,OAAO,MAAMpB,EAAE,wBAAwB,GAAG,OAAOoB,EAAY,QAAQ,SAAS,OAAA;AAAA,MAChF;AAAA,QACE,OAAO,MAAMpB,EAAE,0BAA0B;AAAA,QACzC,OAAOoB,EAAY;AAAA,QACnB,SAAS;AAAA,MAAA;AAAA,MAEX;AAAA,QACE,OAAO,MAAMpB,EAAE,6BAA6B;AAAA,QAC5C,OAAOoB,EAAY;AAAA,QACnB,SAAS;AAAA,MAAA;AAAA,IACX,GAEIC,IAAmB;AAAA,MACvB,EAAE,OAAO,MAAMrB,EAAE,iBAAiB,GAAG,OAAOsB,EAAa,SAAS,SAAS,OAAA;AAAA,MAC3E,EAAE,OAAO,MAAMtB,EAAE,iBAAiB,GAAG,OAAOsB,EAAa,SAAS,SAAS,UAAA;AAAA,MAC3E,EAAE,OAAO,MAAMtB,EAAE,gBAAgB,GAAG,OAAOsB,EAAa,QAAQ,SAAS,QAAA;AAAA,MACzE,EAAE,OAAO,MAAMtB,EAAE,iBAAiB,GAAG,OAAOsB,EAAa,SAAS,SAAS,UAAA;AAAA,MAC3E;AAAA,QACE,OAAO,MAAMtB,EAAE,mBAAmB;AAAA,QAClC,OAAOsB,EAAa;AAAA,QACpB,SAAS;AAAA,MAAA;AAAA,MAEX,EAAE,OAAO,MAAMtB,EAAE,iBAAiB,GAAG,OAAOsB,EAAa,SAAS,SAAS,UAAA;AAAA,IAAmB,GAK1FC,IAAmBC,GAA2B;AAAA,MAClD,QAAQ,CAAC,WAAW;AAAA,MACpB,QAAQ,EAAE,WAAW,aAAA;AAAA,IAAa,CACnC,GAEKC,IAAyC;AAAA,MAC7C,EAAE,MAAM,SAAS,OAAO,MAAMzB,EAAE,cAAc,GAAG,OAAO,IAAI,OAAO,SAAA;AAAA,MACnE;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAMA,EAAE,aAAa;AAAA,QAC5B,aAAa;AAAA;AAAA,QACb,SAASc;AAAA,QACT,QAAQ,EAAE,SAASY,EAAe,OAAO,OAAO,EAAE,WAAW,IAAM,YAAY,GAAA,EAAK;AAAA,MAAE;AAAA,MAExF;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAM1B,EAAE,aAAa;AAAA,QAC5B,OAAO;AAAA,QACP,UAAU,EAAE,SAAS,GAAA;AAAA,QACrB,MAAM;AAAA,MAAA;AAAA,MAER;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAMA,EAAE,kBAAkB;AAAA,QACjC,OAAO;AAAA,QACP,KAAK;AAAA,QACL,SAASmB;AAAA,MAAA;AAAA,MAEX,EAAE,KAAK,iBAAiB,OAAO,MAAMnB,EAAE,uBAAuB,GAAG,OAAO,KAAK,QAAQ,WAAA;AAAA,MACrF;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAMA,EAAE,mBAAmB;AAAA,QAClC,OAAO;AAAA,QACP,QAAQ;AAAA;AAAA;AAAA,QAGR,QAAQ,EAAE,MAAM,aAAa,SAAS0B,EAAe,SAAA;AAAA,MAAS;AAAA,MAEhE;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAM1B,EAAE,iBAAiB;AAAA,QAChC,OAAO;AAAA,QACP,QAAQ,CAAA2B,MACNC,EAAQD,CAAC,IACLE,EAAEC,GAAM,EAAE,MAAM,SAAS,MAAM,QAAQ,UAAU,MAAS,MAAM9B,EAAE,iBAAiB,CAAC,IACpF6B,EAAE,QAAQ,EAAE,OAAO,UAAA,GAAa,GAAGF,EAAE,SAAS,KAAK;AAAA,MAAA;AAAA,MAE3D;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAM3B,EAAE,mBAAmB;AAAA,QAClC,OAAO;AAAA,QACP,KAAK;AAAA,QACL,QAAQ,EAAE,SAAS0B,EAAe,MAAA;AAAA,QAClC,SAASL;AAAA,MAAA;AAAA,MAEX;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAMrB,EAAE,oBAAoB;AAAA,QACnC,OAAO;AAAA,QACP,OAAO;AAAA,QACP,QAAQ,CAAA2B,MAAMA,EAAE,aAAa,IAAIA,EAAE,aAAa;AAAA,MAAA;AAAA,MAElD,EAAE,KAAK,YAAY,OAAO,MAAM3B,EAAE,cAAc,GAAG,OAAO,KAAK,UAAU,EAAE,SAAS,KAAK;AAAA,MACzF;AAAA,QACE,KAAK;AAAA,QACL,OAAO,MAAMA,EAAE,kBAAkB;AAAA,QACjC,OAAO;AAAA,QACP,OAAO;AAAA,QACP,eAAe;AAAA,QACf,QAAQ,CAAA2B,MACNE,EAAEE,IAAQ,EAAE,MAAM,GAAG,UAAU,GAAA,GAAS,MAAM;AAAA,UAC5CF;AAAA,YACEG;AAAA,YACA,EAAE,MAAM,SAAS,YAAY,IAAM,MAAM,WAAW,SAAS,MAAMC,EAAWN,CAAC,EAAA;AAAA,YAC/E,MAAM3B,EAAE,eAAe;AAAA,UAAA;AAAA,UAEzB4B,EAAQD,CAAC,KAAKrB,EAAU,QAAQ,oCAAoC,IAChEuB;AAAA,YACEG;AAAA,YACA,EAAE,MAAM,SAAS,YAAY,IAAM,MAAM,SAAS,SAAS,MAAME,EAAQP,CAAC,EAAA;AAAA,YAC1E,MAAM3B,EAAE,cAAc;AAAA,UAAA,IAExB;AAAA,QAAA,CACL;AAAA,MAAA;AAAA,IACL;AAEF,IAAAmC,GAAoBV,CAAO;AAK3B,UAAMW,IAAQC,GAAA;AACd,IAAAC;AAAA,MACE,CAAC9B,GAAU,MAAM4B,EAAM,MAAM,KAAK;AAAA,MAClC,CAAC,CAACG,GAAMC,CAAK,MAAM;AACjB,QAAKD,KAGDH,EAAM,SAAS,qBAEnBK,GAAkBF,GAAM,SAASC,KAAS,OAAO,SAAY,OAAOA,CAAK,CAAC;AAAA,MAC5E;AAAA,MACA,EAAE,WAAW,GAAA;AAAA,IAAK;AAIpB,UAAME,IAAajC,EAAI,EAAK,GACtBkC,IAAYlC,EAAsB,IAAI,GACtCmC,IAAWnC,EAAiB,EAAE,GAC9BoC,IAAkBpC,EAAI,EAAK,GAE3BqC,IAAgB,CAACC,MAAoBC,GAAehD,GAAG+C,CAAC;AAE9D,mBAAed,EAAWN,GAAc;AACtC,MAAAgB,EAAU,QAAQhB,GAClBe,EAAW,QAAQ,IACnBE,EAAS,QAAQ,CAAA,GACjBC,EAAgB,QAAQ;AACxB,UAAI;AACF,cAAM,EAAE,OAAA7B,EAAA,IAAU,MAAMC,EAAO,QAAQ;AAAA,UACrC,MAAM;AAAA,UACN,UAAU;AAAA,UACV,gBAAgBU,EAAE;AAAA,QAAA,CACnB;AACD,QAAAiB,EAAS,QAAQ5B,EAAM,SAAS,CAACiC,GAAGC,MAAMD,EAAE,aAAaC,EAAE,UAAU;AAAA,MACvE,QAAQ;AAAA,MAER,UAAA;AACE,QAAAL,EAAgB,QAAQ;AAAA,MAC1B;AAAA,IACF;AAEA,aAASX,EAAQP,GAAc;AAC7B,MAAAvB,EAAQ;AAAA,QACN,MAAM;AAAA,QACN,SAASJ,EAAE,uBAAuB,EAAE,MAAM2B,EAAE,SAAS;AAAA,QACrD,QAAQ,MAAMV,EAAO,KAAKU,EAAE,EAAE;AAAA,QAC9B,YAAY3B,EAAE,gBAAgB;AAAA,MAAA,CAC/B,EAAE,KAAK,CAAAmD,MAAM;;AACZ,QAAIA,OAAIC,IAAA5C,EAAS,UAAT,QAAA4C,EAAgB;AAAA,MAC1B,CAAC;AAAA,IACH;AAGA,UAAMC,IAAY5C,EAAI,EAAK,GACrB6C,IAAkB7C,EAAI,CAAC,GAEvB8C,IAAe1C,EAAS,MAAM;AAAA,MAClC,EAAE,OAAOb,EAAE,kBAAkB,GAAG,OAAO,EAAA;AAAA,MACvC,GAAG,CAAC,GAAG,IAAI,EAAE,EAAE,IAAI,CAAAwD,OAAM,EAAE,OAAOxD,EAAE,sBAAsB,EAAE,GAAAwD,EAAA,CAAG,GAAG,OAAOA,IAAI;AAAA,IAAA,CAC9E;AAED,mBAAeC,IAAU;;AACvB,UAAI;AACF,cAAMD,IAAI,MAAMvC,EAAO,SAAS;AAAA,UAC9B,YAAYqC,EAAgB,UAAU,IAAI,OAAOA,EAAgB;AAAA,QAAA,CAClE;AACD,QAAApD,EAAQ,QAAQF,EAAE,mBAAmB,EAAE,GAAAwD,EAAA,CAAG,CAAC,GAC3C,QAAMJ,IAAA5C,EAAS,UAAT,gBAAA4C,EAAgB;AAAA,MACxB,SAASM,GAAG;AACV,eAAAxD,EAAQ,MAAMyD,EAAeD,CAAC,CAAC,GACxB;AAAA,MACT;AAAA,IACF;;;;QAIEE,EA2BaC,EAAAC,EAAA,GAAA;AAAA,UA1BV,SAASD,EAAAE,EAAA;AAAA,mBACN;AAAA,UAAJ,KAAIvD;AAAA,UACH,SAAAiB;AAAA,UACA,SAASoC,EAAA5C,CAAA,EAAO;AAAA,UAChB,QAAQ,EAAA,WAAA,QAAA;AAAA,UACR,qBAAmB4C,EAAAtC,CAAA;AAAA,UACpB,eAAA;AAAA,UACC,kBAAgBsC,EAAAG,EAAA;AAAA,UACjB,kBAAA;AAAA,UACA,eAAY;AAAA,UACX,SAAKC,EAAA,CAAA,MAAAA,EAAA,CAAA,IAAE,CAAAP,MAAKG,EAAA3D,CAAA,EAAQ,MAAM2D,EAAAF,CAAA,EAAeD,CAAC,CAAA;AAAA,QAAA;UAEhC,qBAAiBQ,EAC1B,CAAiC,EADH,WAAAC,QAAS;AAAA,YACvCP,EAAiCQ,IAAA,EAApB,OAAOD,EAAA,GAAS,MAAA,GAAA,CAAA,OAAA,CAAA;AAAA,UAAA;UAEpB,mBACT,MAQW;AAAA,qBARXE,EAQWR,EAAA7B,CAAA,GAAA;AAAA,cANT,MAAK;AAAA,cACL,WAAA;AAAA,cACC,gCAAOqB,EAAA,QAAS;AAAA,YAAA;cAEN,QAAK,MAAsC;AAAA,gBAAtCO,EAAsCU,IAAA;AAAA,kBAA7B,MAAK;AAAA,kBAAY,MAAM;AAAA,gBAAA;;yBAAiB,MACjE;AAAA,gBADiEC,EAAA,QAC9DV,EAAA7D,CAAA,EAAC,eAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;kBANI,gCAAgC;AAAA,YAAA;;;;QAY9C4D,EAagBY,IAAA;AAAA,UAZN,MAAMnB,EAAA;AAAA,kDAAAA,EAAS,QAAAoB;AAAA,UACtB,OAAOZ,EAAA7D,CAAA,EAAC,oBAAA;AAAA,UACR,OAAO;AAAA,UACP,cAAYyD;AAAA,UACZ,gBAAcI,EAAA7D,CAAA,EAAC,gBAAA;AAAA,QAAA;qBAEhB,MAKS;AAAA,YALT4D,EAKSC,EAAAa,EAAA,GAAA;AAAA,cALD,mBAAgB;AAAA,cAAQ,eAAa;AAAA,cAAI,0BAAuB;AAAA,YAAA;yBACtE,MAEc;AAAA,gBAFdd,EAEcC,EAAAc,EAAA,GAAA;AAAA,kBAFA,OAAOd,EAAA7D,CAAA,EAAC,oBAAA;AAAA,kBAAwB,UAAA;AAAA,gBAAA;6BAC5C,MAAoE;AAAA,oBAApE4D,EAAoEC,EAAAe,EAAA,GAAA;AAAA,sBAAlD,OAAOtB,EAAA;AAAA,+DAAAA,EAAe,QAAAmB;AAAA,sBAAG,SAASlB,EAAA;AAAA,oBAAA;;;;gBAEtDsB,EAA0D,OAA1DC,IAA0DC,EAA/BlB,EAAA7D,CAAA,EAAC,mBAAA,CAAA,GAAA,CAAA;AAAA,cAAA;;;;;;QAKhC4D,EA4DWC,EAAAmB,EAAA,GAAA;AAAA,UA3DD,MAAMtC,EAAA;AAAA,kDAAAA,EAAU,QAAA+B;AAAA,UACvB,WAAW7D,EAAA,QAAM,WAAA;AAAA,UACjB,OAAOA,EAAA,QAAS,SAAS;AAAA,UACzB,QAAQA,EAAA,QAAM,SAAY;AAAA,UAC1B,wBAAqBA,EAAA,OAAM;AAAA,UAC3B,OAAKqE,GAAErE,EAAA,QAAM,qBAAwB,MAAS;AAAA,QAAA;qBAE/C,MAmDmB;AAAA,YAnDnBgD,EAmDmBC,EAAAqB,EAAA,GAAA;AAAA,cAnDA,OAAOrB,EAAA7D,CAAA,EAAC,eAAA;AAAA,cAAmB,UAAA;AAAA,cAAU,oBAAkBY,EAAA;AAAA,YAAA;yBACxE,MAiDW;AAAA,gBAjDK+B,EAAA,cAAhBwC,EAiDWC,GAAA,EAAA,KAAA,KAAA;AAAA,kBAhDTxB,EA4CiBC,EAAAwB,EAAA,GAAA;AAAA,oBA3Cf,mBAAgB;AAAA,oBACf,QAAQ;AAAA,oBACT,UAAA;AAAA,oBACA,MAAK;AAAA,oBACL,eAAY;AAAA,kBAAA;+BAEZ,MAEsB;AAAA,sBAFtBzB,EAEsBC,EAAAyB,CAAA,GAAA;AAAA,wBAFA,OAAOzB,EAAA7D,CAAA,EAAC,aAAA;AAAA,sBAAA;mCAC5B,MAAuB;AAAA,0BAApBuE,EAAAQ,EAAApC,EAAA,MAAU,OAAO,GAAA,CAAA;AAAA,wBAAA;;;sBAEtBiB,EAUsBC,EAAAyB,CAAA,GAAA;AAAA,wBAVA,OAAOzB,EAAA7D,CAAA,EAAC,kBAAA;AAAA,sBAAA;mCAC5B,MAQE;AAAA,0BAPAuE,EAAAQ,EAAApC,EAAA,MAAU,aAAakB,EAAAzC,CAAA,EAAY,SAAyByC,EAAA7D,CAAA,EAAC,wBAAA,IAA6C2C,EAAA,MAAU,aAAakB,EAAAzC,CAAA,EAAY,UAA4ByC,EAAA7D,CAAA,EAAC,0BAAA,IAAiD2C,EAAA,MAAU,aAAakB,EAAAzC,CAAA,EAAY,gBAAoCyC,EAAA7D,CAAA,EAAC,6BAAA,IAAsD6D,EAAA7D,CAAA,EAAC,0BAAA,CAAA,GAAA,CAAA;AAAA,wBAAA;;;sBAS9V4D,EAIsBC,EAAAyB,CAAA,GAAA;AAAA,wBAJA,OAAOzB,EAAA7D,CAAA,EAAC,mBAAA;AAAA,sBAAA;mCAC5B,MAEQ;AAAA,0BAFR4D,EAEQC,EAAA/B,CAAA,GAAA;AAAA,4BAFD,MAAK;AAAA,4BAAS,UAAU;AAAA,4BAAQ,MAAM+B,EAAA0B,EAAA,EAAiB5C,EAAA,MAAU,SAAS;AAAA,0BAAA;uCAC/E,MAAwC;AAAA,kCAArCG,EAAcH,EAAA,MAAU,SAAS,CAAA,GAAA,CAAA;AAAA,4BAAA;;;;;;sBAGxCiB,EAEsBC,EAAAyB,CAAA,GAAA;AAAA,wBAFA,OAAOzB,EAAA7D,CAAA,EAAC,uBAAA;AAAA,sBAAA;mCAC5B,MAA0C;AAAA,8BAAvC6D,EAAA2B,CAAA,EAAY7C,EAAA,MAAU,aAAa,CAAA,GAAA,CAAA;AAAA,wBAAA;;;sBAExCiB,EAEsBC,EAAAyB,CAAA,GAAA;AAAA,wBAFA,OAAOzB,EAAA7D,CAAA,EAAC,mBAAA;AAAA,sBAAA;mCAC5B,MAAsC;AAAA,8BAAnC6D,EAAA2B,CAAA,EAAY7C,EAAA,MAAU,SAAS,CAAA,GAAA,CAAA;AAAA,wBAAA;;;sBAEpCiB,EAEsBC,EAAAyB,CAAA,GAAA;AAAA,wBAFA,OAAOzB,EAAA7D,CAAA,EAAC,iBAAA;AAAA,sBAAA;mCAC5B,MAAoF;AAAA,0BAAjFuE,EAAAQ,EAAApC,EAAA,MAAU,WAAO,OAAWkB,KAAC,iBAAA,IAAA,GAAyBlB,EAAA,MAAU,SAAS,KAAA,GAAA,CAAA;AAAA,wBAAA;;;sBAE9EiB,EAEsBC,EAAAyB,CAAA,GAAA;AAAA,wBAFA,OAAOzB,EAAA7D,CAAA,EAAC,cAAA;AAAA,sBAAA;mCAC5B,MAA+B;AAAA,0BAA5BuE,EAAAQ,EAAApC,EAAA,MAAU,YAAQ,GAAA,GAAA,CAAA;AAAA,wBAAA;;;sBAEIA,EAAA,MAAU,oBAArC0B,EAEsBR,EAAAyB,CAAA,GAAA;AAAA;wBAF6B,OAAOzB,EAAA7D,CAAA,EAAC,iBAAA;AAAA,sBAAA;mCACzD,MAAyD;AAAA,0BAAzD6E,EAAyD,OAAzDY,IAAyDV,EAA9BpC,EAAA,MAAU,WAAW,GAAA,CAAA;AAAA,wBAAA;;;sBAEvBA,EAAA,MAAU,kBAArC0B,EAEsBR,EAAAyB,CAAA,GAAA;AAAA;wBAF2B,OAAOzB,EAAA7D,CAAA,EAAC,eAAA;AAAA,sBAAA;mCACvD,MAAiE;AAAA,0BAAjE6E,EAAiE,OAAjEa,IAAiEX,EAA5BpC,EAAA,MAAU,SAAS,GAAA,CAAA;AAAA,wBAAA;;;;;;kBAI5DkC,EAA6D,OAA7Dc,IAA6DZ,EAA9BlB,EAAA7D,CAAA,EAAC,kBAAA,CAAA,GAAA,CAAA;AAAA,kBAChC4D,EAA4DgC,IAAA;AAAA,oBAA7C,MAAMhD,EAAA;AAAA,oBAAW,SAASC,EAAA;AAAA,kBAAA;;;;;;;;;;;;"}
@@ -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-4d98120b"]]);
4
+ const m = /* @__PURE__ */ t(o, [["__scopeId", "data-v-c532e04a"]]);
5
5
  export {
6
- _ as default
6
+ m as default
7
7
  };
8
8
  //# sourceMappingURL=index.vue.js.map
@@ -1,19 +1,19 @@
1
- import { defineComponent as z, computed as u, ref as j, onMounted as J, onActivated as V, onDeactivated as G, onUnmounted as U, openBlock as g, createElementBlock as _, normalizeClass as b, createElementVNode as l, normalizeStyle as y, Fragment as W, renderList as q, createBlock as K, unref as r, withCtx as p, createVNode as c, toDisplayString as T, h as N } from "vue";
1
+ import { defineComponent as J, computed as u, ref as j, onMounted as V, onActivated as W, onDeactivated as G, onUnmounted as U, openBlock as g, createElementBlock as _, normalizeClass as b, createElementVNode as l, normalizeStyle as y, Fragment as Y, renderList as q, createBlock as K, unref as r, withCtx as p, createVNode as c, toDisplayString as T, h as N } from "vue";
2
2
  import { useMessage as P, NCard as A, NSpin as Q, NTag as X } from "naive-ui";
3
3
  import { SmartTable as C } from "smart-naive-table";
4
- import { Icon as Y } from "@iconify/vue";
5
- import { useShellBreakpoint as Z } from "../../../composables/useShellBreakpoint.js";
6
- import { useI18n as ee } from "vue-i18n";
7
- import te from "../../../components/Chart/index.vue.js";
8
- import { jobApi as oe } from "../../../api/index.js";
9
- import { translateError as ae } from "../../../utils/error.js";
10
- import { fmtDateTime as ne } from "../../../utils/format.js";
11
- import { TABLE_MIN_ROW_HEIGHT as I, TABLE_TOOLBAR as S } from "../../../utils/tableToolbar.js";
12
- import B from "../../../components/TableTotal/index.vue.js";
13
- const re = { class: "stat" }, ie = { class: "stat-val tabular" }, le = { class: "stat-label" }, ke = /* @__PURE__ */ z({
4
+ import { Icon as Z } from "@iconify/vue";
5
+ import { useShellBreakpoint as ee } from "../../../composables/useShellBreakpoint.js";
6
+ import { useI18n as te } from "vue-i18n";
7
+ import oe from "../../../components/Chart/index.vue.js";
8
+ import { jobApi as ae } from "../../../api/index.js";
9
+ import { translateError as ne } from "../../../utils/error.js";
10
+ import { fmtDateTime as re } from "../../../utils/format.js";
11
+ import { TABLE_MIN_ROW_HEIGHT as S, TABLE_TOOLBAR as I } from "../../../utils/tableToolbar.js";
12
+ import L from "../../../components/TableTotal/index.vue.js";
13
+ const ie = { class: "stat" }, le = { class: "stat-val tabular" }, se = { class: "stat-label" }, xe = /* @__PURE__ */ J({
14
14
  __name: "index",
15
- setup(se) {
16
- const { t } = ee(), L = P(), { bp: M, width: h } = Z(), i = u(() => M.value === "narrow"), E = u(() => h.value < 520 ? 1 : h.value < 1e3 ? 2 : 4), H = u(() => {
15
+ setup(ce) {
16
+ const { t } = te(), B = P(), { bp: E, width: h } = ee(), i = u(() => E.value === "narrow"), R = u(() => h.value < 520 ? 1 : h.value < 1e3 ? 2 : 4), M = { gridTemplateColumns: "minmax(0, 1fr)" }, H = u(() => {
17
17
  const e = h.value < 1e3, a = e ? 488 : 240;
18
18
  return {
19
19
  flex: `1 1 ${a}px`,
@@ -24,25 +24,25 @@ const re = { class: "stat" }, ie = { class: "stat-val tabular" }, le = { class:
24
24
  }), s = j(null), f = j(!0);
25
25
  async function w(e = !0) {
26
26
  try {
27
- s.value = await oe.dashboard();
27
+ s.value = await ae.dashboard();
28
28
  } catch (a) {
29
- e || L.error(ae(a));
29
+ e || B.error(ne(a));
30
30
  } finally {
31
31
  f.value = !1;
32
32
  }
33
33
  }
34
- let d = null;
34
+ let m = null;
35
35
  function k() {
36
- d == null && (d = window.setInterval(() => void w(), 15e3));
36
+ m == null && (m = window.setInterval(() => void w(), 15e3));
37
37
  }
38
38
  function x() {
39
- d != null && (window.clearInterval(d), d = null);
39
+ m != null && (window.clearInterval(m), m = null);
40
40
  }
41
- J(() => {
41
+ V(() => {
42
42
  w(!1), k();
43
- }), V(k), G(x), U(x);
44
- const v = (e) => e === void 0 ? "—" : e, R = u(() => {
45
- var e, a, o, m;
43
+ }), W(k), G(x), U(x);
44
+ const v = (e) => e === void 0 ? "—" : e, $ = u(() => {
45
+ var e, a, o, d;
46
46
  return [
47
47
  {
48
48
  key: "todaySuccess",
@@ -65,11 +65,11 @@ const re = { class: "stat" }, ie = { class: "stat-val tabular" }, le = { class:
65
65
  {
66
66
  key: "totalJobs",
67
67
  icon: "ph:clock-countdown",
68
- value: v((m = s.value) == null ? void 0 : m.totalJobs),
68
+ value: v((d = s.value) == null ? void 0 : d.totalJobs),
69
69
  color: "var(--signal)"
70
70
  }
71
71
  ];
72
- }), $ = u(() => {
72
+ }), D = u(() => {
73
73
  var a;
74
74
  const e = ((a = s.value) == null ? void 0 : a.trend) ?? [];
75
75
  return {
@@ -92,7 +92,7 @@ const re = { class: "stat" }, ie = { class: "stat-val tabular" }, le = { class:
92
92
  ]
93
93
  };
94
94
  });
95
- function D(e) {
95
+ function O(e) {
96
96
  const a = Math.max(0, Date.now() - new Date(e).getTime()), o = Math.floor(a / 1e3);
97
97
  return o < 10 ? t("job.monitor.justNow") : o < 60 ? t("job.monitor.secondsAgo", { n: o }) : o < 3600 ? t("job.monitor.minutesAgo", { n: Math.floor(o / 60) }) : t("job.monitor.hoursAgo", { n: Math.floor(o / 3600) });
98
98
  }
@@ -109,9 +109,9 @@ const re = { class: "stat" }, ie = { class: "stat-val tabular" }, le = { class:
109
109
  title: () => t("job.monitor.upcomingTime"),
110
110
  key: "nextRunTime",
111
111
  width: 170,
112
- render: (e) => N("span", { class: "tabular" }, ne(e.nextRunTime, { empty: "—" }))
112
+ render: (e) => N("span", { class: "tabular" }, re(e.nextRunTime, { empty: "—" }))
113
113
  }
114
- ], O = [
114
+ ], z = [
115
115
  { type: "index", title: () => t("common.rowNo"), width: 64, align: "center" },
116
116
  {
117
117
  title: () => t("job.monitor.nodeName"),
@@ -133,40 +133,40 @@ const re = { class: "stat" }, ie = { class: "stat-val tabular" }, le = { class:
133
133
  title: () => t("job.monitor.lastHeartbeat"),
134
134
  key: "lastHeartbeat",
135
135
  width: 110,
136
- render: (e) => D(e.lastHeartbeat)
136
+ render: (e) => O(e.lastHeartbeat)
137
137
  },
138
138
  { title: () => t("job.monitor.workerId"), key: "workerId", width: 90, align: "center" },
139
139
  { title: () => t("job.monitor.pid"), key: "pid", width: 90, align: "center" }
140
140
  ];
141
141
  return (e, a) => {
142
- var o, m;
142
+ var o, d;
143
143
  return g(), _("div", {
144
144
  class: b(["view", { "fill-page fill-page--soft": !i.value }])
145
145
  }, [
146
146
  l("div", {
147
147
  class: "stats",
148
- style: y({ gridTemplateColumns: `repeat(${E.value}, minmax(0, 1fr))` })
148
+ style: y({ gridTemplateColumns: `repeat(${R.value}, minmax(0, 1fr))` })
149
149
  }, [
150
- (g(!0), _(W, null, q(R.value, (n) => (g(), K(r(A), {
150
+ (g(!0), _(Y, null, q($.value, (n) => (g(), K(r(A), {
151
151
  key: n.key,
152
152
  bordered: !0,
153
153
  class: "a-card",
154
154
  "content-style": "padding: 14px 16px"
155
155
  }, {
156
156
  default: p(() => [
157
- l("div", re, [
157
+ l("div", ie, [
158
158
  l("div", {
159
159
  class: "stat-ico",
160
160
  style: y({ color: n.color })
161
161
  }, [
162
- c(r(Y), {
162
+ c(r(Z), {
163
163
  icon: n.icon,
164
164
  width: 28
165
165
  }, null, 8, ["icon"])
166
166
  ], 4),
167
167
  l("div", null, [
168
- l("div", ie, T(n.value), 1),
169
- l("div", le, T(r(t)(`job.monitor.${n.key}`)), 1)
168
+ l("div", le, T(n.value), 1),
169
+ l("div", se, T(r(t)(`job.monitor.${n.key}`)), 1)
170
170
  ])
171
171
  ])
172
172
  ]),
@@ -181,7 +181,7 @@ const re = { class: "stat" }, ie = { class: "stat-val tabular" }, le = { class:
181
181
  default: p(() => [
182
182
  c(r(Q), { show: f.value }, {
183
183
  default: p(() => [
184
- c(te, { option: $.value }, null, 8, ["option"])
184
+ c(oe, { option: D.value }, null, 8, ["option"])
185
185
  ]),
186
186
  _: 1
187
187
  }, 8, ["show"])
@@ -190,7 +190,7 @@ const re = { class: "stat" }, ie = { class: "stat-val tabular" }, le = { class:
190
190
  }, 8, ["title"]),
191
191
  l("div", {
192
192
  class: b(["job-tables", { "fill-main": !i.value }]),
193
- style: y(i.value ? void 0 : H.value)
193
+ style: y(i.value ? M : H.value)
194
194
  }, [
195
195
  l("div", {
196
196
  class: b(["job-table", { "fill-main": !i.value }])
@@ -201,14 +201,14 @@ const re = { class: "stat" }, ie = { class: "stat-val tabular" }, le = { class:
201
201
  "row-key": (n) => `${n.jobId}-${n.nextRunTime}`,
202
202
  loading: f.value,
203
203
  search: { container: "table" },
204
- toolbar: r(S),
204
+ toolbar: r(I),
205
205
  "fill-height": !i.value,
206
- "min-row-height": r(I),
206
+ "min-row-height": r(S),
207
207
  "card-on-narrow": i.value,
208
208
  "storage-key": "sys-job-monitor-upcoming"
209
209
  }, {
210
210
  "pagination-prefix": p(({ itemCount: n }) => [
211
- c(B, { count: n }, null, 8, ["count"])
211
+ c(L, { count: n }, null, 8, ["count"])
212
212
  ]),
213
213
  _: 1
214
214
  }, 8, ["data", "row-key", "loading", "toolbar", "fill-height", "min-row-height", "card-on-narrow"])
@@ -217,19 +217,19 @@ const re = { class: "stat" }, ie = { class: "stat-val tabular" }, le = { class:
217
217
  class: b(["job-table", { "fill-main": !i.value }])
218
218
  }, [
219
219
  c(r(C), {
220
- columns: O,
221
- data: ((m = s.value) == null ? void 0 : m.nodes) ?? [],
220
+ columns: z,
221
+ data: ((d = s.value) == null ? void 0 : d.nodes) ?? [],
222
222
  "row-key": "nodeName",
223
223
  loading: f.value,
224
224
  search: { container: "table" },
225
- toolbar: r(S),
225
+ toolbar: r(I),
226
226
  "fill-height": !i.value,
227
- "min-row-height": r(I),
227
+ "min-row-height": r(S),
228
228
  "card-on-narrow": i.value,
229
229
  "storage-key": "sys-job-monitor-nodes"
230
230
  }, {
231
231
  "pagination-prefix": p(({ itemCount: n }) => [
232
- c(B, { count: n }, null, 8, ["count"])
232
+ c(L, { count: n }, null, 8, ["count"])
233
233
  ]),
234
234
  _: 1
235
235
  }, 8, ["data", "loading", "toolbar", "fill-height", "min-row-height", "card-on-narrow"])
@@ -240,6 +240,6 @@ const re = { class: "stat" }, ie = { class: "stat-val tabular" }, le = { class:
240
240
  }
241
241
  });
242
242
  export {
243
- ke as default
243
+ xe as default
244
244
  };
245
245
  //# sourceMappingURL=index2.vue.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index2.vue.js","sources":["../../../../src/views/system/job-monitor/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 任务监控 = 4 张 stat 卡 + 近 14 日成败趋势 + 即将执行 + 集群节点,整页吃一个 dashboard 端点。\n// 15 秒轮询:页面被 keep-alive,切走的标签没必要继续打点 → onDeactivated 也要停,回来再启;\n// onUnmounted 兜底清定时器,防组件销毁后计时器泄漏还在发请求。\nimport { computed, h, onActivated, onDeactivated, onMounted, onUnmounted, ref } from 'vue'\nimport { NCard, NSpin, NTag, useMessage } from 'naive-ui'\nimport { SmartTable, type SmartTableColumn } from 'smart-naive-table'\nimport { Icon } from '@iconify/vue'\nimport { useShellBreakpoint } from '#/composables/useShellBreakpoint'\nimport { useI18n } from 'vue-i18n'\nimport BaseChart from '#/components/Chart/index.vue'\nimport type { EChartsOption } from 'echarts'\nimport { jobApi } from '#/api'\nimport { translateError } from '#/utils/error'\nimport { fmtDateTime } from '#/utils/format'\nimport { TABLE_MIN_ROW_HEIGHT, TABLE_TOOLBAR } from '#/utils/tableToolbar'\nimport TableTotal from '#/components/TableTotal/index.vue'\nimport type { JobDashboard, JobNodeItem, JobUpcomingItem } from '#/types/api'\n\nconst { t } = useI18n()\nconst message = useMessage()\n\n// 栅格按内容区宽度分档(不是视口)\nconst { bp, width: pw } = useShellBreakpoint()\nconst narrow = computed(() => bp.value === 'narrow')\nconst statCols = computed(() => (pw.value < 520 ? 1 : pw.value < 1000 ? 2 : 4))\nconst tablesStyle = computed(() => {\n const stacked = pw.value < 1000\n const basis = stacked ? 488 : 240\n return {\n flex: `1 1 ${basis}px`,\n minHeight: `${basis}px`,\n gridTemplateColumns: stacked ? 'minmax(0, 1fr)' : 'repeat(2, minmax(0, 1fr))',\n gridTemplateRows: stacked ? 'repeat(2, minmax(0, 1fr))' : 'minmax(0, 1fr)',\n }\n})\n\nconst data = ref<JobDashboard | null>(null)\nconst loading = ref(true)\n\nasync function load(silent = true) {\n try {\n data.value = await jobApi.dashboard()\n } catch (e) {\n // 首次失败要让用户知道;轮询失败静默(网络抖一下不必每 15 秒糊一脸红)\n if (!silent) message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n\nlet timer: number | null = null\nfunction start() {\n if (timer != null) return\n timer = window.setInterval(() => void load(), 15_000)\n}\nfunction stop() {\n if (timer != null) {\n window.clearInterval(timer)\n timer = null\n }\n}\nonMounted(() => {\n void load(false)\n start()\n})\nonActivated(start)\nonDeactivated(stop)\nonUnmounted(stop)\n\n/** 计数未到位时显示 —,而不是先闪个 0。 */\nconst num = (v: number | undefined) => (v === undefined ? '—' : v)\nconst stats = computed(() => [\n {\n key: 'todaySuccess',\n icon: 'ph:check-circle',\n value: num(data.value?.todaySuccess),\n color: 'var(--ok)',\n },\n {\n key: 'todayFailed',\n icon: 'ph:x-circle',\n value: num(data.value?.todayFailed),\n color: 'var(--err)',\n },\n {\n key: 'running',\n icon: 'ph:circle-notch',\n value: num(data.value?.running),\n color: 'var(--color-info)',\n },\n {\n key: 'totalJobs',\n icon: 'ph:clock-countdown',\n value: num(data.value?.totalJobs),\n color: 'var(--signal)',\n },\n])\n\n// 柱线组合:成功是当日总量,用柱;失败通常小一个量级,压在柱上会看不见,用线单独描出来。\nconst trendOption = computed<EChartsOption>(() => {\n const trend = data.value?.trend ?? []\n return {\n tooltip: { trigger: 'axis' },\n // 图例位置写死在顶部:留给默认值时它会落到绘图区底部、压在 x 轴日期标签上。\n // grid.top 的 32 就是给它留的位置。\n legend: { top: 0 },\n grid: { left: 8, right: 16, bottom: 8, top: 32, containLabel: true },\n xAxis: { type: 'category', data: trend.map(p => p.date.slice(5)) }, // MM-dd 足够,14 天跨年概率忽略\n yAxis: { type: 'value', minInterval: 1 },\n series: [\n { name: t('job.monitor.trendSuccess'), type: 'bar', data: trend.map(p => p.success) },\n {\n name: t('job.monitor.trendFailed'),\n type: 'line',\n smooth: true,\n data: trend.map(p => p.failed),\n },\n ],\n }\n})\n\n/** 最后心跳的相对时间(轮询 15 秒一刷,精确到秒/分/时够用)。 */\nfunction relative(iso: string): string {\n const diff = Math.max(0, Date.now() - new Date(iso).getTime())\n const sec = Math.floor(diff / 1000)\n if (sec < 10) return t('job.monitor.justNow')\n if (sec < 60) return t('job.monitor.secondsAgo', { n: sec })\n if (sec < 3600) return t('job.monitor.minutesAgo', { n: Math.floor(sec / 60) })\n return t('job.monitor.hoursAgo', { n: Math.floor(sec / 3600) })\n}\n\nconst upcomingColumns: SmartTableColumn<JobUpcomingItem>[] = [\n { type: 'index', title: () => t('common.rowNo'), width: 64, align: 'center' },\n {\n title: () => t('job.monitor.upcomingJob'),\n key: 'name',\n ellipsis: { tooltip: true },\n search: {}, // 静态数据:条件由 SmartTable 前端求值\n },\n {\n title: () => t('job.monitor.upcomingTime'),\n key: 'nextRunTime',\n width: 170,\n render: r => h('span', { class: 'tabular' }, fmtDateTime(r.nextRunTime, { empty: '—' })),\n },\n]\n\nconst nodeColumns: SmartTableColumn<JobNodeItem>[] = [\n { type: 'index', title: () => t('common.rowNo'), width: 64, align: 'center' },\n {\n title: () => t('job.monitor.nodeName'),\n key: 'nodeName',\n ellipsis: { tooltip: true },\n search: {},\n },\n {\n title: () => t('job.monitor.role'),\n key: 'isLeader',\n width: 90,\n render: r =>\n h(NTag, { size: 'small', bordered: false, type: r.isLeader ? 'primary' : 'default' }, () =>\n t(r.isLeader ? 'job.monitor.leader' : 'job.monitor.standby'),\n ),\n },\n {\n title: () => t('job.monitor.lastHeartbeat'),\n key: 'lastHeartbeat',\n width: 110,\n render: r => relative(r.lastHeartbeat),\n },\n { title: () => t('job.monitor.workerId'), key: 'workerId', width: 90, align: 'center' },\n { title: () => t('job.monitor.pid'), key: 'pid', width: 90, align: 'center' },\n]\n</script>\n\n<template>\n <!-- 窄档(内容区 < 600)整页自然滚动,不锁一屏;表格换成卡片列表 -->\n <div class=\"view\" :class=\"{ 'fill-page fill-page--soft': !narrow }\">\n <!-- 统计卡按内容区宽度分档:< 520 一列,< 1000 两列,否则四列 -->\n <div class=\"stats\" :style=\"{ gridTemplateColumns: `repeat(${statCols}, minmax(0, 1fr))` }\">\n <n-card\n v-for=\"s in stats\"\n :key=\"s.key\"\n :bordered=\"true\"\n class=\"a-card\"\n content-style=\"padding: 14px 16px\"\n >\n <div class=\"stat\">\n <div class=\"stat-ico\" :style=\"{ color: s.color }\">\n <Icon :icon=\"s.icon\" :width=\"28\" />\n </div>\n <div>\n <div class=\"stat-val tabular\">{{ s.value }}</div>\n <div class=\"stat-label\">{{ t(`job.monitor.${s.key}`) }}</div>\n </div>\n </div>\n </n-card>\n </div>\n\n <n-card :title=\"t('job.monitor.trendTitle')\" :bordered=\"true\" class=\"a-card\">\n <n-spin :show=\"loading\">\n <BaseChart :option=\"trendOption\" />\n </n-spin>\n </n-card>\n\n <!-- 统计条与趋势图按内容定高(.fill-page > * 已是 flex-shrink:0),\n 底部这一栏吃掉剩余高度,两张表各自在卡片里滚。\n 这页是仪表盘不是列表页:统计条 + 320px 趋势图不参与瓜分,1080p 上给两张表还剩 200 来 px,\n 768p 上就只剩一条缝了 —— 所以外壳叠 .fill-page--soft,再给这一栏一个下限(内容区 < 1000 时两张表\n 上下排,下限 488 = 每张 240 + 间距;>= 1000 并排,下限 240)。 -->\n <div\n class=\"job-tables\"\n :class=\"{ 'fill-main': !narrow }\"\n :style=\"narrow ? undefined : tablesStyle\"\n >\n <!-- 两张表都是 SmartTable 静态数据模式;不放表名(设计:表格工具栏没有标题),列头已能分辨。\n 窄档(内容区 < 600)整页自然滚动,卡片列表由 card-on-narrow 内置。\n card-on-narrow 跟页面窄档走而不是让库按表格自身宽度判:宽屏下两张表并排各约半宽,会被误判成窄 -->\n <div class=\"job-table\" :class=\"{ 'fill-main': !narrow }\">\n <SmartTable\n :columns=\"upcomingColumns\"\n :data=\"data?.upcoming ?? []\"\n :row-key=\"(r: JobUpcomingItem) => `${r.jobId}-${r.nextRunTime}`\"\n :loading=\"loading\"\n :search=\"{ container: 'table' }\"\n :toolbar=\"TABLE_TOOLBAR\"\n :fill-height=\"!narrow\"\n :min-row-height=\"TABLE_MIN_ROW_HEIGHT\"\n :card-on-narrow=\"narrow\"\n storage-key=\"sys-job-monitor-upcoming\"\n >\n <template #pagination-prefix=\"{ itemCount }\">\n <TableTotal :count=\"itemCount\" />\n </template>\n </SmartTable>\n </div>\n <div class=\"job-table\" :class=\"{ 'fill-main': !narrow }\">\n <SmartTable\n :columns=\"nodeColumns\"\n :data=\"data?.nodes ?? []\"\n row-key=\"nodeName\"\n :loading=\"loading\"\n :search=\"{ container: 'table' }\"\n :toolbar=\"TABLE_TOOLBAR\"\n :fill-height=\"!narrow\"\n :min-row-height=\"TABLE_MIN_ROW_HEIGHT\"\n :card-on-narrow=\"narrow\"\n storage-key=\"sys-job-monitor-nodes\"\n >\n <template #pagination-prefix=\"{ itemCount }\">\n <TableTotal :count=\"itemCount\" />\n </template>\n </SmartTable>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n/* display / flex-direction / 整屏高度链都在 styles/layout.css 的 .fill-page,这里只留卡片间距。 */\n.view {\n gap: var(--gap-card);\n}\n\n/*\n * .fill-page--soft 把「恰好一屏」放宽成「至少一屏」,这里再给两张表所在的那一栏一个下限:\n * 卡片头尾约 62px + small 表头 34px + 4 行 x 34px ≈ 240px,少于这个就不叫表了。\n * 高屏上剩余高度本来就大于下限,页面仍然恰好一屏;矮屏上顶到下限后由 .page 正常出滚动条。\n * 容器和栅格项都要给:容器是 flex 子项(.fill-main 带 min-height:0,不设下限会被压过内容),\n * 栅格项则决定单列(l 断点以下两张表上下排)时每张表各自的下限。\n */\n.stats {\n display: grid;\n gap: var(--gap-card);\n flex-shrink: 0;\n}\n.job-tables {\n display: grid;\n gap: var(--gap-card);\n}\n.stat {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n/* 图标底盘:取语义色 12% 作浅底,同工作台手法,避免图标\"裸浮\" */\n.stat-ico {\n flex-shrink: 0;\n width: 48px;\n height: 48px;\n border-radius: var(--radius-lg);\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, currentColor 12%, transparent);\n}\n.stat-val {\n font-size: 28px;\n font-weight: 600;\n letter-spacing: -0.04em;\n color: var(--text-1);\n line-height: 34px;\n}\n.stat-label {\n font-size: 14px;\n color: var(--text-2);\n}\n</style>\n"],"names":["useI18n","message","useMessage","bp","pw","useShellBreakpoint","narrow","computed","statCols","tablesStyle","stacked","basis","data","ref","loading","load","silent","jobApi","e","translateError","timer","start","stop","onMounted","onActivated","onDeactivated","onUnmounted","num","v","stats","_a","_b","_c","_d","trendOption","trend","p","relative","iso","diff","sec","upcomingColumns","r","h","fmtDateTime","nodeColumns","NTag","_createElementBlock","_normalizeClass","_createElementVNode","_Fragment","_renderList","s","_createBlock","_unref","NCard","_hoisted_1","_normalizeStyle","_createVNode","Icon","_hoisted_2","_toDisplayString","_hoisted_3","NSpin","BaseChart","SmartTable","TABLE_TOOLBAR","TABLE_MIN_ROW_HEIGHT","_withCtx","itemCount","TableTotal"],"mappings":"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"}
1
+ {"version":3,"file":"index2.vue.js","sources":["../../../../src/views/system/job-monitor/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 任务监控 = 4 张 stat 卡 + 近 14 日成败趋势 + 即将执行 + 集群节点,整页吃一个 dashboard 端点。\n// 15 秒轮询:页面被 keep-alive,切走的标签没必要继续打点 → onDeactivated 也要停,回来再启;\n// onUnmounted 兜底清定时器,防组件销毁后计时器泄漏还在发请求。\nimport { computed, h, onActivated, onDeactivated, onMounted, onUnmounted, ref } from 'vue'\nimport { NCard, NSpin, NTag, useMessage } from 'naive-ui'\nimport { SmartTable, type SmartTableColumn } from 'smart-naive-table'\nimport { Icon } from '@iconify/vue'\nimport { useShellBreakpoint } from '#/composables/useShellBreakpoint'\nimport { useI18n } from 'vue-i18n'\nimport BaseChart from '#/components/Chart/index.vue'\nimport type { EChartsOption } from 'echarts'\nimport { jobApi } from '#/api'\nimport { translateError } from '#/utils/error'\nimport { fmtDateTime } from '#/utils/format'\nimport { TABLE_MIN_ROW_HEIGHT, TABLE_TOOLBAR } from '#/utils/tableToolbar'\nimport TableTotal from '#/components/TableTotal/index.vue'\nimport type { JobDashboard, JobNodeItem, JobUpcomingItem } from '#/types/api'\n\nconst { t } = useI18n()\nconst message = useMessage()\n\n// 栅格按内容区宽度分档(不是视口)\nconst { bp, width: pw } = useShellBreakpoint()\nconst narrow = computed(() => bp.value === 'narrow')\nconst statCols = computed(() => (pw.value < 520 ? 1 : pw.value < 1000 ? 2 : 4))\n// 窄档必须显式给单列:网格默认的 auto 列会被表格的最小内容宽撑到 600,而库判卡片的条件是表格根宽 < 600,\n// 于是表格永远不换成卡片、页面横向溢出,还自己维持住这个状态。\nconst NARROW_TABLES_STYLE = { gridTemplateColumns: 'minmax(0, 1fr)' }\nconst tablesStyle = computed(() => {\n const stacked = pw.value < 1000\n const basis = stacked ? 488 : 240\n return {\n flex: `1 1 ${basis}px`,\n minHeight: `${basis}px`,\n gridTemplateColumns: stacked ? 'minmax(0, 1fr)' : 'repeat(2, minmax(0, 1fr))',\n gridTemplateRows: stacked ? 'repeat(2, minmax(0, 1fr))' : 'minmax(0, 1fr)',\n }\n})\n\nconst data = ref<JobDashboard | null>(null)\nconst loading = ref(true)\n\nasync function load(silent = true) {\n try {\n data.value = await jobApi.dashboard()\n } catch (e) {\n // 首次失败要让用户知道;轮询失败静默(网络抖一下不必每 15 秒糊一脸红)\n if (!silent) message.error(translateError(e))\n } finally {\n loading.value = false\n }\n}\n\nlet timer: number | null = null\nfunction start() {\n if (timer != null) return\n timer = window.setInterval(() => void load(), 15_000)\n}\nfunction stop() {\n if (timer != null) {\n window.clearInterval(timer)\n timer = null\n }\n}\nonMounted(() => {\n void load(false)\n start()\n})\nonActivated(start)\nonDeactivated(stop)\nonUnmounted(stop)\n\n/** 计数未到位时显示 —,而不是先闪个 0。 */\nconst num = (v: number | undefined) => (v === undefined ? '—' : v)\nconst stats = computed(() => [\n {\n key: 'todaySuccess',\n icon: 'ph:check-circle',\n value: num(data.value?.todaySuccess),\n color: 'var(--ok)',\n },\n {\n key: 'todayFailed',\n icon: 'ph:x-circle',\n value: num(data.value?.todayFailed),\n color: 'var(--err)',\n },\n {\n key: 'running',\n icon: 'ph:circle-notch',\n value: num(data.value?.running),\n color: 'var(--color-info)',\n },\n {\n key: 'totalJobs',\n icon: 'ph:clock-countdown',\n value: num(data.value?.totalJobs),\n color: 'var(--signal)',\n },\n])\n\n// 柱线组合:成功是当日总量,用柱;失败通常小一个量级,压在柱上会看不见,用线单独描出来。\nconst trendOption = computed<EChartsOption>(() => {\n const trend = data.value?.trend ?? []\n return {\n tooltip: { trigger: 'axis' },\n // 图例位置写死在顶部:留给默认值时它会落到绘图区底部、压在 x 轴日期标签上。\n // grid.top 的 32 就是给它留的位置。\n legend: { top: 0 },\n grid: { left: 8, right: 16, bottom: 8, top: 32, containLabel: true },\n xAxis: { type: 'category', data: trend.map(p => p.date.slice(5)) }, // MM-dd 足够,14 天跨年概率忽略\n yAxis: { type: 'value', minInterval: 1 },\n series: [\n { name: t('job.monitor.trendSuccess'), type: 'bar', data: trend.map(p => p.success) },\n {\n name: t('job.monitor.trendFailed'),\n type: 'line',\n smooth: true,\n data: trend.map(p => p.failed),\n },\n ],\n }\n})\n\n/** 最后心跳的相对时间(轮询 15 秒一刷,精确到秒/分/时够用)。 */\nfunction relative(iso: string): string {\n const diff = Math.max(0, Date.now() - new Date(iso).getTime())\n const sec = Math.floor(diff / 1000)\n if (sec < 10) return t('job.monitor.justNow')\n if (sec < 60) return t('job.monitor.secondsAgo', { n: sec })\n if (sec < 3600) return t('job.monitor.minutesAgo', { n: Math.floor(sec / 60) })\n return t('job.monitor.hoursAgo', { n: Math.floor(sec / 3600) })\n}\n\nconst upcomingColumns: SmartTableColumn<JobUpcomingItem>[] = [\n { type: 'index', title: () => t('common.rowNo'), width: 64, align: 'center' },\n {\n title: () => t('job.monitor.upcomingJob'),\n key: 'name',\n ellipsis: { tooltip: true },\n search: {}, // 静态数据:条件由 SmartTable 前端求值\n },\n {\n title: () => t('job.monitor.upcomingTime'),\n key: 'nextRunTime',\n width: 170,\n render: r => h('span', { class: 'tabular' }, fmtDateTime(r.nextRunTime, { empty: '—' })),\n },\n]\n\nconst nodeColumns: SmartTableColumn<JobNodeItem>[] = [\n { type: 'index', title: () => t('common.rowNo'), width: 64, align: 'center' },\n {\n title: () => t('job.monitor.nodeName'),\n key: 'nodeName',\n ellipsis: { tooltip: true },\n search: {},\n },\n {\n title: () => t('job.monitor.role'),\n key: 'isLeader',\n width: 90,\n render: r =>\n h(NTag, { size: 'small', bordered: false, type: r.isLeader ? 'primary' : 'default' }, () =>\n t(r.isLeader ? 'job.monitor.leader' : 'job.monitor.standby'),\n ),\n },\n {\n title: () => t('job.monitor.lastHeartbeat'),\n key: 'lastHeartbeat',\n width: 110,\n render: r => relative(r.lastHeartbeat),\n },\n { title: () => t('job.monitor.workerId'), key: 'workerId', width: 90, align: 'center' },\n { title: () => t('job.monitor.pid'), key: 'pid', width: 90, align: 'center' },\n]\n</script>\n\n<template>\n <!-- 窄档(内容区 < 600)整页自然滚动,不锁一屏;表格换成卡片列表 -->\n <div class=\"view\" :class=\"{ 'fill-page fill-page--soft': !narrow }\">\n <!-- 统计卡按内容区宽度分档:< 520 一列,< 1000 两列,否则四列 -->\n <div class=\"stats\" :style=\"{ gridTemplateColumns: `repeat(${statCols}, minmax(0, 1fr))` }\">\n <n-card\n v-for=\"s in stats\"\n :key=\"s.key\"\n :bordered=\"true\"\n class=\"a-card\"\n content-style=\"padding: 14px 16px\"\n >\n <div class=\"stat\">\n <div class=\"stat-ico\" :style=\"{ color: s.color }\">\n <Icon :icon=\"s.icon\" :width=\"28\" />\n </div>\n <div>\n <div class=\"stat-val tabular\">{{ s.value }}</div>\n <div class=\"stat-label\">{{ t(`job.monitor.${s.key}`) }}</div>\n </div>\n </div>\n </n-card>\n </div>\n\n <n-card :title=\"t('job.monitor.trendTitle')\" :bordered=\"true\" class=\"a-card\">\n <n-spin :show=\"loading\">\n <BaseChart :option=\"trendOption\" />\n </n-spin>\n </n-card>\n\n <!-- 统计条与趋势图按内容定高(.fill-page > * 已是 flex-shrink:0),\n 底部这一栏吃掉剩余高度,两张表各自在卡片里滚。\n 这页是仪表盘不是列表页:统计条 + 320px 趋势图不参与瓜分,1080p 上给两张表还剩 200 来 px,\n 768p 上就只剩一条缝了 —— 所以外壳叠 .fill-page--soft,再给这一栏一个下限(内容区 < 1000 时两张表\n 上下排,下限 488 = 每张 240 + 间距;>= 1000 并排,下限 240)。 -->\n <div\n class=\"job-tables\"\n :class=\"{ 'fill-main': !narrow }\"\n :style=\"narrow ? NARROW_TABLES_STYLE : tablesStyle\"\n >\n <!-- 两张表都是 SmartTable 静态数据模式;不放表名(设计:表格工具栏没有标题),列头已能分辨。\n 窄档(内容区 < 600)整页自然滚动,卡片列表由 card-on-narrow 内置。\n card-on-narrow 跟页面窄档走而不是让库按表格自身宽度判:宽屏下两张表并排各约半宽,会被误判成窄 -->\n <div class=\"job-table\" :class=\"{ 'fill-main': !narrow }\">\n <SmartTable\n :columns=\"upcomingColumns\"\n :data=\"data?.upcoming ?? []\"\n :row-key=\"(r: JobUpcomingItem) => `${r.jobId}-${r.nextRunTime}`\"\n :loading=\"loading\"\n :search=\"{ container: 'table' }\"\n :toolbar=\"TABLE_TOOLBAR\"\n :fill-height=\"!narrow\"\n :min-row-height=\"TABLE_MIN_ROW_HEIGHT\"\n :card-on-narrow=\"narrow\"\n storage-key=\"sys-job-monitor-upcoming\"\n >\n <template #pagination-prefix=\"{ itemCount }\">\n <TableTotal :count=\"itemCount\" />\n </template>\n </SmartTable>\n </div>\n <div class=\"job-table\" :class=\"{ 'fill-main': !narrow }\">\n <SmartTable\n :columns=\"nodeColumns\"\n :data=\"data?.nodes ?? []\"\n row-key=\"nodeName\"\n :loading=\"loading\"\n :search=\"{ container: 'table' }\"\n :toolbar=\"TABLE_TOOLBAR\"\n :fill-height=\"!narrow\"\n :min-row-height=\"TABLE_MIN_ROW_HEIGHT\"\n :card-on-narrow=\"narrow\"\n storage-key=\"sys-job-monitor-nodes\"\n >\n <template #pagination-prefix=\"{ itemCount }\">\n <TableTotal :count=\"itemCount\" />\n </template>\n </SmartTable>\n </div>\n </div>\n </div>\n</template>\n\n<style scoped>\n/* display / flex-direction / 整屏高度链都在 styles/layout.css 的 .fill-page,这里只留卡片间距。 */\n.view {\n gap: var(--gap-card);\n}\n\n/*\n * .fill-page--soft 把「恰好一屏」放宽成「至少一屏」,这里再给两张表所在的那一栏一个下限:\n * 卡片头尾约 62px + small 表头 34px + 4 行 x 34px ≈ 240px,少于这个就不叫表了。\n * 高屏上剩余高度本来就大于下限,页面仍然恰好一屏;矮屏上顶到下限后由 .page 正常出滚动条。\n * 容器和栅格项都要给:容器是 flex 子项(.fill-main 带 min-height:0,不设下限会被压过内容),\n * 栅格项则决定单列(l 断点以下两张表上下排)时每张表各自的下限。\n */\n.stats {\n display: grid;\n gap: var(--gap-card);\n flex-shrink: 0;\n}\n.job-tables {\n display: grid;\n gap: var(--gap-card);\n}\n.stat {\n display: flex;\n align-items: center;\n gap: 16px;\n}\n/* 图标底盘:取语义色 12% 作浅底,同工作台手法,避免图标\"裸浮\" */\n.stat-ico {\n flex-shrink: 0;\n width: 48px;\n height: 48px;\n border-radius: var(--radius-lg);\n display: flex;\n align-items: center;\n justify-content: center;\n background: color-mix(in srgb, currentColor 12%, transparent);\n}\n.stat-val {\n font-size: 28px;\n font-weight: 600;\n letter-spacing: -0.04em;\n color: var(--text-1);\n line-height: 34px;\n}\n.stat-label {\n font-size: 14px;\n color: var(--text-2);\n}\n</style>\n"],"names":["useI18n","message","useMessage","bp","pw","useShellBreakpoint","narrow","computed","statCols","NARROW_TABLES_STYLE","tablesStyle","stacked","basis","data","ref","loading","load","silent","jobApi","e","translateError","timer","start","stop","onMounted","onActivated","onDeactivated","onUnmounted","num","v","stats","_a","_b","_c","_d","trendOption","trend","p","relative","iso","diff","sec","upcomingColumns","r","h","fmtDateTime","nodeColumns","NTag","_createElementBlock","_normalizeClass","_createElementVNode","_Fragment","_renderList","s","_createBlock","_unref","NCard","_hoisted_1","_normalizeStyle","_createVNode","Icon","_hoisted_2","_toDisplayString","_hoisted_3","NSpin","BaseChart","SmartTable","TABLE_TOOLBAR","TABLE_MIN_ROW_HEIGHT","_withCtx","itemCount","TableTotal"],"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 m = /* @__PURE__ */ t(o, [["__scopeId", "data-v-421f41e4"]]);
4
+ const p = /* @__PURE__ */ t(o, [["__scopeId", "data-v-11588ddc"]]);
5
5
  export {
6
- m as default
6
+ p as default
7
7
  };
8
8
  //# sourceMappingURL=index.vue.js.map
@@ -1,4 +1,4 @@
1
- import { defineComponent as M, ref as f, computed as x, h as u, resolveDirective as R, openBlock as g, createElementBlock as L, Fragment as F, createVNode as a, unref as e, withCtx as o, withDirectives as H, createBlock as w, createTextVNode as _, toDisplayString as i, normalizeStyle as O, normalizeClass as V, createElementVNode as n, createCommentVNode as W } from "vue";
1
+ import { defineComponent as M, ref as f, computed as w, h as u, resolveDirective as R, openBlock as g, createElementBlock as L, Fragment as F, createVNode as a, unref as e, withCtx as o, withDirectives as H, createBlock as x, createTextVNode as _, toDisplayString as i, normalizeStyle as O, normalizeClass as V, createElementVNode as n, createCommentVNode as W } from "vue";
2
2
  import { useElementSize as $ } from "@vueuse/core";
3
3
  import { useMessage as q, NButton as T, NDrawer as G, NDrawerContent as P, NDescriptions as U, NDescriptionsItem as s } from "naive-ui";
4
4
  import { useI18n as j } from "vue-i18n";
@@ -14,12 +14,12 @@ import { operatorText as z, fmtDateTime as E } from "../../../../utils/format.js
14
14
  const oe = { class: "mono break" }, ae = { class: "mono break" }, re = { class: "mono break" }, ie = { class: "mono" }, se = { class: "muted break" }, ne = { class: "num" }, ce = { class: "exception" }, pe = { class: "exception" }, ze = /* @__PURE__ */ M({
15
15
  __name: "index",
16
16
  setup(me) {
17
- const { t } = j(), N = q(), { confirm: C } = Q(), d = f(), D = x(
17
+ const { t } = j(), N = q(), { confirm: C } = Q(), d = f(), D = w(
18
18
  () => {
19
19
  var l;
20
20
  return (l = d.value) == null ? void 0 : l.$el;
21
21
  }
22
- ), { width: v } = $(D), p = x(() => v.value > 0 && v.value < 600), S = Y({ ranges: ["createTime"] }), y = [
22
+ ), { width: v } = $(D), p = w(() => v.value > 0 && v.value < 600), S = Y({ ranges: ["createTime"] }), y = [
23
23
  { type: "index", title: () => t("common.rowNo"), width: 64, align: "center" },
24
24
  {
25
25
  key: "exceptionType",
@@ -51,11 +51,14 @@ const oe = { class: "mono break" }, ae = { class: "mono break" }, re = { class:
51
51
  },
52
52
  {
53
53
  key: "ip",
54
+ width: 140,
55
+ ellipsis: { tooltip: !0 },
54
56
  title: () => t("log.ip"),
55
57
  render: (l) => u("span", { class: "mono muted" }, l.ip || "—")
56
58
  },
57
59
  {
58
60
  key: "createTime",
61
+ width: 170,
59
62
  title: () => t("common.createTime"),
60
63
  render: (l) => u("span", { class: "num muted", style: "white-space: nowrap" }, E(l.createTime)),
61
64
  search: { type: "daterange", actions: b.dayRange }
@@ -110,7 +113,7 @@ const oe = { class: "mono break" }, ae = { class: "mono break" }, re = { class:
110
113
  a(le, { count: m }, null, 8, ["count"])
111
114
  ]),
112
115
  "toolbar-right": o(() => [
113
- H((g(), w(e(T), {
116
+ H((g(), x(e(T), {
114
117
  type: "error",
115
118
  secondary: "",
116
119
  onClick: I
@@ -147,7 +150,7 @@ const oe = { class: "mono break" }, ae = { class: "mono break" }, re = { class:
147
150
  "native-scrollbar": p.value
148
151
  }, {
149
152
  default: o(() => [
150
- r.value ? (g(), w(e(U), {
153
+ r.value ? (g(), x(e(U), {
151
154
  key: 0,
152
155
  "label-placement": "left",
153
156
  column: 1,
@@ -1 +1 @@
1
- {"version":3,"file":"index2.vue.js","sources":["../../../../../src/views/system/log/exception/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 异常日志 = 只读 SmartTable + 详情抽屉。后端无 exception/{id},分页项已含全字段 → 抽屉直接用行数据。\n// 只记未捕获异常(程序缺陷);业务异常不进本表。堆栈保持危险色 <pre>——堆栈非代码,高亮无意义。\nimport { computed, h, ref } from 'vue'\nimport { useElementSize } from '@vueuse/core'\nimport {\n NButton,\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 { useConfirm } from '#/composables/useConfirm'\nimport { logApi } from '#/api'\nimport { translateError } from '#/utils/error'\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 { fmtDateTime, operatorText } from '#/utils/format'\nimport type { SysExceptionLog } from '#/types/api'\n\nconst { t } = useI18n()\nconst message = useMessage()\nconst { confirm } = useConfirm()\nconst tableRef = ref<SmartTableInst<SysExceptionLog>>()\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// 日期区间:条件构造器里是同一字段的两行(大于等于 + 小于等于),序列化器合并成 [起, 止],\n// api 层 splitRange 再拆成 StartTime/EndTime 并给结束日补 23:59:59。\nconst filterSerializer = createFlatFilterSerializer({ ranges: ['createTime'] })\n\nconst columns: SmartTableColumn<SysExceptionLog>[] = [\n { type: 'index', title: () => t('common.rowNo'), width: 64, align: 'center' },\n {\n key: 'exceptionType',\n title: () => t('log.exceptionType'),\n ellipsis: { tooltip: true },\n search: { actions: SEARCH_ACTIONS.fuzzy },\n render: r => h('span', { class: 'mono' }, r.exceptionType),\n },\n {\n key: 'message',\n title: () => t('log.exceptionMessage'),\n ellipsis: { tooltip: true },\n render: r => r.message || '—',\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: 'operator',\n title: () => t('log.operator'),\n width: 120,\n ellipsis: { tooltip: true },\n render: r => operatorText(r),\n },\n {\n key: 'ip',\n title: () => t('log.ip'),\n render: r => h('span', { class: 'mono muted' }, r.ip || '—'),\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 {\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<SysExceptionLog | null>(null)\nfunction openDetail(r: SysExceptionLog) {\n detailRow.value = r\n showDetail.value = true\n}\nfunction clearLogs() {\n confirm({\n type: 'error',\n content: t('log.clearExceptionConfirm'),\n action: () => logApi.exceptionClear(),\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.exceptionPage\"\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-exception\"\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\n v-auth=\"'DELETE:/api/v1/sys/log/exception'\"\n type=\"error\"\n secondary\n @click=\"clearLogs\"\n >\n <template #icon><AppIcon icon=\"ph:trash\" :size=\"16\" /></template>\n {{ t('log.clear') }}\n </n-button>\n </template>\n </SmartTable>\n\n <!-- 详情抽屉:宽档右侧 620,窄档底部抽屉(.st-sheet 由全局样式补圆角与滚动链);无底部按钮 -->\n <n-drawer\n v-model:show=\"showDetail\"\n :placement=\"isNarrow ? 'bottom' : 'right'\"\n :width=\"isNarrow ? undefined : 'min(620px, 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.exceptionType')\">\n <span class=\"mono break\">{{ detailRow.exceptionType }}</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.traceId')\">\n <span class=\"mono break\">{{ detailRow.traceId || '—' }}</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.exceptionMessage')\">\n <pre class=\"exception\">{{ detailRow.message || '—' }}</pre>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.stackTrace')\">\n <pre class=\"exception\">{{ detailRow.stackTrace || '—' }}</pre>\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":["useI18n","message","useMessage","confirm","useConfirm","tableRef","ref","tableEl","computed","_a","tableWidth","useElementSize","isNarrow","filterSerializer","createFlatFilterSerializer","columns","SEARCH_ACTIONS","h","r","operatorText","fmtDateTime","NButton","openDetail","deriveHeaderFilters","showDetail","detailRow","clearLogs","logApi","ok","_createVNode","_unref","SmartTable","TABLE_TOOLBAR","TABLE_MIN_ROW_HEIGHT","_cache","e","translateError","_withCtx","itemCount","TableTotal","_createBlock","AppIcon","_createTextVNode","NDrawer","$event","NDrawerContent","NDescriptions","NDescriptionsItem","_createElementVNode","_hoisted_1","_toDisplayString","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8"],"mappings":"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"}
1
+ {"version":3,"file":"index2.vue.js","sources":["../../../../../src/views/system/log/exception/index.vue"],"sourcesContent":["<script setup lang=\"ts\">\n// 异常日志 = 只读 SmartTable + 详情抽屉。后端无 exception/{id},分页项已含全字段 → 抽屉直接用行数据。\n// 只记未捕获异常(程序缺陷);业务异常不进本表。堆栈保持危险色 <pre>——堆栈非代码,高亮无意义。\nimport { computed, h, ref } from 'vue'\nimport { useElementSize } from '@vueuse/core'\nimport {\n NButton,\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 { useConfirm } from '#/composables/useConfirm'\nimport { logApi } from '#/api'\nimport { translateError } from '#/utils/error'\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 { fmtDateTime, operatorText } from '#/utils/format'\nimport type { SysExceptionLog } from '#/types/api'\n\nconst { t } = useI18n()\nconst message = useMessage()\nconst { confirm } = useConfirm()\nconst tableRef = ref<SmartTableInst<SysExceptionLog>>()\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// 日期区间:条件构造器里是同一字段的两行(大于等于 + 小于等于),序列化器合并成 [起, 止],\n// api 层 splitRange 再拆成 StartTime/EndTime 并给结束日补 23:59:59。\nconst filterSerializer = createFlatFilterSerializer({ ranges: ['createTime'] })\n\nconst columns: SmartTableColumn<SysExceptionLog>[] = [\n { type: 'index', title: () => t('common.rowNo'), width: 64, align: 'center' },\n {\n key: 'exceptionType',\n title: () => t('log.exceptionType'),\n ellipsis: { tooltip: true },\n search: { actions: SEARCH_ACTIONS.fuzzy },\n render: r => h('span', { class: 'mono' }, r.exceptionType),\n },\n {\n key: 'message',\n title: () => t('log.exceptionMessage'),\n ellipsis: { tooltip: true },\n render: r => r.message || '—',\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: 'operator',\n title: () => t('log.operator'),\n width: 120,\n ellipsis: { tooltip: true },\n render: r => operatorText(r),\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 {\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<SysExceptionLog | null>(null)\nfunction openDetail(r: SysExceptionLog) {\n detailRow.value = r\n showDetail.value = true\n}\nfunction clearLogs() {\n confirm({\n type: 'error',\n content: t('log.clearExceptionConfirm'),\n action: () => logApi.exceptionClear(),\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.exceptionPage\"\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-exception\"\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\n v-auth=\"'DELETE:/api/v1/sys/log/exception'\"\n type=\"error\"\n secondary\n @click=\"clearLogs\"\n >\n <template #icon><AppIcon icon=\"ph:trash\" :size=\"16\" /></template>\n {{ t('log.clear') }}\n </n-button>\n </template>\n </SmartTable>\n\n <!-- 详情抽屉:宽档右侧 620,窄档底部抽屉(.st-sheet 由全局样式补圆角与滚动链);无底部按钮 -->\n <n-drawer\n v-model:show=\"showDetail\"\n :placement=\"isNarrow ? 'bottom' : 'right'\"\n :width=\"isNarrow ? undefined : 'min(620px, 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.exceptionType')\">\n <span class=\"mono break\">{{ detailRow.exceptionType }}</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.traceId')\">\n <span class=\"mono break\">{{ detailRow.traceId || '—' }}</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.exceptionMessage')\">\n <pre class=\"exception\">{{ detailRow.message || '—' }}</pre>\n </n-descriptions-item>\n <n-descriptions-item :label=\"t('log.stackTrace')\">\n <pre class=\"exception\">{{ detailRow.stackTrace || '—' }}</pre>\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":["useI18n","message","useMessage","confirm","useConfirm","tableRef","ref","tableEl","computed","_a","tableWidth","useElementSize","isNarrow","filterSerializer","createFlatFilterSerializer","columns","SEARCH_ACTIONS","h","r","operatorText","fmtDateTime","NButton","openDetail","deriveHeaderFilters","showDetail","detailRow","clearLogs","logApi","ok","_createVNode","_unref","SmartTable","TABLE_TOOLBAR","TABLE_MIN_ROW_HEIGHT","_cache","e","translateError","_withCtx","itemCount","TableTotal","_createBlock","AppIcon","_createTextVNode","NDrawer","$event","NDrawerContent","NDescriptions","NDescriptionsItem","_createElementVNode","_hoisted_1","_toDisplayString","_hoisted_2","_hoisted_3","_hoisted_4","_hoisted_5","_hoisted_6","_hoisted_7","_hoisted_8"],"mappings":"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"}