getStock($skuCode, $warehouseId); $available = $this->getAvailableQuantity($stock); if ($available < $quantity) { throw new \Exception("商品 {$skuCode} 可用库存不足,当前可用{$available},需占用{$quantity}"); } $stock->increment('locked_quantity', $quantity); StockLog::create([ 'sku_code' => $skuCode, 'warehouse_id' => $warehouseId, 'change_quantity' => $quantity, 'type' => 'lock', 'order_id' => $orderId, 'remark' => "锁定库存,订单ID {$orderId}", ]); return $stock; }); } /** * 获取指定SKU在仓库的可用库存 */ public function checkStock($skuCode, $warehouseId) { $stock = Stock::where('sku_code', $skuCode) ->where('warehouse_id', $warehouseId) ->first(); if (!$stock) { return 0; // 无记录表示库存为0 } return $this->getAvailableQuantity($stock); } /** * 发货出库(扣减锁定库存) */ public function ship($skuCode, $warehouseId, $quantity, $orderId, $trackingNo = null) { if ($quantity <= 0) { throw new \InvalidArgumentException('出库数量必须为正数'); } return DB::transaction(function () use ($skuCode, $warehouseId, $quantity, $orderId, $trackingNo) { $stock = $this->getStock($skuCode, $warehouseId); // 检查锁定库存是否足够 if ($stock->locked_quantity < $quantity) { throw new \Exception("商品 {$skuCode} 锁定库存不足,当前锁定{$stock->locked_quantity},需出库{$quantity}"); } // 扣减总库存和锁定库存 $stock->decrement('quantity', $quantity); $stock->decrement('locked_quantity', $quantity); StockLog::create([ 'sku_code' => $skuCode, 'warehouse_id' => $warehouseId, 'change_quantity' => -$quantity, 'type' => 'ship', 'order_id' => $orderId, 'remark' => "发货出库,订单ID {$orderId},运单号 {$trackingNo}", ]); return $stock; }); } /** * 获取或创建库存记录 */ protected function getStock($skuCode, $warehouseId) { return Stock::firstOrCreate( ['sku_code' => $skuCode, 'warehouse_id' => $warehouseId], [ 'quantity' => 0, 'locked_quantity' => 0, 'defective_quantity' => 0, ] ); } /** * 计算可用库存 */ protected function getAvailableQuantity($stock) { return $stock->quantity - $stock->locked_quantity - $stock->defective_quantity; } }