文档目录
商品库存接口

简介

本文件面向电商应用开发者,系统化说明商品库存管理的接口能力与实现机制,覆盖以下目标:

  • 商品库存查询接口的 HTTP 方法与参数规范
  • 库存状态检查:库存数量、可售状态、预售/锁定等
  • 库存扣减逻辑:下单锁定、支付确认扣减、订单取消解锁
  • 库存预警:低库存提醒与自动下架(建议方案)
  • 多仓库库存管理:调拨与同步(扩展建议)
  • 库存历史记录与审计:基于订单状态日志的追溯
  • 完整请求/响应示例与事务一致性保障说明

项目结构

围绕库存的核心代码集中在订单域服务层与商品模型层:

  • 库存校验与实时库存计算:OrderStockGuard
  • 订单状态机与付款联动(含库存扣减/解锁):OrderStatusTransition
  • 定时任务(超时未付自动取消并释放库存):OrderScheduledTasks
  • 对外门面:OrderService(聚合库存相关方法)
  • 商品数据模型:Product(包含 stock 字段)
  • 订单明细模型:OrderItem(包含 item_number、stock_lock 等)
  • 小程序商品 API 控制器与路由:ProductController、product.php
graph TB
A["API 层<br/>ProductController"] --> B["商品服务<br/>FrontProductService"]
C["订单门面<br/>OrderService"] --> D["库存守卫<br/>OrderStockGuard"]
C --> E["状态机<br/>OrderStatusTransition"]
C --> F["定时任务<br/>OrderScheduledTasks"]
E --> G["数据库<br/>product / order / order_item"]
D --> G
F --> G

核心组件

  • 库存守卫 OrderStockGuard:提供 checkStock 与 realTimeStock,负责“过期订单回收 + 实时可售库存”的计算与校验。
  • 状态机 OrderStatusTransition:在订单付款成功后扣减实际库存,并在完成态或无物流场景下推进到已完成;同时解锁下单时占用的库存。
  • 定时任务 OrderScheduledTasks:自动取消超时未付款订单,并释放被锁定的库存。
  • 订单门面 OrderService:统一暴露 checkStock、realTimeStock、autoCancelOrder 等方法供上层调用。
  • 商品模型 Product:包含 stock 字段,作为库存源。
  • 订单明细 OrderItem:记录 item_number、stock_lock、order_status 等,用于锁定与状态同步。

架构总览

库存相关的关键流程如下:

  • 下单前校验:调用 OrderService.checkStock → OrderStockGuard.checkStock,先触发 autoCancelOrder 回收过期占用,再计算 realTimeStock 并与配置 site.stock 开关结合判断是否可下单。
  • 下单锁定:创建订单条目时,将对应行标记为 stock_lock=1,表示该数量已被占用。
  • 支付成功:OrderStatusTransition.changeStatus 在 PAID 状态下扣减 product.stock 并增加 sales,同时将 order_item.stock_lock 置为 0(已转为实际扣减)。
  • 超时取消:OrderScheduledTasks.autoCancelOrder 将 PENDING 且超时的订单置为 CANCELLED,并将对应 order_item.stock_lock 置为 0,释放库存。
sequenceDiagram
participant Client as "客户端"
participant API as "ProductController"
participant OS as "OrderService"
participant SG as "OrderStockGuard"
participant ST as "OrderStatusTransition"
participant DB as "数据库"
Client->>API : 获取商品详情/列表
API-->>Client : 返回商品信息(含stock/sales)
Client->>OS : checkStock(module, item_id, number)
OS->>SG : checkStock(...)
SG->>DB : 回收过期订单锁定(autoCancelOrder)
SG->>DB : 读取product.stock
SG->>DB : 计算order_item中stock_lock之和
SG-->>OS : 返回real_time_stock/校验结果
OS-->>Client : 返回校验结果
Note over Client,DB : 下单后order_item.stock_lock=1
Client->>ST : changeStatus(order_sn, PAID)
ST->>DB : 扣减product.stock并增加sales
ST->>DB : 更新order_item.stock_lock=0
ST-->>Client : 返回状态变更结果

详细组件分析

库存查询与校验(checkStock / realTimeStock)

  • 输入参数
    • module:模块名(如 product)
    • item_id:商品 ID
    • number:购买数量
  • 处理逻辑
    • 参数合法性校验
    • 触发 autoCancelOrder 回收过期订单占用的库存
    • 若目标表存在 stock 字段,则读取 stock 并计算 realTimeStock = stock - sum(order_item.item_number where stock_lock=1)
    • 当 site.stock 开启且 number > realTimeStock,返回 out_stock 及剩余库存
    • 否则返回 without_limit
  • 输出字段
    • code:without_limit / out_stock / invalid_params / error
    • real_time_stock:仅在校验库存时返回
    • msg:错误提示文案
