docs(changelog): #8677 团期预支可支取上限改为整团已收(修改接口·管理后台)
changelog-filename-gate / validate (push) Failing after 2s
changelog-filename-gate / validate (push) Failing after 2s
Refs wx/HL#8677 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
这个提交包含在:
@@ -0,0 +1,293 @@
|
|||||||
|
---
|
||||||
|
schema: "hl-changelog/v2"
|
||||||
|
ticket: "8677"
|
||||||
|
title: "团期预支可支取上限改为「整团已收(扣已退)− 在途」——GB-ADM-040 advanceAvailable 与 GB-ADM-042 发起上限同步改口径"
|
||||||
|
consumer: "admin"
|
||||||
|
author: "jw(GIT)"
|
||||||
|
change_type: "修改接口"
|
||||||
|
backend_status: "deployed"
|
||||||
|
gateway_status: "verified"
|
||||||
|
frontend_status: "not_required"
|
||||||
|
frontend_owner: ""
|
||||||
|
frontend_ref: ""
|
||||||
|
target_release: ""
|
||||||
|
verified_at: ""
|
||||||
|
status_note: "团期预支的可支取上限原为「团期尾款池(Σ 各户 max(0, 应收 − 已付))− 在途」,全额收款的团可支取恒为 0(TEST「11月1日额济纳胡杨林深秋4日游」应收 = 已收 26340.00 → 0.00),部分收款的团反倒能按还没收的钱预支。jw 2026-10-01 定案改为「团期已收池 − 在途」:已收池 = Σ 本团活跃子订单 max(0, 已付 − 已退),CANCELLED 户记 0;硬上限,超额 585004、无放宽通道;普通订单上限不改;部分收款团上限收紧属预期;存量不回溯(在途已超新上限时可支取显示 0.00、只拦新申请)。GB-ADM-040 的 advanceAvailable 与 GB-ADM-042 的发起校验共用同一方法,同时生效。路径、入参、出参字段名与类型零变化,错误码不变;变的是取值口径,属「语义取值」变化,按 jw 2026-09-18 口径推送。已合并 dev-v3(PR #8686,merge commit f4f545148)并部署测试服。hl-ui v2.1 弹窗「剩余可支取」与财务 Tab「可支取余额」都直接显示后端 advanceAvailable,前端零改动,frontend_status 记 not_required。"
|
||||||
|
updated_at: "2026-10-01"
|
||||||
|
base: "dev-v3"
|
||||||
|
---
|
||||||
|
|
||||||
|
# 团期预支可支取上限改为整团已收(管理后台)
|
||||||
|
|
||||||
|
> **服务**: hl-order-service-v3(端口 8086/8186)
|
||||||
|
|
||||||
|
## 一、接口背景
|
||||||
|
|
||||||
|
团期「发起团期预支」弹窗里的「剩余可支取」、财务 Tab 的「可支取余额」,以及发起时的超额校验,原先都按**整团还没收的尾款**算上限。
|
||||||
|
全额收款的团尾款为 0,于是一分钱都预支不了;只收了一部分的团,反倒能按还没收的钱预支。
|
||||||
|
|
||||||
|
本次改为只预支已经收到手的钱:上限 = 整团已收(扣已退)− 在途预支。
|
||||||
|
|
||||||
|
## 二、变更接口清单
|
||||||
|
|
||||||
|
| # | 接口 | 方法 | 路径 | 变更类型 | 说明 |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| 1 | GB-ADM-040 团期财务总览 | GET | `/v3/admin/order/group-batch/{groupBatchId}/finance` | 修改接口 | 出参 `advanceAvailable` 取值口径改为「团期已收池 − 在途」;字段名、类型与其余字段零变化 |
|
||||||
|
| 2 | GB-ADM-042 发起团期预支 | POST | `/v3/admin/order/group-batch/{groupBatchId}/advance` | 修改接口 | 金额上限改为同一口径;入参、出参、错误码零变化 |
|
||||||
|
|
||||||
|
## 三、接口详情
|
||||||
|
|
||||||
|
### 1. GB-ADM-040 团期财务总览 `GET /v3/admin/order/group-batch/{groupBatchId}/finance`
|
||||||
|
|
||||||
|
**VO**: `GroupBatchFinanceRespVO`
|
||||||
|
|
||||||
|
#### 使用场景
|
||||||
|
|
||||||
|
团期详情「财务」Tab 切换即加载:四张金额卡、可支取余额、待审批预支、逐户付款。「发起团期预支」弹窗的「剩余可支取」也直接取本接口的 `advanceAvailable`。
|
||||||
|
|
||||||
|
#### 入参
|
||||||
|
|
||||||
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| groupBatchId | path | Long | 是 | 正整数,团期聚合主键 | 团期 ID,不存在返 589501 |
|
||||||
|
|
||||||
|
#### 出参
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| advanceAvailable | BigDecimal(字符串序列化) | **本次改口径**。可支取余额 = max(0, 团期已收池 − 在途)。团期已收池 = Σ 本团活跃子订单 max(0, 已付 − 已退),CANCELLED 户记 0;在途 = 本团期待审批 + 已通过 + 已付款的预支(团期级 ∪ 子订单级,口径不变)。即发起预支的硬上限 |
|
||||||
|
| receivedAmount | BigDecimal | 整团已收(既有字段,本次未改)。毛已付,**不扣退款**;有退款时 `advanceAvailable` 的基数会小于它 |
|
||||||
|
| receivableAmount | BigDecimal | 整团应收(既有字段,本次未改) |
|
||||||
|
| unpaidAmount | BigDecimal | 整团待收(既有字段,本次未改;**不再**是预支上限的基数) |
|
||||||
|
| advanceApproved | BigDecimal | 已预支(既有字段,本次未改) |
|
||||||
|
| advancePending | BigDecimal | 待审批预支(既有字段,本次未改) |
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
|
||||||
|
```http
|
||||||
|
GET /v3/admin/order/group-batch/2104839654727618562/finance HTTP/1.1
|
||||||
|
Host: api.test.1814.love
|
||||||
|
Authorization: Bearer <admin token>
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "成功",
|
||||||
|
"data": {
|
||||||
|
"receivableAmount": "26340.00",
|
||||||
|
"receivedAmount": "26340.00",
|
||||||
|
"unpaidAmount": "0.00",
|
||||||
|
"advanceApproved": "0.00",
|
||||||
|
"advancePending": "0.00",
|
||||||
|
"advanceAvailable": "26340.00"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 空数据 / 降级响应
|
||||||
|
|
||||||
|
团里没有活跃子订单、或已收全部被在途占满时,`advanceAvailable` 返回 `"0.00"`,不返回 null、不返回负数。
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "成功",
|
||||||
|
"data": {
|
||||||
|
"receivableAmount": "0.00",
|
||||||
|
"receivedAmount": "0.00",
|
||||||
|
"unpaidAmount": "0.00",
|
||||||
|
"advanceApproved": "0.00",
|
||||||
|
"advancePending": "0.00",
|
||||||
|
"advanceAvailable": "0.00"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 错误响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 589501,
|
||||||
|
"message": "团期不存在",
|
||||||
|
"data": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| 错误码 | 触发条件 |
|
||||||
|
|---|---|
|
||||||
|
| 589501 | groupBatchId 不存在或已软删 |
|
||||||
|
|
||||||
|
#### 业务边界
|
||||||
|
|
||||||
|
- 展示值与 GB-ADM-042 的发起校验出自同一个方法,弹窗显示多少就能发起多少。
|
||||||
|
- 取户与在途同源:活跃子订单集按 `group_batch_id` 一跳圈定,已取消户不计入已收。
|
||||||
|
- 部分退款的户按「已付 − 已退」计入;单户已退不少于已付时按 0 计。
|
||||||
|
- 存量不回溯:在途已超过新上限的团(存量预支或事后退款),这里显示 `"0.00"`,已有预支记录不变。
|
||||||
|
|
||||||
|
### 2. GB-ADM-042 发起团期预支 `POST /v3/admin/order/group-batch/{groupBatchId}/advance`
|
||||||
|
|
||||||
|
**VO**: `OrderAdvanceRespVO`
|
||||||
|
|
||||||
|
#### 使用场景
|
||||||
|
|
||||||
|
团期管理员为本团主报账人申请团期级预支,创建即待审批(SUBMITTED),财务在审批中心审批。本次只改金额上限的口径。
|
||||||
|
|
||||||
|
#### 入参
|
||||||
|
|
||||||
|
| 字段 | 位置 | 类型 | 必填 | 约束 | 说明 |
|
||||||
|
|---|---|---|---|---|---|
|
||||||
|
| groupBatchId | path | Long | 是 | 正整数 | 团期 ID |
|
||||||
|
| payeeStaffId | body | Long | 是 | 须为本团主报账人(PRIMARY) | 借款对象,否则 589557 |
|
||||||
|
| advanceType | body | String | 是 | 数据字典 `advance_type` 内的值 | 借款类型,否则 585006 |
|
||||||
|
| amount | body | BigDecimal | 是 | ≥ 0.01,且 ≤ 当前 `advanceAvailable` | 预支金额;**上限口径本次改为团期已收池 − 在途**,超出 585004 |
|
||||||
|
| purpose | body | String | 否 | ≤ 255 字 | 用途说明 |
|
||||||
|
| voucherUrl | body | String | 否 | ≤ 512 字符 | 凭证文件 URL |
|
||||||
|
|
||||||
|
#### 出参
|
||||||
|
|
||||||
|
| 字段 | 类型 | 说明 |
|
||||||
|
|---|---|---|
|
||||||
|
| id | Long | 预支 ID(既有,本次未改) |
|
||||||
|
| status | String | 恒为 `SUBMITTED`(既有,本次未改) |
|
||||||
|
| amount | BigDecimal | 预支金额(既有,本次未改) |
|
||||||
|
| payeeStaffId / payeeName | Long / String | 领款人(既有,本次未改) |
|
||||||
|
|
||||||
|
#### 请求示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"payeeStaffId": 1009,
|
||||||
|
"advanceType": "ACCOMMODATION_DEPOSIT",
|
||||||
|
"amount": "24760.00",
|
||||||
|
"purpose": "额济纳段酒店押金先行垫付"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 响应示例
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 200,
|
||||||
|
"message": "成功",
|
||||||
|
"data": {
|
||||||
|
"id": "2105531450843668481",
|
||||||
|
"orderId": null,
|
||||||
|
"payeeStaffId": "1007",
|
||||||
|
"payeeName": "白云飞",
|
||||||
|
"payeeRole": "LEADER",
|
||||||
|
"advanceType": "ACCOMMODATION_DEPOSIT",
|
||||||
|
"amount": 24760.0,
|
||||||
|
"status": "SUBMITTED",
|
||||||
|
"statusText": "待审批",
|
||||||
|
"submittedAt": "2026-10-01 13:33:11"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 空数据 / 降级响应
|
||||||
|
|
||||||
|
本接口为写接口,无空数据形态;校验不通过时不写库、不占额度,返回下方错误。
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 585004,
|
||||||
|
"message": "预支金额超过可用余额上限",
|
||||||
|
"data": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 错误响应
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": 585004,
|
||||||
|
"message": "预支金额超过可用余额上限",
|
||||||
|
"data": null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
| 错误码 | 触发条件 |
|
||||||
|
|---|---|
|
||||||
|
| 585004 | `amount` 大于当前可支取余额(团期已收池 − 在途);**本次口径变化**,错误码与文案不变 |
|
||||||
|
| 585003 | `amount` ≤ 0 |
|
||||||
|
| 589541 | 团期状态不允许发起预支(进入核单后关闭) |
|
||||||
|
| 589557 | 借款对象不是本团主报账人 |
|
||||||
|
|
||||||
|
#### 业务边界
|
||||||
|
|
||||||
|
- 上限在 `@Lock4j` 按 groupBatchId 串行的段内计算,读-算-插之间无并发窗口。
|
||||||
|
- 硬上限:超额一律 585004,没有放宽通道;审批时不再复核额度(维持现状)。
|
||||||
|
- 普通订单的预支上限不随本次改动,仍是「本单待收尾款 − 本单在途」。
|
||||||
|
- 部分收款的团上限随之收紧(例:应收 10720、已收 1600 的团,可支取由 9120.00 变为 1600.00)。
|
||||||
|
|
||||||
|
## 四、契约约束与正确调用方式
|
||||||
|
|
||||||
|
- 弹窗「剩余可支取」与财务 Tab「可支取余额」继续直接读 `advanceAvailable`,**不要**用 `receivedAmount − advanceApproved − advancePending` 本地推算:`receivedAmount` 不扣退款,且在途还含已付款的预支。
|
||||||
|
- 发起前以最新一次 GB-ADM-040 的 `advanceAvailable` 为准;并发发起时以服务端 585004 为准。
|
||||||
|
|
||||||
|
## 五、数据库行为
|
||||||
|
|
||||||
|
零数据库变更:不新增表、列或索引。GB-ADM-040 只读;GB-ADM-042 写入行为不变(校验通过后在 `order_advance` 插入一行 `scope=GROUP_BATCH`、`status=SUBMITTED`,并写团期时间线)。
|
||||||
|
上限的取数改为只读聚合 `order_main.paid_amount` / `refunded_amount`(按本团活跃子订单一次批量取),不再读应付尾款。
|
||||||
|
|
||||||
|
## 六、边界行为
|
||||||
|
|
||||||
|
- 全额收款、无在途:可支取 = 整团已收净额。
|
||||||
|
- 已收全部被在途占满,或事后退款使已收低于在途:可支取 `"0.00"`,新申请 585004。
|
||||||
|
- 团里一户都不剩:已收为 0,可支取 `"0.00"`。
|
||||||
|
|
||||||
|
## 六.6、修改前后对比
|
||||||
|
|
||||||
|
| 项 | 修改前 | 修改后 |
|
||||||
|
|---|---|---|
|
||||||
|
| 上限基数 | 团期尾款池 = Σ 各户 max(0, 应收 − 已付) | 团期已收池 = Σ 活跃户 max(0, 已付 − 已退),取消户记 0 |
|
||||||
|
| 全额收款的团 | 可支取恒为 `0.00` | 可支取 = 整团已收净额 |
|
||||||
|
| 部分收款的团 | 可支取 = 还没收的尾款 − 在途 | 可支取 = 已收净额 − 在途(收紧) |
|
||||||
|
| 取户口径 | 按 `product_batch_id` 圈 | 按 `group_batch_id` 一跳(与在途同源) |
|
||||||
|
| 路径 / 入参 / 出参 / 错误码 | — | 逐字未变 |
|
||||||
|
|
||||||
|
## 六.7、影响评估
|
||||||
|
|
||||||
|
- **兼容性**:字段名、类型、错误码不变;数值口径变化,前端零改动。
|
||||||
|
- **性能**:上限计算由一次按排期圈单改为一次按子订单 ID 批量取单,单团期无 N+1。
|
||||||
|
- **回滚**:撤销 PR #8686 的合并提交后重新部署 order-v3,无数据与配置残留。
|
||||||
|
|
||||||
|
## 七、不影响范围
|
||||||
|
|
||||||
|
- 普通订单(非团期)的预支上限与订单级预支接口。
|
||||||
|
- 已预支 / 待审批两个数、预支记录列表(GB-ADM-043)、核单扣回口径。
|
||||||
|
- 网关:路径未变、无新增路由与权限码。
|
||||||
|
- 小程序端:本接口仅管理后台使用。
|
||||||
|
|
||||||
|
## 八、测试环境已验证
|
||||||
|
|
||||||
|
2026-10-01 13:14–14:59 测试服(`api.test.1814.love`),部署 `dev-v3 @ f4f545148`(order-v3 双实例 8086/8186)。
|
||||||
|
每个状态节点都用 SQL 按同一公式独立手算并与 `advanceAvailable` 对照,**29 次对照全部一致**。
|
||||||
|
|
||||||
|
| 场景 | 读数 / 结果 |
|
||||||
|
|---|---|
|
||||||
|
| 部署身份:全额收款团「11月1日额济纳胡杨林深秋4日游」(应收 = 已收 26340.00) | 经网关 8 次 + 直连两实例全是 `"26340.00"`(旧口径为 `"0.00"`) |
|
||||||
|
| 部分收款团「滇西北冬日三日团·一月廿二期」(应收 10720 / 已收 1600) | `"1600.00"`(旧口径为 9120.00) |
|
||||||
|
| 自建全额收款团(已收 24760.00) | 可支取 `"24760.00"`;发起 24760.00 → 200 SUBMITTED,可支取变 `"0.00"`;再发起 0.01 → 585004 |
|
||||||
|
| 自建部分收款团(应收 22080 / 已收 15720) | `"15720.00"`;待审 1200 后 `"14520.00"`;14520.01 → 585004,14520.00 → 200 |
|
||||||
|
| 部分退款 1840(真实退款链路) | 21880 → `"20040.00"`;再取消一户(已付 7360)→ `"12680.00"` |
|
||||||
|
| 在途 | 待审 / 已批 / 已付都扣;驳回、撤回不扣 |
|
||||||
|
| 存量不回溯 | 在途占满后取消一户,可支取仍 `"0.00"`,新申请 585004,已有预支记录逐字段不变 |
|
||||||
|
| 普通订单 | 上限仍是「本单待收 − 本单在途」:两档已付下超 0.01 都报 585004、等额都成功,与新口径可区分 |
|
||||||
|
|
||||||
|
- 验收造数已全部回收,回读零残留。
|
||||||
|
- 单元测试:团期 / 预支整包 + 全部 ArchTest 258 类 4131 例 0 失败;合并提交上复跑定向 32 类 250 例 0 失败。
|
||||||
|
|
||||||
|
## 十、相关文档
|
||||||
|
|
||||||
|
- 工单 #8677、PR #8686(merge commit `f4f545148`)
|
||||||
|
- 团期统一池原设计:#7154(docs/group 接口文档 §0B.4,本次同步改为已收池)
|
||||||
|
- 团单子订单禁走订单级入口、在途含 PAID:#8384
|
||||||
|
|
||||||
|
## 关联 / 联系人
|
||||||
|
|
||||||
|
- 后端:jw
|
||||||
|
- 前端:不涉及(`frontend_status: not_required`)
|
||||||
在新工单中引用
屏蔽一个用户