news 2026/9/29 17:52:06

Node.js+Vue五金车间生产计划管理系统开发复盘

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Node.js+Vue五金车间生产计划管理系统开发复盘

五金车间最像打仗的地方不是生产线,而是计划员那张桌子。我刚做完的这套基于 node.js 和 vue 的五金工厂车间生产计划管理系统,想解决的正是这个问题:把销售订单变成可执行的车间计划,再把计划和执行之间的信息差抹平。做之前我以为最难的是排产算法,做之后才发现最难的是让计划员、车间主任和工人对同一组数据有一个统一的认识。这篇文章我会从业务背景、技术选型、模块设计、数据库与后端细节、前端落地,再到上线踩坑,完整复盘一遍,适合正在考虑自研或选型工厂管理系统的团队参考。

1. 五金车间的排产痛点:Excel、ERP 之间的那块空地

1.1 五金车间生产管理的业务特征

五金工厂和电子厂、汽配厂的管理重点差别很大。五金件常见的工艺是冲压、拉伸、机加工、抛光、电镀或者氧化,工序数量不多,但它是典型的多品种、小批量、插单频繁的业态。一个车间里同时可能有几十个在制订单,每一张订单又可能拆成三五个规格,每个规格对应一套模具或者一个加工程序。

这种业态下,真正难管的地方反而不是工艺,而是“什么时候开哪台机、用哪套模具、做多少个、做完给谁”。冲压车间换一次模可能需要半小时,如果排程不合理,一天的有效产出直接打六折。机加工车间则要错开不同订单对同一台设备的争抢,但交期晚一天客户就催。

我接触过不少五金厂,计划员手上同时维护三样东西:一张 Excel 总排程表、一块写在白板上的插单信息、以及手机里各种微信群里的临时通知。Excel 表本身没有约束力,插单一进来,整张表就要重新拖一遍;白板上的内容没人归档,到了月底就说不清上个月到底做过什么。

1.2 现有工具的断层:Excel 灵活但不可控,ERP 重但适配差

不是所有人都在用 ERP,用 ERP 的五金厂也未必用好。Excel 的优势是灵活,任何规则都能硬排进去,但它的劣势同样致命:交期撞车它不报警,库存不足它不提示,两个计划员各排各的版本也没有冲突检测,最后装进车间主任脑子里的排程,永远和 Excel 里那个版本对不上。

ERP 是另一种极端。它适合业务规范、流程固定的大型厂,能管到采购、财务、成本、MRP 这些环节。但中小五金厂的流程往往没有那么标准,很多物料连编码都没统一。上 ERP 意味着车间每个动作要被录进系统,操作繁琐、界面复杂、权限死板,工人一抗拒,系统里的数据很快就失真了。

中间其实有一块空地:一个只负责“订单 → 计划 → 工单 → 报工 → 看板”的管理系统,比 Excel 多约束、多实时性,比 ERP 轻量、贴近车间真实习惯。这套 node.js + vue 的系统定位就在这个位置,不碰财务和总账,把车间计划这条主线的信息同步问题解决掉。

1.3 写代码前最重要的一件事:先把数据理清楚

很多人拿到这个需求第一反应是建表写接口,但实操中第一个拦住项目的往往是基础数据。物料编码有没有统一?BOM 是不是最新版?工艺路线里的工时是拍脑袋还是实测过?

我开始时吃过这个亏。厂里仓库管料叫“黄铜套”,工艺那边叫“HPb59-1 毛坯”,采购单上又是另一个名称,一套系统里三种叫法,等于没上系统。后来项目组做的第一件事,是把所有常用物料和产品编码重新编了一遍,编好规则再导入系统主数据。

如果你也要做类似系统,我的建议是:先花一到两周梳理物料编码、BOM、工序和设备的清单,再动技术框架。数据是排程的地基,地基歪了,后面所有报表都是数字游戏。

2. 为什么这个系统押注 Node.js + Vue:一次完整的技术选型复盘

2.1 前后端同构对中小项目团队的意义

