349 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			349 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package service
 | 
						||
 | 
						||
import (
 | 
						||
	"time"
 | 
						||
 | 
						||
	"git.huangwc.com/pig/pig-farm-controller/internal/app/dto"
 | 
						||
	domain_pig "git.huangwc.com/pig/pig-farm-controller/internal/domain/pig"
 | 
						||
	"git.huangwc.com/pig/pig-farm-controller/internal/infra/logs"
 | 
						||
	"git.huangwc.com/pig/pig-farm-controller/internal/infra/models"
 | 
						||
)
 | 
						||
 | 
						||
// PigBatchService 接口定义保持不变,继续作为应用层对外的契约。
 | 
						||
type PigBatchService interface {
 | 
						||
	CreatePigBatch(operatorID uint, dto *dto.PigBatchCreateDTO) (*dto.PigBatchResponseDTO, error)
 | 
						||
	GetPigBatch(id uint) (*dto.PigBatchResponseDTO, error)
 | 
						||
	UpdatePigBatch(id uint, dto *dto.PigBatchUpdateDTO) (*dto.PigBatchResponseDTO, error)
 | 
						||
	DeletePigBatch(id uint) error
 | 
						||
	ListPigBatches(isActive *bool) ([]*dto.PigBatchResponseDTO, error)
 | 
						||
 | 
						||
	// Pig Pen Management
 | 
						||
	AssignEmptyPensToBatch(batchID uint, penIDs []uint, operatorID uint) error
 | 
						||
	ReclassifyPenToNewBatch(fromBatchID uint, toBatchID uint, penID uint, operatorID uint, remarks string) error
 | 
						||
	RemoveEmptyPenFromBatch(batchID uint, penID uint) error
 | 
						||
	MovePigsIntoPen(batchID uint, toPenID uint, quantity int, operatorID uint, remarks string) error
 | 
						||
 | 
						||
	// Trade Sub-service
 | 
						||
	SellPigs(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
 | 
						||
 | 
						||
	// Transfer Sub-service
 | 
						||
	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
 | 
						||
 | 
						||
	// Sick Pig Management
 | 
						||
	RecordSickPigs(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error
 | 
						||
	RecordSickPigRecovery(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error
 | 
						||
	RecordSickPigDeath(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error
 | 
						||
	RecordSickPigCull(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error
 | 
						||
 | 
						||
	// Normal Pig Management
 | 
						||
	RecordDeath(operatorID uint, batchID uint, penID uint, quantity int, happenedAt time.Time, remarks string) error
 | 
						||
	RecordCull(operatorID uint, batchID uint, penID uint, quantity int, happenedAt time.Time, remarks string) error
 | 
						||
}
 | 
						||
 | 
						||
// pigBatchService 的实现现在依赖于领域服务接口。
 | 
						||
type pigBatchService struct {
 | 
						||
	logger        *logs.Logger
 | 
						||
	domainService domain_pig.PigBatchService // 依赖注入领域服务
 | 
						||
}
 | 
						||
 | 
						||
// NewPigBatchService 构造函数被修改,以注入领域服务。
 | 
						||
func NewPigBatchService(domainService domain_pig.PigBatchService, logger *logs.Logger) PigBatchService {
 | 
						||
	return &pigBatchService{
 | 
						||
		logger:        logger,
 | 
						||
		domainService: domainService,
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// toPigBatchResponseDTO 负责将领域模型转换为应用层DTO,这个职责保留在应用层。
 | 
						||
func (s *pigBatchService) toPigBatchResponseDTO(batch *models.PigBatch, currentTotalQuantity, currentTotalPigsInPens int) *dto.PigBatchResponseDTO {
 | 
						||
	if batch == nil {
 | 
						||
		return nil
 | 
						||
	}
 | 
						||
	return &dto.PigBatchResponseDTO{
 | 
						||
		ID:                     batch.ID,
 | 
						||
		BatchNumber:            batch.BatchNumber,
 | 
						||
		OriginType:             batch.OriginType,
 | 
						||
		StartDate:              batch.StartDate,
 | 
						||
		EndDate:                batch.EndDate,
 | 
						||
		InitialCount:           batch.InitialCount,
 | 
						||
		Status:                 batch.Status,
 | 
						||
		IsActive:               batch.IsActive(),
 | 
						||
		CurrentTotalQuantity:   currentTotalQuantity,
 | 
						||
		CurrentTotalPigsInPens: currentTotalPigsInPens,
 | 
						||
		CreateTime:             batch.CreatedAt,
 | 
						||
		UpdateTime:             batch.UpdatedAt,
 | 
						||
	}
 | 
						||
}
 | 
						||
 | 
						||
// CreatePigBatch 现在将请求委托给领域服务处理。
 | 
						||
func (s *pigBatchService) CreatePigBatch(operatorID uint, dto *dto.PigBatchCreateDTO) (*dto.PigBatchResponseDTO, error) {
 | 
						||
	// 1. DTO -> 领域模型
 | 
						||
	batch := &models.PigBatch{
 | 
						||
		BatchNumber:  dto.BatchNumber,
 | 
						||
		OriginType:   dto.OriginType,
 | 
						||
		StartDate:    dto.StartDate,
 | 
						||
		InitialCount: dto.InitialCount,
 | 
						||
		Status:       dto.Status,
 | 
						||
	}
 | 
						||
 | 
						||
	// 2. 调用领域服务
 | 
						||
	createdBatch, err := s.domainService.CreatePigBatch(operatorID, batch)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 创建猪批次失败: %v", err)
 | 
						||
		return nil, MapDomainError(err)
 | 
						||
	}
 | 
						||
 | 
						||
	// 3. 领域模型 -> DTO
 | 
						||
	return s.toPigBatchResponseDTO(createdBatch, dto.InitialCount, 0), nil
 | 
						||
}
 | 
						||
 | 
						||
// GetPigBatch 从领域服务获取数据并转换为DTO,同时处理错误转换。
 | 
						||
func (s *pigBatchService) GetPigBatch(id uint) (*dto.PigBatchResponseDTO, error) {
 | 
						||
	batch, err := s.domainService.GetPigBatch(id)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Warnf("应用层: 获取猪批次失败, ID: %d, 错误: %v", id, err)
 | 
						||
		return nil, MapDomainError(err)
 | 
						||
	}
 | 
						||
	currentTotalQuantity, err := s.domainService.GetCurrentPigQuantity(id)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Warnf("应用层: 获取猪批次总数失败, ID: %d, 错误: %v", id, err)
 | 
						||
		return nil, MapDomainError(err)
 | 
						||
	}
 | 
						||
	currentTotalPigsInPens, err := s.domainService.GetTotalPigsInPensForBatch(id)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Warnf("应用层: 获取猪批次存栏总数失败, ID: %d, 错误: %v", id, err)
 | 
						||
		return nil, MapDomainError(err)
 | 
						||
	}
 | 
						||
	return s.toPigBatchResponseDTO(batch, currentTotalQuantity, currentTotalPigsInPens), nil
 | 
						||
}
 | 
						||
 | 
						||
// UpdatePigBatch 协调获取、更新和保存的流程,并处理错误转换。
 | 
						||
func (s *pigBatchService) UpdatePigBatch(id uint, dto *dto.PigBatchUpdateDTO) (*dto.PigBatchResponseDTO, error) {
 | 
						||
	// 1. 先获取最新的领域模型
 | 
						||
	existingBatch, err := s.domainService.GetPigBatch(id)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Warnf("应用层: 更新猪批次失败,获取原批次信息错误, ID: %d, 错误: %v", id, err)
 | 
						||
		return nil, MapDomainError(err)
 | 
						||
	}
 | 
						||
 | 
						||
	// 2. 将DTO中的变更应用到模型上
 | 
						||
	if dto.BatchNumber != nil {
 | 
						||
		existingBatch.BatchNumber = *dto.BatchNumber
 | 
						||
	}
 | 
						||
	if dto.OriginType != nil {
 | 
						||
		existingBatch.OriginType = *dto.OriginType
 | 
						||
	}
 | 
						||
	if dto.StartDate != nil {
 | 
						||
		existingBatch.StartDate = *dto.StartDate
 | 
						||
	}
 | 
						||
	if dto.EndDate != nil {
 | 
						||
		existingBatch.EndDate = *dto.EndDate
 | 
						||
	}
 | 
						||
	if dto.InitialCount != nil {
 | 
						||
		existingBatch.InitialCount = *dto.InitialCount
 | 
						||
	}
 | 
						||
	if dto.Status != nil {
 | 
						||
		existingBatch.Status = *dto.Status
 | 
						||
	}
 | 
						||
 | 
						||
	// 3. 调用领域服务执行更新
 | 
						||
	updatedBatch, err := s.domainService.UpdatePigBatch(existingBatch)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 更新猪批次失败, ID: %d, 错误: %v", id, err)
 | 
						||
		return nil, MapDomainError(err)
 | 
						||
	}
 | 
						||
 | 
						||
	// 4. 填充猪群信息
 | 
						||
	currentTotalQuantity, err := s.domainService.GetCurrentPigQuantity(id)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Warnf("应用层: 获取猪批次总数失败, ID: %d, 错误: %v", id, err)
 | 
						||
		return nil, MapDomainError(err)
 | 
						||
	}
 | 
						||
	currentTotalPigsInPens, err := s.domainService.GetTotalPigsInPensForBatch(id)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Warnf("应用层: 获取猪批次存栏总数失败, ID: %d, 错误: %v", id, err)
 | 
						||
		return nil, MapDomainError(err)
 | 
						||
	}
 | 
						||
 | 
						||
	// 5. 转换并返回结果
 | 
						||
	return s.toPigBatchResponseDTO(updatedBatch, currentTotalQuantity, currentTotalPigsInPens), nil
 | 
						||
}
 | 
						||
 | 
						||
