☰
SpringBoot+Vue实现EHS安全环保管理系统:毕业设计实战解析
2026/9/30 3:03:52 网站建设 项目流程

做毕业设计选题目的时候,我盯着"EHS安全环保管理系统"看了很久。EHS是Environment、Health、Safety的缩写,翻译过来就是环境、健康、安全。国内但凡有点规模的制造企业、化工企业,都有专门的EHS部门,负责隐患排查、环境监测、职业健康档案这些事。选题的价值不用多讲,企业里是真的有这套需求,不是凭空造出来的业务。

这个项目我用了SpringBoot做后端主体框架、Vue做前端页面、MySQL存业务数据,做成了一套面向企业的一体化综合管控平台。它把安全巡检、隐患整改、环境数据监测、员工健康档案、培训记录这些散落的业务全部收到一个系统里,形成从发现问题到整改验收的闭环。不管是打算拿来当毕业设计,还是未来想往企业数字化方向走,这套项目的参考价值都很高。

这篇内容我会把整个项目的设计思路、核心模块、落地过程和踩过的坑全部理一遍,适合正在做SpringBoot毕设的同学,也适合想要快速理解企业EHS业务逻辑的开发新人。

1. 项目定位:为什么企业需要一套EHS综合管控平台

1.1 传统EHS管理的痛点

先说业务端。很多没进过工厂的人可能想象不到,过去几年不少企业的安全管理还是靠Excel和微信群里的一张张表格。安全隐患排查完了,整改单要么打印出来找人签,要么拍照发群,回头一统计全是散的数据。环境监测的数据来自不同设备,监控人员每天抄一次表,抄完再人工录入系统。员工体检档案归人事管,特种作业证归安全部管,培训记录又是另一套Excel。这种信息割裂导致的最直接结果,就是出事之后追溯难、统计难、责任划分也难。

我做这个系统之前专门问过在企业做EHS的朋友,他给我列了几个高频痛点。一是隐患台账无法闭环,发现了问题但整改结果没人跟;二是数据口径不统一,环境监测数据覆盖不全,领导要看报表就得临时整理;三是档案管理混乱,员工健康档案和特种作业证到期提醒基本靠人脑;四是整改责任不明确,同一个隐患今天推明天,最终变成事故隐患。这些痛点其实就是系统功能模块的源头,项目做得好不好,核心就看你有没有真正解决其中几个问题。

1.2 系统核心价值:从记录工具到管理闭环

EHS系统建设的核心,不是做一个"电子台账",而是把一个管理闭环跑起来。闭环是什么概念?拿安全隐患来说,完整链条是"巡检发现-登记上报-任务指派-限期整改-复查验收-归档统计"。系统要做的不只是把每个节点记录下来,更重要的是在每个节点设置状态约束:发现隐患必须指派责任人,指派后必须有整改期限,超期未整改要自动提醒,整改完成后必须复查确认。只要这个链条能在系统里转起来,管理效率就会明显提升。

环境监测模块同理。系统按时采集废水、废气、噪声、固废等监测数据,超过排放限值时自动预警,并且定期生成趋势报表。这样环境管理就从"被动应付检查"变成"主动掌握数据"。健康档案模块把员工基本信息、体检记录、职业病危害接触史、特种作业证书放在一起,证书到期系统自动提醒。这三个业务域统一在一个平台里,就是EHS一体化管控平台的核心价值。

1.3 这套项目适合谁

这个题目的定位很清晰,就是面向企业内部管理的业务系统,天然适合作为计算机相关专业的毕业设计。它有三层价值。第一层是技术价值,项目把SpringBoot、MyBatis-Plus、Spring Security、Vue、MySQL这些主流技术在真实业务场景里全部用上了,做完能撑起项目经验。第二层是业务价值,EHS是真实的企业管理需求,不是虚构场景,无论是答辩还是作品集展示,都能讲出实际业务逻辑。第三层是差异化价值,和满大街的商城、图书管理系统相比,EHS系统在选题上明显更有辨识度,也更容易体现设计者对业务的理解深度。

