package com.huaheng.test; import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.math.MathUtil; import cn.hutool.core.util.ObjectUtil; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.huaheng.HuaHengApplication; import com.huaheng.framework.redis.RedisCache; import com.huaheng.pc.config.location.domain.Location; import com.huaheng.pc.config.location.domain.LocationStatus; import com.huaheng.pc.config.location.service.LocationService; import com.huaheng.pc.config.material.service.MaterialService; import com.huaheng.pc.inventory.inventoryTransaction.domain.InventoryTransaction; import com.huaheng.pc.inventory.inventoryTransaction.domain.vo.InventoryRankVO; import com.huaheng.pc.inventory.inventoryTransaction.service.InventoryTransactionService; import lombok.extern.slf4j.Slf4j; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; import java.util.*; import java.util.stream.Collectors; /** * @author yiwenpeng * @date 2023/7/20 09:49 */ @Slf4j @SpringBootTest(classes = HuaHengApplication.class) @RunWith(SpringRunner.class) public class Demo { @Autowired private LocationService locationService; @Resource private RedisCache redisCache; @Resource private MaterialService materialService; @Resource private InventoryTransactionService inventoryTransactionService; /* 将上一周物料出库次数排名前100的记录到数据库里面,每周更新一次这个排名,每次入库的时候用托盘中的所有物料,根据物料出入库次数排名计算出本次入库要分配的库位。 方案一:假设一个仓库前后各一个出口,离这两个出口近的前2列,包括所有行和层,都设置为常用库位(A区),前4列所有行和层的外侧库位,设置为一般常用库位(B区),其他的就是剩余库位了,不常用C区。 方案二:找到哪个离出口最近的库位,然后分配库位的时候,用方法找到离这个库位最近的库位,进行分配,但是每次分配只能分配离这个库位最近的。 */ private final static String INVENTORY_RANKING_KEY = "INVENTORY_RANKING"; @Test public void test() { // 统计物料出入库的频率,将常用的物料优先分配离出入口近的库位,外侧库位优先。 // 常用的物料,需要华恒自己根据物料出入库的频次进行判断 // 获取统计排行前30位的物料信息 // 优先出库原始数据,历史数据(1期暂时不做考虑,不需要考虑原始数据) // 入库数据存放至A区 // 常用库位(A区) Map<String, InventoryRankVO> inventoryRankMap = inventoryTransactionService.getMaterialDetailByKey(INVENTORY_RANKING_KEY); String inputOrOutMaterialCode = "DR-QB-01M"; InventoryRankVO inputMaterialCode = inventoryRankMap.get(inputOrOutMaterialCode); // 判断是否存在排行物料 if (ObjectUtil.isNotEmpty(inputMaterialCode)) { // 获取常用库区 List<Location> locationList = locationService .list(new LambdaQueryWrapper<Location>() .eq(Location::getZoneCode, "A")); // .eq(Location::getStatus, LocationStatus.)); if (CollectionUtil.isNotEmpty(locationList)) { LinkedList<Location> locationLinkedList = new LinkedList<>(locationList); locationLinkedList.sort(Comparator.comparingInt(Location::getId)); Location nearestLocation = locationLinkedList.pollFirst(); if (ObjectUtil.isNotEmpty(nearestLocation)) { System.out.print("Nearest Location: " + nearestLocation); } else { System.out.print("No locations available."); } } } } public static Location findNearestLocation(List<Location> locations, String locationCode) { if (locations == null || locations.isEmpty() || locationCode == null) { return null; } Location targetLocation = null; int minDistance = Integer.MAX_VALUE; int targetRow = Integer.parseInt(locationCode.substring(1, 3)); // Extract row number from locationCode int targetColumn = Integer.parseInt(locationCode.substring(3, 5)); // Extract column number from locationCode int targetLayer = Integer.parseInt(locationCode.substring(5, 7)); // Extract layer number from locationCode for (Location location : locations) { if (location.getCode().equals(locationCode)) { continue; // Skip the location with the same code as the target code } int rowDistance = Math.abs(targetRow - location.getIRow()); int columnDistance = Math.abs(targetColumn - location.getIColumn()); int layerDistance = Math.abs(targetLayer - location.getILayer()); int totalDistance = rowDistance + columnDistance + layerDistance; if (totalDistance < minDistance) { minDistance = totalDistance; targetLocation = location; } } return targetLocation; } }