From 53f078154ed7fb94aa210afa22e0e3c08d729d9d Mon Sep 17 00:00:00 2001 From: Julian Date: Mon, 20 Apr 2026 13:14:43 -0400 Subject: [PATCH] fix 5 --- src/components/ConversationView.vue | 6 +- src/components/HistoryView.vue | 2 +- src/components/SettingsView.vue | 4 +- src/components/TranslationView.vue | 3 +- src/domain/translation.ts | 89 ++++++++++++++++++++++++++++ src/lib/prompt-builders.ts | 2 +- src/lib/translation-service.ts | 2 +- src/stores/conversation.ts | 2 +- src/stores/history.ts | 2 +- src/stores/settings.ts | 91 +---------------------------- 10 files changed, 103 insertions(+), 100 deletions(-) create mode 100644 src/domain/translation.ts diff --git a/src/components/ConversationView.vue b/src/components/ConversationView.vue index f4a0011..2181bda 100644 --- a/src/components/ConversationView.vue +++ b/src/components/ConversationView.vue @@ -7,12 +7,14 @@ import { ShieldCheck, RotateCcw } from 'lucide-vue-next'; import { - useSettingsStore, + useSettingsStore, +} from '../stores/settings'; +import { LANGUAGES, SPEAKER_IDENTITY_OPTIONS, TONE_REGISTER_OPTIONS, type Participant -} from '../stores/settings'; +} from '../domain/translation'; import { useConversationStore } from '../stores/conversation'; import { useLogsStore } from '../stores/logs'; import { cn } from '../lib/utils'; diff --git a/src/components/HistoryView.vue b/src/components/HistoryView.vue index 68506cc..0a51a12 100644 --- a/src/components/HistoryView.vue +++ b/src/components/HistoryView.vue @@ -2,7 +2,7 @@ import { ref, computed, watch } from 'vue'; import { Clock, Search, ArrowRightLeft, Trash2, User, Type, Copy, Check, FileText } from 'lucide-vue-next'; import { useHistoryStore } from '../stores/history'; -import { SPEAKER_IDENTITY_OPTIONS, TONE_REGISTER_OPTIONS } from '../stores/settings'; +import { SPEAKER_IDENTITY_OPTIONS, TONE_REGISTER_OPTIONS } from '../domain/translation'; import { cn } from '../lib/utils'; import { useClipboard } from '../composables/useClipboard'; diff --git a/src/components/SettingsView.vue b/src/components/SettingsView.vue index e9c939e..6134ab2 100644 --- a/src/components/SettingsView.vue +++ b/src/components/SettingsView.vue @@ -8,9 +8,9 @@ import { DEFAULT_REFINEMENT_TEMPLATE, CONVERSATION_SYSTEM_PROMPT_TEMPLATE, CONVERSATION_EVALUATION_PROMPT_TEMPLATE, - CONVERSATION_REFINEMENT_PROMPT_TEMPLATE, - type ApiProfile + CONVERSATION_REFINEMENT_PROMPT_TEMPLATE } from '../stores/settings'; +import type { ApiProfile } from '../domain/translation'; import { cn } from '../lib/utils'; import HistoryView from './HistoryView.vue'; import LogsView from './LogsView.vue'; diff --git a/src/components/TranslationView.vue b/src/components/TranslationView.vue index d3695f8..5bb7e1f 100644 --- a/src/components/TranslationView.vue +++ b/src/components/TranslationView.vue @@ -3,7 +3,8 @@ import { ref, computed, onMounted, onUnmounted } from 'vue'; import { storeToRefs } from 'pinia'; import { ChevronDown, Check, ArrowRightLeft, Trash2, FileText, Plus, Loader2, Send, User, Type, Copy, Save } from 'lucide-vue-next'; import { listen } from '@tauri-apps/api/event'; -import { useSettingsStore, LANGUAGES, SPEAKER_IDENTITY_OPTIONS, TONE_REGISTER_OPTIONS } from '../stores/settings'; +import { LANGUAGES, SPEAKER_IDENTITY_OPTIONS, TONE_REGISTER_OPTIONS } from '../domain/translation'; +import { useSettingsStore } from '../stores/settings'; import { useHistoryStore } from '../stores/history'; import { useLogsStore } from '../stores/logs'; import { useTranslationWorkspaceStore } from '../stores/translation-workspace'; diff --git a/src/domain/translation.ts b/src/domain/translation.ts new file mode 100644 index 0000000..2bc86c4 --- /dev/null +++ b/src/domain/translation.ts @@ -0,0 +1,89 @@ +export interface Language { + displayName: string; + englishName: string; + code: string; +} + +export const LANGUAGES: Language[] = [ + { displayName: '中文(简体)', englishName: 'Simplified Chinese', code: 'zh-Hans' }, + { displayName: '中文(繁体)', englishName: 'Traditional Chinese', code: 'zh-Hant' }, + { displayName: '英语(美国)', englishName: 'American English', code: 'en-US' }, + { displayName: '英语(英国)', englishName: 'British English', code: 'en-GB' }, + { displayName: '西班牙语', englishName: 'Spanish', code: 'es' }, + { displayName: '葡萄牙语', englishName: 'Portuguese', code: 'pt' }, + { displayName: '日语', englishName: 'Japanese', code: 'ja' }, + { displayName: '韩语', englishName: 'Korean', code: 'ko' }, + { displayName: '法语', englishName: 'French', code: 'fr' }, + { displayName: '德语', englishName: 'German', code: 'de' }, + { displayName: '意大利语', englishName: 'Italian', code: 'it' }, + { displayName: '俄语', englishName: 'Russian', code: 'ru' }, + { displayName: '越南语', englishName: 'Vietnamese', code: 'vi' }, + { displayName: '泰语', englishName: 'Thai', code: 'th' }, + { displayName: '阿拉伯语', englishName: 'Arabic', code: 'ar' }, +]; + +export const SPEAKER_IDENTITY_OPTIONS = [ + { label: '男性', value: 'Male' }, + { label: '女性', value: 'Female' }, + { label: '中性', value: 'Gender-neutral' }, +] as const; + +export const TONE_REGISTER_OPTIONS = [ + { label: '自动识别', value: 'Auto-detect', description: '分析并保持原文的语气、情绪和礼貌程度' }, + { label: '正式专业', value: 'Formal & Professional', description: '商务邮件、法律合同、官方报告' }, + { label: '礼貌客气', value: 'Polite & Respectful', description: '与长辈、客户或初次见面的人交流' }, + { label: '礼貌随和', value: 'Polite & Conversational', description: '得体但不刻板的日常对话' }, + { label: '中性标准', value: 'Neutral & Standard', description: '维基百科、说明书、客观的新闻报道' }, + { label: '非正式', value: 'Casual & Informal', description: '朋友聊天、社交媒体、非正式简讯' }, + { label: '亲切友好', value: 'Warm & Friendly', description: '社区信函、给朋友的建议、温馨提示' }, + { label: '严谨权威', value: 'Strict & Authoritative', description: '警示标志、强制规定、上级指令' }, + { label: '热情生动', value: 'Enthusiastic & Vivid', description: '广告文案、旅游推荐、博主推文' }, +] as const; + +export interface ApiProfile { + id: string; + name: string; + apiBaseUrl: string; + apiKey: string; + modelName: string; +} + +export interface HistoryItem { + id: string; + timestamp: string; + sourceLang: Language; + targetLang: Language; + sourceText: string; + targetText: string; + context: string; + speakerIdentity: string; + toneRegister: string; + modelName: string; +} + +export interface Participant { + name: string; + gender: string; + language: Language; + tone: string; +} + +export interface ChatMessage { + id: string; + sender: 'me' | 'partner'; + original: string; + translated: string; + timestamp: string; + evaluation?: string; + isEvaluating?: boolean; + isRefining?: boolean; +} + +export interface ChatSession { + id: string; + title: string; + me: Participant; + partner: Participant; + messages: ChatMessage[]; + lastActivity: string; +} diff --git a/src/lib/prompt-builders.ts b/src/lib/prompt-builders.ts index 346c84b..5474630 100644 --- a/src/lib/prompt-builders.ts +++ b/src/lib/prompt-builders.ts @@ -1,4 +1,4 @@ -import type { Language, Participant } from '../stores/settings'; +import type { Language, Participant } from '../domain/translation'; interface SingleTranslationPromptContext { sourceLang: Language; diff --git a/src/lib/translation-service.ts b/src/lib/translation-service.ts index 14d6b57..a0cbe8d 100644 --- a/src/lib/translation-service.ts +++ b/src/lib/translation-service.ts @@ -1,5 +1,5 @@ import { invoke } from '@tauri-apps/api/core'; -import type { ApiProfile } from '../stores/settings'; +import type { ApiProfile } from '../domain/translation'; interface Message { role: string; diff --git a/src/stores/conversation.ts b/src/stores/conversation.ts index 139d8c1..22cd021 100644 --- a/src/stores/conversation.ts +++ b/src/stores/conversation.ts @@ -1,6 +1,6 @@ import { defineStore } from 'pinia'; import { useLocalStorage } from '@vueuse/core'; -import type { ChatMessage, ChatSession, Participant } from './settings'; +import type { ChatMessage, ChatSession, Participant } from '../domain/translation'; function formatTimestamp() { const now = new Date(); diff --git a/src/stores/history.ts b/src/stores/history.ts index 8c84723..16fc735 100644 --- a/src/stores/history.ts +++ b/src/stores/history.ts @@ -1,6 +1,6 @@ import { defineStore } from 'pinia'; import { useLocalStorage } from '@vueuse/core'; -import type { HistoryItem } from './settings'; +import type { HistoryItem } from '../domain/translation'; function formatTimestamp() { const now = new Date(); diff --git a/src/stores/settings.ts b/src/stores/settings.ts index 03db3d5..c4f9956 100644 --- a/src/stores/settings.ts +++ b/src/stores/settings.ts @@ -1,48 +1,7 @@ import { computed } from 'vue'; import { defineStore } from 'pinia'; import { useLocalStorage } from '@vueuse/core'; - -export interface Language { - displayName: string; // UI 显示的中文名,如 "英语(英国)" - englishName: string; // 文件中的第二列,用于 {SOURCE_LANG} - code: string; // 文件中的第一列,用于 {SOURCE_CODE} -} - -export const LANGUAGES: Language[] = [ - { displayName: '中文(简体)', englishName: 'Simplified Chinese', code: 'zh-Hans' }, - { displayName: '中文(繁体)', englishName: 'Traditional Chinese', code: 'zh-Hant' }, - { displayName: '英语(美国)', englishName: 'American English', code: 'en-US' }, - { displayName: '英语(英国)', englishName: 'British English', code: 'en-GB' }, - { displayName: '西班牙语', englishName: 'Spanish', code: 'es' }, - { displayName: '葡萄牙语', englishName: 'Portuguese', code: 'pt' }, - { displayName: '日语', englishName: 'Japanese', code: 'ja' }, - { displayName: '韩语', englishName: 'Korean', code: 'ko' }, - { displayName: '法语', englishName: 'French', code: 'fr' }, - { displayName: '德语', englishName: 'German', code: 'de' }, - { displayName: '意大利语', englishName: 'Italian', code: 'it' }, - { displayName: '俄语', englishName: 'Russian', code: 'ru' }, - { displayName: '越南语', englishName: 'Vietnamese', code: 'vi' }, - { displayName: '泰语', englishName: 'Thai', code: 'th' }, - { displayName: '阿拉伯语', englishName: 'Arabic', code: 'ar' }, -]; - -export const SPEAKER_IDENTITY_OPTIONS = [ - { label: '男性', value: 'Male' }, - { label: '女性', value: 'Female' }, - { label: '中性', value: 'Gender-neutral' }, -]; - -export const TONE_REGISTER_OPTIONS = [ - { label: '自动识别', value: 'Auto-detect', description: '分析并保持原文的语气、情绪和礼貌程度' }, - { label: '正式专业', value: 'Formal & Professional', description: '商务邮件、法律合同、官方报告' }, - { label: '礼貌客气', value: 'Polite & Respectful', description: '与长辈、客户或初次见面的人交流' }, - { label: '礼貌随和', value: 'Polite & Conversational', description: '得体但不刻板的日常对话' }, - { label: '中性标准', value: 'Neutral & Standard', description: '维基百科、说明书、客观的新闻报道' }, - { label: '非正式', value: 'Casual & Informal', description: '朋友聊天、社交媒体、非正式简讯' }, - { label: '亲切友好', value: 'Warm & Friendly', description: '社区信函、给朋友的建议、温馨提示' }, - { label: '严谨权威', value: 'Strict & Authoritative', description: '警示标志、强制规定、上级指令' }, - { label: '热情生动', value: 'Enthusiastic & Vivid', description: '广告文案、旅游推荐、博主推文' }, -]; +import { LANGUAGES, SPEAKER_IDENTITY_OPTIONS, TONE_REGISTER_OPTIONS, type ApiProfile, type Language } from '../domain/translation'; 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. @@ -106,54 +65,6 @@ export const DEFAULT_REFINEMENT_TEMPLATE = `You are a senior translation editor. 4. If a piece of feedback contradicts the [Source Text], prioritize accuracy and provide a balanced refinement. 5. Produce ONLY the refined {TARGET_LANG} translation, without any additional explanations, notes, or commentary.`; -export interface ApiProfile { - id: string; - name: string; - apiBaseUrl: string; - apiKey: string; - modelName: string; -} - -export interface HistoryItem { - id: string; - timestamp: string; - sourceLang: Language; - targetLang: Language; - sourceText: string; - targetText: string; - context: string; - speakerIdentity: string; - toneRegister: string; - modelName: string; -} - -export interface Participant { - name: string; - gender: string; - language: Language; - tone: string; -} - -export interface ChatMessage { - id: string; - sender: 'me' | 'partner'; - original: string; - translated: string; - timestamp: string; - evaluation?: string; // AI 审计结果 (JSON 字符串) - isEvaluating?: boolean; // 审计状态 - isRefining?: boolean; // 润色状态 -} - -export interface ChatSession { - id: string; - title: string; - me: Participant; - partner: Participant; - messages: ChatMessage[]; - lastActivity: string; -} - export const CONVERSATION_SYSTEM_PROMPT_TEMPLATE = `# Role: Professional Real-time Conversation Translator # Participants: