diff --git a/internal/domain/recipe/raw_material_service.go b/internal/domain/recipe/raw_material_service.go index 1ade9ec..17befb8 100644 --- a/internal/domain/recipe/raw_material_service.go +++ b/internal/domain/recipe/raw_material_service.go @@ -12,10 +12,18 @@ import ( "gorm.io/gorm" ) +// StockQuerier 定义了从外部领域查询库存的接口。 +// 这样,配方领域就不需要知道库存是如何存储或计算的。 +type StockQuerier interface { + // GetCurrentStock 根据原料ID获取当前库存量。 + GetCurrentStock(ctx context.Context, rawMaterialID uint32) (float32, error) +} + // 定义领域特定的错误 var ( ErrRawMaterialNameConflict = fmt.Errorf("原料名称已存在") ErrRawMaterialNotFound = fmt.Errorf("原料不存在") + ErrStockNotEmpty = fmt.Errorf("原料尚有库存,无法删除") ) // RawMaterialService 定义了原料领域的核心业务服务接口 @@ -33,14 +41,16 @@ type rawMaterialServiceImpl struct { ctx context.Context uow repository.UnitOfWork rawMaterialRepo repository.RawMaterialRepository + stockQuerier StockQuerier } // NewRawMaterialService 创建一个新的 RawMaterialService 实例 -func NewRawMaterialService(ctx context.Context, uow repository.UnitOfWork, rawMaterialRepo repository.RawMaterialRepository) RawMaterialService { +func NewRawMaterialService(ctx context.Context, uow repository.UnitOfWork, rawMaterialRepo repository.RawMaterialRepository, stockQuerier StockQuerier) RawMaterialService { return &rawMaterialServiceImpl{ ctx: ctx, uow: uow, rawMaterialRepo: rawMaterialRepo, + stockQuerier: stockQuerier, } } @@ -116,6 +126,16 @@ func (s *rawMaterialServiceImpl) DeleteRawMaterial(ctx context.Context, id uint3 return fmt.Errorf("获取待删除的原料失败: %w", err) } + // 检查原料是否有库存 + stock, err := s.stockQuerier.GetCurrentStock(serviceCtx, id) + if err != nil { + return fmt.Errorf("检查原料库存失败: %w", err) + } + if stock > 0 { + // 如果库存大于0,返回业务错误,阻止删除 + return ErrStockNotEmpty + } + if err := s.rawMaterialRepo.DeleteRawMaterial(serviceCtx, id); err != nil { return fmt.Errorf("删除原料失败: %w", err) }