refactor(websocket): 重构频道订阅处理器基类实现

- 提取公共基类 BaseChannelSubscribeHandler 处理订阅逻辑
- 将原处理器拆分为带 GRPC 调用和简单订阅两种实现
- 使用依赖注入替代 Autowired 注解
- 统一订阅和取消订阅的处理流程
- 优化日志记录和异常处理机制
This commit is contained in:
lixiaolong 2026-06-05 14:57:57 +08:00
parent 05b90f8dc3
commit f57c9b9dda
22 changed files with 312 additions and 126 deletions

View File

@ -111,4 +111,5 @@ public class InspectionWaypointController extends BaseController
{ {
return toAjax(inspectionWaypointService.deleteInspectionWaypointByIds(ids)); return toAjax(inspectionWaypointService.deleteInspectionWaypointByIds(ids));
} }
} }

View File

@ -0,0 +1,95 @@
package com.cmvr.framework.websocket.handler;
import com.cmvr.framework.websocket.manager.ChannelSubscriptionManager;
import com.cmvr.framework.websocket.message.WSChannelSubscriptionMessage;
import com.cmvr.framework.websocket.service.GrpcClientService;
import lombok.RequiredArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.socket.WebSocketSession;
import java.util.concurrent.CompletableFuture;
@RequiredArgsConstructor
public abstract class BaseChannelSubscribeHandler implements WSMessageHandler<WSChannelSubscriptionMessage> {
protected final Logger log = LoggerFactory.getLogger(getClass());
protected final ChannelSubscriptionManager channelSubscriptionManager;
protected final GrpcClientService grpcClientService;
/**
* 是否需要GRPC远程调用
* true=格式 service/method/terminalId/deviceId 走grpc
* false=普通频道只本地订阅不调用grpc
*/
protected abstract boolean isNeedGrpc(String channel);
/**
* 解析grpc四个参数 [service,method,terminalId,deviceId]
* 只有isNeedGrpc=true才会进入执行
*/
protected abstract String[] parseGrpcParam(String channel);
@Override
public void handle(WebSocketSession session, WSChannelSubscriptionMessage message) throws Exception {
String action = message.getAction();
String userId = session.getAttributes().get("userId").toString();
String channel = message.getChannel();
switch (action) {
case "subscribe":
doSubscribe(channel, session);
break;
case "unsubscribe":
doUnSubscribe(channel, session);
break;
default:
log.warn("未知订阅动作:{}channel:{}", action, channel);
return;
}
log.info("用户{} {}频道{}", userId, "subscribe".equals(action) ? "订阅" : "取消订阅", channel);
}
/** 订阅统一模板 */
private void doSubscribe(String channel, WebSocketSession session) {
boolean needGrpc = isNeedGrpc(channel);
// 没人订阅 + 需要grpc 发起远端订阅
if (needGrpc && !channelSubscriptionManager.hasSubscribers(channel)) {
String[] params = parseGrpcParam(channel);
String service = params[0];
String method = params[1];
String terminalId = params[2];
String deviceId = params[3];
CompletableFuture.runAsync(() -> {
try {
grpcClientService.send(true, terminalId, deviceId, service, method);
} catch (Exception e) {
log.error("频道{} grpc订阅异常", channel, e);
}
});
}
// 本地统一订阅
channelSubscriptionManager.subscribe(channel, session);
}
/** 取消订阅统一模板 */
private void doUnSubscribe(String channel, WebSocketSession session) {
channelSubscriptionManager.unsubscribe(channel, session);
boolean needGrpc = isNeedGrpc(channel);
// 无任何订阅 + 需要grpc 远端取消
if (needGrpc && !channelSubscriptionManager.hasSubscribers(channel)) {
String[] params = parseGrpcParam(channel);
String service = params[0];
String method = params[1];
String terminalId = params[2];
String deviceId = params[3];
CompletableFuture.runAsync(() -> {
try {
grpcClientService.send(false, terminalId, deviceId, service, method);
} catch (Exception e) {
log.error("频道{} grpc取消订阅异常", channel, e);
}
});
}
}
}

View File

