LES任务下发、LES回传;AGV任务下发;AGV上报

main
huojin\hj 2025-08-05 13:55:42 +08:00
parent 4673e9fa42
commit 8cdfe962f6
17 changed files with 820 additions and 110 deletions

View File

@ -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;
}
}

View File

@ -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;
}

View File

@ -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);
}

View File

@ -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;

View File

@ -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);

View File

@ -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);
}

View File

@ -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);
/**
* agvJSON
*
* @param agvTask
*/
String sendAgvTaskCcJson(AgvTask agvTask);
/**
* agvJSON
*
* @param agvTask
*/
String sendAgvTaskHjJson(AgvTask agvTask);
/**
* agvJSON
*
* @param agvTask
*/
String sendAgvTaskGtJson(AgvTask agvTask);
/**
* agvJSON
*
* @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);
}

View File

@ -75,4 +75,12 @@ public interface LesService {
*/
void genAgvSchedulingTask( LesRequest lesRequest);
/**
* LES
* @param currentPositionCode
* @param taskCode
* @return json
*/
String lesCallBack(String currentPositionCode,String taskCode);
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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);
}
}

View File

@ -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);
}
}
}
}

View File

@ -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;

View File

@ -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

View File

@ -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);
}

View File

@ -73,5 +73,5 @@ public interface DictService {
*/
void download(List<DictDto> queryAll, HttpServletResponse response) throws IOException;
Dict getDictDescription(String name);
Dict findDictByName(String name);
}

View File

@ -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){