zhoushihao
2024-11-21 b4f51417997c20dd15e3db19d5055edd55d872cd
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
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
package com.mes.job;
 
import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.github.yulichang.toolkit.JoinWrappers;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.kangaroohy.milo.model.ReadWriteEntity;
import com.kangaroohy.milo.service.MiloService;
import com.mes.base.entity.BigStorageCageBaseInfo;
import com.mes.bigstorage.entity.BigStorageCage;
import com.mes.bigstorage.entity.BigStorageCageDetails;
import com.mes.bigstorage.entity.BigStorageDTO;
import com.mes.bigstorage.entity.dto.SlotSequenceDTO;
import com.mes.bigstorage.entity.dto.TemperingLayoutDTO;
import com.mes.bigstorage.service.BigStorageCageDetailsService;
import com.mes.bigstorage.service.BigStorageCageService;
import com.mes.bigstoragecagetask.entity.BigStorageCageHistoryTask;
import com.mes.bigstoragecagetask.entity.BigStorageCageTask;
import com.mes.bigstoragecagetask.service.BigStorageCageHistoryTaskService;
import com.mes.bigstoragecagetask.service.BigStorageCageTaskService;
import com.mes.bigstoragetask.entity.UpdateBigStorageCageDTO;
import com.mes.common.config.Const;
import com.mes.damage.entity.Damage;
import com.mes.damage.service.DamageService;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.hollow.service.BigStorageCageHollowService;
import com.mes.temperingglass.entity.TemperingGlass;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.service.TemperingGlassService;
import com.mes.utils.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
 
import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;
 
/**
 * @author SNG-015
 */
@Component
@Slf4j
public class OpcPlcStorageCageHollowTask {
    @Resource
    private BigStorageCageDetailsService bigStorageCageDetailsService;
 
    @Resource
    private BigStorageCageHollowDetailsService bigStorageCageHollowDetailsService;
    @Resource
    private TemperingGlassService temperingGlassService;
    @Resource
    private DamageService damageService;
    @Resource
    private GlassInfoService glassInfoService;
    @Resource
    private BigStorageCageService bigStorageCageService;
    @Resource
    private BigStorageCageHollowService bigStorageCageHollowService;
    @Resource
    private BigStorageCageHistoryTaskService bigStorageCageHistoryTaskService;
    @Resource
    private BigStorageCageTaskService bigStorageCageTaskService;
    @Autowired(required = false)
    MiloService miloService;
    @Resource
    private RedisUtil redisUtil;
 
    @Value("${mes.slotWidth}")
    private Integer slotWidth;
 
    @Value("${mes.glassGap}")
    private Integer glassGap;
 
    @Value("${mes.carWidth}")
    private Integer carWidth;
 
    @Value("${mes.outCarMaxSize}")
    private Integer outCarMaxSize;
 
    @Value("${mes.sequence.order}")
    private boolean sequenceOrder;
 
 
    public void inBigStorageTask() throws Exception {
        ReadWriteEntity inkageEntity = miloService.readFromOpcUa("DLP2A.DLP2A.mesControl");
        if (true != Boolean.parseBoolean(inkageEntity.getValue() + "")) {
            log.info("当前为非联机状态,结束进片任务");
            return;
        }
        ReadWriteEntity requestEntity = miloService.readFromOpcUa("DLP2A.DLP2A.RequestMes");
        if (!"1".equals(requestEntity.getValue() + "")) {
            log.info("当前未收到进片请求,结束进片任务");
            return;
        }
        ReadWriteEntity mesReplyEntity = miloService.readFromOpcUa("DLP2A.DLP2A.MesReply");
        if ("1".equals(mesReplyEntity.getValue() + "")) {
            log.info("有正在执行的任务,结束进片任务");
            return;
        }
        //获取进片任务表
        List<BigStorageCageTask> inTaskList = bigStorageCageTaskService.queryTaskMessage("big_storage_cage_in_two_task");
        if (CollectionUtils.isEmpty(inTaskList)) {
            log.info("当前大车无进片玻璃,结束进片任务");
        }
        List<String> glassIdList = inTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList());
        log.info("获取任务的玻璃id:{}", glassIdList);
        List<GlassInfo> glassInfoList = glassInfoService.list(new LambdaQueryWrapper<GlassInfo>().in(GlassInfo::getGlassId, glassIdList));
        Map<String, List<GlassInfo>> glassListMap = glassInfoList.stream().collect(Collectors.groupingBy(GlassInfo::getGlassId));
 