2. 技术选型与架构设计:为什么核心框架选SpringBoot

2.1 SpringBoot解决了什么问题

选技术框架的时候,我考虑过SSH(Struts2+Spring+Hibernate)和SSM(Spring+SpringMVC+MyBatis),最后还是定了SpringBoot。原因很简单,SpringBoot解决了传统Spring项目里最烦人的配置问题。以前搭一个SSM项目,需要写web.xml、spring-mvc.xml、spring-mybatis.xml,配置数据源、事务管理器、拦截器,哪一步写错都要排查半天。SpringBoot用自动配置和约定优于配置的思路,把大部分样板配置都替你做好了,项目里只需要在application.yml里写上数据源参数和少量自定义配置就能跑起来。

SpringBoot还有一个很实际的优点:内嵌Tomcat。以前部署SSM项目要先装Tomcat、配置server.xml、把war包丢进webapps目录,SpringBoot项目打成jar包直接java -jar就能启动,部署成本低了一大截。对于毕设项目来说,这意味着在Windows上开发完,传到云服务器上也能很快跑起来,演示的时候阻力小很多。

2.2 整体架构:前后端分离

EHS系统我采用了前后端分离的架构。后端是SpringBoot项目,提供RESTful API接口;前端是Vue 2 + Element UI构建的单页应用;数据库用MySQL 8.0,缓存用Redis。接口交互统一走JSON格式,前端通过axios调用后端接口。为什么选前后端分离?一是开发过程可以并行推进,我先把后端的接口文档定义好,前端的同学(或自己写的时候)可以按接口联调;二是后期维护方便,改了前端界面不影响后端逻辑;三是在答辩演示时可以直接用浏览器访问,界面效果比重后端模板渲染的JSP页面要好看很多。

前后端分离也会带来一些额外工作,比如跨域处理、接口鉴权、统一返回格式。跨域问题在开发环境通过后端配置CORS解决,线上部署时把前端打包后的静态文件交给Nginx托管,再把/api路径反向代理到后端服务,这样浏览器视角只有同源的请求,跨域问题基本不存在。

2.3 数据库设计:一张关系图谱

EHS系统的数据模型是整个项目的底盘。我把它分成五个域:用户权限域、安全业务域、环境业务域、健康业务域、系统支撑域。

用户权限域包含用户表、角色表、菜单表和用户角色关联表。安全业务域包含巡检计划表、隐患登记表、隐患整改表、复查验收表。环境业务域包含监测点表、监测数据表、排放限值表、预警记录表。健康业务域包含员工档案表、体检记录表、证书表、培训记录表。系统支撑域包含公告表、操作日志表和文件存储表。

这里有个值得注意的设计原则:EHS系统的核心表普遍适合"主表+子表"的结构。比如隐患登记表是主表,记录隐患的基本信息;隐患整改表是子表,记录责任人、整改措施、整改期限;复查验收表是另一个子表,记录复查结果和验收人。三张表通过隐患ID关联起来,这样从发现到验收全程都有迹可循。

3. 核心业务模块拆解:安全、环境、健康三大业务域

3.1 安全隐患排查闭环

安全隐患排查是整个EHS系统最核心的模块,也是我在答辩时花了最多时间讲的部分。这个模块的业务流程是:巡检人员按巡检计划到现场检查,发现问题后在系统里登记隐患,登记内容包括隐患位置、隐患描述、隐患等级(一般/较大/重大)、现场照片;系统根据隐患等级自动生成整改任务,指派给对应责任人,并设定整改截止日期;责任人在期限内上传整改说明和整改后照片;最后由安全管理人员进行复查验收,验收通过则隐患关闭,验收不通过则退回重新整改。

