@liujitcn/kratos-admin-system 0.0.19 → 0.0.21

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 (86) hide show
  1. package/README.md +51 -50
  2. package/dist/package/declarations/src/api/system/base_language.d.ts +51 -0
  3. package/dist/package/declarations/src/api/system/base_translation.d.ts +7 -0
  4. package/dist/package/declarations/src/api/system/code_gen_i18n.d.ts +8 -0
  5. package/dist/package/declarations/src/components/DynamicTranslationCell.vue.d.ts +39 -0
  6. package/dist/package/declarations/src/components/DynamicTranslationEditor.vue.d.ts +23 -0
  7. package/dist/package/declarations/src/components/dynamicTranslation.d.ts +44 -0
  8. package/dist/package/declarations/src/rpc/system/admin/v1/base_config.d.ts +5 -0
  9. package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +79 -0
  10. package/dist/package/declarations/src/rpc/system/admin/v1/base_language.d.ts +114 -0
  11. package/dist/package/declarations/src/rpc/system/admin/v1/base_menu.d.ts +40 -0
  12. package/dist/package/declarations/src/rpc/system/admin/v1/base_translation.d.ts +102 -0
  13. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen.d.ts +2 -0
  14. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_column.d.ts +7 -0
  15. package/dist/package/declarations/src/rpc/system/admin/v1/code_gen_table.d.ts +13 -0
  16. package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue.d.ts +23 -0
  17. package/dist/package/declarations/src/views/tool/code-gen/config.d.ts +7 -7
  18. package/dist/package/declarations/src/views/tool/language/index.vue.d.ts +3 -0
  19. package/dist/package/src/api/base/ai_message.ts +7 -12
  20. package/dist/package/src/api/base/sse.ts +3 -1
  21. package/dist/package/src/api/system/base_language.ts +137 -0
  22. package/dist/package/src/api/system/base_translation.ts +22 -0
  23. package/dist/package/src/api/system/code_gen_column.ts +17 -3
  24. package/dist/package/src/api/system/code_gen_i18n.ts +18 -0
  25. package/dist/package/src/api/system/code_gen_table.ts +12 -4
  26. package/dist/package/src/components/DynamicTranslationCell.vue +176 -0
  27. package/dist/package/src/components/DynamicTranslationEditor.vue +166 -0
  28. package/dist/package/src/components/dynamicTranslation.ts +86 -0
  29. package/dist/package/src/locales/README.md +28 -0
  30. package/dist/package/src/locales/en-US.json +929 -0
  31. package/dist/package/src/locales/es-ES.json +928 -0
  32. package/dist/package/src/locales/fr-FR.json +928 -0
  33. package/dist/package/src/locales/ja-JP.json +929 -0
  34. package/dist/package/src/locales/ko-KR.json +928 -0
  35. package/dist/package/src/locales/zh-CN.json +929 -0
  36. package/dist/package/src/locales/zh-TW.json +928 -0
  37. package/dist/package/src/module.ts +19 -1
  38. package/dist/package/src/rpc/system/admin/v1/base_config.ts +5 -0
  39. package/dist/package/src/rpc/system/admin/v1/base_dict.ts +81 -0
  40. package/dist/package/src/rpc/system/admin/v1/base_language.ts +135 -0
  41. package/dist/package/src/rpc/system/admin/v1/base_menu.ts +41 -0
  42. package/dist/package/src/rpc/system/admin/v1/base_translation.ts +117 -0
  43. package/dist/package/src/rpc/system/admin/v1/code_gen.ts +5 -1
  44. package/dist/package/src/rpc/system/admin/v1/code_gen_column.ts +8 -0
  45. package/dist/package/src/rpc/system/admin/v1/code_gen_table.ts +15 -0
  46. package/dist/package/src/views/ai/chat/components/AiMarkdown.vue +1 -6
  47. package/dist/package/src/views/ai/chat/components/ChatPanel.vue +70 -53
  48. package/dist/package/src/views/ai/chat/components/SessionPanel.vue +20 -9
  49. package/dist/package/src/views/ai/chat/components/XSender.vue +36 -23
  50. package/dist/package/src/views/ai/chat/index.vue +55 -39
  51. package/dist/package/src/views/ai/chat/message.ts +18 -17
  52. package/dist/package/src/views/base/api/index.vue +121 -83
  53. package/dist/package/src/views/base/area/index.vue +81 -31
  54. package/dist/package/src/views/base/config/index.vue +272 -78
  55. package/dist/package/src/views/base/dept/index.vue +110 -61
  56. package/dist/package/src/views/base/dict/index.vue +137 -58
  57. package/dist/package/src/views/base/dict/item.vue +147 -61
  58. package/dist/package/src/views/base/job/index.vue +134 -81
  59. package/dist/package/src/views/base/job/log.vue +21 -22
  60. package/dist/package/src/views/base/log/index.vue +68 -46
  61. package/dist/package/src/views/base/menu/index.vue +257 -156
  62. package/dist/package/src/views/base/migration/index.vue +49 -29
  63. package/dist/package/src/views/base/post/index.vue +128 -59
  64. package/dist/package/src/views/base/role/index.vue +145 -78
  65. package/dist/package/src/views/base/tenant/index.vue +132 -63
  66. package/dist/package/src/views/base/user/components/dept-tree.vue +2 -1
  67. package/dist/package/src/views/base/user/index.vue +192 -112
  68. package/dist/package/src/views/profile/components/base.vue +44 -27
  69. package/dist/package/src/views/profile/components/password.vue +43 -27
  70. package/dist/package/src/views/profile/components/security.vue +89 -53
  71. package/dist/package/src/views/profile/index.vue +10 -9
  72. package/dist/package/src/views/tool/api-doc/index.vue +6 -2
  73. package/dist/package/src/views/tool/code-gen/code-preview/index.vue +30 -14
  74. package/dist/package/src/views/tool/code-gen/columns/index.vue +382 -273
  75. package/dist/package/src/views/tool/code-gen/columns/option-copy.ts +1 -6
  76. package/dist/package/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue +118 -0
  77. package/dist/package/src/views/tool/code-gen/components/CodeGenProgressDialog.vue +65 -36
  78. package/dist/package/src/views/tool/code-gen/components/CodePreviewPane.vue +8 -5
  79. package/dist/package/src/views/tool/code-gen/config.ts +114 -77
  80. package/dist/package/src/views/tool/code-gen/preview/data.ts +19 -17
  81. package/dist/package/src/views/tool/code-gen/preview/index.vue +96 -58
  82. package/dist/package/src/views/tool/code-gen/proto/index.vue +110 -62
  83. package/dist/package/src/views/tool/code-gen/table/index.vue +197 -117
  84. package/dist/package/src/views/tool/language/index.vue +256 -0
  85. package/dist/package/src/views/tool/project-doc/index.vue +17 -15
  86. package/package.json +6 -2
