文档目录
库存变动日志表

简介

本文件为 DouPHP 电商系统的“库存变动日志模块”提供完整的表结构设计文档,聚焦于库存变动记录表 dou_inventory_log。目标包括:

  • 明确字段设计:变动类型、变动数量、变动原因、操作人、时间戳等
  • 覆盖典型业务场景:采购入库、销售出库、调拨入库、盘点调整、损耗扣减
  • 建立审计追踪机制:支持数据追溯与问题排查
  • 给出查询优化、历史数据分析与报表生成的技术方案
  • 面向电商平台开发者提供可落地的库存审计数据模型参考

说明:当前仓库未直接包含 dou_inventory_log 的建表语句或实现代码,本文基于订单与购物车流程中的库存校验点,结合通用电商实践,给出推荐设计与落地方案。

项目结构

围绕库存变动的关键入口与相关界面:

  • 订单结算阶段进行库存校验,并可能根据配置决定是否锁定库存
  • 购物车添加时进行库存检查,避免超卖
  • 后台商品管理页面展示库存字段,便于运营查看与调整
graph TB
A["前端下单"] --> B["订单服务<br/>CheckoutService"]
C["购物车服务<br/>CartService"] --> D["库存校验"]
B --> D
D --> E{"是否启用库存"}
E -- 是 --> F["记录库存变动日志<br/>dou_inventory_log"]
E -- 否 --> G["跳过库存变更"]
H["后台商品页<br/>product.htm"] --> I["查看库存字段"]

核心组件

  • 订单结算服务:在创建订单前对购物车内商品进行库存校验;若启用库存策略,则在支付后或发货环节扣减库存并记录日志
  • 购物车服务:在加入购物车时进行库存检查,防止超卖
  • 后台商品管理:展示商品库存字段,用于日常管理与调整

架构总览

库存变动日志的核心职责是“不可变地记录每一次库存变化”,以支撑审计与追溯。建议采用事件驱动方式,在以下边界点触发日志写入:

  • 订单支付成功或发货时:销售出库
  • 供应商到货入库:采购入库
  • 仓库间调拨:调拨入库/出库
  • 盘点差异:盘点调整
  • 过期/破损:损耗扣减
sequenceDiagram
participant U as "用户"
participant O as "订单服务<br/>CheckoutService"
participant S as "库存服务"
participant DB as "数据库<br/>dou_inventory_log"
participant P as "商品服务<br/>ProductService"
U->>O : 提交订单
O->>O : 校验库存(购物车/订单)
alt 启用库存
O->>S : 扣减库存(或锁定)
S->>DB : 写入库存变动日志
S-->>O : 返回结果
O-->>U : 订单创建/支付成功
else 不启用库存
O-->>U : 继续流程(不写日志)
end
Note over S,DB : 所有库存变动均落库,形成审计轨迹

详细组件分析

表结构:dou_inventory_log(推荐)

  • 设计目标

    • 完整记录每次库存变化的“谁、何时、为何、多少、影响范围”
    • 支持按商品、仓库、单号、类型等多维度检索与统计
    • 保证幂等与可重放,避免重复记账
  • 字段定义(建议)

    • id: 主键,自增
    • item_id: 商品ID(关联商品表)
    • sku_id: 规格SKU ID(可选,精细化到规格)
    • warehouse_id: 仓库ID(多仓场景)
    • type: 变动类型(枚举:采购入库、销售出库、调拨入库、调拨出库、盘点调整、损耗扣减、退货入库、其他)
    • quantity: 变动数量(正数为增加,负数为减少)
    • before_stock: 变动前库存快照(便于核对)
    • after_stock: 变动后库存快照(便于核对)
    • source_type: 来源模块(如 order、purchase、transfer、stocktake、damage、return、manual)
    • source_id: 来源单号/ID(如订单号、采购单号、调拨单号、盘点单号)
    • operator_id: 操作人ID(系统/管理员/会员/第三方)
    • operator_name: 操作人名称(冗余,便于展示)
    • reason: 变动原因(文本,补充说明)
    • remark: 备注(扩展信息,JSON 或文本)
    • created_at: 创建时间(索引)
    • updated_at: 更新时间(可选)
  • 索引建议

    • 复合索引:(item_id, created_at)
    • 复合索引:(warehouse_id, created_at)
    • 索引:(source_type, source_id)
    • 索引:(type, created_at)
    • 索引:(operator_id, created_at)
  • 约束与一致性

    • quantity 必须为非零整数
    • before_stock 与 after_stock 需满足 after_stock = before_stock + quantity
    • 同一 source_type+source_id 应保证幂等(唯一约束或去重逻辑)
