修改infra.repository包
This commit is contained in:
@@ -1,11 +1,14 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
|
||||
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
|
||||
|
||||
"gorm.io/datatypes"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -39,67 +42,71 @@ type ListPlansOptions struct {
|
||||
// 这是为了让业务逻辑层依赖于抽象,而不是具体的数据库实现
|
||||
type PlanRepository interface {
|
||||
// ListPlans 获取计划列表,支持过滤和分页
|
||||
ListPlans(opts ListPlansOptions, page, pageSize int) ([]models.Plan, int64, error)
|
||||
ListPlans(ctx context.Context, opts ListPlansOptions, page, pageSize int) ([]models.Plan, int64, error)
|
||||
// GetBasicPlanByID 根据ID获取计划的基本信息,不包含子计划和任务详情
|
||||
GetBasicPlanByID(id uint) (*models.Plan, error)
|
||||
GetBasicPlanByID(ctx context.Context, id uint) (*models.Plan, error)
|
||||
// GetPlanByID 根据ID获取计划,包含子计划和任务详情
|
||||
GetPlanByID(id uint) (*models.Plan, error)
|
||||
GetPlanByID(ctx context.Context, id uint) (*models.Plan, error)
|
||||
// GetPlansByIDs 根据ID列表获取计划,不包含子计划和任务详情
|
||||
GetPlansByIDs(ids []uint) ([]models.Plan, error)
|
||||
GetPlansByIDs(ctx context.Context, ids []uint) ([]models.Plan, error)
|
||||
// CreatePlan 创建一个新的计划
|
||||
CreatePlan(plan *models.Plan) error
|
||||
CreatePlan(ctx context.Context, plan *models.Plan) error
|
||||
// CreatePlanTx 在指定事务中创建一个新的计划
|
||||
CreatePlanTx(tx *gorm.DB, plan *models.Plan) error
|
||||
CreatePlanTx(ctx context.Context, tx *gorm.DB, plan *models.Plan) error
|
||||
// UpdatePlanMetadataAndStructure 更新计划的元数据和结构,但不包括状态等运行时信息
|
||||
UpdatePlanMetadataAndStructure(plan *models.Plan) error
|
||||
UpdatePlanMetadataAndStructure(ctx context.Context, plan *models.Plan) error
|
||||
// UpdatePlan 更新计划的所有字段
|
||||
UpdatePlan(plan *models.Plan) error
|
||||
UpdatePlan(ctx context.Context, plan *models.Plan) error
|
||||
// UpdatePlanStatus 更新指定计划的状态
|
||||
UpdatePlanStatus(id uint, status models.PlanStatus) error
|
||||
UpdatePlanStatus(ctx context.Context, id uint, status models.PlanStatus) error
|
||||
// UpdateExecuteCount 更新指定计划的执行计数
|
||||
UpdateExecuteCount(id uint, count uint) error
|
||||
UpdateExecuteCount(ctx context.Context, id uint, count uint) error
|
||||
// DeletePlan 根据ID删除计划,同时删除其关联的任务(非子任务)或子计划关联
|
||||
DeletePlan(id uint) error
|
||||
DeletePlan(ctx context.Context, id uint) error
|
||||
// FlattenPlanTasks 递归展开计划,返回按执行顺序排列的所有任务列表
|
||||
FlattenPlanTasks(planID uint) ([]models.Task, error)
|
||||
FlattenPlanTasks(ctx context.Context, planID uint) ([]models.Task, error)
|
||||
// DeleteTask 根据ID删除任务
|
||||
DeleteTask(id int) error
|
||||
DeleteTask(ctx context.Context, id int) error
|
||||
// FindPlanAnalysisTaskByParamsPlanID 根据Parameters中的ParamsPlanID字段值查找TaskPlanAnalysis类型的Task
|
||||
FindPlanAnalysisTaskByParamsPlanID(paramsPlanID uint) (*models.Task, error)
|
||||
FindPlanAnalysisTaskByParamsPlanID(ctx context.Context, paramsPlanID uint) (*models.Task, error)
|
||||
// FindRunnablePlans 获取所有应执行的计划
|
||||
FindRunnablePlans() ([]*models.Plan, error)
|
||||
FindRunnablePlans(ctx context.Context) ([]*models.Plan, error)
|
||||
// FindInactivePlans 获取所有已禁用或已停止的计划
|
||||
FindInactivePlans() ([]*models.Plan, error)
|
||||
FindInactivePlans(ctx context.Context) ([]*models.Plan, error)
|
||||
|
||||
// FindPlanAnalysisTaskByPlanID 根据 PlanID 找到其关联的 'plan_analysis' 任务
|
||||
FindPlanAnalysisTaskByPlanID(planID uint) (*models.Task, error)
|
||||
FindPlanAnalysisTaskByPlanID(ctx context.Context, planID uint) (*models.Task, error)
|
||||
|
||||
// CreatePlanAnalysisTask 创建一个 plan_analysis 类型的任务并返回它
|
||||
CreatePlanAnalysisTask(plan *models.Plan) (*models.Task, error)
|
||||
CreatePlanAnalysisTask(ctx context.Context, plan *models.Plan) (*models.Task, error)
|
||||
|
||||
// FindPlansWithPendingTasks 查找所有正在执行的计划
|
||||
FindPlansWithPendingTasks() ([]*models.Plan, error)
|
||||
FindPlansWithPendingTasks(ctx context.Context) ([]*models.Plan, error)
|
||||
|
||||
// StopPlanTransactionally 停止一个计划的执行,包括更新状态、移除待执行任务和更新执行日志
|
||||
StopPlanTransactionally(planID uint) error
|
||||
StopPlanTransactionally(ctx context.Context, planID uint) error
|
||||
|
||||
// UpdatePlanStateAfterExecution 更新计划执行后的状态(计数和状态)
|
||||
UpdatePlanStateAfterExecution(planID uint, newCount uint, newStatus models.PlanStatus) error
|
||||
UpdatePlanStateAfterExecution(ctx context.Context, planID uint, newCount uint, newStatus models.PlanStatus) error
|
||||
}
|
||||
|
||||
// gormPlanRepository 是 PlanRepository 的 GORM 实现
|
||||
type gormPlanRepository struct {
|
||||
db *gorm.DB
|
||||
ctx context.Context
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
// NewGormPlanRepository 创建一个新的 PlanRepository GORM 实现实例
|
||||
func NewGormPlanRepository(db *gorm.DB) PlanRepository {
|
||||
func NewGormPlanRepository(ctx context.Context, db *gorm.DB) PlanRepository {
|
||||
return &gormPlanRepository{
|
||||
db: db,
|
||||
ctx: ctx,
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
// ListPlans 获取计划列表,支持过滤和分页
|
||||
func (r *gormPlanRepository) ListPlans(opts ListPlansOptions, page, pageSize int) ([]models.Plan, int64, error) {
|
||||
func (r *gormPlanRepository) ListPlans(ctx context.Context, opts ListPlansOptions, page, pageSize int) ([]models.Plan, int64, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "ListPlans")
|
||||
if page <= 0 || pageSize <= 0 {
|
||||
return nil, 0, ErrInvalidPagination
|
||||
}
|
||||
@@ -107,7 +114,7 @@ func (r *gormPlanRepository) ListPlans(opts ListPlansOptions, page, pageSize int
|
||||
var plans []models.Plan
|
||||
var total int64
|
||||
|
||||
query := r.db.Model(&models.Plan{})
|
||||
query := r.db.WithContext(repoCtx).Model(&models.Plan{})
|
||||
|
||||
switch opts.PlanType {
|
||||
case PlanTypeFilterCustom:
|
||||
@@ -132,10 +139,11 @@ func (r *gormPlanRepository) ListPlans(opts ListPlansOptions, page, pageSize int
|
||||
}
|
||||
|
||||
// GetBasicPlanByID 根据ID获取计划的基本信息,不包含子计划和任务详情
|
||||
func (r *gormPlanRepository) GetBasicPlanByID(id uint) (*models.Plan, error) {
|
||||
func (r *gormPlanRepository) GetBasicPlanByID(ctx context.Context, id uint) (*models.Plan, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "GetBasicPlanByID")
|
||||
var plan models.Plan
|
||||
// GORM 默认不会加载关联,除非使用 Preload,所以直接 First 即可满足要求
|
||||
result := r.db.First(&plan, id)
|
||||
result := r.db.WithContext(repoCtx).First(&plan, id)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
@@ -143,12 +151,13 @@ func (r *gormPlanRepository) GetBasicPlanByID(id uint) (*models.Plan, error) {
|
||||
}
|
||||
|
||||
// GetPlansByIDs 根据ID列表获取计划,不包含子计划和任务详情
|
||||
func (r *gormPlanRepository) GetPlansByIDs(ids []uint) ([]models.Plan, error) {
|
||||
func (r *gormPlanRepository) GetPlansByIDs(ctx context.Context, ids []uint) ([]models.Plan, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "GetPlansByIDs")
|
||||
var plans []models.Plan
|
||||
if len(ids) == 0 {
|
||||
return plans, nil
|
||||
}
|
||||
err := r.db.Where("id IN ?", ids).Find(&plans).Error
|
||||
err := r.db.WithContext(repoCtx).Where("id IN ?", ids).Find(&plans).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -156,11 +165,12 @@ func (r *gormPlanRepository) GetPlansByIDs(ids []uint) ([]models.Plan, error) {
|
||||
}
|
||||
|
||||
// GetPlanByID 根据ID获取计划,包含子计划和任务详情
|
||||
func (r *gormPlanRepository) GetPlanByID(id uint) (*models.Plan, error) {
|
||||
func (r *gormPlanRepository) GetPlanByID(ctx context.Context, id uint) (*models.Plan, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "GetPlanByID")
|
||||
var plan models.Plan
|
||||
|
||||
// 先获取基本计划信息
|
||||
result := r.db.First(&plan, id)
|
||||
result := r.db.WithContext(repoCtx).First(&plan, id)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
@@ -170,14 +180,14 @@ func (r *gormPlanRepository) GetPlanByID(id uint) (*models.Plan, error) {
|
||||
case models.PlanContentTypeSubPlans:
|
||||
// 加载子计划引用
|
||||
var subPlans []models.SubPlan
|
||||
result = r.db.Where("parent_plan_id = ?", plan.ID).Order("execution_order").Find(&subPlans)
|
||||
result = r.db.WithContext(repoCtx).Where("parent_plan_id = ?", plan.ID).Order("execution_order").Find(&subPlans)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
// 递归加载每个子计划的完整信息
|
||||
for i := range subPlans {
|
||||
childPlan, err := r.GetPlanByID(subPlans[i].ChildPlanID)
|
||||
childPlan, err := r.GetPlanByID(repoCtx, subPlans[i].ChildPlanID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -187,7 +197,7 @@ func (r *gormPlanRepository) GetPlanByID(id uint) (*models.Plan, error) {
|
||||
plan.SubPlans = subPlans
|
||||
case models.PlanContentTypeTasks:
|
||||
// 加载任务
|
||||
result = r.db.Preload("Tasks", func(taskDB *gorm.DB) *gorm.DB {
|
||||
result = r.db.WithContext(repoCtx).Preload("Tasks", func(taskDB *gorm.DB) *gorm.DB {
|
||||
return taskDB.Order("execution_order")
|
||||
}).First(&plan, id)
|
||||
if result.Error != nil {
|
||||
@@ -201,12 +211,14 @@ func (r *gormPlanRepository) GetPlanByID(id uint) (*models.Plan, error) {
|
||||
}
|
||||
|
||||
// CreatePlan 创建一个新的计划
|
||||
func (r *gormPlanRepository) CreatePlan(plan *models.Plan) error {
|
||||
return r.CreatePlanTx(r.db, plan)
|
||||
func (r *gormPlanRepository) CreatePlan(ctx context.Context, plan *models.Plan) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "CreatePlan")
|
||||
return r.CreatePlanTx(repoCtx, r.db, plan)
|
||||
}
|
||||
|
||||
// CreatePlanTx 在指定事务中创建一个新的计划
|
||||
func (r *gormPlanRepository) CreatePlanTx(tx *gorm.DB, plan *models.Plan) error {
|
||||
func (r *gormPlanRepository) CreatePlanTx(ctx context.Context, tx *gorm.DB, plan *models.Plan) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "CreatePlanTx")
|
||||
// 1. 前置校验
|
||||
if plan.ID != 0 {
|
||||
return ErrCreateWithNonZeroID
|
||||
@@ -239,7 +251,7 @@ func (r *gormPlanRepository) CreatePlanTx(tx *gorm.DB, plan *models.Plan) error
|
||||
|
||||
if len(ids) > 0 {
|
||||
var count int64
|
||||
if err := tx.Model(&models.Plan{}).Where("id IN ?", ids).Count(&count).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Model(&models.Plan{}).Where("id IN ?", ids).Count(&count).Error; err != nil {
|
||||
return fmt.Errorf("验证子计划存在性失败: %w", err)
|
||||
}
|
||||
if int(count) != len(ids) {
|
||||
@@ -251,13 +263,13 @@ func (r *gormPlanRepository) CreatePlanTx(tx *gorm.DB, plan *models.Plan) error
|
||||
// 2. 创建根计划
|
||||
// GORM 会自动处理关联的 Tasks (如果 ContentType 是 tasks 且 Task.ID 为 0),
|
||||
// 以及 Tasks 内部已经填充好的 Devices 关联。
|
||||
if err := tx.Create(plan).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Create(plan).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 3. 创建触发器Task
|
||||
// 关键修改:调用 createPlanAnalysisTask 并处理其返回的 Task 对象
|
||||
_, err := r.createPlanAnalysisTask(tx, plan)
|
||||
_, err := r.createPlanAnalysisTask(repoCtx, tx, plan)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -265,32 +277,36 @@ func (r *gormPlanRepository) CreatePlanTx(tx *gorm.DB, plan *models.Plan) error
|
||||
}
|
||||
|
||||
// UpdatePlan 更新计划
|
||||
func (r *gormPlanRepository) UpdatePlan(plan *models.Plan) error {
|
||||
return r.db.Save(plan).Error
|
||||
func (r *gormPlanRepository) UpdatePlan(ctx context.Context, plan *models.Plan) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "UpdatePlan")
|
||||
return r.db.WithContext(repoCtx).Save(plan).Error
|
||||
}
|
||||
|
||||
// UpdatePlanMetadataAndStructure 是更新计划元数据和结构的公共入口点
|
||||
func (r *gormPlanRepository) UpdatePlanMetadataAndStructure(plan *models.Plan) error {
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
return r.updatePlanMetadataAndStructureTx(tx, plan)
|
||||
func (r *gormPlanRepository) UpdatePlanMetadataAndStructure(ctx context.Context, plan *models.Plan) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "UpdatePlanMetadataAndStructure")
|
||||
return r.db.WithContext(repoCtx).Transaction(func(tx *gorm.DB) error {
|
||||
return r.updatePlanMetadataAndStructureTx(repoCtx, tx, plan)
|
||||
})
|
||||
}
|
||||
|
||||
// updatePlanMetadataAndStructureTx 在事务中协调整个更新过程
|
||||
func (r *gormPlanRepository) updatePlanMetadataAndStructureTx(tx *gorm.DB, plan *models.Plan) error {
|
||||
if err := r.validatePlanTree(tx, plan); err != nil {
|
||||
func (r *gormPlanRepository) updatePlanMetadataAndStructureTx(ctx context.Context, tx *gorm.DB, plan *models.Plan) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "updatePlanMetadataAndStructureTx")
|
||||
if err := r.validatePlanTree(repoCtx, tx, plan); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := r.reconcilePlanNode(tx, plan); err != nil {
|
||||
if err := r.reconcilePlanNode(repoCtx, tx, plan); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 更新Plan触发器
|
||||
return r.updatePlanAnalysisTask(tx, plan)
|
||||
return r.updatePlanAnalysisTask(repoCtx, tx, plan)
|
||||
}
|
||||
|
||||
// validatePlanTree 对整个计划树进行全面的只读健康检查
|
||||
func (r *gormPlanRepository) validatePlanTree(tx *gorm.DB, plan *models.Plan) error {
|
||||
func (r *gormPlanRepository) validatePlanTree(ctx context.Context, tx *gorm.DB, plan *models.Plan) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "validatePlanTree")
|
||||
// 1. 检查根节点
|
||||
if plan == nil || plan.ID == 0 {
|
||||
return ErrUpdateWithInvalidRoot
|
||||
@@ -319,7 +335,7 @@ func (r *gormPlanRepository) validatePlanTree(tx *gorm.DB, plan *models.Plan) er
|
||||
|
||||
if len(idsToCheck) > 0 {
|
||||
var count int64
|
||||
if err := tx.Model(&models.Plan{}).Where("id IN ?", idsToCheck).Count(&count).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Model(&models.Plan{}).Where("id IN ?", idsToCheck).Count(&count).Error; err != nil {
|
||||
return fmt.Errorf("检查计划存在性时出错: %w", err)
|
||||
}
|
||||
if int(count) != len(idsToCheck) {
|
||||
@@ -358,12 +374,13 @@ func validateNodeAndDetectCycles(plan *models.Plan, allIDs, recursionStack map[u
|
||||
}
|
||||
|
||||
// reconcilePlanNode 递归地同步数据库状态以匹配给定的计划节点
|
||||
func (r *gormPlanRepository) reconcilePlanNode(tx *gorm.DB, plan *models.Plan) error {
|
||||
func (r *gormPlanRepository) reconcilePlanNode(ctx context.Context, tx *gorm.DB, plan *models.Plan) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "reconcilePlanNode")
|
||||
if plan == nil {
|
||||
return nil
|
||||
}
|
||||
// 1. 更新节点本身的基础字段
|
||||
if err := tx.Model(plan).Select("Name", "Description", "ExecutionType", "ExecuteNum", "CronExpression", "ContentType").Updates(plan).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Model(plan).Select("Name", "Description", "ExecutionType", "ExecuteNum", "CronExpression", "ContentType").Updates(plan).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -371,26 +388,27 @@ func (r *gormPlanRepository) reconcilePlanNode(tx *gorm.DB, plan *models.Plan) e
|
||||
switch plan.ContentType {
|
||||
case models.PlanContentTypeTasks:
|
||||
// 清理旧的子计划关联
|
||||
if err := tx.Where("parent_plan_id = ?", plan.ID).Delete(&models.SubPlan{}).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Where("parent_plan_id = ?", plan.ID).Delete(&models.SubPlan{}).Error; err != nil {
|
||||
return fmt.Errorf("更新时清理旧的子计划关联失败: %w", err)
|
||||
}
|
||||
// 协调任务列表
|
||||
return r.reconcileTasks(tx, plan)
|
||||
return r.reconcileTasks(repoCtx, tx, plan)
|
||||
case models.PlanContentTypeSubPlans:
|
||||
// 清理旧的任务
|
||||
if err := tx.Where("plan_id = ?", plan.ID).Delete(&models.Task{}).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Where("plan_id = ?", plan.ID).Delete(&models.Task{}).Error; err != nil {
|
||||
return fmt.Errorf("更新时清理旧的任务失败: %w", err)
|
||||
}
|
||||
// 协调子计划关联
|
||||
return r.reconcileSubPlans(tx, plan)
|
||||
return r.reconcileSubPlans(repoCtx, tx, plan)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// reconcileTasks 精确同步任务列表
|
||||
func (r *gormPlanRepository) reconcileTasks(tx *gorm.DB, plan *models.Plan) error {
|
||||
func (r *gormPlanRepository) reconcileTasks(ctx context.Context, tx *gorm.DB, plan *models.Plan) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "reconcileTasks")
|
||||
var existingTasks []models.Task
|
||||
if err := tx.Where("plan_id = ?", plan.ID).Find(&existingTasks).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Where("plan_id = ?", plan.ID).Find(&existingTasks).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -403,12 +421,12 @@ func (r *gormPlanRepository) reconcileTasks(tx *gorm.DB, plan *models.Plan) erro
|
||||
task := &plan.Tasks[i]
|
||||
if task.ID == 0 {
|
||||
task.PlanID = plan.ID
|
||||
if err := tx.Create(task).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Create(task).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
delete(existingTaskMap, task.ID) // 从待删除map中移除
|
||||
if err := tx.Model(task).Updates(task).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Model(task).Updates(task).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -420,15 +438,16 @@ func (r *gormPlanRepository) reconcileTasks(tx *gorm.DB, plan *models.Plan) erro
|
||||
}
|
||||
|
||||
if len(tasksToDelete) > 0 {
|
||||
return r.deleteTasksTx(tx, tasksToDelete)
|
||||
return r.deleteTasksTx(repoCtx, tx, tasksToDelete)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// reconcileSubPlans 精确同步子计划关联并递归
|
||||
func (r *gormPlanRepository) reconcileSubPlans(tx *gorm.DB, plan *models.Plan) error {
|
||||
func (r *gormPlanRepository) reconcileSubPlans(ctx context.Context, tx *gorm.DB, plan *models.Plan) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "reconcileSubPlans")
|
||||
var existingLinks []models.SubPlan
|
||||
if err := tx.Where("parent_plan_id = ?", plan.ID).Find(&existingLinks).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Where("parent_plan_id = ?", plan.ID).Find(&existingLinks).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -441,12 +460,12 @@ func (r *gormPlanRepository) reconcileSubPlans(tx *gorm.DB, plan *models.Plan) e
|
||||
link := &plan.SubPlans[i]
|
||||
link.ParentPlanID = plan.ID
|
||||
if link.ID == 0 {
|
||||
if err := tx.Create(link).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Create(link).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
delete(existingLinkMap, link.ID) // 从待删除map中移除
|
||||
if err := tx.Model(link).Updates(link).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Model(link).Updates(link).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -458,7 +477,7 @@ func (r *gormPlanRepository) reconcileSubPlans(tx *gorm.DB, plan *models.Plan) e
|
||||
}
|
||||
|
||||
if len(linksToDelete) > 0 {
|
||||
if err := tx.Delete(&models.SubPlan{}, linksToDelete).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Delete(&models.SubPlan{}, linksToDelete).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -466,11 +485,12 @@ func (r *gormPlanRepository) reconcileSubPlans(tx *gorm.DB, plan *models.Plan) e
|
||||
}
|
||||
|
||||
// DeletePlan 根据ID删除计划,同时删除其关联的任务(非子任务)或子计划关联
|
||||
func (r *gormPlanRepository) DeletePlan(id uint) error {
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
func (r *gormPlanRepository) DeletePlan(ctx context.Context, id uint) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "DeletePlan")
|
||||
return r.db.WithContext(repoCtx).Transaction(func(tx *gorm.DB) error {
|
||||
// 1. 检查该计划是否是其他计划的子计划
|
||||
var count int64
|
||||
if err := tx.Model(&models.SubPlan{}).Where("child_plan_id = ?", id).Count(&count).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Model(&models.SubPlan{}).Where("child_plan_id = ?", id).Count(&count).Error; err != nil {
|
||||
return fmt.Errorf("检查计划是否为子计划失败: %w", err)
|
||||
}
|
||||
if count > 0 {
|
||||
@@ -479,7 +499,7 @@ func (r *gormPlanRepository) DeletePlan(id uint) error {
|
||||
|
||||
var plan models.Plan
|
||||
// 2. 获取计划以确定其内容类型
|
||||
if err := tx.First(&plan, id).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).First(&plan, id).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -487,18 +507,18 @@ func (r *gormPlanRepository) DeletePlan(id uint) error {
|
||||
switch plan.ContentType {
|
||||
case models.PlanContentTypeTasks:
|
||||
// 删除与此计划关联的所有非子任务
|
||||
if err := tx.Where("plan_id = ?", id).Delete(&models.Task{}).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Where("plan_id = ?", id).Delete(&models.Task{}).Error; err != nil {
|
||||
return fmt.Errorf("删除计划ID %d 的任务失败: %w", id, err)
|
||||
}
|
||||
case models.PlanContentTypeSubPlans:
|
||||
// 删除与此计划关联的所有子计划链接
|
||||
if err := tx.Where("parent_plan_id = ?", id).Delete(&models.SubPlan{}).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Where("parent_plan_id = ?", id).Delete(&models.SubPlan{}).Error; err != nil {
|
||||
return fmt.Errorf("删除计划ID %d 的子计划关联失败: %w", id, err)
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 删除计划本身
|
||||
if err := tx.Delete(&models.Plan{}, id).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Delete(&models.Plan{}, id).Error; err != nil {
|
||||
return fmt.Errorf("删除计划ID %d 失败: %w", id, err)
|
||||
}
|
||||
|
||||
@@ -507,17 +527,19 @@ func (r *gormPlanRepository) DeletePlan(id uint) error {
|
||||
}
|
||||
|
||||
// FlattenPlanTasks 递归展开计划,返回按执行顺序排列的所有任务列表
|
||||
func (r *gormPlanRepository) FlattenPlanTasks(planID uint) ([]models.Task, error) {
|
||||
plan, err := r.GetPlanByID(planID)
|
||||
func (r *gormPlanRepository) FlattenPlanTasks(ctx context.Context, planID uint) ([]models.Task, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "FlattenPlanTasks")
|
||||
plan, err := r.GetPlanByID(repoCtx, planID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("获取计划(ID: %d)失败: %w", planID, err)
|
||||
}
|
||||
|
||||
return r.flattenPlanTasksRecursive(plan)
|
||||
return r.flattenPlanTasksRecursive(repoCtx, plan)
|
||||
}
|
||||
|
||||
// flattenPlanTasksRecursive 递归展开计划的内部实现
|
||||
func (r *gormPlanRepository) flattenPlanTasksRecursive(plan *models.Plan) ([]models.Task, error) {
|
||||
func (r *gormPlanRepository) flattenPlanTasksRecursive(ctx context.Context, plan *models.Plan) ([]models.Task, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "flattenPlanTasksRecursive")
|
||||
var tasks []models.Task
|
||||
|
||||
switch plan.ContentType {
|
||||
@@ -535,10 +557,10 @@ func (r *gormPlanRepository) flattenPlanTasksRecursive(plan *models.Plan) ([]mod
|
||||
|
||||
// 确保子计划已经被加载
|
||||
if subPlan.ChildPlan != nil {
|
||||
subTasks, err = r.flattenPlanTasksRecursive(subPlan.ChildPlan)
|
||||
subTasks, err = r.flattenPlanTasksRecursive(repoCtx, subPlan.ChildPlan)
|
||||
} else {
|
||||
// 如果子计划未加载,则从数据库获取并递归展开
|
||||
subTasks, err = r.FlattenPlanTasks(subPlan.ChildPlanID)
|
||||
subTasks, err = r.FlattenPlanTasks(repoCtx, subPlan.ChildPlanID)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
@@ -556,22 +578,24 @@ func (r *gormPlanRepository) flattenPlanTasksRecursive(plan *models.Plan) ([]mod
|
||||
}
|
||||
|
||||
// DeleteTask 根据ID删除任务
|
||||
func (r *gormPlanRepository) DeleteTask(id int) error {
|
||||
func (r *gormPlanRepository) DeleteTask(ctx context.Context, id int) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "DeleteTask")
|
||||
// 使用事务确保操作的原子性
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
return r.deleteTasksTx(tx, []int{id})
|
||||
return r.db.WithContext(repoCtx).Transaction(func(tx *gorm.DB) error {
|
||||
return r.deleteTasksTx(repoCtx, tx, []int{id})
|
||||
})
|
||||
}
|
||||
|
||||
// deleteTasksTx 在事务中批量软删除任务,并物理删除其在关联表中的记录
|
||||
func (r *gormPlanRepository) deleteTasksTx(tx *gorm.DB, ids []int) error {
|
||||
func (r *gormPlanRepository) deleteTasksTx(ctx context.Context, tx *gorm.DB, ids []int) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "deleteTasksTx")
|
||||
if len(ids) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
// 检查是否有待执行任务引用了这些任务
|
||||
var pendingTaskCount int64
|
||||
if err := tx.Model(&models.PendingTask{}).Where("task_id IN ?", ids).Count(&pendingTaskCount).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Model(&models.PendingTask{}).Where("task_id IN ?", ids).Count(&pendingTaskCount).Error; err != nil {
|
||||
return fmt.Errorf("检查待执行任务时出错: %w", err)
|
||||
}
|
||||
|
||||
@@ -584,12 +608,12 @@ func (r *gormPlanRepository) deleteTasksTx(tx *gorm.DB, ids []int) error {
|
||||
|
||||
// 1. 直接、高效地从关联表中物理删除所有相关记录
|
||||
// 这是最关键的优化,避免了不必要的查询和循环
|
||||
if err := tx.Where("task_id IN ?", ids).Delete(&models.DeviceTask{}).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Where("task_id IN ?", ids).Delete(&models.DeviceTask{}).Error; err != nil {
|
||||
return fmt.Errorf("清理任务的设备关联失败: %w", err)
|
||||
}
|
||||
|
||||
// 2. 对任务本身进行软删除
|
||||
result := tx.Delete(&models.Task{}, ids)
|
||||
result := tx.WithContext(repoCtx).Delete(&models.Task{}, ids)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
@@ -603,13 +627,15 @@ func (r *gormPlanRepository) deleteTasksTx(tx *gorm.DB, ids []int) error {
|
||||
}
|
||||
|
||||
// FindPlanAnalysisTaskByParamsPlanID 根据Parameters中的ParamsPlanID字段值查找TaskPlanAnalysis类型的Task
|
||||
func (r *gormPlanRepository) FindPlanAnalysisTaskByParamsPlanID(paramsPlanID uint) (*models.Task, error) {
|
||||
return r.findPlanAnalysisTask(r.db, paramsPlanID)
|
||||
func (r *gormPlanRepository) FindPlanAnalysisTaskByParamsPlanID(ctx context.Context, paramsPlanID uint) (*models.Task, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "FindPlanAnalysisTaskByParamsPlanID")
|
||||
return r.findPlanAnalysisTask(repoCtx, r.db, paramsPlanID)
|
||||
}
|
||||
|
||||
// createPlanAnalysisTask 用于创建一个TaskPlanAnalysis类型的Task
|
||||
// 关键修改:Task.PlanID 设置为 0,实际 PlanID 存储在 Parameters 中,并返回创建的 Task
|
||||
func (r *gormPlanRepository) createPlanAnalysisTask(tx *gorm.DB, plan *models.Plan) (*models.Task, error) {
|
||||
func (r *gormPlanRepository) createPlanAnalysisTask(ctx context.Context, tx *gorm.DB, plan *models.Plan) (*models.Task, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "createPlanAnalysisTask")
|
||||
m := map[string]interface{}{
|
||||
models.ParamsPlanID: plan.ID,
|
||||
}
|
||||
@@ -627,22 +653,23 @@ func (r *gormPlanRepository) createPlanAnalysisTask(tx *gorm.DB, plan *models.Pl
|
||||
Parameters: datatypes.JSON(parameters),
|
||||
}
|
||||
|
||||
if err := tx.Create(task).Error; err != nil {
|
||||
if err := tx.WithContext(repoCtx).Create(task).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return task, nil
|
||||
}
|
||||
|
||||
// updatePlanAnalysisTask 使用更安全的方式更新触发器任务
|
||||
func (r *gormPlanRepository) updatePlanAnalysisTask(tx *gorm.DB, plan *models.Plan) error {
|
||||
task, err := r.findPlanAnalysisTask(tx, plan.ID)
|
||||
func (r *gormPlanRepository) updatePlanAnalysisTask(ctx context.Context, tx *gorm.DB, plan *models.Plan) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "updatePlanAnalysisTask")
|
||||
task, err := r.findPlanAnalysisTask(repoCtx, tx, plan.ID)
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return fmt.Errorf("查找现有计划分析任务失败: %w", err)
|
||||
}
|
||||
|
||||
// 如果触发器任务不存在,则创建一个
|
||||
if task == nil {
|
||||
_, err := r.createPlanAnalysisTask(tx, plan)
|
||||
_, err := r.createPlanAnalysisTask(repoCtx, tx, plan)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -650,24 +677,26 @@ func (r *gormPlanRepository) updatePlanAnalysisTask(tx *gorm.DB, plan *models.Pl
|
||||
task.Name = fmt.Sprintf("'%s'计划触发器", plan.Name)
|
||||
task.Description = fmt.Sprintf("计划名: %s, 计划ID: %d", plan.Name, plan.ID)
|
||||
|
||||
return tx.Save(task).Error
|
||||
return tx.WithContext(repoCtx).Save(task).Error
|
||||
}
|
||||
|
||||
func (r *gormPlanRepository) FindRunnablePlans() ([]*models.Plan, error) {
|
||||
func (r *gormPlanRepository) FindRunnablePlans(ctx context.Context) ([]*models.Plan, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "FindRunnablePlans")
|
||||
var plans []*models.Plan
|
||||
err := r.db.
|
||||
err := r.db.WithContext(repoCtx).
|
||||
Where("status = ?", models.PlanStatusEnabled).
|
||||
Where(
|
||||
r.db.Where("execution_type = ?", models.PlanExecutionTypeManual).
|
||||
r.db.WithContext(repoCtx).Where("execution_type = ?", models.PlanExecutionTypeManual).
|
||||
Or("execution_type = ? AND (execute_num = 0 OR execute_count < execute_num)", models.PlanExecutionTypeAutomatic),
|
||||
).
|
||||
Find(&plans).Error
|
||||
return plans, err
|
||||
}
|
||||
|
||||
func (r *gormPlanRepository) FindInactivePlans() ([]*models.Plan, error) {
|
||||
func (r *gormPlanRepository) FindInactivePlans(ctx context.Context) ([]*models.Plan, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "FindInactivePlans")
|
||||
var plans []*models.Plan
|
||||
err := r.db.
|
||||
err := r.db.WithContext(repoCtx).
|
||||
Where("status != ?", models.PlanStatusEnabled).
|
||||
Find(&plans).Error
|
||||
return plans, err
|
||||
@@ -675,9 +704,10 @@ func (r *gormPlanRepository) FindInactivePlans() ([]*models.Plan, error) {
|
||||
|
||||
// findPlanAnalysisTask 是一个内部使用的、更高效的查找方法
|
||||
// 关键修改:通过查询 parameters JSON 字段来查找
|
||||
func (r *gormPlanRepository) findPlanAnalysisTask(tx *gorm.DB, planID uint) (*models.Task, error) {
|
||||
func (r *gormPlanRepository) findPlanAnalysisTask(ctx context.Context, tx *gorm.DB, planID uint) (*models.Task, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "findPlanAnalysisTask")
|
||||
var task models.Task
|
||||
err := tx.Where("type = ? AND parameters->>'plan_id' = ?", models.TaskPlanAnalysis, fmt.Sprintf("%d", planID)).First(&task).Error
|
||||
err := tx.WithContext(repoCtx).Where("type = ? AND parameters->>'plan_id' = ?", models.TaskPlanAnalysis, fmt.Sprintf("%d", planID)).First(&task).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, nil // 未找到不是错误,返回nil, nil
|
||||
}
|
||||
@@ -686,28 +716,31 @@ func (r *gormPlanRepository) findPlanAnalysisTask(tx *gorm.DB, planID uint) (*mo
|
||||
|
||||
// FindPlanAnalysisTaskByPlanID 是暴露给外部的公共方法
|
||||
// 关键修改:通过查询 parameters JSON 字段来查找
|
||||
func (r *gormPlanRepository) FindPlanAnalysisTaskByPlanID(planID uint) (*models.Task, error) {
|
||||
return r.findPlanAnalysisTask(r.db, planID)
|
||||
func (r *gormPlanRepository) FindPlanAnalysisTaskByPlanID(ctx context.Context, planID uint) (*models.Task, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "FindPlanAnalysisTaskByPlanID")
|
||||
return r.findPlanAnalysisTask(repoCtx, r.db, planID)
|
||||
}
|
||||
|
||||
// CreatePlanAnalysisTask 创建一个 plan_analysis 类型的任务并返回它
|
||||
// 这个方法是公开的,主要由 TaskManager 在发现触发器任务定义丢失时调用。
|
||||
func (r *gormPlanRepository) CreatePlanAnalysisTask(plan *models.Plan) (*models.Task, error) {
|
||||
func (r *gormPlanRepository) CreatePlanAnalysisTask(ctx context.Context, plan *models.Plan) (*models.Task, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "CreatePlanAnalysisTask")
|
||||
var createdTask *models.Task
|
||||
err := r.db.Transaction(func(tx *gorm.DB) error {
|
||||
err := r.db.WithContext(repoCtx).Transaction(func(tx *gorm.DB) error {
|
||||
var err error
|
||||
createdTask, err = r.createPlanAnalysisTask(tx, plan)
|
||||
createdTask, err = r.createPlanAnalysisTask(repoCtx, tx, plan)
|
||||
return err
|
||||
})
|
||||
return createdTask, err
|
||||
}
|
||||
|
||||
// FindPlansWithPendingTasks 查找所有正在执行的计划
|
||||
func (r *gormPlanRepository) FindPlansWithPendingTasks() ([]*models.Plan, error) {
|
||||
func (r *gormPlanRepository) FindPlansWithPendingTasks(ctx context.Context) ([]*models.Plan, error) {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "FindPlansWithPendingTasks")
|
||||
var plans []*models.Plan
|
||||
|
||||
// 关联 pending_tasks, task_execution_logs, tasks 表来查找符合条件的计划
|
||||
err := r.db.Table("plans").
|
||||
err := r.db.WithContext(repoCtx).Table("plans").
|
||||
Joins("JOIN tasks ON plans.id = tasks.plan_id").
|
||||
Joins("JOIN task_execution_logs ON tasks.id = task_execution_logs.task_id").
|
||||
Joins("JOIN pending_tasks ON task_execution_logs.id = pending_tasks.task_execution_log_id").
|
||||
@@ -718,20 +751,21 @@ func (r *gormPlanRepository) FindPlansWithPendingTasks() ([]*models.Plan, error)
|
||||
}
|
||||
|
||||
// StopPlanTransactionally 停止一个计划的执行,包括更新状态、移除待执行任务和更新执行日志。
|
||||
func (r *gormPlanRepository) StopPlanTransactionally(planID uint) error {
|
||||
return r.db.Transaction(func(tx *gorm.DB) error {
|
||||
func (r *gormPlanRepository) StopPlanTransactionally(ctx context.Context, planID uint) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "StopPlanTransactionally")
|
||||
return r.db.WithContext(repoCtx).Transaction(func(tx *gorm.DB) error {
|
||||
// 使用事务创建新的仓库实例,确保所有操作都在同一个事务中
|
||||
planRepoTx := NewGormPlanRepository(tx)
|
||||
executionLogRepoTx := NewGormExecutionLogRepository(tx)
|
||||
pendingTaskRepoTx := NewGormPendingTaskRepository(tx)
|
||||
planRepoTx := NewGormPlanRepository(repoCtx, tx)
|
||||
executionLogRepoTx := NewGormExecutionLogRepository(repoCtx, tx)
|
||||
pendingTaskRepoTx := NewGormPendingTaskRepository(repoCtx, tx)
|
||||
|
||||
// 1. 更新计划状态为“已停止”
|
||||
if err := planRepoTx.UpdatePlanStatus(planID, models.PlanStatusDisabled); err != nil {
|
||||
if err := planRepoTx.UpdatePlanStatus(repoCtx, planID, models.PlanStatusDisabled); err != nil {
|
||||
return fmt.Errorf("更新计划 #%d 状态为 '已停止' 失败: %w", planID, err)
|
||||
}
|
||||
|
||||
// 2. 查找当前正在进行的计划执行日志
|
||||
planLog, err := executionLogRepoTx.FindInProgressPlanExecutionLogByPlanID(planID)
|
||||
planLog, err := executionLogRepoTx.FindInProgressPlanExecutionLogByPlanID(repoCtx, planID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("查找计划 #%d 正在进行的执行日志失败: %w", planID, err)
|
||||
}
|
||||
@@ -742,7 +776,7 @@ func (r *gormPlanRepository) StopPlanTransactionally(planID uint) error {
|
||||
}
|
||||
|
||||
// 3. 查找所有需要被取消的任务执行日志
|
||||
taskLogs, err := executionLogRepoTx.FindIncompleteTaskExecutionLogsByPlanLogID(planLog.ID)
|
||||
taskLogs, err := executionLogRepoTx.FindIncompleteTaskExecutionLogsByPlanLogID(repoCtx, planLog.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("查找计划执行日志 #%d 下未完成的任务日志失败: %w", planLog.ID, err)
|
||||
}
|
||||
@@ -754,12 +788,12 @@ func (r *gormPlanRepository) StopPlanTransactionally(planID uint) error {
|
||||
}
|
||||
|
||||
// 3.1 批量更新任务执行日志状态为“已取消”
|
||||
if err := executionLogRepoTx.UpdateTaskExecutionLogStatusByIDs(taskLogIDs, models.ExecutionStatusCancelled); err != nil {
|
||||
if err := executionLogRepoTx.UpdateTaskExecutionLogStatusByIDs(repoCtx, taskLogIDs, models.ExecutionStatusCancelled); err != nil {
|
||||
return fmt.Errorf("批量更新任务执行日志状态为 '已取消' 失败: %w", err)
|
||||
}
|
||||
|
||||
// 3.2 查找并删除待执行队列中对应的任务
|
||||
pendingTasks, err := pendingTaskRepoTx.FindPendingTasksByTaskLogIDs(taskLogIDs)
|
||||
pendingTasks, err := pendingTaskRepoTx.FindPendingTasksByTaskLogIDs(repoCtx, taskLogIDs)
|
||||
if err != nil {
|
||||
return fmt.Errorf("查找计划执行日志 #%d 下对应的待执行任务失败: %w", planLog.ID, err)
|
||||
}
|
||||
@@ -769,14 +803,14 @@ func (r *gormPlanRepository) StopPlanTransactionally(planID uint) error {
|
||||
for _, pt := range pendingTasks {
|
||||
pendingTaskIDs = append(pendingTaskIDs, pt.ID)
|
||||
}
|
||||
if err := pendingTaskRepoTx.DeletePendingTasksByIDs(pendingTaskIDs); err != nil {
|
||||
if err := pendingTaskRepoTx.DeletePendingTasksByIDs(repoCtx, pendingTaskIDs); err != nil {
|
||||
return fmt.Errorf("批量删除待执行任务失败: %w", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 4. 更新计划执行历史的总状态为“失败”
|
||||
if err := executionLogRepoTx.UpdatePlanExecutionLogStatus(planLog.ID, models.ExecutionStatusFailed); err != nil {
|
||||
if err := executionLogRepoTx.UpdatePlanExecutionLogStatus(repoCtx, planLog.ID, models.ExecutionStatusFailed); err != nil {
|
||||
return fmt.Errorf("更新计划执行日志 #%d 状态为 '失败' 失败: %w", planLog.ID, err)
|
||||
}
|
||||
|
||||
@@ -785,8 +819,9 @@ func (r *gormPlanRepository) StopPlanTransactionally(planID uint) error {
|
||||
}
|
||||
|
||||
// UpdatePlanStatus 更新指定计划的状态
|
||||
func (r *gormPlanRepository) UpdatePlanStatus(id uint, status models.PlanStatus) error {
|
||||
result := r.db.Model(&models.Plan{}).Where("id = ?", id).Update("status", status)
|
||||
func (r *gormPlanRepository) UpdatePlanStatus(ctx context.Context, id uint, status models.PlanStatus) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "UpdatePlanStatus")
|
||||
result := r.db.WithContext(repoCtx).Model(&models.Plan{}).Where("id = ?", id).Update("status", status)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
@@ -796,16 +831,18 @@ func (r *gormPlanRepository) UpdatePlanStatus(id uint, status models.PlanStatus)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *gormPlanRepository) UpdatePlanStateAfterExecution(planID uint, newCount uint, newStatus models.PlanStatus) error {
|
||||
return r.db.Model(&models.Plan{}).Where("id = ?", planID).Updates(map[string]interface{}{
|
||||
func (r *gormPlanRepository) UpdatePlanStateAfterExecution(ctx context.Context, planID uint, newCount uint, newStatus models.PlanStatus) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "UpdatePlanStateAfterExecution")
|
||||
return r.db.WithContext(repoCtx).Model(&models.Plan{}).Where("id = ?", planID).Updates(map[string]interface{}{
|
||||
"execute_count": newCount,
|
||||
"status": newStatus,
|
||||
}).Error
|
||||
}
|
||||
|
||||
// UpdateExecuteCount 更新指定计划的执行计数
|
||||
func (r *gormPlanRepository) UpdateExecuteCount(id uint, count uint) error {
|
||||
result := r.db.Model(&models.Plan{}).Where("id = ?", id).Update("execute_count", count)
|
||||
func (r *gormPlanRepository) UpdateExecuteCount(ctx context.Context, id uint, count uint) error {
|
||||
repoCtx := logs.AddFuncName(ctx, r.ctx, "UpdateExecuteCount")
|
||||
result := r.db.WithContext(repoCtx).Model(&models.Plan{}).Where("id = ?", id).Update("execute_count", count)
|
||||
if result.Error != nil {
|
||||
return result.Error
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user