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
package com.mes.job.opccallback;
 
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.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.kangaroohy.milo.runner.subscription.SubscriptionCallback;
import com.mes.common.config.Const;
import com.mes.edgstoragecage.entity.EdgStorageCage;
import com.mes.edgstoragecage.entity.EdgStorageCageDetails;
import com.mes.edgstoragecage.service.EdgStorageCageDetailsService;
import com.mes.edgstoragecage.service.EdgStorageCageService;
import com.mes.glassinfo.entity.GlassInfo;
import com.mes.glassinfo.service.GlassInfoService;
import com.mes.opctask.entity.EdgStorageDeviceTask;
import com.mes.opctask.entity.EdgStorageDeviceTaskHistory;
import com.mes.opctask.service.EdgStorageDeviceTaskHistoryService;
import com.mes.opctask.service.EdgStorageDeviceTaskService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
 
import javax.annotation.Resource;
import java.util.List;
 
/**
 * @Author : zhoush
 * @Date: 2024/10/10 14:13
 * @Description:
 */
@Service
@Slf4j
public class CacheGlassStartCallback implements SubscriptionCallback {
 
    private static final String EDG_STORAGE_DEVICE_ONE_TASK = "edg_storage_device_one_task";
 
    private static final String EDG_STORAGE_DEVICE_TWO_TASK = "edg_storage_device_two_task";
 
    @Resource
    EdgStorageDeviceTaskService edgStorageDeviceTaskService;
    @Resource
    GlassInfoService glassInfoService;
    @Resource
    EdgStorageCageDetailsService edgStorageCageDetailsService;
    @Resource
    EdgStorageCageService edgStorageCageService;
    @Resource
    EdgStorageDeviceTaskHistoryService edgStorageDeviceTaskHistoryService;
 
    @Value("${mes.glassGap}")
    private int glassGap;
    @Value("${mes.threshold}")
    private int threshold;
    @Value("${mes.cellLength}")
    private int cellLength;
 
    @Override
    public void onSubscribe(String identifier, Object value) {
        String tableName = identifier.contains("edg_storage_device_one_task") ? EDG_STORAGE_DEVICE_ONE_TASK : EDG_STORAGE_DEVICE_TWO_TASK;
        EdgStorageDeviceTask task = edgStorageDeviceTaskService.queryTaskMessage(tableName);
        try {
            if (task == null) {
                log.info("任务表基础数据录入失败,请检查数据是否录入成功");
                return;
            }
            int request = task.getTaskState();
            log.info("开始执行任务,任务请信息为{}", task);
            if (request == 0) {
                log.info("未收到任务请求,结束本次任务");
            } else if (request == 1) {
                //进片任务
                intoTask(task, tableName);
            } else if (request == 2) {
                //出片任务
                outTask(task, tableName);
            } else if (request == 3) {
                //直通任务
                if (!outTask(task, tableName)) {
                    intoTask(task, tableName);
                }
            } else if (request == 4) {
                log.info("将启动子改为0");
                task.setTaskRunning(Const.GLASS_CACHE_TYPE_EMPTY);
                edgStorageDeviceTaskService.updateTaskMessage(tableName, task);
            } else {
                finishTask(task, tableName);
            }
        } catch (Exception e) {
            log.info("执行任务过程中发生异常,任务字{},{}", task.getTaskState(), e.getMessage());
            log.info("将启动子改为0");
            task.setTaskState(Const.GLASS_CACHE_TYPE_EMPTY);
            edgStorageDeviceTaskService.updateTaskMessage(tableName, task);
        }
    }
 
