change ui to zh
This commit is contained in:
@@ -13,8 +13,8 @@
|
|||||||
"windows": [
|
"windows": [
|
||||||
{
|
{
|
||||||
"title": "gemmatrans-client",
|
"title": "gemmatrans-client",
|
||||||
"width": 800,
|
"width": 1400,
|
||||||
"height": 600
|
"height": 900
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"security": {
|
"security": {
|
||||||
|
|||||||
40
src/App.vue
40
src/App.vue
@@ -158,14 +158,14 @@ const translate = async () => {
|
|||||||
<button
|
<button
|
||||||
@click="view = 'settings'"
|
@click="view = 'settings'"
|
||||||
:class="cn('p-2 rounded-full transition-colors', view === 'settings' ? 'bg-blue-50 text-blue-600' : 'hover:bg-slate-100 text-slate-600')"
|
:class="cn('p-2 rounded-full transition-colors', view === 'settings' ? 'bg-blue-50 text-blue-600' : 'hover:bg-slate-100 text-slate-600')"
|
||||||
title="Settings"
|
title="设置"
|
||||||
>
|
>
|
||||||
<Settings class="w-5 h-5" />
|
<Settings class="w-5 h-5" />
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
@click="view = 'logs'"
|
@click="view = 'logs'"
|
||||||
:class="cn('p-2 rounded-full transition-colors', view === 'logs' ? 'bg-blue-50 text-blue-600' : 'hover:bg-slate-100 text-slate-600')"
|
:class="cn('p-2 rounded-full transition-colors', view === 'logs' ? 'bg-blue-50 text-blue-600' : 'hover:bg-slate-100 text-slate-600')"
|
||||||
title="Debug Logs"
|
title="调试日志"
|
||||||
>
|
>
|
||||||
<FileText class="w-5 h-5" />
|
<FileText class="w-5 h-5" />
|
||||||
</button>
|
</button>
|
||||||
@@ -184,18 +184,18 @@ const translate = async () => {
|
|||||||
>
|
>
|
||||||
<option v-for="lang in LANGUAGES" :key="lang.code" :value="lang.code">{{ lang.name }}</option>
|
<option v-for="lang in LANGUAGES" :key="lang.code" :value="lang.code">{{ lang.name }}</option>
|
||||||
</select>
|
</select>
|
||||||
<button @click="swapLanguages" class="p-1.5 hover:bg-slate-200 rounded-md transition-colors">
|
<button @click="swapLanguages" class="p-1.5 hover:bg-slate-200 rounded-md transition-colors" title="交换语言">
|
||||||
<ArrowRightLeft class="w-4 h-4 text-slate-500" />
|
<ArrowRightLeft class="w-4 h-4 text-slate-500" />
|
||||||
</button>
|
</button>
|
||||||
<div class="ml-auto flex items-center gap-2">
|
<div class="ml-auto flex items-center gap-2">
|
||||||
<button @click="clearSource" class="p-1.5 hover:bg-slate-200 rounded-md transition-colors" title="Clear">
|
<button @click="clearSource" class="p-1.5 hover:bg-slate-200 rounded-md transition-colors" title="清空内容">
|
||||||
<Trash2 class="w-4 h-4 text-slate-500" />
|
<Trash2 class="w-4 h-4 text-slate-500" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<textarea
|
<textarea
|
||||||
v-model="sourceText"
|
v-model="sourceText"
|
||||||
placeholder="Type text here..."
|
placeholder="请输入待翻译内容..."
|
||||||
class="flex-1 p-6 resize-none outline-none text-lg leading-relaxed placeholder:text-slate-300"
|
class="flex-1 p-6 resize-none outline-none text-lg leading-relaxed placeholder:text-slate-300"
|
||||||
></textarea>
|
></textarea>
|
||||||
<div class="p-4 border-t flex justify-end">
|
<div class="p-4 border-t flex justify-end">
|
||||||
@@ -206,7 +206,7 @@ const translate = async () => {
|
|||||||
>
|
>
|
||||||
<Loader2 v-if="isTranslating" class="w-4 h-4 animate-spin" />
|
<Loader2 v-if="isTranslating" class="w-4 h-4 animate-spin" />
|
||||||
<Send v-else class="w-4 h-4" />
|
<Send v-else class="w-4 h-4" />
|
||||||
{{ isTranslating ? 'Translating...' : 'Translate' }}
|
{{ isTranslating ? '正在翻译...' : '翻译' }}
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -221,7 +221,7 @@ const translate = async () => {
|
|||||||
<option v-for="lang in LANGUAGES" :key="lang.code" :value="lang.code">{{ lang.name }}</option>
|
<option v-for="lang in LANGUAGES" :key="lang.code" :value="lang.code">{{ lang.name }}</option>
|
||||||
</select>
|
</select>
|
||||||
<div class="ml-auto flex items-center gap-2">
|
<div class="ml-auto flex items-center gap-2">
|
||||||
<button @click="copyTarget" class="p-1.5 hover:bg-slate-200 rounded-md transition-colors relative" title="Copy">
|
<button @click="copyTarget" class="p-1.5 hover:bg-slate-200 rounded-md transition-colors relative" title="复制结果">
|
||||||
<Check v-if="showCopyFeedback" class="w-4 h-4 text-green-600" />
|
<Check v-if="showCopyFeedback" class="w-4 h-4 text-green-600" />
|
||||||
<Copy v-else class="w-4 h-4 text-slate-500" />
|
<Copy v-else class="w-4 h-4 text-slate-500" />
|
||||||
</button>
|
</button>
|
||||||
@@ -231,7 +231,7 @@ const translate = async () => {
|
|||||||
<template v-if="targetText">
|
<template v-if="targetText">
|
||||||
{{ targetText }}
|
{{ targetText }}
|
||||||
</template>
|
</template>
|
||||||
<span v-else class="text-slate-300 italic">Translation will appear here...</span>
|
<span v-else class="text-slate-300 italic">翻译结果将在此显示...</span>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -240,10 +240,10 @@ const translate = async () => {
|
|||||||
<div v-else-if="view === 'settings'" class="flex-1 overflow-y-auto bg-slate-50 p-6 md:p-10">
|
<div v-else-if="view === 'settings'" class="flex-1 overflow-y-auto bg-slate-50 p-6 md:p-10">
|
||||||
<div class="max-w-2xl mx-auto space-y-8">
|
<div class="max-w-2xl mx-auto space-y-8">
|
||||||
<section>
|
<section>
|
||||||
<h2 class="text-sm font-semibold text-slate-500 uppercase tracking-wider mb-4">API Configuration</h2>
|
<h2 class="text-sm font-semibold text-slate-500 uppercase tracking-wider mb-4">API 配置</h2>
|
||||||
<div class="bg-white rounded-xl shadow-sm border p-6 space-y-4">
|
<div class="bg-white rounded-xl shadow-sm border p-6 space-y-4">
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<label class="text-sm font-medium text-slate-700">Ollama API Address</label>
|
<label class="text-sm font-medium text-slate-700">Ollama API 地址</label>
|
||||||
<input
|
<input
|
||||||
v-model="settings.ollamaApiAddress"
|
v-model="settings.ollamaApiAddress"
|
||||||
type="text"
|
type="text"
|
||||||
@@ -252,7 +252,7 @@ const translate = async () => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<label class="text-sm font-medium text-slate-700">Ollama Model Name</label>
|
<label class="text-sm font-medium text-slate-700">Ollama 模型名称</label>
|
||||||
<input
|
<input
|
||||||
v-model="settings.modelName"
|
v-model="settings.modelName"
|
||||||
type="text"
|
type="text"
|
||||||
@@ -262,8 +262,8 @@ const translate = async () => {
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<label class="text-sm font-medium text-slate-700">Enable Streaming</label>
|
<label class="text-sm font-medium text-slate-700">启用流式输出</label>
|
||||||
<p class="text-xs text-slate-500">Render text as it is generated</p>
|
<p class="text-xs text-slate-500">在生成时即时渲染文本</p>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
@click="settings.enableStreaming = !settings.enableStreaming"
|
@click="settings.enableStreaming = !settings.enableStreaming"
|
||||||
@@ -282,12 +282,12 @@ const translate = async () => {
|
|||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section>
|
<section>
|
||||||
<h2 class="text-sm font-semibold text-slate-500 uppercase tracking-wider mb-4">Prompt Engineering</h2>
|
<h2 class="text-sm font-semibold text-slate-500 uppercase tracking-wider mb-4">提示词工程</h2>
|
||||||
<div class="bg-white rounded-xl shadow-sm border p-6">
|
<div class="bg-white rounded-xl shadow-sm border p-6">
|
||||||
<div class="space-y-2">
|
<div class="space-y-2">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<label class="text-sm font-medium text-slate-700">System Prompt Template</label>
|
<label class="text-sm font-medium text-slate-700">系统提示词模板</label>
|
||||||
<button @click="settings.systemPromptTemplate = DEFAULT_TEMPLATE" class="text-xs text-blue-600 hover:underline">Reset to Default</button>
|
<button @click="settings.systemPromptTemplate = DEFAULT_TEMPLATE" class="text-xs text-blue-600 hover:underline">恢复默认值</button>
|
||||||
</div>
|
</div>
|
||||||
<textarea
|
<textarea
|
||||||
v-model="settings.systemPromptTemplate"
|
v-model="settings.systemPromptTemplate"
|
||||||
@@ -307,18 +307,18 @@ const translate = async () => {
|
|||||||
<div v-else-if="view === 'logs'" class="flex-1 overflow-y-auto bg-slate-50 p-6 md:p-10">
|
<div v-else-if="view === 'logs'" class="flex-1 overflow-y-auto bg-slate-50 p-6 md:p-10">
|
||||||
<div class="max-w-3xl mx-auto space-y-6">
|
<div class="max-w-3xl mx-auto space-y-6">
|
||||||
<div class="flex items-center justify-between">
|
<div class="flex items-center justify-between">
|
||||||
<h2 class="text-sm font-semibold text-slate-500 uppercase tracking-wider">Debug Logs</h2>
|
<h2 class="text-sm font-semibold text-slate-500 uppercase tracking-wider">调试日志</h2>
|
||||||
<button
|
<button
|
||||||
@click="settings.logs = []"
|
@click="settings.logs = []"
|
||||||
class="text-xs text-red-600 hover:underline flex items-center gap-1"
|
class="text-xs text-red-600 hover:underline flex items-center gap-1"
|
||||||
>
|
>
|
||||||
<Trash2 class="w-3 h-3" />
|
<Trash2 class="w-3 h-3" />
|
||||||
Clear All Logs
|
清空全部日志
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="bg-white rounded-xl shadow-sm border p-4 space-y-4">
|
<div class="bg-white rounded-xl shadow-sm border p-4 space-y-4">
|
||||||
<div v-if="settings.logs.length === 0" class="text-sm text-slate-400 text-center py-10 italic">
|
<div v-if="settings.logs.length === 0" class="text-sm text-slate-400 text-center py-10 italic">
|
||||||
No logs recorded yet. Try translating something.
|
暂无日志记录。请尝试进行翻译。
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
v-for="(log, idx) in settings.logs"
|
v-for="(log, idx) in settings.logs"
|
||||||
@@ -334,7 +334,7 @@ const translate = async () => {
|
|||||||
log.type === 'response' ? 'bg-green-100 text-green-700' :
|
log.type === 'response' ? 'bg-green-100 text-green-700' :
|
||||||
'bg-red-100 text-red-700'
|
'bg-red-100 text-red-700'
|
||||||
)"
|
)"
|
||||||
>{{ log.type }}</span>
|
>{{ log.type === 'request' ? '请求' : log.type === 'response' ? '响应' : '错误' }}</span>
|
||||||
</div>
|
</div>
|
||||||
<pre class="bg-slate-50 p-3 rounded-lg overflow-x-auto text-slate-600 max-h-48 leading-relaxed shadow-inner border border-slate-100">{{ typeof log.content === 'object' ? JSON.stringify(log.content, null, 2) : log.content }}</pre>
|
<pre class="bg-slate-50 p-3 rounded-lg overflow-x-auto text-slate-600 max-h-48 leading-relaxed shadow-inner border border-slate-100">{{ typeof log.content === 'object' ? JSON.stringify(log.content, null, 2) : log.content }}</pre>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -8,12 +8,12 @@ export interface Language {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const LANGUAGES: Language[] = [
|
export const LANGUAGES: Language[] = [
|
||||||
{ name: 'English', code: 'en' },
|
{ name: '英语', code: 'en' },
|
||||||
{ name: 'Chinese', code: 'zh-Hans' },
|
{ name: '中文', code: 'zh-Hans' },
|
||||||
{ name: 'Japanese', code: 'ja' },
|
{ name: '日语', code: 'ja' },
|
||||||
{ name: 'Spanish', code: 'es' },
|
{ name: '西班牙语', code: 'es' },
|
||||||
{ name: 'French', code: 'fr' },
|
{ name: '法语', code: 'fr' },
|
||||||
{ name: 'German', code: 'de' },
|
{ name: '德语', code: 'de' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const DEFAULT_TEMPLATE = `You are a professional {SOURCE_LANG} ({SOURCE_CODE}) to {TARGET_LANG} ({TARGET_CODE}) translator. Your goal is to accurately convey the meaning and nuances of the original {SOURCE_LANG} text while adhering to {TARGET_LANG} grammar, vocabulary, and cultural sensitivities.
|
export const DEFAULT_TEMPLATE = `You are a professional {SOURCE_LANG} ({SOURCE_CODE}) to {TARGET_LANG} ({TARGET_CODE}) translator. Your goal is to accurately convey the meaning and nuances of the original {SOURCE_LANG} text while adhering to {TARGET_LANG} grammar, vocabulary, and cultural sensitivities.
|
||||||
|
|||||||
Reference in New Issue
Block a user