# 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 | 初始版本,支持账单上传、查询、手动添加和统计 |