diff --git a/changelogs-v2/2026-09/29_8504_应收台账加rowType入参-修改接口-管理后台.md b/changelogs-v2/2026-09/29_8504_应收台账加rowType入参-修改接口-管理后台.md new file mode 100644 index 00000000..5e0520b7 --- /dev/null +++ b/changelogs-v2/2026-09/29_8504_应收台账加rowType入参-修改接口-管理后台.md @@ -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 +``` + +**响应**: + +```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 +``` + +**响应**(注意 `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 +``` + +**响应**(两种行混排,前端按每行 `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