下单预占 → 发货实扣 → 退回释放 → 采购入库 | 模块解耦:StockResolver ⇢ StateRouter
| 输入 | lenses: [{sku, sph, cyl}] |
|---|---|
| 输出 | [{stock, reserved, available, inStock}] |
| 输入 | stockResults: [{inStock, inRange}] |
|---|---|
| 输出 | {targetStatus, wfStep, deliveryType} |
{inStock: bool} 一个字段连接
| getStockMap() | 全表缓存(1575行, 2min TTL)— 供 StockResolver 读 |
|---|---|
| queryStockByRx() | 单记录过滤查询 — 供写操作锁内 fresh read |
| reserveStock() | 下单预占: withLock + fresh read + PATCH 预占+=qty |
| convertReservation() | 发货实扣: 库存−1 + 预占−1 原子写入 |
| releaseReservation() | 退回释放: 预占 −= toRelease |
| estimateDeliveryByRx() | 交期预估: 三档判定(有货/排产/定制) |
| POST /api/submit | 写订单 → reserveStock() 预占 |
|---|---|
| POST /api/admin/confirm | resolveStock() → routeConfirm() → 写状态 |
| POST /api/admin/ship | convertReservation() → 写物流 → 发通知 |
| POST /api/admin/revert | 退状态 → releaseReservation() 释放预占 |
| POST /api/admin/procurement | 创建成品采购单 → procurement 表 |
| POST .../procurement/:id/receive | withLock → 库存+N → stock_movement 入库流水 |
| GET /api/admin/stock-detail | 库存列表 + 预占/可用 + SKU 汇总 |
| 字段 | 类型 | 说明 |
|---|---|---|
| SKU编号 | TEXT | 产品型号(与 SKU_CATALOG 一致) |
| SPH / CYL | NUMBER(0.00) | 球镜 / 柱镜,步长 0.25 |
| 当前库存 | NUMBER | 物理在库片数 |
| 预占库存 🆕 | NUMBER | 已被订单预约但未出库的片数 |
| 可用库存 | —(代码计算) | 当前库存 − 预占库存 |
| 安全库存 | NUMBER | 低于此值触发 rule12 库存预警 |
| 最近出库 | DATE | 最后一次出库时间戳 |
| 字段 | 类型 | 写入口径 |
|---|---|---|
| 单据号 | TEXT | MOV-YYYYMMDD-XXXX |
| 类型 | 单选 | 入库 / 出库 |
| 来源去向 | 单选 | 入库: 采购到货、生产回补、退货退回、盘点补录 出库: 订单发货、报废损耗、调拨出库、盘点差异 |
| SKU编号 / SPH / CYL | TEXT/NUMBER | 度数定位 |
| 数量 | NUMBER | 变动片数 |
| 变动前库存 / 变动后库存 | NUMBER | 审计追溯 |
| 关联单号 | TEXT | 订单编号 / 采购编号 / 退换单号 |
| 字段 | 类型 | 说明 |
|---|---|---|
| 采购编号 | TEXT | PO-YYYYMMDD-XXXX |
| 采购类型 | 单选 | 模具 / 毛坯 / 成品 🆕 |
| 关联SKU | TEXT | 产品型号 |
| SPH / CYL 🆕 | NUMBER | 球镜/柱镜(成品采购专用,可选字段) |
| 数量 | NUMBER | 采购片数 |
| 发起日期 / 预计到货 | DATE | 采购时间线 |
| 状态 | 单选 | 待下单 → 已下单 → 已到货 → 已取消 |