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
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
package com.mes.interaction.largeglass.handler;
 
import com.mes.device.entity.DeviceConfig;
import com.mes.device.vo.DevicePlcVO;
import com.mes.interaction.BaseDeviceLogicHandler;
import com.mes.device.service.DevicePlcOperationService;
import com.mes.interaction.largeglass.config.LargeGlassConfig;
import com.mes.interaction.largeglass.model.GridRange;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
 
import java.time.LocalDateTime;
import java.util.*;
 
/**
 * 大理片笼设备逻辑处理器
 * 负责格子范围配置、每格尺寸配置、逻辑判断等
 * 不涉及PLC写入操作,只用于逻辑判断和配置管理
 */
@Slf4j
@Component
public class LargeGlassLogicHandler extends BaseDeviceLogicHandler {
 
    public LargeGlassLogicHandler(DevicePlcOperationService devicePlcOperationService) {
        super(devicePlcOperationService);
    }
 
    @Override
    public String getDeviceType() {
        return DeviceConfig.DeviceType.LARGE_GLASS;
    }
 
    @Override
    protected DevicePlcVO.OperationResult doExecute(DeviceConfig deviceConfig,
                                                    String operation,
                                                    Map<String, Object> params,
                                                    Map<String, Object> logicParams) {
        try {
            LargeGlassConfig config = parseLargeGlassConfig(logicParams);
            
            switch (operation) {
                case "checkGrid":
                case "validateGrid":
                    return handleCheckGrid(deviceConfig, params, config);
                case "getGridInfo":
                    return handleGetGridInfo(deviceConfig, params, config);
                case "findAvailableGrid":
                    return handleFindAvailableGrid(deviceConfig, params, config);
                case "getGridPosition":
                    return handleGetGridPosition(deviceConfig, params, config);
                default:
                    return buildResult(deviceConfig, operation, false, 
                            "不支持的操作: " + operation);
            }
        } catch (Exception e) {
            log.error("大理片笼处理异常: deviceId={}, operation={}", 
                    deviceConfig.getId(), operation, e);
            return buildResult(deviceConfig, operation, false, 
                    "处理异常: " + e.getMessage());
        }
    }
 
    /**
     * 检查格子是否有效
     */
    private DevicePlcVO.OperationResult handleCheckGrid(
            DeviceConfig deviceConfig,
            Map<String, Object> params,
            LargeGlassConfig config) {
        
        Integer gridNumber = getIntegerParam(params, "gridNumber");
        if (gridNumber == null) {
            return buildResult(deviceConfig, "checkGrid", false, 
                    "未提供格子编号");
        }
        
        GridRange gridRange = findGridRange(gridNumber, config);
        if (gridRange == null) {
            return buildResult(deviceConfig, "checkGrid", false, 
                    String.format("格子编号 %d 不在配置范围内", gridNumber));
        }
        
        return buildResult(deviceConfig, "checkGrid", true, 
                String.format("格子编号 %d 有效,位于第 %d 行,范围 %d~%d", 
                        gridNumber, gridRange.getRow(), gridRange.getStart(), gridRange.getEnd()));
    }
 
    /**
     * 获取格子信息
     */
    private DevicePlcVO.OperationResult handleGetGridInfo(
            DeviceConfig deviceConfig,
            Map<String, Object> params,
            LargeGlassConfig config) {
        
        Integer gridNumber = getIntegerParam(params, "gridNumber");
        if (gridNumber == null) {
            return buildResult(deviceConfig, "getGridInfo", false, 
                    "未提供格子编号");
        }
        
        GridRange gridRange = findGridRange(gridNumber, config);
        if (gridRange == null) {
            return buildResult(deviceConfig, "getGridInfo", false, 
                    String.format("格子编号 %d 不在配置范围内", gridNumber));
        }
        
        Map<String, Object> gridInfo = new HashMap<>();
        gridInfo.put("gridNumber", gridNumber);
        gridInfo.put("row", gridRange.getRow());
        gridInfo.put("start", gridRange.getStart());
        gridInfo.put("end", gridRange.getEnd());
        gridInfo.put("length", config.getGridLength());
        gridInfo.put("width", config.getGridWidth());
        gridInfo.put("thickness", config.getGridThickness());
        
        return buildResult(deviceConfig, "getGridInfo", true, 
                "格子信息获取成功", gridInfo);
    }
 