@ -5,67 +5,26 @@ import com.cmvr.framework.websocket.enums.WSMessageTypeEnum;
import com.cmvr.framework.websocket.manager.ChannelSubscriptionManager; import com.cmvr.framework.websocket.manager.ChannelSubscriptionManager;
import com.cmvr.framework.websocket.message.WSChannelSubscriptionMessage; import com.cmvr.framework.websocket.message.WSChannelSubscriptionMessage;
import com.cmvr.framework.websocket.service.GrpcClientService; import com.cmvr.framework.websocket.service.GrpcClientService;
import org.slf4j.Logger; import org.springframework.stereotype.Component;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.socket.WebSocketSession;
import java.util.concurrent.CompletableFuture;
/** @Component
* 频道订阅消息处理
*/
@WSMessageType(value = WSMessageTypeEnum.CHANNEL_SUBSCRIPTION, messageClass = WSChannelSubscriptionMessage.class) @WSMessageType(value = WSMessageTypeEnum.CHANNEL_SUBSCRIPTION, messageClass = WSChannelSubscriptionMessage.class)
public class ChannelSubscriptionMessageHandler implements WSMessageHandler<WSChannelSubscriptionMessage> { public class ChannelSubscriptionMessageHandler extends BaseChannelSubscribeHandler {
private static final Logger log = LoggerFactory.getLogger(ChannelSubscriptionMessageHandler.class);
@Autowired public ChannelSubscriptionMessageHandler(ChannelSubscriptionManager channelSubscriptionManager, GrpcClientService grpcClientService) {
private ChannelSubscriptionManager channelSubscriptionManager; super(channelSubscriptionManager, grpcClientService);
@Autowired
private GrpcClientService grpcClientService;
public void handle(WebSocketSession session, WSChannelSubscriptionMessage message) throws Exception {
String action = message.getAction();
String userId = session.getAttributes().get("userId").toString();
// service/method/terminalId/deviceId
String channel = message.getChannel();
String[] channelInfoArr = channel.split("\\/");
String service = channelInfoArr[0];
String method = channelInfoArr[1];
String terminalId = channelInfoArr[2];
String deviceId = channelInfoArr[3];
if ("subscribe".equals(action)) {
if (!channelSubscriptionManager.hasSubscribers(channel)) {
// 异步调用gRPC
CompletableFuture.runAsync(() -> {
try {
grpcClientService.send(true, terminalId, deviceId, service, method);
} catch (Exception e) {
log.error("gRPC订阅失败: {}", e.getMessage());
}
});
}
channelSubscriptionManager.subscribe(channel, session);
} else if ("unsubscribe".equals(action)) {
channelSubscriptionManager.unsubscribe(channel, session);
if (!channelSubscriptionManager.hasSubscribers(channel)) {
CompletableFuture.runAsync(() -> {
try {
grpcClientService.send(false, terminalId, deviceId, service, method);
} catch (Exception e) {
log.error("gRPC取消订阅失败: {}", e.getMessage());
}
});
}
} else {
System.out.println("未知频道操作: " + action);
return;
} }
// 统一记录日志 // 当前频道带 / 分段需要grpc
log.info("用户{} {} 频道{}", userId, getActionDescription(action), channel); @Override
protected boolean isNeedGrpc(String channel) {
return channel.contains("/");
} }
// 根据动作获取描述文本 @Override
private String getActionDescription(String action) { protected String[] parseGrpcParam(String channel) {
return "subscribe".equals(action) ? "订阅了" : "取消订阅了"; return channel.split("/");
} }
} }

View File

