自动化立体仓库 - WMS系统
Junjie
2023-05-12 fd1bfa1163d438ec6cabfdd6e01e632d31189c80
库位规则、混载库位
13个文件已修改
403 ■■■■ 已修改文件
src/main/java/com/zy/asrs/entity/LocRule.java 29 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/LocMastMapper.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/mapper/LocRuleMapper.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/LocMastService.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/LocRuleService.java 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/LocMastServiceImpl.java 13 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/LocRuleServiceImpl.java 62 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/utils/Utils.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/common/service/CommonService.java 194 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/LocMastMapper.xml 41 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/LocRuleMapper.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/locRule/locRule.js 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/locRule/locRule.html 18 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/entity/LocRule.java
@@ -159,9 +159,22 @@
    @ApiModelProperty(value= "备注")
    private String memo;
    /**
     * 是否支持混载{0:不支持,1:支持}
     */
    @ApiModelProperty(value= "是否支持混载")
    private Integer mixed;
    /**
     * 支持混载情况下,没找到库位是否继续寻找{0:否,1:是}
     */
    @ApiModelProperty(value= "是否继续寻找")
    @TableField("keep_go")
    private Integer keepGo;
    public LocRule() {}
    public LocRule(String matnr,String specs,String model,String cstmr,String batch,String other,Integer rowBeg,Integer rowEnd,Integer bayBeg,Integer bayEnd,Integer levBeg,Integer levEnd,Integer limit,Integer status,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo) {
    public LocRule(String matnr,String specs,String model,String cstmr,String batch,String other,Integer rowBeg,Integer rowEnd,Integer bayBeg,Integer bayEnd,Integer levBeg,Integer levEnd,Integer limit,Integer status,Long createBy,Date createTime,Long updateBy,Date updateTime,String memo,Integer mixed) {
        this.matnr = matnr;
        this.specs = specs;
        this.model = model;
@@ -181,6 +194,7 @@
        this.updateBy = updateBy;
        this.updateTime = updateTime;
        this.memo = memo;
        this.mixed = mixed;
    }
//    LocRule locRule = new LocRule(
@@ -249,5 +263,18 @@
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(this.updateTime);
    }
    public String getMixed$() {
        if (this.mixed == null) {
            return "";
        }
        return this.mixed == 1 ? "是" : "否";
    }
    public String getKeepGo$() {
        if (this.keepGo == null) {
            return "";
        }
        return this.keepGo == 1 ? "是" : "否";
    }
}
src/main/java/com/zy/asrs/mapper/LocMastMapper.java
@@ -23,7 +23,7 @@
    @Select("select count(*) as count from asr_loc_mast where 1=1 and loc_sts = 'O' and crn_no = #{crnNo}")
    Integer selectEmptyLocCount(@Param("crnNo") Integer crnNo);
    List<LocMast> queryFreeLocMast2(@Param("rows") List<Integer> rows, @Param("rowsLen") Integer rowsLen, @Param("locType1") Short locType1);
    List<LocMast> queryFreeLocMast2(Short locType1, Integer rowBeg, Integer rowEnd, Integer bayBeg, Integer bayEnd, Integer levBeg, Integer levEnd);
    LocMast selectAvailableNearLocDesc(@Param("groupLoc") List<String> groupOuterLoc);
