企业级 MES 制造执行系统架构设计与实践

引言

制造执行系统(Manufacturing Execution System,MES)是连接企业计划层与车间执行层的核心系统,负责生产计划的执行、生产过程的监控、质量管理、设备管理等关键功能。本文以 PointLion Cloud MES 模块为例,深入探讨如何基于 Spring Cloud 微服务架构构建企业级 MES 系统。

相关链接

技术架构概览

核心技术栈

  • Spring Boot 2.7.18: 微服务基础框架
  • Spring Cloud 2021.0.9: 微服务治理
  • Spring Cloud Alibaba 2021.0.6.2: 阿里云生态集成
  • MyBatis Plus 3.5.10.1: ORM 框架
  • Flowable 6.8.0: 工作流引擎
  • Redisson 3.41.0: 分布式缓存
  • XXL-Job 2.4.0: 分布式任务调度
  • RocketMQ 2.3.1: 消息队列
  • TDengine 3.3.3: 时序数据库

MES 系统功能架构

复制代码
┌─────────────────────────────────────────────────────────┐
│                      前端展示层                            │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐  │
│  │ PC 端   │  │ 移动端   │  │ 大屏     │  │ 报表     │  │
│  └─────────┘  └─────────┘  └─────────┘  └─────────┘  │
├─────────────────────────────────────────────────────────┤
│                      应用服务层                            │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐  │
│  │ 计划管理 │  │ 生产执行 │  │ 质量管理 │  │ 设备管理 │  │
│  │ 工艺管理 │  │ 仓储管理 │  │ 能源管理 │  │ 系统管理 │  │
│  └─────────┘  └─────────┘  └─────────┘  └─────────┘  │
├─────────────────────────────────────────────────────────┤
│                      业务中台层                            │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐  │
│  │ 工作流  │  │ 规则引擎 │  │ 数据采集 │  │ 告警中心 │  │
│  │ 权限管理 │  │ 多租户   │  │ 数据权限 │  │ 审计日志 │  │
│  └─────────┘  └─────────┘  └─────────┘  └─────────┘  │
├─────────────────────────────────────────────────────────┤
│                      数据存储层                            │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐  │
│  │ MySQL   │  │ Redis   │  │TDengine │  │ RocketMQ│  │
│  └─────────┘  └─────────┘  └─────────┘  └─────────┘  │
├─────────────────────────────────────────────────────────┤
│                      设备集成层                            │
│  ┌─────────┐  ┌─────────┐  ┌─────────┐  ┌─────────┐  │
│  │ PLC     │  │ 传感器  │  │ 数控设备 │  │ AGV     │  │
│  └─────────┘  └─────────┘  └─────────┘  └─────────┘  │
└─────────────────────────────────────────────────────────┘

生产计划管理模块设计

生产工单管理核心实现

java 复制代码
@Service
public class ProductionOrderService {
    
    private final ProductionOrderMapper orderMapper;
    private final WorkOrderRouter workOrderRouter;
    private final RedissonClient redissonClient;
    private final RocketMQTemplate rocketMQTemplate;
    
    /**
     * 创建生产工单
     */
    @Transactional(rollbackFor = Exception.class)
    public Long createProductionOrder(ProductionOrderCreateReq req) {
        // 1. 参数校验
        validateOrderCreateReq(req);
        
        // 2. 构建工单实体
        ProductionOrder order = buildProductionOrder(req);
        
        // 3. 工单排程计算
        scheduleWorkOrder(order);
        
        // 4. 物料需求计算
        calculateMaterialRequirement(order);
        
        // 5. 保存工单
        orderMapper.insert(order);
        
        // 6. 发送工单创建消息
        sendOrderCreateMessage(order);
        
        return order.getId();
    }
    
