@liujitcn/kratos-admin-system 0.0.39 → 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 (39) 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/components/DynamicI18nCell.vue.d.ts +2 -8
  4. package/dist/package/declarations/src/components/DynamicI18nEditor.vue.d.ts +20 -3
  5. package/dist/package/declarations/src/components/dynamicI18n.d.ts +2 -2
  6. package/dist/package/declarations/src/locales/generated.d.ts +5797 -5813
  7. package/dist/package/declarations/src/rpc/system/admin/v1/base_config.d.ts +4 -40
  8. package/dist/package/declarations/src/utils/code-gen-progress.d.ts +3 -0
  9. package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenGenerateConfirm.vue.d.ts +11 -0
  10. package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue.d.ts +5 -9
  11. package/dist/package/declarations/src/views/tool/code-gen/config.d.ts +3 -0
  12. package/dist/package/src/api/system/admin/v1/base_config.ts +0 -20
  13. package/dist/package/src/components/DynamicI18nCell.vue +55 -220
  14. package/dist/package/src/components/DynamicI18nEditor.vue +150 -146
  15. package/dist/package/src/components/dynamicI18n.ts +10 -6
  16. package/dist/package/src/config/index.ts +1 -3
  17. package/dist/package/src/locales/en-US.json +1430 -1434
  18. package/dist/package/src/locales/ja-JP.json +1430 -1434
  19. package/dist/package/src/locales/zh-CN.json +1429 -1433
  20. package/dist/package/src/locales/zh-TW.json +1429 -1433
  21. package/dist/package/src/module.ts +0 -1
  22. package/dist/package/src/rpc/system/admin/v1/base_config.ts +3 -43
  23. package/dist/package/src/utils/code-gen-progress.ts +15 -0
  24. package/dist/package/src/views/base/config/index.vue +183 -48
  25. package/dist/package/src/views/base/dict/index.vue +6 -9
  26. package/dist/package/src/views/base/dict/item.vue +6 -15
  27. package/dist/package/src/views/base/job/index.vue +16 -17
  28. package/dist/package/src/views/base/menu/index.vue +78 -15
  29. package/dist/package/src/views/tool/code-gen/columns/index.vue +17 -25
  30. package/dist/package/src/views/tool/code-gen/components/CodeGenGenerateConfirm.vue +115 -0
  31. package/dist/package/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue +27 -186
  32. package/dist/package/src/views/tool/code-gen/components/CodeGenProgressDialog.vue +2 -0
  33. package/dist/package/src/views/tool/code-gen/config.ts +15 -1
  34. package/dist/package/src/views/tool/code-gen/table/index.vue +69 -40
  35. package/package.json +3 -2
  36. package/dist/package/declarations/src/config/database-backup.d.ts +0 -12
  37. package/dist/package/declarations/src/views/base/runtime-config/index.vue.d.ts +0 -3
  38. package/dist/package/src/config/database-backup.ts +0 -57
  39. package/dist/package/src/views/base/runtime-config/index.vue +0 -479
@@ -1,5 +1,4 @@
1
1
  import type { Component } from "vue";
2
- import { User } from "@element-plus/icons-vue";
3
2
  import { defineAdminModule } from "@liujitcn/kratos-admin-core";
4
3
  import Ai from "./components/Ai.vue";
5
4
  import ForcedPasswordDialog from "./components/ForcedPasswordDialog.vue";
@@ -24,16 +24,8 @@ export enum BaseConfigType {
24
24
  BASE_CONFIG_TYPE_DICT = 4,
25
25
  /** BASE_CONFIG_TYPE_BOOLEAN - 布尔。 */
26
26
  BASE_CONFIG_TYPE_BOOLEAN = 5,
27
- }
28
-
29
- /** 系统配置隐藏状态。 */
30
- export enum BaseConfigHiddenStatus {
31
- /** BASE_CONFIG_HIDDEN_STATUS_UNSPECIFIED - 未指定隐藏状态。 */
32
- BASE_CONFIG_HIDDEN_STATUS_UNSPECIFIED = 0,
33
- /** BASE_CONFIG_HIDDEN_STATUS_VISIBLE - 普通配置,可在通用配置页面展示。 */
34
- BASE_CONFIG_HIDDEN_STATUS_VISIBLE = 1,
35
- /** BASE_CONFIG_HIDDEN_STATUS_HIDDEN - 隐藏配置,仅允许通过专用配置表单访问。 */
36
- BASE_CONFIG_HIDDEN_STATUS_HIDDEN = 2,
27
+ /** BASE_CONFIG_TYPE_FORM - 表单。 */
28
+ BASE_CONFIG_TYPE_FORM = 6,
37
29
  }
