修正范围: - 23_4290_发票申请入参票种修正-修改接口-管理后台.md - 23_4290_发票申请票种修正-修改接口-小程序端.md - 23_4258_发票详情接口-新增接口-管理后台.md - 23_4265_发票列表page结构调整-修改接口-管理后台.md 主要变更(4份文件均已对齐最终线上契约): 1. amount 入参/出参全部改为 JSON number(单位元,如 986.00), 原「integer 分/字符串分/×100」描述已作废 2. 各文件顶部勘误节追加「截至 PR #4311 收口」条目, 关联 Issue #4290/#4296/#4310、PR #4292/#4302/#4311 3. 详情接口边界示例:专票 email 由 null 改为始终有值(全电子交付) 4. 列表接口:records.amount 和 stats.amount 均改为 number 类型
316 行
10 KiB
Markdown
316 行
10 KiB
Markdown
# 发票详情接口(财务开票弹窗 / 详情页)
|
||
|
||
> 变更类型:新增接口
|
||
> 端类型:管理后台
|
||
> 日期:2026-06-23 | Issue:#4258 | PR:#4262 | 服务:hl-order-service-v3
|
||
|
||
---
|
||
|
||
> **勘误(2026-06-23,#4292 #4302)**:本文件初版(#4262)包含 3 处与最终实现不符的内容,已在本次修正:
|
||
> 1. `invoiceType` 枚举已删除 `ELECTRONIC`(电子发票),只保留 `VAT_NORMAL`(增值税普通发票)和 `VAT_SPECIAL`(增值税专用发票)
|
||
> 2. 出参已删除 `mailAddress` 字段(无纸质邮寄,全电子交付)
|
||
> 3. `email` 字段始终有值(全电子交付),不再是"电子发票为 null"
|
||
> 4. `amount` 字段改为 JSON number(单位**元**,如 `986.00`),原「字符串/单位分」均已作废;边界示例专票 `email` 由 null 改为始终有值(全电子交付)。关联 PR [#4311](https://git.1814.love:8443/wx/HL/pulls/4311),Issue [#4290](https://git.1814.love:8443/wx/HL/issues/4290) [#4310](https://git.1814.love:8443/wx/HL/issues/4310)。
|
||
|
||
## 接口背景
|
||
|
||
财务在「上传发票 PDF」弹窗或发票详情页中,需要读取完整的开票申请明细:抬头信息、开票金额、专票四项(银行账号、注册地址、注册电话)、开票后的发票号 / PDF / 推送记录。本接口返回单张发票的全量字段,供弹窗回显和详情页展示使用。
|
||
|
||
---
|
||
|
||
## 变更清单
|
||
|
||
| # | 变更类型 | 说明 |
|
||
|---|---------|------|
|
||
| 1 | 新增接口 | `GET /v3/admin/order/invoice/{id}` 发票详情 |
|
||
|
||
---
|
||
|
||
## 接口详情
|
||
|
||
| 项 | 说明 |
|
||
|---|------|
|
||
| **方法 + 路径** | `GET /v3/admin/order/invoice/{id}` |
|
||
| **接口名** | 发票详情(财务开票弹窗 / 详情页) |
|
||
| **描述** | 返回单张发票的完整申请明细、状态、开票痕迹、推送痕迹及订单冗余信息 |
|
||
| **认证** | 管理后台 JWT(Bearer Token) |
|
||
| **幂等性** | 只读,天然幂等 |
|
||
| **限流** | 无特殊限流 |
|
||
|
||
---
|
||
|
||
## 接口入参
|
||
|
||
### 路径参数
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
|--------|------|------|------|
|
||
| `id` | string(Long 雪花 ID) | 是 | 发票 ID,前端以字符串传输防精度丢失 |
|
||
|
||
### 请求体
|
||
|
||
无。
|
||
|
||
---
|
||
|
||
## 出参字段
|
||
|
||
返回结构:`Result<AdminInvoiceDetailRespVO>`
|
||
|
||
### 标识字段
|
||
|
||
| 字段名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| `id` | string | 发票 ID(雪花 ID,字符串) |
|
||
| `orderId` | string | 所属订单 ID |
|
||
| `orderNo` | string | 订单编号,如 `ORD2026062300001` |
|
||
|
||
### 开票申请明细
|
||
|
||
| 字段名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| `invoiceType` | string | 发票类型枚举值,见枚举节 |
|
||
| `invoiceTypeText` | string | 发票类型中文名,如「增值税普通发票」 |
|
||
| `titleType` | string | 抬头类型,`COMPANY` 或 `PERSONAL` |
|
||
| `titleName` | string | 发票抬头(企业名称或个人姓名) |
|
||
| `taxNo` | string / null | 税号,个人抬头为 null |
|
||
| `bankName` | string / null | 开户银行,**仅专票**有值,其余 null |
|
||
| `bankAccount` | string / null | 银行账号,**仅专票**有值,其余 null |
|
||
| `registAddress` | string / null | 注册地址,**仅专票**有值,其余 null |
|
||
| `registPhone` | string / null | 注册电话,**仅专票**有值,其余 null |
|
||
| `amount` | number | 开票金额,JSON number,单位**元**(如 `986.00`) |
|
||
| `email` | string | 收件邮箱(始终有值,全电子交付) |
|
||
| `applyReason` | string / null | 备注(申请原因) |
|
||
|
||
### 状态字段
|
||
|
||
| 字段名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| `status` | string | 发票状态枚举值,见枚举节 |
|
||
| `statusText` | string | 发票状态中文名,如「待开票」 |
|
||
| `requestedBy` | string / null | 申请人姓名 |
|
||
| `requestedAt` | string / null | 申请时间,ISO 8601,如 `"2026-06-20T14:30:00"` |
|
||
|
||
### 开票痕迹(ISSUED 后有值)
|
||
|
||
| 字段名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| `invoiceNo` | string / null | 发票号码,开票后回填 |
|
||
| `fileUrl` | string / null | 发票 PDF 下载 URL(OSS 直链),开票后回填 |
|
||
| `pdfName` | string / null | PDF 文件名,如 `"invoice_202606230001.pdf"` |
|
||
| `pdfSize` | string / null | PDF 大小(字节数),字符串,如 `"204800"` |
|
||
| `issuedBy` | string / null | 开票操作人姓名 |
|
||
| `issuedAt` | string / null | 开票时间,ISO 8601 |
|
||
|
||
### 推送痕迹(PUSHED 后有值)
|
||
|
||
| 字段名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| `pushedAt` | string / null | 推送时间,ISO 8601 |
|
||
| `pushedChannels` | array(string) / null | 推送渠道列表,如 `["EMAIL","WECHAT"]`;未推送为 null |
|
||
|
||
### 订单冗余字段
|
||
|
||
| 字段名 | 类型 | 说明 |
|
||
|--------|------|------|
|
||
| `productName` | string | 产品名称 |
|
||
| `tierName` | string / null | 产品档次名称 |
|
||
| `contactName` | string | 客户联系人姓名 |
|
||
| `customizerName` | string / null | 定制师姓名 |
|
||
| `departureDate` | string | 出发日期,格式 `YYYY-MM-DD` |
|
||
|
||
---
|
||
|
||
## 枚举 / 数据字典
|
||
|
||
### 发票类型(invoiceType)
|
||
|
||
| 枚举值 | 中文名 | 说明 |
|
||
|--------|--------|------|
|
||
| `VAT_NORMAL` | 增值税普通发票 | 普票,专票四项字段均为 null |
|
||
| `VAT_SPECIAL` | 增值税专用发票 | 专票,bankName / bankAccount / registAddress / registPhone 有值 |
|
||
|
||
### 抬头类型(titleType)
|
||
|
||
| 枚举值 | 中文名 |
|
||
|--------|--------|
|
||
| `COMPANY` | 企业 |
|
||
| `PERSONAL` | 个人 |
|
||
|
||
### 发票状态(status)
|
||
|
||
| 枚举值 | 中文名 | 说明 |
|
||
|--------|--------|------|
|
||
| `REQUESTED` | 待开票 | 申请已提交,财务未处理 |
|
||
| `ISSUED` | 已开票(待推送) | 财务已上传 PDF,尚未推送给客户 |
|
||
| `PUSHED` | 已推送 | 已推送给客户 |
|
||
| `VOIDED` | 已作废 | 该发票已作废 |
|
||
|
||
---
|
||
|
||
## 错误码
|
||
|
||
| 错误码 | 含义 | 触发场景 |
|
||
|--------|------|---------|
|
||
| `581500` | 发票不存在 | 传入的 `id` 在库中不存在或已软删除 |
|
||
| `401` | 未授权 | 未携带有效 JWT |
|
||
| `403` | 无权限 | 当前账号无发票管理权限 |
|
||
|
||
---
|
||
|
||
## 示例
|
||
|
||
### 典型成功(REQUESTED 状态,普票,全字段)
|
||
|
||
请求:
|
||
```
|
||
GET /v3/admin/order/invoice/1934567890123456789
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
响应:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"id": "1934567890123456789",
|
||
"orderId": "1920000000000000001",
|
||
"orderNo": "ORD2026062300001",
|
||
"invoiceType": "VAT_NORMAL",
|
||
"invoiceTypeText": "增值税普通发票",
|
||
"titleType": "COMPANY",
|
||
"titleName": "呼籁科技有限公司",
|
||
"taxNo": "91310000XXXXXXXXXX",
|
||
"bankName": null,
|
||
"bankAccount": null,
|
||
"registAddress": null,
|
||
"registPhone": null,
|
||
"amount": 986.00,
|
||
"email": "finance@hulalv.com",
|
||
"applyReason": "报销使用",
|
||
"status": "REQUESTED",
|
||
"statusText": "待开票",
|
||
"requestedBy": "张三",
|
||
"requestedAt": "2026-06-20T14:30:00",
|
||
"invoiceNo": null,
|
||
"fileUrl": null,
|
||
"pdfName": null,
|
||
"pdfSize": null,
|
||
"issuedBy": null,
|
||
"issuedAt": null,
|
||
"pushedAt": null,
|
||
"pushedChannels": null,
|
||
"productName": "云南香格里拉深度游5日",
|
||
"tierName": "标准档",
|
||
"contactName": "李四",
|
||
"customizerName": "王五",
|
||
"departureDate": "2026-07-10"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 边界情况(ISSUED 状态,含 fileUrl / invoiceNo,专票四项有值)
|
||
|
||
请求:
|
||
```
|
||
GET /v3/admin/order/invoice/1934567890123456790
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
响应:
|
||
```json
|
||
{
|
||
"code": 200,
|
||
"msg": "success",
|
||
"data": {
|
||
"id": "1934567890123456790",
|
||
"orderId": "1920000000000000002",
|
||
"orderNo": "ORD2026062200001",
|
||
"invoiceType": "VAT_SPECIAL",
|
||
"invoiceTypeText": "增值税专用发票",
|
||
"titleType": "COMPANY",
|
||
"titleName": "某某贸易有限公司",
|
||
"taxNo": "91310000YYYYYYYYYY",
|
||
"bankName": "工商银行上海支行",
|
||
"bankAccount": "6222 0000 0000 0001",
|
||
"registAddress": "上海市浦东新区XX路XX号",
|
||
"registPhone": "021-12345678",
|
||
"amount": 1500.00,
|
||
"email": "finance@company.com",
|
||
"applyReason": null,
|
||
"status": "ISSUED",
|
||
"statusText": "已开票(待推送)",
|
||
"requestedBy": "赵六",
|
||
"requestedAt": "2026-06-21T09:00:00",
|
||
"invoiceNo": "20260623000001",
|
||
"fileUrl": "https://oss.hulalv.com/invoice/202606/invoice_20260623000001.pdf",
|
||
"pdfName": "invoice_20260623000001.pdf",
|
||
"pdfSize": "204800",
|
||
"issuedBy": "财务小陈",
|
||
"issuedAt": "2026-06-22T16:00:00",
|
||
"pushedAt": null,
|
||
"pushedChannels": null,
|
||
"productName": "西藏拉萨朝圣7日",
|
||
"tierName": "尊享档",
|
||
"contactName": "赵六",
|
||
"customizerName": "孙七",
|
||
"departureDate": "2026-08-01"
|
||
}
|
||
}
|
||
```
|
||
|
||
### 业务失败(发票不存在)
|
||
|
||
请求:
|
||
```
|
||
GET /v3/admin/order/invoice/9999999999999999999
|
||
Authorization: Bearer <token>
|
||
```
|
||
|
||
响应:
|
||
```json
|
||
{
|
||
"code": 581500,
|
||
"msg": "发票不存在",
|
||
"data": null
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 业务边界
|
||
|
||
**适用场景**
|
||
- 财务在「上传发票 PDF」弹窗打开时调用,回显完整申请明细
|
||
- 发票详情页查看全量开票及推送信息
|
||
|
||
**不适用场景**
|
||
- 批量查询多张发票(用列表接口 `GET /v3/admin/order/invoice/page`)
|
||
- 小程序端查询发票(本接口仅管理后台)
|
||
|
||
**特殊边界**
|
||
- 专票五项字段(`taxNo` / `bankName` / `bankAccount` / `registAddress` / `registPhone`):taxNo 普票公司抬头也需填,专票四项仅 `invoiceType=VAT_SPECIAL` 时有值,前端按 invoiceType 决定是否展示
|
||
- 开票痕迹字段(`invoiceNo` / `fileUrl` / `pdfName` / `pdfSize` / `issuedBy` / `issuedAt`):状态为 `ISSUED` 或 `PUSHED` 时有值,`REQUESTED` 和 `VOIDED` 时为 null
|
||
- 推送痕迹字段(`pushedAt` / `pushedChannels`):仅 `PUSHED` 时有值
|
||
- `amount` 为 JSON number,单位**元**(如 `986.00`),前端直接渲染,无需除以 100
|
||
|
||
---
|
||
|
||
## 注意事项
|
||
|
||
1. `id` / `orderId` 为 Long 雪花 ID,前端必须以**字符串**接收,不可用 JS number 类型(会丢失精度)
|
||
2. `amount` 为 JSON number,单位**元**(如 `986.00`),前端直接渲染,无需除以 100
|
||
3. `pdfSize` 单位为**字节**,字符串格式,展示时自行换算为 KB / MB
|
||
4. `pushedChannels` 未推送时为 null,不是空数组 `[]`,前端判断时注意区分
|
||
|
||
---
|
||
|
||
## 关联 / 联系人
|
||
|
||
| 项 | 内容 |
|
||
|----|------|
|
||
| **Issue** | [#4258 发票详情接口](https://git.1814.love:8443/wx/HL/issues/4258) |
|
||
| **PR** | [#4262](https://git.1814.love:8443/wx/HL/pulls/4262) |
|
||
| **后端负责人** | yst |
|