package handlers import ( "net/http" "strconv" "sale/internal/models" "sale/internal/utils" "github.com/gin-gonic/gin" ) type PaymentChannelHandler struct{} func NewPaymentChannelHandler() *PaymentChannelHandler { return &PaymentChannelHandler{} } func (h *PaymentChannelHandler) PublicList(c *gin.Context) { var channels []models.PaymentChannel utils.DB.Where("is_enabled = ?", true).Order("sort_order ASC, id ASC").Find(&channels) type publicChannel struct { ID uint `json:"id"` Name string `json:"name"` Code string `json:"code"` Type string `json:"type"` Icon string `json:"icon"` FeeRate float64 `json:"fee_rate"` MinAmount float64 `json:"min_amount"` MaxAmount float64 `json:"max_amount"` SortOrder int `json:"sort_order"` } var result []publicChannel for _, ch := range channels { result = append(result, publicChannel{ ID: ch.ID, Name: ch.Name, Code: ch.Code, Type: ch.Type, Icon: ch.Icon, FeeRate: ch.FeeRate, MinAmount: ch.MinAmount, MaxAmount: ch.MaxAmount, SortOrder: ch.SortOrder, }) } c.JSON(http.StatusOK, gin.H{"data": result}) } func (h *PaymentChannelHandler) List(c *gin.Context) { var channels []models.PaymentChannel utils.DB.Order("sort_order ASC, id ASC").Find(&channels) c.JSON(http.StatusOK, gin.H{"data": channels}) } func (h *PaymentChannelHandler) GetByID(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var channel models.PaymentChannel if err := utils.DB.First(&channel, id).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Payment channel not found"}) return } c.JSON(http.StatusOK, gin.H{"data": channel}) } func (h *PaymentChannelHandler) Create(c *gin.Context) { var req struct { Name string `json:"name"` Code string `json:"code"` Type string `json:"type"` Icon string `json:"icon"` FeeRate float64 `json:"fee_rate"` MinAmount float64 `json:"min_amount"` MaxAmount float64 `json:"max_amount"` Config string `json:"config"` IsEnabled bool `json:"is_enabled"` SortOrder int `json:"sort_order"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } var existing models.PaymentChannel if err := utils.DB.Where("code = ?", req.Code).First(&existing).Error; err == nil { c.JSON(http.StatusBadRequest, gin.H{"error": "支付通道代码已存在"}) return } channel := models.PaymentChannel{ Name: req.Name, Code: req.Code, Type: req.Type, Icon: req.Icon, FeeRate: req.FeeRate, MinAmount: req.MinAmount, MaxAmount: req.MaxAmount, Config: req.Config, IsEnabled: req.IsEnabled, SortOrder: req.SortOrder, } if err := utils.DB.Create(&channel).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to create payment channel"}) return } c.JSON(http.StatusCreated, gin.H{"data": channel}) } func (h *PaymentChannelHandler) Update(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var channel models.PaymentChannel if err := utils.DB.First(&channel, id).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Payment channel not found"}) return } var req struct { Name *string `json:"name"` Code *string `json:"code"` Type *string `json:"type"` Icon *string `json:"icon"` FeeRate *float64 `json:"fee_rate"` MinAmount *float64 `json:"min_amount"` MaxAmount *float64 `json:"max_amount"` Config *string `json:"config"` IsEnabled *bool `json:"is_enabled"` SortOrder *int `json:"sort_order"` } if err := c.ShouldBindJSON(&req); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } updates := make(map[string]interface{}) if req.Name != nil { updates["name"] = *req.Name } if req.Code != nil && *req.Code != channel.Code { var existing models.PaymentChannel if err := utils.DB.Where("code = ? AND id != ?", *req.Code, id).First(&existing).Error; err == nil { c.JSON(http.StatusBadRequest, gin.H{"error": "支付通道代码已存在"}) return } updates["code"] = *req.Code } if req.Type != nil { updates["type"] = *req.Type } if req.Icon != nil { updates["icon"] = *req.Icon } if req.FeeRate != nil { updates["fee_rate"] = *req.FeeRate } if req.MinAmount != nil { updates["min_amount"] = *req.MinAmount } if req.MaxAmount != nil { updates["max_amount"] = *req.MaxAmount } if req.Config != nil { updates["config"] = *req.Config } if req.IsEnabled != nil { updates["is_enabled"] = *req.IsEnabled } if req.SortOrder != nil { updates["sort_order"] = *req.SortOrder } utils.DB.Model(&channel).Updates(updates) c.JSON(http.StatusOK, gin.H{"data": channel}) } func (h *PaymentChannelHandler) Delete(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) if err := utils.DB.Delete(&models.PaymentChannel{}, id).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to delete payment channel"}) return } c.JSON(http.StatusOK, gin.H{"message": "Payment channel deleted successfully"}) } func (h *PaymentChannelHandler) Toggle(c *gin.Context) { id, _ := strconv.Atoi(c.Param("id")) var channel models.PaymentChannel if err := utils.DB.First(&channel, id).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": "Payment channel not found"}) return } channel.IsEnabled = !channel.IsEnabled utils.DB.Save(&channel) c.JSON(http.StatusOK, gin.H{"data": channel}) }