@@ -35,4 +35,6 @@
    List<LocMast> selectLocByLev(Integer lev);
    List<LocMast> selectEmptyByLocNos(@Param("locNos") List<String> locNos);
}
src/main/java/com/zy/asrs/mapper/LocRuleMapper.java
@@ -5,8 +5,14 @@
import org.apache.ibatis.annotations.Mapper;
import org.springframework.stereotype.Repository;
import java.util.List;
@Mapper
@Repository
public interface LocRuleMapper extends BaseMapper<LocRule> {
    LocRule selectByMatnr(String matnr);
    LocRule selectByMixed(Integer mixed);
}
src/main/java/com/zy/asrs/service/LocMastService.java
@@ -12,7 +12,7 @@
     * 检索可用库位
     */
    List<LocMast> queryFreeLocMast(List<Integer> rows, Integer rowsLen, Short locType1);
    List<LocMast> queryFreeLocMast2(List<Integer> rows, Integer rowsLen, Short locType1);
    List<LocMast> queryFreeLocMast2(Short locType1, Integer rowBeg, Integer rowEnd, Integer bayBeg, Integer bayEnd, Integer levBeg, Integer levEnd);
    /**
     * 检索可用库位0
@@ -63,4 +63,6 @@
    //查询指定楼层的库位数据
    List<LocMast> selectLocByLev(Integer lev);
    List<LocMast> selectEmptyByLocNos(List<String> locNos);
}
src/main/java/com/zy/asrs/service/LocRuleService.java
@@ -1,10 +1,19 @@
package com.zy.asrs.service;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.entity.LocRule;
import com.baomidou.mybatisplus.service.IService;
import java.util.List;
public interface LocRuleService extends IService<LocRule> {
    LocRule find(String matnr, String batch, int startRow, int endRow);
    LocRule find(String matnr);
    //找混载库位规则
    LocRule findMixed();
    //将库位规则组转换为库位组
    List<LocMast> locRuleToLocNos(LocRule locRule);
}
src/main/java/com/zy/asrs/service/impl/LocMastServiceImpl.java
@@ -34,8 +34,8 @@
    }
    @Override
    public List<LocMast> queryFreeLocMast2(List<Integer> rows, Integer rowsLen, Short locType1) {
        return this.baseMapper.queryFreeLocMast(rows, rowsLen, locType1);
    public List<LocMast> queryFreeLocMast2(Short locType1, Integer rowBeg, Integer rowEnd, Integer bayBeg, Integer bayEnd, Integer levBeg, Integer levEnd) {
        return this.baseMapper.queryFreeLocMast2(locType1, rowBeg, rowEnd, bayBeg, bayEnd, levBeg, levEnd);
    }
    @Override
@@ -94,6 +94,10 @@
        LocMast finalRes = null;
        for (String locNo0 : locNos) {
            LocMast locMast = this.selectById(locNo0);
            if (locMast == null) {
                continue;
            }
            if (locMast.getLocSts().equals("O")) {
                if (finalRes == null) {
                    finalRes = locMast;
@@ -180,4 +184,9 @@
    public List<LocMast> selectLocByLev(Integer lev) {
        return this.baseMapper.selectLocByLev(lev);
    }
    @Override
    public List<LocMast> selectEmptyByLocNos(List<String> locNos) {
        return this.baseMapper.selectEmptyByLocNos(locNos);
    }
}
src/main/java/com/zy/asrs/service/impl/LocRuleServiceImpl.java
@@ -2,23 +2,31 @@
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.core.common.Cools;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.entity.Mat;
import com.zy.asrs.mapper.LocRuleMapper;
import com.zy.asrs.entity.LocRule;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.service.LocRuleService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.zy.asrs.service.MatService;
import com.zy.asrs.utils.Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service("locRuleService")
public class LocRuleServiceImpl extends ServiceImpl<LocRuleMapper, LocRule> implements LocRuleService {
    @Autowired
    private MatService matService;
    @Autowired
    private LocMastService locMastService;
    @Override
    public LocRule find(String matnr, String batch, int startRow, int endRow) {
    public LocRule find(String matnr) {
        if (Cools.isEmpty(matnr)) {
            return null;
        }
@@ -26,25 +34,39 @@
        if (Cools.isEmpty(mat)) {
            return null;
        }
        LocRule locRule = null;
        do {
            locRule = this.selectOne(new EntityWrapper<LocRule>().eq("matnr", matnr).ge("row_beg", startRow).le("row_end", endRow).eq("status", 1));
            if (null != locRule) {
                break;
        return this.baseMapper.selectByMatnr(matnr);
    }
    //找混载库位规则
    @Override
    public LocRule findMixed() {
        return this.baseMapper.selectByMixed(1);//搜索混载库位规则
    }
    //将库位规则转换为库位组
    @Override
    public List<LocMast> locRuleToLocNos(LocRule locRule) {
        ArrayList<String> locNos = new ArrayList<>();
        //将所有符合混载规则的库位号进行存储
        Integer rowBeg = locRule.getRowBeg();
        Integer rowEnd = locRule.getRowEnd();
        Integer bayBeg = locRule.getBayBeg();
        Integer bayEnd = locRule.getBayEnd();
        Integer levBeg = locRule.getLevBeg();
        Integer levEnd = locRule.getLevEnd();
        for (int i = rowBeg; i <= rowEnd; i++) {
            for (int j = bayBeg; j <= bayEnd; j++) {
                for (int k = levBeg; k <= levEnd; k++) {
                    String locNo = Utils.getLocNo(i, j, k);
                    locNos.add(locNo);
                }
            }
            locRule = this.selectOne(new EntityWrapper<LocRule>().eq("specs", mat.getSpecs()).ge("row_beg", startRow).le("row_end", endRow).eq("status", 1));
            if (null != locRule) {
                break;
            }
            locRule = this.selectOne(new EntityWrapper<LocRule>().eq("model", mat.getModel()).ge("row_beg", startRow).le("row_end", endRow).eq("status", 1));
            if (null != locRule) {
                break;
            }
            locRule = this.selectOne(new EntityWrapper<LocRule>().eq("batch", batch).ge("row_beg", startRow).le("row_end", endRow).eq("status", 1));
            if (null != locRule) {
                break;
            }
        } while (false);
        return locRule;
        }
        return locMastService.selectEmptyByLocNos(locNos);
    }
}
src/main/java/com/zy/asrs/utils/Utils.java
@@ -185,7 +185,9 @@
    }
    public static String getLocNo(Number row, Number bay, Number lev) {
        return zerofill(String.valueOf(row), 2) + zerofill(String.valueOf(bay), 3) + zerofill(String.valueOf(lev), 2);
    }
    public static List<String> getGroupLoc(String locNo){
        int row = getRow(locNo);
src/main/java/com/zy/common/service/CommonService.java
@@ -59,6 +59,8 @@
    private LocDetlService locDetlService;
    @Autowired
    private SlaveProperties slaveProperties;
    @Autowired
    private LocRuleService locRuleService;
    /**
     * 生成工作号
@@ -112,13 +114,132 @@
     * @return locNo 检索到的库位号
     */
    public StartupDto getLocNo(Integer staDescId, Integer sourceStaNo, List<String> matNos, LocTypeDto locTypeDto,int times) {
        StartupDto startupDto = new StartupDto();
        // 目标库位
        LocMast locMast = null;
        //混载找库位
        locMast = getLocNoStep1(matNos, locTypeDto);
        if (locMast != null) {
            //找到库位,返回dto
            return getLocNoStep6(staDescId, sourceStaNo, locMast);//返回dto
        }
        //库位规则
        locMast = getLocNoStep2(matNos, locTypeDto);
        if (locMast != null) {
            //找到库位,返回dto
            return getLocNoStep6(staDescId, sourceStaNo, locMast);//返回dto
        }
        // 靠近摆放规则 --- 相同订单号, 同天同规格物料
        locMast = getLocNoStep3(staDescId, matNos, locTypeDto);
        if (locMast != null) {
            //找到库位,返回dto
            return getLocNoStep6(staDescId, sourceStaNo, locMast);//返回dto
        }
        // 靠近摆放规则 --- 空托
        locMast = getLocNoStep4(staDescId, locTypeDto);
        if (locMast != null) {
            //找到库位,返回dto
            return getLocNoStep6(staDescId, sourceStaNo, locMast);//返回dto
        }
        // 如果没有相近物料,则按规则轮询货架
        // 开始查找库位 ==============================>>
        locMast = getLocNoStep5(locTypeDto, times);
        if (locMast != null) {
            //找到库位,返回dto
            return getLocNoStep6(staDescId, sourceStaNo, locMast);//返回dto
        }
        //找不到库位,抛出异常
        throw new CoolException("没有空库位");
    }
    /**
     * 混载找库位
     */
    private LocMast getLocNoStep1(List<String> matNos, LocTypeDto locTypeDto) {
        LocMast locMast = null;
        //判断当前货物是否为混载货物
        String firstMatNos = matNos.get(0);
        boolean mixed = false;//默认不是混载货物
        for (String matNo : matNos) {
            if (!firstMatNos.equals(matNo)) {
                mixed = true;//混载货物
                break;
            }
        }
        if (!mixed) {
            return locMast;//不是混载货物,直接跳出当前任务
        }
        // 找混载库位规则
        LocRule locRule = locRuleService.findMixed();
        if (locRule == null) {
            return locMast;//没有混载规则,跳出当前任务
        }
        //将库位规则组转换为库位组
        List<LocMast> locMasts = locRuleService.locRuleToLocNos(locRule);
        if (locMasts == null || locMasts.size() == 0) {
            if (locRule.getKeepGo() == 0) {
                //找不到空库位,且禁止继续寻找其他非混载区域库位
                //找不到库位,抛出异常
                throw new CoolException("混载区域没有空库位");
            }
            return locMast;//没有混载规则,跳出当前任务
        }
        for (LocMast one : locMasts) {
            LocMast locMast0 = locMastService.findOutMost(one.getLocNo());
            if (null != locMast0) {
                // 浅库位符合尺寸检测
                if (VersionUtils.locMoveCheckLocType(locMast0, locTypeDto)) {
                    // 因库位移转、需预留空库位
                    if (locMastService.checkEmptyCount(locMast0, 10)) {
                        locMast = locMast0;
                        break;
                    }
                }
            }
        }
        return locMast;
    }
    /**
     * 库位规则
     */
    private LocMast getLocNoStep2(List<String> matNos, LocTypeDto locTypeDto) {
        LocMast locMast = null;
        // 库区锁定
        LocRule locRule = locRuleService.find(Cools.isEmpty(matNos) ? null : matNos.get(0));
        if (!Cools.isEmpty(locRule)) {
            List<LocMast> locMasts = locMastService.queryFreeLocMast2(locTypeDto.getLocType1(), locRule.getRowBeg(), locRule.getRowEnd(), locRule.getBayBeg(), locRule.getBayEnd(), locRule.getLevBeg(), locRule.getLevEnd());
            for (LocMast one : locMasts) {
                LocMast locMast0 = locMastService.findOutMost(one.getLocNo());
                if (null != locMast0) {
                    // 浅库位符合尺寸检测
                    if (VersionUtils.locMoveCheckLocType(locMast0, locTypeDto)) {
                        // 因库位移转、需预留空库位
                        if (locMastService.checkEmptyCount(locMast0, 10)) {
                            locMast = locMast0;
                            break;
                        }
                    }
                }
            }
        }
        return locMast;
    }
    // 靠近摆放规则 --- 相同订单号, 同天同规格物料
    private LocMast getLocNoStep3(Integer staDescId, List<String> matNos, LocTypeDto locTypeDto) {
        LocMast locMast = null;
        if (!Cools.isEmpty(matNos) && matNos.size() == 1 && staDescId == 1) {
            //先判断工作档,查找主档IOType=1, wrkSts < 10的工作明细,料号相同的明细库位
            List<WrkMast> wrkMasts = wrkMastService.selectSameMatnrs(matNos.get(0));
@@ -128,7 +249,6 @@
                    // 浅库位符合尺寸检测
                    if (VersionUtils.locMoveCheckLocType(locMast0, locTypeDto)) {
                        locMast = locMast0;
                        break;
                    }
                }
            }
