23 KiB
23 KiB
盘古用户平台 - 系统设计文档
| 文档信息 | 内容 |
|---|---|
| 文档版本 | V1.0 |
| 项目名称 | 盘古用户平台(Pangu User Platform) |
| 编写团队 | pangu |
| 创建日期 | 2026-01-31 |
1. 系统架构设计
1.1 整体架构
┌─────────────────────────────────────────────────────────────────────────┐
│ 客户端层 │
├─────────────────┬─────────────────┬─────────────────┬───────────────────┤
│ 管理后台 │ 小程序 │ H5 │ 第三方应用 │
│ (Vue 3) │ (微信小程序) │ (Vue/H5) │ (API调用) │
└────────┬────────┴────────┬────────┴────────┬────────┴────────┬──────────┘
│ │ │ │
▼ ▼ ▼ ▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 网关层 (Nginx) │
│ - 负载均衡 - SSL终结 - 静态资源 │
└─────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────┐
│ 应用服务层 (Spring Boot) │
├─────────────────────────────────────────────────────────────────────────┤
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌─────────────┐ │
│ │ 认证模块 │ │ 用户模块 │ │ 学校模块 │ │ 应用模块 │ │
│ │ - JWT认证 │ │ - 会员管理 │ │ - 学校管理 │ │ - 应用管理 │ │
│ │ - 权限控制 │ │ - 学生管理 │ │ - 年级班级 │ │ - 接口授权 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └─────────────┘ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ 基础模块 │ │ 系统模块 │ │ 开放API │ │
│ │ - 区域管理 │ │ - 用户管理 │ │ - 对外接口 │ │
│ │ - 学科管理 │ │ - 角色权限 │ │ - 签名验证 │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ │
└─────────────────────────────────────────────────────────────────────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ MySQL │ │ Redis │ │ MinIO │
│ 主数据库 │ │ 缓存/会话 │ │ 文件存储 │
└─────────────┘ └─────────────┘ └─────────────┘
1.2 技术选型
| 层次 | 技术 | 版本 | 说明 |
|---|---|---|---|
| 前端 | Vue | 3.x | 管理后台框架 |
| Element Plus | 2.x | UI组件库 | |
| Axios | 1.x | HTTP客户端 | |
| Pinia | 2.x | 状态管理 | |
| 后端 | Spring Boot | 3.5.x | 应用框架 |
| Sa-Token | 1.44.x | 认证与权限 | |
| MyBatis Plus | 3.5.x | ORM框架 | |
| Hutool | 5.x | 工具库 | |
| JDK | 17+ | 运行环境(LTS) | |
| 数据库 | MySQL | 8.0 | 主数据库 |
| Redis | 7.x | 缓存 | |
| 中间件 | Nginx | 1.20+ | 反向代理 |
| MinIO | - | 文件存储(可选) | |
| 基础框架 | RuoYi-Vue-Plus | 5.5.x | 多租户快速开发框架(Dromara) |
1.3 模块划分
pangu-user-platform/
├── backend/
│ ├── pangu-admin/ # 启动与认证入口(Spring Boot 主模块)
│ ├── pangu-common/ # 公共模块
│ │ ├── pangu-common-core/ # 核心工具、常量、异常
│ │ ├── pangu-common-redis/ # Redis/Redisson
│ │ ├── pangu-common-security/# 安全与加解密
│ │ ├── pangu-common-satoken/ # Sa-Token 认证
│ │ ├── pangu-common-mybatis/# MyBatis Plus 扩展
│ │ ├── pangu-common-web/ # Web 配置与工具
│ │ └── 其他 common 子模块 # 日志、OSS、短信、租户等
│ ├── pangu-modules/
│ │ ├── pangu-system/ # 系统模块(用户、角色、菜单、部门、字典、监控等)
│ │ ├── pangu-business/ # 业务模块(学校、会员、学生、应用、基础数据、H5、开放API)
│ │ ├── pangu-generator/ # 代码生成器
│ │ ├── pangu-job/ # 定时任务(SnailJob)
│ │ ├── pangu-demo/ # 示例模块
│ │ └── pangu-workflow/ # 工作流(可选)
│ ├── pangu-extend/ # 扩展(Monitor Admin、SnailJob Server 等)
│ └── pom.xml # 后端父 POM(RuoYi-Vue-Plus 5.5.x)
└── frontend/ # 管理后台前端(Vue 3 + Element Plus + Vite)
2. 模块设计
2.1 认证模块
2.1.1 后台用户认证
┌─────────────────────────────────────────────────────────────┐
│ 后台登录流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 用户 ──► 输入账号密码 ──► 输入验证码 ──► 登录请求 │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 验证验证码 │ │
│ └────────┬────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ 验证账号密码 │ │
│ └────────┬────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ 检查账号状态 │ │
│ └────────┬────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ 生成JWT Token │ │
│ └────────┬────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ 缓存用户信息 │ │
│ └────────┬────────┘ │
│ ▼ │
│ 返回Token │
└─────────────────────────────────────────────────────────────┘
2.1.2 会员端认证(三种方式)
方式一:手机号 + 验证码登录
/**
* 验证码登录流程
* 1. 前端请求发送验证码
* 2. 后端生成6位验证码,存入Redis(5分钟有效)
* 3. 调用短信服务发送验证码
* 4. 前端提交手机号+验证码
* 5. 后端验证验证码,生成Token
*/
方式二:手机号 + 密码登录
/**
* 密码登录流程
* 1. 前端提交手机号+密码
* 2. 后端查询会员信息
* 3. BCrypt验证密码
* 4. 检查账号状态
* 5. 生成Token返回
*/
方式三:微信登录
/**
* 微信登录流程
* 1. 前端调用wx.login获取code
* 2. 前端提交code到后端
* 3. 后端调用微信接口换取openId
* 4. 根据openId查询会员
* 5. 已注册:直接生成Token
* 6. 未注册:创建新会员,生成Token
*/
2.1.3 Token设计
| 字段 | 说明 |
|---|---|
| sub | 用户ID |
| type | 用户类型(admin/member) |
| exp | 过期时间 |
| iat | 签发时间 |
Token配置:
- 后台用户Token有效期:30分钟(可续期)
- 会员Token有效期:7天
- Token存储位置:Redis
2.2 权限控制设计
2.2.1 RBAC权限模型
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 用户 │────▶│ 角色 │────▶│ 权限 │
└─────────┘ └─────────┘ └─────────┘
│ │ │
│ │ │
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ 部门 │ │ 角色菜单 │ │ 菜单 │
└─────────┘ └─────────┘ └─────────┘
2.2.2 数据权限控制
/**
* 数据权限级别
* 1. 全部数据权限 - 超级管理员
* 2. 部门数据权限 - 分公司用户(只能看本区域数据)
* 3. 本人数据权限 - 学校用户(只能看本校数据)
*/
@DataScope(deptAlias = "d", userAlias = "u")
public List<School> selectSchoolList(School school) {
// 自动拼接数据权限SQL
}
2.3 学校模块设计
2.3.1 数据结构
区域(Region)
└── 学校(School)
└── 年级关联(SchoolGrade)
└── 班级关联(SchoolClass)
2.3.2 核心服务
public interface ISchoolService {
/**
* 查询学校列表(树形结构)
*/
List<SchoolTreeVO> selectSchoolTree(Long regionId);
/**
* 新增学校
*/
int insertSchool(School school);
/**
* 编辑学校
*/
int updateSchool(School school);
/**
* 删除学校(检查关联)
*/
int deleteSchool(Long schoolId);
/**
* 为学校挂载年级
*/
int bindGrades(Long schoolId, List<Long> gradeIds);
/**
* 为年级挂载班级
*/
int bindClasses(Long schoolGradeId, List<Long> classIds);
}
2.4 会员模块设计
2.4.1 会员与学生关系
┌─────────────┐ ┌─────────────┐
│ 会员 │ 1 n │ 学生 │
│ (Member) │◀─────────▶│ (Student) │
└─────────────┘ └─────────────┘
│
│ 身份类型
▼
┌─────────────────────────────────────────┐
│ 家长:可绑定任意学校的学生 │
│ 教师:只能绑定本校学生 │
└─────────────────────────────────────────┘
2.4.2 核心服务
public interface IMemberService {
/**
* 会员登录(验证码)
*/
LoginVO loginBySms(String phone, String code);
/**
* 会员登录(密码)
*/
LoginVO loginByPassword(String phone, String password);
/**
* 会员登录(微信)
*/
LoginVO loginByWechat(String code);
/**
* 重置密码
*/
String resetPassword(Long memberId);
/**
* 绑定学生
*/
int bindStudent(Long memberId, Long studentId);
/**
* 解绑学生
*/
int unbindStudent(Long memberId, Long studentId);
}
2.5 应用模块设计
2.5.1 应用认证流程
┌────────────────────────────────────────────────────────────────┐
│ 第三方应用调用API流程 │
├────────────────────────────────────────────────────────────────┤
│ │
│ 第三方应用 ──► 生成签名 ──► 发起请求 ──► 网关验证 ──► 业务处理 │
│ │
│ 签名规则: │
│ 1. 参数按ASCII排序 │
│ 2. 拼接成 key1=value1&key2=value2 格式 │
│ 3. 末尾追加 &appSecret=xxx │
│ 4. MD5加密得到sign │
│ │
│ 请求头: │
│ - X-App-Id: 应用编码 │
│ - X-Timestamp: 时间戳 │
│ - X-Sign: 签名 │
│ │
└────────────────────────────────────────────────────────────────┘
2.5.2 接口授权控制
/**
* 接口授权拦截器
* 检查应用是否有权限访问当前接口
*/
@Component
public class ApiAuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response,
Object handler) {
String appId = request.getHeader("X-App-Id");
String uri = request.getRequestURI();
// 1. 验证签名
if (!verifySign(request)) {
throw new ApiException("签名验证失败");
}
// 2. 检查应用状态
Application app = applicationService.getByAppId(appId);
if (app == null || !app.isEnabled()) {
throw new ApiException("应用不存在或已禁用");
}
// 3. 检查接口授权
if (!app.hasPermission(uri)) {
throw new ApiException("无权访问该接口");
}
return true;
}
}
3. 接口设计规范
3.1 RESTful API规范
| HTTP方法 | 用途 | 示例 |
|---|---|---|
| GET | 查询资源 | GET /api/schools |
| POST | 创建资源 | POST /api/schools |
| PUT | 更新资源 | PUT /api/schools/{id} |
| DELETE | 删除资源 | DELETE /api/schools/{id} |
3.2 统一响应格式
{
"code": 200,
"msg": "操作成功",
"data": {
// 业务数据
}
}
3.3 错误码定义
| 错误码 | 说明 |
|---|---|
| 200 | 成功 |
| 400 | 请求参数错误 |
| 401 | 未授权 |
| 403 | 禁止访问 |
| 404 | 资源不存在 |
| 500 | 服务器错误 |
3.4 分页参数
| 参数 | 类型 | 说明 |
|---|---|---|
| pageNum | int | 页码,从1开始 |
| pageSize | int | 每页条数,默认10 |
3.5 分页响应
{
"code": 200,
"msg": "查询成功",
"data": {
"total": 100,
"rows": [...]
}
}
4. 安全设计
4.1 密码安全
/**
* 密码加密存储
* 使用BCrypt算法,自动加盐
*/
String encodedPassword = BCrypt.hashpw(rawPassword, BCrypt.gensalt());
/**
* 密码验证
*/
boolean matches = BCrypt.checkpw(rawPassword, encodedPassword);
4.2 防重放攻击
/**
* 请求时间戳验证
* 请求时间与服务器时间相差不超过5分钟
*/
long timestamp = Long.parseLong(request.getHeader("X-Timestamp"));
if (Math.abs(System.currentTimeMillis() - timestamp) > 5 * 60 * 1000) {
throw new ApiException("请求已过期");
}
4.3 敏感数据脱敏
/**
* 手机号脱敏:138****1234
*/
public static String maskPhone(String phone) {
return phone.replaceAll("(\\d{3})\\d{4}(\\d{4})", "$1****$2");
}
4.4 SQL注入防护
- 使用MyBatis参数化查询
- 禁止拼接SQL语句
- 使用白名单校验排序字段
4.5 XSS防护
- 输入数据HTML转义
- 使用Content-Security-Policy头
- 设置HttpOnly Cookie
5. 缓存设计
5.1 缓存策略
| 缓存KEY | 过期时间 | 说明 |
|---|---|---|
| login_tokens:{token} | 30min/7day | 登录Token |
| captcha:{uuid} | 5min | 图形验证码 |
| sms_code:{phone} | 5min | 短信验证码 |
| user_info:{userId} | 30min | 用户信息 |
| dict_data:{dictType} | 永久 | 字典数据 |
| region_tree | 24h | 区域树 |
5.2 缓存更新策略
- 登录Token:登录时创建,退出时删除
- 用户信息:修改时删除,下次查询时重建
- 字典数据:修改时手动刷新
- 区域树:修改时手动刷新
6. 日志设计
6.1 日志级别
| 级别 | 使用场景 |
|---|---|
| ERROR | 系统异常、业务错误 |
| WARN | 警告信息、潜在问题 |
| INFO | 业务关键操作 |
| DEBUG | 调试信息(仅开发环境) |
6.2 操作日志
记录以下操作:
- 用户登录/登出
- 数据新增/修改/删除
- 密码重置
- 应用密钥重置
日志字段:
- 操作人
- 操作时间
- 操作模块
- 操作类型
- 操作描述
- 请求参数
- 响应结果
- IP地址
7. 部署架构
7.1 单机部署
┌─────────────────────────────────────────┐
│ 服务器 (8C16G) │
├─────────────────────────────────────────┤
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ Nginx │ │ 后端 │ │ 前端 │ │
│ │ :80 │ │ :8080 │ │ 静态 │ │
│ └─────────┘ └─────────┘ └─────────┘ │
│ │
│ ┌─────────┐ ┌─────────┐ │
│ │ MySQL │ │ Redis │ │
│ │ :3306 │ │ :6379 │ │
│ └─────────┘ └─────────┘ │
└─────────────────────────────────────────┘
7.2 集群部署(预留)
┌─────────┐
│ SLB │
└────┬────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Nginx1 │ │ Nginx2 │ │ Nginx3 │
└────┬─────┘ └────┬─────┘ └────┬─────┘
│ │ │
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ App1 │ │ App2 │ │ App3 │
└──────────┘ └──────────┘ └──────────┘
│
┌───────────────┼───────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ MySQL主 │ │ MySQL从 │ │ Redis │
└──────────┘ └──────────┘ └──────────┘
文档结束