no message
parent
f521e2cb73
commit
d73d0d454f
|
|
@ -93,6 +93,22 @@ public class Point implements Serializable {
|
|||
@Schema(description = "位置坐标y")
|
||||
private java.lang.Integer positionY;
|
||||
|
||||
|
||||
/**
|
||||
* 位置坐标x
|
||||
*/
|
||||
@Excel(name = "第二层坐标X", width = 15)
|
||||
@Schema(description = "位置坐标x")
|
||||
private java.lang.Integer positionTwoX;
|
||||
|
||||
/**
|
||||
* 位置坐标y
|
||||
*/
|
||||
@Excel(name = "第二层坐标Y", width = 15)
|
||||
@Schema(description = "第二层坐标Y")
|
||||
private java.lang.Integer positionTwoY;
|
||||
|
||||
|
||||
/**
|
||||
* 是否双通道
|
||||
* 0-单通道 1-双通道
|
||||
|
|
|
|||
|
|
@ -48,4 +48,5 @@ public interface PointMapper extends BaseMapper<Point> {
|
|||
|
||||
@Select("SELECT * FROM base_point WHERE col_num = #{colNum} AND layer_num = #{layerNum} ORDER BY row_num ASC")
|
||||
List<Point> findByColAndLayer(@Param("colNum") String colNum, @Param("layerNum") String layerNum);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -7,6 +7,8 @@ import org.cpte.modules.base.entity.Point;
|
|||
import org.cpte.modules.base.entity.Stock;
|
||||
import org.cpte.modules.base.mapper.PointMapper;
|
||||
import org.cpte.modules.base.mapper.StockMapper;
|
||||
import org.cpte.modules.constant.enums.CommonStatusEnum;
|
||||
import org.cpte.modules.constant.enums.TaskTypeEnum;
|
||||
import org.cpte.modules.inventory.entity.Inventory;
|
||||
import org.cpte.modules.inventory.mapper.InventoryMapper;
|
||||
import org.cpte.modules.inventoryLog.entity.InventoryLog;
|
||||
|
|
@ -142,6 +144,7 @@ public class BatchProcessor {
|
|||
if (CollectionUtils.isNotEmpty(updateToPickDetail)) {
|
||||
batchUtil.updateBatchPickDetail(updateToPickDetail);
|
||||
}
|
||||
|
||||
if (CollectionUtils.isNotEmpty(deleteToTask)) {
|
||||
taskMapper.deleteByIds(deleteToTask);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,10 @@ public enum CommonStatusEnum {
|
|||
|
||||
USED(1, "占用"),
|
||||
|
||||
ONE(1, "一层"),
|
||||
|
||||
TWO(2, "二层"),
|
||||
|
||||
;
|
||||
/**
|
||||
* 值
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ import org.cpte.modules.constant.enums.*;
|
|||
import org.cpte.modules.conveyorLine.request.ScanTrayRequest;
|
||||
import org.cpte.modules.conveyorLine.vo.PointScore;
|
||||
import org.cpte.modules.conveyorLine.vo.ScanTrayData;
|
||||
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.receive.entity.Asn;
|
||||
|
|
@ -28,6 +29,7 @@ import org.springframework.stereotype.Service;
|
|||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* 扫描托盘处理
|
||||
|
|
@ -78,7 +80,7 @@ public class ScanTrayProcessor {
|
|||
|
||||
// 4.智能分配库位
|
||||
String areaCode = getAreaCode(data.getAsn().getOrderType());
|
||||
Point dstPoint = allocatePoint(data.getItemKeys(), data.getStation(), areaCode);
|
||||
Point dstPoint = allocatePoint(data.getItemKeys(), data.getStation(), areaCode, BusinessTypeEnum.INBOUND.getValue());
|
||||
|
||||
// 5.生成TES任务
|
||||
agvTaskService.processAgvTask(data, dstPoint);
|
||||
|
|
@ -192,21 +194,63 @@ public class ScanTrayProcessor {
|
|||
*
|
||||
* @param itemKeys 物料属性
|
||||
* @param station 工作站
|
||||
* @param areaCode 库区
|
||||
* @param type 业务类型
|
||||
* @return 目标库位
|
||||
*/
|
||||
public Point allocatePoint(List<ItemKey> itemKeys, Point station, String areaCode) {
|
||||
//1.优先寻找同物料/同仓库/同项目号/同任务号/同批次/同外部库存状态
|
||||
public Point allocatePoint(List<ItemKey> itemKeys, Point station, String areaCode, String type) {
|
||||
//1.优先寻找同物料/同仓库/同项目号/同任务号/同批次/同外部库存状态的库位
|
||||
List<Long> itemKeyIds = itemKeys.stream().map(ItemKey::getId).toList();
|
||||
List<Point> availablePoints = pointService.findClusterPoint(itemKeyIds, areaCode);
|
||||
if (CollectionUtils.isEmpty(availablePoints)) {
|
||||
//2.获取所有可用库位
|
||||
availablePoints = pointMapper.queryPoints(null, CommonStatusEnum.FREE.getValue(), areaCode);
|
||||
}
|
||||
//根据巷到分组,得到每个巷道有多个库位,<巷道编号,库位个数>
|
||||
//根据巷道分组,得到每个巷道有多个库位,<巷道编号,库位个数>
|
||||
Map<String, Long> colMap = getColMap(areaCode);
|
||||
|
||||
List<PointScore> scoredPoints = availablePoints.stream()
|
||||
.map(point -> clusterPointScore(point, station, itemKeys, colMap))
|
||||
//根据layerNum层来分组
|
||||
Map<String, List<Point>> layerMap = availablePoints.stream().collect(Collectors.groupingBy(Point::getLayerNum));
|
||||
|
||||
List<PointScore> firstScoredPoints = new ArrayList<>();
|
||||
List<PointScore> secondScoredPoints = new ArrayList<>();
|
||||
|
||||
//移位选择最优库位
|
||||
if (type.equals(BusinessTypeEnum.MOVE.getValue())) {
|
||||
String layerNum = station.getLayerNum();
|
||||
Station currentStation = new Station(station.getPositionX(), station.getPositionY());
|
||||
List<Point> firstLevelPoints = layerMap.get(layerNum);
|
||||
if (CollectionUtils.isNotEmpty(firstLevelPoints)) {
|
||||
firstScoredPoints = firstLevelPoints.stream()
|
||||
.map(point -> clusterPointScore(point, currentStation, itemKeys, colMap))
|
||||
.toList();
|
||||
}
|
||||
} else {
|
||||
//入库选择最优库位
|
||||
//计算第一层的库位分数
|
||||
Station firstStation = new Station(station.getPositionX(), station.getPositionY());
|
||||
List<Point> firstLevelPoints = layerMap.get(String.valueOf(CommonStatusEnum.ONE.getValue()));
|
||||
if (CollectionUtils.isNotEmpty(firstLevelPoints)) {
|
||||
firstScoredPoints = firstLevelPoints.stream()
|
||||
.map(point -> clusterPointScore(point, firstStation, itemKeys, colMap))
|
||||
.toList();
|
||||
}
|
||||
|
||||
//计算第二层的库位分数
|
||||
Station secondStation = new Station(station.getPositionTwoX(), station.getPositionTwoY());
|
||||
List<Point> secondLevelPoints = layerMap.get(String.valueOf(CommonStatusEnum.TWO.getValue()));
|
||||
if (CollectionUtils.isNotEmpty(secondLevelPoints)) {
|
||||
secondScoredPoints = secondLevelPoints.stream()
|
||||
.map(point -> clusterPointScore(point, secondStation, itemKeys, colMap))
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
//合并获取最优库位
|
||||
List<PointScore> scoredPoints = Stream.concat(
|
||||
firstScoredPoints.stream(),
|
||||
secondScoredPoints.stream()
|
||||
)
|
||||
.sorted(Comparator.comparing(PointScore::getScore).reversed())
|
||||
.toList();
|
||||
|
||||
|
|
@ -221,7 +265,7 @@ public class ScanTrayProcessor {
|
|||
/**
|
||||
* 库位评分计算
|
||||
*/
|
||||
private PointScore clusterPointScore(Point point, Point station, List<ItemKey> itemKeys, Map<String, Long> colMap) {
|
||||
private PointScore clusterPointScore(Point point, Station station, List<ItemKey> itemKeys, Map<String, Long> colMap) {
|
||||
double totalScore;
|
||||
|
||||
// 1. 距离评分 - 考虑从入库口到库位的距离
|
||||
|
|
@ -241,6 +285,7 @@ public class ScanTrayProcessor {
|
|||
|
||||
totalScore = distanceScore + channelDepthScore + channelScore;
|
||||
log.info("【{}】库位总分:{} - 距离评分: {} - 通道深度策略评分: {} - 通道类型评分: {} - 均衡评分: {} - 物料聚集评分: {}", point.getPointCode(), totalScore, distanceScore, channelDepthScore, channelScore, 0, 0);
|
||||
|
||||
return new PointScore(point, totalScore);
|
||||
}
|
||||
|
||||
|
|
@ -406,11 +451,13 @@ public class ScanTrayProcessor {
|
|||
* 计算距离评分
|
||||
* 基于入库口位置和库位坐标计算最短路径距离
|
||||
*/
|
||||
private double calculateClusterDistanceCost(Point point, Point station) {
|
||||
|
||||
private double calculateClusterDistanceCost(Point point, Station station) {
|
||||
// 计算曼哈顿距离
|
||||
double distance = Math.abs(point.getPositionX() - station.getPositionX()) + Math.abs(point.getPositionY() - station.getPositionY());
|
||||
|
||||
// 使用更大的标准化参数(根据实际坐标范围)
|
||||
double normalizationFactor = 250000.0; // 或使用动态计算的最大距离值
|
||||
double normalizationFactor = 300000.0;
|
||||
// 距离越小分数越高
|
||||
return Math.max(0, 100 - (distance / normalizationFactor) * 100);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
package org.cpte.modules.conveyorLine.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import org.cpte.modules.base.entity.Point;
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class Station {
|
||||
// X坐标
|
||||
private Integer positionX;
|
||||
// Y坐标
|
||||
private Integer positionY;
|
||||
}
|
||||
|
|
@ -12,7 +12,12 @@ import java.net.URLDecoder;
|
|||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.cpte.modules.base.entity.ItemKey;
|
||||
import org.cpte.modules.base.entity.Point;
|
||||
import org.cpte.modules.base.entity.Stock;
|
||||
import org.cpte.modules.base.mapper.PointMapper;
|
||||
import org.cpte.modules.base.mapper.StockMapper;
|
||||
import org.cpte.modules.base.service.IItemKeyService;
|
||||
import org.cpte.modules.constant.enums.CommonStatusEnum;
|
||||
import org.jeecg.common.api.vo.Result;
|
||||
import org.jeecg.common.system.query.QueryGenerator;
|
||||
import org.jeecg.common.system.query.QueryRuleEnum;
|
||||
|
|
@ -53,12 +58,19 @@ import org.apache.shiro.authz.annotation.RequiresPermissions;
|
|||
@RequestMapping("/inventory")
|
||||
@Slf4j
|
||||
public class InventoryController extends JeecgController<Inventory, IInventoryService> {
|
||||
@Autowired
|
||||
private StockMapper stockMapper;
|
||||
|
||||
@Autowired
|
||||
private PointMapper pointMapper;
|
||||
|
||||
@Autowired
|
||||
private IInventoryService inventoryService;
|
||||
|
||||
@Autowired
|
||||
private IItemKeyService itemKeyService;
|
||||
|
||||
|
||||
/**
|
||||
* 分页列表查询
|
||||
*
|
||||
|
|
@ -125,6 +137,15 @@ public class InventoryController extends JeecgController<Inventory, IInventorySe
|
|||
@RequiresPermissions("inventory:data_inventory:edit")
|
||||
@RequestMapping(value = "/edit", method = {RequestMethod.PUT, RequestMethod.POST})
|
||||
public Result<String> edit(@RequestBody Inventory inventory) {
|
||||
Inventory oldInventory = inventoryService.getById(inventory.getId());
|
||||
Point oldPoint = pointMapper.selectById(oldInventory.getPointId());
|
||||
Point newPoint = pointMapper.selectById(inventory.getPointId());
|
||||
if(!oldPoint.getId().equals(newPoint.getId())){
|
||||
oldPoint.setStatus(CommonStatusEnum.FREE.getValue());
|
||||
pointMapper.updateById(oldPoint);
|
||||
newPoint.setStatus(CommonStatusEnum.USED.getValue());
|
||||
pointMapper.updateById(newPoint);
|
||||
}
|
||||
ItemKey itemKey = itemKeyService.createItemKey(inventory.getItemId(), inventory.getWhCode(), inventory.getProject(), inventory.getTaskNo(), inventory.getPropC1(), inventory.getPropC3());
|
||||
inventory.setItemKeyId(itemKey.getId());
|
||||
inventoryService.updateById(inventory);
|
||||
|
|
@ -142,6 +163,17 @@ public class InventoryController extends JeecgController<Inventory, IInventorySe
|
|||
@RequiresPermissions("inventory:data_inventory:delete")
|
||||
@DeleteMapping(value = "/delete")
|
||||
public Result<String> delete(@RequestParam(name = "id", required = true) String id) {
|
||||
Inventory inventory = inventoryService.getById(id);
|
||||
Stock stock = stockMapper.selectById(inventory.getStockId());
|
||||
if (stock != null) {
|
||||
stock.setStatus(CommonStatusEnum.FREE.getValue());
|
||||
stockMapper.updateById(stock);
|
||||
}
|
||||
Point point = pointMapper.selectById(inventory.getPointId());
|
||||
if (point != null) {
|
||||
point.setStatus(CommonStatusEnum.FREE.getValue());
|
||||
pointMapper.updateById(point);
|
||||
}
|
||||
inventoryService.removeById(id);
|
||||
return Result.OK("删除成功!");
|
||||
}
|
||||
|
|
@ -157,7 +189,21 @@ public class InventoryController extends JeecgController<Inventory, IInventorySe
|
|||
@RequiresPermissions("inventory:data_inventory:deleteBatch")
|
||||
@DeleteMapping(value = "/deleteBatch")
|
||||
public Result<String> deleteBatch(@RequestParam(name = "ids", required = true) String ids) {
|
||||
this.inventoryService.removeByIds(Arrays.asList(ids.split(",")));
|
||||
List<Long> invIds = Arrays.stream(ids.split(",")).map(Long::parseLong).toList();
|
||||
List<Inventory> inventories = inventoryService.listByIds(invIds);
|
||||
for (Inventory inventory : inventories) {
|
||||
Stock stock = stockMapper.selectById(inventory.getStockId());
|
||||
if (stock != null) {
|
||||
stock.setStatus(CommonStatusEnum.FREE.getValue());
|
||||
stockMapper.updateById(stock);
|
||||
}
|
||||
Point point = pointMapper.selectById(inventory.getPointId());
|
||||
if (point != null) {
|
||||
point.setStatus(CommonStatusEnum.FREE.getValue());
|
||||
pointMapper.updateById(point);
|
||||
}
|
||||
}
|
||||
this.inventoryService.removeByIds(invIds);
|
||||
return Result.OK("批量删除成功!");
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.extension.service.IService;
|
|||
import org.cpte.modules.receive.entity.Asn;
|
||||
import org.cpte.modules.receive.entity.AsnDetail;
|
||||
import org.cpte.modules.receive.entity.ReceiveRecord;
|
||||
import org.cpte.modules.shipping.entity.Task;
|
||||
|
||||
import java.math.BigDecimal;
|
||||
import java.util.List;
|
||||
|
|
@ -53,4 +54,10 @@ public interface IInventoryService extends IService<Inventory> {
|
|||
* @param stockIds 容器ID
|
||||
*/
|
||||
void deleteByStockIds(List<Long> stockIds);
|
||||
|
||||
/**
|
||||
* 移动库存
|
||||
* @param tasks 移位任务
|
||||
*/
|
||||
void moveInventory(List<Task> tasks);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,12 +2,17 @@ package org.cpte.modules.inventory.service.impl;
|
|||
|
||||
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.cpte.modules.base.entity.Point;
|
||||
import org.cpte.modules.base.mapper.PointMapper;
|
||||
import org.cpte.modules.constant.enums.CommonStatusEnum;
|
||||
import org.cpte.modules.constant.enums.InventoryStatusEnum;
|
||||
import org.cpte.modules.inventory.entity.Inventory;
|
||||
import org.cpte.modules.inventory.mapper.InventoryMapper;
|
||||
import org.cpte.modules.inventory.service.IInventoryService;
|
||||
import org.cpte.modules.receive.entity.Asn;
|
||||
import org.cpte.modules.receive.entity.ReceiveRecord;
|
||||
import org.cpte.modules.shipping.entity.Task;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
|
@ -23,6 +28,9 @@ import java.util.*;
|
|||
*/
|
||||
@Service
|
||||
public class InventoryServiceImpl extends ServiceImpl<InventoryMapper, Inventory> implements IInventoryService {
|
||||
@Autowired
|
||||
private PointMapper pointMapper;
|
||||
|
||||
@Override
|
||||
public Inventory buildInventory(Long stockId, BigDecimal receivedQty, Asn asn, ReceiveRecord receiveRecord) {
|
||||
return Inventory.builder()
|
||||
|
|
@ -82,5 +90,30 @@ public class InventoryServiceImpl extends ServiceImpl<InventoryMapper, Inventory
|
|||
this.baseMapper.deleteByStockIds(stockIds);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void moveInventory(List<Task> tasks) {
|
||||
List<Inventory> updateToInventoryList = new ArrayList<>();
|
||||
List<Point> updateToPointList = new ArrayList<>();
|
||||
for (Task task : tasks) {
|
||||
Inventory inventory = this.baseMapper.selectById(task.getInventoryId());
|
||||
inventory.setPointId(task.getToPointId());
|
||||
inventory.setStatus(InventoryStatusEnum.AVAILABLE.getValue());
|
||||
updateToInventoryList.add(inventory);
|
||||
}
|
||||
List<Long> srcPointIds = tasks.stream().map(Task::getFromPointId).distinct().toList();
|
||||
List<Point> srcPoints = pointMapper.selectByIds(srcPointIds);
|
||||
for (Point point : srcPoints) {
|
||||
point.setStatus(CommonStatusEnum.FREE.getValue());
|
||||
updateToPointList.add(point);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(updateToInventoryList)) {
|
||||
this.baseMapper.updateById(updateToInventoryList);
|
||||
}
|
||||
if (CollectionUtils.isNotEmpty(updateToPointList)) {
|
||||
pointMapper.updateById(updateToPointList);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ public interface AsnDetailMapper extends BaseMapper<AsnDetail> {
|
|||
* @param status 状态
|
||||
* @return AsnDetail
|
||||
*/
|
||||
@Select("select * from data_asn_detail where stock_id = #{stockId} and status = #{status} ")
|
||||
List<AsnDetail> queryByStockCode(@Param("stockId") Long stockId, @Param("status") Integer status);
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,4 +15,14 @@
|
|||
WHERE
|
||||
asn_id = #{mainId}
|
||||
</select>
|
||||
|
||||
<select id="queryByStockCode" resultType="org.cpte.modules.receive.entity.AsnDetail">
|
||||
SELECT *
|
||||
FROM data_asn_detail
|
||||
WHERE
|
||||
stock_id = #{stockId}
|
||||
<if test="status != null">
|
||||
AND status = #{status}
|
||||
</if>
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
|
|||
|
|
@ -11,13 +11,11 @@ import org.cpte.modules.base.service.IItemService;
|
|||
import org.cpte.modules.base.service.IPointService;
|
||||
import org.cpte.modules.base.service.IStockService;
|
||||
import org.cpte.modules.constant.GeneralConstant;
|
||||
import org.cpte.modules.constant.enums.AgvVendorEnum;
|
||||
import org.cpte.modules.constant.enums.AreaTypeEnum;
|
||||
import org.cpte.modules.constant.enums.AsnOrderTypeEnum;
|
||||
import org.cpte.modules.constant.enums.BusinessTypeEnum;
|
||||
import org.cpte.modules.constant.enums.*;
|
||||
import org.cpte.modules.inventory.mapper.InventoryMapper;
|
||||
import org.cpte.modules.receive.entity.Asn;
|
||||
import org.cpte.modules.receive.entity.AsnDetail;
|
||||
import org.cpte.modules.receive.mapper.AsnDetailMapper;
|
||||
import org.cpte.modules.receive.mapper.AsnMapper;
|
||||
import org.cpte.modules.receive.service.IAsnDetailService;
|
||||
import org.cpte.modules.receive.service.IAsnService;
|
||||
|
|
@ -42,6 +40,9 @@ public class InBoundTaskProcessor {
|
|||
@Autowired
|
||||
private AsnMapper asnMapper;
|
||||
|
||||
@Autowired
|
||||
private AsnDetailMapper asnDetailMapper;
|
||||
|
||||
@Autowired
|
||||
private InventoryMapper inventoryMapper;
|
||||
|
||||
|
|
@ -148,11 +149,24 @@ public class InBoundTaskProcessor {
|
|||
String lpn = lpns.iterator().next();
|
||||
Stock stock = stockService.validateStock(lpn);
|
||||
if (inventoryMapper.exitsStockInventory(stock.getId()) != null) {
|
||||
throw new RuntimeException("【" + lpn + "】托盘已入库");
|
||||
throw new RuntimeException("【" + lpn + "】托盘已入库,请勿下发");
|
||||
}
|
||||
|
||||
//验证托盘未完成,不能继续下发当前托盘的任务
|
||||
List<AsnDetail> asnDetail = asnDetailMapper.queryByStockCode(stock.getId(), null);
|
||||
boolean hasUnfinishedTask = asnDetail.stream().anyMatch(ad -> !isAsnCompleted(ad));
|
||||
if (hasUnfinishedTask) {
|
||||
throw new RuntimeException("【" + lpn + "】托盘任务未完成,请勿下发");
|
||||
}
|
||||
return stock;
|
||||
}
|
||||
|
||||
// 辅助方法 - 判断 ASN 是否已完成
|
||||
private boolean isAsnCompleted(AsnDetail asnDetail) {
|
||||
return AsnStatusEnum.CLOSED.getValue().equals(asnDetail.getStatus())
|
||||
|| AsnStatusEnum.CANCELED.getValue().equals(asnDetail.getStatus());
|
||||
}
|
||||
|
||||
/**
|
||||
* 验证任务号
|
||||
*
|
||||
|
|
|
|||
|
|
@ -31,4 +31,6 @@ public interface TaskMapper extends BaseMapper<Task> {
|
|||
|
||||
@Select("SELECT * FROM data_task WHERE pick_id = #{pickId} ")
|
||||
List<Task> queryTaskByMainId(@Param("pickId")Long pickId);
|
||||
|
||||
List<Task> queryByInventoryIds(@Param("inventoryIds") List<Long> inventoryIds);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,4 +8,12 @@
|
|||
#{pickId}
|
||||
</foreach>
|
||||
</select>
|
||||
|
||||
<select id="queryByInventoryIds" resultType="org.cpte.modules.shipping.entity.Task">
|
||||
SELECT * FROM data_task
|
||||
WHERE inventory_id IN
|
||||
<foreach collection="inventoryIds" item="inventoryId" open="(" separator="," close=")">
|
||||
#{inventoryId}
|
||||
</foreach>
|
||||
</select>
|
||||
</mapper>
|
||||
|
|
@ -64,4 +64,6 @@ public interface ITaskService extends IService<Task> {
|
|||
* @return List<Task>
|
||||
*/
|
||||
List<Task> queryTaskByMainId(Long id);
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ import org.apache.commons.lang3.StringUtils;
|
|||
import org.cpte.modules.base.entity.*;
|
||||
import org.cpte.modules.base.mapper.AreaMapper;
|
||||
import org.cpte.modules.base.mapper.ItemKeyMapper;
|
||||
import org.cpte.modules.base.mapper.PointMapper;
|
||||
import org.cpte.modules.base.service.IItemKeyService;
|
||||
import org.cpte.modules.base.service.IItemService;
|
||||
import org.cpte.modules.base.service.IPointService;
|
||||
|
|
@ -22,6 +23,7 @@ import org.cpte.modules.shipping.entity.Pick;
|
|||
import org.cpte.modules.shipping.entity.PickDetail;
|
||||
import org.cpte.modules.shipping.entity.Task;
|
||||
import org.cpte.modules.shipping.mapper.PickDetailMapper;
|
||||
import org.cpte.modules.shipping.mapper.TaskMapper;
|
||||
import org.cpte.modules.shipping.service.IPickDetailService;
|
||||
import org.cpte.modules.shipping.service.ITaskService;
|
||||
import org.cpte.modules.shipping.vo.AllocationData;
|
||||
|
|
@ -46,12 +48,17 @@ public class AllocateProcessor {
|
|||
@Autowired
|
||||
private AreaMapper areaMapper;
|
||||
|
||||
@Autowired
|
||||
private PointMapper pointMapper;
|
||||
|
||||
@Autowired
|
||||
private PickDetailMapper pickDetailMapper;
|
||||
|
||||
@Autowired
|
||||
private ItemKeyMapper itemKeyMapper;
|
||||
|
||||
|
||||
|
||||
@Autowired
|
||||
private InventoryMapper inventoryMapper;
|
||||
|
||||
|
|
@ -391,18 +398,6 @@ public class AllocateProcessor {
|
|||
.toList();
|
||||
Map<Long, Point> pointMap = pointService.queryByPointIdsToMap(pointIds);
|
||||
|
||||
// 按巷道和层分组
|
||||
Map<String, List<Point>> colLayerPointsMap = new HashMap<>();
|
||||
|
||||
for (Point point : pointMap.values()) {
|
||||
String key = point.getColNum() + "-" + point.getLayerNum();
|
||||
if (colLayerPointsMap.containsKey(key)) {
|
||||
continue;
|
||||
}
|
||||
List<Point> points = pointService.findByColAndLayer(point.getColNum(), point.getLayerNum());
|
||||
colLayerPointsMap.put(key, points);
|
||||
}
|
||||
|
||||
//获取出库口的库位
|
||||
List<Point> outPoints = pointService.queryPoints(null, null, AreaTypeEnum.CK_DOCK.getValue());
|
||||
|
||||
|
|
@ -410,9 +405,7 @@ public class AllocateProcessor {
|
|||
return matchedInventories.stream()
|
||||
.map(inventory -> {
|
||||
Point currPoint = pointMap.get(inventory.getPointId());
|
||||
String key = currPoint.getColNum() + "-" + currPoint.getLayerNum();
|
||||
List<Point> points = colLayerPointsMap.get(key);
|
||||
return calculateMoveCount(inventory, currPoint, points, outPoints);
|
||||
return calculateMoveCount(inventory, currPoint, outPoints);
|
||||
})
|
||||
//按分数倒序排序、移动次数升序排序
|
||||
.sorted(Comparator.comparing(InventoryScore::getScore).reversed()
|
||||
|
|
@ -426,10 +419,9 @@ public class AllocateProcessor {
|
|||
*
|
||||
* @param inventory 库存
|
||||
* @param currPoint 当前库位
|
||||
* @param points 当前库位巷道的库位集合
|
||||
* @return 库位位移次数
|
||||
*/
|
||||
private InventoryScore calculateMoveCount(Inventory inventory, Point currPoint, List<Point> points, List<Point> outPoints) {
|
||||
private InventoryScore calculateMoveCount(Inventory inventory, Point currPoint, List<Point> outPoints) {
|
||||
// 位移分数
|
||||
double moveScore;
|
||||
//移位库位
|
||||
|
|
@ -439,6 +431,9 @@ public class AllocateProcessor {
|
|||
Point bestPoint = getBestOutboundPoint(currPoint, outPoints);
|
||||
double distanceScore = calculateClusterDistanceCost(currPoint, bestPoint) * 0.3;
|
||||
|
||||
//当前巷道的库位数
|
||||
List<Point> points= pointMapper.findByColAndLayer(currPoint.getColNum(), currPoint.getLayerNum());
|
||||
|
||||
// 目标库位的深度位转换为索引
|
||||
int targetIndex = Integer.parseInt(currPoint.getRowNum()) - 1;
|
||||
|
||||
|
|
@ -729,6 +724,7 @@ public class AllocateProcessor {
|
|||
Point toPoint = allocatePoint(fromPoint, itemKeyMap.get(inv.getItemKeyId()));
|
||||
Task moveTask = taskService.bulidTask(taskNo, TaskTypeEnum.MOVE.getValue(), moveItem, fromPoint, toPoint, stock, null, null, inv.getItemKeyId(), inv.getId(), inv.getQuantity(), 0);
|
||||
moveList.add(moveTask);
|
||||
pointService.bindPoint(toPoint);
|
||||
log.info("生成移位任务:{}- 容器:{} - 库位:{} - 库存数量:{}", taskNo, stock.getStockCode(), fromPoint.getPointCode(), inv.getQuantity());
|
||||
}
|
||||
return moveList;
|
||||
|
|
@ -744,7 +740,7 @@ public class AllocateProcessor {
|
|||
Area area = areaMapper.selectById(currentPoint.getAreaId());
|
||||
String areaCode = area.getAreaCode();
|
||||
List<ItemKey> itemKeyIds = Collections.singletonList(itemKey);
|
||||
return scanTrayProcessor.allocatePoint(itemKeyIds, currentPoint, areaCode);
|
||||
return scanTrayProcessor.allocatePoint(itemKeyIds, currentPoint, areaCode,BusinessTypeEnum.MOVE.getValue());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ import org.cpte.modules.constant.GeneralConstant;
|
|||
import org.cpte.modules.constant.enums.AgvStatusEnum;
|
||||
import org.cpte.modules.constant.enums.AgvVendorEnum;
|
||||
import org.cpte.modules.constant.enums.BusinessTypeEnum;
|
||||
import org.cpte.modules.inventory.service.IInventoryService;
|
||||
import org.cpte.modules.inventory.service.impl.InventoryServiceImpl;
|
||||
import org.cpte.modules.receive.service.IAsnService;
|
||||
import org.cpte.modules.shipping.entity.Task;
|
||||
import org.cpte.modules.shipping.mapper.TaskMapper;
|
||||
|
|
@ -55,6 +57,9 @@ public class ITesAgvServiceImpl implements ITesAgvService {
|
|||
@Autowired
|
||||
private IAgvTaskService agvTaskService;
|
||||
|
||||
@Autowired
|
||||
private IInventoryService inventoryService;
|
||||
|
||||
@Override
|
||||
public String generateTesAgvTaskJson(AgvTask agvTask) {
|
||||
NewMovePodTaskRequest newMovePodTaskRequest = new NewMovePodTaskRequest();
|
||||
|
|
@ -214,6 +219,9 @@ public class ITesAgvServiceImpl implements ITesAgvService {
|
|||
String endCode = pointService.getElevatorPoint(agvTask.getEndCode(), GeneralConstant.CK_ELEVATOR_TASK_INDEX);
|
||||
agvTaskService.createAgvTask(null, agvTask.getCarrierCode(), agvTask.getEndCode(), endCode, null, BusinessTypeEnum.OUTBOUND.getValue(), 0, AgvVendorEnum.HIK.getValue());
|
||||
}*/
|
||||
}else if(BusinessTypeEnum.MOVE.getValue().equals(agvTask.getType())){
|
||||
List<Task> tasks = taskMapper.queryByAgvTask(agvTask.getId());
|
||||
inventoryService.moveInventory(tasks);
|
||||
}
|
||||
|
||||
agvTask.setStatus(AgvStatusEnum.COMPLETED.getValue());
|
||||
|
|
|
|||
|
|
@ -299,8 +299,8 @@ public class BatchUtil {
|
|||
ps.setString(8, task.getToPointCode());
|
||||
ps.setLong(9, task.getStockId());
|
||||
ps.setString(10, task.getStockCode());
|
||||
ps.setLong(11, task.getPickId());
|
||||
ps.setLong(12, task.getPickDetailId());
|
||||
ps.setObject(11, task.getPickId());
|
||||
ps.setObject(12, task.getPickDetailId());
|
||||
ps.setLong(13, task.getItemKeyId());
|
||||
ps.setLong(14, task.getInventoryId());
|
||||
ps.setBigDecimal(15, task.getPlanQty());
|
||||
|
|
|
|||
Loading…
Reference in New Issue