@ -4,12 +4,10 @@ import com.cmvr.framework.websocket.annotation.WSMessageType;
import com.cmvr.framework.websocket.enums.WSMessageTypeEnum; import com.cmvr.framework.websocket.enums.WSMessageTypeEnum;
import com.cmvr.framework.websocket.message.WSHeartbeatMessage; import com.cmvr.framework.websocket.message.WSHeartbeatMessage;
import org.springframework.web.socket.WebSocketSession; import org.springframework.web.socket.WebSocketSession;
import java.io.IOException; import java.io.IOException;
@WSMessageType(value = WSMessageTypeEnum.HEARTBEAT, messageClass = WSHeartbeatMessage.class) @WSMessageType(value = WSMessageTypeEnum.HEARTBEAT, messageClass = WSHeartbeatMessage.class)
public class HeartbeatMessageHandler implements WSMessageHandler<WSHeartbeatMessage>{ public class HeartbeatMessageHandler implements WSMessageHandler<WSHeartbeatMessage>{
@Override @Override
public void handle(WebSocketSession session, WSHeartbeatMessage message) throws IOException { public void handle(WebSocketSession session, WSHeartbeatMessage message) throws IOException {
System.out.println("heartbeat"); System.out.println("heartbeat");

View File

@ -0,0 +1,29 @@
package com.cmvr.framework.websocket.handler;
import com.cmvr.framework.websocket.annotation.WSMessageType;
import com.cmvr.framework.websocket.enums.WSMessageTypeEnum;
import com.cmvr.framework.websocket.manager.ChannelSubscriptionManager;
import com.cmvr.framework.websocket.message.WSChannelSubscriptionMessage;
import com.cmvr.framework.websocket.service.GrpcClientService;
import org.springframework.stereotype.Component;
@Component
@WSMessageType(value = WSMessageTypeEnum.CHANNEL_SUBSCRIPTION, messageClass = WSChannelSubscriptionMessage.class)
public class SimpleChannelSubscribeHandler extends BaseChannelSubscribeHandler {
public SimpleChannelSubscribeHandler(ChannelSubscriptionManager channelSubscriptionManager, GrpcClientService grpcClientService) {
super(channelSubscriptionManager, grpcClientService);
}
// 简单频道不需要grpc调用
@Override
protected boolean isNeedGrpc(String channel) {
return false;
}
// 不会执行到随便返回
@Override
protected String[] parseGrpcParam(String channel) {
return new String[0];
}
}

View File

@ -51,4 +51,8 @@ public class InspectionTask extends BaseEntity
@ApiModelProperty("地图id") @ApiModelProperty("地图id")
private String mapId; private String mapId;
@Excel(name = "点位数量")
@ApiModelProperty("点位数量")
private Integer waypointCount;
} }

View File

@ -54,4 +54,8 @@ public class InspectionTaskInstance extends BaseEntity
@ApiModelProperty("检测任务id") @ApiModelProperty("检测任务id")
private String taskInsId; private String taskInsId;
@Excel(name = "点位数量")
@ApiModelProperty("点位数量")
private Integer waypointCount;
} }

View File

@ -94,4 +94,8 @@ public class InspectionTaskInstanceVo extends BaseEntity
@ApiModelProperty("检测任务id") @ApiModelProperty("检测任务id")
private String taskInsId; private String taskInsId;
@Excel(name = "点位数量")
@ApiModelProperty("点位数量")
private Integer waypointCount;
} }

View File

@ -66,4 +66,8 @@ public class InspectionTaskVo extends BaseEntity
@ApiModelProperty("地图名称") @ApiModelProperty("地图名称")
private String mapName; private String mapName;
@Excel(name = "点位数量")
@ApiModelProperty("点位数量")
private Integer waypointCount;
} }

View File