// DeletePigBatch 将删除操作委托给领域服务,并转换领域错误为应用层错误。
 | 
						||
func (s *pigBatchService) DeletePigBatch(id uint) error {
 | 
						||
	err := s.domainService.DeletePigBatch(id)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 删除猪批次失败, ID: %d, 错误: %v", id, err)
 | 
						||
		return MapDomainError(err)
 | 
						||
	}
 | 
						||
	return nil
 | 
						||
}
 | 
						||
 | 
						||
// ListPigBatches 从领域服务获取列表并进行转换。
 | 
						||
func (s *pigBatchService) ListPigBatches(isActive *bool) ([]*dto.PigBatchResponseDTO, error) {
 | 
						||
	batches, err := s.domainService.ListPigBatches(isActive)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 批量查询猪批次失败: %v", err)
 | 
						||
		return nil, MapDomainError(err)
 | 
						||
	}
 | 
						||
 | 
						||
	var responseDTOs []*dto.PigBatchResponseDTO
 | 
						||
	for _, batch := range batches {
 | 
						||
		currentTotalQuantity, err := s.domainService.GetCurrentPigQuantity(batch.ID)
 | 
						||
		if err != nil {
 | 
						||
			s.logger.Warnf("应用层: 获取猪批次总数失败, ID: %d, 错误: %v", batch.ID, err)
 | 
						||
			return nil, MapDomainError(err)
 | 
						||
		}
 | 
						||
		currentTotalPigsInPens, err := s.domainService.GetTotalPigsInPensForBatch(batch.ID)
 | 
						||
		if err != nil {
 | 
						||
			s.logger.Warnf("应用层: 获取猪批次存栏总数失败, ID: %d, 错误: %v", batch.ID, err)
 | 
						||
			return nil, MapDomainError(err)
 | 
						||
		}
 | 
						||
		responseDTOs = append(responseDTOs, s.toPigBatchResponseDTO(batch, currentTotalQuantity, currentTotalPigsInPens))
 | 
						||
	}
 | 
						||
 | 
						||
	return responseDTOs, nil
 | 
						||
}
 | 
						||
 | 
						||
