网盘系统 API 接口文档

微服务架构 · 统一网关入口

网关地址:http://localhost:8888

服务架构图

前端
Gateway:8888
User:8081
Drive:8082
TMDB:8083
Drive:8082
OpenList:13000
各网盘

路由规则

请求路径转发服务说明
/api/login, /api/registeruser-service登录注册
/api/token/**, /api/login-logs/**user-service令牌/日志
/api/users/**user-service用户管理
/api/profile/**user-service个人资料
/api/drive/**drive-service网盘管理
/api/drive/**/sync-filesdrive-serviceOpenList 文件同步
/api/drive/**/play-urldrive-serviceOpenList 播放链接
/api/icon/**drive-serviceIcon管理
/api/movies/**tmdb-service电影管理
/api/tmdb/**, /api/tmdb-scraper/**tmdb-serviceTMDB刮削

用户认证服务

wangpan-user-service : 8081
POST /api/login 用户登录

请求体

{ "username": "用户名", "password": "密码" }

成功响应示例

{ "code": 200, "message": "登录成功", "data": { "id": 7, "username": "lrq", "userType": 0, // 0=普通用户, 1=VIP, 2=管理员 "status": 1, "email": "xxx@xx.com", "phone": "138****0000", "realName": "张三", "avatarUrl": "", "lastLoginIp": "127.0.0.1", "lastLoginTime": "2026-06-10T11:20:21", "hasTmdbKey": false, "token": "tk_xxx...", "tokenType": "Bearer", "expireIn": 604800 } }

失败响应示例 — 用户名或密码错误

{ "code": 400, "message": "用户名或密码错误", "data": null }

失败响应示例 — 账号被禁用

{ "code": 403, "message": "账号已被禁用,请联系管理员", "data": null }

失败响应示例 — 参数缺失

{ "code": 400, "message": "用户名和密码不能为空", "data": null }

userType 说明

角色权限说明
0普通用户仅访问自己的数据(如日志只看自己的)
1VIP 用户普通用户 + 更多存储空间
2管理员可查看所有用户数据(如全部日志)
POST /api/register 用户注册

请求体

{ "username": "用户名", "password": "密码" }

成功响应示例

{ "code": 200, "message": "注册成功", "data": { "id": 10, "username": "newuser" } }

失败响应示例 — 用户名已存在

{ "code": 409, "message": "用户名已被占用", "data": null }

失败响应示例 — 参数缺失

{ "code": 400, "message": "用户名和密码不能为空", "data": null }
GET /api/token/validate 令牌验证

请求头

Authorization: Bearer <token>

成功响应示例 — Token 有效

{ "code": 200, "message": "Token 有效", "data": { "valid": true, "userId": 7, "username": "lrq", "expireTime": "2026-06-17T11:20:21" } }

失败响应示例 — Token 无效或已过期

{ "code": 401, "message": "Token 无效或已过期", "data": null }
GET /api/login-logs 登录日志查询需Token

权限说明

用户类型可见范围
普通用户(userType=0/1)仅自己的登录记录
管理员(userType=2)所有用户的登录记录

查询参数

参数类型必填说明
usernameString按用户名模糊筛选(管理员可用)
resultString登录结果:success / fail
startDateString开始日期(含),格式:yyyy-MM-dd,如 2026-06-01
endDateString结束日期(含),格式:yyyy-MM-dd,如 2026-06-10
pageNoint页码,默认 1
pageSizeint每页条数,默认 20

提示:可组合使用多个筛选条件,如 ?result=fail&startDate=2026-06-01&endDate=2026-06-10

成功响应示例

{ "code": 200, "message": "查询成功", "data": { "total": 10, "list": [ { "id": 1, "userId": 7, "username": "lrq", "loginIp": "127.0.0.1", "loginTime": "2026-06-10T11:20:21", "result": "success", "userAgent": "Mozilla/5.0..." } ], "pageNo": 1, "pageSize": 20 } }

失败响应示例 — 未登录

{ "code": 401, "message": "未登录或 Token 无效", "data": null }

失败响应示例 — 权限不足

{ "code": 403, "message": "权限不足,无法查看其他用户的登录日志", "data": null }

用户管理

wangpan-user-service : 8081 仅管理员 (userType=2)
GET /api/users 查询用户列表需Token + 管理员

权限说明

角色访问权限
普通/VIP 用户403 权限不足
管理员可查看所有用户列表

查询参数

参数类型必填说明
usernameString用户名模糊搜索
statusint状态:0=禁用, 1=正常, 2=锁定
userTypeint角色:0=普通, 1=VIP, 2=管理员
pageNoint页码,默认 1
pageSizeint每页条数,默认 20

成功响应示例

{ "code": 200, "message": "查询成功", "data": { "total": 5, "list": [ { "id": 7, "username": "lrq", "userType": 0, "status": 1, ... } ], "pageNo": 1, "pageSize": 20 } }

失败响应示例 — 权限不足

{ "code": 403, "message": "权限不足,仅管理员可访问", "data": null }

失败响应示例 — 未登录

{ "code": 401, "message": "未登录或 Token 无效", "data": null }
POST /api/users 新增用户需Token + 管理员

请求体

{ "username": "必填", "password": "必填", "email": "可选", "phone": "可选", "realName": "可选", "status": 1, // 可选:0=禁用, 1=正常, 默认1 "userType": 0 // 可选:0=普通, 1=VIP, 2=管理员, 默认0 }

成功响应

{ "code": 200, "message": "用户创建成功", "data": { "id": 10, "username": "newuser", "email": "new@test.com", "status": 1, "userType": 0 } }

失败响应示例 — 用户名已存在

{ "code": 409, "message": "用户名已被占用", "data": null }

失败响应示例 — 参数缺失

{ "code": 400, "message": "用户名或密码不能为空", "data": null }

失败响应示例 — 权限不足

{ "code": 403, "message": "非管理员,无权限操作", "data": null }

失败响应示例 — 服务器错误

{ "code": 500, "message": "服务器内部错误", "data": null }
PUT /api/users/{userId} 修改用户信息需Token + 管理员

路径参数

参数类型说明
userIdLong目标用户 ID

请求体(部分更新,只传需要修改的字段)

{ "email": "新邮箱", // 可选 "phone": "新手机号", // 可选 "realName": "新姓名", // 可选 "status": 0, // 可选:0=禁用, 1=正常, 2=锁定 "userType": 1 // 可选:0=普通, 1=VIP, 2=管理员 }

成功响应

{ "code": 200, "message": "用户信息更新成功", "data": { "id": 10, "username": "newuser", "email": "new@test.com", "status": 1, "userType": 0 } }

失败响应示例 — 用户不存在

{ "code": 404, "message": "目标用户不存在", "data": null }

失败响应示例 — 参数缺失

{ "code": 400, "message": "没有需要更新的字段", "data": null }

失败响应示例 — 权限不足

{ "code": 403, "message": "非管理员,无权限操作", "data": null }

失败响应示例 — 服务器错误

{ "code": 500, "message": "服务器内部错误", "data": null }
DELETE /api/users/{userId} 删除用户(软删除)需Token + 管理员

路径参数

参数类型说明
userIdLong要删除的用户 ID

说明

软删除操作,将 is_deleted 设为 1,不物理删除数据。

成功响应

{ "code": 200, "message": "用户删除成功", "data": null }

失败响应示例 — 用户不存在

{ "code": 404, "message": "目标用户不存在", "data": null }

失败响应示例 — 删除失败

{ "code": 400, "message": "删除失败,用户可能已被删除", "data": null }

失败响应示例 — 权限不足

{ "code": 403, "message": "非管理员,无权限操作", "data": null }

失败响应示例 — 服务器错误

{ "code": 500, "message": "服务器内部错误", "data": null }

个人资料

wangpan-user-service : 8081
GET /api/profile 获取当前用户个人资料需Token

功能说明

获取当前登录用户的基本信息(不含密码等敏感字段)。

成功响应示例

{ "code": 200, "message": "查询成功", "data": { "id": 1, "username": "admin", "email": "admin@example.com", "phone": "13800138000", "realName": "管理员", "avatarUrl": "http://...", "userType": 2, "status": 1, "createTime": "2024-01-01T00:00:00" } }

失败响应示例 — 未登录

{ "code": 401, "message": "未登录或 Token 无效", "data": null }

失败响应示例 — 用户不存在

{ "code": 404, "message": "用户不存在", "data": null }
PUT /api/profile/username 修改用户名需Token

功能说明

修改当前登录用户的用户名。

校验规则:

  • 用户名不能为空
  • 新用户名不能与当前用户名相同
  • 新用户名不能被其他用户占用

请求体

{ "username": "新用户名" }

成功响应示例

{ "code": 200, "message": "用户名修改成功", "data": null }

失败响应示例 — 用户名已存在

{ "code": 409, "message": "用户名已被其他用户使用", "data": null }

失败响应示例 — 参数错误

{ "code": 400, "message": "新用户名不能为空或与当前用户名相同", "data": null }
PUT /api/profile/avatar 修改头像需Token

功能说明

修改当前登录用户的头像。

流程:

  1. 接收 Base64 编码的图片数据
  2. 解析 MIME 类型和 Base64 内容
  3. 上传到 MinIO(路径:avatar/{userId}_{timestamp}.{ext})
  4. 更新数据库中的 avatar_url 字段

支持的图片格式:PNG、JPG/JPEG、GIF、WebP

请求体

{ "avatarData": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." }

成功响应示例

{ "code": 200, "message": "头像更新成功", "data": { "avatarUrl": "http://118.178.238.159:39000/wangpan/avatar/1_1719234567890.png?..." } }

失败响应示例 — 图片格式不支持

{ "code": 400, "message": "不支持的图片格式,仅支持 PNG、JPG、GIF、WebP", "data": null }

失败响应示例 — MinIO 上传失败

{ "code": 500, "message": "头像上传失败,请稍后重试", "data": null }

网盘管理服务

wangpan-drive-service : 8082
POST /api/drive 创建网盘需Token

请求体

{ "name": "网盘名称", "description": "网盘描述", "logoData": "data:image/png;base64,iVBOR..." }

参数说明

参数类型必填说明
nameString网盘名称
descriptionString网盘描述
logoDataStringLogo图片Base64编码,支持 data:image/xxx;base64, 前缀格式,上传后存储到MinIO,数据库仅保存URL

成功响应示例

{ "code": 200, "message": "创建成功", "data": { "id": 1, "name": "我的网盘", "description": "个人网盘", "logoUrl": "http://118.178.238.159:39000/wangpan/drive/1/logo.png", "createTime": "2026-06-26T10:00:00" } }

失败响应示例 — 参数缺失

{ "code": 400, "message": "网盘名称不能为空", "data": null }

失败响应示例 — 未登录

{ "code": 401, "message": "未登录或 Token 无效", "data": null }
GET /api/drive 查询网盘列表需Token

查询参数

参数默认值说明
pageNo1页码
pageSize20每页条数

响应字段

字段类型说明
idLong网盘ID
nameString网盘名称
descriptionString网盘描述
logoUrlString网盘Logo图片链接(MinIO存储地址)
folderCountInteger文件夹数量
fileCountInteger文件数量
totalSizeLong总大小(字节)
statusString状态
createTimeString创建时间
updateTimeString更新时间

成功响应示例

{ "code": 200, "message": "查询成功", "data": { "total": 2, "list": [ { "id": 1, "name": "我的网盘", "description": "个人网盘", "logoUrl": "http://118.178.238.159:39000/wangpan/drive/1/logo.png", "folderCount": 5, "fileCount": 20, "totalSize": 10737418240, "status": "active", "createTime": "2026-06-26T10:00:00", "updateTime": "2026-06-26T10:00:00" } ], "pageNo": 1, "pageSize": 20 } }

失败响应示例 — 未登录

{ "code": 401, "message": "未登录或 Token 无效", "data": null }
GET /api/drive/{id} 查询网盘详情需Token

路径参数

参数类型说明
idLong网盘ID

响应字段

字段类型说明
idLong网盘ID
nameString网盘名称
descriptionString网盘描述
logoUrlString网盘Logo图片链接(MinIO存储地址)
folderCountInteger文件夹数量
fileCountInteger文件数量
totalSizeLong总大小(字节)
statusString状态
createTimeString创建时间
updateTimeString更新时间

成功响应示例

{ "code": 200, "message": "查询成功", "data": { "id": 1, "name": "我的网盘", "description": "个人网盘", "logoUrl": "http://118.178.238.159:39000/wangpan/drive/1/logo.png", "folderCount": 5, "fileCount": 20, "totalSize": 10737418240, "status": "active", "createTime": "2026-06-26T10:00:00", "updateTime": "2026-06-26T10:00:00" } }

失败响应示例 — 网盘不存在

{ "code": 404, "message": "网盘不存在", "data": null }

失败响应示例 — 未登录

{ "code": 401, "message": "未登录或 Token 无效", "data": null }
PUT /api/drive/{id} 更新网盘需Token

请求体

{ "name": "新网盘名称", "description": "新描述", "logoData": "data:image/png;base64,iVBOR..." }

参数说明

参数类型必填说明
nameString网盘名称
descriptionString网盘描述
logoDataString新的Logo图片Base64编码,传入后覆盖旧Logo;不传则保留原Logo

成功响应示例

{ "code": 200, "message": "更新成功", "data": { "id": 1, "name": "新网盘名称", "description": "新描述", "logoUrl": "http://118.178.238.159:39000/wangpan/drive/1/logo.png", "updateTime": "2026-06-26T11:00:00" } }

失败响应示例 — 网盘不存在

{ "code": 404, "message": "网盘不存在", "data": null }

失败响应示例 — 权限不足

{ "code": 403, "message": "无权修改该网盘", "data": null }
DELETE /api/drive/{id} 删除网盘需Token

路径参数

参数类型说明
idLong网盘ID

成功响应示例

{ "code": 200, "message": "删除成功", "data": null }

失败响应示例 — 网盘不存在

{ "code": 404, "message": "网盘不存在", "data": null }

失败响应示例 — 权限不足

{ "code": 403, "message": "无权删除该网盘", "data": null }
POST /api/drive/{driveId}/folders 创建文件夹需Token

请求体

{ "name": "文件夹名称", "parentId": 0 }

成功响应示例

{ "code": 200, "message": "创建成功", "data": { "id": 1, "driveId": 1, "parentId": 0, "name": "我的电影", "description": "", "depth": 0, "createTime": "2026-06-26T10:00:00" } }

失败响应示例 — 参数缺失

{ "code": 400, "message": "文件夹名称不能为空", "data": null }

失败响应示例 — 网盘不存在

{ "code": 404, "message": "网盘不存在", "data": null }
GET /api/drive/{driveId}/folders 查询文件夹列表需Token

查询参数

参数默认值说明
parentId0父文件夹 ID

成功响应示例

{ "code": 200, "message": "查询成功", "data": [ { "id": 1, "driveId": 1, "parentId": 0, "name": "我的电影", "description": "", "depth": 0, "childFolderCount": 2, "fileCount": 5, "createTime": "2026-06-26T10:00:00" } ] }

失败响应示例 — 网盘不存在

{ "code": 404, "message": "网盘不存在", "data": null }

失败响应示例 — 未登录

{ "code": 401, "message": "未登录或 Token 无效", "data": null }
GET /api/drive/{driveId}/folders/{folderId} 查询文件夹详情需Token

路径参数

参数类型说明
driveIdLong网盘ID
folderIdLong文件夹ID

响应字段

字段类型说明
idLong文件夹ID
driveIdLong所属网盘ID
parentIdLong父文件夹ID(0表示根目录)
nameString文件夹名称
descriptionString文件夹描述
depthInteger层级深度
childFolderCountInteger子文件夹数量
fileCountInteger文件数量
totalSizeLong总大小(字节)
createTimeString创建时间
updateTimeString更新时间

成功响应示例

{ "code": 200, "message": "查询成功", "data": { "id": 1, "driveId": 1, "parentId": 0, "name": "我的电影", "description": "收藏的电影", "depth": 0, "childFolderCount": 2, "fileCount": 5, "totalSize": 5368709120, "createTime": "2026-06-26T10:00:00", "updateTime": "2026-06-26T10:00:00" } }

失败响应示例 — 文件夹不存在

{ "code": 404, "message": "文件夹不存在", "data": null }

失败响应示例 — 未登录

{ "code": 401, "message": "未登录或 Token 无效", "data": null }
PUT /api/drive/{driveId}/folders/{folderId} 更新文件夹需Token

路径参数

参数类型说明
driveIdLong网盘ID
folderIdLong文件夹ID

请求体(部分更新)

{ "name": "新文件夹名称", "description": "新描述", "parentId": 0 }

参数说明

参数类型必填说明
nameString文件夹名称
descriptionString文件夹描述
parentIdLong父文件夹ID(可移动文件夹)

成功响应示例

{ "code": 200, "message": "更新成功", "data": { "id": 1, "driveId": 1, "parentId": 0, "name": "新文件夹名称", "description": "新描述", "updateTime": "2026-06-26T11:00:00" } }

失败响应示例 — 文件夹不存在

{ "code": 404, "message": "文件夹不存在", "data": null }

失败响应示例 — 权限不足

{ "code": 403, "message": "无权修改该文件夹", "data": null }
DELETE /api/drive/{driveId}/folders/{folderId} 删除文件夹需Token

路径参数

参数类型说明
driveIdLong网盘ID
folderIdLong文件夹ID

说明

删除文件夹前会检查文件夹是否为空,如果包含子文件夹或电影文件则拒绝删除。

错误码

code说明
400文件夹不为空或数据库操作失败
401未登录或Token无效
403无权访问该文件夹
POST /api/drive/{driveId}/movies 创建电影(只传文件名)需Token

路径参数

参数类型说明
driveIdLong网盘ID

请求体

{ "title": "文件名.mp4", // 必填,文件名(同时作为电影标题) "folderId": 0 // 可选,默认0(根目录) }

参数说明

参数类型必填说明
titleString文件名(同时作为电影标题,后续通过 TMDB 刮削补充信息)
folderIdLong目标文件夹ID,默认0(根目录)

说明

只记录文件名,不上传文件数据。创建后通过 TMDB 刮削接口补充电影的海报、描述、评分等信息。自动检测 MIME 类型(mp4/mkv/avi → video/mp4)。

成功响应示例

{ "code": 200, "message": "创建成功", "data": { "id": 1, "driveId": 1, "folderId": 0, "title": "电影.mp4", "originalName": "电影.mp4", "mimeType": "video/mp4", "createTime": "2026-06-26T10:00:00" } }

失败响应示例 — 参数缺失

{ "code": 400, "message": "文件名不能为空", "data": null }

失败响应示例 — 网盘不存在

{ "code": 404, "message": "网盘不存在", "data": null }
GET /api/drive/{driveId}/folders/{folderId}/movies 查询电影文件列表需Token

路径参数

参数类型说明
driveIdLong网盘ID
folderIdLong文件夹ID(0表示根目录)

查询参数

参数默认值说明
pageNo1页码
pageSize20每页条数(最大100)

响应字段

字段类型说明
list[].idLong电影ID
list[].titleString电影名称
list[].originalNameString原始文件名
list[].mimeTypeStringMIME类型
list[].fileSizeLong文件大小(字节)
list[].extensionString文件扩展名
list[].minioUrlStringMinIO文件访问URL
list[].ratingInteger评分
list[].tagsString标签
totalInteger总数
pageNoInteger当前页码
pageSizeInteger每页条数

成功响应示例

{ "code": 200, "message": "查询成功", "data": { "total": 5, "pageNo": 1, "pageSize": 20, "list": [ { "id": 1, "title": "电影.mp4", "originalName": "电影.mp4", "mimeType": "video/mp4", "fileSize": 1073741824, "extension": "mp4", "minioUrl": "http://...", "rating": 85, "tags": "动作,科幻" } ] } }

失败响应示例 — 网盘不存在

{ "code": 404, "message": "网盘不存在", "data": null }

失败响应示例 — 未登录

{ "code": 401, "message": "未登录或 Token 无效", "data": null }
GET /api/drive/{driveId}/movies/{movieId} 查询电影文件详情需Token

路径参数

参数类型说明
driveIdLong网盘ID
movieIdLong电影ID

响应字段

字段类型说明
idLong电影ID
driveIdLong所属网盘ID
folderIdLong所属文件夹ID
titleString电影名称
originalNameString原始文件名
mimeTypeStringMIME类型
fileSizeLong文件大小(字节)
extensionString文件扩展名
descriptionString描述
maintainerString维护者
statusString状态
categoryString分类
scrapeTypeString刮削类型
ratingInteger评分
tagsString标签
overviewString电影简介(TMDB刮削)
castsString主演(逗号分隔,TMDB刮削)
directorsString导演(逗号分隔,TMDB刮削)
minioUrlStringMinIO文件访问URL
posterUrlString海报URL
createTimeString创建时间
updateTimeString更新时间

成功响应示例

{ "code": 200, "message": "查询成功", "data": { "id": 1, "driveId": 1, "folderId": 0, "title": "电影.mp4", "originalName": "电影.mp4", "mimeType": "video/mp4", "fileSize": 1073741824, "extension": "mp4", "description": "电影描述", "rating": 85, "tags": "动作,科幻", "overview": "电影简介...", "casts": "主演1,主演2", "directors": "导演1", "posterUrl": "http://...", "minioUrl": "http://...", "createTime": "2026-06-26T10:00:00", "updateTime": "2026-06-26T10:00:00" } }

失败响应示例 — 电影不存在

{ "code": 404, "message": "电影不存在", "data": null }

失败响应示例 — 未登录

{ "code": 401, "message": "未登录或 Token 无效", "data": null }
PUT /api/drive/{driveId}/movies/{movieId} 更新电影文件信息需Token

路径参数

参数类型说明
driveIdLong网盘ID
movieIdLong电影ID

请求体(部分更新,所有字段可选)

{ "title": "新电影名称", "originalName": "新文件名.mp4", "description": "新描述", "rating": 90, "tags": "新标签", "category": "新分类" }

参数说明

参数类型说明
titleString电影名称
originalNameString原始文件名(用于 TMDB 刮削有误时修改)
descriptionString描述
ratingInteger评分 0-100
tagsString标签
categoryString分类

说明

用于 TMDB 刮削有误时,用户可自定义修改文件名等信息。所有字段均为可选,只更新传入的字段。

成功响应示例

{ "code": 200, "message": "更新成功", "data": { "id": 1, "title": "新电影名称", "rating": 90, "updateTime": "2026-06-26T11:00:00" } }

失败响应示例 — 电影不存在

{ "code": 404, "message": "电影不存在", "data": null }

失败响应示例 — 权限不足

{ "code": 403, "message": "无权修改该电影", "data": null }
DELETE /api/drive/{driveId}/movies/{movieId} 删除电影文件需Token

路径参数

参数类型说明
driveIdLong网盘ID
movieIdLong电影ID

说明

逻辑删除(软删除),删除后自动更新网盘和文件夹的统计信息。

成功响应示例

{ "code": 200, "message": "删除成功", "data": null }

失败响应示例 — 电影不存在

{ "code": 404, "message": "电影不存在", "data": null }

失败响应示例 — 权限不足

{ "code": 403, "message": "无权删除该电影", "data": null }
GET /api/drive/movies/duplicates 检查重复电影需Token

功能说明

查询当前用户所有网盘下所有文件夹中的电影,按标题(title)分组找出重复的电影。返回每组重复电影的详细信息,包括所在文件夹的完整路径,前端可让用户选择删除其中一个。

成功响应

{ "code": 200, "message": "查询成功", "data": { "duplicateGroups": [ { "title": "电影名称", "count": 2, "movies": [ { "id": 10, "driveId": 1, "folderId": 5, "title": "电影名称", "originalName": "电影名称.mp4", "fileSize": 1073741824, "extension": "mp4", "category": "sci-fi", "rating": 85, "createTime": "2025-01-01T10:00:00", "folderPath": "我的电影库/科幻/2024" }, { "id": 20, "driveId": 1, "folderId": 8, "title": "电影名称", "originalName": "电影名称.mkv", "fileSize": 2147483648, "extension": "mkv", "category": "sci-fi", "rating": null, "createTime": "2025-02-01T15:00:00", "folderPath": "我的电影库/动作" } ] } ], "totalGroups": 1, "totalDuplicates": 2 } }

返回字段说明

字段类型说明
duplicateGroupsArray重复电影分组列表
duplicateGroups[].titleString重复的电影标题
duplicateGroups[].countInteger该标题下的重复数量
duplicateGroups[].moviesArray该标题下的所有电影记录
duplicateGroups[].movies[].idLong电影ID(可用于删除接口)
duplicateGroups[].movies[].folderPathString所在文件夹完整路径,如"网盘名/文件夹1/文件夹2"
totalGroupsInteger重复组总数
totalDuplicatesInteger涉及重复的电影总数

错误码

code说明
401未登录或 Token 无效
500服务器内部错误

Icon 管理服务

wangpan-drive-service : 8082
POST /api/icon 创建 Icon需Token

请求体(JSON)

字段类型必填说明
nameStringIcon 名称(最大100字符)
urlString条件必填外网链接 URL(最大500字符,linkType为external或both时必填)
internalUrlString条件必填内网链接 URL(最大500字符,linkType为internal或both时必填)
linkTypeString链接类型:external(仅外网,默认)/ internal(仅内网)/ both(内外网)
descriptionStringIcon 描述(最大500字符)
sortOrderInteger排序值,数字越小越靠前,默认0

请求示例(仅外网)

{ "name": "百度", "url": "https://www.baidu.com", "linkType": "external", "description": "搜索引擎", "sortOrder": 1 }

请求示例(内外网都有)

{ "name": "内部系统", "url": "https://system.example.com", "internalUrl": "http://192.168.1.100:8080", "linkType": "both", "description": "内部管理系统", "sortOrder": 2 }

成功响应(200)

{ "code": 200, "message": "创建成功", "data": { "id": 1, "name": "百度", "url": "https://www.baidu.com", "internalUrl": null, "linkType": "external", "description": "搜索引擎", "sortOrder": 1, "status": "active", "logoUrl": "http://118.178.238.159:39000/wangpan/icons/2/1718265600000.png", "createTime": "2026-06-13T16:00:00" } }
GET /api/icon 查询当前用户的 Icon 列表需Token

功能说明

查询当前登录用户的所有 Icon,按 sortOrder 升序、createTime 降序排列。每个用户只能看到自己创建的 Icon。

成功响应(200)

{ "code": 200, "message": "查询成功", "data": { "list": [ { "id": 1, "name": "百度", "url": "https://www.baidu.com", "internalUrl": null, "linkType": "external", "description": "搜索引擎", "sortOrder": 1, "status": "active", "logoUrl": "http://118.178.238.159:39000/wangpan/icons/2/1718265600000.png", "createTime": "2026-06-13T16:00:00", "updateTime": "2026-06-13T16:00:00" } ], "total": 1 } }
GET /api/icon/{id} 查询单个 Icon 详情需Token

路径参数

参数类型说明
idLongIcon ID

成功响应(200)

{ "code": 200, "message": "查询成功", "data": { "id": 1, "name": "百度", "url": "https://www.baidu.com", "internalUrl": null, "linkType": "external", "description": "搜索引擎", "sortOrder": 1, "status": "active", "logoUrl": "http://118.178.238.159:39000/wangpan/icons/2/1718265600000.png", "createTime": "2026-06-13T16:00:00", "updateTime": "2026-06-13T16:00:00" } }

失败响应示例 — Icon 不存在

{ "code": 404, "message": "Icon 不存在或无权访问", "data": null }

失败响应示例 — 未登录

{ "code": 401, "message": "未登录或 Token 无效", "data": null }
PUT /api/icon/{id} 更新 Icon需Token

路径参数

参数类型说明
idLongIcon ID

请求体(JSON,所有字段可选)

字段类型说明
nameStringIcon 名称
urlString外网链接
internalUrlString内网链接
linkTypeString链接类型:external / internal / both
descriptionStringIcon 描述
sortOrderInteger排序值

请求示例

{ "name": "新名称", "url": "https://new-url.com", "internalUrl": "http://192.168.1.100:8080", "linkType": "both", "sortOrder": 2 }

成功响应(200)

{ "code": 200, "message": "更新成功", "data": { "id": 1, "name": "新名称", "url": "https://new-url.com", "internalUrl": "http://192.168.1.100:8080", "linkType": "both", "description": "搜索引擎", "sortOrder": 2, "status": "active", "logoUrl": "http://118.178.238.159:39000/wangpan/icons/2/1718265600000.png", "createTime": "2026-06-13T16:00:00", "updateTime": "2026-06-13T17:00:00" } }

错误码

code说明
401未登录或 Token 无效
500Icon 不存在或无权修改
DELETE /api/icon/{id} 删除 Icon需Token

路径参数

参数类型说明
idLongIcon ID

成功响应(200)

{ "code": 200, "message": "删除成功", "data": null }

错误码

code说明
401未登录或 Token 无效
500Icon 不存在或无权删除
POST /api/icon/{id}/logo 上传自定义图标图片需Token

功能说明

上传自定义图标图片替换自动抓取的 logo。上传后会自动删除旧的 MinIO 图片,防止硬盘空间浪费。系统每 24 小时自动清理无用图片。

路径参数

参数类型说明
idLongIcon ID

请求格式

multipart/form-data

字段类型必填说明
fileFile图片文件(png/jpg/jpeg/gif/webp/ico,最大 1MB)

请求示例(curl)

curl -X POST http://localhost:8888/api/icon/1/logo \ -H "Authorization: Bearer <token>" \ -F "file=@/path/to/icon.png"

成功响应(200)

{ "code": 200, "message": "图标上传成功", "data": { "id": 1, "name": "百度", "logoUrl": "http://118.178.238.159:39000/wangpan/icons/2/1718265600000.png", "updateTime": "2026-06-15T10:00:00" } }

失败响应示例 — 文件为空

{ "code": 400, "message": "上传文件为空", "data": null }

失败响应示例 — 文件格式不支持

{ "code": 400, "message": "不支持的文件格式,仅支持 png/jpg/jpeg/gif/webp/ico", "data": null }

失败响应示例 — 文件超过 1MB

{ "code": 400, "message": "文件大小超过限制(最大 1MB)", "data": null }

失败响应示例 — Icon 不存在

{ "code": 404, "message": "Icon 不存在", "data": null }

TMDB 刮削服务

wangpan-tmdb-service : 8083
GET /api/movies/recommend 今日推荐(每天固定3部电影)需Token

功能说明

从当前用户的电影库中随机抽取3部电影用于首页展示。

推荐规则:

  • 从 00:00 到 23:59 返回固定的3部电影
  • 当天不管查询多少次都返回相同的结果
  • 第二天 00:00 后重新随机挑选3部
  • 推荐结果缓存在 wp_daily_recommend 表中

成功响应示例

{ "code": 200, "message": "查询成功", "data": { "list": [ { "id": 10, "title": "电影名称1", "posterUrl": "海报URL", "rating": 85, "category": "动作", "tags": "标签1,标签2", "createTime": "2025-01-01T10:00:00" }, { "id": 20, "title": "电影名称2", ... }, { "id": 30, "title": "电影名称3", ... } ], "count": 3 } }

返回字段说明

字段类型说明
listArray推荐的电影列表(最多3部)
list[].idLong电影ID
list[].titleString电影标题
list[].posterUrlString海报URL
list[].ratingInteger评分(0-100)
list[].categoryString分类
list[].tagsString标签
list[].createTimeString创建时间
countInteger实际返回的电影数量(可能小于3)

失败响应示例 — 未登录或 Token 无效

{ "code": 401, "message": "未登录或 Token 已过期", "data": null }

失败响应示例 — 服务器内部错误

{ "code": 500, "message": "服务器内部错误,请稍后重试", "data": null }
GET /api/movies 电影列表查询(按文件夹分组,每组最多10条)需Token

功能说明

wp_drive_movie 表查询当前用户所有电影,按文件夹分组返回,每个文件夹最多返回 10 条电影数据。支持分页:pageNo 控制文件夹分页。

查询参数

参数类型必填说明
keywordString搜索关键词
statusString电影状态:active(正常)/ deleted(已删除)
scrapeTypeString刮削类型:tmdb / manual / none
sortByString排序字段(如 createTime、rating、title)
sortOrderString排序方向:asc / desc
pageNoint页码,默认 1
pageSizeint每页条数(文件夹数),默认 20

响应字段说明

字段类型说明
totalFoldersInteger文件夹总数
pageNoInteger当前页码
pageSizeInteger每页条数
folderGroups[].folderIdLong文件夹ID
folderGroups[].movieCountInteger该文件夹下返回的电影数量
folderGroups[].movies[].idLong电影ID
folderGroups[].movies[].driveIdLong所属网盘ID
folderGroups[].movies[].folderIdLong所属文件夹ID
folderGroups[].movies[].titleString电影名称
folderGroups[].movies[].originalNameString原始文件名
folderGroups[].movies[].mimeTypeStringMIME类型
folderGroups[].movies[].fileSizeLong文件大小(字节)
folderGroups[].movies[].extensionString文件扩展名
folderGroups[].movies[].descriptionString描述
folderGroups[].movies[].scrapeStatusString刮削状态
folderGroups[].movies[].ratingInteger评分(0-100)
folderGroups[].movies[].tagsString标签
folderGroups[].movies[].overviewString电影简介(TMDB刮削)
folderGroups[].movies[].castsString主演(逗号分隔,TMDB刮削)
folderGroups[].movies[].directorsString导演(逗号分隔,TMDB刮削)
folderGroups[].movies[].posterUrlString竖版海报URL(2:3 比例)
folderGroups[].movies[].backdropUrlString横版背景图URL(16:9 比例)
folderGroups[].movies[].minioUrlStringMinIO 文件访问URL
folderGroups[].movies[].createTimeString创建时间
folderGroups[].movies[].updateTimeString更新时间

响应示例

{ "code": 200, "message": "查询成功", "data": { "totalFolders": 5, "pageNo": 1, "pageSize": 20, "folderGroups": [ { "folderId": 3, "movieCount": 2, "movies": [ { "id": 1, "driveId": 1, "folderId": 3, "title": "肖申克的救赎", "posterUrl": "http://...:39000/wangpan/posters/1/poster_xxx.jpg", "backdropUrl": "http://...:39000/wangpan/posters/1/backdrop_xxx.jpg", "rating": 93, ... } ] } ] } }

失败响应示例 — 未登录或 Token 无效

{ "code": 401, "message": "未登录或 Token 已过期", "data": null }

失败响应示例 — 参数错误

{ "code": 400, "message": "请求参数错误", "data": null }
GET /api/movies/{id} 电影详情查询需Token

功能说明

查询单部电影的完整详情信息,包括基本信息、海报、评分、简介、导演、主演等。

路径参数

参数类型说明
idLong电影ID

响应字段说明

字段类型说明
idLong电影ID
driveIdLong所属网盘ID
folderIdLong所属文件夹ID
titleString电影名称
originalNameString原始文件名
mimeTypeStringMIME类型
fileSizeLong文件大小(字节)
extensionString文件扩展名
descriptionString电影描述
scrapeStatusString刮削状态:pending/scraping/success/failed
ratingInteger评分(0-100)
overviewString电影简介(TMDB刮削)
castsString主演(逗号分隔,TMDB刮削)
directorsString导演(逗号分隔,TMDB刮削)
posterUrlString竖版海报URL(2:3 比例)
backdropUrlString横版背景图URL(16:9 比例)
tagsString标签(逗号分隔)
createTimeString创建时间
updateTimeString更新时间

成功响应示例

{ "code": 200, "message": "查询成功", "data": { "id": 1, "driveId": 1, "folderId": 3, "title": "肖申克的救赎", "originalName": "肖申克的救赎.mp4", "mimeType": "video/mp4", "fileSize": 2147483648, "extension": "mp4", "description": "电影描述", "scrapeStatus": "success", "rating": 93, "overview": "电影简介...", "casts": "Tim Robbins, Morgan Freeman", "directors": "Frank Darabont", "posterUrl": "http://...:39000/wangpan/posters/1/poster_xxx.jpg", "backdropUrl": "http://...:39000/wangpan/posters/1/backdrop_xxx.jpg", "tags": "剧情,犯罪", "createTime": "2025-01-01T10:00:00", "updateTime": "2025-01-15T10:00:00" } }

失败响应示例 — 电影不存在

{ "code": 404, "message": "电影不存在或无权访问", "data": null }

失败响应示例 — 未登录或 Token 无效

{ "code": 401, "message": "未登录或 Token 已过期", "data": null }
GET /api/movies/{id}/scrape-status 查询单部电影刮削状态需Token

功能说明

查询单部电影的刮削状态,返回三种状态:刮削中(scraping)、刮削失败(failed)、刮削成功(success)。

路径参数

参数类型说明
idLong电影ID

响应字段说明

字段类型说明
movieIdLong电影ID
titleString电影名称
statusString刮削状态:scraping / failed / success / unknown
messageString状态描述信息
errorString失败原因(仅 status=failed 时返回)
posterUrlString竖版海报URL(仅 status=success 时返回)
backdropUrlString横版背景图URL(仅 status=success 时返回)
ratingInteger评分(仅 status=success 时返回)
categoryString分类(仅 status=success 时返回)
tagsString标签(仅 status=success 时返回)
overviewString电影简介(仅 status=success 时返回)
castsString主演(仅 status=success 时返回)
directorsString导演(仅 status=success 时返回)

响应示例 - 刮削中

{ "code": 200, "message": "查询成功", "data": { "movieId": 1, "title": "电影名称", "status": "scraping", "message": "正在刮削中,请稍候..." } }

响应示例 - 刮削失败

{ "code": 200, "message": "查询成功", "data": { "movieId": 1, "title": "电影名称", "status": "failed", "message": "刮削失败", "error": "TMDB API 请求失败" } }

响应示例 - 刮削成功

{ "code": 200, "message": "查询成功", "data": { "movieId": 1, "title": "电影名称", "status": "success", "message": "刮削成功", "posterUrl": "http://...:39000/wangpan/posters/1/poster_xxx.jpg", "backdropUrl": "http://...:39000/wangpan/posters/1/backdrop_xxx.jpg", "rating": 85, "category": "动作", "tags": "动作,科幻", "overview": "电影简介...", "casts": "主演1,主演2", "directors": "导演1" } }

失败响应示例 — 未登录或 Token 无效

{ "code": 401, "message": "未登录或 Token 已过期", "data": null }

失败响应示例 — 电影不存在

{ "code": 404, "message": "电影不存在或无权访问", "data": null }
POST /api/movies 创建电影需Token

功能说明

创建新的电影记录,title 为必填字段。

请求体(所有字段可选,title 必填)

{ "title": "电影名称", // 必填 "maintainer": "维护者", // 可选 "status": "active", // 可选:active / deleted "category": "动作", // 可选 "scrapeType": "tmdb", // 可选:tmdb / manual / none "rating": 85, // 可选:0-100 "posterUrl": "海报URL", // 可选 "tags": "标签1,标签2" // 可选 }

成功响应示例

{ "code": 200, "message": "创建成功", "data": { "id": 1, "title": "电影名称", "createTime": "2025-01-01T10:00:00" } }

失败响应示例 — 缺少必填字段

{ "code": 400, "message": "电影名称不能为空", "data": null }

失败响应示例 — 未登录或 Token 无效

{ "code": 401, "message": "未登录或 Token 已过期", "data": null }
PUT /api/movies/{id} 更新电影需Token

功能说明

更新指定电影的信息,支持部分更新。

路径参数

参数类型说明
idLong电影ID

请求体(部分更新,所有字段可选)

{ "title": "新电影名称", "maintainer": "新维护者", "status": "active", "category": "新分类", "scrapeType": "tmdb", "rating": 90, "posterUrl": "新海报URL", "tags": "新标签" }

成功响应示例

{ "code": 200, "message": "更新成功", "data": { "id": 1, "title": "新电影名称", "updateTime": "2025-01-15T10:00:00" } }

失败响应示例 — 电影不存在

{ "code": 404, "message": "电影不存在", "data": null }

失败响应示例 — 未登录或 Token 无效

{ "code": 401, "message": "未登录或 Token 已过期", "data": null }
DELETE /api/movies/{id} 删除电影需Token

功能说明

删除指定的电影记录。

路径参数

参数类型说明
idLong电影ID

成功响应示例

{ "code": 200, "message": "删除成功", "data": null }

失败响应示例 — 电影不存在

{ "code": 404, "message": "电影不存在", "data": null }

失败响应示例 — 未登录或 Token 无效

{ "code": 401, "message": "未登录或 Token 已过期", "data": null }
POST /api/movies/batch-delete 批量删除电影需Token

功能说明

批量删除多个电影记录。

请求体

{ "ids": [1, 2, 3] }

成功响应示例

{ "code": 200, "message": "批量删除成功", "data": { "deletedCount": 3 } }

失败响应示例 — 参数错误

{ "code": 400, "message": "电影ID列表不能为空", "data": null }

失败响应示例 — 未登录或 Token 无效

{ "code": 401, "message": "未登录或 Token 已过期", "data": null }
GET /api/movies/stats 电影统计需Token

功能说明

获取当前用户的电影数量统计,按刮削类型和分类分组。

响应示例

{ "code": 200, "data": { "totalCount": 10, "scrapedCount": 8, "pendingCount": 2 } }

失败响应示例 — 未登录或 Token 无效

{ "code": 401, "message": "未登录或 Token 已过期", "data": null }
GET /api/tmdb/key 获取 TMDB API Key需Token

功能说明

获取当前用户配置的 TMDB API Key。

成功响应示例

{ "code": 200, "message": "查询成功", "data": { "tmdbApiKey": "your_api_key_here" } }

失败响应示例 — 未登录或 Token 无效

{ "code": 401, "message": "未登录或 Token 已过期", "data": null }
POST /api/tmdb/key 设置 TMDB API Key需Token

请求体

{ "tmdbApiKey": "你的API Key" }
POST /api/tmdb-scraper/scrape 单部电影刮削需Token

功能说明

手动触发单部电影刮削,自动匹配TMDB最佳结果。刮削完成后会更新电影的简介、导演、主演、海报等信息。注意:两次请求需间隔5秒,防止频繁点击。

请求方式

支持两种方式传递 movieId:

1. URL 查询参数?movieId=1

2. 请求体 JSON

{ "movieId": 1 }

响应字段说明

字段类型说明
movieIdLong电影ID
userIdLong用户ID
tmdbIdLongTMDB电影ID
titleString电影标题(来自TMDB)
originalTitleString原始标题(外文)
overviewString电影简介
releaseDateString上映日期
posterPathStringTMDB海报路径
backdropPathStringTMDB背景图路径
localPosterUrlString本地竖版海报URL(MinIO)
localBackdropUrlString本地横版背景图URL(MinIO)
tmdbRatingIntegerTMDB评分(0-100分制)
voteCountInteger投票数
runtimeInteger片长(分钟)
genresString类型(逗号分隔)
directorsString导演(逗号分隔,最多2位)
castsString主演(逗号分隔,最多5位)
originalLanguageString原始语言
productionCountriesString制片国家(逗号分隔)
cacheTimeString缓存时间
statusString缓存状态

成功响应示例

{ "code": 200, "message": "刮削成功", "data": { "movieId": 1, "userId": 1, "tmdbId": 597, "title": "泰坦尼克号", "originalTitle": "Titanic", "overview": "1912年4月10日,泰坦尼克号从 Southampton 出发...", "releaseDate": "1997-11-18", "posterPath": "/9xjZS2rlVxm8SFx8kPC3JIGCOY.jpg", "backdropPath": "/rTh4K5uw9HypmpGslcKd4QfHl93.jpg", "localPosterUrl": "http://...:39000/wangpan/posters/poster_1_597.jpg", "localBackdropUrl": "http://...:39000/wangpan/posters/backdrop_1_597.jpg", "tmdbRating": 78, "voteCount": 24563, "runtime": 194, "genres": "剧情, 爱情, 灾难", "directors": "James Cameron", "casts": "Leonardo DiCaprio, Kate Winslet, Billy Zane, Kathy Bates, Frances Fisher", "originalLanguage": "en", "productionCountries": "United States of America", "cacheTime": "2026-06-26T16:30:00", "status": "active" } }

失败响应示例 — 操作过于频繁

{ "code": 500, "message": "操作过于频繁,请等待 3 秒后再试", "data": null }

失败响应示例 — 未找到匹配结果

{ "code": 500, "message": "TMDB未找到匹配的电影: xxx", "data": null }

失败响应示例 — 未登录或 Token 无效

{ "code": 401, "message": "未登录或 Token 已过期", "data": null }
GET /api/tmdb-scraper/search 搜索TMDB电影(返回所有匹配结果供前端选择)需Token

功能说明

根据电影ID自动获取标题,搜索TMDB返回所有匹配结果。如果查询出多条结果,前端应展示列表让用户选择。

查询参数

参数类型必填说明
movieIdLong电影ID(自动获取标题搜索)
keywordString自定义搜索关键词(不传则使用电影标题)

响应字段说明

字段类型说明
movieIdLong电影ID
keywordString搜索关键词
totalInteger搜索结果总数
list[].tmdbIdLongTMDB电影ID(用于确认刮削)
list[].titleString电影标题
list[].originalTitleString原始标题
list[].releaseDateString上映日期
list[].overviewString电影简介
list[].posterPathString海报图片URL
list[].voteAverageDouble评分

响应示例

{ "code": 200, "message": "查询成功", "data": { "movieId": 23, "keyword": "泰坦尼克号", "total": 3, "list": [ { "tmdbId": 597, "title": "泰坦尼克号", "originalTitle": "Titanic", "releaseDate": "1997-11-18", "overview": "电影简介...", "posterPath": "https://image.tmdb.org/t/p/w500/xxx.jpg", "voteAverage": 7.9 } ] } }
POST /api/tmdb-scraper/confirm 确认刮削(用户选择TMDB结果后执行)需Token

功能说明

用户从搜索结果中选择一部电影后,调用此接口执行刮削。刮削完成后会更新电影的简介、导演、主演、海报等信息。注意:两次请求需间隔5秒,防止频繁点击。

请求体

{ "movieId": 23, "tmdbId": 597 }

响应字段说明

字段类型说明
movieIdLong电影ID
userIdLong用户ID
tmdbIdLongTMDB电影ID
titleString电影标题(来自TMDB)
originalTitleString原始标题(外文)
overviewString电影简介
releaseDateString上映日期
posterPathStringTMDB海报路径
backdropPathStringTMDB背景图路径
localPosterUrlString本地竖版海报URL(MinIO)
localBackdropUrlString本地横版背景图URL(MinIO)
tmdbRatingIntegerTMDB评分(0-100分制)
voteCountInteger投票数
runtimeInteger片长(分钟)
genresString类型(逗号分隔)
directorsString导演(逗号分隔,最多2位)
castsString主演(逗号分隔,最多5位)
originalLanguageString原始语言
productionCountriesString制片国家(逗号分隔)
cacheTimeString缓存时间
statusString缓存状态

成功响应示例

{ "code": 200, "message": "刮削成功", "data": { "movieId": 23, "userId": 1, "tmdbId": 597, "title": "泰坦尼克号", "originalTitle": "Titanic", "overview": "1912年4月10日,泰坦尼克号从 Southampton 出发...", "releaseDate": "1997-11-18", "posterPath": "/9xjZS2rlVxm8SFx8kPC3JIGCOY.jpg", "backdropPath": "/rTh4K5uw9HypmpGslcKd4QfHl93.jpg", "localPosterUrl": "http://...:39000/wangpan/posters/poster_23_597.jpg", "localBackdropUrl": "http://...:39000/wangpan/posters/backdrop_23_597.jpg", "tmdbRating": 78, "voteCount": 24563, "runtime": 194, "genres": "剧情, 爱情, 灾难", "directors": "James Cameron", "casts": "Leonardo DiCaprio, Kate Winslet, Billy Zane, Kathy Bates, Frances Fisher", "originalLanguage": "en", "productionCountries": "United States of America", "cacheTime": "2026-06-26T16:30:00", "status": "active" } }

失败响应示例 — 操作过于频繁

{ "code": 500, "message": "操作过于频繁,请等待 3 秒后再试", "data": null }

失败响应示例 — 电影不存在

{ "code": 404, "message": "电影不存在", "data": null }

失败响应示例 — 未登录或 Token 无效

{ "code": 401, "message": "未登录或 Token 已过期", "data": null }
POST /api/tmdb-scraper/batch-scrape 批量刮削需Token

请求体(movieIds 可选)

{ "movieIds": [1, 2, 3] } // 可选:不传则自动查找需要刮削的电影

响应示例

{ "code": 200, "message": "批量刮削完成", "data": { "successCount": 2, "failCount": 0, "total": 2 } }
GET /api/tmdb-scraper/caches 查询缓存列表需Token

查询参数

参数默认值说明
pageNo1页码
pageSize20每页条数
GET /api/tmdb-scraper/stats 刮削统计需Token

响应示例

{ "code": 200, "data": { "totalCaches": 5, "activeCaches": 3, "expiredCaches": 2, "userId": 2 } }
POST /api/tmdb-scraper/trigger 手动触发定时任务需Token

功能说明

手动触发 TMDB 定时扫描任务,查找需要刮削的电影并执行刮削。无需请求体。

响应示例

{ "code": 200, "message": "扫描任务已触发", "data": { "message": "扫描任务已触发", "triggeredBy": 2, "triggerType": "manual" } }
GET /api/tmdb-scraper/scraper-logs 查询刮削日志需Token

查询参数

参数默认值说明
pageNo1页码
pageSize20每页条数

响应示例

{ "code": 200, "data": { "total": 10, "list": [ { "id": 1, "scanTime": "2026-06-18T10:00:00", "totalMovies": 5, "successCount": 4, "failCount": 1 } ], "pageNo": 1, "pageSize": 20 } }
DELETE /api/tmdb-scraper/cache/{movieId} 删除缓存需Token

路径参数

参数类型说明
movieIdLong电影ID

功能说明

删除指定电影的 TMDB 刮削缓存,下次刮削时将重新从 TMDB 获取数据。

响应示例

{ "code": 200, "message": "缓存删除成功", "data": null }

OpenList 多网盘聚合服务

wangpan-drive-service : 8082 · 依赖 OpenList 服务 (http://ldfun.asia:13000)

功能说明

OpenList 集成模块将 OpenList 作为多网盘聚合后端,支持 80+ 种网盘服务(阿里云盘、百度网盘、UC网盘、OneDrive 等)。 Java 服务负责业务逻辑(用户、权限、TMDB 刮削),OpenList 负责文件操作(上传、下载、预览)。

前端
Gateway:8888
Drive:8082
OpenList:13000
各网盘

前置配置

1. 在 OpenList 管理后台 (http://ldfun.asia:13000/@manage) 添加网盘存储
2. 记录存储的 挂载路径(如 /uc)和 存储 ID(通过 API 获取)
3. 在 application.yml 中配置 OpenList 服务地址和账号密码
4. 创建网盘时传入 openlistStorageIdopenlistMountPath 关联 OpenList 存储

POST /api/drive 创建网盘(关联 OpenList 存储) 需Token

请求头

Authorization: Bearer <token> Content-Type: application/json

请求体

{ "name": "UC网盘电影库", "description": "UC网盘存储", "openlistStorageId": "1", "openlistMountPath": "/uc" }

字段说明

字段类型必填说明
nameString网盘名称
descriptionString网盘描述
openlistStorageIdStringOpenList 存储 ID(不传则仅记录元数据)
openlistMountPathStringOpenList 挂载路径(如 "/uc")

成功响应示例

{ "code": 200, "message": "创建成功", "data": { "id": 1, "name": "UC网盘电影库", "description": "UC网盘存储", "openlistStorageId": "1", "openlistMountPath": "/uc", "folderCount": 0, "fileCount": 0, "totalSize": 0, "status": "active", "createTime": "2026-06-26T15:00:00", "updateTime": "2026-06-26T15:00:00" } }

失败响应示例

{ "code": 400, "message": "创建网盘失败:网盘名称不能为空", "data": null }
POST /api/drive/{driveId}/folders/{folderId}/sync-files 从 OpenList 同步文件夹文件 需Token

请求头

Authorization: Bearer <token>

路径参数

参数类型说明
driveIdLong网盘 ID
folderIdLong文件夹 ID(0 表示根目录)

功能说明

调用 OpenList API 获取指定路径下的文件列表,自动创建数据库中缺失的电影记录。 已存在的文件不会重复创建。同步后文件可进行 TMDB 刮削。

成功响应示例

{ "code": 200, "message": "同步成功", "data": { "syncCount": 5, "totalFiles": 10 } }

响应字段说明

字段说明
syncCount本次新增的电影记录数量
totalFilesOpenList 中该路径下的文件总数

失败响应示例

{ "code": 400, "message": "同步失败:网盘未关联 OpenList 存储", "data": null }
GET /api/drive/{driveId}/movies/{movieId}/play-url 获取电影真实播放链接 需Token

请求头

Authorization: Bearer <token>

路径参数

参数类型说明
driveIdLong网盘 ID
movieIdLong电影 ID

功能说明

调用 OpenList API 获取文件的真实下载地址,返回的 URL 可直接用于视频播放器播放。 仅支持 storageTypeopenlist 的电影记录。

成功响应示例

{ "code": 200, "message": "获取成功", "data": { "playUrl": "https://uc网盘真实下载地址/xxx.mp4", "fileName": "阿凡达.mp4", "fileSize": 1073741824 } }

响应字段说明

字段说明
playUrl真实播放/下载地址,可直接用于视频播放器
fileName文件名
fileSize文件大小(字节)

失败响应示例

{ "code": 400, "message": "获取失败:该电影不是 OpenList 管理的文件", "data": null }
GET /api/drive 查看网盘列表(含 OpenList 信息) 需Token

请求头

Authorization: Bearer <token>

成功响应示例

{ "code": 200, "data": [ { "id": 1, "name": "UC网盘电影库", "openlistStorageId": "1", "openlistMountPath": "/uc", "folderCount": 2, "fileCount": 10, "totalSize": 10737418240, "status": "active" } ] }

新增字段说明

字段说明
openlistStorageId关联的 OpenList 存储 ID(null 表示未关联)
openlistMountPathOpenList 挂载路径(如 "/uc")
GET /api/drive/{driveId}/folders/{folderId}/movies 查看电影列表(含 OpenList 信息) 需Token

请求头

Authorization: Bearer <token>

路径参数

参数类型说明
driveIdLong网盘 ID
folderIdLong文件夹 ID(0 表示根目录)

成功响应示例

{ "code": 200, "data": { "list": [ { "id": 1, "title": "阿凡达.mp4", "openlistFilePath": "/uc/阿凡达.mp4", "storageType": "openlist", "fileSize": 1073741824, "mimeType": "video/mp4" } ], "total": 10, "page": 1, "pageSize": 20 } }

新增字段说明

字段说明
openlistFilePathOpenList 文件路径(如 "/uc/阿凡达.mp4")
storageType存储类型:metadata(仅元数据)/ openlist(OpenList 管理)
fileSize文件大小(字节)

前端调用示例

创建网盘

const response = await fetch('/api/drive', { method: 'POST', headers: { 'Authorization': `Bearer ${token}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ name: 'UC网盘电影库', openlistStorageId: '1', openlistMountPath: '/uc' }) });

同步文件

const response = await fetch(`/api/drive/${driveId}/folders/${folderId}/sync-files`, { method: 'POST', headers: { 'Authorization': `Bearer ${token}` } }); const data = await response.json(); console.log(`同步了 ${data.data.syncCount} 个文件`);

播放视频

const response = await fetch(`/api/drive/${driveId}/movies/${movieId}/play-url`, { headers: { 'Authorization': `Bearer ${token}` } }); const data = await response.json(); videoPlayer.src = data.data.playUrl; // 直接设置视频源 videoPlayer.play();

通用响应格式

{ "code": 200, "message": "操作结果描述", "data": { ... } }

状态码说明

状态码说明
200请求成功
400请求参数错误
401未授权 / 令牌无效
403权限不足
404资源不存在
500服务器内部错误

认证说明

除以下 3 个接口 外,所有接口都需要在请求头中携带访问令牌:

无需 Token 的接口:
  POST /api/login  用户登录
  POST /api/register  用户注册
  GET /api/token/validate?token=xxx  令牌验证(token 通过 URL 参数传递)

需要 Token 的接口(带 需Token 标识):
  在请求头中添加:Authorization: Bearer <token>