    /**
     * 工单排程计算
     */
    private void scheduleWorkOrder(ProductionOrder order) {
        // 1. 获取生产线信息
        ProductionLine line = productionLineMapper.selectById(order.getLineId());
        
        // 2. 获取工艺路线
        ProcessRoute route = processRouteMapper.selectById(order.getRouteId());
        
        // 3. 计算标准工时
        List<ProcessStep> steps = route.getSteps();
        long totalStandardTime = 0;
        for (ProcessStep step : steps) {
            totalStandardTime += step.getStandardTime() * order.getQuantity();
        }
        
        // 4. 计算排产时间
        LocalDateTime startTime = calculateStartTime(order, line);
        LocalDateTime endTime = startTime.plusSeconds(totalStandardTime);
        
        // 5. 产能冲突检查
        if (hasCapacityConflict(line.getId(), startTime, endTime)) {
            throw new BusinessException("产线产能冲突,无法排产");
        }
        
        order.setPlanStartTime(startTime);
        order.setPlanEndTime(endTime);
        order.setStandardTime(totalStandardTime);
    }
    
    /**
     * 物料需求计算(MRP)
     */
    private void calculateMaterialRequirement(ProductionOrder order) {
        // 1. 获取 BOM 清单
        List<BomNode> bomList = bomMapper.selectByProductId(order.getProductId());
        
        // 2. 计算物料需求
        List<MaterialRequirement> requirements = new ArrayList<>();
        for (BomNode bom : bomList) {
            MaterialRequirement req = new MaterialRequirement();
            req.setOrderId(order.getId());
            req.setMaterialId(bom.getMaterialId());
            req.setRequiredQuantity(bom.getQuantity() * order.getQuantity());
            req.setUnit(bom.getUnit());
            
            // 3. 检查库存
            MaterialStock stock = materialStockMapper.selectByMaterialId(bom.getMaterialId());
            if (stock != null && stock.getAvailableQuantity() >= req.getRequiredQuantity()) {
                req.setSupplyStatus("SUFFICIENT");
            } else {
                req.setSupplyStatus("SHORTAGE");
                req.setShortageQuantity(req.getRequiredQuantity() - 
                    (stock != null ? stock.getAvailableQuantity() : 0));
            }
            
            requirements.add(req);
        }
        
        // 4. 保存物料需求
        materialRequirementMapper.batchInsert(requirements);
    }
    
    /**
     * 工单开工
     */
    public void startWorkOrder(Long orderId) {
        ProductionOrder order = orderMapper.selectById(orderId);
        
        // 1. 状态检查
        if (!"PENDING".equals(order.getStatus())) {
            throw new BusinessException("工单状态不允许开工");
        }
        
        // 2. 前置条件检查
        checkStartConditions(order);
        
        // 3. 更新工单状态
        order.setStatus("IN_PROGRESS");
        order.setActualStartTime(LocalDateTime.now());
        orderMapper.updateById(order);
        
        // 4. 记录操作日志
        operationLogService.record("WORK_ORDER_START", orderId, 
            "工单开工,操作人:" + SecurityUtils.getUsername());
        
        // 5. 发送开工消息
        rocketMQTemplate.syncSend("MES:WORK_ORDER_START", order);
        
        // 6. 更新设备状态
        updateEquipmentStatus(order);
    }
    
    /**
     * 工单完工
     */
    public void completeWorkOrder(Long orderId, WorkOrderCompleteReq req) {
        ProductionOrder order = orderMapper.selectById(orderId);
        
        // 1. 使用分布式锁保证并发安全
        RLock lock = redissonClient.getLock("work_order:complete:" + orderId);
        try {
            if (lock.tryLock(10, TimeUnit.SECONDS)) {
                try {
                    // 2. 状态检查
                    if (!"IN_PROGRESS".equals(order.getStatus())) {
                        throw new BusinessException("工单状态不允许完工");
                    }
                    
                    // 3. 数量核对
                    if (req.getCompletedQuantity().compareTo(order.getQuantity()) > 0) {
                        throw new BusinessException("完工数量不能大于计划数量");
                    }
                    
                    // 4. 质量检查
                    if (!qualityCheckService.checkOrderQuality(orderId, req.getQualityData())) {
                        throw new BusinessException("质量检查不合格,无法完工");
                    }
                    
                    // 5. 更新工单状态
                    order.setStatus("COMPLETED");
                    order.setActualEndTime(LocalDateTime.now());
                    order.setCompletedQuantity(req.getCompletedQuantity());
                    order.setQualifiedQuantity(req.getQualifiedQuantity());
                    order.setDefectiveQuantity(req.getDefectiveQuantity());
                    order.setCompleteReason(req.getReason());
                    orderMapper.updateById(order);
                    
                    // 6. 库存更新
                    inventoryService.finishWorkOrder(order);
                    
                    // 7. 物料扣减
                    materialService.deductMaterial(order);
                    
                    // 8. 记录操作日志
                    operationLogService.record("WORK_ORDER_COMPLETE", orderId, 
                        "工单完工,操作人:" + SecurityUtils.getUsername());
                    
                    // 9. 发送完工消息
                    rocketMQTemplate.syncSend("MES:WORK_ORDER_COMPLETE", order);
                    
                } finally {
                    lock.unlock();
                }
            } else {
                throw new BusinessException("系统繁忙,请稍后重试");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new BusinessException("系统异常");
        }
    }
}

生产执行管理模块设计

工序作业管理

java 复制代码
@Service
public class ProcessOperationService {
    