    private boolean intoTask(EdgStorageDeviceTask task, String tableName) {
        //获取玻璃的基本信息
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, task.getGlassIdIn()));
        if (null == glassInfo) {
            log.info("进片玻璃信息不存在,玻璃id:{}", task.getGlassIdIn());
            return Boolean.FALSE;
        }
        //获取当前进片玻璃id和进片格子  相同尺寸可以放下的格子
        EdgStorageCage edgStorageCage = edgStorageCageService.getEdgStorageCageBySize(1, glassInfo.getWidth(), glassInfo.getHeight(), task.getCurrentCell());
        if (edgStorageCage == null) {
            log.info("相同尺寸可以放下的格子未找到,格子id:{}", task.getCurrentCell());
//            SELECT * from edg_storage_cage where device_id = 1 and remain_width > 1000 order by abs(slot - 10)
            List<EdgStorageCage> storageCageList = edgStorageCageService.list(new LambdaQueryWrapper<EdgStorageCage>().eq(EdgStorageCage::getDeviceId, 1)
                    .eq(EdgStorageCage::getEnableState, Const.SLOT_ON)
                    .ge(EdgStorageCage::getRemainWidth, Math.max(glassInfo.getWidth(), glassInfo.getHeight())).last("order by abs(slot - " + task.getCurrentCell() + ")"));
//            //直通任务
//            if (flag && CollectionUtil.isNotEmpty(emptyList)) {
//                return emptyList.get(0);
//            }
            if (CollectionUtil.isEmpty(storageCageList) || storageCageList.size() == 1) {
                log.info("没有多余的空格子");
                return Boolean.FALSE;
            }
            edgStorageCage = storageCageList.get(0);
        }
        log.info("4、将玻璃信息插入卧式理片笼,当前玻璃信息:{}", glassInfo);
        EdgStorageCageDetails details = new EdgStorageCageDetails();
        BeanUtils.copyProperties(glassInfo, details);
        details.setState(Const.GLASS_STATE_IN);
        details.setSlot(edgStorageCage.getSlot());
        details.setDeviceId(edgStorageCage.getDeviceId());
        edgStorageCageDetailsService.save(details);
 
        //更新任务信息
        task.setStartCell(edgStorageCage.getSlot());
        task.setTaskRunning(Const.GLASS_CACHE_TYPE_IN);
        edgStorageDeviceTaskService.updateTaskMessage(tableName, task);
        saveHistoryTask(task);
        return Boolean.TRUE;
    }
 
    private boolean outTask(EdgStorageDeviceTask task, String tableName) {
        EdgStorageCageDetails edgStorageCageDetails = null;
        //笼内是版图相差是否超过阈值
        boolean flag = queryMaxMinDiff(threshold);
        if (flag) {
            EdgStorageCageDetails minEdgDetails = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                    .inSql(EdgStorageCageDetails::getSlot, "select slot from edg_storage_cage where enable_state = " + Const.SLOT_ON)
                    .eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN)
                    .orderByAsc(EdgStorageCageDetails::getTemperingLayoutId)
                    .orderBy(Boolean.TRUE, Boolean.TRUE, EdgStorageCageDetails::getTemperingFeedSequence)
                    .last("limit 1"));
