# 发票服务 API 文档

## 基本信息

- **服务地址**: `http://localhost:8086`
- **API版本**: v1
- **Base Path**: `/api/invoices`

## 认证

所有API请求需要在Header中传递用户信息：
- `X-User-Id`: 用户ID
- `X-User-Name`: 用户名称

---

## 接口列表

### 1. 获取发票列表

**GET** `/api/invoices`

分页查询发票列表

**请求参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| tenantId | Long | 否 | 租户ID |
| status | Integer | 否 | 发票状态：0-待审核, 1-已开具, 2-已作废, 3-已红冲 |
| invoiceType | Integer | 否 | 发票类型：1-专用发票, 2-普通发票, 3-电子发票, 4-卷式发票 |
| keyword | String | 否 | 关键词搜索（发票号、购方名称、订单号） |
| startDate | String | 否 | 开始日期 (yyyy-MM-dd) |
| endDate | String | 否 | 结束日期 (yyyy-MM-dd) |
| page | Integer | 否 | 页码，默认1 |
| size | Integer | 否 | 每页数量，默认20 |

**响应示例:**
```json
{
  "list": [
    {
      "id": 1,
      "invoiceNo": "INV20260404001",
      "invoiceType": 2,
      "invoiceTypeName": "增值税普通发票",
      "status": 1,
      "statusName": "已开具",
      "buyerName": "测试公司",
      "buyerTaxNo": "91110000XXXXXXXX",
      "totalAmount": 1130.00,
      "amount": 1000.00,
      "taxAmount": 130.00,
      "taxRate": 0.13,
      "invoiceDate": "2026-04-04",
      "applyDate": "2026-04-03",
      "createdAt": "2026-04-03T10:00:00"
    }
  ],
  "total": 100,
  "current_page": 1,
  "last_page": 5,
  "page_size": 20
}
```

---

### 2. 获取发票详情

**GET** `/api/invoices/{id}`

根据ID获取发票详细信息

**路径参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | Long | 是 | 发票ID |

**响应示例:**
```json
{
  "id": 1,
  "invoiceNo": "INV20260404001",
  "invoiceCode": "144031900110",
  "invoiceType": 2,
  "invoiceTypeName": "增值税普通发票",
  "status": 1,
  "statusName": "已开具",
  "buyerName": "测试公司",
  "buyerTaxNo": "91110000XXXXXXXX",
  "buyerAddressPhone": "北京市朝阳区 010-12345678",
  "buyerBankAccount": "中国银行 123456789",
  "sellerName": "销售公司",
  "sellerTaxNo": "91110000YYYYYYYY",
  "totalAmount": 1130.00,
  "amount": 1000.00,
  "taxAmount": 130.00,
  "taxRate": 0.13,
  "orderId": 100,
  "orderNo": "ORD20260401001",
  "customerId": 50,
  "customerName": "测试客户",
  "invoiceContent": "咨询服务",
  "drawer": "开票人",
  "reviewer": "复核人",
  "payee": "收款人",
  "invoiceDate": "2026-04-04",
  "applyDate": "2026-04-03",
  "pdfPath": "/files/invoices/2026/04/INV20260404001.pdf",
  "imagePath": "/files/invoices/2026/04/INV20260404001.png",
  "applicantId": 10,
  "applicantName": "张三",
  "auditorId": 20,
  "auditorName": "李四",
  "issuerId": 30,
  "issuerName": "王五",
  "items": [
    {
      "id": 1,
      "goodsName": "咨询服务",
      "spec": "标准版",
      "unit": "次",
      "quantity": 1.0000,
      "unitPrice": 1130.00,
      "amount": 1000.00,
      "taxRate": 0.13,
      "taxAmount": 130.00,
      "totalAmount": 1130.00
    }
  ]
}
```

---

### 3. 根据发票号获取发票

**GET** `/api/invoices/no/{invoiceNo}`

**路径参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| invoiceNo | String | 是 | 发票号 |

---

### 4. 创建发票申请

**POST** `/api/invoices`

