2d847e154f
中华文明全图鉴——文物全图系统(PC Web 地图 + NestJS API + 管理后台)。 含三大 IP(文物南迁北归 / 国宝海外回归 / 博物馆手艺人)、AI 文物对话、 文物地图与详情、以及 demo-video-kit 演示视频生成工具。
658 lines
11 KiB
Markdown
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 记录。
|