Initial project baseline

This commit is contained in:
2026-07-04 02:40:45 +08:00
commit d5d8caef2f
86 changed files with 15590 additions and 0 deletions
+300
View File
@@ -0,0 +1,300 @@
# 后端 API 说明
本文档按 `backend/service/app.py``backend/service/schemas.py` 当前代码整理。
## 基础约定
- 默认后端地址:`http://localhost:8000`
- 请求体中上传文件使用 `multipart/form-data`
- `params` 字段是 JSON 字符串,顶层必须是对象
- 任务状态存在内存中,服务重启后状态会丢失
## Jobs
### GET `/api/health`
返回:
```json
{"ok": true}
```
### GET `/api/jobs`
返回内存中的任务状态列表,最新任务在前。
### POST `/api/jobs`
创建词云任务。
Form 字段:
| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `name_list` | 是 | `.xlsx` 名单文件 |
| `mask_image` | IMAGE 模式必填 | `.png` / `.jpg` / `.jpeg` 掩膜 |
| `font_file` | 否 | 临时上传字体,支持后端 `_FONT_EXTENSIONS` 中的格式 |
| `font_id` | 否 | 使用已上传字体 |
| `params` | 否 | JSON 字符串,合并到任务配置 |
字体格式当前支持 `.ttf``.ttc``.otf`
`params` 示例:
```json
{
"MODE": "IMAGE",
"DATA_COL_INDEX": 1,
"SEED": 42,
"N_REPETITIONS": 20,
"ENABLE_STROKE_WEIGHTS": false,
"FONT_COLOR": "#000000"
}
```
响应:
```json
{"job_id": "..." }
```
### GET `/api/jobs/{job_id}`
返回 `JobStatus`
```json
{
"job_id": "...",
"status": "queued|running|success|failed",
"stage": "...",
"progress_percent": 0,
"message": "...",
"created_at": "...",
"updated_at": "...",
"artifacts": {},
"error": ""
}
```
### GET `/api/jobs/{job_id}/detail`
返回状态和最近事件:
```json
{
"status": {},
"recent_events": []
}
```
### GET `/api/jobs/{job_id}/events`
SSE 事件流。事件数据模型:
```json
{
"type": "log|status",
"stage": "placing_words",
"progress_percent": 65,
"message": "...",
"timestamp": "..."
}
```
### GET `/api/jobs/{job_id}/result`
返回可下载产物 URL
```json
{
"job_id": "...",
"status": "success",
"image_url": "/api/jobs/{job_id}/files/png",
"svg_url": "/api/jobs/{job_id}/files/svg",
"svg_stroke_url": "/api/jobs/{job_id}/files/svg_stroke",
"db_url": "/api/jobs/{job_id}/files/db",
"metrics_url": "/api/jobs/{job_id}/files/metrics"
}
```
### GET `/api/jobs/{job_id}/files/{kind}`
下载产物。`kind` 支持:
- `png`
- `svg`
- `svg_stroke`
- `db`
- `metrics`
### GET `/api/jobs/{job_id}/locations`
查询词语位置。查询参数:
| 参数 | 说明 |
| --- | --- |
| `name` | 可选;为空返回全部,非空精确匹配 |
返回:
```json
{
"job_id": "...",
"query": "",
"total": 1,
"canvas_width": 8000,
"canvas_height": 4000,
"matches": [
{
"id": 1,
"name": "张三",
"x": 100,
"y": 200,
"font_size": 64,
"color": "#000000",
"orientation": "horizontal",
"box_x": 100,
"box_y": 200,
"box_width": 120,
"box_height": 50
}
]
}
```
### GET `/api/jobs/{job_id}/occupancy_mask`
返回 PNG,显示每个已放置词语的 bounding box。
### GET `/api/jobs/{job_id}/custom.svg`
按已生成 DB 重新导出 SVG。
查询参数:
| 参数 | 默认 | 说明 |
| --- | --- | --- |
| `fill` | `fill` | `fill` / `dot` / `line` / `ring` |
| `stroke` | `0` | 是否描边 |
| `spacing` | `10` | 点阵间距 |
| `radius` | `2` | 点阵半径 |
| `color` | `#000000` | 输出颜色 |
| `line_spacing` | `6` | 线填充间距 |
| `line_width` | `1` | 线宽 |
| `line_angle` | `0` | 线角度 |
| `ring_radius` | `3` | 环半径 |
| `ring_width` | `1` | 环线宽 |
| `ring_spacing` | `8` | 环间距 |
## Templates
### GET `/api/templates`
返回后端硬编码模板列表:
- `poster_1x2`
- `poster_4x5`
- `poster_1x1`
- `poster_3x4`
- `poster_16x9`
## Assets
### POST `/api/assets`
上传素材。Form 字段:
| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `file` | 是 | 素材文件 |
| `name` | 否 | 名称 |
| `type` | 否 | 默认 `upload` |
### POST `/api/assets/from-job/{job_id}`
从任务产物导入素材。Form 字段:
| 字段 | 默认 | 说明 |
| --- | --- | --- |
| `kind` | `png` | 产物类型 |
| `name` | 空 | 素材名称 |
| `type` | `wordcloud` | 素材类型 |
### GET `/api/assets`
列出素材。支持查询参数:
- `type`
- `job_id`
### GET `/api/assets/{asset_id}`
获取素材元数据。
### GET `/api/assets/{asset_id}/download`
下载素材文件。
### DELETE `/api/assets/{asset_id}`
删除素材。
## Projects
### POST `/api/projects`
Form 字段:
| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `name` | 是 | 工程名 |
| `template_id` | 是 | 模板 ID |
| `background_color` | 是 | `#RRGGBB` |
| `stickers` | 否 | JSON 数组字符串 |
### GET `/api/projects`
返回工程摘要列表。
### GET `/api/projects/{project_id}`
返回工程完整数据。
### PATCH `/api/projects/{project_id}`
按传入 Form 字段部分更新工程。
### DELETE `/api/projects/{project_id}`
删除工程。
## Fonts
### GET `/api/fonts`
返回字体列表,包含默认字体项。
### POST `/api/fonts`
上传字体。Form 字段:
| 字段 | 必填 | 说明 |
| --- | --- | --- |
| `file` | 是 | 字体文件 |
| `name` | 否 | 字体名 |
### DELETE `/api/fonts/{font_id}`
删除已上传字体。默认字体不能删除。
## 常见错误
| 场景 | 状态码 | detail |
| --- | --- | --- |
| `params` 不是合法 JSON | 400 | `params must be valid JSON` |
| `params` 不是对象 | 400 | `params must be JSON object` |
| `name_list``.xlsx` | 400 | `name_list must be xlsx` |
| IMAGE 模式缺少掩膜 | 400 | `mask_image is required when MODE=IMAGE` |
| job 不存在 | 404 | `job not found` |
| 产物未就绪 | 404 | `artifact not ready` |
| 文件类型未知 | 404 | `unknown artifact kind` |