//            select * from edg_storage_cage_details where width = 551 and height = 1151 and id in (select min(id ) from edg_storage_cage_details where state = 100 group by slot )
            edgStorageCageDetails = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                    .eq(EdgStorageCageDetails::getWidth, minEdgDetails.getWidth())
                    .eq(EdgStorageCageDetails::getHeight, minEdgDetails.getHeight())
                    .inSql(EdgStorageCageDetails::getId, "select min(id) from edg_storage_cage_details where state = 100 group by slot ")
                    .last("order by abs(slot - " + task.getCurrentCell() + ")  asc limit 1")
            );
            //给直通任务
            if (null == edgStorageCageDetails && StringUtils.isNotBlank(task.getGlassIdIn())) {
                GlassInfo glassInInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
                        .eq(GlassInfo::getGlassId, task.getGlassIdIn())
                        .eq(GlassInfo::getWidth, minEdgDetails.getWidth())
                        .eq(GlassInfo::getHeight, minEdgDetails.getHeight()));
                if (null != glassInInfo) {
                    edgStorageCageDetails = new EdgStorageCageDetails();
                    BeanUtils.copyProperties(glassInInfo, edgStorageCageDetails);
                }
            }
            if (null == edgStorageCageDetails) {
                edgStorageCageDetails = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                        .eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN)
                        .eq(EdgStorageCageDetails::getSlot, minEdgDetails.getSlot())
                        .orderByAsc(EdgStorageCageDetails::getId)
                        .last("limit 1")
                );
            }
        }
        if (null == edgStorageCageDetails) {
            //        获取上次任务
//        获取历史表中上次任务最后一片尺寸
            EdgStorageDeviceTaskHistory edgeData = edgStorageDeviceTaskHistoryService.getOne(new LambdaQueryWrapper<EdgStorageDeviceTaskHistory>()
                    .eq(EdgStorageDeviceTaskHistory::getTaskState, Const.RAW_GLASS_TASK_SUCCESS)
                    .in(EdgStorageDeviceTaskHistory::getTaskType, Const.GLASS_CACHE_TYPE_OUT, Const.GLASS_CACHE_TYPE_THROUGH)
                    .orderByDesc(EdgStorageDeviceTaskHistory::getId).last("limit 1"));
            if (null != edgeData) {
                GlassInfo glassOutInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, edgeData.getGlassIdOut()));
                //笼内的玻璃的尺寸是否和上一次任务一致
                edgStorageCageDetails = edgStorageCageDetailsService.queryEdgStorageDetailsBySize(glassOutInfo.getWidth(), glassOutInfo.getHeight());
                if (null == edgStorageCageDetails && StringUtils.isNotBlank(task.getGlassIdIn())) {
                    GlassInfo glassInInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
                            .eq(GlassInfo::getGlassId, task.getGlassIdIn())
                            .eq(GlassInfo::getWidth, glassOutInfo.getWidth())
                            .eq(GlassInfo::getHeight, glassOutInfo.getHeight()));
                    if (null != glassInInfo) {
                        edgStorageCageDetails = new EdgStorageCageDetails();
                        BeanUtils.copyProperties(glassInInfo, edgStorageCageDetails);
                    }
                }
            }
        }
        if (null == edgStorageCageDetails) {
            edgStorageCageDetails = edgStorageCageDetailsService.queryEdgStorageDetailsBySize(0, 0);
        }
        if (edgStorageCageDetails == null && StringUtils.isNotBlank(task.getGlassIdIn())) {
            //和上次任务不存在相同尺寸
            GlassInfo glassInInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, task.getGlassIdIn()));
            edgStorageCageDetails = new EdgStorageCageDetails();
            BeanUtils.copyProperties(glassInInfo, edgStorageCageDetails);
        }
        if (edgStorageCageDetails == null) {
            //和上次任务不存在相同尺寸
            log.info("笼内没有玻璃了");
            return Boolean.FALSE;
        }
        int taskType = Const.GLASS_CACHE_TYPE_OUT;
        String glassId = edgStorageCageDetails.getGlassId();
        if (glassId.equals(task.getGlassIdIn())) {
            log.info("5、直通任务,将玻璃信息插入卧式理片笼,当前玻璃信息:{}", edgStorageCageDetails);
            //玻璃信息替换
            String glassIdChange = queryAndChangeGlass(glassId);
            if (StringUtils.isNotBlank(glassIdChange)) {
                edgStorageCageDetails = new EdgStorageCageDetails();
                GlassInfo one = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
                BeanUtils.copyProperties(one, edgStorageCageDetails);
            }
            EdgStorageCage storageCage = edgStorageCageService.getOne(new LambdaQueryWrapper<EdgStorageCage>().eq(EdgStorageCage::getDeviceId, 1)
                    .eq(EdgStorageCage::getEnableState, Const.SLOT_ON)
                    .ge(EdgStorageCage::getRemainWidth, cellLength).last("order by abs(slot - " + task.getCurrentCell() + ")")
                    .last("limit 1"));
            Assert.isTrue(null != storageCage, "格子已满,无法执行直通任务");
            log.info("3、查询卧式理片笼里面的空格:{}", storageCage);
            edgStorageCageDetails.setSlot(storageCage.getSlot());
            edgStorageCageDetails.setState(Const.GLASS_STATE_OUT);
            edgStorageCageDetailsService.save(edgStorageCageDetails);
            taskType = Const.GLASS_CACHE_TYPE_THROUGH;
        } else {
            log.info("5、非直通任务,将玻璃信息插入卧式理片笼,当前玻璃信息:{}", edgStorageCageDetails);
            if (!edgStorageCageDetails.getSlot().equals(task.getCurrentCell())) {
                EdgStorageCageDetails currentGlass = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                        .eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN)
                        .eq(EdgStorageCageDetails::getSlot, task.getCurrentCell()).eq(EdgStorageCageDetails::getWidth, edgStorageCageDetails.getWidth())
                        .eq(EdgStorageCageDetails::getHeight, edgStorageCageDetails.getHeight()).eq(EdgStorageCageDetails::getThickness, edgStorageCageDetails.getThickness())
                );
                if (null != currentGlass) {
                    edgStorageCageDetails = currentGlass;
                }
            }
            //玻璃信息替换
            String glassIdChange = queryAndChangeGlass(edgStorageCageDetails.getGlassId());
            //处理在卧理内的玻璃信息:笼内的数据处理
            queryEdgAndChangeGlass(edgStorageCageDetails.getGlassId(), glassIdChange);
            LambdaUpdateWrapper<EdgStorageCageDetails> wrapper = new LambdaUpdateWrapper<>();
            wrapper.eq(EdgStorageCageDetails::getGlassId, edgStorageCageDetails.getGlassId()).set(EdgStorageCageDetails::getState, Const.GLASS_STATE_OUT);
            edgStorageCageDetailsService.update(wrapper);
            log.info("5、更新出片玻璃的状态为{}", Const.GLASS_STATE_OUT);
        }
 
        //玻璃信息替换