        //计算目标格子
        List<BigStorageCageHistoryTask> historyTasks = new ArrayList<>();
        for (BigStorageCageTask task : inTaskList) {
            GlassInfo info = glassListMap.get(task.getGlassId()).get(0);
            //获取目标格子信息
//            BigStorageDTO bigStorageDTO = bigStorageCageDetailsService.queryTargetSlotByTempering(info);
 
            BigStorageDTO bigStorageDTO = bigStorageCageHollowDetailsService.queryTargetSlotByHollow(info);
//            临时更新格子的剩余尺寸:防止相邻玻璃进同一格子造成剩余尺寸不足,玻璃越界的情况,任务完成后再次更新大理片笼表剩余宽度(按照笼内玻璃数量更新大理片笼剩余尺寸)
            bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>()
                    .set(BigStorageCage::getRemainWidth, bigStorageDTO.getWidth() - Math.max(info.getWidth(), info.getHeight()) - glassGap)
                    .eq(BigStorageCage::getSlot, bigStorageDTO.getSlot()));
            task.setTargetSlot(bigStorageDTO.getSlot());
            task.setGlassId(info.getGlassId());
            bigStorageCageTaskService.updateTaskMessage("big_storage_cage_in_two_task", task);
            //存放历史任务
            BigStorageCageHistoryTask historyTask = new BigStorageCageHistoryTask();
            BeanUtils.copyProperties(task, historyTask);
            historyTask.setTaskType(Const.BIG_STORAGE_BEFORE_IN);
            historyTask.setGlassCount(glassInfoList.size());
            historyTask.setTaskState(Const.ENGINEERING_NEW);
            historyTasks.add(historyTask);
            BigStorageCageDetails cageDetails = new BigStorageCageDetails();
            BeanUtils.copyProperties(info, cageDetails);
            cageDetails.setSlot(bigStorageDTO.getSlot());
            cageDetails.setState(Const.GLASS_STATE_NEW);
            cageDetails.setDeviceId(bigStorageDTO.getDeviceId());
            cageDetails.setGap(glassGap);
            cageDetails.setId(null);
            bigStorageCageDetailsService.save(cageDetails);
        }
        //历史数据入库
        bigStorageCageHistoryTaskService.saveBatch(historyTasks);
        //向opc发送启动信号
        miloService.writeToOpcWord(generateReadWriteEntity("DLP2A.DLP2A.MesReply", 1));
    }
 
    //@Scheduled(fixedDelay = 1000)
    public void outBigStorageTask() throws Exception {
        Date startDate = new Date();
        ReadWriteEntity inkageEntity = miloService.readFromOpcUa("DLP2B.DLP2B.mesControl");
        if (true != Boolean.parseBoolean(inkageEntity.getValue() + "")) {
            log.info("当前为非联机状态,结束进片任务");
            return;
        }
        ReadWriteEntity requestEntity = miloService.readFromOpcUa("DLP2B.DLP2B.RequestMes");
        if (!"1".equals(requestEntity.getValue() + "")) {
            log.info("当前未收到出片请求,结束出片任务");
            return;
        }
        //获取出片任务表
        List<BigStorageCageTask> outTaskList = bigStorageCageTaskService.queryTaskMessage("big_storage_cage_out_two_task");
        if (CollectionUtils.isNotEmpty(outTaskList)) {
            log.info("有正在执行的出片任务,结束本次出片任务");
            return;
        }
        //todo:是否允许钢化
        if (redisUtil.getCacheObject("temperingSwitch")) {
            //是否有正在钢化的玻璃:钢化小片表关联历史任务表,筛选未出笼的玻璃信息
            List<TemperingGlass> temperingGlassList = temperingGlassService.selectJoinList(TemperingGlass.class, new MPJLambdaWrapper<TemperingGlass>()
                    .selectAll(TemperingGlass.class)
                    .leftJoin(BigStorageCageHistoryTask.class, BigStorageCageHistoryTask::getGlassId, TemperingGlass::getGlassId)
                    .eq(TemperingGlass::getState, Const.TEMPERING_NEW)
                    .eq(BigStorageCageHistoryTask::getTaskType, Const.BIG_STORAGE_BEFORE_OUT)
                    .isNull(BigStorageCageHistoryTask::getGlassId)
                    .orderBy(Boolean.TRUE, sequenceOrder, TemperingGlass::getTemperingFeedSequence));
            //todo:历史任务表
            if (CollectionUtils.isNotEmpty(temperingGlassList)) {
                log.info("有正在出片的钢化任务");
                computeOutGlassInfo(temperingGlassList, "big_storage_cage_out_two_task", Const.TEMPERING_OUT_TARGET_POSITION, Const.GLASS_STATE_OUT_ING, Const.BIG_STORAGE_BEFORE_OUT);
                Date endDate = new Date();
                log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
                return;
            }
            //钢化优先:获取理片笼  玻璃小片  破损表 数量   判断笼内版图是否到齐
            List<TemperingLayoutDTO> temperingLayoutDTOList = bigStorageCageDetailsService.temperingIsAll();
            if (CollectionUtils.isNotEmpty(temperingLayoutDTOList)) {
                //玻璃到齐包括已出片的
                //到齐,将玻璃小片数据存入钢化小片表,逻辑生成出片任务  结束
                for (TemperingLayoutDTO item : temperingLayoutDTOList) {
//                    if (item.getEngineerId().equals(redisUtil.getCacheObject("temperingengineerId"))) {
                    List<TemperingGlass> temperingGlassInfos = glassInfoService.selectJoinList(TemperingGlass.class, JoinWrappers.lambda(GlassInfo.class)
                            .selectAll(GlassInfo.class)
                            .select("-1 as state")
                            .selectAs(BigStorageCageDetails::getSlot, TemperingGlassInfo::getSlot)
                            .innerJoin(BigStorageCageDetails.class, BigStorageCageDetails::getGlassId, GlassInfo::getGlassId)
                            .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                            .eq(GlassInfo::getTemperingLayoutId, item.getTemperingLayoutId())
                            .eq(GlassInfo::getEngineerId, item.getEngineerId())
                            .orderBy(Boolean.TRUE, sequenceOrder, GlassInfo::getTemperingFeedSequence));
                    if (CollectionUtils.isNotEmpty(temperingGlassInfos)) {
                        temperingGlassService.saveBatch(temperingGlassInfos);
                        computeOutGlassInfo(temperingGlassInfos, "big_storage_cage_out_two_task", Const.TEMPERING_OUT_TARGET_POSITION, Const.GLASS_STATE_OUT_ING, Const.BIG_STORAGE_BEFORE_OUT);
                        Date endDate = new Date();
                        log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
                        return;
                    }
//                    }
                }
            }
        }
        //是否有人工下片任务   有直接出
        List<BigStorageCageDetails> artificialList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_ARTIFICIAL)
                .orderByAsc(BigStorageCageDetails::getSlot)
                .orderByAsc(BigStorageCageDetails::getId));
        if (CollectionUtils.isNotEmpty(artificialList)) {
            computeOutGlassInfo(artificialList, "big_storage_cage_out_two_task", Const.ARTIFICIAL_OUT_TARGET_POSITION, Const.GLASS_STATE_OUT_ING, Const.BIG_STORAGE_BEFORE_OUT);
            Date endDate = new Date();
            log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
            return;
        }
        //是否存在需要内部调度的格子:执行内部调度任务
        List<TemperingLayoutDTO> temperingOccupySlotList = bigStorageCageDetailsService.queryTemperingOccupySlot();
        if (CollectionUtils.isNotEmpty(temperingOccupySlotList)) {
            loop:
            for (TemperingLayoutDTO temperingOccupySlot : temperingOccupySlotList) {
                List<SlotSequenceDTO> slotSequenceList = bigStorageCageDetailsService.queryGlassMaxAndMin(temperingOccupySlot.getEngineerId(), temperingOccupySlot.getTemperingLayoutId());
                for (int i = 0; i < slotSequenceList.size() - 1; i++) {
                    SlotSequenceDTO first = slotSequenceList.get(i);
                    SlotSequenceDTO second = slotSequenceList.get(i + 1);
                    int slotWidth = carWidth - first.getRemainWidth() - glassGap;
                    int totalCount = first.getGlassCount() + second.getGlassCount();
                    if (totalCount <= 6 && first.getMinSequence() == second.getMaxSequence() + 1
                            && second.getRemainWidth() > slotWidth && slotWidth >= 0) {
 
                        List<BigStorageCageDetails> list = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                                .eq(BigStorageCageDetails::getSlot, first.getSlot()).eq(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                                .orderBy(Boolean.TRUE, sequenceOrder, BigStorageCageDetails::getTemperingFeedSequence));
                        if (CollectionUtils.isNotEmpty(list)) {
                            computeOutGlassInfo(list, "big_storage_cage_out_two_task", second.getSlot(), Const.GLASS_STATE_SCHEDULE_ING, Const.BIG_STORAGE_BEFORE_DISPATCH);
                        }
                        updateSlotRemainBySlots(Arrays.asList(second.getSlot()));
                        break loop;
                    }
                }
            }
        }
        Date endDate = new Date();
        log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
        return;
    }
 
    //@Scheduled(fixedDelay = 1000)
    public void finishInBigStorageTask() throws Exception {
        ReadWriteEntity inkageEntity = miloService.readFromOpcUa("DLP2A.DLP2A.mesControl");
        if (true != Boolean.parseBoolean(inkageEntity.getValue() + "")) {
            log.info("当前为非联机状态,结束完成进片任务");
            return;
        }
        //获取进片任务表
        List<BigStorageCageTask> inTaskList = bigStorageCageTaskService.queryTaskMessage("big_storage_cage_in_two_task");
        if (CollectionUtils.isEmpty(inTaskList)) {
            log.info("当前大车无进片玻璃,结束完成进片任务");
            return;
        }
        List<BigStorageCageTask> unFinishTaskList = inTaskList.stream().filter(e -> e.getTaskState() <= 1 || e.getStartSlot() == 0).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(unFinishTaskList)) {
            log.info("存在未完成的玻璃信息,玻璃:{}", unFinishTaskList);
            return;
        }
        Map<Integer, List<BigStorageCageTask>> taskMap = inTaskList.stream().collect(Collectors.groupingBy(BigStorageCageTask::getTaskState));
        //按照任务状态修改大理片笼内的玻璃数据
