This commit is contained in:
aikai 2025-02-17 14:55:42 +08:00
commit 5c736b266f
25 changed files with 826 additions and 63 deletions

View File

@ -0,0 +1,22 @@
package cn.iocoder.yudao.module.mqtt.api.path;
import cn.iocoder.yudao.module.mqtt.api.path.dto.RelatedPathNode;
import cn.iocoder.yudao.module.mqtt.enums.ApiConstants;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestParam;
import javax.validation.Valid;
@FeignClient(name = ApiConstants.NAME) // TODO 芋艿fallbackFactory =
@Tag(name = "MQTT 服务 - 参数配置")
public interface PathPlanningApi {
String PREFIX = ApiConstants.PREFIX + "/config";
@PostMapping(PREFIX + "/synchronousPoint")
@Operation(summary = "下发任务给车机")
void synchronousPointToPP( @RequestBody RelatedPathNode relatedPathNode, @RequestParam("topic") String topic);
}

View File

@ -0,0 +1,67 @@
package cn.iocoder.yudao.module.mqtt.api.path.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PositionMapLineDTO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "28062")
private Long id;
@Schema(description = "地图id", example = "20863")
private Long positionMapId;
@Schema(description = "出发点id(点位子表id)", example = "20863")
private Long startingPointId;
@Schema(description = "结束点id(点位子表id)", example = "15890")
private Long endPointId;
@Schema(description = "行走方法 0.直线 1.上左曲线2.上右曲线3.下左曲线 4.下右曲线")
private Integer method;
@Schema(description = "方向 1.单向 2.双向", example = "15890")
private Integer direction;
@Schema(description = "正向限速(m/s)", example = "15890")
private BigDecimal forwardSpeedLimit;
@Schema(description = "反向限速(m/s)", example = "15890")
private BigDecimal reverseSpeedLimit;
@Schema(description = "开始控制点x轴")
private String beginControlX;
@Schema(description = "开始控制点y轴")
private String beginControlY;
@Schema(description = "结束控制点x轴")
private String endControlX;
@Schema(description = "结束控制点y轴")
private String endControlY;
@Schema(description = "膨胀区域前")
private BigDecimal expansionZoneFront;
@Schema(description = "膨胀区域后")
private BigDecimal expansionZoneAfter;
@Schema(description = "膨胀区域左")
private BigDecimal expansionZoneLeft;
@Schema(description = "膨胀区域右")
private BigDecimal expansionZoneRight;
@Schema(description = "车头朝向( 0:正向 1:反向)", example = "15890")
private Integer toward;
}

View File

@ -0,0 +1,25 @@
package cn.iocoder.yudao.module.mqtt.api.path.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class RelatedPathNode {
@Schema(description = "楼层", example = "20863")
private Integer floor;
@Schema(description = "区域", example = "20863")
private String area;
@Schema(description = "点位状态(0:新增、1:删除、2更新)", example = "20863")
private Integer pointStatus = 0;
private List<PositionMapLineDTO> control_nodes;
}

View File

@ -20,5 +20,5 @@ public interface RobotTaskApi {
@PostMapping(PREFIX + "/distribute/tasks") @PostMapping(PREFIX + "/distribute/tasks")
@Operation(summary = "下发任务给车机") @Operation(summary = "下发任务给车机")
CommonResult<String> sendTaskToRobot(@Valid @RequestBody List<RobotAcceptTaskDTO> robotTaskDOS ); void sendTaskToRobot(@Valid @RequestBody List<RobotAcceptTaskDTO> robotTaskDOS );
} }

View File

@ -0,0 +1,30 @@
package cn.iododer.yudao.module.mqtt.api.path;
import cn.iocoder.yudao.module.mqtt.api.path.PathPlanningApi;
import cn.iocoder.yudao.module.mqtt.api.path.dto.RelatedPathNode;
import cn.iododer.yudao.module.mqtt.util.MqttUtils;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RestController;
@RestController // 提供 RESTful API 接口 Feign 调用
@Validated
@Slf4j
public class PathPlanningApiImpl implements PathPlanningApi {
@Autowired
private MqttUtils mqttUtils;
@Override
public void synchronousPointToPP(RelatedPathNode relatedPathNode, String topic) {
try {
mqttUtils.pub(topic, JSON.toJSONString(relatedPathNode));
log.info("同步给路径规划完成 :{}", topic);
} catch (MqttException e) {
log.info("同步点位信息给路径规划异常 :{}",e);
}
}
}

View File

