docs: 新增用户认证、OSS 存储、异步任务设计
- database.md: 新增 user 表,project 关联 user_id,恢复 OSS 对象存储, 移除 60 分钟文件过期,新增 JWT/OSS 环境变量配置 - api.md: 新增认证章节和错误码表,补充用户注册/登录/修改密码接口, 工程管理新增列表/详情/删除接口,各接口补充错误响应说明 - async-tasks.md: 完善任务队列设计、Worker 流程、并发控制、管线进度、 质检重试与任务级重试策略、进度推送方式
This commit is contained in:
+250
-20
@@ -6,6 +6,39 @@
|
||||
{ "code": 0, "message": "ok", "data": {} }
|
||||
```
|
||||
|
||||
## 认证
|
||||
|
||||
除健康检查和注册登录外,所有接口需在请求头携带 Bearer Token:
|
||||
|
||||
```
|
||||
Authorization: Bearer <token>
|
||||
```
|
||||
|
||||
Token 通过登录接口获取,过期时间由 `GEN2D_JWT_EXPIRE` 控制(默认 7200 秒)。Token 过期或无效时返回:
|
||||
|
||||
```json
|
||||
{ "code": 401, "message": "未登录或 Token 已过期", "data": null }
|
||||
```
|
||||
|
||||
权限不足时返回:
|
||||
|
||||
```json
|
||||
{ "code": 403, "message": "无权访问该资源", "data": null }
|
||||
```
|
||||
|
||||
## 错误码
|
||||
|
||||
| code | 含义 | 场景 |
|
||||
|------|------|------|
|
||||
| 0 | 成功 | — |
|
||||
| 400 | 请求参数错误 | 缺少必填字段、格式不合法 |
|
||||
| 401 | 未认证 | Token 缺失、过期、无效 |
|
||||
| 403 | 无权访问 | 访问不属于自己的资源 |
|
||||
| 404 | 资源不存在 | 工程/任务/素材 ID 不存在 |
|
||||
| 409 | 冲突 | 用户名或邮箱已注册 |
|
||||
| 429 | 请求过于频繁 | 触发速率限制 |
|
||||
| 500 | 服务器内部错误 | 未预期异常 |
|
||||
|
||||
## 状态说明
|
||||
|
||||
- [x] 已完成
|
||||
@@ -19,14 +52,157 @@
|
||||
|------|------|------|------|
|
||||
| [x] | GET | `/api/v1/health` | 健康检查 |
|
||||
|
||||
## 工程管理
|
||||
## 用户认证
|
||||
|
||||
| 状态 | 方法 | 路径 | 说明 |
|
||||
|------|------|------|------|
|
||||
| [ ] | POST | `/api/v1/auth/register` | 用户注册 |
|
||||
| [ ] | POST | `/api/v1/auth/login` | 用户登录 |
|
||||
| [ ] | GET | `/api/v1/auth/me` | 获取当前用户信息 |
|
||||
| [ ] | PUT | `/api/v1/auth/password` | 修改密码 |
|
||||
|
||||
### POST /api/v1/auth/register
|
||||
|
||||
```json
|
||||
{
|
||||
"username": "player1",
|
||||
"email": "player1@example.com",
|
||||
"password": "s3cretP@ss"
|
||||
}
|
||||
```
|
||||
|
||||
| 字段 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| `username` | string | 是 | 3-64 字符,字母数字下划线 |
|
||||
| `email` | string | 是 | 邮箱地址 |
|
||||
| `password` | string | 是 | 8-128 字符 |
|
||||
|
||||
响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "ok",
|
||||
"data": {
|
||||
"id": "user_a1B2c3D4",
|
||||
"username": "player1",
|
||||
"email": "player1@example.com",
|
||||
"token": "eyJhbGciOiJIUzI1NiIs...",
|
||||
"expiresAt": "2026-05-24T12:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### POST /api/v1/auth/login
|
||||
|
||||
```json
|
||||
{
|
||||
"username": "player1",
|
||||
"password": "s3cretP@ss"
|
||||
}
|
||||
```
|
||||
|
||||
支持 `username` 或 `email` 登录:
|
||||
|
||||
```json
|
||||
{
|
||||
"email": "player1@example.com",
|
||||
"password": "s3cretP@ss"
|
||||
}
|
||||
```
|
||||
|
||||
响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "ok",
|
||||
"data": {
|
||||
"id": "user_a1B2c3D4",
|
||||
"username": "player1",
|
||||
"email": "player1@example.com",
|
||||
"token": "eyJhbGciOiJIUzI1NiIs...",
|
||||
"expiresAt": "2026-05-24T12:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### GET /api/v1/auth/me
|
||||
|
||||
需认证。响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "ok",
|
||||
"data": {
|
||||
"id": "user_a1B2c3D4",
|
||||
"username": "player1",
|
||||
"email": "player1@example.com",
|
||||
"createdAt": "2026-05-24T10:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### PUT /api/v1/auth/password
|
||||
|
||||
需认证。
|
||||
|
||||
```json
|
||||
{
|
||||
"oldPassword": "s3cretP@ss",
|
||||
"newPassword": "n3wS3cretP@ss"
|
||||
}
|
||||
```
|
||||
|
||||
错误响应:
|
||||
|
||||
| 场景 | code | message |
|
||||
|------|------|---------|
|
||||
| 原密码错误 | 400 | 原密码不正确 |
|
||||
| 用户名已存在 | 409 | 用户名已被注册 |
|
||||
| 邮箱已存在 | 409 | 邮箱已被注册 |
|
||||
|
||||
## 工程管理
|
||||
|
||||
需认证。以下接口均需携带 Bearer Token,工程归属于当前登录用户。
|
||||
|
||||
| 状态 | 方法 | 路径 | 说明 |
|
||||
|------|------|------|------|
|
||||
| [ ] | GET | `/api/v1/projects` | 获取当前用户的工程列表 |
|
||||
| [ ] | POST | `/api/v1/projects` | 创建工程 |
|
||||
| [ ] | GET | `/api/v1/projects/:projectId` | 获取工程信息 |
|
||||
| [ ] | DELETE | `/api/v1/projects/:projectId` | 删除工程(级联删除任务和素材) |
|
||||
| [ ] | GET | `/api/v1/projects/:projectId/tasks` | 获取工程下的任务列表 |
|
||||
|
||||
### GET /api/v1/projects
|
||||
|
||||
获取当前用户的工程列表。
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `page` | int | 页码,默认 1 |
|
||||
| `pageSize` | int | 每页条数,默认 20 |
|
||||
|
||||
响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "ok",
|
||||
"data": {
|
||||
"total": 3,
|
||||
"projects": [
|
||||
{
|
||||
"id": "proj_abc123",
|
||||
"name": "我的像素游戏",
|
||||
"createdAt": "2026-05-24T10:00:00Z"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### POST /api/v1/projects
|
||||
|
||||
```json
|
||||
@@ -50,6 +226,44 @@
|
||||
}
|
||||
```
|
||||
|
||||
### GET /api/v1/projects/:projectId
|
||||
|
||||
响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "ok",
|
||||
"data": {
|
||||
"id": "proj_abc123",
|
||||
"name": "我的像素游戏",
|
||||
"createdAt": "2026-05-24T10:00:00Z",
|
||||
"updatedAt": "2026-05-24T10:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
错误响应:
|
||||
|
||||
| 场景 | code | message |
|
||||
|------|------|---------|
|
||||
| projectId 不存在 | 404 | 工程不存在 |
|
||||
| 工程不属于当前用户 | 403 | 无权访问该工程 |
|
||||
|
||||
### DELETE /api/v1/projects/:projectId
|
||||
|
||||
级联删除工程下的所有任务、素材及 OSS 文件。
|
||||
|
||||
响应:
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
"message": "ok",
|
||||
"data": null
|
||||
}
|
||||
```
|
||||
|
||||
### GET /api/v1/projects/:projectId/tasks
|
||||
|
||||
| 参数 | 类型 | 说明 |
|
||||
@@ -80,6 +294,8 @@
|
||||
|
||||
## 工程风格
|
||||
|
||||
需认证。风格归属于工程,仅工程所属用户可操作。
|
||||
|
||||
| 状态 | 方法 | 路径 | 说明 |
|
||||
|------|------|------|------|
|
||||
| [ ] | GET | `/api/v1/projects/:projectId/style` | 获取工程风格 |
|
||||
@@ -100,6 +316,8 @@
|
||||
|
||||
## 素材生成
|
||||
|
||||
需认证。任务归属于当前用户的工程,跨用户访问返回 403。
|
||||
|
||||
| 状态 | 方法 | 路径 | 说明 |
|
||||
|------|------|------|------|
|
||||
| [ ] | POST | `/api/v1/generate` | 提交生成任务,返回 taskId |
|
||||
@@ -153,6 +371,15 @@
|
||||
}
|
||||
```
|
||||
|
||||
去重:相同 `prompt + assetType + params` 的并发请求返回已有 taskId,不重复创建任务。
|
||||
|
||||
错误响应:
|
||||
|
||||
| 场景 | code | message |
|
||||
|------|------|---------|
|
||||
| projectId 不存在或不属于当前用户 | 403 | 无权访问该工程 |
|
||||
| prompt 为空 | 400 | prompt 不能为空 |
|
||||
|
||||
### GET /api/v1/tasks/:taskId
|
||||
|
||||
响应:
|
||||
@@ -166,39 +393,40 @@
|
||||
"projectId": "proj_abc123",
|
||||
"prompt": "一个拿剑的小人",
|
||||
"assetType": "sprite",
|
||||
"taskStyle": null,
|
||||
"params": { "resolution": 64, "format": "spritesheet" },
|
||||
"status": "running",
|
||||
"stage": "asset_generator",
|
||||
"progress": 45,
|
||||
"retryCount": 0,
|
||||
"error": null,
|
||||
"createdAt": "2026-05-24T10:05:00Z",
|
||||
"updatedAt": "2026-05-24T10:05:30Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
任务状态机:
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| `status` | string | 任务状态:`pending` / `running` / `completed` / `failed` |
|
||||
| `stage` | string | 当前管线阶段,`running` 时有值 |
|
||||
| `progress` | int | 0-100,整体进度 |
|
||||
| `retryCount` | int | 质检重试次数 |
|
||||
| `error` | string | 失败原因,仅 `failed` 时有值 |
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> pending
|
||||
pending --> running : 管线开始执行
|
||||
running --> completed : 四阶段全部通过
|
||||
running --> failed : 节点执行失败 / 超过重试次数
|
||||
completed --> [*]
|
||||
failed --> [*]
|
||||
```
|
||||
状态机与管线阶段详见 [异步任务](async-tasks.md)。
|
||||
|
||||
管线阶段(对应 Eino Graph 节点):
|
||||
错误响应:
|
||||
|
||||
| 阶段 | 说明 |
|
||||
|------|------|
|
||||
| `prompt_builder` | 合并风格,生成三段式提示词 |
|
||||
| `asset_generator` | 调用 AI 推理 API 出图 |
|
||||
| `quality_supervisor` | 视觉模型质检(可能触发重试回到 prompt_builder) |
|
||||
| `format_adapter` | 格式转换、spritesheet 打包 |
|
||||
| 场景 | code | message |
|
||||
|------|------|---------|
|
||||
| taskId 不存在 | 404 | 任务不存在 |
|
||||
| 任务不属于当前用户 | 403 | 无权访问该任务 |
|
||||
|
||||
### GET /api/v1/tasks/:taskId/assets
|
||||
|
||||
任务状态为 `completed` 时返回素材列表,其他状态返回空数组。
|
||||
|
||||
```json
|
||||
{
|
||||
"code": 0,
|
||||
@@ -207,7 +435,7 @@ stateDiagram-v2
|
||||
"assets": [
|
||||
{
|
||||
"id": "asset_001",
|
||||
"url": "/files/tasks/task_xyz789/spritesheet.png",
|
||||
"url": "https://cdn.example.com/users/user_a1B2c3D4/projects/proj_abc123/tasks/task_xyz789/output/spritesheet.png",
|
||||
"format": "png",
|
||||
"width": 256,
|
||||
"height": 64,
|
||||
@@ -225,7 +453,7 @@ stateDiagram-v2
|
||||
|
||||
### WebSocket 消息格式
|
||||
|
||||
连接路径:`ws://host/api/v1/tasks/:taskId/ws`
|
||||
连接路径:`ws://host/api/v1/tasks/:taskId/ws?token=<jwt>`(通过 query 参数传递 Token)
|
||||
|
||||
```typescript
|
||||
interface PipelineProgress {
|
||||
@@ -267,6 +495,8 @@ interface PipelineProgress {
|
||||
|
||||
## 缓存管理
|
||||
|
||||
需认证。
|
||||
|
||||
| 状态 | 方法 | 路径 | 说明 |
|
||||
|------|------|------|------|
|
||||
| [ ] | DELETE | `/api/v1/cache/:key` | 清除特定缓存 |
|
||||
|
||||
Reference in New Issue
Block a user