@liujitcn/kratos-admin-core 0.0.21 → 0.0.23

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 (85) hide show
  1. package/dist/package/declarations/src/api/base/language.d.ts +3 -3
  2. package/dist/package/declarations/src/components/Dict/index.vue.d.ts +4 -3
  3. package/dist/package/declarations/src/components/Dict/value.d.ts +11 -0
  4. package/dist/package/declarations/src/locales/generated.d.ts +3382 -0
  5. package/dist/package/declarations/src/locales/index.d.ts +11 -21
  6. package/dist/package/declarations/src/rpc/base/v1/config.d.ts +11 -1
  7. package/dist/package/declarations/src/rpc/base/v1/language.d.ts +7 -13
  8. package/dist/package/declarations/src/rpc/base/v1/login.d.ts +13 -1
  9. package/dist/package/declarations/src/rpc/system/admin/v1/auth.d.ts +1 -1
  10. package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +7 -77
  11. package/dist/package/declarations/src/rpc/system/admin/v1/base_translation.d.ts +54 -81
  12. package/dist/package/declarations/src/rpc/system/admin/v1/common.d.ts +13 -0
  13. package/dist/package/declarations/src/stores/modules/auth.d.ts +6 -6
  14. package/dist/package/declarations/src/utils/passwordCrypto.d.ts +1 -1
  15. package/dist/package/src/App.vue +2 -8
  16. package/dist/package/src/api/base/language.ts +4 -4
  17. package/dist/package/src/bootstrap.ts +1 -1
  18. package/dist/package/src/components/CronExpression/index.vue +19 -19
  19. package/dist/package/src/components/Dialog/FormDialog.vue +1 -1
  20. package/dist/package/src/components/Dict/index.vue +21 -7
  21. package/dist/package/src/components/Dict/value.ts +18 -0
  22. package/dist/package/src/components/ImportExcel/index.vue +10 -10
  23. package/dist/package/src/components/LocaleSwitch/index.vue +1 -1
  24. package/dist/package/src/components/ProForm/components/DynamicList.vue +1 -1
  25. package/dist/package/src/components/ProForm/components/KvList.vue +2 -2
  26. package/dist/package/src/components/ProForm/index.vue +2 -2
  27. package/dist/package/src/components/ProTable/components/ColSetting.vue +3 -3
  28. package/dist/package/src/components/ProTable/components/TableColumn.vue +1 -1
  29. package/dist/package/src/components/ProTable/index.vue +4 -4
  30. package/dist/package/src/components/SearchForm/components/SearchFormItem.vue +2 -2
  31. package/dist/package/src/components/SelectFilter/index.vue +1 -1
  32. package/dist/package/src/components/TreeFilter/index.vue +4 -4
  33. package/dist/package/src/components/Upload/File.vue +6 -6
  34. package/dist/package/src/components/Upload/Files.vue +7 -7
  35. package/dist/package/src/components/Upload/Img.vue +4 -4
  36. package/dist/package/src/components/Upload/Imgs.vue +5 -5
  37. package/dist/package/src/components/WangEditor/index.vue +1 -1
  38. package/dist/package/src/hooks/useDownload.ts +1 -1
  39. package/dist/package/src/hooks/useHandleData.ts +2 -2
  40. package/dist/package/src/hooks/useTheme.ts +1 -1
  41. package/dist/package/src/layouts/components/Header/components/AssemblySize.vue +1 -1
  42. package/dist/package/src/layouts/components/Header/components/Avatar.vue +5 -5
  43. package/dist/package/src/layouts/components/Header/components/Breadcrumb.vue +2 -2
  44. package/dist/package/src/layouts/components/Header/components/Fullscreen.vue +2 -2
  45. package/dist/package/src/layouts/components/Header/components/PasswordDialog.vue +1 -1
  46. package/dist/package/src/layouts/components/Header/components/SearchMenu.vue +3 -3
  47. package/dist/package/src/layouts/components/Main/index.vue +1 -0
  48. package/dist/package/src/layouts/components/Tabs/components/MoreButton.vue +5 -5
  49. package/dist/package/src/layouts/components/Tabs/index.vue +15 -1
  50. package/dist/package/src/layouts/components/ThemeDrawer/index.vue +7 -7
  51. package/dist/package/src/locales/README.md +2 -2
  52. package/dist/package/src/locales/en-US.json +142 -117
  53. package/dist/package/src/locales/es-ES.json +226 -201
  54. package/dist/package/src/locales/fr-FR.json +226 -201
  55. package/dist/package/src/locales/generated.ts +57 -0
  56. package/dist/package/src/locales/index.ts +54 -55
  57. package/dist/package/src/locales/ja-JP.json +177 -152
  58. package/dist/package/src/locales/ko-KR.json +221 -196
  59. package/dist/package/src/locales/zh-CN.json +142 -117
  60. package/dist/package/src/locales/zh-TW.json +147 -122
  61. package/dist/package/src/modules/kratosAdmin.ts +3 -17
  62. package/dist/package/src/routers/modules/dynamicRouter.ts +4 -4
  63. package/dist/package/src/routers/modules/staticRouter.ts +2 -2
  64. package/dist/package/src/rpc/base/v1/config.ts +12 -1
  65. package/dist/package/src/rpc/base/v1/language.ts +7 -13
  66. package/dist/package/src/rpc/base/v1/login.ts +14 -1
  67. package/dist/package/src/rpc/system/admin/v1/auth.ts +1 -1
  68. package/dist/package/src/rpc/system/admin/v1/base_dict.ts +7 -79
  69. package/dist/package/src/rpc/system/admin/v1/base_translation.ts +54 -81
  70. package/dist/package/src/rpc/system/admin/v1/common.ts +21 -0
  71. package/dist/package/src/stores/modules/config.ts +2 -2
  72. package/dist/package/src/stores/modules/user.ts +1 -1
  73. package/dist/package/src/styles/element.scss +2 -0
  74. package/dist/package/src/utils/color.ts +4 -4
  75. package/dist/package/src/utils/eleValidate.ts +2 -2
  76. package/dist/package/src/utils/index.ts +3 -3
  77. package/dist/package/src/utils/passwordCrypto.ts +2 -2
  78. package/dist/package/src/utils/request.ts +6 -6
  79. package/dist/package/src/views/login/components/LoginForm.vue +15 -12
  80. package/package.json +2 -2
  81. package/vite.config.ts +12 -8
  82. package/dist/package/declarations/src/rpc/base/v1/enum.d.ts +0 -43
  83. package/dist/package/declarations/src/rpc/system/common/v1/enum.d.ts +0 -67
  84. package/dist/package/src/rpc/base/v1/enum.ts +0 -54
  85. package/dist/package/src/rpc/system/common/v1/enum.ts +0 -80
