Skyeye 云零代码智能制造系统发布 SaaS 模块 v3.19.12。该系统采用 Spring Boot、UNI-APP 与 Ant Design Vue 构建,覆盖 CRM、ERP、MES、项目管理、财务、考勤、招聘、售后、工作流和报表设计等业务。比版本号更值得关注的是它所呈现的平台思路:把制造企业的流程、数据和多端入口放进同一套可配置底座,并通过 SaaS 模块服务多个组织或租户。
零代码在制造场景中解决什么问题
制造企业的系统通常不是缺少功能,而是功能之间容易断裂。销售订单进入 CRM,生产计划进入 ERP 或 MES,售后工单又落入另一套系统。员工不得不重复录入客户、物料、设备和组织信息,管理者也很难获得口径一致的报表。
Skyeye 所列出的模块覆盖了从客户、项目、生产到人力和财务的较长业务链,并提供 100 多种电子流程。零代码模式在这里的价值,不只是拖拽页面,而是让实施人员围绕统一数据模型配置表单、审批节点、权限和报表。例如,“客户投诉”可以串联售后工单、质量处理、责任人审批和结果回访,而不必为每次流程调整重新开发整套前后端。
但零代码不等于没有工程成本。物料编码、工序状态、组织层级、审批权限和财务口径仍然需要明确建模。如果基础数据混乱,图形化配置只会更快地复制混乱。
SaaS 模块的关键不是登录页,而是租户边界
SaaS 化意味着一套部署可以承载多个企业或组织。对制造系统而言,租户隔离至少应覆盖以下对象:
- 用户、角色、部门与数据权限;
- 客户、供应商、物料、仓库和设备;
- 订单、工单、生产记录与质量记录;
- 附件、导出文件、缓存、消息和审计日志;
- 工作流定义以及租户自己的表单配置。
应用层在查询条件中增加 tenant_id 只是起点。异步任务、报表导出、消息消费和定时作业也必须携带租户上下文,否则普通页面看似隔离,后台任务仍可能读取或写入其他租户的数据。
版本摘要没有展开 v3.19.12 的具体变更清单,因此不能仅凭发布信息判断它采用了哪一种隔离模型。评估时应直接验证跨租户访问、缓存键设计、文件路径、备份恢复和管理员权限,而不是只检查前端菜单是否分开。
可以这样实践:为 Spring Boot 服务补上租户上下文
下面是一个可改造的 Spring Boot 配置示例。这里明确做两个假设:网关已经完成身份认证,并通过 X-Tenant-Id 传递可信租户编号;业务表使用共享数据库、共享表,并包含 tenant_id 字段。生产环境不能直接信任浏览器提交的租户编号,网关必须根据登录凭证校验用户与租户的关系。
先配置请求头名称和无需租户上下文的公共路径:
# application.yml
tenancy:
header-name: X-Tenant-Id
excluded-paths:
- /actuator/health
- /api/auth/login
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/skyeye_demo?useSSL=false&serverTimezone=UTC
username: skyeye
password: change-me
可以这样实现一个最小租户上下文和过滤器:
package com.example.tenancy;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import java.io.IOException;
final class TenantContext {
private static final ThreadLocal<Long> CURRENT = new ThreadLocal<>();
static void set(long tenantId) {
CURRENT.set(tenantId);
}
static long require() {
Long tenantId = CURRENT.get();
if (tenantId == null) {
throw new IllegalStateException("Tenant context is missing");
}
return tenantId;
}
static void clear() {
CURRENT.remove();
}
}
@Component
public class TenantFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(
HttpServletRequest request,
HttpServletResponse response,
FilterChain filterChain) throws ServletException, IOException {
String value = request.getHeader("X-Tenant-Id");
if (value == null || !value.matches("[1-9][0-9]*")) {
response.sendError(400, "Missing or invalid X-Tenant-Id");
return;
}
try {
TenantContext.set(Long.parseLong(value));
filterChain.doFilter(request, response);
} finally {
TenantContext.clear();
}
}
}
数据库表应同时建立租户维度的唯一约束,避免两个企业之间发生编码冲突:
CREATE TABLE material (
id BIGINT PRIMARY KEY AUTO_INCREMENT,
tenant_id BIGINT NOT NULL,
material_code VARCHAR(64) NOT NULL,
material_name VARCHAR(255) NOT NULL,
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
UNIQUE KEY uk_material_tenant_code (tenant_id, material_code),
KEY idx_material_tenant_name (tenant_id, material_name)
);
接口联调时可以直接发送租户请求头:
curl -i \
-H 'Authorization: Bearer replace-with-token' \
-H 'X-Tenant-Id: 1001' \
http://localhost:8080/api/materials
这个示例只展示上下文入口,不能单独构成完整的租户隔离方案。实际项目还需要让 ORM 自动注入 tenant_id 条件,并为消息队列、线程池和定时任务显式传递租户编号。依赖 ThreadLocal 时尤其要在 finally 中清理,避免线程复用造成上下文泄漏。
升级与采用时应验证什么
对于已经运行 Skyeye 的团队,升级 v3.19.12 前应先在预发布环境复制关键流程,重点回归销售订单、生产工单、库存变更、考勤结算和财务相关链路。零代码平台的配置也是生产资产,应纳入导出、版本管理、差异审查和回滚流程。
新项目则可以从一条跨模块闭环开始,例如“销售订单 → 生产计划 → 领料 → 完工入库 → 发货”,不要一次启用所有模块。上线前至少完成以下检查:
- 两个测试租户使用相同物料编码,确认数据与唯一约束互不影响;
- 使用租户 A 的令牌访问租户 B 的记录,确认服务端拒绝请求;
- 检查导出文件、对象存储目录和缓存键是否包含租户维度;
- 验证工作流发布、变更和回滚是否有审计记录;
- 对移动端、管理端和异步任务执行同一套权限测试;
- 在升级前备份数据库、附件和零代码配置,并实际演练恢复。
Skyeye v3.19.12 展示的是一套覆盖面较广的智能制造平台路线。真正决定落地质量的,不是模块数量,而是数据模型是否统一、租户边界是否可靠,以及关键制造流程能否被持续验证和审计。