@ -24,18 +24,14 @@ public class RobotTaskApiImpl implements RobotTaskApi {
private MqttUtils mqttUtils; private MqttUtils mqttUtils;
@Override @Override
public CommonResult<String> sendTaskToRobot(List<RobotAcceptTaskDTO> robotTaskDOS) { public void sendTaskToRobot(List<RobotAcceptTaskDTO> robotTaskDOS) {
String str ="SUCCESS";
for (RobotAcceptTaskDTO robotTaskDO : robotTaskDOS) { for (RobotAcceptTaskDTO robotTaskDO : robotTaskDOS) {
log.info("发送MQTT消息 :{}",JSON.toJSONString(robotTaskDO)); log.info("发送MQTT消息 :{}",JSON.toJSONString(robotTaskDO));
try { try {
mqttUtils.pub( robotTaskDO.getTopic(), JSON.toJSONString(robotTaskDO)); mqttUtils.pub( robotTaskDO.getTopic(), JSON.toJSONString(robotTaskDO));
} catch (Exception e) { } catch (Exception e) {
log.info("消息发送异常 :{}",e.getMessage()); log.info("消息发送异常 :{}",e.getMessage());
str ="FAIL";
} }
} }
return success(str);
} }
} }

View File

@ -229,4 +229,7 @@ public interface ErrorCodeConstants {
// ========== 车辆充电记录 1_002_043_001 ========== // ========== 车辆充电记录 1_002_043_001 ==========
ErrorCode CHARGE_LOG_NOT_EXISTS = new ErrorCode(1_002_043_001, "车辆充电记录不存在"); ErrorCode CHARGE_LOG_NOT_EXISTS = new ErrorCode(1_002_043_001, "车辆充电记录不存在");
// ========== 路径规划 1_002_044_001 ==========
ErrorCode PATH_PLANNING_NOT_EXISTS = new ErrorCode(1_002_044_001, "不存在需要同步给路径规划的数据");
} }

View File

@ -0,0 +1,29 @@
package cn.iocoder.yudao.module.system.constant.path;
/**
* 下发给PP的TOPIC
*/
public class PathPlanningTopicConstant {
/**
* 同步全部地图点位
*/
public static String SYNCHRONOUS_ALL_MAP_POINT = "SYNCHRONOUS_MAP_POINT";
/**
* 添加地图点位给PP
*/
public static String ADD_MAP_POINT = "ADD_MAP_POINT";
/**
* 删除地图点位
*/
public static String DELETE_MAP_POINT = "DELETE_MAP_POINT";
/**
* 更新地图点位
*/
public static String UPDATE_MAP_POINT = "UPDATE_MAP_POINT";
}

View File

@ -0,0 +1,11 @@
package cn.iocoder.yudao.module.system.constant.robot;
/**
* 下发给车机的TOPIC
*/
public class RobotTopicConstant {
/**
* 下发任务给车机的topic 拼接mac地址
*/
public static String ROBOT_TASK_TOPIC = "ROBOT_TASK_";
}

View File

@ -1,16 +1,14 @@
package cn.iocoder.yudao.module.system.controller.admin.path; package cn.iocoder.yudao.module.system.controller.admin.path;
import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapSaveReqVO;
import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationSaveReqVO; import cn.iocoder.yudao.module.system.controller.admin.robot.vo.RobotInformationSaveReqVO;
import cn.iocoder.yudao.module.system.service.path.PathPlanningService; import cn.iocoder.yudao.module.system.service.path.PathPlanningService;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated; import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.*;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.validation.Valid; import javax.validation.Valid;
@ -26,11 +24,11 @@ public class PathPlanningController {
@Resource @Resource
private PathPlanningService pathPlanningService; private PathPlanningService pathPlanningService;
@PutMapping("/synchronousPoint") @PostMapping("/synchronousPoint")
@Operation(summary = "同步全部的点位信息") @Operation(summary = "同步全部的点位信息")
@PreAuthorize("@ss.hasPermission('robot:information:synchronousPoint')") @PreAuthorize("@ss.hasPermission('robot:information:synchronousPoint')")
public CommonResult<String> synchronousPoint() { public CommonResult<String> synchronousPoint(@RequestBody PositionMapSaveReqVO positionMapSaveReqVO) {
pathPlanningService.synchronousPoint(); pathPlanningService.synchronousPoint(positionMapSaveReqVO);
return success("同步完成"); return success("同步完成");
} }

View File

@ -0,0 +1,64 @@
package cn.iocoder.yudao.module.system.controller.admin.positionmap.dto;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Data;
import java.math.BigDecimal;
import java.time.LocalDateTime;
@Data
@Builder
public class PositionMapLineDTO {
@Schema(description = "主键ID", requiredMode = Schema.RequiredMode.REQUIRED, example = "28062")
private Long id;
@Schema(description = "地图id", example = "20863")
private Long positionMapId;
@Schema(description = "出发点id(点位子表id)", example = "20863")
private Long startingPointId;
@Schema(description = "结束点id(点位子表id)", example = "15890")
private Long endPointId;
@Schema(description = "行走方法 0.直线 1.上左曲线2.上右曲线3.下左曲线 4.下右曲线")
private Integer method;
@Schema(description = "方向 1.单向 2.双向", example = "15890")
private Integer direction;
@Schema(description = "正向限速(m/s)", example = "15890")
private BigDecimal forwardSpeedLimit;
@Schema(description = "反向限速(m/s)", example = "15890")
private BigDecimal reverseSpeedLimit;
@Schema(description = "开始控制点x轴")
private String beginControlX;
@Schema(description = "开始控制点y轴")
private String beginControlY;
@Schema(description = "结束控制点x轴")
private String endControlX;
@Schema(description = "结束控制点y轴")
private String endControlY;
@Schema(description = "膨胀区域前")
private BigDecimal expansionZoneFront;
@Schema(description = "膨胀区域后")
private BigDecimal expansionZoneAfter;
@Schema(description = "膨胀区域左")
private BigDecimal expansionZoneLeft;
@Schema(description = "膨胀区域右")
private BigDecimal expansionZoneRight;
@Schema(description = "车头朝向( 0:正向 1:反向)")
private Integer toward;
}

View File

@ -77,4 +77,8 @@ public class PositionMapLinePageReqVO extends PageParam {
@DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND) @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
private LocalDateTime[] createTime; private LocalDateTime[] createTime;
@Schema(description = "车头朝向( 0:正向 1:反向)", example = "15890")
private Integer toward;
} }

