Merge branch 'dev' into cbs

This commit is contained in:
cbs 2025-02-17 15:00:12 +08:00
commit bd3aadaffd
25 changed files with 377 additions and 24 deletions

View File

@ -213,6 +213,7 @@ public class CollectionUtils {
return builder.build();
}
/**
* 对比老新两个列表找出新增修改删除的数据
*
@ -253,6 +254,39 @@ public class CollectionUtils {
return asList(createList, updateList, deleteList);
}
public static <T> List<List<T>> compareLists(List<T> oldList, List<T> newList, BiPredicate<T, T> sameFunc) {
List<T> added = new ArrayList<>();
List<T> modified = new ArrayList<>();
List<T> removed = new ArrayList<>(oldList); // 初始化为旧列表后续动态移除匹配项
// 单次双重循环处理新增修改并动态计算删除列表
for (T newItem : newList) {
boolean isFound = false;
T matchedOldItem = null;
Iterator<T> it = removed.iterator(); // 指向待删除列表的迭代器
// 在待删除列表中查找匹配项
while (it.hasNext()) {
T oldItem = it.next();
if (sameFunc.test(oldItem, newItem)) {
isFound = true;
matchedOldItem = oldItem;
it.remove(); // 移除匹配的旧元素表示它未被删除
break;
}
}
if (!isFound) {
added.add(newItem); // 未找到匹配加入新增列表
} else if (!newItem.equals(matchedOldItem)) {
modified.add(newItem); // 找到匹配但内容不同加入修改列表
}
}
// 此时removed中剩余的元素即为需删除的项
return Arrays.asList(added, modified, removed);
}
public static boolean containsAny(Collection<?> source, Collection<?> candidates) {
return org.springframework.util.CollectionUtils.containsAny(source, candidates);
}

View File

@ -0,0 +1,32 @@
package cn.iocoder.yudao.module.system.controller.admin.bulletinboard;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.system.controller.admin.bulletinboard.vo.BulletinBoardVO;
import cn.iocoder.yudao.module.system.service.bulletinboard.BulletinBoardService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
@Tag(name = "管理后台 - 整体看板")
@RestController
@RequestMapping("/system/bulletinBoard")
public class BulletinBoardController {
@Resource
private BulletinBoardService bulletinBoardService;
@GetMapping({"/get"})
@Operation(summary = "获取整体看板信息")
@PermitAll
public CommonResult<BulletinBoardVO> get() {
BulletinBoardVO vo = bulletinBoardService.getBulletinBoard();
return success(vo);
}
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.system.controller.admin.bulletinboard.vo;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationStatisticsVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotWarnMsgDO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
import java.util.List;
@Data
@ToString(callSuper = true)
public class BulletinBoardVO {
@Schema(description = "任务状态")
private TaskStatusVO taskStatusVO;
@Schema(description = "正在执行任务")
private List<RobotTaskDO> underway;
@Schema(description = "待执行任务")
private List<RobotTaskDO> pendingExecution;
@Schema(description = "车辆状态")
private RobotInformationStatisticsVO statistics;
@Schema(description = "车辆异常信息")
private List<RobotWarnMsgDO> robotWarnMsgDOS;
}

View File

@ -0,0 +1,16 @@
package cn.iocoder.yudao.module.system.controller.admin.bulletinboard.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
@Data
@ToString(callSuper = true)
public class RobotElectricityLevelVO {
@Schema(description = "AGV编号")
private String robotNo;
@Schema(description = "状态")
private String status;
@Schema(description = "电量")
private String batSoc;
}

View File

@ -0,0 +1,23 @@
package cn.iocoder.yudao.module.system.controller.admin.bulletinboard.vo;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.ToString;
@Data
@ToString(callSuper = true)
public class TaskStatusVO {
@Schema(description = "待执行")
private Integer pendingExecutionNum;
@Schema(description = "正在进行")
private Integer underwayNum;
@Schema(description = "已完成")
private Integer completedNum;
@Schema(description = "已取消")
private Integer cancelledNum;
@Schema(description = "异常")
private Integer abnormalNum;
@Schema(description = "当日任务数")
private Integer tasksNumber;
}

View File

@ -25,6 +25,12 @@ public class NodeBaseDTO {
@Schema(description = "坐标y轴")
private String locationY;
@Schema(description = "实际坐标x轴")
private String actualLocationX;
@Schema(description = "实际坐标y轴")
private String actualLocationY;
@Schema(description = "类型 1.路径点位 2.库位点 3.充电桩 4.停车点 5.区域变更点 6.等待点 --- 后续补充", example = "1")
private Integer type;

View File

@ -28,6 +28,15 @@ public class PositionMapLinePageReqVO extends PageParam {
@Schema(description = "结束点id(点位子表id)", example = "15890")
private Long endPointId;
@Schema(description = "开始点位x轴", example = "15890")
private String startPointX;
@Schema(description = "开始点位y轴", example = "15890")
private String startPointY;
@Schema(description = "结束点位x轴", example = "15890")
private String endPointX;
@Schema(description = "结束点位y轴", example = "15890")
private String endPointY;
@Schema(description = "开始控制点x轴", example = "15890")
private String beginControlX;

View File

@ -29,6 +29,15 @@ public class PositionMapLineRespVO {
@ExcelProperty("结束点id(点位子表id)")
private Long endPointId;
@Schema(description = "开始点位x轴", example = "15890")
private String startPointX;
@Schema(description = "开始点位y轴", example = "15890")
private String startPointY;
@Schema(description = "结束点位x轴", example = "15890")
private String endPointX;
@Schema(description = "结束点位y轴", example = "15890")
private String endPointY;
@Schema(description = "开始控制点x轴", example = "15890")
@ExcelProperty("开始控制点x轴")
private String beginControlX;

View File

@ -25,6 +25,15 @@ public class PositionMapLineSaveReqVO {
@Schema(description = "结束点id(点位子表id)", example = "15890")
private Long endPointId;
@Schema(description = "开始点位x轴", example = "15890")
private String startPointX;
@Schema(description = "开始点位y轴", example = "15890")
private String startPointY;
@Schema(description = "结束点位x轴", example = "15890")
private String endPointX;
@Schema(description = "结束点位y轴", example = "15890")
private String endPointY;
@Schema(description = "开始控制点x轴", example = "15890")
private String beginControlX;

View File

@ -94,6 +94,14 @@ public class WareHouseLocationDO extends BaseDO {
* 库位坐标y轴
*/
private String locationY;
/**
* 实际坐标x轴
*/
private String actualLocationX;
/**
* 实际坐标y轴
*/
private String actualLocationY;
/**
* 宽度
*/

