refactor: refactor locales, separate locales within apps,fixed #12

This commit is contained in:
vben
2024-07-07 00:17:44 +08:00
parent 3571511394
commit 208d4188fc
77 changed files with 486 additions and 394 deletions

View File

@@ -0,0 +1,15 @@
import { defineBuildConfig } from 'unbuild';
export default defineBuildConfig({
clean: true,
declaration: true,
entries: [
'src/index',
{
builder: 'mkdist',
input: './src/langs',
// loaders: ['postcss'],
outDir: './dist/langs',
},
],
});

View File

@@ -0,0 +1,52 @@
{
"name": "@vben-core/locales",
"version": "5.0.0",
"homepage": "https://github.com/vbenjs/vue-vben-admin",
"bugs": "https://github.com/vbenjs/vue-vben-admin/issues",
"repository": {
"type": "git",
"url": "git+https://github.com/vbenjs/vue-vben-admin.git",
"directory": "packages/@vben-core/forward/locales"
},
"license": "MIT",
"type": "module",
"scripts": {
"build": "pnpm unbuild",
"stub": "pnpm unbuild --stub"
},
"files": [
"dist"
],
"sideEffects": [
"**/*.css"
],
"main": "./dist/index.mjs",
"module": "./dist/index.mjs",
"exports": {
".": {
"types": "./src/index.ts",
"development": "./src/index.ts",
"default": "./dist/index.mjs"
},
"./langs/*": {
"default": "./dist/langs/*"
}
},
"publishConfig": {
"exports": {
".": {
"types": "./dist/index.d.ts",
"default": "./dist/index.mjs"
}
}
},
"peerDependencies": {
"vite": "latest"
},
"dependencies": {
"@intlify/core-base": "^9.13.1",
"@vben-core/typings": "workspace:*",
"vue": "^3.4.31",
"vue-i18n": "^9.13.1"
}
}

View File

@@ -0,0 +1,72 @@
import type { SupportedLanguagesType } from '@vben-core/typings';
import type { Locale } from 'vue-i18n';
import type { ImportLocaleFn } from './typing';
import { unref } from 'vue';
import { createI18n } from 'vue-i18n';
const loadedLanguages = new Set<string>();
// TODOimport.meta.env 和 import.meta.glob 是源码依赖会导致该包依赖外部项目必须是vite才可以
const i18n = createI18n({
globalInjection: true,
legacy: false,
locale: '',
messages: {},
missingWarn: import.meta.env.PROD,
silentFallbackWarn: !import.meta.env.PROD,
silentTranslationWarn: !import.meta.env.PROD, // true - warning off
});
const modules = import.meta.glob('./langs/*.y(a)?ml');
const localesMap = loadLocalesMap(modules);
/**
* Load locale modules
* @param modules
*/
function loadLocalesMap(modules: Record<string, () => Promise<unknown>>) {
const localesMap: Record<Locale, ImportLocaleFn> = {};
for (const [path, loadLocale] of Object.entries(modules)) {
const key = path.match(/([\w-]*)\.y(a)?ml/)?.[1];
if (key) {
localesMap[key] = loadLocale as ImportLocaleFn;
}
}
return localesMap;
}
/**
* Set i18n language
* @param locale
*/
function setI18nLanguage(locale: Locale) {
i18n.global.locale.value = locale;
document?.querySelector('html')?.setAttribute('lang', locale);
}
/**
* Load locale messages
* @param lang
*/
async function loadI18nMessages(lang: SupportedLanguagesType) {
if (unref(i18n.global.locale) === lang) {
return setI18nLanguage(lang);
}
if (loadedLanguages.has(lang)) {
return setI18nLanguage(lang);
}
const message = await localesMap[lang]();
i18n.global.setLocaleMessage(lang, message.default);
loadedLanguages.add(lang);
return setI18nLanguage(lang);
}
export { i18n, loadI18nMessages, loadLocalesMap, setI18nLanguage };

View File

@@ -0,0 +1,33 @@
import type {
ImportLocaleFn,
LoadMessageFn,
LocaleSetupOptions,
SupportedLanguagesType,
} from './typing';
import type { App } from 'vue';
import { i18n, loadI18nMessages, loadLocalesMap } from './i18n';
const $t = i18n.global.t;
let loadMessages: LoadMessageFn;
async function loadLocaleMessages(lang: SupportedLanguagesType) {
const mergeMessage = await loadMessages(lang);
await loadI18nMessages(lang);
i18n.global.mergeLocaleMessage(lang, mergeMessage);
}
async function setupI18n(app: App, options: LocaleSetupOptions = {}) {
const { defaultLocale = 'zh-CN' } = options;
// app可以自行扩展一些第三方库和组件库的国际化
loadMessages = options.loadMessages || (async () => ({}));
app.use(i18n);
await loadLocaleMessages(defaultLocale);
}
export { $t, loadLocaleMessages, loadLocalesMap, setupI18n };
export { useI18n } from 'vue-i18n';
export type { Locale } from 'vue-i18n';
export type { ImportLocaleFn };