//        重新计算大理片笼内的剩余尺寸
        taskMap.forEach((e1, v) -> {
            if (e1 == 2) {
                //进片完成
                log.info("3、获取进片已完成的玻璃信息id:{}", v);
                List<Integer> inSuccessGlassSlot = v.stream().map(BigStorageCageTask::getTargetSlot).collect(Collectors.toList());
                List<UpdateBigStorageCageDTO> storageCageDTOList = v.stream().map(e -> {
                    UpdateBigStorageCageDTO storageCageDTO = new UpdateBigStorageCageDTO();
                    BeanUtils.copyProperties(e, storageCageDTO);
                    return storageCageDTO;
                }).collect(Collectors.toList());
                bigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_IN);
                log.info("4、大理片笼进片状态已完成已完成的玻璃信息id:{}", v);
                updateSlotRemainBySlots(inSuccessGlassSlot);
            } else if (e1 == 3) {
                //破损处理
                dealDamageInTask(v);
            } else {
                //清空理片笼空数据
                noDealInTask(v);
            }
        });
        for (BigStorageCageTask item : inTaskList) {
            //更新历史任务表中的任务状态
            bigStorageCageHistoryTaskService.update(new LambdaUpdateWrapper<BigStorageCageHistoryTask>()
                    .set(BigStorageCageHistoryTask::getTaskState, item.getTaskState())
                    .eq(BigStorageCageHistoryTask::getTaskType, Const.BIG_STORAGE_BEFORE_IN)
                    .eq(BigStorageCageHistoryTask::getTargetSlot, item.getTargetSlot())
                    .eq(BigStorageCageHistoryTask::getGlassId, item.getGlassId()));
            item.setTargetSlot(0);
            //清空任务表数据
            bigStorageCageTaskService.updateTaskMessage("big_storage_cage_in_two_task", item);
        }
        //清空启动状态
        //向opc发送启动信号
        miloService.writeToOpcWord(generateReadWriteEntity("DLP2A.DLP2A.MesReply", 0));
    }
 
    //@Scheduled(fixedDelay = 1000)
    public void finishOutBigStorageTask() throws Exception {
        ReadWriteEntity inkageEntity = miloService.readFromOpcUa("DLP2B.DLP2B.mesControl");
        if (true != Boolean.parseBoolean(inkageEntity.getValue() + "")) {
            log.info("当前为非联机状态,结束完成出片任务");
            return;
        }
        //获取进片任务表
        List<BigStorageCageTask> outTaskList = bigStorageCageTaskService.queryTaskMessage("big_storage_cage_out_two_task");
        if (CollectionUtils.isEmpty(outTaskList)) {
            log.info("当前大车无进片玻璃,结束完成进片任务");
            return;
        }
        List<BigStorageCageTask> unFinishTaskList = outTaskList.stream().filter(e -> e.getTaskState() <= 1 || e.getStartSlot() == 0).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(unFinishTaskList)) {
            log.info("存在未完成的玻璃信息,玻璃:{}", unFinishTaskList);
            return;
        }
        Map<Integer, List<BigStorageCageTask>> taskMap = outTaskList.stream().collect(Collectors.groupingBy(BigStorageCageTask::getTaskState));
        int taskType = 0;
        if (Const.OUT_TARGET_POSITION_ALL.contains(outTaskList.get(0).getTargetSlot())) {
            taskType = Const.BIG_STORAGE_BEFORE_OUT;
        } else {
            taskType = Const.BIG_STORAGE_BEFORE_DISPATCH;
        }
        //按照任务状态修改大理片笼内的玻璃数据
