docs: 归档项目需求分析、一期开发说明书及Kingbase数据库审计报告

This commit is contained in:
wangzhibiao committed 2026-09-13 23:16:37 +08:00
1 parent 83797f9286
commit 9d053bf41f
24 files changed
+17152

No files matched your search

@@ -0,0 +1,79 @@
# RailwaySystem 代码基线审计:项目概览
> 审计日期:2026-09-11
> 审计对象:当前 Git 工作树(包含已跟踪、未提交及未跟踪代码)
> 审计方式:静态只读检查;未连接数据库,未执行迁移,未编译、未启动、未修改业务代码。文中“存在”表示仓库中有相应代码,“可运行/已接通”只有在存在直接证据时才成立。
## 1. 工程定位与版本
- 当前仓库分支为 `main`。
- 后端是经典版 **RuoYi-Vue 前后端分离项目**,若依版本 **3.9.1**。依据:`RuoYi-Vue/README.md`、`RuoYi-Vue/pom.xml`、`RuoYi-Vue/ruoyi-admin/src/main/resources/application.yml`。
- 无法仅凭当前仓库证明最初从若依上游的哪个 Git 分支拉取;能确认的是当前代码属于经典 Vue 2 / Spring Boot 2 的 RuoYi-Vue 3.9.1 技术线,而当前仓库自己的分支是 `main`。
- 项目中有两个 Vue 工程:
- `build_ui/`:标题和描述均为“智慧培训管理平台”,含完整 `src/views/train` 与 `src/api/train`,是当前培训业务前端。
- `RuoYi-Vue/ruoyi-ui/`:描述为“知识图谱构建平台”,没有本次 14 组培训 CRUD 对应页面,应视为历史/基础前端副本,不能与 `build_ui/` 混为一个运行入口。
## 2. 后端技术栈
| 项目 | 当前代码证据 | 结论 |
| --- | --- | --- |
| Java | `RuoYi-Vue/pom.xml` 的 `java.version=1.8` | 源码/字节码目标 Java 8 |
| 当前机器 Java | `java -version` 为 OpenJDK 21.0.2 | 本机实际 Maven 运行时是 Java 21,与项目目标版本不同 |
| Spring Boot | `RuoYi-Vue/pom.xml` 的 `spring-boot.version=2.5.15` | Spring Boot 2.5.15 |
| Spring Framework | 同文件 `spring-framework.version=5.3.39` | 5.3.39 |
| Spring Security | 同文件 `spring-security.version=5.7.14` | 5.7.14,方法级鉴权 |
| 持久层 | `pagehelper-spring-boot-starter=1.4.7`、`mapper/**/*.xml` | 原生 MyBatis XML + PageHelper;未发现 MyBatis-Plus/baomidou |
| 数据源 | `application-druid.yml` | Druid 1.2.27,当前主库配置为 KingbaseES |
| JDBC 驱动 | 根 POM 与 `ruoyi-admin/pom.xml` | `com.kingbase:kingbase8:8.6.0`;MySQL 驱动也仍保留 |
| Excel | `ruoyi-common/.../ExcelUtil.java`、POI 4.1.2 | 若依 Excel 导入导出基础能力保留;培训 Controller 仅接了导出 |
| Token/JWT | `TokenService.java`、`JwtAuthenticationTokenFilter.java` | JWT 携带会话键,登录态主体保存在 Redis |
## 3. Maven 模块关系
父工程 `RuoYi-Vue/pom.xml` 聚合 7 个模块:
| 模块 | 作用 | 主要依赖关系 |
| --- | --- | --- |
| `ruoyi-admin` | Spring Boot 启动入口、Web Controller、配置 | 依赖 `framework`、`quartz`、`generator`、`train` |
| `ruoyi-framework` | Security、Token、AOP、数据源、Web 框架 | 依赖 `ruoyi-system` |
| `ruoyi-system` | 用户、角色、菜单、部门、字典、日志、配置、公告 | 依赖 `ruoyi-common` |
| `ruoyi-quartz` | Quartz 定时任务与任务日志 | 依赖 `ruoyi-common` |
| `ruoyi-generator` | 代码生成器 | 依赖 `ruoyi-common`、Druid |
| `ruoyi-common` | 通用返回、分页、异常、Excel、文件、安全工具 | 公共基础层 |
| `ruoyi-train` | 14 个培训领域对象、Mapper、Service | 依赖 `ruoyi-common`;Controller 放在 `ruoyi-admin` |
依据:`RuoYi-Vue/pom.xml:257`、各模块 `pom.xml`、`RuoYi-Vue/ruoyi-admin/pom.xml`。
## 4. 前端技术栈
`build_ui/package.json` 显示:Vue 2.6.12、Vue Router 3.4.9、Vuex 3.6.0、Element UI 2.15.12、Axios 0.24.0、ECharts 5.4.0、Vue CLI Service 4.4.6。`engines` 只声明 Node `>=8.9`、npm `>=3.0.0`,范围过宽,不能代表在当前 Node 22 上已被官方验证。
当前机器为 Node 22.23.2、npm 10.9.8。`build_ui/node_modules/.bin/vue-cli-service` 存在;本次没有执行 `npm run dev` 或构建。`build_ui/vue.config.js` 中存在尚未提交的 Node 22/MD4 兼容处理,并将开发端口从 80 改为 8080。
## 5. 数据库、Redis与环境
- 当前激活的 Spring profile 是 `druid`,配置位置:`RuoYi-Vue/ruoyi-admin/src/main/resources/application.yml`。
- 实际 datasource 配置位置:`RuoYi-Vue/ruoyi-admin/src/main/resources/application-druid.yml`。
- 当前配置使用 KingbaseES JDBC URL、`com.kingbase8.Driver` 与 `kingbase8:8.6.0`;账号口令以明文存在配置文件中,本报告不复述。
- `application.yml` 同时将 PageHelper 方言固定为 `mysql`;若依系统 Mapper 和代码生成器还存在 `date_format`、`find_in_set`、反引号、`ifnull` 等 MySQL 语法。
- Redis 配置为本机 `localhost:6379`、database 0。Token 会话、验证码/密码错误计数、缓存和在线用户依赖 Redis,因此正常登录运行时 Redis 是实际依赖。
- `ruoyi-quartz`、Quartz Controller/Service/Mapper、`sql/quartz.sql` 均存在;这只能证明定时任务框架保留,不能证明已配置培训业务任务。
## 6. 已保留的若依能力
代码层已保留:登录、JWT/Redis 登录态、RBAC、动态菜单、按钮权限、操作日志、数据权限框架、字典、定时任务、文件上传下载、Excel 工具、分页、统一返回、全局异常处理、代码生成、系统配置、通知公告。
“正常保留”不等于“已在 Kingbase 环境验证正常”。其中系统 SQL、代码生成元数据查询、PageHelper 方言和训练权限配置仍存在明确的接通风险,详见 `03_database_current_state.md`、`06_security_and_permissions.md` 和 `09_reusable_ruoyi_capabilities.md`。
## 7. 培训业务总体成熟度
- 后端存在 14 组标准生成式 CRUD,每组均有 Entity、Mapper、XML、Service、ServiceImpl、Controller。
- 前端当前工作树存在 14 组对应 CRUD 页面/API;其中成绩页面/API以及部分适配文件仍未跟踪,教室、宿舍、成绩 Controller 的别名也未提交。
- 14 组 Controller 共形成 84 个映射:每组 6 个,分别为分页列表、导出、详情、新增、修改、批量删除。
- 未发现培训导入接口、统计接口、设备回调/外部接入接口、流程动作接口、领域事务或专用 DTO/VO。
- 仓库没有 14 张 `train_` 表的 DDL、培训菜单/权限初始化 SQL、培训种子数据或迁移文件,也没有培训自动化测试。
- 因此当前基线应描述为:**14 组数据模型和 CRUD 脚手架基本齐全,但端到端可运行状态、数据库对象、菜单权限和业务闭环尚未由仓库证据证明。**
## 8. 审计边界
本次没有查询实时数据库。因此以下事项仍属“未验证”:14 张业务表是否已真实创建、表字段/约束是否与设计一致、当前 `sys_menu` 是否另由人工配置、当前 Kingbase 实例是否开启兼容模式、现有账号是否拥有培训权限、外部设备或系统是否另有未入库服务。
+107
View File
@@ -0,0 +1,107 @@
# RailwaySystem 简化项目树
已忽略 `.git`、`node_modules*`、`target`、`dist`、IDE 目录、日志、Office 临时锁文件和大型依赖目录。
```text
RailwaySystem/
├── RuoYi-Vue/ # Maven 后端父工程,同时保留一个旧/基础 Vue 工程
│ ├── pom.xml # 3.9.1 父 POM,聚合 7 个 Maven 模块
│ ├── README.md # RuoYi-Vue 3.9.1 说明
│ ├── ruoyi-admin/
│ │ └── src/main/
│ │ ├── java/com/ruoyi/
│ │ │ ├── RuoYiApplication.java
│ │ │ └── web/controller/
│ │ │ ├── common/ # 文件上传下载
│ │ │ ├── monitor/ # 监控、日志、在线用户等
│ │ │ ├── system/ # 用户、角色、菜单、字典、配置等
│ │ │ └── train/ # 14 个培训 Controller
│ │ └── resources/
│ │ ├── application.yml
│ │ ├── application-druid.yml
│ │ ├── logback.xml
│ │ └── mybatis/mybatis-config.xml
│ ├── ruoyi-common/
│ │ └── src/main/java/com/ruoyi/common/
│ │ ├── annotation/ # @Log、@DataScope、@Excel 等
│ │ ├── core/ # BaseEntity、AjaxResult、分页模型
│ │ ├── exception/ # 公共异常
│ │ └── utils/ # Excel、文件、分页、Security 等工具
│ ├── ruoyi-framework/
│ │ └── src/main/java/com/ruoyi/framework/
│ │ ├── aspectj/ # 操作日志、数据权限切面
│ │ ├── config/ # Security、Redis、Druid等配置
│ │ ├── security/filter/ # JWT 请求过滤器
│ │ └── web/ # Token/Login 服务、全局异常处理
│ ├── ruoyi-system/
│ │ └── src/main/
│ │ ├── java/com/ruoyi/system/ # sys_user/sys_role/sys_menu等领域与服务
│ │ └── resources/mapper/system/# 系统表 MyBatis XML
│ ├── ruoyi-quartz/ # Quartz 任务、任务日志、Controller/Mapper
│ ├── ruoyi-generator/ # 代码生成 Controller/Service/Mapper/模板
│ ├── ruoyi-train/
│ │ └── src/main/
│ │ ├── java/com/ruoyi/train/
│ │ │ ├── domain/ # 14 个 Train* Entity;均继承 BaseEntity
│ │ │ ├── mapper/ # 14 个 Mapper 接口
│ │ │ └── service/
│ │ │ └── impl/ # 14 个 ServiceImpl
│ │ └── resources/mapper/train/ # 14 个 Mapper XML
│ ├── ruoyi-ui/ # 历史/基础 Vue 2 前端,描述为知识图谱平台
│ │ └── src/{api,router,store,views}
│ └── sql/
│ ├── ry_20250522.sql # 若依系统表 MySQL 风格初始化脚本
│ └── quartz.sql # Quartz 表脚本
├── build_ui/ # 当前智慧培训管理平台 Vue 2 前端
│ ├── package.json
│ ├── vue.config.js # 当前开发端口 8080,代理后端 8090
│ ├── .env.development
│ ├── .env.staging
│ ├── .env.production
│ └── src/
│ ├── api/
│ │ ├── system/ # 用户、角色、菜单、字典等若依 API
│ │ ├── monitor/ # 监控 API
│ │ ├── tool/ # 代码生成 API
│ │ └── train/ # 培训 API 文件
│ ├── router/index.js # 常量路由;业务菜单由 /getRouters 动态加载
│ ├── store/modules/permission.js # 动态路由组装与权限过滤
│ └── views/
│ ├── system/ # 若依系统管理页面
│ ├── monitor/ # 若依监控页面
│ ├── tool/ # 若依代码生成/Swagger页面
│ ├── dashboard/ # 若依示例图表组件
│ └── train/
│ ├── teacher/ # 教师 CRUD
│ ├── student/ # 学员 CRUD
│ ├── course/ # 课程 CRUD
│ ├── plan/ # 开班计划 CRUD
│ ├── dormitory/ # 宿舍 CRUD(当前有未提交改动)
│ ├── auth/ # 宿舍权限 CRUD
│ ├── classroom/ # 教室 CRUD
│ ├── site/ # 实训场地 CRUD
│ ├── report/ # 开班报到 CRUD
│ ├── board/ # 电子班牌 CRUD
│ ├── checkin/ # 签到 CRUD
│ ├── score/ # 成绩 CRUD(未跟踪)
│ ├── duration/ # 学习时长 CRUD
│ ├── portrait/ # 画像记录 CRUD
│ ├── student-score/ # 成绩筛选视图(未跟踪)
│ ├── course-score/ # 课程成绩筛选视图(未跟踪)
│ ├── equipment/ # 规划提示页(未跟踪)
│ ├── extra/ # 规划提示页(未跟踪)
│ ├── person/ # 旧知识图谱人物页面
│ ├── character/ # 旧图谱/示例统计页面
│ ├── analysis/ # 旧分析页面
│ └── weather/ # 旧天气页面
├── doc/ # 需求、数据表设计、功能分析与补充材料
├── uploadPath/ # 文件上传目录
└── start-local.sh # 未跟踪的一键启动脚本
```
## 目录关系说明
- 培训 Controller 与业务实现分处两个 Maven 模块:Controller 在 `ruoyi-admin`,Entity/Mapper/Service/XML 在 `ruoyi-train`;`ruoyi-admin` 通过 POM 依赖 `ruoyi-train`。
- `build_ui/src/router/index.js` 只定义登录、首页、个人中心等常量路由。培训页面是否出现在菜单中取决于后端 `/getRouters` 返回的 `sys_menu` 数据。
- 仓库的 `RuoYi-Vue/sql/` 只有若依系统表和 Quartz 脚本,没有培训业务表 DDL。
- `RuoYi-Vue/ruoyi-admin/D:/...` 是 Maven POM 中 Windows 输出路径在 macOS 上形成的字面目录,属于构建产物/依赖副本,不是业务模块。
@@ -0,0 +1,510 @@
# 培训业务模块与 14 组 CRUD 盘点
## 1. 审计口径
本文件来自对以下实际目录的逐项比对:
- Controller:`RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/train/`
- Domain:`RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/domain/`
- Mapper:`RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/mapper/`
- Service:`RuoYi-Vue/ruoyi-train/src/main/java/com/ruoyi/train/service/`
- XML:`RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/`
- 前端:`build_ui/src/views/train/`、`build_ui/src/api/train/`
- 表设计:`doc/学员管理系统数据表设计_20260907_1_.docx`
14 组后端均为同一生成式结构:分页列表、Excel 导出、详情、新增、修改、物理批量删除。未发现培训专用 DTO/VO;Controller 直接接收并返回 Domain。ServiceImpl 基本为 Mapper 委托,没有领域校验、跨表编排、事务流程或外部系统调用。
## 2. 模块逐项盘点
### 2.1 教师信息
**模块名称:** 教师信息(`train_teacher`)
**后端:**
- Controller:`TrainTeacherController`
- Service:`ITrainTeacherService`
- ServiceImpl:`TrainTeacherServiceImpl`
- Mapper:`TrainTeacherMapper`
- XML:`TrainTeacherMapper.xml`
- Domain / Entity:`TrainTeacher`
- DTO / VO:无
**前端:**
- views:`build_ui/src/views/train/teacher/index.vue`
- api:`build_ui/src/api/train/teacher.js`
**数据库:** 涉及表 `train_teacher`
**当前已有功能:**
1. 教师条件列表、详情、新增、修改、批量删除。
2. 基于 `@Excel` 字段注解的导出。
3. 字段覆盖工号、姓名、性别、出生日期、院系、职称、电话、邮箱及公共审计字段。
**明显缺失:**
1. 没有教师与 `sys_user` 的账号关联。
2. 没有资质/证书、状态、可授课程、授课范围及教师数据权限。
3. 删除为物理删除;无导入接口、查重与跨表引用校验。
### 2.2 学员信息
**模块名称:** 学员信息(`train_student`)
**后端:**
- Controller:`TrainStudentController`
- Service:`ITrainStudentService`
- ServiceImpl:`TrainStudentServiceImpl`
- Mapper:`TrainStudentMapper`
- XML:`TrainStudentMapper.xml`
- Domain / Entity:`TrainStudent`
- DTO / VO:无
**前端:**
- views:`build_ui/src/views/train/student/index.vue`
- api:`build_ui/src/api/train/student.js`
**数据库:** 涉及表 `train_student`
**当前已有功能:**
1. 学员条件列表、详情、新增、修改、批量删除。
2. Excel 导出。
3. 保存学号、姓名、性别、出生日期、院系、专业、班级、电话。
**明显缺失:**
1. 没有学员与 `sys_user` 的账号关联,也没有身份证/人脸等报到和门禁所需身份数据。
2. 没有参训/报名关系、学员在某期培训中的状态。
3. 删除为物理删除;无培训学员导入接口和重复校验。
### 2.3 课程信息
**模块名称:** 课程信息(`train_course`)
**后端:**
- Controller:`TrainCourseController`
- Service:`ITrainCourseService`
- ServiceImpl:`TrainCourseServiceImpl`
- Mapper:`TrainCourseMapper`
- XML:`TrainCourseMapper.xml`
- Domain / Entity:`TrainCourse`
- DTO / VO:无
**前端:**
- views:`build_ui/src/views/train/course/index.vue`
- api:`build_ui/src/api/train/course.js`
**数据库:** 涉及表 `train_course`
**当前已有功能:**
1. 课程条件列表、详情、新增、修改、批量删除。
2. Excel 导出。
3. 文档、视频、模型链接和模型资源 ID 以文本字段保存。
**明显缺失:**
1. 没有课程版本、章节、课次、课表、资源实体及资源关系。
2. 附件和多资源使用逗号分隔/文本 URL,没有与已有上传能力形成业务关系。
3. 无课程发布、审核、上下架等动作。
### 2.4 开班计划
**模块名称:** 开班计划(`train_class_plan`)
**后端:**
- Controller:`TrainClassPlanController`
- Service:`ITrainClassPlanService`
- ServiceImpl:`TrainClassPlanServiceImpl`
- Mapper:`TrainClassPlanMapper`
- XML:`TrainClassPlanMapper.xml`
- Domain / Entity:`TrainClassPlan`
- DTO / VO:无
**前端:**
- views:`build_ui/src/views/train/plan/index.vue`
- api:`build_ui/src/api/train/plan.js`
**数据库:** 涉及表 `train_class_plan`
**当前已有功能:**
1. 计划条件列表、详情、新增、修改、批量删除。
2. Excel 导出。
3. 保存单个 `c_id`、单个 `t_id`、起止时间、地点、招生人数、报名条件、状态。
**明显缺失:**
1. 一个计划只有一个课程与一个教师,不能表达一班多课、多教师、逐课次安排。
2. 没有参训名单、报名审核、开班/结班等状态动作。
3. 没有教室、实训场地、课程时间冲突校验。
### 2.5 宿舍信息
**模块名称:** 宿舍信息(`train_dormitory_info`)
**后端:**
- Controller:`TrainDormitoryInfoController`
- Service:`ITrainDormitoryInfoService`
- ServiceImpl:`TrainDormitoryInfoServiceImpl`
- Mapper:`TrainDormitoryInfoMapper`
- XML:`TrainDormitoryInfoMapper.xml`
- Domain / Entity:`TrainDormitoryInfo`
- DTO / VO:无
**前端:**
- views:`build_ui/src/views/train/dormitory/index.vue`(有未提交修改)
- api:`build_ui/src/api/train/dormitory.js`(未跟踪)
**数据库:** 涉及表 `train_dormitory_info`
**当前已有功能:**
1. 当前工作树页面与 API 支持宿舍列表、详情、新增、修改、删除。
2. 保存楼栋、房间号、床位总数/已用数、门锁序列号、状态。
3. Controller 同时接受 `/train/dorminfo` 与 `/train/dormitory`,该别名改动尚未提交。
**明显缺失:**
1. 当前页面没有导出按钮和 `v-hasPermi` 按钮权限控制;后端仍有导出接口。
2. 没有独立床位实体、床位占用唯一性或容量一致性校验。
3. 无楼栋/楼层层级和住宿状态流转。
### 2.6 宿舍权限分配
**模块名称:** 宿舍权限分配(`train_dorm_auth`)
**后端:**
- Controller:`TrainDormAuthController`
- Service:`ITrainDormAuthService`
- ServiceImpl:`TrainDormAuthServiceImpl`
- Mapper:`TrainDormAuthMapper`
- XML:`TrainDormAuthMapper.xml`
- Domain / Entity:`TrainDormAuth`
- DTO / VO:无
**前端:**
- views:`build_ui/src/views/train/auth/index.vue`
- api:`build_ui/src/api/train/auth.js`
**数据库:** 涉及表 `train_dorm_auth`
**当前已有功能:**
1. 权限记录条件列表、详情、新增、修改、批量删除。
2. Excel 导出。
3. 保存学员、计划、宿舍、床号、授权起止时间和人脸下发状态。
**明显缺失:**
1. 没有实际门锁下发接口、回调、重试、错误详情或操作流水。
2. 住宿分配与设备授权耦合在一张表,没有独立住宿分配状态。
3. 没有床位冲突、时段重叠、人员/计划/房间存在性校验。
### 2.7 教室信息
**模块名称:** 教室信息(`train_classroom_info`)
**后端:**
- Controller:`TrainClassroomInfoController`
- Service:`ITrainClassroomInfoService`
- ServiceImpl:`TrainClassroomInfoServiceImpl`
- Mapper:`TrainClassroomInfoMapper`
- XML:`TrainClassroomInfoMapper.xml`
- Domain / Entity:`TrainClassroomInfo`
- DTO / VO:无
**前端:**
- views:`build_ui/src/views/train/classroom/index.vue`
- api:页面实际导入 `build_ui/src/api/train/info.js`;另有未跟踪的 `classroom.js`
**数据库:** 涉及表 `train_classroom_info`
**当前已有功能:**
1. 教室列表、详情、新增、修改、删除与导出。
2. 保存名称、位置、容量、状态。
3. 当前 Controller 接受 `/train/classroominfo`、`/train/classroom`、`/train/info` 三个前缀,属于未提交兼容改动。
**明显缺失:**
1. 前后端权限分别为 `train:info:*` 和 `system:info:*`,不一致。
2. 多个 API 文件/别名并存,规范入口尚未收敛。
3. 无排课占用、时间冲突与容量校验。
### 2.8 实训场地
**模块名称:** 实训场地(`train_training_site`)
**后端:**
- Controller:`TrainTrainingSiteController`
- Service:`ITrainTrainingSiteService`
- ServiceImpl:`TrainTrainingSiteServiceImpl`
- Mapper:`TrainTrainingSiteMapper`
- XML:`TrainTrainingSiteMapper.xml`
- Domain / Entity:`TrainTrainingSite`
- DTO / VO:无
**前端:**
- views:`build_ui/src/views/train/site/index.vue`
- api:`build_ui/src/api/train/site.js`
**数据库:** 涉及表 `train_training_site`
**当前已有功能:**
1. 场地条件列表、详情、新增、修改、批量删除。
2. Excel 导出。
3. 保存名称、位置、容量、配套设备文本、状态。
**明显缺失:**
1. 配套设备仅为文本字段,没有设备资产关系。
2. 无场地排期、占用、冲突和容量校验。
3. 无场地类型、设备可用状态的独立管理。
### 2.9 开班报到
**模块名称:** 开班报到(`train_class_report`)
**后端:**
- Controller:`TrainClassReportController`
- Service:`ITrainClassReportService`
- ServiceImpl:`TrainClassReportServiceImpl`
- Mapper:`TrainClassReportMapper`
- XML:`TrainClassReportMapper.xml`
- Domain / Entity:`TrainClassReport`
- DTO / VO:无
**前端:**
- views:`build_ui/src/views/train/report/index.vue`
- api:`build_ui/src/api/train/report.js`
**数据库:** 涉及表 `train_class_report`
**当前已有功能:**
1. 报到记录条件列表、详情、新增、修改、批量删除。
2. Excel 导出。
3. 保存报到方式、设备号、时间、状态,以及宿舍/教室/场地分配 ID。
**明显缺失:**
1. 页面是人工维护 CRUD,没有身份证/人脸设备接入或回调接口。
2. 没有参训名单作为报到资格来源,也没有防重复报到与状态流转。
3. 报到事件与三类资源分配耦合,未见原子事务和容量/冲突校验。
### 2.10 电子班牌
**模块名称:** 电子班牌设备(`train_electronic_board`)
**后端:**
- Controller:`TrainElectronicBoardController`
- Service:`ITrainElectronicBoardService`
- ServiceImpl:`TrainElectronicBoardServiceImpl`
- Mapper:`TrainElectronicBoardMapper`
- XML:`TrainElectronicBoardMapper.xml`
- Domain / Entity:`TrainElectronicBoard`
- DTO / VO:无
**前端:**
- views:`build_ui/src/views/train/board/index.vue`
- api:`build_ui/src/api/train/board.js`
**数据库:** 涉及表 `train_electronic_board`
**当前已有功能:**
1. 班牌设备条件列表、详情、新增、修改、批量删除。
2. Excel 导出。
3. 保存序列号、绑定教室/计划、IP、显示内容、播放模式、签到类型、在线状态、最后心跳。
**明显缺失:**
1. 没有心跳上报、内容发布、设备命令、签到回调等外部接入接口。
2. 没有设备认证、签名、幂等和离线判定任务。
3. `board_playmode` 的设计注释与 `board_status` 都使用“离线/在线”语义,字段边界不清。
### 2.11 学员签到
**模块名称:** 学员签到(`train_student_checkin`)
**后端:**
- Controller:`TrainStudentCheckinController`
- Service:`ITrainStudentCheckinService`
- ServiceImpl:`TrainStudentCheckinServiceImpl`
- Mapper:`TrainStudentCheckinMapper`
- XML:`TrainStudentCheckinMapper.xml`
- Domain / Entity:`TrainStudentCheckin`
- DTO / VO:无
**前端:**
- views:`build_ui/src/views/train/checkin/index.vue`
- api:`build_ui/src/api/train/checkin.js`
**数据库:** 涉及表 `train_student_checkin`
**当前已有功能:**
1. 签到记录条件列表、详情、新增、修改、批量删除。
2. Excel 导出。
3. 保存计划、课程、学员、班牌、签到方式/状态,以及课次起止时间。
**明显缺失:**
1. 没有 `lesson_id`/课次实体;每条签到重复保存课程起止时间。
2. 没有设备签到接入、二维码生成/核验、迟到早退计算或补签审批。
3. 没有同一学员同一课次的唯一约束/幂等证据。
### 2.12 多类型成绩
**模块名称:** 多类型成绩(`train_score_info`)
**后端:**
- Controller:`TrainScoreInfoController`
- Service:`ITrainScoreInfoService`
- ServiceImpl:`TrainScoreInfoServiceImpl`
- Mapper:`TrainScoreInfoMapper`
- XML:`TrainScoreInfoMapper.xml`
- Domain / Entity:`TrainScoreInfo`
- DTO / VO:无
**前端:**
- views:`build_ui/src/views/train/score/index.vue`(未跟踪)
- api:`build_ui/src/api/train/score.js`(未跟踪)
- 只读衍生视图:`student-score/index.vue`、`course-score/index.vue`(均未跟踪)
**数据库:** 涉及表 `train_score_info`
**当前已有功能:**
1. 当前工作树有成绩列表、详情、新增、修改、删除页面/API;后端有导出接口。
2. 保存课程成绩、实训成绩、考核成绩、来源类型/系统、导入时间。
3. 学员成绩和课程成绩页面只是调用同一列表接口做筛选;课程成绩页以 `examScore` 在前端计算显示评级。
**明显缺失:**
1. 成绩页面没有按钮权限指令和导出入口,文件仍未纳入 Git。
2. 没有 Excel 导入接口、外部采集接口、错误反馈、审核/发布/锁定。
3. 没有权重、综合分公式及版本;代码未计算真正综合成绩。
### 2.13 学习时长
**模块名称:** 学习时长统计(`train_study_duration`)
**后端:**
- Controller:`TrainStudyDurationController`
- Service:`ITrainStudyDurationService`
- ServiceImpl:`TrainStudyDurationServiceImpl`
- Mapper:`TrainStudyDurationMapper`
- XML:`TrainStudyDurationMapper.xml`
- Domain / Entity:`TrainStudyDuration`
- DTO / VO:无
**前端:**
- views:`build_ui/src/views/train/duration/index.vue`
- api:`build_ui/src/api/train/duration.js`
**数据库:** 涉及表 `train_study_duration`
**当前已有功能:**
1. 时长记录条件列表、详情、新增、修改、批量删除。
2. Excel 导出。
3. 保存设备类型、起止时间、时长秒数和同步时间。
**明显缺失:**
1. 没有设备/外部系统上报接口、外部事件 ID、幂等与异常记录。
2. 没有由起止时间校验或计算 `study_seconds` 的业务逻辑。
3. 无汇总统计接口;所谓“统计”当前仍是明细 CRUD。
### 2.14 学员画像
**模块名称:** 学员画像(`train_student_portrait`)
**后端:**
- Controller:`TrainStudentPortraitController`
- Service:`ITrainStudentPortraitService`
- ServiceImpl:`TrainStudentPortraitServiceImpl`
- Mapper:`TrainStudentPortraitMapper`
- XML:`TrainStudentPortraitMapper.xml`
- Domain / Entity:`TrainStudentPortrait`
- DTO / VO:无
**前端:**
- views:`build_ui/src/views/train/portrait/index.vue`
- api:`build_ui/src/api/train/portrait.js`
**数据库:** 涉及表 `train_student_portrait`
**当前已有功能:**
1. 画像记录条件列表、详情、新增、修改、批量删除。
2. Excel 导出。
3. 保存总学习时长、平均成绩、签到率、标签和综合描述。
**明显缺失:**
1. 没有从签到、成绩、学习时长聚合生成画像的服务。
2. 没有指标/标签规则、版本、快照历史或生成时间。
3. 前端只是表格 CRUD,没有雷达图、趋势或画像工作台。
## 3. 14 组 CRUD 完整度
| 模块 | 数据表 | Entity | Mapper | Service | Controller | 前端 API | 前端页面 | CRUD 完整度 |
| --- | --- | --- | --- | --- | --- | --- | --- | --- |
| 教师 | `train_teacher` | `TrainTeacher` | 接口+XML | 接口+Impl | `TrainTeacherController` | `teacher.js` | `teacher/index.vue` | 疑似生成但未接通 |
| 学员 | `train_student` | `TrainStudent` | 接口+XML | 接口+Impl | `TrainStudentController` | `student.js` | `student/index.vue` | 疑似生成但未接通 |
| 课程 | `train_course` | `TrainCourse` | 接口+XML | 接口+Impl | `TrainCourseController` | `course.js` | `course/index.vue` | 疑似生成但未接通 |
| 开班计划 | `train_class_plan` | `TrainClassPlan` | 接口+XML | 接口+Impl | `TrainClassPlanController` | `plan.js` | `plan/index.vue` | 疑似生成但未接通 |
| 宿舍 | `train_dormitory_info` | `TrainDormitoryInfo` | 接口+XML | 接口+Impl | `TrainDormitoryInfoController` | `dormitory.js`(未跟踪) | `dormitory/index.vue`(已修改) | 疑似生成但未接通 |
| 宿舍权限 | `train_dorm_auth` | `TrainDormAuth` | 接口+XML | 接口+Impl | `TrainDormAuthController` | `auth.js` | `auth/index.vue` | 疑似生成但未接通 |
| 教室 | `train_classroom_info` | `TrainClassroomInfo` | 接口+XML | 接口+Impl | `TrainClassroomInfoController`(已修改) | `info.js`(已修改) | `classroom/index.vue` | 疑似生成但未接通 |
| 实训场地 | `train_training_site` | `TrainTrainingSite` | 接口+XML | 接口+Impl | `TrainTrainingSiteController` | `site.js` | `site/index.vue` | 疑似生成但未接通 |
| 开班报到 | `train_class_report` | `TrainClassReport` | 接口+XML | 接口+Impl | `TrainClassReportController` | `report.js` | `report/index.vue` | 疑似生成但未接通 |
| 电子班牌 | `train_electronic_board` | `TrainElectronicBoard` | 接口+XML | 接口+Impl | `TrainElectronicBoardController` | `board.js` | `board/index.vue` | 疑似生成但未接通 |
| 学员签到 | `train_student_checkin` | `TrainStudentCheckin` | 接口+XML | 接口+Impl | `TrainStudentCheckinController` | `checkin.js` | `checkin/index.vue` | 疑似生成但未接通 |
| 多类型成绩 | `train_score_info` | `TrainScoreInfo` | 接口+XML | 接口+Impl | `TrainScoreInfoController`(已修改) | `score.js`(未跟踪) | `score/index.vue`(未跟踪) | 疑似生成但未接通 |
| 学习时长 | `train_study_duration` | `TrainStudyDuration` | 接口+XML | 接口+Impl | `TrainStudyDurationController` | `duration.js` | `duration/index.vue` | 疑似生成但未接通 |
| 学员画像 | `train_student_portrait` | `TrainStudentPortrait` | 接口+XML | 接口+Impl | `TrainStudentPortraitController` | `portrait.js` | `portrait/index.vue` | 疑似生成但未接通 |
### 判断说明
这里的“疑似生成但未接通”不是说缺少 CRUD 文件。相反,14 组的六类后端构件和对应前端页面/API在当前工作树都存在。采用该结论是因为:
1. 仓库没有培训表 DDL或迁移,无法证明运行数据库有表。
2. 仓库没有培训 `sys_menu`/权限初始化 SQL,前后端权限字符串还普遍不一致。
3. 成绩、宿舍 API及部分页面/Controller适配尚未提交。
4. 没有端到端测试、接口测试或当前启动验证证据。
若只按“是否具有生成器产出的 CRUD 文件”衡量,14 组均为代码层齐全;若按“用户可从菜单登录并完成 CRUD”衡量,目前没有一组可以由仓库证据确认“完整”。
@@ -0,0 +1,147 @@
# 数据库当前状态
## 1. 审计边界与结论
本次只检查代码、Mapper XML、配置、SQL 文件和数据表设计文档,没有连接或查询实时数据库。因此本文件区分三种事实:
- **代码引用**:Mapper 明确执行某张表。
- **设计存在**:`doc/学员管理系统数据表设计_20260907_1_.docx` 描述了该表。
- **数据库实存**:本次未验证,不能由 Entity 或 Mapper 的存在推导。
代码正配置为 KingbaseES,但仓库中的唯一系统初始化脚本和多处 Mapper 仍为 MySQL 方言;培训业务又完全没有可执行 DDL/迁移。这是继续开发前必须先确认的数据库基线问题。
## 2. 数据源与驱动
| 项目 | 当前状态 | 代码依据 |
| --- | --- | --- |
| 数据库 | KingbaseES | `RuoYi-Vue/ruoyi-admin/src/main/resources/application-druid.yml` 使用 `jdbc:kingbase8:` |
| 驱动类 | `com.kingbase8.Driver` | 同上 |
| Maven 驱动 | `com.kingbase:kingbase8:8.6.0` | `RuoYi-Vue/pom.xml`、`ruoyi-admin/pom.xml` |
| 连接池 | Druid 1.2.27 | 根 POM、`application-druid.yml` |
| 当前库/schema | 配置指向 `training` / `public` | `application-druid.yml`;主机、用户名和口令不在报告中复述 |
| 其他驱动 | MySQL Connector 仍在 `ruoyi-admin` 依赖中 | `RuoYi-Vue/ruoyi-admin/pom.xml:46` |
| PageHelper 方言 | 固定为 `mysql` | `application.yml:109` |
## 3. 表分类
### A. 若依系统表,不建议修改
`RuoYi-Vue/sql/ry_20250522.sql` 定义并由 `ruoyi-system`、`ruoyi-framework`、`ruoyi-quartz`、`ruoyi-generator` 使用的主要表包括:
- 账号与组织:`sys_user`、`sys_dept`、`sys_post`、`sys_role`。
- 权限关系:`sys_menu`、`sys_user_role`、`sys_role_menu`、`sys_role_dept`、`sys_user_post`。
- 基础配置:`sys_config`、`sys_dict_type`、`sys_dict_data`、`sys_notice`。
- 日志:`sys_oper_log`、`sys_logininfor`。
- 定时任务:`sys_job`、`sys_job_log`,以及 `quartz.sql` 中的 `qrtz_*` 表。
- 代码生成:`gen_table`、`gen_table_column`。
这些表支撑若依登录、RBAC、菜单、数据权限、字典、配置、公告、日志、任务和代码生成。培训业务应通过新增菜单、角色关系和业务关联复用它们,不应改造其结构来代替培训领域表。本次未修改任何 `sys_*` 表。
### B. 当前培训业务表
以下 14 张表同时出现在设计文档和 Mapper XML 中:
| 表 | Entity | 主键 | Mapper SQL | 设计字段与 Entity/Mapper |
| --- | --- | --- | --- | --- |
| `train_teacher` | `TrainTeacher` | `t_id` / `String` | 查、增、改、物理删 | 显式业务字段一致;另继承 BaseEntity 属性 |
| `train_student` | `TrainStudent` | `s_id` / `String` | 查、增、改、物理删 | 显式业务字段一致;另继承 BaseEntity 属性 |
| `train_course` | `TrainCourse` | `c_id` / `String` | 查、增、改、物理删 | 显式业务字段一致;另继承 BaseEntity 属性 |
| `train_class_plan` | `TrainClassPlan` | `plan_id` / `String` | 查、增、改、物理删 | 显式业务字段一致;另继承 BaseEntity 属性 |
| `train_dormitory_info` | `TrainDormitoryInfo` | `dorm_id` / `String` | 查、增、改、物理删 | 显式业务字段一致;另继承 BaseEntity 属性 |
| `train_dorm_auth` | `TrainDormAuth` | `auth_id` / `Long` | 查、增、改、物理删;generated keys | 显式业务字段一致;另继承 BaseEntity 属性 |
| `train_classroom_info` | `TrainClassroomInfo` | `class_room_id` / `String` | 查、增、改、物理删 | 显式业务字段一致;另继承 BaseEntity 属性 |
| `train_training_site` | `TrainTrainingSite` | `site_id` / `String` | 查、增、改、物理删 | 显式业务字段一致;另继承 BaseEntity 属性 |
| `train_class_report` | `TrainClassReport` | `report_id` / `Long` | 查、增、改、物理删;generated keys | 显式业务字段一致;另继承 BaseEntity 属性 |
| `train_electronic_board` | `TrainElectronicBoard` | `board_id` / `String` | 查、增、改、物理删 | 显式业务字段一致;另继承 BaseEntity 属性 |
| `train_student_checkin` | `TrainStudentCheckin` | `checkin_id` / `Long` | 查、增、改、物理删;generated keys | 显式业务字段一致;另继承 BaseEntity 属性 |
| `train_score_info` | `TrainScoreInfo` | `score_id` / `Long` | 查、增、改、物理删;generated keys | 显式业务字段一致;另继承 BaseEntity 属性 |
| `train_study_duration` | `TrainStudyDuration` | `dur_id` / `Long` | 查、增、改、物理删;generated keys | 显式业务字段一致;另继承 BaseEntity 属性 |
| `train_student_portrait` | `TrainStudentPortrait` | `portrait_id` / `Long` | 查、增、改、物理删;generated keys | 显式业务字段一致;另继承 BaseEntity 属性 |
“一致”仅指设计文档字段名与 Entity/Mapper 显式映射的静态比对,未验证真实 Kingbase 表结构、长度、默认值、约束和类型。
### C. 代码中引用但设计文档没有的培训表
在 `ruoyi-train/src/main/resources/mapper/train` 的当前 14 个 XML 中未发现此类表。旧知识图谱/天气前端页面调用的接口没有相应当前培训后端 Controller,不能据此认定存在业务表。
### D. 设计文档存在但代码尚未实现的表
以《学员管理系统数据表设计》列出的 14 张具体表为范围,未发现只在设计文档存在而完全没有 Entity/Mapper 的表。
需要区分:需求与功能分析材料提出或暗示了参训关系、课次/课表、床位、设备同步流水等概念,但这些并不是该数据表设计文档中已经命名的表,因此不计入本节 D 类;它们作为领域缺口列在 `10_gap_and_conflict_analysis.md`。
## 4. 字段与公共字段
14 个 `Train*` Domain 全部 `extends BaseEntity`。`BaseEntity` 提供:`searchValue`、`createBy`、`createTime`、`updateBy`、`updateTime`、`remark`、`params`。
当前培训设计和 Mapper 的实际使用方式并不完全统一:
- 教师、学员、课程、计划、宿舍、宿舍权限、教室、场地、班牌显式定义 `createUser`,映射数据库 `create_user`;同时从 BaseEntity 继承 `createTime`、`updateTime`、`remark`。
- 报到表只显式映射 `create_time`,没有 `create_user`、`update_time`、`remark`。
- 签到表没有通用审计字段。
- 成绩表使用 `import_time`,学习时长表使用 `sync_time`,画像表使用 `update_time`。
- 培训表 Mapper 未使用 BaseEntity 的 `createBy`/`updateBy` 写入 `create_by`/`update_by`;业务表设计使用的是 `create_user`。
- 部分 ServiceImpl 会设置 `createTime` 或 `updateTime`,但没有统一填充器;这不是 MyBatis-Plus 项目。
因此,虽然所有实体继承 BaseEntity,不能据此认为所有培训表都具备完整一致的若依公共字段。
## 5. 主键生成
- 字符串业务主键:`t_id`、`s_id`、`c_id`、`plan_id`、`dorm_id`、`class_room_id`、`site_id`、`board_id`。Mapper 仅在属性非空时插入,没有 UUID/雪花算法等 Java 侧生成逻辑;前端表单需提供或数据库必须有另行默认值。
- 数字主键:`auth_id`、`report_id`、`checkin_id`、`score_id`、`dur_id`、`portrait_id`。相应 XML 使用 `useGeneratedKeys="true"` 与 `keyProperty`。
- 设计文档将数字主键写为 `INT AUTO_INCREMENT`。这属于 MySQL 表述;在 Kingbase 应由实际 identity/sequence 定义与驱动回填能力共同保证。本次未连接数据库,未验证生成键行为。
## 6. 删除方式
- 14 个培训 Mapper 的删除语句均为 `delete from train_*`,包括批量 `IN` 删除。
- 培训 Domain 未发现 `delFlag`,设计文档也未为这些表定义 `del_flag`。
- 因此当前培训 CRUD 是物理删除,不是若依系统表常用的逻辑删除。
## 7. 外键与完整性
设计文档在描述列中标注多处“外键”,但仓库没有培训 DDL,也没有 `FOREIGN KEY` 约束脚本。Mapper 采用单表 SQL,ServiceImpl 未见关联对象存在性检查、级联策略或事务编排。
所以当前只能确认“字段表达了引用意图”,不能确认数据库中已创建外键、唯一索引或级联规则。
## 8. SQL 初始化与迁移
仓库中可见:
- `RuoYi-Vue/sql/ry_20250522.sql`:若依系统表初始化,整体为 MySQL DDL/DML 风格。
- `RuoYi-Vue/sql/quartz.sql`:Quartz 表脚本。
未发现:
- 14 张 `train_*` 表的可执行 DDL或种子数据。
- 培训 `sys_menu`、角色和权限初始化 SQL。
- Flyway、Liquibase 或其他版本化迁移目录/配置。
设计 DOCX 只是表结构说明,不是可执行迁移。
## 9. Kingbase 兼容性事实
当前配置与代码同时存在以下待验证点:
1. `application.yml` 固定 `pagehelper.helperDialect: mysql`。
2. `ry_20250522.sql` 大量使用 `AUTO_INCREMENT`、`ENGINE=InnoDB`、反引号、MySQL 类型宽度和 `sysdate()`。
3. 系统 Mapper 使用 `date_format(...)`、`find_in_set(...)`、`ifnull(...)` 和反引号列名,例如 `SysUserMapper.xml`、`SysDeptMapper.xml`、`SysMenuMapper.xml`。
4. `DataScopeAspect` 动态拼接 `find_in_set`。
5. 代码生成器读取 `information_schema` 时同时依赖 `current_database()` 以及 MySQL 的 `column_key`、`column_comment`、`extra='auto_increment'`、`column_type` 语义。
6. 培训设计文档采用 `DATETIME`、`TINYINT`、`AUTO_INCREMENT` 和 `ON UPDATE CURRENT_TIMESTAMP`。
7. 培训数字主键依赖 JDBC generated keys。
8. Druid 校验 SQL 为 `SELECT 1 FROM DUAL`。
这不等于所有语句在 Kingbase 必然失败,因为 Kingbase 可能启用兼容模式;但仓库没有记录目标兼容模式,也没有验证脚本/测试结果。不能把“已换驱动和 URL”视为完成数据库适配。
## 10. `sys_*` 表当前如何被使用
- `sys_user`:登录主体、个人资料、用户管理、角色/岗位关系。
- `sys_role`:角色定义与数据范围类型。
- `sys_menu`:菜单树、路由组件、权限字符串;`/getRouters` 动态返回前端路由。
- `sys_role_menu`、`sys_user_role`:RBAC 关系。
- `sys_dept`、`sys_role_dept`:部门树与数据权限。
- `sys_oper_log`、`sys_logininfor`:操作与登录日志。
- `sys_dict_*`、`sys_config`、`sys_notice`:字典、参数、公告。
- `sys_job`、`sys_job_log`:Quartz 任务定义与执行日志。
培训表当前未与 `sys_user` 建立代码层关系,培训 Service 也未应用若依数据权限切面。后续应在现有权限体系上增加培训关系和权限配置,不应修改系统表结构来复制一套登录/RBAC。
+112
View File
@@ -0,0 +1,112 @@
# 培训接口盘点
## 1. 总体结论
在 `RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/train/` 找到 14 个 Controller、84 个映射。每个模块严格重复 6 个端点:列表、导出、详情、新增、修改、删除。
未发现培训业务动作接口、统计聚合接口、Excel 导入接口、外部设备/系统接入接口。`report`、`checkin`、`board`、`auth`、`duration`、`score` 的名称具有业务含义,但其 Controller 实现仍只是通用 CRUD。
## 2. 实际接口
| 模块 | Method | URL | Controller 方法 | 权限码 | 当前用途 |
| --- | --- | --- | --- | --- | --- |
| 教师 | GET | `/train/teacher/list` | `TrainTeacherController.list` | `system:teacher:list` | 纯CRUD:分页列表 |
| 教师 | POST | `/train/teacher/export` | `export` | `system:teacher:export` | 纯CRUD:Excel导出 |
| 教师 | GET | `/train/teacher/{tId}` | `getInfo` | `system:teacher:query` | 纯CRUD:详情 |
| 教师 | POST | `/train/teacher` | `add` | `system:teacher:add` | 纯CRUD:新增 |
| 教师 | PUT | `/train/teacher` | `edit` | `system:teacher:edit` | 纯CRUD:修改 |
| 教师 | DELETE | `/train/teacher/{tIds}` | `remove` | `system:teacher:remove` | 纯CRUD:批量物理删除 |
| 学员 | GET | `/train/student/list` | `TrainStudentController.list` | `system:student:list` | 纯CRUD:分页列表 |
| 学员 | POST | `/train/student/export` | `export` | `system:student:export` | 纯CRUD:Excel导出 |
| 学员 | GET | `/train/student/{sId}` | `getInfo` | `system:student:query` | 纯CRUD:详情 |
| 学员 | POST | `/train/student` | `add` | `system:student:add` | 纯CRUD:新增 |
| 学员 | PUT | `/train/student` | `edit` | `system:student:edit` | 纯CRUD:修改 |
| 学员 | DELETE | `/train/student/{sIds}` | `remove` | `system:student:remove` | 纯CRUD:批量物理删除 |
| 课程 | GET | `/train/course/list` | `TrainCourseController.list` | `system:course:list` | 纯CRUD:分页列表 |
| 课程 | POST | `/train/course/export` | `export` | `system:course:export` | 纯CRUD:Excel导出 |
| 课程 | GET | `/train/course/{cId}` | `getInfo` | `system:course:query` | 纯CRUD:详情 |
| 课程 | POST | `/train/course` | `add` | `system:course:add` | 纯CRUD:新增 |
| 课程 | PUT | `/train/course` | `edit` | `system:course:edit` | 纯CRUD:修改 |
| 课程 | DELETE | `/train/course/{cIds}` | `remove` | `system:course:remove` | 纯CRUD:批量物理删除 |
| 开班计划 | GET | `/train/plan/list` | `TrainClassPlanController.list` | `system:plan:list` | 纯CRUD:分页列表 |
| 开班计划 | POST | `/train/plan/export` | `export` | `system:plan:export` | 纯CRUD:Excel导出 |
| 开班计划 | GET | `/train/plan/{planId}` | `getInfo` | `system:plan:query` | 纯CRUD:详情 |
| 开班计划 | POST | `/train/plan` | `add` | `system:plan:add` | 纯CRUD:新增 |
| 开班计划 | PUT | `/train/plan` | `edit` | `system:plan:edit` | 纯CRUD:修改 |
| 开班计划 | DELETE | `/train/plan/{planIds}` | `remove` | `system:plan:remove` | 纯CRUD:批量物理删除 |
| 宿舍 | GET | `/train/dorminfo/list`;别名 `/train/dormitory/list` | `TrainDormitoryInfoController.list` | `system:info:list` | 纯CRUD:分页列表 |
| 宿舍 | POST | `/train/dorminfo/export`;别名 `/train/dormitory/export` | `export` | `system:info:export` | 纯CRUD:Excel导出 |
| 宿舍 | GET | `/train/dorminfo/{dormId}`;别名 `/train/dormitory/{dormId}` | `getInfo` | `system:info:query` | 纯CRUD:详情 |
| 宿舍 | POST | `/train/dorminfo`;别名 `/train/dormitory` | `add` | `system:info:add` | 纯CRUD:新增 |
| 宿舍 | PUT | `/train/dorminfo`;别名 `/train/dormitory` | `edit` | `system:info:edit` | 纯CRUD:修改 |
| 宿舍 | DELETE | `/train/dorminfo/{dormIds}`;别名 `/train/dormitory/{dormIds}` | `remove` | `system:info:remove` | 纯CRUD:批量物理删除 |
| 宿舍权限 | GET | `/train/auth/list` | `TrainDormAuthController.list` | `system:auth:list` | 纯CRUD:分页列表 |
| 宿舍权限 | POST | `/train/auth/export` | `export` | `system:auth:export` | 纯CRUD:Excel导出 |
| 宿舍权限 | GET | `/train/auth/{authId}` | `getInfo` | `system:auth:query` | 纯CRUD:详情 |
| 宿舍权限 | POST | `/train/auth` | `add` | `system:auth:add` | 纯CRUD:新增授权记录;不下发设备 |
| 宿舍权限 | PUT | `/train/auth` | `edit` | `system:auth:edit` | 纯CRUD:修改授权记录 |
| 宿舍权限 | DELETE | `/train/auth/{authIds}` | `remove` | `system:auth:remove` | 纯CRUD:批量物理删除 |
| 教室 | GET | `/train/classroominfo/list`;别名 `/train/classroom/list`、`/train/info/list` | `TrainClassroomInfoController.list` | `system:info:list` | 纯CRUD:分页列表 |
| 教室 | POST | `/train/classroominfo/export`;同前缀别名 | `export` | `system:info:export` | 纯CRUD:Excel导出 |
| 教室 | GET | `/train/classroominfo/{classRoomId}`;同前缀别名 | `getInfo` | `system:info:query` | 纯CRUD:详情 |
| 教室 | POST | `/train/classroominfo`;同前缀别名 | `add` | `system:info:add` | 纯CRUD:新增 |
| 教室 | PUT | `/train/classroominfo`;同前缀别名 | `edit` | `system:info:edit` | 纯CRUD:修改 |
| 教室 | DELETE | `/train/classroominfo/{classRoomIds}`;同前缀别名 | `remove` | `system:info:remove` | 纯CRUD:批量物理删除 |
| 实训场地 | GET | `/train/site/list` | `TrainTrainingSiteController.list` | `system:site:list` | 纯CRUD:分页列表 |
| 实训场地 | POST | `/train/site/export` | `export` | `system:site:export` | 纯CRUD:Excel导出 |
| 实训场地 | GET | `/train/site/{siteId}` | `getInfo` | `system:site:query` | 纯CRUD:详情 |
| 实训场地 | POST | `/train/site` | `add` | `system:site:add` | 纯CRUD:新增 |
| 实训场地 | PUT | `/train/site` | `edit` | `system:site:edit` | 纯CRUD:修改 |
| 实训场地 | DELETE | `/train/site/{siteIds}` | `remove` | `system:site:remove` | 纯CRUD:批量物理删除 |
| 开班报到 | GET | `/train/report/list` | `TrainClassReportController.list` | `system:report:list` | 纯CRUD:分页列表 |
| 开班报到 | POST | `/train/report/export` | `export` | `system:report:export` | 纯CRUD:Excel导出 |
| 开班报到 | GET | `/train/report/{reportId}` | `getInfo` | `system:report:query` | 纯CRUD:详情 |
| 开班报到 | POST | `/train/report` | `add` | `system:report:add` | 纯CRUD:新增报到记录;非设备报到动作 |
| 开班报到 | PUT | `/train/report` | `edit` | `system:report:edit` | 纯CRUD:修改记录 |
| 开班报到 | DELETE | `/train/report/{reportIds}` | `remove` | `system:report:remove` | 纯CRUD:批量物理删除 |
| 电子班牌 | GET | `/train/board/list` | `TrainElectronicBoardController.list` | `system:board:list` | 纯CRUD:分页列表 |
| 电子班牌 | POST | `/train/board/export` | `export` | `system:board:export` | 纯CRUD:Excel导出 |
| 电子班牌 | GET | `/train/board/{boardId}` | `getInfo` | `system:board:query` | 纯CRUD:详情 |
| 电子班牌 | POST | `/train/board` | `add` | `system:board:add` | 纯CRUD:登记设备;非接入接口 |
| 电子班牌 | PUT | `/train/board` | `edit` | `system:board:edit` | 纯CRUD:修改设备记录 |
| 电子班牌 | DELETE | `/train/board/{boardIds}` | `remove` | `system:board:remove` | 纯CRUD:批量物理删除 |
| 学员签到 | GET | `/train/checkin/list` | `TrainStudentCheckinController.list` | `system:checkin:list` | 纯CRUD:分页列表 |
| 学员签到 | POST | `/train/checkin/export` | `export` | `system:checkin:export` | 纯CRUD:Excel导出 |
| 学员签到 | GET | `/train/checkin/{checkinId}` | `getInfo` | `system:checkin:query` | 纯CRUD:详情 |
| 学员签到 | POST | `/train/checkin` | `add` | `system:checkin:add` | 纯CRUD:新增记录;非设备签到协议 |
| 学员签到 | PUT | `/train/checkin` | `edit` | `system:checkin:edit` | 纯CRUD:修改记录 |
| 学员签到 | DELETE | `/train/checkin/{checkinIds}` | `remove` | `system:checkin:remove` | 纯CRUD:批量物理删除 |
| 成绩 | GET | `/train/scoreinfo/list`;别名 `/train/score/list` | `TrainScoreInfoController.list` | `system:info:list` | 纯CRUD:分页列表 |
| 成绩 | POST | `/train/scoreinfo/export`;别名 `/train/score/export` | `export` | `system:info:export` | 纯CRUD:Excel导出 |
| 成绩 | GET | `/train/scoreinfo/{scoreId}`;别名 `/train/score/{scoreId}` | `getInfo` | `system:info:query` | 纯CRUD:详情 |
| 成绩 | POST | `/train/scoreinfo`;别名 `/train/score` | `add` | `system:info:add` | 纯CRUD:新增;非批量导入/外部采集 |
| 成绩 | PUT | `/train/scoreinfo`;别名 `/train/score` | `edit` | `system:info:edit` | 纯CRUD:修改 |
| 成绩 | DELETE | `/train/scoreinfo/{scoreIds}`;别名 `/train/score/{scoreIds}` | `remove` | `system:info:remove` | 纯CRUD:批量物理删除 |
| 学习时长 | GET | `/train/duration/list` | `TrainStudyDurationController.list` | `system:duration:list` | 纯CRUD:分页明细,不是统计聚合 |
| 学习时长 | POST | `/train/duration/export` | `export` | `system:duration:export` | 纯CRUD:Excel导出 |
| 学习时长 | GET | `/train/duration/{durId}` | `getInfo` | `system:duration:query` | 纯CRUD:详情 |
| 学习时长 | POST | `/train/duration` | `add` | `system:duration:add` | 纯CRUD:新增;非外部上报接口 |
| 学习时长 | PUT | `/train/duration` | `edit` | `system:duration:edit` | 纯CRUD:修改 |
| 学习时长 | DELETE | `/train/duration/{durIds}` | `remove` | `system:duration:remove` | 纯CRUD:批量物理删除 |
| 学员画像 | GET | `/train/portrait/list` | `TrainStudentPortraitController.list` | `system:portrait:list` | 纯CRUD:分页列表,不生成画像 |
| 学员画像 | POST | `/train/portrait/export` | `export` | `system:portrait:export` | 纯CRUD:Excel导出 |
| 学员画像 | GET | `/train/portrait/{portraitId}` | `getInfo` | `system:portrait:query` | 纯CRUD:详情 |
| 学员画像 | POST | `/train/portrait` | `add` | `system:portrait:add` | 纯CRUD:手工新增画像记录 |
| 学员画像 | PUT | `/train/portrait` | `edit` | `system:portrait:edit` | 纯CRUD:修改记录 |
| 学员画像 | DELETE | `/train/portrait/{portraitIds}` | `remove` | `system:portrait:remove` | 纯CRUD:批量物理删除 |
## 3. 接口类型统计
| 类型 | 数量 | 结论 |
| --- | ---: | --- |
| 纯 CRUD/导出接口 | 84 | 14 组 × 6 个 |
| 业务动作接口 | 0 | 未发现开班、报到确认、补签审批、成绩发布、画像生成等动作 |
| 外部系统接入接口 | 0 | 未发现设备心跳、签到回调、门锁下发回执、学习记录/成绩采集 |
| 统计接口 | 0 | 前端成绩视图仍调用普通列表;学习时长 Controller 也只返回明细分页 |
| 培训导入接口 | 0 | 只有若依 `SysUserController` 有系统用户导入 |
## 4. 需要注意的映射现状
- 教室、宿舍、成绩 Controller 的多前缀别名属于当前未提交改动。
- 教室页面当前使用 `api/train/info.js`;另有未跟踪 `classroom.js`,形成两个 API 命名入口。
- 前端多数按钮权限使用 `train:*`,后端使用 `system:*`;宿舍、教室、成绩后端甚至共享 `system:info:*`。这会直接影响非超级管理员访问。
@@ -0,0 +1,72 @@
# 培训前端现状
## 1. 前端入口与路由机制
当前培训业务前端是 `build_ui/`:`package.json` 的 description 为“智慧培训管理平台”,`src/views/train` 和 `src/api/train` 均位于此处。
`build_ui/src/router/index.js` 没有静态培训菜单,只包含登录、首页、个人中心和若依少量隐藏动态路由。登录后,`build_ui/src/store/modules/permission.js` 调用 `build_ui/src/api/menu.js` 的 `GET /getRouters`,按后端 `sys_menu` 数据加载组件。
因此:
- 仓库代码可以确认“页面文件存在”。
- 仓库不能确认“当前数据库菜单存在且角色已授权”。
- `RuoYi-Vue/sql/ry_20250522.sql` 未发现任何 `train` 菜单/权限数据,精确菜单名称和路径只能通过实时 `sys_menu` 再核验。
## 2. 页面与 API 对照
表中的“菜单”表示该页面预期承载的功能名称,不表示已在实时 `sys_menu` 中确认。
| 菜单/功能 | 页面路径 | API | 当前完成度 | 备注 |
| --- | --- | --- | --- | --- |
| 教师信息 | `views/train/teacher/index.vue` | `api/train/teacher.js` → `/train/teacher` | CRUD页面存在,接通未证实 | 有列表/详情/增改删/导出;按钮用 `train:teacher:*`,后端用 `system:teacher:*` |
| 学员信息 | `views/train/student/index.vue` | `api/train/student.js` → `/train/student` | CRUD页面存在,接通未证实 | 同类权限不一致;无培训学员导入 |
| 课程信息 | `views/train/course/index.vue` | `api/train/course.js` → `/train/course` | CRUD页面存在,接通未证实 | 附件/资源仍为文本输入 |
| 开班计划 | `views/train/plan/index.vue` | `api/train/plan.js` → `/train/plan` | CRUD页面存在,接通未证实 | 不是课表或班级工作台 |
| 宿舍信息 | `views/train/dormitory/index.vue` | `api/train/dormitory.js` → `/train/dorminfo` | 部分存在 | 页面已修改、API未跟踪;无按钮权限与导出按钮 |
| 宿舍权限 | `views/train/auth/index.vue` | `api/train/auth.js` → `/train/auth` | CRUD页面存在,接通未证实 | 仅维护授权记录,不调用门锁系统 |
| 教室信息 | `views/train/classroom/index.vue` | 实际用 `api/train/info.js` → `/train/classroominfo` | CRUD页面存在,接通未证实 | `info.js`已修改;另有未跟踪`classroom.js`;别名未提交 |
| 实训场地 | `views/train/site/index.vue` | `api/train/site.js` → `/train/site` | CRUD页面存在,接通未证实 | 配套设备为文本字段 |
| 开班报到 | `views/train/report/index.vue` | `api/train/report.js` → `/train/report` | CRUD页面存在,接通未证实 | 表单手工录入,不是现场报到工作台 |
| 电子班牌 | `views/train/board/index.vue` | `api/train/board.js` → `/train/board` | CRUD页面存在,接通未证实 | 设备登记,不含心跳/内容发布/签到回调 |
| 学员签到 | `views/train/checkin/index.vue` | `api/train/checkin.js` → `/train/checkin` | CRUD页面存在,接通未证实 | 手工维护签到记录,无课次和设备流程 |
| 成绩信息 | `views/train/score/index.vue` | `api/train/score.js` → `/train/scoreinfo` | 部分存在 | 页面/API未跟踪;无权限指令与导出入口 |
| 学习时长 | `views/train/duration/index.vue` | `api/train/duration.js` → `/train/duration` | CRUD页面存在,接通未证实 | 是明细 CRUD,不是聚合统计工作台 |
| 学员画像 | `views/train/portrait/index.vue` | `api/train/portrait.js` → `/train/portrait` | CRUD页面存在,接通未证实 | 编辑指标/文本的表格,无画像计算和可视化 |
| 学员成绩档案 | `views/train/student-score/index.vue` | `api/train/score.js` 的列表 | 只读筛选页,未跟踪 | 按学号过滤同一 CRUD 列表,无专用统计接口 |
| 课程成绩总览 | `views/train/course-score/index.vue` | `api/train/score.js` 的列表 | 只读筛选页,未跟踪 | “综合评级”仅按 `examScore` 前端判断,不是三类成绩综合算法 |
| 自主学习设备 | `views/train/equipment/index.vue` | 无 | 占位页,未跟踪 | 文案宣称部分能力“已就绪”,代码没有相应设备接入 |
| 设备物联管理 | `views/train/extra/index.vue` | 无 | 占位页,未跟踪 | 仅 `el-result` 与跳转按钮 |
| 人物/人员页面 | `views/train/person/index.vue` | 使用旧角色/图谱相关逻辑 | 遗留页面 | 权限为 `train:role:*`,无对应当前培训 Controller |
| 图谱页面 | `views/train/character/graph.vue` | `api/train/character.js` | 遗留/未接通 | 当前后端未找到对应培训 Controller |
| 图表示例 | `views/train/character/charts.vue` | 旧接口/本地数据 | 演示性质 | 含 ECharts、随机数和历史地址,不能视为培训统计已实现 |
| 时间地点分析 | `views/train/analysis/timeAndAddress.vue` | 旧逻辑 | 遗留/未接通 | 无当前培训统计 Controller 对应 |
| 天气 | `views/train/weather/index.vue` | 旧逻辑 | 遗留/未接通 | 与 14 张培训表无对应关系 |
所有路径相对于 `build_ui/src/`。
## 3. 用户要求的页面能力确认
| 能力 | 结论 | 依据 |
| --- | --- | --- |
| 已有哪些菜单 | 无法从仓库确认实时菜单;路由由 `/getRouters` + `sys_menu` 动态生成 | `router/index.js`、`store/modules/permission.js`、`api/menu.js`;系统 SQL无train菜单 |
| 页面调用哪个 API | 14个主要页面都有对应API文件;教室实际使用`info.js` | 页面 import 与 `src/api/train/*.js` |
| 页面是否只是 CRUD | 14个核心业务页本质均为 CRUD;两个成绩衍生页只是列表筛选 | 页面 methods 与后端 Controller |
| 业务工作台 | 不存在 | 首页 `views/index.vue` 仅展示平台名称、版本和图片 |
| 统计图 | 培训业务统计图未实现 | `dashboard/*Chart.vue` 是若依示例;`character/charts.vue` 含随机/旧数据且无培训统计API |
| 画像 | 只有画像记录 CRUD | `views/train/portrait/index.vue` |
| 模拟设备页面 | 没有可运行模拟设备;只有设备管理 CRUD、遗留图表和两个占位页 | `board`、`equipment`、`extra` |
| 报到页面 | 有,但只是报到记录 CRUD | `views/train/report/index.vue` |
| 课程表页面 | 未发现 | `views/train`、router 与 API 搜索无 timetable/schedule/课程表实现 |
## 4. 权限与前端接通风险
大多数生成页面的按钮写成 `v-hasPermi="['train:<module>:<action>']"`,而对应 Controller 使用 `system:<module>:<action>`。教室页面用 `train:info:*`,宿舍/教室/成绩后端共用 `system:info:*`;宿舍与成绩当前页面又没有按钮权限指令。
超级管理员因若依通配权限可能掩盖此问题,但普通角色可能出现:菜单能见而按钮隐藏、按钮可见而请求被 403、三个模块共享过宽权限等现象。实际结果还取决于实时 `sys_menu.perms`,本次没有查询数据库。
## 5. 当前工作树状态对前端基线的影响
- `score.js`、成绩 CRUD 页面、学生成绩页、课程成绩页、两个占位页均未跟踪。
- `dormitory/index.vue` 已修改,`dormitory.js` 未跟踪。
- `info.js` 与 `vue.config.js` 已修改未提交。
- 因此当前文件系统能看到的页面能力高于最近一次提交 `83797f92` 中可复现的能力;在提交或交接前应先明确哪些文件属于正式基线。
@@ -0,0 +1,107 @@
# 权限与账号体系
## 1. 登录机制
当前使用若依标准的 Spring Security + JWT + Redis 登录链路:
1. `SysLoginController.login` 接收 `LoginBody`,调用 `SysLoginService.login`。
2. `SysLoginService` 通过 `AuthenticationManager` 完成用户名/密码认证,底层使用 `UserDetailsServiceImpl` 加载 `sys_user`。
3. 密码使用 `BCryptPasswordEncoder`;密码重试与锁定由 `SysPasswordService` 配合 Redis 缓存处理。
4. `TokenService.createToken` 生成 UUID,将完整 `LoginUser` 存入 Redis,并用 JJWT 生成 token。
5. 客户端在 `Authorization` 请求头携带 token;`JwtAuthenticationTokenFilter` 解析后把认证对象放入 Spring SecurityContext。
6. `SecurityConfig` 配置无状态会话,除白名单外的请求都需认证,并启用方法级权限。
代码依据:
- `RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysLoginController.java`
- `RuoYi-Vue/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java`
- `RuoYi-Vue/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java`
- `RuoYi-Vue/ruoyi-framework/src/main/java/com/ruoyi/framework/security/filter/JwtAuthenticationTokenFilter.java`
- `RuoYi-Vue/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java`
当前 `SysLoginService.login` 中验证码校验调用被注释掉;虽然 `/captchaImage`、配置项和缓存代码仍存在,实际登录服务当前不执行 `validateCaptcha`。这应在继续开发前作为当前事实确认,而不能只看登录页面是否显示验证码。
## 2. `sys_user`、`sys_role`、`sys_menu`
- `sys_user` 是认证主体,关联部门、岗位与角色;`SysUserMapper.xml`、`SysUserServiceImpl` 和 `SysUserController` 保留完整管理能力。
- `sys_role` 定义角色键、状态、菜单权限及 `data_scope`;通过 `sys_user_role` 关联用户,通过 `sys_role_menu` 关联菜单。
- `sys_menu` 同时承载目录/菜单/按钮、前端路由组件和 `perms` 权限字符串。`SysLoginController.getRouters` 调用 `SysMenuService.buildMenus` 返回动态路由。
- 初始化 SQL 只有若依内置 admin/common 角色及系统菜单;没有仓库内培训菜单 SQL。
## 3. 权限字符串如何定义和校验
后端 Controller 通过:
```java
@PreAuthorize("@ss.hasPermi('system:teacher:list')")
```
调用 Spring Bean `ss` 的 `PermissionService.hasPermi`。当前登录用户的权限集合由 `SysPermissionService.getMenuPermission` 从角色/菜单关系加载,管理员获得通配权限。前端 `v-hasPermi` 指令按相同字符串决定按钮显示。
问题在于培训权限没有统一:
- 后端 14 组使用 `system:teacher:*`、`system:student:*` 等 `system:*` 前缀。
- 前端生成页面普遍使用 `train:teacher:*`、`train:student:*` 等 `train:*` 前缀。
- 宿舍、教室、成绩三个后端 Controller 共用 `system:info:*`,权限粒度互相重叠。
- 宿舍和成绩当前页面没有按钮权限指令。
- 仓库没有培训 `sys_menu.perms` 数据可用于裁决哪一侧才是既定规范。
因此培训权限对超级管理员可能表面可用,对普通角色则很可能不能按预期工作。
## 4. 数据权限
若依数据权限框架存在:
- `@DataScope` 注解。
- `DataScopeAspect` 根据角色的 `data_scope` 拼接部门/本人范围 SQL。
- `SysRole` 保存数据范围配置。
当前 `@DataScope` 只在若依系统域的 `SysUserServiceImpl`、`SysRoleServiceImpl`、`SysDeptServiceImpl` 等位置使用;`ruoyi-train` 未发现 `@DataScope`,培训 Mapper SQL也没有部门、教师或班级范围条件。
所以“数据权限能力可复用”成立,“培训数据已经受数据权限保护”不成立。
## 5. 教师、学员与账号关联
- `TrainTeacher` 没有 `userId`/用户名字段,Mapper 不查询 `sys_user`。
- `TrainStudent` 同样没有 `userId`/用户名字段。
- `train_class_plan` 只有 `t_id`,表示计划中的授课教师工号;没有将当前登录 `sys_user` 映射到 `t_id` 的关系。
- 培训 Service/Mapper 没有基于当前登录人过滤计划、学员、成绩或签到。
结论:当前没有“教师只能查看自己所带班级”的实现,也没有学员只能查看本人数据的实现。
## 6. 操作日志
若依 `@Log` + `LogAspect` + 异步日志组件保留。培训 Controller 对以下动作加了日志:
- Excel 导出:`BusinessType.EXPORT`
- 新增:`INSERT`
- 修改:`UPDATE`
- 删除:`DELETE`
可记录的主要内容包括业务标题、业务类型、HTTP 方法、请求 URI、操作者、部门、IP、请求参数、返回结果、成功/失败状态、错误消息和耗时,并写入 `sys_oper_log`。
培训列表/详情读取通常没有 `@Log`。现有日志是接口操作记录,不是领域审计轨迹;没有修改前快照、字段级差异、报到/设备下发状态机流水或外部请求/回执详情。
代码依据:`LogAspect.java`、`SysOperLog.java`、`AsyncFactory.java` 及 14 个培训 Controller。
## 7. 导入导出权限
- 若依系统用户模块支持 `system:user:import`、`system:user:export`,并提供导入模板。
- `ExcelUtil` 是通用能力,可被培训模块复用。
- 14 个培训 Controller 都有后端 Excel 导出接口与 `*:export` 权限;多数前端页面也有导出按钮。
- 培训模块没有任何导入接口、导入模板接口或 `*:import` 权限。成绩的 `source_type=2 Excel批量导入` 只是字段枚举含义,不代表导入功能存在。
## 8. 是否需要重造权限系统
不需要。现有若依登录、用户、角色、菜单、按钮权限、数据权限与日志框架应直接复用。
继续开发需要在现有体系内补齐培训权限:统一权限命名;向 `sys_menu` 增加培训目录、页面和按钮权限;建立 `sys_user` 与教师/学员业务身份关系;明确教师、学员和管理员的数据范围规则;在培训查询入口应用数据权限或业务范围过滤。以上是后续设计方向,本次未修改任何系统表或代码。
## 9. 需要进一步确认的安全运行配置
- JWT secret、数据库账号口令和 Druid 控制台口令目前以明文配置存在;本报告不复述具体值。
- 登录页当前有未提交的默认口令改动。
- 验证码校验在登录服务中被注释。
- `SecurityConfig` 对上传资源路径存在匿名 GET 配置,需与实际公开文件范围共同评审。
这些事实会影响上线基线,但本次审计没有自动修复。
@@ -0,0 +1,103 @@
# 启动方式与运行环境
> 本次只整理配置和现有脚本,没有启动 Redis、后端、前端或数据库,没有执行 Maven/npm 构建。
## 1. 后端启动
### 现有方式
- Spring Boot 入口:`RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java`。
- Maven 父工程:`RuoYi-Vue/pom.xml`;可按 Maven 多模块方式构建 `ruoyi-admin`,但本次没有执行,因为会产生/更新 `target`。
- 当前工作树已有 `RuoYi-Vue/ruoyi-admin/target/ruoyi-admin.jar`。
- 未跟踪脚本 `start-local.sh` 会用以下方式启动现有 JAR:
```text
java --add-opens ... -jar RuoYi-Vue/ruoyi-admin/target/ruoyi-admin.jar
```
脚本将日志写到 `RuoYi-Vue/ruoyi-admin/backend.log`,并检查 `http://localhost:8090/captchaImage`。
### 默认端口与上下文
- 后端 HTTP 端口:`8090`。
- context path:`/`。
- 配置文件:`RuoYi-Vue/ruoyi-admin/src/main/resources/application.yml`。
## 2. 前端启动
当前培训前端目录:`build_ui/`。
`build_ui/package.json` 定义:
```text
npm run dev # vue-cli-service serve
npm run build:prod # 生产构建
npm run build:stage # staging 构建
npm run lint # ESLint;配置含 --fix,会修改文件,本次未执行
```
当前 `build_ui/node_modules/.bin/vue-cli-service` 存在。`build_ui/vue.config.js` 当前开发端口为 `8080`,代理 `/dev-api` 到 `http://localhost:8090` 并移除前缀。
`start-local.sh` 会先探测 8080;若未启动则在 `build_ui` 执行 `npm run dev`。该脚本会启动服务、创建目录并写日志,因此本次没有执行。
## 3. 数据库连接
| 项目 | 当前配置 |
| --- | --- |
| 配置文件 | `RuoYi-Vue/ruoyi-admin/src/main/resources/application-druid.yml` |
| 数据库 | KingbaseES |
| 驱动 | `com.kingbase8.Driver` / Maven `com.kingbase:kingbase8:8.6.0` |
| 数据库与 schema | `training` / `public` |
| 连接池 | Druid |
| 校验 SQL | `SELECT 1 FROM DUAL` |
主机、端口、用户名和口令直接写在配置文件中,没有通过环境变量注入;本报告不复述凭据。文件中还保留多组已注释的 MySQL/Kingbase历史连接信息。
## 4. Redis 要求
- 配置文件:`application.yml`。
- 当前地址:`localhost:6379`,database 0,无密码配置。
- 本机检测到 `/opt/homebrew/bin/redis-server`。
- Redis 用于 token 会话、登录状态续期、验证码缓存、密码错误计数、系统缓存和在线用户,因此正常登录链路需要 Redis。
- `start-local.sh` 会通过 `redis-cli ping` 探测并在需要时以 daemon 方式启动 Redis;本次未执行。
## 5. Profile 与环境文件
### 后端
- `spring.profiles.active: druid`。
- 存在 `application.yml` 与 `application-druid.yml`。
- 未发现独立的 `application-dev.yml`、`application-test.yml`、`application-prod.yml`。
- `application-druid.yml` 内通过注释区分开发/生产连接,并非可切换的 Spring profile。
### 前端
| 模式 | 文件 | API 前缀 |
| --- | --- | --- |
| development | `build_ui/.env.development` | `/dev-api` |
| staging | `build_ui/.env.staging` | `/stage-api` |
| production | `build_ui/.env.production` | `/prod-api` |
开发代理只对当前 `VUE_APP_BASE_API` 生效;生产/测试部署需要由外部 Web 服务器或网关将相应前缀转发到后端,仓库中未见完整部署配置。
## 6. 环境变量
- 后端 datasource、Redis、JWT secret 等均来自 YAML 固定值;未发现必须由操作系统提供的业务环境变量。
- 前端通过 `.env.*` 注入 `VUE_APP_TITLE`、`VUE_APP_BASE_API`、`ENV`,开发模式还设置 `VUE_CLI_BABEL_TRANSPILE_MODULES`。
- `vue.config.js` 可通过 `port` 或 `npm_config_port` 覆盖前端端口。
## 7. 当前机器工具链
| 工具 | 当前机器版本 | 项目目标/声明 | 说明 |
| --- | --- | --- | --- |
| Java | OpenJDK 21.0.2 | POM target/source 1.8 | 版本跨度较大;现有脚本加了若干 `--add-opens` |
| Maven | 3.9.2 | 未单独锁定 wrapper | 来自 IntelliJ 内置 Maven 路径 |
| Node | 22.23.2 | `>=8.9` | `vue.config.js` 有未提交 MD4 兼容补丁 |
| npm | 10.9.8 | `>=3.0.0` | 依赖目录存在,本次未安装/更新 |
| Redis Server | Homebrew 路径存在 | localhost:6379 | 本次未探测运行状态 |
## 8. 当前启动可验证程度
仓库内有后端 JAR和前端依赖,但不能据此确认它们与当前未提交源码一致。尤其当前源码有 Controller 路径、前端 API、端口和配置改动;现有 JAR可能早于这些修改。
本次未执行启动、健康检查、登录、API 调用或数据库查询,所以运行状态标记为“未验证”。
+103
View File
@@ -0,0 +1,103 @@
# Git 状态(只读快照)
> 审计开始时读取;没有执行 `reset`、`checkout`、`clean`、`restore`、stage、commit 或其他工作区修改命令。审计结束后会额外出现本目录下 12 个允许生成的 Markdown 文件。
## 1. 当前分支
```text
main
```
## 2. 最近 5 个提交
```text
83797f92 2026-09-10 15:40:10 +0800 add RuoYi-Vue
6d0feb95 2026-09-10 15:20:14 +0800 初始版本
b2486c37 2026-09-10 14:14:00 +0800 上传新文件
a1d771b7 2026-09-10 14:13:49 +0800 上传新文件
9815093e 2026-09-10 14:13:00 +0800 上传新文件
```
## 3. 审计开始时的已跟踪未提交修改
```text
M RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/train/TrainClassroomInfoController.java
M RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/train/TrainDormitoryInfoController.java
M RuoYi-Vue/ruoyi-admin/src/main/java/com/ruoyi/web/controller/train/TrainScoreInfoController.java
M RuoYi-Vue/ruoyi-admin/src/main/resources/application.yml
M RuoYi-Vue/ruoyi-admin/src/main/resources/logback.xml
M build_ui/src/api/train/info.js
M build_ui/src/views/login.vue
M build_ui/src/views/train/dormitory/index.vue
M build_ui/vue.config.js
```
`git diff --stat`:9 个文件,102 行新增、132 行删除。主要内容是教室/宿舍/成绩 Controller 路径别名、本地上传和日志路径、教室 API 路径、登录页默认口令、宿舍页面以及 Node 22/前端端口适配。
## 4. 审计开始时的未跟踪文件
### 系统/临时文件
```text
.DS_Store
RuoYi-Vue/.DS_Store
doc/.~学员管理系统功能分析_20260831.docx
doc/.~学员管理系统数据表设计_20260907_1_.docx
doc/.~学员管理系统相关需求.docx
```
### 代码与运行文件
```text
RuoYi-Vue/ruoyi-admin/D:/maven_repository/com/kingbase/kingbase8/8.6.0/kingbase8-8.6.0.jar
build_ui/src/api/train/classroom.js
build_ui/src/api/train/dormitory.js
build_ui/src/api/train/score.js
build_ui/src/views/train/course-score/index.vue
build_ui/src/views/train/equipment/index.vue
build_ui/src/views/train/extra/index.vue
build_ui/src/views/train/score/index.vue
build_ui/src/views/train/student-score/index.vue
start-local.sh
```
### 既有分析文档
```text
RuoYi-Vue/docs/kingbase_compatibility_audit.md
RuoYi-Vue/docs/kingbase_fact_check.md
doc/RailwaySystem 一期 P0 需求确认表 V0.1.md
doc/RailwaySystem 一期需求分析与业务基线 V0.1.md
doc/RailwaySystem 一期默认开发决策与需求假设 V0.1.md
doc/RailwaySystem 智慧培训系统一期 PRD V0.9.md
doc/学员管理系统功能分析_20260831.md
doc/学员管理系统数据表设计_20260907_1_.md
doc/学员管理系统相关需求.md
doc/智慧培训系统一期详细开发说明书.md
doc/elk.bundled.js
doc/railwaysystem.html
```
## 5. 本次审计新增的允许文件
```text
docs/codebase-audit/00_project_overview.md
docs/codebase-audit/01_project_tree.md
docs/codebase-audit/02_training_modules_inventory.md
docs/codebase-audit/03_database_current_state.md
docs/codebase-audit/04_api_inventory.md
docs/codebase-audit/05_frontend_inventory.md
docs/codebase-audit/06_security_and_permissions.md
docs/codebase-audit/07_runtime_and_environment.md
docs/codebase-audit/08_git_status.md
docs/codebase-audit/09_reusable_ruoyi_capabilities.md
docs/codebase-audit/10_gap_and_conflict_analysis.md
docs/codebase-audit/11_executive_summary.md
```
## 6. 仓库卫生观察
- Git 已跟踪约 116,171 个 `node_modules*` 下的依赖文件;这使仓库体积、diff、跨平台复现和依赖更新成本显著上升。
- POM 的 Windows 绝对输出路径 `D:\maven_repository\...` 在 macOS 工作区生成了字面 `D:` 目录和未跟踪 JAR。
- Git remote 配置中包含内联认证信息;本报告将其记为 `[REDACTED_SECRET]`,不复述远端地址。应由仓库负责人单独处理凭据和远端配置。
- 当前可见前端能力有一部分只存在于未跟踪文件;如果在其他机器从 `main` 克隆,将缺少这些页面/API。
@@ -0,0 +1,57 @@
# 可复用的若依能力
## 1. 分类结果
| 能力 | 分类 | 当前代码依据 | 培训业务现状 |
| --- | --- | --- | --- |
| 登录 | 可以直接复用 | `SysLoginController`、`SysLoginService`、`UserDetailsServiceImpl` | 登录链路完整;验证码校验当前被注释,运行仍需核验 |
| RBAC | 可以直接复用 | `sys_user`、`sys_role`、用户角色/角色菜单 Mapper与Service | 无需另建账号角色系统 |
| 菜单权限 | 需要扩展 | `SysMenuController`、`SysMenuServiceImpl`、`GET /getRouters` | 框架可复用;仓库无培训菜单初始化数据 |
| 按钮权限 | 需要扩展 | 后端 `@PreAuthorize("@ss.hasPermi(...)")`、前端 `v-hasPermi` | 训练前后端权限前缀不一致,三个模块共用`system:info:*` |
| 操作日志 | 可以直接复用 | `@Log`、`LogAspect`、`SysOperLog`、异步日志管理 | 培训增改删/导出已标注;业务状态轨迹仍需扩展 |
| 数据权限 | 需要扩展 | `@DataScope`、`DataScopeAspect`、角色`data_scope` | 培训 Service/Mapper 尚未接入,教师/学员范围不存在 |
| 字典 | 可以直接复用 | `SysDictTypeController`、`SysDictDataController`、前端字典组件 | 培训状态字段目前多为数字输入/注释,未见业务字典SQL |
| 定时任务 | 需要扩展 | `ruoyi-quartz`、`SysJobController`、`sys_job`、`quartz.sql` | 框架保留;未见培训任务,如授权失效/设备离线/画像刷新 |
| 文件上传 | 可以直接复用 | `CommonController` 的 `/common/upload`、`/common/uploads`、下载接口;前端上传组件 | 课程附件字段尚未与上传结果建立结构化业务关系 |
| Excel 导入 | 需要扩展 | `ExcelUtil`、`SysUserController.importData/importTemplate` | 通用能力存在;培训无导入 Controller/权限/错误处理 |
| Excel 导出 | 可以直接复用 | `ExcelUtil`、培训14个Controller的`/export` | 后端全部存在;宿舍/成绩当前页面无导出入口 |
| 分页 | 可以直接复用 | `BaseController.startPage`、PageHelper、`TableDataInfo` | 14个列表全部使用;Kingbase方言配置仍需确认 |
| 统一返回格式 | 可以直接复用 | `AjaxResult`、`TableDataInfo`、`BaseController.toAjax` | 培训 Controller 已使用 |
| 异常处理 | 可以直接复用 | `GlobalExceptionHandler`、认证/业务异常体系 | 通用能力存在;培训尚少领域校验,因此领域错误语义不足 |
| 代码生成 | 需要进一步确认 | `ruoyi-generator`、`GenController`、Velocity模板 | 模块完整,但元数据查询含 MySQL 语义,Kingbase可用性未验证 |
| 系统配置 | 可以直接复用 | `SysConfigController/Service/Mapper`、`sys_config` | 可保存培训参数;不应代替领域表 |
| 通知 | 需要扩展 | `SysNoticeController`、`sys_notice` | 当前是通知公告 CRUD,不是站内信/短信/设备推送工作流 |
## 2. 直接复用时的边界
### 登录与账号
复用 `sys_user`、`sys_role`、`sys_menu` 和现有 token,不再建设第二套用户名密码、角色菜单或登录页面。培训身份需要新增业务关联,而不是复制系统账号表。
### 权限
若依权限机制本身完整,但培训权限数据和命名尚未形成可复现基线。应先确认统一的 `train:<resource>:<action>` 或既有命名,再配置菜单/按钮;当前 `system:*` 与 `train:*` 并存不能视为已接通。
### 日志
现有 `@Log` 足以覆盖管理端接口操作。设备下发、回调、报到、成绩发布等需要可追溯状态时,应在领域内扩展业务流水;不要把 `sys_oper_log` 当作所有业务状态历史。
### 数据权限
现有框架适合部门/本人范围,但“教师只能看所带班级”“学员只能看本人”依赖教师/学员与 `sys_user` 的映射及参训/授课关系。当前模型没有这些关系,不能只加一个 `@DataScope` 就完成。
### Excel
培训实体已有 `@Excel` 注解,导出接口已生成。导入还需要模板、字段校验、错误行反馈、重复策略、事务边界和权限;成绩/学员字段中的“可导入”描述不是实现。
### 文件
通用上传下载已经具备。课程的文档/视频/模型字段目前只是字符串,应先决定复用上传后的相对路径、资源 ID或专门资源表,然后再接业务流程。
### 定时任务
Quartz 管理和日志可直接承载未来任务,但仓库尚无培训 Job。后续若需要授权到期、设备离线检测、画像周期计算或同步重试,可以扩展现有 `ruoyi-quartz`,无需新增调度平台。
## 3. 静态存在与运行正常的区别
上述分类说明代码层是否可复用,不代表已在当前 Kingbase实例和当前未提交前端上运行验证。尤其 PageHelper方言、系统 Mapper SQL、代码生成器元数据 SQL、培训菜单权限和业务表实存状态都需要先验证。
@@ -0,0 +1,303 @@
# 当前实现与未来业务设计的冲突点
> 本文件只报告基于当前代码能确认的模型/接通冲突,不提供重构代码,也不假定未入库系统的行为。
## 1. 开班计划只能直接挂一个课程和一个教师
**当前实现**
`TrainClassPlan`/`train_class_plan` 只有一个 `c_id` 和一个 `t_id`,Mapper 为单表 CRUD。
↓
**潜在问题**
一个培训班无法表达多门课程、多名教师、课程顺序和每次上课的时间地点。
↓
**可能影响哪些业务**
课程表、教师排课、教室/场地冲突检查、按课次签到、课程成绩和班级统计。
## 2. 没有参训/报名关系
**当前实现**
学员是独立主数据;报到、签到、成绩、时长、画像各自直接保存 `student_id + plan_id`。代码与表设计中没有 enrollment/plan_student/班级学员关系。
↓
**潜在问题**
无法明确某学员是否被录取、退训、结业或属于哪一期培训,也无法以一份稳定名单约束后续记录。
↓
**可能影响哪些业务**
报名审核、班级花名册、报到资格、住宿分配、签到名单、成绩发布、结业证书与教师数据权限。
## 3. 签到没有课次实体
**当前实现**
`train_student_checkin` 有 `plan_id`、`c_id`、`lesson_start_time`、`lesson_end_time`,但没有 `lesson_id`;每条学生签到重复保存课次时间。
↓
**潜在问题**
无法稳定标识一次上课,课程时间调整会产生历史不一致,也难以建立“一人一课次一次有效签到”的唯一规则。
↓
**可能影响哪些业务**
课程表、二维码签到、设备签到幂等、迟到/早退判断、补签、按课次出勤统计。
## 4. 学员模型偏高校学籍,缺少培训账号和身份信息
**当前实现**
`TrainStudent` 主要字段是院系、专业、班级、学号;没有 `sys_user` 关联、身份证、人脸特征/资源、人员状态或来源单位等代码字段。
↓
**潜在问题**
业务身份与登录身份无法对应,现场报到和门锁人脸授权的数据来源不完整;非高校培训场景也难以表达。
↓
**可能影响哪些业务**
学员登录、自助查询、现场报到、门禁授权、教师查看班级、跨单位培训。
## 5. 教师模型不能支撑账号、资质和授课范围
**当前实现**
`TrainTeacher` 只有工号、姓名、院系、职称、联系方式等基础字段;没有 `sys_user` 关联、启停状态、资质证书、可授课程关系。计划只保存一个 `t_id`。
↓
**潜在问题**
无法从当前登录用户确定教师身份,也无法约束其可查看班级或可教授课程。
↓
**可能影响哪些业务**
教师工作台、教师数据权限、排课、资质审查、课程授权。
## 6. 宿舍只有房间聚合,没有独立床位
**当前实现**
`train_dormitory_info` 保存 `bed_total` 和 `bed_used`;`bed_no` 只作为 `train_dorm_auth` 的自由文本字段存在。
↓
**潜在问题**
无法可靠管理每张床的状态、性别/房间约束、占用唯一性、维修与预留;`bed_used` 容易与授权记录不一致。
↓
**可能影响哪些业务**
自动分房、床位冲突、容量统计、换房、退宿、住宿看板。
## 7. 住宿分配与门锁人脸授权耦合
**当前实现**
`train_dorm_auth` 同时保存学员住宿位置、床位号、授权起止时间和 `face_sync_status`。
↓
**潜在问题**
业务住宿事实与设备同步状态无法独立演进;没有下发流水、重试次数、失败原因、设备回执和撤权记录。
↓
**可能影响哪些业务**
分房、换房、门禁下发、失败补偿、到期撤权、审计追踪。
## 8. 报到记录同时承担资源分配
**当前实现**
`train_class_report` 同一行保存报到事件及 `alloc_dorm_id`、`alloc_classroom_id`、`alloc_site_id`。Service 只是单表新增/修改,没有事务编排。
↓
**潜在问题**
一次报到被迫绑定三类资源,无法记录多次尝试、资源调整或单独失败,也没有容量和冲突校验。
↓
**可能影响哪些业务**
现场报到、住宿分配、教室/场地调度、设备异常恢复、操作审计。
## 9. 成绩固定三列且没有计算/发布规则
**当前实现**
`train_score_info` 固定为 `course_score`、`train_score`、`exam_score`;没有权重、规则版本、综合分、发布状态或审批字段。未跟踪的课程成绩页只按 `examScore` 显示“综合评级”。
↓
**潜在问题**
无法解释综合结果,课程差异化考核和规则变更会直接影响历史成绩可追溯性;页面名称可能造成错误理解。
↓
**可能影响哪些业务**
成绩导入、综合成绩、排名、补考、结业判定、画像和报表。
## 10. “成绩可导入/外部采集”目前只是字段枚举
**当前实现**
`source_type` 注释包含手工、Excel、外部接口,但培训 Controller 只有单条 CRUD和导出,没有导入、回调或批处理接口。
↓
**潜在问题**
数据来源字段会被人工填写,却没有与真实采集渠道、批次、错误行和幂等键绑定。
↓
**可能影响哪些业务**
Excel 批量导入、VR/3D/实操系统对接、数据追溯、重复数据处理。
## 11. 学习时长“统计”仍是人工可编辑明细
**当前实现**
`train_study_duration` 同时存起止时间和 `study_seconds`;Controller 可手工增改删,未见计算校验、外部事件 ID、同步状态或汇总 SQL。
↓
**潜在问题**
同一记录的时间差与秒数可能不一致,外部重传可能重复入库,汇总结果缺少可信来源。
↓
**可能影响哪些业务**
学习达标、时长报表、设备对接、学员画像、考核结果。
## 12. 画像是手工 CRUD 快照,没有生成链路
**当前实现**
`train_student_portrait` 直接保存总时长、平均成绩、签到率、标签和文本;Service 不读取签到、成绩、时长表,前端只提供编辑表格。
↓
**潜在问题**
画像指标可能与来源明细不一致,无法说明何时、按何规则生成,也不能回溯历史版本。
↓
**可能影响哪些业务**
学员评价、推荐、教学改进、结业报告、管理驾驶舱。
## 13. 设备表有状态字段,但没有设备协议接口
**当前实现**
电子班牌保存最后心跳和在线状态,宿舍授权保存人脸同步状态;后端只有管理 CRUD。设备相关前端另有两个无 API 的占位页。
↓
**潜在问题**
页面可编辑“在线/已下发”等结果字段,却没有系统生成这些状态的接入、认证、回执和超时逻辑。
↓
**可能影响哪些业务**
班牌内容发布、签到、人脸门锁、设备在线监控、故障告警。
## 14. 培训权限前后端不一致
**当前实现**
前端多数使用 `train:*`,后端使用 `system:*`;宿舍、教室、成绩后端共用 `system:info:*`;仓库没有培训菜单 SQL。
↓
**潜在问题**
普通角色的按钮显示与后端授权可能不一致,三个资源也无法独立授权;管理员通配权限会隐藏问题。
↓
**可能影响哪些业务**
所有培训菜单、增改删、导入导出和角色验收。
## 15. 培训查询没有数据范围
**当前实现**
`ruoyi-train` 无 `@DataScope`,教师/学员也未关联 `sys_user`,Mapper 列表是单表条件查询。
↓
**潜在问题**
拥有列表权限的普通账号可能看到所有培训数据,无法实现“教师只看所带班级”或“学员只看本人”。
↓
**可能影响哪些业务**
教师门户、学员门户、成绩与画像隐私、组织隔离。
## 16. 培训表没有可执行数据库基线
**当前实现**
14 张表只有 DOCX 设计和 Mapper引用;仓库只有若依系统/Quartz SQL,没有培训 DDL、迁移、索引、外键或菜单脚本。
↓
**潜在问题**
不同环境可能靠人工建表而漂移,代码中字段对齐不代表真实数据库一致,也无法在新环境复现。
↓
**可能影响哪些业务**
所有培训 CRUD、联调、测试、部署、回滚和交接。
## 17. Kingbase 配置与 MySQL 方言并存
**当前实现**
Datasource 使用 Kingbase 8.6.0,但 PageHelper 为 mysql;若依 Mapper/生成器和系统 SQL使用 MySQL 特有语法,设计文档也含 `AUTO_INCREMENT`、`ON UPDATE CURRENT_TIMESTAMP`。
↓
**潜在问题**
是否可运行取决于 Kingbase兼容模式和具体版本;部分系统能力可能启动正常但在特定查询/生成/数据权限路径失败。
↓
**可能影响哪些业务**
分页、用户/角色/菜单查询、数据权限、Quartz、代码生成、初始化部署和数字主键回填。
## 18. DATETIME 在接口展示中被格式化为日期
**当前实现**
开班起止、报到、签到、课次、授权、学习起止/同步、导入、心跳等 Java `Date` 字段普遍使用 `@JsonFormat(pattern="yyyy-MM-dd")`,Excel也只导出日期。
↓
**潜在问题**
时分秒在 JSON/Excel 表示中丢失,时间型业务无法准确展示和回传,前端日期选择器也多按日处理。
↓
**可能影响哪些业务**
课表、报到时间、迟到早退、门禁授权时段、设备心跳、学习时长和数据同步审计。
## 19. 字符串主键没有代码生成策略
**当前实现**
8 个字符串主键只在非空时由 Mapper插入,没有 UUID/雪花/业务编号生成服务;生成页面让用户填写主键。
↓
**潜在问题**
空值是否可插入取决于数据库默认值,手工编号又可能冲突;不同入口难以统一编号规则。
↓
**可能影响哪些业务**
教师、学员、课程、计划、宿舍、教室、场地、班牌的新建和外部同步。
## 20. 当前工作树不是稳定可复现基线
**当前实现**
存在 9 个已跟踪修改文件、多项未跟踪业务页面/API、未跟踪启动脚本,以及大量已跟踪依赖文件。现有 JAR也不保证与当前源码一致。
↓
**潜在问题**
高级负责人、测试和部署人员从 `main` 获取的代码与本机可见能力不同,难以判断哪个状态应作为后续开发起点。
↓
**可能影响哪些业务**
所有开发任务拆分、缺陷复现、联调、发布和责任边界。
+138
View File
@@ -0,0 +1,138 @@
# RailwaySystem 代码基线审计 Executive Summary
## 1. 当前工程一句话描述
RailwaySystem 是基于 RuoYi-Vue 3.9.1、Spring Boot 2.5.15、Vue 2 与 KingbaseES 配置的前后端分离培训管理项目;当前已形成 14 组培训数据 CRUD 脚手架,但数据库对象、菜单权限、Kingbase兼容和业务闭环尚无仓库证据证明已经端到端跑通。
## 2. 当前技术栈
- 后端:Java 8 编译目标、Spring Boot 2.5.15、Spring Framework 5.3.39、Spring Security 5.7.14、MyBatis XML、PageHelper 1.4.7、Druid 1.2.27、JJWT 0.9.1、Redis、Quartz、Apache POI。
- 数据库:当前 datasource 指向 KingbaseES,驱动 `com.kingbase:kingbase8:8.6.0`;MySQL驱动和多处 MySQL方言仍保留。
- 前端:Vue 2.6.12、Vue Router 3.4.9、Vuex 3.6.0、Element UI 2.15.12、Axios 0.24.0、ECharts 5.4.0、Vue CLI 4.4.6。
- 模块:`ruoyi-admin`、`ruoyi-framework`、`ruoyi-system`、`ruoyi-quartz`、`ruoyi-generator`、`ruoyi-common`、`ruoyi-train`,以及培训前端 `build_ui`。
- 当前机器:Java 21.0.2、Maven 3.9.2、Node 22.23.2、npm 10.9.8;源码目标与本机工具链有明显年代跨度。
## 3. 已经存在的培训模块
共 14 组:
1. 教师 `train_teacher`
2. 学员 `train_student`
3. 课程 `train_course`
4. 开班计划 `train_class_plan`
5. 宿舍 `train_dormitory_info`
6. 宿舍权限/门锁授权 `train_dorm_auth`
7. 教室 `train_classroom_info`
8. 实训场地 `train_training_site`
9. 开班报到 `train_class_report`
10. 电子班牌 `train_electronic_board`
11. 学员签到 `train_student_checkin`
12. 多类型成绩 `train_score_info`
13. 学习时长 `train_study_duration`
14. 学员画像 `train_student_portrait`
每组都有 Entity、Mapper接口、Mapper XML、Service接口、ServiceImpl和 Controller。当前工作树也有对应前端 CRUD页面和 API,但成绩、宿舍等部分文件尚未跟踪。
## 4. 已经真正跑通的功能
本次审计没有启动服务或连接数据库,因此**不能确认任何培训模块已经端到端跑通**。
能够确认的只是代码能力:
- 若依登录、RBAC、动态菜单、日志、分页、统一返回、异常处理、Excel、上传、Quartz和代码生成框架都在仓库中。
- 14 组培训后端静态 CRUD调用链完整。
- 当前文件系统中 14 组前端页面/API可找到。
- 当前存在后端 JAR和前端依赖目录,但它们不保证与未提交源码一致,也不能替代运行验证。
## 5. 目前只是 CRUD、尚未形成业务闭环的部分
14 个培训 Controller 合计 84 个映射,全部属于列表、导出、详情、新增、修改、删除。没有发现:
- 开班/结班、报名审核、参训名单等业务动作。
- 课次、排课、课程表和资源冲突校验。
- 现场身份证/人脸报到流程。
- 电子班牌心跳、内容发布、签到回调。
- 门锁人脸下发、回执、重试、撤权。
- Excel成绩/学员导入、外部成绩与学习记录采集。
- 综合成绩计算、发布、锁定和追溯。
- 画像计算规则与生成任务。
- 培训统计聚合接口或真正业务工作台。
## 6. 当前数据库现状
- 代码和设计文档一致指向 14 张 `train_*` 业务表,但仓库没有这些表的可执行 DDL、迁移或种子数据。
- 本次未查询实时数据库,不能确认表是否存在、字段/索引/外键/默认值是否一致。
- 14 个 Entity 都继承 BaseEntity,但表的公共字段不统一;业务表主要用 `create_user`,并未统一使用若依 `create_by/update_by`。
- 所有培训删除都是物理删除,没有 `del_flag` 逻辑删除。
- 数字主键依赖 JDBC generated keys,设计写为 MySQL `AUTO_INCREMENT`;字符串主键没有代码生成策略。
- `sys_*` 表继续支撑若依系统功能,不应修改结构或复制一套权限系统。
- 当前 Kingbase驱动配置与 MySQL方言并存,是上线/联调前的关键验证项。
## 7. 当前前端现状
- `build_ui` 是培训前端,14 个核心模块页面本质都是 CRUD。
- 首页只是“基地学员管理平台 V1.0”信息卡,不是业务工作台。
- 报到、签到、画像、学习时长、电子班牌均只有数据维护页,没有对应业务流程。
- 两个未跟踪成绩页只是对同一成绩列表做筛选;课程成绩页把 `examScore` 单列当作评级依据。
- `equipment`、`extra` 是未跟踪占位页;旧 `character`/`analysis` 页面含随机或遗留接口,不能算培训统计已实现。
- 未发现课程表页面。
- 培训路由依赖实时 `sys_menu` 动态加载,仓库没有培训菜单 SQL,所以现有菜单无法由代码仓库确认。
## 8. 当前权限体系
- 登录主体是 `sys_user`,角色为 `sys_role`,菜单/按钮权限来自 `sys_menu.perms`。
- Controller 用 `@PreAuthorize("@ss.hasPermi(...)")`,前端用 `v-hasPermi`。
- 培训前端多数使用 `train:*`,后端使用 `system:*`,权限码不一致。
- 宿舍、教室、成绩三个 Controller共用 `system:info:*`,授权粒度冲突。
- 教师和学员均未关联 `sys_user`。
- 培训模块未使用 `@DataScope`,不存在“教师只能看所带班级”或“学员只能看本人”的代码。
- 培训增改删和导出已使用若依操作日志;列表/详情和领域状态变化没有专门审计轨迹。
## 9. 可以直接复用的若依能力
可以直接复用:登录、用户/角色基础 RBAC、操作日志、字典框架、文件上传下载、Excel工具、分页、统一返回、异常处理、系统配置。
需要在现有框架上扩展:培训菜单/按钮权限、培训数据权限、培训 Excel导入、培训 Quartz任务、业务操作流水、公告之外的消息/设备通知。
需要进一步确认:代码生成器、若依系统 Mapper、PageHelper、Quartz和初始化 SQL在目标 Kingbase模式下的完整兼容性。
## 10. 当前最重要的10个代码/业务冲突
1. **没有可执行培训数据库基线**:14 张表只有设计文档与 Mapper,无 DDL/迁移,实际数据库状态不可复现。
2. **Kingbase与MySQL方言混用**:Kingbase驱动已启用,但 PageHelper、系统 Mapper、生成器和 SQL仍含 MySQL语法。
3. **培训权限未接通**:前端 `train:*` 与后端 `system:*` 不一致,三个模块共用 `system:info:*`,也没有菜单初始化 SQL。
4. **无账号业务身份和数据范围**:教师/学员不关联 `sys_user`,没有教师班级范围和学员本人范围。
5. **无参训关系**:学员与培训计划之间没有正式 enrollment/花名册实体,后续业务各自直接引用两个 ID。
6. **无课次/课表**:计划只能关联一个课程与一个教师,签到以重复的起止时间代替课次 ID。
7. **报到只是 CRUD且混合资源分配**:没有设备报到流程,报到、宿舍、教室、场地绑定在同一记录。
8. **住宿和门锁授权耦合**:没有独立床位、分配状态、设备下发流水和失败补偿。
9. **成绩/时长/画像没有计算与采集闭环**:字段存在,但导入、外部采集、综合算法、画像生成均不存在。
10. **工作树不是稳定基线**:关键路径适配和多个页面/API未提交,当前 JAR与源码也未证明一致。
## 11. 如果继续开发,建议首先确认的代码层问题
1. 确定以当前工作树还是提交 `83797f92` 为开发基线,逐项归属现有未提交/未跟踪文件。
2. 获取只读数据库结构快照,核验 14 张业务表、系统表、主键、索引、外键、默认值和 Kingbase兼容模式。
3. 建立可版本管理的培训 DDL/迁移与菜单权限 SQL基线;不要修改 `sys_*` 表结构。
4. 统一培训 API前缀与权限字符串,取消 `system:info:*` 的跨模块复用,并验证普通角色。
5. 明确教师/学员与 `sys_user` 的关联,以及教师、学员、管理员的数据可见范围。
6. 在扩展页面前确认参训关系、课次/课表、独立床位等基础领域关系;这些关系决定报到、签到、住宿、成绩和画像的可实现性。
7. 在目标 Kingbase环境逐项验证 PageHelper、若依系统查询、数据权限、代码生成、Quartz和 generated keys。
8. 统一 DATETIME 的 JSON/Excel格式;当前多个时间字段只输出 `yyyy-MM-dd`。
9. 明确字符串主键生成规则与物理删除/逻辑删除策略。
10. 区分管理端 CRUD、业务动作、外部接入和统计接口,避免继续用可编辑状态字段代替真实流程。
## 12. 需要高级技术负责人进一步评审的文件路径
优先级从高到低:
1. `docs/codebase-audit/10_gap_and_conflict_analysis.md`:决定后续领域模型和开发顺序。
2. `docs/codebase-audit/03_database_current_state.md`:确认 Kingbase、DDL、主键、公共字段、物理删除和系统表边界。
3. `docs/codebase-audit/06_security_and_permissions.md`:确认权限命名、账号关联和数据范围。
4. `docs/codebase-audit/02_training_modules_inventory.md`:掌握14组 CRUD的实际代码边界。
5. `docs/codebase-audit/08_git_status.md`:确定可复现基线和未提交文件归属。
6. `RuoYi-Vue/ruoyi-admin/src/main/resources/application-druid.yml`:数据库连接与兼容配置;含敏感信息,评审时注意脱敏。
7. `RuoYi-Vue/ruoyi-admin/src/main/resources/application.yml`:端口、Redis、JWT、MyBatis和 PageHelper配置。
8. `RuoYi-Vue/ruoyi-system/src/main/resources/mapper/system/` 与 `RuoYi-Vue/ruoyi-generator/src/main/resources/mapper/generator/`:Kingbase兼容重点。
9. `RuoYi-Vue/ruoyi-train/src/main/resources/mapper/train/`:14张表的当前实际 SQL契约。
10. `doc/学员管理系统数据表设计_20260907_1_.docx`:当前14表设计来源。