实现删除计划
This commit is contained in:
		| @@ -10,12 +10,13 @@ import ( | |||||||
|  |  | ||||||
| // 定义仓库层可导出的公共错误 | // 定义仓库层可导出的公共错误 | ||||||
| var ( | var ( | ||||||
| 	ErrUpdateWithInvalidRoot   = errors.New("更新操作的目标根计划无效或ID为0") | 	ErrUpdateWithInvalidRoot    = errors.New("更新操作的目标根计划无效或ID为0") | ||||||
| 	ErrNewSubPlanInUpdate      = errors.New("计划树中包含一个ID为0的新子计划,更新操作只允许关联已存在的计划") | 	ErrNewSubPlanInUpdate       = errors.New("计划树中包含一个ID为0的新子计划,更新操作只允许关联已存在的计划") | ||||||
| 	ErrNodeDoesNotExist        = errors.New("计划树中包含一个或多个在数据库中不存在的计划") | 	ErrNodeDoesNotExist         = errors.New("计划树中包含一个或多个在数据库中不存在的计划") | ||||||
| 	ErrCreateWithNonZeroID     = errors.New("创建操作的计划ID必须为0") | 	ErrCreateWithNonZeroID      = errors.New("创建操作的计划ID必须为0") | ||||||
| 	ErrSubPlanIDIsZeroOnCreate = errors.New("子计划ID为0,创建操作只允许关联已存在的计划") | 	ErrSubPlanIDIsZeroOnCreate  = errors.New("子计划ID为0,创建操作只允许关联已存在的计划") | ||||||
| 	ErrMixedContent            = errors.New("计划不能同时包含任务和子计划") | 	ErrMixedContent             = errors.New("计划不能同时包含任务和子计划") | ||||||
|  | 	ErrDeleteWithReferencedPlan = errors.New("禁止删除正在被引用的计划") | ||||||
| ) | ) | ||||||
|  |  | ||||||
| // PlanRepository 定义了与计划模型相关的数据库操作接口 | // PlanRepository 定义了与计划模型相关的数据库操作接口 | ||||||
| @@ -27,10 +28,12 @@ type PlanRepository interface { | |||||||
| 	GetBasicPlanByID(id uint) (*models.Plan, error) | 	GetBasicPlanByID(id uint) (*models.Plan, error) | ||||||
| 	// GetPlanByID 根据ID获取计划,包含子计划和任务详情 | 	// GetPlanByID 根据ID获取计划,包含子计划和任务详情 | ||||||
| 	GetPlanByID(id uint) (*models.Plan, error) | 	GetPlanByID(id uint) (*models.Plan, error) | ||||||
| 	// Create 创建一个新的计划 | 	// CreatePlan 创建一个新的计划 | ||||||
| 	Create(plan *models.Plan) error | 	CreatePlan(plan *models.Plan) error | ||||||
| 	// UpdatePlan 更新计划,包括子计划和任务 | 	// UpdatePlan 更新计划,包括子计划和任务 | ||||||
| 	UpdatePlan(plan *models.Plan) error | 	UpdatePlan(plan *models.Plan) error | ||||||
|  | 	// DeletePlan 根据ID删除计划,同时删除其关联的任务(非子任务)或子计划关联 | ||||||
|  | 	DeletePlan(id uint) error | ||||||
| } | } | ||||||
|  |  | ||||||
| // gormPlanRepository 是 PlanRepository 的 GORM 实现 | // gormPlanRepository 是 PlanRepository 的 GORM 实现 | ||||||
| @@ -112,8 +115,8 @@ func (r *gormPlanRepository) GetPlanByID(id uint) (*models.Plan, error) { | |||||||
| 	return &plan, nil | 	return &plan, nil | ||||||
| } | } | ||||||
|  |  | ||||||
| // Create 创建一个新的计划 | // CreatePlan 创建一个新的计划 | ||||||
| func (r *gormPlanRepository) Create(plan *models.Plan) error { | func (r *gormPlanRepository) CreatePlan(plan *models.Plan) error { | ||||||
| 	return r.db.Transaction(func(tx *gorm.DB) error { | 	return r.db.Transaction(func(tx *gorm.DB) error { | ||||||
| 		// 1. 前置校验 | 		// 1. 前置校验 | ||||||
| 		if plan.ID != 0 { | 		if plan.ID != 0 { | ||||||
| @@ -362,4 +365,43 @@ func (r *gormPlanRepository) reconcileSubPlans(tx *gorm.DB, plan *models.Plan) e | |||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  |  | ||||||
| /// ABC | // DeletePlan 根据ID删除计划,同时删除其关联的任务(非子任务)或子计划关联 | ||||||
|  | func (r *gormPlanRepository) DeletePlan(id uint) error { | ||||||
|  | 	return r.db.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 { | ||||||
|  | 			return fmt.Errorf("检查计划是否为子计划失败: %w", err) | ||||||
|  | 		} | ||||||
|  | 		if count > 0 { | ||||||
|  | 			return ErrDeleteWithReferencedPlan | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		var plan models.Plan | ||||||
|  | 		// 2. 获取计划以确定其内容类型 | ||||||
|  | 		if err := tx.First(&plan, id).Error; err != nil { | ||||||
|  | 			return err | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// 3. 根据内容类型删除关联数据 | ||||||
|  | 		switch plan.ContentType { | ||||||
|  | 		case models.PlanContentTypeTasks: | ||||||
|  | 			// 删除与此计划关联的所有非子任务 | ||||||
|  | 			if err := tx.Where("plan_id = ? AND parent_task_id IS NULL", 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 { | ||||||
|  | 				return fmt.Errorf("删除计划ID %d 的子计划关联失败: %w", id, err) | ||||||
|  | 			} | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		// 4. 删除计划本身 | ||||||
|  | 		if err := tx.Delete(&models.Plan{}, id).Error; err != nil { | ||||||
|  | 			return fmt.Errorf("删除计划ID %d 失败: %w", id, err) | ||||||
|  | 		} | ||||||
|  |  | ||||||
|  | 		return nil | ||||||
|  | 	}) | ||||||
|  | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user