feat: 自动补空任务
This commit is contained in:
@@ -46,17 +46,19 @@ public interface PackagePointMapper extends BaseMapperX<PackagePointDO> {
|
||||
* 尝试锁定点位
|
||||
*
|
||||
* @param pointId 点位标识
|
||||
* @param pointStatus 预期点位状态
|
||||
* @return 更新行数
|
||||
*/
|
||||
int tryLockPoint(@Param("pointId") Long pointId);
|
||||
int tryLockPoint(@Param("pointId") Long pointId, @Param("pointStatus") String pointStatus);
|
||||
|
||||
/**
|
||||
* 释放点位锁
|
||||
*
|
||||
* @param pointId 点位标识
|
||||
* @param pointStatus 预期点位状态
|
||||
* @return 更新行数
|
||||
*/
|
||||
int unlockPoint(@Param("pointId") Long pointId);
|
||||
int unlockPoint(@Param("pointId") Long pointId, @Param("pointStatus") String pointStatus);
|
||||
|
||||
default PageResult<PackagePointDO> selectPage(PackagePointPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<PackagePointDO>()
|
||||
|
||||
@@ -44,6 +44,14 @@ public class BoxAutoJob {
|
||||
@XxlJob("autoSubRollDownCallEmptyJob")
|
||||
@TenantJob
|
||||
public void autoSubRollDownCallEmptyJob() {
|
||||
log.info("子卷下线补充空架子任务创建开始.....");
|
||||
XxlJobHelper.log("子卷下线补充空架子任务创建开始");
|
||||
|
||||
packageBoxBusinessService.autoSubRollDownCallEmpty();
|
||||
|
||||
String msg = "子卷下线补充空架子任务创建结束";
|
||||
XxlJobHelper.log(msg);
|
||||
XxlJobHelper.handleSuccess(msg);
|
||||
log.info(msg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,4 +11,9 @@ public interface PackageBoxBusinessService {
|
||||
* 自动创建子卷下线送待检区任务
|
||||
*/
|
||||
void autoSendSubRollTask();
|
||||
|
||||
/**
|
||||
* 自动创建子卷下线补充空架子任务
|
||||
*/
|
||||
void autoSubRollDownCallEmpty();
|
||||
}
|
||||
|
||||
@@ -33,6 +33,12 @@ public class PackageBoxBusinessServiceImpl implements PackageBoxBusinessService
|
||||
/** 子卷下线任务回调处理器编码 */
|
||||
private static final String SUB_ROLL_DOWN_HANDLE_CODE = "subRollDownAgvTask";
|
||||
|
||||
/** 子卷下线补充空架子业务类型 */
|
||||
private static final String SUB_ROLL_CALL_EMPTY_BIZ_TYPE = "SUB_ROLL_CALL_EMPTY";
|
||||
|
||||
/** 子卷下线补充空架子任务回调处理器编码 */
|
||||
private static final String SUB_ROLL_CALL_EMPTY_HANDLE_CODE = "subRollCallEmptyAgvTask";
|
||||
|
||||
/**
|
||||
* ACS 搬运任务类型
|
||||
*/
|
||||
@@ -66,13 +72,13 @@ public class PackageBoxBusinessServiceImpl implements PackageBoxBusinessService
|
||||
|
||||
Iterator<PackagePointDO> destinationIterator = destinationPointList.iterator();
|
||||
for (PackagePointDO sourcePoint : sourcePointList) {
|
||||
if (packagePointMapper.tryLockPoint(sourcePoint.getPointId()) == 0) {
|
||||
if (packagePointMapper.tryLockPoint(sourcePoint.getPointId(), sourcePoint.getPointStatus()) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PackagePointDO destinationPoint = lockNextDestinationPoint(destinationIterator);
|
||||
if (destinationPoint == null) {
|
||||
packagePointMapper.unlockPoint(sourcePoint.getPointId());
|
||||
packagePointMapper.unlockPoint(sourcePoint.getPointId(), sourcePoint.getPointStatus());
|
||||
log.info("没有可用的待检区点位,结束本轮任务创建");
|
||||
break;
|
||||
}
|
||||
@@ -83,6 +89,47 @@ public class PackageBoxBusinessServiceImpl implements PackageBoxBusinessService
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 自动创建子卷下线补充空架子任务
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void autoSubRollDownCallEmpty() {
|
||||
List<PackagePointDO> offlineEmptyPointList = packagePointMapper.selectAvailablePointList(
|
||||
BoxPointTypeEnum.OFFLINE_POINT.getCode(), BoxPointStatusEnum.EMPTY.getCode());
|
||||
List<PackagePointDO> packingEmptyContainerPointList = packagePointMapper.selectAvailablePointList(
|
||||
BoxPointTypeEnum.PACKING_POINT.getCode(), BoxPointStatusEnum.EMPTY_CONTAINER.getCode());
|
||||
List<PackagePointDO> inspectionEmptyContainerPointList = packagePointMapper.selectAvailablePointList(
|
||||
BoxPointTypeEnum.INSPECTION_PENDING_POINT.getCode(), BoxPointStatusEnum.EMPTY_CONTAINER.getCode());
|
||||
List<PackagePointDO> inspectionEmptyPointList = packagePointMapper.selectAvailablePointList(
|
||||
BoxPointTypeEnum.INSPECTION_PENDING_POINT.getCode(), BoxPointStatusEnum.EMPTY.getCode());
|
||||
|
||||
Iterator<PackagePointDO> packingSourceIterator = packingEmptyContainerPointList.iterator();
|
||||
Iterator<PackagePointDO> inspectionSourceIterator = inspectionEmptyContainerPointList.iterator();
|
||||
for (PackagePointDO offlineDestinationPoint : offlineEmptyPointList) {
|
||||
if (packagePointMapper.tryLockPoint(
|
||||
offlineDestinationPoint.getPointId(), offlineDestinationPoint.getPointStatus()) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PackagePointDO sourcePoint = lockNextSourcePoint(packingSourceIterator);
|
||||
if (sourcePoint == null) {
|
||||
sourcePoint = lockNextSourcePoint(inspectionSourceIterator);
|
||||
}
|
||||
if (sourcePoint == null) {
|
||||
packagePointMapper.unlockPoint(
|
||||
offlineDestinationPoint.getPointId(), offlineDestinationPoint.getPointStatus());
|
||||
break;
|
||||
}
|
||||
|
||||
Long taskId = createCallEmptyTransportTask(sourcePoint, offlineDestinationPoint);
|
||||
log.info("子卷下线补充空架子任务创建成功,任务标识={},起点编码={},目的点编码={}",
|
||||
taskId, sourcePoint.getPointCode(), offlineDestinationPoint.getPointCode());
|
||||
}
|
||||
|
||||
createPackingToInspectionTask(packingSourceIterator, inspectionEmptyPointList.iterator());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建子卷下线送待检区运输任务
|
||||
*
|
||||
@@ -110,6 +157,75 @@ public class PackageBoxBusinessServiceImpl implements PackageBoxBusinessService
|
||||
return transportTaskApi.createTransportTask(task).getCheckedData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建子卷下线补充空架子运输任务
|
||||
*
|
||||
* @param sourcePoint 起点
|
||||
* @param destinationPoint 目的点
|
||||
* @return 运输任务标识
|
||||
*/
|
||||
private Long createCallEmptyTransportTask(PackagePointDO sourcePoint, PackagePointDO destinationPoint) {
|
||||
TransportTaskCreateReqDTO task = new TransportTaskCreateReqDTO();
|
||||
task.setTaskName("子卷下线补充空架子任务");
|
||||
task.setOwnerService(TaskOwnerServiceEnum.LMS.name());
|
||||
task.setBizType(SUB_ROLL_CALL_EMPTY_BIZ_TYPE);
|
||||
task.setBizId(sourcePoint.getVehicleCode());
|
||||
task.setTaskType(PackageTaskTypeEnum.SUB_ROLL_CALL_EMPTY_AGV.getCode());
|
||||
task.setHandleCode(SUB_ROLL_CALL_EMPTY_HANDLE_CODE);
|
||||
task.setAcsTaskType(ACS_MOVE_TASK_TYPE);
|
||||
task.setAgvSystemType(AGV_SYSTEM_TYPE);
|
||||
task.setPointCode1(sourcePoint.getPointCode());
|
||||
task.setPointCode2(destinationPoint.getPointCode());
|
||||
task.setVehicleCode(sourcePoint.getVehicleCode());
|
||||
task.setProductArea(sourcePoint.getProductArea());
|
||||
task.setIsAutoIssue("1");
|
||||
task.setIsCreateFinish(true);
|
||||
return transportTaskApi.createTransportTask(task).getCheckedData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将剩余装箱点空架子转运到待检点空位
|
||||
*
|
||||
* @param sourceIterator 装箱点空架子候选迭代器
|
||||
* @param destinationIterator 待检点空位候选迭代器
|
||||
*/
|
||||
private void createPackingToInspectionTask(Iterator<PackagePointDO> sourceIterator,
|
||||
Iterator<PackagePointDO> destinationIterator) {
|
||||
while (destinationIterator.hasNext()) {
|
||||
PackagePointDO destinationPoint = destinationIterator.next();
|
||||
if (packagePointMapper.tryLockPoint(
|
||||
destinationPoint.getPointId(), destinationPoint.getPointStatus()) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PackagePointDO sourcePoint = lockNextSourcePoint(sourceIterator);
|
||||
if (sourcePoint == null) {
|
||||
packagePointMapper.unlockPoint(destinationPoint.getPointId(), destinationPoint.getPointStatus());
|
||||
break;
|
||||
}
|
||||
|
||||
Long taskId = createCallEmptyTransportTask(sourcePoint, destinationPoint);
|
||||
log.info("装箱点空架子送待检点任务创建成功,任务标识={},起点编码={},目的点编码={}",
|
||||
taskId, sourcePoint.getPointCode(), destinationPoint.getPointCode());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 从候选点位中锁定下一个可用的空架子起点
|
||||
*
|
||||
* @param sourceIterator 空架子起点候选迭代器
|
||||
* @return 成功锁定的起点,没有可用点位时返回 null
|
||||
*/
|
||||
private PackagePointDO lockNextSourcePoint(Iterator<PackagePointDO> sourceIterator) {
|
||||
while (sourceIterator.hasNext()) {
|
||||
PackagePointDO sourcePoint = sourceIterator.next();
|
||||
if (packagePointMapper.tryLockPoint(sourcePoint.getPointId(), sourcePoint.getPointStatus()) > 0) {
|
||||
return sourcePoint;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 从候选点位中锁定下一个可用的待检区点位
|
||||
*
|
||||
@@ -119,7 +235,8 @@ public class PackageBoxBusinessServiceImpl implements PackageBoxBusinessService
|
||||
private PackagePointDO lockNextDestinationPoint(Iterator<PackagePointDO> destinationIterator) {
|
||||
while (destinationIterator.hasNext()) {
|
||||
PackagePointDO destinationPoint = destinationIterator.next();
|
||||
if (packagePointMapper.tryLockPoint(destinationPoint.getPointId()) > 0) {
|
||||
if (packagePointMapper.tryLockPoint(
|
||||
destinationPoint.getPointId(), destinationPoint.getPointStatus()) > 0) {
|
||||
return destinationPoint;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
package cn.code.nl.module.lms.tasks.box;
|
||||
|
||||
import cn.code.nl.framework.execute.core.AbstractTask;
|
||||
import cn.code.nl.framework.execute.core.dto.TaskExecuteDTO;
|
||||
import cn.code.nl.module.lms.dal.dataobject.packagepoint.PackagePointDO;
|
||||
import cn.code.nl.module.lms.dal.mysql.packagepoint.PackagePointMapper;
|
||||
import cn.code.nl.module.lms.enums.BoxPointStatusEnum;
|
||||
import cn.code.nl.module.task.api.TransportTaskApi;
|
||||
import cn.code.nl.module.task.dto.TaskInfoDTO;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 子卷下线补充空架子 AGV 任务
|
||||
*
|
||||
* @Author: liyongde
|
||||
* @Date: 2026/8/13
|
||||
*/
|
||||
@Slf4j
|
||||
@Component("subRollCallEmptyAgvTask")
|
||||
public class SubRollCallEmptyAgvTask extends AbstractTask {
|
||||
|
||||
/** 运输任务接口 */
|
||||
@Resource
|
||||
private TransportTaskApi transportTaskApi;
|
||||
|
||||
/** 装箱点位 Mapper */
|
||||
@Resource
|
||||
private PackagePointMapper packagePointMapper;
|
||||
|
||||
/**
|
||||
* 任务完成后将目的点更新为空载具
|
||||
*
|
||||
* @param taskExecuteDTO 任务执行信息
|
||||
*/
|
||||
@Override
|
||||
public void doHandleFinish(TaskExecuteDTO taskExecuteDTO) {
|
||||
TaskInfoDTO taskInfoDTO = transportTaskApi.getTaskById(taskExecuteDTO.getTaskId()).getCheckedData();
|
||||
PackagePointDO endPoint = packagePointMapper.selectByPointCode(taskInfoDTO.getPointCode2(), false);
|
||||
PackagePointDO updatePoint = new PackagePointDO();
|
||||
updatePoint.setPointId(endPoint.getPointId());
|
||||
updatePoint.setVehicleCode(taskInfoDTO.getVehicleCode());
|
||||
updatePoint.setContainerName("");
|
||||
updatePoint.setPointStatus(BoxPointStatusEnum.EMPTY_CONTAINER.getCode());
|
||||
updatePoint.setLockStatus("0");
|
||||
packagePointMapper.updateById(updatePoint);
|
||||
log.info("任务{}执行完成,空架子已存入点位{}", taskExecuteDTO.getTaskId(), taskInfoDTO.getPointCode2());
|
||||
}
|
||||
|
||||
/**
|
||||
* 任务取消后解锁起点和目的点
|
||||
*
|
||||
* @param taskExecuteDTO 任务执行信息
|
||||
*/
|
||||
@Override
|
||||
public void doHandleCancel(TaskExecuteDTO taskExecuteDTO) {
|
||||
TaskInfoDTO taskInfoDTO = transportTaskApi.getTaskById(taskExecuteDTO.getTaskId()).getCheckedData();
|
||||
PackagePointDO startPoint = packagePointMapper.selectByPointCode(taskInfoDTO.getPointCode1(), false);
|
||||
PackagePointDO endPoint = packagePointMapper.selectByPointCode(taskInfoDTO.getPointCode2(), false);
|
||||
PackagePointDO updateStartPoint = new PackagePointDO();
|
||||
updateStartPoint.setPointId(startPoint.getPointId());
|
||||
updateStartPoint.setLockStatus("0");
|
||||
PackagePointDO updateEndPoint = new PackagePointDO();
|
||||
updateEndPoint.setPointId(endPoint.getPointId());
|
||||
updateEndPoint.setLockStatus("0");
|
||||
packagePointMapper.updateBatch(List.of(updateStartPoint, updateEndPoint));
|
||||
log.info("任务{}已取消,起点{}和目的点{}已解锁", taskExecuteDTO.getTaskId(),
|
||||
taskInfoDTO.getPointCode1(), taskInfoDTO.getPointCode2());
|
||||
}
|
||||
|
||||
/**
|
||||
* 取货完成后将起点更新为空位
|
||||
*
|
||||
* @param taskExecuteDTO 任务执行信息
|
||||
*/
|
||||
@Override
|
||||
public void doHandlePicked(TaskExecuteDTO taskExecuteDTO) {
|
||||
TaskInfoDTO taskInfoDTO = transportTaskApi.getTaskById(taskExecuteDTO.getTaskId()).getCheckedData();
|
||||
PackagePointDO startPoint = packagePointMapper.selectByPointCode(taskInfoDTO.getPointCode1(), false);
|
||||
PackagePointDO updatePoint = new PackagePointDO();
|
||||
updatePoint.setPointId(startPoint.getPointId());
|
||||
updatePoint.setLockStatus("0");
|
||||
updatePoint.setPointStatus(BoxPointStatusEnum.EMPTY.getCode());
|
||||
updatePoint.setVehicleCode("");
|
||||
updatePoint.setContainerName("");
|
||||
packagePointMapper.updateById(updatePoint);
|
||||
log.info("任务{}执行取货完成,点位{}已释放", taskExecuteDTO.getTaskId(), taskInfoDTO.getPointCode1());
|
||||
}
|
||||
}
|
||||
@@ -16,16 +16,22 @@
|
||||
|
||||
<update id="tryLockPoint">
|
||||
UPDATE lms_package_point
|
||||
SET lock_status = '1'
|
||||
SET lock_status = '1',
|
||||
updater = '0',
|
||||
update_time = CURRENT_TIMESTAMP
|
||||
WHERE point_id = #{pointId}
|
||||
AND point_status = #{pointStatus}
|
||||
AND lock_status = '0'
|
||||
AND deleted = b'0'
|
||||
</update>
|
||||
|
||||
<update id="unlockPoint">
|
||||
UPDATE lms_package_point
|
||||
SET lock_status = '0'
|
||||
SET lock_status = '0',
|
||||
updater = '0',
|
||||
update_time = CURRENT_TIMESTAMP
|
||||
WHERE point_id = #{pointId}
|
||||
AND point_status = #{pointStatus}
|
||||
AND lock_status = '1'
|
||||
AND deleted = b'0'
|
||||
</update>
|
||||
|
||||
Reference in New Issue
Block a user