大数跨境

SpringBoot+Vue3 实战 MES :生产批次追溯从原料来源到成品去向,设计双向可查的关系网络

SpringBoot+Vue3 实战 MES :生产批次追溯从原料来源到成品去向,设计双向可查的关系网络 企业软件源码
2026-11-11
4
导读:从原料混批、生产转化、成品拆分与质量核查出发,结合 MES 已有批次生成、正逆向查询和产出质检实现,解释批次身份、工单关联精度、事件证据、数量单位、递归边界与可核验的追溯设计。

SpringBoot+Vue3 实战 MES :生产批次追溯从原料来源到成品去向,设计双向可查的关系网络

质量人员发现一批原料存在异常,第一反应不是查它的名称,而是确认:它投入了哪些生产任务,形成了哪些成品,哪些还在库,哪些已经发出。换一个方向,客户反馈某批产品异常,又要查回原料、工单和检验记录。一次混批、一次拆分、一次返工,都会让问题超出“按批次号查一张表”的范围。

▲ 关系设计示意:两个原料批次可以进入同一生产过程,产出又可能分为不同批次与去向。正向和逆向查询沿同一组事实运行,不是两套独立维护的数据。

一、追溯的核心不是编号,而是可解释的关联

批次号用于标识一组在业务上共同管理的物料,但它本身不记录转化关系。知道原料批次 A 和成品批次 C 都存在,不等于知道 A 是否参与了 C 的生产,更不等于知道参与了多少。

追溯需要把身份、事件和证据连接起来:身份说明是哪一批;事件说明发生了投料、产出、拆分、合并或转移;证据说明这条关系来自哪张业务单、哪一行和哪个时点。缺少其中一层,查询结果就容易变成“看起来有关联”的列表。

批次管理与序列号管理也不同。批次描述一组对象的共同属性,序列号通常标识单件。一个成品批次可以包含多件序列号产品,关系需要显式记录;不能把一串能扫码的号码都统称为同一种追溯身份。

层次
需要回答的问题
单靠批次号做不到的事
批次身份
这是谁、属于什么物料
不能自动推导上下游
转化关系
哪些输入形成哪些输出
不能由名称相似判断因果
数量与单位
关联多少、采用什么计量
不能按条数代替数量
单据证据
关系从哪里来
不能只返回一个无来源结论
查询边界
查到了哪里、还有什么未知
不能把空结果一律当没有关联

本文把追溯看作业务关系建模问题,而不是某个数据库产品的选型题。先把事实记录清楚,关系型数据库也可以支持有价值的追溯;关系缺失时,换成图数据库也不会自动获得真实的投料证据。

二、先确认现有 MES 能力,再讨论精细化设计

当前工程的 Maven 聚合包含 MES 模块,实际应用也提供批次追溯入口。源码中不仅有批次生成,还存在 getForwardBatchList 与 getBackwardBatchList 两个方向的查询,以及递归防环和深度上限。

因此,不能把现有系统说成“只有批次编号,没有追溯”。更准确的边界是:已有批次与单据关联查询;更精细的投料分摊、完整路径证据和跨域去向展示,需要按业务进一步验证与扩展。

1. 工单描述生产上下文,不应直接等同于精确谱系

生产工单关联物料、任务、计划和 BOM 等信息,为后续报工、消耗和产出提供上下文。BOM 描述计划需要什么,实际消耗记录才描述本次用了什么,两者不能互相代替。

▲ 真实工单详情。工单是追溯的重要连接点,但计划物料不等于实际投料批次,精确追溯仍需消耗记录。

例如,同一工单先后投入两批原料,并分两次报工。按工单关联可以圈定相关范围,但未必能确认第一批原料只进入第一批产出。若现场没有记录到报工、工序或投料事件层级,系统就应说明关系精度,而不是自行分摊出一组精确数量。

2. 产出与质检,让“生产了多少”和“可以放行多少”分开