@ -1,6 +1,7 @@
package com.cmvr.inspection.listener; package com.cmvr.inspection.listener;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper; import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.cmvr.common.utils.DateUtils; import com.cmvr.common.utils.DateUtils;
import com.cmvr.framework.websocket.service.MessagePushService; import com.cmvr.framework.websocket.service.MessagePushService;
import com.cmvr.inspection.domain.InspectionTaskInstance; import com.cmvr.inspection.domain.InspectionTaskInstance;
@ -9,74 +10,144 @@ import com.cmvr.inspection.service.IInspectionTaskInstanceService;
import com.cmvr.test.flow.runtime.event.FlowExecutionEvent; import com.cmvr.test.flow.runtime.event.FlowExecutionEvent;
import com.cmvr.test.flow.runtime.event.FlowExecutionListener; import com.cmvr.test.flow.runtime.event.FlowExecutionListener;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.HashMap; import java.util.*;
import java.util.Map;
@Component @Component
@Slf4j @Slf4j
public class InspectionFlowExecutionListener implements FlowExecutionListener { public class InspectionFlowExecutionListener implements FlowExecutionListener {
@Autowired private final IInspectionTaskInstanceService inspectionTaskInstanceService;
private IInspectionTaskInstanceService inspectionTaskInstanceService; private final MessagePushService messagePushService;
@Autowired
private MessagePushService messagePushService; /** key:itemId, value:已完成节点集合 */
private final Map<String, Set<String>> itemNodeExecutMap = new HashMap<>();
/** key:taskInsId(流程实例id=taskInsId), value:已执行item集合 */
private final Map<String, Set<String>> taskItemExecutMap = new HashMap<>();
public InspectionFlowExecutionListener(IInspectionTaskInstanceService inspectionTaskInstanceService, MessagePushService messagePushService) {
this.inspectionTaskInstanceService = inspectionTaskInstanceService;
this.messagePushService = messagePushService;
}
@Override @Override
public void onEvent(FlowExecutionEvent event) { public void onEvent(FlowExecutionEvent event) {
// 节点执行事件 String instId = event.getInstId();
if (event.getNodeId() != null) { String itemId = event.getItemId();
String info = event.getEventType() == FlowExecutionEvent.EventType.NODE_STARTED ? "开始执行" : "执行完成"; String nodeId = event.getNodeId();
// 查询巡检任务实例event中的instId是巡检任务中的taskInsId if (StrUtil.isBlank(instId)) {
InspectionTaskInstance inspectionTaskInstance = inspectionTaskInstanceService.lambdaQuery().eq(InspectionTaskInstance::getTaskInsId, event.getInstId()) return;
.one();
String insId = inspectionTaskInstance.getId();
Map<String, String> data = new HashMap<>();
data.put("insId", insId);
data.put("logInfo", info);
try {
messagePushService.pushToChannel("Inspection/TaskInstance", data);
} catch (Exception e) {
log.info("如果没人订阅,则吃掉异常");
} }
// 1.节点完成才记录当前item下node
if (StrUtil.isNotBlank(itemId) && StrUtil.isNotBlank(nodeId)
&& FlowExecutionEvent.EventType.NODE_COMPLETED == event.getEventType()) {
itemNodeExecutMap.computeIfAbsent(itemId, k -> new HashSet<>()).add(nodeId);
} }
// 通过 instId 找到巡检任务实例并修改其状态 // 任意事件当前任务绑定itemitem一启动就入Map所以统计已完成item要-1
// 1.构造更新条件 if (StrUtil.isNotBlank(instId) && StrUtil.isNotBlank(itemId)) {
LambdaQueryChainWrapper<InspectionTaskInstance> wrapper = inspectionTaskInstanceService.lambdaQuery() taskItemExecutMap.computeIfAbsent(instId, k -> new HashSet<>()).add(itemId);
.eq(InspectionTaskInstance::getTaskInsId, event.getInstId()); }
// 2.要更新的字段
InspectionTaskInstance updateEntity = getInspectionTaskInstance(); InspectionTaskInstance taskInstance = inspectionTaskInstanceService.lambdaQuery()
.eq(InspectionTaskInstance::getTaskInsId, instId)
.one();
if (taskInstance == null) {
log.warn("未查询到巡检实例,taskInsId:{}", instId);
return;
}
int targetStatus = TaskStatusEnum.RUNNING.getCode();
boolean needUpdateDb = false;
Date now = DateUtils.getNowDate();
switch (event.getEventType()) { switch (event.getEventType()) {
case TASK_COMPLETED: case TASK_COMPLETED:
// 设置状态为成功 targetStatus = TaskStatusEnum.SUCCESS.getCode();
updateEntity.setStatus(TaskStatusEnum.SUCCESS.getCode()); needUpdateDb = true;
// 正确APIupdate(更新实体, 条件Wrapper) clearCache(instId);
inspectionTaskInstanceService.update(updateEntity, wrapper.getWrapper()); pushCompleteMsg(taskInstance.getId(), now, targetStatus);
break; break;
case TASK_FAILED: case TASK_FAILED:
// 设置状态为失败 targetStatus = TaskStatusEnum.FAILED.getCode();
updateEntity.setStatus(TaskStatusEnum.FAILED.getCode()); needUpdateDb = true;
// 正确APIupdate(更新实体, 条件Wrapper) clearCache(instId);
inspectionTaskInstanceService.update(updateEntity, wrapper.getWrapper());
break; break;
case NODE_COMPLETED: case NODE_COMPLETED:
// 判断当前任务所有节点是否执行完毕 default:
break; break;
} }
if (needUpdateDb) {
taskInstance.setStatus(targetStatus);
taskInstance.setEndTime(now);
inspectionTaskInstanceService.updateById(taskInstance);
} }
@NotNull // 节点推送
private static InspectionTaskInstance getInspectionTaskInstance() { if (StrUtil.isNotBlank(nodeId)) {
InspectionTaskInstance updateEntity = InspectionTaskInstance.builder() int waypointCount = taskInstance.getWaypointCount() == null ? 0 : taskInstance.getWaypointCount();
.endTime(DateUtils.getNowDate()) double progress = 0D;
if (waypointCount > 0) {
// 当前任务已执行item数量item启动就存入集合已完整跑完的item=总数-1
Set<String> itemSet = taskItemExecutMap.getOrDefault(instId, new HashSet<>());
int itemTotal = itemSet.size();
int finishedItemNum = itemTotal - 1;
// 当前item已完成节点数
Set<String> finishedNodeSet = itemNodeExecutMap.getOrDefault(itemId, new HashSet<>());
int finishedNode = finishedNodeSet.size();
int totalNode = event.getNodeCount() == 0 ? 1 : event.getNodeCount();
// 已完整跑完点位占比
double itemTotalRatio = finishedItemNum / (double) waypointCount;
// 当前运行item内部节点占比
double innerRatio = finishedNode / (double) totalNode / waypointCount;
// 还原你的兜底防止循环节点进度超限最低不低于极小值
double singleItemBase = 1d / waypointCount;
innerRatio = Math.max(singleItemBase - 0.01, innerRatio);
progress = (itemTotalRatio + innerRatio) * 100;
}
String info = event.getEventType() == FlowExecutionEvent.EventType.NODE_STARTED ? "开始执行" : "执行完成";
Map<String, Object> pushMap = MapUtil.<String, Object>builder()
.put("createTime", now)
.put("insId", taskInstance.getId())
.put("logInfo", "节点【" + event.getNodeName() + "" + info)
.put("status", targetStatus)
.put("progress", String.format("%.2f", progress))
.put("itemId", itemId)
.put("taskId", taskInstance.getTaskId())
.build(); .build();
updateEntity.setUpdateTime(DateUtils.getNowDate()); try {
return updateEntity; messagePushService.pushToChannel("InspectionTaskInstance", pushMap);
} catch (Exception e) {
log.info("消息推送异常,无订阅忽略,itemId:{}", itemId, e);
}
}
} }
/** 任务结束统一清理缓存 */
private void clearCache(String taskInsId) {
Set<String> itemList = taskItemExecutMap.getOrDefault(taskInsId, new HashSet<>());
itemList.forEach(itemNodeExecutMap::remove);
taskItemExecutMap.remove(taskInsId);
}
/**
* 推送完成任务信息参数dbInsId为数据库主键ID
*/
public void pushCompleteMsg(String dbInsId, Date now, int targetStatus) {
Map<String, Object> pushMap = MapUtil.<String, Object>builder()
.put("createTime", now)
.put("insId", dbInsId)
.put("status", targetStatus)
.build();
try {
messagePushService.pushToChannel("InspectionTaskInstance", pushMap);
} catch (Exception e) {
log.info("消息推送异常,无订阅忽略,insId:{}", dbInsId, e);
}
}
} }

