From 5e49cd3f955e4793e7a5f1249100326d09192f99 Mon Sep 17 00:00:00 2001 From: huang <1724659546@qq.com> Date: Mon, 6 Oct 2025 17:56:13 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0MovePigsIntoPen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/domain/pig/pen_transfer_manager.go | 26 +++++++ .../pig/pig_batch_service_pen_transfer.go | 68 ++++++++++++++++++- 2 files changed, 93 insertions(+), 1 deletion(-) diff --git a/internal/domain/pig/pen_transfer_manager.go b/internal/domain/pig/pen_transfer_manager.go index 41b7cfb..99bc80d 100644 --- a/internal/domain/pig/pen_transfer_manager.go +++ b/internal/domain/pig/pen_transfer_manager.go @@ -2,6 +2,7 @@ package pig import ( "errors" + "fmt" "git.huangwc.com/pig/pig-farm-controller/internal/infra/models" "git.huangwc.com/pig/pig-farm-controller/internal/infra/repository" @@ -25,6 +26,9 @@ type PigPenTransferManager interface { // GetCurrentPigsInPen 通过汇总猪只迁移日志,计算给定猪栏中的当前猪只数量。 GetCurrentPigsInPen(tx *gorm.DB, penID uint) (int, error) + + // GetTotalPigsInPensForBatchTx 计算指定猪群下所有猪栏的当前总存栏数 + GetTotalPigsInPensForBatchTx(tx *gorm.DB, batchID uint) (int, error) } // pigPenTransferManager 是 PigPenTransferManager 接口的具体实现。 @@ -117,3 +121,25 @@ func (s *pigPenTransferManager) GetCurrentPigsInPen(tx *gorm.DB, penID uint) (in return totalPigs, nil } + +// GetTotalPigsInPensForBatchTx 计算指定猪群下所有猪栏的当前总存栏数 +// 该方法通过遍历猪群下的每个猪栏,并调用 GetCurrentPigsInPen 来累加存栏数。 +func (s *pigPenTransferManager) GetTotalPigsInPensForBatchTx(tx *gorm.DB, batchID uint) (int, error) { + // 1. 获取该批次下所有猪栏的列表 + pensInBatch, err := s.GetPensByBatchID(tx, batchID) + if err != nil { + return 0, fmt.Errorf("获取猪群 %d 下属猪栏失败: %w", batchID, err) + } + + totalPigs := 0 + // 2. 遍历每个猪栏,累加其存栏数 + for _, pen := range pensInBatch { + pigsInPen, err := s.GetCurrentPigsInPen(tx, pen.ID) + if err != nil { + return 0, fmt.Errorf("获取猪栏 %d 存栏数失败: %w", pen.ID, err) + } + totalPigs += pigsInPen + } + + return totalPigs, nil +} diff --git a/internal/domain/pig/pig_batch_service_pen_transfer.go b/internal/domain/pig/pig_batch_service_pen_transfer.go index 2c6b7f6..e1d8d86 100644 --- a/internal/domain/pig/pig_batch_service_pen_transfer.go +++ b/internal/domain/pig/pig_batch_service_pen_transfer.go @@ -208,7 +208,73 @@ func (s *pigBatchService) AssignEmptyPensToBatch(batchID uint, penIDs []uint, op // MovePigsIntoPen 将猪只从“虚拟库存”移入指定猪栏 func (s *pigBatchService) MovePigsIntoPen(batchID uint, toPenID uint, quantity int, operatorID uint, remarks string) error { - panic("implement me") + if quantity <= 0 { + return errors.New("迁移数量必须大于零") + } + + return s.uow.ExecuteInTransaction(func(tx *gorm.DB) error { + // 1. 验证猪批次是否存在且活跃 + pigBatch, err := s.pigBatchRepo.GetPigBatchByIDTx(tx, batchID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return ErrPigBatchNotFound + } + return fmt.Errorf("获取猪批次信息失败: %w", err) + } + if !pigBatch.IsActive() { + return ErrPigBatchNotActive + } + + // 2. 校验目标猪栏 + toPen, err := s.transferSvc.GetPenByID(tx, toPenID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return fmt.Errorf("目标猪栏 %d 不存在: %w", toPenID, ErrPenNotFound) + } + return fmt.Errorf("获取目标猪栏 %d 信息失败: %w", toPenID, err) + } + + // 校验目标猪栏的归属和状态 + if toPen.PigBatchID == nil { + return fmt.Errorf("目标猪栏 %s 不属于当前批次 %s", toPen.PenNumber, batchID) + } + if toPen.PigBatchID != nil && *toPen.PigBatchID != batchID { + return fmt.Errorf("目标猪栏 %s 已被其他批次 %d 占用,无法移入", toPen.PenNumber, *toPen.PigBatchID) + } + + // 3. 校验猪群中有足够的“未分配”猪只 + currentBatchTotal, err := s.getCurrentPigQuantityTx(tx, batchID) + if err != nil { + return fmt.Errorf("获取猪群 %d 当前总数量失败: %w", batchID, err) + } + + // 获取该批次下所有猪栏的当前总存栏数 + totalPigsInPens, err := s.transferSvc.GetTotalPigsInPensForBatchTx(tx, batchID) + if err != nil { + return fmt.Errorf("计算猪群 %d 下属猪栏总存栏失败: %w", batchID, err) + } + + unassignedPigs := currentBatchTotal - totalPigsInPens + if unassignedPigs < quantity { + return fmt.Errorf("猪群 %d 未分配猪只不足,当前未分配 %d 头,需要移入 %d 头", batchID, unassignedPigs, quantity) + } + + // 4. 记录转移日志 + logIn := &models.PigTransferLog{ + TransferTime: time.Now(), + PigBatchID: batchID, + PenID: toPenID, + Quantity: quantity, // 调入为正数 + Type: models.PigTransferTypeInternal, // 首次入栏 + OperatorID: operatorID, + Remarks: remarks, + } + if err := s.transferSvc.LogTransfer(tx, logIn); err != nil { + return fmt.Errorf("记录入栏日志失败: %w", err) + } + + return nil + }) } // ReclassifyPenToNewBatch 连猪带栏,整体划拨到另一个猪群