tourze / stock-manage-bundle
专注于库存数量管理(Stock Management)
Installs: 301
Dependents: 3
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
Type:symfony-bundle
pkg:composer/tourze/stock-manage-bundle
Requires
- doctrine/collections: ^2.3
- doctrine/dbal: ^4.0
- doctrine/doctrine-bundle: ^2.13
- doctrine/orm: ^3.0
- easycorp/easyadmin-bundle: ^4
- knplabs/knp-menu: ^3.7
- monolog/monolog: ^3.1
- psr/log: ^3|^2|^1
- symfony/config: ^7.3
- symfony/console: ^7.3
- symfony/dependency-injection: ^7.3
- symfony/doctrine-bridge: ^7.3
- symfony/event-dispatcher: ^7.3
- symfony/event-dispatcher-contracts: ^3
- symfony/framework-bundle: ^7.3
- symfony/http-foundation: ^7.3
- symfony/http-kernel: ^7.3
- symfony/property-access: ^7.3
- symfony/routing: ^7.3
- symfony/security-core: ^7.3
- symfony/service-contracts: ^3.6
- symfony/validator: ^7.3
- symfony/yaml: ^7.3
- tourze/bundle-dependency: 1.*
- tourze/doctrine-indexed-bundle: 1.0.*
- tourze/doctrine-timestamp-bundle: 1.1.*
- tourze/doctrine-user-bundle: 1.0.*
- tourze/easy-admin-enum-field-bundle: 1.0.*
- tourze/easy-admin-extra-bundle: 1.0.*
- tourze/easy-admin-menu-bundle: 1.0.*
- tourze/enum-extra: 1.0.*
- tourze/json-rpc-core: 1.0.*
- tourze/product-core-bundle: 1.0.*
- tourze/product-service-contracts: 1.0.*
- tourze/symfony-dependency-service-loader: 1.0.*
Requires (Dev)
- doctrine/doctrine-fixtures-bundle: ^4.0
- doctrine/persistence: ^4.1
- phpstan/phpstan: ^2.1
- phpunit/phpunit: ^11.5
- tourze/phpunit-base: 1.*
- tourze/phpunit-doctrine-entity: 1.*
- tourze/phpunit-enum: 1.*
- tourze/phpunit-symfony-kernel-test: 1.0.*
- tourze/phpunit-symfony-unit-test: 1.*
- tourze/phpunit-symfony-web-test: 1.*
README
一个专注于库存数量管理的 Symfony Bundle,提供完整的库存操作、预占、调拨、预警等功能。
✨ 特性
🎯 核心功能
- 库存批次管理 - 支持批次创建、合并、拆分
- 库存调整 - 支持盘点、报损、报溢等调整类型
- 库存预占 - 支持订单预占和自动过期清理
- 入库出库 - 完整的入库出库流程管理
- 库存日志 - 完整的库存变动追踪
- 库存预警 - 低库存、超库存等多级预警
- 库存快照 - 定期库存快照和趋势分析
- 多种分配策略 - 支持 FIFO/LIFO/FEFO 等库存分配策略
- 虚拟库存 - 支持虚拟库存和组合商品库存
- 库存锁定 - 业务锁定和操作锁定机制
🎨 管理界面
- EasyAdmin 集成 - 完整的后台管理界面
- 向导式操作 - 入库出库向导流程
- 可视化仪表板 - 库存概览和关键指标展示
- 多维度查询 - 按SKU、批次、仓库等维度查询
🔧 技术特性
- 事件驱动 - 完整的事件系统支持扩展
- 异步处理 - 支持队列异步处理库存操作
- 事务安全 - 确保库存操作的事务一致性
- 高性能 - 批量操作和缓存优化
- 可扩展 - 策略模式支持自定义分配算法
📦 安装
使用 Composer 安装:
composer require tourze/stock-manage-bundle
在 config/bundles.php 中注册 Bundle:
return [ // ... Tourze\StockManageBundle\StockManageBundle::class => ['all' => true], ];
🚀 快速开始
基础配置
在 config/packages/stock_manage.yaml 中配置:
stock_manage: default_allocation_strategy: 'fifo' # 默认分配策略 reservation_expire_minutes: 30 # 预占过期时间(分钟) enable_negative_stock: false # 是否允许负库存 alert_thresholds: # 预警阈值配置 low_stock: 10 out_of_stock: 0
创建库存批次
use Tourze\StockManageBundle\Service\StockService; use Tourze\ProductServiceContracts\SKU; $stockService = $container->get(StockService::class); $sku = new SKU('PROD001'); $batch = $stockService->createBatch([ 'sku' => $sku, 'batch_no' => 'BATCH20240101001', 'quantity' => 100, 'unit_cost' => 50.00, 'production_date' => new DateTime('2024-01-01'), 'expiry_date' => new DateTime('2024-12-31'), 'location_id' => 'WH01', 'quality_level' => 'A' ]);
检查库存可用性
$sku = new SKU('PROD001'); $available = $stockService->checkStockAvailability($sku, 10); if ($available) { $stockSummary = $stockService->getAvailableStock($sku); echo "可用库存: " . $stockSummary->getTotalQuantity(); }
库存预占
use Tourze\StockManageBundle\Service\ReservationService; $reservationService = $container->get(ReservationService::class); $sku = new SKU('PROD001'); $reservation = $reservationService->reserve( $sku, 10, new DateTime('+30 minutes'), 'ORDER123' ); // 确认预占 $reservationService->confirm($reservation); // 取消预占 $reservationService->cancel($reservation);
库存调整
use Tourze\StockManageBundle\Enum\StockAdjustmentType; $adjustment = $adjustmentService->createAdjustment([ 'sku' => $sku, 'quantity' => -5, // 盘亏5个 'reason' => '库存盘点', 'type' => StockAdjustmentType::INVENTORY_CHECK, 'operator' => 'admin' ]);
📊 数据模型
核心实体
StockBatch - 库存批次
库存的核心实体,记录每个批次的详细信息:
sku- 商品SKUbatchNo- 批次号quantity- 总数量availableQuantity- 可用数量reservedQuantity- 预留数量lockedQuantity- 锁定数量unitCost- 单位成本productionDate- 生产日期expiryDate- 到期日期locationId- 仓库位置
StockAdjustment - 库存调整
记录库存调整操作:
adjustType- 调整类型(盘点、报损、报溢等)quantity- 调整数量reason- 调整原因status- 调整状态operator- 操作人
StockReservation - 库存预占
管理库存预占记录:
reservationType- 预占类型quantity- 预占数量expireTime- 过期时间sourceType- 预占来源类型sourceId- 预占来源ID
StockInbound - 入库记录
管理入库操作:
inboundType- 入库类型(采购、生产、退货等)quantity- 入库数量supplier- 供应商信息batchNo- 关联批次号
StockOutbound - 出库记录
管理出库操作:
outboundType- 出库类型(销售、调拨、报损等)quantity- 出库数量targetLocation- 目标位置
扩展实体
VirtualStock - 虚拟库存
支持虚拟商品库存管理,用于组合商品或服务类商品。
BundleStock - 组合商品库存
管理组合商品的库存关系,支持父子商品的库存联动。
BusinessStockLock - 业务锁定
业务层面的库存锁定,如大订单锁定、促销锁定等。
OperationalStockLock - 操作锁定
操作层面的库存锁定,防止并发操作冲突。
🔧 服务接口
核心服务
StockService - 库存管理服务
interface StockServiceInterface { public function createBatch(array $data): StockBatch; public function getAvailableStock(SKU $sku, array $criteria = []): StockSummary; public function checkStockAvailability(SKU $sku, int $quantity, array $criteria = []): bool; public function mergeBatches(array $batches, string $targetBatchNo): StockBatch; public function splitBatch(StockBatch $batch, int $splitQuantity, string $newBatchNo): StockBatch; }
ReservationService - 预占服务
interface ReservationServiceInterface { public function reserve(SKU $sku, int $quantity, DateTimeInterface $expireTime, ?string $sourceId = null): StockReservation; public function confirm(StockReservation $reservation): void; public function cancel(StockReservation $reservation): void; public function releaseExpiredReservations(): int; }
InboundService - 入库服务
interface InboundServiceInterface { public function processInbound(array $data): StockInbound; public function completeInbound(StockInbound $inbound): void; public function cancelInbound(StockInbound $inbound): void; }
OutboundService - 出库服务
interface OutboundServiceInterface { public function processOutbound(array $data): StockOutbound; public function completeOutbound(StockOutbound $outbound): void; public function cancelOutbound(StockOutbound $outbound): void; }
分配策略
Bundle 支持多种库存分配策略:
- FifoStrategy - 先进先出策略
- LifoStrategy - 后进先出策略
- FefoStrategy - 先到期先出策略
自定义策略:
use Tourze\StockManageBundle\Service\AllocationStrategy\AbstractAllocationStrategy; class CustomAllocationStrategy extends AbstractAllocationStrategy { public function getStrategyName(): string { return 'custom'; } public function allocate(array $batches, int $quantity, array $criteria = []): array { // 实现自定义分配逻辑 return $allocatedBatches; } }
🎯 管理界面
EasyAdmin 后台
Bundle 提供了完整的 EasyAdmin 后台管理界面:
库存管理
- 库存调整 (
/admin/stock/adjustment) - 库存调整记录管理 - 库存预警 (
/admin/stock/alert) - 库存预警设置和处理 - 库存批次 (
/admin/stock/batch) - 批次详情和管理 - 入库管理 (
/admin/stock/inbound) - 入库单据管理 - 出库管理 (
/admin/stock/outbound) - 出库单据管理 - 库存预占 (
/admin/stock/reservation) - 预占记录管理 - 库存概览 (
/admin/stock/overview) - 总体库存状态
向导界面
- 采购入库向导 - 采购商品入库流程
- 生产入库向导 - 生产完成入库流程
- 调拨入库向导 - 仓库调拨入库流程
- 退货入库向导 - 退货商品入库流程
数据可视化
- 库存趋势图表
- 分类库存分布
- 库存周转率分析
- 预警状态统计
📅 命令行工具
stock-manage:cleanup-expired-reservations
清理过期的库存预占记录:
php bin/console stock-manage:cleanup-expired-reservations
建议设置定时任务定期执行:
# 每分钟执行一次清理 * * * * * php /path/to/project/bin/console stock-manage:cleanup-expired-reservations
stock-manage:generate-alerts
生成库存预警:
php bin/console stock-manage:generate-alerts --level=low --threshold=10
stock-manage:create-snapshot
创建库存快照:
php bin/console stock-manage:create-snapshot --comment="月末快照"
🎭 事件系统
Bundle 提供了完整的事件系统,支持业务扩展:
库存事件
StockCreatedEvent- 库存创建事件StockAdjustedEvent- 库存调整事件StockAllocatedEvent- 库存分配事件StockLockedEvent- 库存锁定事件StockReservedEvent- 库存预占事件StockInboundEvent- 库存入库事件StockOutboundEvent- 库存出库事件
事件监听器示例
use Symfony\Component\EventDispatcher\Attribute\AsEventListener; use Tourze\StockManageBundle\Event\StockAdjustedEvent; #[AsEventListener(event: StockAdjustedEvent::class)] class StockAdjustmentListener { public function __invoke(StockAdjustedEvent $event): void { $adjustment = $event->getAdjustment(); // 发送通知 // 记录审计日志 // 同步到外部系统 } }
内置监听器
StockAlertListener- 库存预警监听器StockAuditListener- 库存审计监听器StockSnapshotListener- 库存快照监听器
🔍 配置参考
完整配置示例
stock_manage: # 分配策略配置 default_allocation_strategy: 'fifo' # 预占配置 reservation: expire_minutes: 30 auto_cleanup: true cleanup_interval: 60 # 秒 # 库存配置 stock: enable_negative: false batch_auto_merge: false default_location: 'DEFAULT' # 预警配置 alerts: enabled: true thresholds: low_stock: 10 out_of_stock: 0 overstock: 1000 notification_channels: ['email', 'webhook'] # 快照配置 snapshot: enabled: true schedule: '0 0 * * *' # 每天0点 retention_days: 30 # 缓存配置 cache: enabled: true ttl: 300 # 5分钟 prefix: 'stock_' # 审计配置 audit: enabled: true log_changes: true include_user_info: true
🧪 测试
运行测试套件:
# 运行所有测试 ./vendor/bin/phpunit packages/stock-manage-bundle/tests # 运行覆盖率测试 ./vendor/bin/phpunit --coverage-html coverage # 运行特定测试 ./vendor/bin/phpunit tests/Service/StockServiceTest.php
测试数据
Bundle 提供了丰富的测试数据固件:
use Tourze\StockManageBundle\DataFixtures\StockBatchFixtures; use Tourze\StockManageBundle\DataFixtures\StockReservationFixtures; // 加载测试数据 $fixtures = new StockBatchFixtures(); $fixtures->load($objectManager);
🔗 API 参考
DTO 对象
StockCheckRequest - 库存检查请求
$request = new StockCheckRequest( sku: new SKU('PROD001'), quantity: 10, locationId: 'WH01', excludeReserved: true );
StockCheckResponse - 库存检查响应
$response = new StockCheckResponse( available: true, totalQuantity: 50, availableQuantity: 30, reservedQuantity: 20, batches: $batchDetails );
JsonRPC 方法
Bundle 提供了 JsonRPC 接口支持:
CheckStockAvailability
// 检查库存可用性 $available = $jsonRpcClient->call('stock.check_availability', [ 'sku' => 'PROD001', 'quantity' => 10, 'location_id' => 'WH01' ]);
ReserveStock
// 预占库存 $reservationId = $jsonRpcClient->call('stock.reserve', [ 'sku' => 'PROD001', 'quantity' => 10, 'expire_minutes' => 30, 'source_id' => 'ORDER123' ]);
🚨 异常处理
异常类型
InsufficientStockException- 库存不足异常BatchNotFoundException- 批次不存在异常DuplicateBatchException- 重复批次异常ReservationNotFoundException- 预占记录不存在异常ReservationExpiredException- 预占已过期异常InvalidQuantityException- 无效数量异常LockException- 锁定异常TransferException- 调拨异常InvalidArgumentException- 参数异常InvalidOperationException- 操作异常
异常处理示例
try { $reservation = $reservationService->reserve($sku, $quantity, $expireTime); } catch (InsufficientStockException $e) { // 处理库存不足 $this->logger->warning('库存不足', [ 'sku' => $sku->getId(), 'requested' => $quantity, 'available' => $e->getAvailableQuantity() ]); } catch (ReservationExpiredException $e) { // 处理预占过期 $this->logger->error('预占已过期', [ 'reservation_id' => $e->getReservationId() ]); }
📈 性能优化
批量操作
// 批量检查库存 $requests = [ new StockCheckRequest(new SKU('PROD001'), 10), new StockCheckRequest(new SKU('PROD002'), 5), // ... ]; $responses = $stockService->batchCheckAvailability($requests);
缓存策略
# 启用查询缓存 doctrine: orm: query_cache_driver: type: redis host: localhost port: 6379
异步处理
# 配置消息队列 framework: messenger: transports: stock: 'doctrine://default?queue_name=stock' routing: 'Tourze\StockManageBundle\Message\StockOperationMessage': stock
🔒 安全考虑
并发控制
- 使用乐观锁防止并发修改
- 库存锁定机制防止超卖
- 事务保证数据一致性
权限控制
security: access_control: - { path: '^/admin/stock', roles: ROLE_STOCK_ADMIN } - { path: '^/api/stock', roles: ROLE_API_USER }
审计日志
所有库存操作都会记录审计日志:
- 操作时间
- 操作用户
- 操作类型
- 变更内容
🤝 贡献指南
欢迎提交 Issue 和 Pull Request!
开发环境设置
# 克隆仓库 git clone https://github.com/tourze/stock-manage-bundle.git # 安装依赖 composer install # 运行测试 ./vendor/bin/phpunit # 代码检查 ./vendor/bin/phpstan
提交规范
- 遵循 PSR-12 编码规范
- 添加单元测试
- 更新相关文档
- 使用语义化提交信息
📄 许可证
本项目采用 MIT 许可证。
🙏 致谢
感谢以下项目:
📞 支持
- 📧 邮箱: support@tourze.com
- 🐛 问题反馈: GitHub Issues
- 📖 文档: 在线文档
注意: 本 Bundle 需要配合 tourze/product-core-bundle 使用,确保已正确安装和配置相关依赖。