View File

@ -50,4 +50,6 @@ public interface InspectionTaskWaypointMapper extends MPJBaseMapper<InspectionT
* @param waypointIds 点位ID数组 * @param waypointIds 点位ID数组
*/ */
void deleteTaskWaypointByWaypointIds(String[] waypointIds); void deleteTaskWaypointByWaypointIds(String[] waypointIds);
} }

View File

@ -52,4 +52,6 @@ public interface InspectionWaypointMapper extends MPJBaseMapper<InspectionWaypo
* @return 巡检点位视图集合 * @return 巡检点位视图集合
*/ */
List<InspectionWaypointVo> selectInspectionWaypointVoList(InspectionWaypoint inspectionWaypoint); List<InspectionWaypointVo> selectInspectionWaypointVoList(InspectionWaypoint inspectionWaypoint);
} }

View File

@ -88,6 +88,9 @@ public class InspectionTaskInstanceServiceImpl extends ServiceImpl<InspectionTas
inspectionTaskInstance.setStatus(TaskStatusEnum.NOT_STARTED.getCode()); inspectionTaskInstance.setStatus(TaskStatusEnum.NOT_STARTED.getCode());
inspectionTaskInstance.setCreateTime(DateUtils.getNowDate()); inspectionTaskInstance.setCreateTime(DateUtils.getNowDate());
inspectionTaskInstance.setCreateBy(SecurityUtils.getUsername()); inspectionTaskInstance.setCreateBy(SecurityUtils.getUsername());
// 获取点位数量
InspectionTask inspectionTask = inspectionTaskService.selectInspectionTaskById(inspectionTaskInstance.getTaskId());
inspectionTaskInstance.setWaypointCount(inspectionTask.getWaypointCount());
return inspectionTaskInstanceMapper.insertInspectionTaskInstance(inspectionTaskInstance); return inspectionTaskInstanceMapper.insertInspectionTaskInstance(inspectionTaskInstance);
} }
@ -106,6 +109,9 @@ public class InspectionTaskInstanceServiceImpl extends ServiceImpl<InspectionTas
} }
inspectionTaskInstance.setUpdateTime(DateUtils.getNowDate()); inspectionTaskInstance.setUpdateTime(DateUtils.getNowDate());
inspectionTaskInstance.setUpdateBy(SecurityUtils.getUsername()); inspectionTaskInstance.setUpdateBy(SecurityUtils.getUsername());
// 获取点位数量
InspectionTask inspectionTask = inspectionTaskService.selectInspectionTaskById(inspectionTaskInstance.getTaskId());
inspectionTaskInstance.setWaypointCount(inspectionTask.getWaypointCount());
return inspectionTaskInstanceMapper.updateInspectionTaskInstance(inspectionTaskInstance); return inspectionTaskInstanceMapper.updateInspectionTaskInstance(inspectionTaskInstance);
} }

