docs(changelog): #8436 团期退单审批放开团期管理员,批后退款进退款审批中心二审
changelog-filename-gate / validate (push) Failing after 2s
changelog-filename-gate / validate (push) Failing after 2s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
这个提交包含在:
@@ -0,0 +1,907 @@
|
||||
---
|
||||
schema: "hl-changelog/v2"
|
||||
ticket: "8436"
|
||||
title: "团期退单审批 GB-ADM-072~075 放开团期管理员;074 审批通过后退款单不再自动审核,以 PENDING 进退款审批中心人工审;退单详情与团期审批中心列表的 canApprove 按退单专用门判定"
|
||||
consumer: "admin"
|
||||
author: "jw(GIT)"
|
||||
change_type: "修改接口"
|
||||
backend_status: "deployed"
|
||||
gateway_status: "verified"
|
||||
frontend_status: "pending"
|
||||
frontend_owner: ""
|
||||
frontend_ref: ""
|
||||
target_release: ""
|
||||
verified_at: ""
|
||||
status_note: "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 均实测生效并已还原。"
|
||||
updated_at: "2026-09-27"
|
||||
base: "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 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
无请求体。
|
||||
|
||||
```http
|
||||
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 调用);团期管理员调用返回同一结构。
|
||||
|
||||
```json
|
||||
{
|
||||
"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
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
无命中时返回空页:
|
||||
|
||||
```json
|
||||
{
|
||||
"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`。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"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,结构与取值不变 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
无请求体。
|
||||
|
||||
```http
|
||||
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`。
|
||||
|
||||
```json
|
||||
{
|
||||
"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 相同)。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"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 |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
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 调用)。本单未改响应,同一请求改后返回同一结构与取值;差别在响应之外的退款单状态,见「业务边界」。
|
||||
|
||||
```json
|
||||
{
|
||||
"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`;退款二审照常。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"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` |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
```http
|
||||
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 的退单申请):
|
||||
|
||||
```json
|
||||
{
|
||||
"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 相同)。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"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` |
|
||||
|
||||
#### 请求示例
|
||||
|
||||
无请求体。
|
||||
|
||||
```http
|
||||
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` 由单测覆盖。
|
||||
|
||||
```json
|
||||
{
|
||||
"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
|
||||
}
|
||||
```
|
||||
|
||||
#### 空数据 / 降级响应
|
||||
|
||||
无命中时返回空页:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 200,
|
||||
"message": "成功",
|
||||
"data": { "records": [], "total": 0, "page": 1, "pageSize": 20 },
|
||||
"success": true
|
||||
}
|
||||
```
|
||||
|
||||
**降级**:两个开关任一置 `false` 时,团期管理员看到的退单行 `canApprove` 回到 `false`;列表本身照常返回(本接口判权不读这两个开关)。
|
||||
|
||||
#### 错误响应
|
||||
|
||||
```json
|
||||
{
|
||||
"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 / 061 `canApprove=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`):无接口变化。
|
||||
- 存量数据:本单前已自动审核的退款单不回溯。
|
||||
|
||||
---
|
||||
|
||||
## 八、测试环境已验证
|
||||
|
||||
**环境**: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 个键、`data` 33 个字段,集合与顺序与改前完全一致;取值差异只在订单号、客户、审批人、时间等造数身份字段。接口文档中 `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](https://git.1814.love/wx/HL/issues/8436)
|
||||
- 关联 PR: [wx/HL#8441](https://git.1814.love/wx/HL/pulls/8441)
|
||||
- 同组端点上一版契约:`changelogs-v2/2026-09/24_8253_团期审批中心统一审核补字段与团期名称搜索-修改接口-管理后台.md`
|
||||
- 提交侧判权:`changelogs-v2/2026-09/27_7608_团期退团提交与核单定稿判权收口批3-修改接口-管理后台.md`
|
||||
|
||||
## 关联 / 联系人
|
||||
|
||||
### 链接
|
||||
|
||||
- **Issue**: [#8436](https://git.1814.love/wx/HL/issues/8436)
|
||||
- **PR**: [#8441](https://git.1814.love/wx/HL/pulls/8441)
|
||||
- **Merge commit**: [c97c0b4ca](https://git.1814.love/wx/HL/commit/c97c0b4ca5348cceba55d0296f2c5e5623a8485a)
|
||||
|
||||
### 联系人
|
||||
|
||||
- **后端负责人**: @jw
|
||||
在新工单中引用
屏蔽一个用户