!596 优化工作流代码逻辑

Merge pull request !596 from AprilWind/warm-flow-future
This commit is contained in:
疯狂的狮子Li 2024-11-06 10:00:57 +00:00 committed by Gitee
commit 09766f2245
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
16 changed files with 228 additions and 151 deletions

View File

@ -16,18 +16,22 @@ import java.util.Arrays;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public enum BusinessStatusEnum { public enum BusinessStatusEnum {
/** /**
* 已撤销 * 已撤销
*/ */
CANCEL("cancel", "已撤销"), CANCEL("cancel", "已撤销"),
/** /**
* 草稿 * 草稿
*/ */
DRAFT("draft", "草稿"), DRAFT("draft", "草稿"),
/** /**
* 待审核 * 待审核
*/ */
WAITING("waiting", "待审核"), WAITING("waiting", "待审核"),
/** /**
* 已完成 * 已完成
*/ */
@ -36,10 +40,12 @@ public enum BusinessStatusEnum {
* 已作废 * 已作废
*/ */
INVALID("invalid", "已作废"), INVALID("invalid", "已作废"),
/** /**
* 已退回 * 已退回
*/ */
BACK("back", "已退回"), BACK("back", "已退回"),
/** /**
* 已终止 * 已终止
*/ */
@ -71,6 +77,16 @@ public enum BusinessStatusEnum {
.orElse(StrUtil.EMPTY); .orElse(StrUtil.EMPTY);
} }
/**
* 判断是否为指定的状态之一草稿已撤销或已退回
*
* @param status 要检查的状态
* @return 如果状态为草稿已撤销或已退回之一则返回 true否则返回 false
*/
public static boolean isDraftOrCancelOrBack(String status) {
return DRAFT.status.equals(status) || CANCEL.status.equals(status) || BACK.status.equals(status);
}
/** /**
* 启动流程校验 * 启动流程校验
* *

View File

@ -88,6 +88,13 @@ public class LoginHelper {
return Convert.toLong(getExtra(USER_KEY)); return Convert.toLong(getExtra(USER_KEY));
} }
/**
* 获取用户id
*/
public static String getUserIdStr() {
return Convert.toStr(getExtra(USER_KEY));
}
/** /**
* 获取用户账户 * 获取用户账户
*/ */

View File

@ -3,9 +3,10 @@ package org.dromara.workflow.common.enums;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
/** /**
* 任务状态枚举 * 任务状态枚举
@ -15,10 +16,12 @@ import java.util.Arrays;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public enum FormTypeEnum { public enum FormTypeEnum {
/** /**
* 自定义表单 * 自定义表单
*/ */
STATIC("static", "自定义表单"), STATIC("static", "自定义表单"),
/** /**
* 动态表单 * 动态表单
*/ */
@ -34,21 +37,18 @@ public enum FormTypeEnum {
*/ */
private final String desc; private final String desc;
private static final Map<String, String> TYPE_DESC_MAP = Arrays.stream(values())
.collect(Collectors.toConcurrentMap(FormTypeEnum::getType, FormTypeEnum::getDesc));
/** /**
* 表单类型 * 表单类型
* *
* @param formType 表单类型 * @param formType 表单类型
*/ */
public static String findByType(String formType) { public static String findByType(String formType) {
if (StringUtils.isBlank(formType)) { // 从缓存中直接获取描述
return StrUtil.EMPTY; return TYPE_DESC_MAP.getOrDefault(formType, StrUtil.EMPTY);
} }
return Arrays.stream(FormTypeEnum.values())
.filter(statusEnum -> statusEnum.getType().equals(formType))
.findFirst()
.map(FormTypeEnum::getDesc)
.orElse(StrUtil.EMPTY);
}
} }

View File

@ -3,8 +3,10 @@ package org.dromara.workflow.common.enums;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import java.util.Arrays;
import java.util.Map; import java.util.Map;
import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function;
import java.util.stream.Collectors;
/** /**
* 消息类型枚举 * 消息类型枚举
@ -14,14 +16,17 @@ import java.util.concurrent.ConcurrentHashMap;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public enum MessageTypeEnum { public enum MessageTypeEnum {
/** /**
* 站内信 * 站内信
*/ */
SYSTEM_MESSAGE("1", "站内信"), SYSTEM_MESSAGE("1", "站内信"),
/** /**
* 邮箱 * 邮箱
*/ */
EMAIL_MESSAGE("2", "邮箱"), EMAIL_MESSAGE("2", "邮箱"),
/** /**
* 短信 * 短信
*/ */
@ -31,21 +36,18 @@ public enum MessageTypeEnum {
private final String desc; private final String desc;
private final static Map<String, MessageTypeEnum> MESSAGE_TYPE_ENUM_MAP = new ConcurrentHashMap<>(MessageTypeEnum.values().length); private static final Map<String, MessageTypeEnum> MESSAGE_TYPE_ENUM_MAP = Arrays.stream(values())
.collect(Collectors.toConcurrentMap(MessageTypeEnum::getCode, Function.identity()));
static {
for (MessageTypeEnum messageType : MessageTypeEnum.values()) {
MESSAGE_TYPE_ENUM_MAP.put(messageType.code, messageType);
}
}
/** /**
* 根据消息类型 code 获取 MessageTypeEnum * 根据消息类型 code 获取 MessageTypeEnum
*
* @param code 消息类型code * @param code 消息类型code
* @return MessageTypeEnum * @return MessageTypeEnum
*/ */
public static MessageTypeEnum getByCode(String code) { public static MessageTypeEnum getByCode(String code) {
return MESSAGE_TYPE_ENUM_MAP.get(code); return MESSAGE_TYPE_ENUM_MAP.getOrDefault(code, null);
} }
} }

