# API 接入指南 ## 认证方式 工作台网页使用 HttpOnly Cookie 会话。外部客户端使用: ```http Authorization: Bearer dd_live_xxx ``` API Key 明文只在创建时返回一次,数据库仅保存 SHA-256 哈希。平台管理员创建平台级 Key;组管理员创建本组项目级 Key。失效或越权请求会返回 `401` 或 `403`。 ## 主要路由 | 路由组 | 用途 | |---|---| | `/api/auth/*` | 登录、退出、当前账号、修改密码 | | `/api/management/groups` | 运营组创建、改名、启停和管理员更换 | | `/api/management/users` | 账号创建、改名、启停和重置密码 | | `/api/management/api-keys` | API Key 创建、查询和吊销 | | `/api/management/audit-logs` | 审计日志查询 | | `/api/management/storage-configs` | COS 配置、连接测试和启用 | | `/api/projects` | 项目创建、查询和编辑 | | `/api/projects/:projectId/collections` | 作品交付集创建、查询和编辑 | | `/api/notes` | 作品查询与创建 | | `/api/notes/:noteId/versions` | 创建作品新版本 | | `/api/notes/:noteId/status` | 草稿与待验收状态切换 | | `/api/notes/:noteId/text-annotations` | 标题/正文批注 | | `/api/images/:imageId/annotations` | 图片坐标批注 | | `/api/review/:slug/*` | 客户登录、浏览、反馈与验收 | | `/api/health` | 数据库就绪检查 | ## 查询运营组、项目、作品交付集和作品 调用方不需要预先知道数据库 ID。使用 API Key 按顺序查询: ```bash # 返回 Key 有权访问的项目,响应包含 group_id、group_name 和项目 id curl http://localhost:3010/api/projects \ -H "Authorization: Bearer $DELIVERY_DESK_API_KEY" # 查询项目中的作品交付集 curl http://localhost:3010/api/projects/1/collections \ -H "Authorization: Bearer $DELIVERY_DESK_API_KEY" # 查询交付集中的作品,响应包含作品 id、external_id 和 version_number curl "http://localhost:3010/api/notes?collectionId=1" \ -H "Authorization: Bearer $DELIVERY_DESK_API_KEY" ``` 项目级 Key 的项目列表只会返回绑定项目;平台级 Key 可以查询全部运营组的项目。创建作品时只传 `collectionId`,服务会据此确定项目和运营组并校验权限,不需要重复传递 `projectId` 或 `groupId`。 ## 创建项目 平台级 API Key 可以指定目标运营组。项目级 Key 不能创建项目。 ```bash curl -X POST http://localhost:3010/api/projects \ -H "Authorization: Bearer $DELIVERY_DESK_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name":"7 月内容计划","slug":"july-content","groupId":1,"client_description":"客户可见说明"}' ``` `slug` 仅支持小写字母、数字和连字符,并作为客户验收链接的一部分。 ## 创建作品交付集 ```bash curl -X POST http://localhost:3010/api/projects/1/collections \ -H "Authorization: Bearer $DELIVERY_DESK_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name":"2026 年 7 月交付","client_description":"本月交付内容"}' ``` 新建作品交付集的 `status` 为 `draft`。上传首件作品后自动变为 `reviewing`;全部非草稿作品通过后自动变为 `completed`。响应中的 `work_count`、`approved_count` 和 `completed_at` 分别表示已提交作品数、已通过作品数和本次完成时间。调用方不应直接维护作品交付集状态;创建作品、新版本、修改验收状态和删除作品都会触发服务端重算。 ## 上传作品 外部客户端使用 JSON 创建作品,`images` 直接传入 1–30 个公开可读的 HTTP/HTTPS 图片 URL。服务只保存 URL,不会下载图片或再次上传到 COS。数组顺序就是展示顺序,第一张为封面。 ```bash curl -X POST http://localhost:3010/api/notes \ -H "Authorization: Bearer $DELIVERY_DESK_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "collectionId": 1, "externalId": "client-work-20260721-001", "title": "作品标题", "description": "正文内容", "tags": ["用户填写的标签原文"], "images": [ "https://cdn.example.com/works/01.jpg", "https://cdn.example.com/works/02.jpg" ] }' ``` `externalId` 是调用方在当前作品交付集内的作品唯一标识,支持字母、数字、点、下划线、冒号和横线,最长 128 位。相同 `collectionId + externalId` 的重复请求不会重复创建作品,而会以 `200` 返回原作品并包含 `"idempotent": true`。创建成功响应中的 `id` 是后续上传版本所需的 `workId`;如果调用方丢失了该 ID,可以通过 `GET /api/notes?collectionId=1&externalId=client-work-20260721-001` 找回。 URL 图片不会进入当前配置的 COS,也不会由服务检查其内容或长期可用性,因此调用方需要保证链接公开、稳定且确实指向图片。工作台手动上传仍接受 JPEG、PNG、GIF、WebP 和 AVIF。标签按原文保存和展示,不会自动添加 `#` 或拆分为标签库。 ## 创建新版本 ```bash curl -X POST http://localhost:3010/api/notes/12/versions \ -H "Authorization: Bearer $DELIVERY_DESK_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "修改后的标题", "description": "修改后的正文", "tags": ["修改后的标签原文"], "images": [ "https://cdn.example.com/works/v2-01.jpg", "https://cdn.example.com/works/v2-02.jpg" ] }' ``` 批注绑定作品版本或具体图片,不会因新版本覆盖历史验收证据。 ## Python 冒烟脚本 项目自带 `tests/api_create_work.py`,只使用 Python 标准库。推荐通过环境变量提供项目级 API Key: ```powershell $env:DELIVERY_DESK_API_KEY = 'dd_live_xxx' python tests/api_create_work.py --project-id 1 --collection-id 1 # 为已有作品创建新版本 python tests/api_create_work.py --project-id 1 --collection-id 1 --work-id 12 ``` 如果项目级 Key 只能访问一个项目,并且项目下只有一个作品交付集,可以省略两个 ID。脚本也支持不传 Key、改用 `--username` 后交互输入密码。 ## 错误响应 错误统一以 JSON 返回: ```json { "error": "错误说明" } ``` 常见状态码:`400` 输入无效、`401` 未认证、`403` 越权、`404` 资源不存在、`409` 唯一性或状态冲突、`500` 服务端错误。