zhoushihao
2025-04-10 0961a4ebfeacaed4787c59e017691775a339616f
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
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
package com.mes.job;
 
import cn.hutool.core.collection.CollectionUtil;
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.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.kangaroohy.milo.model.ReadWriteEntity;
import com.kangaroohy.milo.service.MiloService;
import com.mes.base.entity.HollowBigStorageCageBaseInfo;
import com.mes.bigstoragecagetask.entity.BigStorageCageTask;
import com.mes.bigstoragecagetask.service.BigStorageCageTaskService;
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.entity.HollowBigStorageCage;
import com.mes.hollow.entity.HollowBigStorageCageDetails;
import com.mes.hollow.entity.HollowGlassOutRelationInfo;
import com.mes.hollow.entity.HollowGlassRelationInfo;
import com.mes.hollow.entity.dto.BigStorageSequenceDTO;
import com.mes.hollow.entity.dto.FlowCardVirtualSlotDTO;
import com.mes.hollow.entity.dto.HollowBigStorageDTO;
import com.mes.hollow.entity.dto.UpdateHollowBigStorageCageDTO;
import com.mes.hollow.service.HollowBigStorageCageDetailsService;
import com.mes.hollow.service.HollowBigStorageCageService;
import com.mes.hollow.service.HollowGlassOutRelationInfoService;
import com.mes.hollow.service.HollowGlassRelationInfoService;
import com.mes.hollowqueue.entity.HollowGlassQueueInfo;
import com.mes.hollowqueue.service.HollowGlassQueueInfoService;
import com.mes.hollowtask.entity.HollowBigStorageCageHistoryTask;
import com.mes.hollowtask.service.HollowBigStorageCageHistoryTaskService;
import com.mes.temperingglass.entity.TemperingGlassInfo;
import com.mes.temperingglass.service.TemperingGlassInfoService;
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.scheduling.annotation.Scheduled;
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 HollowBigStorageCageService hollowBigStorageCageService;
 
    @Resource
    private HollowBigStorageCageHistoryTaskService hollowBigStorageCageHistoryTaskService;
    @Resource
    private HollowGlassRelationInfoService hollowGlassRelationInfoService;
    @Resource
    private HollowBigStorageCageDetailsService hollowBigStorageCageDetailsService;
    @Resource
    private DamageService damageService;
    @Resource
    private GlassInfoService glassInfoService;
    @Resource
    private BigStorageCageTaskService bigStorageCageTaskService;
 
    @Resource
    private TemperingGlassInfoService temperingGlassInfoService;
    @Resource
    private HollowGlassQueueInfoService hollowGlassQueueInfoService;
    @Resource
    private HollowGlassOutRelationInfoService hollowGlassOutRelationInfoService;
 
    private static final String BIG_STORAGE_CAGE_IN_TWO_TASK = "big_storage_cage_in_two_task";
    private static final String BIG_STORAGE_CAGE_OUT_TWO_TASK = "big_storage_cage_out_two_task";
    /**
     * 直通格子
     */
    private static final Integer THROUGH_SLOT = 920;
    @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.slotMaxHeight}")
    private Integer slotMaxHeight;
    @Value("${mes.slotMaxthickness}")
    private Integer slotMaxthickness;
 
    @Scheduled(fixedDelay = 1000)
    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 = new ArrayList();
        ReadWriteEntity fromOpcUa = miloService.readFromOpcUa("DLP2A.DLP2A.FROM1");
        List<String> glassIdList = new ArrayList<>();
        for (int i = 1; i <= 6; i++) {
            ReadWriteEntity requestWord = miloService.readFromOpcUa("DLP2A.DLP2A.DI" + i);
            if (null != requestWord.getValue()) {
                BigStorageCageTask task = new BigStorageCageTask();
                task.setGlassId(requestWord.getValue() + "");
                task.setStartSlot(Integer.parseInt(fromOpcUa.getValue() + ""));
                inTaskList.add(task);
                glassIdList.add(requestWord.getValue() + "");
                continue;
            }
        }
        if (CollectionUtil.isEmpty(inTaskList)) {
            log.info("当前大车无进片玻璃,结束进片任务");
            return;
        }
        log.info("获取任务的玻璃id:{}", glassIdList);
        Map<String, Long> glassCountMap = glassIdList.stream().collect(Collectors.groupingBy(e -> e, Collectors.counting()));
        for (Map.Entry<String, Long> entry : glassCountMap.entrySet()) {
            if (entry.getValue() > 1) {
                log.info("进片玻璃{}存在相同,结束本次任务", entry.getKey());
                //向plc发送报警:同一车进片玻璃存在相同
                miloService.writeToOpcWord(generateReadWriteEntity("DLP2A.DLP2A.alarmSignal", 2));
                return;
            }
        }
        List<HollowBigStorageCageDetails> detailsList = hollowBigStorageCageDetailsService.list(new LambdaQueryWrapper<HollowBigStorageCageDetails>().in(HollowBigStorageCageDetails::getGlassId, glassIdList)
                .in(HollowBigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL_ZERO));
        if (CollectionUtil.isNotEmpty(detailsList)) {
            log.info("理片笼存在相同的进片玻璃{},结束本次任务", detailsList);
            //向plc发送报警:理片笼存在相同的进片玻璃
            miloService.writeToOpcWord(generateReadWriteEntity("DLP2A.DLP2A.alarmSignal", 4));
            return;
        }
        List<GlassInfo> glassInfoList = glassInfoService.list(new LambdaQueryWrapper<GlassInfo>().in(GlassInfo::getGlassId, glassIdList));
 
        if (glassInfoList.size() != inTaskList.size()) {
            log.info("进片任务数量{}与玻璃数量{}不匹配,结束本次进片", inTaskList.size(), glassInfoList.size());
            //向plc发送报警:进片任务数量与系统查询到的玻璃数量不匹配
            miloService.writeToOpcWord(generateReadWriteEntity("DLP2A.DLP2A.alarmSignal", 8));
            return;
        }
        //按照玻璃厚度分组,判断剩余格子是否可以存放
        Map<Double, Long> thickCountMap = glassInfoList.stream().collect(Collectors.groupingBy(GlassInfo::getThickness, Collectors.counting()));
        for (Map.Entry<Double, Long> entry : thickCountMap.entrySet()) {
            int count = hollowBigStorageCageService.count(new LambdaQueryWrapper<HollowBigStorageCage>()
                    .eq(HollowBigStorageCage::getEnableState, Const.SLOT_ON).eq(HollowBigStorageCage::getRemainWidth, slotWidth)
                    .le(HollowBigStorageCage::getMinThickness, entry.getKey())
                    .ge(HollowBigStorageCage::getMaxThickness, entry.getKey()));
            if (count < entry.getValue()) {
                log.info("笼内格子剩余数量不足,结束本次进片");
                //向plc发送报警:笼内格子剩余数量不足
                miloService.writeToOpcWord(generateReadWriteEntity("DLP2A.DLP2A.alarmSignal", 16));
                return;
            }
        }
        //超大尺寸
        if (slotMaxHeight < Math.min(glassInfoList.get(0).getWidth(), glassInfoList.get(0).getHeight()) || glassInfoList.get(0).getThickness() >= slotMaxthickness) {
            int count = hollowBigStorageCageDetailsService.count(new LambdaQueryWrapper<HollowBigStorageCageDetails>()
                    .eq(HollowBigStorageCageDetails::getSlot, THROUGH_SLOT)
                    .in(HollowBigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL));
            if (count > 0) {
                log.info("直通片台存在玻璃,结束本次进片");
                //向plc发送报警:直通片台存在玻璃,无法继续直通
                miloService.writeToOpcWord(generateReadWriteEntity("DLP2A.DLP2A.alarmSignal", 64));
                return;
            }
        }
 
        log.info("将钢化小片表内的状态改为钢化结束,玻璃id有:{}", glassIdList);
        //修改钢化任务表中的状态
        temperingGlassInfoService.update(new LambdaUpdateWrapper<TemperingGlassInfo>()
                .set(TemperingGlassInfo::getState, Const.TEMPERING_END).in(TemperingGlassInfo::getGlassId, glassIdList));
        //报工
        log.info("将接收到的玻璃进行钢化自动报工,玻璃id有:{}", glassIdList);
        for (String glass : glassIdList) {
            damageService.autoSubmitReport(glass, inTaskList.get(0).getStartSlot(), "钢化", "进中空理片笼", 1);
        }
        Map<String, List<GlassInfo>> glassListMap = glassInfoList.stream().collect(Collectors.groupingBy(GlassInfo::getGlassId));
 
        //计算目标格子
        List<HollowBigStorageCageHistoryTask> historyTasks = new ArrayList<>();
        try {
            if (slotMaxHeight > Math.min(glassInfoList.get(0).getWidth(), glassInfoList.get(0).getHeight()) && glassInfoList.get(0).getThickness() < slotMaxthickness) {
                for (BigStorageCageTask task : inTaskList) {
                    GlassInfo info = glassListMap.get(task.getGlassId()).get(0);
                    HollowBigStorageDTO bigStorageDTO = hollowGlassRelationInfoService.queryHollowTargetSlot(info.getFlowCardId(),
                            info.getWidth(), info.getHeight(), info.getTotalLayer(), info.getLayer());
//            临时更新格子的剩余尺寸:防止相邻玻璃进同一格子造成剩余尺寸不足,玻璃越界的情况,任务完成后再次更新大理片笼表剩余宽度(按照笼内玻璃数量更新大理片笼剩余尺寸)
                    hollowBigStorageCageService.update(new LambdaUpdateWrapper<HollowBigStorageCage>()
                            .set(HollowBigStorageCage::getRemainWidth, bigStorageDTO.getRemainWidth() - Math.max(info.getWidth(), info.getHeight()) - glassGap)
                            .eq(HollowBigStorageCage::getSlot, bigStorageDTO.getSlot()));
                    task.setTargetSlot(bigStorageDTO.getSlot());
                    task.setGlassId(info.getGlassId());
                    bigStorageCageTaskService.updateTaskMessage(BIG_STORAGE_CAGE_IN_TWO_TASK, task);
                    //存放历史任务
                    HollowBigStorageCageHistoryTask historyTask = new HollowBigStorageCageHistoryTask();
                    BeanUtils.copyProperties(task, historyTask);
                    historyTask.setTaskType(Const.BIG_STORAGE_AFTER_IN);
                    historyTask.setGlassCount(glassInfoList.size());
                    historyTask.setTaskState(Const.ENGINEERING_NEW);
                    historyTasks.add(historyTask);
                    //存放详情数据
                    HollowBigStorageCageDetails cageDetails = new HollowBigStorageCageDetails();
                    BeanUtils.copyProperties(bigStorageDTO, cageDetails);
                    BeanUtils.copyProperties(info, cageDetails);
                    cageDetails.setState(Const.GLASS_STATE_NEW);
                    cageDetails.setSequence(bigStorageDTO.getSlotSequence());
                    cageDetails.setGap(glassGap);
                    cageDetails.setId(null);
                    hollowBigStorageCageDetailsService.save(cageDetails);
                    hollowGlassRelationInfoService.update(new LambdaUpdateWrapper<HollowGlassRelationInfo>()
                            .set(HollowGlassRelationInfo::getGlassId, cageDetails.getGlassId())
                            .set(HollowGlassRelationInfo::getTemperingLayoutId, cageDetails.getTemperingLayoutId())
                            .set(HollowGlassRelationInfo::getTemperingFeedSequence, cageDetails.getTemperingFeedSequence())
                            .set(HollowGlassRelationInfo::getEngineerId, cageDetails.getEngineerId())
                            .set(HollowGlassRelationInfo::getState, Const.HOLLOW_RELATION_OCCUPY)
                            .eq(HollowGlassRelationInfo::getFlowCardId, bigStorageDTO.getFlowCardId())
                            .eq(HollowGlassRelationInfo::getLayer, bigStorageDTO.getLayer())
                            .eq(HollowGlassRelationInfo::getVirtualSlot, bigStorageDTO.getVirtualSlot())
                            .eq(HollowGlassRelationInfo::getSlotSequence, bigStorageDTO.getSlotSequence())
                            .eq(HollowGlassRelationInfo::getHollowSequence, bigStorageDTO.getHollowSequence())
                    );
                }
            } else {
                BigStorageCageTask task = inTaskList.get(0);
                task.setTargetSlot(THROUGH_SLOT);
                bigStorageCageTaskService.updateTaskMessage("big_storage_cage_in_two_task", task);
                //存放历史任务
                HollowBigStorageCageHistoryTask historyTask = new HollowBigStorageCageHistoryTask();
                BeanUtils.copyProperties(task, historyTask);
                historyTask.setTaskType(Const.BIG_STORAGE_AFTER_IN);
                historyTask.setGlassCount(glassInfoList.size());
                historyTask.setTaskState(Const.ENGINEERING_NEW);
                historyTasks.add(historyTask);
                GlassInfo info = glassInfoList.get(0);
                HollowBigStorageCageDetails cageDetails = new HollowBigStorageCageDetails();
                BeanUtils.copyProperties(info, cageDetails);
                cageDetails.setSlot(THROUGH_SLOT);
                cageDetails.setState(Const.GLASS_STATE_NEW);
                cageDetails.setDeviceId(0);
                cageDetails.setSequence(0);
                cageDetails.setHollowSequence(0);
                cageDetails.setGap(glassGap);
                cageDetails.setFilmsId(info.getFilmsid());
                cageDetails.setId(null);
                hollowBigStorageCageDetailsService.save(cageDetails);
            }
        } catch (Exception exception) {
            log.info("进片任务执行中发生异常:{}", exception);
            hollowGlassRelationInfoService.update(new LambdaUpdateWrapper<HollowGlassRelationInfo>()
                    .set(HollowGlassRelationInfo::getGlassId, null)
                    .set(HollowGlassRelationInfo::getTemperingLayoutId, null)
                    .set(HollowGlassRelationInfo::getTemperingFeedSequence, null)
                    .set(HollowGlassRelationInfo::getEngineerId, null)
                    .set(HollowGlassRelationInfo::getState, Const.HOLLOW_RELATION_NEW)
                    .eq(HollowGlassRelationInfo::getState, Const.HOLLOW_RELATION_OCCUPY)
            );
        }
        //历史数据入库
        hollowBigStorageCageHistoryTaskService.saveBatch(historyTasks);
        //向opc发送启动信号
        List<ReadWriteEntity> list = new ArrayList<>();
        for (int i = 1; i <= inTaskList.size(); i++) {
            list.add(generateReadWriteEntity("DLP2A.DLP2A.TO" + i, inTaskList.get(i - 1).getTargetSlot()));
        }
        list.add(generateReadWriteEntity("DLP2A.DLP2A.MesReply", 1));
        miloService.writeToOpcWord(list);
    }
 
    @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 (CollectionUtil.isNotEmpty(outTaskList)) {
            log.info("有正在执行的出片任务,结束本次出片任务");
            return;
        }
 
        //获取空闲且领取任务的数据信息,没有任务直接走玻璃调度
        HashMap<Integer, ReadWriteEntity> map = new HashMap<>();
        ReadWriteEntity oneEntity = miloService.readFromOpcUa("CMJ1.CMJ1.isFree");
        ReadWriteEntity twoEntity = miloService.readFromOpcUa("ZKQ2.ZKQ2.isFree");
        ReadWriteEntity threeEntity = miloService.readFromOpcUa("ZKQ3.ZKQ3.isFree");
        map.put(930, oneEntity);
        map.put(931, twoEntity);
        map.put(932, threeEntity);
        HollowGlassOutRelationInfo hollowGlassOutRelationInfo = null;
        int cell = -1;
        for (int i = 930; i < 931; i++) {
            if (null == hollowGlassOutRelationInfo) {
                ReadWriteEntity entity = map.get(i);
                cell = i;
                if (null != entity.getValue() && ("1".equals(entity.getValue() + "") || Boolean.parseBoolean(twoEntity.getValue() + ""))) {
                    hollowGlassOutRelationInfo = hollowGlassOutRelationInfoService
                            .getOne(new LambdaQueryWrapper<HollowGlassOutRelationInfo>()
                                    .eq(HollowGlassOutRelationInfo::getCell, cell)
                                    .eq(HollowGlassOutRelationInfo::getState, Const.HOLLOW_FLOW_CARD_START)
                            );
                }
            } else {
                break;
            }
        }
        for (int i = 930; i <= 932; i++) {
            if (null == hollowGlassOutRelationInfo) {
                cell = i;
                hollowGlassOutRelationInfo = hollowGlassOutRelationInfoService
                        .getOne(new LambdaQueryWrapper<HollowGlassOutRelationInfo>()
                                .eq(HollowGlassOutRelationInfo::getCell, cell)
                                .eq(HollowGlassOutRelationInfo::getState, Const.HOLLOW_FLOW_CARD_START)
                        );
            } else {
                break;
            }
        }
 
        if (null != hollowGlassOutRelationInfo) {
            //是否允许中空
            //是否有正在中空的玻璃:中空小片表筛选未出笼的玻璃信息
//            获取当前中空任务未完成出片的玻璃信息
            List<HollowGlassQueueInfo> unFinishHollowQueueList = hollowGlassQueueInfoService.list(new LambdaQueryWrapper<HollowGlassQueueInfo>()
                    .eq(HollowGlassQueueInfo::getFlowCardId, hollowGlassOutRelationInfo.getFlowCardId())
                    .eq(HollowGlassQueueInfo::getCell, cell)
                    .eq(HollowGlassQueueInfo::getState, Const.TEMPERING_NEW)
                    .orderByAsc(HollowGlassQueueInfo::getHollowSequence));
            if (CollectionUtil.isNotEmpty(unFinishHollowQueueList)) {
                log.info("有正在出片的中空任务");
                Integer isPair = unFinishHollowQueueList.get(0).getIsPair();
                hollowOutGlassByIsPair(unFinishHollowQueueList, hollowGlassOutRelationInfo.getCell(), isPair, hollowGlassOutRelationInfo.getTotalLayer(), hollowGlassOutRelationInfo.getIsForce());
                Date endDate = new Date();
                log.info("大理片笼出片任务结束时间:{},共耗时:{}ms,结束扫码任务", endDate, endDate.getTime() - startDate.getTime());
                return;
            } else {
                //将中空任务状态改为已完成
                hollowGlassOutRelationInfoService.update(new LambdaUpdateWrapper<HollowGlassOutRelationInfo>()
                        .eq(HollowGlassOutRelationInfo::getFlowCardId, hollowGlassOutRelationInfo.getFlowCardId())
                        .eq(HollowGlassOutRelationInfo::getCell, hollowGlassOutRelationInfo.getCell())
                        .set(HollowGlassOutRelationInfo::getState, Const.HOLLOW_FLOW_CARD_SUCCESS));
            }
        }
