文档目录
订单物流相关表

简介

本设计文档聚焦 DouPHP 电商系统的“订单物流”能力,围绕订单发货、物流公司选择、运单号管理、收货地址快照、退货寄回物流等核心场景,梳理并说明相关数据库表结构、业务处理流程、异常处理与扩展点。面向电商平台开发者提供可落地的集成参考实现,帮助快速完成多家物流公司的接入、轨迹追踪、配送范围限制、运费计算、签收确认与统计分析等复杂场景的数据建模与流程编排。

项目结构与范围

  • 订单主表与物流字段:订单主表包含物流公司标识、运单号、发货时间等关键字段,用于承载正向发货的物流信息。
  • 收货地址快照:订单下单时冻结收货地址,避免后续地址变更影响历史订单。
  • 退货物流:售后退货场景下,记录买家寄回物流的公司与运单号、寄出时间。
  • 物流公司来源:物流公司来自已启用的配送插件列表,支持多物流公司集成。
  • 发货流程:后台录入物流公司与运单号,首次填写时推进订单状态并解锁库存;后续更新仅刷新物流信息。
graph TB
A["订单主表<br/>dou_order"] --> B["物流公司/配送方式<br/>plugin 表 slug"]
A --> C["收货地址快照<br/>dou_order_address"]
D["售后退货表<br/>dou_aftersale_return"] --> E["售后状态机<br/>返回已发货"]
F["后台订单服务<br/>OrderService::tracking"] --> A
F --> G["核心订单服务<br/>changeStatus / getShippingList"]

核心数据模型与表设计

  • 订单主表(dou_order)
    • 关键字段:shipping_id(物流公司/配送方式 slug)、tracking_no(运单号)、shipped_at(发货时间)、status(订单状态)、allow_aftersale(是否允许售后)、item_amount/shipping_fee/order_amount(金额)。
    • 作用:承载正向发货的物流信息与订单生命周期状态。
  • 收货地址快照(dou_order_address)
    • 关键字段:order_id、contact_name、phone、country、province、address、postcode。
    • 作用:下单瞬间冻结收货信息,与会员地址本解耦,确保历史订单地址一致性。
  • 售后退货表(dou_aftersale_return)
    • 关键字段:aftersale_id、shipping_company、tracking_no、shipped_at(DATETIME)。
    • 作用:记录买家退货寄出的物流公司、运单号与寄出时间,并与售后状态机联动。
  • 物流公司来源(plugin 表)
    • 通过 plugin.slug 表示启用的配送方式,后台下拉列表由核心订单服务获取。
