瀏覽代碼

1.完善是否是三向车紧急任务判断
2.添加普通移库任务对接

zhifei 1 年之前
父節點
當前提交
c283c902fd
共有 19 個文件被更改,包括 646 次插入296 次删除
  1. 23 11
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/tianao/TianaoApiContoller.java
  2. 1 1
      ruoyi-system/src/main/java/com/ruoyi/system/config/MQTTConfig.java
  3. 4 0
      ruoyi-system/src/main/java/com/ruoyi/system/init/PublishAGVInfo.java
  4. 1 1
      warewms-ams/src/main/java/com/ruoyi/ams/agv/ndc/AciService.java
  5. 3 1
      warewms-ams/src/main/java/com/ruoyi/ams/agv/ndc/service/StatusUpdateService.java
  6. 64 28
      warewms-ams/src/main/java/com/ruoyi/ams/agv/ndc/service/impl/AmsNdcEventServiceImpl.java
  7. 69 47
      warewms-ams/src/main/java/com/ruoyi/ams/agv/ndc/service/impl/SocketBufferServiceImpl.java
  8. 35 40
      warewms-ams/src/main/java/com/ruoyi/ams/agv/ndc/service/impl/StatusUpdateServiceImpl.java
  9. 69 65
      warewms-ams/src/main/java/com/ruoyi/ams/business/BusinessServiceImpl.java
  10. 34 21
      warewms-ams/src/main/java/com/ruoyi/ams/task/service/impl/WcsTaskServiceImpl.java
  11. 11 1
      warewms-base/src/main/java/com/ruoyi/base/constant/Constant.java
  12. 2 0
      warewms-base/src/main/java/com/ruoyi/base/mapper/BaseLocationInfoMapper.java
  13. 1 1
      warewms-base/src/main/java/com/ruoyi/base/service/IBaseLocationInfoService.java
  14. 6 3
      warewms-base/src/main/java/com/ruoyi/base/service/impl/BaseLocationInfoServiceImpl.java
  15. 42 21
      warewms-base/src/main/java/com/ruoyi/base/service/impl/CarInfoServiceImpl.java
  16. 32 0
      warewms-base/src/main/resources/mapper/base/BaseLocationInfoMapper.xml
  17. 21 18
      warewms-tianao/src/main/java/com/ruoyi/tianao/job/FeedbackJob.java
  18. 29 3
      warewms-tianao/src/main/java/com/ruoyi/tianao/service/TianaoService.java
  19. 199 34
      warewms-tianao/src/main/java/com/ruoyi/tianao/service/impl/TianaoServiceImpl.java

+ 23 - 11
ruoyi-admin/src/main/java/com/ruoyi/web/controller/warewms/tianao/TianaoApiContoller.java

@@ -1,9 +1,14 @@
 package com.ruoyi.web.controller.warewms.tianao;
 
+import cn.hutool.json.JSONArray;
 import com.alibaba.fastjson.JSONObject;
 import com.ruoyi.ams.agv.ndc.entity.CarStatus;
 import com.ruoyi.ams.task.domain.WcsTask;
+import com.ruoyi.base.domain.CarInfo;
+import com.ruoyi.base.service.ICarInfoService;
 import com.ruoyi.common.core.controller.BaseController;
+import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.system.init.PublishAGVInfo;
 import com.ruoyi.tianao.domian.TianaoTask;
 import com.ruoyi.tianao.service.TianaoService;
 import io.swagger.annotations.Api;
