Files
jiu/backend/config/config.go
T
wangjia 655c1d366e feat: 公开商品页重设计 + web 上传修复 + 二维码配置
- 公开商品页(/product/:uuid)全面重设计:全宽正方形图片轮播、
  左右滑动切图、点击放大全屏查看、商品参数含描述、页脚贴底
- 修复 Flutter web 文件上传无反应(path→bytes)
- 修复 web 路由空白页(usePathUrlStrategy + 单层 MaterialApp.router)
- 二维码 URL 改为从 STORAGE_PUBLIC_URL 环境变量读取
- 新增 PUBLIC_URL dart-define → AppConfig.publicBaseUrl
- 新增 CI/CD workflows + NAS runner compose 配置
- seed S001 补充商品描述字段

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-30 00:31:11 +08:00

82 lines
2.4 KiB
Go

package config
import (
"log"
"strings"
"github.com/spf13/viper"
)
type Config struct {
Server ServerConfig
Database DatabaseConfig
JWT JWTConfig
License LicenseConfig
Storage StorageConfig
}
type ServerConfig struct {
Port string `mapstructure:"port"`
Mode string `mapstructure:"mode"` // debug | release
CORSOrigin string `mapstructure:"cors_origin"` // 允许的 CORS 来源,生产设为具体域名
}
type DatabaseConfig struct {
DSN string `mapstructure:"dsn"`
}
type JWTConfig struct {
Secret string `mapstructure:"secret"`
AccessExpireMin int `mapstructure:"access_expire_min"` // Access Token 有效分钟数
RefreshExpireH int `mapstructure:"refresh_expire_h"` // Refresh Token 有效小时数
}
type LicenseConfig struct {
HMACSecret string `mapstructure:"hmac_secret"` // 许可证签名密钥
}
type StorageConfig struct {
UploadDir string `mapstructure:"upload_dir"`
BaseURL string `mapstructure:"base_url"`
PublicURL string `mapstructure:"public_url"` // 商品公开页基础 URL,用于生成二维码
}
var C Config
func Load() {
viper.SetConfigName("config")
viper.SetConfigType("yaml")
viper.AddConfigPath(".")
viper.AddConfigPath("./config")
// 环境变量覆盖(生产部署时使用)
viper.SetEnvKeyReplacer(strings.NewReplacer(".", "_"))
viper.AutomaticEnv()
// 显式绑定没有默认值的 key,确保 AutomaticEnv 能找到对应 env var
_ = viper.BindEnv("database.dsn", "DATABASE_DSN")
_ = viper.BindEnv("jwt.secret", "JWT_SECRET")
_ = viper.BindEnv("license.hmac_secret", "LICENSE_HMAC_SECRET")
_ = viper.BindEnv("storage.upload_dir", "STORAGE_UPLOAD_DIR")
_ = viper.BindEnv("storage.base_url", "STORAGE_BASE_URL")
_ = viper.BindEnv("storage.public_url", "STORAGE_PUBLIC_URL")
// 默认值
viper.SetDefault("server.port", "8080")
viper.SetDefault("server.mode", "debug")
viper.SetDefault("server.cors_origin", "*")
viper.SetDefault("jwt.access_expire_min", 60)
viper.SetDefault("jwt.refresh_expire_h", 168) // 7天
viper.SetDefault("storage.upload_dir", "./uploads/images")
viper.SetDefault("storage.base_url", "http://localhost:8080/images")
viper.SetDefault("storage.public_url", "http://localhost:8081")
if err := viper.ReadInConfig(); err != nil {
log.Println("[config] no config file found, using defaults and env vars")
}
if err := viper.Unmarshal(&C); err != nil {
log.Fatalf("[config] failed to unmarshal config: %v", err)
}
}