@@ -148,7 +268,12 @@
            }
        }
        return locMast;
    }
    // 靠近摆放规则 --- 空托
    private LocMast getLocNoStep4(Integer staDescId, LocTypeDto locTypeDto) {
        LocMast locMast = null;
        // 靠近摆放规则 --- 空托
        if (staDescId == 10) {
            //先判断工作档,查找主档IOType=1, wrkSts < 10的工作明细,料号相同的明细库位
@@ -174,7 +299,6 @@
                            if (VersionUtils.locMoveCheckLocType(locMast0, locTypeDto)) {
                                locMast = locMast0;
                                break;
                            }
                        }
                    }
@@ -182,7 +306,38 @@
            }
        }
        // 如果没有相近物料,则按规则轮询货架
        return locMast;
    }
    // 如果没有相近物料,则按规则轮询货架
    private LocMast getLocNoStep5(LocTypeDto locTypeDto, int times) {
        LocMast locMast = null;
        // 1.当检索库排为浅库位排时,优先寻找当前库排的深库位排
        List<LocMast> peakLocs = locMastService.selectAllPeakLoc();
        for (LocMast peakLoc : peakLocs) {
            List<String> groupInsideLoc = Utils.getGroupInsideLoc(peakLoc.getLocNo());
            if (!Cools.isEmpty(groupInsideLoc)) {
                if (!locMastService.checkAllLocEmpty(groupInsideLoc)) continue;
                locMast = peakLoc;
                break;
            } else {
                locMast = peakLoc;
                break;
            }
        }
        // 2.库位当前所属尺寸无空库位时,调整尺寸参数,向上兼容检索库位
        if (Cools.isEmpty(locMast)) {
            log.error("系统没有空库位!!! 尺寸规格: {}, 轮询次数:{}", JSON.toJSONString(locTypeDto), times);
        }
        return locMast;
    }
    //返回dto
    private StartupDto getLocNoStep6(Integer staDescId, Integer sourceStaNo, LocMast locMast) {
        StartupDto startupDto = new StartupDto();
        // 获取目标站
        Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>()
                .eq("type_no", staDescId)
@@ -199,38 +354,13 @@
            throw new CoolException("目标站" + staDesc.getCrnStn() + "不可用");
        }
        // 开始查找库位 ==============================>>
        // 1.当检索库排为浅库位排时,优先寻找当前库排的深库位排
        if (locMast == null) {
            List<LocMast> peakLocs = locMastService.selectAllPeakLoc();
            for (LocMast peakLoc : peakLocs) {
                List<String> groupInsideLoc = Utils.getGroupInsideLoc(peakLoc.getLocNo());
                if (!Cools.isEmpty(groupInsideLoc)){
                    if (!locMastService.checkAllLocEmpty(groupInsideLoc)) continue;
                    locMast = peakLoc;
                    break;
                }else {
                    locMast=peakLoc;
                    break;
                }
            }
        }
        // 2.库位当前所属尺寸无空库位时,调整尺寸参数,向上兼容检索库位
        if (Cools.isEmpty(locMast)) {
            log.error("系统没有空库位!!! 尺寸规格: {}, 轮询次数:{}", JSON.toJSONString(locTypeDto), times);
            throw new CoolException("没有空库位");
        }
        String locNo = locMast.getLocNo();
        // 生成工作号
        int workNo = getWorkNo(0);
        // 返回dto
        startupDto.setWorkNo(workNo);
        startupDto.setSourceStaNo(sourceStaNo);
        startupDto.setStaNo(staNo.getDevNo());
        startupDto.setLocNo(locNo);
        startupDto.setLocNo(locMast.getLocNo());
        return startupDto;
    }
