实现启动计划

This commit is contained in:
2025-09-22 14:21:08 +08:00
parent 0a8e6793ef
commit bd2d1c6b63
3 changed files with 59 additions and 5 deletions

View File

@@ -350,9 +350,50 @@ func (c *Controller) DeletePlan(ctx *gin.Context) {
// @Success 200 {object} controller.Response "业务码为200代表成功启动计划"
// @Router /api/v1/plans/{id}/start [post]
func (c *Controller) StartPlan(ctx *gin.Context) {
// 占位符:此处应调用服务层或仓库层来启动计划
c.logger.Infof("收到启动计划请求 (占位符)")
controller.SendResponse(ctx, controller.CodeSuccess, "启动计划接口占位符", nil)
// 1. 从 URL 路径中获取 ID
idStr := ctx.Param("id")
id, err := strconv.ParseUint(idStr, 10, 32)
if err != nil {
controller.SendErrorResponse(ctx, controller.CodeBadRequest, "无效的计划ID格式")
return
}
// 2. 检查计划是否存在
plan, err := c.planRepo.GetBasicPlanByID(uint(id))
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
controller.SendErrorResponse(ctx, controller.CodeNotFound, "计划不存在")
return
}
c.logger.Errorf("启动计划时获取计划信息失败: %v", err)
controller.SendErrorResponse(ctx, controller.CodeInternalError, "获取计划信息时发生内部错误")
return
}
// 3. 检查计划当前状态
if plan.Status == models.PlanStatusEnabled {
controller.SendErrorResponse(ctx, controller.CodeBadRequest, "计划已处于启动状态,无需重复操作")
return
}
// 4. 更新计划状态为“已启动”
if err := c.planRepo.UpdatePlanStatus(plan.ID, models.PlanStatusEnabled); err != nil {
c.logger.Errorf("更新计划 #%d 状态为 '已启动' 失败: %v", plan.ID, err)
controller.SendErrorResponse(ctx, controller.CodeInternalError, "更新计划状态失败")
return
}
c.logger.Infof("已成功更新计划 #%d 的状态为 '已启动'", plan.ID)
// 5. 为计划创建或更新触发器
if err := c.analysisPlanTaskManager.CreateOrUpdateTrigger(plan.ID); err != nil {
// 此处错误不回滚状态,因为状态更新已成功,但需要明确告知用户触发器创建失败
c.logger.Errorf("为计划 #%d 创建或更新触发器失败: %v", plan.ID, err)
controller.SendErrorResponse(ctx, controller.CodeInternalError, "计划状态已更新,但创建执行触发器失败,请检查计划配置或稍后重试")
return
}
// 6. 发送成功响应
controller.SendResponse(ctx, controller.CodeSuccess, "计划已成功启动", nil)
}
// StopPlan godoc

View File

@@ -67,8 +67,7 @@ func (m *AnalysisPlanTaskManager) Refresh() error {
}
// CreateOrUpdateTrigger 为给定的 planID 创建其关联的触发任务。
// 这个方法是幂等的:如果一个有效的触发器已存在,它将不会重复创建
// 关键修改:如果触发器已存在,会根据计划类型更新其执行时间。
// 如果触发器已存在,会根据计划类型更新其执行时间
func (m *AnalysisPlanTaskManager) CreateOrUpdateTrigger(planID uint) error {
m.mu.Lock()
defer m.mu.Unlock()

View File

@@ -34,6 +34,8 @@ type PlanRepository interface {
CreatePlan(plan *models.Plan) error
// UpdatePlan 更新计划,包括子计划和任务
UpdatePlan(plan *models.Plan) error
// UpdatePlanStatus 更新指定计划的状态
UpdatePlanStatus(id uint, status models.PlanStatus) error
// DeletePlan 根据ID删除计划同时删除其关联的任务非子任务或子计划关联
DeletePlan(id uint) error
// FlattenPlanTasks 递归展开计划,返回按执行顺序排列的所有任务列表
@@ -643,3 +645,15 @@ func (r *gormPlanRepository) FindPlansWithPendingTasks() ([]*models.Plan, error)
return plans, err
}
// UpdatePlanStatus 更新指定计划的状态
func (r *gormPlanRepository) UpdatePlanStatus(id uint, status models.PlanStatus) error {
result := r.db.Model(&models.Plan{}).Where("id = ?", id).Update("status", status)
if result.Error != nil {
return result.Error
}
if result.RowsAffected == 0 {
return gorm.ErrRecordNotFound
}
return nil
}