View File

@@ -0,0 +1,234 @@
page:
essentials:
login: Login
register: Register
code-login: Code Login
qrcode-login: Qrcode Login
forget-password: Forget Password
dashboard:
title: Dashboard
analytics: Analytics
workspace: Workspace
vben:
about: About
document: Document
common:
back: Back
back-to-home: Back To Home
login: Login
logout: Logout
prompt: Prompt
cancel: Cancel
confirm: Comfirm
not-data: No data
refresh: Refresh
fallback:
page-not-found: Oops! Page Not Found
page-not-found-desc: Sorry, we couldn't find the page you were looking for.
forbidden: Oops! Access Denied
forbidden-desc: Sorry, but you don't have permission to access this page.
internal-error: Oops! Something Went Wrong
internal-error-desc: Sorry, but the server encountered an error.
offline: Offline Page
offline-error: Oops! Network Error
offline-error-desc: Sorry, can't connect to the internet. Check your connection.
coming-soon: Coming soon
widgets:
document: Document
qa: FAQ & Help
setting: Setting
logout-tip: Do you want to log out?
view-all: View all messages
notifications: Notifications
make-all-as-read: Make all as read
clear-notifications: Clear
search:
title: Search
search-navigate: Search Navigate
select: To select
navigate: To navigate
close: To close
no-results: No results for
no-recent: No recent searches
recent: Recent
authentication:
welcome-back: Welcome Back
page-title: Plug-and-play backend system
page-desc: Efficient, versatile frontend template
login-success: Login successful
login-success-desc: Welcome back
login-subtitle: Enter your account details to manage your projects
username: Username
password: Password
username-tip: Username is required
password-tip: Password is required
remember-me: Remember Me
create-an-account: Create an account
create-account: Create account
already-account: Already have an account?
account-tip: Don't have an account yet?
sign-up: Sign Up
sign-up-subtitle: Make managing your applications simple and fun
comfirm-password: Comfirm Password
comfirm-password-tip: The passwords entered twice do not match
sign-up-agree: I agree to
sign-up-privacy-policy: Privacy-policy
sign-up-terms: Terms
sign-up-agree-tip: Please agree to the Privacy Policy and Terms
go-login: Login instead
password-strength: Use 8 or more characters with a mix of letters, numbers & symbols
forget-password: Forget Password?
forget-password-subtitle: Enter your email and we'll send you instructions to reset your password
email-tip: Email is required
send-reset-link: Send Reset Link
email: Email
qrcode-subtitle: Please scan the QR code to log in on your mobile device
qrcode-prompt: Scanning the code to complete the login
qrcode-login: QR Login
code-subtitle: Please enter your phone number to start managing your projects
code: Security code
code-tip: Security code is required
mobile: Mobile
mobile-login: Mobile Login
mobile-tip: Mobile is required
send-code: Get Security code
send-text: "Reacquire in {0}s"
third-party-login: Or continue with
layout:
center: Align Center
align-left: Align Left
align-right: Align Right
preferences:
title: Preferences
subtitle: Customize Preferences & Preview in Real Time
reset-tip: The data has changed, click to reset
# appearance
appearance: Appearance
# layout
layout: Layout
content: Content
other: Other
wide: Fluid
compact: Fixed Width
follow-system: Follow System
vertical: Vertical
vertical-tip: Side Vertical Menu Mode
horizontal: Horizontal
horizontal-tip: Top Horizontal Menu
two-column: Two Column
two-column-tip: Vertical Two Column Menu Mode
mixed-menu: Mixed Menu
split-menu: Split Menu
mixed-menu-tip: Vertical & Horizontal Menu Co-exists
full-content: Full Content
full-content-tip: Display only the main content, no menus
weak-mode: Color Weak Mode
gray-mode: Gray Mode
normal: Normal
plain: Plain
rounded: Rounded
interface-control: Interface Layout Control
copy: Copy Preferences
copy-success: Copy successful. Please replace in `src/preferences.ts` of the app
clear-and-logout: Clear Cache & Logout
reset-success: Preferences reset successfully
mode: Mode
logo-visible: Display Logo
# general
general: General
language: Language
dynamic-title: Dynamic Title
ai-assistant: Ai Assistant
sidebar:
title: Sidebar
width: Width
visible: Display Sidebar
collapsed: Collpase Menu
collapsed-show-title: Display menu name
tabbar:
title: Tabbar
enable: Enable Tab Bar
icon: Display Tabbar Icon
context-menu:
reload: Reload
close: Close
pin: Pin
unpin: Unpin
close-left: Close Left
close-right: Close Right
close-other: Close Other
close-all: Close All
navigation-menu:
title: Navigation Menu
style: Navigation menu style
split: Navigation Menu Separation
accordion: Sidebar Navigation Menu Accordion mode
split-tip: When enabled, the sidebar shows the top bar's submenu
breadcrumb:
title: Breadcrumb
home: Display the home button
enable: Enable Breadcrumb
icon: Display breadcrumb icon
background: background
style: Breadcrumb Type
hide-only-one: Hidden when only one left
animation:
title: Animation
loading: Page transition loading
transition: Page transition animation
progress: Page transition progress
theme:
title: Theme
radius: Radius
light: Light
dark: Dark
dark-menu: Semi Dark Menu
weak-mode: Color Weak Mode
gray-mode: Gray Mode
builtin:
title: Built-in
default: Default
violet: Violet
pink: Pink
rose: Rose
sky-blue: Sky Blue
deep-blue: Deep Blue
green: Green
deep-green: Deep Green
orange: Orange
yellow: Yellow
zinc: Zinc
neutral: Neutral
slate: Slate
gray: Gray
custom: Custom
header:
title: Header
visible: Display Header
mode-static: Static
mode-fixed: Fixed
mode-auto: Auto hide/display
mode-auto-scroll: Scroll hide/display
footer:
title: Footer
visible: Display Footer
fixed: Fixed at the bottom
copyright:
title: Copyright
enable: Enable copyright
company-name: Company name
company-site-link: Company homepage
date: Date
icp: ICP number
icp-link: ICP Site Link
shortcut-keys:
title: Shortcut Keys
global: Global
search: Global Search
logout: Logout
preferences: Preferences

