Junjie
17 小时以前 77580a84dc16fd19cd7afa4f61c59689de820065
#增加同步地图坐标与库位绑定关系
5个文件已修改
246 ■■■■■ 已修改文件
src/main/java/com/zy/asrs/controller/BasMapController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/BasMapService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/service/impl/BasMapServiceImpl.java 185 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/static/js/basMap/basMap.js 44 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/webapp/views/basMap/basMap.html 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/zy/asrs/controller/BasMapController.java
@@ -165,6 +165,13 @@
        return R.ok().add(levList);
    }
    @PostMapping("/basMap/syncLocMast/auth")
    @ManagerAuth(memo = "同步库位号和实际坐标")
    public R syncLocMast(@RequestParam Integer lev) {
        int updatedCount = basMapService.syncLocMastByMap(lev);
        return R.ok("第" + lev + "层locType同步完成,更新" + updatedCount + "条库位数据");
    }
    @PostMapping("/basMap/crn/upload")
    public R uploadExcel(@RequestParam("file") MultipartFile file) {
        File tempFile = null;
src/main/java/com/zy/asrs/service/BasMapService.java
@@ -14,4 +14,6 @@
    List<Integer> getLevList();//获取所有楼层地图
    int syncLocMastByMap(Integer lev);//按地图同步指定楼层locType
}
src/main/java/com/zy/asrs/service/impl/BasMapServiceImpl.java
@@ -1,18 +1,38 @@
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) {
@@ -29,4 +49,155 @@
        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;
        }
    }
}
src/main/webapp/static/js/basMap/basMap.js
@@ -819,6 +819,7 @@
                    loading: false,
                    exporting: false,
                    importingMap: false,
                    syncingLocMast: false,
                    initializingLocMast: false,
                    tableData: [],
                    selection: [],
@@ -1230,6 +1231,49 @@
                        });
                    }).catch(function () {});
                },
                promptSyncLocMast: function () {
                    var self = this;
                    self.$prompt('请输入需要同步的楼层', '同步地图坐标', {
                        confirmButtonText: '下一步',
                        cancelButtonText: '取消',
                        inputPattern: /^\d+$/,
                        inputErrorMessage: '请输入数字层数'
                    }).then(function (payload) {
                        var lev = $.trim(payload && payload.value ? payload.value : '');
                        self.$confirm('将按当前地图重新同步第' + lev + '层地图坐标与库位绑定关系。是否继续?', '同步地图坐标', {
                            confirmButtonText: '继续同步',
                            cancelButtonText: '取消',
                            type: 'warning'
                        }).then(function () {
                            self.syncingLocMast = true;
                            $.ajax({
                                url: baseUrl + '/basMap/syncLocMast/auth',
                                method: 'POST',
                                headers: self.authHeaders(),
                                data: {
                                    lev: lev
                                },
                                success: function (res) {
                                    if (self.handleForbidden(res)) {
                                        return;
                                    }
                                    if (!res || res.code !== 200) {
                                        self.$message.error((res && res.msg) ? res.msg : '同步失败');
                                        return;
                                    }
                                    self.$message.success(res.msg || '同步成功');
                                    self.loadTable();
                                },
                                error: function () {
                                    self.$message.error('同步失败');
                                },
                                complete: function () {
                                    self.syncingLocMast = false;
                                }
                            });
                        }).catch(function () {});
                    }).catch(function () {});
                },
                submitDialog: function () {
                    var self = this;
                    if (!self.$refs.dialogForm) {
src/main/webapp/views/basMap/basMap.html
@@ -431,6 +431,14 @@
                            size="small"
                            plain
                            icon="el-icon-refresh"
                            :loading="syncingLocMast"
                            @click="promptSyncLocMast">
                            同步地图坐标
                        </el-button>
                        <el-button
                            size="small"
                            plain
                            icon="el-icon-refresh"
                            :loading="initializingLocMast"
                            @click="promptInitLocMast">
                            初始化库位