接手teanary售后系统升级这个项目,最开始并不是因为什么宏大的技术愿景,而是被一条用户投诉逼出来的。有个用户凌晨申请了退货,系统秒回了一封"已受理"的邮件,然后整整三天没有任何动静,退货申请既没通过也没驳回,用户以为是商家装死,直接跑去投诉渠道刷了一整屏的帖子。这事传回技术部,研发一看后台,工单其实早就流转到了仓库确认节点,只是仓库那边一直没点"同意收货",系统也完全没有提醒机制。用户看不到进度,客服查不到节点,研发改不了逻辑——一套售后系统,硬生生卡成了三不管地带。
"teanary 售后系统升级"这个项目,说白了就两件事:让用户安心,让系统可扩展。用户安心,指的是用户能随时知道售后申请走到哪一步,每个环节有明确预期,超时了有人兜底;系统可扩展,指的是售后流程不用每次新需求一来就改代码、发版本,而是通过状态机、事件、插件化的方式,把后续可能出现的维修、换货、以旧换新、线下门店核销这些五花八门的场景,都变成可配置、可插拔的能力。这篇就把整个升级过程中的设计思路、落地细节、踩坑记录都摊开讲,给正在折腾售后、工单、客服系统的朋友一个参考。
1. 升级前,售后链路卡在了哪儿
先别急着谈方案,得先搞清楚旧系统到底哪里疼。teanary原来的售后系统不是没有,而是功能都有,但逻辑全部写死在代码里,流程完全是"能跑就算赢"的状态。我把问题拆成三端来看,每一端都有自己的火气。
1.1 用户侧:不是不能退,是"不知道退到哪一步了"
用户侧最大的痛点不是审核不通过,而是"状态不可见"。用户提交退货申请后,看到的状态永远只有两种:处理中、已完成。至于系统到底在等谁、是仓库没收货、是财务没打款、还是客服忘了点按钮,用户一概不知。
这带来的连锁反应很典型:用户不知道进度,就只能催客服;客服去后台查单,发现状态是"处理中",也不知道具体卡在哪个内部节点;于是客服只能回复"已催促,请耐心等待"。用户觉得被敷衍,客服觉得被冤枉,两边都在跟一个说不清的状态搏斗。
另外还有个很现实的体验问题:退款什么时候到账、上门取件谁联系、运费谁承担、超时了会怎样,这些信息在用户提交售后申请的那一刻全部是缺失的。用户填完单子就像把东西扔进了一个黑箱,全靠信念等待。这种不确定感,本身就是投诉率居高不下的重要来源。
1.2 客服侧:大量人工核对,工单靠人肉流转
客服侧的问题更直接:大量本来应该由系统自动流转、自动通知的环节,全在靠人工盯。举个例子,用户申请退货后,需要仓库确认收货,但旧系统没有任何超时提醒。仓库如果那天忙忘了,工单就会一直挂在"待收货确认"状态,直到用户来催,客服才手工去联系仓库。
还有一类工作量来自信息重复录入。用户发起换货,客服需要手动复制一遍用户收货地址;仓库反馈商品有破损,客服再手动登记损坏情况;财务需要打款,客服还要手工同步退款金额。每一步都靠人在不同后台和表格之间搬运数据,看着是小事,量一大就会出错。
最要命的是,当同一笔订单涉及退款、换货、补发多个售后动作时,旧系统只能串行处理:先关掉退款,再开一张换货工单,再开一张补发工单。一旦中间某个节点挂了,整条链路就断了,客服只能从头查一遍。这种"人肉工作流"不仅效率低,还完全谈不上可靠。
1.3 开发侧:状态机写死,新需求一加就崩
开发侧的问题最核心:旧系统的售后退款流程,是用一大坨 if else 和 switch case 拼出来的状态流转。看着像状态机,实际上每个分支都跟业务代码强耦合。想加一个"超时自动同意退货"的规则,就得去翻三尺深的代码;想区分"退货退款"和"仅退款"两种流程,就得复制粘贴一大段业务逻辑然后改几个字段。
我当时随手翻了一下代码,发现一个工单状态对应的行为散落在十几个类里,有的写在 controller,有的写在 service,还有的藏在定时任务的 SQL 里。改一个状态流转,你敢保证不漏?事实就是不敢保证,所以每次售后业务有调整,研发周期都得按周算。
更尴尬的是,当时的"可扩展"完全停留在口号层面。仓库对接了一套自研 ERP,财务接了一个外部支付平台,客服用的是另一个工单系统,每加一个外部依赖,就要在售后系统里硬编码对应的 HTTP 调用和回调处理。系统越来越重,可扩展性却越来越差,用一句话总结就是:所有地方都能改,改哪里都心惊胆战。这种状
