pcm-coordinator/internal/logic/core/editresourcespeclogic.go

164 lines
4.2 KiB
Go

package core
import (
"context"
"github.com/pkg/errors"
"github.com/zeromicro/go-zero/core/logx"
"gitlink.org.cn/JointCloud/pcm-coordinator/internal/svc"
"gitlink.org.cn/JointCloud/pcm-coordinator/internal/types"
"gitlink.org.cn/JointCloud/pcm-coordinator/pkg/models"
"gitlink.org.cn/JointCloud/pcm-coordinator/pkg/utils"
"gorm.io/gorm"
)
type EditResourceSpecLogic struct {
logx.Logger
ctx context.Context
svcCtx *svc.ServiceContext
}
func NewEditResourceSpecLogic(ctx context.Context, svcCtx *svc.ServiceContext) *EditResourceSpecLogic {
return &EditResourceSpecLogic{
Logger: logx.WithContext(ctx),
ctx: ctx,
svcCtx: svcCtx,
}
}
func (l *EditResourceSpecLogic) EditResourceSpec(req *types.EditResourceReq) (resp *types.CommonResp, err error) {
// 初始化事务
tx := l.svcCtx.DbEngin.Begin()
defer func() {
if r := recover(); r != nil {
tx.Rollback()
panic(r)
} else if err != nil {
tx.Rollback()
}
}()
// 1. 验证资源规格存在
var existing models.TResourceSpec
if err = tx.Model(&models.TResourceSpec{}).
Where("id = ? AND deleted_at IS NULL", req.Id).
First(&existing).
Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.Errorf("资源规格不存在 (ID: %d)", req.Id)
}
return nil, errors.Wrapf(err, "查询资源规格失败 (ID: %d)", req.Id)
}
// 2. 参数校验
if err = validateRequestParams(req); err != nil {
return nil, err
}
// 3. 转换参数
statusInt := utils.StringToInt64(req.Status)
costPerUnit := utils.StringToFloat64(req.CostPerUnit)
// 4. 更新主资源规格
if err = updateMainResourceSpec(tx, req.Id, statusInt, req.CostType, costPerUnit); err != nil {
return nil, err
}
// 5. 更新子资源规格
if err = updateSubResources(tx, req); err != nil {
return nil, err
}
// 提交事务
if err = tx.Commit().Error; err != nil {
return nil, errors.Wrap(err, "提交事务失败")
}
// 返回成功响应
return resp, nil
}
// validateRequestParams 验证请求参数合法性
func validateRequestParams(req *types.EditResourceReq) error {
// 状态校验
if req.Status != "0" && req.Status != "1" {
return errors.Errorf("资源规格状态不合法 (ID: %d)", req.Id)
}
// 计费类型校验
validCostTypes := map[string]struct{}{
"hourly": {},
"daily": {},
"monthly": {},
"perUse": {},
}
if _, ok := validCostTypes[req.CostType]; !ok {
return errors.Errorf("资源规格计费类型不合法 (ID: %d)", req.Id)
}
return nil
}
// updateMainResourceSpec 更新主资源规格
func updateMainResourceSpec(tx *gorm.DB, id int64, status int64, costType string, costPerUnit float64) error {
return tx.Model(&models.TResourceSpec{}).
Where("id = ?", id).
Updates(map[string]interface{}{
"status": status,
"cost_type": costType,
"cost_per_unit": costPerUnit,
}).
Error
}
// updateSubResources 更新子资源规格
func updateSubResources(tx *gorm.DB, req *types.EditResourceReq) error {
// 定义更新操作集合
updateOperations := []struct {
Value string
Unit string
SpecType string
SpecName string
}{
{req.CpuValue, req.CpuUnit, "CPU", ""},
{req.MemoryValue, req.MemoryUnit, "MEMORY", "RAM"},
{req.StorageValue, req.StorageUnit, "STORAGE", ""},
}
// 批量执行更新操作
for _, op := range updateOperations {
if op.Value == "" && op.Unit == "" {
continue
}
if err := updateBaseResourceSpec(tx, req.Id, op.SpecType, op.SpecName, op.Value, op.Unit); err != nil {
return errors.Wrapf(err, "更新%s规格失败 (ID: %d)", op.SpecType, req.Id)
}
}
return nil
}
// updateBaseResourceSpec 通用基础资源规格更新函数
func updateBaseResourceSpec(tx *gorm.DB, specID int64, specType string, specName string, value, unit string) error {
updates := make(map[string]interface{})
if value != "" {
updates["total_value"] = value
}
if unit != "" {
updates["total_unit"] = unit
}
if len(updates) == 0 {
return nil
}
query := tx.Model(&models.TBaseResourceSpec{}).
Where("resource_spec_id = ? AND type = ?", specID, specType)
if specName != "" {
query = query.Where("name = ?", specName)
}
if err := query.Updates(updates).Error; err != nil {
return errors.Wrapf(err, "更新%s规格失败", specType)
}
return nil
}