Refs wx/HL#8677 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
13 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 | 8677 | 团期预支可支取上限改为「整团已收(扣已退)− 在途」——GB-ADM-040 advanceAvailable 与 GB-ADM-042 发起上限同步改口径 | admin | jw(GIT) | 修改接口 | deployed | verified | not_required | 团期预支的可支取上限原为「团期尾款池(Σ 各户 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。 | 2026-10-01 | 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 | 待审批预支(既有字段,本次未改) |
请求示例
GET /v3/admin/order/group-batch/2104839654727618562/finance HTTP/1.1
Host: api.test.1814.love
Authorization: Bearer <admin token>
响应示例
{
"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、不返回负数。
{
"code": 200,
"message": "成功",
"data": {
"receivableAmount": "0.00",
"receivedAmount": "0.00",
"unpaidAmount": "0.00",
"advanceApproved": "0.00",
"advancePending": "0.00",
"advanceAvailable": "0.00"
}
}
错误响应
{
"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 | 领款人(既有,本次未改) |
请求示例
{
"payeeStaffId": 1009,
"advanceType": "ACCOMMODATION_DEPOSIT",
"amount": "24760.00",
"purpose": "额济纳段酒店押金先行垫付"
}
响应示例
{
"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"
}
}
空数据 / 降级响应
本接口为写接口,无空数据形态;校验不通过时不写库、不占额度,返回下方错误。
{
"code": 585004,
"message": "预支金额超过可用余额上限",
"data": null
}
错误响应
{
"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)