171 lines
6.9 KiB
Plaintext
171 lines
6.9 KiB
Plaintext
import { DEFAULT_LANG } from "@/constants/i18n.constants";
|
|
import { I18N_EN_US } from "@/constants/i18n-locales/en-us";
|
|
import { I18N_ZH_HK } from "@/constants/i18n-locales/zh-hk";
|
|
import { I18N_ZH_CN } from "@/constants/i18n-locales/zh-cn";
|
|
import { I18N_ZH_TW } from "@/constants/i18n-locales/zh-tw";
|
|
|
|
export const I18N_FALLBACK_BUNDLES: Record<string, Record<string, string>> = {
|
|
"zh-cn": I18N_ZH_CN,
|
|
"zh-tw": I18N_ZH_TW,
|
|
"zh-hk": I18N_ZH_HK,
|
|
"en-us": I18N_EN_US,
|
|
};
|
|
|
|
const normalizeBundleLang = (lang: string): string => {
|
|
const source = (lang || "").trim();
|
|
if (!source) return "zh-cn";
|
|
const normalized = source.replaceAll("_", "-");
|
|
const lower = normalized.toLowerCase();
|
|
|
|
// bundle key 统一收敛为本地词包文件名使用的小写语言 key。
|
|
if (lower === "zh-cn" || lower === "zh-hans") return "zh-cn";
|
|
if (lower === "zh-tw" || lower === "zh-hant") return "zh-tw";
|
|
if (lower === "zh-hk") return "zh-hk";
|
|
if (lower === "en-us" || lower === "en") return "en-us";
|
|
if (lower.startsWith("zh-hans")) return "zh-cn";
|
|
if (lower.startsWith("zh-cn")) return "zh-cn";
|
|
if (lower.startsWith("zh-hant-hk")) return "zh-hk";
|
|
if (lower.startsWith("zh-hk")) return "zh-hk";
|
|
if (lower.startsWith("zh-hant")) return "zh-tw";
|
|
if (lower.startsWith("zh-tw")) return "zh-tw";
|
|
if (lower.startsWith("en-")) return "en-us";
|
|
if (lower.startsWith("en-us")) return "en-us";
|
|
|
|
if (normalized === "zh-CN") return "zh-cn";
|
|
if (normalized === "zh-TW") return "zh-tw";
|
|
if (normalized === "zh-HK") return "zh-hk";
|
|
if (normalized === "en-US") return "en-us";
|
|
|
|
return lower;
|
|
};
|
|
|
|
export const toBundleKey = (lang: string): string => {
|
|
return normalizeBundleLang(lang);
|
|
};
|
|
|
|
const zhFallback = I18N_FALLBACK_BUNDLES[toBundleKey(DEFAULT_LANG)] || {};
|
|
|
|
/**
|
|
* 历史中文字面量到 i18n key 的兼容映射表。
|
|
*
|
|
* 作用:
|
|
* 1. 兼容仍然传入中文字面量的老组件/老页面 props
|
|
* 2. 兼容部分第三方组件内部仍会透传旧中文的场景
|
|
* 3. 为 `translateText()` 提供迁移过渡期桥接能力
|
|
*
|
|
* 注意:
|
|
* - 这里不是主词典,不应用于新增业务文案
|
|
* - 新代码应优先直接传 `Mobile.*` key
|
|
* - 只有“历史兼容”或“三方兼容”确有必要时,才允许继续补充映射项
|
|
*/
|
|
export const I18N_LITERAL_LOOKUP: Record<string, string> = {
|
|
// 导航与首页基础文案
|
|
首页: "Mobile.Nav.home",
|
|
智联录: "Mobile.Nav.unionRecord",
|
|
智能体: "Mobile.Nav.agent",
|
|
应用: "Mobile.Nav.app",
|
|
最近使用: "Mobile.Common.recentUsed",
|
|
会话记录: "Mobile.Common.conversationHistory",
|
|
菜单: "Mobile.Common.menu",
|
|
提示: "Mobile.Common.tip",
|
|
全部: "Mobile.Common.all",
|
|
暂无数据: "Mobile.Common.noData",
|
|
没有更多数据了: "Mobile.Common.noMoreData",
|
|
|
|
// 登录与认证链路
|
|
"登录 / 注册": "Mobile.Common.loginRegister",
|
|
"当前展示为体验数据,登录后使用完整功能": "Mobile.Common.noticeExperience",
|
|
同意: "Mobile.Common.agree",
|
|
不同意: "Mobile.Common.disagree",
|
|
|
|
// 个人中心与公共状态
|
|
语言: "Mobile.Profile.language",
|
|
|
|
// 协议、链接与通用反馈
|
|
"已阅读并同意协议:": "Mobile.Auth.agreementPrefix",
|
|
服务使用协议: "Mobile.Auth.serviceAgreement",
|
|
隐私协议: "Mobile.Auth.privacyAgreement",
|
|
"请同意服务协议及隐私保护!": "Mobile.Auth.pleaseAgreeProtocol",
|
|
链接地址配置错误: "Mobile.Link.invalidConfig",
|
|
链接已复制: "Mobile.Link.copied",
|
|
"链接已复制,请手动粘贴打开": "Mobile.Link.copyAndOpen",
|
|
打开链接失败: "Mobile.Link.openFailed",
|
|
加载中: "Mobile.Page.loading",
|
|
"加载中...": "Mobile.Page.loadingMore",
|
|
请输入内容: "Mobile.Page.inputRequired",
|
|
重试: "Mobile.Common.retry",
|
|
复制成功: "Mobile.Common.copySuccess",
|
|
复制失败: "Mobile.Common.copyFailed",
|
|
来自: "Mobile.Common.from",
|
|
页面首页: "Mobile.Common.pageHome",
|
|
工作台: "Mobile.Common.workspace",
|
|
|
|
// 搜索与列表页
|
|
搜索智能体: "Mobile.AgentSearch.placeholder",
|
|
暂无结果: "Mobile.AgentSearch.emptyResult",
|
|
|
|
// 聊天输入与会话主链路
|
|
拍照: "Mobile.Chat.takePhoto",
|
|
相册: "Mobile.Chat.album",
|
|
文件: "Mobile.Chat.file",
|
|
技能: "Mobile.Chat.skill",
|
|
对话设置: "Mobile.Conversation.settingsTitle",
|
|
相关会话: "Mobile.Conversation.relatedTitle",
|
|
查看全部: "Mobile.Conversation.viewAll",
|
|
消息内容不是字符串: "Mobile.ThirdParty.UniAiX.invalidMessageContent",
|
|
复制代码: "Mobile.ThirdParty.MpHtml.copyCode",
|
|
保存成功: "Mobile.ThirdParty.MpHtml.saveSuccess",
|
|
执行计划: "Mobile.ThirdParty.MpHtml.executionPlan",
|
|
调用参数: "Mobile.ThirdParty.MpHtml.callArguments",
|
|
调用结果: "Mobile.ThirdParty.MpHtml.callResult",
|
|
结果为空: "Mobile.ThirdParty.MpHtml.emptyResult",
|
|
请填写验证码: "Mobile.ThirdParty.UniCaptcha.fillCaptcha",
|
|
scene不能为空: "Mobile.ThirdParty.UniCaptcha.sceneRequired",
|
|
保存失败: "Mobile.ThirdParty.XTools.saveFailed",
|
|
当前环境不支持微信操作: "Mobile.ThirdParty.XTools.wechatUnsupported",
|
|
"获取服务失败,不支持该操作": "Mobile.ThirdParty.XTools.getServiceFailed",
|
|
|
|
// 会话、沙盒与业务页遗留文案
|
|
全部会话: "Mobile.Conversation.allConversations",
|
|
新建会话: "Mobile.Conversation.newConversation",
|
|
更多信息: "Mobile.Conversation.moreInfo",
|
|
收藏: "Mobile.Conversation.favorite",
|
|
分享: "Mobile.Conversation.share",
|
|
会话链接Key不能为空: "Mobile.Conversation.chatKeyRequired",
|
|
会话ID不能为空: "Mobile.Conversation.idRequired",
|
|
智能体电脑选择: "Mobile.Sandbox.selectorTitle",
|
|
电脑不可用: "Mobile.Sandbox.unavailable",
|
|
无可用电脑: "Mobile.Sandbox.noneAvailable",
|
|
搜索智联录: "Mobile.AgentUnion.searchPlaceholder",
|
|
获取主页智能体列表失败: "Mobile.AgentUnion.fetchHomeAgentListFailed",
|
|
获取分类信息失败: "Mobile.AgentList.fetchCategoryFailed",
|
|
获取智能体列表失败: "Mobile.AgentList.fetchAgentFailed",
|
|
取消收藏失败: "Mobile.AgentList.unCollectFailed",
|
|
添加收藏失败: "Mobile.AgentList.collectFailed",
|
|
"你确认要删除该智能体吗?": "Mobile.AgentList.confirmDeleteAgent",
|
|
删除失败: "Mobile.AgentList.deleteFailed",
|
|
未命名会话: "Mobile.Conversation.unnamed",
|
|
未知智能体: "Mobile.Conversation.unknownAgent",
|
|
执行中: "Mobile.Conversation.executing",
|
|
"我是你的智能助手,有什么需要帮忙的吗?": "Mobile.TempSession.defaultDesc",
|
|
请输入指令: "Mobile.TempSession.inputPlaceholder",
|
|
};
|
|
|
|
export const getLocalFallback = (lang: string, key: string): string => {
|
|
const bundleKey = toBundleKey(lang);
|
|
const defaultBundleKey = toBundleKey(DEFAULT_LANG);
|
|
return (
|
|
I18N_FALLBACK_BUNDLES[bundleKey]?.[key] ||
|
|
I18N_FALLBACK_BUNDLES[defaultBundleKey]?.[key] ||
|
|
""
|
|
);
|
|
};
|
|
|
|
export const resolveLiteralKey = (value: string): string => {
|
|
return I18N_LITERAL_LOOKUP[value] || value;
|
|
};
|
|
|
|
export const getZhFallback = (key: string): string => {
|
|
return zhFallback[key] || key;
|
|
};
|