Go to file
2026-06-25 18:29:27 +08:00
.idea feat: 完成网盘电影刮削系统全量功能开发 2026-06-25 18:25:08 +08:00
.trae/rules docs(git-commit-rules): 完善git提交信息规则文档 2026-06-25 18:29:27 +08:00
.vscode Initial commit 2026-06-15 10:25:06 +08:00
logs 任务:添加监控及服务重启脚本 2026-06-25 18:27:47 +08:00
monitoring 任务:添加监控及服务重启脚本 2026-06-25 18:27:47 +08:00
wangpan-common 任务:添加监控及服务重启脚本 2026-06-25 18:27:47 +08:00
wangpan-drive-service 任务:添加监控及服务重启脚本 2026-06-25 18:27:47 +08:00
wangpan-gateway 任务:添加监控及服务重启脚本 2026-06-25 18:27:47 +08:00
wangpan-tmdb-service 任务:添加监控及服务重启脚本 2026-06-25 18:27:47 +08:00
wangpan-user-service 任务:添加监控及服务重启脚本 2026-06-25 18:27:47 +08:00
API.md Initial commit 2026-06-15 10:25:06 +08:00
pom.xml Initial commit 2026-06-15 10:25:06 +08:00
PROJECT_REFERENCE.md fix: 统一 wp_drive_movie 表映射,移除废弃的 wp_movie 表引用 2026-06-18 19:02:43 +08:00
README.md docs: 新增 README.md 项目文档 2026-06-18 19:08:44 +08:00
restart-services.ps1 任务:添加监控及服务重启脚本 2026-06-25 18:27:47 +08:00
restart-services.sh 任务:添加监控及服务重启脚本 2026-06-25 18:27:47 +08:00

WangPan 网盘系统

基于 Spring Cloud 微服务架构的个人网盘系统支持文件管理、电影元数据刮削TMDB、用户认证等功能。


目录


项目简介

WangPan 是一个功能完整的个人网盘系统,采用微服务架构设计,主要功能包括:

  • 用户认证注册、登录、Token 管理、登录日志
  • 网盘管理:创建网盘、文件夹管理、电影文件上传/管理
  • TMDB 刮削:自动从 TMDB 获取电影元数据(标题、评分、海报、简介等)
  • Icon 管理:自定义图标上传与管理
  • API 网关:统一入口,路由转发,认证拦截

技术栈

技术 版本 用途
Java 17 开发语言
Spring Boot 3.2.5 应用框架
Spring Cloud Gateway 2023.0.1 API 网关
MyBatis-Plus 3.5.7 ORM 框架
MySQL 8.0.33 关系型数据库
MinIO 8.5.7 对象存储(文件/图片)
Jasypt 3.0.5 配置文件加密
Maven 3.x 构建工具

模块架构

wangpan/
├── wangpan-common/          # 公共模块DO/Mapper/Repository/Entity/Util/Interceptor
├── wangpan-user-service/   # 用户认证服务(端口 8081
├── wangpan-drive-service/  # 网盘管理服务(端口 8082
├── wangpan-tmdb-service/   # TMDB 刮削服务(端口 8083
└── wangpan-gateway/        # API 网关(端口 8888

服务端口与职责

服务 端口 职责
wangpan-user-service 8081 用户注册、登录、Token 签发与验证、登录日志
wangpan-drive-service 8082 网盘 CRUD、文件夹管理、电影管理、Icon 管理、重复检测
wangpan-tmdb-service 8083 TMDB API 调用、电影元数据刮削、刮削缓存、定时扫描
wangpan-gateway 8888 统一路由入口、CORS 跨域、认证拦截、API 文档页面

分层架构

Controller  →  接收请求、参数校验、调用 Service、返回 Result
    ↓
Service     →  业务逻辑处理、事务管理
    ↓
Repository  →  数据访问封装、Entity ↔ DO 转换、LambdaQueryWrapper 查询
    ↓
Mapper      →  MyBatis-Plus BaseMapper 接口 + XML 复杂 SQL
    ↓
DO          →  数据库表映射(@TableName 注解)

快速开始

环境要求

  • JDK 17+
  • Maven 3.6+
  • MySQL 8.0+
  • MinIO Server

1. 克隆项目

git clone http://ldfun.asia:8418/djl1022/java.git
cd java

2. 编译项目

mvn clean install -DskipTests

3. 配置数据库与 MinIO

