package handlers import ( "errors" "goalfymax-admin/pkg/utils" "strconv" "github.com/gin-gonic/gin" "gorm.io/gorm" ) // VmPricingHandler 虚拟机价格配置处理器 type VmPricingHandler struct { db *gorm.DB response *utils.Response } // NewVmPricingHandler 创建处理器 func NewVmPricingHandler(db *gorm.DB) *VmPricingHandler { return &VmPricingHandler{ db: db, response: utils.NewResponse(), } } // VmSpecResponse 虚拟机规格响应 type VmSpecResponse struct { ID uint `json:"id"` SpecType string `json:"spec_type"` CPUCores int `json:"cpu_cores"` MemoryGB int `json:"memory_gb"` Description *string `json:"description"` CostPricePerMinute float64 `json:"cost_price_per_minute"` MarkupRate float64 `json:"markup_rate"` IsActive bool `json:"is_active"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` } // VmTemplateResponse 虚拟机模板响应 type VmTemplateResponse struct { ID uint `json:"id"` SpecType string `json:"spec_type"` TemplateID string `json:"template_id"` IsDefault bool `json:"is_default"` CreatedAt string `json:"created_at"` UpdatedAt string `json:"updated_at"` } // VmSpecCreateRequest 规格创建请求 type VmSpecCreateRequest struct { SpecType string `json:"spec_type" binding:"required"` CPUCores int `json:"cpu_cores" binding:"required"` MemoryGB int `json:"memory_gb" binding:"required"` Description *string `json:"description"` CostPricePerMinute float64 `json:"cost_price_per_minute" binding:"required"` MarkupRate *float64 `json:"markup_rate"` IsActive *bool `json:"is_active"` } // VmSpecUpdateRequest 规格更新请求 type VmSpecUpdateRequest struct { CostPricePerMinute *float64 `json:"cost_price_per_minute"` MarkupRate *float64 `json:"markup_rate"` IsActive *bool `json:"is_active"` } // VmTemplateCreateRequest 模板创建请求 type VmTemplateCreateRequest struct { SpecType string `json:"spec_type" binding:"required"` TemplateID string `json:"template_id" binding:"required"` IsDefault bool `json:"is_default"` } // VmTemplateUpdateRequest 模板更新请求 type VmTemplateUpdateRequest struct { IsDefault *bool `json:"is_default"` } // GetVmSpecs 获取虚拟机规格列表 func (h *VmPricingHandler) GetVmSpecs(c *gin.Context) { var specs []VmSpecResponse // 构建查询条件 query := h.db.Table("sb_sandbox_specs") // 添加筛选条件 if specType := c.Query("spec_type"); specType != "" { query = query.Where("spec_type LIKE ?", "%"+specType+"%") } if status := c.Query("status"); status != "" { if status == "active" { query = query.Where("is_active = ?", true) } else if status == "inactive" { query = query.Where("is_active = ?", false) } } // 分页 page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) size, _ := strconv.Atoi(c.DefaultQuery("size", "10")) offset := (page - 1) * size // 先获取总数 var total int64 err := query.Count(&total).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } // 然后获取分页数据 err = query.Order("created_at DESC").Offset(offset).Limit(size).Find(&specs).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } h.response.Page(c, specs, total, page, size) } // UpdateVmSpec 更新虚拟机规格 func (h *VmPricingHandler) UpdateVmSpec(c *gin.Context) { id := c.Param("id") var req VmSpecUpdateRequest if err := c.ShouldBindJSON(&req); err != nil { h.response.BadRequest(c, err.Error()) return } // 构建更新字段 updates := make(map[string]interface{}) if req.CostPricePerMinute != nil { updates["cost_price_per_minute"] = *req.CostPricePerMinute } if req.MarkupRate != nil { updates["markup_rate"] = *req.MarkupRate } if req.IsActive != nil { updates["is_active"] = *req.IsActive } if len(updates) == 0 { h.response.BadRequest(c, "没有需要更新的字段") return } // 检查规格是否存在 var count int64 err := h.db.Table("sb_sandbox_specs").Where("id = ?", id).Count(&count).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } if count == 0 { h.response.NotFound(c, "规格不存在") return } // 更新规格 err = h.db.Table("sb_sandbox_specs").Where("id = ?", id).Updates(updates).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } h.response.Success(c, "规格更新成功") } // DeleteVmSpec 删除虚拟机规格 func (h *VmPricingHandler) DeleteVmSpec(c *gin.Context) { id := c.Param("id") // 检查规格是否存在 var count int64 err := h.db.Table("sb_sandbox_specs").Where("id = ?", id).Count(&count).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } if count == 0 { h.response.NotFound(c, "规格不存在") return } // 删除规格 err = h.db.Table("sb_sandbox_specs").Where("id = ?", id).Delete(nil).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } h.response.Success(c, "规格删除成功") } // CreateVmSpec 创建虚拟机规格 func (h *VmPricingHandler) CreateVmSpec(c *gin.Context) { var req VmSpecCreateRequest if err := c.ShouldBindJSON(&req); err != nil { h.response.BadRequest(c, err.Error()) return } // 检查规格类型是否已存在 var count int64 err := h.db.Table("sb_sandbox_specs").Where("spec_type = ?", req.SpecType).Count(&count).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } if count > 0 { h.response.BadRequest(c, "该配置类型已存在") return } // 设置默认值 markupRate := 0.3000 // 默认30% if req.MarkupRate != nil { markupRate = *req.MarkupRate } isActive := true if req.IsActive != nil { isActive = *req.IsActive } // 创建规格 insertData := map[string]interface{}{ "spec_type": req.SpecType, "cpu_cores": req.CPUCores, "memory_gb": req.MemoryGB, "cost_price_per_minute": req.CostPricePerMinute, "markup_rate": markupRate, "is_active": isActive, } if req.Description != nil { insertData["description"] = *req.Description } err = h.db.Table("sb_sandbox_specs").Create(insertData).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } h.response.Success(c, "规格创建成功") } // GetVmTemplates 获取虚拟机模板列表 func (h *VmPricingHandler) GetVmTemplates(c *gin.Context) { var templates []VmTemplateResponse // 构建查询条件 query := h.db.Table("sb_sandbox_templates") // 添加筛选条件 if specType := c.Query("spec_type"); specType != "" { query = query.Where("spec_type = ?", specType) } // 分页 page, _ := strconv.Atoi(c.DefaultQuery("page", "1")) size, _ := strconv.Atoi(c.DefaultQuery("size", "10")) offset := (page - 1) * size // 先获取总数 var total int64 err := query.Count(&total).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } // 然后获取分页数据 err = query.Order("spec_type ASC, created_at DESC").Offset(offset).Limit(size).Find(&templates).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } h.response.Page(c, templates, total, page, size) } // CreateVmTemplate 创建虚拟机模板 func (h *VmPricingHandler) CreateVmTemplate(c *gin.Context) { var req VmTemplateCreateRequest if err := c.ShouldBindJSON(&req); err != nil { h.response.BadRequest(c, err.Error()) return } // 检查规格是否存在 var specCount int64 err := h.db.Table("sb_sandbox_specs").Where("spec_type = ?", req.SpecType).Count(&specCount).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } if specCount == 0 { h.response.BadRequest(c, "规格类型不存在") return } // 如果设置为默认模板,需要先取消同规格的其他默认模板 if req.IsDefault { err = h.db.Table("sb_sandbox_templates"). Where("spec_type = ? AND is_default = ?", req.SpecType, true). Update("is_default", false).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } } // 检查是否已存在相同的规格-模板组合 var existingCount int64 err = h.db.Table("sb_sandbox_templates"). Where("spec_type = ? AND template_id = ?", req.SpecType, req.TemplateID). Count(&existingCount).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } if existingCount > 0 { h.response.BadRequest(c, "该规格和模板的组合已存在") return } // 创建模板 insertData := map[string]interface{}{ "spec_type": req.SpecType, "template_id": req.TemplateID, "is_default": req.IsDefault, } err = h.db.Table("sb_sandbox_templates").Create(insertData).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } h.response.Success(c, "模板创建成功") } // DeleteVmTemplate 删除虚拟机模板 func (h *VmPricingHandler) DeleteVmTemplate(c *gin.Context) { id := c.Param("id") // 检查模板是否存在 var count int64 err := h.db.Table("sb_sandbox_templates").Where("id = ?", id).Count(&count).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } if count == 0 { h.response.NotFound(c, "模板不存在") return } // 删除模板 err = h.db.Table("sb_sandbox_templates").Where("id = ?", id).Delete(nil).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } h.response.Success(c, "模板删除成功") } // SetDefaultVmTemplate 设置默认模板 func (h *VmPricingHandler) SetDefaultVmTemplate(c *gin.Context) { id := c.Param("id") // 获取模板信息 var template VmTemplateResponse err := h.db.Table("sb_sandbox_templates").Where("id = ?", id).First(&template).Error if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { h.response.NotFound(c, "模板不存在") return } h.response.InternalServerError(c, err.Error()) return } // 取消同规格的其他默认模板 err = h.db.Table("sb_sandbox_templates"). Where("spec_type = ? AND is_default = ? AND id != ?", template.SpecType, true, id). Update("is_default", false).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } // 设置当前模板为默认 err = h.db.Table("sb_sandbox_templates").Where("id = ?", id).Update("is_default", true).Error if err != nil { h.response.InternalServerError(c, err.Error()) return } h.response.Success(c, "默认模板设置成功") }