| | |
| | | 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) { |
| | |
| | | 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; |
| | | } |
| | | } |
| | | } |