//        重新计算大理片笼内的剩余尺寸
        Integer finalTaskType = taskType;
        taskMap.forEach((e1, v) -> {
            if (e1 == 2) {
                //进片完成
                log.info("3、获取进片已完成的玻璃信息id:{}", v);
                List<Integer> outSuccessGlassSlot = new ArrayList<>();
                if (finalTaskType.equals(Const.BIG_STORAGE_BEFORE_OUT)) {
                    outSuccessGlassSlot = v.stream().map(BigStorageCageTask::getStartSlot).collect(Collectors.toList());
                } else {
                    outSuccessGlassSlot = v.stream().map(BigStorageCageTask::getTargetSlot).collect(Collectors.toList());
                }
                List<UpdateBigStorageCageDTO> storageCageDTOList = v.stream().map(e -> {
                    UpdateBigStorageCageDTO storageCageDTO = new UpdateBigStorageCageDTO();
                    storageCageDTO.setGlassId(e.getGlassId());
                    if (finalTaskType.equals(Const.BIG_STORAGE_BEFORE_OUT)) {
                        storageCageDTO.setTargetSlot(e.getStartSlot());
                    } else {
                        storageCageDTO.setTargetSlot(e.getTargetSlot());
                    }
                    return storageCageDTO;
                }).collect(Collectors.toList());
                bigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_OUT);
                log.info("4、大理片笼进片状态已完成已完成的玻璃信息id:{}", v);
                updateSlotRemainBySlots(outSuccessGlassSlot);
            } else if (e1 == 3) {
                //破损处理
                dealDamageOutTask(v);
            } else {
                //清空理片笼空数据
                noDealOutTask(v);
            }
        });
        for (BigStorageCageTask item : outTaskList) {
            //更新历史任务表中的任务状态
            bigStorageCageHistoryTaskService.update(new LambdaUpdateWrapper<BigStorageCageHistoryTask>()
                    .set(BigStorageCageHistoryTask::getTaskState, item.getTaskState())
                    .eq(BigStorageCageHistoryTask::getTaskType, taskType)
                    .eq(BigStorageCageHistoryTask::getGlassId, item.getGlassId()));
        }
