@liujitcn/kratos-admin-system 0.0.38 → 0.0.40

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 (147) hide show
  1. package/README.md +22 -0
  2. package/dist/package/declarations/src/api/system/admin/v1/base_config.d.ts +1 -5
  3. package/dist/package/declarations/src/api/system/admin/v1/base_login_log.d.ts +3 -1
  4. package/dist/package/declarations/src/api/system/admin/v1/base_session.d.ts +7 -1
  5. package/dist/package/declarations/src/components/DynamicI18nCell.vue.d.ts +2 -8
  6. package/dist/package/declarations/src/components/DynamicI18nEditor.vue.d.ts +20 -3
  7. package/dist/package/declarations/src/components/dynamicI18n.d.ts +2 -2
  8. package/dist/package/declarations/src/locales/generated.d.ts +5770 -5686
  9. package/dist/package/declarations/src/rpc/base/v1/login.d.ts +2 -0
  10. package/dist/package/declarations/src/rpc/base/v1/notification.d.ts +1 -1
  11. package/dist/package/declarations/src/rpc/base/v1/oauth.d.ts +4 -0
  12. package/dist/package/declarations/src/rpc/base/v1/oauth_client.d.ts +1 -1
  13. package/dist/package/declarations/src/rpc/system/admin/v1/base_api_log.d.ts +1 -1
  14. package/dist/package/declarations/src/rpc/system/admin/v1/base_config.d.ts +4 -40
  15. package/dist/package/declarations/src/rpc/system/admin/v1/base_data_access_log.d.ts +1 -1
  16. package/dist/package/declarations/src/rpc/system/admin/v1/base_i18n.d.ts +1 -1
  17. package/dist/package/declarations/src/rpc/system/admin/v1/base_log.d.ts +1 -1
  18. package/dist/package/declarations/src/rpc/system/admin/v1/base_login_log.d.ts +10 -1
  19. package/dist/package/declarations/src/rpc/system/admin/v1/base_login_policy.d.ts +8 -0
  20. package/dist/package/declarations/src/rpc/system/admin/v1/base_message.d.ts +1 -1
  21. package/dist/package/declarations/src/rpc/system/admin/v1/base_message_category.d.ts +1 -1
  22. package/dist/package/declarations/src/rpc/system/admin/v1/base_migration.d.ts +1 -1
  23. package/dist/package/declarations/src/rpc/system/admin/v1/base_operation_log.d.ts +1 -1
  24. package/dist/package/declarations/src/rpc/system/admin/v1/base_permission_log.d.ts +1 -1
  25. package/dist/package/declarations/src/rpc/system/admin/v1/base_policy_evaluation_log.d.ts +1 -1
  26. package/dist/package/declarations/src/rpc/system/admin/v1/base_redact_output_policy.d.ts +1 -1
  27. package/dist/package/declarations/src/rpc/system/admin/v1/base_redact_storage_policy.d.ts +1 -1
  28. package/dist/package/declarations/src/rpc/system/admin/v1/base_session.d.ts +41 -0
  29. package/dist/package/declarations/src/rpc/system/admin/v1/base_table_archive.d.ts +1 -1
  30. package/dist/package/declarations/src/rpc/system/admin/v1/base_table_archive_record.d.ts +1 -1
  31. package/dist/package/declarations/src/rpc/system/admin/v1/base_table_archive_restore.d.ts +1 -1
  32. package/dist/package/declarations/src/rpc/system/admin/v1/base_table_backup.d.ts +1 -1
  33. package/dist/package/declarations/src/rpc/system/admin/v1/base_table_backup_record.d.ts +1 -1
  34. package/dist/package/declarations/src/rpc/system/admin/v1/base_table_backup_restore.d.ts +1 -1
  35. package/dist/package/declarations/src/rpc/system/admin/v1/base_table_source.d.ts +1 -1
  36. package/dist/package/declarations/src/rpc/system/admin/v1/cache.d.ts +1 -1
  37. package/dist/package/declarations/src/rpc/system/admin/v1/oauth_client.d.ts +1 -1
  38. package/dist/package/declarations/src/rpc/system/admin/v1/ops_monitoring.d.ts +1 -1
  39. package/dist/package/declarations/src/utils/code-gen-progress.d.ts +3 -0
  40. package/dist/package/declarations/src/views/profile/components/login-log.vue.d.ts +3 -0
  41. package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenGenerateConfirm.vue.d.ts +11 -0
  42. package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue.d.ts +5 -9
  43. package/dist/package/declarations/src/views/tool/code-gen/config.d.ts +3 -0
  44. package/dist/package/src/api/base/v1/sse.ts +11 -2
  45. package/dist/package/src/api/system/admin/v1/base_config.ts +0 -20
  46. package/dist/package/src/api/system/admin/v1/base_login_log.ts +10 -0
  47. package/dist/package/src/api/system/admin/v1/base_session.ts +32 -1
  48. package/dist/package/src/components/DynamicI18nCell.vue +55 -220
  49. package/dist/package/src/components/DynamicI18nEditor.vue +150 -146
  50. package/dist/package/src/components/dynamicI18n.ts +10 -6
  51. package/dist/package/src/config/index.ts +1 -3
  52. package/dist/package/src/locales/en-US.json +1444 -1435
  53. package/dist/package/src/locales/ja-JP.json +1448 -1439
  54. package/dist/package/src/locales/zh-CN.json +1444 -1435
  55. package/dist/package/src/locales/zh-TW.json +1445 -1436
  56. package/dist/package/src/rpc/base/v1/ai_message.ts +1 -1
  57. package/dist/package/src/rpc/base/v1/ai_session.ts +1 -1
  58. package/dist/package/src/rpc/base/v1/ai_tool.ts +1 -1
  59. package/dist/package/src/rpc/base/v1/config.ts +1 -1
  60. package/dist/package/src/rpc/base/v1/login.ts +3 -1
  61. package/dist/package/src/rpc/base/v1/notification.ts +2 -2
  62. package/dist/package/src/rpc/base/v1/oauth.ts +5 -1
  63. package/dist/package/src/rpc/base/v1/oauth_client.ts +2 -2
  64. package/dist/package/src/rpc/base/v1/sse.ts +1 -1
  65. package/dist/package/src/rpc/common/v1/analytics.ts +1 -1
  66. package/dist/package/src/rpc/common/v1/common.ts +1 -1
  67. package/dist/package/src/rpc/common/v1/enum.ts +1 -1
  68. package/dist/package/src/rpc/common/v1/types.ts +1 -1
  69. package/dist/package/src/rpc/google/protobuf/empty.ts +1 -1
  70. package/dist/package/src/rpc/google/protobuf/timestamp.ts +1 -1
  71. package/dist/package/src/rpc/system/admin/v1/auth.ts +1 -1
  72. package/dist/package/src/rpc/system/admin/v1/base_api.ts +1 -1
  73. package/dist/package/src/rpc/system/admin/v1/base_api_log.ts +2 -2
  74. package/dist/package/src/rpc/system/admin/v1/base_area.ts +1 -1
  75. package/dist/package/src/rpc/system/admin/v1/base_config.ts +4 -44
  76. package/dist/package/src/rpc/system/admin/v1/base_dashboard.ts +1 -1
  77. package/dist/package/src/rpc/system/admin/v1/base_data_access_log.ts +2 -2
  78. package/dist/package/src/rpc/system/admin/v1/base_dept.ts +1 -1
  79. package/dist/package/src/rpc/system/admin/v1/base_dict.ts +1 -1
  80. package/dist/package/src/rpc/system/admin/v1/base_dict_item.ts +1 -1
  81. package/dist/package/src/rpc/system/admin/v1/base_file.ts +1 -1
  82. package/dist/package/src/rpc/system/admin/v1/base_i18n.ts +2 -2
  83. package/dist/package/src/rpc/system/admin/v1/base_job.ts +1 -1
  84. package/dist/package/src/rpc/system/admin/v1/base_job_log.ts +1 -1
  85. package/dist/package/src/rpc/system/admin/v1/base_language.ts +1 -1
  86. package/dist/package/src/rpc/system/admin/v1/base_log.ts +2 -2
  87. package/dist/package/src/rpc/system/admin/v1/base_login_log.ts +12 -2
  88. package/dist/package/src/rpc/system/admin/v1/base_login_policy.ts +11 -1
  89. package/dist/package/src/rpc/system/admin/v1/base_menu.ts +1 -1
  90. package/dist/package/src/rpc/system/admin/v1/base_message.ts +2 -2
  91. package/dist/package/src/rpc/system/admin/v1/base_message_category.ts +2 -2
  92. package/dist/package/src/rpc/system/admin/v1/base_migration.ts +2 -2
  93. package/dist/package/src/rpc/system/admin/v1/base_operation_log.ts +2 -2
  94. package/dist/package/src/rpc/system/admin/v1/base_permission_log.ts +2 -2
  95. package/dist/package/src/rpc/system/admin/v1/base_policy_evaluation_log.ts +2 -2
  96. package/dist/package/src/rpc/system/admin/v1/base_post.ts +1 -1
  97. package/dist/package/src/rpc/system/admin/v1/base_redact_common.ts +1 -1
  98. package/dist/package/src/rpc/system/admin/v1/base_redact_output_policy.ts +2 -2
  99. package/dist/package/src/rpc/system/admin/v1/base_redact_rule.ts +1 -1
  100. package/dist/package/src/rpc/system/admin/v1/base_redact_storage_policy.ts +2 -2
  101. package/dist/package/src/rpc/system/admin/v1/base_role.ts +1 -1
  102. package/dist/package/src/rpc/system/admin/v1/base_session.ts +47 -1
  103. package/dist/package/src/rpc/system/admin/v1/base_table_archive.ts +2 -2
  104. package/dist/package/src/rpc/system/admin/v1/base_table_archive_record.ts +2 -2
  105. package/dist/package/src/rpc/system/admin/v1/base_table_archive_restore.ts +2 -2
  106. package/dist/package/src/rpc/system/admin/v1/base_table_backup.ts +2 -2
  107. package/dist/package/src/rpc/system/admin/v1/base_table_backup_record.ts +2 -2
  108. package/dist/package/src/rpc/system/admin/v1/base_table_backup_restore.ts +2 -2
  109. package/dist/package/src/rpc/system/admin/v1/base_table_source.ts +2 -2
  110. package/dist/package/src/rpc/system/admin/v1/base_tenant.ts +1 -1
  111. package/dist/package/src/rpc/system/admin/v1/base_third_account.ts +1 -1
  112. package/dist/package/src/rpc/system/admin/v1/base_user.ts +1 -1
  113. package/dist/package/src/rpc/system/admin/v1/cache.ts +2 -2
  114. package/dist/package/src/rpc/system/admin/v1/code_gen.ts +1 -1
  115. package/dist/package/src/rpc/system/admin/v1/code_gen_column.ts +1 -1
  116. package/dist/package/src/rpc/system/admin/v1/code_gen_proto.ts +1 -1
  117. package/dist/package/src/rpc/system/admin/v1/code_gen_table.ts +1 -1
  118. package/dist/package/src/rpc/system/admin/v1/common.ts +1 -1
  119. package/dist/package/src/rpc/system/admin/v1/oauth_client.ts +2 -2
  120. package/dist/package/src/rpc/system/admin/v1/ops_monitoring.ts +2 -2
  121. package/dist/package/src/rpc/system/admin/v1/runtime_log.ts +1 -1
  122. package/dist/package/src/rpc/system/common/v1/common.ts +1 -1
  123. package/dist/package/src/rpc/system/config/v1/system_config.ts +1 -1
  124. package/dist/package/src/utils/code-gen-progress.ts +15 -0
  125. package/dist/package/src/views/base/config/index.vue +183 -48
  126. package/dist/package/src/views/base/dict/index.vue +6 -9
  127. package/dist/package/src/views/base/dict/item.vue +6 -15
  128. package/dist/package/src/views/base/job/index.vue +16 -17
  129. package/dist/package/src/views/base/login-policy/index.vue +28 -0
  130. package/dist/package/src/views/base/menu/index.vue +78 -15
  131. package/dist/package/src/views/base/online-session/index.vue +116 -0
  132. package/dist/package/src/views/base/user/index.vue +20 -8
  133. package/dist/package/src/views/profile/components/login-log.vue +123 -0
  134. package/dist/package/src/views/profile/components/session.vue +46 -61
  135. package/dist/package/src/views/profile/index.vue +13 -9
  136. package/dist/package/src/views/tool/code-gen/code-preview/index.vue +5 -15
  137. package/dist/package/src/views/tool/code-gen/columns/index.vue +17 -25
  138. package/dist/package/src/views/tool/code-gen/components/CodeGenGenerateConfirm.vue +115 -0
  139. package/dist/package/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue +27 -186
  140. package/dist/package/src/views/tool/code-gen/components/CodeGenProgressDialog.vue +2 -0
  141. package/dist/package/src/views/tool/code-gen/config.ts +15 -1
  142. package/dist/package/src/views/tool/code-gen/table/index.vue +100 -45
  143. package/package.json +3 -2
  144. package/dist/package/declarations/src/config/database-backup.d.ts +0 -12
  145. package/dist/package/src/config/database-backup.ts +0 -57
  146. package/dist/package/src/views/base/runtime-config/index.vue +0 -479
  147. /package/dist/package/declarations/src/views/base/{runtime-config → online-session}/index.vue.d.ts +0 -0
