Files
docs/一期/一期头程订单闭环设计.md
T

377 lines
30 KiB
Markdown
Raw Normal View History

2026-07-31 10:43:30 +08:00
# 一期头程订单闭环设计
> 状态:产品决策已确认,前端静态闭环实施中
> 创建日期:2026-07-28
2026-08-04 15:41:54 +08:00
> 适用范围:`apps/client-web`、`apps/admin-web`、`baiyue-firstleg`
2026-07-31 10:43:30 +08:00
## 一、目标
一期形成可验收的最小订单闭环:
1. 企业注册成功后可直接登录,不经过注册审核。
2. 企业提交资料,由平台人员人工点击审核通过;只有审核通过的企业才可提交头程订单。
3. 企业客户创建头程订单并保存草稿,提交后平台后台收到待审核任务。
4. 平台人员审核订单;信息有误时由后台人工修改,或联系客户修改,不设置驳回操作。
5. 平台人员受理、订舱并更新运输状态,企业客户查看订单详情和处理进度。
6. 企业客户在允许的状态下取消订单。
本设计先统一业务契约,不预先绑定尚未确认的 Java 框架、数据库、中间件或微服务拆分方式。
## 原型依据与迁移原则
一期原型统一以 `docs/悦/` 为依据。快递公司、往来单位的直接参考页面位于 `docs/悦/货代SAAS平台后台/货代SaaS平台原型.html` 的“通用”菜单:
| 原型页面 | 已有内容 | 一期迁移说明 |
|---|---|---|
| 快递公司 | 公司名称、编码、官网、客服电话、合作状态;名称/编码和状态筛选;新增、导入、导出、编辑入口 | 保留核心字段与列表方向;状态统一映射为 `ACTIVE` / `INACTIVE`;一期实现标准模板导入,不实现导出 |
| 往来单位 | 单位名称、类型、联系人、电话、启停状态;名称、类型和状态筛选;新增、导入、导出、编辑、详情入口 | 补充稳定编码、邮箱和完整地址;类型与一期订单的发货方/收货方角色统一;一期实现标准模板导入,不实现导出 |
现有 HTML 原型已完成菜单、静态列表、演示数据和表格渲染,但多数按钮没有完整的数据提交、校验、失败反馈和持久化流程。因此迁移到 `apps/admin-web`、`apps/client-web` 时,必须按当前项目的 Vue、Pinia、RBAC、响应式和测试约定重新实现,不能把原型存在等同于当前工程已经完成。
原型负责提供信息架构、字段和视觉参考;一期范围、数据隔离、权限和历史快照规则以本设计及开发进度表为准。原型中的 FBA、海外仓、库位、货架、托盘、船期价格和完整 WMS 菜单不因复用同一页面而进入一期。
## 二、一期边界
### 纳入一期
- 客户端:订单列表、组合筛选、创建、编辑草稿、提交、详情、取消。
- 管理后台:企业资料审核通过、订单列表、详情、待审核订单人工修改、受理、负责人分配和状态更新。
- 服务端:真实租户隔离、权限校验、状态机、幂等提交、并发控制和操作时间线。
- 公共契约:订单状态、运输方式、优先级、列表摘要和详情模型。
- 平台收货仓:后台维护国内收货仓档案和启停状态;客户端新建订单只选择已启用仓库。
- 快递公司:后台人员统一维护快递公司档案和启停状态;企业客户端不维护,订单详情只读展示履约快递信息。
- 往来单位:后台人员维护发货单位、收货单位、供应商和服务商;企业客户端只读选择当前可用的发货方和收货方。
- 货物信息:一期至少支持一条货物明细,并允许同一订单包含多条明细。
### 暂不纳入一期
- 在线询价、自动报价和费率计算。
- 应收应付、对账、结算和利润核算。
- 报关、清关、保险和完整单证中心。
- 船期自动同步、承运商接口和实时物流轨迹。
- Excel 批量下单、快速下单和复制订单。
- 客户端批量取消或批量修改。
- FBA/海外目的仓、库存、库位、货架及入出库等 WMS 作业。
- 将旧架构文档中的 11 个微服务直接作为一期落地方案。
原型中的 FBA 批量下单、渠道、商检、退税和复杂货物属性作为后续扩展依据,不进入一期最小闭环的必填字段。
## 三、参与者与数据边界
| 参与者 | 数据范围 | 主要操作 |
|---|---|---|
| 企业成员 | 当前租户订单 | 查看列表与详情 |
| 企业订单操作员 | 当前租户订单 | 创建、编辑草稿、提交、取消 |
| 企业管理员 | 当前租户订单 | 拥有企业端全部订单权限 |
| 平台运营 | 获授权数据范围内订单 | 审核、人工修改、受理、分配负责人 |
| 平台操作员 | 获授权数据范围内订单 | 订舱、更新运输状态与处理说明 |
| 平台超级管理员 | 全部订单 | 平台端全部订单操作 |
服务端必须从已验证身份中取得租户上下文。客户端传入的 `tenantId`、`customerId` 或查询参数不能作为授权依据。
企业客户端菜单和操作权限由企业管理员为本企业角色分配。一个成员可拥有多个角色,权限取角色权限并集;一期不引入部门或组织架构,成员直接归属企业。企业管理员不能配置平台后台菜单,也不能跨企业授权。
客户读取、更新、提交和取消订单时,服务端必须同时匹配订单 ID、当前租户 ID 和删除标记;不允许先按全局 ID 查出订单后再仅依赖前端隐藏。
平台国内收货仓由后台统一维护,企业客户只读选择。停用仓库不得用于新建或重新提交订单,但不能破坏历史订单已经保存的仓库名称;一期首批覆盖义乌、深圳、青岛、上海、宁波和厦门,不将其与 FBA/海外目的仓混为同一模型。
快递公司和往来单位均由当前平台后台人员维护。企业客户端不提供对应的新增、编辑、启停菜单和写接口:快递公司只通过订单详情展示,往来单位只用于下单时只读查询和选择。服务端必须按后台人员权限和数据范围校验写操作,并按当前企业可见范围过滤客户端往来单位查询,不能依赖前端隐藏按钮实现边界。
## 四、一期订单状态
### 已确认的统一状态
| 稳定编码 | 中文名称 | 含义 |
|---|---|---|
| `DRAFT` | 草稿 | 客户尚未提交,可继续编辑 |
| `PENDING_REVIEW` | 待审核 | 客户已提交,等待平台审核 |
| `ACCEPTED` | 已受理 | 平台审核通过并进入履约准备 |
| `BOOKED` | 已订舱 | 已完成舱位或对应运输资源确认 |
| `IN_TRANSIT` | 运输中 | 货物已进入运输过程 |
| `COMPLETED` | 已完成 | 一期订单履约结束 |
| `CANCELLED` | 已取消 | 客户或平台按规则取消 |
2026-08-04 15:41:54 +08:00
该方案与当前管理后台实现最接近。两个前端应用内 `shared/` 现有“处理中”以及旧架构文档中的“已确认、已报关、到港待提”不作为一期并存状态;产品确认后分别迁移。
2026-07-31 10:43:30 +08:00
### 允许的状态转换
```text
草稿 ──客户提交──> 待审核 ──平台受理──> 已受理 ──平台订舱──> 已订舱
│ │ │
└──客户取消──> 已取消 ├──后台人工修改/联系客户修改──> 待审核 │
└──客户取消申请/平台取消──> 已取消 └──发运──> 运输中 ──完成──> 已完成
```
- 草稿可由客户编辑、提交或取消。
- 待审核订单允许获授权的后台人员人工修改;平台无法直接确认的信息由平台联系客户修改。客户和后台修改后订单仍保持待审核,修改前后值、操作者和时间必须写入审计记录。
- 已受理后取消可能已经产生成本,一期默认仅平台可执行;客户只能联系平台处理。
- 已订舱、运输中和已完成不允许客户取消。
- 已取消和已完成为终态,不允许直接恢复。
- 所有状态变更必须校验当前状态,不能由前端提交任意目标状态。
## 五、一期数据模型
### 企业资料审核状态
企业账号状态与企业资料审核状态分离:注册成功即可创建账号和登录,不能用禁用账号或注册待审核状态代替下单资格。企业资料至少保存 `verificationStatus`(`UNSUBMITTED`、`PENDING`、`APPROVED`)、`submittedAt`、`approvedAt`、`approvedBy` 和资料版本;只有 `APPROVED` 可提交订单。资料提交、修改和审核通过均写入审计记录。
### 订单主信息
| 字段 | 必填阶段 | 说明 |
|---|---|---|
| `id` | 服务端生成 | 内部稳定 ID,不承载租户信息 |
| `orderNo` | 提交时生成 | 客户可见业务单号;租户内和平台范围均应唯一 |
| `tenantId` | 服务端注入 | 不接受客户指定 |
| `referenceNo` | 可选 | 客户内部参考号;建议租户内非强制唯一 |
| `receivingWarehouseId` | 提交必填 | 平台国内收货仓 ID;提交时必须存在且处于启用状态 |
| `receivingWarehouseName` | 服务端保存 | 下单时仓库名称冗余,兼容列表和旧消费者 |
| `receivingWarehouseSnapshot` | 服务端保存 | 下单时仓库展示快照,至少包含 ID、编码、名称、省、市和详细地址 |
2026-08-04 14:57:50 +08:00
| `shipperCounterpartyId` | 可选 | 兼容后台往来单位引用;企业客户端下单不强制选择 |
| `shipperSnapshot` | 我司提货时提交必填 | 仅取货方式为 `PICKUP` 时保存提货公司、联系人、电话和地址快照;自送快递、自送卡车不要求 |
| `consigneeCounterpartyId` | 可选 | 兼容后台往来单位引用;企业客户端下单不强制选择 |
| `consigneeSnapshot` | 私人仓时提交必填 | 仅目的仓类型为 `PRIVATE` 时保存私人收件地址快照;FBA 仓、海外仓使用所选公共仓主数据,不重复填写收件资料 |
2026-07-31 10:43:30 +08:00
| `deliveryInfo` | 平台维护 | 可选履约信息,包含快递公司 ID/快照和快递单号;企业客户端只读 |
| `transportMode` | 提交必填 | FCL、LCL、AIR、ROAD |
| `businessType` | 提交必填 | 一期支持 EXPORT、IMPORT |
| `origin` | 提交必填 | 起运地或起运港 |
| `destination` | 提交必填 | 目的地或目的港 |
| `expectedDepartureDate` | 可选 | 客户期望出发日期,不等同于平台确认 ETD |
| `etd`、`eta` | 平台维护 | 平台受理后的预计节点 |
| `priority` | 可选 | NORMAL、URGENT、EXPEDITED,默认 NORMAL |
| `customerRemark` | 可选 | 客户和平台均可见 |
| `internalRemark` | 可选 | 仅平台可见,不得返回客户接口 |
| `operatorId` | 平台维护 | 负责人内部用户 ID |
| `status` | 服务端维护 | 使用稳定英文编码 |
| `version` | 服务端维护 | 乐观锁版本,防止覆盖并发修改 |
| `createdBy`、`createdAt`、`updatedAt` | 服务端维护 | 审计信息 |
订单金额不由客户创建接口提交。一期若后台继续展示金额,应标记为平台估算字段,并在报价/结算范围确认后单独设计。
### 平台收货仓
| 字段 | 说明 |
|---|---|
| `id` | 服务端稳定 ID |
| `code` | 平台内唯一仓库编码,统一大写 |
| `name` | 客户可见仓库名称 |
| `province`、`city`、`address` | 国内收货地址 |
| `contactName`、`contactPhone` | 收货联系信息 |
| `businessHours` | 收货时间说明 |
| `status` | `ACTIVE` 或 `INACTIVE` |
| `remark`、`updatedAt` | 运营说明和更新时间 |
订单只持有仓库 ID 与不可编辑的必要展示快照,不复制联系人、电话、营业时间、运营备注等会持续维护的完整仓库档案。快照字段为 `id`、`code`、`name`、`province`、`city`、`address`;订单详情优先读取快照,不能回查当前仓库主数据覆盖历史值。真实服务端接入后,创建和提交均需重新校验仓库可用性,并在同一事务中持久化快照,不能只依赖客户端下拉选项。
### 快递公司
| 字段 | 说明 |
|---|---|
| `id` | 服务端稳定 ID |
| `code` | 平台内唯一稳定编码 |
| `name` | 快递公司名称 |
| `customerServicePhone` | 客服电话,可选 |
| `trackingUrl` | 官方查询网址,可选 |
| `status` | `ACTIVE` 或 `INACTIVE` |
| `remark`、`updatedAt` | 后台说明和更新时间 |
快递公司只能由获授权的后台人员维护。停用后不得新增到订单履约信息,但历史订单继续展示保存的快递公司名称和编码。企业客户端不直接查询快递公司主数据,只通过订单详情响应读取后台已保存的履约信息。一期不接快递轨迹订阅和自动回传;一个订单只支持一组快递公司与快递单号,多包裹和多段运输后续扩展。
### 往来单位
| 字段 | 说明 |
|---|---|
| `id` | 服务端稳定 ID |
| `code` | 所属数据范围内唯一编码 |
| `name` | 单位名称 |
| `types` | 可多选的稳定单位类型集合;一期覆盖供应商、客户、承运商、报关行、发货单位和收货单位 |
| `contactName`、`contactPhone`、`email` | 主要联系人信息 |
| `country`、`province`、`city`、`postalCode`、`address` | 主要地址信息 |
| `status` | `ACTIVE` 或 `INACTIVE` |
| `dataScopeId` | 所属业务数据范围,由服务端维护 |
| `remark`、`updatedAt` | 后台说明和更新时间 |
往来单位只能由获授权的后台人员维护,企业客户端只读查询当前可见且已启用的发货单位和收货单位。单位类型使用稳定编码,同一单位允许拥有供应商、客户、承运商、报关行、发货单位、收货单位中的多个类型。数据按所属业务主体隔离,后台人员只能在授权范围维护和查看。订单提交时服务端重新校验单位类型、启用状态和数据范围,并保存发货方、收货方快照;主数据后续改名、改地址或停用不得覆盖历史订单。订单内允许调整本单快照,但不得反向修改往来单位档案。
### 基础资料批量导入
一期确认支持后台批量导入快递公司和往来单位,企业客户端不提供导入入口。平台提供版本化的 `.xlsx` 标准模板;后台人员上传后,服务端先完成整批校验,存在任一错误时不写入业务表,并返回包含行号、字段和原因的错误报告。
导入至少校验必填字段、稳定编码、名称、单位类型、联系方式、地址、数据范围和启停值;同一文件内重复、与现有档案重复或越过操作人数据范围的记录必须拒绝,不得静默覆盖已有档案。一期批量导入只新增,不更新或覆盖已有档案;任一记录失败时整批不写入。每次导入记录操作人、原始文件名、总行数、成功/失败数量、失败原因摘要和服务端时间。文件大小和最大行数使用服务端可配置上限;快递公司和往来单位导出不纳入一期。
### 货物明细
| 字段 | 必填 | 说明 |
|---|---|---|
| `id` | 服务端生成 | 明细 ID |
| `lineNo` | 是 | 订单内序号 |
| `sku` | 否 | 客户 SKU |
| `cargoNameCn` | 是 | 中文品名 |
| `cargoNameEn` | 否 | 英文品名 |
| `pieces` | 是 | 件数,正整数 |
| `packageCount` | 否 | 箱数/包装数,非负整数 |
| `grossWeightKg` | 是 | 毛重,必须大于 0 |
| `volumeCbm` | 是 | 体积,必须大于 0 |
| `containerType` | FCL 时必填 | 20GP、40GP、40HQ 等 |
| `containerCount` | FCL 时必填 | 柜量,正整数 |
| `remark` | 否 | 客户可见备注 |
主表中的总件数、总重量、总体积应由服务端根据明细汇总,不接受客户端独立提交两套可能冲突的合计。
### 时间线
每次提交、待审核订单修改、受理、状态变化、取消和负责人变化均写入不可由客户端编辑的时间线:
- 事件类型和事件标题;
- 变更前后状态;
- 操作说明、修改摘要或取消原因;
- 操作者 ID、名称和操作者类型;
- 服务端发生时间;
- 请求关联 ID,便于审计和排错。
## 六、接口草案
统一前缀暂用 `/api/v1`。具体服务拆分不影响浏览器端契约。
### 客户端接口
| 方法 | 路径 | 权限编码 | 说明 |
|---|---|---|---|
| `GET` | `/api/v1/client/first-leg-orders` | `order:first-leg:list` | 当前租户订单分页列表 |
| `POST` | `/api/v1/client/first-leg-orders` | `order:first-leg:create` | 创建草稿 |
| `GET` | `/api/v1/client/first-leg-orders/{id}` | `order:first-leg:view` | 当前租户订单详情 |
| `PUT` | `/api/v1/client/first-leg-orders/{id}` | `order:first-leg:update` | 编辑草稿;平台联系客户后可修改本企业待审核订单,状态保持待审核并记录审计 |
| `POST` | `/api/v1/client/first-leg-orders/{id}/submit` | `order:first-leg:submit` | 幂等提交草稿;提交前强制校验企业资料审核已通过 |
| `POST` | `/api/v1/client/first-leg-orders/{id}/cancel` | `order:first-leg:cancel` | 按状态规则取消 |
| `GET` | `/api/v1/client/platform-receiving-warehouses` | 登录用户 | 查询客户端可选择的启用收货仓 |
| `GET` | `/api/v1/client/counterparties` | 登录用户 | 按当前数据范围只读查询已启用的发货单位和收货单位 |
| `GET` | `/api/v1/client/me` | 登录用户 | 查询当前成员的用户名、姓名、手机、邮箱、微信和所属公司 |
| `PUT` | `/api/v1/client/me` | 登录用户 | 更新真实姓名、手机、邮箱和微信;用户名与所属公司不可修改 |
| `POST` | `/api/v1/client/me/password` | 登录用户 | 校验当前密码后修改密码并记录安全审计 |
| `GET` | `/api/v1/client/company-profile` | `company:profile:view` | 查询当前企业基本信息、法人信息、联系信息和地址 |
| `PUT` | `/api/v1/client/company-profile` | `company:profile:write` | 按企业权限更新允许维护的公司信息 |
| `GET` | `/api/v1/client/company-qualifications` | `company:qualification:view` | 查询资质文件类型、状态、有效期和安全访问地址 |
| `POST` | `/api/v1/client/company-qualifications` | `company:qualification:write` | 上传或更新企业资质文件 |
### 管理后台接口
| 方法 | 路径 | 权限编码 | 说明 |
|---|---|---|---|
| `GET` | `/api/v1/admin/first-leg-orders` | `first-leg:list` | 按平台数据范围查询 |
| `POST` | `/api/v1/admin/first-leg-orders` | `first-leg:create` | 平台代客创建订单 |
| `GET` | `/api/v1/admin/first-leg-orders/{id}` | `first-leg:list` | 订单完整详情,含内部信息 |
| `PUT` | `/api/v1/admin/first-leg-orders/{id}` | `first-leg:update` | 按状态规则维护订单 |
| `POST` | `/api/v1/admin/first-leg-orders/{id}/accept` | `first-leg:status` | 受理并可分配负责人 |
| `POST` | `/api/v1/admin/first-leg-orders/{id}/assign` | `first-leg:assign` | 分配负责人 |
| `POST` | `/api/v1/admin/first-leg-orders/{id}/transition` | `first-leg:status` | 执行服务端允许的后续状态转换 |
| `POST` | `/api/v1/admin/first-leg-orders/{id}/cancel` | `first-leg:status` | 平台取消,原因必填 |
| `GET` | `/api/v1/admin/company-verifications` | `company:verification:list` | 查询企业资料审核状态和待审核企业 |
| `GET` | `/api/v1/admin/company-verifications/{companyId}` | `company:verification:list` | 查看企业资料与资质详情 |
| `POST` | `/api/v1/admin/company-verifications/{companyId}/approve` | `company:verification:approve` | 人工点击审核通过并开通下单资格;一期无驳回动作 |
| `GET` | `/api/v1/admin/platform-receiving-warehouses` | `warehouse:list` | 分页查询全部平台收货仓 |
| `POST` | `/api/v1/admin/platform-receiving-warehouses` | `warehouse:write` | 新增平台收货仓 |
| `PUT` | `/api/v1/admin/platform-receiving-warehouses/{id}` | `warehouse:write` | 编辑平台收货仓 |
| `POST` | `/api/v1/admin/platform-receiving-warehouses/{id}/status` | `warehouse:write` | 启用或停用收货仓 |
| `GET` | `/api/v1/admin/express-companies` | `express-company:list` | 分页查询快递公司 |
| `POST` | `/api/v1/admin/express-companies` | `express-company:write` | 新增快递公司 |
| `PUT` | `/api/v1/admin/express-companies/{id}` | `express-company:write` | 编辑快递公司 |
| `POST` | `/api/v1/admin/express-companies/{id}/status` | `express-company:write` | 启用或停用快递公司 |
| `POST` | `/api/v1/admin/express-companies/import` | `express-company:import` | 使用标准模板批量导入快递公司,整批校验后提交 |
| `GET` | `/api/v1/admin/counterparties` | `counterparty:list` | 按授权数据范围分页查询往来单位 |
| `POST` | `/api/v1/admin/counterparties` | `counterparty:write` | 在授权数据范围内新增往来单位 |
| `PUT` | `/api/v1/admin/counterparties/{id}` | `counterparty:write` | 编辑往来单位 |
| `POST` | `/api/v1/admin/counterparties/{id}/status` | `counterparty:write` | 启用或停用往来单位 |
| `POST` | `/api/v1/admin/counterparties/import` | `counterparty:import` | 在授权数据范围内使用标准模板批量导入往来单位 |
| `PUT` | `/api/v1/admin/first-leg-orders/{id}/delivery-info` | `first-leg:update` | 后台维护快递公司和快递单号 |
一期不使用通用的“传任意目标状态”接口替代状态动作。服务端根据当前状态、动作、操作者和权限决定目标状态。
### 请求一致性
- 创建和提交接口接受 `Idempotency-Key`,服务端按租户、用户、接口和键去重。
- 更新请求携带 `version`;版本不一致返回冲突,不静默覆盖。
- 提交和状态动作在同一事务内更新订单、版本和时间线。
- 分页参数统一为 `page`、`pageSize`,并设置服务端最大页容量。
- API 响应继续采用仓库已有 `ApiResponse<T>` 外层结构;错误码需在后端设计时统一补充。
## 七、页面范围
### 我的信息
按客户端原型提供“基本信息”和“修改密码”两个页签。基本信息展示用户名、真实姓名、手机号、邮箱、微信和所属公司,支持进入编辑、保存与取消;用户名和所属公司始终只读,真实姓名、手机号、邮箱和微信允许按权限编辑。修改密码要求当前密码、新密码和确认密码,覆盖强度校验、两次输入不一致、错误反馈、重复提交防护及成功后的会话处理。
### 公司信息
按客户端原型提供“企业基本信息、联系信息、资质文件”三个页签。基本信息覆盖公司名称、统一信用代码、企业类型、注册地、成立日期、注册资本、法人姓名和法人电话;联系信息覆盖联系人、手机、邮箱、微信和地址;资质文件展示文件类型、验证状态、有效期、上传时间,并支持查看、下载及获授权用户更新。企业数据只能读取当前企业,服务端根据企业角色控制可编辑字段和资质操作。注册不审核;企业资料未审核通过时可继续登录、查看和补充资料,但创建页必须显示下单资格提示,提交订单接口必须拒绝并返回可识别错误码。
### 客户工作台
订单列表包含订单号、参考号、运输方式、起运地、目的地、状态、负责人、预计时间和更新时间;支持关键词、状态、运输方式和创建日期筛选。
创建页按以下顺序组织:
1. 运输信息和平台收货仓;
2. 从后台维护的往来单位中选择发货方和收货方;
3. 货物明细;
4. 客户备注;
5. 保存草稿或提交审核;提交前校验企业资料已经平台人工审核通过。
详情页展示订单摘要、发货方/收货方快照、货物明细、服务端时间线、履约快递公司、快递单号和当前可用操作。内部备注、成本和平台内部操作信息不得进入客户响应;企业客户端不能修改快递信息或往来单位档案。
### 管理后台
新增企业资料审核、平台收货仓、快递公司和往来单位管理。企业资料审核只有“审核通过”,资料不正确时由平台联系客户修改;基础资料页面支持列表筛选、新增、编辑和启停,并由 RBAC 与数据范围控制。快递公司、往来单位页面沿用 `docs/悦` 原型的信息层级和主要字段,但使用当前后台视觉体系和交互组件重新实现;一期实现标准模板下载、文件上传、校验结果和错误报告,不提供导出入口。保留当前订单列表和详情方向,将自由状态下拉改为服务端返回的可用动作;补充待审核订单人工修改、受理、分配、订舱、发运、完成、取消和履约快递信息维护动作,不提供驳回入口。
## 八、测试与验收
- 租户 A 无法读取、更新、提交或取消租户 B 的订单。
- 草稿可以反复保存,提交请求重复发送只产生一次状态变化。
- 待审核订单仅允许当前企业获授权成员或获授权平台人员修改核心业务字段,修改后状态保持待审核且必须完整留痕;其他非草稿状态禁止修改。
- 服务端拒绝非法状态跳转和缺少权限的状态动作。
- 并发修改返回明确冲突,客户端保留用户输入并支持重新加载。
- 客户接口永不返回内部备注、成本或不必要的人员信息。
- 列表覆盖加载、空数据、失败、无权限和分页边界。
- 创建页覆盖校验错误、提交中、重复点击、失败恢复和离开未保存提示。
- 管理后台覆盖待审核订单人工修改、联系客户修改后的并发冲突、受理、负责人失效及状态变更失败,并确认无驳回入口和接口。
- 仓库编码必须唯一;停用仓库不出现在客户新建订单选项中,仓库改名、改地址或停用后,历史订单仍展示下单时的编码、名称和地址快照。
- 企业客户端无法调用快递公司或往来单位写接口,也不显示维护入口;伪造请求必须由服务端拒绝。
- 往来单位查询只返回当前企业可见且已启用的发货单位和收货单位;跨数据范围 ID 在保存草稿和提交时均被拒绝。
- 往来单位改名、改地址或停用后,历史订单继续展示下单时快照;停用单位不能用于新订单提交。
- 快递公司编码和名称满足唯一规则;停用公司不能新增到履约信息,历史订单继续展示已保存快照。
- 客户端订单详情只读展示快递公司和快递单号,接口不得接受客户修改履约快递信息。
- 我的信息只能读取当前登录成员;修改所属公司或其他成员资料的伪造请求必须拒绝,修改密码必须校验当前密码并写入安全审计。
- 注册成功后无需审核即可登录;公司信息只返回当前企业数据,未通过企业资料审核时服务端拒绝提交订单,审核通过后允许提交。普通成员无写权限时仍可按授权查看,资质文件下载使用受控地址并覆盖过期、缺失、上传失败和无权限状态。
- 快递公司和往来单位批量导入仅允许具备对应导入权限的后台人员调用;企业客户端和普通写权限不能绕过独立导入权限。
- 导入文件覆盖模板版本、空文件、超限文件、缺列、类型错误、重复编码、跨数据范围和恶意文件名;任一行失败时业务数据不发生部分写入,并可下载逐行错误报告。
## 九、实施顺序
1. 将已确认的注册、企业资料审核、订单修改和基础资料规则冻结为接口契约。
2026-08-04 15:41:54 +08:00
2. 以 Java Controller、DTO 和 OpenAPI 为跨端契约来源,在 Admin、Client 各自应用内 `shared/` 和 API 适配层维护前端映射。
3. 在 `baiyue-firstleg` 定义企业资料审核、订单、收货仓、快递公司和往来单位接口,并以服务端状态机和权限校验作为唯一业务规则来源。
2026-07-31 10:43:30 +08:00
4. 实现后台基础资料维护、快递公司/往来单位批量导入和企业客户端往来单位只读查询。
5. 实现客户工作台订单列表、创建和详情页面,静态阶段通过 API 适配层提供可替换数据源。
6. 将管理后台订单 Pinia 模拟操作迁移到同一 API 契约,并接入履约快递信息。
7. 增加跨租户、状态机、幂等、基础资料越权和前端业务流程测试。
## 十、已确认实施决策
以下决策于 2026-07-28 至 2026-07-29 确认:
1. 采用“草稿、待审核、已受理、已订舱、运输中、已完成、已取消”七个一期状态,不设置“已驳回”。
2. 待审核订单无驳回操作;信息有误时由后台人工修改,或由平台联系客户修改,订单保持待审核并完整记录修改审计。
3. 已受理后客户不能直接取消,一期由客户联系平台并由平台执行取消。
4. 保留平台代客户创建订单的能力。
5. 一期使用本设计的精简必填字段;FBA 批量下单、渠道、商检和退税后续扩展。
6. 快递公司和往来单位均由当前平台后台人员维护;企业客户端不提供维护入口和写接口,仅按权限只读使用。
7. 一期包含快递公司、往来单位标准模板批量导入,不包含对应导出功能。
8. 一期客户端包含我的信息和公司信息,范围以 `docs/悦/头程下单/柏悦客户端.html` 原型为基准并接入真实权限与接口。
9. 企业注册不需要审核,注册成功即可登录;提交订单前必须提交企业资料并由平台人工点击审核通过。
10. 一期支持一个用户拥有多个角色,权限取角色权限并集。
11. 往来单位按所属业务主体隔离并支持一个单位拥有多个稳定编码类型;一期类型覆盖供应商、客户、承运商、报关行、发货单位和收货单位。
12. 一个订单一期只支持一组快递公司和快递单号。
13. 快递公司、往来单位批量导入一期只新增,不更新或覆盖已有档案;重复或任一行错误时整批失败。
14. “我的信息”中的用户名只读,不允许修改。
15. 企业客户端菜单和操作权限由企业管理员为本企业角色分配,一期不做部门/组织架构。
16. 企业注册一期不接短信或邮箱验证码,只做基础字段、密码和账号重复校验。
17. 一期仅支持中文账号密码登录,不做多语言、微信和企业微信登录。