技术选型那天,会议室里其实吵过一轮。有人提议 Spring Boot + Vue,理由是 Java 稳定、招人容易;也有人想用 Python + Vue,图开发快。最后定的还是 Node.js + Vue,这是基于团队规模和使用场景综合考量后的结果。

最直接的收益是前后端同构。项目组就三四个人,前端用 Vue,后端用 Node.js,两边都是 JavaScript/TypeScript,一个全栈工程师就能独立把一个模块从接口写到页面。Java 项目常见的前端工程师看不懂后端、后端工程师不愿意碰前端的隔阂,在这个项目里少了很多。

加上 Vue 的生态确实适合做管理后台。Element Plus 组件库把表格、表单、弹窗、标签页这些高频元素都封装好了,开发效率比从零写快非常多。这类车间管理系统本质上是大量 CRUD 和状态流转的组合,Vue 的响应式数据模型和组件复用能力正好踩在这个需求点上。

2.2 Node.js 的非阻塞模型恰好匹配车间高频小请求

车间上报进度的场景很特殊:数量大、单次请求小、频率高。一台设备每完成一批就要点一次“完工”或者用扫码枪扫一次工单号,设备一多,服务器面对的是每秒几十上百个轻量请求,每个请求业务逻辑不重,但并发量不小。

Node.js 基于事件循环和非阻塞 I/O,对这种 I/O 密集的小请求处理起来很顺手,单进程能扛住比传统同步模型高很多的并发连接。再加上 Socket.io 做 WebSocket 推送,看板数据可以直接从服务端推到车间大屏,不需要轮询,实时性也更有保障。

要注意的是,这不代表 Node.js 万能。如果系统里涉及大量复杂的报表聚合计算、多表关联的复杂事务,Node.js 写起来会比 Spring Boot 更费劲。所以在架构上我把重统计接口都放到独立服务里,配合 Redis 缓存,主业务接口保持轻量。

2.3 和 Spring Boot、Python 方案的真实对比

不少同行问为什么不直接用 Spring Boot。能用,而且很多工厂项目确实这么选。但如果你的团队本来就不是 Java 背景,为了一个小系统专门去搭一套 Java 技术栈,Maven、JVM 调优、类库版本冲突这些维护成本会很快吞掉开发效率。Spring Boot 的强项是大团队、长周期、重事务,我们的场景显得杀鸡用牛刀。

Python + Django 也评估过。开发原型确实快,管理后台能现成生成,但实时推送和并发处理没有 Node.js 顺手,而且一门后端语言和前端割裂,小团队维护起来两头都要管。

我把三套方案的差异整理成了表格,方便大家在类似项目里做判断。

技术栈优势在这个场景下的劣势
Spring Boot + Vue事务成熟、大团队规范、资料丰富部署重、开发节奏慢、团队要求高
Python + Vue原型快、后端起手容易实时推送一般、前后端异构
Node.js + Vue同构、轻量、并发好、部署简单复杂事务要小心、生态偏前端

这个项目最终选择 Node.js + Vue,不是因为它比其他方案高级,而是它和最真实的资源情况匹配:团队小、周期紧、并发特点明显、部署环境只有一台服务器。

2.4 环境搭建时容易被忽略的版本细节

Node.js 版本建议直接选 LTS。项目里用的是 18.20.4,生产环境不要追最新版,等一个版本在社区里沉淀半年以上再上,能少踩很多坑。Vue 这边用的是 Vue 3 + Vite + Element Plus,开发依赖用 pnpm 管理依赖,比 npm 更快也更省磁盘空间。

开发环境搭建的完整动作大概是这样的:

# 安装 nvm,用它管理 Node 版本 nvm install 18.20.4 nvm use 18.20.4 node -v # 创建 Vue 项目 npm create vue@latest npm install npm run dev

这里有个容易踩的小细节:Vue 3 的响应式包装和 Vue 2 差别很大,如果团队之前熟的是 Vue 2 选项式 API,接手 Vue 3 组合式 API 需要一点适应期。后面讲到前端组件时我会再展开。

3. 业务模块拆解:计划、工单、物料、看板是如何串成一条闭环的

3.1 主数据:物料编码、BOM 与工艺路线

