From 3577e139b9c03cfb5d9f6389b2323cd4a1a1faee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A2=81=E6=B6=9B?= Date: Sat, 18 Apr 2026 00:52:34 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=B0=E5=A2=9E=20=E5=AE=8C=E6=95=B4?= =?UTF-8?q?=E7=9A=84=E5=9B=BD=E9=99=85=E5=8C=96(i18n)=E6=94=AF=E6=8C=81?= =?UTF-8?q?=EF=BC=8C=E6=94=AF=E6=8C=81=E4=B8=AD=E8=8B=B1=E6=97=A5=E4=B8=89?= =?UTF-8?q?=E7=A7=8D=E8=AF=AD=E8=A8=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lang-zh-CN.png | Bin 0 -> 27644 bytes main.js | 108 ++++++++++--- package-lock.json | 103 +++++++++---- package.json | 3 + preload.js | 5 + src/App.vue | 323 ++++++++++++++++++++++++--------------- src/locales/en-US.js | 130 ++++++++++++++++ src/locales/index.js | 130 ++++++++++++++++ src/locales/ja-JP.js | 130 ++++++++++++++++ src/main.js | 23 ++- theme-dark.png | Bin 0 -> 22391 bytes theme-solarized-dark.png | Bin 0 -> 22593 bytes theme-xcode.png | Bin 0 -> 22585 bytes 13 files changed, 786 insertions(+), 169 deletions(-) create mode 100644 lang-zh-CN.png create mode 100644 src/locales/en-US.js create mode 100644 src/locales/index.js create mode 100644 src/locales/ja-JP.js create mode 100644 theme-dark.png create mode 100644 theme-solarized-dark.png create mode 100644 theme-xcode.png diff --git a/lang-zh-CN.png b/lang-zh-CN.png new file mode 100644 index 0000000000000000000000000000000000000000..8f3f7f0d4b08f9e56c69105290a14422aacd24fd GIT binary patch literal 27644 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 E08$Ds5C8xG literal 0 HcmV?d00001 diff --git a/main.js b/main.js index 6b57f35..a306b88 100644 --- a/main.js +++ b/main.js @@ -9,6 +9,68 @@ let mainWindow let tray const isDev = process.argv.includes('--dev') +// 主进程翻译 +const trayTranslations = { + 'zh-CN': { + showWindow: '显示主窗口', + switchApiConfig: '切换 API 配置', + exit: '退出', + tooltip: 'iFlow 设置编辑器' + }, + 'en-US': { + showWindow: 'Show Window', + switchApiConfig: 'Switch API Config', + exit: 'Exit', + tooltip: 'iFlow Settings Editor' + }, + 'ja-JP': { + showWindow: 'メインウィンドウを表示', + switchApiConfig: 'API 設定切替', + exit: '終了', + tooltip: 'iFlow 設定エディタ' + } +} + +function getTrayTranslation() { + const settings = readSettings() + const lang = settings?.language || 'zh-CN' + return trayTranslations[lang] || trayTranslations['zh-CN'] +} + +// 错误消息翻译 +const errorTranslations = { + 'zh-CN': { + configNotFound: '配置文件不存在', + configNotExist: '配置 "{name}" 不存在', + configAlreadyExists: '配置 "{name}" 已存在', + cannotDeleteDefault: '不能删除默认配置', + cannotRenameDefault: '不能重命名默认配置', + switchFailed: '切换API配置失败' + }, + 'en-US': { + configNotFound: 'Configuration file not found', + configNotExist: 'Configuration "{name}" does not exist', + configAlreadyExists: 'Configuration "{name}" already exists', + cannotDeleteDefault: 'Cannot delete default configuration', + cannotRenameDefault: 'Cannot rename default configuration', + switchFailed: 'Failed to switch API configuration' + }, + 'ja-JP': { + configNotFound: '設定ファイルが存在しません', + configNotExist: 'プロファイル "{name}" が存在しません', + configAlreadyExists: 'プロファイル "{name}" が既に存在します', + cannotDeleteDefault: 'デフォルトプロファイルは削除できません', + cannotRenameDefault: 'デフォルトプロファイルは名前変更できません', + switchFailed: 'API 設定の切替に失敗しました' + } +} + +function getErrorTranslation() { + const settings = readSettings() + const lang = settings?.language || 'zh-CN' + return errorTranslations[lang] || errorTranslations['zh-CN'] +} + // 创建系统托盘 function createTray() { // 获取图标路径 - 打包后需要从 extraResources 获取 @@ -30,7 +92,7 @@ function createTray() { trayIcon = trayIcon.resize({ width: 16, height: 16 }) tray = new Tray(trayIcon) - tray.setToolTip('iFlow 设置编辑器') + tray.setToolTip(getTrayTranslation().tooltip) updateTrayMenu() @@ -59,9 +121,10 @@ function updateTrayMenu() { click: () => switchApiProfileFromTray(name) })) + const t = getTrayTranslation() const contextMenu = Menu.buildFromTemplate([ { - label: '显示主窗口', + label: t.showWindow, click: () => { if (mainWindow) { mainWindow.show() @@ -71,12 +134,12 @@ function updateTrayMenu() { }, { type: 'separator' }, { - label: '切换 API 配置', + label: t.switchApiConfig, submenu: profileMenuItems }, { type: 'separator' }, { - label: '退出', + label: t.exit, click: () => { app.isQuitting = true app.quit() @@ -198,6 +261,10 @@ ipcMain.on('window-close', () => { } }) ipcMain.handle('is-maximized', () => mainWindow.isMaximized()) +// 监听语言切换以更新托盘菜单 +ipcMain.on('language-changed', () => { + updateTrayMenu() +}) // API 配置相关的字段 const API_FIELDS = ['selectedAuthType', 'apiKey', 'baseUrl', 'modelName', 'searchApiKey', 'cna'] // 读取设置文件 @@ -245,12 +312,13 @@ ipcMain.handle('list-api-profiles', async () => { ipcMain.handle('switch-api-profile', async (event, profileName) => { try { const settings = readSettings() + const t = getErrorTranslation() if (!settings) { - return { success: false, error: '配置文件不存在' } + return { success: false, error: t.configNotFound } } const profiles = settings.apiProfiles || {} if (!profiles[profileName]) { - return { success: false, error: `配置 "${profileName}" 不存在` } + return { success: false, error: t.configNotExist.replace('{name}', profileName) } } // 保存当前配置到 apiProfiles(如果当前配置存在) const currentProfile = settings.currentApiProfile || 'default' @@ -282,8 +350,9 @@ ipcMain.handle('switch-api-profile', async (event, profileName) => { ipcMain.handle('create-api-profile', async (event, name) => { try { const settings = readSettings() + const t = getErrorTranslation() if (!settings) { - return { success: false, error: '配置文件不存在' } + return { success: false, error: t.configNotFound } } if (!settings.apiProfiles) { settings.apiProfiles = { default: {} } @@ -295,7 +364,7 @@ ipcMain.handle('create-api-profile', async (event, name) => { } } if (settings.apiProfiles[name]) { - return { success: false, error: `配置 "${name}" 已存在` } + return { success: false, error: t.configAlreadyExists.replace('{name}', name) } } // 复制当前配置到新配置 const newConfig = {} @@ -315,15 +384,16 @@ ipcMain.handle('create-api-profile', async (event, name) => { ipcMain.handle('delete-api-profile', async (event, name) => { try { const settings = readSettings() + const t = getErrorTranslation() if (!settings) { - return { success: false, error: '配置文件不存在' } + return { success: false, error: t.configNotFound } } if (name === 'default') { - return { success: false, error: '不能删除默认配置' } + return { success: false, error: t.cannotDeleteDefault } } const profiles = settings.apiProfiles || {} if (!profiles[name]) { - return { success: false, error: `配置 "${name}" 不存在` } + return { success: false, error: t.configNotExist.replace('{name}', name) } } delete profiles[name] settings.apiProfiles = profiles @@ -348,18 +418,19 @@ ipcMain.handle('delete-api-profile', async (event, name) => { ipcMain.handle('rename-api-profile', async (event, oldName, newName) => { try { const settings = readSettings() + const t = getErrorTranslation() if (!settings) { - return { success: false, error: '配置文件不存在' } + return { success: false, error: t.configNotFound } } if (oldName === 'default') { - return { success: false, error: '不能重命名默认配置' } + return { success: false, error: t.cannotRenameDefault } } const profiles = settings.apiProfiles || {} if (!profiles[oldName]) { - return { success: false, error: `配置 "${oldName}" 不存在` } + return { success: false, error: t.configNotExist.replace('{name}', oldName) } } if (profiles[newName]) { - return { success: false, error: `配置 "${newName}" 已存在` } + return { success: false, error: t.configAlreadyExists.replace('{name}', newName) } } profiles[newName] = profiles[oldName] delete profiles[oldName] @@ -377,15 +448,16 @@ ipcMain.handle('rename-api-profile', async (event, oldName, newName) => { ipcMain.handle('duplicate-api-profile', async (event, sourceName, newName) => { try { const settings = readSettings() + const t = getErrorTranslation() if (!settings) { - return { success: false, error: '配置文件不存在' } + return { success: false, error: t.configNotFound } } const profiles = settings.apiProfiles || {} if (!profiles[sourceName]) { - return { success: false, error: `配置 "${sourceName}" 不存在` } + return { success: false, error: t.configNotExist.replace('{name}', sourceName) } } if (profiles[newName]) { - return { success: false, error: `配置 "${newName}" 已存在` } + return { success: false, error: t.configAlreadyExists.replace('{name}', newName) } } // 深拷贝配置 profiles[newName] = JSON.parse(JSON.stringify(profiles[sourceName])) diff --git a/package-lock.json b/package-lock.json index 18e2481..b3d9d29 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,13 +1,16 @@ { "name": "iflow-settings-editor", - "version": "1.0.0", + "version": "1.5.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "iflow-settings-editor", - "version": "1.0.0", + "version": "1.5.1", "license": "MIT", + "dependencies": { + "vue-i18n": "^9.14.5" + }, "devDependencies": { "@icon-park/vue-next": "^1.4.2", "@vitejs/plugin-vue": "^6.0.6", @@ -22,7 +25,6 @@ "version": "7.27.1", "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz", "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -32,7 +34,6 @@ "version": "7.28.5", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", - "dev": true, "license": "MIT", "engines": { "node": ">=6.9.0" @@ -42,7 +43,6 @@ "version": "7.29.2", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz", "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==", - "dev": true, "license": "MIT", "dependencies": { "@babel/types": "^7.29.0" @@ -68,7 +68,6 @@ "version": "7.29.0", "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz", "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==", - "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", @@ -417,6 +416,50 @@ "vue": "3.x" } }, + "node_modules/@intlify/core-base": { + "version": "9.14.5", + "resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-9.14.5.tgz", + "integrity": "sha512-5ah5FqZG4pOoHjkvs8mjtv+gPKYU0zCISaYNjBNNqYiaITxW8ZtVih3GS/oTOqN8d9/mDLyrjD46GBApNxmlsA==", + "license": "MIT", + "dependencies": { + "@intlify/message-compiler": "9.14.5", + "@intlify/shared": "9.14.5" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/message-compiler": { + "version": "9.14.5", + "resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-9.14.5.tgz", + "integrity": "sha512-IHzgEu61/YIpQV5Pc3aRWScDcnFKWvQA9kigcINcCBXN8mbW+vk9SK+lDxA6STzKQsVJxUPg9ACC52pKKo3SVQ==", + "license": "MIT", + "dependencies": { + "@intlify/shared": "9.14.5", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, + "node_modules/@intlify/shared": { + "version": "9.14.5", + "resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-9.14.5.tgz", + "integrity": "sha512-9gB+E53BYuAEMhbCAxVgG38EZrk59sxBtv3jSizNL2hEWlgjBjAw1AwpLHtNaeda12pe6W20OGEa0TwuMSRbyQ==", + "license": "MIT", + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -524,7 +567,6 @@ "version": "1.5.5", "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz", "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==", - "dev": true, "license": "MIT" }, "node_modules/@malept/cross-spawn-promise": { @@ -1085,7 +1127,6 @@ "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.32.tgz", "integrity": "sha512-4x74Tbtqnda8s/NSD6e1Dr5p1c8HdMU5RWSjMSUzb8RTcUQqevDCxVAitcLBKT+ie3o0Dl9crc/S/opJM7qBGQ==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.29.2", @@ -1099,7 +1140,6 @@ "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.32.tgz", "integrity": "sha512-ybHAu70NtiEI1fvAUz3oXZqkUYEe5J98GjMDpTGl5iHb0T15wQYLR4wE3h9xfuTNA+Cm2f4czfe8B4s+CCH57Q==", - "dev": true, "license": "MIT", "dependencies": { "@vue/compiler-core": "3.5.32", @@ -1110,7 +1150,6 @@ "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/compiler-sfc/-/compiler-sfc-3.5.32.tgz", "integrity": "sha512-8UYUYo71cP/0YHMO814TRZlPuUUw3oifHuMR7Wp9SNoRSrxRQnhMLNlCeaODNn6kNTJsjFoQ/kqIj4qGvya4Xg==", - "dev": true, "license": "MIT", "dependencies": { "@babel/parser": "^7.29.2", @@ -1128,18 +1167,22 @@ "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.32.tgz", "integrity": "sha512-Gp4gTs22T3DgRotZ8aA/6m2jMR+GMztvBXUBEUOYOcST+giyGWJ4WvFd7QLHBkzTxkfOt8IELKNdpzITLbA2rw==", - "dev": true, "license": "MIT", "dependencies": { "@vue/compiler-dom": "3.5.32", "@vue/shared": "3.5.32" } }, + "node_modules/@vue/devtools-api": { + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz", + "integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==", + "license": "MIT" + }, "node_modules/@vue/reactivity": { "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/reactivity/-/reactivity-3.5.32.tgz", "integrity": "sha512-/ORasxSGvZ6MN5gc+uE364SxFdJ0+WqVG0CENXaGW58TOCdrAW76WWaplDtECeS1qphvtBZtR+3/o1g1zL4xPQ==", - "dev": true, "license": "MIT", "dependencies": { "@vue/shared": "3.5.32" @@ -1149,7 +1192,6 @@ "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/runtime-core/-/runtime-core-3.5.32.tgz", "integrity": "sha512-pDrXCejn4UpFDFmMd27AcJEbHaLemaE5o4pbb7sLk79SRIhc6/t34BQA7SGNgYtbMnvbF/HHOftYBgFJtUoJUQ==", - "dev": true, "license": "MIT", "dependencies": { "@vue/reactivity": "3.5.32", @@ -1160,7 +1202,6 @@ "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/runtime-dom/-/runtime-dom-3.5.32.tgz", "integrity": "sha512-1CDVv7tv/IV13V8Nip1k/aaObVbWqRlVCVezTwx3K07p7Vxossp5JU1dcPNhJk3w347gonIUT9jQOGutyJrSVQ==", - "dev": true, "license": "MIT", "dependencies": { "@vue/reactivity": "3.5.32", @@ -1173,7 +1214,6 @@ "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/server-renderer/-/server-renderer-3.5.32.tgz", "integrity": "sha512-IOjm2+JQwRFS7W28HNuJeXQle9KdZbODFY7hFGVtnnghF51ta20EWAZJHX+zLGtsHhaU6uC9BGPV52KVpYryMQ==", - "dev": true, "license": "MIT", "dependencies": { "@vue/compiler-ssr": "3.5.32", @@ -1187,7 +1227,6 @@ "version": "3.5.32", "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.32.tgz", "integrity": "sha512-ksNyrmRQzWJJ8n3cRDuSF7zNNontuJg1YHnmWRJd2AMu8Ij2bqwiiri2lH5rHtYPZjj4STkNcgcmiQqlOjiYGg==", - "dev": true, "license": "MIT" }, "node_modules/@xmldom/xmldom": { @@ -2107,7 +2146,6 @@ "version": "3.2.3", "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.2.3.tgz", "integrity": "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==", - "dev": true, "license": "MIT" }, "node_modules/date-fns": { @@ -2654,7 +2692,6 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz", "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==", - "dev": true, "license": "BSD-2-Clause", "engines": { "node": ">=0.12" @@ -2765,7 +2802,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz", "integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==", - "dev": true, "license": "MIT" }, "node_modules/extract-zip": { @@ -3920,7 +3956,6 @@ "version": "0.30.21", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", - "dev": true, "license": "MIT", "dependencies": { "@jridgewell/sourcemap-codec": "^1.5.5" @@ -4080,7 +4115,6 @@ "version": "3.3.11", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz", "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==", - "dev": true, "funding": [ { "type": "github", @@ -4220,7 +4254,6 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", - "dev": true, "license": "ISC" }, "node_modules/picomatch": { @@ -4255,7 +4288,6 @@ "version": "8.5.9", "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.9.tgz", "integrity": "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==", - "dev": true, "funding": [ { "type": "opencollective", @@ -4702,7 +4734,6 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", - "dev": true, "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" @@ -5009,7 +5040,7 @@ "version": "5.9.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, + "devOptional": true, "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -5159,7 +5190,6 @@ "version": "3.5.32", "resolved": "https://registry.npmjs.org/vue/-/vue-3.5.32.tgz", "integrity": "sha512-vM4z4Q9tTafVfMAK7IVzmxg34rSzTFMyIe0UUEijUCkn9+23lj0WRfA83dg7eQZIUlgOSGrkViIaCfqSAUXsMw==", - "dev": true, "license": "MIT", "dependencies": { "@vue/compiler-dom": "3.5.32", @@ -5177,6 +5207,27 @@ } } }, + "node_modules/vue-i18n": { + "version": "9.14.5", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-9.14.5.tgz", + "integrity": "sha512-0jQ9Em3ymWngyiIkj0+c/k7WgaPO+TNzjKSNq9BvBQaKJECqn9cd9fL4tkDhB5G1QBskGl9YxxbDAhgbFtpe2g==", + "deprecated": "v9 and v10 no longer supported. please migrate to v11. about maintenance status, see https://vue-i18n.intlify.dev/guide/maintenance.html", + "license": "MIT", + "dependencies": { + "@intlify/core-base": "9.14.5", + "@intlify/shared": "9.14.5", + "@vue/devtools-api": "^6.5.0" + }, + "engines": { + "node": ">= 16" + }, + "funding": { + "url": "https://github.com/sponsors/kazupon" + }, + "peerDependencies": { + "vue": "^3.0.0" + } + }, "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", diff --git a/package.json b/package.json index af114ec..b6b3fab 100644 --- a/package.json +++ b/package.json @@ -91,5 +91,8 @@ "electron-builder": "^24.13.3", "vite": "^8.0.8", "vue": "^3.4.0" + }, + "dependencies": { + "vue-i18n": "^9.14.5" } } diff --git a/preload.js b/preload.js index 96ba334..4f3a38b 100644 --- a/preload.js +++ b/preload.js @@ -23,5 +23,10 @@ contextBridge.exposeInMainWorld('electronAPI', { // 托盘事件监听 onApiProfileSwitched: (callback) => { ipcRenderer.on('api-profile-switched', (event, profileName) => callback(profileName)) + }, + + // 语言切换通知 + notifyLanguageChanged: () => { + ipcRenderer.send('language-changed') } }) \ No newline at end of file diff --git a/src/App.vue b/src/App.vue index 420f588..6ca3a6e 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,17 +1,17 @@
-
暂无 MCP 服务器
-
点击上方按钮添加第一个服务器
+
{{ $t('mcp.noServers') }}
+
{{ $t('mcp.addFirstServer') }}
@@ -177,7 +177,7 @@
@@ -187,8 +187,8 @@
{{ showInputDialog.placeholder }}
- - + +
@@ -197,8 +197,8 @@
- - 新建 API 配置 + + {{ $t('api.createTitle') }}
- - + +
- +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
@@ -255,7 +255,7 @@
- 编辑 API 配置 + {{ $t('api.editTitle') }}
- +
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
@@ -308,7 +308,7 @@
- {{ isEditingServer ? '编辑服务器' : '添加服务器' }} + {{ isEditingServer ? $t('mcp.editServer') : $t('mcp.addServer') }}
- - + +
- - + +
- - + +
- - + +
- - + +
- - + +
@@ -384,7 +384,7 @@
{{ showMessageDialog.title }}
{{ showMessageDialog.message }}
- +
@@ -392,7 +392,9 @@