View File

@ -50,6 +50,14 @@ public class DeviceInformationDO extends BaseDO {
* 库位坐标y轴
*/
private String locationY;
/**
* 实际坐标x轴
*/
private String actualLocationX;
/**
* 实际坐标y轴
*/
private String actualLocationY;
/**
* 宽度
*/

View File

@ -45,6 +45,14 @@ public class ParkingSpotDO extends BaseDO {
* 库位坐标y轴
*/
private String locationY;
/**
* 实际坐标x轴
*/
private String actualLocationX;
/**
* 实际坐标y轴
*/
private String actualLocationY;
/**
* 宽度
*/

View File

@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.system.dal.dataobject.positionmap;
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import com.baomidou.mybatisplus.annotation.*;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.*;
/**
@ -45,6 +46,14 @@ public class PositionMapItemDO extends BaseDO {
* 坐标y轴
*/
private String locationY;
/**
* 实际坐标x轴
*/
private String actualLocationX;
/**
* 实际坐标y轴
*/
private String actualLocationY;
/**
* 类型 1.路径点位 2.库位点 3.充电桩 4.停车点 5.区域变更点 6.等待点 --- 后续补充
*/

View File

@ -42,6 +42,22 @@ public class PositionMapLineDO extends BaseDO {
* 结束点id(点位子表id)
*/
private Long endPointId;
/**
* 开始点位x轴
*/
private String startPointX;
/**
* 开始点位y轴
*/
private String startPointY;
/**
* 结束点位x轴
*/
private String endPointX;
/**
* 结束点位y轴
*/
private String endPointY;
/**
* 开始控制点x轴
*/

View File

@ -12,7 +12,8 @@ public enum RobotTaskDetailStatusEnum {
NEW(0),//未开始
DOING(1),//执行中
DONE(2),//已完成
CLOSE(3); //已取消
CLOSE(3), //已取消
ABNORMAL(4); //异常
/**
* 类型
*/

View File

@ -14,6 +14,7 @@ import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.PostConstruct;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@ -66,7 +67,7 @@ public class NodeProcessingContext {
strategy.processNodes(positionMapId, nodeBaseDTOS);
List<PositionMapItemDO> newList = BeanUtil.copyToList(nodeBaseDTOS, PositionMapItemDO.class);
List<List<PositionMapItemDO>> list = CollectionUtils.diffList(oldItemList, newList,
List<List<PositionMapItemDO>> list = CollectionUtils.compareLists(oldItemList, newList,
(oldVal, newVal) -> ObjectUtil.equal(oldVal.getId(), newVal.getId()));
positionMapItemService.batchSaveOrEditOrDel(positionMapId, list);
}

View File

@ -32,6 +32,8 @@ public class DeviceStrategyImpl implements NodeProcessingStrategy {
DeviceInformationDO deviceInformationDO = JSONUtil.toBean(item.getDataJson(), DeviceInformationDO.class);
deviceInformationDO.setLocationX(item.getLocationX());
deviceInformationDO.setLocationY(item.getLocationY());
deviceInformationDO.setActualLocationX(item.getActualLocationX());
deviceInformationDO.setActualLocationY(item.getActualLocationY());
deviceInformationDO.setPositionMapId(positionMapId);
deviceInformationDO.setPositionMapItemId(item.getId());

View File

@ -38,6 +38,8 @@ public class HouseLocationStrategyImpl implements NodeProcessingStrategy {
for (WareHouseLocationDO wareHouseLocationDO : wareHouseLocationDOS) {
wareHouseLocationDO.setLocationX(item.getLocationX());
wareHouseLocationDO.setLocationY(item.getLocationY());
wareHouseLocationDO.setActualLocationX(item.getActualLocationX());
wareHouseLocationDO.setActualLocationY(item.getActualLocationY());
if (wareHouseLocationDO.getId() == null) {
wareHouseLocationDO.setId(getId());
}

View File

@ -36,6 +36,8 @@ public class ParkingSpotStrategyImpl implements NodeProcessingStrategy {
}
parkingSpotDO.setLocationX(item.getLocationX());
parkingSpotDO.setLocationY(item.getLocationY());
parkingSpotDO.setActualLocationX(item.getLocationX());
parkingSpotDO.setActualLocationY(item.getLocationY());
parkingSpotDO.setPositionMapId(positionMapId);
parkingSpotDO.setPositionMapItemId(item.getId());

View File

@ -0,0 +1,18 @@
package cn.iocoder.yudao.module.system.service.bulletinboard;
import cn.iocoder.yudao.module.system.controller.admin.bulletinboard.vo.BulletinBoardVO;
/**
* 获取看板信息 Service 接口
*
* @author 陈宾顺
*/
public interface BulletinBoardService {
/**
* 获取看板信息
*
* @return
*/
BulletinBoardVO getBulletinBoard();
}

View File

@ -0,0 +1,114 @@
package cn.iocoder.yudao.module.system.service.bulletinboard;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.json.JSONUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.controller.admin.bulletinboard.vo.BulletinBoardVO;
import cn.iocoder.yudao.module.system.controller.admin.bulletinboard.vo.RobotElectricityLevelVO;
import cn.iocoder.yudao.module.system.controller.admin.bulletinboard.vo.TaskStatusVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationStatisticsVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotInformationDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotWarnMsgDO;
import cn.iocoder.yudao.module.system.enums.robot.RobotTaskDetailStatusEnum;
import cn.iocoder.yudao.module.system.service.robot.RobotInformationService;
import cn.iocoder.yudao.module.system.service.robot.RobotTaskService;
import cn.iocoder.yudao.module.system.service.robot.RobotWarnMsgService;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* 获取看板信息 Service 实现类
*
* @author 艾楷
*/
@Service
@Validated
public class BulletinBoardServiceImpl implements BulletinBoardService {
@Resource
private RobotTaskService taskService;
@Resource
private RobotWarnMsgService robotWarnMsgService;
@Resource
private RobotInformationService robotInformationService;
@Resource
private RedisUtil redisUtil;
@Override
public BulletinBoardVO getBulletinBoard() {
BulletinBoardVO vo = new BulletinBoardVO();
LocalDateTime now = LocalDateTime.now();
List<RobotTaskDO> list = taskService.list(new LambdaQueryWrapperX<RobotTaskDO>()
.ge(RobotTaskDO::getCreateTime, LocalDateTimeUtil.beginOfDay(now)));
Map<Integer, List<RobotTaskDO>> taskMap = list.stream().collect(Collectors.groupingBy(RobotTaskDO::getTaskStatus));
// 任务状态
TaskStatusVO taskStatusVO = new TaskStatusVO();
// 正在执行
List<RobotTaskDO> underway = taskMap.get(RobotTaskDetailStatusEnum.DOING.getType());
//根据时间降序
if (CollectionUtil.isNotEmpty(underway)) {
underway.sort((o1, o2) -> o2.getStartTime().compareTo(o1.getStartTime()));
}
// 待执行
List<RobotTaskDO> pendingExecution = taskMap.get(RobotTaskDetailStatusEnum.NEW.getType());
//根据时间降序
if (CollectionUtil.isNotEmpty(pendingExecution)) {
pendingExecution.sort((o1, o2) -> o2.getCreateTime().compareTo(o1.getCreateTime()));
}
// 已完成
List<RobotTaskDO> completed = taskMap.get(RobotTaskDetailStatusEnum.DONE.getType());
// 已取消
List<RobotTaskDO> cancelled = taskMap.get(RobotTaskDetailStatusEnum.CLOSE.getType());
taskStatusVO.setPendingExecutionNum(CollectionUtil.isEmpty(pendingExecution) ? 0 : pendingExecution.size());
taskStatusVO.setUnderwayNum(CollectionUtil.isEmpty(underway) ? 0 : underway.size());
taskStatusVO.setCompletedNum(CollectionUtil.isEmpty(completed) ? 0 : completed.size());
taskStatusVO.setCancelledNum(CollectionUtil.isEmpty(cancelled) ? 0 : cancelled.size());
int abnormalNum = CollectionUtil.isEmpty(taskMap.get(RobotTaskDetailStatusEnum.ABNORMAL.getType())) ? 0 : taskMap.get(RobotTaskDetailStatusEnum.ABNORMAL.getType()).size();
taskStatusVO.setAbnormalNum(abnormalNum);
taskStatusVO.setTasksNumber(list.size());
vo.setTaskStatusVO(taskStatusVO);
// 获取车辆异常信息
List<RobotWarnMsgDO> robotWarnMsgDOS = robotWarnMsgService.list(new LambdaQueryWrapperX<RobotWarnMsgDO>()
.ge(RobotWarnMsgDO::getCreateTime, LocalDateTimeUtil.beginOfDay(now)));
// 正在执行任务
vo.setUnderway(underway);
// 待执行任务
vo.setPendingExecution(pendingExecution);
// 车辆状态
RobotInformationStatisticsVO statisticsVO = robotInformationService.statisticsInformation();
vo.setStatistics(statisticsVO);
// 车辆异常信息
vo.setRobotWarnMsgDOS(robotWarnMsgDOS);
List<RobotElectricityLevelVO> robotElectricityLevelVOS = new ArrayList<>();
List<RobotInformationDO> allRobot = robotInformationService.getAllRobot();
for (RobotInformationDO robotInformationDO : allRobot) {
String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC + robotInformationDO.getMacAddress();
Object object = redisUtil.get(pose2dKey);
RobotStatusDataPoseDTO robotStatusDataPoseDTO = JSONUtil.toBean((String) object, RobotStatusDataPoseDTO.class);
if (robotStatusDataPoseDTO != null) {
RobotElectricityLevelVO robotElectricityLevelVO = new RobotElectricityLevelVO();
robotElectricityLevelVO.setRobotNo(robotInformationDO.getRobotNo());
robotElectricityLevelVO.setBatSoc(robotStatusDataPoseDTO.getBat_soc());
robotElectricityLevelVOS.add(robotElectricityLevelVO);
}
}
return null;
}
}

View File

@ -8,13 +8,14 @@ import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskPageReq
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskRespVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotTaskSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotTaskDO;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* 机器人任务主表 Service 接口
*
* @author 陈宾顺
*/
public interface RobotTaskService {
public interface RobotTaskService extends IService<RobotTaskDO> {
/**
* 创建机器人任务主表

View File

@ -2,7 +2,9 @@ package cn.iocoder.yudao.module.system.service.robot;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.*;
@ -19,24 +21,23 @@ import cn.iocoder.yudao.module.system.enums.robot.*;
import cn.iocoder.yudao.module.system.util.redis.RedisUtil;
import cn.iocoder.yudao.module.system.util.redis.RedissonUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import java.util.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception0;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
@ -49,7 +50,7 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;
@Slf4j
@Service
@Validated
public class RobotTaskServiceImpl implements RobotTaskService {
public class RobotTaskServiceImpl extends ServiceImpl<RobotTaskMapper,RobotTaskDO> implements RobotTaskService {
private final String RESULT = "SUCCESS";

View File

@ -7,13 +7,14 @@ import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotWarnMsgPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotWarnMsgSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotWarnMsgDO;
import com.baomidou.mybatisplus.extension.service.IService;
/**
* 机器人告警信息 Service 接口
*
* @author 陈宾顺
*/
public interface RobotWarnMsgService {
public interface RobotWarnMsgService extends IService<RobotWarnMsgDO> {
/**
* 创建机器人告警信息

View File

@ -1,18 +1,16 @@
package cn.iocoder.yudao.module.system.service.robot;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotWarnMsgPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotWarnMsgSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.robot.RobotWarnMsgDO;
import cn.iocoder.yudao.module.system.dal.mysql.robot.RobotWarnMsgMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;
import java.util.*;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import javax.annotation.Resource;
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.WARN_MSG_NOT_EXISTS;
@ -24,7 +22,7 @@ import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.WARN_MSG_N
*/
@Service
@Validated
public class RobotWarnMsgServiceImpl implements RobotWarnMsgService {
public class RobotWarnMsgServiceImpl extends ServiceImpl<RobotWarnMsgMapper, RobotWarnMsgDO> implements RobotWarnMsgService {
@Resource
private RobotWarnMsgMapper warnMsgMapper;