文档目录
订单服务实现

简介

本文件面向 DouPHP 框架的订单服务,系统性梳理从购物车、结算下单、支付处理、物流配送到售后处理的完整业务流程;重点说明订单生命周期管理、数据一致性保障、并发安全策略,以及与支付、物流、库存等外部系统的集成方式。文档以代码级为依据,提供流程图与时序图帮助理解复杂业务场景和异常分支。

项目结构

订单相关能力按“前台交易”“后台运营”“核心编排”分层组织:

  • 前台交易层:购物车、结算、收银台,负责用户侧下单与支付交互。
  • 后台运营层:订单列表、详情、发货、线下付款审核、批量操作、报表。
  • 核心编排层:订单核心门面与状态机,统一对外签名并组合子服务。
graph TB
subgraph "前台"
A["购物车 CartService"]
B["结算 CheckoutService"]
C["收银台 CashierService"]
end
subgraph "核心"
D["订单核心 OrderService"]
E["状态机 OrderStatusTransition"]
end
subgraph "后台"
F["后台订单 OrderService(Admin)"]
G["订单模型 Order(Model)"]
end
A --> D
B --> D
C --> D
D --> E
F --> D
F --> G

核心组件

  • 订单核心门面 OrderService:聚合购物车、状态机、订单明细、库存守卫、定时任务、结算选项,对外提供稳定接口。
  • 状态机 OrderStatusTransition:负责订单状态变更、支付方式写入、订单号生成、付款后联动(积分/分销/等级升级)、事件派发。
  • 前台结算 CheckoutService:结算页数据组装、运费重算、优惠券试算与核销、下单事务(含价格防篡改、库存校验、地址快照)。
  • 前台收银台 CashierService:收银台/支付页数据、余额+网关混合支付预览与执行、线下凭证保存、货到付款提交。
  • 购物车 CartService:加购、改数量、删条目,跨模块/积分兑换时清空购物车,规格属性校验与实时库存检查。
  • 后台订单 OrderService(Admin):列表筛选、详情组装、发货、线下付款审核、批量删除/取消、自动化任务触发、退款入口。
  • 订单模型 Order(Model):查询构造器、统计口径(成交额/订单数/新客复购/Top商品/分类组成/支付方式聚合等)。

架构总览

订单服务采用“薄编排 + 强内聚”的分层设计:

  • 前台控制器仅做参数收集与响应格式化,核心逻辑下沉至 Service。
  • 核心服务通过组合多个子服务完成领域职责,避免单体臃肿。
  • 状态机集中管控状态迁移与副作用,保证一致性与可观测性。
  • 后台服务聚焦运营管理,复用核心服务的能力。
classDiagram
class OrderService {
+getCart()
+clearCart()
+changeStatus()
+createOrderSn()
+checkStock()
+autoCancelOrder()
+getPaymentList()
+getShippingList()
+payTimeLimit()
}
class OrderStatusTransition {
+changeStatus()
+writePayId()
+createOrderSn()
+distributionReward()
+retryPaidEffects()
}
class CheckoutService {
+getCheckoutData()
+recalculateShipping()
+applyCoupon()
+createOrder()
}
class CashierService {
+getCashierOrder()
+getPayOrder()
+previewWalletSplit()
+payWithWalletAndGateway()
+savePayEvidence()
+submitCod()
}
class CartService {
+addToCart()
+updateCartItem()
+deleteCartItem()
}
class Admin_OrderService {
+buildOrderListData()
+buildOrderViewData()
+tracking()
+action()
+payCheck()
+payReject()
+retryPaidEffects()
}
CheckoutService --> OrderService : "调用"
CashierService --> OrderService : "调用"
CartService --> OrderService : "调用"
OrderService --> OrderStatusTransition : "委托"
Admin_OrderService --> OrderService : "委托"

详细组件分析

购物车与下单流程

  • 加入购物车:支持跨模块/积分兑换清空购物车;非商品或一键购买模式直接清空;规格属性校验;库存检查。
  • 更新/删除购物车:仅在普通商品且未开启快速购买时允许修改;动态计算小计与总价。
  • 结算页:加载默认收货信息、运费规则、可用优惠券;支持运费重算与优惠券试算。
  • 创建订单(事务):
    • 库存校验:逐项检查可售库存。
    • 价格防篡改:基于定价服务重新计算最终价,与前端传入金额比对,差异拒绝下单。
    • 优惠券核销:单券模式,资格判定通过后写 coupon_log 与 order_coupon。
    • 运费计算:根据配送插件配置与条件减免。
    • 写入订单与明细:包含分销奖励比例、是否关联模块等。
    • 地址快照:将收货信息冻结到 order_address。
    • 零元订单直走 PAID:积分兑换或金额被优惠券打到 0 时跳过待付款。
    • 清理购物车。
