[teanary]售后系统升级:让用户安心,也让系统可扩展

4 阅读4分钟

售后系统升级:让用户安心,也让系统可扩展

项目:gitee.com/teanary/tea…

做电商最难的,往往不是卖货,而是售后。
用户希望流程简单透明,客服希望处理高效有据可查,技术团队则需要一套能长期演进的架构。

这次我们把售后能力做了一次完整升级:前台支持 仅退款、退货退款、换货,后台提供统一审核与处理入口;同时在技术上完成了模型、状态机和服务层的重构,让“业务体验”和“工程质量”同步提升。


先看结果:用户体验有什么变化?

用户现在可以在 个人中心 -> 我的订单 -> 订单详情 直接发起售后,不需要额外联系客服找入口。
并且支持两种粒度:

  • 按单个商品发起;
  • 按整单发起。

提交时,用户填写:

  • 售后理由(必填);
  • 详细说明(选填)。

提交后可在订单页直接查看售后记录与进度,核心信息(类型、状态、时间、理由、说明)一目了然,减少反复沟通成本。


再看后台:客服处理为什么更顺手?

后台新增了售后管理页,客服可按订单号、用户、类型、状态等维度筛选并批量处理。
常见动作包括:

  • 审核通过;
  • 审核拒绝;
  • 标记完成;
  • 取消售后。

同时支持填写内部备注,用于团队协作和过程留痕。该备注默认只在后台可见,避免对用户暴露内部沟通信息。


技术架构:我们怎么把这件事“做稳”?

这次不是“多加几个字段和按钮”,而是采用了分层设计,核心是把业务规则从页面中抽离出来。

1. 数据模型层

新增独立售后实体 after_sales,并与订单域核心对象建立关联:

  • order_id:关联订单;
  • order_item_id:关联订单行;
  • product_id:关联商品;
  • warehouse_id:关联仓库;
  • user_id:关联发起用户。

这样做的价值是:售后成为一等业务对象,后续统计、审计、扩展都不再依赖“订单备注式”存储。

2. 领域与服务层

通过 AfterSale 模型承载关系映射与状态定义,通过 AfterSaleService 统一处理关键动作:

  • 创建售后;
  • 审核(通过/拒绝);
  • 完成;
  • 取消;
  • (预留)退货物流更新。

页面只负责交互,规则由服务层集中维护,避免“前台一套规则、后台一套规则”的分裂问题。

3. 交互层(Livewire)

前台用户申请与后台客服处理都使用 Livewire 组件,保持交互一致、反馈及时,减少传统多控制器分散逻辑带来的维护负担。


状态机设计:保证流程可追踪、可回放

售后单状态流转

  • pending -> approved -> completed
  • pending -> rejected
  • approved / in_return -> canceled

订单状态联动

  • 发起售后或审核通过:订单置为 after_sale
  • 售后完成:订单置为 after_sale_done
  • 特定取消场景:订单可回退为 completed

联动由服务层统一触发,保证状态一致性,降低脏数据概率。


关键约束:支持“多次申请”,但不允许“超量申请”

真实业务里,同一订单常常会多次发起售后(例如分批发现问题)。
我们支持这一能力,但加了硬约束:

  • 基于 order_id + order_item_id 聚合已占用售后数量;
  • 排除已取消、已拒绝的记录;
  • 新申请数量 + 已占用数量 <= 购买数量。

这样既满足业务灵活性,也守住了风控边界。


为什么说这套架构“能继续长”?

本次版本先打通主流程,但关键扩展位已预留,后续可以平滑升级:

  • refund_amount:对接支付网关做自动退款;
  • exchange_product_id:接入换货目标 SKU 与补发链路;
  • logistics_company / tracking_number:闭环退货物流追踪;
  • images:支持凭证图片上传与审核。

也就是说,当前我们实现的是“流程可用”,下一步可以逐步演进到“资金流 + 物流流 + 库存流”协同的一体化售后系统。


小结

这次售后升级,本质上做了两件事:

  • 对用户:把售后变成看得见、跟得上、可追踪的服务体验;
  • 对系统:把售后从页面功能升级为可扩展的业务能力。

短期提升体验,长期降低维护成本。
这也是我们在业务迭代中始终坚持的原则:先让流程跑通,再让架构跑远。