no message
parent
c0b11a68eb
commit
a0623c4b3d
|
|
@ -3,23 +3,14 @@ package org.cpte.modules.quartz.job;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.collections4.CollectionUtils;
|
import org.apache.commons.collections4.CollectionUtils;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.cpte.modules.agvTask.mapper.AgvTaskMapper;
|
|
||||||
import org.cpte.modules.agvTask.vo.ConNoAgv;
|
|
||||||
import org.cpte.modules.constant.enums.PickStatusEnum;
|
|
||||||
import org.cpte.modules.constant.enums.PickTypeEnum;
|
|
||||||
import org.cpte.modules.shipping.entity.Pick;
|
|
||||||
import org.cpte.modules.shipping.entity.PickDetail;
|
import org.cpte.modules.shipping.entity.PickDetail;
|
||||||
import org.cpte.modules.shipping.mapper.PickDetailMapper;
|
import org.cpte.modules.shipping.mapper.PickDetailMapper;
|
||||||
import org.cpte.modules.shipping.service.IPickDetailService;
|
|
||||||
import org.cpte.modules.shipping.service.IPickService;
|
import org.cpte.modules.shipping.service.IPickService;
|
||||||
import org.cpte.modules.shipping.vo.AllocationPickDetailData;
|
|
||||||
import org.cpte.modules.utils.RedisDistributedLockUtil;
|
import org.cpte.modules.utils.RedisDistributedLockUtil;
|
||||||
import org.quartz.Job;
|
import org.quartz.Job;
|
||||||
import org.quartz.JobExecutionContext;
|
import org.quartz.JobExecutionContext;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -27,8 +18,6 @@ import java.util.stream.Collectors;
|
||||||
*/
|
*/
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public class AllocatePickDetailJob implements Job {
|
public class AllocatePickDetailJob implements Job {
|
||||||
@Autowired
|
|
||||||
private AgvTaskMapper agvTaskMapper;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private PickDetailMapper pickDetailMapper;
|
private PickDetailMapper pickDetailMapper;
|
||||||
|
|
@ -36,15 +25,13 @@ public class AllocatePickDetailJob implements Job {
|
||||||
@Autowired
|
@Autowired
|
||||||
private IPickService pickService;
|
private IPickService pickService;
|
||||||
|
|
||||||
@Autowired
|
|
||||||
private IPickDetailService pickDetailService;
|
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private RedisDistributedLockUtil redissonLock;
|
private RedisDistributedLockUtil redissonLock;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute(JobExecutionContext jobExecutionContext) {
|
public void execute(JobExecutionContext jobExecutionContext) {
|
||||||
String lockKey = "lock:allocation";
|
|
||||||
|
String lockKey = "lock:allocate";
|
||||||
String lockValue = null;
|
String lockValue = null;
|
||||||
try {
|
try {
|
||||||
lockValue = redissonLock.tryLock(lockKey, 10);
|
lockValue = redissonLock.tryLock(lockKey, 10);
|
||||||
|
|
@ -57,14 +44,7 @@ public class AllocatePickDetailJob implements Job {
|
||||||
log.info("没有待分配的出库明细");
|
log.info("没有待分配的出库明细");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
//1.数据准备
|
allocate(pickDetails);
|
||||||
AllocationPickDetailData data = prepareData(pickDetails);
|
|
||||||
|
|
||||||
// 处理成品、配件类型的出库单
|
|
||||||
processCpPjTypePicks(data.getCpPjPickIds(), data.getPickDetailMap(), data.getPickMap());
|
|
||||||
|
|
||||||
// 处理其他类型的出库单
|
|
||||||
processOtherTypePicks(data.getOtherPickIds(), data.getPickDetailMap(), data.getPickMap());
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
log.error("分配明细异常", e);
|
log.error("分配明细异常", e);
|
||||||
throw e;
|
throw e;
|
||||||
|
|
@ -73,166 +53,10 @@ public class AllocatePickDetailJob implements Job {
|
||||||
redissonLock.unlock(lockKey, lockValue);
|
redissonLock.unlock(lockKey, lockValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private void allocate(List<PickDetail> pickDetails) {
|
||||||
* 数据准备
|
for (PickDetail detail : pickDetails) {
|
||||||
*/
|
|
||||||
private AllocationPickDetailData prepareData(List<PickDetail> pickDetailList) {
|
|
||||||
|
|
||||||
//根据出库单ID进行分组
|
|
||||||
Map<Long, List<PickDetail>> pickDetailMap = pickDetailList.stream().collect(Collectors.groupingBy(PickDetail::getPickId));
|
|
||||||
|
|
||||||
// 获取所有出库单信息
|
|
||||||
List<Long> pickIds = new ArrayList<>(pickDetailMap.keySet());
|
|
||||||
Map<Long, Pick> pickMap = pickDetailService.queryByPickIdsToMap(pickIds);
|
|
||||||
|
|
||||||
|
|
||||||
// 成品、配件类型/其他类型
|
|
||||||
List<Long> cpPjPickIds = new ArrayList<>();
|
|
||||||
List<Long> otherPickIds = new ArrayList<>();
|
|
||||||
|
|
||||||
for (Long pickId : pickIds) {
|
|
||||||
Pick pick = pickMap.get(pickId);
|
|
||||||
if (isCPOrPJType(pick.getOrderType())) {
|
|
||||||
cpPjPickIds.add(pickId);
|
|
||||||
} else {
|
|
||||||
otherPickIds.add(pickId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return new AllocationPickDetailData(cpPjPickIds, otherPickIds, pickDetailMap, pickMap);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理成品/配件类型的出库单
|
|
||||||
*/
|
|
||||||
private void processCpPjTypePicks(List<Long> cpPjPickIds, Map<Long, List<PickDetail>> pickDetailMap, Map<Long, Pick> pickMap) {
|
|
||||||
if (CollectionUtils.isEmpty(cpPjPickIds)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1. 获取当前系统中所有正在执行的AGV任务
|
|
||||||
List<ConNoAgv> executeAgv= agvTaskMapper.queryIsExecuteAgvTask();
|
|
||||||
Set<String> executeAgvKeys = buildExecuteAgvKey(executeAgv);
|
|
||||||
|
|
||||||
//2.处理明细
|
|
||||||
processPickDetails(cpPjPickIds, pickDetailMap, pickMap, executeAgvKeys);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建正在执行任务的键集合
|
|
||||||
*/
|
|
||||||
private Set<String> buildExecuteAgvKey(List<ConNoAgv> executeAgv) {
|
|
||||||
if (CollectionUtils.isEmpty(executeAgv)) {
|
|
||||||
return Collections.emptySet();
|
|
||||||
}
|
|
||||||
|
|
||||||
Set<String> taskKeys = new HashSet<>(executeAgv.size());
|
|
||||||
for (ConNoAgv agv : executeAgv) {
|
|
||||||
String key = buildAgvKey(agv.getConNo(), agv.getItemId());
|
|
||||||
taskKeys.add(key);
|
|
||||||
}
|
|
||||||
return taskKeys;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 构建AGV唯一键
|
|
||||||
*/
|
|
||||||
private String buildAgvKey(String conNo, Long itemId) {
|
|
||||||
return conNo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理拣货明细
|
|
||||||
*/
|
|
||||||
private void processPickDetails(List<Long> cpPjPickIds,
|
|
||||||
Map<Long, List<PickDetail>> pickDetailMap,
|
|
||||||
Map<Long, Pick> pickMap,
|
|
||||||
Set<String> executingTaskKeys) {
|
|
||||||
for (Long pickId : cpPjPickIds) {
|
|
||||||
Pick pick = pickMap.get(pickId);
|
|
||||||
if (pick == null) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
List<PickDetail> details = pickDetailMap.get(pickId);
|
|
||||||
if (CollectionUtils.isEmpty(details)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
boolean allocated = processSinglePickDetails(pick, details, executingTaskKeys);
|
|
||||||
if (allocated) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理单个pick的明细
|
|
||||||
* @return 是否成功分配
|
|
||||||
*/
|
|
||||||
private boolean processSinglePickDetails(Pick pick,
|
|
||||||
List<PickDetail> details,
|
|
||||||
Set<String> executingTaskKeys) {
|
|
||||||
for (PickDetail detail : details) {
|
|
||||||
// 跳过已分配的任务
|
|
||||||
if (isAlreadyAssigned(detail.getStatus())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 构建当前任务的唯一键
|
|
||||||
String currentKey = buildAgvKey(pick.getConNo(), detail.getItemId());
|
|
||||||
|
|
||||||
// 检查是否需要分配
|
|
||||||
if (shouldAllocatePickDetail(executingTaskKeys, currentKey)) {
|
|
||||||
boolean allocated = allocatePickDetail(detail);
|
|
||||||
if (allocated) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false; // 未分配任何明细
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 判断是否需要分配拣货明细
|
|
||||||
*/
|
|
||||||
private boolean shouldAllocatePickDetail(Set<String> executingTaskKeys, String currentKey) {
|
|
||||||
// 如果没有正在执行的任务,直接分配
|
|
||||||
if (CollectionUtils.isEmpty(executingTaskKeys)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果有正在执行的任务,且当前任务已存在,则分配
|
|
||||||
return executingTaskKeys.contains(currentKey);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 处理其他类型的出库单
|
|
||||||
*/
|
|
||||||
private void processOtherTypePicks(List<Long> otherPickIds, Map<Long, List<PickDetail>> pickDetailMap, Map<Long, Pick> pickMap) {
|
|
||||||
if (CollectionUtils.isEmpty(otherPickIds)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
for (Long pickId : otherPickIds) {
|
|
||||||
List<PickDetail> details = pickDetailMap.get(pickId);
|
|
||||||
if (CollectionUtils.isEmpty(details)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
allocateOtherPick(details);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 分配单个其他类型出库单的所有明细
|
|
||||||
*/
|
|
||||||
private void allocateOtherPick(List<PickDetail> details) {
|
|
||||||
for (PickDetail detail : details) {
|
|
||||||
// 如果已分配,跳过
|
|
||||||
if (isAlreadyAssigned(detail.getStatus())) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
boolean allocated = allocatePickDetail(detail);
|
boolean allocated = allocatePickDetail(detail);
|
||||||
if (allocated) {
|
if (allocated) {
|
||||||
return;
|
return;
|
||||||
|
|
@ -240,16 +64,6 @@ public class AllocatePickDetailJob implements Job {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 辅助方法
|
|
||||||
private boolean isCPOrPJType(Integer orderType) {
|
|
||||||
return PickTypeEnum.CP.getValue().equals(orderType)
|
|
||||||
|| PickTypeEnum.PJ.getValue().equals(orderType);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean isAlreadyAssigned(Integer status) {
|
|
||||||
return PickStatusEnum.ASSIGNED.getValue().equals(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean allocatePickDetail(PickDetail pickDetail) {
|
private boolean allocatePickDetail(PickDetail pickDetail) {
|
||||||
try {
|
try {
|
||||||
return pickService.allocatePickDetail(pickDetail);
|
return pickService.allocatePickDetail(pickDetail);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue