no message

main
HUOJIN\92525 2026-01-08 17:29:27 +08:00
parent d8b84477ad
commit 31d08765ab
14 changed files with 218 additions and 2455 deletions

View File

@ -56,7 +56,6 @@ public interface AgvTaskMapper extends BaseMapper<AgvTask> {
* *
* @param endCode * @param endCode
*/ */
@Select(value = "select * from data_agv_task where end_code = #{endCode} and type='OUTBOUND' and status = 4 and agv_vendor = 'TES' order by create_time desc limit 1 ")
AgvTask queryByLastEndCode(@Param("endCode") String endCode); AgvTask queryByLastEndCode(@Param("endCode") String endCode);
/** /**

View File

@ -1,5 +1,21 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.cpte.modules.agvTask.mapper.AgvTaskMapper"> <mapper namespace="org.cpte.modules.agvTask.mapper.AgvTaskMapper">
<select id="queryByLastEndCode" resultType="org.cpte.modules.agvTask.entity.AgvTask">
(SELECT * FROM data_agv_task
WHERE start_code = #{endCode}
AND type IN ('INBOUND','OUTBOUND')
AND agv_vendor = 'TES'
ORDER BY create_time DESC
LIMIT 1)
UNION ALL
(SELECT * FROM data_agv_task
WHERE end_code = #{endCode}
AND type IN ('INBOUND','OUTBOUND')
AND agv_vendor = 'TES'
ORDER BY create_time DESC
LIMIT 1)
ORDER BY create_time DESC
LIMIT 1
</select>
</mapper> </mapper>

View File

@ -22,4 +22,7 @@ public interface AreaMapper extends BaseMapper<Area> {
*/ */
@Select("select * from base_area where area_code = #{areaCode}") @Select("select * from base_area where area_code = #{areaCode}")
Area queryByAreaCode(@Param("areaCode") String areaCode); Area queryByAreaCode(@Param("areaCode") String areaCode);
@Select("select * from base_area where id in (select area_id from base_point where point_code = #{pointCode})")
Area queryByPointCode(@Param("pointCode") String pointCode);
} }

View File