src/main/resources/mapper/LocMastMapper.xml
@@ -156,4 +156,45 @@
    <select id="selectLocByLev" resultMap="BaseResultMap">
        SELECT * FROM asr_loc_mast WHERE lev1 = #{lev}
    </select>
    <select id="queryFreeLocMast2" resultMap="BaseResultMap">
        select *
        from asr_loc_mast
        where 1=1
        and loc_sts='O'
        <if test="locType1 != null">
            and loc_type1 = #{locType1}
        </if>
        <if test="rowBeg != null">
            and row1 >= #{rowBeg}
        </if>
        <if test="rowEnd != null">
            and row1 &lt;= #{rowEnd}
        </if>
        <if test="bayBeg != null">
            and bay1 >= #{bayBeg}
        </if>
        <if test="bayEnd != null">
            and bay1 &lt;= #{bayEnd}
        </if>
        <if test="levBeg != null">
            and lev1 >= #{levBeg}
        </if>
        <if test="levEnd != null">
            and lev1 &lt;= #{levEnd}
        </if>
        and loc_no not in ('0100101')
        order by loc_sts desc ,lev1 asc,bay1 asc
    </select>
    <select id="selectEmptyByLocNos" resultMap="BaseResultMap">
        SELECT * FROM asr_loc_mast
        WHERE loc_sts IN ('O')
        AND loc_no IN
        <foreach collection="locNos" item="loc" index="index" open="(" close=")" separator=",">
            #{loc}
        </foreach>
        ORDER BY
        row1 ASC
    </select>
