文件
hl-api-changelog/changelogs-v2/2026-09/20_8005_退单户候选列表与提交前预览-新增接口-管理后台.md
T

15 KiB
原始文件 Blame 文件历史

schema, ticket, title, consumer, author, change_type, backend_status, gateway_status, frontend_status, frontend_owner, frontend_ref, target_release, verified_at, status_note, updated_at, base
schema ticket title consumer author change_type backend_status gateway_status frontend_status frontend_owner frontend_ref target_release verified_at status_note updated_at base
hl-changelog/v2 8005 退单户候选列表 GB-ADM-070b 与提交前预览 GB-ADM-070c admin jw(GIT) 新增接口 deployed verified verified mmg 0ab85a7e31452d16483b718b6449d0534c8ddb02 2026-09-20 团期「退单户」弹窗两个新端点:候选下拉 GET .../{groupBatchId}/withdraw-candidates 每行给「联系人·团号·订单号·已付金额」并只返回当前可退的户(排除已取消/已完成/出行中,以及已提交待审的户);摘要条 GET .../{groupBatchId}/sub-order/{orderId}/withdraw-preview 在点「提交退团审核」之前给出「待退多少」,零写入,与提交响应逐分一致。A3 /orders 与 GB-ADM-070 提交端点不变。后端已合并 dev-v3(0139aebe4)并部署 TEST,网关实测 AC-1~AC-10 全通过。前端待办:下拉改调新端点并展示四段;选中一户后调预览端点渲染摘要条(不要用 /v3/admin/order/{id}/cancel-preview,那个恒按退改政策算,团期早期阶段会少显示)。注意人数字段是 participantCount(与 A3、GB-ADM-072/073 同名),不是 peopleCount。前端已交付(hl-ui v2.1 @ 0ab85a7e):下拉改调 withdraw-candidates 按四段渲染(teamNo null 省略团号段、customerName null 兜「未命名」);选中一户即调 withdraw-preview 渲染摘要条(FULL_DEPOSIT 显「待退定金」/POLICY 显「预计退款」,同行亮已付避免误读订金基数,warnings 逐条渲染,快速切换选中户有竞态防护);人数取 participantCount;未使用 cancel-preview。新建弹窗 spec 7/7,scoped checkpoint 全绿。 2026-09-20 dev-v3

order-v3: 退单户候选列表与提交前预览

存放目录: changelogs-v2/{YYYY-MM}/(管理后台,二期 order-v3)

服务: hl-order-service-v3 (端口 8086) PR: #8010 Issue: #8005 日期: 2026-09-20 影响范围: 管理后台「团期订单 → 团期详情 → 退单户」弹窗


⚠️ 关键变化

  1. 新增候选下拉端点,每行给四段:订单联系人 · 团号 · 订单号 · 已付金额。原先前端拿 A3 /orders 喂下拉,那是带出行人/需求明细的重装配分页接口,且没有可退性过滤。
  2. 新增提交前预览端点,在点「提交退团审核」之前就能给出「待退定金 ¥11,860」。原先唯一算这个数的入口是提交端点本身(写方法、会建待审申请单)。
  3. 候选只返回当前可退的户:已取消 / 已完成 / 出行中的户,以及已提交退单待审的户,不再出现在下拉里。
  4. 人数字段是 participantCount,与 A3 子订单项、GB-ADM-072/073 同名。

一、背景

退单弹窗的下拉每行只显示「未命名 · HL20260920105808925」——兜底文案加一串订单号,运营无法判断要退的是哪一户、退了要退多少钱。

后端其实一直在返回姓名与已付金额(A3 的 customerName / paidAmount),「未命名」是前端兜底文案;但后端确有三个缺口:候选集没有可退性过滤(已提交待审的户能被重复选中,提交端才靠 589529 兜底)、联系人姓名零回落、以及提交前拿不到预计退款额。本单补前两个缺口并新开预览端点,A3 与提交端点均不动。


二、变更接口清单

