1
18 小时以前 b71ca6faa130dbd9baed68d1402365ccc63e79c2
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,45 +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);
    }
    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;
    }
    /**
@@ -99,6 +105,39 @@
    public static List<LocItem> getEfficiencyFirstItemList(String matnrCode, String splrBatch, Double anfme) {
        LambdaQueryWrapper<LocItem> locItemQueryWrapper = new LambdaQueryWrapper<>();
        locItemQueryWrapper.eq(LocItem::getMatnrCode, matnrCode);
        locItemQueryWrapper.eq(StringUtils.isNotBlank(splrBatch), LocItem::getBatch, splrBatch);
        String applySql = String.format(
                "EXISTS (SELECT 1 FROM man_loc ml " +
                        "WHERE ml.use_status = '%s'" +
                        "AND ml.id = man_loc_item.loc_id " +
                        ")",
                LocStsType.LOC_STS_TYPE_F.type
        );
        locItemQueryWrapper.apply(applySql);
        LocItemService locItemService = SpringUtils.getBean(LocItemService.class);
        List<LocItem> locItems = locItemService.list(locItemQueryWrapper);
        locItems.sort(Comparator.comparing((LocItem item) -> !LocUtils.isShallowLoc(item.getLocCode())));
        List<LocItem> locsSet = locItems.stream().filter(locItem -> locItem.getAnfme().compareTo(anfme) == 0.0).collect(Collectors.toList());
        if (!locsSet.isEmpty()) {
            return locsSet;
        }
        return locItems;
    }
    /**
     * 出库策略:--〈效率优化〉
     *
     * @param matnrCode
     * @param splrBatch
     * @param anfme
     * @return
     */
    public static List<LocItem> getEfficiencyFirstItemList(String matnrCode, String splrBatch, Double anfme,String locCode) {
        LambdaQueryWrapper<LocItem> locItemQueryWrapper = new LambdaQueryWrapper<>();
        locItemQueryWrapper.eq(LocItem::getMatnrCode, matnrCode);
        if (!Cools.isEmpty(locCode)){
            locItemQueryWrapper.eq(LocItem::getLocCode, locCode);
        }
        locItemQueryWrapper.eq(StringUtils.isNotBlank(splrBatch), LocItem::getBatch, splrBatch);
        String applySql = String.format(
                "EXISTS (SELECT 1 FROM man_loc ml " +
@@ -150,6 +189,41 @@
        return locItems;
    }
    /**
     * 出库策略:--<先进先出>
     *
     * @param matnrCode
     * @param splrBatch
     * @param anfme
     * @return
     */
    public static List<LocItem> getFirstInFirstOutItemList(String matnrCode, String splrBatch, Double anfme,String locCode) {
        LambdaQueryWrapper<LocItem> locItemQueryWrapper = new LambdaQueryWrapper<>();
        locItemQueryWrapper.eq(LocItem::getMatnrCode, matnrCode);
        if (!Cools.isEmpty(locCode)){
            locItemQueryWrapper.eq(LocItem::getLocCode, locCode);
        }
        locItemQueryWrapper.eq(StringUtils.isNotEmpty(splrBatch), LocItem::getBatch, splrBatch);
        //如果批次不为空,按批次先后出库
        if (StringUtils.isNotBlank(splrBatch)) {
            locItemQueryWrapper.orderByAsc(LocItem::getBatch);
        } else {
            locItemQueryWrapper.orderByAsc(LocItem::getCreateTime);
        }
        String applySql = String.format(
                "EXISTS (SELECT 1 FROM man_loc ml " +
                        "WHERE ml.use_status = '%s'" +
                        "AND ml.id = man_loc_item.loc_id " +
                        ")",
                LocStsType.LOC_STS_TYPE_F.type
        );
        locItemQueryWrapper.apply(applySql);
        LocItemService locItemService = SpringUtils.getBean(LocItemService.class);
        List<LocItem> locItems = locItemService.list(locItemQueryWrapper);
        return locItems;
    }
    /**
     * 获取出库库位信息
     *
@@ -174,14 +248,14 @@
            }
            List<LocItem> locItems;
            if (Objects.isNull(waveRule)) {
                locItems = LocManageUtil.getFirstInFirstOutItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme());
                locItems = LocManageUtil.getFirstInFirstOutItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme(),locCode);
            } else {
                if (WaveRuleType.Efficiency_First.type.equals(waveRule.getType())) {
                    locItems = LocManageUtil.getEfficiencyFirstItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme());
                    locItems = LocManageUtil.getEfficiencyFirstItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme(),locCode);
                } else if (WaveRuleType.First_In_First_Out.type.equals(waveRule.getType())) {
                    locItems = LocManageUtil.getFirstInFirstOutItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme());
                    locItems = LocManageUtil.getFirstInFirstOutItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme(),locCode);
                } else {
                    locItems = LocManageUtil.getFirstInFirstOutItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme());
                    locItems = LocManageUtil.getFirstInFirstOutItemList(item.getMatnrCode(), item.getBatch(), item.getAnfme(),locCode);
                }
            }
            for (LocItem locItem : locItems) {
@@ -227,6 +301,7 @@
                                .apply("cross_zone_area != '[]'")  // 不是空数组
                                .apply("container_type != '[]'")
                                .apply("station_alias != '[]'")
                                .apply("station_alias_sta_no != '[]'")
                                .apply("JSON_CONTAINS(cross_zone_area, {0}) = 1", loc.getAreaId().toString())//可执行库区区区域id
                                .apply("JSON_CONTAINS(container_type, {0}) = 1", containerType.getContainerType().toString())//容器类型
                                .eq(BasStationArea::getDeleted, 0));