package repository import ( "context" "errors" "time" "git.huangwc.com/pig/pig-farm-controller/internal/infra/logs" "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "gorm.io/gorm" ) // PigSickLogListOptions 定义了查询病猪日志时的可选参数 type PigSickLogListOptions struct { PigBatchID *uint PenID *uint Reason *models.PigBatchSickPigReasonType TreatmentLocation *models.PigBatchSickPigTreatmentLocation OperatorID *uint StartTime *time.Time // 基于 happened_at 字段 EndTime *time.Time // 基于 happened_at 字段 OrderBy string // 例如 "happened_at desc" } // PigSickLogRepository 定义了与病猪日志模型相关的数据库操作接口。 type PigSickLogRepository interface { // CreatePigSickLog 创建一条新的病猪日志记录 CreatePigSickLog(ctx context.Context, log *models.PigSickLog) error CreatePigSickLogTx(ctx context.Context, tx *gorm.DB, log *models.PigSickLog) error // GetLastLogByBatchTx 在事务中获取指定批次和猪栏的最新一条 PigSickLog 记录 GetLastLogByBatchTx(ctx context.Context, tx *gorm.DB, batchID uint) (*models.PigSickLog, error) // ListPigSickLogs 支持分页和过滤的病猪日志列表查询 ListPigSickLogs(ctx context.Context, opts PigSickLogListOptions, page, pageSize int) ([]models.PigSickLog, int64, error) } // gormPigSickLogRepository 是 PigSickLogRepository 接口的 GORM 实现。 type gormPigSickLogRepository struct { ctx context.Context db *gorm.DB } // NewGormPigSickLogRepository 创建一个新的 PigSickLogRepository GORM 实现实例。 func NewGormPigSickLogRepository(ctx context.Context, db *gorm.DB) PigSickLogRepository { return &gormPigSickLogRepository{ctx: ctx, db: db} } // CreatePigSickLog 创建一条新的病猪日志记录 func (r *gormPigSickLogRepository) CreatePigSickLog(ctx context.Context, log *models.PigSickLog) error { repoCtx := logs.AddFuncName(ctx, r.ctx, "CreatePigSickLog") return r.CreatePigSickLogTx(repoCtx, r.db, log) } func (r *gormPigSickLogRepository) CreatePigSickLogTx(ctx context.Context, tx *gorm.DB, log *models.PigSickLog) error { repoCtx := logs.AddFuncName(ctx, r.ctx, "CreatePigSickLogTx") return tx.WithContext(repoCtx).Create(log).Error } // GetLastLogByBatchTx 在事务中获取指定批次和猪栏的最新一条 PigSickLog 记录 func (r *gormPigSickLogRepository) GetLastLogByBatchTx(ctx context.Context, tx *gorm.DB, batchID uint) (*models.PigSickLog, error) { repoCtx := logs.AddFuncName(ctx, r.ctx, "GetLastLogByBatchTx") var lastLog models.PigSickLog err := tx.WithContext(repoCtx). Where("pig_batch_id = ?", batchID). Order("happened_at DESC"). // 按时间降序排列 First(&lastLog).Error // 获取第一条记录 (即最新一条) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { return nil, gorm.ErrRecordNotFound // 明确返回记录未找到错误 } return nil, err } return &lastLog, nil } // ListPigSickLogs 实现了分页和过滤查询病猪日志的功能 func (r *gormPigSickLogRepository) ListPigSickLogs(ctx context.Context, opts PigSickLogListOptions, page, pageSize int) ([]models.PigSickLog, int64, error) { repoCtx := logs.AddFuncName(ctx, r.ctx, "ListPigSickLogs") if page <= 0 || pageSize <= 0 { return nil, 0, ErrInvalidPagination } var results []models.PigSickLog var total int64 query := r.db.WithContext(repoCtx).Model(&models.PigSickLog{}) if opts.PigBatchID != nil { query = query.Where("pig_batch_id = ?", *opts.PigBatchID) } if opts.PenID != nil { query = query.Where("pen_id = ?", *opts.PenID) } if opts.Reason != nil { query = query.Where("reason = ?", *opts.Reason) } if opts.TreatmentLocation != nil { query = query.Where("treatment_location = ?", *opts.TreatmentLocation) } if opts.OperatorID != nil { query = query.Where("operator_id = ?", *opts.OperatorID) } if opts.StartTime != nil { query = query.Where("happened_at >= ?", *opts.StartTime) } if opts.EndTime != nil { query = query.Where("happened_at <= ?", *opts.EndTime) } if err := query.Count(&total).Error; err != nil { return nil, 0, err } orderBy := "happened_at DESC" if opts.OrderBy != "" { orderBy = opts.OrderBy } query = query.Order(orderBy) offset := (page - 1) * pageSize err := query.Limit(pageSize).Offset(offset).Find(&results).Error return results, total, err }