chore: restructure project and add i18n support
- Reorganize project structure with new electron and shared directories - Add comprehensive i18n support with Chinese, English, and Japanese locales - Update build configurations and TypeScript paths for new structure - Add various UI components including chat interface and task management - Include Windows release binaries and localization files - Update dependencies and fix import paths throughout the codebase
This commit is contained in:
23
src/i18n/constants.ts
Normal file
23
src/i18n/constants.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
export const SUPPORTED_LANGUAGE_CODES = ['en', 'zh', 'ja'] as const;
|
||||
export type LanguageCode = (typeof SUPPORTED_LANGUAGE_CODES)[number];
|
||||
|
||||
export const SUPPORTED_LANGUAGES = [
|
||||
{ code: 'en', label: 'English' },
|
||||
{ code: 'zh', label: '中文' },
|
||||
{ code: 'ja', label: '日本語' },
|
||||
] as const;
|
||||
|
||||
// 命名空间定义
|
||||
export const NAMESPACES = [
|
||||
'common',
|
||||
'conversation',
|
||||
'setting',
|
||||
'menu',
|
||||
'login',
|
||||
'dashboard',
|
||||
'task',
|
||||
'rate',
|
||||
'knowledge',
|
||||
'component',
|
||||
] as const;
|
||||
export type Namespace = (typeof NAMESPACES)[number];
|
||||
106
src/i18n/index.ts
Normal file
106
src/i18n/index.ts
Normal file
@@ -0,0 +1,106 @@
|
||||
import { createI18n, type I18n, type I18nOptions } from 'vue-i18n';
|
||||
import { SUPPORTED_LANGUAGE_CODES, SUPPORTED_LANGUAGES, NAMESPACES, type LanguageCode } from './constants';
|
||||
import { resolveSupportedLanguage, detectSystemLanguage } from './resolver';
|
||||
|
||||
// 使用 import.meta.glob 动态加载所有语言文件
|
||||
// 文件路径模式:./locales/{语言}/{命名空间}.json
|
||||
const modules = import.meta.glob('./locales/*/*.json', { eager: true });
|
||||
|
||||
// 构建 vue-i18n 格式的资源对象:{ [locale]: { [namespace]: messages } }
|
||||
function buildResources() {
|
||||
const resources: Record<string, Record<string, any>> = {};
|
||||
|
||||
// 初始化每种语言的空对象
|
||||
SUPPORTED_LANGUAGE_CODES.forEach(lang => {
|
||||
resources[lang] = {};
|
||||
});
|
||||
|
||||
// 遍历所有模块,按语言和命名空间组织
|
||||
for (const [path, module] of Object.entries(modules)) {
|
||||
// 路径示例:'./locales/en/common.json'
|
||||
const match = path.match(/\.\/locales\/([a-z]{2})\/([a-z]+)\.json$/);
|
||||
if (!match) continue;
|
||||
|
||||
const [, lang, namespace] = match;
|
||||
if (!SUPPORTED_LANGUAGE_CODES.includes(lang as LanguageCode) || !NAMESPACES.includes(namespace as any)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// @ts-expect-error: module 可能是 Module 类型
|
||||
const messages = (module as any).default || module;
|
||||
resources[lang][namespace] = messages;
|
||||
}
|
||||
|
||||
return resources;
|
||||
}
|
||||
|
||||
// 获取持久化的语言设置(稍后由 Pinia store 提供)
|
||||
function getPersistedLanguage(): LanguageCode | null {
|
||||
try {
|
||||
const saved = localStorage.getItem('diona-language');
|
||||
return saved && SUPPORTED_LANGUAGE_CODES.includes(saved as LanguageCode) ? saved as LanguageCode : null;
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// 确定初始语言:持久化设置 > 系统语言 > 默认中文
|
||||
function determineInitialLocale(): LanguageCode {
|
||||
const persisted = getPersistedLanguage();
|
||||
if (persisted) return persisted;
|
||||
|
||||
const systemLang = detectSystemLanguage();
|
||||
return systemLang;
|
||||
}
|
||||
|
||||
async function createI18nInstance() {
|
||||
const resources = buildResources();
|
||||
const initialLocale = determineInitialLocale();
|
||||
|
||||
const options: I18nOptions = {
|
||||
legacy: false,
|
||||
locale: initialLocale,
|
||||
fallbackLocale: 'zh',
|
||||
messages: resources, // 使用构建的资源对象
|
||||
availableLocales: SUPPORTED_LANGUAGE_CODES,
|
||||
fallbackFormat: true,
|
||||
datetimeFormats: {},
|
||||
numberFormats: {},
|
||||
};
|
||||
|
||||
const i18n = createI18n(options);
|
||||
return i18n;
|
||||
}
|
||||
|
||||
// 创建 i18n 实例
|
||||
export const i18n = await createI18nInstance();
|
||||
|
||||
// 兼容性 API
|
||||
export async function setLanguage(lang: LanguageCode, _i18n?: I18n) {
|
||||
const __i18n = _i18n ?? i18n;
|
||||
|
||||
if (__i18n.mode === 'legacy') {
|
||||
__i18n.global.locale = lang;
|
||||
return;
|
||||
}
|
||||
|
||||
(__i18n.global.locale as unknown as { value: LanguageCode }).value = lang;
|
||||
|
||||
// 持久化到 localStorage(稍后由 Pinia store 处理)
|
||||
try {
|
||||
localStorage.setItem('diona-language', lang);
|
||||
} catch {}
|
||||
}
|
||||
|
||||
export function getLanguage() {
|
||||
if (i18n.mode === 'legacy') {
|
||||
return i18n.global.locale;
|
||||
}
|
||||
|
||||
return (i18n.global.locale as unknown as { value: LanguageCode }).value;
|
||||
}
|
||||
|
||||
// 导出类型和常量
|
||||
export type { LanguageCode };
|
||||
export { SUPPORTED_LANGUAGE_CODES, SUPPORTED_LANGUAGES, NAMESPACES };
|
||||
export default i18n;
|
||||
143
src/i18n/locales/en.json
Normal file
143
src/i18n/locales/en.json
Normal file
@@ -0,0 +1,143 @@
|
||||
{
|
||||
"window": {
|
||||
"minimize": "Minimize",
|
||||
"maximize": "Maximize",
|
||||
"restore": "Restore",
|
||||
"close": "Close"
|
||||
},
|
||||
"main": {
|
||||
"welcome": {
|
||||
"helloMessage": "Hello, I'm Diona"
|
||||
},
|
||||
"conversation": {
|
||||
"placeholder": "Type a message...",
|
||||
"newConversation": "New Conversation",
|
||||
"selectModel": "Please select model",
|
||||
"createConversation": "Create Conversation",
|
||||
"searchPlaceholder": "Search conversations...",
|
||||
"goSettings": "Go to",
|
||||
"settings": "Settings Window",
|
||||
"addModel": "to add a model",
|
||||
"dialog": {
|
||||
"title": "Confirm Deletion",
|
||||
"content": "Are you sure you want to delete this conversation?",
|
||||
"content_1": "Are you sure you want to delete the selected conversations? This action cannot be undone."
|
||||
},
|
||||
"operations": {
|
||||
"pin": "Pin Selected",
|
||||
"del": "Delete Selected",
|
||||
"selectAll": "Select All",
|
||||
"cancel": "Cancel"
|
||||
}
|
||||
},
|
||||
"sidebar": {
|
||||
"conversations": "Conversations",
|
||||
"settings": "Settings",
|
||||
"help": "Help"
|
||||
},
|
||||
"message": {
|
||||
"dialog": {
|
||||
"title": "Confirm Deletion",
|
||||
"messageDelete": "Are you sure you want to delete this message?",
|
||||
"batchDelete": "Are you sure you want to delete the selected messages?",
|
||||
"copySuccess": "Copied successfully"
|
||||
},
|
||||
"batchActions": {
|
||||
"deleteSelected": "Delete Selected"
|
||||
},
|
||||
"rendering": "Thinking...",
|
||||
"stoppedGeneration": "(Stopped generating)",
|
||||
"sending": "Sending",
|
||||
"stopGeneration": "Stop generating",
|
||||
"send": "Send"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"cancel": "Cancel",
|
||||
"confirm": "Confirm"
|
||||
},
|
||||
"settings": {
|
||||
"title": "Settings",
|
||||
"base": "Basic Settings",
|
||||
"provider": {
|
||||
"modelConfig": "Model Configuration"
|
||||
},
|
||||
"theme": {
|
||||
"label": "Theme Settings",
|
||||
"dark": "Dark Theme",
|
||||
"light": "Light Theme",
|
||||
"system": "System Theme",
|
||||
"primaryColor": "Primary Color"
|
||||
},
|
||||
"appearance": {
|
||||
"fontSize": "Font Size",
|
||||
"fontSizeOptions": {
|
||||
"10": "Tiny (10px)",
|
||||
"12": "Small (12px)",
|
||||
"14": "Normal (14px)",
|
||||
"16": "Medium (16px)",
|
||||
"18": "Large (18px)",
|
||||
"20": "Larger (20px)",
|
||||
"24": "Extra Large (24px)"
|
||||
}
|
||||
},
|
||||
"behavior": {
|
||||
"minimizeToTray": "Minimize to tray when closed"
|
||||
},
|
||||
"language": {
|
||||
"label": "Language"
|
||||
},
|
||||
"providers": {
|
||||
"defaultModel": "Default Model",
|
||||
"apiKey": "API Key",
|
||||
"apiUrl": "API URL"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"conversation": {
|
||||
"newConversation": "New Conversation",
|
||||
"sortBy": "Sort By",
|
||||
"sortByCreateTime": "Sort by Creation Time",
|
||||
"sortByUpdateTime": "Sort by Update Time",
|
||||
"sortByName": "Sort by Name",
|
||||
"sortByModel": "Sort by Model",
|
||||
"sortAscending": "Ascending",
|
||||
"sortDescending": "Descending",
|
||||
"pinConversation": "Pin Conversation",
|
||||
"unpinConversation": "Unpin Conversation",
|
||||
"renameConversation": "Rename Conversation",
|
||||
"delConversation": "Delete Conversation",
|
||||
"batchOperations": "Batch Operations"
|
||||
},
|
||||
"message": {
|
||||
"copyMessage": "Copy Message",
|
||||
"deleteMessage": "Delete Message",
|
||||
"selectMessage": "Select Message"
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"tooltip": "Diona Application",
|
||||
"showWindow": "Show Window",
|
||||
"exit": "Exit"
|
||||
},
|
||||
"timeAgo": {
|
||||
"justNow": "Just now",
|
||||
"minutes": "{count} minutes ago",
|
||||
"hours": "{count} hours ago",
|
||||
"days": "{count} days ago",
|
||||
"months": "{count} months ago",
|
||||
"years": "{count} years ago",
|
||||
"weekday": {
|
||||
"sun": "Sunday",
|
||||
"mon": "Monday",
|
||||
"tue": "Tuesday",
|
||||
"wed": "Wednesday",
|
||||
"thu": "Thursday",
|
||||
"fri": "Friday",
|
||||
"sat": "Saturday"
|
||||
}
|
||||
},
|
||||
"app": {
|
||||
"title": "Diona Application"
|
||||
}
|
||||
}
|
||||
37
src/i18n/locales/en/common.json
Normal file
37
src/i18n/locales/en/common.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"window": {
|
||||
"minimize": "Minimize",
|
||||
"maximize": "Maximize",
|
||||
"restore": "Restore",
|
||||
"close": "Close"
|
||||
},
|
||||
"dialog": {
|
||||
"cancel": "Cancel",
|
||||
"confirm": "Confirm"
|
||||
},
|
||||
"tray": {
|
||||
"tooltip": "Diona Application",
|
||||
"showWindow": "Show Window",
|
||||
"exit": "Exit"
|
||||
},
|
||||
"timeAgo": {
|
||||
"justNow": "Just now",
|
||||
"minutes": "{count} minutes ago",
|
||||
"hours": "{count} hours ago",
|
||||
"days": "{count} days ago",
|
||||
"months": "{count} months ago",
|
||||
"years": "{count} years ago",
|
||||
"weekday": {
|
||||
"sun": "Sunday",
|
||||
"mon": "Monday",
|
||||
"tue": "Tuesday",
|
||||
"wed": "Wednesday",
|
||||
"thu": "Thursday",
|
||||
"fri": "Friday",
|
||||
"sat": "Saturday"
|
||||
}
|
||||
},
|
||||
"app": {
|
||||
"title": "Diona Application"
|
||||
}
|
||||
}
|
||||
1
src/i18n/locales/en/component.json
Normal file
1
src/i18n/locales/en/component.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
47
src/i18n/locales/en/conversation.json
Normal file
47
src/i18n/locales/en/conversation.json
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"welcome": {
|
||||
"helloMessage": "Hello, I'm Diona"
|
||||
},
|
||||
"conversation": {
|
||||
"placeholder": "Type a message...",
|
||||
"newConversation": "New Conversation",
|
||||
"selectModel": "Please select model",
|
||||
"createConversation": "Create Conversation",
|
||||
"searchPlaceholder": "Search conversations...",
|
||||
"goSettings": "Go to",
|
||||
"settings": "Settings Window",
|
||||
"addModel": "to add a model",
|
||||
"dialog": {
|
||||
"title": "Confirm Deletion",
|
||||
"content": "Are you sure you want to delete this conversation?",
|
||||
"content_1": "Are you sure you want to delete the selected conversations? This action cannot be undone."
|
||||
},
|
||||
"operations": {
|
||||
"pin": "Pin Selected",
|
||||
"del": "Delete Selected",
|
||||
"selectAll": "Select All",
|
||||
"cancel": "Cancel"
|
||||
}
|
||||
},
|
||||
"sidebar": {
|
||||
"conversations": "Conversations",
|
||||
"settings": "Settings",
|
||||
"help": "Help"
|
||||
},
|
||||
"message": {
|
||||
"dialog": {
|
||||
"title": "Confirm Deletion",
|
||||
"messageDelete": "Are you sure you want to delete this message?",
|
||||
"batchDelete": "Are you sure you want to delete the selected messages?",
|
||||
"copySuccess": "Copied successfully"
|
||||
},
|
||||
"batchActions": {
|
||||
"deleteSelected": "Delete Selected"
|
||||
},
|
||||
"rendering": "Thinking...",
|
||||
"stoppedGeneration": "(Stopped generating)",
|
||||
"sending": "Sending",
|
||||
"stopGeneration": "Stop generating",
|
||||
"send": "Send"
|
||||
}
|
||||
}
|
||||
1
src/i18n/locales/en/dashboard.json
Normal file
1
src/i18n/locales/en/dashboard.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
src/i18n/locales/en/knowledge.json
Normal file
1
src/i18n/locales/en/knowledge.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
20
src/i18n/locales/en/login.json
Normal file
20
src/i18n/locales/en/login.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"title": "Login",
|
||||
"subtitle": "24/7 digital employee, never closed",
|
||||
"username": "Username",
|
||||
"usernamePlaceholder": "Please enter username",
|
||||
"password": "Password",
|
||||
"passwordPlaceholder": "Please enter password",
|
||||
"code": "Verification Code",
|
||||
"codePlaceholder": "Please enter verification code",
|
||||
"loginButton": "Login",
|
||||
"rememberPassword": "Remember password",
|
||||
"forgotPassword": "Forgot password?",
|
||||
"agreeTerms": "I agree to the",
|
||||
"termsOfUse": "Terms of Use",
|
||||
"privacyPolicy": "Privacy Policy",
|
||||
"and": "and",
|
||||
"usernameRequired": "Please enter username",
|
||||
"passwordRequired": "Please enter password",
|
||||
"codeRequired": "Please enter verification code"
|
||||
}
|
||||
22
src/i18n/locales/en/menu.json
Normal file
22
src/i18n/locales/en/menu.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"conversation": {
|
||||
"newConversation": "New Conversation",
|
||||
"sortBy": "Sort By",
|
||||
"sortByCreateTime": "Sort by Creation Time",
|
||||
"sortByUpdateTime": "Sort by Update Time",
|
||||
"sortByName": "Sort by Name",
|
||||
"sortByModel": "Sort by Model",
|
||||
"sortAscending": "Ascending",
|
||||
"sortDescending": "Descending",
|
||||
"pinConversation": "Pin Conversation",
|
||||
"unpinConversation": "Unpin Conversation",
|
||||
"renameConversation": "Rename Conversation",
|
||||
"delConversation": "Delete Conversation",
|
||||
"batchOperations": "Batch Operations"
|
||||
},
|
||||
"message": {
|
||||
"copyMessage": "Copy Message",
|
||||
"deleteMessage": "Delete Message",
|
||||
"selectMessage": "Select Message"
|
||||
}
|
||||
}
|
||||
1
src/i18n/locales/en/rate.json
Normal file
1
src/i18n/locales/en/rate.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
37
src/i18n/locales/en/setting.json
Normal file
37
src/i18n/locales/en/setting.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"title": "Settings",
|
||||
"base": "Basic Settings",
|
||||
"provider": {
|
||||
"modelConfig": "Model Configuration"
|
||||
},
|
||||
"theme": {
|
||||
"label": "Theme Settings",
|
||||
"dark": "Dark Theme",
|
||||
"light": "Light Theme",
|
||||
"system": "System Theme",
|
||||
"primaryColor": "Primary Color"
|
||||
},
|
||||
"appearance": {
|
||||
"fontSize": "Font Size",
|
||||
"fontSizeOptions": {
|
||||
"10": "Tiny (10px)",
|
||||
"12": "Small (12px)",
|
||||
"14": "Normal (14px)",
|
||||
"16": "Medium (16px)",
|
||||
"18": "Large (18px)",
|
||||
"20": "Larger (20px)",
|
||||
"24": "Extra Large (24px)"
|
||||
}
|
||||
},
|
||||
"behavior": {
|
||||
"minimizeToTray": "Minimize to tray when closed"
|
||||
},
|
||||
"language": {
|
||||
"label": "Language"
|
||||
},
|
||||
"providers": {
|
||||
"defaultModel": "Default Model",
|
||||
"apiKey": "API Key",
|
||||
"apiUrl": "API URL"
|
||||
}
|
||||
}
|
||||
1
src/i18n/locales/en/task.json
Normal file
1
src/i18n/locales/en/task.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
src/i18n/locales/ja.json
Normal file
1
src/i18n/locales/ja.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
src/i18n/locales/ja/common.json
Normal file
1
src/i18n/locales/ja/common.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
src/i18n/locales/ja/component.json
Normal file
1
src/i18n/locales/ja/component.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
src/i18n/locales/ja/conversation.json
Normal file
1
src/i18n/locales/ja/conversation.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
src/i18n/locales/ja/dashboard.json
Normal file
1
src/i18n/locales/ja/dashboard.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
src/i18n/locales/ja/knowledge.json
Normal file
1
src/i18n/locales/ja/knowledge.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
src/i18n/locales/ja/login.json
Normal file
1
src/i18n/locales/ja/login.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
src/i18n/locales/ja/menu.json
Normal file
1
src/i18n/locales/ja/menu.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
src/i18n/locales/ja/rate.json
Normal file
1
src/i18n/locales/ja/rate.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
src/i18n/locales/ja/setting.json
Normal file
1
src/i18n/locales/ja/setting.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
src/i18n/locales/ja/task.json
Normal file
1
src/i18n/locales/ja/task.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
143
src/i18n/locales/zh.json
Normal file
143
src/i18n/locales/zh.json
Normal file
@@ -0,0 +1,143 @@
|
||||
{
|
||||
"window": {
|
||||
"minimize": "最小化",
|
||||
"maximize": "最大化",
|
||||
"restore": "还原",
|
||||
"close": "关闭"
|
||||
},
|
||||
"main": {
|
||||
"welcome": {
|
||||
"helloMessage": "你好,我是迪奥娜"
|
||||
},
|
||||
"conversation": {
|
||||
"placeholder": "输入消息...",
|
||||
"newConversation": "新对话",
|
||||
"selectModel": "请选择模型",
|
||||
"createConversation": "创建对话",
|
||||
"searchPlaceholder": "搜索对话...",
|
||||
"goSettings": "快去",
|
||||
"settings": "设置窗口",
|
||||
"addModel": "添加模型",
|
||||
"dialog": {
|
||||
"title": "确认删除",
|
||||
"content": "确定要删除这个对话吗?",
|
||||
"content_1": "确定要删除选中的对话吗?此操作不可撤销。"
|
||||
},
|
||||
"operations": {
|
||||
"pin": "置顶所选",
|
||||
"del": "删除所选",
|
||||
"selectAll": "全选",
|
||||
"cancel": "取消"
|
||||
}
|
||||
},
|
||||
"sidebar": {
|
||||
"conversations": "对话",
|
||||
"settings": "设置",
|
||||
"help": "帮助"
|
||||
},
|
||||
"message": {
|
||||
"dialog": {
|
||||
"title": "确认删除",
|
||||
"messageDelete": "确认删除该条消息?",
|
||||
"batchDelete": "确认删除选中的消息?",
|
||||
"copySuccess": "复制成功"
|
||||
},
|
||||
"batchActions": {
|
||||
"deleteSelected": "删除选中项"
|
||||
},
|
||||
"rendering": "思考中...",
|
||||
"stoppedGeneration": "(已停止生成)",
|
||||
"sending": "发送中",
|
||||
"stopGeneration": "停止生成",
|
||||
"send": "发送"
|
||||
}
|
||||
},
|
||||
"dialog": {
|
||||
"cancel": "取消",
|
||||
"confirm": "确认"
|
||||
},
|
||||
"settings": {
|
||||
"title": "设置",
|
||||
"base": "基础设置",
|
||||
"provider": {
|
||||
"modelConfig": "模型配置"
|
||||
},
|
||||
"providers": {
|
||||
"defaultModel": "默认模型",
|
||||
"apiKey": "API密钥",
|
||||
"apiUrl": "API地址"
|
||||
},
|
||||
"theme": {
|
||||
"label": "主题设置",
|
||||
"dark": "深色主题",
|
||||
"light": "浅色主题",
|
||||
"system": "跟随系统",
|
||||
"primaryColor": "主题颜色"
|
||||
},
|
||||
"appearance": {
|
||||
"fontSize": "字体大小",
|
||||
"fontSizeOptions": {
|
||||
"10": "极小 (10px)",
|
||||
"12": "小 (12px)",
|
||||
"14": "正常 (14px)",
|
||||
"16": "中 (16px)",
|
||||
"18": "大 (18px)",
|
||||
"20": "较大 (20px)",
|
||||
"24": "超大 (24px)"
|
||||
}
|
||||
},
|
||||
"behavior": {
|
||||
"minimizeToTray": "关闭时最小化到托盘"
|
||||
},
|
||||
"language": {
|
||||
"label": "语言设置"
|
||||
}
|
||||
},
|
||||
"menu": {
|
||||
"conversation": {
|
||||
"newConversation": "新建对话",
|
||||
"sortBy": "排序方式",
|
||||
"sortByCreateTime": "按创建时间排序",
|
||||
"sortByUpdateTime": "按更新时间排序",
|
||||
"sortByName": "按名称排序",
|
||||
"sortByModel": "按模型排序",
|
||||
"sortAscending": "递增",
|
||||
"sortDescending": "递减",
|
||||
"pinConversation": "置顶对话",
|
||||
"unpinConversation": "取消置顶",
|
||||
"renameConversation": "重命名对话",
|
||||
"delConversation": "删除对话",
|
||||
"batchOperations": "批量操作"
|
||||
},
|
||||
"message": {
|
||||
"copyMessage": "复制消息",
|
||||
"deleteMessage": "删除消息",
|
||||
"selectMessage": "选择消息"
|
||||
}
|
||||
},
|
||||
"tray": {
|
||||
"tooltip": "迪奥娜",
|
||||
"showWindow": "显示窗口",
|
||||
"exit": "退出"
|
||||
},
|
||||
"timeAgo": {
|
||||
"justNow": "刚刚",
|
||||
"minutes": "{count}分钟前",
|
||||
"hours": "{count}小时前",
|
||||
"days": "{count}天前",
|
||||
"months": "{count}个月前",
|
||||
"years": "{count}年前",
|
||||
"weekday": {
|
||||
"sun": "星期日",
|
||||
"mon": "星期一",
|
||||
"tue": "星期二",
|
||||
"wed": "星期三",
|
||||
"thu": "星期四",
|
||||
"fri": "星期五",
|
||||
"sat": "星期六"
|
||||
}
|
||||
},
|
||||
"app": {
|
||||
"title": "迪奥娜"
|
||||
}
|
||||
}
|
||||
37
src/i18n/locales/zh/common.json
Normal file
37
src/i18n/locales/zh/common.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"window": {
|
||||
"minimize": "最小化",
|
||||
"maximize": "最大化",
|
||||
"restore": "还原",
|
||||
"close": "关闭"
|
||||
},
|
||||
"dialog": {
|
||||
"cancel": "取消",
|
||||
"confirm": "确认"
|
||||
},
|
||||
"tray": {
|
||||
"tooltip": "迪奥娜",
|
||||
"showWindow": "显示窗口",
|
||||
"exit": "退出"
|
||||
},
|
||||
"timeAgo": {
|
||||
"justNow": "刚刚",
|
||||
"minutes": "{count}分钟前",
|
||||
"hours": "{count}小时前",
|
||||
"days": "{count}天前",
|
||||
"months": "{count}个月前",
|
||||
"years": "{count}年前",
|
||||
"weekday": {
|
||||
"sun": "星期日",
|
||||
"mon": "星期一",
|
||||
"tue": "星期二",
|
||||
"wed": "星期三",
|
||||
"thu": "星期四",
|
||||
"fri": "星期五",
|
||||
"sat": "星期六"
|
||||
}
|
||||
},
|
||||
"app": {
|
||||
"title": "迪奥娜"
|
||||
}
|
||||
}
|
||||
1
src/i18n/locales/zh/component.json
Normal file
1
src/i18n/locales/zh/component.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
47
src/i18n/locales/zh/conversation.json
Normal file
47
src/i18n/locales/zh/conversation.json
Normal file
@@ -0,0 +1,47 @@
|
||||
{
|
||||
"welcome": {
|
||||
"helloMessage": "你好,我是迪奥娜"
|
||||
},
|
||||
"conversation": {
|
||||
"placeholder": "输入消息...",
|
||||
"newConversation": "新对话",
|
||||
"selectModel": "请选择模型",
|
||||
"createConversation": "创建对话",
|
||||
"searchPlaceholder": "搜索对话...",
|
||||
"goSettings": "快去",
|
||||
"settings": "设置窗口",
|
||||
"addModel": "添加模型",
|
||||
"dialog": {
|
||||
"title": "确认删除",
|
||||
"content": "确定要删除这个对话吗?",
|
||||
"content_1": "确定要删除选中的对话吗?此操作不可撤销。"
|
||||
},
|
||||
"operations": {
|
||||
"pin": "置顶所选",
|
||||
"del": "删除所选",
|
||||
"selectAll": "全选",
|
||||
"cancel": "取消"
|
||||
}
|
||||
},
|
||||
"sidebar": {
|
||||
"conversations": "对话",
|
||||
"settings": "设置",
|
||||
"help": "帮助"
|
||||
},
|
||||
"message": {
|
||||
"dialog": {
|
||||
"title": "确认删除",
|
||||
"messageDelete": "确认删除该条消息?",
|
||||
"batchDelete": "确认删除选中的消息?",
|
||||
"copySuccess": "复制成功"
|
||||
},
|
||||
"batchActions": {
|
||||
"deleteSelected": "删除选中项"
|
||||
},
|
||||
"rendering": "思考中...",
|
||||
"stoppedGeneration": "(已停止生成)",
|
||||
"sending": "发送中",
|
||||
"stopGeneration": "停止生成",
|
||||
"send": "发送"
|
||||
}
|
||||
}
|
||||
1
src/i18n/locales/zh/dashboard.json
Normal file
1
src/i18n/locales/zh/dashboard.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
1
src/i18n/locales/zh/knowledge.json
Normal file
1
src/i18n/locales/zh/knowledge.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
20
src/i18n/locales/zh/login.json
Normal file
20
src/i18n/locales/zh/login.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"title": "登录",
|
||||
"subtitle": "24小时在岗,从不打烊的数字员工",
|
||||
"username": "账号",
|
||||
"usernamePlaceholder": "请输入账号",
|
||||
"password": "密码",
|
||||
"passwordPlaceholder": "请输入密码",
|
||||
"code": "验证码",
|
||||
"codePlaceholder": "请输入验证码",
|
||||
"loginButton": "登 录",
|
||||
"rememberPassword": "记住密码",
|
||||
"forgotPassword": "忘记密码?",
|
||||
"agreeTerms": "我已同意",
|
||||
"termsOfUse": "《使用协议》",
|
||||
"privacyPolicy": "《隐私协议》",
|
||||
"and": "和",
|
||||
"usernameRequired": "请输入账号",
|
||||
"passwordRequired": "请输入密码",
|
||||
"codeRequired": "请输入验证码"
|
||||
}
|
||||
22
src/i18n/locales/zh/menu.json
Normal file
22
src/i18n/locales/zh/menu.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"conversation": {
|
||||
"newConversation": "新建对话",
|
||||
"sortBy": "排序方式",
|
||||
"sortByCreateTime": "按创建时间排序",
|
||||
"sortByUpdateTime": "按更新时间排序",
|
||||
"sortByName": "按名称排序",
|
||||
"sortByModel": "按模型排序",
|
||||
"sortAscending": "递增",
|
||||
"sortDescending": "递减",
|
||||
"pinConversation": "置顶对话",
|
||||
"unpinConversation": "取消置顶",
|
||||
"renameConversation": "重命名对话",
|
||||
"delConversation": "删除对话",
|
||||
"batchOperations": "批量操作"
|
||||
},
|
||||
"message": {
|
||||
"copyMessage": "复制消息",
|
||||
"deleteMessage": "删除消息",
|
||||
"selectMessage": "选择消息"
|
||||
}
|
||||
}
|
||||
1
src/i18n/locales/zh/rate.json
Normal file
1
src/i18n/locales/zh/rate.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
37
src/i18n/locales/zh/setting.json
Normal file
37
src/i18n/locales/zh/setting.json
Normal file
@@ -0,0 +1,37 @@
|
||||
{
|
||||
"title": "设置",
|
||||
"base": "基础设置",
|
||||
"provider": {
|
||||
"modelConfig": "模型配置"
|
||||
},
|
||||
"theme": {
|
||||
"label": "主题设置",
|
||||
"dark": "深色主题",
|
||||
"light": "浅色主题",
|
||||
"system": "跟随系统",
|
||||
"primaryColor": "主题颜色"
|
||||
},
|
||||
"appearance": {
|
||||
"fontSize": "字体大小",
|
||||
"fontSizeOptions": {
|
||||
"10": "极小 (10px)",
|
||||
"12": "小 (12px)",
|
||||
"14": "正常 (14px)",
|
||||
"16": "中 (16px)",
|
||||
"18": "大 (18px)",
|
||||
"20": "较大 (20px)",
|
||||
"24": "超大 (24px)"
|
||||
}
|
||||
},
|
||||
"behavior": {
|
||||
"minimizeToTray": "关闭时最小化到托盘"
|
||||
},
|
||||
"language": {
|
||||
"label": "语言设置"
|
||||
},
|
||||
"providers": {
|
||||
"defaultModel": "默认模型",
|
||||
"apiKey": "API密钥",
|
||||
"apiUrl": "API地址"
|
||||
}
|
||||
}
|
||||
1
src/i18n/locales/zh/task.json
Normal file
1
src/i18n/locales/zh/task.json
Normal file
@@ -0,0 +1 @@
|
||||
{}
|
||||
38
src/i18n/resolver.ts
Normal file
38
src/i18n/resolver.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { SUPPORTED_LANGUAGE_CODES, type LanguageCode } from './constants';
|
||||
|
||||
// 创建语言代码集合用于快速查找
|
||||
const SUPPORTED_LANGUAGE_CODE_SET = new Set<string>(SUPPORTED_LANGUAGE_CODES);
|
||||
|
||||
/**
|
||||
* 标准化语言代码(处理 zh-CN、zh_TW 等变体)
|
||||
*/
|
||||
export function normalizeLocale(locale: string | null | undefined): string {
|
||||
return locale?.trim().toLowerCase().replaceAll('_', '-') ?? '';
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析支持的语言代码
|
||||
* @param locale 原始语言代码(如 'zh-CN', 'en-US')
|
||||
* @param fallback 回退语言代码,默认为 'zh'
|
||||
* @returns 支持的语言代码
|
||||
*/
|
||||
export function resolveSupportedLanguage(
|
||||
locale: string | null | undefined,
|
||||
fallback: LanguageCode = 'zh',
|
||||
): LanguageCode {
|
||||
const normalizedLocale = normalizeLocale(locale);
|
||||
if (!normalizedLocale) return fallback;
|
||||
|
||||
const [baseLanguage] = normalizedLocale.split('-');
|
||||
return SUPPORTED_LANGUAGE_CODE_SET.has(baseLanguage)
|
||||
? (baseLanguage as LanguageCode)
|
||||
: fallback;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检测系统语言
|
||||
*/
|
||||
export function detectSystemLanguage(): LanguageCode {
|
||||
if (typeof navigator === 'undefined') return 'zh';
|
||||
return resolveSupportedLanguage(navigator.language);
|
||||
}
|
||||
Reference in New Issue
Block a user