BOX · 生产物料拉动系统

把现场扫码、仓库补料、配送标签和收货确认接在同一条任务流程里,让每一次叫料都有状态、有记录,也能找到对应的物料和工位。

Versigent(维智捷)· 芜湖 / 工作项目 · 2026.04 - 至今 / Java 17 · Spring Boot · JPA · MySQL

背景与目标

生产现场缺料时,最急的事情是把正确的物料送到正确的工位。过去,这个动作常常要经过口头叫料、仓库确认、配料和配送几次转述。物料号、仓库料号、工位地址和数量没有放在同一处,接收信息的人需要再次核对。等物料送出以后,现场还需要知道任务到哪一步,仓库也需要确认这一单是否已经结束。BOX 就是从这条日常流程开始做的。

我的目标是把一次叫料变成有编号、有状态、有操作记录的任务。现场扫码后,系统能够识别物料和工位,仓库能够集中接收补料需求,配送标签能够带着同一组信息继续流转,现场收货后能够确认闭环。这样,后续排查一次送错、漏配或重复叫料时,不必从头问一圈人,而是先找到对应任务和它的操作过程。

这是一项工作项目。我参与现场需求梳理和系统建设,负责前后端、数据库及微信小程序的开发维护,也参与服务器部署、问题排查和版本迭代。项目仓库还包含 Android 扫码端、打印代理和部署资料。不同客户端服务于同一条物料流程,但仓库存在多个版本,代码中的能力与现场实际启用的功能需要分别说明。

现场问题与业务约束

不同编码需要落到同一笔业务

现场叫得出口的物料号、仓库使用的料号、打印在标签上的编码,不一定是同一种标识。扫码枪读到的也不总是一串干净的数字,可能带回车、Tab、BOM,也可能读出 JSON 或键值对内容。因此,系统不能把扫描文本直接当成唯一业务编号;它需要先整理输入,再查找候选标签,最后确认是否存在明确、唯一的匹配。

另一类问题来自连续操作。操作员可能再次扫同一个码,设备可能重试网络请求,仓库任务还没有出发时也可能收到同一份需求。如果每次请求都直接新增任务,看板上的数量就会失真,仓库也容易重复配料。扫码入口必须区分一次请求的重复提交和同一标签的重复业务需求,并在生成任务之前处理这些情况。

双盒物料又多了一层状态约束:正在使用的盒子扫空后,备用盒需要能够接上。不是任意两个盒子都可以切换,配对关系、当前使用状态和备用盒满料状态都需要校验。若数据不完整或备用盒还未准备好,继续执行会把异常带到现场。因此,这一段逻辑需要把正常流转与异常停止写得同样清楚。

技术架构与职责分工

Spring Boot 负责业务,Vue 负责操作界面

后端使用 Java 17 和 Spring Boot,按 Controller、Service、Entity、Repository 组织代码。Controller 接收扫码、任务、标签和导入请求,Service 处理状态转换与业务规则,JPA Repository 负责数据访问。MySQL 用于业务数据存储,项目依赖也保留了 H2。这样的分层让界面调整、业务条件变化和数据库操作不必挤在同一个接口方法里。

前端使用 Vue3、TypeScript、Vite 和 Element Plus,结合 Axios 调用业务接口,ECharts 支持数据展示。任务、物料、映射和标签等页面围绕现场及仓库的操作展开,而不是只展示一组统计数字。前后端之间通过明确的数据结构传递任务编号、状态和关联信息,使列表、操作入口和后端校验能够对应到同一笔业务。

实时变化通过 Spring 的 WebSocket 消息通道推送。任务生成、打印任务提交等动作能够发布到对应主题,减少看板完全依赖手动刷新。推送服务同时记录 Outbox 信息,失败时留下原因。这里的价值是让业务操作和界面更新有连接,也保留排查线索;它并不意味着网络故障时的消息已经获得端到端必达保证。

部署方面,master 分支保留了 Ubuntu、MySQL、Spring Boot 和 Nginx 的运维说明。Nginx 提供前端静态文件,并将 API 和 WebSocket 请求反向代理给本机后端,浏览器通过同一入口访问。服务启动、日志查看、版本更新和地址变化都需要纳入交付考虑。对现场工具来说,能开机恢复、能找到入口、出问题能定位,与页面功能同样重要。

关键功能与实现

扫码解析与业务匹配

LabelResolverService 先清理扫描内容边界和控制字符,限制异常长度,再从普通内容、JSON 字段、键值对和启用的规则中提取查询候选。候选命中结果按标签记录去重,最后要求唯一匹配。找不到标签或找到多个标签时返回明确的业务错误,而不是随便取第一条。规则表提供了前缀、精确值、正则等匹配入口,便于后续增加码制时减少核心流程改动。

ScanService 在标签解析之后继续处理叫料。标签不存在时还会进入物料号叫料路径;标签存在时检查关键字段与状态,记录扫描时间、设备和操作员,并关联周转盒及补货任务。这个顺序把输入解析、基础数据检查和任务生成分开,避免一个看似有效的码在缺少数量、物料或送达工位的情况下继续流转。

重复请求与双盒切换

请求侧使用幂等键和请求摘要记录执行状态,区分正在处理、已完成和失败的请求;扫码业务还通过业务锁围绕同一个扫描对象执行。业务侧则查询尚未出发的补货任务,遇到重复扫码时返回已有任务编号并写入审计记录。这两层处理分别应对网络重试与现场重复操作,目的都是减少重复单据,而不是用前端按钮禁用来代替后端约束。

