Agv任务上报、输送线扫描托盘

main
HUOJIN\92525 2025-11-07 17:55:05 +08:00
parent 68c3773cfc
commit eb8cf7ca0b
31 changed files with 1145 additions and 49 deletions

View File

@ -104,7 +104,9 @@ public class AutoLogAspect {
if(sysUser!=null){
dto.setUserid(sysUser.getUsername());
dto.setUsername(sysUser.getRealname());
}else {
dto.setUserid("赛意");
dto.setUsername("赛意");
}
//耗时
dto.setCostTime(time);

View File

@ -52,10 +52,20 @@ public class DictAspect {
/**
* Pointcut
*/
@Pointcut("(@within(org.springframework.web.bind.annotation.RestController) || " +
/* @Pointcut("(@within(org.springframework.web.bind.annotation.RestController) || " +
"@within(org.springframework.stereotype.Controller) || @annotation(org.jeecg.common.aspect.annotation.AutoDict)) " +
"&& execution(public org.jeecg.common.api.vo.Result org.jeecg..*.*(..)) || execution(public * org.cpte..*.*Controller.*(..))")
public void excudeService() {
}*/
/**
* Pointcut
*/
@Pointcut("(@within(org.springframework.web.bind.annotation.RestController) || " +
"@within(org.springframework.stereotype.Controller) || @annotation(org.jeecg.common.aspect.annotation.AutoDict)) " +
"&& (execution(public org.jeecg.common.api.vo.Result org.jeecg..*.*(..)) || " +
"(execution(public * org.cpte..*.*Controller.*(..)) && !execution(public org.cpte.modules.hikAgv.response.* org.cpte.modules.hikAgv.controller.*.*(..))))")
public void excudeService() {
}
@Around("excudeService()")

View File

@ -14,5 +14,9 @@
<groupId>org.jeecgframework.boot3</groupId>
<artifactId>cpte-boot-base-core</artifactId>
</dependency>
<dependency>
<groupId>org.jeecgframework.boot3</groupId>
<artifactId>cpte-system-biz</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -1,6 +1,7 @@
package org.cpte.modules.agvTask.entity;
import java.io.Serializable;
import java.sql.Timestamp;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
@ -13,6 +14,8 @@ import org.jeecgframework.poi.excel.annotation.Excel;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.experimental.Accessors;
import javax.persistence.Column;
/**
* @Description: AGV
* @author: cpte
@ -99,13 +102,27 @@ public class AgvTask implements Serializable {
@Schema(description = "返回报文")
private java.lang.String resMessage;
/**
*
*
*/
@Excel(name = "返回时间", width = 20, format = "yyyy-MM-dd HH:mm:ss")
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "返回时间")
private java.util.Date resMessageTime;
@Schema(description = "走出储位时间")
private java.util.Date outBinTime;
/**
*
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "开始时间")
private java.util.Date startTime;
/**
*
*/
@JsonFormat(timezone = "GMT+8", pattern = "yyyy-MM-dd HH:mm:ss")
@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
@Schema(description = "完成时间")
private java.util.Date endTime;
/**
*
*/

View File

@ -3,6 +3,7 @@ package org.cpte.modules.agvTask.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.cpte.modules.agvTask.entity.AgvTask;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
@ -13,5 +14,6 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
* @Version: V1.0
*/
public interface AgvTaskMapper extends BaseMapper<AgvTask> {
@Select(value = "select count(agv.id) from data_agv_task where carrier_code = #{carrierCode} and start_code = #{startCode} and end_code= #{endCode} and status in ('CREATED','ARRIVED','EXECUTING') ")
Long isAGVTaskDuplicate(String carrierCode, String startCode, String endCode);
}

View File

@ -3,6 +3,8 @@ package org.cpte.modules.agvTask.service;
import org.cpte.modules.agvTask.entity.AgvTask;
import com.baomidou.mybatisplus.extension.service.IService;
import java.util.List;
/**
* @Description: AGV
* @author: cpte
@ -22,4 +24,10 @@ public interface IAgvTaskService extends IService<AgvTask> {
*/
AgvTask createAgvTask(String status, String carrierCode, String startCode, String endCode, String taskType,String type);
/**
* agvTask
*
* @param status
*/
List<AgvTask> queryAgvTaskList(String status);
}

View File

@ -1,5 +1,6 @@
package org.cpte.modules.agvTask.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.cpte.modules.agvTask.entity.AgvTask;
import org.cpte.modules.agvTask.mapper.AgvTaskMapper;
import org.cpte.modules.agvTask.service.IAgvTaskService;
@ -9,6 +10,8 @@ import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
/**
* @Description: AGV
* @author: cpte
@ -33,4 +36,11 @@ public class AgvTaskServiceImpl extends ServiceImpl<AgvTaskMapper, AgvTask> impl
.build();
return this.save(agvTask) ? agvTask : null;
}
@Override
public List<AgvTask> queryAgvTaskList(String status) {
LambdaQueryWrapper<AgvTask> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(AgvTask::getStatus, status);
return this.list(queryWrapper);
}
}

View File

@ -0,0 +1,42 @@
package org.cpte.modules.conveyorLine.controller;
import com.alibaba.fastjson.JSON;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.extern.slf4j.Slf4j;
import org.cpte.modules.conveyorLine.request.ScanTrayRequest;
import org.cpte.modules.conveyorLine.service.IConveyorLineService;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.config.shiro.IgnoreAuth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "输送线")
@RestController
@RequestMapping("/api/conveyorLine")
@Slf4j
public class ConveyorLineController {
@Autowired
private IConveyorLineService iConveyorLineService;
/**
* 线
*
* @param scanTrayRequest
*/
@AutoLog(value = "输送线扫描")
@Operation(summary = "输送线-扫描托盘")
@PostMapping(value = "/scanTray")
@IgnoreAuth
public Result<String> scanTray(@RequestBody @Valid ScanTrayRequest scanTrayRequest) {
iConveyorLineService.scanTray(scanTrayRequest);
return Result.OK("扫描成功");
}
}