View File

@ -90,4 +90,8 @@ public class PositionMapLineRespVO {
@ExcelProperty("创建时间") @ExcelProperty("创建时间")
private LocalDateTime createTime; private LocalDateTime createTime;
@Schema(description = "车头朝向( 0:正向 1:反向)", example = "15890")
@ExcelProperty("车头朝向( 0:正向 1:反向)")
private Integer toward;
} }

View File

@ -70,4 +70,8 @@ public class PositionMapLineSaveReqVO {
@Schema(description = "反向限速(m/s)", example = "15890") @Schema(description = "反向限速(m/s)", example = "15890")
private BigDecimal reverseSpeedLimit; private BigDecimal reverseSpeedLimit;
@Schema(description = "车头朝向( 0:正向 1:反向)", example = "15890")
private Integer toward;
} }

View File

@ -24,4 +24,7 @@ public class RobotInformationStatisticsVO {
@Schema(description = "故障") @Schema(description = "故障")
private Integer fault = 0; private Integer fault = 0;
@Schema(description = "总数")
private Integer total = 0;
} }

View File

@ -107,4 +107,8 @@ public class PositionMapLineDO extends BaseDO {
*/ */
private BigDecimal reverseSpeedLimit; private BigDecimal reverseSpeedLimit;
/**
* 车头朝向( 0:正向 1:反向)
*/
private Integer toward;
} }

View File

@ -3,10 +3,13 @@ package cn.iocoder.yudao.module.system.dal.mysql.positionmap;
import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX; import cn.iocoder.yudao.framework.mybatis.core.mapper.BaseMapperX;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX; import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.mqtt.api.path.dto.PositionMapLineDTO;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapLinePageReqVO; import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapLinePageReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapLineDO; import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapLineDO;
import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Mapper;
import java.util.List;
/** /**
* 仓库点位地图连线 Mapper * 仓库点位地图连线 Mapper
* *
@ -24,4 +27,9 @@ public interface PositionMapLineMapper extends BaseMapperX<PositionMapLineDO> {
.orderByDesc(PositionMapLineDO::getId)); .orderByDesc(PositionMapLineDO::getId));
} }
/**
* 查看所有的点位地图连线
* @return
*/
List<PositionMapLineDTO> getAllPositionMapLine(PositionMapLineDO positionMapLineDO);
} }

View File

@ -0,0 +1,21 @@
package cn.iocoder.yudao.module.system.enums.line;
import lombok.AllArgsConstructor;
import lombok.Getter;
/**
* ware_position_map_line表的direction
*/
@Getter
@AllArgsConstructor
public enum DirectionEnum {
ONE_WAY(1,"单向"),
TWO_WAY(2,"双向");
/**
* 类型
*/
private final Integer type;
private final String msg;
}

View File

@ -1,14 +0,0 @@
package cn.iocoder.yudao.module.system.enums.robot;
import lombok.AllArgsConstructor;
import lombok.Getter;
@Getter
@AllArgsConstructor
public enum RobotTopicEnum {
ROBOT_TASK("ROBOT_TASK_"); //下发指令给车机
/**
* 类型
*/
private final String topic;
}

View File

@ -1,10 +1,11 @@
package cn.iocoder.yudao.module.system.framework.mqtt; package cn.iocoder.yudao.module.system.framework.mqtt;
import cn.iocoder.yudao.module.mqtt.api.path.PathPlanningApi;
import cn.iocoder.yudao.module.mqtt.api.task.RobotTaskApi; import cn.iocoder.yudao.module.mqtt.api.task.RobotTaskApi;
import org.springframework.cloud.openfeign.EnableFeignClients; import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
@Configuration(proxyBeanMethods = false) @Configuration(proxyBeanMethods = false)
@EnableFeignClients(clients = {RobotTaskApi.class}) @EnableFeignClients(clients = {RobotTaskApi.class, PathPlanningApi.class})
public class MqttConfiguration { public class MqttConfiguration {
} }

View File

@ -1,5 +1,7 @@
package cn.iocoder.yudao.module.system.service.path; package cn.iocoder.yudao.module.system.service.path;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapSaveReqVO;
public interface PathPlanningService { public interface PathPlanningService {
void synchronousPoint(); void synchronousPoint(PositionMapSaveReqVO positionMapSaveReqVO);
} }