现有产出生成逻辑会关联报工、工单、工作站与工序,再根据物料批次配置获取或生成批次。需要检验时先生成待检产出行,后续按检验结果处理;不需检验的分支则按合格与不合格数量创建相应行和明细。

▲ 真实过程检验详情。质量结果应与具体业务对象关联,而不是成为追溯页面上一个无法回查的“合格”标签。

这里也要避免一个误解:质量拆行不必然生成新的批次身份。批次、质量状态、库存位置和产出明细是不同维度。到底拆批还是只拆库存明细,取决于物料配置与业务规则,不能看到两行记录就认定已经形成两条独立批次谱系。

3. 双向追溯入口已经存在,结果仍需解释

批次追溯详情显示批次信息,并提供“向前追溯”“向后追溯”两个标签。当前前端分别调用对应查询接口,服务端沿单据关系递归获取关联批次。

▲ 真实批次追溯界面:从原料批次 RAW-BATCH-001 查到两条关联产出批次。它证明现有单据关系可以查询,不代表已采集完整发货去向或精确投料分摊。

在本文中,正向指从原料查询后续产出与去向,逆向指从成品回查原料来源。界面词语与业务团队的习惯应保持一致;如果“向前”在某个组织被理解为向历史查,最好直接显示“查去向”“查来源”,减少歧义。

三、源码里的关联路径,能证明到什么精度

当前批次 Mapper 的正向查询,从原料消耗明细进入消耗单,再关联报工与生产产出记录,最后得到产出行中的批次。逆向查询则从产出明细进入产出单,再经工单关联消耗单和消耗明细。

这是一条有业务依据的查询链,不是按批次名称做模糊匹配。但其中的重要连接使用了工单身份,因此结果应首先解释为工单相关的上下游范围,而不是天然精确到某次投料对某件成品的数量归属。

举个设计示例:工单 W 使用原料 A 和 B,分两次产出 C 和 D。如果只有工单级连接,系统可能得到 A、B 都与 C、D 相关。这个范围对初步质量排查很有价值,却不能据此声称 C 中恰好包含 A 的某个比例。

要提高精度,需要现场采集更细的事件,例如投料批次与报工任务、设备批次、工序段或容器的对应关系。数据没有采到的部分,应标成未知或粗粒度关联。不能为了让追溯图看起来完整,就用平均分摊制造不存在的事实。

批次生成规则也会影响后续追溯粒度

MesWmBatchServiceImpl 会读取物料批次配置,根据启用的属性检查必填项并构造匹配条件。符合已有批次条件时复用,否则生成新批次码。生产日期、供应商、客户、工单、工作站等是否参与区分,取决于配置。

现有产出链路还会把生产日期处理到当天起点,但这并不表示“同一天必定只有一个批次”。其他启用属性仍然参与匹配。批次规则应该表达真实的管理粒度,而不是为了减少编号数量随意合并。

下面摘出已有产出逻辑中构造批次请求的部分,展示批次与生产上下文如何连接,省略后续质量分支。

MesProWorkOrderDO workOrder = workOrderService.getWorkOrder(        feedback.getWorkOrderId());MesWmBatchGenerateReqVO batchRequest = new MesWmBatchGenerateReqVO()        .setItemId(feedback.getItemId())        .setProduceDate(LocalDate.now().atStartOfDay())        .setExpireDate(feedback.getExpireDate())        .setWorkOrderId(feedback.getWorkOrderId())        .setClientId(workOrder != null ? workOrder.getClientId() : null)        .setSalesOrderCode(workOrder != null ? workOrder.getOrderSourceCode() : null)        .setWorkstationId(feedback.getWorkstationId())        .setLotNumber(feedback.getLotNumber());MesWmBatchDO batch = batchService.getOrGenerateBatchCode(batchRequest);Long batchId = batch != null ? batch.getId() : null;String batchCode = batch != null ? batch.getCode() : null;// 后续产出行和产出明细引用 batchId、batchCode。// 是否启用批次以及哪些属性参与匹配,由物料批次配置决定。