// AssignEmptyPensToBatch 委托给领域服务
 | 
						||
func (s *pigBatchService) AssignEmptyPensToBatch(batchID uint, penIDs []uint, operatorID uint) error {
 | 
						||
	err := s.domainService.AssignEmptyPensToBatch(batchID, penIDs, operatorID)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 为猪批次分配空栏失败, 批次ID: %d, 错误: %v", batchID, err)
 | 
						||
		return MapDomainError(err)
 | 
						||
	}
 | 
						||
	return nil
 | 
						||
}
 | 
						||
 | 
						||
// ReclassifyPenToNewBatch 委托给领域服务
 | 
						||
func (s *pigBatchService) ReclassifyPenToNewBatch(fromBatchID uint, toBatchID uint, penID uint, operatorID uint, remarks string) error {
 | 
						||
	err := s.domainService.ReclassifyPenToNewBatch(fromBatchID, toBatchID, penID, operatorID, remarks)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 划拨猪栏到新批次失败, 源批次ID: %d, 错误: %v", fromBatchID, err)
 | 
						||
		return MapDomainError(err)
 | 
						||
	}
 | 
						||
	return nil
 | 
						||
}
 | 
						||
 | 
						||
// RemoveEmptyPenFromBatch 委托给领域服务
 | 
						||
