# 中华文明全图鉴——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 ``` 游客地图接口可匿名访问,但会根据匿名权限隐藏敏感坐标。 ## 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 记录。