从立项到落地:我如何用SpringBoot+Vue3+MyBatis把工厂车间管理系统从零撸出来
做工厂车间管理系统这事儿,听起来像是大厂给制造业客户定制的活,实际上用主流Java技术栈完全可以自己搞定。如果你正在找一套能直接二开、结构清晰、前后端分离的SpringBoot+Vue3+MyBatis+MySQL车间管理源码,或者准备自己动手从零搭一套,这篇分享应该能帮你省下不少查资料的功夫。
这套系统的核心价值在于:把车间里最常遇到的“工单流转、工序报工、物料领用、产量统计”这些业务流程,通过一套B/S架构的Web应用管起来。前端Vue3负责交互,后端SpringBoot提供接口,MyBatis做数据库操作,MySQL存业务数据。我这个项目就是从这些需求出发,一步步设计并实现出来的。我会把技术选型、数据库设计、后端接口、前端页面的完整思路,以及实际开发中踩过的坑都整理出来,不管是想学习还是想直接复现,都能有个清晰的方向。
1. 项目概述与整体设计拆解
1.1 车间管理到底管什么
接触过制造业项目的同学都知道,车间管理的本质其实是“三流合一”:实物流、信息流、数据流。工人干完一件活,在系统里输入工号、工序号、数量、工时,这就把实物的加工进度变成了信息流;这些信息汇总到数据库,再生成产量报表、设备利用率、人员绩效,这就是数据流。车间系统做得好不好,就看这三条流能不能顺畅地流转起来。
我设计这套系统的第一件事,就是先把业务边界画清楚。参考市面上常见的MES(制造执行系统)功能模块,但不过度设计,只保留了车间日常管理中最核心的模块:
- 基础数据管理:产品、物料、工序、工位、设备、班次
- 生产工单管理:工单创建、派工、状态流转、查询
- 工序报工与计时:按工序登记合格数、不合格数、工时
- 物料领用与退料:计划领料、实际领料、余料退回
- 质量检验记录:首检、巡检、完工检的模板与记录
- 产量与绩效统计:按班组、按日期多维度汇总
这套模块划分的思路是“基础数据先行、业务数据为主、统计报表兜底”。基础数据是一切的前提,设备没建档、工序未定义,工单就没法排产;业务数据是系统每天要产生的大量流水记录;报表则是管理者打开系统最希望看到的东西。如果一开始就把权限、审批、消息通知这些辅助功能铺开,很容易陷入“为了复杂而复杂”的泥潭。
1.2 为什么选前后端分离架构
前后端分离在这套系统里不是跟风,而是有明确诉求的。车间环境的现场终端通常不只一种:办公室里的PC、车间现场的触屏一体机、班组长的平板电脑,这些设备的浏览器版本、屏幕尺寸差异很大。前端用Vue3单独部署,后端只暴露JSON接口,意味着将来要在车间加一台PDA扫码终端,只需要开发对应的移动端页面,后端接口完全不用动。
还有一个重要原因是团队协作。后端同学专注SpringBoot的接口和业务逻辑,前端同学专注Vue3的组件和页面交互,两边只要提前约定好接口文档,就可以并行开发。我用Swagger/knife4j做接口文档,前端开发过程中直接在线调试,效率比传统的JSP或Thymeleaf模板方案高很多。
当然,前后端分离也有代价,最直接的就是部署复杂度上升,以及要面对跨域问题。这套系统里我在后端统一配置了跨域过滤器,允许指定来源的请求访问接口,同时在前端用axios走代理转发,双保险处理。实测下来只要配置对了,跨域基本不会成为开发的拦路虎。
1.3 技术栈选型的核心考量
技术栈选择方面,我在立项时其实做了一个小表格对比。后端Java是主力,生态成熟、招人容易、长期维护有保障;SpringBoot是当前Java后端的事实标准,自动配置能力大幅降低了整合成本;MyBatis在制造业这种“复杂SQL、多表联查、字段多且杂”的场景下比JPA更顺手,SQL可控性强,优化起来也直观;MySQL在中小并发规模下性能稳定、运维简单、社区资料多。前端Vue3的组合也是一套公开发布社区验证过的技术栈。
值得强调的是版本选择。很多教程给出的SpringBoot版本是2.x,如果你跟着做没问题,但新版SpringBoot 3.x要求JDK17,MyBatis-Spring-Boot-Starter也升级到了3.x,两者的包名和组织ID都有变化。我在项目里锁定了SpringBoot 2.7.x + JDK8 + MyBatis 2.x的组合,这是目前兼容性最稳、资料最多的搭配。这套系统中数据库用MySQL 8.0,注意8.0的默认认证插件和5.x不同,驱动也需要用新版。
2. 数据库设计:一张表一张表抠出来的车间数据底座
2.1 核心业务表的结构设计
车间系统的数据模型是典型的主-子结构加状态机流转。以生产工单为核心,往下挂工序计划、报工记录、物料消耗、质检结果,形成一个以工单为主线的业务闭环。
先把核心表的结构理出来供参考:
| 数据表 | 核心字段 | 设计要点 |
|---|---|---|
| t_work_order | order_no, product_id, plan_qty, status, plan_start, plan_end | 工单编号唯一,状态初始为CREATED |
| t_process_plan | order_id, process_no, process_name, work_station, standard_hours | 每个工单拆成多道工序 |
| t_work_report | order_id, process_plan_id, worker_no, qualified_qty, defective_qty, work_hours | 报工的唯一性由工序+人员+日期约束 |
| t_material_requisition | order_id, material_id, requ_qty, act_qty, return_qty | 领料数量不允许超过BOM计划上限 |
| t_quality_record | order_id, process_plan_id, check_type, check_result | check_type区分首检、巡检、完工检 |
| t_equipment | equipment_code, equipment_name, status, maintenance_cycle | 设备状态与工单工序相关联 |
这张表是反复推敲后的结果。比如工件报工表t_work_report,我给它加了一个业务唯一索引(order_id, process_plan_id, worker_no, report_date),防止同一个人在同一天对同一道工序重复报工。刚开始没加,结果测试阶段就出现了重复数据,后来才补上,算是踩过的第一个坑。
工单状态字段我用的字符串枚举(CREATED、RELEASED、IN_PROCESS、COMPLETED、CLOSED),没有用数字。虽然业界有争论说数字省空间、查询快,但在实际开发中字符串枚举可读性更强,日志里直接能看出来状态含义,排查问题时不用对着数字查字典。对中小规模系统来说,这点存储开销完全可以忽略。
2.2 冗余字段与统计效率的取舍
车间系统有个特性:数据量涨得很快。一台设备一天报工几十条,一个车间几百人,一个月的流水就是几万到几十万条。等到要统计月度产量的时候,如果全靠多表JOIN去实时计算,数据库的压力非常大。
我的方案是在业务表中适当冗余部分字段,减少查询时的联表次数。举例来说,报工表t_work_report里除了关联外键,还冗余了product_id、product_name、workshop_name这些展示字段。表结构多几个字段,换来的是查询统计时少了几张表连接,这买卖对车间这种高频率写入、中低频复杂查询的系统来说非常划算。
这个思路同样用于工单表。t_work_order里我冗余了product_name、customer_name、plan_qty_text,这样列表页加载工单时一条SQL就能查出所有关键信息,不需要每个字段都JOIN字典表。
2.3 数据库字段与索引的实操细节
字段类型选择上遵循几条实用规则:数量字段一律用INT,不做成DECIMAL;工时字段用DECIMAL(10,1),保留一位小数就够了;金额相关的用DECIMAL(12,2);业务状态字段用VARCHAR(20)存英文枚举;备注类字段用VARCHAR(500),不要太长。这样做的原因是让字段语义一目了然,后端实体映射时也不容易出错。
索引设计这块,初期设计只给主键和外键建了索引,后来在排查接口慢的时候才发现问题。经过实际调优,最终形成了一套索引方案:
- 工单表:order_no建唯一索引,status、plan_start_date各建普通索引
- 报工表:业务唯一索引覆盖(order_id + process_plan_id + worker_no + report_date),报工日期单独建索引用于日报统计
- 物料表:material_code唯一索引
- 设备表:equipment_code唯一索引,status普通索引
这里的核心经验是不要过度索引。车间系统写入频繁,每多一个索引就多一次写操作的开销。我见过一些项目在手腕表上建了七八个索引,结果导入数据时慢得离谱。原则就是:高频查询的WHERE条件建索引,JOIN字段和外键建索引,其他的别犹豫,删掉。
3. 后端核心实现:SpringBoot接口设计和MyBatis实战
3.1 后端项目结构与分层思想
后端工程我按标准的分层架构来做:controller、service、mapper、entity、dto、vo,外加common包存放统一返回结果、异常处理、工具类。用Maven做依赖管理,项目结构如下:
src/main/java/com/example/workshop ├── controller # 接收请求,参数校验,返回结果 ├── service # 业务逻辑层,事务管理 │ └── impl ├── mapper # MyBatis的Mapper接口 ├── entity # 数据库实体映射 ├── dto # 入参对象 ├── vo # 出参对象 ├── common # 统一返回、异常、常量 └── config # 跨域、MyBatis、异步配置controller层保持轻量,主要做参数接收和返回;业务逻辑都下沉到service层,保证service方法内部有完整的事务边界。这张图看起来平平无奇,但这样分层的好处是长期维护一个规模适中的项目时非常省心——接口出问题,第一眼就能判断是参数校验的问题还是业务逻辑的问题。
3.2 统一返回结构与全局异常处理
前后端分离项目必须统一返回格式,否则前台拿到数据时根本不知道如何处理。我在common包里定义了一个Result 类,结构很简单:
{ "code": 200, "message": "success", "data": {} }code为200代表成功,其他数字代表各种业务异常。前端axios封装里根据code作统一判断,成功就处理data,失败就弹出message。
全局异常处理这块用了SpringBoot的@RestControllerAdvice,拦截所有未被捕获的异常。最重要的一点:业务异常和系统异常必须分开处理。业务异常(比如“物料库存不足”“工单已关闭不允许报工”)返回200但code不为200,系统异常(比如空指针、数据库连接失败)返回500。这是我在实际项目中踩过的坑——早期把业务异常也throw成500,前端拿到后只知道“系统错误”,用户根本不知道怎么处理。
3.3 MyBatis的SQL写法与动态查询
MyBatis在这套系统里的使用,核心是XML文件里的动态SQL。车间系统的查询条件非常多,工单列表要根据状态、日期范围、产品分类、工单号模糊查询,如果每个组合都写一条SQL,工作量不可想象。用 和 标签拼接条件,一条SQL搞定:
<select id="selectWorkOrderPage" resultType="com.example.workshop.vo.WorkOrderVO"> SELECT wo.id, wo.order_no, wo.product_name, wo.plan_qty, wo.status, wo.plan_start_date, wo.plan_end_date FROM t_work_order wo <where> <if test="orderNo != null and orderNo != ''"> AND wo.order_no LIKE CONCAT('%', #{orderNo}, '%') </if> <if test="status != null and status != ''"> AND wo.status = #{status} </if> <if test="startDate != null"> AND wo.plan_start_date >= #{startDate} </if> <if test="endDate != null"> AND wo.plan_start_date <= #{endDate} </if> </where> ORDER BY wo.create_time DESC </select>这里有个细节值得注意:日期比较用的是>和<,这是XML中的转义写法,直接用大于号小于号会报XML解析错误。类似这种转义问题,不写一遍根本不会记得,网上的资料也容易漏掉。
另一个MyBatis的实用场景是批量插入。报工数据经常是工人一次性录多道工序,前端传一个列表过来,后端如果用for循环逐条插入,性能差不说,还容易造成事务长度不稳定。我用MySQL的批量插入语法,Mapper里写:
<insert id="batchInsertWorkReport"> INSERT INTO t_work_report (order_id, process_plan_id, worker_no, qualified_qty, defective_qty, work_hours, report_date) VALUES <foreach collection="list" item="item" separator=","> (#{item.orderId}, #{item.processPlanId}, #{item.workerNo}, #{item.qualifiedQty}, #{item.defectiveQty}, #{item.workHours}, #{item.reportDate}) </foreach> </insert>配合service层的事务注解@Transactional,要么全成功要么全回滚。这对报表统计的一致性非常重要,如果中途插入一半失败,工单进度就错了,后面排产都会跟着错。
3.4 MyBatis缓存机制的坑与经验
网上讲MyBatis缓存的内容不少,我在实际项目中也体会到了它的存在感。MyBatis一级缓存默认开启,作用域是SqlSession;二级缓存默认不开启,需要手动在Mapper XML中配置 。
我的建议是:车间业务系统里不要开二级缓存。原因很简单,数据实时性要求高,工人刚报完工,马上要在看板看到最新的产量数据。二级缓存可能导致另一个会话查到的还是旧数据,除非你花大量精力管理缓存刷新策略,否则得不偿失。一级缓存在同一个SqlSession中查出不同数据的概率本来就低,保持默认配置就好。
真正影响性能的是整个查询链路。我遇到过一次工单列表接口很慢的问题,排查后发现是N+1查询——先查主表数据,再循环查询每个工单的工序进度。解决办法是改成一次性联表查询,或者用MyBatis的collection嵌套查询(但要注意Mysql的limit问题)。这类问题不做压测很难发现,等你看到接口响应时间超过三秒就晚了。
4. 前端Vue3实现:从登录到工作台的完整模块开发
4.1 前端工程结构与核心目录
前端部分基于Vue3 + Vite + Pinia + Vue Router + Element Plus来构建。Vite的启动速度和热更新体验比Webpack时代好了一个量级,对前后端分离开发来说,前端体验直接影响调试效率。
目录结构按业务模块划分:
src ├── api/ # 所有接口请求封装,按业务模块拆文件 ├── assets/ # 静态资源 ├── components/ # 全局通用组件 ├── layout/ # 后台布局,侧边栏、顶栏、主内容区 ├── router/ # 路由配置,含动态路由 ├── store/ # Pinia状态管理 ├── views/ # 页面组件,按模块分包 │ ├── dashboard/ # 工作台首页 │ ├── order/ # 工单管理 │ ├── report/ # 报工管理 │ ├── material/ # 物料管理 │ ├── quality/ # 质量管理 │ └── system/ # 用户与角色权限 └── utils/ # 工具类,axios封装、日期处理等这样的目录结构让多人协作开发时互不干扰。每个开发者在自己的views目录下加页面,在api目录下加接口文件,遇到冲突的概率很小。实践中这种按模块划分的组织方式,比较适合中后台管理系统。
4.2 axios封装与接口请求规范
axios封装是前端开发的第一个核心环节。我在utils/request.js里创建了一个axios实例,统一配置baseURL、超时时间、请求拦截器和响应拦截器:
const service = axios.create({ baseURL: import.meta.env.VITE_API_BASE_URL, timeout: 15000 }) service.interceptors.request.use(config => { const token = localStorage.getItem('token') if (token) { config.headers['Authorization'] = 'Bearer ' + token } return config }) service.interceptors.response.use(response => { const res = response.data if (res.code !== 200) { ElMessage.error(res.message) return Promise.reject(new Error(res.message)) } return res.data }, error => { ElMessage.error(error.message || '请求失败') return Promise.reject(error) })两个实用小技巧分享:一是在响应拦截器里直接把data解出来,页面里调用接口时就不用写两层解构;二是遇到401时在这里统一跳转登录页,并清理本地token。这样授权过期的处理逻辑集中在一个地方,而不是散落在每个页面。
时间格式化也是车间的刚需。我封装了一个dayjs工具函数,报表页的日期范围、工时计算的格式化都复用它,避免每个页面写重复代码。
4.3 动态路由与权限控制
车间系统的用户角色分三类:车间主任、班组长、操作工。三种角色看到的菜单和操作按钮完全不同。主任看全模块报表,班组长能派工和审批,操作工只能报工和查看自己的记录。
我用动态路由实现权限控制。登录时后端根据用户角色返回一份权限标识列表,前端在路由守卫里判断当前用户能访问哪些页面,不能访问的直接重定向到首页。具体实现是:router里先放一份完整的静态路由配置,登录后根据权限过滤出菜单并在router.addRoute()里动态添加。
按钮级别的权限通过自定义指令v-permission实现,没有权限的元素直接被移除。这个方案比单纯在页面里写if判断更优雅,而且方便统一管理。权限数据从后端接口一次性拉取,存Pinia里,全局都能访问。
4.4 工作台与报表页面的数据可视化
车间系统的首页工作台是给管理者每天打开就要看的东西,我用Vue3集成了ECharts。最核心的是三个图:产量趋势折线图(近7天每日合格产量)、工序完工率柱状图、设备状态饼图。数据来源是后端提供的统计接口,前端拿到后转换成图表需要的格式,用ECharts的watch属性监听变化并更新图表。
图表这块有个经验可以分享:ECharts在Vue3里不要直接写在生命周期里init一次就不管了,如果数据异步加载,图表的option更新需要调用setOption。我封装了一个useEcharts的Composition API,把init、setOption、resize、销毁这四件事放在一起管理,页面引入后传一个option对象和容器ref就完事。这样报表模块里十几个图表配置起来不会出现重复样板代码。
5. 关键业务流程的闭环实现
5.1 工单创建到完工的完整流转
车间系统的核心业务是工单流。生产计划员创建工单,工单状态为“已创建”;之后工单被派发到车间班组,状态变成“已下达”;工人开始报工时,状态自动更新为“进行中”;所有工序都完成了,状态变为“已完成”;最后车间主任复核产量与工时数据,工单“关闭”。
后端我在每个状态流转的service方法里做了前置校验,防止跳过中间的步骤。比如工单要从“已创建”变成“已下达”,必须先校验工单是否存在、是否处于正确的状态、工序计划是否已维护。这个状态机设计到位后,整个系统的数据一致性就有了保障。
有人可能觉得这点逻辑简单到不值得写,但我见过太多系统的状态字段就是摆设,前端随便传一个字符串就能让工单变成任意状态。一旦数据乱了,后面所有统计报表全废,这是制造业老板最不能忍的。
5.2 报工逻辑中的事务一致性
报工功能是整个系统使用频率最高、最容易出问题的功能。操作工输入工序号、合格数量、不合格数量、工时、日期,点保存。后端的处理链是:写入报工记录、更新工单累计产量、更新工序计划完工数量、写一条设备使用日志。这一步涉及四张表的更新,必须放在同一个事务里。
为了让报工逻辑不至于在并发场景下出错,我给工单累计产量字段加上了乐观锁。worker更新完成产量时,SQL是:
UPDATE t_work_order SET completed_qty = completed_qty + #{qty} WHERE id = #{orderId}这种累加式的更新天然具有原子性,比先查后写安全得多。并发两个工人同时报工,MySQL的行锁保证了不会丢数据。之前有人问“要不要用Redis做锁”,我个人觉得这个场景根本不需要——数据库层面的行锁已经解决了问题,引入分布式锁是过度设计。
5.3 物料领用与库存联动的设计
物料模块的核心是领用与消耗的联动。车间根据工单的BOM来领料,系统会校验领料数量不能超过计划数量;实际完工后的退料数量又会回补库存。这个模块最容易出问题的地方在于“物料编码不统一”。前期如果物料基础数据不规范,同样的螺丝在不同工单里可能编成两个不同的编码,库存就会永远对不上。
所以在基础数据模块里,我设计了一个物料档案的导入功能,支持通过Excel批量导入,但在导入时强制校验物料编码的唯一性,重复的直接在导入结果里提示。这一步在系统上线初期非常关键,基础数据质量决定了后续所有数据的可信度。
6. 环境搭建与部署上线全记录
6.1 开发环境版本匹配方案
版本匹配是新手最容易踩坑的地方。我这边锁定的开发环境组合如下,照着配基本不会出兼容性问题:
| 组件 | 版本 | 备注 |
|---|---|---|
| JDK | 1.8 | 稳定、主流教程最多 |
| SpringBoot | 2.7.18 | 2.x系列的最后一个版本 |
| MyBatis Starter | 2.3.1 | 与SpringBoot 2.7兼容 |
| MySQL | 8.0.x | 如果之前项目用5.7也没问题 |
| Node.js | 18.x | Vite5要求Node18+ |
| Vue | 3.4.x | 当前稳定版 |
| Vite | 5.x | 构建工具 |
| Element Plus | 2.x | Vue3的UI组件库 |
重点说说为什么不用SpringBoot 3.x。SpringBoot 3.0强制要求JDK17,很多公司的生产服务器还是JDK8环境,如果为了追新导致部署环境不兼容,就得不偿失了。SpringBoot 2.7是2.x的最后一个版本,安全补丁和维护都还跟得上,属于这个技术栈下的务实选择。打算用SpringBoot 3.x的朋友,需要替换MyBatis starter依赖的groupId,这也是我在热词里看到“springboot版本太高”这个问题时的真实感触。
6.2 MySQL配置与初始化
MySQL安装完成后,需要创建数据库并初始化表结构。我开发时用的初始化SQL脚本,注意了三点:字符集统一utf8mb4、排序规则utf8mb4_general_ci、数据库时区与Java应用保持一致。
连接信息方面,我用的是:
jdbc:mysql://localhost:3306/workshop_db?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/ShanghaiuseSSL=false这个参数是MySQL 8.0的常见问题来源。MySQL默认开启SSL导致Java连接时报SSL连接错误,一开始我排查了很久,最后确认是在连接URL上加useSSL=false解决。如果你用MySQL 8.0安装时选了默认的caching_sha2_password认证插件,老版本的驱动可能会报认证失败,升级驱动到8.x即可。
6.3 前后端打包与部署
开发环境调试没问题后,要把系统部署到生产环境。前端Vue3项目执行npm run build,产物在dist目录,里面是纯静态文件。我用Nginx来托管前端静态文件,同时配置反向代理,把/api前缀的请求转发给后端的SpringBoot应用。
关键Nginx配置片段:
server { listen 80; server_name your-domain.com; location / { root /var/www/workshop-front; try_files $uri $uri/ /index.html; } location /api/ { proxy_pass http://127.0.0.1:8080/; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; } }try_files那行是给Vue Router的history模式用的,否则刷新页面会404;proxy_pass末尾的斜杠表示把/api/前缀去掉再转发给后端,后端接口不需要感知客户端的前缀配置。这套配置我在多个项目里验证过,稳定可靠。后端jar包用java -jar启动,配合systemd做守护进程,重启后自动拉起。
7. 常见问题与排查技巧实录
7.1 数据库连接与启动失败类问题
问题一:启动SpringBoot时报数据库连接拒绝
一般是MySQL没启动、端口被占用、连接地址或账号密码错误。排查三步走:确认mysql服务状态、确认防火墙放行3306端口、用命令行客户端测试连接。
问题二:报Communications link failure
这个问题在MySQL 8.0上很常见,大概率是useSSL和时区参数没配好。在连接URL上加上useSSL=false和serverTimezone=UTC,通常能解决。还不行就看MySQL的wait_timeout和Java连接池的连接验证配置,增加一个test-on-borrow的配置项。
问题三:Maven依赖下载慢
国内网络环境下换阿里云镜像,在settings.xml里加mirror配置。这里提醒一点:SpringBoot项目用Maven构建时优先确认maven和JDK版本匹配,maven 3.8以上配合JDK8没问题。很多“构建失败”的报错并不是代码问题,而是环境问题。
7.2 跨域与会话问题
问题一:前端调用接口报跨域错误
我的方案是后端写一个WebMvcConfigurer,配置CorsRegistry允许指定来源。同时开发环境在前端配置Vite的proxy代理,让浏览器看起来是同源请求。两种方式都要做,因为开发环境走代理,生产环境走Nginx,场景不同。
问题二:登录后请求没有携带token
检查前端请求拦截器有没有在header里加上Authorization,检查后端有没有配置允许Authorization头通过跨域请求。Word: 后端配CORS时,allowedHeaders里要写上Authorization,否则浏览器会因为CORS预检失败而拦截请求。
7.3 数据与性能问题
问题一:工单列表接口越来越慢
数据量增长后的常见症状。排查后发现是没加索引导致全表扫描,在WHERE条件和ORDER BY字段上补了索引,速度快了十倍不止。另外还做了分页查询,列表接口强制要求传入pageNum和pageSize。
问题二:报工数据重复
这是业务逻辑问题,不是技术问题。我在报工表上加业务唯一索引从源头兜底,同时在service层增加了查询校验,双保险后这个问题彻底消失。
问题三:报表统计口径对不上
报表数据不准,99%是SQL写错或者事务边界不对。拿产量日报举例,要确保统计的是报工表中合格数量的汇总,而不是工单表中的计划数量。建议报表开发完成后,拿一个已知数据的日期做人工核对,确认后再上线。车间系统上线后直接面对一线使用者,报表出错一次,后续人家就不信任系统了,翻盘成本极高。
7.4 前端开发常见问题速查
| 问题现象 | 原因 | 解决方案 |
|---|---|---|
| 刷新页面404 | 未配置try_files | Nginx配置回退到index.html |
| 图表不更新 | 未调用setOption | 监听数据变化并调用setOption |
| 菜单不显示 | 权限数据未加载完加载了路由 | 在路由守卫里await store初始化 |
| 请求重复发送 | 未处理token过期自动重试 | 拦截器统一处理401跳转 |
这些都是我实际开发过程中一个一个排掉的坑,每个都能让你卡上一段时间。把这些记录放在一起,是希望大家能少走弯路。
最后说说我个人在实际项目中的体会。做车间管理系统这类业务软件,技术栈真不是最难的部分,难的是理解业务、设计数据模型、处理好边界条件。SpringBoot+Vue3+MyBatis+MySQL这套组合足够成熟稳定,交给新人也容易接手。我在开发这套系统的过程中,最大的收获不是掌握了某个新框架,而是学会了怎么把一个模糊的业务需求拆解成表结构、接口和页面。后续这个项目我还在考虑加入消息推送(比如工单完工后自动通知下道工序操作工)、设备联网的Iot数据接入,以及基于历史产量数据的预测分析。如果你也准备做或正在做类似的项目,欢迎交流经验,毕竟车间管理的水很深,团队合作才能少犯错。