11 KiB
11 KiB
架构文档
本文档用于描述 yoyuzh.xyz 当前的系统结构、模块边界、关键流程和部署方式,便于后续窗口快速建立整体上下文。
1. 系统概览
项目是一个前后端分离的全栈站点,核心由三部分组成:
- React 前端站点
- Spring Boot 后端 API
- 文件存储层(本地文件系统或 S3 兼容对象存储)
业务主线已经从旧教务方向切换为:
- 账号系统
- 个人网盘
- 快传
- 管理台
2. 仓库结构与职责
2.1 前端
路径:
front/
核心职责:
- 页面路由与交互
- 登录态管理
- 网盘 UI 与缓存
- 快传发/收流程
- 管理台前端
- 生产环境 API 基址拼装与调用
关键入口:
front/src/App.tsxfront/src/lib/api.tsfront/src/components/layout/Layout.tsx
主要页面:
front/src/pages/Login.tsxfront/src/pages/Overview.tsxfront/src/pages/Files.tsxfront/src/pages/Transfer.tsxfront/src/pages/TransferReceive.tsxfront/src/pages/FileShare.tsx
2.2 后端
路径:
backend/
核心职责:
- 认证与 JWT 鉴权
- 网盘元数据与文件流转
- 快传信令与会话状态
- 管理台 API
- S3 兼容对象存储 / 本地存储抽象
后端包结构:
com.yoyuzh.authcom.yoyuzh.filescom.yoyuzh.transfercom.yoyuzh.admincom.yoyuzh.configcom.yoyuzh.common
启动类:
backend/src/main/java/com/yoyuzh/PortalBackendApplication.java
2.3 文档与脚本
docs/: 实现计划与补充文档scripts/: 前端静态站发布、对象存储迁移和本地辅助脚本
3. 模块划分
3.1 认证模块
核心文件:
backend/src/main/java/com/yoyuzh/auth/AuthController.javabackend/src/main/java/com/yoyuzh/auth/AuthService.javabackend/src/main/java/com/yoyuzh/auth/JwtTokenProvider.javabackend/src/main/java/com/yoyuzh/config/JwtAuthenticationFilter.javabackend/src/main/java/com/yoyuzh/auth/RefreshTokenService.java
职责:
- 注册、登录、刷新登录态
- 用户资料查询和修改
- 用户自行修改密码
- 头像上传
- 单设备登录控制
- 邀请码消费与轮换
关键实现说明:
- access token 使用 JWT
- refresh token 持久化到数据库
- 当前会话通过
activeSessionId + JWT sid claim绑定 - 新登录会挤掉旧设备
- 当前密码策略统一为“至少 8 位且包含大写字母”
3.2 网盘模块
核心文件:
backend/src/main/java/com/yoyuzh/files/FileController.javabackend/src/main/java/com/yoyuzh/files/FileService.javabackend/src/main/java/com/yoyuzh/files/storage/*front/src/pages/Files.tsx
职责:
- 文件/文件夹上传、下载、删除、重命名
- 目录创建与分页列表
- 移动、复制
- 分享链接与导入
- 前端树状目录导航
关键实现说明:
- 文件元数据在数据库
- 文件内容走存储层抽象
- 支持本地磁盘和 S3 兼容对象存储
- 当前线上网盘文件存储已切到多吉云对象存储,后端先通过多吉云临时密钥 API 换取短期 S3 会话,再访问底层 COS 兼容桶
- 前端会缓存目录列表和最后访问路径
3.3 快传模块
核心文件:
backend/src/main/java/com/yoyuzh/transfer/TransferController.javabackend/src/main/java/com/yoyuzh/transfer/TransferService.javabackend/src/main/java/com/yoyuzh/transfer/TransferSession.javafront/src/pages/Transfer.tsxfront/src/pages/TransferReceive.tsxfront/src/lib/transfer-runtime.tsfront/src/lib/transfer-protocol.ts
职责:
- 创建快传会话
- 生成取件码与分享链接
- WebRTC 信令交换
- 浏览器端文件发送与接收
- 接收后下载或存入网盘
关键实现说明:
- 后端只做信令和会话状态,不中转文件内容
- 文件内容走浏览器 DataChannel
- 接收端支持部分文件选择
- 多文件或文件夹可走 ZIP 下载
- 在线快传是一次性浏览器 P2P 传输,首个接收者进入后即占用该会话
- 离线快传会把文件内容落到站点存储,线上环境使用多吉云对象存储,默认保留 7 天并支持重复接收
- 登录页提供直达快传入口;匿名用户只允许创建在线快传并接收在线快传,离线快传相关操作仍要求登录
- 已登录发送端可在快传页查看自己未过期的离线快传记录,并重新打开取件码 / 二维码 / 分享链接详情弹层
3.4 管理台模块
核心文件:
backend/src/main/java/com/yoyuzh/admin/AdminController.javabackend/src/main/java/com/yoyuzh/admin/AdminService.javafront/src/admin/*
职责:
- 管理用户
- 管理文件
- 查看邀请码
- 展示总存储量、下载流量、今日请求次数、快传使用量、离线快传占用和请求折线图
- 调整离线快传总上限
关键实现说明:
- 管理台依赖后端 summary/users/files 接口
- 当前邀请码由后端返回给管理台展示
- 用户列表会展示每个用户的已用空间 / 配额
- 管理员修改用户密码后,旧密码应立即失效,新密码可直接重新登录
4. 关键业务流程
4.1 登录流程
- 前端登录页调用
/api/auth/login - 后端鉴权成功后签发 access token + refresh token
- 后端刷新
activeSessionId - 前端本地存储
portal-session - 后续请求通过
Authorization: Bearer <token>访问 - JWT 过滤器校验 token、用户状态和会话 ID 是否仍匹配
补充说明:
- 前端生产构建当前仍会把 API 基址固化为
https://api.yoyuzh.xyz/api - 因此前端登录、刷新、受保护接口访问都依赖
api.yoyuzh.xyz这条独立 API 子域名链路 - 若该子域名在某些网络环境下 TLS/SNI 不稳定,前端会直接表现为“网络异常”或“登录失败”
4.2 邀请码注册流程
- 用户提交注册信息与邀请码
- 后端验证用户名、邮箱、手机号唯一性
- 邀请码服务校验当前邀请码
- 注册成功后自动轮换邀请码
- 返回登录态
4.3 网盘上传流程
- 前端在
Files页面选择文件或文件夹 - 前端优先调用
/api/files/upload/initiate - 如果存储支持直传,则浏览器直接上传到对象存储
- 前端再调用
/api/files/upload/complete - 如果直传失败,会回退到代理上传接口
/api/files/upload
4.4 文件分享流程
- 登录用户创建分享链接
- 后端生成 token
- 公开用户通过
/share/:token查看详情 - 登录用户可以导入到自己的网盘
4.5 快传流程
- 发送端可在登录后或未登录状态下创建在线快传会话
- 若是在线模式,后端返回
sessionId + pickupCode并保留 15 分钟的一次性会话 - 接收端通过取件码或分享链接加入在线会话
- 双方通过
/api/transfer/.../signals交换 offer / answer / ice - DataChannel 建立后传输文件内容
- 接收端可直接下载或存入网盘
4.6 离线快传流程
- 发送端登录后创建离线快传会话
- 后端生成
sessionId + pickupCode,并为每个文件创建离线存储槽位 - 发送端把文件上传到站点存储
- 上传完成后,会话变为可接收状态并保留 7 天
- 接收端通过取件码或分享链接打开会话
- 接收端可直接下载离线文件,也可登录后存入网盘
- 文件在有效期内不会因一次接收而被删除,过期后由后端清理任务自动销毁
补充说明:
- 离线快传的创建、查找、加入和下载都要求登录
- 匿名用户进入
/transfer时默认落在发送页,但仅会看到在线模式 - 登录用户可通过
/api/transfer/sessions/offline/mine拉取自己仍在有效期内的离线快传会话,用于在快传页回看历史取件信息
4.7 管理员改密流程
- 管理台调用
PUT /api/admin/users/{userId}/password - 后端按统一密码规则校验新密码
- 后端重算密码哈希并写回用户表
- 后端刷新
activeSessionId并撤销该用户全部 refresh token - 旧密码后续登录应失败,新密码登录成功
5. 前端路由架构
路由入口:
front/src/App.tsx
主要路由:
/login/overview/files/transfer/share/:token/admin/*
说明:
/transfer同时承担发送端和接收端入口/share/:token是公开文件分享页/admin/*为懒加载管理台
6. 安全模型
6.1 访问控制
由 SecurityConfig 控制:
/api/auth/**公开/api/transfer/**公开GET /api/files/share-links/{token}公开/api/files/**、/api/user/**、/api/admin/**需登录
6.2 单设备登录
当前实现不是只撤销 refresh token,而是同时控制 access token:
- 用户表记录
activeSessionId - JWT 里包含
sid - 过滤器每次请求都会比对当前用户的
activeSessionId - 新登录成功后,旧设备 token 会失效
7. 存储架构
抽象层:
backend/src/main/java/com/yoyuzh/files/storage/FileContentStorage.java
实现方向:
- 本地文件系统
- S3 兼容对象存储
设计目的:
- 让文件元数据逻辑与底层存储解耦
- 上传、下载、复制、移动都通过统一抽象收口
当前线上状态:
- 生产环境文件桶已切到多吉云对象存储
- 后端通过多吉云临时密钥 API 获取短期
accessKeyId / secretAccessKey / sessionToken - 实际对象访问走 S3 兼容协议,底层 endpoint 为 COS 兼容地址
- 普通文件下载仍采用“后端鉴权后返回签名 URL,浏览器直连对象存储下载”的主链路
8. 部署架构
8.1 前端
- 构建工具:Vite
- 发布方式:对象存储静态站发布
- 发布脚本:
node scripts/deploy-front-oss.mjs
8.2 后端
- 打包方式:
mvn package - 产物:
backend/target/yoyuzh-portal-backend-0.0.1-SNAPSHOT.jar - 线上通常采用 jar + systemd 方式运行
当前已知线上信息:
- 服务名:
my-site-api.service - 运行包路径:
/opt/yoyuzh/yoyuzh-portal-backend.jar - 额外配置文件:
/opt/yoyuzh/application-prod.yml - 环境变量文件:
/opt/yoyuzh/app.env - 2026-04-02 已重新部署,服务状态为
active (running)
9. 开发注意事项
- 仓库根目录没有
package.json,不要在根目录执行npm - 前端命令只从
front/package.json读取 - 后端命令只从
backend/pom.xml读取 - 前端
npm run lint实际是tsc --noEmit - 后端没有单独 lint 命令
- 本仓库大量使用 Lombok,VS Code 若出现“final 字段未初始化”之类误报,优先检查 Lombok 扩展、Java Language Server 和 annotation processor
10. 新窗口建议阅读顺序
后续新窗口进入仓库时,建议顺序:
memory.mddocs/architecture.mddocs/api-reference.mdAGENTS.md
如果要继续某个具体功能,再进入对应模块的:
- 前端页面文件
- 后端 Controller / Service
- 紧邻测试文件