简介:基于RuoYi框架的前后端分离MES制造执行系统源码,定位为可直接落地或二次开发的项目模板,适合中小制造企业信息化建设者、若依框架开发者及课程实训学员。压缩包为RAR格式,整体约285.47MB,包含完整工程源码、数据库脚本以及详细的部署教程文档。系统功能覆盖系统管理、主数据、物料产品管理、工作站设置、生产管理、生产排产、节假日/工作日设置、排班日历、仓储管理、库存现有量、条码管理、设备管理、统计报表和可视化大屏等模块,能够帮助企业实现从基础数据维护到生产计划、执行、追溯、报表的闭环管理。资源已获得749人次浏览学习,若依开发者可通过对照源码理解前后端分离架构下的功能开发思路,实施运维人员则能借助文档快速完成环境搭建与配置。整体而言,这份资源既能用于快速构建MES原型,也可作为深入掌握若依框架和智能制造业务逻辑的综合性学习资料。
1. 项目概述与技术选型思路
搞工厂信息化这些年,我见过太多制造企业在MES选型上踩坑。要么买一套成品MES回来发现跟自家工艺流程对不上,要么找外包定制开发结果交付一堆没法维护的“屎山”代码。所以当我自己需要一套可二次开发的MES系统时,直接在开源社区里翻,最终敲定了基于Ruoyi框架的前后端分离MES方案。
这套系统解决的核心问题很直白:用成熟的开源框架解决权限、用户、菜单等通用后台能力,把开发精力全部集中在排产、工单、质检、追溯这批制造管理核心业务上。Ruoyi本身就是国内用得最多的Java后台管理框架之一,基于Spring Boot + Vue前后端分离,代码规范、文档齐全、社区活跃度高,用它做底座能省掉至少三周的框架搭建时间。
对于工厂端的需求来说,这套MES需要能落地跟踪三个维度的数据:在制品去到哪个工位了、当前工序合格率怎么样、这批物料批次号对应哪张销售订单。围绕这三个核心诉求,我梳理出了系统的五大功能域:基础资料管理(物料、工序、设备、产线)、生产执行管理(工单下发、报工、移转)、质量管控(检验、不合格品处理)、追溯管理(批次追踪、防错校验)和报表看板(产量统计、OEE、异常记录)。
提示:如果你所在企业已经有ERP系统,这套MES建议优先打通物料主数据和领料出库接口。MES管的是“车间怎么干活”,ERP管的是“这个活儿值多少钱”,两者数据对不上,上系统反而会制造更多管理混乱。
2. 核心功能模块与业务场景拆解
2.1 系统权限与组织架构设计
Ruoyi框架自带了一套完整的RBAC权限体系,包括用户、角色、菜单、部门四个核心要素。在MES场景下,我把它重新映射成了车间管理的实际业务角色:系统管理员负责基础配置,计划员下发生产工单,车间组长执行报工审核,质检员独立操作质量模块,设备管理员维护设备台账。
一个很容易被忽略的细节是数据权限。车间主任应该只能看到自己产线的数据,而不是全厂的数据。Ruoyi原生支持了数据权限隔离,我在工单、报工记录、质量检验单这些业务表上都预留了dept_id字段,配合框架的注解实现自动过滤,避免在Service层里反复写where dept_id = ?这种贫血代码。
菜单权限这块,我遵循了一个原则:按操作动作拆分按钮权限,而不是把整个页面扔给一组人。比如工单管理页面,计划员有新增和下达按钮,车间组长只有查询和报工入口,质检员则在质量模块里才有操作权限。这样配置权限后再去评审系统,业务部门基本挑不出毛病。
2.2 生产工单与排产计划管理
MES的排产业务我建议直接做一层抽象:从ERP接过来的生产订单在MES侧转换为内部工单,工单下可以挂多张工序流转卡。每张流转卡记录一个批次的产品在当前工序的投入数、产出数、不良数、报工人员和报工时间。
在数据库中,生产工单我设计了表结构如下:
CREATE TABLE mes_production_order ( id BIGINT AUTO_INCREMENT PRIMARY KEY, order_no VARCHAR(64) NOT NULL COMMENT '生产工单号', product_id BIGINT NOT NULL COMMENT '产品ID', plan_qty INT NOT NULL COMMENT '计划数量', completed_qty INT DEFAULT 0 COMMENT '完成数量', status TINYINT NOT NULL COMMENT '状态:0草稿 1已下达 2生产中 3完工 4关闭', plan_start DATETIME COMMENT '计划开始时间', plan_end DATETIME COMMENT '计划结束时间', create_by VARCHAR(32), create_time DATETIME, dept_id BIGINT ) ENGINE=InnoDB COMMENT '生产工单表';工单的推进顺序我按“下达—开工—报工—质检—完工”五个状态机流转,每一步都在前端页面和后端接口做双重状态校验,避免跳状态造成的生产数据错乱。排产甘特图这块用Vue + Gantt-elastic实现,按产线资源维度展示工单的时间排布,计划员拖拽调整时后端同步校验设备产能是否超负荷。
2.3 质量检验与不合格品处理流程
质量管理模块是最能体现MES价值的地方,也是二次开发量最大的部分。我实现了三种检验类型:来料检验(IQC)、过程检验(IPQC)、完工检验(FQC),分别对应原材料入场、工序流转中、成品入库前三个节点。
每种检验都支持按检验项目配置标准值上下限,报工时自动带出检验任务。比如某工序的关键尺寸要求是50±0.05mm,操作工报工时系统会强制弹出检验录入窗口,数值超出公差范围时直接拦截报工。这一块的价值在于把质量管控从“事后抽检”前移到“过程管控”,不良品还没流到下一道工序就已经被掐断。
不合格品处理是另一个关键流程。检验不合格的批次需要走“评审—返工/返修/报废—重新报工”的闭环。我在系统里增加了不合格品评审单,由质量工程师填写处理意见,选择“返工”的话系统自动生成返工工单流回对应工序。
2.4 生产追溯与物料批次管理
生产追溯是MES的硬指标,很多汽车、电子行业的客户审核就卡在这一项。我实现的追溯方案是正向与反向双向追踪:输入产品序列号可以查到它用了哪批物料、经过哪些工序、每道工序谁做的、检验数据是多少;输入物料批次号可以倒查这批料用在了哪些成品上,实现快速召回。
物料批次管理在初始化基础资料时就要反复强调:原材料入库时必须维护供应商批次号,产线领料必须扫批次码,完工入库时要把关键物料批次与成品序列号做关联绑定。这三点任何一环断掉,追溯链就补不回来了。
考虑到部分小微企业没有上PDA或扫码枪,我额外开发了手工录入追溯入口,允许在工位电脑上手动输入批次号。虽然效率不及扫码,但至少保住数据完整性,等后期上设备再平滑切换。
3. 部署环境准备与配置要点
3.1 环境版本清单与依赖选型
这套MES源码的技术栈是前后端分离的代表性组合,我在多台服务器和本地Windows环境上都跑通过,环境版本按下面这份清单基本不会出问题:
| 组件 | 推荐版本 | 说明 |
|---|---|---|
| JDK | 1.8(建议202以上小版本) | Ruoyi官方对JDK8支持最稳定 |
| MySQL | 5.7 或 8.0 | 生产环境务必8.0,支持窗口函数 |
| Redis | 5.x 或 6.x | 用于验证码、会话缓存和定时任务 |
| Node.js | 14.x ~ 16.x | Vue前端编译用,版本过高会报OpenSSL错误 |
| Nginx | 1.20+ | 生产环境静态资源转发和接口反向代理 |
| Maven | 3.6+ | 后端依赖管理 |
选JDK8而不是JDK11或17的原因很实在:Ruoyi框架和大部分第三方依赖对JDK8的兼容性验证最充分,遇到疑难问题更容易搜到解决方案。Node.js版本是个大坑,我试过Node 18编译ruoyi-ui时直接报error:0308010C:digital envelope routines::unsupported,这是OpenSSL版本不匹配造成的,要么降到Node16,要么设NODE_OPTIONS=--openssl-legacy-provider环境变量,但建议直接换版本省心。
3.2 源码目录结构解析
拿到源码第一件事是看懂目录结构,不要盲目在IDE里猛开项目。整体的工程分为两个主要部分:ruoyi-ui(前端Vue项目)和后端多模块Maven工程。
后端模块的设计逻辑我要多说几句。Ruoyi是一个单体多模块的架构,各个模块按职责拆分非常清晰:
ruoyi-admin -- 控制器入口层,放controller和启动类 ruoyi-framework -- 框架核心配置,安全、拦截器、AOP、线程池 ruoyi-system -- 系统管理模块,用户、角色、菜单、部门 ruoyi-common -- 公共工具类、注解、常量、通用返回对象 ruoyi-quartz -- 定时任务模块,基于Quartz实现 ruoyi-generator -- 代码生成模块,能一键生成单表CRUD代码 ruoyi-mes -- MES业务模块,我新增的业务代码全放这里我二次开发时把MES相关的实体、Mapper、Service、Controller全部放在ruoyi-mes模块里,少动框架原生的系统模块代码。这样后续升级Ruoyi版本时有明确的分界线,不会出现代码冲突牵扯不清的情况。这种“寄生式开发”的策略对基于开源框架做二次开发至关重要。
3.3 核心配置文件修改建议
后端配置文件集中在ruoyi-admin/src/main/resources/application.yml,生产环境建议用application-druid.yml做数据源扩展。我直接贴一份已经验证可用的核心配置片段:
spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driverClassName: com.mysql.cj.jdbc.Driver druid: url: jdbc:mysql://localhost:3306/mes_db?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8 username: root password: 你的数据库密码 initial-size: 5 min-idle: 5 max-active: 20 validation-query: SELECT 1 FROM DUAL redis: host: localhost port: 6379 password: 如果设置了redis密码就填 database: 0 token: expire-time: 120 # 令牌有效期单位分钟生产环境下我会额外开启Druid监控页面,在application.yml里配置druid.stat-view-servlet.enabled=true并设置独立的访问账号密码,方便排查SQL慢查询和连接池占用问题。这里要非常严肃地提醒一句:Druid监控页面上线前务必改掉默认的loginUsername和loginPassword,否则数据库连接信息直接裸奔公网。
前端配置文件在ruoyi-ui/vue.config.js里几个关键项:
devServer: { host: '0.0.0.0', port: 80, proxy: { '/dev-api': { target: 'http://localhost:8080', // 后端服务地址 changeOrigin: true, pathRewrite: { '^/dev-api': '' } } } }本机联调的时候前端走代理模式最方便,不用处理跨域,改后端代码自动热加载。但生产部署不建议用前端代理,直接把编译产物交给Nginx托管,用/prod-api指到后端接口地址。
4. 实操部署全流程与验证记录
4.1 数据库初始化与基础数据准备
先用Navicat或命令行创建数据库实例,我实际部署时用这行命令:
mysql -u root -p -e "CREATE DATABASE IF NOT EXISTS mes_db DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"接着导入两份SQL脚本:Ruoyi框架自带的ry_*.sql(系统管理相关表)和MES业务模块的mes_tables.sql(工单、工序、质检等业务表)。可能有人会问为什么不用自带的数据自动初始化功能,我的经验是手动导入能更清楚地掌握哪些表是框架的、哪些表是业务自己的,后续做数据迁移和备份时心里有数。
导入完成后进入sys_config参数表,把几个关键参数做调整:
UPDATE sys_config SET config_value = 'false' WHERE config_key = 'sys.account.captchaEnabled'; -- 测试阶段先关掉登录验证码,调通了再打开这一步仅限本地调试环境,生产环境务必保持验证码开启且建议升级为行为验证。
4.2 后端服务编译与区块配置
将源码导入IDEA,等Maven拉完依赖后,我的习惯是先整体执行一次clean package -DskipTests,确认编译通过再运行启动类。启动类位于ruoyi-admin模块下,类名RuoYiApplication,右键直接运行。首次启动会去加载Ruoyi定时任务配置和权限标识,日志刷到**“启动成功”并且Tomcat started on port(s): 8080**这句话出现就说明后端已经跑起来了。
启动过程中如果遇到Failed to configure a DataSource这类错误,九成原因是application.yml里的数据源连接参数没配对。拿日志里报的URL直接在Navicat测试一遍连接,能连上说明配置没错,否则就是账号权限或防火墙拦截的问题。
4.3 前端环境配置与本地联调验证
前端需要先安装依赖,在ruoyi-ui目录执行:
npm install --registry=https://registry.npmmirror.com npm run dev依赖安装时间取决于网络状况,国内开发者建议锁定淘宝镜像源,能够明显提升安装速度。只有命令行编号上:App running at: Local: http://localhost:80才表明前端已启动。
经验补充:npm install如果报
node-sass相关的错,大概率是Node.js版本和node-sass的对应关系不匹配。可以先npm uninstall node-sass再npm install sass --save-dev,把sass换成dart-sass实现,兼容性更好,编译速度也不差。
打开浏览器访问http://localhost:80,用admin/admin123登录(这是Ruoyi默认账号,生产环境务必修改),看到系统管理菜单和MES业务菜单都在左侧导航里,说明前后端联调成功。
4.4 Docker部署方案与Nginx配置
测试环境我用Docker Compose来编排整个环境,一份配置搞定MySQL、Redis和Nginx,极大降低部署出错的概率。
version: '3' services: mysql: image: mysql:8.0 container_name: mes-mysql restart: always environment: MYSQL_ROOT_PASSWORD: 你的密码 MYSQL_DATABASE: mes_db command: --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci volumes: - /data/mes/mysql:/var/lib/mysql - /data/mes/sql:/docker-entrypoint-initdb.d ports: - "3306:3306" redis: image: redis:6.0 container_name: mes-redis restart: always ports: - "6379:6379" nginx: image: nginx:1.20 container_name: mes-nginx restart: always ports: - "80:80" volumes: - /data/mes/nginx/conf:/etc/nginx/conf.d - /data/mes/dist:/usr/share/nginx/html depends_on: - java-app后端Java服务打包成JAR后直接java -jar运行,如果要容器化就自己写一个Dockerfile,基于openjdk:8-jre镜像,挂载JAR包和配置文件即可。Nginx的关键配置如下:
server { listen 80; server_name your-domain.com; # 前端静态资源 location / { root /usr/share/nginx/html; index index.html index.htm; try_files $uri $uri/ /index.html; # Vue history路由关键配置 } # 后端接口反向代理 location /prod-api/ { proxy_pass http://java-app:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } }try_files这一行是Vue路由不空白页的核心关键,缺少它刷新页面直接404。另外生产环境也要考虑Nginx对请求体大小的限制,MES在图片上传和报表导出时经常遇到413 Request Entity Too Large错误,在http块加一行client_max_body_size 50m就能解决。
4.5 上线前的完整功能验证清单
系统部署完成后不能直接扔给车间用,需要按业务主线跑一遍完整的验证流程。我整理了一份个人常用的上线验证清单:
- 创建几个不同角色的测试账号,验证菜单权限和数据权限隔离是否正确
- 新建一个产品信息和BOM,确认编码唯一性和失效校验生效
- 下达一张生产工单,跑通“下达—开工—报工—检验—完工”全链路
- 故意录入一条超差检验数据,验证过程检验拦截是否生效
- 用同一个物料批次号做正向和反向追溯,核对追溯链数据完整性
- 验证定时任务,比如日报表推送和库存低位预警,观察日志和消息队列消费情况
- 检查Druid监控页面的慢SQL清单,对执行时间超过2秒的SQL做索引优化
这份清单建议打印出来逐项打钩,不要嫌麻烦。工厂上线系统最怕的就是“看着能跑,一用就挂”,提前把核心路径验证扎实,后面能省无数扯皮的功夫。
5. 部署与运维中的典型坑与排查技巧
5.1 深色表单Token过期与登录弹回
这是前后端分离项目常见问题,表现是用户登录后没过多久就被踢回登录页。排查思路按三步走:先看Redis里的token缓存是否还在,再确认网关或Nginx的会话超时配置是否过短,最后检查服务器时间和本机时间是否相差太大,JWT签发和校验对时间偏差极其敏感。
我线上曾经遇到一次诡异问题:服务器和本机时间相差了8个小时(时区设置错误),导致签发出来的token在本地校验时永远早失效,后来通过统一在启动脚本里加-Duser.timezone=GMT+8参数解决了。
5.2 前端编译内存溢出导致构建失败
多模块工程前端在构建的时候,偶尔会遇到JavaScript heap out of memory报错,尤其在服务器配置不高的情况下。处理方式是在编译脚本里调整Node内存限制:
NODE_OPTIONS=--max-old-space-size=2048 npm run build:prod或者对webpack配置做适当的cache优化和并行压缩、,都能减少内存占用。如果连续构建多次仍失败,留意下是不是服务器本身内存太小,至少保证2G以上可用内存再编译。
5.3 附件上传后无法预览
MES里我集成了工单附件、检验图片的存储功能,默认存在本地磁盘目录。部分服务器上能上传成功但预览时打不开,定位后是文件读写权限问题。Tomcat或Java进程以什么用户启动,就要给上传目录授权对应用户:
chown -R 服务启动用户:服务启动用户 /data/mes/upload同时注意在application.yml里配置ruoyi.profile时,不要用相对路径,统一用绝对路径,否则换目录部署时奇奇怪怪的问题会一个接一个冒出来。
5.4 生产工单号自动生成规则冲突
MES的业务表在设计时我实现了工单号、检验单号、追溯批次号等多处自动编码。一开始用“日期+流水号”的格式,比如MO20250215001,上线运行一段时间后出现编号不连续的问题。原因是并发请求下如果用常规的查询max值再加1的方式生成,两个请求同时读到同一个max,就会产生重复编号。
按下这个坑是在编码生成逻辑上引入Redis自增计数器,固定前缀按天作为Redis key,利用INCR命令的原子性保证编号唯一且连续。这样一天内编号从1开始递增,第二天自动重置,多实例部署也不会撞号。这是个非常典型的并发安全问题,千万别等到线上出了问题再改,代价太大。
再提醒一句:MES这类系统的定时任务建议用Ruoyi自带的Quartz管理,不要自己另起线程池跑。Quartz的持久化任务存储可以保证任务宕机恢复后还能继续执行,而普通线程池没有这方面的保障。
6. 二次开发方向与个人踩坑心得
这套源码真正有价值的地方在于它可以作为一条生产线数字化改造的骨架,业务上还能往下面这几个方向持续扩展。
第一个方向是设备数据采集(SCADA)。在MES基础之上增加Modbus、OPC UA协议的采集网关,设备实时产量、运行状态和故障代码直接汇入MES看板,实现透明生产。这部分的重点是抽象一层设备接入服务,不同通信协议的设备统一上报到消息队列,再由MES消费更新工单进度。
第二个方向是与条码/RFID系统的深度集成。目前追溯链依赖人工录入,如果条件允许,引入PDA扫码或固定式读码器,报工效率和准确性都会有质的提升。接口设计上建议单独做一个mes-api模块,预留统一的物料扫码、工位上报、序列号绑定接口,方便外部硬件接入。
第三个方向是移动端适配。车间主管不可能天天抱着电脑看数据,用Ruoyi的移动端框架做一个简化版的移动端,看工单执行进度、处理异常消息、审批不合格品评审单,这些场景都是刚需。
最后分享一点个人感受——这套系统的成长过程遵循一个原则:先在最小的业务范围内跑通,再逐步扩大覆盖范围。不少工厂上线MES一开始就想把所有车间和所有流程都管起来,结果团队学习成本陡增,实施周期无限拉长,最后项目就烂尾了。务实的做法是选两条典型产线试运行,把数据流和业务流彻底理顺,员工操作习惯培养起来,再复制到全厂,成功率会高得多。
对正在准备上MES的企业来说,用这套源码做技术可行性验证和人员培训,确实是一个低成本、收益明晰的起步路径。真正跑起来之后你会发现,车间里那些以前靠口头沟通的信息,都被明确地记录在系统里,管理效率的提升是看得见摸得着的。
本文还有配套的精品资源,点击获取