issue_29 #32
@@ -47,8 +47,6 @@ type PigBatchService interface {
|
|||||||
DeletePigBatch(id uint) error
|
DeletePigBatch(id uint) error
|
||||||
// ListPigBatches 批量查询猪批次。
|
// ListPigBatches 批量查询猪批次。
|
||||||
ListPigBatches(isActive *bool) ([]*models.PigBatch, error)
|
ListPigBatches(isActive *bool) ([]*models.PigBatch, error)
|
||||||
// UpdatePigBatchPens 更新猪批次关联的猪栏。
|
|
||||||
UpdatePigBatchPens(batchID uint, desiredPenIDs []uint) error
|
|
||||||
// AssignEmptyPensToBatch 为猪群分配空栏
|
// AssignEmptyPensToBatch 为猪群分配空栏
|
||||||
AssignEmptyPensToBatch(batchID uint, penIDs []uint, operatorID uint) error
|
AssignEmptyPensToBatch(batchID uint, penIDs []uint, operatorID uint) error
|
||||||
// MovePigsIntoPen 将猪只从“虚拟库存”移入指定猪栏
|
// MovePigsIntoPen 将猪只从“虚拟库存”移入指定猪栏
|
||||||
|
|||||||
@@ -126,106 +126,6 @@ func (s *pigBatchService) ListPigBatches(isActive *bool) ([]*models.PigBatch, er
|
|||||||
return s.pigBatchRepo.ListPigBatches(isActive)
|
return s.pigBatchRepo.ListPigBatches(isActive)
|
||||||
}
|
}
|
||||||
|
|
||||||
// UpdatePigBatchPens 实现了在事务中更新猪批次关联猪栏的复杂逻辑。
|
|
||||||
// 它通过调用底层的 PigPenTransferManager 来执行数据库操作,从而保持了职责的清晰。
|
|
||||||
func (s *pigBatchService) UpdatePigBatchPens(batchID uint, desiredPenIDs []uint) error {
|
|
||||||
// 使用工作单元来确保操作的原子性
|
|
||||||
return s.uow.ExecuteInTransaction(func(tx *gorm.DB) error {
|
|
||||||
// 1. 验证猪批次是否存在且活跃
|
|
||||||
// 注意: 此处依赖一个假设存在的 pigBatchRepo.GetPigBatchByIDTx 方法
|
|
||||||
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. 获取当前关联的猪栏 (通过子服务)
|
|
||||||
currentPens, err := s.transferSvc.GetPensByBatchID(tx, batchID)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("获取当前关联猪栏失败: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
currentPenMap := make(map[uint]models.Pen)
|
|
||||||
currentPenIDsSet := make(map[uint]struct{})
|
|
||||||
for _, pen := range currentPens {
|
|
||||||
currentPenMap[pen.ID] = *pen
|
|
||||||
currentPenIDsSet[pen.ID] = struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 构建期望猪栏ID集合
|
|
||||||
desiredPenIDsSet := make(map[uint]struct{})
|
|
||||||
for _, penID := range desiredPenIDs {
|
|
||||||
desiredPenIDsSet[penID] = struct{}{}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. 计算需要添加和移除的猪栏
|
|
||||||
var pensToRemove []uint
|
|
||||||
for penID := range currentPenIDsSet {
|
|
||||||
if _, found := desiredPenIDsSet[penID]; !found {
|
|
||||||
pensToRemove = append(pensToRemove, penID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var pensToAdd []uint
|
|
||||||
for _, penID := range desiredPenIDs {
|
|
||||||
if _, found := currentPenIDsSet[penID]; !found {
|
|
||||||
pensToAdd = append(pensToAdd, penID)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 5. 处理移除猪栏的逻辑
|
|
||||||
for _, penID := range pensToRemove {
|
|
||||||
currentPen := currentPenMap[penID]
|
|
||||||
updates := make(map[string]interface{})
|
|
||||||
updates["pig_batch_id"] = nil
|
|
||||||
|
|
||||||
if currentPen.Status == models.PenStatusOccupied {
|
|
||||||
updates["status"] = models.PenStatusEmpty
|
|
||||||
}
|
|
||||||
|
|
||||||
if err := s.transferSvc.UpdatePenFields(tx, penID, updates); err != nil {
|
|
||||||
return fmt.Errorf("移除猪栏 %d 失败: %w", penID, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 6. 处理添加猪栏的逻辑
|
|
||||||
for _, penID := range pensToAdd {
|
|
||||||
// 通过子服务获取猪栏信息
|
|
||||||
actualPen, 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 actualPen.Status != models.PenStatusEmpty {
|
|
||||||
return fmt.Errorf("猪栏 %s 状态为 %s,无法分配: %w", actualPen.PenNumber, actualPen.Status, ErrPenStatusInvalidForAllocation)
|
|
||||||
}
|
|
||||||
if actualPen.PigBatchID != nil {
|
|
||||||
return fmt.Errorf("猪栏 %s 已被其他批次 %d 使用: %w", actualPen.PenNumber, *actualPen.PigBatchID, ErrPenOccupiedByOtherBatch)
|
|
||||||
}
|
|
||||||
|
|
||||||
updates := map[string]interface{}{
|
|
||||||
"pig_batch_id": &batchID,
|
|
||||||
"status": models.PenStatusOccupied,
|
|
||||||
}
|
|
||||||
if err := s.transferSvc.UpdatePenFields(tx, penID, updates); err != nil {
|
|
||||||
return fmt.Errorf("添加猪栏 %d 失败: %w", penID, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetCurrentPigQuantity 实现了获取指定猪批次的当前猪只数量的逻辑。
|
// GetCurrentPigQuantity 实现了获取指定猪批次的当前猪只数量的逻辑。
|
||||||
func (s *pigBatchService) GetCurrentPigQuantity(batchID uint) (int, error) {
|
func (s *pigBatchService) GetCurrentPigQuantity(batchID uint) (int, error) {
|
||||||
var getErr error
|
var getErr error
|
||||||
|
|||||||
Reference in New Issue
Block a user