feat(i18n): 实现前端国际化

- 新增英文、日文和中文翻译文件
- 添加语言切换功能
- 更新各组件的文本内容以支持国际化
This commit is contained in:
himeditator
2025-07-03 23:29:10 +08:00
parent d608bf59c7
commit 0a10068b38
12 changed files with 348 additions and 77 deletions

View File

@@ -9,6 +9,11 @@
margin-right: 10px; margin-right: 10px;
} }
.switch-label {
display: inline-block;
margin-right: 10px;
}
.input-area { .input-area {
width: calc(100% - 100px); width: calc(100% - 100px);
min-width: 100px; min-width: 100px;

View File

@@ -0,0 +1,3 @@
/* :root {
} */

View File

@@ -1,6 +1,6 @@
body { body {
margin: 0; margin: 0;
padding: 0; padding: 0;
height: 100vh; height: 100vh;
overflow: hidden; overflow: hidden;
} }

View File

@@ -1,20 +1,20 @@
<template> <template>
<div class="caption-list"> <div class="caption-list">
<div class="caption-title"> <div class="caption-title">
<span style="margin-right: 30px;">字幕记录</span> <span style="margin-right: 30px;">{{ $t('log.title') }}</span>
<a-button <a-button
type="primary" type="primary"
style="margin-right: 20px;" style="margin-right: 20px;"
@click="exportCaptions" @click="exportCaptions"
:disabled="captionData.length === 0" :disabled="captionData.length === 0"
> >
导出字幕记录 {{ $t('log.export') }}
</a-button> </a-button>
<a-button <a-button
danger danger
@click="clearCaptions" @click="clearCaptions"
> >
清空字幕记录 {{ $t('log.clear') }}
</a-button> </a-button>
</div> </div>
<a-table <a-table
@@ -54,7 +54,7 @@ const pagination = ref({
pageSize: 10, pageSize: 10,
showSizeChanger: true, showSizeChanger: true,
pageSizeOptions: ['10', '20', '50'], pageSizeOptions: ['10', '20', '50'],
showTotal: (total: number) => ` ${total} 条记录`, showTotal: (total: number) => `Total: ${total}`,
onChange: (page: number, pageSize: number) => { onChange: (page: number, pageSize: number) => {
pagination.value.current = page pagination.value.current = page
pagination.value.pageSize = pageSize pagination.value.pageSize = pageSize
@@ -67,19 +67,19 @@ const pagination = ref({
const columns = [ const columns = [
{ {
title: '序号', title: 'index',
dataIndex: 'index', dataIndex: 'index',
key: 'index', key: 'index',
width: 80, width: 80,
}, },
{ {
title: '时间', title: 'time',
dataIndex: 'time', dataIndex: 'time',
key: 'time', key: 'time',
width: 160, width: 160,
}, },
{ {
title: '字幕内容', title: 'content',
dataIndex: 'content', dataIndex: 'content',
key: 'content', key: 'content',
}, },

View File

@@ -1,19 +1,19 @@
<template> <template>
<a-card size="small" title="字幕样式设置"> <a-card size="small" :title="$t('style.title')">
<template #extra> <template #extra>
<a @click="applyStyle">应用样式</a> | <a @click="applyStyle">{{ $t('style.applyStyle') }}</a> |
<a @click="backStyle">取消更改</a> | <a @click="backStyle">{{ $t('style.cancelChange') }}</a> |
<a @click="resetStyle">恢复默认</a> <a @click="resetStyle">{{ $t('style.resetStyle') }}</a>
</template> </template>
<div class="input-item"> <div class="input-item">
<span class="input-label">字体族</span> <span class="input-label">{{ $t('style.fontFamily') }}</span>
<a-input <a-input
class="input-area" class="input-area"
v-model:value="currentFontFamily" v-model:value="currentFontFamily"
/> />
</div> </div>
<div class="input-item"> <div class="input-item">
<span class="input-label">字体颜色</span> <span class="input-label">{{ $t('style.fontColor') }}</span>
<a-input <a-input
class="input-area" class="input-area"
type="color" type="color"
@@ -22,7 +22,7 @@
<div class="input-item-value">{{ currentFontColor }}</div> <div class="input-item-value">{{ currentFontColor }}</div>
</div> </div>
<div class="input-item"> <div class="input-item">
<span class="input-label">字体大小</span> <span class="input-label">{{ $t('style.fontSize') }}</span>
<a-input <a-input
class="input-area" class="input-area"
type="range" type="range"
@@ -32,7 +32,7 @@
<div class="input-item-value">{{ currentFontSize }}px</div> <div class="input-item-value">{{ currentFontSize }}px</div>
</div> </div>
<div class="input-item"> <div class="input-item">
<span class="input-label">背景颜色</span> <span class="input-label">{{ $t('style.background') }}</span>
<a-input <a-input
class="input-area" class="input-area"
type="color" type="color"
@@ -41,7 +41,7 @@
<div class="input-item-value">{{ currentBackground }}</div> <div class="input-item-value">{{ currentBackground }}</div>
</div> </div>
<div class="input-item"> <div class="input-item">
<span class="input-label">背景透明度</span> <span class="input-label">{{ $t('style.opacity') }}</span>
<a-input <a-input
class="input-area" class="input-area"
type="range" type="range"
@@ -49,30 +49,33 @@
max="100" max="100"
v-model:value="currentOpacity" v-model:value="currentOpacity"
/> />
<div class="input-item-value">{{ currentOpacity }}</div> <div class="input-item-value">{{ currentOpacity }}%</div>
</div> </div>
<div class="input-item"> <div class="input-item">
<span class="input-label">显示预览</span> <span class="input-label">{{ $t('style.preview') }}</span>
<a-switch v-model:checked="displayPreview" /> <a-switch v-model:checked="displayPreview" />
<span class="input-label">显示翻译</span> <sapn style="display:inline-block;width:20px;"></sapn>
<a-switch v-model:checked="currentTransDisplay" /> <div style="display: inline-block;">
<span class="switch-label">{{ $t('style.translation') }}</span>
<a-switch v-model:checked="currentTransDisplay" />
</div>
</div> </div>
<div v-show="currentTransDisplay"> <div v-show="currentTransDisplay">
<a-card size="small" title="翻译样式设置"> <a-card size="small" :title="$t('style.trans.title')">
<template #extra> <template #extra>
<a @click="useSameStyle">使用相同样式</a> <a @click="useSameStyle">{{ $t('style.trans.useSame') }}</a>
</template> </template>
<div class="input-item"> <div class="input-item">
<span class="input-label">翻译字体</span> <span class="input-label">{{ $t('style.fontFamily') }}</span>
<a-input <a-input
class="input-area" class="input-area"
v-model:value="currentTransFontFamily" v-model:value="currentTransFontFamily"
/> />
</div> </div>
<div class="input-item"> <div class="input-item">
<span class="input-label">翻译颜色</span> <span class="input-label">{{ $t('style.fontColor') }}</span>
<a-input <a-input
class="input-area" class="input-area"
type="color" type="color"
@@ -81,7 +84,7 @@
<div class="input-item-value">{{ currentTransFontColor }}</div> <div class="input-item-value">{{ currentTransFontColor }}</div>
</div> </div>
<div class="input-item"> <div class="input-item">
<span class="input-label">翻译大小</span> <span class="input-label">{{ $t('style.fontSize') }}</span>
<a-input <a-input
class="input-area" class="input-area"
type="range" type="range"
@@ -92,7 +95,6 @@
</div> </div>
</a-card> </a-card>
</div> </div>
</a-card> </a-card>
<Teleport to="body"> <Teleport to="body">
@@ -109,7 +111,7 @@
fontSize: currentFontSize + 'px', fontSize: currentFontSize + 'px',
color: currentFontColor color: currentFontColor
}"> }">
{{ "This is a preview of subtitle styles." }} {{ $t('example.original') }}
</p> </p>
<p class="preview-translation" v-if="currentTransDisplay" <p class="preview-translation" v-if="currentTransDisplay"
:style="{ :style="{
@@ -117,7 +119,7 @@
fontSize: currentTransFontSize + 'px', fontSize: currentTransFontSize + 'px',
color: currentTransFontColor color: currentTransFontColor
}" }"
>这是字幕样式预览(翻译)</p> >{{ $t('example.translation') }}</p>
</div> </div>
</Teleport> </Teleport>

View File

@@ -1,12 +1,12 @@
<template> <template>
<div style="height: 20px;"></div> <div style="height: 20px;"></div>
<a-card size="small" title="字幕控制"> <a-card size="small" :title="$t('engine.title')">
<template #extra> <template #extra>
<a @click="applyChange">更改设置</a> | <a @click="applyChange">{{ $t('engine.applyChange') }}</a> |
<a @click="cancelChange">取消更改</a> <a @click="cancelChange">{{ $t('engine.cancelChange') }}</a>
</template> </template>
<div class="input-item"> <div class="input-item">
<span class="input-label">源语言</span> <span class="input-label">{{ $t('engine.sourceLang') }}</span>
<a-select <a-select
class="input-area" class="input-area"
v-model:value="currentSourceLang" v-model:value="currentSourceLang"
@@ -14,7 +14,7 @@
></a-select> ></a-select>
</div> </div>
<div class="input-item"> <div class="input-item">
<span class="input-label">翻译语言</span> <span class="input-label">{{ $t('engine.transLang') }}</span>
<a-select <a-select
class="input-area" class="input-area"
v-model:value="currentTargetLang" v-model:value="currentTargetLang"
@@ -22,7 +22,7 @@
></a-select> ></a-select>
</div> </div>
<div class="input-item"> <div class="input-item">
<span class="input-label">字幕引擎</span> <span class="input-label">{{ $t('engine.captionEngine') }}</span>
<a-select <a-select
class="input-area" class="input-area"
v-model:value="currentEngine" v-model:value="currentEngine"
@@ -30,7 +30,7 @@
></a-select> ></a-select>
</div> </div>
<div class="input-item"> <div class="input-item">
<span class="input-label">音频选择</span> <span class="input-label">{{ $t('engine.audioType') }}</span>
<a-select <a-select
class="input-area" class="input-area"
v-model:value="currentAudio" v-model:value="currentAudio"
@@ -38,23 +38,33 @@
></a-select> ></a-select>
</div> </div>
<div class="input-item"> <div class="input-item">
<span class="input-label">启用翻译</span> <span class="input-label">{{ $t('engine.enableTranslation') }}</span>
<a-switch v-model:checked="currentTranslation" /> <a-switch v-model:checked="currentTranslation" />
<span class="input-label">自定义引擎</span> <sapn style="display:inline-block;width:20px;"></sapn>
<a-switch v-model:checked="currentCustomized" /> <div style="display: inline-block;">
<span class="switch-label">{{ $t('engine.customEngine') }}</span>
<a-switch v-model:checked="currentCustomized" />
</div>
</div> </div>
<div v-show="currentCustomized"> <div v-show="currentCustomized">
<a-card size="small" title="自定义字幕引擎"> <a-card size="small" :title="$t('engine.custom.title')">
<p class="customize-note">说明允许用户使用自定义字幕引擎提供字幕提供的引擎要能通过 <code>child_process.spawn()</code> 进行启动且需要通过 IPC 与项目 node.js 后端进行通信具体通信接口见后端实现</p> <template #extra>
<a-popover>
<template #content>
<p class="customize-note">{{ $t('engine.custom.note') }}</p>
</template>
<a><InfoCircleOutlined />{{ $t('engine.custom.attention') }}</a>
</a-popover>
</template>
<div class="input-item"> <div class="input-item">
<span class="input-label">引擎路径</span> <span class="input-label">{{ $t('engine.custom.app') }}</span>
<a-input <a-input
class="input-area" class="input-area"
v-model:value="currentCustomizedApp" v-model:value="currentCustomizedApp"
></a-input> ></a-input>
</div> </div>
<div class="input-item"> <div class="input-item">
<span class="input-label">引擎指令</span> <span class="input-label">{{ $t('engine.custom.command') }}</span>
<a-input <a-input
class="input-area" class="input-area"
v-model:value="currentCustomizedCommand" v-model:value="currentCustomizedCommand"
@@ -71,7 +81,7 @@ import { ref, computed, watch } from 'vue'
import { storeToRefs } from 'pinia' import { storeToRefs } from 'pinia'
import { useEngineControlStore } from '@renderer/stores/engineControl' import { useEngineControlStore } from '@renderer/stores/engineControl'
import { notification } from 'ant-design-vue' import { notification } from 'ant-design-vue'
import { InfoCircleOutlined } from '@ant-design/icons-vue';
const engineControl = useEngineControlStore() const engineControl = useEngineControlStore()
const { captionEngine, audioType, changeSignal } = storeToRefs(engineControl) const { captionEngine, audioType, changeSignal } = storeToRefs(engineControl)
@@ -108,8 +118,8 @@ function applyChange(){
engineControl.sendControlChange() engineControl.sendControlChange()
notification.open({ notification.open({
message: '字幕控制已更改', message: '字幕控制已更改',
description: '如果字幕引擎已经启动,需要关闭后重启才会生效' description: '如果字幕引擎已经启动,需要关闭后重启才会生效'
}); });
} }
@@ -137,8 +147,8 @@ watch(changeSignal, (val) => {
@import url(../assets/input.css); @import url(../assets/input.css);
.customize-note { .customize-note {
padding: 0 20px; padding: 10px 10px 0;
color: red; color: red;
font-size: 12px; max-width: min(40vw, 480px);
} }
</style> </style>

View File

@@ -2,16 +2,22 @@
<div class="caption-stat"> <div class="caption-stat">
<a-row> <a-row>
<a-col :span="6"> <a-col :span="6">
<a-statistic title="字幕引擎" :value="(customized && customizedApp)?'自定义':engine" /> <a-statistic
:title="$t('status.engine')"
:value="(customized && customizedApp)?$t('status.customized'):engine"
/>
</a-col> </a-col>
<a-col :span="6"> <a-col :span="6">
<a-statistic title="字幕引擎状态" :value="engineEnabled?'已启动':'未启动'" /> <a-statistic
:title="$t('status.status')"
:value="engineEnabled?$t('status.started'):$t('status.stopped')"
/>
</a-col> </a-col>
<a-col :span="6"> <a-col :span="6">
<a-statistic title="已记录字幕" :value="captionData.length" /> <a-statistic :title="$t('status.logNumber')" :value="captionData.length" />
</a-col> </a-col>
<a-col :span="6"> <a-col :span="6">
<div class="about-tag">关于本项目</div> <div class="about-tag">{{ $t('status.aboutProj') }}</div>
<GithubOutlined class="proj-info" @click="showAbout = true"/> <GithubOutlined class="proj-info" @click="showAbout = true"/>
</a-col> </a-col>
</a-row> </a-row>
@@ -22,42 +28,51 @@
type="primary" type="primary"
class="control-button" class="control-button"
@click="openCaptionWindow" @click="openCaptionWindow"
>打开字幕窗口</a-button> >{{ $t('status.openCaption') }}</a-button>
<a-button <a-button
class="control-button" class="control-button"
@click="startEngine" @click="startEngine"
>启动字幕引擎</a-button> >{{ engineEnabled ? $t('status.restartEngine') : $t('status.startEngine') }}</a-button>
<!-- TODO 添加重启字幕引擎功能 -->
<a-button <a-button
danger class="control-button" danger class="control-button"
@click="stopEngine" @click="stopEngine"
>关闭字幕引擎</a-button> >{{ $t('status.stopEngine') }}</a-button>
</div> </div>
<a-modal v-model:open="showAbout" title="关于本项目" :footer="null"> <a-modal v-model:open="showAbout" :title="$t('status.about.title')" :footer="null">
<div class="about-modal-content"> <div class="about-modal-content">
<h2 class="about-title">Auto Caption 项目</h2> <h2 class="about-title">{{ $t('status.about.proj') }}</h2>
<p class="about-desc">一个跨平台的实时字幕显示软件</p> <p class="about-desc">{{ $t('status.about.desc') }}</p>
<a-divider /> <a-divider />
<div class="about-info"> <div class="about-info">
<p><b>作者</b>HiMeditator</p> <p><b>{{ $t('status.about.version') }}</b><a-tag color="green">v0.1.0</a-tag></p>
<p><b>版本</b>v0.1.0</p>
<p> <p>
<b>项目地址</b> <b>{{ $t('status.about.author') }}</b>
<a href="https://github.com/HiMeditator/auto-caption" target="_blank"> <a
GitHub | auto-caption href="https://github.com/HiMeditator"
target="_blank"
>
<a-tag color="blue">HiMeditator</a-tag>
</a> </a>
</p> </p>
<p> <p>
<b>用户手册</b> <b>{{ $t('status.about.projLink') }}</b>
<a href="https://github.com/HiMeditator/auto-caption" target="_blank">
<a-tag color="blue">GitHub | auto-caption</a-tag>
</a>
</p>
<p>
<b>{{ $t('status.about.manual') }}</b>
<a <a
href="https://github.com/HiMeditator/auto-caption/blob/main/assets/user-manual_zh.md" href="https://github.com/HiMeditator/auto-caption/blob/main/assets/user-manual_zh.md"
target="_blank" target="_blank"
> >
GitHub | user-manual_zh.md <a-tag color="blue">GitHub | user-manual_zh.md</a-tag>
</a> </a>
</p> </p>
</div> </div>
<div class="about-date">2026 6 26 </div> <div class="about-date">{{ $t('status.about.date') }}</div>
</div> </div>
</a-modal> </a-modal>
</template> </template>
@@ -125,6 +140,10 @@ function stopEngine() {
font-size: 1em; font-size: 1em;
} }
.about-info b {
margin-right: 1em;
}
.about-date { .about-date {
margin-top: 1.5em; margin-top: 1.5em;
color: #aaa; color: #aaa;

View File

@@ -1,8 +1,16 @@
<template> <template>
<a-card size="small" title="通用设置"> <a-card size="small" :title="$t('general.title')">
<div> <div>
<div class="input-item"> <div class="input-item">
<span class="input-label">边栏宽度</span> <span class="input-label">{{ $t('general.uiLanguage') }}</span>
<a-radio-group v-model:value="uiLanguage">
<a-radio-button value="zh">中文</a-radio-button>
<a-radio-button value="en">English</a-radio-button>
<a-radio-button value="ja">日本語</a-radio-button>
</a-radio-group>
</div>
<div class="input-item">
<span class="input-label">{{ $t('general.barWidth') }}</span>
<a-input <a-input
type="range" class="span-input" type="range" class="span-input"
min="6" max="12" v-model:value="leftBarWidth" min="6" max="12" v-model:value="leftBarWidth"
@@ -18,7 +26,7 @@ import { storeToRefs } from 'pinia'
import { useGeneralSettingStore } from '@renderer/stores/generalSetting' import { useGeneralSettingStore } from '@renderer/stores/generalSetting'
const generalSettingStore = useGeneralSettingStore() const generalSettingStore = useGeneralSettingStore()
const { leftBarWidth } = storeToRefs(generalSettingStore) const { uiLanguage, leftBarWidth } = storeToRefs(generalSettingStore)
</script> </script>
<style scoped> <style scoped>

View File

@@ -1,3 +1,76 @@
export default { export default {
example: {
"original": "这是字幕样式预览。",
"translation": "(Translation) This is a preview of subtitle styles."
},
general: {
"title": "General Settings",
"uiLanguage": "Language",
"barWidth": "Width"
},
engine: {
"title": "Caption Engine Settings",
"applyChange": "Apply Chnages",
"cancelChange": "Cancel Changes",
"sourceLang": "Source",
"transLang": "Translation",
"captionEngine": "Engine",
"audioType": "Audio Type",
"systemOutput": "System Audio Output (Speaker)",
"systemInput": "System Audio Input (Microphone)",
"enableTranslation": "Translation",
"customEngine": "Custom Engine",
custom: {
"title": "Custom Caption Engine",
"attention": "Attention",
"note": "Note: Allows users to provide captions using a custom engine. The provided engine should be able to start via the command line and can specify parameters through command-line instructions. The engine needs to communicate with the node.js backend using standard output. For more information, refer to the project's documentation.",
"app": "Engine Path",
"command": "Command"
}
},
style: {
"title": "Caption Style Settings",
"applyStyle": "Apply",
"cancelChange": "Cancel",
"resetStyle": "Reset",
"fontFamily": "Font Family",
"fontColor": "Font Color",
"fontSize": "Font Size",
"background": "Background",
"opacity": "Opacity",
"preview": "Preview",
"translation": "Show Translation",
trans: {
"title": "Translation Style Settings",
"useSame": "Use Original Style"
}
},
status: {
"engine": "Caption Engine",
"customized": "Customized",
"status": "Engine Status",
"started": "Started",
"stopped": "Not Started",
"logNumber": "Caption Count",
"aboutProj": "About Project",
"openCaption": "Open Caption Window",
"startEngine": "Start Caption Engine",
"restartEngine": "Restart Caption Engine",
"stopEngine": "Stop Caption Engine",
about: {
"title": "About This Project",
"proj": "Auto Caption Project",
"desc": "A cross-platform real-time caption display software supporting multiple languages.",
"version": "Software Version",
"author": "Project Author",
"projLink": "Project Link",
"manual": "User Manual",
"date": "June 26, 2026"
}
},
log: {
"title": "Caption Log",
"export": "Export Caption Log",
"clear": "Clear Caption Log"
}
} }

View File

@@ -1,3 +1,76 @@
export default { export default {
example: {
"original": "这是字幕样式预览。",
"translation": "(翻訳)これは字幕のスタイルのプレビューです。"
},
general: {
"title": "一般設定",
"uiLanguage": "言語設定",
"barWidth": "左側の幅"
},
engine: {
"title": "字幕エンジン設定",
"applyChange": "変更を適用",
"cancelChange": "変更をキャンセル",
"sourceLang": "ソース言語",
"transLang": "翻訳言語",
"captionEngine": "エンジン",
"audioType": "オーディオ",
"systemOutput": "システムオーディオ出力(スピーカー)",
"systemInput": "システムオーディオ入力(マイク)",
"enableTranslation": "翻訳",
"customEngine": "カスタムエンジン",
custom: {
"title": "カスタムキャプションエンジン",
"attention": "注意事項",
"note": "注意:ユーザーがカスタムエンジンを使用して字幕を提供できるようにします。提供するエンジンは、コマンドラインから起動でき、パラメータをコマンドラインの指示で指定できる必要があります。エンジンは、標準出力を使用して node.js バックエンドと通信する必要があります。詳細については、プロジェクトドキュメントを参照してください。",
"app": "パス",
"command": "コマンド"
}
},
style: {
"title": "字幕スタイル設定",
"applyStyle": "適用",
"cancelChange": "キャンセル",
"resetStyle": "リセット",
"fontFamily": "フォント",
"fontColor": "カラー",
"fontSize": "サイズ",
"background": "背景色",
"opacity": "不透明度",
"preview": "プレビュー",
"translation": "翻訳表示",
trans: {
"title": "翻訳スタイル設定",
"useSame": "原文のスタイルを使用"
}
},
status: {
"engine": "字幕エンジン",
"customized": "カスタマイズ済み",
"status": "エンジン状態",
"started": "開始済み",
"stopped": "未開始",
"logNumber": "字幕数",
"aboutProj": "プロジェクト情報",
"openCaption": "字幕ウィンドウを開く",
"startEngine": "字幕エンジンを開始",
"restartEngine": "字幕エンジンを再起動",
"stopEngine": "字幕エンジンを停止",
about: {
"title": "このプロジェクトについて",
"proj": "Auto Caption プロジェクト",
"desc": "複数の言語をサポートするクロスプラットフォームのリアルタイム字幕表示ソフトウェア。",
"version": "ソフトウェアバージョン",
"author": "プロジェクト作者",
"projLink": "プロジェクトリンク",
"manual": "ユーザーマニュアル",
"date": "2026 年 6 月 26 日"
}
},
log: {
"title": "字幕ログ",
"export": "エクスポート",
"clear": "字幕ログをクリア"
}
} }

View File

@@ -1,8 +1,76 @@
export default { export default {
example: { example: {
"original": "This is a preview of subtitle styles.", "original": "This is a preview of subtitle styles.",
"translation": "这是字幕样式预览(翻译)" "translation": "(翻译)这是字幕样式预览"
}, },
general: { general: {
"title": "通用设置",
"uiLanguage": "界面语言",
"barWidth": "左侧宽度"
},
engine: {
"title": "字幕引擎设置",
"applyChange": "应用更改",
"cancelChange": "取消更改",
"sourceLang": "源语言",
"transLang": "翻译语言",
"captionEngine": "字幕引擎",
"audioType": "音频类型",
"systemOutput": "系统音频输出(扬声器)",
"systemInput": "系统音频输入(麦克风)",
"enableTranslation": "启用翻译",
"customEngine": "自定义引擎",
custom: {
"title": "自定义字幕引擎",
"attention": "注意事项",
"note": "说明:允许用户使用自定义引擎提供字幕。提供的引擎要能通过命令行启动,且可以提供命令行指令来指定参数。引擎需要使用标准输出与软件 node.js 后端进行通信。详细信息参考项目文档。",
"app": "引擎路径",
"command": "引擎指令"
}
},
style: {
"title": "字幕样式设置",
"applyStyle": "应用样式",
"cancelChange": "取消更改",
"resetStyle": "恢复默认",
"fontFamily": "字体族",
"fontColor": "字体颜色",
"fontSize": "字体大小",
"background": "背景颜色",
"opacity": "不透明度",
"preview": "显示预览",
"translation": "显示翻译",
trans: {
"title": "翻译样式设置",
"useSame": "使用原文样式"
}
},
status: {
"engine": "字幕引擎",
"customized": "自定义",
"status": "引擎状态",
"started": "已启动",
"stopped": "未启动",
"logNumber": "字幕数量",
"aboutProj": "项目关于",
"openCaption": "打开字幕窗口",
"startEngine": "启动字幕引擎",
"restartEngine": "重启字幕引擎",
"stopEngine": "关闭字幕引擎",
about: {
"title": "关于本项目",
"proj": "Auto Caption 项目",
"desc": "一个跨平台的支持多种语言的实时字幕显示软件。",
"version": "软件版本",
"author": "项目作者",
"projLink": "项目链接",
"manual": "用户手册",
"date": "2026 年 6 月 26 日"
}
},
log: {
"title": "字幕记录",
"export": "导出字幕记录",
"clear": "清空字幕记录"
} }
} }

View File

@@ -1,9 +1,19 @@
import { ref } from 'vue' import { ref, watch } from 'vue'
import { defineStore } from 'pinia' import { defineStore } from 'pinia'
import i18n from '../i18n'
import type { UILanguage } from '../types'
export const useGeneralSettingStore = defineStore('generalSetting', () => { export const useGeneralSettingStore = defineStore('generalSetting', () => {
const uiLanguage = ref<UILanguage>('zh')
const leftBarWidth = ref<number>(8) const leftBarWidth = ref<number>(8)
watch(uiLanguage, (newValue) => {
i18n.global.locale.value = newValue
console.log(newValue)
})
return { return {
uiLanguage,
leftBarWidth leftBarWidth
} }
}) })