228 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			228 lines
		
	
	
		
			5.7 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package dto
 | 
						||
 | 
						||
import (
 | 
						||
	"encoding/json"
 | 
						||
	"fmt"
 | 
						||
 | 
						||
	"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
 | 
						||
)
 | 
						||
 | 
						||
// NewPlanToResponse 将Plan模型转换为PlanResponse
 | 
						||
func NewPlanToResponse(plan *models.Plan) (*PlanResponse, error) {
 | 
						||
	if plan == nil {
 | 
						||
		return nil, nil
 | 
						||
	}
 | 
						||
 | 
						||
	response := &PlanResponse{
 | 
						||
		ID:             plan.ID,
 | 
						||
		Name:           plan.Name,
 | 
						||
		Description:    plan.Description,
 | 
						||
		PlanType:       plan.PlanType,
 | 
						||
		ExecutionType:  plan.ExecutionType,
 | 
						||
		Status:         plan.Status,
 | 
						||
		ExecuteNum:     plan.ExecuteNum,
 | 
						||
		ExecuteCount:   plan.ExecuteCount,
 | 
						||
		CronExpression: plan.CronExpression,
 | 
						||
		ContentType:    plan.ContentType,
 | 
						||
	}
 | 
						||
 | 
						||
	// 转换子计划
 | 
						||
	if plan.ContentType == models.PlanContentTypeSubPlans {
 | 
						||
		response.SubPlans = make([]SubPlanResponse, len(plan.SubPlans))
 | 
						||
		for i, subPlan := range plan.SubPlans {
 | 
						||
			subPlanResp, err := SubPlanToResponse(&subPlan)
 | 
						||
			if err != nil {
 | 
						||
				return nil, err
 | 
						||
			}
 | 
						||
			response.SubPlans[i] = subPlanResp
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	// 转换任务
 | 
						||
	if plan.ContentType == models.PlanContentTypeTasks {
 | 
						||
		response.Tasks = make([]TaskResponse, len(plan.Tasks))
 | 
						||
		for i, task := range plan.Tasks {
 | 
						||
			taskResp, err := TaskToResponse(&task)
 | 
						||
			if err != nil {
 | 
						||
				return nil, err
 | 
						||
			}
 | 
						||
			response.Tasks[i] = taskResp
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	return response, nil
 | 
						||
}
 | 
						||
 | 
						||
// NewPlanFromCreateRequest 将CreatePlanRequest转换为Plan模型,并进行业务规则验证
 | 
						||
func NewPlanFromCreateRequest(req *CreatePlanRequest) (*models.Plan, error) {
 | 
						||
	if req == nil {
 | 
						||
		return nil, nil
 | 
						||
	}
 | 
						||
 | 
						||
	plan := &models.Plan{
 | 
						||
		Name:           req.Name,
 | 
						||
		Description:    req.Description,
 | 
						||
		ExecutionType:  req.ExecutionType,
 | 
						||
		ExecuteNum:     req.ExecuteNum,
 | 
						||
		CronExpression: req.CronExpression,
 | 
						||
		// ContentType 和 PlanType 在控制器中设置,此处不再处理
 | 
						||
	}
 | 
						||
 | 
						||
	// 处理子计划 (通过ID引用)
 | 
						||
	if req.SubPlanIDs != nil {
 | 
						||
		subPlanSlice := req.SubPlanIDs
 | 
						||
		plan.SubPlans = make([]models.SubPlan, len(subPlanSlice))
 | 
						||
		for i, childPlanID := range subPlanSlice {
 | 
						||
			plan.SubPlans[i] = models.SubPlan{
 | 
						||
				ChildPlanID:    childPlanID,
 | 
						||
				ExecutionOrder: i, // 默认执行顺序, ReorderSteps会再次确认
 | 
						||
			}
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	// 处理任务
 | 
						||
	if req.Tasks != nil {
 | 
						||
		taskSlice := req.Tasks
 | 
						||
		plan.Tasks = make([]models.Task, len(taskSlice))
 | 
						||
		for i, taskReq := range taskSlice {
 | 
						||
			task, err := TaskFromRequest(&taskReq)
 | 
						||
			if err != nil {
 | 
						||
				return nil, err
 | 
						||
			}
 | 
						||
			plan.Tasks[i] = task
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	// 1. 首先,执行重复性验证
 | 
						||
	if err := plan.ValidateExecutionOrder(); err != nil {
 | 
						||
		// 如果检测到重复,立即返回错误
 | 
						||
		return nil, err
 | 
						||
	}
 | 
						||
 | 
						||
	// 2. 然后,调用方法来修复顺序断层
 | 
						||
	plan.ReorderSteps()
 | 
						||
 | 
						||
	return plan, nil
 | 
						||
}
 | 
						||
 | 
						||
// NewPlanFromUpdateRequest 将UpdatePlanRequest转换为Plan模型,并进行业务规则验证
 | 
						||
func NewPlanFromUpdateRequest(req *UpdatePlanRequest) (*models.Plan, error) {
 | 
						||
	if req == nil {
 | 
						||
		return nil, nil
 | 
						||
	}
 | 
						||
 | 
						||
	plan := &models.Plan{
 | 
						||
		Name:           req.Name,
 | 
						||
		Description:    req.Description,
 | 
						||
		ExecutionType:  req.ExecutionType,
 | 
						||
		ExecuteNum:     req.ExecuteNum,
 | 
						||
		CronExpression: req.CronExpression,
 | 
						||
		// ContentType 和 PlanType 在控制器中设置,此处不再处理
 | 
						||
	}
 | 
						||
 | 
						||
	// 处理子计划 (通过ID引用)
 | 
						||
	if req.SubPlanIDs != nil {
 | 
						||
		subPlanSlice := req.SubPlanIDs
 | 
						||
		plan.SubPlans = make([]models.SubPlan, len(subPlanSlice))
 | 
						||
		for i, childPlanID := range subPlanSlice {
 | 
						||
			plan.SubPlans[i] = models.SubPlan{
 | 
						||
				ChildPlanID:    childPlanID,
 | 
						||
				ExecutionOrder: i, // 默认执行顺序, ReorderSteps会再次确认
 | 
						||
			}
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	// 处理任务
 | 
						||
	if req.Tasks != nil {
 | 
						||
		taskSlice := req.Tasks
 | 
						||
		plan.Tasks = make([]models.Task, len(taskSlice))
 | 
						||
		for i, taskReq := range taskSlice {
 | 
						||
			task, err := TaskFromRequest(&taskReq)
 | 
						||
			if err != nil {
 | 
						||
				return nil, err
 | 
						||
			}
 | 
						||
			plan.Tasks[i] = task
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	// 1. 首先,执行重复性验证
 | 
						||
	if err := plan.ValidateExecutionOrder(); err != nil {
 | 
						||
		// 如果检测到重复,立即返回错误
 | 
						||
		return nil, err
 | 
						||
	}
 | 
						||
 | 
						||
	// 2. 然后,调用方法来修复顺序断层
 | 
						||
	plan.ReorderSteps()
 | 
						||
 | 
						||
	return plan, nil
 | 
						||
}
 | 
						||
 | 
						||
// SubPlanToResponse 将SubPlan模型转换为SubPlanResponse
 | 
						||
func SubPlanToResponse(subPlan *models.SubPlan) (SubPlanResponse, error) {
 | 
						||
	if subPlan == nil {
 | 
						||
		return SubPlanResponse{}, nil
 | 
						||
	}
 | 
						||
 | 
						||
	response := SubPlanResponse{
 | 
						||
		ID:             subPlan.ID,
 | 
						||
		ParentPlanID:   subPlan.ParentPlanID,
 | 
						||
		ChildPlanID:    subPlan.ChildPlanID,
 | 
						||
		ExecutionOrder: subPlan.ExecutionOrder,
 | 
						||
	}
 | 
						||
 | 
						||
	// 如果有完整的子计划数据,也进行转换
 | 
						||
	if subPlan.ChildPlan != nil {
 | 
						||
		childPlanResp, err := NewPlanToResponse(subPlan.ChildPlan)
 | 
						||
		if err != nil {
 | 
						||
			return SubPlanResponse{}, err
 | 
						||
		}
 | 
						||
		response.ChildPlan = childPlanResp
 | 
						||
	}
 | 
						||
 | 
						||
	return response, nil
 | 
						||
}
 | 
						||
 | 
						||
// TaskToResponse 将Task模型转换为TaskResponse
 | 
						||
func TaskToResponse(task *models.Task) (TaskResponse, error) {
 | 
						||
	if task == nil {
 | 
						||
		return TaskResponse{}, nil
 | 
						||
	}
 | 
						||
 | 
						||
	var params map[string]interface{}
 | 
						||
	if len(task.Parameters) > 0 && string(task.Parameters) != "null" {
 | 
						||
		if err := task.ParseParameters(¶ms); err != nil {
 | 
						||
			return TaskResponse{}, fmt.Errorf("parsing task parameters failed (ID: %d): %w", task.ID, err)
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	return TaskResponse{
 | 
						||
		ID:             task.ID,
 | 
						||
		PlanID:         task.PlanID,
 | 
						||
		Name:           task.Name,
 | 
						||
		Description:    task.Description,
 | 
						||
		ExecutionOrder: task.ExecutionOrder,
 | 
						||
		Type:           task.Type,
 | 
						||
		Parameters:     params,
 | 
						||
	}, nil
 | 
						||
}
 | 
						||
 | 
						||
// TaskFromRequest 将TaskRequest转换为Task模型
 | 
						||
func TaskFromRequest(req *TaskRequest) (models.Task, error) {
 | 
						||
	if req == nil {
 | 
						||
		return models.Task{}, nil
 | 
						||
	}
 | 
						||
 | 
						||
	paramsJSON, err := json.Marshal(req.Parameters)
 | 
						||
	if err != nil {
 | 
						||
		return models.Task{}, fmt.Errorf("serializing task parameters failed: %w", err)
 | 
						||
	}
 | 
						||
 | 
						||
	return models.Task{
 | 
						||
		Name:           req.Name,
 | 
						||
		Description:    req.Description,
 | 
						||
		ExecutionOrder: req.ExecutionOrder,
 | 
						||
		Type:           req.Type,
 | 
						||
		Parameters:     paramsJSON,
 | 
						||
	}, nil
 | 
						||
}
 |