View File

@ -0,0 +1,13 @@
package org.cpte.modules.conveyorLine.request;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class ScanTrayRequest {
//托盘码
@NotBlank(message = "托盘码不能为空")
@JsonProperty("stockCode")
private String stockCode;
}

View File

@ -0,0 +1,13 @@
package org.cpte.modules.conveyorLine.service;
import org.cpte.modules.conveyorLine.request.ScanTrayRequest;
public interface IConveyorLineService {
/**
*
*
* @param scanTrayRequest
*/
void scanTray(ScanTrayRequest scanTrayRequest);
}

View File

@ -0,0 +1,27 @@
package org.cpte.modules.conveyorLine.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.cpte.modules.conveyorLine.request.ScanTrayRequest;
import org.cpte.modules.conveyorLine.service.IConveyorLineService;
import org.cpte.modules.receive.entity.AsnDetail;
import org.cpte.modules.receive.mapper.AsnDetailMapper;
import org.cpte.modules.receive.service.IAsnService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@Slf4j
public class IConveyorLineServiceImpl implements IConveyorLineService {
@Autowired
private AsnDetailMapper asnDetailMapper;
@Override
public void scanTray(ScanTrayRequest scanTrayRequest) {
AsnDetail asnDetail=asnDetailMapper.queryByStockCode(scanTrayRequest.getStockCode());
if(asnDetail==null){
throw new RuntimeException("【"+scanTrayRequest.getStockCode()+"】托盘,无入库信息");
}
}
}

View File

