fix: 套轴时间排序、AGV换托盘

opt: 下卷校验上下轴
fix: 下卷任务校验
feat: 管芯托盘界面查看
This commit is contained in:
2025-03-20 13:53:55 +08:00
parent e83dfde69e
commit 459bd30d25
27 changed files with 701 additions and 41 deletions

View File

@@ -67,5 +67,12 @@ public class BstIvtStockingivtController {
return new ResponseEntity<>(bstIvtStockingivtService.operateIvt(param), HttpStatus.OK);
}
@Log("管芯托盘库存")
//@SaCheckPermission("@el.check('bstIvtStockingivt:del')")
@PostMapping("/showDetail")
public ResponseEntity<Object> showDetail(@RequestBody JSONObject param) {
return new ResponseEntity<>(bstIvtStockingivtService.showDetail(param), HttpStatus.OK);
}
}

View File

@@ -2,6 +2,9 @@ package org.nl.b_lms.bst.ivt.stockingivt.service;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.nl.b_lms.bst.ivt.stockingivt.service.dto.ShowStockVo;
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.common.domain.query.PageQuery;
import com.baomidou.mybatisplus.extension.service.IService;
import org.nl.b_lms.bst.ivt.stockingivt.service.dao.BstIvtStockingivt;
@@ -78,4 +81,23 @@ public interface IBstIvtStockingivtService extends IService<BstIvtStockingivt> {
BstIvtStockingivt getCanMovePointOne(String location, String pointType);
JSONObject operateIvt(JSONObject jsonObject) ;
/**
* 分组聚合获取需要管芯的托盘位置
* @param pointType
* @param tube
* @param location
* @return
*/
List<BhTubePointDto> getNeedPaperTubePoint(String pointType, String tube, String location);
/**
* 获取3个托盘的数据
* @param location
* @param pointType
* @return
*/
List<BhTubeMovePointDto> getCanMovePointList(String location, String pointType);
List<List<ShowStockVo>> showDetail(JSONObject param);
}

View File

@@ -2,6 +2,8 @@ package org.nl.b_lms.bst.ivt.stockingivt.service.dao.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.nl.b_lms.bst.ivt.stockingivt.service.dao.BstIvtStockingivt;
import org.nl.b_lms.sch.tasks.slitter.mapper.dto.BhTubeMovePointDto;
import org.nl.b_lms.sch.tasks.slitter.mapper.dto.BhTubePointDto;
import java.util.List;
@@ -29,4 +31,15 @@ public interface BstIvtStockingivtMapper extends BaseMapper<BstIvtStockingivt> {
List<BstIvtStockingivt> getEmptyPointNotTask(String location, String pointType);
BstIvtStockingivt getCanMovePointOne(String location, String pointType);
/**
* 分组聚合获取备货区中数量够用的的货位
* @param pointType 类型0暂存位置1靠近分切机
* @param tube 纸管号 两个都是一样的,因此拿一个就行
* @param location 位置0上区域1下区域
* @return /
*/
List<BhTubePointDto> getNeedPaperTubePoint(String pointType, String tube, String location);
List<BhTubeMovePointDto> getCanMovePointList(String location, String pointType);
}

View File

@@ -12,7 +12,7 @@
AND bs.ivt_status = '1'
AND bs.is_used = '1'
AND mp.material_code = #{tube}
AND mp.qty <![CDATA[ >= ]]> #{qty}
AND mp.qty <![CDATA[ > ]]> #{qty}
AND 0 = (SELECT COUNT(*)
FROM sch_base_task t
WHERE (t.point_code1 = bs.point_code OR t.point_code2 = bs.point_code OR
@@ -48,4 +48,46 @@
AND t.task_status <![CDATA[ < ]]> '07')
ORDER BY bs.ivt_status, mp.qty LIMIT 1
</select>
<select id="getNeedPaperTubePoint" resultType="org.nl.b_lms.sch.tasks.slitter.mapper.dto.BhTubePointDto">
SELECT bs.point_code,
MAX(bs.vehicle_code) AS vehicle_code,
SUM(mp.qty) AS qty
FROM `bst_ivt_stockingivt` bs
LEFT JOIN
md_pb_papervehicle mp
ON mp.vehicle_code = bs.vehicle_code
WHERE bs.point_location = #{location}
AND bs.point_type = #{pointType}
AND bs.ivt_status = '1'
AND bs.is_used = '1'
AND mp.material_code = #{tube}
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)
AND t.task_status <![CDATA[ < ]]> '07')
GROUP BY bs.point_code;
</select>
<select id="getCanMovePointList" resultType="org.nl.b_lms.sch.tasks.slitter.mapper.dto.BhTubeMovePointDto">
SELECT bs.point_code,
MAX(bs.vehicle_code) AS vehicle_code,
MAX(bs.ivt_status) AS ivt_status,
IFNULL(SUM(mp.qty), 0) AS qty
FROM `bst_ivt_stockingivt` bs
LEFT JOIN
md_pb_papervehicle mp
ON mp.vehicle_code = bs.vehicle_code
WHERE bs.point_type = '1'
AND bs.point_location = '0'
AND bs.is_used = '1'
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)
AND t.task_status <![CDATA[ < ]]> '07')
GROUP BY bs.point_code
ORDER BY ivt_status ASC,
qty ASC;
</select>
</mapper>

View File

@@ -0,0 +1,20 @@
package org.nl.b_lms.bst.ivt.stockingivt.service.dto;
import lombok.Data;
/**
* @Author: lyd
* @Date: 2025/3/20
*/
@Data
public class ShowStockVo {
/**
* 0: 空, 1空位2管芯
*/
private String have_qzz;
/**
* 管芯信息
*/
private String tube;
}