View File

@ -1,8 +1,30 @@
package cn.iocoder.yudao.module.system.service.path; package cn.iocoder.yudao.module.system.service.path;
import cn.hutool.core.util.ObjectUtil;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.module.mqtt.api.path.PathPlanningApi;
import cn.iocoder.yudao.module.mqtt.api.path.dto.PositionMapLineDTO;
import cn.iocoder.yudao.module.mqtt.api.path.dto.RelatedPathNode;
import cn.iocoder.yudao.module.system.constant.path.PathPlanningTopicConstant;
import cn.iocoder.yudao.module.system.controller.admin.positionmap.vo.PositionMapSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapDO;
import cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapLineDO;
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapLineMapper;
import cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapMapper;
import cn.iocoder.yudao.module.system.enums.line.DirectionEnum;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
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.PATH_PLANNING_NOT_EXISTS;
/** /**
* 同步信息给车辆 * 同步信息给车辆
@ -12,11 +34,120 @@ import org.springframework.validation.annotation.Validated;
public class PathPlanningServiceImpl implements PathPlanningService { public class PathPlanningServiceImpl implements PathPlanningService {
@Resource
private PositionMapLineMapper positionMapLineMapper;
@Resource
private PositionMapMapper positionMapMapper;
public static ExecutorService executor = Executors.newFixedThreadPool(5);
@Resource
private PathPlanningApi pathPlanningApi;
/** /**
* 同步全部的点位信息 * 同步全部的点位信息
*/ */
@Override @Override
public void synchronousPoint() { public void synchronousPoint(PositionMapSaveReqVO data) {
List<PositionMapDO> positionMapDOS = positionMapMapper.selectList(new LambdaQueryWrapperX<PositionMapDO>()
.eq(ObjectUtil.isNotEmpty(data.getFloor()), PositionMapDO::getFloor, data.getFloor())
.eq(ObjectUtil.isNotEmpty(data.getArea()), PositionMapDO::getArea, data.getArea()));
PositionMapLineDO positionMapLineDO = new PositionMapLineDO();
List<PositionMapLineDTO> positionLines = positionMapLineMapper.getAllPositionMapLine(positionMapLineDO);
// List<PositionMapLineDO> positionLines = positionMapLineMapper.selectList(new LambdaQueryWrapperX<PositionMapLineDO>());
if (ObjectUtil.isEmpty(positionMapDOS) || ObjectUtil.isEmpty(positionLines)) {
throw exception(PATH_PLANNING_NOT_EXISTS);
}
Map<Long, List<PositionMapLineDTO>> positionMapLineMap = positionLines.stream()
.collect(Collectors.groupingBy(PositionMapLineDTO::getPositionMapId));
for (PositionMapDO positionMapDO : positionMapDOS) {
RelatedPathNode relatedPathNode = new RelatedPathNode();
relatedPathNode.setFloor(positionMapDO.getFloor());
relatedPathNode.setArea(positionMapDO.getArea());
List<PositionMapLineDTO> positionMapLineDOS = positionMapLineMap.get(positionMapDO.getId());
if (ObjectUtil.isEmpty(positionMapLineDOS)) {
continue;
}
assembleDataToPP(relatedPathNode,positionMapLineDOS);
}
} }
/**
* 组装数据发送到PP
* @param relatedPathNode
* @param positionMapLineDOS
*/
private void assembleDataToPP(RelatedPathNode relatedPathNode, List<PositionMapLineDTO> positionMapLineDOS) {
executor.execute(() -> {
List<PositionMapLineDTO> list = new ArrayList<>();
for (PositionMapLineDTO positionMapLineDO : positionMapLineDOS) {
list.add(positionMapLineDO);
if (DirectionEnum.ONE_WAY.getType().equals(positionMapLineDO.getDirection())) {
continue;
}
PositionMapLineDTO build = PositionMapLineDTO.builder()
.id(positionMapLineDO.getId())
.positionMapId(positionMapLineDO.getPositionMapId())
.startingPointId(positionMapLineDO.getEndPointId())
.endPointId(positionMapLineDO.getStartingPointId())
.direction(1)
.forwardSpeedLimit(positionMapLineDO.getReverseSpeedLimit())
.reverseSpeedLimit(positionMapLineDO.getForwardSpeedLimit())
.beginControlX(positionMapLineDO.getEndControlX())
.beginControlY(positionMapLineDO.getEndControlY())
.endControlX(positionMapLineDO.getBeginControlX())
.endControlY(positionMapLineDO.getBeginControlY())
.expansionZoneFront(positionMapLineDO.getExpansionZoneAfter())
.expansionZoneAfter(positionMapLineDO.getExpansionZoneFront())
.expansionZoneLeft(positionMapLineDO.getExpansionZoneRight())
.expansionZoneRight(positionMapLineDO.getExpansionZoneLeft())
.toward(positionMapLineDO.getToward())
.build();
list.add(build);
}
relatedPathNode.setControl_nodes(list);
pathPlanningApi.synchronousPointToPP(relatedPathNode, PathPlanningTopicConstant.SYNCHRONOUS_ALL_MAP_POINT);
});
}
} }

