152 lines
6.5 KiB
Markdown
152 lines
6.5 KiB
Markdown
# 项目 API 文档(益选营业额系统)
|
||
|
||
## 概述
|
||
- 基础地址:`http://<服务器或域名>:<PORT>`(默认 `57778`,本地开发默认 `5000`)
|
||
- 返回格式:`application/json`
|
||
- 本地时区:`Asia/Shanghai`,时间字段按本地时区输出
|
||
- 截止时间:支持分钟级配置(`config.json` 中 `cutoff_time`,例如 `13:18`;未设置时使用 `cutoff_hour`,分钟视为 `00`)
|
||
|
||
## 认证
|
||
- 管理接口需在请求头携带 `X-Admin-Token: <ADMIN_TOKEN>`(容器环境变量或 `.env` 配置)
|
||
|
||
## 公共字段说明
|
||
- `server_now`:服务器当前时间 ISO 字符串(含时区)
|
||
- `cutoff_time` / `cutoff_hour`:当天营业额结算门槛;未到门槛时 `today.amount=null`
|
||
- `is_final`:某日期是否已定版(仅定版数据会计入汇总)
|
||
|
||
## 接口列表
|
||
|
||
### 1. 指标看板
|
||
- 路径:`GET /api/metrics`
|
||
- 说明:返回今日/昨日/前日、本周、上周、本月汇总数据;`today.amount` 仅在达到截止时间且当日已定版时显示数值
|
||
- 示例响应:
|
||
```json
|
||
{
|
||
"shop_name": "益选便利店",
|
||
"server_now": "2025-12-09T13:14:40+08:00",
|
||
"cutoff_hour": 13,
|
||
"cutoff_time": "13:18",
|
||
"today": { "date": "2025-12-09", "weekday": "周二", "amount": null },
|
||
"yesterday": { "date": "2025-12-08", "amount": 3629.76 },
|
||
"day_before": { "date": "2025-12-07", "amount": 2408.70 },
|
||
"this_week": { "start": "2025-12-08", "end": "2025-12-08", "total": 3629.76 },
|
||
"last_week": { "start": "2025-12-01", "end": "2025-12-07", "total": 4211.79 },
|
||
"this_month": { "start": "2025-12-01", "end": "2025-12-08", "total": 7841.55 }
|
||
}
|
||
```
|
||
- 代码位置:`backend/app.py:225`
|
||
|
||
### 2. 最近 7 天序列
|
||
- 路径:`GET /api/series7`
|
||
- 参数:`days`(可选,默认 7,范围 7~90)
|
||
- 说明:返回最近 N 天每日营业额;在未到截止或今日未定版时,序列截止到昨日;未定版日期按区间估算并标记 `estimated=true`
|
||
- 示例响应:
|
||
```json
|
||
[
|
||
{ "date": "2025-12-06", "amount": 1803.09, "estimated": false },
|
||
{ "date": "2025-12-07", "amount": 2408.70, "estimated": false },
|
||
{ "date": "2025-12-08", "amount": 3629.76, "estimated": false }
|
||
]
|
||
```
|
||
- 代码位置:`backend/app.py:287`
|
||
|
||
### 3. 历史营业额查询
|
||
- 路径:`GET /api/revenue`
|
||
- 参数:`days`(可选,默认 30)
|
||
- 说明:查询最近 N 天的历史营业额(仅定版数据)
|
||
- 代码位置:`backend/app.py:365`
|
||
|
||
### 4. 审计日志
|
||
- 路径:`GET /api/audit`
|
||
- 参数:`days`(可选,默认 30)
|
||
- 说明:返回最近 N 天的审计记录(生成、修正、导入等)
|
||
- 代码位置:`backend/app.py:373`
|
||
|
||
### 5. 健康检查
|
||
- 路径:`GET /api/health`
|
||
- 说明:服务健康状态(数据库、调度器、时区)
|
||
- 代码位置:`backend/app.py:389`
|
||
|
||
### 6. 导出 CSV
|
||
- 路径:`GET /api/export`
|
||
- 说明:导出已定版营业额为 CSV 文本(`date,amount`)
|
||
- 代码位置:`backend/app.py:402`
|
||
|
||
### 7. 单页入口
|
||
- 路径:`GET /`、`GET /admin`
|
||
- 说明:前端看板与管理页入口(静态文件)
|
||
- 代码位置:`backend/app.py:409`、`backend/app.py:414`
|
||
|
||
### 8. 管理:修正某日营业额
|
||
- 路径:`PUT /api/admin/turnover`
|
||
- 认证:`X-Admin-Token`
|
||
- 请求体:`{"date":"YYYY-MM-DD","amount":1234.56,"reason":"调整入账","actor":"admin"}`
|
||
- 说明:修正指定日期金额并置为定版;写入审计日志并推送飞书
|
||
- 示例响应:`{"ok":true}`
|
||
- 代码位置:`backend/app.py:418`
|
||
|
||
### 9. 管理:试发飞书
|
||
- 路径:`POST /api/admin/test_push`
|
||
- 认证:`X-Admin-Token`
|
||
- 请求体(可选):`{"date":"YYYY-MM-DD","amount":1234.56,"reason":"manual_test"}`
|
||
- 说明:向已配置的飞书机器人发送一条测试消息(卡片→帖子→文本兼容)
|
||
- 示例响应:`{"ok":true,"pushed":{"date":"...","amount":1234.56,"reason":"..."}}`
|
||
- 代码位置:`backend/app.py:443`
|
||
|
||
### 10. 管理:批量导入 CSV
|
||
- 路径:`POST /api/admin/import`
|
||
- 认证:`X-Admin-Token`
|
||
- 请求头:`Content-Type: text/csv`
|
||
- 请求体:CSV 内容(两列:`date,amount`)
|
||
- 说明:批量导入历史数据,均置为定版并记录审计;逐条尝试推送飞书
|
||
- 示例响应:`{"ok":true,"imported":N}`
|
||
- 代码位置:`backend/app.py:487`
|
||
|
||
### 11. 管理:读取服务器日志
|
||
- 路径:`GET /api/admin/logs?lines=200`
|
||
- 认证:`X-Admin-Token`
|
||
- 说明:读取 `app.log` 最近 N 行(含飞书推送状态与返回体片段)
|
||
- 示例响应:`{"lines":["飞书推送卡片成功: status=200 body=...", ...]}`
|
||
- 代码位置:`backend/app.py:498`
|
||
|
||
### 12. 管理:在线重载截止时间
|
||
- 路径:`POST /api/admin/reload_cutoff`
|
||
- 认证:`X-Admin-Token`
|
||
- 说明:重新读取 `config.json` 的 `cutoff_time`/`cutoff_hour`,用新值更新 APScheduler 的每日触发任务,并立即执行一次结算检查
|
||
- 示例响应:`{"ok":true,"cutoff_time":"13:18"}`
|
||
- 代码位置:`backend/app.py:333`
|
||
|
||
### 13. 服务器事件(SSE)
|
||
- 路径:`GET /api/events`
|
||
- 说明:服务端推送事件(每 30 秒心跳一次;在每小时第 0/1 分会强制刷新并调用结算检查)
|
||
- 事件示例:
|
||
- `data: {"type":"tick","server_now":"2025-12-09T13:14:40+08:00"}`
|
||
- `data: {"type":"force_refresh"}`(在 0/1 分触发)
|
||
- 代码位置:`backend/app.py:571`
|
||
|
||
## 触发与结算逻辑(参考)
|
||
- 结算判断:本地时区 `now >= cutoff_time` 时尝试 `daily_job()`(`backend/app.py:128-149`)
|
||
- APScheduler:按 `hour:minute` 注册每日触发任务(`backend/app.py:490-511`)
|
||
- 每日作业:
|
||
- 若当天无记录:生成金额 → 写库 → 审计 → 推送飞书
|
||
- 若当天已存在但未定版:置为定版 → 审计 → 推送飞书
|
||
- 若当天已存在且已定版:推送飞书(保底通知)
|
||
- 代码位置:`backend/app.py:101-126`
|
||
|
||
## 配置文件(关键字段)
|
||
- 路径:`/app/config.json`(容器内;通过 `docker-compose.yml` 映射宿主机 `./config.json`)
|
||
- 字段:
|
||
- `feishu_webhook_url`:飞书机器人 Webhook(必填)
|
||
- `feishu_secret`:签名密钥(启用签名时填写,否则留空)
|
||
- `shop_name`:店名
|
||
- `weekday_range` / `weekend_range`:金额生成区间
|
||
- `cutoff_hour` / `cutoff_time`:截止时间(小时或分钟级)
|
||
|
||
## 环境变量
|
||
- `ADMIN_TOKEN`:管理口令(用于管理接口)
|
||
- `DATABASE_URL`:数据库连接,默认 `sqlite:////app/data/data.db`(容器),本地默认 `sqlite:///data/data.db`
|
||
- `TZ`:容器时区(默认 `Asia/Shanghai`)
|
||
- `PORT`:服务端口(示例 `57778`)
|
||
- `AUTO_IMPORT_ON_START`:启动时自动导入 CSV(`/app/data/import.csv`)
|
||
|