@@ -3,26 +3,41 @@
3
3
  <div v-loading="loading" class="table-box migration-page">
4
4
  <main class="migration-content">
5
5
  <el-form class="migration-filters" :model="filters" inline @submit.prevent="handleSearch">
6
- <el-form-item label="模块">
7
- <el-input v-model="filters.module" clearable placeholder="请输入迁移模块" @keyup.enter="handleSearch" />
6
+ <el-form-item :label="t('system.migration.field.module')">
7
+ <el-input
8
+ v-model="filters.module"
9
+ clearable
10
+ :placeholder="t('system.migration.placeholder.module')"
11
+ @keyup.enter="handleSearch"
12
+ />
8
13
  </el-form-item>
9
- <el-form-item label="数据源">
10
- <el-input v-model="filters.data_source" clearable placeholder="请输入数据源名称" @keyup.enter="handleSearch" />
14
+ <el-form-item :label="t('system.migration.field.dataSource')">
15
+ <el-input
16
+ v-model="filters.data_source"
17
+ clearable
18
+ :placeholder="t('system.migration.placeholder.dataSource')"
19
+ @keyup.enter="handleSearch"
20
+ />
11
21
  </el-form-item>
12
- <el-form-item label="版本">
13
- <el-input v-model="filters.version" clearable placeholder="请输入版本号" @keyup.enter="handleSearch" />
22
+ <el-form-item :label="t('system.migration.field.version')">
23
+ <el-input
24
+ v-model="filters.version"
25
+ clearable
26
+ :placeholder="t('system.migration.placeholder.version')"
27
+ @keyup.enter="handleSearch"
28
+ />
14
29
  </el-form-item>
