实现关闭计划

This commit is contained in:
2025-09-22 15:17:54 +08:00
parent bd2d1c6b63
commit 4096499d28
5 changed files with 138 additions and 3 deletions

View File

@@ -56,6 +56,12 @@ type PlanRepository interface {
// FindPlansWithPendingTasks 查找所有正在执行的计划
FindPlansWithPendingTasks() ([]*models.Plan, error)
// DB 返回底层的数据库连接实例,用于服务层事务
DB() *gorm.DB
// StopPlanTransactionally 停止一个计划的执行,包括更新状态、移除待执行任务和更新执行日志
StopPlanTransactionally(planID uint) error
}
// gormPlanRepository 是 PlanRepository 的 GORM 实现
@@ -646,6 +652,78 @@ func (r *gormPlanRepository) FindPlansWithPendingTasks() ([]*models.Plan, error)
return plans, err
}
// DB 返回底层的数据库连接实例
func (r *gormPlanRepository) DB() *gorm.DB {
return r.db
}
// StopPlanTransactionally 停止一个计划的执行,包括更新状态、移除待执行任务和更新执行日志。
func (r *gormPlanRepository) StopPlanTransactionally(planID uint) error {
return r.db.Transaction(func(tx *gorm.DB) error {
// 使用事务创建新的仓库实例,确保所有操作都在同一个事务中
planRepoTx := NewGormPlanRepository(tx)
executionLogRepoTx := NewGormExecutionLogRepository(tx)
pendingTaskRepoTx := NewGormPendingTaskRepository(tx)
// 1. 更新计划状态为“已停止”
if err := planRepoTx.UpdatePlanStatus(planID, models.PlanStatusDisabled); err != nil {
return fmt.Errorf("更新计划 #%d 状态为 '已停止' 失败: %w", planID, err)
}
// 2. 查找当前正在进行的计划执行日志
planLog, err := executionLogRepoTx.FindInProgressPlanExecutionLogByPlanID(planID)
if err != nil {
return fmt.Errorf("查找计划 #%d 正在进行的执行日志失败: %w", planID, err)
}
if planLog == nil {
// 没有正在进行的执行,直接返回成功
return nil
}
// 3. 查找所有需要被取消的任务执行日志
taskLogs, err := executionLogRepoTx.FindIncompleteTaskExecutionLogsByPlanLogID(planLog.ID)
if err != nil {
return fmt.Errorf("查找计划执行日志 #%d 下未完成的任务日志失败: %w", planLog.ID, err)
}
if len(taskLogs) > 0 {
var taskLogIDs []uint
for _, tl := range taskLogs {
taskLogIDs = append(taskLogIDs, tl.ID)
}
// 3.1 批量更新任务执行日志状态为“已取消”
if err := executionLogRepoTx.UpdateLogStatusByIDs(taskLogIDs, models.ExecutionStatusCancelled); err != nil {
return fmt.Errorf("批量更新任务执行日志状态为 '已取消' 失败: %w", err)
}
// 3.2 查找并删除待执行队列中对应的任务
pendingTasks, err := pendingTaskRepoTx.FindPendingTasksByTaskLogIDs(taskLogIDs)
if err != nil {
return fmt.Errorf("查找计划执行日志 #%d 下对应的待执行任务失败: %w", planLog.ID, err)
}
if len(pendingTasks) > 0 {
var pendingTaskIDs []uint
for _, pt := range pendingTasks {
pendingTaskIDs = append(pendingTaskIDs, pt.ID)
}
if err := pendingTaskRepoTx.DeletePendingTasksByIDs(pendingTaskIDs); err != nil {
return fmt.Errorf("批量删除待执行任务失败: %w", err)
}
}
}
// 4. 更新计划执行历史的总状态为“失败”
if err := executionLogRepoTx.UpdatePlanExecutionLogStatus(planLog.ID, models.ExecutionStatusFailed); err != nil {
return fmt.Errorf("更新计划执行日志 #%d 状态为 '失败' 失败: %w", planLog.ID, err)
}
return nil
})
}
// UpdatePlanStatus 更新指定计划的状态
func (r *gormPlanRepository) UpdatePlanStatus(id uint, status models.PlanStatus) error {
result := r.db.Model(&models.Plan{}).Where("id = ?", id).Update("status", status)