LES任务下发、LES回传;AGV任务下发;AGV上报
							parent
							
								
									4673e9fa42
								
							
						
					
					
						commit
						8cdfe962f6
					
				| 
						 | 
				
			
			@ -1,35 +1,27 @@
 | 
			
		|||
package com.youchain.exception.handler;
 | 
			
		||||
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
import com.alibaba.fastjson.JSONObject;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
 | 
			
		||||
import java.time.LocalDateTime;
 | 
			
		||||
 | 
			
		||||
@Data
 | 
			
		||||
@Slf4j
 | 
			
		||||
public class LesResult {
 | 
			
		||||
    private Object data;//数据
 | 
			
		||||
    private String debugMsg;//调试信息
 | 
			
		||||
    private String displayMsg;//描述信息,失败原因
 | 
			
		||||
    private String requestId;//请求id
 | 
			
		||||
    private int resultCode;//返回码
 | 
			
		||||
    private String serverTime;//请求时间,服务器时间戳
 | 
			
		||||
 | 
			
		||||
    public static LesResult fail(String requestId, String displayMsg) {
 | 
			
		||||
        return result(requestId,400, displayMsg, null);
 | 
			
		||||
    public static JSONObject fail(String requestId, String displayMsg) {
 | 
			
		||||
        return result(requestId, 400, displayMsg, null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static LesResult success(String requestId) {
 | 
			
		||||
    public static JSONObject success(String requestId) {
 | 
			
		||||
        return result(requestId, 2000, "", null);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static LesResult result(String requestId, int resultCode, String displayMsg, Object data) {
 | 
			
		||||
        LesResult lesResult = new LesResult();
 | 
			
		||||
        lesResult.setRequestId(requestId);
 | 
			
		||||
        lesResult.setServerTime(LocalDateTime.now().toString());
 | 
			
		||||
        lesResult.setResultCode(resultCode);
 | 
			
		||||
        lesResult.setDisplayMsg(displayMsg);
 | 
			
		||||
        lesResult.setDebugMsg("");
 | 
			
		||||
        lesResult.setData(data);
 | 
			
		||||
        return lesResult;
 | 
			
		||||
    public static JSONObject result(String requestId, int resultCode, String displayMsg, Object data) {
 | 
			
		||||
        JSONObject jsonObject = new JSONObject(true); // true 保持顺序
 | 
			
		||||
        jsonObject.put("requestId", requestId);
 | 
			
		||||
        jsonObject.put("serverTime", System.currentTimeMillis()); // 数值类型时间戳
 | 
			
		||||
        jsonObject.put("resultCode", resultCode);
 | 
			
		||||
        jsonObject.put("displayMsg", displayMsg == null ? "" : displayMsg);
 | 
			
		||||
        jsonObject.put("debugMsg", "");
 | 
			
		||||
        jsonObject.put("data", data == null ? "" : data);
 | 
			
		||||
        return jsonObject;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
package com.youchain.businessdata.inputJson;
 | 
			
		||||
 | 
			
		||||
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
 | 
			
		||||
import io.swagger.annotations.ApiModelProperty;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -33,6 +34,6 @@ public class LesRequest {
 | 
			
		|||
    String onlineNo;
 | 
			
		||||
 | 
			
		||||
    @ApiModelProperty(value = "节点", required = true)
 | 
			
		||||
    List<PositionCodeRequest> positionCodes;
 | 
			
		||||
    List<PositionCodeRequest> positionCodePath;
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -30,59 +30,12 @@ import java.util.Map;
 | 
			
		|||
 **/
 | 
			
		||||
public interface AgvTaskRepository extends JpaRepository<AgvTask, Long>, JpaSpecificationExecutor<AgvTask> {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 本周任务数统计
 | 
			
		||||
     * @return
 | 
			
		||||
     */
 | 
			
		||||
    @Query(value = " SELECT " +
 | 
			
		||||
            "    weekDay," +
 | 
			
		||||
            "    taskCount" +
 | 
			
		||||
            " FROM (" +
 | 
			
		||||
            "    SELECT " +
 | 
			
		||||
            "        0 AS sort_order," +
 | 
			
		||||
            "        NULL AS date," +
 | 
			
		||||
            "        '总计' AS weekDay," +
 | 
			
		||||
            "        SUM(task_count) AS taskCount" +
 | 
			
		||||
            "    FROM (" +
 | 
			
		||||
            "        SELECT " +
 | 
			
		||||
            "            DATE(create_time) AS date," +
 | 
			
		||||
            "            COUNT(id) AS task_count" +
 | 
			
		||||
            "        FROM data_agv_task  " +
 | 
			
		||||
            "        WHERE " +
 | 
			
		||||
            "        WEEK(create_time, 1) = WEEK(CURDATE(), 1)" +
 | 
			
		||||
            "        GROUP BY DATE(create_time)" +
 | 
			
		||||
            "    ) sub" +
 | 
			
		||||
            "    UNION ALL" +
 | 
			
		||||
            "    SELECT " +
 | 
			
		||||
            "        1 AS sort_order," +
 | 
			
		||||
            "        dr.date," +
 | 
			
		||||
            "        CASE " +
 | 
			
		||||
            "            WHEN WEEKDAY(dr.date) = 0 THEN '周一'" +
 | 
			
		||||
            "            WHEN WEEKDAY(dr.date) = 1 THEN '周二'" +
 | 
			
		||||
            "            WHEN WEEKDAY(dr.date) = 2 THEN '周三'" +
 | 
			
		||||
            "            WHEN WEEKDAY(dr.date) = 3 THEN '周四'" +
 | 
			
		||||
            "            WHEN WEEKDAY(dr.date) = 4 THEN '周五'" +
 | 
			
		||||
            "            WHEN WEEKDAY(dr.date) = 5 THEN '周六'" +
 | 
			
		||||
            "            WHEN WEEKDAY(dr.date) = 6 THEN '周日'" +
 | 
			
		||||
            "        END AS weekDay," +
 | 
			
		||||
            "        COALESCE(dt.task_count, 0) AS taskCount" +
 | 
			
		||||
            "    FROM " +
 | 
			
		||||
            "        (SELECT " +
 | 
			
		||||
            "            CURDATE() - INTERVAL (WEEKDAY(CURDATE())) DAY + INTERVAL weeks DAY AS date" +
 | 
			
		||||
            "         FROM " +
 | 
			
		||||
            "            (SELECT 0 AS weeks UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6) weeks" +
 | 
			
		||||
            "        ) dr" +
 | 
			
		||||
            "    LEFT JOIN (" +
 | 
			
		||||
            "        SELECT " +
 | 
			
		||||
            "            DATE(create_time) AS date," +
 | 
			
		||||
            "            COUNT(id) AS task_count" +
 | 
			
		||||
            "        FROM data_agv_task  " +
 | 
			
		||||
            "        WHERE " +
 | 
			
		||||
            "        WEEK(create_time, 1) = WEEK(CURDATE(), 1)" +
 | 
			
		||||
            "        GROUP BY DATE(create_time)" +
 | 
			
		||||
            "    ) dt " +
 | 
			
		||||
            "    ON dr.date = dt.date" +
 | 
			
		||||
            " ) result" +
 | 
			
		||||
            " ORDER BY sort_order, date;", nativeQuery = true)
 | 
			
		||||
    List<Object[]> queryWeeklyTaskCounts();
 | 
			
		||||
    @Query(value = "select count(agv.id) from AgvTask agv where agv.stockCode=:stockCode and agv.startSlotCode=:srcPointCode and agv.endSlotCode=:endPointCode  and agv.status in ('OPEN','ATCALL','UP_CONTAINER') ")
 | 
			
		||||
    int isAGVTaskDuplicate(String stockCode, String srcPointCode, String endPointCode);
 | 
			
		||||
 | 
			
		||||
    @Query(value = "select count(agv.id) from AgvTask agv where agv.startSlotCode=:startSlotCode and agv.type=:type and agv.jobType=:jobType  and agv.status  in ('OPEN','ATCALL','UP_CONTAINER') ")
 | 
			
		||||
    int findByStartSlotCode(String startSlotCode, String type, String jobType);
 | 
			
		||||
 | 
			
		||||
    @Query(value = "select count(agv.id) from AgvTask agv where agv.endSlotCode=:endSlotCode and agv.type=:type and agv.jobType=:jobType and agv.status in ('OPEN','ATCALL','UP_CONTAINER')  ")
 | 
			
		||||
    int findByEndSlotCode(String endSlotCode, String type, String jobType);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,5 @@
 | 
			
		|||
package com.youchain.businessdata.repository;
 | 
			
		||||
 | 
			
		||||
import com.youchain.businessdata.domain.AgvTask;
 | 
			
		||||
import com.youchain.businessdata.domain.Les;
 | 
			
		||||
import org.springframework.data.jpa.repository.JpaRepository;
 | 
			
		||||
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,6 +76,7 @@ public class LesController {
 | 
			
		|||
    public ResponseEntity<Object> genAgvSchedulingTask(@RequestBody LesRequest lesRequest) {
 | 
			
		||||
        String id = lesRequest.getGuId();//请求id
 | 
			
		||||
        try {
 | 
			
		||||
            lesService.genAgvSchedulingTask(lesRequest);
 | 
			
		||||
            return new ResponseEntity<>(LesResult.success(id), HttpStatus.OK);
 | 
			
		||||
        } catch (Exception e) {
 | 
			
		||||
            return new ResponseEntity<>(LesResult.fail(id, e.getMessage()), HttpStatus.BAD_REQUEST);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -101,5 +101,29 @@ public interface AgvTaskService {
 | 
			
		|||
     */
 | 
			
		||||
    AgvTask createAgvTask(String bizStatus, Stock stock, Point srcPoint, Point endPoint,String jobType);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据容器查询任务
 | 
			
		||||
     *
 | 
			
		||||
     * @param stockCode 容器
 | 
			
		||||
     */
 | 
			
		||||
    Boolean isAGVTaskDuplicate(String stockCode, String srcPointCode, String endPointCode);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据起点查询是否有重复任务
 | 
			
		||||
     *
 | 
			
		||||
     * @param startSlotCode 点位
 | 
			
		||||
     * @param type          任务类型
 | 
			
		||||
     * @param jobType       作业类型
 | 
			
		||||
     */
 | 
			
		||||
    Boolean findByStartSlotCode(String startSlotCode, String type, String jobType);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 根据终点查询是否有重复任务
 | 
			
		||||
     *
 | 
			
		||||
     * @param endSlotCode 点位
 | 
			
		||||
     * @param type        任务类型
 | 
			
		||||
     * @param jobType     作业类型
 | 
			
		||||
     */
 | 
			
		||||
    Boolean findByEndSlotCode(String endSlotCode, String type, String jobType);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,100 @@
 | 
			
		|||
package com.youchain.businessdata.service;
 | 
			
		||||
 | 
			
		||||
import com.youchain.businessdata.domain.AgvTask;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
public interface KMReService {
 | 
			
		||||
    /**
 | 
			
		||||
     * 容器入场JSON
 | 
			
		||||
     *
 | 
			
		||||
     * @param containerCode 容器编号
 | 
			
		||||
     * @param position      点位
 | 
			
		||||
     */
 | 
			
		||||
    String containerInJson(String containerCode, String position);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 容器入场
 | 
			
		||||
     *
 | 
			
		||||
     * @param containerCode 容器
 | 
			
		||||
     * @param position      点位
 | 
			
		||||
     * @param itemCode      物料
 | 
			
		||||
     */
 | 
			
		||||
    void containerIn(String containerCode, String position, String itemCode);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 容器出场JSON
 | 
			
		||||
     *
 | 
			
		||||
     * @param containerCode 容器编号
 | 
			
		||||
     */
 | 
			
		||||
    String containerOutJson(String containerCode);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 容器出场
 | 
			
		||||
     *
 | 
			
		||||
     * @param containerCode 容器
 | 
			
		||||
     */
 | 
			
		||||
    void containerOut(String containerCode);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 下发容器入场或出场或放行
 | 
			
		||||
     *
 | 
			
		||||
     * @param url  接口地址
 | 
			
		||||
     * @param json 接口json
 | 
			
		||||
     */
 | 
			
		||||
    void sendAgvTaskToContainer(String url, String json);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 下发agv叉车任务JSON
 | 
			
		||||
     *
 | 
			
		||||
     * @param agvTask 任务
 | 
			
		||||
     */
 | 
			
		||||
    String sendAgvTaskCcJson(AgvTask agvTask);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 下发agv货架任务JSON
 | 
			
		||||
     *
 | 
			
		||||
     * @param agvTask 任务
 | 
			
		||||
     */
 | 
			
		||||
    String sendAgvTaskHjJson(AgvTask agvTask);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 下发agv滚筒任务JSON
 | 
			
		||||
     *
 | 
			
		||||
     * @param agvTask 任务
 | 
			
		||||
     */
 | 
			
		||||
    String sendAgvTaskGtJson(AgvTask agvTask);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 下发agv牵引车任务JSON
 | 
			
		||||
     *
 | 
			
		||||
     * @param agvTask   任务
 | 
			
		||||
     * @param tugModels 牵引车型号
 | 
			
		||||
     */
 | 
			
		||||
    String sendAgvTaskQYCJson(AgvTask agvTask, List<String> tugModels);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 下发agv任务
 | 
			
		||||
     *
 | 
			
		||||
     * @param agvTasks 任务
 | 
			
		||||
     */
 | 
			
		||||
    void sendAgvTask(AgvTask agvTasks, String json);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 任务回报更新状态
 | 
			
		||||
     *
 | 
			
		||||
     * @param agvTask         任务
 | 
			
		||||
     * @param status          状态
 | 
			
		||||
     * @param containerCode   容器
 | 
			
		||||
     * @param currentPosition 当前位置
 | 
			
		||||
     */
 | 
			
		||||
    void missionStateCallback(AgvTask agvTask, String status, String containerCode, String currentPosition);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 任务放行Json
 | 
			
		||||
     *
 | 
			
		||||
     * @param agvTask 任务
 | 
			
		||||
     */
 | 
			
		||||
    String operationFeedbackJson(AgvTask agvTask);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -75,4 +75,12 @@ public interface LesService {
 | 
			
		|||
     */
 | 
			
		||||
    void genAgvSchedulingTask( LesRequest lesRequest);
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * LES任务回调
 | 
			
		||||
     * @param currentPositionCode 当前点位
 | 
			
		||||
     * @param taskCode 任务号
 | 
			
		||||
     * @return json
 | 
			
		||||
     */
 | 
			
		||||
    String lesCallBack(String currentPositionCode,String taskCode);
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,7 @@
 | 
			
		|||
package com.youchain.businessdata.service.dto;
 | 
			
		||||
 | 
			
		||||
import io.swagger.annotations.ApiModelProperty;
 | 
			
		||||
import lombok.Data;
 | 
			
		||||
 | 
			
		||||
import javax.persistence.Column;
 | 
			
		||||
import java.sql.Timestamp;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,6 +34,7 @@ import org.springframework.data.domain.Pageable;
 | 
			
		|||
import java.util.*;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.util.stream.Collectors;
 | 
			
		||||
import javax.persistence.Query;
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -138,4 +139,19 @@ public class AgvTaskServiceImpl implements AgvTaskService {
 | 
			
		|||
        return agvTask;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Boolean isAGVTaskDuplicate(String stockCode, String srcPointCode, String endPointCode) {
 | 
			
		||||
        return agvTaskRepository.isAGVTaskDuplicate(stockCode, srcPointCode, endPointCode)>0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Boolean findByStartSlotCode(String startSlotCode, String type, String jobType) {
 | 
			
		||||
        return agvTaskRepository.findByStartSlotCode(startSlotCode, type, jobType)>0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Boolean findByEndSlotCode(String endSlotCode, String type, String jobType) {
 | 
			
		||||
        return agvTaskRepository.findByEndSlotCode(endSlotCode, type, jobType)>0;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1,558 @@
 | 
			
		|||
package com.youchain.businessdata.service.impl;
 | 
			
		||||
 | 
			
		||||
import com.alibaba.fastjson.JSON;
 | 
			
		||||
import com.alibaba.fastjson.JSONArray;
 | 
			
		||||
import com.alibaba.fastjson.JSONObject;
 | 
			
		||||
import com.youchain.basicdata.domain.Point;
 | 
			
		||||
import com.youchain.basicdata.domain.Stock;
 | 
			
		||||
import com.youchain.basicdata.service.PointService;
 | 
			
		||||
import com.youchain.basicdata.service.StockService;
 | 
			
		||||
import com.youchain.businessdata.domain.AgvTask;
 | 
			
		||||
import com.youchain.businessdata.domain.Task;
 | 
			
		||||
import com.youchain.businessdata.service.*;
 | 
			
		||||
import com.youchain.exception.BadRequestException;
 | 
			
		||||
import com.youchain.modules.quartz.utils.TimeNumberUtils;
 | 
			
		||||
import com.youchain.modules.system.domain.Dict;
 | 
			
		||||
import com.youchain.modules.system.repository.DictRepository;
 | 
			
		||||
import com.youchain.utils.*;
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
import org.springframework.transaction.annotation.Transactional;
 | 
			
		||||
 | 
			
		||||
import java.sql.Timestamp;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
@Service
 | 
			
		||||
@Slf4j
 | 
			
		||||
@RequiredArgsConstructor
 | 
			
		||||
public class KMReServiceImpl implements KMReService {
 | 
			
		||||
    private final DictRepository dictRepository;
 | 
			
		||||
    private final StockService stockService;
 | 
			
		||||
    private final PointService pointService;
 | 
			
		||||
    private final TaskService taskService;
 | 
			
		||||
    private final AgvTaskService agvTaskService;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 容器入场Json
 | 
			
		||||
     *
 | 
			
		||||
     * @param containerCode 容器编号
 | 
			
		||||
     * @param position      点位
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public String containerInJson(String containerCode, String position) {
 | 
			
		||||
        JSONObject jsonObject = new JSONObject(true);
 | 
			
		||||
        //请求 id
 | 
			
		||||
        jsonObject.put("requestId", String.valueOf(System.currentTimeMillis()));
 | 
			
		||||
        //容器类型
 | 
			
		||||
        jsonObject.put("containerType", "");
 | 
			
		||||
        //容器编号
 | 
			
		||||
        jsonObject.put("containerCode", containerCode);
 | 
			
		||||
        //容器当前位置
 | 
			
		||||
        jsonObject.put("position", position);
 | 
			
		||||
        //角度
 | 
			
		||||
        jsonObject.put("enterOrientation", "");
 | 
			
		||||
        return jsonObject.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 容器入场
 | 
			
		||||
     *
 | 
			
		||||
     * @param containerCode 容器
 | 
			
		||||
     * @param position      点位
 | 
			
		||||
     * @param itemCode      物料
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public void containerIn(String containerCode, String position, String itemCode) {
 | 
			
		||||
        //验证容器是否存在
 | 
			
		||||
        Stock stock = stockService.validateStock(containerCode);
 | 
			
		||||
 | 
			
		||||
        //验证点位是否存在
 | 
			
		||||
        Point point = pointService.validatePoint(position);
 | 
			
		||||
 | 
			
		||||
        //入空车
 | 
			
		||||
        this.handleEmptyContainer(stock, point);
 | 
			
		||||
 | 
			
		||||
        //下发任务
 | 
			
		||||
        this.sendAgvTaskToContainer(UrlApi.containerIn(), this.containerInJson(containerCode, position));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 容器出场Json
 | 
			
		||||
     *
 | 
			
		||||
     * @param containerCode 容器编号
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public String containerOutJson(String containerCode) {
 | 
			
		||||
        JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());
 | 
			
		||||
        //请求 id
 | 
			
		||||
        jsonObject.put("requestId", String.valueOf(System.currentTimeMillis()));
 | 
			
		||||
        //容器类型
 | 
			
		||||
        jsonObject.put("containerType", "");
 | 
			
		||||
        //容器编号
 | 
			
		||||
        jsonObject.put("containerCode", containerCode);
 | 
			
		||||
        //容器当前位置
 | 
			
		||||
        jsonObject.put("position", "");
 | 
			
		||||
        return jsonObject.toJSONString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 容器出场
 | 
			
		||||
     *
 | 
			
		||||
     * @param containerCode 容器
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public void containerOut(String containerCode) {
 | 
			
		||||
        //验证容器
 | 
			
		||||
        Stock stock = stockService.validateStock(containerCode);
 | 
			
		||||
 | 
			
		||||
        //释放点位
 | 
			
		||||
        Point point = stock.getPoint();
 | 
			
		||||
        if (point != null) {
 | 
			
		||||
            pointService.freePoint(point);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //释放容器
 | 
			
		||||
        stockService.usedStock(stock, null, BaseStatus.FREE);
 | 
			
		||||
 | 
			
		||||
        //下发任务
 | 
			
		||||
        this.sendAgvTaskToContainer(UrlApi.containerOut(), this.containerOutJson(containerCode));
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 入空车
 | 
			
		||||
     *
 | 
			
		||||
     * @param stock 容器
 | 
			
		||||
     * @param point 点位
 | 
			
		||||
     */
 | 
			
		||||
    public void handleEmptyContainer(Stock stock, Point point) {
 | 
			
		||||
        //占用点位
 | 
			
		||||
        pointService.usedPoint(point);
 | 
			
		||||
 | 
			
		||||
        //占用容器
 | 
			
		||||
        stockService.usedStock(stock, point, BaseStatus.FREE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 下发容器入场或容器出场
 | 
			
		||||
     *
 | 
			
		||||
     * @param url  接口地址
 | 
			
		||||
     * @param json 接口json
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public void sendAgvTaskToContainer(String url, String json) {
 | 
			
		||||
        Dict dict = dictRepository.findDictByName("OPEN");
 | 
			
		||||
        if (dict != null) {
 | 
			
		||||
            String resultJson = HttpPostUtil.sendPostReq(url, json);
 | 
			
		||||
            if (StringUtils.isEmpty(resultJson)) {
 | 
			
		||||
                throw new BadRequestException("AGV返回信息:接口调用失败!");
 | 
			
		||||
            }
 | 
			
		||||
            JSONObject resultObject = JSON.parseObject(resultJson);
 | 
			
		||||
            if (resultObject == null) {
 | 
			
		||||
                throw new BadRequestException("AGV返回信息:接口数据返回为空!");
 | 
			
		||||
            }
 | 
			
		||||
            String code = resultObject.getString("code");
 | 
			
		||||
            String message = resultObject.getString("message");
 | 
			
		||||
            if (!"0".equals(code)) {
 | 
			
		||||
                throw new BadRequestException("AGV返回信息:接口调用失败!" + message);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 叉车任务Json
 | 
			
		||||
     *
 | 
			
		||||
     * @param agvTasks 任务
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public String sendAgvTaskCcJson(AgvTask agvTasks) {
 | 
			
		||||
 | 
			
		||||
        JSONObject jsonObject = new JSONObject(true);
 | 
			
		||||
        String requestId = TimeNumberUtils.getCcCode();
 | 
			
		||||
        Map<String, Object> objMap = new LinkedHashMap<>();
 | 
			
		||||
        objMap.put("orgId", "KUKA");//库存组织 ID
 | 
			
		||||
        objMap.put("requestId", requestId);//请求 id
 | 
			
		||||
        objMap.put("missionCode", agvTasks.getId());//任务编号
 | 
			
		||||
        objMap.put("missionType", agvTasks.getJobType());//货 架 ( 托 盘 ) 移动 RACK_MOVE
 | 
			
		||||
        objMap.put("viewBoardType", "");//
 | 
			
		||||
        objMap.put("containerCode", agvTasks.getStockCode());//
 | 
			
		||||
        objMap.put("robotType", "FORKLIFT");//机器人功能类型
 | 
			
		||||
        objMap.put("robotId", "");//机器人编号
 | 
			
		||||
        objMap.put("priority", "1");//数值越小,优先级越高,默认是 1
 | 
			
		||||
        JSONArray missionDataArray = new JSONArray();
 | 
			
		||||
        JSONObject missionDataObj = new JSONObject(true);
 | 
			
		||||
        Map<String, Object> missionDataMap = new LinkedHashMap<>();
 | 
			
		||||
        missionDataMap.put("sequence", 1);//序号
 | 
			
		||||
        missionDataMap.put("position", agvTasks.getStartSlotCode());//点位
 | 
			
		||||
        String nodeType = "NODE_POINT";
 | 
			
		||||
        if (BizStatus.PICK.equals(agvTasks.getType())) {
 | 
			
		||||
            nodeType = "NODE_SLOT";
 | 
			
		||||
        }
 | 
			
		||||
        missionDataMap.put("nodeType", nodeType);//
 | 
			
		||||
        missionDataMap.put("stackNumber", 0);
 | 
			
		||||
        missionDataMap.put("actionConfirm", false);
 | 
			
		||||
        missionDataObj.putAll(missionDataMap);
 | 
			
		||||
        missionDataArray.add(missionDataObj);
 | 
			
		||||
 | 
			
		||||
        JSONObject missionDataObj2 = new JSONObject(new LinkedHashMap<>());
 | 
			
		||||
        Map<String, Object> missionDataMap2 = new LinkedHashMap<>();
 | 
			
		||||
        missionDataMap2.put("sequence", 2);//序号
 | 
			
		||||
        missionDataMap2.put("position", agvTasks.getEndSlotCode());//目标点
 | 
			
		||||
        String nodeType2 = "NODE_SLOT";
 | 
			
		||||
        if (BizStatus.PICK.equals(agvTasks.getType())) {
 | 
			
		||||
            nodeType2 = "NODE_POINT";
 | 
			
		||||
        }
 | 
			
		||||
        missionDataMap2.put("nodeType", nodeType2);//
 | 
			
		||||
        missionDataMap2.put("stackNumber", 0);
 | 
			
		||||
        missionDataMap2.put("actionConfirm", false);
 | 
			
		||||
        missionDataObj2.putAll(missionDataMap2);
 | 
			
		||||
        missionDataArray.add(missionDataObj2);
 | 
			
		||||
 | 
			
		||||
        objMap.put("missionData", missionDataArray);
 | 
			
		||||
        jsonObject.putAll(objMap);
 | 
			
		||||
        return jsonObject.toJSONString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 货架任务Json
 | 
			
		||||
     *
 | 
			
		||||
     * @param agvTasks 任务
 | 
			
		||||
     */
 | 
			
		||||
    @Override
 | 
			
		||||
    public String sendAgvTaskHjJson(AgvTask agvTasks) {
 | 
			
		||||
        JSONObject jsonObject = new JSONObject(true);
 | 
			
		||||
        String requestId = TimeNumberUtils.getHjCode();
 | 
			
		||||
        Map<String, Object> objMap = new LinkedHashMap<>();
 | 
			
		||||
        objMap.put("orgId", "KUKA");//库存组织 ID
 | 
			
		||||
        objMap.put("requestId", requestId);//请求 id
 | 
			
		||||
        objMap.put("missionCode", agvTasks.getId());//任务编号
 | 
			
		||||
        objMap.put("missionType", agvTasks.getJobType());//货 架 ( 托 盘 ) 移动 RACK_MOVE
 | 
			
		||||
        objMap.put("viewBoardType", "");//IDENTIFY_REQUIRE
 | 
			
		||||
        objMap.put("robotType", "LIFT");//机器人功能类型
 | 
			
		||||
        objMap.put("priority", "1");//数值越小,优先级越高,默认是 1
 | 
			
		||||
        JSONArray missionDataArray = new JSONArray();
 | 
			
		||||
        JSONObject missionDataObj = new JSONObject(true);
 | 
			
		||||
        Map<String, Object> missionDataMap = new LinkedHashMap<>();
 | 
			
		||||
        missionDataMap.put("sequence", 1);//序号
 | 
			
		||||
        missionDataMap.put("containerCode", agvTasks.getStockCode());//容器
 | 
			
		||||
        missionDataMap.put("startPosition", agvTasks.getStartSlotCode());//点位
 | 
			
		||||
        missionDataMap.put("startPositionType", "NODE_POINT");//
 | 
			
		||||
        missionDataMap.put("endPosition", agvTasks.getEndSlotCode());//点位
 | 
			
		||||
        missionDataMap.put("endPositionType", "NODE_POINT");//
 | 
			
		||||
        missionDataObj.putAll(missionDataMap);
 | 
			
		||||
        missionDataArray.add(missionDataObj);
 | 
			
		||||
 | 
			
		||||
        objMap.put("missionData", missionDataArray);
 | 
			
		||||
        jsonObject.putAll(objMap);
 | 
			
		||||
        return jsonObject.toJSONString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String sendAgvTaskGtJson(AgvTask agvTask) {
 | 
			
		||||
        JSONObject jsonObject = new JSONObject(true);
 | 
			
		||||
        String requestId = TimeNumberUtils.getGTTaskCode();
 | 
			
		||||
        Map<String, Object> objMap = new LinkedHashMap<>();
 | 
			
		||||
        objMap.put("orgId", "KUKA");//库存组织 ID(或工厂代码,供应商代码)
 | 
			
		||||
        objMap.put("requestId", requestId);//请求 id
 | 
			
		||||
        objMap.put("missionCode", agvTask.getId());//任务编号
 | 
			
		||||
        objMap.put("missionType", "ROLLER_MOVE");//任务类型 :滚筒
 | 
			
		||||
        objMap.put("viewBoardType", "");//上视识别类型:
 | 
			
		||||
        objMap.put("robotType", "ROLLER");
 | 
			
		||||
        objMap.put("priority", "1");
 | 
			
		||||
        objMap.put("lockRobotAfterFinish", false);
 | 
			
		||||
        JSONArray missionDataArray = new JSONArray();
 | 
			
		||||
 | 
			
		||||
        JSONObject missionDataObj = new JSONObject(true);
 | 
			
		||||
        Map<String, Object> missionDataMap = new LinkedHashMap<>();
 | 
			
		||||
        missionDataMap.put("sequence", 1);//序号
 | 
			
		||||
        missionDataMap.put("position", agvTask.getStartSlotCode());//起点
 | 
			
		||||
        missionDataMap.put("type", "NODE_POINT");//
 | 
			
		||||
        missionDataMap.put("actionType", "ROLLER_RECEIVE");//
 | 
			
		||||
        missionDataMap.put("binCode", "");//容器
 | 
			
		||||
        missionDataMap.put("rollerLevel", 1);//
 | 
			
		||||
        missionDataMap.put("deviceCode", agvTask.getStartSlotCode());//设备编号
 | 
			
		||||
        missionDataMap.put("actionConfirm", true);//
 | 
			
		||||
        missionDataMap.put("passStrategy", "AUTO");//
 | 
			
		||||
        missionDataObj.putAll(missionDataMap);
 | 
			
		||||
        missionDataArray.add(missionDataObj);
 | 
			
		||||
 | 
			
		||||
        JSONObject missionDataObj2 = new JSONObject(true);
 | 
			
		||||
        Map<String, Object> missionDataMap2 = new LinkedHashMap<>();
 | 
			
		||||
        missionDataMap2.put("sequence", 2);//序号
 | 
			
		||||
        missionDataMap2.put("position", "FX001");//中转点
 | 
			
		||||
        missionDataMap2.put("type", "NODE_POINT");//
 | 
			
		||||
        missionDataMap2.put("actionType", "");//
 | 
			
		||||
        missionDataMap2.put("binCode", "");//容器
 | 
			
		||||
        missionDataMap2.put("rollerLevel", 1);//
 | 
			
		||||
        missionDataMap2.put("deviceCode", "");//
 | 
			
		||||
        missionDataMap2.put("actionConfirm", false);//
 | 
			
		||||
        missionDataMap2.put("passStrategy", "MANUAL");//
 | 
			
		||||
        missionDataObj2.putAll(missionDataMap2);
 | 
			
		||||
        missionDataArray.add(missionDataObj2);
 | 
			
		||||
 | 
			
		||||
        JSONObject missionDataObj3 = new JSONObject(true);
 | 
			
		||||
        Map<String, Object> missionDataMap3 = new LinkedHashMap<>();
 | 
			
		||||
        missionDataMap3.put("sequence", 3);//序号
 | 
			
		||||
        missionDataMap3.put("position", agvTask.getEndSlotCode());//终点
 | 
			
		||||
        missionDataMap3.put("type", "NODE_POINT");//
 | 
			
		||||
        missionDataMap3.put("actionType", "ROLLER_SEND");//
 | 
			
		||||
        missionDataMap3.put("binCode", "");//容器
 | 
			
		||||
        missionDataMap3.put("rollerLevel", 1);//
 | 
			
		||||
        missionDataMap3.put("deviceCode", agvTask.getEndSlotCode());//终点
 | 
			
		||||
        missionDataMap3.put("actionConfirm", true);//
 | 
			
		||||
        missionDataMap3.put("passStrategy", "AUTO");//
 | 
			
		||||
        missionDataObj3.putAll(missionDataMap3);
 | 
			
		||||
        missionDataArray.add(missionDataObj3);
 | 
			
		||||
 | 
			
		||||
        objMap.put("missionData", missionDataArray);
 | 
			
		||||
        jsonObject.putAll(objMap);
 | 
			
		||||
        return jsonObject.toJSONString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String sendAgvTaskQYCJson(AgvTask agvTask, List<String> tugModels) {
 | 
			
		||||
        JSONObject jsonObject = new JSONObject(true);
 | 
			
		||||
        String requestId = TimeNumberUtils.getGTTaskCode();
 | 
			
		||||
        Map<String, Object> objMap = new LinkedHashMap<>();
 | 
			
		||||
        objMap.put("orgId", "KUKA");//库存组织 ID(或工厂代码,供应商代码)
 | 
			
		||||
        objMap.put("requestId", requestId);//请求 id
 | 
			
		||||
        objMap.put("missionCode", agvTask.getId());//任务编号
 | 
			
		||||
        objMap.put("missionType", "TUGGER_MOVE");//任务类型 :滚筒
 | 
			
		||||
        objMap.put("viewBoardType", "");//上视识别类型:
 | 
			
		||||
        objMap.put("robotType", "TUGGER");
 | 
			
		||||
        objMap.put("priority", "1");
 | 
			
		||||
        objMap.put("templateCode", "");
 | 
			
		||||
        objMap.put("lockRobotAfterFinish", false);
 | 
			
		||||
        objMap.put("unlockRobotId", "");
 | 
			
		||||
        objMap.put("unlockMissionCode", "");
 | 
			
		||||
 | 
			
		||||
        JSONArray missionDataArray = new JSONArray();
 | 
			
		||||
 | 
			
		||||
        JSONObject missionDataObj = new JSONObject(true);
 | 
			
		||||
        Map<String, Object> missionDataMap = new LinkedHashMap<>();
 | 
			
		||||
        missionDataMap.put("sequence", 1);//序号
 | 
			
		||||
        missionDataMap.put("type", "NODE_POINT");//作业类型:点位:NODE_POINT;区域:NODE_AREA
 | 
			
		||||
        missionDataMap.put("position", agvTask.getStartSlotCode());//起点
 | 
			
		||||
        missionDataMap.put("actionType", "TUGGER_ATTACH");//动作:TUGGER_ATTACH:挂钩;TUGGER_DETACH:脱钩
 | 
			
		||||
        missionDataMap.put("tugCount", tugModels.size());//牵引车后方的拖挂车数量
 | 
			
		||||
        missionDataMap.put("passStrategy", "MANUAL");//当前任务点结束后放行策略:自动:AUTO;手动:MANUAL
 | 
			
		||||
        missionDataMap.put("tugModels", tugModels);//牵引车后方的拖挂车规格【模型名字】需要和tugCount一致
 | 
			
		||||
        missionDataObj.putAll(missionDataMap);
 | 
			
		||||
        missionDataArray.add(missionDataObj);
 | 
			
		||||
 | 
			
		||||
        JSONObject missionDataObj2 = new JSONObject(true);
 | 
			
		||||
        Map<String, Object> missionDataMap2 = new LinkedHashMap<>();
 | 
			
		||||
        missionDataMap2.put("sequence", 2);//序号
 | 
			
		||||
        missionDataMap2.put("type", "NODE_AREA");//作业类型:点位:NODE_POINT;区域:NODE_AREA
 | 
			
		||||
        missionDataMap2.put("position", agvTask.getEndSlotCode());//终点
 | 
			
		||||
        missionDataMap.put("actionType", "TUGGER_DETACH");//动作:TUGGER_ATTACH:挂钩;TUGGER_DETACH:脱钩
 | 
			
		||||
        missionDataMap.put("passStrategy", "AUTO");//当前任务点结束后放行策略:自动:AUTO;手动:MANUAL
 | 
			
		||||
        missionDataMap2.put("waitingMillis", 0);//自动触发离开当前任务节点的时间,默认单位:毫秒
 | 
			
		||||
        missionDataObj2.putAll(missionDataMap2);
 | 
			
		||||
        missionDataArray.add(missionDataObj2);
 | 
			
		||||
 | 
			
		||||
        objMap.put("missionData", missionDataArray);
 | 
			
		||||
        jsonObject.putAll(objMap);
 | 
			
		||||
        return jsonObject.toJSONString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public void sendAgvTask(AgvTask agvTasks, String json) {
 | 
			
		||||
        Dict dict = dictRepository.findDictByName("OPEN");
 | 
			
		||||
        String resultJson = "";
 | 
			
		||||
        if (dict != null) {
 | 
			
		||||
            resultJson = HttpPostUtil.sendPostReq(UrlApi.submitMission(), json);
 | 
			
		||||
            if (StringUtils.isEmpty(resultJson)) {
 | 
			
		||||
                throw new BadRequestException("AGV返回信息:下发任务接口调用失败!");
 | 
			
		||||
            }
 | 
			
		||||
            JSONObject resulObject = JSON.parseObject(resultJson);
 | 
			
		||||
            if (resulObject == null) {
 | 
			
		||||
                throw new BadRequestException("AGV返回信息:下发任务接口返回为空!");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            String code = resulObject.getString("code");
 | 
			
		||||
            String message = resulObject.getString("message");
 | 
			
		||||
            if (!"0".equals(code)) {
 | 
			
		||||
                throw new BadRequestException("AGV返回消息:" + message);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        agvTasks.setJobForce(agvTasks.getId().toString());
 | 
			
		||||
        agvTasks.setJobForceAsc((1));
 | 
			
		||||
        agvTasks.setStatus(BizStatus.ATCALL);
 | 
			
		||||
        agvTasks.setJobMessage(resultJson);
 | 
			
		||||
        agvTasks.setReqMessage(json);
 | 
			
		||||
        agvTasks.setStartTime(new Timestamp(System.currentTimeMillis()));
 | 
			
		||||
        agvTaskService.update(agvTasks);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public void missionStateCallback(AgvTask agvTask, String status, String containerCode, String currentPosition) {
 | 
			
		||||
        Stock stock = stockService.validateStock(containerCode);
 | 
			
		||||
        //顶升的是起点;其它终点;
 | 
			
		||||
        Point point;
 | 
			
		||||
        String pointCode;
 | 
			
		||||
        if ("UP_CONTAINER".equals(status) || "FORK_UP".equals(status)) {
 | 
			
		||||
            pointCode = agvTask.getStartSlotCode();
 | 
			
		||||
        } else {
 | 
			
		||||
            pointCode = agvTask.getEndSlotCode();
 | 
			
		||||
        }
 | 
			
		||||
        point = pointService.queryPoint(pointCode, null, null, null);
 | 
			
		||||
        switch (status) {
 | 
			
		||||
            case "UP_CONTAINER":
 | 
			
		||||
            case "FORK_UP":
 | 
			
		||||
                handleUpContainer(agvTask, stock, point);//容器顶升
 | 
			
		||||
                break;
 | 
			
		||||
            case "FORK_DOWN":
 | 
			
		||||
                //容器放下
 | 
			
		||||
                break;
 | 
			
		||||
            case "ARRIVED":
 | 
			
		||||
                //容器到达
 | 
			
		||||
                break;
 | 
			
		||||
            case "COMPLETED":
 | 
			
		||||
                handleComContainer(agvTask, stock, point);//任务完成
 | 
			
		||||
                break;
 | 
			
		||||
            case "CANCELED":
 | 
			
		||||
                handleCanceledTask(agvTask, stock, point);//任务取消
 | 
			
		||||
                break;
 | 
			
		||||
            case "RESEND":
 | 
			
		||||
                handleResendTask(agvTask);//重新发送
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String operationFeedbackJson(AgvTask agvTask) {
 | 
			
		||||
        JSONObject jsonObject = new JSONObject(new LinkedHashMap<>());
 | 
			
		||||
        //请求 id
 | 
			
		||||
        jsonObject.put("requestId", String.valueOf(System.currentTimeMillis()));
 | 
			
		||||
        //容器类型
 | 
			
		||||
        jsonObject.put("containerCode", "");
 | 
			
		||||
        //容器编号
 | 
			
		||||
        jsonObject.put("missionCode", agvTask.getId());
 | 
			
		||||
        //容器当前位置
 | 
			
		||||
        jsonObject.put("position", "");
 | 
			
		||||
        return jsonObject.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 容器顶升
 | 
			
		||||
     *
 | 
			
		||||
     * @param agvTask 任务
 | 
			
		||||
     * @param stock   容器
 | 
			
		||||
     */
 | 
			
		||||
    private void handleUpContainer(AgvTask agvTask, Stock stock, Point startPoint) {
 | 
			
		||||
        //顶升,起点释放点位
 | 
			
		||||
        pointService.freePoint(startPoint);
 | 
			
		||||
        agvTask.setStockCode(stock == null ? null : stock.getCode());
 | 
			
		||||
        agvTask.setStatus(BizStatus.UP_CONTAINER);
 | 
			
		||||
        agvTaskService.update(agvTask);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 任务完成
 | 
			
		||||
     *
 | 
			
		||||
     * @param agvTask 任务
 | 
			
		||||
     * @param stock   容器
 | 
			
		||||
     */
 | 
			
		||||
    private void handleComContainer(AgvTask agvTask, Stock stock, Point endPoint) {
 | 
			
		||||
        //任务完成;根据AGV任务的目标点位走对应流程
 | 
			
		||||
        switch (agvTask.getType()) {
 | 
			
		||||
            case BizStatus.PICK:
 | 
			
		||||
                break;
 | 
			
		||||
            case BizStatus.ASN:
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                throw new BadRequestException("任务类型不存在!");
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        //更新任务状态
 | 
			
		||||
        this.updateAgvTaskStatus(agvTask, stock, BizStatus.FINISH);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 任务取消完成
 | 
			
		||||
     *
 | 
			
		||||
     * @param agvTask 任务
 | 
			
		||||
     * @param stock   容器
 | 
			
		||||
     */
 | 
			
		||||
    private void handleCanceledTask(AgvTask agvTask, Stock stock, Point endPoint) {
 | 
			
		||||
 | 
			
		||||
        //更新任务状态
 | 
			
		||||
        this.updateAgvTaskStatus(agvTask, stock, BizStatus.CANCEL);
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 重新发送任务
 | 
			
		||||
     *
 | 
			
		||||
     * @param agvTask 任务
 | 
			
		||||
     */
 | 
			
		||||
    private synchronized void handleResendTask(AgvTask agvTask) {
 | 
			
		||||
        Boolean bool = agvTaskService.isAGVTaskDuplicate(agvTask.getStockCode(), agvTask.getStartSlotCode(), agvTask.getEndSlotCode());
 | 
			
		||||
        if (bool) {
 | 
			
		||||
            throw new BadRequestException("任务已重新生成,请勿重复操作! ");
 | 
			
		||||
        }
 | 
			
		||||
        AgvTask newAgvTask = AgvTask.builder()
 | 
			
		||||
                .stockCode(agvTask.getStockCode())
 | 
			
		||||
                .type(agvTask.getType())
 | 
			
		||||
                .jobType(agvTask.getJobType())
 | 
			
		||||
                .jobPriority(1)
 | 
			
		||||
                .startSlotCode(agvTask.getStartSlotCode())
 | 
			
		||||
                .endSlotCode(agvTask.getEndSlotCode())
 | 
			
		||||
                .slotCode(agvTask.getSlotCode())
 | 
			
		||||
                .status(BizStatus.OPEN)
 | 
			
		||||
                .lineSlotCode(agvTask.getLineSlotCode())
 | 
			
		||||
                .build();
 | 
			
		||||
        agvTaskService.create(newAgvTask);
 | 
			
		||||
 | 
			
		||||
        List<Task> taskList = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
        for (Task task : taskList) {
 | 
			
		||||
            task.setAgvTask(newAgvTask);
 | 
			
		||||
            taskService.update(task);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
        // 根据任务类型发送不同的实现
 | 
			
		||||
        switch (agvTask.getJobType()) {
 | 
			
		||||
            case "FORKLIFT_MOVE":
 | 
			
		||||
                sendAgvTask(newAgvTask, sendAgvTaskCcJson(newAgvTask));
 | 
			
		||||
                break;
 | 
			
		||||
            case "RACK_MOVE":
 | 
			
		||||
                sendAgvTask(newAgvTask, sendAgvTaskHjJson(newAgvTask));
 | 
			
		||||
                break;
 | 
			
		||||
            case "ROLLER_MOVE":
 | 
			
		||||
                sendAgvTask(newAgvTask, sendAgvTaskGtJson(newAgvTask));
 | 
			
		||||
                break;
 | 
			
		||||
            default:
 | 
			
		||||
                throw new BadRequestException("任务类型不支持: " + agvTask.getJobType());
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 更新任务状态
 | 
			
		||||
     *
 | 
			
		||||
     * @param agvTask 任务
 | 
			
		||||
     * @param stock   容器
 | 
			
		||||
     * @param status  状态
 | 
			
		||||
     */
 | 
			
		||||
    private void updateAgvTaskStatus(AgvTask agvTask, Stock stock, String status) {
 | 
			
		||||
        agvTask.setStockCode(stock == null ? null : stock.getCode());
 | 
			
		||||
        agvTask.setStatus(status);
 | 
			
		||||
        agvTask.setEndTime(new Timestamp(new Date().getTime()));
 | 
			
		||||
        agvTaskService.update(agvTask);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,14 +1,20 @@
 | 
			
		|||
package com.youchain.businessdata.service.impl;
 | 
			
		||||
 | 
			
		||||
import com.alibaba.fastjson.JSON;
 | 
			
		||||
import com.alibaba.fastjson.JSONObject;
 | 
			
		||||
import com.youchain.businessdata.domain.AgvTask;
 | 
			
		||||
import com.youchain.businessdata.domain.Les;
 | 
			
		||||
import com.youchain.businessdata.inputJson.LesRequest;
 | 
			
		||||
import com.youchain.businessdata.inputJson.PositionCodeRequest;
 | 
			
		||||
import com.youchain.businessdata.repository.LesRepository;
 | 
			
		||||
import com.youchain.businessdata.service.KMReService;
 | 
			
		||||
import com.youchain.businessdata.service.LesService;
 | 
			
		||||
import com.youchain.businessdata.service.dto.LesDto;
 | 
			
		||||
import com.youchain.businessdata.service.dto.LesQueryCriteria;
 | 
			
		||||
import com.youchain.businessdata.service.mapstruct.LesMapper;
 | 
			
		||||
import com.youchain.exception.BadRequestException;
 | 
			
		||||
import com.youchain.modules.system.domain.Dict;
 | 
			
		||||
import com.youchain.modules.system.repository.DictRepository;
 | 
			
		||||
import com.youchain.utils.*;
 | 
			
		||||
import lombok.RequiredArgsConstructor;
 | 
			
		||||
import lombok.extern.slf4j.Slf4j;
 | 
			
		||||
| 
						 | 
				
			
			@ -19,6 +25,8 @@ import org.springframework.transaction.annotation.Transactional;
 | 
			
		|||
 | 
			
		||||
import javax.servlet.http.HttpServletResponse;
 | 
			
		||||
import java.io.IOException;
 | 
			
		||||
import java.sql.Timestamp;
 | 
			
		||||
import java.text.SimpleDateFormat;
 | 
			
		||||
import java.util.*;
 | 
			
		||||
 | 
			
		||||
@Service
 | 
			
		||||
| 
						 | 
				
			
			@ -28,6 +36,8 @@ public class LesServiceImpl implements LesService {
 | 
			
		|||
 | 
			
		||||
    private final LesRepository lesRepository;
 | 
			
		||||
 | 
			
		||||
    private final DictRepository dictRepository;
 | 
			
		||||
 | 
			
		||||
    private final LesMapper lesMapper;
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
| 
						 | 
				
			
			@ -97,8 +107,7 @@ public class LesServiceImpl implements LesService {
 | 
			
		|||
        validateParams(lesRequest);
 | 
			
		||||
 | 
			
		||||
        //验证任务是否存在
 | 
			
		||||
        String taskCode = lesRequest.getTaskCode();
 | 
			
		||||
        validateLes(taskCode);
 | 
			
		||||
        validateLes(lesRequest.getTaskCode());
 | 
			
		||||
 | 
			
		||||
        String materialCode = lesRequest.getMaterialCode();//物料代码
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -107,9 +116,36 @@ public class LesServiceImpl implements LesService {
 | 
			
		|||
            createLes(lesRequest);
 | 
			
		||||
        } else {
 | 
			
		||||
            //直接转发给AGV
 | 
			
		||||
            sendLesTask(JSON.toJSONString(lesRequest));
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public String lesCallBack(String currentPositionCode,String taskCode) {
 | 
			
		||||
        JSONObject jsonObject = new JSONObject(true);
 | 
			
		||||
        String guid = String.valueOf(System.currentTimeMillis());
 | 
			
		||||
        //LES任务的业务单号,不一定唯一
 | 
			
		||||
        jsonObject.put("reqCode", guid);
 | 
			
		||||
        //请求 id
 | 
			
		||||
        jsonObject.put("guid", guid);
 | 
			
		||||
        //系统标识
 | 
			
		||||
        jsonObject.put("appId", "KUKA");
 | 
			
		||||
        //请求时间
 | 
			
		||||
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
 | 
			
		||||
        jsonObject.put("reqTime", sdf.format(new Date()));
 | 
			
		||||
        //当前点位
 | 
			
		||||
        jsonObject.put("currentPositionCode", currentPositionCode);
 | 
			
		||||
        //关联任务号
 | 
			
		||||
        jsonObject.put("relReqTask", "");
 | 
			
		||||
        //备注
 | 
			
		||||
        jsonObject.put("data", "");
 | 
			
		||||
        //LES产生的任务号
 | 
			
		||||
        jsonObject.put("taskCode", taskCode);
 | 
			
		||||
        //method
 | 
			
		||||
        jsonObject.put("method", "end");
 | 
			
		||||
        return jsonObject.toString();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 验证参数有效性
 | 
			
		||||
     *
 | 
			
		||||
| 
						 | 
				
			
			@ -117,10 +153,23 @@ public class LesServiceImpl implements LesService {
 | 
			
		|||
     */
 | 
			
		||||
    private void validateParams(LesRequest lesRequest) {
 | 
			
		||||
        if (StringUtils.isEmpty(lesRequest.getTaskCode())) {
 | 
			
		||||
            throw new BadRequestException("任务号必填!");
 | 
			
		||||
            throw new BadRequestException("taskCode必填");
 | 
			
		||||
        }
 | 
			
		||||
        //物料有值;说明是料箱上线场景
 | 
			
		||||
        if (StringUtils.isNotEmpty(lesRequest.getMaterialCode())) {
 | 
			
		||||
            if (lesRequest.getPositionCodes().isEmpty() || lesRequest.getPositionCodes().size() < 2) {
 | 
			
		||||
            if(StringUtils.isEmpty(lesRequest.getRouteCode())){
 | 
			
		||||
                throw new BadRequestException("routeCode必填");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(StringUtils.isEmpty(lesRequest.getBoxNo())){
 | 
			
		||||
                throw new BadRequestException("boxNo必填");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if(StringUtils.isEmpty(lesRequest.getOnlineNo())){
 | 
			
		||||
                throw new BadRequestException("onlineNo必填");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (lesRequest.getPositionCodePath()==null ||lesRequest.getPositionCodePath().isEmpty() || lesRequest.getPositionCodePath().size() < 2) {
 | 
			
		||||
                throw new BadRequestException("节点不能为空且长度至少为2");
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -134,14 +183,14 @@ public class LesServiceImpl implements LesService {
 | 
			
		|||
    private void validateLes(String taskCode) {
 | 
			
		||||
        Les les = lesRepository.findByTaskCode(taskCode);
 | 
			
		||||
        if (les != null) {
 | 
			
		||||
            throw new BadRequestException(taskCode + "任务号已存在!");
 | 
			
		||||
            throw new BadRequestException(taskCode + "任务号系统已接收,请勿重复请求");
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    @Transactional(rollbackFor = Exception.class)
 | 
			
		||||
    public void createLes(LesRequest lesRequest) {
 | 
			
		||||
        //节点集合
 | 
			
		||||
        List<PositionCodeRequest> positionCodes = lesRequest.getPositionCodes();
 | 
			
		||||
        List<PositionCodeRequest> positionCodes = lesRequest.getPositionCodePath();
 | 
			
		||||
        //起点对象
 | 
			
		||||
        PositionCodeRequest srcPosition = positionCodes.get(0);
 | 
			
		||||
        //终点对象
 | 
			
		||||
| 
						 | 
				
			
			@ -162,4 +211,25 @@ public class LesServiceImpl implements LesService {
 | 
			
		|||
        lesRepository.save(les);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    private void sendLesTask(String json) {
 | 
			
		||||
        Dict dict = dictRepository.findDictByName("OPEN");
 | 
			
		||||
        String resultJson = "";
 | 
			
		||||
        if (dict != null) {
 | 
			
		||||
            resultJson = HttpPostUtil.sendPostReq(UrlApi.submitMission(), json);
 | 
			
		||||
            if (StringUtils.isEmpty(resultJson)) {
 | 
			
		||||
                throw new BadRequestException("AGV返回信息:下发任务接口调用失败");
 | 
			
		||||
            }
 | 
			
		||||
            JSONObject resulObject = JSON.parseObject(resultJson);
 | 
			
		||||
            if (resulObject == null) {
 | 
			
		||||
                throw new BadRequestException("AGV返回信息:下发任务接口返回为空");
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            String code = resulObject.getString("code");
 | 
			
		||||
            String message = resulObject.getString("message");
 | 
			
		||||
            if (!"0".equals(code)) {
 | 
			
		||||
                throw new BadRequestException("AGV返回消息:" + message);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,9 +1,7 @@
 | 
			
		|||
package com.youchain.businessdata.service.mapstruct;
 | 
			
		||||
 | 
			
		||||
import com.youchain.base.BaseMapper;
 | 
			
		||||
import com.youchain.businessdata.domain.AgvTask;
 | 
			
		||||
import com.youchain.businessdata.domain.Les;
 | 
			
		||||
import com.youchain.businessdata.service.dto.AgvTaskDto;
 | 
			
		||||
import com.youchain.businessdata.service.dto.LesDto;
 | 
			
		||||
import org.mapstruct.Mapper;
 | 
			
		||||
import org.mapstruct.ReportingPolicy;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,7 @@ import java.util.Date;
 | 
			
		|||
 | 
			
		||||
public class TimeNumberUtils {
 | 
			
		||||
    private static int sequence = 0;
 | 
			
		||||
    private static int length = 5;
 | 
			
		||||
    private static final int length = 5;
 | 
			
		||||
 | 
			
		||||
    public static synchronized String getCKCode() {
 | 
			
		||||
        sequence = sequence >= 999999 ? 1 : sequence + 1;
 | 
			
		||||
| 
						 | 
				
			
			@ -23,20 +23,20 @@ public class TimeNumberUtils {
 | 
			
		|||
        return "RK"+datetime +addLeftZero(s, length);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static synchronized String getRCCode() {
 | 
			
		||||
    public static synchronized String getCcCode() {
 | 
			
		||||
        sequence = sequence >= 999999 ? 1 : sequence + 1;
 | 
			
		||||
        String datetime = new SimpleDateFormat("yyMMddHHmmss")
 | 
			
		||||
                .format(new Date());
 | 
			
		||||
        String s = Integer.toString(sequence);
 | 
			
		||||
        return "RC"+datetime +addLeftZero(s, length);
 | 
			
		||||
        return "CC"+datetime +addLeftZero(s, length);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static synchronized String getXJTaskCode() {
 | 
			
		||||
    public static synchronized String getHjCode() {
 | 
			
		||||
        sequence = sequence >= 999999 ? 1 : sequence + 1;
 | 
			
		||||
        String datetime = new SimpleDateFormat("yyMMddHHmmss")
 | 
			
		||||
                .format(new Date());
 | 
			
		||||
        String s = Integer.toString(sequence);
 | 
			
		||||
        return "XJ"+datetime +addLeftZero(s, length);
 | 
			
		||||
        return "HJ"+datetime +addLeftZero(s, length);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static synchronized String getGTTaskCode() {
 | 
			
		||||
| 
						 | 
				
			
			@ -47,13 +47,6 @@ public class TimeNumberUtils {
 | 
			
		|||
        return "GT"+datetime +addLeftZero(s, length);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static synchronized String getKLXTaskCode() {
 | 
			
		||||
        sequence = sequence >= 999999 ? 1 : sequence + 1;
 | 
			
		||||
        String datetime = new SimpleDateFormat("yyMMddHHmmss")
 | 
			
		||||
                .format(new Date());
 | 
			
		||||
        String s = Integer.toString(sequence);
 | 
			
		||||
        return "KLX"+datetime +addLeftZero(s, length);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * 左填0
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -42,9 +42,6 @@ public interface DictRepository extends JpaRepository<Dict, Long>, JpaSpecificat
 | 
			
		|||
     */
 | 
			
		||||
    List<Dict> findByIdIn(Set<Long> ids);
 | 
			
		||||
 | 
			
		||||
    @Query(value = "SELECT * FROM sys_dict b WHERE b.name = ?1 ", nativeQuery = true)
 | 
			
		||||
    Dict getDictDescription(String name);
 | 
			
		||||
 | 
			
		||||
    @Query(value = " from Dict where description = :description ")
 | 
			
		||||
    Dict findDictByDescription(String description);
 | 
			
		||||
    @Query("from Dict dict where dict.name = :name ")
 | 
			
		||||
    Dict findDictByName(String name);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -73,5 +73,5 @@ public interface DictService {
 | 
			
		|||
     */
 | 
			
		||||
    void download(List<DictDto> queryAll, HttpServletResponse response) throws IOException;
 | 
			
		||||
 | 
			
		||||
    Dict getDictDescription(String name);
 | 
			
		||||
    Dict findDictByName(String name);
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -26,6 +26,7 @@ import lombok.RequiredArgsConstructor;
 | 
			
		|||
import com.youchain.modules.system.repository.DictRepository;
 | 
			
		||||
import com.youchain.modules.system.service.mapstruct.DictMapper;
 | 
			
		||||
import org.springframework.cache.annotation.CacheConfig;
 | 
			
		||||
import org.springframework.cache.annotation.Cacheable;
 | 
			
		||||
import org.springframework.data.domain.Page;
 | 
			
		||||
import org.springframework.data.domain.Pageable;
 | 
			
		||||
import org.springframework.stereotype.Service;
 | 
			
		||||
| 
						 | 
				
			
			@ -116,8 +117,9 @@ public class DictServiceImpl implements DictService {
 | 
			
		|||
    }
 | 
			
		||||
 | 
			
		||||
    @Override
 | 
			
		||||
    public Dict getDictDescription(String name) {
 | 
			
		||||
        return dictRepository.getDictDescription(name);
 | 
			
		||||
    @Cacheable(key = "#name", unless = "#result == null")
 | 
			
		||||
    public Dict findDictByName(String name) {
 | 
			
		||||
        return dictRepository.findDictByName(name);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public void delCaches(Dict dict){
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue