docs(changelog-v2): 应收台账新增 rowType 入参 + 查看按钮对接指引(PR #8505 / Issue #8504)
changelog-filename-gate / validate (push) Failing after 1s

这个提交包含在:
yaosutu
2026-09-29 11:40:31 +08:00
父节点 7c7ece465c
当前提交 d7bec334e5
@@ -0,0 +1,342 @@
---
schema: "hl-changelog/v2"
ticket: "frontend"
title: "应收台账新增 rowType 入参(全部/散客订单/团期切换)+ 查看按钮对接指引"
consumer: "admin"
author: "yst(GIT)"
change_type: "修改接口"
backend_status: "required"
gateway_status: "not_required"
frontend_status: "required"
frontend_owner: ""
frontend_ref: ""
target_release: ""
verified_at: ""
status_note: "应收台账分页接口新增可选入参 rowType(空=全部 / ORDER=散客订单 / GROUP_BATCH=团期整团聚合行),后端过滤后 total 正确,前端需加顶部切换;另每行需加「查看」按钮,按 rowType 分流跳订单详情 / 出团详情(路由规则见 §十二)。"
updated_at: "2026-09-29"
base: "dev-v3"
---
# finance:应收台账新增 rowType 入参 + 查看按钮对接(管理后台)
**服务**: hl-order-service-v3(finance 模块,同进程)
**PR**: https://git.1814.love/wx/HL/pulls/8505
**Issue**: https://git.1814.love/wx/HL/issues/8504
---
## 一、接口背景
管理后台「应收台账」页面调用 `GET /admin/finance/receipt/receivable/page`(#8191 交付的只读台账页)。台账行是**双轨**的:
- `rowType = ORDER`:散客订单行,一行 = 一个订单
- `rowType = GROUP_BATCH`:团期整团聚合行,一行 = 一个出团批次(整团应收汇总)
本次变更给分页接口**新增一个可选入参 `rowType`**,支持页面顶部「全部 / 散客订单 / 团期」三态切换,由后端过滤(此前前端只能本地过滤,分页 total 会错)。
另财务要求在每行加「查看」按钮点行进详情。**查看按钮是纯前端动作**——行出参字段已够用(`rowType` / `id` / `groupBatchId` 都有),不依赖本次后端发版,但跳转路由规则必须按 §十二 执行,跳错必 404。
## 二、变更清单
| 项 | 变更 |
|---|---|
| `GET /admin/finance/receipt/receivable/page` 入参 | **新增可选 Query 参数 `rowType`**(空/不传 = 全部,`ORDER` = 只散客订单行,`GROUP_BATCH` = 只团期整团聚合行) |
| 出参字段 | **不变**(行 VO 字段同 #8191) |
| 数据库表 | 零 DDL |
| 前端页面 | 需加顶部「全部/散客订单/团期」切换(把 `rowType` 传给后端)+ 每行加「查看」按钮(按 §十二 分流跳转) |
## 三、接口详情
- **路径**:`GET /admin/finance/receipt/receivable/page`
- **认证**:网关 JWT(admin)
- **幂等性**:是(只读查询,可重复调用无副作用)
- **限流**:无特殊限流
## 四、接口入参
### 4.1 路径参数 / Query 参数
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| `pageNo` | Integer | ✅ | 页码,从 1 开始 |
| `pageSize` | Integer | ✅ | 每页条数 |
| `keyword` | String | ❌ | 关键字模糊搜索(订单号 / 团号 / 产品名 / 客户名等),语义不变 |
| `receivableStatus` | String | ❌ | 收款状态过滤,语义不变(枚举见 §六) |
| `rowType` | String | ❌ | **本次新增**。行类型过滤:`ORDER` = 只返回散客订单行;`GROUP_BATCH` = 只返回团期整团聚合行;**空或不传 = 全部**(向后兼容) |
### 4.2 请求体字段
无(GET 请求)。
## 五、出参
外层为标准分页响应包:`code` / `data` / `message` / `success`,其中 `data` 含 `list`(行数组)/ `total` / `pageNo` / `pageSize`。
行 VO 字段(与 #8191 一致,本次未变):
| 字段 | 类型 | 说明 |
|------|------|------|
| `rowType` | String | 行类型:`ORDER` / `GROUP_BATCH` |
| `id` | String | 行主键。`ORDER` 行 = 订单 ID;`GROUP_BATCH` 行 = 团期批次 ID(⚠️ 见 §十二,跳转时不能混用) |
| `groupBatchId` | String | 团期批次 ID。**仅 `GROUP_BATCH` 行有值**,`ORDER` 行为 null |
| `orderNo` | String | 订单号(`GROUP_BATCH` 行为团号口径,按行展示即可) |
| `teamNo` | String | 团号 |
| `productName` | String | 产品名称 |
| `customerName` | String | 客户姓名。**`GROUP_BATCH` 行恒为 null**,前端显示「—」 |
| `customerPhone` | String | 客户电话。**`GROUP_BATCH` 行恒为 null**,前端显示「—」 |
| `orderStatus` | String | 订单状态码 |
| `orderStatusName` | String | 订单状态中文名 |
| `receivableStatus` | String | 收款状态码(枚举见 §六) |
| `receivableStatusName` | String | 收款状态中文名 |
| `receivableAmount` | Number | 应收金额(元) |
| `paidAmount` | Number | 已付金额(元) |
| `collectedAmount` | Number | 已收金额(元) |
| `balanceAmount` | Number | 待收尾款(元) |
> ⚠️ `id` / `groupBatchId` 为 Long 大数(雪花 ID)序列化的**字符串**;各金额字段如以字符串下发同样**当字符串处理**。JS 全程禁止 `Number()` 转换 ID 类字段,防精度丢失。
## 六、枚举 / 数据字典
### 6.1 rowType(行类型)
**所属字段**:Query 入参 `rowType` / 出参行 `rowType` | **类型**:`String`
| 值 | 中文 | 说明 |
|----|------|------|
| `ORDER` | 散客订单 | 一行 = 一个订单 |
| `GROUP_BATCH` | 团期整团 | 一行 = 一个出团批次(整团应收汇总聚合行) |
> 入参侧:空 / 不传 = 全部;非法值后端按「全部」处理(不过滤),不报错。
### 6.2 receivableStatus(收款状态)
**所属字段**:Query 入参 `receivableStatus` / 出参行 `receivableStatus` | **类型**:`String`
| 值 | 中文 | 说明 |
|----|------|------|
| `UNPAID` | 未收款 | 已收为 0 |
| `PARTIAL` | 部分收款 | 已收 > 0 但未收齐 |
| `DONE` | 已收齐 | 已收 = 应收 |
## 七、错误码
本接口为只读分页查询,**无业务错误码**。仅标准网关层错误:
| HTTP | 场景 |
|------|------|
| 401 | 未登录 / token 失效 |
| 403 | 无权限访问 |
## 八、示例
### 8.1 典型成功(rowType=ORDER,只查散客订单行)
**请求**:
```http
GET /admin/finance/receipt/receivable/page?pageNo=1&pageSize=10&rowType=ORDER&receivableStatus=UNPAID
Authorization: Bearer <admin-token>
```
**响应**:
```json
{
"code": 200,
"data": {
"list": [
{
"rowType": "ORDER",
"id": "1964123456789012345",
"groupBatchId": null,
"orderNo": "O20260928123001",
"teamNo": "T20261005-01",
"productName": "呼伦贝尔草原五日游",
"customerName": "张三",
"customerPhone": "138****1234",
"orderStatus": "CONFIRMED",
"orderStatusName": "已确认",
"receivableStatus": "UNPAID",
"receivableStatusName": "未收款",
"receivableAmount": 5980.00,
"paidAmount": 0.00,
"collectedAmount": 0.00,
"balanceAmount": 5980.00
}
],
"total": 1,
"pageNo": 1,
"pageSize": 10
},
"message": "成功",
"success": true
}
```
### 8.2 边界(rowType=GROUP_BATCH,团行 customerName/customerPhone 为 null)
**请求**:
```http
GET /admin/finance/receipt/receivable/page?pageNo=1&pageSize=10&rowType=GROUP_BATCH
Authorization: Bearer <admin-token>
```
**响应**(注意 `customerName` / `customerPhone` 恒为 null,前端显示「—」):
```json
{
"code": 200,
"data": {
"list": [
{
"rowType": "GROUP_BATCH",
"id": "1964999888777666555",
"groupBatchId": "1964999888777666555",
"orderNo": "GB20261005-01",
"teamNo": "T20261005-01",
"productName": "阿尔山秋色摄影团",
"customerName": null,
"customerPhone": null,
"orderStatus": "CONFIRMED",
"orderStatusName": "已确认",
"receivableStatus": "PARTIAL",
"receivableStatusName": "部分收款",
"receivableAmount": 88000.00,
"paidAmount": 50000.00,
"collectedAmount": 50000.00,
"balanceAmount": 38000.00
}
],
"total": 1,
"pageNo": 1,
"pageSize": 10
},
"message": "成功",
"success": true
}
```
### 8.3 不传 rowType(全部,ORDER + GROUP_BATCH 行混合返回)
**请求**:
```http
GET /admin/finance/receipt/receivable/page?pageNo=1&pageSize=10
Authorization: Bearer <admin-token>
```
**响应**(两种行混排,前端按每行 `rowType` 自行决定展示与跳转):
```json
{
"code": 200,
"data": {
"list": [
{
"rowType": "ORDER",
"id": "1964123456789012345",
"groupBatchId": null,
"orderNo": "O20260928123001",
"teamNo": "T20261005-01",
"productName": "呼伦贝尔草原五日游",
"customerName": "张三",
"customerPhone": "138****1234",
"orderStatus": "CONFIRMED",
"orderStatusName": "已确认",
"receivableStatus": "DONE",
"receivableStatusName": "已收齐",
"receivableAmount": 5980.00,
"paidAmount": 5980.00,
"collectedAmount": 5980.00,
"balanceAmount": 0.00
},
{
"rowType": "GROUP_BATCH",
"id": "1964999888777666555",
"groupBatchId": "1964999888777666555",
"orderNo": "GB20261005-01",
"teamNo": "T20261005-01",
"productName": "阿尔山秋色摄影团",
"customerName": null,
"customerPhone": null,
"orderStatus": "CONFIRMED",
"orderStatusName": "已确认",
"receivableStatus": "UNPAID",
"receivableStatusName": "未收款",
"receivableAmount": 88000.00,
"paidAmount": 0.00,
"collectedAmount": 0.00,
"balanceAmount": 88000.00
}
],
"total": 2,
"pageNo": 1,
"pageSize": 10
},
"message": "成功",
"success": true
}
```
## 九、业务边界
- ✅ **适用场景**:应收台账分页查询,支持全部 / 只看散客订单 / 只看团期三种过滤。
- ⚠️ **不传 `rowType` = 全部**,与旧版行为完全一致(向后兼容)。
- ⚠️ `GROUP_BATCH` 行是分页折叠的**聚合行**,整团一页内只占一行;`total` 为近似口径(既有行为,本次未变)。
- ⚠️ `rowType` 传非法值(非 `ORDER` / `GROUP_BATCH`)后端按「全部」处理,不过滤也不报错,前端不要做非法值兜底展示。
## 十、修改前后对比
### 10.1 入参级对比
| 项 | 修改前 | 修改后 |
|---|---|---|
| Query 参数 | pageNo / pageSize / keyword / receivableStatus | **+ rowType**(可选,空=全部) |
| 「只看散客订单 / 只看团期」实现方式 | 前端拿全部分页结果本地过滤,**total 与实际行数对不上**,翻页错乱 | 后端按 `rowType` 过滤,**total 正确**,翻页正常 |
### 10.2 行为级对比
| 场景 | 修改前 | 修改后 |
|---|---|---|
| 不传 rowType | 全部行(ORDER + GROUP_BATCH 混排) | 同左(不变) |
| 切「散客订单」 | 无此能力(只能本地过滤) | `rowType=ORDER`,后端只返回 ORDER 行 |
| 切「团期」 | 无此能力 | `rowType=GROUP_BATCH`,后端只返回团行 |
## 十一、影响评估 / 回滚
- **是否破坏向后兼容**:否。`rowType` 为可选入参,不传时行为与旧版完全一致。
- **前端是否必须同步上线**:切换功能(顶部三态)建议改用后端过滤以修正 total;「查看」按钮不依赖本次后端发版(行出参字段 #8191 已齐备),可先行上线。
- **影响已有数据**:无(零 DDL、零数据迁移)。
- **回滚方案**:后端回退本 PR 即恢复旧行为(前端不传 rowType 不受影响);前端回退页面版本即可。
## 十二、注意事项
**本节是重点:「查看」按钮的路由分流规则。**
每行加「查看」按钮时,**必须先读该行的 `rowType` 再决定跳哪个详情页**:
| 行 `rowType` | 跳转前端路由 | 路由参数取哪个字段 | 后端详情接口 |
|---|---|---|---|
| `ORDER` | `/order-v2/detail/{id}` | 行的 **`id`**(= 订单 ID) | `GET /v3/admin/order/{id}` |
| `GROUP_BATCH` | `/order-v2/batch/detail/{code}` | 行的 **`groupBatchId`**(= 团期批次 ID) | `GET /v3/admin/order/group-batch/{groupBatchId}` |
逐条红线:
- ⚠️ **GROUP_BATCH 行绝不能拿 `id` 跳订单详情页**(`/order-v2/detail/{id}`)——团行的 `id` 里装的是**批次 ID**,按订单详情跳**必 404**(后端契约写死,订单详情只认订单 ID)。
- ⚠️ 团行跳转用的是独立的 **`groupBatchId`** 字段,不要用 `id`(虽然当前团行 `id == groupBatchId`,但契约上以 `groupBatchId` 为准)。
- ⚠️ 团行跳转的前端路由参数名是 **`:code`** 不是 `:id`,对应页面叫「**出团详情**」(`/order-v2/batch/detail/:code`)。
- ⚠️ `id` / `groupBatchId` 是 Long 大数序列化的字符串,拼接路由时**原样字符串拼接**,禁止 `Number()` 转换。
- ⚠️ `GROUP_BATCH` 行 `customerName` / `customerPhone` 恒为 null,列表显示「—」,不要显示「null」字样。
## 十三、关联 / 联系人
### 13.1 链接
- Issue:https://git.1814.love/wx/HL/issues/8504
- PR:https://git.1814.love/wx/HL/pulls/8505
- Merge commit:https://git.1814.love/wx/HL/commit/cf140ebed1
### 13.2 联系人
- 后端负责人:yst