@@ -160,13 +160,13 @@ const dialogVisible = ref(false);
160
160
  const activeTab = ref<CronSegmentKey>("second");
161
161
 
162
162
  const presetOptions = computed(() => [
163
- { label: t("core.cron.preset.everyMinute"), value: "0 * * * * *" },
164
- { label: t("core.cron.preset.everyFiveMinutes"), value: "0 */5 * * * *" },
165
- { label: t("core.cron.preset.everyHour"), value: "0 0 * * * *" },
166
- { label: t("core.cron.preset.dailyMidnight"), value: "0 0 0 * * *" },
167
- { label: t("core.cron.preset.dailyEight"), value: "0 0 8 * * *" },
168
- { label: t("core.cron.preset.monthlyFirst"), value: "0 0 0 1 * *" },
169
- { label: t("core.cron.preset.nextYearDaily"), value: `0 0 0 * * ${currentYear + 1}` }
163
+ { label: t("core.cron.preset.every_minute"), value: "0 * * * * *" },
164
+ { label: t("core.cron.preset.every_five_minutes"), value: "0 */5 * * * *" },
165
+ { label: t("core.cron.preset.every_hour"), value: "0 0 * * * *" },
166
+ { label: t("core.cron.preset.daily_midnight"), value: "0 0 0 * * *" },
167
+ { label: t("core.cron.preset.daily_eight"), value: "0 0 8 * * *" },
168
+ { label: t("core.cron.preset.monthly_first"), value: "0 0 0 1 * *" },
169
+ { label: t("core.cron.preset.next_year_daily"), value: `0 0 0 * * ${currentYear + 1}` }
170
170
  ]);
171
171
 
172
172
  /** 创建单个 Cron 字段的默认编辑状态。 */
@@ -221,7 +221,7 @@ const expressionDescription = computed(() => {
221
221
  formatSegmentDescription("month", editorState.month),
222
222
  formatSegmentDescription("year", editorState.year)
223
223
  ].filter(Boolean);
224
- return descriptionList.length ? descriptionList.join(t("core.cron.descriptionSeparator")) : t("core.cron.notConfigured");
224
+ return descriptionList.length ? descriptionList.join(t("core.cron.description_separator")) : t("core.cron.not_configured");
225
225
  });
226
226
 
227
227
  /** 打开 Cron 编辑弹窗,并按当前表达式回填编辑状态。 */
@@ -300,17 +300,17 @@ function formatSegmentDescription(segmentKey: CronSegmentKey, segment: CronSegme
300
300
  start: segment.stepStart,
301
301
  unit,
302
302
  step: segment.stepValue,
303
- cycleUnit: t(`core.cron.cycleUnit.${segmentKey}`)
303
+ cycleUnit: t(`core.cron.cycle_unit.${segmentKey}`)
304
304
  });
305
305
  case "specific":
306
306
  return segment.specific.length
307
307
  ? t("core.cron.description.specific", {
308
308
  segment: segmentName,
309
- values: segment.specific.map(item => formatSpecificLabel(segmentKey, item)).join(t("core.cron.valueSeparator"))
309
+ values: segment.specific.map(item => formatSpecificLabel(segmentKey, item)).join(t("core.cron.value_separator"))
310
310
  })
311
311
  : t("core.cron.description.unspecified", { segment: segmentName });
312
312
  case "last":
313
- return t("core.cron.lastDay");
313
+ return t("core.cron.last_day");
314
314
  case "weekday":
