liweidong
liweidong-hj 1 month ago
parent 5ee6114ecd
commit 6057f5b8ae
  1. 4
      blade-common/src/main/java/org/springblade/common/constant/LauncherConstant.java
  2. 2
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/mapper/LocationMapper.java
  3. 4
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/mapper/LocationMapper.xml
  4. 8
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/ILocationService.java
  5. 11
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/ITaskExecuteRecordService.java
  6. 14
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/IOrderBoxServiceImpl.java
  7. 5
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/LocationServiceImpl.java
  8. 38
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/StorageMonitoringServiceImpl.java
  9. 87
      blade-service/blade-desk/src/main/java/org/springblade/desk/logistics/service/impl/TaskExecuteRecordServiceImpl.java

@ -12,9 +12,9 @@ public interface LauncherConstant {
/**
* nacos 命名空间
*/
// String NACOS_NAMESPACE = "feaf627f-a847-463b-8b73-24a0538f526e";
String NACOS_NAMESPACE = "feaf627f-a847-463b-8b73-24a0538f526e";
// 生产环境
String NACOS_NAMESPACE = "db3f4da1-ae19-4104-8c17-6d9b8f069401";
// String NACOS_NAMESPACE = "db3f4da1-ae19-4104-8c17-6d9b8f069401";
// 测试环境
// String NACOS_NAMESPACE = "6cdd0310-0d61-4f54-891a-7fb06224d9b8";

@ -13,4 +13,6 @@ public interface LocationMapper extends BaseMapper<Location> {
List<Location> selectByLocationStatus(@Param("statusFree") Integer statusFree);
List<Location> selectByStatus(@Param("status") Integer status);
Location selectByLocationCode(@Param("locationCode") String locationCode, @Param("status")int status);
}

@ -13,4 +13,8 @@
select id, location_name, location_code, location_status, status, create_user, create_time, create_dept, update_user, update_time, is_deleted, remark
from LM_LOCATION where IS_DELETED = 0 and status = #{status} and LOCATION_STATUS = 0;
</select>
<select id="selectByLocationCode" resultType="org.springblade.desk.logistics.pojo.entity.Location">
select id, location_name, location_code, location_status, status, create_user, create_time, create_dept, update_user, update_time, is_deleted, remark
from LM_LOCATION where IS_DELETED = 0 and status = #{status} and LOCATION_CODE = #{locationCode};
</select>
</mapper>

@ -52,4 +52,12 @@ public interface ILocationService extends BaseService<Location> {
* @return
*/
List<Location> selectByStatus(Integer status);
/**
* 根据库位编码 层数 查询
* @param locationCode 库位编码
* @param status 层数
* @return
*/
Location selectByLocationCode(String locationCode, int status);
}

@ -75,7 +75,7 @@ public interface ITaskExecuteRecordService extends BaseService<TaskExecuteRecord
* @param taskCode
* @return
*/
boolean containerToEmpty(String taskCode);
boolean containerToCtu(String taskCode);
/**
* CTU调用接口
@ -87,5 +87,12 @@ public interface ITaskExecuteRecordService extends BaseService<TaskExecuteRecord
* @param type
* @return
*/
boolean genCtuSchedulingTask(String taskTyp,String ctnrTyp, String ctnrCode,String startPos, String endPos, String type);
AgvSchedulingTaskVO genCtuSchedulingTask(String taskTyp,String ctnrTyp, String ctnrCode,String startPos, String endPos, String type);
/**
* agv调用前置接口
* @param taskCode
* @return
*/
boolean containerToAgv(String taskCode);
}

