# Imager API 文档 Base URL: `http://:/api` --- ## 相册 ### GET /api/albums 获取全量相册列表(从内存缓存)。 **参数**:无 **响应**:`AlbumInfo[]` ```json [ { "id": "uuid", "title": "相册标题", "document": "文件夹名", "description": "描述", "cover_image_id": "uuid", "image_count": 100, "created_at": "2024-01-01T00:00:00", "tags": ["标签1", "标签2"], "persons": ["人物1"] } ] ``` --- ### GET /api/search 组合搜索(关键词/标签/人物过滤)。 **参数**(query): | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | q | string | - | 标题关键词模糊匹配 | | tag | string | - | 标签精确匹配 | | person | string | - | 人物精确或模糊匹配 | | page | int | 1 | 页码 | | limit | int | 50 | 每页条数(最大 200) | **响应**:`AlbumInfo[]` --- ### GET /api/album/random 从缓存随机返回一个相册。 **参数**:无 **响应**:`AlbumInfo` --- ### GET /api/album/{id} 获取相册详情(含图片列表、标签、人物)。 **参数**(path): | 参数 | 类型 | 说明 | |------|------|------| | id | uuid | 相册 ID | **响应**:`AlbumWithImages` ```json { "album": { "id": "uuid", "title": "标题", "description": "描述", "cover_image_id": "uuid", "image_count": 100, "created_at": "...", "updated_at": "..." }, "images": [ { "id": "uuid", "album_id": "uuid", "filename": "1.jpg", "original_url": "...", "title": "图片标题", "description": null, "file_size": 123456, "width": 1920, "height": 1080, "mime_type": "image/jpeg", "created_at": "..." } ], "image_count": 100, "tags": ["标签1", "标签2"], "persons": ["人物1"] } ``` --- ### POST /api/albums 创建新相册。 **请求体**: ```json { "title": "相册标题", "document": "文件夹名", "description": "描述(可选)" } ``` **响应**(201 Created): ```json { "id": "uuid" } ``` --- ## 图片 ### GET /api/image/{id} 获取图片原始二进制数据。 **参数**(path): | 参数 | 类型 | 说明 | |------|------|------| | id | uuid | 图片 ID | **响应**:二进制图片数据,Content-Type 按实际 mime 类型。带 ETag,Cache-Control: public, max-age=31536000。 --- ## 收藏 ### GET /api/favorites 获取当前用户的收藏列表。 **参数**:无(用户固定为 default_user) **响应**:`FavoriteWithImage[]` --- ### GET /api/favorites/status/{id} 检查某图片的收藏状态。 **参数**(path): | 参数 | 类型 | 说明 | |------|------|------| | id | uuid | 图片 ID | --- ### POST /api/favorites 添加收藏。 **请求体**: ```json { "image_id": "uuid", "album_id": "uuid" } ``` **响应**(201 Created): ```json { "id": "uuid" } ``` --- ### DELETE /api/favorites/{id} 按收藏 ID 取消收藏。 **参数**(path): | 参数 | 类型 | 说明 | |------|------|------| | id | uuid | 收藏 ID | --- ### DELETE /api/favorites/image/{id} 按图片 ID 取消收藏。 **参数**(path): | 参数 | 类型 | 说明 | |------|------|------| | id | uuid | 图片 ID | --- ## 人物 ### GET /api/people 从内存缓存获取所有人名列表。 **参数**:无 **响应**: ```json { "total": 100, "persons": [ { "id": 1, "name": "人物名", "display_name": "显示名", "total_albums": 10, "total_images": 50, "aliases": ["别名1", "别名2"] } ] } ``` --- ### GET /api/people/search 从内存缓存搜索人名。 **参数**(query): | 参数 | 类型 | 说明 | |------|------|------| | q | string | 搜索关键词 | **响应**:同上 `PersonListResponse` --- ### GET /api/people/{name} 获取人物详情及关联相册。 **参数**(path): | 参数 | 类型 | 说明 | |------|------|------| | name | string | 人物名称 | **响应**:`PersonWithAlbums` ```json { "album_count": 10, "person": { "id": 1, "name": "人物名", "display_name": "显示名", "total_albums": 10, "total_images": 50, "original_names": null, "created_at": "", "updated_at": "" }, "albums": [/* AlbumInfo[] */] } ``` --- ### GET /api/people/{id}/aliases 查询人物别名。 **参数**(path): | 参数 | 类型 | 说明 | |------|------|------| | id | int | 人物 ID | --- ### POST /api/people/delete/{name} 删除人物(从 imager.db + search.db 中清除),并重新解析受影响的相册。 **参数**(path): | 参数 | 类型 | 说明 | |------|------|------| | name | string | 人物名(URL 编码) | **响应**: ```json { "success": true, "person": "人物名", "albums_affected": 5, "persons_updated": 3, "tags_updated": 8, "synced": 5, "message": "人物 '人物名' 已删除,影响 5 个相册,重新解析完成..." } ``` --- ## 标签 / 元数据 ### GET /api/metadata/stats 从内存缓存计算元数据统计。 **参数**:无 **响应**: ```json { "total_persons": 100, "total_aliases": 50, "total_albums": 10000, "total_images": 50000, "total_tags": 2000 } ``` --- ### GET /api/tags/search 按标签搜索相册。 **参数**(query): | 参数 | 类型 | 说明 | |------|------|------| | tag | string | **必填**,标签名 | **响应**:`AlbumInfo[]` --- ### GET /api/tags/popular 获取热门标签。 **参数**(query): | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | limit | int | 50 | 返回数量 | **响应**: ```json { "total": 50, "tags": [ { "tag": "标签名", "count": 1000, "album_count": 1000 } ] } ``` --- ### POST /api/tags/delete/{name} 删除标签(从 dict/album_tags/tags 表中清除),并重新解析受影响的相册。 **参数**(path): | 参数 | 类型 | 说明 | |------|------|------| | name | string | 标签名(URL 编码) | **响应**: ```json { "success": true, "tag": "标签名", "albums_affected": 5, "persons_updated": 3, "tags_updated": 8, "synced": 5, "message": "标签 '标签名' 已删除,影响 5 个相册,重新解析完成..." } ``` --- ## 推荐 ### GET /api/recommend/tags 标签自动补全推荐。 **参数**(query): | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | q | string | - | 输入前缀 | | limit | int | 10 | 返回数量 | --- ### GET /api/recommend/persons 人物自动补全推荐。 **参数**(query): | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | q | string | - | 输入名称 | | limit | int | 10 | 返回数量 | --- ### GET /api/recommend/related 关联推荐(标签共现 + 共现人物)。 **参数**(query): | 参数 | 类型 | 说明 | |------|------|------| | context | string | **必填**,标签或人名 | | limit | int | 默认 15 | --- ### GET /api/recommend/popular-persons 获取热门人物排行榜。 **参数**(query): | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | limit | int | 20(最大 50) | 返回数量 | **响应**: ```json [ { "name": "人物名", "display_name": "显示名", "total_albums": 10, "total_images": 50, "top_tags": ["标签1", "标签2"], "aliases": ["别名1"] } ] ``` --- ## 管线 ### POST /api/pipeline/run 手动触发完整管线。 **参数**:无 **响应**: ```json { "success": true, "tags_cleaned": 0, "short_tags_removed": 0, "person_like_tags_removed": 0, "dirty_albums_detected": 0, "non_persons_deleted": 0, "stop_word_persons_removed": 0, "new_albums_found": 0, "persons_updated": 0, "tags_updated": 0, "persons_merged": 0, "aliases_moved": 0, "tags_removed_person": 0, "empty_albums_deleted": 0, "dup_albums_deleted": 0, "search_db_synced": 0, "message": "管线执行完毕:..." } ``` --- ### POST /api/pipeline/reparse 重置所有相册为未处理状态,重新解析全部标签和人物并同步到 search.db。 **参数**:无 **响应**: ```json { "success": true, "albums_parsed": 100, "persons_updated": 80, "tags_updated": 200, "synced_to_search_db": 100, "message": "重新解析完成:..." } ``` --- ### POST /api/pipeline/reparse-persons 重置所有相册,重新解析全部人物(清空 search.db 的人物关联后运行完整管线)。 **参数**:无 **响应**: ```json { "success": true, "albums_parsed": 100, "persons_updated": 80, "persons_merged": 5, "aliases_moved": 3, "non_persons_deleted": 2, "stop_word_persons_removed": 1, "synced_to_search_db": 100, "message": "人物重新解析完成:..." } ``` --- ### POST /api/pipeline/reparse-tags 重置所有相册,重新解析全部标签(清空 search.db 的标签关联后运行完整管线)。 **参数**:无 **响应**: ```json { "success": true, "albums_parsed": 100, "tags_updated": 200, "short_tags_removed": 5, "synced_to_search_db": 100, "message": "标签重新解析完成:..." } ``` --- ## 词典 ### GET /api/dict/stats 查看标签词典状态。 **参数**:无 **响应**: ```json { "stats": "标签词典: ...", "categories": [ { "name": "style", "label": "风格", "count": 50 } ], "total_tags": 2000, "total_stop_words": 20, "person_prefixes": ["prefix1"], "excluded_person_names": ["name1"], "included_person_names": ["name2"] } ``` --- ### POST /api/dict/reload 从 search.db 的 dict 表热重载词典到内存。 **参数**:无 **响应**: ```json { "success": true, "message": "词典已从 search.db 重载: ..." } ``` --- ### POST /api/dict/update 批量更新 dict 表条目,并自动重载内存词典。 **请求体**(数组): ```json [ { "word": "写真", "type": "tag", "category": "topic", "freq": null, "merged_to": null }, { "word": "张三", "type": "person", "category": null, "freq": null, "merged_to": null } ] ``` **type 可选值**:`tag`、`person`、`stop_word`、`person_prefix`、`excluded_person` **响应**: ```json { "success": true, "message": "更新 2 条字典条目,词典已从 search.db 重载: ...", "updated": 2 } ``` --- ## 缓存 ### POST /api/cache/refresh 手动刷新所有内存缓存(AlbumsCache / TagCache / PersonCache)。 **参数**:无 **响应**: ```json { "success": true, "message": "缓存已刷新" } ``` --- ## 迁移 ### GET /api/migration/stats 查看当前数据库迁移状态。 **参数**:无 --- ### POST /api/migration/run 执行从旧数据库的数据迁移。 **参数**(query): | 参数 | 类型 | 说明 | |------|------|------| | path | string | **必填**,旧数据库文件路径 | --- ## 队列 ### GET /api/queue/stats 获取任务队列状态。 **参数**:无 --- ## 静态页面 | 方法 | 路径 | 说明 | |------|------|------| | GET | `/` | 首页(相册列表) | | GET | `/album` | 相册详情页(需 ?id=xxx 参数) | | GET | `/assets/*` | 静态资源文件 | --- > 所有 API 响应均为 JSON 格式(仅 `/api/image/{id}` 返回二进制)。无认证鉴权。