Files
selfrelease 2d847e154f chore: 初始化仓库
中华文明全图鉴——文物全图系统(PC Web 地图 + NestJS API + 管理后台)。
含三大 IP(文物南迁北归 / 国宝海外回归 / 博物馆手艺人)、AI 文物对话、
文物地图与详情、以及 demo-video-kit 演示视频生成工具。
2026-06-13 20:55:44 +08:00

658 lines
11 KiB
Markdown

# 中华文明全图鉴——API 设计文档
## 1. API 设计目标
本文档定义 PC Web 地图站 MVP、管理后台和后端服务之间的 REST API 契约。第一阶段优先覆盖:登录鉴权、机构、文物、位置、标签、地图点位、数字资产和操作日志。
## 2. 通用约定
## 2.1 Base URL
```txt
/api/v1
```
## 2.2 响应格式
成功:
```json
{
"success": true,
"data": {},
"request_id": "req_20260612_xxx"
}
```
失败:
```json
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "字段校验失败",
"details": []
},
"request_id": "req_20260612_xxx"
}
```
## 2.3 分页格式
请求参数:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---:|---|
| page | number | 1 | 页码 |
| page_size | number | 20 | 每页数量,最大 100 |
响应:
```json
{
"items": [],
"pagination": {
"page": 1,
"page_size": 20,
"total": 100,
"total_pages": 5
}
}
```
## 2.4 鉴权方式
后台和需要登录的接口使用:
```txt
Authorization: Bearer <access_token>
```
游客地图接口可匿名访问,但会根据匿名权限隐藏敏感坐标。
## 2.5 常用错误码
| code | HTTP 状态 | 说明 |
|---|---:|---|
| UNAUTHORIZED | 401 | 未登录或 token 无效 |
| FORBIDDEN | 403 | 无权限 |
| NOT_FOUND | 404 | 资源不存在 |
| VALIDATION_ERROR | 422 | 参数校验失败 |
| CONFLICT | 409 | 数据冲突 |
| INTERNAL_ERROR | 500 | 服务异常 |
---
# 3. Auth API
## 3.1 登录
```http
POST /api/v1/auth/login
```
请求:
```json
{
"username": "admin",
"password": "password"
}
```
响应:
```json
{
"access_token": "jwt-token",
"user": {
"id": "uuid",
"username": "admin",
"nickname": "管理员",
"user_type": "admin",
"institution_id": null,
"roles": ["admin"]
}
}
```
## 3.2 当前用户
```http
GET /api/v1/auth/me
```
## 3.3 退出登录
```http
POST /api/v1/auth/logout
```
---
# 4. Map API
## 4.1 地图顶部统计
```http
GET /api/v1/map/summary
```
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| view | string | 否 | all、at_home、away、south_migration |
| category | string | 否 | 门类 |
| dynasty | string | 否 | 年代 |
| institution_id | uuid | 否 | 机构 |
| tags | string | 否 | 标签 code,逗号分隔 |
响应:
```json
{
"total_artifacts": 1000,
"domestic_count": 920,
"overseas_count": 80,
"on_display_count": 600,
"in_storage_count": 300,
"loaned_count": 20,
"unknown_location_count": 80
}
```
## 4.2 地图点位查询
```http
GET /api/v1/map/points
```
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| bbox | string | 是 | `minLng,minLat,maxLng,maxLat` |
| zoom | number | 是 | 地图缩放级别 |
| view | string | 否 | all、at_home、away、south_migration |
| category | string | 否 | 门类 |
| dynasty | string | 否 | 年代 |
| level | string | 否 | 级别 |
| display_status | string | 否 | 展出状态 |
| tags | string | 否 | 标签 code,逗号分隔 |
响应:
```json
{
"points": [
{
"id": "uuid",
"type": "artifact",
"artifact_id": "uuid",
"name": "千里江山图",
"category": "painting_calligraphy",
"dynasty": "北宋",
"level": "level_1",
"current_status": "at_home",
"display_status": "on_display",
"precision": "exact_building",
"coordinates": [116.397, 39.916],
"story_hook": "18 岁天才少年留下的唯一作品",
"persona_quote": "我只画了一次,但你们看了一千年。",
"institution": {
"id": "uuid",
"name": "故宫博物院"
}
}
],
"clusters": [
{
"id": "cluster_1",
"type": "cluster",
"count": 28,
"coordinates": [116.397, 39.916]
}
]
}
```
## 4.3 附近文物
```http
GET /api/v1/map/nearby
```
查询参数:
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| lng | number | 是 | 经度 |
| lat | number | 是 | 纬度 |
| radius_km | number | 否 | 半径,默认 10 |
| limit | number | 否 | 数量,默认 20 |
---
# 5. Institution API
## 5.1 机构列表
```http
GET /api/v1/institutions
```
查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| keyword | string | 名称关键词 |
| country | string | 国家 |
| province | string | 省份 |
| city | string | 城市 |
| publish_status | string | 发布状态 |
| page | number | 页码 |
| page_size | number | 每页数量 |
## 5.2 机构详情
```http
GET /api/v1/institutions/{id}
```
## 5.3 创建机构
```http
POST /api/v1/institutions
```
权限:管理员。
请求:
```json
{
"name": "故宫博物院",
"short_name": "故宫",
"institution_type": "museum",
"country": "中国",
"province": "北京",
"city": "北京",
"address": "北京市东城区景山前街4号",
"location": {
"lng": 116.397,
"lat": 39.916
},
"official_website": "https://www.dpm.org.cn",
"description": "明清两代皇家宫殿博物馆"
}
```
## 5.4 编辑机构
```http
PATCH /api/v1/institutions/{id}
```
## 5.5 启用/禁用机构
```http
PATCH /api/v1/institutions/{id}/status
```
## 5.6 机构文物列表
```http
GET /api/v1/institutions/{id}/artifacts
```
---
# 6. Artifact API
## 6.1 文物列表
```http
GET /api/v1/artifacts
```
查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| keyword | string | 名称关键词 |
| category | string | 门类 |
| dynasty | string | 年代 |
| level | string | 级别 |
| current_status | string | 当前状态 |
| institution_id | uuid | 机构 ID |
| tags | string | 标签 code,逗号分隔 |
| publish_status | string | 发布状态 |
| page | number | 页码 |
| page_size | number | 每页数量 |
## 6.2 文物详情
```http
GET /api/v1/artifacts/{id}
```
响应:
```json
{
"id": "uuid",
"unified_map_id": "CN-2026-001234",
"name": "千里江山图",
"category": "painting_calligraphy",
"dynasty": "北宋",
"level": "level_1",
"material": "绢本设色",
"dimensions": "纵51.5厘米,横1191.5厘米",
"current_status": "at_home",
"summary": "北宋青绿山水长卷。",
"story_hook": "18 岁天才少年留下的唯一作品",
"persona_quote": "我只画了一次,但你们看了一千年。",
"current_location": {},
"tags": [],
"assets": []
}
```
## 6.3 创建文物
```http
POST /api/v1/artifacts
```
权限:管理员、机构用户。
请求:
```json
{
"name": "千里江山图",
"category": "painting_calligraphy",
"dynasty": "北宋",
"level": "level_1",
"material": "绢本设色",
"dimensions": "纵51.5厘米,横1191.5厘米",
"current_status": "at_home",
"home_institution_id": "uuid",
"summary": "北宋青绿山水长卷。",
"story_hook": "18 岁天才少年留下的唯一作品",
"persona_quote": "我只画了一次,但你们看了一千年。"
}
```
## 6.4 编辑文物
```http
PATCH /api/v1/artifacts/{id}
```
## 6.5 发布文物
```http
POST /api/v1/artifacts/{id}/publish
```
## 6.6 撤回文物
```http
POST /api/v1/artifacts/{id}/unpublish
```
## 6.7 归档文物
```http
POST /api/v1/artifacts/{id}/archive
```
---
# 7. Location API
## 7.1 文物位置列表
```http
GET /api/v1/artifacts/{artifact_id}/locations
```
## 7.2 新增文物位置
```http
POST /api/v1/artifacts/{artifact_id}/locations
```
请求:
```json
{
"location_type": "domestic",
"institution_id": "uuid",
"precise_location": {
"lng": 116.397,
"lat": 39.916
},
"public_location": {
"lng": 116.397,
"lat": 39.916
},
"precision": "exact_building",
"room_name": "武英殿",
"cabinet_no": "A-01",
"display_status": "on_display",
"source_type": "institution_feed",
"source_description": "机构直供"
}
```
## 7.3 编辑位置
```http
PATCH /api/v1/locations/{id}
```
## 7.4 设置当前位置
```http
POST /api/v1/locations/{id}/set-current
```
---
# 8. Tag API
## 8.1 标签分类列表
```http
GET /api/v1/tag-categories
```
## 8.2 标签列表
```http
GET /api/v1/tags
```
查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| category_id | uuid | 分类 ID |
| keyword | string | 标签名 |
| is_active | boolean | 是否启用 |
## 8.3 新增标签
```http
POST /api/v1/tags
```
## 8.4 编辑标签
```http
PATCH /api/v1/tags/{id}
```
## 8.5 启用/禁用标签
```http
PATCH /api/v1/tags/{id}/status
```
## 8.6 绑定文物标签
```http
POST /api/v1/artifacts/{artifact_id}/tags
```
请求:
```json
{
"tag_id": "uuid",
"value_text": "南迁北归",
"source_type": "manual_entry"
}
```
## 8.7 解绑文物标签
```http
DELETE /api/v1/artifact-tags/{id}
```
---
# 9. Asset API
## 9.1 获取上传签名
```http
POST /api/v1/assets/upload-token
```
请求:
```json
{
"filename": "artifact.jpg",
"mime_type": "image/jpeg",
"size_bytes": 1024000
}
```
## 9.2 创建数字资产记录
```http
POST /api/v1/assets
```
请求:
```json
{
"artifact_id": "uuid",
"asset_type": "image",
"title": "文物主图",
"url": "https://oss.example.com/artifact.jpg",
"thumbnail_url": "https://oss.example.com/artifact-thumb.jpg",
"mime_type": "image/jpeg",
"size_bytes": 1024000,
"copyright_owner": "故宫博物院",
"license_scope": "平台展示"
}
```
## 9.3 数字资产列表
```http
GET /api/v1/assets
```
## 9.4 删除数字资产
```http
DELETE /api/v1/assets/{id}
```
---
# 10. Operation Log API
## 10.1 操作日志列表
```http
GET /api/v1/operation-logs
```
查询参数:
| 参数 | 类型 | 说明 |
|---|---|---|
| operator_id | uuid | 操作人 |
| action | string | 操作类型 |
| target_type | string | 目标类型 |
| target_id | uuid | 目标 ID |
| start_time | string | 开始时间 |
| end_time | string | 结束时间 |
## 10.2 操作日志详情
```http
GET /api/v1/operation-logs/{id}
```
---
# 11. Health API
## 11.1 服务健康检查
```http
GET /api/v1/health
```
响应:
```json
{
"status": "ok",
"time": "2026-06-12T15:20:00.000Z",
"dependencies": {
"database": "ok",
"redis": "ok"
}
}
```
---
# 12. 权限矩阵
| API 模块 | 游客 | 注册用户 | 机构用户 | 管理员 |
|---|---|---|---|---|
| Map 读取 | 允许 | 允许 | 允许 | 允许 |
| Artifact 读取公开数据 | 允许 | 允许 | 允许 | 允许 |
| Artifact 写入 | 不允许 | 不允许 | 本机构 | 全部 |
| Institution 读取 | 允许 | 允许 | 允许 | 允许 |
| Institution 写入 | 不允许 | 不允许 | 本机构部分字段 | 全部 |
| Location 写入 | 不允许 | 不允许 | 本机构文物 | 全部 |
| Tag 读取 | 允许 | 允许 | 允许 | 允许 |
| Tag 管理 | 不允许 | 不允许 | 部分绑定 | 全部 |
| Asset 管理 | 不允许 | 不允许 | 本机构文物 | 全部 |
| Operation Log | 不允许 | 不允许 | 本机构 | 全部 |
# 13. API 测试要点
- 未登录访问后台写接口应返回 401。
- 机构用户访问其他机构文物写接口应返回 403。
- 地图点位接口在 bbox 缺失时应返回 422。
- 游客访问地图点位时不得返回 precise_location。
- 文物发布前缺少必要字段时应返回 422。
- 标签筛选、门类筛选、年代筛选应支持组合查询。
- 操作写接口必须产生 operation_logs 记录。