@ -2,7 +2,6 @@ package org.springblade.desk.logistics.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import groovy.lang.Lazy;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
@ -15,7 +14,6 @@ import org.springblade.desk.logistics.service.*;
import org.springblade.desk.logistics.utils.AgvTaskTypeUtil;
import org.springblade.desk.order.pojo.entity.YieldOrder;
import org.springblade.desk.order.service.IYieldOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
@ -25,9 +23,7 @@ import java.util.*;
import java.util.stream.Collectors;
import static org.springblade.desk.logistics.constant.AgvConstant.EQUIPMENT_TYPE_AGV;
import static org.springblade.desk.logistics.pojo.entity.OrderBind.STATUS_UNBINDED;
import static org.springblade.desk.logistics.pojo.entity.Station.*;
import static org.springblade.desk.logistics.utils.CollectionCheckUtil.isFieldInCollection;
/**
* 订单箱业务实现类
@ -63,7 +59,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
private final AgvTaskTypeUtil agvTaskTypeUtil;
private final IBsWorkCenterService bsWorkCenterService;
private final IPipelineService iPipelineOrderBoxService;
private final IPipelineService pipelineService;
/**
* 任务运行中状态集合包含任务从启动到待入库的所有中间状态
@ -83,7 +79,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
RUNNING_STATUSES.add(Task.STATUS_BACK_TO_STORAGE);// 返库状态
}
public IOrderBoxServiceImpl(IYieldOrderService iYieldOrderService, ITaskService iTaskService, IOrderBindService iOrderBindService, IStationService iStationService, ILocationService iLocationService, AgvTaskTypeUtil agvTaskTypeUtil, IBsWorkCenterService bsWorkCenterService, IPipelineService iPipelineOrderBoxService) {
public IOrderBoxServiceImpl(IYieldOrderService iYieldOrderService, ITaskService iTaskService, IOrderBindService iOrderBindService, IStationService iStationService, ILocationService iLocationService, AgvTaskTypeUtil agvTaskTypeUtil, IBsWorkCenterService bsWorkCenterService, IPipelineService iPipelineOrderBoxService, IPipelineService pipelineService) {
this.iYieldOrderService = iYieldOrderService;
this.iTaskService = iTaskService;
this.iOrderBindService = iOrderBindService;
@ -91,7 +87,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
this.iLocationService = iLocationService;
this.agvTaskTypeUtil = agvTaskTypeUtil;
this.bsWorkCenterService = bsWorkCenterService;
this.iPipelineOrderBoxService = iPipelineOrderBoxService;
this.pipelineService = pipelineService;
}
/**
@ -328,7 +324,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
try {
// 2. 获取AGV任务类型并调用调度接口
String taskType = agvTaskTypeUtil.getTaskType(Integer.valueOf(targetStation.getStationPosition()), true);
boolean agvResult = iPipelineOrderBoxService.genAgvSchedulingTask(
boolean agvResult = pipelineService.genAgvSchedulingTask(
taskType, stationCode, DROPOFF_CONVEYOR_LINE, EQUIPMENT_TYPE_AGV, taskList.get(0)
);
@ -362,7 +358,7 @@ public class IOrderBoxServiceImpl implements IOrderBoxService {
try {
// 3. 获取AGV任务类型并调用调度接口
String taskType = agvTaskTypeUtil.getTaskType(Integer.valueOf(targetStation.getStationPosition()), false);
boolean agvResult = iPipelineOrderBoxService.genAgvSchedulingTask(
boolean agvResult = pipelineService.genAgvSchedulingTask(
taskType, sourceStationCode, endStation.getStationCode(), EQUIPMENT_TYPE_AGV, taskList.get(0)
);

@ -60,4 +60,9 @@ public class LocationServiceImpl extends BaseServiceImpl<LocationMapper, Locatio
public List<Location> selectByStatus(Integer status) {
return locationMapper.selectByStatus(status);
}
@Override
public Location selectByLocationCode(String locationCode, int status) {
return locationMapper.selectByLocationCode(locationCode,status);
}
}

@ -1,16 +1,16 @@
package org.springblade.desk.logistics.service.impl;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springblade.desk.logistics.constant.AgvConstant;
import org.springblade.desk.logistics.pojo.entity.Location;
import org.springblade.desk.logistics.pojo.entity.Station;
import org.springblade.desk.logistics.pojo.entity.Task;
import org.springblade.desk.logistics.service.ILocationService;
import org.springblade.desk.logistics.service.IStationService;
import org.springblade.desk.logistics.service.IStorageMonitoringService;
import org.springblade.desk.logistics.service.ITaskService;
import org.springframework.scheduling.annotation.Scheduled;
import org.springblade.desk.logistics.pojo.vo.AgvSchedulingTaskVO;
import org.springblade.desk.logistics.service.*;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import java.util.List;
@ -51,6 +51,8 @@ public class StorageMonitoringServiceImpl implements IStorageMonitoringService {
*/
private final ILocationService locationService;
private final ITaskExecuteRecordService taskExecuteRecordService;
/**
* 构造器注入依赖Spring官方推荐方式
* <p>
@ -58,15 +60,16 @@ public class StorageMonitoringServiceImpl implements IStorageMonitoringService {
* 1. 强制依赖注入避免NPE空指针异常
* 2. 便于单元测试时模拟依赖
* 3. 符合依赖倒置原则降低耦合
*
* @param taskService 任务服务BeanSpring自动注入
* @param stationService 站点服务BeanSpring自动注入
* @param locationService 库位服务BeanSpring自动注入
* @param taskExecuteRecordService
*/
public StorageMonitoringServiceImpl(ITaskService taskService, IStationService stationService, ILocationService locationService) {
public StorageMonitoringServiceImpl(ITaskService taskService, IStationService stationService, ILocationService locationService, ITaskExecuteRecordService taskExecuteRecordService) {
this.taskService = taskService;
this.stationService = stationService;
this.locationService = locationService;
this.taskExecuteRecordService = taskExecuteRecordService;
}
/**
@ -167,8 +170,25 @@ public class StorageMonitoringServiceImpl implements IStorageMonitoringService {
// ========== 步骤2.5:触发AGV小车移动指令(待实现) ==========
log.info("【仓储监控】站点ID:{} - 准备调用AGV接口,任务ID:{},库位ID:{}",
station.getId(), firstTask.getId(), locationId);
// todo: 调用AGV接口传递任务ID和站点ID,触发小车移动
// agvService.dispatchAgv(firstTask.getId(), station.getId());
// 调用AGV接口传递任务ID和站点ID,触发小车移动
// 查询空闲梳齿架子
List<Location> locationList = locationService.selectByStatus(1);
if(CollectionUtils.isEmpty(locationList)){
log.error("库位暂时没有空闲梳齿架子");
return;
}
String locationCode = locationList.get(0).getLocationCode();
//调用ctu
AgvSchedulingTaskVO ctuSchedulingTask = taskExecuteRecordService.genCtuSchedulingTask("CTu2", "1", firstTask.getBoxBarcode(), location.getLocationCode(),
locationCode, AgvConstant.EQUIPMENT_TYPE_CTU);
//调用成功 添加任务
if(null != ctuSchedulingTask){
// 添加任务
boolean record = taskExecuteRecordService.inboundRecord(ctuSchedulingTask, firstTask);
}
processedCount++; // 成功处理计数+1

@ -14,12 +14,12 @@ import org.springblade.desk.logistics.constant.AgvConstant;
import org.springblade.desk.logistics.mapper.TaskExecuteRecordMapper;
import org.springblade.desk.logistics.pojo.dto.AGVCallBackDto;
import org.springblade.desk.logistics.pojo.entity.Location;
import org.springblade.desk.logistics.pojo.entity.Station;
import org.springblade.desk.logistics.pojo.entity.Task;
import org.springblade.desk.logistics.pojo.entity.TaskExecuteRecord;
import org.springblade.desk.logistics.pojo.vo.AgvSchedulingTaskVO;
import org.springblade.desk.logistics.service.ILocationService;
import org.springblade.desk.logistics.service.ITaskExecuteRecordService;
import org.springblade.desk.logistics.service.ITaskService;
import org.springblade.desk.logistics.service.*;
import org.springblade.desk.logistics.utils.AgvTaskTypeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
@ -28,6 +28,9 @@ import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.springblade.desk.logistics.constant.AgvConstant.EQUIPMENT_TYPE_AGV;
import static org.springblade.desk.logistics.pojo.entity.Station.DROPOFF_CONVEYOR_LINE;
/**
* 物流AGV小车任务执行记录服务实现类
* <p>
@ -52,6 +55,18 @@ public class TaskExecuteRecordServiceImpl extends BaseServiceImpl<TaskExecuteRec
@Autowired
ILocationService locationService;
@Autowired
ITaskExecuteRecordService taskExecuteRecordService;
@Autowired
IStationService stationService;
@Autowired
IPipelineService iPipelineService;
@Autowired
AgvTaskTypeUtil agvTaskTypeUtil;
/**
* AGV小车任务状态回调接口
* <p>
@ -125,7 +140,10 @@ public class TaskExecuteRecordServiceImpl extends BaseServiceImpl<TaskExecuteRec
log.info("任务单号{}已完成,准备调用东哥接口", agvCallBack.getTaskCode());
//判断是否需要调用ctu接口
containerToEmpty(agvCallBack.getTaskCode());
containerToCtu(agvCallBack.getTaskCode());
//判断是否需要调用agv接口
containerToAgv(agvCallBack.getTaskCode());
}
// 回调处理成功
@ -260,7 +278,7 @@ public class TaskExecuteRecordServiceImpl extends BaseServiceImpl<TaskExecuteRec
}
@Override
public boolean containerToEmpty(String taskCode) {
public boolean containerToCtu(String taskCode) {
TaskExecuteRecord taskExecuteRecord = taskExecuteRecordMapper.selectByTaskCode(taskCode);
if(null == taskExecuteRecord){
@ -286,21 +304,23 @@ public class TaskExecuteRecordServiceImpl extends BaseServiceImpl<TaskExecuteRec
Location location = locationService.getById(task.getLocationId());
boolean ctuSchedulingTask = genCtuSchedulingTask
AgvSchedulingTaskVO ctuSchedulingTask = genCtuSchedulingTask
("CTu2", "1", task.getBoxBarcode(), taskExecuteRecord.getEndPos(), location.getLocationCode(), AgvConstant.EQUIPMENT_TYPE_CTU);
if(!ctuSchedulingTask){
if(null != ctuSchedulingTask){
task.setTaskStatus(Task.STATUS_LOCATION);
boolean taskUpdate = taskService.updateById(task);
if(!taskUpdate){
log.error("Task状态修改失败");
}
// 添加任务
boolean record = taskExecuteRecordService.inboundRecord(ctuSchedulingTask, task);
}
return true;
}
@Override
public boolean genCtuSchedulingTask(String taskTyp, String ctnrTyp, String ctnrCode,
public AgvSchedulingTaskVO genCtuSchedulingTask(String taskTyp, String ctnrTyp, String ctnrCode,
String startPos, String endPos, String type) {
// 接口地址
String url = "http://172.22.252.10:8181/rcms/services/rest/hikRpcService/genAgvSchedulingTask";
@ -346,7 +366,7 @@ public class TaskExecuteRecordServiceImpl extends BaseServiceImpl<TaskExecuteRec
if (!StringUtils.hasText(responseStr)) {
log.error("调用CTU调度任务接口失败,响应为空");
return false;
return new AgvSchedulingTaskVO();
}
// 解析响应
@ -358,19 +378,64 @@ public class TaskExecuteRecordServiceImpl extends BaseServiceImpl<TaskExecuteRec
if ("0".equals(code)) {
log.info("CTU调度任务创建成功,任务类型:{},任务单号:{},容器编号:{},起始位置:{},目标位置:{}",
taskTyp, taskCode, ctnrCode, startPos, endPos);
return true;
return AgvSchedulingTaskVO.success(taskCode,taskTyp,startPos,endPos,type);
} else {
// code不等于0,输出错误信息
log.error("CTU调度任务创建失败,错误码:{},错误信息:{},任务类型:{},容器编号:{},起始位置:{},目标位置:{}",
code, message, taskTyp, ctnrCode, startPos, endPos);
return false;
return AgvSchedulingTaskVO.fail(code,message);
}
} catch (Exception e) {
log.error("调用CTU调度任务接口异常,任务类型:{},容器编号:{},起始位置:{},目标位置:{}",
taskTyp, ctnrCode, startPos, endPos, e);
return new AgvSchedulingTaskVO();
}
}
@Override
public boolean containerToAgv(String taskCode) {
TaskExecuteRecord taskExecuteRecord = taskExecuteRecordMapper.selectByTaskCode(taskCode);
if(null == taskExecuteRecord){
log.error("未根据taskCode查询到有效数据,请求参数:{}", taskCode);
return false;
}
Task task = taskService.getById(taskExecuteRecord.getTaskId());
if(null == task){
log.error("查询不到Task数据,请求参数:{}", taskExecuteRecord.getTaskId());
return false;
}
String endPos = taskExecuteRecord.getEndPos();
Location location = locationService.selectByLocationCode(endPos,1);
if(null != location){
//拿到站点
Long stationId = task.getStationId();
if(null == stationId){
log.error("查询不到Task的站点数据,请求参数:{}", taskCode);
return false;
}
Station station = stationService.getById(task.getStationId());
if(null == station){
log.error("查询不到站点数据,请求参数:{}", task.getStationId());
return false;
}
//调用agv小车
// 调用AGV
String taskType = agvTaskTypeUtil.getTaskType(Integer.valueOf(station.getStationPosition()));
boolean agvResult = iPipelineService.genAgvSchedulingTask(
taskType, location.getLocationCode(),station.getStationCode() , EQUIPMENT_TYPE_AGV, task
);
return agvResult;
}
return false;
}
/**

Loading…
Cancel
Save