func (s *pigBatchService) RemoveEmptyPenFromBatch(batchID uint, penID uint) error {
 | 
						||
	err := s.domainService.RemoveEmptyPenFromBatch(batchID, penID)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 从猪批次移除空栏失败, 批次ID: %d, 猪栏ID: %d, 错误: %v", batchID, penID, err)
 | 
						||
		return MapDomainError(err)
 | 
						||
	}
 | 
						||
	return nil
 | 
						||
}
 | 
						||
 | 
						||
// MovePigsIntoPen 委托给领域服务
 | 
						||
func (s *pigBatchService) MovePigsIntoPen(batchID uint, toPenID uint, quantity int, operatorID uint, remarks string) error {
 | 
						||
	err := s.domainService.MovePigsIntoPen(batchID, toPenID, quantity, operatorID, remarks)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 将猪只移入猪栏失败, 批次ID: %d, 目标猪栏ID: %d, 错误: %v", batchID, toPenID, err)
 | 
						||
		return MapDomainError(err)
 | 
						||
	}
 | 
						||
	return nil
 | 
						||
}
 | 
						||
 | 
						||
// SellPigs 委托给领域服务
 | 
						||
func (s *pigBatchService) SellPigs(batchID uint, penID uint, quantity int, unitPrice float64, tatalPrice float64, traderName string, tradeDate time.Time, remarks string, operatorID uint) error {
 | 
						||
	err := s.domainService.SellPigs(batchID, penID, quantity, unitPrice, tatalPrice, traderName, tradeDate, remarks, operatorID)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 卖猪失败, 批次ID: %d, 错误: %v", batchID, err)
 | 
						||
		return MapDomainError(err)
 | 
						||
	}
 | 
						||
	return nil
 | 
						||
}
 | 
						||
 | 
						||
// BuyPigs 委托给领域服务
 | 
						||
func (s *pigBatchService) BuyPigs(batchID uint, penID uint, quantity int, unitPrice float64, tatalPrice float64, traderName string, tradeDate time.Time, remarks string, operatorID uint) error {
 | 
						||
	err := s.domainService.BuyPigs(batchID, penID, quantity, unitPrice, tatalPrice, traderName, tradeDate, remarks, operatorID)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 买猪失败, 批次ID: %d, 错误: %v", batchID, err)
 | 
						||
		return MapDomainError(err)
 | 
						||
	}
 | 
						||
	return nil
 | 
						||
}
 | 
						||
 | 
						||
// TransferPigsAcrossBatches 委托给领域服务
 | 
						||
func (s *pigBatchService) TransferPigsAcrossBatches(sourceBatchID uint, destBatchID uint, fromPenID uint, toPenID uint, quantity uint, operatorID uint, remarks string) error {
 | 
						||
	err := s.domainService.TransferPigsAcrossBatches(sourceBatchID, destBatchID, fromPenID, toPenID, quantity, operatorID, remarks)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 跨群调栏失败, 源批次ID: %d, 错误: %v", sourceBatchID, err)
 | 
						||
		return MapDomainError(err)
 | 
						||
	}
 | 
						||
	return nil
 | 
						||
}
 | 
						||
 | 
						||
