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