ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Java Web开源MES系统设计:业务模型、技术架构与实施经验

Java Web开源MES系统设计:业务模型、技术架构与实施经验 简介这是一套面向制造业数字化转型开发者与工业信息化工程师的开源制造执行系统MES完整源码基于Java后端与Vue前端技术栈构建旨在解决生产过程实时监控、工单调度、物料追踪与质量闭环等核心管理难题。资源包共588个文件总大小3.62MB涵盖264个Java业务逻辑代码、81个Vue组件、62个JavaScript交互脚本、87个SVG矢量图标及31个XML配置文件辅以SCSS样式、VM模板与批处理脚本体现前后端分离、模块化如ruoyi-mes核心模块、可扩展架构设计。已有505人学习下载适合具备Java Web与Vue基础的中高级开发者快速掌握MES系统落地实践。读者可直接获取含数据库SQL脚本、多环境启动脚本run.bat/build.bat等、若依框架使用手册及完整LICENSE协议的开箱即用工程显著降低工业软件二次开发门槛。 我做了三年离散制造企业的信息化咨询又花了一年多时间把一套MES系统的原型代码从零写到能上线中间推倒重来两次最后沉淀下来一个基于Java和Web技术栈的开源版本。这个过程中踩过的坑、推翻过和重构和思路我觉得比代码本身更有价值。这篇博客就围绕这套开源MES设计源码讲清楚它在业务上解决什么问题、技术上为什么这样选型、代码怎么组织、以及上线过程中那些文档里不会告诉你的细节。1. 为什么我坚持用Java Web技术栈做MES1.1 制造企业的IT现状决定了技术选型很多人讨论MES技术栈的时候会陷入什么技术新就用什么的误区。但我做项目时间长了以后发现制造企业的MES选型有一个非常现实的约束IT部门已有的技术积累和运维能力。国内制造业的信息化系统用友、金蝶、SAP这些ERP系统占据了主流地位而这些系统的深度定制、二次开发、接口对接大量基于Java技术体系。制造企业的IT团队哪怕是做报表、做接口、做数据分析最熟悉的人才储备几乎都是Java方向。MES作为跟ERP频繁交互的生产执行层系统选Java Web栈意味着企业IT团队能够自己接手运维和二次开发而不是被原厂或集成商长期绑定。Web技术在这里的意义不只是一个前端界面技术而是整个产品交付形态的转变。早期我接触过的一些MES是CS架构客户端装在生产现场的工控机、质检台、仓库电脑上每次更新版本的维护成本都让人头大。Web化之后工位终端只需要一个浏览器不管是Windows工控机、安卓PDA、还是车间大屏访问同一个服务端前端资源更新即时生效。一套代码覆盖PC端、PDA端、大屏端这是我在项目预算有限、实施周期紧张的情况下敢接单的原因。1.2 市面上Java Web开源MES的两个极端开始做开源版本之前我花了不少时间研究市面上的开源MES项目发现基本是两个极端。一个极端是功能看着齐全但没法用的演示型项目。这类项目在GitHub上star数量不少界面UI做得漂亮菜单里涵盖了计划、排程、质量、设备、仓储等模块点进去全是写死的假数据数据库脚本跑一遍登录进去都是demo数据。真正拿到车间去面对一天几千条报工记录、几十台设备的采集数据、复杂的工单变更流程时性能扛不住业务逻辑对不上代码写着写着就无从下手。另一个极端是专业但太重的企业级框架。这类项目往往从国外知名开源产品二次开发而来技术栈复杂、权限模型庞大、二次开发的文档却几乎没有。我见过有项目集成了一整套工作流引擎加上规则引擎光配置文件的复杂度就能劝退绝大多数实施人员。对国内中小制造企业来说这套东西根本落不了地。基于这两个极端我做这套开源MES设计源码时给自己定了几条原则业务模型要贴合国内离散制造业的真实场景技术栈要主流但不过度设计代码结构要能让人一天之内看懂核心业务流。下面我会围绕这几个原则展开讲讲具体是怎么设计的。2. MES系统到底要解决制造现场的哪些问题2.1 从一张手工报表说起理解MES的核心业务模型我建议先别看系统菜单而是看制造现场每天都在发生什么。以我熟悉的离散制造场景机加工、装配、电子制造为例车间主任每天早上一来第一件事是看昨天的产量报表这张表通常是怎么来的统计员拿着一张张纸质流转卡对着Excel手工录入算每个工序的完成数、合格数、工时。数据的上报时间滞后至少一个班次。如果中途有质量问题需要追溯要找到某一个批次某个件的所有加工记录翻纸质卡片的查询工作量巨大。生产计划员更头疼ERP把生产订单下达到车间后计划员要把订单拆分成工序计划、分配到每个工位然后跟进每个工单的实际进度。ERP只管订单下了MES要管订单现场干得怎么样了。没有MES计划员只能频繁跑现场确认进度电话一个接一个地问班组长3号工单到哪道工序了得到的信息还不一定准确。MES要解决的本质上就是这四个问题生产进度是否透明、产品质量是否可追溯、设备状态是否可视、人员绩效是否可量化。围绕这四个问题系统的业务模型再逐一展开。2.2 MES的核心业务模型我把这套开源MES的业务模型划分为六大主数据加五大业务流。六大主数据是物料、工艺路线、BOM、设备、工序、人员五大业务流是工单执行流、物料流转流、质量管控流、设备运维流、安灯异常流。六大主数据是整个MES的数据地基我重点说说工艺路线和BOM在MES和ERP里的区别。ERP里的工艺路线往往只维护一个大致的工序划分和标准工时用于成本核算字段相对简单。但MES这边每个工序要挂上对应的作业指导书、质检方案、采集项定义、设备参数甚至要把产品装配关系拆成工序级BOM即在第几道工序要用到哪些物料。这套数据结构不建立好后续的报工、质检、追溯全部无从谈起。五大业务流里面工单执行流是核心。生产订单从ERP同步过来或者直接在MES里手工创建系统把它拆解为工序任务分配到各工位工人在工位终端扫码开工、报工每道工序完成后进行工序转移系统记录每个节点的操作人、设备、时间、数量、质量状态。物料流转流与工单执行流并行关注每个物料批次在工序间的流转位置实现正反向追溯。质量管控流覆盖来料检验、工序检验、完工检验异常情况触发不合格品处理流程。设备运维流管理设备点检、维保、故障记录。安灯异常流则处理生产现场的异常上报、呼叫响应和闭环处理。这些业务流之间不是孤立的一个工人在报工的同时系统已经在后台扣减了在制品数量、统计了工时、更新了质量检验记录、写入了设备使用时间。这也是MES跟普通的进销存软件最大的区别MES是围绕工单的生产过程进行实时数据采集和联动处理的系统。3. 系统架构设计单体优先接口先行3.1 后端分层设计在技术架构上我经历了从微服务到模块化单体的反思过程。最开始我也想着做微服务拆订单服务、质量服务、设备服务等但拆完就发现MES系统的核心业务流程是强事务强一致性的一次报工操作可能同时更新工单状态、工序进度、质量记录、设备台账等多个业务对象。如果拆成多个服务事务处理变成分布式事务复杂度成倍增加而中小制造企业的并发量根本不需要这样的架构。所以最终这个开源版本采用模块化单体架构一个Spring Boot应用内部按业务域划分模块模块之间通过接口调用未来如果真的需要拆服务模块边界已经预留好了。后端技术栈方面核心是Spring Boot 3.x。安全认证用了Spring Security集成JWT接口鉴权到按钮级别。持久层用的MyBatis-Plus配合代码生成器可以快速生成单表CRUD。数据库主要支持MySQL 8.x同时也兼容了PostgreSQL。Redis用于缓存基础数据和会话管理。工单进度、设备状态这类需要实时推送的数据用WebSocket推送到看板客户端。代码分层遵循标准的三层架构之上增加了一层领域服务层。Controller层只做参数校验和路由不写业务代码。Service层处理业务逻辑但Service之间不能互相调用对方的Mapper需要通过领域服务层来交互这样做的目的是为了划分业务边界比如质量模块需要获取工单信息只能通过工单域提供的接口获取不能直接去查工单表。3.2 数据库设计的关键取舍MES系统的数据库设计有几个关键取舍我在代码仓库的数据库设计文档里写得很详细这里挑几个容易踩坑的点讲讲。第一个是工序间报工的数据建模。我见过很多MES把每道工序报工记录直接做成一个表用工序ID区分字段冗余严重。我这边采用两张核心表工单工序表每个工单拆分的所有工序计划及状态和工序报工记录表每次报工的实际数据快照。报工记录表里冗余了工单号、产品编码、工序编码、操作工、设备编号、计划数量、合格数量、不合格数量、报工时长、报工时间等字段。冗余是有意的因为报工记录是后续追溯和统计分析的原始数据需要保持数据的不可变性不能通过关联查询去还原当时的状态。第二个是物料批次追溯模型。追溯查询是MES的高频功能比如客户投诉某个批次的零件有质量问题需要反查这批零件用了哪些原材料批次、经过哪些设备加工、操作工是谁。正向追溯和反向追溯的SQL要能在秒级内返回结果这就需要设计好物料批号和工序投料记录的索引。我采用的方案是维护一张生产投料记录表记录每一个工单的每一道工序投入了哪些物料批次、数量多少。有了这张表正反向追溯都只需要简单的表关联查询。关于数据库字段设计还有一点要强调MES的数据量增长很快但不代表需要过度设计。一些初创项目把雪花ID、分库分表、读写分离一开始就全上了结果团队维护成本极高。我这套代码默认使用数据库自增ID在分布式部署场景下可以通过配置切换为雪花ID索引设计根据实际查询场景来做不做过度设计。等单日报工记录超过几十万条再考虑分表对于绝大多数制造企业这个量级意味着已经是几千人的大厂规模了。3.3 前端与实时通信方案前端部分采用Vue 3 Element Plus Vite的SPA架构PC端管理后台、车间工位端、看板大屏端共用一套代码通过路由和角色控制访问不同的页面布局。车间工位端是我花精力比较多的地方。它的使用场景是车间工人文化水平参差不齐有些老师傅不习惯用电脑所以工位端界面要做得尽量简单——一个大按钮是开工一个大按钮是报工扫码输入框自动聚焦。这套设计理念跟普通后台管理系统完全不一样相当于开发人员在设计界面时就要有用户研究意识要从一线工人的使用习惯倒推界面设计而不是把通用表格塞给他们。我为此专门做了一个极简模式的工位页面在分辨率1024x768的工业触屏一体机上也能顺畅操作。实时数据这块看板大屏的产量、设备状态、异常信息都是通过WebSocket推送的。实现起来倒不复杂前端建立WebSocket连接后后端把车间、产线、工单维度订阅关系维护在Redis里业务数据变更时发布事件到对应的订阅通道前端收到消息后局部刷新视图。关键点是断线重连和消息补偿不然看板在车间容易掉线后数据一直不刷新。我处理的办法是前端在重连成功后主动拉取一次全量数据保证断线期间的数据不会丢。4. 核心业务模块的设计思路与代码实现4.1 工单执行流的实现细节工单模块是整套MES的发动机。生产订单从ERP同步到MES后也支持手工创建系统自动根据订单产品对应的工艺路线生成工单工序计划。// 工单创建核心逻辑简化版 Transactional public WorkOrder createWorkOrder(WorkOrderCreateRequest request) { // 1. 校验物料、工艺路线、BOM是否存在 Material material materialRepository.findById(request.getMaterialId()) .orElseThrow(() - new BusinessException(物料不存在)); Routing routing routingRepository.findByMaterialIdAndVersion( material.getId(), request.getRoutingVersion()); if (routing null) { throw new BusinessException(该物料未维护工艺路线); } // 2. 创建工单主记录 WorkOrder order new WorkOrder(); order.setOrderNo(generateOrderNo()); // 自动生成工单号 order.setMaterialId(material.getId()); order.setPlanQty(request.getPlanQty()); order.setStatus(WorkOrderStatus.CREATED); // 3. 根据工艺路线展开工序计划 ListRoutingProcess processes routing.getProcesses(); ListWorkOrderProcess orderProcesses new ArrayList(); for (int i 0; i processes.size(); i) { RoutingProcess rp processes.get(i); WorkOrderProcess op new WorkOrderProcess(); op.setProcessCode(rp.getProcessCode()); op.setProcessName(rp.getProcessName()); op.setSeq(i 1); op.setPlanQty(request.getPlanQty()); op.setStatus(ProcessStatus.PENDING); orderProcesses.add(op); } workOrderProcessRepository.saveAll(orderProcesses); // 4. 初始化工单执行汇总数据 WorkOrderSummary summary new WorkOrderSummary(); summary.setOrderId(order.getId()); summary.setCompletedQty(0); summary.setQualifiedQty(0); summary.setScrappedQty(0); workOrderSummaryRepository.save(summary); return order; }这段代码展示了工单创建的关键流程校验基础数据、生成工单主记录、展开工序计划、初始化执行汇总。我在注释里标了每个步骤的目的因为工单创建看起来简单但每一步都可能出错比如工艺路线版本没维护、BOM没生效、物料状态不是可生产状态等。报工是整个系统里并发量最高的操作。车间里几十个工位同时提交报工每次报工不仅要更新工单工序状态还要实时刷新产量看板。这里我用数据库乐观锁控制工序并发报工即在工序表增加version字段更新时比对版本号防止两个工位同时给同一道工序报工导致数据错乱。-- 报工更新工序进度乐观锁防并发 UPDATE work_order_process SET completed_qty #{completedQty}, qualified_qty #{qualifiedQty}, status CASE WHEN #{completedQty} plan_qty THEN COMPLETED ELSE IN_PROGRESS END, version version 1 WHERE id #{id} AND version #{version}4.2 质量追溯与防错机制质量模块在开源版本里做了一个完整的追溯链路。追溯的最小单元是物料批次每个物料批次有唯一的批次号通过批次号可以关联到工单、加工设备、操作工、检验记录、原材料批次。// 反向追溯从成品批次追溯原材料批次 public TraceResult traceBackward(String finishedBatchNo) { // 1. 根据成品批次找到最后一道工序的报工记录 WorkReport lastReport reportRepository.findByBatchNo(finishedBatchNo); if (lastReport null) { throw new BusinessException(未找到该批次的生产记录); } // 2. 沿工单找到所有工序的投料记录 ListMaterialIssueRecord issueRecords issueRecordRepository .findByOrderId(lastReport.getOrderId()); // 3. 整理成树状追溯结构 TraceResult result new TraceResult(); result.setOrderNo(lastReport.getOrderNo()); result.setProcessRecords(reportRepository.findByOrderId(lastReport.getOrderId())); result.setMaterialRecords(issueRecords); return result; }实际项目里做追溯优化的时候我还加了一个数据快照机制报工的时候不仅写入报工记录还把当时的工单信息、产品信息、物料批次信息生成一份冗余快照存入追溯表。这个设计的初衷是防止后期基础数据被修改比如产品名称改了、物料编码换了导致历史追溯查出来的信息跟当时实际生产情况不一致。记录历史状态而不是查询时去关联当前主数据这是MES生产追溯设计的核心思想。防错机制方面我实现了两个实用的功能。一个是物料防错工位报工时扫描物料批次条码系统自动校验该批次是否属于当前工单BOM范围内如果不匹配则拒绝报工并提示。另一个是工序防错系统判断当前工单是否已完成前置工序的报工未完成前置工序则不允许后工序开工。这两个防错功能是我在项目实施中被客户反复要求的很多时候质量问题就是最基本的工序错乱和物料用错导致的。4.3 设备数据采集与看板联动设备模块的核心是设备台账、点检保养和OEE统计。OEE的统计需要设备运行数据这块我通过两种方式采集一种是支持OPC UA协议的数据采集服务自动采集设备状态和产量数据另一种是设备无数据接口的场景下由人工在工位端手工录入运行状态。开源的设备采集服务我用的是Eclipse Milo库来实现OPC UA客户端采集到的设备状态数据发送到MQTT消息队列后端订阅消息解析后更新设备状态和OEE计算。这样设计的好处是采集服务与主业务服务解耦采集服务挂了不影响报工等核心业务操作。设备OEE的计算公式是OEE 时间开动率 × 性能开动率 × 合格品率 时间开动率 实际运行时间 / 计划运行时间 性能开动率 理论节拍 × 生产数量 / 实际运行时间 合格品率 合格品数量 / 生产数量这套计算逻辑在代码里是独立一个工具类实现的因为我在多个项目中发现每个客户对OEE的统计口径理解都不太一样有的客户要求按班次算有的要求按天算有的要排除换型时间。所以我把OEE的计算公式参数化了运营管理员可以在系统设置里配置每个班次的计划运行时间、换型时间、停机时间等参数系统再基于参数计算而非硬编码。5. 开源项目的代码组织与二次开发指引5.1 代码仓库结构说明代码仓库的目录结构是经过几次整理后确定的力求让一个首次接触的开发者能在半小时内找到关键的代码位置。mes-platform/ ├── mes-admin # 后台管理前端Vue3 Element Plus ├── mes-workstation # 工位端前端极简模式 ├── mes-server # 后端主服务Spring Boot │ ├── mes-common # 通用工具、常量、异常定义 │ ├── mes-framework # 框架配置安全、Web、数据库、Redis │ ├── mes-system # 系统管理用户、角色、菜单、字典 │ ├── mes-domain # 领域模型定义 │ ├── mes-repository # 数据访问层 │ ├── mes-service # 业务服务层 │ └── mes-web # Web接口层 ├── mes-collect # 设备数据采集服务OPC UA / MQTT ├── sql # 数据库初始化脚本 └── docs # 设计文档、部署文档、接口文档这里重点说说业务模块的划分。我按mes-order工单、mes-quality质量、mes-equipment设备、mes-material物料、mes-ou组织架构包括工厂、车间、产线、工序划分模块。每个模块内部的代码组织保持统一domain放实体类repository放MyBatis-Plus的Mapper接口service放业务逻辑controller放REST接口。这样一个新开发者接手一个模块的开发任务只需要关注这一个模块内部的四个包即可。建议拿到代码之后先跑通启动流程再自上而下看一遍创建工单到报工完成这条主链路的代码不要上来就去研究设备采集、安灯联动的代码那部分涉及外部系统对接背景知识要求高。5.2 部署文档与二次开发要点部署这块我在docs目录下写了两份文档一份是面向小企业的单机部署文档一台服务器跑数据库后端前端NGINX做静态资源服务另一份是面向有一定规模企业的集群部署文档MySQL、Redis、后端服务、前端静态资源分离部署。我个人的建议是第一版先老老实实单机部署。MES系统的数据量虽然增长快但单台的服务器配置到位建议32G内存、8核CPU起步磁盘用SSD支撑一两百个并发用户的日常操作没有问题。等系统真的跑起来之后再根据监控数据决定是否要拆集群。二次开发最常见的需求有三个对接客户自己的ERP系统、调整报表格式、增加客户特有的业务字段。针对第一个需求我在代码里预留了一个open-api模块提供了一套基于AppKey/AppSecret鉴权的开放接口专门用于ERP、WMS、SCADA等系统的数据集成接口文档在docs/接口文档.md里。针对第二个需求报表部分我引入了积木报表作为内置报表引擎支持在线设计报表模板。针对第三个需求我建议优先使用扩展字段机制不要直接修改核心表的表结构因为升级代码的时候改过的表结构会导致SQL脚本冲突。6. 从开源代码到真正上线要过的五道坎6.1 基础数据的整理远比写代码困难这是我在多次实施中体会最深的一条MES项目的实施难点不在软件功能而在基础数据的整理。物料编码是否规范、工艺路线是否完整、BOM是否准确、工序名称是否统一这些数据如果本身有问题MES上线就是灾难。我见过一家企业上了MES后发现同一个物料在ERP里有三套编码车间工人根本不知道该扫哪个码。后面花了两个月做数据清洗才勉强能用。所以如果你准备在企业里推MES第一个要做的不是看软件演示而是把ERP里的物料、BOM、工艺路线数据导出来先做一次数据健康度检查。给开源项目做实施建议的话先花两周梳理基础数据再花一周做系统配置和测试最后再开始试运行这个节奏是比较稳妥的。6.2 车间网络的稳定性与工位终端选型MES在车间运行依赖的是车间网络。很多制造企业的车间环境比较恶劣高温、粉尘、电磁干扰WiFi覆盖不稳定工控机老旧这些问题都会直接影响报工效率。我建议车间网络尽量用有线网络工位固定位置都用RJ45网线超五类以上移动场景如PDA扫码枪才用WiFi而且需要在车间部署企业级AP并做好漫游配置。工位终端不要买几千块钱的消费级平板推荐用工业触控一体机里面配的是低功耗工控主板支持7x24小时运行耐用性完全不在一个级别。6.3 条码标签与扫码设备的标准化MES操作里最高频的动作是扫码所以条码规则和扫码设备必须标准化。条码规则方面物料批次条码推荐使用Code128编码包含物料编码和批次号信息关键字段用固定长度。在代码里我封装了一个条码解析工具类支持自定义条码规则配置这样不同企业的条码格式都能适配。扫码设备这块固定工位建议用USB接口的工业扫码枪推荐霍尼韦尔、新大陆等主流品牌即插即用免驱支持主流系统。移动场景用工业PDA操作系统选Android的话我开源了一个配套的PDA扫码应用接口已经跟后端联调好了装上去就能用。6.4 试运行期间的人工并行与双轨制MES上线最忌讳的就是一刀切停掉旧流程直接切到新系统。稳妥的做法是双轨制试运行纸质流转卡和MES并行跑一个月每天统计两边数据的差异原因确认系统数据准确率达到要求之后再逐步取消纸质流转卡。双轨制阶段工人会觉得工作量翻倍抱怨声会很大。这个阶段要安排车间主任和IT人员现场盯着随时解决操作问题同时跟一线工人讲清楚为什么要上MES——不是为了监控他们而是为了出了问题能快速响应、减少扯皮。很多工人用顺手之后反而觉得比手写报表省事多了。6.5 历史数据迁移是上线后第一个大麻烦试运行通过之后紧接着要面对的就是历史数据迁移。已经生产完的工单要不要录进MES在制工单怎么办未完成的质检单如何处理我的建议是已经关闭的工单不要迁只把近三个月的在制工单导入状态调整为已开工或待报工其他历史数据作为离线文档归档。质量追溯的数据可以保留少量关键批次的信息录入系统其余作为历史纸质档案封存。这样既保证了追溯的连续性又不需要投入大量人力做数据补录。部署方案这块我写了一份基于Docker Compose的一键部署配置文件能用一条命令把MySQL、Redis、后端服务、前端界面全部拉起来version: 3.8 services: mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: ${MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: mes ports: - 3306:3306 volumes: - mysql_data:/var/lib/mysql - ./sql:/docker-entrypoint-initdb.d redis: image: redis:7-alpine ports: - 6379:6379 mes-server: build: ./mes-server ports: - 8080:8080 environment: SPRING_DATASOURCE_URL: jdbc:mysql://mysql:3306/mes SPRING_DATA_REDIS_HOST: redis depends_on: - mysql - redis mes-admin: build: ./mes-admin ports: - 80:80 depends_on: - mes-server volumes: mysql_data:这种部署方式适合测试环境快速验证生产环境我还是建议手动部署每一层单独管理便于运维排查问题。7. 开源社区版和企业定制版怎么取舍这套系统我开源出来后陆续有开发者问能不能直接用于商业项目。我的回答是社区版代码完全可以用于学习和中小企业的轻量级应用它包含了MES最核心的业务闭环。但如果你的客户有复杂的排产算法需求、多工厂协同需求、高级质量管理SPC需求需要在代码基础上做不少扩展。我见过一些企业拿着开源MES直接上生产环境的用得也不差关键看业务复杂度。如果你是做标准件加工的工艺路线相对固定工序数量少这套系统的工单执行流和质量管理模块可以直接用。但如果你做的是大型装备制造一个产品的BOM上千行、工艺路线几十道工序、还牵扯到齐套分析、高级排程那这套开源版本只能作为起点需要团队有较强的二次开发能力。从投入产出的角度看如果你所在的企业年产值不大、IT团队只有一两个人采购商业MES的成本可能难以承受源码开放、无授权费用的开源MES确实是个现实的选择。但一定要对实施的工作量有清醒认知——不是下载了代码就能跑基础数据、网络改造、人员培训、流程变革每一项都是投入。代码仓库的README里我写了一段话MES不是买来的也不是下载来的是跟企业一起长出来的。这段话是我做MES几年最深的感悟。软件只是载体真正让系统活起来的是企业自己的管理流程和执行力。希望通过开源这套Java Web版的MES源码能让更多制造企业以低成本的方式理解MES、应用MES也让更多Java开发者能通过这个项目接触制造业数字化的真实场景。本文还有配套的精品资源点击获取
返回列表