Files
pig-farm-controller/internal/infra/repository/plan_repository.go

96 lines
2.9 KiB
Go
Raw Normal View History

2025-09-13 13:04:19 +08:00
package repository
import (
2025-09-13 14:53:31 +08:00
"fmt"
2025-09-13 13:04:19 +08:00
"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
"gorm.io/gorm"
)
// PlanRepository 定义了与计划模型相关的数据库操作接口
// 这是为了让业务逻辑层依赖于抽象,而不是具体的数据库实现
type PlanRepository interface {
// ListBasicPlans 获取所有计划的基本信息,不包含子计划和任务详情
ListBasicPlans() ([]models.Plan, error)
// GetBasicPlanByID 根据ID获取计划的基本信息不包含子计划和任务详情
GetBasicPlanByID(id uint) (*models.Plan, error)
}
// gormPlanRepository 是 PlanRepository 的 GORM 实现
type gormPlanRepository struct {
db *gorm.DB
}
// NewGormPlanRepository 创建一个新的 PlanRepository GORM 实现实例
func NewGormPlanRepository(db *gorm.DB) PlanRepository {
return &gormPlanRepository{
db: db,
}
}
// ListBasicPlans 获取所有计划的基本信息,不包含子计划和任务详情
func (r *gormPlanRepository) ListBasicPlans() ([]models.Plan, error) {
var plans []models.Plan
// GORM 默认不会加载关联,除非使用 Preload所以直接 Find 即可满足要求
result := r.db.Find(&plans)
if result.Error != nil {
return nil, result.Error
}
return plans, nil
}
// GetBasicPlanByID 根据ID获取计划的基本信息不包含子计划和任务详情
func (r *gormPlanRepository) GetBasicPlanByID(id uint) (*models.Plan, error) {
var plan models.Plan
// GORM 默认不会加载关联,除非使用 Preload所以直接 First 即可满足要求
result := r.db.First(&plan, id)
if result.Error != nil {
return nil, result.Error
}
return &plan, nil
}
2025-09-13 14:53:31 +08:00
// GetPlanByID 根据ID获取计划包含子计划和任务详情
func (r *gormPlanRepository) GetPlanByID(id uint) (*models.Plan, error) {
var plan models.Plan
// 先获取基本计划信息
result := r.db.First(&plan, id)
if result.Error != nil {
return nil, result.Error
}
// 根据内容类型加载关联数据
switch plan.ContentType {
case models.PlanContentTypeSubPlans:
// 加载子计划引用
var subPlans []models.SubPlan
result = r.db.Where("parent_plan_id = ?", plan.ID).Order("order").Find(&subPlans)
if result.Error != nil {
return nil, result.Error
}
// 递归加载每个子计划的完整信息
for i := range subPlans {
// 递归调用确保子计划数据可以被获取
// 注意SubPlan结构体中没有ChildPlan字段所以这里只是递归获取确保数据完整性
childPlan, err := r.GetPlanByID(subPlans[i].ChildPlanID)
if err != nil {
return nil, err
}
subPlans[i].ChildPlan = childPlan
}
plan.SubPlans = subPlans
case models.PlanContentTypeTasks:
// 加载任务
result = r.db.Preload("Tasks", func(taskDB *gorm.DB) *gorm.DB {
return taskDB.Order("order")
}).Find(&plan)
default:
return nil, fmt.Errorf("未知的计划内容类型: %v; 计划ID: %v", plan.ContentType, plan.ID)
}
return &plan, nil
}