简介:这是一套面向信息系统开发实训的矿山安全管理系统后台工程,采用Java技术栈,兼顾人工智能在风险预测、异常检测中的应用思路,适用于系统分析与设计课程项目、毕业设计及Java Web后端初学者。压缩包共79个文件,以70个Java源文件为主,覆盖后台核心业务逻辑、Servlet/JSP处理、数据访问与接口集成;辅以Gradle构建配置、properties配置文件、XML映射和Windows启动脚本,整体仅118KB,目录结构清晰,便于直接导入工程展开学习。目前已有75人学习浏览,适合对照矿山业务流程理解需求分析、系统架构与数据库设计的落地过程。通过该工程,读者可快速掌握Web后端从配置、编码到构建运行的全链路写法,并了解如何结合人工智能模块辅助完成安全预警、用户管理、数据统计等典型功能,为后续真实项目开发提供可复用的蓝本。
1. 从实训交付的 zip 开始:这套后台究竟在解决什么问题
在信息系统开发实训里,拿来交差的往往不是代码仓库,而是一个 zip 压缩包,名称就写成“矿山安全管理系统,后台”。压缩包里面装着后台管理端的源码、数据库脚本和部署说明。决定这门课成绩的,往往不是谁代码写得漂亮,而是谁能用最短的时间把它跑通、读透,再改出一两个能演示的功能。
这篇笔记就围绕这类后台 zip 展开:解压之后怎么检查目录,技术栈怎么判断,数据库和服务端要改哪些配置,业务表怎么读,部署中为什么总在一个地方翻车。读者是刚拿到实训压缩包准备写报告、准备答辩的开发者,以及打算照着这类项目练手做个人作品的人。
2. 拆解矿山安全后台 zip:目录结构、技术栈与交付物检查
拿到 zip 先别急着双击解压,也别急着往 IDEA 里拖。把它当成一个交付物来拆,拆清楚了再动手,能省下大半个晚上。实训项目打包有固定的习惯:前端、后端、数据库脚本和说明文档各自独立成目录,最后压成一个 zip。你看到的“后台”两个字,一般意味着这一包主要是管理端,不包含 App 或小程序端。
2.1 压缩包里那几样东西:前端、后端、数据库脚本和文档
我经手过的实训后台压缩包,目录命名各不相同,但骨架高度相似。常见的结构是下面这张表,遇到不同名字时对照着认就行:
| 常见目录名 | 里面装的是什么 | 在部署里起什么作用 |
|---|---|---|
| backend / server / api | Spring Boot 或 SSM 工程 | 提供登录、权限、业务接口 |
| frontend / web / ui | Vue 工程,配 Element Plus 居多 | 后台管理界面 |
| sql / database / db | 建库建表语句和初始化数据 | 让后台有数据可跑 |
| README.md / 部署说明.txt | 环境要求、默认账号、启动顺序 | 部署时第一个该看的东西 |
| 需求文档 / 实训报告模板 | 业务说明和报告要求 | 写报告、做答辩的素材 |
判断这些目录靠什么?不是靠猜,是看特征文件。backend 里找 pom.xml 或 build.gradle,frontend 里找 package.json,sql 目录里找 .sql 文件。如果一整个 zip 里只有一个工程目录而没有 sql 目录,那就去 application.yml 里找 spring.datasource 指向的初始化脚本,很多后台会把建表语句放在 resources 下的 db 目录里。
拿到压缩包后先列清单是个好习惯,不要凭感觉解压到桌面就开跑。清单能告诉你三件事:这包里有没有缺件、前后端是不是齐全、数据库脚本到底在哪个角落。缺了数据库脚本的项目,后面不管怎么配都起不来,早发现早找人补。
2.2 实训后台为什么常见这套技术栈:前后端分离与单体模板二选一
矿山安全管理系统这类后台,业务本质是“表单加报表加审批”,数据模型复杂但计算量不大。这种场景下,Java 系后端加 MySQL 是实训项目里最保守也最顺手的组合。Spring Boot 的自动配置让新手不用碰繁琐的 XML,MyBatis 或 JPA 负责和表结构打交道,前端用 Vue 3 加 Element Plus 能快速拼出表格、表单、弹窗这些后台管理界面。
但同样叫“后台”,工程形态有两种,部署方式完全不同。前后端分离的工程里能看到独立的 package.json,前端开发服务器和后端接口服务器分开跑;服务端渲染的工程里只有一个 Java 工程,页面由 Thymeleaf 或 JSP 直接渲染。判断方法很简单:根目录有前端工程且带 package.json,就是前后端分离;Java 工程的 pom.xml 里引了 spring-boot-starter-thymeleaf,页面大多在后端里。
区分这点的意义在于,很多人照着前后端分离的教程去跑一个服务端渲染的项目,折腾一晚上都起不来。先确认形态,再决定是跑两个服务还是一个服务,这是实训部署里最容易被忽略的判断。最近常听到的“vue3 后台管理系统”指的也是第一种形态,Vue 3 加 Vite 的项目结构,看 package.json 里的依赖版本就能确认。
2.3 解压前先做三件事:校验完整性、识破伪加密、盯紧 README
不要双击解压,先用命令行看一眼压缩包本身有没有问题。常见做法是下面三条命令:
unzip -l 矿山安全管理系统后台.zip # 只看压缩包里的文件清单,不解压 unzip -t 矿山安全管理系统后台.zip # 测试压缩包完整性 unzip -o 矿山安全管理系统后台.zip -d ./mine-safetyunzip -l用来确认包内结构,unzip -t会逐个文件测试 CRC 校验,输出No errors detected in compressed data才说明文件是完整的。最后一条才是正式解压,-o表示覆盖已存在文件,-d指定解压目录。如果你用的是 Windows,tar -xf在 PowerShell 里也能解压 zip,但unzip -t这种完整性校验还是建议用 7-Zip 或 WinRAR 的“测试压缩文件”功能代替。
解压时报 “invalid zip archive: could not find EOCD”,说明压缩包在传输过程中损坏了,EOCD 是 zip 格式的中央目录尾部标记,找不到它说明文件不完整。还有一种情况是解压时突然要求输入密码,而 README 里根本没提密码这件事,那大概率是“zip 伪加密”:加密标志位被改过,文件数据本身没锁。这类坑放到避坑章节展开,在这里你只需要记住:先测试、再解压,别把损坏的包直接当源码去排查。
README 是实训压缩包里性价比最高的文件,里面通常写了 JDK 版本、Node 版本、MySQL 版本、默认账号密码。按 README 准备环境,比踩完坑再回头读文档省事得多。我一般会先把 README 里的版本号记下来,和本机环境对一遍,再开始装依赖。
3. 把后台跑起来:数据库初始化、后端配置与前端构建三步走
跑通一个后台 zip 的顺序是固定的:先数据,再服务端,最后界面。数据层没初始化,后端启动时会一直报连接失败;后端服务没起来,前端界面再漂亮也拿不到数据。按三步走,不要跳步,也不要并行折腾。
3.1 建库导数据:mysql 命令行把 SQL 一次性灌进去
找到 sql 目录后,先建库,再导数据。不要在可视化工具里乱点,命令行最直接,报错也最明确:
mysql -uroot -p \ -e "CREATE DATABASE IF NOT EXISTS mine_safety DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;" mysql -uroot -p --default-character-set=utf8mb4 mine_safety < sql/init.sql第一条命令创建数据库,IF NOT EXISTS防止重复执行报错,DEFAULT CHARACTER SET utf8mb4指定字符集,这个很关键,后台里存中文姓名、隐患描述、整改记录都靠它。COLLATE utf8mb4_general_ci是排序规则,一般实训项目用它最省事。第二条命令将 SQL 脚本导入到 mine_safety 库,--default-character-set=utf8mb4告诉客户端用 UTF-8 编码发送指令,避免中文注释乱码。
如果 sql 目录里不止一个文件,常见的命名规律是 schema.sql 负责建表,data.sql 负责初始化数据。先执行建表脚本,再执行数据脚本。如果 README 里说“直接执行 init.sql”,那通常一个文件里既包含建表也包含数据,按说明执行即可。
导入完成后验证一下,不能只看命令行有没有报错:
mysql -uroot -p -e "USE mine_safety; SHOW TABLES; SELECT COUNT(*) FROM sys_user;"SHOW TABLES列出全部表名,确认表结构已经建好;SELECT COUNT(*) FROM sys_user确认用户表里有初始化数据。如果表数量和你预期的业务模块对不上,或者 sys_user 表是空的,说明初始化数据没灌进去,这时候就不要继续往后走了,先回头处理数据问题。
3.2 后端配置三处必改:数据源、端口、Redis 连接
后端工程的配置文件通常是 application.yml 或者 application.properties。实训交付的计算机里编的是别人的环境,到了你机器上必然要改。最常改动的是数据源、服务端口和 Redis 连接。一个典型的改动如下:
server: port: 8080 spring: datasource: url: jdbc:mysql://localhost:3306/mine_safety?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: "换成你的数据库密码" driver-class-name: com.mysql.cj.jdbc.Driver redis: host: localhost port: 6379 password:数据源 URL 里的几个参数是实训后台最常见的坑源。characterEncoding=utf8负责中文编码,serverTimezone=Asia/Shanghai解决 MySQL 8 时区报错,useSSL=false避免本地连接时 SSL 告警刷屏。driver-class-name在 MySQL 5.x 时代是com.mysql.jdbc.Driver,MySQL 8 必须写成com.mysql.cj.jdbc.Driver,两个版本差别看这里就能分辨出来。
Redis 不是所有实训后台都会用到,但很多带验证码功能的系统会用它存验证码。如果项目里确实集成了 Redis,本机没装或没启动,后端启动时报Unable to connect to Redis,那就是这个配置的问题。启动 Redis 后再重新启动后端就能恢复正常。如果不想装 Redis,检查代码里是否有开关可以禁用验证码,但实训阶段不建议这么做,因为演示时验证码本身也是功能点。
改完配置,启动后端有两种常见方式。一是在 IDEA 里找到主类直接运行,适合调试;二是命令行打包运行,适合模拟线上环境:
cd backend mvn clean package -DskipTests java -jar target/mine-safety-backend.jar-DskipTests跳过测试,避免单元测试失败打断打包。打包完成后用java -jar启动,看到 Spring Boot 的横幅和Started字样,说明后端已经起来了。这一步不要着急去点前端页面,先用接口验证后端状态。
3.3 前端构建:npm install 失败先检查 Node 版本
前端工程拿到手之后,先确认 Node 环境,再装依赖,不要一上来就npm install然后干等。Node 版本和后端 JDK 版本一样是个玄学问题,但好在它通常写在 README 里:
cd frontend node -v # 查看当前 Node 版本 npm -v # 查看 npm 版本 npm install # 安装依赖vue3 加 Vite 的前端工程对 Node 版本有明确要求,Vite 4 以上需要 Node 14.18 或更高,Vite 5 则建议 Node 18。如果你本机 Node 版本过低,npm install会报Unsupported engine警告,甚至直接失败。版本不匹配时,优先安装 README 要求的 Node 版本,而不是硬着头皮在旧版本上继续。
依赖安装完成后,启动开发服务器之前,还要检查一个文件:.env.development或者vue.config.js。前端 dev 模式访问后端接口靠的是转发配置,常见的变量名是VITE_API_BASE_URL或VUE_APP_BASE_URL:
# 以 .env.development 为例 VITE_API_BASE_URL=http://localhost:8080这里写的是后端的服务地址,如果后端端口改成了 8081,这里必须同步改。配置不对的话,前端页面能打开,但所有请求都会 404 或 500。改完配置再执行:
npm run devVite 默认端口是 5173,Vue CLI 默认是 8080。如果 8080 被后端占了,Vite 会自动换端口,页面地址以命令行输出为准。
3.4 启动顺序与首次登录验证:先看日志再点页面
所有服务启动后,顺序整理一下:MySQL 和 Redis 先起,接着是后端,最后是前端 dev。不要同时在多个终端里输出一堆日志然后挨个找错,一个服务一个服务地启动,每个服务启动成功再起下一个。
后端起来后,先用 curl 验证登录接口,这一步能确定后端、数据库、Redis 三者是否已经连通:
curl -X POST http://localhost:8080/api/login \ -H "Content-Type: application/json" \ -d '{"username":"admin","password":"admin123"}'这里的/api/login是常见写法,具体路径以后端代码里的请求映射为准。如果你看到响应里包含token或者code字段,说明后端已经正常工作。如果提示用户名密码错误,那是初始化数据问题,不是连通性问题;如果提示连接失败,才需要回头检查服务状态。
接口验证通过后才打开浏览器访问http://localhost:5173,登录失败就能确定问题在前端还是账号密码。这个习惯可以帮你把“整个系统跑不起来”这个大问题,拆成“数据库没数据”“后端没起来”“前端转发不对”这三个独立的小问题。
4. 读懂矿山安全后台的核心业务:从表结构到实训报告素材
后台跑通只是第一步,实训报告和答辩要的是“你懂这个系统在做什么”。矿山安全管理系统,业务主线是一条风险链条:先辨识风险、管控风险,风险失控变成隐患,隐患没有及时整改就可能导致事故。后台的每个菜单,几乎都挂在这条链条的某个环节上。
4.1 用户-角色-菜单权限模型:后台管理系统的骨架子
几乎每个后台管理系统都会先做权限模块。矿山安全管理系统里的用户不是铁板一块:矿长看全局报表,安全科长管理隐患排查,值班员只录报警记录。不同角色看到的菜单、能按的按钮都不一样。实现这套控制的标准做法是 RBAC,也就是“用户-角色-菜单”三层模型:
| 表名 | 关键字段 | 作用 |
|---|---|---|
| sys_user | id, username, password, real_name, status | 后台账号表 |
| sys_role | id, role_name, role_key | 角色表 |
| sys_menu | id, parent_id, menu_name, path, perms | 菜单和权限标识 |
| sys_user_role | user_id, role_id | 用户和角色关联 |
| sys_role_menu | role_id, menu_id | 角色和菜单关联 |
用户登录成功后,后台根据用户 ID 查出角色,再根据角色查出菜单列表,最终生成该用户能看到的侧边栏。这个逻辑在实训报告里可以写成一节“基于 RBAC 的权限模型设计”,比只写“我做了登录功能”有分量得多。
权限模型里有个细节值得关注:perms字段。它通常存类似hazard:add、hazard:delete这样的权限标识,按钮级别的控制靠它实现。演示的时候,给普通角色去掉hazard:delete权限,页面上“删除”按钮会自动消失,这个操作在答辩现场比讲十页 PPT 都直观。
另外强调一点:登录接口不要用字符串拼接 SQL,要用参数绑定。实训后台的登录接口最容易招黑,用 MyBatis 的#{username}就能防止注入,这也是安全和考核里常问的一个点,能在报告里提一句会很加分。
4.2 隐患排查与整改闭环:一张表和一个状态机
隐患管理是矿山安全管理系统里最有业务深度的模块。一个隐患从被发现到销号,要经历发现、派单、整改、复查、销号这几个环节。后台实现的核心是一张隐患表和其中一个状态字段:
| 字段 | 示例值 | 说明 |
|---|---|---|
| hazard_name | 主井口照明缺失 | 隐患名称 |
| hazard_level | 一般隐患 / 重大隐患 | 等级,影响整改期限 |
| location | 副斜井 120m 处 | 位置描述 |
| discover_user | 张三 | 发现人 |
| rectify_user | 李四 | 整改责任人 |
| deadline | 2025-06-30 | 整改期限 |
| status | 0 待整改 / 1 整改中 / 2 待复查 / 3 已闭环 | 状态流转 |
状态用tinyint就够了,新手容易犯的错是把状态写成字符串,比如“待整改”“整改中”,后面要加个新状态就得改代码。用数字表示状态,页面上做一层映射,既好扩展又好过滤。列表页的“待整改”“已逾期”筛选,本质都是对 status 和 deadline 字段的查询。
实训报告里写这个模块时,把状态流转描述成“发现—派单—整改—复查—销号”的闭环,再配上一句“未按期整改的隐患自动标红”,整个系统的业务感就出来了。如果你打算给这个后台加功能,给隐患列表加一个“超期未改”的筛选条件,是最贴合业务且改动量最小的小功能。
4.3 报警记录与处置流程:把闭环思路用在同一处
报警管理是矿山安全系统的另一个核心模块。真实场景里,传感器检测到瓦斯浓度超限或者温度异常,会把数据推送到后台生成一条报警记录。实训项目没有真实传感器,常见的做法是在初始化数据里造上千条模拟报警,让列表和报表有数据可看。
报警记录表的设计思路和隐患表一致:记录事实,跟踪状态,关联处理人:
| 字段 | 示例值 | 说明 |
|---|---|---|
| alert_type | 瓦斯 / 一氧化碳 / 温度 | 报警类型 |
| alert_value | 1.2 | 实测值 |
| threshold_value | 1.0 | 阈值,超过即报警 |
| alert_time | 2025-06-18 08:23:11 | 报警时间 |
| handle_user | 王五 | 处置人 |
| handle_note | 已安排通风检查 | 处置说明 |
| status | 0 未处置 / 1 已处置 | 处置状态 |
这类表的设计方式相对直接,但业务含义很清楚:“报警”负责记录异常,“处置人”和“处置说明”负责记录响应。在实训报告的业务流程章节,把“报警产生、值班员确认、处置反馈、复核销号”这条链路画成文字流程图,整个模块的完整性就体现出来了。
读这些业务表时有一个通用套路:先找状态字段,再找时间字段。状态字段告诉你业务走到哪一步,时间字段告诉你每一步花了多久。后台列表页几乎所有的筛选和提醒,都是在 status、deadline、handle_time 这几个字段上做文章。
5. 部署避坑清单:5 个真实翻车点与排查命令
实训项目跑不起来的报错,翻来覆去就那么几类。这一章按“现象、原因、解决”的结构整理五个高发问题,遇到报错先对号入座,再去翻日志,比瞎试快得多。这里的每一条都是我见过的真实翻车场景,不是理论推断。
5.1 数据库导入报错:字符集和版本两个老对手
现象:导入 SQL 时报ERROR 1067或者ERROR 1064,有时导入到一半中断,前面的表建好了,后面的表没建。更多的时候是 SQL 文件用记事本打开正常,但导入后中文全变问号。
原因:常见有两个。一是 SQL 文件是 UTF-8 编码,但 MySQL 客户端默认字符集不是 UTF-8,导致中文乱码,甚至触发字符集不兼容的报错;二是 SQL 脚本里用了 MySQL 8.0 的语法或配置,本机却是 MySQL 5.7,版本差异导致执行失败。
解决:建库时显式指定字符集,导入时用--default-character-set=utf8mb4,这是两条命令,不是一条:
mysql -uroot -p -e "ALTER DATABASE mine_safety CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;" mysql -uroot -p --default-character-set=utf8mb4 mine_safety < sql/init.sql如果你的 SQL 脚本里包含CREATE DATABASE语句,先删除这行,或者改用source方式导入,避免重复建库。MySQL 版本不一致的问题,最好在 README 里确认,如果你能在本地查到mysql --version,对照一下即可。版本相差太大时,最省事的方案是安装 README 要求的版本,而不是修补 SQL。
5.2 后端起不来:端口占用、Redis 没起、数据源连不上
现象:后端启动时打印一段日志后退出,常见的是APPLICATION FAILED TO START。日志里翻到关键行,报错内容五花八门,但归结起来无非三种:port was already in use、Unable to connect to Redis、Communications link failure或Access denied。
原因:端口被其他程序占了,后端没有拿到 8080 端口;Redis 服务没启动;数据库地址、用户名或密码配置错误。这三个问题有一个共同特点:不是代码问题,是环境问题。
解决:分开定位,先看端口,再看中间件,最后看密码。端口检查用下面两条命令之一:
netstat -ano | findstr :8080 ss -lntp | grep 8080Windows 用netstat,Linux 用ss。查出来占用端口的进程号后,确认是没用的进程再结束它,不要乱杀。如果确认是端口冲突又不想动其他服务,直接改server.port换成 8081 也可以。Redis 没起就启动 Redis,数据源连不上就拿着application.yml里的用户名密码去命令行试一次mysql -u用户名 -p密码,能连就说明配置没问题,连不上就改配置。
排查这类问题有一个经验:日志里最先出现的异常往往才是根因,后面跟着的一串堆栈大多数是连锁反应。所以不要看日志最后几行,而是搜第一处Caused by,那才是问题的源头。
5.3 前端白屏:baseURL 和路由模式的组合问题
现象:npm run dev能打开登录页,但登录后整个页面空白,控制台全是 404;或者页面能打开,接口请求全部指向了错误地址。
原因:两类。一是前端请求后端的地址配置不对,.env.development里的VITE_API_BASE_URL指向了不存在的端口或路径;二是前端用的是 history 路由模式,刷新或跳转时后端没有把请求回退到首页。
解决:先改 baseURL,把.env.development里的地址指向实际的后端地址。再处理路由回退,Vite 的 devServer 配置里加上一行:
// vite.config.js export default { server: { host: '0.0.0.0', port: 5173, historyApiFallback: true } }historyApiFallback: true的作用是:当用户直接访问某个前端路由地址时,devServer 把请求回退到 index.html,由前端路由接管。如果你用 Nginx 部署打包后的前端页面,需要在 Nginx 配置里加try_files $uri $uri/ /index.html;,作用一样。这个配置漏掉的话,登录成功后跳转的瞬间就会白屏。
判断 baseURL 和路由问题有个笨办法:按 F12 打开浏览器开发者工具,看 Network 面板。请求地址是http://localhost:5173/api/xxx说明转发没生效;请求地址是http://localhost:8080/api/xxx但返回 404,那就要看后端这个路径到底存不存在。
5.4 解压失败:EOCD 找不到和 zip 伪加密
现象:解压时报invalid zip archive: could not find EOCD,或者打开压缩包时没有任何提示要求输入密码,但解压到一半就开始要密码。还有一种是解压工具提示文件损坏,但压缩包能在另一个工具里正常打开。
原因:could not find EOCD说明压缩包的末尾缺少 zip 格式的中央目录尾部标记,通常是传输过程中文件截断或者下载不完整。而“突然让输密码”的情况,大概率是伪加密——zip 文件头的加密标志位被改动过,文件数据本身并没有真正加密,工具检测到标志位就要求输入密码。
解决:先换工具验证。Windows 下用 7-Zip 打开列表,如果 7-Zip 能直接展开目录而系统自带解压工具要密码,伪加密的可能性就很大。伪加密的修复思路是去掉加密标志位而不是破解密码,常见做法是用解压工具的“复制到”功能将文件重新打包一次,新生成的 zip 不再包含伪加密标志。注意这个方法只适合处理你在实训中拿到的交付包,不要拿它处理未知来源的压缩包。
EOCD 报错没有取巧的修复办法,最靠谱的还是让发包的人重新打包上传,本地补救可以使用zip -FF尝试修复,但成功率看运气。与其花一小时修复一个损坏的文件,不如直接重新拿一份原始包。这条经验是用时间换来的,实训周里最不值钱的就是等待。
5.5 登录不进去:默认账号密码和加密方式
现象:页面能打开,后端接口也正常,但无论试admin/admin、admin/123456都提示用户名或密码错误。
原因:初始化 SQL 里的密码不是明文,而是加密后的摘要值。实训后台常见的加密方式是 MD5 或 BCrypt,数据库里sys_user表存的password字段是一串看不出规律的字符,而不是可读的密码。README 里没写默认账号,或者写了但你抄错穿了。
解决:第一优先去 README 里找默认账号。找不到的话,登录数据库直接看初始化数据:
SELECT username, password, status FROM sys_user WHERE status = 1;如果能看到密码列是一串密文,说明密码确实加密了,你需要向项目作者确认默认密码。如果对方也提供不了,本机实训库可以自己重置一条测试账号,但前提是你能确认系统用的是什么加密算法。MD5 加密的话可以找在线工具生成一个已知密码的 MD5 值,BCrypt 则需要用代码生成,然后更新到库里:
UPDATE sys_user SET password = '替换成加密后的值' WHERE username = 'admin';这条 SQL 只建议用在本机实训数据库,正式环境绝对不要绕过认证去改密码表。演示前务必确认一次测试账号能登录,并提前想好登录失败时的替代方案。
6. 答辩前加个小功能:让操作日志替你说话
如果时间还能挤出半天,值得给后台加一个操作日志模块。它改动量小,演示效果直观,还能顺便体现“你理解如何在统一的地方做埋点”。实现方式用一个注解加一个切面,前后端都不需要动大手术。
6.1 用注解加日志:简单、演示效果好
先定义一个注解,用来标记“需要记录日志”的接口:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface OperLog { String module(); // 模块名,比如 "隐患管理" String action(); // 操作名,比如 "整改复核" }再写一个切面,拦截带这个注解的方法,方法执行完后把操作记录写入日志表:
@Aspect @Component public class OperLogAspect { @Around("@annotation(operLog)") public Object around(ProceedingJoinPoint pjp, OperLog operLog) throws Throwable { long start = System.currentTimeMillis(); Object result = pjp.proceed(); long cost = System.currentTimeMillis() - start; // 实际项目中从安全上下文取当前登录用户 String username = SecurityUtil.getUsername(); operLogMapper.insert(username, operLog.module(), operLog.action(), cost); return result; } }这个切面的逻辑很直白:@Around控制方法执行前后,pjp.proceed()负责调用原始业务方法,执行结束后把用户名、模块名、操作名和耗时写入sys_oper_log表。SecurityUtil.getUsername()需要换成项目里实际的取当前登录用户的方式,Spring Security 有SecurityContextHolder,自定义拦截器可能有自己的工具类,照着项目里已有的写法改即可。
给“整改复核”或者“报警处置”接口加上@OperLog(module = "隐患管理", action = "整改复核")注解,演示时点一下按钮,然后打开日志菜单,刚才的操作已经出现在列表里了。这个从前台操作到后台落库再到页面显示的闭环,答辩时比任何口头描述都有说服力。
6.2 演示节奏与验证方法
如果项目结构简单,不想引入切面,直接在 service 方法的 finally 块里插入一条日志记录也能达到同样的演示效果。差别在于代码侵入性强一些,但逻辑更直白,实训报告里也好解释。
验证分为两步。第一步,在页面上执行一次操作;第二步,刷新日志页面看记录是否出现,同时用 SQL 确认落库:
SELECT * FROM sys_oper_log ORDER BY create_time DESC LIMIT 5;演示前先按这个流程完整走一遍,千万不要现场第一次操作就展示,日志没写进去会非常被动。我自己翻过这样的车:答辩前觉得功能简单,没有预演,现场点击后日志列表空着,后来才发现是日志表没有初始化菜单权限,页面接口报错了。现在我的习惯是,任何新增功能都先在测试库里完整走两遍,再谈演示。希望帮到你。
本文还有配套的精品资源,点击获取