package handler import ( "encoding/json" "fmt" "log" "net/http" "strconv" "sync" "kfz-goods-pricing/internal/config" "kfz-goods-pricing/internal/repository" ) // ConfigHandler 配置处理器 type ConfigHandler struct { configPath string mu sync.Mutex } // NewConfigHandler 创建配置处理器实例 func NewConfigHandler(configPath string) *ConfigHandler { return &ConfigHandler{ configPath: configPath, } } // GetConfigPrice 获取配置 // 先读 yaml(Port/TimerInterval/APIRateLimit/CallbackURL),再用数据库值覆盖价格字段 func (h *ConfigHandler) GetConfigPrice(w http.ResponseWriter, r *http.Request) { h.mu.Lock() defer h.mu.Unlock() // 1. 加载yaml配置 cfg, err := config.Load(h.configPath) if err != nil { log.Printf("[GetConfigPrice] 读取配置失败: %s", err.Error()) w.Header().Set("Content-Type", "application/json") w.Write([]byte(fmt.Sprintf(`{"code":500,"message":"读取配置失败: %s"}`, err.Error()))) return } // 2. 查询 kfz_config 数据库,有数据则覆盖对应字段 dbCfg, err := repository.GetKfzConfig() if err != nil { log.Printf("[GetConfigPrice] 查询kfz_config失败: %s", err.Error()) // 查询出错不影响返回yaml配置,继续执行 } else if dbCfg != nil { cfg.NewPrice = dbCfg.NewPrice cfg.PlaceholderDownPrice = dbCfg.PlaceholderDownPrice cfg.MinShippingFee = dbCfg.MinShippingFee cfg.MinPrice = dbCfg.MinPrice cfg.QueryIndex = dbCfg.QueryIndex } // 同步全局配置 config.SetGlobal(cfg) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]interface{}{ "code": 200, "message": "success", "data": cfg, }) } // SetConfigPrice 修改价格配置 // 保存到 kfz_config 表,永远只有 ID=1 一条记录 // 入参中只传需要修改的字段,未传的字段保持数据库原值不变 func (h *ConfigHandler) SetConfigPrice(w http.ResponseWriter, r *http.Request) { r.ParseMultipartForm(32 << 20) h.mu.Lock() defer h.mu.Unlock() // 1. 获取现有配置(无数据则为空结构体) dbCfg, err := repository.GetKfzConfig() if err != nil { log.Printf("[SetConfigPrice] 查询kfz_config失败: %s", err.Error()) w.Header().Set("Content-Type", "application/json") w.Write([]byte(fmt.Sprintf(`{"code":500,"message":"查询配置失败: %s"}`, err.Error()))) return } if dbCfg == nil { dbCfg = &repository.KfzConfig{} } // 2. 只更新入参中提供的字段 if len(r.PostForm["new_price"]) > 0 { dbCfg.NewPrice, _ = strconv.ParseFloat(r.PostForm.Get("new_price"), 64) } if len(r.PostForm["placeholder_down_price"]) > 0 { dbCfg.PlaceholderDownPrice, _ = strconv.ParseFloat(r.PostForm.Get("placeholder_down_price"), 64) } if len(r.PostForm["min_shipping_fee"]) > 0 { dbCfg.MinShippingFee, _ = strconv.ParseFloat(r.PostForm.Get("min_shipping_fee"), 64) } if len(r.PostForm["min_price"]) > 0 { dbCfg.MinPrice, _ = strconv.ParseFloat(r.PostForm.Get("min_price"), 64) } if len(r.PostForm["query_index"]) > 0 { dbCfg.QueryIndex, _ = strconv.Atoi(r.PostForm.Get("query_index")) } // 3. 保存 if err := repository.SaveKfzConfig(dbCfg); err != nil { log.Printf("[SetConfigPrice] 保存kfz_config失败: %s", err.Error()) w.Header().Set("Content-Type", "application/json") w.Write([]byte(fmt.Sprintf(`{"code":500,"message":"保存配置失败: %s"}`, err.Error()))) return } log.Printf("[SetConfigPrice] 配置保存成功: new_price=%.2f, placeholder_down_price=%.2f, min_shipping_fee=%.2f, min_price=%.2f, query_index=%d", dbCfg.NewPrice, dbCfg.PlaceholderDownPrice, dbCfg.MinShippingFee, dbCfg.MinPrice, dbCfg.QueryIndex) w.Header().Set("Content-Type", "application/json") json.NewEncoder(w).Encode(map[string]interface{}{ "code": 200, "message": "success", }) }