erDiagram
DOU_INVENTORY_LOG {
int id PK
int item_id
int sku_id
int warehouse_id
enum type
int quantity
int before_stock
int after_stock
enum source_type
string source_id
int operator_id
string operator_name
text reason
json remark
datetime created_at
datetime updated_at
}

业务场景与日志写入时机

  • 采购入库
    • 触发点:采购单收货确认
    • 类型:采购入库
    • 数量:正数
    • 来源:purchase/purchase_order_id
  • 销售出库
    • 触发点:订单支付成功或发货
    • 类型:销售出库
    • 数量:负数
    • 来源:order/order_sn
  • 调拨入库/出库
    • 触发点:调拨单审核通过
    • 类型:调拨入库/调拨出库
    • 数量:正/负
    • 来源:transfer/transfer_id
  • 盘点调整
    • 触发点:盘点单审核
    • 类型:盘点调整
    • 数量:正/负
    • 来源:stocktake/stocktake_id
  • 损耗扣减
    • 触发点:报损审批
    • 类型:损耗扣减
    • 数量:负数
    • 来源:damage/damage_id
flowchart TD
Start(["开始"]) --> CheckType{"变动类型?"}
CheckType --> |采购入库| Purchase["记录采购入库日志<br/>quantity>0"]
CheckType --> |销售出库| Sale["记录销售出库日志<br/>quantity<0"]
CheckType --> |调拨入库| TransferIn["记录调拨入库日志<br/>quantity>0"]
CheckType --> |调拨出库| TransferOut["记录调拨出库日志<br/>quantity<0"]
CheckType --> |盘点调整| Stocktake["记录盘点调整日志<br/>quantity±"]
CheckType --> |损耗扣减| Damage["记录损耗扣减日志<br/>quantity<0"]
Purchase --> End(["结束"])
Sale --> End
TransferIn --> End
TransferOut --> End
Stocktake --> End
Damage --> End

与现有代码的集成点

  • 订单结算时的库存校验与锁定
    • 在创建订单前后进行库存校验,依据配置决定是否锁定库存
    • 建议在支付成功后执行实际扣减并写入日志
  • 购物车添加时的库存检查
    • 防止超卖,确保可售数量充足
  • 后台商品页
    • 展示库存字段,便于运营人员查看与调整

依赖关系分析

  • 订单服务依赖库存校验能力,并在合适时机触发库存扣减与日志写入
  • 购物车服务依赖库存校验,避免超卖
  • 后台商品管理依赖商品服务,展示库存字段
  • 日志表作为审计事实表,被报表与分析任务读取
graph LR
Order["订单服务"] --> InvLog["库存变动日志"]
Cart["购物车服务"] --> Order
Admin["后台商品管理"] --> Product["商品服务"]
Product --> InvLog
InvLog --> Report["报表与分析"]

性能考虑

  • 索引设计
    • 针对高频查询维度建立复合索引:商品、仓库、时间范围、类型、来源单号
  • 写入优化
    • 批量写入日志(事务内合并),降低IO
    • 使用异步队列处理日志落库,解耦主流程
  • 读优化
    • 报表查询走只读副本或物化视图
    • 分页查询限制时间范围,避免全表扫描
  • 存储规划
    • 按月分表或分区,控制单表大小
    • 冷热数据分离,历史归档至低成本存储

故障排查指南

  • 常见问题
    • 库存不一致:核对 before_stock/after_stock 与 quantity 的一致性
    • 重复记账:检查 source_type+source_id 的唯一性
    • 超卖:核查购物车与订单结算的库存校验路径
  • 定位方法
    • 通过 source_id(订单号/采购单号等)反查日志明细
    • 按时间范围与类型筛选异常记录
    • 结合操作人字段定位人为调整
  • 修复建议
    • 对异常记录进行补录或冲销(新增反向变动行)
    • 完善前置校验与幂等保护

结论

通过引入 dou_inventory_log 表,将库存变动以不可变日志形式固化,可实现:

  • 全链路审计与追溯
  • 精准的问题定位与责任划分
  • 稳定的报表与分析基础 建议在生产环境落地时,结合订单与购物车流程的库存校验点,统一接入日志写入,并配套索引、分区与监控告警策略。

附录

  • 术语
    • 变动类型:描述库存变化的业务含义(采购入库、销售出库等)
    • 来源模块:触发变动的业务模块(order、purchase、transfer 等)
    • 来源单号:关联的业务单据编号(订单号、采购单号等)
  • 扩展建议
    • 支持多仓库、多货主、批次/序列号管理
    • 与财务成本核算对接(移动加权平均、先进先出等)
    • 与WMS/ERP系统集成,双向同步库存状态
添加日期:2026-10-05