    /**
     * 查找可用格子
     */
    private DevicePlcVO.OperationResult handleFindAvailableGrid(
            DeviceConfig deviceConfig,
            Map<String, Object> params,
            LargeGlassConfig config) {
        
        // 这里可以根据实际需求实现查找逻辑
        // 例如:查找第一个可用格子、查找指定行可用格子等
        
        List<GridRange> gridRanges = config.getGridRanges();
        if (gridRanges == null || gridRanges.isEmpty()) {
            return buildResult(deviceConfig, "findAvailableGrid", false, 
                    "未配置格子范围");
        }
        
        // 简单实现:返回第一个格子的起始位置
        GridRange firstRange = gridRanges.get(0);
        Integer availableGrid = firstRange.getStart();
        
        Map<String, Object> result = new HashMap<>();
        result.put("availableGrid", availableGrid);
        result.put("row", firstRange.getRow());
        
        return buildResult(deviceConfig, "findAvailableGrid", true, 
                String.format("找到可用格子: %d", availableGrid), result);
    }
 
    /**
     * 根据目标位置获取格子编号
     */
    private DevicePlcVO.OperationResult handleGetGridPosition(
            DeviceConfig deviceConfig,
            Map<String, Object> params,
            LargeGlassConfig config) {
        
        Integer targetPosition = getIntegerParam(params, "targetPosition");
        if (targetPosition == null) {
            return buildResult(deviceConfig, "getGridPosition", false, 
                    "未提供目标位置");
        }
        
        // 查找目标位置在哪个格子范围内
        GridRange gridRange = findGridRangeByPosition(targetPosition, config);
        if (gridRange == null) {
            return buildResult(deviceConfig, "getGridPosition", false, 
                    String.format("目标位置 %d 不在任何格子范围内", targetPosition));
        }
        
        // 计算格子编号(假设位置就是格子编号,或根据实际规则计算)
        Integer gridNumber = targetPosition;
        
        Map<String, Object> result = new HashMap<>();
        result.put("gridNumber", gridNumber);
        result.put("row", gridRange.getRow());
        result.put("position", targetPosition);
        
        return buildResult(deviceConfig, "getGridPosition", true, 
                String.format("目标位置 %d 对应格子编号 %d,第 %d 行", 
                        targetPosition, gridNumber, gridRange.getRow()), result);
    }
 
    /**
     * 解析大理片笼配置
     */
    private LargeGlassConfig parseLargeGlassConfig(Map<String, Object> logicParams) {
        LargeGlassConfig config = new LargeGlassConfig();
        
        if (logicParams == null) {
            return config;
        }
        
        // 解析格子范围配置
        @SuppressWarnings("unchecked")
        List<Map<String, Object>> gridRangesConfig = 
                (List<Map<String, Object>>) logicParams.get("gridRanges");
        
        if (gridRangesConfig != null) {
            List<GridRange> gridRanges = new ArrayList<>();
            for (Map<String, Object> rangeConfig : gridRangesConfig) {
                Integer row = getIntegerValue(rangeConfig.get("row"));
                Integer start = getIntegerValue(rangeConfig.get("start"));
                Integer end = getIntegerValue(rangeConfig.get("end"));
                
                if (row != null && start != null && end != null) {
                    gridRanges.add(new GridRange(row, start, end));
                }
            }
            config.setGridRanges(gridRanges);
        }
        
        // 解析每格尺寸
        config.setGridLength(getLogicParam(logicParams, "gridLength", 2000)); // 默认2000mm
        config.setGridWidth(getLogicParam(logicParams, "gridWidth", 1500));  // 默认1500mm
        config.setGridThickness(getLogicParam(logicParams, "gridThickness", 5)); // 默认5mm
        
        return config;
    }
 
