@liujitcn/kratos-admin-core 0.0.19 → 0.0.21
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/LocaleSwitch/index.vue.d.ts +3 -0
- package/dist/package/declarations/src/index.d.ts +2 -0
- package/dist/package/declarations/src/locales/index.d.ts +63 -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 +2 -0
- package/dist/package/declarations/src/rpc/base/v1/language.d.ts +26 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_dict.d.ts +79 -0
- package/dist/package/declarations/src/rpc/system/admin/v1/base_translation.d.ts +102 -0
- package/dist/package/declarations/src/stores/interface/index.d.ts +2 -0
- 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/passwordStrength.d.ts +0 -7
- package/dist/package/src/App.vue +10 -1
- 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 +9 -4
- package/dist/package/src/components/Dialog/ProDialog.vue +10 -4
- package/dist/package/src/components/Dict/index.vue +5 -2
- 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/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 +10 -2
- 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/Tabs/components/MoreButton.vue +9 -7
- 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 +258 -0
- package/dist/package/src/locales/es-ES.json +258 -0
- package/dist/package/src/locales/fr-FR.json +258 -0
- package/dist/package/src/locales/index.ts +223 -0
- package/dist/package/src/locales/ja-JP.json +258 -0
- package/dist/package/src/locales/ko-KR.json +258 -0
- package/dist/package/src/locales/zh-CN.json +258 -0
- package/dist/package/src/locales/zh-TW.json +258 -0
- package/dist/package/src/modules/index.ts +7 -2
- package/dist/package/src/modules/kratosAdmin.ts +19 -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 +3 -2
- package/dist/package/src/routers/modules/staticRouter.ts +8 -4
- package/dist/package/src/rpc/base/v1/config.ts +2 -0
- package/dist/package/src/rpc/base/v1/language.ts +37 -0
- package/dist/package/src/rpc/system/admin/v1/base_dict.ts +81 -0
- package/dist/package/src/rpc/system/admin/v1/base_translation.ts +117 -0
- package/dist/package/src/stores/interface/index.ts +2 -0
- package/dist/package/src/stores/modules/config.ts +5 -1
- package/dist/package/src/stores/modules/user.ts +2 -1
- package/dist/package/src/stores/runtime.ts +1 -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 +7 -6
- package/dist/package/src/utils/oauthProvider.ts +15 -10
- package/dist/package/src/utils/passwordCrypto.ts +3 -2
- 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 +53 -27
- 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 +3 -1
- package/types/generated/auto-imports.d.ts +129 -111
- package/types/generated/components.d.ts +67 -67
- package/vite.config.ts +8 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="password-strength">
|
|
3
3
|
<div class="password-strength__header">
|
|
4
|
-
<span
|
|
4
|
+
<span>{{ t("core.password.strength") }}</span>
|
|
5
5
|
<strong :class="`password-strength__label password-strength__label--${strength.level}`">
|
|
6
|
-
{{ strength.
|
|
6
|
+
{{ t(`core.password.strength.${strength.level}`) }}
|
|
7
7
|
</strong>
|
|
8
8
|
</div>
|
|
9
9
|
<div class="password-strength__bars">
|
|
@@ -17,13 +17,16 @@
|
|
|
17
17
|
}"
|
|
18
18
|
/>
|
|
19
19
|
</div>
|
|
20
|
-
<p class="password-strength__tip">{{ tip }}</p>
|
|
20
|
+
<p class="password-strength__tip">{{ tip || t("core.password.tip") }}</p>
|
|
21
21
|
</div>
|
|
22
22
|
</template>
|
|
23
23
|
|
|
24
24
|
<script setup lang="ts">
|
|
25
25
|
import { computed } from "vue";
|
|
26
|
-
import { getPasswordStrength
|
|
26
|
+
import { getPasswordStrength } from "../../utils/passwordStrength";
|
|
27
|
+
import { useLocaleStore } from "../../locales";
|
|
28
|
+
|
|
29
|
+
const { t } = useLocaleStore();
|
|
27
30
|
|
|
28
31
|
/** 密码强度组件属性。 */
|
|
29
32
|
interface PasswordStrengthProps {
|
|
@@ -35,7 +38,7 @@ interface PasswordStrengthProps {
|
|
|
35
38
|
|
|
36
39
|
const props = withDefaults(defineProps<PasswordStrengthProps>(), {
|
|
37
40
|
password: "",
|
|
38
|
-
tip:
|
|
41
|
+
tip: ""
|
|
39
42
|
});
|
|
40
43
|
|
|
41
44
|
/** 强度条固定为三段,保持所有页面一致。 */
|
|
@@ -1,16 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="dynamic-list">
|
|
3
3
|
<div v-for="(item, index) in modelValue" :key="index" class="dynamic-list__item">
|
|
4
|
-
<el-input v-model="modelValue[index]" v-bind="
|
|
4
|
+
<el-input v-model="modelValue[index]" v-bind="resolvedInputProps" />
|
|
5
5
|
<el-button :icon="Delete" circle type="danger" plain @click="handleRemove(index)" />
|
|
6
6
|
</div>
|
|
7
|
-
<el-button :icon="Plus" type="primary" plain @click="handleAdd"
|
|
7
|
+
<el-button :icon="Plus" type="primary" plain @click="handleAdd">{{ t("common.action.create") }}</el-button>
|
|
8
8
|
</div>
|
|
9
9
|
</template>
|
|
10
10
|
|
|
11
11
|
<script setup lang="ts" name="DynamicList">
|
|
12
12
|
import { computed } from "vue";
|
|
13
13
|
import { Delete, Plus } from "@element-plus/icons-vue";
|
|
14
|
+
import { useLocaleStore } from "../../../locales";
|
|
15
|
+
|
|
16
|
+
const { t } = useLocaleStore();
|
|
14
17
|
|
|
15
18
|
/** 动态字符串列表组件属性。 */
|
|
16
19
|
interface DynamicListProps {
|
|
@@ -20,9 +23,11 @@ interface DynamicListProps {
|
|
|
20
23
|
|
|
21
24
|
const props = withDefaults(defineProps<DynamicListProps>(), {
|
|
22
25
|
modelValue: () => [],
|
|
23
|
-
inputProps: () => ({
|
|
26
|
+
inputProps: () => ({})
|
|
24
27
|
});
|
|
25
28
|
|
|
29
|
+
const resolvedInputProps = computed(() => ({ placeholder: t("common.placeholder.inputContent"), ...props.inputProps }));
|
|
30
|
+
|
|
26
31
|
const emit = defineEmits<{
|
|
27
32
|
"update:modelValue": [value: string[]];
|
|
28
33
|
}>();
|
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<div class="kv-list">
|
|
3
3
|
<div v-for="(item, index) in modelValue" :key="index" class="kv-list__item">
|
|
4
|
-
<el-input v-model="item.key" v-bind="
|
|
5
|
-
<el-input v-model="item.value" v-bind="
|
|
4
|
+
<el-input v-model="item.key" v-bind="resolvedKeyInputProps" />
|
|
5
|
+
<el-input v-model="item.value" v-bind="resolvedValueInputProps" />
|
|
6
6
|
<el-button :icon="Delete" circle type="danger" plain @click="handleRemove(index)" />
|
|
7
7
|
</div>
|
|
8
|
-
<el-button :icon="Plus" type="primary" plain v-bind="addButtonProps" @click="handleAdd">
|
|
8
|
+
<el-button :icon="Plus" type="primary" plain v-bind="addButtonProps" @click="handleAdd">
|
|
9
|
+
{{ addText || t("common.action.create") }}
|
|
10
|
+
</el-button>
|
|
9
11
|
</div>
|
|
10
12
|
</template>
|
|
11
13
|
|
|
12
14
|
<script setup lang="ts" name="KvList">
|
|
13
15
|
import { computed } from "vue";
|
|
14
16
|
import { Delete, Plus } from "@element-plus/icons-vue";
|
|
17
|
+
import { useLocaleStore } from "../../../locales";
|
|
18
|
+
|
|
19
|
+
const { t } = useLocaleStore();
|
|
15
20
|
|
|
16
21
|
/** 键值对列表单项。 */
|
|
17
22
|
interface KvItem {
|
|
@@ -30,12 +35,15 @@ interface KvListProps {
|
|
|
30
35
|
|
|
31
36
|
const props = withDefaults(defineProps<KvListProps>(), {
|
|
32
37
|
modelValue: () => [],
|
|
33
|
-
keyInputProps: () => ({
|
|
34
|
-
valueInputProps: () => ({
|
|
35
|
-
addText: "
|
|
38
|
+
keyInputProps: () => ({}),
|
|
39
|
+
valueInputProps: () => ({}),
|
|
40
|
+
addText: "",
|
|
36
41
|
addButtonProps: () => ({})
|
|
37
42
|
});
|
|
38
43
|
|
|
44
|
+
const resolvedKeyInputProps = computed(() => ({ placeholder: t("common.field.parameterName"), ...props.keyInputProps }));
|
|
45
|
+
const resolvedValueInputProps = computed(() => ({ placeholder: t("common.field.parameterValue"), ...props.valueInputProps }));
|
|
46
|
+
|
|
39
47
|
const emit = defineEmits<{
|
|
40
48
|
"update:modelValue": [value: KvItem[]];
|
|
41
49
|
}>();
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<!-- 列设置 -->
|
|
3
|
-
<el-drawer v-model="drawerVisible" title="
|
|
3
|
+
<el-drawer v-model="drawerVisible" :title="t('core.table.columnSetting')" 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="
|
|
7
|
-
<el-table-column v-slot="scope" prop="isShow" align="center" label="
|
|
6
|
+
<el-table-column prop="label" align="left" :label="t('core.table.columnName')" />
|
|
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>
|
|
10
|
-
<el-table-column v-slot="scope" prop="sortable" align="center" label="
|
|
10
|
+
<el-table-column v-slot="scope" prop="sortable" align="center" :label="t('core.table.sort')">
|
|
11
11
|
<el-switch v-model="scope.row.sortable"></el-switch>
|
|
12
12
|
</el-table-column>
|
|
13
13
|
<template #empty>
|
|
14
14
|
<div class="table-empty">
|
|
15
15
|
<img src="../../../assets/images/notData.png" alt="notData" />
|
|
16
|
-
<div
|
|
16
|
+
<div>{{ t("core.table.noConfigurableColumns") }}</div>
|
|
17
17
|
</div>
|
|
18
18
|
</template>
|
|
19
19
|
</el-table>
|
|
@@ -24,10 +24,12 @@
|
|
|
24
24
|
<script setup lang="ts" name="ColSetting">
|
|
25
25
|
import { ref } from "vue";
|
|
26
26
|
import { ColumnProps } from "../../../components/ProTable/interface";
|
|
27
|
+
import { useLocaleStore } from "../../../locales";
|
|
27
28
|
|
|
28
29
|
defineProps<{ colSetting: ColumnProps[] }>();
|
|
29
30
|
|
|
30
31
|
const drawerVisible = ref<boolean>(false);
|
|
32
|
+
const { t } = useLocaleStore();
|
|
31
33
|
|
|
32
34
|
const openColSetting = () => {
|
|
33
35
|
drawerVisible.value = true;
|
|
@@ -10,6 +10,7 @@ import { ColumnProps, HeaderRenderScope, RenderScope, TableActionProps } from ".
|
|
|
10
10
|
import type { TableAlign } from "../../../utils/proTable";
|
|
11
11
|
import { filterEnum, formatValue, handleProp, handleRowAccordingToProp } from "../../../utils";
|
|
12
12
|
import { formatPrice } from "../../../utils/utils";
|
|
13
|
+
import { t } from "../../../locales";
|
|
13
14
|
|
|
14
15
|
const props = defineProps<{
|
|
15
16
|
column: ColumnProps;
|
|
@@ -119,7 +120,7 @@ const renderImageCell = (item: ColumnProps, scope: RenderScope<any>) => {
|
|
|
119
120
|
}
|
|
120
121
|
},
|
|
121
122
|
{
|
|
122
|
-
error: () => h(ElText, { type: "info", size: "small" }, () => "
|
|
123
|
+
error: () => h(ElText, { type: "info", size: "small" }, () => t("common.message.noData"))
|
|
123
124
|
}
|
|
124
125
|
);
|
|
125
126
|
};
|
|
@@ -31,18 +31,22 @@
|
|
|
31
31
|
</div>
|
|
32
32
|
<div v-if="showToolButtonArea" class="header-button-ri">
|
|
33
33
|
<slot name="toolButton">
|
|
34
|
-
<el-tooltip
|
|
34
|
+
<el-tooltip
|
|
35
|
+
v-if="showTreeToggleButton"
|
|
36
|
+
:content="isTreeExpanded ? t('core.table.collapseAll') : t('core.table.expandAll')"
|
|
37
|
+
placement="top"
|
|
38
|
+
>
|
|
35
39
|
<el-button class="tool-button" :icon="isTreeExpanded ? Fold : Expand" circle @click="toggleTreeExpand" />
|
|
36
40
|
</el-tooltip>
|
|
37
|
-
<el-tooltip v-if="showToolButton('refresh')" content="
|
|
41
|
+
<el-tooltip v-if="showToolButton('refresh')" :content="t('core.table.refresh')" placement="top">
|
|
38
42
|
<el-button class="tool-button" :icon="Refresh" circle @click="handleToolRefresh" />
|
|
39
43
|
</el-tooltip>
|
|
40
|
-
<el-tooltip v-if="showToolButton('setting') && columns.length" content="
|
|
44
|
+
<el-tooltip v-if="showToolButton('setting') && columns.length" :content="t('core.table.columnSetting')" placement="top">
|
|
41
45
|
<el-button class="tool-button" :icon="Operation" circle @click="openColSetting" />
|
|
42
46
|
</el-tooltip>
|
|
43
47
|
<el-tooltip
|
|
44
48
|
v-if="showToolButton('search') && searchColumns?.length"
|
|
45
|
-
:content="isShowSearch ? '
|
|
49
|
+
:content="isShowSearch ? t('core.table.hideSearch') : t('core.table.showSearch')"
|
|
46
50
|
placement="top"
|
|
47
51
|
>
|
|
48
52
|
<el-button class="tool-button" :icon="Search" circle @click="isShowSearch = !isShowSearch" />
|
|
@@ -104,7 +108,7 @@
|
|
|
104
108
|
<div class="table-empty">
|
|
105
109
|
<slot name="empty">
|
|
106
110
|
<img src="../../assets/images/notData.png" alt="notData" />
|
|
107
|
-
<div
|
|
111
|
+
<div>{{ t("common.message.noData") }}</div>
|
|
108
112
|
</slot>
|
|
109
113
|
</div>
|
|
110
114
|
</template>
|
|
@@ -128,7 +132,14 @@ import { ref, watch, provide, onMounted, unref, computed, nextTick, useAttrs, us
|
|
|
128
132
|
import { ElTable } from "element-plus";
|
|
129
133
|
import { useTable } from "../../hooks/useTable";
|
|
130
134
|
import { useSelection } from "../../hooks/useSelection";
|
|
131
|
-
import {
|
|
135
|
+
import {
|
|
136
|
+
ColumnProps,
|
|
137
|
+
EnumProps,
|
|
138
|
+
HeaderActionProps,
|
|
139
|
+
HeaderActionScope,
|
|
140
|
+
ProTableProps,
|
|
141
|
+
TypeProps
|
|
142
|
+
} from "../../components/ProTable/interface";
|
|
132
143
|
import { Expand, Fold, Refresh, Operation, Search } from "@element-plus/icons-vue";
|
|
133
144
|
import { generateUUID, handleProp } from "../../utils";
|
|
134
145
|
import { resolveTableColumnAlign } from "../../utils/proTable";
|
|
@@ -137,6 +148,9 @@ import Pagination from "./components/Pagination.vue";
|
|
|
137
148
|
import ColSetting from "./components/ColSetting.vue";
|
|
138
149
|
import TableColumn from "./components/TableColumn.vue";
|
|
139
150
|
import Sortable from "sortablejs";
|
|
151
|
+
import { useLocaleStore } from "../../locales";
|
|
152
|
+
|
|
153
|
+
const { t } = useLocaleStore();
|
|
140
154
|
|
|
141
155
|
// 接受父组件参数,配置默认值
|
|
142
156
|
const props = withDefaults(defineProps<ProTableProps>(), {
|
|
@@ -208,8 +222,18 @@ const headerActionScope = computed<HeaderActionScope>(() => ({
|
|
|
208
222
|
}));
|
|
209
223
|
|
|
210
224
|
// 表格操作 Hooks
|
|
211
|
-
const {
|
|
212
|
-
|
|
225
|
+
const {
|
|
226
|
+
loading,
|
|
227
|
+
tableData,
|
|
228
|
+
pageable,
|
|
229
|
+
searchParam,
|
|
230
|
+
searchInitParam,
|
|
231
|
+
getTableList,
|
|
232
|
+
search,
|
|
233
|
+
reset,
|
|
234
|
+
handleSizeChange,
|
|
235
|
+
handleCurrentChange
|
|
236
|
+
} = useTable(props.requestApi, props.initParam, props.pagination, props.dataCallback, props.requestError);
|
|
213
237
|
|
|
214
238
|
// 清空选中数据列表
|
|
215
239
|
const clearSelection = () => tableRef.value!.clearSelection();
|
|
@@ -299,10 +323,11 @@ const setEnumMapValue = (prop: string | undefined, data: { [key: string]: any }[
|
|
|
299
323
|
* 根据状态开关配置自动生成搜索下拉枚举,避免状态列只配置开关后搜索框无选项。
|
|
300
324
|
*/
|
|
301
325
|
const buildStatusEnum = (column: ColumnProps): EnumProps[] => {
|
|
302
|
-
if (column.enum || column.dictCode || column.cellType !== "status" || column.search?.el !== "select" || !column.statusProps)
|
|
326
|
+
if (column.enum || column.dictCode || column.cellType !== "status" || column.search?.el !== "select" || !column.statusProps)
|
|
327
|
+
return [];
|
|
303
328
|
return [
|
|
304
|
-
{ label: column.statusProps.activeText ?? "
|
|
305
|
-
{ label: column.statusProps.inactiveText ?? "
|
|
329
|
+
{ label: column.statusProps.activeText ?? t("common.status.enabled"), value: column.statusProps.activeValue },
|
|
330
|
+
{ label: column.statusProps.inactiveText ?? t("common.status.disabled"), value: column.statusProps.inactiveValue }
|
|
306
331
|
];
|
|
307
332
|
};
|
|
308
333
|
|
|
@@ -49,6 +49,9 @@ import {
|
|
|
49
49
|
import Dict from "../../../components/Dict/index.vue";
|
|
50
50
|
import { handleProp } from "../../../utils";
|
|
51
51
|
import { ColumnProps, SearchType } from "../../../components/ProTable/interface";
|
|
52
|
+
import { useLocaleStore } from "../../../locales";
|
|
53
|
+
|
|
54
|
+
const { t } = useLocaleStore();
|
|
52
55
|
|
|
53
56
|
/** 单个搜索表单项组件属性。 */
|
|
54
57
|
interface SearchFormItem {
|
|
@@ -151,12 +154,14 @@ const placeholder = computed(() => {
|
|
|
151
154
|
const search = props.column.search;
|
|
152
155
|
if (["datetimerange", "daterange", "monthrange"].includes(search?.props?.type) || search?.props?.isRange) {
|
|
153
156
|
return {
|
|
154
|
-
rangeSeparator: search?.props?.rangeSeparator ?? "
|
|
155
|
-
startPlaceholder: search?.props?.startPlaceholder ?? "
|
|
156
|
-
endPlaceholder: search?.props?.endPlaceholder ?? "
|
|
157
|
+
rangeSeparator: search?.props?.rangeSeparator ?? "-",
|
|
158
|
+
startPlaceholder: search?.props?.startPlaceholder ?? t("common.field.startTime"),
|
|
159
|
+
endPlaceholder: search?.props?.endPlaceholder ?? t("common.field.endTime")
|
|
157
160
|
};
|
|
158
161
|
}
|
|
159
|
-
const placeholder =
|
|
162
|
+
const placeholder =
|
|
163
|
+
search?.props?.placeholder ??
|
|
164
|
+
(search?.el?.includes("input") ? t("common.placeholder.input") : t("common.placeholder.select"));
|
|
160
165
|
return { placeholder };
|
|
161
166
|
});
|
|
162
167
|
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
</GridItem>
|
|
19
19
|
<GridItem v-if="showOperation" suffix>
|
|
20
20
|
<div class="operation">
|
|
21
|
-
<el-button type="primary" :icon="Search" @click="search">
|
|
22
|
-
<el-button :icon="Delete" @click="reset">
|
|
21
|
+
<el-button type="primary" :icon="Search" @click="search">{{ t("common.action.search") }}</el-button>
|
|
22
|
+
<el-button :icon="Delete" @click="reset">{{ t("common.action.reset") }}</el-button>
|
|
23
23
|
<el-button v-if="showCollapse" type="primary" link class="search-isOpen" @click="collapsed = !collapsed">
|
|
24
|
-
{{ collapsed ? "
|
|
24
|
+
{{ collapsed ? t("common.action.expand") : t("common.action.collapse") }}
|
|
25
25
|
<el-icon class="el-icon--right">
|
|
26
26
|
<component :is="collapsed ? ArrowDown : ArrowUp"></component>
|
|
27
27
|
</el-icon>
|
|
@@ -40,6 +40,9 @@ import { Delete, Search, ArrowDown, ArrowUp } from "@element-plus/icons-vue";
|
|
|
40
40
|
import SearchFormItem from "./components/SearchFormItem.vue";
|
|
41
41
|
import Grid from "../../components/Grid/index.vue";
|
|
42
42
|
import GridItem from "../../components/Grid/components/GridItem.vue";
|
|
43
|
+
import { useLocaleStore } from "../../locales";
|
|
44
|
+
|
|
45
|
+
const { t } = useLocaleStore();
|
|
43
46
|
|
|
44
47
|
/** ProTable 搜索表单组件属性。 */
|
|
45
48
|
interface ProTableProps {
|
|
@@ -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"
|
|
7
|
+
<span v-if="!item.options.length" class="select-filter-notData">{{ t("common.message.noData") }}</span>
|
|
8
8
|
<el-scrollbar>
|
|
9
9
|
<ul class="select-filter-list">
|
|
10
10
|
<li
|
|
@@ -32,6 +32,9 @@
|
|
|
32
32
|
|
|
33
33
|
<script setup lang="ts" name="selectFilter">
|
|
34
34
|
import { ref, watch } from "vue";
|
|
35
|
+
import { useLocaleStore } from "../../locales";
|
|
36
|
+
|
|
37
|
+
const { t } = useLocaleStore();
|
|
35
38
|
|
|
36
39
|
/** 筛选项候选值。 */
|
|
37
40
|
interface OptionsProps {
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
</template>
|
|
15
15
|
</el-input>
|
|
16
16
|
<el-dialog v-model="dialogVisible" :title="placeholder" top="50px" width="66%">
|
|
17
|
-
<el-input v-model="inputValue" placeholder="
|
|
17
|
+
<el-input v-model="inputValue" :placeholder="t('core.icon.search')" size="large" :prefix-icon="Icons.Search" />
|
|
18
18
|
<el-scrollbar v-if="Object.keys(iconsList).length">
|
|
19
19
|
<div class="icon-list">
|
|
20
20
|
<div v-for="item in iconsList" :key="item" class="icon-item" @click="selectIcon(item)">
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
</div>
|
|
24
24
|
</div>
|
|
25
25
|
</el-scrollbar>
|
|
26
|
-
<el-empty v-else description="
|
|
26
|
+
<el-empty v-else :description="t('core.icon.empty')" />
|
|
27
27
|
</el-dialog>
|
|
28
28
|
</div>
|
|
29
29
|
</template>
|
|
@@ -31,6 +31,9 @@
|
|
|
31
31
|
<script setup lang="ts" name="SelectIcon">
|
|
32
32
|
import { ref, computed, watch } from "vue";
|
|
33
33
|
import * as Icons from "@element-plus/icons-vue";
|
|
34
|
+
import { useLocaleStore } from "../../locales";
|
|
35
|
+
|
|
36
|
+
const { t } = useLocaleStore();
|
|
34
37
|
|
|
35
38
|
/** 图标选择器组件属性。 */
|
|
36
39
|
interface SelectIconProps {
|
|
@@ -42,10 +45,11 @@ interface SelectIconProps {
|
|
|
42
45
|
|
|
43
46
|
const props = withDefaults(defineProps<SelectIconProps>(), {
|
|
44
47
|
iconValue: "",
|
|
45
|
-
title: "
|
|
48
|
+
title: "",
|
|
46
49
|
clearable: true,
|
|
47
|
-
placeholder: "
|
|
50
|
+
placeholder: ""
|
|
48
51
|
});
|
|
52
|
+
const placeholder = computed(() => props.placeholder || t("core.icon.placeholder"));
|
|
49
53
|
|
|
50
54
|
// 重新接收一下,防止打包后 clearable 报错
|
|
51
55
|
const valueIcon = ref(props.iconValue);
|
|
@@ -4,14 +4,14 @@
|
|
|
4
4
|
{{ title }}
|
|
5
5
|
</h4>
|
|
6
6
|
<div class="search">
|
|
7
|
-
<el-input v-model="filterText" placeholder="
|
|
7
|
+
<el-input v-model="filterText" :placeholder="t('core.tree.filterPlaceholder')" 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"
|
|
13
|
-
<el-dropdown-item @click="toggleTreeNodes(true)"
|
|
14
|
-
<el-dropdown-item @click="toggleTreeNodes(false)"
|
|
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>
|
|
15
15
|
</el-dropdown-menu>
|
|
16
16
|
</template>
|
|
17
17
|
</el-dropdown>
|
|
@@ -51,6 +51,9 @@
|
|
|
51
51
|
<script setup lang="ts" name="TreeFilter">
|
|
52
52
|
import { ref, watch, onBeforeMount, nextTick } from "vue";
|
|
53
53
|
import { ElTree } from "element-plus";
|
|
54
|
+
import { useLocaleStore } from "../../locales";
|
|
55
|
+
|
|
56
|
+
const { locale, t } = useLocaleStore();
|
|
54
57
|
|
|
55
58
|
// 接收父组件参数并设置默认值
|
|
56
59
|
interface TreeFilterProps {
|
|
@@ -97,7 +100,7 @@ const normalizeLazyNodes = (nodes: { [key: string]: any }[] = []) =>
|
|
|
97
100
|
|
|
98
101
|
const updateTreeData = (data: { [key: string]: any }[]) => {
|
|
99
102
|
treeData.value = props.lazy ? normalizeLazyNodes(data) : data;
|
|
100
|
-
const allNode = { id: "", [props.label]: "
|
|
103
|
+
const allNode = { id: "", [props.label]: t("common.value.all"), isLeaf: true };
|
|
101
104
|
treeAllData.value = props.showAll ? [allNode, ...treeData.value] : treeData.value;
|
|
102
105
|
};
|
|
103
106
|
|
|
@@ -110,7 +113,10 @@ onBeforeMount(async () => {
|
|
|
110
113
|
}
|
|
111
114
|
});
|
|
112
115
|
|
|
113
|
-
const loadTreeNode = async (
|
|
116
|
+
const loadTreeNode = async (
|
|
117
|
+
node: { level: number; data?: { [key: string]: any } },
|
|
118
|
+
resolve: (data: { [key: string]: any }[]) => void
|
|
119
|
+
) => {
|
|
114
120
|
if (!props.requestApi) {
|
|
115
121
|
resolve([]);
|
|
116
122
|
return;
|
|
@@ -141,6 +147,8 @@ watch(
|
|
|
141
147
|
{ deep: true, immediate: true }
|
|
142
148
|
);
|
|
143
149
|
|
|
150
|
+
watch(locale, () => updateTreeData(treeData.value));
|
|
151
|
+
|
|
144
152
|
const filterText = ref("");
|
|
145
153
|
watch(filterText, val => {
|
|
146
154
|
treeRef.value!.filter(val);
|
|
@@ -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.unnamedFile") }}</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.fileFailed"));
|
|
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.fileFormatInvalid"),
|
|
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.fileSizeExceeded", { 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.fileSuccess"),
|
|
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.fileFailed"),
|
|
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.unnamedFile") }}</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.fileFailed"));
|
|
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.fileFormatInvalid"),
|
|
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.fileSizeExceeded", { 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.fileSuccess"),
|
|
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.fileFailed"),
|
|
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.limitExceeded", { limit: props.limit }),
|
|
166
173
|
type: "warning"
|
|
167
174
|
});
|
|
168
175
|
}
|