update 优化 重构将 WorkflowUtils 工具类改为 FlwCommonService 更通用的业务处理

This commit is contained in:
疯狂的狮子Li
2025-03-06 17:22:24 +08:00
parent eb96432a2f
commit 2a231ec72c
8 changed files with 299 additions and 223 deletions

View File

@@ -3,6 +3,8 @@ package org.dromara.resource.api;
import lombok.RequiredArgsConstructor; import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import java.util.List;
/** /**
* 消息服务 * 消息服务
* *
@@ -21,7 +23,7 @@ public class RemoteMessageServiceStub implements RemoteMessageService {
* @param message 消息文本 * @param message 消息文本
*/ */
@Override @Override
public void publishMessage(Long sessionKey, String message) { public void publishMessage(List<Long> sessionKey, String message) {
try { try {
remoteMessageService.publishMessage(sessionKey, message); remoteMessageService.publishMessage(sessionKey, message);
} catch (Exception e) { } catch (Exception e) {

View File

@@ -102,7 +102,7 @@ public class TokenController {
Long userId = LoginHelper.getUserId(); Long userId = LoginHelper.getUserId();
scheduledExecutorService.schedule(() -> { scheduledExecutorService.schedule(() -> {
remoteMessageService.publishMessage(userId, "欢迎登录RuoYi-Cloud-Plus微服务管理系统"); remoteMessageService.publishMessage(List.of(userId), "欢迎登录RuoYi-Cloud-Plus微服务管理系统");
}, 3, TimeUnit.SECONDS); }, 3, TimeUnit.SECONDS);
return R.ok(loginVo); return R.ok(loginVo);
} }

View File

@@ -0,0 +1,58 @@
package org.dromara.workflow.service;
import org.dromara.warm.flow.core.entity.User;
import java.util.List;
import java.util.Set;
/**
* 通用 工作流服务
*
* @author LionLi
*/
public interface IFlwCommonService {
/**
* 构建工作流用户
*
* @param userList 办理用户
* @param taskId 任务ID
* @return 用户
*/
Set<User> buildUser(List<User> userList, Long taskId);
/**
* 发送消息
*
* @param flowName 流程定义名称
* @param messageType 消息类型
* @param message 消息内容,为空则发送默认配置的消息内容
*/
void sendMessage(String flowName, Long instId, List<String> messageType, String message);
/**
* 驳回
*
* @param message 审批意见
* @param instanceId 流程实例id
* @param targetNodeCode 目标节点
* @param flowStatus 流程状态
* @param flowHisStatus 节点操作状态
*/
void backTask(String message, Long instanceId, String targetNodeCode, String flowStatus, String flowHisStatus);
/**
* 申请人节点编码
*
* @param definitionId 流程定义id
* @return 申请人节点编码
*/
String applyNodeCode(Long definitionId);
/**
* 删除运行中的任务
*
* @param taskIds 任务id
*/
void deleteRunTask(List<Long> taskIds);
}

View File

@@ -0,0 +1,214 @@
package org.dromara.workflow.service.impl;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.dubbo.config.annotation.DubboReference;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.resource.api.RemoteMailService;
import org.dromara.resource.api.RemoteMessageService;
import org.dromara.system.api.domain.vo.RemoteUserVo;
import org.dromara.warm.flow.core.constant.ExceptionCons;
import org.dromara.warm.flow.core.dto.FlowParams;
import org.dromara.warm.flow.core.entity.Node;
import org.dromara.warm.flow.core.entity.Task;
import org.dromara.warm.flow.core.entity.User;
import org.dromara.warm.flow.core.enums.NodeType;
import org.dromara.warm.flow.core.enums.SkipType;
import org.dromara.warm.flow.core.service.NodeService;
import org.dromara.warm.flow.core.service.TaskService;
import org.dromara.warm.flow.core.service.UserService;
import org.dromara.warm.flow.core.utils.AssertUtil;
import org.dromara.warm.flow.orm.entity.FlowNode;
import org.dromara.warm.flow.orm.entity.FlowTask;
import org.dromara.warm.flow.orm.entity.FlowUser;
import org.dromara.warm.flow.orm.mapper.FlowNodeMapper;
import org.dromara.warm.flow.orm.mapper.FlowTaskMapper;
import org.dromara.workflow.common.ConditionalOnEnable;
import org.dromara.workflow.common.enums.MessageTypeEnum;
import org.dromara.workflow.service.IFlwCommonService;
import org.dromara.workflow.service.IFlwTaskAssigneeService;
import org.dromara.workflow.service.IFlwTaskService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 工作流工具
*
* @author LionLi
*/
@ConditionalOnEnable
@Slf4j
@RequiredArgsConstructor
@Service
public class FlwCommonServiceImpl implements IFlwCommonService {
private final FlowNodeMapper flowNodeMapper;
private final FlowTaskMapper flowTaskMapper;
private final UserService userService;
private final TaskService taskService;
private final NodeService nodeService;
@DubboReference
private RemoteMessageService remoteMessageService;
@DubboReference
private RemoteMailService remoteMailService;
/**
* 构建工作流用户
*
* @param userList 办理用户
* @param taskId 任务ID
* @return 用户
*/
@Override
public Set<User> buildUser(List<User> userList, Long taskId) {
if (CollUtil.isEmpty(userList)) {
return Set.of();
}
Set<User> list = new HashSet<>();
Set<String> processedBySet = new HashSet<>();
for (User user : userList) {
IFlwTaskAssigneeService taskAssigneeService = SpringUtils.getBean(IFlwTaskAssigneeService.class);
// 根据 processedBy 前缀判断处理人类型,分别获取用户列表
List<RemoteUserVo> users = taskAssigneeService.fetchUsersByStorageId(user.getProcessedBy());
// 转换为 FlowUser 并添加到结果集合
if (CollUtil.isNotEmpty(users)) {
users.forEach(dto -> {
String processedBy = String.valueOf(dto.getUserId());
if (!processedBySet.contains(processedBy)) {
FlowUser flowUser = new FlowUser();
flowUser.setType(user.getType());
flowUser.setProcessedBy(processedBy);
flowUser.setAssociated(taskId);
list.add(flowUser);
processedBySet.add(processedBy);
}
});
}
}
return list;
}
/**
* 发送消息
*
* @param flowName 流程定义名称
* @param messageType 消息类型
* @param message 消息内容,为空则发送默认配置的消息内容
*/
@Override
public void sendMessage(String flowName, Long instId, List<String> messageType, String message) {
IFlwTaskService flwTaskService = SpringUtils.getBean(IFlwTaskService.class);
List<RemoteUserVo> userList = new ArrayList<>();
List<FlowTask> list = flwTaskService.selectByInstId(instId);
if (StringUtils.isBlank(message)) {
message = "有新的【" + flowName + "】单据已经提交至您,请您及时处理。";
}
for (Task task : list) {
List<RemoteUserVo> users = flwTaskService.currentTaskAllUser(task.getId());
if (CollUtil.isNotEmpty(users)) {
userList.addAll(users);
}
}
if (CollUtil.isNotEmpty(userList)) {
for (String code : messageType) {
MessageTypeEnum messageTypeEnum = MessageTypeEnum.getByCode(code);
if (ObjectUtil.isNotEmpty(messageTypeEnum)) {
switch (messageTypeEnum) {
case SYSTEM_MESSAGE:
List<Long> userIds = StreamUtils.toList(userList, RemoteUserVo::getUserId).stream().distinct().collect(Collectors.toList());
remoteMessageService.publishMessage(userIds, message);
break;
case EMAIL_MESSAGE:
remoteMailService.send(StreamUtils.join(userList, RemoteUserVo::getEmail), "单据审批提醒", message);
break;
case SMS_MESSAGE:
//todo 短信发送
break;
default:
throw new IllegalStateException("Unexpected value: " + messageTypeEnum);
}
}
}
}
}
/**
* 驳回
*
* @param message 审批意见
* @param instanceId 流程实例id
* @param targetNodeCode 目标节点
* @param flowStatus 流程状态
* @param flowHisStatus 节点操作状态
*/
@Override
public void backTask(String message, Long instanceId, String targetNodeCode, String flowStatus, String flowHisStatus) {
IFlwTaskService flwTaskService = SpringUtils.getBean(IFlwTaskService.class);
List<FlowTask> list = flwTaskService.selectByInstId(instanceId);
if (CollUtil.isNotEmpty(list)) {
List<FlowTask> tasks = StreamUtils.filter(list, e -> e.getNodeCode().equals(targetNodeCode));
if (list.size() == tasks.size()) {
return;
}
}
for (FlowTask task : list) {
List<RemoteUserVo> userList = flwTaskService.currentTaskAllUser(task.getId());
FlowParams flowParams = FlowParams.build();
flowParams.nodeCode(targetNodeCode);
flowParams.message(message);
flowParams.skipType(SkipType.PASS.getKey());
flowParams.flowStatus(flowStatus).hisStatus(flowHisStatus);
flowParams.ignore(true);
//解决会签没权限问题
if (CollUtil.isNotEmpty(userList)) {
flowParams.handler(userList.get(0).getUserId().toString());
}
taskService.skip(task.getId(), flowParams);
}
//解决会签多人审批问题
backTask(message, instanceId, targetNodeCode, flowStatus, flowHisStatus);
}
/**
* 申请人节点编码
*
* @param definitionId 流程定义id
* @return 申请人节点编码
*/
@Override
public String applyNodeCode(Long definitionId) {
//获取已发布的流程节点
List<FlowNode> flowNodes = flowNodeMapper.selectList(new LambdaQueryWrapper<FlowNode>().eq(FlowNode::getDefinitionId, definitionId));
AssertUtil.isTrue(CollUtil.isEmpty(flowNodes), ExceptionCons.NOT_PUBLISH_NODE);
Node startNode = flowNodes.stream().filter(t -> NodeType.isStart(t.getNodeType())).findFirst().orElse(null);
AssertUtil.isNull(startNode, ExceptionCons.LOST_START_NODE);
Node nextNode = nodeService.getNextNode(definitionId, startNode.getNodeCode(), null, SkipType.PASS.getKey());
return nextNode.getNodeCode();
}
/**
* 删除运行中的任务
*
* @param taskIds 任务id
*/
@Override
public void deleteRunTask(List<Long> taskIds) {
if (CollUtil.isEmpty(taskIds)) {
return;
}
userService.deleteByTaskIds(taskIds);
flowTaskMapper.deleteByIds(taskIds);
}
}

View File

@@ -33,8 +33,8 @@ import org.dromara.workflow.common.constant.FlowConstant;
import org.dromara.workflow.domain.FlowCategory; import org.dromara.workflow.domain.FlowCategory;
import org.dromara.workflow.domain.vo.FlowDefinitionVo; import org.dromara.workflow.domain.vo.FlowDefinitionVo;
import org.dromara.workflow.mapper.FlwCategoryMapper; import org.dromara.workflow.mapper.FlwCategoryMapper;
import org.dromara.workflow.service.IFlwCommonService;
import org.dromara.workflow.service.IFlwDefinitionService; import org.dromara.workflow.service.IFlwDefinitionService;
import org.dromara.workflow.utils.WorkflowUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@@ -64,6 +64,7 @@ public class FlwDefinitionServiceImpl implements IFlwDefinitionService {
private final FlowNodeMapper flowNodeMapper; private final FlowNodeMapper flowNodeMapper;
private final FlowSkipMapper flowSkipMapper; private final FlowSkipMapper flowSkipMapper;
private final FlwCategoryMapper flwCategoryMapper; private final FlwCategoryMapper flwCategoryMapper;
private final IFlwCommonService flwCommonService;
/** /**
* 查询流程定义列表 * 查询流程定义列表
@@ -125,7 +126,7 @@ public class FlwDefinitionServiceImpl implements IFlwDefinitionService {
List<String> errorMsg = new ArrayList<>(); List<String> errorMsg = new ArrayList<>();
if (CollUtil.isNotEmpty(flowNodes)) { if (CollUtil.isNotEmpty(flowNodes)) {
for (FlowNode flowNode : flowNodes) { for (FlowNode flowNode : flowNodes) {
String applyNodeCode = WorkflowUtils.applyNodeCode(id); String applyNodeCode = flwCommonService.applyNodeCode(id);
if (StringUtils.isBlank(flowNode.getPermissionFlag()) && !applyNodeCode.equals(flowNode.getNodeCode()) && NodeType.BETWEEN.getKey().equals(flowNode.getNodeType())) { if (StringUtils.isBlank(flowNode.getPermissionFlag()) && !applyNodeCode.equals(flowNode.getNodeCode()) && NodeType.BETWEEN.getKey().equals(flowNode.getNodeType())) {
errorMsg.add(flowNode.getNodeName()); errorMsg.add(flowNode.getNodeName());
} }

View File

@@ -46,9 +46,9 @@ import org.dromara.workflow.domain.vo.FlowVariableVo;
import org.dromara.workflow.handler.FlowProcessEventHandler; import org.dromara.workflow.handler.FlowProcessEventHandler;
import org.dromara.workflow.mapper.FlwCategoryMapper; import org.dromara.workflow.mapper.FlwCategoryMapper;
import org.dromara.workflow.mapper.FlwInstanceMapper; import org.dromara.workflow.mapper.FlwInstanceMapper;
import org.dromara.workflow.service.IFlwCommonService;
import org.dromara.workflow.service.IFlwInstanceService; import org.dromara.workflow.service.IFlwInstanceService;
import org.dromara.workflow.service.IFlwTaskService; import org.dromara.workflow.service.IFlwTaskService;
import org.dromara.workflow.utils.WorkflowUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -76,6 +76,7 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
private final IFlwTaskService flwTaskService; private final IFlwTaskService flwTaskService;
private final FlwInstanceMapper flwInstanceMapper; private final FlwInstanceMapper flwInstanceMapper;
private final FlwCategoryMapper flwCategoryMapper; private final FlwCategoryMapper flwCategoryMapper;
private final IFlwCommonService flwCommonService;
/** /**
* 分页查询正在运行的流程实例 * 分页查询正在运行的流程实例
@@ -245,15 +246,15 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
} }
String message = bo.getMessage(); String message = bo.getMessage();
BusinessStatusEnum.checkCancelStatus(instance.getFlowStatus()); BusinessStatusEnum.checkCancelStatus(instance.getFlowStatus());
String applyNodeCode = WorkflowUtils.applyNodeCode(definition.getId()); String applyNodeCode = flwCommonService.applyNodeCode(definition.getId());
//撤销 //撤销
WorkflowUtils.backTask(message, instance.getId(), applyNodeCode, BusinessStatusEnum.CANCEL.getStatus(), BusinessStatusEnum.CANCEL.getStatus()); flwCommonService.backTask(message, instance.getId(), applyNodeCode, BusinessStatusEnum.CANCEL.getStatus(), BusinessStatusEnum.CANCEL.getStatus());
//判断或签节点是否有多个,只保留一个 //判断或签节点是否有多个,只保留一个
List<Task> currentTaskList = taskService.list(FlowEngine.newTask().setInstanceId(instance.getId())); List<Task> currentTaskList = taskService.list(FlowEngine.newTask().setInstanceId(instance.getId()));
if (CollUtil.isNotEmpty(currentTaskList)) { if (CollUtil.isNotEmpty(currentTaskList)) {
if (currentTaskList.size() > 1) { if (currentTaskList.size() > 1) {
currentTaskList.remove(0); currentTaskList.remove(0);
WorkflowUtils.deleteRunTask(StreamUtils.toList(currentTaskList, Task::getId)); flwCommonService.deleteRunTask(StreamUtils.toList(currentTaskList, Task::getId));
} }
} }

View File

@@ -23,8 +23,6 @@ import org.dromara.common.core.validate.EditGroup;
import org.dromara.common.mybatis.core.page.PageQuery; import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo; import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper; import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.resource.api.RemoteMailService;
import org.dromara.resource.api.RemoteMessageService;
import org.dromara.system.api.RemoteUserService; import org.dromara.system.api.RemoteUserService;
import org.dromara.system.api.domain.vo.RemoteUserVo; import org.dromara.system.api.domain.vo.RemoteUserVo;
import org.dromara.warm.flow.core.dto.FlowParams; import org.dromara.warm.flow.core.dto.FlowParams;
@@ -38,7 +36,6 @@ import org.dromara.warm.flow.orm.mapper.FlowInstanceMapper;
import org.dromara.warm.flow.orm.mapper.FlowTaskMapper; import org.dromara.warm.flow.orm.mapper.FlowTaskMapper;
import org.dromara.workflow.api.domain.RemoteStartProcessReturn; import org.dromara.workflow.api.domain.RemoteStartProcessReturn;
import org.dromara.workflow.common.ConditionalOnEnable; import org.dromara.workflow.common.ConditionalOnEnable;
import org.dromara.workflow.common.enums.MessageTypeEnum;
import org.dromara.workflow.common.enums.TaskAssigneeType; import org.dromara.workflow.common.enums.TaskAssigneeType;
import org.dromara.workflow.common.enums.TaskStatusEnum; import org.dromara.workflow.common.enums.TaskStatusEnum;
import org.dromara.workflow.domain.bo.*; import org.dromara.workflow.domain.bo.*;
@@ -48,8 +45,8 @@ import org.dromara.workflow.handler.FlowProcessEventHandler;
import org.dromara.workflow.handler.WorkflowPermissionHandler; import org.dromara.workflow.handler.WorkflowPermissionHandler;
import org.dromara.workflow.mapper.FlwCategoryMapper; import org.dromara.workflow.mapper.FlwCategoryMapper;
import org.dromara.workflow.mapper.FlwTaskMapper; import org.dromara.workflow.mapper.FlwTaskMapper;
import org.dromara.workflow.service.IFlwCommonService;
import org.dromara.workflow.service.IFlwTaskService; import org.dromara.workflow.service.IFlwTaskService;
import org.dromara.workflow.utils.WorkflowUtils;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
@@ -73,6 +70,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
private final TaskService taskService; private final TaskService taskService;
private final InsService insService; private final InsService insService;
private final DefService defService; private final DefService defService;
private final UserService userService;
private final HisTaskService hisTaskService; private final HisTaskService hisTaskService;
private final NodeService nodeService; private final NodeService nodeService;
private final FlowInstanceMapper flowInstanceMapper; private final FlowInstanceMapper flowInstanceMapper;
@@ -82,13 +80,10 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
private final FlowProcessEventHandler flowProcessEventHandler; private final FlowProcessEventHandler flowProcessEventHandler;
private final FlwTaskMapper flwTaskMapper; private final FlwTaskMapper flwTaskMapper;
private final FlwCategoryMapper flwCategoryMapper; private final FlwCategoryMapper flwCategoryMapper;
private final IFlwCommonService flwCommonService;
@DubboReference @DubboReference
private RemoteUserService remoteUserService; private RemoteUserService remoteUserService;
@DubboReference
private RemoteMessageService remoteMessageService;
@DubboReference
private RemoteMailService remoteMailService;
/** /**
* 启动任务 * 启动任务
@@ -177,7 +172,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
Instance instance = taskService.skip(taskId, flowParams); Instance instance = taskService.skip(taskId, flowParams);
this.setHandler(instance, flowTask, flowCopyList); this.setHandler(instance, flowTask, flowCopyList);
// 消息通知 // 消息通知
this.sendMessage(definition.getFlowName(), ins.getId(), messageType, notice); flwCommonService.sendMessage(definition.getFlowName(), ins.getId(), messageType, notice);
return true; return true;
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
@@ -205,7 +200,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
} }
List<Long> taskIdList = StreamUtils.toList(flowTasks, FlowTask::getId); List<Long> taskIdList = StreamUtils.toList(flowTasks, FlowTask::getId);
// 获取与当前任务关联的用户列表 // 获取与当前任务关联的用户列表
List<User> associatedUsers = WorkflowUtils.getFlowUserService().getByAssociateds(taskIdList); List<User> associatedUsers = userService.getByAssociateds(taskIdList);
if (CollUtil.isEmpty(associatedUsers)) { if (CollUtil.isEmpty(associatedUsers)) {
return; return;
} }
@@ -214,16 +209,16 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
for (FlowTask flowTask : flowTasks) { for (FlowTask flowTask : flowTasks) {
List<User> users = StreamUtils.filter(associatedUsers, user -> Objects.equals(user.getAssociated(), flowTask.getId())); List<User> users = StreamUtils.filter(associatedUsers, user -> Objects.equals(user.getAssociated(), flowTask.getId()));
if (CollUtil.isNotEmpty(users)) { if (CollUtil.isNotEmpty(users)) {
userList.addAll(WorkflowUtils.buildUser(users, flowTask.getId())); userList.addAll(flwCommonService.buildUser(users, flowTask.getId()));
} }
} }
// 批量删除现有任务的办理人记录 // 批量删除现有任务的办理人记录
WorkflowUtils.getFlowUserService().deleteByTaskIds(taskIdList); userService.deleteByTaskIds(taskIdList);
// 确保要保存的 userList 不为空 // 确保要保存的 userList 不为空
if (CollUtil.isEmpty(userList)) { if (CollUtil.isEmpty(userList)) {
return; return;
} }
WorkflowUtils.getFlowUserService().saveBatch(userList); userService.saveBatch(userList);
} }
/** /**
@@ -263,7 +258,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
return flowUser; return flowUser;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
// 批量保存抄送人员 // 批量保存抄送人员
WorkflowUtils.getFlowUserService().saveBatch(userList); userService.saveBatch(userList);
} }
/** /**
@@ -391,7 +386,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
BusinessStatusEnum.checkBackStatus(inst.getFlowStatus()); BusinessStatusEnum.checkBackStatus(inst.getFlowStatus());
Long definitionId = task.getDefinitionId(); Long definitionId = task.getDefinitionId();
Definition definition = defService.getById(definitionId); Definition definition = defService.getById(definitionId);
String applyNodeCode = WorkflowUtils.applyNodeCode(definitionId); String applyNodeCode = flwCommonService.applyNodeCode(definitionId);
FlowParams flowParams = FlowParams.build(); FlowParams flowParams = FlowParams.build();
flowParams.nodeCode(bo.getNodeCode()); flowParams.nodeCode(bo.getNodeCode());
flowParams.message(message); flowParams.message(message);
@@ -404,7 +399,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
Instance instance = insService.getById(inst.getId()); Instance instance = insService.getById(inst.getId());
this.setHandler(instance, task, null); this.setHandler(instance, task, null);
// 消息通知 // 消息通知
this.sendMessage(definition.getFlowName(), instance.getId(), messageType, notice); flwCommonService.sendMessage(definition.getFlowName(), instance.getId(), messageType, notice);
return true; return true;
} catch (Exception e) { } catch (Exception e) {
log.error(e.getMessage(), e); log.error(e.getMessage(), e);
@@ -638,7 +633,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
List<FlowTask> flowTasks = this.selectByIdList(taskIdList); List<FlowTask> flowTasks = this.selectByIdList(taskIdList);
// 批量删除现有任务的办理人记录 // 批量删除现有任务的办理人记录
if (CollUtil.isNotEmpty(flowTasks)) { if (CollUtil.isNotEmpty(flowTasks)) {
WorkflowUtils.getFlowUserService().deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId)); userService.deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId));
List<User> userList = flowTasks.stream() List<User> userList = flowTasks.stream()
.map(flowTask -> { .map(flowTask -> {
FlowUser flowUser = new FlowUser(); FlowUser flowUser = new FlowUser();
@@ -649,7 +644,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
}) })
.collect(Collectors.toList()); .collect(Collectors.toList());
if (CollUtil.isNotEmpty(userList)) { if (CollUtil.isNotEmpty(userList)) {
WorkflowUtils.getFlowUserService().saveBatch(userList); userService.saveBatch(userList);
} }
} }
} catch (Exception e) { } catch (Exception e) {
@@ -668,7 +663,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
public Map<Long, List<RemoteUserVo>> currentTaskAllUser(List<Long> taskIdList) { public Map<Long, List<RemoteUserVo>> currentTaskAllUser(List<Long> taskIdList) {
Map<Long, List<RemoteUserVo>> map = new HashMap<>(); Map<Long, List<RemoteUserVo>> map = new HashMap<>();
// 获取与当前任务关联的用户列表 // 获取与当前任务关联的用户列表
List<User> associatedUsers = WorkflowUtils.getFlowUserService().getByAssociateds(taskIdList); List<User> associatedUsers = userService.getByAssociateds(taskIdList);
Map<Long, List<User>> listMap = StreamUtils.groupByKey(associatedUsers, User::getAssociated); Map<Long, List<User>> listMap = StreamUtils.groupByKey(associatedUsers, User::getAssociated);
for (Map.Entry<Long, List<User>> entry : listMap.entrySet()) { for (Map.Entry<Long, List<User>> entry : listMap.entrySet()) {
List<User> value = entry.getValue(); List<User> value = entry.getValue();
@@ -688,53 +683,11 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
@Override @Override
public List<RemoteUserVo> currentTaskAllUser(Long taskId) { public List<RemoteUserVo> currentTaskAllUser(Long taskId) {
// 获取与当前任务关联的用户列表 // 获取与当前任务关联的用户列表
List<User> userList = WorkflowUtils.getFlowUserService().getByAssociateds(Collections.singletonList(taskId)); List<User> userList = userService.getByAssociateds(Collections.singletonList(taskId));
if (CollUtil.isEmpty(userList)) { if (CollUtil.isEmpty(userList)) {
return Collections.emptyList(); return Collections.emptyList();
} }
return remoteUserService.selectListByIds(StreamUtils.toList(userList, e -> Long.valueOf(e.getProcessedBy()))); return remoteUserService.selectListByIds(StreamUtils.toList(userList, e -> Long.valueOf(e.getProcessedBy())));
} }
/**
* 发送消息
*
* @param flowName 流程定义名称
* @param messageType 消息类型
* @param message 消息内容,为空则发送默认配置的消息内容
*/
private void sendMessage(String flowName, Long instId, List<String> messageType, String message) {
List<RemoteUserVo> userList = new ArrayList<>();
List<FlowTask> list = this.selectByInstId(instId);
if (StringUtils.isBlank(message)) {
message = "有新的【" + flowName + "】单据已经提交至您,请您及时处理。";
}
for (Task task : list) {
List<RemoteUserVo> users = this.currentTaskAllUser(task.getId());
if (CollUtil.isNotEmpty(users)) {
userList.addAll(users);
}
}
if (CollUtil.isNotEmpty(userList)) {
for (String code : messageType) {
MessageTypeEnum messageTypeEnum = MessageTypeEnum.getByCode(code);
if (ObjectUtil.isNotEmpty(messageTypeEnum)) {
switch (messageTypeEnum) {
case SYSTEM_MESSAGE:
List<Long> userIds = StreamUtils.toList(userList, RemoteUserVo::getUserId).stream().distinct().collect(Collectors.toList());
remoteMessageService.publishMessage(userIds, message);
break;
case EMAIL_MESSAGE:
remoteMailService.send(StreamUtils.join(userList, RemoteUserVo::getEmail), "单据审批提醒", message);
break;
case SMS_MESSAGE:
//todo 短信发送
break;
default:
throw new IllegalStateException("Unexpected value: " + messageTypeEnum);
}
}
}
}
}
} }

View File

@@ -1,153 +0,0 @@
package org.dromara.workflow.utils;
import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.system.api.domain.vo.RemoteUserVo;
import org.dromara.warm.flow.core.constant.ExceptionCons;
import org.dromara.warm.flow.core.dto.FlowParams;
import org.dromara.warm.flow.core.entity.Node;
import org.dromara.warm.flow.core.entity.User;
import org.dromara.warm.flow.core.enums.NodeType;
import org.dromara.warm.flow.core.enums.SkipType;
import org.dromara.warm.flow.core.service.NodeService;
import org.dromara.warm.flow.core.service.TaskService;
import org.dromara.warm.flow.core.service.UserService;
import org.dromara.warm.flow.core.utils.AssertUtil;
import org.dromara.warm.flow.orm.entity.FlowNode;
import org.dromara.warm.flow.orm.entity.FlowTask;
import org.dromara.warm.flow.orm.entity.FlowUser;
import org.dromara.warm.flow.orm.mapper.FlowNodeMapper;
import org.dromara.warm.flow.orm.mapper.FlowTaskMapper;
import org.dromara.workflow.service.IFlwTaskAssigneeService;
import org.dromara.workflow.service.IFlwTaskService;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
/**
* 工作流工具
*
* @author may
*/
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class WorkflowUtils {
private static final IFlwTaskAssigneeService TASK_ASSIGNEE_SERVICE = SpringUtils.getBean(IFlwTaskAssigneeService.class);
private static final IFlwTaskService FLW_TASK_SERVICE = SpringUtils.getBean(IFlwTaskService.class);
private static final FlowNodeMapper FLOW_NODE_MAPPER = SpringUtils.getBean(FlowNodeMapper.class);
private static final FlowTaskMapper FLOW_TASK_MAPPER = SpringUtils.getBean(FlowTaskMapper.class);
private static final UserService USER_SERVICE = SpringUtils.getBean(UserService.class);
private static final TaskService TASK_SERVICE = SpringUtils.getBean(TaskService.class);
private static final NodeService NODE_SERVICE = SpringUtils.getBean(NodeService.class);
/**
* 获取工作流用户service
*/
public static UserService getFlowUserService() {
return USER_SERVICE;
}
/**
* 构建工作流用户
*
* @param userList 办理用户
* @param taskId 任务ID
* @return 用户
*/
public static Set<User> buildUser(List<User> userList, Long taskId) {
if (CollUtil.isEmpty(userList)) {
return Set.of();
}
Set<User> list = new HashSet<>();
Set<String> processedBySet = new HashSet<>();
for (User user : userList) {
// 根据 processedBy 前缀判断处理人类型,分别获取用户列表
List<RemoteUserVo> users = TASK_ASSIGNEE_SERVICE.fetchUsersByStorageId(user.getProcessedBy());
// 转换为 FlowUser 并添加到结果集合
if (CollUtil.isNotEmpty(users)) {
users.forEach(dto -> {
String processedBy = String.valueOf(dto.getUserId());
if (!processedBySet.contains(processedBy)) {
FlowUser flowUser = new FlowUser();
flowUser.setType(user.getType());
flowUser.setProcessedBy(processedBy);
flowUser.setAssociated(taskId);
list.add(flowUser);
processedBySet.add(processedBy);
}
});
}
}
return list;
}
/**
* 驳回
*
* @param message 审批意见
* @param instanceId 流程实例id
* @param targetNodeCode 目标节点
* @param flowStatus 流程状态
* @param flowHisStatus 节点操作状态
*/
public static void backTask(String message, Long instanceId, String targetNodeCode, String flowStatus, String flowHisStatus) {
List<FlowTask> list = FLW_TASK_SERVICE.selectByInstId(instanceId);
if (CollUtil.isNotEmpty(list)) {
List<FlowTask> tasks = StreamUtils.filter(list, e -> e.getNodeCode().equals(targetNodeCode));
if (list.size() == tasks.size()) {
return;
}
}
for (FlowTask task : list) {
List<RemoteUserVo> userList = FLW_TASK_SERVICE.currentTaskAllUser(task.getId());
FlowParams flowParams = FlowParams.build();
flowParams.nodeCode(targetNodeCode);
flowParams.message(message);
flowParams.skipType(SkipType.PASS.getKey());
flowParams.flowStatus(flowStatus).hisStatus(flowHisStatus);
flowParams.ignore(true);
//解决会签没权限问题
if (CollUtil.isNotEmpty(userList)) {
flowParams.handler(userList.get(0).getUserId().toString());
}
TASK_SERVICE.skip(task.getId(), flowParams);
}
//解决会签多人审批问题
backTask(message, instanceId, targetNodeCode, flowStatus, flowHisStatus);
}
/**
* 申请人节点编码
*
* @param definitionId 流程定义id
* @return 申请人节点编码
*/
public static String applyNodeCode(Long definitionId) {
//获取已发布的流程节点
List<FlowNode> flowNodes = FLOW_NODE_MAPPER.selectList(new LambdaQueryWrapper<FlowNode>().eq(FlowNode::getDefinitionId, definitionId));
AssertUtil.isTrue(CollUtil.isEmpty(flowNodes), ExceptionCons.NOT_PUBLISH_NODE);
Node startNode = flowNodes.stream().filter(t -> NodeType.isStart(t.getNodeType())).findFirst().orElse(null);
AssertUtil.isNull(startNode, ExceptionCons.LOST_START_NODE);
Node nextNode = NODE_SERVICE.getNextNode(definitionId, startNode.getNodeCode(), null, SkipType.PASS.getKey());
return nextNode.getNodeCode();
}
/**
* 删除运行中的任务
*
* @param taskIds 任务id
*/
public static void deleteRunTask(List<Long> taskIds) {
if (CollUtil.isEmpty(taskIds)) {
return;
}
USER_SERVICE.deleteByTaskIds(taskIds);
FLOW_TASK_MAPPER.deleteByIds(taskIds);
}
}