From 0576a790dda1d4f093d73fd030692320376b432f Mon Sep 17 00:00:00 2001 From: huang <1724659546@qq.com> Date: Mon, 6 Oct 2025 18:08:56 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=20ReclassifyPenToNewBatch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pig/pig_batch_service_pen_transfer.go | 102 +++++++++++++++++- 1 file changed, 101 insertions(+), 1 deletion(-) diff --git a/internal/domain/pig/pig_batch_service_pen_transfer.go b/internal/domain/pig/pig_batch_service_pen_transfer.go index e1d8d86..0ef76a7 100644 --- a/internal/domain/pig/pig_batch_service_pen_transfer.go +++ b/internal/domain/pig/pig_batch_service_pen_transfer.go @@ -279,5 +279,105 @@ func (s *pigBatchService) MovePigsIntoPen(batchID uint, toPenID uint, quantity i // ReclassifyPenToNewBatch 连猪带栏,整体划拨到另一个猪群 func (s *pigBatchService) ReclassifyPenToNewBatch(fromBatchID uint, toBatchID uint, penID uint, operatorID uint, remarks string) error { - panic("implement me") + if fromBatchID == toBatchID { + return errors.New("源猪群和目标猪群不能相同") + } + + return s.uow.ExecuteInTransaction(func(tx *gorm.DB) error { + // 1. 核心业务规则校验 + // 1.1 校验猪群存在 + fromBatch, err := s.pigBatchRepo.GetPigBatchByIDTx(tx, fromBatchID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return fmt.Errorf("源猪群 %d 不存在", fromBatchID) + } + return fmt.Errorf("获取源猪群信息失败: %w", err) + } + toBatch, err := s.pigBatchRepo.GetPigBatchByIDTx(tx, toBatchID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return fmt.Errorf("目标猪群 %d 不存在", toBatchID) + } + return fmt.Errorf("获取目标猪群信息失败: %w", err) + } + + // 1.2 校验猪栏归属 + pen, err := s.transferSvc.GetPenByID(tx, penID) + if err != nil { + if errors.Is(err, gorm.ErrRecordNotFound) { + return fmt.Errorf("猪栏 %d 不存在: %w", penID, ErrPenNotFound) + } + return fmt.Errorf("获取猪栏 %d 信息失败: %w", penID, err) + } + if pen.PigBatchID == nil || *pen.PigBatchID != fromBatchID { + return fmt.Errorf("猪栏 %v 不属于源猪群 %v,无法划拨", pen.PenNumber, fromBatch.BatchNumber) + } + + // 2. 获取猪栏当前存栏数 + quantity, err := s.transferSvc.GetCurrentPigsInPen(tx, penID) + if err != nil { + return fmt.Errorf("获取猪栏 %v 存栏数失败: %w", pen.PenNumber, err) + } + + // 3. 更新猪栏的归属 + updates := map[string]interface{}{ + "pig_batch_id": &toBatchID, + } + if err := s.transferSvc.UpdatePenFields(tx, penID, updates); err != nil { + return fmt.Errorf("更新猪栏 %v 归属失败: %w", pen.PenNumber, err) + } + // 如果猪栏是空的,则只进行归属变更,不影响猪群数量 + if quantity == 0 { + return nil // 空栏划拨,不涉及猪只数量变更 + } + + // 4. 记录猪只从旧批次“迁出”的猪栏日志 + correlationID := uuid.New().String() + logOut := &models.PigTransferLog{ + TransferTime: time.Now(), + PigBatchID: fromBatchID, + PenID: penID, + Quantity: -quantity, // 迁出为负数 + Type: models.PigTransferTypeCrossBatch, + CorrelationID: correlationID, + OperatorID: operatorID, + Remarks: fmt.Sprintf("整栏划拨迁出: %d头猪从批次 %v 随猪栏 %v 划拨至批次 %v。备注: %s", quantity, fromBatch.BatchNumber, pen.PenNumber, toBatch.BatchNumber, remarks), + } + if err := s.transferSvc.LogTransfer(tx, logOut); err != nil { + return fmt.Errorf("记录猪栏 %d 迁出日志失败: %w", penID, err) + } + + // 5. 记录猪只到新批次“迁入”的猪栏日志 + logIn := &models.PigTransferLog{ + TransferTime: time.Now(), + PigBatchID: toBatchID, + PenID: penID, + Quantity: quantity, // 迁入为正数 + Type: models.PigTransferTypeCrossBatch, + CorrelationID: correlationID, + OperatorID: operatorID, + Remarks: fmt.Sprintf("整栏划拨迁入: %v头猪随猪栏 %v 从批次 %v 划拨入。备注: %s", quantity, fromBatch.BatchNumber, pen.PenNumber, remarks), + } + if err := s.transferSvc.LogTransfer(tx, logIn); err != nil { + return fmt.Errorf("记录猪栏 %d 迁入日志失败: %w", penID, err) + } + + // 7. 通过创建批次日志来修改猪群总数,确保数据可追溯 + now := time.Now() + // 7.1 记录源猪群数量减少 + reasonOutBatch := fmt.Sprintf("整栏划拨: %d头猪随猪栏 %v 从批次 %v 划拨至批次 %v。备注: %s", quantity, pen.PenNumber, fromBatch.BatchNumber, toBatchID, remarks) + err = s.updatePigBatchQuantityTx(tx, operatorID, fromBatchID, models.ChangeTypeTransferOut, -quantity, reasonOutBatch, now) + if err != nil { + return fmt.Errorf("更新源猪群 %v 数量失败: %w", fromBatch.BatchNumber, err) + } + + // 7.2 记录目标猪群数量增加 + reasonInBatch := fmt.Sprintf("整栏划拨: %v头猪随猪栏 %v 从批次 %v 划拨入。备注: %s", quantity, pen.PenNumber, fromBatch.BatchNumber, remarks) + err = s.updatePigBatchQuantityTx(tx, operatorID, toBatchID, models.ChangeTypeTransferIn, quantity, reasonInBatch, now) + if err != nil { + return fmt.Errorf("更新目标猪群 %v 数量失败: %w", toBatch.BatchNumber, err) + } + + return nil + }) }