# 接口 方法 路径 变更类型 说明
1 退单户候选列表 GET /v3/admin/order/group-batch/{groupBatchId}/withdraw-candidates 新增 下拉候选行:联系人/团号/订单号/已付金额 + 人数 + 支付状态中文名
2 退单预览 GET /v3/admin/order/group-batch/{groupBatchId}/sub-order/{orderId}/withdraw-preview 新增 提交前给两个金额与退改政策,零写入

三、接口详情

1. 退单户候选列表 GET /v3/admin/order/group-batch/{groupBatchId}/withdraw-candidates

VO: Result<List<WithdrawCandidateVO>>

使用场景

「退单户」弹窗的「选择要退的子订单」下拉。前端按 customerName · teamNo · orderNo · 已付 ¥paidAmount 渲染每一行;teamNo 为 null 时省略团号那一段,该行仍要展示。

入参

字段 位置 类型 必填 约束 说明
groupBatchId Path Long 是 团期主订单 ID 团期不存在返 589500

出参

字段 类型 说明
orderId String 子订单 ID(Long 序列化为字符串,避免精度丢失)
orderNo String 订单号,HL + 17 位,创单即生成、永不变
teamNo String 团号,形如 26-3627。订金支付成功后才生成,未付订金为 null
customerName String 订单联系人。order_main.customer_name 为空时回落首位出行人姓名;仍为空返 null(前端自行兜文案,后端不返「未命名」)
participantCount Integer 该户人数(成人+儿童+小童+婴儿)。与 A3、GB-ADM-072/073 同名,不是 peopleCount
paidAmount BigDecimal 该户已付(毛累计,含订金+尾款,退款不回减),与 GB-ADM-070 提交响应同源
payStatusName String 支付状态中文名:未支付 / 已付定金 / 已付全款

请求示例

GET /v3/admin/order/group-batch/2101506167098511362/withdraw-candidates
Authorization: Bearer <token>

响应示例

(测试服真实响应,2026-09-20;团期「jw测试1期」5 户,其中 2 户未付订金)

{
  "code": 200,
  "message": "成功",
  "data": [
    {
      "orderId": "2101506167043985410",
      "orderNo": "HL20260920105808925",
      "teamNo": "26-3627",
      "customerName": "张三",
      "participantCount": 6,
      "paidAmount": 2000.00,
      "payStatusName": "已付定金"
    },
    {
      "orderId": "2101507603395973121",
      "orderNo": "HL20260920110351387",
      "teamNo": null,
      "customerName": "晓辉",
      "participantCount": 2,
      "paidAmount": 0.00,
      "payStatusName": "未支付"
    }
  ],
  "success": true
}

空数据 / 降级响应

团期下没有可退的户(全部已取消/已完成/出行中,或全部已提交待审)时返回空数组,不是 null:

{ "code": 200, "message": "成功", "data": [], "success": true }

错误响应

{ "code": 589507, "message": "无操作权限(当前角色未授予团期权限,或该团期不在您名下)", "data": null }
code 触发条件
589500 团期不存在(含已软删)
589507 没有 group-batch:view 权限
401 未登录(网关拦截)

业务边界

  • 只读,零副作用。
  • 只返回订单状态 ∈ {PENDING_PAY,CUSTOMIZING,PENDING_DEPARTURE} 且没有在途(PENDING)退单申请的户。
  • 未付订金的户不排除:teamNo 为 null、paidAmount 为 0.00 照常下发。
  • 排序与 A3 一致(按子订单 ID 升序)。
  • 该户一旦提交退单申请,立即从本列表消失;申请被驳回后重新出现。

2. 退单预览 GET /v3/admin/order/group-batch/{groupBatchId}/sub-order/{orderId}/withdraw-preview

VO: Result<WithdrawSubOrderRespVO>(与 GB-ADM-070 提交响应同构,仅 approvalId 为 null)

使用场景

下拉里选中一户后、点「提交退团审核」之前,渲染摘要条「退款户:陈昊 · 2 人 · 定制师 王浩 · 待退定金 ¥11,860」。联系人与人数取候选行,定制师与两个金额取本端点。

