@liujitcn/kratos-admin-system 0.0.46 → 0.0.48

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 (51) hide show
  1. package/dist/package/declarations/src/components/log.d.ts +2 -0
  2. package/dist/package/src/components/LogTable.vue +5 -2
  3. package/dist/package/src/components/log.ts +6 -2
  4. package/dist/package/src/views/ai/chat/components/ChatPanel.vue +2 -9
  5. package/dist/package/src/views/base/api/index.vue +0 -2
  6. package/dist/package/src/views/base/api-log/index.vue +6 -5
  7. package/dist/package/src/views/base/area/index.vue +0 -2
  8. package/dist/package/src/views/base/backup-management/archive-config/index.vue +1 -1
  9. package/dist/package/src/views/base/backup-management/archive-record/index.vue +7 -6
  10. package/dist/package/src/views/base/backup-management/archive-restore/index.vue +2 -1
  11. package/dist/package/src/views/base/backup-management/backup-config/index.vue +1 -1
  12. package/dist/package/src/views/base/backup-management/backup-record/index.vue +4 -3
  13. package/dist/package/src/views/base/backup-management/backup-restore/index.vue +2 -1
  14. package/dist/package/src/views/base/config/index.vue +2 -4
  15. package/dist/package/src/views/base/data-access-log/index.vue +5 -4
  16. package/dist/package/src/views/base/dept/index.vue +3 -5
  17. package/dist/package/src/views/base/dict/index.vue +2 -4
  18. package/dist/package/src/views/base/dict/item.vue +2 -4
  19. package/dist/package/src/views/base/file/index.vue +3 -5
  20. package/dist/package/src/views/base/job/index.vue +2 -4
  21. package/dist/package/src/views/base/job/log.vue +3 -4
  22. package/dist/package/src/views/base/language/index.vue +3 -5
  23. package/dist/package/src/views/base/login-log/index.vue +4 -3
  24. package/dist/package/src/views/base/login-policy/index.vue +0 -2
  25. package/dist/package/src/views/base/menu/index.vue +3 -5
  26. package/dist/package/src/views/base/message/index.vue +7 -9
  27. package/dist/package/src/views/base/message-category/index.vue +1 -3
  28. package/dist/package/src/views/base/migration/index.vue +2 -14
  29. package/dist/package/src/views/base/oauth-client/index.vue +0 -2
  30. package/dist/package/src/views/base/online-session/index.vue +8 -3
  31. package/dist/package/src/views/base/operation-log/index.vue +5 -4
  32. package/dist/package/src/views/base/permission-log/index.vue +4 -3
  33. package/dist/package/src/views/base/policy-evaluation-log/index.vue +5 -4
  34. package/dist/package/src/views/base/post/index.vue +2 -4
  35. package/dist/package/src/views/base/redact-output-policy/index.vue +1 -1
  36. package/dist/package/src/views/base/redact-rule/index.vue +0 -2
  37. package/dist/package/src/views/base/redact-storage-policy/index.vue +1 -1
  38. package/dist/package/src/views/base/role/index.vue +2 -4
  39. package/dist/package/src/views/base/tenant/index.vue +2 -4
  40. package/dist/package/src/views/base/user/index.vue +2 -4
  41. package/dist/package/src/views/message/inbox/index.vue +0 -2
  42. package/dist/package/src/views/profile/components/base.vue +2 -1
  43. package/dist/package/src/views/profile/components/login-log.vue +2 -2
  44. package/dist/package/src/views/profile/components/session.vue +8 -1
  45. package/dist/package/src/views/tool/cache/index.vue +8 -11
  46. package/dist/package/src/views/tool/code-gen/components/CodeGenProgressDialog.vue +3 -3
  47. package/dist/package/src/views/tool/code-gen/preview/index.vue +0 -2
  48. package/dist/package/src/views/tool/code-gen/table/index.vue +1 -3
  49. package/dist/package/src/views/tool/ops-monitoring/index.vue +4 -4
  50. package/dist/package/src/views/tool/runtime-log/index.vue +2 -13
  51. package/package.json +3 -3
@@ -4,6 +4,8 @@ import type { BaseLogTraceItem } from "@liujitcn/kratos-admin-system/rpc/system/
4
4
  export declare function createLogEnumOptions(items: Array<[number, string]>): EnumProps[];
5
5
  /** 根据枚举值查找展示文案。 */
6
6
  export declare function logEnumLabel(options: EnumProps[], value: unknown, fallback?: string): string;
7
+ /** 格式化审计日志时间,统一输出本地日期时间文本。 */
8
+ export declare function formatLogDateTime(value: unknown): string;
7
9
  /** 格式化日志 HTTP 状态码并补充状态语义。 */
8
10
  export declare function formatLogStatusCode(value: unknown, t: (key: string) => string): string;
9
11
  /** 格式化日志耗时,零值表示未采集。 */
@@ -24,7 +24,9 @@
24
24
  <el-table-column :label="t('system.base.log.trace.duration')" width="110" align="right">
25
25
  <template #default="scope">{{ formatDuration(scope.row.duration_ms) }}</template>
26
26
  </el-table-column>
27
- <el-table-column prop="occurred_at" :label="t('system.base.log.field.occurred_at')" width="190" />
27
+ <el-table-column :label="t('system.base.log.field.occurred_at')" width="190" align="center">
28
+ <template #default="scope">{{ formatLogDateTime(scope.row.occurred_at) }}</template>
29
+ </el-table-column>
28
30
  </el-table>
29
31
  </section>
30
32
 
@@ -45,7 +47,7 @@ import { formatJson } from "@liujitcn/kratos-admin-core/format";
45
47
  import { t } from "@liujitcn/kratos-admin-core";
46
48
  import { BaseLogType, BaseLogResult } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_log";
47
49
  import type { BaseLogTraceItem } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_log";
48
- import { logEnumLabel } from "./log";
50
+ import { formatLogDateTime, logEnumLabel } from "./log";
49
51
 
50
52
  /** 审计详情字段配置。 */