    private final ProcessOperationMapper operationMapper;
    private final WorkStationService workStationService;
    private final EquipmentService equipmentService;
    private final RedissonClient redissonClient;
    
    /**
     * 工序开工
     */
    @Transactional(rollbackFor = Exception.class)
    public void startProcessOperation(ProcessOperationStartReq req) {
        // 1. 获取工序信息
        ProcessOperation operation = operationMapper.selectById(req.getOperationId());
        if (operation == null) {
            throw new BusinessException("工序不存在");
        }
        
        // 2. 状态检查
        if (!"PENDING".equals(operation.getStatus())) {
            throw new BusinessException("工序状态不允许开工");
        }
        
        // 3. 工位检查
        WorkStation station = workStationService.getById(req.getStationId());
        if (station == null || !"ACTIVE".equals(station.getStatus())) {
            throw new BusinessException("工位不可用");
        }
        
        // 4. 设备检查
        if (req.getEquipmentId() != null) {
            Equipment equipment = equipmentService.getById(req.getEquipmentId());
            if (equipment == null || !"RUNNING".equals(equipment.getStatus())) {
                throw new BusinessException("设备不可用");
            }
        }
        
        // 5. 人员资质检查
        if (!checkOperatorQualification(req.getOperatorId(), operation.getProcessId())) {
            throw new BusinessException("操作人员无此工序资质");
        }
        
        // 6. 更新工序状态
        operation.setStatus("IN_PROGRESS");
        operation.setStationId(req.getStationId());
        operation.setEquipmentId(req.getEquipmentId());
        operation.setOperatorId(req.getOperatorId());
        operation.setActualStartTime(LocalDateTime.now());
        operationMapper.updateById(operation);
        
        // 7. 记录工序开工事件
        recordOperationEvent(operation, "START");
        
        // 8. 更新工位状态
        workStationService.updateStatus(req.getStationId(), "BUSY");
    }
    
