|
|
@@ -1,20 +1,36 @@
|
|
|
package com.github.zuihou.business.controller.externalApi;
|
|
|
|
|
|
+import cn.hutool.core.util.ArrayUtil;
|
|
|
import com.alibaba.fastjson.JSONArray;
|
|
|
import com.alibaba.fastjson.JSONObject;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
|
|
import com.github.zuihou.base.R;
|
|
|
+import com.github.zuihou.business.DemoLine.DemoLineConstant;
|
|
|
+import com.github.zuihou.business.edgeLibrary.entity.StockInfo;
|
|
|
+import com.github.zuihou.business.edgeLibrary.entity.Storge;
|
|
|
+import com.github.zuihou.business.edgeLibrary.service.StockInfoService;
|
|
|
+import com.github.zuihou.business.edgeLibrary.service.StorgeService;
|
|
|
+import com.github.zuihou.business.operationManagementCenter.entity.TTask;
|
|
|
+import com.github.zuihou.business.operationManagementCenter.entity.TaskNode;
|
|
|
import com.github.zuihou.business.operationManagementCenter.service.OrderService;
|
|
|
+import com.github.zuihou.business.operationManagementCenter.service.TaskNodeService;
|
|
|
+import com.github.zuihou.business.operationManagementCenter.service.TaskService;
|
|
|
import com.github.zuihou.business.productionReadyCenter.entity.AAutoNodeLog;
|
|
|
import com.github.zuihou.business.productionReadyCenter.service.AAutoNodeLogService;
|
|
|
import com.github.zuihou.business.productionResourceCenter.dao.ProductionresourceBizMapper;
|
|
|
+import com.github.zuihou.business.productionResourceCenter.service.ProductionresourcePositionService;
|
|
|
+import com.github.zuihou.business.util.MsgUtil;
|
|
|
+import com.github.zuihou.common.util.DateUtil;
|
|
|
import com.github.zuihou.context.BaseContextHandler;
|
|
|
import com.github.zuihou.database.mybatis.conditions.query.LbqWrapper;
|
|
|
import com.github.zuihou.log.annotation.SysLog;
|
|
|
import com.github.zuihou.tenant.entity.Productionresource;
|
|
|
import com.github.zuihou.tenant.service.ProductionresourceService;
|
|
|
+import com.google.common.collect.Maps;
|
|
|
import io.swagger.annotations.Api;
|
|
|
import io.swagger.annotations.ApiOperation;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
+import org.apache.commons.compress.utils.Lists;
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
import org.springframework.validation.annotation.Validated;
|
|
|
@@ -24,9 +40,9 @@ import org.springframework.web.bind.annotation.RequestMapping;
|
|
|
import org.springframework.web.bind.annotation.RestController;
|
|
|
|
|
|
import java.time.LocalDateTime;
|
|
|
-import java.util.HashMap;
|
|
|
-import java.util.List;
|
|
|
-import java.util.Map;
|
|
|
+import java.util.*;
|
|
|
+import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* <p>
|
|
|
@@ -53,6 +69,18 @@ public class SynProductionStatus {
|
|
|
private OrderService orderService;
|
|
|
@Autowired
|
|
|
private AAutoNodeLogService autoNodeLogService;
|
|
|
+ @Autowired
|
|
|
+ private TaskService taskService;
|
|
|
+ @Autowired
|
|
|
+ private TaskNodeService taskNodeService;
|
|
|
+ @Autowired
|
|
|
+ private StockInfoService stockInfoService;
|
|
|
+ @Autowired
|
|
|
+ private StorgeService storgeService;
|
|
|
+ @Autowired
|
|
|
+ private ProductionresourcePositionService productionresourcePositionService;
|
|
|
+ @Autowired
|
|
|
+ private MsgUtil msgUtil;
|
|
|
|
|
|
@ApiOperation(value = "设备状态同步", notes = "设备状态同步")
|
|
|
@PostMapping("/synProductionStatus")
|
|
|
@@ -99,9 +127,126 @@ public class SynProductionStatus {
|
|
|
}
|
|
|
|
|
|
// 状态变化重调度
|
|
|
- if(!isAlarm && networkChanged){
|
|
|
+ if(!isAlarm && !networkChanged){
|
|
|
//orderService.reschedulingPlanTasks();
|
|
|
+ this.taskSchedule();
|
|
|
}
|
|
|
return R.success();
|
|
|
}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 上下料站任务权限自动调整
|
|
|
+ *
|
|
|
+ */
|
|
|
+ public void taskSchedule(){
|
|
|
+ LbqWrapper<com.github.zuihou.business.productionResourceCenter.entity.Productionresource> lbqWrapper = new LbqWrapper<com.github.zuihou.business.productionResourceCenter.entity.Productionresource>();
|
|
|
+ lbqWrapper.eq(com.github.zuihou.business.productionResourceCenter.entity.Productionresource::getStatus, "1").ne(com.github.zuihou.business.productionResourceCenter.entity.Productionresource::getOnlineStatus, "0").isNotNull(com.github.zuihou.business.productionResourceCenter.entity.Productionresource::getModeSpecification);
|
|
|
+ //获取全部加工在线的加工设备
|
|
|
+ List<com.github.zuihou.business.productionResourceCenter.entity.Productionresource> macProductionResources = productionresourceBizMapper.selectList(lbqWrapper);
|
|
|
+ //获取未处于加工状态的加工设备
|
|
|
+ List<com.github.zuihou.business.productionResourceCenter.entity.Productionresource> bizProductionResources = macProductionResources.stream().filter(item->item.getOnlineStatus().equals("1")).collect(Collectors.toList());
|
|
|
+
|
|
|
+ if(bizProductionResources.size()>0){
|
|
|
+ List<Long> macResourceIds = macProductionResources.stream().map(com.github.zuihou.business.productionResourceCenter.entity.Productionresource::getId).collect(Collectors.toList());
|
|
|
+ List<Long> resourceIds = bizProductionResources.stream().map(com.github.zuihou.business.productionResourceCenter.entity.Productionresource::getId).collect(Collectors.toList());
|
|
|
+ //获取线边库加工任务列表(模糊匹配舱体和框体线边库)
|
|
|
+ List<Long> storgeIds = storgeService.list(new LbqWrapper<Storge>().eq(Storge::getLockStatus, "1").like(Storge::getName, "T_库位")).stream().map(Storge::getId).collect(Collectors.toList());
|
|
|
+ //获取线边库零件编号
|
|
|
+ List<String> completeBatchNos = stockInfoService.list(new LbqWrapper<StockInfo>().eq(StockInfo::getGoodsType, "4").in(StockInfo::getStorgeId, storgeIds)).stream().map(StockInfo::getCompleteBatchNo).collect(Collectors.toList());
|
|
|
+ //获取线边库满足条件的节点
|
|
|
+ List<TaskNode> taskNodeList = completeBatchNos.size()>0 ? taskNodeService.list(new LbqWrapper<TaskNode>().eq(TaskNode::getExeStatus,"2").in(TaskNode::getTargetResourceId, macResourceIds).in(TaskNode::getCompleteBatchNo, completeBatchNos).eq(TaskNode::getNodeName, "放本序设备")) : Lists.newArrayList();
|
|
|
+ //获得线边库加工设备列表
|
|
|
+ //Map<Long, List<TaskNode>> taskNodeMap = taskNodeList.stream().filter(item-> resourceIds.contains(item.getTargetResourceId())).collect(Collectors.groupingBy(TaskNode::getResourceId, LinkedHashMap::new, Collectors.toList()));
|
|
|
+
|
|
|
+ if(taskNodeList != null && taskNodeList.size() > 0) {
|
|
|
+ List<TTask> updatedTaskList = Lists.newArrayList();
|
|
|
+ List<TaskNode> updatedTaskNodeList = taskNodeList.stream().filter(item-> bizProductionResources.stream().anyMatch(productionresource->{
|
|
|
+ //线边库节点的目标设备
|
|
|
+ com.github.zuihou.business.productionResourceCenter.entity.Productionresource device = productionresourceBizMapper.selectById(item.getTargetResourceId());
|
|
|
+ List targetList = productionresourcePositionService.getFreeProductionresourcePositionByIds(new String[]{productionresource.getId().toString()});
|
|
|
+ item.setTargetResourceId(productionresource.getId());
|
|
|
+ return device.getModeSpecification().equals(productionresource.getModeSpecification()) && targetList.size()>0 && !device.getId().equals(productionresource.getId());
|
|
|
+ })).collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 执行任务和节点设备更新
|
|
|
+ if(updatedTaskNodeList.size()>0){
|
|
|
+ TaskNode updatedNode = updatedTaskNodeList.get(0);
|
|
|
+ //只默认取当前第一条任务
|
|
|
+ TTask updatedTask = taskService.getById(updatedNode.getTaskId());
|
|
|
+ com.github.zuihou.business.productionResourceCenter.entity.Productionresource targetDevice = productionresourceBizMapper.selectById(updatedNode.getTargetResourceId());
|
|
|
+ //更新缓存中哈默上传文件路径IP信息
|
|
|
+ if(targetDevice.getModeSpecification().equals("HEIDENHAIN")){
|
|
|
+ String uploadInfo = msgUtil.redis_get(DemoLineConstant.DEMOLINE_HEIDENHAIN_FILE_URL+"_"+updatedTask.getId())!=null? msgUtil.redis_get(DemoLineConstant.DEMOLINE_HEIDENHAIN_FILE_URL+"_"+updatedTask.getId()).toString(): null;
|
|
|
+ if(StringUtils.isNotEmpty(uploadInfo)){
|
|
|
+ JSONObject jsonObject = JSONObject.parseObject(uploadInfo);
|
|
|
+ jsonObject.put("url", targetDevice.getIp());
|
|
|
+ msgUtil.redis_set(DemoLineConstant.DEMOLINE_HEIDENHAIN_FILE_URL+"_"+updatedTask.getId(), jsonObject.toJSONString(), 30, TimeUnit.DAYS);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 执行任务和节点设备更新
|
|
|
+ if(updatedTask!=null && updatedTask.getResourceId() != null){
|
|
|
+ updatedTask.setResourceId(updatedNode.getTargetResourceId());
|
|
|
+ JSONObject dyChangedInfo = new JSONObject();
|
|
|
+ List<TaskNode> taskNodes = taskNodeService.list(new LbqWrapper<TaskNode>().eq(TaskNode::getTaskId, updatedTask.getId()));
|
|
|
+ //更新节点目的设备
|
|
|
+ taskNodes.stream().forEach(taskNode->{
|
|
|
+ if(null != taskNode.getTargetResourceId()){
|
|
|
+ if(taskNode.getResourceId().equals(taskNode.getTargetResourceId())){
|
|
|
+ if(!dyChangedInfo.containsKey("fromResource")){
|
|
|
+ dyChangedInfo.put("fromResource", taskNode.getResourceId());
|
|
|
+ }
|
|
|
+ taskNode.setResourceId(updatedTask.getResourceId());
|
|
|
+ }
|
|
|
+ taskNode.setTargetResourceId(updatedTask.getResourceId());
|
|
|
+ }
|
|
|
+ });
|
|
|
+ taskService.updateById(updatedTask);
|
|
|
+ taskNodeService.updateBatchById(taskNodes);
|
|
|
+ dyChangedInfo.put("toResource", updatedTask.getResourceId());
|
|
|
+ dyChangedInfo.put("time", DateUtil.formatTime(new Date()));
|
|
|
+
|
|
|
+ // 缓存数据更新
|
|
|
+ //TaskNode currTaskNode = taskNodeService.getOne(new LbqWrapper<TaskNode>().eq(TaskNode::getTaskId,updatedTask.getId()).eq(TaskNode::getExeStatus,"2"));
|
|
|
+ msgUtil.redis_set(DemoLineConstant.DEMOLINE_RESOURCE_DY_CHANGE +"_"+updatedTask.getId(), dyChangedInfo.toJSONString(), 1, TimeUnit.DAYS);
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ //获取即将加工设备列表
|
|
|
+ List<TTask> tasks = taskService.list(new LbqWrapper<TTask>().eq(TTask::getStatus,"2").like(TTask::getProcedureName,"上料"));
|
|
|
+ Map<Long, List<TTask>> nextTaskMap = tasks.stream().map(item -> {
|
|
|
+ return taskService.getNNextTask(item, 1);
|
|
|
+ }).filter(item -> resourceIds.contains(item.getResourceId())).collect(Collectors.groupingBy(TTask::getResourceId, LinkedHashMap::new, Collectors.toList()));
|
|
|
+
|
|
|
+ if (!nextTaskMap.isEmpty() && nextTaskMap.size() > 0 ) {
|
|
|
+ //获取当前排产设备数量最少的加工设备
|
|
|
+ List<TTask> priorityTasks = nextTaskMap.entrySet().stream().map(m -> m.getValue()).min(Comparator.comparingInt(item -> {
|
|
|
+ return item.size();
|
|
|
+ })).get();
|
|
|
+
|
|
|
+ List<TTask> maxTasks = nextTaskMap.entrySet().stream().map(m -> m.getValue()).max(Comparator.comparingInt(item -> {
|
|
|
+ return item.size();
|
|
|
+ })).get();
|
|
|
+
|
|
|
+ //单一设备任务执行完成而设备排产数量超出空闲设备数量
|
|
|
+ if (priorityTasks.size() ==0 && maxTasks.size()>bizProductionResources.size()) {
|
|
|
+ //设备无执行任务重排产
|
|
|
+ orderService.reschedulingPlanTasks();
|
|
|
+ } else {
|
|
|
+ //实时调整上料任务的优先级
|
|
|
+ TTask priorityTask = priorityTasks.stream().sorted(Comparator.comparing(TTask::getPrority, Comparator.reverseOrder()).thenComparing(TTask::getProcedureOrder, Comparator.reverseOrder()).thenComparing(TTask::getExpectStartTime)).collect(Collectors.toList()).get(0);
|
|
|
+ int procedureOrder = taskService.getOne(new LbqWrapper<TTask>().select(TTask::getProcedureOrder).eq(TTask::getResourceId, priorityTask.getResourceId()).orderByDesc(TTask::getProcedureOrder).last("limit 1")).getProcedureOrder();
|
|
|
+ UpdateWrapper<TTask> updateWrapper = new UpdateWrapper<TTask>();
|
|
|
+ TTask currTask = taskService.getNNextTask(priorityTask, -1);
|
|
|
+ updateWrapper.lambda().eq(TTask::getId, currTask.getId()).set(TTask::getProcedureOrder, ++procedureOrder);
|
|
|
+ taskService.update(null, updateWrapper);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
}
|