refactor: config package

This commit is contained in:
2026-02-04 20:49:40 +08:00
parent 0e94ae3220
commit a4173c327d
10 changed files with 206 additions and 91 deletions

116
internal/config/config.go Normal file
View File

@@ -0,0 +1,116 @@
package config
import (
"log/slog"
"os"
"path/filepath"
"sync"
"github.com/spf13/viper"
)
// WindowState 定义窗口状态
type WindowState struct {
Width int `mapstructure:"width"`
Height int `mapstructure:"height"`
X int `mapstructure:"x"`
Y int `mapstructure:"y"`
Maximised bool `mapstructure:"maximised"`
}
type Config struct {
mu sync.RWMutex
WindowState WindowState `mapstructure:"window_state"`
SavePath string `mapstructure:"save_path"`
}
// 默认窗口配置
var defaultWindowState = WindowState{
Width: 1024,
Height: 768,
X: -1,
Y: -1,
}
func getConfigDir() string {
configPath, err := os.UserConfigDir()
if err != nil {
configPath = "/tmp"
}
return filepath.Join(configPath, "mesh-drop")
}
func getUserHomeDir() string {
home, err := os.UserHomeDir()
if err != nil {
return "/tmp"
}
return home
}
// New 读取配置
func Load() *Config {
configDir := getConfigDir()
err := os.MkdirAll(configDir, 0755)
if err != nil {
slog.Error("Failed to create config directory", "error", err)
}
configFile := filepath.Join(configDir, "config.json")
// 设置默认值
defaultSavePath := filepath.Join(getUserHomeDir(), "Downloads")
viper.SetDefault("window_state", defaultWindowState)
viper.SetDefault("save_path", defaultSavePath)
viper.SetConfigFile(configFile)
viper.SetConfigType("json")
// 尝试读取配置
if err := viper.ReadInConfig(); err != nil {
if _, ok := err.(viper.ConfigFileNotFoundError); ok {
slog.Info("Config file not found, using defaults")
} else {
slog.Warn("Failed to read config file, using defaults", "error", err)
}
}
var config Config
if err := viper.Unmarshal(&config); err != nil {
slog.Error("Failed to unmarshal config", "error", err)
}
return &config
}
// Save 保存配置到磁盘
func (c *Config) Save() error {
c.mu.RLock()
defer c.mu.RUnlock()
configDir := getConfigDir()
if err := os.MkdirAll(configDir, 0755); err != nil {
return err
}
if err := viper.WriteConfig(); err != nil {
slog.Error("Failed to write config", "error", err)
return err
}
return nil
}
// SetSavePath 修改配置
func (c *Config) SetSavePath(savePath string) {
c.mu.Lock()
defer c.mu.Unlock()
c.SavePath = savePath
viper.Set("save_path", savePath)
}
func (c *Config) GetSavePath() string {
c.mu.RLock()
defer c.mu.RUnlock()
return c.SavePath
}

View File

@@ -1,54 +0,0 @@
package config
import (
"encoding/json"
"os"
"path/filepath"
)
// WindowState 定义窗口状态
type WindowState struct {
Width int `json:"width"`
Height int `json:"height"`
X int `json:"x"`
Y int `json:"y"`
Maximised bool `json:"maximised"`
}
// 默认窗口配置
var DefaultWindowState = WindowState{
Width: 1024,
Height: 768,
X: -1, // -1 表示让系统自动决定位置
Y: -1,
}
// GetConfigPath 获取配置文件路径
func GetConfigPath() string {
configDir, _ := os.UserConfigDir()
appDir := filepath.Join(configDir, "mesh-drop")
_ = os.MkdirAll(appDir, 0755)
return filepath.Join(appDir, "window.json")
}
// LoadWindowState 读取配置
func LoadWindowState() WindowState {
path := GetConfigPath()
data, err := os.ReadFile(path)
if err != nil {
return DefaultWindowState
}
var state WindowState
if err := json.Unmarshal(data, &state); err != nil {
return DefaultWindowState
}
return state
}
// SaveWindowState 保存配置
func SaveWindowState(state WindowState) error {
path := GetConfigPath()
data, _ := json.MarshalIndent(state, "", " ")
return os.WriteFile(path, data, 0644)
}

View File

@@ -140,7 +140,7 @@ func (s *Service) handleUpload(c *gin.Context) {
savePath := task.SavePath
if savePath == "" {
savePath = s.savePath
savePath = s.config.GetSavePath()
}
ctxReader := &ContextReader{

View File

@@ -4,6 +4,7 @@ import (
"context"
"fmt"
"log/slog"
"mesh-drop/internal/config"
"mesh-drop/internal/discovery"
"sync"
@@ -12,9 +13,9 @@ import (
)
type Service struct {
app *application.App
port int
savePath string // 默认下载目录
config *config.Config
app *application.App
port int
// pendingRequests 存储等待用户确认的通道
// Key: TransferID, Value: *Transfer
@@ -27,14 +28,14 @@ type Service struct {
cancelMap sync.Map
}
func NewService(app *application.App, port int, defaultSavePath string, discoveryService *discovery.Service) *Service {
func NewService(config *config.Config, app *application.App, port int, discoveryService *discovery.Service) *Service {
gin.SetMode(gin.ReleaseMode)
return &Service{
app: app,
port: port,
savePath: defaultSavePath,
discoveryService: discoveryService,
config: config,
}
}