feat(system): 新增线库和库区相关功能并优化机器人状态获取

- 新增线库(巷道)和库区的保存、修改和删除功能
- 实现线库和库区名称的唯一性校验
- 优化机器人状态信息获取逻辑
-修复公告板服务中的潜在空指针异常
This commit is contained in:
aikai 2025-03-20 17:17:46 +08:00
parent 268deceb22
commit f6d9e2749a
11 changed files with 57 additions and 21 deletions

View File

@ -170,9 +170,11 @@ public interface ErrorCodeConstants {
// ========== 线库/巷道 1-002-030-000 ==========
ErrorCode HOUSE_LANE_NOT_EXISTS = new ErrorCode(1-002-030-001, "线库不存在");
ErrorCode DUPLICATE_LINE_LIBRARY_NAME = new ErrorCode(1-002-030-002, "线库名称重复");
// ========== 库区 1-002-031-000 ==========
ErrorCode HOUSE_AREA_NOT_EXISTS = new ErrorCode(1-002-031-001, "库区不存在");
ErrorCode DUPLICATE_RESERVOIR_NAME = new ErrorCode(1-002-031-002, "库区名称重复");
// ========== 库位 1-002-032-000 ==========
ErrorCode HOUSE_LOCATION_NOT_EXISTS = new ErrorCode(1-002-032-001, "库位不存在");

View File

@ -3,6 +3,7 @@ package cn.iocoder.yudao.module.system.controller.admin.housearea.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import javax.validation.constraints.NotNull;
import java.util.List;
@Schema(description = "管理后台 - 库区新增/修改 Request VO")
@ -15,10 +16,11 @@ public class HouseAreaSaveReqVO {
@Schema(description = "地图id", example = "芋艿")
private Long positionMapId;
@Schema(description = "地图id", example = "芋艿")
@Schema(description = "物料说明", example = "芋艿")
private String skuInfo;
@Schema(description = "库区名称", example = "李四")
@NotNull(message = "库区名称不能为空")
private String areaName;
@Schema(description = "库区说明")

View File

@ -20,12 +20,12 @@ public class WareHouseLaneRespVO {
@ExcelProperty("地图id")
private Long positionMapId;
@Schema(description = "巷道名称", example = "芋艿")
@ExcelProperty("巷道名称")
@Schema(description = "线库名称", example = "芋艿")
@ExcelProperty("线库名称")
private String laneName;
@Schema(description = "巷道说明(可以拓展为区域说明)")
@ExcelProperty("巷道说明(可以拓展为区域说明)")
@Schema(description = "线库说明(可以拓展为区域说明)")
@ExcelProperty("线库说明(可以拓展为区域说明)")
private String laneMsg;
@Schema(description = "创建时间", requiredMode = Schema.RequiredMode.REQUIRED)

View File

@ -15,7 +15,11 @@ public class WareHouseLaneSaveReqVO {
@Schema(description = "地图id", example = "芋艿")
private Long positionMapId;
@Schema(description = "物料说明", example = "芋艿")
private String skuInfo;
@Schema(description = "线库名称", example = "芋艿")
@NotNull(message = "线库名称不能为空")
private String laneName;
@Schema(description = "线库说明(可以拓展为说明)")

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.dal.dataobject.houselane;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
import java.util.List;
@ -31,14 +32,19 @@ public class WareHouseLaneDO extends BaseDO {
*/
private Long positionMapId;
/**
* 巷道名称
* 线库名称
*/
private String laneName;
/**
* 巷道说明(可以拓展为区域说明)
* 线库说明(可以拓展为区域说明)
*/
private String laneMsg;
/**
* 物料信息
*/
private String skuInfo;
/**
* 节点ids
*/

View File

@ -1,10 +1,8 @@
package cn.iocoder.yudao.module.system.dal.mysql.housearea;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.controller.admin.housearea.vo.HouseAreaPageReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.housearea.HouseAreaDO;
import org.apache.ibatis.annotations.Mapper;
@ -19,6 +17,7 @@ public interface HouseAreaMapper extends BaseMapperX<HouseAreaDO> {
default PageResult<HouseAreaDO> selectPage(HouseAreaPageReqVO reqVO) {
return selectPage(reqVO, new LambdaQueryWrapperX<HouseAreaDO>()
.eqIfPresent(HouseAreaDO::getPositionMapId, reqVO.getPositionMapId())
.likeIfPresent(HouseAreaDO::getAreaName, reqVO.getAreaName())
.eqIfPresent(HouseAreaDO::getAreaMsg, reqVO.getAreaMsg())
.betweenIfPresent(HouseAreaDO::getCreateTime, reqVO.getCreateTime())

View File

@ -1,6 +1,7 @@
package cn.iocoder.yudao.module.system.service.bulletinboard;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.json.JSONUtil;
@ -31,6 +32,7 @@ import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
@ -109,7 +111,10 @@ public class BulletinBoardServiceImpl implements BulletinBoardService {
List<RobotElectricityLevelVO> robotElectricityLevelVOS = new ArrayList<>();
List<RobotInformationDO> allRobot = robotInformationService.getAllRobot();
List<RobotInfoStatusVO> agvListStatusInfo = robotInformationService.getAGVListStatusInfo();
Map<String, RobotInfoStatusVO> map = agvListStatusInfo.stream().collect(Collectors.toMap(RobotInfoStatusVO::getMacAddress, Function.identity()));
Map<String, RobotInfoStatusVO> map = new HashMap<>();
if (CollUtil.isNotEmpty(agvListStatusInfo)){
map = agvListStatusInfo.stream().collect(Collectors.toMap(RobotInfoStatusVO::getMacAddress, Function.identity()));
}
for (RobotInformationDO robotInformationDO : allRobot) {
String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC + robotInformationDO.getMacAddress();
Object object = redisUtil.get(pose2dKey);

View File

@ -30,8 +30,7 @@ import java.util.List;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.HOUSE_AREA_NOT_EXISTS;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.THERE_ARE_ALREADY_STORAGE_LOCATIONS_IN_OTHER_STORAGE_AREAS;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
/**
* 库区 Service 实现类
@ -95,6 +94,15 @@ public class HouseAreaServiceImpl extends ServiceImpl<HouseAreaMapper, HouseArea
@Override
@Transactional(rollbackFor = Exception.class)
public void createOrEditOrDel(HouseAreaSaveReqVO createReqVO) {
// 判断名称唯一
Long count = houseAreaMapper.selectCount(
new LambdaQueryWrapper<HouseAreaDO>()
.eq(HouseAreaDO::getAreaName, createReqVO.getAreaName())
.ne(ObjectUtil.isNotNull(createReqVO.getId()), HouseAreaDO::getId, createReqVO.getId())
);
if (count > 0) {
throw exception(DUPLICATE_RESERVOIR_NAME);
}
HouseAreaDO houseArea = BeanUtil.copyProperties(createReqVO, HouseAreaDO.class);
houseAreaMapper.insertOrUpdate(houseArea);
// -- 先判定这些点位是否在同一区域内 - 如果不在则提示 哪些点位不在同一区域内

View File

@ -7,17 +7,16 @@ import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.common.enums.NodeTypeEnum;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.controller.admin.houselane.vo.WareHouseLanePageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.houselane.vo.WareHouseLaneSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.dto.PositionMapConditionDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.housearea.HouseAreaDO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselane.WareHouseLaneDO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapItemDO;
import cn.iocoder.yudao.module.system.dal.mysql.houselane.WareHouseLaneMapper;
import cn.iocoder.yudao.module.system.service.houselocation.HouseLocationService;
import cn.iocoder.yudao.module.system.service.positionmap.PositionMapItemService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -30,8 +29,7 @@ import java.util.List;
import java.util.stream.Collectors;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.THERE_ARE_ALREADY_STORAGE_LOCATIONS_IN_OTHER_LINE_WAREHOUSES;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.THE_LINE_LIBRARY_POINTS_ARE_NOT_LOCATED_IN_THE_SAME_AREA;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
/**
@ -70,6 +68,15 @@ public class WareHouseLaneServiceImpl extends ServiceImpl<WareHouseLaneMapper, W
@Override
@Transactional(rollbackFor = Exception.class)
public void createOrEditOrDel(WareHouseLaneSaveReqVO createReqVO) {
// 判断名称唯一
Long num = houseLaneMapper.selectCount(
new LambdaQueryWrapper<WareHouseLaneDO>()
.eq(WareHouseLaneDO::getLaneName, createReqVO.getLaneName())
.ne(ObjectUtil.isNotNull(createReqVO.getId()), WareHouseLaneDO::getId, createReqVO.getId())
);
if (num > 0) {
throw exception(DUPLICATE_LINE_LIBRARY_NAME);
}
WareHouseLaneDO houseLane = BeanUtil.copyProperties(createReqVO, WareHouseLaneDO.class);
houseLaneMapper.insertOrUpdate(houseLane);
// -- 先判定这些点位是否在同一区域内 - 如果不在则提示 哪些点位不在同一区域内

View File

@ -29,6 +29,7 @@ import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
@ -118,9 +119,10 @@ public class PositionMapServiceImpl extends ServiceImpl<PositionMapMapper, Posit
byte[] bytes = yamlFile.getBytes();
// Parse the YAML file
Yaml yaml = new Yaml();
Map<String, Object> data = yaml.load(new String(bytes));
Map<String, Object> data = yaml.load(new String(bytes,StandardCharsets.UTF_8));
Object floor = data.get("floor");
Object area = data.get("area");
// -- 根据楼和区域查询是否有存在地图信息 - 如果有存在则替换 - 并且通知所有该楼该区域的AGV
if (ObjUtil.isEmpty(floor) || ObjUtil.isEmpty(area)) {
throw exception(AGV_UPLOAD_INFORMATION_DOES_NOT_INCLUDE_FLOOR_OR_AREA_INFORMATION);

View File

@ -405,12 +405,13 @@ public class RobotInformationServiceImpl extends ServiceImpl<RobotInformationMap
public List<RobotInfoStatusVO> getAGVListStatusInfo() {
List<RobotInfoStatusVO> list = new ArrayList<>();
// -- 先从缓存中 获取AGV状态信息 - 如果没有的话 - 再从数据库中获取 - 并且缓存到redis中
List<RobotInformationDO> robotInformationDO = informationMapper.selectList();
if (robotInformationDO == null) {
List<RobotInformationDO> robotInformationDOS = informationMapper.selectList();
if (CollUtil.isEmpty(robotInformationDOS)) {
return list;
}
for (RobotInformationDO informationDO : robotInformationDO) {
for (RobotInformationDO informationDO : robotInformationDOS) {
RobotInfoStatusVO vo = new RobotInfoStatusVO();
vo.setMacAddress(informationDO.getMacAddress());
//0待命1任务中2锁定3离线4:充电中5:故障
String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC + informationDO.getMacAddress();
Object object = redisUtil.get(pose2dKey);