693 lines
11 KiB
Markdown
693 lines
11 KiB
Markdown
# Imager API 文档
|
||
|
||
Base URL: `http://<host>:<port>/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}` 返回二进制)。无认证鉴权。
|