Junjie
15 小时以前 c97c04770c17c36c554963bf8bb8d8fafc6a8d43
src/main/java/com/zy/asrs/service/impl/BasMapServiceImpl.java
@@ -15,15 +15,19 @@
import com.zy.asrs.service.BasMapService;
import com.zy.asrs.service.LocMastService;
import com.zy.asrs.utils.Utils;
import com.zy.common.utils.NavigateSolution;
import com.zy.common.utils.RedisUtil;
import com.zy.core.News;
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.Collections;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
@@ -36,6 +40,14 @@
    @Autowired
    private RedisUtil redisUtil;
    // 地图拓扑变化后,这些可达性和站点选择结果都可能过期,必须整体失效。
    private static final String[] MAP_DERIVED_CACHE_PREFIXES = {
            RedisKeyType.STATION_REACHABLE_CACHE.key,
            RedisKeyType.PRECOMPUTE_IN_TASK_ROW_CACHE.key,
            RedisKeyType.IN_STATION_ROUTE_CACHE.key,
            RedisKeyType.OUT_STATION_ROUTE_CACHE.key
    };
    @Override
    public BasMap selectLatestMap(Integer lev) {
        return this.baseMapper.selectLatestMap(lev);
@@ -43,7 +55,9 @@
    @Override
    public boolean deleteByLev(Integer lev) {
        return this.baseMapper.deleteByLev(lev);
        boolean deleted = this.baseMapper.deleteByLev(lev);
        refreshMapRuntimeCaches(Collections.singletonList(lev));
        return deleted;
    }
    @Override
@@ -65,6 +79,109 @@
    @Override
    @Transactional
    public void saveMapPayloadInBatches(Integer lev, String data, String originData, Date updateTime) {
        if (lev == null || lev <= 0) {
            throw new CoolException("楼层不能为空");
        }
        Date now = updateTime == null ? new Date() : updateTime;
        BasMap basMap = this.getOne(new QueryWrapper<BasMap>().select("id", "data").eq("lev", lev));
        boolean existingMap = basMap != null;
        if (basMap == null) {
            basMap = insertLightMap(lev, now);
        }
        if (existingMap) {
            updateLastDataOnly(basMap.getId(), basMap.getData());
        }
        updateDataOnly(basMap.getId(), data, now);
        updateOriginDataOnly(basMap.getId(), originData);
    }
    private BasMap insertLightMap(Integer lev, Date now) {
        BasMap insertMap = new BasMap();
        insertMap.setLev(lev);
        insertMap.setCreateTime(now);
        insertMap.setUpdateTime(now);
        if (!this.save(insertMap)) {
            throw new CoolException("地图基础信息保存失败");
        }
        return insertMap;
    }
    private void updateLastDataOnly(Integer id, String lastData) {
        UpdateWrapper<BasMap> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id)
                .set("last_data", lastData);
        if (!this.update(updateWrapper)) {
            throw new CoolException("地图历史数据保存失败");
        }
    }
    private void updateDataOnly(Integer id, String data, Date updateTime) {
        UpdateWrapper<BasMap> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id)
                .set("data", data)
                .set("update_time", updateTime);
        if (!this.update(updateWrapper)) {
            throw new CoolException("地图运行数据保存失败");
        }
    }
    private void updateOriginDataOnly(Integer id, String originData) {
        UpdateWrapper<BasMap> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", id)
                .set("origin_data", originData);
        if (!this.update(updateWrapper)) {
            throw new CoolException("地图编辑数据保存失败");
        }
    }
    @Override
    public void refreshMapRuntimeCaches(List<Integer> levList) {
        redisUtil.del(RedisKeyType.LOC_MAP_BASE.key);
        redisUtil.del(RedisKeyType.LOC_MAST_MAP_LIST.key);
        clearMapDerivedRedisCaches();
        if (levList == null || levList.isEmpty()) {
            return;
        }
        LinkedHashSet<Integer> distinctLevSet = new LinkedHashSet<>(levList);
        for (Integer lev : distinctLevSet) {
            if (lev == null) {
                continue;
            }
            NavigateSolution.clearMapCache(lev);
            if (!hasMapLev(lev)) {
                continue;
            }
            refreshNavigateMapCache(lev);
        }
    }
    private void clearMapDerivedRedisCaches() {
        for (String keyPrefix : MAP_DERIVED_CACHE_PREFIXES) {
            redisUtil.deleteByPrefix(keyPrefix);
        }
    }
    private boolean hasMapLev(Integer lev) {
        if (lev == null) {
            return false;
        }
        return this.count(new QueryWrapper<BasMap>().eq("lev", lev)) > 0;
    }
    private void refreshNavigateMapCache(Integer lev) {
        try {
            NavigateSolution.refreshMapCache(lev);
        } catch (Exception e) {
            News.error("地图运行缓存刷新失败,lev={}", lev, e);
            throw e;
        }
    }
    @Override
    @Transactional
    public int syncLocMastByMap(Integer lev) {
        if (lev == null || lev <= 0) {
            throw new CoolException("请输入有效楼层");