恒美微站
首页
关于我们
建站服务
主题模板
案例展示
资讯中心
联系我们
基于SpringBoot+Vue的MES生产制造执行系统开发实战
首页
资讯中心
/
基于SpringBoot+Vue的MES生产制造执行系统开发实战
基于SpringBoot+Vue的MES生产制造执行系统开发实战
发布时间:2026/10/5 7:10:40
1. 标题背后这个MES系统到底要做到什么程度1.1 先给MES一个清晰的定义别急着写代码我之前带过几个做毕设的学弟也评审过不少企业内部自研的MES项目发现一个通病拿到基于SpringBootVue的MES生产制造执行系统这个标题就直接开敲代码写到一半才发慌——因为压根没想过MES到底覆盖哪些业务。先把这个概念捋清楚。MESManufacturing Execution System制造执行系统是处于企业ERP企业资源计划和底层工业控制PLC、SCADA、传感器之间的那一层信息化系统。它管的不是财务、不是采购订单而是车间里今天生产什么、谁在做、做到哪一步了、良率多少、设备状态如何这类实时执行层面的问题。标题里如果只写MES生产制造执行系统多数情况下指的是离散制造或流程制造场景里最核心的那一部分生产工单管理、报工、工序流转、质量检验、设备状态。有的还会带上生产计划排程、物料批次追溯、看板展示。具体到你要交付的系统第一步不是写代码而是跟用户一起划边界。这里有个非常现实的问题MES是个很大的概念工业界有人说MES有11大功能模块包括资源分配、作业计划、数据采集、质量管理、绩效分析等。如果你全做半年都做不完。毕设也好、企业内部小规模试点也好通常需要聚焦在以工单流转为主线以报工和质量数据为核心的最小闭环上。我在实际推进这类项目时的做法是先问自己三个问题——系统服务的对象是谁车间主任、班组长、一线操作工还是质量工程师系统上线后第一个月要回答什么问题今天各产线完成了多少工单、有没有异常、合格率是多少数据从哪里来人工录入、扫码枪、还是设备自动采集这三个问题回答清楚了功能清单自然就出来了标题也就有了具体的肉身。1.2 功能清单与边界划定一个可以直接抄的MVP方案结合标题生产制造执行系统这个粒度我给一个经过验证的、工作量可控的功能划分方案你可以直接拿去做需求说明书模块核心功能优先级说明基础数据物料管理、BOM物料清单、工序定义、工作中心/产线P0没有这些工单无从谈起生产工单工单创建、派工、工单状态流转待开工→生产中→完工P0整个系统的生命线报工管理工序报工、完工数量录入、工时填报、异常上报P0车间用得最多的页面最好能支持扫码质量检验来料检、过程检、完工检不合格品记录P1质量模块是MES区别于进销存的关键设备管理设备台账、点检记录、运行状态P2可先做台账和状态点检计划后补生产看板车间大屏或PC看板展示工单进度、产量趋势、异常警报P1这是最能看见效果的模块系统管理用户、角色、权限、字典、日志P0基于SpringBootVue的项目基本都有现成框架为什么把质量和追溯也放进来因为很多初学者把MES做成了电子工单填写系统只有记录没有闭环。真正的MES哪怕是最简化的版本至少要能回答这批货是哪个工单做的、哪道工序、哪个操作工、用的哪批物料、检验结果是什么。这就倒逼你必须设计好数据表之间的关系而不是各写各的模块。边界划定这块我建议在第一版明确砍掉这些高级排产APS复杂度远超MES本身、设备PLC实时采集需要硬件和工业协议至少留到二期、与ERP的深度集成这是另一个系统的故事最多留个接口位。先做一个能在真实车间跑起来的闭环比做一个看起来很大但哪都飘着的系统强得多。2. SpringBoot Vue这个选型组合背后是有讲究的2.1 为什么不是JSP单体也不是微服务全家桶现在很多教材还在教JSPServlet那套也有部分项目一上来就上SpringCloud Alibaba全家桶加Docker加K8s。放到MES这个场景里这两个极端都不合适。单体JSP方案的痛点在于前后端耦合太深。MES这类系统的页面交互频率很高——工单列表要随时刷新、报工表单要动态校验、看板要轮询或推送数据。用JSP做这些不是不行但每次改个样式、调个交互都要重新编译部署整个War包车间里用着的系统不可能让你这么折腾。另外现在前端生态里Vue、Element UI这类组件库带来的开发效率提升是JSP时代完全没法比的。微服务方案对MES来说是过度设计。一个几百人规模的工厂并发量再高也远没到需要拆几十个微服务的程度。而且MES的业务逻辑本质上围绕工单状态流转这条主线服务拆得越细跨服务调用和分布式事务问题越复杂。你想想看一个报工动作同时要更新工单进度、插入产量记录、可能还要扣减WIP在制品数量这些操作在单体应用里就是一个本地事务拆成微服务后每个都得处理最终一致性对开发者的要求完全不是一个量级。SpringBootVue的组合是质量、效率和复杂度的黄金平衡点。SpringBoot负责把后端的业务逻辑、权限、数据持久化整理得干干净净Vue负责把车间用户需要的交互体验做出来。前后端通过JSON交互接口清晰联调方便部署也简单——一个Fat Jar可执行jar包就能跑起来。对MES这个场景来说这种实用主义的选型思路比追逐技术潮流重要得多。2.2 若依这类脚手架能不能直接拿来改我的真实建议热搜词里面反复出现若依框架mes基于若依框架的mes说明很多人已经意识到从零搭一套SpringBootVue的后台管理系统光是用户、角色、菜单、字典这些基础功能就得写两周不如直接用开源脚手架。我的态度很明确能用就用但必须想清楚你是在用框架还是在被框架用。若依RuoYi这类脚手架确实把SpringBoot后台管理该有的东西都准备齐了统一认证、权限控制、代码生成器、定时任务、操作日志等。我曾见过好几个MES项目在RuoYi基础上改三个月就上线了第一版效率确实高。但这里有几个坑必须先有心理准备第一脚手架的代码风格一旦接受了后面很难改。RuoYi的Controller通常返回AjaxResultService层习惯上直接用实体类接收参数这些风格在你项目初期没什么问题但一旦并发量上来或业务复杂到一定程度你会想重构到时候代价非常大。第二代码生成器生成的东西只适合管理后台不适合车间操作端。RuoYi的代码生成器擅长生成标准的单表CRUD页面——物料列表、用户列表这种。但MES里最核心的报工页面是扫码→自动带出工单→填数量→提交这种高频操作流生成器给不了这种交互。所以我的用法是脚手架只用来解决系统管理和基础架构核心业务页面必须自己动手设计。第三权限模型要提前设计。RuoYi默认的权限粒度是菜单和按钮级别这对MES够用但车间场景还有一个特殊需求不同班组的工单可见性隔离。比如冲压A班的员工登录后应该只看到A班对应的工单和产量。这需要你在标准的RBAC之上再叠加一层数据权限的过滤逻辑RuoYi自带的DataScope注解可以帮你做这个但前提是你理解它的原理而不是无脑套用。2.3 JDK与SpringBoot版本搭配版本太高到底是怎么个高法热搜词里有条springboot版本太高这句话在MES项目的语境下通常有两种含义要么是SpringBoot版本和JDK版本不匹配导致启动失败要么是Spring Boot 3.x之后的一些API变化把老代码搞崩了。以现在的环境来看我建议的稳定搭配是JDK 17 SpringBoot 2.7.x或3.x取决于你的依赖生态 Vue 3 Element Plus。JDK 8确实还能跑SpringBoot 2.x但从2025年这个时间点往回看新项目不建议再用JDK 8了JDK 17是LTS版本长期维护且SpringBoot 3.x已经全面转向JDK 17基线。这里有个容易被坑的细节如果用了SpringBoot 3.x很多老版本的第三方组件用不了。比如你搜springboot整合activemqspringboot整合flink这些组件在SpringBoot 2.x时代的配置方式到了3.x可能全变了。所以我的原则是团队的熟练度比版本新更优先。如果团队之前的主力是SpringBoot 2.xJDK 8那就维持这个组合别为了追新把整个技术栈的风险拉高。MES系统用户最在乎的是稳定不是框架版本有多新。实际启动配置里还有两个小细节值得注意。第一spring-boot-maven-plugin的版本要和SpringBoot父依赖版本一致否则打包后运行会报no main manifest attribute。第二如果你的MES系统用到了WebSocket看板推送SpringBoot 2.7之后内置的WebSocket支持要求在配置里显式注册ServerEndpointExporter这个坑我后面会展开说。3. 核心模块拆解从生产计划到完工报工数据是怎么流起来的3.1 基础数据建模BOM、工序、工作中心的表结构设计思路MES系统里最无聊但最重要的部分是基础数据。你工单建得再漂亮如果BOM物料清单是错的后面全完。我在设计基础数据表时通常遵循三件套原则物料、工艺路线、工作中心。物料表mes_material核心字段没什么悬念物料编码必须唯一、物料名称、规格型号、单位、物料类型原材料/半成品/成品、默认仓库。这里要强调一点物料编码一旦生成并投入使用尽量不要允许修改。因为这些编码会被工单、BOM、库存记录反复引用改编码等于把所有历史数据都弄脏了。我在实际项目中遇到过用户要求改编码的情况最后是通过新增一个新编码物料停用旧编码的方式解决的而不是真的去改原记录。BOM表mes_bom的设计要分两级比较好mes_bom_headerBOM头存成品物料、版本号、状态mes_bom_itemBOM行存子件物料、用量、损耗率。用过ERP的人都知道BOM有版本管理的问题MES也一样——工艺改版了、物料替代了都要靠版本来控制。建议BOM头表加一个is_active字段同一成品物料只允许一个有效版本。工艺路线表mes_route是MES里容易被忽略但极其核心的表。它定义了生产这个物料要经过哪些工序每道工序的序号是多少在哪个工作中心做。至少要有工序编码、工序名称、工序序号、工作中心ID、标准工时、是否质检工序。为什么工艺路线重要因为工单下发后每道工序的报工顺序、质检节点都依赖它。没有工艺路线的话报工就是一笔糊涂账。工作中心表mes_workcenter可以理解成车间里的一组设备或一个产线单元。比如冲压A线装配B线检测C区。字段至少包括工作中心编码、名称、所属车间、负责人、状态启用/停用、产能可选。工作中心和设备的区别要搞清楚工作中心是产能和排产的单位设备是具体执行单位。MVP阶段可以简化成工作中心下面挂设备先把台账建起来设备点检和状态采集放到二期。3.2 工单生命周期与状态机设计这是整个MES的命脉如果说基础数据是MES的骨架工单就是血液。工单模块设计得健不健壮直接决定系统能不能在车间里活下来。我对工单状态的定义通常是这样的可以根据实际场景增删状态含义触发动作已创建工单刚刚导入手动创建成功还没有下发新建/导入已下发生产指令下达车间班组长可见并可派工下发/审核生产中至少有一道工序开始报工首道工序报工已完工所有工序均完成报工且质检通过末道工序完工报工质检确认已关闭工单数据归档不再允许任何修改关闭操作已取消因计划变更等原因作废取消操作通常要二次确认为什么状态机这么重要因为MES里每一个状态变更往往都伴随着业务校验。比如已创建不能直接变成生产中必须先下发已完工的工单不允许再报工加数量除非走返工流程重新打开。这些规则写在Service层里比写在一堆if-else里要清晰得多。我在实操中有一个心得工单编号的生成建议独立设计不要用数据库自增ID。格式可以是WO 日期 流水号比如WO20250607001。原因是车间用户对编号有天然的习惯认知拿到编号就能看出来是哪天下达的、第几张工单。用代码在Service层加锁生成或者用一个单独的sequence表防止高并发下重复。一次性批量导入工单时尤其要注意这个并发问题我在测试时真的踩过——多线程导入生成了一模一样的工单号因为社保都没有对生成逻辑做同步。工单详情页面还要展示产品信息、计划数量、已完工数量、合格数量、不良数量、进度百分比完工数量/计划数量等聚合数据。建议这些聚合字段不要实时去报工表里count而是在报工提交时同步更新工单表的累计字段。省下的查询开销很可观车间列表页按小时刷新的场景非常吃这个优化。3.3 报工、质检与物料追溯把数据闭环做完整的实践报工是整个MES里头最贴近操作工的功能。我见过的失败案例里大部分是报工页面设计得太复杂工人不愿意用。报工的核心诉求只有一个让操作工用最少操作把我做了什么、做了多少、用了多少时间真实记录进系统。MVP阶段的报工页面我建议采用列表弹窗模式产线上的平板/电脑显示当前工单的未完成工序列表点击某道工序弹出报工窗口填写完工数量、报废数量、备注有条件的接扫码枪直接扫工单条码带出所有信息。报废数量不要和完工数量混在一个输入框里否则后面质量统计没法做。质检模块的设计分两种独立质检和工序内检。独立质检是质检员用专门的质检页面录入检验结果工序内检是操作工在报工时同时录入自检数据。MVP阶段建议先把独立质检做出来质检任务可以从完工工单中生成检验结果包括合格数量、不合格数量、缺陷代码建议先做缺陷字典表。只有工单的完工数量被质检确认之后这个工单才算真正完成。批次追溯是MES常提起但MVP阶段容易被砍掉的功能。砍掉也能上线运行但我建议至少留一张物料批次流转表mes_material_trace字段包括物料编码、批次号、来源工单、去向工单、工序编号、操作工、时间、数量。理由很简单现在不记批次将来一旦出现质量客诉你想查都没地方查。早期哪怕只记工单号不记供应商批次也先把追溯的路径打通后面要扩展再补。4. 后端接口与业务逻辑的实现要点SpringBoot侧的关键代码思路4.1 RESTful接口设计与统一返回体MES系统的接口设计我建议老老实实走REST风格因为前后端分离下大家认知成本最低。资源路径的设计直接对应业务对象/api/workorder工单、/api/report报工、/api/quality/inspection质检结果、/api/material物料等。统一返回体这块RuoYi里叫AjaxResult自己写也行。核心就一个原则前端只要看code就知道成功还是失败错误信息要人话。我常用的结构是{ code: 200, message: 操作成功, data: { } }code200代表成功非200代表业务失败500代表系统异常。这里有实用建议不要把数据库的异常堆栈直接抛给前端。Controller层要用RestControllerAdvice做全局异常拦截把SQLIntegrityConstraintViolationException这种硬核错误翻译成数据已被引用无法删除这种业务语言。接口的命名还有个细节——所有干活的接口都用POST查询可以用GET。为什么因为MES里大部分写操作报工、转发、审核、关闭一旦执行就是状态变更用POST最稳妥避免刷新页面时浏览器重复弹确认框。查询接口注意要支持分页和筛选条件列表页不可能把所有数据一次性拉过来。4.2 RBAC权限模型菜单、按钮、数据三个维度要分开做权限这个东西没做之前觉得简单做了之后发现全是细节。SpringBootVue的MES系统我建议分三个维度来做权限第一维是菜单权限——用户能看到哪些菜单和页面。这个通常用前端路由守卫加后端菜单查询结合实现。后端根据用户角色返回菜单树前端动态生成路由表。RuoYi自带这个能力数据库里维护菜单表即可。第二维是按钮权限——用户能点哪些按钮。比如班组长能下发工单操作工只能报工。实现方式是在按钮上绑定一个类似system:workorder:dispatch这样的权限标识前端根据用户拥有的权限集合判断是否渲染。注意这些标识要在后端接口上也校验前端隐藏只是用户体验后端校验才是安全底线。第三维是数据权限——用户只能看哪些数据。车间场景这个需求非常具体A班的操作工登录后看不到B班的数据。实现上可以维护工单表里的shift_group字段班组/车间查询时根据当前用户的属性自动拼过滤条件。如果在RuoYi基础上做可以用它自带的DataScope注解去搞本质上是MyBatis在SQL层面动态拼了一条过滤条件。这里有个非常容易踩的坑权限校验不能只依赖前端路由守卫。我见过有项目把操作工不能访问工单列表只写在Vue路由的beforeEach里后端接口照样能不带token直接访问这是个灾难级漏洞而且测试一测一个准。正确的做法是后端接口的PreAuthorize注解做硬校验前端路由守卫只负责交互体验。4.3 并发与唯一性控制报工别把数据写重了MES现场有一个天然的特殊场景多个操作工可能同时给同一个工单的不同工序报工甚至极端情况下同一工序重复提交。后端不做并发控制的话工单的完工数量会出现超过计划数量、重复扣库存这些问题。我的做法是三层防护第一层数据库唯一约束。报工表mes_report加一个唯一索引字段组合可以是workorder_id process_id report_no报工单单号这样同一工单同一工序的重复报工请求直接就被数据库挡回来。第二层业务校验锁。在Service层的报工方法上加Transactional并且用select for update锁定工单行记录再校验当前累计完工数量 本次报工数量 计划数量。为什么加select for update因为事务隔离级别默认的可重复读并不能防止两个事务同时读同一行然后各自累加必须把行锁住让第二个事务等第一个提交。第三层接口幂等。前端在报工提交按钮点击后立刻置灰/loading防止连点后端接收报工请求时检查report_no是否已经存在存在则直接返回该报工记录已提交请勿重复操作。这个设计对扫码枪连扫两次的场景特别有效。给自己留个提示MVP阶段的报工并发量其实不大三层防护主要防的是人肉重复点击而不是高并发但是一旦你把MES接入了PDA扫码枪或者PAD端这些防护就变成刚需了。所以宁可早做别等出了重复数据再补。5. 前端Vue的实现细节页面结构、路由、数据交互怎么组织5.1 Vue3 Element Plus的页面结构规划MES系统的前端我强烈建议基于Vue 3 Vite Element Plus来搭。Element Plus是Element UI的Vue3版本对后台管理系统的表格、表单、弹窗、树形组件覆盖得很全面。加上Vite的开发服务秒启动调试体验比Webpack时代好太多。页面结构建议遵循布局框架业务页面的两层设计。布局框架用一套统一的侧边菜单顶部栏内容区主内容区用一个router-view承载由布局组件统一管理。业务页面按照模块拆成目录src/views/ ├── dashboard/ # 生产看板 ├── material/ # 物料管理 ├── bom/ # BOM管理 ├── workorder/ # 工单管理 ├── report/ # 报工管理 ├── quality/ # 质检管理 ├── device/ # 设备管理 └── system/ # 系统管理用户/角色/菜单/字典每个业务页面内部建议切成三个文件而不是一个巨大的单文件组件index.vue页面入口、components/xxxForm.vue业务表单弹窗、api/xxx.js接口请求封装。这样做的收益是——当MES业务逻辑膨胀的时候你能很快定位是改页面还是改表单还是改接口。不过要提醒一句Vue页面不要做得太花哨车间用户最烦花里胡哨的加载动画和大屏特效。表格、表单、状态、按钮清晰地摆在面前是最好的。生产看板可以做得悦目一些但核心还是信息密度和刷新及时性。5.2 路由设计与管理动态路由 路由守卫Vue路由在MES项目里核心关注两件事动态加载菜单和登录鉴权。如果你的权限模型是后端根据用户角色返回菜单树那前端就需要做动态路由。登录成功拿到菜单数据后用router.addRoute循环注册路由然后再next()放行。这里有个我踩过的坑直接刷新页面时报匹配不到路由。原因通常是刷新时beforeEach里拦截到目标路由但此时路由还没注册完。解法有两种要么在beforeEach里等菜单加载完成再next({ ...to, replace: true })要么在全局守卫里维护一个hasLoadedRoutes标志位加载过一次就不重复加载。这是MES前端最容易出问题的环节之一一定要自己在测试里反复刷新验证。路由守卫的职责分配建议如下未登录无token→ 一律跳转/login已登录但访问不存在的路由 → 跳转到404页不要让白屏裸奔已登录但当前用户没有某菜单权限 → 跳转到首页或提示无权限不要直接放行后端接口仍然要校验另外MES项目管理后台通常会有多角色访问管理员、计划员、班组长、质检员。页面不要因为角色的不同做完全不同的版本角色的差异性尽量体现在按钮和字段权限上。比如质检员登录后可以看到所有工单列表但只能看到质检按钮计划员可以看到派工按钮操作工登录后默认跳转到自己的报工页面这些在路由层和按钮权限层配合实现即可。5.3 axios封装、token处理与跨域问题前后端分离第一个绕不开的话题就是请求封装和跨域。axios封装这块不要省统一在一个文件里管理所有请求。我给出的封装思路// src/utils/request.js import axios from axios const service axios.create({ baseURL: /api, // 后端统一前缀 timeout: 20000 // 车间网络环境不一定好给足超时时间 }) // 请求拦截器自动挂token service.interceptors.request.use(config { const token localStorage.getItem(token) if (token) { config.headers[Authorization] token } return config }, error Promise.reject(error)) // 响应拦截器统一处理状态码 service.interceptors.response.use( response { const res response.data // 根据后端code判断业务是否成功 if (res.code 200) { return res.data } else { // 这里可以根据业务失败做统一提示比如删除冲突 return Promise.reject(new Error(res.message)) } }, error { // 401 未登录/登录过期统一跳登录页 if (error.response error.response.status 401) { localStorage.removeItem(token) location.href /login } return Promise.reject(error) } ) export default service跨域问题在开发环境下最常见。Vue开发服务器端口一般是5173Vite默认SpringBoot端口一般是8080直接请求必然跨域。我推荐的做法是开发环境用Vite的proxy代理// vite.config.js server: { proxy: { /api: { target: http://localhost:8080, changeOrigin: true, // 不需要rewrite后端Controller就是/api/something前缀 } } }代理的好处是前端代码里统一写/api/xxx不用写全路径生产环境再把/api反代到后端同一个域名下开发生产和部署环境的口径就是一致的。实际上线之后把Vue打包出的静态文件直接放进SpringBoot的static目录下同源部署就不存在跨域问题了这也是标题中出现的vue打包放进springboot中所对应的核心诉求后面第六节我会专门讲。5.4 生产看板的实时刷新WebSocket还是轮询车间看板是MES系统里最能体现实时生产状态的模块。每次报工之后产量、工单进度、设备状态都变了看板如果还停留在旧数据上车间主任第一个炸。有两个方案可以做轮询前端每隔5秒或10秒调一次接口拉最新数据。优点是实现简单后端只需要写一个查询接口前端用setInterval定时请求。缺点是每次刷新都是全量数据数据量大时浪费带宽但MVP阶段的车间看板数据量通常不大轮询完全可行。WebSocket后端在报工服务里主动推送消息给所有在线的看板客户端。优点是实时性极高、省流量缺点是接入复杂度上升还要处理断线重连、心跳保活的问题服务端需要维护一个WebSocket连接池。我的建议是MVP阶段先用轮询把看板做出来跑通业务后期如果实时性要求高了再平滑切换WebSocket。而且即便用轮询也要注意后端接口的性能看板接口尽量走轻量的聚合查询SQL里用子查询或者冗余字段不要在接口里循环查数据库。另外给轮询接口加一个Cacheable或者用本地缓存做10秒级的过期能显著降低数据库压力。如果你决定用WebSocketSpringBoot端有一个大坑SpringBoot 2.7及以上版本默认不自动扫描ServerEndpoint注解的Bean。必须新建一个配置类注入ServerEndpointExporterConfiguration public class WebSocketConfig { Bean public ServerEndpointExporter serverEndpointExporter() { return new ServerEndpointExporter(); } }不搞这一步WebSocket端点永远注册不上去客户端连不上前端控制台会报404。我当年在这个坑里卡了小半天所以特别写出来提醒后来的人。6. 部署与运维Vue打包进SpringBoot以及上线后遇到的坑6.1 标准打包流程前端build后端Fat JarMES系统的部署架构MVP阶段我强烈推荐单机部署后端一个SpringBoot进程前端静态文件交给SpringBoot托管数据库用MySQL所有东西跑在一台服务器上。车间人数少、并发低这个架构完全扛得住。具体打包流程分三步第一步前端构建cd mes-web npm run build构建完成后dist目录下生成静态文件index.html js/css资源。第二步把构建产物复制到后端cp -r dist/* ../mes-server/src/main/resources/static/第三步后端打包cd ../mes-server mvn clean package -DskipTests执行完会在target目录下生成一个可执行jar包比如mes-server-1.0.0.jar。运行java -jar mes-server-1.0.0.jar --spring.profiles.activeprod这里有个容易忽略的配置。SpringBoot的static目录优先级低于classpath下的public、resources、META-INF/resources只要你的页面资源不是放在static下访问就是404。而且如果你用spring.mvc.static-path-pattern自定义过静态资源映射前缀Vue打包出来的资源路径就很可能匹配不上。我建议把Vue的资源放在src/main/resources/static/下然后不要修改spring.mvc.static-path-pattern的默认值默认是/**。如果非要改记住把Vue路由的history模式改成hash模式或者让后端写一个Controller转发所有非API请求到index.html二选一别让环境配置和打包路径打架。6.2 一次静态资源404的完整排查链路从页面白屏到找到真凶标题的热搜词里有vue打包放进springboot中这个话题我太有发言权了。虽然流程看着简单但实战里十有八九会遇到问题。我复盘一次真实经历你看完就懂了。现象是这样的把前端打包放进后端static目录浏览器访问http://localhost:8080/index.htmlHTML内容正常返回但控制台报一堆JS/CSS资源404页面白屏。我当时的排查链路是这样的第一步先看HTML源代码。Vue打包后的index.html里面JS和CSS的引用路径是长这样的script src/assets/index-abc123.js/script注意看这里是绝对路径/assets/...而不是相对路径./assets/...。这意味着浏览器会去请求http://localhost:8080/assets/index-abc123.js。第二步检查assets目录是否真的在static下。我打开target/classes/static/assets目录文件确实在。那为什么404第三步看SpringBoot的静态资源映射。SpringBoot默认把classpath:/static/映射到根路径/**。理论上/assets/index-abc123.js应该能命中。我一度怀疑是缓存问题清理了浏览器缓存还是404。第四步抓请求响应。发现500错误而非404点进去看异常堆栈报的是No mapping for GET /assets/index-abc123.js——这是Spring MVC在告诉你它根本没找到这个路径对应的Handler。第五步突然反应过来项目里配置了一个WebMvcConfigurer里面定义了registry.addResourceHandler(/upload/**) .addResourceLocations(file: uploadPath /);虽然这个配置只针对/upload/**但我又想起来为了做后端接口统一返回我在配置里加过spring.mvc.static-path-pattern/static/**这就完蛋了。一旦设置了static-path-pattern/static/**SpringBoot的默认静态资源映射就从/**改成了/static/**。Vue打包出来的HTML引用/assets/xxx.js自然就404。第六步解决。把spring.mvc.static-path-pattern改回/**或者把Vue的base路径改成/static/。我最后选了后者因为希望保留一个/static前缀方便后端做统一API前缀隔离。修改Vite的base配置// vite.config.js export default defineConfig({ base: /static/, // ... })重新打包、部署资源全部正常加载页面不再白屏。这个坑给我留下的教训是一旦发现页面白屏静态资源404优先怀疑是不是改了static-path-pattern而不是一上来就怀疑目录放错位置。同样的道理如果页面能打开但刷新某个子路由时404那一般是前端路由用了history模式而服务器没有把非API请求转发到index.html要么切hash要么在后端加一个ViewController转发。6.3 服务器部署建议MySQL、环境变量、日志与监控部署MES系统到生产环境除了打包还有几件小事必须做不然上线当天就会出事。数据库环境变量化。数据库地址、用户名、密码不要写死在application.yml里用${DB_HOST}这种占位符加上--spring.datasource.urljdbc:mysql://...启动参数去覆盖。理由很简单代码库会被多个人共享仓库里只要有生产环境的数据库密码bash就是一个安全隐患。日志别打到控制台就完了。logging.file.namelogs/mes.log改成输出到文件日志级别建议info。同时配置logback的按天滚动和保留天数一般保留30天足够。MES系统上线初期查日志是你定位问题最重要的手段没有之一。看板接口依赖数据库查询高峰期要留意慢SQL。在application.yml里打开慢SQL日志spring.jpa.show-sqlfalse mybatis.configuration.log-implorg.apache.ibatis.logging.stdout.StdOutImpl这个能帮你直观看到每次操作实际执行的SQL。但注意生产环境不要把SQL打到接口返回里不然接口性能报表都是假的。监控这一块热搜词里有skywalking能部署到mes制造系统上面吗。这个问题我可以直接回答能但你得评估投入产出。SkyWalking是APM应用性能监控工具对SpringBoot应用来说部署方式是一个Java Agent配置好之后它能自动采集调用链、JVM指标、慢查询等信息。对MES系统来说最大的价值是当某个报工接口突然变慢你能一眼定位是哪个SQL慢、哪次远程调用卡了而不是靠猜。但我的建议是MVP阶段不必上SkyWalking先把基础的日志和MySQL慢日志做好就够了。原因很简单MVP阶段系统复杂度低你完全能靠日志定位问题过早引入APM工具一是多一个中间件要维护二是它对JVM有性能开销虽然通常忽略不计。如果你是非要上不可注意SkyWalking Agent要和SpringBoot的JDK版本兼容JDK 17配8.x版本没问题JDK 21要确认Agent版本兼容性再上。7. 一些掏心窝的话MES系统的成功不在技术本身写到最后我还是想讲点技术之外的东西。做MES系统这些年我最大的感受是MES项目的成败七成在业务沟通三成在技术实现。很多人在SpringBoot和Vue里投入了全部精力把接口写得漂漂亮亮、页面做得精致无比上线后却发现车间用不起来。为什么因为需求阶段你没跟车间主任聊透工单的流转在你们实际现场到底走哪些环节没跟操作工确认过你们最受不了的是不是每做一道工序都要在电脑上点好几下。我在第一版MES上线后连续一周蹲在车间看工人怎么用发现报工页面把完工数量和报废数量分开两个输入框其实已经很好了但操作工还是经常把数量填反。后来加了确认弹窗——本次报工完工100报废2确认提交——这个改动比后端任何性能优化都管用。如果你正在做这个标题下的项目无论它是你的毕业设计还是公司试点项目我的终极建议是第一版功能砍到不能再砍但数据闭环要走完整。工单必须能流转报工必须能触发产量更新和质量记录看板必须能看到实时状态。哪怕界面简陋一点性能慢一点只要业务上是闭环的这个系统就是活的就能继续演进。技术选型上SpringBootVue已经被无数项目验证过是MES这个体量的最佳拍档不用怀疑自己。版本搭配上稳住别追求最新。模块划分上抓住工单、报工、质量三条主线。部署上守好打包进static、注意静态路径映射、跨域交给代理这几个关键点你就能把一个看着唬人的MES生产制造执行系统从标题变成车间里真正在用的工具。