15 KiB
15 KiB
产品整体架构文档 — 道路救援企业培训系统
版本:V1.0 生成日期:2026-04-07 证据状态:✅ 已验证 证据来源:[SRC-FEAT-01] [SRC-SQL-01] [SRC-API-01] [SRC-CODE-01]
1. 产品定位
1.1 产品目标
为道路救援企业提供一站式内部培训管理平台,通过数字化方式替代口口相传的知识传承模式,实现知识沉淀、在线考核、培训过程管控三位一体。[SRC-FEAT-01]
1.2 核心价值
| 价值维度 | 解决的痛点 | 实现方式 |
|---|---|---|
| 知识沉淀 | 知识依赖口口相传,无法沉淀 | 结构化知识库(文档+视频) |
| 高效考核 | 出题组卷效率低,纸质考试成本高 | 在线题库 + 自动/手动组卷 + 在线考试 |
| 培训管控 | 培训效果难追踪,进度不透明 | 培训计划+进度跟踪+成绩统计 |
| 标准化输出 | 服务标准参差不齐 | 统一平台 + 及格线控制 + 必考机制 |
1.3 目标用户
| 角色 | 人数 | 核心诉求 |
|---|---|---|
| 管理员 | 3-5人 | 系统配置、人员管理、全平台数据可见 |
| 讲师(技师) | 30-50人 | 本部门知识上传、出题、发布考试、管理培训计划 |
| 学员 | ~450人 | 学习资料、参加考试、查看进度 |
[SRC-FEAT-01:二、用户画像]
1.4 使用场景
- 管理员场景:系统初始化时维护组织架构;日常监控各部门培训完成情况。
- 讲师场景:救援规范更新后,上传新手册并更新题库,发布新考试,关联到培训计划。
- 学员场景:PC端浏览知识库预习、参加指定考试、查看自己的培训进度。
- 企业微信场景:学员通过企业微信 H5 入口完成移动端学习和考试。
2. 系统整体架构
2.1 架构分层
| 层次 | 组件 | 职责 |
|---|---|---|
| 表现层 | PC浏览器(管理员/讲师)、企业微信H5(学员)、移动端浏览器 | 用户交互,HTML+CSS+JS 原生技术栈 |
| 网关层 | Spring Boot 应用(JWT认证、权限拦截、日志、异常处理) | 请求入口,统一认证鉴权,全局异常处理 |
| 业务层 | 5个业务模块(auth / system / knowledge / exam / training) | 核心业务逻辑,按模块边界划分,禁止跨模块直接调用数据层 |
| 数据层 | MySQL 8.0(MyBatis Plus ORM)+ 文件存储(本地/MinIO/OSS) | 持久化业务数据和媒体文件 |
[SRC-FEAT-01:七、架构设计蓝图]
2.2 技术架构概览
| 技术选型 | 版本 | 用途 |
|---|---|---|
| Spring Boot | 3.1.2 | 主框架 |
| MyBatis Plus | 3.5.3+ | ORM,简化CRUD |
| MySQL | 8.0 | 主数据库 |
| java-jwt | 4.4+ | JWT Token 签发与验证 |
| Spring Security | 6.x | BCrypt 密码加密 |
| weixin-java-cp | - | 企业微信 SDK(OAuth 登录) |
| Springdoc OpenAPI | 2.2+ | API 文档 |
| Spring @Scheduled | - | 考试超时自动交卷定时任务 |
| 文件存储 | - | V1 本地存储,V2 可扩展 MinIO/OSS |
[SRC-FEAT-01:7.3 技术选型]
2.3 系统依赖关系
外部系统依赖:
企业微信API ←→ auth 模块(OAuth 换 userid)
文件存储服务 ←→ knowledge 模块(上传/下载文件)
文档预览服务(可选) ←→ knowledge 模块(在线预览)
内部模块依赖方向(单向,禁止逆向调用):
training → knowledge(引用知识内容、学习进度)
training → exam(引用考试通过状态)
knowledge / exam / training → system(查询用户/部门信息)
所有模块 → auth(权限校验拦截器)
3. 业务架构图
graph TD
subgraph 客户端
PC[PC浏览器<br>管理员/讲师]
WX[企业微信H5<br>学员]
MB[移动端浏览器<br>学员]
end
subgraph 后端服务
subgraph 网关层
GW[JWT认证 / 权限拦截 / 异常处理]
end
subgraph 业务域
AUTH[认证模块<br>auth]
SYS[系统管理<br>system]
KM[知识库模块<br>knowledge]
EX[考试模块<br>exam]
TR[培训模块<br>training]
end
end
subgraph 数据层
DB[(MySQL 8.0)]
FS[文件存储<br>本地/MinIO]
end
subgraph 外部服务
WXAPI[企业微信API]
PREVIEW[文档预览服务<br>可选]
end
PC --> GW
WX --> GW
MB --> GW
GW --> AUTH
GW --> SYS
GW --> KM
GW --> EX
GW --> TR
AUTH --> WXAPI
KM --> FS
KM --> PREVIEW
TR --> KM
TR --> EX
KM --> SYS
EX --> SYS
TR --> SYS
AUTH --> DB
SYS --> DB
KM --> DB
EX --> DB
TR --> DB
4. 核心业务流程说明
4.1 用户主流程(学员)
sequenceDiagram
participant 学员
participant 前端
participant 后端
participant 企业微信
学员->>前端: 点击企业微信登录
前端->>企业微信: 跳转 OAuth 授权
企业微信-->>前端: 返回 code
前端->>后端: code 换 Token
后端->>企业微信: code → userid
后端->>后端: 查 sys_user 匹配
alt 用户已录入
后端-->>前端: JWT Token + 用户信息
前端->>学员: 进入工作台
else 用户未录入
后端-->>前端: 错误:联系管理员
end
学员->>前端: 查看培训计划
前端->>后端: GET /api/student/training
后端-->>前端: 计划列表 + 进度
学员->>前端: 参加考试
前端->>后端: POST /api/student/exam/{id}/start
后端->>后端: 校验时间窗口 + 剩余次数
后端-->>前端: 试题 + 考试时长
学员->>前端: 答题 + 交卷
前端->>后端: POST /api/student/exam/{id}/submit
后端->>后端: 自动判分
后端-->>前端: 成绩 + 排名 + 答案解析
4.2 管理流程(讲师)
flowchart LR
A[上传知识<br>DRAFT] --> B[发布知识<br>PUBLISHED]
B --> C{有培训计划?}
C -->|是| D[关联到培训计划]
C -->|否| E[学员自由学习]
F[创建题目<br>DRAFT] --> G[发布题目<br>PUBLISHED]
G --> H[组卷<br>手动/自动]
H --> I[发布试卷<br>PUBLISHED]
I --> J[创建考试<br>设置时间/次数]
J --> K[指定考试对象<br>部门/小组/个人]
D --> L[创建培训计划]
J --> L
L --> M[分配学员<br>部门/小组/个人]
M --> N[发布培训计划]
4.3 数据流转流程
flowchart TB
subgraph 内容生产
KM_CREATE[知识创建<br>km_knowledge DRAFT]
KM_PUBLISH[发布知识<br>PUBLISHED]
QS_CREATE[题目创建<br>ex_question DRAFT]
QS_PUBLISH[发布题目<br>PUBLISHED]
PP_CREATE[组卷<br>ex_paper + ex_paper_question]
EX_CREATE[创建考试<br>ex_exam + ex_exam_target]
TR_CREATE[培训计划<br>tr_plan + tr_plan_knowledge<br>+ tr_plan_exam + tr_plan_target]
end
subgraph 学员消费
LEARN[学习知识<br>→ km_knowledge_progress UPSERT]
EXAM[参加考试<br>→ ex_exam_record 创建/更新]
PROGRESS[进度计算<br>必修知识完成数 + 必考通过数]
end
KM_CREATE --> KM_PUBLISH --> LEARN
QS_CREATE --> QS_PUBLISH --> PP_CREATE --> EX_CREATE --> EXAM
TR_CREATE --> LEARN
TR_CREATE --> EXAM
LEARN --> PROGRESS
EXAM --> PROGRESS
5. 数据架构
5.1 核心数据实体(共19张表)
[SRC-SQL-01] [SRC-SQL-02]
| 数据域 | 表名 | 核心字段 | 说明 |
|---|---|---|---|
| 系统 | sys_center | id, name | 中心(最高层级) |
| 系统 | sys_department | id, name, center_id | 部门(隶属中心) |
| 系统 | sys_group | id, name, department_id | 小组(隶属部门) |
| 系统 | sys_user | id, wx_userid, role(0/1/2), department_id, group_id, status | 用户(ADMIN/LECTURER/STUDENT) |
| 知识库 | km_category | id, name, parent_id, department_id | 知识分类(多级树) |
| 知识库 | km_knowledge | id, title, type(0文档/1视频), file_url, department_id, status(0/1/2) | 知识内容 |
| 知识库 | km_knowledge_progress | id, user_id, knowledge_id, status, progress, duration, video_position, source, plan_id | 学习进度 |
| 考试 | ex_question_category | id, name, parent_id, department_id | 题目分类 |
| 考试 | ex_question | id, type(0/1/2), content, options(JSON), answer, analysis, status | 题目 |
| 考试 | ex_paper | id, title, total_score, duration, pass_score, status | 试卷 |
| 考试 | ex_paper_question | paper_id, question_id, score, sort_order | 试卷-题目关联 |
| 考试 | ex_exam | id, title, paper_id, start_time, end_time, max_attempts, status(0/1/2) | 考试 |
| 考试 | ex_exam_target | exam_id, target_type(0部门/1小组/2个人), target_id | 考试对象 |
| 考试 | ex_exam_record | id, exam_id, user_id, attempt_no, score, passed, answers(JSON), status, version | 考试记录(含乐观锁) |
| 培训 | tr_plan | id, title, start_date, end_date, department_id, status(0/1/2) | 培训计划 |
| 培训 | tr_plan_knowledge | plan_id, knowledge_id, required, sort_order | 计划-知识关联 |
| 培训 | tr_plan_exam | plan_id, exam_id, required, sort_order | 计划-考试关联(V1.0.1) |
| 培训 | tr_plan_target | plan_id, target_type, target_id | 计划-对象 |
| 培训 | tr_plan_progress | plan_id, user_id, knowledge_id, completed, complete_time | 旧版进度(已被 km_knowledge_progress 替代) |
5.2 实体关系图
erDiagram
sys_center ||--o{ sys_department : "中心下辖多个部门"
sys_department ||--o{ sys_group : "部门下辖多个小组"
sys_department ||--o{ sys_user : "用户属于部门"
sys_group ||--o{ sys_user : "用户可归属小组"
sys_department ||--o{ km_category : "按部门隔离"
km_category ||--o{ km_knowledge : "知识归属分类"
sys_user ||--o{ km_knowledge_progress : "学员学习进度"
km_knowledge ||--o{ km_knowledge_progress : "知识对应进度"
sys_department ||--o{ ex_question_category : "按部门隔离"
ex_question_category ||--o{ ex_question : "题目归属分类"
ex_paper ||--o{ ex_paper_question : "试卷包含多道题"
ex_question ||--o{ ex_paper_question : "题目被多张试卷引用"
ex_paper ||--|| ex_exam : "考试使用某试卷"
ex_exam ||--o{ ex_exam_target : "考试指定对象"
ex_exam ||--o{ ex_exam_record : "考试产生记录"
sys_user ||--o{ ex_exam_record : "学员的考试记录"
tr_plan ||--o{ tr_plan_knowledge : "计划包含多个知识"
tr_plan ||--o{ tr_plan_exam : "计划关联多场考试"
tr_plan ||--o{ tr_plan_target : "计划分配给对象"
km_knowledge ||--o{ tr_plan_knowledge : "知识被计划引用"
ex_exam ||--o{ tr_plan_exam : "考试被计划引用"
5.3 数据生命周期
| 数据类型 | 创建 | 有效态 | 失效态 | 删除方式 |
|---|---|---|---|---|
| 知识/题目/试卷 | DRAFT | PUBLISHED | OFFLINE | 逻辑删除(deleted=1) |
| 考试 | NOT_STARTED | IN_PROGRESS | ENDED | 逻辑删除 |
| 培训计划 | NOT_STARTED | IN_PROGRESS | ENDED | 逻辑删除 |
| 考试记录 | IN_PROGRESS | SUBMITTED | 永久保留(取最高分) | 不删除 |
| 学习进度 | NOT_STARTED | IN_PROGRESS | COMPLETED | UPSERT更新 |
6. 权限与角色体系
6.1 角色定义
[SRC-FEAT-01:4.1 权限规则] [SRC-SQL-01:sys_user.role]
| 角色 | 枚举值(DB) | 数据范围 |
|---|---|---|
| 管理员 ADMIN | role=0 | 全平台(无部门隔离) |
| 讲师 LECTURER | role=1 | 本部门(department_id匹配) |
| 学员 STUDENT | role=2 | 本部门(只读;自己的进度/成绩) |
6.2 权限分层(按功能菜单)
| 菜单/功能 | ADMIN | LECTURER | STUDENT |
|---|---|---|---|
| 组织架构管理 | ✅ 全部 | ❌ | ❌ |
| 员工管理 | ✅ 全部 | 👁️ 本部门只读 | ❌ |
| 知识库-分类管理 | ✅ 全部 | ✅ 本部门 | ❌ |
| 知识库-知识列表 | ✅ 全部 | ✅ 本部门(含草稿) | 👁️ 本部门已发布 |
| 考题管理-题库分类 | ✅ | ✅ 本部门 | ❌ |
| 考题管理-题目列表 | ✅ | ✅ 本部门 | ❌ |
| 试卷管理 | ✅ | ✅ 本部门 | ❌ |
| 考试管理 | ✅ | ✅ 本部门发布 | 👁️ 我的考试 |
| 培训计划 | ✅ | ✅ 本部门创建/管理 | 👁️ 我的培训 |
| 系统设置 | ✅ | ❌ | ❌ |
| 工作台 | ✅ | ✅ | ✅(学员视图) |
[SRC-FEAT-01:8.1 角色菜单权限对照表]
6.3 控制逻辑
认证层:JWT Token 携带 userId + role,每次请求由 AuthInterceptor 解析验证。[SRC-CODE-01:common/interceptor/AuthInterceptor.java]
授权层:
- 接口级:
@PreAuthorize/ SecurityConfig 按角色匹配路径(/api/student/**仅 STUDENT) - 数据级:Service 层注入
department_id过滤,讲师/学员查询一律追加WHERE department_id = ?
隔离规则:
- 4类数据(知识库、题库、试卷/考试、培训计划)均按
department_id隔离 - 管理员不注入部门过滤,讲师注入本部门,学员额外限制只查 PUBLISHED 状态
7. 系统扩展点分析
7.1 可扩展模块
| 扩展点 | 当前状态 | V2+ 扩展方向 |
|---|---|---|
| 文件存储 | 本地文件系统 | 抽象 FileStorageService 接口 → MinIO/OSS 实现切换 |
| 认证方式 | 企业微信 OAuth(账号密码作备选) | 可接入 SSO/LDAP |
| 定时任务 | Spring @Scheduled(单机) | 可替换为 XXL-Job/SchedulerX 支持集群 |
| 统计报表 | 无(V2规划) | 新增 statistics 模块,不影响现有模块 |
| 通知 | 无(V2规划) | 可插入企业微信消息推送 |
7.2 可插拔能力
- 文档预览:kkFileView / OnlyOffice 作为可选外部服务,knowledge 模块通过 URL 调用,可随时替换
- 视频播放器:video.js 为前端组件,与后端解耦,可替换
- 批量导入:EasyExcel 依赖已选型,可随时为题目/用户管理添加 Excel 导入功能
7.3 易变业务点
| 易变点 | 变化方向 | 影响范围 |
|---|---|---|
| 培训完成判定逻辑(当前:必修知识+必考通过) | V2 可能增加签到、线下课时 | TrainingProgressService.calculateProgress() |
| 知识学习完成判定(视频90%/文档时长) | 可能改为100%或按章节 | KnowledgeLearningService.isCompleted() |
| 考试排名计算口径(当前:最高分排名 DENSE_RANK) | 可能改为平均分/最后一次 | SQL窗口函数,需同步修改 |
| 组织架构层级(当前:中心→部门→小组三级) | 可能增减层级 | system 模块全面影响 |