38
30
 
39
31
  /** 系统配置分页查询条件 */
@@ -86,14 +78,12 @@ export interface BaseConfigForm {
86
78
  site: BaseConfigSite;
87
79
  /** 配置名称 */
88
80
  name: string;
89
- /** 配置类型:1、文本,2、图片,3、富文本,4、字典,5、布尔 */
81
+ /** 配置类型:1、文本,2、图片,3、富文本,4、字典,5、布尔,6、表单 */
90
82
  type: BaseConfigType;
91
83
  /** 配置key */
92
84
  key: string;
93
85
  /** 配置value */
94
86
  value: string;
95
- /** 隐藏状态 */
96
- hidden_status: BaseConfigHiddenStatus;
97
87
  /** 配置名称多语言翻 */
98
88
  name_i18ns: BaseI18n[];
99
89
  /** 配置value文本/富文本配置值的多语言翻译 */
@@ -146,8 +136,6 @@ export interface BaseConfig {
146
136
  key: string;
147
137
  /** 配置value */
148
138
  value: string;
149
- /** 隐藏状态 */
150
- hidden_status: BaseConfigHiddenStatus;
151
139
  /** 状态:枚举【Status】 */
152
140
  status: Status;
153
141
  /** 创建时间 */
@@ -158,30 +146,6 @@ export interface BaseConfig {
158
146
  i18ns: BaseI18n[];
159
147
  }
160
148
 
161
- /** 按配置键查询系统配置请求参数。 */
162
- export interface GetBaseConfigByKeyRequest {
163
- /** 配置key */
164
- key: string;
165
- }
166
-
167
- /** 按配置键返回系统配置值。 */
168
- export interface BaseConfigValue {
169
- /** 配置key */
170
- key: string;
171
- /** JSON格式配置值 */
172
- value_json: string;
173
- /** 更新时间 */
174
- updated_at: string;
175
- }
176
-
177
- /** 按配置键更新系统配置请求参数。 */
178
- export interface UpdateBaseConfigByKeyRequest {
179
- /** 配置key */
180
- key: string;
181
- /** JSON格式配置值 */
182
- value_json: string;
183
- }
184
-
185
149
  /** Admin系统配置服务 */
186
150
  export interface BaseConfigService {
187
151
  /** 刷新缓存 */
@@ -190,14 +154,10 @@ export interface BaseConfigService {
190
154
  PageBaseConfig(request: PageBaseConfigRequest): Promise<PageBaseConfigResponse>;
191
155
  /** 查询系统配置 */
192
156
  GetBaseConfig(request: GetBaseConfigRequest): Promise<BaseConfigForm>;
193
- /** 按配置键查询隐藏系统配置。 */
194
- GetBaseConfigByKey(request: GetBaseConfigByKeyRequest): Promise<BaseConfigValue>;
195
157
  /** 创建系统配置 */
196
158
  CreateBaseConfig(request: CreateBaseConfigRequest): Promise<Empty>;
197
159
  /** 更新系统配置 */
198
160
  UpdateBaseConfig(request: UpdateBaseConfigRequest): Promise<Empty>;
199
- /** 按配置键更新隐藏系统配置。 */
200
- UpdateBaseConfigByKey(request: UpdateBaseConfigByKeyRequest): Promise<Empty>;
201
161
  /** 删除系统配置 */
202
162
  DeleteBaseConfig(request: DeleteBaseConfigRequest): Promise<Empty>;
203
163
  /** 设置状态 */
@@ -0,0 +1,15 @@
1
+ import type { CodeGenTask } from "../rpc/system/admin/v1/code_gen";
2
+
3
+ /** 补齐 ProtoJSON 省略的零值计数,统一 HTTP 与 SSE 任务快照。 */
4
+ export function normalizeCodeGenTask(task: CodeGenTask): CodeGenTask {
5
+ return {
6
+ ...task,
7
+ completed_steps: task.completed_steps ?? 0,
8
+ total_steps: task.total_steps ?? 0,
9
+ tables: (task.tables ?? []).map(table => ({
10
+ ...table,
11
+ completed_steps: table.completed_steps ?? 0,
12
+ total_steps: table.total_steps ?? 0
13
+ }))
14
+ };
15
+ }
@@ -12,8 +12,13 @@
12
12
  <FormDialog
13
13
  v-model="dialog.visible"
14
14
  ref="formDialogRef"
15
+ class="system-config-dialog"
15
16
  :title="t(dialog.titleKey, { resource: t('system.base.config.resource') })"
16
- width="1200px"
17
+ width="min(1440px, calc(100vw - 32px))"
18
+ top="4vh"
19
+ :col-span="12"
20
+ :gutter="24"
21
+ :confirm-loading="saving"
17
22
  :model="formData"
18
23
  :fields="formFields"
19
24
  :rules="rules"
@@ -56,6 +61,25 @@
56
61
  inline-prompt
57
62
  />
58
63
  </template>
64
+ <template #formValue>
65
+ <div class="config-form-value">
66
+ <template v-if="formDefinition">
67
+ <p>
68
+ <el-icon><component :is="formDefinition.icon" /></el-icon> {{ t(formDefinition.descriptionKey) }}
69
+ </p>
70
+ <ProForm
71
+ :key="formDefinition.key"
72
+ ref="valueFormRef"
73
+ :model="formValue"
74
+ :fields="localizedFormFields"
75
+ :col-span="12"
76
+ :gutter="24"
77
+ label-width="180px"
78
+ />
79
+ </template>
80
+ <el-alert v-else :title="t('system.base.config.message.form_unavailable')" type="warning" :closable="false" />
81
+ </div>
82
+ </template>
59
83
  <template #nameI18ns>
60
84
  <DynamicI18nEditor v-model="nameI18nValues" :source="formData.name" :maxlength="100" />
61
85
  </template>
@@ -67,12 +91,14 @@
67
91
  </template>
68
92
 
69
93
  <script setup lang="ts">
70
- import { computed, h, reactive, ref } from "vue";
94
+ import { computed, h, reactive, ref, watch } from "vue";
71
95
  import { useDebounceFn } from "@vueuse/core";
72
96
  import type { ColumnProps, HeaderActionProps, ProTableInstance } from "@liujitcn/kratos-admin-core/components/ProTable/interface";
73
97
  import ProTable from "@liujitcn/kratos-admin-core/components/ProTable";
98
+ import ProForm from "@liujitcn/kratos-admin-core/components/ProForm/index.vue";
99
+ import { runtimeConfigDefinitions, type RuntimeConfigModel } from "@liujitcn/kratos-admin-system/config";
74
100
  import FormDialog from "@liujitcn/kratos-admin-core/components/Dialog/FormDialog.vue";
75
- import type { ProFormField, ProFormOption } from "@liujitcn/kratos-admin-core/components/ProForm/interface";
101
+ import type { ProFormField, ProFormOption, ProFormInstance } from "@liujitcn/kratos-admin-core/components/ProForm/interface";
76
102
  import DictLabel from "@liujitcn/kratos-admin-core/components/Dict/DictLabel.vue";
77
103
  import RichTextPreview from "@liujitcn/kratos-admin-core/components/RichTextPreview/index.vue";
78
104
  import UploadImg from "@liujitcn/kratos-admin-core/components/Upload/Img.vue";
@@ -88,13 +114,17 @@ import type {
88
114
  import type { BaseI18n } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_i18n";
89
115
  import { BaseConfigSite } from "@liujitcn/kratos-admin-system/rpc/base/v1/config";
90
116
  import { Status } from "@liujitcn/kratos-admin-system/rpc/common/v1/enum";
91
- import { BaseConfigHiddenStatus, BaseConfigType } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_config";
117
+ import { BaseConfigType } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_config";
92
118
  import { I18nTargetType } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_i18n";
93
119
  import { buildPageRequest, normalizeSelectedIds } from "@liujitcn/kratos-admin-core/table";
94
120
  import { t } from "@liujitcn/kratos-admin-core";
95
121
  import DynamicI18nEditor from "@liujitcn/kratos-admin-system/components/DynamicI18nEditor.vue";
96
122
  import DynamicI18nCell from "@liujitcn/kratos-admin-system/components/DynamicI18nCell.vue";
97
- import { getEditableLanguageOptions, type DynamicI18nValue } from "@liujitcn/kratos-admin-system/components/dynamicI18n";
123
+ import {
124
+ getEditableLanguageOptions,
125
+ serializeDynamicI18ns,
126
+ type DynamicI18nValue
127
+ } from "@liujitcn/kratos-admin-system/components/dynamicI18n";
98
128
 
99
129
  /** 系统配置编辑表单状态,新增时枚举字段保持为空,避免把未知值 0 显示为下拉文本。 */
100
130
  type BaseConfigFormState = Omit<BaseConfigForm, "site" | "type"> & {
@@ -113,6 +143,37 @@ const { BUTTONS } = useAuthButtons();
113
143
  const proTable = ref<ProTableInstance>();
114
144
  const formDialogRef = ref<InstanceType<typeof FormDialog>>();
115
145
 
146
+ const saving = ref(false);
147
+ const valueFormRef = ref<ProFormInstance>();
148
+ const formValue = ref<RuntimeConfigModel>({});
149
+ const formDefinition = computed(() => runtimeConfigDefinitions.find(item => item.key === formData.key));
150
+ const localizedFormFields = computed<ProFormField[]>(() =>
151
+ (formDefinition.value?.fields ?? []).map(field => ({
152
+ prop: field.prop,
153
+ label: t(field.labelKey),
154
+ component: field.component,
155
+ props: field.props,
156
+ itemProps: field.itemProps,
157
+ options: field.options,
158
+ visible: field.visible,
159
+ labelTooltip: field.labelTooltipKey ? t(field.labelTooltipKey) : undefined,
160
+ rules: field.rules?.map(rule => ({
161
+ ...rule,
162
+ message: t(
163
+ rule.messageKey,
164
+ rule.messageArgs
165
+ ? Object.fromEntries(
166
+ Object.entries(rule.messageArgs).map(([key, value]) => [
167
+ key,
168
+ typeof value === "object" ? t(value.key) : typeof value === "boolean" ? String(value) : value
169
+ ])
170
+ )
171
+ : undefined
172
+ )
173
+ }))
174
+ }))
175
+ );
176
+
116
177
  const dialog = reactive({
117
178
  titleKey: "common.action.create_resource",
118
179
  visible: false
@@ -131,8 +192,6 @@ const formData = reactive<BaseConfigFormState>({
131
192
  key: "",
132
193
  /** 配置value */
133
194
  value: "",
134
- /** 隐藏状态。 */
135
- hidden_status: BaseConfigHiddenStatus.BASE_CONFIG_HIDDEN_STATUS_VISIBLE,
136
195
  /** 状态 */
137
196
  status: Status.STATUS_ENABLE,
138
197
  /** 配置名称非主语言翻译。 */
@@ -141,6 +200,16 @@ const formData = reactive<BaseConfigFormState>({
141
200
  value_i18ns: []
142
201
  });
143
202
 
203
+ /** 切换表单类型或编码时加载对应默认内容。 */
204
+ watch(
205
+ () => [formData.type, formData.key],
206
+ () => {
207
+ loadFormValue();
208
+ if (formData.type === BaseConfigType.BASE_CONFIG_TYPE_FORM) formData.site = BaseConfigSite.BASE_CONFIG_SITE_SYSTEM;
209
+ },
210
+ { flush: "sync" }
211
+ );
212
+
144
213
  /** 将配置值翻译记录转换为编辑器值,缺少记录时保留可编辑的空行。 */
145
214
  function normalizeConfigI18ns(targetType: I18nTargetType): DynamicI18nValue[] {
146
215
  const records = targetType === I18nTargetType.I18N_TARGET_TYPE_BASE_CONFIG_NAME ? formData.name_i18ns : formData.value_i18ns;
@@ -258,6 +327,7 @@ const dictValueCode = computed(() => BASE_CONFIG_DICT_CODE_MAP[formData.key] ??
258
327
  const formFields = computed<ProFormField[]>(() => [
259
328
  {
260
329
  prop: "name",
330
+ suffixSlotName: "nameI18ns",
261
331
  label: t("system.base.config.field.name"),
262
332
  component: "input",
263
333
  props: {
@@ -269,12 +339,13 @@ const formFields = computed<ProFormField[]>(() => [
269
339
  prop: "site",
270
340
  label: t("system.base.config.field.site"),
271
341
  component: "dict",
272
- props: { code: "base_config_site", disabled: formData.id > 0 }
342
+ props: { code: "base_config_site", disabled: formData.id > 0 || formData.type === BaseConfigType.BASE_CONFIG_TYPE_FORM }
273
343
  },
274
344
  {
275
345
  prop: "key",
276
346
  label: t("system.base.config.field.key"),
277
- component: "input",
347
+ component: formData.type === BaseConfigType.BASE_CONFIG_TYPE_FORM ? "select" : "input",
348
+ options: runtimeConfigDefinitions.map(item => ({ label: `${t(item.titleKey)}(${item.key})`, value: item.key })),
278
349
  props: {
279
350
  placeholder: t("common.validation.required_input", { field: t("system.base.config.field.key") }),
280
351
  disabled: formData.id > 0
@@ -286,11 +357,20 @@ const formFields = computed<ProFormField[]>(() => [
286
357
  component: "dict",
287
358
  props: { code: "base_config_type", disabled: formData.id > 0 }
288
359
  },
360
+ {
361
+ prop: "formValue",
362
+ label: t("system.base.config.field.value"),
363
+ component: "slot",
364
+ slotName: "formValue",
365
+ visible: model => model.type === BaseConfigType.BASE_CONFIG_TYPE_FORM,
366
+ colSpan: 24
367
+ },
289
368
  {
290
369
  prop: "value",
291
370
  label: t("system.base.config.field.value"),
292
371
  component: "slot",
293
372
  slotName: "textValue",
373
+ suffixSlotName: "valueI18ns",
294
374
  visible: model => model.type == BaseConfigType.BASE_CONFIG_TYPE_TEXT
295
375
  },
296
376
  {
@@ -305,6 +385,7 @@ const formFields = computed<ProFormField[]>(() => [
305
385
  label: t("system.base.config.field.value"),
306
386
  component: "slot",
307
387
  slotName: "richTextValue",
388
+ suffixSlotName: "valueI18ns",
308
389
  visible: model => model.type == BaseConfigType.BASE_CONFIG_TYPE_RICH_TEXT,
309
390
  colSpan: 24
310
391
  },
@@ -323,22 +404,12 @@ const formFields = computed<ProFormField[]>(() => [
323
404
  visible: model => model.type == BaseConfigType.BASE_CONFIG_TYPE_BOOLEAN
324
405
  },
325
406
  {
326
- prop: "i18ns",
327
- label: t("system.base.i18n.field.name_i18ns"),
328
- component: "slot",
329
- slotName: "nameI18ns",
330
- colSpan: 24
331
- },
332
- {
333
- prop: "i18ns",
334
- label: t("system.base.i18n.field.value_i18ns"),
335
- component: "slot",
336
- slotName: "valueI18ns",
337
- visible: model =>
338
- model.type == BaseConfigType.BASE_CONFIG_TYPE_TEXT || model.type == BaseConfigType.BASE_CONFIG_TYPE_RICH_TEXT,
339
- colSpan: 24
340
- },
341
- { prop: "status", label: t("common.field.status"), component: "radio-group", options: statusOptions.value }
407
+ prop: "status",
408
+ label: t("common.field.status"),
409
+ component: "radio-group",
410
+ options: statusOptions.value,
411
+ props: { disabled: formData.type === BaseConfigType.BASE_CONFIG_TYPE_FORM }
412
+ }
342
413
  ]);
343
414
 
344
415
  /** 系统配置表格列配置。 */
@@ -384,7 +455,8 @@ const columns = computed<ColumnProps[]>(() => [
384
455
  inactiveValue: Status.STATUS_DISABLE,
385
456
  activeText: t("common.status.enabled"),
386
457
  inactiveText: t("common.status.disabled"),
387
- disabled: () => !BUTTONS.value["base:config:status"],
458
+ disabled: scope =>
459
+ !BUTTONS.value["base:config:status"] || (scope.row as BaseConfig).type === BaseConfigType.BASE_CONFIG_TYPE_FORM,
388
460
  beforeChange: scope => handleBeforeSetStatus(scope.row as BaseConfig)
389
461
  }
390
462
  },
@@ -411,7 +483,8 @@ const columns = computed<ColumnProps[]>(() => [
411
483
  type: "danger",
412
484
  link: true,
413
485
  icon: Delete,
414
- hidden: () => !BUTTONS.value["base:config:delete"],
486
+ hidden: scope =>
487
+ !BUTTONS.value["base:config:delete"] || (scope.row as BaseConfig).type === BaseConfigType.BASE_CONFIG_TYPE_FORM,
415
488
  onClick: scope => handleDelete(scope.row as BaseConfig)
416
489
  }
417
490
  ]
@@ -433,6 +506,7 @@ function renderConfigNameCell(row: BaseConfig) {
433
506
  * 将配置键渲染为可悬停查看配置值的单元格。
434
507
  */
435
508
  function renderConfigKeyCell(row: BaseConfig) {
509
+ if (row.type === BaseConfigType.BASE_CONFIG_TYPE_FORM) return h("span", row.key);
436
510
  return h(
437
511
  ElTooltip,
438
512
  {
@@ -537,10 +611,23 @@ async function handleOpenDialog(configId?: number) {
537
611
  await loadEnabledBaseLanguages();
538
612
  resetForm();
539
613
  dialog.titleKey = configId ? "common.action.edit_resource" : "common.action.create_resource";
614
+ if (configId) {
615
+ Object.assign(formData, await defBaseConfigService.GetBaseConfig({ id: configId }));
616
+ if (formData.type === BaseConfigType.BASE_CONFIG_TYPE_FORM) {
617
+ loadFormValue(formData.value);
618
+ }
619
+ }
540
620
  dialog.visible = true;
541
- if (!configId) return;
621
+ }
542
622
 
543
- Object.assign(formData, await defBaseConfigService.GetBaseConfig({ id: configId }));
623
+ /** 按注册定义创建独立模型,并用已保存的配置值覆盖默认值。 */
624
+ function loadFormValue(value?: string) {
625
+ const definition = formDefinition.value;
626
+ formValue.value =
627
+ formData.type === BaseConfigType.BASE_CONFIG_TYPE_FORM && definition
628
+ ? Object.assign(definition.createModel(), value ? JSON.parse(value) : {})
629
+ : {};
630
+ valueFormRef.value?.clearValidate();
544
631
  }
545
632
 
546
633
  /**
@@ -563,36 +650,62 @@ function resetForm() {
563
650
  formData.type = undefined;
564
651
  formData.key = "";
565
652
  formData.value = "";
566
- formData.hidden_status = BaseConfigHiddenStatus.BASE_CONFIG_HIDDEN_STATUS_VISIBLE;
567
653
  formData.name_i18ns = [];
568
654
  formData.value_i18ns = [];
655
+ formValue.value = {};
656
+ valueFormRef.value?.clearValidate();
569
657
  formData.status = Status.STATUS_ENABLE;
570
658
  }
571
659
 
572
660
  /**
573
661
  * 提交系统配置表单。
574
662
  */
575
- function handleSubmit() {
576
- if (formData.type === BaseConfigType.BASE_CONFIG_TYPE_BOOLEAN) {
663
+ async function handleSubmit() {
664
+ if (formData.type === BaseConfigType.BASE_CONFIG_TYPE_FORM) {
665
+ if (!formDefinition.value) {
666
+ ElMessage.warning(t("system.base.config.message.form_unavailable"));
667
+ return;
668
+ }
669
+ if ((await valueFormRef.value?.validate()) !== true) return;
670
+ formData.value = JSON.stringify(formValue.value);
671
+ } else if (formData.type === BaseConfigType.BASE_CONFIG_TYPE_BOOLEAN) {
577
672
  formData.value = formData.value === "true" ? "true" : "false";
578
673
  }
579
- formDialogRef.value?.validate()?.then(valid => {
580
- if (!valid) return;
581
-
674
+ if ((await formDialogRef.value?.validate()) !== true) return;
675
+ saving.value = true;
676
+ try {
582
677
  const submitData = JSON.parse(JSON.stringify(formData)) as BaseConfigForm;
583
- const request = submitData.id
584
- ? defBaseConfigService.UpdateBaseConfig({ base_config: submitData })
585
- : defBaseConfigService.CreateBaseConfig({ base_config: submitData });
586
- request.then(() => {
587
- ElMessage.success(
588
- t(submitData.id ? "common.message.update_success" : "common.message.create_success", {
589
- resource: t("system.base.config.resource")
590
- })
591
- );
592
- handleCloseDialog();
593
- refreshTable();
594
- });
595
- });
678
+ submitData.name_i18ns = serializeDynamicI18ns(
679
+ nameI18nValues.value,
680
+ I18nTargetType.I18N_TARGET_TYPE_BASE_CONFIG_NAME,
681
+ submitData.id,
682
+ submitData.name
683
+ );
684
+ submitData.value_i18ns =
685
+ submitData.type === BaseConfigType.BASE_CONFIG_TYPE_TEXT || submitData.type === BaseConfigType.BASE_CONFIG_TYPE_RICH_TEXT
686
+ ? serializeDynamicI18ns(
687
+ valueI18nValues.value,
688
+ I18nTargetType.I18N_TARGET_TYPE_BASE_CONFIG_VALUE,
689
+ submitData.id,
690
+ submitData.value
691
+ )
692
+ : [];
693
+
694
+ if (submitData.id) {
695
+ await defBaseConfigService.UpdateBaseConfig({ base_config: submitData });
696
+ } else {
697
+ await defBaseConfigService.CreateBaseConfig({ base_config: submitData });
698
+ }
699
+ ElMessage.success(
700
+ t(submitData.id ? "common.message.update_success" : "common.message.create_success", {
701
+ resource: t("system.base.config.resource")
702
+ })
703
+ );
704
+ handleCloseDialog();
705
+ refreshTable();
706
+ } finally {
707
+ saving.value = false;
708
+ }
596
709
  }
597
710
 
598
711
  /**
@@ -679,6 +792,15 @@ function handleDelete(selected?: number | string | Array<number | string> | Base
679
792
  </script>
680
793
 
681
794
  <style scoped lang="scss">
795
+ .config-form-value {
796
+ width: 100%;
797
+ min-width: 0;
798
+ > p {
799
+ margin: 0 0 16px;
800
+ color: var(--el-text-color-secondary);
801
+ }
802
+ }
803
+
682
804
  .config-key-cell {
683
805
  cursor: pointer;
684
806
  border-bottom: 1px dashed var(--el-color-info);
@@ -723,4 +845,17 @@ function handleDelete(selected?: number | string | Array<number | string> | Base
723
845
  max-width: 100%;
724
846
  height: auto;
725
847
  }
848
+ @media (max-width: 767px) {
849
+ :global(.system-config-dialog .el-col) {
850
+ flex: 0 0 100%;
851
+ max-width: 100%;
852
+ }
853
+ :global(.system-config-dialog .el-form-item) {
854
+ flex-direction: column;
855
+ }
856
+ :global(.system-config-dialog .el-form-item__label) {
857
+ justify-content: flex-start;
858
+ width: auto !important;
859
+ }
860
+ }
726
861
  </style>
@@ -21,11 +21,7 @@
21
21
  @close="handleCloseDialog"
22
22
  >
23
23
  <template #i18ns>
24
- <DynamicI18nEditor
25
- v-model="i18nValues"
26
- :source="formData.name"
27
- :maxlength="50"
28
- />
24
+ <DynamicI18nEditor v-model="i18nValues" :source="formData.name" :maxlength="50" />
29
25
  </template>
30
26
  </FormDialog>
31
27
  </div>
@@ -124,6 +120,7 @@ const statusOptions = computed<ProFormOption[]>(() => [
124
120
  const formFields = computed<ProFormField[]>(() => [
125
121
  {
126
122
  prop: "name",
123
+ suffixSlotName: "i18ns",
127
124
  label: t("system.base.dict.field.name"),
128
125
  component: "input",
129
126
  props: { placeholder: t("system.base.dict.placeholder.name") }
@@ -134,7 +131,6 @@ const formFields = computed<ProFormField[]>(() => [
134
131
  component: "input",
135
132
  props: { placeholder: t("system.base.dict.placeholder.code") }
136
133
  },
137
- { prop: "i18ns", label: t("system.base.i18n.field.i18ns"), component: "slot", slotName: "i18ns" },
138
134
  { prop: "status", label: t("common.field.status"), component: "radio-group", options: statusOptions.value }
139
135
  ]);
140
136
 
@@ -261,7 +257,7 @@ async function handleOpenDialog(dictId?: number) {
261
257
 
262
258
  const data = await defBaseDictService.GetBaseDict({ id: dictId });
263
259
  Object.assign(formData, data);
264
- i18nValues.value = normalizeDynamicI18ns(data.i18ns as DynamicI18nRecord[]);
260
+ i18nValues.value = normalizeDynamicI18ns(data.i18ns as DynamicI18nRecord[]);
265
261
  }
266
262
 
267
263
  /**
@@ -283,7 +279,7 @@ function resetForm() {
283
279
  formData.name = "";
284
280
  formData.i18ns = [];
285
281
  formData.status = Status.STATUS_ENABLE;
286
- i18nValues.value = normalizeDynamicI18ns(undefined);
282
+ i18nValues.value = normalizeDynamicI18ns(undefined);
287
283
  }
288
284
 
289
285
  /**
@@ -297,7 +293,8 @@ function handleSubmit() {
297
293
  submitData.i18ns = serializeDynamicI18ns(
298
294
  i18nValues.value,
299
295
  I18nTargetType.I18N_TARGET_TYPE_BASE_DICT_NAME,
300
- submitData.id
296
+ submitData.id,
297
+ submitData.name
301
298
  );
302
299
  const request = submitData.id
303
300
  ? defBaseDictService.UpdateBaseDict({ base_dict: submitData })
@@ -36,11 +36,7 @@
36
36
  </div>
37
37
  </template>
38
38
  <template #i18ns>
39
- <DynamicI18nEditor
40
- v-model="i18nValues"
41
- :source="formData.label"
42
- :maxlength="100"
43
- />
39
+ <DynamicI18nEditor v-model="i18nValues" :source="formData.label" :maxlength="100" />
44
40
  </template>
45
41
  </FormDialog>
46
42
  </div>
@@ -147,6 +143,7 @@ const statusOptions = computed<ProFormOption[]>(() => [
147
143
  const formFields = computed<ProFormField[]>(() => [
148
144
  {
149
145
  prop: "label",
146
+ suffixSlotName: "i18ns",
150
147
  label: t("system.base.dict.item.field.label"),
151
148
  component: "input",
152
149
  props: { placeholder: t("system.base.dict.item.placeholder.label") }
@@ -157,13 +154,6 @@ const formFields = computed<ProFormField[]>(() => [
157
154
  component: "input",
158
155
  props: { placeholder: t("system.base.dict.item.placeholder.value") }
159
156
  },
160
- {
161
- prop: "i18ns",
162
- label: t("system.base.i18n.field.i18ns"),
163
- component: "slot",
164
- slotName: "i18ns",
165
- colSpan: 24
166
- },
167
157
  {
168
158
  prop: "sort",
169
159
  label: t("common.field.sort"),
@@ -330,7 +320,7 @@ async function handleOpenDialog(dictItemId?: number) {
330
320
 
331
321
  const data = await defBaseDictItemService.GetBaseDictItem({ id: dictItemId });
332
322
  Object.assign(formData, data);
333
- i18nValues.value = normalizeDynamicI18ns(data.i18ns as DynamicI18nRecord[]);
323
+ i18nValues.value = normalizeDynamicI18ns(data.i18ns as DynamicI18nRecord[]);
334
324
  }
335
325
 
336
326
  /**
@@ -355,7 +345,7 @@ function resetForm() {
355
345
  formData.tag_type = "";
356
346
  formData.sort = 1;
357
347
  formData.status = Status.STATUS_ENABLE;
358
- i18nValues.value = normalizeDynamicI18ns(undefined);
348
+ i18nValues.value = normalizeDynamicI18ns(undefined);
359
349
  }
360
350
 
361
351
  /**
@@ -370,7 +360,8 @@ function handleSubmit() {
370
360
  submitData.i18ns = serializeDynamicI18ns(
371
361
  i18nValues.value,
372
362
  I18nTargetType.I18N_TARGET_TYPE_BASE_DICT_ITEM_LABEL,
373
- submitData.id
363
+ submitData.id,
364
+ submitData.label
374
365
  );
375
366
  const request = submitData.id
376
367
  ? defBaseDictItemService.UpdateBaseDictItem({ base_dict_item: submitData })