    /**
     * 工序报工
     */
    @Transactional(rollbackFor = Exception.class)
    public void reportProcessOperation(ProcessOperationReportReq req) {
        // 1. 获取工序信息
        ProcessOperation operation = operationMapper.selectById(req.getOperationId());
        if (operation == null) {
            throw new BusinessException("工序不存在");
        }
        
        // 2. 状态检查
        if (!"IN_PROGRESS".equals(operation.getStatus())) {
            throw new BusinessException("工序状态不允许报工");
        }
        
        // 3. 数量校验
        if (req.getReportedQuantity().compareTo(BigDecimal.ZERO) <= 0) {
            throw new BusinessException("报工数量必须大于零");
        }
        
        // 4. 使用分布式锁防止重复报工
        RLock lock = redissonClient.getLock("process:report:" + req.getOperationId());
        try {
            if (lock.tryLock(5, TimeUnit.SECONDS)) {
                try {
                    // 5. 创建报工记录
                    ProcessReport report = new ProcessReport();
                    report.setOperationId(req.getOperationId());
                    report.setOrderId(operation.getOrderId());
                    report.setProcessId(operation.getProcessId());
                    report.setReportedQuantity(req.getReportedQuantity());
                    report.setQualifiedQuantity(req.getQualifiedQuantity());
                    report.setDefectiveQuantity(req.getDefectiveQuantity());
                    report.setOperatorId(req.getOperatorId());
                    report.setReportTime(LocalDateTime.now());
                    report.setRemark(req.getRemark());
                    
                    processReportMapper.insert(report);
                    
                    // 6. 更新工序累计数量
                    operation.setReportedQuantity(operation.getReportedQuantity()
                        .add(req.getReportedQuantity()));
                    operation.setQualifiedQuantity(operation.getQualifiedQuantity()
                        .add(req.getQualifiedQuantity()));
                    operation.setDefectiveQuantity(operation.getDefectiveQuantity()
                        .add(req.getDefectiveQuantity()));
                    
                    // 7. 检查工序是否完成
                    if (operation.getReportedQuantity().compareTo(operation.getPlanQuantity()) >= 0) {
                        operation.setStatus("COMPLETED");
                        operation.setActualEndTime(LocalDateTime.now());
                        
                        // 释放工位
                        workStationService.updateStatus(operation.getStationId(), "IDLE");
                    }
                    
                    operationMapper.updateById(operation);
                    
                    // 8. 记录报工事件
                    recordOperationEvent(operation, "REPORT");
                    
                    // 9. 触发下游工序检查
                    checkNextOperation(operation);
                    
                } finally {
                    lock.unlock();
                }
            } else {
                throw new BusinessException("系统繁忙,请稍后重试");
            }
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
            throw new BusinessException("系统异常");
        }
    }
    
    /**
     * 工序暂停/恢复
     */
    public void pauseProcessOperation(Long operationId, boolean pause) {
        ProcessOperation operation = operationMapper.selectById(operationId);
        if (operation == null) {
            throw new BusinessException("工序不存在");
        }
        
        if ("IN_PROGRESS".equals(operation.getStatus())) {
            operation.setStatus(pause ? "PAUSED" : "IN_PROGRESS");
            operationMapper.updateById(operation);
            
            // 记录暂停/恢复事件
            recordOperationEvent(operation, pause ? "PAUSE" : "RESUME");
        } else {
            throw new BusinessException("工序状态不允许此操作");
        }
    }
}

质量管理模块设计

质量检验管理

java 复制代码
@Service
public class QualityInspectionService {
    
    private final QualityInspectionMapper inspectionMapper;
    private final InspectionStandardService standardService;
    private final InspectionTaskService taskService;
    
    /**
     * 创建检验任务
     */
    @Transactional(rollbackFor = Exception.class)
    public Long createInspectionTask(InspectionTaskCreateReq req) {
        // 1. 获取检验标准
        InspectionStandard standard = standardService.getById(req.getStandardId());
        if (standard == null) {
            throw new BusinessException("检验标准不存在");
        }
        
        // 2. 生成检验任务
        InspectionTask task = new InspectionTask();
        task.setTaskNo(generateTaskNo());
        task.setStandardId(req.getStandardId());
        task.setOrderId(req.getOrderId());
        task.setBatchNo(req.getBatchNo());
        task.setSampleType(req.getSampleType());
        task.setSampleQuantity(req.getSampleQuantity());
        task.setStatus("PENDING");
        task.setPlanTime(LocalDateTime.now().plusHours(standard.getResponseTime()));
        task.setCreateTime(LocalDateTime.now());
        
        inspectionMapper.insert(task);
        
        // 3. 生成检验项目
        generateInspectionItems(task, standard);
        
        // 4. 分配检验员
        assignInspector(task);
        
        return task.getId();
    }
    