@ -0,0 +1,60 @@
package org.cpte.modules.hikAgv.controller;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.cpte.modules.hikAgv.request.submit.SubmitRequest;
import org.cpte.modules.hikAgv.request.taskReporter.TaskReporterRequest;
import org.cpte.modules.hikAgv.response.ResponesData;
import org.cpte.modules.hikAgv.service.IHikAgvService;
import org.jeecg.common.api.vo.Result;
import org.cpte.modules.hikAgv.response.HikResult;
import org.jeecg.common.aspect.annotation.AutoLog;
import org.jeecg.config.shiro.IgnoreAuth;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Tag(name = "海康AGV")
@RestController
@RequestMapping("/api/robot")
@Slf4j
public class HikAgvController {
@Autowired
private IHikAgvService hikAgvService;
/**
*
*
* @param submitRequest
*/
@AutoLog(value = "任务下发")
@Operation(summary = "海康AGV-任务下发")
@PostMapping(value = "/controller/task/submit")
@IgnoreAuth
public Result<String> submit(@RequestBody SubmitRequest submitRequest) {
hikAgvService.sendAgvTask("http://localhost:8000/cpte-wms/rcs/rtas/api/robot/controller/task/submit", JSON.toJSONString(submitRequest), null);
return Result.OK("下发成功!");
}
@AutoLog(value = "任务上报")
@Operation(summary = "海康AGV-任务上报")
@PostMapping(value = "/reporter/task")
@IgnoreAuth
public HikResult taskReporter(@RequestBody TaskReporterRequest taskReporterRequest) {
try {
hikAgvService.taskReporter(taskReporterRequest);
ResponesData data = new ResponesData();
data.setRobotTaskCode(taskReporterRequest.getRobotTaskCode());
return HikResult.success(data);
} catch (Exception e) {
return HikResult.error("上报失败: " + e.getMessage());
}
}
}

View File

@ -0,0 +1,28 @@
package org.cpte.modules.hikAgv.request.submit;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
*
*
* AGV
*/
@Data
public class AngleInfo {
/**
*
*
* ABSOLUTE:
*/
@JsonProperty("type")
private String type;
/**
*
* type
* [0, 90, 180, -90, 360]
*/
@JsonProperty("code")
private String code;
}

View File

@ -0,0 +1,34 @@
package org.cpte.modules.hikAgv.request.submit;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
*
*
* AGV
*/
@Data
public class CarrierInfo {
/**
*
*
*/
@JsonProperty("carrierType")
private String carrierType;
/**
*
*
*/
@JsonProperty("carrierCode")
private String carrierCode;
/**
*
* 0
*/
@JsonProperty("layer")
private String layer;
}

View File

@ -0,0 +1,30 @@
package org.cpte.modules.hikAgv.request.submit;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
/**
*
*
* AGV
*/
@Data
public class Extra {
/**
*
* AGV
*/
@JsonProperty("angleInfo")
private AngleInfo angleInfo;
/**
*
*
*
*/
@JsonProperty("carrierInfo")
private List<CarrierInfo> carrierInfo;
}

View File

@ -0,0 +1,104 @@
package org.cpte.modules.hikAgv.request.submit;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import lombok.Data;
import java.util.List;
/**
* AGV
* <p>
* AGVDTO
*
*/
@JsonPropertyOrder({
"taskType",
"targetRoute",
"initPriority",
"deadline",
"robotType",
"robotCode",
"interrupt",
"robotTaskCode",
"groupCode",
"extra"
})
@Data
public class SubmitRequest {
/**
*
* AGV
*/
@JsonProperty("taskType")
private String taskType;
/**
*
*
*/
@JsonProperty("targetRoute")
private List<TargetRoute> targetRoute;
/**
*
*
*/
@JsonProperty("initPriority")
private Integer initPriority;
/**
*
* ISO 86012021-04-04T12:23:55Z
*/
@JsonProperty("deadline")
private String deadline;
/**
*
*
* GROUPS:
* ROBOTS:
*/
@JsonProperty("robotType")
private String robotType;
/**
*
* robotType
*/
@JsonProperty("robotCode")
private List<String> robotCode;
/**
*
*
* 1: -
* 0: -
*/
@JsonProperty("interrupt")
private Integer interrupt;
/**
*
*
*/
@JsonProperty("robotTaskCode")
private String robotTaskCode;
/**
*
*
*/
@JsonProperty("groupCode")
private String groupCode;
/**
*
*
*
*/
@JsonProperty("extra")
private Extra extra;
}

View File

@ -0,0 +1,70 @@
package org.cpte.modules.hikAgv.request.submit;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
import java.util.List;
/**
*
*
* AGV
*/
@Data
public class TargetRoute {
/**
*
* 0
*/
@JsonProperty("seq")
private Integer seq;
/**
*
*
*/
@JsonProperty("type")
private String type;
/**
*
*
*/
@JsonProperty("code")
private String code;
/**
*
* AMR
*
* COLLECT:
* DELIVERY:
* ROTATE:
*/
@JsonProperty("operation")
private String operation;
/**
*
*
* GROUPS:
* ROBOTS:
*/
@JsonProperty("robotType")
private String robotType;
/**
*
* [robotType]
*/
@JsonProperty("robotCode")
private List<String> robotCode;
/**
*
* 使
*/
@JsonProperty("extra")
private Extra extra;
}

