488 lines
11 KiB
Markdown
488 lines
11 KiB
Markdown
# BillAI 服务器 API 文档
|
||
|
||
## 概述
|
||
|
||
BillAI 服务器是一个基于 Go 的后端服务,用于处理账单的上传、清洗、分析和存储。提供 REST API 接口供前端调用。
|
||
|
||
**服务地址**: `http://localhost:8080`
|
||
|
||
---
|
||
|
||
## API 接口列表
|
||
|
||
### 1. 健康检查
|
||
|
||
**端点**: `GET /health`
|
||
|
||
**功能**: 检查服务器健康状态
|
||
|
||
**参数**: 无
|
||
|
||
**响应示例**:
|
||
```json
|
||
{
|
||
"status": "ok",
|
||
"version": "1.0.0"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 账单管理 API
|
||
|
||
### 2. 上传账单文件
|
||
|
||
**端点**: `POST /api/upload`
|
||
|
||
**功能**: 上传支付宝或微信账单文件进行清洗和分析
|
||
|
||
**请求方式**: `multipart/form-data`
|
||
|
||
**请求参数**:
|
||
|
||
| 参数名 | 类型 | 必需 | 说明 |
|
||
|-------|------|------|------|
|
||
| file | File | ✓ | 账单文件(CSV格式) |
|
||
| type | string | ✓ | 账单类型:`alipay` 或 `wechat` |
|
||
| format | string | - | 输出格式:`csv` 或 `json`(默认: csv) |
|
||
| year | number | - | 账单年份(用于数据验证) |
|
||
| month | number | - | 账单月份(用于数据验证) |
|
||
|
||
**响应示例** (成功):
|
||
```json
|
||
{
|
||
"result": true,
|
||
"message": "账单处理完成",
|
||
"data": {
|
||
"bill_type": "alipay",
|
||
"raw_count": 50,
|
||
"cleaned_count": 48,
|
||
"duplicate_count": 2,
|
||
"needs_review_count": 5,
|
||
"file_name": "20260110_150405_alipay_1.csv"
|
||
}
|
||
}
|
||
```
|
||
|
||
**响应示例** (全部重复):
|
||
```json
|
||
{
|
||
"result": true,
|
||
"message": "文件中的 50 条记录全部已存在,无需重复导入",
|
||
"data": {
|
||
"bill_type": "alipay",
|
||
"raw_count": 0,
|
||
"cleaned_count": 0,
|
||
"duplicate_count": 50
|
||
}
|
||
}
|
||
```
|
||
|
||
**响应示例** (失败):
|
||
```json
|
||
{
|
||
"result": false,
|
||
"message": "账单类型无效,仅支持 alipay 或 wechat"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 3. 获取账单列表
|
||
|
||
**端点**: `GET /api/bills`
|
||
|
||
**功能**: 获取清洗后的账单数据,支持分页、筛选和排序
|
||
|
||
**请求参数** (Query):
|
||
|
||
| 参数名 | 类型 | 必需 | 说明 |
|
||
|-------|------|------|------|
|
||
| page | number | - | 页码(从1开始,默认: 1) |
|
||
| page_size | number | - | 每页数量(默认: 20,最大: 100) |
|
||
| start_date | string | - | 开始日期(YYYY-MM-DD 格式) |
|
||
| end_date | string | - | 结束日期(YYYY-MM-DD 格式) |
|
||
| category | string | - | 交易分类筛选 |
|
||
| type | string | - | 账单来源:`alipay`、`wechat` 或 `manual` |
|
||
| income_expense | string | - | 收支类型:`收入` 或 `支出` |
|
||
|
||
**响应示例**:
|
||
```json
|
||
{
|
||
"result": true,
|
||
"data": {
|
||
"total": 150,
|
||
"page": 1,
|
||
"page_size": 20,
|
||
"pages": 8,
|
||
"total_expense": 5250.50,
|
||
"total_income": 8000.00,
|
||
"bills": [
|
||
{
|
||
"_id": "507f1f77bcf86cd799439011",
|
||
"bill_type": "alipay",
|
||
"transaction_id": "2021123456789",
|
||
"merchant_order_no": "2021123456",
|
||
"time": "2026-01-10T10:30:00Z",
|
||
"category": "餐饮美食",
|
||
"merchant": "星巴克",
|
||
"description": "咖啡",
|
||
"income_expense": "支出",
|
||
"amount": 28.00,
|
||
"pay_method": "支付宝",
|
||
"status": "交易成功",
|
||
"remark": "员工补贴",
|
||
"review_level": "",
|
||
"created_at": "2026-01-10T10:30:00Z",
|
||
"updated_at": "2026-01-10T10:30:00Z",
|
||
"source_file": "20260110_150405_alipay_1.csv",
|
||
"upload_batch": "20260110_150405"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
**错误响应**:
|
||
```json
|
||
{
|
||
"result": false,
|
||
"message": "数据库未连接"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 4. 手动创建账单
|
||
|
||
**端点**: `POST /api/bills/manual`
|
||
|
||
**功能**: 手动添加单条或批量账单,支持去重
|
||
|
||
**请求方式**: `application/json`
|
||
|
||
**请求体**:
|
||
```json
|
||
{
|
||
"bills": [
|
||
{
|
||
"time": "2026-01-10 14:30:00",
|
||
"category": "餐饮美食",
|
||
"merchant": "测试餐厅",
|
||
"description": "午餐",
|
||
"income_expense": "支出",
|
||
"amount": 50.00,
|
||
"pay_method": "支付宝",
|
||
"status": "交易成功",
|
||
"remark": "测试账单"
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
**请求参数说明**:
|
||
|
||
| 参数名 | 类型 | 必需 | 说明 |
|
||
|-------|------|------|------|
|
||
| bills | Array | ✓ | 账单数组 |
|
||
| bills[].time | string | ✓ | 交易时间(格式: `YYYY-MM-DD HH:mm:ss`) |
|
||
| bills[].category | string | ✓ | 交易分类 |
|
||
| bills[].income_expense | string | ✓ | 收支类型:`收入` 或 `支出` |
|
||
| bills[].amount | number | ✓ | 金额(>0) |
|
||
| bills[].merchant | string | - | 交易对方(可选) |
|
||
| bills[].description | string | - | 商品说明 |
|
||
| bills[].pay_method | string | - | 支付方式 |
|
||
| bills[].status | string | - | 交易状态(默认: `交易成功`) |
|
||
| bills[].remark | string | - | 备注 |
|
||
|
||
**响应示例** (成功):
|
||
```json
|
||
{
|
||
"result": true,
|
||
"message": "创建成功",
|
||
"data": {
|
||
"success": 1,
|
||
"failed": 0,
|
||
"duplicates": 0
|
||
}
|
||
}
|
||
```
|
||
|
||
**响应示例** (部分失败):
|
||
```json
|
||
{
|
||
"result": true,
|
||
"message": "创建成功",
|
||
"data": {
|
||
"success": 3,
|
||
"failed": 1,
|
||
"duplicates": 0
|
||
}
|
||
}
|
||
```
|
||
|
||
**错误响应**:
|
||
```json
|
||
{
|
||
"result": false,
|
||
"message": "时间格式错误: 2026-01-10"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 5. 获取需要复核的记录
|
||
|
||
**端点**: `GET /api/review`
|
||
|
||
**功能**: 获取清洗过程中标记为需要人工复核的记录
|
||
|
||
**请求参数** (Query):
|
||
|
||
| 参数名 | 类型 | 必需 | 说明 |
|
||
|-------|------|------|------|
|
||
| file | string | ✓ | 输出文件名(来自上传接口返回值) |
|
||
| page | number | - | 页码(默认: 1) |
|
||
| page_size | number | - | 每页数量(默认: 20) |
|
||
|
||
**响应示例**:
|
||
```json
|
||
{
|
||
"result": true,
|
||
"data": {
|
||
"total": 5,
|
||
"page": 1,
|
||
"page_size": 20,
|
||
"high_count": 2,
|
||
"low_count": 3,
|
||
"records": [
|
||
{
|
||
"row": 15,
|
||
"time": "2026-01-10 10:30:00",
|
||
"merchant": "未知商户",
|
||
"amount": 100.00,
|
||
"category": "未分类",
|
||
"review_level": "HIGH",
|
||
"issue": "无法识别的商户名称",
|
||
"suggestion": "请手动确认或修改商户名称"
|
||
}
|
||
]
|
||
}
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 6. 获取月度统计数据
|
||
|
||
**端点**: `GET /api/monthly-stats`
|
||
|
||
**功能**: 获取每个月的收入、支出统计(不受日期筛选影响,返回全部月份数据)
|
||
|
||
**请求参数**: 无
|
||
|
||
**响应示例**:
|
||
```json
|
||
{
|
||
"result": true,
|
||
"data": [
|
||
{
|
||
"month": "2025-12",
|
||
"expense": 8234.50,
|
||
"income": 15000.00
|
||
},
|
||
{
|
||
"month": "2026-01",
|
||
"expense": 5250.50,
|
||
"income": 8000.00
|
||
}
|
||
]
|
||
}
|
||
```
|
||
|
||
**错误响应**:
|
||
```json
|
||
{
|
||
"result": false,
|
||
"message": "数据库未连接"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 数据模型
|
||
|
||
### 账单数据 (CleanedBill)
|
||
|
||
```go
|
||
type CleanedBill struct {
|
||
ID primitive.ObjectID `bson:"_id,omitempty" json:"_id"`
|
||
BillType string `bson:"bill_type" json:"bill_type"` // alipay/wechat/manual
|
||
TransactionID string `bson:"transaction_id" json:"transaction_id"`
|
||
MerchantOrderNo string `bson:"merchant_order_no" json:"merchant_order_no"`
|
||
Time time.Time `bson:"time" json:"time"`
|
||
Category string `bson:"category" json:"category"`
|
||
Merchant string `bson:"merchant" json:"merchant"`
|
||
Description string `bson:"description" json:"description"`
|
||
IncomeExpense string `bson:"income_expense" json:"income_expense"` // 收入/支出
|
||
Amount float64 `bson:"amount" json:"amount"`
|
||
PayMethod string `bson:"pay_method" json:"pay_method"`
|
||
Status string `bson:"status" json:"status"`
|
||
Remark string `bson:"remark" json:"remark"`
|
||
ReviewLevel string `bson:"review_level" json:"review_level"` // HIGH/LOW/""
|
||
CreatedAt time.Time `bson:"created_at" json:"created_at"`
|
||
UpdatedAt time.Time `bson:"updated_at" json:"updated_at"`
|
||
SourceFile string `bson:"source_file" json:"source_file"`
|
||
UploadBatch string `bson:"upload_batch" json:"upload_batch"`
|
||
}
|
||
```
|
||
|
||
### 月度统计 (MonthlyStat)
|
||
|
||
```go
|
||
type MonthlyStat struct {
|
||
Month string `bson:"month" json:"month"` // YYYY-MM
|
||
Expense float64 `bson:"expense" json:"expense"` // 支出总额
|
||
Income float64 `bson:"income" json:"income"` // 收入总额
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 错误处理
|
||
|
||
所有 API 响应都遵循以下格式:
|
||
|
||
```json
|
||
{
|
||
"result": boolean,
|
||
"message": "错误或成功消息",
|
||
"data": {}
|
||
}
|
||
```
|
||
|
||
### 常见错误码
|
||
|
||
| HTTP 状态码 | result | 说明 |
|
||
|-----------|--------|------|
|
||
| 200 | true | 请求成功 |
|
||
| 200 | false | 业务逻辑错误(如参数不合法) |
|
||
| 400 | false | 请求参数错误 |
|
||
| 404 | false | 资源不存在 |
|
||
| 500 | false | 服务器内部错误 |
|
||
|
||
---
|
||
|
||
## 时区说明
|
||
|
||
- **存储**: 所有时间在数据库中按 **UTC 时区** 存储(ISO 8601 格式)
|
||
- **输入**: 手动添加账单时,时间按 **本地时区** 解析(使用 `time.ParseInLocation`)
|
||
- **输出**: API 返回的时间均为 ISO 8601 UTC 格式
|
||
|
||
### 时间格式
|
||
|
||
- 手动创建账单时: `YYYY-MM-DD HH:mm:ss`(本地时间)
|
||
- 日期筛选参数: `YYYY-MM-DD`(本地日期)
|
||
- API 返回时间: ISO 8601 UTC 格式(如 `2026-01-10T10:30:00Z`)
|
||
|
||
---
|
||
|
||
## 使用示例
|
||
|
||
### 上传账单文件
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/api/upload \
|
||
-F "file=@statement.csv" \
|
||
-F "type=alipay" \
|
||
-F "format=csv"
|
||
```
|
||
|
||
### 查询账单列表
|
||
|
||
```bash
|
||
curl "http://localhost:8080/api/bills?page=1&page_size=20&start_date=2026-01-01&end_date=2026-01-10&type=alipay"
|
||
```
|
||
|
||
### 手动添加账单
|
||
|
||
```bash
|
||
curl -X POST http://localhost:8080/api/bills/manual \
|
||
-H "Content-Type: application/json" \
|
||
-d '{
|
||
"bills": [
|
||
{
|
||
"time": "2026-01-10 14:30:00",
|
||
"category": "餐饮美食",
|
||
"merchant": "星巴克",
|
||
"income_expense": "支出",
|
||
"amount": 28.00,
|
||
"pay_method": "支付宝"
|
||
}
|
||
]
|
||
}'
|
||
```
|
||
|
||
### 获取月度统计
|
||
|
||
```bash
|
||
curl http://localhost:8080/api/monthly-stats
|
||
```
|
||
|
||
---
|
||
|
||
## 配置
|
||
|
||
服务器配置文件位于 `config.yaml`,主要配置项:
|
||
|
||
```yaml
|
||
server:
|
||
port: "8080"
|
||
|
||
mongodb:
|
||
uri: "mongodb://admin:password@localhost:27017"
|
||
database: "billai"
|
||
collections:
|
||
raw: "bills_raw"
|
||
cleaned: "bills_cleaned"
|
||
|
||
analyzer:
|
||
mode: "http" # http 或 process
|
||
url: "http://analyzer:8001"
|
||
```
|
||
|
||
---
|
||
|
||
## 开发信息
|
||
|
||
### 目录结构
|
||
|
||
```
|
||
server/
|
||
├── main.go # 程序入口
|
||
├── router/ # 路由配置
|
||
├── handler/ # 请求处理器
|
||
├── service/ # 业务逻辑
|
||
├── repository/ # 数据访问层
|
||
├── database/ # 数据库连接
|
||
├── model/ # 数据模型
|
||
├── adapter/ # 外部服务适配器
|
||
├── config/ # 配置管理
|
||
└── README.md # 本文件
|
||
```
|
||
|
||
### 主要依赖
|
||
|
||
- **Gin**: Web 框架
|
||
- **MongoDB Driver**: 数据库驱动
|
||
- **Go 1.21**: 运行环境
|
||
|
||
---
|
||
|
||
## 版本历史
|
||
|
||
| 版本 | 日期 | 说明 |
|
||
|-----|------|------|
|
||
| 1.0.0 | 2026-01-10 | 初始版本,支持账单上传、查询、手动添加和统计 |
|
||
|