    /**
     * 查找格子所在的格子范围
     */
    private GridRange findGridRange(Integer gridNumber, LargeGlassConfig config) {
        List<GridRange> gridRanges = config.getGridRanges();
        if (gridRanges == null) {
            return null;
        }
        
        for (GridRange range : gridRanges) {
            if (gridNumber >= range.getStart() && gridNumber <= range.getEnd()) {
                return range;
            }
        }
        
        return null;
    }
 
    /**
     * 根据位置查找格子范围
     */
    private GridRange findGridRangeByPosition(Integer position, LargeGlassConfig config) {
        List<GridRange> gridRanges = config.getGridRanges();
        if (gridRanges == null) {
            return null;
        }
        
        for (GridRange range : gridRanges) {
            if (position >= range.getStart() && position <= range.getEnd()) {
                return range;
            }
        }
        
        return null;
    }
 
    /**
     * 获取整数参数
     */
    private Integer getIntegerParam(Map<String, Object> params, String key) {
        if (params == null) {
            return null;
        }
        return getIntegerValue(params.get(key));
    }
 
    /**
     * 获取整数值
     */
    private Integer getIntegerValue(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 DevicePlcVO.OperationResult buildResult(DeviceConfig deviceConfig,
                                                    String operation,
                                                    boolean success,
                                                    String message) {
        return buildResult(deviceConfig, operation, success, message, null);
    }
 
    /**
     * 构建操作结果(带数据)
     */
    private DevicePlcVO.OperationResult buildResult(DeviceConfig deviceConfig,
                                                    String operation,
                                                    boolean success,
                                                    String message,
                                                    Map<String, Object> data) {
        DevicePlcVO.OperationResult.OperationResultBuilder builder = 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());
        
        if (data != null) {
            builder.data(data);
        }
        
        return builder.build();
    }
 
    @Override
    public String validateLogicParams(DeviceConfig deviceConfig) {
        Map<String, Object> logicParams = parseLogicParams(deviceConfig);
        LargeGlassConfig config = parseLargeGlassConfig(logicParams);
        
        // 验证格子范围配置
        List<GridRange> gridRanges = config.getGridRanges();
        if (gridRanges == null || gridRanges.isEmpty()) {
            return "必须配置至少一个格子范围(gridRanges)";
        }
        
        // 验证每格尺寸
        if (config.getGridLength() == null || config.getGridLength() <= 0) {
            return "格子长度(gridLength)必须大于0";
        }
        if (config.getGridWidth() == null || config.getGridWidth() <= 0) {
            return "格子宽度(gridWidth)必须大于0";
        }
        if (config.getGridThickness() == null || config.getGridThickness() <= 0) {
            return "格子厚度(gridThickness)必须大于0";
        }
        
        return null; // 验证通过
    }
 
    @Override
    public String getDefaultLogicParams() {
        Map<String, Object> defaultParams = new HashMap<>();
        
        // 默认格子范围配置:第一行1~52格,第二行53~101格
        List<Map<String, Object>> gridRanges = new ArrayList<>();
        
        Map<String, Object> row1 = new HashMap<>();
        row1.put("row", 1);
        row1.put("start", 1);
        row1.put("end", 52);
        gridRanges.add(row1);
        
        Map<String, Object> row2 = new HashMap<>();
        row2.put("row", 2);
        row2.put("start", 53);
        row2.put("end", 101);
        gridRanges.add(row2);
        
        defaultParams.put("gridRanges", gridRanges);
        
        // 默认每格尺寸(mm)
        defaultParams.put("gridLength", 2000);   // 长度2000mm
        defaultParams.put("gridWidth", 1500);    // 宽度1500mm
        defaultParams.put("gridThickness", 5);   // 厚度5mm
        
        try {
            return objectMapper.writeValueAsString(defaultParams);
        } catch (Exception e) {
            log.error("生成默认逻辑参数失败", e);
            return "{}";
        }
    }
}