Compare commits

..
4 Commits
Author SHA1 Message Date
wc24 ac57de97cb fix(i18n): correct t:prefixed strings to ILabel objects for translation 2026-05-24 22:50:59 +08:00
wc24 0b8f873a4c fix(ShrimpEditDrawer): i18n fieldRequired translation with label param 2026-05-24 22:32:32 +08:00
wc24 d580fc53b9 chore: bump version to 0.2.2 & sync locales 2026-05-24 21:11:03 +08:00
wc24 9746be581d v0.2.1: i18n messages 改成深合并
initI18n 之前用 spread 浅合并:
  { ...zh_cn, ...(extra['zh-cn'] || {}) }

业务侧只要定义同名一级键(如 'user'),框架自带 user.* 全部被覆盖,
表现是控制台 [intlify] Not found 'user.operationLog' / 'user.xxx' 之类。

改成递归 deepMerge,框架 locale 在底,业务侧叠在上,同 leaf key 业务覆盖框架。
2026-05-23 22:48:10 +08:00
5 changed files with 37 additions and 13 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "shrimp-admin",
"version": "0.2.0",
"version": "0.2.4",
"private": true,
"description": "Shrimp 框架前端 — 消费 ShrimpServer + ShrimpTable 契约的经典 Vue3 + Element Plus 实现",
"main": "src/index.ts",
+26 -10
View File
@@ -12,6 +12,22 @@ import { IShrimpResponse, ILabel } from './IShrimpType'
import { ShrimpClient, handleShrimpResponse, type IShrimpTipper, type IRouteInfo } from './ShrimpClient'
import FieldString from './components/fields/FieldString.vue'
// ============== 工具 ==============
/** locale 深合并:嵌套对象按 key 递归 merge,非对象值 src 覆盖 dst。仅服务于 i18n messages,没必要拉 lodash。 */
function deepMerge(dst: Record<string, any>, src: Record<string, any>): Record<string, any> {
const out: Record<string, any> = { ...dst }
for (const key in src) {
const sv = src[key], dv = out[key]
if (sv && typeof sv === 'object' && !Array.isArray(sv) && dv && typeof dv === 'object' && !Array.isArray(dv)) {
out[key] = deepMerge(dv, sv)
} else {
out[key] = sv
}
}
return out
}
// ============== Options ==============
export interface ShrimpAdminConfig {
@@ -169,14 +185,14 @@ export class VueAdmin extends ShrimpClient {
}
initI18n(extraLocales?: Record<string, any>) {
const merged: Record<string, any> = {
'zh-cn': { ...zh_cn, ...(extraLocales?.['zh-cn'] || {}) },
'en': { ...en, ...(extraLocales?.['en'] || {}) },
}
if (extraLocales) {
for (const key in extraLocales) {
if (!(key in merged)) merged[key] = extraLocales[key]
}
// 深合并:框架自带 locale 在底,业务侧叠在上。
// 旧版用 spread 浅合并,业务侧只要定义了同名一级键(如 user)就会把框架的 user.* 全部替换,
// 表现是控制台 [intlify] Not found 'user.operationLog' key 之类的报错。
const builtins: Record<string, any> = { 'zh-cn': zh_cn, 'en': en }
const merged: Record<string, any> = {}
const langs = new Set([...Object.keys(builtins), ...Object.keys(extraLocales || {})])
for (const lang of langs) {
merged[lang] = deepMerge(builtins[lang] || {}, extraLocales?.[lang] || {})
}
this.i18n = createI18n({
locale: this.localData.get("lang") || 'zh-cn',
@@ -255,7 +271,7 @@ export class VueAdmin extends ShrimpClient {
{
path: "/login",
component: () => import('./views/login.vue'),
meta: { title: "t:login.signIn" }
meta: { title: { t: 'login.signIn' } }
},
{
path: "/:pathMatch(.*)",
@@ -327,7 +343,7 @@ export class VueAdmin extends ShrimpClient {
}
},
(error) => {
ElMessage.error(this.t('t:base.netError'))
ElMessage.error(this.t({ t: 'base.netError' }))
throw error
}
)
+1 -1
View File
@@ -53,7 +53,7 @@ function buildRules(field: IFieldConfig): FormItemRule[] {
if (field.required) {
rules.push({
required: true,
message: vueAdmin.t('shrimp.fieldRequired'),
message: vueAdmin.t({ t: 'shrimp.fieldRequired', params: { field: field.label } }),
trigger: 'change',
...(field.type === 'string' || field.type === 'textarea' || field.type === 'password' ? { trigger: 'blur' } : {}),
})
+4 -1
View File
@@ -25,7 +25,10 @@
"enabled": "Enabled",
"pressEnter": "Press Enter to add",
"expand": "Expand",
"collapse": "Collapse"
"collapse": "Collapse",
"back": "Back",
"refresh": "Refresh",
"notFound": "Not Found"
},
"user": {
"username": "Username",
+5
View File
@@ -38,6 +38,7 @@
"active": "启用状态",
"createdAt": "创建时间",
"updatedAt": "更新时间",
"menuManage": "用户",
"operationLog": "操作日志"
},
"operationLog": {
@@ -55,6 +56,7 @@
"powers": "权限",
"createdAt": "创建时间",
"updatedAt": "更新时间",
"menuManage": "角色",
"menuList": "角色列表",
"empty": "暂无角色",
"addRole": "新增角色",
@@ -91,6 +93,9 @@
"PWError": "请输入密码"
},
"power": {
"user": "用户",
"role": "角色",
"zerobase": "Zero Base",
"add": "新增",
"edit": "编辑",
"delete": "删除",