View File

@@ -2,19 +2,19 @@ package org.nl.b_lms.bst.ivt.stockingivt.service.impl;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.nl.b_lms.bst.ivt.papervehicle.service.IMdPbPapervehicleService;
import org.nl.b_lms.bst.ivt.papervehicle.service.dao.MdPbPapervehicle;
import org.nl.b_lms.bst.ivt.stockingivt.service.dto.ShowStockVo;
import org.nl.b_lms.sch.tasks.slitter.constant.SlitterConstant;
import org.nl.b_lms.sch.tasks.slitter.service.SlitterService;
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.util.SlitterTaskUtil;
import org.nl.modules.common.exception.BadRequestException;
import org.nl.common.domain.query.PageQuery;
@@ -46,7 +46,7 @@ public class BstIvtStockingivtServiceImpl extends ServiceImpl<BstIvtStockingivtM
@Autowired
private BstIvtStockingivtMapper bstIvtStockingivtMapper;
@Autowired
private IMdPbPapervehicleService PapervehicleService;
private IMdPbPapervehicleService papervehicleService;
@Autowired
private WmsToAcsService wmsToAcsService;
@Autowired
@@ -163,7 +163,7 @@ public class BstIvtStockingivtServiceImpl extends ServiceImpl<BstIvtStockingivtM
String material_name = mater.getMaterial_name();
//查询当前载具和排是否存在库存
MdPbPapervehicle papervehicle = PapervehicleService.getOne(new LambdaQueryWrapper<MdPbPapervehicle>().eq(MdPbPapervehicle::getVehicle_code, vehicle_code)
MdPbPapervehicle papervehicle = papervehicleService.getOne(new LambdaQueryWrapper<MdPbPapervehicle>().eq(MdPbPapervehicle::getVehicle_code, vehicle_code)
.eq(MdPbPapervehicle::getRow_num, row_num));
if (ObjectUtil.isNotEmpty(papervehicle) && !papervehicle.getMaterial_code().equals(material_code)) {
throw new BadRequestException("当前排物料为【" + papervehicle.getMaterial_code() + "】,与绑定的物料不同,如需要请先清除库存,再进行绑定!");
@@ -180,7 +180,7 @@ public class BstIvtStockingivtServiceImpl extends ServiceImpl<BstIvtStockingivtM
if (num == 1) {
//只判断第二排的纸管长度
int nextNum = num + 1;
MdPbPapervehicle nextPaper = PapervehicleService.getOne(new LambdaQueryWrapper<MdPbPapervehicle>().eq(MdPbPapervehicle::getVehicle_code, vehicle_code)
MdPbPapervehicle nextPaper = papervehicleService.getOne(new LambdaQueryWrapper<MdPbPapervehicle>().eq(MdPbPapervehicle::getVehicle_code, vehicle_code)
.eq(MdPbPapervehicle::getRow_num, nextNum));
if (ObjectUtil.isNotEmpty(nextPaper)) {
//获取第二排的纸管高度和纸管类型
@@ -194,7 +194,7 @@ public class BstIvtStockingivtServiceImpl extends ServiceImpl<BstIvtStockingivtM
} else {
//判断后一排的纸管高度
int nextNum = num + 1;
MdPbPapervehicle nextPaper = PapervehicleService.getOne(new LambdaQueryWrapper<MdPbPapervehicle>().eq(MdPbPapervehicle::getVehicle_code, vehicle_code)
MdPbPapervehicle nextPaper = papervehicleService.getOne(new LambdaQueryWrapper<MdPbPapervehicle>().eq(MdPbPapervehicle::getVehicle_code, vehicle_code)
.eq(MdPbPapervehicle::getRow_num, nextNum));
if (ObjectUtil.isNotEmpty(nextPaper)) {
//获取后一排的纸管高度和纸管类型
@@ -208,7 +208,7 @@ public class BstIvtStockingivtServiceImpl extends ServiceImpl<BstIvtStockingivtM
//判断前一排的纸管高度
int preNum = num - 1;
MdPbPapervehicle prePaper = PapervehicleService.getOne(new LambdaQueryWrapper<MdPbPapervehicle>().eq(MdPbPapervehicle::getVehicle_code, vehicle_code)
MdPbPapervehicle prePaper = papervehicleService.getOne(new LambdaQueryWrapper<MdPbPapervehicle>().eq(MdPbPapervehicle::getVehicle_code, vehicle_code)
.eq(MdPbPapervehicle::getRow_num, preNum));
if (ObjectUtil.isNotEmpty(prePaper)) {
//获取后一排的纸管高度和纸管类型
@@ -227,7 +227,7 @@ public class BstIvtStockingivtServiceImpl extends ServiceImpl<BstIvtStockingivtM
papervehicle.setUpdate_optid(currentUserId);
papervehicle.setUpdate_optname(nickName);
papervehicle.setUpdate_time(now);
PapervehicleService.updateById(papervehicle);
papervehicleService.updateById(papervehicle);
} else {
papervehicle = new MdPbPapervehicle();
papervehicle.setIvt_id(IdUtil.getSnowflake(1, 1).nextIdStr());
@@ -239,20 +239,20 @@ public class BstIvtStockingivtServiceImpl extends ServiceImpl<BstIvtStockingivtM
papervehicle.setUpdate_optid(currentUserId);
papervehicle.setUpdate_optname(nickName);
papervehicle.setUpdate_time(now);
PapervehicleService.save(papervehicle);
papervehicleService.save(papervehicle);
}
}
if (type.equals("2")) {
PapervehicleService.remove(new LambdaQueryWrapper<MdPbPapervehicle>().eq(MdPbPapervehicle::getVehicle_code, vehicle_code)
papervehicleService.remove(new LambdaQueryWrapper<MdPbPapervehicle>().eq(MdPbPapervehicle::getVehicle_code, vehicle_code)
.eq(MdPbPapervehicle::getRow_num, row_num));
}
//判断绑定的纸管是否在机械手范围内,如果存在的话把最新库存推送给电气
BstIvtStockingivt bstIvtStockingivt = bstIvtStockingivtMapper.selectOne(new LambdaQueryWrapper<BstIvtStockingivt>().eq(BstIvtStockingivt::getVehicle_code, vehicle_code));
if (bstIvtStockingivt != null && bstIvtStockingivt.getPoint_type().equals("1")) {
List<MdPbPapervehicle> list = PapervehicleService.list(new LambdaQueryWrapper<MdPbPapervehicle>().eq(MdPbPapervehicle::getVehicle_code, vehicle_code));
List<MdPbPapervehicle> list = papervehicleService.list(new LambdaQueryWrapper<MdPbPapervehicle>().eq(MdPbPapervehicle::getVehicle_code, vehicle_code));
JSONObject jo = new JSONObject();
SlitterTaskUtil.doSavePaperInfos(list, jo);
jo.put("product_area", bstIvtStockingivt.getProduct_area());
@@ -265,4 +265,60 @@ public class BstIvtStockingivtServiceImpl extends ServiceImpl<BstIvtStockingivtM
result.put("message", "操作成功!");
return result;
}
@Override
public List<BhTubePointDto> getNeedPaperTubePoint(String pointType, String tube, String location) {
return bstIvtStockingivtMapper.getNeedPaperTubePoint(pointType, tube, location);
}
@Override
public List<BhTubeMovePointDto> getCanMovePointList(String location, String pointType) {
return bstIvtStockingivtMapper.getCanMovePointList(location, pointType);
}
@Override
public List<List<ShowStockVo>> showDetail(JSONObject param) {
List<List<ShowStockVo>> res = new ArrayList<>();
// vehicle_code
String vehicleCode = param.getString("vehicle_code");
if (ObjectUtil.isEmpty(vehicleCode)) {
// 5*5的0
for (int i = 0; i < 5; i++) {
List<ShowStockVo> list = new ArrayList<>();
for (int j = 0; j < 5; j++) {
ShowStockVo one = new ShowStockVo();
one.setHave_qzz("0");
one.setTube("-");
list.add(one);
}
res.add(list);
}
} else {
// 获取数据
List<MdPbPapervehicle> papers = papervehicleService.list(new LambdaQueryWrapper<MdPbPapervehicle>()
.eq(MdPbPapervehicle::getVehicle_code, vehicleCode)
.orderByAsc(MdPbPapervehicle::getRow_num));
// 初始化 5*5的1
for (int i = 0; i < 5; i++) {
// 获取对应排的数据
int index = i;
MdPbPapervehicle mdPbPapervehicle = papers.stream().filter(p -> p.getRow_num().equals(index + 1)).findFirst().orElse(null);
int indexJ = mdPbPapervehicle == null ? 0 : mdPbPapervehicle.getQty().intValue();
List<ShowStockVo> list = new ArrayList<>();
for (int j = 0; j < 5; j++) {
ShowStockVo one = new ShowStockVo();
one.setHave_qzz("1");
one.setTube("-");
if (j < indexJ && indexJ != 0) {
one.setHave_qzz("2");
one.setTube(mdPbPapervehicle.getMaterial_name());
}
list.add(one);
}
res.add(list);
}
}
return res;
}
}

View File

@@ -46,6 +46,12 @@ public class SlitterPdaController {
public ResponseEntity<Object> downRolls2(@RequestBody JSONObject param) {
return new ResponseEntity<>(slitterDevices.downRolls2(param), HttpStatus.OK);
}
@PostMapping("/downRollsCheck")
@Log("下卷2提示确认")
@SaIgnore
public ResponseEntity<Object> downRollsCheck(@RequestBody JSONObject param) {
return new ResponseEntity<>(slitterDevices.downRollsCheck(param), HttpStatus.OK);
}
@PostMapping("/moveVehicle")
@Log("搬运废箔斗")

View File

@@ -138,4 +138,18 @@ public interface IPdmBiSlittingproductionplanService extends IService<PdmBiSlitt
PdmBiSlittingproductionplan getByContainerNameNotStatus(String containerName);
List<SlitterPlanDistinctDto> getAllHalfPlanRestruct(List<String> qzzs);
/**
* 获取能够套轴的分切计划,虚拟卷,固定是常规卷
* @param day 天数
* @return
*/
List<SlitterPlanDistinctDto> getAllCutPlan2(Integer day);
/**
* 根据设备获取计划
* @param deviceCode
* @return
*/
List<PdmBiSlittingproductionplan> getXnPlanByDevice(String deviceCode);
}

View File

@@ -19,4 +19,6 @@ public interface PdmBiSlittingproductionplanMapper extends BaseMapper<PdmBiSlitt
List<PdmBiSlittingproductionplan> getCurrentPlanInfos(SlitterPlanDistinctDto dto);
List<SlitterPlanDistinctDto> getAllHalfPlanRestruct(List<String> qzzs);
List<SlitterPlanDistinctDto> getAllCutPlan2(Integer day);
}

View File

@@ -197,4 +197,31 @@
WHERE
rn = 1;
</select>
<select id="getAllCutPlan2" resultType="org.nl.b_lms.sch.tasks.slitter.mapper.dto.SlitterPlanDistinctDto">
SELECT p.resource_name,
p.parent_container_name,
p.split_group,
p.up_or_down,
p.qzz_size,
p.qzz_generation,
MIN(p.start_time) AS start_time
FROM `pdm_bi_slittingproductionplan` p
WHERE p.`status` = '01'
AND p.is_child_tz_ok = '0'
AND p.is_paper_ok = '1'
AND p.is_delete = '0'
AND IFNULL(p.up_or_down, '') <![CDATA[ <> ]]> ''
AND IFNULL(p.left_or_right, '') <![CDATA[ <> ]]> ''
AND DATE ( p.start_time ) >= DATE_SUB( CURDATE()
, INTERVAL #{day} DAY )
AND p.container_name LIKE '%虚拟%'
AND '1' = ( SELECT c.is_used FROM st_ivt_cutpointivt c WHERE c.ext_code = p.resource_name )
GROUP BY
p.resource_name,
p.parent_container_name,
p.split_group,
p.up_or_down,
p.qzz_size,
p.qzz_generation
</select>
</mapper>

View File

@@ -196,4 +196,18 @@ public class PdmBiSlittingproductionplanServiceImpl extends ServiceImpl<PdmBiSli
public List<SlitterPlanDistinctDto> getAllHalfPlanRestruct(List<String> qzzs) {
return pdmBiSlittingproductionplanMapper.getAllHalfPlanRestruct(qzzs);
}
@Override
public List<SlitterPlanDistinctDto> getAllCutPlan2(Integer day) {
return pdmBiSlittingproductionplanMapper.getAllCutPlan2(day);
}
@Override
public List<PdmBiSlittingproductionplan> getXnPlanByDevice(String deviceCode) {
LambdaQueryWrapper<PdmBiSlittingproductionplan> lam = new QueryWrapper<PdmBiSlittingproductionplan>().lambda();
lam.eq(PdmBiSlittingproductionplan::getResource_name, deviceCode)
.like(PdmBiSlittingproductionplan::getContainer_name, "虚拟")
.eq(PdmBiSlittingproductionplan::getIs_delete, "0");
return this.list(lam);
}
}

View File

@@ -94,6 +94,8 @@ public interface IschBaseTaskService extends IService<SchBaseTask> {
* @return
*/
List<SchBaseTask> checkHaveStartTask(String pointCode);
List<SchBaseTask> checkHaveTrussTask(List<String> codes);
}

View File

@@ -166,6 +166,21 @@ public class SchBaseTaskServiceImpl extends ServiceImpl<SchBaseTaskMapper, SchBa
return schBaseTaskMapper.checkHaveStartTask(pointCode);
}
@Override
public List<SchBaseTask> checkHaveTrussTask(List<String> codes) {
LambdaQueryWrapper<SchBaseTask> lam = new LambdaQueryWrapper<>();
lam.lt(SchBaseTask::getTask_status, "07")
.eq(SchBaseTask::getIs_delete, "0")
.and(la2 -> la2.in(SchBaseTask::getPoint_code1, codes)
.or()
.in(SchBaseTask::getPoint_code2, codes)
.or()
.in(SchBaseTask::getPoint_code3, codes)
.or()
.in(SchBaseTask::getPoint_code4, codes));
return this.list(lam);
}
}

View File

@@ -24,6 +24,8 @@ import org.nl.b_lms.sch.tasks.slitter.TrussCallAirShaftTask;
import org.nl.b_lms.sch.tasks.slitter.TrussCallShaftCacheTask;
import org.nl.b_lms.sch.tasks.slitter.constant.SlitterConstant;
import org.nl.b_lms.sch.tasks.slitter.constant.SlitterEnum;
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.common.enums.NoticeTypeEnum;
@@ -37,8 +39,13 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Comparator;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -86,6 +93,9 @@ public class AutoCallAirShaftTask {
public final static String IS_ONLY_PULLING = "IS_ONLY_PULLING";
public final static String TZ_DAY = "TZ_DAY";
private static final DateTimeFormatter TIME_FORMATTER =
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
/**
* hint: 目前只是考虑了上区域
* 执行套轴和拔轴任务的逻辑处理。
@@ -119,7 +129,15 @@ public class AutoCallAirShaftTask {
}
Integer integer = Integer.valueOf(ObjectUtil.isEmpty(tzDay.getValue()) ? "0" : tzDay.getValue());
// 2、获取分切计划数据 校验代数 todo 顺序可能需要考虑
List<SlitterPlanDistinctDto> planAll = slittingproductionplanService.getAllCutPlan(integer);
// List<SlitterPlanDistinctDto> planAll = slittingproductionplanService.getAllCutPlan(integer);
List<SlitterPlanDistinctDto> planAllNoSort = slittingproductionplanService.getAllCutPlan2(integer);
// 排序
List<SlitterPlanDistinctDto> planAll = planAllNoSort.stream()
.sorted(Comparator.comparing(
dto -> LocalDateTime.parse(dto.getStart_time(), TIME_FORMATTER)
))
.collect(Collectors.toList());
// 过滤
String value = paramObj.getValue();
List<String> prefixList = Arrays.asList(value.split("[,]"));
List<SlitterPlanDistinctDto> plans = planAll.stream()
@@ -313,28 +331,60 @@ public class AutoCallAirShaftTask {
return plan.getFRP_material();
}
}).collect(Collectors.toList());
// 判断另一台穿拔轴机的管芯
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"));
log.info("同位置的另一台穿拔轴机构:{}", one);
// 另一台所需要的数量
int otherDeviceTubeSize = 0;
// 缺省的数量
int needQuantity = 0;
// 判断当前区域location对应的备货区是否含有相同的纸管 校验了不在搬运中
// type=1, 关联对象material_code=纸管, qty > 0
List<BstIvtStockingivt> useList = stockingivtService.getPaperTubePoint("1", tubes.get(0), location, tubes.size());
// type=1(桁架底下的托盘), 关联对象material_code=纸管, qty > 0
List<BstIvtStockingivt> useList = stockingivtService.getPaperTubePoint("1", tubes.get(0), location, 0);
if (useList.size() > 0) {
// 求和,三个托盘中需要的管芯的数量。
int sum = useList.stream().mapToInt(BstIvtStockingivt::getQty).sum();
if (ObjectUtil.isNotEmpty(one)) {
if (one.getTube_code1().equals(tubes.get(0))) {
otherDeviceTubeSize = (int) Stream.of(one.getTube_code1(), one.getTube_code2()).filter(ObjectUtil::isNotEmpty).count();
}
}
// 说明三个位置中有包含此纸管的数据。
return;
if (sum >= tubes.size() + otherDeviceTubeSize) {
return;
}
// 如果不够,就计算还缺多少个
int needTemp = tubes.size() + otherDeviceTubeSize - sum;
// 兜底
needQuantity = needTemp > 0 ? needTemp : 1;
}
// 查找type=0的位置中是否存在 校验了不在搬运中
List<BstIvtStockingivt> stockingivtList = stockingivtService.getPaperTubePoint("0", tubes.get(0), location, tubes.size());
if (stockingivtList.size() == 0) {
// 查找type=0的位置(待命的托盘)中是否存在(需要判断的是单独一个托盘) 校验了不在搬运中
List<BhTubePointDto> stockingivtList = stockingivtService.getNeedPaperTubePoint("0", tubes.get(0), location);
// 找一个点位: 目的需要的点位
// 筛选单独托盘有超过所需数
BhTubePointDto needPoint = null;
for (BhTubePointDto bhTubePointDto : stockingivtList) {
if (bhTubePointDto.getQty() >= needQuantity) {
needPoint = bhTubePointDto;
break;
}
}
if (needPoint == null) {
// 不存在则站内通知
noticeService.createNotice("备货区找不到[" + tubes.get(0) + "]的纸管信息",
"点位[" + empty.getPoint_name() + "]无法从备货区找到纸管信息",
NoticeTypeEnum.EXCEPTION.getCode());
return;
}
// 找一个点位: 目的需要的点位
BstIvtStockingivt needPoint = stockingivtList.get(0);
// 找到就创建AGV搬运任务
// 筛选3个位置中数量最少的搬走
BstIvtStockingivt needMovePoint = stockingivtService.getCanMovePointOne(location, "1");
// 筛选3个位置中数量最少的搬走, 如果是空位,直接搬运过来
List<BhTubeMovePointDto> needMovePointList = stockingivtService.getCanMovePointList(location, "1");
// 空位就直接创建搬过来的任务
BhTubeMovePointDto needMovePoint = needMovePointList.size() > 0 ? needMovePointList.get(0) : null;
if (ObjectUtil.isEmpty(needMovePoint) || "0".equals(needMovePoint.getIvt_status())) {
// 直接搬过来即可
JSONObject param = new JSONObject();

View File

@@ -0,0 +1,24 @@
package org.nl.b_lms.sch.tasks.slitter.mapper.dto;
import lombok.Data;
/**
* @Author: lyd
* @Date: 2025/3/19
*/
@Data
public class BhTubeMovePointDto {
/**
* 点位
*/
private String point_code;
/**
* 托盘号
*/
private String vehicle_code;
private String ivt_status;
/**
* 数量
*/
private Integer qty;
}

View File

@@ -0,0 +1,24 @@
package org.nl.b_lms.sch.tasks.slitter.mapper.dto;
import lombok.Data;
/**
* @Author: lyd
* @Date: 2025/3/18
*/
@Data
public class BhTubePointDto {
/**
* 点位
*/
private String point_code;
/**
* 托盘号
*/
private String vehicle_code;
/**
* 数量
*/
private Integer qty;
}

View File

@@ -37,4 +37,9 @@ public class SlitterPlanDistinctDto {
* 气胀轴代数
*/
private String qzz_generation;
/**
* 开始时间
*/
private String start_time;
}

View File

@@ -334,4 +334,11 @@ public interface SlitterService {
* @return
*/
JSONObject rollCacheManageTip(JSONObject param);
/**
* 下卷确认
* @param param
* @return
*/
JSONObject downRollsCheck(JSONObject param);
}

View File

@@ -57,11 +57,9 @@ import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -810,7 +808,7 @@ public class SlitterServiceImpl implements SlitterService {
if (list.size() == 0) {
throw new BadRequestException("分切机" + device_code + " 的分切计划 " + qzzNo + " 不存在");
}
List<SchBaseTask> tasks = taskService.checkHaveTask(device_code);
List<SchBaseTask> tasks = taskService.checkHaveTrussTask(Arrays.asList(deviceCode.getUp_point_code(), deviceCode.getDown_point_code()));
if (tasks.size() > 0) {
throw new BadRequestException("分切机" + device_code + " 已经有存在的任务");
}
@@ -1948,6 +1946,11 @@ public class SlitterServiceImpl implements SlitterService {
String downRightSizeK = param.getString("down_right_size_k");
String downLeftSizeV = param.getString("down_left_size_v");
String downRightSizeV = param.getString("down_right_size_v");
// 获取设备的
List<PdmBiSlittingproductionplan> checkPlans = slittingproductionplanService.getXnPlanByDevice(deviceCode);
if (!doCheckCanCallAgain(checkPlans)) {
throw new BadRequestException("气胀轴正在准备或配送中、未使用,不允许二次呼叫套轴!");
}
List<PdmBiSlittingproductionplan> plans = new ArrayList<>();
// 虚拟计划
for (int i = 0; i < 4; i++) {
@@ -2116,6 +2119,16 @@ public class SlitterServiceImpl implements SlitterService {
return res;
}
private boolean doCheckCanCallAgain(List<PdmBiSlittingproductionplan> checkPlans) {
// 如果is_paper_ok = 2那就不允许
for (PdmBiSlittingproductionplan checkPlan : checkPlans) {
if ("2".equals(checkPlan.getIs_paper_ok())) {
return false;
}
}
return true;
}
@Override
public List<CallPlanViewVO> showManualView(JSONObject param) {
return slitterMapper.showManualView();
@@ -2124,13 +2137,30 @@ public class SlitterServiceImpl implements SlitterService {
@Override
public JSONObject downRolls2(JSONObject param) {
log.info("下卷2的输入参数为{}", param);
// param: device_code, container
// param: device_code, container: [{"container_name":"子卷号", "site":"上下轴1/2"}]
String device_code = param.getString("device_code");
List<SchBaseTask> tasks = taskService.checkHaveTask(device_code);
StIvtCutpointivt deviceCode = cutpointivtService.getPintByExtCode(device_code, false);
List<SchBaseTask> tasks = taskService.checkHaveTrussTask(Arrays.asList(deviceCode.getUp_point_code(), deviceCode.getDown_point_code()));
if (tasks.size() > 0) {
throw new BadRequestException("分切机" + device_code + " 已经有存在的任务");
}
return mesSlittingMachineSendMaterial(param);
JSONArray conArray = param.getJSONArray("container");
List<String> containerNames = new ArrayList<>();
for (int i = 0; i < conArray.size(); i++) {
JSONObject container = conArray.getJSONObject(i);
containerNames.add(container.getString("container_name"));
}
List<PdmBiSlittingproductionplan> plans = slittingproductionplanService.getByContainerNames(containerNames);
// 兜底校验:判断与实际是否一致
SlitterTaskUtil.validateConsistency(conArray, plans);
JSONObject reqParam = new JSONObject();
reqParam.put("device_code", device_code);
reqParam.put("container", containerNames);
mesSlittingMachineSendMaterial(reqParam);
JSONObject res = new JSONObject();
res.put("status", HttpStatus.HTTP_OK);
res.put("message", "子卷出站任务生成成功!");
return res;
}
@Override
@@ -2174,4 +2204,31 @@ public class SlitterServiceImpl implements SlitterService {
res.put("data", data);
return res;
}
@Override
public JSONObject downRollsCheck(JSONObject param) {
// param: device_code, container: [{"container_name":"子卷号", "site":"上下轴1/2"}]
JSONObject res = new JSONObject();
String device_code = param.getString("device_code");
List<SchBaseTask> tasks = taskService.checkHaveTask(device_code);
if (tasks.size() > 0) {
throw new BadRequestException("分切机" + device_code + " 已经有存在的任务");
}
JSONArray conArray = param.getJSONArray("container");
List<String> containerNames = new ArrayList<>();
for (int i = 0; i < conArray.size(); i++) {
JSONObject container = conArray.getJSONObject(i);
containerNames.add(container.getString("container_name"));
}
List<PdmBiSlittingproductionplan> plans = slittingproductionplanService.getByContainerNames(containerNames);
try {
SlitterTaskUtil.validateConsistency(conArray, plans);
} catch (Exception e) {
res.put("flag", "2");
res.put("message", e.getMessage());
}
res.put("flag", "1");
return res;
}
}

View File

@@ -4,6 +4,7 @@ import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.nl.b_lms.bst.ivt.papervehicle.service.dao.MdPbPapervehicle;
import org.nl.b_lms.pdm.bi.slittingproductionplan.service.dao.PdmBiSlittingproductionplan;
import org.nl.b_lms.sch.tasks.slitter.constant.SlitterConstant;
@@ -14,12 +15,15 @@ import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @Author: lyd
* @Description: 分切部分的任务工具类
* @Date: 2024/4/12
*/
@Slf4j
public class SlitterTaskUtil {
/** B1区域 */
@@ -452,4 +456,44 @@ public class SlitterTaskUtil {
default: throw new BadRequestException("站点输入错误: " + input);
}
}
/**
* 下卷前置校验,判断卷的上下轴属性与实际是否一致 - 校验子卷属性
* @param jsonArray 子卷数组
* @param plans 计划
*/
public static void validateConsistency(JSONArray jsonArray, List<PdmBiSlittingproductionplan> plans) {
if (plans.size() == 0) {
throw new BadRequestException("计划未找到请确保MES已推送。");
}
// 1. 将 List<PdmBiSlittingproductionplan> 转为 Map<container_name, up_or_down>
Map<String, String> planMap = plans.stream()
.collect(Collectors.toMap(
p -> p.getContainer_name(),
p -> p.getUp_or_down(),
// 如果有重复 key保留第一个按需调整
(existing, replacement) -> existing
));
// 2. 遍历 JSONArray
for (int i = 0; i < jsonArray.size(); i++) {
JSONObject item = jsonArray.getJSONObject(i);
String containerName = item.getString("container_name");
String site = item.getString("site");
// 3. 检查 Plan 中是否存在对应的 container_name
if (!planMap.containsKey(containerName)) {
throw new BadRequestException("校验失败: container_name " + containerName + " 在计划列表中不存在");
}
// 4. 比较 site 和 up_or_down 是否一致
String expectedUpDown = planMap.get(containerName);
if (!expectedUpDown.equals(site)) {
throw new BadRequestException("校验失败: 子卷号 " + containerName
+ " 的上下轴位置值 '" + site
+ "' 与计划中的上下轴位置值 '" + expectedUpDown + "' 不一致");
}
}
log.info("分切下卷计划位置校验通过!");
}
}

View File

@@ -1,5 +1,6 @@
package org.nl.init;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
@@ -11,11 +12,16 @@ import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.nl.b_lms.bst.ivt.shafttubeivt.service.dao.BstIvtShafttubeivt;
import org.nl.b_lms.bst.ivt.shafttubeivt.service.dao.mapper.BstIvtShafttubeivtMapper;
import org.nl.b_lms.pdm.bi.slittingproductionplan.service.IPdmBiSlittingproductionplanService;
import org.nl.b_lms.pdm.bi.slittingproductionplan.service.dao.PdmBiSlittingproductionplan;
import org.nl.b_lms.pdm.subpackagerelation.dao.PdmBiSubpackagerelation;
import org.nl.b_lms.pdm.subpackagerelation.dao.mapper.PdmBiSubpackagerelationMapper;
import org.nl.b_lms.sch.point.dao.BstIvtPackageinfoivt;
import org.nl.b_lms.sch.point.dao.mapper.SchBasePointMapper;
import org.nl.b_lms.sch.point.service.IbstIvtPackageinfoivtService;
import org.nl.b_lms.sch.tasks.first_floor_area.*;
import org.nl.b_lms.sch.tasks.slitter.service.impl.SlitterServiceImpl;
import org.nl.b_lms.sch.tasks.slitter.util.SlitterTaskUtil;
import org.nl.b_lms.storage_manage.ios.service.iostorInv.util.service.OutBoxManageService;
import org.nl.common.enums.ContainerLevelEnum;
import org.nl.common.enums.PackageInfoIvtEnum;
@@ -26,6 +32,7 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import javax.annotation.Resource;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@@ -62,6 +69,43 @@ public class EventTest {
private PdmBiSubpackagerelationMapper pdmBiSubpackagerelationMapper;
@Autowired
private BstIvtShafttubeivtMapper bstIvtShafttubeivtMapper;
@Autowired
private SchBasePointMapper schBasePointMapper;
@Autowired
private IPdmBiSlittingproductionplanService slittingproductionplanService;
@Test
public void sss() {
System.out.println(schBasePointMapper.queryKZPoint());
}
@Test
public void getWeight() {
List<PdmBiSlittingproductionplan> plans = slittingproductionplanService.getByQzzNos(Arrays.asList("B203-4"));
String weights = "";
SlitterTaskUtil.setPaperWeightStr(weights, plans);
slittingproductionplanService.updateBatchById(plans);
System.out.println(weights);
}
@Test
public void testValidate() {
// 示例数据
JSONArray jsonArray = JSONArray.parseArray(
"[{\"container_name\":\"A\", \"site\":\"1\"},{\"container_name\":\"B\", \"site\":\"2\"}]"
);
PdmBiSlittingproductionplan p1 = new PdmBiSlittingproductionplan();
PdmBiSlittingproductionplan p2 = new PdmBiSlittingproductionplan();
p1.setContainer_name("A");
p1.setUp_or_down("1");
p2.setContainer_name("B");
p2.setUp_or_down("2");
List<PdmBiSlittingproductionplan> plans = Arrays.asList(p1, p2);
// 执行校验
SlitterTaskUtil.validateConsistency(jsonArray, plans);
}
@Test
public void sl() {

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

View File

@@ -24,4 +24,12 @@ export function edit(data) {
})
}
export default { add, edit, del }
export function showDetail(data) {
return request({
url: 'api/bstIvtStockingivt/showDetail',
method: 'post',
data
})
}
export default { add, edit, del, showDetail }

View File

@@ -83,12 +83,24 @@
</div>
</el-dialog>
<!--表格渲染-->
<el-table ref="table" v-loading="crud.loading" :data="crud.data" size="mini" style="width: 100%;" @selection-change="crud.selectionChangeHandler">
<el-table
ref="table"
v-loading="crud.loading"
:data="crud.data"
size="mini"
style="width: 100%;"
:highlight-current-row="true"
@selection-change="crud.selectionChangeHandler"
>
<el-table-column type="selection" width="55" />
<el-table-column prop="point_code" label="点位编码" :min-width="flexWidth('point_code',crud.data,'点位编码')" />
<el-table-column prop="point_code" label="点位编码" :min-width="flexWidth('point_code',crud.data,'点位编码')">
<template slot-scope="scope">
<el-link type="primary" @click="toView(scope.$index, scope.row)">{{ scope.row.point_code }}</el-link>
</template>
</el-table-column>
<el-table-column prop="point_name" label="点位名称" :min-width="flexWidth('point_name',crud.data,'点位名称')" />
<el-table-column prop="vehicle_code" label="托盘号" :min-width="flexWidth('vehicle_code',crud.data,'托盘号')" />
<el-table-column prop="product_area" label="区域" :min-width="flexWidth('product_area',crud.data,'区域')" />
<!-- <el-table-column prop="product_area" label="区域" :min-width="flexWidth('product_area',crud.data,'区域')" />-->
<el-table-column prop="point_type" label="点位类型" :min-width="flexWidth('point_type',crud.data,'点位类型')">
<template slot-scope="scope">
{{ dict.label.STOCK_POINT_TYPE[scope.row.point_type] }}
@@ -105,10 +117,12 @@
</template>
</el-table-column>
<el-table-column prop="sort_seq" label="顺序号" :min-width="flexWidth('sort_seq',crud.data,'顺序号')" />
<el-table-column prop="is_used" label="是否启用" :min-width="flexWidth('is_used',crud.data,'是否启用')" />
<el-table-column prop="is_used" label="是否启用" :min-width="flexWidth('is_used',crud.data,'是否启用')">
<template slot-scope="scope">
{{ scope.row.is_used === '1' ? '启用' : '禁用' }}
</template>
</el-table-column>
<el-table-column prop="remark" label="备注" :min-width="flexWidth('remark',crud.data,'备注')" />
<el-table-column prop="create_name" label="创建人" :min-width="flexWidth('create_name',crud.data,'创建人')" />
<el-table-column prop="create_time" label="创建时间" :min-width="flexWidth('create_time',crud.data,'创建时间')" />
<el-table-column prop="update_optname" label="修改人" :min-width="flexWidth('update_optname',crud.data,'修改人')" />
<el-table-column prop="update_time" label="修改时间" :min-width="flexWidth('update_time',crud.data,'修改时间')" />
<el-table-column prop="plan" label="规划" :min-width="flexWidth('plan',crud.data,'规划')" />
@@ -125,6 +139,7 @@
<!--分页组件-->
<pagination />
</div>
<tube-dialog :dialog-show.sync="showView" :rows="rows" :vehicle_code="vehicle_code" />
</div>
</template>
@@ -135,6 +150,7 @@ import rrOperation from '@crud/RR.operation'
import crudOperation from '@crud/CRUD.operation'
import udOperation from '@crud/UD.operation'
import pagination from '@crud/Pagination'
import TubeDialog from '@/views/b_lms/bst/ivt/stockingivt/tubeDialog.vue'
const defaultForm = {
ivt_id: null,
@@ -159,7 +175,7 @@ const defaultForm = {
export default {
name: 'BstIvtStockingivt',
dicts: ['STOCK_POINT_STATUS', 'STOCK_POINT_TYPE', 'point_location'],
components: { pagination, crudOperation, rrOperation, udOperation },
components: { TubeDialog, pagination, crudOperation, rrOperation, udOperation },
mixins: [presenter(), header(), form(defaultForm), crud()],
cruds() {
return CRUD({
@@ -203,12 +219,28 @@ export default {
create_time: [
{ required: true, message: '创建时间不能为空', trigger: 'blur' }
]
}}
},
showView: false,
vehicle_code: '',
rows: {}
}
},
methods: {
// 钩子在获取表格数据之前执行false 则代表不获取数据
[CRUD.HOOK.beforeRefresh]() {
return true
},
toView(index, row) {
// vehicle_code point_code
console.log(row)
const param = {
vehicle_code: this.vehicle_code
}
crudBstIvtStockingivt.showDetail(param).then(res => {
this.vehicle_code = row.vehicle_code
this.showView = true
this.rows = res
})
}
}
}

View File

@@ -0,0 +1,125 @@
<template>
<el-dialog :visible.sync="dialogVisible" title="托盘详情">
<div class="grid-container">
<div
v-for="(row, rowIndex) in grid"
:key="rowIndex"
class="grid-row"
>
<div
v-for="(cell, colIndex) in row"
:key="colIndex"
class="grid-cell"
>
<img
:src="cell.have_qzz == '0' ? imageC : cell.have_qzz == '1' ? imageA : imageB"
alt="方块"
class="grid-image"
>
</div>
</div>
</div>
</el-dialog>
</template>
<script>
import crudBstIvtStockingivt from './bstIvtStockingivt'
export default {
name: 'TubeDialog',
props: {
dialogShow: {
type: Boolean,
default: false
},
rows: {
type: Object
},
vehicleCode: {
type: String
}
},
data() {
return {
dialogVisible: false,
form: {},
imageA: require('@/assets/images/empty.png'), // 默认图片路径
imageC: require('@/assets/images/empty2.png'), // 默认图片路径
imageB: require('@/assets/images/showTube.png'), // 特殊状态图片路径
grid: Array(5).fill().map(() =>
Array(5).fill().map(() => ({
have_qzz: false
}))
)
}
},
watch: {
dialogShow: {
handler(newValue) {
this.dialogVisible = newValue
}
},
rows: {
handler(newValue) {
this.grid = newValue
}
}
},
methods: {
open() {
// this.queryTableDtl()
},
close() {
this.$emit('update:dialogShow', false)
this.currentDis = {}
this.currentdtl = null
this.tableDtl = []
this.tabledis = []
this.$emit('AddChanged')
},
// toggleCell(row, col) {
// console.log(this.grid)
// this.$set(this.grid[row], col, {
// ...this.grid[row][col],
// have_qzz: !this.grid[row][col].have_qzz
// })
// },
queryTableDtl() {
const param = {
vehicle_code: this.vehicle_code
}
crudBstIvtStockingivt.showDetail(param).then(res => {
this.grid = res
})
}
}
}
</script>
<style scoped>
.grid-container {
display: flex;
flex-direction: column;
gap: 5px;
}
.grid-row {
display: flex;
gap: 5px;
justify-content: center;
}
.grid-cell {
width: 50px;
height: 50px;
cursor: pointer;
border: 1px solid #ddd;
transition: all 0.3s;
}
.grid-image {
width: 100%;
height: 100%;
object-fit: cover;
}
</style>