@@ -4,6 +4,7 @@ import type {
4
4
  BaseLoginLogService,
5
5
  GetBaseLoginLogRequest,
6
6
  PageBaseLoginLogRequest,
7
+ PageCurrentUserLoginLogRequest,
7
8
  PageBaseLoginLogResponse
8
9
  } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_login_log";
9
10
 
@@ -11,6 +12,15 @@ const BASE_LOGIN_LOG_URL = "/v1/admin/base/login-log";
11
12
 
12
13
  /** Admin 登录日志服务。 */
13
14
  export class BaseLoginLogServiceImpl implements BaseLoginLogService {
15
+ /** 查询当前用户本人的登录记录。 */
16
+ PageCurrentUserLoginLog(request: PageCurrentUserLoginLogRequest): Promise<PageBaseLoginLogResponse> {
17
+ return service<PageCurrentUserLoginLogRequest, PageBaseLoginLogResponse>({
18
+ url: `${BASE_LOGIN_LOG_URL}/current-user`,
19
+ method: "get",
20
+ params: request
21
+ });
22
+ }
23
+
14
24
  /** 查询登录日志分页列表。 */
15
25
  PageBaseLoginLog(request: PageBaseLoginLogRequest): Promise<PageBaseLoginLogResponse> {
16
26
  return service<PageBaseLoginLogRequest, PageBaseLoginLogResponse>({
@@ -1,8 +1,13 @@
1
1
  import service from "@liujitcn/kratos-admin-core/request";
2
2
  import type {
3
3
  BaseSession,
4
+ ListCurrentBaseSessionsRequest,
5
+ ListCurrentBaseSessionsResponse,
4
6
  GetCurrentBaseSessionRequest,
5
- RevokeAllBaseSessionsRequest
7
+ PageOnlineBaseSessionsRequest,
8
+ PageOnlineBaseSessionsResponse,
9
+ RevokeAllBaseSessionsRequest,
10
+ RevokeBaseSessionRequest
6
11
  } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_session";
7
12
  import type { Empty } from "@liujitcn/kratos-admin-system/rpc/google/protobuf/empty";
8
13
 
@@ -10,6 +15,15 @@ const SESSION_URL = "/v1/admin/base/session";
10
15
 
11
16
  /** BaseSessionService Admin会话管理服务。 */
12
17
  export class BaseSessionServiceImpl {
18
+ /** 查询当前用户全部有效会话。 */
19
+ ListCurrentBaseSessions(request: ListCurrentBaseSessionsRequest): Promise<ListCurrentBaseSessionsResponse> {
20
+ return service<ListCurrentBaseSessionsRequest, ListCurrentBaseSessionsResponse>({
21
+ url: `${SESSION_URL}/current-user`,
22
+ method: "get",
23
+ params: request
24
+ });
25
+ }
26
+
13
27
  /** 查询当前用户会话。 */
14
28
  GetCurrentBaseSession(request: GetCurrentBaseSessionRequest): Promise<BaseSession> {
15
29
  return service<GetCurrentBaseSessionRequest, BaseSession>({
@@ -27,6 +41,23 @@ export class BaseSessionServiceImpl {
27
41
  data: request
28
42
  });
29
43
  }
44
+
45
+ /** 分页查询当前在线用户会话。 */
46
+ PageOnlineBaseSessions(request: PageOnlineBaseSessionsRequest): Promise<PageOnlineBaseSessionsResponse> {
47
+ return service<PageOnlineBaseSessionsRequest, PageOnlineBaseSessionsResponse>({
48
+ url: `${SESSION_URL}/online`,
49
+ method: "get",
50
+ params: request
51
+ });
52
+ }
53
+
54
+ /** 下线指定用户会话。 */
55
+ RevokeBaseSession(request: RevokeBaseSessionRequest): Promise<Empty> {
56
+ return service<RevokeBaseSessionRequest, Empty>({
57
+ url: `${SESSION_URL}/${request.session_id}`,
58
+ method: "delete"
59
+ });
60
+ }
30
61
  }
31
62
 
32
63
  /** defBaseSessionService Admin会话管理服务实例。 */
@@ -1,269 +1,104 @@
1
1
  <template>
2
- <el-link class="dynamic-i18n-cell" type="primary" underline="never" @click="openDialog">
3
- <span class="dynamic-i18n-cell__source">{{ displaySource || "--" }}</span>
4
- </el-link>
5
-
6
- <ProDialog
7
- v-model="dialogVisible"
8
- :title="displaySource"
9
- width="760px"
10
- append-to-body
11
- :show-footer="false"
12
- :destroy-on-close="true"
13
- @closed="handleDialogClosed"
2
+ <DynamicI18nEditor
3
+ v-if="enabled"
4
+ :key="`${targetType}:${targetId}`"
5
+ :model-value="values"
6
+ :source="source"
7
+ :readonly="!editable || !targetType || !targetId || saving"
8
+ :maxlength="10000"
9
+ @update:model-value="saveValues"
14
10
  >
15
- <el-table v-loading="loading" :data="i18nRows" border>
16
- <el-table-column :label="t('common.field.language')" width="150">
17
- <template #default="{ row }">
18
- {{ getLanguageLabel(row.locale) }}
19
- </template>
20
- </el-table-column>
21
- <el-table-column :label="t('system.base.i18n.field.i18ns')" min-width="360">
22
- <template #default="{ row }">
23
- <el-input
24
- v-if="row.editing"
25
- v-model="row.text"
26
- :placeholder="t('system.base.i18n.placeholder.text', { language: getLanguageLabel(row.locale) })"
27
- />
28
- <span v-else class="dynamic-i18n-dialog__text">
29
- {{ row.text || t("common.value.none") }}
30
- </span>
31
- </template>
32
- </el-table-column>
33
- <el-table-column v-if="editable" :label="t('common.field.operation')" width="200" fixed="right">
34
- <template #default="{ row }">
35
- <el-button
36
- v-if="editable && !row.editing"
37
- link
38
- type="primary"
39
- :icon="EditPen"
40
- @click="startEdit(row as DynamicI18nRow)"
41
- >
42
- {{ t("common.action.edit") }}
43
- </el-button>
44
- <template v-else>
45
- <el-button
46
- link
47
- type="primary"
48
- :icon="Check"
49
- :loading="row.saving"
50
- @click="saveI18n(row as DynamicI18nRow)"
51
- >
52
- {{ t("common.action.save") }}
53
- </el-button>
54
- <el-button link :icon="Close" :disabled="row.saving" @click="cancelEdit(row as DynamicI18nRow)">
55
- {{ t("common.action.cancel") }}
56
- </el-button>
57
- </template>
58
- </template>
59
- </el-table-column>
60
- </el-table>
61
- </ProDialog>
11
+ <template #trigger="{ open }">
12
+ <el-link class="dynamic-i18n-cell" type="primary" underline="never" @click="open">
13
+ <span>{{ displaySource || "--" }}</span>
14
+ </el-link>
15
+ </template>
16
+ </DynamicI18nEditor>
17
+ <span v-else>{{ source || "--" }}</span>
62
18
  </template>
63
19
 
64
20
  <script setup lang="ts">
65
21
  import { computed, ref, watch } from "vue";
66
- import { ElMessage } from "element-plus";
67
- import { Check, Close, EditPen } from "@element-plus/icons-vue";
68
- import ProDialog from "@liujitcn/kratos-admin-core/components/Dialog/ProDialog.vue";
69
22
  import { t, useLocaleStore } from "@liujitcn/kratos-admin-core";
70
- import { loadEnabledBaseLanguages, useEnabledBaseLanguages } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_language";
71
23
  import { defBaseI18nService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_i18n";
72
- import type { BaseI18n } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_i18n";
73
- import { I18nTargetType } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_i18n";
74
- import { getLanguageLabel } from "./dynamicI18n";
24
+ import type { BaseI18n, I18nTargetType } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_i18n";
25
+ import DynamicI18nEditor from "./DynamicI18nEditor.vue";
26
+ import { getEditableLanguageOptions, type DynamicI18nValue } from "./dynamicI18n";
75
27
 
76
- /** DynamicI18nCellProps 动态翻译列表单元格属性。 */
28
+ /** 列表国际化字段入口,未启用非主语言时退回普通文本。 */
77
29
  interface DynamicI18nCellProps {
78
- /** 资源源文。 */
79
30
  source: string;
80
- /** 统一翻译表目标类型。 */
81
31
  targetType?: I18nTargetType;
82
- /** 目标资源编号。 */
83
32
  targetId?: number;
84
- /** 资源列表返回的非主语言翻译。 */
85
33
  i18ns?: BaseI18n[];
86
- /** 是否允许编辑翻译。 */
87
34
  editable?: boolean;
88
35
  }
89
-
90
- const props = withDefaults(defineProps<DynamicI18nCellProps>(), {
91
- editable: true
92
- });
93
-
94
- const editable = computed(() => props.editable);
95
-
96
- const { languages } = useEnabledBaseLanguages();
36
+ const props = withDefaults(defineProps<DynamicI18nCellProps>(), { editable: true });
97
37
  const { locale } = useLocaleStore();
98
- const dialogVisible = ref(false);
99
- const loading = ref(false);
100
- const i18nRows = ref<DynamicI18nRow[]>([]);
101
- const i18nOverrides = ref(new Map<string, string>());
102
-
103
- const displaySource = computed(() => {
104
- const override = i18nOverrides.value.get(locale.value);
105
- if (override) return override;
106
- const i18n = props.i18ns?.find(item => item.locale === locale.value && item.name);
107
- return i18n?.name || props.source;
108
- });
109
-
110
- watch(
111
- () => [props.targetType, props.targetId],
112
- () => {
113
- i18nRows.value = [];
114
- i18nOverrides.value.clear();
115
- dialogVisible.value = false;
116
- }
38
+ const enabled = computed(() => getEditableLanguageOptions().length > 0);
39
+ const overrides = ref(new Map<string, string>());
40
+ const saving = ref(false);
41
+ let resourceVersion = 0;
42
+ const values = computed<DynamicI18nValue[]>(() =>
43
+ getEditableLanguageOptions().map(({ value }) => {
44
+ const record = props.i18ns?.find(item => item.locale === value);
45
+ return { id: record?.id ?? 0, locale: value, text: overrides.value.get(value) ?? record?.name ?? "" };
46
+ })
117
47
  );
48
+ const displaySource = computed(() => values.value.find(item => item.locale === locale.value)?.text || props.source);
118
49
 
119
- /** DynamicI18nRow 描述弹窗内可编辑的单语言翻译行。 */
120
- interface DynamicI18nRow {
121
- /** 翻译记录主键,新增翻译时为空。 */
122
- id: number;
123
- /** 语言区域。 */
124
- locale: string;
125
- /** 翻译文本。 */
126
- text: string;
127
- /** 是否处于编辑状态。 */
128
- editing: boolean;
129
- /** 是否正在保存。 */
130
- saving: boolean;
131
- /** 编辑前的文本,用于取消编辑。 */
132
- originalText: string;
133
- }
134
-
135
- /** openDialog 打开翻译编辑弹窗并加载当前资源译文。 */
136
- async function openDialog() {
137
- dialogVisible.value = true;
138
- await loadI18ns();
139
- }
140
-
141
- /** loadI18ns 查询当前资源的翻译并补齐启用语言行。 */
142
- async function loadI18ns() {
50
+ /** 仅在确认后保存发生变化的译文,打开窗口不会自动翻译或写库。 */
51
+ async function saveValues(next: DynamicI18nValue[]) {
143
52
  const targetType = props.targetType;
144
53
  const targetId = props.targetId;
145
- if (!targetType || !targetId) return;
146
- loading.value = true;
54
+ if (!props.editable || !targetType || !targetId || saving.value) return;
55
+ const changed = next.filter(item => item.text !== values.value.find(value => value.locale === item.locale)?.text);
56
+ if (!changed.length) return;
57
+ const version = resourceVersion;
58
+ saving.value = true;
147
59
  try {
148
- await loadEnabledBaseLanguages();
149
- const rows = await queryI18nRows();
150
- i18nRows.value = rows;
151
- if (!props.editable) return;
152
- const missingRows = rows.filter(row => !row.text);
153
- if (missingRows.length === 0) return;
154
- if (!props.source) return;
155
- const draft = await defBaseI18nService.DraftBaseI18n({ source: props.source });
156
- const i18ns = new Map(draft.i18ns.map(item => [item.locale, item.i18n]));
157
60
  const results = await Promise.allSettled(
158
- missingRows.map(async row => {
159
- const i18n = i18ns.get(row.locale);
160
- if (!i18n) throw new Error("i18n not found");
61
+ changed.map(async item => {
161
62
  await defBaseI18nService.UpdateBaseI18n({
162
- id: row.id,
63
+ id: item.id,
163
64
  target_type: targetType,
164
65
  target_id: targetId,
165
- locale: row.locale,
166
- name: i18n
66
+ locale: item.locale,
67
+ name: item.text
167
68
  });
168
- return { row, text: i18n };
69
+ return item;
169
70
  })
170
71
  );
72
+ if (version !== resourceVersion) return;
171
73
  for (const result of results) {
172
- if (result.status !== "fulfilled") continue;
173
- result.value.row.text = result.value.text;
174
- result.value.row.originalText = result.value.text;
175
- i18nOverrides.value.set(result.value.row.locale, result.value.text);
74
+ if (result.status === "fulfilled") overrides.value.set(result.value.locale, result.value.text);
176
75
  }
177
- } catch {
178
- ElMessage.error(t("common.message.system_error"));
76
+ if (results.some(result => result.status === "rejected")) ElMessage.error(t("common.message.system_error"));
77
+ else ElMessage.success(t("common.message.operation_success"));
179
78
  } finally {
180
- loading.value = false;
79
+ if (version === resourceVersion) saving.value = false;
181
80
  }
182
81
  }
183
82
 
184
- /** queryI18nRows 将列表返回的翻译记录补齐为可编辑语言行。 */
185
- async function queryI18nRows(): Promise<DynamicI18nRow[]> {
186
- const records = new Map((props.i18ns ?? []).map(item => [item.locale, item]));
187
- return languages.value
188
- .filter(item => !item.is_primary)
189
- .map(item => {
190
- const record = records.get(item.language_code);
191
- const text = i18nOverrides.value.get(item.language_code) ?? record?.name ?? "";
192
- return {
193
- id: record?.id ?? 0,
194
- locale: item.language_code,
195
- text,
196
- editing: false,
197
- saving: false,
198
- originalText: text
199
- };
200
- });
201
- }
202
-
203
- /** startEdit 开启指定语言的编辑状态。 */
204
- function startEdit(row: DynamicI18nRow) {
205
- if (!props.editable) return;
206
- row.originalText = row.text;
207
- row.editing = true;
208
- }
209
-
210
- /** cancelEdit 恢复编辑前的内容。 */
211
- function cancelEdit(row: DynamicI18nRow) {
212
- row.text = row.originalText;
213
- row.editing = false;
214
- }
215
-
216
- /** saveI18n 使用统一更新接口保存指定语言译文。 */
217
- async function saveI18n(row: DynamicI18nRow) {
218
- const targetType = props.targetType;
219
- const targetId = props.targetId;
220
- if (!props.editable || row.saving || !targetType || !targetId) return;
221
- if (row.id === 0 && !row.text) {
222
- row.editing = false;
223
- return;
224
- }
225
- row.saving = true;
226
- try {
227
- await defBaseI18nService.UpdateBaseI18n({
228
- id: row.id,
229
- target_type: targetType,
230
- target_id: targetId,
231
- locale: row.locale,
232
- name: row.text
233
- });
234
- ElMessage.success(t("common.message.operation_success"));
235
- row.editing = false;
236
- row.originalText = row.text;
237
- i18nOverrides.value.set(row.locale, row.text);
238
- } catch {
239
- ElMessage.error(t("common.message.system_error"));
240
- } finally {
241
- row.saving = false;
83
+ watch(
84
+ () => [props.targetType, props.targetId],
85
+ () => {
86
+ resourceVersion++;
87
+ overrides.value.clear();
88
+ saving.value = false;
242
89
  }
243
- }
244
-
245
- /** handleDialogClosed 清理弹窗状态,避免复用旧资源译文。 */
246
- function handleDialogClosed() {
247
- i18nRows.value = [];
248
- loading.value = false;
249
- }
90
+ );
250
91
  </script>
251
92
 
252
93
  <style scoped>
253
94
  .dynamic-i18n-cell {
254
95
  display: inline-flex;
255
- align-items: center;
256
96
  min-width: 0;
257
97
  max-width: 100%;
258
98
  }
259
- .dynamic-i18n-cell__source {
260
- min-width: 0;
99
+ .dynamic-i18n-cell span {
261
100
  overflow: hidden;
262
101
  text-overflow: ellipsis;
263
102
  white-space: nowrap;
264
103
  }
265
- .dynamic-i18n-dialog__text {
266
- min-width: 0;
267
- overflow-wrap: anywhere;
268
- }
269
104
  </style>