@liujitcn/kratos-admin-system 0.0.21 → 0.0.24

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 (106) hide show
  1. package/dist/package/declarations/src/api/system/base_language.d.ts +5 -4
  2. package/dist/package/declarations/src/api/system/base_translation.d.ts +7 -4
  3. package/dist/package/declarations/src/api/system/ops_monitoring.d.ts +19 -0
  4. package/dist/package/declarations/src/api/system/ops_monitoring_sse.d.ts +12 -0
  5. package/dist/package/declarations/src/components/DynamicTranslationCell.vue.d.ts +9 -32
  6. package/dist/package/declarations/src/components/DynamicTranslationEditor.vue.d.ts +3 -6
  7. package/dist/package/declarations/src/components/dynamicTranslation.d.ts +11 -17
  8. package/dist/package/declarations/src/locales/generated.d.ts +6536 -0
  9. package/dist/package/declarations/src/rpc/base/v1/ai_session.d.ts +12 -2
  10. package/dist/package/declarations/src/rpc/base/v1/ai_tool.d.ts +9 -1
  11. package/dist/package/declarations/src/rpc/base/v1/config.d.ts +35 -0
  12. package/dist/package/declarations/src/rpc/system/admin/v1/auth.d.ts +1 -1
  13. package/dist/package/declarations/src/rpc/system/admin/v1/base_config.d.ts +23 -7
  14. package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +7 -77
  15. package/dist/package/declarations/src/rpc/system/admin/v1/base_job.d.ts +9 -1
  16. package/dist/package/declarations/src/rpc/system/admin/v1/base_language.d.ts +7 -2
  17. package/dist/package/declarations/src/rpc/system/admin/v1/base_menu.d.ts +5 -40
  18. package/dist/package/declarations/src/rpc/system/admin/v1/base_migration.d.ts +6 -6
  19. package/dist/package/declarations/src/rpc/system/admin/v1/base_role.d.ts +13 -1
  20. package/dist/package/declarations/src/rpc/system/admin/v1/base_translation.d.ts +54 -81
  21. package/dist/package/declarations/src/rpc/system/admin/v1/base_user.d.ts +11 -1
  22. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen.d.ts +11 -11
  23. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_table.d.ts +11 -1
  24. package/dist/package/declarations/src/rpc/system/admin/v1/common.d.ts +13 -0
  25. package/dist/package/declarations/src/rpc/system/admin/v1/ops_monitoring.d.ts +222 -0
  26. package/dist/package/declarations/src/views/tool/ops-monitoring/index.vue.d.ts +3 -0
  27. package/dist/package/src/api/base/ai_message.ts +2 -2
  28. package/dist/package/src/api/system/base_language.ts +13 -15
  29. package/dist/package/src/api/system/base_translation.ts +17 -6
  30. package/dist/package/src/api/system/ops_monitoring.ts +88 -0
  31. package/dist/package/src/api/system/ops_monitoring_sse.ts +49 -0
  32. package/dist/package/src/components/DynamicTranslationCell.vue +199 -126
  33. package/dist/package/src/components/DynamicTranslationEditor.vue +109 -78
  34. package/dist/package/src/components/dynamicTranslation.ts +11 -31
  35. package/dist/package/src/locales/README.md +7 -5
  36. package/dist/package/src/locales/en-US.json +876 -872
  37. package/dist/package/src/locales/es-ES.json +900 -895
  38. package/dist/package/src/locales/fr-FR.json +896 -891
  39. package/dist/package/src/locales/generated.ts +22 -0
  40. package/dist/package/src/locales/ja-JP.json +876 -872
  41. package/dist/package/src/locales/ko-KR.json +881 -876
  42. package/dist/package/src/locales/zh-CN.json +876 -872
  43. package/dist/package/src/locales/zh-TW.json +876 -871
  44. package/dist/package/src/module.ts +3 -17
  45. package/dist/package/src/rpc/base/v1/ai_session.ts +13 -2
  46. package/dist/package/src/rpc/base/v1/ai_tool.ts +10 -1
  47. package/dist/package/src/rpc/base/v1/config.ts +47 -0
  48. package/dist/package/src/rpc/system/admin/v1/auth.ts +1 -1
  49. package/dist/package/src/rpc/system/admin/v1/base_config.ts +24 -7
  50. package/dist/package/src/rpc/system/admin/v1/base_dict.ts +7 -79
  51. package/dist/package/src/rpc/system/admin/v1/base_job.ts +10 -1
  52. package/dist/package/src/rpc/system/admin/v1/base_language.ts +8 -2
  53. package/dist/package/src/rpc/system/admin/v1/base_menu.ts +5 -41
  54. package/dist/package/src/rpc/system/admin/v1/base_migration.ts +8 -8
  55. package/dist/package/src/rpc/system/admin/v1/base_role.ts +14 -1
  56. package/dist/package/src/rpc/system/admin/v1/base_translation.ts +54 -81
  57. package/dist/package/src/rpc/system/admin/v1/base_user.ts +12 -1
  58. package/dist/package/src/rpc/system/admin/v1/code_gen.ts +11 -11
  59. package/dist/package/src/rpc/system/admin/v1/code_gen_table.ts +12 -1
  60. package/dist/package/src/rpc/system/admin/v1/common.ts +21 -0
  61. package/dist/package/src/rpc/system/admin/v1/ops_monitoring.ts +255 -0
  62. package/dist/package/src/views/ai/chat/components/ChatPanel.vue +36 -36
  63. package/dist/package/src/views/ai/chat/components/SessionPanel.vue +6 -6
  64. package/dist/package/src/views/ai/chat/components/XSender.vue +20 -20
  65. package/dist/package/src/views/ai/chat/index.vue +33 -32
  66. package/dist/package/src/views/ai/chat/message.ts +16 -15
  67. package/dist/package/src/views/base/api/index.vue +55 -56
  68. package/dist/package/src/views/base/area/index.vue +18 -19
  69. package/dist/package/src/views/base/config/index.vue +143 -133
  70. package/dist/package/src/views/base/dept/index.vue +42 -43
  71. package/dist/package/src/views/base/dict/index.vue +49 -45
  72. package/dist/package/src/views/base/dict/item.vue +54 -49
  73. package/dist/package/src/views/base/job/index.vue +51 -52
  74. package/dist/package/src/views/base/job/log.vue +18 -18
  75. package/dist/package/src/views/{tool → base}/language/index.vue +51 -47
  76. package/dist/package/src/views/base/log/index.vue +40 -40
  77. package/dist/package/src/views/base/menu/index.vue +220 -177
  78. package/dist/package/src/views/base/migration/index.vue +24 -24
  79. package/dist/package/src/views/base/post/index.vue +42 -43
  80. package/dist/package/src/views/base/role/index.vue +54 -55
  81. package/dist/package/src/views/base/tenant/index.vue +42 -43
  82. package/dist/package/src/views/base/user/components/dept-tree.vue +1 -1
  83. package/dist/package/src/views/base/user/index.vue +69 -71
  84. package/dist/package/src/views/profile/components/base.vue +9 -9
  85. package/dist/package/src/views/profile/components/password.vue +19 -20
  86. package/dist/package/src/views/profile/components/security.vue +20 -20
  87. package/dist/package/src/views/profile/index.vue +3 -3
  88. package/dist/package/src/views/tool/api-doc/index.vue +1 -1
  89. package/dist/package/src/views/tool/code-gen/code-preview/index.vue +13 -13
  90. package/dist/package/src/views/tool/code-gen/columns/index.vue +89 -89
  91. package/dist/package/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue +5 -5
  92. package/dist/package/src/views/tool/code-gen/components/CodeGenProgressDialog.vue +21 -21
  93. package/dist/package/src/views/tool/code-gen/components/CodePreviewPane.vue +5 -5
  94. package/dist/package/src/views/tool/code-gen/config.ts +60 -60
  95. package/dist/package/src/views/tool/code-gen/preview/data.ts +2 -2
  96. package/dist/package/src/views/tool/code-gen/preview/index.vue +30 -31
  97. package/dist/package/src/views/tool/code-gen/proto/index.vue +43 -43
  98. package/dist/package/src/views/tool/code-gen/table/index.vue +95 -95
  99. package/dist/package/src/views/tool/ops-monitoring/index.vue +1175 -0
  100. package/dist/package/src/views/tool/project-doc/index.vue +7 -7
  101. package/package.json +2 -2
  102. package/dist/package/declarations/src/rpc/base/v1/enum.d.ts +0 -43
  103. package/dist/package/declarations/src/rpc/system/common/v1/enum.d.ts +0 -67
  104. package/dist/package/src/rpc/base/v1/enum.ts +0 -54
  105. package/dist/package/src/rpc/system/common/v1/enum.ts +0 -80
  106. /package/dist/package/declarations/src/views/{tool → base}/language/index.vue.d.ts +0 -0