如果物料没有启用批次管理,服务可能返回空批次结果。下游不能为了“让图不缺节点”凭空生成一个批次;应如实说明该段链路缺少批次级身份,并决定是否需要从业务采集环节补齐。

四、用事件连接输入与输出,比只维护一张上下游表更稳妥

最简单的关系表只有来源批次和目标批次。它能支持基本查询,但一旦出现混批、拆批、返工、撤销和单位转换,就很难解释为什么存在这条边。

更稳妥的模型,是在输入与输出之间保留转化事件。事件记录业务类型、工单或工序、发生时间和来源单据;参与项记录某个批次作为输入还是输出、数量和单位;查询可以在此基础上形成批次关联。

▲ 精细谱系建议模型。现有消耗、产出和质检单据提供事实来源;统一事件与精度标识是增强设计,不是已新增的数据库表。

以两种原料共同形成一批成品为例,事件可以记录 A 消耗多少、B 消耗多少、C 产出多少。它保留了真实输入输出,却不必虚构“A 对 C 的一对一分摊金额或重量”。若行业需要进一步分摊,分摊方法和依据应另行定义。

拆批同样需要说明语义。把同一批货放到两个库位,可能只需要两条库存记录,不需要新批次;重新包装或质量分级后形成新的管理身份,则可能需要新批次并保留来源关系。物理移动、库存拆行和批次身份变化不能混为一谈。

返工会让关系网络出现更复杂的路径。原成品重新投入加工时,可以记录新的转化事件,而不是覆盖原产出记录。查询需要防止环路,但也不能把合法返工关系简单删除。事件时间和业务身份能帮助区分重复数据与真实重复加工。

五、正向与逆向查询,应该共享同一份事实

两种方向的区别在于沿哪一端扩展邻居,而不是分别维护两套容易不同步的来源和去向清单。每条事实关系只应有一个可信来源,再由查询决定方向。

现有实现用 visited 集合避免重复递归,并设置最大追溯深度 20。下面是正向查询的核心代码,保持实际控制逻辑。

public List<MesWmBatchDO> getForwardBatchList(String code) {    return getForwardBatchList(code, new HashSet<>(), 0);}private List<MesWmBatchDO> getForwardBatchList(        String code, Set<String> visited, int depth) {    if (code == null || !visited.add(code) || depth >= MAX_TRACE_DEPTH) {        return new ArrayList<>();    }    List<MesWmBatchDO> list = batchMapper.selectListByForward(code);    if (CollUtil.isEmpty(list)) {        return new ArrayList<>();    }    List<MesWmBatchDO> results = new ArrayList<>(list);    for (MesWmBatchDO batch : list) {        results.addAll(getForwardBatchList(batch.getCode(), visited, depth + 1));    }    return results;}

防止重复递归与保证最终结果去重,是两个不同目标。上面的 visited 约束继续扩展,但结果由各层列表合并而成;多条路径可能触达同一批次,展示层仍需要考虑节点唯一性和路径保留。不能只因为出现了集合,就宣称所有输出已经去重。

另外,达到深度上限时返回空扩展,可以保护系统,但如果界面没有提示,用户可能误以为已经查到全部。用于正式质量排查时,建议返回查询是否截断、使用的范围和限制,以及哪些关系因权限或缺失数据未能展开。

▲ 增强查询时序:结果不仅展示批次,还应展示路径依据和查询边界;深度限制、节点上限与权限范围都属于结果解释的一部分。

大范围查询要保留边,而不是只返回扁平批次列表

如果结果只是十个批次号,用户不知道每个批次通过哪张单据与起点相关。可以把节点与关系分开返回:节点按身份去重,关系保留来源、目标、事件和精度。已经展开过的节点不必再次查询,但第二条合法路径不能因此丢失。

下面是增强查询的设计伪代码,展示有限范围的图遍历。实际实现还需加入租户与数据权限、批量查询、超时和结果大小限制。

