Initial commit: TaskPool React panel
- React frontend with route-level code splitting - Backend rebranded from Baihu to TaskPool - DB brand migration script and local compatibility
This commit is contained in:
@@ -0,0 +1,226 @@
|
||||
package services
|
||||
|
||||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/engigu/taskpool/internal/constant"
|
||||
"github.com/engigu/taskpool/internal/logger"
|
||||
"github.com/engigu/taskpool/internal/utils"
|
||||
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
type ServerConfig struct {
|
||||
Port int `ini:"port"`
|
||||
Host string `ini:"host"`
|
||||
URLPrefix string `ini:"url_prefix"`
|
||||
PprofEnabled bool `ini:"pprof_enabled"`
|
||||
CookieName string `ini:"cookie_name"`
|
||||
}
|
||||
|
||||
type DatabaseConfig struct {
|
||||
Type string `ini:"type"`
|
||||
Host string `ini:"host"`
|
||||
Port int `ini:"port"`
|
||||
User string `ini:"user"`
|
||||
Password string `ini:"password"`
|
||||
DBName string `ini:"dbname"`
|
||||
Path string `ini:"path"`
|
||||
DSN string `ini:"dsn"`
|
||||
TablePrefix string `ini:"table_prefix"`
|
||||
SSLMode string `ini:"ssl_mode"`
|
||||
}
|
||||
|
||||
type SecurityConfig struct {
|
||||
Secret string `ini:"secret"`
|
||||
}
|
||||
|
||||
type RedisConfig struct {
|
||||
Enabled bool `ini:"enabled"`
|
||||
Host string `ini:"host"`
|
||||
Port int `ini:"port"`
|
||||
Password string `ini:"password"`
|
||||
DB int `ini:"db"`
|
||||
}
|
||||
|
||||
type AppConfig struct {
|
||||
Server ServerConfig `ini:"server"`
|
||||
Database DatabaseConfig `ini:"database"`
|
||||
Security SecurityConfig `ini:"security"`
|
||||
Redis RedisConfig `ini:"redis"`
|
||||
}
|
||||
|
||||
var Config *AppConfig
|
||||
|
||||
// getEnvStr 获取环境变量字符串
|
||||
func getEnvStr(key string, target *string) {
|
||||
if v := os.Getenv(key); v != "" {
|
||||
*target = v
|
||||
_ = os.Unsetenv(key)
|
||||
}
|
||||
}
|
||||
|
||||
// getEnvBool 获取环境变量布尔值
|
||||
func getEnvBool(key string, target *bool) {
|
||||
if v := os.Getenv(key); v != "" {
|
||||
if b, err := strconv.ParseBool(v); err == nil {
|
||||
*target = b
|
||||
}
|
||||
_ = os.Unsetenv(key)
|
||||
}
|
||||
}
|
||||
|
||||
// getEnvInt 获取环境变量整数
|
||||
func getEnvInt(key string, target *int) {
|
||||
if v := os.Getenv(key); v != "" {
|
||||
if n, err := strconv.Atoi(v); err == nil {
|
||||
*target = n
|
||||
}
|
||||
_ = os.Unsetenv(key)
|
||||
}
|
||||
}
|
||||
|
||||
func LoadConfig(path string) (*AppConfig, error) {
|
||||
// 路径发现逻辑:参数优先 -> 环境变量优先 -> 默认常量
|
||||
if path == "" {
|
||||
if envPath := os.Getenv("BH_CONFIG_PATH"); envPath != "" {
|
||||
path = envPath
|
||||
} else {
|
||||
path = constant.ConfigPath
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化默认配置
|
||||
Config = &AppConfig{
|
||||
Server: ServerConfig{
|
||||
Port: 8052,
|
||||
Host: "0.0.0.0",
|
||||
PprofEnabled: false,
|
||||
CookieName: "BHToken",
|
||||
},
|
||||
Database: DatabaseConfig{
|
||||
Type: "sqlite",
|
||||
Host: "localhost",
|
||||
Port: 3306,
|
||||
User: "root",
|
||||
Password: "",
|
||||
DBName: "taskpool",
|
||||
Path: constant.DefaultDBPath,
|
||||
TablePrefix: "taskpool_",
|
||||
},
|
||||
Security: SecurityConfig{
|
||||
Secret: "",
|
||||
},
|
||||
}
|
||||
|
||||
// 检查配置文件是否存在
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
// 配置文件存在,从文件加载
|
||||
logger.Infof("[Config] 从文件加载配置: %s", path)
|
||||
cfg, err := ini.Load(path)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := cfg.MapTo(Config); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
} else {
|
||||
// 配置文件不存在,使用环境变量
|
||||
logger.Info("[Config] 配置文件不存在,从环境变量加载")
|
||||
applyEnvOverrides()
|
||||
}
|
||||
|
||||
// 设置默认数据库路径
|
||||
if Config.Database.Path == "" {
|
||||
Config.Database.Path = constant.DefaultDBPath
|
||||
}
|
||||
// sqlite:新路径不存在时,回退旧版 data/baihu.db,避免升级后丢库
|
||||
if Config.Database.Type == "sqlite" || Config.Database.Type == "" {
|
||||
if _, err := os.Stat(Config.Database.Path); err != nil {
|
||||
legacy := strings.ReplaceAll(Config.Database.Path, "taskpool.db", "baihu.db")
|
||||
if legacy == Config.Database.Path {
|
||||
legacy = filepath.Join(constant.DataDir, "baihu.db")
|
||||
}
|
||||
if _, err2 := os.Stat(legacy); err2 == nil {
|
||||
logger.Infof("[Config] 使用旧版数据库文件: %s", legacy)
|
||||
Config.Database.Path = legacy
|
||||
}
|
||||
}
|
||||
}
|
||||
// 表前缀:若仍是默认 taskpool_ 且配置文件未显式迁移,保留兼容旧库 baihu_
|
||||
if Config.Database.TablePrefix == "" {
|
||||
Config.Database.TablePrefix = "taskpool_"
|
||||
}
|
||||
|
||||
// 设置配置到 constant 包
|
||||
if Config.Server.CookieName != "" {
|
||||
constant.CookieName = Config.Server.CookieName
|
||||
}
|
||||
constant.TablePrefix = Config.Database.TablePrefix
|
||||
constant.RuntimeDBType = Config.Database.Type
|
||||
constant.RuntimeDBHost = Config.Database.Host
|
||||
constant.RuntimeDBPort = Config.Database.Port
|
||||
constant.RuntimeDBUser = Config.Database.User
|
||||
constant.RuntimeDBPassword = Config.Database.Password
|
||||
constant.RuntimeDBName = Config.Database.DBName
|
||||
constant.RuntimeDBPath = Config.Database.Path
|
||||
constant.RuntimeDBDSN = Config.Database.DSN
|
||||
constant.RuntimeDBTablePrefix = Config.Database.TablePrefix
|
||||
constant.RuntimeDBSSLMode = Config.Database.SSLMode
|
||||
|
||||
// 暂存旧的 Secret,不再直接给 constant 赋值(改为到 settings 初始化时判断)
|
||||
// constant.Secret = Config.Security.Secret
|
||||
|
||||
// 设置演示模式
|
||||
if v := os.Getenv("BH_DEMO_MODE"); v == "true" || v == "1" {
|
||||
constant.DemoMode = true
|
||||
logger.Info("[Config] 演示模式已启用")
|
||||
_ = os.Unsetenv("BH_DEMO_MODE")
|
||||
}
|
||||
|
||||
// 输出配置信息(隐藏敏感信息)
|
||||
logger.Infof("[Config] 服务地址: %s:%d", Config.Server.Host, Config.Server.Port)
|
||||
if Config.Server.URLPrefix != "" {
|
||||
logger.Infof("[Config] URL前缀: %s", Config.Server.URLPrefix)
|
||||
}
|
||||
|
||||
maskedHost := utils.MaskString(Config.Database.Host)
|
||||
maskedDBName := utils.MaskString(Config.Database.DBName)
|
||||
logger.Infof("[Config] 数据库: type=%s, host=%s, port=%d, dbname=%s, dsn=%v",
|
||||
Config.Database.Type, maskedHost, Config.Database.Port, maskedDBName, Config.Database.DSN != "")
|
||||
|
||||
return Config, nil
|
||||
}
|
||||
|
||||
// applyEnvOverrides 从环境变量加载配置
|
||||
func applyEnvOverrides() {
|
||||
// Server
|
||||
getEnvInt("BH_SERVER_PORT", &Config.Server.Port)
|
||||
getEnvStr("BH_SERVER_HOST", &Config.Server.Host)
|
||||
getEnvStr("BH_SERVER_URL_PREFIX", &Config.Server.URLPrefix)
|
||||
getEnvBool("BH_SERVER_PPROF", &Config.Server.PprofEnabled)
|
||||
getEnvStr("BH_COOKIE_NAME", &Config.Server.CookieName)
|
||||
|
||||
// Database
|
||||
getEnvStr("BH_DB_TYPE", &Config.Database.Type)
|
||||
getEnvStr("BH_DB_HOST", &Config.Database.Host)
|
||||
getEnvInt("BH_DB_PORT", &Config.Database.Port)
|
||||
getEnvStr("BH_DB_USER", &Config.Database.User)
|
||||
getEnvStr("BH_DB_PASSWORD", &Config.Database.Password)
|
||||
getEnvStr("BH_DB_NAME", &Config.Database.DBName)
|
||||
getEnvStr("BH_DB_PATH", &Config.Database.Path)
|
||||
getEnvStr("BH_DB_DSN", &Config.Database.DSN)
|
||||
getEnvStr("BH_DB_TABLE_PREFIX", &Config.Database.TablePrefix)
|
||||
getEnvStr("BH_DB_SSL_MODE", &Config.Database.SSLMode)
|
||||
|
||||
// Security
|
||||
getEnvStr("BH_SECRET", &Config.Security.Secret)
|
||||
|
||||
}
|
||||
|
||||
func GetConfig() *AppConfig {
|
||||
return Config
|
||||
}
|
||||
Reference in New Issue
Block a user