@liujitcn/kratos-admin-system 0.0.26 → 0.0.28

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 (71) hide show
  1. package/dist/package/declarations/src/api/system/base_i18n.d.ts +10 -0
  2. package/dist/package/declarations/src/api/system/code_gen_i18n.d.ts +1 -1
  3. package/dist/package/declarations/src/api/system/runtime_log.d.ts +13 -0
  4. package/dist/package/declarations/src/api/system/runtime_log_sse.d.ts +8 -0
  5. package/dist/package/declarations/src/components/DynamicTranslationCell.vue.d.ts +3 -3
  6. package/dist/package/declarations/src/components/dynamicTranslation.d.ts +1 -1
  7. package/dist/package/declarations/src/locales/generated.d.ts +1057 -0
  8. package/dist/package/declarations/src/rpc/common/v1/enum.d.ts +15 -6
  9. package/dist/package/declarations/src/rpc/system/admin/v1/base_api.d.ts +10 -1
  10. package/dist/package/declarations/src/rpc/system/admin/v1/base_config.d.ts +4 -4
  11. package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +5 -5
  12. package/dist/package/declarations/src/rpc/system/admin/v1/{base_translation.d.ts → base_i18n.d.ts} +3 -3
  13. package/dist/package/declarations/src/rpc/system/admin/v1/base_menu.d.ts +3 -3
  14. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_column.d.ts +1 -1
  15. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_table.d.ts +1 -1
  16. package/dist/package/declarations/src/rpc/system/admin/v1/ops_monitoring.d.ts +4 -0
  17. package/dist/package/declarations/src/rpc/system/admin/v1/project_document.d.ts +6 -0
  18. package/dist/package/declarations/src/rpc/system/admin/v1/runtime_log.d.ts +96 -0
  19. package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue.d.ts +1 -1
  20. package/dist/package/declarations/src/views/tool/runtime-log/index.vue.d.ts +3 -0
  21. package/dist/package/src/api/base/sse.ts +3 -2
  22. package/dist/package/src/api/system/{base_translation.ts → base_i18n.ts} +5 -5
  23. package/dist/package/src/api/system/code_gen_i18n.ts +1 -1
  24. package/dist/package/src/api/system/runtime_log.ts +80 -0
  25. package/dist/package/src/api/system/runtime_log_sse.ts +40 -0
  26. package/dist/package/src/components/Ai.vue +9 -2
  27. package/dist/package/src/components/DynamicTranslationCell.vue +9 -9
  28. package/dist/package/src/components/DynamicTranslationEditor.vue +3 -3
  29. package/dist/package/src/components/dynamicTranslation.ts +1 -1
  30. package/dist/package/src/locales/en-US.json +33 -2
  31. package/dist/package/src/locales/generated.ts +2 -0
  32. package/dist/package/src/locales/ja-JP.json +964 -0
  33. package/dist/package/src/locales/zh-CN.json +33 -2
  34. package/dist/package/src/locales/zh-TW.json +33 -2
  35. package/dist/package/src/rpc/common/v1/enum.ts +16 -6
  36. package/dist/package/src/rpc/system/admin/v1/base_api.ts +11 -1
  37. package/dist/package/src/rpc/system/admin/v1/base_config.ts +4 -4
  38. package/dist/package/src/rpc/system/admin/v1/base_dict.ts +5 -5
  39. package/dist/package/src/rpc/system/admin/v1/{base_translation.ts → base_i18n.ts} +4 -4
  40. package/dist/package/src/rpc/system/admin/v1/base_menu.ts +3 -3
  41. package/dist/package/src/rpc/system/admin/v1/code_gen_column.ts +1 -1
  42. package/dist/package/src/rpc/system/admin/v1/code_gen_table.ts +1 -1
  43. package/dist/package/src/rpc/system/admin/v1/ops_monitoring.ts +4 -0
  44. package/dist/package/src/rpc/system/admin/v1/project_document.ts +6 -0
  45. package/dist/package/src/rpc/system/admin/v1/runtime_log.ts +113 -0
  46. package/dist/package/src/views/ai/chat/message.ts +12 -2
  47. package/dist/package/src/views/base/api/index.vue +20 -20
  48. package/dist/package/src/views/base/config/index.vue +11 -11
  49. package/dist/package/src/views/base/dept/index.vue +8 -8
  50. package/dist/package/src/views/base/dict/index.vue +9 -9
  51. package/dist/package/src/views/base/dict/item.vue +9 -9
  52. package/dist/package/src/views/base/job/index.vue +11 -11
  53. package/dist/package/src/views/base/language/index.vue +9 -9
  54. package/dist/package/src/views/base/menu/index.vue +14 -9
  55. package/dist/package/src/views/base/post/index.vue +8 -8
  56. package/dist/package/src/views/base/role/index.vue +8 -8
  57. package/dist/package/src/views/base/tenant/index.vue +8 -8
  58. package/dist/package/src/views/base/user/index.vue +8 -8
  59. package/dist/package/src/views/tool/api-doc/index.vue +14 -6
  60. package/dist/package/src/views/tool/code-gen/code-preview/index.vue +17 -0
  61. package/dist/package/src/views/tool/code-gen/columns/index.vue +8 -53
  62. package/dist/package/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue +97 -15
  63. package/dist/package/src/views/tool/code-gen/components/CodeGenProgressDialog.vue +3 -12
  64. package/dist/package/src/views/tool/code-gen/preview/index.vue +3 -6
  65. package/dist/package/src/views/tool/code-gen/proto/index.vue +7 -8
  66. package/dist/package/src/views/tool/code-gen/table/index.vue +34 -2
  67. package/dist/package/src/views/tool/ops-monitoring/index.vue +153 -49
  68. package/dist/package/src/views/tool/project-doc/index.vue +9 -4
  69. package/dist/package/src/views/tool/runtime-log/index.vue +883 -0
  70. package/package.json +2 -2
  71. package/dist/package/declarations/src/api/system/base_translation.d.ts +0 -10