    /**
     * 执行质量检验
     */
    @Transactional(rollbackFor = Exception.class)
    public void executeInspection(InspectionExecuteReq req) {
        // 1. 获取检验任务
        InspectionTask task = inspectionMapper.selectById(req.getTaskId());
        if (task == null) {
            throw new BusinessException("检验任务不存在");
        }
        
        // 2. 状态检查
        if (!"ASSIGNED".equals(task.getStatus())) {
            throw new BusinessException("检验任务状态不允许执行");
        }
        
        // 3. 获取检验项目
        List<InspectionItem> items = inspectionItemMapper.selectByTaskId(req.getTaskId());
        
        // 4. 处理检验结果
        boolean allPassed = true;
        for (InspectionItemResult result : req.getResults()) {
            InspectionItem item = findItem(items, result.getItemId());
            if (item == null) {
                continue;
            }
            
            // 判断是否合格
            boolean passed = judgeItemResult(item, result);
            
            // 保存检验结果
            InspectionItemRecord record = new InspectionItemRecord();
            record.setTaskId(req.getTaskId());
            record.setItemId(result.getItemId());
            record.setInspectionValue(result.getValue());
            record.setPassed(passed);
            record.setInspectorId(req.getInspectorId());
            record.setInspectionTime(LocalDateTime.now());
            record.setRemark(result.getRemark());
            
            inspectionItemRecordMapper.insert(record);
            
            if (!passed) {
                allPassed = false;
            }
        }
        
        // 5. 更新任务状态
        task.setStatus("COMPLETED");
        task.setInspectorId(req.getInspectorId());
        task.setInspectionTime(LocalDateTime.now());
        task.setResult(allPassed ? "PASSED" : "FAILED");
        task.setRemark(req.getRemark());
        inspectionMapper.updateById(task);
        
        // 6. 处理不合格品
        if (!allPassed) {
            handleDefectiveProduct(task);
        }
    }
    
    /**
     * 判断检验项结果
     */
    private boolean judgeItemResult(InspectionItem item, InspectionItemResult result) {
        switch (item.getJudgeType()) {
            case "VALUE":
                // 数值判断
                return judgeValueResult(item, result.getValue());
            case "VISUAL":
                // 目视判断
                return "PASS".equalsIgnoreCase(result.getValue());
            case "FUNCTIONAL":
                // 功能测试判断
                return judgeFunctionalResult(item, result);
            default:
                return true;
        }
    }
    
    /**
     * 数值判断
     */
    private boolean judgeValueResult(InspectionItem item, String valueStr) {
        try {
            double value = Double.parseDouble(valueStr);
            
            // 获取检验规格
            InspectionSpec spec = item.getSpec();
            if (spec == null) {
                return true;
            }
            
            // 判断是否在规格范围内
            switch (spec.getSpecType()) {
                case "RANGE":
                    return value >= spec.getMinValue() && value <= spec.getMaxValue();
                case "MAX":
                    return value <= spec.getMaxValue();
                case "MIN":
                    return value >= spec.getMinValue();
                case "TARGET":
                    double tolerance = spec.getTolerance();
                    double target = spec.getTargetValue();
                    return Math.abs(value - target) <= tolerance;
                default:
                    return true;
            }
        } catch (NumberFormatException e) {
            return false;
        }
    }
    
    /**
     * 处理不合格品
     */
    private void handleDefectiveProduct(InspectionTask task) {
        // 1. 创建不合格品记录
        DefectiveProduct defective = new DefectiveProduct();
        defective.setTaskId(task.getId());
        defective.setOrderId(task.getOrderId());
        defective.setBatchNo(task.getBatchNo());
        defective.setDefectType("QUALITY");
        defective.setStatus("PENDING");
        defective.setCreateTime(LocalDateTime.now());
        
        defectiveProductMapper.insert(defective);
        
        // 2. 发起不合格品处理流程
        startDefectiveHandlingProcess(defective);
        
        // 3. 发送告警通知
        sendDefectiveAlarm(defective);
    }
}

设备管理模块设计

设备监控与状态管理

java 复制代码
@Service
public class EquipmentMonitorService {
    
    private final EquipmentMapper equipmentMapper;
    private final EquipmentStatusCache statusCache;
    private final RedissonClient redissonClient;
    private final TDengineTemplate tdengineTemplate;
    
    /**
     * 更新设备状态
     */
    public void updateEquipmentStatus(String equipmentCode, EquipmentStatus status) {
        // 1. 更新 Redis 缓存
        String cacheKey = "equipment:status:" + equipmentCode;
        RBucket<String> bucket = redissonClient.getBucket(cacheKey);
        bucket.set(status.name(), 30, TimeUnit.MINUTES);
        
        // 2. 更新数据库
        equipmentMapper.updateStatus(equipmentCode, status.name());
        
        // 3. 记录状态变更日志
        recordStatusChange(equipmentCode, status);
        
        // 4. 发布状态变更事件
        publishStatusChangeEvent(equipmentCode, status);
    }
    
