@liujitcn/kratos-admin-core 0.0.20 → 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.
- package/README.md +2 -2
- package/dist/package/declarations/src/api/base/language.d.ts +8 -0
- package/dist/package/declarations/src/components/Dialog/ProDialog.vue.d.ts +1 -0
- package/dist/package/declarations/src/components/Dict/index.vue.d.ts +4 -3
- package/dist/package/declarations/src/components/Dict/value.d.ts +11 -0
- package/dist/package/declarations/src/components/LocaleSwitch/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/index.d.ts +2 -0
- package/dist/package/declarations/src/locales/generated.d.ts +3382 -0
- package/dist/package/declarations/src/locales/index.d.ts +53 -0
- package/dist/package/declarations/src/modules/index.d.ts +7 -2
- package/dist/package/declarations/src/request.d.ts +1 -0
- package/dist/package/declarations/src/routers/modules/staticRouter.d.ts +1 -0
- package/dist/package/declarations/src/rpc/base/v1/config.d.ts +13 -1
- package/dist/package/declarations/src/rpc/base/v1/language.d.ts +20 -0
- package/dist/package/declarations/src/rpc/base/v1/login.d.ts +13 -1
- package/dist/package/declarations/src/rpc/system/admin/v1/auth.d.ts +1 -1
- package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +9 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_translation.d.ts +75 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/common.d.ts +13 -0
- package/dist/package/declarations/src/stores/interface/index.d.ts +2 -0
- package/dist/package/declarations/src/stores/modules/auth.d.ts +6 -6
- package/dist/package/declarations/src/stores/runtime.d.ts +1 -0
- package/dist/package/declarations/src/utils/dict.d.ts +2 -2
- package/dist/package/declarations/src/utils/index.d.ts +1 -1
- package/dist/package/declarations/src/utils/oauthProvider.d.ts +2 -0
- package/dist/package/declarations/src/utils/passwordCrypto.d.ts +1 -1
- package/dist/package/declarations/src/utils/passwordStrength.d.ts +0 -7
- package/dist/package/src/App.vue +5 -2
- package/dist/package/src/api/base/language.ts +20 -0
- package/dist/package/src/api/base/oauth.ts +0 -1
- package/dist/package/src/api/system/auth.ts +0 -1
- package/dist/package/src/bootstrap.ts +57 -2
- package/dist/package/src/components/CronExpression/index.vue +80 -82
- package/dist/package/src/components/Dialog/FormDialog.vue +10 -5
- package/dist/package/src/components/Dialog/ProDialog.vue +10 -4
- package/dist/package/src/components/Dict/index.vue +26 -9
- package/dist/package/src/components/Dict/value.ts +18 -0
- package/dist/package/src/components/ECharts/config/index.ts +6 -1
- package/dist/package/src/components/ErrorMessage/index.vue +3 -1
- package/dist/package/src/components/ImportExcel/index.vue +29 -18
- package/dist/package/src/components/LocaleSwitch/index.vue +28 -0
- package/dist/package/src/components/PasswordStrength/index.vue +8 -5
- package/dist/package/src/components/ProForm/components/DynamicList.vue +8 -3
- package/dist/package/src/components/ProForm/components/KvList.vue +14 -6
- package/dist/package/src/components/ProForm/index.vue +2 -2
- package/dist/package/src/components/ProTable/components/ColSetting.vue +7 -5
- package/dist/package/src/components/ProTable/components/TableColumn.vue +2 -1
- package/dist/package/src/components/ProTable/index.vue +36 -11
- package/dist/package/src/components/SearchForm/components/SearchFormItem.vue +9 -4
- package/dist/package/src/components/SearchForm/index.vue +6 -3
- package/dist/package/src/components/SelectFilter/index.vue +4 -1
- package/dist/package/src/components/SelectIcon/index.vue +8 -4
- package/dist/package/src/components/TreeFilter/index.vue +14 -6
- package/dist/package/src/components/Upload/File.vue +18 -13
- package/dist/package/src/components/Upload/Files.vue +22 -15
- package/dist/package/src/components/Upload/Img.vue +14 -11
- package/dist/package/src/components/Upload/Imgs.vue +15 -12
- package/dist/package/src/components/WangEditor/index.vue +12 -4
- package/dist/package/src/directives/modules/copy.ts +2 -1
- package/dist/package/src/hooks/useDownload.ts +3 -2
- package/dist/package/src/hooks/useHandleData.ts +5 -4
- package/dist/package/src/hooks/useTheme.ts +2 -1
- package/dist/package/src/hooks/useTime.ts +11 -2
- package/dist/package/src/index.ts +2 -0
- package/dist/package/src/layouts/components/Header/ToolBarRight.vue +2 -0
- package/dist/package/src/layouts/components/Header/components/AssemblySize.vue +8 -6
- package/dist/package/src/layouts/components/Header/components/Avatar.vue +11 -9
- package/dist/package/src/layouts/components/Header/components/Breadcrumb.vue +11 -3
- package/dist/package/src/layouts/components/Header/components/Fullscreen.vue +4 -2
- package/dist/package/src/layouts/components/Header/components/InfoDialog.vue +6 -3
- package/dist/package/src/layouts/components/Header/components/PasswordDialog.vue +6 -3
- package/dist/package/src/layouts/components/Header/components/SearchMenu.vue +5 -3
- package/dist/package/src/layouts/components/Header/components/ThemeSetting.vue +3 -1
- package/dist/package/src/layouts/components/Main/index.vue +1 -0
- package/dist/package/src/layouts/components/Tabs/components/MoreButton.vue +9 -7
- package/dist/package/src/layouts/components/Tabs/index.vue +15 -1
- package/dist/package/src/layouts/components/ThemeDrawer/index.vue +27 -24
- package/dist/package/src/locales/README.md +15 -0
- package/dist/package/src/locales/en-US.json +283 -0
- package/dist/package/src/locales/es-ES.json +283 -0
- package/dist/package/src/locales/fr-FR.json +283 -0
- package/dist/package/src/locales/generated.ts +57 -0
- package/dist/package/src/locales/index.ts +222 -0
- package/dist/package/src/locales/ja-JP.json +283 -0
- package/dist/package/src/locales/ko-KR.json +283 -0
- package/dist/package/src/locales/zh-CN.json +283 -0
- package/dist/package/src/locales/zh-TW.json +283 -0
- package/dist/package/src/modules/index.ts +7 -2
- package/dist/package/src/modules/kratosAdmin.ts +5 -1
- package/dist/package/src/request.ts +8 -1
- package/dist/package/src/routers/index.ts +4 -1
- package/dist/package/src/routers/modules/dynamicRouter.ts +5 -4
- package/dist/package/src/routers/modules/staticRouter.ts +8 -4
- package/dist/package/src/rpc/base/v1/config.ts +14 -1
- package/dist/package/src/rpc/base/v1/language.ts +31 -0
- package/dist/package/src/rpc/base/v1/login.ts +14 -1
- package/dist/package/src/rpc/system/admin/v1/auth.ts +1 -1
- package/dist/package/src/rpc/system/admin/v1/base_dict.ts +9 -0
- package/dist/package/src/rpc/system/admin/v1/base_translation.ts +90 -0
- package/dist/package/src/rpc/system/admin/v1/common.ts +21 -0
- package/dist/package/src/stores/interface/index.ts +2 -0
- package/dist/package/src/stores/modules/config.ts +7 -3
- package/dist/package/src/stores/modules/user.ts +2 -1
- package/dist/package/src/stores/runtime.ts +1 -0
- package/dist/package/src/styles/element.scss +2 -0
- package/dist/package/src/utils/color.ts +5 -4
- package/dist/package/src/utils/dict.ts +27 -4
- package/dist/package/src/utils/eleValidate.ts +3 -2
- package/dist/package/src/utils/errorHandler.ts +9 -8
- package/dist/package/src/utils/index.ts +9 -8
- package/dist/package/src/utils/oauthProvider.ts +15 -10
- package/dist/package/src/utils/passwordCrypto.ts +4 -3
- package/dist/package/src/utils/passwordStrength.ts +1 -16
- package/dist/package/src/utils/request.ts +13 -8
- package/dist/package/src/views/error/403.vue +3 -1
- package/dist/package/src/views/error/404.vue +3 -1
- package/dist/package/src/views/error/500.vue +3 -1
- package/dist/package/src/views/error/pending.vue +5 -2
- package/dist/package/src/views/login/components/LoginForm.vue +58 -29
- package/dist/package/src/views/login/index.scss +6 -0
- package/dist/package/src/views/login/index.vue +2 -0
- package/dist/package/types/generated/auto-imports.d.ts +129 -111
- package/dist/package/types/generated/components.d.ts +67 -67
- package/package.json +4 -2
- package/types/generated/auto-imports.d.ts +129 -111
- package/types/generated/components.d.ts +67 -67
- package/vite.config.ts +12 -0
- package/dist/package/declarations/src/rpc/base/v1/enum.d.ts +0 -43
- package/dist/package/declarations/src/rpc/system/common/v1/enum.d.ts +0 -67
- package/dist/package/src/rpc/base/v1/enum.ts +0 -54
- package/dist/package/src/rpc/system/common/v1/enum.ts +0 -80
|
@@ -12,20 +12,22 @@
|
|
|
12
12
|
:on-error="uploadError"
|
|
13
13
|
:accept="fileType.join(',')"
|
|
14
14
|
>
|
|
15
|
-
<el-button type="primary" :disabled="selfDisabled"
|
|
15
|
+
<el-button type="primary" :disabled="selfDisabled">{{ t("core.upload.action") }}</el-button>
|
|
16
16
|
</el-upload>
|
|
17
17
|
|
|
18
18
|
<div v-if="fileInfo?.url" class="file-card">
|
|
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 || "
|
|
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>
|
|
26
26
|
<div class="file-card__action">
|
|
27
|
-
<el-button link type="primary" :icon="Download" @click.stop="handleDownload"
|
|
28
|
-
<el-button v-if="!selfDisabled" link type="danger" :icon="Delete" @click.stop="handleDelete"
|
|
27
|
+
<el-button link type="primary" :icon="Download" @click.stop="handleDownload">{{ t("common.action.download") }}</el-button>
|
|
28
|
+
<el-button v-if="!selfDisabled" link type="danger" :icon="Delete" @click.stop="handleDelete">
|
|
29
|
+
{{ t("common.action.delete") }}
|
|
30
|
+
</el-button>
|
|
29
31
|
</div>
|
|
30
32
|
</div>
|
|
31
33
|
</div>
|
|
@@ -38,6 +40,9 @@ import { ElNotification, formContextKey, formItemContextKey } from "element-plus
|
|
|
38
40
|
import type { UploadProps, UploadRequestOptions, UploadUserFile } from "element-plus";
|
|
39
41
|
import { defFileService } from "../../api/base/file";
|
|
40
42
|
import type { FileInfo } from "../../rpc/base/v1/file";
|
|
43
|
+
import { useLocaleStore } from "../../locales";
|
|
44
|
+
|
|
45
|
+
const { t } = useLocaleStore();
|
|
41
46
|
|
|
42
47
|
/** 单文件上传组件属性。 */
|
|
43
48
|
interface UploadFileProps {
|
|
@@ -68,7 +73,7 @@ type UploadRequestError = Parameters<NonNullable<UploadRequestOptions["onError"]
|
|
|
68
73
|
|
|
69
74
|
/** 兼容 Element Plus 上传组件要求的错误对象结构。 */
|
|
70
75
|
function buildUploadError(error: unknown): UploadRequestError {
|
|
71
|
-
const uploadError = error instanceof Error ? error : new Error("
|
|
76
|
+
const uploadError = error instanceof Error ? error : new Error(t("core.upload.file_failed"));
|
|
72
77
|
return Object.assign(uploadError, {
|
|
73
78
|
status: 500,
|
|
74
79
|
method: "POST",
|
|
@@ -88,16 +93,16 @@ const beforeUpload: UploadProps["beforeUpload"] = rawFile => {
|
|
|
88
93
|
|
|
89
94
|
if (!fileTypeValid) {
|
|
90
95
|
ElNotification({
|
|
91
|
-
title: "
|
|
92
|
-
message: "
|
|
96
|
+
title: t("common.title.warning"),
|
|
97
|
+
message: t("core.upload.file_format_invalid"),
|
|
93
98
|
type: "warning"
|
|
94
99
|
});
|
|
95
100
|
}
|
|
96
101
|
|
|
97
102
|
if (!fileSizeValid) {
|
|
98
103
|
ElNotification({
|
|
99
|
-
title: "
|
|
100
|
-
message:
|
|
104
|
+
title: t("common.title.warning"),
|
|
105
|
+
message: t("core.upload.file_size_exceeded", { size: props.fileSize }),
|
|
101
106
|
type: "warning"
|
|
102
107
|
});
|
|
103
108
|
}
|
|
@@ -125,8 +130,8 @@ const uploadSuccess = (response: FileInfo | undefined) => {
|
|
|
125
130
|
});
|
|
126
131
|
formItemContext?.prop && formContext?.validateField([formItemContext.prop as string]);
|
|
127
132
|
ElNotification({
|
|
128
|
-
title: "
|
|
129
|
-
message: "
|
|
133
|
+
title: t("common.title.notice"),
|
|
134
|
+
message: t("core.upload.file_success"),
|
|
130
135
|
type: "success"
|
|
131
136
|
});
|
|
132
137
|
};
|
|
@@ -134,8 +139,8 @@ const uploadSuccess = (response: FileInfo | undefined) => {
|
|
|
134
139
|
/** 处理文件上传失败提示。 */
|
|
135
140
|
const uploadError = () => {
|
|
136
141
|
ElNotification({
|
|
137
|
-
title: "
|
|
138
|
-
message: "
|
|
142
|
+
title: t("common.title.warning"),
|
|
143
|
+
message: t("core.upload.file_failed"),
|
|
139
144
|
type: "error"
|
|
140
145
|
});
|
|
141
146
|
};
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
:on-exceed="handleExceed"
|
|
15
15
|
:accept="fileType.join(',')"
|
|
16
16
|
>
|
|
17
|
-
<el-button type="primary" :disabled="selfDisabled"
|
|
17
|
+
<el-button type="primary" :disabled="selfDisabled">{{ t("core.upload.action") }}</el-button>
|
|
18
18
|
</el-upload>
|
|
19
19
|
|
|
20
20
|
<div v-if="_fileList.length" class="file-list">
|
|
@@ -22,13 +22,17 @@
|
|
|
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 || "
|
|
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>
|
|
29
29
|
<div class="file-card__action">
|
|
30
|
-
<el-button link type="primary" :icon="Download" @click.stop="handleDownload(file)"
|
|
31
|
-
|
|
30
|
+
<el-button link type="primary" :icon="Download" @click.stop="handleDownload(file)">
|
|
31
|
+
{{ t("common.action.download") }}
|
|
32
|
+
</el-button>
|
|
33
|
+
<el-button v-if="!selfDisabled" link type="danger" :icon="Delete" @click.stop="handleRemove(file)">
|
|
34
|
+
{{ t("common.action.delete") }}
|
|
35
|
+
</el-button>
|
|
32
36
|
</div>
|
|
33
37
|
</div>
|
|
34
38
|
</div>
|
|
@@ -42,6 +46,9 @@ import { ElNotification, formContextKey, formItemContextKey } from "element-plus
|
|
|
42
46
|
import type { UploadProps, UploadRequestOptions, UploadUserFile } from "element-plus";
|
|
43
47
|
import { defFileService } from "../../api/base/file";
|
|
44
48
|
import type { FileInfo } from "../../rpc/base/v1/file";
|
|
49
|
+
import { useLocaleStore } from "../../locales";
|
|
50
|
+
|
|
51
|
+
const { t } = useLocaleStore();
|
|
45
52
|
|
|
46
53
|
/** 多文件上传组件属性。 */
|
|
47
54
|
interface UploadFilesProps {
|
|
@@ -75,7 +82,7 @@ type UploadRequestError = Parameters<NonNullable<UploadRequestOptions["onError"]
|
|
|
75
82
|
|
|
76
83
|
/** 兼容 Element Plus 上传组件要求的错误对象结构。 */
|
|
77
84
|
function buildUploadError(error: unknown): UploadRequestError {
|
|
78
|
-
const uploadError = error instanceof Error ? error : new Error("
|
|
85
|
+
const uploadError = error instanceof Error ? error : new Error(t("core.upload.file_failed"));
|
|
79
86
|
return Object.assign(uploadError, {
|
|
80
87
|
status: 500,
|
|
81
88
|
method: "POST",
|
|
@@ -102,16 +109,16 @@ const beforeUpload: UploadProps["beforeUpload"] = rawFile => {
|
|
|
102
109
|
|
|
103
110
|
if (!fileTypeValid) {
|
|
104
111
|
ElNotification({
|
|
105
|
-
title: "
|
|
106
|
-
message: "
|
|
112
|
+
title: t("common.title.warning"),
|
|
113
|
+
message: t("core.upload.file_format_invalid"),
|
|
107
114
|
type: "warning"
|
|
108
115
|
});
|
|
109
116
|
}
|
|
110
117
|
|
|
111
118
|
if (!fileSizeValid) {
|
|
112
119
|
ElNotification({
|
|
113
|
-
title: "
|
|
114
|
-
message:
|
|
120
|
+
title: t("common.title.warning"),
|
|
121
|
+
message: t("core.upload.file_size_exceeded", { size: props.fileSize }),
|
|
115
122
|
type: "warning"
|
|
116
123
|
});
|
|
117
124
|
}
|
|
@@ -143,8 +150,8 @@ const uploadSuccess = (response: FileInfo | undefined) => {
|
|
|
143
150
|
emit("update:fileList", _fileList.value);
|
|
144
151
|
formItemContext?.prop && formContext?.validateField([formItemContext.prop as string]);
|
|
145
152
|
ElNotification({
|
|
146
|
-
title: "
|
|
147
|
-
message: "
|
|
153
|
+
title: t("common.title.notice"),
|
|
154
|
+
message: t("core.upload.file_success"),
|
|
148
155
|
type: "success"
|
|
149
156
|
});
|
|
150
157
|
};
|
|
@@ -152,8 +159,8 @@ const uploadSuccess = (response: FileInfo | undefined) => {
|
|
|
152
159
|
/** 处理文件上传失败提示。 */
|
|
153
160
|
const uploadError = () => {
|
|
154
161
|
ElNotification({
|
|
155
|
-
title: "
|
|
156
|
-
message: "
|
|
162
|
+
title: t("common.title.warning"),
|
|
163
|
+
message: t("core.upload.file_failed"),
|
|
157
164
|
type: "error"
|
|
158
165
|
});
|
|
159
166
|
};
|
|
@@ -161,8 +168,8 @@ const uploadError = () => {
|
|
|
161
168
|
/** 超出上传数量限制时给出提示。 */
|
|
162
169
|
function handleExceed() {
|
|
163
170
|
ElNotification({
|
|
164
|
-
title: "
|
|
165
|
-
message:
|
|
171
|
+
title: t("common.title.warning"),
|
|
172
|
+
message: t("core.upload.limit_exceeded", { limit: props.limit }),
|
|
166
173
|
type: "warning"
|
|
167
174
|
});
|
|
168
175
|
}
|
|
@@ -19,15 +19,15 @@
|
|
|
19
19
|
<div class="upload-handle" @click.stop>
|
|
20
20
|
<div v-if="!self_disabled" class="handle-icon" @click="editImg">
|
|
21
21
|
<el-icon><Edit /></el-icon>
|
|
22
|
-
<span
|
|
22
|
+
<span>{{ t("common.action.edit") }}</span>
|
|
23
23
|
</div>
|
|
24
24
|
<div class="handle-icon" @click="imgViewVisible = true">
|
|
25
25
|
<el-icon><ZoomIn /></el-icon>
|
|
26
|
-
<span
|
|
26
|
+
<span>{{ t("common.action.view") }}</span>
|
|
27
27
|
</div>
|
|
28
28
|
<div v-if="!self_disabled" class="handle-icon" @click="deleteImg">
|
|
29
29
|
<el-icon><Delete /></el-icon>
|
|
30
|
-
<span
|
|
30
|
+
<span>{{ t("common.action.delete") }}</span>
|
|
31
31
|
</div>
|
|
32
32
|
</div>
|
|
33
33
|
</template>
|
|
@@ -54,6 +54,9 @@ import { defFileService } from "../../api/base/file";
|
|
|
54
54
|
import { ElNotification, formContextKey, formItemContextKey } from "element-plus";
|
|
55
55
|
import type { UploadProps, UploadRequestOptions } from "element-plus";
|
|
56
56
|
import type { FileInfo } from "../../rpc/base/v1/file";
|
|
57
|
+
import { useLocaleStore } from "../../locales";
|
|
58
|
+
|
|
59
|
+
const { t } = useLocaleStore();
|
|
57
60
|
|
|
58
61
|
/** 单图上传组件属性。 */
|
|
59
62
|
interface UploadFileProps {
|
|
@@ -141,15 +144,15 @@ const beforeUpload: UploadProps["beforeUpload"] = rawFile => {
|
|
|
141
144
|
const imgType = props.fileType.includes(rawFile.type as File.ImageMimeType);
|
|
142
145
|
if (!imgType)
|
|
143
146
|
ElNotification({
|
|
144
|
-
title: "
|
|
145
|
-
message: "
|
|
147
|
+
title: t("common.title.warning"),
|
|
148
|
+
message: t("core.upload.image_format_invalid"),
|
|
146
149
|
type: "warning"
|
|
147
150
|
});
|
|
148
151
|
if (!imgSize)
|
|
149
152
|
setTimeout(() => {
|
|
150
153
|
ElNotification({
|
|
151
|
-
title: "
|
|
152
|
-
message:
|
|
154
|
+
title: t("common.title.warning"),
|
|
155
|
+
message: t("core.upload.image_size_exceeded", { size: props.fileSize }),
|
|
153
156
|
type: "warning"
|
|
154
157
|
});
|
|
155
158
|
}, 0);
|
|
@@ -161,8 +164,8 @@ const beforeUpload: UploadProps["beforeUpload"] = rawFile => {
|
|
|
161
164
|
* */
|
|
162
165
|
const uploadSuccess = () => {
|
|
163
166
|
ElNotification({
|
|
164
|
-
title: "
|
|
165
|
-
message: "
|
|
167
|
+
title: t("common.title.notice"),
|
|
168
|
+
message: t("core.upload.image_success"),
|
|
166
169
|
type: "success"
|
|
167
170
|
});
|
|
168
171
|
};
|
|
@@ -172,8 +175,8 @@ const uploadSuccess = () => {
|
|
|
172
175
|
* */
|
|
173
176
|
const uploadError = () => {
|
|
174
177
|
ElNotification({
|
|
175
|
-
title: "
|
|
176
|
-
message: "
|
|
178
|
+
title: t("common.title.warning"),
|
|
179
|
+
message: t("core.upload.image_failed"),
|
|
177
180
|
type: "error"
|
|
178
181
|
});
|
|
179
182
|
};
|
|
@@ -27,11 +27,11 @@
|
|
|
27
27
|
<div class="upload-handle" @click.stop>
|
|
28
28
|
<div class="handle-icon" @click="handlePictureCardPreview(file)">
|
|
29
29
|
<el-icon><ZoomIn /></el-icon>
|
|
30
|
-
<span
|
|
30
|
+
<span>{{ t("common.action.view") }}</span>
|
|
31
31
|
</div>
|
|
32
32
|
<div v-if="!self_disabled" class="handle-icon" @click="handleRemove(file)">
|
|
33
33
|
<el-icon><Delete /></el-icon>
|
|
34
|
-
<span
|
|
34
|
+
<span>{{ t("common.action.delete") }}</span>
|
|
35
35
|
</div>
|
|
36
36
|
</div>
|
|
37
37
|
</template>
|
|
@@ -50,6 +50,9 @@ import { defFileService } from "../../api/base/file";
|
|
|
50
50
|
import type { UploadProps, UploadFile, UploadUserFile, UploadRequestOptions } from "element-plus";
|
|
51
51
|
import { ElNotification, formContextKey, formItemContextKey } from "element-plus";
|
|
52
52
|
import type { FileInfo } from "../../rpc/base/v1/file";
|
|
53
|
+
import { useLocaleStore } from "../../locales";
|
|
54
|
+
|
|
55
|
+
const { t } = useLocaleStore();
|
|
53
56
|
|
|
54
57
|
/** 多图上传组件属性。 */
|
|
55
58
|
interface UploadFileProps {
|
|
@@ -107,15 +110,15 @@ const beforeUpload: UploadProps["beforeUpload"] = rawFile => {
|
|
|
107
110
|
const imgType = props.fileType.includes(rawFile.type as File.ImageMimeType);
|
|
108
111
|
if (!imgType)
|
|
109
112
|
ElNotification({
|
|
110
|
-
title: "
|
|
111
|
-
message: "
|
|
113
|
+
title: t("common.title.warning"),
|
|
114
|
+
message: t("core.upload.image_format_invalid"),
|
|
112
115
|
type: "warning"
|
|
113
116
|
});
|
|
114
117
|
if (!imgSize)
|
|
115
118
|
setTimeout(() => {
|
|
116
119
|
ElNotification({
|
|
117
|
-
title: "
|
|
118
|
-
message:
|
|
120
|
+
title: t("common.title.warning"),
|
|
121
|
+
message: t("core.upload.image_size_exceeded", { size: props.fileSize }),
|
|
119
122
|
type: "warning"
|
|
120
123
|
});
|
|
121
124
|
}, 0);
|
|
@@ -153,8 +156,8 @@ const uploadSuccess = (response: FileInfo | undefined, uploadFile: UploadFile) =
|
|
|
153
156
|
// 调用 el-form 内部的校验方法(可自动校验)
|
|
154
157
|
formItemContext?.prop && formContext?.validateField([formItemContext.prop as string]);
|
|
155
158
|
ElNotification({
|
|
156
|
-
title: "
|
|
157
|
-
message: "
|
|
159
|
+
title: t("common.title.notice"),
|
|
160
|
+
message: t("core.upload.image_success"),
|
|
158
161
|
type: "success"
|
|
159
162
|
});
|
|
160
163
|
};
|
|
@@ -173,8 +176,8 @@ const handleRemove = (file: UploadFile) => {
|
|
|
173
176
|
* */
|
|
174
177
|
const uploadError = () => {
|
|
175
178
|
ElNotification({
|
|
176
|
-
title: "
|
|
177
|
-
message: "
|
|
179
|
+
title: t("common.title.warning"),
|
|
180
|
+
message: t("core.upload.image_failed"),
|
|
178
181
|
type: "error"
|
|
179
182
|
});
|
|
180
183
|
};
|
|
@@ -184,8 +187,8 @@ const uploadError = () => {
|
|
|
184
187
|
* */
|
|
185
188
|
const handleExceed = () => {
|
|
186
189
|
ElNotification({
|
|
187
|
-
title: "
|
|
188
|
-
message:
|
|
190
|
+
title: t("common.title.warning"),
|
|
191
|
+
message: t("core.upload.image_limit_exceeded", { limit: props.limit }),
|
|
189
192
|
type: "warning"
|
|
190
193
|
});
|
|
191
194
|
};
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
class="editor-content"
|
|
7
7
|
:style="{ height }"
|
|
8
8
|
:mode="mode"
|
|
9
|
-
:default-config="
|
|
9
|
+
:default-config="resolvedEditorConfig"
|
|
10
10
|
@on-created="handleCreated"
|
|
11
11
|
@on-blur="handleBlur"
|
|
12
12
|
/>
|
|
@@ -20,6 +20,9 @@ import { Editor, Toolbar } from "@wangeditor/editor-for-vue";
|
|
|
20
20
|
import { defFileService } from "../../api/base/file";
|
|
21
21
|
import "@wangeditor/editor/dist/css/style.css";
|
|
22
22
|
import { formContextKey, formItemContextKey } from "element-plus";
|
|
23
|
+
import { useLocaleStore } from "../../locales";
|
|
24
|
+
|
|
25
|
+
const { t } = useLocaleStore();
|
|
23
26
|
|
|
24
27
|
// 富文本 DOM 元素
|
|
25
28
|
const editorRef = shallowRef();
|
|
@@ -47,7 +50,6 @@ const props = withDefaults(defineProps<RichEditorProps>(), {
|
|
|
47
50
|
},
|
|
48
51
|
editorConfig: () => {
|
|
49
52
|
return {
|
|
50
|
-
placeholder: "请输入内容...",
|
|
51
53
|
MENU_CONF: {}
|
|
52
54
|
};
|
|
53
55
|
},
|
|
@@ -56,6 +58,12 @@ const props = withDefaults(defineProps<RichEditorProps>(), {
|
|
|
56
58
|
hideToolBar: false,
|
|
57
59
|
disabled: false
|
|
58
60
|
});
|
|
61
|
+
const editorMenuConfig = props.editorConfig.MENU_CONF ?? {};
|
|
62
|
+
const resolvedEditorConfig = computed(() => ({
|
|
63
|
+
...props.editorConfig,
|
|
64
|
+
placeholder: props.editorConfig.placeholder || t("common.placeholder.input_content"),
|
|
65
|
+
MENU_CONF: editorMenuConfig
|
|
66
|
+
}));
|
|
59
67
|
|
|
60
68
|
// 获取 el-form 组件上下文
|
|
61
69
|
const formContext = inject(formContextKey, void 0);
|
|
@@ -91,7 +99,7 @@ const valueHtml = computed({
|
|
|
91
99
|
* @param insertFn 上传成功后的回调函数(插入到富文本编辑器中)
|
|
92
100
|
* */
|
|
93
101
|
type InsertFnTypeImg = (url: string, alt?: string, href?: string) => void;
|
|
94
|
-
|
|
102
|
+
editorMenuConfig["uploadImage"] = {
|
|
95
103
|
async customUpload(file: File, insertFn: InsertFnTypeImg) {
|
|
96
104
|
if (!uploadImgValidate(file)) return;
|
|
97
105
|
try {
|
|
@@ -115,7 +123,7 @@ const uploadImgValidate = (file: File): boolean => {
|
|
|
115
123
|
* @param insertFn 上传成功后的回调函数(插入到富文本编辑器中)
|
|
116
124
|
* */
|
|
117
125
|
type InsertFnTypeVideo = (url: string, poster?: string) => void;
|
|
118
|
-
|
|
126
|
+
editorMenuConfig["uploadVideo"] = {
|
|
119
127
|
async customUpload(file: File, insertFn: InsertFnTypeVideo) {
|
|
120
128
|
if (!uploadVideoValidate(file)) return;
|
|
121
129
|
try {
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import type { Directive, DirectiveBinding } from "vue";
|
|
8
8
|
import { ElMessage } from "element-plus";
|
|
9
|
+
import { t } from "../../locales";
|
|
9
10
|
/** 复制指令绑定后挂载复制内容的元素类型。 */
|
|
10
11
|
interface ElType extends HTMLElement {
|
|
11
12
|
copyData: string | number;
|
|
@@ -29,7 +30,7 @@ async function handleClick(this: any) {
|
|
|
29
30
|
await navigator.clipboard.writeText(this.copyData);
|
|
30
31
|
ElMessage({
|
|
31
32
|
type: "success",
|
|
32
|
-
message: "
|
|
33
|
+
message: t("core.clipboard.success")
|
|
33
34
|
});
|
|
34
35
|
} catch (err) {
|
|
35
36
|
console.error("复制操作不被支持或失败: ", err);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ElNotification } from "element-plus";
|
|
2
|
+
import { t } from "../locales";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* @description 接收数据流生成 blob,创建链接,下载文件
|
|
@@ -17,8 +18,8 @@ export const useDownload = async (
|
|
|
17
18
|
) => {
|
|
18
19
|
if (isNotify) {
|
|
19
20
|
ElNotification({
|
|
20
|
-
title: "
|
|
21
|
-
message: "
|
|
21
|
+
title: t("common.title.notice"),
|
|
22
|
+
message: t("core.download.large_file_notice"),
|
|
22
23
|
type: "info",
|
|
23
24
|
duration: 3000
|
|
24
25
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ElMessageBox, ElMessage } from "element-plus";
|
|
2
2
|
import { HandleData } from "./interface";
|
|
3
|
+
import { t } from "../locales";
|
|
3
4
|
|
|
4
5
|
/**
|
|
5
6
|
* @description 操作单条数据信息 (二次确认【删除、禁用、启用、重置密码】)
|
|
@@ -16,9 +17,9 @@ export const useHandleData = (
|
|
|
16
17
|
confirmType: HandleData.MessageType = "warning"
|
|
17
18
|
) => {
|
|
18
19
|
return new Promise((resolve, reject) => {
|
|
19
|
-
ElMessageBox.confirm(
|
|
20
|
-
confirmButtonText: "
|
|
21
|
-
cancelButtonText: "
|
|
20
|
+
ElMessageBox.confirm(t("core.data.confirm_action", { action: message }), t("common.title.warning"), {
|
|
21
|
+
confirmButtonText: t("common.action.confirm"),
|
|
22
|
+
cancelButtonText: t("common.action.cancel"),
|
|
22
23
|
type: confirmType,
|
|
23
24
|
draggable: true
|
|
24
25
|
})
|
|
@@ -27,7 +28,7 @@ export const useHandleData = (
|
|
|
27
28
|
if (!res) return reject(false);
|
|
28
29
|
ElMessage({
|
|
29
30
|
type: "success",
|
|
30
|
-
message:
|
|
31
|
+
message: t("core.data.operation_success", { action: message })
|
|
31
32
|
});
|
|
32
33
|
resolve(true);
|
|
33
34
|
})
|
|
@@ -7,6 +7,7 @@ import { getLightColor, getDarkColor } from "../utils/color";
|
|
|
7
7
|
import { menuTheme } from "../styles/theme/menu";
|
|
8
8
|
import { asideTheme } from "../styles/theme/aside";
|
|
9
9
|
import { headerTheme } from "../styles/theme/header";
|
|
10
|
+
import { t } from "../locales";
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* @description 全局主题 hooks
|
|
@@ -29,7 +30,7 @@ export const useTheme = () => {
|
|
|
29
30
|
const changePrimary = (val: string | null) => {
|
|
30
31
|
if (!val) {
|
|
31
32
|
val = DEFAULT_PRIMARY;
|
|
32
|
-
ElMessage({ type: "success", message:
|
|
33
|
+
ElMessage({ type: "success", message: t("core.theme.primary_reset", { color: DEFAULT_PRIMARY }) });
|
|
33
34
|
}
|
|
34
35
|
// 计算主题颜色变化
|
|
35
36
|
document.documentElement.style.setProperty("--el-color-primary", val);
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ref } from "vue";
|
|
2
|
+
import { getCurrentLocale } from "../locales";
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* @description 获取本地时间
|
|
@@ -18,7 +19,7 @@ export const useTime = () => {
|
|
|
18
19
|
const date = new Date();
|
|
19
20
|
year.value = date.getFullYear();
|
|
20
21
|
month.value = date.getMonth() + 1;
|
|
21
|
-
week.value = "
|
|
22
|
+
week.value = new Intl.DateTimeFormat(getCurrentLocale(), { weekday: "short" }).format(date);
|
|
22
23
|
day.value = date.getDate();
|
|
23
24
|
hour.value =
|
|
24
25
|
(date.getHours() + "")?.padStart(2, "0") ||
|
|
@@ -29,7 +30,15 @@ export const useTime = () => {
|
|
|
29
30
|
second.value =
|
|
30
31
|
(date.getSeconds() + "")?.padStart(2, "0") ||
|
|
31
32
|
new Intl.NumberFormat(undefined, { minimumIntegerDigits: 2 }).format(date.getSeconds());
|
|
32
|
-
nowTime.value =
|
|
33
|
+
nowTime.value = new Intl.DateTimeFormat(getCurrentLocale(), {
|
|
34
|
+
year: "numeric",
|
|
35
|
+
month: "2-digit",
|
|
36
|
+
day: "2-digit",
|
|
37
|
+
hour: "2-digit",
|
|
38
|
+
minute: "2-digit",
|
|
39
|
+
second: "2-digit",
|
|
40
|
+
hour12: false
|
|
41
|
+
}).format(date);
|
|
33
42
|
};
|
|
34
43
|
|
|
35
44
|
updateTime();
|
|
@@ -5,5 +5,7 @@
|
|
|
5
5
|
/// <reference path="../types/generated/components.d.ts" />
|
|
6
6
|
|
|
7
7
|
export * from "./modules";
|
|
8
|
+
export * from "./locales";
|
|
9
|
+
export { defLanguageService } from "./api/base/language";
|
|
8
10
|
export { kratosAdminModule } from "./modules/kratosAdmin";
|
|
9
11
|
export { bootstrapAdminApp } from "./bootstrap";
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
<div class="tool-bar-ri">
|
|
3
3
|
<div class="header-icon">
|
|
4
4
|
<component :is="tool.component" v-for="tool in headerTools" :id="tool.name" :key="tool.name" />
|
|
5
|
+
<LocaleSwitch id="localeSwitch" />
|
|
5
6
|
<AssemblySize id="assemblySize" />
|
|
6
7
|
<SearchMenu id="searchMenu" />
|
|
7
8
|
<ThemeSetting id="themeSetting" />
|
|
@@ -18,6 +19,7 @@ import SearchMenu from "./components/SearchMenu.vue";
|
|
|
18
19
|
import ThemeSetting from "./components/ThemeSetting.vue";
|
|
19
20
|
import Fullscreen from "./components/Fullscreen.vue";
|
|
20
21
|
import Avatar from "./components/Avatar.vue";
|
|
22
|
+
import LocaleSwitch from "../../../components/LocaleSwitch/index.vue";
|
|
21
23
|
|
|
22
24
|
const headerTools = getAdminHeaderTools();
|
|
23
25
|
</script>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<el-tooltip effect="dark" content="
|
|
2
|
+
<el-tooltip effect="dark" :content="t('core.header.size_select')" placement="bottom" :show-after="200">
|
|
3
3
|
<el-dropdown trigger="click" @command="setAssemblySize">
|
|
4
4
|
<i :class="'iconfont icon-contentright'" class="toolBar-icon"></i>
|
|
5
5
|
<template #dropdown>
|
|
@@ -22,15 +22,17 @@
|
|
|
22
22
|
import { computed } from "vue";
|
|
23
23
|
import { useGlobalStore } from "../../../../stores/modules/global";
|
|
24
24
|
import { AssemblySizeType } from "../../../../stores/interface";
|
|
25
|
+
import { useLocaleStore } from "../../../../locales";
|
|
25
26
|
|
|
26
27
|
const globalStore = useGlobalStore();
|
|
27
28
|
const assemblySize = computed(() => globalStore.assemblySize);
|
|
29
|
+
const { t } = useLocaleStore();
|
|
28
30
|
|
|
29
|
-
const assemblySizeList = [
|
|
30
|
-
{ label: "
|
|
31
|
-
{ label: "
|
|
32
|
-
{ label: "
|
|
33
|
-
];
|
|
31
|
+
const assemblySizeList = computed(() => [
|
|
32
|
+
{ label: t("core.header.size.default"), value: "default" },
|
|
33
|
+
{ label: t("core.header.size.large"), value: "large" },
|
|
34
|
+
{ label: t("core.header.size.small"), value: "small" }
|
|
35
|
+
]);
|
|
34
36
|
|
|
35
37
|
const setAssemblySize = (item: AssemblySizeType) => {
|
|
36
38
|
if (assemblySize.value === item) return;
|
|
@@ -23,11 +23,11 @@
|
|
|
23
23
|
@click.stop="handleUserMenuAction(action.path)"
|
|
24
24
|
>
|
|
25
25
|
<el-icon v-if="action.icon"><component :is="action.icon" /></el-icon>
|
|
26
|
-
<span>{{ action.label }}</span>
|
|
26
|
+
<span>{{ action.labelKey ? t(action.labelKey) : action.label }}</span>
|
|
27
27
|
</button>
|
|
28
28
|
<button class="action-btn action-btn--danger" type="button" @click="logout">
|
|
29
29
|
<el-icon><SwitchButton /></el-icon>
|
|
30
|
-
<span
|
|
30
|
+
<span>{{ t("common.action.logout") }}</span>
|
|
31
31
|
</button>
|
|
32
32
|
</div>
|
|
33
33
|
</div>
|
|
@@ -46,16 +46,18 @@ import type { DropdownInstance } from "element-plus";
|
|
|
46
46
|
import defaultAvatar from "../../../../assets/images/avatar.png";
|
|
47
47
|
import { navigateTo } from "../../../../utils/router";
|
|
48
48
|
import { getAdminUserMenuActions } from "../../../../modules";
|
|
49
|
+
import { useLocaleStore } from "../../../../locales";
|
|
49
50
|
|
|
50
51
|
const router = useRouter();
|
|
51
52
|
const userStore = useUserStore();
|
|
52
53
|
const authStore = useAuthStore();
|
|
53
54
|
const userMenuActions = getAdminUserMenuActions();
|
|
54
55
|
const dropdownRef = ref<DropdownInstance>();
|
|
56
|
+
const { t } = useLocaleStore();
|
|
55
57
|
const avatarSrc = ref(defaultAvatar);
|
|
56
|
-
const displayName = computed(() => userStore.userInfo.nick_name || userStore.userInfo.user_name || "
|
|
57
|
-
const roleName = computed(() => userStore.userInfo.role_name || "
|
|
58
|
-
const deptName = computed(() => userStore.userInfo.dept_name || "
|
|
58
|
+
const displayName = computed(() => userStore.userInfo.nick_name || userStore.userInfo.user_name || t("core.layout.not_set"));
|
|
59
|
+
const roleName = computed(() => userStore.userInfo.role_name || t("core.layout.role_unassigned"));
|
|
60
|
+
const deptName = computed(() => userStore.userInfo.dept_name || t("core.layout.department_unassigned"));
|
|
59
61
|
const profileSummary = computed(() => `${roleName.value} / ${deptName.value}`);
|
|
60
62
|
const availableUserMenuActions = computed(() => {
|
|
61
63
|
return userMenuActions.flatMap(action => {
|
|
@@ -84,9 +86,9 @@ watch(
|
|
|
84
86
|
|
|
85
87
|
/** 退出登录并清理当前登录态。 */
|
|
86
88
|
const logout = () => {
|
|
87
|
-
ElMessageBox.confirm("
|
|
88
|
-
confirmButtonText: "
|
|
89
|
-
cancelButtonText: "
|
|
89
|
+
ElMessageBox.confirm(t("core.layout.logout_confirm"), t("common.title.warning"), {
|
|
90
|
+
confirmButtonText: t("common.action.confirm"),
|
|
91
|
+
cancelButtonText: t("common.action.cancel"),
|
|
90
92
|
type: "warning"
|
|
91
93
|
}).then(async () => {
|
|
92
94
|
// 1.执行退出登录接口并清理本地状态
|
|
@@ -94,7 +96,7 @@ const logout = () => {
|
|
|
94
96
|
|
|
95
97
|
// 2.重定向到登录页
|
|
96
98
|
router.replace(LOGIN_URL);
|
|
97
|
-
ElMessage.success("
|
|
99
|
+
ElMessage.success(t("core.layout.logout_success"));
|
|
98
100
|
});
|
|
99
101
|
};
|
|
100
102
|
|
|
@@ -27,20 +27,28 @@ import { ArrowRight } from "@element-plus/icons-vue";
|
|
|
27
27
|
import { useAuthStore } from "../../../../stores/modules/auth";
|
|
28
28
|
import { useGlobalStore } from "../../../../stores/modules/global";
|
|
29
29
|
import type { RouteItem } from "../../../../rpc/system/admin/v1/auth";
|
|
30
|
-
import { BaseMenuType } from "../../../../rpc/system/
|
|
30
|
+
import { BaseMenuType } from "../../../../rpc/system/admin/v1/common";
|
|
31
31
|
import { getRouteMetaIcon, getRouteMetaTitle, getRouteTarget, isExternalPath } from "../../../../utils";
|
|
32
|
+
import { useLocaleStore } from "../../../../locales";
|
|
32
33
|
|
|
33
34
|
const route = useRoute();
|
|
34
35
|
const router = useRouter();
|
|
35
36
|
const authStore = useAuthStore();
|
|
36
37
|
const globalStore = useGlobalStore();
|
|
38
|
+
const { t } = useLocaleStore();
|
|
37
39
|
|
|
38
40
|
const breadcrumbList = computed(() => {
|
|
39
41
|
let breadcrumbData = authStore.breadcrumbListGet[route.matched[route.matched.length - 1].path] ?? [];
|
|
40
42
|
// 🙅♀️不需要首页面包屑可删除以下判断
|
|
41
|
-
if (breadcrumbData[0]?.path !== HOME_URL
|
|
43
|
+
if (breadcrumbData[0]?.path !== HOME_URL) {
|
|
42
44
|
breadcrumbData = [
|
|
43
|
-
{
|
|
45
|
+
{
|
|
46
|
+
path: HOME_URL,
|
|
47
|
+
name: "home",
|
|
48
|
+
type: BaseMenuType.BASE_MENU_TYPE_MENU,
|
|
49
|
+
meta: { icon: "HomeFilled", title: t("core.layout.home"), params: [] },
|
|
50
|
+
children: []
|
|
51
|
+
},
|
|
44
52
|
...breadcrumbData
|
|
45
53
|
];
|
|
46
54
|
}
|