@liujitcn/kratos-admin-system 0.0.39 → 0.0.41
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.
- package/README.md +22 -0
- package/dist/package/declarations/src/api/system/admin/v1/base_config.d.ts +1 -5
- package/dist/package/declarations/src/components/DynamicI18nCell.vue.d.ts +2 -8
- package/dist/package/declarations/src/components/DynamicI18nEditor.vue.d.ts +20 -3
- package/dist/package/declarations/src/components/dynamicI18n.d.ts +2 -2
- package/dist/package/declarations/src/locales/generated.d.ts +5797 -5813
- package/dist/package/declarations/src/rpc/system/admin/v1/base_config.d.ts +4 -40
- package/dist/package/declarations/src/utils/code-gen-progress.d.ts +3 -0
- package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenGenerateConfirm.vue.d.ts +11 -0
- package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue.d.ts +5 -9
- package/dist/package/declarations/src/views/tool/code-gen/config.d.ts +3 -0
- package/dist/package/src/api/system/admin/v1/base_config.ts +0 -20
- package/dist/package/src/components/DynamicI18nCell.vue +55 -220
- package/dist/package/src/components/DynamicI18nEditor.vue +150 -146
- package/dist/package/src/components/dynamicI18n.ts +10 -6
- package/dist/package/src/config/index.ts +1 -3
- package/dist/package/src/locales/en-US.json +1430 -1434
- package/dist/package/src/locales/ja-JP.json +1430 -1434
- package/dist/package/src/locales/zh-CN.json +1429 -1433
- package/dist/package/src/locales/zh-TW.json +1429 -1433
- package/dist/package/src/module.ts +0 -1
- package/dist/package/src/rpc/system/admin/v1/base_config.ts +3 -43
- package/dist/package/src/utils/code-gen-progress.ts +15 -0
- package/dist/package/src/views/base/config/index.vue +183 -48
- package/dist/package/src/views/base/dict/index.vue +6 -9
- package/dist/package/src/views/base/dict/item.vue +6 -15
- package/dist/package/src/views/base/job/index.vue +16 -17
- package/dist/package/src/views/base/menu/index.vue +78 -15
- package/dist/package/src/views/tool/code-gen/columns/index.vue +17 -25
- package/dist/package/src/views/tool/code-gen/components/CodeGenGenerateConfirm.vue +115 -0
- package/dist/package/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue +27 -186
- package/dist/package/src/views/tool/code-gen/components/CodeGenProgressDialog.vue +2 -0
- package/dist/package/src/views/tool/code-gen/config.ts +15 -1
- package/dist/package/src/views/tool/code-gen/table/index.vue +69 -40
- package/package.json +3 -2
- package/dist/package/declarations/src/config/database-backup.d.ts +0 -12
- package/dist/package/declarations/src/views/base/runtime-config/index.vue.d.ts +0 -3
- package/dist/package/src/config/database-backup.ts +0 -57
- package/dist/package/src/views/base/runtime-config/index.vue +0 -479
|
@@ -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="
|
|
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 {
|
|
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 {
|
|
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: "
|
|
327
|
-
label: t("
|
|
328
|
-
component: "
|
|
329
|
-
|
|
330
|
-
|
|
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:
|
|
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:
|
|
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
|
-
|
|
621
|
+
}
|
|
542
622
|
|
|
543
|
-
|
|
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.
|
|
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()
|
|
580
|
-
|
|
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
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 })
|