public TraceGraph trace(BatchId start, Direction direction, Scope scope) {    Deque<Visit> queue = new ArrayDeque<>();    Set<BatchId> expanded = new HashSet<>();    TraceGraph graph = new TraceGraph();    queue.add(new Visit(start, 0));    while (!queue.isEmpty()) {        Visit visit = queue.removeFirst();        if (!expanded.add(visit.id())) continue;        if (visit.depth() >= limits.maxDepth()) {            graph.markTruncated(visit.id());            continue;        }        for (TraceEdge edge : relations.authorizedNeighbors(visit.id(), direction, scope)) {            graph.addEdgeIfAbsent(edge);            BatchId next = edge.neighbor(direction);            if (graph.reachesNodeLimit()) return graph.asTruncated();            queue.addLast(new Visit(next, visit.depth() + 1));        }    }    return graph;}

这个示例故意把关系的授权检查放在查询接口里。企业内不同公司、工厂和客户资料可能有不同可见范围,追溯不能成为跨组织枚举数据的后门。无权展开时应遵守安全策略,不应为了让图连通而返回受限批次名称。

六、数量、单位和质量状态,比关系线更容易出错

一条关系可能代表 100 千克原料、20 件半成品或 8 箱成品。不同物料和单位不能直接相加。需要建立统一计量或明确转换依据,保留转换时的规则和精度;无法转换时就分别展示,不要生成一个没有物理意义的总量。

即使单位相同,也不能简单要求所有制造过程输入数量等于输出数量。加工损耗、辅料、联产品和返工都会影响数量关系。守恒校验应围绕具体工艺和可比较的量定义,而不是对所有事件套一条通用等式。

质量状态还可能在生产之后发生变化。一个批次先处于待检,后来部分放行、部分隔离;历史发货与当前库存需要分别关联当时事实。仅查看批次当前状态,可能无法解释此前发生的流转。

因此,质量记录应保留检验对象、时间、结果和处理依据。将质检记录挂在关系网络上,是为了能够回到具体证据,不是让一枚绿色标签覆盖整个生命周期。

查询影响范围也不是责任认定。某原料批次与某成品批次有关联,只能说明它值得进一步核查;是否存在质量问题、需要采取何种处置,应结合检验、工艺和企业管理要求。系统不能把关系存在直接翻译成“全部不合格”。

七、从成品继续查到库存与发货,需要明确跨域边界

生产关系说明来源,库存和发货记录说明去向。要把链路延伸到仓库、客户或订单,必须核对跨模块使用的是同一个批次身份,或者存在可追溯的映射。

如果 MES 与 WMS 各自保存批次码,同一个字符串未必就是同一对象;如果 ERP 的发货记录只保留物料而没有批次,链路会在这里中断。界面应显示“该环节缺少批次明细”,而不是把所有同物料发货都当成该批次的去向。

本次已经核对的批次查询主要沿消耗与产出关系展开。主图中的客户和仓库去向,是完整目标链路的一部分,不能据此宣称当前查询页面已经完成所有跨模块发货追踪。正式扩展时,需要继续核对出库行、库存明细与批次字段的绑定。

对外部供应商批次,还要区分企业内部批次 ID 与供应商原始批号。供应商批号可能在不同供应商之间重复,内部身份不能只用一段外部字符串作为全局主键。

八、数据修正与撤销,要保持追溯事实可解释

现场录入可能选错批次,也可能在报工后发现数量有误。直接修改历史关系会让此前查询结果失去依据。更稳妥的方式是按业务规则作废错误记录、生成纠正或反向记录,并保留原单据与修正原因。

不是所有场景都需要完整事件溯源架构,但至少应知道一条关系是正常、已撤销还是由后续记录修正。查询默认应使用有效事实,同时允许有权限的人员查看修正过程。

导入历史数据时,尤其不能为了让链路完整而批量猜测关系。可以标记为“人工补录”“工单级推定”或“原始明细确认”,让不同证据强度在结果中可区分。真正的高质量追溯,不是没有未知,而是未知有明确边界。

九、怎样验收双向追溯是否真的可靠

