- OPEN_API_DEBUG 记录鉴权、查单、推送业务字段与 req_id - LOG_FILE 默认 logs/app.log,标准日志/Gin/GORM 同时输出控制台与文件
104 lines
2.6 KiB
Go
104 lines
2.6 KiB
Go
package config
|
||
|
||
import (
|
||
"os"
|
||
"path/filepath"
|
||
"strconv"
|
||
"strings"
|
||
|
||
"github.com/joho/godotenv"
|
||
)
|
||
|
||
type Config struct {
|
||
Port string
|
||
JWTSecret string
|
||
DBPath string
|
||
Mode string // debug / release
|
||
// OpenAPIKey 皮肤源头开放接口标识(Header: X-Api-Key,可公开给对接方)
|
||
OpenAPIKey string
|
||
// OpenAPISecret 签名密钥(仅用于 HMAC,不走 Header)
|
||
OpenAPISecret string
|
||
// OpenSignSkew 签名时间戳允许偏差(秒)
|
||
OpenSignSkew int64
|
||
// OpenAPIDebug 开放接口详细调试日志
|
||
OpenAPIDebug bool
|
||
// LogFile 日志文件路径;非空时同时写控制台与文件
|
||
LogFile string
|
||
}
|
||
|
||
// Load 加载配置:先尝试读取 .env,再读系统环境变量(已存在的系统环境变量优先级更高)
|
||
func Load() *Config {
|
||
loadDotEnv()
|
||
mode := getEnv("GIN_MODE", "debug")
|
||
// OPEN_API_DEBUG 优先;未设置时 debug 模式默认开启
|
||
debugOpen := getEnvBool("OPEN_API_DEBUG", mode == "debug" || mode == "")
|
||
return &Config{
|
||
Port: getEnv("PORT", "8080"),
|
||
JWTSecret: getEnv("JWT_SECRET", "affiliate-dash-dev-secret-change-me"),
|
||
DBPath: getEnv("DB_PATH", "data/app.db"),
|
||
Mode: mode,
|
||
OpenAPIKey: getEnv("OPEN_API_KEY", "sk_source_dev_key_change_me"),
|
||
OpenAPISecret: getEnv("OPEN_API_SECRET", "sk_source_dev_secret_change_me"),
|
||
OpenSignSkew: int64(getEnvInt("OPEN_SIGN_SKEW", 300)),
|
||
OpenAPIDebug: debugOpen,
|
||
LogFile: getEnv("LOG_FILE", "logs/app.log"),
|
||
}
|
||
}
|
||
|
||
func getEnvBool(key string, def bool) bool {
|
||
v := os.Getenv(key)
|
||
if v == "" {
|
||
return def
|
||
}
|
||
switch strings.ToLower(strings.TrimSpace(v)) {
|
||
case "1", "true", "yes", "on":
|
||
return true
|
||
case "0", "false", "no", "off":
|
||
return false
|
||
default:
|
||
return def
|
||
}
|
||
}
|
||
|
||
// loadDotEnv 依次尝试常见路径,不覆盖已有环境变量
|
||
func loadDotEnv() {
|
||
var paths []string
|
||
if wd, err := os.Getwd(); err == nil {
|
||
paths = append(paths,
|
||
filepath.Join(wd, ".env"),
|
||
filepath.Join(wd, "..", ".env"), // 在 backend/ 下启动时读仓库根 .env
|
||
filepath.Join(wd, "backend", ".env"), // 在仓库根启动时
|
||
)
|
||
}
|
||
paths = append(paths, ".env")
|
||
|
||
seen := map[string]struct{}{}
|
||
for _, p := range paths {
|
||
abs, err := filepath.Abs(p)
|
||
if err != nil {
|
||
continue
|
||
}
|
||
if _, ok := seen[abs]; ok {
|
||
continue
|
||
}
|
||
seen[abs] = struct{}{}
|
||
_ = godotenv.Load(abs) // 忽略不存在;不覆盖已在环境中的变量
|
||
}
|
||
}
|
||
|
||
func getEnv(key, def string) string {
|
||
if v := os.Getenv(key); v != "" {
|
||
return v
|
||
}
|
||
return def
|
||
}
|
||
|
||
func getEnvInt(key string, def int) int {
|
||
if v := os.Getenv(key); v != "" {
|
||
if n, err := strconv.Atoi(v); err == nil {
|
||
return n
|
||
}
|
||
}
|
||
return def
|
||
}
|