opt: 空盘优先到入库点、最后一根轴竞争问题

This commit is contained in:
2025-11-10 15:25:07 +08:00
parent 51f58c3bdf
commit 7c238dac1a
7 changed files with 146 additions and 13 deletions

View File

@@ -75,6 +75,13 @@ public interface IBstIvtStockingivtService extends IService<BstIvtStockingivt> {
* @return /
*/
List<BstIvtStockingivt> getEmptyPointNotTask(String location, String pointType);
/**
* 获取备货区空位,没有任务的位置
* @param location 位置0上区域1下区域
* @param pointType [] 类型0暂存位置1靠近分切机
* @return /
*/
List<BstIvtStockingivt> getEmptyPointNotTask2(String location, List<String> pointType);
/**
* 根据点位编码获取备货区点位

View File

@@ -34,6 +34,8 @@ public interface BstIvtStockingivtMapper extends BaseMapper<BstIvtStockingivt> {
*/
List<BstIvtStockingivt> getEmptyPointNotTask(String location, String pointType);
List<BstIvtStockingivt> getEmptyPointNotTask2(String location, List<String> pointTypes);
BstIvtStockingivt getCanMovePointOne(String location, String pointType);
/**

View File

@@ -160,4 +160,22 @@
GROUP BY
bs.point_code;
</select>
<select id="getEmptyPointNotTask2"
resultType="org.nl.b_lms.bst.ivt.stockingivt.service.dao.BstIvtStockingivt">
SELECT bs.*
FROM `bst_ivt_stockingivt` bs
WHERE bs.point_location = #{location}
AND bs.is_used = '1'
AND bs.ivt_status = '0'
AND bs.point_type IN
<foreach item="code" collection="pointTypes" open="(" separator="," close=")">
#{code}
</foreach>
AND 0 = (SELECT COUNT(*)
FROM sch_base_task t
WHERE (t.point_code1 = bs.point_code OR t.point_code2 = bs.point_code OR
t.point_code3 = bs.point_code OR t.point_code4 = bs.point_code)
AND t.task_status <![CDATA[ < ]]> '07')
ORDER BY bs.point_type DESC
</select>
</mapper>

View File

@@ -119,6 +119,11 @@ public class BstIvtStockingivtServiceImpl extends ServiceImpl<BstIvtStockingivtM
return bstIvtStockingivtMapper.getEmptyPointNotTask(location, pointType);
}
@Override
public List<BstIvtStockingivt> getEmptyPointNotTask2(String location, List<String> pointType) {
return bstIvtStockingivtMapper.getEmptyPointNotTask2(location, pointType);
}
@Override
public BstIvtStockingivt getPointByCode(String pointCode, boolean flag) {
LambdaQueryWrapper<BstIvtStockingivt> lam = new LambdaQueryWrapper<>();

View File

@@ -94,6 +94,7 @@ public class TrussCallShaftCacheTask extends AbstractAcsTask {
endPointObj.setHave_qzz("1");
endPointObj.setPlan("");
TaskUtils.updateOptMessageByBShaftPoint(endPointObj);
shafttubeivtService.updateById(endPointObj);
}

View File

@@ -34,6 +34,7 @@ import org.nl.b_lms.sch.tasks.slitter.mapper.dto.BhTubeMovePointDto;
import org.nl.b_lms.sch.tasks.slitter.mapper.dto.BhTubePointDto;
import org.nl.b_lms.sch.tasks.slitter.mapper.dto.SlitterPlanDistinctDto;
import org.nl.b_lms.sch.tasks.slitter.util.SlitterTaskUtil;
import org.nl.b_lms.storage_manage.ios.enums.IOSEnum;
import org.nl.common.enums.NoticeTypeEnum;
import org.nl.common.utils.TaskUtils;
import org.nl.modules.common.exception.BadRequestException;
@@ -315,14 +316,15 @@ public class AutoCallAirShaftTask extends Prun {
stepErrorInfo.add("没有套轴暂存位没有相同规格的气胀轴来拔轴,直接去气胀轴库获取。");
//若套轴暂存位没有相同规格的气胀轴,直接去气胀轴库找即可
// 调用ACS滚条气涨轴下来
if (!toAcsOutShaft(needPlans, plans, qzzSize, location, empty)) {
String callOutStatus = toAcsOutShaft(needPlans, plans, qzzSize, location, empty);
if ("0".equals(callOutStatus)) {
log.error("呼叫出轴失败-穿拔轴{}不进行套轴,跳过!", empty.getPoint_code());
stepErrorInfo.add("呼叫出轴失败-穿拔轴" + empty.getPoint_code() + "不进行套轴,直接做拔轴!");
makePullShaft(empty, specification);
return;
}
// 保存所需要的分切计划数据到点位上(套轴对接位)更新分切计划
saveCutPlanMessage(empty, needPlans, qzzSize);
saveCutPlanMessage(empty, needPlans, qzzSize, callOutStatus);
// toCallAgvMovePaperTube(needPlans, location, empty, plans);
return;
}
@@ -371,7 +373,7 @@ public class AutoCallAirShaftTask extends Prun {
return;
}
// 保存所需要的分切计划数据到点位上(套轴对接位)更新分切计划
saveCutPlanMessage(empty, needPlans, qzzSize);
saveCutPlanMessage(empty, needPlans, qzzSize, "0");
SlitterTaskUtil.putCurrentPaperSpec(param, oldPlans);
// 套管数量
param.put("casingCount", needPlans.size());
@@ -807,24 +809,25 @@ public class AutoCallAirShaftTask extends Prun {
* @param qzzSize 气涨轴尺寸
* @param location 位置:上半部分还是下半部分
* @param empty 套拔轴点位
* @return 0: 呼叫失败1呼叫成功2该点位需要从密集库获取
*/
private Boolean toAcsOutShaft(List<PdmBiSlittingproductionplan> needPlans, List<SlitterPlanDistinctDto> plans, String qzzSize, String location, BstIvtShafttubeivt empty) {
private String toAcsOutShaft(List<PdmBiSlittingproductionplan> needPlans, List<SlitterPlanDistinctDto> plans, String qzzSize, String location, BstIvtShafttubeivt empty) {
Integer movePaperTube = toCallAgvMovePaperTube(needPlans, location, empty, plans);
if (movePaperTube == 2) {
log.info("跳过,无法更换托盘。");
stepErrorInfo.add("呼叫AGV更换托盘失败无法更换托盘。");
return false;
return "0";
}
if (movePaperTube != 0) {
skipTheSameTubePlans(needPlans);
return false;
return "0";
}
// 需要区分上下
List<BstIvtShafttubeivt> shafttubeivts = bstIvtShafttubeivtService.getByQzzSize(qzzSize, empty.getPoint_code(), location);
if (shafttubeivts.size() == 0) {
log.error("气胀轴库找不到[" + qzzSize + "]规格的气涨轴位");
stepErrorInfo.add("气胀轴库找不到[" + qzzSize + "]规格的气涨轴位");
return false;
return "0";
}
// 气涨轴库
BstIvtShafttubeivt shafttubeivt = shafttubeivts.get(0);
@@ -839,9 +842,9 @@ public class AutoCallAirShaftTask extends Prun {
if (ObjectUtil.isEmpty(pointStatus) || ObjectUtil.isEmpty(pointStatus.getJSONArray("data"))) {
log.error("获取气胀轴库信息失败");
stepErrorInfo.add("获取ACS气胀轴库信息失败...");
return false;
return "0";
}
boolean judgment1 = true;
boolean judgment1 = false;
boolean judgment2 = true;
// 获取气涨轴缓存没有任务的点位
List<BstIvtShafttubeivt> qzzCache = bstIvtShafttubeivtService.getNotTaskShaftCache(qzzSize,
@@ -849,6 +852,58 @@ public class AutoCallAirShaftTask extends Prun {
if (qzzCache.size() == 0) {
log.warn("未找到气胀轴密集库气涨轴规格「" + qzzSize + "」的暂存位");
judgment2 = false;
} else {
// 查找正在进行的取货点任务(未确定取货位)
LambdaQueryWrapper<SchBaseTask> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.lt(SchBaseTask::getTask_status, TaskStatusEnum.FINISHED.getCode());
queryWrapper.eq(SchBaseTask::getIs_delete, IOSEnum.IS_NOTANDYES.code(""));
queryWrapper.in(SchBaseTask::getTask_type,
Arrays.asList(SlitterEnum.TASK_TYPE.code("穿拔轴位<>气胀轴缓存位"),
SlitterEnum.TASK_TYPE.code("人工叫空轴桁架任务")));
queryWrapper.likeRight(SchBaseTask::getPoint_code1, "B_QHD");
List<SchBaseTask> baseTasks = taskService.list(queryWrapper);
if (baseTasks.size() > 0) {
// 过滤
List<SchBaseTask> collect = baseTasks.stream().filter(task -> {
if (ObjectUtil.isNotEmpty(task.getPoint_code3())) {
JSONObject object = JSONObject.parseObject(task.getRequest_param());
if (ObjectUtil.isEmpty(object)) {
return false;
}
String size = object.getString("qzz_size");
String generation = object.getString("qzz_generation");
return "6".equals(qzzSize)
? qzzSize.equals(size)
: qzzSize.equals(size) && empty.getQzz_generation().equals(generation);
}
BstIvtShafttubeivt cbzj = bstIvtShafttubeivtService.getByPointCode(task.getPoint_code2(), false);
if (ObjectUtil.isEmpty(cbzj)) {
return false;
}
return "6".equals(qzzSize)
? qzzSize.equals(cbzj.getQzz_size())
: qzzSize.equals(cbzj.getQzz_size()) && empty.getQzz_generation().equals(cbzj.getQzz_generation());
}).collect(Collectors.toList());
if (collect.size() > 0) {
if (qzzCache.size() - collect.size() <= 0) {
log.warn("未找到气胀轴密集库气涨轴规格「" + qzzSize + "」的暂存位");
judgment2 = false;
}
}
} else {
// 查看另一台机构的尺寸是否一致plan是否为2
BstIvtShafttubeivt one = bstIvtShafttubeivtService.getOne(new LambdaQueryWrapper<BstIvtShafttubeivt>()
.ne(BstIvtShafttubeivt::getPoint_code, empty.getPoint_code())
.eq(BstIvtShafttubeivt::getPoint_location, empty.getPoint_location())
.eq(BstIvtShafttubeivt::getPoint_type, empty.getPoint_type())
.eq(BstIvtShafttubeivt::getIs_used, "1"));
if (ObjectUtil.isNotEmpty(one.getPlan()) && "2".equals(one.getPlan())) {
if (qzzSize.equals(one.getQzz_size()) && "6".equals(qzzSize)) {
judgment2 = (qzzCache.size() - 1) > 0;
}
}
}
// todo: 检查正在进行的放货点任务(已经确定放货位)[先不要考虑]
}
JSONObject data2 = pointStatus.getJSONArray("data").getJSONObject(0);
if (data2.getInteger("qty") == 0) {
@@ -858,7 +913,7 @@ public class AutoCallAirShaftTask extends Prun {
if (!judgment1 && !judgment2) {
log.warn("没有气胀轴不给ACS写出轴信息");
stepErrorInfo.add("呼叫气胀轴失败,(密集库/暂存架)没有" + qzzSize + "寸的气胀轴不给ACS写出轴信息。请人工补轴或将对应的分切计划点击入站完成");
return false;
return "0";
}
// 判断气胀轴密集库是否有数据
JSONArray acsParam = new JSONArray();
@@ -872,7 +927,7 @@ public class AutoCallAirShaftTask extends Prun {
log.info("开始给ACS写信号出气胀轴 - {}", acsQzz);
JSONObject action = wmsToAcsService.action(acsParam);
log.info("下发给ACS写信号出气涨轴返回参数{}", action);
return true;
return judgment1 ? "1" : "2";
}
/**
@@ -906,7 +961,7 @@ public class AutoCallAirShaftTask extends Prun {
* @param needPlans 需要的分切计划
* @param qzzSize 气涨轴尺寸
*/
private void saveCutPlanMessage(BstIvtShafttubeivt empty, List<PdmBiSlittingproductionplan> needPlans, String qzzSize) {
private void saveCutPlanMessage(BstIvtShafttubeivt empty, List<PdmBiSlittingproductionplan> needPlans, String qzzSize, String remark) {
log.info("正在保存套轴信息 - {} , 尺寸 - {} 到点位 - {}", needPlans, qzzSize, empty);
empty.setHave_qzz(SlitterConstant.SLITTER_YES);
empty.setQzz_size(qzzSize);
@@ -934,6 +989,7 @@ public class AutoCallAirShaftTask extends Prun {
empty.setContainer_name2(plan.getContainer_name());
}
}
empty.setPlan(remark);
bstIvtShafttubeivtService.updateById(empty);
// 分切计划
// 将分切计划is_paper_ok 1(准备好纸管) -> 2(套好气胀轴)
@@ -1021,6 +1077,7 @@ public class AutoCallAirShaftTask extends Prun {
/**
* 检测气胀轴密集库/气胀轴缓存库有没有空位
*
* @param empty
* @param specification
* @param plan

View File

@@ -3,6 +3,7 @@ package org.nl.b_lms.sch.tasks.slitter.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import org.nl.b_lms.storage_manage.ios.enums.IOSEnum;
import org.nl.common.utils.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
@@ -1055,7 +1056,7 @@ public class SlitterServiceImpl implements SlitterService {
List<SchBaseTask> tasks = taskService.checkHaveTask(deviceCode);
if (CollectionUtil.isEmpty(tasks)) {
// 查找一个没有任务的空位
List<BstIvtStockingivt> list = stockingivtService.getEmptyPointNotTask(device.getPoint_location(), "0");
List<BstIvtStockingivt> list = stockingivtService.getEmptyPointNotTask2(device.getPoint_location(), Arrays.asList("0", "2"));
if (list.size() == 0) {
noticeService.createNotice("备货区找不到空位置搬运",
"备货区" + deviceCode + "异常",
@@ -1132,6 +1133,7 @@ public class SlitterServiceImpl implements SlitterService {
shaftPoint.setContainer_name1("");
shaftPoint.setContainer_name2("");
shaftPoint.setQzz_size("");
shaftPoint.setPlan("");
TaskUtils.updateOptMessageByBShaftPoint(shaftPoint);
shafttubeivtService.update(shaftPoint);
// 初始化 预分配点位
@@ -3048,6 +3050,7 @@ public class SlitterServiceImpl implements SlitterService {
}
@Override
@Transactional(rollbackFor = Exception.class)
public JSONObject callShaft(JSONObject param) {
// area、point_code、row(size,generation)
log.info("呼叫空轴:{}", param);
@@ -3104,6 +3107,46 @@ public class SlitterServiceImpl implements SlitterService {
if (shafttubeivts.size() == 0) {
throw new BadRequestException("没有气胀轴尺寸[" + rowJSONObject.getString("size") + "],代数["
+ rowJSONObject.getString("generation") + "]的库存!");
} else {
// 查找正在进行的取货点任务(未确定取货位)
LambdaQueryWrapper<SchBaseTask> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.lt(SchBaseTask::getTask_status, TaskStatusEnum.FINISHED.getCode());
queryWrapper.eq(SchBaseTask::getIs_delete, IOSEnum.IS_NOTANDYES.code(""));
queryWrapper.in(SchBaseTask::getTask_type,
Arrays.asList(SlitterEnum.TASK_TYPE.code("穿拔轴位<>气胀轴缓存位"),
SlitterEnum.TASK_TYPE.code("人工叫空轴桁架任务")));
queryWrapper.likeRight(SchBaseTask::getPoint_code1, "B_QHD");
List<SchBaseTask> baseTasks = taskService.list(queryWrapper);
if (baseTasks.size() > 0) {
// 过滤
List<SchBaseTask> collect = baseTasks.stream().filter(task -> {
if (ObjectUtil.isNotEmpty(task.getPoint_code3())) {
JSONObject object = JSONObject.parseObject(task.getRequest_param());
if (ObjectUtil.isEmpty(object)) {
return false;
}
String size = object.getString("qzz_size");
String generation = object.getString("qzz_generation");
return "6".equals(rowJSONObject.getString("size"))
? rowJSONObject.getString("size").equals(size)
: rowJSONObject.getString("size").equals(size) && rowJSONObject.getString("generation").equals(generation);
}
BstIvtShafttubeivt cbzj = shafttubeivtService.getByPointCode(task.getPoint_code2(), false);
if (ObjectUtil.isEmpty(cbzj)) {
return false;
}
return "6".equals(rowJSONObject.getString("size"))
? rowJSONObject.getString("size").equals(cbzj.getQzz_size())
: rowJSONObject.getString("size").equals(cbzj.getQzz_size()) && rowJSONObject.getString("generation").equals(cbzj.getQzz_generation());
}).collect(Collectors.toList());
if (collect.size() > 0) {
if (shafttubeivts.size() - collect.size() <= 0) {
throw new BadRequestException("气胀轴尺寸[" + rowJSONObject.getString("size") + "],代数["
+ rowJSONObject.getString("generation") + "]的库存不满足!");
}
}
}
// todo: 检查正在进行的放货点任务(已经确定放货位)[先不要考虑]
}
// 创建桁架任务(二次分配)
JSONObject taskParam = new JSONObject();