front/docs/仓储模块设计方案.md
2026-09-05 18:37:50 +08:00

1196 lines
48 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# OMS 仓储模块 — 产品与技术设计方案
> **版本**:v0.3(轻量版 + `C_` 表前缀 + 库位 + 入库箱)
> **基线文档**:`docs/oms系统设计-050801.md`、`docs/rbac系统设计-060801.md`、`docs/前端页面设计规范.md`
> **参考实现**:WMS 六页业务逻辑(**按需裁剪,不做完整 WMS**)
> **对照仓库**:`C:\Users\wilso\Desktop\oms0414-back`(Fake 框架 + SqlSugar)
---
## 0 轻量版总览(推荐阅读)
> v0.1 按 WMS 能力完整对标,**表多、接口多、状态细**。若目标仅是「客户能管 SKU、预报入库、看库存、接店铺单发货」,采用本节 **轻量版** 即可,全文 §1~§11 中标注 **〔轻量〕** / **〔延后〕** 处以此为准。
### 0.1 设计取向
| 项 | v0.1 完整版 | **v0.3 轻量版(当前)** |
| --- | --- | --- |
| 定位 | 对标 WMS 仓储子系统 | OMS 附属 **基础仓储**,保留库位与入库箱 |
| **仓储表命名** | `t_wh_*` | **`C_` + 表名**(如 `C_sku`、`C_inventory`) |
| 数据表 | 18 张 | **13 张**(店铺 4 `t_*` + 仓储 9 `C_*`) |
| 后端 Service | 6 个 | **3 个**(店铺 2 + 仓储 1) |
| 库存模型 | 批次 lot + 冻结 + 流水 | **SKU × 仓库 × 库位** 余额,不做 FIFO/流水 |
| 入库预报 | 箱 → SKU + 收货日志 | **主表 + 箱 + 箱内 SKU**(保留箱号) |
| 组合 SKU / 库存同步 / 拆单 | 一期设计 | **延后** |
| 权限粒度 | 20+ Action | **每页 Query + Save + Delete**(库存加 Relocate) |
### 0.2 表清单
**命名约定**
| 范围 | 前缀 | 示例 |
| --- | --- | --- |
| 仓储模块(本文) | **`C_`** | `C_sku`、`C_inventory`、`C_inbound_box` |
| 订单 — 店铺(归属订单模块) | `t_` | `t_sales_store`、`t_sales_store_order` |
| 系统主数据 | `t_` | `t_warehouse_address` |
**订单 — 店铺(4 张,`t_` 前缀)**
| 表 | 说明 |
| --- | --- |
| `t_sales_store` | 店铺 + Token 合并(Token 加密,列表脱敏) |
| `t_sales_store_order` | 店铺订单主表 |
| `t_sales_store_order_line` | 订单明细 |
| `C_sku_platform_map` | 平台 SKU → 库内 SKU(发货匹配;归属仓储域,用 `C_`) |
**仓储(9 张,`C_` 前缀)**
| 表 | 说明 |
| --- | --- |
| `C_sku` | 我的 SKU |
| `C_bin_location` | 库位主数据(按仓库) |
| `C_inventory` | 库存余额:`CustomerId + WarehouseId + SkuId + BinLocationId → Qty` |
| `C_inbound_notice` | 入库预报主表 |
| `C_inbound_box` | 入库箱(箱号/箱唛) |
| `C_inbound_box_line` | 箱内 SKU 行 |
| `C_parcel` | 我的包裹 |
| `C_parcel_item` | 包裹明细 |
**延后(相对 v0.1 / 原完整版)**
| 原概念 | 处理 |
| --- | --- |
| `t_sales_store_token` | 合并进 `t_sales_store` |
| `t_sales_store_share` / 拆单 / 录单表 | 延后 |
| `C_sku_bundle`(组合 SKU) | 延后 |
| `C_stock_movement`(库存流水) | 延后 |
| `C_inbound_receipt_log`(收货日志) | 延后,状态字段够用 |
### 0.3 轻量版核心流程(够用即可)
```mermaid
flowchart LR
SKU["我的 SKU<br/>C_sku"] --> MAP["平台映射<br/>C_sku_platform_map"]
MAP --> PSO["店铺订单"]
BIN["库位<br/>C_bin_location"]
IBN["入库预报<br/>C_inbound_notice"] --> BOX["入库箱<br/>C_inbound_box"]
BOX --> INV["库存<br/>C_inventory"]
BIN --> INV
PAR["我的包裹<br/>C_parcel"] -->|"上架到库位"| INV
PSO -->|"匹配库存"| INV
PSO -->|"生成小包单"| ORD["t_order"]
```
1. **我的 SKU**:维护库内编码 + 尺重;绑平台 SKU(`C_sku_platform_map`)。
2. **库位**:按仓库维护 `C_bin_location`;库存按 **库位** 记数量。
3. **入库预报**:主表 + **箱号**(`C_inbound_box`)+ 箱内 SKU(`C_inbound_box_line`);收货上架时写入 `C_inventory`。
4. **我的库存**:按 SKU 汇总展示,可展开 **各库位明细**;支持 **换库位**(不调 FIFO、不记流水)。
5. **我的包裹**:预报快递单号;到仓后上架到指定库位。
6. **店铺订单**:库存匹配时按库位扣减 `C_inventory.Qty` 并建 `t_order`。
### 0.4 轻量版接口原则
- 每个页面 **列表 + 详情 + 保存 + 删除**;统计合并为 `summary`。
- 仓储一个 `WarehouseService`(`/warehouse/*`)。
- **保留**:库位列表、入库箱结构、换库位、上架指定库位。
- **不做**:库存流水、FIFO 批次、冻结量、组合 SKU、平台库存回写。
### 0.5 轻量版实施顺序
| 阶段 | 交付 | 说明 | 状态 |
| --- | --- | --- | --- |
| **Step 1 表** | SQL + SqlSugar 实体 | `sql/migrate_warehouse_module.sql` + `Oms.Domain` 实体 | **已完成** |
| **Step 2 接口** | `WarehouseService` + 店铺 Service | `/warehouse/*`、`/order/platform-store*` | **已完成** |
| **Step 3 页面** | 前端 6 页 + 路由 + RBAC 菜单 | `views/warehouse/*`、`order/platformStore*` | **已完成** |
**Step 2 交付物(2026-07-11)**
| 层级 | 路径 |
| --- | --- |
| Repository | `Oms.Domain/WarehouseAggregate/Repositories`、`Oms.SqlSugarCore/Warehouse/`;`OrdersAggregate/Repositories`(店铺) |
| DTO | `Oms.Application/Dtos/Warehouse/`、`Dtos/PlatformStore/` |
| Service | `Services/Warehouse/WarehouseService`;`PlatformStoreService`;`PlatformStoreOrderService` |
**M1~M4 业务分期**
| 阶段 | 交付 | 说明 |
| --- | --- | --- |
| **M1** | `C_sku` + `C_bin_location` + `C_inventory` + 入库预报(含箱) | 5 张 `C_*` 表 + 约 12 接口 |
| **M2** | `C_parcel` + 库存列表/换库位 | +2 张表 + 2 页 |
| **M3** | 店铺授权 + 店铺订单 | +3 表 + 2 Service + 2 页 |
| **M4** | 库存匹配 → `t_order` | 打通订单 | **已完成** |
**M4 交付物(2026-07-11)**
| 项 | 说明 |
| --- | --- |
| `PlatformStoreOrderParcelBuilder` | 店铺订单 → `OrderParcelCreateInput` |
| `POST /order/platform-store-order/match-inventory` | 扣库存 → 创建小包 → 回写 `LinkedOrderId` |
| `POST /order/platform-store-order/batch-match-inventory` | 批量匹配 |
| 前端 | 销售产品选择、关联服务单号、批量匹配按钮 |
---
## 1 导读
### 1.1 这份文档解决什么问题?
将 WMS 中与客户履约相关的 **6 个页面** 迁入 OMS,拆为两块:
| 归属 | 页面 | 原 WMS 路由(参考) |
| --- | --- | --- |
| **订单模块**(扩展现有 §4) | 店铺授权、店铺订单 | `/order/platform/shop`、`/order/platform/shop-orderv2` |
| **仓储模块**(本文新建 §9) | 我的包裹、我的库存、我的 SKU、入库预报 | `/wms/package/package`、`/wms/stock/myinventory2`、`/wms/stock/merchants`、`/wms/stock/warehousingorder` |
设计原则:
1. **表名、字段名、接口路径全部重新命名**,不沿用 WMS 的 `vip_*` / `wms_*` 命名。
2. **业务逻辑对齐 WMS**,在 OMS 会话隔离、分页规范、审计字段上对齐现有 OMS 约定。
3. **与现有 OMS 模块边界清晰**:小包订单(`t_order`)与仓储库存(`C_*`)分离;店铺订单通过 `C_sku_platform_map` 匹配库存。
### 1.2 与 OMS 其它模块的关系
```mermaid
flowchart TB
subgraph Order["订单模块 §4"]
PS["店铺授权<br/>t_sales_store"]
PSO["店铺订单<br/>t_sales_store_order"]
PO["小包订单<br/>t_order"]
end
subgraph Warehouse["仓储模块 C_*"]
BIN["库位<br/>C_bin_location"]
PAR["我的包裹<br/>C_parcel"]
SKU["我的 SKU<br/>C_sku"]
INV["库存<br/>C_inventory"]
IBN["入库预报<br/>C_inbound_notice"]
end
subgraph System["系统主数据 §8"]
WA["仓库地址<br/>t_warehouse_address"]
end
subgraph Operation["操作模块 §6"]
INB["入库扫描<br/>t_inbound_record"]
OUT["出库扫描<br/>t_outbound_record"]
end
PS --> PSO
PSO -->|"SKU 映射 + 库存匹配"| SKU
PSO -->|"一键发货 / 录单"| PO
PAR --> INV
IBN --> INV
BIN --> INV
SKU --> INV
WA --> PAR
WA --> IBN
INB -.->|"小包运单收货"| PO
OUT -.->|"小包运单出库"| PO
```
| 边界 | 说明 |
| --- | --- |
| `t_order` vs `t_sales_store_order` | 前者为 OMS 小包物流订单;后者为电商平台拉取的 **店铺履约单**,二者通过 `LinkedOrderId` 可选关联 |
| `t_warehouse_address` | 仓储业务统一引用系统主数据仓库(`WarehouseId` → `t_warehouse_address.Id`),**不新建**客户侧仓库表 |
| `t_inbound_record` / `t_outbound_record` | 面向 **小包运单**(`WaybillNo`)的仓内扫描;与仓储模块的 **SKU 入库预报 / 包裹到仓** 是不同业务线,表不合并 |
| 客户隔离 | 全模块 `CustomerId` → `t_customer.Id`;规则同 OMS §3.3.5 / §4.4.0 |
### 1.3 建议阅读路径
| 角色 | 路径 |
| --- | --- |
| 产品 / 测试 | **§2 页面与菜单** → **§5 主流程** → **§8 枚举** |
| 后端 / DBA | **§3 表结构** → **§4 接口** → **§7 WMS 对照** |
| 前端 | **§2** → **§4** → `docs/前端页面设计规范.md` |
---
## 2 页面、路由与权限
### 2.1 菜单结构
```
订单(已有 /order)
├── …(查价、下单、我的订单等)
├── 店铺授权 /order/platformStore
└── 店铺订单 /order/platformStoreOrder
仓储(新建 /warehouse)
├── 我的包裹 /warehouse/parcel
├── 我的库存 /warehouse/inventory
├── 我的 SKU /warehouse/sku
└── 入库预报 /warehouse/inboundNotice
```
### 2.2 前端路由(`src/router/routes/newModules/`)
**订单模块扩展**(`order.ts` 追加 children):
| path | name | component | permission |
| --- | --- | --- | --- |
| `platformStore` | `OrderPlatformStore` | `views/order/platformStore/index.vue` | `Order.PlatformStore.Query` |
| `platformStoreOrder` | `OrderPlatformStoreOrder` | `views/order/platformStoreOrder/index.vue` | `Order.PlatformStoreOrder.Query` |
**仓储模块新建**(`warehouse.ts`):
| path | name | component | permission |
| --- | --- | --- | --- |
| `parcel` | `WarehouseParcel` | `views/warehouse/parcel/index.vue` | `Warehouse.Parcel.Query` |
| `inventory` | `WarehouseInventory` | `views/warehouse/inventory/index.vue` | `Warehouse.Inventory.Query` |
| `sku` | `WarehouseSku` | `views/warehouse/sku/index.vue` | `Warehouse.Sku.Query` |
| `inboundNotice` | `WarehouseInboundNotice` | `views/warehouse/inboundNotice/index.vue` | `Warehouse.InboundNotice.Query` |
列表页布局遵循 `docs/前端页面设计规范.md`:`xxx-container`、`table-toolbar`、分页右上角、`PaginationPro` 默认 50 条。
### 2.3 RBAC 权限码
格式:`{Module}.{Resource}.{Action}`(与 RBAC §5.2 一致)。
#### 2.3.1 订单 — 店铺域
| 权限码 | 说明 |
| --- | --- |
| `Order.PlatformStore` | 店铺授权模块 |
| `Order.PlatformStore.Query` | 列表 / 详情 |
| `Order.PlatformStore.Create` | 新增授权 / OAuth 回调落库 |
| `Order.PlatformStore.Update` | 改名、自动发货开关 |
| `Order.PlatformStore.Delete` | 删除店铺 |
| `Order.PlatformStoreOrder` | 店铺订单模块 |
| `Order.PlatformStoreOrder.Query` | 列表 / 详情 / 状态统计 |
| `Order.PlatformStoreOrder.Sync` | 同步平台状态 |
| `Order.PlatformStoreOrder.Rts` | 准备发货(Ready To Ship) |
| `Order.PlatformStoreOrder.MatchInventory` | 匹配库存(映射 SKU 后扣减建单) |
| `Order.PlatformStoreOrder.CreateLogistics` | 创建物流订单 |
| `Order.PlatformStoreOrder.CreateFulfill` | 创建物流&代发订单 |
| `Order.PlatformStoreOrder.Suspend` | 搁置 / 取消搁置 |
| `Order.PlatformStoreOrder.Delete` | 删除 |
| `Order.PlatformStoreOrder.Export` | 导出 |
| `Order.PlatformStoreOrder.Label` | 获取 / 打印面单 |
| `Order.PlatformStoreOrder.Tag` | 自定义标签 |
#### 2.3.2 仓储域 **〔轻量:每资源 3 个权限即可〕**
| 权限码 | 说明 |
| --- | --- |
| `Warehouse.Sku.Query` / `.Save` / `.Delete` | 我的 SKU |
| `Warehouse.InboundNotice.Query` / `.Save` / `.Delete` | 入库预报 |
| `Warehouse.Parcel.Query` / `.Save` / `.Delete` | 我的包裹 |
| `Warehouse.Inventory.Query` / `.Relocate` | 我的库存(查询 + 换库位) |
| `Warehouse.BinLocation.Query` / `.Save` | 库位维护(管理端/仓库端) |
**〔延后〕**:ApplyStorage、Putaway、Relocate、Adjust、Import、Mapping、Print 等细粒度 Action — 首期 Save 接口内覆盖。
### 2.4 后端 Service 与路由前缀 **〔轻量〕**
| 业务域 | Service 类 | 路由前缀 |
| --- | --- | --- |
| 店铺授权 | `PlatformStoreService` | `/order/platform-store/*` |
| 店铺订单 | `PlatformStoreOrderService` | `/order/platform-store-order/*` |
| 仓储(合并) | **`WarehouseService`** | `/warehouse/*` |
> 轻量版仓储 **一个 Service** 即可,按子路径分 SKU / 入库 / 包裹 / 库存。
---
## 3 数据表结构设计
> 遵循 OMS §3.1 公共规范。
> **轻量版以 §0.2 为准**;下列分节含完整版字段,标注 **〔延后〕** 的表/字段在轻量版中不建。
### 3.0 轻量版表结构(v0.3 推荐落地)
> **仓储表一律 `C_` 前缀**;字段仍用 OMS 驼峰(`PascalCase`);必备审计字段见 §3.1 公共规范。
#### 3.0.1 `t_sales_store`(店铺,含 Token)
在 §3.1.1 基础上 **合并** Token,新增:`AccessToken`、`RefreshToken`、`TokenExtraJson`(加密,列表脱敏)。
#### 3.0.2 `C_sku`(我的 SKU)
| 字段 | 类型 | 非空 | 说明 |
| --- | --- | --- | --- |
| Id | BIGINT | 是 | 主键 |
| CustomerId | BIGINT | 是 | 客户 |
| SkuCode | VARCHAR(64) | 是 | 库内编码 |
| SkuName | VARCHAR(256) | 是 | 名称 |
| SkuImageUrl | VARCHAR(512) | 否 | 图片 |
| WeightG / LengthCm / WidthCm / HeightCm | DECIMAL | 否 | 尺重 |
| Remark | VARCHAR(512) | 否 | 备注 |
| 审计字段 | — | 是 | |
**索引**:`uk_c_sku_code` (`CustomerId`, `SkuCode`)。
#### 3.0.3 `C_bin_location`(库位)
| 字段 | 类型 | 非空 | 说明 |
| --- | --- | --- | --- |
| Id | BIGINT | 是 | 主键 |
| WarehouseId | BIGINT | 是 | → `t_warehouse_address.Id` |
| BinCode | VARCHAR(32) | 是 | 库位编码,如 `A-01-02` |
| BinName | VARCHAR(64) | 否 | 展示名称 |
| ZoneCode | VARCHAR(32) | 否 | 库区 |
| IsEnabled | TINYINT | 是 | 是否启用,默认 1 |
| Remark | VARCHAR(512) | 否 | 备注 |
| 审计字段 | — | 是 | |
**索引**:`uk_c_bin_wh_code` (`WarehouseId`, `BinCode`)。
> 库位为 **仓库级主数据**(不按客户拆分);库存余额按客户 + 库位区分。
#### 3.0.4 `C_inventory`(库存余额)
| 字段 | 类型 | 非空 | 说明 |
| --- | --- | --- | --- |
| Id | BIGINT | 是 | 主键 |
| CustomerId | BIGINT | 是 | 客户 |
| WarehouseId | BIGINT | 是 | 仓库 |
| SkuId | BIGINT | 是 | → `C_sku.Id` |
| BinLocationId | BIGINT | 是 | → `C_bin_location.Id` |
| Qty | INT | 是 | 可用数量(匹配时直接扣减) |
| 审计字段 | — | 是 | |
**唯一索引**:`uk_c_inventory` (`CustomerId`, `WarehouseId`, `SkuId`, `BinLocationId`)。
> 「我的库存」列表:按 `SkuId` 聚合 `SUM(Qty)`;详情/换库位:按 `BinLocationId` 展开。
> **不做**冻结量、FIFO 批次、库存流水表。
#### 3.0.5 `C_inbound_notice` + `C_inbound_box` + `C_inbound_box_line`(入库预报,含箱号)
**主表 `C_inbound_notice`**
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| CustomerId | BIGINT | 客户 |
| WarehouseId | BIGINT | 仓库 |
| NoticeNo | VARCHAR(32) | `IN` + 雪花 |
| MarkReference | VARCHAR(64) | 唛头 |
| InboundType | VARCHAR(16) | `normal` / `return` |
| ReceiptStatus | VARCHAR(16) | `forecasted` → `received` → `completed` |
| ExpectedArrivalTime | DATETIME | 可选 |
| ActualArrivalTime | DATETIME | 收货时写入 |
| Remark | VARCHAR(512) | |
**箱表 `C_inbound_box`**
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| InboundNoticeId | BIGINT | 主表 |
| BoxSeqNo | VARCHAR(16) | 箱序号 |
| MarkBoxNo | VARCHAR(64) | **箱唛号/箱号** |
| WeightG | DECIMAL(10,2) | 箱重(g),可选 |
| LengthCm / WidthCm / HeightCm | DECIMAL | 箱尺寸,可选 |
| IsReceived | TINYINT | 是否已收货 |
**箱内 SKU 行 `C_inbound_box_line`**
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| InboundBoxId | BIGINT | 箱 |
| SkuId | BIGINT | → `C_sku.Id` |
| SkuCode | VARCHAR(64) | 冗余编码 |
| PlannedQty | INT | 计划数量 |
| ReceivedQty | INT | 实收数量 |
| BinLocationId | BIGINT | 上架库位(收货确认时填入) |
**收货上架逻辑**:`confirm-receive` 按箱清点 → 按行 `ReceivedQty` + `BinLocationId` **累加** `C_inventory.Qty` → 主表 `completed`。
#### 3.0.6 `C_parcel` + `C_parcel_item`(我的包裹)
**主表**:`TrackingNo`、`CarrierName`、`WarehouseId`、`LifecycleStatus`(`inTransit` / `arrived` / `stored`)、`ArrivalTime`、`Remark`。
**明细**:`ProductName`、`Quantity`、`SkuId`(上架时关联)、`BinLocationId`(上架库位,可选)。
#### 3.0.7 `C_sku_platform_map`(平台 SKU 映射)
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| CustomerId | BIGINT | 客户 |
| StoreId | BIGINT | → `t_sales_store.Id` |
| PlatformSku | VARCHAR(128) | 平台 listing SKU |
| SkuId | BIGINT | → `C_sku.Id` |
| SkuCode | VARCHAR(64) | 冗余 |
**索引**:`uk_c_sku_map` (`StoreId`, `PlatformSku`)。
#### 3.0.8 `t_sales_store_order`(店铺订单,字段精简)
保留核心字段 + 明细行;`MappedSkuId` 指向 `C_sku.Id`。拆单/录单表延后。
---
### 3.1 订单模块 — 店铺授权
#### 3.1.1 销售店铺表 `t_sales_store`
| 字段名 | 类型 | 非空 | 说明 |
| --- | --- | --- | --- |
| Id | BIGINT | 是 | 主键 |
| CustomerId | BIGINT | 是 | 客户 Id |
| PlatformCode | VARCHAR(32) | 是 | 平台:`lazada` / `shopee` / `tiktok` / `temu` / `manual` |
| StoreNickname | VARCHAR(128) | 是 | 店铺昵称(用户自定义) |
| PlatformStoreId | VARCHAR(64) | 否 | 平台侧店铺 Id |
| PlatformAccount | VARCHAR(128) | 否 | 平台账号 |
| SiteCountry | VARCHAR(8) | 否 | 开户站点国家码 |
| SellerId | VARCHAR(64) | 否 | 平台卖家 Id |
| AuthStatus | VARCHAR(16) | 是 | `active` / `expired` / `revoked` |
| AuthTime | DATETIME | 否 | 授权时间 |
| TokenExpireTime | DATETIME | 否 | Access Token 过期 |
| RefreshExpireTime | DATETIME | 否 | Refresh Token 过期 |
| IsAutoFulfill | TINYINT | 是 | 是否自动发货,默认 0 |
| SortOrder | INT | 否 | 排序 |
| Remark | VARCHAR(512) | 否 | 备注 |
| IsDeleted / 审计字段 | — | 是 | 见 §3.1 公共规范 |
**索引**:`idx_sales_store_customer` (`CustomerId`, `IsDeleted`);`uk_sales_store_platform` (`CustomerId`, `PlatformCode`, `PlatformStoreId`) 唯一(`PlatformStoreId` 为空时 manual 店铺允许多条)。
#### 3.1.2 店铺授权凭证表 `t_sales_store_token` **〔轻量:合并至 3.0.1,不单独建表〕**
> 敏感字段加密存储;列表接口 **不返回** `AccessToken` / `RefreshToken` 明文。
| 字段名 | 类型 | 非空 | 说明 |
| --- | --- | --- | --- |
| Id | BIGINT | 是 | 主键 |
| StoreId | BIGINT | 是 | → `t_sales_store.Id` |
| AccessToken | VARCHAR(2048) | 否 | 加密 |
| RefreshToken | VARCHAR(2048) | 否 | 加密 |
| TokenType | VARCHAR(32) | 否 | 默认 `Bearer` |
| Scope | VARCHAR(512) | 否 | 授权范围 |
| ExtraJson | JSON | 否 | 平台扩展(如 Lazada 多站点 userId) |
| IsDeleted / 审计字段 | — | 是 | |
#### 3.1.3 店铺共享表 `t_sales_store_share` **〔延后〕**
| 字段名 | 类型 | 非空 | 说明 |
| --- | --- | --- | --- |
| Id | BIGINT | 是 | 主键 |
| StoreId | BIGINT | 是 | 主店铺 |
| SharedCustomerId | BIGINT | 是 | 被共享的子客户 Id |
| IsDeleted / 审计字段 | — | 是 | |
---
### 3.2 订单模块 — 店铺订单
#### 3.2.1 店铺订单表 `t_sales_store_order`
| 字段名 | 类型 | 非空 | 说明 |
| --- | --- | --- | --- |
| Id | BIGINT | 是 | 主键 |
| CustomerId | BIGINT | 是 | 客户 Id |
| StoreId | BIGINT | 是 | → `t_sales_store.Id` |
| PlatformCode | VARCHAR(32) | 是 | 冗余平台码 |
| PlatformOrderNo | VARCHAR(64) | 是 | 平台订单号 |
| OrderCountry | VARCHAR(8) | 否 | 订单国家 |
| ItemCount | INT | 否 | 商品行数 |
| TotalAmount | DECIMAL(18,4) | 否 | 订单总额 |
| Currency | VARCHAR(8) | 否 | 币种 |
| PaymentMethod | VARCHAR(64) | 否 | 付款方式 |
| PlatformOrderTime | DATETIME | 否 | 平台下单时间 |
| PlatformPayTime | DATETIME | 否 | 平台付款时间 |
| FulfillStatus | VARCHAR(32) | 是 | 履约状态,见 §8.1 |
| PlatformStatus | VARCHAR(64) | 否 | 平台原始状态码 |
| PlatformStatusLabel | VARCHAR(128) | 否 | 平台状态展示文案 |
| ShippingLabelNo | VARCHAR(64) | 否 | 面单号 |
| ShippingLabelUrl | VARCHAR(512) | 否 | 面单文件 URL |
| IsMultiLabel | TINYINT | 是 | 是否多面单/拆单 |
| DeliveryMethod | VARCHAR(64) | 否 | 运输方式 code |
| DeliveryMethodLabel | VARCHAR(128) | 否 | 运输方式展示 |
| DeliveryStatus | VARCHAR(32) | 否 | 物流子状态 |
| ShippingCarrier | VARCHAR(64) | 否 | 物流承运商 |
| PickupType | VARCHAR(32) | 否 | 取件类型:`pickup` / `dropoff` |
| CustomTags | VARCHAR(512) | 否 | 用户自定义标签,逗号分隔 |
| IsSuspended | TINYINT | 是 | 是否搁置 |
| PresaleDays | INT | 否 | 预售天数 |
| BuyerRemark | VARCHAR(1024) | 否 | 买家备注 |
| SellerPickRemark | VARCHAR(1024) | 否 | 卖家拣货备注 |
| SellerPickRemarkTime | DATETIME | 否 | 拣货备注时间 |
| WarehouseId | BIGINT | 否 | 发货仓库 → `t_warehouse_address.Id` |
| LinkedOrderId | BIGINT | 否 | 关联 OMS 小包订单 `t_order.Id` |
| LastSyncTime | DATETIME | 否 | 最近同步时间 |
| StatusChangedTime | DATETIME | 否 | 状态变更时间 |
| SystemShipTime | DATETIME | 否 | 系统发货时间 |
| SystemLabelPrintTime | DATETIME | 否 | 系统打印面单时间 |
| SystemPushTime | DATETIME | 否 | 推送到出库时间 |
| IsDeleted / 审计字段 | — | 是 | |
**索引**:`uk_store_order_no` (`StoreId`, `PlatformOrderNo`);`idx_store_order_customer_status` (`CustomerId`, `FulfillStatus`, `PlatformOrderTime`)。
#### 3.2.2 店铺订单明细表 `t_sales_store_order_line`
| 字段名 | 类型 | 非空 | 说明 |
| --- | --- | --- | --- |
| Id | BIGINT | 是 | 主键 |
| StoreOrderId | BIGINT | 是 | → `t_sales_store_order.Id` |
| PlatformLineId | VARCHAR(64) | 否 | 平台行 Id / itemId |
| PlatformSku | VARCHAR(128) | 否 | 平台 SKU |
| ProductName | VARCHAR(512) | 否 | 商品名称 |
| ProductImageUrl | VARCHAR(512) | 否 | 商品图 |
| ProductUrl | VARCHAR(512) | 否 | 商品链接 |
| VariantText | VARCHAR(256) | 否 | 规格属性 |
| UnitPrice | DECIMAL(18,4) | 否 | 单价 |
| Quantity | INT | 是 | 数量 |
| Currency | VARCHAR(8) | 否 | 币种 |
| IsShipExcluded | TINYINT | 是 | 是否拒绝发货 |
| MappedSkuId | BIGINT | 否 | 映射的仓储 SKU → `C_sku.Id` |
| IsDeleted / 审计字段 | — | 是 | |
#### 3.2.3 店铺订单快速录单表 `t_sales_store_order_draft` **〔延后〕**
#### 3.2.4 店铺订单拆单表 `t_sales_store_order_split` **〔延后〕**
---
### 3.3 仓储模块 — 我的包裹
#### 3.3.1 客户包裹表 `C_parcel`
| 字段名 | 类型 | 非空 | 说明 |
| --- | --- | --- | --- |
| Id | BIGINT | 是 | 主键 |
| CustomerId | BIGINT | 是 | 客户 Id |
| WarehouseId | BIGINT | 是 | → `t_warehouse_address.Id` |
| TrackingNo | VARCHAR(64) | 是 | 快递单号 |
| CarrierName | VARCHAR(64) | 否 | 快递公司 |
| SourcePlatform | VARCHAR(32) | 否 | 来源平台(淘宝、拼多多等) |
| ParcelCategory | VARCHAR(16) | 是 | `single` 一票一单 / `multi` 一票多单 / `unclaimed` 待认领 / `stock` 库存件 |
| LifecycleStatus | VARCHAR(16) | 是 | 见 §8.2:`inTransit` / `arrived` / `unclaimed` / `expired` |
| PurchaseOrderNo | VARCHAR(64) | 否 | 采购订单号(与 OMS 小包无关) |
| BizScene | VARCHAR(16) | 否 | 业务场景,如 `consolidation` 集运 |
| ImageUrl | VARCHAR(512) | 否 | 包裹图片 |
| LengthCm | DECIMAL(10,2) | 否 | 长(cm) |
| WidthCm | DECIMAL(10,2) | 否 | 宽(cm) |
| HeightCm | DECIMAL(10,2) | 否 | 高(cm) |
| VolumeCbm | DECIMAL(12,4) | 否 | 体积 |
| WeightKg | DECIMAL(10,3) | 否 | 重量(kg) |
| ArrivalTime | DATETIME | 否 | 到仓时间 |
| LinkedSkuId | BIGINT | 否 | 关联仓储 SKU |
| Remark | VARCHAR(512) | 否 | 备注 |
| IsDeleted / 审计字段 | — | 是 | |
**索引**:`uk_c_parcel_tracking` (`CustomerId`, `TrackingNo`, `WarehouseId`);`idx_c_parcel_status` (`CustomerId`, `LifecycleStatus`)。
#### 3.3.2 包裹明细表 `C_parcel_item`
| 字段名 | 类型 | 非空 | 说明 |
| --- | --- | --- | --- |
| Id | BIGINT | 是 | 主键 |
| ParcelId | BIGINT | 是 | → `C_parcel.Id` |
| ProductName | VARCHAR(512) | 否 | 商品名称 |
| ProductCategory | VARCHAR(64) | 否 | 商品分类 |
| Quantity | INT | 是 | 数量 |
| ImageUrl | VARCHAR(512) | 否 | 图片 |
| AttributeText | VARCHAR(256) | 否 | 属性 |
| SkuId | BIGINT | 否 | 库内 SKU(上架时关联) |
| SkuCode | VARCHAR(64) | 否 | 冗余编码 |
| BinLocationId | BIGINT | 否 | 上架库位 |
| IsDeleted / 审计字段 | — | 是 | |
---
### 3.4 仓储模块 — 我的 SKU
#### 3.4.1 仓储 SKU 主表 `C_sku`
| 字段名 | 类型 | 非空 | 说明 |
| --- | --- | --- | --- |
| Id | BIGINT | 是 | 主键 |
| CustomerId | BIGINT | 是 | 客户 Id |
| SkuCode | VARCHAR(64) | 是 | 库内 SKU 编码 |
| SkuName | VARCHAR(256) | 是 | SKU 名称 |
| SkuImageUrl | VARCHAR(512) | 否 | 图片 |
| CategoryCode | VARCHAR(64) | 否 | 分类 |
| IsBundle | TINYINT | 是 | 是否组合 SKU |
| WeightG | DECIMAL(10,2) | 否 | 重量(g) |
| LengthCm | DECIMAL(10,2) | 否 | 长(cm) |
| WidthCm | DECIMAL(10,2) | 否 | 宽(cm) |
| HeightCm | DECIMAL(10,2) | 否 | 高(cm) |
| ReferencePrice | DECIMAL(18,4) | 否 | 参考价 |
| Currency | VARCHAR(8) | 否 | 币种 |
| Remark | VARCHAR(512) | 否 | 备注 |
| IsDeleted / 审计字段 | — | 是 | |
**索引**:`uk_c_sku_code` (`CustomerId`, `SkuCode`)。
#### 3.4.2 组合 SKU 子项表 `C_sku_bundle_item` **〔延后〕**
#### 3.4.3 平台 SKU 映射表 `C_sku_platform_map`
| 字段名 | 类型 | 非空 | 说明 |
| --- | --- | --- | --- |
| Id | BIGINT | 是 | 主键 |
| CustomerId | BIGINT | 是 | 客户 Id |
| StoreId | BIGINT | 是 | → `t_sales_store.Id` |
| PlatformSku | VARCHAR(128) | 是 | 平台 listing SKU |
| PlatformProductId | VARCHAR(64) | 否 | 平台商品 Id |
| SkuId | BIGINT | 是 | → `C_sku.Id` |
| SkuCode | VARCHAR(64) | 是 | 冗余库内编码 |
| IsDeleted / 审计字段 | — | 是 | |
**索引**:`uk_c_sku_map` (`StoreId`, `PlatformSku`)。
---
### 3.5 仓储模块 — 我的库存
#### 3.5.1 库存余额表 `C_inventory`(见 §3.0.4)
#### 3.5.2 库位表 `C_bin_location`(见 §3.0.3)
#### 3.5.3 库存流水表 `C_stock_movement` **〔延后〕**
---
### 3.6 仓储模块 — 入库预报
#### 3.6.1 入库预报主表 `C_inbound_notice`
| 字段名 | 类型 | 非空 | 说明 |
| --- | --- | --- | --- |
| Id | BIGINT | 是 | 主键 |
| CustomerId | BIGINT | 是 | 客户 Id |
| WarehouseId | BIGINT | 是 | 仓库 |
| NoticeNo | VARCHAR(32) | 是 | 入库单号,规则 `IN` + 雪花 Id |
| MarkReference | VARCHAR(64) | 否 | 唛头参考号 |
| InboundType | VARCHAR(16) | 是 | `normal` 普通 / `return` 退货 |
| ReceiptStatus | VARCHAR(16) | 是 | 见 §8.4 |
| FirstMileCarrier | VARCHAR(64) | 否 | 头程物流 |
| FirstMileTrackingNo | VARCHAR(64) | 否 | 头程单号 |
| ExpectedArrivalTime | DATETIME | 否 | 预计到货 |
| ActualArrivalTime | DATETIME | 否 | 实际到货 |
| IsException | TINYINT | 是 | 是否异常件 |
| ExceptionNote | VARCHAR(1024) | 否 | 异常说明 |
| ExceptionImageUrls | VARCHAR(2048) | 否 | 异常图片,分号分隔 |
| CustomerFeedback | TINYINT | 否 | 客户是否已确认异常 |
| Remark | VARCHAR(512) | 否 | 备注 |
| IsDeleted / 审计字段 | — | 是 | |
**索引**:`uk_c_inbound_notice_no` (`NoticeNo`);`idx_c_inbound_customer_status` (`CustomerId`, `ReceiptStatus`)。
#### 3.6.2 入库箱表 `C_inbound_box`(见 §3.0.5)
| 字段名 | 类型 | 非空 | 说明 |
| --- | --- | --- | --- |
| Id | BIGINT | 是 | 主键 |
| InboundNoticeId | BIGINT | 是 | → `C_inbound_notice.Id` |
| BoxSeqNo | VARCHAR(16) | 是 | 箱序号 |
| MarkBoxNo | VARCHAR(64) | 否 | 箱唛号/箱号 |
| WeightG | DECIMAL(10,2) | 否 | 箱重(g) |
| LengthCm / WidthCm / HeightCm | DECIMAL(10,2) | 否 | 箱尺寸 |
| IsReceived | TINYINT | 是 | 是否已收货 |
| 审计字段 | — | 是 | |
#### 3.6.3 入库箱 SKU 行表 `C_inbound_box_line`(见 §3.0.5)
| 字段名 | 类型 | 非空 | 说明 |
| --- | --- | --- | --- |
| Id | BIGINT | 是 | 主键 |
| InboundBoxId | BIGINT | 是 | → `C_inbound_box.Id` |
| SkuId | BIGINT | 是 | → `C_sku.Id` |
| SkuCode | VARCHAR(64) | 是 | 冗余编码 |
| PlannedQty | INT | 是 | 计划入库数量 |
| ReceivedQty | INT | 否 | 实收数量 |
| BinLocationId | BIGINT | 否 | 上架库位(收货时填) |
| 审计字段 | — | 是 | |
#### 3.6.4 入库收货日志表 `C_inbound_receipt_log` **〔延后〕**
---
## 4 接口设计
> 分页:`{ items, total }`;默认 `pageSize=30`。客户隔离同 §6。
> **轻量版接口以 §4.0 为准**;§4.1~§4.6 为完整版参考。
### 4.0 轻量版接口清单(推荐)
#### 仓储 `WarehouseService` — 共 **20 个**
| 页面 | 方法 | 路径 | 说明 |
| --- | --- | --- | --- |
| SKU | POST | `/warehouse/sku/list` | 列表 |
| SKU | GET | `/warehouse/sku/detail` | 详情 |
| SKU | POST | `/warehouse/sku/save` | 新增/编辑 |
| SKU | POST | `/warehouse/sku/delete` | 删除 |
| SKU | POST | `/warehouse/sku/bind-mapping` | 绑定平台 SKU |
| 库位 | POST | `/warehouse/bin-location/list` | 按仓库查库位 |
| 库位 | POST | `/warehouse/bin-location/save` | 新增/编辑库位 |
| 入库 | POST | `/warehouse/inbound/list` | 列表 |
| 入库 | GET | `/warehouse/inbound/detail` | 详情含 `boxes[].lines[]` |
| 入库 | POST | `/warehouse/inbound/save` | 新增/编辑(含箱号,仅 forecasted) |
| 入库 | POST | `/warehouse/inbound/delete` | 删除 |
| 入库 | POST | `/warehouse/inbound/confirm-receive` | 按箱收货上架 → 写 `C_inventory` |
| 入库 | GET | `/warehouse/inbound/summary` | 状态 Tab 数量 |
| 包裹 | POST | `/warehouse/parcel/list` | 列表 |
| 包裹 | POST | `/warehouse/parcel/save` | 新增/编辑 |
| 包裹 | POST | `/warehouse/parcel/delete` | 删除 |
| 包裹 | POST | `/warehouse/parcel/putaway` | 到仓上架(指定 `binLocationId`) |
| 库存 | POST | `/warehouse/inventory/list` | 按 SKU 聚合列表 |
| 库存 | GET | `/warehouse/inventory/bin-detail` | 某 SKU 各库位明细 |
| 库存 | POST | `/warehouse/inventory/relocate` | 换库位(源库位 → 目标库位) |
#### 店铺 — 共 **14 个**(首期可再砍)
| 页面 | 方法 | 路径 | 说明 |
| --- | --- | --- | --- |
| 授权 | POST | `/order/platform-store/list` | 列表 |
| 授权 | POST | `/order/platform-store/auth-url` | OAuth |
| 授权 | POST | `/order/platform-store/save` | 改名等 |
| 授权 | POST | `/order/platform-store/delete` | 删除 |
| 订单 | POST | `/order/platform-store-order/list` | 列表 |
| 订单 | GET | `/order/platform-store-order/detail` | 详情 |
| 订单 | GET | `/order/platform-store-order/summary` | 状态统计(合并多个 count 接口) |
| 订单 | POST | `/order/platform-store-order/sync-status` | 同步 |
| 订单 | POST | `/order/platform-store-order/ready-to-ship` | RTS |
| 订单 | POST | `/order/platform-store-order/match-inventory` | 库存匹配 → `t_order` |
| 订单 | POST | `/order/platform-store-order/fetch-label` | 面单 |
| 订单 | POST | `/order/platform-store-order/toggle-suspend` | 搁置 |
| 订单 | POST | `/order/platform-store-order/delete` | 删除 |
**入库 `save` 请求(含箱号)**
```json
{
"id": 0,
"warehouseId": 1,
"markReference": "MARK-001",
"inboundType": "normal",
"remark": "",
"boxes": [
{
"boxSeqNo": "1",
"markBoxNo": "BOX-001",
"weightG": 1200,
"lengthCm": 40,
"widthCm": 30,
"heightCm": 20,
"lines": [
{ "skuId": 1001, "skuCode": "SKU-A001", "plannedQty": 50 }
]
}
]
}
```
**`confirm-receive` 请求要点**:按箱提交实收数量及每行 `binLocationId`,服务端 upsert `C_inventory`。
**库存匹配**:按 `C_sku_platform_map` 解析 SKU,从指定库位(或默认库位)扣减 `C_inventory.Qty`;不足则失败;不记流水。
---
### 4.1 订单 — 店铺授权 `/order/platform-store/*`(完整版参考)
| 接口 | 方法 | 路径 | 说明 |
| --- | --- | --- | --- |
| 店铺列表 | POST | `/order/platform-store/list` | 分页;筛 `platformCode`、`storeNickname`、授权到期 |
| 授权 URL | POST | `/order/platform-store/auth-url` | 获取 OAuth 跳转地址 |
| OAuth 回调落库 | POST | `/order/platform-store/auth-callback` | 各平台 token 写入 `t_sales_store_token` |
| 店铺详情 | GET | `/order/platform-store/detail` | `id` |
| 改名 | POST | `/order/platform-store/rename` | `id`, `storeNickname` |
| 删除 | POST | `/order/platform-store/delete` | `ids[]` |
| 自动发货开关 | POST | `/order/platform-store/toggle-auto-fulfill` | `ids[]`, `enabled` |
| 到期提醒统计 | GET | `/order/platform-store/expiration-stats` | 即将过期 / 已过期数量 |
| 状态统计 | POST | `/order/platform-store/dashboard-stats` | 按平台汇总店铺与订单数 |
**列表请求示例**
```json
{
"page": 1,
"pageSize": 30,
"platformCode": "shopee",
"storeNickname": "",
"expirationFilter": "normal"
}
```
`expirationFilter`:`normal` / `within7days` / `expired`。
**列表响应 `items[]` 关键字段**:`id`, `platformCode`, `platformName`, `storeNickname`, `platformAccount`, `siteCountry`, `authStatus`, `authTime`, `tokenExpireTime`, `isAutoFulfill`, `createTime`。
**平台子接口**(建议内聚于 `PlatformStoreService`,路径带平台段):
| 平台 | 路径前缀 |
| --- | --- |
| Shopee | `/order/platform-store/shopee/*` |
| Lazada | `/order/platform-store/lazada/*` |
| TikTok | `/order/platform-store/tiktok/*` |
---
### 4.2 订单 — 店铺订单 `/order/platform-store-order/*`
| 接口 | 方法 | 路径 | 说明 |
| --- | --- | --- | --- |
| 订单列表 | POST | `/order/platform-store-order/list` | 分页 + 多 Tab 状态 |
| 状态统计 | POST | `/order/platform-store-order/status-count` | 各履约状态数量 |
| 待发货统计 | GET | `/order/platform-store-order/pending-ship-count` | |
| 取消单统计 | GET | `/order/platform-store-order/canceled-count` | |
| 订单详情 | GET | `/order/platform-store-order/detail` | 含 `lines[]`、拆单、草稿 |
| 准备发货 RTS | POST | `/order/platform-store-order/ready-to-ship` | 单条 |
| 批量 RTS | POST | `/order/platform-store-order/batch-ready-to-ship` | |
| 库存匹配下单 | POST | `/order/platform-store-order/match-inventory` | 按 SKU 映射扣库存并创建 `t_order` 草稿 |
| 批量库存匹配 | POST | `/order/platform-store-order/batch-match-inventory` | |
| 同步平台状态 | POST | `/order/platform-store-order/sync-status` | |
| 搁置 / 取消搁置 | POST | `/order/platform-store-order/toggle-suspend` | |
| 删除 | POST | `/order/platform-store-order/delete` | `ids[]` |
| 获取面单 | POST | `/order/platform-store-order/fetch-label` | 返回 `shippingLabelUrl` |
| 更新标签 | POST | `/order/platform-store-order/update-tags` | `id`, `customTags` |
| 快速录单 | POST | `/order/platform-store-order/add-draft` | 写入 `t_sales_store_order_draft` |
| 导出 | POST | `/order/platform-store-order/export` | 异步或同步文件流 |
**列表请求关键字段**
```json
{
"page": 1,
"pageSize": 30,
"platformCode": "shopee",
"fulfillStatus": "pending",
"platformOrderNo": "",
"shippingLabelNo": "",
"storeId": null,
"isSuspended": false,
"orderTimeStart": "2026-01-01",
"orderTimeEnd": "2026-04-01",
"searchType": "orderNo",
"searchKeyword": ""
}
```
`searchType`:`orderNo`(平台单号)/ `labelNo`(面单号)/ `whSku`(库内 SKU)。
**列表响应 `items[]` 关键字段**:`id`, `storeId`, `storeNickname`, `platformCode`, `platformOrderNo`, `orderCountry`, `totalAmount`, `currency`, `platformOrderTime`, `fulfillStatus`, `fulfillStatusLabel`, `shippingLabelNo`, `shippingLabelUrl`, `isMultiLabel`, `deliveryMethodLabel`, `customTags`, `isSuspended`, `presaleDays`, `lines[]`(含 `platformSku`, `productName`, `quantity`, `isShipExcluded`), `linkedOrderId`。
**库存匹配下单逻辑(对齐 WMS `matchSkuInventoryOrder`)**
1. 校验店铺订单归属与 `fulfillStatus` 允许发货。
2. 按 `C_sku_platform_map` 解析每行 `MappedSkuId`;未映射行失败。
3. 按库位扣减 `C_inventory.Qty`(优先默认库位或请求指定 `binLocationId`)。
4. 调用 OMS `CreateParcelCoreAsync` 创建小包订单草稿,回写 `LinkedOrderId`。
5. 更新店铺订单 `fulfillStatus`。
---
### 4.3 仓储 — 我的包裹 `/warehouse/parcel/*`
| 接口 | 方法 | 路径 | 说明 |
| --- | --- | --- | --- |
| 包裹列表 | POST | `/warehouse/parcel/list` | 按 `lifecycleStatus` Tab |
| 状态统计 | POST | `/warehouse/parcel/status-count` | 各状态数量 |
| 包裹详情 | GET | `/warehouse/parcel/detail` | 含 `items[]` |
| 新增 | POST | `/warehouse/parcel/create` | |
| 编辑 | POST | `/warehouse/parcel/update` | |
| 删除 | POST | `/warehouse/parcel/delete` | `ids[]` |
| 申请入库 | POST | `/warehouse/parcel/apply-storage` | 到仓包裹进入库存流程 |
**列表请求**:`lifecycleStatus`(`inTransit`/`arrived`/`unclaimed`/`expired`)、`warehouseId`、`trackingNo`、`parcelCategory`、`productName`(模糊搜明细)。
**创建请求**
```json
{
"warehouseId": 1,
"trackingNo": "SF1234567890",
"carrierName": "顺丰",
"parcelCategory": "single",
"remark": "",
"items": [
{
"productName": "手机壳",
"quantity": 2,
"imageUrl": "",
"attributeText": "黑色"
}
]
}
```
---
### 4.4 仓储 — 我的库存 `/warehouse/inventory/*`
| 接口 | 方法 | 路径 | 说明 |
| --- | --- | --- | --- |
| 库存汇总列表 | POST | `/warehouse/inventory/list` | 已入库 SKU 维度 |
| 在途列表 | POST | `/warehouse/inventory/in-transit-list` | 已到仓未上架(对齐 WMS `packageList3`) |
| 状态统计 | GET | `/warehouse/inventory/status-count` | 已到仓 / 已入库数量 |
| 库位明细 | GET | `/warehouse/inventory/bin-detail` | 某 SKU 多库位 |
| 上架 | POST | `/warehouse/inventory/putaway` | 包裹或 SKU 上架 |
| 换库位 | POST | `/warehouse/inventory/relocate` | |
| 调整数量 | POST | `/warehouse/inventory/adjust-qty` | 多库位批量调整 |
| 更新尺重 | POST | `/warehouse/inventory/update-dimension` | |
| 库存流水 | POST | `/warehouse/inventory/movement-list` | 分页 |
| 导出 | POST | `/warehouse/inventory/export` | |
**库存列表请求**:`whSkuCode`, `productName`, `availabilityFilter`(`available`/`replenish`/`all`)、`warehouseId`, `sortBy`(`putawayTime`/`availableQty`)。
**列表响应 `items[]`**:`whSkuId`, `whSkuCode`, `skuName`, `availableQty`, `onHandQty`, `frozenQty`, `binLocationCode`, `lengthCm`, `widthCm`, `heightCm`, `weightG`, `putawayTime`, `parcelTrackingNo`(来源包裹)。
---
### 4.5 仓储 — 我的 SKU `/warehouse/sku/*`
| 接口 | 方法 | 路径 | 说明 |
| --- | --- | --- | --- |
| SKU 列表 | POST | `/warehouse/sku/list` | 分页 |
| 类型统计 | GET | `/warehouse/sku/type-count` | 普通 / 组合数量 |
| 详情 | GET | `/warehouse/sku/detail` | 含映射、组合子项 |
| 新增 | POST | `/warehouse/sku/create` | |
| 编辑 | POST | `/warehouse/sku/update` | |
| 删除 | POST | `/warehouse/sku/delete` | |
| 批量删除 | POST | `/warehouse/sku/batch-delete` | |
| 批量导入 | POST | `/warehouse/sku/import` | Excel |
| 组合 SKU 导入 | POST | `/warehouse/sku/import-bundle` | |
| 映射详情 | GET | `/warehouse/sku/mapping-detail` | `whSkuId` |
| 批量绑定平台 SKU | POST | `/warehouse/sku/bind-platform-sku` | |
| 导入映射 | POST | `/warehouse/sku/import-mapping` | |
| 打印 SKU 标签 | POST | `/warehouse/sku/print-label` | 返回 PDF URL |
**列表请求**:`skuCode`, `skuName`, `isBundle`, `mappingStatus`(`mapped`/`unmapped`/`all`), `sortBy`。
**列表响应**:`id`, `skuCode`, `skuName`, `skuImageUrl`, `isBundle`, `weightG`, `lengthCm`, `widthCm`, `heightCm`, `referencePrice`, `currency`, `mappingCount`, `onHandQty`, `inboundPendingQty`, `binLocationCode`。
---
### 4.6 仓储 — 入库预报 `/warehouse/inbound-notice/*`
| 接口 | 方法 | 路径 | 说明 |
| --- | --- | --- | --- |
| 列表 | POST | `/warehouse/inbound-notice/list` | 分页 |
| 状态统计 | POST | `/warehouse/inbound-notice/status-count` | |
| 详情 | GET | `/warehouse/inbound-notice/detail` | 含 `boxes[].lines[]` |
| 新增 | POST | `/warehouse/inbound-notice/create` | |
| 编辑 | POST | `/warehouse/inbound-notice/update` | 仅 `receiptStatus=forecasted` 可编辑 |
| 删除 | POST | `/warehouse/inbound-notice/delete` | |
| 导入校验 | POST | `/warehouse/inbound-notice/import-validate` | 箱号导入预检 |
| 导入保存 | POST | `/warehouse/inbound-notice/import-save` | |
| 异常信息 | GET | `/warehouse/inbound-notice/exception-detail` | |
| 标记异常 | POST | `/warehouse/inbound-notice/mark-exception` | |
| 取消异常 | POST | `/warehouse/inbound-notice/clear-exception` | |
| 确认收货 | POST | `/warehouse/inbound-notice/confirm-receive` | 客户侧确认到仓 |
| SKU 清点 | POST | `/warehouse/inbound-notice/inspect` | |
| 打印标签 | POST | `/warehouse/inbound-notice/print-label` | PDF |
| 生成单号 | GET | `/warehouse/inbound-notice/next-no` | 可选预取 |
**创建请求**
```json
{
"warehouseId": 1,
"markReference": "MARK-001",
"inboundType": "normal",
"remark": "",
"boxes": [
{
"boxSeqNo": "1",
"markBoxNo": "BOX-001",
"weightG": 1200,
"lengthCm": 40,
"widthCm": 30,
"heightCm": 20,
"lines": [
{
"whSkuId": 1001,
"whSkuCode": "SKU-A001",
"plannedQty": 50
}
]
}
]
}
```
服务端生成 `noticeNo` = `IN` + SnowflakeId。
**列表响应关键字段**:`id`, `noticeNo`, `markReference`, `warehouseId`, `warehouseName`, `inboundType`, `receiptStatus`, `receiptStatusLabel`, `expectedArrivalTime`, `actualArrivalTime`, `skuSummary`, `receivedSkuSummary`, `receiveProgress`, `boxCount`, `receivedBoxCount`, `isException`, `createTime`。
---
## 5 主业务流程
### 5.1 店铺授权 → 拉单
```mermaid
sequenceDiagram
participant U as 客户
participant OMS as OMS API
participant Plat as 电商平台
U->>OMS: 获取 auth-url
OMS-->>U: OAuth URL
U->>Plat: 授权
Plat-->>OMS: auth-callback(code)
OMS->>OMS: 写入 t_sales_store + token
Note over OMS,Plat: 定时任务拉取店铺订单
OMS->>Plat: 拉单 API
OMS->>OMS: upsert t_sales_store_order
```
- 平台订单 **定时同步** + 手动「同步状态」;Token 过期前刷新(各平台 Adapter)。
- Manual 店铺:无 OAuth,支持手工录入订单(二期)。
### 5.2 店铺订单 → 小包发货
1. 用户在「店铺订单」筛选 `fulfillStatus=pending`。
2. 操作「库存匹配」:映射 → 扣库存 → 创建 `t_order`。
3. 或操作「准备发货」:调平台 RTS API → 更新 `fulfillStatus`。
4. 获取平台面单 → 可关联 OMS 出库流程。
### 5.3 入库预报 → 库存
1. 客户维护 `C_sku` → 创建入库预报(`C_inbound_notice` + **箱号** `C_inbound_box` + 箱内行 `C_inbound_box_line`)→ `ReceiptStatus=forecasted`。
2. 仓库 `confirm-receive`:按箱清点,每行指定 `BinLocationId` → 累加 `C_inventory.Qty` → `completed`。
3. **不做**清点/上架多态、收货日志表。
### 5.4 我的包裹 → 库存
1. 客户登记快递单号 → `inTransit`。
2. 到仓 → `arrived`;`putaway` 指定 `SkuId` + `BinLocationId` → 累加 `C_inventory` → `stored`。
---
## 6 客户数据隔离
与 OMS §4.4.0 对齐,扩展至仓储模块:
| 规则 | 说明 |
| --- | --- |
| 隔离键 | `effectiveCustomerId` = `t_customer.Id` |
| 列表 | 强制 `CustomerId = effectiveCustomerId` |
| 单条读写 | 先查主表 `CustomerId`,不匹配返回「数据不存在」 |
| 子客户 | 与订单模块策略统一(推荐归并主客户 Id) |
| 关联表 | 通过主表 `OrderId` / `ParcelId` / `InboundNoticeId` 间接隔离 |
| 管理员 | `loginType=0` 可传 `customerId` 查指定客户(与现网订单一致) |
---
## 7 WMS 对照表(实现参考,非字段拷贝)
| WMS 概念 | WMS 表/字段 | OMS 设计 |
| --- | --- | --- |
| 店铺 | `vip_shop` | `t_sales_store` + `t_sales_store_token` |
| 店铺订单 | `vip_shop_ord` | `t_sales_store_order` |
| 订单明细 | `vip_shop_ord_pro` | `t_sales_store_order_line` |
| 包裹 | `vip_package` | `C_parcel` |
| 包裹明细 | `vip_package_pro` | `C_parcel_item` |
| 库存余额 | `vip_package_inventory` | `C_inventory`(按库位) |
| 库位 | `storage_id` / `storageText` | `C_bin_location` |
| 库存流水 | `wms_stock_record` | `C_stock_movement` |
| 商品 SKU | `wms_goods_sku` | `C_sku` |
| 组合 SKU | `wms_goods_sku_combine` | `C_sku_bundle_item` |
| 平台映射 | `wms_shop_mapping_products_contact` | `C_sku_platform_map` |
| 入库单 | `wms_warehousing_order` | `C_inbound_notice` |
| 入库箱 | `wms_warehousing_box` | `C_inbound_box` |
| 箱内 SKU | `wms_warehousing_box_goods` | `C_inbound_box_line` |
| 收货日志 | `wms_warehousing_order_inbound_log` | `C_inbound_receipt_log` |
| 会员 | `vipId` | `CustomerId` |
| 仓库 | `whseId` | `WarehouseId` → `t_warehouse_address` |
| WMS 接口前缀 | OMS 接口前缀 |
| --- | --- |
| `/vip/shop/*` | `/order/platform-store/*` |
| `/vip/ord/*` | `/order/platform-store-order/*` |
| `/vip/package/*` | `/warehouse/parcel/*`、`/warehouse/inventory/*` |
| `/wms/warehousing/sku/*` | `/warehouse/sku/*` |
| `/wms/warehousing/order/*` | `/warehouse/inbound/*` |
---
## 8 枚举与常量
### 8.1 店铺订单履约状态 `FulfillStatus`
| 值 | 说明 | WMS 对应 |
| --- | --- | --- |
| `all` | 全部(筛选用) | `0` |
| `pending` | 待处理 | `pending` |
| `toShip` | 待发货 | `toBeShipped` |
| `canceled` | 已取消 | `cancel` |
| `suspended` | 已搁置 | `suspended` |
| `shipped` | 已发货 | `shipped` |
| `completed` | 已完成 | `completed` |
### 8.2 包裹生命周期 `LifecycleStatus`
**轻量版(3 态)**:`inTransit` / `arrived` / `stored`
| 值 | 说明 | WMS `pkgStatus` |
| --- | --- | --- |
| `inTransit` | 待到仓 | `1` |
| `arrived` | 已到仓 | `2` |
| `stored` | 已入库 | — |
| ~~`unclaimed`~~ | 待认领 **〔延后〕** | `3` |
| ~~`expired`~~ | 已到期 **〔延后〕** | `4` |
### 8.3 库存变动类型 `MovementType` **〔延后,轻量版不建流水表〕**
| 值 | 说明 |
| --- | --- |
| `inbound` | 入库上架 |
| `allocate` | 订单分配冻结 |
| `release` | 释放冻结 |
| `outbound` | 出库扣减 |
| `adjust` | 人工调整 |
| `relocate` | 换库位 |
### 8.4 入库预报状态 `ReceiptStatus`
**轻量版(3 态)**:`forecasted` → `received` → `completed`
| 值 | 说明 | WMS `adopt` |
| --- | --- | --- |
| `forecasted` | 已预报 | `N` |
| `received` | 已到仓待确认 | `B`/`C` 合并 |
| `completed` | 已入库 | `Y` |
| ~~`inspecting`~~ / ~~`putaway`~~ / ~~`exception`~~ | **〔延后〕** | |
### 8.5 平台编码 `PlatformCode`
| 值 | 平台 |
| --- | --- |
| `lazada` | Lazada |
| `shopee` | Shopee |
| `tiktok` | TikTok Shop |
| `temu` | Temu |
| `manual` | 手工店铺 |
---
## 9 实施分期建议 **〔轻量版见 §0.5〕**
| 阶段 | 范围 | 交付物 |
| --- | --- | --- |
| **M1** | SKU + 入库预报 + 库存余额 | 3 表 + `WarehouseService` 10 个接口 + 2 页 |
| **M2** | 包裹 + 库存只读页 | +2 表 + 6 接口 + 2 页 |
| **M3** | 店铺授权 + 店铺订单 | +3 表 + 2 Service + 2 页 |
| **M4** | 库存匹配 → `t_order` | 打通订单 | **已完成** |
**完整版分期(v0.1,仅供参考)**
| 阶段 | 范围 |
| --- | --- |
| P0~P4 | 见原表 |
---
## 10 附录:迁移脚本
**一步建表(推荐)**
```
sql/migrate_warehouse_module.sql -- 仓储 C_* 9 张 + 店铺 t_sales_* 3 张
```
执行后需在 `Oms.Domain` 中已有对应实体(Step 1 已落地)。
---
## 11 待决事项(评审时确认)
1. **子客户订单归属**:与订单模块统一。
2. **库位维护入口**:`C_bin_location` 放仓储菜单还是系统仓库管理 — 建议 **仓库地址详情页** 或仓储下子页。
3. **默认库位**:每仓库是否预置一个 `DEFAULT` 库位,简化客户上架。
4. **包裹是否 M1 必做**:主路径若为入库预报,包裹可 M2。
5. **平台首期范围**:Shopee / Lazada / TikTok 择几先做。
---
*文档结束。实现时以 `docs/oms系统设计-050801.md` §3 公共规范与 `docs/rbac系统设计-060801.md` 权限模型为准;若与本文冲突,以评审结论更新本文档版本号。*