package main import ( "encoding/json" "fmt" "log/slog" "time" "u-desk/internal/api" "u-desk/internal/common" "u-desk/internal/service" "u-desk/internal/storage" "u-desk/internal/storage/models" "gorm.io/gorm" ) // ========== 应用配置接口 ========== // GetAppConfig 获取应用配置 func (a *App) GetAppConfig() (map[string]interface{}, error) { if a.configAPI == nil { return nil, fmt.Errorf("配置服务正在初始化中") } return a.configAPI.GetAppConfig() } // SaveAppConfig 保存应用配置 func (a *App) SaveAppConfig(req SaveAppConfigRequest) (map[string]interface{}, error) { if a.configAPI == nil { return nil, fmt.Errorf("配置服务正在初始化中") } oldConfig, _ := a.configAPI.GetAppConfig() var oldVisibleTabs []string if success, ok := oldConfig["success"].(bool); ok && success { if data, ok := oldConfig["data"].(map[string]interface{}); ok { if vtInterface, ok := data["visibleTabs"].([]interface{}); ok { oldVisibleTabs = common.InterfaceSliceToStringSlice(vtInterface) } } } apiReq := api.SaveAppConfigRequest{ Tabs: req.Tabs, VisibleTabs: req.VisibleTabs, DefaultTab: req.DefaultTab, } result, err := a.configAPI.SaveAppConfig(apiReq) if err != nil { return result, err } if success, ok := result["success"].(bool); ok && success { a.handleNewlyEnabledModules(oldVisibleTabs, req.VisibleTabs) } return result, nil } func (a *App) LoadConnectionProfiles() ([]map[string]interface{}, error) { list, err := a.ensureProfileSvc().ListProfiles() if err != nil { return nil, err } var result []map[string]interface{} data, _ := json.Marshal(list) if err := json.Unmarshal(data, &result); err != nil { return nil, fmt.Errorf("解析连接配置失败: %w", err) } return result, nil } func (a *App) SaveConnectionProfile(req SaveProfileRequest) (map[string]interface{}, error) { p := &models.ConnectionProfile{ Name: req.Name, Host: req.Host, Port: req.Port, Username: req.Username, Password: req.Password, KeyPath: req.KeyPath, Type: req.Type, Provider: req.Provider, Token: req.Token, AccessKey: req.AccessKey, SecretKey: req.SecretKey, Bucket: req.Bucket, Region: req.Region, Endpoint: req.Endpoint, } if req.LastConnected != nil { t := time.Unix(*req.LastConnected, 0) p.LastConnected = &t } if req.ID != nil { p.ID = *req.ID } if err := a.ensureProfileSvc().SaveProfile(p); err != nil { return nil, err } return map[string]interface{}{"id": float64(p.ID), "success": true}, nil } func (a *App) DeleteConnectionProfile(id uint) error { return a.ensureProfileSvc().DeleteProfile(id) } // BgmGetPlaylist 获取播放列表 func (a *App) BgmGetPlaylist() ([]BgmPlaylistItem, error) { db := storage.GetDB() if db == nil { return nil, fmt.Errorf("数据库未初始化") } var rows []models.BgmPlaylist if err := db.Order("sort ASC").Find(&rows).Error; err != nil { return nil, fmt.Errorf("查询播放列表失败: %w", err) } items := make([]BgmPlaylistItem, len(rows)) for i, r := range rows { items[i] = BgmPlaylistItem{Name: r.Name, Path: r.Path, ProfileID: r.ProfileID} } return items, nil } // BgmSavePlaylist 全量保存播放列表(前端调用时传完整列表) func (a *App) BgmSavePlaylist(items []BgmPlaylistItem) error { db := storage.GetDB() if db == nil { return fmt.Errorf("数据库未初始化") } return db.Transaction(func(tx *gorm.DB) error { if err := tx.Exec("DELETE FROM bgm_playlist").Error; err != nil { return err } sort := uint(0) for _, item := range items { if item.Name == "" || item.Path == "" { continue } if err := tx.Create(&models.BgmPlaylist{Name: item.Name, Path: item.Path, ProfileID: item.ProfileID, Sort: sort}).Error; err != nil { return err } sort++ } return nil }) } func (a *App) ensureProfileSvc() *service.ProfileService { a.mu.Lock() defer a.mu.Unlock() if a.profileSvc == nil { a.profileSvc = service.NewProfileService() } return a.profileSvc } // getVisibleTabs 获取配置中的可见 Tabs func (a *App) getVisibleTabs() []string { config, err := a.configAPI.GetAppConfig() if err != nil { slog.Warn("读取配置失败,使用默认配置", "error", err) return common.DefaultVisibleTabs } success, ok := config["success"].(bool) if !ok || !success { slog.Warn("配置读取失败,使用默认配置") return common.DefaultVisibleTabs } data, ok := config["data"].(map[string]interface{}) if !ok { return common.DefaultVisibleTabs } visibleTabsInterface, ok := data["visibleTabs"].([]interface{}) if !ok { return common.DefaultVisibleTabs } visibleTabs := common.InterfaceSliceToStringSlice(visibleTabsInterface) if len(visibleTabs) == 0 { return common.DefaultVisibleTabs } return visibleTabs } // handleNewlyEnabledModules 处理新启用的模块 func (a *App) handleNewlyEnabledModules(oldTabs, newTabs []string) { newlyEnabled := common.Difference(newTabs, oldTabs) if len(newlyEnabled) == 0 { return } slog.Info("检测到新启用的模块", "modules", newlyEnabled) for _, tab := range newlyEnabled { switch tab { case common.TabFileSystem: a.initFilesystemModule() case common.TabDevice: slog.Info("设备测试模块已启用") } } } // initModulesByConfig 根据配置初始化模块 func (a *App) initModulesByConfig(visibleTabs []string) error { if common.Contains(visibleTabs, common.TabFileSystem) { a.initFilesystemModule() if a.filesystem == nil { return fmt.Errorf("文件系统服务初始化失败") } } else { slog.Info("跳过文件系统模块(未启用)") } return nil }