92 lines
2.3 KiB
Go
92 lines
2.3 KiB
Go
package config
|
||
|
||
import (
|
||
"fmt"
|
||
"os"
|
||
"path/filepath"
|
||
|
||
"gopkg.in/yaml.v3"
|
||
)
|
||
|
||
// Config 项目根目录 config/config.{env}.yaml(敏感项已 gitignore)。
|
||
type Config struct {
|
||
Feishu FeishuConfig `yaml:"feishu"`
|
||
HisenseGeo HisenseGeoConfig `yaml:"hisense_geo"`
|
||
}
|
||
|
||
// FeishuConfig 飞书应用凭证。
|
||
type FeishuConfig struct {
|
||
AppID string `yaml:"app_id"`
|
||
AppSecret string `yaml:"app_secret"`
|
||
}
|
||
|
||
// HisenseGeoConfig 海信 GEO 生产环境接口配置。
|
||
type HisenseGeoConfig struct {
|
||
BaseURL string `yaml:"base_url"` // 默认 https://geo-api.hisense.com
|
||
Token string `yaml:"token"` // x-token,勿提交仓库
|
||
}
|
||
|
||
// Load 按 APP_ENV 加载 config 目录下配置,默认 dev。
|
||
// 查找顺序:
|
||
// 1. CONFIG_PATH / FEISHU_CONFIG_PATH
|
||
// 2. 当前工作目录 ./config/config.{env}.yaml
|
||
// 3. 向上查找含 config/ 目录的项目根下的 config/config.{env}.yaml
|
||
func Load() (*Config, error) {
|
||
env := os.Getenv("APP_ENV")
|
||
if env == "" {
|
||
env = "dev"
|
||
}
|
||
name := "config." + env + ".yaml"
|
||
rel := filepath.Join("config", name)
|
||
|
||
candidates := []string{}
|
||
if p := os.Getenv("CONFIG_PATH"); p != "" {
|
||
candidates = append(candidates, p)
|
||
}
|
||
if p := os.Getenv("FEISHU_CONFIG_PATH"); p != "" {
|
||
candidates = append(candidates, p)
|
||
}
|
||
candidates = append(candidates, rel)
|
||
if root := FindProjectRoot(); root != "" {
|
||
candidates = append(candidates, filepath.Join(root, rel))
|
||
}
|
||
|
||
var lastErr error
|
||
for _, path := range candidates {
|
||
data, err := os.ReadFile(path)
|
||
if err != nil {
|
||
lastErr = err
|
||
continue
|
||
}
|
||
var cfg Config
|
||
if err := yaml.Unmarshal(data, &cfg); err != nil {
|
||
return nil, fmt.Errorf("解析配置失败 (%s): %w", path, err)
|
||
}
|
||
if cfg.HisenseGeo.BaseURL == "" {
|
||
cfg.HisenseGeo.BaseURL = "https://geo-api.hisense.com"
|
||
}
|
||
return &cfg, nil
|
||
}
|
||
return nil, fmt.Errorf("未找到配置文件 %s(放在 config/ 目录,或设置 CONFIG_PATH): %w", rel, lastErr)
|
||
}
|
||
|
||
// FindProjectRoot 向上查找包含 config/ 目录的项目根。
|
||
func FindProjectRoot() string {
|
||
wd, err := os.Getwd()
|
||
if err != nil {
|
||
return ""
|
||
}
|
||
dir := wd
|
||
for {
|
||
cfgDir := filepath.Join(dir, "config")
|
||
if st, err := os.Stat(cfgDir); err == nil && st.IsDir() {
|
||
return dir
|
||
}
|
||
parent := filepath.Dir(dir)
|
||
if parent == dir {
|
||
return ""
|
||
}
|
||
dir = parent
|
||
}
|
||
}
|