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:
duanshuwen
2026-04-06 14:39:06 +08:00
parent e76b034d50
commit 6615d11dd6
311 changed files with 823682 additions and 4460 deletions

129
src/store/locale.ts Normal file
View File

@@ -0,0 +1,129 @@
import { defineStore } from 'pinia';
import { i18n, setLanguage, getLanguage, type LanguageCode } from '@src/i18n';
import { SUPPORTED_LANGUAGES, SUPPORTED_LANGUAGE_CODES } from '@src/i18n/constants';
import { resolveSupportedLanguage, detectSystemLanguage } from '@src/i18n/resolver';
// 持久化键
const STORAGE_KEY = 'diona-language';
interface LocaleState {
language: LanguageCode;
initialized: boolean;
}
export const useLocaleStore = defineStore('locale', {
state: (): LocaleState => ({
language: 'zh',
initialized: false,
}),
getters: {
currentLanguage: (state) => state.language,
isChinese: (state) => state.language === 'zh',
isEnglish: (state) => state.language === 'en',
isJapanese: (state) => state.language === 'ja',
languageLabel: (state) => {
const lang = SUPPORTED_LANGUAGES.find(l => l.code === state.language);
return lang?.label || '中文';
},
},
actions: {
/**
* 初始化语言设置
* 优先级:持久化设置 > 系统语言 > 默认中文
*/
async init() {
if (this.initialized) return;
try {
// 1. 尝试从 localStorage 读取持久化设置
const saved = localStorage.getItem(STORAGE_KEY);
let lang: LanguageCode = 'zh';
if (saved && SUPPORTED_LANGUAGE_CODES.includes(saved as LanguageCode)) {
lang = saved as LanguageCode;
} else {
// 2. 检测系统语言
lang = detectSystemLanguage();
}
// 3. 应用语言设置
await this.setLanguage(lang, false); // 不持久化,因为已经是持久化的值
this.initialized = true;
} catch (error) {
console.error('Failed to initialize locale store:', error);
// 降级处理:使用默认中文
await this.setLanguage('zh', false);
this.initialized = true;
}
},
/**
* 设置语言
* @param language 目标语言代码
* @param persist 是否持久化到 localStorage默认为 true
*/
async setLanguage(language: LanguageCode, persist: boolean = true) {
// 验证语言代码有效性
const resolvedLang = resolveSupportedLanguage(language);
if (resolvedLang === this.language) {
return; // 语言未变化
}
try {
// 1. 更新 i18n 实例
await setLanguage(resolvedLang, i18n);
// 2. 更新 store 状态
this.language = resolvedLang;
// 3. 持久化到 localStorage
if (persist) {
localStorage.setItem(STORAGE_KEY, resolvedLang);
}
// 4. 触发语言变化事件(供其他组件监听)
window.dispatchEvent(new CustomEvent('language-changed', {
detail: { language: resolvedLang }
}));
} catch (error) {
console.error('Failed to set language:', error);
throw error;
}
},
/**
* 切换语言(轮换支持的语言)
*/
async toggleLanguage() {
const currentIndex = SUPPORTED_LANGUAGE_CODES.indexOf(this.language);
const nextIndex = (currentIndex + 1) % SUPPORTED_LANGUAGE_CODES.length;
const nextLanguage = SUPPORTED_LANGUAGE_CODES[nextIndex];
await this.setLanguage(nextLanguage);
},
/**
* 重置为系统语言
*/
async resetToSystemLanguage() {
const systemLang = detectSystemLanguage();
await this.setLanguage(systemLang);
},
/**
* 同步 i18n 实例与 store 状态(用于外部更改的情况)
*/
syncWithI18n() {
const currentLang = getLanguage();
if (currentLang !== this.language) {
this.language = currentLang as LanguageCode;
}
},
},
});
// 导出类型
export type { LanguageCode };

25
src/store/sharedStore.ts Normal file
View File

@@ -0,0 +1,25 @@
import { defineStore } from 'pinia'
import { isEqual } from 'lodash-es'
export const useSharedStore = defineStore('shared', {
state: () => ({
sharedData: {},
}),
actions: {
updateSharedData(data: any) {
this.sharedData = Object.assign(this.sharedData, data)
const cloneData = JSON.parse(JSON.stringify(this.sharedData))
if (!isEqual(this.sharedData, data)) {
// 同步状态到主进程
try {
} catch (error) {
}
}
}
}
})

73
src/store/userinfo.ts Normal file
View File

@@ -0,0 +1,73 @@
import { defineStore } from 'pinia'
import { authOauth2TokenUsingPost } from "@src/api"
import { Session } from '@utils/storage'
import { encryption } from '@utils/other'
export const useUserStore = defineStore('userInfo', {
state: () => ({
token: Session.get('token'),
}),
actions: {
/**
* 登录方法
* @function login
* @async
* @param {Object} data - 登录数据
* @returns {Promise<Object>}
*/
async login(data: any) {
data.grant_type = 'password';
data.scope = 'server';
// const { VITE_OAUTH2_PASSWORD_CLIENT, VITE_PWD_ENC_KEY } = (import.meta as any).env
// const basicAuth = 'Basic ' + window.btoa(VITE_OAUTH2_PASSWORD_CLIENT);
// Session.set('basicAuth', basicAuth);
// let encPassword = data.password;
// 密码加密
// if (VITE_PWD_ENC_KEY) {
// encPassword = encryption(data.password, VITE_PWD_ENC_KEY);
// }
return new Promise((resolve, reject) => {
authOauth2TokenUsingPost({
body: { clientId: '', ...data },
options: {
headers: {
isToken: true,
// Authorization: basicAuth,
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Basic Y3VzdG9tUEM6Y3VzdG9tUEM='
}
}
})
.then((res: any) => {
// 存储token 信息
Session.set('token', res.access_token);
Session.set('refresh_token', res.refresh_token);
resolve(res)
})
.catch((err) => {
reject(err);
});
});
},
// 退出系统
logOut() {
return new Promise((resolve, reject) => {
// logout(this.token).then(() => {
// this.token = ''
// this.roles = []
// this.permissions = []
// removeToken()
// resolve()
// }).catch(error => {
// reject(error)
// })
})
}
}
})