| | |
| | | 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; |
| | |
| | | @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); |
| | |
| | | |
| | | @Override |
| | | public boolean deleteByLev(Integer lev) { |
| | | return this.baseMapper.deleteByLev(lev); |
| | | boolean deleted = this.baseMapper.deleteByLev(lev); |
| | | refreshMapRuntimeCaches(Collections.singletonList(lev)); |
| | | return deleted; |
| | | } |
| | | |
| | | @Override |
| | |
| | | |
| | | @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("请输入有效楼层"); |