View File

@ -3,9 +3,10 @@ package org.dromara.workflow.common.enums;
import cn.hutool.core.util.StrUtil; import cn.hutool.core.util.StrUtil;
import lombok.AllArgsConstructor; import lombok.AllArgsConstructor;
import lombok.Getter; import lombok.Getter;
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays; import java.util.Arrays;
import java.util.Map;
import java.util.stream.Collectors;
/** /**
* 任务状态枚举 * 任务状态枚举
@ -15,50 +16,62 @@ import java.util.Arrays;
@Getter @Getter
@AllArgsConstructor @AllArgsConstructor
public enum TaskStatusEnum { public enum TaskStatusEnum {
/** /**
* 撤销 * 撤销
*/ */
CANCEL("cancel", "撤销"), CANCEL("cancel", "撤销"),
/** /**
* 通过 * 通过
*/ */
PASS("pass", "通过"), PASS("pass", "通过"),
/** /**
* 待审核 * 待审核
*/ */
WAITING("waiting", "待审核"), WAITING("waiting", "待审核"),
/** /**
* 作废 * 作废
*/ */
INVALID("invalid", "作废"), INVALID("invalid", "作废"),
/** /**
* 退回 * 退回
*/ */
BACK("back", "退回"), BACK("back", "退回"),
/** /**
* 终止 * 终止
*/ */
TERMINATION("termination", "终止"), TERMINATION("termination", "终止"),
/** /**
* 转办 * 转办
*/ */
TRANSFER("transfer", "转办"), TRANSFER("transfer", "转办"),
/** /**
* 委托 * 委托
*/ */
PENDING("pending", "委托"), PENDING("pending", "委托"),
/** /**
* 抄送 * 抄送
*/ */
COPY("copy", "抄送"), COPY("copy", "抄送"),
/** /**
* 加签 * 加签
*/ */
SIGN("sign", "加签"), SIGN("sign", "加签"),
/** /**
* 减签 * 减签
*/ */
SIGN_OFF("sign_off", "减签"), SIGN_OFF("sign_off", "减签"),
/** /**
* 超时 * 超时
*/ */
@ -74,21 +87,18 @@ public enum TaskStatusEnum {
*/ */
private final String desc; private final String desc;
private static final Map<String, String> STATUS_DESC_MAP = Arrays.stream(values())
.collect(Collectors.toConcurrentMap(TaskStatusEnum::getStatus, TaskStatusEnum::getDesc));
/** /**
* 任务业务状态 * 任务业务状态
* *
* @param status 状态 * @param status 状态
*/ */
public static String findByStatus(String status) { public static String findByStatus(String status) {
if (StringUtils.isBlank(status)) { // 从缓存中直接获取描述
return StrUtil.EMPTY; return STATUS_DESC_MAP.getOrDefault(status, StrUtil.EMPTY);
} }
return Arrays.stream(TaskStatusEnum.values())
.filter(statusEnum -> statusEnum.getStatus().equals(status))
.findFirst()
.map(TaskStatusEnum::getDesc)
.orElse(StrUtil.EMPTY);
}
} }

View File

