⬆️ Upgrade wails v3 from Alpha 9 to Alpha 10
This commit is contained in:
@@ -38,7 +38,7 @@ type Migratable interface {
|
||||
|
||||
// ConfigMigrationService 配置迁移服务
|
||||
type ConfigMigrationService[T Migratable] struct {
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
configDir string
|
||||
configName string
|
||||
targetVersion string
|
||||
@@ -54,7 +54,7 @@ type MigrationResult struct {
|
||||
|
||||
// NewConfigMigrationService 创建配置迁移服务
|
||||
func NewConfigMigrationService[T Migratable](
|
||||
logger *log.LoggerService,
|
||||
logger *log.Service,
|
||||
configDir string,
|
||||
configName, targetVersion, configPath string,
|
||||
) *ConfigMigrationService[T] {
|
||||
@@ -312,7 +312,7 @@ func chainLoad(k *koanf.Koanf, loaders ...func() error) error {
|
||||
}
|
||||
|
||||
// 工厂函数
|
||||
func NewAppConfigMigrationService(logger *log.LoggerService, configDir, settingsPath string) *ConfigMigrationService[*models.AppConfig] {
|
||||
func NewAppConfigMigrationService(logger *log.Service, configDir, settingsPath string) *ConfigMigrationService[*models.AppConfig] {
|
||||
return NewConfigMigrationService[*models.AppConfig](
|
||||
logger, configDir, "settings", CurrentAppConfigVersion, settingsPath)
|
||||
}
|
||||
|
@@ -49,7 +49,7 @@ type ConfigListener struct {
|
||||
type ConfigNotificationService struct {
|
||||
listeners map[ConfigChangeType][]*ConfigListener // 支持多监听器的map
|
||||
mu sync.RWMutex // 监听器map的读写锁
|
||||
logger *log.LoggerService // 日志服务
|
||||
logger *log.Service // 日志服务
|
||||
koanf *koanf.Koanf // koanf实例
|
||||
ctx context.Context
|
||||
cancel context.CancelFunc
|
||||
@@ -57,7 +57,7 @@ type ConfigNotificationService struct {
|
||||
}
|
||||
|
||||
// NewConfigNotificationService 创建配置通知服务
|
||||
func NewConfigNotificationService(k *koanf.Koanf, logger *log.LoggerService) *ConfigNotificationService {
|
||||
func NewConfigNotificationService(k *koanf.Koanf, logger *log.Service) *ConfigNotificationService {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
return &ConfigNotificationService{
|
||||
listeners: make(map[ConfigChangeType][]*ConfigListener),
|
||||
@@ -445,8 +445,8 @@ func CreateDataPathListener(name string, callback func() error) *ConfigListener
|
||||
}
|
||||
}
|
||||
|
||||
// OnShutdown 关闭服务
|
||||
func (cns *ConfigNotificationService) OnShutdown() error {
|
||||
// ServiceShutdown 关闭服务
|
||||
func (cns *ConfigNotificationService) ServiceShutdown() error {
|
||||
cns.Cleanup()
|
||||
return nil
|
||||
}
|
||||
|
@@ -18,12 +18,12 @@ import (
|
||||
|
||||
// ConfigService 应用配置服务
|
||||
type ConfigService struct {
|
||||
koanf *koanf.Koanf // koanf 实例
|
||||
logger *log.LoggerService // 日志服务
|
||||
configDir string // 配置目录
|
||||
settingsPath string // 设置文件路径
|
||||
mu sync.RWMutex // 读写锁
|
||||
fileProvider *file.File // 文件提供器,用于监听
|
||||
koanf *koanf.Koanf // koanf 实例
|
||||
logger *log.Service // 日志服务
|
||||
configDir string // 配置目录
|
||||
settingsPath string // 设置文件路径
|
||||
mu sync.RWMutex // 读写锁
|
||||
fileProvider *file.File // 文件提供器,用于监听
|
||||
|
||||
// 配置通知服务
|
||||
notificationService *ConfigNotificationService
|
||||
@@ -55,7 +55,7 @@ func (e *ConfigError) Is(target error) bool {
|
||||
}
|
||||
|
||||
// NewConfigService 创建新的配置服务实例
|
||||
func NewConfigService(logger *log.LoggerService) *ConfigService {
|
||||
func NewConfigService(logger *log.Service) *ConfigService {
|
||||
// 获取用户主目录
|
||||
homeDir, err := os.UserHomeDir()
|
||||
if err != nil {
|
||||
@@ -298,8 +298,8 @@ func (cs *ConfigService) SetDataPathChangeCallback(callback func() error) error
|
||||
return cs.notificationService.RegisterListener(dataPathListener)
|
||||
}
|
||||
|
||||
// OnShutdown 关闭服务
|
||||
func (cs *ConfigService) OnShutdown() error {
|
||||
// ServiceShutdown 关闭服务
|
||||
func (cs *ConfigService) ServiceShutdown() error {
|
||||
cs.stopWatching()
|
||||
if cs.notificationService != nil {
|
||||
cs.notificationService.Cleanup()
|
||||
|
@@ -2,7 +2,6 @@ package services
|
||||
|
||||
import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
@@ -10,7 +9,7 @@ import (
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
"github.com/wailsapp/wails/v3/pkg/services/log"
|
||||
_ "modernc.org/sqlite" // SQLite driver
|
||||
"github.com/wailsapp/wails/v3/pkg/services/sqlite"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -64,14 +63,14 @@ CREATE TABLE IF NOT EXISTS key_bindings (
|
||||
// DatabaseService provides shared database functionality
|
||||
type DatabaseService struct {
|
||||
configService *ConfigService
|
||||
logger *log.LoggerService
|
||||
db *sql.DB
|
||||
logger *log.Service
|
||||
SQLite *sqlite.Service
|
||||
mu sync.RWMutex
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// NewDatabaseService creates a new database service
|
||||
func NewDatabaseService(configService *ConfigService, logger *log.LoggerService) *DatabaseService {
|
||||
func NewDatabaseService(configService *ConfigService, logger *log.Service) *DatabaseService {
|
||||
if logger == nil {
|
||||
logger = log.New()
|
||||
}
|
||||
@@ -79,11 +78,12 @@ func NewDatabaseService(configService *ConfigService, logger *log.LoggerService)
|
||||
return &DatabaseService{
|
||||
configService: configService,
|
||||
logger: logger,
|
||||
SQLite: sqlite.New(),
|
||||
}
|
||||
}
|
||||
|
||||
// OnStartup initializes the service when the application starts
|
||||
func (ds *DatabaseService) OnStartup(ctx context.Context, _ application.ServiceOptions) error {
|
||||
// ServiceStartup initializes the service when the application starts
|
||||
func (ds *DatabaseService) ServiceStartup(ctx context.Context, options application.ServiceOptions) error {
|
||||
ds.ctx = ctx
|
||||
return ds.initDatabase()
|
||||
}
|
||||
@@ -111,24 +111,26 @@ func (ds *DatabaseService) initDatabase() error {
|
||||
file.Close()
|
||||
}
|
||||
|
||||
db, err := sql.Open("sqlite", dbPath)
|
||||
if err != nil {
|
||||
// 配置SQLite服务
|
||||
ds.SQLite.Configure(&sqlite.Config{
|
||||
DBSource: dbPath,
|
||||
})
|
||||
|
||||
// 打开数据库连接
|
||||
if err := ds.SQLite.Open(); err != nil {
|
||||
return fmt.Errorf("failed to open database: %w", err)
|
||||
}
|
||||
|
||||
ds.db = db
|
||||
|
||||
// Apply optimization settings
|
||||
if _, err := db.Exec(sqlOptimizationSettings); err != nil {
|
||||
// 应用性能优化设置
|
||||
if err := ds.SQLite.Execute(sqlOptimizationSettings); err != nil {
|
||||
return fmt.Errorf("failed to apply optimization settings: %w", err)
|
||||
}
|
||||
|
||||
// Create all tables
|
||||
// 创建表和索引
|
||||
if err := ds.createTables(); err != nil {
|
||||
return fmt.Errorf("failed to create tables: %w", err)
|
||||
}
|
||||
|
||||
// Create indexes
|
||||
if err := ds.createIndexes(); err != nil {
|
||||
return fmt.Errorf("failed to create indexes: %w", err)
|
||||
}
|
||||
@@ -154,7 +156,7 @@ func (ds *DatabaseService) createTables() error {
|
||||
}
|
||||
|
||||
for _, table := range tables {
|
||||
if _, err := ds.db.Exec(table); err != nil {
|
||||
if err := ds.SQLite.Execute(table); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -177,35 +179,25 @@ func (ds *DatabaseService) createIndexes() error {
|
||||
}
|
||||
|
||||
for _, index := range indexes {
|
||||
if _, err := ds.db.Exec(index); err != nil {
|
||||
if err := ds.SQLite.Execute(index); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetDB returns the database connection
|
||||
func (ds *DatabaseService) GetDB() *sql.DB {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
return ds.db
|
||||
}
|
||||
|
||||
// OnShutdown shuts down the service when the application closes
|
||||
func (ds *DatabaseService) OnShutdown() error {
|
||||
if ds.db != nil {
|
||||
return ds.db.Close()
|
||||
}
|
||||
return nil
|
||||
// ServiceShutdown shuts down the service when the application closes
|
||||
func (ds *DatabaseService) ServiceShutdown() error {
|
||||
return ds.SQLite.Close()
|
||||
}
|
||||
|
||||
// OnDataPathChanged handles data path changes
|
||||
func (ds *DatabaseService) OnDataPathChanged() error {
|
||||
// Close existing database
|
||||
if ds.db != nil {
|
||||
ds.db.Close()
|
||||
// 关闭当前连接
|
||||
if err := ds.SQLite.Close(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Reinitialize with new path
|
||||
// 用新路径重新初始化
|
||||
return ds.initDatabase()
|
||||
}
|
||||
|
@@ -7,12 +7,12 @@ import (
|
||||
|
||||
// DialogService 对话框服务,处理文件选择等对话框操作
|
||||
type DialogService struct {
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
window *application.WebviewWindow // 绑定的窗口
|
||||
}
|
||||
|
||||
// NewDialogService 创建新的对话框服务实例
|
||||
func NewDialogService(logger *log.LoggerService) *DialogService {
|
||||
func NewDialogService(logger *log.Service) *DialogService {
|
||||
if logger == nil {
|
||||
logger = log.New()
|
||||
}
|
||||
@@ -30,7 +30,8 @@ func (ds *DialogService) SetWindow(window *application.WebviewWindow) {
|
||||
|
||||
// SelectDirectory 打开目录选择对话框
|
||||
func (ds *DialogService) SelectDirectory() (string, error) {
|
||||
dialog := application.OpenFileDialogWithOptions(&application.OpenFileDialogOptions{
|
||||
dialog := application.OpenFileDialog()
|
||||
dialog.SetOptions(&application.OpenFileDialogOptions{
|
||||
// 目录选择配置
|
||||
CanChooseDirectories: true, // 允许选择目录
|
||||
CanChooseFiles: false, // 不允许选择文件
|
||||
|
@@ -11,7 +11,6 @@ import (
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
"github.com/wailsapp/wails/v3/pkg/services/log"
|
||||
_ "modernc.org/sqlite" // SQLite driver
|
||||
)
|
||||
|
||||
// SQL constants for document operations
|
||||
@@ -70,13 +69,13 @@ SELECT id FROM documents WHERE is_deleted = 0 ORDER BY id LIMIT 1`
|
||||
// DocumentService provides document management functionality
|
||||
type DocumentService struct {
|
||||
databaseService *DatabaseService
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
mu sync.RWMutex
|
||||
ctx context.Context
|
||||
}
|
||||
|
||||
// NewDocumentService creates a new document service
|
||||
func NewDocumentService(databaseService *DatabaseService, logger *log.LoggerService) *DocumentService {
|
||||
func NewDocumentService(databaseService *DatabaseService, logger *log.Service) *DocumentService {
|
||||
if logger == nil {
|
||||
logger = log.New()
|
||||
}
|
||||
@@ -87,8 +86,8 @@ func NewDocumentService(databaseService *DatabaseService, logger *log.LoggerServ
|
||||
}
|
||||
}
|
||||
|
||||
// OnStartup initializes the service when the application starts
|
||||
func (ds *DocumentService) OnStartup(ctx context.Context, _ application.ServiceOptions) error {
|
||||
// ServiceStartup initializes the service when the application starts
|
||||
func (ds *DocumentService) ServiceStartup(ctx context.Context, options application.ServiceOptions) error {
|
||||
ds.ctx = ctx
|
||||
// Ensure default document exists
|
||||
if err := ds.ensureDefaultDocument(); err != nil {
|
||||
@@ -100,13 +99,20 @@ func (ds *DocumentService) OnStartup(ctx context.Context, _ application.ServiceO
|
||||
// ensureDefaultDocument ensures a default document exists
|
||||
func (ds *DocumentService) ensureDefaultDocument() error {
|
||||
// Check if any document exists
|
||||
var count int
|
||||
db := ds.databaseService.GetDB()
|
||||
err := db.QueryRow(sqlCountDocuments).Scan(&count)
|
||||
rows, err := ds.databaseService.SQLite.Query(sqlCountDocuments)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if len(rows) == 0 {
|
||||
return fmt.Errorf("failed to query document count")
|
||||
}
|
||||
|
||||
count, ok := rows[0]["COUNT(*)"].(int64)
|
||||
if !ok {
|
||||
return fmt.Errorf("failed to convert count to int64")
|
||||
}
|
||||
|
||||
// If no documents exist, create default document
|
||||
if count == 0 {
|
||||
defaultDoc := models.NewDefaultDocument()
|
||||
@@ -121,20 +127,50 @@ func (ds *DocumentService) GetDocumentByID(id int64) (*models.Document, error) {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
|
||||
var doc models.Document
|
||||
var isDeletedInt int
|
||||
db := ds.databaseService.GetDB()
|
||||
row := db.QueryRow(sqlGetDocumentByID, id)
|
||||
err := row.Scan(&doc.ID, &doc.Title, &doc.Content, &doc.CreatedAt, &doc.UpdatedAt, &isDeletedInt)
|
||||
rows, err := ds.databaseService.SQLite.Query(sqlGetDocumentByID, id)
|
||||
if err != nil {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return nil, nil
|
||||
}
|
||||
return nil, fmt.Errorf("failed to get document by ID: %w", err)
|
||||
}
|
||||
doc.IsDeleted = isDeletedInt == 1
|
||||
|
||||
return &doc, nil
|
||||
if len(rows) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
row := rows[0]
|
||||
doc := &models.Document{}
|
||||
|
||||
// 从Row中提取数据
|
||||
if idVal, ok := row["id"].(int64); ok {
|
||||
doc.ID = idVal
|
||||
}
|
||||
|
||||
if title, ok := row["title"].(string); ok {
|
||||
doc.Title = title
|
||||
}
|
||||
|
||||
if content, ok := row["content"].(string); ok {
|
||||
doc.Content = content
|
||||
}
|
||||
|
||||
if createdAt, ok := row["created_at"].(string); ok {
|
||||
t, err := time.Parse("2006-01-02 15:04:05", createdAt)
|
||||
if err == nil {
|
||||
doc.CreatedAt = t
|
||||
}
|
||||
}
|
||||
|
||||
if updatedAt, ok := row["updated_at"].(string); ok {
|
||||
t, err := time.Parse("2006-01-02 15:04:05", updatedAt)
|
||||
if err == nil {
|
||||
doc.UpdatedAt = t
|
||||
}
|
||||
}
|
||||
|
||||
if isDeletedInt, ok := row["is_deleted"].(int64); ok {
|
||||
doc.IsDeleted = isDeletedInt == 1
|
||||
}
|
||||
|
||||
return doc, nil
|
||||
}
|
||||
|
||||
// CreateDocument creates a new document and returns the created document with ID
|
||||
@@ -152,20 +188,30 @@ func (ds *DocumentService) CreateDocument(title string) (*models.Document, error
|
||||
IsDeleted: false,
|
||||
}
|
||||
|
||||
db := ds.databaseService.GetDB()
|
||||
result, err := db.Exec(sqlInsertDocument, doc.Title, doc.Content, doc.CreatedAt, doc.UpdatedAt)
|
||||
if err != nil {
|
||||
// 执行插入操作
|
||||
if err := ds.databaseService.SQLite.Execute(sqlInsertDocument,
|
||||
doc.Title, doc.Content, doc.CreatedAt, doc.UpdatedAt); err != nil {
|
||||
return nil, fmt.Errorf("failed to create document: %w", err)
|
||||
}
|
||||
|
||||
// Get the auto-generated ID
|
||||
id, err := result.LastInsertId()
|
||||
// 获取自增ID
|
||||
lastIDRows, err := ds.databaseService.SQLite.Query("SELECT last_insert_rowid()")
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get last insert ID: %w", err)
|
||||
}
|
||||
|
||||
// Return the created document with ID
|
||||
doc.ID = id
|
||||
if len(lastIDRows) == 0 {
|
||||
return nil, fmt.Errorf("no rows returned for last insert ID query")
|
||||
}
|
||||
|
||||
// 从结果中提取ID
|
||||
lastID, ok := lastIDRows[0]["last_insert_rowid()"].(int64)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("failed to convert last insert ID to int64")
|
||||
}
|
||||
|
||||
// 返回带ID的文档
|
||||
doc.ID = lastID
|
||||
return doc, nil
|
||||
}
|
||||
|
||||
@@ -174,8 +220,7 @@ func (ds *DocumentService) UpdateDocumentContent(id int64, content string) error
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
|
||||
db := ds.databaseService.GetDB()
|
||||
_, err := db.Exec(sqlUpdateDocumentContent, content, time.Now(), id)
|
||||
err := ds.databaseService.SQLite.Execute(sqlUpdateDocumentContent, content, time.Now(), id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update document content: %w", err)
|
||||
}
|
||||
@@ -187,8 +232,7 @@ func (ds *DocumentService) UpdateDocumentTitle(id int64, title string) error {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
|
||||
db := ds.databaseService.GetDB()
|
||||
_, err := db.Exec(sqlUpdateDocumentTitle, title, time.Now(), id)
|
||||
err := ds.databaseService.SQLite.Execute(sqlUpdateDocumentTitle, title, time.Now(), id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update document title: %w", err)
|
||||
}
|
||||
@@ -205,8 +249,7 @@ func (ds *DocumentService) DeleteDocument(id int64) error {
|
||||
return fmt.Errorf("cannot delete the default document")
|
||||
}
|
||||
|
||||
db := ds.databaseService.GetDB()
|
||||
_, err := db.Exec(sqlMarkDocumentAsDeleted, time.Now(), id)
|
||||
err := ds.databaseService.SQLite.Execute(sqlMarkDocumentAsDeleted, time.Now(), id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to mark document as deleted: %w", err)
|
||||
}
|
||||
@@ -218,8 +261,7 @@ func (ds *DocumentService) RestoreDocument(id int64) error {
|
||||
ds.mu.Lock()
|
||||
defer ds.mu.Unlock()
|
||||
|
||||
db := ds.databaseService.GetDB()
|
||||
_, err := db.Exec(sqlRestoreDocument, time.Now(), id)
|
||||
err := ds.databaseService.SQLite.Execute(sqlRestoreDocument, time.Now(), id)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to restore document: %w", err)
|
||||
}
|
||||
@@ -231,22 +273,38 @@ func (ds *DocumentService) ListAllDocumentsMeta() ([]*models.Document, error) {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
|
||||
db := ds.databaseService.GetDB()
|
||||
rows, err := db.Query(sqlListAllDocumentsMeta)
|
||||
rows, err := ds.databaseService.SQLite.Query(sqlListAllDocumentsMeta)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list document meta: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var documents []*models.Document
|
||||
for rows.Next() {
|
||||
var doc models.Document
|
||||
err := rows.Scan(&doc.ID, &doc.Title, &doc.CreatedAt, &doc.UpdatedAt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to scan document meta: %w", err)
|
||||
for _, row := range rows {
|
||||
doc := &models.Document{IsDeleted: false}
|
||||
|
||||
if id, ok := row["id"].(int64); ok {
|
||||
doc.ID = id
|
||||
}
|
||||
doc.IsDeleted = false
|
||||
documents = append(documents, &doc)
|
||||
|
||||
if title, ok := row["title"].(string); ok {
|
||||
doc.Title = title
|
||||
}
|
||||
|
||||
if createdAt, ok := row["created_at"].(string); ok {
|
||||
t, err := time.Parse("2006-01-02 15:04:05", createdAt)
|
||||
if err == nil {
|
||||
doc.CreatedAt = t
|
||||
}
|
||||
}
|
||||
|
||||
if updatedAt, ok := row["updated_at"].(string); ok {
|
||||
t, err := time.Parse("2006-01-02 15:04:05", updatedAt)
|
||||
if err == nil {
|
||||
doc.UpdatedAt = t
|
||||
}
|
||||
}
|
||||
|
||||
documents = append(documents, doc)
|
||||
}
|
||||
|
||||
return documents, nil
|
||||
@@ -257,22 +315,38 @@ func (ds *DocumentService) ListDeletedDocumentsMeta() ([]*models.Document, error
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
|
||||
db := ds.databaseService.GetDB()
|
||||
rows, err := db.Query(sqlListDeletedDocumentsMeta)
|
||||
rows, err := ds.databaseService.SQLite.Query(sqlListDeletedDocumentsMeta)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to list deleted document meta: %w", err)
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var documents []*models.Document
|
||||
for rows.Next() {
|
||||
var doc models.Document
|
||||
err := rows.Scan(&doc.ID, &doc.Title, &doc.CreatedAt, &doc.UpdatedAt)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to scan deleted document meta: %w", err)
|
||||
for _, row := range rows {
|
||||
doc := &models.Document{IsDeleted: true}
|
||||
|
||||
if id, ok := row["id"].(int64); ok {
|
||||
doc.ID = id
|
||||
}
|
||||
doc.IsDeleted = true
|
||||
documents = append(documents, &doc)
|
||||
|
||||
if title, ok := row["title"].(string); ok {
|
||||
doc.Title = title
|
||||
}
|
||||
|
||||
if createdAt, ok := row["created_at"].(string); ok {
|
||||
t, err := time.Parse("2006-01-02 15:04:05", createdAt)
|
||||
if err == nil {
|
||||
doc.CreatedAt = t
|
||||
}
|
||||
}
|
||||
|
||||
if updatedAt, ok := row["updated_at"].(string); ok {
|
||||
t, err := time.Parse("2006-01-02 15:04:05", updatedAt)
|
||||
if err == nil {
|
||||
doc.UpdatedAt = t
|
||||
}
|
||||
}
|
||||
|
||||
documents = append(documents, doc)
|
||||
}
|
||||
|
||||
return documents, nil
|
||||
@@ -283,14 +357,22 @@ func (ds *DocumentService) GetFirstDocumentID() (int64, error) {
|
||||
ds.mu.RLock()
|
||||
defer ds.mu.RUnlock()
|
||||
|
||||
db := ds.databaseService.GetDB()
|
||||
var id int64
|
||||
err := db.QueryRow(sqlGetFirstDocumentID).Scan(&id)
|
||||
rows, err := ds.databaseService.SQLite.Query(sqlGetFirstDocumentID)
|
||||
if err != nil {
|
||||
if err == sql.ErrNoRows {
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return 0, nil // No documents exist
|
||||
}
|
||||
return 0, fmt.Errorf("failed to get first document ID: %w", err)
|
||||
}
|
||||
|
||||
if len(rows) == 0 {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
id, ok := rows[0]["id"].(int64)
|
||||
if !ok {
|
||||
return 0, fmt.Errorf("failed to convert ID to int64")
|
||||
}
|
||||
|
||||
return id, nil
|
||||
}
|
||||
|
@@ -41,7 +41,7 @@ WHERE id = ?`
|
||||
// ExtensionService 扩展管理服务
|
||||
type ExtensionService struct {
|
||||
databaseService *DatabaseService
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
|
||||
mu sync.RWMutex
|
||||
ctx context.Context
|
||||
@@ -73,7 +73,7 @@ func (e *ExtensionError) Is(target error) bool {
|
||||
}
|
||||
|
||||
// NewExtensionService 创建扩展服务实例
|
||||
func NewExtensionService(databaseService *DatabaseService, logger *log.LoggerService) *ExtensionService {
|
||||
func NewExtensionService(databaseService *DatabaseService, logger *log.Service) *ExtensionService {
|
||||
if logger == nil {
|
||||
logger = log.New()
|
||||
}
|
||||
@@ -105,29 +105,26 @@ func (es *ExtensionService) initDatabase() error {
|
||||
defer es.mu.Unlock()
|
||||
|
||||
// 检查是否已有扩展数据
|
||||
db := es.databaseService.GetDB()
|
||||
if db == nil {
|
||||
return &ExtensionError{"get_database", "", fmt.Errorf("database connection is nil")}
|
||||
}
|
||||
|
||||
var count int
|
||||
err := db.QueryRow("SELECT COUNT(*) FROM extensions").Scan(&count)
|
||||
rows, err := es.databaseService.SQLite.Query("SELECT COUNT(*) FROM extensions")
|
||||
if err != nil {
|
||||
return &ExtensionError{"check_extensions_count", "", err}
|
||||
}
|
||||
|
||||
es.logger.Info("Extension database check", "existing_count", count)
|
||||
if len(rows) == 0 {
|
||||
return &ExtensionError{"check_extensions_count", "", fmt.Errorf("no rows returned")}
|
||||
}
|
||||
|
||||
count, ok := rows[0]["COUNT(*)"].(int64)
|
||||
if !ok {
|
||||
return &ExtensionError{"convert_count", "", fmt.Errorf("failed to convert count to int64")}
|
||||
}
|
||||
|
||||
// 如果没有数据,插入默认配置
|
||||
if count == 0 {
|
||||
es.logger.Info("No extensions found, inserting default extensions...")
|
||||
if err := es.insertDefaultExtensions(); err != nil {
|
||||
es.logger.Error("Failed to insert default extensions", "error", err)
|
||||
return err
|
||||
}
|
||||
es.logger.Info("Default extensions inserted successfully")
|
||||
} else {
|
||||
es.logger.Info("Extensions already exist, skipping default insertion")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -136,21 +133,16 @@ func (es *ExtensionService) initDatabase() error {
|
||||
// insertDefaultExtensions 插入默认扩展配置
|
||||
func (es *ExtensionService) insertDefaultExtensions() error {
|
||||
defaultSettings := models.NewDefaultExtensionSettings()
|
||||
db := es.databaseService.GetDB()
|
||||
now := time.Now()
|
||||
|
||||
es.logger.Info("Starting to insert default extensions", "count", len(defaultSettings.Extensions))
|
||||
|
||||
for i, ext := range defaultSettings.Extensions {
|
||||
es.logger.Info("Inserting extension", "index", i+1, "id", ext.ID, "enabled", ext.Enabled)
|
||||
for _, ext := range defaultSettings.Extensions {
|
||||
|
||||
configJSON, err := json.Marshal(ext.Config)
|
||||
if err != nil {
|
||||
es.logger.Error("Failed to marshal config", "extension", ext.ID, "error", err)
|
||||
return &ExtensionError{"marshal_config", string(ext.ID), err}
|
||||
}
|
||||
|
||||
_, err = db.Exec(sqlInsertExtension,
|
||||
err = es.databaseService.SQLite.Execute(sqlInsertExtension,
|
||||
string(ext.ID),
|
||||
ext.Enabled,
|
||||
ext.IsDefault,
|
||||
@@ -159,31 +151,24 @@ func (es *ExtensionService) insertDefaultExtensions() error {
|
||||
now,
|
||||
)
|
||||
if err != nil {
|
||||
es.logger.Error("Failed to insert extension", "extension", ext.ID, "error", err)
|
||||
return &ExtensionError{"insert_extension", string(ext.ID), err}
|
||||
}
|
||||
|
||||
es.logger.Info("Successfully inserted extension", "id", ext.ID)
|
||||
}
|
||||
|
||||
es.logger.Info("Completed inserting all default extensions")
|
||||
return nil
|
||||
}
|
||||
|
||||
// OnStartup 启动时调用
|
||||
func (es *ExtensionService) OnStartup(ctx context.Context, _ application.ServiceOptions) error {
|
||||
// ServiceStartup 启动时调用
|
||||
func (es *ExtensionService) ServiceStartup(ctx context.Context, options application.ServiceOptions) error {
|
||||
es.ctx = ctx
|
||||
es.logger.Info("Extension service starting up")
|
||||
|
||||
// 初始化数据库
|
||||
var initErr error
|
||||
es.initOnce.Do(func() {
|
||||
es.logger.Info("Initializing extension database...")
|
||||
if err := es.initDatabase(); err != nil {
|
||||
es.logger.Error("failed to initialize extension database", "error", err)
|
||||
initErr = err
|
||||
} else {
|
||||
es.logger.Info("Extension database initialized successfully")
|
||||
}
|
||||
})
|
||||
return initErr
|
||||
@@ -194,28 +179,36 @@ func (es *ExtensionService) GetAllExtensions() ([]models.Extension, error) {
|
||||
es.mu.RLock()
|
||||
defer es.mu.RUnlock()
|
||||
|
||||
db := es.databaseService.GetDB()
|
||||
rows, err := db.Query(sqlGetAllExtensions)
|
||||
rows, err := es.databaseService.SQLite.Query(sqlGetAllExtensions)
|
||||
if err != nil {
|
||||
return nil, &ExtensionError{"query_extensions", "", err}
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var extensions []models.Extension
|
||||
for rows.Next() {
|
||||
for _, row := range rows {
|
||||
var ext models.Extension
|
||||
var configJSON string
|
||||
if err := rows.Scan(&ext.ID, &ext.Enabled, &ext.IsDefault, &configJSON); err != nil {
|
||||
return nil, &ExtensionError{"scan_extension", "", err}
|
||||
}
|
||||
if err := json.Unmarshal([]byte(configJSON), &ext.Config); err != nil {
|
||||
return nil, &ExtensionError{"unmarshal_config", string(ext.ID), err}
|
||||
}
|
||||
extensions = append(extensions, ext)
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, &ExtensionError{"rows_error", "", err}
|
||||
if id, ok := row["id"].(string); ok {
|
||||
ext.ID = models.ExtensionID(id)
|
||||
}
|
||||
|
||||
if enabled, ok := row["enabled"].(int64); ok {
|
||||
ext.Enabled = enabled == 1
|
||||
}
|
||||
|
||||
if isDefault, ok := row["is_default"].(int64); ok {
|
||||
ext.IsDefault = isDefault == 1
|
||||
}
|
||||
|
||||
if configJSON, ok := row["config"].(string); ok {
|
||||
var config models.ExtensionConfig
|
||||
if err := json.Unmarshal([]byte(configJSON), &config); err != nil {
|
||||
return nil, &ExtensionError{"unmarshal_config", string(ext.ID), err}
|
||||
}
|
||||
ext.Config = config
|
||||
}
|
||||
|
||||
extensions = append(extensions, ext)
|
||||
}
|
||||
|
||||
return extensions, nil
|
||||
@@ -231,7 +224,6 @@ func (es *ExtensionService) UpdateExtensionState(id models.ExtensionID, enabled
|
||||
es.mu.Lock()
|
||||
defer es.mu.Unlock()
|
||||
|
||||
db := es.databaseService.GetDB()
|
||||
var configJSON []byte
|
||||
var err error
|
||||
|
||||
@@ -242,20 +234,28 @@ func (es *ExtensionService) UpdateExtensionState(id models.ExtensionID, enabled
|
||||
}
|
||||
} else {
|
||||
// 如果没有提供配置,保持原有配置
|
||||
var currentConfigJSON string
|
||||
err = db.QueryRow("SELECT config FROM extensions WHERE id = ?", string(id)).Scan(¤tConfigJSON)
|
||||
rows, err := es.databaseService.SQLite.Query("SELECT config FROM extensions WHERE id = ?", string(id))
|
||||
if err != nil {
|
||||
return &ExtensionError{"query_current_config", string(id), err}
|
||||
}
|
||||
|
||||
if len(rows) == 0 {
|
||||
return &ExtensionError{"query_current_config", string(id), fmt.Errorf("extension not found")}
|
||||
}
|
||||
|
||||
currentConfigJSON, ok := rows[0]["config"].(string)
|
||||
if !ok {
|
||||
return &ExtensionError{"convert_config", string(id), fmt.Errorf("failed to get current config")}
|
||||
}
|
||||
|
||||
configJSON = []byte(currentConfigJSON)
|
||||
}
|
||||
|
||||
_, err = db.Exec(sqlUpdateExtension, enabled, string(configJSON), time.Now(), string(id))
|
||||
err = es.databaseService.SQLite.Execute(sqlUpdateExtension, enabled, string(configJSON), time.Now(), string(id))
|
||||
if err != nil {
|
||||
return &ExtensionError{"update_extension", string(id), err}
|
||||
}
|
||||
|
||||
es.logger.Info("extension state updated", "id", id, "enabled", enabled)
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -277,8 +277,7 @@ func (es *ExtensionService) ResetAllExtensionsToDefault() error {
|
||||
defer es.mu.Unlock()
|
||||
|
||||
// 删除所有现有扩展
|
||||
db := es.databaseService.GetDB()
|
||||
_, err := db.Exec(sqlDeleteAllExtensions)
|
||||
err := es.databaseService.SQLite.Execute(sqlDeleteAllExtensions)
|
||||
if err != nil {
|
||||
return &ExtensionError{"delete_all_extensions", "", err}
|
||||
}
|
||||
@@ -288,6 +287,5 @@ func (es *ExtensionService) ResetAllExtensionsToDefault() error {
|
||||
return err
|
||||
}
|
||||
|
||||
es.logger.Info("all extensions reset to default")
|
||||
return nil
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ import (
|
||||
|
||||
// HotkeyService Windows全局热键服务
|
||||
type HotkeyService struct {
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
configService *ConfigService
|
||||
app *application.App
|
||||
|
||||
@@ -52,7 +52,7 @@ func (e *HotkeyError) Unwrap() error {
|
||||
}
|
||||
|
||||
// NewHotkeyService 创建热键服务实例
|
||||
func NewHotkeyService(configService *ConfigService, logger *log.LoggerService) *HotkeyService {
|
||||
func NewHotkeyService(configService *ConfigService, logger *log.Service) *HotkeyService {
|
||||
if logger == nil {
|
||||
logger = log.New()
|
||||
}
|
||||
@@ -202,7 +202,7 @@ func cBool(b bool) C.int {
|
||||
// toggleWindow 切换窗口
|
||||
func (hs *HotkeyService) toggleWindow() {
|
||||
if hs.app != nil {
|
||||
hs.app.EmitEvent("hotkey:toggle-window", nil)
|
||||
hs.app.Event.Emit("hotkey:toggle-window", nil)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -259,7 +259,7 @@ func (hs *HotkeyService) IsRegistered() bool {
|
||||
return hs.isRegistered.Load()
|
||||
}
|
||||
|
||||
// OnShutdown 关闭服务
|
||||
// ServiceShutdown 关闭服务
|
||||
func (hs *HotkeyService) ServiceShutdown() error {
|
||||
hs.cancel()
|
||||
hs.wg.Wait()
|
||||
|
@@ -80,7 +80,7 @@ var globalHotkeyService *HotkeyService
|
||||
|
||||
// HotkeyService macOS全局热键服务
|
||||
type HotkeyService struct {
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
configService *ConfigService
|
||||
app *application.App
|
||||
mu sync.RWMutex
|
||||
@@ -105,7 +105,7 @@ func (e *HotkeyError) Unwrap() error {
|
||||
}
|
||||
|
||||
// NewHotkeyService 创建新的热键服务实例
|
||||
func NewHotkeyService(configService *ConfigService, logger *log.LoggerService) *HotkeyService {
|
||||
func NewHotkeyService(configService *ConfigService, logger *log.Service) *HotkeyService {
|
||||
if logger == nil {
|
||||
logger = log.New()
|
||||
}
|
||||
@@ -290,8 +290,8 @@ func (hs *HotkeyService) ToggleWindow() {
|
||||
}
|
||||
}
|
||||
|
||||
// OnShutdown 关闭热键服务
|
||||
func (hs *HotkeyService) OnShutdown() error {
|
||||
// ServiceShutdown 关闭热键服务
|
||||
func (hs *HotkeyService) ServiceShutdown() error {
|
||||
return hs.UnregisterHotkey()
|
||||
}
|
||||
|
||||
|
@@ -141,7 +141,7 @@ import (
|
||||
|
||||
// HotkeyService Linux全局热键服务
|
||||
type HotkeyService struct {
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
configService *ConfigService
|
||||
app *application.App
|
||||
|
||||
@@ -170,7 +170,7 @@ func (e *HotkeyError) Unwrap() error {
|
||||
}
|
||||
|
||||
// NewHotkeyService 创建热键服务实例
|
||||
func NewHotkeyService(configService *ConfigService, logger *log.LoggerService) *HotkeyService {
|
||||
func NewHotkeyService(configService *ConfigService, logger *log.Service) *HotkeyService {
|
||||
if logger == nil {
|
||||
logger = log.New()
|
||||
}
|
||||
@@ -384,8 +384,8 @@ func (hs *HotkeyService) IsRegistered() bool {
|
||||
return hs.isRegistered.Load()
|
||||
}
|
||||
|
||||
// OnShutdown 关闭服务
|
||||
func (hs *HotkeyService) OnShutdown() error {
|
||||
// ServiceShutdown 关闭服务
|
||||
func (hs *HotkeyService) ServiceShutdown() error {
|
||||
hs.cancel()
|
||||
hs.wg.Wait()
|
||||
C.closeX11Display()
|
||||
|
@@ -51,7 +51,7 @@ const (
|
||||
// KeyBindingService 快捷键管理服务
|
||||
type KeyBindingService struct {
|
||||
databaseService *DatabaseService
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
|
||||
mu sync.RWMutex
|
||||
ctx context.Context
|
||||
@@ -83,7 +83,7 @@ func (e *KeyBindingError) Is(target error) bool {
|
||||
}
|
||||
|
||||
// NewKeyBindingService 创建快捷键服务实例
|
||||
func NewKeyBindingService(databaseService *DatabaseService, logger *log.LoggerService) *KeyBindingService {
|
||||
func NewKeyBindingService(databaseService *DatabaseService, logger *log.Service) *KeyBindingService {
|
||||
if logger == nil {
|
||||
logger = log.New()
|
||||
}
|
||||
@@ -106,29 +106,26 @@ func (kbs *KeyBindingService) initDatabase() error {
|
||||
defer kbs.mu.Unlock()
|
||||
|
||||
// 检查是否已有快捷键数据
|
||||
db := kbs.databaseService.GetDB()
|
||||
if db == nil {
|
||||
return &KeyBindingError{"get_database", "", fmt.Errorf("database connection is nil")}
|
||||
}
|
||||
|
||||
var count int
|
||||
err := db.QueryRow("SELECT COUNT(*) FROM key_bindings").Scan(&count)
|
||||
rows, err := kbs.databaseService.SQLite.Query("SELECT COUNT(*) FROM key_bindings")
|
||||
if err != nil {
|
||||
return &KeyBindingError{"check_keybindings_count", "", err}
|
||||
}
|
||||
|
||||
kbs.logger.Info("KeyBinding database check", "existing_count", count)
|
||||
if len(rows) == 0 {
|
||||
return &KeyBindingError{"check_keybindings_count", "", fmt.Errorf("no rows returned")}
|
||||
}
|
||||
|
||||
count, ok := rows[0]["COUNT(*)"].(int64)
|
||||
if !ok {
|
||||
return &KeyBindingError{"convert_count", "", fmt.Errorf("failed to convert count to int64")}
|
||||
}
|
||||
|
||||
// 如果没有数据,插入默认配置
|
||||
if count == 0 {
|
||||
kbs.logger.Info("No key bindings found, inserting default key bindings...")
|
||||
if err := kbs.insertDefaultKeyBindings(); err != nil {
|
||||
kbs.logger.Error("Failed to insert default key bindings", "error", err)
|
||||
return err
|
||||
}
|
||||
kbs.logger.Info("Default key bindings inserted successfully")
|
||||
} else {
|
||||
kbs.logger.Info("Key bindings already exist, skipping default insertion")
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -137,17 +134,13 @@ func (kbs *KeyBindingService) initDatabase() error {
|
||||
// insertDefaultKeyBindings 插入默认快捷键配置
|
||||
func (kbs *KeyBindingService) insertDefaultKeyBindings() error {
|
||||
defaultConfig := models.NewDefaultKeyBindingConfig()
|
||||
db := kbs.databaseService.GetDB()
|
||||
now := time.Now()
|
||||
|
||||
kbs.logger.Info("Starting to insert default key bindings", "count", len(defaultConfig.KeyBindings))
|
||||
for _, kb := range defaultConfig.KeyBindings {
|
||||
|
||||
for i, kb := range defaultConfig.KeyBindings {
|
||||
kbs.logger.Info("Inserting key binding", "index", i+1, "command", kb.Command, "key", kb.Key, "extension", kb.Extension)
|
||||
|
||||
_, err := db.Exec(sqlInsertKeyBinding,
|
||||
kb.Command,
|
||||
kb.Extension,
|
||||
err := kbs.databaseService.SQLite.Execute(sqlInsertKeyBinding,
|
||||
string(kb.Command), // 转换为字符串存储
|
||||
string(kb.Extension), // 转换为字符串存储
|
||||
kb.Key,
|
||||
kb.Enabled,
|
||||
kb.IsDefault,
|
||||
@@ -155,72 +148,63 @@ func (kbs *KeyBindingService) insertDefaultKeyBindings() error {
|
||||
now,
|
||||
)
|
||||
if err != nil {
|
||||
kbs.logger.Error("Failed to insert key binding", "command", kb.Command, "error", err)
|
||||
return &KeyBindingError{"insert_keybinding", string(kb.Command), err}
|
||||
}
|
||||
|
||||
kbs.logger.Info("Successfully inserted key binding", "command", kb.Command)
|
||||
}
|
||||
|
||||
kbs.logger.Info("Completed inserting all default key bindings")
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetKeyBindingConfig 获取完整快捷键配置
|
||||
func (kbs *KeyBindingService) GetKeyBindingConfig() (*models.KeyBindingConfig, error) {
|
||||
keyBindings, err := kbs.GetAllKeyBindings()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
config := &models.KeyBindingConfig{
|
||||
KeyBindings: keyBindings,
|
||||
}
|
||||
return config, nil
|
||||
}
|
||||
|
||||
// GetAllKeyBindings 获取所有快捷键配置
|
||||
func (kbs *KeyBindingService) GetAllKeyBindings() ([]models.KeyBinding, error) {
|
||||
kbs.mu.RLock()
|
||||
defer kbs.mu.RUnlock()
|
||||
|
||||
db := kbs.databaseService.GetDB()
|
||||
rows, err := db.Query(sqlGetAllKeyBindings)
|
||||
rows, err := kbs.databaseService.SQLite.Query(sqlGetAllKeyBindings)
|
||||
if err != nil {
|
||||
return nil, &KeyBindingError{"query_keybindings", "", err}
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var keyBindings []models.KeyBinding
|
||||
for rows.Next() {
|
||||
for _, row := range rows {
|
||||
var kb models.KeyBinding
|
||||
if err := rows.Scan(&kb.Command, &kb.Extension, &kb.Key, &kb.Enabled, &kb.IsDefault); err != nil {
|
||||
return nil, &KeyBindingError{"scan_keybinding", "", err}
|
||||
}
|
||||
keyBindings = append(keyBindings, kb)
|
||||
}
|
||||
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, &KeyBindingError{"rows_error", "", err}
|
||||
if command, ok := row["command"].(string); ok {
|
||||
kb.Command = models.KeyBindingCommand(command)
|
||||
}
|
||||
|
||||
if extension, ok := row["extension"].(string); ok {
|
||||
kb.Extension = models.ExtensionID(extension)
|
||||
}
|
||||
|
||||
if key, ok := row["key"].(string); ok {
|
||||
kb.Key = key
|
||||
}
|
||||
|
||||
if enabled, ok := row["enabled"].(int64); ok {
|
||||
kb.Enabled = enabled == 1
|
||||
}
|
||||
|
||||
if isDefault, ok := row["is_default"].(int64); ok {
|
||||
kb.IsDefault = isDefault == 1
|
||||
}
|
||||
|
||||
keyBindings = append(keyBindings, kb)
|
||||
}
|
||||
|
||||
return keyBindings, nil
|
||||
}
|
||||
|
||||
// OnStartup 启动时调用
|
||||
func (kbs *KeyBindingService) OnStartup(ctx context.Context, _ application.ServiceOptions) error {
|
||||
// ServiceStartup 启动时调用
|
||||
func (kbs *KeyBindingService) ServiceStartup(ctx context.Context, options application.ServiceOptions) error {
|
||||
kbs.ctx = ctx
|
||||
kbs.logger.Info("KeyBinding service starting up")
|
||||
|
||||
// 初始化数据库
|
||||
var initErr error
|
||||
kbs.initOnce.Do(func() {
|
||||
kbs.logger.Info("Initializing keybinding database...")
|
||||
if err := kbs.initDatabase(); err != nil {
|
||||
kbs.logger.Error("failed to initialize keybinding database", "error", err)
|
||||
initErr = err
|
||||
} else {
|
||||
kbs.logger.Info("KeyBinding database initialized successfully")
|
||||
}
|
||||
})
|
||||
return initErr
|
||||
|
@@ -33,7 +33,7 @@ type MigrationProgress struct {
|
||||
|
||||
// MigrationService 迁移服务
|
||||
type MigrationService struct {
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
mu sync.RWMutex
|
||||
progress atomic.Value // stores MigrationProgress
|
||||
|
||||
@@ -42,7 +42,7 @@ type MigrationService struct {
|
||||
}
|
||||
|
||||
// NewMigrationService 创建迁移服务
|
||||
func NewMigrationService(logger *log.LoggerService) *MigrationService {
|
||||
func NewMigrationService(logger *log.Service) *MigrationService {
|
||||
if logger == nil {
|
||||
logger = log.New()
|
||||
}
|
||||
@@ -417,8 +417,8 @@ func (ms *MigrationService) CancelMigration() error {
|
||||
return fmt.Errorf("no active migration to cancel")
|
||||
}
|
||||
|
||||
// OnShutdown 服务关闭
|
||||
func (ms *MigrationService) OnShutdown() error {
|
||||
// ServiceShutdown 服务关闭
|
||||
func (ms *MigrationService) ServiceShutdown() error {
|
||||
ms.CancelMigration()
|
||||
return nil
|
||||
}
|
||||
|
@@ -26,7 +26,7 @@ type SelfUpdateResult struct {
|
||||
|
||||
// SelfUpdateService 自我更新服务
|
||||
type SelfUpdateService struct {
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
configService *ConfigService
|
||||
config *models.AppConfig
|
||||
|
||||
@@ -35,7 +35,7 @@ type SelfUpdateService struct {
|
||||
}
|
||||
|
||||
// NewSelfUpdateService 创建自我更新服务实例
|
||||
func NewSelfUpdateService(configService *ConfigService, logger *log.LoggerService) (*SelfUpdateService, error) {
|
||||
func NewSelfUpdateService(configService *ConfigService, logger *log.Service) (*SelfUpdateService, error) {
|
||||
// 获取配置
|
||||
appConfig, err := configService.GetConfig()
|
||||
if err != nil {
|
||||
|
@@ -5,12 +5,14 @@ import (
|
||||
|
||||
"github.com/wailsapp/wails/v3/pkg/application"
|
||||
"github.com/wailsapp/wails/v3/pkg/services/log"
|
||||
"github.com/wailsapp/wails/v3/pkg/services/sqlite"
|
||||
)
|
||||
|
||||
// ServiceManager 服务管理器,负责协调各个服务
|
||||
type ServiceManager struct {
|
||||
configService *ConfigService
|
||||
databaseService *DatabaseService
|
||||
sqliteService *sqlite.Service
|
||||
documentService *DocumentService
|
||||
migrationService *MigrationService
|
||||
systemService *SystemService
|
||||
@@ -22,7 +24,7 @@ type ServiceManager struct {
|
||||
startupService *StartupService
|
||||
selfUpdateService *SelfUpdateService
|
||||
translationService *TranslationService
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
}
|
||||
|
||||
// NewServiceManager 创建新的服务管理器实例
|
||||
@@ -33,6 +35,9 @@ func NewServiceManager() *ServiceManager {
|
||||
// 初始化配置服务
|
||||
configService := NewConfigService(logger)
|
||||
|
||||
// 初始化SQLite服务
|
||||
sqliteService := sqlite.New()
|
||||
|
||||
// 初始化数据库服务
|
||||
databaseService := NewDatabaseService(configService, logger)
|
||||
|
||||
@@ -91,6 +96,7 @@ func NewServiceManager() *ServiceManager {
|
||||
return &ServiceManager{
|
||||
configService: configService,
|
||||
databaseService: databaseService,
|
||||
sqliteService: sqliteService,
|
||||
documentService: documentService,
|
||||
migrationService: migrationService,
|
||||
systemService: systemService,
|
||||
@@ -111,7 +117,8 @@ func NewServiceManager() *ServiceManager {
|
||||
func (sm *ServiceManager) GetServices() []application.Service {
|
||||
services := []application.Service{
|
||||
application.NewService(sm.configService),
|
||||
application.NewService(sm.databaseService),
|
||||
application.NewService(sm.sqliteService), // SQLite服务必须在数据库服务之前初始化
|
||||
application.NewService(sm.databaseService), // 数据库服务必须在依赖它的服务之前初始化
|
||||
application.NewService(sm.documentService),
|
||||
application.NewService(sm.keyBindingService),
|
||||
application.NewService(sm.extensionService),
|
||||
@@ -138,7 +145,7 @@ func (sm *ServiceManager) GetDialogService() *DialogService {
|
||||
}
|
||||
|
||||
// GetLogger 获取日志服务实例
|
||||
func (sm *ServiceManager) GetLogger() *log.LoggerService {
|
||||
func (sm *ServiceManager) GetLogger() *log.Service {
|
||||
return sm.logger
|
||||
}
|
||||
|
||||
@@ -181,3 +188,8 @@ func (sm *ServiceManager) GetTranslationService() *TranslationService {
|
||||
func (sm *ServiceManager) GetDatabaseService() *DatabaseService {
|
||||
return sm.databaseService
|
||||
}
|
||||
|
||||
// GetSQLiteService 获取SQLite服务实例
|
||||
func (sm *ServiceManager) GetSQLiteService() *sqlite.Service {
|
||||
return sm.sqliteService
|
||||
}
|
||||
|
@@ -15,14 +15,14 @@ import (
|
||||
|
||||
// DarwinStartupImpl macOS 平台开机启动实现
|
||||
type DarwinStartupImpl struct {
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
disabled bool
|
||||
appPath string
|
||||
appName string
|
||||
}
|
||||
|
||||
// newStartupImplementation 创建平台特定的开机启动实现
|
||||
func newStartupImplementation(logger *log.LoggerService) StartupImplementation {
|
||||
func newStartupImplementation(logger *log.Service) StartupImplementation {
|
||||
return &DarwinStartupImpl{
|
||||
logger: logger,
|
||||
}
|
||||
|
@@ -13,7 +13,7 @@ import (
|
||||
|
||||
// LinuxStartupImpl Linux 平台开机启动实现
|
||||
type LinuxStartupImpl struct {
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
autostartDir string
|
||||
execPath string
|
||||
appName string
|
||||
@@ -37,7 +37,7 @@ X-GNOME-Autostart-enabled=true
|
||||
`
|
||||
|
||||
// newStartupImplementation 创建平台特定的开机启动实现
|
||||
func newStartupImplementation(logger *log.LoggerService) StartupImplementation {
|
||||
func newStartupImplementation(logger *log.Service) StartupImplementation {
|
||||
return &LinuxStartupImpl{
|
||||
logger: logger,
|
||||
}
|
||||
|
@@ -7,7 +7,7 @@ import (
|
||||
// StartupService 开机启动服务
|
||||
type StartupService struct {
|
||||
configService *ConfigService
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
impl StartupImplementation
|
||||
initError error
|
||||
}
|
||||
@@ -19,7 +19,7 @@ type StartupImplementation interface {
|
||||
}
|
||||
|
||||
// NewStartupService 创建开机启动服务实例
|
||||
func NewStartupService(configService *ConfigService, logger *log.LoggerService) *StartupService {
|
||||
func NewStartupService(configService *ConfigService, logger *log.Service) *StartupService {
|
||||
service := &StartupService{
|
||||
configService: configService,
|
||||
logger: logger,
|
||||
|
@@ -15,7 +15,7 @@ import (
|
||||
|
||||
// WindowsStartupImpl Windows 平台开机启动实现
|
||||
type WindowsStartupImpl struct {
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
registryKey string
|
||||
execPath string
|
||||
workingDir string
|
||||
@@ -23,7 +23,7 @@ type WindowsStartupImpl struct {
|
||||
}
|
||||
|
||||
// newStartupImplementation 创建平台特定的开机启动实现
|
||||
func newStartupImplementation(logger *log.LoggerService) StartupImplementation {
|
||||
func newStartupImplementation(logger *log.Service) StartupImplementation {
|
||||
return &WindowsStartupImpl{
|
||||
logger: logger,
|
||||
}
|
||||
|
@@ -15,7 +15,7 @@ import (
|
||||
type StoreOption struct {
|
||||
FilePath string
|
||||
AutoSave bool
|
||||
Logger *log.LoggerService
|
||||
Logger *log.Service
|
||||
}
|
||||
|
||||
// Store 泛型存储服务
|
||||
@@ -25,7 +25,7 @@ type Store[T any] struct {
|
||||
dataMap sync.Map // thread-safe map
|
||||
unsaved atomic.Bool
|
||||
initOnce sync.Once
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
}
|
||||
|
||||
// NewStore 存储服务
|
||||
|
@@ -9,7 +9,7 @@ import (
|
||||
|
||||
// SystemService 系统监控服务
|
||||
type SystemService struct {
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
}
|
||||
|
||||
// MemoryStats 内存统计信息
|
||||
@@ -29,7 +29,7 @@ type MemoryStats struct {
|
||||
}
|
||||
|
||||
// NewSystemService 创建新的系统服务实例
|
||||
func NewSystemService(logger *log.LoggerService) *SystemService {
|
||||
func NewSystemService(logger *log.Service) *SystemService {
|
||||
return &SystemService{
|
||||
logger: logger,
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ import (
|
||||
|
||||
// TranslationService 翻译服务
|
||||
type TranslationService struct {
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
factory *translator.TranslatorFactory
|
||||
defaultTimeout time.Duration
|
||||
translators map[translator.TranslatorType]translator.Translator
|
||||
@@ -18,7 +18,7 @@ type TranslationService struct {
|
||||
}
|
||||
|
||||
// NewTranslationService 创建翻译服务实例
|
||||
func NewTranslationService(logger *log.LoggerService) *TranslationService {
|
||||
func NewTranslationService(logger *log.Service) *TranslationService {
|
||||
service := &TranslationService{
|
||||
logger: logger,
|
||||
factory: translator.NewTranslatorFactory(),
|
||||
|
@@ -7,14 +7,14 @@ import (
|
||||
|
||||
// TrayService 系统托盘服务
|
||||
type TrayService struct {
|
||||
logger *log.LoggerService
|
||||
logger *log.Service
|
||||
configService *ConfigService
|
||||
app *application.App
|
||||
mainWindow *application.WebviewWindow
|
||||
}
|
||||
|
||||
// NewTrayService 创建新的系统托盘服务实例
|
||||
func NewTrayService(logger *log.LoggerService, configService *ConfigService) *TrayService {
|
||||
func NewTrayService(logger *log.Service, configService *ConfigService) *TrayService {
|
||||
return &TrayService{
|
||||
logger: logger,
|
||||
configService: configService,
|
||||
@@ -42,7 +42,7 @@ func (ts *TrayService) HandleWindowClose() {
|
||||
if ts.ShouldMinimizeToTray() {
|
||||
// 隐藏到托盘
|
||||
ts.mainWindow.Hide()
|
||||
ts.app.EmitEvent("window:hidden", nil)
|
||||
ts.app.Event.Emit("window:hidden", nil)
|
||||
} else {
|
||||
// 直接退出应用
|
||||
ts.app.Quit()
|
||||
@@ -54,7 +54,7 @@ func (ts *TrayService) HandleWindowMinimize() {
|
||||
if ts.ShouldMinimizeToTray() {
|
||||
// 隐藏到托盘
|
||||
ts.mainWindow.Hide()
|
||||
ts.app.EmitEvent("window:hidden", nil)
|
||||
ts.app.Event.Emit("window:hidden", nil)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ func (ts *TrayService) ShowWindow() {
|
||||
ts.mainWindow.Restore()
|
||||
ts.mainWindow.Focus()
|
||||
if ts.app != nil {
|
||||
ts.app.EmitEvent("window:shown", nil)
|
||||
ts.app.Event.Emit("window:shown", nil)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -10,7 +10,7 @@ import (
|
||||
// SetupSystemTray 设置系统托盘及其功能
|
||||
func SetupSystemTray(app *application.App, mainWindow *application.WebviewWindow, assets embed.FS, trayService *services.TrayService) {
|
||||
// 创建系统托盘
|
||||
systray := app.NewSystemTray()
|
||||
systray := app.SystemTray.New()
|
||||
|
||||
// 设置图标
|
||||
iconBytes, _ := assets.ReadFile("appicon.png")
|
||||
|
Reference in New Issue
Block a user