技术实现上,有几个关键点需要重点处理。第一是隐患等级的自动判断,一般企业会按风险矩阵来定级,我在系统里做了一个简单的规则引擎,根据隐患类型和影响范围自动给出建议等级,人工可以修改。第二是整改超期提醒,我用SpringBoot自带的@Scheduled定时任务每天扫描一次隐患表,把超过整改期限且状态未关闭的记录筛选出来,生成待办提醒。第三是图片上传,现场照片使用MultipartFile接收,存到服务器本地磁盘,数据库只保存文件路径,避免把图片直接塞进数据库。

// 隐患整改超期扫描,每天凌晨执行一次 @Scheduled(cron = "0 0 1 * * ?") public void scanOverdueRectification() { List<Hazard> overdueList = hazardMapper.selectOverdueList(); for (Hazard hazard : overdueList) { // 更新隐患状态为逾期 hazard.setStatus(2); // 生成一条待办提醒 todoService.createTodo("隐患逾期", hazard.getRectifier(), hazard.getId()); } }

3.2 环境监测与预警联动

环境监测模块相比安全模块稍微简单一些,但是数据量大、实时性要求高。系统的思路是:在厂区设置若干监测点,每个监测点监测废水COD、氨氮、pH值、废气颗粒物、噪声分贝、VOCs等指标,数据来源可以是人工录入,也可以通过接口对接在线监测设备。系统每天按监测点汇总数据存入监测明细表,超过排放限值时标记超标并生成预警记录,同时给环境管理员发送提醒。

这个模块有两个技术难点。第一是数据展示,需要按时间范围查询监测数据并用折线图展示趋势。我在前端用了ECharts,后端提供一个带时间范围参数和历史数据的查询接口,返回按日期分组的数据列表,前端直接渲染折线图。第二是预警规则配置,企业不同监测点的限值不一样,比如有的点COD限值是60mg/L,有的点是100mg/L,所以我把排放限值做成独立的数据表,支持按监测点配置,预警逻辑统一读取限值表中的数据进行比对。

-- 监测点指标限值表,按监测点和指标维度配置 CREATE TABLE monitor_limit ( id BIGINT PRIMARY KEY AUTO_INCREMENT, point_id BIGINT NOT NULL COMMENT '监测点ID', indicator VARCHAR(50) NOT NULL COMMENT '监测指标', limit_value DECIMAL(10,2) NOT NULL COMMENT '排放限值', unit VARCHAR(20) COMMENT '单位', create_time DATETIME DEFAULT CURRENT_TIMESTAMP );

3.3 职业健康档案与证书管理

健康域在EHS系统里经常被弱化,但做企业版本一定不能漏。这个模块管理员工的基础健康档案、年度体检记录、职业病危害接触史、特种作业证书等。特种作业证书的管理有一个很实用的功能:证书到期提前提醒。我在证书表里存了发证日期和有效期,系统每天扫描一次,有效期不足30天的证书自动生成提醒,发给员工本人和相关管理人员。员工体检记录则按年度归档,支持按部门、岗位筛选查询,也能设置职业病复查提醒。

3.4 培训记录与应急管理

培训记录模块主要管理安全培训计划、培训签到记录和考核结果。企业每年都有三级安全教育、应急演练等培训任务,系统里面按"计划-执行-归档"三步走:安全部门制定年度培训计划,执行时记录参训人员名单和培训照片,结束后归档培训资料并统计覆盖率。应急管理模块做一个简化版就够:维护应急物资台账、应急组织架构,以及应急预案的版本管理。这两个模块在功能上是锦上添花,但能显著提升业务完整性。

4. 实操落地:从项目初始化到核心功能实现

4.1 工程结构怎么搭

SpringBoot项目的工程结构我建议按业务分包,而不是按技术分包。按技术分包是controller、service、mapper这种分法,适合小型项目;EHS系统业务模块多,用按业务分包的方式,每个业务域下面的代码放一起,维护性更好。我的做法是:

com.example.ehs ├── common # 通用类:统一返回值、异常处理、工具类 ├── config # 配置类:CORS、拦截器、定时任务 ├── security # 安全认证:JWT工具、登录校验、权限注解 ├── module │ ├── safety # 安全业务:隐患、巡检、整改 │ ├── environment # 环境业务:监测点、数据、预警 │ ├── health # 健康业务:档案、体检、证书 │ ├── system # 系统管理:用户、角色、菜单、日志