    /**
     * 采集设备实时数据
     */
    @Async
    public void collectEquipmentData(EquipmentData data) {
        // 1. 数据校验
        if (!validateEquipmentData(data)) {
            return;
        }
        
        // 2. 写入时序数据库
        String sql = String.format(
            "INSERT INTO %s USING equipment_data TAGS (?,?) VALUES (?,?,?)",
            "eq_" + data.getEquipmentCode()
        );
        
        tdengineTemplate.update(sql, 
            data.getEquipmentCode(),
            data.getEquipmentType(),
            data.getTimestamp(),
            data.getDataKey(),
            data.getDataValue()
        );
        
        // 3. 更新实时数据缓存
        updateRealtimeDataCache(data);
        
        // 4. 检查告警阈值
        checkAlarmThreshold(data);
    }
    
    /**
     * 检查告警阈值
     */
    private void checkAlarmThreshold(EquipmentData data) {
        // 1. 获取告警规则
        List<AlarmRule> rules = alarmRuleMapper.selectByEquipmentCode(
            data.getEquipmentCode(), data.getDataKey()
        );
        
        // 2. 检查是否触发告警
        for (AlarmRule rule : rules) {
            if (checkRuleTriggered(rule, data)) {
                // 创建告警
                createAlarm(rule, data);
            }
        }
    }
    
    /**
     * 检查规则是否触发
     */
    private boolean checkRuleTriggered(AlarmRule rule, EquipmentData data) {
        try {
            double value = Double.parseDouble(data.getDataValue());
            
            switch (rule.getCompareType()) {
                case "GT":
                    return value > rule.getThreshold();
                case "LT":
                    return value < rule.getThreshold();
                case "GTE":
                    return value >= rule.getThreshold();
                case "LTE":
                    return value <= rule.getThreshold();
                case "EQ":
                    return value == rule.getThreshold();
                case "NE":
                    return value != rule.getThreshold();
                default:
                    return false;
            }
        } catch (NumberFormatException e) {
            return false;
        }
    }
    
    /**
     * 设备 OEE 计算
     */
    public OEEResult calculateOEE(String equipmentCode, LocalDateTime start, LocalDateTime end) {
        // 1. 获取计划生产时间
        long plannedTime = getPlannedProductionTime(equipmentCode, start, end);
        
        // 2. 获取实际运行时间
        long actualTime = getActualRunningTime(equipmentCode, start, end);
        
        // 3. 计算可用率
        double availabilityRate = plannedTime > 0 ? (double) actualTime / plannedTime : 0;
        
        // 4. 获取标准产量和实际产量
        long standardOutput = getStandardOutput(equipmentCode, start, end);
        long actualOutput = getActualOutput(equipmentCode, start, end);
        
        // 5. 计算性能率
        double performanceRate = plannedTime > 0 ? 
            (double) actualOutput / standardOutput : 0;
        
        // 6. 获取合格品数量和总数量
        long qualifiedCount = getQualifiedCount(equipmentCode, start, end);
        long totalCount = getTotalCount(equipmentCode, start, end);
        
        // 7. 计算质量率
        double qualityRate = totalCount > 0 ? (double) qualifiedCount / totalCount : 0;
        
        // 8. 计算 OEE
        double oee = availabilityRate * performanceRate * qualityRate;
        
        // 9. 构建结果
        OEEResult result = new OEEResult();
        result.setEquipmentCode(equipmentCode);
        result.setStartTime(start);
        result.setEndTime(end);
        result.setAvailabilityRate(availabilityRate);
        result.setPerformanceRate(performanceRate);
        result.setQualityRate(qualityRate);
        result.setOee(oee);
        
        return result;
    }
}

数据采集与实时监控

基于 XXL-Job 的定时数据采集

java 复制代码
@Component
@JobHandler(name = "mesDataCollectionJob")
public class MESDataCollectionJob extends IJobHandler {
    
    @Autowired
    private DataCollectionService dataCollectionService;
    