View File

@ -0,0 +1,15 @@
package org.cpte.modules.hikAgv.request.taskReporter;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class Extra {
@JsonProperty("async")
private String async;
//节点信息
@JsonProperty("values")
private Values values;
}

View File

@ -0,0 +1,36 @@
package org.cpte.modules.hikAgv.request.taskReporter;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* AGV
* <p>
* AGVDTO
*
*/
@Data
public class TaskReporterRequest {
/**
*
*
*/
@JsonProperty("robotTaskCode")
private String robotTaskCode;
/**
*
* AGV
*/
@JsonProperty("singleRobotCode")
private String singleRobotCode;
/**
*
*
*/
@JsonProperty("extra")
private Extra extra;
}

View File

@ -0,0 +1,124 @@
package org.cpte.modules.hikAgv.request.taskReporter;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
/**
* AGV
* <p>
* AGV
*/
@Data
public class Values {
/**
*
* AGV
*/
@JsonProperty("mapCode")
private String mapCode;
/**
*
*
* BIN -
* SITE -
*/
@JsonProperty("slotCategory")
private String slotCategory;
/**
*
* AGV
*/
@JsonProperty("slotCode")
private String slotCode;
/**
*
* 1.
* 2.
*/
@JsonProperty("slotName")
private String slotName;
/**
* x
* AGVX
*/
@JsonProperty("x")
private Integer x;
/**
* y
* AGVY
*/
@JsonProperty("y")
private Integer y;
/**
*
* 使:
* start :
* outbin :
* end :
*/
@JsonProperty("method")
private String method;
/**
*
*
*/
@JsonProperty("carrierCategory")
private String carrierCategory;
/**
*
*
*/
@JsonProperty("carrierType")
private String carrierType;
/**
*
*
*/
@JsonProperty("carrierCode")
private String carrierCode;
/**
*
*
*/
@JsonProperty("amrCategory")
private String amrCategory;
/**
*
*
*/
@JsonProperty("amrType")
private String amrType;
/**
*
*
*/
@JsonProperty("amrCode")
private String amrCode;
/**
*
*
*/
@JsonProperty("carrierName")
private String carrierName;
/**
*
*
*/
@JsonProperty("carrierDir")
private String carrierDir;
}

View File

@ -0,0 +1,46 @@
package org.cpte.modules.hikAgv.response;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.io.Serializable;
/**
*
*
* @author scott
* @email cpteos@163.com
* @date 2019119
*/
@Data
public class HikResult implements Serializable {
/**
*
*/
private String code = "";
/**
*
*/
private String message = "";
/**
* data
*/
private ResponesData data;
public static HikResult success(ResponesData data) {
HikResult response = new HikResult();
response.code = "SUCCESS";
response.message = "成功";
response.data = data;
return response;
}
public static HikResult error(String message) {
HikResult response = new HikResult();
response.code = "FAIL";
response.message = message;
return response;
}
}

View File

@ -0,0 +1,10 @@
package org.cpte.modules.hikAgv.response;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class ResponesData {
@JsonProperty("robotTaskCode")
private String robotTaskCode;
}

View File

@ -0,0 +1,30 @@
package org.cpte.modules.hikAgv.service;
import org.cpte.modules.agvTask.entity.AgvTask;
import org.cpte.modules.hikAgv.request.submit.SubmitRequest;
import org.cpte.modules.hikAgv.request.taskReporter.TaskReporterRequest;
public interface IHikAgvService {
/**
* JSON
*
* @param agvTask
*/
SubmitRequest generateAgvTaskJson(AgvTask agvTask);
/**
*
*
* @param url
* @param json json
* @param agvTask
*/
void sendAgvTask(String url, String json, AgvTask agvTask);
/**
*
*
* @param taskReporterRequest
*/
void taskReporter(TaskReporterRequest taskReporterRequest);
}

View File