之所以这么分,是因为毕业设计项目规模不大,按技术分包到后面会越写越乱,一个controller目录下面塞几十个文件,自己都找不到。按业务分包之后,改安全模块就进safety目录,改环境模块就进environment目录,逻辑清晰很多。

4.2 用户权限设计:RBAC模型落地

权限管理是所有管理系统绕不开的部分。EHS系统我用的是经典RBAC模型:用户归属于角色,角色绑定菜单和操作权限。后端实现上,登录接口用Spring Security + JWT完成认证,用户登录成功后签发一个有效期为24小时的JWT令牌,前端拿到令牌存在本地,之后每次请求都在Authorization请求头带上令牌。后端写一个拦截器统一验证令牌有效性,并把当前用户信息放入请求上下文。

权限控制要做到"不同角色看到不同菜单"。系统里我预设了四种角色:系统管理员、安全管理员、环境管理员、普通员工。管理员能看到全部菜单,普通员工只能看到隐患登记、我的待办、我的培训等有限菜单。权限的粒度控制在按钮级别,比如隐患登记页面,普通员工只能新增登记,不能执行整改验收。这些通过自定义注解@PreAuthorize结合Spring Security的权限表达式实现。

@PreAuthorize("hasAuthority('safety:rectify:update')") @PostMapping("/rectify/update") public Result updateRectification(@RequestBody Rectification rectification) { return rectificationService.update(rectification); }

4.3 数据库表设计的关键细节

表设计是决定项目后期好不好改的关键。我总结了几个实操中非常重要的小细节。第一,每张表都要有id、create_time、update_time、deleted这四件套,id用自增主键,create_time和update_time用DATETIME类型,deleted做逻辑删除,避免物理删除数据导致历史记录丢失。第二,隐患、巡检、监测数据这类业务表,建议带上company_id或者department_id字段,虽然毕设场景下不一定有多租户需求,但加上这个字段以后做数据隔离和按部门统计都很方便。

第三,外键能不用就不用,表之间的关联通过业务字段维护。比如隐患表和整改表通过hazard_id关联,不建物理外键,这样删除和批量更新数据时不会被数据库约束卡住。第四,大字段要单独处理,隐患描述、整改措施这些用TEXT类型,搜索的时候不要用LIKE全表扫描,毕设阶段数据量不大可以接受,但如果想做得讲究一些,可以给状态字段、时间字段建上索引。

4.4 文件上传与报表展示实现细节

隐患照片上传模块,我设置了单张不超过5MB的限制,文件按日期目录存储,文件名用UUID重新生成,避免中文文件名乱码和重名覆盖。存储路径配置在application.yml里,上传成功后返回给前端的值是文件相对路径,前端显示图片时拼接一个固定的访问前缀。要注意的是,SpringBoot默认单次请求最大文件大小是1MB,如果直接上传超过1MB的图片会报错,需要在配置里调大:

spring: servlet: multipart: max-file-size: 5MB max-request-size: 20MB

报表展示这块,首页做了数据看板,包括隐患整改率、本月巡检次数、环境监测超标次数、培训完成率等核心指标。前端用ECharts的折线图和饼图展示,后端提供统计接口,SQL使用GROUP BY按时间维度汇总。这里有一个性能优化的点:统计查询如果每次都实时计算,数据量大了以后会很慢,我给首页看板加了一层Redis缓存,统计结果缓存5分钟,用户刷新页面时直接读缓存,体验明显更流畅。

5. 常见问题排查与避坑实录

5.1 SpringBoot版本和依赖冲突问题

做毕设过程中最容易踩的坑就是版本。我刚开始用SpringBoot 3.0以上版本,结果发现MyBatis-Plus和Spring Security的兼容性还没有完全跟上,网上搜到的很多教程和依赖配置都是针对SpringBoot 2.x的,照抄下来不是包冲突就是bean注入报错。后来我果断降回SpringBoot 2.7.x,并且锁定MyBatis-Plus 3.5.x和Spring Security 5.7.x,整个项目才稳定下来。