51
53
  export interface LogDetailField {
@@ -130,6 +132,7 @@ function formatField(field: LogDetailField) {
130
132
  if (field.enum) return logEnumLabel(field.enum, value, t("common.value.unknown"));
131
133
  if (field.format) return field.format(value);
132
134
  if (field.code) return formatJson(String(value));
135
+ if (field.key.endsWith("_at") || field.key.endsWith("_time")) return formatLogDateTime(value);
133
136
  return String(value);
134
137
  }
135
138
 
@@ -1,4 +1,5 @@
1
1
  import type { ColumnProps, EnumProps, SearchProps } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
2
+ import { formatDateTime } from "@liujitcn/kratos-admin-core/format";
2
3
  import { defBaseLogService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_log";
3
4
  import type { BaseLogTraceItem } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_log";
4
5
 
@@ -12,6 +13,11 @@ export function logEnumLabel(options: EnumProps[], value: unknown, fallback = ""
12
13
  return options.find(item => item.value === value)?.label ?? (fallback || String(value ?? ""));
13
14
  }
14
15
 
16
+ /** 格式化审计日志时间,统一输出本地日期时间文本。 */
17
+ export function formatLogDateTime(value: unknown): string {
18
+ return formatDateTime(typeof value === "string" || typeof value === "number" ? value : undefined);
19
+ }
20
+
15
21
  /** 格式化日志 HTTP 状态码并补充状态语义。 */
16
22
  export function formatLogStatusCode(value: unknown, t: (key: string) => string): string {
17
23
  const code = Number(value);
@@ -66,8 +72,6 @@ export function logDetailColumn(label: string, onClick: (id: string) => void): C
66
72
  return {
67
73
  prop: "detailAction",
68
74
  label,
69
- width: 100,
70
- fixed: "right",
71
75
  cellType: "actions",
72
76
  actions: [
73
77
  {
@@ -334,6 +334,7 @@ import type { FilesCardProps } from "vue-element-plus-x/types/FilesCard";
334
334
  import { Check, CopyDocument, DataAnalysis, Delete, EditPen, Link, Memo, PieChart, Refresh, User } from "@element-plus/icons-vue";
335
335
  import { ElMessage } from "element-plus";
336
336
  import { getCurrentLocale, t } from "@liujitcn/kratos-admin-core";
337
+ import { formatDateTime } from "@liujitcn/kratos-admin-core/format";
337
338
  import type { AiAction } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_message";
338
339
  import { type AiAttachment, type AiSession } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_session";
339
340
  import type { AiShortcut, AiToolCall } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_tool";
@@ -737,15 +738,7 @@ function formatDurationMs(value?: number) {
737
738
  function resolveMessageReplyTime(item: ChatMessageItem) {
738
739
  const timestamp = resolveMessageCreatedAt(item);
739
740
  if (!timestamp) return "";
740
- return new Intl.DateTimeFormat(getCurrentLocale(), {
741
- year: "numeric",
742
- month: "2-digit",
743
- day: "2-digit",
744
- hour: "2-digit",
745
- minute: "2-digit",
746
- second: "2-digit",
747
- hour12: false
748
- }).format(new Date(timestamp));
741
+ return formatDateTime(timestamp);
749
742
  }
750
743
 
751
744
  /** 解析消息创建时间戳,兼容 protobuf Timestamp 结构。 */
@@ -277,8 +277,6 @@ const columns = computed<ColumnProps[]>(() => [
277
277
  {
278
278
  prop: "operation",
279
279
  label: t("common.field.action"),
280
- width: 210,
281
- fixed: "right",
282
280
  cellType: "actions",
283
281
  actions: [
284
282
  {
@@ -6,6 +6,7 @@
6
6
  import { computed, ref } from "vue";
7
7
  import type { ColumnProps } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
8
8
  import { t } from "@liujitcn/kratos-admin-core";
9
+ import { formatLogDateTime } from "@liujitcn/kratos-admin-system/components/log";
9
10
  import { buildPageRequest } from "@liujitcn/kratos-admin-core/table";
10
11
  import LogTable, { type LogTableConfig } from "@liujitcn/kratos-admin-system/components/LogTable.vue";
11
12
  import {
@@ -36,7 +37,7 @@ const resultOptions = computed(() =>
36
37
  const columns = computed<ColumnProps[]>(() => [
37
38
  { prop: "operation", label: t("system.base.log.field.operation"), minWidth: 320, search: { el: "input" } },
38
39
  { prop: "method", label: t("system.base.log.field.method"), minWidth: 90 },
39
- { prop: "status_code", label: t("system.base.log.field.status_code"), minWidth: 100 },
40
+ { prop: "status_code", label: t("system.base.log.field.status_code"), minWidth: 100, align: "right" },
40
41
  {
41
42
  prop: "result",
42
43
  label: t("system.base.log.field.result"),
@@ -44,9 +45,9 @@ const columns = computed<ColumnProps[]>(() => [
44
45
  search: { el: "select", enum: resultOptions.value },
45
46
  render: scope => logEnumLabel(resultOptions.value, (scope.row as BaseApiLog).result)
46
47
  },
47
- { prop: "latency_ms", label: t("system.base.log.field.latency_ms"), minWidth: 110 },
48
+ { prop: "latency_ms", label: t("system.base.log.field.latency_ms"), minWidth: 110, align: "right" },
48
49
  { prop: "user_name", label: t("system.base.log.field.user_name"), minWidth: 130 },
49
- { prop: "occurred_at", label: t("system.base.log.field.occurred_at"), minWidth: 190, search: logDateSearch(t) },
50
+ { prop: "occurred_at", label: t("system.base.log.field.occurred_at"), minWidth: 190, align: "center", search: logDateSearch(t) },
50
51
  logDetailColumn(t("common.action.view"), id => page.value?.handleOpenDialog(id))
51
52
  ]);
52
53
 
@@ -76,8 +77,8 @@ const config = computed<LogTableConfig>(() => ({
76
77
  { key: "user_agent", label: t("system.base.log.field.user_agent"), span: 2 },
77
78
  { key: "request_id", label: t("system.base.log.field.request_id") },
78
79
  { key: "trace_id", label: t("system.base.log.field.trace_id") },
79
- { key: "occurred_at", label: t("system.base.log.field.occurred_at") },
80
- { key: "created_at", label: t("system.base.log.field.created_at") }
80
+ { key: "occurred_at", format: formatLogDateTime, label: t("system.base.log.field.occurred_at") },
81
+ { key: "created_at", format: formatLogDateTime, label: t("system.base.log.field.created_at") }
81
82
  ],
82
83
  request: requestTable,
83
84
  get: getDetail
@@ -145,8 +145,6 @@ const columns = computed<ColumnProps[]>(() => [
145
145
  {
146
146
  prop: "operation",
147
147
  label: t("common.field.operation"),
148
- width: 150,
149
- fixed: "right",
150
148
  cellType: "actions",
151
149
  actions: [
152
150
  {
@@ -71,7 +71,7 @@ const columns = computed<ColumnProps[]>(() => [
71
71
  { prop: "online_retention_days", label: t("system.backup.field.online_retention_days"), width: 120 },
72
72
  { prop: "archive_retention_days", label: t("system.backup.field.archive_retention_days"), width: 120 },
73
73
  { prop: "status", label: t("common.field.status"), width: 100, cellType: "status", statusProps: { activeValue: Status.STATUS_ENABLE, inactiveValue: Status.STATUS_DISABLE, activeText: t("common.status.enabled"), inactiveText: t("common.status.disabled"), disabled: () => !BUTTONS.value["base:table-archive:status"], beforeChange: scope => setStatus(scope.row as BaseTableArchiveForm) } },
74
- { prop: "operation", label: t("common.field.operation"), width: 180, fixed: "right", cellType: "actions", actions: [{ label: t("common.action.edit"), link: true, icon: EditPen, hidden: () => !BUTTONS.value["base:table-archive:update"], onClick: scope => openDialog((scope.row as BaseTableArchiveForm).id) }, { label: t("common.action.delete"), link: true, type: "danger", icon: Delete, hidden: () => !BUTTONS.value["base:table-archive:delete"], onClick: scope => remove(scope.row as BaseTableArchiveForm) }] }
74
+ { prop: "operation", label: t("common.field.operation"), cellType: "actions", actions: [{ label: t("common.action.edit"), link: true, icon: EditPen, hidden: () => !BUTTONS.value["base:table-archive:update"], onClick: scope => openDialog((scope.row as BaseTableArchiveForm).id) }, { label: t("common.action.delete"), link: true, type: "danger", icon: Delete, hidden: () => !BUTTONS.value["base:table-archive:delete"], onClick: scope => remove(scope.row as BaseTableArchiveForm) }] }
75
75
  ]);
76
76
  const headerActions = computed<HeaderActionProps[]>(() => [{ label: t("common.action.create"), type: "primary", icon: CirclePlus, hidden: !BUTTONS.value["base:table-archive:create"], onClick: () => openDialog() }, { label: t("common.action.delete"), type: "danger", icon: Delete, hidden: !BUTTONS.value["base:table-archive:delete"], disabled: scope => !scope.isSelected, onClick: scope => remove(scope.selectedListIds as number[]) }]);
77
77
 
@@ -10,6 +10,7 @@ import ProTable from "@liujitcn/kratos-admin-core/components/ProTable";
10
10
  import type { ColumnProps, ProTableInstance } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
11
11
  import { buildPageRequest } from "@liujitcn/kratos-admin-core/table";
12
12
  import { t } from "@liujitcn/kratos-admin-core";
13
+ import { formatDateTime } from "@liujitcn/kratos-admin-core/format";
13
14
  import { defBaseTableArchiveRecordService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_table_archive_record";
14
15
  import { BaseTableArchiveMode } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_table_archive";
15
16
  import { BaseTableArchiveRecordStatus, type PageBaseTableArchiveRecordRequest } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_table_archive_record";
@@ -23,17 +24,17 @@ const statusOptions = computed(() => [
23
24
  { label: t("system.backup.status.deleted"), value: BaseTableArchiveRecordStatus.BASE_TABLE_ARCHIVE_RECORD_STATUS_DELETED }
24
25
  ]);
25
26
  const columns = computed<ColumnProps[]>(() => [
26
- { prop: "id", label: t("system.backup.field.id"), width: 90 },
27
+ { prop: "id", label: t("system.backup.field.id"), width: 90, align: "right" },
27
28
  { prop: "source_name", label: t("system.backup.field.source_name"), minWidth: 140 },
28
29
  { prop: "table_name", label: t("system.backup.field.table_name"), minWidth: 180 },
29
30
  { prop: "archive_mode", label: t("system.backup.field.archive_mode"), width: 130, render: scope => scope.row.archive_mode === BaseTableArchiveMode.BASE_TABLE_ARCHIVE_MODE_INTERNAL_DATABASE ? t("system.backup.archive.mode.internal") : t("system.backup.archive.mode.oss") },
30
- { prop: "cutoff_at", label: t("system.backup.field.cutoff_at"), minWidth: 170 },
31
- { prop: "archived_rows", label: t("system.backup.field.archived_rows"), width: 110 },
32
- { prop: "deleted_rows", label: t("system.backup.field.deleted_rows"), width: 110 },
31
+ { prop: "cutoff_at", align: "center", label: t("system.backup.field.cutoff_at"), minWidth: 170, render: scope => formatDateTime(scope.row.cutoff_at) },
32
+ { prop: "archived_rows", label: t("system.backup.field.archived_rows"), width: 110, align: "right" },
33
+ { prop: "deleted_rows", label: t("system.backup.field.deleted_rows"), width: 110, align: "right" },
33
34
  { prop: "object_key", label: t("system.backup.field.object_key"), minWidth: 220 },
34
35
  { prop: "status", label: t("common.field.status"), width: 110, search: { el: "select", enum: statusOptions.value }, render: scope => statusOptions.value.find(item => item.value === scope.row.status)?.label ?? String(scope.row.status) },
35
- { prop: "started_at", label: t("system.backup.field.started_at"), minWidth: 170 },
36
- { prop: "finished_at", label: t("system.backup.field.finished_at"), minWidth: 170 }
36
+ { prop: "started_at", align: "center", label: t("system.backup.field.started_at"), minWidth: 170, render: scope => formatDateTime(scope.row.started_at) },
37
+ { prop: "finished_at", align: "center", label: t("system.backup.field.finished_at"), minWidth: 170, render: scope => formatDateTime(scope.row.finished_at) }
37
38
  ]);
38
39
 
39
40
  /** 请求归档记录分页列表。 */
@@ -19,6 +19,7 @@ import type { ProFormField, ProFormInstance, ProFormOption } from "@liujitcn/kra
19
19
  import { buildPageRequest } from "@liujitcn/kratos-admin-core/table";
20
20
  import { useAuthButtons } from "@liujitcn/kratos-admin-core/auth";
21
21
  import { t } from "@liujitcn/kratos-admin-core";
22
+ import { formatDateTime } from "@liujitcn/kratos-admin-core/format";
22
23
  import { defBaseTableArchiveRestoreService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_table_archive_restore";
23
24
  import { BaseTableArchiveRestoreMode, BaseTableArchiveRestoreStatus, type BaseTableArchiveRestore } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_table_archive_restore";
24
25
 
@@ -36,7 +37,7 @@ const formRules = computed(() => ({
36
37
  { type: "number", min: 1, message: t("system.backup.validation.archive_record_id_positive"), trigger: "change" }
37
38
  ]
38
39
  }));
39
- const columns = computed<ColumnProps[]>(() => [{ prop: "id", label: t("system.backup.field.id"), width: 90 }, { prop: "archive_record_id", label: t("system.backup.field.archive_record_id"), width: 130 }, { prop: "table_name", label: t("system.backup.field.table_name"), minWidth: 180 }, { prop: "restore_mode", label: t("system.backup.field.restore_mode"), width: 120, render: scope => modeOptions.value.find(item => item.value === scope.row.restore_mode)?.label ?? String(scope.row.restore_mode) }, { prop: "restored_rows", label: t("system.backup.field.restored_rows"), width: 110 }, { prop: "status", label: t("common.field.status"), width: 110 }, { prop: "error", label: t("system.backup.field.error"), minWidth: 220 }, { prop: "started_at", label: t("system.backup.field.started_at"), minWidth: 170 }, { prop: "finished_at", label: t("system.backup.field.finished_at"), minWidth: 170 }]);
40
+ const columns = computed<ColumnProps[]>(() => [{ prop: "id", label: t("system.backup.field.id"), width: 90 }, { prop: "archive_record_id", label: t("system.backup.field.archive_record_id"), width: 130 }, { prop: "table_name", label: t("system.backup.field.table_name"), minWidth: 180 }, { prop: "restore_mode", label: t("system.backup.field.restore_mode"), width: 120, render: scope => modeOptions.value.find(item => item.value === scope.row.restore_mode)?.label ?? String(scope.row.restore_mode) }, { prop: "restored_rows", label: t("system.backup.field.restored_rows"), width: 110 }, { prop: "status", label: t("common.field.status"), width: 110 }, { prop: "error", label: t("system.backup.field.error"), minWidth: 220 }, { prop: "started_at", align: "center", label: t("system.backup.field.started_at"), minWidth: 170, render: scope => formatDateTime(scope.row.started_at) }, { prop: "finished_at", align: "center", label: t("system.backup.field.finished_at"), minWidth: 170, render: scope => formatDateTime(scope.row.finished_at) }]);
40
41
 
41
42
  /** 请求归档恢复记录分页列表。 */
42
43
  async function requestTable(params: Record<string, unknown>) { const data = await defBaseTableArchiveRestoreService.PageBaseTableArchiveRestore(buildPageRequest(params)); return { data: { list: data.base_table_archive_restores ?? [], total: data.total } }; }
@@ -55,7 +55,7 @@ const columns = computed<ColumnProps[]>(() => [
55
55
  { prop: "oss_prefix", label: t("system.backup.field.oss_prefix"), minWidth: 180 },
56
56
  { prop: "retention_count", label: t("system.backup.field.retention_count"), width: 110 },
57
57
  { prop: "status", label: t("common.field.status"), width: 100, cellType: "status", statusProps: { activeValue: Status.STATUS_ENABLE, inactiveValue: Status.STATUS_DISABLE, activeText: t("common.status.enabled"), inactiveText: t("common.status.disabled"), disabled: () => !BUTTONS.value["base:table-backup:status"], beforeChange: scope => setStatus(scope.row as BaseTableBackupForm) } },
58
- { prop: "operation", label: t("common.field.operation"), width: 180, fixed: "right", cellType: "actions", actions: [{ label: t("common.action.edit"), link: true, icon: EditPen, hidden: () => !BUTTONS.value["base:table-backup:update"], onClick: scope => openDialog((scope.row as BaseTableBackupForm).id) }, { label: t("common.action.delete"), link: true, type: "danger", icon: Delete, hidden: () => !BUTTONS.value["base:table-backup:delete"], onClick: scope => remove(scope.row as BaseTableBackupForm) }] }
58
+ { prop: "operation", label: t("common.field.operation"), cellType: "actions", actions: [{ label: t("common.action.edit"), link: true, icon: EditPen, hidden: () => !BUTTONS.value["base:table-backup:update"], onClick: scope => openDialog((scope.row as BaseTableBackupForm).id) }, { label: t("common.action.delete"), link: true, type: "danger", icon: Delete, hidden: () => !BUTTONS.value["base:table-backup:delete"], onClick: scope => remove(scope.row as BaseTableBackupForm) }] }
59
59
  ]);
60
60
  const headerActions = computed<HeaderActionProps[]>(() => [{ label: t("common.action.create"), type: "primary", icon: CirclePlus, hidden: !BUTTONS.value["base:table-backup:create"], onClick: () => openDialog() }, { label: t("common.action.delete"), type: "danger", icon: Delete, hidden: !BUTTONS.value["base:table-backup:delete"], disabled: scope => !scope.isSelected, onClick: scope => remove(scope.selectedListIds as number[]) }]);
61
61
 
@@ -10,6 +10,7 @@ import ProTable from "@liujitcn/kratos-admin-core/components/ProTable";
10
10
  import type { ColumnProps, ProTableInstance } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
11
11
  import { buildPageRequest } from "@liujitcn/kratos-admin-core/table";
12
12
  import { t } from "@liujitcn/kratos-admin-core";
13
+ import { formatDateTime } from "@liujitcn/kratos-admin-core/format";
13
14
  import { defBaseTableBackupRecordService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_table_backup_record";
14
15
  import { BaseTableBackupRecordStatus, type PageBaseTableBackupRecordRequest } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_table_backup_record";
15
16
 
@@ -22,14 +23,14 @@ const statusOptions = computed(() => [
22
23
  { label: t("system.backup.status.deleted"), value: BaseTableBackupRecordStatus.BASE_TABLE_BACKUP_RECORD_STATUS_DELETED }
23
24
  ]);
24
25
  const columns = computed<ColumnProps[]>(() => [
25
- { prop: "id", label: t("system.backup.field.id"), width: 90 },
26
+ { prop: "id", label: t("system.backup.field.id"), width: 90, align: "right" },
26
27
  { prop: "source_name", label: t("system.backup.field.source_name"), minWidth: 140 },
27
28
  { prop: "database_name", label: t("system.backup.field.database_name"), minWidth: 160 },
28
29
  { prop: "object_key", label: t("system.backup.field.object_key"), minWidth: 260 },
29
30
  { prop: "size_bytes", label: t("system.backup.field.size_bytes"), width: 110 },
30
31
  { prop: "status", label: t("common.field.status"), width: 110, search: { el: "select", enum: statusOptions.value }, render: scope => statusOptions.value.find(item => item.value === scope.row.status)?.label ?? String(scope.row.status) },
31
- { prop: "started_at", label: t("system.backup.field.started_at"), minWidth: 170 },
32
- { prop: "finished_at", label: t("system.backup.field.finished_at"), minWidth: 170 },
32
+ { prop: "started_at", align: "center", label: t("system.backup.field.started_at"), minWidth: 170, render: scope => formatDateTime(scope.row.started_at) },
33
+ { prop: "finished_at", align: "center", label: t("system.backup.field.finished_at"), minWidth: 170, render: scope => formatDateTime(scope.row.finished_at) },
33
34
  { prop: "verified_at", label: t("system.backup.field.verified_at"), minWidth: 170 }
34
35
  ]);
35
36
 
@@ -19,6 +19,7 @@ import type { ProFormField, ProFormInstance, ProFormOption } from "@liujitcn/kra
19
19
  import { buildPageRequest } from "@liujitcn/kratos-admin-core/table";
20
20
  import { useAuthButtons } from "@liujitcn/kratos-admin-core/auth";
21
21
  import { t } from "@liujitcn/kratos-admin-core";
22
+ import { formatDateTime } from "@liujitcn/kratos-admin-core/format";
22
23
  import { defBaseTableBackupRestoreService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_table_backup_restore";
23
24
  import { defBaseTableSourceService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_table_source";
24
25
  import { BaseTableBackupRestoreMode, BaseTableBackupRestoreStatus, type BaseTableBackupRestore } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_table_backup_restore";
@@ -40,7 +41,7 @@ const formRules = computed(() => ({
40
41
  target_source_name: [{ required: true, message: t("system.backup.validation.target_source_name"), trigger: "blur" }],
41
42
  target_database: [{ required: true, message: t("system.backup.validation.target_database"), trigger: "blur" }]
42
43
  }));
43
- const columns = computed<ColumnProps[]>(() => [{ prop: "id", label: t("system.backup.field.id"), width: 90 }, { prop: "backup_record_id", label: t("system.backup.field.backup_record_id"), width: 130 }, { prop: "source_name", label: t("system.backup.field.source_name"), minWidth: 130 }, { prop: "target_source_name", label: t("system.backup.field.target_source_name"), minWidth: 130 }, { prop: "target_database", label: t("system.backup.field.target_database"), minWidth: 150 }, { prop: "restore_mode", label: t("system.backup.field.restore_mode"), width: 120, render: scope => modeOptions.value.find(item => item.value === scope.row.restore_mode)?.label ?? String(scope.row.restore_mode) }, { prop: "status", label: t("common.field.status"), width: 110 }, { prop: "error", label: t("system.backup.field.error"), minWidth: 220 }, { prop: "started_at", label: t("system.backup.field.started_at"), minWidth: 170 }, { prop: "finished_at", label: t("system.backup.field.finished_at"), minWidth: 170 }]);
44
+ const columns = computed<ColumnProps[]>(() => [{ prop: "id", label: t("system.backup.field.id"), width: 90 }, { prop: "backup_record_id", label: t("system.backup.field.backup_record_id"), width: 130 }, { prop: "source_name", label: t("system.backup.field.source_name"), minWidth: 130 }, { prop: "target_source_name", label: t("system.backup.field.target_source_name"), minWidth: 130 }, { prop: "target_database", label: t("system.backup.field.target_database"), minWidth: 150 }, { prop: "restore_mode", label: t("system.backup.field.restore_mode"), width: 120, render: scope => modeOptions.value.find(item => item.value === scope.row.restore_mode)?.label ?? String(scope.row.restore_mode) }, { prop: "status", label: t("common.field.status"), width: 110 }, { prop: "error", label: t("system.backup.field.error"), minWidth: 220 }, { prop: "started_at", align: "center", label: t("system.backup.field.started_at"), minWidth: 170, render: scope => formatDateTime(scope.row.started_at) }, { prop: "finished_at", align: "center", label: t("system.backup.field.finished_at"), minWidth: 170, render: scope => formatDateTime(scope.row.finished_at) }]);
44
45
 
45
46
  /** 请求备份恢复记录分页列表。 */
46
47
  async function requestTable(params: Record<string, unknown>) { const data = await defBaseTableBackupRestoreService.PageBaseTableBackupRestore(buildPageRequest(params)); return { data: { list: data.base_table_backup_restores ?? [], total: data.total } }; }
@@ -489,13 +489,11 @@ const columns = computed<ColumnProps[]>(() => [
489
489
  beforeChange: scope => handleBeforeSetStatus(scope.row as BaseConfig)
490
490
  }
491
491
  },
492
- { prop: "created_at", label: t("common.field.created_at"), minWidth: 180 },
493
- { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180 },
492
+ { prop: "created_at", align: "center", label: t("common.field.created_at"), minWidth: 180 },
493
+ { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180, align: "center" },
494
494
  {
495
495
  prop: "operation",
496
496
  label: t("common.field.operation"),
497
- width: 150,
498
- fixed: "right",
499
497
  cellType: "actions",
500
498
  actions: [
501
499
  {
@@ -6,6 +6,7 @@
6
6
  import { computed, ref } from "vue";
7
7
  import type { ColumnProps } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
8
8
  import { t } from "@liujitcn/kratos-admin-core";
9
+ import { formatLogDateTime } from "@liujitcn/kratos-admin-system/components/log";
9
10
  import { buildPageRequest } from "@liujitcn/kratos-admin-core/table";
10
11
  import LogTable, { type LogTableConfig } from "@liujitcn/kratos-admin-system/components/LogTable.vue";
11
12
  import {
@@ -44,10 +45,10 @@ const columns = computed<ColumnProps[]>(() => [
44
45
  { prop: "resource_type", label: t("system.base.log.field.resource_type"), minWidth: 150, search: { el: "input" } },
45
46
  { prop: "table_name", label: t("system.base.log.field.table_name"), minWidth: 150 },
46
47
  { prop: "access_type", label: t("system.base.log.field.access_type"), minWidth: 120, search: { el: "select", enum: accessTypeOptions.value }, render: scope => logEnumLabel(accessTypeOptions.value, (scope.row as BaseDataAccessLog).access_type) },
47
- { prop: "affected_rows", label: t("system.base.log.field.affected_rows"), minWidth: 110 },
48
+ { prop: "affected_rows", label: t("system.base.log.field.affected_rows"), minWidth: 110, align: "right" },
48
49
  { prop: "sensitive", label: t("system.base.log.field.sensitive"), minWidth: 110, search: { el: "switch" }, render: scope => (scope.row as BaseDataAccessLog).sensitive ? t("common.value.yes") : t("common.value.no") },
49
50
  { prop: "result", label: t("system.base.log.field.result"), minWidth: 110, search: { el: "select", enum: resultOptions.value }, render: scope => logEnumLabel(resultOptions.value, (scope.row as BaseDataAccessLog).result) },
50
- { prop: "occurred_at", label: t("system.base.log.field.occurred_at"), minWidth: 190, search: logDateSearch(t) },
51
+ { prop: "occurred_at", label: t("system.base.log.field.occurred_at"), minWidth: 190, align: "center", search: logDateSearch(t) },
51
52
  logDetailColumn(t("common.action.view"), id => page.value?.handleOpenDialog(id))
52
53
  ]);
53
54
 
@@ -78,8 +79,8 @@ const config = computed<LogTableConfig>(() => ({
78
79
  { key: "reason_code", label: t("system.base.log.field.reason_code") },
79
80
  { key: "request_id", label: t("system.base.log.field.request_id") },
80
81
  { key: "trace_id", label: t("system.base.log.field.trace_id") },
81
- { key: "occurred_at", label: t("system.base.log.field.occurred_at") },
82
- { key: "created_at", label: t("system.base.log.field.created_at") }
82
+ { key: "occurred_at", format: formatLogDateTime, label: t("system.base.log.field.occurred_at") },
83
+ { key: "created_at", format: formatLogDateTime, label: t("system.base.log.field.created_at") }
83
84
  ],
84
85
  request: requestTable,
85
86
  get: getDetail
@@ -196,7 +196,7 @@ const columns = computed<ColumnProps[]>(() => [
196
196
  }
197
197
  ] satisfies ColumnProps[])
198
198
  : []),
199
- { prop: "name", label: t("system.base.dept.field.name"), minWidth: 140, align: "left", search: { el: "input" } },
199
+ { prop: "name", label: t("system.base.dept.field.name"), minWidth: 140, align: "right", search: { el: "input" } },
200
200
  { prop: "remark", label: t("common.field.remark"), minWidth: 160, search: { el: "input" } },
201
201
  { prop: "sort", label: t("common.field.sort"), minWidth: 90, align: "right" },
202
202
  {
@@ -214,13 +214,11 @@ const columns = computed<ColumnProps[]>(() => [
214
214
  beforeChange: scope => handleBeforeSetStatus(scope.row as BaseDept)
215
215
  }
216
216
  },
217
- { prop: "created_at", label: t("common.field.created_at"), minWidth: 180 },
218
- { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180 },
217
+ { prop: "created_at", align: "center", label: t("common.field.created_at"), minWidth: 180 },
218
+ { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180, align: "center" },
219
219
  {
220
220
  prop: "operation",
221
221
  label: t("common.field.operation"),
222
- width: 220,
223
- fixed: "right",
224
222
  cellType: "actions",
225
223
  actions: [
226
224
  {
@@ -172,13 +172,11 @@ const columns = computed<ColumnProps[]>(() => [
172
172
  beforeChange: scope => handleBeforeSetStatus(scope.row as BaseDict)
173
173
  }
174
174
  },
175
- { prop: "created_at", label: t("common.field.created_at"), minWidth: 180 },
176
- { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180 },
175
+ { prop: "created_at", align: "center", label: t("common.field.created_at"), minWidth: 180 },
176
+ { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180, align: "center" },
177
177
  {
178
178
  prop: "operation",
179
179
  label: t("common.field.action"),
180
- width: 240,
181
- fixed: "right",
182
180
  cellType: "actions",
183
181
  actions: [
184
182
  {
@@ -234,13 +234,11 @@ const columns = computed<ColumnProps[]>(() => [
234
234
  beforeChange: scope => handleBeforeSetStatus(scope.row as BaseDictItem)
235
235
  }
236
236
  },
237
- { prop: "created_at", label: t("common.field.created_at"), minWidth: 180 },
238
- { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180 },
237
+ { prop: "created_at", align: "center", label: t("common.field.created_at"), minWidth: 180 },
238
+ { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180, align: "center" },
239
239
  {
240
240
  prop: "operation",
241
241
  label: t("common.field.action"),
242
- width: 180,
243
- fixed: "right",
244
242
  cellType: "actions",
245
243
  actions: [
246
244
  {
@@ -110,15 +110,13 @@ const columns = computed<ColumnProps[]>(() => [
110
110
  { prop: "file_name", label: t("system.base.file.field.name"), minWidth: 220, search: { el: "input" } },
111
111
  { prop: "extension", label: t("system.base.file.field.extension"), width: 100, search: { el: "input" } },
112
112
  { prop: "mime_type", label: t("system.base.file.field.mime"), minWidth: 180 },
113
- { prop: "size", label: t("system.base.file.field.size"), width: 120, render: scope => formatFileSize((scope.row as BaseFile).size) },
113
+ { prop: "size", label: t("system.base.file.field.size"), width: 120, align: "right", render: scope => formatFileSize((scope.row as BaseFile).size) },
114
114
  { prop: "content_hash", label: t("system.base.file.field.hash"), minWidth: 220 },
115
- { prop: "tenant_id", label: t("system.base.file.field.tenant"), width: 100 },
116
- { prop: "created_at", label: t("common.field.created_at"), minWidth: 180 },
115
+ { prop: "tenant_id", label: t("system.base.file.field.tenant"), width: 100, align: "right" },
116
+ { prop: "created_at", align: "center", label: t("common.field.created_at"), minWidth: 180 },
117
117
  {
118
118
  prop: "operation",
119
119
  label: t("common.field.operation"),
120
- width: 150,
121
- fixed: "right",
122
120
  cellType: "actions",
123
121
  actions: [
124
122
  {
@@ -367,13 +367,11 @@ const columns = computed<ColumnProps[]>(() => [
367
367
  beforeChange: scope => handleBeforeSetStatus(scope.row as BaseJob)
368
368
  }
369
369
  },
370
- { prop: "created_at", label: t("common.field.created_at"), minWidth: 180 },
371
- { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180 },
370
+ { prop: "created_at", align: "center", label: t("common.field.created_at"), minWidth: 180 },
371
+ { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180, align: "center" },
372
372
  {
373
373
  prop: "operation",
374
374
  label: t("common.field.action"),
375
- width: 380,
376
- fixed: "right",
377
375
  render: scope => renderOperationCell(scope as unknown as RenderScope<BaseJob>)
378
376
  }
379
377
  ]);
@@ -9,7 +9,7 @@
9
9
  <DictLabel v-model="detail.status" code="base_job_log_status" />
10
10
  </el-descriptions-item>
11
11
  <el-descriptions-item :label="t('system.base.job.log.field.process_time')">{{ detail.process_time }}</el-descriptions-item>
12
- <el-descriptions-item :label="t('system.base.job.log.field.execute_time')">{{ detail.execute_time }}</el-descriptions-item>
12
+ <el-descriptions-item :label="t('system.base.job.log.field.execute_time')">{{ formatDateTime(detail.execute_time) }}</el-descriptions-item>
13
13
  </el-descriptions>
14
14
 
15
15
  <el-descriptions :title="t('system.base.job.log.section.execution')" border :column="1" class="mt-4">
@@ -48,7 +48,7 @@ import ProDialog from "@liujitcn/kratos-admin-core/components/Dialog/ProDialog.v
48
48
  import { defBaseJobService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_job";
49
49
  import { defBaseJobLogService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_job_log";
50
50
  import { buildPageRequest } from "@liujitcn/kratos-admin-core/table";
51
- import { formatJson } from "@liujitcn/kratos-admin-core/format";
51
+ import { formatDateTime, formatJson } from "@liujitcn/kratos-admin-core/format";
52
52
  import type { BaseJobLog, PageBaseJobLogRequest } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_job_log";
53
53
  import { BaseJobLogStatus } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_job_log";
54
54
  import { t } from "@liujitcn/kratos-admin-core";
@@ -115,6 +115,7 @@ const columns = computed<ColumnProps[]>(() => [
115
115
  prop: "execute_time",
116
116
  label: t("system.base.job.log.field.execute_time"),
117
117
  minWidth: 180,
118
+ align: "center",
118
119
  search: {
119
120
  el: "date-picker",
120
121
  props: {
@@ -132,8 +133,6 @@ const columns = computed<ColumnProps[]>(() => [
132
133
  {
133
134
  prop: "detailAction",
134
135
  label: t("common.field.action"),
135
- width: 100,
136
- fixed: "right",
137
136
  cellType: "actions",
138
137
  actions: [
139
138
  {
@@ -85,7 +85,7 @@ const formFields = computed<ProFormField[]>(() => [
85
85
  const columns = computed<ColumnProps[]>(() => [
86
86
  { prop: "native_name", label: t("system.base.language.field.native_name"), minWidth: 130 },
87
87
  { prop: "language_name", label: t("system.base.language.field.name"), minWidth: 130, search: { el: "input" } },
88
- { prop: "language_code", label: t("system.base.language.field.code"), minWidth: 120, search: { el: "input" } },
88
+ { prop: "language_code", align: "center", label: t("system.base.language.field.code"), minWidth: 120, search: { el: "input" } },
89
89
  {
90
90
  prop: "is_primary",
91
91
  label: t("system.base.language.field.primary"),
@@ -115,13 +115,11 @@ const columns = computed<ColumnProps[]>(() => [
115
115
  beforeChange: scope => handleBeforeSetStatus(scope.row as BaseLanguage)
116
116
  }
117
117
  },
118
- { prop: "sort", label: t("system.base.language.field.sort"), width: 80 },
119
- { prop: "created_at", label: t("common.field.created_at"), minWidth: 180 },
118
+ { prop: "sort", label: t("system.base.language.field.sort"), width: 80, align: "right" },
119
+ { prop: "created_at", align: "center", label: t("common.field.created_at"), minWidth: 180 },
120
120
  {
121
121
  prop: "operation",
122
122
  label: t("common.field.operation"),
123
- width: 150,
124
- fixed: "right",
125
123
  cellType: "actions",
126
124
  actions: [
127
125
  { label: t("common.action.edit"), type: "primary", link: true, icon: EditPen, hidden: () => !BUTTONS.value["base:language:update"], onClick: scope => handleOpenDialog((scope.row as BaseLanguage).id) },
@@ -6,6 +6,7 @@
6
6
  import { computed, ref } from "vue";
7
7
  import type { ColumnProps } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
8
8
  import { t } from "@liujitcn/kratos-admin-core";
9
+ import { formatLogDateTime } from "@liujitcn/kratos-admin-system/components/log";
9
10
  import { buildPageRequest } from "@liujitcn/kratos-admin-core/table";
10
11
  import LogTable, { type LogTableConfig } from "@liujitcn/kratos-admin-system/components/LogTable.vue";
11
12
  import { logDateSearch, logDetailColumn, logEnumLabel, createLogEnumOptions, requestLogTrace } from "@liujitcn/kratos-admin-system/components/log";
@@ -54,7 +55,7 @@ const columns = computed<ColumnProps[]>(() => [
54
55
  render: scope => logEnumLabel(resultOptions.value, (scope.row as BaseLoginLog).result)
55
56
  },
56
57
  { prop: "client_ip", label: t("system.base.log.field.client_ip"), minWidth: 140 },
57
- { prop: "occurred_at", label: t("system.base.log.field.occurred_at"), minWidth: 190, search: logDateSearch(t) },
58
+ { prop: "occurred_at", label: t("system.base.log.field.occurred_at"), minWidth: 190, align: "center", search: logDateSearch(t) },
58
59
  logDetailColumn(t("common.action.view"), id => page.value?.handleOpenDialog(id))
59
60
  ]);
60
61
 
@@ -78,8 +79,8 @@ const config = computed<LogTableConfig>(() => ({
78
79
  { key: "user_agent", label: t("system.base.log.field.user_agent"), span: 2 },
79
80
  { key: "request_id", label: t("system.base.log.field.request_id") },
80
81
  { key: "trace_id", label: t("system.base.log.field.trace_id") },
81
- { key: "occurred_at", label: t("system.base.log.field.occurred_at") },
82
- { key: "created_at", label: t("system.base.log.field.created_at") }
82
+ { key: "occurred_at", format: formatLogDateTime, label: t("system.base.log.field.occurred_at") },
83
+ { key: "created_at", format: formatLogDateTime, label: t("system.base.log.field.created_at") }
83
84
  ],
84
85
  request: requestTable,
85
86
  get: getDetail
@@ -260,8 +260,6 @@ const columns = computed<ColumnProps[]>(() => [
260
260
  {
261
261
  prop: "operation",
262
262
  label: t("common.field.operation"),
263
- width: 150,
264
- fixed: "right",
265
263
  cellType: "actions",
266
264
  actions: [
267
265
  {
@@ -313,7 +313,7 @@ const columns = computed<ColumnProps[]>(() => [
313
313
  prop: "meta.title",
314
314
  label: t("system.base.menu.field.name"),
315
315
  minWidth: 220,
316
- align: "left",
316
+ align: "right",
317
317
  search: { el: "input", key: "title" },
318
318
  showOverflowTooltip: false,
319
319
  render: scope => renderMenuTitleCell(scope as unknown as RenderScope<BaseMenu>)
@@ -352,13 +352,11 @@ const columns = computed<ColumnProps[]>(() => [
352
352
  width: 100,
353
353
  render: scope => renderHiddenCell(scope as unknown as RenderScope<BaseMenu>)
354
354
  },
355
- { prop: "created_at", label: t("common.field.created_at"), minWidth: 180 },
356
- { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180 },
355
+ { prop: "created_at", align: "center", label: t("common.field.created_at"), minWidth: 180 },
356
+ { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180, align: "center" },
357
357
  {
358
358
  prop: "operation",
359
359
  label: t("common.field.action"),
360
- width: 220,
361
- fixed: "right",
362
360
  cellType: "actions",
363
361
  actions: [
364
362
  {
@@ -104,25 +104,25 @@
104
104
  }}</el-descriptions-item>
105
105
  </el-descriptions>
106
106
  <el-table :data="detail.data.dispatches" style="margin-top: 16px" size="small">
107
- <el-table-column prop="id" label="ID" width="90" />
107
+ <el-table-column prop="id" label="ID" width="90" align="right" />
108
108
  <el-table-column prop="audience_type" :label="t('system.base.message.field.audience_type')" width="120">
109
109
  <template #default="scope">{{ optionLabel(audienceOptions, scope.row.audience_type) }}</template>
110
110
  </el-table-column>
111
- <el-table-column prop="audience_id" :label="t('system.base.message.field.audience_id')" width="110" />
111
+ <el-table-column prop="audience_id" :label="t('system.base.message.field.audience_id')" width="110" align="right" />
112
112
  <el-table-column prop="include_children" :label="t('system.base.message.field.include_children')" width="120">
113
113
  <template #default="scope">{{ scope.row.include_children ? t("common.value.yes") : t("common.value.no") }}</template>
114
114
  </el-table-column>
115
115
  <el-table-column prop="status" :label="t('common.field.status')" width="120" />
116
- <el-table-column prop="matched_total" :label="t('system.base.message.field.matched_total')" width="110" />
117
- <el-table-column prop="inserted_total" :label="t('system.base.message.field.inserted_total')" width="110" />
118
- <el-table-column prop="attempt_count" :label="t('system.base.message.field.attempt_count')" width="90" />
116
+ <el-table-column prop="matched_total" :label="t('system.base.message.field.matched_total')" width="110" align="right" />
117
+ <el-table-column prop="inserted_total" :label="t('system.base.message.field.inserted_total')" width="110" align="right" />
118
+ <el-table-column prop="attempt_count" :label="t('system.base.message.field.attempt_count')" width="90" align="right" />
119
119
  <el-table-column
120
120
  prop="last_error"
121
121
  :label="t('system.base.message.field.last_error')"
122
122
  min-width="220"
123
123
  show-overflow-tooltip
124
124
  />
125
- <el-table-column :label="t('common.field.operation')" width="90">
125
+ <el-table-column :label="t('common.field.operation')">
126
126
  <template #default="scope">
127
127
  <el-button
128
128
  v-if="scope.row.status === MessageDispatchStatus.MESSAGE_DISPATCH_STATUS_FAILED && BUTTONS['base:message:retry']"
@@ -419,13 +419,11 @@ const columns = computed<ColumnProps[]>(() => [
419
419
  render: scope => optionLabel(statusOptions.value, (scope.row as BaseMessage).status)
420
420
  },
421
421
  { prop: "delivered_total", label: t("system.base.message.field.delivered_total"), width: 100, align: "right" },
422
- { prop: "created_at", label: t("common.field.created_at"), minWidth: 180 },
422
+ { prop: "created_at", align: "center", label: t("common.field.created_at"), minWidth: 180 },
423
423
  {
424
424
  prop: "operation",
425
425
  label: t("common.field.operation"),
426
- width: 380,
427
426
  className: "message-operation-column",
428
- fixed: "right",
429
427
  cellType: "actions",
430
428
  actions: [
431
429
  {
@@ -234,12 +234,10 @@ const columns = computed<ColumnProps[]>(() => [
234
234
  beforeChange: scope => handleSetStatus(scope.row as BaseMessageCategory)
235
235
  }
236
236
  },
237
- { prop: "created_at", label: t("common.field.created_at"), minWidth: 180 },
237
+ { prop: "created_at", align: "center", label: t("common.field.created_at"), minWidth: 180 },
238
238
  {
239
239
  prop: "operation",
240
240
  label: t("common.field.operation"),
241
- width: 180,
242
- fixed: "right",
243
241
  cellType: "actions",
244
242
  actions: [
245
243
  {
@@ -57,7 +57,7 @@
57
57
  <div class="migration-list-item__data-source">
58
58
  {{ history.module || t("system.base.migration.value.default_module") }} · {{ history.data_source || "default" }}
59
59
  </div>
60
- <time :datetime="history.created_at">{{ formatDate(history.created_at) }}</time>
60
+ <time :datetime="history.created_at">{{ formatDateTime(history.created_at) }}</time>
61
61
  </button>
62
62
  </div>
63
63
 
@@ -160,6 +160,7 @@ import type {
160
160
  PageBaseMigrationRequest
161
161
  } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_migration";
162
162
  import { getCurrentLocale, t } from "@liujitcn/kratos-admin-core";
163
+ import { formatDateTime } from "@liujitcn/kratos-admin-core/format";
163
164
 
164
165
  defineOptions({
165
166
  name: "BaseMigration",
@@ -296,19 +297,6 @@ async function copySql(sql: string) {
296
297
  }
297
298
  }
298
299
 
299
- /**
300
- * 格式化列表日期。
301
- */
302
- function formatDate(value: string) {
303
- if (!value) return "--";
304
- const date = new Date(value.replace(" ", "T"));
305
- if (Number.isNaN(date.getTime())) return value;
306
- return new Intl.DateTimeFormat(getCurrentLocale(), {
307
- year: "numeric",
308
- month: "short",
309
- day: "numeric"
310
- }).format(date);
311
- }
312
300
 
313
301
  onMounted(() => {
314
302
  loadMigrationHistory();
@@ -235,8 +235,6 @@ const columns = computed<ColumnProps[]>(() => [
235
235
  {
236
236
  prop: "operation",
237
237
  label: t("common.field.operation"),
238
- width: 280,
239
- fixed: "right",
240
238
  cellType: "actions",
241
239
  actions: [
242
240
  {
@@ -20,6 +20,7 @@ import { DEFAULT_TENANT_CODE } from "@liujitcn/kratos-admin-core/tenant";
20
20
  import { useUserStore } from "@liujitcn/kratos-admin-core/stores/runtime";
21
21
  import { useAuthButtons } from "@liujitcn/kratos-admin-core/auth";
22
22
  import { buildPageRequest } from "@liujitcn/kratos-admin-core/table";
23
+ import { formatDateTime } from "@liujitcn/kratos-admin-core/format";
23
24
  import { t } from "@liujitcn/kratos-admin-core";
24
25
  import { defBaseTenantService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_tenant";
25
26
  import { defBaseSessionService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_session";
@@ -49,12 +50,16 @@ const columns = computed<ColumnProps[]>(() => [
49
50
  { prop: "client_ip", label: t("system.base.online_session.field.client_ip"), minWidth: 140 },
50
51
  { prop: "device", label: t("system.base.online_session.field.device"), minWidth: 180 },
51
52
  { prop: "user_agent", label: t("system.base.online_session.field.user_agent"), minWidth: 220 },
52
- { prop: "issued_at", label: t("system.base.online_session.field.issued_at"), minWidth: 180 },
53
+ {
54
+ prop: "issued_at",
55
+ label: t("system.base.online_session.field.issued_at"),
56
+ minWidth: 180,
57
+ align: "center",
58
+ render: scope => formatDateTime((scope.row as BaseSession).issued_at)
59
+ },
53
60
  {
54
61
  prop: "operation",
55
62
  label: t("common.field.operation"),
56
- width: 100,
57
- fixed: "right",
58
63
  cellType: "actions",
59
64
  actions: [
60
65
  {
@@ -6,6 +6,7 @@
6
6
  import { computed, ref } from "vue";
7
7
  import type { ColumnProps } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
8
8
  import { t } from "@liujitcn/kratos-admin-core";
9
+ import { formatLogDateTime } from "@liujitcn/kratos-admin-system/components/log";
9
10
  import { buildPageRequest } from "@liujitcn/kratos-admin-core/table";
10
11
  import LogTable, { type LogTableConfig } from "@liujitcn/kratos-admin-system/components/LogTable.vue";
11
12
  import { logDateSearch, logDetailColumn, logEnumLabel, createLogEnumOptions, requestLogTrace } from "@liujitcn/kratos-admin-system/components/log";
@@ -36,12 +37,12 @@ const actionOptions = computed(() => createLogEnumOptions([
36
37
  ]));
37
38
  const columns = computed<ColumnProps[]>(() => [
38
39
  { prop: "resource_type", label: t("system.base.log.field.resource_type"), minWidth: 150, search: { el: "input" } },
39
- { prop: "resource_id", label: t("system.base.log.field.resource_id"), minWidth: 120 },
40
+ { prop: "resource_id", label: t("system.base.log.field.resource_id"), minWidth: 120, align: "right" },
40
41
  { prop: "resource_name", label: t("system.base.log.field.resource_name"), minWidth: 160 },
41
42
  { prop: "action", label: t("system.base.log.field.action"), minWidth: 110, search: { el: "select", enum: actionOptions.value }, render: scope => logEnumLabel(actionOptions.value, (scope.row as BaseOperationLog).action) },
42
43
  { prop: "result", label: t("system.base.log.field.result"), minWidth: 110, search: { el: "select", enum: resultOptions.value }, render: scope => logEnumLabel(resultOptions.value, (scope.row as BaseOperationLog).result) },
43
44
  { prop: "user_name", label: t("system.base.log.field.user_name"), minWidth: 130 },
44
- { prop: "occurred_at", label: t("system.base.log.field.occurred_at"), minWidth: 190, search: logDateSearch(t) },
45
+ { prop: "occurred_at", label: t("system.base.log.field.occurred_at"), minWidth: 190, align: "center", search: logDateSearch(t) },
45
46
  logDetailColumn(t("common.action.view"), id => page.value?.handleOpenDialog(id))
46
47
  ]);
47
48
 
@@ -68,8 +69,8 @@ const config = computed<LogTableConfig>(() => ({
68
69
  { key: "reason", label: t("system.base.log.field.reason"), span: 2 },
69
70
  { key: "request_id", label: t("system.base.log.field.request_id") },
70
71
  { key: "trace_id", label: t("system.base.log.field.trace_id") },
71
- { key: "occurred_at", label: t("system.base.log.field.occurred_at") },
72
- { key: "created_at", label: t("system.base.log.field.created_at") }
72
+ { key: "occurred_at", format: formatLogDateTime, label: t("system.base.log.field.occurred_at") },
73
+ { key: "created_at", format: formatLogDateTime, label: t("system.base.log.field.created_at") }
73
74
  ],
74
75
  request: requestTable,
75
76
  get: getDetail
@@ -6,6 +6,7 @@
6
6
  import { computed, ref } from "vue";
7
7
  import type { ColumnProps } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
8
8
  import { t } from "@liujitcn/kratos-admin-core";
9
+ import { formatLogDateTime } from "@liujitcn/kratos-admin-system/components/log";
9
10
  import { buildPageRequest } from "@liujitcn/kratos-admin-core/table";
10
11
  import LogTable, { type LogTableConfig } from "@liujitcn/kratos-admin-system/components/LogTable.vue";
11
12
  import { logDateSearch, logDetailColumn, logEnumLabel, createLogEnumOptions, requestLogTrace } from "@liujitcn/kratos-admin-system/components/log";
@@ -46,7 +47,7 @@ const columns = computed<ColumnProps[]>(() => [
46
47
  { prop: "action", label: t("system.base.log.field.action"), minWidth: 110, search: { el: "select", enum: actionOptions.value }, render: scope => logEnumLabel(actionOptions.value, (scope.row as BasePermissionLog).action) },
47
48
  { prop: "result", label: t("system.base.log.field.result"), minWidth: 110, search: { el: "select", enum: resultOptions.value }, render: scope => logEnumLabel(resultOptions.value, (scope.row as BasePermissionLog).result) },
48
49
  { prop: "user_name", label: t("system.base.log.field.user_name"), minWidth: 130 },
49
- { prop: "occurred_at", label: t("system.base.log.field.occurred_at"), minWidth: 190, search: logDateSearch(t) },
50
+ { prop: "occurred_at", label: t("system.base.log.field.occurred_at"), minWidth: 190, align: "center", search: logDateSearch(t) },
50
51
  logDetailColumn(t("common.action.view"), id => page.value?.handleOpenDialog(id))
51
52
  ]);
52
53
 
@@ -72,8 +73,8 @@ const config = computed<LogTableConfig>(() => ({
72
73
  { key: "reason", label: t("system.base.log.field.reason"), span: 2 },
73
74
  { key: "request_id", label: t("system.base.log.field.request_id") },
74
75
  { key: "trace_id", label: t("system.base.log.field.trace_id") },
75
- { key: "occurred_at", label: t("system.base.log.field.occurred_at") },
76
- { key: "created_at", label: t("system.base.log.field.created_at") }
76
+ { key: "occurred_at", format: formatLogDateTime, label: t("system.base.log.field.occurred_at") },
77
+ { key: "created_at", format: formatLogDateTime, label: t("system.base.log.field.created_at") }
77
78
  ],
78
79
  request: requestTable,
79
80
  get: getDetail
@@ -6,6 +6,7 @@
6
6
  import { computed, ref } from "vue";
7
7
  import type { ColumnProps } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
8
8
  import { t } from "@liujitcn/kratos-admin-core";
9
+ import { formatLogDateTime } from "@liujitcn/kratos-admin-system/components/log";
9
10
  import { buildPageRequest } from "@liujitcn/kratos-admin-core/table";
10
11
  import LogTable, { type LogTableConfig } from "@liujitcn/kratos-admin-system/components/LogTable.vue";
11
12
  import {
@@ -42,8 +43,8 @@ const columns = computed<ColumnProps[]>(() => [
42
43
  { prop: "engine", label: t("system.base.log.field.engine"), minWidth: 100 },
43
44
  { prop: "evaluation_type", label: t("system.base.log.field.evaluation_type"), minWidth: 160, search: { el: "select", enum: evaluationTypeOptions.value }, render: scope => logEnumLabel(evaluationTypeOptions.value, (scope.row as BasePolicyEvaluationLog).evaluation_type) },
44
45
  { prop: "decision", label: t("system.base.log.field.decision"), minWidth: 110, search: { el: "select", enum: decisionOptions.value }, render: scope => logEnumLabel(decisionOptions.value, (scope.row as BasePolicyEvaluationLog).decision) },
45
- { prop: "duration_ms", label: t("system.base.log.field.duration_ms"), minWidth: 110 },
46
- { prop: "occurred_at", label: t("system.base.log.field.occurred_at"), minWidth: 190, search: logDateSearch(t) },
46
+ { prop: "duration_ms", label: t("system.base.log.field.duration_ms"), minWidth: 110, align: "right" },
47
+ { prop: "occurred_at", label: t("system.base.log.field.occurred_at"), minWidth: 190, align: "center", search: logDateSearch(t) },
47
48
  logDetailColumn(t("common.action.view"), id => page.value?.handleOpenDialog(id))
48
49
  ]);
49
50
 
@@ -75,8 +76,8 @@ const config = computed<LogTableConfig>(() => ({
75
76
  { key: "client_ip", label: t("system.base.log.field.client_ip") },
76
77
  { key: "request_id", label: t("system.base.log.field.request_id") },
77
78
  { key: "trace_id", label: t("system.base.log.field.trace_id") },
78
- { key: "occurred_at", label: t("system.base.log.field.occurred_at") },
79
- { key: "created_at", label: t("system.base.log.field.created_at") }
79
+ { key: "occurred_at", format: formatLogDateTime, label: t("system.base.log.field.occurred_at") },
80
+ { key: "created_at", format: formatLogDateTime, label: t("system.base.log.field.created_at") }
80
81
  ],
81
82
  request: requestTable,
82
83
  get: getDetail
@@ -210,13 +210,11 @@ const columns = computed<ColumnProps[]>(() => [
210
210
  }
211
211
  },
212
212
  { prop: "remark", label: t("common.field.remark"), minWidth: 160 },
213
- { prop: "created_at", label: t("common.field.created_at"), minWidth: 180 },
214
- { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180 },
213
+ { prop: "created_at", align: "center", label: t("common.field.created_at"), minWidth: 180 },
214
+ { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180, align: "center" },
215
215
  {
216
216
  prop: "operation",
217
217
  label: t("common.field.operation"),
218
- width: 180,
219
- fixed: "right",
220
218
  cellType: "actions",
221
219
  actions: [
222
220
  {
@@ -245,7 +245,7 @@ const columns = computed<ColumnProps[]>(() => [
245
245
  { prop: "mode", label: t("system.base.redact_output_policy.field.mode"), width: 110, enum: modeEnums.value, isFilterEnum: true },
246
246
  { prop: "rule_name", label: t("system.base.redact_output_policy.field.rule"), width: 150 },
247
247
  { prop: "status", label: t("common.field.status"), width: 100, cellType: "status", statusProps: { activeValue: Status.STATUS_ENABLE, inactiveValue: Status.STATUS_DISABLE, activeText: t("common.status.enabled"), inactiveText: t("common.status.disabled"), disabled: () => !BUTTONS.value["base:redact-output-policy:status"], beforeChange: scope => changeStatus(scope.row as BaseRedactOutputPolicy) } },
248
- { prop: "actions", label: t("common.field.operation"), width: 150, fixed: "right", cellType: "actions", actions: [{ label: t("common.action.edit"), type: "primary", link: true, icon: EditPen, hidden: () => !BUTTONS.value["base:redact-output-policy:update"], onClick: scope => openDialog((scope.row as BaseRedactOutputPolicy).id) }, { label: t("common.action.delete"), type: "danger", link: true, icon: Delete, hidden: () => !BUTTONS.value["base:redact-output-policy:delete"], onClick: scope => deleteItems(scope.row as BaseRedactOutputPolicy) }] }
248
+ { prop: "actions", label: t("common.field.operation"), cellType: "actions", actions: [{ label: t("common.action.edit"), type: "primary", link: true, icon: EditPen, hidden: () => !BUTTONS.value["base:redact-output-policy:update"], onClick: scope => openDialog((scope.row as BaseRedactOutputPolicy).id) }, { label: t("common.action.delete"), type: "danger", link: true, icon: Delete, hidden: () => !BUTTONS.value["base:redact-output-policy:delete"], onClick: scope => deleteItems(scope.row as BaseRedactOutputPolicy) }] }
249
249
  ]);
250
250
  const headerActions = computed<HeaderActionProps[]>(() => [{ label: t("common.action.create"), type: "success", icon: CirclePlus, hidden: () => !BUTTONS.value["base:redact-output-policy:create"], onClick: () => openDialog() }, { label: t("common.action.delete"), type: "danger", icon: Delete, hidden: () => !BUTTONS.value["base:redact-output-policy:delete"], disabled: scope => !scope.selectedList.length, onClick: scope => deleteItems(scope.selectedList as BaseRedactOutputPolicy[]) }]);
251
251
 
@@ -189,8 +189,6 @@ const columns = computed<ColumnProps[]>(() => [
189
189
  {
190
190
  prop: "actions",
191
191
  label: t("common.field.operation"),
192
- width: 100,
193
- fixed: "right",
194
192
  cellType: "actions",
195
193
  actions: [{ label: t("common.action.edit"), type: "primary", link: true, icon: EditPen, hidden: () => !BUTTONS.value["base:redact-rule:update"], onClick: scope => openDialog((scope.row as BaseRedactRule).id) }]
196
194
  }
@@ -208,7 +208,7 @@ const columns = computed<ColumnProps[]>(() => [
208
208
  { prop: "column_name", label: t("system.base.redact_storage_policy.field.column_name"), minWidth: 150, search: { el: "input" } },
209
209
  { prop: "rule_name", label: t("system.base.redact_storage_policy.field.rule"), minWidth: 150 },
210
210
  { prop: "status", label: t("common.field.status"), width: 100, cellType: "status", statusProps: { activeValue: Status.STATUS_ENABLE, inactiveValue: Status.STATUS_DISABLE, activeText: t("common.status.enabled"), inactiveText: t("common.status.disabled"), disabled: () => !BUTTONS.value["base:redact-storage-policy:status"], beforeChange: scope => changeStatus(scope.row as BaseRedactStoragePolicy) } },
211
- { prop: "actions", label: t("common.field.operation"), width: 150, fixed: "right", cellType: "actions", actions: [{ label: t("common.action.edit"), type: "primary", link: true, icon: EditPen, hidden: () => !BUTTONS.value["base:redact-storage-policy:update"], onClick: scope => openDialog((scope.row as BaseRedactStoragePolicy).id) }, { label: t("common.action.delete"), type: "danger", link: true, icon: Delete, hidden: () => !BUTTONS.value["base:redact-storage-policy:delete"], onClick: scope => deleteItems(scope.row as BaseRedactStoragePolicy) }] }
211
+ { prop: "actions", label: t("common.field.operation"), cellType: "actions", actions: [{ label: t("common.action.edit"), type: "primary", link: true, icon: EditPen, hidden: () => !BUTTONS.value["base:redact-storage-policy:update"], onClick: scope => openDialog((scope.row as BaseRedactStoragePolicy).id) }, { label: t("common.action.delete"), type: "danger", link: true, icon: Delete, hidden: () => !BUTTONS.value["base:redact-storage-policy:delete"], onClick: scope => deleteItems(scope.row as BaseRedactStoragePolicy) }] }
212
212
  ]);
213
213
  const headerActions = computed<HeaderActionProps[]>(() => [{ label: t("common.action.create"), type: "success", icon: CirclePlus, hidden: () => !BUTTONS.value["base:redact-storage-policy:create"], onClick: () => openDialog() }, { label: t("common.action.delete"), type: "danger", icon: Delete, hidden: () => !BUTTONS.value["base:redact-storage-policy:delete"], disabled: scope => !scope.selectedList.length, onClick: scope => deleteItems(scope.selectedList as BaseRedactStoragePolicy[]) }]);
214
214
 
@@ -339,13 +339,11 @@ const columns = computed<ColumnProps[]>(() => [
339
339
  beforeChange: scope => handleBeforeSetStatus(scope.row as BaseRole)
340
340
  }
341
341
  },
342
- { prop: "created_at", label: t("common.field.created_at"), minWidth: 180 },
343
- { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180 },
342
+ { prop: "created_at", align: "center", label: t("common.field.created_at"), minWidth: 180 },
343
+ { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180, align: "center" },
344
344
  {
345
345
  prop: "operation",
346
346
  label: t("common.field.action"),
347
- width: 280,
348
- fixed: "right",
349
347
  cellType: "actions",
350
348
  actions: [
351
349
  {
@@ -182,13 +182,11 @@ const columns = computed<ColumnProps[]>(() => [
182
182
  beforeChange: scope => handleBeforeSetStatus(scope.row as BaseTenant)
183
183
  }
184
184
  },
185
- { prop: "created_at", label: t("common.field.created_at"), minWidth: 180 },
186
- { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180 },
185
+ { prop: "created_at", align: "center", label: t("common.field.created_at"), minWidth: 180 },
186
+ { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180, align: "center" },
187
187
  {
188
188
  prop: "operation",
189
189
  label: t("common.field.operation"),
190
- width: 150,
191
- fixed: "right",
192
190
  cellType: "actions",
193
191
  actions: [
194
192
  {
@@ -516,13 +516,11 @@ const columns = computed<ColumnProps[]>(() => [
516
516
  }
517
517
  },
518
518
  { prop: "remark", label: t("common.field.remark"), minWidth: 160 },
519
- { prop: "created_at", label: t("common.field.created_at"), minWidth: 180 },
520
- { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180 },
519
+ { prop: "created_at", align: "center", label: t("common.field.created_at"), minWidth: 180 },
520
+ { prop: "updated_at", label: t("common.field.updated_at"), minWidth: 180, align: "center" },
521
521
  {
522
522
  prop: "operation",
523
523
  label: t("common.field.action"),
524
- width: 260,
525
- fixed: "right",
526
524
  cellType: "actions",
527
525
  actions: [
528
526
  {
@@ -121,8 +121,6 @@ const columns = computed<ColumnProps[]>(() => [
121
121
  {
122
122
  prop: "operation",
123
123
  label: t("common.field.operation"),
124
- width: 250,
125
- fixed: "right",
126
124
  cellType: "actions",
127
125
  actions: [
128
126
  { label: t("common.action.view"), link: true, icon: View, onClick: scope => openDetail(scope.row as Notification) },
@@ -64,7 +64,7 @@
64
64
  </div>
65
65
  <div class="detail-item detail-item--wide">
66
66
  <span class="detail-label">{{ t("common.field.created_at") }}</span>
67
- <span class="detail-value">{{ profile.created_at || "--" }}</span>
67
+ <span class="detail-value">{{ formatDateTime(profile.created_at) }}</span>
68
68
  </div>
69
69
  </div>
70
70
  </div>
@@ -91,6 +91,7 @@
91
91
  <script setup lang="ts">
92
92
  import { computed, reactive, ref, watch } from "vue";
93
93
  import { t } from "@liujitcn/kratos-admin-core";
94
+ import { formatDateTime } from "@liujitcn/kratos-admin-core/format";
94
95
  import { defProfileAuthService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/auth";
95
96
  import type { UserProfileForm } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/auth";
96
97
  import { BaseUserIDType } from "@liujitcn/kratos-admin-system/rpc/system/common/v1/common";
@@ -44,7 +44,7 @@ const resultOptions = computed<Array<[number, string]>>(() => [
44
44
  [BaseLogResult.BASE_LOG_RESULT_ERROR, t("system.base.log.result.error")]
45
45
  ]);
46
46
  const columns = computed<ColumnProps[]>(() => [
47
- { prop: "occurred_at", label: t("system.profile.login_log.field.occurred_at"), minWidth: 180 },
47
+ { prop: "occurred_at", label: t("system.profile.login_log.field.occurred_at"), minWidth: 180, align: "center" },
48
48
  {
49
49
  prop: "login_type",
50
50
  label: t("system.profile.login_log.field.login_type"),
@@ -58,7 +58,7 @@ const columns = computed<ColumnProps[]>(() => [
58
58
  render: scope => enumLabel(resultOptions.value, (scope.row as BaseLoginLog).result)
59
59
  },
60
60
  { prop: "client_ip", label: t("system.profile.login_log.field.client_ip"), minWidth: 140 },
61
- { prop: "device_id", label: t("system.profile.login_log.field.device_id"), minWidth: 160 },
61
+ { prop: "device_id", label: t("system.profile.login_log.field.device_id"), minWidth: 160, align: "right" },
62
62
  { prop: "reason", label: t("system.profile.login_log.field.reason"), minWidth: 180 }
63
63
  ]);
64
64
 
@@ -30,6 +30,7 @@ import type { ColumnProps, ProTableInstance } from "@liujitcn/kratos-admin-core/
30
30
  import { useRouter } from "vue-router";
31
31
  import { t } from "@liujitcn/kratos-admin-core";
32
32
  import { LOGIN_URL } from "@liujitcn/kratos-admin-core/config";
33
+ import { formatDateTime } from "@liujitcn/kratos-admin-core/format";
33
34
  import { useUserStore } from "@liujitcn/kratos-admin-core/stores/runtime";
34
35
  import { defBaseSessionService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_session";
35
36
  import type { BaseSession } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_session";
@@ -52,7 +53,13 @@ const columns = computed<ColumnProps[]>(() => [
52
53
  },
53
54
  { prop: "client_ip", label: t("system.profile.session.field.client_ip"), minWidth: 140 },
54
55
  { prop: "device", label: t("system.profile.session.field.device"), minWidth: 200 },
55
- { prop: "issued_at", label: t("system.profile.session.field.issued_at"), minWidth: 180 },
56
+ {
57
+ prop: "issued_at",
58
+ label: t("system.profile.session.field.issued_at"),
59
+ minWidth: 180,
60
+ align: "center",
61
+ render: scope => formatDateTime((scope.row as BaseSession).issued_at)
62
+ },
56
63
  {
57
64
  prop: "expires_in",
58
65
  label: t("system.profile.session.field.expires_in"),
@@ -46,6 +46,7 @@ import ProTable from "@liujitcn/kratos-admin-core/components/ProTable";
46
46
  import ProDialog from "@liujitcn/kratos-admin-core/components/Dialog/ProDialog.vue";
47
47
  import type { ColumnProps, ProTableInstance } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
48
48
  import { buildPageRequest } from "@liujitcn/kratos-admin-core/table";
49
+ import { formatDateTime } from "@liujitcn/kratos-admin-core/format";
49
50
  import { t } from "@liujitcn/kratos-admin-core";
50
51
  import RichTextPreview from "@liujitcn/kratos-admin-core/components/RichTextPreview/index.vue";
51
52
  import { defCacheService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/cache";
@@ -114,31 +115,33 @@ const columns = computed<ColumnProps[]>(() => [
114
115
  prop: "ttl_seconds",
115
116
  label: t("system.cache.field.ttl"),
116
117
  width: 130,
118
+ align: "right",
117
119
  render: scope => formatTtl((scope.row as CacheEntry).ttl_seconds)
118
120
  },
119
121
  {
120
122
  prop: "expires_at",
121
123
  label: t("system.cache.field.expires_at"),
122
124
  minWidth: 185,
123
- render: scope => formatDate(scope.row.expires_at)
125
+ align: "center",
126
+ render: scope => formatDateTime(scope.row.expires_at)
124
127
  },
125
128
  {
126
129
  prop: "created_at",
127
130
  label: t("system.cache.field.created_at"),
128
131
  minWidth: 185,
129
- render: scope => formatDate(scope.row.created_at)
132
+ align: "center",
133
+ render: scope => formatDateTime(scope.row.created_at)
130
134
  },
131
135
  {
132
136
  prop: "updated_at",
137
+ align: "center",
133
138
  label: t("system.cache.field.updated_at"),
134
139
  minWidth: 185,
135
- render: scope => formatDate(scope.row.updated_at)
140
+ render: scope => formatDateTime(scope.row.updated_at)
136
141
  },
137
142
  {
138
143
  prop: "operation",
139
144
  label: t("common.field.operation"),
140
- width: 90,
141
- fixed: "right",
142
145
  cellType: "actions",
143
146
  actions: [
144
147
  {
@@ -237,12 +240,6 @@ function formatTtl(ttl: number) {
237
240
  return `${Math.floor(ttl / 3600)}h ${Math.floor((ttl % 3600) / 60)}m`;
238
241
  }
239
242
 
240
- /** 格式化时间字段。 */
241
- function formatDate(value: string) {
242
- if (!value) return "-";
243
- const date = new Date(value);
244
- return Number.isNaN(date.getTime()) ? value : date.toLocaleString();
245
- }
246
243
  </script>
247
244
 
248
245
  <style lang="scss" scoped>
@@ -107,7 +107,8 @@
107
107
  <script setup lang="ts">
108
108
  import { onBeforeUnmount, ref, watch } from "vue";
109
109
  import { Check, CircleClose, Clock, CopyDocument, Document, Loading, Minus } from "@element-plus/icons-vue";
110
- import { getCurrentLocale, t } from "@liujitcn/kratos-admin-core";
110
+ import { t } from "@liujitcn/kratos-admin-core";
111
+ import { formatDateTime } from "@liujitcn/kratos-admin-core/format";
111
112
  import ProDialog from "@liujitcn/kratos-admin-core/components/Dialog/ProDialog.vue";
112
113
  import { defCodeGenService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/code_gen";
113
114
  import { subscribeCodeGenProgress, type SseStop } from "../../../../utils/code_gen_sse";
@@ -236,8 +237,7 @@ function isFinished(status: CodeGenTaskStatus) {
236
237
 
237
238
  /** 格式化任务时间。 */
238
239
  function formatTime(value: string) {
239
- const date = new Date(value);
240
- return !value || Number.isNaN(date.getTime()) ? "-" : date.toLocaleString(getCurrentLocale());
240
+ return formatDateTime(value);
241
241
  }
242
242
 
243
243
  /** 弹出展示命令输出。 */
@@ -262,8 +262,6 @@ const tableColumns = computed<ColumnProps[]>(() => {
262
262
  result.push({
263
263
  prop: "operation",
264
264
  label: t("common.field.operation"),
265
- width: actions.length === 1 ? 100 : 180,
266
- fixed: "right",
267
265
  cellType: "actions",
268
266
  actions
269
267
  });
@@ -461,12 +461,10 @@ const columns = computed<ColumnProps[]>(() => [
461
461
  search: { el: "select" }
462
462
  },
463
463
  { prop: "remark", label: t("system.code.gen.table.field.remark"), minWidth: 180, showOverflowTooltip: true },
464
- { prop: "created_at", label: t("system.code.gen.table.field.created_at"), minWidth: 180 },
464
+ { prop: "created_at", label: t("system.code.gen.table.field.created_at"), minWidth: 180, align: "center" },
465
465
  {
466
466
  prop: "operation",
467
467
  label: t("common.field.operation"),
468
- width: 660,
469
- fixed: "right",
470
468
  cellType: "actions",
471
469
  actions: [
472
470
  {
@@ -151,10 +151,10 @@
151
151
  ><code class="ops-route">{{ row.route }}</code></template
152
152
  >
153
153
  </el-table-column>
154
- <el-table-column prop="qps" label="QPS" width="75" />
155
- <el-table-column prop="latency" label="P95" width="85" />
156
- <el-table-column prop="errorRate" :label="t('system.ops_monitoring.error_rate')" width="85" />
157
- <el-table-column :label="t('system.ops_monitoring.status.label')" width="85" align="right">
154
+ <el-table-column prop="qps" label="QPS" width="75" align="right" />
155
+ <el-table-column prop="latency" label="P95" width="85" align="right" />
156
+ <el-table-column prop="errorRate" :label="t('system.ops_monitoring.error_rate')" width="85" align="right" />
157
+ <el-table-column :label="t('system.ops_monitoring.status.label')" width="85" align="center">
158
158
  <template #default="{ row }"
159
159
  ><el-tag :type="row.healthy ? 'success' : 'warning'" size="small" effect="plain">{{ row.status }}</el-tag></template
160
160
  >
@@ -178,7 +178,8 @@
178
178
  <script setup lang="ts">
179
179
  import { Document, Download, Operation, Refresh, Search, VideoPause, VideoPlay } from "@element-plus/icons-vue";
180
180
  import { computed, nextTick, onActivated, onBeforeUnmount, onDeactivated, onMounted, ref, watch } from "vue";
181
- import { getCurrentLocale, t } from "@liujitcn/kratos-admin-core";
181
+ import { t } from "@liujitcn/kratos-admin-core";
182
+ import { formatDateTime } from "@liujitcn/kratos-admin-core/format";
182
183
  import { defRuntimeLogService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/runtime_log";
183
184
  import { subscribeRuntimeLog } from "../../../utils/runtime_log_sse";
184
185
  import type {
@@ -450,18 +451,6 @@ function formatFileSize(rawBytes: number) {
450
451
  return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
451
452
  }
452
453
 
453
- /** 格式化日志文件时间。 */
454
- function formatDateTime(value: string) {
455
- if (!value) return "-";
456
- const date = new Date(value);
457
- if (Number.isNaN(date.getTime())) return value;
458
- return new Intl.DateTimeFormat(getCurrentLocale(), {
459
- month: "2-digit",
460
- day: "2-digit",
461
- hour: "2-digit",
462
- minute: "2-digit"
463
- }).format(date);
464
- }
465
454
 
466
455
  watch([keyword, selectedLevels], () => {
467
456
  if (!activeFile.value) return;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@liujitcn/kratos-admin-system",
3
3
  "private": false,
4
- "version": "0.0.46",
4
+ "version": "0.0.48",
5
5
  "type": "module",
6
6
  "description": "kratos-admin system management module",
7
7
  "license": "MIT",
@@ -14,9 +14,9 @@
14
14
  "@lucide/vue": "^1.39.0",
15
15
  "@microsoft/fetch-event-source": "^2.0.1",
16
16
  "sortablejs": "^1.15.2",
17
- "swagger-ui-dist": "^5.32.9",
17
+ "swagger-ui-dist": "^5.32.15",
18
18
  "vue-element-plus-x": "^2.0.3",
19
- "@liujitcn/kratos-admin-core": "0.0.46"
19
+ "@liujitcn/kratos-admin-core": "0.0.48"
20
20
  },
21
21
  "peerDependencies": {
22
22
  "@element-plus/icons-vue": "^2.3.1",