|
|
@ -1,8 +1,16 @@ |
|
|
package com.gaotao.modules.automatedWarehouse.task; |
|
|
package com.gaotao.modules.automatedWarehouse.task; |
|
|
|
|
|
|
|
|
import com.gaotao.common.utils.AgvClientUtil; |
|
|
import com.gaotao.common.utils.AgvClientUtil; |
|
|
|
|
|
import com.gaotao.modules.api.entity.WareHouseTransferRequest; |
|
|
|
|
|
import com.gaotao.modules.api.service.AgvMessageService; |
|
|
|
|
|
import com.gaotao.modules.api.service.WmsMessageService; |
|
|
|
|
|
import com.gaotao.modules.automatedWarehouse.entity.PalletDetailData; |
|
|
import com.gaotao.modules.automatedWarehouse.entity.WmsTransportTask; |
|
|
import com.gaotao.modules.automatedWarehouse.entity.WmsTransportTask; |
|
|
|
|
|
import com.gaotao.modules.automatedWarehouse.entity.WmsTransportTaskDetail; |
|
|
|
|
|
import com.gaotao.modules.automatedWarehouse.mapper.WcsIntegrationMapper; |
|
|
import com.gaotao.modules.automatedWarehouse.service.AgvTaskService; |
|
|
import com.gaotao.modules.automatedWarehouse.service.AgvTaskService; |
|
|
|
|
|
import com.gaotao.modules.warehouse.entity.Pallet; |
|
|
|
|
|
import com.gaotao.modules.warehouse.service.PalletService; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
import lombok.extern.slf4j.Slf4j; |
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
import org.springframework.beans.factory.annotation.Autowired; |
|
|
import org.springframework.scheduling.annotation.Scheduled; |
|
|
import org.springframework.scheduling.annotation.Scheduled; |
|
|
@ -11,6 +19,7 @@ import org.springframework.stereotype.Component; |
|
|
import java.util.Arrays; |
|
|
import java.util.Arrays; |
|
|
import java.util.Date; |
|
|
import java.util.Date; |
|
|
import java.util.List; |
|
|
import java.util.List; |
|
|
|
|
|
import java.util.Map; |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* AGV任务优先级调度定时任务 |
|
|
* AGV任务优先级调度定时任务 |
|
|
@ -22,14 +31,17 @@ public class AgvTaskScheduler { |
|
|
|
|
|
|
|
|
@Autowired |
|
|
@Autowired |
|
|
private AgvTaskService agvTaskService; |
|
|
private AgvTaskService agvTaskService; |
|
|
|
|
|
|
|
|
|
|
|
@Autowired |
|
|
|
|
|
private PalletService palletService; |
|
|
@Autowired |
|
|
@Autowired |
|
|
private AgvClientUtil agvClientUtil; |
|
|
private AgvClientUtil agvClientUtil; |
|
|
|
|
|
|
|
|
|
|
|
@Autowired |
|
|
|
|
|
private WcsIntegrationMapper wcsIntegrationMapper; |
|
|
|
|
|
@Autowired |
|
|
|
|
|
private WmsMessageService wmsMessageService; |
|
|
/** |
|
|
/** |
|
|
* 定时任务:每分钟执行一次AGV任务优先级调度 |
|
|
* 定时任务:每分钟执行一次AGV任务优先级调度 |
|
|
* cron表达式:0 * * * * ? 表示每分钟的第0秒执行 |
|
|
* cron表达式:0 * * * * ? 表示每分钟的第0秒执行 |
|
|
* |
|
|
|
|
|
* 调度策略: |
|
|
* 调度策略: |
|
|
* - 如果执行中任务数 >= 10,则不下发新任务 |
|
|
* - 如果执行中任务数 >= 10,则不下发新任务 |
|
|
* - 如果执行中任务数 < 10,则下发多个优先级高的任务,但总数不超过10 |
|
|
* - 如果执行中任务数 < 10,则下发多个优先级高的任务,但总数不超过10 |
|
|
@ -100,6 +112,54 @@ public class AgvTaskScheduler { |
|
|
log.info("=== AGV任务优先级调度定时任务执行完成 ==="); |
|
|
log.info("=== AGV任务优先级调度定时任务执行完成 ==="); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
@Scheduled(cron = "0 * * * * ?") |
|
|
|
|
|
public void scheduleDOFeedback() { |
|
|
|
|
|
log.info("=== 开始处理AGV回调相关业务 ==="); |
|
|
|
|
|
//1.查出wms_transport_task_detail中 status为已录入的数据 |
|
|
|
|
|
List<WmsTransportTaskDetail> list = wcsIntegrationMapper.getTransportTaskDetailListWithStatus("55"); |
|
|
|
|
|
for (int i = 0; i < list.size(); i++) { |
|
|
|
|
|
WmsTransportTaskDetail inData = list.get(i); |
|
|
|
|
|
try { |
|
|
|
|
|
WmsTransportTask checkTask= wcsIntegrationMapper.getTransportTaskByTaskNo(inData.getTaskNo()); |
|
|
|
|
|
if(checkTask==null){ |
|
|
|
|
|
throw new RuntimeException("运输任务不存在"); |
|
|
|
|
|
} |
|
|
|
|
|
if("送货完成".equals(inData.getStatus())){ |
|
|
|
|
|
// 5. 更新栈板calling_flag为N |
|
|
|
|
|
String username = "AGV_SYSTEM"; |
|
|
|
|
|
wcsIntegrationMapper.updatePalletCallingFlag(inData.getSite(), checkTask.getPalletId(), "N", username); |
|
|
|
|
|
log.info("栈板{}的calling_flag已更新为N", checkTask.getPalletId()); |
|
|
|
|
|
|
|
|
|
|
|
// 6. 更新运输任务状态为已完成 |
|
|
|
|
|
wcsIntegrationMapper.updateTransportTaskStatusByTaskNo(inData.getTaskNo(), "已完成"); |
|
|
|
|
|
log.info("运输任务{}状态已更新为已完成", inData.getTaskNo()); |
|
|
|
|
|
|
|
|
|
|
|
// 7. 检查栈板是否有明细,如果有则执行移库操作 |
|
|
|
|
|
List<PalletDetailData> palletDetails = wcsIntegrationMapper.getPalletDetailsData(inData.getSite(), checkTask.getPalletId()); |
|
|
|
|
|
if (palletDetails != null && !palletDetails.isEmpty()) { |
|
|
|
|
|
log.info("栈板{}存在明细,开始执行移库操作", checkTask.getPalletId()); |
|
|
|
|
|
executeWarehouseTransfer(checkTask); |
|
|
|
|
|
} else { |
|
|
|
|
|
log.info("栈板{}无明细,跳过移库操作,但需要更新栈板位置", checkTask.getPalletId()); |
|
|
|
|
|
// 即使没有明细,也要更新栈板位置到目标站点 |
|
|
|
|
|
updatePalletLocationOnly(checkTask, username); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
wcsIntegrationMapper.updateTransportTaskDetailStatusForId(inData.getId(),"已完成"); |
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
log.error("处理AGV回调数据失败:error={}", e.getMessage()); |
|
|
|
|
|
wcsIntegrationMapper.updateTransportTaskDetailStatusForId(inData.getId(),"回调处理失败"); |
|
|
|
|
|
// 继续处理下一个数据 |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//2 循环执行 每次执行trycatch 防止中间报错后续数据无法处理,如果报错, 则跳过该数据 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
/** |
|
|
/** |
|
|
* 将任务下发到AGV系统 |
|
|
* 将任务下发到AGV系统 |
|
|
* @param task 运输任务 |
|
|
* @param task 运输任务 |
|
|
@ -133,4 +193,80 @@ public class AgvTaskScheduler { |
|
|
log.info("手动触发AGV任务优先级调度"); |
|
|
log.info("手动触发AGV任务优先级调度"); |
|
|
scheduleAgvTaskByPriority(); |
|
|
scheduleAgvTaskByPriority(); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private void executeWarehouseTransfer(WmsTransportTask transportTask) { |
|
|
|
|
|
try { |
|
|
|
|
|
// 获取起始站点和目标站点信息 |
|
|
|
|
|
Map<String, Object> fromStationInfo = getStationInfo(transportTask.getFromLocation()); |
|
|
|
|
|
Map<String, Object> toStationInfo = getStationInfo(transportTask.getToLocation()); |
|
|
|
|
|
|
|
|
|
|
|
// 检查站点的仓库和库位是否不同 |
|
|
|
|
|
String fromWarehouseId = (String) fromStationInfo.get("warehouseCode"); |
|
|
|
|
|
String fromLocationId = (String) fromStationInfo.get("locationCode"); |
|
|
|
|
|
String toWarehouseId = (String) toStationInfo.get("warehouseCode"); |
|
|
|
|
|
String toLocationId = (String) toStationInfo.get("locationCode"); |
|
|
|
|
|
|
|
|
|
|
|
if (!fromWarehouseId.equals(toWarehouseId) || !fromLocationId.equals(toLocationId)) { |
|
|
|
|
|
log.info("站点仓库或库位不同,执行移库操作:从 {}-{} 到 {}-{}", |
|
|
|
|
|
fromWarehouseId, fromLocationId, toWarehouseId, toLocationId); |
|
|
|
|
|
|
|
|
|
|
|
// 构建移库请求 |
|
|
|
|
|
WareHouseTransferRequest transferRequest = new WareHouseTransferRequest(); |
|
|
|
|
|
transferRequest.setSite(transportTask.getSite()); |
|
|
|
|
|
transferRequest.setTransType("移库"); |
|
|
|
|
|
transferRequest.setPalletId(transportTask.getPalletId()); |
|
|
|
|
|
transferRequest.setToWarehouseId(toWarehouseId); |
|
|
|
|
|
transferRequest.setToLocationId(toLocationId); |
|
|
|
|
|
transferRequest.setBusinessType("AGV移库"); |
|
|
|
|
|
transferRequest.setRemark("AGV任务完成自动移库"); |
|
|
|
|
|
transferRequest.setToStation(transportTask.getToLocation()); |
|
|
|
|
|
// 调用移库方法 |
|
|
|
|
|
wmsMessageService.doWareHouseForPallet(transferRequest); |
|
|
|
|
|
log.info("移库操作执行成功"); |
|
|
|
|
|
} else { |
|
|
|
|
|
log.info("站点仓库和库位相同,无需执行移库操作"); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
log.error("移库操作执行失败:{}", e.getMessage(), e); |
|
|
|
|
|
throw new RuntimeException("移库操作失败:" + e.getMessage()); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
private Map<String, Object> getStationInfo(String stationCode) { |
|
|
|
|
|
Map<String, Object> stationInfo = wcsIntegrationMapper.getStationInfoByCode(stationCode); |
|
|
|
|
|
if (stationInfo == null) { |
|
|
|
|
|
throw new RuntimeException("未找到站点信息:" + stationCode); |
|
|
|
|
|
} |
|
|
|
|
|
return stationInfo; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
|
* 仅更新栈板位置(复用现有Pallet service逻辑) |
|
|
|
|
|
*/ |
|
|
|
|
|
private void updatePalletLocationOnly(WmsTransportTask transportTask, String username) { |
|
|
|
|
|
try { |
|
|
|
|
|
// 查询当前栈板信息 |
|
|
|
|
|
Pallet pallet = palletService.lambdaQuery() |
|
|
|
|
|
.eq(Pallet::getSite, transportTask.getSite()) |
|
|
|
|
|
.eq(Pallet::getPalletId, transportTask.getPalletId()) |
|
|
|
|
|
.one(); |
|
|
|
|
|
|
|
|
|
|
|
if (pallet == null) { |
|
|
|
|
|
throw new RuntimeException("栈板不存在:" + transportTask.getPalletId()); |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 更新栈板位置信息(复用doWareHouseForPallet中的逻辑) |
|
|
|
|
|
pallet.setLocationCode(transportTask.getToLocation()); |
|
|
|
|
|
palletService.updateById(pallet); |
|
|
|
|
|
|
|
|
|
|
|
log.info("栈板{}位置已更新到目标站点{}", transportTask.getPalletId(), transportTask.getToLocation()); |
|
|
|
|
|
|
|
|
|
|
|
} catch (Exception e) { |
|
|
|
|
|
log.error("更新栈板位置失败:{}", e.getMessage(), e); |
|
|
|
|
|
throw new RuntimeException("更新栈板位置失败:" + e.getMessage()); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
} |
|
|
} |