//        String glassIdChange = queryAndChangeGlass(edgStorageCageDetails.getGlassId());
        //处理在卧理内的玻璃信息:笼内的数据处理
//        queryEdgAndChangeGlass(edgStorageCageDetails.getGlassId(), glassIdChange);
        //生成出片任务
        task.setGlassIdOut(edgStorageCageDetails.getGlassId());
        task.setStartCell(edgStorageCageDetails.getSlot());
        task.setTaskRunning(taskType);
        task.setWidth((int) edgStorageCageDetails.getWidth() * 10);
        task.setHeight((int) edgStorageCageDetails.getHeight() * 10);
        task.setThickness((int) edgStorageCageDetails.getThickness() * 10);
        task.setFilmRemove(0);
        edgStorageDeviceTaskService.updateTaskMessage(tableName, task);
        saveHistoryTask(task);
        //更新详情表任务出片中
        edgStorageCageDetailsService.update(new LambdaUpdateWrapper<EdgStorageCageDetails>()
                .set(EdgStorageCageDetails::getState, Const.GLASS_STATE_OUT)
                .eq(EdgStorageCageDetails::getGlassId, edgStorageCageDetails.getGlassId()));
        return Boolean.TRUE;
    }
 
    private boolean finishTask(EdgStorageDeviceTask task, String tableName) {
        if (task.getTaskState() <= 4) {
            log.info("有正在执行的任务,结束");
            return Boolean.FALSE;
        }
        Integer cell = task.getStartCell();
        Integer state = task.getTaskState();
        task.setTaskRunning(Const.GLASS_CACHE_TYPE_EMPTY);
        task.setTaskState(Const.GLASS_CACHE_TYPE_EMPTY);
        task.setGlassIdOut("");
        task.setStartCell(0);
        task.setWidth(0);
        task.setHeight(0);
        task.setThickness(0);
        task.setFilmRemove(0);
        edgStorageDeviceTaskService.updateTaskMessage(tableName, task);
        edgStorageDeviceTaskHistoryService.update(new LambdaUpdateWrapper<EdgStorageDeviceTaskHistory>()
                .eq(EdgStorageDeviceTaskHistory::getTaskState, Const.RAW_GLASS_TASK_NEW)
                .set(EdgStorageDeviceTaskHistory::getTaskState,
                        Const.GLASS_CACHE_TYPE_FINISH.equals(state) ? Const.RAW_GLASS_TASK_SUCCESS : Const.RAW_GLASS_TASK_FAILURE)
        );
        updateCellRemainWidth(cell);
        return Boolean.TRUE;
    }
 
    /**
     * 查询玻璃并进行交换
     *
     * @param glassId
     * @return
     */
    public String queryAndChangeGlass(String glassId) {
        GlassInfo glassInfo = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>().eq(GlassInfo::getGlassId, glassId));