15
30
  <el-form-item class="migration-filters__actions">
16
- <el-button type="primary" :icon="Search" native-type="submit">查询</el-button>
17
- <el-button :icon="Refresh" @click="handleReset">重置</el-button>
31
+ <el-button type="primary" :icon="Search" native-type="submit">{{ t("common.action.search") }}</el-button>
32
+ <el-button :icon="Refresh" @click="handleReset">{{ t("common.action.reset") }}</el-button>
18
33
  </el-form-item>
19
34
  </el-form>
20
35
 
21
- <el-empty v-if="!loading && !histories.length" description="暂无升级历史" />
36
+ <el-empty v-if="!loading && !histories.length" :description="t('system.migration.message.emptyHistory')" />
22
37
 
23
- <section v-else class="migration-workspace" aria-label="数据库升级历史">
38
+ <section v-else class="migration-workspace" :aria-label="t('system.migration.title.history')">
24
39
  <aside class="migration-list-panel">
25
- <div class="migration-list-scroll" role="listbox" aria-label="升级记录列表">
40
+ <div class="migration-list-scroll" role="listbox" :aria-label="t('system.migration.title.list')">
26
41
  <button
27
42
  v-for="history in histories"
28
43
  :key="history.id"
@@ -36,14 +51,14 @@
36
51
  <strong>{{ history.version }}</strong>
37
52
  </div>
38
53
  <div class="migration-list-item__data-source">
39
- {{ history.module || "数据库迁移" }} · {{ history.data_source || "default" }}
54
+ {{ history.module || t("system.migration.value.defaultModule") }} · {{ history.data_source || "default" }}
40
55
  </div>
41
56
  <time :datetime="history.created_at">{{ formatDate(history.created_at) }}</time>
42
57
  </button>
43
58
  </div>
44
59
 
45
60
  <div v-if="pageable.total > pageable.page_size" class="migration-pagination">
46
- <span class="migration-pagination__total">共 {{ pageable.total }} 条</span>
61
+ <span class="migration-pagination__total">{{ t("system.migration.message.total", { total: pageable.total }) }}</span>
47
62
  <el-pagination
48
63
  background
49
64
  small
@@ -65,7 +80,8 @@
65
80
  <header class="detail-header">
66
81
  <div class="detail-header__title">
67
82
  <span class="detail-header__data-source">
68
- {{ selectedMigration.module || "数据库迁移" }} · {{ selectedMigration.data_source || "default" }}
83
+ {{ selectedMigration.module || t("system.migration.value.defaultModule") }} ·
84
+ {{ selectedMigration.data_source || "default" }}
69
85
  </span>
70
86
  <div class="detail-header__version">
71
87
  <h2>{{ selectedMigration.version }}</h2>
@@ -81,7 +97,7 @@
81
97
  <section v-if="selectedMigration.description" class="detail-section">
82
98
  <div class="detail-section__title">
83
99
  <el-icon><Document /></el-icon>
84
- <span>升级说明</span>
100
+ <span>{{ t("system.migration.section.description") }}</span>
85
101
  </div>
86
102
  <MarkdownPreview
87
103
  class="migration-markdown"
@@ -94,26 +110,26 @@
94
110
  <section v-if="selectedMigration.up_sql || selectedMigration.down_sql" class="detail-section">
95
111
  <div class="detail-section__title">
96
112
  <el-icon><Files /></el-icon>
97
- <span>SQL 脚本</span>
113
+ <span>{{ t("system.migration.section.sql") }}</span>
98
114
  </div>
99
115
  <el-collapse class="release-sql">
100
116
  <el-collapse-item v-if="selectedMigration.up_sql" name="up">
101
117
  <template #title>
102
118
  <span class="sql-title">
103
119
  <el-icon><DocumentAdd /></el-icon>
104
- <span>升级脚本</span>
120
+ <span>{{ t("system.migration.field.upScript") }}</span>
105
121
  <code>up.sql</code>
106
122
  </span>
107
123
  </template>
108
124
  <div class="sql-panel">
109
125
  <pre class="sql-code"><code>{{ selectedMigration.up_sql }}</code></pre>
