update 调整并行环节撤销错误 增加办理校验

This commit is contained in:
gssong 2024-12-15 14:11:01 +08:00
parent 1383a3a3b1
commit 0e96074dac
5 changed files with 148 additions and 29 deletions

View File

@ -3,6 +3,7 @@ package org.dromara.common.core.enums;
import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor;
import lombok.Getter;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.utils.StringUtils;
import java.util.ArrayList;
@ -141,4 +142,82 @@ public enum BusinessStatusEnum {
return list;
}
/**
* 启动流程校验
*
* @param status 状态
*/
public static void checkStartStatus(String status) {
if (WAITING.getStatus().equals(status)) {
throw new ServiceException("该单据已提交过申请,正在审批中!");
} else if (FINISH.getStatus().equals(status)) {
throw new ServiceException("该单据已完成申请!");
} else if (INVALID.getStatus().equals(status)) {
throw new ServiceException("该单据已作废!");
} else if (TERMINATION.getStatus().equals(status)) {
throw new ServiceException("该单据已终止!");
} else if (StringUtils.isBlank(status)) {
throw new ServiceException("流程状态为空!");
}
}
/**
* 撤销流程校验
*
* @param status 状态
*/
public static void checkCancelStatus(String status) {
if (CANCEL.getStatus().equals(status)) {
throw new ServiceException("该单据已撤销!");
} else if (FINISH.getStatus().equals(status)) {
throw new ServiceException("该单据已完成申请!");
} else if (INVALID.getStatus().equals(status)) {
throw new ServiceException("该单据已作废!");
} else if (TERMINATION.getStatus().equals(status)) {
throw new ServiceException("该单据已终止!");
} else if (BACK.getStatus().equals(status)) {
throw new ServiceException("该单据已退回!");
} else if (StringUtils.isBlank(status)) {
throw new ServiceException("流程状态为空!");
}
}
/**
* 驳回流程校验
*
* @param status 状态
*/
public static void checkBackStatus(String status) {
if (BACK.getStatus().equals(status)) {
throw new ServiceException("该单据已退回!");
} else if (FINISH.getStatus().equals(status)) {
throw new ServiceException("该单据已完成申请!");
} else if (INVALID.getStatus().equals(status)) {
throw new ServiceException("该单据已作废!");
} else if (TERMINATION.getStatus().equals(status)) {
throw new ServiceException("该单据已终止!");
} else if (CANCEL.getStatus().equals(status)) {
throw new ServiceException("该单据已撤销!");
} else if (StringUtils.isBlank(status)) {
throw new ServiceException("流程状态为空!");
}
}
/**
* 作废,终止流程校验
*
* @param status 状态
*/
public static void checkInvalidStatus(String status) {
if (FINISH.getStatus().equals(status)) {
throw new ServiceException("该单据已完成申请!");
} else if (INVALID.getStatus().equals(status)) {
throw new ServiceException("该单据已作废!");
} else if (TERMINATION.getStatus().equals(status)) {
throw new ServiceException("该单据已终止!");
} else if (StringUtils.isBlank(status)) {
throw new ServiceException("流程状态为空!");
}
}
}

View File

