2025-11-19 17:34:42 +08:00

151 lines
3.8 KiB
Go

package config
import (
"fmt"
"log"
"os"
"path/filepath"
legacy "weatherstation/internal/config"
"gopkg.in/yaml.v3"
)
type Config struct {
Addr string
UIServeDir string
BigscreenDir string
TemplateDir string
StaticDir string
DevEnableCORS bool
Legacy *legacy.Config
SMS SmsConfig
AuthSecret string
}
// SmsConfig holds Aliyun SMS settings loaded from config/env.
type SmsConfig struct {
AccessKeyID string
AccessKeySecret string
SignName string
TemplateCode string
Endpoint string // optional, default dysmsapi.aliyuncs.com
}
func Load() Config {
lg := legacy.GetConfig()
port := lg.Server.WebPort
if port <= 0 {
port = 8080
}
cfg := Config{
Addr: fmt.Sprintf(":%d", port),
UIServeDir: "core/frontend/dist/ui",
BigscreenDir: "core/frontend/dist/bigscreen",
TemplateDir: "templates",
StaticDir: "static",
DevEnableCORS: true,
Legacy: lg,
SMS: SmsConfig{},
AuthSecret: "change-me-dev", // default dev secret; override with CORE_AUTH_SECRET
}
// Try load SMS from YAML (same search order as legacy)
type smsAliyun struct {
AccessKeyID string `yaml:"access_key_id"`
AccessKeySecret string `yaml:"access_key_secret"`
SignName string `yaml:"sign_name"`
TemplateCode string `yaml:"template_code"`
Endpoint string `yaml:"endpoint"`
}
var smsFile struct {
SMS struct {
Enabled bool `yaml:"enabled"`
Provider string `yaml:"provider"`
Aliyun smsAliyun `yaml:"aliyun"`
} `yaml:"sms"`
}
// Probe possible locations
exePath, _ := os.Executable()
exeDir := ""
if exePath != "" {
exeDir = filepath.Dir(exePath)
}
candidates := []string{
filepath.Join(exeDir, "config.yaml"),
filepath.Join(exeDir, "..", "config.yaml"),
"config.yaml",
"../config.yaml",
"../../config.yaml",
"/etc/weatherstation/config.yaml",
filepath.Join(os.Getenv("HOME"), ".weatherstation", "config.yaml"),
}
for _, p := range candidates {
if b, err := os.ReadFile(p); err == nil {
if err := yaml.Unmarshal(b, &smsFile); err == nil {
cfg.SMS.AccessKeyID = smsFile.SMS.Aliyun.AccessKeyID
cfg.SMS.AccessKeySecret = smsFile.SMS.Aliyun.AccessKeySecret
if v := smsFile.SMS.Aliyun.SignName; v != "" {
cfg.SMS.SignName = v
}
if v := smsFile.SMS.Aliyun.TemplateCode; v != "" {
cfg.SMS.TemplateCode = v
}
if v := smsFile.SMS.Aliyun.Endpoint; v != "" {
cfg.SMS.Endpoint = v
}
}
break
}
}
if v := os.Getenv("CORE_ADDR"); v != "" {
cfg.Addr = v
}
if v := os.Getenv("CORE_UI_DIR"); v != "" {
cfg.UIServeDir = v
}
if v := os.Getenv("CORE_BIGSCREEN_DIR"); v != "" {
cfg.BigscreenDir = v
}
if v := os.Getenv("CORE_TEMPLATE_DIR"); v != "" {
cfg.TemplateDir = v
}
if v := os.Getenv("CORE_STATIC_DIR"); v != "" {
cfg.StaticDir = v
}
if v := os.Getenv("CORE_ENABLE_CORS"); v != "" {
if v == "0" || v == "false" {
cfg.DevEnableCORS = false
} else {
cfg.DevEnableCORS = true
}
}
// Auth secret; do not log value
if v := os.Getenv("CORE_AUTH_SECRET"); v != "" {
cfg.AuthSecret = v
}
// SMS settings (do not log secrets)
if v := os.Getenv("CORE_SMS_AK"); v != "" {
cfg.SMS.AccessKeyID = v
}
if v := os.Getenv("CORE_SMS_SK"); v != "" {
cfg.SMS.AccessKeySecret = v
}
if v := os.Getenv("CORE_SMS_SIGN"); v != "" {
cfg.SMS.SignName = v
}
if v := os.Getenv("CORE_SMS_TPL"); v != "" {
cfg.SMS.TemplateCode = v
}
if v := os.Getenv("CORE_SMS_ENDPOINT"); v != "" {
cfg.SMS.Endpoint = v
}
log.Printf("config: addr=%s ui=%s bigscreen=%s tpl=%s static=%s cors=%v sms.sign=%v sms.tpl=%v auth.secret=%v", cfg.Addr, cfg.UIServeDir, cfg.BigscreenDir, cfg.TemplateDir, cfg.StaticDir, cfg.DevEnableCORS, cfg.SMS.SignName != "", cfg.SMS.TemplateCode != "", cfg.AuthSecret != "")
return cfg
}