确保 MySQL 数据库 wangpan 已创建MinIO 服务已启动。配置文件中的密码均使用 Jasypt 加密,无需手动修改。

4. 启动服务

必须通过以下命令启动每个服务Jasypt 解密密钥必须传入):

# 启动用户服务(端口 8081
java -DJASYPT_ENCRYPTOR_PASSWORD=wangpan-secret-key-2024 -jar wangpan-user-service/target/wangpan-user-service-1.0-SNAPSHOT.jar

# 启动网盘服务(端口 8082
java -DJASYPT_ENCRYPTOR_PASSWORD=wangpan-secret-key-2024 -jar wangpan-drive-service/target/wangpan-drive-service-1.0-SNAPSHOT.jar

# 启动 TMDB 服务(端口 8083
java -DJASYPT_ENCRYPTOR_PASSWORD=wangpan-secret-key-2024 -jar wangpan-tmdb-service/target/wangpan-tmdb-service-1.0-SNAPSHOT.jar

# 启动网关(端口 8888
java -DJASYPT_ENCRYPTOR_PASSWORD=wangpan-secret-key-2024 -jar wangpan-gateway/target/wangpan-gateway-1.0-SNAPSHOT.jar

注意-DJASYPT_ENCRYPTOR_PASSWORD=wangpan-secret-key-2024 是解密配置文件中加密密码的密钥,必须传入,否则服务启动会报错。

5. 访问系统


配置说明

Jasypt 配置加密

所有敏感信息数据库密码、MinIO 密钥、TMDB API Key均使用 Jasypt 加密存储,格式为 ENC(加密后的密文)

所有服务统一配置

jasypt:
  encryptor:
    password: ${JASYPT_ENCRYPTOR_PASSWORD}          # 必须通过环境变量或 -D 参数传入
    algorithm: PBEWITHHMACSHA512ANDAES_256           # 统一使用强加密算法
    key-obtention-iterations: 1000
    pool-size: 1
    salt-generator-classname: org.jasypt.salt.RandomSaltGenerator
    iv-generator-classname: org.jasypt.iv.RandomIvGenerator
    string-output-type: base64

加密密钥wangpan-secret-key-2024

数据库连接

  • 地址118.178.238.159:33306
  • 数据库名wangpan
  • 连接参数useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true

MinIO 对象存储

  • 地址118.178.238.159:39000
  • 存储桶wangpan(网盘文件)、tmdbTMDB 缓存数据)

网关路由