@ -33,6 +33,9 @@ public class SyncPointProcessor {
public Boolean syncPoint(Area area, JSONObject pointJsonObject) { public Boolean syncPoint(Area area, JSONObject pointJsonObject) {
try { try {
if(pointJsonObject==null){
return Boolean.TRUE;
}
JSONArray laneListArray = extractLaneList(pointJsonObject); JSONArray laneListArray = extractLaneList(pointJsonObject);
if (CollectionUtils.isEmpty(laneListArray)) { if (CollectionUtils.isEmpty(laneListArray)) {
return Boolean.TRUE; return Boolean.TRUE;
@ -136,15 +139,43 @@ public class SyncPointProcessor {
if (CollectionUtils.isEmpty(nodeArray)) { if (CollectionUtils.isEmpty(nodeArray)) {
return; return;
} }
int lineNo = 1;
boolean isDoubleLane = faceDirArray != null && faceDirArray.size() > 1; boolean isDoubleLane = faceDirArray != null && faceDirArray.size() > 1;
if(isDoubleLane){
processNodesForward(area, nodeArray, colNum, true, pointMap, data, processedPointCodes);
}else{
String faceDir=faceDirArray.getString(0);
if("E".equals(faceDir)){
//反方向
processNodesReverse(area, nodeArray, colNum, pointMap, data, processedPointCodes);
}else if("W".equals(faceDir)){
processNodesForward(area, nodeArray, colNum, false, pointMap, data, processedPointCodes);
}else {
log.error("处理库位数据失败: 巷道方向错误");
}
}
}
//正向添加库位
private void processNodesForward(Area area, JSONArray nodeArray, String colNum,
boolean isDoubleLane, Map<String, Point> pointMap,
SyncPointData data, Set<String> processedPointCodes) {
for (int j = 0; j < nodeArray.size(); j++) { for (int j = 0; j < nodeArray.size(); j++) {
JSONObject nodeObject = nodeArray.getJSONObject(j); JSONObject nodeObject = nodeArray.getJSONObject(j);
processSingleNode(area, nodeObject, colNum, String.valueOf(lineNo), processSingleNode(area, nodeObject, colNum, String.valueOf(j + 1),
isDoubleLane, pointMap, data, processedPointCodes); isDoubleLane, pointMap, data, processedPointCodes);
lineNo++; }
}
// 逆向处理节点的方法
private void processNodesReverse(Area area, JSONArray nodeArray, String colNum,
Map<String, Point> pointMap,
SyncPointData data, Set<String> processedPointCodes) {
for (int j = nodeArray.size() - 1; j >= 0; j--) {
JSONObject nodeObject = nodeArray.getJSONObject(j);
// 计算正向行号从1开始
int forwardLineNo = nodeArray.size() - j;
processSingleNode(area, nodeObject, colNum, String.valueOf(forwardLineNo),
false, pointMap, data, processedPointCodes);
} }
} }
@ -177,12 +208,9 @@ public class SyncPointProcessor {
rowNum, positionX, positionY, izDoubleLane); rowNum, positionX, positionY, izDoubleLane);
data.addInsertPoint(newPoint); data.addInsertPoint(newPoint);
} else { } else {
if (isPointChanged(existingPoint, colNum, layerNum, rowNum, updatePointFrom(existingPoint, rowNum, colNum, layerNum,
positionX, positionY, izDoubleLane)) {
updatePointFrom(existingPoint, colNum, layerNum, rowNum,
positionX, positionY, izDoubleLane); positionX, positionY, izDoubleLane);
data.addUpdatePoint(existingPoint); data.addUpdatePoint(existingPoint);
}
} }
log.debug("处理库位: {}", pointCode); log.debug("处理库位: {}", pointCode);
@ -218,14 +246,14 @@ public class SyncPointProcessor {
/** /**
* *
*/ */
private boolean isPointChanged(Point point, String rowNum, String colNum, String layerNum, Integer positionX, Integer positionY, Integer izDoubleLane) { /* private boolean isPointChanged(Point point, String rowNum, String colNum, String layerNum, Integer positionX, Integer positionY, Integer izDoubleLane) {
return !Objects.equals(point.getRowNum(), rowNum) || return !Objects.equals(point.getRowNum(), rowNum) ||
!Objects.equals(point.getColNum(), colNum) || !Objects.equals(point.getColNum(), colNum) ||
!Objects.equals(point.getLayerNum(), layerNum) || !Objects.equals(point.getLayerNum(), layerNum) ||
!Objects.equals(point.getPositionX(), positionX) || !Objects.equals(point.getPositionX(), positionX) ||
!Objects.equals(point.getPositionY(), positionY) || !Objects.equals(point.getPositionY(), positionY) ||
!Objects.equals(point.getIzDoubleLane(), izDoubleLane); !Objects.equals(point.getIzDoubleLane(), izDoubleLane);
} }*/
/** /**
* *

View File

@ -6,6 +6,8 @@ import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils; import org.apache.commons.lang3.StringUtils;
import org.cpte.modules.agvTask.entity.AgvTask; import org.cpte.modules.agvTask.entity.AgvTask;
import org.cpte.modules.agvTask.mapper.AgvTaskMapper; import org.cpte.modules.agvTask.mapper.AgvTaskMapper;
import org.cpte.modules.base.entity.Area;
import org.cpte.modules.base.mapper.AreaMapper;
import org.cpte.modules.constant.enums.*; import org.cpte.modules.constant.enums.*;
import org.cpte.modules.conveyorLine.request.ScanTrayRequest; import org.cpte.modules.conveyorLine.request.ScanTrayRequest;
import org.cpte.modules.conveyorLine.service.IConveyorLineService; import org.cpte.modules.conveyorLine.service.IConveyorLineService;
@ -23,7 +25,7 @@ import java.util.List;
public class IConveyorLineServiceImpl implements IConveyorLineService { public class IConveyorLineServiceImpl implements IConveyorLineService {
@Autowired @Autowired
private TaskMapper taskMapper; private AreaMapper areaMapper;
@Autowired @Autowired
private AgvTaskMapper agvTaskMapper; private AgvTaskMapper agvTaskMapper;
@ -63,22 +65,32 @@ public class IConveyorLineServiceImpl implements IConveyorLineService {
jsonObject.put("endCode", ""); jsonObject.put("endCode", "");
jsonObject.put("izAll", ""); jsonObject.put("izAll", "");
jsonObject.put("description", ""); jsonObject.put("description", "");
String description;
//工作站库区
Area area = areaMapper.queryByPointCode(conveyorLine);
if(area==null){
return jsonObject;
}
if(AreaTypeEnum.RK_DOCK.getValue().equals(area.getAreaCode())){
}else{
}
AgvTask agvTask = agvTaskMapper.queryByLastEndCode(conveyorLine); AgvTask agvTask = agvTaskMapper.queryByLastEndCode(conveyorLine);
if (agvTask == null) { if (agvTask == null) {
return jsonObject; return jsonObject;
} }
List<Task> tasks = taskMapper.queryByAgvTask(agvTask.getId()); if(BusinessTypeEnum.INBOUND.getValue().equals(agvTask.getType())){
if (CollectionUtils.isEmpty(tasks)) { //先查询扫描成功的日志并返回成功描述信息,如果没有则返回扫描异常信息
return jsonObject;
} }
String stockCode = tasks.get(0).getStockCode(); String stockCode = agvTask.getCarrierCode();
String taskType = BusinessTypeEnum.getDescByValue(agvTask.getType()); String taskType = BusinessTypeEnum.getDescByValue(agvTask.getType());
String endCode = agvTask.getEndCode(); String endCode = agvTask.getEndCode();
String izAll = agvTask.getIzAll() == 1 ? "拆托" : "整托"; String izAll = agvTask.getIzAll() == 1 ? "拆托" : "整托";
String description = izAll.equals("拆托") description = izAll.equals("拆托")
? "请人工将托盘【" + stockCode + "】叉走,避免任务拥堵" ? "请人工将托盘【" + stockCode + "】叉走,避免任务拥堵"
: "请等待AGV将托盘【" + stockCode + "】叉走"; : "请等待AGV将托盘【" + stockCode + "】叉走";

View File

@ -11,10 +11,7 @@ import org.quartz.Job;
import org.quartz.JobExecutionContext; import org.quartz.JobExecutionContext;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import java.util.ArrayList; import java.util.*;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -30,9 +27,6 @@ public class AllocateJob implements Job {
@Autowired @Autowired
private IPickService pickService; private IPickService pickService;
@Autowired
private ITaskService iTaskService;
@Autowired @Autowired
private BaseCommonService baseCommonService; private BaseCommonService baseCommonService;
@ -42,58 +36,63 @@ public class AllocateJob implements Job {
// 缓存最大大小,防止内存溢出 // 缓存最大大小,防止内存溢出
private static final int MAX_CACHE_SIZE = 1000; private static final int MAX_CACHE_SIZE = 1000;
// 使用静态变量跟踪当前分配位置 // 记录上次分配的索引
private static volatile int currentIndex = 0; private int lastProcessedIndex = -1;
@Override @Override
public void execute(JobExecutionContext jobExecutionContext) { public void execute(JobExecutionContext jobExecutionContext) {
// 查询未分配或者部分分配的出库 // 查询未分配或者部分分配的出库
List<Long> pickList = pickMapper.queryUnallocatedPick(); List<Long> pickList = pickMapper.queryUnallocatedPick();
if (CollectionUtils.isNotEmpty(pickList)) { if (CollectionUtils.isEmpty(pickList)) {
// 轮询分配每次只处理一个ID log.info("没有待分配的出库单");
if (currentIndex < pickList.size()) { lastProcessedIndex = -1; // 重置索引
Long currentPickId = pickList.get(currentIndex); return;
List<Long> singlePickList = List.of(currentPickId); }
long startTime = System.currentTimeMillis(); pickList.sort(Long::compareTo);
List<String> resultMsg;
try {
resultMsg = pickService.allocatePick(singlePickList);
}catch (Exception e){
resultMsg=List.of(e.getMessage());
}
long endTime = System.currentTimeMillis();
log.info("分配出库明细耗时:{}ms处理ID{}", endTime - startTime, currentPickId);
if (CollectionUtils.isNotEmpty(resultMsg)) { int currentIndex = (lastProcessedIndex + 1) % pickList.size();
// 生成缓存键 Long pickId = pickList.get(currentIndex);
String cacheKey = generateCacheKey(resultMsg);
// 检查是否已经处理过相同的内容 log.info("上次分配索引: {}, 本次分配索引: {}, 分配出库单ID: {}", lastProcessedIndex, currentIndex, pickId);
if (!processedCache.containsKey(cacheKey)) {
// 新内容,记录日志
baseCommonService.addLog("出库任务分配:" + "\n" + cacheKey, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_1);
// 添加到缓存
processedCache.put(cacheKey, true);
// 控制缓存大小 // 分配单个出库单
if (processedCache.size() > MAX_CACHE_SIZE) { long startTime = System.currentTimeMillis();
processedCache.clear(); List<String> resultMsg;
} try {
// 每次只分配一个出库单
resultMsg = pickService.allocatePick(Collections.singletonList(pickId));
if (CollectionUtils.isNotEmpty(resultMsg)) {
// 生成缓存键
String cacheKey = generateCacheKey(resultMsg);
// 检查是否已经处理过相同的内容
if (!processedCache.containsKey(cacheKey)) {
// 新内容,记录日志
baseCommonService.addLog("出库任务分配:" + "\n" + cacheKey, CommonConstant.LOG_TYPE_2, CommonConstant.OPERATE_TYPE_1);
// 添加到缓存
processedCache.put(cacheKey, true);
// 控制缓存大小
if (processedCache.size() > MAX_CACHE_SIZE) {
processedCache.clear();
} }
} }
// 更新索引,循环使用
currentIndex = (currentIndex + 1) % pickList.size();
} }
// 更新索引
lastProcessedIndex = currentIndex;
} catch (Exception e) {
resultMsg = List.of(e.getMessage());
log.error("分配出库单失败ID: {}, 错误: {}", pickId, e.getMessage());
// 失败也更新索引,等待下次继续分配
lastProcessedIndex = currentIndex;
} }
long endTime = System.currentTimeMillis();
log.info("分配出库明细耗时:{}ms处理ID{}", endTime - startTime, pickId);
//生成出库AGV出库任务
long startTime2 = System.currentTimeMillis();
iTaskService.generateAgvTask();
long endTime2 = System.currentTimeMillis();
log.info("生成AGV出库任务耗时{}ms", endTime2 - startTime2);
} }
/** /**

View File

@ -46,16 +46,10 @@ public class SyncPointJob implements Job {
Integer pageSize = Integer.parseInt(params.getString("pageSize")); Integer pageSize = Integer.parseInt(params.getString("pageSize"));
Integer pageNum = Integer.parseInt(params.getString("pageNum")); Integer pageNum = Integer.parseInt(params.getString("pageNum"));
// 检查是否需要处理
if (pageNum >= MAX_PAGE_NUM) {
log.info("已处理到最新页数,无需继续查询");
return;
}
pageNum = getLastProcessedKey(pageNum);
log.info("当前页数: {} - 每页条数: {}", pageNum, pageSize); log.info("当前页数: {} - 每页条数: {}", pageNum, pageSize);
boolean success = pointService.syncPoint(regionCode, pageNum, pageSize); boolean success = pointService.syncPoint(regionCode, pageNum, pageSize);
if (success) { if (success) {
updateLastProcessedDate(pageNum); log.info("同步库位成功");
} }
log.info("同步库位完成,耗时: {} ms", System.currentTimeMillis() - startTime); log.info("同步库位完成,耗时: {} ms", System.currentTimeMillis() - startTime);
@ -63,31 +57,4 @@ public class SyncPointJob implements Job {
baseCommonService.addLog(String.valueOf(e), CommonConstant.LOG_TYPE_4, null); baseCommonService.addLog(String.valueOf(e), CommonConstant.LOG_TYPE_4, null);
} }
} }
/**
* +1
*/
private Integer getLastProcessedKey(Integer pageNum) {
try {
Object dateObj = redisUtil.get(PAGE_NUM_KEY);
if (dateObj != null) {
return Integer.parseInt(dateObj.toString())+1;
}
} catch (Exception e) {
log.warn("从Redis获取上次处理页数失败使用默认页数", e);
}
// 默认页数
pageNum = 1;
redisUtil.set(PAGE_NUM_KEY, pageNum);
return pageNum;
}
/**
*
*/
private void updateLastProcessedDate(Integer pageNum) {
redisUtil.set(PAGE_NUM_KEY, pageNum);
}
} }

View File

@ -7,6 +7,7 @@ import org.cpte.modules.constant.GeneralConstant;
import org.cpte.modules.constant.enums.AgvStatusEnum; import org.cpte.modules.constant.enums.AgvStatusEnum;
import org.cpte.modules.constant.enums.AgvVendorEnum; import org.cpte.modules.constant.enums.AgvVendorEnum;
import org.cpte.modules.hikAgv.service.IHikAgvService; import org.cpte.modules.hikAgv.service.IHikAgvService;
import org.cpte.modules.shipping.service.ITaskService;
import org.cpte.modules.tesAgv.service.ITesAgvService; import org.cpte.modules.tesAgv.service.ITesAgvService;
import org.quartz.Job; import org.quartz.Job;
import org.quartz.JobExecutionContext; import org.quartz.JobExecutionContext;
@ -17,6 +18,10 @@ import java.util.List;
@Slf4j @Slf4j
public class TesAgvJob implements Job { public class TesAgvJob implements Job {
@Autowired
private ITaskService iTaskService;
@Autowired @Autowired
private AgvTaskMapper agvTaskMapper; private AgvTaskMapper agvTaskMapper;
@ -25,6 +30,13 @@ public class TesAgvJob implements Job {
@Override @Override
public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException { public void execute(JobExecutionContext jobExecutionContext) throws JobExecutionException {
//生成出库AGV出库任务
long startTime2 = System.currentTimeMillis();
iTaskService.generateAgvTask();
long endTime2 = System.currentTimeMillis();
log.info("生成AGV出库任务耗时{}ms", endTime2 - startTime2);
// 查询待执行任务 // 查询待执行任务
List<AgvTask> agvTaskList = agvTaskMapper.queryAgvTaskList(AgvStatusEnum.CREATED.getValue(), AgvVendorEnum.TES.getValue()); List<AgvTask> agvTaskList = agvTaskMapper.queryAgvTaskList(AgvStatusEnum.CREATED.getValue(), AgvVendorEnum.TES.getValue());
if (agvTaskList.isEmpty()) { if (agvTaskList.isEmpty()) {

View File

@ -95,7 +95,7 @@ public class AsnDetailServiceImpl extends ServiceImpl<AsnDetailMapper, AsnDetail
public void processInboundTask(InboundRequest inboundRequest, Map<String, Item> itemMap, Point srcPoint, Stock stock) { public void processInboundTask(InboundRequest inboundRequest, Map<String, Item> itemMap, Point srcPoint, Stock stock) {
//1.获取工作站 //1.获取工作站
Point station = null; Point station = null;
if (AsnOrderTypeEnum.PRODUCT.getValue().equals(inboundRequest.getType())) { if (AsnOrderTypeEnum.PRODUCT.getValue().equals(inboundRequest.getType()) && srcPoint != null) {
station = getStationPoint(inboundRequest.getType()); station = getStationPoint(inboundRequest.getType());
} }
@ -108,9 +108,9 @@ public class AsnDetailServiceImpl extends ServiceImpl<AsnDetailMapper, AsnDetail
stockService.bindStock(stock); stockService.bindStock(stock);
//4.成品入库生成AGV任务 //4.成品入库生成AGV任务
/*if (AsnOrderTypeEnum.PRODUCT.getValue().equals(inboundRequest.getType()) && station != null) { if (AsnOrderTypeEnum.PRODUCT.getValue().equals(inboundRequest.getType()) && station != null) {
agvTaskService.createAgvTask(asn.getId(), stock.getStockCode(), srcPoint.getPointCode(), station.getPointCode(), null, BusinessTypeEnum.INBOUND.getValue(), 0, AgvVendorEnum.HIK.getValue()); agvTaskService.createAgvTask(asn.getId(), stock.getStockCode(), srcPoint.getPointCode(), station.getPointCode(), null, BusinessTypeEnum.INBOUND.getValue(), 0, AgvVendorEnum.HIK.getValue());
}*/ }
} }
/** /**
@ -189,7 +189,7 @@ public class AsnDetailServiceImpl extends ServiceImpl<AsnDetailMapper, AsnDetail
.receivedQty(BigDecimal.ZERO) .receivedQty(BigDecimal.ZERO)
.stockId(stock.getId()) .stockId(stock.getId())
.fromPointId(srcPoint == null ? null : srcPoint.getId()) .fromPointId(srcPoint == null ? null : srcPoint.getId())
.stationId(station== null ? null : station.getId()) .stationId(station == null ? null : station.getId())
.status(AsnStatusEnum.CREATED.getValue()) .status(AsnStatusEnum.CREATED.getValue())
.project(detail.getProject()) .project(detail.getProject())
.taskNo(detail.getTaskNo()) .taskNo(detail.getTaskNo())

View File

@ -105,11 +105,11 @@ public class InBoundTaskProcessor {
throw new RuntimeException("【" + inboundRequest.getType() + "】任务类型错误"); throw new RuntimeException("【" + inboundRequest.getType() + "】任务类型错误");
} }
if (AsnOrderTypeEnum.PRODUCT.getValue().equals(inboundRequest.getType())) { /* if (AsnOrderTypeEnum.PRODUCT.getValue().equals(inboundRequest.getType())) {
if (StringUtils.isBlank(inboundRequest.getLocationFrom())) { if (StringUtils.isBlank(inboundRequest.getLocationFrom())) {
throw new RuntimeException("起点(LocationFrom)必填"); throw new RuntimeException("起点(LocationFrom)必填");
} }
} }*/
if (CollectionUtils.isEmpty(inboundRequest.getDetails())) { if (CollectionUtils.isEmpty(inboundRequest.getDetails())) {
throw new RuntimeException("入库信息不能为空"); throw new RuntimeException("入库信息不能为空");
@ -214,7 +214,7 @@ public class InBoundTaskProcessor {
*/ */
private Point validateSrcPoint(Integer orderType, String srcPointCode) { private Point validateSrcPoint(Integer orderType, String srcPointCode) {
Point srcPoint = null; Point srcPoint = null;
if (AsnOrderTypeEnum.PRODUCT.getValue().equals(orderType)) { if (AsnOrderTypeEnum.PRODUCT.getValue().equals(orderType) && StringUtils.isNotBlank(srcPointCode)) {
srcPoint = pointService.validatePoint(srcPointCode); srcPoint = pointService.validatePoint(srcPointCode);
} }
return srcPoint; return srcPoint;

View File

@ -68,7 +68,7 @@ public class OutBoundTaskProcessor {
Map<String, Stock> stockMap = validateStock(outboundRequest.getDetails()); Map<String, Stock> stockMap = validateStock(outboundRequest.getDetails());
//5.出库处理 //5.出库处理
pickDetailService.processOutBoundTask(outboundRequest, itemMap,stockMap); pickDetailService.processOutBoundTask(outboundRequest, itemMap, stockMap);
} }
/** /**
@ -159,8 +159,8 @@ public class OutBoundTaskProcessor {
* @param detail * @param detail
*/ */
private Map<String, Stock> validateStock(List<OutboundRequest.OutboundDetail> detail) { private Map<String, Stock> validateStock(List<OutboundRequest.OutboundDetail> detail) {
//获取明细中所有的容器 //获取明细中所有的容器,
List<String> stockCodes = detail.stream().map(OutboundRequest.OutboundDetail::getLpn).toList(); List<String> stockCodes = detail.stream().map(OutboundRequest.OutboundDetail::getLpn).filter(StringUtils::isNotBlank).toList();
if (CollectionUtils.isNotEmpty(stockCodes)) { if (CollectionUtils.isNotEmpty(stockCodes)) {
//获取数据库已存在容器 //获取数据库已存在容器
Map<String, Stock> exitStockMap = stockService.queryByStockCodesToMap(stockCodes); Map<String, Stock> exitStockMap = stockService.queryByStockCodesToMap(stockCodes);

View File

@ -15,6 +15,7 @@ import org.cpte.modules.base.service.processor.BatchProcessor;
import org.cpte.modules.constant.GeneralConstant; import org.cpte.modules.constant.GeneralConstant;
import org.cpte.modules.constant.enums.*; import org.cpte.modules.constant.enums.*;
import org.cpte.modules.conveyorLine.service.processor.ScanTrayProcessor; import org.cpte.modules.conveyorLine.service.processor.ScanTrayProcessor;
import org.cpte.modules.conveyorLine.vo.Station;
import org.cpte.modules.inventory.entity.Inventory; import org.cpte.modules.inventory.entity.Inventory;
import org.cpte.modules.inventory.mapper.InventoryMapper; import org.cpte.modules.inventory.mapper.InventoryMapper;
import org.cpte.modules.inventoryLog.service.IInventoryLogService; import org.cpte.modules.inventoryLog.service.IInventoryLogService;
@ -155,11 +156,11 @@ public class AllocateProcessor {
data.setItemMap(itemMap); data.setItemMap(itemMap);
//筛选查询库存的条件(非空去重)外部仓库、项目号、任务号、批次、外部库存状态 //筛选查询库存的条件(非空去重)外部仓库、项目号、任务号、批次、外部库存状态
List<String> whCodeList = pickMap.values().stream().map(Pick::getWhCode).filter(StringUtils::isNotBlank).distinct().toList(); List<String> whCodeList = pickMap.values().stream().map(Pick::getWhCode).distinct().toList();
List<String> projectList = pickDetails.stream().map(PickDetail::getProject).filter(StringUtils::isNotBlank).distinct().toList(); List<String> projectList = pickDetails.stream().map(PickDetail::getProject).distinct().toList();
List<String> taskNoList = pickDetails.stream().map(PickDetail::getTaskNo).filter(StringUtils::isNotBlank).distinct().toList(); List<String> taskNoList = pickDetails.stream().map(PickDetail::getTaskNo).distinct().toList();
List<String> propC1List = pickDetails.stream().map(PickDetail::getPropC1).filter(StringUtils::isNotBlank).distinct().toList(); List<String> propC1List = pickDetails.stream().map(PickDetail::getPropC1).distinct().toList();
List<String> propC3List = pickDetails.stream().map(PickDetail::getPropC3).filter(StringUtils::isNotBlank).distinct().toList(); List<String> propC3List = pickDetails.stream().map(PickDetail::getPropC3).distinct().toList();
List<ItemKey> itemKeys = itemKeyMapper.queryItemKeys(itemIds, whCodeList, projectList, taskNoList, propC1List, propC3List); List<ItemKey> itemKeys = itemKeyMapper.queryItemKeys(itemIds, whCodeList, projectList, taskNoList, propC1List, propC3List);
//根据物料属性分组 //根据物料属性分组
@ -481,15 +482,76 @@ public class AllocateProcessor {
* @return * @return
*/ */
private Point getBestOutboundPoint(Point currPoint, List<Point> outPoints) { private Point getBestOutboundPoint(Point currPoint, List<Point> outPoints) {
//获取距离最近的出库口 //提升机第一层的坐标
return outPoints.stream() Station oneHoist = new Station(4160, 12080);
.min(Comparator.comparingDouble(point -> //提升机第二层的坐标
Math.abs(currPoint.getPositionX() - point.getPositionX()) + Station twoHoist = new Station(94160, 12080);
Math.abs(currPoint.getPositionY() - point.getPositionY()))) // 获取当前库位所在的层数
.orElse(null); int currentLayer = Integer.parseInt(currPoint.getLayerNum());
// 用于存储最佳出库口
Point bestOutPoint = null;
//最小总距离
double minTotalDistance = Double.MAX_VALUE;
// 遍历所有出库口,计算每个出库口的总距离
for (Point outPoint : outPoints) {
double totalDistance = 0;
if (CommonStatusEnum.ONE.getValue().equals(currentLayer)) {
// 如果是第一层:当前库位到第一层提升机的距离 + 第一层提升机到出库口的距离
double currToHoist = calculateManhattanDistance(currPoint, oneHoist);
double hoistToOut = calculateManhattanDistance(oneHoist, outPoint);
totalDistance = currToHoist + hoistToOut;
} else if (CommonStatusEnum.TWO.getValue().equals(currentLayer)) {
// 当前库位到第二层提升机的距离
double currToTwoHoist = calculateManhattanDistance(currPoint, twoHoist);
// 第二层提升机到第一层提升机的距离
double twoHoistToOneHoist = calculateManhattanDistance(twoHoist, oneHoist);
// 第一层提升机到出库口的距离
double oneHoistToOut = calculateManhattanDistance(oneHoist, outPoint);
totalDistance = currToTwoHoist + twoHoistToOneHoist + oneHoistToOut;
}
// 如果当前出库口的总距离更小,更新最佳出库口
if (totalDistance < minTotalDistance) {
minTotalDistance = totalDistance;
bestOutPoint = outPoint;
}
}
return bestOutPoint;
} }
// 重载方法用于计算Station和Station之间的曼哈顿距离
private double calculateManhattanDistance(Station station, Station station2) {
int dx = Math.abs(station.getPositionX() - station2.getPositionX());
int dy = Math.abs(station.getPositionY() - station2.getPositionY());
return dx + dy; // 曼哈顿距离
}
// 重载方法用于计算Station和Point之间的曼哈顿距离
private double calculateManhattanDistance(Station station, Point point) {
// 假设Station也有getX()和getY()方法
int dx = Math.abs(station.getPositionX() - point.getPositionX());
int dy = Math.abs(station.getPositionY() - point.getPositionY());
return dx + dy; // 曼哈顿距离
}
// 重载方法用于计算Point和Station之间的曼哈顿距离
private double calculateManhattanDistance(Point point,Station station) {
// 假设Station也有getX()和getY()方法
int dx = Math.abs(station.getPositionX() - point.getPositionX());
int dy = Math.abs(station.getPositionY() - point.getPositionY());
return dx + dy; // 曼哈顿距离
}
/** /**
* *
* *
@ -611,7 +673,7 @@ public class AllocateProcessor {
Point fromPoint = data.getPointMap().get(inventory.getPointId()); Point fromPoint = data.getPointMap().get(inventory.getPointId());
// 判断是否整托分配 // 判断是否整托分配
BigDecimal originalAvailableQty = BigDecimalUtil.subtract(inventory.getQuantity(), inventory.getQueuedQty(), 0); BigDecimal originalAvailableQty = inventory.getQuantity();
Integer izAll = originalAvailableQty.compareTo(allocateQty) == 0 ? 0 : 1; Integer izAll = originalAvailableQty.compareTo(allocateQty) == 0 ? 0 : 1;
// 目标库位 // 目标库位

View File

@ -155,7 +155,7 @@ spring:
password: Youchain@56 password: Youchain@56
driver-class-name: com.mysql.cj.jdbc.Driver driver-class-name: com.mysql.cj.jdbc.Driver
# # shardingjdbc数据源 # # shardingjdbc数据源
# sharding-db: # sharding-db: 47.103.100.52 10.254.27.192
# driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver # driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
# url: jdbc:shardingsphere:classpath:sharding.yaml # url: jdbc:shardingsphere:classpath:sharding.yaml
#redis 配置 #redis 配置
@ -280,6 +280,7 @@ jeecg:
#分布式锁配置 #分布式锁配置
redisson: redisson:
address: 47.117.45.79:6379 address: 47.117.45.79:6379
#address: 10.254.27.192:6379
password: cpte@123 password: cpte@123
type: STANDALONE type: STANDALONE
enabled: true enabled: true

File diff suppressed because it is too large Load Diff