系统里的主数据是后面所有模块的地基。我拆成三张核心表来聊:

产品表存产品编码、名称、图号、规格、版本号。五金件经常会改图纸,产品版本不管理好,工单下发后车间做的可能还是老版本,这个问题我在项目里见过不止一次。所以每个产品必须带版本号,工单生成时把产品版本快照到工单上,避免后续改版把历史工单也改了。

物料清单,也就是 BOM,记录每个产品需要哪些原材料、标准件,数量是多少。注意五金件会有边角料和损耗率,我在 BOM 里专门加了一个 plan_loss_rate 字段,冲压的首件调试废料就通过这个字段消化,而不是让工人把损耗记到成品头上。

工艺路线是每类产品经过的工序集合,包括工序号、工序名、使用设备类型、标准工时、每小时产出等。排程能排多细,完全取决于工艺路线维护到什么程度。至少要维护到“工序级”,不然甘特图只能排到订单,排不到设备。

3.2 计划生成逻辑:净需求计算和合并规则

计划员从销售订单勾选一批订单,点击“生成计划”,系统自动算出净需求。公式不复杂,但每项含义要跟业务确认清楚:

净需求 = 订单数量 - 可用库存 - 在制订单对应数量 - 已下达工单未完工数量

这里“在制订单对应数量”是指已经进入生产但还没完工入库的数量,如果漏算,计划员会把已经生产的量再排一遍,造成重复生产。

算出净需求后,系统按交期和客户优先级排序。排列组合这里有个优化点:尽量把批量小、同材质同规格的产品合并成一张工单。五金车间最大的浪费在换模,一张工单做 50 件和做 500 件,准备时间可能差不多,所以排程时优先合并相同产品编号、相近交期的需求,减少模具切换次数。

3.3 排程与工单下发:从计划到可执行的过程

计划生成后进入排程界面,我用的是前端甘特图组件。横轴是设备或者产线,纵轴是时间,工单就是一个方块,计划员可以拖动调整开工时间。系统排程时会自动检查设备占用冲突,时间重叠了会标红提示。

排程完成后,计划员选中工单点击“下发”。这一步我特意做成了有条件的操作:系统先跑一次物料齐套检查,缺料的工单不能下发。这个约束在纸质时代是计划员凭记忆做的,系统化之后变成了硬规则,实际运行中帮业务方挡住了很多次缺料开工导致停工等待的问题。

工单核心字段包括工单号、产品、数量、计划开始时间、计划结束时间、使用的工序路线、优先级、状态。工单号我用的是独立生成的业务编号,比如 WO + 年月日 + 流水号,而不是数据库自增 ID,这个习惯后面帮了大忙,打印条码、跨部门沟通时都能一眼识别。

3.4 物料需求计算与领料退料

工单下发后,系统根据 BOM 自动展开物料需求:工单数量乘以 BOM 里每个物料的单件用量,再乘上计划损耗率,得到物料需求量。和库存实时比对,生成缺料清单。

五金厂的领料比电子厂粗放,经常是车间一次性领一批材料放到工位,月底再退。所以这里我没有按“领料单严格倒冲”的精细模型,而是采用“大领大退”模式:车间可以批量开领料单,完工后退回余料,系统记录一个物料批次去向,做到批次可追溯即可。对五金车间来说,追溯粒度控制在“工单 + 物料批次”级别就够用了,太细反而增加工人操作负担,系统会被抵制。

3.5 车间报工与进度看板的实时刷新

报工是整个系统使用频率最高的功能,工人扫工单条码后进入报工页,输入本次完工数量和不良数量,点击提交。系统累加到工单的 completed_quantity 和 defective_quantity 上,同时计算剩余量。

每次报工数据变化后,服务端通过 WebSocket 把工单进度和设备状态推到车间看板。看板大屏只显示三块内容:今天的计划任务列表、每张工单的进度条、以及设备状态(运行中/空闲/故障)。不要放太多花哨图表,车间里真正有用的就是这几项。

4. 后端与数据库的严谨性设计:生产数据不能靠“感觉”

4.1 核心表结构设计与字段注意事项