sequenceDiagram
participant U as "用户"
participant CS as "CheckoutService"
participant OS as "OrderService"
participant DB as "数据库"
participant PS as "PricingService"
participant PL as "配送插件"
participant CP as "优惠券资格"
U->>CS : 提交结算表单
CS->>OS : getCart()
CS->>PS : 重新计算售价
CS->>CP : 校验优惠券资格
CS->>PL : 读取运费配置
CS->>DB : 开始事务
CS->>DB : 扣积分(若积分兑换)
CS->>DB : 写入order/order_item/order_address/order_coupon
CS->>DB : 提交事务
CS->>OS : changeStatus(PAID) if 零元订单
CS-->>U : 返回订单号与金额

支付处理与状态推进

  • 收银台数据:获取待付款订单、支付剩余时间。
  • 余额+网关混合支付:先计算余额抵扣,再决定是否需要网关;余额扣减失败则回退。
  • 线下凭证:上传凭证后标记 pay_id=offlinepay,订单进入等待确认状态。
  • 货到付款:立即标记支付成功,后续由状态机决定是否自动完成。
  • 状态机:PAID 时若无物流插件或非商品模块,直接推进到 COMPLETED;否则保持 PAID 等待发货。
sequenceDiagram
participant U as "用户"
participant CAS as "CashierService"
participant OS as "OrderService"
participant OST as "OrderStatusTransition"
participant PAY as "PaymentService"
U->>CAS : 选择支付方式
CAS->>PAY : markSucceededByWallet / markSucceeded
PAY-->>CAS : 成功/失败
alt 余额不足或失败
CAS-->>U : 提示失败
else 成功
CAS->>OST : changeStatus(PAID)
OST-->>CAS : 可能自动COMPLETED
CAS-->>U : 跳转订单页
end

物流配送与发货

  • 后台填写物流公司/运单号:首次填写时推进订单为已发货并解锁库存;重复填写仅更新物流信息。
  • 发货字段:shipping_id、tracking_no、shipped_at、allow_aftersale、stock_lock 解锁。
flowchart TD
Start(["后台填写物流"]) --> CheckFirst{"是否首次填写?"}
CheckFirst -- 否 --> UpdateOnly["更新 shipping_id/tracking_no/shipped_at"]
CheckFirst -- 是 --> ChangeStatus["changeStatus(COMPLETED)"]
ChangeStatus --> UpdateFields["写入 shipped_at/allow_aftersale"]
UpdateFields --> Unlock["解锁库存 stock_lock=0"]
UpdateOnly --> End(["完成"])
Unlock --> End

售后服务与退款

  • 后台退款入口:委托核心服务的 adminRefund(具体退款由各支付插件实现)。
  • 自动售后标记:超过时限自动关闭可申请售后标记。
  • 订单详情展示:结合支付历史与优惠券明细,便于售后判断。

后台订单管理与报表

  • 列表筛选:支持用户名、状态、订单号、收件人、时间范围;收件人多维模糊匹配 order_address。
  • 详情组装:支付历史、支付方式展示名、物流公司名、优惠券明细、是否允许重试支付。
  • 批量操作:批量删除订单及关联行;批量取消未付款订单(事务内原子更新订单、明细、关联模块状态)。
  • 自动化任务:自动取消超时未付款、自动评价、自动售后标记。
  • 销售统计:实付订单额、订单数、新客复购、Top商品、分类组成、支付方式聚合等。

依赖关系分析

  • 前台控制器与路由:小程序订单控制器承载购物车入口,其他动作拆分到独立控制器。
  • 核心服务依赖:
    • 订单核心门面依赖状态机、购物车查询、订单明细、库存守卫、定时任务、结算选项。
    • 状态机依赖钱包服务、事件系统、模块扩展(分销/会员等级)。
  • 后台服务依赖:
    • 后台订单服务依赖核心订单服务、支付台账服务、支付方式名称解析。
    • 后台模型提供查询构造器与统计口径。
