package com.mes.interaction.workstation.scanner.handler; import com.mes.device.entity.DeviceConfig; import com.mes.device.entity.GlassInfo; import com.mes.device.service.DevicePlcOperationService; import com.mes.device.service.GlassInfoService; import com.mes.device.vo.DevicePlcVO; import com.mes.interaction.workstation.base.WorkstationBaseHandler; import com.mes.interaction.workstation.config.WorkstationLogicConfig; import com.mes.s7.enhanced.EnhancedS7Serializer; import com.mes.s7.provider.S7SerializerProvider; import com.mes.service.PlcDynamicDataService; import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Component; import org.springframework.util.StringUtils; import java.time.LocalDateTime; import java.util.Arrays; import java.util.List; import java.util.Map; /** * 卧转立扫码设备逻辑处理器 * 负责从MES写区读取玻璃尺寸,并落库 glass_info */ @Slf4j @Component public class HorizontalScannerLogicHandler extends WorkstationBaseHandler { private static final List MES_FIELDS = Arrays.asList("mesSend", "mesGlassId", "mesWidth", "mesHeight", "workLine"); private final PlcDynamicDataService plcDynamicDataService; private final GlassInfoService glassInfoService; private final S7SerializerProvider s7SerializerProvider; public HorizontalScannerLogicHandler(DevicePlcOperationService devicePlcOperationService, PlcDynamicDataService plcDynamicDataService, GlassInfoService glassInfoService, S7SerializerProvider s7SerializerProvider) { super(devicePlcOperationService); this.plcDynamicDataService = plcDynamicDataService; this.glassInfoService = glassInfoService; this.s7SerializerProvider = s7SerializerProvider; } @Override public String getDeviceType() { return DeviceConfig.DeviceType.WORKSTATION_SCANNER; } @Override protected DevicePlcVO.OperationResult doExecute(DeviceConfig deviceConfig, String operation, Map params, Map logicParams) { WorkstationLogicConfig config = parseWorkstationConfig(logicParams); EnhancedS7Serializer serializer = s7SerializerProvider.getSerializer(deviceConfig); if (serializer == null) { return buildResult(deviceConfig, operation, false, "获取PLC序列化器失败"); } try { log.debug("卧转立扫码读取MES写区: deviceId={}, scanInterval={}ms", deviceConfig.getId(), config.getScanIntervalMs()); Map mesData = plcDynamicDataService.readPlcData(deviceConfig, MES_FIELDS, serializer); if (mesData == null || mesData.isEmpty()) { return buildResult(deviceConfig, operation, false, "读取MES写区失败"); } Integer mesSend = parseInteger(mesData.get("mesSend")); if (mesSend == null || mesSend == 0) { return buildResult(deviceConfig, operation, true, "暂无待处理的玻璃信息"); } String glassId = parseString(mesData.get("mesGlassId")); if (!StringUtils.hasText(glassId)) { return buildResult(deviceConfig, operation, false, "MES写区未提供玻璃ID"); } Integer longSide = convertDimension(parseInteger(mesData.get("mesWidth"))); Integer shortSide = convertDimension(parseInteger(mesData.get("mesHeight"))); Integer workLine = parseInteger(mesData.get("workLine")); GlassInfo glassInfo = buildGlassInfo(glassId, longSide, shortSide, workLine); boolean saved = glassInfoService.saveOrUpdateGlassInfo(glassInfo); if (!saved) { return buildResult(deviceConfig, operation, false, "保存玻璃信息失败: " + glassId); } // 读取到MES数据后,重置mesSend,避免重复消费 plcDynamicDataService.writePlcField(deviceConfig, "mesSend", 0, serializer); String msg = String.format("玻璃[%s] 尺寸[%s x %s] 已接收并入库,workLine=%s", glassId, longSide != null ? longSide + "mm" : "-", shortSide != null ? shortSide + "mm" : "-", workLine != null ? workLine : "-"); return buildResult(deviceConfig, operation, true, msg); } catch (Exception e) { log.error("卧转立扫码处理异常, deviceId={}", deviceConfig.getId(), e); return buildResult(deviceConfig, operation, false, "处理异常: " + e.getMessage()); } } private GlassInfo buildGlassInfo(String glassId, Integer longSide, Integer shortSide, Integer workLine) { GlassInfo glassInfo = new GlassInfo(); glassInfo.setGlassId(glassId.trim()); if (longSide != null) { glassInfo.setGlassLength(longSide); } if (shortSide != null) { glassInfo.setGlassWidth(shortSide); } glassInfo.setStatus(GlassInfo.Status.ACTIVE); if (workLine != null) { glassInfo.setDescription("workLine=" + workLine); } return glassInfo; } private Integer parseInteger(Object value) { if (value instanceof Number) { return ((Number) value).intValue(); } if (value == null) { return null; } try { return Integer.parseInt(String.valueOf(value)); } catch (NumberFormatException e) { return null; } } private String parseString(Object value) { return value == null ? null : String.valueOf(value).trim(); } private Integer convertDimension(Integer raw) { if (raw == null) { return null; } return raw / 10; } private DevicePlcVO.OperationResult buildResult(DeviceConfig deviceConfig, String operation, boolean success, String message) { return DevicePlcVO.OperationResult.builder() .deviceId(deviceConfig.getId()) .deviceName(deviceConfig.getDeviceName()) .deviceCode(deviceConfig.getDeviceCode()) .projectId(deviceConfig.getProjectId() != null ? String.valueOf(deviceConfig.getProjectId()) : null) .operation(operation) .success(success) .message(message) .timestamp(LocalDateTime.now()) .build(); } }