自动化立体仓库 - WMS系统
chen.llin
2 天以前 2816415f539ef54839e331657edae7055c243ad8
src/main/java/com/zy/asrs/service/impl/LocCacheServiceImpl.java
@@ -1,26 +1,23 @@
package com.zy.asrs.service.impl;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.core.common.Cools;
import com.core.common.R;
import com.core.common.SnowflakeIdWorker;
import com.core.exception.CoolException;
import com.zy.asrs.entity.BasAreas;
import com.zy.asrs.entity.BasWhsType;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.entity.LocCache;
import com.zy.asrs.entity.param.LocMastInitParam;
import com.zy.asrs.mapper.LocCacheMapper;
import com.zy.asrs.entity.LocCache;
import com.zy.asrs.service.BasAreasService;
import com.zy.asrs.service.BasWhsTypeService;
import com.zy.asrs.service.LocCacheService;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.zy.common.model.Shelves;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
@@ -31,6 +28,9 @@
    @Autowired
    private BasAreasService basAreasService;
    @Autowired
    private SnowflakeIdWorker snowflakeIdWorker;
    /**
     * @author Ryan
@@ -50,15 +50,16 @@
                for (int b = param.getStartBay(); b <= param.getEndBay(); b++) {
                    for (int l = param.getStartLev(); l <= param.getEndLev(); l++) {
                        // 获取库位号
                        String locNo = String.format("CA") + String.format("%02d", r) + String.format("%03d", b) + String.format("%02d", l);
                        String locNo = areas.getAreaNo() + String.format("%02d", r) + String.format("%03d", b) + String.format("%02d", l);
                        Date now = new Date();
                        LocCache locMast = new LocCache();
                        // 手动生成ID
                        locMast.setId(snowflakeIdWorker.nextId());
                        locMast.setLocNo(locNo);
                        locMast.setLocSts("O");
                        locMast.setRow1(r); // 排
                        locMast.setBay1(b); // 列
                        locMast.setLev1(l); // 层
                        locMast.setId(null);
                        locMast.setLocType1(!Cools.isEmpty(param.getLocType1()) ? param.getLocType1() : 1);
                        locMast.setLocType2(param.getLocType2());
                        locMast.setLocType3(param.getLocType3());
@@ -78,12 +79,324 @@
                }
            }
            if (!this.insertBatch(list)) {
                throw new CoolException("添加失败!!");
            // SQL Server 批量插入获取生成键可能失败,改用循环单条插入确保所有记录都能成功插入
            int successCount = 0;
            for (LocCache locCache : list) {
                if (this.insert(locCache)) {
                    successCount++;
                } else {
                    log.error("插入库位失败: {}", locCache.getLocNo());
                }
            }
            return R.ok("初始化成功");
            if (successCount != list.size()) {
                throw new CoolException(String.format("添加失败!成功插入 %d 条,应插入 %d 条", successCount, list.size()));
            }
            return R.ok("初始化成功,共插入 " + successCount + " 条记录");
        } catch (Exception e) {
            log.error("初始化库位失败", e);
            return R.error("初始化失败===>" + e.getMessage());
        }
    }
    /**
     * 锁定/解锁缓存库位(复用AGV搬货后的库位有货逻辑)
     * 锁定:满托设置为 "F"(在库),空托设置为 "D"(空桶/空栈板)
     * 解锁:统一设置为 "O"(空库位)
     * @param locNo 库位号
     * @param lock 是否锁定,true-锁定,false-解锁
     * @param fullPlt 是否满托,true-满托(设置为F),false-空托(设置为D),解锁时忽略此参数
     * @param userId 用户ID
     * @return 操作结果
     */
    @Override
    public R lockOrUnlockLocCache(String locNo, Boolean lock, Boolean fullPlt, Long userId) {
        try {
            if (Cools.isEmpty(locNo)) {
                return R.error("库位号不能为空");
            }
            // 根据库位号查询库位
            EntityWrapper<LocCache> wrapper = new EntityWrapper<>();
            wrapper.eq("loc_no", locNo);
            LocCache locCache = this.selectOne(wrapper);
            if (Cools.isEmpty(locCache)) {
                return R.error("库位不存在:" + locNo);
            }
            // 更新库位状态
            String locSts;
            if (lock) {
                // 锁定:满托设置为"F"(在库),空托设置为"D"(空桶/空栈板)
                if (fullPlt == null) {
                    return R.error("锁定操作时,满托参数不能为空");
                }
                locSts = fullPlt ? "F" : "D";
                locCache.setFullPlt(fullPlt ? "Y" : "N");
            } else {
                // 解锁:统一设置为"O"(空库位)
                locSts = "O";
                locCache.setFullPlt("N");
            }
            locCache.setLocSts(locSts);
            locCache.setModiUser(userId);
            locCache.setModiTime(new Date());
            boolean success = this.updateById(locCache);
            if (success) {
                String action = lock ? "锁定" : "解锁";
                String detail = lock ? (fullPlt ? "满托" : "空托") : "";
                log.info("{}库位成功:{},库位状态:{},{},操作人:{}", action, locNo, locCache.getLocSts(), detail, userId);
                return R.ok(action + "成功");
            } else {
                return R.error("操作失败");
            }
        } catch (Exception e) {
            log.error("锁定/解锁库位失败", e);
            return R.error("操作失败:" + e.getMessage());
        }
    }
    /**
     * 锁定/解锁当前排的所有库位
     * @param locNo 库位号(用于获取排号)
     * @param lock 是否锁定,true-锁定,false-解锁
     * @param userId 用户ID
     * @return 操作结果
     */
    @Override
    public R lockOrUnlockRowLocCache(String locNo, Boolean lock, Boolean fullPlt, Long userId) {
        try {
            if (Cools.isEmpty(locNo)) {
                return R.error("库位号不能为空");
            }
            // 根据库位号查询库位,获取排号
            EntityWrapper<LocCache> wrapper = new EntityWrapper<>();
            wrapper.eq("loc_no", locNo);
            LocCache locCache = this.selectOne(wrapper);
            if (Cools.isEmpty(locCache)) {
                return R.error("库位不存在:" + locNo);
            }
            Integer row = locCache.getRow1();
            if (Cools.isEmpty(row)) {
                return R.error("库位排号为空:" + locNo);
            }
            // 查询当前排的1、2、3列的所有库位(解锁整排时只清空1、2、3列)
            EntityWrapper<LocCache> rowWrapper = new EntityWrapper<>();
            rowWrapper.eq("row1", row)
                    .in("bay1", Arrays.asList(1, 2, 3)); // 只查询1、2、3列
            // 如果库位有库区ID,也加上库区条件
            if (!Cools.isEmpty(locCache.getAreaId())) {
                rowWrapper.eq("area_id", locCache.getAreaId());
            }
            List<LocCache> locCacheList = this.selectList(rowWrapper);
            if (Cools.isEmpty(locCacheList)) {
                return R.error("当前排没有找到库位");
            }
            // 批量更新库位状态
            Date now = new Date();
            int successCount = 0;
            String locSts;
            if (lock) {
                // 锁定:满托设置为"F"(在库),空托设置为"D"(空桶/空栈板)
                if (fullPlt == null) {
                    return R.error("锁定操作时,满托参数不能为空");
                }
                locSts = fullPlt ? "F" : "D";
            } else {
                // 解锁:统一设置为"O"(空库位)
                locSts = "O";
            }
            for (LocCache cache : locCacheList) {
                cache.setLocSts(locSts);
                if (lock) {
                    cache.setFullPlt(fullPlt ? "Y" : "N");
                } else {
                    cache.setFullPlt("N");
                }
                cache.setModiUser(userId);
                cache.setModiTime(now);
                if (this.updateById(cache)) {
                    successCount++;
                }
            }
            String action = lock ? "锁定" : "解锁";
            log.info("{}排{}所有库位成功,共{}个库位,操作人:{}", action, row, successCount, userId);
            return R.ok(String.format("%s成功,共处理 %d 个库位", action, successCount));
        } catch (Exception e) {
            log.error("锁定/解锁排库位失败", e);
            return R.error("操作失败:" + e.getMessage());
        }
    }
    /**
     * 锁定/解锁当前列的所有库位
     * @param locNo 库位号(用于获取列号bay1)
     * @param lock 是否锁定,true-锁定,false-解锁
     * @param fullPlt 是否满托,true-满托(设置为F),false-空托(设置为D),解锁时忽略此参数
     * @param userId 用户ID
     * @return 操作结果
     */
    @Override
    public R lockOrUnlockBayLocCache(String locNo, Boolean lock, Boolean fullPlt, Long userId) {
        try {
            if (Cools.isEmpty(locNo)) {
                return R.error("库位号不能为空");
            }
            // 根据库位号查询库位,获取列号
            EntityWrapper<LocCache> wrapper = new EntityWrapper<>();
            wrapper.eq("loc_no", locNo);
            LocCache locCache = this.selectOne(wrapper);
            if (Cools.isEmpty(locCache)) {
                return R.error("库位不存在:" + locNo);
            }
            Integer bay = locCache.getBay1();
            if (Cools.isEmpty(bay)) {
                return R.error("库位列号为空:" + locNo);
            }
            // 查询当前列的所有库位
            EntityWrapper<LocCache> bayWrapper = new EntityWrapper<>();
            bayWrapper.eq("bay1", bay);
            // 如果库位有库区ID,也加上库区条件
            if (!Cools.isEmpty(locCache.getAreaId())) {
                bayWrapper.eq("area_id", locCache.getAreaId());
            }
            List<LocCache> locCacheList = this.selectList(bayWrapper);
            if (Cools.isEmpty(locCacheList)) {
                return R.error("当前列没有找到库位");
            }
            // 批量更新库位状态
            Date now = new Date();
            int successCount = 0;
            String locSts;
            if (lock) {
                // 锁定:满托设置为"F"(在库),空托设置为"D"(空桶/空栈板)
                if (fullPlt == null) {
                    return R.error("锁定操作时,满托参数不能为空");
                }
                locSts = fullPlt ? "F" : "D";
            } else {
                // 解锁:统一设置为"O"(空库位)
                locSts = "O";
            }
            for (LocCache cache : locCacheList) {
                cache.setLocSts(locSts);
                if (lock) {
                    cache.setFullPlt(fullPlt ? "Y" : "N");
                } else {
                    cache.setFullPlt("N");
                }
                cache.setModiUser(userId);
                cache.setModiTime(now);
                if (this.updateById(cache)) {
                    successCount++;
                }
            }
            String action = lock ? "锁定" : "解锁";
            log.info("{}列{}所有库位成功,共{}个库位,操作人:{}", action, bay, successCount, userId);
            return R.ok(String.format("%s成功,共处理 %d 个库位", action, successCount));
        } catch (Exception e) {
            log.error("锁定/解锁列库位失败", e);
            return R.error("操作失败:" + e.getMessage());
        }
    }
    /**
     * 清空整排的所有库位(所有列)
     * @param locNo 库位号(用于获取排号row1)
     * @param lock 是否锁定,true-锁定,false-解锁(清空)
     * @param fullPlt 是否满托,true-满托(设置为F),false-空托(设置为D),解锁时忽略此参数
     * @param userId 用户ID
     * @return 操作结果
     */
    @Override
    public R clearAllColumnsInRow(String locNo, Boolean lock, Boolean fullPlt, Long userId) {
        try {
            if (Cools.isEmpty(locNo)) {
                return R.error("库位号不能为空");
            }
            // 根据库位号查询库位,获取排号
            EntityWrapper<LocCache> wrapper = new EntityWrapper<>();
            wrapper.eq("loc_no", locNo);
            LocCache locCache = this.selectOne(wrapper);
            if (Cools.isEmpty(locCache)) {
                return R.error("库位不存在:" + locNo);
            }
            Integer row = locCache.getRow1();
            if (Cools.isEmpty(row)) {
                return R.error("库位排号为空:" + locNo);
            }
            // 查询当前排的所有库位(所有列,不限制bay1)
            EntityWrapper<LocCache> rowWrapper = new EntityWrapper<>();
            rowWrapper.eq("row1", row);
            // 如果库位有库区ID,也加上库区条件
            if (!Cools.isEmpty(locCache.getAreaId())) {
                rowWrapper.eq("area_id", locCache.getAreaId());
            }
            List<LocCache> locCacheList = this.selectList(rowWrapper);
            if (Cools.isEmpty(locCacheList)) {
                return R.error("当前排没有找到库位");
            }
            // 批量更新库位状态
            Date now = new Date();
            int successCount = 0;
            String locSts;
            if (lock) {
                // 锁定:满托设置为"F"(在库),空托设置为"D"(空桶/空栈板)
                if (fullPlt == null) {
                    return R.error("锁定操作时,满托参数不能为空");
                }
                locSts = fullPlt ? "F" : "D";
            } else {
                // 解锁:统一设置为"O"(空库位)
                locSts = "O";
            }
            for (LocCache cache : locCacheList) {
                cache.setLocSts(locSts);
                if (lock) {
                    cache.setFullPlt(fullPlt ? "Y" : "N");
                } else {
                    cache.setFullPlt("N");
                }
                cache.setModiUser(userId);
                cache.setModiTime(now);
                if (this.updateById(cache)) {
                    successCount++;
                }
            }
            String action = lock ? "锁定" : "清空";
            log.info("{}排{}所有库位(所有列)成功,共{}个库位,操作人:{}", action, row, successCount, userId);
            return R.ok(String.format("%s成功,共处理 %d 个库位", action, successCount));
        } catch (Exception e) {
            log.error("清空整排库位失败", e);
            return R.error("操作失败:" + e.getMessage());
        }
    }
}