feat(i18n): 后端添加国际化支持、优化前端界面

- 后端添加并实现国际化支持
- 前端引入 vue-i18n 模块(尚未添加国际化逻辑)
- 优化用户界面样式,统一输入框和标签样式
This commit is contained in:
himeditator
2025-07-03 20:36:09 +08:00
parent 3dcba07b6e
commit d608bf59c7
22 changed files with 344 additions and 229 deletions

11
src/main/i18n/index.ts Normal file
View File

@@ -0,0 +1,11 @@
import zh from './lang/zh'
import en from './lang/en'
import ja from './lang/ja'
import { allConfig } from '../utils/AllConfig'
export function i18n(key: string): string{
if(allConfig.uiLanguage === 'zh') return zh[key] || key
else if(allConfig.uiLanguage === 'en') return en[key] || key
else if(allConfig.uiLanguage === 'ja') return ja[key] || key
else return key
}

8
src/main/i18n/lang/en.ts Normal file
View File

@@ -0,0 +1,8 @@
export default {
"gummy.env.missing": "DASHSCOPE_API_KEY environment variable not detected. To use the gummy engine, you need to obtain an API Key from Alibaba Cloud's Bailian platform and add it to your local environment variables.",
"platform.unsupported": "Unsupported platform: ",
"engine.start.error": "Caption engine failed to start: ",
"engine.output.parse.error": "Unable to parse caption engine output as a JSON object: ",
"engine.error": "Caption engine error: ",
"engine.shutdown.error": "Failed to shut down the caption engine process: "
}

8
src/main/i18n/lang/ja.ts Normal file
View File

@@ -0,0 +1,8 @@
export default {
"gummy.env.missing": "DASHSCOPE_API_KEY 環境変数が検出されませんでした。Gummy エンジンを使用するには、Alibaba Cloud の百煉プラットフォームから API Key を取得し、ローカル環境変数に追加する必要があります。",
"platform.unsupported": "サポートされていないプラットフォーム: ",
"engine.start.error": "字幕エンジンの起動に失敗しました: ",
"engine.output.parse.error": "字幕エンジンの出力を JSON オブジェクトとして解析できませんでした: ",
"engine.error": "字幕エンジンエラー: ",
"engine.shutdown.error": "字幕エンジンプロセスの終了に失敗しました: "
}

8
src/main/i18n/lang/zh.ts Normal file
View File

@@ -0,0 +1,8 @@
export default {
"gummy.env.missing": "没有检测到 DASHSCOPE_API_KEY 环境变量,如果要使用 gummy 引擎,需要在阿里云百炼平台获取 API Key 并添加到本机环境变量",
"platform.unsupported": "不支持的平台:",
"engine.start.error": "字幕引擎启动失败:",
"engine.output.parse.error": "字幕引擎输出内容无法解析为 JSON 对象:",
"engine.error": "字幕引擎错误:",
"engine.shutdown.error": "字幕引擎进程关闭失败:"
}

View File

@@ -1,4 +1,4 @@
import { Styles, CaptionItem, Controls } from '../types'
import { UILanguage, Styles, CaptionItem, Controls } from '../types'
import { app, BrowserWindow } from 'electron'
import * as path from 'path'
import * as fs from 'fs'
@@ -29,6 +29,7 @@ const defaultControls: Controls = {
class AllConfig {
uiLanguage: UILanguage = 'ja'
styles: Styles = {...defaultStyles};
controls: Controls = {...defaultControls};
captionLog: CaptionItem[] = [];
@@ -39,14 +40,16 @@ class AllConfig {
const configPath = path.join(app.getPath('userData'), 'config.json')
if(fs.existsSync(configPath)){
const config = JSON.parse(fs.readFileSync(configPath, 'utf-8'))
this.setStyles(config.styles)
this.setControls(config.controls)
if(config.uiLanguage) this.uiLanguage = config.uiLanguage
if(config.styles) this.setStyles(config.styles)
if(config.controls) this.setControls(config.controls)
console.log('[INFO] Read Config from:', configPath)
}
}
public writeConfig() {
const config = {
uiLanguage: this.uiLanguage,
controls: this.controls,
styles: this.styles
}

View File

@@ -4,6 +4,7 @@ import { is } from '@electron-toolkit/utils'
import path from 'path'
import { controlWindow } from '../ControlWindow'
import { allConfig } from './AllConfig'
import { i18n } from '../i18n'
export class CaptionEngine {
appPath: string = ''
@@ -18,7 +19,7 @@ export class CaptionEngine {
else if (allConfig.controls.engine === 'gummy') {
allConfig.controls.customized = false
if(!process.env.DASHSCOPE_API_KEY) {
controlWindow.sendErrorMessage('没有检测到 DASHSCOPE_API_KEY 环境变量,如果要使用 gummy 引擎,需要在阿里云百炼平台获取 API Key 并添加到本机环境变量')
controlWindow.sendErrorMessage(i18n('gummy.env.missing'))
return false
}
let gummyName = ''
@@ -29,8 +30,8 @@ export class CaptionEngine {
gummyName = 'main-gummy'
}
else {
controlWindow.sendErrorMessage('Unsupported platform: ' + process.platform)
throw new Error('Unsupported platform')
controlWindow.sendErrorMessage(i18n('platform.unsupported') + process.platform)
throw new Error(i18n('platform.unsupported'))
}
if (is.dev) {
this.appPath = path.join(
@@ -66,7 +67,7 @@ export class CaptionEngine {
this.process = spawn(this.appPath, this.command)
}
catch (e) {
controlWindow.sendErrorMessage('字幕引擎启动失败:' + e)
controlWindow.sendErrorMessage(i18n('engine.start.error') + e)
console.error('[ERROR] Error starting subprocess:', e)
return
}
@@ -80,7 +81,7 @@ export class CaptionEngine {
controlWindow.window.webContents.send('control.engine.started')
}
this.process.stdout.on('data', (data) => {
this.process.stdout.on('data', (data: any) => {
const lines = data.toString().split('\n');
lines.forEach((line: string) => {
if (line.trim()) {
@@ -88,7 +89,7 @@ export class CaptionEngine {
const caption = JSON.parse(line);
allConfig.updateCaptionLog(caption);
} catch (e) {
controlWindow.sendErrorMessage('字幕引擎输出内容无法解析为 JSON 对象:' + e)
controlWindow.sendErrorMessage(i18n('engine.output.parse.error') + e)
console.error('[ERROR] Error parsing JSON:', e);
}
}
@@ -96,7 +97,7 @@ export class CaptionEngine {
});
this.process.stderr.on('data', (data) => {
controlWindow.sendErrorMessage('字幕引擎错误:' + data)
controlWindow.sendErrorMessage(i18n('engine.error') + data)
console.error(`[ERROR] Subprocess Error: ${data}`);
});
@@ -115,7 +116,7 @@ export class CaptionEngine {
if (process.platform === "win32" && this.process.pid) {
exec(`taskkill /pid ${this.process.pid} /t /f`, (error) => {
if (error) {
controlWindow.sendErrorMessage('字幕引擎进程关闭失败:' + error)
controlWindow.sendErrorMessage(i18n('engine.shutdown.error') + error)
console.error(`[ERROR] Failed to kill process: ${error}`)
}
});