#
Junjie
2024-08-16 d4f47a3c09e994f896dc358df93656751a812e49
#
6个文件已添加
18个文件已修改
880 ■■■■■ 已修改文件
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/controller/WorkController.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/LanewayRule.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/OrderDetl.java 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/TaskDetl.java 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/enums/LocTypeHeightType.java 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/entity/param/GeneratePakInParam.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/LocTypeBindMapper.java 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/MatFieldMapper.java 66 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/ViewLocDetlMapper.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/ViewOrderDetlMapper.java 12 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/mapper/ViewTaskDetlMapper.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/LanewayRuleService.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/LocTypeBindService.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/WorkService.java 12 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/LanewayRuleServiceImpl.java 17 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/LocDetlServiceImpl.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/LocTypeBindServiceImpl.java 26 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/MatFieldServiceImpl.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/asrs/service/impl/WorkServiceImpl.java 253 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/java/com/zy/asrs/wms/utils/LocUtils.java 316 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/resources/mapper/asrs/LocTypeBindMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/resources/mapper/asrs/ViewLocDetlMapper.xml 15 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/resources/mapper/asrs/ViewOrderDetlMapper.xml 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
zy-asrs-wms/src/main/resources/mapper/asrs/ViewTaskDetlMapper.xml 25 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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>