View File

@ -181,7 +181,7 @@ public class RobotInformationServiceImpl implements RobotInformationService {
} }
if (RobotStatisticsTypeEnum.OFFLINE.getType().equals(pageReqVO.getRobotStatisticsType()) if (RobotStatisticsTypeEnum.OFFLINE.getType().equals(pageReqVO.getRobotStatisticsType())
&& v.getOnlineStatus().equals(1)) { && v.getOnlineStatus().equals(0)) {
resultList.add(v); resultList.add(v);
continue; continue;
} }
@ -216,8 +216,6 @@ public class RobotInformationServiceImpl implements RobotInformationService {
v.setElectricity(robotStatusDataPoseDTO.getBat_soc()); v.setElectricity(robotStatusDataPoseDTO.getBat_soc());
v.setFloor(robotStatusDataPoseDTO.getFloor()); v.setFloor(robotStatusDataPoseDTO.getFloor());
v.setArea(robotStatusDataPoseDTO.getArea()); v.setArea(robotStatusDataPoseDTO.getArea());
} else if (ObjectUtil.isEmpty(object)) {
//离线
v.setOnlineStatus(1); v.setOnlineStatus(1);
} }
@ -273,32 +271,35 @@ public class RobotInformationServiceImpl implements RobotInformationService {
Integer fault = 0; Integer fault = 0;
//0待命1任务中2锁定3离线4:充电中5:故障 //0待命1任务中2锁定3离线4:充电中5:故障
for (RobotInformationDO v : existRobot) { for (RobotInformationDO v : existRobot) {
String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC + v.getMacAddress(); String pose2dKey = RobotTaskChcheConstant.ROBOT_INFORMATION_POSE_BAT_SOC +v.getMacAddress();
Object object = redisUtil.get(pose2dKey); Object object = redisUtil.get(pose2dKey);
if (ObjectUtil.isEmpty(object)) { if (ObjectUtil.isEmpty(object)) {
//离线
offline++; offline++;
} else if (RobotTaskModelEnum.REJECTION.getType().equals(v.getRobotTaskModel())) { }
if (RobotTaskModelEnum.REJECTION.getType().equals(v.getRobotTaskModel())) {
//锁定
doLock++; doLock++;
} else if (RobotStatusEnum.STAND_BY.getType().equals(v.getRobotStatus())) { }
//设置异常
//查看机器人最后做的任务是不是充电 String errorLevelKey = RobotTaskChcheConstant.ROBOT_ERROR_LEVEL +v.getMacAddress();
RobotTaskDetailDO robotTaskDetailDO = taskDetailMapper.selectOne(new LambdaQueryWrapper<RobotTaskDetailDO>() Object errorLevel = redisUtil.get(errorLevelKey);
.eq(RobotTaskDetailDO::getRobotNo, v.getRobotNo()) if (ObjectUtil.isNotEmpty(errorLevel) && Integer.valueOf(errorLevel.toString()).intValue() >= 3) {
.orderByDesc(RobotTaskDetailDO::getCreateTime)
.last("limit 1"));
if (ObjectUtil.isNotEmpty(robotTaskDetailDO)
&& RobotTaskTypeEnum.CHARGE.getType().equals(robotTaskDetailDO.getTaskType())
&& RobotTaskStatusEnum.DOING.getType().equals(robotTaskDetailDO.getTaskStatus())) {
charge++;
} else {
standby++;
}
} else if (RobotStatusEnum.DOING.getType().equals(v.getRobotStatus())) {
inTask++;
} else {
fault++; fault++;
} }
if (RobotStatusEnum.STAND_BY.getType().equals(v.getRobotStatus())) {
//待命中
standby++;
}else if (RobotStatusEnum.CHARGE.getType().equals(v.getRobotStatus())) {
//充电中
charge++;
}else {
//任务中
inTask++;
}
} }
info.setStandby(standby); info.setStandby(standby);
info.setInTask(inTask); info.setInTask(inTask);
@ -306,6 +307,7 @@ public class RobotInformationServiceImpl implements RobotInformationService {
info.setOffline(offline); info.setOffline(offline);
info.setCharge(charge); info.setCharge(charge);
info.setFault(fault); info.setFault(fault);
info.setTotal(existRobot.size());
return info; return info;
} }

View File