双盒流程要求配对数量正确,当前盒处于允许的状态,备用盒已经满料。正常情况下,当前盒转入等待补货,备用盒转为使用中,再建立对应补货任务;异常情况下记录健康状态、锁定原因和告警,并停止切换。这样的状态管理让“不能继续”的原因也成为业务数据,便于仓库或现场人员找到需要修正的位置。

任务流转、收货与异常

TaskService 把接单、开始配料、配料完成、配送、到达和完成等动作放进状态转换逻辑。每个动作先校验任务当前状态,再更新状态及相关信息。例如,不能把刚创建的任务直接当成已经送达,也不能忽略配料前的库存关联。ScanService 还提供现场收货确认,把扫描内容解析到配送任务,再交由任务服务处理闭环;填写空盒信息时,流程能够衔接空盒回收。

异常上报与正常收货使用不同入口,保留异常类型、原因、设备、人员和关联物料工位信息。系统会把异常状态反映到任务和大屏,而不是只在当前页面弹出一句错误。审计记录贯穿扫描、状态操作和打印提交,使后续分析能够还原“谁在什么设备上,对哪一项业务做了什么”,而不是只有最终结果。

标签、打印与批量导入

标签承载物料、数量、仓库、工位地址、人员、二维码、图片和使用状态等信息。打印服务建立独立打印任务,将业务任务与打印任务编号关联,并提供按状态查看的入口。对于已生成的打印任务,代码会检查既有记录,减少重复提交。二维码生成与表格处理分别使用 ZXing、Apache POI 和 Commons CSV 等依赖,服务于现场识别与基础数据整理。

ImportService 接受 Excel 和 CSV,对导入类型、文件扩展名与字段进行处理,整理物料、映射和标签等基础数据。CSV 会先转换成统一的工作表结构,处理 BOM 和空白,再沿同一套行解析逻辑执行。映射解析兼容带序号与不带序号的列布局,同时将料号、仓库代码、盒子规格、数量和工位组织到关联数据中。导入不是简单上传附件,它直接影响后续扫码是否能够正确匹配。

导入过程为每次上传建立批次,逐行处理时分别统计成功与失败,将错误行号、原始行内容和错误说明保存到对应批次。最后区分全部成功、部分成功和失败,使维护人员能够回到具体行修正数据,而不是看到一句“导入失败”就重新检查整个表格。这个机制也说明上传文件与数据真正进入业务之间还有校验过程,不能只凭文件被接收就确认导入完成。

打印端同样区分提交与完成。PrintJobService 接收状态回调,保存外部任务编号、打印时间或失败原因,并记录接口审计与推送更新;业务任务取消时,还会检查打印任务当前状态并处理取消。它把设备侧结果重新带回业务系统,帮助排查“任务已生成,但标签有没有真正打印”的问题,具体打印设备与代理仍需按部署环境验收。

分支中的权限与外部扫码扩展

fix/mapping-import-timeout 分支进一步限制映射导入的角色和数据范围。ImportController 对料号映射上传要求管理员权限,普通管理员只能操作对应范围;查看导入错误时也检查批次类型与操作人。这部分代码说明导入功能开始同时考虑“能否上传”和“能看哪一批结果”,不能把页面按钮是否可见当作完整权限控制。

同一分支还有外部扫码中继与 Linux Worker。Worker 从中继领取命令,把允许的扫码动作转换成内部 API 请求,将 requestId 透传为幂等键,再回报完成或失败;网络类失败与业务类失败有不同的重试处理。它提供了一条跨网络连接扫码操作的实现路线,但属于分支扩展,是否在现场使用仍要以部署记录为准,不能与 main 的现有业务能力直接合并成已上线结论。

完成目的与现场结果

项目把叫料信息、仓库任务和配送标签统一到同一条业务链路上。现场知道需求已经被记录,仓库知道需要配什么、送到哪里,配送和收货有状态可查,异常能够关联到具体任务。对我来说,最重要的交付不是多一个页面,而是把原本依靠转述的动作变成可查询、可校验、可维护的操作过程。

按此前个人提供的现场成果说明,叫料响应由约 10-15 分钟缩短到 3-5 分钟,仓库配料效率提升约 30%,人工沟通减少约 50%,配送异常减少约 40%,任务可追溯率达到 100%。这些数字属于现场成果记录,保留原来的来源;源码能说明系统采用了哪些机制,不能独立证明效率统计或追溯率的测量结果。

指标改善情况
叫料响应时间约 10–15 分钟 → 3–5 分钟
仓库配料效率提升约 30%
人工沟通次数减少约 50%
配送异常减少约 40%
任务可追溯率达到 100%

维护经验与后续方向

这项经历让我把业务建模、接口开发和现场问题放在一起考虑。一个标签字段缺失、一种二维码码制不统一、一次重复扫描,都可能影响整条流程。维护时需要先确认业务对象和当前状态,再查看请求、任务、打印与审计记录,最后判断是基础数据、操作条件、接口还是部署环境的问题。清楚的关联和错误信息能够减少排查时的猜测。

后续库存联动、AGV 配送和计划协同已有对应扩展空间,但进一步建设需要同时确认真实库存口径、设备接口、异常接管和现场责任边界。每个分支应分别核对版本与部署范围;外部扫码中继也需要结合实际网络、设备和重试场景验收。继续扩展的目的仍然是让物料流程更准确地运行,而不是把仓库中出现过的模块都写成已经投产的功能。

查看项目源码 ↗

编辑评论