diff --git a/internal/domain/pig/pig_batch_service_pig_sick.go b/internal/domain/pig/pig_batch_service_pig_sick.go index fecac92..2897268 100644 --- a/internal/domain/pig/pig_batch_service_pig_sick.go +++ b/internal/domain/pig/pig_batch_service_pig_sick.go @@ -1,20 +1,87 @@ package pig import ( + "errors" + "fmt" "time" "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" + "gorm.io/gorm" ) // RecordSickPigs 记录新增病猪事件。 func (s *pigBatchService) RecordSickPigs(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error { - // 1. 检查批次是否活跃 + if quantity <= 0 { + return errors.New("新增病猪数量必须大于0") + } - // 2. 检查猪栏是否关联 + var err error + // 1. 开启事务 + err = s.uow.ExecuteInTransaction(func(tx *gorm.DB) error { + // 1.1 检查批次是否活跃 + batch, err := s.pigBatchRepo.GetPigBatchByIDTx(tx, batchID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return ErrPigBatchNotFound + } + return fmt.Errorf("获取批次 %d 失败: %w", batchID, err) + } + if !batch.IsActive() { + return fmt.Errorf("批次 %d 不活跃,无法记录病猪事件", batchID) + } - // 3. 检查剩余健康猪不能少于即将转化的病猪数量 + // 1.2 检查猪栏是否关联 + pen, err := s.transferSvc.GetPenByID(tx, penID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return ErrPenNotFound + } + return fmt.Errorf("获取猪栏 %d 失败: %w", penID, err) + } + if pen.PigBatchID == nil || *pen.PigBatchID != batchID { + return fmt.Errorf("猪栏 %d 未与批次 %d 关联", penID, batchID) + } - // 4. 创建病猪日志 + // 1.3 检查剩余健康猪不能少于即将转化的病猪数量 + totalPigsInBatch, err := s.getCurrentPigQuantityTx(tx, batchID) + if err != nil { + return fmt.Errorf("获取批次 %d 总猪只数量失败: %w", batchID, err) + } + + currentSickPigs, err := s.sickSvc.GetCurrentSickPigCount(tx, batchID) + if err != nil { + return fmt.Errorf("获取批次 %d 当前病猪数量失败: %w", batchID, err) + } + + healthyPigs := totalPigsInBatch - currentSickPigs + if healthyPigs < quantity { + return fmt.Errorf("健康猪数量不足,当前健康猪 %d 头,尝试记录病猪 %d 头", healthyPigs, quantity) + } + + // 1.4 创建病猪日志 + sickLog := &models.PigSickLog{ + PigBatchID: batchID, + PenID: penID, + ChangeCount: quantity, // 新增病猪,ChangeCount 为正数 + Reason: models.SickPigReasonTypeIllness, + TreatmentLocation: treatmentLocation, + Remarks: remarks, + OperatorID: operatorID, + HappenedAt: happenedAt, + } + + if err := s.sickSvc.ProcessSickPigLog(tx, sickLog); err != nil { + return fmt.Errorf("处理病猪日志失败: %w", err) + } + + return nil + }) + + if err != nil { + return fmt.Errorf("记录新增病猪事件失败: %w", err) + } + + return nil } // RecordSickPigRecovery 记录病猪康复事件。