Files
goalfylearning-admin/internal/api/handlers/vm_pricing_handler.go

404 lines
10 KiB
Go

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, "默认模板设置成功")
}