diff --git a/changelogs-v2-mp/2026-06/23_4250_退款申诉新增+售后工单下线-小程序端.md b/changelogs-v2-mp/2026-06/23_4250_退款申诉新增+售后工单下线-小程序端.md new file mode 100644 index 0000000..bc23332 --- /dev/null +++ b/changelogs-v2-mp/2026-06/23_4250_退款申诉新增+售后工单下线-小程序端.md @@ -0,0 +1,222 @@ +# 退款申诉(新增)+ 统一售后工单接口下线(小程序端) + +- 端类型:小程序端 +- 变更类型:新增接口(4)+ 删除接口(统一售后工单 mp 端) +- 关联 Issue:#4250 PR:#4251 #4254 +- 日期:2026-06-23 + +--- + +## ① 接口背景 + +售后体系重构:原"投诉 + 申诉统一售后工单"方向作废,拆为**投诉**与**申诉**两套独立能力。 +- **申诉**:用户对"退款被拒"或"退款金额"不服时发起,**小程序入口仍是「退款申诉」**。申诉记录单独存(不再混入退款申请表)。 +- **关键变化**:申诉**复用既有退款审批**——发起申诉后系统自动建一笔 PENDING 退款申请,由管理员在退款审批里复核(通过则退款 / 驳回则结束);申诉本身不再有独立审批。 +- 原统一售后工单接口(`/v3/mp/aftersale/ticket*`)**全部下线**。 + +--- + +## ② 变更清单 + +| # | 方法 | 路径 | 类型 | +|---|---|---|---| +| 1 | POST | `/v3/mp/refund/appeal` | 🆕 新增(发起申诉)| +| 2 | GET | `/v3/mp/refund/appeal/my` | 🆕 新增(我的申诉,分页)| +| 3 | GET | `/v3/mp/refund/appeal/{id}` | 🆕 新增(申诉详情)| +| 4 | POST | `/v3/mp/refund/appeal/{id}/withdraw` | 🆕 新增(撤回申诉)| +| 5 | ALL | `/v3/mp/aftersale/ticket*` | ❌ 删除(统一售后工单下线,调用返回 404)| + +统一响应包装 `Result`:`{ code, message, data, success }`,`code=200` 为成功。 + +--- + +## ③ 接口详情 + +### 1. 发起申诉 `POST /v3/mp/refund/appeal` +用户对一笔退款申请发起申诉。两种类型:`REFUND_REJECTED`(退款被拒,原退款 status=REJECTED 才可申诉)/ `REFUND_AMOUNT_DISPUTE`(退款金额异议,原退款 status=REFUNDED 求补差)。 +> 发起成功后:① 落一条申诉记录(PENDING)② **自动建一笔 PENDING 退款申请**走退款审批 ③ 订单进入「售后中」。 + +### 2. 我的申诉 `GET /v3/mp/refund/appeal/my` +当前登录用户的申诉分页列表。 + +### 3. 申诉详情 `GET /v3/mp/refund/appeal/{id}` +单条申诉详情,含关联的两笔退款(来源退款 + 申诉触发的退款)。 + +### 4. 撤回申诉 `POST /v3/mp/refund/appeal/{id}/withdraw` +仅 `PENDING`(审批中)状态可撤回;撤回会一并取消申诉触发的那笔 PENDING 退款申请。 + +--- + +## ④ 入参 + +### 接口1 create(`@RequestBody`,登录态 userId 由网关注入) +| 参数 | 类型 | 必填 | 说明 | +|---|---|---|---| +| refundApplicationId | long | 是 | 来源退款申请 ID(被申诉的那笔退款)| +| appealType | string | 是 | 申诉类型:`REFUND_REJECTED` / `REFUND_AMOUNT_DISPUTE` | +| appealReason | string | 是 | 申诉理由(≤2000 字)| +| appealAmount | string(decimal) | 否 | 期望退款金额(金额异议时填)| +| mediaTraceIds | string[] | 否 | 凭证图片机审 traceId 列表(前端上传后透传,≤12)| + +### 接口2 my +| 参数 | 类型 | 必填 | 说明 | +|---|---|---|---| +| pageNo | int | 否 | 页码,默认 1 | +| pageSize | int | 否 | 每页条数,默认 20 | + +### 接口3 detail / 接口4 withdraw +| 参数 | 位置 | 类型 | 说明 | +|---|---|---|---| +| id | path | long | 申诉 ID | + +--- + +## ⑤ 出参 + +### 接口1 create `Result` +`data` = 新建申诉 ID(字符串化 Long)。 + +### 接口2 my `Result>`;接口3 detail `Result` +`PageResult`:`{ records[], total, page, pageSize }`。`AppealMpRespVO`: + +| 字段 | 类型 | 说明 | +|---|---|---| +| id | string(Long) | 申诉 ID | +| orderId | string(Long) | 订单 ID | +| refundApplicationId | string(Long) | 来源退款申请 ID | +| appealType | string | 申诉类型(枚举值,见⑥)| +| appealTypeLabel | string | 申诉类型中文名 | +| appealReason | string | 申诉理由 | +| appealAmount | string(decimal) | 申诉退款金额 | +| appealStatus | string | 申诉状态(枚举值,见⑥)| +| appealStatusLabel | string | 申诉状态中文名 | +| applicantName | string | 申请人姓名 | +| reviewedAt | datetime | 审批完成时间(可空)| +| createTime | datetime | 创建时间 | +| sourceRefund | object | 来源退款信息(被申诉的原退款),见下 | +| triggeredRefund | object | 申诉触发的退款信息(申诉建单后自动生成的退款),见下 | + +`sourceRefund` / `triggeredRefund` 结构(关联退款信息): +| 字段 | 类型 | 说明 | +|---|---|---| +| refundApplicationId | string(Long) | 退款申请 ID | +| status | string | 退款状态(PENDING/APPROVED/REJECTED/REFUNDING/REFUNDED/CANCELLED/ABNORMAL)| +| actualAmount | string(decimal) | 实际退款金额(可空)| + +### 接口4 withdraw `Result` +`data` = null。 + +--- + +## ⑥ 枚举 / 数据字典 + +**申诉类型 appealType**: +| 值 | 含义 | +|---|---| +| REFUND_REJECTED | 退款被拒(原退款被驳回后申诉)| +| REFUND_AMOUNT_DISPUTE | 退款金额异议(已退款但金额有异议,求补差)| + +**申诉状态 appealStatus**: +| 值 | 含义 | +|---|---| +| PENDING | 审批中(申诉触发的退款申请待退款审批)| +| REJECTED | 已驳回(退款审批驳回)| +| REFUNDED | 退款到账(申诉成功,退款已退)| +| WITHDRAWN | 已撤回 | + +--- + +## ⑦ 错误码(段位 530600-530699) + +| code | message | +|---|---| +| 530601 | 申诉必须关联一笔退款申请 | +| 530602 | 关联的退款申请不存在 | +| 530603 | 退款申请当前状态不满足申诉条件 | +| 530604 | 该退款申请已有处理中的申诉,请勿重复提交 | +| 530605 | 申诉退款金额超出可退余额 | +| 530606 | 申诉记录不存在 | +| 530607 | 无权操作此申诉 | +| 530608 | 当前申诉状态不允许撤回,仅待审核状态可撤回 | +| 530609 | 申诉类型无效 | + +--- + +## ⑧ 示例 + +### 典型:发起申诉(退款被拒) +请求 `POST /v3/mp/refund/appeal`: +```json +{ "refundApplicationId": 20001, "appealType": "REFUND_REJECTED", + "appealReason": "退款审核不合理,申请复核", "appealAmount": "300.00", + "mediaTraceIds": [] } +``` +响应:`{ "code":200, "message":"成功", "data":"40001", "success":true }` + +### 典型:我的申诉 +请求 `GET /v3/mp/refund/appeal/my?pageNo=1&pageSize=10`,响应(节选一项): +```json +{ "code":200, "success":true, "data": { "total":1, "records":[ + { "id":"40001", "orderId":"10001", "appealType":"REFUND_REJECTED", "appealTypeLabel":"退款被拒", + "appealStatus":"PENDING", "appealStatusLabel":"审批中", "appealAmount":"300.00", + "sourceRefund": { "refundApplicationId":"20001", "status":"REJECTED", "actualAmount":null }, + "triggeredRefund": { "refundApplicationId":"20009", "status":"PENDING", "actualAmount":null } } +] } } +``` + +### 异常:重复申诉 +对同一退款申请已有处理中申诉时再发起: +```json +{ "code":530604, "message":"该退款申请已有处理中的申诉,请勿重复提交", "success":false } +``` + +### 异常:调用已下线的工单接口 +请求 `POST /v3/mp/aftersale/ticket`(旧统一售后工单接口): +```json +{ "code":404, "message":"Not Found" } +``` + +--- + +## ⑨ 业务边界 + +- 申诉**复用退款审批**:发起后自动建 PENDING 退款申请,管理员在退款审批里复核——**前端不要再调用任何"申诉审批"接口**(已无独立申诉审批)。 +- 申诉状态跟随其触发的退款申请:退款到账→REFUNDED,退款审批驳回→REJECTED。 +- 撤回仅 PENDING 可撤,且会取消触发的 PENDING 退款。 +- 申诉发起即把订单标记「售后中」,终结(REFUNDED/REJECTED/WITHDRAWN 且无其他活跃售后)后回切。 + +--- + +## ⑩ 修改前后对比 + +| | 修改前 | 修改后 | +|---|---|---| +| 申诉入口 | 统一售后工单 `POST /v3/mp/aftersale/ticket`(category=APPEAL)| `POST /v3/mp/refund/appeal` | +| 我的申诉 | `/v3/mp/aftersale/ticket/my` | `/v3/mp/refund/appeal/my` | +| 详情/撤回 | `/v3/mp/aftersale/ticket/{id}` `/{id}/withdraw` | `/v3/mp/refund/appeal/{id}` `/{id}/withdraw` | +| 审批 | 申诉独立 OA 审批 | 无(复用退款审批)| + +--- + +## ⑪ 影响评估 / 回滚 + +- **破坏性**:`/v3/mp/aftersale/ticket*` 已删,调用返回 404,前端涉及"退款申诉"的页面**必须切到新申诉接口**。 +- 投诉接口不在此列(投诉走 C 端经 BFF 的现有通道,无变化)。 +- 回滚:后端回滚 PR #4251 #4254。 + +--- + +## ⑫ 注意事项 + +- 金额字段(appealAmount / actualAmount)均为**字符串**,前端按字符串处理防精度丢失。 +- Long 型 ID 均字符串化返回(防 JS 精度)。 +- 上传凭证图片仍走既有 wx 内容安全机审通道(mediaTraceIds 透传)。 + +--- + +## ⑬ 关联 / 联系人 + +- Issue:https://git.1814.love:8443/wx/HL/issues/4250 +- PR:https://git.1814.love:8443/wx/HL/pulls/4251 ・ https://git.1814.love:8443/wx/HL/pulls/4254 +- 后端负责人:腰苏图 +- 已部署测试服并网关实调验证通过(申诉接口 200 / 工单接口 404)。 diff --git a/changelogs-v2/2026-06/23_4250_退款申诉新增+售后工单下线-管理后台.md b/changelogs-v2/2026-06/23_4250_退款申诉新增+售后工单下线-管理后台.md new file mode 100644 index 0000000..ba99d43 --- /dev/null +++ b/changelogs-v2/2026-06/23_4250_退款申诉新增+售后工单下线-管理后台.md @@ -0,0 +1,205 @@ +# 退款申诉(新增)+ 统一售后工单接口下线(管理后台) + +- 端类型:管理后台 +- 变更类型:新增接口(2)+ 删除接口(统一售后工单 admin 端) +- 关联 Issue:#4250 PR:#4251 #4254 +- 日期:2026-06-23 + +--- + +## ① 接口背景 + +售后体系重构:原"投诉 + 申诉统一售后工单"方向作废,拆为**投诉**与**申诉**两套独立能力。 +- **申诉**:用户对"退款被拒"或"退款金额"不服时发起;申诉记录单独存。管理后台新增**申诉查询**(只读列表 + 详情)。 +- **关键**:申诉**复用退款审批**——用户发起申诉后系统自动建一笔 PENDING 退款申请,管理员在**既有「退款审批」**里复核(通过退款 / 驳回结束),**不再有独立的"申诉审批"接口**。申诉列表用于查看与跟踪。 +- **投诉**:从 `com.hulalv.complaint` 迁入售后域(纯内部移包),**HTTP 路径与字段完全不变**(`/v3/admin/complaint/*`),管理后台无需改动。 +- 原统一售后工单 admin 接口(`/v3/admin/aftersale/ticket*`)**全部下线**。 + +--- + +## ② 变更清单 + +| # | 方法 | 路径 | 类型 | +|---|---|---|---| +| 1 | GET | `/v3/admin/refund/appeal/page` | 🆕 新增(申诉分页查询,只读)| +| 2 | GET | `/v3/admin/refund/appeal/{id}` | 🆕 新增(申诉详情,只读)| +| 3 | ALL | `/v3/admin/aftersale/ticket*` | ❌ 删除(统一售后工单下线,调用返回 404)| + +> 投诉 `/v3/admin/complaint/page`、`/v3/admin/complaint/{id}` **无变化**(仅后端移包,路径/入参/出参不变),不在本次变更内。 + +统一响应包装 `Result`:`{ code, message, data, success }`,`code=200` 为成功。 + +--- + +## ③ 接口详情 + +### 1. 申诉分页查询 `GET /v3/admin/refund/appeal/page` +管理后台查申诉列表(**只读**),每条关联展示两笔退款:来源退款(被申诉的原退款)+ 申诉触发的退款(申诉建单自动生成、走退款审批的那笔)。 + +### 2. 申诉详情 `GET /v3/admin/refund/appeal/{id}` +单条申诉详情。 + +> 管理后台**无申诉审批接口**:申诉触发的退款在「退款审批」列表里复核(即对那笔退款做通过/驳回)。 + +--- + +## ④ 入参 + +### 接口1 page(query 参数,登录态 adminId 由网关注入) +| 参数 | 类型 | 必填 | 说明 | +|---|---|---|---| +| page | int | 否 | 页码(从 1 开始),默认 1 | +| pageSize | int | 否 | 每页条数,默认 20 | +| orderId | long | 否 | 订单 ID 精确匹配 | +| appealType | string | 否 | 申诉类型:`REFUND_REJECTED` / `REFUND_AMOUNT_DISPUTE` | +| appealStatus | string | 否 | 申诉状态:`PENDING` / `REJECTED` / `REFUNDED` / `WITHDRAWN` | +| applicantName | string | 否 | 申请人姓名(模糊匹配)| +| createTimeStart | datetime | 否 | 创建时间起 | +| createTimeEnd | datetime | 否 | 创建时间止 | + +### 接口2 detail +| 参数 | 位置 | 类型 | 说明 | +|---|---|---|---| +| id | path | long | 申诉 ID | + +--- + +## ⑤ 出参 + +### 接口1 page `Result>`;接口2 detail `Result` +`PageResult`:`{ records[], total, page, pageSize }`。`AppealAdminRespVO`: + +| 字段 | 类型 | 说明 | +|---|---|---| +| id | string(Long) | 申诉 ID | +| orderId | string(Long) | 订单 ID | +| refundApplicationId | string(Long) | 来源退款申请 ID | +| appealType | string | 申诉类型(枚举值,见⑥)| +| appealTypeLabel | string | 申诉类型中文名 | +| appealReason | string | 申诉理由 | +| appealAmount | string(decimal) | 申诉退款金额 | +| appealStatus | string | 申诉状态(枚举值,见⑥)| +| appealStatusLabel | string | 申诉状态中文名 | +| linkedRefundId | string(Long) | 申诉触发的退款申请 ID | +| auditStatus | string | 凭证机审状态(PENDING/APPROVED/MANUAL_REVIEW/REJECTED)| +| applicantType | string | 申请人类型(USER/ADMIN/SYSTEM)| +| applicantId | string(Long) | 申请人 ID | +| applicantName | string | 申请人姓名 | +| reviewedAt | datetime | 审批完成时间(可空)| +| createTime | datetime | 创建时间 | +| updateTime | datetime | 更新时间 | +| sourceRefund | object | 来源退款信息(被申诉的原退款),见下 | +| triggeredRefund | object | 申诉触发的退款信息(自动生成、走退款审批的退款),见下 | + +`sourceRefund` / `triggeredRefund` 结构(关联退款信息): +| 字段 | 类型 | 说明 | +|---|---|---| +| refundApplicationId | string(Long) | 退款申请 ID | +| status | string | 退款状态(PENDING/APPROVED/REJECTED/REFUNDING/REFUNDED/CANCELLED/ABNORMAL)| +| actualAmount | string(decimal) | 实际退款金额(可空)| + +--- + +## ⑥ 枚举 / 数据字典 + +**申诉类型 appealType**: +| 值 | 含义 | +|---|---| +| REFUND_REJECTED | 退款被拒(原退款被驳回后申诉)| +| REFUND_AMOUNT_DISPUTE | 退款金额异议(已退款但金额有异议,求补差)| + +**申诉状态 appealStatus**: +| 值 | 含义 | +|---|---| +| PENDING | 审批中(申诉触发的退款待退款审批)| +| REJECTED | 已驳回(退款审批驳回)| +| REFUNDED | 退款到账(申诉成功)| +| WITHDRAWN | 已撤回 | + +--- + +## ⑦ 错误码(段位 530600-530699) + +| code | message | +|---|---| +| 530601 | 申诉必须关联一笔退款申请 | +| 530602 | 关联的退款申请不存在 | +| 530603 | 退款申请当前状态不满足申诉条件 | +| 530604 | 该退款申请已有处理中的申诉,请勿重复提交 | +| 530605 | 申诉退款金额超出可退余额 | +| 530606 | 申诉记录不存在 | +| 530607 | 无权操作此申诉 | +| 530608 | 当前申诉状态不允许撤回,仅待审核状态可撤回 | +| 530609 | 申诉类型无效 | + +> 查询类接口(page/detail)正常只返 200;上述错误码主要由 C 端发起/撤回触发,管理后台展示用。 + +--- + +## ⑧ 示例 + +### 典型:申诉分页 +请求 `GET /v3/admin/refund/appeal/page?page=1&pageSize=10&appealStatus=PENDING`,响应(节选一项): +```json +{ "code":200, "success":true, "data": { "total":1, "page":1, "pageSize":10, "records":[ + { "id":"40001", "orderId":"10001", "refundApplicationId":"20001", + "appealType":"REFUND_REJECTED", "appealTypeLabel":"退款被拒", + "appealStatus":"PENDING", "appealStatusLabel":"审批中", "appealAmount":"300.00", + "linkedRefundId":"20009", "auditStatus":"APPROVED", "applicantName":"孙磊", + "sourceRefund": { "refundApplicationId":"20001", "status":"REJECTED", "actualAmount":null }, + "triggeredRefund": { "refundApplicationId":"20009", "status":"PENDING", "actualAmount":null } } +] } } +``` + +### 典型:申诉详情 +请求 `GET /v3/admin/refund/appeal/40001` → 返回上表单条 `AppealAdminRespVO` 全字段。 + +### 异常:调用已下线的工单接口 +请求 `GET /v3/admin/aftersale/ticket/page`(旧统一售后工单接口): +```json +{ "code":404, "message":"Not Found" } +``` + +--- + +## ⑨ 业务边界 + +- 管理后台**无申诉审批动作**:要处理申诉,去【退款审批】对"申诉触发的退款"(triggeredRefund / linkedRefundId)做通过/驳回。 +- 申诉列表 `triggeredRefund` 展示这笔退款的审批/到账状态,便于跟踪。 +- 申诉/投诉任一活跃 → 订单进「售后中」(订单列表「售后」Tab);都终结后回切。 + +--- + +## ⑩ 修改前后对比 + +| | 修改前 | 修改后 | +|---|---|---| +| 申诉列表 | 统一售后工单 `/v3/admin/aftersale/ticket/page`(category=APPEAL)| `/v3/admin/refund/appeal/page` | +| 申诉详情 | `/v3/admin/aftersale/ticket/{id}` | `/v3/admin/refund/appeal/{id}` | +| 申诉审批 | 工单处置(process/resolve)| 无独立审批,走退款审批 | +| 投诉 | `/v3/admin/complaint/*` | **不变**(仅后端移包)| + +--- + +## ⑪ 影响评估 / 回滚 + +- **破坏性**:`/v3/admin/aftersale/ticket*` 已删,调用返回 404,管理后台涉及"售后工单/申诉"的页面**必须切到新申诉接口**,并把申诉的处理引导到「退款审批」。 +- 投诉接口无变化(移包对前端透明)。 +- 回滚:后端回滚 PR #4251 #4254。 + +--- + +## ⑫ 注意事项 + +- 金额字段(appealAmount / actualAmount)均为**字符串**,前端按字符串处理防精度丢失。 +- Long 型 ID 均字符串化返回。 +- 申诉为只读查询,无新增/编辑/审批写接口。 + +--- + +## ⑬ 关联 / 联系人 + +- Issue:https://git.1814.love:8443/wx/HL/issues/4250 +- PR:https://git.1814.love:8443/wx/HL/pulls/4251 ・ https://git.1814.love:8443/wx/HL/pulls/4254 +- 后端负责人:腰苏图 +- 已部署测试服并网关实调验证通过(申诉接口 200 / 投诉接口 200 / 工单接口 404)。