    @Override
    public void execute() throws Exception {
        // 1. 获取所有激活的数据采集任务
        List<DataCollectionTask> tasks = dataCollectionService.getActiveTasks();
        
        // 2. 并行执行采集任务
        tasks.parallelStream().forEach(task -> {
            try {
                dataCollectionService.executeTask(task);
            } catch (Exception e) {
                log.error("数据采集任务执行失败: {}", task, e);
            }
        });
    }
}

实时数据监控大屏

java 复制代码
@RestController
@RequestMapping("/mes/monitor")
public class MESMonitorController {
    
    @Autowired
    private ProductionMonitorService productionMonitorService;
    
    /**
     * 获取生产实时数据
     */
    @GetMapping("/production/realtime")
    public CommonResult<ProductionRealtimeData> getProductionRealtime(
        @RequestParam Long lineId) {
        ProductionRealtimeData data = productionMonitorService
            .getRealtimeData(lineId);
        return CommonResult.success(data);
    }
    
    /**
     * 获取设备运行状态
     */
    @GetMapping("/equipment/status")
    public CommonResult<List<EquipmentStatusData>> getEquipmentStatus(
        @RequestParam(required = false) String lineId) {
        List<EquipmentStatusData> data = productionMonitorService
            .getEquipmentStatus(lineId);
        return CommonResult.success(data);
    }
    
    /**
     * 获取生产计划完成情况
     */
    @GetMapping("/plan/progress")
    public CommonResult<List<PlanProgressData>> getPlanProgress(
        @RequestParam String date) {
        List<PlanProgressData> data = productionMonitorService
            .getPlanProgress(date);
        return CommonResult.success(data);
    }
    
    /**
     * 获取质量统计信息
     */
    @GetMapping("/quality/statistics")
    public CommonResult<QualityStatisticsData> getQualityStatistics(
        @RequestParam String date,
        @RequestParam(required = false) String lineId) {
        QualityStatisticsData data = productionMonitorService
            .getQualityStatistics(date, lineId);
        return CommonResult.success(data);
    }
}

总结

本文介绍了基于 Spring Cloud 微服务架构构建企业级 MES 系统的设计与实现。通过生产计划管理、生产执行管理、质量管理、设备管理等核心模块的设计,展示了如何构建一个完整的制造执行系统。

关键技术要点:

  1. 微服务架构: 基于 Spring Cloud 实现服务拆分与治理
  2. 工作流引擎: 使用 Flowable 实现复杂的业务流程管理
  3. 分布式调度: 使用 XXL-Job 实现定时任务调度
  4. 消息驱动: 使用 RocketMQ 实现服务间异步通信
  5. 时序数据存储: 使用 TDengine 处理海量设备数据
  6. 分布式协调: 使用 Redisson 实现分布式锁和缓存
  7. 数据权限: 基于多租户和数据权限实现数据隔离
相关推荐
zzqssliu5 小时前
基于策略模式与责任链的代购商品多源采集架构实战
架构·策略模式
龙智DevSecOps解决方案8 小时前
3A 游戏优化技术栈:如何打通引擎级分析工具与 DevOps 持续集成管线?
unity·性能优化·游戏开发·技术美术·perforce·unrealengine
大熊猫侯佩8 小时前
WWDC26:SwiftUI 8 的 @State 全新“懒加载”机制与最佳实践
性能优化·swiftui·observable·懒加载·state·swift宏·实例初始化
韩小兔修媛史8 小时前
SpringCloud八股文面试
spring·spring cloud·面试
shushangyun_9 小时前
批发商城系统源码多少钱?2026最新报价一览
java·开发语言·人工智能·spring·spring cloud
@insist1239 小时前
系统架构设计师-计算机网络基础体系全梳理
计算机网络·系统架构·软考·系统架构设计师·软件水平考试
山东点狮信息科技有限公司9 小时前
点狮OA-企业级 OA 办公自动化系统架构设计与实践
spring cloud·微服务·性能优化·架构·系统架构
taocarts_bidfans9 小时前
反向海淘系统架构设计与 taocarts 分层实践
系统架构·反向海淘·taocarts
swordbob9 小时前
Nacos vs Eureka
spring cloud·云原生·eureka