//       重置任务表数据
        bigStorageCageTaskService.updateOutTaskMessage("big_storage_cage_out_two_task");
        //清空启动状态
        //向opc发送启动信号
        miloService.writeToOpcWord(generateReadWriteEntity("DLP2B.DLP2B.MesReply", 0));
    }
 
    private void dealDamageInTask(List<BigStorageCageTask> damageTaskList) {
//        获取进片任务表中状态为破损的数据
        log.info("破损的玻璃信息有:{}", damageTaskList);
        //移除理片笼详情表任务执行过程中破损的玻璃
        bigStorageCageDetailsService.remove(new LambdaQueryWrapper<BigStorageCageDetails>()
                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_NEW)
                .in(BigStorageCageDetails::getGlassId, damageTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList())));
        //将破损信息新增入破损表
        List<Integer> slotList = new ArrayList<>();
        for (BigStorageCageTask item : damageTaskList) {
            Damage damage = new Damage();
            damage.setGlassId(item.getGlassId());
            damage.setLine(item.getStartSlot());
            damage.setWorkingProcedure("磨边");
            damage.setRemark("进笼前卧转立");
            damage.setStatus(1);
            damage.setType(item.getTaskState());
            damageService.insertDamage(damage);
            slotList.add(item.getTargetSlot());
        }
        //更新格子剩余宽度
        updateSlotRemainBySlots(slotList);
        log.info("进片任务-破损任务执行完成");
    }
 
    private void dealDamageOutTask(List<BigStorageCageTask> damageTaskList) {
//        获取进片任务表中状态为破损的数据
        log.info("破损的玻璃信息有:{}", damageTaskList);
        //移除理片笼详情表任务执行过程中破损的玻璃
        bigStorageCageDetailsService.remove(new LambdaQueryWrapper<BigStorageCageDetails>()
                .in(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL_ZERO)
                .in(BigStorageCageDetails::getGlassId, damageTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList())));
        //将破损信息新增入破损表
        List<Integer> slotList = new ArrayList<>();
        for (BigStorageCageTask item : damageTaskList) {
            Damage damage = new Damage();
            damage.setGlassId(item.getGlassId());
            damage.setLine(item.getStartSlot());
            damage.setWorkingProcedure("钢化前");
            damage.setRemark("进笼后卧转立");
            damage.setStatus(1);
            damage.setType(item.getTaskState());
            damageService.insertDamage(damage);
            slotList.add(item.getTargetSlot());
            slotList.add(item.getStartSlot());
        }
        //更新格子剩余宽度
        updateSlotRemainBySlots(slotList);
        log.info("出片任务-破损任务执行完成");
    }
 
    private void noDealInTask(List<BigStorageCageTask> noDealTaskList) {
//        获取进片任务表中状态为破损的数据
        log.info("破损的玻璃信息有:{}", noDealTaskList);
        //移除理片笼详情表未执行任务的空记录信息
        bigStorageCageDetailsService.remove(new LambdaQueryWrapper<BigStorageCageDetails>()
                .eq(BigStorageCageDetails::getState, Const.GLASS_STATE_NEW)
                .in(BigStorageCageDetails::getGlassId, noDealTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList())));
        //记录格子号,按格子号更新剩余尺寸
        List<Integer> slotList = new ArrayList<>();
        for (BigStorageCageTask item : noDealTaskList) {
            slotList.add(item.getTargetSlot());
            slotList.add(item.getStartSlot());
        }
        //更新格子剩余宽度
        updateSlotRemainBySlots(slotList);
        log.info("进片任务-无动作执行完成");
    }
 
    private void noDealOutTask(List<BigStorageCageTask> noDealTaskList) {
//        获取进片任务表中状态为破损的数据
        log.info("破损的玻璃信息有:{}", noDealTaskList);
        if (Const.OUT_TARGET_POSITION_ALL.contains(noDealTaskList.get(0).getTargetSlot())) {
            //出片任务:将出片中状态恢复为在笼内
            List<String> glassList = noDealTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList());
            bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
                    .set(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                    .in(BigStorageCageDetails::getGlassId, glassList));
 
        } else {
            //调度任务:将调度中状态改为在笼内,格子号恢复为调度前的格子
            for (BigStorageCageTask item : noDealTaskList) {
                bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
                        .set(BigStorageCageDetails::getSlot, item.getStartSlot())
                        .set(BigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                        .eq(BigStorageCageDetails::getGlassId, item.getGlassId()));
            }
        }
        //将破损信息新增入破损表
        List<Integer> slotList = new ArrayList<>();
        for (BigStorageCageTask item : noDealTaskList) {
            slotList.add(item.getTargetSlot());
            slotList.add(item.getStartSlot());
        }
        //更新格子剩余宽度
        updateSlotRemainBySlots(slotList);
        log.info("出片任务-无动作执行完成");
    }
 
    /**
     * 出片一次仅生成一车玻璃
     *
     * @param list
     * @param <T>
     * @return
     */
    private <T extends BigStorageCageBaseInfo> Boolean computeOutGlassInfo(List<T> list, String tableName, int targetSlot, int state, int taskType) {
        //任务数据:获取车子存放玻璃最大数量,玻璃间隔
        List<BigStorageCageTask> bigStorageCageTaskList = new ArrayList<>();
        //打车剩余尺寸
        Integer remainWidth = carWidth;
        for (T e : list) {
            if (bigStorageCageTaskList.size() >= outCarMaxSize || Math.max((int) e.getWidth(), (int) e.getHeight()) > remainWidth) {
                break;
            }
            //计算当前出片车剩尺寸
            remainWidth = remainWidth - Math.max((int) e.getWidth(), (int) e.getHeight()) - glassGap;
            bigStorageCageTaskList.add(new BigStorageCageTask(e.getGlassId(), e.getSlot(), targetSlot,
                    0));
        }
        Assert.isFalse(CollectionUtils.isEmpty(bigStorageCageTaskList), "未获取出片数据,结束出片任务");
        log.info("获取出片任务数据{}条,执行保存", bigStorageCageTaskList.size());
        List<String> glassIds = bigStorageCageTaskList.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList());
        int glassCount = bigStorageCageTaskList.size();
        //生成出片任务条数不足6补全
        while (bigStorageCageTaskList.size() < 6) {
            bigStorageCageTaskList.add(new BigStorageCageTask("", 0, 0, 0));
        }
        //清空任务表数据
        bigStorageCageTaskService.removeAll("big_storage_cage_out_two_task");
        bigStorageCageTaskService.saveTaskMessage(tableName, bigStorageCageTaskList);
        List<BigStorageCageHistoryTask> historyList = bigStorageCageTaskList.stream().filter(e -> StringUtils.isNotBlank(e.getGlassId())).map(e -> {
            BigStorageCageHistoryTask history = new BigStorageCageHistoryTask();
            BeanUtils.copyProperties(e, history);
            history.setGlassCount(glassCount);
            history.setTaskType(taskType);
            return history;
        }).collect(Collectors.toList());
        bigStorageCageHistoryTaskService.saveBatch(historyList);
 
        log.info("将出片玻璃{}玻璃状态改为出片中", glassIds);
        bigStorageCageDetailsService.update(new LambdaUpdateWrapper<BigStorageCageDetails>()
                .set(BigStorageCageDetails::getState, state)
                .set(Const.GLASS_STATE_SCHEDULE_ING.equals(state), BigStorageCageBaseInfo::getSlot, targetSlot)
                .in(BigStorageCageDetails::getGlassId, glassIds));
        try {
            miloService.writeToOpcWord(generateReadWriteEntity("DLP2B.DLP2B.MesReply", 1));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return Boolean.TRUE;
    }
 
 
    public void updateSlotRemainBySlots(List<Integer> slotList) {
        //获取格子内所有的玻璃信息
        List<BigStorageCageDetails> inSlotGlassList = bigStorageCageDetailsService.list(new LambdaQueryWrapper<BigStorageCageDetails>()
                .in(BigStorageCageDetails::getSlot, slotList).in(BigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL));
        Map<Integer, Double> slotRemainMap = new HashMap<>();
        //是否存在有格子非空的玻璃
        if (CollectionUtils.isNotEmpty(inSlotGlassList)) {
            //存在  将格子内的玻璃分别进行更新
            slotRemainMap = inSlotGlassList.stream()
                    .collect(Collectors.groupingBy(BigStorageCageDetails::getSlot, Collectors.summingDouble(item -> Math.max(item.getWidth(), item.getHeight()) + glassGap)));
            slotRemainMap.forEach((e, v) -> {
                double remainWidth = slotWidth - v >= 0 ? slotWidth - v : 0;
                bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, remainWidth)
                        .eq(BigStorageCage::getSlot, e));
            });
        }
        //过滤不存在玻璃的格子 将宽度重置为原始宽度5000
        Set<Integer> remainSlotList = slotRemainMap.keySet();
        slotList.removeAll(remainSlotList);
        if (CollectionUtils.isNotEmpty(slotList)) {
            bigStorageCageService.update(new LambdaUpdateWrapper<BigStorageCage>().set(BigStorageCage::getRemainWidth, slotWidth)
                    .in(BigStorageCage::getSlot, slotList));
        }
    }
 
    private ReadWriteEntity generateReadWriteEntity(String identifier, Object value) {
        return ReadWriteEntity.builder()
                .identifier(identifier)
                //Kep中是Long类型,即:Int32,Java中的int类型
                .value(value)
                .build();
    }
}