From c97c04770c17c36c554963bf8bb8d8fafc6a8d43 Mon Sep 17 00:00:00 2001
From: Junjie <fallin.jie@qq.com>
Date: 星期四, 07 五月 2026 09:43:35 +0800
Subject: [PATCH] #地图更新刷新缓存
---
src/main/java/com/zy/asrs/service/impl/BasMapServiceImpl.java | 318 +++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 310 insertions(+), 8 deletions(-)
diff --git a/src/main/java/com/zy/asrs/service/impl/BasMapServiceImpl.java b/src/main/java/com/zy/asrs/service/impl/BasMapServiceImpl.java
index b325718..7f3cb64 100644
--- a/src/main/java/com/zy/asrs/service/impl/BasMapServiceImpl.java
+++ b/src/main/java/com/zy/asrs/service/impl/BasMapServiceImpl.java
@@ -1,18 +1,52 @@
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.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
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.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;
@Service("basMapService")
public class BasMapServiceImpl extends ServiceImpl<BasMapMapper, BasMap> implements BasMapService {
+
+ @Autowired
+ private LocMastService locMastService;
+ @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) {
@@ -21,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
@@ -29,4 +65,270 @@
return this.baseMapper.selectList(new QueryWrapper<>()).stream().map(BasMap::getLev).collect(Collectors.toList());
}
+ @Override
+ public IPage<BasMap> pageLight(Page<BasMap> page, QueryWrapper<BasMap> wrapper) {
+ QueryWrapper<BasMap> queryWrapper = wrapper == null ? new QueryWrapper<>() : wrapper;
+ queryWrapper.select("id", "create_time", "update_time", "lev", "base_row", "base_row_code", "base_bay", "base_bay_code");
+ return this.baseMapper.selectPage(page, queryWrapper);
+ }
+
+ @Override
+ public BasMap selectPayloadById(Integer id) {
+ return this.baseMapper.selectPayloadById(id);
+ }
+
+ @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("鍦板浘杩愯缂撳瓨鍒锋柊澶辫触锛宭ev={}", lev, e);
+ throw e;
+ }
+ }
+
+ @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 + "灞傚簱浣峫ocType鍚屾澶辫触锛�" + 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;
+ }
+ }
}
--
Gitblit v1.9.1