//        redisUtil.setCacheObject("dispatchHollowSwitch",true);
        //是否存在需要内部调度的格子:执行内部调度任务
        if (redisUtil.getCacheObject("dispatchHollowSwitch")) {
            //todo:获取笼内单格已经到齐的玻璃格子信息
            List<FlowCardVirtualSlotDTO> virtualList = hollowBigStorageCageDetailsService.queryIsAllNeedDispatchVirtualSlot();
            if (CollectionUtil.isEmpty(virtualList)) {
                log.info("没有需要调度的格子");
                return;
            }
            List<HollowBigStorageCageDetails> list = new ArrayList<>();
            loop:
            for (FlowCardVirtualSlotDTO dto : virtualList) {
                List<BigStorageSequenceDTO> sequenceDTOList = hollowBigStorageCageDetailsService.queryNeedDispatchSlot(dto);
                if (CollectionUtil.isEmpty(sequenceDTOList) || sequenceDTOList.size() == 1) {
                    continue;
                }
                int sequence = -1;
                int startSlot = -1;
                for (BigStorageSequenceDTO item : sequenceDTOList) {
                    if (item.getMinSequence() == sequence + 1) {
                        //生成调度任务
                        int targetSlot = item.getSlot();
                        list = hollowBigStorageCageDetailsService.list(new LambdaQueryWrapper<HollowBigStorageCageDetails>()
                                .eq(HollowBigStorageCageDetails::getState, Const.GLASS_STATE_IN).eq(HollowBigStorageCageDetails::getSlot, startSlot));
                        hollowOutGlassByIsPair(list, targetSlot, 0, 0, 0);
                        List<Integer> slotList = new ArrayList<>();
                        slotList.add(targetSlot);
                        updateSlotRemainBySlots(slotList);
                        break loop;
                    }
                    sequence = item.getMaxSequence();
                    startSlot = item.getSlot();
                }
            }
        }
        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 = new ArrayList();
        List<String> glassIdList = new ArrayList<>();
        ReadWriteEntity toWord = miloService.readFromOpcUa("DLP2A.DLP2A.TO1");
        if ("0".equals(toWord.getValue() + "")) {
            log.info("完成任务已执行,结束本次完成进片任务");
            return;
        }
        for (int i = 1; i <= 6; i++) {
            ReadWriteEntity requestWord = miloService.readFromOpcUa("DLP2A.DLP2A.DI" + i);
            ReadWriteEntity statetWord = miloService.readFromOpcUa("DLP2A.DLP2A.STATE" + i);
            ReadWriteEntity toOpcUa = miloService.readFromOpcUa("DLP2A.DLP2A.TO" + i);
            ReadWriteEntity fromOpcUa = miloService.readFromOpcUa("DLP2A.DLP2A.FROM" + i);
 
            if (null != requestWord.getValue()) {
                BigStorageCageTask task = new BigStorageCageTask();
                task.setGlassId(requestWord.getValue() + "");
                task.setTargetSlot(Integer.parseInt(toOpcUa.getValue() + ""));
                task.setTaskState(Integer.parseInt(statetWord.getValue() + ""));
                task.setStartSlot(Integer.parseInt(fromOpcUa.getValue() + ""));
                inTaskList.add(task);
                glassIdList.add(requestWord.getValue() + "");
                continue;
            }
        }
        if (CollectionUtil.isEmpty(inTaskList)) {
            log.info("当前大车无进片玻璃,结束完成进片任务");
            return;
        }
        List<BigStorageCageTask> unFinishTaskList = inTaskList.stream().filter(e -> e.getTaskState() <= 1 || e.getStartSlot() == 0).collect(Collectors.toList());
        if (CollectionUtil.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<UpdateHollowBigStorageCageDTO> storageCageDTOList = v.stream().map(e -> {
                    UpdateHollowBigStorageCageDTO storageCageDTO = new UpdateHollowBigStorageCageDTO();
                    BeanUtils.copyProperties(e, storageCageDTO);
                    return storageCageDTO;
                }).collect(Collectors.toList());
                hollowBigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_IN);
                log.info("4、大理片笼进片状态已完成已完成的玻璃信息id:{}", v);
                updateSlotRemainBySlots(inSuccessGlassSlot);
                List<String> glassList = v.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList());
                hollowGlassRelationInfoService.update(new LambdaUpdateWrapper<HollowGlassRelationInfo>()
                        .set(HollowGlassRelationInfo::getState, Const.HOLLOW_RELATION_SUCCESS)
                        .eq(HollowGlassRelationInfo::getState, Const.HOLLOW_RELATION_OCCUPY)
                        .in(HollowGlassRelationInfo::getGlassId, glassList)
                );
            } else if (e1 == 3) {
                //破损处理
                dealDamageInTask(v);
                List<String> glassList = v.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList());
                hollowGlassRelationInfoService.update(new LambdaUpdateWrapper<HollowGlassRelationInfo>()
                        .set(HollowGlassRelationInfo::getGlassId, null)
                        .set(HollowGlassRelationInfo::getTemperingLayoutId, null)
                        .set(HollowGlassRelationInfo::getTemperingFeedSequence, null)
                        .set(HollowGlassRelationInfo::getEngineerId, null)
                        .set(HollowGlassRelationInfo::getState, Const.HOLLOW_RELATION_NEW)
                        .eq(HollowGlassRelationInfo::getState, Const.HOLLOW_RELATION_OCCUPY)
                        .in(HollowGlassRelationInfo::getGlassId, glassList)
                );
            } else {
                //清空理片笼空数据
                noDealInTask(v);
                List<String> glassList = v.stream().map(BigStorageCageTask::getGlassId).collect(Collectors.toList());
                hollowGlassRelationInfoService.update(new LambdaUpdateWrapper<HollowGlassRelationInfo>()
                        .set(HollowGlassRelationInfo::getGlassId, null)
                        .set(HollowGlassRelationInfo::getTemperingLayoutId, null)
                        .set(HollowGlassRelationInfo::getTemperingFeedSequence, null)
                        .set(HollowGlassRelationInfo::getEngineerId, null)
                        .set(HollowGlassRelationInfo::getState, Const.HOLLOW_RELATION_NEW)
                        .eq(HollowGlassRelationInfo::getState, Const.HOLLOW_RELATION_OCCUPY)
                        .in(HollowGlassRelationInfo::getGlassId, glassList)
                );
            }
        });
        for (BigStorageCageTask item : inTaskList) {
            //更新历史任务表中的任务状态
            hollowBigStorageCageHistoryTaskService.update(new LambdaUpdateWrapper<HollowBigStorageCageHistoryTask>()
                    .set(HollowBigStorageCageHistoryTask::getTaskState, item.getTaskState())
                    .eq(HollowBigStorageCageHistoryTask::getTaskType, Const.BIG_STORAGE_AFTER_IN)
                    .eq(HollowBigStorageCageHistoryTask::getTargetSlot, item.getTargetSlot())
                    .eq(HollowBigStorageCageHistoryTask::getGlassId, item.getGlassId()));
            item.setTargetSlot(0);
            //清空任务表数据
            bigStorageCageTaskService.updateTaskMessage("big_storage_cage_in_one_task", item);
        }
        //清空启动状态
        //向opc发送启动信号
        //向opc发送启动信号
        List<ReadWriteEntity> list = new ArrayList<>();
        for (int i = 1; i <= 6; i++) {
            list.add(generateReadWriteEntity("DLP2A.DLP2A.TO" + i, 0));
        }
        list.add(generateReadWriteEntity("DLP2A.DLP2A.MesReply", 0));
        miloService.writeToOpcWord(list);
    }
 
    @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 (CollectionUtil.isEmpty(outTaskList)) {
            log.info("当前大车无进片玻璃,结束完成进片任务");
            return;
        }
        List<BigStorageCageTask> unFinishTaskList = outTaskList.stream().filter(e -> e.getTaskState() <= 1 || e.getStartSlot() == 0).collect(Collectors.toList());
        if (CollectionUtil.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_AFTER_OUT;
        } else {
            taskType = Const.BIG_STORAGE_AFTER_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_AFTER_OUT)) {
                    outSuccessGlassSlot = v.stream().map(BigStorageCageTask::getStartSlot).collect(Collectors.toList());
                } else {
                    List<Integer> targetSuccessGlassSlot = v.stream().map(BigStorageCageTask::getTargetSlot).collect(Collectors.toList());
                    List<Integer> startoutSuccessGlassSlot = v.stream().map(BigStorageCageTask::getStartSlot).collect(Collectors.toList());
                    outSuccessGlassSlot.addAll(targetSuccessGlassSlot);
                    outSuccessGlassSlot.addAll(startoutSuccessGlassSlot);
                }
                List<UpdateHollowBigStorageCageDTO> storageCageDTOList = v.stream().map(e -> {
                    UpdateHollowBigStorageCageDTO storageCageDTO = new UpdateHollowBigStorageCageDTO();
                    storageCageDTO.setGlassId(e.getGlassId());
                    if (finalTaskType.equals(Const.BIG_STORAGE_AFTER_OUT)) {
                        storageCageDTO.setTargetSlot(e.getStartSlot());
                    } else {
                        storageCageDTO.setTargetSlot(e.getTargetSlot());
                    }
                    return storageCageDTO;
                }).collect(Collectors.toList());
                if (finalTaskType.equals(Const.BIG_STORAGE_AFTER_OUT)) {
                    hollowBigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_OUT);
                } else {
                    hollowBigStorageCageDetailsService.updateBySlot(storageCageDTOList, Const.GLASS_STATE_IN);
                    //按照格子信息更新对应的设备id
                    List<Integer> slotList = storageCageDTOList.stream().map(UpdateHollowBigStorageCageDTO::getTargetSlot).distinct().collect(Collectors.toList());
                    hollowBigStorageCageDetailsService.updateDeviceIdBySlot(slotList);
                }
                log.info("4、大理片笼进片状态已完成已完成的玻璃信息id:{}", v);
                updateSlotRemainBySlots(outSuccessGlassSlot);
            } else if (e1 == 3) {
                //破损处理
                dealDamageOutTask(v);
            } else {
                //清空理片笼空数据
                noDealOutTask(v);
            }
        });
 
        for (BigStorageCageTask item : outTaskList) {
            //更新历史任务表中的任务状态
            hollowBigStorageCageHistoryTaskService.update(new LambdaUpdateWrapper<HollowBigStorageCageHistoryTask>()
                    .set(HollowBigStorageCageHistoryTask::getTaskState, item.getTaskState())
                    .eq(HollowBigStorageCageHistoryTask::getTaskType, taskType)
                    .eq(HollowBigStorageCageHistoryTask::getGlassId, item.getGlassId()));
            //更新中空小片表
            Integer taskState = item.getTaskState();
            if (taskState == 2) {
                hollowGlassQueueInfoService.update(new LambdaUpdateWrapper<HollowGlassQueueInfo>()
                        .set(HollowGlassQueueInfo::getState, Const.TEMPERING_OUT).eq(HollowGlassQueueInfo::getGlassId, item.getGlassId()));
            } else if (taskState == 3) {
//                temperingGlassInfoService.remove(new LambdaQueryWrapper<TemperingGlassInfo>().eq(TemperingGlassInfo::getGlassId, item.getGlassId()));
                hollowGlassQueueInfoService.update(new LambdaUpdateWrapper<HollowGlassQueueInfo>()
                        .set(HollowGlassQueueInfo::getState, Const.TEMPERING_DAMAGE).eq(HollowGlassQueueInfo::getGlassId, item.getGlassId()));
 
            } else {
//                空执行
            }
        }
        try {
            //更新数量
            //按照玻璃id获取需要出片对列表中的数据
            if (finalTaskType.equals(Const.BIG_STORAGE_AFTER_OUT)) {
                HollowGlassQueueInfo hollowGlassQueueInfo = hollowGlassQueueInfoService.getOne(new LambdaQueryWrapper<HollowGlassQueueInfo>()
                        .eq(HollowGlassQueueInfo::getGlassId, outTaskList.get(0).getGlassId())
                        .orderByDesc(HollowGlassQueueInfo::getUpdateTime).last("limit 1"));
                List<HollowGlassQueueInfo> list = hollowGlassQueueInfoService.list(new LambdaQueryWrapper<HollowGlassQueueInfo>()
                                .eq(HollowGlassQueueInfo::getFlowCardId, hollowGlassQueueInfo.getFlowCardId())
                                .eq(HollowGlassQueueInfo::getCell, hollowGlassQueueInfo.getCell())
//                        .eq(HollowGlassQueueInfo::getIsPair, 1)
                                .eq(HollowGlassQueueInfo::getState, Const.TEMPERING_NEW)
                );
                if (CollectionUtil.isEmpty(list)) {
//                任务更新为已完成
                    hollowGlassOutRelationInfoService.update(new UpdateWrapper<HollowGlassOutRelationInfo>()
                            .eq("flow_card_id", hollowGlassQueueInfo.getFlowCardId())
                            .eq("cell", hollowGlassQueueInfo.getCell())
                            .setSql("pair_quantity = total_pair_quantity")
                            .set("state", Const.HOLLOW_FLOW_CARD_SUCCESS)
                    );
                } else {
//               计算剩余玻璃对数,用任务总队数减剩余对数
                    int remainCount = list.size() / hollowGlassQueueInfo.getTotalLayer();
                    hollowGlassOutRelationInfoService.update(new UpdateWrapper<HollowGlassOutRelationInfo>()
                            .eq("flow_card_id", hollowGlassQueueInfo.getFlowCardId())
                            .eq("cell", hollowGlassQueueInfo.getCell())
                            .setSql("pair_quantity = total_pair_quantity -" + remainCount)
                    );
                }
            }
        } catch (Exception e) {
            log.info("计算玻璃数量过程中出现错误,错误信息{}", e.getMessage());
        }
 