@@ -3,12 +3,12 @@
3
3
  <template v-if="isEmptyState">
4
4
  <div class="agent-chat-empty">
5
5
  <div class="agent-chat-empty__title">{{ welcomeTitle }}</div>
6
- <div class="agent-chat-empty__desc">{{ t("system.ai.chat.welcomeDescription") }}</div>
6
+ <div class="agent-chat-empty__desc">{{ t("system.ai.chat.welcome_description") }}</div>
7
7
  <section v-if="hasShortcutPanel" class="agent-shortcuts">
8
8
  <div class="agent-shortcuts__head">
9
9
  <div>
10
10
  <div class="agent-shortcuts__eyebrow">{{ t("system.ai.chat.shortcut.eyebrow") }}</div>
11
- <div class="agent-shortcuts__title">{{ t("system.ai.chat.shortcut.startTitle") }}</div>
11
+ <div class="agent-shortcuts__title">{{ t("system.ai.chat.shortcut.start_title") }}</div>
12
12
  </div>
13
13
  <div class="agent-shortcuts__actions">
14
14
  <span class="agent-shortcuts__count">{{ shortcutBatchLabel }}</span>
@@ -19,13 +19,13 @@
19
19
  :disabled="sending"
20
20
  @click="refreshShortcutBatch"
21
21
  >
22
- <span>{{ t("system.ai.chat.action.refreshShortcuts") }}</span>
22
+ <span>{{ t("system.ai.chat.action.refresh_shortcuts") }}</span>
23
23
  <el-icon><Refresh /></el-icon>
24
24
  </button>
25
25
  </div>
26
26
  </div>
27
27
  <div v-if="loadingShortcuts" class="agent-shortcuts__loading">
28
- {{ t("system.ai.chat.message.loadingShortcuts") }}
28
+ {{ t("system.ai.chat.message.loading_shortcuts") }}
29
29
  </div>
30
30
  <div v-else class="agent-shortcuts__grid">
31
31
  <button
@@ -106,7 +106,7 @@
106
106
  <button
107
107
  class="agent-message-tool-copy"
108
108
  type="button"
109
- :aria-label="t('system.ai.chat.action.copyRequest')"
109
+ :aria-label="t('system.ai.chat.action.copy_request')"
110
110
  @click.stop="handleCopyToolRequest(tool)"
111
111
  >
112
112
  <el-icon><CopyDocument /></el-icon>
@@ -134,10 +134,10 @@
134
134
  }"
135
135
  >
136
136
  <div v-if="isAIFailedMessage(item)" class="agent-message-error">
137
- <div class="agent-message-error__title">{{ t("system.ai.chat.message.serverError") }}</div>
137
+ <div class="agent-message-error__title">{{ t("system.ai.chat.message.server_error") }}</div>
138
138
  <div class="agent-message-error__content">{{ resolveAIErrorMessage(item) }}</div>
139
139
  <el-collapse v-if="item.fallback_reason" class="agent-message-error__detail" accordion>
140
- <el-collapse-item :title="t('system.ai.chat.title.errorDetail')" :name="String(item.id)">
140
+ <el-collapse-item :title="t('system.ai.chat.title.error_detail')" :name="String(item.id)">
141
141
  <pre>{{ item.fallback_reason }}</pre>
142
142
  </el-collapse-item>
143
143
  </el-collapse>
