no message
parent
d8b84477ad
commit
31d08765ab
|
|
@ -56,7 +56,6 @@ public interface AgvTaskMapper extends BaseMapper<AgvTask> {
|
|||
*
|
||||
* @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);
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1,5 +1,21 @@
|
|||
<?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">
|
||||
<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>
|
||||
|
|
@ -22,4 +22,7 @@ public interface AreaMapper extends BaseMapper<Area> {
|
|||
*/
|
||||
@Select("select * from base_area where area_code = #{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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,6 +33,9 @@ public class SyncPointProcessor {
|
|||
|
||||
public Boolean syncPoint(Area area, JSONObject pointJsonObject) {
|
||||
try {
|
||||
if(pointJsonObject==null){
|
||||
return Boolean.TRUE;
|
||||
}
|
||||
JSONArray laneListArray = extractLaneList(pointJsonObject);
|
||||
if (CollectionUtils.isEmpty(laneListArray)) {
|
||||
return Boolean.TRUE;
|
||||
|
|
@ -136,15 +139,43 @@ public class SyncPointProcessor {
|
|||
if (CollectionUtils.isEmpty(nodeArray)) {
|
||||
return;
|
||||
}
|
||||
|
||||
int lineNo = 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++) {
|
||||
JSONObject nodeObject = nodeArray.getJSONObject(j);
|
||||
processSingleNode(area, nodeObject, colNum, String.valueOf(lineNo),
|
||||
processSingleNode(area, nodeObject, colNum, String.valueOf(j + 1),
|
||||
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,13 +208,10 @@ public class SyncPointProcessor {
|
|||
rowNum, positionX, positionY, izDoubleLane);
|
||||
data.addInsertPoint(newPoint);
|
||||
} else {
|
||||
if (isPointChanged(existingPoint, colNum, layerNum, rowNum,
|
||||
positionX, positionY, izDoubleLane)) {
|
||||
updatePointFrom(existingPoint, colNum, layerNum, rowNum,
|
||||
updatePointFrom(existingPoint, rowNum, colNum, layerNum,
|
||||
positionX, positionY, izDoubleLane);
|
||||
data.addUpdatePoint(existingPoint);
|
||||
}
|
||||
}
|
||||
|
||||
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) ||
|
||||
!Objects.equals(point.getColNum(), colNum) ||
|
||||
!Objects.equals(point.getLayerNum(), layerNum) ||
|
||||
!Objects.equals(point.getPositionX(), positionX) ||
|
||||
!Objects.equals(point.getPositionY(), positionY) ||
|
||||
!Objects.equals(point.getIzDoubleLane(), izDoubleLane);
|
||||
}
|
||||
}*/
|
||||
|
||||
/**
|
||||
* 更新物料信息
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@ import org.apache.commons.collections4.CollectionUtils;
|
|||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.cpte.modules.agvTask.entity.AgvTask;
|
||||
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.conveyorLine.request.ScanTrayRequest;
|
||||
import org.cpte.modules.conveyorLine.service.IConveyorLineService;
|
||||
|
|
@ -23,7 +25,7 @@ import java.util.List;
|
|||
public class IConveyorLineServiceImpl implements IConveyorLineService {
|
||||
|
||||
@Autowired
|
||||
private TaskMapper taskMapper;
|
||||
private AreaMapper areaMapper;
|
||||
|
||||
@Autowired
|
||||
private AgvTaskMapper agvTaskMapper;
|
||||
|
|
@ -63,22 +65,32 @@ public class IConveyorLineServiceImpl implements IConveyorLineService {
|
|||
jsonObject.put("endCode", "");
|
||||
jsonObject.put("izAll", "");
|
||||
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);
|
||||
if (agvTask == null) {
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
List<Task> tasks = taskMapper.queryByAgvTask(agvTask.getId());
|
||||
if (CollectionUtils.isEmpty(tasks)) {
|
||||
return jsonObject;
|
||||
if(BusinessTypeEnum.INBOUND.getValue().equals(agvTask.getType())){
|
||||
//先查询扫描成功的日志并返回成功描述信息,如果没有则返回扫描异常信息
|
||||
}
|
||||
|
||||
String stockCode = tasks.get(0).getStockCode();
|
||||
String stockCode = agvTask.getCarrierCode();
|
||||
String taskType = BusinessTypeEnum.getDescByValue(agvTask.getType());
|
||||
String endCode = agvTask.getEndCode();
|
||||
String izAll = agvTask.getIzAll() == 1 ? "拆托" : "整托";
|
||||
String description = izAll.equals("拆托")
|
||||
description = izAll.equals("拆托")
|
||||
? "请人工将托盘【" + stockCode + "】叉走,避免任务拥堵"
|
||||
: "请等待AGV将托盘【" + stockCode + "】叉走";
|
||||
|
||||
|
|
|
|||
|
|
@ -11,10 +11,7 @@ import org.quartz.Job;
|
|||
import org.quartz.JobExecutionContext;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
|
|
@ -30,9 +27,6 @@ public class AllocateJob implements Job {
|
|||
@Autowired
|
||||
private IPickService pickService;
|
||||
|
||||
@Autowired
|
||||
private ITaskService iTaskService;
|
||||
|
||||
@Autowired
|
||||
private BaseCommonService baseCommonService;
|
||||
|
||||
|
|
@ -42,28 +36,32 @@ public class AllocateJob implements Job {
|
|||
// 缓存最大大小,防止内存溢出
|
||||
private static final int MAX_CACHE_SIZE = 1000;
|
||||
|
||||
// 使用静态变量跟踪当前分配位置
|
||||
private static volatile int currentIndex = 0;
|
||||
// 记录上次分配的索引
|
||||
private int lastProcessedIndex = -1;
|
||||
|
||||
@Override
|
||||
public void execute(JobExecutionContext jobExecutionContext) {
|
||||
// 查询未分配或者部分分配的出库
|
||||
List<Long> pickList = pickMapper.queryUnallocatedPick();
|
||||
if (CollectionUtils.isNotEmpty(pickList)) {
|
||||
// 轮询分配,每次只处理一个ID
|
||||
if (currentIndex < pickList.size()) {
|
||||
Long currentPickId = pickList.get(currentIndex);
|
||||
List<Long> singlePickList = List.of(currentPickId);
|
||||
if (CollectionUtils.isEmpty(pickList)) {
|
||||
log.info("没有待分配的出库单");
|
||||
lastProcessedIndex = -1; // 重置索引
|
||||
return;
|
||||
}
|
||||
pickList.sort(Long::compareTo);
|
||||
|
||||
int currentIndex = (lastProcessedIndex + 1) % pickList.size();
|
||||
Long pickId = pickList.get(currentIndex);
|
||||
|
||||
log.info("上次分配索引: {}, 本次分配索引: {}, 分配出库单ID: {}", lastProcessedIndex, currentIndex, pickId);
|
||||
|
||||
|
||||
// 分配单个出库单
|
||||
long startTime = System.currentTimeMillis();
|
||||
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);
|
||||
|
||||
// 每次只分配一个出库单
|
||||
resultMsg = pickService.allocatePick(Collections.singletonList(pickId));
|
||||
if (CollectionUtils.isNotEmpty(resultMsg)) {
|
||||
// 生成缓存键
|
||||
String cacheKey = generateCacheKey(resultMsg);
|
||||
|
|
@ -83,17 +81,18 @@ public class AllocateJob implements Job {
|
|||
}
|
||||
}
|
||||
|
||||
// 更新索引,循环使用
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -46,16 +46,10 @@ public class SyncPointJob implements Job {
|
|||
Integer pageSize = Integer.parseInt(params.getString("pageSize"));
|
||||
Integer pageNum = Integer.parseInt(params.getString("pageNum"));
|
||||
|
||||
// 检查是否需要处理
|
||||
if (pageNum >= MAX_PAGE_NUM) {
|
||||
log.info("已处理到最新页数,无需继续查询");
|
||||
return;
|
||||
}
|
||||
pageNum = getLastProcessedKey(pageNum);
|
||||
log.info("当前页数: {} - 每页条数: {}", pageNum, pageSize);
|
||||
boolean success = pointService.syncPoint(regionCode, pageNum, pageSize);
|
||||
if (success) {
|
||||
updateLastProcessedDate(pageNum);
|
||||
log.info("同步库位成功");
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取上次处理的页数+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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import org.cpte.modules.constant.GeneralConstant;
|
|||
import org.cpte.modules.constant.enums.AgvStatusEnum;
|
||||
import org.cpte.modules.constant.enums.AgvVendorEnum;
|
||||
import org.cpte.modules.hikAgv.service.IHikAgvService;
|
||||
import org.cpte.modules.shipping.service.ITaskService;
|
||||
import org.cpte.modules.tesAgv.service.ITesAgvService;
|
||||
import org.quartz.Job;
|
||||
import org.quartz.JobExecutionContext;
|
||||
|
|
@ -17,6 +18,10 @@ import java.util.List;
|
|||
|
||||
@Slf4j
|
||||
public class TesAgvJob implements Job {
|
||||
|
||||
@Autowired
|
||||
private ITaskService iTaskService;
|
||||
|
||||
@Autowired
|
||||
private AgvTaskMapper agvTaskMapper;
|
||||
|
||||
|
|
@ -25,6 +30,13 @@ public class TesAgvJob implements Job {
|
|||
|
||||
@Override
|
||||
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());
|
||||
if (agvTaskList.isEmpty()) {
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ public class AsnDetailServiceImpl extends ServiceImpl<AsnDetailMapper, AsnDetail
|
|||
public void processInboundTask(InboundRequest inboundRequest, Map<String, Item> itemMap, Point srcPoint, Stock stock) {
|
||||
//1.获取工作站
|
||||
Point station = null;
|
||||
if (AsnOrderTypeEnum.PRODUCT.getValue().equals(inboundRequest.getType())) {
|
||||
if (AsnOrderTypeEnum.PRODUCT.getValue().equals(inboundRequest.getType()) && srcPoint != null) {
|
||||
station = getStationPoint(inboundRequest.getType());
|
||||
}
|
||||
|
||||
|
|
@ -108,9 +108,9 @@ public class AsnDetailServiceImpl extends ServiceImpl<AsnDetailMapper, AsnDetail
|
|||
stockService.bindStock(stock);
|
||||
|
||||
//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());
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -189,7 +189,7 @@ public class AsnDetailServiceImpl extends ServiceImpl<AsnDetailMapper, AsnDetail
|
|||
.receivedQty(BigDecimal.ZERO)
|
||||
.stockId(stock.getId())
|
||||
.fromPointId(srcPoint == null ? null : srcPoint.getId())
|
||||
.stationId(station== null ? null : station.getId())
|
||||
.stationId(station == null ? null : station.getId())
|
||||
.status(AsnStatusEnum.CREATED.getValue())
|
||||
.project(detail.getProject())
|
||||
.taskNo(detail.getTaskNo())
|
||||
|
|
|
|||
|
|
@ -105,11 +105,11 @@ public class InBoundTaskProcessor {
|
|||
throw new RuntimeException("【" + inboundRequest.getType() + "】任务类型错误");
|
||||
}
|
||||
|
||||
if (AsnOrderTypeEnum.PRODUCT.getValue().equals(inboundRequest.getType())) {
|
||||
/* if (AsnOrderTypeEnum.PRODUCT.getValue().equals(inboundRequest.getType())) {
|
||||
if (StringUtils.isBlank(inboundRequest.getLocationFrom())) {
|
||||
throw new RuntimeException("起点(LocationFrom)必填");
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if (CollectionUtils.isEmpty(inboundRequest.getDetails())) {
|
||||
throw new RuntimeException("入库信息不能为空");
|
||||
|
|
@ -214,7 +214,7 @@ public class InBoundTaskProcessor {
|
|||
*/
|
||||
private Point validateSrcPoint(Integer orderType, String srcPointCode) {
|
||||
Point srcPoint = null;
|
||||
if (AsnOrderTypeEnum.PRODUCT.getValue().equals(orderType)) {
|
||||
if (AsnOrderTypeEnum.PRODUCT.getValue().equals(orderType) && StringUtils.isNotBlank(srcPointCode)) {
|
||||
srcPoint = pointService.validatePoint(srcPointCode);
|
||||
}
|
||||
return srcPoint;
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ public class OutBoundTaskProcessor {
|
|||
Map<String, Stock> stockMap = validateStock(outboundRequest.getDetails());
|
||||
|
||||
//5.出库处理
|
||||
pickDetailService.processOutBoundTask(outboundRequest, itemMap,stockMap);
|
||||
pickDetailService.processOutBoundTask(outboundRequest, itemMap, stockMap);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -159,8 +159,8 @@ public class OutBoundTaskProcessor {
|
|||
* @param 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)) {
|
||||
//获取数据库已存在容器
|
||||
Map<String, Stock> exitStockMap = stockService.queryByStockCodesToMap(stockCodes);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import org.cpte.modules.base.service.processor.BatchProcessor;
|
|||
import org.cpte.modules.constant.GeneralConstant;
|
||||
import org.cpte.modules.constant.enums.*;
|
||||
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.mapper.InventoryMapper;
|
||||
import org.cpte.modules.inventoryLog.service.IInventoryLogService;
|
||||
|
|
@ -155,11 +156,11 @@ public class AllocateProcessor {
|
|||
data.setItemMap(itemMap);
|
||||
|
||||
//筛选查询库存的条件(非空去重)外部仓库、项目号、任务号、批次、外部库存状态
|
||||
List<String> whCodeList = pickMap.values().stream().map(Pick::getWhCode).filter(StringUtils::isNotBlank).distinct().toList();
|
||||
List<String> projectList = pickDetails.stream().map(PickDetail::getProject).filter(StringUtils::isNotBlank).distinct().toList();
|
||||
List<String> taskNoList = pickDetails.stream().map(PickDetail::getTaskNo).filter(StringUtils::isNotBlank).distinct().toList();
|
||||
List<String> propC1List = pickDetails.stream().map(PickDetail::getPropC1).filter(StringUtils::isNotBlank).distinct().toList();
|
||||
List<String> propC3List = pickDetails.stream().map(PickDetail::getPropC3).filter(StringUtils::isNotBlank).distinct().toList();
|
||||
List<String> whCodeList = pickMap.values().stream().map(Pick::getWhCode).distinct().toList();
|
||||
List<String> projectList = pickDetails.stream().map(PickDetail::getProject).distinct().toList();
|
||||
List<String> taskNoList = pickDetails.stream().map(PickDetail::getTaskNo).distinct().toList();
|
||||
List<String> propC1List = pickDetails.stream().map(PickDetail::getPropC1).distinct().toList();
|
||||
List<String> propC3List = pickDetails.stream().map(PickDetail::getPropC3).distinct().toList();
|
||||
List<ItemKey> itemKeys = itemKeyMapper.queryItemKeys(itemIds, whCodeList, projectList, taskNoList, propC1List, propC3List);
|
||||
|
||||
//根据物料属性分组
|
||||
|
|
@ -481,15 +482,76 @@ public class AllocateProcessor {
|
|||
* @return 最佳出库口
|
||||
*/
|
||||
private Point getBestOutboundPoint(Point currPoint, List<Point> outPoints) {
|
||||
//获取距离最近的出库口
|
||||
return outPoints.stream()
|
||||
.min(Comparator.comparingDouble(point ->
|
||||
Math.abs(currPoint.getPositionX() - point.getPositionX()) +
|
||||
Math.abs(currPoint.getPositionY() - point.getPositionY())))
|
||||
.orElse(null);
|
||||
//提升机第一层的坐标
|
||||
Station oneHoist = new Station(4160, 12080);
|
||||
//提升机第二层的坐标
|
||||
Station twoHoist = new Station(94160, 12080);
|
||||
// 获取当前库位所在的层数
|
||||
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());
|
||||
|
||||
// 判断是否整托分配
|
||||
BigDecimal originalAvailableQty = BigDecimalUtil.subtract(inventory.getQuantity(), inventory.getQueuedQty(), 0);
|
||||
BigDecimal originalAvailableQty = inventory.getQuantity();
|
||||
Integer izAll = originalAvailableQty.compareTo(allocateQty) == 0 ? 0 : 1;
|
||||
|
||||
// 目标库位
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ spring:
|
|||
password: Youchain@56
|
||||
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||
# # shardingjdbc数据源
|
||||
# sharding-db:
|
||||
# sharding-db: 47.103.100.52 10.254.27.192
|
||||
# driver-class-name: org.apache.shardingsphere.driver.ShardingSphereDriver
|
||||
# url: jdbc:shardingsphere:classpath:sharding.yaml
|
||||
#redis 配置
|
||||
|
|
@ -280,6 +280,7 @@ jeecg:
|
|||
#分布式锁配置
|
||||
redisson:
|
||||
address: 47.117.45.79:6379
|
||||
#address: 10.254.27.192:6379
|
||||
password: cpte@123
|
||||
type: STANDALONE
|
||||
enabled: true
|
||||
|
|
|
|||
2336
hs_err_pid20204.log
2336
hs_err_pid20204.log
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue