package handlers import ( "awesomeProject/internal/common" "awesomeProject/internal/config" "awesomeProject/internal/events" "awesomeProject/internal/models" "net/http" "strconv" "time" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // AdminConfigHandler 管理端系统配置处理器 type AdminConfigHandler struct{} // GetSystemConfigs 获取系统配置列表 func (h *AdminConfigHandler) GetSystemConfigs(c *gin.Context) { currentUser, _ := c.Get("current_user") user := currentUser.(models.User) // 只有管理员可以查看系统配置 if user.SystemRole != 0 { c.JSON(http.StatusOK, common.Error(403, "权限不足")) return } // 分页参数 page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) pageSize, _ := strconv.Atoi(c.DefaultQuery("page_size", "10")) if page < 1 { page = 1 } if pageSize < 1 || pageSize > 100 { pageSize = 10 } // 搜索参数 configKey := c.Query("config_key") configType := c.Query("config_type") isSystem := c.Query("is_system") db := common.GetDB() var configs []models.SystemConfig var total int64 // 构建查询条件 query := db.Model(&models.SystemConfig{}) // 添加搜索条件 if configKey != "" { query = query.Where("config_key LIKE ?", "%"+configKey+"%") } if configType != "" { query = query.Where("config_type = ?", configType) } if isSystem != "" { query = query.Where("is_system = ?", isSystem) } // 获取总数 query.Count(&total) // 分页查询 offset := (page - 1) * pageSize err := query.Offset(offset).Limit(pageSize).Order("is_system DESC, created_at DESC").Find(&configs).Error if err != nil { c.JSON(http.StatusOK, common.Error(500, "查询系统配置失败")) return } // 构建返回数据 result := map[string]interface{}{ "list": configs, "total": total, "page": page, "page_size": pageSize, } c.JSON(http.StatusOK, common.Success(result)) } // GetSystemConfig 获取单个系统配置 func (h *AdminConfigHandler) GetSystemConfig(c *gin.Context) { currentUser, _ := c.Get("current_user") user := currentUser.(models.User) // 只有管理员可以查看系统配置 if user.SystemRole != 0 { c.JSON(http.StatusOK, common.Error(403, "权限不足")) return } configID, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { c.JSON(http.StatusOK, common.Error(400, "配置ID无效")) return } var config models.SystemConfig err = common.GetDB().First(&config, uint(configID)).Error if err != nil { if err == gorm.ErrRecordNotFound { c.JSON(http.StatusOK, common.Error(404, "系统配置不存在")) } else { c.JSON(http.StatusOK, common.Error(500, "查询系统配置失败")) } return } c.JSON(http.StatusOK, common.Success(config)) } // CreateSystemConfig 创建系统配置 func (h *AdminConfigHandler) CreateSystemConfig(c *gin.Context) { currentUser, _ := c.Get("current_user") user := currentUser.(models.User) // 只有管理员可以创建系统配置 if user.SystemRole != 0 { c.JSON(http.StatusOK, common.Error(403, "权限不足")) return } var newConfig models.SystemConfig if err := c.ShouldBindJSON(&newConfig); err != nil { c.JSON(http.StatusOK, common.Error(400, "参数错误: "+err.Error())) return } // 检查配置键是否已存在 var existConfig models.SystemConfig if err := common.GetDB().Where("config_key = ?", newConfig.ConfigKey).First(&existConfig).Error; err == nil { c.JSON(http.StatusOK, common.Error(400, "配置键已存在")) return } // 保存配置 if err := common.GetDB().Create(&newConfig).Error; err != nil { c.JSON(http.StatusOK, common.Error(500, "创建系统配置失败")) return } c.JSON(http.StatusOK, common.Success(newConfig)) } // UpdateSystemConfig 更新系统配置 func (h *AdminConfigHandler) UpdateSystemConfig(c *gin.Context) { currentUser, _ := c.Get("current_user") user := currentUser.(models.User) // 只有管理员可以更新系统配置 if user.SystemRole != 0 { c.JSON(http.StatusOK, common.Error(403, "权限不足")) return } configID, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { c.JSON(http.StatusOK, common.Error(400, "配置ID无效")) return } var updateData models.SystemConfig if err := c.ShouldBindJSON(&updateData); err != nil { c.JSON(http.StatusOK, common.Error(400, "参数错误: "+err.Error())) return } // 检查配置是否存在 var existConfig models.SystemConfig if err := common.GetDB().First(&existConfig, uint(configID)).Error; err != nil { c.JSON(http.StatusOK, common.Error(404, "系统配置不存在")) return } // 如果是系统配置,不允许修改配置键 if existConfig.IsSystem == 1 && updateData.ConfigKey != existConfig.ConfigKey { c.JSON(http.StatusOK, common.Error(400, "系统配置不允许修改配置键")) return } // 如果修改了配置键,检查是否已存在 if updateData.ConfigKey != existConfig.ConfigKey { var duplicateConfig models.SystemConfig if err := common.GetDB().Where("config_key = ? AND id != ?", updateData.ConfigKey, configID).First(&duplicateConfig).Error; err == nil { c.JSON(http.StatusOK, common.Error(400, "配置键已存在")) return } } // 记录旧值,用于事件触发 oldValue := existConfig.ConfigValue // 更新配置信息 updateData.ID = uint(configID) if err := common.GetDB().Model(&existConfig).Updates(&updateData).Error; err != nil { c.JSON(http.StatusOK, common.Error(500, "更新系统配置失败")) return } // 返回更新后的配置信息 var updatedConfig models.SystemConfig common.GetDB().First(&updatedConfig, uint(configID)) // 如果配置值发生变化,触发配置变更事件 if oldValue != updatedConfig.ConfigValue { configEvent := config.ConfigEvent{ ConfigKey: updatedConfig.ConfigKey, OldValue: oldValue, NewValue: updatedConfig.ConfigValue, ChangeType: "update", ChangedBy: user.ID, ChangedAt: time.Now().Unix(), } // 异步触发事件,避免阻塞响应 go func() { events.GetConfigEventManager().TriggerEvent(configEvent) }() // 记录配置变更日志(可选) go h.logConfigChange(configEvent) } c.JSON(http.StatusOK, common.Success(updatedConfig)) } // DeleteSystemConfig 删除系统配置 func (h *AdminConfigHandler) DeleteSystemConfig(c *gin.Context) { currentUser, _ := c.Get("current_user") user := currentUser.(models.User) // 只有管理员可以删除系统配置 if user.SystemRole != 0 { c.JSON(http.StatusOK, common.Error(403, "权限不足")) return } configID, err := strconv.ParseUint(c.Param("id"), 10, 32) if err != nil { c.JSON(http.StatusOK, common.Error(400, "配置ID无效")) return } // 检查配置是否存在 var existConfig models.SystemConfig if err := common.GetDB().First(&existConfig, uint(configID)).Error; err != nil { c.JSON(http.StatusOK, common.Error(404, "系统配置不存在")) return } // 系统配置不允许删除 if existConfig.IsSystem == 1 { c.JSON(http.StatusOK, common.Error(400, "系统配置不允许删除")) return } // 删除配置 if err := common.GetDB().Delete(&existConfig).Error; err != nil { c.JSON(http.StatusOK, common.Error(500, "删除系统配置失败")) return } c.JSON(http.StatusOK, common.Success(nil)) } // GetConfigByKey 根据配置键获取配置值(公共方法) func (h *AdminConfigHandler) GetConfigByKey(c *gin.Context) { configKey := c.Param("key") if configKey == "" { c.JSON(http.StatusOK, common.Error(400, "配置键不能为空")) return } var config models.SystemConfig err := common.GetDB().Where("config_key = ?", configKey).First(&config).Error if err != nil { if err == gorm.ErrRecordNotFound { c.JSON(http.StatusOK, common.Error(404, "配置不存在")) } else { c.JSON(http.StatusOK, common.Error(500, "查询配置失败")) } return } c.JSON(http.StatusOK, common.Success(config)) } // InitSystemConfigs 初始化系统配置 func (h *AdminConfigHandler) InitSystemConfigs() error { db := common.GetDB() // 检查是否已有系统配置 var count int64 db.Model(&models.SystemConfig{}).Where("is_system = 1").Count(&count) if count > 0 { return nil // 已有系统配置,不重复创建 } // 创建默认系统配置 defaultConfigs := []models.SystemConfig{ { ConfigKey: "warehouse_price_rate", ConfigValue: "1.10", ConfigName: "入库价格增值率", ConfigDescription: "商品进入用户仓库时的价格增值比例", ConfigType: "number", IsSystem: 1, }, { ConfigKey: "shipping_fee_rate", ConfigValue: "0.05", ConfigName: "运费比例", ConfigDescription: "基于商品价格计算的运费比例", ConfigType: "number", IsSystem: 1, }, { ConfigKey: "platform_commission_rate", ConfigValue: "0.03", ConfigName: "平台佣金比例", ConfigDescription: "平台从交易中收取的佣金比例", ConfigType: "number", IsSystem: 1, }, { ConfigKey: "min_withdraw_amount", ConfigValue: "100.00", ConfigName: "最小提现金额", ConfigDescription: "用户最小提现金额限制", ConfigType: "number", IsSystem: 1, }, { ConfigKey: "max_product_images", ConfigValue: "9", ConfigName: "商品最大图片数量", ConfigDescription: "单个商品最多可上传的图片数量", ConfigType: "number", IsSystem: 1, }, } for _, config := range defaultConfigs { if err := db.Create(&config).Error; err != nil { return err } } return nil } // logConfigChange 记录配置变更日志 func (h *AdminConfigHandler) logConfigChange(event config.ConfigEvent) { db := common.GetDB() // 创建配置变更记录 configChange := config.ConfigChange{ ConfigKey: event.ConfigKey, OldValue: convertToString(event.OldValue), NewValue: convertToString(event.NewValue), ChangeType: event.ChangeType, ChangedBy: event.ChangedBy, ChangedAt: event.ChangedAt, Extra: map[string]interface{}{ "ip": "", // 可以从context中获取 "user_agent": "", // 可以从context中获取 }, } // 保存到数据库 if err := db.Create(&configChange).Error; err != nil { // 记录日志失败不应该影响主流程,只记录错误日志 // common.Logger.Printf("记录配置变更日志失败: %v", err) } } // convertToString 将interface{}转换为字符串 func convertToString(value interface{}) string { if value == nil { return "" } if str, ok := value.(string); ok { return str } return "" }