@ -0,0 +1,251 @@
package org.cpte.modules.hikAgv.service.impl;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.cpte.modules.agvTask.entity.AgvTask;
import org.cpte.modules.agvTask.mapper.AgvTaskMapper;
import org.cpte.modules.agvTask.service.IAgvTaskService;
import org.cpte.modules.constant.enums.*;
import org.cpte.modules.hikAgv.request.submit.*;
import org.cpte.modules.hikAgv.request.taskReporter.TaskReporterRequest;
import org.cpte.modules.hikAgv.service.IHikAgvService;
import org.jeecg.modules.system.mapper.SysDictMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.*;
@Service
@Slf4j
public class IHikAgvServiceImpl implements IHikAgvService {
// 接口开关
final String open_flag = "OPEN";
// 成功码
final String success_code = "SUCCESS";
@Autowired
private SysDictMapper sysDictMapper;
@Autowired
private AgvTaskMapper agvTaskMapper;
@Autowired
private IAgvTaskService iAgvTaskService;
@Override
public SubmitRequest generateAgvTaskJson(AgvTask agvTask) {
SubmitRequest submitRequest = new SubmitRequest();
submitRequest.setTaskType("PF-LMR-COMMON");
// 设置起点路径
TargetRoute srcTargetRoute = createSrcTargetRoute(agvTask);
// 设置终点路径
TargetRoute dstTargetRoute = createDstTargetRoute(agvTask);
submitRequest.setTargetRoute(Arrays.asList(srcTargetRoute, dstTargetRoute));
submitRequest.setInitPriority(agvTask == null ? 99 : agvTask.getPriority());
LocalDateTime now = LocalDateTime.now(ZoneOffset.UTC);
String deadline = now.format(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"));
submitRequest.setDeadline(deadline);
submitRequest.setRobotType("GROUPS");
submitRequest.setRobotCode(Collections.singletonList("c3a1e7bb"));
Extra extra1 = new Extra();
extra1.setCarrierInfo(createCarrierInfoList(agvTask == null ? "" : agvTask.getCarrierCode()));
submitRequest.setExtra(extra1);
submitRequest.setInterrupt(0);
submitRequest.setRobotTaskCode(agvTask == null ? "" : agvTask.getId());
submitRequest.setGroupCode(agvTask == null ? "" : agvTask.getId());
return submitRequest;
}
@Override
public void sendAgvTask(String url, String json, AgvTask agvTask) {
log.info("请求报文:{}", json);
// 检查接口开关, 未开启则返回
if (sysDictMapper.queryByDictCode(open_flag) == null) {
updateAgvTaskResponse(agvTask, "接口未开启", "FAILED");
return;
}
String code = null;
String message = null;
try {
//String result = HttpPostUtil.sendPostReq(url, json);
String result = "{\n" +
" \"message\": \"成功\",\n" +
" \"code\":\"SUCCESS\",\n" +
"}";
if (StringUtils.isEmpty(result)) {
message = "AGV返回信息:下发任务接口调用失败";
throw new RuntimeException(message);
}
JSONObject resulObject = JSON.parseObject(result);
if (resulObject == null) {
message = "AGV返回信息:下发任务接口返回为空";
throw new RuntimeException(message);
}
code = resulObject.getString("code");
message = resulObject.getString("message");
if (!success_code.equals(code)) {
throw new RuntimeException("AGV返回消息:" + message);
}
// 更新任务状态
updateAgvTaskResponse(agvTask, message, code);
} catch (Exception e) {
// 记录异常到 AgvTask
updateAgvTaskResponse(agvTask, e.getMessage(), "FAILED");
throw e; // 继续向上抛出异常供 Controller 层处理
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public void taskReporter(TaskReporterRequest taskReporterRequest) {
AgvTask agvTask = agvTaskMapper.selectById(taskReporterRequest.getRobotTaskCode());
String status = taskReporterRequest.getExtra().getValues().getMethod();
switch (status) {
case "outbin":
//走出储位
handleOutBin(agvTask);
break;
case "end":
//任务完成
handleEnd(agvTask);
break;
case "resend":
//重新发送
handleResend(agvTask);
break;
}
}
/**
*
*
* @param agvTask
*/
private void handleOutBin(AgvTask agvTask) {
}
/**
*
*
* @param agvTask
*/
private void handleEnd(AgvTask agvTask) {
agvTask.setStatus(AgvStatusEnum.COMPLETED.getValue());
agvTask.setEndTime(new Date());
agvTaskMapper.updateById(agvTask);
}
/**
*
*
* @param agvTask
*/
private void handleResend(AgvTask agvTask) {
Long count = agvTaskMapper.isAGVTaskDuplicate(agvTask.getCarrierCode(), agvTask.getStartCode(), agvTask.getEndCode());
if (count > 0) {
throw new RuntimeException("任务已重新生成,请勿重复操作! ");
}
AgvTask newAgvTask = iAgvTaskService.createAgvTask(AgvStatusEnum.CREATED.getValue(), agvTask.getCarrierCode(), agvTask.getStartCode(), agvTask.getEndCode(), agvTask.getTaskType(), agvTask.getType());
switch (agvTask.getType()) {
case "INBOUND":
case "OUTBOUND":
//下发任务
sendAgvTask("", "", newAgvTask);
break;
default:
throw new RuntimeException("任务类型不支持: " + agvTask.getType());
}
}
private void updateAgvTaskResponse(AgvTask agvTask, String message, String code) {
if (agvTask != null) {
if (success_code.equals(code)) {
agvTask.setStatus(AgvStatusEnum.EXECUTING.getValue());
}
agvTask.setResMessage(message);
agvTask.setStartTime(new Date());
agvTaskMapper.updateById(agvTask);
}
}
/**
*
*
* @param agvTask
* @return TargetRoute
*/
private TargetRoute createSrcTargetRoute(AgvTask agvTask) {
TargetRoute srcTargetRoute = new TargetRoute();
srcTargetRoute.setSeq(0);
srcTargetRoute.setType("ZONE");
srcTargetRoute.setCode(agvTask == null ? "" : agvTask.getStartCode());
srcTargetRoute.setOperation("COLLECT");
srcTargetRoute.setExtra(null);
srcTargetRoute.setRobotType("GROUPS");
srcTargetRoute.setRobotCode(Collections.singletonList("a361flb8"));
return srcTargetRoute;
}
/**
*
*
* @param agvTask
* @return TargetRoute
*/
private TargetRoute createDstTargetRoute(AgvTask agvTask) {
TargetRoute dstTargetRoute = new TargetRoute();
dstTargetRoute.setSeq(1);
dstTargetRoute.setType("SITE");
dstTargetRoute.setCode(agvTask == null ? "" : agvTask.getEndCode());
dstTargetRoute.setOperation("DELIVERY");
Extra extra = new Extra();
AngleInfo angleInfo = new AngleInfo();
angleInfo.setType("RELATIVE");
angleInfo.setCode("90");
extra.setAngleInfo(angleInfo);
extra.setCarrierInfo(createCarrierInfoList(agvTask == null ? "" : agvTask.getCarrierCode()));
dstTargetRoute.setExtra(extra);
return dstTargetRoute;
}
private List<CarrierInfo> createCarrierInfoList(String carrierCode) {
List<CarrierInfo> carrierInfoList = new ArrayList<>();
CarrierInfo cif = new CarrierInfo();
cif.setCarrierType("1"); // 建议替换为常量
cif.setCarrierCode(carrierCode);
cif.setLayer("0");
carrierInfoList.add(cif);
return carrierInfoList;
}
}

View File

@ -0,0 +1,38 @@
package org.cpte.modules.quartz.job;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.cpte.modules.agvTask.entity.AgvTask;
import org.cpte.modules.agvTask.service.IAgvTaskService;
import org.cpte.modules.constant.enums.AgvStatusEnum;
import org.cpte.modules.hikAgv.service.IHikAgvService;
import org.jeecg.common.util.DateUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
@Slf4j
public class AgvTaskJob implements Job {
@Autowired
private IAgvTaskService agvTaskService;
@Autowired
private IHikAgvService hikAgvService;
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
// 查询待执行任务
List<AgvTask> agvTaskList = agvTaskService.queryAgvTaskList(AgvStatusEnum.CREATED.getValue());
String taskSubmitUrl = "http://localhost:8000/cpte-wms/rcs/rtas/api/robot/controller/task/submit";
for (AgvTask agvTask : agvTaskList) {
try {
hikAgvService.sendAgvTask(taskSubmitUrl, JSON.toJSONString(hikAgvService.generateAgvTaskJson(agvTask)), agvTask);
} catch (Exception e) {
log.error("发送AGV任务失败任务ID: {}", agvTask.getId(), e);
}
}
}
}

View File

@ -1,6 +1,9 @@
package org.cpte.modules.receive.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Select;
import org.cpte.modules.receive.entity.Asn;
import org.cpte.modules.receive.entity.AsnDetail;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Param;
@ -28,4 +31,18 @@ public interface AsnDetailMapper extends BaseMapper<AsnDetail> {
* @return List<AsnDetail>
*/
public List<AsnDetail> selectByMainId(@Param("mainId") String mainId);
/**
*
*
* @param stockCode
* @return AsnDetail
*/
@Select("select * from data_asn_detail " +
"join data_asn on data_asn.id=data_asn_detail.asn_id " +
"join base_stock on data_asn_detail.stock_id=base_stock.id " +
"where base_stock.stock_code = #{stockCode} " +
"and data_asn.status='CREATED' ")
AsnDetail queryByStockCode(@Param("stockCode") String stockCode);
}

View File

@ -22,4 +22,6 @@ public interface AsnMapper extends BaseMapper<Asn> {
*/
@Select("select * from data_asn where no = #{no}")
Asn queryByNo(@Param("no") String no);
}

View File

@ -0,0 +1,75 @@
package org.cpte.modules.utils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
@Slf4j
public class HttpPostUtil {
public static String sendPostReq(String apiUrl, String jsonRequest) {
HttpURLConnection connection = null;
try {
// 创建URL对象并建立连接
URL url = new URL(apiUrl);
connection = (HttpURLConnection) url.openConnection();
// 配置连接参数
connection.setConnectTimeout(5000);
connection.setReadTimeout(10000);
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setUseCaches(false);
connection.setRequestMethod("POST");
// 设置HTTP头
connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
connection.setRequestProperty("Accept", "application/json");
// 写入请求体
byte[] requestData = jsonRequest.getBytes(StandardCharsets.UTF_8);
connection.setRequestProperty("Content-Length", String.valueOf(requestData.length));
try (OutputStream os = connection.getOutputStream()) {
os.write(requestData);
}
// 处理响应
int responseCode = connection.getResponseCode();
if (responseCode >= HttpURLConnection.HTTP_BAD_REQUEST) {
// 错误处理
try (InputStream errorStream = connection.getErrorStream()) {
String errorResponse = "";
if (errorStream != null) {
errorResponse = new String(IOUtils.toByteArray(errorStream), StandardCharsets.UTF_8);
}
log.error("HTTP请求失败: 状态码={}, 错误响应={}", responseCode, errorResponse);
return null;
}
}
// 读取正常响应
try (InputStream inputStream = connection.getInputStream()) {
String response = new String(IOUtils.toByteArray(inputStream), StandardCharsets.UTF_8);
if (response.trim().isEmpty()) {
log.warn("HTTP请求返回空响应");
}
return response;
}
} catch (IOException e) {
log.error("HTTP请求异常: {}", e.getMessage(), e);
return null;
} finally {
// 确保连接断开
if (connection != null) {
connection.disconnect();
}
}
}
}

View File

@ -1,25 +0,0 @@
package org.jeecg.modules.quartz.job;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.util.DateUtils;
import org.quartz.Job;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
@Slf4j
public class AgvTaskJob implements Job {
/**
* QuartzJobController
*/
private String parameter;
public void setParameter(String parameter) {
this.parameter = parameter;
}
@Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
log.info(" Job Execution key" + jobExecutionContext.getJobDetail().getKey());
log.info(String.format("welcome %s! Jeecg-Boot 带参数定时任务 SampleParamJob ! 时间:" + DateUtils.now(), this.parameter));
}
}

View File

@ -214,4 +214,7 @@ public interface SysDictMapper extends BaseMapper<SysDict> {
* @return
*/
int removeLogicDeleted(@Param("ids")List<String> ids);
@Select("select * from sys_dict where description = #{description}")
SysDict queryByDictCode(String description);
}