opt:二楼出入库卡控

This commit is contained in:
2026-08-11 10:59:53 +07:00
parent f41571698d
commit a8ec9741f1
14 changed files with 633 additions and 23 deletions

View File

@@ -39,6 +39,8 @@ import org.nl.modules.common.exception.BadRequestException;
import org.nl.modules.common.utils.RedisUtils;
import org.nl.modules.wql.core.bean.WQLObject;
import org.nl.modules.wql.util.SpringContextHolder;
import org.nl.system.service.dict.dao.Dict;
import org.nl.system.service.dict.dao.mapper.SysDictMapper;
import org.nl.system.service.param.ISysParamService;
import org.nl.system.service.param.dao.Param;
import org.nl.system.service.param.impl.SysParamServiceImpl;
@@ -82,6 +84,9 @@ public class VehicleTwoServiceImpl implements VehicleTwoService {
@Autowired
private IBstIvtBoxinfoService iBstIvtBoxinfoService;
@Autowired
private SysDictMapper sysDictMapper;
@Autowired
private LmsToMesService lmsToMesService;
@@ -317,10 +322,15 @@ public class VehicleTwoServiceImpl implements VehicleTwoService {
whereJson.put("material_barcode", material_barcode);
whereJson.put("bill_type", IOSEnum.IN_TYPE.code("盘点入库"));
if (whereJson.getString("vehicle_code").startsWith("YNY")) {
//whereJson.put("move_block_num", "4");
} else{
List<Dict> dict = sysDictMapper.selectList(new LambdaQueryWrapper<Dict>()
.eq( Dict::getCode, "inventory_block_point")
.eq(Dict::getValue, point_code));
if (whereJson.getString("vehicle_code").startsWith("YNY")) {
whereJson.put("move_block_num", "4");
} else if(!CollectionUtils.isEmpty(dict)){
whereJson.put("move_block_num", dict.get(0).getLabel());
// whereJson.put("move_block_num", "2");
}
if (!whereJson.containsKey("point_code")) {

View File

@@ -7,9 +7,11 @@ import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.nl.b_lms.storage_manage.ios.enums.IOSEnum;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.dao.StIvtIostorinvdis;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.impl.StIvtIostorinvdisServiceImpl;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.util.AisleConflictHelper;
import org.nl.common.utils.SecurityUtils;
import org.nl.language.LangBehavior;
import org.nl.modules.common.exception.BadRequestException;
@@ -18,6 +20,7 @@ import org.nl.modules.wql.util.SpringContextHolder;
import org.nl.wms.sch.AcsTaskDto;
import org.nl.wms.sch.manage.AbstractAcsTask;
import org.nl.wms.sch.manage.TaskStatusEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -31,6 +34,7 @@ import static org.nl.wms.util.TaskUtil.getRoutePlanCode;
* Created by Lxy on 2024/1/19.
*/
@Service
@Slf4j
public class TwoInEmpTask extends AbstractAcsTask {
/**
@@ -38,6 +42,9 @@ public class TwoInEmpTask extends AbstractAcsTask {
*/
private final String THIS_CLASS = TwoInEmpTask.class.getName();
@Autowired
private AisleConflictHelper aisleConflictHelper;
@Override
public List<AcsTaskDto> addTask() {
/*
@@ -49,6 +56,11 @@ public class TwoInEmpTask extends AbstractAcsTask {
for (int i = 0; i < arr.size(); i++) {
JSONObject json = arr.getJSONObject(i);
if (!aisleConflictHelper.canDispatchInbound(json.getString("point_code1"), json.getString("point_code2"))) {
log.info("空托盘入库任务[{}]因巷道冲突被跳过不下发ACS", json.getString("task_code"));
continue;
}
char dtl_type = json.getString("task_type").charAt(json.getString("task_type").length() - 1);
AcsTaskDto dto = AcsTaskDto.builder()
.ext_task_id(json.getString("task_id"))

View File

@@ -13,6 +13,7 @@ import org.nl.b_lms.storage_manage.ios.service.iostorInv.IStIvtIostorinvService;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.IStIvtIostorinvdisService;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.dao.StIvtIostorinvdis;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.impl.StIvtIostorinvdisServiceImpl;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.util.AisleConflictHelper;
import org.nl.common.utils.SecurityUtils;
import org.nl.language.LangBehavior;
import org.nl.modules.common.exception.BadRequestException;
@@ -37,6 +38,7 @@ import static org.nl.wms.util.TaskUtil.getRoutePlanCode;
* Created by Lxy on 2024/1/19.
*/
@Service
@lombok.extern.slf4j.Slf4j
public class TwoInTask extends AbstractAcsTask {
/**
@@ -56,6 +58,9 @@ public class TwoInTask extends AbstractAcsTask {
@Autowired
private IStIvtIostorinvService iStIvtIostorinvService;
@Autowired
private AisleConflictHelper aisleConflictHelper;
@Override
public List<AcsTaskDto> addTask() {
/*
@@ -67,6 +72,11 @@ public class TwoInTask extends AbstractAcsTask {
for (int i = 0; i < arr.size(); i++) {
JSONObject json = arr.getJSONObject(i);
if (!aisleConflictHelper.canDispatchInbound(json.getString("point_code1"), json.getString("point_code2"))) {
log.info("入库任务[{}]因巷道冲突被跳过不下发ACS", json.getString("task_code"));
continue;
}
char dtl_type = json.getString("task_type").charAt(json.getString("task_type").length() - 1);
AcsTaskDto dto = AcsTaskDto.builder()
.ext_task_id(json.getString("task_id"))

View File

@@ -129,6 +129,11 @@ public class TwoLashTask extends AbstractAcsTask {
isBinding = IOSEnum.IS_NOTANDYES.code("");
}
}
if(IOSEnum.IS_NOTANDYES.code("").equals(isBinding) && IOSEnum.IS_NOTANDYES.code("").equals(json.getString("is_auto_issue"))){
isBinding = IOSEnum.IS_NOTANDYES.code("");
}
interaction_json.put("isBinding", isBinding);
char dtl_type = json.getString("task_type").charAt(json.getString("task_type").length() - 1);

View File

@@ -5,7 +5,9 @@ import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.nl.b_lms.storage_manage.ios.enums.IOSEnum;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.util.AisleConflictHelper;
import org.nl.common.utils.SecurityUtils;
import org.nl.language.LangBehavior;
import org.nl.modules.common.exception.BadRequestException;
@@ -13,6 +15,7 @@ import org.nl.modules.wql.core.bean.WQLObject;
import org.nl.wms.sch.AcsTaskDto;
import org.nl.wms.sch.manage.AbstractAcsTask;
import org.nl.wms.sch.manage.TaskStatusEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -26,6 +29,7 @@ import static org.nl.wms.util.TaskUtil.getRoutePlanCode;
* Created by Lxy on 2024/1/19.
*/
@Service
@Slf4j
public class TwoOutEmpTask extends AbstractAcsTask {
/**
@@ -33,6 +37,9 @@ public class TwoOutEmpTask extends AbstractAcsTask {
*/
private final String THIS_CLASS = TwoOutEmpTask.class.getName();
@Autowired
private AisleConflictHelper aisleConflictHelper;
@Override
public List<AcsTaskDto> addTask() {
/*
@@ -44,6 +51,11 @@ public class TwoOutEmpTask extends AbstractAcsTask {
for (int i = 0; i < arr.size(); i++) {
JSONObject json = arr.getJSONObject(i);
if (!aisleConflictHelper.canDispatchOutbound(json.getString("point_code1"), json.getString("point_code2"))) {
log.info("空托盘出库任务[{}]因巷道冲突被跳过不下发ACS", json.getString("task_code"));
continue;
}
char dtl_type = json.getString("task_type").charAt(json.getString("task_type").length() - 1);
AcsTaskDto dto = AcsTaskDto.builder()
.ext_task_id(json.getString("task_id"))

View File

@@ -16,6 +16,7 @@ import org.nl.b_lms.storage_manage.ios.enums.IOSEnum;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.dao.StIvtIostorinvdis;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.dao.mapper.StIvtIostorinvdisMapper;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.impl.StIvtIostorinvOutServiceImpl;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.util.AisleConflictHelper;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.util.impl.LashManageServiceImpl;
import org.nl.b_lms.storage_manage.md.dao.MdPdStoragevehicleext;
import org.nl.b_lms.storage_manage.md.dao.mapper.MdPdStoragevehicleextMapper;
@@ -61,6 +62,9 @@ public class TwoOutTask extends AbstractAcsTask {
@Autowired
private MdPdStoragevehicleextMapper mdPdStoragevehicleextMapper;
@Autowired
private AisleConflictHelper aisleConflictHelper;
@Override
@@ -129,6 +133,11 @@ public class TwoOutTask extends AbstractAcsTask {
for (int i = 0; i < taskArr.size(); i++) {
JSONObject json = taskArr.get(i);
if (!aisleConflictHelper.canDispatchOutbound(json.getString("point_code1"), json.getString("point_code2"))) {
log.info("出库任务[{}]因巷道冲突被跳过不下发ACS", json.getString("task_code"));
continue;
}
char dtl_type = json.getString("task_type").charAt(json.getString("task_type").length() - 1);
AcsTaskDto dto = AcsTaskDto.builder()
.ext_task_id(json.getString("task_id"))

View File

@@ -112,8 +112,9 @@
FROM
ST_IVT_IOStorInvDis dis
LEFT JOIN pdm_bi_subpackagerelation sub ON sub.container_name = dis.pcsn
LEFT JOIN st_ivt_iostorinv inv on dis.iostorinv_id = inv.iostorinv_id
WHERE
dis.work_status = '00'
dis.work_status = '00' and inv.io_type = '1'
<if test="iostorinvdtl_id != null and iostorinvdtl_id != ''">
AND dis.iostorinvdtl_id= #{iostorinvdtl_id}
</if>

View File

@@ -0,0 +1,341 @@
package org.nl.b_lms.storage_manage.ios.service.iostorInv.util;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.nl.b_lms.sch.task.dao.SchBaseTask;
import org.nl.b_lms.sch.task.dao.mapper.SchBaseTaskMapper;
import org.nl.b_lms.storage_manage.st.dao.StIvtStructattr;
import org.nl.b_lms.storage_manage.st.dao.mapper.StIvtStructattrMapper;
import org.nl.wms.sch.manage.TaskStatusEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.*;
@Component
@Slf4j
public class AisleConflictHelper {
private static final String TWO_IN_TASK_CLASS = "org.nl.b_lms.sch.tasks.TwoInTask";
private static final String TWO_IN_EMP_TASK_CLASS = "org.nl.b_lms.sch.tasks.TwoInEmpTask";
private static final String TWO_OUT_TASK_CLASS = "org.nl.b_lms.sch.tasks.TwoOutTask";
private static final String TWO_OUT_EMP_TASK_CLASS = "org.nl.b_lms.sch.tasks.TwoOutEmpTask";
private static final String BOX_SSX_TASK_CLASS = "org.nl.b_lms.sch.tasks.boxstack.BoxSSXTask";
private static final String LARGE_PALLET = "large";
private static final String SMALL_PALLET = "small";
private static final List<String> LARGE_PALLET_AISLES = Arrays.asList("1", "2", "3");
private static final String SMALL_PALLET_AISLE = "4";
private static final List<String> INBOUND_TASK_CLASSES = Arrays.asList(TWO_IN_TASK_CLASS, TWO_IN_EMP_TASK_CLASS);
private static final List<String> OUTBOUND_TASK_CLASSES = Arrays.asList(TWO_OUT_TASK_CLASS, TWO_OUT_EMP_TASK_CLASS);
@Autowired
private SchBaseTaskMapper schBaseTaskMapper;
@Autowired
private StIvtStructattrMapper stIvtStructattrMapper;
/**
* 根据货位编码获取巷道编号(block_num)
*/
public String getBlockNumByPointCode(String pointCode) {
if (StrUtil.isBlank(pointCode)) {
return null;
}
StIvtStructattr attr = stIvtStructattrMapper.selectOne(
new LambdaQueryWrapper<StIvtStructattr>()
.eq(StIvtStructattr::getStruct_code, pointCode)
.last("LIMIT 1")
);
if (attr != null && attr.getBlock_num() != null) {
return attr.getBlock_num().toString();
}
return null;
}
/**
* 判断输送线点位是否在二楼(立体库)
* 规则: 去掉CK或RK前缀,剩余数字的第一位为楼层
* 注意: 仅适用于输送线点位(CK/RK开头),不适用于货位点(L开头)
*/
public boolean isSecondFloor(String pointCode) {
if (StrUtil.isBlank(pointCode)) {
return false;
}
String code = pointCode.replaceFirst("^(CK|RK)", "");
if (StrUtil.isBlank(code) || !code.matches("\\d+")) {
return false;
}
return code.startsWith("2");
}
/**
* 根据载具编码前缀获取托盘类型
* YNX = 大托盘, YNY = 小托盘
*/
public String getPalletType(String vehicleCode) {
if (StrUtil.isBlank(vehicleCode)) {
return null;
}
if (vehicleCode.startsWith("YNX")) {
return LARGE_PALLET;
} else if (vehicleCode.startsWith("YNY")) {
return SMALL_PALLET;
}
return null;
}
/**
* 获取巷道的托盘类型
*/
public String getPalletTypeByBlockNum(String blockNum) {
if (LARGE_PALLET_AISLES.contains(blockNum)) {
return LARGE_PALLET;
}
if (SMALL_PALLET_AISLE.equals(blockNum)) {
return SMALL_PALLET;
}
return null;
}
/**
* 判断指定巷道是否有入库任务(已下发或执行中)
* 入库任务: handle_class in (TwoInTask, TwoInEmpTask), task_status < '07'
* 入库任务通过 point_code2(货位) 关联巷道
*/
public boolean hasInboundTask(String blockNum) {
if (StrUtil.isBlank(blockNum)) {
return false;
}
List<SchBaseTask> tasks = schBaseTaskMapper.selectList(
new LambdaQueryWrapper<SchBaseTask>()
.in(SchBaseTask::getHandle_class, INBOUND_TASK_CLASSES)
.lt(SchBaseTask::getTask_status, TaskStatusEnum.FINISHED.getCode())
.eq(SchBaseTask::getIs_delete, "0")
);
for (SchBaseTask task : tasks) {
String aisle = getBlockNumByPointCode(task.getPoint_code2());
if (blockNum.equals(aisle)) {
return true;
}
}
return false;
}
/**
* 判断指定巷道是否有出库任务(已下发或执行中)
* 出库任务: handle_class in (TwoOutTask, TwoOutEmpTask), task_status in ('05','06')
* 出库任务通过 point_code1(货位) 关联巷道
*/
public boolean hasOutboundTask(String blockNum) {
if (StrUtil.isBlank(blockNum)) {
return false;
}
List<SchBaseTask> tasks = schBaseTaskMapper.selectList(
new LambdaQueryWrapper<SchBaseTask>()
.in(SchBaseTask::getHandle_class, OUTBOUND_TASK_CLASSES)
.in(SchBaseTask::getTask_status, TaskStatusEnum.ISSUE.getCode(), TaskStatusEnum.EXECUTING.getCode())
.eq(SchBaseTask::getIs_delete, "0")
);
for (SchBaseTask task : tasks) {
String aisle = getBlockNumByPointCode(task.getPoint_code1());
if (blockNum.equals(aisle)) {
return true;
}
}
return false;
}
/**
* 判断是否存在小托盘输送线任务(BoxSSXTask)
*/
public boolean hasSmallPalletConveyorTask() {
List<SchBaseTask> tasks = schBaseTaskMapper.selectList(
new LambdaQueryWrapper<SchBaseTask>()
.eq(SchBaseTask::getHandle_class, BOX_SSX_TASK_CLASS)
.lt(SchBaseTask::getTask_status, TaskStatusEnum.FINISHED.getCode())
.eq(SchBaseTask::getIs_delete, "0")
);
return !tasks.isEmpty();
}
/**
* 获取有大托盘出库任务的巷道数量(执行中)
* 包含 TwoOutTask 和 TwoOutEmpTask
*/
public int countLargePalletOutboundAisles() {
List<SchBaseTask> tasks = schBaseTaskMapper.selectList(
new LambdaQueryWrapper<SchBaseTask>()
.in(SchBaseTask::getHandle_class, OUTBOUND_TASK_CLASSES)
.in(SchBaseTask::getTask_status, TaskStatusEnum.ISSUE.getCode(), TaskStatusEnum.EXECUTING.getCode())
.eq(SchBaseTask::getIs_delete, "0")
);
Set<String> occupiedAisles = new HashSet<>();
for (SchBaseTask task : tasks) {
String aisle = getBlockNumByPointCode(task.getPoint_code1());
if (LARGE_PALLET_AISLES.contains(aisle)) {
occupiedAisles.add(aisle);
}
}
return occupiedAisles.size();
}
/**
* 获取大托盘可用的入库巷道列表(排除有出库任务的巷道)
* 包含 TwoOutTask 和 TwoOutEmpTask
*/
public List<String> getAvailableLargePalletAisles() {
List<SchBaseTask> tasks = schBaseTaskMapper.selectList(
new LambdaQueryWrapper<SchBaseTask>()
.in(SchBaseTask::getHandle_class, OUTBOUND_TASK_CLASSES)
.in(SchBaseTask::getTask_status, TaskStatusEnum.ISSUE.getCode(), TaskStatusEnum.EXECUTING.getCode())
.eq(SchBaseTask::getIs_delete, "0")
);
Set<String> occupiedAisles = new HashSet<>();
for (SchBaseTask task : tasks) {
String aisle = getBlockNumByPointCode(task.getPoint_code1());
if (LARGE_PALLET_AISLES.contains(aisle)) {
occupiedAisles.add(aisle);
}
}
List<String> availableAisles = new ArrayList<>(LARGE_PALLET_AISLES);
availableAisles.removeAll(occupiedAisles);
return availableAisles;
}
/**
* 从可用巷道中随机选择一个
*/
public String randomSelectAisle(List<String> availableAisles) {
if (availableAisles == null || availableAisles.isEmpty()) {
return null;
}
int index = new Random().nextInt(availableAisles.size());
return availableAisles.get(index);
}
/**
* 判断出库任务是否可以下发(综合检查)
* @param pointCode1 出库起点(货位位置, 如L1-01-01)
* @param pointCode2 出库终点(输送线点位, 如CK2009)
* @return true: 可以下发, false: 不可下发
*/
public boolean canDispatchOutbound(String pointCode1, String pointCode2) {
// 通过输送线点位判断是否二楼
if (!isSecondFloor(pointCode2)) {
return true;
}
// 通过货位点获取巷道
String blockNum = getBlockNumByPointCode(pointCode1);
if (StrUtil.isBlank(blockNum)) {
return true;
}
if (hasInboundTask(blockNum)) {
log.info("巷道[{}]有入库任务,出库任务不下发", blockNum);
return false;
}
String palletType = getPalletTypeByBlockNum(blockNum);
if (SMALL_PALLET.equals(palletType)) {
if (hasSmallPalletConveyorTask()) {
log.info("小托盘输送线任务存在,巷道[{}]出库任务不下发", blockNum);
return false;
}
} else if (LARGE_PALLET.equals(palletType)) {
int outboundCount = countLargePalletOutboundAisles();
if (outboundCount > 2) {
log.info("大托盘出库巷道数[{}] > 2巷道[{}]出库任务不下发", outboundCount, blockNum);
return false;
}
}
return true;
}
/**
* 判断入库任务是否可以下发(综合检查)
* @param pointCode1 入库起点(输送线点位, 如RK2011)
* @param pointCode2 入库终点(货位位置, 如L1-01-01)
* @return true: 可以下发, false: 不可下发
*/
public boolean canDispatchInbound(String pointCode1, String pointCode2) {
// 通过输送线点位判断是否二楼
if (!isSecondFloor(pointCode1)) {
return true;
}
// 通过货位点获取巷道
String blockNum = getBlockNumByPointCode(pointCode2);
if (StrUtil.isBlank(blockNum)) {
return true;
}
String palletType = getPalletTypeByBlockNum(blockNum);
if (SMALL_PALLET.equals(palletType)) {
if (hasOutboundTask(SMALL_PALLET_AISLE)) {
log.info("小托盘巷道[{}]有出库任务,入库任务不下发", blockNum);
return false;
}
} else if (LARGE_PALLET.equals(palletType)) {
List<String> availableAisles = getAvailableLargePalletAisles();
if (!availableAisles.contains(blockNum)) {
log.info("大托盘巷道[{}]有出库任务,入库任务不下发", blockNum);
return false;
}
}
return true;
}
/**
* 在入库申请时,获取推荐的巷道编号(考虑冲突)
* @param vehicleCode 载具编码
* @return 推荐的巷道编号如果无法分配返回null
*/
public Integer getRecommendedBlockForInbound(String vehicleCode) {
String aisle = getRecommendedAisleForInbound(vehicleCode);
if (aisle == null) {
return null;
}
return Integer.valueOf(aisle);
}
/**
* 在入库申请时,获取推荐的巷道(考虑冲突)
* @param vehicleCode 载具编码
* @return 推荐的巷道编号如果无法分配返回null
*/
public String getRecommendedAisleForInbound(String vehicleCode) {
String palletType = getPalletType(vehicleCode);
if (palletType == null) {
return null;
}
if (SMALL_PALLET.equals(palletType)) {
if (hasOutboundTask(SMALL_PALLET_AISLE)) {
log.info("小托盘巷道[{}]有出库任务,无法分配入库任务", SMALL_PALLET_AISLE);
return null;
}
return SMALL_PALLET_AISLE;
}
if (LARGE_PALLET.equals(palletType)) {
List<String> availableAisles = getAvailableLargePalletAisles();
if (availableAisles.isEmpty()) {
log.info("所有大托盘巷道都有出库任务,无法分配入库任务");
return null;
}
return randomSelectAisle(availableAisles);
}
return null;
}
}

View File

@@ -83,8 +83,10 @@ public class InVehicleManageServiceImpl implements InVehicleManageService {
jsonParam.put("stor_id", IOSEnum.STOR_ID.code("印尼仓库"));
jsonParam.put("sect_id", RegionTypeEnum.TWO_BZC01.getId());
jsonParam.put("vehicle_type", whereJson.getString("vehicle_type"));
if("2".equals(whereJson.getString("vehicle_type"))) {
//todo 默认需要调整,根据当前的出库任务确认如果是2楼入库则需要判断出库任务如果出库任务
// 优先使用 applyTwo 前置检查中已分配的巷道
if (StringUtils.isNotBlank(whereJson.getString("move_block_num"))) {
jsonParam.put("move_block_num", whereJson.getString("move_block_num"));
} else if("2".equals(whereJson.getString("vehicle_type"))) {
jsonParam.put("move_block_num","3");
} else {
jsonParam.put("move_block_num","4");

View File

@@ -11,6 +11,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sun.xml.bind.v2.TODO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.nl.b_lms.sch.point.dao.SchBasePoint;
import org.nl.b_lms.sch.point.dao.mapper.SchBasePointMapper;
import org.nl.b_lms.sch.task.dao.SchBaseTask;
@@ -38,9 +39,11 @@ import org.nl.modules.wql.util.SpringContextHolder;
import org.nl.system.service.param.ISysParamService;
import org.nl.system.service.param.dao.Param;
import org.nl.system.service.param.impl.SysParamServiceImpl;
import org.nl.wms.ext.acs.service.AcsToWmsService;
import org.nl.wms.ext.acs.service.WmsToAcsService;
import org.nl.wms.pda.st.service.impl.PrintServiceImpl;
import org.nl.wms.sch.manage.TaskStatusEnum;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
@@ -108,6 +111,9 @@ public class LashManageServiceImpl implements LashManageService {
private final ISysParamService iSysParamService;
private final SchBaseTaskMapper schBaseTaskMapper;
@Autowired
private WmsToAcsService wmsToAcsService;
@Override
@Transactional
public void createLashTask(JSONObject whereJson) {
@@ -197,6 +203,12 @@ public class LashManageServiceImpl implements LashManageService {
if (jsonPoint.getString("point_code").equals(IOSEnum.POINT_CODE.code("1124"))) {
checkMove();
}
if (jsonPoint.getString("point_code").equals(IOSEnum.POINT_CODE.code("1125"))) {
checkMove2();
}
}
end_point = jsonPoint.getString("point_code");
schBasePointMapper.updateById(JSON.parseObject(jsonPoint.toString(), SchBasePoint.class));
@@ -237,6 +249,11 @@ public class LashManageServiceImpl implements LashManageService {
}
end_point = jsonPoint.getString("point_code");
if (jsonPoint.getString("point_code").equals(IOSEnum.POINT_CODE.code("1125")) && empPointList.size() == 2) {
checkMove3();
}
schBasePointMapper.updateById(JSON.parseObject(jsonPoint.toString(), SchBasePoint.class));
boolean remove_flag = iBstIvtBoxlashboundService.remove(new QueryWrapper<BstIvtBoxlashbound>().lambda()
@@ -534,4 +551,152 @@ public class LashManageServiceImpl implements LashManageService {
}
}
}
/**
* 校验1124捆扎位是否可以强制离开
*/
private void checkMove2() {
// 判断1125工位是否有有货
SchBasePoint pointDao = schBasePointMapper.selectOne(
new QueryWrapper<SchBasePoint>().lambda()
.eq(SchBasePoint::getPoint_code, IOSEnum.POINT_CODE.code("1125"))
);
SchBasePoint pointDao2 = schBasePointMapper.selectOne(
new QueryWrapper<SchBasePoint>().lambda()
.eq(SchBasePoint::getPoint_code, IOSEnum.POINT_CODE.code("1124"))
);
if (ObjectUtil.isNotEmpty(pointDao.getVehicle_code()) && pointDao.getVehicle_qty().intValue() == 1
&& ObjectUtil.isNotEmpty(pointDao2.getVehicle_code()) && pointDao2.getVehicle_qty().intValue() == 1
) {
// 判断是否还有去1125工位的行架任务
List<SchBaseTask> taskList = ischBaseTaskService.list(
new QueryWrapper<SchBaseTask>().lambda()
.eq(SchBaseTask::getTask_type, TASKEnum.LASH_TYPE.code("捆扎桁架任务"))
.eq(SchBaseTask::getIs_delete, IOSEnum.IS_NOTANDYES.code(""))
.eq(SchBaseTask::getPoint_code2, IOSEnum.POINT_CODE.code("1125"))
.ne(SchBaseTask::getTask_status, TaskStatusEnum.FINISHED.getCode())
);
// 判断是否还有去1124工位的行架任务
List<SchBaseTask> taskList2 = ischBaseTaskService.list(
new QueryWrapper<SchBaseTask>().lambda()
.eq(SchBaseTask::getTask_type, TASKEnum.LASH_TYPE.code("捆扎桁架任务"))
.eq(SchBaseTask::getIs_delete, IOSEnum.IS_NOTANDYES.code(""))
.eq(SchBaseTask::getPoint_code2, IOSEnum.POINT_CODE.code("1124"))
.ne(SchBaseTask::getTask_status, TaskStatusEnum.FINISHED.getCode())
);
//判断当前点位是否有托盘
JSONObject device_jo = new JSONObject();
device_jo.put("device_code", IOSEnum.POINT_CODE.code("1125"));
device_jo.put("product_area", IOSEnum.PRODUCT_AREA.code("BLK"));
JSONArray device_ja = new JSONArray();
device_ja.add(device_jo);
JSONObject device_data = wmsToAcsService.getPointStatus(device_ja);
JSONObject data = device_data.getJSONArray("data").getJSONObject(0);
// 如果是不为空的则下发强制离开
if (ObjectUtil.isNotEmpty(taskList) && ObjectUtil.isEmpty(taskList2) && data.getIntValue("move") == 0) {
WmsToAcsService wmsToAcsService = SpringContextHolder.getBean(WmsToAcsService.class);
JSONArray action_rows = new JSONArray();
JSONObject action_jo = new JSONObject();
action_jo.put("device_code", IOSEnum.POINT_CODE.code("1124"));
action_jo.put("code", "to_command");
action_jo.put("product_area", "BLK");
action_jo.put("value", "26");
action_rows.add(action_jo);
wmsToAcsService.action(action_rows);
JSONArray action_rows2 = new JSONArray();
JSONObject action_jo2 = new JSONObject();
action_jo2.put("device_code", "MXDDHJ");
action_jo2.put("product_area", "BLK");
action_jo2.put("code", "to_command");
action_jo2.put("value", "1124");
action_rows2.add(action_jo2);
wmsToAcsService.action(action_rows2);
// 更新点位数量
pointDao.setVehicle_qty(BigDecimal.valueOf(0));
pointDao.setVehicle_code("");
schBasePointMapper.updateById(pointDao);
}
}
}
/**
* 校验1125是否有托盘
*/
private void checkMove3() {
// 判断1124工位是否有有货
SchBasePoint pointDao = schBasePointMapper.selectOne(
new QueryWrapper<SchBasePoint>().lambda()
.eq(SchBasePoint::getPoint_code, IOSEnum.POINT_CODE.code("1124"))
);
// 判断是否还有去1125工位的行架任务
List<SchBaseTask> taskList = ischBaseTaskService.list(
new QueryWrapper<SchBaseTask>().lambda()
.eq(SchBaseTask::getTask_type, TASKEnum.LASH_TYPE.code("捆扎桁架任务"))
.eq(SchBaseTask::getIs_delete, IOSEnum.IS_NOTANDYES.code(""))
.eq(SchBaseTask::getPoint_code2, IOSEnum.POINT_CODE.code("1125"))
.ne(SchBaseTask::getTask_status, TaskStatusEnum.FINISHED.getCode())
);
List<SchBaseTask> taskList2 = ischBaseTaskService.list(
new QueryWrapper<SchBaseTask>().lambda()
.eq(SchBaseTask::getTask_type, TASKEnum.LASH_TYPE.code("捆扎桁架任务"))
.eq(SchBaseTask::getIs_delete, IOSEnum.IS_NOTANDYES.code(""))
.eq(SchBaseTask::getPoint_code2, IOSEnum.POINT_CODE.code("1124"))
.ne(SchBaseTask::getTask_status, TaskStatusEnum.FINISHED.getCode())
);
if (StringUtils.isBlank(pointDao.getVehicle_code()) && pointDao.getVehicle_qty().intValue() == 0
) {
//判断当前点位是否有托盘
JSONObject device_jo = new JSONObject();
device_jo.put("device_code", IOSEnum.POINT_CODE.code("1125"));
device_jo.put("product_area", IOSEnum.PRODUCT_AREA.code("BLK"));
JSONArray device_ja = new JSONArray();
device_ja.add(device_jo);
JSONObject device_data = wmsToAcsService.getPointStatus(device_ja);
JSONObject data = device_data.getJSONArray("data").getJSONObject(0);
// 如果托盘为空
if (ObjectUtil.isEmpty(taskList) && ObjectUtil.isEmpty(taskList2) && data.getIntValue("move") == 0) {
WmsToAcsService wmsToAcsService = SpringContextHolder.getBean(WmsToAcsService.class);
JSONArray action_rows = new JSONArray();
JSONObject action_jo = new JSONObject();
action_jo.put("device_code", IOSEnum.POINT_CODE.code("1124"));
action_jo.put("code", "to_command");
action_jo.put("product_area", "BLK");
action_jo.put("value", "26");
action_rows.add(action_jo);
wmsToAcsService.action(action_rows);
JSONArray action_rows2 = new JSONArray();
JSONObject action_jo2 = new JSONObject();
action_jo2.put("device_code", "MXDDHJ");
action_jo2.put("product_area", "BLK");
action_jo2.put("code", "to_command");
action_jo2.put("value", "1124");
action_rows2.add(action_jo2);
wmsToAcsService.action(action_rows2);
// 更新点位数量
pointDao.setVehicle_qty(BigDecimal.valueOf(0));
pointDao.setVehicle_code("");
schBasePointMapper.updateById(pointDao);
}
}
}
}

View File

@@ -69,7 +69,7 @@
AND attr.block_num = #{param.block_num}
</if>
<if test="param.row_num != '' || param.row_num != null ">
AND attr.row_num != #{param.row_num}
AND attr.row_num = #{param.row_num}
</if>
</select>

View File

@@ -153,6 +153,11 @@ public class AcsToWmsController {
@PostMapping("/deviceApplyTwo")
@Log(value = "二期发货申请捆扎、贴标", isInterfaceLog = true, interfaceLogType = InterfaceLogType.ACS_TO_LMS)
@ApiLog(
bizCode = "/api/wms/task/deviceApplyTwo",
bizDesc = "二期发货申请捆扎、贴标",
systemFlag = "acs"
)
@SaIgnore
public ResponseEntity<Object> deviceApplyTwo(@RequestBody JSONObject whereJson) {
return new ResponseEntity<>(acsToWmsService.deviceApplyTwo(whereJson), HttpStatus.OK);

View File

@@ -51,6 +51,7 @@ import org.nl.b_lms.storage_manage.database.service.dao.MdpbBoxtype;
import org.nl.b_lms.storage_manage.ios.enums.IOSEnum;
import org.nl.b_lms.storage_manage.ios.enums.TASKEnum;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.IStIvtIostorinvOutService;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.util.AisleConflictHelper;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.util.service.*;
import org.nl.b_lms.storage_manage.md.dao.MdPdStorageVehicleInfo;
import org.nl.b_lms.storage_manage.md.dao.MdPdStoragevehicleext;
@@ -209,6 +210,9 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
@Autowired
private RedisUtils redisUtils;
@Autowired
private AisleConflictHelper aisleConflictHelper;
/**
* task_id任务标识
@@ -1321,15 +1325,23 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
if (CollectionUtils.isEmpty(errorMsg)) {
whereJson.put("bill_type", IOSEnum.IN_TYPE.code("生产入库"));
whereJson.put("material_barcode",containers);
if(whereJson.getString("vehicle_code").startsWith("YNX")) {
//todo 默认需要调整,根据当前的出库任务确认如果是2楼入库则需要判断出库任务如果出库任务
//whereJson.put("move_block_num", "3");
} else if(whereJson.getString("vehicle_code").startsWith("YNY")) {
String vehicleCode = whereJson.getString("vehicle_code");
String deviceCode = whereJson.getString("device_code");
if (aisleConflictHelper.isSecondFloor(deviceCode)) {
if(vehicleCode.startsWith("YNX")) {
Integer recommendedBlock = aisleConflictHelper.getRecommendedBlockForInbound(vehicleCode);
if (recommendedBlock == null) {
throw new BadRequestException("当前所有大托盘巷道都有出库任务,无法分配入库货位");
}
whereJson.put("move_block_num", String.valueOf(recommendedBlock));
} else if(vehicleCode.startsWith("YNY")) {
if (aisleConflictHelper.hasOutboundTask("4")) {
throw new BadRequestException("4号巷道有出库任务无法分配小托盘入库货位");
}
whereJson.put("move_block_num", "4");
}
if (
!whereJson.containsKey("point_code")
) {
}
if (!whereJson.containsKey("point_code")) {
whereJson.put("point_code", whereJson.getString("device_code"));
}
inBussManageService.inTask(whereJson);
@@ -1370,8 +1382,24 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
} else if (type.equals(IOSEnum.ACSTOLMS_TYPE.code("空盘入库"))) {
// 2-空盘入库
whereJson.put("vehicle_type", whereJson.getString("container_type"));
// whereJson.put("heightLevel", redisUtils.get(whereJson.getString("vehicle_code")+"InVehicleInHeightLevel"));
whereJson.put("heightLevel", "1");
// 二楼空托盘入库前置巷道冲突检查
String empDeviceCode = whereJson.getString("device_code");
String empVehicleCode = whereJson.getString("vehicle_code");
if (aisleConflictHelper.isSecondFloor(empDeviceCode)) {
if(empVehicleCode.startsWith("YNX")) {
Integer recommendedBlock = aisleConflictHelper.getRecommendedBlockForInbound(empVehicleCode);
if (recommendedBlock == null) {
throw new BadRequestException("当前所有大托盘巷道都有出库任务,无法分配空托盘入库货位");
}
whereJson.put("move_block_num", String.valueOf(recommendedBlock));
} else if(empVehicleCode.startsWith("YNY")) {
if (aisleConflictHelper.hasOutboundTask("4")) {
throw new BadRequestException("4号巷道有出库任务无法分配空托盘入库货位");
}
whereJson.put("move_block_num", "4");
}
}
inVehicleManageService.inVehicle(whereJson);
redisUtils.del(whereJson.getString("vehicle_code")+"InVehicleInHeightLevel");
} else if (type.equals(IOSEnum.ACSTOLMS_TYPE.code("空盘出库"))) {
@@ -1478,12 +1506,22 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
mdPdStoragevehicleextMapper.updateById(mdPdStoragevehicleext);
}
//优先巷道
if(whereJson.getString("vehicle_code").startsWith("YNX")) {
//todo 默认需要调整,根据当前的出库任务确认如果是2楼入库则需要判断出库任务如果出库任务
//whereJson.put("move_block_num", "3");
} else if(whereJson.getString("vehicle_code").startsWith("YNY")) {
String vehicleCode2 = whereJson.getString("vehicle_code");
String deviceCode2 = whereJson.getString("device_code");
if (aisleConflictHelper.isSecondFloor(deviceCode2)) {
if(vehicleCode2.startsWith("YNX")) {
Integer recommendedBlock = aisleConflictHelper.getRecommendedBlockForInbound(vehicleCode2);
if (recommendedBlock == null) {
throw new BadRequestException("当前所有大托盘巷道都有出库任务,无法分配入库货位");
}
whereJson.put("move_block_num", String.valueOf(recommendedBlock));
} else if(vehicleCode2.startsWith("YNY")) {
if (aisleConflictHelper.hasOutboundTask("4")) {
throw new BadRequestException("4号巷道有出库任务无法分配小托盘入库货位");
}
whereJson.put("move_block_num", "4");
}
}
whereJson.put("material_barcode", material_barcodes);
inBussManageService.inTask(whereJson);

View File

@@ -175,7 +175,6 @@ public abstract class AbstractAcsTask {
List<SchBaseTask> outBigTaskList = workingTaskList.stream().filter(task->oneFloorReturnBigVehicleOutTaskStartPoint.contains(task.getPoint_code2())).collect(Collectors.toList());
List<SchBaseTask> outSmallTaskList = workingTaskList.stream().filter(task->oneFloorReturnSmallVehicleOutTaskStartPoint.contains(task.getPoint_code2())).collect(Collectors.toList());
if(CollectionUtil.isEmpty(taskList)){
return null;
}
@@ -197,6 +196,7 @@ public abstract class AbstractAcsTask {
}
if (ObjectUtil.isNotEmpty(taskList)) {
JSONArray arr = JSONArray.parseArray(JSON.toJSONString(taskList));
if (acsUtil == null) {