zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/WorkController.java
@@ -22,7 +22,11 @@ @PostMapping("/rpc/generatePakIn") public R generatePakIn(@RequestBody GeneratePakInParam param) { try { workService.generatePakIn(param); if (param.getTaskType() == 10) { workService.generateEmptyPakIn(param);//空托盘 }else { workService.generatePakIn(param);//满托盘 } return R.ok("添加成功"); } catch (Exception e) { return R.error(e.getMessage()); zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/LanewayRule.java
@@ -1,5 +1,6 @@ package com.zy.asrs.wms.asrs.entity; import com.alibaba.fastjson.JSON; import com.baomidou.mybatisplus.annotation.TableLogic; import java.text.SimpleDateFormat; import java.util.Date; @@ -25,6 +26,7 @@ import java.io.Serializable; import java.util.Date; import java.util.List; @Data @TableName("strategy_laneway_rule") @@ -136,6 +138,24 @@ // null // 备注 // ); public List<Integer> getLaneX$() { if (null == this.laneX){ return null; } List<Integer> list = JSON.parseArray(this.laneX, Integer.class); if (list.isEmpty()) { return null; } return list; } public List<Integer> getLaneY$() { if (null == this.laneY){ return null; } List<Integer> list = JSON.parseArray(this.laneY, Integer.class); if (list.isEmpty()) { return null; } return list; } public String getHostId$(){ HostService service = SpringUtils.getBean(HostService.class); Host host = service.getById(this.hostId); zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/OrderDetl.java
@@ -9,6 +9,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.fasterxml.jackson.annotation.JsonAnyGetter; import com.zy.asrs.common.utils.Synchro; import com.zy.asrs.wms.asrs.entity.param.FieldParam; import com.zy.asrs.wms.asrs.service.MatFieldService; import com.zy.asrs.wms.asrs.service.MatService; import com.zy.asrs.wms.asrs.service.OrderService; import com.zy.asrs.wms.asrs.service.WaitPakinService; @@ -333,5 +335,18 @@ dynamicFields.put(key, value); } //获取索引字段 public List<FieldParam> getUniqueField() { MatFieldService service = SpringUtils.getBean(MatFieldService.class); List<FieldParam> list = new ArrayList<>(); for (MatField matField : service.list(new LambdaQueryWrapper<MatField>().eq(MatField::getUnique, 1))) { FieldParam param = new FieldParam(); param.setName(matField.getName()); param.setValue(dynamicFields.get(matField.getName())); list.add(param); } return list; } } zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetl.java
@@ -103,6 +103,12 @@ private Long matId; /** * 商品编号 */ @ApiModelProperty(value= "商品编号") private String matnr; /** * 所属机构 */ @ApiModelProperty(value= "所属机构") zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/enums/LocTypeHeightType.java
New file @@ -0,0 +1,33 @@ package com.zy.asrs.wms.asrs.entity.enums; /** * 库位高度类型 */ public enum LocTypeHeightType { LOW(1, "low", "低库位"), MIDDLE(2, "middle", "中库位"), HEIGHT(3, "height", "高库位"), ; public Integer id; public String flag; public String desc; LocTypeHeightType(Integer id, String flag, String desc) { this.id = id; this.flag = flag; this.desc = desc; } public static LocTypeHeightType get(Integer id) { for (LocTypeHeightType value : LocTypeHeightType.values()) { if (value.id.equals(id)) { return value; } } return null; } } zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/param/GeneratePakInParam.java
@@ -14,4 +14,7 @@ //源站点 private String originSite; //库位高度{LocTypeHeightType} private Integer locTypeHeight; } zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/LocTypeBindMapper.java
@@ -5,8 +5,12 @@ import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; import java.util.List; @Mapper @Repository public interface LocTypeBindMapper extends BaseMapper<LocTypeBind> { List<Long> getLocIdListByTypeId(Long typeId); } zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/MatFieldMapper.java
@@ -1,6 +1,5 @@ package com.zy.asrs.wms.asrs.mapper; import com.zy.asrs.wms.asrs.entity.LocDetlField; import com.zy.asrs.wms.asrs.entity.MatField; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.Mapper; @@ -18,9 +17,20 @@ @SelectProvider(type = SqlProvider.class, method = "createViewSql") void createView(@Param("list") List<MatField> list); @SelectProvider(type = SqlProvider.class, method = "createLocDetlView") void createLocDetlView(); @SelectProvider(type = SqlProvider.class, method = "createTaskDetlFieldSql") void createTaskDetlFieldView(@Param("list") List<MatField> list); @SelectProvider(type = SqlProvider.class, method = "createViewTaskDetlSql") void createViewTaskDetlView(); @SelectProvider(type = SqlProvider.class, method = "createOrderDetlFieldSql") void createOrderDetlFieldView(@Param("list") List<MatField> list); @SelectProvider(type = SqlProvider.class, method = "createViewOrderDetlSql") void createViewOrderDetlView(); class SqlProvider { public String createViewSql(Map<String, Object> params) { @@ -48,6 +58,58 @@ return sql.toString(); } public String createTaskDetlFieldSql(Map<String, Object> params) { List<MatField> list = (List<MatField>) params.get("list"); StringBuilder sql = new StringBuilder(); sql.append(" CREATE OR REPLACE VIEW view_man_task_detl_field AS \n"); sql.append(" SELECT detl_id as _detl_id "); for (MatField matField : list) { sql.append(", MAX(CASE WHEN name = '").append(matField.getName()).append("' THEN value END) AS ").append(matField.getName()); } sql.append(" FROM man_task_detl_field "); sql.append(" GROUP BY _detl_id "); return sql.toString(); } public String createViewTaskDetlSql() { StringBuilder sql = new StringBuilder(); sql.append(" CREATE OR REPLACE VIEW view_man_task_detl AS \n"); sql.append(" select * from man_task_detl td "); sql.append(" left join view_man_task_detl_field tdf "); sql.append(" on td.id = tdf._detl_id "); return sql.toString(); } public String createOrderDetlFieldSql(Map<String, Object> params) { List<MatField> list = (List<MatField>) params.get("list"); StringBuilder sql = new StringBuilder(); sql.append(" CREATE OR REPLACE VIEW view_man_order_detl_field AS \n"); sql.append(" SELECT detl_id as _detl_id "); for (MatField matField : list) { sql.append(", MAX(CASE WHEN name = '").append(matField.getName()).append("' THEN value END) AS ").append(matField.getName()); } sql.append(" FROM man_order_detl_field "); sql.append(" GROUP BY _detl_id "); return sql.toString(); } public String createViewOrderDetlSql() { StringBuilder sql = new StringBuilder(); sql.append(" CREATE OR REPLACE VIEW view_man_order_detl AS \n"); sql.append(" select * from man_order_detl od "); sql.append(" left join view_man_order_detl_field odf "); sql.append(" on od.id = odf._detl_id "); return sql.toString(); } } } zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/ViewLocDetlMapper.java
@@ -15,6 +15,8 @@ List<Map<String,Object>> getList(String matnr, String batch, List<FieldParam> param); List<Map<String,Object>> getListLike(String matnr, String batch, List<FieldParam> param); Map<String,Object> getById(Long id); } zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/ViewOrderDetlMapper.java
New file @@ -0,0 +1,12 @@ package com.zy.asrs.wms.asrs.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.zy.asrs.wms.asrs.entity.ViewLocDetl; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; @Mapper @Repository public interface ViewOrderDetlMapper extends BaseMapper<ViewLocDetl> { } zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/ViewTaskDetlMapper.java
New file @@ -0,0 +1,20 @@ package com.zy.asrs.wms.asrs.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.zy.asrs.wms.asrs.entity.ViewLocDetl; import com.zy.asrs.wms.asrs.entity.param.FieldParam; import org.apache.ibatis.annotations.Mapper; import org.springframework.stereotype.Repository; import java.util.List; import java.util.Map; @Mapper @Repository public interface ViewTaskDetlMapper extends BaseMapper<ViewLocDetl> { List<Map<String,Object>> getList(String matnr, String batch, List<FieldParam> param); Map<String,Object> getById(Long id); } zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/LanewayRuleService.java
@@ -2,7 +2,10 @@ import com.baomidou.mybatisplus.extension.service.IService; import com.zy.asrs.wms.asrs.entity.LanewayRule; import com.zy.asrs.wms.asrs.entity.Loc; public interface LanewayRuleService extends IService<LanewayRule> { LanewayRule getLaneByLoc(Loc loc); } zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/LocTypeBindService.java
@@ -1,8 +1,15 @@ package com.zy.asrs.wms.asrs.service; import com.baomidou.mybatisplus.extension.service.IService; import com.zy.asrs.wms.asrs.entity.LocType; import com.zy.asrs.wms.asrs.entity.LocTypeBind; import java.util.List; public interface LocTypeBindService extends IService<LocTypeBind> { List<Long> getLocIdListByTypeId(Long typeId); List<Long> getLocIdListByType(LocType locType); } zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/WorkService.java
@@ -11,12 +11,18 @@ //生成优先级 Integer generateIoPri(Long taskType); //生成可用库位号 Loc generateLoc(Long taskType); //生成空托盘可用库位号 Loc generateEmptyLoc(Long taskType, Integer locTypeHeight); //生成入库任务 //生成可用库位号 Loc generateLoc(Long taskType, String barcode, Integer locTypeHeight); //生成入库任务(满托盘) boolean generatePakIn(GeneratePakInParam param); //生成入库任务(空托盘) boolean generateEmptyPakIn(GeneratePakInParam param); //完成任务 boolean completeTask(Long taskId); zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/LanewayRuleServiceImpl.java
@@ -1,12 +1,29 @@ package com.zy.asrs.wms.asrs.service.impl; import com.zy.asrs.wms.asrs.entity.Loc; import com.zy.asrs.wms.asrs.mapper.LanewayRuleMapper; import com.zy.asrs.wms.asrs.entity.LanewayRule; import com.zy.asrs.wms.asrs.service.LanewayRuleService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; import java.util.List; @Service("lanewayRuleService") public class LanewayRuleServiceImpl extends ServiceImpl<LanewayRuleMapper, LanewayRule> implements LanewayRuleService { @Override public LanewayRule getLaneByLoc(Loc loc) { List<LanewayRule> list = this.list(); for (LanewayRule rule : list) { List<Integer> laneX = rule.getLaneX$(); List<Integer> laneY = rule.getLaneY$(); laneX.addAll(laneY); if (laneX.contains(loc.getRow1())) { return rule; } } return null; } } zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/LocDetlServiceImpl.java
@@ -66,7 +66,7 @@ param.add(fieldParam); } List<Map<String, Object>> list2 = viewLocDetlMapper.getList(matnr, batch, param); List<Map<String, Object>> list2 = viewLocDetlMapper.getListLike(matnr, batch, param); List<LocDetl> locDetls = new ArrayList<>(); for (Map<String, Object> objectMap : list2) { LocDetl locDetl = JSON.parseObject(JSON.toJSONString(objectMap), LocDetl.class); zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/LocTypeBindServiceImpl.java
@@ -1,12 +1,38 @@ package com.zy.asrs.wms.asrs.service.impl; import com.alibaba.fastjson.JSON; import com.zy.asrs.framework.common.Cools; import com.zy.asrs.wms.asrs.entity.LocType; import com.zy.asrs.wms.asrs.mapper.LocTypeBindMapper; import com.zy.asrs.wms.asrs.entity.LocTypeBind; import com.zy.asrs.wms.asrs.service.LocTypeBindService; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import org.springframework.stereotype.Service; import java.util.Collections; import java.util.List; @Service("locTypeBindService") public class LocTypeBindServiceImpl extends ServiceImpl<LocTypeBindMapper, LocTypeBind> implements LocTypeBindService { @Override public List<Long> getLocIdListByTypeId(Long typeId) { return this.baseMapper.getLocIdListByTypeId(typeId); } @Override public List<Long> getLocIdListByType(LocType locType) { List<Long> locIdList = this.getLocIdListByTypeId(locType.getId()); if (!Cools.isEmpty(locType.getContain())) { List<Long> list = JSON.parseArray(locType.getContain(), Long.class); for (Long id : list) { List<Long> longs = this.getLocIdListByTypeId(id); if (!longs.isEmpty()) { locIdList.addAll(longs); } } } return locIdList; } } zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/MatFieldServiceImpl.java
@@ -19,6 +19,13 @@ List<MatField> list = this.list(); this.baseMapper.createView(list); this.baseMapper.createLocDetlView(); this.baseMapper.createTaskDetlFieldView(list); this.baseMapper.createViewTaskDetlView(); this.baseMapper.createOrderDetlFieldView(list); this.baseMapper.createViewOrderDetlView(); } @Override zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/WorkServiceImpl.java
@@ -7,13 +7,12 @@ import com.zy.asrs.wms.asrs.entity.enums.OrderSettleType; import com.zy.asrs.wms.asrs.entity.param.GeneratePakInParam; import com.zy.asrs.wms.asrs.service.*; import com.zy.asrs.wms.utils.LocUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.Date; import java.util.List; import java.util.Random; import java.util.*; @Service("workService") public class WorkServiceImpl implements WorkService { @@ -44,6 +43,8 @@ private TaskDetlLogService taskDetlLogService; @Autowired private TaskDetlFieldLogService taskDetlFieldLogService; @Autowired private LocUtils locUtils; @Override public String generateTaskNo(Long taskType) { @@ -58,20 +59,92 @@ } @Override public Loc generateLoc(Long taskType) { LocSts locSts = locStsService.getOne(new LambdaQueryWrapper<LocSts>().eq(LocSts::getLocSts, String.valueOf(LocStsType.O))); List<Loc> list = locService.list(new LambdaQueryWrapper<Loc>().eq(Loc::getLocStsId, locSts.getId())); if (list.isEmpty()) { throw new CoolException("没有空库位"); public Loc generateEmptyLoc(Long taskType, Integer locTypeHeight) { Loc defaultLoc = null; //1.从库存或任务中匹配相邻库位 defaultLoc = locUtils.getNeighborEmptyLoc(taskType, locTypeHeight); if (defaultLoc != null) { return defaultLoc; } return list.get(0); //2.获取推荐库位 List<Loc> suggestLoc = locUtils.getSuggestEmptyLoc(taskType, locTypeHeight); //获取库位 if (!suggestLoc.isEmpty()) { defaultLoc = locUtils.filterLoc(taskType, suggestLoc); if(defaultLoc != null) { return defaultLoc; } } //3.从全局库位中获取(完整巷道) List<Loc> globalLoc = locUtils.getGlobalEmptyLoc(taskType, locTypeHeight); //获取库位 if (!globalLoc.isEmpty()) { defaultLoc = locUtils.filterAllLoc(globalLoc); if(defaultLoc != null) { return defaultLoc; } } return defaultLoc; } @Override public Loc generateLoc(Long taskType, String barcode, Integer locTypeHeight) { List<WaitPakin> waitPakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getBarcode, barcode)); if (taskType != 10 && waitPakins.isEmpty()) { throw new CoolException("托盘未组托"); } WaitPakin waitPakin = waitPakins.get(0); OrderDetl detl = waitPakin.getDetl$(); if (detl == null) { throw new CoolException("订单明细不存在"); } Mat mat = detl.getMat$(); if (mat == null) { throw new CoolException("商品不存在"); } Loc defaultLoc = null; //1.从库存或任务中匹配相邻库位 defaultLoc = locUtils.getNeighborLoc(taskType, detl, locTypeHeight); if (defaultLoc != null) { return defaultLoc; } //2.获取推荐库位 List<Loc> suggestLoc = locUtils.getSuggestLoc(taskType, mat.getId(), detl.getBatch(), locTypeHeight); //获取库位 if (!suggestLoc.isEmpty()) { defaultLoc = locUtils.filterLoc(taskType, suggestLoc); if(defaultLoc != null) { return defaultLoc; } } //3.从全局库位中获取(完整巷道) List<Loc> globalLoc = locUtils.getGlobalLoc(taskType, locTypeHeight); //获取库位 if (!globalLoc.isEmpty()) { defaultLoc = locUtils.filterAllLoc(globalLoc); if(defaultLoc != null) { return defaultLoc; } } return defaultLoc; } @Override @Transactional public boolean generatePakIn(GeneratePakInParam param) { List<WaitPakin> waitPakins = waitPakinService.list(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getBarcode, param.getBarcode())); if (waitPakins.isEmpty()) { if (param.getTaskType() != 10 && waitPakins.isEmpty()) { throw new CoolException("托盘未组托"); } @@ -80,8 +153,16 @@ throw new CoolException("任务类型不存在"); } Task one = taskService.getOne(new LambdaQueryWrapper<Task>().eq(Task::getBarcode, param.getBarcode())); if (one != null) { throw new CoolException("任务已经创建,请勿重复请求"); } //生成库位 Loc loc = this.generateLoc(param.getTaskType()); Loc loc = this.generateLoc(param.getTaskType(), param.getBarcode(), param.getLocTypeHeight()); if(loc == null) { throw new CoolException("没有空库位"); } Task task = new Task(); task.setTaskNo(this.generateTaskNo(taskType.getId()));//任务号 @@ -111,6 +192,7 @@ taskDetl.setOrderNo(waitPakin.getOrderNo()); taskDetl.setDetlId(waitPakin.getDetlId()); taskDetl.setMatId(waitPakin.getDetl$().getMatId()); taskDetl.setMatnr(waitPakin.getDetl$().getMat$().getMatnr()); boolean taskDetlSave = taskDetlService.save(taskDetl); if(!taskDetlSave){ throw new CoolException("任务明细生成失败"); @@ -179,6 +261,45 @@ } @Override public boolean generateEmptyPakIn(GeneratePakInParam param) { TaskType taskType = taskTypeService.getById(param.getTaskType()); if (taskType == null) { throw new CoolException("任务类型不存在"); } //生成库位 Loc loc = this.generateEmptyLoc(param.getTaskType(), param.getLocTypeHeight()); if(loc == null) { throw new CoolException("没有空库位"); } Task task = new Task(); task.setTaskNo(this.generateTaskNo(taskType.getId()));//任务号 task.setTaskSts(1L);//1.生成入库任务 task.setTaskType(taskType.getId());//任务类型 task.setIoPri(this.generateIoPri(taskType.getId()));//优先级 task.setOriginLoc(null); task.setTargetLoc(loc.getLocNo()); task.setOriginSite(param.getOriginSite()); task.setTargetSite(null); task.setBarcode(null);//托盘码 boolean taskSave = taskService.save(task); if (!taskSave) { throw new CoolException("任务生成失败"); } //库位O => S loc.setLocStsId(LocStsType.S.val()); loc.setUpdateTime(new Date()); boolean locUpdate = locService.updateById(loc); if(!locUpdate){ throw new CoolException("库位状态更新失败"); } return true; } @Override public boolean completeTask(Long taskId) { Task task = taskService.getById(taskId); if(task == null){ @@ -214,15 +335,11 @@ throw new CoolException("任务不存在"); } List<TaskDetl> taskDetls = taskDetlService.getTaskDetlByTaskId(taskId); if (taskDetls.isEmpty()) { throw new CoolException("任务明细不存在"); } //更新库位状态 Loc loc = null; switch (task.getTaskType().intValue()) { case 1://入库 case 10://空板 case 53://拣料 case 54://并板 case 57://盘点 @@ -243,6 +360,7 @@ case 103://拣料 case 104://并板 case 107://盘点 case 110://空板 loc = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, task.getOriginLoc())); if(loc == null){ throw new CoolException("库位不存在"); @@ -258,64 +376,71 @@ break; } //回滚订单 for (TaskDetl taskDetl : taskDetls) { OrderDetl orderDetl = orderDetlService.getById(taskDetl.getDetlId()); if(orderDetl == null){ throw new CoolException("订单明细不存在"); if (task.getTaskType() != 10) { List<TaskDetl> taskDetls = taskDetlService.getTaskDetlByTaskId(taskId); if (taskDetls.isEmpty()) { throw new CoolException("任务明细不存在"); } //回滚工作数量 orderDetl.setWorkQty(orderDetl.getWorkQty() - taskDetl.getAnfme()); orderDetl.setUpdateTime(new Date()); boolean orderDetlUpdate = orderDetlService.updateById(orderDetl); if(!orderDetlUpdate){ throw new CoolException("工作数量回滚失败"); } //入库回滚组托通知档 if (task.getTaskType() == 1) { WaitPakin waitPakin = waitPakinService.getOne(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getDetlId, taskDetl.getDetlId()).eq(WaitPakin::getBarcode, task.getBarcode())); if(waitPakin == null){ throw new CoolException("组托通知档不存在"); //回滚订单 for (TaskDetl taskDetl : taskDetls) { OrderDetl orderDetl = orderDetlService.getById(taskDetl.getDetlId()); if(orderDetl == null){ throw new CoolException("订单明细不存在"); } waitPakin.setIoStatus(0); waitPakin.setUpdateTime(new Date()); boolean updateWaitPakin = waitPakinService.updateById(waitPakin); if(!updateWaitPakin){ throw new CoolException("组托通知档回滚失败"); } } List<TaskDetlField> detlFields = taskDetlFieldService.list(new LambdaQueryWrapper<TaskDetlField>().eq(TaskDetlField::getDetlId, taskDetl.getId())); for (TaskDetlField detlField : detlFields) { //明细扩展字段数据保存至历史档 TaskDetlFieldLog taskDetlFieldLog = new TaskDetlFieldLog(); taskDetlFieldLog.sync(detlField); if (!taskDetlFieldLogService.save(taskDetlFieldLog)) { throw new CoolException("明细扩展字段转历史档案失败"); //回滚工作数量 orderDetl.setWorkQty(orderDetl.getWorkQty() - taskDetl.getAnfme()); orderDetl.setUpdateTime(new Date()); boolean orderDetlUpdate = orderDetlService.updateById(orderDetl); if(!orderDetlUpdate){ throw new CoolException("工作数量回滚失败"); } //删除明细扩展 boolean removeField = taskDetlFieldService.removeById(detlField.getId()); if(!removeField){ throw new CoolException("回滚扩展明细失败"); //入库回滚组托通知档 if (task.getTaskType() == 1) { WaitPakin waitPakin = waitPakinService.getOne(new LambdaQueryWrapper<WaitPakin>().eq(WaitPakin::getDetlId, taskDetl.getDetlId()).eq(WaitPakin::getBarcode, task.getBarcode())); if(waitPakin == null){ throw new CoolException("组托通知档不存在"); } waitPakin.setIoStatus(0); waitPakin.setUpdateTime(new Date()); boolean updateWaitPakin = waitPakinService.updateById(waitPakin); if(!updateWaitPakin){ throw new CoolException("组托通知档回滚失败"); } } } List<TaskDetlField> detlFields = taskDetlFieldService.list(new LambdaQueryWrapper<TaskDetlField>().eq(TaskDetlField::getDetlId, taskDetl.getId())); for (TaskDetlField detlField : detlFields) { //明细扩展字段数据保存至历史档 TaskDetlFieldLog taskDetlFieldLog = new TaskDetlFieldLog(); taskDetlFieldLog.sync(detlField); if (!taskDetlFieldLogService.save(taskDetlFieldLog)) { throw new CoolException("明细扩展字段转历史档案失败"); } //删除明细扩展 boolean removeField = taskDetlFieldService.removeById(detlField.getId()); if(!removeField){ throw new CoolException("回滚扩展明细失败"); } } //明细数据保存至历史档 TaskDetlLog taskDetlLog = new TaskDetlLog(); taskDetlLog.sync(taskDetl); if (!taskDetlLogService.save(taskDetlLog)) { throw new CoolException("明细数据转历史档案失败"); } //明细数据保存至历史档 TaskDetlLog taskDetlLog = new TaskDetlLog(); taskDetlLog.sync(taskDetl); if (!taskDetlLogService.save(taskDetlLog)) { throw new CoolException("明细数据转历史档案失败"); } //删除明细 boolean removeDetl = taskDetlService.removeById(taskDetl.getId()); if(!removeDetl){ throw new CoolException("回滚明细失败"); //删除明细 boolean removeDetl = taskDetlService.removeById(taskDetl.getId()); if(!removeDetl){ throw new CoolException("回滚明细失败"); } } } zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/LocUtils.java
New file @@ -0,0 +1,316 @@ package com.zy.asrs.wms.utils; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.zy.asrs.framework.common.Cools; import com.zy.asrs.framework.exception.CoolException; import com.zy.asrs.wms.asrs.entity.*; import com.zy.asrs.wms.asrs.entity.enums.LocStsType; import com.zy.asrs.wms.asrs.entity.enums.LocTypeHeightType; import com.zy.asrs.wms.asrs.mapper.ViewLocDetlMapper; import com.zy.asrs.wms.asrs.mapper.ViewTaskDetlMapper; import com.zy.asrs.wms.asrs.service.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.util.ArrayList; import java.util.List; import java.util.Map; @Component public class LocUtils { @Autowired private TaskService taskService; @Autowired private LocService locService; @Autowired private SuggestLocRuleService suggestLocRuleService; @Autowired private LanewayRuleService lanewayRuleService; @Autowired private LocTypeService locTypeService; @Autowired private LocTypeBindService locTypeBindService; @Autowired private ViewLocDetlMapper viewLocDetlMapper; @Autowired private ViewTaskDetlMapper viewTaskDetlMapper; //从库存或任务中匹配相邻库位(满托盘) public Loc getNeighborLoc(Long taskType, OrderDetl orderDetl, Integer locTypeHeight) { //满托盘 //从任务中进行匹配 List<Loc> locs = new ArrayList<>(); List<Map<String, Object>> list = viewTaskDetlMapper.getList(orderDetl.getMat$().getMatnr(), orderDetl.getBatch(), orderDetl.getUniqueField()); for (Map<String, Object> map : list) { Task task = taskService.getById(map.get("taskId").toString()); if(task == null) { continue; } String targetLoc = task.getTargetLoc(); Loc one = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, targetLoc)); if(one == null) { continue; } locs.add(one); } Loc loc = filterLoc(taskType, locs); if (loc != null) { return loc; } //从库存中进行匹配 List<Loc> locs2 = new ArrayList<>(); List<Map<String, Object>> list2 = viewLocDetlMapper.getList(orderDetl.getMat$().getMatnr(), orderDetl.getBatch(), orderDetl.getUniqueField()); for (Map<String, Object> map : list2) { Loc one = locService.getById(map.get("locId").toString()); if(one == null) { continue; } locs2.add(one); } Loc loc2 = filterLoc(taskType, locs2); if (loc2 != null) { return loc2; } return null; } //获取推荐库位(满托盘) public List<Loc> getSuggestLoc(Long taskType, Long matId, String batch, Integer locTypeHeight) { //满托盘 List<Loc> locs = new ArrayList<>(); LocTypeHeightType locTypeHeightType = LocTypeHeightType.get(locTypeHeight); if (locTypeHeightType == null) { throw new CoolException("库位高度类型异常"); } //获取库位高度 LocType locType = locTypeService.getOne(new LambdaQueryWrapper<LocType>().eq(LocType::getFlag, locTypeHeightType.flag)); //符合库位高度的库位集合 List<Long> locIdList = locTypeBindService.getLocIdListByType(locType); LambdaQueryWrapper<SuggestLocRule> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(SuggestLocRule::getLocType, 1); wrapper.eq(SuggestLocRule::getMatId, matId); if (!Cools.isEmpty(batch)) { wrapper.eq(SuggestLocRule::getBatch, batch); } List<SuggestLocRule> suggestLocRules = suggestLocRuleService.list(wrapper); for (SuggestLocRule suggestLocRule : suggestLocRules) { LambdaQueryWrapper<Loc> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.ge(Loc::getRow1, suggestLocRule.getStartRow()); queryWrapper.le(Loc::getRow1, suggestLocRule.getTargetRow()); queryWrapper.ge(Loc::getBay1, suggestLocRule.getStartBay()); queryWrapper.le(Loc::getBay1, suggestLocRule.getTargetBay()); queryWrapper.ge(Loc::getLev1, suggestLocRule.getStartLev()); queryWrapper.le(Loc::getLev1, suggestLocRule.getTargetLev()); queryWrapper.eq(Loc::getLocStsId, LocStsType.O.val()); queryWrapper.in(Loc::getId, locIdList); List<Loc> list = locService.list(queryWrapper); if (!list.isEmpty()) { locs.addAll(list); } } return locs; } //获取全局库位(完整巷道) public List<Loc> getGlobalLoc(Long taskType, Integer locTypeHeight) { List<Loc> locs = new ArrayList<>(); LocTypeHeightType locTypeHeightType = LocTypeHeightType.get(locTypeHeight); if (locTypeHeightType == null) { throw new CoolException("库位高度类型异常"); } //获取库位高度 LocType locType = locTypeService.getOne(new LambdaQueryWrapper<LocType>().eq(LocType::getFlag, locTypeHeightType.flag)); //符合库位高度的库位集合 List<Long> locIdList = locTypeBindService.getLocIdListByType(locType); LambdaQueryWrapper<Loc> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(Loc::getLocStsId, LocStsType.O.val()); queryWrapper.in(Loc::getId, locIdList); List<Loc> list = locService.list(queryWrapper); if (!list.isEmpty()) { locs.addAll(list); } return locs; } //从库位集合中获取符合深浅的库位 public Loc filterLoc(Long taskType, List<Loc> locs) { if (locs == null || locs.isEmpty()) { return null; } Loc defaultLoc = null; for (Loc loc : locs) { //获取库位所在巷道 LanewayRule lanewayRule = lanewayRuleService.getLaneByLoc(loc); if(lanewayRule == null) { throw new CoolException("库位未配置巷道"); } //获取库位方向 List<Integer> direction = null; if (lanewayRule.getLaneX$().contains(loc.getRow1())) { direction = lanewayRule.getLaneX$(); }else { direction = lanewayRule.getLaneY$(); } for (Integer row : direction) { Loc one = locService.getOne(new LambdaQueryWrapper<Loc>() .eq(Loc::getRow1, row) .eq(Loc::getBay1, loc.getBay1()) .eq(Loc::getLev1, loc.getLev1())); if (one == null) { continue; } if(one.getLocStsId() != LocStsType.O.val()) { continue; } //当前库位是空库位 defaultLoc = one; break; } if (defaultLoc != null) { break; } } return defaultLoc; } //从库位集合中获取完整空巷道 public Loc filterAllLoc(List<Loc> locs) { if (locs == null || locs.isEmpty()) { return null; } Loc defaultLoc = null; for (Loc loc : locs) { //获取库位所在巷道 LanewayRule lanewayRule = lanewayRuleService.getLaneByLoc(loc); if(lanewayRule == null) { throw new CoolException("库位未配置巷道"); } //获取库位方向 List<Integer> direction = null; if (lanewayRule.getLaneX$().contains(loc.getRow1())) { direction = lanewayRule.getLaneX$(); }else { direction = lanewayRule.getLaneY$(); } boolean flag = false; List<Loc> allLocs = new ArrayList<>(); for (Integer row : direction) { Loc one = locService.getOne(new LambdaQueryWrapper<Loc>() .eq(Loc::getRow1, row) .eq(Loc::getBay1, loc.getBay1()) .eq(Loc::getLev1, loc.getLev1())); if (one == null) { continue; } if(one.getLocStsId() != LocStsType.O.val()) { flag = true; break; } allLocs.add(one); } if (flag) { continue; } if (!allLocs.isEmpty()) { defaultLoc = allLocs.get(0); break;//找到一个完整空巷道 } } return defaultLoc; } //从库存或任务中匹配相邻库位(空托盘) public Loc getNeighborEmptyLoc(Long taskType, Integer locTypeHeight) { //从任务中进行匹配 List<Loc> locs = new ArrayList<>(); List<Task> list = taskService.list(new LambdaQueryWrapper<Task>().eq(Task::getTaskType, 10)); for (Task task : list) { String targetLoc = task.getTargetLoc(); Loc one = locService.getOne(new LambdaQueryWrapper<Loc>().eq(Loc::getLocNo, targetLoc)); if(one == null) { continue; } locs.add(one); } Loc loc = filterLoc(taskType, locs); if (loc != null) { return loc; } //从库存中进行匹配 List<Loc> locs2 = locService.list(new LambdaQueryWrapper<Loc>().eq(Loc::getLocStsId, LocStsType.D.val())); Loc loc2 = filterLoc(taskType, locs2); if (loc2 != null) { return loc2; } return null; } //获取推荐库位(空托盘) public List<Loc> getSuggestEmptyLoc(Long taskType, Integer locTypeHeight) { List<Loc> locs = new ArrayList<>(); //空托盘 List<SuggestLocRule> suggestLocRules = suggestLocRuleService.list(new LambdaQueryWrapper<SuggestLocRule>().eq(SuggestLocRule::getLocType, 0)); for (SuggestLocRule suggestLocRule : suggestLocRules) { LambdaQueryWrapper<Loc> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.ge(Loc::getRow1, suggestLocRule.getStartRow()); queryWrapper.le(Loc::getRow1, suggestLocRule.getTargetRow()); queryWrapper.ge(Loc::getBay1, suggestLocRule.getStartBay()); queryWrapper.le(Loc::getBay1, suggestLocRule.getTargetBay()); queryWrapper.ge(Loc::getLev1, suggestLocRule.getStartLev()); queryWrapper.le(Loc::getLev1, suggestLocRule.getTargetLev()); queryWrapper.eq(Loc::getLocStsId, LocStsType.O.val()); List<Loc> list = locService.list(queryWrapper); if (!list.isEmpty()) { locs.addAll(list); } } return locs; } //获取全局库位(完整巷道) public List<Loc> getGlobalEmptyLoc(Long taskType, Integer locTypeHeight) { List<Loc> locs = new ArrayList<>(); LocTypeHeightType locTypeHeightType = LocTypeHeightType.get(locTypeHeight); if (locTypeHeightType == null) { throw new CoolException("库位高度类型异常"); } //获取库位高度 LocType locType = locTypeService.getOne(new LambdaQueryWrapper<LocType>().eq(LocType::getFlag, locTypeHeightType.flag)); //符合库位高度的库位集合 List<Long> locIdList = locTypeBindService.getLocIdListByType(locType); LambdaQueryWrapper<Loc> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(Loc::getLocStsId, LocStsType.O.val()); queryWrapper.in(Loc::getId, locIdList); List<Loc> list = locService.list(queryWrapper); if (!list.isEmpty()) { locs.addAll(list); } return locs; } } zy-asrs-wms/src/main/resources/mapper/asrs/LocTypeBindMapper.xml
@@ -2,4 +2,9 @@ <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zy.asrs.wms.asrs.mapper.LocTypeBindMapper"> <select id="getLocIdListByTypeId" resultType="long"> select distinct loc_id from man_loc_type_bind where type_id = #{typeId} </select> </mapper> zy-asrs-wms/src/main/resources/mapper/asrs/ViewLocDetlMapper.xml
@@ -10,6 +10,21 @@ </if> <if test="param!=null and param.size()>0"> <foreach item="item" collection="param" index="index"> <if test="item.value!=null"> and ${item.name} = #{item.value} </if> </foreach> </if> </select> <select id="getListLike" resultType="map"> select * from view_man_loc_detl ld where matnr = #{matnr} <if test="batch!=null"> and batch = #{batch} </if> <if test="param!=null and param.size()>0"> <foreach item="item" collection="param" index="index"> and ${item.name} like CONCAT('%',#{item.value},'%') </foreach> </if> zy-asrs-wms/src/main/resources/mapper/asrs/ViewOrderDetlMapper.xml
New file @@ -0,0 +1,5 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zy.asrs.wms.asrs.mapper.ViewOrderDetlMapper"> </mapper> zy-asrs-wms/src/main/resources/mapper/asrs/ViewTaskDetlMapper.xml
New file @@ -0,0 +1,25 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zy.asrs.wms.asrs.mapper.ViewTaskDetlMapper"> <select id="getList" resultType="map"> select * from view_man_task_detl td where matnr = #{matnr} <if test="batch!=null"> and batch = #{batch} </if> <if test="param!=null and param.size()>0"> <foreach item="item" collection="param" index="index"> <if test="item.value!=null"> and ${item.name} = #{item.value} </if> </foreach> </if> </select> <select id="getById" resultType="map"> select * from view_man_task_detl where id = #{id} </select> </mapper>