package com.zy.asrs.service.impl; 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 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 implements BasMapService { @Autowired private LocMastService locMastService; @Autowired private RedisUtil redisUtil; @Override public BasMap selectLatestMap(Integer lev) { return this.baseMapper.selectLatestMap(lev); } @Override public boolean deleteByLev(Integer lev) { return this.baseMapper.deleteByLev(lev); } @Override public List getLevList() { 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 locLevList = new ArrayList<>(locMastService.getLevList()); if (Cools.isEmpty(locLevList) || !locLevList.contains(lev)) { throw new CoolException("第" + lev + "层暂无库位数据,请先初始化库位"); } List basMapList = this.list(new QueryWrapper().orderByAsc("lev")); if (Cools.isEmpty(basMapList)) { throw new CoolException("请先初始化地图"); } Map 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 targetList = buildTargetLocMeta(basMap, lev); List 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 currentList, List targetList) { Map 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 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 locMastList = locMastService.list(new QueryWrapper().eq("lev1", 1)); redisUtil.set(RedisKeyType.LOC_MAST_MAP_LIST.key, JSON.toJSONString(locMastList), 60 * 60 * 24); } private List buildTargetLocMeta(BasMap basMap, Integer targetLev) { if (basMap == null || Cools.isEmpty(basMap.getData())) { throw new CoolException("第" + targetLev + "层地图数据为空,无法同步locType"); } List> 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 targetList = new ArrayList<>(); int initRow = 1; for (int mapX = 0; mapX < dataList.size(); mapX++) { List 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; } } }