96 lines
2.9 KiB
Go
96 lines
2.9 KiB
Go
package repository
|
||
|
||
import (
|
||
"fmt"
|
||
|
||
"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
|
||
}
|
||
|
||
// 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
|
||
}
|