fix: 子卷下线区送满卷任务
This commit is contained in:
@@ -12,34 +12,34 @@ public enum BoxPointStatusEnum {
|
||||
/**
|
||||
* 空位
|
||||
*/
|
||||
EMPTY(1, "空位"),
|
||||
EMPTY("1", "空位"),
|
||||
/**
|
||||
* 空载具
|
||||
*/
|
||||
EMPTY_CONTAINER(2, "空载具"),
|
||||
EMPTY_CONTAINER("2", "空载具"),
|
||||
/**
|
||||
* 有子卷
|
||||
*/
|
||||
HAS_SUB_ROLL(3, "有子卷"),
|
||||
HAS_SUB_ROLL("3", "有子卷"),
|
||||
/**
|
||||
* 合格品
|
||||
*/
|
||||
QUALIFIED(4, "合格品"),
|
||||
QUALIFIED("4", "合格品"),
|
||||
/**
|
||||
* 管制品
|
||||
*/
|
||||
CONTROLLED(5, "管制品");
|
||||
CONTROLLED("5", "管制品");
|
||||
|
||||
/**
|
||||
* 字典键值
|
||||
*/
|
||||
private final Integer code;
|
||||
private final String code;
|
||||
/**
|
||||
* 字典标签
|
||||
*/
|
||||
private final String desc;
|
||||
|
||||
BoxPointStatusEnum(Integer code, String desc) {
|
||||
BoxPointStatusEnum(String code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
@@ -49,7 +49,7 @@ public enum BoxPointStatusEnum {
|
||||
* @param code 编码
|
||||
* @return 匹配的枚举,未找到返回null
|
||||
*/
|
||||
public static BoxPointStatusEnum getByCode(Integer code) {
|
||||
public static BoxPointStatusEnum getByCode(String code) {
|
||||
for (BoxPointStatusEnum statusEnum : values()) {
|
||||
if (statusEnum.getCode().equals(code)) {
|
||||
return statusEnum;
|
||||
|
||||
@@ -13,28 +13,28 @@ public enum BoxPointTypeEnum {
|
||||
/**
|
||||
* 下线点
|
||||
*/
|
||||
OFFLINE_POINT(1, "下线点"),
|
||||
OFFLINE_POINT("1", "下线点"),
|
||||
/**
|
||||
* 待检点
|
||||
*/
|
||||
INSPECTION_PENDING_POINT(2, "待检点"),
|
||||
INSPECTION_PENDING_POINT("2", "待检点"),
|
||||
/**
|
||||
* 不合格点
|
||||
*/
|
||||
UNQUALIFIED_POINT(3, "不合格点"),
|
||||
UNQUALIFIED_POINT("3", "不合格点"),
|
||||
/**
|
||||
* 装箱点
|
||||
*/
|
||||
PACKING_POINT(4, "装箱点"),
|
||||
PACKING_POINT("4", "装箱点"),
|
||||
/**
|
||||
* 装箱对接点
|
||||
*/
|
||||
PACKING_DOCK_POINT(5, "装箱对接点");
|
||||
PACKING_DOCK_POINT("5", "装箱对接点");
|
||||
|
||||
private final Integer code;
|
||||
private final String code;
|
||||
private final String desc;
|
||||
|
||||
BoxPointTypeEnum(Integer code, String desc) {
|
||||
BoxPointTypeEnum(String code, String desc) {
|
||||
this.code = code;
|
||||
this.desc = desc;
|
||||
}
|
||||
@@ -44,7 +44,7 @@ public enum BoxPointTypeEnum {
|
||||
* @param code 字典键值
|
||||
* @return 匹配枚举,无匹配返回null
|
||||
*/
|
||||
public static BoxPointTypeEnum getByCode(Integer code) {
|
||||
public static BoxPointTypeEnum getByCode(String code) {
|
||||
for (BoxPointTypeEnum item : values()) {
|
||||
if (item.getCode().equals(code)) {
|
||||
return item;
|
||||
|
||||
@@ -86,6 +86,14 @@ public class PackagePointRespVO implements VO {
|
||||
@ExcelProperty("所属等待点类型")
|
||||
private String waitPointType;
|
||||
|
||||
@Schema(description = "锁状态")
|
||||
@ExcelProperty("锁状态")
|
||||
private String lockStatus;
|
||||
|
||||
@Schema(description = "生产区域")
|
||||
@ExcelProperty("生产区域")
|
||||
private String productArea;
|
||||
|
||||
@Schema(description = "更新时间", requiredMode = Schema.RequiredMode.REQUIRED)
|
||||
@ExcelProperty("更新时间")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package cn.code.nl.module.lms.dal.dataobject.packagepoint;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
import java.util.*;
|
||||
import java.time.LocalDateTime;
|
||||
@@ -97,5 +98,10 @@ public class PackagePointDO extends BaseDO {
|
||||
*/
|
||||
private String lockStatus;
|
||||
|
||||
/**
|
||||
* 生产区域
|
||||
*/
|
||||
private String productArea;
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -6,8 +6,11 @@ import cn.code.nl.framework.mybatis.core.query.LambdaQueryWrapperX;
|
||||
import cn.code.nl.module.lms.controller.admin.packagepoint.vo.PackagePointPageReqVO;
|
||||
import cn.code.nl.module.lms.dal.dataobject.packagepoint.PackagePointDO;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 装箱区点位库存 Mapper
|
||||
*
|
||||
@@ -16,6 +19,32 @@ import org.springframework.util.StringUtils;
|
||||
@Mapper
|
||||
public interface PackagePointMapper extends BaseMapperX<PackagePointDO> {
|
||||
|
||||
/**
|
||||
* 查询可用点位
|
||||
*
|
||||
* @param pointType 点位类型
|
||||
* @param pointStatus 点位状态
|
||||
* @return 可用点位列表
|
||||
*/
|
||||
List<PackagePointDO> selectAvailablePointList(@Param("pointType") String pointType,
|
||||
@Param("pointStatus") String pointStatus);
|
||||
|
||||
/**
|
||||
* 尝试锁定点位
|
||||
*
|
||||
* @param pointId 点位标识
|
||||
* @return 更新行数
|
||||
*/
|
||||
int tryLockPoint(@Param("pointId") Long pointId);
|
||||
|
||||
/**
|
||||
* 释放点位锁
|
||||
*
|
||||
* @param pointId 点位标识
|
||||
* @return 更新行数
|
||||
*/
|
||||
int unlockPoint(@Param("pointId") Long pointId);
|
||||
|
||||
default PageResult<PackagePointDO> selectPage(PackagePointPageReqVO reqVO) {
|
||||
return selectPage(reqVO, new LambdaQueryWrapperX<PackagePointDO>()
|
||||
.eqIfPresent(PackagePointDO::getPointType, reqVO.getPointType())
|
||||
|
||||
@@ -29,7 +29,7 @@ public class BoxAutoJob {
|
||||
log.info("子卷下线送到待检区任务创建开始.....");
|
||||
XxlJobHelper.log("子卷下线送到待检区任务创建开始");
|
||||
|
||||
|
||||
packageBoxBusinessService.autoSendSubRollTask();
|
||||
|
||||
String msg = "子卷下线送到待检区任务创建结束";
|
||||
XxlJobHelper.log(msg);
|
||||
|
||||
@@ -6,4 +6,9 @@ package cn.code.nl.module.lms.service.packagepoint;
|
||||
* @Date: 2026/8/10 17:15
|
||||
*/
|
||||
public interface PackageBoxBusinessService {
|
||||
|
||||
/**
|
||||
* 自动创建子卷下线送待检区任务
|
||||
*/
|
||||
void autoSendSubRollTask();
|
||||
}
|
||||
|
||||
@@ -1,12 +1,126 @@
|
||||
package cn.code.nl.module.lms.service.packagepoint;
|
||||
|
||||
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.lms.enums.BoxPointTypeEnum;
|
||||
import cn.code.nl.module.task.api.TransportTaskApi;
|
||||
import cn.code.nl.module.task.dto.TransportTaskCreateReqDTO;
|
||||
import cn.code.nl.module.task.enums.TaskOwnerServiceEnum;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 装箱业务服务实现类
|
||||
*
|
||||
* @Author: liyongde
|
||||
* @Date: 2026/8/10 17:16
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class PackageBoxBusinessServiceImpl implements PackageBoxBusinessService{
|
||||
public class PackageBoxBusinessServiceImpl implements PackageBoxBusinessService {
|
||||
|
||||
/** 子卷下线送待检区业务类型 */
|
||||
private static final String SUB_ROLL_DOWN_BIZ_TYPE = "SUB_ROLL_DOWN";
|
||||
|
||||
/** 子卷下线任务回调处理器编码 */
|
||||
private static final String SUB_ROLL_DOWN_HANDLE_CODE = "subRollDownAgvTask";
|
||||
|
||||
/**
|
||||
* ACS 搬运任务类型
|
||||
*/
|
||||
private static final String ACS_MOVE_TASK_TYPE = "7";
|
||||
|
||||
/**
|
||||
* AGV 系统类型
|
||||
*/
|
||||
private static final String AGV_SYSTEM_TYPE = "1";
|
||||
|
||||
@Resource
|
||||
private PackagePointMapper packagePointMapper;
|
||||
|
||||
@Resource
|
||||
private TransportTaskApi transportTaskApi;
|
||||
|
||||
/**
|
||||
* 自动创建子卷下线送待检区任务
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void autoSendSubRollTask() {
|
||||
List<PackagePointDO> sourcePointList = packagePointMapper.selectAvailablePointList(
|
||||
BoxPointTypeEnum.OFFLINE_POINT.getCode(), BoxPointStatusEnum.HAS_SUB_ROLL.getCode());
|
||||
List<PackagePointDO> destinationPointList = packagePointMapper.selectAvailablePointList(
|
||||
BoxPointTypeEnum.INSPECTION_PENDING_POINT.getCode(), BoxPointStatusEnum.EMPTY.getCode());
|
||||
if (CollectionUtils.isEmpty(sourcePointList) || CollectionUtils.isEmpty(destinationPointList)) {
|
||||
log.info("没有可配对的子卷下线点或待检区点位,结束本轮任务创建");
|
||||
return;
|
||||
}
|
||||
|
||||
Iterator<PackagePointDO> destinationIterator = destinationPointList.iterator();
|
||||
for (PackagePointDO sourcePoint : sourcePointList) {
|
||||
if (packagePointMapper.tryLockPoint(sourcePoint.getPointId()) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PackagePointDO destinationPoint = lockNextDestinationPoint(destinationIterator);
|
||||
if (destinationPoint == null) {
|
||||
packagePointMapper.unlockPoint(sourcePoint.getPointId());
|
||||
log.info("没有可用的待检区点位,结束本轮任务创建");
|
||||
break;
|
||||
}
|
||||
|
||||
Long taskId = createSubRollTransportTask(sourcePoint, destinationPoint);
|
||||
log.info("子卷下线送待检区任务创建成功,任务标识={},起点编码={},目的点编码={}",
|
||||
taskId, sourcePoint.getPointCode(), destinationPoint.getPointCode());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建子卷下线送待检区运输任务
|
||||
*
|
||||
* @param sourcePoint 起点
|
||||
* @param destinationPoint 目的点
|
||||
* @return 运输任务标识
|
||||
*/
|
||||
private Long createSubRollTransportTask(PackagePointDO sourcePoint, PackagePointDO destinationPoint) {
|
||||
TransportTaskCreateReqDTO task = new TransportTaskCreateReqDTO();
|
||||
task.setTaskName("子卷下线送待检区任务");
|
||||
task.setOwnerService(TaskOwnerServiceEnum.LMS.name());
|
||||
task.setBizType(SUB_ROLL_DOWN_BIZ_TYPE);
|
||||
task.setBizId(sourcePoint.getContainerName());
|
||||
task.setHandleCode(SUB_ROLL_DOWN_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.setMaterialCode(sourcePoint.getContainerName());
|
||||
task.setProductArea(sourcePoint.getProductArea());
|
||||
task.setIsAutoIssue("1");
|
||||
task.setIsCreateFinish(true);
|
||||
return transportTaskApi.createTransportTask(task).getCheckedData();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从候选点位中锁定下一个可用的待检区点位
|
||||
*
|
||||
* @param destinationIterator 待检区候选点位迭代器
|
||||
* @return 成功锁定的待检区点位,没有可用点位时返回 null
|
||||
*/
|
||||
private PackagePointDO lockNextDestinationPoint(Iterator<PackagePointDO> destinationIterator) {
|
||||
while (destinationIterator.hasNext()) {
|
||||
PackagePointDO destinationPoint = destinationIterator.next();
|
||||
if (packagePointMapper.tryLockPoint(destinationPoint.getPointId()) > 0) {
|
||||
return destinationPoint;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
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 lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 子卷下线AGV任务
|
||||
* @Author: liyongde
|
||||
* @Date: 2026/8/12 14:44
|
||||
*/
|
||||
@Slf4j
|
||||
@Component("subRollDownAgvTask")
|
||||
public class SubRollDownAgvTask extends AbstractTask {
|
||||
@Override
|
||||
public void doHandleFinish(TaskExecuteDTO taskExecuteDTO) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doHandleCancel(TaskExecuteDTO taskExecuteDTO) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void doHandlePicked(TaskExecuteDTO taskExecuteDTO) {
|
||||
// 取货完成,释放点位
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
/**
|
||||
*
|
||||
* @Author: liyongde
|
||||
* @Date: 2026/8/12 14:44
|
||||
*/
|
||||
package cn.code.nl.module.lms.tasks;
|
||||
@@ -2,11 +2,49 @@
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="cn.code.nl.module.lms.dal.mysql.packagepoint.PackagePointMapper">
|
||||
|
||||
<!--
|
||||
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。
|
||||
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。
|
||||
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。
|
||||
文档可见:https://www.iocoder.cn/MyBatis/x-plugins/
|
||||
-->
|
||||
<select id="selectAvailablePointList"
|
||||
resultType="cn.code.nl.module.lms.dal.dataobject.packagepoint.PackagePointDO">
|
||||
SELECT point_id,
|
||||
point_code,
|
||||
point_name,
|
||||
point_type,
|
||||
container_name,
|
||||
point_status,
|
||||
vehicle_code,
|
||||
block,
|
||||
point_location,
|
||||
sort_seq,
|
||||
is_used,
|
||||
remark,
|
||||
plan,
|
||||
row_num,
|
||||
col_num,
|
||||
depth,
|
||||
wait_point_type,
|
||||
lock_status
|
||||
FROM lms_package_point
|
||||
WHERE point_type = #{pointType}
|
||||
AND point_status = #{pointStatus}
|
||||
AND lock_status = '0'
|
||||
AND deleted = b'0'
|
||||
AND is_used = true
|
||||
ORDER BY sort_seq, point_id
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
<update id="tryLockPoint">
|
||||
UPDATE lms_package_point
|
||||
SET lock_status = '1'
|
||||
WHERE point_id = #{pointId}
|
||||
AND lock_status = '0'
|
||||
AND deleted = b'0'
|
||||
</update>
|
||||
|
||||
<update id="unlockPoint">
|
||||
UPDATE lms_package_point
|
||||
SET lock_status = '0'
|
||||
WHERE point_id = #{pointId}
|
||||
AND lock_status = '1'
|
||||
AND deleted = b'0'
|
||||
</update>
|
||||
|
||||
</mapper>
|
||||
|
||||
@@ -10,8 +10,8 @@ import lombok.Getter;
|
||||
@AllArgsConstructor
|
||||
public enum TaskOwnerServiceEnum {
|
||||
|
||||
LMS("lms", "lms-server"),
|
||||
WMS("wms", "wms-server");
|
||||
LMS("lms", "LMS"),
|
||||
WMS("wms", "WMS");
|
||||
|
||||
/**
|
||||
* MQ Topic 前缀
|
||||
|
||||
@@ -17,6 +17,7 @@ CREATE TABLE `lms_package_point`
|
||||
`col_num` char(6) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '0' COMMENT '列',
|
||||
`depth` char(1) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '0' COMMENT '深浅位0浅位1深位',
|
||||
`wait_point_type` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT '0' COMMENT '所属等待点类型',
|
||||
`lock_status` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL DEFAULT '0' COMMENT '锁状态',
|
||||
`creator` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '创建者',
|
||||
`create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`updater` varchar(64) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT '' COMMENT '更新者',
|
||||
|
||||
Reference in New Issue
Block a user