**请求体:**
```json
{
  "invoiceType": 2,
  "buyerName": "测试公司",
  "buyerTaxNo": "91110000XXXXXXXX",
  "buyerAddressPhone": "北京市朝阳区 010-12345678",
  "buyerBankAccount": "中国银行 123456789",
  "totalAmount": 1130.00,
  "amount": 1000.00,
  "taxAmount": 130.00,
  "taxRate": 0.13,
  "orderId": 100,
  "orderNo": "ORD20260401001",
  "customerId": 50,
  "customerName": "测试客户",
  "invoiceContent": "咨询服务",
  "remark": "备注信息",
  "items": [
    {
      "goodsName": "咨询服务",
      "spec": "标准版",
      "unit": "次",
      "quantity": 1.0000,
      "unitPrice": 1130.00,
      "amount": 1000.00,
      "taxRate": 0.13,
      "taxAmount": 130.00,
      "totalAmount": 1130.00
    }
  ]
}
```

**响应:** 返回创建的发票详情

---

### 5. 更新发票申请

**PUT** `/api/invoices/{id}`

仅允许更新待审核状态的发票

**路径参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | Long | 是 | 发票ID |

**请求体:** 同创建发票申请

---

### 6. 删除发票申请

**DELETE** `/api/invoices/{id}`

仅允许删除待审核状态的发票

**路径参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | Long | 是 | 发票ID |

---

### 7. 审核发票申请

**POST** `/api/invoices/{id}/audit`

**路径参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | Long | 是 | 发票ID |

**请求参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| auditStatus | Integer | 是 | 审核状态：1-通过, 0-拒绝 |
| auditRemark | String | 否 | 审核备注 |

**响应:** 返回审核后的发票详情

---

### 8. 开具发票

**POST** `/api/invoices/{id}/issue`

**路径参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | Long | 是 | 发票ID |

**请求参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| invoiceNo | String | 是 | 发票号码 |
| invoiceCode | String | 否 | 发票代码 |
| invoiceDate | String | 否 | 开票日期 (yyyy-MM-dd)，默认当天 |
| drawer | String | 否 | 开票人 |
| reviewer | String | 否 | 复核人 |
| payee | String | 否 | 收款人 |

**响应:** 返回开具后的发票详情

---

### 9. 作废发票

**POST** `/api/invoices/{id}/void`

**路径参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | Long | 是 | 发票ID |

**请求参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| reason | String | 是 | 作废原因 |

**响应:** 返回作废后的发票详情

---

### 10. 红冲发票

**POST** `/api/invoices/{id}/reverse`

**路径参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | Long | 是 | 发票ID |

**请求参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| reason | String | 是 | 红冲原因 |

**响应:** 返回红冲后的发票详情

---

### 11. 根据订单ID获取发票列表

**GET** `/api/invoices/order/{orderId}`

**路径参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| orderId | Long | 是 | 订单ID |

---

### 12. 根据客户ID获取发票列表

**GET** `/api/invoices/customer/{customerId}`

**路径参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| customerId | Long | 是 | 客户ID |

---

### 13. 获取租户已开具发票总金额

**GET** `/api/invoices/tenant/{tenantId}/amount`

**路径参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| tenantId | Long | 是 | 租户ID |

**响应示例:**
```json
100000.00
```

---

### 14. 获取日期范围内发票数量

**GET** `/api/invoices/tenant/{tenantId}/count`

**路径参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| tenantId | Long | 是 | 租户ID |

**请求参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| startDate | String | 是 | 开始日期 (yyyy-MM-dd) |
| endDate | String | 是 | 结束日期 (yyyy-MM-dd) |

**响应示例:**
```json
10
```

---

### 15. 更新发票PDF路径

**PUT** `/api/invoices/{id}/pdf`

**路径参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | Long | 是 | 发票ID |

**请求参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| pdfPath | String | 是 | PDF文件路径 |

---

### 16. 更新发票图片路径

**PUT** `/api/invoices/{id}/image`

**路径参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | Long | 是 | 发票ID |

**请求参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| imagePath | String | 是 | 图片文件路径 |

---

### 17. 获取发票明细

**GET** `/api/invoices/{id}/items`

**路径参数:**

| 参数 | 类型 | 必填 | 说明 |
|------|------|------|------|
| id | Long | 是 | 发票ID |

---

## 错误码

| 错误码 | 说明 |
|--------|------|
| INVOICE_ERROR | 发票业务异常 |
| VALIDATION_ERROR | 参数校验失败 |
| SYSTEM_ERROR | 系统异常 |

---

## 发票状态流转

```
待审核(0) --> 已开具(1) --> 已作废(2)
                    |
                    +--> 已红冲(3)
                    
待审核(0) --> 已作废(2) (审核拒绝)
```
