2.4.3
This commit is contained in:
@@ -14,9 +14,19 @@
|
||||
<div class="flex items-center justify-between mb-3">
|
||||
<span class="font-medium text-gray-800">源文本</span>
|
||||
<div class="flex gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<label class="flex items-center gap-1 cursor-pointer">
|
||||
<input type="radio" v-model="inputMode" value="bulk" class="w-4 h-4" />
|
||||
<span class="text-sm text-gray-700">批量导入</span>
|
||||
</label>
|
||||
<label class="flex items-center gap-1 cursor-pointer">
|
||||
<input type="radio" v-model="inputMode" value="individual" class="w-4 h-4" />
|
||||
<span class="text-sm text-gray-700">单个编辑</span>
|
||||
</label>
|
||||
</div>
|
||||
<button @click="addSentence"
|
||||
class="px-3 py-1 text-sm bg-blue-100 text-blue-700 border border-blue-300 rounded hover:bg-blue-200">
|
||||
新增一行
|
||||
新增
|
||||
</button>
|
||||
<button @click="fetchPrologue" :disabled="isFetching || !isElectronEnv"
|
||||
class="px-3 py-1 text-sm bg-purple-100 text-purple-700 border border-purple-300 rounded hover:bg-purple-200 disabled:opacity-50">
|
||||
@@ -29,12 +39,32 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<textarea :value="bulkText || sentences.join('\n')" @input="handleBulkChange" @paste="handlePaste"
|
||||
placeholder="每行一句打招呼内容..."
|
||||
class="w-full h-32 p-3 border border-gray-300 rounded text-sm text-gray-900 resize-none focus:border-blue-500 focus:outline-none" />
|
||||
<!-- 批量导入模式 -->
|
||||
<div v-if="inputMode === 'bulk'">
|
||||
<textarea :value="bulkText || sentences.join('\n')" @input="handleBulkChange"
|
||||
@paste="handlePaste" placeholder="每行一句打招呼内容..."
|
||||
class="w-full h-32 p-3 border border-gray-300 rounded text-sm text-gray-900 resize-none focus:border-blue-500 focus:outline-none" />
|
||||
|
||||
<div class="text-xs text-gray-500 mt-2">
|
||||
提示: 每行一句,可直接粘贴多行文本
|
||||
<div class="text-xs text-gray-500 mt-2">
|
||||
提示: 每行一句,可直接粘贴多行文本
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 单个编辑模式 -->
|
||||
<div v-else class="space-y-3">
|
||||
<div v-for="(sentence, index) in sentences" :key="index"
|
||||
class="bg-white rounded border border-gray-200 p-3">
|
||||
<div class="flex items-center justify-between mb-2">
|
||||
<span class="text-xs text-gray-500">话术 {{ index + 1 }}</span>
|
||||
<button @click="removeSentence(index)"
|
||||
class="text-red-500 hover:text-red-700 text-sm">
|
||||
删除
|
||||
</button>
|
||||
</div>
|
||||
<textarea :value="sentence" @input="updateSentence($event.target.value, index)"
|
||||
placeholder="输入打招呼内容(可包含多行)..."
|
||||
class="w-full h-20 p-2 border border-gray-200 rounded text-sm text-gray-900 resize-none focus:border-blue-500 focus:outline-none" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -78,13 +108,15 @@
|
||||
]">
|
||||
{{ region }}
|
||||
</div>
|
||||
<div v-if="filteredRegions.length === 0" class="col-span-full text-center py-8 text-gray-400">
|
||||
<div v-if="filteredRegions.length === 0"
|
||||
class="col-span-full text-center py-8 text-gray-400">
|
||||
未找到相关大区
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 选中大区的语言预览 -->
|
||||
<div v-if="selectedRegions.length > 0" class="mb-4 p-3 bg-blue-50 border border-blue-200 rounded">
|
||||
<div v-if="selectedRegions.length > 0"
|
||||
class="mb-4 p-3 bg-blue-50 border border-blue-200 rounded">
|
||||
<div class="text-sm text-blue-800 font-medium mb-2">
|
||||
选中 {{ selectedRegions.length }} 个大区,将翻译以下 {{ selectedLanguages.length }} 种语言:
|
||||
</div>
|
||||
@@ -112,7 +144,8 @@
|
||||
<!-- 当前语言的翻译结果 -->
|
||||
<div class="space-y-2 max-h-40 overflow-auto">
|
||||
<template v-if="translations[activeTab]?.length">
|
||||
<div v-for="(t, i) in translations[activeTab]" :key="i" class="flex items-center gap-2">
|
||||
<div v-for="(t, i) in translations[activeTab]" :key="i"
|
||||
class="flex items-center gap-2">
|
||||
<input type="text" :value="t" @input="updateTranslation($event.target.value, i)"
|
||||
class="flex-1 px-3 py-1.5 text-sm text-gray-900 border border-gray-300 rounded focus:border-blue-500 focus:outline-none" />
|
||||
<div class="relative group/source">
|
||||
@@ -141,22 +174,23 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 底部 -->
|
||||
<div class="p-4 border-t border-gray-200 flex justify-between items-center">
|
||||
<span class="text-xs text-gray-500">
|
||||
共 {{ sentences.filter(Boolean).length }} 句 · 选择 {{ selectedRegions.length }} 个大区 · {{
|
||||
selectedLanguages.length }} 种语言
|
||||
</span>
|
||||
<div class="flex gap-3">
|
||||
<button @click="onClose" class="px-4 py-2 text-sm text-gray-600 hover:bg-gray-100 rounded-lg">
|
||||
取消
|
||||
</button>
|
||||
<button @click="handleConfirm"
|
||||
class="px-4 py-2 text-sm bg-blue-500 text-white rounded-lg hover:bg-blue-600">
|
||||
确定
|
||||
</button>
|
||||
<!-- 底部 -->
|
||||
<div class="p-4 border-t border-gray-200 flex justify-between items-center">
|
||||
<span class="text-xs text-gray-500">
|
||||
共 {{ sentences.filter(Boolean).length }} 句 · 选择 {{ selectedRegions.length }} 个大区 · {{
|
||||
selectedLanguages.length }} 种语言
|
||||
</span>
|
||||
<div class="flex gap-3">
|
||||
<button @click="onClose"
|
||||
class="px-4 py-2 text-sm text-gray-600 hover:bg-gray-100 rounded-lg">
|
||||
取消
|
||||
</button>
|
||||
<button @click="handleConfirm"
|
||||
class="px-4 py-2 text-sm bg-blue-500 text-white rounded-lg hover:bg-blue-600">
|
||||
确定
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -180,6 +214,7 @@ const REGION_LIST = getRegions()
|
||||
|
||||
const sentences = ref([''])
|
||||
const bulkText = ref('')
|
||||
const inputMode = ref('bulk') // 'bulk' 或 'individual'
|
||||
const selectedRegions = ref([])
|
||||
const translations = ref({})
|
||||
const activeTab = ref('')
|
||||
@@ -262,6 +297,7 @@ function loadFromStorage() {
|
||||
if (data.translations) translations.value = data.translations
|
||||
if (typeof data.needTranslate === 'boolean') needTranslate.value = data.needTranslate
|
||||
if (data.activeTab) activeTab.value = data.activeTab
|
||||
if (data.inputMode) inputMode.value = data.inputMode
|
||||
} catch (e) {
|
||||
console.error('加载本地数据失败:', e)
|
||||
}
|
||||
@@ -275,6 +311,7 @@ function saveToStorage() {
|
||||
translations: translations.value,
|
||||
needTranslate: needTranslate.value,
|
||||
activeTab: activeTab.value,
|
||||
inputMode: inputMode.value,
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -285,6 +322,17 @@ const addSentence = () => {
|
||||
sentences.value.push('')
|
||||
}
|
||||
|
||||
const updateSentence = (value, index) => {
|
||||
sentences.value[index] = value
|
||||
}
|
||||
|
||||
const removeSentence = (index) => {
|
||||
sentences.value.splice(index, 1)
|
||||
if (sentences.value.length === 0) {
|
||||
sentences.value.push('')
|
||||
}
|
||||
}
|
||||
|
||||
const handlePaste = (e) => {
|
||||
// e.preventDefault() handled by Vue if needed but standard logic applies
|
||||
// We can rely on @paste event
|
||||
@@ -397,6 +445,7 @@ const handleTranslate = async () => {
|
||||
try {
|
||||
const result = await window.electronAPI.translate(joinedText, lang)
|
||||
if (result.success) {
|
||||
console.log(`翻译结果完整 ${lang} 成功:`, result)
|
||||
let translatedLines = result.result.split('\n').map(s => s.trim())
|
||||
|
||||
if (translatedLines.length > 0) {
|
||||
|
||||
Reference in New Issue
Block a user