✨ Added context menu
This commit is contained in:
@@ -9,19 +9,20 @@ import (
|
||||
|
||||
// ServiceManager 服务管理器,负责协调各个服务
|
||||
type ServiceManager struct {
|
||||
pathManager *PathManager
|
||||
configService *ConfigService
|
||||
documentService *DocumentService
|
||||
migrationService *MigrationService
|
||||
systemService *SystemService
|
||||
hotkeyService *HotkeyService
|
||||
dialogService *DialogService
|
||||
trayService *TrayService
|
||||
keyBindingService *KeyBindingService
|
||||
extensionService *ExtensionService
|
||||
startupService *StartupService
|
||||
selfUpdateService *SelfUpdateService
|
||||
logger *log.LoggerService
|
||||
pathManager *PathManager
|
||||
configService *ConfigService
|
||||
documentService *DocumentService
|
||||
migrationService *MigrationService
|
||||
systemService *SystemService
|
||||
hotkeyService *HotkeyService
|
||||
dialogService *DialogService
|
||||
trayService *TrayService
|
||||
keyBindingService *KeyBindingService
|
||||
extensionService *ExtensionService
|
||||
startupService *StartupService
|
||||
selfUpdateService *SelfUpdateService
|
||||
translationService *TranslationService
|
||||
logger *log.LoggerService
|
||||
}
|
||||
|
||||
// NewServiceManager 创建新的服务管理器实例
|
||||
@@ -68,6 +69,9 @@ func NewServiceManager() *ServiceManager {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
// 初始化翻译服务
|
||||
translationService := NewTranslationService(logger)
|
||||
|
||||
// 使用新的配置通知系统设置热键配置变更监听
|
||||
err = configService.SetHotkeyChangeCallback(func(enable bool, hotkey *models.HotkeyCombo) error {
|
||||
return hotkeyService.UpdateHotkey(enable, hotkey)
|
||||
@@ -85,18 +89,19 @@ func NewServiceManager() *ServiceManager {
|
||||
}
|
||||
|
||||
return &ServiceManager{
|
||||
configService: configService,
|
||||
documentService: documentService,
|
||||
migrationService: migrationService,
|
||||
systemService: systemService,
|
||||
hotkeyService: hotkeyService,
|
||||
dialogService: dialogService,
|
||||
trayService: trayService,
|
||||
keyBindingService: keyBindingService,
|
||||
extensionService: extensionService,
|
||||
startupService: startupService,
|
||||
selfUpdateService: selfUpdateService,
|
||||
logger: logger,
|
||||
configService: configService,
|
||||
documentService: documentService,
|
||||
migrationService: migrationService,
|
||||
systemService: systemService,
|
||||
hotkeyService: hotkeyService,
|
||||
dialogService: dialogService,
|
||||
trayService: trayService,
|
||||
keyBindingService: keyBindingService,
|
||||
extensionService: extensionService,
|
||||
startupService: startupService,
|
||||
selfUpdateService: selfUpdateService,
|
||||
translationService: translationService,
|
||||
logger: logger,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,6 +119,7 @@ func (sm *ServiceManager) GetServices() []application.Service {
|
||||
application.NewService(sm.extensionService),
|
||||
application.NewService(sm.startupService),
|
||||
application.NewService(sm.selfUpdateService),
|
||||
application.NewService(sm.translationService),
|
||||
}
|
||||
return services
|
||||
}
|
||||
@@ -162,3 +168,8 @@ func (sm *ServiceManager) GetExtensionService() *ExtensionService {
|
||||
func (sm *ServiceManager) GetSelfUpdateService() *SelfUpdateService {
|
||||
return sm.selfUpdateService
|
||||
}
|
||||
|
||||
// GetTranslationService 获取翻译服务实例
|
||||
func (sm *ServiceManager) GetTranslationService() *TranslationService {
|
||||
return sm.translationService
|
||||
}
|
||||
|
253
internal/services/translation_service.go
Normal file
253
internal/services/translation_service.go
Normal file
@@ -0,0 +1,253 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"sync"
|
||||
"time"
|
||||
"voidraft/internal/common/translator"
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/services/log"
|
||||
"golang.org/x/text/language"
|
||||
)
|
||||
|
||||
// TranslationService 翻译服务
|
||||
type TranslationService struct {
|
||||
logger *log.LoggerService
|
||||
factory *translator.TranslatorFactory
|
||||
defaultTimeout time.Duration
|
||||
activeTranslator translator.TranslatorType
|
||||
translators map[translator.TranslatorType]translator.Translator
|
||||
mutex sync.RWMutex
|
||||
}
|
||||
|
||||
// NewTranslationService 创建翻译服务实例
|
||||
func NewTranslationService(logger *log.LoggerService) *TranslationService {
|
||||
factory := translator.NewTranslatorFactory()
|
||||
defaultTimeout := 10 * time.Second
|
||||
|
||||
// 默认使用bin翻译
|
||||
activeType := translator.BingTranslatorType
|
||||
|
||||
// 预初始化所有翻译器
|
||||
translators := make(map[translator.TranslatorType]translator.Translator)
|
||||
|
||||
service := &TranslationService{
|
||||
logger: logger,
|
||||
factory: factory,
|
||||
defaultTimeout: defaultTimeout,
|
||||
activeTranslator: activeType,
|
||||
translators: translators,
|
||||
}
|
||||
|
||||
// 延迟初始化翻译器以提高启动速度
|
||||
go service.initTranslators()
|
||||
|
||||
return service
|
||||
}
|
||||
|
||||
// initTranslators 初始化所有翻译器
|
||||
func (s *TranslationService) initTranslators() {
|
||||
types := []translator.TranslatorType{
|
||||
translator.GoogleTranslatorType,
|
||||
translator.BingTranslatorType,
|
||||
translator.YoudaoTranslatorType,
|
||||
translator.DeeplTranslatorType,
|
||||
}
|
||||
|
||||
for _, t := range types {
|
||||
trans, err := s.factory.Create(t)
|
||||
if err != nil {
|
||||
s.logger.Error("Failed to create translator: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
trans.SetTimeout(s.defaultTimeout)
|
||||
|
||||
s.mutex.Lock()
|
||||
s.translators[t] = trans
|
||||
s.mutex.Unlock()
|
||||
}
|
||||
}
|
||||
|
||||
// getTranslator 获取指定类型的翻译器
|
||||
func (s *TranslationService) getTranslator(translatorType translator.TranslatorType) (translator.Translator, error) {
|
||||
s.mutex.RLock()
|
||||
trans, exists := s.translators[translatorType]
|
||||
s.mutex.RUnlock()
|
||||
|
||||
if exists {
|
||||
return trans, nil
|
||||
}
|
||||
|
||||
// 如果翻译器尚未初始化,则立即创建
|
||||
trans, err := s.factory.Create(translatorType)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
trans.SetTimeout(s.defaultTimeout)
|
||||
|
||||
s.mutex.Lock()
|
||||
s.translators[translatorType] = trans
|
||||
s.mutex.Unlock()
|
||||
|
||||
return trans, nil
|
||||
}
|
||||
|
||||
// Translate 使用当前活跃翻译器进行翻译
|
||||
// @param {string} text - 待翻译文本
|
||||
// @param {string} from - 源语言代码 (如 "en", "zh", "auto")
|
||||
// @param {string} to - 目标语言代码 (如 "en", "zh")
|
||||
// @returns {string} 翻译后的文本
|
||||
// @returns {error} 可能的错误
|
||||
func (s *TranslationService) Translate(text string, from string, to string) (string, error) {
|
||||
// 解析语言标签
|
||||
var fromLang, toLang language.Tag
|
||||
var err error
|
||||
|
||||
if from == "auto" {
|
||||
fromLang = language.Und // 未定义,表示自动检测
|
||||
} else {
|
||||
fromLang, err = language.Parse(from)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
toLang, err = language.Parse(to)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 获取活跃翻译器
|
||||
s.mutex.RLock()
|
||||
activeType := s.activeTranslator
|
||||
s.mutex.RUnlock()
|
||||
|
||||
trans, err := s.getTranslator(activeType)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 执行翻译
|
||||
return trans.Translate(text, fromLang, toLang)
|
||||
}
|
||||
|
||||
// TranslateWithFallback 尝试使用当前活跃翻译器翻译,如果失败则尝试备用翻译器
|
||||
// @param {string} text - 待翻译文本
|
||||
// @param {string} from - 源语言代码 (如 "en", "zh", "auto")
|
||||
// @param {string} to - 目标语言代码 (如 "en", "zh")
|
||||
// @returns {string} 翻译后的文本
|
||||
// @returns {string} 使用的翻译器类型
|
||||
// @returns {error} 可能的错误
|
||||
func (s *TranslationService) TranslateWithFallback(text string, from string, to string) (string, string, error) {
|
||||
// 首先尝试活跃翻译器
|
||||
s.mutex.RLock()
|
||||
primaryType := s.activeTranslator
|
||||
s.mutex.RUnlock()
|
||||
|
||||
result, err := s.TranslateWith(text, from, to, string(primaryType))
|
||||
if err == nil {
|
||||
return result, string(primaryType), nil
|
||||
}
|
||||
|
||||
// 备用翻译器列表
|
||||
fallbacks := []translator.TranslatorType{
|
||||
translator.GoogleTranslatorType,
|
||||
translator.BingTranslatorType,
|
||||
translator.DeeplTranslatorType,
|
||||
translator.YoudaoTranslatorType,
|
||||
}
|
||||
|
||||
// 尝试备用翻译器
|
||||
for _, fallbackType := range fallbacks {
|
||||
if fallbackType == primaryType {
|
||||
continue // 跳过已尝试的主要翻译器
|
||||
}
|
||||
|
||||
result, err := s.TranslateWith(text, from, to, string(fallbackType))
|
||||
if err == nil {
|
||||
return result, string(fallbackType), nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", "", err // 所有翻译器都失败时返回最后一个错误
|
||||
}
|
||||
|
||||
// TranslateWith 使用指定翻译器进行翻译
|
||||
// @param {string} text - 待翻译文本
|
||||
// @param {string} from - 源语言代码 (如 "en", "zh", "auto")
|
||||
// @param {string} to - 目标语言代码 (如 "en", "zh")
|
||||
// @param {string} translatorType - 翻译器类型 ("google", "bing", "youdao", "deepl")
|
||||
// @returns {string} 翻译后的文本
|
||||
// @returns {error} 可能的错误
|
||||
func (s *TranslationService) TranslateWith(text string, from string, to string, translatorType string) (string, error) {
|
||||
// 参数验证
|
||||
if text == "" {
|
||||
return "", nil // 空文本无需翻译
|
||||
}
|
||||
|
||||
// 转换为翻译器类型
|
||||
transType := translator.TranslatorType(translatorType)
|
||||
|
||||
// 获取指定翻译器
|
||||
trans, err := s.getTranslator(transType)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// 创建翻译参数
|
||||
params := translator.TranslationParams{
|
||||
From: from,
|
||||
To: to,
|
||||
Tries: 2,
|
||||
Delay: 500 * time.Millisecond,
|
||||
}
|
||||
|
||||
// 执行翻译
|
||||
return trans.TranslateWithParams(text, params)
|
||||
}
|
||||
|
||||
// SetActiveTranslator 设置活跃翻译器
|
||||
// @param {string} translatorType - 翻译器类型 ("google", "bing", "youdao", "deepl")
|
||||
// @returns {error} 可能的错误
|
||||
func (s *TranslationService) SetActiveTranslator(translatorType string) error {
|
||||
transType := translator.TranslatorType(translatorType)
|
||||
|
||||
// 验证翻译器类型
|
||||
_, err := s.factory.Create(transType)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
s.mutex.Lock()
|
||||
s.activeTranslator = transType
|
||||
s.mutex.Unlock()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAvailableTranslators 获取所有可用翻译器类型
|
||||
// @returns {[]string} 翻译器类型列表
|
||||
func (s *TranslationService) GetAvailableTranslators() []string {
|
||||
return []string{
|
||||
string(translator.GoogleTranslatorType),
|
||||
string(translator.BingTranslatorType),
|
||||
string(translator.YoudaoTranslatorType),
|
||||
string(translator.DeeplTranslatorType),
|
||||
}
|
||||
}
|
||||
|
||||
// SetTimeout 设置翻译超时时间
|
||||
// @param {int} seconds - 超时秒数
|
||||
func (s *TranslationService) SetTimeout(seconds int) {
|
||||
timeout := time.Duration(seconds) * time.Second
|
||||
|
||||
s.mutex.Lock()
|
||||
s.defaultTimeout = timeout
|
||||
s.mutex.Unlock()
|
||||
|
||||
// 更新所有现有翻译器的超时设置
|
||||
for _, t := range s.translators {
|
||||
t.SetTimeout(timeout)
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user