flowchart TD
Start(["进入 checkStock"]) --> Validate["校验参数合法性"]
Validate --> |非法| ReturnInvalid["返回 invalid_params"]
Validate --> |合法| AutoCancel["触发 autoCancelOrder 回收过期锁定"]
AutoCancel --> HasStock{"目标表有 stock 字段?"}
HasStock --> |否| ReturnOK["返回 without_limit"]
HasStock --> |是| ReadStock["读取 product.stock"]
ReadStock --> CalcReal["计算 realTimeStock = stock - sum(stock_lock=1)"]
CalcReal --> CheckLimit{"site.stock 开启且 number > realTimeStock?"}
CheckLimit --> |是| ReturnOut["返回 out_stock + real_time_stock"]
CheckLimit --> |否| ReturnOK

库存扣减与解锁(下单锁定、支付确认、订单取消)

  • 下单锁定:创建订单条目时将 stock_lock 置为 1,表示该数量被占用但不扣减实际库存。
  • 支付确认:OrderStatusTransition.changeStatus 在 PAID 状态下:
    • 扣减 product.stock 并增加 sales
    • 将对应 order_item.stock_lock 置为 0
  • 订单取消:OrderScheduledTasks.autoCancelOrder 对超时未付款订单:
    • 将 order.status 置为 CANCELLED
    • 将 order_item.order_status 置为 CANCELLED 并释放 stock_lock=0
    • 若启用 item_link_status,同步模块自身订单状态
sequenceDiagram
participant OI as "order_item"
participant PR as "product"
participant ST as "OrderStatusTransition"
participant OT as "OrderScheduledTasks"
Note over OI : 下单后 stock_lock=1
OT->>OI : 超时取消时 stock_lock=0
ST->>PR : 付款成功后 stock -= item_number
ST->>PR : sales += item_number
ST->>OI : stock_lock=0

库存状态检查(可售/预售/锁定)

  • 可售状态:由 realTimeStock 决定,即 stock 减去被锁定的数量。
  • 预售/锁定:通过 order_item.stock_lock=1 表示被锁定但未扣减;当 payment 成功后才真正扣减。
  • 配置开关:site.stock 控制是否进行库存限制;关闭时仍可展示实时库存值。

库存预警与自动下架(建议方案)

当前代码未内置“低库存阈值自动下架”的逻辑,但可通过以下方式扩展:

  • 监控点:在库存变动后(扣减/释放)或定时任务执行后,比较 product.stock 与阈值,低于阈值时:
    • 设置商品下架标志(例如 status 或自定义字段)
    • 发送低库存通知(短信/站内信/邮件)
  • 触发时机:
    • 支付成功后(扣减)
    • 超时取消后(释放)
    • 定时任务批量扫描(每小时/每天)
  • 幂等性:避免重复下架,使用上次阈值告警时间戳去重。

多仓库库存管理(扩展建议)

当前实现以单仓 product.stock 为主,未体现仓库维度。可扩展方向:

  • 引入仓库表 warehouse 与库存分仓表 warehouse_stock(item_id, warehouse_id, stock, locked)
  • 下单锁定与扣减时按仓库策略分配(就近发货/按比例)
  • 库存调拨:创建调拨单,生成入库/出库流水,保证事务一致
  • 库存同步:跨仓/跨平台同步时采用版本号或事件驱动,避免并发冲突

库存历史记录与审计

  • 订单状态日志:order_status_log 记录每次状态变更(from_status、to_status、reason、operator_type、ip),可用于追踪库存变动的上下文。
  • 订单明细:order_item 记录 item_number、stock_lock、order_status,便于回溯某次下单的锁定与释放。
  • 建议新增:库存操作日志表 inventory_log(item_id、warehouse_id、change_type、quantity、before、after、operator、created_at),用于精细化审计。

依赖关系分析

  • OrderService 聚合 OrderStockGuard、OrderStatusTransition、OrderScheduledTasks,形成稳定的对外签名。
  • OrderStockGuard 依赖 OrderScheduledTasks 进行过期订单回收,确保校验准确性。
  • OrderStatusTransition 在付款成功后修改 product.stock 与 order_item.stock_lock,并写入 order_status_log。
  • 商品模型 Product 提供 stock 字段;订单明细 OrderItem 提供锁定与数量信息。
