package config import ( "fmt" "github.com/spf13/viper" ) // GlobalConfig 全局配置实例 var GlobalConfig Config type Config struct { App AppConfig `mapstructure:"app"` Ingest IngestConfig `mapstructure:"ingest"` Media MediaConfig `mapstructure:"media"` Vision VisionConfig `mapstructure:"vision"` } // VisionConfig 视觉服务(FashionSigLIP)配置,供 `spider embed` 回填向量使用。 type VisionConfig struct { Endpoint string `mapstructure:"endpoint"` // 如 http://127.0.0.1:8900 Concurrency int `mapstructure:"concurrency"` // 下载并发,默认 4 } // MediaConfig 媒体机直传配置(把下载/上传从后端搬到 spider 所在机器)。 // // 打开后 spider 会:下载图片 → 内容 sha1 生成 key → 向后端申请预签名 PUT 地址 // → 直接传到对象存储 → 上报时只带 key。后端 worker 则跳过下载与上传,只写库。 // 关闭时行为与旧版完全一致(上报 URL,由后端下载)。 type MediaConfig struct { Upload bool `mapstructure:"upload"` // 是否启用直传 Concurrency int `mapstructure:"concurrency"` // 下载/上传并发,默认 6 } // IngestConfig 入库管线配置:爬虫 → 后台 ingest 接口(HMAC 签名)。 // spider 不直连数据库:品牌任务经 GET /admin/internal/crawl/brands 拉取, // 抓取结果经 POST /admin/internal/ingest 上报,由后台 worker 异步落库。 type IngestConfig struct { Enabled bool `mapstructure:"enabled"` // 是否启用签名上报(替代直写) Endpoint string `mapstructure:"endpoint"` // 后台 ingest 地址,如 http://localhost:8092/admin/internal/ingest Secret string `mapstructure:"secret"` // 必须与后台 INGEST_SECRET 一致 HashIDSecret string `mapstructure:"hashid_secret"` // 必须与后台 HASHID_SECRET 一致(用于编码 brand_uid) } type AppConfig struct { MaxCo int `mapstructure:"max_co"` Debug bool `mapstructure:"debug"` // 新增 Debug 字段 } // InitConfig 初始化并读取 YAML 配置文件 func InitConfig(cfgFile string) error { if cfgFile != "" { // 如果命令行指定了配置文件路径 viper.SetConfigFile(cfgFile) } else { // 默认在当前目录下查找 config.yaml viper.AddConfigPath(".") viper.SetConfigType("yaml") viper.SetConfigName("config") } if err := viper.ReadInConfig(); err != nil { return fmt.Errorf("读取配置文件失败: %w", err) } // 解析到结构体 if err := viper.Unmarshal(&GlobalConfig); err != nil { return fmt.Errorf("解析配置文件结构失败: %w", err) } return nil }