erDiagram
DOU_ORDER {
int id PK
string order_sn UK
int user_id
string shipping_id
string tracking_no
datetime shipped_at
decimal item_amount
decimal shipping_fee
decimal order_amount
string status
string allow_aftersale
datetime created_at
}
DOU_ORDER_ADDRESS {
int id PK
int order_id FK
string contact_name
string phone
string country
string province
string address
string postcode
datetime created_at
}
DOU_AFTERSALE_RETURN {
int aftersale_id PK
string shipping_company
string tracking_no
datetime shipped_at
}
DOU_ORDER ||--o{ DOU_ORDER_ADDRESS : "一对一快照"
DOU_ORDER ||--|| DOU_AFTERSALE_RETURN : "售后退货关联"

架构总览

  • 入口层:后台订单控制器接收物流提交请求,调用表单校验与服务层。
  • 服务层:
    • 后台订单服务负责物流保存、首次发货状态推进、库存解锁。
    • 核心订单服务提供状态机、物流公司列表、支付/配送选项等能力。
  • 数据层:订单主表、收货地址快照、售后退货表与插件表协作。
  • 售后链路:用户提交退货物流后写入退货表并推进售后状态。
sequenceDiagram
participant Admin as "后台管理员"
participant Ctrl as "订单控制器"
participant Req as "表单校验"
participant Svc as "后台订单服务"
participant Core as "核心订单服务"
participant DB as "数据库"
Admin->>Ctrl : 提交物流order_id, shipping_id, tracking_no
Ctrl->>Req : 参数校验
Req-->>Ctrl : 校验通过
Ctrl->>Svc : tracking(data)
alt 首次填写运单号
Svc->>Core : changeStatus(COMPLETED)
Core-->>Svc : 成功
Svc->>DB : 更新 order(shipping_id, tracking_no, shipped_at, allow_aftersale)
Svc->>DB : 更新 order_item(stock_lock=0)
else 非首次更新
Svc->>DB : 更新 order(shipping_id, tracking_no, shipped_at)
end
Ctrl-->>Admin : 跳转订单详情

关键业务流程详解

物流配送流程管理(发货)

  • 触发点:后台订单详情页“保存物流”。
  • 规则:
    • 首次填写运单号:将订单状态推进为已完成,设置 allow_aftersale=1,并解锁库存。
    • 非首次更新:仅刷新物流公司、运单号与发货时间。
  • 结果:订单主表 shipping_id/tracking_no/shipped_at 更新;order_item.stock_lock 在首次发货时清零。
flowchart TD
Start(["开始"]) --> Check{"是否已有运单号?"}
Check -- 否 --> FirstShip["推进订单状态为已完成<br/>设置 allow_aftersale=1<br/>解锁库存"]
FirstShip --> UpdateOrder["更新 order.shipping_id/tracking_no/shipped_at"]
Check -- 是 --> UpdateOnly["仅更新 order.shipping_id/tracking_no/shipped_at"]
UpdateOrder --> End(["结束"])
UpdateOnly --> End

物流信息查询

  • 物流公司下拉:由核心订单服务获取启用配送插件列表,后台详情页渲染。
  • 订单详情展示:从订单主表读取 shipping_id/tracking_no/shipped_at,并从插件表解析物流公司名称。
  • 收货地址:统一从收货地址快照表读取联系人、电话、省市区、详细地址、邮编。
graph LR
UI["后台订单详情页"] --> List["getShippingList()"]
UI --> ReadOrder["读取 order.shipping_id/tracking_no/shipped_at"]
UI --> ReadAddr["读取 order_address 快照"]
List --> Plugin["plugin 表 slug→name"]

签收确认

  • 当前实现以“首次填写运单号即视为发货完成”,订单状态推进为已完成,并开启售后窗口。
  • 若需引入第三方物流轨迹回调或签收事件,可在现有 order.tracking_no 基础上扩展:
    • 新增轨迹表记录节点时间与状态;
    • 通过外部回调更新轨迹与订单签收状态;
    • 结合售后状态机进行签收后的业务联动(如自动评价、结算分佣等)。

退货物流

  • 用户提交退货物流:写入 dou_aftersale_return(shipping_company、tracking_no、shipped_at),并推进售后状态至“返回已发货”。
  • 后台展示:售后详情页显示退货公司、运单号与寄出时间。
sequenceDiagram
participant User as "用户"
participant ASvc as "售后服务中心"
participant DB as "数据库"
participant Status as "售后状态机"
User->>ASvc : 提交退货物流公司、运单号
ASvc->>DB : 写入/更新 aftersale_return
ASvc->>Status : changeStatus(RETURN_SHIPPED)
Status-->>ASvc : 成功
ASvc-->>User : 提示成功

多家物流公司集成支持

  • 物流公司来源:通过核心订单服务的 getShippingList 获取已启用配送插件列表,后台详情页下拉框渲染。
  • 扩展方式:新增配送插件并在系统中启用,即可出现在物流公司选择中;订单主表使用 slug 标识物流公司。

物流轨迹追踪

  • 当前实现:订单主表仅记录运单号;未内置轨迹拉取与存储逻辑。
  • 建议方案:
    • 新增轨迹表(order_id、company_slug、tracking_no、event_time、event_desc、source 等);
    • 定时任务或回调接口拉取轨迹并去重入库;
    • 前端按时间轴展示轨迹节点。

配送范围限制与运费计算

  • 范围限制:建议在配送插件内实现(基于地区、重量、体积等规则),订单主表仅记录最终选择的 shipping_id。
  • 运费计算:订单主表记录 shipping_fee,可由结算流程根据插件策略计算并持久化。

依赖关系分析

  • 控制器依赖表单校验与服务层:
    • 控制器接收物流提交,委托 OrderTrackingFormRequest 校验,再调用 OrderService::tracking。
  • 服务层依赖核心订单服务:
    • 首次发货调用 changeStatus 推进状态;
    • 物流公司列表通过 getShippingList 获取。
  • 数据层依赖订单主表、收货地址快照、售后退货表与插件表。
graph TB
Ctrl["订单控制器"] --> Req["表单校验"]
Ctrl --> Svc["后台订单服务"]
Svc --> Core["核心订单服务"]
Svc --> DB["订单/地址/退货/插件表"]

性能与扩展性建议

  • 索引优化:
    • 对 order.order_sn、order.status、order.shipping_id、order.tracking_no 建立合适索引以提升查询效率。
    • 对 order_address.order_id 建立索引以加速地址快照查询。
    • 对 aftersale_return.aftersale_id 建立唯一索引以避免重复写入。
  • 批量操作:
    • 批量取消订单时使用事务保证一致性,减少锁竞争。
  • 扩展点:
    • 在配送插件中实现范围限制与运费计算,保持订单主表简洁。
    • 新增轨迹表与回调接口,解耦第三方物流 API 调用。

故障排查指南

  • 物流提交失败:
    • 检查表单校验是否通过(order_id、shipping_id、tracking_no)。
    • 检查订单是否存在且状态允许更新。
  • 状态推进异常:
    • 首次发货会推进到已完成并解锁库存,若失败请查看日志与事务回滚情况。
  • 退货物流写入异常:
    • 检查 aftersale_return 表结构与 shipped_at 字段类型(DATETIME)。
    • 确认售后状态机是否允许 RETURN_SHIPPED 转换。

结论

DouPHP 的订单物流体系以订单主表为核心,结合收货地址快照与售后退货表,形成了完整的正向发货与退货物流闭环。通过核心订单服务提供的状态机与配送插件列表,系统具备良好的扩展性,便于接入多家物流公司、实现轨迹追踪、范围限制与运费计算等复杂场景。建议在现有基础上补充轨迹表与回调机制,进一步提升物流可视性与自动化水平。

附录:字段与状态参考

  • 订单主表关键字段
    • shipping_id:物流公司/配送方式 slug
    • tracking_no:运单号
    • shipped_at:发货时间
    • status:订单状态
    • allow_aftersale:是否允许售后
  • 收货地址快照关键字段
    • contact_name、phone、country、province、address、postcode
  • 售后退货表关键字段
    • shipping_company、tracking_no、shipped_at(DATETIME)
  • 物流公司来源
    • 通过核心订单服务的 getShippingList 获取启用插件列表
添加日期:2026-10-05