315
315
  return t("core.cron.description.weekday", { day: segment.weekday });
316
316
  default:
@@ -320,7 +320,7 @@ function formatSegmentDescription(segmentKey: CronSegmentKey, segment: CronSegme
320
320
 
321
321
  /** 格式化指定值模式下的单个展示值。 */
322
322
  function formatSpecificLabel(segmentKey: CronSegmentKey, value: number) {
323
- return t("core.cron.valueWithUnit", { value, unit: t(`core.cron.unit.${segmentKey}`) });
323
+ return t("core.cron.value_with_unit", { value, unit: t(`core.cron.unit.${segmentKey}`) });
324
324
  }
325
325
 
326
326
  /**
@@ -468,7 +468,7 @@ const CronSegmentEditor = defineComponent({
468
468
  const unit = t(`core.cron.unit.${segmentProps.unitKey}`);
469
469
  return numberOptions.value.map(item => ({
470
470
  value: item,
471
- label: t("core.cron.valueWithUnit", { value: item, unit })
471
+ label: t("core.cron.value_with_unit", { value: item, unit })
472
472
  }));
473
473
  });
474
474
 
@@ -499,7 +499,7 @@ const CronSegmentEditor = defineComponent({
499
499
  {segmentProps.supportsEvery && (
500
500
  <label class="segment-editor__row">
501
501
  {h(ElRadio, { modelValue: localState.mode, value: "every", onChange: () => handleModeChange("every") })}
502
- <span>{t("core.cron.everyUnit", { unit: t(`core.cron.unit.${segmentProps.unitKey}`) })}</span>
502
+ <span>{t("core.cron.every_unit", { unit: t(`core.cron.unit.${segmentProps.unitKey}`) })}</span>
503
503
  </label>
504
504
  )}
505
505
 
@@ -544,7 +544,7 @@ const CronSegmentEditor = defineComponent({
544
544
  controlsPosition: "right",
545
545
  "onUpdate:modelValue": value => handleNumberChange("stepStart", Number(value))
546
546
  })}
547
- <span>{t("core.cron.startEvery", { unit: t(`core.cron.unit.${segmentProps.unitKey}`) })}</span>
547
+ <span>{t("core.cron.start_every", { unit: t(`core.cron.unit.${segmentProps.unitKey}`) })}</span>
548
548
  {h(ElInputNumber, {
549
549
  modelValue: localState.stepValue,
550
550
  min: 1,
@@ -552,7 +552,7 @@ const CronSegmentEditor = defineComponent({
552
552
  controlsPosition: "right",
553
553
  "onUpdate:modelValue": value => handleNumberChange("stepValue", Number(value))
554
554
  })}
555
- <span>{t("core.cron.runOnce", { unit: t(`core.cron.cycleUnit.${segmentProps.unitKey}`) })}</span>
555
+ <span>{t("core.cron.run_once", { unit: t(`core.cron.cycle_unit.${segmentProps.unitKey}`) })}</span>
556
556
  </label>
557
557
  )}
558
558
 
@@ -580,7 +580,7 @@ const CronSegmentEditor = defineComponent({
580
580
  {segmentProps.supportsLast && (
581
581
  <label class="segment-editor__row">
582
582
  {h(ElRadio, { modelValue: localState.mode, value: "last", onChange: () => handleModeChange("last") })}
583
- <span>{t("core.cron.lastDay")}</span>
583
+ <span>{t("core.cron.last_day")}</span>
584
584
  </label>
585
585
  )}
586
586
 
@@ -588,7 +588,7 @@ const CronSegmentEditor = defineComponent({
588
588
  <label class="segment-editor__row">
589
589
  {h(ElRadio, { modelValue: localState.mode, value: "weekday", onChange: () => handleModeChange("weekday") })}
590
590
  <span>{t("core.cron.workday")}</span>
591
- <span>{t("core.cron.thisMonth")}</span>
591
+ <span>{t("core.cron.this_month")}</span>
592
592
  {h(ElInputNumber, {
593
593
  modelValue: localState.weekday,
594
594
  min: segmentProps.min,
@@ -596,7 +596,7 @@ const CronSegmentEditor = defineComponent({
596
596
  controlsPosition: "right",
597
597
  "onUpdate:modelValue": value => handleNumberChange("weekday", Number(value))
598
598
  })}
599
- <span>{t("core.cron.nearestWorkday")}</span>
599
+ <span>{t("core.cron.nearest_workday")}</span>
600
600
  </label>
601
601
  )}
602
602
  </div>
@@ -81,7 +81,7 @@ const props = withDefaults(defineProps<FormDialogProps>(), {
81
81
  width: "500px",
82
82
  top: "8vh",
83
83
  rules: () => ({}),
84
- labelWidth: "110px",
84
+ labelWidth: "",
85
85
  gutter: 20,
86
86
  colSpan: 24,
87
87
  confirmText: "",
@@ -42,6 +42,7 @@ import { ref, watch } from "vue";
42
42
  import { useDictStore } from "../../stores/modules/dict";
43
43
  import type { OptionBaseDictResponse_BaseDictItem } from "../../rpc/system/admin/v1/base_dict";
44
44
  import { useLocaleStore } from "../../locales";
45
+ import { normalizeDictValue, normalizeDictValues, type DictOptionValue } from "./value";
45
46
 
46
47
  const { t } = useLocaleStore();
47
48
 
@@ -50,7 +51,7 @@ type DictType = "select" | "radio" | "checkbox";
50
51
  /** 字典值转换后的目标类型。 */
51
52
  type DictCodeType = "string" | "number";
52
53
  /** 字典组件对外绑定值类型。 */
53
- type DictValue = string | number;
54
+ type DictValue = DictOptionValue;
54
55
 
55
56
  /** 字典组件属性。 */
56
57
  interface DictProps {
@@ -82,6 +83,7 @@ const dictStore = useDictStore();
82
83
  const options = ref<Array<{ label: string; value: DictValue }>>([]);
83
84
  const selectedSingleValue = ref<DictValue | undefined>();
84
85
  const selectedMultiValue = ref<DictValue[]>([]);
86
+ const optionsLoaded = ref(false);
85
87
 
86
88
  /**
87
89
  * 同步外部传入值到组件内部值。
@@ -107,24 +109,35 @@ function convertDictValue(dictItem: OptionBaseDictResponse_BaseDictItem): DictVa
107
109
  */
108
110
  async function loadOptions() {
109
111
  // 按当前字典编码兜底刷新,避免持久化旧缓存里缺少该字典导致下拉无数据。
112
+ optionsLoaded.value = false;
110
113
  const dictList = await dictStore.ensureDictionary(props.code);
111
114
 
112
115
  options.value = dictList.map(dictItem => ({
113
116
  label: dictItem.label,
114
117
  value: convertDictValue(dictItem)
115
118
  }));
119
+ optionsLoaded.value = true;
116
120
  }
117
121
 
118
122
  /**
119
123
  * 校验当前值是否仍在可选项内,避免字典切换后残留无效值。
120
124
  */
121
125
  function ensureSelectedValueValid() {
122
- if (props.type === "checkbox") return;
123
- if (selectedSingleValue.value === undefined || selectedSingleValue.value === null || selectedSingleValue.value === "") return;
124
- const matched = options.value.some(option => option.value === selectedSingleValue.value);
125
- if (matched) return;
126
- selectedSingleValue.value = undefined;
127
- emit("update:modelValue", undefined);
126
+ const availableValues = options.value.map(option => option.value);
127
+ if (props.type === "checkbox") {
128
+ const normalizedValues = normalizeDictValues(selectedMultiValue.value, availableValues);
129
+ if (normalizedValues.length === selectedMultiValue.value.length) return;
130
+ selectedMultiValue.value = normalizedValues;
131
+ emit("update:modelValue", normalizedValues);
132
+ return;
133
+ }
134
+ const normalizedValue = normalizeDictValue(
135
+ selectedSingleValue.value,
136
+ availableValues
137
+ );
138
+ if (normalizedValue === selectedSingleValue.value) return;
139
+ selectedSingleValue.value = normalizedValue;
140
+ emit("update:modelValue", normalizedValue);
128
141
  }
129
142
 
130
143
  /**
@@ -145,6 +158,7 @@ watch(
145
158
  () => props.modelValue,
146
159
  modelValue => {
147
160
  syncSelectedValue(modelValue);
161
+ if (optionsLoaded.value) ensureSelectedValueValid();
148
162
  },
149
163
  { immediate: true }
150
164
  );
@@ -0,0 +1,18 @@
1
+ /** 字典组件支持的选项值类型。 */
2
+ export type DictOptionValue = string | number;
3
+
4
+ /**
5
+ * 将不在当前字典选项中的单选值归一化为空值。
6
+ *
7
+ * 字典选项通常异步加载,表单重置可能在选项加载完成后再次写入未知枚举值;
8
+ * 统一归一化可以避免 Element Plus 将无匹配的数字直接渲染出来。
9
+ */
10
+ export function normalizeDictValue(value: DictOptionValue | undefined, options: readonly DictOptionValue[]) {
11
+ if (value === undefined || value === null || value === "") return undefined;
12
+ return options.some(option => option === value) ? value : undefined;
13
+ }
14
+
15
+ /** 过滤不在当前字典选项中的多选值。 */
16
+ export function normalizeDictValues(values: readonly DictOptionValue[] | undefined, options: readonly DictOptionValue[]) {
17
+ return (values ?? []).filter(value => options.some(option => option === value));
18
+ }
@@ -1,13 +1,13 @@
1
1
  <template>
2
2
  <el-dialog
3
3
  v-model="dialogVisible"
4
- :title="t('core.upload.batchAdd', { resource: parameter.title })"
4
+ :title="t('core.upload.batch_add', { resource: parameter.title })"
5
5
  :destroy-on-close="true"
6
6
  width="580px"
7
7
  draggable
8
8
  >
9
9
  <el-form class="drawer-multiColumn-form" label-width="100px">
10
- <el-form-item :label="t('core.upload.templateDownload')">
10
+ <el-form-item :label="t('core.upload.template_download')">
11
11
  <el-button type="primary" :icon="Download" @click="downloadTemp">{{ t("common.action.download") }}</el-button>
12
12
  </el-form-item>
13
13
  <el-form-item :label="t('core.upload.file')">
@@ -30,17 +30,17 @@
30
30
  <upload-filled />
31
31
  </el-icon>
32
32
  <div class="el-upload__text">
33
- {{ t("core.upload.dragOrClick") }}<em>{{ t("core.upload.click") }}</em>
33
+ {{ t("core.upload.drag_or_click") }}<em>{{ t("core.upload.click") }}</em>
34
34
  </div>
35
35
  </slot>
36
36
  <template #tip>
37
37
  <slot name="tip">
38
- <div class="el-upload__tip">{{ t("core.upload.excelFormat", { size: parameter.fileSize ?? 5 }) }}</div>
38
+ <div class="el-upload__tip">{{ t("core.upload.excel_format", { size: parameter.fileSize ?? 5 }) }}</div>
39
39
  </slot>
40
40
  </template>
41
41
  </el-upload>
42
42
  </el-form-item>
43
- <el-form-item :label="t('core.upload.dataCover')">
43
+ <el-form-item :label="t('core.upload.data_cover')">
44
44
  <el-switch v-model="isCover" />
45
45
  </el-form-item>
46
46
  </el-form>
@@ -111,14 +111,14 @@ const beforeExcelUpload = (file: UploadRawFile) => {
111
111
  if (!isExcel)
112
112
  ElNotification({
113
113
  title: t("common.title.warning"),
114
- message: t("core.upload.fileFormatInvalid"),
114
+ message: t("core.upload.file_format_invalid"),
115
115
  type: "warning"
116
116
  });
117
117
  if (!fileSize)
118
118
  setTimeout(() => {
119
119
  ElNotification({
120
120
  title: t("common.title.warning"),
121
- message: t("core.upload.fileSizeExceeded", { size: parameter.value.fileSize ?? 5 }),
121
+ message: t("core.upload.file_size_exceeded", { size: parameter.value.fileSize ?? 5 }),
122
122
  type: "warning"
123
123
  });
124
124
  }, 0);
@@ -129,7 +129,7 @@ const beforeExcelUpload = (file: UploadRawFile) => {
129
129
  const handleExceed = () => {
130
130
  ElNotification({
131
131
  title: t("common.title.warning"),
132
- message: t("core.upload.singleFileOnly"),
132
+ message: t("core.upload.single_file_only"),
133
133
  type: "warning"
134
134
  });
135
135
  };
@@ -138,7 +138,7 @@ const handleExceed = () => {
138
138
  const excelUploadError = () => {
139
139
  ElNotification({
140
140
  title: t("common.title.warning"),
141
- message: t("core.upload.batchFailed", { resource: parameter.value.title }),
141
+ message: t("core.upload.batch_failed", { resource: parameter.value.title }),
142
142
  type: "error"
143
143
  });
144
144
  };
@@ -147,7 +147,7 @@ const excelUploadError = () => {
147
147
  const excelUploadSuccess = () => {
148
148
  ElNotification({
149
149
  title: t("common.title.notice"),
150
- message: t("core.upload.batchSuccess", { resource: parameter.value.title }),
150
+ message: t("core.upload.batch_success", { resource: parameter.value.title }),
151
151
  type: "success"
152
152
  });
153
153
  };
@@ -18,7 +18,7 @@ import { type SupportedLocale, useLocaleStore } from "../../locales";
18
18
 
19
19
  const { locale, setLocale, languageOptions, t } = useLocaleStore();
20
20
  const localeOptions = computed(() => {
21
- return languageOptions.value.map(item => ({ value: item.language_code, label: item.language_name }));
21
+ return languageOptions.value.map(item => ({ value: item.language_code, label: item.native_name }));
22
22
  });
23
23
 
24
24
  /** 切换管理端语言并刷新动态本地化数据。 */
@@ -26,7 +26,7 @@ const props = withDefaults(defineProps<DynamicListProps>(), {
26
26
  inputProps: () => ({})
27
27
  });
28
28
 
29
- const resolvedInputProps = computed(() => ({ placeholder: t("common.placeholder.inputContent"), ...props.inputProps }));
29
+ const resolvedInputProps = computed(() => ({ placeholder: t("common.placeholder.input_content"), ...props.inputProps }));
30
30
 
31
31
  const emit = defineEmits<{
32
32
  "update:modelValue": [value: string[]];
@@ -41,8 +41,8 @@ const props = withDefaults(defineProps<KvListProps>(), {
41
41
  addButtonProps: () => ({})
42
42
  });
43
43
 
44
- const resolvedKeyInputProps = computed(() => ({ placeholder: t("common.field.parameterName"), ...props.keyInputProps }));
45
- const resolvedValueInputProps = computed(() => ({ placeholder: t("common.field.parameterValue"), ...props.valueInputProps }));
44
+ const resolvedKeyInputProps = computed(() => ({ placeholder: t("common.field.parameter_name"), ...props.keyInputProps }));
45
+ const resolvedValueInputProps = computed(() => ({ placeholder: t("common.field.parameter_value"), ...props.valueInputProps }));
46
46
 
47
47
  const emit = defineEmits<{
48
48
  "update:modelValue": [value: KvItem[]];
@@ -3,7 +3,7 @@
3
3
  <el-row :gutter="gutter">
4
4
  <template v-for="field in visibleFields" :key="field.prop">
5
5
  <span v-if="field.rowBreakBefore" class="pro-form__row-break" aria-hidden="true" />
6
- <el-col :span="field.colSpan ?? colSpan">
6
+ <el-col :span="field.colSpan ?? colSpan" :xs="24">
7
7
  <el-form-item :label="field.label" :prop="field.prop" :rules="field.rules" v-bind="resolveFieldItemProps(field)">
8
8
  <template v-if="field.labelTooltip" #label>
9
9
  <div class="pro-form__label">
@@ -47,7 +47,7 @@ interface ProFormProps {
47
47
 
48
48
  const props = withDefaults(defineProps<ProFormProps>(), {
49
49
  rules: () => ({}),
50
- labelWidth: "110px",
50
+ labelWidth: "",
51
51
  gutter: 20,
52
52
  colSpan: 24
53
53
  });
@@ -1,9 +1,9 @@
1
1
  <template>
2
2
  <!-- 列设置 -->
3
- <el-drawer v-model="drawerVisible" :title="t('core.table.columnSetting')" size="450px">
3
+ <el-drawer v-model="drawerVisible" :title="t('core.table.column_setting')" size="450px">
4
4
  <div class="table-main">
5
5
  <el-table :data="colSetting" :border="true" row-key="prop" default-expand-all :tree-props="{ children: '_children' }">
6
- <el-table-column prop="label" align="left" :label="t('core.table.columnName')" />
6
+ <el-table-column prop="label" align="left" :label="t('core.table.column_name')" />
7
7
  <el-table-column v-slot="scope" prop="isShow" align="center" :label="t('core.table.show')">
8
8
  <el-switch v-model="scope.row.isShow"></el-switch>
9
9
  </el-table-column>
@@ -13,7 +13,7 @@
13
13
  <template #empty>
14
14
  <div class="table-empty">
15
15
  <img src="../../../assets/images/notData.png" alt="notData" />
16
- <div>{{ t("core.table.noConfigurableColumns") }}</div>
16
+ <div>{{ t("core.table.no_configurable_columns") }}</div>
17
17
  </div>
18
18
  </template>
19
19
  </el-table>
@@ -120,7 +120,7 @@ const renderImageCell = (item: ColumnProps, scope: RenderScope<any>) => {
120
120
  }
121
121
  },
122
122
  {
123
- error: () => h(ElText, { type: "info", size: "small" }, () => t("common.message.noData"))
123
+ error: () => h(ElText, { type: "info", size: "small" }, () => t("common.message.no_data"))
124
124
  }
125
125
  );
126
126
  };
@@ -33,7 +33,7 @@
33
33
  <slot name="toolButton">
34
34
  <el-tooltip
35
35
  v-if="showTreeToggleButton"
36
- :content="isTreeExpanded ? t('core.table.collapseAll') : t('core.table.expandAll')"
36
+ :content="isTreeExpanded ? t('core.table.collapse_all') : t('core.table.expand_all')"
37
37
  placement="top"
38
38
  >
39
39
  <el-button class="tool-button" :icon="isTreeExpanded ? Fold : Expand" circle @click="toggleTreeExpand" />
@@ -41,12 +41,12 @@
41
41
  <el-tooltip v-if="showToolButton('refresh')" :content="t('core.table.refresh')" placement="top">
42
42
  <el-button class="tool-button" :icon="Refresh" circle @click="handleToolRefresh" />
43
43
  </el-tooltip>
44
- <el-tooltip v-if="showToolButton('setting') && columns.length" :content="t('core.table.columnSetting')" placement="top">
44
+ <el-tooltip v-if="showToolButton('setting') && columns.length" :content="t('core.table.column_setting')" placement="top">
45
45
  <el-button class="tool-button" :icon="Operation" circle @click="openColSetting" />
46
46
  </el-tooltip>
47
47
  <el-tooltip
48
48
  v-if="showToolButton('search') && searchColumns?.length"
49
- :content="isShowSearch ? t('core.table.hideSearch') : t('core.table.showSearch')"
49
+ :content="isShowSearch ? t('core.table.hide_search') : t('core.table.show_search')"
50
50
  placement="top"
51
51
  >
52
52
  <el-button class="tool-button" :icon="Search" circle @click="isShowSearch = !isShowSearch" />
@@ -108,7 +108,7 @@
108
108
  <div class="table-empty">
109
109
  <slot name="empty">
110
110
  <img src="../../assets/images/notData.png" alt="notData" />
111
- <div>{{ t("common.message.noData") }}</div>
111
+ <div>{{ t("common.message.no_data") }}</div>
112
112
  </slot>
113
113
  </div>
114
114
  </template>
@@ -155,8 +155,8 @@ const placeholder = computed(() => {
155
155
  if (["datetimerange", "daterange", "monthrange"].includes(search?.props?.type) || search?.props?.isRange) {
156
156
  return {
157
157
  rangeSeparator: search?.props?.rangeSeparator ?? "-",
158
- startPlaceholder: search?.props?.startPlaceholder ?? t("common.field.startTime"),
159
- endPlaceholder: search?.props?.endPlaceholder ?? t("common.field.endTime")
158
+ startPlaceholder: search?.props?.startPlaceholder ?? t("common.field.start_time"),
159
+ endPlaceholder: search?.props?.endPlaceholder ?? t("common.field.end_time")
160
160
  };
161
161
  }
162
162
  const placeholder =
@@ -4,7 +4,7 @@
4
4
  <div class="select-filter-item-title">
5
5
  <span>{{ item.title }} :</span>
6
6
  </div>
7
- <span v-if="!item.options.length" class="select-filter-notData">{{ t("common.message.noData") }}</span>
7
+ <span v-if="!item.options.length" class="select-filter-notData">{{ t("common.message.no_data") }}</span>
8
8
  <el-scrollbar>
9
9
  <ul class="select-filter-list">
10
10
  <li
@@ -4,14 +4,14 @@
4
4
  {{ title }}
5
5
  </h4>
6
6
  <div class="search">
7
- <el-input v-model="filterText" :placeholder="t('core.tree.filterPlaceholder')" clearable />
7
+ <el-input v-model="filterText" :placeholder="t('core.tree.filter_placeholder')" clearable />
8
8
  <el-dropdown trigger="click">
9
9
  <el-icon size="20"><More /></el-icon>
10
10
  <template #dropdown>
11
11
  <el-dropdown-menu>
12
- <el-dropdown-item v-if="!multiple" @click="resetSelected">{{ t("core.tree.resetSelection") }}</el-dropdown-item>
13
- <el-dropdown-item @click="toggleTreeNodes(true)">{{ t("core.table.expandAll") }}</el-dropdown-item>
14
- <el-dropdown-item @click="toggleTreeNodes(false)">{{ t("core.table.collapseAll") }}</el-dropdown-item>
12
+ <el-dropdown-item v-if="!multiple" @click="resetSelected">{{ t("core.tree.reset_selection") }}</el-dropdown-item>
13
+ <el-dropdown-item @click="toggleTreeNodes(true)">{{ t("core.table.expand_all") }}</el-dropdown-item>
14
+ <el-dropdown-item @click="toggleTreeNodes(false)">{{ t("core.table.collapse_all") }}</el-dropdown-item>
15
15
  </el-dropdown-menu>
16
16
  </template>
17
17
  </el-dropdown>
@@ -19,7 +19,7 @@
19
19
  <div class="file-card__main">
20
20
  <el-icon class="file-card__icon"><Document /></el-icon>
21
21
  <div class="file-card__meta">
22
- <div class="file-card__name">{{ fileInfo.name || t("core.upload.unnamedFile") }}</div>
22
+ <div class="file-card__name">{{ fileInfo.name || t("core.upload.unnamed_file") }}</div>
23
23
  <div class="file-card__url">{{ fileInfo.url }}</div>
24
24
  </div>
25
25
  </div>
@@ -73,7 +73,7 @@ type UploadRequestError = Parameters<NonNullable<UploadRequestOptions["onError"]
73
73
 
74
74
  /** 兼容 Element Plus 上传组件要求的错误对象结构。 */
75
75
  function buildUploadError(error: unknown): UploadRequestError {
76
- const uploadError = error instanceof Error ? error : new Error(t("core.upload.fileFailed"));
76
+ const uploadError = error instanceof Error ? error : new Error(t("core.upload.file_failed"));
77
77
  return Object.assign(uploadError, {
78
78
  status: 500,
79
79
  method: "POST",
@@ -94,7 +94,7 @@ const beforeUpload: UploadProps["beforeUpload"] = rawFile => {
94
94
  if (!fileTypeValid) {
95
95
  ElNotification({
96
96
  title: t("common.title.warning"),
97
- message: t("core.upload.fileFormatInvalid"),
97
+ message: t("core.upload.file_format_invalid"),
98
98
  type: "warning"
99
99
  });
100
100
  }
@@ -102,7 +102,7 @@ const beforeUpload: UploadProps["beforeUpload"] = rawFile => {
102
102
  if (!fileSizeValid) {
103
103
  ElNotification({
104
104
  title: t("common.title.warning"),
105
- message: t("core.upload.fileSizeExceeded", { size: props.fileSize }),
105
+ message: t("core.upload.file_size_exceeded", { size: props.fileSize }),
106
106
  type: "warning"
107
107
  });
108
108
  }
@@ -131,7 +131,7 @@ const uploadSuccess = (response: FileInfo | undefined) => {
131
131
  formItemContext?.prop && formContext?.validateField([formItemContext.prop as string]);
132
132
  ElNotification({
133
133
  title: t("common.title.notice"),
134
- message: t("core.upload.fileSuccess"),
134
+ message: t("core.upload.file_success"),
135
135
  type: "success"
136
136
  });
137
137
  };
@@ -140,7 +140,7 @@ const uploadSuccess = (response: FileInfo | undefined) => {
140
140
  const uploadError = () => {
141
141
  ElNotification({
142
142
  title: t("common.title.warning"),
143
- message: t("core.upload.fileFailed"),
143
+ message: t("core.upload.file_failed"),
144
144
  type: "error"
145
145
  });
146
146
  };
@@ -22,7 +22,7 @@
22
22
  <div class="file-card__main">
23
23
  <el-icon class="file-card__icon"><Document /></el-icon>
24
24
  <div class="file-card__meta">
25
- <div class="file-card__name">{{ file.name || t("core.upload.unnamedFile") }}</div>
25
+ <div class="file-card__name">{{ file.name || t("core.upload.unnamed_file") }}</div>
26
26
  <div class="file-card__url">{{ file.url }}</div>
27
27
  </div>
28
28
  </div>
@@ -82,7 +82,7 @@ type UploadRequestError = Parameters<NonNullable<UploadRequestOptions["onError"]
82
82
 
83
83
  /** 兼容 Element Plus 上传组件要求的错误对象结构。 */
84
84
  function buildUploadError(error: unknown): UploadRequestError {
85
- const uploadError = error instanceof Error ? error : new Error(t("core.upload.fileFailed"));
85
+ const uploadError = error instanceof Error ? error : new Error(t("core.upload.file_failed"));
86
86
  return Object.assign(uploadError, {
87
87
  status: 500,
88
88
  method: "POST",
@@ -110,7 +110,7 @@ const beforeUpload: UploadProps["beforeUpload"] = rawFile => {
110
110
  if (!fileTypeValid) {
111
111
  ElNotification({
112
112
  title: t("common.title.warning"),
113
- message: t("core.upload.fileFormatInvalid"),
113
+ message: t("core.upload.file_format_invalid"),
114
114
  type: "warning"
115
115
  });
116
116
  }
@@ -118,7 +118,7 @@ const beforeUpload: UploadProps["beforeUpload"] = rawFile => {
118
118
  if (!fileSizeValid) {
119
119
  ElNotification({
120
120
  title: t("common.title.warning"),
121
- message: t("core.upload.fileSizeExceeded", { size: props.fileSize }),
121
+ message: t("core.upload.file_size_exceeded", { size: props.fileSize }),
122
122
  type: "warning"
123
123
  });
124
124
  }
@@ -151,7 +151,7 @@ const uploadSuccess = (response: FileInfo | undefined) => {
151
151
  formItemContext?.prop && formContext?.validateField([formItemContext.prop as string]);
152
152
  ElNotification({
153
153
  title: t("common.title.notice"),
154
- message: t("core.upload.fileSuccess"),
154
+ message: t("core.upload.file_success"),
155
155
  type: "success"
156
156
  });
157
157
  };
@@ -160,7 +160,7 @@ const uploadSuccess = (response: FileInfo | undefined) => {
160
160
  const uploadError = () => {
161
161
  ElNotification({
162
162
  title: t("common.title.warning"),
163
- message: t("core.upload.fileFailed"),
163
+ message: t("core.upload.file_failed"),
164
164
  type: "error"
165
165
  });
166
166
  };
@@ -169,7 +169,7 @@ const uploadError = () => {
169
169
  function handleExceed() {
170
170
  ElNotification({
171
171
  title: t("common.title.warning"),
172
- message: t("core.upload.limitExceeded", { limit: props.limit }),
172
+ message: t("core.upload.limit_exceeded", { limit: props.limit }),
173
173
  type: "warning"
174
174
  });
175
175
  }
@@ -145,14 +145,14 @@ const beforeUpload: UploadProps["beforeUpload"] = rawFile => {
145
145
  if (!imgType)
146
146
  ElNotification({
147
147
  title: t("common.title.warning"),
148
- message: t("core.upload.imageFormatInvalid"),
148
+ message: t("core.upload.image_format_invalid"),
149
149
  type: "warning"
150
150
  });
151
151
  if (!imgSize)
152
152
  setTimeout(() => {
153
153
  ElNotification({
154
154
  title: t("common.title.warning"),
155
- message: t("core.upload.imageSizeExceeded", { size: props.fileSize }),
155
+ message: t("core.upload.image_size_exceeded", { size: props.fileSize }),
156
156
  type: "warning"
157
157
  });
158
158
  }, 0);
@@ -165,7 +165,7 @@ const beforeUpload: UploadProps["beforeUpload"] = rawFile => {
165
165
  const uploadSuccess = () => {
166
166
  ElNotification({
167
167
  title: t("common.title.notice"),
168
- message: t("core.upload.imageSuccess"),
168
+ message: t("core.upload.image_success"),
169
169
  type: "success"
170
170
  });
171
171
  };
@@ -176,7 +176,7 @@ const uploadSuccess = () => {
176
176
  const uploadError = () => {
177
177
  ElNotification({
178
178
  title: t("common.title.warning"),
179
- message: t("core.upload.imageFailed"),
179
+ message: t("core.upload.image_failed"),
180
180
  type: "error"
181
181
  });
182
182
  };