View File

@@ -0,0 +1,233 @@
page:
essentials:
login: 登陆
register: 注册
code-login: 验证码登陆
qrcode-login: 二维码登陆
forget-password: 忘记密码
dashboard:
title: 概览
analytics: 分析页
workspace: 工作台
vben:
about: 关于
document: 文档
common:
back: 返回
back-to-home: 返回首页
login: 登录
logout: 退出登录
prompt: 提示
cancel: 取消
confirm: 确认
not-data: 暂无数据
refresh: 刷新
loading-menu: 加载菜单中
fallback:
page-not-found: 哎呀!未找到页面
page-not-found-desc: 抱歉,我们无法找到您要找的页面。
forbidden: 哎呀!访问被拒绝
forbidden-desc: 抱歉,您没有权限访问此页面。
internal-error: 哎呀!出错了
internal-error-desc: 抱歉,服务器遇到错误。
offline: 离线页面
offline-error: 哎呀!网络错误
offline-error-desc: 抱歉,无法连接到互联网,请检查您的网络连接并重试。
coming-soon: 即将推出
widgets:
document: 文档
qa: 问题 & 帮助
setting: 设置
logout-tip: 是否退出登录?
view-all: 查看所有消息
notifications: 通知
make-all-as-read: 全部标记为已读
clear-notifications: 清空
search:
title: 搜索
search-navigate: 搜索导航菜单
select: 选择
navigate: 导航
close: 关闭
no-results: 未找到搜索结果
no-recent: 没有搜索历史
recent: 搜索历史
authentication:
welcome-back: 欢迎回来
page-title: 开箱即用的大型中后台管理系统
page-desc: 工程化、高性能、跨组件库的前端模版
login-success: 登录成功
login-success-desc: 欢迎回来
login-subtitle: 请输入您的帐户信息以开始管理您的项目
username: 账号
password: 密码
username-tip: 请输入用户名
password-tip: 请输入密码
remember-me: 记住账号
create-an-account: 创建一个账号
create-account: 创建账号
already-account: 已经有账号了?
account-tip: 还没有账号?
sign-up: 注册
sign-up-subtitle: 让您的应用程序管理变得简单而有趣
comfirm-password: 确认密码
comfirm-password-tip: 两次输入的密码不一致
sign-up-agree: 我同意
sign-up-privacy-policy: 隐私政策
sign-up-terms: 条款
sign-up-agree-tip: 请同意隐私政策和条款
go-login: 去登录
password-strength: 使用 8 个或更多字符,混合字母、数字和符号
forget-password: 忘记密码?
forget-password-subtitle: 输入您的电子邮件,我们将向您发送重置密码的连接
email-tip: 请输入邮箱
send-reset-link: 发送重置链接
email: 邮箱
qrcode-subtitle: 请用手机扫描二维码登录
qrcode-prompt: 扫码后点击 '确认',即可完成登录
qrcode-login: 扫码登录
code-subtitle: 请输入您的手机号码以开始管理您的项目
code: 验证码
code-tip: 请输入验证码
mobile: 手机号码
mobile-login: 手机号登录
mobile-tip: 请输入手机号码
send-code: 获取验证码
send-text: "{0}秒后重新获取"
third-party-login: 其他登录方式
layout:
center: 居中
align-left: 居左
align-right: 居右
preferences:
title: 偏好设置
subtitle: 自定义偏好设置 & 实时预览
reset-tip: 数据有变化,点击可进行重置
# appearance
appearance: 外观
# layout
layout: 布局
content: 内容
other: 其它
wide: 流式
compact: 定宽
follow-system: 跟随系统
vertical: 垂直
vertical-tip: 侧边垂直菜单模式
horizontal: 水平
horizontal-tip: 水平菜单模式,菜单全部显示在顶部
two-column: 双列菜单
two-column-tip: 垂直双列菜单模式
mixed-menu: 混合菜单
mixed-menu-tip: 垂直水平菜单共存
split-menu: 切割菜单
full-content: 内容全屏
full-content-tip: 不显示任何菜单,只显示内容主体
interface-control: 界面布局控制
normal: 默认
plain: 朴素
rounded: 圆润
copy: 复制偏好设置
copy-success: 拷贝成功,请在 app 下的 `src/preferences.ts`内进行覆盖
clear-and-logout: 清空缓存 & 退出登录
reset-success: 重置偏好设置成功
mode: 模式
logo-visible: 显示 Logo
# general
general: 通用
language: 语言
dynamic-title: 动态标题
ai-assistant: Ai 助手
sidebar:
title: 侧边栏
width: 宽度
visible: 显示侧边栏
collapsed: 折叠菜单
collapsed-show-title: 显示菜单名
tabbar:
title: 标签栏
enable: 启用标签栏
icon: 显示标签栏图标
context-menu:
reload: 重新加载
close: 关闭标签页
pin: 固定标签页
unpin: 取消固定标签页
close-left: 关闭左侧标签页
close-right: 关闭右侧标签页
close-other: 关闭其它标签页
close-all: 关闭全部标签页
navigation-menu:
title: 导航菜单
style: 导航菜单风格
accordion: 侧边导航菜单手风琴模式
split: 导航菜单分离
split-tip: 开启时,侧边栏显示顶栏对应菜单的子菜单
breadcrumb:
title: 面包屑导航
enable: 开启面包屑导航
icon: 显示面包屑图标
home: 显示首页按钮
style: 面包屑风格
hide-only-one: 仅有一个时隐藏
background: 背景
animation:
title: 动画
loading: 页面切换 Loading
transition: 页面切换动画
progress: 页面切换进度条
theme:
title: 主题
radius: 圆角
light: 浅色
dark: 深色
dark-menu: 深色菜单
weak-mode: 色弱模式
gray-mode: 灰色模式
builtin:
title: 内置主题
default: 默认
violet: 紫罗兰
pink: 樱花粉
rose: 玫瑰红
sky-blue: 天蓝色
deep-blue: 深蓝色
green: 浅绿色
deep-green: 深绿色
orange: 橙黄色
yellow: 柠檬黄
zinc: 锌色灰
neutral: 中性色
slate: 石板灰
gray: 中灰色
custom: 自定义
header:
title: 顶栏
mode-static: 静止
mode-fixed: 固定
mode-auto: 自动隐藏和显示
mode-auto-scroll: 滚动隐藏和显示
visible: 显示顶栏
footer:
title: 底栏
visible: 显示底栏
fixed: 固定在底部
copyright:
title: 版权
enable: 启用版权
company-name: 公司名
company-site-link: 公司主页
date: 日期
icp: ICP 备案号
icp-link: ICP 网站链接
shortcut-keys:
title: 快捷键
global: 全局
search: 全局搜索
logout: 退出登录
preferences: 偏好设置

View File

@@ -0,0 +1,28 @@
import type { SupportedLanguagesType } from '@vben-core/typings';
type ImportLocaleFn = () => Promise<{ default: Record<string, string> }>;
type LoadMessageFn = (
lang: SupportedLanguagesType,
) => Promise<Record<string, string>>;
interface LocaleSetupOptions {
/**
* Default language
* @default zh-CN
*/
defaultLocale?: SupportedLanguagesType;
/**
* Load message function
* @param lang
* @returns
*/
loadMessages?: LoadMessageFn;
}
export type {
ImportLocaleFn,
LoadMessageFn,
LocaleSetupOptions,
SupportedLanguagesType,
};

View File

@@ -0,0 +1,6 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"extends": "@vben/tsconfig/web.json",
"include": ["src"],
"exclude": ["node_modules"]
}