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