pangu-user-platform/docs/02-系统设计/系统设计文档_v1.0.md

600 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 盘古用户平台 - 系统设计文档
---
| 文档信息 | 内容 |
|---------|------|
| **文档版本** | 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.3.x | 应用框架LTS版本 |
| | Spring Security | 6.x | 安全框架 |
| | MyBatis Plus | 3.5.x | ORM框架 |
| | JWT | 0.12.x | Token认证 |
| | Hutool | 5.x | 工具库 |
| | JDK | 17+ | 运行环境LTS |
| **数据库** | MySQL | 8.0 | 主数据库 |
| | Redis | 7.x | 缓存 |
| **中间件** | Nginx | 1.20+ | 反向代理 |
| | MinIO | - | 文件存储(可选)|
| **基础框架** | RuoYi-Vue | 3.8.x | 快速开发框架 |
### 1.3 模块划分
```
pangu-user-platform/
├── pangu-admin/ # 后台管理模块
├── pangu-api/ # 移动端API模块
├── pangu-open/ # 开放平台API模块
├── pangu-common/ # 公共模块
│ ├── pangu-common-core/ # 核心工具
│ ├── pangu-common-redis/ # Redis工具
│ └── pangu-common-security/# 安全工具
├── pangu-framework/ # 框架核心
├── pangu-system/ # 系统模块复用RuoYi
├── pangu-generator/ # 代码生成器
└── pangu-ui/ # 前端工程
```
---
## 2. 模块设计
### 2.1 认证模块
#### 2.1.1 后台用户认证
```
┌─────────────────────────────────────────────────────────────┐
│ 后台登录流程 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 用户 ──► 输入账号密码 ──► 输入验证码 ──► 登录请求 │
│ │ │
│ ▼ │
│ ┌─────────────────┐ │
│ │ 验证验证码 │ │
│ └────────┬────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ 验证账号密码 │ │
│ └────────┬────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ 检查账号状态 │ │
│ └────────┬────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ 生成JWT Token │ │
│ └────────┬────────┘ │
│ │ │
│ ┌────────▼────────┐ │
│ │ 缓存用户信息 │ │
│ └────────┬────────┘ │
│ ▼ │
│ 返回Token │
└─────────────────────────────────────────────────────────────┘
```
#### 2.1.2 会员端认证(三种方式)
**方式一:手机号 + 验证码登录**
```java
/**
* 验证码登录流程
* 1. 前端请求发送验证码
* 2. 后端生成6位验证码存入Redis5分钟有效
* 3. 调用短信服务发送验证码
* 4. 前端提交手机号+验证码
* 5. 后端验证验证码生成Token
*/
```
**方式二:手机号 + 密码登录**
```java
/**
* 密码登录流程
* 1. 前端提交手机号+密码
* 2. 后端查询会员信息
* 3. BCrypt验证密码
* 4. 检查账号状态
* 5. 生成Token返回
*/
```
**方式三:微信登录**
```java
/**
* 微信登录流程
* 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 数据权限控制
```java
/**
* 数据权限级别
* 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 核心服务
```java
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 核心服务
```java
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 接口授权控制
```java
/**
* 接口授权拦截器
* 检查应用是否有权限访问当前接口
*/
@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 统一响应格式
```json
{
"code": 200,
"msg": "操作成功",
"data": {
// 业务数据
}
}
```
### 3.3 错误码定义
| 错误码 | 说明 |
|-------|------|
| 200 | 成功 |
| 400 | 请求参数错误 |
| 401 | 未授权 |
| 403 | 禁止访问 |
| 404 | 资源不存在 |
| 500 | 服务器错误 |
### 3.4 分页参数
| 参数 | 类型 | 说明 |
|-----|------|------|
| pageNum | int | 页码从1开始 |
| pageSize | int | 每页条数默认10 |
### 3.5 分页响应
```json
{
"code": 200,
"msg": "查询成功",
"data": {
"total": 100,
"rows": [...]
}
}
```
---
## 4. 安全设计
### 4.1 密码安全
```java
/**
* 密码加密存储
* 使用BCrypt算法自动加盐
*/
String encodedPassword = BCrypt.hashpw(rawPassword, BCrypt.gensalt());
/**
* 密码验证
*/
boolean matches = BCrypt.checkpw(rawPassword, encodedPassword);
```
### 4.2 防重放攻击
```java
/**
* 请求时间戳验证
* 请求时间与服务器时间相差不超过5分钟
*/
long timestamp = Long.parseLong(request.getHeader("X-Timestamp"));
if (Math.abs(System.currentTimeMillis() - timestamp) > 5 * 60 * 1000) {
throw new ApiException("请求已过期");
}
```
### 4.3 敏感数据脱敏
```java
/**
* 手机号脱敏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 │
└──────────┘ └──────────┘ └──────────┘
```
---
*文档结束*