# 产品整体架构文档 — 道路救援企业培训系统 > 版本: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. 业务架构图 ```mermaid graph TD subgraph 客户端 PC[PC浏览器
管理员/讲师] WX[企业微信H5
学员] MB[移动端浏览器
学员] end subgraph 后端服务 subgraph 网关层 GW[JWT认证 / 权限拦截 / 异常处理] end subgraph 业务域 AUTH[认证模块
auth] SYS[系统管理
system] KM[知识库模块
knowledge] EX[考试模块
exam] TR[培训模块
training] end end subgraph 数据层 DB[(MySQL 8.0)] FS[文件存储
本地/MinIO] end subgraph 外部服务 WXAPI[企业微信API] PREVIEW[文档预览服务
可选] 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 用户主流程(学员) ```mermaid 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 管理流程(讲师) ```mermaid flowchart LR A[上传知识
DRAFT] --> B[发布知识
PUBLISHED] B --> C{有培训计划?} C -->|是| D[关联到培训计划] C -->|否| E[学员自由学习] F[创建题目
DRAFT] --> G[发布题目
PUBLISHED] G --> H[组卷
手动/自动] H --> I[发布试卷
PUBLISHED] I --> J[创建考试
设置时间/次数] J --> K[指定考试对象
部门/小组/个人] D --> L[创建培训计划] J --> L L --> M[分配学员
部门/小组/个人] M --> N[发布培训计划] ``` ### 4.3 数据流转流程 ```mermaid flowchart TB subgraph 内容生产 KM_CREATE[知识创建
km_knowledge DRAFT] KM_PUBLISH[发布知识
PUBLISHED] QS_CREATE[题目创建
ex_question DRAFT] QS_PUBLISH[发布题目
PUBLISHED] PP_CREATE[组卷
ex_paper + ex_paper_question] EX_CREATE[创建考试
ex_exam + ex_exam_target] TR_CREATE[培训计划
tr_plan + tr_plan_knowledge
+ tr_plan_exam + tr_plan_target] end subgraph 学员消费 LEARN[学习知识
→ km_knowledge_progress UPSERT] EXAM[参加考试
→ ex_exam_record 创建/更新] PROGRESS[进度计算
必修知识完成数 + 必考通过数] 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 实体关系图 ```mermaid 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 模块全面影响 |