feat: Implement initial customer authorization code and invoice management modules with API documentation and configuration.
This commit is contained in:
1 parent
c3d0f4aa2a
commit
b65b4ac801
10 files changed
+708
-251
No files matched your search
@@ -0,0 +1,80 @@
|
|||||||
|
# 2026.2.24-用户端发票申请修改
|
||||||
|
|
||||||
|
## 1. 需求背景
|
||||||
|
目前用户申请发票后,如果被管理员驳回(状态为 `rejected`),用户无法修改该申请信息并重新提交。由于每个订单只能关联一个发票记录,用户也无法为该订单重新发起新的申请。因此需要增加一个发票修改接口,允许用户在驳回状态下编辑发票信息并重新进入待处理状态。
|
||||||
|
|
||||||
|
## 2. 业务流程
|
||||||
|
1. **用户侧**:查看发票详情,发现状态为“已驳回”,查看“驳回原因”和“修改建议”。
|
||||||
|
2. **用户侧**:点击修改,编辑发票抬头、税号、邮箱等信息。
|
||||||
|
3. **提交修改**:调用修改接口。
|
||||||
|
- 系统校验发票当前状态必须为 `rejected`。
|
||||||
|
- 系统校验发票所属权。
|
||||||
|
- 系统更新发票信息,并将状态重置为 `pending`。
|
||||||
|
- 系统清空原有的驳回信息(可选,或保留历史但在界面不再作为当前驳回提示)。
|
||||||
|
4. **管理侧**:发票重新出现在待处理列表中。
|
||||||
|
|
||||||
|
## 3. 接口设计
|
||||||
|
|
||||||
|
### 3.1 修改发票申请 (客户端)
|
||||||
|
|
||||||
|
- **接口地址**:`PUT /api/cu/invoices/{id}`
|
||||||
|
- **鉴权**:需要客户端登录态 (`CustomerAuth`)
|
||||||
|
- **请求参数 (JSON Body)**:
|
||||||
|
|
||||||
|
| 字段名 | 类型 | 必填 | 说明 |
|
||||||
|
| :--- | :--- | :--- | :--- |
|
||||||
|
| invoice_type | string | 是 | 发票类型: personal/enterprise/vat_special |
|
||||||
|
| receiver_email| string | 是 | 收票邮箱 |
|
||||||
|
| title | string | 是 | 发票抬头 |
|
||||||
|
| taxpayer_id | string | 否 | 纳税人识别号 (企业类型必填) |
|
||||||
|
| content | string | 否 | 开票内容 |
|
||||||
|
| remark | string | 否 | 备注 |
|
||||||
|
|
||||||
|
> [!NOTE]
|
||||||
|
> `order_id` 不允许修改,因为发票记录与订单是一一绑定的。
|
||||||
|
|
||||||
|
- **逻辑校验**:
|
||||||
|
1. **存在性校验**:发票 ID 必须存在。
|
||||||
|
2. **权限校验**:发票必须属于当前登录的客户用户 (`cu_user_id`)。
|
||||||
|
3. **状态校验**:只有 `status = 'rejected'` 的发票允许修改。若状态为 `pending` 或 `issued`,则返回错误。
|
||||||
|
4. **字段校验**:与创建发票时的校验逻辑一致(如企业类型必须有税号)。
|
||||||
|
|
||||||
|
- **数据更新**:
|
||||||
|
- 更新传入的业务字段。
|
||||||
|
- `status` 更新为 `pending`。
|
||||||
|
- `updated_at` 更新为当前时间。
|
||||||
|
- `reject_reason`、`suggestion`、`rejected_at`、`rejected_by` 建议清空,以表示这是一次全新的提交。
|
||||||
|
|
||||||
|
### 3.2 响应示例
|
||||||
|
|
||||||
|
**成功响应**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": "000000",
|
||||||
|
"message": "成功",
|
||||||
|
"data": {
|
||||||
|
"id": "invoice-uuid",
|
||||||
|
"invoice_no": "INV20260224001",
|
||||||
|
"status": "pending"
|
||||||
|
},
|
||||||
|
"timestamp": "2026-02-24T18:00:00Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**失败响应 (状态错误)**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"code": "700004",
|
||||||
|
"message": "发票当前状态不允许该操作",
|
||||||
|
"timestamp": "2026-02-24T18:00:00Z"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 4. 影响范围
|
||||||
|
- **后端模型**:需新增 `InvoiceUpdateRequest` 结构体。
|
||||||
|
- **后端服务**:`CuInvoiceService` 新增 `UpdateInvoice` 方法。
|
||||||
|
- **后端接口**:`router.go` 注册新路由。
|
||||||
|
- **前端**:发票详情页增加修改按钮(仅在驳回时显示),跳转至编辑页。
|
||||||
|
|
||||||
|
## 5. 错误码补充
|
||||||
|
- `700006`: 发票当前状态不允许修改 (如果 700004 语义不够具体可以新增,或沿用 700004)。
|
||||||
@@ -2,8 +2,10 @@
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# 使用默认配置
|
# 使用默认配置
|
||||||
go run cmd/main.go
|
cd cmd
|
||||||
|
go run .
|
||||||
|
|
||||||
# 指定配置文件
|
# 指定配置文件
|
||||||
|
cd cmd
|
||||||
go run . -config configs/config.dev.yaml
|
go run . -config configs/config.dev.yaml
|
||||||
```
|
```
|
||||||
+193
-129
@@ -1,17 +1,10 @@
|
|||||||
// Package swagger GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
|
// Code generated by swaggo/swag. DO NOT EDIT.
|
||||||
// This file was generated by swaggo/swag
|
|
||||||
package swagger
|
package swagger
|
||||||
|
|
||||||
import (
|
import "github.com/swaggo/swag"
|
||||||
"bytes"
|
|
||||||
"encoding/json"
|
|
||||||
"strings"
|
|
||||||
"text/template"
|
|
||||||
|
|
||||||
"github.com/swaggo/swag"
|
const docTemplate = `{
|
||||||
)
|
|
||||||
|
|
||||||
var doc = `{
|
|
||||||
"schemes": {{ marshal .Schemes }},
|
"schemes": {{ marshal .Schemes }},
|
||||||
"swagger": "2.0",
|
"swagger": "2.0",
|
||||||
"info": {
|
"info": {
|
||||||
@@ -737,11 +730,6 @@ var doc = `{
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"data": {
|
"data": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
@@ -755,8 +743,6 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -912,6 +898,103 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "客户修改已被驳回的发票申请并重新提交",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"发票管理"
|
||||||
|
],
|
||||||
|
"summary": "客户修改发票申请",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "发票ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "发票修改请求",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.InvoiceUpdateRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "成功",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/models.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"invoice_no": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "请求参数无效",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "未认证",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "权限不足",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "发票不存在",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "服务器内部错误",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/cu/invoices/{id}/download": {
|
"/api/cu/invoices/{id}/download": {
|
||||||
@@ -1011,22 +1094,12 @@ var doc = `{
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"data": {
|
"data": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"token": {
|
"token": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"customer_id": {
|
"customer_id": {
|
||||||
@@ -1052,13 +1125,9 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1220,11 +1289,6 @@ var doc = `{
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"data": {
|
"data": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"expire_time": {
|
"expire_time": {
|
||||||
@@ -1247,8 +1311,6 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -1306,11 +1368,6 @@ var doc = `{
|
|||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"license_count": {
|
"license_count": {
|
||||||
@@ -1321,8 +1378,6 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -1337,11 +1392,6 @@ var doc = `{
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"data": {
|
"data": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"discount_description": {
|
"discount_description": {
|
||||||
@@ -1361,8 +1411,6 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -1543,19 +1591,19 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
"description": ""
|
"description": "Bad Request"
|
||||||
},
|
},
|
||||||
"401": {
|
"401": {
|
||||||
"description": ""
|
"description": "Unauthorized"
|
||||||
},
|
},
|
||||||
"403": {
|
"403": {
|
||||||
"description": ""
|
"description": "Forbidden"
|
||||||
},
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": ""
|
"description": "Not Found"
|
||||||
},
|
},
|
||||||
"409": {
|
"409": {
|
||||||
"description": ""
|
"description": "Conflict"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1609,11 +1657,6 @@ var doc = `{
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"data": {
|
"data": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"expire_time": {
|
"expire_time": {
|
||||||
@@ -1636,8 +1679,6 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -1697,11 +1738,6 @@ var doc = `{
|
|||||||
"data": {
|
"data": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
@@ -1721,8 +1757,6 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2128,22 +2162,12 @@ var doc = `{
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"data": {
|
"data": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"token": {
|
"token": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"customer_id": {
|
"customer_id": {
|
||||||
@@ -2169,13 +2193,9 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -6506,7 +6526,11 @@ var doc = `{
|
|||||||
},
|
},
|
||||||
"customer_info": {
|
"customer_info": {
|
||||||
"description": "客户信息(仅在详情接口返回)",
|
"description": "客户信息(仅在详情接口返回)",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.CustomerInfoForAuthCode"
|
"$ref": "#/definitions/models.CustomerInfoForAuthCode"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"customer_name": {
|
"customer_name": {
|
||||||
"description": "客户名称",
|
"description": "客户名称",
|
||||||
@@ -6815,8 +6839,12 @@ var doc = `{
|
|||||||
"properties": {
|
"properties": {
|
||||||
"new_authorization_code": {
|
"new_authorization_code": {
|
||||||
"description": "新生成的授权码信息",
|
"description": "新生成的授权码信息",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.AuthorizationCodeShareResponseItem"
|
"$ref": "#/definitions/models.AuthorizationCodeShareResponseItem"
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"models.AuthorizationCodeShareResponseItem": {
|
"models.AuthorizationCodeShareResponseItem": {
|
||||||
@@ -7133,6 +7161,10 @@ var doc = `{
|
|||||||
"description": "订单过期时间",
|
"description": "订单过期时间",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"has_invoice_applied": {
|
||||||
|
"description": "是否已申请发票(根据 invoices 表判断)",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"id": {
|
"id": {
|
||||||
"description": "订单ID",
|
"description": "订单ID",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -7528,7 +7560,11 @@ var doc = `{
|
|||||||
},
|
},
|
||||||
"authorization_stats": {
|
"authorization_stats": {
|
||||||
"description": "授权统计信息(仅在详情接口返回)",
|
"description": "授权统计信息(仅在详情接口返回)",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.AuthorizationStats"
|
"$ref": "#/definitions/models.AuthorizationStats"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"company_size": {
|
"company_size": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -7853,11 +7889,19 @@ var doc = `{
|
|||||||
"properties": {
|
"properties": {
|
||||||
"period": {
|
"period": {
|
||||||
"description": "时间段信息",
|
"description": "时间段信息",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.TrendPeriod"
|
"$ref": "#/definitions/models.TrendPeriod"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"summary": {
|
"summary": {
|
||||||
"description": "汇总信息",
|
"description": "汇总信息",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.TrendSummary"
|
"$ref": "#/definitions/models.TrendSummary"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"trend_data": {
|
"trend_data": {
|
||||||
"description": "趋势数据",
|
"description": "趋势数据",
|
||||||
@@ -7893,7 +7937,11 @@ var doc = `{
|
|||||||
},
|
},
|
||||||
"authorization_info": {
|
"authorization_info": {
|
||||||
"description": "授权信息",
|
"description": "授权信息",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.AuthorizationInfo"
|
"$ref": "#/definitions/models.AuthorizationInfo"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"device_info": {
|
"device_info": {
|
||||||
"description": "设备信息",
|
"description": "设备信息",
|
||||||
@@ -8489,6 +8537,47 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"models.InvoiceUpdateRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"invoice_type",
|
||||||
|
"receiver_email",
|
||||||
|
"title"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"content": {
|
||||||
|
"description": "开票内容,非必填,最多200字符",
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 200
|
||||||
|
},
|
||||||
|
"invoice_type": {
|
||||||
|
"description": "发票类型,必填,personal-个人/enterprise-企业普票/vat_special-增值税专用发票",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"personal",
|
||||||
|
"enterprise",
|
||||||
|
"vat_special"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"receiver_email": {
|
||||||
|
"description": "收票邮箱,必填,格式为邮箱地址",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"remark": {
|
||||||
|
"description": "备注,可选",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"taxpayer_id": {
|
||||||
|
"description": "纳税人识别号,企业发票必填,个人发票可为空",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"description": "发票抬头,必填,最多200字符",
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"models.InvoiceUploadResponse": {
|
"models.InvoiceUploadResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -8717,7 +8806,11 @@ var doc = `{
|
|||||||
},
|
},
|
||||||
"authorization_code": {
|
"authorization_code": {
|
||||||
"description": "关联字段(用于查询时的JOIN)",
|
"description": "关联字段(用于查询时的JOIN)",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.AuthorizationCode"
|
"$ref": "#/definitions/models.AuthorizationCode"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"authorization_code_id": {
|
"authorization_code_id": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -9303,7 +9396,11 @@ var doc = `{
|
|||||||
},
|
},
|
||||||
"business_order": {
|
"business_order": {
|
||||||
"description": "关联的业务订单信息",
|
"description": "关联的业务订单信息",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.PaymentBusinessOrder"
|
"$ref": "#/definitions/models.PaymentBusinessOrder"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"payment_no": {
|
"payment_no": {
|
||||||
"description": "支付单号",
|
"description": "支付单号",
|
||||||
@@ -9418,7 +9515,11 @@ var doc = `{
|
|||||||
},
|
},
|
||||||
"growth_rate": {
|
"growth_rate": {
|
||||||
"description": "增长率(同比上月)",
|
"description": "增长率(同比上月)",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.GrowthRate"
|
"$ref": "#/definitions/models.GrowthRate"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"total_auth_codes": {
|
"total_auth_codes": {
|
||||||
"description": "总授权码数量(所有授权码的累计总数)",
|
"description": "总授权码数量(所有授权码的累计总数)",
|
||||||
@@ -9512,6 +9613,7 @@ var doc = `{
|
|||||||
},
|
},
|
||||||
"securityDefinitions": {
|
"securityDefinitions": {
|
||||||
"BearerAuth": {
|
"BearerAuth": {
|
||||||
|
"description": "Bearer token for authentication",
|
||||||
"type": "apiKey",
|
"type": "apiKey",
|
||||||
"name": "Authorization",
|
"name": "Authorization",
|
||||||
"in": "header"
|
"in": "header"
|
||||||
@@ -9519,56 +9621,18 @@ var doc = `{
|
|||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
type swaggerInfo struct {
|
|
||||||
Version string
|
|
||||||
Host string
|
|
||||||
BasePath string
|
|
||||||
Schemes []string
|
|
||||||
Title string
|
|
||||||
Description string
|
|
||||||
}
|
|
||||||
|
|
||||||
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
// SwaggerInfo holds exported Swagger Info so clients can modify it
|
||||||
var SwaggerInfo = swaggerInfo{
|
var SwaggerInfo = &swag.Spec{
|
||||||
Version: "1.0",
|
Version: "1.0",
|
||||||
Host: "",
|
Host: "",
|
||||||
BasePath: "/",
|
BasePath: "/",
|
||||||
Schemes: []string{"http", "https"},
|
Schemes: []string{"http", "https"},
|
||||||
Title: "License Manager API",
|
Title: "License Manager API",
|
||||||
Description: "Bearer token for authentication",
|
Description: "软件授权管理平台API文档",
|
||||||
}
|
InfoInstanceName: "swagger",
|
||||||
|
SwaggerTemplate: docTemplate,
|
||||||
type s struct{}
|
|
||||||
|
|
||||||
func (s *s) ReadDoc() string {
|
|
||||||
sInfo := SwaggerInfo
|
|
||||||
sInfo.Description = strings.Replace(sInfo.Description, "\n", "\\n", -1)
|
|
||||||
|
|
||||||
t, err := template.New("swagger_info").Funcs(template.FuncMap{
|
|
||||||
"marshal": func(v interface{}) string {
|
|
||||||
a, _ := json.Marshal(v)
|
|
||||||
return string(a)
|
|
||||||
},
|
|
||||||
"escape": func(v interface{}) string {
|
|
||||||
// escape tabs
|
|
||||||
str := strings.Replace(v.(string), "\t", "\\t", -1)
|
|
||||||
// replace " with \", and if that results in \\", replace that with \\\"
|
|
||||||
str = strings.Replace(str, "\"", "\\\"", -1)
|
|
||||||
return strings.Replace(str, "\\\\\"", "\\\\\\\"", -1)
|
|
||||||
},
|
|
||||||
}).Parse(doc)
|
|
||||||
if err != nil {
|
|
||||||
return doc
|
|
||||||
}
|
|
||||||
|
|
||||||
var tpl bytes.Buffer
|
|
||||||
if err := t.Execute(&tpl, sInfo); err != nil {
|
|
||||||
return doc
|
|
||||||
}
|
|
||||||
|
|
||||||
return tpl.String()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
swag.Register("swagger", &s{})
|
swag.Register(SwaggerInfo.InstanceName(), SwaggerInfo)
|
||||||
}
|
}
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
],
|
],
|
||||||
"swagger": "2.0",
|
"swagger": "2.0",
|
||||||
"info": {
|
"info": {
|
||||||
"description": "Bearer token for authentication",
|
"description": "软件授权管理平台API文档",
|
||||||
"title": "License Manager API",
|
"title": "License Manager API",
|
||||||
"termsOfService": "http://swagger.io/terms/",
|
"termsOfService": "http://swagger.io/terms/",
|
||||||
"contact": {
|
"contact": {
|
||||||
@@ -726,11 +726,6 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"data": {
|
"data": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
@@ -744,8 +739,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -901,6 +894,103 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"put": {
|
||||||
|
"security": [
|
||||||
|
{
|
||||||
|
"BearerAuth": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"description": "客户修改已被驳回的发票申请并重新提交",
|
||||||
|
"consumes": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"produces": [
|
||||||
|
"application/json"
|
||||||
|
],
|
||||||
|
"tags": [
|
||||||
|
"发票管理"
|
||||||
|
],
|
||||||
|
"summary": "客户修改发票申请",
|
||||||
|
"parameters": [
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "发票ID",
|
||||||
|
"name": "id",
|
||||||
|
"in": "path",
|
||||||
|
"required": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"description": "发票修改请求",
|
||||||
|
"name": "request",
|
||||||
|
"in": "body",
|
||||||
|
"required": true,
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.InvoiceUpdateRequest"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"responses": {
|
||||||
|
"200": {
|
||||||
|
"description": "成功",
|
||||||
|
"schema": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/models.APIResponse"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"data": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"id": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"invoice_no": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"status": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"400": {
|
||||||
|
"description": "请求参数无效",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"401": {
|
||||||
|
"description": "未认证",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"403": {
|
||||||
|
"description": "权限不足",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "发票不存在",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.ErrorResponse"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"500": {
|
||||||
|
"description": "服务器内部错误",
|
||||||
|
"schema": {
|
||||||
|
"$ref": "#/definitions/models.ErrorResponse"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"/api/cu/invoices/{id}/download": {
|
"/api/cu/invoices/{id}/download": {
|
||||||
@@ -1000,22 +1090,12 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"data": {
|
"data": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"token": {
|
"token": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"customer_id": {
|
"customer_id": {
|
||||||
@@ -1041,13 +1121,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -1209,11 +1285,6 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"data": {
|
"data": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"expire_time": {
|
"expire_time": {
|
||||||
@@ -1236,8 +1307,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -1295,11 +1364,6 @@
|
|||||||
"in": "body",
|
"in": "body",
|
||||||
"required": true,
|
"required": true,
|
||||||
"schema": {
|
"schema": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"license_count": {
|
"license_count": {
|
||||||
@@ -1310,8 +1374,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
@@ -1326,11 +1388,6 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"data": {
|
"data": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"discount_description": {
|
"discount_description": {
|
||||||
@@ -1350,8 +1407,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -1532,19 +1587,19 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"400": {
|
"400": {
|
||||||
"description": ""
|
"description": "Bad Request"
|
||||||
},
|
},
|
||||||
"401": {
|
"401": {
|
||||||
"description": ""
|
"description": "Unauthorized"
|
||||||
},
|
},
|
||||||
"403": {
|
"403": {
|
||||||
"description": ""
|
"description": "Forbidden"
|
||||||
},
|
},
|
||||||
"404": {
|
"404": {
|
||||||
"description": ""
|
"description": "Not Found"
|
||||||
},
|
},
|
||||||
"409": {
|
"409": {
|
||||||
"description": ""
|
"description": "Conflict"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1598,11 +1653,6 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"data": {
|
"data": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"expire_time": {
|
"expire_time": {
|
||||||
@@ -1625,8 +1675,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -1686,11 +1734,6 @@
|
|||||||
"data": {
|
"data": {
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"id": {
|
"id": {
|
||||||
@@ -1710,8 +1753,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2117,22 +2158,12 @@
|
|||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"data": {
|
"data": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"token": {
|
"token": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"allOf": [
|
|
||||||
{
|
|
||||||
"type": "object"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
"customer_id": {
|
"customer_id": {
|
||||||
@@ -2158,13 +2189,9 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -6495,7 +6522,11 @@
|
|||||||
},
|
},
|
||||||
"customer_info": {
|
"customer_info": {
|
||||||
"description": "客户信息(仅在详情接口返回)",
|
"description": "客户信息(仅在详情接口返回)",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.CustomerInfoForAuthCode"
|
"$ref": "#/definitions/models.CustomerInfoForAuthCode"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"customer_name": {
|
"customer_name": {
|
||||||
"description": "客户名称",
|
"description": "客户名称",
|
||||||
@@ -6804,8 +6835,12 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"new_authorization_code": {
|
"new_authorization_code": {
|
||||||
"description": "新生成的授权码信息",
|
"description": "新生成的授权码信息",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.AuthorizationCodeShareResponseItem"
|
"$ref": "#/definitions/models.AuthorizationCodeShareResponseItem"
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"models.AuthorizationCodeShareResponseItem": {
|
"models.AuthorizationCodeShareResponseItem": {
|
||||||
@@ -7122,6 +7157,10 @@
|
|||||||
"description": "订单过期时间",
|
"description": "订单过期时间",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"has_invoice_applied": {
|
||||||
|
"description": "是否已申请发票(根据 invoices 表判断)",
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"id": {
|
"id": {
|
||||||
"description": "订单ID",
|
"description": "订单ID",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -7517,7 +7556,11 @@
|
|||||||
},
|
},
|
||||||
"authorization_stats": {
|
"authorization_stats": {
|
||||||
"description": "授权统计信息(仅在详情接口返回)",
|
"description": "授权统计信息(仅在详情接口返回)",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.AuthorizationStats"
|
"$ref": "#/definitions/models.AuthorizationStats"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"company_size": {
|
"company_size": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -7842,11 +7885,19 @@
|
|||||||
"properties": {
|
"properties": {
|
||||||
"period": {
|
"period": {
|
||||||
"description": "时间段信息",
|
"description": "时间段信息",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.TrendPeriod"
|
"$ref": "#/definitions/models.TrendPeriod"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"summary": {
|
"summary": {
|
||||||
"description": "汇总信息",
|
"description": "汇总信息",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.TrendSummary"
|
"$ref": "#/definitions/models.TrendSummary"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"trend_data": {
|
"trend_data": {
|
||||||
"description": "趋势数据",
|
"description": "趋势数据",
|
||||||
@@ -7882,7 +7933,11 @@
|
|||||||
},
|
},
|
||||||
"authorization_info": {
|
"authorization_info": {
|
||||||
"description": "授权信息",
|
"description": "授权信息",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.AuthorizationInfo"
|
"$ref": "#/definitions/models.AuthorizationInfo"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"device_info": {
|
"device_info": {
|
||||||
"description": "设备信息",
|
"description": "设备信息",
|
||||||
@@ -8478,6 +8533,47 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"models.InvoiceUpdateRequest": {
|
||||||
|
"type": "object",
|
||||||
|
"required": [
|
||||||
|
"invoice_type",
|
||||||
|
"receiver_email",
|
||||||
|
"title"
|
||||||
|
],
|
||||||
|
"properties": {
|
||||||
|
"content": {
|
||||||
|
"description": "开票内容,非必填,最多200字符",
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 200
|
||||||
|
},
|
||||||
|
"invoice_type": {
|
||||||
|
"description": "发票类型,必填,personal-个人/enterprise-企业普票/vat_special-增值税专用发票",
|
||||||
|
"type": "string",
|
||||||
|
"enum": [
|
||||||
|
"personal",
|
||||||
|
"enterprise",
|
||||||
|
"vat_special"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"receiver_email": {
|
||||||
|
"description": "收票邮箱,必填,格式为邮箱地址",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"remark": {
|
||||||
|
"description": "备注,可选",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"taxpayer_id": {
|
||||||
|
"description": "纳税人识别号,企业发票必填,个人发票可为空",
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"description": "发票抬头,必填,最多200字符",
|
||||||
|
"type": "string",
|
||||||
|
"maxLength": 200
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"models.InvoiceUploadResponse": {
|
"models.InvoiceUploadResponse": {
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"properties": {
|
"properties": {
|
||||||
@@ -8706,7 +8802,11 @@
|
|||||||
},
|
},
|
||||||
"authorization_code": {
|
"authorization_code": {
|
||||||
"description": "关联字段(用于查询时的JOIN)",
|
"description": "关联字段(用于查询时的JOIN)",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.AuthorizationCode"
|
"$ref": "#/definitions/models.AuthorizationCode"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"authorization_code_id": {
|
"authorization_code_id": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
@@ -9292,7 +9392,11 @@
|
|||||||
},
|
},
|
||||||
"business_order": {
|
"business_order": {
|
||||||
"description": "关联的业务订单信息",
|
"description": "关联的业务订单信息",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.PaymentBusinessOrder"
|
"$ref": "#/definitions/models.PaymentBusinessOrder"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"payment_no": {
|
"payment_no": {
|
||||||
"description": "支付单号",
|
"description": "支付单号",
|
||||||
@@ -9407,7 +9511,11 @@
|
|||||||
},
|
},
|
||||||
"growth_rate": {
|
"growth_rate": {
|
||||||
"description": "增长率(同比上月)",
|
"description": "增长率(同比上月)",
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
"$ref": "#/definitions/models.GrowthRate"
|
"$ref": "#/definitions/models.GrowthRate"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"total_auth_codes": {
|
"total_auth_codes": {
|
||||||
"description": "总授权码数量(所有授权码的累计总数)",
|
"description": "总授权码数量(所有授权码的累计总数)",
|
||||||
@@ -9501,6 +9609,7 @@
|
|||||||
},
|
},
|
||||||
"securityDefinitions": {
|
"securityDefinitions": {
|
||||||
"BearerAuth": {
|
"BearerAuth": {
|
||||||
|
"description": "Bearer token for authentication",
|
||||||
"type": "apiKey",
|
"type": "apiKey",
|
||||||
"name": "Authorization",
|
"name": "Authorization",
|
||||||
"in": "header"
|
"in": "header"
|
||||||
|
|||||||
@@ -109,7 +109,8 @@ definitions:
|
|||||||
description: 客户ID
|
description: 客户ID
|
||||||
type: string
|
type: string
|
||||||
customer_info:
|
customer_info:
|
||||||
$ref: '#/definitions/models.CustomerInfoForAuthCode'
|
allOf:
|
||||||
|
- $ref: '#/definitions/models.CustomerInfoForAuthCode'
|
||||||
description: 客户信息(仅在详情接口返回)
|
description: 客户信息(仅在详情接口返回)
|
||||||
customer_name:
|
customer_name:
|
||||||
description: 客户名称
|
description: 客户名称
|
||||||
@@ -337,7 +338,8 @@ definitions:
|
|||||||
models.AuthorizationCodeShareResponse:
|
models.AuthorizationCodeShareResponse:
|
||||||
properties:
|
properties:
|
||||||
new_authorization_code:
|
new_authorization_code:
|
||||||
$ref: '#/definitions/models.AuthorizationCodeShareResponseItem'
|
allOf:
|
||||||
|
- $ref: '#/definitions/models.AuthorizationCodeShareResponseItem'
|
||||||
description: 新生成的授权码信息
|
description: 新生成的授权码信息
|
||||||
type: object
|
type: object
|
||||||
models.AuthorizationCodeShareResponseItem:
|
models.AuthorizationCodeShareResponseItem:
|
||||||
@@ -567,6 +569,9 @@ definitions:
|
|||||||
expired_at:
|
expired_at:
|
||||||
description: 订单过期时间
|
description: 订单过期时间
|
||||||
type: string
|
type: string
|
||||||
|
has_invoice_applied:
|
||||||
|
description: 是否已申请发票(根据 invoices 表判断)
|
||||||
|
type: boolean
|
||||||
id:
|
id:
|
||||||
description: 订单ID
|
description: 订单ID
|
||||||
type: string
|
type: string
|
||||||
@@ -860,7 +865,8 @@ definitions:
|
|||||||
address:
|
address:
|
||||||
type: string
|
type: string
|
||||||
authorization_stats:
|
authorization_stats:
|
||||||
$ref: '#/definitions/models.AuthorizationStats'
|
allOf:
|
||||||
|
- $ref: '#/definitions/models.AuthorizationStats'
|
||||||
description: 授权统计信息(仅在详情接口返回)
|
description: 授权统计信息(仅在详情接口返回)
|
||||||
company_size:
|
company_size:
|
||||||
type: string
|
type: string
|
||||||
@@ -1094,10 +1100,12 @@ definitions:
|
|||||||
models.DashboardAuthorizationTrendResponse:
|
models.DashboardAuthorizationTrendResponse:
|
||||||
properties:
|
properties:
|
||||||
period:
|
period:
|
||||||
$ref: '#/definitions/models.TrendPeriod'
|
allOf:
|
||||||
|
- $ref: '#/definitions/models.TrendPeriod'
|
||||||
description: 时间段信息
|
description: 时间段信息
|
||||||
summary:
|
summary:
|
||||||
$ref: '#/definitions/models.TrendSummary'
|
allOf:
|
||||||
|
- $ref: '#/definitions/models.TrendSummary'
|
||||||
description: 汇总信息
|
description: 汇总信息
|
||||||
trend_data:
|
trend_data:
|
||||||
description: 趋势数据
|
description: 趋势数据
|
||||||
@@ -1122,7 +1130,8 @@ definitions:
|
|||||||
description: 激活时间
|
description: 激活时间
|
||||||
type: string
|
type: string
|
||||||
authorization_info:
|
authorization_info:
|
||||||
$ref: '#/definitions/models.AuthorizationInfo'
|
allOf:
|
||||||
|
- $ref: '#/definitions/models.AuthorizationInfo'
|
||||||
description: 授权信息
|
description: 授权信息
|
||||||
device_info:
|
device_info:
|
||||||
additionalProperties: true
|
additionalProperties: true
|
||||||
@@ -1556,6 +1565,37 @@ definitions:
|
|||||||
description: 发票总数
|
description: 发票总数
|
||||||
type: integer
|
type: integer
|
||||||
type: object
|
type: object
|
||||||
|
models.InvoiceUpdateRequest:
|
||||||
|
properties:
|
||||||
|
content:
|
||||||
|
description: 开票内容,非必填,最多200字符
|
||||||
|
maxLength: 200
|
||||||
|
type: string
|
||||||
|
invoice_type:
|
||||||
|
description: 发票类型,必填,personal-个人/enterprise-企业普票/vat_special-增值税专用发票
|
||||||
|
enum:
|
||||||
|
- personal
|
||||||
|
- enterprise
|
||||||
|
- vat_special
|
||||||
|
type: string
|
||||||
|
receiver_email:
|
||||||
|
description: 收票邮箱,必填,格式为邮箱地址
|
||||||
|
type: string
|
||||||
|
remark:
|
||||||
|
description: 备注,可选
|
||||||
|
type: string
|
||||||
|
taxpayer_id:
|
||||||
|
description: 纳税人识别号,企业发票必填,个人发票可为空
|
||||||
|
type: string
|
||||||
|
title:
|
||||||
|
description: 发票抬头,必填,最多200字符
|
||||||
|
maxLength: 200
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- invoice_type
|
||||||
|
- receiver_email
|
||||||
|
- title
|
||||||
|
type: object
|
||||||
models.InvoiceUploadResponse:
|
models.InvoiceUploadResponse:
|
||||||
properties:
|
properties:
|
||||||
file_url:
|
file_url:
|
||||||
@@ -1725,7 +1765,8 @@ definitions:
|
|||||||
activation_ip:
|
activation_ip:
|
||||||
type: string
|
type: string
|
||||||
authorization_code:
|
authorization_code:
|
||||||
$ref: '#/definitions/models.AuthorizationCode'
|
allOf:
|
||||||
|
- $ref: '#/definitions/models.AuthorizationCode'
|
||||||
description: 关联字段(用于查询时的JOIN)
|
description: 关联字段(用于查询时的JOIN)
|
||||||
authorization_code_id:
|
authorization_code_id:
|
||||||
type: string
|
type: string
|
||||||
@@ -2139,7 +2180,8 @@ definitions:
|
|||||||
description: 支付金额,单位元
|
description: 支付金额,单位元
|
||||||
type: number
|
type: number
|
||||||
business_order:
|
business_order:
|
||||||
$ref: '#/definitions/models.PaymentBusinessOrder'
|
allOf:
|
||||||
|
- $ref: '#/definitions/models.PaymentBusinessOrder'
|
||||||
description: 关联的业务订单信息
|
description: 关联的业务订单信息
|
||||||
payment_no:
|
payment_no:
|
||||||
description: 支付单号
|
description: 支付单号
|
||||||
@@ -2222,7 +2264,8 @@ definitions:
|
|||||||
description: 即将过期数量(30天内即将过期的授权码,且未被锁定)
|
description: 即将过期数量(30天内即将过期的授权码,且未被锁定)
|
||||||
type: integer
|
type: integer
|
||||||
growth_rate:
|
growth_rate:
|
||||||
$ref: '#/definitions/models.GrowthRate'
|
allOf:
|
||||||
|
- $ref: '#/definitions/models.GrowthRate'
|
||||||
description: 增长率(同比上月)
|
description: 增长率(同比上月)
|
||||||
total_auth_codes:
|
total_auth_codes:
|
||||||
description: 总授权码数量(所有授权码的累计总数)
|
description: 总授权码数量(所有授权码的累计总数)
|
||||||
@@ -2291,7 +2334,7 @@ info:
|
|||||||
email: support@swagger.io
|
email: support@swagger.io
|
||||||
name: API Support
|
name: API Support
|
||||||
url: http://www.swagger.io/support
|
url: http://www.swagger.io/support
|
||||||
description: Bearer token for authentication
|
description: 软件授权管理平台API文档
|
||||||
license:
|
license:
|
||||||
name: MIT
|
name: MIT
|
||||||
url: https://opensource.org/licenses/MIT
|
url: https://opensource.org/licenses/MIT
|
||||||
@@ -2730,9 +2773,7 @@ paths:
|
|||||||
- $ref: '#/definitions/models.APIResponse'
|
- $ref: '#/definitions/models.APIResponse'
|
||||||
- properties:
|
- properties:
|
||||||
data:
|
data:
|
||||||
allOf:
|
properties:
|
||||||
- type: object
|
|
||||||
- properties:
|
|
||||||
id:
|
id:
|
||||||
type: string
|
type: string
|
||||||
invoice_no:
|
invoice_no:
|
||||||
@@ -2806,6 +2847,66 @@ paths:
|
|||||||
summary: 客户发票详情
|
summary: 客户发票详情
|
||||||
tags:
|
tags:
|
||||||
- 发票管理
|
- 发票管理
|
||||||
|
put:
|
||||||
|
consumes:
|
||||||
|
- application/json
|
||||||
|
description: 客户修改已被驳回的发票申请并重新提交
|
||||||
|
parameters:
|
||||||
|
- description: 发票ID
|
||||||
|
in: path
|
||||||
|
name: id
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
- description: 发票修改请求
|
||||||
|
in: body
|
||||||
|
name: request
|
||||||
|
required: true
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.InvoiceUpdateRequest'
|
||||||
|
produces:
|
||||||
|
- application/json
|
||||||
|
responses:
|
||||||
|
"200":
|
||||||
|
description: 成功
|
||||||
|
schema:
|
||||||
|
allOf:
|
||||||
|
- $ref: '#/definitions/models.APIResponse'
|
||||||
|
- properties:
|
||||||
|
data:
|
||||||
|
properties:
|
||||||
|
id:
|
||||||
|
type: string
|
||||||
|
invoice_no:
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
type: string
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
"400":
|
||||||
|
description: 请求参数无效
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.ErrorResponse'
|
||||||
|
"401":
|
||||||
|
description: 未认证
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.ErrorResponse'
|
||||||
|
"403":
|
||||||
|
description: 权限不足
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.ErrorResponse'
|
||||||
|
"404":
|
||||||
|
description: 发票不存在
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.ErrorResponse'
|
||||||
|
"500":
|
||||||
|
description: 服务器内部错误
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/models.ErrorResponse'
|
||||||
|
security:
|
||||||
|
- BearerAuth: []
|
||||||
|
summary: 客户修改发票申请
|
||||||
|
tags:
|
||||||
|
- 发票管理
|
||||||
/api/cu/invoices/{id}/download:
|
/api/cu/invoices/{id}/download:
|
||||||
get:
|
get:
|
||||||
consumes:
|
consumes:
|
||||||
@@ -2897,15 +2998,11 @@ paths:
|
|||||||
- $ref: '#/definitions/models.APIResponse'
|
- $ref: '#/definitions/models.APIResponse'
|
||||||
- properties:
|
- properties:
|
||||||
data:
|
data:
|
||||||
allOf:
|
properties:
|
||||||
- type: object
|
|
||||||
- properties:
|
|
||||||
token:
|
token:
|
||||||
type: string
|
type: string
|
||||||
user:
|
user:
|
||||||
allOf:
|
properties:
|
||||||
- type: object
|
|
||||||
- properties:
|
|
||||||
customer_id:
|
customer_id:
|
||||||
type: string
|
type: string
|
||||||
email:
|
email:
|
||||||
@@ -3021,9 +3118,7 @@ paths:
|
|||||||
- $ref: '#/definitions/models.APIResponse'
|
- $ref: '#/definitions/models.APIResponse'
|
||||||
- properties:
|
- properties:
|
||||||
data:
|
data:
|
||||||
allOf:
|
properties:
|
||||||
- type: object
|
|
||||||
- properties:
|
|
||||||
expire_time:
|
expire_time:
|
||||||
type: string
|
type: string
|
||||||
id:
|
id:
|
||||||
@@ -3118,15 +3213,15 @@ paths:
|
|||||||
schema:
|
schema:
|
||||||
$ref: '#/definitions/models.APIResponse'
|
$ref: '#/definitions/models.APIResponse'
|
||||||
"400":
|
"400":
|
||||||
description: ""
|
description: Bad Request
|
||||||
"401":
|
"401":
|
||||||
description: ""
|
description: Unauthorized
|
||||||
"403":
|
"403":
|
||||||
description: ""
|
description: Forbidden
|
||||||
"404":
|
"404":
|
||||||
description: ""
|
description: Not Found
|
||||||
"409":
|
"409":
|
||||||
description: ""
|
description: Conflict
|
||||||
security:
|
security:
|
||||||
- BearerAuth: []
|
- BearerAuth: []
|
||||||
summary: 删除订单
|
summary: 删除订单
|
||||||
@@ -3160,9 +3255,7 @@ paths:
|
|||||||
- $ref: '#/definitions/models.APIResponse'
|
- $ref: '#/definitions/models.APIResponse'
|
||||||
- properties:
|
- properties:
|
||||||
data:
|
data:
|
||||||
allOf:
|
properties:
|
||||||
- type: object
|
|
||||||
- properties:
|
|
||||||
expire_time:
|
expire_time:
|
||||||
type: string
|
type: string
|
||||||
order_id:
|
order_id:
|
||||||
@@ -3209,9 +3302,7 @@ paths:
|
|||||||
name: request
|
name: request
|
||||||
required: true
|
required: true
|
||||||
schema:
|
schema:
|
||||||
allOf:
|
properties:
|
||||||
- type: object
|
|
||||||
- properties:
|
|
||||||
license_count:
|
license_count:
|
||||||
type: integer
|
type: integer
|
||||||
package_id:
|
package_id:
|
||||||
@@ -3227,9 +3318,7 @@ paths:
|
|||||||
- $ref: '#/definitions/models.APIResponse'
|
- $ref: '#/definitions/models.APIResponse'
|
||||||
- properties:
|
- properties:
|
||||||
data:
|
data:
|
||||||
allOf:
|
properties:
|
||||||
- type: object
|
|
||||||
- properties:
|
|
||||||
discount_description:
|
discount_description:
|
||||||
type: string
|
type: string
|
||||||
discount_rate:
|
discount_rate:
|
||||||
@@ -3305,9 +3394,7 @@ paths:
|
|||||||
- properties:
|
- properties:
|
||||||
data:
|
data:
|
||||||
items:
|
items:
|
||||||
allOf:
|
properties:
|
||||||
- type: object
|
|
||||||
- properties:
|
|
||||||
id:
|
id:
|
||||||
type: string
|
type: string
|
||||||
max_devices:
|
max_devices:
|
||||||
@@ -3572,15 +3659,11 @@ paths:
|
|||||||
- $ref: '#/definitions/models.APIResponse'
|
- $ref: '#/definitions/models.APIResponse'
|
||||||
- properties:
|
- properties:
|
||||||
data:
|
data:
|
||||||
allOf:
|
properties:
|
||||||
- type: object
|
|
||||||
- properties:
|
|
||||||
token:
|
token:
|
||||||
type: string
|
type: string
|
||||||
user:
|
user:
|
||||||
allOf:
|
properties:
|
||||||
- type: object
|
|
||||||
- properties:
|
|
||||||
customer_id:
|
customer_id:
|
||||||
type: string
|
type: string
|
||||||
email:
|
email:
|
||||||
@@ -6196,6 +6279,7 @@ schemes:
|
|||||||
- https
|
- https
|
||||||
securityDefinitions:
|
securityDefinitions:
|
||||||
BearerAuth:
|
BearerAuth:
|
||||||
|
description: Bearer token for authentication
|
||||||
in: header
|
in: header
|
||||||
name: Authorization
|
name: Authorization
|
||||||
type: apiKey
|
type: apiKey
|
||||||
|
|||||||
@@ -200,3 +200,54 @@ func (h *CuInvoiceHandler) DownloadInvoice(c *gin.Context) {
|
|||||||
// 重定向到文件URL
|
// 重定向到文件URL
|
||||||
c.Redirect(http.StatusFound, fileURL)
|
c.Redirect(http.StatusFound, fileURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// UpdateInvoice 客户修改发票申请
|
||||||
|
// @Summary 客户修改发票申请
|
||||||
|
// @Description 客户修改已被驳回的发票申请并重新提交
|
||||||
|
// @Tags 发票管理
|
||||||
|
// @Accept json
|
||||||
|
// @Produce json
|
||||||
|
// @Security BearerAuth
|
||||||
|
// @Param id path string true "发票ID"
|
||||||
|
// @Param request body models.InvoiceUpdateRequest true "发票修改请求"
|
||||||
|
// @Success 200 {object} models.APIResponse{data=object{id=string,invoice_no=string,status=string}} "成功"
|
||||||
|
// @Failure 400 {object} models.ErrorResponse "请求参数无效"
|
||||||
|
// @Failure 401 {object} models.ErrorResponse "未认证"
|
||||||
|
// @Failure 403 {object} models.ErrorResponse "权限不足"
|
||||||
|
// @Failure 404 {object} models.ErrorResponse "发票不存在"
|
||||||
|
// @Failure 500 {object} models.ErrorResponse "服务器内部错误"
|
||||||
|
// @Router /api/cu/invoices/{id} [put]
|
||||||
|
func (h *CuInvoiceHandler) UpdateInvoice(c *gin.Context) {
|
||||||
|
lang := middleware.GetLanguage(c)
|
||||||
|
invoiceID := c.Param("id")
|
||||||
|
|
||||||
|
var req models.InvoiceUpdateRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
c.JSON(http.StatusBadRequest, models.ErrorResponse{
|
||||||
|
Code: "900001",
|
||||||
|
Message: i18n.GetI18nErrorMessage("900001", lang),
|
||||||
|
Timestamp: getCurrentTimestamp(),
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
invoice, err := h.invoiceService.UpdateInvoice(c.Request.Context(), invoiceID, getCuUserID(c), &req)
|
||||||
|
if err != nil {
|
||||||
|
handleI18nError(c, err, lang)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
response := invoice.ToResponse()
|
||||||
|
result := map[string]interface{}{
|
||||||
|
"id": response.ID,
|
||||||
|
"invoice_no": response.InvoiceNo,
|
||||||
|
"status": response.Status,
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, models.APIResponse{
|
||||||
|
Code: "000000",
|
||||||
|
Message: i18n.GetI18nErrorMessage("000000", lang),
|
||||||
|
Data: result,
|
||||||
|
Timestamp: getCurrentTimestamp(),
|
||||||
|
})
|
||||||
|
}
|
||||||
@@ -288,6 +288,7 @@ func SetupRouter() *gin.Engine {
|
|||||||
cuAuth.POST("/invoices", cuInvoiceHandler.CreateInvoice)
|
cuAuth.POST("/invoices", cuInvoiceHandler.CreateInvoice)
|
||||||
cuAuth.GET("/invoices", cuInvoiceHandler.GetUserInvoices)
|
cuAuth.GET("/invoices", cuInvoiceHandler.GetUserInvoices)
|
||||||
cuAuth.GET("/invoices/:id", cuInvoiceHandler.GetUserInvoiceDetail)
|
cuAuth.GET("/invoices/:id", cuInvoiceHandler.GetUserInvoiceDetail)
|
||||||
|
cuAuth.PUT("/invoices/:id", cuInvoiceHandler.UpdateInvoice)
|
||||||
cuAuth.GET("/invoices/summary", cuInvoiceHandler.GetUserInvoiceSummary)
|
cuAuth.GET("/invoices/summary", cuInvoiceHandler.GetUserInvoiceSummary)
|
||||||
cuAuth.GET("/invoices/:id/download", cuInvoiceHandler.DownloadInvoice)
|
cuAuth.GET("/invoices/:id/download", cuInvoiceHandler.DownloadInvoice)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,16 @@ type InvoiceCreateRequest struct {
|
|||||||
Remark *string `json:"remark,omitempty"` // 备注,可选
|
Remark *string `json:"remark,omitempty"` // 备注,可选
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// InvoiceUpdateRequest 客户端修改发票请求结构
|
||||||
|
type InvoiceUpdateRequest struct {
|
||||||
|
InvoiceType string `json:"invoice_type" binding:"required,oneof=personal enterprise vat_special"` // 发票类型,必填,personal-个人/enterprise-企业普票/vat_special-增值税专用发票
|
||||||
|
ReceiverEmail string `json:"receiver_email" binding:"required,email"` // 收票邮箱,必填,格式为邮箱地址
|
||||||
|
Title string `json:"title" binding:"required,max=200"` // 发票抬头,必填,最多200字符
|
||||||
|
TaxpayerID *string `json:"taxpayer_id,omitempty"` // 纳税人识别号,企业发票必填,个人发票可为空
|
||||||
|
Content string `json:"content" binding:"omitempty,max=200"` // 开票内容,非必填,最多200字符
|
||||||
|
Remark *string `json:"remark,omitempty"` // 备注,可选
|
||||||
|
}
|
||||||
|
|
||||||
// InvoiceListRequest 发票列表查询请求结构
|
// InvoiceListRequest 发票列表查询请求结构
|
||||||
// 注:apply_date 支持 YYYY-MM-DD 或 RFC3339 时间范围 "start,end"。
|
// 注:apply_date 支持 YYYY-MM-DD 或 RFC3339 时间范围 "start,end"。
|
||||||
type InvoiceListRequest struct {
|
type InvoiceListRequest struct {
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ type CuInvoiceRepository interface {
|
|||||||
|
|
||||||
// ========== 通用工具方法 ==========
|
// ========== 通用工具方法 ==========
|
||||||
Create(invoice *models.Invoice) error
|
Create(invoice *models.Invoice) error
|
||||||
|
Update(invoice *models.Invoice) error
|
||||||
GetByID(id string) (*models.Invoice, error)
|
GetByID(id string) (*models.Invoice, error)
|
||||||
CheckOrderInvoiceExists(orderID string) (bool, error)
|
CheckOrderInvoiceExists(orderID string) (bool, error)
|
||||||
}
|
}
|
||||||
@@ -33,6 +34,12 @@ func (r *cuInvoiceRepository) Create(invoice *models.Invoice) error {
|
|||||||
return r.db.Create(invoice).Error
|
return r.db.Create(invoice).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *cuInvoiceRepository) Update(invoice *models.Invoice) error {
|
||||||
|
// 使用 Select 指定更新字段,确保可以清空某些字段(虽然此处目前主要是业务更新和状态重置)
|
||||||
|
// 或者直接使用 Save 更新全量字段
|
||||||
|
return r.db.Save(invoice).Error
|
||||||
|
}
|
||||||
|
|
||||||
func (r *cuInvoiceRepository) GetByID(id string) (*models.Invoice, error) {
|
func (r *cuInvoiceRepository) GetByID(id string) (*models.Invoice, error) {
|
||||||
var invoice models.Invoice
|
var invoice models.Invoice
|
||||||
err := r.db.Where("id = ? AND deleted_at IS NULL", id).First(&invoice).Error
|
err := r.db.Where("id = ? AND deleted_at IS NULL", id).First(&invoice).Error
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ type CuInvoiceService interface {
|
|||||||
GetUserInvoices(ctx context.Context, cuUserID string, req *models.InvoiceListRequest) (*models.InvoiceListResponse, error)
|
GetUserInvoices(ctx context.Context, cuUserID string, req *models.InvoiceListRequest) (*models.InvoiceListResponse, error)
|
||||||
GetInvoiceSummary(ctx context.Context, cuUserID string) (*models.InvoiceSummaryResponse, error)
|
GetInvoiceSummary(ctx context.Context, cuUserID string) (*models.InvoiceSummaryResponse, error)
|
||||||
DownloadInvoice(ctx context.Context, invoiceID, cuUserID string) (string, error)
|
DownloadInvoice(ctx context.Context, invoiceID, cuUserID string) (string, error)
|
||||||
|
UpdateInvoice(ctx context.Context, invoiceID, cuUserID string, req *models.InvoiceUpdateRequest) (*models.Invoice, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type cuInvoiceService struct {
|
type cuInvoiceService struct {
|
||||||
@@ -175,6 +176,54 @@ func (s *cuInvoiceService) DownloadInvoice(ctx context.Context, invoiceID, cuUse
|
|||||||
return *invoice.InvoiceFileURL, nil
|
return *invoice.InvoiceFileURL, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *cuInvoiceService) UpdateInvoice(ctx context.Context, invoiceID, cuUserID string, req *models.InvoiceUpdateRequest) (*models.Invoice, error) {
|
||||||
|
lang := pkgcontext.GetLanguageFromContext(ctx)
|
||||||
|
|
||||||
|
// 获取原发票
|
||||||
|
invoice, err := s.repo.GetByID(invoiceID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, i18n.NewI18nError("700001", lang)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 权限校验
|
||||||
|
if invoice.CuUserID != cuUserID {
|
||||||
|
return nil, i18n.NewI18nError("700001", lang)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 状态校验:只有被驳回的发票可以修改
|
||||||
|
if invoice.Status != models.InvoiceStatusRejected {
|
||||||
|
return nil, i18n.NewI18nError("700004", lang)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 业务逻辑校验:发票类型和纳税人识别号
|
||||||
|
if req.InvoiceType != models.InvoiceTypePersonal && (req.TaxpayerID == nil || *req.TaxpayerID == "") {
|
||||||
|
return nil, i18n.NewI18nError("700004", lang)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新字段
|
||||||
|
invoice.InvoiceType = req.InvoiceType
|
||||||
|
invoice.Title = req.Title
|
||||||
|
invoice.TaxpayerID = req.TaxpayerID
|
||||||
|
invoice.Content = req.Content
|
||||||
|
invoice.ReceiverEmail = req.ReceiverEmail
|
||||||
|
invoice.Remark = req.Remark
|
||||||
|
|
||||||
|
// 重置状态和驳回信息
|
||||||
|
invoice.Status = models.InvoiceStatusPending
|
||||||
|
invoice.RejectReason = nil
|
||||||
|
invoice.Suggestion = nil
|
||||||
|
invoice.RejectedAt = nil
|
||||||
|
invoice.RejectedBy = nil
|
||||||
|
|
||||||
|
// 更新数据库
|
||||||
|
err = s.repo.Update(invoice)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return invoice, nil
|
||||||
|
}
|
||||||
|
|
||||||
// ========== 私有辅助方法 ==========
|
// ========== 私有辅助方法 ==========
|
||||||
|
|
||||||
// fillDisplayFields 填充响应结构的多语言显示字段
|
// fillDisplayFields 填充响应结构的多语言显示字段
|
||||||
|
|||||||
Reference in new issue
Block a user