110
- <el-tooltip content="复制升级脚本" placement="top">
126
+ <el-tooltip :content="t('system.migration.action.copyUpScript')" placement="top">
111
127
  <el-button
112
128
  class="sql-copy"
113
129
  text
114
130
  circle
115
131
  :icon="CopyDocument"
116
- aria-label="复制升级脚本"
132
+ :aria-label="t('system.migration.action.copyUpScript')"
117
133
  @click.stop="copySql(selectedMigration.up_sql)"
118
134
  />
119
135
  </el-tooltip>
@@ -123,19 +139,19 @@
123
139
  <template #title>
124
140
  <span class="sql-title">
125
141
  <el-icon><DocumentRemove /></el-icon>
126
- <span>回退脚本</span>
142
+ <span>{{ t("system.migration.field.downScript") }}</span>
127
143
  <code>down.sql</code>
128
144
  </span>
129
145
  </template>
130
146
  <div class="sql-panel">
131
147
  <pre class="sql-code"><code>{{ selectedMigration.down_sql }}</code></pre>
132
- <el-tooltip content="复制回退脚本" placement="top">
148
+ <el-tooltip :content="t('system.migration.action.copyDownScript')" placement="top">
133
149
  <el-button
134
150
  class="sql-copy"
135
151
  text
136
152
  circle
137
153
  :icon="CopyDocument"
138
- aria-label="复制回退脚本"
154
+ :aria-label="t('system.migration.action.copyDownScript')"
139
155
  @click.stop="copySql(selectedMigration.down_sql)"
140
156
  />
141
157
  </el-tooltip>
@@ -146,15 +162,14 @@
146
162
 
147
163
  <div v-if="!hasDetailContent" class="detail-empty">
148
164
  <el-icon><Document /></el-icon>
149
- <span>该记录暂无描述或脚本</span>
165
+ <span>{{ t("system.migration.message.emptyDetail") }}</span>
150
166
  </div>
151
167
  </template>
152
168
  </div>
153
169
  </template>
154
- <el-empty v-else description="请选择一条升级记录" />
170
+ <el-empty v-else :description="t('system.migration.message.selectRecord')" />
155
171
  </section>
156
172
  </section>
157
-
158
173
  </main>
159
174
  </div>
160
175
  </template>
@@ -166,7 +181,12 @@ import MarkdownPreview from "@liujitcn/kratos-admin-core/components/MarkdownPrev
166
181
  import { useGlobalStore } from "@liujitcn/kratos-admin-core/stores/runtime";
167
182
  import { buildPageRequest } from "@liujitcn/kratos-admin-core/table";
168
183
  import { defBaseMigrationService } from "@liujitcn/kratos-admin-system/api/system/base_migration";
169
- import type { BaseMigration, BaseMigrationListItem, PageBaseMigrationRequest } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_migration";
184
+ import type {
185
+ BaseMigration,
186
+ BaseMigrationListItem,
187
+ PageBaseMigrationRequest
188
+ } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_migration";
189
+ import { getCurrentLocale, t } from "@liujitcn/kratos-admin-core";
170
190
 
