智能制造行业对 MES(制造执行系统)的需求从来不是"有没有",而是"能不能快速适配产线变化"。Skyeye 云这次发布的 v3.19.5,核心看点不在版本号本身,而是它用 SpringBoot + UNI-APP + Ant Design Vue 搭出的零代码底座,把 MES 从定制开发拉到了配置驱动的轨道上。
一套底座,跑一百多种流程
Skyeye 的架构思路很直接:一个零代码平台承载所有业务模块——CRM、ERP、MES、OA、EHR、薪资考勤、云售后、报表设计、工作流……总共超过 100 种电子流程。MES 只是其中一个切面,但它和 ERP、考勤、薪资之间的数据流转(比如工单完工触发计件工资)是真正考验平台连通性的地方。
技术栈拆开看:
- 后端:SpringBoot,负责流程引擎、权限、数据模型
- 移动端:UNI-APP,一套代码跑 iOS / Android / 小程序,车间扫码、报工场景直接落地
- 前端管理界面:Ant Design Vue,表单设计器、流程编排器都在这里
零代码的实现方式不是"没有代码",而是"业务人员不写代码"——平台提供表单设计器、流程编排、报表拖拽,开发者只需要在极端场景下才介入自定义脚本。
MES 模块在这个体系里做什么
MES 在 Skyeye 里不是独立系统,而是平台上的一个业务域。它覆盖的典型场景包括:
- 生产工单下达与排程
- 车间报工(扫码 + UNI-APP 移动端)
- 工艺路线与工序流转
- 物料追溯与质量记录
- 设备状态采集
关键在于,这些流程的表单字段、审批节点、数据联动规则都是通过平台配置出来的,不是硬编码。当产线换产品型号时,改配置而不是改代码。
实践:用 SpringBoot 搭一个最小零代码表单引擎原型
Skyeye 的零代码能力依赖完整的表单设计器和流程引擎,但如果你想在自己的项目里尝试类似思路,可以从一个最简的动态表单驱动开始。下面是一个可运行的 SpringBoot 示例——用 JSON Schema 定义表单,后端动态存储,前端按 Schema 渲染。
1. Maven 依赖
<!-- pom.xml 核心依赖 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.7.18</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
<version>2.7.18</version>
</dependency>
<dependency>
<groupId>com.github.everit-org.json-schema</groupId>
<artifactId>org.everit.json.schema</artifactId>
<version>1.14.4</version>
</dependency>
</dependencies>
MongoDB 适合存动态结构数据——表单定义和提交数据都不需要预建表。
2. 表单定义与提交 Controller
package com.example.zeroform;
import org.everit.json.schema.Schema;
import org.everit.json.schema.loader.SchemaLoader;
import org.json.JSONObject;
import org.json.JSONTokener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
@RestController
@RequestMapping("/api/form")
public class FormController {
@Autowired
private MongoTemplate mongoTemplate;
// 创建表单 Schema(管理员配置,相当于零代码设计器产出)
@PostMapping("/define")
public Map<String, Object> defineForm(@RequestBody Map<String, Object> schemaDef) {
// schemaDef 包含 formKey + JSON Schema
mongoTemplate.save(schemaDef, "form_definitions");
return Map.of("status", "ok", "formKey", schemaDef.get("formKey"));
}
// 提交表单数据(车间报工等场景)
@PostMapping("/submit/{formKey}")
public Map<String, Object> submitForm(
@PathVariable String formKey,
@RequestBody Map<String, Object> formData
) {
// 取出 Schema 做校验
Map<String, Object> def = mongoTemplate.findOne(
org.springframework.data.mongodb.core.query.Query.query(
org.springframework.data.mongodb.core.query.Criteria.where("formKey").is(formKey)
), Map.class, "form_definitions"
);
if (def == null) {
return Map.of("status", "error", "message", "表单定义不存在");
}
JSONObject schemaJson = new JSONObject(def.get("schema"));
Schema schema = SchemaLoader.load(schemaJson);
JSONObject dataJson = new JSONObject(formData);
try {
schema.validate(dataJson); // 校验失败会抛 ValidationException
} catch (Exception e) {
return Map.of("status", "error", "message", e.getMessage());
}
formData.put("formKey", formKey);
mongoTemplate.save(formData, "form_submissions");
return Map.of("status", "ok");
}
}
3. 一个 MES 报工表单的 Schema 示例
{
"formKey": "mes_work_report",
"schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["workOrderId", "operatorId", "completedQty", "defectQty"],
"properties": {
"workOrderId": { "type": "string", "title": "工单号" },
"operatorId": { "type": "string", "title": "操作员ID" },
"completedQty": { "type": "integer", "minimum": 0, "title": "完工数量" },
"defectQty": { "type": "integer", "minimum": 0, "title": "不良数量" },
"stationCode": { "type": "string", "title": "工位编码" },
"remark": { "type": "string", "maxLength": 200, "title": "备注" }
}
}
}
调用 POST /api/form/define 存入这个 Schema,之后车间人员通过 POST /api/form/submit/mes_work_report 提交报工数据,后端自动校验字段类型和必填项。新增字段?改 Schema 就行,不用改代码、不用改数据库表结构。
4. 启动类与配置
package com.example.zeroform;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ZeroFormApplication {
public static void main(String[] args) {
SpringApplication.run(ZeroFormApplication.class, args);
}
}
# application.yml
spring:
data:
mongodb:
uri: mongodb://localhost:27017/zeroform
server:
port: 8080
本地跑起来后,用 curl 就能测试完整流程:
# 1. 定义 MES 报工表单
curl -X POST http://localhost:8080/api/form/define \
-H "Content-Type: application/json" \
-d '{
"formKey": "mes_work_report",
"schema": {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["workOrderId","operatorId","completedQty","defectQty"],
"properties": {
"workOrderId": {"type":"string","title":"工单号"},
"operatorId": {"type":"string","title":"操作员ID"},
"completedQty": {"type":"integer","minimum":0,"title":"完工数量"},
"defectQty": {"type":"integer","minimum":0,"title":"不良数量"},
"stationCode": {"type":"string","title":"工位编码"},
"remark": {"type":"string","maxLength":200,"title":"备注"}
}
}
}'
# 2. 提交一条报工数据
curl -X POST http://localhost:8080/api/form/submit/mes_work_report \
-H "Content-Type: application/json" \
-d '{
"workOrderId": "WO-20240601-001",
"operatorId": "EMP-0087",
"completedQty": 120,
"defectQty": 3,
"stationCode": "ST-A03",
"remark": "换线后首批次"
}'
这个原型离 Skyeye 的完整零代码平台还有很大距离——缺少流程编排、权限控制、前端设计器、多模块数据联动——但它展示了"Schema 驱动表单 + 动态存储"这条核心路径的实现起点。
零代码平台的取舍
Skyeye 把 CRM、ERP、MES、OA、薪资考勤全塞进一个平台,好处是数据天然互通、部署运维集中;代价是:
- 模块耦合度:100 多种流程共享同一套权限和流程引擎,某个模块的配置变更可能影响全局行为,需要严格的租户/模块隔离机制
- 深度定制受限:零代码覆盖 80% 场景没问题,但极端业务逻辑(比如复杂排程算法、实时设备协议解析)最终还是需要写代码介入
- 性能瓶颈:动态表单 + 通用流程引擎的查询效率,比专门优化的硬编码 MES 要低,大规模产线数据采集时需要关注
落地建议
如果你在评估这类零代码制造平台,可以按这个清单走:
- 先选一个模块试跑:不要一口气上全模块。MES 报工 + 考勤联动是最容易验证连通性的组合。
- 测极限场景:拿一条真实产线的峰值报工数据量压一下提交接口,看动态 Schema 校验的延迟是否可接受。
- 确认扩展边界:问清楚哪些场景需要写自定义脚本、脚本运行在什么沙箱里、有没有热更新机制。
- 看移动端体验:UNI-APP 在扫码场景下的响应速度和离线能力,直接决定车间工人愿不愿意用。
- 数据导出与迁移:动态存储的数据怎么导出为标准格式,未来如果换平台,迁移成本多大。
零代码不是万能药,但它确实把"从需求到上线"的时间从月级压缩到了天级。Skyeye v3.19.5 的 MES 模块更新,本质上是这条路上的又一个增量——表单更丰富、流程节点更多、和 ERP/考勤的联动更顺。真正决定它能不能用在你的产线上,还是得跑起来试。