Files
dygou_go/internal/config/config.go
T
yml2213 8790c4ca33 增加设置界面、debug日志等级、版本号展示、构建脚本
- 新增设置弹窗: trace开关/正文上限、日志等级(debug/info/warn/error)、并发数、重试次数
- 配置运行时生效,持久化到 config.json
- 日志系统支持 debug 级别过滤
- 工具栏展示版本号(v0.0.2),来源 wails.json + constants.go
- 抢购并发数和重试次数改为读取配置,不再写死常量
- 新增 build.sh 构建脚本,Windows exe 文件名带版本号
- config.json 加入 .gitignore
2026-06-24 20:18:33 +08:00

174 lines
4.5 KiB
Go

package config
import (
"encoding/json"
"errors"
"os"
"path/filepath"
"runtime"
"strconv"
"douyu_go/internal/constants"
"douyu_go/internal/logger"
"douyu_go/internal/types"
)
// DefaultAppPaths 收集运行时路径,支持环境变量覆盖。
// 所有相对路径会基于当前工作目录解析为绝对路径,避免打包后工作目录不同导致路径错位。
func DefaultAppPaths() types.AppPaths {
return types.AppPaths{
ConfigFile: resolvePath(envOrDefault("DOUYU_CONFIG", constants.DefaultConfigFile)),
AccountFile: resolvePath(envOrDefault("DOUYU_USERS", constants.DefaultAccountFile)),
LogDir: resolvePath(envOrDefault("DOUYU_LOG_DIR", constants.DefaultLogDir)),
SuccessDir: resolvePath(envOrDefault("DOUYU_SUCCESS_DIR", constants.DefaultSuccessDir)),
FontFiles: CollectFontCandidates(),
}
}
// resolvePath 将相对路径解析为绝对路径。
func resolvePath(path string) string {
if filepath.IsAbs(path) {
return path
}
if abs, err := filepath.Abs(path); err == nil {
return abs
}
return path
}
func envOrDefault(key, fallback string) string {
if value := os.Getenv(key); value != "" {
return filepath.Clean(value)
}
return fallback
}
// LoadTraceConfig 读取 trace 开关;默认关闭,避免保存敏感调试数据。
func LoadTraceConfig() types.TraceConfig {
return types.TraceConfig{
Enabled: isTruthyEnv("DOUYU_TRACE"),
MaxBodyBytes: envInt("DOUYU_TRACE_MAX_BODY", 0),
}
}
func isTruthyEnv(key string) bool {
switch os.Getenv(key) {
case "1", "true", "TRUE", "yes", "YES", "on", "ON":
return true
default:
return false
}
}
func envInt(key string, fallback int) int {
raw := os.Getenv(key)
if raw == "" {
return fallback
}
value, err := strconv.Atoi(raw)
if err != nil || value <= 0 {
return fallback
}
return value
}
// defaultConfig 返回内置默认配置。
func defaultConfig() types.Config {
return types.Config{
TimeAPIURL: constants.DefaultTimeAPI,
TraceEnabled: false,
TraceMaxBody: 0,
LogLevel: "info",
Concurrency: constants.DefaultConcurrency,
Attempts: constants.DefaultAttempts,
}
}
// LoadConfig 读取配置文件;缺失时安静使用内置默认配置。
func LoadConfig(path string) types.Config {
cfg := defaultConfig()
if path == "" {
path = constants.DefaultConfigFile
}
f, err := os.Open(path)
if err != nil {
if errors.Is(err, os.ErrNotExist) {
logger.LogEvent("配置", "info", "配置加载完成: 内置默认配置")
} else {
logger.LogEvent("配置", "warn", "读取 %s 出错,使用内置默认配置: %v", path, err)
}
return cfg
}
defer f.Close()
if err := json.NewDecoder(f).Decode(&cfg); err != nil {
logger.LogEvent("配置", "warn", "解析 %s 失败,使用内置默认配置: %v", path, err)
return defaultConfig()
}
if cfg.TimeAPIURL == "" {
cfg.TimeAPIURL = constants.DefaultTimeAPI
}
if cfg.Concurrency <= 0 {
cfg.Concurrency = constants.DefaultConcurrency
}
if cfg.Attempts <= 0 {
cfg.Attempts = constants.DefaultAttempts
}
if cfg.LogLevel == "" {
cfg.LogLevel = "info"
}
logger.LogEvent("配置", "success", "配置加载完成: %s", path)
return cfg
}
// SaveConfig 将配置写入文件。
func SaveConfig(path string, cfg types.Config) error {
if path == "" {
path = constants.DefaultConfigFile
}
data, err := json.MarshalIndent(cfg, "", " ")
if err != nil {
return err
}
return os.WriteFile(path, data, 0644)
}
// CollectFontCandidates 收集常见中文字体路径,允许用 DOUYU_FONT 指定自定义字体。
func CollectFontCandidates() []string {
candidates := []string{}
if custom := os.Getenv("DOUYU_FONT"); custom != "" {
candidates = append(candidates, custom)
}
candidates = append(candidates,
"Microsoft Yahei.ttf",
"Microsoft YaHei.ttf",
"NotoSansCJKsc-Regular.otf",
"NotoSansCJK-Regular.ttc",
)
switch runtime.GOOS {
case "darwin":
candidates = append(candidates,
"/System/Library/Fonts/PingFang.ttc",
"/System/Library/Fonts/Supplemental/Arial Unicode.ttf",
"/System/Library/Fonts/Supplemental/Songti.ttc",
)
case "windows":
candidates = append(candidates,
`C:\Windows\Fonts\msyh.ttc`,
`C:\Windows\Fonts\simhei.ttf`,
`C:\Windows\Fonts\simsun.ttc`,
)
default:
candidates = append(candidates,
"/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc",
"/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.otf",
"/usr/share/fonts/truetype/noto/NotoSansCJK-Regular.ttc",
"/usr/share/fonts/truetype/wqy/wqy-microhei.ttc",
"/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
)
}
return candidates
}