入参

字段 位置 类型 必填 约束 说明
groupBatchId Path Long 是 团期主订单 ID 团期不存在返 589500
orderId Path Long 是 子订单 ID 不属于该团期返 589502

出参

字段 类型 说明
approvalId String 恒为 null——尚未建单,本端点不写库
paidAmount BigDecimal 该户已付
estimatedRefundAmount BigDecimal 预计退款额。FULL_DEPOSIT 模式下基数是订金应付额(不是已付额)
refundMode String FULL_DEPOSIT(招募中/资源准备中全退定金)/ POLICY(物资准备中/待出发按退改政策阶梯扣)
refundPolicy Object 退改政策明细,仅 POLICY 模式给,否则 null
consultantName String 该户定制师姓名(信息项,不是审批人)
warnings Array 非阻断提示,如满团提示、订金为 0 提示;无提示时为空数组

请求示例

GET /v3/admin/order/group-batch/2101506167098511362/sub-order/2101506167043985410/withdraw-preview
Authorization: Bearer <token>

响应示例

(测试服真实响应,2026-09-20;团期招募中 → FULL_DEPOSIT,该户已付 2000、订金应付 9000)

{
  "code": 200,
  "message": "成功",
  "data": {
    "approvalId": null,
    "paidAmount": 2000.00,
    "estimatedRefundAmount": 9000.00,
    "refundMode": "FULL_DEPOSIT",
    "refundPolicy": null,
    "consultantName": "金卫",
    "warnings": []
  },
  "success": true
}

空数据 / 降级响应

POLICY 模式下退改政策取不到时 refundPolicy 为 null,两个金额照常返回;warnings 无提示时是空数组而非 null。

{
  "code": 200,
  "message": "成功",
  "data": {
    "approvalId": null,
    "paidAmount": 500.00,
    "estimatedRefundAmount": 500.00,
    "refundMode": "POLICY",
    "refundPolicy": null,
    "consultantName": null,
    "warnings": []
  },
  "success": true
}

错误响应

{ "code": 589501, "message": "团期状态不允许当前操作", "data": null }
code 触发条件
589500 团期不存在
589501 团期已到出行中及以后(与提交端点同口径,走售后退款)
589502 该子订单不属于本团期
589507 没有 group-batch:view 权限

业务边界

  • 零写入:不建 PENDING 申请单、不写状态时间线、不动订单/名额/金额。测试服实测调用前后 group_batch_approval 行数不变。
  • 与提交端点走同一套退款模式解析与金额估算,两个金额与提交后逐分一致(FULL_DEPOSIT 与 POLICY 两种模式均已实测对照)。
  • 不判「是否已有在途申请」:已提交待审的户本就不在候选列表里,预览是只读的。
  • 实退以审批通过时按当时团期状态重算的为准;POLICY 下距出发天数每天在变。

四、契约约束与正确调用方式

场景 做法
✅ 渲染退单下拉 调 withdraw-candidates,按 customerName · teamNo · orderNo · 已付 ¥paidAmount 四段渲染
✅ teamNo 为 null 省略团号那一段,该行仍要展示(未付订金的户照样能退)
✅ customerName 为 null 前端自行兜文案(如「未命名」);后端只在真没有姓名时返 null
✅ 渲染摘要条的「待退多少」 调 withdraw-preview
❌ 继续拿 A3 /orders 喂下拉 它没有可退性过滤,已取消户、已提交待审的户都会出现,运营可能重复提交
❌ 用 /v3/admin/order/{id}/cancel-preview 算待退金额 那个恒按退改政策算,团期早期阶段(全退定金)会少显示
❌ 用 peopleCount 取人数 本端点是 participantCount,与 A3、GB-ADM-072/073 一致
❌ 把 estimatedRefundAmount 当最终退款额 实退按审批通过时重算