171
191
  defineOptions({
172
192
  name: "BaseMigration",
@@ -296,9 +316,9 @@ function handleCurrentPageChange(page: number) {
296
316
  async function copySql(sql: string) {
297
317
  try {
298
318
  await navigator.clipboard.writeText(sql);
299
- ElMessage.success("SQL 脚本已复制");
319
+ ElMessage.success(t("system.migration.message.copySuccess"));
300
320
  } catch {
301
- ElMessage.error("复制失败,请手动选择脚本内容");
321
+ ElMessage.error(t("system.migration.message.copyFailed"));
302
322
  }
303
323
  }
304
324
 
@@ -309,7 +329,7 @@ function formatDate(value: string) {
309
329
  if (!value) return "--";
310
330
  const date = new Date(value.replace(" ", "T"));
311
331
  if (Number.isNaN(date.getTime())) return value;
312
- return new Intl.DateTimeFormat("zh-CN", {
332
+ return new Intl.DateTimeFormat(getCurrentLocale(), {
313
333
  year: "numeric",
314
334
  month: "short",
315
335
  day: "numeric"
@@ -12,7 +12,7 @@
12
12
  <FormDialog
13
13
  v-model="dialog.visible"
14
14
  ref="formDialogRef"
15
- :title="dialog.title"
15
+ :title="t(dialog.titleKey, { resource: t('system.post.resource') })"
16
16
  width="560px"
17
17
  :model="formData"
18
18
  :fields="formFields"
@@ -41,6 +41,7 @@ import { Status } from "@liujitcn/kratos-admin-system/rpc/common/v1/enum";
41
41
  import { buildPageRequest, normalizeSelectedIds } from "@liujitcn/kratos-admin-core/table";
42
42
  import { DEFAULT_TENANT_CODE, requestTenantOptions } from "@liujitcn/kratos-admin-core/tenant";
43
43
  import { useUserStore } from "@liujitcn/kratos-admin-core/stores/runtime";
44
+ import { t } from "@liujitcn/kratos-admin-core";
44
45
 
45
46
  defineOptions({
46
47
  name: "BasePost",
@@ -59,14 +60,14 @@ const proTable = ref<ProTableInstance>();
59
60
  const formDialogRef = ref<InstanceType<typeof FormDialog>>();
60
61
 
61
62
  const dialog = reactive({
62
- title: "",
63
+ titleKey: "system.common.action.createResource",
63
64
  visible: false
64
65
  });
65
66
  const tenantOptions = ref<SelectOptionResponse_Option[]>([]);
66
- const statusOptions: ProFormOption[] = [
67
- { label: "启用", value: Status.ENABLE },
68
- { label: "禁用", value: Status.DISABLE }
69
- ];
67
+ const statusOptions = computed<ProFormOption[]>(() => [
68
+ { label: t("common.status.enabled"), value: Status.ENABLE },
69
+ { label: t("common.status.disabled"), value: Status.DISABLE }
70
+ ]);
70
71
  const formData = reactive<BasePostFormState>({
71
72
  /** 岗位ID。 */
72
73
  id: 0,
@@ -83,20 +84,54 @@ const formData = reactive<BasePostFormState>({
83
84
  /** 备注。 */
84
85
  remark: ""
85
86
  });
86
- const rules = reactive({
87
- tenant_id: [{ required: true, message: "请选择所属租户", trigger: "change" }],
87
+ const rules = computed(() => ({
88
+ tenant_id: [
89
+ {
90
+ required: true,
91
+ message: t("system.common.validation.requiredSelect", { field: t("system.common.field.tenant") }),
92
+ trigger: "change"
93
+ }
94
+ ],
88
95
  name: [
89
- { required: true, message: "请输入岗位名称", trigger: "blur" },
90
- { max: 30, message: "岗位名称不能超过 30 个字符", trigger: "blur" }
96
+ {
97
+ required: true,
98
+ message: t("system.common.validation.requiredInput", { field: t("system.post.field.name") }),
99
+ trigger: "blur"
100
+ },
101
+ {
102
+ max: 30,
103
+ message: t("system.common.validation.maxLength", { field: t("system.post.field.name"), max: 30 }),
104
+ trigger: "blur"
105
+ }
91
106
  ],
92
107
  code: [
93
- { required: true, message: "请输入岗位编号", trigger: "blur" },
94
- { max: 20, message: "岗位编号不能超过 20 个字符", trigger: "blur" }
108
+ {
109
+ required: true,
110
+ message: t("system.common.validation.requiredInput", { field: t("system.post.field.code") }),
111
+ trigger: "blur"
112
+ },
113
+ {
114
+ max: 20,
115
+ message: t("system.common.validation.maxLength", { field: t("system.post.field.code"), max: 20 }),
116
+ trigger: "blur"
117
+ }
95
118
  ],
96
- sort: [{ required: true, type: "number", min: 1, message: "排序必须大于 0", trigger: "blur" }],
97
- status: [{ required: true, message: "请选择状态", trigger: "change" }],
98
- remark: [{ max: 500, message: "备注不能超过 500 个字符", trigger: "blur" }]
99
- });
119
+ sort: [{ required: true, type: "number", min: 1, message: t("system.common.validation.sortPositive"), trigger: "blur" }],
120
+ status: [
121
+ {
122
+ required: true,
123
+ message: t("system.common.validation.requiredSelect", { field: t("system.common.field.status") }),
124
+ trigger: "change"
125
+ }
126
+ ],
127
+ remark: [
128
+ {
129
+ max: 500,
130
+ message: t("system.common.validation.maxLength", { field: t("system.common.field.remark"), max: 500 }),
131
+ trigger: "blur"
132
+ }
133
+ ]
134
+ }));
100
135
 
101
136
  /** 当前登录账号是否默认租户。 */
102
137
  const isDefaultTenant = computed(() => userStore.userInfo.tenant_code === DEFAULT_TENANT_CODE);
@@ -105,22 +140,41 @@ const isDefaultTenant = computed(() => userStore.userInfo.tenant_code === DEFAUL
105
140
  const formFields = computed<ProFormField[]>(() => [
106
141
  {
107
142
  prop: "tenant_id",
108
- label: "所属租户",
143
+ label: t("system.common.field.tenant"),
109
144
  component: "select",
110
- props: { placeholder: "请选择所属租户", filterable: true, disabled: Boolean(formData.id) },
145
+ props: {
146
+ placeholder: t("system.common.validation.requiredSelect", { field: t("system.common.field.tenant") }),
147
+ filterable: true,
148
+ disabled: Boolean(formData.id)
149
+ },
111
150
  visible: () => isDefaultTenant.value,
112
151
  options: tenantOptions.value
113
152
  },
114
- { prop: "name", label: "岗位名称", component: "input", props: { placeholder: "请输入岗位名称" } },
115
- { prop: "code", label: "岗位编号", component: "input", props: { placeholder: "请输入岗位编号" } },
153
+ {
154
+ prop: "name",
155
+ label: t("system.post.field.name"),
156
+ component: "input",
157
+ props: { placeholder: t("system.common.validation.requiredInput", { field: t("system.post.field.name") }) }
158
+ },
159
+ {
160
+ prop: "code",
161
+ label: t("system.post.field.code"),
162
+ component: "input",
163
+ props: { placeholder: t("system.common.validation.requiredInput", { field: t("system.post.field.code") }) }
164
+ },
116
165
  {
117
166
  prop: "sort",
118
- label: "排序",
167
+ label: t("system.common.field.sort"),
119
168
  component: "input-number",
120
169
  props: { min: 1, precision: 0, step: 1, controlsPosition: "right", style: { width: "100%" } }
121
170
  },
122
- { prop: "status", label: "状态", component: "radio-group", options: statusOptions },
123
- { prop: "remark", label: "备注", component: "textarea", props: { placeholder: "请输入备注" } }
171
+ { prop: "status", label: t("system.common.field.status"), component: "radio-group", options: statusOptions.value },
172
+ {
173
+ prop: "remark",
174
+ label: t("system.common.field.remark"),
175
+ component: "textarea",
176
+ props: { placeholder: t("system.common.placeholder.remark") }
177
+ }
124
178
  ]);
125
179
 
126
180
  /** 岗位表格列配置。 */
@@ -130,7 +184,7 @@ const columns = computed<ColumnProps[]>(() => [
130
184
  ? ([
131
185
  {
132
186
  prop: "tenant_id",
133
- label: "租户",
187
+ label: t("system.common.field.tenant"),
134
188
  minWidth: 140,
135
189
  showOverflowTooltip: true,
136
190
  search: { el: "select", key: "tenant_id", props: { filterable: true }, order: 1 },
@@ -138,36 +192,36 @@ const columns = computed<ColumnProps[]>(() => [
138
192
  }
139
193
  ] satisfies ColumnProps[])
140
194
  : []),
141
- { prop: "name", label: "岗位名称", minWidth: 140, search: { el: "input" } },
142
- { prop: "code", label: "岗位编号", minWidth: 140, search: { el: "input" } },
143
- { prop: "sort", label: "排序", minWidth: 90, align: "right" },
195
+ { prop: "name", label: t("system.post.field.name"), minWidth: 140, search: { el: "input" } },
196
+ { prop: "code", label: t("system.post.field.code"), minWidth: 140, search: { el: "input" } },
197
+ { prop: "sort", label: t("system.common.field.sort"), minWidth: 90, align: "right" },
144
198
  {
145
199
  prop: "status",
146
- label: "状态",
200
+ label: t("system.common.field.status"),
147
201
  minWidth: 100,
148
202
  search: { el: "select" },
149
203
  cellType: "status",
150
204
  statusProps: {
151
205
  activeValue: Status.ENABLE,
152
206
  inactiveValue: Status.DISABLE,
153
- activeText: "启用",
154
- inactiveText: "禁用",
207
+ activeText: t("common.status.enabled"),
208
+ inactiveText: t("common.status.disabled"),
155
209
  disabled: () => !BUTTONS.value["base:post:status"],
156
210
  beforeChange: scope => handleBeforeSetStatus(scope.row as BasePost)
157
211
  }
158
212
  },
159
- { prop: "remark", label: "备注", minWidth: 160 },
160
- { prop: "created_at", label: "创建时间", minWidth: 180 },
161
- { prop: "updated_at", label: "更新时间", minWidth: 180 },
213
+ { prop: "remark", label: t("system.common.field.remark"), minWidth: 160 },
214
+ { prop: "created_at", label: t("system.common.field.createdAt"), minWidth: 180 },
215
+ { prop: "updated_at", label: t("system.common.field.updatedAt"), minWidth: 180 },
162
216
  {
163
217
  prop: "operation",
164
- label: "操作",
218
+ label: t("system.common.field.operation"),
165
219
  width: 180,
166
220
  fixed: "right",
167
221
  cellType: "actions",
168
222
  actions: [
169
223
  {
170
- label: "编辑",
224
+ label: t("common.action.edit"),
171
225
  type: "primary",
172
226
  link: true,
173
227
  icon: EditPen,
@@ -176,7 +230,7 @@ const columns = computed<ColumnProps[]>(() => [
176
230
  onClick: (scope, params) => handleOpenDialog((params?.postId as number | undefined) ?? (scope.row as BasePost).id)
177
231
  },
178
232
  {
179
- label: "删除",
233
+ label: t("common.action.delete"),
180
234
  type: "danger",
181
235
  link: true,
182
236
  icon: Delete,
@@ -188,23 +242,23 @@ const columns = computed<ColumnProps[]>(() => [
188
242
  ]);
189
243
 
190
244
  /** 岗位顶部按钮配置。 */
191
- const headerActions: HeaderActionProps[] = [
245
+ const headerActions = computed<HeaderActionProps[]>(() => [
192
246
  {
193
- label: "新增",
247
+ label: t("common.action.create"),
194
248
  type: "success",
195
249
  icon: CirclePlus,
196
250
  hidden: () => !BUTTONS.value["base:post:create"],
197
251
  onClick: () => handleOpenDialog()
198
252
  },
199
253
  {
200
- label: "删除",
254
+ label: t("common.action.delete"),
201
255
  type: "danger",
202
256
  icon: Delete,
203
257
  hidden: () => !BUTTONS.value["base:post:delete"],
204
258
  disabled: scope => !scope.selectedList.length,
205
259
  onClick: scope => handleDelete(scope.selectedList as BasePost[])
206
260
  }
207
- ];
261
+ ]);
208
262
 
209
263
  /** 请求岗位分页列表。 */
210
264
  async function requestBasePostTable(params: PageBasePostRequest) {
@@ -231,7 +285,7 @@ async function loadTenantOptions() {
231
285
  async function handleOpenDialog(id?: number) {
232
286
  resetForm();
233
287
  await loadTenantOptions();
234
- dialog.title = id ? "修改岗位" : "新增岗位";
288
+ dialog.titleKey = id ? "system.common.action.editResource" : "system.common.action.createResource";
235
289
  dialog.visible = true;
236
290
  if (id) Object.assign(formData, await defBasePostService.GetBasePost({ id }));
237
291
  }
@@ -264,7 +318,11 @@ function handleSubmit() {
264
318
  ? defBasePostService.UpdateBasePost({ base_post: submitData })
265
319
  : defBasePostService.CreateBasePost({ base_post: submitData });
266
320
  request.then(() => {
267
- ElMessage.success(submitData.id ? "修改岗位成功" : "新增岗位成功");
321
+ ElMessage.success(
322
+ t(submitData.id ? "system.common.message.updateSuccess" : "system.common.message.createSuccess", {
323
+ resource: t("system.post.resource")
324
+ })
325
+ );
268
326
  handleCloseDialog();
269
327
  refreshTable();
270
328
  });
@@ -274,15 +332,24 @@ function handleSubmit() {
274
332
  /** 在岗位状态切换前确认并提交。 */
275
333
  async function handleBeforeSetStatus(row: BasePost) {
276
334
  const nextStatus = row.status === Status.ENABLE ? Status.DISABLE : Status.ENABLE;
277
- const text = nextStatus === Status.ENABLE ? "启用" : "禁用";
335
+ const text = t(nextStatus === Status.ENABLE ? "common.status.enabled" : "common.status.disabled");
278
336
  try {
279
- await ElMessageBox.confirm(`是否确定${text}岗位?\n岗位名称:${row.name || row.code || `ID:${row.id}`}`, "提示", {
280
- confirmButtonText: "确认",
281
- cancelButtonText: "取消",
282
- type: "warning"
283
- });
337
+ await ElMessageBox.confirm(
338
+ t("system.common.dialog.statusChange", {
339
+ action: text,
340
+ resource: t("system.post.resource"),
341
+ field: t("system.post.field.name"),
342
+ value: row.name || row.code || `ID:${row.id}`
343
+ }),
344
+ t("common.title.notice"),
345
+ {
346
+ confirmButtonText: t("common.action.confirm"),
347
+ cancelButtonText: t("common.action.cancel"),
348
+ type: "warning"
349
+ }
350
+ );
284
351
  await defBasePostService.SetBasePostStatus({ id: row.id, status: nextStatus });
285
- ElMessage.success(`${text}成功`);
352
+ ElMessage.success(t("system.common.message.statusSuccess", { action: text }));
286
353
  refreshTable();
287
354
  return true;
288
355
  } catch {
@@ -297,28 +364,30 @@ function handleDelete(selected?: number | string | Array<number | string> | Base
297
364
  : selected && typeof selected === "object"
298
365
  ? [selected as BasePost]
299
366
  : [];
300
- const postIds = (postList.length ? postList.map(item => item.id) : normalizeSelectedIds(selected as number | string | Array<number | string>)).join(",");
367
+ const postIds = (
368
+ postList.length ? postList.map(item => item.id) : normalizeSelectedIds(selected as number | string | Array<number | string>)
369
+ ).join(",");
301
370
  if (!postIds) {
302
- ElMessage.warning("请勾选删除项");
371
+ ElMessage.warning(t("system.common.message.selectDeleteItem"));
303
372
  return;
304
373
  }
305
374
  const confirmMessage =
306
375
  postList.length === 1
307
- ? `是否确定删除岗位?\n岗位名称:${postList[0].name || postList[0].code || `ID:${postList[0].id}`}`
376
+ ? `${t("system.common.dialog.deleteSingle", { resource: t("system.post.resource") })}\n${t("system.common.dialog.resourceField", { field: t("system.post.field.name"), value: postList[0].name || postList[0].code || `ID:${postList[0].id}` })}`
308
377
  : postList.length > 1
309
- ? `确认删除已选中的 ${postList.length} 个岗位吗?`
310
- : "确认删除已选中的岗位吗?";
311
- ElMessageBox.confirm(confirmMessage, "警告", {
312
- confirmButtonText: "确定",
313
- cancelButtonText: "取消",
378
+ ? t("system.common.dialog.deleteBatch", { count: postList.length, unit: "", resource: t("system.post.resource") })
379
+ : t("system.common.dialog.deleteSelected", { resource: t("system.post.resource") });
380
+ ElMessageBox.confirm(confirmMessage, t("common.title.warning"), {
381
+ confirmButtonText: t("common.action.confirm"),
382
+ cancelButtonText: t("common.action.cancel"),
314
383
  type: "warning"
315
384
  }).then(
316
385
  () =>
317
386
  defBasePostService.DeleteBasePost({ id: postIds }).then(() => {
318
- ElMessage.success("删除岗位成功");
387
+ ElMessage.success(t("system.common.message.deleteSuccess", { resource: t("system.post.resource") }));
319
388
  refreshTable();
320
389
  }),
321
- () => ElMessage.info("已取消删除岗位")
390
+ () => ElMessage.info(t("system.common.dialog.cancelDelete", { resource: t("system.post.resource") }))
322
391
  );
323
392
  }
324
393
  </script>