src/main/java/com/zy/asrs/mapper/LocDetlMapper.java
@@ -32,6 +32,8 @@ List<String> selectSameDetl(@Param("matnr") String matnr); List<String> selectSameLevDetl(@Param("matnr") String matnr, @Param("lev") Integer lev); @Select("SELECT ld.loc_no FROM asr_loc_detl ld LEFT JOIN asr_loc_mast lm ON ld.loc_no = lm.loc_no WHERE (1 = 1 AND ld.matnr = #{matnr} AND (lm.row1 >= #{start} AND lm.row1 <= #{end}) AND lm.loc_sts = 'F' AND DateDiff(dd, lm.modi_time, getdate()) = 0) ORDER BY lm.modi_time ASC") List<String> selectSameDetlToday(@Param("matnr") String matnr, @Param("start") Integer start, @Param("end") Integer end); src/main/java/com/zy/asrs/mapper/LocMastMapper.java
@@ -26,6 +26,11 @@ */ List<LocMast> selectAreaEmpty(Short locType1, Integer locType3); /** * 搜索指定区域可用库位 */ List<LocMast> selectAreaEmptyByLev(Short locType1, Integer locType3, Integer lev); LocMast selectAvailableNearLocDesc(@Param("groupLoc") List<String> groupOuterLoc); LocMast selectAvailableNearLocAsc(@Param("groupOuterLoc") List<String> groupOuterLoc); src/main/java/com/zy/asrs/mapper/WrkMastMapper.java
@@ -29,4 +29,5 @@ List<WrkMast> selectSameMatnrs(@Param("matnr") String matnr); List<WrkMast> selectSameLevMatnrs(@Param("matnr") String matnr, @Param("lev") Integer lev); } src/main/java/com/zy/asrs/service/LocDetlService.java
@@ -32,6 +32,11 @@ List<String> getSameDetl(String matnr); /** * 获取相同规格货物 */ List<String> getSameLevDetl(String matnr, Integer lev); /** * 获取当天相同规格货物的深库位号 * @param matnr 物料号 * @return locNo 库位号 src/main/java/com/zy/asrs/service/LocMastService.java
@@ -18,6 +18,11 @@ List<LocMast> selectAreaEmpty(Short locType1, Integer locType3); /** * 搜索指定区域可用库位 */ List<LocMast> selectAreaEmptyByLev(Short locType1, Integer locType3, Integer lev); /** * 获取同组货架的空库位 * @param sourceLocNo 源库位 * @return 同组空库位集合 src/main/java/com/zy/asrs/service/WrkMastService.java
@@ -28,5 +28,7 @@ WrkMast selectOfPick(Integer wrkNo, Integer ioType); List<WrkMast> selectSameMatnrs(String s); List<WrkMast> selectSameMatnrs(String matnr); List<WrkMast> selectSameLevMatnrs(String matnr, Integer lev); } src/main/java/com/zy/asrs/service/impl/LocDetlServiceImpl.java
@@ -58,6 +58,11 @@ } @Override public List<String> getSameLevDetl(String matnr, Integer lev) { return this.baseMapper.selectSameLevDetl(matnr, lev); } @Override public List<String> getSameDetlToday(String matnr, Integer start, Integer end) { return this.baseMapper.selectSameDetlToday(matnr, start, end); } src/main/java/com/zy/asrs/service/impl/LocMastServiceImpl.java
@@ -39,6 +39,11 @@ } @Override public List<LocMast> selectAreaEmptyByLev(Short locType1, Integer locType3, Integer lev) { return this.baseMapper.selectAreaEmptyByLev(locType1, locType3, lev); } @Override public List<String> queryGroupEmptyStock(String sourceLocNo) { if (Cools.isEmpty(sourceLocNo)) { return null; src/main/java/com/zy/asrs/service/impl/WrkMastServiceImpl.java
@@ -95,4 +95,8 @@ return this.baseMapper.selectSameMatnrs(matnr); } @Override public List<WrkMast> selectSameLevMatnrs(String matnr, Integer lev) { return this.baseMapper.selectSameLevMatnrs(matnr, lev); } } src/main/java/com/zy/common/service/CommonService.java
@@ -503,4 +503,215 @@ return startupDto; } /** * 四向库获取库位 */ public StartupDto getShuttleLocNo(Integer staDescId, Integer sourceStaNo, List<String> matNos, LocTypeDto locTypeDto) { RowLastno rowLastno = rowLastnoService.selectOne(new EntityWrapper<RowLastno>().eq("whs_type", 1)); //起始层 Integer startLev = rowLastno.getCurrentRow(); return getShuttleLocNo(staDescId, sourceStaNo, matNos, locTypeDto, startLev, 0); } public StartupDto getShuttleLocNo(Integer staDescId, Integer sourceStaNo, List<String> matNos, LocTypeDto locTypeDto, int startLev, int times) { RowLastno rowLastno = rowLastnoService.selectOne(new EntityWrapper<RowLastno>().eq("whs_type", 1)); //起始层 Integer currentLev = rowLastno.getCurrentRow(); if (times > 0 && startLev == currentLev) { throw new CoolException("未找到可用库位"); } rowLastno.setCurrentRow(currentLev >= rowLastno.geteRow() ? rowLastno.getsRow() : currentLev + 1);//更新楼层 rowLastnoService.updateById(rowLastno); // 目标库位 LocMast locMast = null; // 靠近摆放规则 --- 空托 locMast = getShuttleEmptyLocNo(staDescId, locTypeDto, currentLev); if (locMast != null) { //找到库位,返回dto return getShuttleLocStartupDto(staDescId, sourceStaNo, locMast);//返回dto } //单品物料 靠近摆放规则 --- 相同订单号, 同天同规格物料 locMast = getShuttleSingleLocNo(matNos, locTypeDto, currentLev); if (locMast != null) { //找到库位,返回dto return getShuttleLocStartupDto(staDescId, sourceStaNo, locMast);//返回dto } // 靠近摆放规则 --- 相同订单号, 同天同规格物料 locMast = getShuttleMixedLocNo(matNos, locTypeDto, currentLev); if (locMast != null) { //找到库位,返回dto return getShuttleLocStartupDto(staDescId, sourceStaNo, locMast);//返回dto } return getShuttleLocNo(staDescId, sourceStaNo, matNos, locTypeDto, startLev, times + 1); } //搜索空托盘库位 private LocMast getShuttleEmptyLocNo(Integer staDescId, LocTypeDto locTypeDto, int lev) { LocMast locMast = null; // 靠近摆放规则 --- 空托 if (staDescId == 10) { //先判断工作档,查找主档IOType=1, wrkSts < 10的工作明细,料号相同的明细库位 List<WrkMast> wrkMasts = wrkMastService.selectList(new EntityWrapper<WrkMast>().eq("io_type", 10)); for (WrkMast wrkMast : wrkMasts) { LocMast locMast0 = locMastService.findNearloc(wrkMast.getLocNo()); if (null != locMast0) { // 浅库位符合尺寸检测 if (VersionUtils.checkLocType(locMast0, locTypeDto)) { locMast = locMast0; break; } } } if (Cools.isEmpty(locMast)) { List<LocMast> locMasts = locMastService.selectList(new EntityWrapper<LocMast>() .eq("loc_sts", "O").eq("lev1", lev).orderBy("row1,bay1,lev1")); if (!locMasts.isEmpty()) { for (LocMast loc : locMasts) { LocMast locMast0 = locMastService.findNearloc(loc.getLocNo()); if (null != locMast0) { // 浅库位符合尺寸检测 if (VersionUtils.checkLocType(locMast0, locTypeDto)) { locMast = locMast0; break; } } } } } } return locMast; } //混放物料 private LocMast getShuttleMixedLocNo(List<String> matNos, LocTypeDto locTypeDto, Integer lev) { LocMast locMast = null; if (matNos.size() > 1) { List<LocMast> locMasts = locMastService.selectAreaEmptyByLev(locTypeDto.getLocType1(), 1, lev);//搜索混放库位 //混放区域直接取第一个即可 for (LocMast mast : locMasts) { // 浅库位符合尺寸检测 if (VersionUtils.checkLocType(mast, locTypeDto)) { locMast = mast; break; } } } return locMast; } //单品物料 靠近摆放规则 --- 相同订单号, 同天同规格物料 private LocMast getShuttleSingleLocNo(List<String> matNos, LocTypeDto locTypeDto, int lev) { LocMast locMast = null; if (matNos.size() == 1) { String matNo = matNos.get(0);//物料号 //先判断工作档,查找主档IOType=1, wrkSts < 10的工作明细,料号相同的明细库位 List<WrkMast> wrkMasts = wrkMastService.selectSameLevMatnrs(matNo, lev); for (WrkMast wrkMast : wrkMasts) { LocMast locMast0 = locMastService.findNearloc(wrkMast.getLocNo()); if (null != locMast0) { // 浅库位符合尺寸检测 if (VersionUtils.checkLocType(locMast0, locTypeDto)) { locMast = locMast0; } } } if (Cools.isEmpty(locMast)) { //再判断库存明细档,料号相同的明细库位 List<String> locNos = locDetlService.getSameLevDetl(matNo, lev); for (String locNo : locNos) { LocMast locMast0 = locMastService.findInnerLoc(locNo); if (null != locMast0) { // 浅库位符合尺寸检测 if (VersionUtils.checkLocType(locMast0, locTypeDto)) { locMast = locMast0; break; } } } } if (Cools.isEmpty(locMast)) { //找新库位 List<LocMast> locMasts = locMastService.selectAreaEmptyByLev(locTypeDto.getLocType1(), 2, lev);//搜索单品库位 for (LocMast mast : locMasts) { List<String> groupLoc = Utils.getGroupLoc(mast.getLocNo()); if (!locMastService.checkAllLocEmpty(groupLoc)) { continue; } LocMast tmp = null; for (String loc : groupLoc) { LocMast locMast1 = locMastService.selectByLoc(loc); if (locMast1 == null) { continue; } if (!locMast1.getLocSts().equals("O")) { continue; } // 浅库位符合尺寸检测 if (VersionUtils.checkLocType(locMast1, locTypeDto)) { tmp = locMast1; break; } } if (!Cools.isEmpty(tmp)) { locMast = tmp; break; } } } if (Cools.isEmpty(locMast)) { //单品找不到库位,允许尝试从混放区域中进行搜索 List<LocMast> locMasts2 = locMastService.selectAreaEmptyByLev(locTypeDto.getLocType1(), 1, lev);//搜索混放库位 //混放区域直接取第一个即可 for (LocMast mast : locMasts2) { // 浅库位符合尺寸检测 if (VersionUtils.checkLocType(mast, locTypeDto)) { locMast = mast; break; } } } } return locMast; } //返回dto private StartupDto getShuttleLocStartupDto(Integer staDescId, Integer sourceStaNo, LocMast locMast) { StartupDto startupDto = new StartupDto(); String locNo = locMast.getLocNo(); // 获取目标站 Wrapper<StaDesc> wrapper = new EntityWrapper<StaDesc>() .eq("type_no", staDescId) .eq("stn_no", sourceStaNo) .eq("crn_no",Utils.stnNoToLiftNo(sourceStaNo));//借用堆垛机号字段充当提升机号 StaDesc staDesc = staDescService.selectOne(wrapper); if (Cools.isEmpty(staDesc)) { log.error("入库路径不存在, staDescId={}, sourceStaNo={}", staDescId, sourceStaNo); throw new CoolException("入库路径不存在"); } // 检测目标站 BasDevp staNo = basDevpService.selectById(staDesc.getCrnStn()); if (!staNo.getAutoing().equals("Y")) { throw new CoolException("目标站" + staDesc.getCrnStn() + "不可用"); } // 生成工作号 int workNo = getWorkNo(0); // 返回dto startupDto.setWorkNo(workNo); startupDto.setSourceStaNo(sourceStaNo); startupDto.setStaNo(staNo.getDevNo()); startupDto.setLocNo(locMast.getLocNo()); return startupDto; } } src/main/java/com/zy/common/web/WcsController.java
@@ -58,6 +58,72 @@ // @Autowired // private ErpService erpService; @PostMapping("/pakin/loc/v2") @ResponseBody public synchronized R getLocNoV2(@RequestBody SearchLocParam param) { if (Cools.isEmpty(param.getIoType())) { return R.error("入出库类型不能为空"); } if (Cools.isEmpty(param.getSourceStaNo())) { return R.error("源站编号不能为空"); } List<WaitPakin> waitPakins = null; ArrayList<Mat> mats = new ArrayList<>(); if (param.getIoType() == 1) { if (Cools.isEmpty(param.getBarcode())) { return R.error("条码不能为空"); } waitPakins = waitPakinService.selectList(new EntityWrapper<WaitPakin>().eq("zpallet", param.getBarcode())); if (Cools.isEmpty(waitPakins)) { WrkMast wrkMast = wrkMastService.selectByBarcode(param.getBarcode()); if (wrkMast != null && (wrkMast.getIoType() == 103 || wrkMast.getIoType() == 104 || wrkMast.getIoType() == 107)) { return R.parse(CodeRes.PICK_600); } return R.parse(CodeRes.NO_COMB_700); } for (WaitPakin waitPakin : waitPakins) { Mat mat = matService.selectByMatnr(waitPakin.getMatnr()); mat.setWeight(waitPakin.getAnfme()); mats.add(mat); } int countLoc = locDetlService.selectCount(new EntityWrapper<LocDetl>().eq("zpallet",param.getBarcode())); int countWrk = wrkDetlService.selectCount(new EntityWrapper<WrkDetl>().eq("zpallet",param.getBarcode())); if (countLoc > 0 || countWrk > 0) { return R.error("工作档/库存条码数据已存在"); } } if (Cools.isEmpty(param.getLocType1())){ return R.error("高低检测信号不能为空"); } // 源站点状态检测 BasDevp sourceStaNo = basDevpService.checkSiteStatus(param.getSourceStaNo(), true); LocTypeDto locTypeDto = new LocTypeDto(sourceStaNo); locTypeDto.setLocType1(param.getLocType1()); StartupDto dto = null; switch (param.getIoType()) { case 1://满托盘入库 dto = startupFullPutStore(param.getSourceStaNo(), param.getBarcode(), locTypeDto, mats, waitPakins, 2); break; case 10://空托盘入库 dto = emptyPlateIn(param.getSourceStaNo(), locTypeDto, param.getBarcode(), 2); break; case 103:// 拣料入库 case 104:// 并板入库 case 107:// 盘点入库 dto = pickWrkPlateIn(param.getWrkNo(), param.getIoType(), param.getSourceStaNo(), locTypeDto, 2); break; default: break; } log.info("/pakin/loc/v1:"+dto + "======托盘码:"+param.getBarcode()); return R.ok().add(dto); } @PostMapping("/pakin/loc/v1") @ResponseBody public synchronized R getLocNo(@RequestBody SearchLocParam param) { @@ -134,17 +200,28 @@ return R.ok().add(dto); } /** * 全板入库 */ public StartupDto startupFullPutStore(Integer devpNo, String barcode, LocTypeDto locTypeDto, List<Mat> mats, List<WaitPakin> waitPakins) { return startupFullPutStore(devpNo, barcode, locTypeDto, mats, waitPakins, 1); } /** * 全板入库 */ @Transactional public StartupDto startupFullPutStore(Integer devpNo, String barcode, LocTypeDto locTypeDto, List<Mat> mats, List<WaitPakin> waitPakins) { public StartupDto startupFullPutStore(Integer devpNo, String barcode, LocTypeDto locTypeDto, List<Mat> mats, List<WaitPakin> waitPakins, Integer version) { // 源站点状态检测 BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true); // 检索库位 List<String> matnrList = mats.stream().map(Mat::getMatnr).distinct().collect(Collectors.toList()); StartupDto dto = commonService.getLocNo(1, 1, devpNo, matnrList, locTypeDto,0); StartupDto dto = null; if (version == 2) { dto = commonService.getShuttleLocNo( 1, devpNo, matnrList, locTypeDto); }else { dto = commonService.getLocNo(1, 1, devpNo, matnrList, locTypeDto, 0); } int workNo = dto.getWorkNo(); Date now = new Date(); // 生成工作档 @@ -156,7 +233,8 @@ Double ioPri = wrkMastService.getIoPri(1, dto.getLocNo()); wrkMast.setIoPri(ioPri); // 优先级 wrkMast.setCrnNo(dto.getCrnNo()); wrkMast.setOutMost(locMastService.isOutMost(dto.getLocNo(), true)?1:0);; wrkMast.setOutMost(locMastService.isOutMost(dto.getLocNo(), true) ? 1 : 0); ; wrkMast.setSourceStaNo(dto.getSourceStaNo()); wrkMast.setStaNo(dto.getStaNo()); wrkMast.setLocNo(dto.getLocNo()); @@ -176,11 +254,11 @@ } waitPakins.forEach(waitPakin -> { Mat mat = matService.selectByMatnr(waitPakin.getMatnr()); if(Cools.isEmpty(mat)){ if (Cools.isEmpty(mat)) { throw new CoolException(waitPakin.getMatnr() + "该物料号无法查询,请查看物料信息是否存在"); } WrkDetl wrkDetl = new WrkDetl(); BeanUtils.copyProperties(waitPakin,wrkDetl); BeanUtils.copyProperties(waitPakin, wrkDetl); wrkDetl.setZpallet(barcode); wrkDetl.setWrkNo(wrkMast.getWrkNo()); wrkDetl.setIoTime(wrkMast.getIoTime()); @@ -217,29 +295,39 @@ // 更新源站点信息 sourceStaNo.setWrkNo(workNo); sourceStaNo.setModiTime(now); if (!basDevpService.updateById(sourceStaNo)){ if (!basDevpService.updateById(sourceStaNo)) { throw new CoolException("更新源站失败"); } // 更新目标库位状态 LocMast locMast = locMastService.selectById(dto.getLocNo()); if (locMast.getLocSts().equals("O")){ if (locMast.getLocSts().equals("O")) { locMast.setLocSts("S"); // S.入库预约 locMast.setModiTime(now); if (!locMastService.updateById(locMast)){ if (!locMastService.updateById(locMast)) { throw new CoolException("改变库位状态失败"); } } else { throw new CoolException(dto.getLocNo()+"目标库位已被占用"); throw new CoolException(dto.getLocNo() + "目标库位已被占用"); } return dto; } @Transactional public StartupDto emptyPlateIn(Integer devpNo, LocTypeDto locTypeDto, String barcode) { return emptyPlateIn(devpNo, locTypeDto, barcode, 1); } @Transactional public StartupDto emptyPlateIn(Integer devpNo, LocTypeDto locTypeDto, String barcode, Integer version) { // 源站点状态检测 BasDevp sourceStaNo = basDevpService.checkSiteStatus(devpNo, true); // 检索库位 StartupDto dto = commonService.getLocNo(1, 10, devpNo, null, locTypeDto,0); StartupDto dto = null; if (version == 2) { dto = commonService.getShuttleLocNo(10, devpNo, null, locTypeDto); }else { dto = commonService.getLocNo(1, 10, devpNo, null, locTypeDto, 0); } int workNo = dto.getWorkNo(); // 生成工作档 WrkMast wrkMast = new WrkMast(); @@ -249,7 +337,8 @@ wrkMast.setIoType(10); // 入出库状态:10.空板入库 Double ioPri = wrkMastService.getIoPri(10, dto.getLocNo()); wrkMast.setIoPri(ioPri); // 优先级 wrkMast.setOutMost(locMastService.isOutMost(dto.getLocNo(), true)?1:0);; wrkMast.setOutMost(locMastService.isOutMost(dto.getLocNo(), true) ? 1 : 0); ; wrkMast.setCrnNo(dto.getCrnNo()); wrkMast.setSourceStaNo(dto.getSourceStaNo()); wrkMast.setStaNo(dto.getStaNo()); @@ -272,25 +361,30 @@ // 更新源站点信息 sourceStaNo.setWrkNo(workNo); sourceStaNo.setModiTime(new Date()); if (!basDevpService.updateById(sourceStaNo)){ if (!basDevpService.updateById(sourceStaNo)) { throw new CoolException("更新源站失败"); } // 更新目标库位状态 LocMast locMast = locMastService.selectById(dto.getLocNo()); if (locMast.getLocSts().equals("O")){ if (locMast.getLocSts().equals("O")) { locMast.setLocSts("S"); // S.入库预约 locMast.setModiTime(new Date()); if (!locMastService.updateById(locMast)){ if (!locMastService.updateById(locMast)) { throw new CoolException("改变库位状态失败"); } } else { throw new CoolException(dto.getLocNo()+"目标库位已被占用"); throw new CoolException(dto.getLocNo() + "目标库位已被占用"); } return dto; } @Transactional public StartupDto pickWrkPlateIn(Integer wrkNo, Integer ioType, Integer devpNo, LocTypeDto locTypeDto) { return pickWrkPlateIn(wrkNo, ioType, devpNo, locTypeDto, 1); } @Transactional public StartupDto pickWrkPlateIn(Integer wrkNo, Integer ioType, Integer devpNo, LocTypeDto locTypeDto, Integer version) { WrkMast wrkMast = wrkMastService.selectOfPick(wrkNo, ioType); if (Cools.isEmpty(wrkMast)) { log.error("{}任务【ioType = {}】已过期!!!", wrkNo, ioType); @@ -307,17 +401,22 @@ devpNo = 341; } } StartupDto dto = commonService.getLocNo(1, ioType - 50, devpNo, matnrList, locTypeDto,0); // 库位号, 堆垛机,目标站 StartupDto dto = null; if (version == 2) { dto = commonService.getShuttleLocNo( ioType - 50, devpNo, matnrList, locTypeDto); // 库位号, 堆垛机,目标站 }else { dto = commonService.getLocNo(1, ioType - 50, devpNo, matnrList, locTypeDto, 0); // 库位号, 堆垛机,目标站 } // 更新目标库位状态 LocMast locMast = locMastService.selectById(dto.getLocNo()); if (locMast.getLocSts().equals("O")){ if (locMast.getLocSts().equals("O")) { locMast.setLocSts("S"); // S.入库预约 locMast.setModiTime(new Date()); if (!locMastService.updateById(locMast)){ if (!locMastService.updateById(locMast)) { throw new CoolException("改变库位状态失败"); } } else { throw new CoolException(dto.getLocNo()+"目标库位已被占用"); throw new CoolException(dto.getLocNo() + "目标库位已被占用"); } return dto; } src/main/resources/mapper/LocDetlMapper.xml
@@ -343,6 +343,27 @@ ORDER BY lm.modi_time ASC </select> <select id="selectSameLevDetl" resultType="java.lang.String"> SELECT ld.loc_no FROM asr_loc_detl ld LEFT JOIN asr_loc_mast lm ON ld.loc_no = lm.loc_no LEFT JOIN ( select loc_no, count(1) as count from asr_loc_detl where 1=1 group by loc_no ) dual on dual.loc_no = lm.loc_no WHERE 1 = 1 AND ld.matnr = #{matnr} AND (lm.loc_sts = 'F') AND dual.count = 1 AND lm.lev1 = #{lev} ORDER BY lm.modi_time ASC </select> <select id="searchByLike" resultMap="BaseResultMap"> select * from asr_loc_detl src/main/resources/mapper/LocMastMapper.xml
@@ -119,7 +119,18 @@ <if test="locType1 != null"> and loc_type1 = #{locType1} </if> ORDER BY lev1,bay1,row1 ORDER BY row1,bay1,lev1 </select> <select id="selectAreaEmptyByLev" resultMap="BaseResultMap"> select * from asr_loc_mast where loc_sts in ('O') and loc_type3 = #{locType3} <if test="locType1 != null"> and loc_type1 = #{locType1} </if> and lev1 = #{lev} ORDER BY row1,bay1,lev1 </select> <select id="selectEmptyByLocNos" resultMap="BaseResultMap"> src/main/resources/mapper/WrkMastMapper.xml
@@ -106,4 +106,8 @@ where m.wrk_no=d.wrk_no and io_type=1 and wrk_sts < 11 and d.matnr = #{matnr} ORDER BY m.wrk_no desc </select> <select id="selectSameLevMatnrs" resultMap="BaseResultMap"> select m.loc_no from asr_wrk_mast m,asr_wrk_detl d,asr_loc_mast lm where m.wrk_no=d.wrk_no and m.loc_no = lm.loc_no and io_type=1 and wrk_sts < 11 and d.matnr = #{matnr} and lm.lev1 = #{lev} ORDER BY m.wrk_no desc </select> </mapper>