数据库用的是 MySQL 8.0,字符集 utf8mb4。核心表我列一下:

表名用途关键字段
products产品主数据id, product_code(唯一索引), name, drawing_no, version, unit
bom_items物料清单id, product_id, material_id, qty, plan_loss_rate, is_key_material
process_routes工艺路线id, product_id, seq_no, process_name, device_type_id, standard_hour, output_per_hour
work_orders工单id, work_order_no(唯一索引), product_id, qty, completed_qty, defective_qty, status, version
work_order_logs报工日志id, work_order_id, user_id, report_qty, defective_qty, created_at
materials物料id, material_code(唯一索引), name, spec, safe_stock, stock_qty
inventory_transactions库存流水id, material_id, work_order_id, type(in/out), qty, created_at
users用户id, username, password_hash, role

两个字段设计的细节值得说。第一,所有业务编号如 work_order_no、product_code、material_code 都要建唯一索引,业务操作按编号查找,不要按自增主键找。第二,hard-delete 禁止,全部逻辑删除,生产中一张工单报错了要能追溯,物理删数据在工厂系统里是禁忌。

4.2 后端分层与参数校验

后端我用的 Express,路由层只做参数接收和校验,业务逻辑放到 service 层,数据库访问放到 dal 层。别把业务逻辑堆在路由回调里,后面改起来会非常痛苦。

参数校验用 Joi,每个接口定义 schema。比如报工接口的校验:

const reportSchema = Joi.object({ quantity: Joi.number().integer().min(1).required(), defectiveQty: Joi.number().integer().min(0).max(Joi.ref('quantity')).default(0), });

这里有个容易忽略的点:defectiveQty 不应该超过本次报工数量 quantity,如果不校验,一次手误就能把不良率刷成 200%。机器校验看起来只是一个小约束,但实际维护数据质量最有效的就是这类小约束。

4.3 乐观锁解决报工冲突

车间报工最典型的并发问题是两三个人同时给同一张工单报工。比如 A 工人扫了工单号输入 50 件,B 工人也同时报 30 件,如果代码只是先查后改再写回,最后数据库里 completed_qty 可能只是最后一次写入的数值,而不是 80 件。

解决方案是用乐观锁。给 work_orders 表加一个 version 字段,每次更新都带版本号:

UPDATE work_orders SET completed_qty = completed_qty + 50, version = version + 1 WHERE id = 123 AND version = 5;

如果影响行数是 0,说明版本过期,接口直接返回“页面数据已变更,请刷新后重试”。车间环境里这种提示比后台去悄悄合并数据更可靠,因为工人能立刻发现别人也在报工,避免漏报。

4.4 权限模型与登录会话

工厂系统权限不用做得很复杂,角色就四种:管理员、计划员、车间主任、工人。工人登录后只能看到自己工序的工单和报工入口,计划员能看全部计划和工单,管理员管基础数据和用户配置。

密码用 bcrypt 加盐哈希保存,绝对不能存明文。前端用 Vue Router 路由守卫做页面级权限判断,后端每个接口再用中间件做角色拦截,两层一起,缺一不可。登录态我用的是 JWT,但会在第 6 节专门说它的坑。

5. 前端页面怎么做到让车间工人愿意用

5.1 页面结构与组件划分

前端项目按菜单拆模块:计划管理、工单管理、物料管理、进度看板、基础数据、系统设置。

计划管理页面是计划员每天打开的第一个页面。左侧列出未排程订单,中间是甘特图排程区域,右侧显示设备占用情况。这个页面我拆成三个组件:PlanGantt.vue 负责甘特图渲染,OrderListPanel.vue 负责待排订单列表,DeviceTimeline.vue 负责设备时间轴。

工单管理页面是车间主任的主战场,列表用卡片而不是表格,因为卡片可以放大显示工单号、产品、数量、状态,一眼扫过去就能找到自己要跟的工单。卡片组件是 WorkOrderCard.vue,状态变化后用动画高亮提示,避免车间主任翻半天看不到新增工单。

5.2 车间平板端的大字体交互

