ZengTao
2025-04-01 a52b87449e493d4312cc81c33a4169eb6be3c144
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
package com.mes.job;
 
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.mes.common.config.Const;
import com.mes.engineering.entity.Engineering;
import com.mes.engineering.mapper.EngineeringMapper;
import com.mes.opctask.entity.LoadGlassDeviceTask;
import com.mes.opctask.entity.LoadGlassDeviceTaskHistory;
import com.mes.opctask.service.LoadGlassDeviceTaskHistoryService;
import com.mes.opctask.service.LoadGlassDeviceTaskService;
import com.mes.pp.entity.OptimizeProject;
import com.mes.pp.service.OptimizeProjectService;
import com.mes.rawglassdetails.entity.RawGlassStorageDetails;
import com.mes.rawglassdetails.service.RawGlassStorageDetailsService;
import com.mes.uppattenusage.entity.UpPattenUsage;
import com.mes.uppattenusage.entity.vo.UpPattenUsageVO;
import com.mes.uppattenusage.mapper.UpPattenUsageMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
 
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
 
/**
 * @Author : zhoush
 * @Date: 2024/10/23 14:30
 * @Description:
 */
@Component
@Slf4j
public class OpcLoadGlassTask {
 
    @Resource
    private EngineeringMapper engineeringMapper;
 
    @Resource
    private LoadGlassDeviceTaskService loadGlassDeviceTaskService;
    @Resource
    private RawGlassStorageDetailsService rawGlassStorageDetailsService;
    @Resource
    private LoadGlassDeviceTaskHistoryService loadGlassDeviceTaskHistoryService;
    @Resource
    private UpPattenUsageMapper upPattenUsageMapper;
    @Resource
    private OptimizeProjectService optimizeProjectService;
 
    private static final List<Integer> LOAD_STATION_01 = Arrays.asList(101, 102);
    private static final List<Integer> LOAD_STATION_02 = Arrays.asList(103, 104);
 
 
    private static final Integer LOAD_GLASS_ONE_DEVICE = 5;
    private static final Integer LOAD_GLASS_TWO_DEVICE = 6;
    private static final String LOAD_GLASS_DEVICE_ONE_TASK = "load_glass_device_one_task";
 
    private static final String LOAD_GLASS_DEVICE_TWO_TASK = "load_glass_device_two_task";
 
    //设备id   上片位信息   任务表不一致   历史任务表公用一张 新增任务/任务结束,后会在历史表中新增一条记录并在结束后更新任务  一个任务即可
    //定时任务扫描上片位有没有原片
    //1、是否有在执行的任务
    //2、1号上片位是否有原片,原片尺寸是否和上片待上片的尺寸一致
    //3、1号无原片,且没有架子,2号上片位尺寸是否和带上片尺寸一致
    //4、不一致可能出现玻璃破损导致的上一架原片数量不够
    @Scheduled(fixedDelay = 5000)
    public void opcLoadGlassOne() {
        opcLoadGlassChild(LOAD_GLASS_DEVICE_ONE_TASK, LOAD_GLASS_ONE_DEVICE);
    }
 
    @Scheduled(fixedDelay = 5000)
    public void opcLoadGlassTwo() {
        opcLoadGlassChild(LOAD_GLASS_DEVICE_TWO_TASK, LOAD_GLASS_TWO_DEVICE);
    }
 
    @Scheduled(fixedDelay = 5000)
    public void opcLoadGlassOneFinish() {
        opcLoadGlassFinishChid(LOAD_GLASS_DEVICE_ONE_TASK, LOAD_GLASS_ONE_DEVICE);
    }
 
    @Scheduled(fixedDelay = 5000)
    public void opcLoadGlassTwoFinish() {
        opcLoadGlassFinishChid(LOAD_GLASS_DEVICE_TWO_TASK, LOAD_GLASS_TWO_DEVICE);
    }
 