@@ -146,7 +146,7 @@
146
146
  <AiMarkdown :content="item.content" :streaming="item.progressState === 'streaming'" />
147
147
  <slot name="flow-blocks" :message="item" :active-flow-message-id="activeFlowMessageID" />
148
148
  <el-collapse v-if="item.fallback_reason" class="agent-message-error__detail" accordion>
149
- <el-collapse-item :title="t('system.ai.chat.title.errorDetail')" :name="String(item.id)">
149
+ <el-collapse-item :title="t('system.ai.chat.title.error_detail')" :name="String(item.id)">
150
150
  <pre>{{ item.fallback_reason }}</pre>
151
151
  </el-collapse-item>
152
152
  </el-collapse>
@@ -209,7 +209,7 @@
209
209
  <button
210
210
  class="agent-message-action agent-message-runtime-trigger"
211
211
  type="button"
212
- :aria-label="t('system.ai.chat.action.viewRuntime')"
212
+ :aria-label="t('system.ai.chat.action.view_runtime')"
213
213
  :disabled="item.progressState === 'streaming'"
214
214
  >
215
215
  <el-icon><DataAnalysis /></el-icon>
@@ -222,30 +222,30 @@
222
222
  <div v-if="resolveTokenTotal(item) > 0" class="agent-runtime-detail__section">
223
223
  <div class="agent-runtime-detail__section-title">Token</div>
224
224
  <div class="agent-runtime-detail__row">
225
- <span>{{ t("system.ai.chat.field.inputTokens") }}</span>
225
+ <span>{{ t("system.ai.chat.field.input_tokens") }}</span>
226
226
  <strong>{{ formatNumber(item.token?.input) }}</strong>
227
227
  </div>
228
228
  <div class="agent-runtime-detail__row">
229
- <span>{{ t("system.ai.chat.field.outputTokens") }}</span>
229
+ <span>{{ t("system.ai.chat.field.output_tokens") }}</span>
230
230
  <strong>{{ formatNumber(item.token?.output) }}</strong>
231
231
  </div>
232
232
  <div v-if="(item.token?.cache ?? 0) > 0" class="agent-runtime-detail__row">
233
- <span>{{ t("system.ai.chat.field.cacheTokens") }}</span>
233
+ <span>{{ t("system.ai.chat.field.cache_tokens") }}</span>
234
234
  <strong>{{ formatNumber(item.token?.cache) }}</strong>
235
235
  </div>
236
236
  <div class="agent-runtime-detail__row is-total">
237
- <span>{{ t("system.ai.chat.field.totalTokens") }}</span>
237
+ <span>{{ t("system.ai.chat.field.total_tokens") }}</span>
238
238
  <strong>{{ formatNumber(item.token?.total) }}</strong>
239
239
  </div>
240
240
  </div>
241
241
  <div v-if="item.first_token_ms > 0 || item.duration_ms > 0" class="agent-runtime-detail__section">
242
242
  <div class="agent-runtime-detail__section-title">{{ t("system.ai.chat.field.duration") }}</div>
243
243
  <div v-if="item.first_token_ms > 0" class="agent-runtime-detail__row">
244
- <span>{{ t("system.ai.chat.field.firstToken") }}</span>
244
+ <span>{{ t("system.ai.chat.field.first_token") }}</span>
245
245
  <strong>{{ formatDurationMs(item.first_token_ms) }}</strong>
246
246
  </div>
247
247
  <div v-if="item.duration_ms > 0" class="agent-runtime-detail__row is-total">
248
- <span>{{ t("system.ai.chat.field.totalDuration") }}</span>
248
+ <span>{{ t("system.ai.chat.field.total_duration") }}</span>
249
249
  <strong>{{ formatDurationMs(item.duration_ms) }}</strong>
250
250
  </div>
251
251
  </div>
@@ -282,7 +282,7 @@
282
282
  <div class="agent-shortcuts__head">
283
283
  <div>
284
284
  <div class="agent-shortcuts__eyebrow">{{ t("system.ai.chat.shortcut.eyebrow") }}</div>
285
- <div class="agent-shortcuts__title">{{ t("system.ai.chat.shortcut.continueTitle") }}</div>
285
+ <div class="agent-shortcuts__title">{{ t("system.ai.chat.shortcut.continue_title") }}</div>
286
286
  </div>
287
287
  <div class="agent-shortcuts__actions">
288
288
  <span class="agent-shortcuts__count">{{ shortcutBatchLabel }}</span>
@@ -293,13 +293,13 @@
293
293
  :disabled="sending"
294
294
  @click="refreshShortcutBatch"
295
295
  >
296
- <span>{{ t("system.ai.chat.action.refreshShortcuts") }}</span>
296
+ <span>{{ t("system.ai.chat.action.refresh_shortcuts") }}</span>
297
297
  <el-icon><Refresh /></el-icon>
298
298
  </button>
299
299
  </div>
300
300
  </div>
301
301
  <div v-if="loadingShortcuts" class="agent-shortcuts__loading">
302
- {{ t("system.ai.chat.message.loadingShortcuts") }}
302
+ {{ t("system.ai.chat.message.loading_shortcuts") }}
303
303
  </div>
304
304
  <div v-else class="agent-shortcuts__grid">
305
305
  <button
@@ -337,7 +337,7 @@ import { getCurrentLocale, t } from "@liujitcn/kratos-admin-core";
337
337
  import type { AiAction } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_message";
338
338
  import { type AiAttachment, type AiSession } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_session";
339
339
  import type { AiShortcut, AiToolCall } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_tool";
340
- import { AiMessageStatus } from "@liujitcn/kratos-admin-system/rpc/base/v1/enum";
340
+ import { AiMessageStatus } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_session";
341
341
  import XSender from "./XSender.vue";
342
342
 
343
343
  // AI Markdown 渲染器依赖较重,仅在真正出现助手消息时再加载。