View File

@ -5,7 +5,6 @@ import java.util.List;
import java.util.UUID; import java.util.UUID;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmvr.inspection.domain.InspectionTaskWaypoint; import com.cmvr.inspection.domain.InspectionTaskWaypoint;
import com.cmvr.inspection.domain.InspectionWaypoint; import com.cmvr.inspection.domain.InspectionWaypoint;
@ -162,8 +161,10 @@ public class InspectionTaskServiceImpl extends ServiceImpl<InspectionTaskMapper,
list.add(tw); list.add(tw);
} }
inspectionTaskWaypointMapper.batchInsertTaskWaypoint(list); inspectionTaskWaypointMapper.batchInsertTaskWaypoint(list);
// 查询巡检任务 // 查询巡检任务,并修改点位数量
InspectionTask inspectionTask = inspectionTaskMapper.selectInspectionTaskById(taskId); InspectionTask inspectionTask = inspectionTaskMapper.selectInspectionTaskById(taskId);
inspectionTask.setWaypointCount(waypointIds.length);
inspectionTaskMapper.updateInspectionTask(inspectionTask);
// 查询点位 // 查询点位
List<InspectionWaypoint> waypoints = inspectionTaskWaypointMapper.selectWaypointsByTaskId(taskId); List<InspectionWaypoint> waypoints = inspectionTaskWaypointMapper.selectWaypointsByTaskId(taskId);
// 同步任务编排 // 同步任务编排

View File

@ -2,7 +2,6 @@ package com.cmvr.inspection.service.impl;
import java.util.List; import java.util.List;
import java.util.UUID; import java.util.UUID;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cmvr.inspection.domain.vo.InspectionWaypointVo; import com.cmvr.inspection.domain.vo.InspectionWaypointVo;
import com.cmvr.inspection.mapper.InspectionTaskWaypointMapper; import com.cmvr.inspection.mapper.InspectionTaskWaypointMapper;
@ -115,5 +114,4 @@ public class InspectionWaypointServiceImpl extends ServiceImpl<InspectionWaypoin
} }
return inspectionWaypointMapper.deleteInspectionWaypointByIds(ids); return inspectionWaypointMapper.deleteInspectionWaypointByIds(ids);
} }
} }

View File

@ -41,10 +41,11 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<result property="createByName" column="create_by_name" /> <result property="createByName" column="create_by_name" />
<result property="updateByName" column="update_by_name" /> <result property="updateByName" column="update_by_name" />
<result property="taskInsId" column="task_ins_id" /> <result property="taskInsId" column="task_ins_id" />
<result property="waypointCount" column="waypoint_count" />
</resultMap> </resultMap>
<sql id="selectInspectionTaskInstanceVo"> <sql id="selectInspectionTaskInstanceVo">
select id, create_by, create_time, update_by, update_time, remark, task_id, robot_id, status, start_time, end_time, task_ins_id from inspection_task_instance select id, create_by, create_time, update_by, update_time, remark, task_id, robot_id, status, start_time, end_time, task_ins_id, waypoint_count from inspection_task_instance
</sql> </sql>
<select id="selectInspectionTaskInstanceList" parameterType="InspectionTaskInstance" resultMap="InspectionTaskInstanceResult"> <select id="selectInspectionTaskInstanceList" parameterType="InspectionTaskInstance" resultMap="InspectionTaskInstanceResult">
@ -76,6 +77,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="startTime != null">start_time,</if> <if test="startTime != null">start_time,</if>
<if test="endTime != null">end_time,</if> <if test="endTime != null">end_time,</if>
<if test="taskInsId != null">task_ins_id,</if> <if test="taskInsId != null">task_ins_id,</if>
<if test="waypointCount != null">waypoint_count,</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},</if> <if test="id != null">#{id},</if>
@ -90,6 +92,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="startTime != null">#{startTime},</if> <if test="startTime != null">#{startTime},</if>
<if test="endTime != null">#{endTime},</if> <if test="endTime != null">#{endTime},</if>
<if test="taskInsId != null">#{taskInsId},</if> <if test="taskInsId != null">#{taskInsId},</if>
<if test="waypointCount != null">#{waypointCount},</if>
</trim> </trim>
</insert> </insert>
@ -107,6 +110,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="startTime != null">start_time = #{startTime},</if> <if test="startTime != null">start_time = #{startTime},</if>
<if test="endTime != null">end_time = #{endTime},</if> <if test="endTime != null">end_time = #{endTime},</if>
<if test="taskInsId != null">task_ins_id = #{taskInsId},</if> <if test="taskInsId != null">task_ins_id = #{taskInsId},</if>
<if test="waypointCount != null">waypoint_count = #{waypointCount},</if>
</trim> </trim>
where id = #{id} where id = #{id}
</update> </update>
@ -123,7 +127,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</delete> </delete>
<select id="selectInspectionTaskInstanceVoList" parameterType="InspectionTaskInstanceQuery" resultMap="InspectionTaskInstanceVoResult"> <select id="selectInspectionTaskInstanceVoList" parameterType="InspectionTaskInstanceQuery" resultMap="InspectionTaskInstanceVoResult">
select ti.id, ti.create_by, ti.create_time, ti.update_by, ti.update_time, ti.remark, select ti.id, ti.create_by, ti.create_time, ti.update_by, ti.update_time, ti.remark,ti.waypoint_count,
ti.task_id, t.task_name, t.task_code, ti.task_id, t.task_name, t.task_code,
ti.robot_id, r.robot_name, ti.robot_id, r.robot_name,
r.current_map_id as robot_current_map_id, m.map_name, r.current_map_id as robot_current_map_id, m.map_name,