//                .inSql(GlassInfo::getEngineerId, "select engineer_id from engineering where state = 1"));
        Assert.isFalse(null == glassInfo, "玻璃信息不存在");        //按照玻璃尺寸
        LambdaQueryWrapper<GlassInfo> queryWrapper = new LambdaQueryWrapper<GlassInfo>()
                .eq(GlassInfo::getWidth, glassInfo.getWidth())
                .eq(GlassInfo::getHeight, glassInfo.getHeight())
                .eq(GlassInfo::getThickness, glassInfo.getThickness())
                .eq(GlassInfo::getFilmsid, glassInfo.getFilmsid())
                .eq(GlassInfo::getFlowCardId, glassInfo.getFlowCardId())
                .eq(GlassInfo::getTotalLayer, glassInfo.getTotalLayer())
                .eq(GlassInfo::getLayer, glassInfo.getLayer())
                .eq(GlassInfo::getEngineerId, glassInfo.getEngineerId())
                .notInSql(GlassInfo::getGlassId, "select distinct glass_id from edg_storage_cage_details " +
                        "where engineer_id = '" + glassInfo.getEngineerId() + "' and width = " + glassInfo.getWidth() + " and height = " + glassInfo.getHeight()
                        + " and state != 100")
                .orderByAsc(GlassInfo::getTemperingLayoutId)
                .orderBy(Boolean.TRUE, Boolean.TRUE, GlassInfo::getTemperingFeedSequence)
                .last("Limit 1");
        GlassInfo swapGlassInfo = glassInfoService.getOne(queryWrapper);
        if (swapGlassInfo != null && !glassInfo.getGlassId().equals(swapGlassInfo.getGlassId())) {
            String swapGlassId = swapGlassInfo.getGlassId();
            log.info("将玻璃{}和玻璃{},信息互换,进玻璃 {}", glassInfo, swapGlassInfo, swapGlassInfo);
            swapGlassInfo.setGlassId(glassId);
            glassInfo.setGlassId(swapGlassId);
            glassInfoService.updateById(swapGlassInfo);
            glassInfoService.updateById(glassInfo);
            return swapGlassId;
        }
        return "";
    }
 
 
    /**
     * 查询卧式理片玻璃并进行交换
     *
     * @param glassId
     * @return
     */
    public void queryEdgAndChangeGlass(String glassId, String swapGlassId) {
        if (StringUtils.isBlank(swapGlassId)) {
            log.info("当前出笼玻璃不存在需要替换的玻璃");
            return;
        }
        //获取待出笼的玻璃
        EdgStorageCageDetails glassInfo = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                .eq(EdgStorageCageDetails::getGlassId, glassId).eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN));
//        获取待出笼的玻璃需要替换的玻璃信息
        EdgStorageCageDetails swapGlassDetailInfo = edgStorageCageDetailsService.getOne(new LambdaQueryWrapper<EdgStorageCageDetails>()
                .eq(EdgStorageCageDetails::getGlassId, swapGlassId).eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN));
 
