@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.
- 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
|
@@ -15,16 +15,9 @@ export declare enum BaseConfigType {
|
|
|
15
15
|
/** BASE_CONFIG_TYPE_DICT - 字典。 */
|
|
16
16
|
BASE_CONFIG_TYPE_DICT = 4,
|
|
17
17
|
/** BASE_CONFIG_TYPE_BOOLEAN - 布尔。 */
|
|
18
|
-
BASE_CONFIG_TYPE_BOOLEAN = 5
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
export declare enum BaseConfigHiddenStatus {
|
|
22
|
-
/** BASE_CONFIG_HIDDEN_STATUS_UNSPECIFIED - 未指定隐藏状态。 */
|
|
23
|
-
BASE_CONFIG_HIDDEN_STATUS_UNSPECIFIED = 0,
|
|
24
|
-
/** BASE_CONFIG_HIDDEN_STATUS_VISIBLE - 普通配置,可在通用配置页面展示。 */
|
|
25
|
-
BASE_CONFIG_HIDDEN_STATUS_VISIBLE = 1,
|
|
26
|
-
/** BASE_CONFIG_HIDDEN_STATUS_HIDDEN - 隐藏配置,仅允许通过专用配置表单访问。 */
|
|
27
|
-
BASE_CONFIG_HIDDEN_STATUS_HIDDEN = 2
|
|
18
|
+
BASE_CONFIG_TYPE_BOOLEAN = 5,
|
|
19
|
+
/** BASE_CONFIG_TYPE_FORM - 表单。 */
|
|
20
|
+
BASE_CONFIG_TYPE_FORM = 6
|
|
28
21
|
}
|
|
29
22
|
/** 系统配置分页查询条件 */
|
|
30
23
|
export interface PageBaseConfigRequest {
|
|
@@ -63,14 +56,12 @@ export interface BaseConfigForm {
|
|
|
63
56
|
site: BaseConfigSite;
|
|
64
57
|
/** 配置名称 */
|
|
65
58
|
name: string;
|
|
66
|
-
/** 配置类型:1、文本,2、图片,3、富文本,4、字典,5
|
|
59
|
+
/** 配置类型:1、文本,2、图片,3、富文本,4、字典,5、布尔,6、表单 */
|
|
67
60
|
type: BaseConfigType;
|
|
68
61
|
/** 配置key */
|
|
69
62
|
key: string;
|
|
70
63
|
/** 配置value */
|
|
71
64
|
value: string;
|
|
72
|
-
/** 隐藏状态 */
|
|
73
|
-
hidden_status: BaseConfigHiddenStatus;
|
|
74
65
|
/** 配置名称多语言翻 */
|
|
75
66
|
name_i18ns: BaseI18n[];
|
|
76
67
|
/** 配置value文本/富文本配置值的多语言翻译 */
|
|
@@ -117,8 +108,6 @@ export interface BaseConfig {
|
|
|
117
108
|
key: string;
|
|
118
109
|
/** 配置value */
|
|
119
110
|
value: string;
|
|
120
|
-
/** 隐藏状态 */
|
|
121
|
-
hidden_status: BaseConfigHiddenStatus;
|
|
122
111
|
/** 状态:枚举【Status】 */
|
|
123
112
|
status: Status;
|
|
124
113
|
/** 创建时间 */
|
|
@@ -128,27 +117,6 @@ export interface BaseConfig {
|
|
|
128
117
|
/** 配置名称及文本/富文本配置值的多语言翻译 */
|
|
129
118
|
i18ns: BaseI18n[];
|
|
130
119
|
}
|
|
131
|
-
/** 按配置键查询系统配置请求参数。 */
|
|
132
|
-
export interface GetBaseConfigByKeyRequest {
|
|
133
|
-
/** 配置key */
|
|
134
|
-
key: string;
|
|
135
|
-
}
|
|
136
|
-
/** 按配置键返回系统配置值。 */
|
|
137
|
-
export interface BaseConfigValue {
|
|
138
|
-
/** 配置key */
|
|
139
|
-
key: string;
|
|
140
|
-
/** JSON格式配置值 */
|
|
141
|
-
value_json: string;
|
|
142
|
-
/** 更新时间 */
|
|
143
|
-
updated_at: string;
|
|
144
|
-
}
|
|
145
|
-
/** 按配置键更新系统配置请求参数。 */
|
|
146
|
-
export interface UpdateBaseConfigByKeyRequest {
|
|
147
|
-
/** 配置key */
|
|
148
|
-
key: string;
|
|
149
|
-
/** JSON格式配置值 */
|
|
150
|
-
value_json: string;
|
|
151
|
-
}
|
|
152
120
|
/** Admin系统配置服务 */
|
|
153
121
|
export interface BaseConfigService {
|
|
154
122
|
/** 刷新缓存 */
|
|
@@ -157,14 +125,10 @@ export interface BaseConfigService {
|
|
|
157
125
|
PageBaseConfig(request: PageBaseConfigRequest): Promise<PageBaseConfigResponse>;
|
|
158
126
|
/** 查询系统配置 */
|
|
159
127
|
GetBaseConfig(request: GetBaseConfigRequest): Promise<BaseConfigForm>;
|
|
160
|
-
/** 按配置键查询隐藏系统配置。 */
|
|
161
|
-
GetBaseConfigByKey(request: GetBaseConfigByKeyRequest): Promise<BaseConfigValue>;
|
|
162
128
|
/** 创建系统配置 */
|
|
163
129
|
CreateBaseConfig(request: CreateBaseConfigRequest): Promise<Empty>;
|
|
164
130
|
/** 更新系统配置 */
|
|
165
131
|
UpdateBaseConfig(request: UpdateBaseConfigRequest): Promise<Empty>;
|
|
166
|
-
/** 按配置键更新隐藏系统配置。 */
|
|
167
|
-
UpdateBaseConfigByKey(request: UpdateBaseConfigByKeyRequest): Promise<Empty>;
|
|
168
132
|
/** 删除系统配置 */
|
|
169
133
|
DeleteBaseConfig(request: DeleteBaseConfigRequest): Promise<Empty>;
|
|
170
134
|
/** 设置状态 */
|
package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenGenerateConfirm.vue.d.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** 生成确认内容,按业务表保留缺失翻译明细。 */
|
|
2
|
+
type __VLS_Props = {
|
|
3
|
+
message: string;
|
|
4
|
+
groups: Array<{
|
|
5
|
+
name: string;
|
|
6
|
+
items: string[];
|
|
7
|
+
}>;
|
|
8
|
+
};
|
|
9
|
+
declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
10
|
+
declare const _default: typeof __VLS_export;
|
|
11
|
+
export default _default;
|
package/dist/package/declarations/src/views/tool/code-gen/components/CodeGenLocaleEditor.vue.d.ts
CHANGED
|
@@ -1,23 +1,19 @@
|
|
|
1
1
|
import type { CodeGenLocaleConfig } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_i18n";
|
|
2
|
-
/**
|
|
2
|
+
/** 代码生成描述使用统一国际化入口,按字段保存回语言配置。 */
|
|
3
3
|
interface CodeGenLocaleEditorProps {
|
|
4
|
-
/** 按语言区域索引的生成配置。 */
|
|
5
4
|
modelValue: Map<string, CodeGenLocaleConfig>;
|
|
6
|
-
/** 中文业务或字段描述。 */
|
|
7
5
|
sourceComment?: string;
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
/** 中文左树标题。 */
|
|
11
|
-
sourceLeftTreeComment?: string;
|
|
6
|
+
field?: keyof CodeGenLocaleConfig;
|
|
7
|
+
disabled?: boolean;
|
|
12
8
|
}
|
|
13
9
|
declare const __VLS_export: import("vue").DefineComponent<CodeGenLocaleEditorProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
14
10
|
"update:modelValue": (value: Map<string, CodeGenLocaleConfig>) => any;
|
|
15
11
|
}, string, import("vue").PublicProps, Readonly<CodeGenLocaleEditorProps> & Readonly<{
|
|
16
12
|
"onUpdate:modelValue"?: ((value: Map<string, CodeGenLocaleConfig>) => any) | undefined;
|
|
17
13
|
}>, {
|
|
14
|
+
disabled: boolean;
|
|
15
|
+
field: keyof CodeGenLocaleConfig;
|
|
18
16
|
sourceComment: string;
|
|
19
|
-
showLeftTreeComment: boolean;
|
|
20
|
-
sourceLeftTreeComment: string;
|
|
21
17
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
|
|
22
18
|
declare const _default: typeof __VLS_export;
|
|
23
19
|
export default _default;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CodeGenLocaleConfig } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_i18n";
|
|
1
2
|
import type { FormRules } from "element-plus";
|
|
2
3
|
import type { ProFormOption } from "@liujitcn/kratos-admin-core/components/ProForm/interface";
|
|
3
4
|
import type { CodeGenColumnFormConfig, CodeGenColumnListConfig, CodeGenColumnOptionConfig, CodeGenColumnQueryConfig } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/code_gen_column";
|
|
@@ -30,3 +31,5 @@ export declare function createDefaultCodeGenListConfig(): CodeGenColumnListConfi
|
|
|
30
31
|
export declare function createDefaultCodeGenFormConfig(): CodeGenColumnFormConfig;
|
|
31
32
|
/** 创建一份独立的字段选项配置。 */
|
|
32
33
|
export declare function createDefaultCodeGenOptionConfig(): CodeGenColumnOptionConfig;
|
|
34
|
+
/** 保存代码生成配置时,以原值补齐尚未填写的启用语言描述。 */
|
|
35
|
+
export declare function withCodeGenLocaleDefaults(values: Map<string, CodeGenLocaleConfig>, comment: string, leftTreeComment?: string): Map<string, CodeGenLocaleConfig>;
|
|
@@ -4,14 +4,11 @@ import {
|
|
|
4
4
|
type BaseConfigService,
|
|
5
5
|
type CreateBaseConfigRequest,
|
|
6
6
|
type DeleteBaseConfigRequest,
|
|
7
|
-
type GetBaseConfigByKeyRequest,
|
|
8
|
-
type BaseConfigValue,
|
|
9
7
|
type GetBaseConfigRequest,
|
|
10
8
|
type PageBaseConfigRequest,
|
|
11
9
|
type PageBaseConfigResponse,
|
|
12
10
|
type RefreshBaseConfigCacheRequest,
|
|
13
11
|
type SetBaseConfigStatusRequest,
|
|
14
|
-
type UpdateBaseConfigByKeyRequest,
|
|
15
12
|
type UpdateBaseConfigRequest
|
|
16
13
|
} from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_config";
|
|
17
14
|
import type { Empty } from "@liujitcn/kratos-admin-system/rpc/google/protobuf/empty";
|
|
@@ -46,14 +43,6 @@ export class BaseConfigServiceImpl implements BaseConfigService {
|
|
|
46
43
|
});
|
|
47
44
|
}
|
|
48
45
|
|
|
49
|
-
/** 按配置键查询隐藏系统配置。 */
|
|
50
|
-
GetBaseConfigByKey(request: GetBaseConfigByKeyRequest): Promise<BaseConfigValue> {
|
|
51
|
-
return service<GetBaseConfigByKeyRequest, BaseConfigValue>({
|
|
52
|
-
url: `${BASE_CONFIG_URL}/key/${request.key}`,
|
|
53
|
-
method: "get"
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
|
|
57
46
|
/** 创建系统配置 */
|
|
58
47
|
CreateBaseConfig(request: CreateBaseConfigRequest): Promise<Empty> {
|
|
59
48
|
return service<BaseConfigForm | undefined, Empty>({
|
|
@@ -72,15 +61,6 @@ export class BaseConfigServiceImpl implements BaseConfigService {
|
|
|
72
61
|
});
|
|
73
62
|
}
|
|
74
63
|
|
|
75
|
-
/** 按配置键更新隐藏系统配置。 */
|
|
76
|
-
UpdateBaseConfigByKey(request: UpdateBaseConfigByKeyRequest): Promise<Empty> {
|
|
77
|
-
return service<Pick<UpdateBaseConfigByKeyRequest, "value_json">, Empty>({
|
|
78
|
-
url: `${BASE_CONFIG_URL}/key/${request.key}`,
|
|
79
|
-
method: "put",
|
|
80
|
-
data: { value_json: request.value_json }
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
64
|
/** 删除系统配置 */
|
|
85
65
|
DeleteBaseConfig(request: DeleteBaseConfigRequest): Promise<Empty> {
|
|
86
66
|
return service<DeleteBaseConfigRequest, Empty>({
|
|
@@ -1,269 +1,104 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
:
|
|
9
|
-
|
|
10
|
-
append-to-body
|
|
11
|
-
:show-footer="false"
|
|
12
|
-
:destroy-on-close="true"
|
|
13
|
-
@closed="handleDialogClosed"
|
|
2
|
+
<DynamicI18nEditor
|
|
3
|
+
v-if="enabled"
|
|
4
|
+
:key="`${targetType}:${targetId}`"
|
|
5
|
+
:model-value="values"
|
|
6
|
+
:source="source"
|
|
7
|
+
:readonly="!editable || !targetType || !targetId || saving"
|
|
8
|
+
:maxlength="10000"
|
|
9
|
+
@update:model-value="saveValues"
|
|
14
10
|
>
|
|
15
|
-
<
|
|
16
|
-
<el-
|
|
17
|
-
<
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
<template #default="{ row }">
|
|
23
|
-
<el-input
|
|
24
|
-
v-if="row.editing"
|
|
25
|
-
v-model="row.text"
|
|
26
|
-
:placeholder="t('system.base.i18n.placeholder.text', { language: getLanguageLabel(row.locale) })"
|
|
27
|
-
/>
|
|
28
|
-
<span v-else class="dynamic-i18n-dialog__text">
|
|
29
|
-
{{ row.text || t("common.value.none") }}
|
|
30
|
-
</span>
|
|
31
|
-
</template>
|
|
32
|
-
</el-table-column>
|
|
33
|
-
<el-table-column v-if="editable" :label="t('common.field.operation')" width="200" fixed="right">
|
|
34
|
-
<template #default="{ row }">
|
|
35
|
-
<el-button
|
|
36
|
-
v-if="editable && !row.editing"
|
|
37
|
-
link
|
|
38
|
-
type="primary"
|
|
39
|
-
:icon="EditPen"
|
|
40
|
-
@click="startEdit(row as DynamicI18nRow)"
|
|
41
|
-
>
|
|
42
|
-
{{ t("common.action.edit") }}
|
|
43
|
-
</el-button>
|
|
44
|
-
<template v-else>
|
|
45
|
-
<el-button
|
|
46
|
-
link
|
|
47
|
-
type="primary"
|
|
48
|
-
:icon="Check"
|
|
49
|
-
:loading="row.saving"
|
|
50
|
-
@click="saveI18n(row as DynamicI18nRow)"
|
|
51
|
-
>
|
|
52
|
-
{{ t("common.action.save") }}
|
|
53
|
-
</el-button>
|
|
54
|
-
<el-button link :icon="Close" :disabled="row.saving" @click="cancelEdit(row as DynamicI18nRow)">
|
|
55
|
-
{{ t("common.action.cancel") }}
|
|
56
|
-
</el-button>
|
|
57
|
-
</template>
|
|
58
|
-
</template>
|
|
59
|
-
</el-table-column>
|
|
60
|
-
</el-table>
|
|
61
|
-
</ProDialog>
|
|
11
|
+
<template #trigger="{ open }">
|
|
12
|
+
<el-link class="dynamic-i18n-cell" type="primary" underline="never" @click="open">
|
|
13
|
+
<span>{{ displaySource || "--" }}</span>
|
|
14
|
+
</el-link>
|
|
15
|
+
</template>
|
|
16
|
+
</DynamicI18nEditor>
|
|
17
|
+
<span v-else>{{ source || "--" }}</span>
|
|
62
18
|
</template>
|
|
63
19
|
|
|
64
20
|
<script setup lang="ts">
|
|
65
21
|
import { computed, ref, watch } from "vue";
|
|
66
|
-
import { ElMessage } from "element-plus";
|
|
67
|
-
import { Check, Close, EditPen } from "@element-plus/icons-vue";
|
|
68
|
-
import ProDialog from "@liujitcn/kratos-admin-core/components/Dialog/ProDialog.vue";
|
|
69
22
|
import { t, useLocaleStore } from "@liujitcn/kratos-admin-core";
|
|
70
|
-
import { loadEnabledBaseLanguages, useEnabledBaseLanguages } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_language";
|
|
71
23
|
import { defBaseI18nService } from "@liujitcn/kratos-admin-system/api/system/admin/v1/base_i18n";
|
|
72
|
-
import type { BaseI18n } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_i18n";
|
|
73
|
-
import
|
|
74
|
-
import {
|
|
24
|
+
import type { BaseI18n, I18nTargetType } from "@liujitcn/kratos-admin-system/rpc/system/admin/v1/base_i18n";
|
|
25
|
+
import DynamicI18nEditor from "./DynamicI18nEditor.vue";
|
|
26
|
+
import { getEditableLanguageOptions, type DynamicI18nValue } from "./dynamicI18n";
|
|
75
27
|
|
|
76
|
-
/**
|
|
28
|
+
/** 列表国际化字段入口,未启用非主语言时退回普通文本。 */
|
|
77
29
|
interface DynamicI18nCellProps {
|
|
78
|
-
/** 资源源文。 */
|
|
79
30
|
source: string;
|
|
80
|
-
/** 统一翻译表目标类型。 */
|
|
81
31
|
targetType?: I18nTargetType;
|
|
82
|
-
/** 目标资源编号。 */
|
|
83
32
|
targetId?: number;
|
|
84
|
-
/** 资源列表返回的非主语言翻译。 */
|
|
85
33
|
i18ns?: BaseI18n[];
|
|
86
|
-
/** 是否允许编辑翻译。 */
|
|
87
34
|
editable?: boolean;
|
|
88
35
|
}
|
|
89
|
-
|
|
90
|
-
const props = withDefaults(defineProps<DynamicI18nCellProps>(), {
|
|
91
|
-
editable: true
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
const editable = computed(() => props.editable);
|
|
95
|
-
|
|
96
|
-
const { languages } = useEnabledBaseLanguages();
|
|
36
|
+
const props = withDefaults(defineProps<DynamicI18nCellProps>(), { editable: true });
|
|
97
37
|
const { locale } = useLocaleStore();
|
|
98
|
-
const
|
|
99
|
-
const
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
return i18n?.name || props.source;
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
watch(
|
|
111
|
-
() => [props.targetType, props.targetId],
|
|
112
|
-
() => {
|
|
113
|
-
i18nRows.value = [];
|
|
114
|
-
i18nOverrides.value.clear();
|
|
115
|
-
dialogVisible.value = false;
|
|
116
|
-
}
|
|
38
|
+
const enabled = computed(() => getEditableLanguageOptions().length > 0);
|
|
39
|
+
const overrides = ref(new Map<string, string>());
|
|
40
|
+
const saving = ref(false);
|
|
41
|
+
let resourceVersion = 0;
|
|
42
|
+
const values = computed<DynamicI18nValue[]>(() =>
|
|
43
|
+
getEditableLanguageOptions().map(({ value }) => {
|
|
44
|
+
const record = props.i18ns?.find(item => item.locale === value);
|
|
45
|
+
return { id: record?.id ?? 0, locale: value, text: overrides.value.get(value) ?? record?.name ?? "" };
|
|
46
|
+
})
|
|
117
47
|
);
|
|
48
|
+
const displaySource = computed(() => values.value.find(item => item.locale === locale.value)?.text || props.source);
|
|
118
49
|
|
|
119
|
-
/**
|
|
120
|
-
|
|
121
|
-
/** 翻译记录主键,新增翻译时为空。 */
|
|
122
|
-
id: number;
|
|
123
|
-
/** 语言区域。 */
|
|
124
|
-
locale: string;
|
|
125
|
-
/** 翻译文本。 */
|
|
126
|
-
text: string;
|
|
127
|
-
/** 是否处于编辑状态。 */
|
|
128
|
-
editing: boolean;
|
|
129
|
-
/** 是否正在保存。 */
|
|
130
|
-
saving: boolean;
|
|
131
|
-
/** 编辑前的文本,用于取消编辑。 */
|
|
132
|
-
originalText: string;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/** openDialog 打开翻译编辑弹窗并加载当前资源译文。 */
|
|
136
|
-
async function openDialog() {
|
|
137
|
-
dialogVisible.value = true;
|
|
138
|
-
await loadI18ns();
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
/** loadI18ns 查询当前资源的翻译并补齐启用语言行。 */
|
|
142
|
-
async function loadI18ns() {
|
|
50
|
+
/** 仅在确认后保存发生变化的译文,打开窗口不会自动翻译或写库。 */
|
|
51
|
+
async function saveValues(next: DynamicI18nValue[]) {
|
|
143
52
|
const targetType = props.targetType;
|
|
144
53
|
const targetId = props.targetId;
|
|
145
|
-
if (!targetType || !targetId) return;
|
|
146
|
-
|
|
54
|
+
if (!props.editable || !targetType || !targetId || saving.value) return;
|
|
55
|
+
const changed = next.filter(item => item.text !== values.value.find(value => value.locale === item.locale)?.text);
|
|
56
|
+
if (!changed.length) return;
|
|
57
|
+
const version = resourceVersion;
|
|
58
|
+
saving.value = true;
|
|
147
59
|
try {
|
|
148
|
-
await loadEnabledBaseLanguages();
|
|
149
|
-
const rows = await queryI18nRows();
|
|
150
|
-
i18nRows.value = rows;
|
|
151
|
-
if (!props.editable) return;
|
|
152
|
-
const missingRows = rows.filter(row => !row.text);
|
|
153
|
-
if (missingRows.length === 0) return;
|
|
154
|
-
if (!props.source) return;
|
|
155
|
-
const draft = await defBaseI18nService.DraftBaseI18n({ source: props.source });
|
|
156
|
-
const i18ns = new Map(draft.i18ns.map(item => [item.locale, item.i18n]));
|
|
157
60
|
const results = await Promise.allSettled(
|
|
158
|
-
|
|
159
|
-
const i18n = i18ns.get(row.locale);
|
|
160
|
-
if (!i18n) throw new Error("i18n not found");
|
|
61
|
+
changed.map(async item => {
|
|
161
62
|
await defBaseI18nService.UpdateBaseI18n({
|
|
162
|
-
id:
|
|
63
|
+
id: item.id,
|
|
163
64
|
target_type: targetType,
|
|
164
65
|
target_id: targetId,
|
|
165
|
-
locale:
|
|
166
|
-
name:
|
|
66
|
+
locale: item.locale,
|
|
67
|
+
name: item.text
|
|
167
68
|
});
|
|
168
|
-
return
|
|
69
|
+
return item;
|
|
169
70
|
})
|
|
170
71
|
);
|
|
72
|
+
if (version !== resourceVersion) return;
|
|
171
73
|
for (const result of results) {
|
|
172
|
-
if (result.status
|
|
173
|
-
result.value.row.text = result.value.text;
|
|
174
|
-
result.value.row.originalText = result.value.text;
|
|
175
|
-
i18nOverrides.value.set(result.value.row.locale, result.value.text);
|
|
74
|
+
if (result.status === "fulfilled") overrides.value.set(result.value.locale, result.value.text);
|
|
176
75
|
}
|
|
177
|
-
|
|
178
|
-
ElMessage.
|
|
76
|
+
if (results.some(result => result.status === "rejected")) ElMessage.error(t("common.message.system_error"));
|
|
77
|
+
else ElMessage.success(t("common.message.operation_success"));
|
|
179
78
|
} finally {
|
|
180
|
-
|
|
79
|
+
if (version === resourceVersion) saving.value = false;
|
|
181
80
|
}
|
|
182
81
|
}
|
|
183
82
|
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
.
|
|
189
|
-
.
|
|
190
|
-
const record = records.get(item.language_code);
|
|
191
|
-
const text = i18nOverrides.value.get(item.language_code) ?? record?.name ?? "";
|
|
192
|
-
return {
|
|
193
|
-
id: record?.id ?? 0,
|
|
194
|
-
locale: item.language_code,
|
|
195
|
-
text,
|
|
196
|
-
editing: false,
|
|
197
|
-
saving: false,
|
|
198
|
-
originalText: text
|
|
199
|
-
};
|
|
200
|
-
});
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
/** startEdit 开启指定语言的编辑状态。 */
|
|
204
|
-
function startEdit(row: DynamicI18nRow) {
|
|
205
|
-
if (!props.editable) return;
|
|
206
|
-
row.originalText = row.text;
|
|
207
|
-
row.editing = true;
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/** cancelEdit 恢复编辑前的内容。 */
|
|
211
|
-
function cancelEdit(row: DynamicI18nRow) {
|
|
212
|
-
row.text = row.originalText;
|
|
213
|
-
row.editing = false;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
/** saveI18n 使用统一更新接口保存指定语言译文。 */
|
|
217
|
-
async function saveI18n(row: DynamicI18nRow) {
|
|
218
|
-
const targetType = props.targetType;
|
|
219
|
-
const targetId = props.targetId;
|
|
220
|
-
if (!props.editable || row.saving || !targetType || !targetId) return;
|
|
221
|
-
if (row.id === 0 && !row.text) {
|
|
222
|
-
row.editing = false;
|
|
223
|
-
return;
|
|
224
|
-
}
|
|
225
|
-
row.saving = true;
|
|
226
|
-
try {
|
|
227
|
-
await defBaseI18nService.UpdateBaseI18n({
|
|
228
|
-
id: row.id,
|
|
229
|
-
target_type: targetType,
|
|
230
|
-
target_id: targetId,
|
|
231
|
-
locale: row.locale,
|
|
232
|
-
name: row.text
|
|
233
|
-
});
|
|
234
|
-
ElMessage.success(t("common.message.operation_success"));
|
|
235
|
-
row.editing = false;
|
|
236
|
-
row.originalText = row.text;
|
|
237
|
-
i18nOverrides.value.set(row.locale, row.text);
|
|
238
|
-
} catch {
|
|
239
|
-
ElMessage.error(t("common.message.system_error"));
|
|
240
|
-
} finally {
|
|
241
|
-
row.saving = false;
|
|
83
|
+
watch(
|
|
84
|
+
() => [props.targetType, props.targetId],
|
|
85
|
+
() => {
|
|
86
|
+
resourceVersion++;
|
|
87
|
+
overrides.value.clear();
|
|
88
|
+
saving.value = false;
|
|
242
89
|
}
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
/** handleDialogClosed 清理弹窗状态,避免复用旧资源译文。 */
|
|
246
|
-
function handleDialogClosed() {
|
|
247
|
-
i18nRows.value = [];
|
|
248
|
-
loading.value = false;
|
|
249
|
-
}
|
|
90
|
+
);
|
|
250
91
|
</script>
|
|
251
92
|
|
|
252
93
|
<style scoped>
|
|
253
94
|
.dynamic-i18n-cell {
|
|
254
95
|
display: inline-flex;
|
|
255
|
-
align-items: center;
|
|
256
96
|
min-width: 0;
|
|
257
97
|
max-width: 100%;
|
|
258
98
|
}
|
|
259
|
-
.dynamic-i18n-
|
|
260
|
-
min-width: 0;
|
|
99
|
+
.dynamic-i18n-cell span {
|
|
261
100
|
overflow: hidden;
|
|
262
101
|
text-overflow: ellipsis;
|
|
263
102
|
white-space: nowrap;
|
|
264
103
|
}
|
|
265
|
-
.dynamic-i18n-dialog__text {
|
|
266
|
-
min-width: 0;
|
|
267
|
-
overflow-wrap: anywhere;
|
|
268
|
-
}
|
|
269
104
|
</style>
|