b9137204a0
- FilePreview.vue: add normalizedFileType computed to handle backend returning uppercase HTML/MD/PPTX (fixes preview/download buttons) - FilePreview.vue: bg-gradient-to-r from-orange-500 -> bg-orange-500 (Tailwind v4 gradient + CSS variable = transparent) - ReportCard.vue: bg-gradient-to-r -> bg-orange-600 for selected state - Add .opencode/, node_modules/, dist/ to .gitignore - Initial git setup for publish project
404 lines
7.8 KiB
Markdown
404 lines
7.8 KiB
Markdown
# 日报分发平台 API 文档
|
||
|
||
本文档面向人工阅读和 AI Agent 调用。接口均 REST 风格,JSON 格式(除文件下载外)。
|
||
|
||
---
|
||
|
||
## 基础信息
|
||
|
||
**本地开发**: `http://localhost:37821`
|
||
**Docker 部署**: `http://<服务器IP>:41733`(前端代理到后端)
|
||
|
||
> Docker 部署时,前端(41733)会自动将 `/api/*` 和 `/uploads/*` 请求转发到后端,无需单独访问后端端口。
|
||
|
||
**认证**: 当前接口均无需认证(开放接口)
|
||
|
||
---
|
||
|
||
## 1. 项目管理
|
||
|
||
### 1.1 获取所有项目
|
||
|
||
**请求**
|
||
|
||
```
|
||
GET /api/projects
|
||
```
|
||
|
||
**Python**
|
||
```python
|
||
import requests
|
||
resp = requests.get("http://192.168.31.240:41733/api/projects")
|
||
print(resp.json())
|
||
```
|
||
|
||
**curl**
|
||
```bash
|
||
curl http://192.168.31.240:41733/api/projects
|
||
```
|
||
|
||
**响应** `200 OK`
|
||
```json
|
||
[
|
||
{
|
||
"id": 1,
|
||
"name": "MiniMax 日报",
|
||
"description": "MiniMax 日报分发",
|
||
"coverImage": null,
|
||
"createdAt": "2026-05-24T11:23:28.734",
|
||
"reportCount": 1,
|
||
"todayNewReports": 1
|
||
}
|
||
]
|
||
```
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| id | Long | 项目 ID |
|
||
| name | String | 项目名称 |
|
||
| description | String | 项目描述 |
|
||
| coverImage | String? | 封面图片 URL,无则为 null |
|
||
| createdAt | String | 创建时间(ISO 8601) |
|
||
| reportCount | Integer | 该项目报告总数 |
|
||
| todayNewReports | Integer | 今日新增报告数 |
|
||
|
||
---
|
||
|
||
### 1.2 创建项目
|
||
|
||
**请求**
|
||
|
||
```
|
||
POST /api/projects
|
||
Content-Type: application/json
|
||
```
|
||
|
||
**Body**
|
||
```json
|
||
{
|
||
"name": "项目名称",
|
||
"description": "项目描述"
|
||
}
|
||
```
|
||
|
||
**Python**
|
||
```python
|
||
import requests
|
||
resp = requests.post(
|
||
"http://192.168.31.240:41733/api/projects",
|
||
json={"name": "新项目", "description": "描述"}
|
||
)
|
||
print(resp.json())
|
||
```
|
||
|
||
**curl**
|
||
```bash
|
||
curl -X POST http://192.168.31.240:41733/api/projects \
|
||
-H "Content-Type: application/json" \
|
||
-d '{"name":"新项目","description":"描述"}'
|
||
```
|
||
|
||
**响应** `201 Created`
|
||
```json
|
||
{
|
||
"id": 2,
|
||
"name": "新项目",
|
||
"description": "描述",
|
||
"coverImage": null,
|
||
"createdAt": "2026-05-24T11:33:34.658",
|
||
"reportCount": 0,
|
||
"todayNewReports": 0
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 1.3 更新项目(含封面上传)
|
||
|
||
**请求**
|
||
|
||
```
|
||
PUT /api/projects/{projectId}
|
||
Content-Type: multipart/form-data
|
||
```
|
||
|
||
**表单字段**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| name | String | 否 | 项目新名称 |
|
||
| description | String | 否 | 项目描述 |
|
||
| coverImage | File | 否 | 封面图片,支持 jpg/png/webp/gif |
|
||
|
||
**Python**
|
||
```python
|
||
import requests
|
||
resp = requests.put(
|
||
"http://192.168.31.240:41733/api/projects/1",
|
||
data={"name": "新名称"},
|
||
files={"coverImage": open("cover.png", "rb")}
|
||
)
|
||
print(resp.json())
|
||
```
|
||
|
||
**curl**
|
||
```bash
|
||
curl -X PUT http://192.168.31.240:41733/api/projects/1 \
|
||
-F "name=新名称" \
|
||
-F "coverImage=@cover.png"
|
||
```
|
||
|
||
**响应** `200 OK` — 返回更新后的项目对象,字段同 1.1
|
||
|
||
---
|
||
|
||
### 1.4 删除项目
|
||
|
||
**请求**
|
||
|
||
```
|
||
DELETE /api/projects/{projectId}
|
||
```
|
||
|
||
**Python**
|
||
```python
|
||
import requests
|
||
requests.delete("http://192.168.31.240:41733/api/projects/1")
|
||
```
|
||
|
||
**curl**
|
||
```bash
|
||
curl -X DELETE http://192.168.31.240:41733/api/projects/1
|
||
```
|
||
|
||
**响应** `204 No Content`(成功无返回体)
|
||
|
||
---
|
||
|
||
## 2. 报告管理
|
||
|
||
### 2.1 获取项目下的报告列表
|
||
|
||
**请求**
|
||
|
||
```
|
||
GET /api/reports?projectId={projectId}
|
||
```
|
||
|
||
**Python**
|
||
```python
|
||
import requests
|
||
resp = requests.get("http://192.168.31.240:41733/api/reports?projectId=1")
|
||
print(resp.json())
|
||
```
|
||
|
||
**curl**
|
||
```bash
|
||
curl "http://192.168.31.240:41733/api/reports?projectId=1"
|
||
```
|
||
|
||
**响应** `200 OK`
|
||
```json
|
||
[
|
||
{
|
||
"id": 1,
|
||
"projectId": 1,
|
||
"fileName": "MiniMax_Daily_2026-05-23.html",
|
||
"fileType": "HTML",
|
||
"filePath": "/app/uploads/1/1779622289908_MiniMax_Daily_2026-05-23.html",
|
||
"uploadTime": "2026-05-24T11:31:29.919",
|
||
"fileContent": null
|
||
}
|
||
]
|
||
```
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| id | Long | 报告 ID |
|
||
| projectId | Long | 所属项目 ID |
|
||
| fileName | String | 文件名(含扩展名) |
|
||
| fileType | String | 文件类型:`HTML` / `MD` / `PPTX` 等 |
|
||
| filePath | String | 服务器存储路径 |
|
||
| uploadTime | String | 上传时间(ISO 8601) |
|
||
| fileContent | String? | 文件内容(列表中为 null,详情接口有值) |
|
||
|
||
---
|
||
|
||
### 2.2 上传报告文件
|
||
|
||
**请求**
|
||
|
||
```
|
||
POST /api/reports
|
||
Content-Type: multipart/form-data
|
||
```
|
||
|
||
**表单字段**
|
||
|
||
| 参数 | 类型 | 必填 | 说明 |
|
||
|------|------|------|------|
|
||
| file | File | 是 | 报告文件本体 |
|
||
| projectId | Long | 是 | 上传到哪个项目 ID |
|
||
| fileType | String | 是 | 文件类型,取值:`HTML` / `MD` / `PPTX` |
|
||
|
||
**文件类型对应关系**
|
||
|
||
| fileType | 对应扩展名 | 说明 |
|
||
|----------|-----------|------|
|
||
| HTML | .html | 网页格式,推荐 |
|
||
| MD | .md | Markdown 格式 |
|
||
| PPTX | .pptx | PowerPoint 格式 |
|
||
|
||
**Python**
|
||
```python
|
||
import requests
|
||
resp = requests.post(
|
||
"http://192.168.31.240:41733/api/reports",
|
||
data={"projectId": 1, "fileType": "HTML"},
|
||
files={"file": ("日报.html", open("日报.html", "rb"), "text/html")}
|
||
)
|
||
print(resp.json())
|
||
```
|
||
|
||
**curl**
|
||
```bash
|
||
curl -X POST http://192.168.31.240:41733/api/reports \
|
||
-F "file=@日报.html" \
|
||
-F "projectId=1" \
|
||
-F "fileType=HTML"
|
||
```
|
||
|
||
> 注意:`requests.post(url, data={...}, files={...})` 中,`projectId` 和 `fileType` 放在 `data` 中,文件放在 `files` 中。错误示例:放在同一个 dict 中。
|
||
|
||
**响应** `201 Created`
|
||
```json
|
||
{
|
||
"id": 1,
|
||
"projectId": 1,
|
||
"fileName": "MiniMax_Daily_2026-05-23.html",
|
||
"fileType": "HTML",
|
||
"filePath": "/app/uploads/1/1779622289908_MiniMax_Daily_2026-05-23.html",
|
||
"uploadTime": "2026-05-24T11:31:29.919",
|
||
"fileContent": null
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2.3 获取报告详情(含文件内容)
|
||
|
||
**请求**
|
||
|
||
```
|
||
GET /api/reports/{reportId}
|
||
```
|
||
|
||
**Python**
|
||
```python
|
||
import requests
|
||
resp = requests.get("http://192.168.31.240:41733/api/reports/1")
|
||
data = resp.json()
|
||
print(data['fileContent']) # HTML/MD 文件的原文内容
|
||
```
|
||
|
||
**curl**
|
||
```bash
|
||
curl http://192.168.31.240:41733/api/reports/1
|
||
```
|
||
|
||
**响应** `200 OK`
|
||
```json
|
||
{
|
||
"id": 1,
|
||
"projectId": 1,
|
||
"fileName": "MiniMax_Daily_2026-05-23.html",
|
||
"fileType": "HTML",
|
||
"filePath": "/app/uploads/1/1779622289908_MiniMax_Daily_2026-05-23.html",
|
||
"uploadTime": "2026-05-24T11:31:29.919",
|
||
"fileContent": "<!DOCTYPE html><html>...</html>"
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
### 2.4 下载报告原始文件
|
||
|
||
**请求**
|
||
|
||
```
|
||
GET /api/reports/{reportId}/download
|
||
```
|
||
|
||
**Python**
|
||
```python
|
||
import requests
|
||
resp = requests.get("http://192.168.31.240:41733/api/reports/1/download")
|
||
with open("report.html", "wb") as f:
|
||
f.write(resp.content)
|
||
```
|
||
|
||
**curl**
|
||
```bash
|
||
curl -o report.html http://192.168.31.240:41733/api/reports/1/download
|
||
```
|
||
|
||
**响应** `200 OK`,Body 为文件的原始字节流(`application/octet-stream`)
|
||
|
||
---
|
||
|
||
### 2.5 删除报告
|
||
|
||
**请求**
|
||
|
||
```
|
||
DELETE /api/reports/{reportId}
|
||
```
|
||
|
||
**Python**
|
||
```python
|
||
import requests
|
||
requests.delete("http://192.168.31.240:41733/api/reports/1")
|
||
```
|
||
|
||
**curl**
|
||
```bash
|
||
curl -X DELETE http://192.168.31.240:41733/api/reports/1
|
||
```
|
||
|
||
**响应** `204 No Content`
|
||
|
||
---
|
||
|
||
## 3. 健康检查
|
||
|
||
**请求**
|
||
|
||
```
|
||
GET /actuator/health
|
||
```
|
||
|
||
**Python**
|
||
```python
|
||
import requests
|
||
resp = requests.get("http://192.168.31.240:41733/actuator/health")
|
||
print(resp.json()) # {"status": "UP"}
|
||
```
|
||
|
||
---
|
||
|
||
## 4. 错误码
|
||
|
||
| HTTP 状态 | 说明 |
|
||
|-----------|------|
|
||
| 200 | 成功 |
|
||
| 201 | 创建成功 |
|
||
| 204 | 删除成功(无返回体) |
|
||
| 400 | 参数错误(如 fileType 不支持) |
|
||
| 404 | 项目或报告不存在 |
|
||
| 500 | 服务器错误 |
|
||
|
||
常见 500 错误原因:
|
||
- `MissingServletRequestParameterException`: 缺少必填参数(如上传时缺少 `projectId` 或 `fileType`)
|
||
- `MultipartException`: 请求不是 multipart 格式(上传接口必须用 `multipart/form-data`)
|
||
- `NoResourceFoundException`: 接口路径不存在(确认 URL 是否正确)
|