46 KiB
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 | 8436 | 团期退单审批 GB-ADM-072~075 放开团期管理员;074 审批通过后退款单不再自动审核,以 PENDING 进退款审批中心人工审;退单详情与团期审批中心列表的 canApprove 按退单专用门判定 | admin | jw(GIT) | 修改接口 | deployed | verified | verified | mmg | 681518ec8cec55f0502fc3bb8622a00a0627e5f6 | v2.1 | 2026-09-27 | PR #8441 已合入 dev-v3(合并提交 c97c0b4ca),2026-09-27 17:25 部署 TEST。五个接口(GB-ADM-072/073/074/075 与团期审批中心列表 GB-ADM-061)的路径、入参、出参结构、错误码与文案全部不变;变的是退单审批人新增团期管理员、canApprove 取值、actualRefundAmount 语义改为应退额,以及 074 通过后退款单停在 PENDING 进退款审批中心、须再调 POST /v3/admin/refund/review 审核才打款。前端需:①退单审批页与团期审批中心页的 isAdmin 整页门禁放行团期管理员,否则团期管理员进不了页面;②退单详情「实退金额」改按应退额展示,最终打款以退款审批中心批复为准;③审批按钮继续只按 canApprove 显隐。两个 nacos 回滚开关缺省均为开。TEST(c97c0b4ca)已验收:团期管理员可列表 / 详情 / 审批通过;FULL_DEPOSIT 退款单以 PENDING 进退款审批中心,calculatedAmount=订金额,人工同意不填金额按订金额落 actualAmount;两个开关置 false 均实测生效并已还原。【2026-09-27 mmg】前端已交付(681518ec):用户拍板两页都放——withdraw/index 与 group-batch-approval/index 整页门禁 isAdmin 扩为 canAccess=isAdmin||isGroupBatchManager;退单详情「实退金额」改「应退金额」+批复为准提示(详情页与 WithdrawApprovalDetailModal 两处),074 成功提示与通过弹窗 alert 补「退款已转退款审批中心待审」;按钮显隐零改(#8253 已按 canApprove)。三 spec 共 18 例全绿,checkpoint 全绿。遗留:团期管理员角色的两页菜单入口需后端 sys_menu 配置。 | 2026-09-27 | dev-v3 |
order-v3: 团期退单审批放开团期管理员 + 批后退款进退款审批中心二审
服务: hl-order-service-v3(端口 8086/8186)
PR: #8441(已合入 dev-v3,合并提交 c97c0b4ca)
Issue: #8436
日期: 2026-09-27
影响范围: 管理后台退单审批页(GB-ADM-072~075)与团期审批中心列表(GB-ADM-061)的审批人范围、按钮显隐,以及退单审批通过后退款的去向
⚠️ 关键变化
🔴 退单审核通过(GB-ADM-074)后不再直接放款。 改前:审批通过即自动审核退款单,退款审批中心的待审列表里看不到这张单。改后:子订单照常取消、名额照常回退,但退款单以 PENDING(待审核)进入退款审批中心,须有人再调 POST /v3/admin/refund/review 审核通过后才打款。
🔴 团期管理员(GROUP_BATCH_MANAGER)可以审批退单。 GB-ADM-072~075 的审批人由 {ADMIN, SUPER_ADMIN} 扩为 {GROUP_BATCH_MANAGER, ADMIN, SUPER_ADMIN},允许自审(提交人与审批人可为同一人)。流团审批不变,团期管理员仍不能批流团。
🟡 canApprove 取值变化:团期管理员调退单详情(073)或团期审批中心列表(061)时,待审退单的 canApprove 由 false 变为 true;流团行仍为 false。
🟡 退单详情 actualRefundAmount 语义变化:它是审批通过时按当时团期状态算出的应退额,最终打款额以退款审批中心的批复为准(审核人可部分同意或驳回)。数值算法没变。
🟢 五个接口的路径、入参、出参结构、错误码与文案全部不变。 589530 文案仍是「仅管理员可处理退单审核」。
⚠️ 前端门禁:hl-ui 退单审批页(src/views/order/withdraw/index.vue)与团期审批中心页(src/views/order/group-batch-approval/index.vue)最外层按 isAdmin 整页门禁,只认 ADMIN / SUPER_ADMIN 角色,团期管理员打开这两页既不渲染也不发请求。后端已放开,页面入口需前端放行。
一、背景
- jw 2026-09-27 定案:团期退单的审批侧由团期管理员处理,允许自审;钱的出口另由退款审批中心把关(二审)。
- 退单是「提交 → 审批」两段(#7100)。本单只改审批侧;提交侧(GB-ADM-070 谁能提交)归 #7608 批 3,本单未改——团期管理员提交退单仍返回
581008。 - 两处放开互相绑定:团期管理员能批退单的前提是退款审批中心还有一道闸。退款审核端点本就拒绝团期管理员(
581008),所以团期管理员批完退单后,钱必须由其他有退款审核权的角色审出去。二审开关一旦关掉,团期管理员的退单审批权随之收回(见「六、边界行为」)。 - 改成人工二审后暴露了一个退款金额问题:订金全额退(
FULL_DEPOSIT)的退款单,退款审批中心展示的应退额(calculatedAmount)原来是政策预览额(已付 × 政策比例),不是订金。以前自动审核时显式传入了订金金额,所以没暴露;改成人工审后,审核人不填金额直接同意就会多退。本单一并修正:此类退款单的calculatedAmount改写为取消时算定的应退额。
二、变更接口清单
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|---|---|---|---|---|---|
| 1 | GB-ADM-072 退单审批分页列表 | GET | /v3/admin/order/group-batch/withdraw/page |
修改(判权) | 放行团期管理员;响应结构与取值不变 |
| 2 | GB-ADM-073 退单申请详情 | GET | /v3/admin/order/group-batch/withdraw/:approvalId |
修改(判权、取值口径) | 放行团期管理员;canApprove 改按退单专用门;actualRefundAmount 语义改为应退额 |
| 3 | GB-ADM-074 退单审核通过 | POST | /v3/admin/order/group-batch/withdraw/:approvalId/approve |
修改(判权、行为) | 放行团期管理员;通过后退款单以 PENDING 进退款审批中心;响应结构不变 |
| 4 | GB-ADM-075 取消退单(驳回) | POST | /v3/admin/order/group-batch/withdraw/:approvalId/reject |
修改(判权) | 放行团期管理员;响应结构与驳回行为不变 |
| 5 | GB-ADM-061 团期审批中心列表 | GET | /v3/admin/order/group-batch/approvals/page |
修改(取值口径) | 退单行 canApprove 改按退单专用门,团期管理员可为 true;判权与结构不变 |
三、接口详情
1. GB-ADM-072 退单审批分页列表 GET /v3/admin/order/group-batch/withdraw/page
VO: WithdrawApprovalListReqVO → Result<PageResult<WithdrawApprovalItemRespVO>>
使用场景
退单审批页主列表,缺省只列待审单。本单起团期管理员也可调用,其余用法不变。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| approvalStatus | Query | String | ❌ | PENDING / APPROVED / REJECTED / ALL |
缺省 PENDING。行为不变 |
| groupBatchId | Query | Long | ❌ | 团期 ID | 行为不变 |
| keyword | Query | String | ❌ | — | 客户姓名 / 订单号模糊。行为不变 |
| createdFrom | Query | String | ❌ | yyyy-MM-dd |
提交时间起。行为不变 |
| createdTo | Query | String | ❌ | yyyy-MM-dd,含当日 |
提交时间止。行为不变 |
| pageNo | Query | Integer | ❌ | 默认 1 | 页码(本接口叫 pageNo,审批中心列表叫 pageNum)。行为不变 |
| pageSize | Query | Integer | ❌ | 默认 20,最大 100 | 行为不变 |
出参
| 字段 | 类型 | 说明 |
|---|---|---|
| data | PageResult<WithdrawApprovalItemRespVO> |
结构完全不变:records / total / page / pageSize |
| records[] | WithdrawApprovalItemRespVO |
字段与取值均不变:approvalId、groupBatchId、batchNo、batchName、batchLabel、productName、departDate、orderId、teamNo、orderNo、customerName、customerPhoneMasked、participantCount、affectedOrderCount、paidAmount、estimatedRefundAmount、refundMode、refundModeName、reason、applicantName、approvalStatus、approvalStatusName、createdAt |
请求示例
无请求体。
GET /v3/admin/order/group-batch/withdraw/page?pageNo=1&pageSize=20&keyword=HL20260927163133498 HTTP/1.1
Host: api.test.1814.love
Authorization: Bearer <审批人 token:ADMIN / SUPER_ADMIN / GROUP_BATCH_MANAGER>
响应示例
记录取自 TEST 2026-09-27 实测响应(订单 2,ADMIN 调用);团期管理员调用返回同一结构。
{
"code": 200,
"message": "成功",
"data": {
"records": [
{
"approvalId": "2104127004276359170",
"groupBatchId": "2104126740546949121",
"batchNo": "Q202612292104126714147975170",
"batchName": "#8436-退单审批验收",
"batchLabel": "168",
"productName": "冻干粉发短信给",
"departDate": "2026-12-29",
"orderId": "2104126787711860738",
"teamNo": "26-6441",
"orderNo": "HL20260927163133498",
"customerName": "测试八四三六乙",
"customerPhoneMasked": "138****4362",
"participantCount": 2,
"affectedOrderCount": 1,
"paidAmount": 6000.00,
"estimatedRefundAmount": 1000.00,
"refundMode": "FULL_DEPOSIT",
"refundModeName": "订金全额退",
"reason": "#8436 验收造数:退单审批(订单2)",
"applicantName": "cw_test_8006_x",
"approvalStatus": "PENDING",
"approvalStatusName": "待审批",
"createdAt": "2026-09-27 16:32:25"
}
],
"total": 1,
"page": 1,
"pageSize": 20
},
"traceId": null,
"success": true
}
空数据 / 降级响应
无命中时返回空页:
{
"code": 200,
"message": "成功",
"data": { "records": [], "total": 0, "page": 1, "pageSize": 20 },
"success": true
}
降级:nacos 开关 group-batch.acl.allow.withdraw-approver-group-batch-manager 或 group-batch.withdraw.refund-second-review 任一置 false 时,团期管理员回到改前口径,调本接口返回 589530;ADMIN / SUPER_ADMIN 不受影响。两个开关缺省均为 true。
错误响应
{
"code": 589530,
"message": "仅管理员可处理退单审核",
"data": null,
"traceId": null,
"success": false
}
| 错误码 | 触发条件 | 本单 |
|---|---|---|
| 589530 | 当前角色不在 {ADMIN, SUPER_ADMIN, GROUP_BATCH_MANAGER};或团期管理员处于回滚态;或请求带不出角色 |
放行集合新增团期管理员;码与文案不变 |
| 401 | 缺少有效 Authorization(网关拦截,响应体 code,HTTP 仍为 200) | 不变 |
业务边界
- 放行规则:
ADMIN/SUPER_ADMIN恒放行;GROUP_BATCH_MANAGER在两个开关都开时放行;定制师、财务、房务、车务等仍589530。 - 团期管理员看到的是全部团期的退单,不按「本人负责的团期」过滤——系统里还没有团期与团期管理员的归属关系。
- 本接口不返回
canApprove;按钮显隐以 073 详情为准。
2. GB-ADM-073 退单申请详情 GET /v3/admin/order/group-batch/withdraw/:approvalId
VO: Result<WithdrawApprovalDetailRespVO>(继承 WithdrawApprovalItemRespVO)
使用场景
退单审批页或团期审批中心退单行打开详情;弹窗的「同意 / 取消退单」按钮按 canApprove 显隐,分别调 074 / 075。本单起团期管理员也可调用,且其 canApprove 可为 true。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| approvalId | Path | Long | ✅ | 退单审批单 ID | 须为退单类型,否则 589531。行为不变 |
出参
| 字段 | 类型 | 说明 |
|---|---|---|
| canApprove | Boolean | 取值口径变化:PENDING、过退单审批角色门(本单起含团期管理员)、团期与订单都存在、且团期仍可退团时为 true;恒非 null。团期管理员调用时由改前的拿不到(589530)变为可见且可为 true |
| actualRefundAmount | BigDecimal | 语义变化:审批通过时按当时团期状态算出的应退额(通过后回填,未通过为 null)。本单起退款单进退款审批中心二审,最终打款额以退款审批中心批复为准;数值算法不变 |
| refundApplicationId | Long | 不变,恒为 null(退款单在审批提交后异步建);要找退款单请按 orderId 查退款审批中心 |
| 其余字段 | — | 与 072 records[] 相同的 23 个字段,加 currentEstimatedRefundAmount、currentRefundMode、refundPolicy、consultantName、approvedByName、approvedAt、approveRemark,结构与取值不变 |
请求示例
无请求体。
GET /v3/admin/order/group-batch/withdraw/2104127004276359170 HTTP/1.1
Host: api.test.1814.love
Authorization: Bearer <审批人 token:ADMIN / SUPER_ADMIN / GROUP_BATCH_MANAGER>
响应示例
TEST 2026-09-27 实测响应(订单 2,ADMIN 调用);团期管理员在两个开关都开时调用,返回同一结构且 canApprove 同为 true。
{
"code": 200,
"message": "成功",
"data": {
"approvalId": "2104127004276359170",
"groupBatchId": "2104126740546949121",
"batchNo": "Q202612292104126714147975170",
"batchName": "#8436-退单审批验收",
"batchLabel": "168",
"productName": "冻干粉发短信给",
"departDate": "2026-12-29",
"orderId": "2104126787711860738",
"teamNo": "26-6441",
"orderNo": "HL20260927163133498",
"customerName": "测试八四三六乙",
"customerPhoneMasked": "138****4362",
"participantCount": 2,
"affectedOrderCount": 1,
"paidAmount": 6000.00,
"estimatedRefundAmount": 1000.00,
"refundMode": "FULL_DEPOSIT",
"refundModeName": "订金全额退",
"reason": "#8436 验收造数:退单审批(订单2)",
"applicantName": "cw_test_8006_x",
"approvalStatus": "PENDING",
"approvalStatusName": "待审批",
"createdAt": "2026-09-27 16:32:25",
"currentEstimatedRefundAmount": 1000.00,
"currentRefundMode": "FULL_DEPOSIT",
"refundPolicy": null,
"actualRefundAmount": null,
"consultantName": "admin",
"approvedByName": null,
"approvedAt": null,
"approveRemark": null,
"refundApplicationId": null,
"canApprove": true
},
"traceId": null,
"success": true
}
空数据 / 降级响应
无空态。团期或订单查不到时对应字段为 null、canApprove=false;团期已推进到出行中及以后时 currentEstimatedRefundAmount / currentRefundMode 为 null、canApprove=false(均不变)。
降级:两个开关任一置 false 时,团期管理员调本接口返回 589530(与 072 相同)。
错误响应
{
"code": 589531,
"message": "退单申请不存在",
"data": null,
"traceId": null,
"success": false
}
| 错误码 | 触发条件 | 本单 |
|---|---|---|
| 589530 | 同 072 | 放行集合新增团期管理员;码与文案不变 |
| 589531 | 退单申请不存在 / 已软删 / 非退单类型 | 不变 |
业务边界
canApprove与 074 用同一道判定:详情显示可审批,074 的角色门就一定放行;按钮显隐只看它,不要前端按角色自判。canApprove=true时点同意,仍可能因团期状态刚推进而收到589501,以 074 返回为准(不变)。actualRefundAmount只代表退单审批这一步算出的应退额;实际打款额看退款审批中心该退款单的审核结果。
3. GB-ADM-074 退单审核通过 POST /v3/admin/order/group-batch/withdraw/:approvalId/approve
VO: ApproveWithdrawReqVO → Result<WithdrawApprovalDetailRespVO>
使用场景
审批人点「同意」:取消该户子订单、名额 −1 户 / −N 人、生成退款单。本单起两处变化:团期管理员也可调用;生成的退款单不再自动审核,停在 PENDING 进入退款审批中心,由有退款审核权的角色调 POST /v3/admin/refund/review 审核后才打款。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| approvalId | Path | Long | ✅ | 退单审批单 ID | 行为不变 |
| remark | Body | String | ❌ | ≤512 字;请求体可整体省略 | 批复备注。行为不变 |
出参
| 字段 | 类型 | 说明 |
|---|---|---|
| data | WithdrawApprovalDetailRespVO |
结构完全不变,同 073。通过后 approvalStatus=APPROVED、approvalStatusName=已通过、actualRefundAmount 为应退额、canApprove=false、refundApplicationId 恒 null |
请求示例
POST /v3/admin/order/group-batch/withdraw/2104126999897542657/approve HTTP/1.1
Host: api.test.1814.love
Authorization: Bearer <审批人 token:ADMIN / SUPER_ADMIN / GROUP_BATCH_MANAGER>
Content-Type: application/json
{"remark": "已与客户确认,同意退单"}
响应示例
TEST 2026-09-27 16:33 实测响应(订单 1,ADMIN 调用)。本单未改响应,同一请求改后返回同一结构与取值;差别在响应之外的退款单状态,见「业务边界」。
{
"code": 200,
"message": "成功",
"data": {
"approvalId": "2104126999897542657",
"groupBatchId": "2104126740546949121",
"batchNo": "Q202612292104126714147975170",
"batchName": "#8436-退单审批验收",
"batchLabel": "168",
"productName": "冻干粉发短信给",
"departDate": "2026-12-29",
"orderId": "2104126740412731393",
"teamNo": "26-9318",
"orderNo": "HL20260927163122212",
"customerName": "测试八四三六甲",
"customerPhoneMasked": "138****4361",
"participantCount": 2,
"affectedOrderCount": 1,
"paidAmount": 6000.00,
"estimatedRefundAmount": 1000.00,
"refundMode": "FULL_DEPOSIT",
"refundModeName": "订金全额退",
"reason": "#8436 验收造数:退单审批(订单1)",
"applicantName": "cw_test_8006_x",
"approvalStatus": "APPROVED",
"approvalStatusName": "已通过",
"createdAt": "2026-09-27 16:32:24",
"currentEstimatedRefundAmount": 1000.00,
"currentRefundMode": "FULL_DEPOSIT",
"refundPolicy": null,
"actualRefundAmount": 1000.00,
"consultantName": "admin",
"approvedByName": "ha_r1_ad",
"approvedAt": "2026-09-27 16:33:16",
"approveRemark": "#8436 改前证据:旧代码 074 审批通过",
"refundApplicationId": null,
"canApprove": false
},
"traceId": null,
"success": true
}
空数据 / 降级响应
无空态。应退额为 0 的退单不建退款单,actualRefundAmount=0.00(不变)。
降级:
group-batch.withdraw.refund-second-review置false:退款单回到改前行为,建单即自动审核通过、不进退款审批中心待审列表,退款单的calculatedAmount也回到政策预览额(改前口径),实退金额仍按取消时算定的金额;同时团期管理员失去退单审批权(072~075 均589530),避免团期管理员一人批完即放款。group-batch.acl.allow.withdraw-approver-group-batch-manager置false:团期管理员调本接口589530;退款二审照常。
错误响应
{
"code": 589532,
"message": "该退单申请已处理,不可重复操作",
"data": null,
"traceId": null,
"success": false
}
| 错误码 | 触发条件 | 本单 |
|---|---|---|
| 589530 | 同 072 | 放行集合新增团期管理员;码与文案不变 |
| 589531 | 退单申请不存在 | 不变 |
| 589532 | 申请已处理;或并发下已被他人处理 | 不变 |
| 589500 | 团期不存在 | 不变 |
| 589501 | 团期状态已不允许退团(出行中及以后) | 不变 |
| 589512 | 子订单不属于该团期 | 不变 |
| 400 | remark 超过 512 字 |
不变 |
业务边界
- 退款单去向:状态
PENDING,出现在退款审批中心待审列表,申请人类型SYSTEM。审核走POST /v3/admin/refund/review;团期管理员调退款审核返回581008「无权查看此订单」——团期管理员能批退单、批不了退款,钱须由其他有退款审核权的角色审出去。 - 退款单应退额(退款审批中心的
calculatedAmount):FULL_DEPOSIT(团期招募中 / 资源准备中)= 订金应付额,与本接口actualRefundAmount一致;POLICY(物资准备中 / 待出发)= 已付 × 政策比例,口径不变。审核人不填approvedAmount直接同意时,按calculatedAmount退。 - 找退款单:本接口响应的
refundApplicationId恒为 null,请按orderId查GET /v3/admin/refund/application/page(可带status=PENDING)。 - 取消原因恰好以「申诉」开头时,退款单的
reasonText前加「取消原因:」,防止被退款域当作申诉单;订单侧的取消原因不变。 - 团期时间线中本步写入的描述由「子订单 #X 退单审核通过,实退 N」改为「子订单 #X 退单审核通过,退款 N 已转退款审批中心待审」;应退为 0 或二审开关关闭时保持原文。
- 允许自审;审批单分别记录提交人与批复人(不变)。
- 并发:同一审批单同时批,只有一个成功,另一个
589532(不变)。
4. GB-ADM-075 取消退单(驳回) POST /v3/admin/order/group-batch/withdraw/:approvalId/reject
VO: RejectWithdrawReqVO → Result<WithdrawApprovalDetailRespVO>
使用场景
审批人点「取消退单」:驳回申请,该户继续留在团期中走原流程。本单起团期管理员也可调用,驳回行为不变。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| approvalId | Path | Long | ✅ | 退单审批单 ID | 行为不变 |
| remark | Body | String | ✅ | 非空白,≤512 字 | 驳回原因。行为不变 |
出参
| 字段 | 类型 | 说明 |
|---|---|---|
| data | WithdrawApprovalDetailRespVO |
结构完全不变,同 073。驳回后 approvalStatus=REJECTED、approvalStatusName=已取消退单,actualRefundAmount / refundApplicationId 为 null,canApprove=false |
请求示例
POST /v3/admin/order/group-batch/withdraw/2104127012929208322/reject HTTP/1.1
Host: api.test.1814.love
Authorization: Bearer <审批人 token:ADMIN / SUPER_ADMIN / GROUP_BATCH_MANAGER>
Content-Type: application/json
{"remark": "客户已改口,继续参团"}
响应示例
TEST 实测(2026-09-27 17:42,ADMIN 驳回造数订单 4 的退单申请):
{
"code": 200,
"message": "成功",
"data": {
"approvalId": "2104127012929208322",
"groupBatchId": "2104126740546949121",
"batchNo": "Q202612292104126714147975170",
"batchName": "#8436-退单审批验收",
"batchLabel": "168",
"productName": "冻干粉发短信给",
"departDate": "2026-12-29",
"orderId": "2104126797589446658",
"teamNo": "26-0687",
"orderNo": "HL20260927163135910",
"customerName": "测试八四三六丁",
"customerPhoneMasked": "138****4364",
"participantCount": 2,
"affectedOrderCount": 1,
"paidAmount": 1000.0,
"estimatedRefundAmount": 1000.0,
"refundMode": "FULL_DEPOSIT",
"refundModeName": "订金全额退",
"reason": "#8436 验收造数:退单审批(订单4)",
"applicantName": "cw_test_8006_x",
"approvalStatus": "REJECTED",
"approvalStatusName": "已取消退单",
"createdAt": "2026-09-27 16:32:27",
"currentEstimatedRefundAmount": 1000.0,
"currentRefundMode": "FULL_DEPOSIT",
"refundPolicy": null,
"actualRefundAmount": null,
"consultantName": "admin",
"approvedByName": "ha_r1_ad",
"approvedAt": "2026-09-27 17:42:34",
"approveRemark": "#8436 验收造数收尾",
"refundApplicationId": null,
"canApprove": false
},
"traceId": null,
"success": true
}
空数据 / 降级响应
无空态。驳回不退款,actualRefundAmount / refundApplicationId 恒 null(不变)。
降级:两个开关任一置 false 时,团期管理员调本接口返回 589530(与 072 相同)。
错误响应
{
"code": 589530,
"message": "仅管理员可处理退单审核",
"data": null,
"traceId": null,
"success": false
}
| 错误码 | 触发条件 | 本单 |
|---|---|---|
| 589530 | 同 072 | 放行集合新增团期管理员;码与文案不变 |
| 589531 | 退单申请不存在 | 不变 |
| 589532 | 申请已处理 | 不变 |
| 400 | remark 为空白或超过 512 字 |
不变 |
业务边界
- 驳回只改审批单状态,订单、名额、钱三项零变动;该户可再次提交退单(不变)。
- 团期管理员可以驳回任一团期的退单(不按团期归属过滤,同 072)。
5. GB-ADM-061 团期审批中心列表 GET /v3/admin/order/group-batch/approvals/page
VO: GroupBatchApprovalListReqVO → Result<PageResult<GroupBatchApprovalItemRespVO>>
使用场景
团期审批中心主列表,一页同时展示流团(DISBAND)与退单户(WITHDRAW)两类申请;前端按每行 canApprove 决定是否显示「同意 / 拒绝」。本单只改退单行 canApprove 的取值口径,判权、入参、出参结构不变。
入参
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|---|---|---|---|---|---|
| bizType | Query | String | ❌ | DISBAND / WITHDRAW |
不传 = 两类都要。行为不变 |
| approvalStatus | Query | String | ❌ | PENDING / APPROVED / REJECTED |
不传 = 全部。行为不变 |
| groupBatchId | Query | Long | ❌ | 团期 ID | 行为不变 |
| batchName | Query | String | ❌ | 空白视为不传 | 团期名称包含匹配;「第N期」/「N」另按期号精确匹配。行为不变 |
| pageNum | Query | Integer | ❌ | ≥1,默认 1 | 行为不变 |
| pageSize | Query | Integer | ❌ | 1–100,默认 20 | 行为不变 |
出参
| 字段 | 类型 | 说明 |
|---|---|---|
| records[].canApprove | Boolean | 取值口径变化:按行类型分门。WITHDRAW 行 = 过退单审批角色门(ADMIN / SUPER_ADMIN,本单起另含两个开关都开时的 GROUP_BATCH_MANAGER)且 PENDING、团期存在且仍可退团;DISBAND 行 = 过流团审批角色门(仍只 ADMIN / SUPER_ADMIN)且其余条件不变。恒非 null |
| records[] 其余字段 | — | 结构与取值不变:approvalId、bizType、bizTypeName、bizTypeText、groupBatchId、batchNo、batchName、batchLabel、approvalStatus、approvalStatusName、orderId、affectedOrderCount、participantCount、estimatedRefundAmount、reason、applicantName、approvedByName、approvedAt、createTime、orderNo、teamNo、customerName、customerPhoneMasked、departDate |
| total / page / pageSize | Long / Integer / Integer | 分页包装,不变;列表字段名是 records |
请求示例
无请求体。
GET /v3/admin/order/group-batch/approvals/page?bizType=WITHDRAW&approvalStatus=PENDING&pageNum=1&pageSize=20 HTTP/1.1
Host: api.test.1814.love
Authorization: Bearer <持 group-batch:view 的账号 token>
响应示例
示例:字段结构与 TEST 实测一致(团期管理员按团期 2104126740546949121 过滤调用,code 200);为展示待审行,这一行的审批状态与 canApprove 按造数订单 2 审批前的状态示意。实测对照:全表唯一一条待审退单行,团期管理员看到 canApprove=true、定制师看到 false;TEST 上没有待审的流团行,团期管理员对流团行恒为 false 由单测覆盖。
{
"code": 200,
"message": "成功",
"data": {
"records": [
{
"approvalId": "2104127004276359170",
"bizType": "WITHDRAW",
"bizTypeName": "退单户",
"bizTypeText": "退单户",
"groupBatchId": "2104126740546949121",
"batchNo": "Q202612292104126714147975170",
"batchName": "#8436-退单审批验收",
"batchLabel": "168",
"approvalStatus": "PENDING",
"approvalStatusName": "待审批",
"orderId": "2104126787711860738",
"affectedOrderCount": 1,
"participantCount": 2,
"estimatedRefundAmount": 1000.00,
"reason": "#8436 验收造数:退单审批(订单2)",
"applicantName": "cw_test_8006_x",
"approvedByName": null,
"approvedAt": null,
"canApprove": true,
"createTime": "2026-09-27 16:32:25",
"orderNo": "HL20260927163133498",
"teamNo": "26-6441",
"customerName": "测试八四三六乙",
"customerPhoneMasked": "138****4362",
"departDate": "2026-12-29"
}
],
"total": 1,
"page": 1,
"pageSize": 20
},
"traceId": null,
"success": true
}
空数据 / 降级响应
无命中时返回空页:
{
"code": 200,
"message": "成功",
"data": { "records": [], "total": 0, "page": 1, "pageSize": 20 },
"success": true
}
降级:两个开关任一置 false 时,团期管理员看到的退单行 canApprove 回到 false;列表本身照常返回(本接口判权不读这两个开关)。
错误响应
{
"code": 589507,
"message": "无操作权限(当前角色未授予团期权限,或该团期不在您名下)",
"data": null,
"traceId": null,
"success": false
}
| 错误码 | 触发条件 | 本单 |
|---|---|---|
| 589507 | 当前角色无 group-batch:view |
不变 |
| 400 | pageNum < 1 或 pageSize 不在 1–100 |
不变 |
| 401 | 缺少有效 Authorization(响应体 code,HTTP 仍为 200) | 不变 |
业务边界
- 判权不变:本接口走
group-batch:view权限码(团期管理员持有),与审批端点的角色门不是同一道门。 - 同一页里团期管理员看到的是:退单行可审批(
canApprove=true,PENDING 且团期仍可退团时),流团行不可审批(canApprove=false)。前端按行读canApprove即可,不需要区分角色。 - 角色门按请求算一次、按行类型取用,与行数无关(不变)。
- 已处理(APPROVED / REJECTED)行
canApprove恒false(不变)。
四、契约约束与正确调用方式
按钮显隐
| 场景 | 做法 |
|---|---|
| ✅ 同意 / 驳回按钮 | 只按 073 详情或 061 行上的 canApprove === true 显示 |
| ❌ 前端按角色自判 | 会漏掉团期管理员,或给团期管理员的流团行错显按钮(点下去 589547 / 589530) |
✅ 589530 提示 |
直接透出 message;文案仍是「仅管理员可处理退单审核」,本单未改,不要按文案推断角色 |
审批通过 ≠ 已退款
| 步骤 | 接口 | 说明 |
|---|---|---|
| ① 批退单 | POST /v3/admin/order/group-batch/withdraw/:approvalId/approve |
子订单取消、名额回退、建退款单(PENDING) |
| ② 找退款单 | GET /v3/admin/refund/application/page?orderId=<子订单ID>&status=PENDING |
074 响应的 refundApplicationId 恒为 null,只能按 orderId 查 |
| ③ 审退款 | POST /v3/admin/refund/review |
body 例:{"applicationId": "<退款单ID>", "decision": "APPROVED"};不传 approvedAmount 时按 calculatedAmount 退;团期管理员调用 581008 |
payload 对照
| 场景 | payload |
|---|---|
| ✅ 074 不带备注 | 无请求体 |
| ✅ 074 带备注 | {"remark": "已与客户确认,同意退单"} |
| ✅ 075 驳回 | {"remark": "客户已改口,继续参团"} |
| ❌ 075 不填原因 | {} 或 {"remark": " "} → 400 |
五、数据库行为
只写外部可观察的结果。零 DDL、零 Flyway、零数据迁移。
| 接口 / 对象 | 改前 | 改后 |
|---|---|---|
| 074 子订单 | 取消 | 不变 |
| 074 团期名额 | −1 户 / −N 人 | 不变 |
| 074 退单审批单 | 置已通过,回填批复人与应退额 | 不变 |
| 074 退款单状态 | 建单即自动审核通过,自动审核记录的审核人为 074 审批人 | 建单停在 PENDING,无自动审核记录 |
074 退款单应退额(FULL_DEPOSIT) |
政策预览额(已付 × 政策比例) | 取消时算定的订金应付额 |
074 退款单应退额(POLICY) |
已付 × 政策比例 | 不变 |
| 074 应退为 0 | 不建退款单 | 不变 |
| 072 / 073 / 075 / 061 | — | 写入行为无变化 |
存量:本单前已自动审核通过的退款单不回溯。
六、边界行为
- 未登录 → 401(网关拦截,不变)。
- 有请求但角色头缺失 →
589530(fail-closed,不变)。 - 团期推进到出行中及以后 → 074 返回
589501,073 / 061canApprove=false(不变)。 - 应退为 0 → 只取消订单、不建退款单,时间线写「实退 0.00」(不变)。
- 团期招募中 / 资源准备中(FULL_DEPOSIT)而该户已付少于订金(含已付 0)→ 应退额仍按订金算(存量口径,本单未改),退款单进审批中心后人工同意会被
530404「审核同意金额超出可退额度」拦下,需按实付改金额或驳回。 - 回滚开关(nacos,缺省均为
true,热刷新):
| 开关 | 置 false 的效果 |
|---|---|
group-batch.acl.allow.withdraw-approver-group-batch-manager |
团期管理员调 072~075 回到 589530;073 / 061 退单行对团期管理员的 canApprove 回到 false;退款二审照常 |
group-batch.withdraw.refund-second-review |
074 通过后退款单回到建单即自动审核通过,calculatedAmount 回到政策预览额(改前口径),实退仍按取消时算定的金额;同时团期管理员失去退单审批权,效果同上一行 |
两个开关只影响团期管理员这一条放行和退款去向;ADMIN / SUPER_ADMIN 恒放行,定制师、财务等恒拒,流团审批恒不放团期管理员,都不读开关。
六.5、枚举 / 数据字典
refundMode(com.hulalv.order.core.enums.OrderRefundMode)
所属字段: WithdrawApprovalItemRespVO.refundMode / WithdrawApprovalDetailRespVO.currentRefundMode | 类型: String
团期退单只会产生下面两个值(由批复时团期状态决定,本单未改):
| 值 | 中文 | 说明 |
|---|---|---|
FULL_DEPOSIT |
订金全额退 | 团期招募中 / 资源准备中;应退 = 订金应付额。本单起退款单应退额与之一致 |
POLICY |
按政策退 | 物资准备中 / 待出发;应退 = 已付 × 退改政策比例 |
六.6、修改前后对比
字段级对比
| 字段 | 改前 | 改后 |
|---|---|---|
073 canApprove(团期管理员调用) |
拿不到详情(589530) |
PENDING 且团期可退团时 true |
061 退单行 canApprove(团期管理员调用) |
恒 false |
PENDING 且团期可退团时 true |
061 流团行 canApprove(团期管理员调用) |
false |
false(不变) |
073 / 074 actualRefundAmount 语义 |
实际退款额 | 应退额,最终以退款审批中心批复为准(数值不变) |
行为级对比
| 行为 | 改前 | 改后 |
|---|---|---|
| 团期管理员调 072~075 | 589530 |
放行(两个开关都开时) |
| 定制师 / 财务 / 房务 / 车务调 072~075 | 589530 |
589530(不变) |
| 074 通过后退款单状态 | 自动审核通过 | PENDING,进退款审批中心待审列表 |
| 074 通过后打款时点 | 自动进入打款流程 | 退款审批中心审核通过之后 |
FULL_DEPOSIT 退款单应退额(已付 6000、订金 1000 的户) |
6000.00(政策预览额) | 1000.00(订金应付额) |
| 团期时间线审批通过那条描述 | 「退单审核通过,实退 N」 | 「退单审核通过,退款 N 已转退款审批中心待审」 |
六.7、影响评估
- 是否破坏向后兼容: 否。路径、入参、出参结构、错误码与文案全部不变;074 通过后钱不再自动退出是本单有意的行为变化。
- 前端是否必须同步上线: 否。不改前端时,管理员的用法与改前一致(只是退款多一道审核);团期管理员被页面
isAdmin门禁挡在页外,用不到新能力。 - 前端 workaround 清理点:
- 退单审批页与团期审批中心页的
isAdmin整页门禁需放行团期管理员;审批中心页里流团行由canApprove=false自然不显示按钮,不需要额外判断。 - 退单详情「实退金额」标签需改按应退额展示,并提示最终以退款审批中心批复为准。
- 074 成功提示可补一句「退款已转退款审批中心」。
- 团期管理员角色的退单审批菜单本单未绑定,需在菜单配置里给该角色挂上两页入口。
- 退单审批页与团期审批中心页的
七、不影响范围
- 仅影响: 退单审批四端点(GB-ADM-072~075)的放行角色,退单详情与审批中心列表的
canApprove,以及 074 通过后退款单的状态与应退额。 - 零影响:
- GB-ADM-070 提交退单:判权不变,团期管理员仍
581008,其余角色需group-batch:withdraw:submit(#7608 批 3)。 - 流团审批(流团详情、GB-ADM-062 同意 / 拒绝、GB-ADM-060 提交):仍只放
ADMIN/SUPER_ADMIN。 - 退款审批中心各接口(列表、详情、
POST /v3/admin/refund/review):结构与判权不变,只是多出团期退单来的PENDING单。 - C 端取消订单的退款:退款模式固定
POLICY,应退额口径不变;唯一可见变化是取消原因恰以「申诉」开头时退款单reasonText加前缀「取消原因:」。 - 小程序端(
consumer: mp):无接口变化。 - 存量数据:本单前已自动审核的退款单不回溯。
- GB-ADM-070 提交退单:判权不变,团期管理员仍
八、测试环境已验证
环境:TEST,经业务网关 https://api.test.1814.love;身份为自签 token(role + adminId)。TEST 上没有持 FINANCE 角色的真实账号,财务用例为自签 role=FINANCE(审批角色门只认角色头,结论成立)。
8.1 改前(旧字节,2026-09-27 16:26~16:36)
构建身份:部署面板显示 order-v3 为 dev-v3 @ 69046568c(16:21:31 部署,不含本单)。扫运行中两个实例(8086 / 8186)所加载的 jar:本单新增的两个日志标签 GB_WITHDRAW_APPROVER_GBM_DISABLED、GB_WITHDRAW_REFUND_SECOND_REVIEW_OFF 均未命中,同一个类里跨版本稳定的 GB_APPROVAL_ROLE_CLAIM_MISSING 命中,说明未命中是版本旧、不是类没打进 jar。取证前后三次复核,两个进程 pid 不变。
判权对照(072 / 073,审批单为造数订单 2 的待审单):
| 角色(adminId) | 072 列表 | 073 详情 |
|---|---|---|
| CUSTOMIZER(1002) | 589530「仅管理员可处理退单审核」 |
589530 |
| GROUP_BATCH_MANAGER(2102259564525301761) | 589530 |
589530 |
| FINANCE(自签) | 589530 |
589530 |
| ADMIN(2103791504101412865,阳性对照) | 200,命中 4 条待审 | 200,canApprove=true |
074 改前行为(订单 1:已付 6000、订金 1000,团期招募中;审批人 ADMIN ha_r1_ad,提交人为另一 ADMIN 账号):
POST /v3/admin/order/group-batch/withdraw/2104126999897542657/approve
→ 200,approvalStatus=APPROVED,refundMode=FULL_DEPOSIT,actualRefundAmount=1000.00,refundApplicationId=null ✓
GET /v3/admin/refund/application/page?orderId=2104126740412731393&status=PENDING
→ 200,total=0(旧字节下退款单不进待审列表)✓
GET /v3/admin/refund/application/page?orderId=2104126740412731393
→ 200,1 条:status=APPROVED,calculatedAmount=6000.00,actualAmount=1000.00,reviewerNameLast=ha_r1_ad ✓
- 退款单建单后约 1 秒内即由 074 审批人自动审核通过(状态流水 PENDING→APPROVED,操作人为 074 审批人),约 2 分钟后复查仍为已通过、尚无打款记录。
- 应退额错位实证:
calculatedAmount=6000.00是政策预览额(已付 6000 × 政策比例 100%),实际审批金额是订金 1000.00——改成人工二审后,审核人不填金额直接同意就会按 6000 退,这是本单一并修正的问题。 - 团期时间线新增「子订单 #HL20260927163122212 退单审核通过,实退 1000.00」;订单时间线新增取消(CUSTOMIZING→CANCELLED)与系统「退款审核通过 ¥1000.00」两条。
- 名额由 12 人 / 6 户回退为 10 人 / 5 户,团期仍为招募中。
8.2 改后(新字节 c97c0b4ca,2026-09-27 17:27~17:39)
构建身份:部署面板 hl-order-service-v3 <- dev-v3 @ c97c0b4ca(17:25:39)。两个实例(8086 / 8186)加载的 jar 都命中本单两个日志标签;逐 AC 共复核 8 次,两个进程 pid 始终不变,窗口内无人重新部署。
判权(072 / 073,审批单为造数订单 2 的待审单,每种各打 2 次):
| 角色(adminId) | 072 列表 | 073 详情 |
|---|---|---|
| GROUP_BATCH_MANAGER(2102259564525301761) | 200,total=4 | 200,approvalStatus=PENDING,canApprove=true |
| CUSTOMIZER(1002) | 589530「仅管理员可处理退单审核」 |
589530 |
| FINANCE(自签) | 589530 |
589530 |
团期管理员审批通过 + 退款进审批中心(订单 2:已付 6000、订金 1000,团期招募中 → FULL_DEPOSIT):
POST /v3/admin/order/group-batch/withdraw/2104127004276359170/approve (团期管理员)
→ 200,approvalStatus=APPROVED,actualRefundAmount=1000.00,refundApplicationId=null ✓
订单 CUSTOMIZING→CANCELLED,团期名额 10 人 / 5 户 → 8 / 4 ✓
GET /v3/admin/refund/application/page?orderId=2104126787711860738&status=PENDING
→ 200,1 条:status=PENDING,calculatedAmount=1000.00,actualAmount=null ✓(改前同场景 total=0)
POST /v3/admin/refund/review (ADMIN,decision=APPROVED,不填金额)
→ 200,status PENDING→APPROVED,actualAmount=1000.00 ✓(未落成 6000)
| 退款单字段 | 改后(订单 2) | 改前(订单 1,8.1) |
|---|---|---|
| 建单后状态 | PENDING,无审核记录 | APPROVED(074 审批人自动审核) |
| applicant_type / refund_type | SYSTEM / DEPOSIT | SYSTEM / DEPOSIT |
| calculated_amount | 1000.00(取消时算定的订金额) | 6000.00(政策预览额) |
| 人工同意后 actual_amount | 1000.00 | —(自动审核 1000.00) |
- 团期时间线:「子订单 #HL20260927163133498 退单审核通过,退款 1000.00 已转退款审批中心待审」(改前为「实退 1000.00」)。
- 074 / 073 响应:外层 5 个键、
data33 个字段,集合与顺序与改前完全一致;取值差异只在订单号、客户、审批人、时间等造数身份字段。接口文档中actualRefundAmount描述已更新为应退额口径。
自审:ADMIN(2102028348437970945)对订单 5 自己提交(070)并自己审批通过(074),审批单 applicant_id = approved_by_id;退款单 PENDING、calculated_amount=1000.00。
回滚开关(nacos tenant=test hl-order-service-v3-test.yml,发布与还原都带 casMd5,还原后与原文 md5 c2206934960057f70b7173159046dc54 / 7522 字节逐字节一致):
开关置 false |
生效 | 实测 |
|---|---|---|
group-batch.acl.allow.withdraw-approver-group-batch-manager |
发布后约 5.6 秒 | 团期管理员调 072:网关 6/6 与两个实例直连均 589530;两台服务日志均有 GB_WITHDRAW_APPROVER_GBM_DISABLED;还原后约 3.3 秒恢复 200 |
group-batch.withdraw.refund-second-review |
发布后约 4.8 秒 | 团期管理员调 072 同样 589530;ADMIN 审批订单 3 后退款单自动 APPROVED、actual_amount=1000.00、calculated_amount=6000.00(回到改前口径),时间线写「实退 1000.00」,日志有 GB_WITHDRAW_REFUND_SECOND_REVIEW_OFF;还原后约 7.1 秒恢复 |
旁证:招募中已付 0 的户(订单 6):074 通过后退款单 PENDING、paid_amount=0.00、calculated_amount=1000.00;人工同意(不填金额)返回 530404「审核同意金额超出可退额度(已付¥0,已退¥0,本次¥1,000)」,随后驳回,终态 REJECTED。FULL_DEPOSIT 按订金算应退额是存量口径,二审把它拦在了打款之前。
造数:班期 2104126714152169473、团期 2104126740546949121(「#8436-退单审批验收」),子订单 6 张;整个团期无一张退款单执行打款,验收结束后待审的退单申请与退款单均已驳回。
8.3 本地证据
| 项 | 读数 |
|---|---|
| 定向单测(守卫 4 类、退单审批 / 退款 / 流团审批服务、两个审批控制器角色门、退款监听器与建单服务等) | rebase 到 307e9efc7 后 19 类 295 例全绿 |
| order-v3 整模块全量(有 Docker,rebase 前) | 13967 例,失败 10 / 错误 8 / 跳过 7;8 个红类中 7 个在基底 69046568c 单跑同样红、红法一致,1 个为并发锁竞争时序抖动(本分支单跑 10/10 绿),均与本单无关 |
| 应退为 0 的退单 | 单测覆盖:审批通过后时间线写「实退 0.00」、不写转审批中心,监听器不建退款单 |
| 流团审批不放团期管理员 | 单测覆盖:流团审批重载对团期管理员恒拒且不读开关 |
九、相关历史 PR
| PR | Issue | 说明 | 是否仍有效 |
|---|---|---|---|
| — | #7100 | 退单改为「提交 → 管理员审批」两段,审批通过即自动审核退款 | ⚠️ 退款自动审核部分已被本单改为二审 |
| — | #7609 | 审批角色门对缺角色头 fail-closed | ✅ 有效 |
| #8256 / #8260 | #8253 | 退单详情与审批中心列表引入 canApprove |
✅ 有效(本单改其退单行取值口径) |
| #8438 | #7608 | 批 3:退单提交接 group-batch:withdraw:submit |
✅ 有效(提交侧,本单未改) |
| 本 PR #8441 | #8436 | 审批侧放开团期管理员 + 批后退款二审 | ✅ 最新 |
十、相关文档
- 关联 Issue: wx/HL#8436
- 关联 PR: wx/HL#8441
- 同组端点上一版契约:
changelogs-v2/2026-09/24_8253_团期审批中心统一审核补字段与团期名称搜索-修改接口-管理后台.md - 提交侧判权:
changelogs-v2/2026-09/27_7608_团期退团提交与核单定稿判权收口批3-修改接口-管理后台.md
关联 / 联系人
链接
联系人
- 后端负责人: @jw