@@ -12,6 +17,8 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
+import java.util.Date;
+
 /**
  * Created with IntelliJ IDEA.
  *
@@ -31,11 +38,18 @@ public class TianaoApiContoller extends BaseController {
     @Autowired
     private TianaoService tianaoService;
 
+    @Autowired
+    PublishAGVInfo publishAGVInfo;
+
+    @Autowired
+    ICarInfoService iCarInfoService;
+
     /**
      * 任务管理接口
      */
     @PostMapping(value = "/taskManage")
     public JSONObject taskManage(@Validated @RequestBody TianaoTask tianaoTask) {
+        log.info("收到WMS的任务:{}", tianaoTask);
         //新增任务
         if ("0".equals(tianaoTask.getTask_type())){
             return  tianaoService.addTask(tianaoTask);
@@ -44,21 +58,19 @@ public class TianaoApiContoller extends BaseController {
         if ("5".equals(tianaoTask.getTask_type())){
             return  tianaoService.updateTask(tianaoTask);
         }
+        //取消任务
         if ("10".equals(tianaoTask.getTask_type())){
             return  tianaoService.cancelTask(tianaoTask);
         }
+        //普通任务
+        if ("15".equals(tianaoTask.getTask_type())){
+            return  tianaoService.addOrdinaryTask(tianaoTask);
+        }
+        //紧急任务
+        if ("20".equals(tianaoTask.getTask_type())){
+            return  tianaoService.addUrgentTask(tianaoTask);
+        }
         return tianaoService.returnJson("e0001","任务取消出错","fail");
     }
 
-    @GetMapping(value = "/testTask")
-    public String testTask( WcsTask wcsTask) {
-        return tianaoService.testTask(wcsTask);
-    }
-
-    @GetMapping(value = "/testAgvAddress")
-    public String testAgvAddress(CarStatus car) {
-        return tianaoService.testAgvAddress(car);
-    }
-
-
 }

+ 1 - 1
ruoyi-system/src/main/java/com/ruoyi/system/config/MQTTConfig.java

@@ -5,7 +5,7 @@ import lombok.Getter;
 @Getter
 public class MQTTConfig {
 
-    private String HOST= "tcp://61.169.55.85:1883";
+    private String HOST= "tcp://192.168.61.72:1883";
 
     private String clientId ="mqtt_client";
 

+ 4 - 0
ruoyi-system/src/main/java/com/ruoyi/system/init/PublishAGVInfo.java

@@ -65,6 +65,8 @@ public class PublishAGVInfo implements CommandLineRunner {
 
     }
 
+
+
     public void publishMessage(String content){
         try {
         // 创建消息
@@ -74,6 +76,8 @@ public class PublishAGVInfo implements CommandLineRunner {
         // 发布消息
         sampleClient.publish(topic, message);
         }catch (MqttException me){
+            closeConnection();
+            initConnect();
             log.error("An exception occurred in the release information,msg:{}",me.getMessage());
         }
     }

+ 1 - 1
warewms-ams/src/main/java/com/ruoyi/ams/agv/ndc/AciService.java

@@ -220,7 +220,7 @@ public class AciService {
                 }
 
             } catch (IOException i) {
-                log.error("NDC通讯异常!", i);
+                log.error("NDC通讯异常!,msg:{}", i);
                 try {
                     socketChannel.close();
                 } catch (Exception exception) {

+ 3 - 1
warewms-ams/src/main/java/com/ruoyi/ams/agv/ndc/service/StatusUpdateService.java

@@ -1,5 +1,7 @@
 package com.ruoyi.ams.agv.ndc.service;
 
+import com.ruoyi.ams.agv.ndc.domain.AmsTask;
+
 /**
  * Created by IntelliJ IDEA.
  * User: andy.qu
@@ -13,7 +15,7 @@ public interface StatusUpdateService {
      * @param id    amstaskid
      * @param carNo 车号(只有取货完成后才会有反馈)
      */
-    void updateStatus(Long id, Integer carNo) throws InterruptedException;
+    void updateStatus(AmsTask amsTask, Integer carNo) throws InterruptedException;
 
 
     /**

+ 64 - 28
warewms-ams/src/main/java/com/ruoyi/ams/agv/ndc/service/impl/AmsNdcEventServiceImpl.java

@@ -1,45 +1,62 @@
 package com.ruoyi.ams.agv.ndc.service.impl;
 
 import java.util.List;
+import java.util.Map;
+import java.util.function.Function;
+import java.util.stream.Collectors;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.google.common.collect.HashBasedTable;
+import com.ruoyi.common.core.redis.RedisCache;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import com.ruoyi.ams.agv.ndc.mapper.AmsNdcEventMapper;
 import com.ruoyi.ams.agv.ndc.domain.AmsNdcEvent;
 import com.ruoyi.ams.agv.ndc.service.IAmsNdcEventService;
 
+import javax.annotation.PostConstruct;
+
 /**
  * Ndc反馈事件代码字典Service业务层处理
- * 
+ *
  * @author andy
  * @date 2022-08-08
  */
 @Service
-public class AmsNdcEventServiceImpl implements IAmsNdcEventService 
-{
+public class AmsNdcEventServiceImpl implements IAmsNdcEventService {
     @Autowired
     private AmsNdcEventMapper amsNdcEventMapper;
 
+    @Autowired
+    RedisCache redisCache;
+
+    /**
+     * 项目启动时,初始化EventCode到缓存
+     */
+    @PostConstruct
+    public void init() {
+        loadingEvnetCache();
+    }
+
     /**
      * 查询Ndc反馈事件代码字典
-     * 
+     *
      * @param id Ndc反馈事件代码字典主键
      * @return Ndc反馈事件代码字典
      */
     @Override
-    public AmsNdcEvent selectAmsNdcEventById(Long id)
-    {
+    public AmsNdcEvent selectAmsNdcEventById(Long id) {
         return amsNdcEventMapper.selectAmsNdcEventById(id);
     }
 
     /**
      * 查询Ndc反馈事件代码字典列表
-     * 
+     *
      * @param amsNdcEvent Ndc反馈事件代码字典
      * @return Ndc反馈事件代码字典
      */
     @Override
-    public List<AmsNdcEvent> selectAmsNdcEventList(AmsNdcEvent amsNdcEvent)
-    {
+    public List<AmsNdcEvent> selectAmsNdcEventList(AmsNdcEvent amsNdcEvent) {
         return amsNdcEventMapper.selectAmsNdcEventList(amsNdcEvent);
     }
 
@@ -50,61 +67,80 @@ public class AmsNdcEventServiceImpl implements IAmsNdcEventService
      * @return Ndc反馈事件代码字典
      */
     @Override
-    public AmsNdcEvent selectAmsNdcEventByModel(AmsNdcEvent amsNdcEvent)
-    {
-        List<AmsNdcEvent> list = amsNdcEventMapper.selectAmsNdcEventList(amsNdcEvent);
-        if (list!=null && list.size()>0) {
-            return list.get(0);
-        } else {
-            return null;
+    public AmsNdcEvent selectAmsNdcEventByModel(AmsNdcEvent amsNdcEvent) {
+        Map<String, AmsNdcEvent> eventTable = redisCache.getCacheObject("ecodeType:" + amsNdcEvent.getType());
+        if (ObjectUtil.isNull(eventTable)) {
+            AmsNdcEvent e = new AmsNdcEvent();
+            e.setType(amsNdcEvent.getType());
+            eventTable = amsNdcEventMapper.selectAmsNdcEventList(e).stream().collect(Collectors.toMap((i) -> i.getEcode().toString(), Function.identity()));
+            if(ObjectUtil.isNull(eventTable)){
+                return null;
+            }
+            redisCache.setCacheObject("ecodeType:" + amsNdcEvent.getType(), eventTable);
+        }
+        return eventTable.get(amsNdcEvent.getEcode().toString());
+
+
+//        List<AmsNdcEvent> list = amsNdcEventMapper.selectAmsNdcEventList(amsNdcEvent);
+//        if (list!=null && list.size()>0) {
+//            return list.get(0);
+//        } else {
+//            return null;
+//        }
+    }
+
+    /**
+     * 初始化所有EventCode到缓存里
+     */
+    private void loadingEvnetCache() {
+        Map<Integer, List<AmsNdcEvent>> collect = amsNdcEventMapper.selectAmsNdcEventList(new AmsNdcEvent()).stream().collect(Collectors.groupingBy(AmsNdcEvent::getType));
+        for (Map.Entry<Integer, List<AmsNdcEvent>> integerListEntry : collect.entrySet()) {
+            Map<String, AmsNdcEvent> collect1 = integerListEntry.getValue().stream().collect(Collectors.toMap((i) -> i.getEcode().toString(), Function.identity()));
+            redisCache.setCacheObject("ecodeType:" + integerListEntry.getKey(),collect1 );
         }
     }
 
     /**
      * 新增Ndc反馈事件代码字典
-     * 
+     *
      * @param amsNdcEvent Ndc反馈事件代码字典
      * @return 结果
      */
     @Override
-    public int insertAmsNdcEvent(AmsNdcEvent amsNdcEvent)
-    {
+    public int insertAmsNdcEvent(AmsNdcEvent amsNdcEvent) {
         return amsNdcEventMapper.insertAmsNdcEvent(amsNdcEvent);
     }
 
     /**
      * 修改Ndc反馈事件代码字典
-     * 
+     *
      * @param amsNdcEvent Ndc反馈事件代码字典
      * @return 结果
      */
     @Override
-    public int updateAmsNdcEvent(AmsNdcEvent amsNdcEvent)
-    {
+    public int updateAmsNdcEvent(AmsNdcEvent amsNdcEvent) {
         return amsNdcEventMapper.updateAmsNdcEvent(amsNdcEvent);
     }
 
     /**
      * 批量删除Ndc反馈事件代码字典
-     * 
+     *
      * @param ids 需要删除的Ndc反馈事件代码字典主键
      * @return 结果
      */
     @Override
-    public int deleteAmsNdcEventByIds(Long[] ids)
-    {
+    public int deleteAmsNdcEventByIds(Long[] ids) {
         return amsNdcEventMapper.deleteAmsNdcEventByIds(ids);
     }
 
     /**
      * 删除Ndc反馈事件代码字典信息
-     * 
+     *
      * @param id Ndc反馈事件代码字典主键
      * @return 结果
      */
     @Override
-    public int deleteAmsNdcEventById(Long id)
-    {
+    public int deleteAmsNdcEventById(Long id) {
         return amsNdcEventMapper.deleteAmsNdcEventById(id);
     }
 }

+ 69 - 47
warewms-ams/src/main/java/com/ruoyi/ams/agv/ndc/service/impl/SocketBufferServiceImpl.java

@@ -9,16 +9,14 @@ import com.ruoyi.ams.agv.ndc.domain.AmsTask;
 import com.ruoyi.ams.agv.ndc.entity.CarStatus;
 import com.ruoyi.ams.agv.ndc.entity.Order;
 import com.ruoyi.ams.agv.ndc.service.*;
+import com.ruoyi.base.domain.CarInfo;
 import com.ruoyi.common.core.redis.RedisCache;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.ThreadPoolExecutor;
@@ -111,14 +109,14 @@ public class SocketBufferServiceImpl implements SocketBufferService {
 
     @Override
     public void handleMsgOrderStatus(byte[] parameters) {
-        int carNo = ByteUtil.getUnsignedShort(parameters, 6);
-        switch (parameters[5]) {
-            case 0x58:
-                //电池余量为千分比
+//        int carNo = ByteUtil.getUnsignedShort(parameters, 6);
+//        switch (parameters[5]) {
+//            case 0x58:
+//                电池余量为千分比
                 //car.setBattery(ByteUtil.getUnsignedShort(parameters, 14) / 10);
                 //car.update();
-                break;
-            case 0x63:
+//                break;
+//            case 0x63:
                 //xy轴位置
                 //car.setX(251770 - ByteUtil.getUnsignedShort(parameters, 6) * 10);
                 //car.setY(96620 - ByteUtil.getUnsignedShort(parameters, 14) * 10);
@@ -128,8 +126,10 @@ public class SocketBufferServiceImpl implements SocketBufferService {
 //                carStatus.setY(96620 - ByteUtil.getUnsignedShort(parameters, 14) * 10);
 //                SpringUtil.getApplicationContext().publishEvent(carStatus);
                 //car.update();
-                break;
-        }
+//                break;
+//        }
+//        log.info("S消息:{}",Arrays.toString(parameters));
+//        log.info("S消息,参数1:{},参数2{},参数3{},参数4{}", ByteUtil.getInt(parameters, 4),ByteUtil.getUnsignedShort(parameters, 6),ByteUtil.getUnsignedShort(parameters, 14),ByteUtil.getInt(parameters, 46));
     }
 
     @Override
@@ -148,6 +148,7 @@ public class SocketBufferServiceImpl implements SocketBufferService {
             event.setLp3("" + ByteUtil.getInt(parameters, 42));
             event.setLp4("" + ByteUtil.getInt(parameters, 46));
             int eventId = event.getId();
+            String agvNo = event.getLp1();
             AmsTask taskBean = new AmsTask();
 //            log.info("反馈event:{}",event);
 //            log.info("----event:" + eventId);
@@ -168,10 +169,17 @@ public class SocketBufferServiceImpl implements SocketBufferService {
                     taskBeanUpdate.setIsDelete(null);
                     amsTaskService.updateAmsTask(taskBeanUpdate);
                     //任务状态回调
-                    long taskId_85 = taskBean.getId().longValue();
+                    AmsTask task = taskBean;
+                    task.setId(taskBean.getId());
+                    task.setEvent(eventId);
+                    task.setServerAck(0);
+                    task.setAciAccept(1);
+                    task.setRoadway("任务回调执行取消");
+                    task.setSystemStatus(null);
+                    task.setIsDelete(null);
                     executorService.execute(() -> {
                         try {
-                            statusUpdateService.updateStatus(taskId_85, icarNo);
+                            statusUpdateService.updateStatus(task, Integer.parseInt(agvNo));
                         } catch (InterruptedException e) {
                             log.error("An exception occurred in the task update,msg,{}",e.getMessage());
                         }
@@ -190,7 +198,7 @@ public class SocketBufferServiceImpl implements SocketBufferService {
                 case 113://user event Fetch Empty
                     log.info("----event:" + eventId + ":" + JSON.toJSONString(event));
 
-                    taskBean.setAciIndex(Integer.parseInt(event.getLp1()));
+                    taskBean.setAciIndex(Integer.parseInt(event.getLp4()));
                     taskBean = amsTaskService.selectAmsTaskByModel(taskBean);
                     if (taskBean != null) {
                         AmsTask taskBeanUpdate01 = new AmsTask();
@@ -200,12 +208,15 @@ public class SocketBufferServiceImpl implements SocketBufferService {
                         taskBeanUpdate01.setSystemStatus(null);
                         taskBeanUpdate01.setIsDelete(null);
                         amsTaskService.updateAmsTask(taskBeanUpdate01);
-
-                        long taskId = taskBean.getId().longValue();
-                        String agvNo = event.getLp2();
+                        AmsTask task02 = taskBean;
+                        task02.setId(taskBean.getId());
+                        task02.setEvent(eventId);
+                        task02.setServerAck(0);
+                        task02.setSystemStatus(null);
+                        task02.setIsDelete(null);
                         executorService.execute(() -> {
                             try {
-                                statusUpdateService.updateStatus(taskId,Integer.parseInt( agvNo));
+                                statusUpdateService.updateStatus(task02,Integer.parseInt( agvNo));
                             } catch (InterruptedException e) {
                                 log.error("An exception occurred in the task update,msg,{}",e.getMessage());
                             }
@@ -220,7 +231,7 @@ public class SocketBufferServiceImpl implements SocketBufferService {
                     break;
                 case 114:
                     //60任务卸货确认
-                    Integer aciIndex = Integer.parseInt(event.getLp1());
+                    Integer aciIndex = Integer.parseInt(event.getLp4());
                     log.info("MSG_EVENT114:卸货确认{}", JSON.toJSONString(event));
 
                     AmsTask task60Search = new AmsTask();
@@ -243,7 +254,7 @@ public class SocketBufferServiceImpl implements SocketBufferService {
                 case 115:
                     //60任务取货确认
 
-                    Integer aciIndexPick = Integer.parseInt(event.getLp1());
+                    Integer aciIndexPick = Integer.parseInt(event.getLp4());
                     log.info("MSG_EVENT114:取货确认{}", JSON.toJSONString(event));
 
                     AmsTask task60SearchPick = new AmsTask();
@@ -288,43 +299,43 @@ public class SocketBufferServiceImpl implements SocketBufferService {
                     break;
                 case 135:
                     //stopword异常
-                    Integer index135 = Integer.parseInt(event.getLp2());
-                    log.info("Stopword Error:" + JSON.toJSONString(event));
+//                    Integer index135 = Integer.parseInt(event.getLp2());
+//                    log.info("Stopword Error:" + JSON.toJSONString(event));
 
-                    AmsTask task135 = new AmsTask();
-                    task135.setAciIndex(index135);
-                    task135 = amsTaskService.selectAmsTaskByModel(task135);
+//                    AmsTask task135 = new AmsTask();
+//                    task135.setAciIndex(index135);
+//                    task135 = amsTaskService.selectAmsTaskByModel(task135);
                     // agvUnloadingConfirmService.agvError(event,task135);
                     break;
                 case 136:
                     //failcode异常
-                    Integer index136 = Integer.parseInt(event.getLp2());
-                    log.info("Failcode Error:" + JSON.toJSONString(event));
+//                    Integer index136 = Integer.parseInt(event.getLp2());
+//                    log.info("Failcode Error:" + JSON.toJSONString(event));
 
-                    AmsTask task136 = new AmsTask();
-                    task136.setAciIndex(index136);
-                    task136 = amsTaskService.selectAmsTaskByModel(task136);
+//                    AmsTask task136 = new AmsTask();
+//                    task136.setAciIndex(index136);
+//                    task136 = amsTaskService.selectAmsTaskByModel(task136);
                     // agvUnloadingConfirmService.agvError(event,task136);
                     break;
                 case 137:
                     //stopword2异常
-                    Integer index137 = Integer.parseInt(event.getLp2());
-                    log.info("Stopword2 Error:" + JSON.toJSONString(event));
+//                    Integer index137 = Integer.parseInt(event.getLp2());
+//                    log.info("Stopword2 Error:" + JSON.toJSONString(event));
 
-                    AmsTask task137 = new AmsTask();
-                    task137.setAciIndex(index137);
-                    task137 = amsTaskService.selectAmsTaskByModel(task137);
+//                    AmsTask task137 = new AmsTask();
+//                    task137.setAciIndex(index137);
+//                    task137 = amsTaskService.selectAmsTaskByModel(task137);
                     // agvUnloadingConfirmService.agvError(event,task137);
                     break;
                 case 139:
                 case 140:
                     //AGV其他异常上报
-                    Integer index139 = Integer.parseInt(event.getLp2());
+//                    Integer index139 = Integer.parseInt(event.getLp2());
                     log.info("Safety Laser Trigger:" + JSON.toJSONString(event));
 
-                    AmsTask task139 = new AmsTask();
-                    task139.setAciIndex(index139);
-                    task139 = amsTaskService.selectAmsTaskByModel(task139);
+//                    AmsTask task139 = new AmsTask();
+//                    task139.setAciIndex(index139);
+//                    task139 = amsTaskService.selectAmsTaskByModel(task139);
                     // agvUnloadingConfirmService.agvError(event,task139);
                     break;
                 case 200://NDC eCode = 4001 | 5秒一次 | 4001消息:充电站点 + INDEX + 车号
@@ -385,13 +396,23 @@ public class SocketBufferServiceImpl implements SocketBufferService {
                     });
                     break;
                 case 203: //NDC eCode = 400 | 反馈坐标
-                    CarStatus carStatus = new CarStatus();
-                    carStatus.setCarNo(icarNo);
-                    carStatus.setX(Integer.parseInt( event.getLp2()));
-                    carStatus.setY(Integer.parseInt(event.getLp3()));
-                    carStatus.setBattery(Integer.parseInt(event.getLp4()));
-//                    log.info("获取AGV信息:{},{},{},{}",carStatus.getCarNo(),carStatus.getX(),carStatus.getY(),carStatus.getBattery());
-                    SpringUtil.getApplicationContext().publishEvent(carStatus);
+                    CarInfo carInfo = new CarInfo();
+                    carInfo.setCarno(Long.parseLong(event.getLp1()));
+                    carInfo.setX(Long.parseLong(event.getLp2()));
+                    carInfo.setY(Long.parseLong(event.getLp3()));
+                    carInfo.setBattery(Long.parseLong(event.getLp4()));
+                    SpringUtil.getApplicationContext().publishEvent(carInfo);
+                    break;
+                case 205: //NDC eCode = 401 | 获取车辆状态
+                    CarInfo car = new CarInfo();
+                    car.setCarno(Long.parseLong(event.getLp1()));
+                    if ("3072".equals(event.getLp2()) || "2048".equals(event.getLp2())){
+                        car.setUserdefine4("state_off");
+                        car.setUpdateType("status");
+                        SpringUtil.getApplicationContext().publishEvent(car);
+                    }
+                    car.setState(event.getLp2());
+//                    log.info("AGV状态:{}",car);
                     break;
                 default:
                     log.info("----event:" + eventId);
@@ -400,6 +421,7 @@ public class SocketBufferServiceImpl implements SocketBufferService {
         }
     }
 
+
     @Override
     public void handleMsgOrderAck(byte[] parameters) {
         AmsTask taskBean = new AmsTask();

+ 35 - 40
warewms-ams/src/main/java/com/ruoyi/ams/agv/ndc/service/impl/StatusUpdateServiceImpl.java

@@ -86,9 +86,7 @@ public class StatusUpdateServiceImpl implements StatusUpdateService {
 
 
     @Override
-    public void updateStatus(Long id, Integer carNo) throws InterruptedException {
-        AmsTask amsTask = amsTaskService.selectAmsTaskById(id);
-        if (amsTask != null) {
+    public void updateStatus(AmsTask amsTask, Integer carNo) throws InterruptedException {
             log.info("任务回调-------------------------》" + amsTask.getTaskNo());
             if (amsTask.getAciIndex() == null) {
                 log.error("没有index,未下发的任务");
@@ -96,20 +94,13 @@ public class StatusUpdateServiceImpl implements StatusUpdateService {
             CallbackResult result = new CallbackResult();
             result.setCarNo(carNo);
             result.setTaskNo(amsTask.getTaskNo());
-            //判断状态
-            if (false) {
-//            if (null != amsTask.getSystemStatus() && amsTask.getSystemStatus() == 3) {
-//                result.setState(2);
-//            } else if (null != amsTask.getSystemStatus() && amsTask.getSystemStatus() == 4) {
-//                result.setState(7);
-            } else {
                 WcsTask wcsTask = wcsTaskMapper.selectWcsTaskByTaskNo(amsTask.getTaskNo());
                 switch (amsTask.getEvent().intValue()) {
                     case 86:
                         result.setState(1);
                         break;
                     case 90:
-                        if (wcsTask.getState()==7){
+                        if (ObjectUtil.isNotNull(redisCache.getCacheObject(wcsTask.getTaskNo()+"cancel")) ||wcsTask.getState() == 7) {
                             log.info("任务已取消!");
                             return;
                         }
@@ -152,19 +143,18 @@ public class StatusUpdateServiceImpl implements StatusUpdateService {
                         });
                         break;
                     case 85:
+                        redisCache.setCacheObject(wcsTask.getTaskNo()+"cancel",wcsTask.getTaskNo(),10,TimeUnit.SECONDS);
                         result.setState(7);
                         break;
                     case 113:
                         result.setState(8);
                         break;
                 }
-            }
             log.info("任务回调执行:{}", result);
             wcsTaskService.callBack(result.getTaskNo(), result.getState(), result.getCarNo());
 
             amsTask.setSystemStatus(result.getState());
             amsTaskService.updateAmsTask(amsTask);
-        }
     }
 
     private void endOfMissionSecurity(WcsTask wcsTask) throws InterruptedException {
@@ -185,7 +175,6 @@ public class StatusUpdateServiceImpl implements StatusUpdateService {
             conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.TO_COMMAND_3.getMetadata(), initial);
             conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.ACK_3.getMetadata(), initial);
         }
-        log.info("agv安全退出");
     }
 
     @Override
@@ -194,7 +183,8 @@ public class StatusUpdateServiceImpl implements StatusUpdateService {
         amsTask.setTaskNo(taskNo);
         amsTask = amsTaskService.selectAmsTaskByModel(amsTask);
         //添加取货卸货前安全握
-        if (AGVUnloadOrPickUpSafetyJudgment(taskNo, type,amsTask.getAciIndex().toString())) {
+        if (AGVUnloadOrPickUpSafetyJudgment(taskNo, type, amsTask.getAciIndex().toString())) {
+            log.info("安全进入被驳回");
             return;
         }
         if (amsTask != null) {
@@ -208,11 +198,11 @@ public class StatusUpdateServiceImpl implements StatusUpdateService {
             addTaskForm.setRemark(taskNo);
             // 取货确认
             if (type.equals(AGV_ACTION.PICKUP.getValue())) {
-                addTaskForm.setExt2("08");
+                addTaskForm.setExt2("0E");
                 addTaskForm.setExt3("0001");
                 // 卸货确认
             } else if (type.equals(AGV_ACTION.UNLOAD.getValue())) {
-                addTaskForm.setExt2("09");
+                addTaskForm.setExt2("0A");
                 addTaskForm.setExt3("0001");
             }
             //如果ams_task已经有此任务的待接收m消息,则不生成新的m消息
@@ -230,6 +220,7 @@ public class StatusUpdateServiceImpl implements StatusUpdateService {
         }
     }
 
+
     @Override
     public synchronized void confirmAnalysis(String taskNo, Integer aciIndex, Integer carNo
             , String updateLocation, String updateValue) {
@@ -353,15 +344,15 @@ public class StatusUpdateServiceImpl implements StatusUpdateService {
         byte initial = 0;
         byte submit = 1;
 
-        if (ObjectUtil.isNull(redisCache.getCacheObject("Confirm"+taskNo))){
+        if (ObjectUtil.isNull(redisCache.getCacheObject("Confirm" + taskNo))) {
             log.info("agv进行安全握");
-            redisCache.setCacheObject("Confirm"+taskNo,new Date().getTime(),60,TimeUnit.SECONDS);
-        }else {
-            Long time = Long.parseLong( redisCache.getCacheObject("Confirm" + taskNo).toString());
+            redisCache.setCacheObject("Confirm" + taskNo, new Date().getTime(), 60, TimeUnit.SECONDS);
+        } else {
+            Long time = Long.parseLong(redisCache.getCacheObject("Confirm" + taskNo).toString());
             DateTime dateTime = new DateTime(new Date(time));
             Duration between = LocalDateTimeUtil.between(dateTime.toLocalDateTime(), new DateTime(new Date()).toLocalDateTime());
             long seconds = between.getSeconds();
-            if (seconds>30){
+            if (seconds > 30) {
                 AmsTask addTaskForm = new AmsTask();
                 addTaskForm.setTaskNo(System.currentTimeMillis() + "");
                 addTaskForm.setBusinessType(Constant.TASK_BUSINESS_TYPE.TASK_m.getValue());
@@ -372,11 +363,11 @@ public class StatusUpdateServiceImpl implements StatusUpdateService {
                 addTaskForm.setRemark(taskNo);
                 // 取货确认
                 if (type.equals(AGV_ACTION.PICKUP.getValue())) {
-                    addTaskForm.setExt2("08");
+                    addTaskForm.setExt2("0E");
                     addTaskForm.setExt3("0002");
                     // 卸货确认
                 } else if (type.equals(AGV_ACTION.UNLOAD.getValue())) {
-                    addTaskForm.setExt2("09");
+                    addTaskForm.setExt2("0A");
                     addTaskForm.setExt3("0002");
                 }
                 //如果ams_task已经有此任务的待接收m消息,则不生成新的m消息
@@ -403,35 +394,39 @@ public class StatusUpdateServiceImpl implements StatusUpdateService {
         BaseLocationInfo from = iBaseLocationInfoService.selectBaseLocationInfoById(Long.parseLong(wcsTask.getLocationFrom()));
         if (to.getZoneId().equals(10005L) || from.getZoneId().equals(10005L)) {
             if ("102102".equals(wcsTask.getLocationTo())) {
-                if (conveyorBeltsPlc.readByte(CnveyorBeltsPlcEnum.RELEASE_SIGNAL_1.getMetadata()) == 1) {
+                byte b = conveyorBeltsPlc.readByte(CnveyorBeltsPlcEnum.RELEASE_SIGNAL_1.getMetadata());
+                log.info("plc消息:b:{}",b);
+                if ( b== 1) {
                     log.info("agv结束安全握,一号位");
                     return false;
-                }else{
-                    log.info("一号位禁止进入原因:{}",conveyorBeltsPlc.readByte(CnveyorBeltsPlcEnum.REJECT_REASON_1.getMetadata()));
-                    if (type.equals(UNLOAD.getValue())){
-                        conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.TO_COMMAND_1.getMetadata(),command_21);
-                    }else {
-                        conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.TO_COMMAND_1.getMetadata(),command_22);
+                } else {
+                    log.info("一号位禁止进入原因:{}", conveyorBeltsPlc.readByte(CnveyorBeltsPlcEnum.REJECT_REASON_1.getMetadata()));
+                    if (type.equals(UNLOAD.getValue())) {
+                        conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.TO_COMMAND_1.getMetadata(), command_21);
+                    } else {
+                        conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.TO_COMMAND_1.getMetadata(), command_22);
                     }
                     conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.ACK_1.getMetadata(), submit);
                     Thread.sleep(3000L);
-                    conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.TO_COMMAND_1.getMetadata(),initial);
+                    conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.TO_COMMAND_1.getMetadata(), initial);
                     conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.ACK_1.getMetadata(), initial);
                 }
             } else {
-                if (conveyorBeltsPlc.readByte(CnveyorBeltsPlcEnum.RELEASE_SIGNAL_3.getMetadata()) == 1) {
+                byte b = conveyorBeltsPlc.readByte(CnveyorBeltsPlcEnum.RELEASE_SIGNAL_3.getMetadata());
+                log.info("plc消息:b:{}",b);
+                if (b == 1) {
                     log.info("agv结束安全握,三号位");
                     return false;
-                }else{
-                    log.info("三号位禁止进入原因:{}",conveyorBeltsPlc.readByte(CnveyorBeltsPlcEnum.REJECT_REASON_3.getMetadata()));
-                    if (type.equals(UNLOAD.getValue())){
-                        conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.TO_COMMAND_3.getMetadata(),command_21);
-                    }else {
-                        conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.TO_COMMAND_3.getMetadata(),command_22);
+                } else {
+                    log.info("三号位禁止进入原因:{}", conveyorBeltsPlc.readByte(CnveyorBeltsPlcEnum.REJECT_REASON_3.getMetadata()));
+                    if (type.equals(UNLOAD.getValue())) {
+                        conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.TO_COMMAND_3.getMetadata(), command_21);
+                    } else {
+                        conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.TO_COMMAND_3.getMetadata(), command_22);
                     }
                     conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.ACK_3.getMetadata(), submit);
                     Thread.sleep(3000L);
-                    conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.TO_COMMAND_3.getMetadata(),initial);
+                    conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.TO_COMMAND_3.getMetadata(), initial);
                     conveyorBeltsPlc.writeByte(CnveyorBeltsPlcEnum.ACK_3.getMetadata(), initial);
                 }
             }

+ 69 - 65
warewms-ams/src/main/java/com/ruoyi/ams/business/BusinessServiceImpl.java

@@ -605,9 +605,22 @@ public class BusinessServiceImpl implements IBusinessService {
             amsTask.setStTo(Integer.parseInt(wcsTask.getLocationTo()));
             amsTask.setDeviceName(wcsTask.getDeviceName());
         } else {
-            System.out.println(locFrom);
-            amsTask.setStFrom(locFrom.getAgvStation().intValue());
-            amsTask.setStTo(locTo.getAgvStation().intValue());
+            int from = locFrom.getAgvStation().intValue();
+            int to = locTo.getAgvStation().intValue();
+            if (wcsTask.getTaskType().equals(Constant.TASK_TYPE.MOVEFORWARD.getValue())) {
+                if (locFrom.getZoneId() == 10013L || locFrom.getZoneId() == 10014L) {
+                    from = Integer.parseInt(locFrom.getUserdefine2());
+                }
+                if (locTo.getZoneId() == 10013L || locTo.getZoneId() == 10014L) {
+                    to = Integer.parseInt(locTo.getUserdefine2());
+                }
+                if (locTo.getId()== 114168L){
+                    to = Integer.parseInt(locTo.getUserdefine2());
+                }
+            }
+
+            amsTask.setStTo(to);
+            amsTask.setStFrom(from);
         }
         amsTask.setExt1(wcsTask.getExt1());
         amsTask.setExt2(wcsTask.getExt2());
@@ -656,15 +669,6 @@ public class BusinessServiceImpl implements IBusinessService {
                     break;
                 }
 
-                //转发任务
-                if (StringUtils.isNotEmpty(wcsTask.getTaskType())
-                        && wcsTask.getTaskType().equals(Constant.TASK_TYPE.FORWARD.getValue())) {
-                    sendTask(wcsTask);
-                    wcsTask.setState(10L);
-                    wcsTaskService.updateWcsTask(wcsTask);
-                    break;
-                }
-
                 try {
                     //任务下发判断
                     businessService.taskDispatchStack(wcsTask);
@@ -710,8 +714,8 @@ public class BusinessServiceImpl implements IBusinessService {
         if(isSplit){
             return false;
         }*/
-        if (StringUtils.isNotEmpty(wcsTask.getParentTask())){
-            if(! wcsTaskService.selectWcsTaskByTaskNo(wcsTask.getParentTask()).getState().equals(2L)) {
+        if (StringUtils.isNotEmpty(wcsTask.getParentTask())) {
+            if (!wcsTaskService.selectWcsTaskByTaskNo(wcsTask.getParentTask()).getState().equals(2L)) {
                 return false;
             }
         }
@@ -721,12 +725,12 @@ public class BusinessServiceImpl implements IBusinessService {
         //来源库位
         BaseLocationInfo basLocationInfoFrom = null;
         //目标区域
-        BaseLocationZone basLocationZoneTo = null;
+//        BaseLocationZone basLocationZoneTo = null;
 
         //起始库位
         basLocationInfoFrom = baseLocationInfoService.selectBaseLocationInfoById(Long.parseLong(wcsTask.getLocationFrom()));
         //目标库位
-        BaseLocationInfo locationInfoTo = baseLocationInfoService.selectBaseLocationInfoById(Long.parseLong(wcsTask.getLocationTo()));
+//        BaseLocationInfo locationInfoTo = baseLocationInfoService.selectBaseLocationInfoById(Long.parseLong(wcsTask.getLocationTo()));
         //TODO 前置任务未完成不进行下发
 //        if (businessService.taskDispatchCheck(wcsTask) == false) {
 //            return false;
@@ -752,60 +756,60 @@ public class BusinessServiceImpl implements IBusinessService {
         }
 
         //起始库位是地堆需要判断是否有阻挡
-        if (basLocationInfoFrom.getLocationType().equals("2")) {
-            //判断队列中是否有阻挡在当前任务之前
-            List<WcsTaskLocationDTO> locationDTOS = wcsTaskService.selectTaskByColNo(basLocationInfoFrom.getColNo(), basLocationInfoFrom.getColIndex(), basLocationInfoFrom.getZoneId(), null);
-            if (locationDTOS.size() > 0) {
-                wcsTask.setRemark("队列中有其他任务阻挡,让其他任务先执行");
-                wcsTaskService.updateWcsTask(wcsTask);
-                return false;
-            }
-
-            //判断出库库位前是否有阻挡
-            List<BaseLocationInfo> beforeLoc = baseLocationInfoService.selectBeforeLocationByColNo(basLocationInfoFrom.getColNo(), basLocationInfoFrom.getColIndex());
-            if (beforeLoc != null) {
-                for (BaseLocationInfo b : beforeLoc) {
-                    //如果前面库位不为空,或者状态占用
-                    //TODO 去除已经在任务中的
-                    if (b.getIsEmpty().equals("N")) {
-                        wcsTask.setRemark("有阻挡物,任务无法执行");
-                        wcsTaskService.updateWcsTask(wcsTask);
-                        return false;
-                    }
-                }
-            }
-        }
+//        if (basLocationInfoFrom.getLocationType().equals("2")) {
+//            //判断队列中是否有阻挡在当前任务之前
+//            List<WcsTaskLocationDTO> locationDTOS = wcsTaskService.selectTaskByColNo(basLocationInfoFrom.getColNo(), basLocationInfoFrom.getColIndex(), basLocationInfoFrom.getZoneId(), null);
+//            if (locationDTOS.size() > 0) {
+//                wcsTask.setRemark("队列中有其他任务阻挡,让其他任务先执行");
+//                wcsTaskService.updateWcsTask(wcsTask);
+//                return false;
+//            }
+//
+//            //判断出库库位前是否有阻挡
+//            List<BaseLocationInfo> beforeLoc = baseLocationInfoService.selectBeforeLocationByColNo(basLocationInfoFrom.getColNo(), basLocationInfoFrom.getColIndex());
+//            if (beforeLoc != null) {
+//                for (BaseLocationInfo b : beforeLoc) {
+//                    //如果前面库位不为空,或者状态占用
+//                    //TODO 去除已经在任务中的
+//                    if (b.getIsEmpty().equals("N")) {
+//                        wcsTask.setRemark("有阻挡物,任务无法执行");
+//                        wcsTaskService.updateWcsTask(wcsTask);
+//                        return false;
+//                    }
+//                }
+//            }
+//        }
 
         currentTask = wcsTask;
 
         //目标库位如果是地堆需要判断是否有阻挡
-        if (locationInfoTo != null && locationInfoTo.getLocationType().equals("2")) {
-            List<BaseLocationInfo> beforeLoc = baseLocationInfoService.selectBeforeLocationByColNo(locationInfoTo.getColNo(), locationInfoTo.getColIndex());
-            if (beforeLoc != null) {
-                for (BaseLocationInfo b : beforeLoc) {
-                    //跳过起始库位
-                    if (b.getId().equals(locationInfoTo.getId())) {
-                        continue;
-                    }
-                    //如果前面库位不为空,或者状态占用
-                    //TODO 排除已经在任务中的
-                    if (b.getIsEmpty().equals("N")) {
-                        currentTask.setRemark("目标库位前方有阻挡1");
-                        currentTask.setUpdateDate(new Date());
-                        wcsTaskService.updateWcsTask(currentTask);
-                        return false;
-                    }
-                }
-            }
-
-            List<WcsTaskLocationDTO> dtos = wcsTaskService.selectTaskByColNoAfter(locationInfoTo.getColNo(), locationInfoTo.getColIndex(), locationInfoTo.getZoneId(), null);
-            if (dtos != null && dtos.size() > 0) {
-                currentTask.setRemark("目标库位同列有未完成的任务");
-                wcsTaskService.updateWcsTask(currentTask);
-                return false;
-            }
+//        if (locationInfoTo != null && locationInfoTo.getLocationType().equals("2")) {
+//            List<BaseLocationInfo> beforeLoc = baseLocationInfoService.selectBeforeLocationByColNo(locationInfoTo.getColNo(), locationInfoTo.getColIndex());
+//            if (beforeLoc != null) {
+//                for (BaseLocationInfo b : beforeLoc) {
+//                    //跳过起始库位
+//                    if (b.getId().equals(locationInfoTo.getId())) {
+//                        continue;
+//                    }
+//                    //如果前面库位不为空,或者状态占用
+//                    //TODO 排除已经在任务中的
+//                    if (b.getIsEmpty().equals("N")) {
+//                        currentTask.setRemark("目标库位前方有阻挡1");
+//                        currentTask.setUpdateDate(new Date());
+//                        wcsTaskService.updateWcsTask(currentTask);
+//                        return false;
+//                    }
+//                }
+//            }
 
-        }
+//            List<WcsTaskLocationDTO> dtos = wcsTaskService.selectTaskByColNoAfter(locationInfoTo.getColNo(), locationInfoTo.getColIndex(), locationInfoTo.getZoneId(), null);
+//            if (dtos != null && dtos.size() > 0) {
+//                currentTask.setRemark("目标库位同列有未完成的任务");
+//                wcsTaskService.updateWcsTask(currentTask);
+//                return false;
+//            }
+//
+//        }
 
         //查询是否有更里面的位置可以存放
 //        if (locationInfoTo != null) {

+ 34 - 21
warewms-ams/src/main/java/com/ruoyi/ams/task/service/impl/WcsTaskServiceImpl.java

@@ -69,6 +69,7 @@ public class WcsTaskServiceImpl implements IWcsTaskService {
     private AutoDoorClient autoDoorClient;
 
     private final List<Integer> statusList = Arrays.asList(2, 3, 4, 7);
+    private final List<String> zoneList = Arrays.asList("10002", "10001", "10005", "10016");
     ;
 
     //任务状态翻译
@@ -350,7 +351,9 @@ public class WcsTaskServiceImpl implements IWcsTaskService {
             return AjaxResult.error("agv回传没有任务记录------------->");
         }
 
-        wcsTask.setAgvNo(carNo + "");
+        if (carNo!=null){
+            wcsTask.setAgvNo(carNo + "");
+        }
 
         if (wcsTask.getState() == 2) {
             log.info("已完成的任务无需反馈");
@@ -361,9 +364,11 @@ public class WcsTaskServiceImpl implements IWcsTaskService {
             return AjaxResult.error("已取消的任务无需重复取消");
         }
         //转发类型任务才回调
-        if (wcsTask.getTaskType().equals(Constant.TASK_TYPE.FORWARD.getValue())) {
             try {
                 CarInfo carInfo = new CarInfo();
+                if(ObjectUtil.isNotNull(wcsTask.getAgvNo())){
+                    carInfo.setCarno(Long.parseLong(wcsTask.getAgvNo()));
+                }
                 switch (state) {
                     case 1:
                         wcsTask.setStartTime(new Date());
@@ -382,17 +387,25 @@ public class WcsTaskServiceImpl implements IWcsTaskService {
                         // 解锁终点库位
                         baseLocationInfoService.unLockLocationStockStatus(Long.parseLong(wcsTask.getLocationTo())
                                 , Constant.WAREHOUSE_ID, updateBy);
-                        // 将中间缓存位库存移动到终点
-                        moveMiddleCacheToDestination(wcsTask);
+
+                        if (zoneList.contains(wcsTask.getAreaTo())) {
+                            baseLocationInfoService.updateLocationIdleAndEmpty(Long.parseLong(wcsTask.getLocationTo()),1L , "NDC");
+                        } else {
+                            // 将中间缓存位库存移动到终点
+                            moveMiddleCacheToDestination(wcsTask);
+                        }
                         //释放redis锁
 //                        if (!StringUtils.isEmpty(wcsTask.getExt8())) {
 //                            redisCache.unlockCacheObject(Long.parseLong(wcsTask.getExt8()));
 //                        }
                         carInfo.setUpdateType("status");
-                        carInfo.setState("1");
+                        carInfo.setUserdefine4("state_idle");
                         SpringUtil.getApplicationContext().publishEvent(carInfo);
                         break;
                     case 3:
+                        carInfo.setUpdateType("status");
+                        carInfo.setUserdefine4("state_run");
+                        SpringUtil.getApplicationContext().publishEvent(carInfo);
                         break;
                     case 4:
                         if (wcsTask.getState() == 4) {
@@ -415,11 +428,6 @@ public class WcsTaskServiceImpl implements IWcsTaskService {
 //                        if (!StringUtils.isEmpty(wcsTask.getExt8())) {
 //                            redisCache.unlockCacheObject(Long.parseLong(wcsTask.getExt8()), wcsTask.getLocationFrom());
 //                        }
-
-                        //修改车辆状态
-                        carInfo.setUpdateType("status");
-                        carInfo.setState("2");
-                        SpringUtil.getApplicationContext().publishEvent(carInfo);
                         break;
                     case 5:
                         break;
@@ -466,13 +474,20 @@ public class WcsTaskServiceImpl implements IWcsTaskService {
                         // 取消任务删除中间缓存库存
 //                        cancelTaskDelMiddleCache(wcsTask);
                         carInfo.setUpdateType("status");
-                        carInfo.setState("1");
+                        carInfo.setUserdefine4("state_idle");
                         SpringUtil.getApplicationContext().publishEvent(carInfo);
+                        WcsTask wcsTask1 = new WcsTask();
+                        wcsTask1.setParentTask(wcsTask.getTaskNo());
+                        wcsTask1 = wcsTaskService.selectWcsTaskByModel(wcsTask1);
+                        if (ObjectUtil.isNotNull(wcsTask1)){
+                            wcsTask1.setState(7L);
+                            wcsTaskService.updateWcsTask(wcsTask1);
+                        }
                         break;
                     case 8:
                         //修改车辆状态
                         carInfo.setUpdateType("status");
-                        carInfo.setState("4");
+                        carInfo.setUserdefine4("state_alarm");
                         SpringUtil.getApplicationContext().publishEvent(carInfo);
                         log.error("任务异常状态------------" + wcsTask.getTaskNo());
                         break;
@@ -483,14 +498,12 @@ public class WcsTaskServiceImpl implements IWcsTaskService {
                 log.info(wcsTask.getTaskNo() + "-----" + "回调状态:" + state + "异常", e);
                 wcsTask.setRemark("回调状态:" + state + "异常");
                 //释放redis锁
-                if (!StringUtils.isEmpty(wcsTask.getExt8())) {
-                    redisCache.unlockCacheObject(Long.parseLong(wcsTask.getExt8()));
-                }
-                throw new RuntimeException();
+//                if (!StringUtils.isEmpty(wcsTask.getExt8())) {
+//                    redisCache.unlockCacheObject(Long.parseLong(wcsTask.getExt8()));
+//                }
+//                throw new RuntimeException();
+                e.printStackTrace();
             }
-        } else {
-
-        }
 
         wcsTask.setUpdateBy(updateBy);
         wcsTask.setState(state.longValue());
@@ -498,8 +511,8 @@ public class WcsTaskServiceImpl implements IWcsTaskService {
         wcsTaskService.updateWcsTask(wcsTask);
         //根据具体状态反馈WMS
         if (statusList.contains(state)) {
-            if (state ==3){
-                wcsTask.setState(1L);
+            if (state == 3 && ObjectUtil.isNull(wcsTask.getParentTask()) ) {
+                    wcsTask.setState(1L);
             }
             SpringUtil.getApplicationContext().publishEvent(wcsTask);
         }

+ 11 - 1
warewms-base/src/main/java/com/ruoyi/base/constant/Constant.java

@@ -438,7 +438,17 @@ public class Constant {
         /**
          * 转发任务
          */
-        FORWARD("FW");
+        FORWARD("FW"),
+
+        /**
+         * 前移车
+         */
+        MOVEFORWARD("MR"),
+
+        /**
+         * 三向车
+         */
+        ThreeWayCar("TWC");
         private String value;
 
         TASK_TYPE(String value) {

+ 2 - 0
warewms-base/src/main/java/com/ruoyi/base/mapper/BaseLocationInfoMapper.java

@@ -254,5 +254,7 @@ public interface BaseLocationInfoMapper {
 
     List<BaseLocationInfo> selectSortedLocatinListByZoneIdNoTask(BaseLocationInfo baseLocationInfo);
 
+    List<BaseLocationInfo> selectSortedLocatinListByZoneIdNoTaskAndOptimal(@Param("baseLocationInfo")BaseLocationInfo baseLocationInfo,@Param("oderBy")String oderBy);
+
     BaseLocationInfo selectLocationByAddress(@Param("colNo") String colNo,@Param("rowNo") String rowNo,@Param("shiftNo") String shiftNo,@Param("zoneId") String zoneId);
 }

+ 1 - 1
warewms-base/src/main/java/com/ruoyi/base/service/IBaseLocationInfoService.java

@@ -304,7 +304,7 @@ public interface IBaseLocationInfoService {
     /**
      * 获取不在任务中的空库位
      */
-    List<BaseLocationInfo> selectSortedLocatinListByZoneIdNoTask(BaseLocationInfo locatio);
+    List<BaseLocationInfo> selectSortedLocatinListByZoneIdNoTask(BaseLocationInfo locatio, String oderBy);
 
 
     AjaxResult syncLocStatus(List<BaseLocationInfo> locationInfoList);

+ 6 - 3
warewms-base/src/main/java/com/ruoyi/base/service/impl/BaseLocationInfoServiceImpl.java

@@ -17,7 +17,6 @@ import com.ruoyi.common.utils.StringUtils;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.data.redis.core.RedisTemplate;
 import org.springframework.stereotype.Service;
 
 import java.util.ArrayList;
@@ -424,8 +423,12 @@ public class BaseLocationInfoServiceImpl implements IBaseLocationInfoService {
     }
 
     @Override
-    public List<BaseLocationInfo> selectSortedLocatinListByZoneIdNoTask(BaseLocationInfo location) {
-        return baseLocationInfoMapper.selectSortedLocatinListByZoneIdNoTask(location);
+    public List<BaseLocationInfo> selectSortedLocatinListByZoneIdNoTask(BaseLocationInfo location, String oderBy) {
+        if (oderBy ==null){
+            return baseLocationInfoMapper.selectSortedLocatinListByZoneIdNoTask(location);
+        }else {
+            return baseLocationInfoMapper.selectSortedLocatinListByZoneIdNoTaskAndOptimal(location,oderBy);
+        }
     }
 
     @Override

+ 42 - 21
warewms-base/src/main/java/com/ruoyi/base/service/impl/CarInfoServiceImpl.java

@@ -1,10 +1,16 @@
 package com.ruoyi.base.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.extra.spring.SpringUtil;
 import com.ruoyi.base.domain.CarInfo;
+import com.ruoyi.base.domain.dto.CarInfoBo;
+import com.ruoyi.base.domain.dto.CarInfoDTO;
 import com.ruoyi.base.mapper.CarInfoMapper;
 import com.ruoyi.base.service.ICarInfoService;
+import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.core.redis.RedisCache;
+import com.ruoyi.common.utils.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.context.event.EventListener;
 import org.springframework.scheduling.annotation.Async;
@@ -28,7 +34,8 @@ public class CarInfoServiceImpl implements ICarInfoService {
     @Autowired
     RedisCache redisCache;
 
-    private static CopyOnWriteArrayList<CarInfo> carList ;
+
+    private static CopyOnWriteArrayList<CarInfo> carList;
 
     /**
      * 查询车辆信息
@@ -49,7 +56,7 @@ public class CarInfoServiceImpl implements ICarInfoService {
      */
     @Override
     public List<CarInfo> selectCarInfoList(CarInfo carInfo) {
-        if (ObjectUtil.isNull(carList) ||carList.size() ==0){
+        if (ObjectUtil.isNull(carList) || carList.size() == 0) {
             carList = new CopyOnWriteArrayList<>(carInfoMapper.selectCarInfoList(carInfo));
         }
         return carList;
@@ -117,38 +124,52 @@ public class CarInfoServiceImpl implements ICarInfoService {
 
     @EventListener
     @Async
-    public void  updateStatus(CarInfo carInfo){
+    public void updateStatus(CarInfo carInfo) {
         int index = -1;
-        if (ObjectUtil.isNull(carList)){
+        CarInfo baseDate = new CarInfo();
+
+        if (ObjectUtil.isNull(carList)) {
             selectCarInfoList(new CarInfo());
         }
         for (int i = 0; i < carList.size(); i++) {
-            if (carList.get(i).getCarno().equals(carInfo.getCarno())){
-                carInfo = carList.get(i);
+            if (carList.get(i).getCarno().equals(carInfo.getCarno())) {
+                baseDate = carList.get(i);
                 index = i;
             }
         }
-        if (index ==-1){
+        if (index == -1) {
             return;
         }
-        if ("status".equals(carInfo.getUpdateType())){
-           if(!carInfo.getState().equals(carInfo.getState())){
-               carInfo.setState(carInfo.getState());
-               carList.set(carInfo.getCarno().intValue() - 1,carInfo);
-           }
-        }else {
+        if ("status".equals(carInfo.getUpdateType())) {
+            if (!carInfo.getUserdefine4().equals(baseDate.getUserdefine4())) {
+                baseDate.setUserdefine4(carInfo.getUserdefine4());
+                if ("state off".equals(carInfo.getUserdefine4())) {
+                    redisCache.setCacheObject("carStatusHistory:" + carInfo.getCarno(), baseDate.getUserdefine4());
+                }
+                if ("state off".equals(baseDate.getUserdefine4())) {
+                    String status = redisCache.getCacheObject("carStatusHistory:" + carInfo.getCarno()).toString();
+                    if (StringUtils.isNotEmpty(status)) {
+                        baseDate.setUserdefine4(status);
+                    }
+                }
+                carList.set(index, baseDate);
+                SpringUtil.getApplicationContext().publishEvent(BeanUtil.copyProperties(baseDate, CarInfoDTO.class));
+            }
+        } else {
             int a = 0;
-            if(!carInfo.getX().equals(carInfo.getX())){
-                carInfo.setX(carInfo.getX());
-                a =1;
+            if (!carInfo.getX().equals(baseDate.getX())) {
+                baseDate.setX(carInfo.getX());
+                a = 1;
             }
-            if(!carInfo.getY().equals(carInfo.getY())){
-                carInfo.setY(carInfo.getY());
-                a =1;
+            if (!carInfo.getY().equals(baseDate.getY())) {
+                baseDate.setY(carInfo.getY());
+                a = 1;
             }
-            if (a==1){
-                carList.set(carInfo.getCarno().intValue() - 1,carInfo);
+            if (a == 1) {
+                carList.set(index, baseDate);
             }
+            SpringUtil.getApplicationContext().publishEvent(BeanUtil.copyProperties(baseDate, CarInfoBo.class));
         }
     }
+
 }

+ 32 - 0
warewms-base/src/main/resources/mapper/base/BaseLocationInfoMapper.xml

@@ -711,4 +711,36 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         and row_no	= #{rowNo}
         and col_no = #{colNo}
     </select>
+    <select id="selectSortedLocatinListByZoneIdNoTaskAndOptimal"
+            parameterType="BaseLocationInfo"  resultMap="BaseLocationInfoResult">
+        <include refid="selectBaseLocationInfoVo"/>
+        <where>
+        <if test="baseLocationInfo.id != null ">and id like concat('%', #{baseLocationInfo.id}, '%')</if>
+        <if test="baseLocationInfo.warehouseId != null ">and warehouse_id = #{baseLocationInfo.warehouseId}</if>
+        <if test="baseLocationInfo.zoneId != null ">and zone_id = #{baseLocationInfo.zoneId}</if>
+        <if test="baseLocationInfo.zoneName != null ">and zone_name = #{baseLocationInfo.zoneName}</if>
+        <if test="baseLocationInfo.locationNo != null  and baseLocationInfo.locationNo != ''">and baseLocationInfolocation_no like concat('%', #{locationNo}, '%')
+        </if>
+        <if test="baseLocationInfo.agvStation != null  and baseLocationInfo.agvStation != ''">and agv_station like concat('%', #{baseLocationInfo.agvStation}, '%')
+        </if>
+        <if test="baseLocationInfo.stockStatus != null  and baseLocationInfo.stockStatus != ''">and stock_status = #{baseLocationInfo.stockStatus}</if>
+        <if test="baseLocationInfo.isEmpty != null  and baseLocationInfo.isEmpty != ''">and is_empty = #{baseLocationInfo.isEmpty}</if>
+        <if test="baseLocationInfo.locationType != null  and baseLocationInfo.locationType != ''">and location_type = #{baseLocationInfo.locationType}</if>
+        and id not in(
+        SELECT
+        location_from AS id
+        FROM
+        wcs_task
+        WHERE
+        state IN ( 1, 3, 4, 5, 8, 9, 10 )
+        UNION
+        SELECT
+        location_to AS id
+        FROM
+        wcs_task
+        WHERE
+        state IN ( 1, 3, 4, 5, 8, 9, 10 ))
+        order by #{oderBy}
+        </where>
+    </select>
 </mapper>

+ 21 - 18
warewms-tianao/src/main/java/com/ruoyi/tianao/job/FeedbackJob.java

@@ -6,10 +6,12 @@ import com.ruoyi.base.domain.CarInfo;
 import com.ruoyi.base.service.ICarInfoService;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.system.init.PublishAGVInfo;
+import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Component;
 
 @Component("feedbackJob")
+@Slf4j
 public class FeedbackJob {
 
     @Autowired
@@ -19,26 +21,27 @@ public class FeedbackJob {
     PublishAGVInfo publishAGVInfo;
 
     public void feedbackVehicleStatus(){
-        JSONArray objects = new JSONArray();
-        for (CarInfo carInfo : iCarInfoService.selectCarInfoList(new CarInfo())) {
-            JSONObject jsonObject = new JSONObject();
-            jsonObject.set("carNo",carInfo.getUserdefine2());
-            jsonObject.set("status",carInfo.getState());
-            objects.add(jsonObject);
-        }
+//        JSONArray objects = new JSONArray();
+//        for (CarInfo carInfo : iCarInfoService.selectCarInfoList(new CarInfo())) {
+//            JSONObject jsonObject = new JSONObject();
+//            jsonObject.set("carNo",carInfo.getUserdefine2());
+//            jsonObject.set("status",carInfo.getState());
+//            objects.add(jsonObject);
+//        }
     }
 
     public void feedbackForkliftCoordinates(){
-        JSONArray objects = new JSONArray();
-        for (CarInfo carInfo : iCarInfoService.selectCarInfoList(new CarInfo())) {
-            JSONObject jsonObject = new JSONObject();
-            jsonObject.set("euqNo",carInfo.getUserdefine2());
-            jsonObject.set("X",carInfo.getX());
-            jsonObject.set("Y",carInfo.getY());
-            jsonObject.set("type",carInfo.getUserdefine3());
-            jsonObject.set("addTime", DateUtils.getTime());
-            objects.add(jsonObject);
-        }
-        publishAGVInfo.publishMessage(objects.toString());
+//        JSONArray objects = new JSONArray();
+//        for (CarInfo carInfo : iCarInfoService.selectCarInfoList(new CarInfo())) {
+//            JSONObject jsonObject = new JSONObject();
+//            jsonObject.set("agvNo",carInfo.getUserdefine1());
+//            jsonObject.set("x",carInfo.getX());
+//            jsonObject.set("y",carInfo.getY());
+//            jsonObject.set("equType",carInfo.getUserdefine3());
+//            jsonObject.set("addTime", DateUtils.getTime());
+//            objects.add(jsonObject);
+//        }
+//        log.info("发送坐标信息,{}",objects);
+//        publishAGVInfo.publishMessage(objects.toString());
     }
 }

+ 29 - 3
warewms-tianao/src/main/java/com/ruoyi/tianao/service/TianaoService.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import com.ruoyi.ams.agv.ndc.domain.AmsTask;
 import com.ruoyi.ams.agv.ndc.entity.CarStatus;
 import com.ruoyi.ams.task.domain.WcsTask;
+import com.ruoyi.base.domain.CarInfo;
 import com.ruoyi.tianao.domian.TianaoTask;
 
 /**
@@ -17,15 +18,40 @@ import com.ruoyi.tianao.domian.TianaoTask;
  **/
 public interface TianaoService {
 
+    /**
+     * 添加出入库任务
+     * @param tianaoTask
+     * @return
+     */
     JSONObject addTask(TianaoTask tianaoTask) ;
 
+    /**
+     * 取消任务
+     * @param tianaoTask
+     * @return
+     */
     JSONObject cancelTask(TianaoTask tianaoTask);
 
+    /**
+     * 修改目标点
+     * @param tianaoTask
+     * @return
+     */
     JSONObject updateTask(TianaoTask tianaoTask);
 
     JSONObject returnJson(String code, String msg, String state);
 
-    String testTask(WcsTask wcsTask);
-
-    String testAgvAddress(CarStatus car);
+    /**
+     * 添加普通移库任务
+     * @param tianaoTask
+     * @return
+     */
+    JSONObject addOrdinaryTask(TianaoTask tianaoTask);
+
+    /**
+     * 添加紧急任务
+     * @param tianaoTask
+     * @return
+     */
+    JSONObject addUrgentTask(TianaoTask tianaoTask);
 }

+ 199 - 34
warewms-tianao/src/main/java/com/ruoyi/tianao/service/impl/TianaoServiceImpl.java

@@ -3,6 +3,7 @@ package com.ruoyi.tianao.service.impl;
 import cn.hutool.core.util.ObjectUtil;
 import cn.hutool.http.HttpRequest;
 import com.alibaba.fastjson.JSONObject;
+import com.github.rholder.retry.*;
 import com.github.xingshuangs.iot.protocol.s7.service.S7PLC;
 import com.ruoyi.ams.agv.ndc.domain.AmsTask;
 import com.ruoyi.ams.agv.ndc.entity.CarStatus;
@@ -14,13 +15,17 @@ import com.ruoyi.ams.task.service.IWcsTaskService;
 import com.ruoyi.base.constant.Constant;
 import com.ruoyi.base.domain.BaseLocationInfo;
 import com.ruoyi.base.domain.CarInfo;
+import com.ruoyi.base.domain.dto.CarInfoBo;
+import com.ruoyi.base.domain.dto.CarInfoDTO;
 import com.ruoyi.base.mapper.BaseLocationZoneMapper;
 import com.ruoyi.base.service.IBaseLocationInfoService;
 import com.ruoyi.base.service.ICarInfoService;
+import com.ruoyi.base.service.impl.CarInfoServiceImpl;
 import com.ruoyi.common.core.redis.RedisCache;
 import com.ruoyi.common.exception.ServiceException;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.system.init.PublishAGVInfo;
 import com.ruoyi.system.service.ISysConfigService;
 import com.ruoyi.tianao.domian.TianaoTask;
 import com.ruoyi.system.init.PlcConnectServiceRunner;
@@ -30,12 +35,15 @@ import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
 import org.springframework.context.event.EventListener;
 import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
+import javax.annotation.Resource;
 import java.util.Arrays;
 import java.util.Date;
 import java.util.List;
+import java.util.concurrent.ExecutionException;
 import java.util.concurrent.TimeUnit;
 
 /**
@@ -84,24 +92,32 @@ public class TianaoServiceImpl implements TianaoService {
     private final List<Long> statusLsit = Arrays.asList(2L, 5L, 6L, 7L);
 
     private final List<Long> zoneList = Arrays.asList(10003L, 10005L, 10016L, 10015L);
+
     private final List<Long> notInventory = Arrays.asList(10005L, 10016L);
 
+    private final List<Long>  threeAgvTaskZoneList = Arrays.asList(10009L, 10000L);
     @Autowired
     private RedisCache redisCache;
 
     @Autowired
     ICarInfoService iCarInfoService;
 
+    @Autowired
+    PublishAGVInfo publishAGVInfo;
+
+    @Resource
+    ThreadPoolTaskExecutor threadPoolTaskExecutor;
 
     @Override
     @Transactional
     public JSONObject addTask(TianaoTask tianaoTask) {
         try {
             if (redisCache.checkIsLock(tianaoTask.getLcs_task_id())) {
-                List<WcsTask> wcsTaskList = wcsTaskMapper.selectWcsTaskByLcsTaskId(tianaoTask.getLcs_task_id());
-                if (ObjectUtil.isNotNull(wcsTaskList) || wcsTaskList.size() > 0) {
-                    return returnJson("e0001", "任务Id已重复", "fail");
-                }
+               return returnJson("e0001", "任务Id已重复", "fail");
+            }
+            List<WcsTask> wcsTaskList = wcsTaskMapper.selectWcsTaskByLcsTaskId(tianaoTask.getLcs_task_id());
+            if (ObjectUtil.isNotNull(wcsTaskList) && wcsTaskList.size() > 0) {
+                return returnJson("e0001", "任务Id已重复", "fail");
             }
             if (tianaoTask.getFrom_location().equals(tianaoTask.getTo_location())) {
                 return returnJson("e0001", "起始库位与目标库位不能相同", "fail");
@@ -122,7 +138,7 @@ public class TianaoServiceImpl implements TianaoService {
             }
             //判断是否需要拆分任务
             if (zoneList.contains(formAddress.getZoneId()) || zoneList.contains(toAddress.getZoneId())) {
-                WcsTask wcsTask = createWcsTask(tianaoTask, formAddress, toAddress, "0");
+                WcsTask wcsTask = createWcsTask(tianaoTask, formAddress, toAddress, "0", Constant.TASK_TYPE.MOVEFORWARD.getValue());
                 formAddress.setIsEmpty("N");
                 iBaseLocationInfoService.updateBaseLocationInfo(formAddress);
                 if (notInventory.contains(toAddress.getZoneId())) {
@@ -133,22 +149,45 @@ public class TianaoServiceImpl implements TianaoService {
             } else {
                 //拆分任务,获取任务执行的中转区
                 Long zoneId = null;
+                String oderBy = null;
                 if (formAddress.getZoneId().equals(10009L) || toAddress.getZoneId().equals(10009L)) {
                     zoneId = Long.parseLong(iSysConfigService.selectConfigByKey("sys.area.B2"));
-                } else {
+                }
+                if (formAddress.getZoneId().equals(10000L) || toAddress.getZoneId().equals(10000L)) {
                     zoneId = Long.parseLong(iSysConfigService.selectConfigByKey("sys.area.C"));
+                    if (toAddress.getColIndex() == 8 || toAddress.getColIndex() == 7) {
+                        oderBy = "userdefine3";
+                    }
+                    if (toAddress.getColIndex() <= 6 && toAddress.getColIndex() >= 3) {
+                        oderBy = "userdefine4";
+                    }
+                    if (toAddress.getColIndex() == 2 || toAddress.getColIndex() == 1) {
+                        oderBy = "userdefine5";
+                    }
+                }
+                if (zoneId ==null){
+                    return returnJson("e0001", "该任务起始点与目标点不符合出入库任务", "fail");
+                }
+                String taskType1 = null;
+                String taskType2 = null;
+                if (formAddress.getZoneId().equals(10009L) || formAddress.getZoneId().equals(10000L)) {
+                    taskType1 = Constant.TASK_TYPE.ThreeWayCar.getValue();
+                    taskType2 = Constant.TASK_TYPE.MOVEFORWARD.getValue();
+                } else {
+                    taskType1 = Constant.TASK_TYPE.MOVEFORWARD.getValue();
+                    taskType2 = Constant.TASK_TYPE.ThreeWayCar.getValue();
                 }
                 //选择中转区空库位
                 BaseLocationInfo baseLocationInfo = new BaseLocationInfo();
                 baseLocationInfo.setZoneId(zoneId);
                 baseLocationInfo.setIsEmpty("Y");
-                List<BaseLocationInfo> baseLocationInfos = iBaseLocationInfoService.selectSortedLocatinListByZoneIdNoTask(baseLocationInfo);
-                if (ObjectUtil.isNull(baseLocationInfos) && baseLocationInfos.size() == 0) {
+                List<BaseLocationInfo> baseLocationInfos = iBaseLocationInfoService.selectSortedLocatinListByZoneIdNoTask(baseLocationInfo, oderBy);
+                if (ObjectUtil.isNull(baseLocationInfos) || baseLocationInfos.size() == 0) {
                     return returnJson("e0001", "没有合适的中转库位", "fail");
                 }
-                System.out.println(baseLocationInfos.get(0));
-                WcsTask wcsTask1 = createWcsTask(tianaoTask, formAddress, baseLocationInfos.get(0), "1");
-                WcsTask wcsTask2 = createWcsTask(tianaoTask, baseLocationInfos.get(0), toAddress, "0");
+                WcsTask wcsTask1 = createWcsTask(tianaoTask, formAddress, baseLocationInfos.get(0), "1", taskType1);
+                Thread.sleep(20L);
+                WcsTask wcsTask2 = createWcsTask(tianaoTask, baseLocationInfos.get(0), toAddress, "0", taskType2);
                 wcsTask2.setParentTask(wcsTask1.getTaskNo());
                 formAddress.setIsEmpty("N");
                 iBaseLocationInfoService.updateBaseLocationInfo(formAddress);
@@ -225,7 +264,7 @@ public class TianaoServiceImpl implements TianaoService {
                 if (ObjectUtil.isNotNull(carNo)) {
                     //修改AGV任务目标地址
                     statusUpdateService.confirmAnalysis(wcsTask.getTaskNo(), amsTask.getAciIndex(), carNo
-                            , "07", baseLocationInfo.getAgvStation().toString());
+                            , "09", baseLocationInfo.getAgvStation().toString());
                     Thread.sleep(1000);
                     //添加切换导航的对接
 //                    statusUpdateService.changeNavigation(carNo,amsTask.getIkey(),"0001");
@@ -244,26 +283,59 @@ public class TianaoServiceImpl implements TianaoService {
         return returnJson("e0001", "任务修改卸货点失败", "fail");
     }
 
-
     @EventListener
     @Async
-    public String getAGVCoordinate(CarStatus car) {
+    public String returnAGVCoordinate(CarInfoDTO car) {
         JSONObject jsonObject = new JSONObject();
         JSONObject jsonObject1 = new JSONObject();
-        jsonObject1.put("carNo", car.getCarNo());
-        jsonObject1.put("y", car.getY());
-        jsonObject1.put("x", car.getX());
+        jsonObject1.put("agvNo", car.getUserdefine1());
+        if (!car.getY().equals(0L) || !car.getX().equals(0L)) {
+            jsonObject1.put("x", car.getX());
+            jsonObject1.put("y", car.getY());
+        }
+        jsonObject1.put("status", car.getUserdefine4());
         jsonObject1.put("time", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date()));
         jsonObject.put("HEADER", jsonObject1);
-//        log.info("反馈AGV坐标请求参数:{}", jsonObject);
-//        String body = HttpRequest.post(AGVStatusBackUrl)
-//                .body(jsonObject.toString())
-//                .contentType("application/json").execute().body();
-//        log.info("反馈AGV坐标回调结果:{}", body);
-//        return body;
-        return null;
+        log.info("反馈AGV坐标和状态请求参数:{}", jsonObject);
+        String body = null;
+        try {
+             body = HttpRequest.post(AGVStatusBackUrl)
+                    .body(jsonObject.toString())
+                    .contentType("application/json").execute().body();
+        }catch (Exception e){
+            log.info("反馈AGV坐标和状态回调失败,msg:{},将进行重试",e);
+            retryCallback(AGVStatusBackUrl,jsonObject);
+        }
+
+        log.info("反馈AGV坐标和状态回调结果:{}", body);
+        return body;
     }
 
+    /**
+     * 异步发送AGV坐标
+     * @param carInfoBo
+     */
+    @EventListener
+    @Async
+    public void returnAGVAddress(CarInfoBo carInfoBo) {
+        if (carInfoBo.getY().equals(0L) || carInfoBo.getX().equals(0L)) {
+            return;
+        }
+        JSONObject jsonObject = new JSONObject();
+        jsonObject.put("agvNo", carInfoBo.getUserdefine1());
+        jsonObject.put("x", carInfoBo.getX());
+        jsonObject.put("y", carInfoBo.getY());
+        jsonObject.put("equType", carInfoBo.getUserdefine3());
+        jsonObject.put("addTime", DateUtils.getTime());
+//        log.info("MQTT反馈AGV坐标:{}", jsonObject);
+        publishAGVInfo.publishMessage(jsonObject.toString());
+    }
+
+    /**
+     * 异步反馈任务状态
+     * @param wcsTask
+     * @return
+     */
     @EventListener
     @Async
     public String tianaoCallBack(WcsTask wcsTask) {
@@ -271,6 +343,12 @@ public class TianaoServiceImpl implements TianaoService {
             if (wcsTask.getState().equals(2L) && "1".equals(wcsTask.getExt5())) {
                 return null;
             }
+            if (StringUtils.isNotEmpty(wcsTask.getParentTask()) && wcsTask.getState().equals(4L)) {
+                return null;
+            }
+            if (StringUtils.isNotEmpty(wcsTask.getParentTask()) && wcsTask.getState().equals(3L)) {
+                wcsTask.setState(4L);
+            }
             JSONObject jsonObject = new JSONObject();
             System.out.println(wcsTask.getAgvNo());
             if ((ObjectUtil.isNotNull(wcsTask.getAgvNo()) || StringUtils.isNotEmpty(wcsTask.getAgvNo())) && !"null".equals(wcsTask.getAgvNo())) {
@@ -287,15 +365,28 @@ public class TianaoServiceImpl implements TianaoService {
             jsonObject.put("task_status", wcsTask.getState());
             jsonObject.put("time", DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, new Date()));
             log.info("反馈任务状态请求参数:{}", jsonObject);
-            String body = HttpRequest.post(taskBackUrl)
-                    .body(jsonObject.toString())
-                    .contentType("application/json").execute().body();
+            String body = null;
+            try {
+                body = HttpRequest.post(taskBackUrl)
+                        .body(jsonObject.toString())
+                        .contentType("application/json").execute().body();
+            }catch (Exception e){
+                log.error("反馈任务状态失败,msg:{},正进行重试",e);
+                retryCallback(taskBackUrl,jsonObject);
+            }
             log.info("反馈任务状态回调结果:{}", body);
             return body;
         }
         return null;
     }
 
+    /**
+     * 反馈格式化
+     * @param code
+     * @param msg
+     * @param state
+     * @return
+     */
     @Override
     public JSONObject returnJson(String code, String msg, String state) {
         JSONObject jsonObject = new JSONObject();
@@ -305,22 +396,68 @@ public class TianaoServiceImpl implements TianaoService {
         return jsonObject;
     }
 
-
+    /**
+     * 添加普通任务
+     * @param tianaoTask
+     * @return
+     */
     @Override
-    public String testTask(WcsTask wcsTask) {
-        return tianaoCallBack(wcsTask);
+    public JSONObject addOrdinaryTask(TianaoTask tianaoTask) {
+        if (redisCache.checkIsLock(tianaoTask.getLcs_task_id())){
+            return returnJson("e0001", "任务Id已重复", "fail");
+        }
+        List<WcsTask> wcsTaskList = wcsTaskMapper.selectWcsTaskByLcsTaskId(tianaoTask.getLcs_task_id());
+        if (ObjectUtil.isNotNull(wcsTaskList) && wcsTaskList.size() > 0) {
+            return returnJson("e0001", "任务Id已重复", "fail");
+        }
+        if (tianaoTask.getFrom_location().equals(tianaoTask.getTo_location())) {
+            return returnJson("e0001", "起始库位与目标库位不能相同", "fail");
+        }
+        BaseLocationInfo formAddress = iBaseLocationInfoService.selectBaseLocationInfoByIdOrNo(tianaoTask.getFrom_location(), Constant.WAREHOUSE_ID);
+        if (ObjectUtil.isNull(formAddress)) {
+            return returnJson("e0001", "起始位置不存在", "fail");
+        }
+        BaseLocationInfo toAddress = iBaseLocationInfoService.selectBaseLocationInfoByIdOrNo(tianaoTask.getTo_location(), Constant.WAREHOUSE_ID);
+        if (ObjectUtil.isNull(toAddress)) {
+            return returnJson("e0001", "目标位置不存在", "fail");
+        }
+        if (!notInventory.contains(toAddress.getZoneId()) && "N".equals(toAddress.getIsEmpty())) {
+            return returnJson("e0001", "目标位置库存不为空", "fail");
+        }
+        if (formAddress.getZoneId().equals(10004L) || toAddress.getZoneId().equals(10004L)) {
+            return returnJson("e0001", "该库区无法进行任务!", "fail");
+        }
+        WcsTask wcsTask = null;
+        if (threeAgvTaskZoneList.contains(formAddress.getZoneId()) || threeAgvTaskZoneList.contains(toAddress.getZoneId())){
+            wcsTask = createWcsTask(tianaoTask, formAddress, toAddress, "0", Constant.TASK_TYPE.ThreeWayCar.getValue());
+        }else {
+            wcsTask = createWcsTask(tianaoTask, formAddress, toAddress, "0", Constant.TASK_TYPE.MOVEFORWARD.getValue());
+        }
+        if ("Y".equals(formAddress.getIsEmpty())){
+            formAddress.setIsEmpty("N");
+            iBaseLocationInfoService.updateBaseLocationInfo(formAddress);
+        }
+        wcsTaskService.insertWcsTask(wcsTask);
+        redisCache.setCacheObject(tianaoTask.getLcs_task_id(), tianaoTask.getLcs_task_id(), 30, TimeUnit.SECONDS);
+        return returnJson("00000", "任务发起成功", "ok");
     }
 
+    /**
+     * 添加紧急任务
+     * @param tianaoTask
+     * @return
+     */
     @Override
-    public String testAgvAddress(CarStatus car) {
-        return getAGVCoordinate(car);
+    public JSONObject addUrgentTask(TianaoTask tianaoTask) {
+        return null;
     }
 
-    private WcsTask createWcsTask(TianaoTask tianaoTask, BaseLocationInfo formAddress, BaseLocationInfo toAddress, String frontLoadingOrNot) {
+
+    private WcsTask createWcsTask(TianaoTask tianaoTask, BaseLocationInfo formAddress, BaseLocationInfo toAddress, String frontLoadingOrNot, String taskType) {
         WcsTask wcsTask = new WcsTask();
         wcsTask.setTaskNo(System.currentTimeMillis() + "");
         wcsTask.setState(9L);
-        wcsTask.setTaskType(Constant.TASK_TYPE.FORWARD.getValue());
+        wcsTask.setTaskType(taskType);
         wcsTask.setBusinessType("01");
         wcsTask.setAreaFrom(formAddress.getZoneId().toString());
         wcsTask.setLocationFrom(formAddress.getId().toString());
@@ -336,4 +473,32 @@ public class TianaoServiceImpl implements TianaoService {
         wcsTask.setExt6(tianaoTask.getTask_type());
         return wcsTask;
     }
+
+    private void retryCallback(String url,JSONObject parameter){
+        threadPoolTaskExecutor.execute (() -> {
+            Retryer<Boolean> retryer = RetryerBuilder.<Boolean>newBuilder()
+                    .retryIfResult(Boolean.FALSE::equals)
+                    .retryIfExceptionOfType(Exception.class)
+                    .withStopStrategy(StopStrategies.stopAfterAttempt(5))
+                    .withWaitStrategy(WaitStrategies.fixedWait(30, TimeUnit.SECONDS))
+                    .build();
+            try {
+                retryer.call(() -> {
+                    try {
+                        String body = HttpRequest.post(url)
+                                .body(parameter.toString())
+                                .contentType("application/json").execute().body();
+                        log.info("重试回调URL:{},结果:{}",url,body);
+                    } catch (Exception e) {
+                        return false;
+                    }
+                    return true;
+                });
+            } catch (ExecutionException e) {
+                throw new RuntimeException(e);
+            } catch (RetryException e) {
+                throw new RuntimeException(e);
+            }
+        });
+    }
 }