应准备可以人工画清楚的小型样本网络,而不是只找一个只有单一路径的批次演示。至少覆盖两个输入、两个输出、共享中间批次、返工和缺失一段关系的情况。

样本
应观察的行为
常见错误
两原料合批产出
保留两个输入及事件依据
只记录最后一次投料
同批次分库位
区分库存拆分与批次身份
自动制造无意义的新批次
多路径到达同一成品
节点不重复,路径不丢失
用节点去重误删第二条关系
返工形成复杂网络
可终止、保留真实事件
无限递归或直接删除返工边
追溯达到上限
明确提示结果截断
把未展开解释成没有后续
发货未记录批次
显示链路缺口
按物料猜测全部客户去向
工单级粗关联
标明精度与证据边界
声称已经精确分摊数量

还应测试正逆向的一致性。在同一授权范围、同一数据截点和相同深度条件下,如果查询确认 A 通过某事件关联 C,逆向查询应能够解释这条同一事件关系。条件不同引起的差异可以存在,但必须可解释。

性能测试则关注层数、分支数、返回节点与单次查询成本。深度只有几层但每层分支很多,仍然可能形成大量结果。可以批量查询相邻关系、按证据分页、限制展示规模,但不能静默截断后继续宣称结果完整。

十、从已有追溯能力,走向更精细的制造证据

第一步,核对物料的批次配置与业务采集,确保批次身份足够稳定;第二步,检查实际消耗和产出是否保留了所需关联;第三步,让查询返回关系依据和范围说明;第四步,再扩展到更细的投料事件及库存、发货去向。

RuoYi Office 的批次服务、生产产出和过程检验提供了可调研的现有链路。可以从生产工单、过程检验、批次追溯三个页面开始,再沿 MesWmBatchServiceImpl、MesWmBatchMapper.xml 和 MesWmProductProduceServiceImpl 对照实现。

本文没有向业务库补造追溯记录,也没有把目标网络伪装成已有完整产品。对制造系统来说,承认当前采集精度,往往比画出一张没有依据的全链路图更有工程价值。

常见问题

有批次号和二维码,是否就有追溯能力?

只有身份基础。还需要采集输入、输出、移动和检验等关系,并能回到业务证据。扫码只是访问入口,不会自动产生缺失的业务链。

按工单查询上下游,算不算追溯?

算,但应说明是工单相关范围。若同一工单存在多次投料和多次产出,没有更细关联时,不能把结果解释为精确消耗分配。

是否必须使用图数据库?

不必须。关系型数据库加明确的事件和参与项可以支撑不少场景。先确认采集粒度、查询规模和证据要求,再决定存储技术。

查不到下游,能否认定没有影响?

不能直接认定。还要区分确实没有业务、权限限制、数据缺失、状态过滤和查询截断。系统应把这些情况区分展示。

结语

生产追溯真正要保存的,不只是一串批次号,而是物料如何参与业务、通过什么事件发生转化、最终流向哪里,以及每一条关联的证据精度。来源与去向使用同一组事实,正向与逆向查询才可能相互解释。

从现有批次与单据查询出发,逐步补齐精细关系、数量依据和查询边界,SpringBoot3+Vue3 的制造系统才能让追溯从“查到一些相关记录”,走向“知道这些记录为什么相关”。


【声明】内容源于网络
0
0
企业软件源码
RuoyiOffice 是一套基于 Spring Boot + Vue3 +Uniapp 的企业一体化管理平台,集 OA、CRM、ERP、工作流、HR、资产、合同、项目、AI应用等业务于一体,帮助企业用一个系统协同管理多类核心业务。
内容 189
粉丝 0
企业软件源码 RuoyiOffice 是一套基于 Spring Boot + Vue3 +Uniapp 的企业一体化管理平台,集 OA、CRM、ERP、工作流、HR、资产、合同、项目、AI应用等业务于一体,帮助企业用一个系统协同管理多类核心业务。
总阅读5.8k
粉丝0
内容189