浏览代码

Merge remote-tracking branch 'origin/master' into master

姚云青 3 年之前
父节点
当前提交
a99fcdce18

+ 3 - 4
imcs-admin-boot/imcs-authority-server/src/main/java/com/github/zuihou/job/DashboardJob.java

@@ -147,10 +147,9 @@ public class DashboardJob {
             LbqWrapper<AAutoNodeLog> warnWrapper = warnWrap.lambda();
             //Date start = new Date();
             //警报弹框只执行一次
-            //返回还未处理、执行状态为失败,并且还未推送的日志记录
-            warnWrapper.eq(AAutoNodeLog::getExeResult,"0").eq(AAutoNodeLog::getStatus,"0")
-                    //.eq(AAutoNodeLog::getSendStatus,"0")
-                    .orderByDesc(AAutoNodeLog::getCreateTime);
+            //返回还未处理、执行状态为失败、需要人工处理,并且还未推送的日志记录
+            warnWrapper.eq(AAutoNodeLog::getExeResult,"0").eq(AAutoNodeLog::getStatus,"0").eq(AAutoNodeLog::getManual, "1")
+                       .orderByDesc(AAutoNodeLog::getCreateTime);
             IPage<AAutoNodeLog> warnData = autoNodeLogService.pageList(new Page<AAutoNodeLog>(1L, 5), warnWrapper);
 
             Map warnMap = Maps.newHashMap();

+ 34 - 13
imcs-admin-boot/imcs-business-biz/src/main/java/com/github/zuihou/business/mq/TaskWorkNode.java

@@ -7,6 +7,10 @@ import com.github.zuihou.base.R;
 import com.github.zuihou.business.DemoLine.DemoCacheKey;
 import com.github.zuihou.business.DemoLine.DemoLineConstant;
 import com.github.zuihou.business.DemoLine.YunjianConstant;
+import com.github.zuihou.business.dispatchRecord.entity.DispatchException;
+import com.github.zuihou.business.dispatchRecord.entity.DispatchRecord;
+import com.github.zuihou.business.dispatchRecord.service.DispatchExceptionService;
+import com.github.zuihou.business.dispatchRecord.service.DispatchRecordService;
 import com.github.zuihou.business.edgeLibrary.dao.StockInfoMapper;
 import com.github.zuihou.business.edgeLibrary.dao.StorgeMapper;
 import com.github.zuihou.business.edgeLibrary.entity.StockInfo;
@@ -48,6 +52,8 @@ import com.github.zuihou.context.BaseContextHandler;
 import com.github.zuihou.database.mybatis.conditions.Wraps;
 import com.github.zuihou.database.mybatis.conditions.query.LbqWrapper;
 import com.github.zuihou.database.mybatis.conditions.query.QueryWrap;
+import com.github.zuihou.exception.BizException;
+import com.github.zuihou.msgs.service.MsgsCenterInfoService;
 import com.github.zuihou.tenant.entity.Module;
 import com.github.zuihou.tenant.entity.ModuleInstruction;
 import com.github.zuihou.tenant.service.ModuleInstructionService;
@@ -142,6 +148,7 @@ public class TaskWorkNode {
     @Autowired
     private BBomMapper bBomMapper;
 
+
     //总控端口
     private final String ZK_port = "120";
 
@@ -153,6 +160,7 @@ public class TaskWorkNode {
 
     public void updateTaskStatusJob(String data) throws InterruptedException {
         JSONObject jsonObject = JSONObject.parseObject(data);
+        System.out.println("返回请求数据: "+data);
         String taskNodeId = jsonObject.getString("taskNodeId");
         //业务类型-1、是普通的节点类型,2-是线边库轮询
         String bizType = jsonObject.getString("bizType");
@@ -160,7 +168,7 @@ public class TaskWorkNode {
         //多产品搬运类型
         String carryType = jsonObject.getString("carryType");
         if(StringUtil.isEmpty(taskNodeId) || StringUtil.isEmpty(bizType)){
-            throw new InterruptedException("数据传输有误");
+            throw new InterruptedException("全局通知异常");
         }
         logger.info("=======================" + taskNodeId);
         BaseContextHandler.setTenant("0000");
@@ -168,11 +176,12 @@ public class TaskWorkNode {
         TaskNode taskNode = taskNodeService.getById(taskNodeId);
 //
         if (taskNode == null || taskNode.getTaskId()== null) {
-            throw new InterruptedException("当前任务节点为空");
+            //模拟处理数据
+            throw new BizException(-1, "当前任务节点为空");
         }
         TTask tTask = taskMapper.selectById(taskNode.getTaskId());
         if (tTask == null || tTask.getStatus() == "3") {
-            throw new InterruptedException("当前任务为空");
+            throw new BizException(-1, "当前任务为空");
         }
 //        //获取配置序数据
         //任务初始化判断
@@ -234,6 +243,7 @@ public class TaskWorkNode {
                 queryMap.put("zone",zZone);
                 //运行条件验证
                 Map conMap = checkCon(taskNode, tTask, queryMap);
+                msgUtil.redis_set_map(CacheKey.TASK_CURRENT_NODE_CONDITION+ "_" + taskNode.getId(), conMap);
 
                 if("03".equals(taskNode.getInterfaceType())){
                     TaskNode beforTaskNode = taskNodeService.getNextNTaskNode(taskNode,-1);
@@ -249,34 +259,45 @@ public class TaskWorkNode {
                     HttpHeaders headers = new HttpHeaders();
                     headers.setContentType(MediaType.parseMediaType("application/json;charset=UTF-8"));
                     String jsonParam = getRequestParam(conMap);
+                    //缓存执行当前节点传参
+                    msgUtil.redis_set(CacheKey.TASK_CURRENT_NODE_PARAMS+"_" + taskNode.getId(), jsonParam);
                     HttpEntity<String> formEntity = new HttpEntity<String>(jsonParam, headers);
-                    //动态调用接口
+
+                    //动态调用接口和新增指令执行时间
+                    log.setMethod(conMap.get("method").toString()).setExecuteTime(new Date());
                     String instructionUrl = DictionaryKey.INSTRUCTION_URL +"/api/"+ conMap.get("method").toString() ;
                     logger.info("instructionUrl=", instructionUrl);
                     logger.info("jsonParam=", jsonParam);
                     returnData = restTemplate.postForObject(instructionUrl, formEntity, String.class);
+
                     logger.info("returnData=", returnData);
                 }
             }
-        } catch (Exception e) {
+        } catch (BizException e) {
             e.printStackTrace();
             JSONObject errJsonObject = new JSONObject();
+            errJsonObject.put("code", "2");
             errJsonObject.put("msg", e.getMessage());
             returnData = errJsonObject.toJSONString();
             logger.error("调用接口发生异常" + e.getMessage());
-            log.setExeResult("0").setFeedback(e.getMessage());
         }
         logger.info("===============================接口返回" + returnData);
         JSONObject retJson = JSONObject.parseObject(returnData);
-//        if(jsonObject.getString("Code").trim() == "1") {
+        String code = retJson.getString("code").trim();
+        if(code == "1") {
             //回调处理
-
             taskNode.setExeStatus("3").setEndTime(new Date()).setExeResult("1");
             taskNodeService.updateAllById(taskNode);
-            log.setExeStatus("3").setEndTime(new Date()).setExeResult("1");
-//        }else{
-//            log.setExeResult("0").setFeedback(jsonObject.getString("Msg"));
-//        }
+            log.setExeStatus("3").setEndTime(new Date()).setExeResult("1").setFeedback("");
+            msgUtil.redis_del(CacheKey.TASK_CURRENT_NODE_CONDITION + "_" + taskNode.getId());
+            msgUtil.redis_del(CacheKey.TASK_CURRENT_NODE_PARAMS + "_" + taskNode.getId());
+        }else if(code == "0"){
+            //需要人工处理解决警报异常
+            log.setExeResult("0").setManual("1").setFeedback(retJson.getString("msg"));
+        }else if(code == "2"){
+            //执行异常处理(无须人工处理和警报提示)
+            log.setExeResult("0").setManual("0").setFeedback(retJson.getString("msg"));
+        }
         if(log.getId()==null){
             autoNodeLogService.save(log);
         }else{
@@ -392,7 +413,7 @@ public class TaskWorkNode {
      * @return
      * @throws Exception
      */
-     public Map checkCon(TaskNode taskNode, TTask task, Map<String, Object> dataMap) throws Exception {
+     public Map checkCon(TaskNode taskNode, TTask task, Map<String, Object> dataMap) throws BizException, InterruptedException {
         Map map = getCheckCon(taskNode, task, dataMap);
         boolean b = (boolean) map.get("result");
         if (!b) {

+ 182 - 8
imcs-admin-boot/imcs-business-biz/src/main/java/com/github/zuihou/business/operationManagementCenter/service/impl/TaskServiceImpl.java

@@ -1,6 +1,8 @@
 package com.github.zuihou.business.operationManagementCenter.service.impl;
 
 import cn.hutool.core.collection.CollectionUtil;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.github.zuihou.authority.dao.auth.StationUserLoginInfoMapper;
 import com.github.zuihou.authority.dao.auth.UserMapper;
@@ -15,26 +17,23 @@ import com.github.zuihou.business.aps.algorithm.ga.GAScheduler;
 import com.github.zuihou.business.aps.instance.domain.basicdata.*;
 import com.github.zuihou.business.classSchedule.dao.ScheduleUserDateMapper;
 import com.github.zuihou.business.edgeLibrary.dao.StockInfoMapper;
+import com.github.zuihou.business.edgeLibrary.dao.StockLogMapper;
 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.StockLogService;
 import com.github.zuihou.business.edgeLibrary.service.StorgeService;
-import com.github.zuihou.business.operationManagementCenter.dao.OrderMapper;
-import com.github.zuihou.business.operationManagementCenter.dao.PlanMapper;
-import com.github.zuihou.business.operationManagementCenter.dao.TTaskMapper;
-import com.github.zuihou.business.operationManagementCenter.dao.WorkpieceMapper;
+import com.github.zuihou.business.operationManagementCenter.dao.*;
 import com.github.zuihou.business.operationManagementCenter.entity.*;
 import com.github.zuihou.business.operationManagementCenter.service.TaskService;
-import com.github.zuihou.business.productionReadyCenter.dao.AutoNodeMapper;
-import com.github.zuihou.business.productionReadyCenter.dao.BomProcedureProductionresourceMapper;
-import com.github.zuihou.business.productionReadyCenter.dao.BomProcedureProgramMapper;
+import com.github.zuihou.business.productionReadyCenter.dao.*;
 import com.github.zuihou.business.productionReadyCenter.entity.*;
 import com.github.zuihou.business.productionResourceCenter.dao.ProductionresourceBizMapper;
 import com.github.zuihou.business.productionResourceCenter.dao.ProductionresourcePositionMapper;
 import com.github.zuihou.business.productionResourceCenter.dao.ZZoneMapper;
 import com.github.zuihou.business.productionResourceCenter.entity.*;
 import com.github.zuihou.business.productionResourceCenter.service.RepairService;
+import com.github.zuihou.business.util.MsgUtil;
 import com.github.zuihou.common.constant.BizConstant;
 import com.github.zuihou.common.constant.CacheKey;
 import com.github.zuihou.common.constant.CodeRuleModule;
@@ -47,12 +46,16 @@ import com.github.zuihou.database.mybatis.conditions.query.QueryWrap;
 import com.github.zuihou.tenant.service.CodeRuleService;
 import com.google.common.collect.Maps;
 import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
+import java.math.BigDecimal;
 import java.sql.Timestamp;
+import java.text.NumberFormat;
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 /**
@@ -112,6 +115,19 @@ public class TaskServiceImpl extends SuperServiceImpl<TTaskMapper, TTask> implem
 
     @Autowired
     private PlanMapper planMapper;
+    @Autowired
+    private StockLogMapper stockLogMapper;
+    @Autowired
+    private MToolClampMapper mToolClampMapper;
+    @Autowired
+    private StockInfoMapper stockInfoMapper;
+    @Autowired
+    private TaskNodeMapper taskNodeMapper;
+    @Autowired
+    private MsgUtil msgUtil;
+    @Autowired
+    private AAutoNodeLogMapper autoNodeLogMapper;
+
 
     @Override
     public List<TTask> createTaskByPlan(List<PlanProduct> planProductList, Map<Long,List<BomProcedure>> bomProcedureMap,String taskBatchNo) {
@@ -857,6 +873,7 @@ public class TaskServiceImpl extends SuperServiceImpl<TTaskMapper, TTask> implem
         return task;
     }
 
+    @Override
     public TTask assignResource(TTask task,Map<Long,BomProcedure>bpMap){
         BomProcedure bp = bpMap.get(task.getProcedureId());
         List<BomProcedureProductionresource> rsList = bp.getProductionresourceList();
@@ -1020,15 +1037,136 @@ public class TaskServiceImpl extends SuperServiceImpl<TTaskMapper, TTask> implem
                 baseMapper.updateById(tTask);
             }
         }else if("end".equals(type)) {
+            TaskNode taskNode = taskNodeMapper.selectOne(Wraps.<TaskNode>lbQ().eq(TaskNode::getTaskId, tTask.getId()).eq(TaskNode::getExeStatus,"2"));
+            String id = taskNode.getId().toString();
+            //验证是否重复回调
+            String cacheId = msgUtil.redis_get(id) == null ? "" : msgUtil.redis_get(id).toString();
+            if (StringUtil.isNotEmpty(cacheId)) {//排除掉重复回调
+                log.info("上下料重复了======================" + cacheId);
+                return null;
+            }
+            //把当前id存放入缓存
+            msgUtil.redis_set(id, id, 1, TimeUnit.HOURS);
+
             if(null == tTask.getEndTime()) {
                 tTask.setEndTime(Calendar.getInstance().getTime());
                 tTask.setStatus("3");
                 baseMapper.updateById(tTask);
             }
+            // 调用rfid读取接口判断rfid里面是否子盘信息,写入原材料信息
+            String meterialId = map.get("meterialId").toString();
+            String uniqueCode = map.get("uniqueCode").toString();
+            // 判断当前工件是否存在夹具,没有夹具stock表插入夹具信息
+            List<StockInfo> stockInfos = stockInfoService.list(Wraps.<StockInfo>lbQ().eq(StockInfo::getCompleteBatchNo, tTask.getCompleteBatchNo()));
+
+            // 先插入夹具信息
+            StockInfo meterialIdStockInfo = new StockInfo();
+            meterialIdStockInfo.setStorgeId(stockInfos.get(0).getStorgeId());
+            meterialIdStockInfo.setLockStatus("1");
+            meterialIdStockInfo.setGoodsType("3");
+            meterialIdStockInfo.setGoodsId(Long.valueOf(meterialId));
+            meterialIdStockInfo.setUniqueCode(String.valueOf(uniqueCode));
+            meterialIdStockInfo.setCompleteBatchNo(tTask.getCompleteBatchNo());
+            stockInfoMapper.insert(meterialIdStockInfo);
+            stockLogService.saveLog(meterialIdStockInfo,BizConstant.STOCK_TYPE_IN);
+
+            // 组织参数回调任务完成
+            List<AAutoNodeLog> autoNodeLogList = autoNodeLogMapper.selectList(Wraps.<AAutoNodeLog>lbQ().eq(AAutoNodeLog::getTaskNodeId, taskNode.getId()));
+            AAutoNodeLog lg = autoNodeLogList.get(0);
+
+            JSONObject jsonObject = new JSONObject();
+            //根据任务查出所有的自动化节点
+            List<TaskNode> taskNodeList = taskNodeMapper.selectList(Wraps.<TaskNode>lbQ().eq(TaskNode::getCompleteBatchNo, tTask.getCompleteBatchNo()));
+
+            Storge jbwFromStorge = (Storge) msgUtil.redis_get(DemoCacheKey.DEMOLINE_CIRCULATION_STORAGE + "_" + tTask.getCompleteBatchNo());
+            //2、取出上下料站
+            Storge sxlzstorge = (Storge) msgUtil.redis_get(DemoCacheKey.DEMOLINE_CAMP + "_" + DemoLineConstant.SXLZ + taskNode.getId());
+            jsonObject.put("srcPosition", jbwFromStorge.getId());
+            jsonObject.put("targetPostion", sxlzstorge.getId());
+            jsonObject.put(DemoLineConstant.DEMOLINE_STOCK_TYPE, DemoLineConstant.DEMOLINE_STOCK_TYPE_METERIAL_CRK);
+
+            msgUtil.redis_set(DemoCacheKey.DEMOLINE_CIRCULATION_STORAGE + "_" + tTask.getCompleteBatchNo(), sxlzstorge, 1, TimeUnit.DAYS);
+
+            //节点完成业务
+            this.taskNodeCallbackBiz(taskNode, tTask, taskNodeList, lg, jsonObject.toJSONString());
+
+            msgUtil.redis_set(CacheKey.TASK_CURRENT_NODE_STATUS + "_" + taskNode.getId(), "1");
+
         }
         return  R.success();
     }
 
+    private void taskNodeCallbackBiz(TaskNode taskNode, TTask task, List<TaskNode> taskNodeList, AAutoNodeLog lg, String bizCallBackData) {
+        //回调的参数
+        JSONObject callBackJson = JSONObject.parseObject(bizCallBackData);
+
+        //获取当前自动化节点的顺序
+        int n = taskNode.getCompleteBatchSort() - 1;
+
+        updateBizStatus(taskNode, task, taskNodeList, lg, callBackJson);
+
+        //websocket推送TODO临时注释
+//        msgUtil.pushTask(task);
+
+        //推送到消息队列
+        msgUtil.pushToNextMq(taskNode, task, taskNodeList, n, callBackJson);
+
+    }
+
+    private void updateBizStatus(TaskNode taskNode, TTask task, List<TaskNode> taskNodeList, AAutoNodeLog lg, JSONObject callBackJson) {
+        //如果是推送当前节点到mq(一个节点执行多次。就不需要更新数据状态)
+        if (this.checkPushNextNode(taskNode, callBackJson)){
+            //获取当前自动化节点的顺序
+            int n = taskNode.getCompleteBatchSort() - 1;
+            //插入执行日志
+            lg.setExeStatus("3");
+            lg.setExeResult("1").setEndTime(new Date());
+            autoNodeLogMapper.updateAllById(lg);
+            //更新节点任务
+            taskNode.setExeStatus("3").setExeResult("1").setEndTime(new Date());
+            taskNodeMapper.updateById(taskNode);
+            //把当前完成的节点放入缓存,用于推送任务完成的百分比
+            NumberFormat numberFormat = NumberFormat.getInstance();
+            numberFormat.setMaximumFractionDigits(2);
+
+            msgUtil.redis_set(CacheKey.TASK_CURRENT_NODE_PERCENT + "_" + task.getResourceId(), numberFormat.format(100 * (float) (n + 1) / (float) taskNodeList.size()));
+            task.setProcess(Double.parseDouble(numberFormat.format(100 * (float) (n + 1) / (float) taskNodeList.size())));
+
+            //更新订单表里的完成数量等等字段
+            if (n == 0 && "1".equals(task.getFirstProcedureFlag())) {
+                Order order = orderMapper.selectById(task.getOrderId());
+                order.setProduceNum((order.getProduceNum() == null ? 0 : order.getProduceNum()) + 1);
+                orderMapper.updateAllById(order);
+            }
+            //解锁相关资源
+            unlockResource(taskNode, task);
+        }
+    }
+
+    private void unlockResource(TaskNode taskNode, TTask task) {
+        //删除当前节点的锁定
+        List<Storge> storgeList = storgeService.list(Wraps.<Storge>lbQ().eq(Storge::getCampId, taskNode.getId()));
+        if (CollectionUtil.isNotEmpty(storgeList)) {
+            storgeService.unlockStorgeList(storgeList);
+        }
+    }
+
+    private boolean checkPushNextNode(TaskNode taskNode, JSONObject callBackJson) {
+        if (callBackJson.containsKey(DemoLineConstant.DEMOLINE_RXJQR_FLAG)) {//柔性机器人的多步骤执行
+            int count = callBackJson.getString(taskNode.getId().toString() + "count") == null ? 0 : Integer.parseInt(callBackJson.getString(taskNode.getId().toString() + "count"));
+            if (count < 2) {//
+                return false;
+            }
+        } else if (callBackJson.containsKey(DemoLineConstant.DEMOLINE_CHANGEHAND_FLAG) || callBackJson.containsKey(DemoLineConstant.DEMOLINE_RXJQR_NOMOVE_FLAG)) {//机器人换手或无需移动的柔性机器人
+            int count = callBackJson.getString(taskNode.getId().toString() + "count") == null ? 0 : Integer.parseInt(callBackJson.getString(taskNode.getId().toString() + "count"));
+            if (count < 1) {//
+                return false;
+            }
+        }
+        return true;
+
+    }
+
     @Override
     public R releaseClamp(Map<String, Object> map){
         TTask tTask = baseMapper.selectById(Long.valueOf(map.get("id").toString()));
@@ -1057,10 +1195,46 @@ public class TaskServiceImpl extends SuperServiceImpl<TTaskMapper, TTask> implem
 
     @Override
     public R procesRfid(Map<String, Object> map){
-        // 先读取rfid内容是否有子盘信息
+        // TODO 先读取rfid内容是否有子盘信息
         // 第一次使用子盘写入子盘唯一编码
         TTask tTask = baseMapper.selectById(Long.valueOf(map.get("id").toString()));
         // 调用rfid读取接口判断rfid里面是否子盘信息,第一次内容为空,写入自盘信息,后续只需更新夹具、和原材料信息
+
+        // 判断当前工件是否存在夹具,没有夹具stock表插入夹具信息
+        List<StockInfo> stockInfos = stockInfoService.list(Wraps.<StockInfo>lbQ().eq(StockInfo::getCompleteBatchNo, tTask.getCompleteBatchNo()));
+        // 只有子盘
+        if(stockInfos.size() ==1){
+            String goodsId = map.get("clampId").toString();
+            Map queryMap = new HashMap();
+            queryMap.put("goodsId", goodsId);
+
+            MToolClamp mToolClamp = mToolClampMapper.selectById(goodsId);
+            String maxMToolClamp = stockInfoMapper.selectMaxNoByProductId(queryMap);
+            int maxMToolClampNo = 0;
+            if(StringUtils.isBlank(maxMToolClamp)){
+                maxMToolClampNo = 0;
+            }else{
+                maxMToolClampNo = Integer.parseInt(maxMToolClamp);
+            }
+            int sumMToolClamp = stockInfoMapper.selectSumInStockByProductId(queryMap);
+            BigDecimal uniqueCode;
+            if(sumMToolClamp < mToolClamp.getNum()){
+                uniqueCode = BigDecimal.valueOf(maxMToolClampNo).add(new BigDecimal(1));;
+            }else{
+                return R.fail("当前夹具数量已用完");
+            }
+            StockInfo trayStockInfo = stockInfos.get(0);
+            // 先插入夹具信息
+            StockInfo clamStockInfo = new StockInfo();
+            clamStockInfo.setStorgeId(trayStockInfo.getStorgeId());
+            clamStockInfo.setLockStatus("1");
+            clamStockInfo.setGoodsType("1");
+            clamStockInfo.setGoodsId(Long.valueOf(goodsId));
+            clamStockInfo.setUniqueCode(String.valueOf(uniqueCode));
+            clamStockInfo.setCompleteBatchNo(tTask.getCompleteBatchNo());
+            stockInfoMapper.insert(clamStockInfo);
+            stockLogService.saveLog(clamStockInfo,BizConstant.STOCK_TYPE_IN);
+        }
         return R.success();
     }
 }

+ 8 - 0
imcs-admin-boot/imcs-business-biz/src/main/java/com/github/zuihou/business/util/MsgUtil.java

@@ -169,4 +169,12 @@ public class MsgUtil implements ApplicationContextAware {
             redisTemplate.delete(key);
         }
     }
+
+    public void redis_set_map(String key, Map<String, Object> map){
+        redisTemplate.opsForHash().putAll(key,  map);
+    }
+
+    public Map redis_get_map(String key){
+        return redisTemplate.opsForHash().entries(key);
+    }
 }

+ 2 - 0
imcs-admin-boot/imcs-business-biz/src/main/resources/mapper_business/base/operationManagementCenter/TTaskMapper.xml

@@ -274,6 +274,7 @@
           itt.task_no AS no,
           ibb.name,
           (SELECT itt1.no FROM  imcs_t_tray itt1, imcs_b_bom_procedure_tray ibbpt1 WHERE ibbpt1.biz_type = 1 AND itt1.id = ibbpt1.tray_id AND ibbpt1.procedure_id = ibbp.id) AS trayNo,
+          imfc.id  AS clampId,
           imfc.no  AS clampNo,
           imfc.name  AS clampName,
           imfc.material_type AS clampType,
@@ -281,6 +282,7 @@
           itt.expect_start_time AS startTime,
           itt.expect_end_time AS endTime,
           itt.status,
+          imm.id AS meteriaId,
           imm.meterial_code AS meterialCode,
           imm.equipment_name AS equipmentName,
           imm.trade_mark AS tradeMark,

+ 3 - 1
imcs-admin-boot/imcs-business-biz/src/main/resources/mapper_business/base/productionReadyCenter/AAutoNodeLogMapper.xml

@@ -16,12 +16,14 @@
         <result column="end_time" jdbcType="TIMESTAMP" property="endTime"/>
         <result column="feedback" jdbcType="VARCHAR" property="feedback"/>
         <result column="status" jdbcType="VARCHAR" property="status"/>
+        <result column="method" jdbcType="VARCHAR" property="method"/>
+        <result column="execute_time" jdbcType="TIMESTAMP" property="executeTime"/>
         <result column="feedback_file" jdbcType="VARCHAR" property="feedbackFile"/>
     </resultMap>
 
     <!-- 通用查询结果列 -->
     <sql id="Base_Column_List">
-        id,create_time ,create_user,update_time,update_user,
+        id,create_time ,create_user,update_time,update_user,method, execute_time,
         auto_node_id, exe_status, exe_result, start_time, end_time, feedback, feedback_file, status, resourceName,instructionName,procedureName,nodeNo
     </sql>
 

+ 91 - 17
imcs-admin-boot/imcs-business-controller/src/main/java/com/github/zuihou/business/controller/dispatchRecord/DispatchExceptionController.java

@@ -3,7 +3,10 @@ package com.github.zuihou.business.controller.dispatchRecord;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.util.ReflectUtil;
 import cn.hutool.core.util.StrUtil;
+import com.alibaba.fastjson.JSONObject;
 import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.github.zuihou.base.R;
 import com.github.zuihou.base.controller.SuperSimpleController;
@@ -13,8 +16,15 @@ import com.github.zuihou.business.dispatchRecord.entity.DispatchRecord;
 import com.github.zuihou.business.dispatchRecord.service.DispatchExceptionService;
 import com.github.zuihou.business.dispatchRecord.service.DispatchRecordService;
 import com.github.zuihou.business.operationManagementCenter.entity.Order;
+import com.github.zuihou.business.operationManagementCenter.entity.TWorkpiece;
+import com.github.zuihou.business.operationManagementCenter.service.WorkpieceService;
 import com.github.zuihou.business.productionReadyCenter.entity.AAutoNodeLog;
+import com.github.zuihou.business.productionReadyCenter.service.AAutoNodeLogService;
+import com.github.zuihou.business.util.MsgUtil;
+import com.github.zuihou.common.constant.CacheKey;
+import com.github.zuihou.common.constant.DictionaryKey;
 import com.github.zuihou.common.util.DateUtil;
+import com.github.zuihou.context.BaseContextHandler;
 import com.github.zuihou.database.mybatis.conditions.Wraps;
 import com.github.zuihou.database.mybatis.conditions.query.LbqWrapper;
 import com.github.zuihou.database.mybatis.conditions.query.QueryWrap;
@@ -24,16 +34,21 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpEntity;
+import org.springframework.http.HttpHeaders;
+import org.springframework.http.MediaType;
 import org.springframework.validation.annotation.Validated;
-import org.springframework.web.bind.annotation.PostMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.client.RestTemplate;
 
+import java.lang.invoke.MethodType;
 import java.lang.reflect.Field;
+import java.lang.reflect.Method;
 import java.time.LocalDateTime;
 import java.util.Date;
 import java.util.Iterator;
+import java.util.List;
 import java.util.Map;
 
 @Slf4j
@@ -42,26 +57,40 @@ import java.util.Map;
 @RequestMapping("/dispatchException")
 @Api(value = "dispatchException", tags = "调度异常")
 @SysLog(enabled = true)
-public class DispatchExceptionController extends SuperSimpleController<DispatchExceptionService, DispatchException> {
+public class DispatchExceptionController extends SuperSimpleController<AAutoNodeLogService, AAutoNodeLog> {
 
-    @ApiOperation(value = "查询设备刀具管理", notes = "查询设备刀具管理")
+    @Autowired
+    private AAutoNodeLogService aAutoNodeLogService;
+
+    @Autowired
+    private WorkpieceService workpieceService;
+
+    @Autowired
+    private MsgUtil msgUtil;
+
+    @Autowired
+    private RestTemplate restTemplate;
+
+    @ApiOperation(value = "查询对话调度异常", notes = "查询对话调度异常")
     @PostMapping("/page")
-    public R<IPage<DispatchException>> page(@RequestBody @Validated PageParams<DispatchException> params) {
-        IPage<DispatchException> page = params.buildPage();
-        QueryWrap<DispatchException> wrap = handlerWrapper(null, params);
-        LbqWrapper<DispatchException> wrapper = wrap.lambda();
-        wrapper.like(DispatchException::getName, params.getModel().getName())
+    public R<IPage<AAutoNodeLog>> page(@RequestBody @Validated PageParams<AAutoNodeLog> params) {
+        IPage<AAutoNodeLog> page = params.buildPage();
+        QueryWrap<AAutoNodeLog> wrap = handlerWrapper(null, params);
+        LbqWrapper<AAutoNodeLog> wrapper = wrap.lambda();
+        wrapper.like(AAutoNodeLog::getInstructionName, params.getModel().getInstructionName())
                 //.geHeader(DispatchException::getOperationTime, StrUtil.isEmpty(params.getModel().getOperationTime_st())?null: LocalDateTime.parse(params.getModel().getOperationTime_st()))
-                .ge(DispatchException::getOperationTime, DateUtil.stringToDate3(params.getModel().getOperationTime_st()))
-                .le(DispatchException::getOperationTime, DateUtil.stringToDate3(params.getModel().getOperationTime_ed()))
+                .ge(AAutoNodeLog::getExecuteTime, DateUtil.stringToDate3(params.getModel().getExecuteTime_st()))
+                .le(AAutoNodeLog::getExecuteTime, DateUtil.stringToDate3(params.getModel().getExecuteTime_ed()))
 //                .leFooter(DispatchException::getOperationTime, StrUtil.isEmpty(params.getModel().getOperationTime_ed())?null:LocalDateTime.parse(params.getModel().getOperationTime_ed()))
-                .orderByDesc(DispatchException::getCreateTime);
-        baseService.page(page, wrapper);
+                .orderByDesc(AAutoNodeLog::getCreateTime);
+        //查询弹框异常
+        wrapper.eq(AAutoNodeLog::getExeResult,"0").eq(AAutoNodeLog::getManual, "1").eq(AAutoNodeLog::getStatus, "0");
+        aAutoNodeLogService.page(page, wrapper);
         return this.success(page);
     }
 
-    private QueryWrap<DispatchException> handlerWrapper(DispatchException model, PageParams<DispatchException> params) {
-       QueryWrap<DispatchException> wrapper = model == null ? Wraps.q() : Wraps.q(model);
+    private QueryWrap<AAutoNodeLog> handlerWrapper(AAutoNodeLog model, PageParams<AAutoNodeLog> params) {
+       QueryWrap<AAutoNodeLog> wrapper = model == null ? Wraps.q() : Wraps.q(model);
        if (CollUtil.isNotEmpty(params.getMap())) {
            Map<String, String> map = params.getMap();
            Iterator var5 = map.entrySet().iterator();
@@ -102,4 +131,49 @@ public class DispatchExceptionController extends SuperSimpleController<DispatchE
            }
        }
 
+    @ApiOperation(value = "修改状态", notes = "修改状态")
+    @GetMapping("/updateStatus")
+    public R<Boolean> updateStatus(@RequestParam(value="ids[]") List<Long> ids) {
+        return R.success(aAutoNodeLogService.updateStatus(ids));
+    }
+
+    @ApiOperation(value = "标记指令完成", notes = "标记指令完成")
+    @PostMapping("/complete")
+    public R<Boolean> complete(@RequestBody Map<String, Long> map) {
+        //return R.success(aAutoNodeLogService.updateStatus(ids));
+        AAutoNodeLog autoNodeLog = aAutoNodeLogService.getById(map.get("id"));
+        Long taskNodeId = autoNodeLog.getTaskNodeId();
+        TWorkpiece tWorkpiece = workpieceService.getWorkPiece(taskNodeId);
+        //节点逻辑处理(待定)
+
+        LambdaUpdateWrapper<AAutoNodeLog> updateWrapper = new UpdateWrapper<AAutoNodeLog>().lambda();
+        updateWrapper.eq(AAutoNodeLog::getId, map.get("id")).set(AAutoNodeLog::getStatus, "1").set(AAutoNodeLog::getExeResult ,"1")
+                .set(AAutoNodeLog::getUpdateUser, BaseContextHandler.getUserId()).set(AAutoNodeLog::getUpdateTime, new Date());
+
+        return R.success(aAutoNodeLogService.update(updateWrapper));
+    }
+
+    @ApiOperation(value = "重发数据节点", notes = "重发数据节点")
+    @PostMapping("/resend")
+    private R<Boolean> resend(@RequestBody Map<String, Long> map){
+        AAutoNodeLog autoNodeLog = aAutoNodeLogService.getById(map.get("id"));
+        Long taskNodeId = autoNodeLog.getTaskNodeId();
+        TWorkpiece tWorkpiece = workpieceService.getWorkPiece(taskNodeId);
+        //判断重发节点操作条件(待定)
+        Map<String, Object> conMap = msgUtil.redis_get_map(CacheKey.TASK_CURRENT_NODE_CONDITION + "_" + taskNodeId);
+        //获取重发执行传参
+        String jsonParam = msgUtil.redis_get(CacheKey.TASK_CURRENT_NODE_PARAMS + "_" + taskNodeId).toString();
+
+        HttpHeaders headers = new HttpHeaders();
+        headers.setContentType(MediaType.parseMediaType("application/json;charset=UTF-8"));
+        HttpEntity<String> formEntity = new HttpEntity<String>(jsonParam, headers);
+
+        String instructionUrl = DictionaryKey.INSTRUCTION_URL +"/api/"+ autoNodeLog.getMethod().toString() ;
+        String returnData = restTemplate.postForObject(instructionUrl, formEntity, String.class);
+        JSONObject retJson = JSONObject.parseObject(returnData);
+        String code = retJson.getString("code").trim();
+
+        return R.success(("1" == code)? true: false);
+    }
+
 }

+ 21 - 13
imcs-admin-boot/imcs-business-controller/src/main/java/com/github/zuihou/business/controller/dispatchRecord/DispatchRecordController.java

@@ -11,6 +11,8 @@ import com.github.zuihou.base.request.PageParams;
 import com.github.zuihou.business.dispatchRecord.entity.DispatchException;
 import com.github.zuihou.business.dispatchRecord.entity.DispatchRecord;
 import com.github.zuihou.business.dispatchRecord.service.DispatchRecordService;
+import com.github.zuihou.business.productionReadyCenter.entity.AAutoNodeLog;
+import com.github.zuihou.business.productionReadyCenter.service.AAutoNodeLogService;
 import com.github.zuihou.business.productionResourceCenter.entity.Tool;
 import com.github.zuihou.common.util.DateUtil;
 import com.github.zuihou.database.mybatis.conditions.Wraps;
@@ -22,6 +24,7 @@ import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.PostMapping;
 import org.springframework.web.bind.annotation.RequestBody;
@@ -40,24 +43,29 @@ import java.util.Map;
 @RequestMapping("/dispatchRecord")
 @Api(value = "dispatchRecord", tags = "调度对话")
 @SysLog(enabled = true)
-public class DispatchRecordController extends SuperSimpleController<DispatchRecordService, DispatchRecord> {
+public class DispatchRecordController extends SuperSimpleController<AAutoNodeLogService, AAutoNodeLog> {
 
-    @ApiOperation(value = "查询设备刀具管理", notes = "查询设备刀具管理")
+    @Autowired
+    private AAutoNodeLogService aAutoNodeLogService;
+
+    @ApiOperation(value = "查询对话调度记录", notes = "查询对话调度记录")
     @PostMapping("/page")
-    public R<IPage<DispatchRecord>> page(@RequestBody @Validated PageParams<DispatchRecord> params) {
-        IPage<DispatchRecord> page = params.buildPage();
-        QueryWrap<DispatchRecord> wrap = handlerWrapper(null, params);
-        LbqWrapper<DispatchRecord> wrapper = wrap.lambda();
-        wrapper.like(DispatchRecord::getName, params.getModel().getName())
-                .ge(DispatchRecord::getDistributeTime, StrUtil.isEmpty(params.getModel().getDistributeTime_st())?null: DateUtil.stringToDate3(params.getModel().getDistributeTime_st()))
-                .le(DispatchRecord::getDistributeTime, StrUtil.isEmpty(params.getModel().getDistributeTime_ed())?null:DateUtil.stringToDate3(params.getModel().getDistributeTime_ed()))
-                .orderByDesc(DispatchRecord::getCreateTime);
-        baseService.page(page, wrapper);
+    public R<IPage<AAutoNodeLog>> page(@RequestBody @Validated PageParams<AAutoNodeLog> params) {
+        IPage<AAutoNodeLog> page = params.buildPage();
+        QueryWrap<AAutoNodeLog> wrap = handlerWrapper(null, params);
+        LbqWrapper<AAutoNodeLog> wrapper = wrap.lambda();
+        wrapper.like(AAutoNodeLog::getInstructionName, params.getModel().getInstructionName())
+                .ge(AAutoNodeLog::getExecuteTime, StrUtil.isEmpty(params.getModel().getExecuteTime_st())?null: DateUtil.stringToDate3(params.getModel().getExecuteTime_st()))
+                .le(AAutoNodeLog::getExecuteTime, StrUtil.isEmpty(params.getModel().getExecuteTime_ed())?null:DateUtil.stringToDate3(params.getModel().getExecuteTime_ed()))
+                .orderByDesc(AAutoNodeLog::getCreateTime);
+        //只展示执行成功的调度指令
+        wrapper.eq(AAutoNodeLog::getExeResult, "1");
+        aAutoNodeLogService.page(page, wrapper);
         return this.success(page);
     }
 
-    private QueryWrap<DispatchRecord> handlerWrapper(DispatchRecord model, PageParams<DispatchRecord> params) {
-       QueryWrap<DispatchRecord> wrapper = model == null ? Wraps.q() : Wraps.q(model);
+    private QueryWrap<AAutoNodeLog> handlerWrapper(AAutoNodeLog model, PageParams<AAutoNodeLog> params) {
+       QueryWrap<AAutoNodeLog> wrapper = model == null ? Wraps.q() : Wraps.q(model);
        if (CollUtil.isNotEmpty(params.getMap())) {
            Map<String, String> map = params.getMap();
            Iterator var5 = map.entrySet().iterator();

+ 18 - 7
imcs-admin-boot/imcs-business-entity/src/main/java/com/github/zuihou/business/productionReadyCenter/entity/AAutoNodeLog.java

@@ -95,13 +95,13 @@ public class AAutoNodeLog extends Entity<Long> {
 
 
     /**
-     * 是否推送(1-已处理0-未处理)
+     * 是否人工处理(1-是0-否)
      */
-    @ApiModelProperty(value = "是否推送(1-已处理0-未处理)")
-    @Length(max = 4, message = "是否推送(1-已处理0-未处理)长度不能超过4")
-    @TableField(value = "send_status", condition = LIKE)
-    @Excel(name = "处理状态(1-已处理0-未处理)")
-    private String sendStatus;
+    @ApiModelProperty(value = "是否人工处理(1-是0-否)")
+    @Length(max = 4, message = "是否人工处理(1-是0-否)长度不能超过4")
+    @TableField(value = "manual", condition = LIKE)
+    @Excel(name = "是否人工处理(1-是0-否)")
+    private String manual;
 
     /**
      * 指令方法名
@@ -112,7 +112,13 @@ public class AAutoNodeLog extends Entity<Long> {
     @Excel(name = "指令方法")
     private String method;
 
-
+    /**
+     * 截止时间
+     */
+    @ApiModelProperty(value = "指令执行时间")
+    @TableField("execute_time")
+    @Excel(name = "指令执行时间", format = DEFAULT_DATE_TIME_FORMAT, width = 20)
+    private Date executeTime;
 
     /**
      * 开始时间
@@ -196,6 +202,11 @@ public class AAutoNodeLog extends Entity<Long> {
     @TableField(exist = false)
     private String nodeNo;
 
+    @TableField(exist = false)
+    private String executeTime_st;
+    @TableField(exist = false)
+    private String executeTime_ed;
+
     @Builder
     public AAutoNodeLog(Long id, LocalDateTime createTime, Long createUser, LocalDateTime updateTime, Long updateUser,
                     Long autoNodeId, String exeStatus, String exeResult, Date startTime, Date endTime,

+ 10 - 0
imcs-admin-boot/imcs-common/src/main/java/com/github/zuihou/common/constant/CacheKey.java

@@ -246,6 +246,16 @@ public interface CacheKey {
      */
     String TASK_CURRENT_NODE_STATUS = "TASK_CURRENT_NODE_STATUS";
 
+    /**
+     * 任务当前节点条件
+     */
+    String TASK_CURRENT_NODE_CONDITION = "TASK_CURRENT_NODE_CONDITION";
+
+    /**
+     * 任务当前节点参数
+     */
+    String TASK_CURRENT_NODE_PARAMS = "TASK_NODE_CURRENT_NODE_CONDITION";
+
     /**
      * 任务询问当前位置
      */