!2 perf: dict add i18n

Merge pull request !2 from small monkey/dict-i18n
This commit is contained in:
马铃薯头 2025-05-19 01:24:44 +00:00 committed by Gitee
commit 7aa489a283
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
8 changed files with 140 additions and 59 deletions

View File

@ -1,4 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { $t } from '@/locales';
defineOptions({ defineOptions({
name: 'TableRowCheckAlert' name: 'TableRowCheckAlert'
}); });
@ -9,10 +11,12 @@ const checkedRowKeys = defineModel<CommonType.IdType[]>('checkedRowKeys', { requ
<template> <template>
<NAlert type="info"> <NAlert type="info">
<span v-if="checkedRowKeys.length"> <span v-if="checkedRowKeys.length">
已选择{{ checkedRowKeys.length }}条记录 {{ $t('common.selected') }} {{ checkedRowKeys.length }} {{ $t('common.anyRecords') }}
<NButton class="pl-6px" text type="primary" @click="() => (checkedRowKeys = [])">清空</NButton> <NButton class="pl-6px" text type="primary" @click="() => (checkedRowKeys = [])">
{{ $t('common.clear') }}
</NButton>
</span> </span>
<span v-else>未选中任何记录</span> <span v-else>{{ $t('common.noSelectRecord') }}</span>
</NAlert> </NAlert>
</template> </template>

View File

@ -66,7 +66,11 @@ const local: App.I18n.Schema = {
yes: 'Yes', yes: 'Yes',
no: 'No' no: 'No'
}, },
second: 'Second' second: 'Second',
selected: 'selected',
anyRecords: 'records',
clear: 'Clear',
noSelectRecord: 'No Records Selected'
}, },
request: { request: {
logout: 'Logout user after request failed', logout: 'Logout user after request failed',
@ -464,11 +468,15 @@ const local: App.I18n.Schema = {
}, },
dict: { dict: {
title: 'Dictionary List', title: 'Dictionary List',
dictTypeTitle: 'Dictionary Type List',
dictName: 'Dictionary Name', dictName: 'Dictionary Name',
dictType: 'Dictionary Type', dictType: 'Dictionary Type',
status: 'Status', status: 'Status',
remark: 'Remark', remark: 'Remark',
createTime: 'Create Time', createTime: 'Create Time',
refreshCacheSuccess: 'Refresh cache successfully',
refreshCache: 'Refresh Cache',
confirmDeleteDictType: 'Are you sure you want to delete dic type',
data: { data: {
title: 'Dictionary Data List', title: 'Dictionary Data List',
label: 'Dictionary Label', label: 'Dictionary Label',
@ -482,6 +490,14 @@ const local: App.I18n.Schema = {
createTime: 'Create Time' createTime: 'Create Time'
}, },
form: { form: {
dictId: {
required: 'Please enter Dictionary Id',
invalid: 'Dictionary Id cannot be empty'
},
dictCode: {
required: 'Please enter Dictionary Code',
invalid: 'Dictionary Code cannot be empty'
},
dictName: { dictName: {
required: 'Please enter Dictionary Name', required: 'Please enter Dictionary Name',
invalid: 'Dictionary Name cannot be empty' invalid: 'Dictionary Name cannot be empty'
@ -526,7 +542,12 @@ const local: App.I18n.Schema = {
addDict: 'Add Dictionary', addDict: 'Add Dictionary',
editDict: 'Edit Dictionary', editDict: 'Edit Dictionary',
addDictData: 'Add Dictionary Data', addDictData: 'Add Dictionary Data',
editDictData: 'Edit Dictionary Data' editDictData: 'Edit Dictionary Data',
addDictType: 'Add Dictionary Type',
editDictType: 'Edit Dictionary Type',
exportDictType: 'Export Dictionary Type',
refreshDictType: 'Refresh Dictionary Type',
dictTypeIsEmpty: 'Dictionary type is empty'
}, },
menu: { menu: {
title: 'Menu List', title: 'Menu List',

View File

@ -66,7 +66,11 @@ const local: App.I18n.Schema = {
yes: '是', yes: '是',
no: '否' no: '否'
}, },
second: '秒' second: '秒',
selected: '已选择',
anyRecords: '条记录',
clear: '清空',
noSelectRecord: '未选中任何记录'
}, },
request: { request: {
logout: '请求失败后登出用户', logout: '请求失败后登出用户',
@ -464,24 +468,36 @@ const local: App.I18n.Schema = {
}, },
dict: { dict: {
title: '字典列表', title: '字典列表',
dictTypeTitle: '字典类型列表',
dictName: '字典名称', dictName: '字典名称',
dictType: '字典类型', dictType: '字典类型',
status: '状态', status: '状态',
remark: '备注', remark: '备注',
createTime: '创建时间', createTime: '创建时间',
refreshCacheSuccess: '刷新缓存成功',
refreshCache: '刷新缓存',
confirmDeleteDictType: '确定删除字典类型',
data: { data: {
title: '字典数据列表', title: '字典数据列表',
label: '字典标签', label: '字典标签',
value: '字典键值', value: '字典键值',
dictSort: '字典排序', dictSort: '字典排序',
isDefault: '是否默认', isDefault: '是否默认',
listClass: '回显样式', listClass: '标签样式',
cssClass: 'CSS样式', cssClass: 'CSS样式',
status: '状态', status: '状态',
remark: '备注', remark: '备注',
createTime: '创建时间' createTime: '创建时间'
}, },
form: { form: {
dictId: {
required: '请输入字典主键',
invalid: '字典主键不能为空'
},
dictCode: {
required: '请输入字典编码',
invalid: '字典编码不能为空'
},
dictName: { dictName: {
required: '请输入字典名称', required: '请输入字典名称',
invalid: '字典名称不能为空' invalid: '字典名称不能为空'
@ -519,14 +535,19 @@ const local: App.I18n.Schema = {
invalid: '回显样式不能为空' invalid: '回显样式不能为空'
}, },
cssClass: { cssClass: {
required: '请输入CSS样式', required: '请输入样式属性(其他样式扩展)',
invalid: 'CSS样式不能为空' invalid: 'CSS样式不能为空'
} }
}, },
addDict: '新增字典', addDict: '新增字典',
editDict: '编辑字典', editDict: '编辑字典',
addDictData: '新增字典数据', addDictData: '新增字典数据',
editDictData: '编辑字典数据' editDictData: '编辑字典数据',
addDictType: '新增字典类型',
editDictType: '编辑字典类型',
exportDictType: '导出字典类型',
refreshDictType: '刷新列表',
dictTypeIsEmpty: '暂无字典类型'
}, },
menu: { menu: {
title: '菜单列表', title: '菜单列表',

15
src/typings/app.d.ts vendored
View File

@ -362,6 +362,10 @@ declare namespace App {
no: string; no: string;
}; };
second: string; second: string;
selected: string;
anyRecords: string;
clear: string;
noSelectRecord: string;
}; };
request: { request: {
logout: string; logout: string;
@ -606,11 +610,15 @@ declare namespace App {
}; };
dict: { dict: {
title: string; title: string;
dictTypeTitle: string;
dictName: string; dictName: string;
dictType: string; dictType: string;
status: string; status: string;
remark: string; remark: string;
createTime: string; createTime: string;
refreshCacheSuccess: string;
refreshCache: string;
confirmDeleteDictType: string;
data: { data: {
title: string; title: string;
label: string; label: string;
@ -624,6 +632,8 @@ declare namespace App {
createTime: string; createTime: string;
}; };
form: { form: {
dictId: FormMsg;
dictCode: FormMsg;
dictName: FormMsg; dictName: FormMsg;
dictType: FormMsg; dictType: FormMsg;
status: FormMsg; status: FormMsg;
@ -639,6 +649,11 @@ declare namespace App {
editDict: string; editDict: string;
addDictData: string; addDictData: string;
editDictData: string; editDictData: string;
addDictType: string;
editDictType: string;
exportDictType: string;
refreshDictType: string;
dictTypeIsEmpty: string;
}; };
menu: { menu: {
title: string; title: string;

View File

@ -53,7 +53,7 @@ const { columns, columnChecks, data, getData, getDataByPage, loading, mobilePagi
}, },
{ {
key: 'dictLabel', key: 'dictLabel',
title: '字典标签', title: $t('page.system.dict.data.label'),
align: 'center', align: 'center',
minWidth: 80, minWidth: 80,
resizable: true, resizable: true,
@ -66,7 +66,7 @@ const { columns, columnChecks, data, getData, getDataByPage, loading, mobilePagi
}, },
{ {
key: 'dictValue', key: 'dictValue',
title: '字典键值', title: $t('page.system.dict.data.value'),
align: 'center', align: 'center',
minWidth: 80, minWidth: 80,
resizable: true, resizable: true,
@ -76,7 +76,7 @@ const { columns, columnChecks, data, getData, getDataByPage, loading, mobilePagi
}, },
{ {
key: 'dictSort', key: 'dictSort',
title: '字典排序', title: $t('page.system.dict.data.dictSort'),
align: 'center', align: 'center',
minWidth: 80, minWidth: 80,
resizable: true, resizable: true,
@ -86,7 +86,7 @@ const { columns, columnChecks, data, getData, getDataByPage, loading, mobilePagi
}, },
{ {
key: 'remark', key: 'remark',
title: '备注', title: $t('page.system.dict.data.remark'),
align: 'center', align: 'center',
minWidth: 80, minWidth: 80,
resizable: true, resizable: true,
@ -96,7 +96,7 @@ const { columns, columnChecks, data, getData, getDataByPage, loading, mobilePagi
}, },
{ {
key: 'createTime', key: 'createTime',
title: '创建时间', title: $t('page.system.dict.data.createTime'),
align: 'center', align: 'center',
minWidth: 80, minWidth: 80,
resizable: true, resizable: true,
@ -193,7 +193,7 @@ async function handleReset() {
async function handleRefreshCache() { async function handleRefreshCache() {
const { error } = await fetchRefreshCache(); const { error } = await fetchRefreshCache();
if (error) return; if (error) return;
window.$message?.success('刷新缓存成功'); window.$message?.success($t('page.system.dict.refreshCacheSuccess'));
await getData(); await getData();
} }
@ -260,7 +260,7 @@ function renderSuffix({ option }: { option: TreeOption }) {
text text
type="primary" type="primary"
icon="material-symbols:drive-file-rename-outline-outline" icon="material-symbols:drive-file-rename-outline-outline"
tooltip-content="修改" tooltip-content={$t('common.edit')}
onClick={(event: Event) => { onClick={(event: Event) => {
event.stopPropagation(); event.stopPropagation();
handleEditType(option as Api.System.DictType); handleEditType(option as Api.System.DictType);
@ -270,8 +270,8 @@ function renderSuffix({ option }: { option: TreeOption }) {
text text
type="error" type="error"
icon="material-symbols:delete-outline" icon="material-symbols:delete-outline"
tooltip-content="删除" tooltip-content={$t('common.delete')}
popconfirm-content={`确定删除字典类型 ${option.dictType} `} popconfirm-content={`${$t('page.system.dict.confirmDeleteDictType')} ${option.dictType} `}
onClick={(event: Event) => event.stopPropagation()} onClick={(event: Event) => event.stopPropagation()}
onPositiveClick={() => handleDeleteType(option as Api.System.DictType)} onPositiveClick={() => handleDeleteType(option as Api.System.DictType)}
/> />
@ -294,12 +294,12 @@ function handleEditType(dictType: Api.System.DictType) {
async function handleDeleteType(dictType: Api.System.DictType) { async function handleDeleteType(dictType: Api.System.DictType) {
const { error } = await fetchBatchDeleteDictType([dictType.dictId]); const { error } = await fetchBatchDeleteDictType([dictType.dictId]);
if (error) return; if (error) return;
window.$message?.success('删除成功'); window.$message?.success($t('common.deleteSuccess'));
getTreeData(); getTreeData();
} }
async function handleExportType() { async function handleExportType() {
download('/system/dict/type/export', searchParams, `字典类型_${new Date().getTime()}.xlsx`); download('/system/dict/type/export', searchParams, `${$t('page.system.dict.dictType')}_${new Date().getTime()}.xlsx`);
} }
const selectable = computed(() => { const selectable = computed(() => {
@ -308,14 +308,14 @@ const selectable = computed(() => {
</script> </script>
<template> <template>
<TableSiderLayout sider-title="字典类型列表"> <TableSiderLayout :sider-title="$t('page.system.dict.dictTypeTitle')">
<template #header-extra> <template #header-extra>
<ButtonIcon <ButtonIcon
v-if="hasAuth('system:dict:add')" v-if="hasAuth('system:dict:add')"
size="small" size="small"
icon="material-symbols:add-rounded" icon="material-symbols:add-rounded"
class="h-18px text-icon" class="h-18px text-icon"
tooltip-content="新增字典类型" :tooltip-content="$t('page.system.dict.addDictType')"
@click.stop="() => handleAddType()" @click.stop="() => handleAddType()"
/> />
<ButtonIcon <ButtonIcon
@ -323,14 +323,14 @@ const selectable = computed(() => {
size="small" size="small"
icon="material-symbols:download-rounded" icon="material-symbols:download-rounded"
class="h-18px text-icon" class="h-18px text-icon"
tooltip-content="导出字典类型" :tooltip-content="$t('page.system.dict.exportDictType')"
@click.stop="() => handleExportType()" @click.stop="() => handleExportType()"
/> />
<ButtonIcon <ButtonIcon
size="small" size="small"
icon="material-symbols:refresh-rounded" icon="material-symbols:refresh-rounded"
class="h-18px text-icon" class="h-18px text-icon"
tooltip-content="刷新列表" :tooltip-content="$t('page.system.dict.refreshDictType')"
@click.stop="() => handleResetTreeData()" @click.stop="() => handleResetTreeData()"
/> />
</template> </template>
@ -354,7 +354,7 @@ const selectable = computed(() => {
@update:selected-keys="handleClickTree" @update:selected-keys="handleClickTree"
> >
<template #empty> <template #empty>
<NEmpty description="暂无字典类型" class="h-full min-h-200px justify-center" /> <NEmpty :description="$t('page.system.dict.dictTypeIsEmpty')" class="h-full min-h-200px justify-center" />
</template> </template>
</NTree> </NTree>
</NSpin> </NSpin>
@ -362,7 +362,7 @@ const selectable = computed(() => {
<div class="h-full flex-col-stretch gap-12px overflow-hidden lt-sm:overflow-auto"> <div class="h-full flex-col-stretch gap-12px overflow-hidden lt-sm:overflow-auto">
<DictDataSearch v-model:model="searchParams" @reset="handleReset" @search="getDataByPage" /> <DictDataSearch v-model:model="searchParams" @reset="handleReset" @search="getDataByPage" />
<TableRowCheckAlert v-model:checked-row-keys="checkedRowKeys" /> <TableRowCheckAlert v-model:checked-row-keys="checkedRowKeys" />
<NCard title="字典数据列表" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper"> <NCard :title="$t('page.system.dict.title')" :bordered="false" size="small" class="sm:flex-1-hidden card-wrapper">
<template #header-extra> <template #header-extra>
<TableHeaderOperation <TableHeaderOperation
v-model:columns="columnChecks" v-model:columns="columnChecks"
@ -382,7 +382,7 @@ const selectable = computed(() => {
<template #icon> <template #icon>
<icon-material-symbols:refresh-rounded class="text-icon" /> <icon-material-symbols:refresh-rounded class="text-icon" />
</template> </template>
刷新缓存 {{ $t('page.system.dict.refreshCache') }}
</NButton> </NButton>
</template> </template>
</TableHeaderOperation> </TableHeaderOperation>

View File

@ -34,8 +34,8 @@ const { createRequiredRule } = useFormRules();
const title = computed(() => { const title = computed(() => {
const titles: Record<NaiveUI.TableOperateType, string> = { const titles: Record<NaiveUI.TableOperateType, string> = {
add: '新增字典数据', add: $t('page.system.dict.addDictData'),
edit: '编辑字典数据' edit: $t('page.system.dict.editDictData')
}; };
return titles[props.operateType]; return titles[props.operateType];
}); });
@ -68,9 +68,9 @@ function createDefaultModel(): Model {
type RuleKey = Extract<keyof Model, 'dictCode' | 'dictLabel' | 'dictValue'>; type RuleKey = Extract<keyof Model, 'dictCode' | 'dictLabel' | 'dictValue'>;
const rules: Record<RuleKey, App.Global.FormRule> = { const rules: Record<RuleKey, App.Global.FormRule> = {
dictCode: createRequiredRule('字典编码不能为空'), dictCode: createRequiredRule($t('page.system.dict.form.dictCode.invalid')),
dictLabel: createRequiredRule('字典标签不能为空'), dictLabel: createRequiredRule($t('page.system.dict.form.dictLabel.invalid')),
dictValue: createRequiredRule('字典键值不能为空') dictValue: createRequiredRule($t('page.system.dict.form.dictValue.invalid'))
}; };
function handleUpdateModelWhenEdit() { function handleUpdateModelWhenEdit() {
@ -146,32 +146,41 @@ function renderTagLabel(option: { label: string; value: string }) {
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%"> <NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable> <NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules"> <NForm ref="formRef" :model="model" :rules="rules">
<NFormItem label="字典类型" path="dictType"> <NFormItem :label="$t('page.system.dict.dictType')" path="dictType">
<NInput v-model:value="model.dictType" disabled placeholder="请输入字典类型" /> <NInput
v-model:value="model.dictType"
disabled
:placeholder="$t('page.system.dict.form.dictType.required')"
/>
</NFormItem> </NFormItem>
<NFormItem label="标签样式" path="listClass"> <NFormItem :label="$t('page.system.dict.data.listClass')" path="listClass">
<NSelect <NSelect
v-model:value="model.listClass" v-model:value="model.listClass"
clearable clearable
:options="listClassOptions" :options="listClassOptions"
placeholder="请选择标签样式" :placeholder="$t('page.system.dict.form.listClass.required')"
:render-label="renderTagLabel" :render-label="renderTagLabel"
/> />
</NFormItem> </NFormItem>
<NFormItem label="数据标签" path="dictLabel"> <NFormItem :label="$t('page.system.dict.data.label')" path="dictLabel">
<NInput v-model:value="model.dictLabel" placeholder="请输入字典标签" /> <NInput v-model:value="model.dictLabel" :placeholder="$t('page.system.dict.form.dictLabel.required')" />
</NFormItem> </NFormItem>
<NFormItem label="数据键值" path="dictValue"> <NFormItem :label="$t('page.system.dict.data.value')" path="dictValue">
<NInput v-model:value="model.dictValue" placeholder="请输入字典键值" /> <NInput v-model:value="model.dictValue" :placeholder="$t('page.system.dict.form.dictValue.required')" />
</NFormItem> </NFormItem>
<NFormItem label="css类名" path="cssClass"> <NFormItem :label="$t('page.system.dict.data.cssClass')" path="cssClass">
<NInput v-model:value="model.cssClass" placeholder="请输入样式属性(其他样式扩展)" /> <NInput v-model:value="model.cssClass" :placeholder="$t('page.system.dict.form.cssClass.required')" />
</NFormItem> </NFormItem>
<NFormItem label="显示排序" path="dictSort"> <NFormItem :label="$t('page.system.dict.data.dictSort')" path="dictSort">
<NInputNumber v-model:value="model.dictSort" placeholder="请输入字典排序" /> <NInputNumber v-model:value="model.dictSort" :placeholder="$t('page.system.dict.form.dictSort.required')" />
</NFormItem> </NFormItem>
<NFormItem label="备注" path="remark"> <NFormItem :label="$t('page.system.dict.data.remark')" path="remark">
<NInput v-model:value="model.remark" :rows="3" type="textarea" placeholder="请输入备注" /> <NInput
v-model:value="model.remark"
:rows="3"
type="textarea"
:placeholder="$t('page.system.dict.form.remark.required')"
/>
</NFormItem> </NFormItem>
</NForm> </NForm>
<template #footer> <template #footer>

View File

@ -34,8 +34,14 @@ async function search() {
<NCollapseItem :title="$t('common.search')" name="user-search"> <NCollapseItem :title="$t('common.search')" name="user-search">
<NForm ref="formRef" :model="model" label-placement="left" :label-width="80"> <NForm ref="formRef" :model="model" label-placement="left" :label-width="80">
<NGrid responsive="self" item-responsive> <NGrid responsive="self" item-responsive>
<NFormItemGi :show-feedback="false" span="12" label="字典标签" path="dictLabel" class="pr-24px"> <NFormItemGi
<NInput v-model:value="model.dictLabel" placeholder="请输入字典标签" /> :show-feedback="false"
span="12"
:label="$t('page.system.dict.data.label')"
path="dictLabel"
class="pr-24px"
>
<NInput v-model:value="model.dictLabel" :placeholder="$t('page.system.dict.form.dictLabel.required')" />
</NFormItemGi> </NFormItemGi>
<NFormItemGi :show-feedback="false" span="12" class="pr-24px"> <NFormItemGi :show-feedback="false" span="12" class="pr-24px">
<NSpace class="w-full" justify="end"> <NSpace class="w-full" justify="end">

View File

@ -32,8 +32,8 @@ const { createRequiredRule } = useFormRules();
const title = computed(() => { const title = computed(() => {
const titles: Record<NaiveUI.TableOperateType, string> = { const titles: Record<NaiveUI.TableOperateType, string> = {
add: '新增字典类型', add: $t('page.system.dict.addDictType'),
edit: '编辑字典类型' edit: $t('page.system.dict.editDictType')
}; };
return titles[props.operateType]; return titles[props.operateType];
}); });
@ -53,9 +53,9 @@ function createDefaultModel(): Model {
type RuleKey = Extract<keyof Model, 'dictId' | 'dictName' | 'dictType'>; type RuleKey = Extract<keyof Model, 'dictId' | 'dictName' | 'dictType'>;
const rules: Record<RuleKey, App.Global.FormRule> = { const rules: Record<RuleKey, App.Global.FormRule> = {
dictId: createRequiredRule('字典主键不能为空'), dictId: createRequiredRule($t('page.system.dict.form.dictValue.invalid')),
dictName: createRequiredRule('字典名称不能为空'), dictName: createRequiredRule($t('page.system.dict.form.dictName.invalid')),
dictType: createRequiredRule('字典类型不能为空') dictType: createRequiredRule($t('page.system.dict.form.dictType.invalid'))
}; };
function handleUpdateModelWhenEdit() { function handleUpdateModelWhenEdit() {
@ -106,14 +106,19 @@ watch(visible, () => {
<NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%"> <NDrawer v-model:show="visible" :title="title" display-directive="show" :width="800" class="max-w-90%">
<NDrawerContent :title="title" :native-scrollbar="false" closable> <NDrawerContent :title="title" :native-scrollbar="false" closable>
<NForm ref="formRef" :model="model" :rules="rules"> <NForm ref="formRef" :model="model" :rules="rules">
<NFormItem label="字典名称" path="dictName"> <NFormItem :label="$t('page.system.dict.dictName')" path="dictName">
<NInput v-model:value="model.dictName" placeholder="请输入字典名称" /> <NInput v-model:value="model.dictName" :placeholder="$t('page.system.dict.form.dictName.required')" />
</NFormItem> </NFormItem>
<NFormItem label="字典类型" path="dictType"> <NFormItem :label="$t('page.system.dict.dictType')" path="dictType">
<NInput v-model:value="model.dictType" placeholder="请输入字典类型" /> <NInput v-model:value="model.dictType" :placeholder="$t('page.system.dict.form.dictValue.required')" />
</NFormItem> </NFormItem>
<NFormItem label="备注" path="remark"> <NFormItem :label="$t('page.system.dict.remark')" path="remark">
<NInput v-model:value="model.remark" :rows="3" type="textarea" placeholder="请输入备注" /> <NInput
v-model:value="model.remark"
:rows="3"
type="textarea"
:placeholder="$t('page.system.dict.form.remark.required')"
/>
</NFormItem> </NFormItem>
</NForm> </NForm>
<template #footer> <template #footer>