- 新增 GET /v3/admin/order/invoice/{id} 发票详情接口(全量字段含专票四项/开票痕迹/推送痕迹)
- GET /v3/admin/order/invoice/page 列表行新增 9 个订单冗余字段
- tab 入参新增 NONE(未申请,代客申请候选)
- tabCounts 和 stats 从扁平对象改为数组(破坏性)
9.6 KiB
9.6 KiB
发票详情接口(财务开票弹窗 / 详情页)
变更类型:新增接口 端类型:管理后台 日期:2026-06-23 | Issue:#4258 | PR:#4262 | 服务:hl-order-service-v3
接口背景
财务在「上传发票 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 |
string | 开票金额,单位分,字符串防精度丢失,如 "98600" |
email |
string / null | 电子发票接收邮箱 |
mailAddress |
string / null | 纸质发票邮寄地址,电子发票为 null |
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 有值 |
ELECTRONIC |
电子发票 | 电子普票,mailAddress 为 null,仅 email 有值 |
抬头类型(titleType)
| 枚举值 | 中文名 |
|---|---|
COMPANY |
企业 |
PERSONAL |
个人 |
发票状态(status)
| 枚举值 | 中文名 | 说明 |
|---|---|---|
REQUESTED |
待开票 | 申请已提交,财务未处理 |
ISSUED |
已开票(待推送) | 财务已上传 PDF,尚未推送给客户 |
PUSHED |
已推送 | 已推送给客户 |
VOIDED |
已作废 | 该发票已作废 |
错误码
| 错误码 | 含义 | 触发场景 |
|---|---|---|
581500 |
发票不存在 | 传入的 id 在库中不存在或已软删除 |
401 |
未授权 | 未携带有效 JWT |
403 |
无权限 | 当前账号无发票管理权限 |
示例
典型成功(REQUESTED 状态,普票,全字段)
请求:
GET /v3/admin/order/invoice/1934567890123456789
Authorization: Bearer <token>
响应:
{
"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": "98600",
"email": "finance@hulalv.com",
"mailAddress": null,
"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>
响应:
{
"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": "150000",
"email": null,
"mailAddress": "上海市浦东新区财务部",
"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>
响应:
{
"code": 581500,
"msg": "发票不存在",
"data": null
}
业务边界
适用场景
- 财务在「上传发票 PDF」弹窗打开时调用,回显完整申请明细
- 发票详情页查看全量开票及推送信息
不适用场景
- 批量查询多张发票(用列表接口
GET /v3/admin/order/invoice/page) - 小程序端查询发票(本接口仅管理后台)
特殊边界
- 专票四项字段(
bankName/bankAccount/registAddress/registPhone):仅invoiceType=VAT_SPECIAL时有值,前端按 invoiceType 决定是否展示这四项 - 开票痕迹字段(
invoiceNo/fileUrl/pdfName/pdfSize/issuedBy/issuedAt):状态为ISSUED或PUSHED时有值,REQUESTED和VOIDED时为 null - 推送痕迹字段(
pushedAt/pushedChannels):仅PUSHED时有值 amount单位为分,前端展示时除以 100 转为元
注意事项
id/orderId为 Long 雪花 ID,前端必须以字符串接收,不可用 JS number 类型(会丢失精度)amount单位为分,字符串格式,展示时除以 100 转为元pdfSize单位为字节,字符串格式,展示时自行换算为 KB / MBpushedChannels未推送时为 null,不是空数组[],前端判断时注意区分
关联 / 联系人
| 项 | 内容 |
|---|---|
| Issue | #4258 发票详情接口 |
| PR | #4262 |
| 后端负责人 | yst |