huang
2025-11-25 19f59c243e8df97c8b9fd9dba4e758be8235d68b
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
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<String> 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<String, Object> params,
                                                    Map<String, Object> 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<String, Object> 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();
    }
}