注意:如果选SpringBoot 3.x,要注意javax.servlet和jakarta.servlet的区别。3.x版把javax迁移到了jakarta命名空间,很多老依赖会直接找不到类。毕设项目如果没有特殊要求,建议直接用2.7.x,资料多、坑少、稳定。

还有一个很常见的问题是Lombok版本和JDK版本不匹配。如果本机JDK是17,而Lombok版本太低,编译时会报"java.lang.ExceptionInInitializerError",解法是升级Lombok到1.18.30以上,或者在maven里显式指定版本。

5.2 数据库连接串容易出错的地方

MySQL数据库连接串里有几个参数经常坑人。一个是serverTimezone,MySQL 8.0默认时区是UTC,如果不指定serverTimezone=Asia/Shanghai,存时间数据时会差8个小时。另一个是SSL参数,不加useSSL=false的话,MySQL会提示SSL连接警告。还有allowPublicKeyRetrieval=true,MySQL 8.0以上在本地连接时如果不加这个参数,有时候会报Public Key Retrieval is not allowed。完整的连接串建议这样写:

spring: datasource: url: jdbc:mysql://localhost:3306/ehs_db?useUnicode=true&characterEncoding=utf8&serverTimezone=Asia/Shanghai&useSSL=false&allowPublicKeyRetrieval=true username: root password: 123456 driver-class-name: com.mysql.cj.jdbc.Driver

5.3 前后端联调时的跨域与鉴权问题

前后端分离开发时,跨域问题是躲不过的。我踩过一次比较隐蔽的坑:后端CORS配置无误,前端请求也能发出去,但自定义的Authorization请求头总是被浏览器拦截,响应里看不到数据。这是因为浏览器在跨域请求前会先发一个OPTIONS预检请求,如果后端没有对OPTIONS请求放开拦截器校验,JWT拦截器会把预检请求拦下来,导致跨域请求失败。解决办法是在JWT拦截器里放行OPTIONS请求:

if ("OPTIONS".equalsIgnoreCase(request.getMethod())) { return true; }

另外一个联调问题绕不开404。前端页面能打开,但调接口全是404,通常是后端Controller的路径映射写错了,或者请求方法的类型不对。排查时先把后端日志打开,看有没有"Request method 'POST' not supported"之类的关键提示,再逐个检查路径。

5.4 毕设答辩时的技术要点

最后聊聊答辩。EHS系统在答辩时老师的高频问题就那几个:第一,为什么选择SpringBoot框架,最容易的回答是高效、内嵌容器、自动配置、生态成熟;第二,系统权限是怎么设计的,把RBAC模型和JWT流程讲清楚就够;第三,隐患闭环的具体流程是什么样的,最好能画出流程图,把发现、整改、验收这三级状态说清楚;第四,系统有哪些创新点或改进空间,可以结合定时提醒、数据看板、证书到期预警这些细节展开。建议准备一两张系统功能的截图放在PPT里,演示时从隐患登记开始,走一遍整改和验收流程,直接展示业务闭环,比干讲架构更有说服力。

整套系统从设计到开发,我用了大概两个多月的时间,真正写代码的时间大概占一半,剩下时间都在理业务逻辑和处理各种环境的坑。现在回头看,EHS系统这个题目选得值:它有真实的企业管理背景,技术栈又是当前Java生态的主流组合,做完之后无论是对SpringBoot自动装配的理解,还是对前后端分离项目从开发到部署的全流程掌握,都有明显提升。如果让我重新做一次,我会在环境监测模块直接预留设备对接的接口,把数据采集做成可以插拔的数据源,这样系统的扩展性会更强。希望这篇复盘对你做SpringBoot方向的毕业设计或者企业信息化项目有一点点帮助,至少少走几个我走过的弯路。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询