@ -173,7 +173,7 @@ public class FlwTaskController extends BaseController {
public R<Void> delegateTask(@Validated({AddGroup.class}) @RequestBody DelegateBo bo) { public R<Void> delegateTask(@Validated({AddGroup.class}) @RequestBody DelegateBo bo) {
return toAjax(taskService.depute( return toAjax(taskService.depute(
bo.getTaskId(), bo.getTaskId(),
String.valueOf(LoginHelper.getUserId()), LoginHelper.getUserIdStr(),
WorkflowUtils.permissionList(), WorkflowUtils.permissionList(),
Collections.singletonList(bo.getUserId()), Collections.singletonList(bo.getUserId()),
bo.getMessage())); bo.getMessage()));
@ -190,7 +190,7 @@ public class FlwTaskController extends BaseController {
public R<Void> transferTask(@Validated({AddGroup.class}) @RequestBody TransferBo bo) { public R<Void> transferTask(@Validated({AddGroup.class}) @RequestBody TransferBo bo) {
return toAjax(taskService.transfer( return toAjax(taskService.transfer(
bo.getTaskId(), bo.getTaskId(),
String.valueOf(LoginHelper.getUserId()), LoginHelper.getUserIdStr(),
WorkflowUtils.permissionList(), WorkflowUtils.permissionList(),
Collections.singletonList(bo.getUserId()), Collections.singletonList(bo.getUserId()),
bo.getMessage())); bo.getMessage()));
@ -207,7 +207,7 @@ public class FlwTaskController extends BaseController {
public R<Void> addSignature(@Validated({AddGroup.class}) @RequestBody AddSignatureBo bo) { public R<Void> addSignature(@Validated({AddGroup.class}) @RequestBody AddSignatureBo bo) {
return toAjax(taskService.addSignature( return toAjax(taskService.addSignature(
bo.getTaskId(), bo.getTaskId(),
String.valueOf(LoginHelper.getUserId()), LoginHelper.getUserIdStr(),
WorkflowUtils.permissionList(), WorkflowUtils.permissionList(),
bo.getUserIds(), bo.getUserIds(),
bo.getMessage())); bo.getMessage()));
@ -224,7 +224,7 @@ public class FlwTaskController extends BaseController {
public R<Void> reductionSignature(@Validated({AddGroup.class}) @RequestBody ReductionSignatureBo bo) { public R<Void> reductionSignature(@Validated({AddGroup.class}) @RequestBody ReductionSignatureBo bo) {
return toAjax(taskService.reductionSignature( return toAjax(taskService.reductionSignature(
bo.getTaskId(), bo.getTaskId(),
String.valueOf(LoginHelper.getUserId()), LoginHelper.getUserIdStr(),
WorkflowUtils.permissionList(), WorkflowUtils.permissionList(),
bo.getUserIds(), bo.getUserIds(),
bo.getMessage())); bo.getMessage()));
@ -246,7 +246,7 @@ public class FlwTaskController extends BaseController {
.setPermissionFlag(WorkflowUtils.permissionList()) .setPermissionFlag(WorkflowUtils.permissionList())
.setCooperateType(CooperateType.APPROVAL.getKey()) .setCooperateType(CooperateType.APPROVAL.getKey())
.setMessage("修改任务办理人") .setMessage("修改任务办理人")
.setCurUser(String.valueOf(LoginHelper.getUserId())) .setCurUser(LoginHelper.getUserIdStr())
.setIgnore(false); .setIgnore(false);
return toAjax(taskService.updateHandler(modifyHandler)); return toAjax(taskService.updateHandler(modifyHandler));
} }

View File

@ -1,6 +1,5 @@
package org.dromara.workflow.domain.bo; package org.dromara.workflow.domain.bo;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import lombok.Data; import lombok.Data;
import org.dromara.common.core.validate.AddGroup; import org.dromara.common.core.validate.AddGroup;

View File

@ -6,7 +6,6 @@ import org.dromara.common.core.validate.AddGroup;
import java.io.Serial; import java.io.Serial;
import java.io.Serializable; import java.io.Serializable;
import java.util.List;
/** /**
* 委派任务请求对象 * 委派任务请求对象

View File

@ -37,5 +37,8 @@ public class FlowInstanceBo implements Serializable {
*/ */
private Long instanceId; private Long instanceId;
/**
* 权限列表
*/
private List<String> permissionList; private List<String> permissionList;
} }

View File

@ -38,5 +38,8 @@ public class FlowTaskBo implements Serializable {
*/ */
private Long instanceId; private Long instanceId;
/**
* 权限列表
*/
private List<String> permissionList; private List<String> permissionList;
} }

View File

@ -13,6 +13,7 @@ import org.apache.ibatis.annotations.Param;
* @date 2024-03-02 * @date 2024-03-02
*/ */
public interface FlwDefMapper { public interface FlwDefMapper {
/** /**
* 流程实例信息 * 流程实例信息
* *
@ -20,7 +21,6 @@ public interface FlwDefMapper {
* @param queryWrapper 条件 * @param queryWrapper 条件
* @return 结果 * @return 结果
*/ */
Page<FlowDefinition> page(@Param("page") Page<FlowDefinition> page, @Param(Constants.WRAPPER) Wrapper<FlowDefinition> queryWrapper);
Page<FlowDefinition> page(@Param("page") Page<FlowDefinition> page,
@Param(Constants.WRAPPER) Wrapper<FlowDefinition> queryWrapper);
} }

View File

@ -14,6 +14,7 @@ import org.dromara.workflow.domain.vo.FlowInstanceVo;
* @date 2024-03-02 * @date 2024-03-02
*/ */
public interface FlwInstanceMapper { public interface FlwInstanceMapper {
/** /**
* 流程实例信息 * 流程实例信息
* *
@ -21,7 +22,6 @@ public interface FlwInstanceMapper {
* @param queryWrapper 条件 * @param queryWrapper 条件
* @return 结果 * @return 结果
*/ */
Page<FlowInstanceVo> page(@Param("page") Page<FlowInstanceVo> page, @Param(Constants.WRAPPER) Wrapper<FlowInstanceBo> queryWrapper);
Page<FlowInstanceVo> page(@Param("page") Page<FlowInstanceVo> page,
@Param(Constants.WRAPPER) Wrapper<FlowInstanceBo> queryWrapper);
} }

View File

@ -17,6 +17,7 @@ import org.dromara.workflow.domain.vo.FlowTaskVo;
* @date 2024-03-02 * @date 2024-03-02
*/ */
public interface FlwTaskMapper { public interface FlwTaskMapper {
/** /**
* 获取待办信息 * 获取待办信息
* *
@ -24,8 +25,7 @@ public interface FlwTaskMapper {
* @param queryWrapper 条件 * @param queryWrapper 条件
* @return 结果 * @return 结果
*/ */
Page<FlowTaskVo> getTaskWaitByPage(@Param("page") Page<FlowTaskVo> page, Page<FlowTaskVo> getTaskWaitByPage(@Param("page") Page<FlowTaskVo> page, @Param(Constants.WRAPPER) Wrapper<FlowTaskBo> queryWrapper);
@Param(Constants.WRAPPER) Wrapper<FlowTaskBo> queryWrapper);
/** /**
* 获取已办 * 获取已办
@ -34,8 +34,7 @@ public interface FlwTaskMapper {
* @param queryWrapper 条件 * @param queryWrapper 条件
* @return 结果 * @return 结果
*/ */
Page<FlowHisTaskVo> getTaskFinishByPage(@Param("page") Page<FlowTaskVo> page, Page<FlowHisTaskVo> getTaskFinishByPage(@Param("page") Page<FlowTaskVo> page, @Param(Constants.WRAPPER) Wrapper<FlowTaskBo> queryWrapper);
@Param(Constants.WRAPPER) Wrapper<FlowTaskBo> queryWrapper);
/** /**
* 查询当前用户的抄送 * 查询当前用户的抄送
@ -44,6 +43,5 @@ public interface FlwTaskMapper {
* @param queryWrapper 条件 * @param queryWrapper 条件
* @return 结果 * @return 结果
*/ */
Page<FlowTaskVo> getTaskCopyByPage(@Param("page") Page<FlowTaskVo> page, Page<FlowTaskVo> getTaskCopyByPage(@Param("page") Page<FlowTaskVo> page, @Param(Constants.WRAPPER) QueryWrapper<FlowTaskBo> queryWrapper);
@Param(Constants.WRAPPER) QueryWrapper<FlowTaskBo> queryWrapper);
} }

View File

@ -6,7 +6,6 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.warm.flow.core.entity.Definition; import com.warm.flow.core.entity.Definition;
import com.warm.flow.core.enums.PublishStatus;
import com.warm.flow.core.service.DefService; import com.warm.flow.core.service.DefService;
import com.warm.flow.orm.entity.FlowDefinition; import com.warm.flow.orm.entity.FlowDefinition;
import com.warm.flow.orm.mapper.FlowDefinitionMapper; import com.warm.flow.orm.mapper.FlowDefinitionMapper;
@ -26,7 +25,6 @@ import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import java.io.IOException; import java.io.IOException;
import java.util.Arrays;
import java.util.List; import java.util.List;
/** /**

View File

@ -31,7 +31,9 @@ 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.workflow.common.enums.TaskStatusEnum; import org.dromara.workflow.common.enums.TaskStatusEnum;
import org.dromara.workflow.domain.bo.*; import org.dromara.workflow.domain.bo.*;
import org.dromara.workflow.domain.vo.*; import org.dromara.workflow.domain.vo.FlowHisTaskVo;
import org.dromara.workflow.domain.vo.FlowTaskVo;
import org.dromara.workflow.domain.vo.WfDefinitionConfigVo;
import org.dromara.workflow.handler.FlowProcessEventHandler; import org.dromara.workflow.handler.FlowProcessEventHandler;
import org.dromara.workflow.mapper.FlwTaskMapper; import org.dromara.workflow.mapper.FlwTaskMapper;
import org.dromara.workflow.service.IFlwInstanceService; import org.dromara.workflow.service.IFlwInstanceService;
@ -44,7 +46,8 @@ import org.springframework.transaction.annotation.Transactional;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import static org.dromara.workflow.common.constant.FlowConstant.*; import static org.dromara.workflow.common.constant.FlowConstant.BUSINESS_KEY;
import static org.dromara.workflow.common.constant.FlowConstant.INITIATOR;
/** /**
* 任务 服务层实现 * 任务 服务层实现
@ -76,36 +79,35 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
@Override @Override
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public Map<String, Object> startWorkFlow(StartProcessBo startProcessBo) { public Map<String, Object> startWorkFlow(StartProcessBo startProcessBo) {
Map<String, Object> map = new HashMap<>(16); String businessKey = startProcessBo.getBusinessKey();
if (StringUtils.isBlank(startProcessBo.getBusinessKey())) { String userId = LoginHelper.getUserIdStr();
if (StringUtils.isBlank(businessKey)) {
throw new ServiceException("启动工作流时必须包含业务ID"); throw new ServiceException("启动工作流时必须包含业务ID");
} }
// 启动流程实例提交申请 // 启动流程实例提交申请
Map<String, Object> variables = startProcessBo.getVariables(); Map<String, Object> variables = startProcessBo.getVariables();
// 流程发起人 // 流程发起人
variables.put(INITIATOR, (String.valueOf(LoginHelper.getUserId()))); variables.put(INITIATOR, userId);
// 业务id // 业务id
variables.put(BUSINESS_KEY, startProcessBo.getBusinessKey()); variables.put(BUSINESS_KEY, businessKey);
WfDefinitionConfigVo wfDefinitionConfigVo = wfDefinitionConfigService.getByTableNameLastVersion(startProcessBo.getTableName()); WfDefinitionConfigVo wfDefinitionConfigVo = wfDefinitionConfigService.getByTableNameLastVersion(startProcessBo.getTableName());
if (wfDefinitionConfigVo == null) { if (wfDefinitionConfigVo == null) {
throw new ServiceException("请到流程定义绑定业务表名与流程KEY"); throw new ServiceException("请到流程定义绑定业务表名与流程KEY");
} }
FlowInstance flowInstance = iFlwInstanceService.instanceByBusinessId(startProcessBo.getBusinessKey()); FlowInstance flowInstance = iFlwInstanceService.instanceByBusinessId(businessKey);
if (flowInstance != null) { if (flowInstance != null) {
List<Task> taskList = taskService.list(new FlowTask().setInstanceId(flowInstance.getId())); List<Task> taskList = taskService.list(new FlowTask().setInstanceId(flowInstance.getId()));
map.put("processInstanceId", taskList.get(0).getInstanceId()); return buildMap(taskList.get(0).getInstanceId(), taskList.get(0).getId());
map.put("taskId", taskList.get(0).getId());
return map;
} }
FlowParams flowParams = new FlowParams(); FlowParams flowParams = new FlowParams();
flowParams.flowCode(wfDefinitionConfigVo.getProcessKey()); flowParams.flowCode(wfDefinitionConfigVo.getProcessKey());
flowParams.variable(startProcessBo.getVariables()); flowParams.variable(startProcessBo.getVariables());
flowParams.setHandler(String.valueOf(LoginHelper.getUserId())); flowParams.setHandler(userId);
flowParams.flowStatus(BusinessStatusEnum.DRAFT.getStatus()); flowParams.flowStatus(BusinessStatusEnum.DRAFT.getStatus());
Instance instance; Instance instance;
try { try {
instance = insService.start(startProcessBo.getBusinessKey(), flowParams); instance = insService.start(businessKey, flowParams);
} catch (Exception e) { } catch (Exception e) {
throw new ServiceException(e.getMessage()); throw new ServiceException(e.getMessage());
} }
@ -114,9 +116,18 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
if (taskList.size() > 1) { if (taskList.size() > 1) {
throw new ServiceException("请检查流程第一个环节是否为申请人!"); throw new ServiceException("请检查流程第一个环节是否为申请人!");
} }
map.put("processInstanceId", instance.getId()); return buildMap(instance.getId(), taskList.get(0).getId());
map.put("taskId", taskList.get(0).getId()); }
return map;
/**
* 构建一个包含给定 `processInstanceId` `taskId` Map
*
* @param instanceId 流程实例的 ID
* @param taskId 任务的 ID
* @return 返回一个包含 `processInstanceId` `taskId` 的不可变 Map
*/
private Map<String, Object> buildMap(Object instanceId, Object taskId) {
return Map.of("processInstanceId", instanceId, "taskId", taskId);
} }
/** /**
@ -128,35 +139,46 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public boolean completeTask(CompleteTaskBo completeTaskBo) { public boolean completeTask(CompleteTaskBo completeTaskBo) {
try { try {
String userId = String.valueOf(LoginHelper.getUserId()); // 获取当前用户ID作为任务处理人
String userId = LoginHelper.getUserIdStr();
// 获取任务ID并查询对应的流程任务和实例信息
Long taskId = completeTaskBo.getTaskId(); Long taskId = completeTaskBo.getTaskId();
FlowTask flowTask = flowTaskMapper.selectById(taskId); FlowTask flowTask = flowTaskMapper.selectById(taskId);
Instance ins = insService.getById(flowTask.getInstanceId()); Instance ins = insService.getById(flowTask.getInstanceId());
//流程定义
// 获取流程定义信息
Definition definition = defService.getById(flowTask.getDefinitionId()); Definition definition = defService.getById(flowTask.getDefinitionId());
//流程提交监听
if (BusinessStatusEnum.DRAFT.getStatus().equals(ins.getFlowStatus()) || BusinessStatusEnum.CANCEL.getStatus().equals(ins.getFlowStatus()) // 检查流程状态是否为草稿已撤销或已退回状态若是则执行流程提交监听
|| BusinessStatusEnum.BACK.getStatus().equals(ins.getFlowStatus())) { if (BusinessStatusEnum.isDraftOrCancelOrBack(ins.getFlowStatus())) {
flowProcessEventHandler.processHandler(definition.getFlowCode(), ins.getBusinessId(), ins.getFlowStatus(), true); flowProcessEventHandler.processHandler(definition.getFlowCode(), ins.getBusinessId(), ins.getFlowStatus(), true);
} }
//办理任务监听
flowProcessEventHandler.processTaskHandler(definition.getFlowCode(), flowTask.getNodeCode(), // 办理任务监听记录任务执行信息
taskId.toString(), ins.getBusinessId()); flowProcessEventHandler.processTaskHandler(definition.getFlowCode(), flowTask.getNodeCode(), taskId.toString(), ins.getBusinessId());
// 构建流程参数包括变量跳转类型消息处理人权限等信息
FlowParams flowParams = new FlowParams(); FlowParams flowParams = new FlowParams();
flowParams.variable(completeTaskBo.getVariables()); flowParams.variable(completeTaskBo.getVariables());
flowParams.skipType(SkipType.PASS.getKey()); flowParams.skipType(SkipType.PASS.getKey());
flowParams.message(completeTaskBo.getMessage()); flowParams.message(completeTaskBo.getMessage());
flowParams.handler(userId); flowParams.handler(userId);
flowParams.permissionFlag(WorkflowUtils.permissionList()); flowParams.permissionFlag(WorkflowUtils.permissionList());
flowParams.flowStatus(BusinessStatusEnum.WAITING.getStatus()) flowParams.flowStatus(BusinessStatusEnum.WAITING.getStatus()).hisStatus(TaskStatusEnum.PASS.getStatus());
.hisStatus(TaskStatusEnum.PASS.getStatus());
// 执行任务跳转并根据返回的处理人设置下一步处理人
setHandler(taskService.skip(taskId, flowParams)); setHandler(taskService.skip(taskId, flowParams));
// 更新实例状态为待审核状态
iFlwInstanceService.updateStatus(ins.getId(), BusinessStatusEnum.WAITING.getStatus()); iFlwInstanceService.updateStatus(ins.getId(), BusinessStatusEnum.WAITING.getStatus());
//判断是否流程结束 //判断是否流程结束
Instance instance = insService.getById(ins.getId()); Instance instance = insService.getById(ins.getId());
// 重新获取实例信息检查流程是否已结束
if (FlowStatus.isFinished(instance.getFlowStatus())) { if (FlowStatus.isFinished(instance.getFlowStatus())) {
// 若流程已结束更新状态为已完成
iFlwInstanceService.updateStatus(instance.getId(), BusinessStatusEnum.FINISH.getStatus()); iFlwInstanceService.updateStatus(instance.getId(), BusinessStatusEnum.FINISH.getStatus());
//流程结束执行监听 // 流程结束监听处理结束后的业务逻辑
flowProcessEventHandler.processHandler(definition.getFlowCode(), instance.getBusinessId(), flowProcessEventHandler.processHandler(definition.getFlowCode(), instance.getBusinessId(),
BusinessStatusEnum.FINISH.getStatus(), false); BusinessStatusEnum.FINISH.getStatus(), false);
} }
@ -174,23 +196,26 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
*/ */
private void setHandler(Instance instance) { private void setHandler(Instance instance) {
if (instance != null) { if (instance != null) {
// 根据流程实例ID查询所有关联的任务
List<FlowTask> flowTasks = flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class) List<FlowTask> flowTasks = flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class)
.eq(FlowTask::getInstanceId, instance.getId())); .eq(FlowTask::getInstanceId, instance.getId()));
// 遍历任务列表处理每个任务的办理人
for (FlowTask flowTask : flowTasks) { for (FlowTask flowTask : flowTasks) {
// 获取与当前任务关联的用户列表
List<User> userList = userService.getByAssociateds(Collections.singletonList(flowTask.getId())); List<User> userList = userService.getByAssociateds(Collections.singletonList(flowTask.getId()));
if (CollUtil.isNotEmpty(userList)) { // 通过工具方法过滤和获取有效用户
Set<User> users = WorkflowUtils.getUser(userList); Set<User> users = WorkflowUtils.getUser(userList);
if (CollUtil.isNotEmpty(users)) { if (CollUtil.isNotEmpty(users)) {
// 删除现有的任务办理人记录确保后续数据清理和更新
userService.deleteByTaskIds(Collections.singletonList(flowTask.getId())); userService.deleteByTaskIds(Collections.singletonList(flowTask.getId()));
for (User user : users) { // 将新的办理人关联到任务ID并批量保存新的办理人列表
user.setAssociated(flowTask.getId()); users.forEach(user -> user.setAssociated(flowTask.getId()));
}
userService.saveBatch(new ArrayList<>(users)); userService.saveBatch(new ArrayList<>(users));
} }
} }
} }
} }
}
/** /**
* 查询当前用户的待办任务 * 查询当前用户的待办任务
@ -235,6 +260,14 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
return TableDataInfo.build(page); return TableDataInfo.build(page);
} }
/**
* 构建待处理任务分页对象
*
* @param pageQuery 分页查询对象
* @param queryWrapper 查询条件封装对象
* @param flowTaskBo 流程任务业务对象
* @return 分页后的待处理任务列表
*/
private Page<FlowTaskVo> buildTaskWaitingPage(PageQuery pageQuery, QueryWrapper<FlowTaskBo> queryWrapper, FlowTaskBo flowTaskBo) { private Page<FlowTaskVo> buildTaskWaitingPage(PageQuery pageQuery, QueryWrapper<FlowTaskBo> queryWrapper, FlowTaskBo flowTaskBo) {
commonCondition(queryWrapper, flowTaskBo); commonCondition(queryWrapper, flowTaskBo);
Page<FlowTaskVo> page = flwTaskMapper.getTaskWaitByPage(pageQuery.build(), queryWrapper); Page<FlowTaskVo> page = flwTaskMapper.getTaskWaitByPage(pageQuery.build(), queryWrapper);
@ -281,14 +314,21 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
return TableDataInfo.build(page); return TableDataInfo.build(page);
} }
/**
* 构建已完成任务分页对象
*
* @param pageQuery 分页查询对象
* @param queryWrapper 查询条件封装对象
* @param flowTaskBo 流程任务业务对象
* @return 分页后的已完成任务列表
*/
private Page<FlowHisTaskVo> buildTaskFinishPage(PageQuery pageQuery, QueryWrapper<FlowTaskBo> queryWrapper, FlowTaskBo flowTaskBo) { private Page<FlowHisTaskVo> buildTaskFinishPage(PageQuery pageQuery, QueryWrapper<FlowTaskBo> queryWrapper, FlowTaskBo flowTaskBo) {
commonCondition(queryWrapper, flowTaskBo); commonCondition(queryWrapper, flowTaskBo);
Page<FlowHisTaskVo> page = flwTaskMapper.getTaskFinishByPage(pageQuery.build(), queryWrapper); Page<FlowHisTaskVo> page = flwTaskMapper.getTaskFinishByPage(pageQuery.build(), queryWrapper);
List<FlowHisTaskVo> records = page.getRecords(); List<FlowHisTaskVo> records = page.getRecords();
// 如果有任务记录为每条记录设置流程状态名称
if (CollUtil.isNotEmpty(records)) { if (CollUtil.isNotEmpty(records)) {
for (FlowHisTaskVo data : records) { records.forEach(data -> data.setFlowStatusName(FlowStatus.getValueByKey(data.getFlowStatus())));
data.setFlowStatusName(FlowStatus.getValueByKey(data.getFlowStatus()));
}
} }
return page; return page;
} }
@ -316,7 +356,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
@Override @Override
public boolean backProcess(BackProcessBo bo) { public boolean backProcess(BackProcessBo bo) {
try { try {
String userId = String.valueOf(LoginHelper.getUserId()); String userId = LoginHelper.getUserIdStr();
Long taskId = bo.getTaskId(); Long taskId = bo.getTaskId();
List<FlowTask> flowTasks = flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class).eq(FlowTask::getId, taskId)); List<FlowTask> flowTasks = flowTaskMapper.selectList(new LambdaQueryWrapper<>(FlowTask.class).eq(FlowTask::getId, taskId));
if (CollUtil.isEmpty(flowTasks)) { if (CollUtil.isEmpty(flowTasks)) {
@ -387,7 +427,7 @@ public class FlwTaskServiceImpl implements IFlwTaskService {
//流程定义 //流程定义
Definition definition = defService.getById(flowTask.getDefinitionId()); Definition definition = defService.getById(flowTask.getDefinitionId());
FlowParams flowParams = new FlowParams(); FlowParams flowParams = new FlowParams();
flowParams.handler(String.valueOf(LoginHelper.getUserId())); flowParams.handler(LoginHelper.getUserIdStr());
flowParams.message(bo.getComment()); flowParams.message(bo.getComment());
flowParams.permissionFlag(WorkflowUtils.permissionList()); flowParams.permissionFlag(WorkflowUtils.permissionList());
flowParams.flowStatus(BusinessStatusEnum.TERMINATION.getStatus()) flowParams.flowStatus(BusinessStatusEnum.TERMINATION.getStatus())

View File

@ -31,10 +31,9 @@ public class WorkflowUtils {
*/ */
public static List<String> permissionList() { public static List<String> permissionList() {
List<RoleDTO> roles = LoginHelper.getLoginUser().getRoles(); List<RoleDTO> roles = LoginHelper.getLoginUser().getRoles();
Long userId = LoginHelper.getUserId();
Long deptId = LoginHelper.getDeptId(); Long deptId = LoginHelper.getDeptId();
List<String> permissionList = StreamUtils.toList(roles, role -> "role:" + role.getRoleId()); List<String> permissionList = StreamUtils.toList(roles, role -> "role:" + role.getRoleId());
permissionList.add(String.valueOf(userId)); permissionList.add(LoginHelper.getUserIdStr());
permissionList.add("dept:" + deptId); permissionList.add("dept:" + deptId);
return permissionList; return permissionList;
} }
@ -46,36 +45,30 @@ public class WorkflowUtils {
* @return 用户 * @return 用户
*/ */
public static List<UserDTO> getHandlerUser(List<User> userList) { public static List<UserDTO> getHandlerUser(List<User> userList) {
List<UserDTO> userDTOList = new ArrayList<>(); if (CollUtil.isEmpty(userList)) {
if (CollUtil.isNotEmpty(userList)) { return List.of();
}
UserService userService = SpringUtils.getBean(UserService.class); UserService userService = SpringUtils.getBean(UserService.class);
List<Long> userIds = new ArrayList<>(); List<Long> userIds = new ArrayList<>();
List<Long> roleIds = new ArrayList<>(); List<Long> roleIds = new ArrayList<>();
List<Long> deptIds = new ArrayList<>(); List<Long> deptIds = new ArrayList<>();
for (User user : userList) { for (User user : userList) {
if (user.getProcessedBy().startsWith("user:")) { String processedBy = user.getProcessedBy();
userIds.add(Long.valueOf(StringUtils.substringAfter(user.getProcessedBy(), StrUtil.C_COLON))); Long id = Long.valueOf(StringUtils.substringAfter(processedBy, StrUtil.C_COLON));
} else if (user.getProcessedBy().startsWith("role:")) { if (processedBy.startsWith("user:")) {
roleIds.add(Long.valueOf(StringUtils.substringAfter(user.getProcessedBy(), StrUtil.C_COLON))); userIds.add(id);
} else if (user.getProcessedBy().startsWith("dept:")) { } else if (processedBy.startsWith("role:")) {
deptIds.add(Long.valueOf(StringUtils.substringAfter(user.getProcessedBy(), StrUtil.C_COLON))); roleIds.add(id);
} else if (processedBy.startsWith("dept:")) {
deptIds.add(id);
} else { } else {
userIds.add(Long.valueOf(user.getProcessedBy())); userIds.add(Long.valueOf(processedBy));
}
}
List<UserDTO> users = userService.selectListByIds(userIds);
if (CollUtil.isNotEmpty(users)) {
userDTOList.addAll(users);
}
List<UserDTO> roleUsers = userService.selectUsersByRoleIds(roleIds);
if (CollUtil.isNotEmpty(roleUsers)) {
userDTOList.addAll(roleUsers);
}
List<UserDTO> deptUsers = userService.selectUsersByDeptIds(deptIds);
if (CollUtil.isNotEmpty(deptUsers)) {
userDTOList.addAll(deptUsers);
} }
} }
// 合并不同类型用户
List<UserDTO> userDTOList = new ArrayList<>(userService.selectListByIds(userIds));
userDTOList.addAll(userService.selectUsersByRoleIds(roleIds));
userDTOList.addAll(userService.selectUsersByDeptIds(deptIds));
return userDTOList; return userDTOList;
} }
@ -86,42 +79,51 @@ public class WorkflowUtils {
* @return 用户 * @return 用户
*/ */
public static Set<User> getUser(List<User> userList) { public static Set<User> getUser(List<User> userList) {
if (CollUtil.isEmpty(userList)) {
return Set.of();
}
Set<User> list = new HashSet<>(); Set<User> list = new HashSet<>();
if (CollUtil.isNotEmpty(userList)) {
UserService userService = SpringUtils.getBean(UserService.class); UserService userService = SpringUtils.getBean(UserService.class);
for (User user : userList) { for (User user : userList) {
if (user.getProcessedBy().startsWith("user:")) { // 根据 processedBy 前缀判断处理人类型分别获取用户列表
Long userId = Long.valueOf(StringUtils.substringAfter(user.getProcessedBy(), StrUtil.C_COLON)); List<UserDTO> users = getAssociatedUsers(userService, user);
List<UserDTO> users = userService.selectListByIds(List.of(userId)); // 转换为 FlowUser 并添加到结果集合
if (CollUtil.isNotEmpty(users)) { if (CollUtil.isNotEmpty(users)) {
FlowUser u = new FlowUser(); users.forEach(dto -> {
u.setType(user.getType()); FlowUser flowUser = new FlowUser();
u.setProcessedBy(String.valueOf(StreamUtils.toList(users, UserDTO::getUserId).get(0))); flowUser.setType(user.getType());
list.add(u); flowUser.setProcessedBy(String.valueOf(dto.getUserId()));
} list.add(flowUser);
} });
if (user.getProcessedBy().startsWith("role:")) {
Long roleId = Long.valueOf(StringUtils.substringAfter(user.getProcessedBy(), StrUtil.C_COLON));
List<UserDTO> roleUsers = userService.selectUsersByRoleIds(List.of(roleId));
for (UserDTO roleUser : roleUsers) {
FlowUser u = new FlowUser();
u.setType(user.getType());
u.setProcessedBy(String.valueOf(roleUser.getUserId()));
list.add(u);
}
}
if (user.getProcessedBy().startsWith("dept:")) {
Long deptId = Long.valueOf(StringUtils.substringAfter(user.getProcessedBy(), StrUtil.C_COLON));
List<UserDTO> deptUsers = userService.selectUsersByDeptIds(List.of(deptId));
for (UserDTO deptUser : deptUsers) {
FlowUser u = new FlowUser();
u.setType(user.getType());
u.setProcessedBy(String.valueOf(deptUser.getUserId()));
list.add(u);
}
}
} }
} }
return list; return list;
} }
/**
* 根据用户的 `processedBy` 前缀userroledept获取关联的用户列表
*
* @param userService 用户服务用于从数据库中查询用户信息
* @param user 办理用户实例通过 `processedBy` 字段识别处理人类型
* @return 返回符合条件的用户DTO列表如果未找到匹配的前缀则返回空列表
*/
private static List<UserDTO> getAssociatedUsers(UserService userService, User user) {
String processedBy = user.getProcessedBy();
// 提取 processedBy 字段中 ":" 后的部分作为ID
Long id = Long.valueOf(StringUtils.substringAfter(processedBy, StrUtil.C_COLON));
if (processedBy.startsWith("user:")) {
// 如果前缀为 "user:"根据用户ID查询
return userService.selectListByIds(List.of(id));
} else if (processedBy.startsWith("role:")) {
// 如果前缀为 "role:"根据角色ID查询用户
return userService.selectUsersByRoleIds(List.of(id));
} else if (processedBy.startsWith("dept:")) {
// 如果前缀为 "dept:"根据部门ID查询用户
return userService.selectUsersByDeptIds(List.of(id));
}
// 未匹配任何前缀返回空列表
return Collections.emptyList();
}
} }