// TransferPigsWithinBatch 委托给领域服务
 | 
						||
func (s *pigBatchService) TransferPigsWithinBatch(batchID uint, fromPenID uint, toPenID uint, quantity uint, operatorID uint, remarks string) error {
 | 
						||
	err := s.domainService.TransferPigsWithinBatch(batchID, fromPenID, toPenID, quantity, operatorID, remarks)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 群内调栏失败, 批次ID: %d, 错误: %v", batchID, err)
 | 
						||
		return MapDomainError(err)
 | 
						||
	}
 | 
						||
	return nil
 | 
						||
}
 | 
						||
 | 
						||
// RecordSickPigs 委托给领域服务
 | 
						||
func (s *pigBatchService) RecordSickPigs(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error {
 | 
						||
	err := s.domainService.RecordSickPigs(operatorID, batchID, penID, quantity, treatmentLocation, happenedAt, remarks)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 记录病猪事件失败, 批次ID: %d, 错误: %v", batchID, err)
 | 
						||
		return MapDomainError(err)
 | 
						||
	}
 | 
						||
	return nil
 | 
						||
}
 | 
						||
 | 
						||
// RecordSickPigRecovery 委托给领域服务
 | 
						||
func (s *pigBatchService) RecordSickPigRecovery(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error {
 | 
						||
	err := s.domainService.RecordSickPigRecovery(operatorID, batchID, penID, quantity, treatmentLocation, happenedAt, remarks)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 记录病猪康复事件失败, 批次ID: %d, 错误: %v", batchID, err)
 | 
						||
		return MapDomainError(err)
 | 
						||
	}
 | 
						||
	return nil
 | 
						||
}
 | 
						||
 | 
						||
// RecordSickPigDeath 委托给领域服务
 | 
						||
func (s *pigBatchService) RecordSickPigDeath(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error {
 | 
						||
	err := s.domainService.RecordSickPigDeath(operatorID, batchID, penID, quantity, treatmentLocation, happenedAt, remarks)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 记录病猪死亡事件失败, 批次ID: %d, 错误: %v", batchID, err)
 | 
						||
		return MapDomainError(err)
 | 
						||
	}
 | 
						||
	return nil
 | 
						||
}
 | 
						||
 | 
						||
// RecordSickPigCull 委托给领域服务
 | 
						||
func (s *pigBatchService) RecordSickPigCull(operatorID uint, batchID uint, penID uint, quantity int, treatmentLocation models.PigBatchSickPigTreatmentLocation, happenedAt time.Time, remarks string) error {
 | 
						||
	err := s.domainService.RecordSickPigCull(operatorID, batchID, penID, quantity, treatmentLocation, happenedAt, remarks)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 记录病猪淘汰事件失败, 批次ID: %d, 错误: %v", batchID, err)
 | 
						||
		return MapDomainError(err)
 | 
						||
	}
 | 
						||
	return nil
 | 
						||
}
 | 
						||
 | 
						||
// RecordDeath 委托给领域服务
 | 
						||
func (s *pigBatchService) RecordDeath(operatorID uint, batchID uint, penID uint, quantity int, happenedAt time.Time, remarks string) error {
 | 
						||
	err := s.domainService.RecordDeath(operatorID, batchID, penID, quantity, happenedAt, remarks)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 记录正常猪只死亡事件失败, 批次ID: %d, 错误: %v", batchID, err)
 | 
						||
		return MapDomainError(err)
 | 
						||
	}
 | 
						||
	return nil
 | 
						||
}
 | 
						||
 | 
						||
// RecordCull 委托给领域服务
 | 
						||
func (s *pigBatchService) RecordCull(operatorID uint, batchID uint, penID uint, quantity int, happenedAt time.Time, remarks string) error {
 | 
						||
	err := s.domainService.RecordCull(operatorID, batchID, penID, quantity, happenedAt, remarks)
 | 
						||
	if err != nil {
 | 
						||
		s.logger.Errorf("应用层: 记录正常猪只淘汰事件失败, 批次ID: %d, 错误: %v", batchID, err)
 | 
						||
		return MapDomainError(err)
 | 
						||
	}
 | 
						||
	return nil
 | 
						||
}
 |