opt:新增2楼出入库卡控逻辑

This commit is contained in:
2026-08-15 09:39:57 +07:00
parent 2ccd8f5191
commit f0a9ae29cd
17 changed files with 504 additions and 221 deletions

View File

@@ -18,7 +18,7 @@ import java.util.Map;
@Getter
public enum BoxStackEnum {
// 木箱任务类型
TASK_TYPE(MapOf.of("木箱入库", "010702", "木箱出库", "010705", "木箱移库", "010706","木箱缓存区到对接位", "010704","木箱行架", "010701","木箱对接位到缓存区", "010703")),
TASK_TYPE(MapOf.of("木箱入库", "010702", "木箱出库", "010704", "木箱移库", "010706","木箱缓存区到对接位", "010704","木箱行架", "010701","木箱对接位到缓存区", "010703")),
// 木箱出入库任务二次分配类型
AGV_ACTION_TYPE(MapOf.of("普通任务", "1", "取货二次分配", "2", "放货二次分配", "3", "取放货二次分配", "4")),
//AGV取放货完成

View File

@@ -265,6 +265,12 @@ public class VehicleTwoServiceImpl implements VehicleTwoService {
throw new BadRequestException("载具不存在!");
}
List<MdPdStoragevehicleext> mdPdStoragevehicleext2 = mdPdStoragevehicleextMapper.selectList(new QueryWrapper<MdPdStoragevehicleext>().eq("pcsn", whereJson.getString("box_no")));
if(null != mdPdStoragevehicleext2 && mdPdStoragevehicleext2.size()>1){
throw new BadRequestException("托盘绑定关系异常,请确认输送线传过来的箱号是否匹配!箱号=" + whereJson.getString("box_no"));
}
MdPdStoragevehicleext mdPdStoragevehicleext = mdPdStoragevehicleextMapper.selectOne(new QueryWrapper<MdPdStoragevehicleext>().eq("storagevehicle_code", mdPdStorageVehicleInfo.getStoragevehicle_code()));
if (ObjectUtil.isEmpty(mdPdStoragevehicleext)) {
@@ -282,12 +288,12 @@ public class VehicleTwoServiceImpl implements VehicleTwoService {
} else {
String pcsn = mdPdStoragevehicleext.getPcsn();
// if (StringUtils.isNotEmpty(pcsn)) {
// JSONArray stIvtStructattr = WQLObject.getWQLObject("st_ivt_structattr").query("storagevehicle_code = '" + pcsn + "'").getResultJSONArray(0);
// if (stIvtStructattr != null && stIvtStructattr.size() > 0) {
// throw new BadRequestException("当前托盘" + whereJson.getString("vehicle_code") + "已经绑定木箱" + pcsn);
// }
// }
if (StringUtils.isNotEmpty(pcsn)) {
JSONArray stIvtStructattr = WQLObject.getWQLObject("st_ivt_structattr").query("storagevehicle_code = '" + pcsn + "'").getResultJSONArray(0);
if (stIvtStructattr != null && stIvtStructattr.size() > 0) {
throw new BadRequestException("当前托盘" + whereJson.getString("vehicle_code") + "已经绑定木箱" + pcsn);
}
}
if(StringUtils.isBlank(mdPdStoragevehicleext.getQty())){
mdPdStoragevehicleext.setQty("1");
@@ -371,6 +377,12 @@ public class VehicleTwoServiceImpl implements VehicleTwoService {
@Override
@Transactional(rollbackFor = Exception.class)
public JSONObject InVehicleIn(JSONObject whereJson) {
MdPdStorageVehicleInfo mdPdStorageVehicleInfo = mdStorageVehicleInfoMapper.selectOne(new QueryWrapper<MdPdStorageVehicleInfo>().eq("storagevehicle_code", whereJson.getString("vehicle_code")));
if (ObjectUtil.isEmpty(mdPdStorageVehicleInfo)) {
throw new BadRequestException("载具不存在!");
}
JSONObject result = new JSONObject();
if("RK2009".equals(whereJson.getString("point_code"))){
@@ -667,6 +679,11 @@ public class VehicleTwoServiceImpl implements VehicleTwoService {
mdPdStoragevehicleextMapper.updateById(mdPdStoragevehicleextPc);
}
List<MdPdStoragevehicleext> mdPdStoragevehicleext2 = mdPdStoragevehicleextMapper.selectList(new QueryWrapper<MdPdStoragevehicleext>().eq("pcsn", whereJson.getString("box_no")));
if(null != mdPdStoragevehicleext2 && mdPdStoragevehicleext2.size()>1){
throw new BadRequestException("托盘绑定关系异常,请确认输送线传过来的箱号是否匹配!箱号=" + whereJson.getString("box_no"));
}
MdPdStoragevehicleext mdPdStoragevehicleext = mdPdStoragevehicleextMapper.selectOne(new QueryWrapper<MdPdStoragevehicleext>().eq("storagevehicle_code", mdPdStorageVehicleInfo.getStoragevehicle_code()));
if (ObjectUtil.isEmpty(mdPdStoragevehicleext)) {

View File

@@ -42,11 +42,10 @@ public class TwoInEmpTask extends AbstractAcsTask {
*/
private final String THIS_CLASS = TwoInEmpTask.class.getName();
@Autowired
private AisleConflictHelper aisleConflictHelper;
@Override
public List<AcsTaskDto> addTask() {
AisleConflictHelper aisleConflictHelper = SpringContextHolder.getBean(AisleConflictHelper.class);
/*
* 下发给ACS时需要特殊处理
*/

View File

@@ -58,11 +58,13 @@ public class TwoInTask extends AbstractAcsTask {
@Autowired
private IStIvtIostorinvService iStIvtIostorinvService;
@Autowired
private AisleConflictHelper aisleConflictHelper;
private AisleConflictHelper getAisleConflictHelper() {
return SpringContextHolder.getBean(AisleConflictHelper.class);
}
@Override
public List<AcsTaskDto> addTask() {
/*
* 下发给ACS时需要特殊处理
*/
@@ -72,7 +74,7 @@ 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"))) {
if (!getAisleConflictHelper().canDispatchInbound(json.getString("point_code1"), json.getString("point_code2"))) {
log.info("入库任务[{}]因巷道冲突被跳过不下发ACS", json.getString("task_code"));
continue;
}

View File

@@ -9,11 +9,16 @@ import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
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;
import org.nl.b_lms.sch.task.service.IschBaseTaskService;
import org.nl.b_lms.storage_manage.database.service.IBstIvtBoxinfoService;
import org.nl.b_lms.storage_manage.database.service.IMdpbBoxtypeService;
import org.nl.b_lms.storage_manage.database.service.dao.BstIvtBoxinfo;
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.dao.mapper.StIvtIostorinvOutMapper;
import org.nl.common.utils.SecurityUtils;
import org.nl.language.LangBehavior;
@@ -28,6 +33,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@@ -61,6 +67,20 @@ public class TwoLashTask extends AbstractAcsTask {
@Autowired
private StIvtIostorinvOutMapper stIvtIostorinvOutMapper;
/**
* 点位mapper服务
*/
@Autowired
private SchBasePointMapper schBasePointMapper;
/**
* 任务服务
*/
@Autowired
private IschBaseTaskService ischBaseTaskService;
@Override
public List<AcsTaskDto> addTask() {
/*
@@ -212,6 +232,11 @@ public class TwoLashTask extends AbstractAcsTask {
action_rows2.add(action_jo2);
wmsToAcsService.action(action_rows2);
//如果是1125强制离开则判断是否有去24的任务如果没有24也下强制离开
if(IOSEnum.POINT_CODE.code("1125").equals(task_jo.getString("point_code2"))){
checkMove();
}
// 更新点位载具、数量
JSONObject pointDao = pointTab.query("point_code = '" + task_jo.getString("point_code2") + "'").uniqueResult(0);
@@ -267,6 +292,52 @@ public class TwoLashTask extends AbstractAcsTask {
}
private void checkMove() {
SchBasePoint pointDao = schBasePointMapper.selectOne(
new QueryWrapper<SchBasePoint>().lambda()
.eq(SchBasePoint::getPoint_code, IOSEnum.POINT_CODE.code("1124"))
);
if (ObjectUtil.isEmpty(pointDao.getVehicle_code()) && pointDao.getVehicle_qty().intValue() == 0) {
// 判断是否还有去1124工位的行架任务
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("1124"))
.ne(SchBaseTask::getTask_status, TaskStatusEnum.FINISHED.getCode())
);
// 如果是空的则下发强制离开
if (ObjectUtil.isEmpty(taskList)) {
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);
}
}
}
@Override
@Transactional(rollbackFor = Exception.class)
public String createTask(JSONObject form) {

View File

@@ -12,6 +12,8 @@ import org.nl.common.utils.SecurityUtils;
import org.nl.language.LangBehavior;
import org.nl.modules.common.exception.BadRequestException;
import org.nl.modules.wql.core.bean.WQLObject;
import org.nl.modules.wql.util.SpringContextHolder;
import org.nl.wms.ext.mes.service.MesToLmsService;
import org.nl.wms.sch.AcsTaskDto;
import org.nl.wms.sch.manage.AbstractAcsTask;
import org.nl.wms.sch.manage.TaskStatusEnum;
@@ -37,9 +39,6 @@ public class TwoOutEmpTask extends AbstractAcsTask {
*/
private final String THIS_CLASS = TwoOutEmpTask.class.getName();
@Autowired
private AisleConflictHelper aisleConflictHelper;
@Override
public List<AcsTaskDto> addTask() {
/*
@@ -51,6 +50,8 @@ public class TwoOutEmpTask extends AbstractAcsTask {
for (int i = 0; i < arr.size(); i++) {
JSONObject json = arr.getJSONObject(i);
AisleConflictHelper aisleConflictHelper = SpringContextHolder.getBean(AisleConflictHelper.class);
if (!aisleConflictHelper.canDispatchOutbound(json.getString("point_code1"), json.getString("point_code2"))) {
log.info("空托盘出库任务[{}]因巷道冲突被跳过不下发ACS", json.getString("task_code"));
continue;

View File

@@ -173,6 +173,34 @@ public class TwoOutHeapTask extends AbstractAcsTask {
.query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0' ORDER BY create_time")
.getResultJSONArray(0).toJavaList(JSONObject.class);
if (CollectionUtils.isEmpty(taskArrAll)) {
return new ArrayList<>();
}
// 按任务组串行下发task_group_id 为空的任务直接下发,不参与分组排序
List<JSONObject> noGroupTasks = taskArrAll.stream()
.filter(t -> StrUtil.isBlank(t.getString("task_group_id")))
.collect(Collectors.toList());
List<JSONObject> groupTasks = taskArrAll.stream()
.filter(t -> StrUtil.isNotBlank(t.getString("task_group_id")))
.collect(Collectors.toList());
// 找出最早创建的任务组,只下发该组的任务
List<JSONObject> earliestGroupTasks = new ArrayList<>();
if (CollUtil.isNotEmpty(groupTasks)) {
String earliestGroupId = findEarliestGroupId(groupTasks);
if (StrUtil.isNotBlank(earliestGroupId)) {
earliestGroupTasks = groupTasks.stream()
.filter(t -> earliestGroupId.equals(t.getString("task_group_id")))
.collect(Collectors.toList());
}
}
// 合并:无组任务 + 最早组任务
List<JSONObject> tasksToDispatch = new ArrayList<>();
tasksToDispatch.addAll(noGroupTasks);
tasksToDispatch.addAll(earliestGroupTasks);
// 是否下发多个AGV输送出库任务
String is_send_many = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode("is_send_many").getValue();
// 是否异常出库口任务
@@ -182,12 +210,12 @@ public class TwoOutHeapTask extends AbstractAcsTask {
if (TWO_EXCEP.equals(IOSEnum.IS_NOTANDYES.code(""))) {
if (is_send_many.equals(IOSEnum.IS_NOTANDYES.code(""))) {
// 只允许每个行架点位有一条任务
taskArr = sendTask(taskArrAll);
taskArr = sendTask(tasksToDispatch);
} else {
taskArr = taskArrAll;
taskArr = tasksToDispatch;
}
} else {
taskArr = taskArrAll;
taskArr = tasksToDispatch;
}
ArrayList<AcsTaskDto> resultList = new ArrayList<>();
@@ -345,14 +373,43 @@ public class TwoOutHeapTask extends AbstractAcsTask {
}
@Transactional
public void sendTaskAcs(String groupTaskId, boolean retry) { WQLObject wo_Task = WQLObject.getWQLObject("sch_base_task");
public void sendTaskAcs(String groupTaskId, boolean retry) {
WQLObject wo_Task = WQLObject.getWQLObject("sch_base_task");
List<JSONObject> taskArrAll = wo_Task
.query("handle_class = '" + THIS_CLASS + "' and task_status = '" + TaskStatusEnum.START_AND_POINT.getCode() + "' and is_delete ='0' ORDER BY create_time")
.getResultJSONArray(0).toJavaList(JSONObject.class);
// 是否下发多个AGV输送出库任务
if (CollectionUtils.isEmpty(taskArrAll)) {
return;
}
// task_group_id 为空的任务直接下发,不参与分组排序
List<JSONObject> noGroupTasks = taskArrAll.stream()
.filter(t -> StrUtil.isBlank(t.getString("task_group_id")))
.collect(Collectors.toList());
List<JSONObject> groupTasks = taskArrAll.stream()
.filter(t -> StrUtil.isNotBlank(t.getString("task_group_id")))
.collect(Collectors.toList());
// 按任务组串行下发:判断传入的 groupTaskId 是否是最早的任务组
List<JSONObject> earliestGroupTasks = new ArrayList<>();
if (CollUtil.isNotEmpty(groupTasks)) {
String earliestGroupId = findEarliestGroupId(groupTasks);
if (StrUtil.isNotBlank(earliestGroupId)) {
earliestGroupTasks = groupTasks.stream()
.filter(t -> earliestGroupId.equals(t.getString("task_group_id")))
.collect(Collectors.toList());
}
}
// 合并:无组任务 + 当前组任务(如果是最早组)
List<JSONObject> tasksToDispatch = new ArrayList<>();
tasksToDispatch.addAll(noGroupTasks);
tasksToDispatch.addAll(earliestGroupTasks);
if (CollUtil.isEmpty(tasksToDispatch)) {
return;
}
List<JSONObject> taskArr;
// 是否异常出库口任务
String TWO_EXCEP = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode("TWO_EXCEP").getValue();
@@ -360,12 +417,12 @@ public class TwoOutHeapTask extends AbstractAcsTask {
String is_send_many = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode("is_send_many").getValue();
if (is_send_many.equals(IOSEnum.IS_NOTANDYES.code(""))) {
// 只允许每个行架点位有一条任务
taskArr = sendTask(taskArrAll);
taskArr = sendTask(tasksToDispatch);
} else {
taskArr = taskArrAll;
taskArr = tasksToDispatch;
}
} else {
taskArr = taskArrAll;
taskArr = tasksToDispatch;
}
ArrayList<AcsTaskDto> resultList = new ArrayList<>();
@@ -400,4 +457,30 @@ public class TwoOutHeapTask extends AbstractAcsTask {
}
}
}
/**
* 找出任务列表中创建时间最早的任务组ID
*
* @param taskList 待处理任务列表
* @return 最早的任务组ID
*/
private String findEarliestGroupId(List<JSONObject> taskList) {
if (CollUtil.isEmpty(taskList)) {
return null;
}
String earliestGroupId = null;
String earliestCreateTime = null;
for (JSONObject task : taskList) {
String groupId = task.getString("task_group_id");
String createTime = task.getString("create_time");
// 找到最早的创建时间
if (StrUtil.isNotBlank(createTime)) {
if (earliestCreateTime == null || createTime.compareTo(earliestCreateTime) < 0) {
earliestCreateTime = createTime;
earliestGroupId = groupId;
}
}
}
return earliestGroupId;
}
}

View File

@@ -62,13 +62,12 @@ public class TwoOutTask extends AbstractAcsTask {
@Autowired
private MdPdStoragevehicleextMapper mdPdStoragevehicleextMapper;
@Autowired
private AisleConflictHelper aisleConflictHelper;
@Override
public List<AcsTaskDto> addTask() {
AisleConflictHelper aisleConflictHelper = SpringContextHolder.getBean(AisleConflictHelper.class);
/*
* 下发给ACS时需要特殊处理
*/

View File

@@ -23,8 +23,9 @@ public class StructattrQuerry extends PdmBiSubpackagerelation {
private List<String> block_in;
private List<String> row_in;
private List<String> not_block;
}

View File

@@ -184,6 +184,28 @@ public class AisleConflictHelper {
return occupiedAisles.size();
}
/**
* 获取有大托盘出库任务的巷道集合(执行中)
* 包含 TwoOutTask 和 TwoOutEmpTask
*/
public Set<String> getLargePalletOutboundAisles() {
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;
}
/**
* 获取大托盘可用的入库巷道列表(排除有出库任务的巷道)
* 包含 TwoOutTask 和 TwoOutEmpTask
@@ -250,9 +272,11 @@ public class AisleConflictHelper {
return false;
}
} else if (LARGE_PALLET.equals(palletType)) {
int outboundCount = countLargePalletOutboundAisles();
if (outboundCount > 2) {
log.info("大托盘出库巷道数[{}] > 2巷道[{}]出库任务不下发", outboundCount, blockNum);
// 获取当前有出库任务的巷道集合
Set<String> occupiedAisles = getLargePalletOutboundAisles();
// 如果当前巷道不在已出库集合中且已有2个巷道在出库则不下发(保留至少一个巷道能入库)
if (!occupiedAisles.contains(blockNum) && occupiedAisles.size() >= 2) {
log.info("大托盘出库巷道数已达[{}]个,巷道[{}]出库任务不下发(保留至少一个巷道入库)", occupiedAisles.size(), blockNum);
return false;
}
}

View File

@@ -668,7 +668,7 @@ public class InBoxManageServiceImpl implements InBoxManageService {
if (type.length() < 4) {
throw new BadRequestException("入库类型字段长度不能少于4!");
}
param.put("barcode", whereJson.getString("box_no") + "-" + type.substring(3, 4));
param.put("barcode", whereJson.getString("box_no") + "-" + trimLeadingZero(type));
//根据木箱高度,判断入库仓位的高度
String height = "";
@@ -689,6 +689,14 @@ public class InBoxManageServiceImpl implements InBoxManageService {
taskBean.immediateNotifyAcs(null);
}
public static String trimLeadingZero(String numStr) {
// 匹配开头一个或多个0
String result = numStr.replaceFirst("^0+", "");
// 全部都是0的情况返回"0"
return result.isEmpty() ? "0" : result;
}
@Override
@Transactional
public JSONObject taskExceptional(JSONObject jsonObject) {

View File

@@ -114,16 +114,14 @@ public class LashManageServiceImpl implements LashManageService {
@Autowired
private WmsToAcsService wmsToAcsService;
@Override
@Transactional
public void createLashTask(JSONObject whereJson) {
@Transactional(rollbackFor = Exception.class)
void createLashTaskBiz(JSONObject whereJson) throws InterruptedException {
/*
* 1.判断此木箱是否需要堆叠
* 2.插入木箱捆扎绑定表
* 3.生成任务
*/
// 查询木箱信息
RedissonUtils.lock(c->{
BstIvtBoxinfo boxDao = iBstIvtBoxinfoService.getOne(
new QueryWrapper<BstIvtBoxinfo>().lambda()
.eq(BstIvtBoxinfo::getBox_no, whereJson.getString("vehicle_code"))
@@ -286,7 +284,18 @@ public class LashManageServiceImpl implements LashManageService {
twoLashTask.createTask(jsonTaskParam);
//测试屏蔽下发acs
twoLashTask.immediateNotifyAcs(null);
},"createLashTask",5,this,"捆扎任务正在创建中");
}
@Override
@Transactional
public void createLashTask(JSONObject whereJson) {
RedissonUtils.lock(c->{
try {
createLashTaskBiz(whereJson);
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "createLashTask",5,"捆扎任务正在创建中");
}
@Override
@@ -506,7 +515,7 @@ public class LashManageServiceImpl implements LashManageService {
/**
* 校验1125捆扎位是否可以强制离开
*/
private void checkMove() {
private void checkMove() throws InterruptedException {
// 判断1125工位是否有有货
SchBasePoint pointDao = schBasePointMapper.selectOne(
new QueryWrapper<SchBasePoint>().lambda()
@@ -525,6 +534,8 @@ public class LashManageServiceImpl implements LashManageService {
// 如果是空的则下发强制离开
if (ObjectUtil.isEmpty(taskList)) {
Thread.sleep(2000);
WmsToAcsService wmsToAcsService = SpringContextHolder.getBean(WmsToAcsService.class);
JSONArray action_rows = new JSONArray();
JSONObject action_jo = new JSONObject();

View File

@@ -1,26 +1,22 @@
package org.nl.b_lms.storage_manage.ios.service.iostorInv.util.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import jodd.util.StringUtil;
import lombok.extern.log4j.Log4j;
import org.nl.b_lms.pdm.subpackagerelation.dao.mapper.PdmBiSubpackagerelationMapper;
import org.nl.b_lms.storage_manage.ios.enums.IOSEnum;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.dto.StructattrQuerry;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.util.service.TwoInBussManageService;
import org.nl.b_lms.storage_manage.st.dao.StIvtStructattr;
import org.nl.b_lms.storage_manage.st.dao.mapper.StIvtStructattrMapper;
import org.nl.modules.common.exception.BadRequestException;
import org.nl.modules.wql.WQL;
import org.nl.modules.wql.core.bean.WQLObject;
import org.nl.modules.wql.util.SpringContextHolder;
import org.nl.system.service.param.impl.SysParamServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import java.util.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
@Service
@@ -32,18 +28,12 @@ public class TwoInBussManageServiceImpl implements TwoInBussManageService {
*/
private List<String> notInBlockList = new ArrayList<>();
@Autowired
private StIvtStructattrMapper stIvtStructattrMapper;
@Autowired
private PdmBiSubpackagerelationMapper pdmBiSubpackagerelationMapper;
@Override
public JSONObject getOneStruct(JSONObject jsonObject) {
/*
* 成品入库规则:
* 1.根据托盘类型确认巷道小托盘负载均衡到所有巷道,大托盘去大托盘巷道
* 2.负载均衡:相同木箱规格(长宽高)、订单、客户、物料的 平均分配在每个巷道
* 3.相同木箱规格、订单、客户、物料的可以放双伸位即可以放2个木箱
* 1.负载均衡:相同木箱规格(长宽高)、订单、客户、物料的 平均分配在每个巷道
* 2.相同木箱规格、订单、客户、物料的可以放双伸位即可以放2个木箱
* 匹配货位逻辑:
* 1.根据仓库、库区查询所有货位,判断是否有空位
* 2.确定巷道:查看每个巷道相同木箱规格等 的数量,找到数量最小的那个巷道
@@ -61,6 +51,10 @@ public class TwoInBussManageServiceImpl implements TwoInBussManageService {
// 子卷包装关系
WQLObject subTab = WQLObject.getWQLObject("pdm_bi_subpackagerelation");
if (StringUtil.isNotBlank(jsonObject.getString("height")) && !jsonObject.getString("height").contains("(")) {
jsonObject.put("height", "(" + jsonObject.getString("height") + ")");
}
/*
* 判断是否有仓位
* 判断条件:库区、仓库、是否启用、是否删除、未锁定、没有载具
@@ -68,28 +62,28 @@ public class TwoInBussManageServiceImpl implements TwoInBussManageService {
// 是否是移库: 提前确定的巷道
String block_num = jsonObject.getString("move_block_num");
JSONArray attrArry = new JSONArray();
String input = jsonObject.getString("height");
List<String> result = Arrays.asList(input.split(","));
if (ObjectUtil.isEmpty(block_num)) {
attrArry = attrTab.query("IFNULL(storagevehicle_code,'') = '' " +
"AND is_used = '" + IOSEnum.IS_NOTANDYES.code("") + "' AND is_delete = '" + IOSEnum.IS_NOTANDYES.code("") + "' " +
"AND lock_type = '" + IOSEnum.LOCK_TYPE.code("未锁定") + "' AND stor_id = '" + jsonObject.getString("stor_id") + "' " +
"AND storagevehicle_type = '" + jsonObject.getString("vehicle_type") + "'" +
"AND height IN " + jsonObject.getString("height") +
"AND sect_id = '" + jsonObject.getString("sect_id") + "' order by height asc").getResultJSONArray(0);
} else {
attrArry = attrTab.query("IFNULL(storagevehicle_code,'') = '' " +
"AND is_used = '" + IOSEnum.IS_NOTANDYES.code("") + "' AND is_delete = '" + IOSEnum.IS_NOTANDYES.code("") + "' " +
"AND lock_type = '" + IOSEnum.LOCK_TYPE.code("未锁定") + "' AND stor_id = '" + jsonObject.getString("stor_id") + "' " +
"AND storagevehicle_type = '" + jsonObject.getString("vehicle_type") + "'" +
"AND height IN " + jsonObject.getString("height") +
"AND sect_id = '" + jsonObject.getString("sect_id") + "' AND block_num = '"+block_num+"' order by height asc")
.getResultJSONArray(0);
LambdaQueryWrapper<StIvtStructattr> stIvtStructattrLambdaQueryWrapper = new LambdaQueryWrapper<>();
stIvtStructattrLambdaQueryWrapper.eq(StIvtStructattr::getIs_delete, IOSEnum.IS_NOTANDYES.code(""))
.eq(StIvtStructattr::getIs_used, IOSEnum.IS_NOTANDYES.code("")).eq(StIvtStructattr::getSect_id, jsonObject.getString("sect_id"))
.eq(StIvtStructattr::getLock_type, IOSEnum.LOCK_TYPE.code("未锁定")).eq(StIvtStructattr::getStor_id, jsonObject.getString("stor_id"))
.in(StIvtStructattr::getHeight, result)
.orderByAsc(StIvtStructattr::getHeight);
//小托盘均入四个巷道(不分类型),大托盘均入三个巷道
if ("2".equals(jsonObject.getString("vehicle_type"))) {
stIvtStructattrLambdaQueryWrapper.eq(StIvtStructattr::getStoragevehicle_type, "2");
}
if (!ObjectUtil.isEmpty(block_num)) {
stIvtStructattrLambdaQueryWrapper.eq(StIvtStructattr::getBlock_num, block_num);
}
List<StIvtStructattr> stIvtStructattrs = stIvtStructattrMapper.selectList(stIvtStructattrLambdaQueryWrapper);
if (ObjectUtil.isEmpty(stIvtStructattrs)) {
if (ObjectUtil.isEmpty(attrArry)) {
throw new BadRequestException("仓位不足!");
}
@@ -97,25 +91,23 @@ public class TwoInBussManageServiceImpl implements TwoInBussManageService {
* 确定巷道:查看每个巷道相同木箱规格等 的数量,找到数量最小的那个巷道
*/
// 获取木箱入库巷道
StructattrQuerry structattrQuerry = pdmBiSubpackagerelationMapper.selectSubpackagerelationInser( jsonObject.getString("box_no"));
structattrQuerry.setStor_id(jsonObject.getString("stor_id"));
structattrQuerry.setSect_id(jsonObject.getString("sect_id"));
structattrQuerry.setMaterial_id(jsonObject.getString("material_id"));
structattrQuerry.setVehicle_type(jsonObject.getString("vehicle_type"));
structattrQuerry.setHeight(result);
JSONObject jsonSub = subTab.query("package_box_sn = '" + jsonObject.getString("box_no") + "'").uniqueResult(0);
jsonSub.put("stor_id", jsonObject.getString("stor_id"));
jsonSub.put("sect_id", jsonObject.getString("sect_id"));
jsonSub.put("material_id", jsonObject.getString("material_id"));
jsonSub.put("vehicle_type", jsonObject.getString("vehicle_type"));
jsonSub.put("height", jsonObject.getString("height"));
// 不是移库则需要找新巷道
if (ObjectUtil.isEmpty(block_num)) {
block_num = getMinBlock(structattrQuerry);
block_num = getMinBlock(jsonSub);
}
structattrQuerry.setBlock_num(block_num);
jsonSub.put("block_num", block_num);
/*
* 找仓位
*/
JSONObject jsonAttr = getStruct(structattrQuerry);
JSONObject jsonAttr = getStruct(jsonSub);
// 如果是移库空并且仓位为空则报错
if (ObjectUtil.isNotEmpty(jsonObject.getString("move_block_num")) && ObjectUtil.isEmpty(jsonAttr)) {
@@ -125,15 +117,20 @@ public class TwoInBussManageServiceImpl implements TwoInBussManageService {
// 为空则新找巷道
if (ObjectUtil.isEmpty(jsonAttr)) {
notInBlockList.add(structattrQuerry.getBlock_num());
structattrQuerry.setNot_block(notInBlockList);
List<String> block = stIvtStructattrMapper.getBlock(structattrQuerry);
jsonSub.put("flag", "1");
notInBlockList.add(jsonSub.getString("block_num"));
for (int i = 0; i < block.size(); i++) {
String s = block.get(i);
structattrQuerry.setBlock_num(s);
String join = "('" + String.join("','", notInBlockList) + "')";
jsonSub.put("not_block", join);
JSONObject jsonAttr_2 = getStruct(structattrQuerry);
List<JSONObject> blockList = WQL.getWO("BST_INRULE").addParamMap(jsonSub)
.process().getResultJSONArray(0).toJavaList(JSONObject.class);
for (int i = 0; i < blockList.size(); i++) {
JSONObject json = blockList.get(i);
jsonSub.put("block_num",json.getString("block_num"));
JSONObject jsonAttr_2 = getStruct(jsonSub);
if (ObjectUtil.isNotEmpty(jsonAttr_2)) {
jsonAttr = jsonAttr_2;
break;
@@ -151,43 +148,54 @@ public class TwoInBussManageServiceImpl implements TwoInBussManageService {
/**
* 获取最小巷道
*
* @param structattrQuerry {
* jsonSub木箱信息
* sect_id库区
* stor_id仓库
* material_id物料
* }
* @param jsonSub {
* jsonSub木箱信息
* sect_id库区
* stor_id仓库
* material_id物料
* }
* @return String 巷道
*/
private String getMinBlock(StructattrQuerry structattrQuerry) {
private String getMinBlock(JSONObject jsonSub) {
// 获取系统参数不入哪个巷道
String not_in_block_num = SpringContextHolder.getBean(SysParamServiceImpl.class).findByCode("not_in_block_num").getValue();
if (!not_in_block_num.equals(IOSEnum.IS_NOTANDYES.code(""))) {
structattrQuerry.setNot_in_block_num(not_in_block_num);
jsonSub.put("not_in_block_num", not_in_block_num);
}
jsonSub.put("flag", "1");
// 获取仓库、库区有空位的巷道
List<String> block = stIvtStructattrMapper.getBlock(structattrQuerry);
List<JSONObject> blockList = WQL.getWO("BST_INRULE").addParamMap(jsonSub)
.process().getResultJSONArray(0).toJavaList(JSONObject.class);
/*
* 查询所属巷道所有木箱
*/
structattrQuerry.setBlock_in(block);
List<StIvtStructattr> boxAllList = stIvtStructattrMapper.getBoxAllList(structattrQuerry);
String block_in = blockList.stream()
.map(row -> row.getString("block_num"))
.collect(Collectors.joining("','"));
jsonSub.put("flag", "2");
jsonSub.put("block_in", "('" + block_in + "')");
List<JSONObject> boxAllList = WQL.getWO("BST_INRULE").addParamMap(jsonSub)
.process().getResultJSONArray(0).toJavaList(JSONObject.class);
// 为空说明没有木箱,返回最小巷道
if (CollUtil.isEmpty(boxAllList)) {
return block.get(0);
if (ObjectUtil.isEmpty(boxAllList)) {
return blockList.get(0).getString("block_num");
}
// 不区分木箱规格:最小木箱数的巷道
JSONObject jsonBlockMin = sumBlockMinNum(block, boxAllList);
JSONObject jsonBlockMin = sumBlockMinNum(blockList, boxAllList);
/*
* 查询所属巷道所有相同规格的木箱
*/
List<StIvtStructattr> boxAllLikeList = stIvtStructattrMapper.getBoxAllLikeList(structattrQuerry);
jsonSub.put("flag", "3");
List<JSONObject> boxAllLikeList = WQL.getWO("BST_INRULE").addParamMap(jsonSub)
.process().getResultJSONArray(0).toJavaList(JSONObject.class);
// 为空说明库内没有相同规格的木箱,则返回不区分木箱规格的最小巷道
if (ObjectUtil.isEmpty(boxAllLikeList)) {
@@ -195,7 +203,7 @@ public class TwoInBussManageServiceImpl implements TwoInBussManageService {
}
// 区分木箱规格:最小木箱的巷道
JSONObject jsonBlockLikeMin = sumBlockMinNum(block, boxAllLikeList);
JSONObject jsonBlockLikeMin = sumBlockMinNum(blockList, boxAllLikeList);
return jsonBlockLikeMin.getString("block_num");
}
@@ -206,32 +214,35 @@ public class TwoInBussManageServiceImpl implements TwoInBussManageService {
* @param boxAllList: 所有木箱
* @return JSONObject最小木箱数的巷道 JSONObject{block_numbox_num}
*/
private JSONObject sumBlockMinNum(List<String> blockList, List<StIvtStructattr> boxAllList) {
private JSONObject sumBlockMinNum(List<JSONObject> blockList, List<JSONObject> boxAllList) {
// 统计各巷道木箱数
Map<BigDecimal, List<StIvtStructattr>> boxGroupedByBlock = boxAllList.stream()
.collect(Collectors.groupingBy(row -> row.getBlock_num()));
ArrayList<JSONObject> blockBoxList = new ArrayList<>();
for (String jsonBlock : blockList) {
JSONObject jsonObject = new JSONObject();
int count = boxGroupedByBlock.getOrDefault(jsonBlock, Collections.emptyList()).size();
jsonObject.put("box_num", String.valueOf(count));
blockBoxList.add(jsonObject);
for (int i = 0; i < blockList.size(); i++) {
JSONObject jsonBlock = blockList.get(i);
List<JSONObject> box_num = boxAllList.stream()
.filter(row -> row.getString("block_num").equals(jsonBlock.getString("block_num")))
.collect(Collectors.toList());
jsonBlock.put("box_num", String.valueOf(box_num.size()));
blockBoxList.add(jsonBlock);
}
// 获取木箱数最少的巷道
return blockBoxList.stream()
.min(Comparator.comparingInt(row -> Integer.parseInt(row.getString("box_num"))))
.orElse(null);
// 最小木箱数的巷道
List<JSONObject> boxNumList = blockBoxList.stream()
.sorted(Comparator.comparing(row -> row.getIntValue("box_num")))
.collect(Collectors.toList());
return boxNumList.get(0);
}
/**
* 获取一个货位公共方法
*
* @param structattrQuerry {
* @param jsonSub {
* jsonSub木箱信息
* sect_id库区
* stor_id仓库
@@ -241,88 +252,100 @@ public class TwoInBussManageServiceImpl implements TwoInBussManageService {
* }
* @return JSONObject 仓位
*/
private JSONObject getStruct(StructattrQuerry structattrQuerry) {
private JSONObject getStruct(JSONObject jsonSub) {
// 根据巷道找这一巷道相同订单号、物料的仓位
JSONObject jsonLikeBox = queryEqualBox(structattrQuerry);
JSONObject jsonLikeBox = queryEqualBox(jsonSub);
if (ObjectUtil.isNotEmpty(jsonLikeBox)) {
return jsonLikeBox;
}
// 获取此仓库、库区、巷道、排的所有空位 根据列、层、深度排序
List<StIvtStructattr> stIvtStructattrs = stIvtStructattrMapper.getstructRow(structattrQuerry);
jsonSub.put("flag", "55");
List<JSONObject> rowStructList = WQL.getWO("BST_INRULE").addParamMap(jsonSub)
.process().getResultJSONArray(0).toJavaList(JSONObject.class);
// 获取此仓库、库区、巷道、排的所有仓位
List<StIvtStructattr> allStruct = stIvtStructattrMapper.getAllStruct(structattrQuerry);
StIvtStructattr stIvtStructattrReturn = new StIvtStructattr();
for (int i = 0; i < stIvtStructattrs.size(); i++) {
StIvtStructattr stIvtStructattr = stIvtStructattrs.get(i);
jsonSub.put("flag", "66");
List<JSONObject> structAllList = WQL.getWO("BST_INRULE").addParamMap(jsonSub)
.process().getResultJSONArray(0).toJavaList(JSONObject.class);
JSONObject jsonAttr = new JSONObject();
for (int i = 0; i < rowStructList.size(); i++) {
JSONObject json = rowStructList.get(i);
// 判断伸位
if (String.valueOf(stIvtStructattr.getZdepth()).equals(IOSEnum.ZDEPTH_STRUCT.code(""))) {
if (json.getString("zdepth").equals(IOSEnum.ZDEPTH_STRUCT.code(""))) {
// 无需深度
stIvtStructattrReturn = stIvtStructattr;
jsonAttr = json;
break;
} else if (String.valueOf(stIvtStructattr.getZdepth()).equals(IOSEnum.ZDEPTH_STRUCT.code(""))) {
} else if (json.getString("zdepth").equals(IOSEnum.ZDEPTH_STRUCT.code(""))) {
/*
* 深货位:判断浅是否阻挡
*/
// 获取此货位对应的浅货位
List<StIvtStructattr> lowAttr = allStruct.stream()
.filter(row ->String.valueOf(row.getCol_num()).equals(String.valueOf(String.valueOf(stIvtStructattr.getCol_num()))) &&
String.valueOf(row.getLayer_num()).equals(String.valueOf(stIvtStructattr.getLayer_num())) &&
String.valueOf( row.getRow_num()).equals(String.valueOf(stIvtStructattr.getRow_num())) &&
String.valueOf(row.getZdepth()).equals(IOSEnum.ZDEPTH_STRUCT.code(""))).collect(Collectors.toList());
List<JSONObject> lowAttr = structAllList.stream()
.filter(row -> row.getString("col_num").equals(json.getString("col_num")) &&
row.getString("layer_num").equals(json.getString("layer_num")) &&
row.getString("row_num").equals(json.getString("row_num")) &&
row.getString("zdepth").equals(IOSEnum.ZDEPTH_STRUCT.code("")))
.collect(Collectors.toList());
if (ObjectUtil.isEmpty(lowAttr) || lowAttr.size() != 1) {
notInBlockList.clear();
throw new BadRequestException("匹配仓位时:" + stIvtStructattr.getStruct_code() + "对应的浅货位错误!");
throw new BadRequestException("匹配仓位时:" + json.getString("struct_code") + "对应的浅货位错误!");
}
// 判断是否有木箱
StIvtStructattr jsonAttrLow = lowAttr.get(0);
if (ObjectUtil.isEmpty(jsonAttrLow.getStoragevehicle_code()) && jsonAttrLow.getLock_type().equals(IOSEnum.LOCK_TYPE.code("未锁定"))) {
JSONObject jsonAttrLow = lowAttr.get(0);
if (ObjectUtil.isEmpty(jsonAttrLow.getString("storagevehicle_code")) && jsonAttrLow.getString("lock_type").equals(IOSEnum.LOCK_TYPE.code("未锁定"))) {
// 没有木箱
stIvtStructattrReturn = stIvtStructattr;
jsonAttr = json;
break;
} else {
continue;
}
} else if (String.valueOf(stIvtStructattr.getZdepth()).equals(IOSEnum.ZDEPTH_STRUCT.code(""))) {
} else if (json.getString("zdepth").equals(IOSEnum.ZDEPTH_STRUCT.code(""))) {
/*
* 浅货位:判断深货位是否空洞
*/
// 获取此货位对应的深货位
List<StIvtStructattr> darkAttr = allStruct.stream()
.filter(row ->String.valueOf(row.getCol_num()).equals(String.valueOf(stIvtStructattr.getCol_num())) &&
String.valueOf(row.getLayer_num()).equals(String.valueOf(stIvtStructattr.getLayer_num())) &&
String.valueOf( row.getRow_num()).equals(String.valueOf(stIvtStructattr.getRow_num())) &&
String.valueOf(row.getZdepth()).equals(IOSEnum.ZDEPTH_STRUCT.code(""))).collect(Collectors.toList());
List<JSONObject> darkAttr = structAllList.stream()
.filter(row -> row.getString("col_num").equals(json.getString("col_num")) &&
row.getString("layer_num").equals(json.getString("layer_num")) &&
row.getString("row_num").equals(json.getString("row_num")) &&
row.getString("zdepth").equals(IOSEnum.ZDEPTH_STRUCT.code("")))
.collect(Collectors.toList());
if (ObjectUtil.isEmpty(darkAttr) || darkAttr.size() != 1) {
notInBlockList.clear();
throw new BadRequestException("匹配仓位时:" + stIvtStructattr.getStruct_code() + "对应的深货位错误!");
throw new BadRequestException("匹配仓位时:" + json.getString("struct_code") + "对应的深货位错误!");
}
// 判断是否有木箱
StIvtStructattr jsonAttrDark = darkAttr.get(0);
JSONObject jsonAttrDark = darkAttr.get(0);
if (ObjectUtil.isNotEmpty(jsonAttrDark.getStoragevehicle_code())) {
if (ObjectUtil.isNotEmpty(jsonAttrDark.getString("storagevehicle_code"))) {
// 判断是否是成品箱,判断内容:是否空托盘、是否空木箱
if (jsonAttrDark.getIs_vehicle().equals(IOSEnum.IS_NOTANDYES.code("")) ||
jsonAttrDark.getIs_packing().equals(IOSEnum.IS_NOTANDYES.code(""))
if (jsonAttrDark.getString("is_vehicle").equals(IOSEnum.IS_NOTANDYES.code("")) ||
jsonAttrDark.getString("is_packing").equals(IOSEnum.IS_NOTANDYES.code(""))
) {
continue;
}
if (jsonAttrDark.getLock_type().equals(IOSEnum.LOCK_TYPE.code("未锁定"))) {
stIvtStructattrReturn = stIvtStructattr;
if (jsonAttrDark.getString("lock_type").equals(IOSEnum.LOCK_TYPE.code("未锁定"))) {
jsonAttr = json;
break;
} else {
continue;
}
} else {
if (jsonAttrDark.getLock_type().equals(IOSEnum.LOCK_TYPE.code("未锁定"))) {
stIvtStructattrReturn = jsonAttrDark;
if (jsonAttrDark.getString("lock_type").equals(IOSEnum.LOCK_TYPE.code("未锁定"))) {
jsonAttr = jsonAttrDark;
break;
} else {
continue;
@@ -331,64 +354,57 @@ public class TwoInBussManageServiceImpl implements TwoInBussManageService {
}
}
if (ObjectUtil.isEmpty(stIvtStructattrReturn)){
return null;
}else {
JSONObject jsonObject = (JSONObject) JSONObject.toJSON(stIvtStructattrReturn);
return jsonObject;
}
return jsonAttr;
}
/**
* 匹配相同订单、物料的仓位
*
* @param structattrQuerry{子卷包装关系}
* @param jsonSub{子卷包装关系}
* @return JSONObject要入库的仓位
*/
private JSONObject queryEqualBox(StructattrQuerry structattrQuerry) {
private JSONObject queryEqualBox(JSONObject jsonSub) {
// 需要返回的仓位
JSONObject result = new JSONObject();
// 1.匹配相同订单号、物料的排row_num
List<StIvtStructattr> likeOrder = stIvtStructattrMapper.getLikeOrder(structattrQuerry);
StructattrQuerry structattrQuerry2 = new StructattrQuerry();
structattrQuerry2.setBlock_num(structattrQuerry.getBlock_num());
structattrQuerry2.setSect_id(structattrQuerry.getSect_id());
structattrQuerry2.setHeight(structattrQuerry.getHeight());
jsonSub.put("flag", "77");
List<JSONObject> rowList = WQL.getWO("BST_INRULE").addParamMap(jsonSub)
.process().getResultJSONArray(0).toJavaList(JSONObject.class);
// 查询此巷道的所有仓位
List<StIvtStructattr> stIvtStructattrs = stIvtStructattrMapper.getallStruct(structattrQuerry2);
List<JSONObject> attrRowAllList = WQL.getWO("BST_INRULE").addParam("flag", "88")
.addParam("sect_id", jsonSub.getString("sect_id"))
.addParam("block_num", jsonSub.getString("block_num")).process().getResultJSONArray(0).toJavaList(JSONObject.class);
for (StIvtStructattr json : likeOrder) {
for (JSONObject json : rowList) {
// 判断此深仓位是否有货、是否被锁住
if (ObjectUtil.isEmpty(json.getStoragevehicle_code())
|| !json.getLock_type().equals(IOSEnum.LOCK_TYPE.code("未锁定"))
if (ObjectUtil.isEmpty(json.getString("storagevehicle_code"))
|| !json.getString("lock_type").equals(IOSEnum.LOCK_TYPE.code("未锁定"))
) {
continue;
}
// 找对应的浅货位
StIvtStructattr darkJson = stIvtStructattrs.stream()
.filter(row ->String.valueOf(row.getCol_num()).equals(String.valueOf(json.getCol_num())) &&
String.valueOf(row.getLayer_num()).equals(String.valueOf(json.getLayer_num())) &&
String.valueOf( row.getRow_num()).equals(String.valueOf(json.getRow_num())) &&
String.valueOf(row.getZdepth()).equals(IOSEnum.ZDEPTH_STRUCT.code("")))
JSONObject darkJson = attrRowAllList.stream()
.filter(row -> row.getString("col_num").equals(json.getString("col_num")) &&
row.getString("layer_num").equals(json.getString("layer_num")) &&
row.getString("row_num").equals(json.getString("row_num")) &&
row.getString("zdepth").equals(IOSEnum.ZDEPTH_STRUCT.code("")))
.findFirst().orElse(null);
if (ObjectUtil.isEmpty(darkJson)) {
notInBlockList.clear();
throw new BadRequestException("匹配相同木箱规格仓位时:" + darkJson.getStruct_code() + "对应的深货位错误!");
throw new BadRequestException("匹配相同木箱规格仓位时:" + json.getString("struct_code") + "对应的深货位错误!");
}
// 判断浅货位是否有货、未锁定
if (ObjectUtil.isNotEmpty(darkJson.getStoragevehicle_code())
|| !darkJson.getLock_type().equals(IOSEnum.LOCK_TYPE.code("未锁定"))
if (ObjectUtil.isNotEmpty(darkJson.getString("storagevehicle_code"))
|| !darkJson.getString("lock_type").equals(IOSEnum.LOCK_TYPE.code("未锁定"))
) {
continue;
}
JSONObject jsonObject = (JSONObject) JSONObject.toJSON(darkJson);
result = jsonObject;
result = darkJson;
break;
}
return result;

View File

@@ -210,9 +210,6 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
@Autowired
private RedisUtils redisUtils;
@Autowired
private AisleConflictHelper aisleConflictHelper;
/**
* task_id任务标识
@@ -225,6 +222,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
@Override
@SneakyThrows
public Map<String, Object> receiveTaskStatusAcs(String string) {
log.info("acs向lms反馈任务状态请求参数--------------------------------------" + string);
JSONArray array = JSONArray.parseArray(string);
//返回处理失败的任务
@@ -1256,6 +1254,9 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
@SneakyThrows
public JSONObject applyTwo(JSONObject whereJson) {
log.info("applyTwo请求参数---------------------------------------------" + whereJson.toString());
AisleConflictHelper aisleConflictHelper = SpringContextHolder.getBean(AisleConflictHelper.class);
JSONObject result = new JSONObject();
String type = whereJson.getString("type");
RLock lock = redissonClient.getLock("acs_to_wms_two_a:" + type);
@@ -1432,10 +1433,13 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
// 处理分割结果不足的情况
throw new BadRequestException("当前木箱号数据异常!" + box_arr.toString());
}
//退货入库
//获取当前的入库类型
whereJson.put("bill_type", "000" + box_arr[1]);
if(box_arr[1].length() == 2){
whereJson.put("bill_type", "00" + box_arr[1]);
} else {
whereJson.put("bill_type", "000" + box_arr[1]);
}
whereJson.put("box_no", box_arr[0]);
} else {
whereJson.put("bill_type", "0012");
@@ -1469,10 +1473,15 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
.eq("is_delete", "0")
.eq("vehicle_code2", whereJson.getString("vehicle_code"))
.lt("task_status", TaskStatusEnum.FINISHED.getCode()));
if (hasTask > 0) {
if (hasTask > 0) {
throw new BadRequestException("托盘" + whereJson.getString("vehicle_code") + "存在执行的任务");
}
List<MdPdStoragevehicleext> mdPdStoragevehicleext2 = mdPdStoragevehicleextMapper.selectList(new QueryWrapper<MdPdStoragevehicleext>().eq("pcsn", whereJson.getString("box_no")));
if(null != mdPdStoragevehicleext2 && mdPdStoragevehicleext2.size()>1){
throw new BadRequestException("托盘绑定关系异常,请确认输送线传过来的箱号是否匹配!箱号=" + whereJson.getString("box_no"));
}
MdPdStoragevehicleext mdPdStoragevehicleext = mdPdStoragevehicleextMapper.selectOne(new QueryWrapper<MdPdStoragevehicleext>().eq("storagevehicle_code", mdPdStorageVehicleInfo.getStoragevehicle_code()));
if (ObjectUtil.isEmpty(mdPdStoragevehicleext)) {
@@ -1553,6 +1562,11 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
throw new BadRequestException("托盘" + whereJson.getString("vehicle_code") + "存在执行的任务");
}
List<MdPdStoragevehicleext> mdPdStoragevehicleext2 = mdPdStoragevehicleextMapper.selectList(new QueryWrapper<MdPdStoragevehicleext>().eq("pcsn", boxDao.getBox_no()));
if(null != mdPdStoragevehicleext2 && mdPdStoragevehicleext2.size()>1){
throw new BadRequestException("托盘绑定关系异常,请确认输送线传过来的箱号是否匹配!箱号=" + boxDao.getBox_no());
}
MdPdStoragevehicleext mdPdStoragevehicleext = mdPdStoragevehicleextMapper.selectOne(new QueryWrapper<MdPdStoragevehicleext>().eq("storagevehicle_code", mdPdStorageVehicleInfo.getStoragevehicle_code()));
if (ObjectUtil.isEmpty(mdPdStoragevehicleext)) {
@@ -1633,7 +1647,7 @@ public class AcsToWmsServiceImpl implements AcsToWmsService {
// }
JSONObject jsonParam = new JSONObject();
jsonParam.put("task_type", "010713");
jsonParam.put("task_type", "010739");
jsonParam.put("start_device_code",whereJson.getString("device_code"));
jsonParam.put("next_device_code",IOSEnum.TYPE_POINT_CODE.code(whereJson.getString("device_code")));
// jsonParam.put("vehicle_code2",mdPdStorageVehicleInfo.getStoragevehicle_code());

View File

@@ -13,12 +13,17 @@ import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.nl.b_lms.pdm.storagevehicleext.dao.MdPbStoragevehicleext;
import org.nl.b_lms.pdm.storagevehicleext.service.IMdPbStoragevehicleextService;
import org.nl.b_lms.sch.tasks.boxstack.BoxSSXTask;
import org.nl.b_lms.storage_manage.ios.enums.IOSEnum;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.dao.StIvtIostorinv;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.dao.StIvtIostorinvdis;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.dao.mapper.StIvtIostorinvMapper;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.dao.mapper.StIvtIostorinvdisMapper;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.dao.mapper.StIvtIostorinvdtlMapper;
import org.nl.b_lms.storage_manage.md.dao.MdPdStorageVehicleInfo;
import org.nl.b_lms.storage_manage.md.dao.mapper.MdStorageVehicleInfoMapper;
import org.nl.common.utils.SecurityUtils;
import org.nl.modules.common.exception.BadRequestException;
import org.nl.modules.wql.WQL;
@@ -31,12 +36,14 @@ import org.nl.wms.ext.acs.service.impl.AcsToWmsServiceImpl;
import org.nl.wms.ext.acs.service.impl.WmsToAcsServiceImpl;
import org.nl.wms.ext.mes.service.LmsToMesService;
import org.nl.wms.pda.st.service.ProductInstorService;
import org.nl.wms.sch.manage.TaskStatusEnum;
import org.nl.wms.sch.tasks.CutConveyorTask;
import org.nl.wms.st.inbill.service.RawAssistIStorService;
import org.nl.wms.st.inbill.service.StorPublicService;
import org.nl.wms.st.inbill.service.impl.InbillServiceImpl;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@@ -73,6 +80,13 @@ public class ProductInstorServiceImpl implements ProductInstorService {
private final StIvtIostorinvdisMapper stIvtIostorinvdisMapper;
private final StIvtIostorinvdtlMapper stIvtIostorinvdtlMapper;
private final MdStorageVehicleInfoMapper mdStorageVehicleInfoMapper;
private final IMdPbStoragevehicleextService mdPbStoragevehicleextService;
@Autowired
private BoxSSXTask boxSSXTask;
@Override
public JSONObject boxQuery(JSONObject whereJson) {
String box_no = whereJson.getString("box_no");
@@ -231,15 +245,15 @@ public class ProductInstorServiceImpl implements ProductInstorService {
if (NumberUtil.sub(box_weight, weight_sys) <= real_weight && NumberUtil.add(box_weight, weight_sys) >= real_weight) {
} else {
//调用ACS让对应蜂鸣器报警
JSONObject param = new JSONObject();
param.put("code", "to_command");
param.put("product_area", "LK");
param.put("value", "99");
param.put("device_code", point_code);
JSONArray rows = new JSONArray();
rows.add(param);
WmsToAcsService wmsToAcsService = SpringContextHolder.getBean(WmsToAcsService.class);
wmsToAcsService.action(rows);
// JSONObject param = new JSONObject();
// param.put("code", "to_command");
// param.put("product_area", "LK");
// param.put("value", "99");
// param.put("device_code", point_code);
// JSONArray rows = new JSONArray();
// rows.add(param);
// WmsToAcsService wmsToAcsService = SpringContextHolder.getBean(WmsToAcsService.class);
// wmsToAcsService.action(rows);
//判断is_pass是否为空如果为空则通知飞书不为空判断为0则不允许通过为1则允许
if (ObjectUtil.isEmpty(sub_jo.getString("is_pass")) || sub_jo.getString("is_pass").equals(IOSEnum.IS_NOTANDYES.code("")) ) {
@@ -347,7 +361,7 @@ public class ProductInstorServiceImpl implements ProductInstorService {
.intValue();
if (num <= (Integer.parseInt(download_attr_num) * 2)) {
throw new BadRequestException("2、3层立库主存区仓位数不足" + download_attr_num + "个,不允许入库!");
throw new BadRequestException("2层立库主存区仓位数不足" + download_attr_num + "个,不允许入库!");
}
}
@@ -361,23 +375,50 @@ public class ProductInstorServiceImpl implements ProductInstorService {
if ("1".equals(point_jo.getString("is_delete"))) {
throw new BadRequestException("该点位已经被删除!");
}
if (!"NBJ01".equals(point_jo.getString("region_code"))) {
throw new BadRequestException("请扫描内包间入库点位!");
}
}
//创建二楼去一楼的任务
JSONObject form = new JSONObject();
form.put("point_code1", point_code);
if (point_code.startsWith("N")) {
form.put("point_code2", "N1001");
String start_device_code = "";
if ("RK2009".equals(point_code)) {
start_device_code = "RK2026";
} else if ("RK2005".equals(point_code)) {
start_device_code = "RK2027";
} else if ("RK2008".equals(point_code)) {
start_device_code = "RK2028";
} else {
form.put("point_code2", "S1001");
throw new BadRequestException("请输入正确的点位!");
}
form.put("vehicle_code", box_no);
form.put("task_type", "010507");
cutConveyorTask.createTask(form);
MdPbStoragevehicleext ext_jo = mdPbStoragevehicleextService.getOne(new QueryWrapper<MdPbStoragevehicleext>().lambda().eq(MdPbStoragevehicleext::getPcsn, box_no));
if(null == ext_jo) {
throw new BadRequestException("木箱和托盘未绑定,请进行绑定!");
}
MdPdStorageVehicleInfo mdPdStorageVehicleInfo = mdStorageVehicleInfoMapper.selectOne(new QueryWrapper<MdPdStorageVehicleInfo>().eq("storagevehicle_code", ext_jo.getStoragevehicle_code()));
if (ObjectUtil.isEmpty(mdPdStorageVehicleInfo)) {
throw new BadRequestException("载具不存在!");
}
whereJson.put("vehicle_code",mdPdStorageVehicleInfo.getStoragevehicle_code());
JSONObject param = new JSONObject();
param.put("type", "4");
param.put("container_type", mdPdStorageVehicleInfo.getStoragevehicle_type().substring(mdPdStorageVehicleInfo.getStoragevehicle_type().length() - 1));
param.put("material_barcode", whereJson.getString("box_no") + "-" + whereJson.getString("bill_type").replace("0", ""));
param.put("barcode", whereJson.getString("vehicle_code"));
param.put("isUncap","1");
JSONObject jsonParam = new JSONObject();
jsonParam.put("start_device_code", start_device_code);
jsonParam.put("next_device_code", "RK2011");
jsonParam.put("vehicle_code2", whereJson.getString("box_no"));
jsonParam.put("vehicle_code", mdPdStorageVehicleInfo.getStoragevehicle_code());
jsonParam.put("task_status", TaskStatusEnum.START_AND_POINT.getCode());
jsonParam.put("task_type", "010713");
jsonParam.put("request_param", param.toString());
boxSSXTask.createTask(jsonParam);
boxSSXTask.immediateNotifyAcs(null);
} else {
JSONArray now_dis_rows = WQL.getWO("QST_IVT_RAWASSISTISTOR").addParam("flag", "18").addParam("box_no", map.get("box_no")).process().getResultJSONArray(0);

View File

@@ -269,7 +269,7 @@
is_used = '1'
AND is_delete = '0'
AND lock_type = '1'
AND sect_code = 'ZC01'
AND sect_code = 'BZC01'
AND IFNULL(storagevehicle_code,'') = ''
OPTION 输入.layer_num <> ""
@@ -282,4 +282,4 @@
ENDSELECT
ENDQUERY
ENDIF
ENDIF

View File

@@ -8,16 +8,12 @@ import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.nl.b_lms.sch.task.dao.SchBaseTask;
import org.nl.b_lms.sch.task.dao.mapper.SchBaseTaskMapper;
import org.nl.b_lms.sch.tasks.TwoOutHeapTask;
import org.nl.common.utils.CollectionUtils;
import org.nl.modules.wql.util.SpringContextHolder;
import org.nl.system.service.param.impl.SysParamServiceImpl;
import org.nl.wms.sch.AcsTaskDto;
import org.nl.wms.sch.AcsUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;