系统要给车间配平板或者工控机,交互设计和办公室完全不一样。工人戴着手套、车间光线差、站着操作,按钮必须够大,文字不能太小。报工页面我把设计模式定为“信息最小化”:屏幕上只显示当前工单的产品、规格、计划数量、已完成数量,下面三个大按钮,“完工 N 件”“不良 N 件”“结束”。

数量输入我用的是数字键盘弹层,不用原生软键盘,因为原生的键盘在平板上会把页面顶上去,体验很差。而且尽量减少点击次数,能扫码就扫码,产品编码和工单号都不允许手动输入,防止输错一个字符找半天。

5.3 看板可视化:不是炫技,是直观

车间看板用的是 ECharts,但真正生效的不是图表样式,而是指标选择。我只保留三个维度:计划完成率、设备利用率、不良率趋势。计划完成率用仪表盘和进度条展示,设备利用率用堆叠柱状图按设备分组,不良率趋势用折线图看最近 14 天走向。

看板的数据通过 Socket.io 推送,服务端在每次报工事件后广播最新数据,前端订阅后更新对应组件。这个链路不复杂,但要注意做好断线重连,车间网络有时候不稳定,WebSocket 掉了要自动重连并拉取一次全量数据兜底。

5.4 移动端和外部系统衔接

车间里还有一类操作需要移动端,比如仓库盘点、车间主任现场巡检。我在架构里预留了一个 H5 的轻量入口,同一个 Vue 项目里通过路由区分,手机扫码打开后进入移动布局。

另外实际情况里,很多工厂已经在用企业微信沟通,可以和现有企业微信账号体系打通,做完单点登录后,工人不需要记住密码,直接在企业微信里打开应用就能看到自己名下待办工单。项目里也把关键事件,比如缺料提醒、工单下发通知,通过企业微信消息推给相关人员,实测下来比短信通知成本低而且触达率高。腾讯地图这类能力在配送场景更常用,这里用不上就不过度设计了。

6. 上线落地阶段最扎心的那些坑

6.1 服务器 Node.js 版本和系统库不匹配

项目上线时遇到最无语的一个问题,是 Linux 服务器上 Node.js 直接启动失败。本地开发用的 Node 18 好好的,但服务器是 CentOS 7.9,系统 glibc 版本偏旧,Node.js 18 的官方二进制需要较新的 GLIBC,结果一启动就报错。

解法是用 nvm 安装与系统匹配的版本,同时确认系统的运行库:

ldd --version nvm install 18.20.4 nvm use 18.20.4

后来我学到的教训是,生产环境的 Node.js 版本必须在项目文档里固定,并且用 .nvmrc 或 volta 锁版本。团队里任何一个人本地升大版本,都可能出现“本地正常、服务器跑不了”的诡异问题。

6.2 前后端分离的跨域和 Nginx 配置

开发环境用 Vite 的 proxy 解决跨域,简单省事:

// vite.config.js server: { proxy: { '/api': { target: 'http://localhost:3000', changeOrigin: true } } }

生产环境我直接用 Nginx 反向代理,让前端页面和后端接口看起来同源,不要去用 CORS 做一堆白名单配置,同源之后 cookie 和 JWT 的处理都干净很多。