@@ -87,7 +87,7 @@
87
87
  <ProDialog
88
88
  v-model="configDialog.visible"
89
89
  :title="configDialogTitle"
90
- width="min(520px, calc(100vw - 32px))"
90
+ width="520px"
91
91
  destroy-on-close
92
92
  :show-close="false"
93
93
  :close-on-click-modal="false"
@@ -599,7 +599,6 @@ onMounted(() => {
599
599
  border-radius: var(--admin-page-radius);
600
600
  box-shadow: var(--admin-page-shadow);
601
601
  }
602
-
603
602
  .code-gen-config-dialog__header {
604
603
  display: flex;
605
604
  gap: 12px;
@@ -607,7 +606,6 @@ onMounted(() => {
607
606
  justify-content: space-between;
608
607
  width: 100%;
609
608
  }
610
-
611
609
  :deep(.code-gen-toolbar) {
612
610
  display: flex;
613
611
  flex-wrap: wrap;
@@ -667,6 +665,7 @@ onMounted(() => {
667
665
  flex-wrap: wrap;
668
666
  gap: 8px;
669
667
  align-items: center;
668
+
670
669
  /* 多行单元格与列标题保持居中,避免文本继承居中而 Flex 子项贴左。 */
671
670
  justify-content: center;
672
671
  min-width: 0;
@@ -693,14 +692,14 @@ onMounted(() => {
693
692
  flex-direction: column;
694
693
  gap: 2px;
695
694
  min-width: 0;
696
- cursor: pointer;
697
695
  text-align: left;
696
+ cursor: pointer;
698
697
  }
699
698
  .code-gen-proto-capability-trigger__comment {
700
699
  overflow: hidden;
701
700
  text-overflow: ellipsis;
702
- white-space: nowrap;
703
701
  color: var(--admin-page-text-primary);
702
+ white-space: nowrap;
704
703
  }
705
704
  .code-gen-proto-capability-popover {
706
705
  display: flex;
@@ -709,8 +708,8 @@ onMounted(() => {
709
708
  }
710
709
  .code-gen-proto-capability-popover__preview {
711
710
  max-width: 100%;
712
- margin: 0;
713
711
  padding: 10px;
712
+ margin: 0;
714
713
  overflow-x: auto;
715
714
  font-size: 12px;
716
715
  line-height: 18px;
@@ -730,8 +729,8 @@ onMounted(() => {
730
729
  }
731
730
  .code-gen-proto-capability-popover__item code {
732
731
  min-width: 0;
733
- overflow-wrap: anywhere;
734
732
  color: var(--admin-page-text-primary);
733
+ overflow-wrap: anywhere;
735
734
  }
736
735
  .code-gen-proto-capability-popover__item .code-gen-proto-capability-popover__path {
737
736
  display: block;
@@ -742,8 +741,8 @@ onMounted(() => {
742
741
  }
743
742
  .code-gen-proto-capability-popover__value {
744
743
  min-width: 0;
745
- overflow-wrap: anywhere;
746
744
  color: var(--admin-page-text-primary);
745
+ overflow-wrap: anywhere;
747
746
  }
748
747
  .code-gen-proto-config-form :deep(.el-select) {
749
748
  width: 100%;
@@ -15,7 +15,8 @@
15
15
  v-model="dialog.visible"
16
16
  ref="formDialogRef"
17
17
  :title="dialogTitle"
18
- width="min(920px, calc(100vw - 32px))"
18
+ width="920px"
19
+ label-width="240px"
19
20
  top="4vh"
20
21
  :model="formData"
21
22
  :fields="formFields"
@@ -587,6 +588,38 @@ async function handleGenerate(selected: CodeGenGenerateTarget) {
587
588
  ElMessage.warning(t("system.code.gen.table.message.disabled", { name: disabledTable.name }));
588
589
  return;
589
590
  }
591
+ generating.value = true;
592
+ let missingTranslations: string[] = [];
593
+ try {
594
+ const previewEntries = await Promise.all(
595
+ tables.map(async table => ({
596
+ table,
597
+ preview: await defCodeGenService.PreviewCodeGen({ table_id: table.id, output_paths: undefined })
598
+ }))
599
+ );
600
+ missingTranslations = previewEntries.flatMap(({ table, preview }) =>
601
+ (preview.missing_translations ?? []).map(item => (tables.length === 1 ? item : `${table.name}: ${item}`))
602
+ );
603
+ } finally {
604
+ generating.value = false;
605
+ }
606
+ if (missingTranslations.length) {
607
+ try {
608
+ await ElMessageBox.alert(
609
+ t("system.code.gen.preview.message.missing_translations", {
610
+ items: missingTranslations.join(t("system.code.gen.preview.value.list_separator"))
611
+ }),
612
+ t("common.title.warning"),
613
+ {
614
+ confirmButtonText: t("common.action.close"),
615
+ type: "warning"
616
+ }
617
+ );
618
+ } catch {
619
+ // 关闭提示框与点击关闭按钮语义一致。
620
+ }
621
+ return;
622
+ }
590
623
  const message =
591
624
  tables.length === 1
592
625
  ? t("system.code.gen.table.dialog.generate_one", { name: tables[0].name })
@@ -936,7 +969,6 @@ function ensureLeftTreeConfig() {
936
969
  /* 固定操作列表头与普通表头使用同一主题背景,并保持行内操作单行展示。 */
937
970
  :deep(.code-gen-table) {
938
971
  --el-table-header-bg-color: var(--el-fill-color-light);
939
-
940
972
  td.el-table-fixed-column--right .cell {
941
973
  white-space: nowrap;
942
974
  }
@@ -189,10 +189,22 @@
189
189
  <code>{{ node.name }}</code>
190
190
  <div class="ops-node-meters">
191
191
  <div v-for="metric in node.metrics" :key="metric.label" class="ops-meter">
192
- <span>{{ metric.label }}</span
193
- ><el-progress :percentage="metric.value" :show-text="false" :color="metric.color" /><strong
194
- >{{ metric.value }}%</strong
195
- >
192
+ <div class="ops-meter-head">
193
+ <span class="ops-meter-label">{{ metric.label }}</span>
194
+ <span class="ops-meter-stats">
195
+ <span>
196
+ {{ t("system.ops_monitoring.node_metric.current") }} {{ metric.usedLabel }} /
197
+ {{ t("system.ops_monitoring.node_metric.total") }} {{ metric.totalLabel }}
198
+ </span>
199
+ <strong>{{ metric.percentageLabel }}</strong>
200
+ </span>
201
+ </div>
202
+ <el-progress
203
+ :percentage="metric.percentage"
204
+ :show-text="false"
205
+ :stroke-width="10"
206
+ :color="metric.color"
207
+ />
196
208
  </div>
197
209
  </div>
198
210
  </div>
@@ -225,15 +237,8 @@
225
237
  </template>
226
238
 
227
239
  <script setup lang="ts">
228
- import { computed, onBeforeUnmount, onMounted, ref } from "vue";
240
+ import { computed, onActivated, onBeforeUnmount, onDeactivated, onMounted, ref } from "vue";
229
241
  import { defOpsMonitoringService } from "@liujitcn/kratos-admin-system/api/system/ops_monitoring";
230
- import {
231
- subscribeOpsMonitoringNodes,
232
- subscribeOpsMonitoringServices,
233
- subscribeOpsMonitoringStorage,
234
- subscribeOpsMonitoringTraffic,
235
- type OpsMonitoringSseStop
236
- } from "@liujitcn/kratos-admin-system/api/system/ops_monitoring_sse";
237
242
  import { getCurrentLocale, t } from "@liujitcn/kratos-admin-core";
238
243
  import type {
239
244
  OpsAlert,
@@ -285,12 +290,28 @@ interface EndpointItem {
285
290
  healthy: boolean;
286
291
  }
287
292
 
288
- /** 实例资源指标。 */
293
+ /** 实例资源单项指标。 */
294
+ interface NodeMetricItem {
295
+ /** 指标名称。 */
296
+ label: string;
297
+ /** 指标使用百分比。 */
298
+ percentage: number;
299
+ /** 两位小数百分比。 */
300
+ percentageLabel: string;
301
+ /** 当前已用容量。 */
302
+ usedLabel: string;
303
+ /** 总容量。 */
304
+ totalLabel: string;
305
+ /** 进度条颜色。 */
306
+ color: string;
307
+ }
308
+
309
+ /** 实例资源信息。 */
289
310
  interface NodeItem {
290
311
  /** 实例名称。 */
291
312
  name: string;
292
313
  /** 实例资源指标。 */
293
- metrics: Array<{ label: string; value: number; color: string }>;
314
+ metrics: NodeMetricItem[];
294
315
  }
295
316
 
296
317
  /** 折线图中的流量趋势点。 */
@@ -341,6 +362,12 @@ const alerts = ref<OpsAlertsResponse>();
341
362
  const windowMinutes = ref(15);
342
363
  const lastCollectedAt = ref("");
343
364
  const trendGridLines = [16, 62, 108, 154, 198];
365
+ const nodeMetricLabelKeys: Record<string, string> = {
366
+ 堆内存: "system.ops_monitoring.node_metric.heap_memory",
367
+ 内存: "system.ops_monitoring.node_metric.memory",
368
+ 硬盘: "system.ops_monitoring.node_metric.disk"
369
+ };
370
+ const byteUnits = ["B", "KB", "MB", "GB", "TB", "PB"];
344
371
  const trafficSummary = computed(() => traffic.value?.traffic);
345
372
 
346
373
  const kpiItems = computed<KpiItem[]>(() => [
@@ -438,7 +465,9 @@ const alertItems = computed(() => (alerts.value?.alerts ?? []).map(mapAlert));
438
465
  const serviceCount = computed(() => availabilityItems.value.length);
439
466
  const onlineCount = computed(() => availabilityItems.value.filter(item => item.tone === "ok").length);
440
467
 
441
- let sseStops: OpsMonitoringSseStop[] = [];
468
+ let monitoringTimer: number | undefined;
469
+ let monitoringActive = false;
470
+ let monitoringRun = 0;
442
471
 
443
472
  async function loadMonitoring() {
444
473
  loading.value = true;
@@ -495,18 +524,23 @@ function updateCollectedAt(value?: string) {
495
524
  if (value) lastCollectedAt.value = value;
496
525
  }
497
526
 
498
- function subscribeRealtime() {
499
- sseStops = [
500
- subscribeOpsMonitoringTraffic(setTraffic),
501
- subscribeOpsMonitoringServices(setServices),
502
- subscribeOpsMonitoringStorage(setStorage),
503
- subscribeOpsMonitoringNodes(setNodes)
504
- ];
527
+ async function startMonitoring() {
528
+ if (monitoringActive) return;
529
+ monitoringActive = true;
530
+ const run = ++monitoringRun;
531
+ await loadMonitoring();
532
+ if (!monitoringActive || run !== monitoringRun) return;
533
+ monitoringTimer = window.setInterval(() => {
534
+ if (!loading.value) void loadMonitoring();
535
+ }, 5000);
505
536
  }
506
537
 
507
- function stopRealtime() {
508
- sseStops.forEach(stop => stop());
509
- sseStops = [];
538
+ function stopMonitoring() {
539
+ monitoringActive = false;
540
+ monitoringRun += 1;
541
+ if (monitoringTimer === undefined) return;
542
+ window.clearInterval(monitoringTimer);
543
+ monitoringTimer = undefined;
510
544
  }
511
545
 
512
546
  function formatNumber(value?: number) {
@@ -579,14 +613,46 @@ function mapEndpoint(endpoint: OpsEndpoint): EndpointItem {
579
613
  function mapNode(node: OpsNode): NodeItem {
580
614
  return {
581
615
  name: node.name,
582
- metrics: (node.metrics ?? []).map(metric => ({
583
- label: metric.label,
584
- value: Math.max(0, Math.min(metric.value, 100)),
585
- color: metric.value >= 70 ? "var(--el-color-warning)" : "var(--el-color-primary)"
586
- }))
616
+ metrics: (node.metrics ?? []).map(metric => {
617
+ const percentage = Math.max(0, Math.min(metric.value, 100));
618
+ return {
619
+ label: translateNodeMetricLabel(metric.label),
620
+ percentage,
621
+ percentageLabel: `${formatFixedNumber(percentage)}%`,
622
+ usedLabel: formatBytes(metric.used_bytes),
623
+ totalLabel: formatBytes(metric.total_bytes),
624
+ color: percentage >= 70 ? "var(--el-color-warning)" : "var(--el-color-primary)"
625
+ };
626
+ })
587
627
  };
588
628
  }
589
629
 
630
+ /** 将字节数格式化为保留两位小数的可读容量。 */
631
+ function formatBytes(value: number) {
632
+ if (!Number.isFinite(value) || value < 0) return "--";
633
+ let unitIndex = 0;
634
+ let displayValue = value;
635
+ while (displayValue >= 1024 && unitIndex < byteUnits.length - 1) {
636
+ displayValue /= 1024;
637
+ unitIndex += 1;
638
+ }
639
+ return `${formatFixedNumber(displayValue)} ${byteUnits[unitIndex]}`;
640
+ }
641
+
642
+ /** 将数值格式化为固定两位小数。 */
643
+ function formatFixedNumber(value: number) {
644
+ return new Intl.NumberFormat(getCurrentLocale(), {
645
+ minimumFractionDigits: 2,
646
+ maximumFractionDigits: 2
647
+ }).format(value);
648
+ }
649
+
650
+ /** 翻译实例资源指标名称,未知指标保留后端原值。 */
651
+ function translateNodeMetricLabel(label: string) {
652
+ const localeKey = nodeMetricLabelKeys[label];
653
+ return localeKey ? t(localeKey) : label;
654
+ }
655
+
590
656
  function mapAlert(alert: OpsAlert) {
591
657
  return {
592
658
  title: alert.title,
@@ -596,12 +662,10 @@ function mapAlert(alert: OpsAlert) {
596
662
  };
597
663
  }
598
664
 
599
- onMounted(async () => {
600
- await loadMonitoring();
601
- subscribeRealtime();
602
- });
603
-
604
- onBeforeUnmount(stopRealtime);
665
+ onMounted(startMonitoring);
666
+ onActivated(startMonitoring);
667
+ onDeactivated(stopMonitoring);
668
+ onBeforeUnmount(stopMonitoring);
605
669
  </script>
606
670
 
607
671
  <style scoped lang="scss">
@@ -656,6 +720,7 @@ onBeforeUnmount(stopRealtime);
656
720
  .ops-panel,
657
721
  .ops-storage-card,
658
722
  .ops-alert-panel {
723
+ min-width: 0;
659
724
  background: var(--ops-card-bg);
660
725
  border: 1px solid var(--ops-card-border);
661
726
  border-radius: var(--admin-page-radius);
@@ -936,7 +1001,7 @@ onBeforeUnmount(stopRealtime);
936
1001
  margin-bottom: 12px;
937
1002
  }
938
1003
  .ops-storage-grid {
939
- grid-template-columns: repeat(2, minmax(0, 1fr));
1004
+ grid-template-columns: minmax(0, 1.4fr) minmax(280px, 0.9fr);
940
1005
  }
941
1006
  .ops-storage-card {
942
1007
  min-width: 0;
@@ -1042,37 +1107,70 @@ onBeforeUnmount(stopRealtime);
1042
1107
  .ops-node-list {
1043
1108
  display: grid;
1044
1109
  gap: 16px;
1110
+ min-width: 0;
1045
1111
  padding-top: 3px;
1046
1112
  }
1047
1113
  .ops-node-row {
1048
1114
  display: grid;
1049
- grid-template-columns: 95px minmax(0, 1fr);
1050
- gap: 10px;
1051
- align-items: center;
1115
+ grid-template-columns: minmax(110px, 0.24fr) minmax(0, 1fr);
1116
+ gap: 18px;
1117
+ align-items: start;
1118
+ min-width: 0;
1052
1119
  }
1053
1120
  .ops-node-row > code {
1121
+ overflow: hidden;
1054
1122
  font-family: var(--el-font-family-monospace);
1055
1123
  font-size: 11px;
1056
1124
  color: var(--ops-text-secondary);
1125
+ text-overflow: ellipsis;
1126
+ white-space: nowrap;
1057
1127
  }
1058
1128
  .ops-node-meters {
1059
1129
  display: grid;
1060
- gap: 7px;
1130
+ gap: 13px;
1131
+ min-width: 0;
1061
1132
  }
1062
1133
  .ops-meter {
1063
1134
  display: grid;
1064
- grid-template-columns: 34px minmax(0, 1fr) 35px;
1065
1135
  gap: 7px;
1066
- align-items: center;
1067
- font-size: 10px;
1136
+ min-width: 0;
1137
+ font-size: 11px;
1068
1138
  color: var(--ops-text-placeholder);
1069
1139
  }
1070
- .ops-meter strong {
1071
- font-size: 11px;
1072
- font-weight: 500;
1140
+ .ops-meter-head,
1141
+ .ops-meter-stats {
1142
+ display: flex;
1143
+ flex-wrap: wrap;
1144
+ gap: 4px 10px;
1145
+ min-width: 0;
1146
+ align-items: center;
1147
+ justify-content: space-between;
1148
+ }
1149
+ .ops-meter-label {
1150
+ flex: none;
1151
+ font-weight: 600;
1073
1152
  color: var(--ops-text-secondary);
1153
+ }
1154
+ .ops-meter-stats {
1155
+ flex: 1;
1156
+ justify-content: flex-end;
1074
1157
  text-align: right;
1075
1158
  }
1159
+ .ops-meter-stats > span {
1160
+ overflow-wrap: anywhere;
1161
+ }
1162
+ .ops-meter-stats strong {
1163
+ flex: none;
1164
+ font-size: 11px;
1165
+ font-weight: 650;
1166
+ color: var(--ops-text-secondary);
1167
+ font-variant-numeric: tabular-nums;
1168
+ }
1169
+ .ops-meter :deep(.el-progress),
1170
+ .ops-meter :deep(.el-progress-bar) {
1171
+ min-width: 0;
1172
+ width: 100%;
1173
+ }
1076
1174
  .ops-alert-panel {
1077
1175
  margin-bottom: 0;
1078
1176
  }
@@ -1127,6 +1225,7 @@ onBeforeUnmount(stopRealtime);
1127
1225
  grid-template-columns: repeat(2, minmax(0, 1fr));
1128
1226
  }
1129
1227
  .ops-primary-grid,
1228
+ .ops-storage-grid,
1130
1229
  .ops-secondary-grid {
1131
1230
  grid-template-columns: 1fr;
1132
1231
  }
@@ -1161,8 +1260,13 @@ onBeforeUnmount(stopRealtime);
1161
1260
  margin-left: 54px;
1162
1261
  }
1163
1262
  .ops-node-row {
1164
- grid-template-columns: 82px minmax(0, 1fr);
1165
- gap: 7px;
1263
+ grid-template-columns: 1fr;
1264
+ gap: 10px;
1265
+ }
1266
+ .ops-meter-stats {
1267
+ flex-basis: 100%;
1268
+ justify-content: flex-start;
1269
+ text-align: left;
1166
1270
  }
1167
1271
  .ops-alert-row {
1168
1272
  grid-template-columns: 8px minmax(0, 1fr);
@@ -72,7 +72,7 @@
72
72
  import { computed, nextTick, onMounted, ref, watch } from "vue";
73
73
  import { Search } from "@element-plus/icons-vue";
74
74
  import type { TreeNodeData } from "element-plus";
75
- import { getCurrentLocale, t } from "@liujitcn/kratos-admin-core";
75
+ import { getCurrentLocale, t, useLocaleStore } from "@liujitcn/kratos-admin-core";
76
76
  import MarkdownPreview from "@liujitcn/kratos-admin-core/components/MarkdownPreview/index.vue";
77
77
  import { useGlobalStore } from "@liujitcn/kratos-admin-core/stores/runtime";
78
78
  import { defProjectDocumentService } from "@liujitcn/kratos-admin-system/api/system/project_document";
@@ -112,6 +112,7 @@ interface ProjectDocumentTreeNode {
112
112
  }
113
113
 
114
114
  const globalStore = useGlobalStore();
115
+ const { locale } = useLocaleStore();
115
116
  const loading = ref(false);
116
117
  const detailLoading = ref(false);
117
118
  const keyword = ref("");
@@ -137,11 +138,11 @@ const filteredDocumentCount = computed(() => {
137
138
  const search = keyword.value.trim().toLocaleLowerCase();
138
139
  if (!search) return documents.value.length;
139
140
  return documents.value.filter(node =>
140
- [node.projectKey, node.projectName, node.path].some(value => value.toLocaleLowerCase().includes(search))
141
+ [node.label, node.projectKey, node.projectName, node.path].some(value => value.toLocaleLowerCase().includes(search))
141
142
  ).length;
142
143
  });
143
144
  const selectedDocumentNodeKey = computed(() => (selectedDocumentId.value ? buildDocumentNodeKey(selectedDocumentId.value) : ""));
144
- const selectedDocumentName = computed(() => selectedDocument.value?.path.split("/").at(-1) ?? "");
145
+ const selectedDocumentName = computed(() => selectedDocument.value?.name ?? "");
145
146
  const selectedDocumentUpdatedAt = computed(
146
147
  () => documents.value.find(node => node.document?.id === selectedDocumentId.value)?.document?.updated_at ?? ""
147
148
  );
@@ -321,7 +322,7 @@ function buildDocumentTreeNode(
321
322
  ): ProjectDocumentTreeNode {
322
323
  return {
323
324
  key: buildDocumentNodeKey(document.id),
324
- label: document.path.split("/").at(-1) ?? document.path,
325
+ label: document.name,
325
326
  kind: "document",
326
327
  projectKey,
327
328
  projectName,
@@ -352,6 +353,10 @@ watch(keyword, value => {
352
353
  documentTreeRef.value?.filter(value);
353
354
  });
354
355
 
356
+ watch(locale, () => {
357
+ void loadDocuments();
358
+ });
359
+
355
360
  onMounted(() => {
356
361
  void loadDocuments();
357
362
  });