View File

@ -36,7 +36,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
</resultMap> </resultMap>
<sql id="selectInspectionTaskVo"> <sql id="selectInspectionTaskVo">
select id, create_by, create_time, update_by, update_time, remark, task_code, task_name, task_type, task_config_id, map_id from inspection_task select id, create_by, create_time, update_by, update_time, remark, task_code, task_name, task_type, task_config_id, map_id, waypoint_count from inspection_task
</sql> </sql>
<select id="selectInspectionTaskList" parameterType="InspectionTask" resultMap="InspectionTaskResult"> <select id="selectInspectionTaskList" parameterType="InspectionTask" resultMap="InspectionTaskResult">
@ -67,6 +67,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="taskType != null">task_type,</if> <if test="taskType != null">task_type,</if>
<if test="taskConfigId != null">task_config_id,</if> <if test="taskConfigId != null">task_config_id,</if>
<if test="mapId != null">map_id,</if> <if test="mapId != null">map_id,</if>
<if test="waypointCount != null">waypoint_count,</if>
</trim> </trim>
<trim prefix="values (" suffix=")" suffixOverrides=","> <trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="id != null">#{id},</if> <if test="id != null">#{id},</if>
@ -80,6 +81,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="taskType != null">#{taskType},</if> <if test="taskType != null">#{taskType},</if>
<if test="taskConfigId != null">#{taskConfigId},</if> <if test="taskConfigId != null">#{taskConfigId},</if>
<if test="mapId != null">#{mapId},</if> <if test="mapId != null">#{mapId},</if>
<if test="waypointCount != null">#{waypointCount},</if>
</trim> </trim>
</insert> </insert>
@ -96,6 +98,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<if test="taskType != null">task_type = #{taskType},</if> <if test="taskType != null">task_type = #{taskType},</if>
<if test="taskConfigId != null">task_config_id = #{taskConfigId},</if> <if test="taskConfigId != null">task_config_id = #{taskConfigId},</if>
<if test="mapId != null">map_id = #{mapId},</if> <if test="mapId != null">map_id = #{mapId},</if>
<if test="waypointCount != null">waypoint_count = #{waypointCount},</if>
</trim> </trim>
where id = #{id} where id = #{id}
</update> </update>
@ -113,7 +116,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
<select id="selectInspectionTaskVoList" parameterType="InspectionTask" resultMap="InspectionTaskVoResult"> <select id="selectInspectionTaskVoList" parameterType="InspectionTask" resultMap="InspectionTaskVoResult">
select t.id, t.create_by, t.create_time, t.update_by, t.update_time, t.remark, select t.id, t.create_by, t.create_time, t.update_by, t.update_time, t.remark,
t.task_code, t.task_name, t.task_type, t.task_config_id, t.map_id, t.task_code, t.task_name, t.task_type, t.task_config_id, t.map_id, t.waypoint_count,
m.map_name, m.map_name,
u1.user_name as create_by_name, u2.user_name as update_by_name u1.user_name as create_by_name, u2.user_name as update_by_name
from inspection_task t from inspection_task t