graph LR
API["API OrderController"] --> CORE["OrderService(核心)"]
FRONT["Front Services"] --> CORE
CORE --> STATE["OrderStatusTransition"]
CORE --> CART["OrderCartQuery"]
CORE --> ITEM["OrderItemQuery"]
CORE --> STOCK["OrderStockGuard"]
CORE --> TASK["OrderScheduledTasks"]
CORE --> OPT["OrderCheckoutOptions"]
ADMIN["Admin OrderService"] --> CORE
ADMIN --> PAY["PaymentService"]

性能与并发特性

  • 事务边界:下单、批量取消等操作使用数据库事务,确保多表写入原子性;异常时回滚。
  • 并发保护:
    • 付款后联动在事务外派发,避免下游失败回滚状态。
    • 积分与分销在同一事务内对订单行加锁(FOR UPDATE),防止回调与后台重跑并发导致重复发放。
    • 订单号生成具备冲突重试与高熵兜底,避免无界重试。
  • 查询优化:列表分页、预加载用户、收件人分组条件、统计 SQL 使用 GROUP BY/聚合函数减少应用层计算。
  • 幂等设计:重试付款联动、优惠券核销、分销奖励均具备去重机制,支持安全重放。

故障排查指南

  • 下单失败:
    • 检查库存校验结果与价格防篡改差异;查看日志中错误通道与异常堆栈。
    • 关注事务是否回滚,以及优惠券资格判定是否通过。
  • 支付异常:
    • 线下凭证未生效:确认 payment_sn 与附件路径是否正确写入;订单状态是否推进到等待确认。
    • 货到付款:确认 markSucceeded 成功后才写入 pay_id/paid_at。
  • 后台操作异常:
    • 线下付款审核:确认是否存在 pending 支付记录;markSucceeded/markFailed 返回值与订单状态变化。
    • 批量取消:检查事务是否提交成功,关联模块状态是否同步更新。
  • 自动化任务:
    • 超时未付款取消、自动评价、售后标记是否在列表入口被触发。

结论

DouPHP 订单服务通过清晰的分层与职责划分,实现了从购物车到售后全链路的闭环管理。核心优势包括:

  • 强一致:下单与批量操作使用事务,状态机集中管控状态迁移。
  • 高可靠:付款后联动在事务外派发,失败不回滚状态;并发场景下通过行锁与幂等设计避免重复发放。
  • 易扩展:核心门面聚合子服务,新增支付/物流/营销能力可通过插件与模块扩展接入。
  • 可观测:完善的日志与统计口径,便于问题定位与经营分析。

附录:关键流程时序图

下单创建订单(含价格防篡改与优惠券核销)

sequenceDiagram
participant FE as "前端"
participant CS as "CheckoutService"
participant OS as "OrderService"
participant DB as "数据库"
participant PR as "PricingService"
participant CO as "优惠券资格"
FE->>CS : 提交结算
CS->>OS : getCart()
CS->>PR : 重新计算售价
CS->>CO : canUse() 校验
CS->>DB : beginTransaction()
CS->>DB : 写入 order/order_item/order_address/order_coupon
CS->>DB : commit()
CS->>OS : changeStatus(PAID) if 零元订单
CS-->>FE : 返回订单号

后台发货与状态推进

sequenceDiagram
participant ADM as "后台管理员"
participant AS as "Admin OrderService"
participant OS as "OrderService"
participant DB as "数据库"
ADM->>AS : 填写物流信息
AS->>OS : changeStatus(COMPLETED) if 首次填写
AS->>DB : 更新 shipping_id/tracking_no/shipped_at
AS->>DB : 解锁库存 stock_lock=0
AS-->>ADM : 返回详情页URL

线下付款审核(通过/驳回)

sequenceDiagram
participant ADM as "后台管理员"
participant AS as "Admin OrderService"
participant PAY as "PaymentService"
participant OS as "OrderService"
ADM->>AS : 点击通过/驳回
alt 通过
AS->>PAY : markSucceeded(payment_sn)
PAY-->>AS : 成功
AS-->>ADM : 跳转详情页
else 驳回
AS->>OS : changeStatus(PENDING)
AS->>PAY : markFailed(payment_sn, reason)
AS-->>ADM : 跳转详情页
end
添加日期:2026-10-05