    /**
     * 定时任务扫码已完成上片的工程,将工程状态改为已完成,同步pp表的工程表,状态改为300
     */
    @Scheduled(fixedDelay = 5000)
    public void updateEngineerState() {
        log.info("修改已完成工程状态任务开始执行");
        List<Engineering> engineerings = engineeringMapper.selectList(new LambdaQueryWrapper<Engineering>().eq(Engineering::getState, Const.ENGINEERING_RUNNING));
        for (Engineering engineering : engineerings) {
            Integer count = upPattenUsageMapper.selectCount(new LambdaQueryWrapper<UpPattenUsage>()
                    .eq(UpPattenUsage::getEngineeringId, engineering.getEngineerId()).ne(UpPattenUsage::getState, Const.LOAD_RAW_GLASS_SUCCESS));
            if (count == 0) {
                engineeringMapper.update(null, new LambdaUpdateWrapper<Engineering>().set(Engineering::getState, Const.ENGINEERING_SUCCESS)
                        .eq(Engineering::getEngineerId, engineering.getEngineerId()));
                optimizeProjectService.update(null, new LambdaUpdateWrapper<OptimizeProject>().set(OptimizeProject::getState, 300)
                        .eq(OptimizeProject::getProjectNo, engineering.getEngineerId()));
            }
        }
    }
 
    private void opcLoadGlassChild(String tableName, Integer deviceId) {
        Engineering engineering = engineeringMapper.selectOne(new LambdaQueryWrapper<Engineering>()
                .eq(Engineering::getState, Const.ENGINEERING_RUNNING).eq(Engineering::getStationCell, deviceId));
        if (null == engineering) {
            log.info("{}上片线,没有工程任务", deviceId);
            return;
        }
        //任务暂停
        LoadGlassDeviceTask task = loadGlassDeviceTaskService.queryTaskMessage(tableName);
        if (0 == task.getInkageState()) {
            log.info("{}上片线,处于离线状态:{},结束本地上片请求", deviceId, task.getInkageState());
            return;
        }
        if (task.getTaskRunning().equals(Const.ENGINEERING_RUNNING)) {
            log.info("{}上片线,有正在执行的任务,结束本地上片请求", deviceId);
            return;
        }
        List<UpPattenUsageVO> pattenUsageList = upPattenUsageMapper.queryRawGlassByEngineeringId(engineering.getEngineerId());
        log.info("按照当前获取到正在需要上片的原片信息有:{}", pattenUsageList);
        if (CollectionUtils.isEmpty(pattenUsageList)) {
            log.info("当前工程需要上片的原片信息为空,任务已结束");
            //todo:是否将工程状态改为已完成
            return;
        }
        Map<String, List<UpPattenUsageVO>> upListMap = pattenUsageList.stream()
                .collect(Collectors.groupingBy(UpPattenUsageVO::getGroupNumber));
        log.info("获取当前需要上片的原片数据");
        List<UpPattenUsageVO> usageVOS = upListMap.get("1");
//        获取1号上片位是有架子且有玻璃
        List<Integer> loadStation = LOAD_GLASS_DEVICE_ONE_TASK.equals(tableName) ? LOAD_STATION_01 : LOAD_STATION_02;
        List<RawGlassStorageDetails> loadStationList = rawGlassStorageDetailsService.list(new LambdaQueryWrapper<RawGlassStorageDetails>()
                .inSql(RawGlassStorageDetails::getSlot, "select slot from raw_glass_storage_station where enable_state = 1")
                .in(RawGlassStorageDetails::getState, Const.RAW_GLASS_STATE_IN_ALL)
                .eq(RawGlassStorageDetails::getDeviceId, deviceId));
        if (CollectionUtils.isEmpty(loadStationList)) {
            log.info("当前上片线路两个上片位都没有原片信息,结束本次上片任务,等待仓储调度任务");
            return;
        }
        RawGlassStorageDetails oneLoadStation = loadStationList.stream().filter(e -> e.getSlot().equals(loadStation.get(0))).findFirst().orElse(null);
        if (null == oneLoadStation) {
            RawGlassStorageDetails twoLoadStation = loadStationList.stream().filter(e -> e.getSlot().equals(loadStation.get(1))).findFirst().orElse(null);
            if (!compareRawSize(usageVOS.get(0), twoLoadStation)) {
                log.info("二号上片位有架子,原片数量为0或者原片信息与待上片尺寸不一致,结束本次上片任务,等待仓储调度任务");
                return;
            }
            int number = Math.min(twoLoadStation.getRemainQuantity(), usageVOS.size());
            //生成上片任务
            task.setTotalCount(number);
            task.setTaskRunning(Const.ENGINEERING_RUNNING);
            task.setRawGlassWidth((int) usageVOS.get(0).getWidth());
            task.setRawGlassHeight((int) usageVOS.get(0).getHeight());
            task.setSlot(loadStation.get(1));
            loadGlassDeviceTaskService.updateTaskMessage(tableName, task);
            saveHistoryTask(task, deviceId);
            return;
        }
        //尺寸不一样或者原片数量大于0
        if (!compareRawSize(usageVOS.get(0), oneLoadStation)) {
            log.info("一号上片位有架子,原片数量为0或者原片信息与待上片尺寸不一致,结束本次上片任务,等待仓储调度任务");
            return;
        }
        //生成上片任务
        int number = Math.min(oneLoadStation.getRemainQuantity(), usageVOS.size());
        task.setTotalCount(number);
        task.setTaskRunning(Const.ENGINEERING_RUNNING);
        task.setRawGlassWidth((int) usageVOS.get(0).getWidth());
        task.setRawGlassHeight((int) usageVOS.get(0).getHeight());
        task.setSlot(loadStation.get(0));
        loadGlassDeviceTaskService.updateTaskMessage(tableName, task);
        saveHistoryTask(task, deviceId);
    }
 