View File

@ -40,14 +40,6 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
select id, create_by, create_time, update_by, update_time, remark, waypoint_name, enabled, sort_order, detect_item_id, map_id from inspection_waypoint select id, create_by, create_time, update_by, update_time, remark, waypoint_name, enabled, sort_order, detect_item_id, map_id from inspection_waypoint
</sql> </sql>
<select id="selectInspectionWaypointList" parameterType="InspectionWaypoint" resultMap="InspectionWaypointResult">
<include refid="selectInspectionWaypointVo"/>
<where>
<if test="waypointName != null and waypointName != ''"> and waypoint_name like concat('%', #{waypointName}, '%')</if>
<if test="enabled != null and enabled != ''"> and enabled = #{enabled}</if>
</where>
</select>
<select id="selectInspectionWaypointById" parameterType="String" resultMap="InspectionWaypointResult"> <select id="selectInspectionWaypointById" parameterType="String" resultMap="InspectionWaypointResult">
<include refid="selectInspectionWaypointVo"/> <include refid="selectInspectionWaypointVo"/>
where id = #{id} where id = #{id}

View File

@ -32,6 +32,11 @@ public class FlowExecutionEvent {
*/ */
private String taskId; private String taskId;
/**
* 节点数量
*/
private Integer nodeCount;
/** /**
* 当前检测项 ID * 当前检测项 ID
*/ */

View File

@ -40,6 +40,7 @@ public class FlowAfterInterceptor extends AbstractFlowMsgPreInterceptor{
.taskId(message.getTaskId()) .taskId(message.getTaskId())
.itemId(message.getItemId()) .itemId(message.getItemId())
.nodeId(message.getNodeId()) .nodeId(message.getNodeId())
.nodeCount(message.getGraph().allNodeIds().size())
.nodeType(message.getNodeType()) .nodeType(message.getNodeType())
.errorMessage(errorMessage) .errorMessage(errorMessage)
.build(); .build();

View File

@ -27,6 +27,7 @@ public class FlowBeforeInterceptor extends AbstractFlowMsgPreInterceptor{
.taskId(message.getTaskId()) .taskId(message.getTaskId())
.itemId(message.getItemId()) .itemId(message.getItemId())
.nodeId(message.getNodeId()) .nodeId(message.getNodeId())
.nodeCount(message.getGraph().allNodeIds().size())
.nodeName(message.getNodeName()) .nodeName(message.getNodeName())
.nodeType(message.getNodeType()) .nodeType(message.getNodeType())
.build(); .build();

View File

@ -57,6 +57,7 @@ CREATE TABLE `inspection_task` (
`task_type` char(1) DEFAULT '1' COMMENT '任务类型(1巡检任务 2讲解任务)', `task_type` char(1) DEFAULT '1' COMMENT '任务类型(1巡检任务 2讲解任务)',
`task_config_id` varchar(64) DEFAULT NULL COMMENT '任务配置ID', `task_config_id` varchar(64) DEFAULT NULL COMMENT '任务配置ID',
`map_id` varchar(64) DEFAULT NULL COMMENT '地图ID', `map_id` varchar(64) DEFAULT NULL COMMENT '地图ID',
`waypoint_count` int(11) DEFAULT '0' COMMENT '点位总数',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
UNIQUE KEY `uk_task_code` (`task_code`) UNIQUE KEY `uk_task_code` (`task_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='巡检任务表'; ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='巡检任务表';
@ -104,6 +105,7 @@ CREATE TABLE `inspection_task_instance` (
`start_time` datetime DEFAULT NULL COMMENT '开始时间', `start_time` datetime DEFAULT NULL COMMENT '开始时间',
`end_time` datetime DEFAULT NULL COMMENT '结束时间', `end_time` datetime DEFAULT NULL COMMENT '结束时间',
`task_ins_id` varchar(64) DEFAULT NULL COMMENT '检测任务id', `task_ins_id` varchar(64) DEFAULT NULL COMMENT '检测任务id',
`waypoint_count` int(11) DEFAULT '0' COMMENT '点位总数',
PRIMARY KEY (`id`), PRIMARY KEY (`id`),
KEY `idx_task_id` (`task_id`), KEY `idx_task_id` (`task_id`),
KEY `idx_robot_id` (`robot_id`), KEY `idx_robot_id` (`robot_id`),