@ -11,6 +11,7 @@ import cn.iocoder.yudao.module.mqtt.api.task.dto.RobotAcceptTaskData;
import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO; import cn.iocoder.yudao.module.system.api.robot.dto.RobotStatusDataPoseDTO;
import cn.iocoder.yudao.module.system.constant.robot.RobotStatusCodeConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotStatusCodeConstant;
import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant; import cn.iocoder.yudao.module.system.constant.robot.RobotTaskChcheConstant;
import cn.iocoder.yudao.module.system.constant.robot.RobotTopicConstant;
import cn.iocoder.yudao.module.system.controller.admin.config.vo.CommonConfigVO; import cn.iocoder.yudao.module.system.controller.admin.config.vo.CommonConfigVO;
import cn.iocoder.yudao.module.system.dal.dataobject.config.CommonConfigDO; import cn.iocoder.yudao.module.system.dal.dataobject.config.CommonConfigDO;
import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO; import cn.iocoder.yudao.module.system.dal.dataobject.houselocation.WareHouseLocationDO;
@ -405,7 +406,7 @@ public class DistributeTasksServiceImpl implements DistributeTasksService {
RobotAcceptTaskDTO robotTaskDO = new RobotAcceptTaskDTO(); RobotAcceptTaskDTO robotTaskDO = new RobotAcceptTaskDTO();
robotTaskDO.setOrder_id(taskDetailDO.getId().toString()); robotTaskDO.setOrder_id(taskDetailDO.getId().toString());
robotTaskDO.setOrder_type("出库");//未定 robotTaskDO.setOrder_type("出库");//未定
robotTaskDO.setTopic(RobotTopicEnum.ROBOT_TASK.getTopic()+macAddress); robotTaskDO.setTopic(RobotTopicConstant.ROBOT_TASK_TOPIC+macAddress);
//1 //1
RobotAcceptTaskData taskOne = new RobotAcceptTaskData(); RobotAcceptTaskData taskOne = new RobotAcceptTaskData();
@ -473,7 +474,7 @@ public class DistributeTasksServiceImpl implements DistributeTasksService {
RobotAcceptTaskDTO robotTaskDO = new RobotAcceptTaskDTO(); RobotAcceptTaskDTO robotTaskDO = new RobotAcceptTaskDTO();
robotTaskDO.setOrder_id(taskDetailDO.getId().toString()); robotTaskDO.setOrder_id(taskDetailDO.getId().toString());
robotTaskDO.setOrder_type("出库");//未定 robotTaskDO.setOrder_type("出库");//未定
robotTaskDO.setTopic(RobotTopicEnum.ROBOT_TASK.getTopic()+macAddress); robotTaskDO.setTopic(RobotTopicConstant.ROBOT_TASK_TOPIC+macAddress);
RobotAcceptTaskData taskOne = new RobotAcceptTaskData(); RobotAcceptTaskData taskOne = new RobotAcceptTaskData();
taskOne.setSerial("1"); taskOne.setSerial("1");
@ -532,7 +533,7 @@ public class DistributeTasksServiceImpl implements DistributeTasksService {
RobotAcceptTaskDTO robotTaskDO = new RobotAcceptTaskDTO(); RobotAcceptTaskDTO robotTaskDO = new RobotAcceptTaskDTO();
robotTaskDO.setOrder_id(taskDetailDO.getId().toString()); robotTaskDO.setOrder_id(taskDetailDO.getId().toString());
robotTaskDO.setOrder_type("出库");//未定 robotTaskDO.setOrder_type("出库");//未定
robotTaskDO.setTopic(RobotTopicEnum.ROBOT_TASK.getTopic()+macAddress); robotTaskDO.setTopic(RobotTopicConstant.ROBOT_TASK_TOPIC+macAddress);
//1 //1
RobotAcceptTaskData taskOne = new RobotAcceptTaskData(); RobotAcceptTaskData taskOne = new RobotAcceptTaskData();

View File

@ -2,11 +2,358 @@
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapLineMapper"> <mapper namespace="cn.iocoder.yudao.module.system.dal.mysql.positionmap.PositionMapLineMapper">
<!-- <resultMap id="BaseResultMap" type="cn.iocoder.yudao.module.system.dal.dataobject.positionmap.PositionMapLineDO">
一般情况下,尽可能使用 Mapper 进行 CRUD 增删改查即可。 <!--@Table ware_position_map_line-->
无法满足的场景,例如说多表关联查询,才使用 XML 编写 SQL。 <result property="id" column="id" jdbcType="INTEGER"/>
代码生成器暂时只生成 Mapper XML 文件本身,更多推荐 MybatisX 快速开发插件来生成查询。 <result property="positionMapId" column="position_map_id" jdbcType="INTEGER"/>
文档可见https://www.iocoder.cn/MyBatis/x-plugins/ <result property="startingPointId" column="starting_point_id" jdbcType="INTEGER"/>
--> <result property="endPointId" column="end_point_id" jdbcType="INTEGER"/>
<result property="beginControlX" column="begin_control_x" jdbcType="VARCHAR"/>
<result property="beginControlY" column="begin_control_y" jdbcType="VARCHAR"/>
<result property="endControlX" column="end_control_x" jdbcType="VARCHAR"/>
<result property="endControlY" column="end_control_y" jdbcType="VARCHAR"/>
<result property="expansionZoneFront" column="expansion_zone_front" jdbcType="NUMERIC"/>
<result property="expansionZoneAfter" column="expansion_zone_after" jdbcType="NUMERIC"/>
<result property="expansionZoneLeft" column="expansion_zone_left" jdbcType="NUMERIC"/>
<result property="expansionZoneRight" column="expansion_zone_right" jdbcType="NUMERIC"/>
<result property="method" column="method" jdbcType="INTEGER"/>
<result property="direction" column="direction" jdbcType="INTEGER"/>
<result property="forwardSpeedLimit" column="forward_speed_limit" jdbcType="NUMERIC"/>
<result property="reverseSpeedLimit" column="reverse_speed_limit" jdbcType="NUMERIC"/>
<result property="creator" column="creator" jdbcType="VARCHAR"/>
<result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
<result property="updater" column="updater" jdbcType="VARCHAR"/>
<result property="updateTime" column="update_time" jdbcType="TIMESTAMP"/>
<result property="deleted" column="deleted" jdbcType="INTEGER"/>
<result property="toward" column="toward" jdbcType="INTEGER"/>
</resultMap>
<!--查询单个-->
<select id="queryById" resultMap="BaseResultMap">
select
id, position_map_id, starting_point_id, end_point_id, begin_control_x, begin_control_y, end_control_x, end_control_y, expansion_zone_front, expansion_zone_after, expansion_zone_left, expansion_zone_right, method, direction, forward_speed_limit, reverse_speed_limit, creator, create_time, updater, update_time, deleted, tenant_id, toward
from ware_position_map_line
where id = #{id}
</select>
<!--查询指定行数据-->
<select id="queryAllByLimit" resultMap="BaseResultMap">
select
id, position_map_id, starting_point_id, end_point_id, begin_control_x, begin_control_y, end_control_x, end_control_y, expansion_zone_front, expansion_zone_after, expansion_zone_left, expansion_zone_right, method, direction, forward_speed_limit, reverse_speed_limit, creator, create_time, updater, update_time, deleted, tenant_id, toward
from ware_position_map_line
<where>
<if test="id != null">
and id = #{id}
</if>
<if test="positionMapId != null">
and position_map_id = #{positionMapId}
</if>
<if test="startingPointId != null">
and starting_point_id = #{startingPointId}
</if>
<if test="endPointId != null">
and end_point_id = #{endPointId}
</if>
<if test="beginControlX != null and beginControlX != ''">
and begin_control_x = #{beginControlX}
</if>
<if test="beginControlY != null and beginControlY != ''">
and begin_control_y = #{beginControlY}
</if>
<if test="endControlX != null and endControlX != ''">
and end_control_x = #{endControlX}
</if>
<if test="endControlY != null and endControlY != ''">
and end_control_y = #{endControlY}
</if>
<if test="expansionZoneFront != null">
and expansion_zone_front = #{expansionZoneFront}
</if>
<if test="expansionZoneAfter != null">
and expansion_zone_after = #{expansionZoneAfter}
</if>
<if test="expansionZoneLeft != null">
and expansion_zone_left = #{expansionZoneLeft}
</if>
<if test="expansionZoneRight != null">
and expansion_zone_right = #{expansionZoneRight}
</if>
<if test="method != null">
and method = #{method}
</if>
<if test="direction != null">
and direction = #{direction}
</if>
<if test="forwardSpeedLimit != null">
and forward_speed_limit = #{forwardSpeedLimit}
</if>
<if test="reverseSpeedLimit != null">
and reverse_speed_limit = #{reverseSpeedLimit}
</if>
<if test="creator != null and creator != ''">
and creator = #{creator}
</if>
<if test="createTime != null">
and create_time = #{createTime}
</if>
<if test="updater != null and updater != ''">
and updater = #{updater}
</if>
<if test="updateTime != null">
and update_time = #{updateTime}
</if>
<if test="deleted != null">
and deleted = #{deleted}
</if>
<if test="toward != null">
and toward = #{toward}
</if>
</where>
limit #{pageable.offset}, #{pageable.pageSize}
</select>
<!--通过实体作为筛选条件查询-->
<sql id="base_sql" >
id,
position_map_id,
starting_point_id,
end_point_id,
begin_control_x,
begin_control_y,
end_control_x,
end_control_y,
expansion_zone_front,
expansion_zone_after,
expansion_zone_left,
expansion_zone_right,
method,
direction,
forward_speed_limit,
reverse_speed_limit,
creator,
toward
</sql>
<!--统计总行数-->
<select id="count" resultType="java.lang.Long">
select count(1)
from ware_position_map_line
<where>
<if test="id != null">
and id = #{id}
</if>
<if test="positionMapId != null">
and position_map_id = #{positionMapId}
</if>
<if test="startingPointId != null">
and starting_point_id = #{startingPointId}
</if>
<if test="endPointId != null">
and end_point_id = #{endPointId}
</if>
<if test="beginControlX != null and beginControlX != ''">
and begin_control_x = #{beginControlX}
</if>
<if test="beginControlY != null and beginControlY != ''">
and begin_control_y = #{beginControlY}
</if>
<if test="endControlX != null and endControlX != ''">
and end_control_x = #{endControlX}
</if>
<if test="endControlY != null and endControlY != ''">
and end_control_y = #{endControlY}
</if>
<if test="expansionZoneFront != null">
and expansion_zone_front = #{expansionZoneFront}
</if>
<if test="expansionZoneAfter != null">
and expansion_zone_after = #{expansionZoneAfter}
</if>
<if test="expansionZoneLeft != null">
and expansion_zone_left = #{expansionZoneLeft}
</if>
<if test="expansionZoneRight != null">
and expansion_zone_right = #{expansionZoneRight}
</if>
<if test="method != null">
and method = #{method}
</if>
<if test="direction != null">
and direction = #{direction}
</if>
<if test="forwardSpeedLimit != null">
and forward_speed_limit = #{forwardSpeedLimit}
</if>
<if test="reverseSpeedLimit != null">
and reverse_speed_limit = #{reverseSpeedLimit}
</if>
<if test="creator != null and creator != ''">
and creator = #{creator}
</if>
<if test="createTime != null">
and create_time = #{createTime}
</if>
<if test="updater != null and updater != ''">
and updater = #{updater}
</if>
<if test="updateTime != null">
and update_time = #{updateTime}
</if>
<if test="deleted != null">
and deleted = #{deleted}
</if>
<if test="toward != null">
and toward = #{toward}
</if>
</where>
</select>
<select id="getAllPositionMapLine"
resultType="cn.iocoder.yudao.module.mqtt.api.path.dto.PositionMapLineDTO">
select
<include refid="base_sql"></include>
from
ware_position_map_line
<where>
<if test="id != null">
and id = #{id}
</if>
<if test="positionMapId != null">
and position_map_id = #{positionMapId}
</if>
<if test="startingPointId != null">
and starting_point_id = #{startingPointId}
</if>
<if test="endPointId != null">
and end_point_id = #{endPointId}
</if>
<if test="beginControlX != null and beginControlX != ''">
and begin_control_x = #{beginControlX}
</if>
<if test="beginControlY != null and beginControlY != ''">
and begin_control_y = #{beginControlY}
</if>
<if test="endControlX != null and endControlX != ''">
and end_control_x = #{endControlX}
</if>
<if test="endControlY != null and endControlY != ''">
and end_control_y = #{endControlY}
</if>
<if test="expansionZoneFront != null">
and expansion_zone_front = #{expansionZoneFront}
</if>
<if test="expansionZoneAfter != null">
and expansion_zone_after = #{expansionZoneAfter}
</if>
<if test="expansionZoneLeft != null">
and expansion_zone_left = #{expansionZoneLeft}
</if>
<if test="expansionZoneRight != null">
and expansion_zone_right = #{expansionZoneRight}
</if>
<if test="method != null">
and method = #{method}
</if>
<if test="direction != null">
and direction = #{direction}
</if>
<if test="forwardSpeedLimit != null">
and forward_speed_limit = #{forwardSpeedLimit}
</if>
<if test="reverseSpeedLimit != null">
and reverse_speed_limit = #{reverseSpeedLimit}
</if>
<if test="creator != null and creator != ''">
and creator = #{creator}
</if>
<if test="createTime != null">
and create_time = #{createTime}
</if>
<if test="updater != null and updater != ''">
and updater = #{updater}
</if>
<if test="updateTime != null">
and update_time = #{updateTime}
</if>
<if test="deleted != null">
and deleted = #{deleted}
</if>
<if test="toward != null">
and toward = #{toward}
</if>
</where>
</select>
<!--通过主键修改数据-->
<update id="updateBySelect">
update ware_position_map_line
<set>
<if test="positionMapId != null">
position_map_id = #{positionMapId},
</if>
<if test="startingPointId != null">
starting_point_id = #{startingPointId},
</if>
<if test="endPointId != null">
end_point_id = #{endPointId},
</if>
<if test="beginControlX != null and beginControlX != ''">
begin_control_x = #{beginControlX},
</if>
<if test="beginControlY != null and beginControlY != ''">
begin_control_y = #{beginControlY},
</if>
<if test="endControlX != null and endControlX != ''">
end_control_x = #{endControlX},
</if>
<if test="endControlY != null and endControlY != ''">
end_control_y = #{endControlY},
</if>
<if test="expansionZoneFront != null">
expansion_zone_front = #{expansionZoneFront},
</if>
<if test="expansionZoneAfter != null">
expansion_zone_after = #{expansionZoneAfter},
</if>
<if test="expansionZoneLeft != null">
expansion_zone_left = #{expansionZoneLeft},
</if>
<if test="expansionZoneRight != null">
expansion_zone_right = #{expansionZoneRight},
</if>
<if test="method != null">
method = #{method},
</if>
<if test="direction != null">
direction = #{direction},
</if>
<if test="forwardSpeedLimit != null">
forward_speed_limit = #{forwardSpeedLimit},
</if>
<if test="reverseSpeedLimit != null">
reverse_speed_limit = #{reverseSpeedLimit},
</if>
<if test="creator != null and creator != ''">
creator = #{creator},
</if>
<if test="createTime != null">
create_time = #{createTime},
</if>
<if test="updater != null and updater != ''">
updater = #{updater},
</if>
<if test="updateTime != null">
update_time = #{updateTime},
</if>
<if test="deleted != null">
deleted = #{deleted},
</if>
<if test="toward != null">
toward = #{toward},
</if>
</set>
where id = #{id}
</update>
</mapper> </mapper>