
简介基于Java和Shell实现的企业危险化学品双重预防机制数字化管理系统源码设计面向企业安全生产管理人员与Java开发工程师重点解决危险化学品库存管理、隐患排查治理和风险实时监测的数字化管控问题。资源包共504个文件压缩后约2.19MB以416个Java源文件为主体实现业务逻辑、数据模型与接口设计配合44个XML配置、26个VM构建文件、4个YML配置和2个SQL脚本可完成系统参数配置、Maven构建管理及数据库初始化另有BAT和Shell脚本便于自动化部署以及docx使用手册便于环境搭建参考。已有338人学习浏览适合有Java基础并希望落地双重预防机制的开发者参考。通过完整源码可清晰理解系统模块划分、数据表关系和配置方式并能基于它进行二次开发或功能移植帮助企业更快落实安全生产主体责任。1. 从 Excel 台账到双重预防机制这套基于 Java 和 Shell 的危化品管理系统到底能干什么做企业安全管理的人应该都有过这种经历危化品库存靠 Excel 台账登记重大危险源的在线监测数据每天人工抄录一遍隐患排查记录散落在纸面整改单和微信聊天记录里上级检查一来光整理台账就要加班一周。这套基于 Java 和 Shell 的企业危险化学品双重预防机制数字化管理系统就是冲着这个痛点来的。它本质上是若依框架下的一个业务系统把风险分级管控和隐患排查治理这两套机制从制度文本变成可运行、可追溯、可统计的数字化流程。源码包里 504 个文件Java 源文件占 416 个配套 XML、VM、YML、SQL、BAT 脚本覆盖了从数据库初始化到后端业务逻辑再到自动化构建的完整链路。适合两类人一类是安全管理岗位想看看双重预防机制在系统里是怎么建模的另一类是 Java 开发想拿一套真实企业级项目练手理解若依框架的分层结构和权限模型。下面按我拆过的顺序从文件结构讲到部署踩坑再到业务实现套路。2. 拆开 504 个文件若依框架下的源码结构与配置角色2.1 文件清单先读懂哪些是业务代码哪些是脚手架拿到源码包第一步不是急着跑起来而是摸清文件构成。这套包的总量按简介描述是 504 个文件其中 Java 源文件 416 个、XML 配置文件 44 个、VM 文件 26 个、YML 配置文件 4 个、BAT 批处理脚本 4 个、属性文件 2 个、SQL 脚本 2 个。我第一次拆这种企业级源码包时有个经验先用文件数量占比判断框架性质。416 个 Java 文件说明这不是小 demo而是完整的业务系统44 个 XML 在若依体系里主要是 MyBatis 的 Mapper 映射文件每个 Mapper 对应一张表的 SQL 操作26 个 VM 文件可能会让人困惑正文里提到它们描述执行环境实际上在若依体系里这些是 Velocity 模板——用于代码生成器的在线模板定义了生成的 Controller、Service、Mapper 层代码的骨架格式不是虚拟机配置。文件类型数量按摘要描述在这套系统里的角色Java 源文件416业务逻辑、实体模型、Controller/Mapper/Service 三层结构XML 配置文件44MyBatis 映射文件、Spring 相关配置VM 文件26代码生成器的 Velocity 模板定义生成代码的骨架YML 配置文件4多环境配置开发/生产/测试BAT 批处理脚本4Windows 下启动、打包、清理的自动化入口属性文件2框架级全局参数SQL 脚本2数据库结构初始化与基础数据关键认知在于416 个 Java 文件里真正属于危化品业务核心的是 Controller、Service、Mapper 三层完成的风险点管理、隐患台账、重大危险源监测数据接入这几个模块其余是若依框架自带的用户、角色、菜单、字典、日志等基础功能。新手指南第一条不要试图逐个文件读先跑起来再用功能反查代码。2.2 配置文件的层级逻辑从 YML 到 XML 再到属性文件这套系统的配置体系分三层。最外层是 4 个 YML 文件在 Spring Boot 体系里负责应用的启动配置包括端口、数据源、Redis、日志级别。若依框架常见的命名是 application.yml 作为主配置application-druid.yml 管数据库连接池application-dev.yml 和 application-prod.yml 区分环境。中间层是 44 个 XML 文件其中大部分是 MyBatis Mapper 映射少部分是 Spring 配置。最内层是 2 个属性文件通常是 logback 日志配置和框架的通用配置。# 典型的多环境数据源配置片段对应 application-druid.yml spring: datasource: type: com.alibaba.druid.pool.DruidDataSource druid: url: jdbc:mysql://localhost:3306/ry_chem?useUnicodetruecharacterEncodingutf8 username: root password: your_password initial-size: 5 min-idle: 5 max-active: 20 max-wait: 60000这里有几个参数值得注意。initial-size 是连接池启动时预创建的连接数生产环境建议保持 5 以上避免第一个请求因为建连慢而超时max-active 是最大活跃连接数危化品系统中如果有实时监测数据轮询写入并发较高20 是若依默认值如果你的监测设备多可以按 50 调max-wait 是获取连接的超时时间60000 毫秒是常见设置调太小会在数据库短暂抖动时直接抛异常。数据库名称里的 ry_chem 是若依默认库名 ry_ 加业务缩写如果你改库名这里的 url 和 SQL 脚本里的建库语句要同步改。另外注意字符集参数 characterEncodingutf8。危化品系统里涉及风险描述、隐患整改内容等中文长文本如果忘记这个参数写入数据库后中文变问号是大概率事件。XML 配置里的 Mapper 文件负责 SQL 与 Java 方法的绑定它们的 namespace 必须和对应 Mapper 接口的全限定名一致这是新手改代码时最容易翻车的地方——改了接口路径忘了同步 XML启动直接报绑定异常。2.3 VM 模板与代码生成这 26 个文件是给开发提速用的26 个 VM 文件在若依体系里属于代码生成器部分它们位于 ruoyi-generator 模块的 resources/vm/java 和 resources/vm/html 目录下。作用是通过模板生成标准的三层代码写一个表结构代码生成器读取表字段套用 VM 模板生成对应的 domain、mapper、service、controller 和前端页面。这套机制对危化品系统有实际价值双重预防机制的台账表很多比如风险点表、隐患登记表、整改记录表它们的 CRUD 模式高度相似用代码生成器把骨架一次性拉出来只改业务特殊的部分效率比手写高得多。我一般会建议拿到这套源码后先跑一次代码生成流程理解模板里 ${tableName}、${className} 这类占位符是怎么被替换的。改模板时有个技巧不要直接改源码包自带的 VM 文件而是复制一份放到自定义目录因为模板改动会影响之后所有生成的代码反向操作容易把框架原本的生成逻辑弄坏。实体类的生成规则尤其要注意字段类型映射——数据库的 datetime 类型在模板里默认生成 Date 对象如果你在危化品的隐患发现时间字段想直接用 LocalDateTime需要自己改模板里的类型映射规则否则生成代码后还要人工替换。3. 半小时跑起来数据库初始化、BAT 脚本与启动参数调优3.1 四个 BAT 脚本的职责边界源码包里有四个 BAT 文件ry.bat、run.bat、package.bat、clean.bat。初次接触可能觉得名字像随手起的但职责很清晰。ry.bat 是若依框架的启动入口封装内部调用 Maven 的 spring-boot:runrun.bat 和 ry.bat 高度相似有的版本里做的是启动前端或直接调用 java -jarpackage.bat 负责打包内部执行 mvn packageclean.bat 执行 mvn clean。我拆过的若依系项目有一半多都是这四个脚本的变体区别只在内部调用的模块名和目标 jar 包名。echo off echo 正在启动 RyoYi 危化品双重预防机制系统... set JAVA_HOMEC:\Program Files\Java\jdk1.8.0_202 set PATH%JAVA_HOME%\bin;%PATH% call mvn clean package -DskipTests -pl ruoyi-admin -am echo 打包完成正在启动... java -jar ruoyi-admin\target\ruoyi-admin.jar pause这段是典型的 package 加运行组合流程。解释一下关键点set JAVA_HOME 指定 JDK 路径这行在多人开发环境里尤其重要——如果你机器上的默认 Java 版本是 11 或 17而项目基于 JDK 8不显式指定就会编译失败-pl ruoyi-admin -am 是 Maven 多模块构建参数pl 指定构建的模块am 表示同时构建依赖模块若依框架拆了 ruoyi-admin、ruoyi-framework、ruoyi-system、ruoyi-generator 等多个模块直接对 admin 打包忽略了依赖模块会报找不到符号。窗口开着不关闭是为了看控制台日志排查启动问题最直接的方式。3.2 数据库初始化的正确手势两个 SQL 脚本对应若依的标准初始化套路一个脚本建库建表结构脚本一个脚本导入初始数据字典、菜单、管理员账号。执行顺序错了会直接报错因为数据脚本引用了结构脚本里的表。mysql -u root -p -e CREATE DATABASE IF NOT EXISTS ry_chem DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci; mysql -u root -p ry_chem /path/to/ry_2024.sql mysql -u root -p ry_chem /path/to/quartz.sql mysql -u root -p ry_chem /path/to/init_data.sql三条命令的含义第一条创建业务数据库字符集用 utf8mb4 而不是老的 utf8因为隐患描述里可能包含生僻字或特殊符号utf8mb4 能存四字节字符第二条导入若依框架的基础表结构用户、角色、菜单、部门第三条导入定时任务表结构第四条是初始数据。这里有个实际踩过的坑如果把初始数据脚本放最后打开系统会发现菜单是空的登录进去没有业务入口。判断哪个是数据脚本很简单——打开文件看内容是 CREATE TABLE 还是 INSERT INTO前者是结构后者是数据。3.3 环境依赖与启动参数调优启动这套系统前要确认三个环境变量JDK 版本8 或 11看项目 pom.xml 里的 maven.compiler 配置、Maven 版本3.5 以上、Redis 服务是否启动。若依的登录验证码和会话缓存依赖 RedisRedis 没启动时系统能跑但不是报登录超时就是验证码不刷新。# Windows 下启动 Redis 后验证连通性 redis-cli ping # 预期返回 PONG netstat -ano | findstr :6379关于启动参数调优我一般会在 ruoyi-admin 的启动脚本里追加 JVM 参数。核心就三个-Xms初始堆大小、-Xmx最大堆大小、-Dfile.encodingUTF-8。危化品系统的并发量通常不会特别大业务复杂度集中在数据准确性上堆内存给 512m 到 1g 足够但文件编码参数必须有——否则生成的导出 Excel 中文文件名会乱码。提示启动时看到报错里有 UnsupportedClassVersionError直接去查 JAVA_HOME 指向的 JDK 版本别去翻代码逻辑十有八九是版本不匹配。4. 把双重预防机制落进代码风险管控与隐患治理的实现套路4.1 双重预防机制的业务建模逻辑双重预防机制在安全生产领域指风险分级管控和隐患排查治理两者不是并列关系而是递进关系先把风险点辨识出来分级管控管控失效的环节再通过隐患排查发现并整改。落到系统里对应的是两条数据链路。风险分级管控链路涉及风险点、危险源、管控措施、风险等级四个核心实体。风险点表记录一个具体的风险区域或设备危险源表关联到具体物质或能量管控措施表描述工程技术措施和管理措施风险等级字段存重大/较大/一般/低四值。隐患排查治理链路涉及隐患登记表、整改任务表、复查记录表核心状态机是待整改、整改中、待复查、已闭环四个状态。这两条链路在一个共同基础上运行组织架构和用户权限。若依框架的部门数据权限在这里就派上了用场——分厂只能看到自己的风险点和隐患台账安全环保部能看到全部并督办。// 风险点实体核心字段对应 risk_point 表 public class RiskPoint extends BaseEntity { private Long id; /** 风险点编码规则区域-装置-序号如 R03-TA-011 */ private String pointCode; /** 风险点名称 */ private String pointName; /** 风险等级1-重大 2-较大 3-一般 4-低 */ private String riskLevel; /** 管控责任人ID */ private Long responsibleUserId; /** 所在部门ID */ private Long deptId; /** 风险描述 */ private String riskDescription; }字段设计的业务含义值得玩味。pointCode 直接遵循化工企业的风险点编码惯例这是为了跟现场的标识牌一一对应riskLevel 用数字不用中文是为了排序和统计方便没必要用枚举类业务上只有四种等级字典存值就够了responsibleUserId 用 Long 而不是字符串是为了保证责任人变更时能联动若依的用户体系。我在拆这套系统时觉得最有价值的是风险描述字段没有限制长度——这看起来是小事实际做安全管理的人都知道真正管用的风险描述往往是大段现场观察记录不是一句存在泄漏风险。4.2 隐患治理闭环的后端实现流程隐患治理的核心逻辑是状态流转和超期预警。前端提交隐患登记后Controller 层接收参数Service 层做数据校验并写入隐患表同时生成一条整改任务记录到任务表任务带有要求完成时间。整改完成后提交复查申请复查人通过后状态变为已闭环超期未完成的记录在定时任务里被标记为红灯预警。Transactional(rollbackFor Exception.class) public int submitRectification(SysHazard hazard, Long taskId) { // 1. 校验隐患数据完整性 if (StringUtils.isBlank(hazard.getHazardDesc())) { return error(隐患描述不能为空); } // 2. 更新隐患主记录状态为整改中 hazard.setStatus(2); hazardMapper.update(hazard); // 3. 创建整改任务记录 HazardTask task new HazardTask(); task.setTaskId(taskId); task.setAssignee(hazard.getResponsibleUserId()); task.setDeadline(DateUtils.addDays(new Date(), hazard.getRequiredDays())); task.setStatus(0); hazardTaskMapper.insert(task); return success(); }这段代码里有三个值得注意的地方。Transactional 注解保证了主记录更新和任务创建是原子操作不会出现隐患状态改了但任务没生成的脏数据——这在安全检查场景是零容忍的审计查起来要解释为什么状态和任务对不上setDeadline 用 requiredDays 加上当前时间算出截止日期而不是前端传一个日期字符串原因是日期计算必须后端定前端传参可以伪造task 初始状态 0 表示待处理后面的复查流程会沿着这表流转。我实际部署中在这个环节加过一个优化在 deadline 字段上建了索引因为定时任务每五分钟扫一次超期未闭环的记录没有索引的话数据量过万后扫描会拖慢主业务。4.3 实时监测数据的接入方式正文里提到的监测及排查信息对应的是重大危险源实时数据接入环节。危化品企业的储罐区、装卸区通常已有 DCS 或独立的气体探测器系统的接入方式一般是两种主动拉取或被动接收。主动拉取是系统定时轮询现场设备的 OPC 接口被动接收是现场通过 MQTT 或 HTTP 推送。考虑到这套源码里没有专门的物联网模块常见做法是写一个定时任务用 JDBC 直连现场数据库获取液位、压力、温度等测点数据再归一到系统的监测记录表。-- 监测数据表核心结构用于存储从现场采集的实时测点值 CREATE TABLE hazard_monitor_record ( id BIGINT AUTO_INCREMENT PRIMARY KEY, point_id BIGINT NOT NULL COMMENT 测点ID关联现场设备编号, monitor_time DATETIME NOT NULL COMMENT 数据采集时间, monitor_value DECIMAL(10,2) NOT NULL COMMENT 测点数值, limit_high DECIMAL(10,2) COMMENT 高限报警值, limit_low DECIMAL(10,2) COMMENT 低限报警值, is_alarm CHAR(1) DEFAULT 0 COMMENT 是否超限0-否 1-是, KEY idx_monitor_time (monitor_time) ) COMMENT 重大危险源监测数据记录表;这张表的设计核心是报警逻辑后置。测点数值和报警上下限存在同一行记录里查询时用一条 SQL 就能判断超限情况不需要在前端做二次计算。is_alarm 字段的建议是在采集写入时直接用 SQL 语句的 CASE WHEN 判断而不是在 Java 里判断再写回省一次数据库往返。5. 常见问题与避坑记录启动失败、乱码和数据不同步的排查顺序5.1 现象BAT 双击运行后直接闪退双击 ry.bat窗口一闪而过什么都没留下。原因脚本默认执行 mvn 命令如果 Maven 的 bin 目录没有加入 PATH 环境变量或者 JDK 版本不是项目要求的 8系统会找不到命令直接退出。解决不要双击在命令行里执行脚本这样窗口关闭时错误信息还在。运行前先执行 mvn -v 和 java -version 确认版本。如果命令行也闪退用编辑器打开 BAT 文件逐条手动执行里面的命令定位是 mvn 找不到还是 jar 包不存在。5.2 现象系统能启动但登录页验证码图片不显示登录页面加载出来了验证码区域是破图或空白后台日志没有明显报错。原因若依的验证码生成后存在 Redis 里请求校验时从 Redis 读取Redis 没启动或配置的连接地址不对都会导致这个现象。其次图片验证码生成的 Key 有失效时间服务器时间和 Redis 保存的时间不匹配也会导致刷新无效。解决先确认 redis-cli ping 返回 PONG再看 application.yml 里的 redis host 和端口是否被改过最后检查服务器系统时间是否正确这个坑很容易漏——虚拟机的时区没同步验证码生成了但比对时因为前后端时间偏差太大直接校验失败。5.3 现象数据库中文全部变成问号或乱码初始化完成登录进系统发现菜单乱码、字典值乱码。原因建库时字符集用了默认的 latin1或者 SQL 脚本导入时的连接字符集不是 utf8。这在 Windows 的 cmd 环境下导库时最容易出现因为默认代码页是 GBK。解决严格按建库命令指定 utf8mb4并在命令行执行 mysql 时加 --default-character-setutf8mb4 参数。已经乱码的库不能只改表字段字符集那样改不了已存数据需要导数据前改或者删库重建重新导入。5.4 现象修改了 Mapper XML 文件但程序行为没变化改了某条 SQL 的条件重启后效果和改之前一样。原因XML 文件编译到了 target 目录而 IDE 里修改的是 src 下的源文件如果没做 cleanMaven 增量构建不会重新拷贝 XML 到 target。这个问题在拆分模块后尤其常见改的可能是 ruoyi-system 下的 XML而运行的 jar 包头部缓存的是旧的类路径资源。解决执行 clean.bat 或者 mvn clean确保 target 目录清空后重新打包。代码改完不生效也是同一个套路先 clean 再跑不要省这一步。5.5 现象定时任务不执行日志里也看不到触发记录配了超期隐患扫描的定时任务到点没跑。原因若依的定时任务模块基于 Quartz任务被禁用或 Cron 表达式有问题都会被跳过。检查顺序看系统管理里的定时任务列表确认状态是启用核对 Cron 表达式是否写了未来时间看 ruoyi-admin 的启动日志中是否有 Quartz 初始化失败的报错。解决先在系统页面手动执行一次任务确认日志有输出再排查 Cron 解析问题。手动执行是区分任务配置问题和任务逻辑异常最快的方式。6. 进阶技巧用 Shell 把系统运维从手动变成定时任务系统部署在 Linux 服务器上后BAT 脚本就失效了Shell 才是生产环境的主角。标题里的Shell在这个场景下最实用的落点不是写多复杂的命令行而是把数据库备份、日志清理、应用健康检查做成三件套定时任务。以数据库备份为例危化品系统的数据有安全合规要求备份不能只靠人记。#!/bin/bash # 危化品系统数据库每日备份脚本 BACKUP_DIR/data/backup/chem_db DATE$(date %Y%m%d_%H%M%S) DB_NAMEry_chem DB_USERroot DB_PASSyour_password # 保留最近 7 天备份删除更早的 find $BACKUP_DIR -name *.sql.gz -mtime 7 -exec rm {} \; # 执行备份并压缩 mysqldump -u$DB_USER -p$DB_PASS --single-transaction --routines $DB_NAME | gzip $BACKUP_DIR/${DB_NAME}_$DATE.sql.gz # 记录备份结果到日志文件 echo $(date %Y-%m-%d %H:%M:%S) backup finished, file: ${DB_NAME}_$DATE.sql.gz /var/log/chem_backup.log几个参数的实际意义--single-transaction 保证 InnoDB 表在备份期间拿到一致性快照不对业务加锁这是生产环境必备选项--routines 备份存储过程和函数危化品系统里可能有统计用的存储过程漏了会导致恢复后功能缺失mtime 7 是清理策略保留 7 天具体天数根据你们公司的安全审计要求定——我们当时被要求保留至少 3 个月所以这个值要按需改成 mtime 90。备份脚本配合 crontab 设置每天凌晨执行# 编辑定时任务每天凌晨 2 点备份日志和错误分别输出 0 2 * * * /usr/local/bin/chem_backup.sh /var/log/chem_backup.log 21另一个值得做的 Shell 操作是启动服务并做健康检查。若依的可执行 jar 直接 nohup 启动后怎么快速判断它真的起来了靠日志里的 Started RuoYiApplication 关键字这是判断 Spring Boot 启动成功的标志比看进程存在与否更可靠。我用过的写法是启动后循环请求健康检查接口十次内不通过就报警for i in {1..10}; do HTTP_CODE$(curl -s -o /dev/null -w %{http_code} http://localhost:8080/login) if [ $HTTP_CODE 200 ]; then echo Service started successfully. break fi sleep 3 donew 参数和 %{http_code} 组合是 Shell 里做 HTTP 健康检查的惯用手段200 表示登录页可访问系统对外可用。最后说一个我自己的教训刚开始管理这套系统的 Linux 部署时备份脚本只写了备份逻辑没写日志结果某天磁盘满了备份失败过了两周才发现备份一直是空的。从那以后我每次写脚本都强制走一遍三件事输出日志、清理策略、手动执行一次确认。这套源码在 Windows 上跑通很容易但真正把它变成可持续运行的系统Shell 这头的功夫才是重头。希望帮到你。本文还有配套的精品资源点击获取