新增删除
This commit is contained in:
@@ -13,14 +13,14 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 【通用线上监听器】为即将到来的任务创建内部“我的消息”记录。
|
||||
* 【通用线上监听器】为即将到来的任务创建内部“我的消息”记录。 知无涯1
|
||||
* <p>
|
||||
* 该监听器被设计为在SequenceFlow的'take'事件上触发。
|
||||
* 它会智能地从流程变量中读取单个接收人(变量名: approval)或多个接收人(变量名: userList),
|
||||
* 然后为每一位接收人创建一条内部消息。
|
||||
* </p>
|
||||
*/
|
||||
@Component("genericMessageListener") // 定义一个清晰、通用的Spring Bean名称
|
||||
@Component("genericMessageListener")
|
||||
@Slf4j
|
||||
public class GenericMessageListener implements ExecutionListener {
|
||||
|
||||
@@ -29,37 +29,41 @@ public class GenericMessageListener implements ExecutionListener {
|
||||
|
||||
@Override
|
||||
public void notify(DelegateExecution execution) {
|
||||
log.info("流程实例 [{}]: 触发通用消息监听器 (GenericMessageListener)...", execution.getProcessInstanceId());
|
||||
log.info("流程实例 [{}]: 触发通用消息监听器...", execution.getProcessInstanceId());
|
||||
|
||||
// 步骤 1: 智能地从流程变量中获取接收人ID列表
|
||||
List<Long> receiverIdList = getReceiverIds(execution);
|
||||
|
||||
// 如果没有找到任何接收人,则记录日志并直接返回
|
||||
if (receiverIdList.isEmpty()) {
|
||||
log.warn("流程实例 [{}]: 未能从流程变量中找到任何有效的接收人 (未能解析 'approval' 或 'userList' 变量),已跳过创建内部消息。", execution.getProcessInstanceId());
|
||||
return;
|
||||
}
|
||||
|
||||
// 步骤 2: 准备消息内容和发送人
|
||||
// 您可以根据业务需求,让消息内容更具动态性,比如从流程变量中获取任务标题
|
||||
// --- 关键改动:获取下一个即将创建的任务ID ---
|
||||
// 注意:在线上监听器中,任务尚未创建,所以我们无法直接获取任务ID。
|
||||
// 但我们可以获取到这个“活动”的定义ID,它在流程定义中是唯一的。
|
||||
String activityId = execution.getCurrentActivityId();
|
||||
|
||||
String taskName = execution.getCurrentFlowElement() != null ? execution.getCurrentFlowElement().getName() : "新";
|
||||
String messageContent = "您有一条新的【" + taskName + "】待办任务需要处理,<a href='http://zhxg.gxsdxy.cn/web/#/pages/Approval/index'>请点击前往处理</a>。";
|
||||
|
||||
// --- 关键改动:构建带有隐藏标识的消息内容 ---
|
||||
String messageText = "您有一条新的【" + taskName + "】待办任务需要处理,";
|
||||
// 我们嵌入一个隐藏的span,它包含了流程实例ID和活动ID作为唯一标识
|
||||
String hiddenIdentifier = String.format("<span id='flow-identifier' data-proc-inst-id='%s' data-activity-id='%s' style='display:none;'></span>",
|
||||
execution.getProcessInstanceId(),
|
||||
activityId);
|
||||
|
||||
String finalContent = messageText + hiddenIdentifier;
|
||||
|
||||
Long senderId = getSenderId();
|
||||
|
||||
// 步骤 3: 遍历所有接收人,并为每位用户创建一条内部消息
|
||||
for (Long receiverId : receiverIdList) {
|
||||
try {
|
||||
CphMsg cphMsg = new CphMsg();
|
||||
cphMsg.setReceiver(receiverId);
|
||||
cphMsg.setSender(senderId);
|
||||
cphMsg.setContent(messageContent);
|
||||
cphMsg.setContent(finalContent); // 使用包含隐藏标识的内容
|
||||
|
||||
// 调用您已有的服务插入消息
|
||||
cphMsgService.insertCphMsg(cphMsg);
|
||||
log.info("已成功为用户 [{}] 创建关于任务 [{}] 的内部消息。", receiverId, taskName);
|
||||
|
||||
log.info("已成功为用户 [{}] 创建内部消息 (关联 Activity ID: {})。", receiverId, activityId);
|
||||
} catch (Exception e) {
|
||||
// 捕获单个用户创建失败的异常,确保不影响其他人
|
||||
log.error("为用户 [{}] 创建内部消息时发生异常: {}", receiverId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,99 @@
|
||||
package com.srs.flowable.listener.disciplinary; // 您可以根据需要调整包路径
|
||||
|
||||
import com.srs.comprehensive.domain.CphMsg;
|
||||
import com.srs.comprehensive.service.ICphMsgService;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.flowable.task.service.delegate.DelegateTask;
|
||||
import org.flowable.task.service.delegate.TaskListener;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Component;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 【任务监听器】在任务完成后,删除内部消息。
|
||||
* <p>
|
||||
* 该监听器被设计为在UserTask的'complete'事件上触发。
|
||||
* 它通过解析消息内容中的隐藏HTML标识来找到与当前已完成任务关联的消息,
|
||||
* 并将其删除。
|
||||
* </p>
|
||||
*/
|
||||
@Component("messageProcessorListener") // 定义一个清晰的Bean名称
|
||||
@Slf4j
|
||||
public class MessageProcessorListener implements TaskListener {
|
||||
|
||||
@Autowired
|
||||
private ICphMsgService cphMsgService;
|
||||
|
||||
/**
|
||||
* 依赖检查方法,确保关键服务已注入。
|
||||
*/
|
||||
@PostConstruct
|
||||
public void checkDependencies() {
|
||||
Assert.notNull(cphMsgService, "ICphMsgService dependency not injected for MessageProcessorListener!");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notify(DelegateTask delegateTask) {
|
||||
// 步骤 1: 获取当前任务的办理人ID
|
||||
String assigneeIdStr = delegateTask.getAssignee();
|
||||
if (assigneeIdStr == null || assigneeIdStr.isEmpty()) {
|
||||
log.warn("任务 [ID: {}] 没有办理人,无法处理消息。", delegateTask.getId());
|
||||
return;
|
||||
}
|
||||
Long receiverId;
|
||||
try {
|
||||
receiverId = Long.parseLong(assigneeIdStr);
|
||||
} catch (NumberFormatException e) {
|
||||
log.error("任务办理人ID '{}' 无法转换为Long类型。", assigneeIdStr);
|
||||
return;
|
||||
}
|
||||
|
||||
// 步骤 2: 获取用于查找消息的唯一标识
|
||||
String processInstanceId = delegateTask.getProcessInstanceId();
|
||||
// taskDefinitionKey 对应流程图中节点的ID,即我之前在 GenericMessageListener 中存入的 activityId
|
||||
String activityId = delegateTask.getTaskDefinitionKey();
|
||||
|
||||
log.info("任务 [ID: {}, Name: {}] (办理人: {}) 已完成。开始查找并处理关联的内部消息...",
|
||||
delegateTask.getId(), delegateTask.getName(), receiverId);
|
||||
log.debug("用于查找的关联标识 -> ProcInst ID: [{}], Activity ID: [{}]", processInstanceId, activityId);
|
||||
|
||||
try {
|
||||
// 步骤 3: 构造用于模糊查询的、唯一的标识字符串
|
||||
// 这个字符串必须与 GenericMessageListener 中生成该标识的逻辑完全一致
|
||||
String searchIdentifier = String.format("data-proc-inst-id='%s' data-activity-id='%s'",
|
||||
processInstanceId,
|
||||
activityId);
|
||||
|
||||
// 步骤 4: 创建查询参数并调用服务
|
||||
CphMsg queryParam = new CphMsg();
|
||||
queryParam.setReceiver(receiverId);
|
||||
queryParam.setContent(searchIdentifier); // 将标识作为模糊查询的内容
|
||||
|
||||
// 注意:这一步要求 CphMsgMapper.xml 中的 selectCphMsgListForFlowable 方法支持对 content 字段的 LIKE 查询
|
||||
List<CphMsg> messagesToProcess = cphMsgService.selectCphMsgListForFlowable(queryParam);
|
||||
|
||||
if (messagesToProcess.isEmpty()) {
|
||||
log.info("未找到需要为用户 [{}] 处理的、与当前任务关联的消息。", receiverId);
|
||||
return;
|
||||
}
|
||||
|
||||
// 步骤 5: 遍历所有找到的消息,并进行处理(删除)
|
||||
for (CphMsg msg : messagesToProcess) {
|
||||
try {
|
||||
cphMsgService.deleteCphMsgById(msg.getId());
|
||||
log.info("已成功删除与任务关联的消息 [ID: {}]。", msg.getId());
|
||||
} catch (Exception e) {
|
||||
// 捕获单个消息删除失败的异常,确保不影响其他消息的处理
|
||||
log.error("删除消息 [ID: {}] 时发生异常: {}", msg.getId(), e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
// 捕获整个处理过程中的异常,确保不影响主流程的流转
|
||||
log.error("处理用户 [{}] 的内部消息时发生严重异常: {}", receiverId, e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user