Compare commits
	
		
			2 Commits
		
	
	
		
			3b109d1547
			...
			51b776f393
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 51b776f393 | |||
| 189d532ac9 | 
@@ -50,12 +50,19 @@ type PigBatchService interface {
 | 
				
			|||||||
	// GetCurrentPigQuantity 获取指定猪批次的当前猪只数量。
 | 
						// GetCurrentPigQuantity 获取指定猪批次的当前猪只数量。
 | 
				
			||||||
	GetCurrentPigQuantity(batchID uint) (int, error)
 | 
						GetCurrentPigQuantity(batchID uint) (int, error)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						UpdatePigBatchQuantity(operatorID uint, batchID uint, changeType models.LogChangeType, changeAmount int, changeReason string, happenedAt time.Time) error
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// 交易子服务
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// SellPigs 处理卖猪的业务逻辑。
 | 
						// SellPigs 处理卖猪的业务逻辑。
 | 
				
			||||||
	SellPigs(batchID uint, penID uint, quantity int, unitPrice float64, tatalPrice float64, traderName string, tradeDate time.Time, remarks string, operatorID uint) error
 | 
						SellPigs(batchID uint, penID uint, quantity int, unitPrice float64, tatalPrice float64, traderName string, tradeDate time.Time, remarks string, operatorID uint) error
 | 
				
			||||||
	// BuyPigs 处理买猪的业务逻辑。
 | 
						// BuyPigs 处理买猪的业务逻辑。
 | 
				
			||||||
	BuyPigs(batchID uint, penID uint, quantity int, unitPrice float64, tatalPrice float64, traderName string, tradeDate time.Time, remarks string, operatorID uint) error
 | 
						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 接口的具体实现。
 | 
					// pigBatchService 是 PigBatchService 接口的具体实现。
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,6 +12,17 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// executeTransferAndLog 是一个私有辅助方法,用于封装创建和记录迁移日志的通用逻辑。
 | 
					// executeTransferAndLog 是一个私有辅助方法,用于封装创建和记录迁移日志的通用逻辑。
 | 
				
			||||||
func (s *pigBatchService) executeTransferAndLog(tx *gorm.DB, fromBatchID, toBatchID, fromPenID, toPenID uint, quantity int, transferType models.PigTransferType, operatorID uint, remarks string) error {
 | 
					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
 | 
						// 1. 生成关联ID
 | 
				
			||||||
	correlationID := uuid.New().String()
 | 
						correlationID := uuid.New().String()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -99,15 +110,21 @@ func (s *pigBatchService) TransferPigsAcrossBatches(sourceBatchID uint, destBatc
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	return s.uow.ExecuteInTransaction(func(tx *gorm.DB) error {
 | 
						return s.uow.ExecuteInTransaction(func(tx *gorm.DB) error {
 | 
				
			||||||
		// 1. 核心业务规则校验
 | 
							// 1. 核心业务规则校验
 | 
				
			||||||
		sourceBatch, err := s.pigBatchRepo.GetPigBatchByID(sourceBatchID)
 | 
							// 1.1 校验猪群存在
 | 
				
			||||||
		if err != nil {
 | 
							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)
 | 
								return fmt.Errorf("获取源猪群信息失败: %w", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		destBatch, err := s.pigBatchRepo.GetPigBatchByID(destBatchID)
 | 
							if _, err := s.pigBatchRepo.GetPigBatchByIDTx(tx, destBatchID); err != nil {
 | 
				
			||||||
		if err != nil {
 | 
								if errors.Is(err, gorm.ErrRecordNotFound) {
 | 
				
			||||||
 | 
									return fmt.Errorf("目标猪群 %d 不存在", destBatchID)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
			return fmt.Errorf("获取目标猪群信息失败: %w", err)
 | 
								return fmt.Errorf("获取目标猪群信息失败: %w", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// 1.2 校验猪栏归属
 | 
				
			||||||
		fromPen, err := s.transferSvc.GetPenByID(tx, fromPenID)
 | 
							fromPen, err := s.transferSvc.GetPenByID(tx, fromPenID)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return fmt.Errorf("获取源猪栏信息失败: %w", err)
 | 
								return fmt.Errorf("获取源猪栏信息失败: %w", err)
 | 
				
			||||||
@@ -116,21 +133,26 @@ func (s *pigBatchService) TransferPigsAcrossBatches(sourceBatchID uint, destBatc
 | 
				
			|||||||
			return fmt.Errorf("源猪栏 %d 不属于源猪群 %d", fromPenID, sourceBatchID)
 | 
								return fmt.Errorf("源猪栏 %d 不属于源猪群 %d", fromPenID, sourceBatchID)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// 2. 调用通用辅助方法执行日志记录
 | 
							// 2. 调用通用辅助方法执行猪只物理转移的日志记录
 | 
				
			||||||
		err = s.executeTransferAndLog(tx, sourceBatchID, destBatchID, fromPenID, toPenID, int(quantity), "跨群调栏", operatorID, remarks)
 | 
							err = s.executeTransferAndLog(tx, sourceBatchID, destBatchID, fromPenID, toPenID, int(quantity), "跨群调栏", operatorID, remarks)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// 3. 修改本聚合的数据(猪群总数)
 | 
							// 3. 通过创建批次日志来修改猪群总数,确保数据可追溯
 | 
				
			||||||
		sourceBatch.InitialCount -= int(quantity)
 | 
							now := time.Now()
 | 
				
			||||||
		destBatch.InitialCount += int(quantity)
 | 
							// 3.1 记录源猪群数量减少
 | 
				
			||||||
 | 
							reasonOut := fmt.Sprintf("跨群调栏: %d头猪从批次 %d 调出至批次 %d。备注: %s", quantity, sourceBatchID, destBatchID, remarks)
 | 
				
			||||||
		if _, _, err := s.pigBatchRepo.UpdatePigBatch(sourceBatch); err != nil {
 | 
							err = s.updatePigBatchQuantityTx(tx, operatorID, sourceBatchID, models.ChangeTypeTransferOut, -int(quantity), reasonOut, now)
 | 
				
			||||||
			return fmt.Errorf("更新源猪群数量失败: %w", err)
 | 
							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
 | 
							return nil
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user