From 053276cfdda66323921bfe278f8624eb9114a707 Mon Sep 17 00:00:00 2001 From: yaosutu <770858045@qq.com> Date: Mon, 5 Oct 2026 22:45:47 +0800 Subject: [PATCH] =?UTF-8?q?docs(changelog):=208796=20=E5=8F=91=E7=A5=A8?= =?UTF-8?q?=E7=AE=A1=E7=90=86=E5=88=97=E8=A1=A8=E5=87=BA=E5=8F=82=E7=A7=BB?= =?UTF-8?q?=E9=99=A4=20stats=20=E7=BB=9F=E8=AE=A1=E5=9D=97=EF=BC=88?= =?UTF-8?q?=E9=A1=B6=E9=83=A84=E5=BC=A0=E7=BB=9F=E8=AE=A1=E5=8D=A1?= =?UTF-8?q?=E7=89=87=E4=B8=8B=E7=BA=BF=EF=BC=8CtabCounts=20=E4=BF=9D?= =?UTF-8?q?=E7=95=99=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...¥¨管理列表出参移除stats-修改接口-管理后台.md | 340 ++++++++++++++++++ 1 file changed, 340 insertions(+) create mode 100644 changelogs-v2/2026-10/05_8796_发票管理列表出参移除stats-修改接口-管理后台.md diff --git a/changelogs-v2/2026-10/05_8796_发票管理列表出参移除stats-修改接口-管理后台.md b/changelogs-v2/2026-10/05_8796_发票管理列表出参移除stats-修改接口-管理后台.md new file mode 100644 index 00000000..21defcca --- /dev/null +++ b/changelogs-v2/2026-10/05_8796_发票管理列表出参移除stats-修改接口-管理后台.md @@ -0,0 +1,340 @@ +--- +schema: "hl-changelog/v2" +ticket: "8796" +title: "发票管理列表出参移除顶部 stats 统计块(records / tabCounts 不变)" +consumer: "admin" +author: "yst" +change_type: "修改接口" +backend_status: "merged" +gateway_status: "not_required" +frontend_status: "pending" +frontend_owner: "" +frontend_ref: "" +target_release: "" +verified_at: "" +status_note: "产品决定下线发票管理列表顶部 4 张统计卡片;出参根级 stats 字段已删,tabCounts 角标计数保留。已合 dev-v3。前端需删除顶部统计卡片渲染逻辑。" +updated_at: "2026-10-05" +base: "dev-v3" +--- + +# order-v3 invoice:发票管理列表出参移除 stats 统计块(管理后台) + +> 注意:**破坏性变更(删字段)**:`GET /v3/admin/order/invoice/page` 出参根级 `stats` 字段已删除。前端若仍引用 `stats` 渲染顶部统计卡片,取到的将是 `undefined`,卡片会空白或异常,**必须同步下线该卡片渲染**。 + +## 1. 接口背景 + +管理后台「财务 → 发票管理」列表页顶部原有 4 张统计卡片:待开票 / 已开票·待推送 / 已推送 / 本月已开票,数据来自列表接口出参根级的 `stats` 数组。 + +产品决定不要这 4 张卡片了(#8796)。后端随之把 `stats` 统计块从列表接口出参整体移除,并清掉后端只为它服务的统计查询逻辑。列表行数据、tab 角标计数均不受影响。 + +## 2. 变更清单 + +| # | 接口 | 变更点 | 类型 | +|---|------|--------|------| +| 1 | `GET /v3/admin/order/invoice/page` | 出参根级删除 `stats` 字段(原 InvoiceStatItemVO 数组:4 项统计卡片数据) | 出参字段删除 | + +入参、路径、`records` 列表行结构、`tabCounts` 角标计数**全部不变**。 + +## 3. 接口详情 + +| 项 | 说明 | +|---|---| +| 服务 | hl-order-service-v3(端口 8086) | +| 路径 | `GET /v3/admin/order/invoice/page` | +| 使用场景 | 管理后台 → 财务 → 发票管理列表(分页 + tab 过滤 + 搜索) | +| 认证 | 管理后台登录态(JWT);网关既有路由 `/v3/admin/**`,无新增网关配置 | +| 幂等性 | 纯查询,天然幂等 | +| 限流 | 无特殊限流 | + +## 4. 接口入参 + +**入参零变化**(Query 参数): + +| 字段 | 类型 | 必填 | 说明 | +|------|------|------|------| +| pageNo | int | 否 | 页码,默认 1 | +| pageSize | int | 否 | 每页条数,默认 10 | +| tab | string | 否 | tab 过滤:REQUESTED(待开票)/ ISSUED(待推送)/ PUSHED(已推送)/ NONE(未申请)/ ALL(全部),默认 ALL | +| orderNo | string | 否 | 订单号模糊搜索 | +| contactName | string | 否 | 客户名(主联系人)模糊搜索 | +| titleName | string | 否 | 开票抬头模糊搜索(NONE tab 传此参数结果置空) | +| requestedBy | string | 否 | 申请人(定制师/用户姓名)模糊搜索 | + +## 5. 出参字段 + +响应统一包装 `Result`,`data` 结构如下。 + +### 5.1 顶层结构(变更后现状) + +| 字段 | 类型 | 说明 | +|------|------|------| +| records | array | 发票列表行(结构见 5.2) | +| total | long | 总条数 | +| page | int | 当前页码 | +| pageSize | int | 每页条数 | +| tabCounts | array | 各 tab 计数(**保留不变**,见 5.3) | +| ~~stats~~ | ~~array~~ | **已删除**,不再返回 | + +部署后实测出参顶层 keys = `["records", "total", "page", "pageSize", "tabCounts"]`,已无 `stats`。 + +### 5.2 records 列表行(InvoicePageItemRespVO,本次未动) + +| 字段 | 类型 | 说明 | +|------|------|------| +| id | string | 发票 ID(字符串防 JS 精度丢失) | +| orderId | string | 订单 ID(字符串) | +| orderNo | string | 订单号 | +| productName | string | 产品名 | +| productCoverImg | string | 产品封面图 URL | +| tierName | string | 档位名 | +| contactName | string | 客户名(主联系人) | +| customizerName | string | 定制师名 | +| departureDate | string(yyyy-MM-dd) | 出发日期 | +| adultCount | int | 成人数 | +| childCount | int | 儿童数 | +| youngChildCount | int | 婴儿/小童数 | +| invoiceType | string | 发票类型(VAT_NORMAL / VAT_SPECIAL) | +| invoiceTypeText | string | 发票类型文案 | +| titleType | string | 抬头类型(COMPANY / PERSONAL) | +| titleName | string | 开票抬头 | +| taxNo | string | 税号 | +| amount | number | 开票金额(元) | +| email | string | 收件邮箱 | +| status | string | 发票状态(REQUESTED / ISSUED / PUSHED / VOIDED) | +| statusText | string | 状态文案(待开票 / 已开票 / 已推送 / 已作废) | +| requestedBy | string | 申请人(定制师名或用户名) | +| requestedAt | string | 申请时间 | +| issuedAt | string | 开票时间(ISSUED 后有值) | +| issuedBy | string | 开票人(财务员工名) | +| invoiceNo | string | 发票号(财务登记) | +| fileUrl | string | 发票文件 URL(ISSUED/PUSHED 后有值) | +| pdfName | string | 发票 PDF 文件名 | +| pdfSize | long | 文件大小(字节) | +| teamNo | string | 团号 | +| createTime | string | 订单创建时间 | +| orderStatus | string | 订单状态 | +| orderStatusText | string | 订单状态文案 | +| flowStatus | string | 流程状态 | +| flowStatusText | string | 流程状态文案 | +| orderAmount | number | 订单应收总额(元) | +| paidAmount | number | 累计已收(元) | +| refundedAmount | number | 累计已退(元) | +| settlementAmount | number | 核单金额(元) | + +### 5.3 tabCounts 项(InvoiceTabCountVO,保留不变) + +固定 5 项,顺序:REQUESTED / ISSUED / PUSHED / NONE / ALL: + +| 字段 | 类型 | 说明 | +|------|------|------| +| code | string | 状态编码(REQUESTED / ISSUED / PUSHED / NONE / ALL) | +| name | string | 中文名(待开票 / 待推送 / 已推送 / 未申请 / 全部) | +| count | int | 计数 | + +tabCounts 为全局全量计数,**不受搜索条件影响**(此行为未变)。 + +## 6. 枚举 / 数据字典 + +本次无枚举变化。涉及枚举均为既有值: + +| 枚举 | 取值 | +|------|------| +| tab | REQUESTED / ISSUED / PUSHED / NONE / ALL | +| status(发票) | REQUESTED(待开票)/ ISSUED(已开票)/ PUSHED(已推送)/ VOIDED(已作废) | +| invoiceType | VAT_NORMAL / VAT_SPECIAL | +| titleType | COMPANY / PERSONAL | + +原 `stats[].code` 的 4 个取值(REQUESTED / ISSUED / PUSHED / CURRENT_MONTH_ISSUED)随字段一并废弃,不再有消费方。 + +## 7. 错误码 + +本接口为查询接口,正常情况无业务错误码。公共错误(未登录 / 无权限)走网关与全局异常处理。发票域业务错误码(5815xx 段,如 581500 发票不存在等)本次无变化,且本列表接口不抛出。 + +## 8. 示例 + +### 8.1 典型成功(REQUESTED tab,第一页) + +请求: + +``` +GET /v3/admin/order/invoice/page?tab=REQUESTED&pageNo=1&pageSize=10 +``` + +响应(注意顶层已无 stats): + +```json +{ + "code": 0, + "data": { + "records": [ + { + "id": "1975812345678901234", + "orderId": "1960123456789012345", + "orderNo": "2026092800001", + "productName": "呼伦贝尔草原 5 日定制游", + "productCoverImg": "https://oss.example.com/cover/abc.jpg", + "tierName": "舒适档", + "contactName": "张三", + "customizerName": "李定制", + "departureDate": "2026-10-15", + "adultCount": 2, + "childCount": 1, + "youngChildCount": 0, + "invoiceType": "VAT_NORMAL", + "invoiceTypeText": "增值税普通发票", + "titleType": "COMPANY", + "titleName": "北京某某科技有限公司", + "taxNo": "91110108MA01C8XH3B", + "amount": 12800.00, + "email": "zhangsan@example.com", + "status": "REQUESTED", + "statusText": "待开票", + "requestedBy": "李定制", + "requestedAt": "2026-10-01 10:23:45", + "issuedAt": null, + "issuedBy": null, + "invoiceNo": null, + "fileUrl": null, + "pdfName": null, + "pdfSize": null, + "teamNo": "T2026101501", + "createTime": "2026-09-28 14:02:11", + "orderStatus": "COMPLETED", + "orderStatusText": "已完成", + "flowStatus": "SETTLED", + "flowStatusText": "已核单", + "orderAmount": 12800.00, + "paidAmount": 12800.00, + "refundedAmount": 0.00, + "settlementAmount": 12800.00 + } + ], + "total": 1, + "page": 1, + "pageSize": 10, + "tabCounts": [ + { "code": "REQUESTED", "name": "待开票", "count": 1 }, + { "code": "ISSUED", "name": "待推送", "count": 3 }, + { "code": "PUSHED", "name": "已推送", "count": 12 }, + { "code": "NONE", "name": "未申请", "count": 45 }, + { "code": "ALL", "name": "全部", "count": 61 } + ] + }, + "msg": "" +} +``` + +### 8.2 边界情况(搜索无命中,空列表) + +请求: + +``` +GET /v3/admin/order/invoice/page?tab=ALL&titleName=不存在的公司名&pageNo=1&pageSize=10 +``` + +响应(records 空数组、total=0,**tabCounts 仍为全局计数**,无 stats): + +```json +{ + "code": 0, + "data": { + "records": [], + "total": 0, + "page": 1, + "pageSize": 10, + "tabCounts": [ + { "code": "REQUESTED", "name": "待开票", "count": 1 }, + { "code": "ISSUED", "name": "待推送", "count": 3 }, + { "code": "PUSHED", "name": "已推送", "count": 12 }, + { "code": "NONE", "name": "未申请", "count": 45 }, + { "code": "ALL", "name": "全部", "count": 61 } + ] + }, + "msg": "" +} +``` + +### 8.3 业务失败(未登录 / token 失效) + +请求: + +``` +GET /v3/admin/order/invoice/page?tab=ALL +(不带 Authorization 头) +``` + +响应: + +```json +{ + "code": 401, + "data": null, + "msg": "未登录或登录已过期" +} +``` + +## 9. 业务边界 + +- **适用**:财务在管理后台发票管理列表做分页浏览、tab 切换、按订单号/客户名/抬头/申请人搜索;tab 角标计数展示。 +- **不适用**:任何需要「待开票 / 已开票 / 已推送 / 本月已开票」汇总卡片数据的场景 —— 后端已不再提供该汇总,前端**不要**自行用 tabCounts 拼凑原 stats 语义(原 stats 含金额合计与「本月已开票」口径,tabCounts 只有张数且无金额维度,CURRENT_MONTH_ISSUED 当月维度无任何替代数据源)。 +- **特殊边界**:VOIDED(已作废)发票不进任何 tab,也不计入 tabCounts;NONE tab 传 titleName / requestedBy 搜索时结果强制为空(既有行为,未变)。 + +## 10. 修改前后对比 + +### 10.1 出参顶层结构对比 + +| 顶层字段 | 修改前 | 修改后 | +|---------|--------|--------| +| records | 有 | 有(不变) | +| total | 有 | 有(不变) | +| page | 有 | 有(不变) | +| pageSize | 有 | 有(不变) | +| tabCounts | 有 | 有(不变) | +| stats | 有(4 项统计数组) | **已删除** | + +### 10.2 被删除的 stats 项结构(原 InvoiceStatItemVO,仅作存档) + +原 `stats` 为固定 4 项数组,顺序 REQUESTED / ISSUED / PUSHED / CURRENT_MONTH_ISSUED: + +| 字段 | 类型 | 说明 | +|------|------|------| +| code | string | 状态编码(REQUESTED / ISSUED / PUSHED / CURRENT_MONTH_ISSUED) | +| name | string | 中文名(待开票 / 已开票·待推送 / 已推送 / 本月已开票) | +| count | int | 张数 | +| amount | number | 合计金额(元) | + +### 10.3 行为级对比 + +| 场景 | 修改前 | 修改后 | +|------|--------|--------| +| 列表查询性能 | 每次查询额外执行统计聚合(按状态计数 + 金额合计、本月口径) | 不再执行统计聚合,查询更轻 | +| tabCounts 值 | 全量计数不受搜索影响 | 同左(不变) | +| 前端顶部卡片 | 可用 stats 渲染 4 张卡片 | 数据源消失,卡片必须下线 | + +## 11. 影响评估 / 回滚 + +### 11.1 影响评估 + +- **破坏兼容**:是(删出参字段)。 +- 前端若仍引用 `data.stats` → 取到 `undefined`,顶部卡片空白或渲染异常(接口本身正常返回,不会报错)。 +- **需要前端同步上线**:是。发票管理页须删除顶部统计卡片渲染逻辑。上线顺序建议:前端先删卡片上线(安全,后端 stats 仍在但无人消费),后端版本随后生效;反向顺序则会出现卡片空白窗口。 +- tab 角标、列表行、搜索、分页逻辑零改动。 + +### 11.2 回滚方案 + +- 后端回滚 = revert PR #8797(恢复 stats 字段与统计查询)。 +- 前端如已删卡片渲染,回滚后端后卡片无数据渲染,需同步回滚前端或保持卡片下线(产品决定下线,原则上不回滚)。 + +## 12. 注意事项 + +1. **前端必做**:删除发票管理列表页顶部 4 张统计卡片(待开票 / 已开票·待推送 / 已推送 / 本月已开票)的全部渲染逻辑与相关样式,清理对 `data.stats` / `stats[]` 的所有引用与类型定义。 +2. 不要试图用 `tabCounts` 还原原统计卡片:原 stats 含金额合计(amount)与「本月已开票」(CURRENT_MONTH_ISSUED)口径,tabCounts 无此数据。 +3. 若产品后续需要恢复统计卡片,属新需求,需重新走 Issue 排期,不是回滚本变更。 +4. 本变更只影响 `GET /v3/admin/order/invoice/page` 一个接口;发票详情(`GET /v3/admin/order/invoice/{id}`)、开票 / 重传 / 推送等接口均未动。 + +## 13. 关联 / 联系人 + +- Issue:https://git.1814.love/wx/HL/issues/8796 +- PR:https://git.1814.love/wx/HL/pulls/8797 +- Commit:https://git.1814.love/wx/HL/commit/ba01a0719a +- 后端负责人:@yst