六、边界行为

  • 团期下无可退户 → data: []。
  • 未付订金户 → teamNo: null、paidAmount: 0.00,仍在候选内。
  • 联系人为空 → 回落首位出行人姓名;出行人也无名或无出行人 → customerName: null。
  • 该户已提交退单待审 → 从候选消失;驳回后重新出现(实测:5 户 → 提交后 4 户 → 驳回后 5 户)。
  • 团期到出行中及以后 → 预览返 589501,与提交端点一致。
  • FULL_DEPOSIT 模式 estimatedRefundAmount 取订金应付额,可能大于 paidAmount(实测已付 2000 / 预计退 9000)。
  • 低权限角色(无 group-batch:view)→ 589507;SUPER_ADMIN / GROUP_BATCH_MANAGER / ADMIN / FINANCE 放行。

七、不影响范围

  • 仅新增两个只读端点,未改任何既有接口的入参、出参与行为。
  • 零影响:
    • A3 GET .../{groupBatchId}/orders(不动,仍带出行人/需求明细)
    • GB-ADM-070 提交退单 POST .../sub-order/{orderId}/withdraw(不动,重复提交仍按 589529 拒)
    • GB-ADM-072/073/074/075 审批列表、详情、通过、驳回
    • 数据库:无表结构变更、无 Flyway
    • 网关:新端点落在既有 /v3/admin/** 通配路由内,无需改路由

八、测试环境已验证

被测版本:hl-order-service-v3 = dev-v3 0139aebe4(2026-09-20 12:53 部署,双实例滚动完成)。取证前确认面板检出 dev-v3 @ 0139aebe4、hl-order-service-v3 与 hl-gateway 均 running;部署前同样两条路径返回业务码 404,可证被测的就是本单代码。网关 https://api.test.1814.love:9443 实测:

AC-1  候选 5 行,四段齐全 + participantCount + payStatusName ✓
AC-2  未付订金 2 户(2101507603395973121 / 2101508527082336258)teamNo=null、paidAmount=0.00,仍在列 ✓
AC-3  customer_name 置空串 → 回落「回落出行人甲」;删出行人 → null;出行人姓名为空格 → null;
      三种情况该户均仍在候选内,响应中「未命名」出现 0 次 ✓(夹具已回滚)
AC-4  对张三提交退单 → 候选 5→4 户、该户消失;驳回后 4→5 户恢复 ✓
AC-5  候选 paidAmount 与 GB-ADM-070 提交响应逐分一致:FULL_DEPOSIT 2000.00=2000.00、POLICY 500.00=500.00 ✓
AC-6  SALES → 589507(candidates 与 preview 均拦);SUPER_ADMIN / GROUP_BATCH_MANAGER / ADMIN / FINANCE → 200 ✓
AC-7  预览 vs 提交 estimatedRefundAmount:FULL_DEPOSIT 9000.00=9000.00、POLICY 500.00=500.00,refundMode 亦一致 ✓
AC-8  预览调用前后 group_batch_approval 行数 55→55 不变;提交后才 56 ✓
AC-9  TRIP_FINISHED 团期:预览 589501、提交 589501,口径一致 ✓
AC-10 提交时传 reason → 审批列表与详情均回读到该原因 ✓
AC-11 团期置 TRAVELLING:预览 / 提交 / 审批通过三处均 589501,且三次调用前后
      审批单总数、该申请状态(PENDING)、团期已报名(5 户/17 人)、订单状态与金额逐项不变 = 零写入 ✓

本地:定向 61/0/0(新增 12 例);order-v3 全量两遍 11453/F1 + 748/F0,唯一失败 MapperBoundaryArchTest.non_refund_not_depend_on_refund_mapper 为 payment 域基线既存(干净 dev-v3 同样失败),与本单无交点。


十、相关文档

  • 关联 Issue: wx/HL#8005
  • 关联 PR: wx/HL#8010
  • 接口文档:docs/group/团期模块接口文档-v2.0.html 已补 GB-ADM-070b / GB-ADM-070c 两节与判权表两行

关联 / 联系人

链接

联系人

  • 后端负责人: @jw
  • 前端负责人: @mmg