fix 5
This commit is contained in:
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
|
||||
@@ -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';
|
||||
|
||||
@@ -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';
|
||||
|
||||
89
src/domain/translation.ts
Normal file
89
src/domain/translation.ts
Normal file
@@ -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;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Language, Participant } from '../stores/settings';
|
||||
import type { Language, Participant } from '../domain/translation';
|
||||
|
||||
interface SingleTranslationPromptContext {
|
||||
sourceLang: Language;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user