Junjie
12 小时以前 77580a84dc16fd19cd7afa4f61c59689de820065
src/main/java/com/zy/asrs/service/impl/BasMapServiceImpl.java
@@ -1,18 +1,38 @@
package com.zy.asrs.service.impl;
import com.zy.asrs.mapper.BasMapMapper;
import com.zy.asrs.entity.BasMap;
import com.zy.asrs.service.BasMapService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import java.util.List;
import java.util.stream.Collectors;
import com.core.common.Cools;
import com.core.exception.CoolException;
import com.zy.asrs.entity.BasMap;
import com.zy.asrs.entity.LocMast;
import com.zy.asrs.mapper.BasMapMapper;
import com.zy.asrs.service.BasMapService;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.utils.Utils;
import com.zy.common.utils.RedisUtil;
import com.zy.core.enums.RedisKeyType;
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.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@Service("basMapService")
public class BasMapServiceImpl extends ServiceImpl<BasMapMapper, BasMap> implements BasMapService {
    @Autowired
    private LocMastService locMastService;
    @Autowired
    private RedisUtil redisUtil;
    @Override
    public BasMap selectLatestMap(Integer lev) {
@@ -29,4 +49,155 @@
        return this.baseMapper.selectList(new QueryWrapper<>()).stream().map(BasMap::getLev).collect(Collectors.toList());
    }
    @Override
    @Transactional
    public int syncLocMastByMap(Integer lev) {
        if (lev == null || lev <= 0) {
            throw new CoolException("请输入有效楼层");
        }
        List<Integer> locLevList = new ArrayList<>(locMastService.getLevList());
        if (Cools.isEmpty(locLevList) || !locLevList.contains(lev)) {
            throw new CoolException("第" + lev + "层暂无库位数据,请先初始化库位");
        }
        List<BasMap> basMapList = this.list(new QueryWrapper<BasMap>().orderByAsc("lev"));
        if (Cools.isEmpty(basMapList)) {
            throw new CoolException("请先初始化地图");
        }
        Map<Integer, BasMap> basMapByLev = new LinkedHashMap<>();
        for (BasMap basMap : basMapList) {
            if (basMap != null && basMap.getLev() != null) {
                basMapByLev.put(basMap.getLev(), basMap);
            }
        }
        BasMap fallbackMap = basMapByLev.size() == 1 ? basMapList.get(0) : null;
        BasMap basMap = basMapByLev.get(lev);
        if (basMap == null) {
            basMap = fallbackMap;
        }
        if (basMap == null) {
            throw new CoolException("第" + lev + "层缺少地图,无法同步locType");
        }
        List<TargetLocMeta> targetList = buildTargetLocMeta(basMap, lev);
        List<LocMast> currentList = new ArrayList<>(locMastService.selectLocByLev(lev));
        if (targetList.size() != currentList.size()) {
            throw new CoolException("第" + lev + "层地图货架数(" + targetList.size() + ")与现有库位数(" + currentList.size() + ")不一致,无法同步locType");
        }
        int updatedCount = syncLevelLocType(lev, currentList, targetList);
        refreshLocMastMapListCache();
        redisUtil.del(RedisKeyType.LOC_MAP_BASE.key);
        return updatedCount;
    }
    private int syncLevelLocType(Integer lev, List<LocMast> currentList, List<TargetLocMeta> targetList) {
        Map<String, TargetLocMeta> targetByLocNo = new LinkedHashMap<>();
        for (TargetLocMeta target : targetList) {
            if (targetByLocNo.put(target.locNo, target) != null) {
                throw new CoolException("第" + lev + "层存在重复库位号:" + target.locNo);
            }
        }
        Date now = new Date();
        int updatedCount = 0;
        for (LocMast current : currentList) {
            TargetLocMeta target = targetByLocNo.get(current.getLocNo());
            if (target == null) {
                throw new CoolException("第" + lev + "层地图中未找到库位号:" + current.getLocNo());
            }
            if (java.util.Objects.equals(current.getLocType(), target.locType)) {
                continue;
            }
            UpdateWrapper<LocMast> updateWrapper = new UpdateWrapper<>();
            updateWrapper.eq("loc_no", current.getLocNo())
                    .set("loc_type", target.locType)
                    .set("modi_time", now);
            if (!locMastService.update(null, updateWrapper)) {
                throw new CoolException("第" + lev + "层库位locType同步失败:" + current.getLocNo());
            }
            updatedCount++;
        }
        return updatedCount;
    }
    private void refreshLocMastMapListCache() {
        List<LocMast> locMastList = locMastService.list(new QueryWrapper<LocMast>().eq("lev1", 1));
        redisUtil.set(RedisKeyType.LOC_MAST_MAP_LIST.key, JSON.toJSONString(locMastList), 60 * 60 * 24);
    }
    private List<TargetLocMeta> buildTargetLocMeta(BasMap basMap, Integer targetLev) {
        if (basMap == null || Cools.isEmpty(basMap.getData())) {
            throw new CoolException("第" + targetLev + "层地图数据为空,无法同步locType");
        }
        List<List<JSONObject>> dataList;
        try {
            dataList = JSON.parseObject(basMap.getData(), List.class);
        } catch (Exception e) {
            throw new CoolException("第" + targetLev + "层地图数据格式错误,无法同步locType");
        }
        if (Cools.isEmpty(dataList)) {
            throw new CoolException("第" + targetLev + "层地图数据为空,无法同步locType");
        }
        List<TargetLocMeta> targetList = new ArrayList<>();
        int initRow = 1;
        for (int mapX = 0; mapX < dataList.size(); mapX++) {
            List<JSONObject> row = dataList.get(mapX);
            if (row == null) {
                continue;
            }
            int initBay = -1;
            for (int mapY = 0; mapY < row.size(); mapY++) {
                JSONObject cell = row.get(mapY);
                if (cell == null || !"shelf".equals(cell.getString("type"))) {
                    continue;
                }
                if (initBay == -1) {
                    initBay = 2;
                }
                String value = cell.getString("value");
                int userConfigRow = -1;
                int userConfigBay = -1;
                try {
                    String[] split = value.split("-");
                    userConfigRow = Integer.parseInt(split[0]);
                    userConfigBay = Integer.parseInt(split[1]);
                } catch (Exception ignored) {
                }
                if (userConfigBay != -1) {
                    initRow = userConfigRow;
                    initBay = userConfigBay;
                }
                targetList.add(new TargetLocMeta(
                        Utils.getLocNo(initRow, initBay, targetLev),
                        Utils.getLocNo(mapX, mapY, targetLev)
                ));
                initBay++;
            }
            if (initBay != -1) {
                initRow++;
            }
        }
        return targetList;
    }
    private static final class TargetLocMeta {
        private final String locNo;
        private final String locType;
        private TargetLocMeta(String locNo, String locType) {
            this.locNo = locNo;
            this.locType = locType;
        }
    }
}