实现
This commit is contained in:
@@ -202,7 +202,7 @@ func (s *planService) UpdatePlan(id uint, req *dto.UpdatePlanRequest) (*dto.Plan
|
||||
planToUpdate.ExecuteCount = 0
|
||||
s.logger.Infof("计划 #%d 被更新,执行计数器已重置为 0。", planToUpdate.ID)
|
||||
|
||||
if err := s.planRepo.UpdatePlan(planToUpdate); err != nil {
|
||||
if err := s.planRepo.UpdatePlanMetadataAndStructure(planToUpdate); err != nil {
|
||||
s.logger.Errorf("%s: 数据库更新计划失败: %v, Plan: %+v", actionType, err, planToUpdate)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -65,7 +65,6 @@ func (app *Application) initializeSystemPlans() error {
|
||||
// 将数据库中已存在的计划的ID和运行时状态字段赋值给预定义计划
|
||||
predefinedPlan.ID = foundExistingPlan.ID
|
||||
predefinedPlan.ExecuteCount = foundExistingPlan.ExecuteCount
|
||||
predefinedPlan.Status = foundExistingPlan.Status
|
||||
|
||||
if err := app.Infra.Repos.PlanRepo.UpdatePlan(predefinedPlan); err != nil {
|
||||
return fmt.Errorf("更新预定义计划 '%s' 失败: %w", predefinedPlan.Name, err)
|
||||
@@ -191,8 +190,22 @@ func (app *Application) initializePendingTasks() error {
|
||||
affectedPlanIDs[log.PlanID] = struct{}{}
|
||||
}
|
||||
|
||||
// 3. 对于每个受影响的 PlanID,重置其 execute_count 并将其状态设置为 Failed
|
||||
// 3. 对于每个受影响的 PlanID,重置其 execute_count 并将其状态设置为 Failed, 系统计划不受此影响
|
||||
for planID := range affectedPlanIDs {
|
||||
// 首先,获取计划的详细信息以判断其类型
|
||||
plan, err := planRepo.GetBasicPlanByID(planID)
|
||||
if err != nil {
|
||||
logger.Errorf("在尝试修正计划状态时,获取计划 #%d 的基本信息失败: %v", planID, err)
|
||||
continue // 获取失败,跳过此计划
|
||||
}
|
||||
|
||||
// 如果是系统计划,则不应标记为失败,仅记录日志
|
||||
if plan.PlanType == models.PlanTypeSystem {
|
||||
logger.Warnf("检测到系统计划 #%d 在应用崩溃前处于未完成状态,但根据策略,将保持其原有状态不标记为失败。", planID)
|
||||
continue // 跳过,不处理
|
||||
}
|
||||
|
||||
// 对于非系统计划,执行原有的失败标记逻辑
|
||||
logger.Warnf("检测到计划 #%d 在应用崩溃前处于未完成状态,将重置其计数并标记为失败。", planID)
|
||||
// 使用 UpdatePlanStateAfterExecution 来更新主表状态,避免影响关联数据
|
||||
if err := planRepo.UpdatePlanStateAfterExecution(planID, 0, models.PlanStatusFailed); err != nil {
|
||||
|
||||
@@ -48,7 +48,9 @@ type PlanRepository interface {
|
||||
GetPlansByIDs(ids []uint) ([]models.Plan, error)
|
||||
// CreatePlan 创建一个新的计划
|
||||
CreatePlan(plan *models.Plan) error
|
||||
// UpdatePlan 更新计划,包括子计划和任务
|
||||
// UpdatePlanMetadataAndStructure 更新计划的元数据和结构,但不包括状态等运行时信息
|
||||
UpdatePlanMetadataAndStructure(plan *models.Plan) error
|
||||
// UpdatePlan 更新计划的所有字段
|
||||
UpdatePlan(plan *models.Plan) error
|
||||
// UpdatePlanStatus 更新指定计划的状态
|
||||
UpdatePlanStatus(id uint, status models.PlanStatus) error
|
||||
@@ -259,15 +261,20 @@ func (r *gormPlanRepository) CreatePlan(plan *models.Plan) error {
|
||||
})
|
||||
}
|
||||
|
||||
// UpdatePlan 是更新计划的公共入口点
|
||||
// UpdatePlan 更新计划
|
||||
func (r *gormPlanRepository) UpdatePlan(plan *models.Plan) error {
|
||||
return r.db.Save(plan).Error
|
||||
}
|
||||
|
||||
// UpdatePlanMetadataAndStructure 是更新计划元数据和结构的公共入口点
|
||||
func (r *gormPlanRepository) UpdatePlanMetadataAndStructure(plan *models.Plan) error {
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
return r.updatePlanTx(tx, plan)
|
||||
return r.updatePlanMetadataAndStructureTx(tx, plan)
|
||||
})
|
||||
}
|
||||
|
||||
// updatePlanTx 在事务中协调整个更新过程
|
||||
func (r *gormPlanRepository) updatePlanTx(tx *gorm.DB, plan *models.Plan) error {
|
||||
// updatePlanMetadataAndStructureTx 在事务中协调整个更新过程
|
||||
func (r *gormPlanRepository) updatePlanMetadataAndStructureTx(tx *gorm.DB, plan *models.Plan) error {
|
||||
if err := r.validatePlanTree(tx, plan); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user