feat(projects): 菜单字典适配 i18n
This commit is contained in:
parent
d141ed5bef
commit
39dd9acca9
@ -3,6 +3,7 @@ import { computed, useAttrs } from 'vue';
|
||||
import type { TagProps } from 'naive-ui';
|
||||
import { useDict } from '@/hooks/business/dict';
|
||||
import { isNotNull } from '@/utils/common';
|
||||
import { $t } from '@/locales';
|
||||
|
||||
defineOptions({ name: 'DictTag' });
|
||||
|
||||
@ -23,13 +24,18 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
|
||||
const attrs = useAttrs() as TagProps;
|
||||
|
||||
const { transformDictData } = useDict(props.dictCode, props.immediate);
|
||||
|
||||
const dictTagData = computed<Api.System.DictData[]>(() => {
|
||||
if (props.dictData) {
|
||||
return [props.dictData];
|
||||
const dictData = props.dictData;
|
||||
if (dictData.dictLabel?.startsWith(`dict.${dictData.dictType}.`)) {
|
||||
dictData.dictLabel = $t(dictData.dictLabel as App.I18n.I18nKey);
|
||||
}
|
||||
return [dictData];
|
||||
}
|
||||
// 避免 props.value 为 0 时,无法触发
|
||||
if (props.dictCode && isNotNull(props.value)) {
|
||||
const { transformDictData } = useDict(props.dictCode, props.immediate);
|
||||
return transformDictData(props.value) || [];
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,8 @@ import { storeToRefs } from 'pinia';
|
||||
import { fetchGetDictDataByType } from '@/service/api/system';
|
||||
import { useDictStore } from '@/store/modules/dict';
|
||||
import { isNull } from '@/utils/common';
|
||||
import { $t } from '@/locales';
|
||||
|
||||
export function useDict(dictType: string, immediate: boolean = true) {
|
||||
const dictStore = useDictStore();
|
||||
const { dictData: dictList } = storeToRefs(dictStore);
|
||||
@ -19,6 +21,11 @@ export function useDict(dictType: string, immediate: boolean = true) {
|
||||
}
|
||||
const { data: dictData, error } = await fetchGetDictDataByType(dictType);
|
||||
if (error) return;
|
||||
dictData.forEach(dict => {
|
||||
if (dict.dictLabel?.startsWith(`dict.${dictType}.`)) {
|
||||
dict.dictLabel = $t(dict.dictLabel as App.I18n.I18nKey);
|
||||
}
|
||||
});
|
||||
dictStore.setDict(dictType, dictData);
|
||||
data.value = dictData;
|
||||
}
|
||||
|
@ -234,6 +234,13 @@ const local: App.I18n.Schema = {
|
||||
exception_404: '404',
|
||||
exception_500: '500'
|
||||
},
|
||||
dict: {
|
||||
sys_user_sex: {
|
||||
male: 'Male',
|
||||
female: 'Female',
|
||||
unknown: 'Unknown'
|
||||
}
|
||||
},
|
||||
page: {
|
||||
login: {
|
||||
common: {
|
||||
|
@ -234,6 +234,13 @@ const local: App.I18n.Schema = {
|
||||
exception_404: '404',
|
||||
exception_500: '500'
|
||||
},
|
||||
dict: {
|
||||
sys_user_sex: {
|
||||
male: '男',
|
||||
female: '女',
|
||||
unknown: '未知'
|
||||
}
|
||||
},
|
||||
page: {
|
||||
login: {
|
||||
common: {
|
||||
|
@ -1,11 +1,17 @@
|
||||
import { ref } from 'vue';
|
||||
import { defineStore } from 'pinia';
|
||||
import { $t } from '@/locales';
|
||||
|
||||
export const useDictStore = defineStore('dict', () => {
|
||||
const dictData = ref<{ [key: string]: Api.System.DictData[] }>({});
|
||||
|
||||
const getDict = (key: string) => {
|
||||
return dictData.value[key];
|
||||
return dictData.value[key]?.map(item => ({
|
||||
...item,
|
||||
dictLabel: item.dictLabel?.startsWith(`dict.${item.dictType}.`)
|
||||
? $t(item.dictLabel as App.I18n.I18nKey)
|
||||
: item.dictLabel
|
||||
}));
|
||||
};
|
||||
|
||||
const setDict = (key: string, dict: Api.System.DictData[]) => {
|
||||
|
@ -103,6 +103,9 @@ export const useRouteStore = defineStore(SetupStoreId.Route, () => {
|
||||
// eslint-disable-next-line complexity
|
||||
function parseRouter(route: ElegantConstRoute, parent?: ElegantConstRoute) {
|
||||
route.meta = route.meta ? route.meta : { title: route.name };
|
||||
if (route.meta.title.startsWith('route.')) {
|
||||
route.meta.i18nKey = route.meta.title as App.I18n.I18nKey;
|
||||
}
|
||||
const isLayout = route.component === 'Layout';
|
||||
const isFramePage = route.component === 'FrameView';
|
||||
const isParentLayout = route.component === 'ParentView';
|
||||
|
1
src/typings/app.d.ts
vendored
1
src/typings/app.d.ts
vendored
@ -467,6 +467,7 @@ declare namespace App {
|
||||
};
|
||||
};
|
||||
route: Record<I18nRouteKey, string>;
|
||||
dict: Record<string, Record<string, string>>;
|
||||
page: {
|
||||
common: {
|
||||
id: string;
|
||||
|
@ -44,13 +44,15 @@ type Model = Api.System.DictDataOperateParams;
|
||||
|
||||
const model: Model = reactive(createDefaultModel());
|
||||
|
||||
const listClassOptions = [
|
||||
{ label: 'primary', value: 'primary' },
|
||||
{ label: 'success', value: 'success' },
|
||||
{ label: 'info', value: 'info' },
|
||||
{ label: 'warning', value: 'warning' },
|
||||
{ label: 'error', value: 'error' },
|
||||
{ label: 'default', value: 'default' }
|
||||
const listClassOptions: Record<string, string>[] = [
|
||||
{ label: 'Text', value: 'text' },
|
||||
{ label: 'Default', value: 'default' },
|
||||
{ label: 'Tertiary', value: 'tertiary' },
|
||||
{ label: 'Primary', value: 'primary' },
|
||||
{ label: 'Info', value: 'info' },
|
||||
{ label: 'Success', value: 'success' },
|
||||
{ label: 'Warning', value: 'warning' },
|
||||
{ label: 'Error', value: 'error' }
|
||||
];
|
||||
|
||||
function createDefaultModel(): Model {
|
||||
@ -134,6 +136,9 @@ watch(visible, () => {
|
||||
});
|
||||
|
||||
function renderTagLabel(option: { label: string; value: string }) {
|
||||
if (option.value === 'text') {
|
||||
return option.label;
|
||||
}
|
||||
return (
|
||||
<NTag size="small" type={option.value as any}>
|
||||
{option.label}
|
||||
|
Loading…
Reference in New Issue
Block a user