路由路径 转发目标
/api/login, /api/register http://localhost:8081
/api/token/**, /api/login-logs/** http://localhost:8081
/api/users/** http://localhost:8081
/api/drive/** http://localhost:8082
/api/icon/** http://localhost:8082
/api/movies/** http://localhost:8083
/api/tmdb/**, /api/tmdb-scraper/** http://localhost:8083

所有路由 StripPrefix=0(不裁剪路径前缀)。


API 接口文档

完整 API 文档请访问:http://localhost:8888/api-doc.html

用户服务(端口 8081

方法 路径 说明 认证
POST /api/login 用户登录
POST /api/register 用户注册
GET /api/token/validate 验证 Token
GET /api/login-logs 查询登录日志 需Token
GET /api/users 查询用户列表 需Token
POST /api/users 创建用户 需Token
PUT /api/users/{userId} 更新用户 需Token
DELETE /api/users/{userId} 删除用户 需Token

网盘服务(端口 8082

方法 路径 说明 认证
POST /api/drive 创建网盘 需Token
GET /api/drive 查询网盘列表 需Token
GET /api/drive/{id} 查询网盘详情 需Token
PUT /api/drive/{id} 更新网盘 需Token
DELETE /api/drive/{id} 删除网盘 需Token
POST /api/drive/{driveId}/folders 创建文件夹 需Token
GET /api/drive/{driveId}/folders 查询文件夹列表 需Token
GET /api/drive/{driveId}/folders/{folderId} 查询文件夹详情 需Token
PUT /api/drive/{driveId}/folders/{folderId} 更新文件夹 需Token
DELETE /api/drive/{driveId}/folders/{folderId} 删除文件夹 需Token
POST /api/drive/{driveId}/movies 添加电影 需Token
GET /api/drive/{driveId}/folders/{folderId}/movies 查询电影列表 需Token
GET /api/drive/{driveId}/movies/{movieId} 查询电影详情 需Token
PUT /api/drive/{driveId}/movies/{movieId} 更新电影 需Token
DELETE /api/drive/{driveId}/movies/{movieId} 删除电影 需Token
GET /api/drive/movies/duplicates 检查重复电影 需Token
POST /api/icon 创建图标 需Token
GET /api/icon 查询图标列表 需Token
GET /api/icon/{id} 查询图标详情 需Token
PUT /api/icon/{id} 更新图标 需Token
DELETE /api/icon/{id} 删除图标 需Token
POST /api/icon/{id}/logo 上传图标 Logo 需Token

TMDB 服务(端口 8083

方法 路径 说明 认证
GET /api/movies 查询电影列表 需Token
GET /api/movies/recommend 推荐电影 需Token
GET /api/movies/{id} 查询电影详情 需Token
POST /api/movies 创建电影 需Token
PUT /api/movies/{id} 更新电影 需Token
DELETE /api/movies/{id} 删除电影 需Token
POST /api/movies/batch-delete 批量删除电影 需Token
GET /api/movies/stats 电影统计 需Token
GET /api/tmdb/key 查询 TMDB API Key 需Token
POST /api/tmdb/key 设置 TMDB API Key 需Token
POST /api/tmdb-scraper/scrape 单部电影刮削 需Token
POST /api/tmdb-scraper/batch-scrape 批量刮削 需Token
GET /api/tmdb-scraper/caches 查询刮削缓存 需Token
GET /api/tmdb-scraper/stats 刮削统计 需Token
POST /api/tmdb-scraper/trigger 手动触发定时任务 需Token
GET /api/tmdb-scraper/scraper-logs 查询刮削日志 需Token
DELETE /api/tmdb-scraper/cache/{movieId} 删除缓存 需Token

统一响应格式

{
  "code": 200,
  "message": "操作成功",
  "data": {}
}
状态码 含义
200 操作成功
400 参数错误
401 未登录 / Token 过期
403 权限不足
404 资源不存在
429 请求过于频繁
500 服务器内部错误

数据库设计

核心表结构

表名 所属模块 说明
wp_user user-service 用户表
wp_drive drive-service 网盘表
wp_drive_folder drive-service 文件夹表
wp_drive_movie drive-service 电影表(唯一电影数据表)
wp_tmdb_cache tmdb-service TMDB 刮削缓存表
wp_tmdb_scraper_log tmdb-service 刮削日志表
wp_tmdb_config tmdb-service TMDB API 配置表
wp_login_log user-service 登录日志表
wp_icon drive-service 图标表

表命名规范

  • 所有表以 wp_ 前缀开头
  • 表名使用小写 + 下划线分隔
  • 主键统一为 idBIGINT AUTO_INCREMENT
  • 状态字段使用字符串枚举值(如 active, deleted
  • 索引命名:idx_字段名

重要约定

wp_drive_movie 是项目中唯一的电影数据表所有模块drive-service、tmdb-service都操作同一张表。不存在 wp_movie 表(已废弃)。


项目规范

命名规范

包结构

com.wangpan
├── common/                         # 公共模块
│   ├── annotation/                 # 自定义注解(@RequireAuth, @RequireAdmin
│   ├── config/                     # 配置类
│   ├── dal/                        # 数据访问层
│   │   ├── dataobject/             # DO 数据对象
│   │   ├── mapper/                 # MyBatis Mapper 接口
│   │   └── repository/             # Repository 封装
│   ├── entity/                     # 业务实体
│   ├── interceptor/                # 拦截器
│   ├── listener/                   # 定时任务
│   └── util/                       # 工具类
├── controller/                     # 控制器(各子模块独立)
├── service/                        # 业务服务(各子模块独立)
└── Application.java                # 启动类(各子模块独立)

类命名

类型 规则 示例
DO {实体名}DO DriveMovieDO, UserDO
Mapper {实体名}Mapper DriveMovieMapper, UserMapper
Repository {实体名}Repository DriveMovieRepository
Entity {实体名} DriveMovie, User
Controller {模块名}Controller DriveController, AuthController
Service {模块名}Service DriveService, TmdbScraperService
工具类 {功能}Util TokenUtil, MinioUtil, EncryptUtil
配置类 {功能}Config WebMvcConfig, MyBatisPlusConfig
定时任务 {功能}Scheduler TmdbScheduler, IconCleanupScheduler

方法命名

操作 规则 示例
查询单个 findBy{条件} findById, findByMovieId
查询列表 queryBy{条件} queryByUserId, queryByDriveAndFolder
统计 countBy{条件} countByDrive, countByUser
插入 insert insert(DriveMovie movie)
更新 update / update{字段} update, updateScrapeInfo
逻辑删除 logicalDelete logicalDelete(Long id, Long userId)
物理删除 delete delete(Long id, Long userId)

编码规范

  1. Controller 直接返回 Result<T> 对象,不返回原始数据
  2. Repository 继承 ServiceImpl<Mapper, DO>,自动获得 CRUD 能力
  3. Mapper 继承 BaseMapper<DO>,简单 CRUD 自动生成
  4. 复杂 SQL 写在 Mapper XML 中,不写在 Java 代码中
  5. 数据库操作 使用 LambdaQueryWrapper / LambdaUpdateWrapper,不拼接 SQL 字符串
  6. 认证 使用 @RequireAuth@RequireAdmin 注解
  7. 当前用户 通过 request.getAttribute("currentUser") 获取

MyBatis XML 映射规则

列别名一致性XML 中 SELECT 的列别名必须与 Java 代码中 Map.get() 的 key 完全一致。

<!-- XML -->
SELECT title, COUNT(*) AS cnt FROM wp_drive_movie ...
// Java 中必须使用相同的 key
g.get("cnt")   // ✅ 正确
g.get("count") // ❌ 错误,别名是 cnt 不是 count

数值安全转换resultType="java.util.Map" 返回的数值,使用 ((Number) g.get("cnt")).intValue() 安全转换。

配置文件规范

  • 所有敏感信息使用 Jasypt ENC(...) 加密
  • 所有服务 Jasypt 加密算法统一为 PBEWITHHMACSHA512ANDAES_256
  • 日志级别生产环境设为 INFO
  • 不启用 MyBatis-Plus SQL 日志输出到控制台
  • Mapper XML 路径使用 classpath*: 前缀(跨模块加载)

部署指南

生产环境环境变量

# Linux / Mac
export JASYPT_ENCRYPTOR_PASSWORD=wangpan-secret-key-2024

# Windows PowerShell
$env:JASYPT_ENCRYPTOR_PASSWORD="wangpan-secret-key-2024"

Docker 部署

docker run -d \
  -e JASYPT_ENCRYPTOR_PASSWORD=wangpan-secret-key-2024 \
  -p 8081:8081 \
  wangpan-user-service:latest

systemd 服务Linux

[Unit]
Description=WangPan User Service

[Service]
Environment=JASYPT_ENCRYPTOR_PASSWORD=wangpan-secret-key-2024
ExecStart=/usr/bin/java -jar /opt/wangpan/wangpan-user-service.jar
Restart=on-failure

[Install]
WantedBy=multi-user.target

启动顺序

  1. MySQL、MinIO确保已启动
  2. wangpan-user-service(端口 8081
  3. wangpan-drive-service(端口 8082
  4. wangpan-tmdb-service(端口 8083
  5. wangpan-gateway(端口 8888

常见问题

Q1启动报错 Failed to bind properties under 'spring.datasource.password'

原因Jasypt 解密密钥未正确传入。

解决:使用 -DJASYPT_ENCRYPTOR_PASSWORD=wangpan-secret-key-2024 参数启动,不要用 $env:xxx 方式设置环境变量Windows 下 Start-Process 子进程不继承)。

Q2TMDB 刮削返回"没有需要刮削的电影"

原因wp_drive_movie 表中没有电影数据,或现有电影的 scrapeType 字段为 none

解决:先通过网盘服务上传电影文件,或通过 POST /api/movies 创建电影记录,确保 scrapeType 不为 none

Q3API 返回 401 未授权

原因Token 过期或未登录。

解决:先调用 POST /api/login 获取 Token在请求头中携带 Authorization: Bearer <token>

Q4如何修改数据库密码

  1. 修改原始密码后,使用 Jasypt 命令行工具重新加密
  2. 将加密后的密文替换 application.yml 中的 ENC(...)
  3. 重启服务

Q5网关路由不生效

原因:路由配置中 StripPrefix=0,且后端服务路径必须与网关路由完全匹配。

解决:检查 wangpan-gateway/application.yml 中的路由配置,确保转发目标正确。


项目参考文件


许可证

内部项目,仅供学习与个人使用。