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<BasMapMapper, BasMap> 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<Integer> 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<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;
|
}
|
}
|
}
|