classDiagram
class OrderService {
+checkStock(module, item_id, number)
+realTimeStock(module, item_id)
+autoCancelOrder(where_conditions)
}
class OrderStockGuard {
+checkStock(module, item_id, number)
+realTimeStock(module, item_id)
}
class OrderStatusTransition {
+changeStatus(order_sn, new_status)
}
class OrderScheduledTasks {
+autoCancelOrder(where_conditions)
}
class Product {
+int stock
}
class OrderItem {
+int item_number
+string stock_lock
+string order_status
}
OrderService --> OrderStockGuard : "委托"
OrderService --> OrderStatusTransition : "委托"
OrderService --> OrderScheduledTasks : "委托"
OrderStockGuard --> OrderScheduledTasks : "依赖"
OrderStatusTransition --> Product : "扣减/销售"
OrderStatusTransition --> OrderItem : "解锁/状态"

性能与一致性

  • 实时库存计算:realTimeStock 通过 sum(order_item.item_number where stock_lock=1) 计算,建议在 order_item 上建立 (module, item_id, stock_lock) 索引以提升聚合性能。
  • 过期订单回收:autoCancelOrder 批量更新,建议在 order 表上建立 (status, created_at) 复合索引。
  • 事务边界:
    • 状态变更与库存扣减在同一事务内提交,失败回滚。
    • 下游联动(积分、分销、会员升级)在事务外派发,失败不影响订单状态。
  • 并发安全:
    • 付款后联动使用 FOR UPDATE 保护,防止重复发放。
    • 库存校验前回收过期锁定,减少竞争条件。

故障排查指南

  • 校验失败(invalid_params):检查传入的 module、item_id、number 是否为空或非法。
  • 库存不足(out_stock):确认 real_time_stock 与 number 的关系,检查是否有大量未付款订单仍锁定库存。
  • 库存不一致:核对 product.stock 与 order_item.stock_lock 的一致性,必要时重新运行 autoCancelOrder。
  • 状态异常:查看 order_status_log,确认状态迁移是否符合预期。

结论

本系统通过 OrderStockGuard、OrderStatusTransition、OrderScheduledTasks 的组合,实现了完整的库存校验、锁定、扣减与释放闭环。配合订单状态日志与订单明细,可提供可靠的库存审计基础。对于低库存预警与多仓库管理,可按建议方案进行扩展,以满足更复杂的业务需求。

附录:API 参考与示例

库存查询接口

  • 说明:用于前端展示商品实时可售库存,或在下单前进行库存校验。
  • 入口:OrderService.checkStock / OrderStockGuard.checkStock
  • 方法:HTTP GET(可由上层控制器封装)
  • 路径:/api/?route=item/check_stock(示例,实际由上层路由定义)
  • 参数
    • module:字符串,商品模块名(如 product)
    • item_id:整数,商品 ID
    • number:整数,购买数量
  • 响应
    • code:without_limit / out_stock / invalid_params / error
    • real_time_stock:整数,仅在校验库存时返回
    • msg:字符串,提示信息
sequenceDiagram
participant C as "客户端"
participant S as "OrderService"
participant G as "OrderStockGuard"
C->>S : GET /api/item/check_stock?module=product&item_id=123&number=2
S->>G : checkStock("product", 123, 2)
G-->>S : {code, real_time_stock?, msg}
S-->>C : JSON 响应

商品详情接口(含库存字段)

  • 说明:小程序商品详情接口,返回商品基本信息与库存字段(stock、sales)。
  • 入口:ProductController.show
  • 方法:HTTP GET
  • 路径:/api/?route=product/show&id=...
  • 响应
    • product:对象,包含 title、image、price、stock、sales 等
    • open:对象,包含 features(如 order 开关)
sequenceDiagram
participant C as "客户端"
participant PC as "ProductController"
participant FPS as "FrontProductService"
C->>PC : GET /api/?route=product/show&id=123
PC->>FPS : buildProductShowData(id, userId)
FPS-->>PC : 商品详情数据
PC-->>C : JSON 响应

请求与响应示例(文本描述)

  • 库存校验请求示例
    • 方法:GET
    • 路径:/api/?route=item/check_stock
    • 参数:module=product&item_id=123&number=2
    • 响应:{code:"without_limit", msg:""} 或 {code:"out_stock", real_time_stock:5, msg:"超出库存数量,剩余库存 5"}
  • 商品详情请求示例
    • 方法:GET
    • 路径:/api/?route=product/show&id=123
    • 响应:{product:{title:"商品标题", stock:100, sales:10}, open:{order:true}}

[以上示例为基于实现行为的描述,非真实代码片段]

事务性与一致性保证

  • 下单锁定:order_item.stock_lock=1 表示占用,不影响 product.stock。
  • 支付确认:在事务内扣减 product.stock 并增加 sales,同时将 stock_lock 置为 0。
  • 超时取消:在事务内将订单置为 CANCELLED,并释放 stock_lock。
  • 状态日志:每次状态变更写入 order_status_log,便于审计与回溯。
添加日期:2026-10-05