diff --git a/changelogs-v2-mp/2026-06/22_4161_售后申诉-新增接口-小程序端.md b/changelogs-v2-mp/2026-06/22_4161_售后申诉-新增接口-小程序端.md new file mode 100644 index 0000000..dcedc70 --- /dev/null +++ b/changelogs-v2-mp/2026-06/22_4161_售后申诉-新增接口-小程序端.md @@ -0,0 +1,340 @@ +# 售后申诉 — 小程序端新增接口 + +- **端类型**:小程序端 +- **变更类型**:新增接口 +- **日期**:2026-06-22 +- **关联 Issue**:https://git.1814.love:8443/wx/HL/issues/4161 +- **关联 PR**:#4185(小程序端接口)/ #4162 #4165 #4168 #4187(基础能力) +- **后端负责人**:腰苏图(yaosutu) + +--- + +## 一、接口背景 + +v3 全新售后服务中心(com.hulalv.aftersale)上线。小程序端用户可发起投诉或申诉、查看自己的工单列表与详情、以及在工单未处置前随时撤回。 + +新增 4 个接口(含 1 个原有但归入本域):发起工单、我的工单列表、工单详情、撤回工单。 + +本次为全新域,不影响任何已有接口。 + +--- + +## 二、变更清单 + +| 编号 | 方法 | 路径 | 说明 | +|------|------|------|------| +| 1 | POST | /v3/mp/aftersale/ticket | 发起投诉/申诉工单 | +| 2 | GET | /v3/mp/aftersale/ticket/my | 我的工单列表(按订单分页) | +| 3 | GET | /v3/mp/aftersale/ticket/{id} | 工单详情 | +| 4 | POST | /v3/mp/aftersale/ticket/{id}/withdraw | 撤回工单 | + +--- + +## 三、接口详情 + +| 属性 | 说明 | +|------|------| +| 认证方式 | JWT Bearer Token(C 端 Token,Gateway 解析后注入 userId) | +| userId 传递 | Gateway 解析 JWT 后注入到请求属性,后端从 HttpServletRequest 取;前端无需传 userId 字段 | +| 限流 | Gateway 默认限流策略 | +| 路径前缀 | /v3/mp/aftersale/ticket | + +--- + +## 四、接口入参 + +### 4.1 POST /v3/mp/aftersale/ticket — 发起工单 + +请求体(JSON): + +| 字段 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------| +| orderId | Long | 是 | — | 订单 ID | +| category | String | 是 | COMPLAINT / APPEAL | 大类:投诉/申诉 | +| type | String | 是 | 见 §六枚举 | 细分类型,必须与 category 匹配 | +| title | String | 是 | 最多 100 字 | 工单标题 | +| description | String | 是 | 最多 2000 字 | 诉求描述 | +| targetRefId | Long | 条件必填 | — | 申诉时必填:关联退款申请 ID;投诉时可不传(不传则用 orderId) | +| claimType | String | 否 | REFUND / RECTIFY / EXPLANATION | 用户诉求类型,仅供参考 | +| claimAmount | Number | 否 | — | 用户期望金额,仅供参考,无约束力 | +| attachments | Array | 否 | 最多 10 个 | 附件 URL 列表(图片/视频) | + +### 4.2 GET /v3/mp/aftersale/ticket/my — 我的工单列表 + +Query 参数: + +| 字段 | 类型 | 必填 | 约束 | 说明 | +|------|------|------|------|------| +| orderId | Long | 是 | — | 订单 ID,只查该订单下的工单 | +| pageNo | Integer | 否 | >= 1 | 页码,默认 1 | +| pageSize | Integer | 否 | 1-50 | 每页条数,默认 20 | + +### 4.3 GET /v3/mp/aftersale/ticket/{id} — 工单详情 + +路径参数:id(String/Long)必填,工单 ID。 + +注:后端校验工单归属,非本人工单返回 586014。 + +### 4.4 POST /v3/mp/aftersale/ticket/{id}/withdraw — 撤回工单 + +路径参数:id(String/Long)必填,工单 ID。 + +无请求体。后端校验:1. 工单归属(非本人返回 586014);2. 状态(只有 SUBMITTED / PROCESSING 可撤回,否则返回 586013)。 + +--- + +## 五、出参字段 + +### 5.1 发起工单 — 返回工单 ID + +```json +{"code": 200, "data": "1895000000000001"} +``` + +data 为 String(Long),即新建工单的 ID。 + +### 5.2 我的工单列表 — PageResult 结构 + +```json +{ + "code": 200, + "data": { + "list": [], + "total": 5, + "pageNo": 1, + "pageSize": 20 + } +} +``` + +### 5.3 工单详情及列表行 — TicketMpRespVO 字段 + +| 字段 | 类型 | 说明 | +|------|------|------| +| id | String(Long) | 工单 ID | +| orderId | String(Long) | 关联订单 ID | +| category | String | 大类枚举值:COMPLAINT / APPEAL | +| categoryLabel | String | 大类中文名:投诉 / 申诉 | +| type | String | 细分类型枚举值,见 §六 | +| typeLabel | String | 细分类型中文名 | +| title | String | 工单标题 | +| description | String | 诉求描述 | +| claimType | String | 用户诉求类型(可选) | +| claimAmount | Number | 用户期望金额(可选) | +| attachments | Array | 附件 URL 列表 | +| status | String | 工单状态枚举值,见 §六 | +| statusLabel | String | 工单状态中文名 | +| resolutionRemark | String | 处置说明(RESOLVED / CLOSED 后可见,用于展示给用户) | +| canWithdraw | Boolean | 是否可撤回(SUBMITTED / PROCESSING 且非终态时为 true) | +| createdAt | String(ISO 8601) | 创建时间 | +| updatedAt | String(ISO 8601) | 更新时间 | + +注:C 端视图隐藏处置细节(decision / resolutionType / resolutionAmount / approvalNo / linkedRefundId),仅展示 status 和 resolutionRemark。 + +### 5.4 撤回工单 + +```json +{"code": 200, "data": null} +``` + +--- + +## 六、枚举 / 数据字典 + +### AftersaleCategory — 工单大类 + +| 枚举值 | 中文名 | 场景 | +|--------|--------|------| +| COMPLAINT | 投诉 | 对已发生的服务质量不满 | +| APPEAL | 申诉 | 对某个处理结果不服,求复核 | + +### AftersaleTicketType — 细分类型(type 字段) + +| 枚举值 | 中文名 | 归属大类 | +|--------|--------|----------| +| ITINERARY | 行程 | COMPLAINT | +| HOTEL | 酒店 | COMPLAINT | +| VEHICLE | 车 | COMPLAINT | +| GUIDE | 导游 | COMPLAINT | +| OTHER | 其他 | COMPLAINT | +| REFUND_REJECTED | 退款被拒 | APPEAL | +| REFUND_AMOUNT_DISPUTE | 退款金额异议 | APPEAL | + +注:type 必须与 category 匹配,否则返回 586012。 + +### AftersaleTicketStatus — 工单状态 + +| 枚举值 | 中文名 | 终态 | 说明 | +|--------|--------|------|------| +| SUBMITTED | 已提交 | 否 | 等待受理 | +| PROCESSING | 处理中 | 否 | 客服受理中 | +| RESOLVED | 已处置 | 否 | 处置方案落定(退款类等待到账) | +| CLOSED | 已关闭 | 是 | 流程终结 | +| WITHDRAWN | 已撤回 | 是 | 用户主动撤回 | + +canWithdraw = true 的条件:status 为 SUBMITTED 或 PROCESSING。 + +### claimType — 用户诉求类型(参考值,无强制约束) + +| 常见值 | 中文名 | +|--------|--------| +| REFUND | 退款 | +| RECTIFY | 整改 | +| EXPLANATION | 要个说法 | + +--- + +## 七、错误码 + +| 错误码 | 说明 | 触发场景 | +|--------|------|----------| +| 586009 | 工单不存在 | 传入 id 找不到工单 | +| 586011 | 同一对象已存在活跃工单 | 防重复提交(同订单下同 target 已有进行中工单) | +| 586012 | category 与 type 不匹配 | 如 COMPLAINT 传了 REFUND_REJECTED | +| 586013 | 撤回时状态非法 | 终态或 RESOLVED 工单不可撤回 | +| 586014 | 非本人工单 | 查看/撤回他人工单 | +| 586015 | 申诉必须关联退款申请 | APPEAL 类工单未传 targetRefId | +| 586016 | 申诉关联退款状态不合法 | 关联的退款申请状态不允许申诉 | + +--- + +## 八、示例 + +### 8.1 典型成功 — 发起投诉工单 + +请求: +``` +POST /v3/mp/aftersale/ticket +Authorization: Bearer {mp_token} +Content-Type: application/json + +{ + "orderId": 1800000000000099, + "category": "COMPLAINT", + "type": "HOTEL", + "title": "酒店降级投诉", + "description": "订单挂四星酒店实际入住三星,要求退差价", + "claimType": "REFUND", + "claimAmount": 600.00, + "attachments": ["https://oss.example.com/img1.jpg"] +} +``` + +响应: +```json +{"code": 200, "data": "1895000000000001"} +``` + +### 8.2 典型成功 — 发起申诉工单(退款被拒) + +``` +POST /v3/mp/aftersale/ticket +Authorization: Bearer {mp_token} +Content-Type: application/json + +{ + "orderId": 1800000000000099, + "category": "APPEAL", + "type": "REFUND_REJECTED", + "targetRefId": 9876543210, + "title": "退款申请被拒申诉", + "description": "退款申请被拒,但供应商确实未提供服务,要求重新审核" +} +``` + +响应: +```json +{"code": 200, "data": "1895000000000002"} +``` + +### 8.3 边界情况 — 查询工单详情(已处置,展示处置说明) + +```json +{ + "code": 200, + "data": { + "id": "1895000000000001", + "orderId": "1800000000000099", + "category": "COMPLAINT", + "categoryLabel": "投诉", + "type": "HOTEL", + "typeLabel": "酒店", + "title": "酒店降级投诉", + "description": "订单挂四星酒店实际入住三星,要求退差价", + "claimType": "REFUND", + "claimAmount": 600.00, + "attachments": ["https://oss.example.com/img1.jpg"], + "status": "CLOSED", + "statusLabel": "已关闭", + "resolutionRemark": "经核实酒店确实降级,已退差价 500 元", + "canWithdraw": false, + "createdAt": "2026-06-22T09:00:00", + "updatedAt": "2026-06-22T15:30:00" + } +} +``` + +### 8.4 业务失败 — 申诉未传 targetRefId + +```json +{"code": 586015, "msg": "申诉必须关联一笔有效的退款申请"} +``` + +### 8.5 业务失败 — 撤回已 CLOSED 工单 + +```json +{"code": 586013, "msg": "撤回时工单状态非法(只有 SUBMITTED / PROCESSING 可撤回)"} +``` + +--- + +## 九、业务边界 + +适用: +- 同一订单下同一 targetRef 只能有一个活跃工单(SUBMITTED / PROCESSING / RESOLVED),否则返回 586011 +- 申诉(APPEAL)类工单必须关联一笔有效的退款申请(targetRefId 必填) +- SUBMITTED / PROCESSING 状态的工单可撤回,canWithdraw=true + +不适用: +- 终态工单(CLOSED / WITHDRAWN)不可撤回 +- 非本人工单不可查看/撤回 + +特殊边界: +- 工单从 PROCESSING 撤回后,若该工单已提交企微 OA,后端会自动撤回 OA 审批(异步,不影响前端响应) +- attachments 最多 10 个,超出返回参数校验错误 + +--- + +## 十、修改前后对比 + +本次为全新域新增接口,无旧接口对比。 + +--- + +## 十一、影响评估 / 回滚 + +本次为全新域,不影响任何已有小程序接口,可独立上线。 + +回滚方案:回滚后端服务版本即可。 + +--- + +## 十二、注意事项 + +1. 发起工单返回值是 String(Long):data 字段为新建工单的 ID,是字符串而非数字。 +2. C 端视图隐藏处置细节:resolutionAmount / decision / approvalNo 等字段在 C 端不返回,不要在小程序页面展示。resolutionRemark 是给用户看的处置说明,可展示。 +3. canWithdraw 字段已由后端计算:前端直接用该字段判断是否显示撤回按钮,无需自行判断状态。 +4. 所有 ID 为字符串:id / orderId 均序列化为字符串,前端不要转 Number。 +5. category=APPEAL 时:targetRefId 必填(关联退款申请 ID),targetRefType 后端自动设为 REFUND_APPLICATION。 + +--- + +## 十三、关联 / 联系人 + +- Issue:https://git.1814.love:8443/wx/HL/issues/4161 +- PR #4185(小程序端接口):https://git.1814.love:8443/wx/HL/pulls/4185 +- PR #4162(售后基建):https://git.1814.love:8443/wx/HL/pulls/4162 +- PR #4165(受理/处置 + OA 接入):https://git.1814.love:8443/wx/HL/pulls/4165 +- PR #4168(OA 回调内部接口):https://git.1814.love:8443/wx/HL/pulls/4168 +- PR #4187(退款驱动联动):https://git.1814.love:8443/wx/HL/pulls/4187 +- 后端负责人:腰苏图(yaosutu)