</mapper>
src/main/resources/mapper/LocRuleMapper.xml
@@ -24,7 +24,22 @@
        <result column="update_by" property="updateBy" />
        <result column="update_time" property="updateTime" />
        <result column="memo" property="memo" />
        <result column="mixed" property="mixed" />
        <result column="keep_go" property="keepGo" />
    </resultMap>
    <select id="selectByMatnr" resultMap="BaseResultMap">
        select * from asr_loc_rule
        where matnr = #{matnr}
        and mixed = 0
        and status = 1
    </select>
    <select id="selectByMixed" resultMap="BaseResultMap">
        select top 1 * from asr_loc_rule
        where mixed = #{mixed}
        and status = 1
    </select>
</mapper>
src/main/webapp/static/js/locRule/locRule.js
@@ -42,6 +42,8 @@
            ,{field: 'updateBy$', align: 'center',title: '修改人员', hide: true}
            ,{field: 'updateTime$', align: 'center',title: '修改时间', hide: true}
            ,{field: 'memo', align: 'center',title: '备注', hide: true}
            ,{field: 'mixed$', align: 'center',title: '混载'}
            ,{field: 'keepGo$', align: 'center',title: '继续搜索'}
            ,{fixed: 'right', title:'操作', align: 'center', toolbar: '#operate', width:120}
        ]],
src/main/webapp/views/locRule/locRule.html
@@ -114,6 +114,24 @@
                        <input class="layui-input" name="limit" placeholder="请输入上限">
                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">混载: </label>
                    <div class="layui-input-block">
                        <select name="mixed">
                            <option value="1">是</option>
                            <option value="0" selected>否</option>
                        </select>
                    </div>
                </div>
                <div class="layui-form-item">
                    <label class="layui-form-label">混载未找到库位继续搜索: </label>
                    <div class="layui-input-block">
                        <select name="keepGo">
                            <option value="1">是</option>
                            <option value="0" selected>否</option>
                        </select>
                    </div>
                </div>
             </div>