    private void opcLoadGlassFinishChid(String tableName, Integer deviceId) {
        LoadGlassDeviceTask task = loadGlassDeviceTaskService.queryTaskMessage(tableName);
        if (task.getTaskRunning().equals(Const.ENGINEERING_NEW)) {
            log.info("无任务,结束");
            return;
        }
        if (task.getTaskState() <= 1) {
            log.info("任务正在执行,结束");
            return;
        }
        //获取任务完成情况
//         已完成数量  破损数量
        Integer finishCount = task.getFinishCount();
        Integer damageCount = task.getDamageCount();
 
        //更新当前架子上的原片剩余情况
        rawGlassStorageDetailsService.update(new UpdateWrapper<RawGlassStorageDetails>()
                .inSql("slot", "select slot from raw_glass_storage_station where enable_state = 1")
                .eq("slot", task.getSlot())
                .eq("state", Const.RAW_GLASS_STATE_IN)
                .setSql("remain_quantity = remain_quantity - " + (finishCount + damageCount)));
        //更新工程下的原片数量 todo:sql待优化
 
        if (finishCount > 0) {
            List<Integer> ids = upPattenUsageMapper.queryFinishByEngineering(deviceId, finishCount);
            upPattenUsageMapper.update(null, new LambdaUpdateWrapper<UpPattenUsage>()
                    .in(UpPattenUsage::getId, ids)
                    .set(UpPattenUsage::getState, Const.LOAD_RAW_GLASS_SUCCESS));
        }
        //任务表数据情况
        task.setTaskRunning(0);
        task.setTotalCount(0);
        task.setRawGlassWidth(0);
        task.setRawGlassHeight(0);
        task.setSlot(0);
        loadGlassDeviceTaskService.updateTaskMessage(tableName, task);
        loadGlassDeviceTaskHistoryService.update(new LambdaUpdateWrapper<LoadGlassDeviceTaskHistory>()
                .set(LoadGlassDeviceTaskHistory::getTaskState, Const.RAW_GLASS_TASK_SUCCESS)
                .eq(LoadGlassDeviceTaskHistory::getTaskState, Const.RAW_GLASS_TASK_NEW)
                .eq(LoadGlassDeviceTaskHistory::getStation, deviceId)
        );
    }
 
    private boolean saveHistoryTask(LoadGlassDeviceTask task, Integer deviceId) {
        LoadGlassDeviceTaskHistory taskHistory = new LoadGlassDeviceTaskHistory();
        BeanUtils.copyProperties(task, taskHistory);
        taskHistory.setStation(deviceId);
        taskHistory.setCreateTime(new Date());
        taskHistory.setTaskState(Const.RAW_GLASS_TASK_NEW);
        loadGlassDeviceTaskHistoryService.save(taskHistory);
        return Boolean.TRUE;
    }
 
    /**
     * 尺寸一样并且原片数量大于0
     *
     * @param upPattenUsage
     * @param details
     * @return
     */
    private boolean compareRawSize(UpPattenUsage upPattenUsage, RawGlassStorageDetails details) {
        boolean flag = upPattenUsage.getWidth() == details.getPatternWidth() && upPattenUsage.getHeight() == details.getPatternHeight() &&
                upPattenUsage.getThickness() == details.getPatternThickness() && upPattenUsage.getFilmsId().equals(details.getFilmsId());
        return flag && details.getRemainQuantity() > 0;
    }
 
}