Compare commits

...

2 Commits

Author SHA1 Message Date
51b776f393 跨群调栏没有调整猪的数量 2025-10-06 17:13:30 +08:00
189d532ac9 增加调栏数量检查 2025-10-06 16:31:24 +08:00
2 changed files with 43 additions and 14 deletions

View File

@@ -50,12 +50,19 @@ type PigBatchService interface {
// GetCurrentPigQuantity 获取指定猪批次的当前猪只数量。
GetCurrentPigQuantity(batchID uint) (int, error)
UpdatePigBatchQuantity(operatorID uint, batchID uint, changeType models.LogChangeType, changeAmount int, changeReason string, happenedAt time.Time) error
// 交易子服务
// SellPigs 处理卖猪的业务逻辑。
SellPigs(batchID uint, penID uint, quantity int, unitPrice float64, tatalPrice float64, traderName string, tradeDate time.Time, remarks string, operatorID uint) error
// BuyPigs 处理买猪的业务逻辑。
BuyPigs(batchID uint, penID uint, quantity int, unitPrice float64, tatalPrice float64, traderName string, tradeDate time.Time, remarks string, operatorID uint) error
UpdatePigBatchQuantity(operatorID uint, batchID uint, changeType models.LogChangeType, changeAmount int, changeReason string, happenedAt time.Time) error
// 调栏子服务
TransferPigsAcrossBatches(sourceBatchID uint, destBatchID uint, fromPenID uint, toPenID uint, quantity uint, operatorID uint, remarks string) error
TransferPigsWithinBatch(batchID uint, fromPenID uint, toPenID uint, quantity uint, operatorID uint, remarks string) error
}
// pigBatchService 是 PigBatchService 接口的具体实现。

View File

@@ -12,6 +12,17 @@ import (
// executeTransferAndLog 是一个私有辅助方法,用于封装创建和记录迁移日志的通用逻辑。
func (s *pigBatchService) executeTransferAndLog(tx *gorm.DB, fromBatchID, toBatchID, fromPenID, toPenID uint, quantity int, transferType models.PigTransferType, operatorID uint, remarks string) error {
// 通用校验:任何调出操作都不能超过源猪栏的当前存栏数
if quantity < 0 { // 当调出时才需要检查
currentPigsInFromPen, err := s.transferSvc.GetCurrentPigsInPen(tx, fromPenID)
if err != nil {
return fmt.Errorf("获取源猪栏 %d 当前猪只数失败: %w", fromPenID, err)
}
if currentPigsInFromPen+quantity < 0 {
return fmt.Errorf("调出数量 %d 超过源猪栏 %d 当前存栏数 %d", -quantity, fromPenID, currentPigsInFromPen)
}
}
// 1. 生成关联ID
correlationID := uuid.New().String()
@@ -99,15 +110,21 @@ func (s *pigBatchService) TransferPigsAcrossBatches(sourceBatchID uint, destBatc
return s.uow.ExecuteInTransaction(func(tx *gorm.DB) error {
// 1. 核心业务规则校验
sourceBatch, err := s.pigBatchRepo.GetPigBatchByID(sourceBatchID)
if err != nil {
// 1.1 校验猪群存在
if _, err := s.pigBatchRepo.GetPigBatchByIDTx(tx, sourceBatchID); err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return fmt.Errorf("源猪群 %d 不存在", sourceBatchID)
}
return fmt.Errorf("获取源猪群信息失败: %w", err)
}
destBatch, err := s.pigBatchRepo.GetPigBatchByID(destBatchID)
if err != nil {
if _, err := s.pigBatchRepo.GetPigBatchByIDTx(tx, destBatchID); err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return fmt.Errorf("目标猪群 %d 不存在", destBatchID)
}
return fmt.Errorf("获取目标猪群信息失败: %w", err)
}
// 1.2 校验猪栏归属
fromPen, err := s.transferSvc.GetPenByID(tx, fromPenID)
if err != nil {
return fmt.Errorf("获取源猪栏信息失败: %w", err)
@@ -116,21 +133,26 @@ func (s *pigBatchService) TransferPigsAcrossBatches(sourceBatchID uint, destBatc
return fmt.Errorf("源猪栏 %d 不属于源猪群 %d", fromPenID, sourceBatchID)
}
// 2. 调用通用辅助方法执行日志记录
// 2. 调用通用辅助方法执行猪只物理转移的日志记录
err = s.executeTransferAndLog(tx, sourceBatchID, destBatchID, fromPenID, toPenID, int(quantity), "跨群调栏", operatorID, remarks)
if err != nil {
return err
}
// 3. 修改本聚合的数据(猪群总数)
sourceBatch.InitialCount -= int(quantity)
destBatch.InitialCount += int(quantity)
if _, _, err := s.pigBatchRepo.UpdatePigBatch(sourceBatch); err != nil {
return fmt.Errorf("更新源猪群数量失败: %w", err)
// 3. 通过创建批次日志来修改猪群总数,确保数据可追溯
now := time.Now()
// 3.1 记录源猪群数量减少
reasonOut := fmt.Sprintf("跨群调栏: %d头猪从批次 %d 调出至批次 %d。备注: %s", quantity, sourceBatchID, destBatchID, remarks)
err = s.updatePigBatchQuantityTx(tx, operatorID, sourceBatchID, models.ChangeTypeTransferOut, -int(quantity), reasonOut, now)
if err != nil {
return fmt.Errorf("更新源猪群 %d 数量失败: %w", sourceBatchID, err)
}
if _, _, err := s.pigBatchRepo.UpdatePigBatch(destBatch); err != nil {
return fmt.Errorf("更新目标猪群数量失败: %w", err)
// 3.2 记录目标猪群数量增加
reasonIn := fmt.Sprintf("跨群调栏: %d头猪从批次 %d 调入。备注: %s", quantity, sourceBatchID, remarks)
err = s.updatePigBatchQuantityTx(tx, operatorID, destBatchID, models.ChangeTypeTransferIn, int(quantity), reasonIn, now)
if err != nil {
return fmt.Errorf("更新目标猪群 %d 数量失败: %w", destBatchID, err)
}
return nil