zhou zhou
2 天以前 464116335cba47ddce55ee3a4ddc87af7fee5d15
rsf-server/src/main/java/com/vincent/rsf/server/manager/utils/LocManageUtil.java
@@ -5,6 +5,7 @@
import com.vincent.rsf.framework.common.SpringUtils;
import com.vincent.rsf.framework.exception.CoolException;
import com.vincent.rsf.server.api.utils.LocUtils;
import com.vincent.rsf.server.common.redis.RedisKeys;
import com.vincent.rsf.server.manager.controller.dto.ExistDto;
import com.vincent.rsf.server.manager.controller.dto.OrderOutItemDto;
import com.vincent.rsf.server.manager.controller.params.WaveToLocParams;
@@ -12,14 +13,20 @@
import com.vincent.rsf.server.manager.enums.TaskType;
import com.vincent.rsf.server.manager.enums.WaveRuleType;
import com.vincent.rsf.server.manager.service.*;
import com.vincent.rsf.server.manager.service.impl.WmsRedisLuaService;
import com.vincent.rsf.server.manager.enums.LocStsType;
import org.apache.commons.lang3.StringUtils;
import java.math.BigDecimal;
import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;
public class LocManageUtil {
    private static final int TARGET_LOC_QUERY_LIMIT = 10;
    private static final String TARGET_LOC_LOCK_KEY_PREFIX = "wms:loc:claim:";
    private static final Duration TARGET_LOC_LOCK_TTL = Duration.ofMinutes(1);
    /**
     * @param
@@ -39,7 +46,7 @@
        Long locType = containerType;
        //TODO 库位策略后续排期
        LocService locService = SpringUtils.getBean(LocService.class);
        Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>()
        List<Loc> locList = locService.list(new LambdaQueryWrapper<Loc>()
                .eq(!Objects.isNull(locType), Loc::getType, locType)
                .eq(Loc::getAreaId, areaId)
                .eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
@@ -47,60 +54,44 @@
                .orderByAsc(Loc::getLev)
                .orderByAsc(Loc::getCol)
                .orderByAsc(Loc::getRow)
                .last("LIMIT 1")
                .last("LIMIT " + TARGET_LOC_QUERY_LIMIT)
        );
        return !Objects.isNull(loc) ? loc.getCode() : null;
        return claimTargetLoc(locList);
    }
    public static String getTargetLoc(Long areaId, Long containerType) {
        Long locType = containerType;
//        if (!Objects.isNull(containerType)) {
//            LocTypeService locService = SpringUtils.getBean(LocTypeService.class);
//            if (containerType.equals(ContainerType.CONTAINER_TYPE_NORMAL.val)) {
//                LocType low = locService.getOne(new LambdaQueryWrapper<LocType>()
//                        .eq(LocType::getCode, "L"));
//                if (Objects.isNull(low)) {
//                    throw new CoolException("庫位類型不存在!!");
//                }
//                locType = low.getId();
//            } else {
//                LocType low = locService.getOne(new LambdaQueryWrapper<LocType>()
//                        .eq(LocType::getCode, "H"));
//                if (Objects.isNull(low)) {
//                    throw new CoolException("庫位類型不存在!!");
//                }
//                locType = low.getId();
//            }
//        }
        //TODO 库位策略后续排期
        LocService locService = SpringUtils.getBean(LocService.class);
        Loc loc = locService.getOne(new LambdaQueryWrapper<Loc>()
        List<Loc> locList = locService.list(new LambdaQueryWrapper<Loc>()
                .eq(!Objects.isNull(locType), Loc::getType, locType)
                .eq(Loc::getAreaId, areaId)
                .eq(Loc::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
                .orderByAsc(Loc::getLev)
                .orderByAsc(Loc::getCol)
                .orderByAsc(Loc::getRow)
                .last("LIMIT 1")
                .last("LIMIT " + TARGET_LOC_QUERY_LIMIT)
        );
        return !Objects.isNull(loc) ? loc.getCode() : null;
        return claimTargetLoc(locList);
    }
    /**
     * @param
     * @return
     * @author Ryan
     * @description 获取目标站点
     * @time 2025/3/31 09:49
     */
    public static String getTargetSite() {
        //TODO 站点策略后续排期
        DeviceSiteService deviceSite = SpringUtils.getBean(DeviceSiteService.class);
        DeviceSite loc = deviceSite.getOne(new LambdaQueryWrapper<DeviceSite>().eq(DeviceSite::getStatus, 1), false);
        return !Objects.isNull(loc) ? loc.getSite() : null;
    private static String claimTargetLoc(List<Loc> locList) {
        if (Cools.isEmpty(locList)) {
            return null;
        }
        WmsRedisLuaService wmsRedisLuaService = SpringUtils.getBean(WmsRedisLuaService.class);
        for (Loc loc : locList) {
            if (Objects.isNull(loc) || Cools.isEmpty(loc.getCode())) {
                continue;
            }
            boolean claimed = wmsRedisLuaService.claimLocation(RedisKeys.locationOccupy(loc.getCode()), loc.getCode(), TARGET_LOC_LOCK_TTL);
            if (claimed) {
                return loc.getCode();
            }
        }
        return null;
    }
    /**
@@ -175,9 +166,7 @@
    public static List<OrderOutItemDto> getOutOrderList(List<WaveToLocParams> params, WaveRule waveRule,String stationId,String locCode) {
        LocService locService = SpringUtils.getBean(LocService.class);
        LocItemService locItemService = SpringUtils.getBean(LocItemService.class);
        DeviceSiteService deviceSiteService = SpringUtils.getBean(DeviceSiteService.class);
        BasStationAreaService basStationAreaService = SpringUtils.getBean(BasStationAreaService.class);
//        List<BasStationArea> basStationAreas = basStationAreaService.list(new LambdaQueryWrapper<>());//
        List<Loc> locList = new  ArrayList<>();
        List<OrderOutItemDto> list = new ArrayList<>();
        //不让站点重复使用问题
@@ -236,7 +225,7 @@
//                        orderOutItemDto.setLocItem(locItem);
                        orderOutItemDto.setLoc(loc);
                        orderOutItemDto.getLocItemList().add(locItem);
                        BasContainer containerType = getContainerType(loc.getBarcode());
                        BasContainer containerType = new WarehouseLocationRetrievalUtil().getContainerByBarcode(loc.getBarcode());
                        if (Cools.isEmpty(containerType)){
                            continue;
                        }
@@ -328,25 +317,11 @@
                            if (Objects.isNull(basStation)) {
                                throw new CoolException("绑定站點不存在!!");
                            }
                            List<DeviceSite> deviceSites = deviceSiteService.list(new LambdaQueryWrapper<DeviceSite>()
                                    .eq(!Objects.isNull(loc.getChannel()), DeviceSite::getChannel, loc.getChannel())
                                    .eq(!Objects.isNull(loc.getAreaId()), DeviceSite::getAreaIdStart, loc.getAreaId())
                                    .eq( DeviceSite::getSite, stationId)
                                    .eq(DeviceSite::getType, issued.doubleValue() >= locItem.getAnfme() && itemList.size() == 1 ? TaskType.TASK_TYPE_OUT.type : TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)
                            );
                            if (!deviceSites.isEmpty()) {
                                List<OrderOutItemDto.staListDto> maps = new ArrayList<>();
                                for (DeviceSite sta : deviceSites) {
                                    OrderOutItemDto.staListDto staListDto = new OrderOutItemDto.staListDto();
                                    staListDto.setStaNo(sta.getSite());
                                    staListDto.setStaName(sta.getSite());
                                    maps.add(staListDto);
                                }
                                orderOutItemDto.setStaNos(maps);
                                orderOutItemDto.setSiteNo(basStation.getStationName());
                            } else {
                                throw new CoolException("未找到符合条件站点路径!!!请检查路径管理!!!");
                            boolean available = new WarehouseLocationRetrievalUtil().queryPathIsItAvailableOutArea(loc.getAreaId().toString(), stationId, loc.getBarcode(),"out");
                            if (!available) {
                                throw new CoolException("未找到符合条件路径!!!请检查路径配置!!!");
                            }
                            orderOutItemDto.setSiteNo(basStation.getStationName());
                            orderOutItemDto.setSource(item.getItemId().toString())
                                    .setTargSiteAreaList(new ArrayList<>())
@@ -355,85 +330,15 @@
                            locList.add(loc);
                            issued = issued.subtract(new BigDecimal(locItem.getAnfme().toString()));
                        } else {
                            List<DeviceSite> deviceSites = deviceSiteService.list(new LambdaQueryWrapper<DeviceSite>()
                                    .eq(!Objects.isNull(loc.getChannel()), DeviceSite::getChannel, loc.getChannel())
                                    .eq(!Objects.isNull(loc.getAreaId()), DeviceSite::getAreaIdStart, loc.getAreaId())
                                    .eq(DeviceSite::getType, issued.doubleValue() >= locItem.getAnfme() && itemList.size() == 1 ? TaskType.TASK_TYPE_OUT.type : TaskType.TASK_TYPE_PICK_AGAIN_OUT.type)
                            );
                            if (!deviceSites.isEmpty()) {
                                List<OrderOutItemDto.staListDto> maps = new ArrayList<>();
                                for (DeviceSite sta : deviceSites) {
                                    OrderOutItemDto.staListDto staListDto = new OrderOutItemDto.staListDto();
                                    staListDto.setStaNo(sta.getSite());
                                    staListDto.setStaName(sta.getSite());
                                    maps.add(staListDto);
                                }
                                orderOutItemDto.setStaNos(maps);
                                //获取满足条件站点
                                Set<String> stationSet = deviceSites.stream().map(DeviceSite::getSite).collect(Collectors.toSet());
                                //已使用站点
                                Set<String> stas = stations.stream().map(BasStation::getStationName).collect(Collectors.toSet());
                                BasStationService basStationService = SpringUtils.getBean(BasStationService.class);
                                BasStation basStation = basStationService.getOne(new LambdaQueryWrapper<BasStation>()
                                        .apply("cross_zone_area != '[]'")  // 不是空数组
                                        .apply("container_type != '[]'")
                                        .apply("JSON_CONTAINS(cross_zone_area, {0}) = 1", loc.getAreaId().toString())//可执行库区区区域id
                                        .apply("JSON_CONTAINS(container_type, {0}) = 1", containerType.getContainerType().toString())//容器类型
                                        .eq(BasStation::getUseStatus, LocStsType.LOC_STS_TYPE_O.type)
                                        .in(BasStation::getStationName, stationSet)
                                        .notIn(!stas.isEmpty(), BasStation::getStationName, stas)
                                        .last("LIMIT 1"));
                                if (Objects.isNull(basStation)) {
                                    throw new CoolException("站點不存在!!");
                                }
                                if (basStation.getType()!=0){
                                    stations.add(basStation);
                                }
                                orderOutItemDto.setSiteNo(basStation.getStationName());
                            } else {
                                throw new CoolException("未找到符合条件站点!!!请检查路径管理!!!");
                            }
                            orderOutItemDto.setSource(item.getItemId().toString())
                                    .setTargSiteAreaList(new ArrayList<>())
                                    .setSourceId(item.getWaveId().toString());
                            list.add(orderOutItemDto);
                            locList.add(loc);
                            issued = issued.subtract(new BigDecimal(locItem.getAnfme().toString()));
                            throw new CoolException("未找到符合条件出库站点区域!!!请检查库区配置!!!");
                        }
//                         if (true){
////                            throw new CoolException("未找到符合条件站点!!!请检查库区配置!!!");
//                        }
                    }
                }
            }
        }
        return list;
    }
    //根据条码获取规则
    private static BasContainer getContainerType(String barcode) {
        BasContainerService basContainerService = SpringUtils.getBean(BasContainerService.class);
        if (Cools.isEmpty(barcode)) {
            throw new CoolException("容器码不能为空");
        }
        List<BasContainer> containers = basContainerService.list(new LambdaQueryWrapper<>());
        for (BasContainer container : containers) {
            String codeType = container.getCodeType();  // 获取正则表达式
            if (barcode.matches(codeType)) {  // 判断条码是否符合这个正则
                return container;
            }
        }
        throw new CoolException("容器码:"+barcode+"异常==>未找到匹配的规则");
    }
}