location /api/ { proxy_pass http://127.0.0.1:3000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; }

这里有个细节,WebSocket 也要走同一个 Nginx,必须单独配置 Upgrade 和 Connection 头,否则看板推送在生产环境会失效。

6.3 JWT 过期与车间工人的“长期在线”需求

JWT 最大的坑是过期问题。车间工人早上登录一次,经常挂着到下班,如果 token 只有两小时有效期,下午就突然没法报工了。又不能让他反复输入密码,工人在机台旁边停下来找管理员重置密码,是灾难。

我的做法是双 token 方案:短期 access token 两小时过期,长期 refresh token 七天有效。axios 响应拦截器里判断 401,自动用 refresh token 换新 token,对工人完全无感。

service.interceptors.response.use( res => res, async (error) => { const original = error.config; if (error.response?.status === 401 && !original._retry) { original._retry = true; await refreshToken(); return service(original); } return Promise.reject(error); } );

这个方案要考虑多标签页同时抢刷新令牌的问题,我当时做了一个简单的并发锁,确保多个请求同时 401 时只发一次刷新请求,避免 token 被反复刷新导致后续全部失效。

6.4 扫码枪输入法干扰与批量报工

扫码枪本质上就是键盘,扫出来的字符串以键盘事件形式输入,最后再补一个回车。问题在于部分国产输入法在中文状态下会拦截扫码内容,本来应该扫出“WO20240515001”,结果变成一段乱码进到输入框。

解决办法是使用全局监听 keypress 事件拼接缓冲区,不走输入框的普通 keydown 路径:

let buffer = ''; let lastTime = Date.now(); window.addEventListener('keypress', (e) => { buffer += e.key; if (Date.now() - lastTime > 100) buffer = ''; lastTime = Date.now(); if (e.key === 'Enter') { handleScan(buffer.trim()); buffer = ''; e.preventDefault(); } });

注意加一个时间判断,防止工人手工敲键盘也被误判成扫码。扫码设备录入的连续按键间隔通常小于 30ms,手工输入很难做到那么快,时间阈值可以调。

最后还有一个容易被忽略的问题:同一张工单,多人同时扫码报工。所以我在报工接口上做了防重复提交,同一个工单同一个用户 5 秒内重复提交会被忽略,前端也会弹个小提示,告诉工人“刚才已经提交过了”。

如果让我重新做一遍这个系统,我会先做“计划 - 工单 - 报工 - 看板”这条主线,跑顺了再往两边加物料、设备和成本。给车间主任留一个 Excel 导出功能特别重要,它不是妥协,而是它给不愿意马上切换到系统的人一个缓冲通道;等数据准确到大家开始依赖看板了,Excel 导出自然就没那么多人用了。业务编号规则也要提前设计好,别用自增 ID 做单号,这个决策越早做,后面打印条码、跨部门沟通、排查问题的时候就越省心。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 17:51:20

大模型三层实战架构:输入-模型-输出责任分层法

1. 这不是讲架构图的课,是教你怎么“喂”大模型的实战手册你有没有试过对着一个大模型反复提问,结果它要么答非所问,要么一本正经地胡说八道?不是模型不行,是你没摸清它的“消化系统”。标题里说的“三层架构”&#x…

作者头像 李华
网站建设 2026/9/29 17:51:14

小波神经网络预测代码:Python毕设工程包实战指南

简介:这份毕业设计资源聚焦小波神经网络(WNN)预测方向,面向具备一定信号处理与机器学习基础的高校学生及研究人员,用于学习小波变换与神经网络融合建模的完整实现思路。压缩包共6个文件,以5个m脚本和1个mat…

作者头像 李华
网站建设 2026/9/29 17:51:11

升级后Fiori目录废弃不用慌:Business Catalog接管与治理实战

业务菜单在升级后一夜之间消失,这可能是我见过最让 SAP 项目组夜不能寐的场景。系统升级本身往往顺风顺水,真正把人逼疯的,是升级完成后用户打开 Fiori 启动板,发现以前常用的磁贴少了一半,或者角色里挂着的 Business …

作者头像 李华
网站建设 2026/9/29 17:50:39

WorkBuddy AI工作台实战:从模型配置到Skill开发的完整指南

1. 为什么我要认真聊聊 WorkBuddy 这个 AI 工作台第一次看到 WorkBuddy 这个名字,我下意识以为又是一个套壳聊天窗口。真正用起来才发现,它想做的事情比“聊天”大得多——它把 AI Agent 的编排、Skill 的挂载、模型配置、任务规则这些原本散落在各个工具…

作者头像 李华
网站建设 2026/9/29 17:49:20

多Agent协作系统状态管理:共享记忆、分布式状态与一致性实践

先说个我在实际项目里反复撞墙后的结论:多 Agent 协作系统的状态管理,本质是给一群各怀绝技但记性极差的临时工,搭一套不会吵架的共享工作台。这两年多 Agent 框架层出不穷,从 AutoGen 到 CrewAI 再到 LangGraph,底层都…

作者头像 李华