@@ -543,7 +543,7 @@ const canRefreshShortcutBatch = computed(() => shortcutAllList.value.length > SH
543
543
  const shortcutBatchLabel = computed(() => {
544
544
  const total = shortcutAllList.value.length;
545
545
  if (props.loadingShortcuts && total === 0) return t("system.ai.chat.status.loading");
546
- if (total <= SHORTCUT_BATCH_SIZE) return t("system.ai.chat.value.itemCount", { count: total });
546
+ if (total <= SHORTCUT_BATCH_SIZE) return t("system.ai.chat.value.item_count", { count: total });
547
547
  const pageIndex = shortcutBatchIndex.value % shortcutBatchCount.value;
548
548
  const start = pageIndex * SHORTCUT_BATCH_SIZE + 1;
549
549
  const end = Math.min(start + SHORTCUT_BATCH_SIZE - 1, total);
@@ -638,9 +638,9 @@ function resolveShortcutIcon(shortcut: AiShortcut) {
638
638
 
639
639
  /** 展示快捷入口的分组和工具依赖摘要,帮助运营判断动作上下文。 */
640
640
  function resolveShortcutMeta(shortcut: AiShortcut) {
641
- const group = shortcut.group || t("system.ai.chat.value.generalAssistant");
641
+ const group = shortcut.group || t("system.ai.chat.value.general_assistant");
642
642
  const toolCount = shortcut.required_tools?.length ?? 0;
643
- return toolCount > 0 ? t("system.ai.chat.value.shortcutTools", { group, count: toolCount }) : group;
643
+ return toolCount > 0 ? t("system.ai.chat.value.shortcut_tools", { group, count: toolCount }) : group;
644
644
  }
645
645
 
646
646
  /** 生成快捷入口对应的流程动作。 */
@@ -674,7 +674,7 @@ function parseActionPayload(payload?: string) {
674
674
 
675
675
  /** 根据消息角色返回可用操作。 */
676
676
  function resolveMessageActions(item: ChatMessageItem) {
677
- if (item.progressState === "streaming" || item.status === AiMessageStatus.GENERATING_AMS) return [];
677
+ if (item.progressState === "streaming" || item.status === AiMessageStatus.AI_MESSAGE_STATUS_GENERATING) return [];
678
678
 
679
679
  const copyAction: MessageActionOption = {
680
680
  key: "copy" as const,
@@ -685,7 +685,7 @@ function resolveMessageActions(item: ChatMessageItem) {
685
685
  const editAction: MessageActionOption = { key: "edit" as const, label: t("common.action.edit"), icon: EditPen };
686
686
  if (item.role === "user") {
687
687
  const actions = isLastEditableUserMessage(item) ? [editAction, copyAction, deleteAction] : [copyAction, deleteAction];
688
- if (item.status === AiMessageStatus.FAILED_AMS) {
688
+ if (item.status === AiMessageStatus.AI_MESSAGE_STATUS_FAILED) {
689
689
  return item.localOnly
690
690
  ? [{ key: "retry" as const, label: t("system.ai.chat.action.resend"), icon: Refresh }, copyAction, deleteAction]
691
691
  : [{ key: "retry" as const, label: t("system.ai.chat.action.resend"), icon: Refresh }, ...actions];
@@ -694,11 +694,11 @@ function resolveMessageActions(item: ChatMessageItem) {
694
694
  }
695
695
 
696
696
  const actions: MessageActionOption[] = [{ key: "retry" as const, label: t("system.ai.chat.action.regenerate"), icon: Refresh }];
697
- if (item.status === AiMessageStatus.SUCCESS_AMS) {
698
- actions.push({ key: "branch" as const, label: t("system.ai.chat.action.createBranch"), icon: BranchActionIcon });
697
+ if (item.status === AiMessageStatus.AI_MESSAGE_STATUS_SUCCESS) {
698
+ actions.push({ key: "branch" as const, label: t("system.ai.chat.action.create_branch"), icon: BranchActionIcon });
699
699
  actions.push({
700
700
  key: "speak" as const,
701
- label: item.speaking ? t("system.ai.chat.action.stopSpeaking") : t("system.ai.chat.action.speak"),
701
+ label: item.speaking ? t("system.ai.chat.action.stop_speaking") : t("system.ai.chat.action.speak"),
702
702
  icon: SpeakActionIcon
703
703
  });
704
704
  }
@@ -707,13 +707,13 @@ function resolveMessageActions(item: ChatMessageItem) {
707
707
 
708
708
  /** 判断是否为需要渲染错误卡片的助手失败消息。 */
709
709
  function isAIFailedMessage(item: ChatMessageItem) {
710
- return item.role !== "user" && item.status === AiMessageStatus.FAILED_AMS;
710
+ return item.role !== "user" && item.status === AiMessageStatus.AI_MESSAGE_STATUS_FAILED;
711
711
  }
712
712
 
713
713
  /** 返回助手错误摘要,优先展示服务端可读错误。 */
714
714
  function resolveAIErrorMessage(item: ChatMessageItem) {
715
715
  const content = String(item.content ?? "").trim();
716
- return content || t("system.ai.chat.message.replyFailed");
716
+ return content || t("system.ai.chat.message.reply_failed");
717
717
  }
718
718
 
719
719
  /** 判断助手消息是否存在最终用量信息。 */
@@ -893,9 +893,9 @@ function formatToolArgumentValue(value: unknown) {
893
893
  async function handleCopyToolRequest(tool: AiToolCall) {
894
894
  try {
895
895
  await navigator.clipboard.writeText(formatToolRequest(tool));
896
- ElMessage.success(t("system.ai.chat.message.requestCopied"));
896
+ ElMessage.success(t("system.ai.chat.message.request_copied"));
897
897
  } catch {
898
- ElMessage.error(t("system.ai.chat.message.copyUnsupported"));
898
+ ElMessage.error(t("system.ai.chat.message.copy_unsupported"));
899
899
  }
900
900
  }
901
901
 
@@ -941,11 +941,11 @@ function submitMessageEdit(item: ChatMessageItem) {
941
941
  if (props.sending) return;
942
942
  const content = editingContent.value;
943
943
  if (content === "") {
944
- ElMessage.warning(t("system.ai.chat.message.contentRequired"));
944
+ ElMessage.warning(t("system.ai.chat.message.content_required"));
945
945
  return;
946
946
  }
947
947
  if (content === String(item.content ?? "")) {
948
- ElMessage.info(t("system.ai.chat.message.contentUnchanged"));
948
+ ElMessage.info(t("system.ai.chat.message.content_unchanged"));
949
949
  return;
950
950
  }
951
951
  emit("messageEdit", { item, content });
@@ -959,9 +959,9 @@ function shouldConfirmMessageAction(action: ChatMessageAction) {
959
959
 
960
960
  /** 返回消息操作确认文案,避免误删或误覆盖当前气泡。 */
961
961
  function resolveActionConfirmTitle(action: ChatMessageAction, item: ChatMessageItem) {
962
- if (action === "delete") return t("system.ai.chat.dialog.confirmDeleteMessage");
963
- if (item.role === "user") return t("system.ai.chat.dialog.confirmResendMessage");
964
- return t("system.ai.chat.dialog.confirmRegenerateMessage");
962
+ if (action === "delete") return t("system.ai.chat.dialog.confirm_delete_message");
963
+ if (item.role === "user") return t("system.ai.chat.dialog.confirm_resend_message");
964
+ return t("system.ai.chat.dialog.confirm_regenerate_message");
965
965
  }
966
966
 
967
967
  /** 统一回复来源标签配色。 */
@@ -2,20 +2,20 @@
2
2
  <aside class="agent-session-panel">
3
3
  <el-input
4
4
  :model-value="keyword"
5
- :placeholder="t('system.ai.chat.placeholder.searchConversation')"
5
+ :placeholder="t('system.ai.chat.placeholder.search_conversation')"
6
6
  clearable
7
7
  :prefix-icon="Search"
8
8
  @update:model-value="handleKeywordUpdate"
9
9
  />
10
10
  <div class="agent-divider"></div>
11
11
  <div class="agent-panel-header">
12
- <div class="agent-panel-title">{{ t("system.ai.chat.title.recentConversations") }}</div>
12
+ <div class="agent-panel-title">{{ t("system.ai.chat.title.recent_conversations") }}</div>
13
13
  <div class="agent-panel-actions">
14
- <el-tooltip :content="t('system.ai.chat.action.collapseSessions')" placement="top">
14
+ <el-tooltip :content="t('system.ai.chat.action.collapse_sessions')" placement="top">
15
15
  <button
16
16
  class="agent-panel-icon"
17
17
  type="button"
18
- :aria-label="t('system.ai.chat.action.collapseSessions')"
18
+ :aria-label="t('system.ai.chat.action.collapse_sessions')"
19
19
  @click="$emit('toggleCollapse')"
20
20
  >
21
21
  <el-icon><DArrowLeft /></el-icon>
@@ -24,7 +24,7 @@
24
24
  <button
25
25
  class="agent-panel-create"
26
26
  type="button"
27
- :aria-label="t('system.ai.chat.action.newConversation')"
27
+ :aria-label="t('system.ai.chat.action.new_conversation')"
28
28
  @click="handleCreateSession"
29
29
  >
30
30
  <el-icon><Plus /></el-icon>
@@ -58,7 +58,7 @@
58
58
  @click.stop
59
59
  @command="command => handleMenuCommand(command, item)"
60
60
  >
61
- <button class="agent-session-more" type="button" :aria-label="t('system.ai.chat.action.conversationMenu')">
61
+ <button class="agent-session-more" type="button" :aria-label="t('system.ai.chat.action.conversation_menu')">
62
62
  <el-icon><MoreFilled /></el-icon>
63
63
  </button>
64
64
  <template #dropdown>
@@ -31,7 +31,7 @@
31
31
  class="agent-icon-button"
32
32
  type="button"
33
33
  :disabled="sending || uploading"
34
- :aria-label="t('system.ai.chat.action.uploadAttachment')"
34
+ :aria-label="t('system.ai.chat.action.upload_attachment')"
35
35
  >
36
36
  <el-icon :class="{ 'is-loading': uploading }">
37
37
  <Loading v-if="uploading" />
@@ -40,10 +40,10 @@
40
40
  </button>
41
41
  </template>
42
42
  <div class="agent-popover-card">
43
- <div class="agent-popover-title">{{ t("system.ai.chat.action.uploadAttachment") }}</div>
44
- <div class="agent-popover-desc">{{ t("system.ai.chat.message.attachmentHint") }}</div>
43
+ <div class="agent-popover-title">{{ t("system.ai.chat.action.upload_attachment") }}</div>
44
+ <div class="agent-popover-desc">{{ t("system.ai.chat.message.attachment_hint") }}</div>
45
45
  <button class="agent-popover-action" type="button" :disabled="sending || uploading" @click="handleSelectAttachment">
46
- {{ uploading ? t("system.ai.chat.status.uploading") : t("system.ai.chat.action.selectLocalFile") }}
46
+ {{ uploading ? t("system.ai.chat.status.uploading") : t("system.ai.chat.action.select_local_file") }}
47
47
  </button>
48
48
  </div>
49
49
  </el-popover>
@@ -55,7 +55,7 @@
55
55
  <template #action-list>
56
56
  <div class="agent-sender-actions">
57
57
  <el-tooltip
58
- :content="recording ? t('system.ai.chat.action.stopVoiceInput') : t('system.ai.chat.action.voiceInput')"
58
+ :content="recording ? t('system.ai.chat.action.stop_voice_input') : t('system.ai.chat.action.voice_input')"
59
59
  placement="top"
60
60
  >
61
61
  <button
@@ -64,7 +64,7 @@
64
64
  type="button"
65
65
  :disabled="sending"
66
66
  :aria-pressed="recording"
67
- :aria-label="recording ? t('system.ai.chat.action.stopVoiceInput') : t('system.ai.chat.action.voiceInput')"
67
+ :aria-label="recording ? t('system.ai.chat.action.stop_voice_input') : t('system.ai.chat.action.voice_input')"
68
68
  @click="handleToggleRecord"
69
69
  >
70
70
  <el-icon :class="{ 'is-loading': recording }">
@@ -164,12 +164,12 @@ const {
164
164
  });
165
165
 
166
166
  const actionHintText = computed(() => {
167
- if (recording.value) return t("system.ai.chat.status.recognizingVoice");
168
- if (uploading.value) return t("system.ai.chat.status.uploadingAttachments");
167
+ if (recording.value) return t("system.ai.chat.status.recognizing_voice");
168
+ if (uploading.value) return t("system.ai.chat.status.uploading_attachments");
169
169
  if (selectedAttachments.value.length) {
170
- return t("system.ai.chat.value.selectedAttachments", { count: selectedAttachments.value.length });
170
+ return t("system.ai.chat.value.selected_attachments", { count: selectedAttachments.value.length });
171
171
  }
172
- return t("system.ai.chat.value.attachmentsAvailable");
172
+ return t("system.ai.chat.value.attachments_available");
173
173
  });
174
174
 
175
175
  const attachmentItems = computed<FilesCardProps[]>(() =>
@@ -196,7 +196,7 @@ function handleSubmit() {
196
196
  if (!trimmedText && selectedAttachments.value.length === 0) return;
197
197
 
198
198
  emit("submit", {
199
- text: trimmedText || t("system.ai.chat.value.analyzeAttachments"),
199
+ text: trimmedText || t("system.ai.chat.value.analyze_attachments"),
200
200
  attachments: [...selectedAttachments.value]
201
201
  });
202
202
  inputText.value = "";
@@ -275,12 +275,12 @@ function matchCumulativeRecordCandidate(text: string, candidate: string) {
275
275
 
276
276
  /** 根据浏览器语音识别错误类型生成用户可理解的提示。 */
277
277
  function resolveRecordErrorMessage(error: RecordError) {
278
- if (error.code === -1) return t("system.ai.chat.message.voiceUnsupported");
278
+ if (error.code === -1) return t("system.ai.chat.message.voice_unsupported");
279
279
  const errorName = error.error ?? "";
280
280
  if (["not-allowed", "service-not-allowed", "permission-denied"].includes(errorName)) {
281
- return t("system.ai.chat.message.microphoneDenied");
281
+ return t("system.ai.chat.message.microphone_denied");
282
282
  }
283
- return t("system.ai.chat.message.voiceFailed");
283
+ return t("system.ai.chat.message.voice_failed");
284
284
  }
285
285
 
286
286
  /** 同步输入器内部文本,保证发送按钮禁用态能实时响应。 */
@@ -327,10 +327,10 @@ async function uploadAttachments(files: File[]) {
327
327
  });
328
328
  selectedAttachments.value = Array.from(attachmentMap.values());
329
329
  if (response?.files?.length) {
330
- ElMessage.success(t("system.ai.chat.message.attachmentsUploaded", { count: response.files.length }));
330
+ ElMessage.success(t("system.ai.chat.message.attachments_uploaded", { count: response.files.length }));
331
331
  }
332
332
  } catch {
333
- ElMessage.error(t("system.ai.chat.message.attachmentUploadFailed"));
333
+ ElMessage.error(t("system.ai.chat.message.attachment_upload_failed"));
334
334
  } finally {
335
335
  uploading.value = false;
336
336
  resetFileInput();
@@ -341,22 +341,22 @@ async function uploadAttachments(files: File[]) {
341
341
  function filterUploadFiles(files: File[]) {
342
342
  const remainingCount = maxAttachmentCount - selectedAttachments.value.length;
343
343
  if (remainingCount <= 0) {
344
- ElMessage.warning(t("system.ai.chat.message.attachmentLimit", { count: maxAttachmentCount }));
344
+ ElMessage.warning(t("system.ai.chat.message.attachment_limit", { count: maxAttachmentCount }));
345
345
  return [];
346
346
  }
347
347
  const validFiles = files.filter(file => {
348
348
  if (!isAcceptedAttachmentFile(file)) {
349
- ElMessage.warning(t("system.ai.chat.message.attachmentUnsupported", { name: file.name }));
349
+ ElMessage.warning(t("system.ai.chat.message.attachment_unsupported", { name: file.name }));
350
350
  return false;
351
351
  }
352
352
  if (file.size > maxAttachmentSize) {
353
- ElMessage.warning(t("system.ai.chat.message.attachmentTooLarge", { name: file.name, size: maxAttachmentSizeMB }));
353
+ ElMessage.warning(t("system.ai.chat.message.attachment_too_large", { name: file.name, size: maxAttachmentSizeMB }));
354
354
  return false;
355
355
  }
356
356
  return true;
357
357
  });
358
358
  if (validFiles.length > remainingCount) {
359
- ElMessage.warning(t("system.ai.chat.message.attachmentRemaining", { count: remainingCount }));
359
+ ElMessage.warning(t("system.ai.chat.message.attachment_remaining", { count: remainingCount }));
360
360
  }
361
361
  return validFiles.slice(0, remainingCount);
362
362
  }
@@ -14,12 +14,12 @@
14
14
  <button
15
15
  class="agent-session-collapsed__toggle"
16
16
  type="button"
17
- :aria-label="t('system.ai.chat.action.expandSessions')"
17
+ :aria-label="t('system.ai.chat.action.expand_sessions')"
18
18
  @click="toggleSessionPanel"
19
19
  >
20
20
  <el-icon><DArrowRight /></el-icon>
21
21
  </button>
22
- <span class="agent-session-collapsed__label">{{ t("system.ai.chat.title.recentConversations") }}</span>
22
+ <span class="agent-session-collapsed__label">{{ t("system.ai.chat.title.recent_conversations") }}</span>
23
23
  </div>
24
24
  <ChatPanel
25
25
  :active-session="activeSession"
@@ -57,7 +57,8 @@ import { defAiToolService } from "@liujitcn/kratos-admin-system/api/base/ai_tool
57
57
  import type { AiAction } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_message";
58
58
  import type { AiSession } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_session";
59
59
  import type { AiShortcut } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_tool";
60
- import { AiMessageStatus, Terminal } from "@liujitcn/kratos-admin-system/rpc/base/v1/enum";
60
+ import { AiMessageStatus } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_session";
61
+ import { Terminal } from "@liujitcn/kratos-admin-system/rpc/base/v1/ai_tool";
61
62
  import ChatPanel from "./components/ChatPanel.vue";
62
63
  import SessionPanel from "./components/SessionPanel.vue";
63
64
  import {
@@ -151,7 +152,7 @@ async function handleSessionAction(payload: { action: SessionAction; item: AiSes
151
152
  await handleDeleteSession(payload.item);
152
153
  } catch (error) {
153
154
  if (error === "cancel" || error === "close") {
154
- ElMessage.info(t("system.ai.chat.message.actionCanceled"));
155
+ ElMessage.info(t("system.ai.chat.message.action_canceled"));
155
156
  }
156
157
  }
157
158
  }
@@ -162,7 +163,7 @@ async function handleCreateSession() {
162
163
  if (!sessionID) return;
163
164
  activeSessionID.value = sessionID;
164
165
  messages.value[sessionID] = [];
165
- ElMessage.success(t("system.ai.chat.message.conversationCreated"));
166
+ ElMessage.success(t("system.ai.chat.message.conversation_created"));
166
167
  }
167
168
 
168
169
  /** 提交用户输入并同步消息流。 */
@@ -226,7 +227,7 @@ async function runAiStreamTask(sessionID: string, payload: SubmitPayload) {
226
227
  );
227
228
 
228
229
  if (!response.body) {
229
- throw new Error(t("system.ai.chat.message.emptyStream"));
230
+ throw new Error(t("system.ai.chat.message.empty_stream"));
230
231
  }
231
232
  await readAiEventStream(
232
233
  response.body,
@@ -236,14 +237,14 @@ async function runAiStreamTask(sessionID: string, payload: SubmitPayload) {
236
237
  controller.signal
237
238
  );
238
239
  if (!task.finished && !controller.signal.aborted) {
239
- throw new Error(t("system.ai.chat.message.incompleteStream"));
240
+ throw new Error(t("system.ai.chat.message.incomplete_stream"));
240
241
  }
241
242
  } catch (error) {
242
243
  if (controller.signal.aborted) return;
243
244
  messages.value[sessionID] = markThinkingMessageFailed(messages.value[sessionID] ?? [], {
244
245
  sessionID
245
246
  });
246
- const message = error instanceof Error ? error.message : t("system.ai.chat.message.requestFailed");
247
+ const message = error instanceof Error ? error.message : t("system.ai.chat.message.request_failed");
247
248
  ElMessage.error(message);
248
249
  } finally {
249
250
  if (runningStreamTaskMap.get(sessionID) === task) {
@@ -305,10 +306,10 @@ async function handleEditMessage(payload: ChatMessageEditPayload) {
305
306
  const currentMessages = messages.value[sessionID] ?? [];
306
307
  messages.value[sessionID] = replacePendingMessages(currentMessages, normalizeMessageList(response.messages));
307
308
  if (response.session) upsertSession(normalizeSession(response.session));
308
- ElMessage.success(t("system.ai.chat.message.updatedAndRegenerated"));
309
+ ElMessage.success(t("system.ai.chat.message.updated_and_regenerated"));
309
310
  } catch (error) {
310
311
  await loadMessages(sessionID, { force: true });
311
- const message = error instanceof Error ? error.message : t("system.ai.chat.message.updateFailed");
312
+ const message = error instanceof Error ? error.message : t("system.ai.chat.message.update_failed");
312
313
  ElMessage.error(message);
313
314
  } finally {
314
315
  setSessionSending(sessionID, false);
@@ -319,9 +320,9 @@ async function handleEditMessage(payload: ChatMessageEditPayload) {
319
320
  async function handleCopyMessage(item: ChatMessageItem) {
320
321
  try {
321
322
  await navigator.clipboard.writeText(String(item.content ?? ""));
322
- ElMessage.success(t("system.ai.chat.message.messageCopied"));
323
+ ElMessage.success(t("system.ai.chat.message.message_copied"));
323
324
  } catch {
324
- ElMessage.error(t("system.ai.chat.message.copyUnsupported"));
325
+ ElMessage.error(t("system.ai.chat.message.copy_unsupported"));
325
326
  }
326
327
  }
327
328
 
@@ -338,7 +339,7 @@ async function handleDeleteMessage(item: ChatMessageItem) {
338
339
  if (item.role === "user") return !message.localOnly;
339
340
  return resolveMessageBubbleKey(message) !== messageKey;
340
341
  });
341
- ElMessage.success(t("system.ai.chat.message.messageDeleted"));
342
+ ElMessage.success(t("system.ai.chat.message.message_deleted"));
342
343
  return;
343
344
  }
344
345
  await defAiMessageService.DeleteAiMessage({
@@ -346,7 +347,7 @@ async function handleDeleteMessage(item: ChatMessageItem) {
346
347
  message_id: String(item.id)
347
348
  });
348
349
  messages.value[sessionID] = (messages.value[sessionID] ?? []).filter(message => String(message.id) !== String(item.id));
349
- ElMessage.success(t("system.ai.chat.message.messageDeleted"));
350
+ ElMessage.success(t("system.ai.chat.message.message_deleted"));
350
351
  }
351
352
 
352
353
  /** 重试失败的一轮消息,或重新生成助手输出。 */
@@ -359,7 +360,7 @@ async function handleRetryMessage(item: ChatMessageItem) {
359
360
  if (item.localOnly) {
360
361
  const payload = resolveLocalRetryPayload(item);
361
362
  if (!payload) {
362
- ElMessage.warning(t("system.ai.chat.message.localRetryMissing"));
363
+ ElMessage.warning(t("system.ai.chat.message.local_retry_missing"));
363
364
  return;
364
365
  }
365
366
  messages.value[sessionID] = (messages.value[sessionID] ?? []).filter(message => !message.localOnly);
@@ -370,8 +371,8 @@ async function handleRetryMessage(item: ChatMessageItem) {
370
371
  }
371
372
  setSessionSending(sessionID, true);
372
373
  if (item.role === "user") {
373
- if (item.status !== AiMessageStatus.FAILED_AMS) {
374
- ElMessage.warning(t("system.ai.chat.message.retryFailedOnly"));
374
+ if (item.status !== AiMessageStatus.AI_MESSAGE_STATUS_FAILED) {
375
+ ElMessage.warning(t("system.ai.chat.message.retry_failed_only"));
375
376
  return;
376
377
  }
377
378
  response = await defAiMessageService.RetryAiUserMessage({
@@ -391,7 +392,7 @@ async function handleRetryMessage(item: ChatMessageItem) {
391
392
  ElMessage.success(item.role === "user" ? t("system.ai.chat.message.resent") : t("system.ai.chat.message.regenerated"));
392
393
  } catch (error) {
393
394
  if (item.role !== "user") await loadMessages(sessionID, { force: true });
394
- const message = error instanceof Error ? error.message : t("system.ai.chat.message.regenerateFailed");
395
+ const message = error instanceof Error ? error.message : t("system.ai.chat.message.regenerate_failed");
395
396
  ElMessage.error(message);
396
397
  } finally {
397
398
  if (!item.localOnly) {
@@ -439,14 +440,14 @@ async function handleBranchMessage(item: ChatMessageItem) {
439
440
  upsertSession(branchSession);
440
441
  messages.value[branchSession.id] = normalizeMessageList(response.messages);
441
442
  activeSessionID.value = branchSession.id;
442
- ElMessage.success(t("system.ai.chat.message.branchCreated"));
443
+ ElMessage.success(t("system.ai.chat.message.branch_created"));
443
444
  }
444
445
 
445
446
  /** 朗读或停止朗读当前助手输出。 */
446
447
  function handleSpeakMessage(item: ChatMessageItem) {
447
448
  if (item.role === "user") return;
448
449
  if (!window.speechSynthesis) {
449
- ElMessage.warning(t("system.ai.chat.message.speechUnsupported"));
450
+ ElMessage.warning(t("system.ai.chat.message.speech_unsupported"));
450
451
  return;
451
452
  }
452
453
  const messageKey = resolveMessageBubbleKey(item);
@@ -672,29 +673,29 @@ async function loadMessages(sessionID: string, options?: { force?: boolean }) {
672
673
  /** 重命名当前会话。 */
673
674
  async function handleRenameSession(item: AiSession) {
674
675
  const { value } = await ElMessageBox.prompt(
675
- t("system.ai.chat.dialog.renameDescription", { title: item.title }),
676
- t("system.ai.chat.dialog.renameTitle"),
676
+ t("system.ai.chat.dialog.rename_description", { title: item.title }),
677
+ t("system.ai.chat.dialog.rename_title"),
677
678
  {
678
679
  confirmButtonText: t("common.action.confirm"),
679
680
  cancelButtonText: t("common.action.cancel"),
680
681
  inputValue: item.title,
681
682
  inputPattern: /\S+/,
682
- inputErrorMessage: t("system.ai.chat.placeholder.conversationName")
683
+ inputErrorMessage: t("system.ai.chat.placeholder.conversation_name")
683
684
  }
684
685
  );
685
686
 
686
687
  const response = await defAiSessionService.UpdateAiSession({ id: item.id, title: value.trim() });
687
688
  upsertSession(normalizeSession(response.session));
688
- ElMessage.success(t("system.ai.chat.message.conversationRenamed"));
689
+ ElMessage.success(t("system.ai.chat.message.conversation_renamed"));
689
690
  }
690
691
 
691
692
  /** 删除当前会话,并自动切换到剩余会话。 */
692
693
  async function handleDeleteSession(item: AiSession) {
693
694
  await ElMessageBox.confirm(
694
- t("system.ai.chat.dialog.deleteDescription", { title: item.title }),
695
- t("system.ai.chat.dialog.deleteTitle"),
695
+ t("system.ai.chat.dialog.delete_description", { title: item.title }),
696
+ t("system.ai.chat.dialog.delete_title"),
696
697
  {
697
- confirmButtonText: t("system.ai.chat.action.confirmDeleteConversation"),
698
+ confirmButtonText: t("system.ai.chat.action.confirm_delete_conversation"),
698
699
  cancelButtonText: t("common.action.cancel"),
699
700
  type: "warning"
700
701
  }
@@ -711,7 +712,7 @@ async function handleDeleteSession(item: AiSession) {
711
712
  const nextSessionID = await ensureActiveSession();
712
713
  if (nextSessionID) await loadMessages(nextSessionID);
713
714
 
714
- ElMessage.success(t("system.ai.chat.message.conversationDeleted"));
715
+ ElMessage.success(t("system.ai.chat.message.conversation_deleted"));
715
716
  }
716
717
 
717
718
  /** 保证当前存在可用会话;当列表为空时自动创建首个会话。 */
@@ -728,7 +729,7 @@ async function ensureActiveSession() {
728
729
  /** 创建新的助手会话,并同步到本地列表。 */
729
730
  async function createSession(options?: { title?: string }) {
730
731
  const response = await defAiSessionService.CreateAiSession({
731
- title: options?.title || t("system.ai.chat.value.newConversation"),
732
+ title: options?.title || t("system.ai.chat.value.new_conversation"),
732
733
  terminal: Terminal.TERMINAL_ADMIN
733
734
  });
734
735
  const normalizedSession = normalizeSession(response.session);
@@ -738,11 +739,11 @@ async function createSession(options?: { title?: string }) {
738
739
 
739
740
  /** 使用当前消息内容生成一个易识别的分支会话标题。 */
740
741
  function buildBranchSessionTitle(item: ChatMessageItem) {
741
- const content = String(item.input_content?.content || item.content || t("system.ai.chat.value.newConversation"))
742
+ const content = String(item.input_content?.content || item.content || t("system.ai.chat.value.new_conversation"))
742
743
  .replace(/\s+/g, " ")
743
744
  .trim();
744
- return t("system.ai.chat.value.branchTitle", {
745
- title: content.slice(0, 18) || t("system.ai.chat.value.newConversation")
745
+ return t("system.ai.chat.value.branch_title", {
746
+ title: content.slice(0, 18) || t("system.ai.chat.value.new_conversation")
746
747
  });
747
748
  }
748
749