@ -20,22 +20,20 @@ import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.warm.flow.core.FlowFactory;
import org.dromara.warm.flow.core.constant.ExceptionCons;
import org.dromara.warm.flow.core.dto.FlowParams;
import org.dromara.warm.flow.core.entity.Definition;
import org.dromara.warm.flow.core.entity.Instance;
import org.dromara.warm.flow.core.entity.Node;
import org.dromara.warm.flow.core.entity.Task;
import org.dromara.warm.flow.core.entity.*;
import org.dromara.warm.flow.core.enums.NodeType;
import org.dromara.warm.flow.core.enums.SkipType;
import org.dromara.warm.flow.core.enums.UserType;
import org.dromara.warm.flow.core.service.DefService;
import org.dromara.warm.flow.core.service.InsService;
import org.dromara.warm.flow.core.service.NodeService;
import org.dromara.warm.flow.core.service.TaskService;
import org.dromara.warm.flow.core.utils.AssertUtil;
import org.dromara.warm.flow.orm.entity.*;
import org.dromara.warm.flow.orm.mapper.FlowDefinitionMapper;
import org.dromara.warm.flow.orm.mapper.FlowHisTaskMapper;
import org.dromara.warm.flow.orm.mapper.FlowInstanceMapper;
import org.dromara.warm.flow.orm.mapper.FlowNodeMapper;
import org.dromara.warm.flow.orm.mapper.FlowTaskMapper;
import org.dromara.workflow.common.enums.TaskStatusEnum;
import org.dromara.workflow.domain.bo.FlowCancelBo;
import org.dromara.workflow.domain.bo.FlowInstanceBo;
@ -46,6 +44,7 @@ import org.dromara.workflow.domain.vo.VariableVo;
import org.dromara.workflow.mapper.FlwInstanceMapper;
import org.dromara.workflow.service.IFlwInstanceService;
import org.dromara.workflow.service.IFlwTaskService;
import org.dromara.workflow.utils.WorkflowUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@ -65,9 +64,9 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
private final InsService insService;
private final DefService defService;
private final FlowHisTaskMapper flowHisTaskMapper;
private final FlowTaskMapper flowTaskMapper;
private final FlowInstanceMapper flowInstanceMapper;
private final FlwInstanceMapper flwInstanceMapper;
private final FlowDefinitionMapper flowDefinitionMapper;
private final TaskService taskService;
private final FlowNodeMapper flowNodeMapper;
private final NodeService nodeService;
@ -198,21 +197,44 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
if (definition == null) {
throw new ServiceException(ExceptionCons.NOT_FOUNT_DEF);
}
BusinessStatusEnum.checkCancelStatus(instance.getFlowStatus());
List<Task> list = taskService.list(FlowFactory.newTask().setInstanceId(instance.getId()));
//获取已发布的流程节点
List<FlowNode> flowNodes = flowNodeMapper.selectList(new LambdaQueryWrapper<FlowNode>().eq(FlowNode::getDefinitionId, definition.getId()));
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(definition.getId(), startNode.getNodeCode(), null, SkipType.NONE.getKey());
FlowParams flowParams = FlowParams.build();
flowParams.nodeCode(nextNode.getNodeCode());
flowParams.message(bo.getMessage());
flowParams.skipType(SkipType.PASS.getKey());
flowParams.flowStatus(BusinessStatusEnum.CANCEL.getStatus()).hisStatus(TaskStatusEnum.CANCEL.getStatus());
flowParams.ignore(true);
taskService.skip(list.get(0).getId(), flowParams);
for (Task task : list) {
FlowParams flowParams = FlowParams.build();
flowParams.nodeCode(nextNode.getNodeCode());
flowParams.message(bo.getMessage());
flowParams.skipType(SkipType.PASS.getKey());
flowParams.flowStatus(BusinessStatusEnum.CANCEL.getStatus()).hisStatus(TaskStatusEnum.CANCEL.getStatus());
flowParams.ignore(true);
taskService.skip(task.getId(), flowParams);
}
//判断申请人节点是否有多个只保留一个
List<Task> currentTaskList = taskService.list(FlowFactory.newTask().setInstanceId(instance.getId()));
if (CollUtil.isNotEmpty(currentTaskList)) {
Task task = currentTaskList.get(0);
if (currentTaskList.size() > 1) {
currentTaskList.remove(0);
List<Long> taskIds = StreamUtils.toList(currentTaskList, Task::getId);
WorkflowUtils.userService.deleteByTaskIds(taskIds);
flowTaskMapper.deleteByIds(taskIds);
}
//如果为空增加一个申请人
List<User> userList = WorkflowUtils.userService.getByAssociateds(Collections.singletonList(task.getId()));
if (CollUtil.isEmpty(userList)) {
FlowUser flowUser = new FlowUser();
flowUser.setAssociated(task.getId());
flowUser.setProcessedBy(LoginHelper.getUserIdStr());
flowUser.setType(UserType.APPROVAL.getKey());
WorkflowUtils.userService.save(flowUser);
}
}
} catch (Exception e) {
log.error("撤销失败: {}", e.getMessage(), e);
throw new ServiceException(e.getMessage());
@ -257,6 +279,7 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
for (FlowHisTaskVo flowHisTaskVo : flowHisTaskVos) {
flowHisTaskVo.setFlowStatus(TaskStatusEnum.WAITING.getStatus());
flowHisTaskVo.setUpdateTime(null);
flowHisTaskVo.setRunDuration(null);
List<UserDTO> allUser = flwTaskService.currentTaskAllUser(flowHisTaskVo.getId());
if (CollUtil.isNotEmpty(allUser)) {
String join = StreamUtils.join(allUser, e -> String.valueOf(e.getUserId()));
@ -390,6 +413,10 @@ public class FlwInstanceServiceImpl implements IFlwInstanceService {
@Transactional(rollbackFor = Exception.class)
public boolean processInvalid(FlowInvalidBo bo) {
try {
Instance instance = insService.getById(bo.getId());
if (instance != null) {
BusinessStatusEnum.checkInvalidStatus(instance.getFlowStatus());
}
List<FlowTask> flowTaskList = flwTaskService.selectByInstId(bo.getId());
for (FlowTask flowTask : flowTaskList) {
FlowParams flowParams = new FlowParams();

View File

@ -12,6 +12,7 @@ import lombok.extern.slf4j.Slf4j;
import org.dromara.common.core.domain.dto.UserDTO;
import org.dromara.common.core.enums.BusinessStatusEnum;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.UserService;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.core.utils.StringUtils;
@ -75,7 +76,6 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
private final HisTaskService hisTaskService;
private final IdentifierGenerator identifierGenerator;
private final NodeService nodeService;
private final org.dromara.common.core.service.UserService sysUserService = SpringUtils.getBean(org.dromara.common.core.service.UserService.class);
/**
* 启动任务
@ -98,6 +98,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
FlowInstance flowInstance = flowInstanceMapper.selectOne(new LambdaQueryWrapper<>(FlowInstance.class)
.eq(FlowInstance::getBusinessId, businessKey));
if (flowInstance != null) {
BusinessStatusEnum.checkStartStatus(flowInstance.getFlowStatus());
List<Task> taskList = taskService.list(new FlowTask().setInstanceId(flowInstance.getId()));
return Map.of(PROCESS_INSTANCE_ID, taskList.get(0).getInstanceId(), TASK_ID, taskList.get(0).getId());
}
@ -152,7 +153,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
flowParams.hisTaskExt(completeTaskBo.getFileId());
// 执行任务跳转并根据返回的处理人设置下一步处理人
setHandler(taskService.skip(taskId, flowParams), flowTask, wfCopyList);
//消息通知
// 消息通知
WorkflowUtils.sendMessage(definition.getFlowName(), ins.getId(), messageType, notice);
return true;
} catch (Exception e) {
@ -180,18 +181,18 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
// 遍历任务列表处理每个任务的办理人
for (FlowTask flowTask : flowTasks) {
// 获取与当前任务关联的用户列表
List<User> associatedUsers = userService.getByAssociateds(Collections.singletonList(flowTask.getId()));
List<User> associatedUsers = WorkflowUtils.userService.getByAssociateds(Collections.singletonList(flowTask.getId()));
if (CollUtil.isNotEmpty(associatedUsers)) {
userList.addAll(WorkflowUtils.buildUser(associatedUsers, flowTask.getId()));
}
}
// 批量删除现有任务的办理人记录
if (CollUtil.isNotEmpty(flowTasks)) {
userService.deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId));
WorkflowUtils.userService.deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId));
}
// 确保要保存的 userList 不为空
if (CollUtil.isNotEmpty(userList)) {
userService.saveBatch(userList);
WorkflowUtils.userService.saveBatch(userList);
}
}
@ -232,7 +233,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
return flowUser;
}).collect(Collectors.toList());
// 批量保存抄送人员
userService.saveBatch(userList);
WorkflowUtils.userService.saveBatch(userList);
}
/**
@ -350,6 +351,8 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
if (CollUtil.isEmpty(flowTasks)) {
throw new ServiceException("任务不存在!");
}
Instance inst = insService.getById(flowTasks.get(0).getInstanceId());
BusinessStatusEnum.checkBackStatus(inst.getFlowStatus());
Long definitionId = flowTasks.get(0).getDefinitionId();
Definition definition = defService.getById(definitionId);
List<FlowSkip> flowSkips = flowSkipMapper.selectList(new LambdaQueryWrapper<>(FlowSkip.class).eq(FlowSkip::getDefinitionId, definitionId));
@ -415,11 +418,20 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
@Transactional(rollbackFor = Exception.class)
public boolean terminationTask(FlowTerminationBo bo) {
try {
Long taskId = bo.getTaskId();
Task task = taskService.getById(taskId);
if (task == null) {
throw new ServiceException("任务不存在!");
}
Instance instance = insService.getById(task.getInstanceId());
if (instance != null) {
BusinessStatusEnum.checkInvalidStatus(instance.getFlowStatus());
}
FlowParams flowParams = new FlowParams();
flowParams.message(bo.getComment());
flowParams.flowStatus(BusinessStatusEnum.TERMINATION.getStatus())
.hisStatus(TaskStatusEnum.TERMINATION.getStatus());
taskService.termination(bo.getTaskId(), flowParams);
taskService.termination(taskId, flowParams);
return true;
} catch (Exception e) {
log.error(e.getMessage(), e);
@ -598,7 +610,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
List<FlowTask> flowTasks = selectByIdList(taskIdList);
// 批量删除现有任务的办理人记录
if (CollUtil.isNotEmpty(flowTasks)) {
userService.deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId));
WorkflowUtils.userService.deleteByTaskIds(StreamUtils.toList(flowTasks, FlowTask::getId));
List<User> userList = flowTasks.stream()
.map(flowTask -> {
FlowUser flowUser = new FlowUser();
@ -609,7 +621,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
})
.collect(Collectors.toList());
if (CollUtil.isNotEmpty(userList)) {
userService.saveBatch(userList);
WorkflowUtils.userService.saveBatch(userList);
}
}
} catch (Exception e) {
@ -628,12 +640,12 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
public Map<Long, List<UserDTO>> currentTaskAllUser(List<Long> taskIdList) {
Map<Long, List<UserDTO>> map = new HashMap<>();
// 获取与当前任务关联的用户列表
List<User> associatedUsers = userService.getByAssociateds(taskIdList);
List<User> associatedUsers = WorkflowUtils.userService.getByAssociateds(taskIdList);
Map<Long, List<User>> listMap = StreamUtils.groupByKey(associatedUsers, User::getAssociated);
for (Map.Entry<Long, List<User>> entry : listMap.entrySet()) {
List<User> value = entry.getValue();
if (CollUtil.isNotEmpty(value)) {
List<UserDTO> userDTOS = sysUserService.selectListByIds(StreamUtils.toList(value, e -> Long.valueOf(e.getProcessedBy())));
List<UserDTO> userDTOS = userService.selectListByIds(StreamUtils.toList(value, e -> Long.valueOf(e.getProcessedBy())));
map.put(entry.getKey(), userDTOS);
}
}
@ -648,10 +660,10 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
@Override
public List<UserDTO> currentTaskAllUser(Long taskId) {
// 获取与当前任务关联的用户列表
List<User> userList = userService.getByAssociateds(Collections.singletonList(taskId));
List<User> userList = WorkflowUtils.userService.getByAssociateds(Collections.singletonList(taskId));
if (CollUtil.isEmpty(userList)) {
return Collections.emptyList();
}
return sysUserService.selectListByIds(StreamUtils.toList(userList, e -> Long.valueOf(e.getProcessedBy())));
return userService.selectListByIds(StreamUtils.toList(userList, e -> Long.valueOf(e.getProcessedBy())));
}
}

View File

@ -151,7 +151,6 @@ public class WfTaskAssigneeServiceImpl implements IWfTaskAssigneeService, Handle
case ROLE -> userService.selectUsersByRoleIds(ids);
case DEPT -> userService.selectUsersByDeptIds(ids);
case POST -> userService.selectUsersByPostIds(ids);
default -> Collections.emptyList();
};
}

View File

@ -13,6 +13,7 @@ import org.dromara.common.sse.dto.SseMessageDto;
import org.dromara.common.sse.utils.SseMessageUtils;
import org.dromara.warm.flow.core.entity.Task;
import org.dromara.warm.flow.core.entity.User;
import org.dromara.warm.flow.core.service.UserService;
import org.dromara.warm.flow.orm.entity.FlowTask;
import org.dromara.warm.flow.orm.entity.FlowUser;
import org.dromara.workflow.common.enums.MessageTypeEnum;
@ -31,6 +32,7 @@ import java.util.*;
public class WorkflowUtils {
public static final IWfTaskAssigneeService taskAssigneeService = SpringUtils.getBean(IWfTaskAssigneeService.class);
public static final IFlwTaskService iFlwTaskService = SpringUtils.getBean(IFlwTaskService.class);
public static final UserService userService = SpringUtils.getBean(UserService.class);
/**
* 构建工作流用户
@ -77,7 +79,7 @@ public class WorkflowUtils {
List<UserDTO> userList = new ArrayList<>();
List<FlowTask> list = iFlwTaskService.selectByInstId(instId);
if (StringUtils.isBlank(message)) {
message = "有新的【" + flowName + "】单据已经提交至您的待办,请您及时处理。";
message = "有新的【" + flowName + "】单据已经提交至您,请您及时处理。";
}
for (Task task : list) {
List<UserDTO> users = iFlwTaskService.currentTaskAllUser(task.getId());