//      玻璃小片表中玻璃已经替换,更新卧理笼内现有的准备出笼的玻璃信息,
        if (null == swapGlassDetailInfo) {
            GlassInfo glassInfoBase = glassInfoService.getOne(new LambdaQueryWrapper<GlassInfo>()
                    .eq(GlassInfo::getGlassId, glassId));
            //需要替换的玻璃为存进卧理,仅需更新当前需要出笼的玻璃信息即可
            edgStorageCageDetailsService.update(new LambdaUpdateWrapper<EdgStorageCageDetails>()
                    .eq(EdgStorageCageDetails::getGlassId, glassId)
                    .set(EdgStorageCageDetails::getTemperingLayoutId, glassInfoBase.getTemperingLayoutId())
                    .set(EdgStorageCageDetails::getTemperingFeedSequence, glassInfoBase.getTemperingFeedSequence()));
        } else {
            //需要替换的玻璃都在卧理内,按照玻璃id对调玻璃信息:对调玻璃id即可
            edgStorageCageDetailsService.update(new LambdaUpdateWrapper<EdgStorageCageDetails>()
                    .eq(EdgStorageCageDetails::getId, glassInfo.getId())
                    .set(EdgStorageCageDetails::getTemperingLayoutId, swapGlassDetailInfo.getTemperingLayoutId())
                    .set(EdgStorageCageDetails::getTemperingFeedSequence, swapGlassDetailInfo.getTemperingFeedSequence())
            );
            edgStorageCageDetailsService.update(new LambdaUpdateWrapper<EdgStorageCageDetails>()
                    .eq(EdgStorageCageDetails::getId, swapGlassDetailInfo.getId())
                    .set(EdgStorageCageDetails::getTemperingLayoutId, glassInfo.getTemperingLayoutId())
                    .set(EdgStorageCageDetails::getTemperingFeedSequence, glassInfo.getTemperingFeedSequence())
            );
        }
    }
 
    /**
     * 获取详情表内最大最小版图id的差值,判断是否出最小版图玻璃
     *
     * @return
     */
    public boolean queryMaxMinDiff(int threshold) {
        //获取笼子内最大版图id和最小版图id插值,判断是否大于阈值,大于阈值直接出最小版图玻璃
        QueryWrapper<EdgStorageCageDetails> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("max(tempering_layout_id)-min(tempering_layout_id) as diff")
                .eq("state", Const.GLASS_STATE_IN)
                .inSql("slot", "select slot from edg_storage_cage where enable_state = " + Const.SLOT_ON);
        List<Object> list = edgStorageCageDetailsService.listObjs(queryWrapper);
        //获取笼内玻璃版图差值是否大于阈值
        if (CollectionUtil.isNotEmpty(list)) {
            Long diff = (Long) list.get(0);
            return diff > threshold;
        } else {
            return Boolean.FALSE;
        }
    }
 
    public boolean saveHistoryTask(EdgStorageDeviceTask task) {
        EdgStorageDeviceTaskHistory taskHistory = new EdgStorageDeviceTaskHistory();
        BeanUtils.copyProperties(task, taskHistory);
        taskHistory.setTaskType(task.getTaskRunning());
        taskHistory.setTaskState(Const.RAW_GLASS_TASK_NEW);
        edgStorageDeviceTaskHistoryService.save(taskHistory);
        return Boolean.TRUE;
    }
 
    private boolean updateCellRemainWidth(int slot) {
        List<EdgStorageCageDetails> list = edgStorageCageDetailsService.list(new LambdaQueryWrapper<EdgStorageCageDetails>().eq(EdgStorageCageDetails::getSlot, slot)
                .eq(EdgStorageCageDetails::getState, Const.GLASS_STATE_IN));
        int remainWidth = cellLength;
        if (CollectionUtil.isNotEmpty(list)) {
            int widthTotal = (int) list.stream().map(e -> Math.max(e.getWidth(), e.getHeight()) + glassGap).mapToDouble(Double::intValue).sum();
            remainWidth = cellLength - widthTotal >= 0 ? cellLength - widthTotal : 0;
        }
        edgStorageCageService.update(new LambdaUpdateWrapper<EdgStorageCage>().
                set(EdgStorageCage::getRemainWidth, remainWidth).eq(EdgStorageCage::getSlot, slot));
        return Boolean.TRUE;
    }
}