# 摄影作品集网站 - API接口设计文档 ## 1. API 概述 ### 1.1 设计原则 - **RESTful 设计**: 遵循 REST 架构风格 - **统一响应格式**: 标准化的 JSON 响应结构 - **版本控制**: API 版本化管理 - **安全认证**: JWT 令牌认证机制 - **错误处理**: 详细的错误码和错误信息 - **性能优化**: 支持分页、筛选、排序 ### 1.2 基础信息 ```yaml Base URL: https://api.photography.iriver.top API Version: v1 Content-Type: application/json Authentication: Bearer Token (JWT) ``` ### 1.3 通用响应格式 #### 1.3.1 成功响应 ```json { "success": true, "code": 200, "message": "Success", "data": { // 具体数据内容 }, "meta": { "timestamp": "2024-01-15T10:30:00Z", "request_id": "req_123456789" } } ``` #### 1.3.2 分页响应 ```json { "success": true, "code": 200, "message": "Success", "data": [ // 数据列表 ], "pagination": { "page": 1, "limit": 20, "total": 150, "total_pages": 8, "has_next": true, "has_prev": false }, "meta": { "timestamp": "2024-01-15T10:30:00Z", "request_id": "req_123456789" } } ``` #### 1.3.3 错误响应 ```json { "success": false, "code": 400, "message": "Bad Request", "error": { "type": "VALIDATION_ERROR", "details": [ { "field": "title", "message": "Title is required" } ] }, "meta": { "timestamp": "2024-01-15T10:30:00Z", "request_id": "req_123456789" } } ``` ### 1.4 HTTP 状态码规范 | 状态码 | 说明 | 使用场景 | |--------|------|----------| | 200 | OK | 请求成功 | | 201 | Created | 资源创建成功 | | 204 | No Content | 删除成功 | | 400 | Bad Request | 请求参数错误 | | 401 | Unauthorized | 未认证 | | 403 | Forbidden | 权限不足 | | 404 | Not Found | 资源不存在 | | 409 | Conflict | 资源冲突 | | 422 | Unprocessable Entity | 数据验证失败 | | 429 | Too Many Requests | 请求过于频繁 | | 500 | Internal Server Error | 服务器内部错误 | ## 2. 认证与授权 ### 2.1 认证机制 #### 2.1.1 登录认证 ```http POST /v1/auth/login Content-Type: application/json { "username": "admin", "password": "password123" } ``` **响应:** ```json { "success": true, "code": 200, "message": "Login successful", "data": { "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "token_type": "Bearer", "expires_in": 86400, "user": { "id": 1, "username": "admin", "email": "admin@example.com", "role": "admin", "display_name": "管理员", "avatar_url": "https://example.com/avatar.jpg" } } } ``` #### 2.1.2 令牌刷新 ```http POST /v1/auth/refresh Content-Type: application/json { "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } ``` #### 2.1.3 登出 ```http POST /v1/auth/logout Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` #### 2.1.4 用户信息 ```http GET /v1/auth/profile Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9... ``` ### 2.2 权限控制 #### 2.2.1 权限级别 ```json { "roles": { "super_admin": { "name": "超级管理员", "permissions": ["*"] }, "admin": { "name": "管理员", "permissions": [ "photo.*", "category.*", "tag.*", "user.read", "user.update", "settings.*" ] }, "editor": { "name": "编辑者", "permissions": [ "photo.read", "photo.create", "photo.update", "category.read", "tag.read", "tag.create" ] }, "user": { "name": "普通用户", "permissions": [ "photo.read", "category.read", "tag.read" ] } } } ``` ## 3. 照片管理 API ### 3.1 照片列表 #### 3.1.1 获取照片列表 ```http GET /v1/photos?page=1&limit=20&status=published&category=1&tag=nature&search=sunset&sort_by=created_at&sort_order=desc ``` **查询参数:** | 参数 | 类型 | 必填 | 说明 | 示例 | |------|------|------|------|------| | page | integer | 否 | 页码,默认1 | 1 | | limit | integer | 否 | 每页数量,默认20 | 20 | | status | string | 否 | 状态筛选 | published, draft, archived | | category | integer | 否 | 分类ID | 1 | | tag | string | 否 | 标签名称 | nature | | search | string | 否 | 搜索关键词 | sunset | | sort_by | string | 否 | 排序字段 | created_at, taken_at, title | | sort_order | string | 否 | 排序方向 | asc, desc | | year | integer | 否 | 年份筛选 | 2024 | | month | integer | 否 | 月份筛选 | 1 | **响应:** ```json { "success": true, "code": 200, "data": [ { "id": 1, "title": "城市夜景", "description": "繁华都市的夜晚景色", "slug": "city-night-view-001", "status": "published", "visibility": "public", "taken_at": "2024-01-15T18:30:00Z", "created_at": "2024-01-15T20:00:00Z", "updated_at": "2024-01-15T20:00:00Z", "view_count": 156, "like_count": 23, "formats": { "thumb_small": "https://cdn.example.com/photos/1/thumb_small.jpg", "thumb_medium": "https://cdn.example.com/photos/1/thumb_medium.jpg", "thumb_large": "https://cdn.example.com/photos/1/thumb_large.jpg", "display": "https://cdn.example.com/photos/1/display.jpg", "webp": "https://cdn.example.com/photos/1/display.webp" }, "exif": { "camera": "Canon EOS R5", "lens": "RF 24-70mm f/2.8L IS USM", "iso": 800, "aperture": "f/2.8", "shutter_speed": "1/125", "focal_length": "50mm" }, "location": { "name": "上海外滩", "latitude": 31.23037, "longitude": 121.47370, "country": "China", "city": "Shanghai" }, "categories": [ { "id": 1, "name": "城市风光", "slug": "cityscape", "color": "#3498db" } ], "tags": [ { "id": 1, "name": "夜景", "slug": "night-view", "color": "#2c3e50" }, { "id": 2, "name": "城市", "slug": "city", "color": "#e74c3c" } ] } ], "pagination": { "page": 1, "limit": 20, "total": 150, "total_pages": 8, "has_next": true, "has_prev": false } } ``` ### 3.2 照片详情 #### 3.2.1 获取照片详情 ```http GET /v1/photos/{id} ``` **路径参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | id | integer | 是 | 照片ID | **响应:** ```json { "success": true, "code": 200, "data": { "id": 1, "title": "城市夜景", "description": "繁华都市的夜晚景色,灯火通明的建筑群构成了美丽的天际线...", "slug": "city-night-view-001", "status": "published", "visibility": "public", "sort_order": 0, "taken_at": "2024-01-15T18:30:00Z", "created_at": "2024-01-15T20:00:00Z", "updated_at": "2024-01-15T20:00:00Z", "view_count": 156, "like_count": 23, "download_count": 5, "file_info": { "original_filename": "DSC_0001.jpg", "file_size": 2048576, "mime_type": "image/jpeg" }, "formats": { "original": "https://cdn.example.com/photos/1/original.jpg", "jpg": "https://cdn.example.com/photos/1/display.jpg", "webp": "https://cdn.example.com/photos/1/display.webp", "thumb_small": "https://cdn.example.com/photos/1/thumb_small.jpg", "thumb_medium": "https://cdn.example.com/photos/1/thumb_medium.jpg", "thumb_large": "https://cdn.example.com/photos/1/thumb_large.jpg" }, "exif": { "camera": "Canon EOS R5", "lens": "RF 24-70mm f/2.8L IS USM", "iso": 800, "aperture": "f/2.8", "shutter_speed": "1/125", "focal_length": "50mm" }, "location": { "name": "上海外滩", "latitude": 31.23037, "longitude": 121.47370, "country": "China", "city": "Shanghai" }, "categories": [ { "id": 1, "name": "城市风光", "slug": "cityscape", "description": "城市景观摄影作品", "color": "#3498db", "is_primary": true } ], "tags": [ { "id": 1, "name": "夜景", "slug": "night-view", "color": "#2c3e50", "confidence": 1.0, "source": "manual" }, { "id": 2, "name": "城市", "slug": "city", "color": "#e74c3c", "confidence": 0.95, "source": "ai" } ], "metadata": { "weather": "clear", "temperature": "15°C", "processing_notes": "调整了曝光和对比度" } } } ``` ### 3.3 照片操作 #### 3.3.1 创建照片 (用于上传后的元数据创建) ```http POST /v1/photos Authorization: Bearer {token} Content-Type: application/json { "title": "城市夜景", "description": "繁华都市的夜晚景色", "file_id": "upload_123456789", "status": "published", "visibility": "public", "taken_at": "2024-01-15T18:30:00Z", "location": { "name": "上海外滩", "latitude": 31.23037, "longitude": 121.47370 }, "categories": [1, 2], "tags": ["夜景", "城市", "建筑"], "metadata": { "weather": "clear", "temperature": "15°C" } } ``` #### 3.3.2 更新照片信息 ```http PUT /v1/photos/{id} Authorization: Bearer {token} Content-Type: application/json { "title": "上海外滩夜景", "description": "更新后的描述", "status": "published", "categories": [1, 3], "tags": ["夜景", "城市", "外滩"] } ``` #### 3.3.3 删除照片 ```http DELETE /v1/photos/{id} Authorization: Bearer {token} ``` #### 3.3.4 批量操作 ```http POST /v1/photos/batch Authorization: Bearer {token} Content-Type: application/json { "photo_ids": [1, 2, 3, 4, 5], "action": "update_status", "data": { "status": "published" } } ``` **支持的批量操作:** - `update_status`: 批量更新状态 - `add_tags`: 批量添加标签 - `remove_tags`: 批量移除标签 - `add_categories`: 批量添加分类 - `remove_categories`: 批量移除分类 - `delete`: 批量删除 ### 3.4 照片搜索 #### 3.4.1 全文搜索 ```http GET /v1/photos/search?q=夜景&category=1&tags=城市,建筑&location=上海&date_from=2024-01-01&date_to=2024-12-31 ``` **查询参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | q | string | 是 | 搜索关键词 | | category | integer | 否 | 分类ID | | tags | string | 否 | 标签名称,逗号分隔 | | location | string | 否 | 地点名称 | | date_from | string | 否 | 开始日期 (YYYY-MM-DD) | | date_to | string | 否 | 结束日期 (YYYY-MM-DD) | | camera | string | 否 | 相机型号 | | lens | string | 否 | 镜头型号 | **响应:** ```json { "success": true, "code": 200, "data": { "photos": [ { "id": 1, "title": "城市夜景", "score": 0.95, "highlight": { "title": "夜景", "description": "繁华都市的夜晚景色" } } ], "facets": { "categories": [ {"name": "城市风光", "count": 15}, {"name": "建筑摄影", "count": 8} ], "tags": [ {"name": "夜景", "count": 12}, {"name": "城市", "count": 20} ], "years": [ {"year": 2024, "count": 25}, {"year": 2023, "count": 18} ] } }, "pagination": { "page": 1, "limit": 20, "total": 25 } } ``` ## 4. 文件上传 API ### 4.1 文件上传 #### 4.1.1 单文件上传 ```http POST /v1/upload/single Authorization: Bearer {token} Content-Type: multipart/form-data file: (binary data) ``` **响应:** ```json { "success": true, "code": 201, "data": { "file_id": "upload_123456789", "original_filename": "DSC_0001.jpg", "file_size": 2048576, "mime_type": "image/jpeg", "upload_url": "https://temp.example.com/upload_123456789.jpg", "status": "uploaded", "exif_extracted": true, "processing_status": "pending" } } ``` #### 4.1.2 多文件上传 ```http POST /v1/upload/multiple Authorization: Bearer {token} Content-Type: multipart/form-data files[]: (binary data) files[]: (binary data) ... ``` **响应:** ```json { "success": true, "code": 201, "data": { "uploaded": [ { "file_id": "upload_123456789", "original_filename": "DSC_0001.jpg", "file_size": 2048576, "status": "uploaded" } ], "failed": [ { "filename": "invalid_file.txt", "error": "Invalid file type" } ], "summary": { "total": 5, "success": 4, "failed": 1 } } } ``` #### 4.1.3 分块上传 ```http POST /v1/upload/chunked/init Authorization: Bearer {token} Content-Type: application/json { "filename": "large_photo.raw", "file_size": 52428800, "mime_type": "image/raw", "chunk_size": 1048576 } ``` **响应:** ```json { "success": true, "code": 201, "data": { "upload_id": "chunked_123456789", "chunk_size": 1048576, "total_chunks": 50, "upload_urls": [ "https://temp.example.com/chunked_123456789/chunk_0", "https://temp.example.com/chunked_123456789/chunk_1" ] } } ``` #### 4.1.4 上传状态查询 ```http GET /v1/upload/status/{file_id} Authorization: Bearer {token} ``` **响应:** ```json { "success": true, "code": 200, "data": { "file_id": "upload_123456789", "status": "processing", "progress": 75, "current_step": "generating_thumbnails", "steps": [ {"name": "uploaded", "status": "completed"}, {"name": "exif_extraction", "status": "completed"}, {"name": "generating_thumbnails", "status": "processing"}, {"name": "optimization", "status": "pending"} ], "estimated_time_remaining": 30 } } ``` ### 4.2 文件处理 #### 4.2.1 重新处理文件 ```http POST /v1/upload/{file_id}/reprocess Authorization: Bearer {token} Content-Type: application/json { "formats": ["thumb_small", "thumb_medium", "webp"], "force": true } ``` #### 4.2.2 删除上传文件 ```http DELETE /v1/upload/{file_id} Authorization: Bearer {token} ``` ## 5. 分类管理 API ### 5.1 分类操作 #### 5.1.1 获取分类列表 ```http GET /v1/categories?include_stats=true&include_tree=true ``` **响应:** ```json { "success": true, "code": 200, "data": { "categories": [ { "id": 1, "name": "城市风光", "slug": "cityscape", "description": "城市景观摄影作品", "parent_id": null, "level": 0, "path": "1", "cover_photo": { "id": 15, "title": "都市夜景", "thumb_url": "https://cdn.example.com/photos/15/thumb_medium.jpg" }, "color": "#3498db", "icon": "building", "sort_order": 1, "is_active": true, "is_featured": true, "photo_count": 45, "direct_photo_count": 30, "created_at": "2024-01-01T00:00:00Z", "updated_at": "2024-01-15T10:30:00Z" } ], "tree": [ { "id": 1, "name": "城市风光", "slug": "cityscape", "photo_count": 45, "children": [ { "id": 2, "name": "夜景摄影", "slug": "night-photography", "photo_count": 15, "children": [] }, { "id": 3, "name": "建筑摄影", "slug": "architecture", "photo_count": 30, "children": [] } ] } ], "stats": { "total_categories": 12, "max_level": 3, "featured_count": 5 } } } ``` #### 5.1.2 获取分类详情 ```http GET /v1/categories/{id} ``` #### 5.1.3 创建分类 ```http POST /v1/categories Authorization: Bearer {token} Content-Type: application/json { "name": "自然风景", "slug": "nature-landscape", "description": "自然风景摄影作品", "parent_id": null, "color": "#27ae60", "icon": "tree", "sort_order": 2, "is_featured": true, "seo_title": "自然风景摄影作品集", "seo_description": "欣赏美丽的自然风景摄影作品" } ``` #### 5.1.4 更新分类 ```http PUT /v1/categories/{id} Authorization: Bearer {token} Content-Type: application/json { "name": "自然风光", "description": "更新后的描述", "color": "#2ecc71" } ``` #### 5.1.5 删除分类 ```http DELETE /v1/categories/{id} Authorization: Bearer {token} ``` #### 5.1.6 设置分类封面 ```http PUT /v1/categories/{id}/cover Authorization: Bearer {token} Content-Type: application/json { "photo_id": 15 } ``` ### 5.2 分类照片管理 #### 5.2.1 获取分类下的照片 ```http GET /v1/categories/{id}/photos?page=1&limit=20&sort_by=created_at&sort_order=desc ``` #### 5.2.2 添加照片到分类 ```http POST /v1/categories/{id}/photos Authorization: Bearer {token} Content-Type: application/json { "photo_ids": [1, 2, 3], "is_primary": true } ``` #### 5.2.3 从分类移除照片 ```http DELETE /v1/categories/{id}/photos Authorization: Bearer {token} Content-Type: application/json { "photo_ids": [1, 2, 3] } ``` ## 6. 标签管理 API ### 6.1 标签操作 #### 6.1.1 获取标签列表 ```http GET /v1/tags?group=all&sort_by=usage_count&sort_order=desc&limit=50 ``` **响应:** ```json { "success": true, "code": 200, "data": [ { "id": 1, "name": "夜景", "slug": "night-view", "description": "夜晚拍摄的景色", "color": "#2c3e50", "icon": "moon", "tag_group": "style", "usage_count": 45, "trend_score": 8.5, "is_active": true, "is_featured": true, "created_at": "2024-01-01T00:00:00Z", "last_used_at": "2024-01-15T10:30:00Z" } ], "groups": { "style": {"name": "摄影风格", "count": 12}, "subject": {"name": "拍摄主题", "count": 18}, "technique": {"name": "拍摄技法", "count": 8}, "location": {"name": "地理位置", "count": 25} } } ``` #### 6.1.2 标签搜索建议 ```http GET /v1/tags/suggestions?q=夜&limit=10 ``` **响应:** ```json { "success": true, "code": 200, "data": [ { "id": 1, "name": "夜景", "slug": "night-view", "usage_count": 45, "match_score": 0.95 }, { "id": 15, "name": "夜市", "slug": "night-market", "usage_count": 12, "match_score": 0.8 } ] } ``` #### 6.1.3 创建标签 ```http POST /v1/tags Authorization: Bearer {token} Content-Type: application/json { "name": "极光", "slug": "aurora", "description": "极光摄影作品", "color": "#9b59b6", "tag_group": "subject", "is_featured": true } ``` #### 6.1.4 更新标签 ```http PUT /v1/tags/{id} Authorization: Bearer {token} Content-Type: application/json { "name": "北极光", "description": "更新后的描述", "color": "#8e44ad" } ``` #### 6.1.5 删除标签 ```http DELETE /v1/tags/{id} Authorization: Bearer {token} ``` ### 6.2 标签统计 #### 6.2.1 标签云数据 ```http GET /v1/tags/cloud?min_usage=5&max_tags=50 ``` **响应:** ```json { "success": true, "code": 200, "data": [ { "id": 1, "name": "夜景", "usage_count": 45, "relative_size": 100, "color": "#2c3e50" }, { "id": 2, "name": "城市", "usage_count": 38, "relative_size": 84, "color": "#e74c3c" } ] } ``` #### 6.2.2 趋势标签 ```http GET /v1/tags/trending?period=30d&limit=10 ``` ## 7. 时间线 API ### 7.1 时间线数据 #### 7.1.1 获取时间线 ```http GET /v1/timeline?year=2024&include_photos=true&photos_limit=5 ``` **响应:** ```json { "success": true, "code": 200, "data": { "years": [ { "year": 2024, "photo_count": 156, "months": [ { "month": 1, "month_name": "一月", "photo_count": 25, "photos": [ { "id": 1, "title": "城市夜景", "thumb_url": "https://cdn.example.com/photos/1/thumb_medium.jpg", "taken_at": "2024-01-15T18:30:00Z" } ], "events": [ { "id": 1, "title": "首次夜景拍摄", "description": "第一次尝试城市夜景摄影", "date": "2024-01-15", "type": "milestone" } ] } ] } ], "stats": { "total_photos": 456, "year_range": [2020, 2024], "most_active_month": { "year": 2024, "month": 3, "count": 45 }, "photos_by_year": [ {"year": 2024, "count": 156}, {"year": 2023, "count": 189}, {"year": 2022, "count": 111} ] } } } ``` #### 7.1.2 获取指定月份详情 ```http GET /v1/timeline/{year}/{month}?include_photos=true ``` ### 7.2 时间线事件 #### 7.2.1 创建事件 ```http POST /v1/timeline/events Authorization: Bearer {token} Content-Type: application/json { "title": "获得摄影比赛奖项", "description": "在城市摄影大赛中获得金奖", "date": "2024-03-15", "type": "achievement", "related_photos": [15, 23, 31] } ``` #### 7.2.2 更新事件 ```http PUT /v1/timeline/events/{id} Authorization: Bearer {token} Content-Type: application/json { "title": "更新后的标题", "description": "更新后的描述" } ``` #### 7.2.3 删除事件 ```http DELETE /v1/timeline/events/{id} Authorization: Bearer {token} ``` ## 8. 系统设置 API ### 8.1 设置管理 #### 8.1.1 获取系统设置 ```http GET /v1/settings?category=all&include_public=true ``` **响应:** ```json { "success": true, "code": 200, "data": { "general": { "site_title": "摄影作品集", "site_description": "专业摄影师作品展示平台", "site_keywords": "摄影,作品集,艺术,创作", "site_author": "摄影师姓名", "site_email": "contact@example.com" }, "upload": { "max_file_size": 52428800, "allowed_types": ["image/jpeg", "image/png", "image/raw"], "max_files_per_batch": 50, "auto_publish": false, "generate_thumbnails": true }, "image": { "quality_jpg": 85, "quality_webp": 80, "max_width": 1920, "max_height": 1080, "watermark_enabled": false }, "display": { "photos_per_page": 20, "thumbnail_size": 300, "theme_primary_color": "#d4af37", "theme_secondary_color": "#2d2d2d", "enable_dark_mode": true, "enable_animations": true } } } ``` #### 8.1.2 更新系统设置 ```http PUT /v1/settings Authorization: Bearer {token} Content-Type: application/json { "site_title": "我的摄影作品集", "upload_max_file_size": 104857600, "display_photos_per_page": 24 } ``` #### 8.1.3 重置设置 ```http POST /v1/settings/reset Authorization: Bearer {token} Content-Type: application/json { "categories": ["upload", "image"], "confirm": true } ``` ### 8.2 缓存管理 #### 8.2.1 清理缓存 ```http POST /v1/settings/cache/clear Authorization: Bearer {token} Content-Type: application/json { "types": ["photos", "categories", "tags", "settings"], "confirm": true } ``` #### 8.2.2 预热缓存 ```http POST /v1/settings/cache/warm Authorization: Bearer {token} Content-Type: application/json { "types": ["popular_photos", "category_tree", "tag_cloud"] } ``` #### 8.2.3 缓存统计 ```http GET /v1/settings/cache/stats Authorization: Bearer {token} ``` **响应:** ```json { "success": true, "code": 200, "data": { "redis": { "connected": true, "used_memory": "15.2MB", "total_keys": 1247, "hit_rate": 0.89 }, "categories": { "photos": {"keys": 456, "hit_rate": 0.92}, "categories": {"keys": 12, "hit_rate": 0.95}, "tags": {"keys": 89, "hit_rate": 0.87}, "settings": {"keys": 1, "hit_rate": 0.99} } } } ``` ## 9. 统计分析 API ### 9.1 仪表板统计 #### 9.1.1 仪表板数据 ```http GET /v1/dashboard/stats?period=30d ``` **响应:** ```json { "success": true, "code": 200, "data": { "summary": { "total_photos": 456, "total_categories": 12, "total_tags": 89, "total_views": 15420, "storage_used": 2684354560, "storage_limit": 10737418240 }, "recent": { "new_photos": 15, "new_views": 234, "new_likes": 67, "period": "7d" }, "trends": { "uploads": [ {"date": "2024-01-01", "count": 5}, {"date": "2024-01-02", "count": 8}, {"date": "2024-01-03", "count": 3} ], "views": [ {"date": "2024-01-01", "count": 156}, {"date": "2024-01-02", "count": 234}, {"date": "2024-01-03", "count": 189} ] }, "popular": { "categories": [ {"name": "城市风光", "count": 45, "percentage": 28.5}, {"name": "自然风景", "count": 38, "percentage": 24.1} ], "tags": [ {"name": "夜景", "count": 45}, {"name": "城市", "count": 38} ], "photos": [ { "id": 15, "title": "都市夜景", "view_count": 1247, "like_count": 89 } ] }, "system_status": { "database": "healthy", "redis": "healthy", "storage": "healthy", "queue": "healthy" } } } ``` ### 9.2 详细统计 #### 9.2.1 照片统计 ```http GET /v1/stats/photos?group_by=month&year=2024 ``` #### 9.2.2 访问统计 ```http GET /v1/stats/views?period=30d&group_by=day ``` #### 9.2.3 存储统计 ```http GET /v1/stats/storage ``` ## 10. 用户管理 API ### 10.1 用户操作 #### 10.1.1 获取用户列表 ```http GET /v1/users?page=1&limit=20&role=all&status=active&search=admin ``` #### 10.1.2 创建用户 ```http POST /v1/users Authorization: Bearer {token} Content-Type: application/json { "username": "editor", "email": "editor@example.com", "password": "password123", "role": "editor", "display_name": "编辑者", "is_active": true } ``` #### 10.1.3 更新用户 ```http PUT /v1/users/{id} Authorization: Bearer {token} Content-Type: application/json { "display_name": "高级编辑者", "role": "admin", "is_active": true } ``` #### 10.1.4 删除用户 ```http DELETE /v1/users/{id} Authorization: Bearer {token} ``` ### 10.2 用户会话管理 #### 10.2.1 获取用户会话 ```http GET /v1/users/{id}/sessions Authorization: Bearer {token} ``` #### 10.2.2 强制下线 ```http DELETE /v1/users/{id}/sessions/{session_id} Authorization: Bearer {token} ``` ## 11. 错误处理 ### 11.1 错误码定义 | 错误码 | HTTP状态码 | 说明 | |--------|------------|------| | VALIDATION_ERROR | 400 | 请求参数验证失败 | | AUTHENTICATION_REQUIRED | 401 | 需要认证 | | INVALID_TOKEN | 401 | 无效的令牌 | | TOKEN_EXPIRED | 401 | 令牌已过期 | | PERMISSION_DENIED | 403 | 权限不足 | | RESOURCE_NOT_FOUND | 404 | 资源不存在 | | RESOURCE_CONFLICT | 409 | 资源冲突 | | UNPROCESSABLE_ENTITY | 422 | 数据处理失败 | | RATE_LIMIT_EXCEEDED | 429 | 请求频率超限 | | INTERNAL_SERVER_ERROR | 500 | 服务器内部错误 | | SERVICE_UNAVAILABLE | 503 | 服务不可用 | ### 11.2 错误响应示例 #### 11.2.1 验证错误 ```json { "success": false, "code": 400, "message": "Validation failed", "error": { "type": "VALIDATION_ERROR", "details": [ { "field": "title", "message": "Title is required", "code": "REQUIRED" }, { "field": "email", "message": "Invalid email format", "code": "INVALID_FORMAT" } ] } } ``` #### 11.2.2 权限错误 ```json { "success": false, "code": 403, "message": "Permission denied", "error": { "type": "PERMISSION_DENIED", "details": { "required_permission": "photo.delete", "user_role": "editor" } } } ``` #### 11.2.3 资源不存在 ```json { "success": false, "code": 404, "message": "Resource not found", "error": { "type": "RESOURCE_NOT_FOUND", "details": { "resource_type": "photo", "resource_id": 999 } } } ``` ## 12. API 限流 ### 12.1 限流策略 | 端点类型 | 限制 | 时间窗口 | |----------|------|----------| | 认证端点 | 5次/IP | 1分钟 | | 上传端点 | 10次/用户 | 1分钟 | | 搜索端点 | 60次/用户 | 1分钟 | | 一般端点 | 1000次/用户 | 1小时 | | 管理端点 | 500次/用户 | 1小时 | ### 12.2 限流响应头 ```http X-RateLimit-Limit: 1000 X-RateLimit-Remaining: 999 X-RateLimit-Reset: 1642636800 X-RateLimit-Window: 3600 ``` ### 12.3 限流超出响应 ```json { "success": false, "code": 429, "message": "Rate limit exceeded", "error": { "type": "RATE_LIMIT_EXCEEDED", "details": { "limit": 1000, "window": 3600, "reset_at": "2024-01-15T11:00:00Z" } } } ``` ## 13. WebHook API ### 13.1 WebHook 配置 #### 13.1.1 创建 WebHook ```http POST /v1/webhooks Authorization: Bearer {token} Content-Type: application/json { "url": "https://example.com/webhook", "events": ["photo.created", "photo.updated", "photo.deleted"], "secret": "webhook_secret_key", "is_active": true } ``` #### 13.1.2 WebHook 事件类型 | 事件类型 | 描述 | 数据载荷 | |----------|------|----------| | photo.created | 照片创建 | 完整照片数据 | | photo.updated | 照片更新 | 更新后的照片数据 | | photo.deleted | 照片删除 | 删除的照片ID | | category.created | 分类创建 | 完整分类数据 | | category.updated | 分类更新 | 更新后的分类数据 | | category.deleted | 分类删除 | 删除的分类ID | | user.login | 用户登录 | 用户基本信息 | | system.backup | 系统备份 | 备份状态信息 | ### 13.2 WebHook 载荷示例 ```json { "event": "photo.created", "timestamp": "2024-01-15T10:30:00Z", "data": { "id": 1, "title": "城市夜景", "status": "published", "created_at": "2024-01-15T10:30:00Z" }, "signature": "sha256=abcdef123456..." } ``` ## 14. API 版本控制 ### 14.1 版本策略 - **URL 版本控制**: `/v1/`, `/v2/` - **向后兼容**: 至少支持2个主版本 - **废弃通知**: 通过响应头通知 ### 14.2 版本响应头 ```http API-Version: 1.0 API-Deprecated: false API-Sunset: 2025-01-15T00:00:00Z ``` ### 14.3 版本变更日志 #### 版本 1.0.0 (当前) - 初始 API 版本 - 支持照片、分类、标签管理 - 用户认证和权限控制 #### 版本 1.1.0 (计划) - 添加 AI 标签推荐 - 支持视频文件 - 增强搜索功能 ## 15. 总结 这个API接口设计文档提供了摄影作品集网站的完整API规范,包括: ### 🎯 设计特点 - **RESTful 风格**: 符合REST架构原则 - **统一响应格式**: 标准化的JSON响应 - **完整的CRUD操作**: 支持所有资源的增删改查 - **灵活的查询**: 丰富的筛选、排序、搜索功能 ### 🔒 安全机制 - **JWT认证**: 基于令牌的认证机制 - **权限控制**: 细粒度的角色权限管理 - **请求限流**: 防止API滥用 - **数据验证**: 严格的输入验证 ### 📊 功能丰富 - **文件上传**: 支持单文件、多文件、分块上传 - **图片处理**: 自动生成多种格式和尺寸 - **全文搜索**: 强大的搜索和筛选功能 - **统计分析**: 详细的数据统计和趋势分析 ### 🛠️ 开发友好 - **详细文档**: 完整的接口说明和示例 - **错误处理**: 清晰的错误码和错误信息 - **版本控制**: 科学的API版本管理 - **WebHook支持**: 事件驱动的集成能力 这个API设计为Golang后端实现提供了完整的接口规范,可以支持前端和管理后台的所有功能需求。