--- schema: "hl-changelog/v2" ticket: "8253" title: "团期审批中心统一审核:列表与流团/退单两类详情、批复响应补团期名称/期号/出行人数/审核时间/联系人电话/canApprove,列表支持团期名称搜索" consumer: "admin" author: "jw(GIT)" change_type: "修改接口" backend_status: "deployed" gateway_status: "verified" frontend_status: "verified" frontend_owner: "mmg" frontend_ref: "4a5a9728163bc50eb37deb893d2ec4a38aaafe9b" target_release: "v2.1" verified_at: "2026-09-24" status_note: "团期审批中心改为一页统一审核流团与退单户。后端改动全部是纯增出参或可选入参,路径、判权、错误码零变化:GB-ADM-061 审批中心列表新增入参 batchName(团期名称包含匹配,「第N期」/「N」另按期号精确匹配,不匹配 batch_no),出参新增 batchLabel、participantCount、approvedAt、customerPhoneMasked、canApprove;流团详情/提交/同意/拒绝共用的 DisbandApprovalRespVO 新增 batchName、batchLabel、approvalStatusName、participantCount、canApprove;退单列表/详情/同意/拒绝共用的 WithdrawApprovalItemRespVO 新增 batchName、batchLabel、customerPhoneMasked、affectedOrderCount(恒 1),详情另增 canApprove。口径订正两处:审批中心列表 WITHDRAW 行 affectedOrderCount 由 null 改为 1;流团驳回 approvalStatusName 由「已取消退单」改为「已拒绝」(退单户驳回仍为「已取消退单」)。participantCount 为提交时快照,group_batch_approval 新增可空列 participant_count(Flyway V20260924_825,版本 20260924.825),流团批准后子订单全取消仍返回快照。canApprove = PENDING 且过审批端点同一道角色门(当前 ADMIN/SUPER_ADMIN)且团期存在,退单户另要求团期仍可退团。已合并 dev-v3:PR #8256(merge 4f9b6facb)、PR #8260(merge 11dd1e2fb,退单 072/073 补 affectedOrderCount=1)。2026-09-23 在 TEST(dev-v3 含 4f9b6facb)验收:列表 62 行逐行对库零异常、WITHDRAW 19 行 affectedOrderCount=1;名称搜索 6 类用例、四条批复路径、四类角色 canApprove 与审批端点拒绝码、participant_count 快照 4/3/3/1 及批准后仍返回 4 均符合;16:17 部署含 11dd1e2fb 的 dev-v3 后,退单列表 19 行与退单详情的 affectedOrderCount 实测均为 1。2026-09-24 在 TEST(dev-v3 检出 cc70c9ba3)补验退单户团期不可退团格:测试团期临时置 TRAVELLING 后,超管查审批中心列表与退单详情该 PENDING 单 canApprove 均为 false(详情 currentRefundMode 为 null),超管调退单同意返回 589501「团期状态不允许当前操作」,审批行仍 PENDING、订单未取消;团期状态已恢复为 RECRUITING 并回查确认。流团 canApprove 的阶段条件由 #8308 追加,以其 changelog 为准。前端需:退单户行加眼睛图标与详情弹窗;弹窗同意/拒绝按钮接 GB-ADM-074/075;按 canApprove 显隐同意/拒绝按钮;新增列(团期名称、出行人数、审核时间、联系人电话)与团期/订单两类跳转;默认 Tab;金额提示文案;另注意 hl-ui 两个审批页各有 isAdmin 整页门禁(见 #8246 A9)。 | 2026-09-24 mmg 交付(拆 A/B 两交付):A=审批中心统一列表加团期名称搜索框与团期名称/联系人电话/出行人数/审核时间四列,团期号/订单ID列改 renderLinkCell 跳转,WITHDRAW 影响订单数按订正显 1,操作列 WITHDRAW 改眼睛入口接新建 WithdrawApprovalDetailModal(073详情+074/075审批,金额权威值不反算),DISBAND 显隐改 canApprove,scroll-x 1650=列宽合计;B=退单审批页加团期名称/联系人电话两列与详情两项,通过/取消退单显隐改 canApprove,scroll-x 2180=列宽合计;affectedOrderCount 恒1订正仅统一列表消费,退单页不加恒值列;「默认Tab」契约零正文提及,按最小解读保持 bizType=ALL/PENDING 默认筛选;组件 spec 5+页面 spec 4+退单页 spec 3 例全绿" updated_at: "2026-09-24" base: "dev-v3" --- # 团期审批中心统一审核:补字段与团期名称搜索(管理后台) > **服务**: hl-order-service-v3(端口 8086/8186) > **PR**: #8256(merge commit `4f9b6facb`)、#8260(merge commit `11dd1e2fb`) > **Issue**: #8253 > **日期**: 2026-09-23 > **影响范围**: 团期审批中心列表与流团/退单两类详情弹窗、批复响应 --- ## 一、背景 审批中心要在**一页**里统一审核「流团」与「退单户」两类申请:列表要能看团期名称/期号、出行人数、审核时间、 退单户联系人电话,要能按团期名称搜,并且要能直接在本页点「同意 / 拒绝」。 此前接口缺这些字段:列表只有 `batchName`(且流团/退单两类详情没有),没有期号、出行人数、审核时间、电话; 前端也无从判断当前账号能不能批,只能把按钮全摆出来、点了再吃 589530 / 589547。 另有两处口径错误一并订正:列表里退单户行的「影响订单数」返回 `null`(实为一户一单,恒 1); 流团被驳回时状态文案显示「已取消退单」(流团驳回的语义是团期继续招募,应为「已拒绝」)。 「出行人数」必须落**提交时快照**:流团批准后整团子订单全部 `CANCELLED`,读时现算恒为 0。 为此 `group_batch_approval` 新增可空列 `participant_count`,与既有的 `affected_order_count` / `estimated_refund_amount` 同一批户、同一时刻取数。 --- ## 二、变更接口清单 | # | 接口 | 方法 | 路径 | 变更类型 | 说明 | |---|---|---|---|---|---| | 1 | GB-ADM-061 团期审批中心列表 | GET | `/v3/admin/order/group-batch/approvals/page` | 修改接口 | 入参新增 `batchName`;出参新增 `batchLabel` `participantCount` `approvedAt` `customerPhoneMasked` `canApprove`;WITHDRAW 行 `affectedOrderCount` 由 null 改为 1;流团驳回文案改为「已拒绝」 | | 2 | GB-ADM-061 流团申请详情 | GET | `/v3/admin/order/group-batch/disband/{approvalId}` | 修改接口 | 出参新增 `batchName` `batchLabel` `approvalStatusName` `participantCount` `canApprove` | | 3 | GB-ADM-060 提交流团申请 | POST | `/v3/admin/order/group-batch/{groupBatchId}/disband` | 修改接口 | 响应同 `DisbandApprovalRespVO`,随之新增同上字段;提交时写出行人数快照 | | 4 | GB-ADM-062 同意流团 | POST | `/v3/admin/order/group-batch/disband/{approvalId}/approve` | 修改接口 | 响应新增同上字段 | | 5 | GB-ADM-062 拒绝流团 | POST | `/v3/admin/order/group-batch/disband/{approvalId}/reject` | 修改接口 | 响应新增同上字段,`approvalStatusName` 为「已拒绝」 | | 6 | GB-ADM-072 退单审批分页列表 | GET | `/v3/admin/order/group-batch/withdraw/page` | 修改接口 | 出参新增 `batchName` `batchLabel` `customerPhoneMasked` `affectedOrderCount`(恒 1);`participantCount` 改为快照优先 | | 7 | GB-ADM-073 退单申请详情 | GET | `/v3/admin/order/group-batch/withdraw/{approvalId}` | 修改接口 | 同 6,另新增 `canApprove` | | 8 | GB-ADM-074 退单审核通过 | POST | `/v3/admin/order/group-batch/withdraw/{approvalId}/approve` | 修改接口 | 响应随 `WithdrawApprovalDetailRespVO` 新增同 7 的字段 | | 9 | GB-ADM-075 取消退单(驳回) | POST | `/v3/admin/order/group-batch/withdraw/{approvalId}/reject` | 修改接口 | 响应随 `WithdrawApprovalDetailRespVO` 新增同 7 的字段 | > 退单提交 `POST /v3/admin/order/group-batch/{groupBatchId}/sub-order/{orderId}/withdraw`(GB-ADM-070) > 名称、入参、出参、返回值四项均未变,只在提交时多写一列出行人数快照,不列入清单,见「五、数据库行为」。 --- ## 三、接口详情 ### 1. GB-ADM-061 团期审批中心列表 `GET /v3/admin/order/group-batch/approvals/page` **VO**: `GroupBatchApprovalListReqVO` → `PageResult` #### 使用场景 审批中心主列表,一页同时展示流团(DISBAND)与退单户(WITHDRAW)两类申请,支持按类型、状态、团期、团期名称筛选。 前端据 `canApprove` 决定每行是否显示「同意 / 拒绝」按钮。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | bizType | Query | String | 否 | `DISBAND` / `WITHDRAW` | 不传 = 两类都要(既有) | | approvalStatus | Query | String | 否 | `PENDING` / `APPROVED` / `REJECTED` | 不传 = 全部(既有) | | groupBatchId | Query | Long | 否 | 团期 ID | 不传 = 全部(既有) | | batchName | Query | String | 否 | 空白视为不传 | **本次新增**。团期名称搜索:名称包含匹配(`%` `_` 按字面转义);输入形如「第N期」或纯数字「N」时另按期号 `batch_label = N` **精确**匹配(输入 14 不会命中 114 期);**不匹配**团期号 batch_no | | pageNum | Query | Integer | 否 | ≥1,默认 1 | 页码(既有) | | pageSize | Query | Integer | 否 | 1–100,默认 20 | 每页条数(既有) | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | records[].batchLabel | String | **本次新增**。期号,如 `1`。界面「团期名称」列渲染为 `第{batchLabel}期 {batchName}`;团期已软删时 null | | records[].batchName | String | 团期名称(既有字段);团期已软删时 null | | records[].participantCount | Integer | **本次新增**。出行人数:DISBAND = 提交时整团非取消子订单人数合计(成人+儿童+小童+婴儿);WITHDRAW = 该户人数。取数规则见「业务边界」;存量已处理流团无快照时为 null | | records[].approvedAt | LocalDateTime | **本次新增**。审核时间 `yyyy-MM-dd HH:mm:ss`;未批复为 null | | records[].customerPhoneMasked | String | **本次新增**。退单户客户手机(脱敏,3 位 + `****` + 4 位,与订单列表同口径);DISBAND 行恒 null;订单查不到或无手机号时 null | | records[].canApprove | Boolean | **本次新增**。当前账号能否在本页审批此单,恒非 null。定义见「四、契约约束」 | | records[].affectedOrderCount | Integer | 影响子订单户数。DISBAND = 提交时整团户数(既有);**WITHDRAW 由 null 改为恒 1** | | records[].approvalStatusName | String | 审批状态中文名。**流团驳回由「已取消退单」改为「已拒绝」**;退单户驳回仍为「已取消退单」;其余「待审批 / 已通过」不变 | | records[].approvalId / bizType / bizTypeName / bizTypeText / groupBatchId / batchNo / approvalStatus / orderId / estimatedRefundAmount / reason / applicantName / approvedByName / createTime / orderNo / customerName / departDate | — | 既有字段,本次未改 | | total / page / pageSize | Long / Integer / Integer | 分页包装(既有),列表字段名是 `records` | #### 请求示例 ```http GET /v3/admin/order/group-batch/approvals/page?approvalStatus=PENDING&batchName=%E7%AC%AC1%E6%9C%9F&pageNum=1&pageSize=20 HTTP/1.1 Host: api.test.1814.love:9443 Authorization: Bearer ``` #### 响应示例 ```json { "code": 200, "message": "成功", "data": { "records": [ { "approvalId": "2102579024482197505", "bizType": "WITHDRAW", "bizTypeText": "退单户", "bizTypeName": "退单户", "groupBatchId": "2101506167098511362", "batchNo": "Q202609272101502082564407298", "batchName": "jw测试1期", "batchLabel": "1", "approvalStatus": "PENDING", "approvalStatusName": "待审批", "orderId": "2101947902601646081", "affectedOrderCount": 1, "participantCount": 2, "estimatedRefundAmount": 3000.00, "reason": null, "applicantName": "金卫", "approvedByName": null, "approvedAt": null, "canApprove": true, "createTime": "2026-09-23 10:01:18", "orderNo": "HL20260921161326904", "customerName": "秋雅", "customerPhoneMasked": "156****7788", "departDate": "2026-09-27" }, { "approvalId": "2102668636865089537", "bizType": "DISBAND", "bizTypeText": "流团", "bizTypeName": "流团", "groupBatchId": "2102668504199254017", "batchNo": "Q202612132102668472729395201", "batchName": "#8253-流团拒绝 50%_x", "batchLabel": "128", "approvalStatus": "REJECTED", "approvalStatusName": "已拒绝", "orderId": null, "affectedOrderCount": 1, "participantCount": 3, "estimatedRefundAmount": 0.00, "reason": "8253 验收:流团拒绝路径", "applicantName": "admin", "approvedByName": "admin", "approvedAt": "2026-09-23 15:59:30", "canApprove": false, "createTime": "2026-09-23 15:57:23", "orderNo": null, "customerName": null, "customerPhoneMasked": null, "departDate": null } ], "total": 2, "page": 1, "pageSize": 20 } } ``` (两行分别取自 TEST 实测响应;为展示两类行拼在同一页,`total` 按示例行数写。) #### 空数据 / 降级响应 `batchName` 有值但零命中时直接返回空页,**不会**退化成「不筛」返回全表: ```json { "code": 200, "message": "成功", "data": { "records": [], "total": 0, "page": 1, "pageSize": 100 }, "success": true } ``` 挂在已软删团期上的申请单照常返回,但团期侧字段(`batchNo` / `batchName` / `batchLabel`)为 null,`canApprove=false`。 #### 错误响应 ```json { "code": 589507, "message": "无操作权限(当前角色未授予团期权限,或该团期不在您名下)", "data": null, "success": false } ``` | 错误码 | 触发条件 | |---|---| | 589507 | 当前角色无 `group-batch:view`(既有) | | 400 | `pageNum` < 1 或 `pageSize` 不在 1–100(既有) | | 401 | 缺少有效 Authorization 头(响应体 code,HTTP 仍为 200) | #### 业务边界 - 判权不变:仍走 `group-batch:view`,与审批端点(ADMIN/SUPER_ADMIN 角色门)不是同一道门,见「四」已知旁路。 - `canApprove` 按请求算一次角色门后逐行套用;已处理(APPROVED / REJECTED)行恒 false。 - `participantCount`:优先读提交时快照;无快照的存量 PENDING 流团按同口径现算;无快照的已处理流团返回 null;无快照的退单户按该户订单现算(退单只取消订单、不清人数列)。 - `batchName` 与 `groupBatchId` 等其他筛选条件同时传时取交集。 - 本页不展示「当前预估退款」「实退金额」,接口既有的 `estimatedRefundAmount` 字段保留不动。 --- ### 2. GB-ADM-061 流团申请详情 `GET /v3/admin/order/group-batch/disband/{approvalId}` **VO**: `DisbandApprovalRespVO` #### 使用场景 审批中心点开一条流团申请时拉详情弹窗;弹窗「同意 / 拒绝」按钮按 `canApprove` 显隐。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | approvalId | Path | Long | 是 | 审批单 ID | 须为 DISBAND 类型,否则 589545 | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | batchName | String | **本次新增**。团期名称;团期已软删时 null | | batchLabel | String | **本次新增**。期号,渲染为 `第{batchLabel}期 {batchName}`;团期已软删时 null | | approvalStatusName | String | **本次新增**。待审批 / 已通过 / 已拒绝 | | participantCount | Integer | **本次新增**。提交时整团非取消子订单人数合计;批准后仍返回快照;存量无快照时 PENDING 现算、已处理为 null | | canApprove | Boolean | **本次新增**。PENDING 且过审批端点同一道角色门且团期存在;恒非 null。流团 canApprove 的阶段条件由 #8308 追加,以其 changelog 为准 | | approvalId / groupBatchId / batchNo / approvalStatus / reason / affectedOrderCount / estimatedRefundAmount / actualRefundAmount / applicantId / applicantName / ccUserNames / approvedById / approvedByName / approvedAt / approveRemark / createTime | — | 既有字段,本次未改 | #### 请求示例 ```http GET /v3/admin/order/group-batch/disband/2102668636605026306 HTTP/1.1 Host: api.test.1814.love:9443 Authorization: Bearer ``` #### 响应示例 ```json { "code": 200, "message": "成功", "data": { "approvalId": "2102668636605026306", "groupBatchId": "2102668502144028673", "batchNo": "Q202612122102668472460963841", "batchName": "#8253-流团同意", "batchLabel": "126", "approvalStatus": "PENDING", "approvalStatusName": "待审批", "reason": "8253 验收:流团同意路径", "affectedOrderCount": 2, "participantCount": 4, "estimatedRefundAmount": 1500.00, "actualRefundAmount": null, "applicantId": "1001", "applicantName": "admin", "ccUserNames": ["admin"], "approvedById": null, "approvedByName": null, "approvedAt": null, "approveRemark": null, "createTime": "2026-09-23 15:57:23", "canApprove": true }, "success": true } ``` #### 空数据 / 降级响应 无列表空态。团期已软删时:`batchNo` / `batchName` / `batchLabel` 为 null,`canApprove=false`; 存量已处理单无快照时 `participantCount` 为 null。其余字段照常返回。 #### 错误响应 ```json { "code": 589545, "message": "流团申请不存在", "data": null, "success": false } ``` | 错误码 | 触发条件 | |---|---| | 589545 | 审批单不存在 / 已软删 / 不是 DISBAND 类型(既有) | | 589507 | 当前角色无 `group-batch:view`(既有) | #### 业务边界 - 判权仍是 `group-batch:view`;持该权限但非 ADMIN/SUPER_ADMIN 的账号能看详情,但 `canApprove=false`。 - 本单交付时 `canApprove` 不校验团期阶段:团期若已推进到出行中,按钮仍可能显示,点同意由端点返回拒绝码,前端以端点返回为准。流团 canApprove 的阶段条件由 #8308 追加,以其 changelog 为准。 - 只读,无副作用。 --- ### 3. GB-ADM-060 提交流团申请 `POST /v3/admin/order/group-batch/{groupBatchId}/disband` **VO**: `DisbandSubmitReqVO` → `DisbandApprovalRespVO` #### 使用场景 团期详情页「流团」按钮提交申请(语义为提交审批,不立即流团)。响应即新建的审批单,字段同接口 2。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | groupBatchId | Path | Long | 是 | 团期 ID | 既有 | | reason | Body | String | 是 | 非空白,≤512 字 | 流团理由(既有) | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | batchName / batchLabel / approvalStatusName / participantCount / canApprove | — | **本次新增**,含义同接口 2。提交成功时 `approvalStatusName=待审批`,`participantCount` 即本次写入的快照 | | 其余字段 | — | 同接口 2 既有字段,本次未改 | #### 请求示例 ```json { "reason": "8253 验收:流团同意路径" } ``` #### 响应示例 ```json { "code": 200, "message": "成功", "data": { "approvalId": "2102668636605026306", "groupBatchId": "2102668502144028673", "batchNo": "Q202612122102668472460963841", "batchName": "#8253-流团同意", "batchLabel": "126", "approvalStatus": "PENDING", "approvalStatusName": "待审批", "reason": "8253 验收:流团同意路径", "affectedOrderCount": 2, "participantCount": 4, "estimatedRefundAmount": 1500.00, "actualRefundAmount": null, "applicantId": "1001", "applicantName": "admin", "ccUserNames": ["admin"], "approvedById": null, "approvedByName": null, "approvedAt": null, "approveRemark": null, "createTime": "2026-09-23 15:57:23", "canApprove": true }, "success": true } ``` #### 空数据 / 降级响应 团期下无非取消子订单时照常提交:`affectedOrderCount=0`、`participantCount=0`(不是 null)。 #### 错误响应 ```json { "code": 589543, "message": "该团期已有流团申请在审批中,请勿重复提交", "data": null, "success": false } ``` | 错误码 | 触发条件 | |---|---| | 589500 | 团期不存在(既有) | | 589507 | 无 `group-batch:manage`(既有) | | 589543 | 同团期已有在途流团申请(既有) | | 589544 | 团期已出行,不可发起(既有) | | 589554 | 团期下有出行中子订单(既有) | | 400 | `reason` 为空或超长(既有) | #### 业务边界 - 校验顺序与失败语义不变;任何拒绝都不写审批单、不写快照。 - 快照与 `affectedOrderCount`、`estimatedRefundAmount` 取自同一批非取消子订单、同一时刻。 - 响应里 `canApprove` 反映**提交人**自己能否批,不代表审批人。 --- ### 4. GB-ADM-062 同意流团 `POST /v3/admin/order/group-batch/disband/{approvalId}/approve` **VO**: `ApproveDisbandReqVO` → `DisbandApprovalRespVO` #### 使用场景 审批中心列表行或流团详情弹窗点「同意」。批准后执行流团(团期置 CANCELLED、子订单取消、批量退定金)。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | approvalId | Path | Long | 是 | 审批单 ID | 既有 | | remark | Body | String | 否 | ≤512 字;请求体可整体省略 | 批复备注(既有) | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | batchName / batchLabel / approvalStatusName / participantCount / canApprove | — | **本次新增**,含义同接口 2。成功后 `approvalStatusName=已通过`、`canApprove=false`;`participantCount` 返回提交时快照(子订单已全取消也不归零) | | 其余字段 | — | 同接口 2 既有字段,本次未改 | #### 请求示例 ```json { "remark": "8253 验收:本页同意流团" } ``` #### 响应示例 ```json { "code": 200, "message": "成功", "data": { "approvalId": "2102668636605026306", "groupBatchId": "2102668502144028673", "batchNo": "Q202612122102668472460963841", "batchName": "#8253-流团同意", "batchLabel": "126", "approvalStatus": "APPROVED", "approvalStatusName": "已通过", "reason": "8253 验收:流团同意路径", "affectedOrderCount": 2, "participantCount": 4, "estimatedRefundAmount": 1500.00, "actualRefundAmount": 1500.00, "applicantId": "1001", "applicantName": "admin", "ccUserNames": ["admin"], "approvedById": "2102028348437970945", "approvedByName": "cw_test_8006_x", "approvedAt": "2026-09-23 15:59:30", "approveRemark": "8253 验收:本页同意流团", "createTime": "2026-09-23 15:57:23", "canApprove": false }, "success": true } ``` #### 空数据 / 降级响应 无空态。存量无快照的申请单批准后 `participantCount` 为 null(子订单已取消,无法还原)。 #### 错误响应 ```json { "code": 589547, "message": "仅管理员可处理流团审批", "data": null, "success": false } ``` | 错误码 | 触发条件 | |---|---| | 589547 | 当前角色不是 ADMIN/SUPER_ADMIN(既有) | | 589545 | 审批单不存在或非 DISBAND(既有) | | 589546 | 审批单已处理 / 并发下已被他人处理(既有) | | 589500 | 团期不存在(既有) | | 589544 / 589554 | 执行流团时团期已出行 / 有出行中子订单(既有) | #### 业务边界 - 执行语义、幂等(行锁 + CAS)与失败回滚本次未改;本次只改响应字段。 - 按钮显隐看 `canApprove`,但最终以本端点返回为准。 --- ### 5. GB-ADM-062 拒绝流团 `POST /v3/admin/order/group-batch/disband/{approvalId}/reject` **VO**: `RejectDisbandReqVO` → `DisbandApprovalRespVO` #### 使用场景 审批中心列表行或流团详情弹窗点「拒绝」,团期继续正常招募。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | approvalId | Path | Long | 是 | 审批单 ID | 既有 | | remark | Body | String | 是 | 非空白,≤512 字 | 拒绝原因(既有) | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | batchName / batchLabel / approvalStatusName / participantCount / canApprove | — | **本次新增**,含义同接口 2。成功后 `approvalStatusName=已拒绝`、`canApprove=false` | | 其余字段 | — | 同接口 2 既有字段,本次未改 | #### 请求示例 ```json { "remark": "8253 验收:本页拒绝流团" } ``` #### 响应示例 ```json { "code": 200, "message": "成功", "data": { "approvalId": "2102668636865089537", "groupBatchId": "2102668504199254017", "batchNo": "Q202612132102668472729395201", "batchName": "#8253-流团拒绝 50%_x", "batchLabel": "128", "approvalStatus": "REJECTED", "approvalStatusName": "已拒绝", "reason": "8253 验收:流团拒绝路径", "affectedOrderCount": 1, "participantCount": 3, "estimatedRefundAmount": 0.00, "actualRefundAmount": null, "applicantId": "1001", "applicantName": "admin", "ccUserNames": ["admin"], "approvedById": "1001", "approvedByName": "admin", "approvedAt": "2026-09-23 15:59:30", "approveRemark": "8253 验收:本页拒绝流团", "createTime": "2026-09-23 15:57:23", "canApprove": false }, "success": true } ``` #### 空数据 / 降级响应 无空态。`actualRefundAmount` 恒 null(拒绝不退款)。 #### 错误响应 ```json { "code": 589547, "message": "仅管理员可处理流团审批", "data": null, "success": false } ``` | 错误码 | 触发条件 | |---|---| | 589547 | 当前角色不是 ADMIN/SUPER_ADMIN(既有) | | 589545 | 审批单不存在或非 DISBAND(既有) | | 589546 | 审批单已处理(既有) | | 400 | `remark` 为空或超长(既有) | #### 业务边界 - 只改审批单状态,团期、子订单、名额零变化(本次未改)。 - 文案订正:流团驳回的 `approvalStatusName` 为「已拒绝」,不再是「已取消退单」。 --- ### 6. GB-ADM-072 退单审批分页列表 `GET /v3/admin/order/group-batch/withdraw/page` **VO**: `WithdrawApprovalListReqVO` → `PageResult` #### 使用场景 退单专用列表(既有,保留兼容)。与审批中心列表的退单户行同口径补字段。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | 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 | 既有 | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | records[].batchName | String | **本次新增**。团期名称;团期查不到时 null | | records[].batchLabel | String | **本次新增**。期号 | | records[].customerPhoneMasked | String | **本次新增**。客户手机脱敏(3 位 + `****` + 4 位);订单查不到或无手机号时 null | | records[].affectedOrderCount | Integer | **本次新增**。影响子订单户数,退单户一户一单,恒 1 | | records[].participantCount | Integer | 该户人数(既有字段)。**取数改为提交时快照优先**,无快照的存量行按订单现算,数值口径不变 | | 其余字段 | — | 既有字段(approvalId、groupBatchId、batchNo、productName、departDate、orderId、orderNo、customerName、paidAmount、estimatedRefundAmount、refundMode、refundModeName、reason、applicantName、approvalStatus、approvalStatusName、createdAt),本次未改 | #### 请求示例 ```http GET /v3/admin/order/group-batch/withdraw/page?approvalStatus=PENDING&pageNo=1&pageSize=5 HTTP/1.1 Host: api.test.1814.love:9443 Authorization: Bearer ``` #### 响应示例 ```json { "code": 200, "message": "成功", "data": { "records": [ { "approvalId": "2102668636105904130", "groupBatchId": "2102668373412450306", "batchNo": "Q202612112102668347315511298", "batchName": "#8253-退单户同意与拒绝", "batchLabel": "125", "productName": "冻干粉发短信给", "departDate": "2026-12-11", "orderId": "2102668373257261058", "orderNo": "HL20260923155620281", "customerName": "测试八二五三", "customerPhoneMasked": "138****5678", "participantCount": 3, "affectedOrderCount": 1, "paidAmount": 1500.00, "estimatedRefundAmount": 1500.00, "refundMode": "FULL_DEPOSIT", "refundModeName": "订金全额退", "reason": "8253 验收:退单户同意路径", "applicantName": "admin", "approvalStatus": "PENDING", "approvalStatusName": "待审批", "createdAt": "2026-09-23 15:57:23" } ], "total": 1, "page": 1, "pageSize": 5 }, "success": true } ``` #### 空数据 / 降级响应 ```json { "code": 200, "message": "成功", "data": { "records": [], "total": 0, "page": 1, "pageSize": 20 }, "success": true } ``` #### 错误响应 ```json { "code": 589530, "message": "仅管理员可处理退单审核", "data": null, "success": false } ``` | 错误码 | 触发条件 | |---|---| | 589530 | 当前角色不是 ADMIN/SUPER_ADMIN(既有) | #### 业务边界 - 判权不变:仅 ADMIN/SUPER_ADMIN。 - 本接口**不返回** `canApprove`(能调通本接口即已过审批角色门;是否仍可退团请看详情接口 7)。 - `affectedOrderCount` 与审批中心列表 WITHDRAW 行同口径,恒 1。 --- ### 7. GB-ADM-073 退单申请详情 `GET /v3/admin/order/group-batch/withdraw/{approvalId}` **VO**: `WithdrawApprovalDetailRespVO`(继承 `WithdrawApprovalItemRespVO`) #### 使用场景 审批中心退单户行点「眼睛」图标打开详情弹窗;弹窗「同意 / 拒绝」按 `canApprove` 显隐,分别接接口 8 / 9。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | approvalId | Path | Long | 是 | 退单审批单 ID | 须为 WITHDRAW 类型,否则 589531 | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | batchName / batchLabel / customerPhoneMasked / affectedOrderCount | — | **本次新增**,同接口 6 | | participantCount | Integer | 同接口 6(快照优先) | | canApprove | Boolean | **本次新增**。PENDING 且过审批端点同一道角色门、团期与订单都存在、且团期状态仍允许退团(出行中及以后为 false);恒非 null | | currentEstimatedRefundAmount / currentRefundMode / refundPolicy / actualRefundAmount / consultantName / approvedByName / approvedAt / approveRemark / refundApplicationId | — | 既有字段,本次未改 | #### 请求示例 ```http GET /v3/admin/order/group-batch/withdraw/2102668636105904130 HTTP/1.1 Host: api.test.1814.love:9443 Authorization: Bearer ``` #### 响应示例 ```json { "code": 200, "message": "成功", "data": { "approvalId": "2102668636105904130", "groupBatchId": "2102668373412450306", "batchNo": "Q202612112102668347315511298", "batchName": "#8253-退单户同意与拒绝", "batchLabel": "125", "productName": "冻干粉发短信给", "departDate": "2026-12-11", "orderId": "2102668373257261058", "orderNo": "HL20260923155620281", "customerName": "测试八二五三", "customerPhoneMasked": "138****5678", "participantCount": 3, "affectedOrderCount": 1, "paidAmount": 1500.00, "estimatedRefundAmount": 1500.00, "refundMode": "FULL_DEPOSIT", "refundModeName": "订金全额退", "reason": "8253 验收:退单户同意路径", "applicantName": "admin", "approvalStatus": "PENDING", "approvalStatusName": "待审批", "createdAt": "2026-09-23 15:57:23", "currentEstimatedRefundAmount": 1500.00, "currentRefundMode": "FULL_DEPOSIT", "refundPolicy": null, "actualRefundAmount": null, "consultantName": "admin", "approvedByName": null, "approvedAt": null, "approveRemark": null, "refundApplicationId": null, "canApprove": true }, "success": true } ``` #### 空数据 / 降级响应 无空态。团期或订单查不到时对应字段为 null,`canApprove=false`;团期已推进到不可退团的状态时 `currentEstimatedRefundAmount` / `currentRefundMode` 为 null、`canApprove=false`(既有降级行为,本次只新增 `canApprove`)。 #### 错误响应 ```json { "code": 589530, "message": "仅管理员可处理退单审核", "data": null, "success": false } ``` | 错误码 | 触发条件 | |---|---| | 589530 | 当前角色不是 ADMIN/SUPER_ADMIN(既有) | | 589531 | 退单申请不存在 / 已软删 / 非 WITHDRAW(既有) | #### 业务边界 - 判权不变:仅 ADMIN/SUPER_ADMIN;因此能看到本详情的账号角色门恒过,`canApprove=false` 只可能因为非 PENDING、团期/订单缺失或团期已不可退团。 - 本页不展示「当前预估退款」「实退金额」,字段保留不动。 --- ### 8. GB-ADM-074 退单审核通过 `POST /v3/admin/order/group-batch/withdraw/{approvalId}/approve` **VO**: `ApproveWithdrawReqVO` → `WithdrawApprovalDetailRespVO` #### 使用场景 退单详情弹窗或审批中心列表行点「同意」:取消该户订单、名额 −1 户 / −N 人、按批复时团期状态生成退款。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | approvalId | Path | Long | 是 | 退单审批单 ID | 既有 | | remark | Body | String | 否 | ≤512 字;请求体可整体省略 | 批复备注(既有) | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | batchName / batchLabel / customerPhoneMasked / affectedOrderCount / canApprove | — | **本次新增**,同接口 7。成功后 `approvalStatusName=已通过`、`canApprove=false` | | 其余字段 | — | 同接口 7 既有字段,本次未改 | #### 请求示例 ```json { "remark": "8253 验收:本页同意退单" } ``` #### 响应示例 ```json { "code": 200, "message": "成功", "data": { "approvalId": "2102668636105904130", "groupBatchId": "2102668373412450306", "batchNo": "Q202612112102668347315511298", "batchName": "#8253-退单户同意与拒绝", "batchLabel": "125", "productName": "冻干粉发短信给", "departDate": "2026-12-11", "orderId": "2102668373257261058", "orderNo": "HL20260923155620281", "customerName": "测试八二五三", "customerPhoneMasked": "138****5678", "participantCount": 3, "affectedOrderCount": 1, "paidAmount": 1500.00, "estimatedRefundAmount": 1500.00, "refundMode": "FULL_DEPOSIT", "refundModeName": "订金全额退", "reason": "8253 验收:退单户同意路径", "applicantName": "admin", "approvalStatus": "APPROVED", "approvalStatusName": "已通过", "createdAt": "2026-09-23 15:57:23", "currentEstimatedRefundAmount": 1500.00, "currentRefundMode": "FULL_DEPOSIT", "refundPolicy": null, "actualRefundAmount": 1500.00, "consultantName": "admin", "approvedByName": "cw_test_8006_x", "approvedAt": "2026-09-23 15:58:55", "approveRemark": "8253 验收:本页同意退单", "refundApplicationId": null, "canApprove": false }, "success": true } ``` #### 空数据 / 降级响应 无空态。零元退单时 `refundApplicationId` 为 null(既有)。 #### 错误响应 ```json { "code": 589530, "message": "仅管理员可处理退单审核", "data": null, "success": false } ``` | 错误码 | 触发条件 | |---|---| | 589530 | 当前角色不是 ADMIN/SUPER_ADMIN(既有) | | 589531 | 退单申请不存在(既有) | | 589532 | 已处理,不可重复操作(既有) | | 589500 | 团期不存在(既有) | | 589501 | 团期状态已不允许退团(出行中及以后,既有) | #### 业务边界 - 执行语义、金额以批复时重算为准、幂等与回滚均未改;本次只改响应字段。 - `canApprove=true` 时点同意仍可能因团期状态刚变化而收到 589501,以端点返回为准。 --- ### 9. GB-ADM-075 取消退单(驳回) `POST /v3/admin/order/group-batch/withdraw/{approvalId}/reject` **VO**: `RejectWithdrawReqVO` → `WithdrawApprovalDetailRespVO` #### 使用场景 退单详情弹窗或审批中心列表行点「拒绝」:该户继续留在团期,订单 / 名额 / 钱零变动。 #### 入参 | 字段 | 位置 | 类型 | 必填 | 约束 | 说明 | |---|---|---|---|---|---| | approvalId | Path | Long | 是 | 退单审批单 ID | 既有 | | remark | Body | String | 是 | 非空白,≤512 字 | 驳回原因(既有) | #### 出参 | 字段 | 类型 | 说明 | |---|---|---| | batchName / batchLabel / customerPhoneMasked / affectedOrderCount / canApprove | — | **本次新增**,同接口 7。成功后 `approvalStatusName=已取消退单`、`canApprove=false` | | 其余字段 | — | 同接口 7 既有字段,本次未改 | #### 请求示例 ```json { "remark": "8253 验收:本页取消退单" } ``` #### 响应示例 ```json { "code": 200, "message": "成功", "data": { "approvalId": "2102668636365967361", "groupBatchId": "2102668373412450306", "batchNo": "Q202612112102668347315511298", "batchName": "#8253-退单户同意与拒绝", "batchLabel": "125", "productName": "冻干粉发短信给", "departDate": "2026-12-11", "orderId": "2102668407507963905", "orderNo": "HL20260923155628432", "customerName": "测试八二五三乙", "customerPhoneMasked": "139****1234", "participantCount": 1, "affectedOrderCount": 1, "paidAmount": 500.00, "estimatedRefundAmount": 500.00, "refundMode": "FULL_DEPOSIT", "refundModeName": "订金全额退", "reason": "8253 验收:退单户拒绝路径", "applicantName": "admin", "approvalStatus": "REJECTED", "approvalStatusName": "已取消退单", "createdAt": "2026-09-23 15:57:23", "currentEstimatedRefundAmount": 500.00, "currentRefundMode": "FULL_DEPOSIT", "refundPolicy": null, "actualRefundAmount": null, "consultantName": "admin", "approvedByName": "admin", "approvedAt": "2026-09-23 15:58:55", "approveRemark": "8253 验收:本页取消退单", "refundApplicationId": null, "canApprove": false }, "success": true } ``` #### 空数据 / 降级响应 无空态。`actualRefundAmount` / `refundApplicationId` 恒 null(驳回不退款)。 #### 错误响应 ```json { "code": 589532, "message": "该退单申请已处理,不可重复操作", "data": null, "success": false } ``` | 错误码 | 触发条件 | |---|---| | 589530 | 当前角色不是 ADMIN/SUPER_ADMIN(既有) | | 589531 | 退单申请不存在(既有) | | 589532 | 已处理,不可重复操作(既有) | | 400 | `remark` 为空或超长(既有) | #### 业务边界 - 订单、名额、退款零变动(本次未改)。 - 退单户驳回文案保持「已取消退单」,与流团驳回「已拒绝」区分。 --- ## 四、契约约束与正确调用方式 ### `canApprove` 的定义 `canApprove = 审批单为 PENDING && 当前账号过审批端点同一道角色门 && 团期存在 && (退单户:团期状态仍允许退团)` - 角色门与审批端点(062/074/075)**复用同一段判定代码**,当前为 ADMIN / SUPER_ADMIN;#8246 若把审批闸改为权限码,本字段同步改。 - 前端据此**显隐**同意 / 拒绝按钮;按钮点下去的结果仍以端点返回为准(团期状态可能在两次请求之间变化)。 - 本单交付时流团的 `canApprove` 不看团期阶段,团期已出行时同意会收到 589544 / 589554。 - 流团 canApprove 的阶段条件由 #8308 追加,以其 changelog 为准。 ### 团期名称渲染与搜索 | 场景 | 请求 | 结果 | |---|---|---| | ✅ 名称子串 | `batchName=退单户` | 名称包含该子串的团期下的申请 | | ✅ 期号 | `batchName=第14期` 或 `batchName=14` | 期号恰为 14 的团期;`14` 另命中名称含「14」的团期;都**不会**命中 114 期 | | ✅ 含通配符 | `batchName=%_` | `%` `_` 按字面匹配,不当通配符 | | ✅ 空白 | `batchName=` 或全空格 | 视为不传,返回全部 | | ❌ 用团期号搜 | `batchName=Q2026...` | 不匹配 batch_no,返回空页;按团期精确筛请用 `groupBatchId` | 「团期名称」列渲染为 `第{batchLabel}期 {batchName}`;两字段任一为 null(团期已软删)时前端自行兜底。 ### 电话与金额 - `customerPhoneMasked` 已脱敏,库内为密文,接口不提供明文。流团行恒 null。 - 本页不展示「当前预估退款」「实退金额」;`estimatedRefundAmount` 等既有金额字段保留,老调用方不受影响。 ### 已知旁路(非本单引入) 持 `group-batch:view` 的非管理员角色(如 CUSTOMIZER、GROUP_BATCH_MANAGER)能打开审批中心列表与流团详情(含退单户联系人与脱敏电话), 此时 `canApprove` 全为 false;调退单列表 / 详情返回 589530,调审批端点返回 589530(退单)/ 589547(流团)。 审批中心列表按 bizType 分权属另议,本单不改判权。 --- ## 五、数据库行为 - `group_batch_approval` 新增可空列 `participant_count INT NULL`(Flyway `V20260924_825__group_batch_approval_add_participant_count.sql`,版本 `20260924.825`),纯 ADD COLUMN,存量行不回填。 - 写入时机只有两个提交端点: - 提交流团(GB-ADM-060,本清单接口 3):写提交时团期下非取消子订单的人数合计(成人+儿童+小童+婴儿),与 `affected_order_count` 同一批户、同一时刻。 - 提交退单(GB-ADM-070,契约四项未变,不在清单):写被退那一户的人数。 - 同意 / 拒绝端点(接口 4、5、8、9)对该列只读不写;执行流团、退单、退款的写库行为本次零改动。 - 列表 / 详情接口只读。名称搜索是先按团期名称 / 期号取团期 ID,再对审批单做 IN 筛选,不写库。 --- ## 六、边界行为 - **挂在已软删团期上的申请单**:照常出现在列表,团期侧字段为 null,`canApprove=false`(批复端点届时也会拒绝)。 - **出行人数取数**:有快照读快照;无快照的存量 PENDING 流团按同口径现算;无快照的已处理流团返回 null;无快照的退单户按该户订单现算。 - **流团批准后**:子订单全部取消,`participantCount` 仍返回提交时快照(不归零)。 - **名称搜索零命中**:直接返回 `total=0` 空页,不退化为全表。 - **角色门拒绝时**:`canApprove` 置 false,列表 / 详情本身不因此报错;对「请求缺角色声明」的处理与审批端点走同一段判定(含同一灰度开关),两者不会分叉。 - **无 token**:响应体 `code=401`(HTTP 状态码仍为 200),与网关既有行为一致。 --- ## 六.6、修改前后对比 | 项 | 修改前 | 修改后 | |---|---|---| | 审批中心列表入参 | 无名称搜索 | 新增可选 `batchName` | | 审批中心列表出参 | 无 `batchLabel` / `participantCount` / `approvedAt` / `customerPhoneMasked` / `canApprove` | 五个字段纯增 | | 审批中心列表 WITHDRAW 行 `affectedOrderCount` | `null` | `1` | | 流团驳回 `approvalStatusName` | 「已取消退单」 | 「已拒绝」 | | 退单户驳回 `approvalStatusName` | 「已取消退单」 | 「已取消退单」(不变) | | `DisbandApprovalRespVO`(接口 2–5) | 无 `batchName` / `batchLabel` / `approvalStatusName` / `participantCount` / `canApprove` | 五个字段纯增 | | `WithdrawApprovalItemRespVO`(接口 6–9) | 无 `batchName` / `batchLabel` / `customerPhoneMasked` / `affectedOrderCount` | 四个字段纯增;`participantCount` 改为快照优先(数值口径不变) | | `WithdrawApprovalDetailRespVO`(接口 7–9) | 无 `canApprove` | 纯增 | | 路径 / 判权 / 错误码 | — | 逐字未变 | | 数据库 | — | `group_batch_approval` 新增可空列 `participant_count` | --- ## 六.7、影响评估 - **兼容性**:九个接口均为纯增出参或可选入参;两处口径订正(WITHDRAW 行 `affectedOrderCount` null→1、流团驳回文案)只影响展示,未发现依赖旧值做分支判断的调用方。 - **性能**:列表的角色门整页只算一次;名称搜索多一次按团期名称 / 期号取主键的查询,零命中短路不再查审批单;出行人数优先读快照,只有存量 PENDING 流团才现算。 - **数据**:新列可空、不回填;存量已处理流团的出行人数返回 null 属预期。 - **回滚**:撤销 PR #8256、#8260 即可;新列可空,保留不影响旧代码读写。 - **判权**:未改任何判权;已知旁路见「四」。 --- ## 七、不影响范围 - 退单提交(GB-ADM-070)的入参、出参、返回值;流团 / 退单的执行语义、退款金额计算、幂等与并发控制。 - 审批中心列表与退单列表的既有筛选参数、分页包装(`records` / `total` / `page` / `pageSize`)。 - 团期看板、团期详情等其他团期接口;小程序端。 - 网关:路径未变、无新增路由与权限码。 --- ## 八、测试环境已验证 2026-09-23,TEST(api.test.1814.love:9443),部署 dev-v3(含 `4f9b6facb`)。造数:新建 3 个团期(期号 125 / 126 / 128), 提交 2 张退单、2 张流团申请,分别走同意 / 拒绝四条路径,逐项对库。 | 验证项 | 读数 | |---|---| | 审批中心列表全量对库 | 接口 `total=62`、本页 62 行、库内未删行 62;逐行比对异常 0;已处理 57 行 `approvedAt` 与库一致,`canApprove` 全 false | | 审批中心列表 WITHDRAW 行 `affectedOrderCount` | 19 行全部为 1(改前同一接口为 null) | | 流团驳回文案 | 列表 DISBAND/REJECTED 行 `approvalStatusName` 全为「已拒绝」(改前为「已取消退单」);WITHDRAW/REJECTED 仍为「已取消退单」 | | 已软删团期上的 PENDING 单 | 4 行团期字段为 null、`canApprove=false` | | 电话脱敏 | WITHDRAW 19 行中 18 行形如 `138****5678`,1 行为 null;DISBAND 行全 null | | 名称搜索:子串 | 命中「#8253-退单户同意与拒绝」2 行 | | 名称搜索:期号 | `第14期` → 6 行全为 14 期,不含 114 期;`14` → 8 行(14 期 6 行 + 名称含「14」的 2 行),同样不含 114 期;`第1期` → 3 行全为 1 期 | | 名称搜索:零命中 | `total=0`、`records=[]` | | 名称搜索:`%` / `_` / `%_` | 各只命中名称为「#8253-流团拒绝 50%_x」的 1 行 | | 名称搜索:空串 / 全空白 | 与不传一致,`total=62` | | 名称搜索:团期号 | 两种团期号输入均 `total=0` | | `canApprove`(4 张 PENDING) | SUPER_ADMIN / ADMIN:列表与两类详情全 true;GROUP_BATCH_MANAGER / CUSTOMIZER:列表与流团详情全 false,退单列表 / 详情 589530 | | 低权限调审批端点 | GROUP_BATCH_MANAGER / CUSTOMIZER 调流团同意 / 拒绝 589547,调退单同意 / 拒绝 589530 | | 出行人数快照 | 提交后 `participant_count` 落库:流团 4 / 3,退单 3 / 1 | | 退单同意 | 订单 `CUSTOMIZING → CANCELLED`;团期 enrolled 人/户 4/2 → 1/1;退款申请 `2102669022577479682` APPROVED,应退 1500.00 / 实退 1500.00;`approved_by_name` 有值 | | 退单拒绝 | 该户订单状态与 update_time 不变,无退款申请;`approvalStatusName=已取消退单` | | 流团同意 | 团期 `RECRUITING → CANCELLED`,2 张活跃子订单取消,退款申请 `2102669171114561538` APPROVED 1500.00 / 1500.00;批准后接口 `participantCount` 仍为 4 | | 流团拒绝 | 团期状态、名额、update_time 不变;`approvalStatusName=已拒绝` | | 无 token | 响应体 `code=401`,HTTP 200 | | 退单列表 / 详情(072/073)`affectedOrderCount` | 16:17 部署 dev-v3(含 `11dd1e2fb`)后实测:退单列表 `approvalStatus=ALL` 共 19 行,`affectedOrderCount` 全为 1;退单详情 `2102668636105904130` 连取 4 次(覆盖两实例)均为 1 | **2026-09-24 补验:退单户团期不可退团**(TEST,部署面板显示后端检出为 dev-v3 `cc70c9ba3`,含 `4f9b6facb` / `11dd1e2fb`)。 提交时团期若已出行,GB-ADM-070 就会直接返回 589501,所以先在招募中的测试团期「#8253-退单户同意与拒绝」(`2102668373412450306`)上提交退单 `2102953813164072962`,再用 SQL 把该团期 `batch_status` 从 `RECRUITING` 临时改为 `TRAVELLING`: | 验证项 | 读数 | |---|---| | 招募中基线 | 列表与退单详情该单 `canApprove=true`,详情 `currentRefundMode=FULL_DEPOSIT` | | 出行中:审批中心列表(`groupBatchId` 过滤,超管) | 该 PENDING 单 `canApprove=false` | | 出行中:退单详情(超管) | `canApprove=false`,`currentRefundMode` / `currentEstimatedRefundAmount` 为 null | | 出行中:超管调退单同意 | `code=589501`,message「团期状态不允许当前操作」(HTTP 200) | | 同意被拦后对库 | 审批行仍 `PENDING`、无批复人;订单仍 `CUSTOMIZING` / `DEPOSIT_PAID`,update_time 不变 | | 恢复 | 团期 `batch_status` 改回 `RECRUITING`,`update_time` 也改回原值 `2026-09-23 15:58:55`,并回查确认;恢复后退单详情 `canApprove=true`。随后驳回这张补验用的退单,清掉造数 | 单元测试(本地):`GroupBatchDisbandApprovalServiceTest` 56 例、`GroupBatchWithdrawApprovalServiceTest` 35 例、 `GroupBatchWithdrawApprovalControllerRoleGateTest` 13 例,合计 104 例 0 失败。 --- ## 十、相关文档 - 工单 #8253;PR #8256(merge `4f9b6facb`)、PR #8260(merge `11dd1e2fb`) - 审批中心列表补 orderNo / customerName / departDate 的前序:#7535 - 名称 / 期号搜索口径同团期看板 keyword:#7942 - 审批闸改权限码的后续:#8246(hl-ui 两个审批页 isAdmin 整页门禁见其 A9) - 流团审批:#7196;退单审批:#7100 ## 关联 / 联系人 - 后端:jw - 前端:待认领(`frontend_status: pending`)