简介
本模块面向小程序端与后台的"售后服务"能力,覆盖退换货申请、维修申请、退款处理等完整流程。文档围绕以下目标展开:
- 售后申请页面的表单填写(申请原因、问题描述、凭证上传)
- 售后状态跟踪机制(待处理、已批准、已拒绝、已取消、等待退货、已发货、已收货、退款中、已退款、退款失败等10种状态流转)
- 售后与订单系统的关联(正确关联原始订单信息)
- 完整的开发示例(申请提交、状态查询、物流跟踪)
- 业务规则(退货期限验证、退款金额计算、物流费用承担等)
项目结构
售后服务在 API 层提供会员侧与工作人员侧接口,业务逻辑集中在前台服务层;状态与类型由核心基础类统一维护;后台管理控制器负责审核、收货、退款派发等操作。
graph TB
subgraph "API 层"
A["AftersaleController<br/>入口"]
B["UserController<br/>会员侧"]
C["WorkController<br/>工作人员侧"]
end
subgraph "业务层"
S["Front AftersaleService<br/>买家申请/工作台处理"]
end
subgraph "核心基础"
ST["AftersaleStatus<br/>10种状态定义"]
TP["AftersaleType<br/>售后类型"]
end
subgraph "后台管理"
AC["Admin AftersaleController<br/>审核/收货/退款"]
end
A --> B
A --> C
B --> S
C --> S
S --> ST
S --> TP
AC --> S
图表来源
- api/controller/aftersale/UserController.php:29-133
- api/controller/aftersale/WorkController.php:30-150
- front/service/aftersale/AftersaleService.php:32-67
- core/domain/aftersale/AftersaleStatus.php:21-128
- core/domain/aftersale/AftersaleType.php:21-73
- admin/controller/aftersale/AftersaleController.php:28-180
章节来源
- api/controller/aftersale/UserController.php:29-133
- api/controller/aftersale/WorkController.php:30-150
- front/service/aftersale/AftersaleService.php:32-67
- core/domain/aftersale/AftersaleStatus.php:21-128
- core/domain/aftersale/AftersaleType.php:21-73
- admin/controller/aftersale/AftersaleController.php:28-180
核心组件
- 会员侧 API(UserController)
- 售后列表、申请表单数据获取、售后申请提交
- 工作人员侧 API(WorkController)
- 售后列表、详情、处理(审核通过并进入退款流程)
- 前台服务(Front AftersaleService)
- 申请校验、创建售后单、明细行与金额计算、时间线、寄回物流、撤销、工作台处理
- 状态与类型(AftersaleStatus、AftersaleType)
- 更新:定义10种售后状态与状态迁移表,确保状态流转合法
- 支持:待处理、已批准、已拒绝、已取消、等待退货、已发货、已收货、退款中、已退款、退款失败
- 后台管理(Admin AftersaleController)
- 列表、详情、审核同意、驳回、确认收货、派发退款、确认网关退款完成
章节来源
- api/controller/aftersale/UserController.php:46-133
- api/controller/aftersale/WorkController.php:65-150
- front/service/aftersale/AftersaleService.php:107-675
- core/domain/aftersale/AftersaleStatus.php:21-128
- core/domain/aftersale/AftersaleType.php:21-73
- admin/controller/aftersale/AftersaleController.php:54-180
架构总览
小程序端通过 API 层调用前台服务完成售后申请与查询;工作人员侧通过同一服务进行售后处理;状态机保证状态迁移一致性与可审计性;后台管理用于人工审核与关键节点操作。
sequenceDiagram
participant App as "小程序前端"
participant APIU as "UserController"
participant APIW as "WorkController"
participant SVC as "Front AftersaleService"
participant STA as "AftersaleStatus"
participant DB as "数据库"
App->>APIU : 获取申请表单数据
APIU->>SVC : buildAftersaleApplyData(orderSn, userId)
SVC->>DB : 查询订单/商品余量
DB-->>SVC : 订单与可退商品清单
SVC-->>APIU : 返回订单/商品/草稿图片
App->>APIU : 提交售后申请(reason, type, item_list, draft_token)
APIU->>SVC : submitAftersaleApply(...)
SVC->>STA : 校验/写入初始状态 pending
SVC->>DB : 写入 aftersale / aftersale_item / order 标记
SVC-->>APIU : 成功
App->>APIW : 工作人员处理(审核通过+金额)
APIW->>SVC : handleAftersaleWorkOrder(...)
SVC->>STA : PENDING→APPROVED→REFUNDING→REFUNDED
SVC->>DB : 写退款记录/更新订单售后状态
SVC-->>APIW : 成功
图表来源
- api/controller/aftersale/UserController.php:65-133
- api/controller/aftersale/WorkController.php:112-150
- front/service/aftersale/AftersaleService.php:136-233
- front/service/aftersale/AftersaleService.php:527-628
- core/domain/aftersale/AftersaleStatus.php:51-84
详细组件分析
会员侧申请流程(小程序)
- 获取申请表单数据
- 校验订单归属与是否允许售后
- 返回订单信息、可退商品清单、草稿图片列表、草稿令牌
- 提交售后申请
- 校验原因与非法字符
- 校验所选商品行是否在订单内且可退
- 按商品余量折算申请金额,写入售后主表与明细行
- 写入申请时间线,绑定草稿附件到真实售后单
- 更新订单售后标志位,防止重复申请
flowchart TD
Start(["开始"]) --> GetForm["获取申请表单数据"]
GetForm --> CheckOrder{"订单存在且允许售后?"}
CheckOrder -- 否 --> Err1["返回不可申请"]
CheckOrder -- 是 --> BuildList["组装商品清单/草稿图片"]
BuildList --> Submit["提交申请"]
Submit --> ValidateReason{"原因合法?"}
ValidateReason -- 否 --> Err2["参数错误"]
ValidateReason -- 是 --> ValidateItems{"商品行有效?"}
ValidateItems -- 否 --> Err3["无效商品行"]
ValidateItems -- 是 --> CreateRecord["创建售后单/明细/时间线"]
CreateRecord --> UpdateOrder["更新订单售后标志"]
UpdateOrder --> End(["结束"])
图表来源
- api/controller/aftersale/UserController.php:65-133
- front/service/aftersale/AftersaleService.php:107-233
章节来源
- api/controller/aftersale/UserController.php:65-133
- front/service/aftersale/AftersaleService.php:107-233
售后状态机与流转
更新:系统现在支持10种完整的售后状态,提供更精细的状态管理
-
状态定义
PENDING- 申请中(待卖家审核)APPROVED- 卖家同意REJECTED- 卖家驳回(终态)CANCELLED- 买家撤销/逾期未寄回系统自动撤销(终态)WAITING_RETURN- 等待买家寄回(仅退货退款)RETURN_SHIPPED- 买家已寄出(填运单)RECEIVED- 卖家确认收货REFUNDING- 退款中(仅退款审核通过直接进,或收货后进)REFUNDED- 退款成功(终态)REFUND_FAILED- 退款失败(网关无回调等,待人工介入,可重试回退款中)
-
迁移规则
- 仅允许在状态表中定义的迁移路径进行流转,终态不可再迁出
- 支持退款失败重试机制(退款失败 → 退款中)
-
典型路径
- 仅退款:申请中 → 卖家同意 → 退款中 → 退款成功
- 退货退款:申请中 → 卖家同意 → 等待买家寄回 → 买家已寄出 → 卖家确认收货 → 退款中 → 退款成功
- 异常处理:退款中 → 退款失败 → 退款中 → 退款成功
stateDiagram-v2
[*] --> 申请中
申请中 --> 卖家同意 : "审核通过"
申请中 --> 已拒绝 : "审核拒绝"
申请中 --> 已取消 : "买家撤销/逾期"
卖家同意 --> 等待买家寄回 : "需退货"
卖家同意 --> 退款中 : "仅退款"
等待买家寄回 --> 买家已寄出 : "填写运单"
等待买家寄回 --> 已取消 : "超时未寄回"
买家已寄出 --> 已收货 : "确认收货"
买家已寄出 --> 已拒绝 : "拒绝收货"
已收货 --> 退款中 : "进入退款"
已收货 --> 已拒绝 : "拒绝退款"
退款中 --> 已退款 : "退款完成"
退款中 --> 退款失败 : "网关失败"
退款失败 --> 退款中 : "重试"
已退款 --> [*]
已拒绝 --> [*]
已取消 --> [*]
图表来源
- core/domain/aftersale/AftersaleStatus.php:21-84
章节来源
- core/domain/aftersale/AftersaleStatus.php:21-128
售后与订单系统关联
- 申请时锁定订单售后标志,避免重复申请
- 明细行基于订单商品行计算可退数量与金额
- 处理完成后更新订单售后状态与退款状态(部分退款/全额退款)
- 若为虚拟/特定模块,可能联动更新对应模块状态
sequenceDiagram
participant U as "用户"
participant API as "UserController"
participant SVC as "AftersaleService"
participant ORD as "订单表"
participant ITM as "订单商品行"
participant AS as "售后主表"
participant ASI as "售后明细"
U->>API : 提交申请
API->>SVC : 校验订单/商品行
SVC->>ITM : 读取可退数量
SVC->>AS : 写入售后单
SVC->>ASI : 写入明细行
SVC->>ORD : 标记 allow_aftersale=0, aftersale_status=1
SVC-->>API : 返回成功
图表来源
- front/service/aftersale/AftersaleService.php:136-233
章节来源
- front/service/aftersale/AftersaleService.php:136-233
物流跟踪(退货场景)
- 买家在"等待买家寄回"状态下填写物流公司与运单号
- 系统写入退货物流表,并推进状态至"买家已寄出"
- 后续由工作人员确认收货,进入退款流程
sequenceDiagram
participant Buyer as "买家"
participant API as "UserController"
participant SVC as "AftersaleService"
participant RT as "退货物流表"
participant STA as "状态机"
Buyer->>API : 提交运单信息
API->>SVC : submitReturnShipping(aftersaleId, company, trackingNo)
SVC->>RT : 写入/更新物流信息
SVC->>STA : WAITING_RETURN → RETURN_SHIPPED
SVC-->>API : 返回成功
图表来源
- front/service/aftersale/AftersaleService.php:336-380
- core/domain/aftersale/AftersaleStatus.php:51-84
章节来源
- front/service/aftersale/AftersaleService.php:336-380
- core/domain/aftersale/AftersaleStatus.php:51-84
后台审核与退款处理
- 审核同意:设置批准金额,推进状态至"退款中",写入人工退款记录,最终完成退款并更新订单售后状态
- 确认收货:将"买家已寄出"推进至"确认收货",随后进入退款流程
- 派发退款:触发支付网关退款(如需要),并支持确认网关退款完成
sequenceDiagram
participant Admin as "后台管理员"
participant AC as "Admin AftersaleController"
participant SVC as "AftersaleService"
participant STA as "状态机"
participant OR as "订单/退款表"
Admin->>AC : 审核同意(金额, 备注)
AC->>SVC : approve(...), reject(...), receive(...), dispatchRefund(...)
SVC->>STA : PENDING→APPROVED→REFUNDING→REFUNDED
SVC->>OR : 写入退款记录/更新订单售后与退款状态
SVC-->>AC : 返回成功
图表来源
- admin/controller/aftersale/AftersaleController.php:100-180
- front/service/aftersale/AftersaleService.php:527-628
- core/domain/aftersale/AftersaleStatus.php:51-84
章节来源
- admin/controller/aftersale/AftersaleController.php:100-180
- front/service/aftersale/AftersaleService.php:527-628
- core/domain/aftersale/AftersaleStatus.php:51-84
表单字段与校验要点
- 申请原因:必填,禁止非法字符
- 售后类型:仅退款/退货退款(影响是否需要寄回)
- 商品选择:从订单商品行中选择,系统校验有效性并按余量折算金额
- 凭证上传:使用草稿令牌暂存图片,提交后绑定到真实售后单
章节来源
- api/controller/aftersale/UserController.php:65-133
- front/service/aftersale/AftersaleService.php:136-233
业务规则汇总
- 退货期限验证:申请前校验订单是否允许售后(含发货时间与政策限制)
- 退款金额计算:按所选商品行的可退数量与金额摊分计算
- 物流费用承担:根据售后类型与平台策略决定运费承担方(可在扩展点配置)
- 撤销规则:仅在"申请中"或"等待买家寄回"可撤销,撤销后恢复订单可再申请
- 新增:退款失败重试机制,支持退款失败后重新尝试退款流程
章节来源
- front/service/aftersale/AftersaleService.php:107-233
- front/service/aftersale/AftersaleService.php:382-413
- core/domain/aftersale/AftersaleStatus.php:51-84
依赖关系分析
- 控制器依赖服务:会员侧与工作人员侧控制器均依赖前台服务完成核心逻辑
- 服务依赖状态机:所有状态变更通过状态机校验,确保一致性
- 服务依赖订单与商品数据:申请与处理均需读取订单与商品行信息
- 后台控制器与服务解耦:后台通过服务方法驱动状态与数据变更
graph LR
UC["UserController"] --> SVC["AftersaleService"]
WC["WorkController"] --> SVC
AC["Admin AftersaleController"] --> SVC
SVC --> STA["AftersaleStatus"]
SVC --> TP["AftersaleType"]
SVC --> ORD["订单/商品表"]
图表来源
- api/controller/aftersale/UserController.php:29-133
- api/controller/aftersale/WorkController.php:30-150
- admin/controller/aftersale/AftersaleController.php:28-180
- front/service/aftersale/AftersaleService.php:32-67
- core/domain/aftersale/AftersaleStatus.php:21-84
- core/domain/aftersale/AftersaleType.php:21-73
章节来源
- api/controller/aftersale/UserController.php:29-133
- api/controller/aftersale/WorkController.php:30-150
- admin/controller/aftersale/AftersaleController.php:28-180
- front/service/aftersale/AftersaleService.php:32-67
- core/domain/aftersale/AftersaleStatus.php:21-84
- core/domain/aftersale/AftersaleType.php:21-73
性能考虑
- 分页与只读字段:列表接口采用分页,仅查询必要字段,减少数据传输
- 批量写入:申请时批量写入售后明细,减少数据库往返
- 状态机校验:集中化状态迁移校验,避免分散逻辑导致额外查询
- 缓存建议:对频繁读取的订单快照与商品清单可引入缓存层(按需扩展)
故障排查指南
- 申请失败
- 检查订单是否存在且允许售后
- 检查原因是否为空或包含非法字符
- 检查所选商品行是否属于当前订单
- 状态无法流转
- 核对当前状态与目标状态是否符合状态机迁移表
- 检查是否处于终态(不可再迁出)
- 新增:检查退款失败状态是否正确处理重试逻辑
- 退款异常
- 检查退款金额是否超过订单金额
- 检查退款记录是否写入成功
- 若为网关退款,确认回调与确认完成流程
- 新增:处理退款失败的重试机制
章节来源
- api/controller/aftersale/UserController.php:94-133
- front/service/aftersale/AftersaleService.php:136-233
- front/service/aftersale/AftersaleService.php:527-628
- core/domain/aftersale/AftersaleStatus.php:51-84
结论
本模块以清晰的分层架构与严格的状态机控制,实现了小程序端的售后服务全流程。更新后的10种状态设计提供了更精细的状态管理能力,支持退款失败重试等复杂业务场景。通过统一的申请校验、明细行金额计算、物流跟踪与退款处理,确保了售后业务的准确性与可追溯性。建议在扩展换货/维修功能时,复用现有状态机与服务层,保持流程一致性与可维护性。
附录
- 常见接口说明
- 会员侧
- 获取申请表单数据:POST/GET 获取订单信息与可退商品清单
- 提交售后申请:POST 提交原因、类型、商品行、草稿令牌
- 填写运单:POST 物流公司与运单号(退货场景)
- 工作人员侧
- 售后列表:GET 按状态筛选
- 售后详情:GET 查看售后单详情
- 处理售后单:POST 审核通过并进入退款流程
- 会员侧
- 状态与类型参考
- 售后类型:仅退款、退货退款、换货(预留)、维修(预留)
- 更新:售后状态:申请中、卖家同意、等待买家寄回、买家已寄出、确认收货、退款中、退款成功、已拒绝、已取消、退款失败
- 新增:状态转换规则
- 支持退款失败重试机制
- 完善的终态保护机制
- 详细的迁移路径验证