重构: App拆分10域文件+并发安全+结构化日志+依赖升级

This commit is contained in:
lxy
2026-05-16 20:45:14 +08:00
parent d17c20c579
commit 767311fc04
27 changed files with 1457 additions and 1218 deletions
+215
View File
@@ -0,0 +1,215 @@
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
}