//       重置任务表数据
        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);
        //移除理片笼详情表任务执行过程中破损的玻璃
        hollowBigStorageCageDetailsService.remove(new LambdaQueryWrapper<HollowBigStorageCageDetails>()
                .eq(HollowBigStorageCageDetails::getState, Const.GLASS_STATE_NEW)
                .in(HollowBigStorageCageDetails::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);
        //移除理片笼详情表任务执行过程中破损的玻璃
        hollowBigStorageCageDetailsService.remove(new LambdaQueryWrapper<HollowBigStorageCageDetails>()
                .in(HollowBigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL_ZERO)
                .in(HollowBigStorageCageDetails::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);
        //移除理片笼详情表未执行任务的空记录信息
        hollowBigStorageCageDetailsService.remove(new LambdaQueryWrapper<HollowBigStorageCageDetails>()
                .eq(HollowBigStorageCageDetails::getState, Const.GLASS_STATE_NEW)
                .in(HollowBigStorageCageDetails::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());
            hollowBigStorageCageDetailsService.update(new LambdaUpdateWrapper<HollowBigStorageCageDetails>()
                    .set(HollowBigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                    .ne(HollowBigStorageCageDetails::getState, Const.GLASS_STATE_OUT)
                    .in(HollowBigStorageCageDetails::getGlassId, glassList));
 
        } else {
            //调度任务:将调度中状态改为在笼内,格子号恢复为调度前的格子
            for (BigStorageCageTask item : noDealTaskList) {
                hollowBigStorageCageDetailsService.update(new LambdaUpdateWrapper<HollowBigStorageCageDetails>()
                        .set(HollowBigStorageCageDetails::getSlot, item.getStartSlot())
                        .set(HollowBigStorageCageDetails::getState, Const.GLASS_STATE_IN)
                        .ne(HollowBigStorageCageDetails::getState, Const.GLASS_STATE_OUT)
                        .eq(HollowBigStorageCageDetails::getGlassId, item.getGlassId()));
            }
        }
        //将破损信息新增入破损表
        List<Integer> slotList = new ArrayList<>();
        for (BigStorageCageTask item : noDealTaskList) {
            slotList.add(item.getTargetSlot());
            slotList.add(item.getStartSlot());
        }
        //更新格子剩余宽度
        updateSlotRemainBySlots(slotList);
        log.info("出片任务-无动作执行完成");
    }
 
 
    private <T extends HollowBigStorageCageBaseInfo> Boolean hollowOutGlassByIsPair(List<T> list,
                                                                                    int targetSlot, int isPair, int totalLayer, int isForce) throws Exception {
        List<T> resultList = new ArrayList<>();
        List<T> tempList = new ArrayList<>();
        int taskType = Const.BIG_STORAGE_AFTER_OUT;
        int taskState = Const.GLASS_STATE_OUT_ING;
        for (T t : list) {
            if (isPair == (t.getIsPair() == null ? 0 : t.getIsPair())) {
                tempList.add(t);
            } else {
                break;
            }
        }
        if (isPair == 0 && isForce != 1) {
            taskType = Const.BIG_STORAGE_AFTER_DISPATCH;
            taskState = Const.GLASS_STATE_SCHEDULE_ING;
            //目前调度任务totalLayer为0  出片调度任务有层号,用于区分调度方式
            // 因为出片存在调度,如果为调度,提前占用格子,更新格子剩余尺寸,避免被进片玻璃占用
            if (totalLayer != 0) {
                resultList.add(list.get(0));
                HollowBigStorageCage storageCage = hollowBigStorageCageService.getOne(new LambdaQueryWrapper<HollowBigStorageCage>()
                        .eq(HollowBigStorageCage::getEnableState, Const.SLOT_ON)
                        .le(HollowBigStorageCage::getMinThickness, list.get(0).getThickness())
                        .ge(HollowBigStorageCage::getMaxThickness, list.get(0).getThickness())
                        .eq(HollowBigStorageCage::getRemainWidth, slotWidth)
                        .orderByAsc(HollowBigStorageCage::getMaxThickness).last("limit 1"));
 
                if (null == storageCage) {
                    //向plc发送报警:直通片台存在玻璃,无法继续直通
                    miloService.writeToOpcWord(generateReadWriteEntity("DLP1A.DLP1A.alarmSignal", 16));
                    Assert.isFalse(storageCage == null, "任务调度没有多余格子,结束调度任务");
                }
 
                targetSlot = storageCage.getSlot();
                hollowBigStorageCageService.update(new LambdaUpdateWrapper<HollowBigStorageCage>()
                        .set(HollowBigStorageCage::getRemainWidth, 0).eq(HollowBigStorageCage::getSlot, targetSlot));
            } else {
                resultList = tempList;
            }
            totalLayer = 0;
        } else {
            resultList = tempList;
        }
        return computeOutGlassInfo(resultList, BIG_STORAGE_CAGE_OUT_TWO_TASK, targetSlot, taskState, taskType, totalLayer, isForce);
    }
 
    /**
     * 出片一次仅生成一车玻璃
     *
     * @param <T>
     * @param list
     * @param totalLayer
     * @return
     */
    private <T extends HollowBigStorageCageBaseInfo> Boolean computeOutGlassInfo(List<T> list, String tableName,
                                                                                 int targetSlot, int state, int taskType, int totalLayer, int isForce) {
        //任务数据:获取车子存放玻璃最大数量,玻璃间隔
        List<T> templist = new ArrayList<>();
        //打车剩余尺寸
        Integer remainWidth = carWidth;
        for (T e : list) {
            if (templist.size() >= outCarMaxSize || Math.max((int) e.getWidth(), (int) e.getHeight()) > remainWidth) {
                break;
            }
            //计算当前出片车剩尺寸
            remainWidth = remainWidth - Math.max((int) e.getWidth(), (int) e.getHeight()) - glassGap;
            templist.add(e);
        }
        Assert.isFalse(CollectionUtil.isEmpty(templist), "未获取出片数据,结束出片任务");
        log.info("获取出片任务数据{}条,执行保存", templist.size());
        List<T> baseInfoList = templist;
        if (1 != isForce) {
            if (taskType == Const.BIG_STORAGE_AFTER_OUT) {
                //校验防止小于等于总层数玻璃片序不匹配的问题,该问题多出现在大片玻璃,3层
                if (templist.size() <= totalLayer) {
                    int tempSequence = templist.get(0).getHollowSequence();
                    List<T> resultList = new ArrayList<>();
                    for (int i = 0; i < templist.size(); i++) {
                        if (tempSequence == list.get(i).getHollowSequence()) {
                            resultList.add(templist.get(i));
                        } else {
                            break;
                        }
                    }
                    baseInfoList = resultList;
                } else {
                    //大于总层数先取totalLyaer倍数数量的玻璃,保证大车上的玻璃成对传
                    int remainCount = templist.size() % totalLayer;
                    if (targetSlot == 930) {
                        baseInfoList = templist.subList(0, totalLayer);
                    } else {
                        baseInfoList = templist.subList(0, templist.size() - remainCount);
                    }
                }
            }
        }
        List<String> glassIds = baseInfoList.stream().map(T::getGlassId).collect(Collectors.toList());
        int glassCount = baseInfoList.size();
        List<BigStorageCageTask> bigStorageCageTaskList = new ArrayList<>();
        //生成出片任务条数不足6补全
        for (T t : baseInfoList) {
            bigStorageCageTaskList.add(new BigStorageCageTask(t.getGlassId(), t.getSlot(), targetSlot, 0));
        }
        while (bigStorageCageTaskList.size() < 6) {
            bigStorageCageTaskList.add(new BigStorageCageTask("", 0, 0, 0));
        }
        //清空任务表数据
        bigStorageCageTaskService.removeAll(tableName);
        bigStorageCageTaskService.saveTaskMessage(tableName, bigStorageCageTaskList);
        List<HollowBigStorageCageHistoryTask> historyList = bigStorageCageTaskList.stream().filter(e -> StringUtils.isNotBlank(e.getGlassId())).map(e -> {
            HollowBigStorageCageHistoryTask history = new HollowBigStorageCageHistoryTask();
            BeanUtils.copyProperties(e, history);
            history.setGlassCount(glassCount);
            history.setTaskType(taskType);
            return history;
        }).collect(Collectors.toList());
        hollowBigStorageCageHistoryTaskService.saveBatch(historyList);
        log.info("将出片玻璃{}玻璃状态改为出片中", glassIds);
        hollowBigStorageCageDetailsService.update(new LambdaUpdateWrapper<HollowBigStorageCageDetails>()
                .set(HollowBigStorageCageDetails::getState, state)
                .set(Const.BIG_STORAGE_AFTER_DISPATCH.equals(taskType), HollowBigStorageCageDetails::getSlot, targetSlot)
                .ne(HollowBigStorageCageDetails::getState, Const.GLASS_STATE_OUT)
                .in(HollowBigStorageCageDetails::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<HollowBigStorageCageDetails> inSlotGlassList = hollowBigStorageCageDetailsService.list(new LambdaQueryWrapper<HollowBigStorageCageDetails>()
                .in(HollowBigStorageCageDetails::getSlot, slotList).in(HollowBigStorageCageDetails::getState, Const.GLASS_STATE_IN_ALL));
        Map<Integer, Double> slotRemainMap = new HashMap<>();
        //是否存在有格子非空的玻璃
        if (CollectionUtils.isNotEmpty(inSlotGlassList)) {
            //存在  将格子内的玻璃分别进行更新
//            List<HollowBigStorageCage> hollowBigStorageCageList = hollowBigStorageCageService.list(new LambdaQueryWrapper<HollowBigStorageCage>()
//                    .lt(HollowBigStorageCage::getRemainWidth, 0).in(HollowBigStorageCage::getSlot, slotList));
//            List<Integer> resultSlotList = hollowBigStorageCageList.stream().map(HollowBigStorageCage::getSlot).collect(Collectors.toList());
            slotRemainMap = inSlotGlassList.stream()
                    .collect(Collectors.groupingBy(HollowBigStorageCageDetails::getSlot, Collectors.summingDouble(item -> Math.max(item.getWidth(), item.getHeight()) + glassGap)));
            slotRemainMap.forEach((e, v) -> {
                double remainWidth = slotWidth - v >= 0 ? slotWidth - v : 0;
                hollowBigStorageCageService.update(new LambdaUpdateWrapper<HollowBigStorageCage>().set(HollowBigStorageCage::getRemainWidth, remainWidth)
                        .eq(HollowBigStorageCage::getSlot, e));
            });
        }
        //过滤不存在玻璃的格子 将宽度重置为原始宽度6200
        Set<Integer> remainSlotList = slotRemainMap.keySet();
        slotList.removeAll(remainSlotList);
        if (CollectionUtils.isNotEmpty(slotList)) {
            hollowBigStorageCageService.update(new LambdaUpdateWrapper<HollowBigStorageCage>().set(HollowBigStorageCage::getRemainWidth, slotWidth)
                    .in(HollowBigStorageCage::getSlot, slotList));
        }
    }
 
    public ReadWriteEntity generateReadWriteEntity(String identifier, Object value) {
        return ReadWriteEntity.builder()
                .identifier(identifier)
                //Kep中是Long类型,即:Int32,Java中的int类型
                .value(value)
                .build();
    }
}