流转工作流程

This commit is contained in:
2024-05-12 16:15:34 +08:00
parent 1a9beeed93
commit eb9818dd7f
71 changed files with 3810 additions and 302 deletions

View File

@@ -0,0 +1,29 @@
package com.njcn.bpm.utils;
import com.njcn.bpm.pojo.vo.task.BpmActivityVO;
import org.flowable.engine.history.HistoricActivityInstance;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
import java.util.List;
/**
* BPM 活动 Convert
*
* @author 芋道源码
*/
@Mapper(uses = DateUtils.class)
public interface BpmActivityConvert {
BpmActivityConvert INSTANCE = Mappers.getMapper(BpmActivityConvert.class);
List<BpmActivityVO> convertList(List<HistoricActivityInstance> list);
@Mappings({
@Mapping(source = "activityId", target = "key"),
@Mapping(source = "activityType", target = "type")
})
BpmActivityVO convert(HistoricActivityInstance bean);
}

View File

@@ -0,0 +1,125 @@
package com.njcn.bpm.utils;
import com.njcn.bpm.event.BpmProcessInstanceStatusEvent;
import com.njcn.bpm.pojo.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO;
import com.njcn.bpm.pojo.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO;
import com.njcn.bpm.pojo.dto.PageResult;
import com.njcn.bpm.pojo.po.BpmCategory;
import com.njcn.bpm.pojo.po.BpmProcessDefinitionInfo;
import com.njcn.bpm.pojo.vo.BpmProcessDefinitionInfoVO;
import com.njcn.bpm.pojo.vo.instance.BpmProcessInstanceVO;
import com.njcn.user.pojo.po.Dept;
import com.njcn.user.pojo.po.User;
import com.njcn.user.pojo.vo.UserVO;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.MappingTarget;
import org.mapstruct.factory.Mappers;
import java.util.List;
import java.util.Map;
/**
* 流程实例 Convert
*
* @author 芋道源码
*/
@Mapper
public interface BpmProcessInstanceConvert {
BpmProcessInstanceConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceConvert.class);
default PageResult<BpmProcessInstanceVO> buildProcessInstancePage(PageResult<HistoricProcessInstance> pageResult,
Map<String, ProcessDefinition> processDefinitionMap,
Map<String, BpmCategory> categoryMap,
Map<String, List<Task>> taskMap,
Map<String, UserVO> userMap,
Map<String, Dept> deptMap) {
PageResult<BpmProcessInstanceVO> vpPageResult = BeanUtils.toBean(pageResult, BpmProcessInstanceVO.class);
for (int i = 0; i < pageResult.getList().size(); i++) {
BpmProcessInstanceVO respVO = vpPageResult.getList().get(i);
respVO.setStatus(FlowableUtils.getProcessInstanceStatus(pageResult.getList().get(i)));
MapUtils.findAndThen(processDefinitionMap, respVO.getProcessDefinitionId(),
processDefinition -> respVO.setCategory(processDefinition.getCategory()));
MapUtils.findAndThen(categoryMap, respVO.getCategory(), category -> respVO.setCategoryName(category.getName()));
respVO.setTasks(BeanUtils.toBean(taskMap.get(respVO.getId()), BpmProcessInstanceVO.Task.class));
// user
if (userMap != null) {
UserVO startUser = userMap.get(pageResult.getList().get(i).getStartUserId());
if (startUser != null) {
respVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceVO.User.class));
MapUtils.findAndThen(deptMap, startUser.getDeptId(), dept -> respVO.getStartUser().setDeptName(dept.getName()));
}
}
}
return vpPageResult;
}
default BpmProcessInstanceVO buildProcessInstance(HistoricProcessInstance processInstance,
ProcessDefinition processDefinition,
BpmProcessDefinitionInfo processDefinitionExt,
String bpmnXml,
UserVO startUser,
Dept dept) {
BpmProcessInstanceVO respVO = BeanUtils.toBean(processInstance, BpmProcessInstanceVO.class);
respVO.setStatus(FlowableUtils.getProcessInstanceStatus(processInstance));
respVO.setFormVariables(FlowableUtils.getProcessInstanceFormVariable(processInstance));
// definition
respVO.setProcessDefinition(BeanUtils.toBean(processDefinition, BpmProcessDefinitionInfoVO.class));
copyTo(processDefinitionExt, respVO.getProcessDefinition());
respVO.getProcessDefinition().setBpmnXml(bpmnXml);
// user
if (startUser != null) {
respVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceVO.User.class));
if (dept != null) {
respVO.getStartUser().setDeptName(dept.getName());
}
}
return respVO;
}
@Mapping(source = "from.id", target = "to.id", ignore = true)
void copyTo(BpmProcessDefinitionInfo from, @MappingTarget BpmProcessDefinitionInfoVO to);
default BpmProcessInstanceStatusEvent buildProcessInstanceStatusEvent(Object source, HistoricProcessInstance instance, Integer status) {
BpmProcessInstanceStatusEvent bpmProcessInstanceStatusEvent = new BpmProcessInstanceStatusEvent(source);
bpmProcessInstanceStatusEvent.setId(instance.getId());
bpmProcessInstanceStatusEvent.setStatus(status);
bpmProcessInstanceStatusEvent.setProcessDefinitionKey(instance.getProcessDefinitionKey());
bpmProcessInstanceStatusEvent.setBusinessKey(instance.getBusinessKey());
return bpmProcessInstanceStatusEvent;
}
default BpmProcessInstanceStatusEvent buildProcessInstanceStatusEvent(Object source, ProcessInstance instance, Integer status) {
BpmProcessInstanceStatusEvent bpmProcessInstanceStatusEvent = new BpmProcessInstanceStatusEvent(source);
bpmProcessInstanceStatusEvent.setId(instance.getId());
bpmProcessInstanceStatusEvent.setStatus(status);
bpmProcessInstanceStatusEvent.setProcessDefinitionKey(instance.getProcessDefinitionKey());
bpmProcessInstanceStatusEvent.setBusinessKey(instance.getBusinessKey());
return bpmProcessInstanceStatusEvent;
}
default BpmMessageSendWhenProcessInstanceApproveReqDTO buildProcessInstanceApproveMessage(ProcessInstance instance) {
BpmMessageSendWhenProcessInstanceApproveReqDTO bpmMessageSendWhenProcessInstanceApproveReqDTO = new BpmMessageSendWhenProcessInstanceApproveReqDTO();
bpmMessageSendWhenProcessInstanceApproveReqDTO.setStartUserId(instance.getStartUserId());
bpmMessageSendWhenProcessInstanceApproveReqDTO.setProcessInstanceId(instance.getId());
bpmMessageSendWhenProcessInstanceApproveReqDTO.setProcessInstanceName(instance.getName());
return bpmMessageSendWhenProcessInstanceApproveReqDTO;
}
default BpmMessageSendWhenProcessInstanceRejectReqDTO buildProcessInstanceRejectMessage(ProcessInstance instance, String reason) {
BpmMessageSendWhenProcessInstanceRejectReqDTO bpmMessageSendWhenProcessInstanceRejectReqDTO = new BpmMessageSendWhenProcessInstanceRejectReqDTO();
bpmMessageSendWhenProcessInstanceRejectReqDTO.setProcessInstanceName(instance.getName());
bpmMessageSendWhenProcessInstanceRejectReqDTO.setProcessInstanceId(instance.getId());
bpmMessageSendWhenProcessInstanceRejectReqDTO.setReason(reason);
bpmMessageSendWhenProcessInstanceRejectReqDTO.setStartUserId(instance.getStartUserId());
return bpmMessageSendWhenProcessInstanceRejectReqDTO;
}
}

View File

@@ -0,0 +1,180 @@
package com.njcn.bpm.utils;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.njcn.bpm.pojo.dto.PageResult;
import com.njcn.bpm.pojo.po.BpmForm;
import com.njcn.bpm.pojo.vo.instance.BpmProcessInstanceVO;
import com.njcn.bpm.pojo.vo.task.BpmTaskVO;
import com.njcn.user.pojo.po.Dept;
import com.njcn.user.pojo.vo.UserVO;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.flowable.task.service.impl.persistence.entity.TaskEntityImpl;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.Date;
import java.util.List;
import java.util.Map;
import static com.njcn.bpm.utils.CollectionUtils.*;
import static com.njcn.bpm.utils.MapUtils.findAndThen;
/**
* Bpm 任务 Convert
*
* @author 芋道源码
*/
@Mapper
public interface BpmTaskConvert {
BpmTaskConvert INSTANCE = Mappers.getMapper(BpmTaskConvert.class);
default PageResult<BpmTaskVO> buildTodoTaskPage(PageResult<Task> pageResult,
Map<String, ProcessInstance> processInstanceMap,
Map<String, UserVO> userMap) {
return BeanUtils.toBean(pageResult, BpmTaskVO.class, taskVO -> {
ProcessInstance processInstance = processInstanceMap.get(taskVO.getProcessInstanceId());
if (processInstance == null) {
return;
}
taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskVO.ProcessInstance.class));
UserVO startUserVO = userMap.get(processInstance.getStartUserId());
taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUserVO, BpmProcessInstanceVO.User.class));
});
}
default PageResult<BpmTaskVO> buildTaskPage(PageResult<HistoricTaskInstance> pageResult,
Map<String, HistoricProcessInstance> processInstanceMap,
Map<String, UserVO> userMap,
Map<String, Dept> deptMap) {
List<BpmTaskVO> taskVOList = convertList(pageResult.getList(), task -> {
BpmTaskVO taskVO = BeanUtils.toBean(task, BpmTaskVO.class);
taskVO.setStatus(FlowableUtils.getTaskStatus(task));
taskVO.setReason(FlowableUtils.getTaskReason(task));
// 用户信息
UserVO assignUser = userMap.get(task.getAssignee());
if (assignUser != null) {
taskVO.setAssigneeUser(BeanUtils.toBean(assignUser, BpmProcessInstanceVO.User.class));
findAndThen(deptMap, assignUser.getDeptId(), dept -> taskVO.getAssigneeUser().setDeptName(dept.getName()));
}
// 流程实例
HistoricProcessInstance processInstance = processInstanceMap.get(taskVO.getProcessInstanceId());
if (processInstance != null) {
UserVO startUser = userMap.get(processInstance.getStartUserId());
taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskVO.ProcessInstance.class));
taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceVO.User.class));
}
return taskVO;
});
return new PageResult<>(taskVOList, pageResult.getTotal());
}
default List<BpmTaskVO> buildTaskListByProcessInstanceId(List<HistoricTaskInstance> taskList,
HistoricProcessInstance processInstance,
Map<String, BpmForm> formMap,
Map<String, UserVO> userMap,
Map<String, Dept> deptMap) {
List<BpmTaskVO> taskVOList = convertList(taskList, task -> {
BpmTaskVO taskVO = BeanUtils.toBean(task, BpmTaskVO.class);
taskVO.setStatus(FlowableUtils.getTaskStatus(task));
taskVO.setReason(FlowableUtils.getTaskReason(task));
// 流程实例
UserVO startUser = userMap.get(processInstance.getStartUserId());
taskVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmTaskVO.ProcessInstance.class));
taskVO.getProcessInstance().setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceVO.User.class));
// 表单信息
BpmForm form = MapUtil.get(formMap, task.getFormKey(), BpmForm.class);
if (form != null) {
taskVO.setFormId(form.getId());
taskVO.setFormName(form.getName());
taskVO.setFormConf(form.getConf());
taskVO.setFormFields(form.getFields());
taskVO.setFormVariables(FlowableUtils.getTaskFormVariable(task));
}
// 用户信息
UserVO assignUser = userMap.get(task.getAssignee());
if (assignUser != null) {
taskVO.setAssigneeUser(BeanUtils.toBean(assignUser, BpmProcessInstanceVO.User.class));
findAndThen(deptMap, assignUser.getDeptId(), dept -> taskVO.getAssigneeUser().setDeptName(dept.getName()));
}
UserVO ownerUser = userMap.get(task.getOwner());
if (ownerUser != null) {
taskVO.setOwnerUser(BeanUtils.toBean(ownerUser, BpmProcessInstanceVO.User.class));
findAndThen(deptMap, ownerUser.getDeptId(), dept -> taskVO.getOwnerUser().setDeptName(dept.getName()));
}
return taskVO;
});
// 拼接父子关系
Map<String, List<BpmTaskVO>> childrenTaskMap = convertMultiMap(
filterList(taskVOList, r -> StrUtil.isNotEmpty(r.getParentTaskId())),
BpmTaskVO::getParentTaskId);
for (BpmTaskVO taskVO : taskVOList) {
taskVO.setChildren(childrenTaskMap.get(taskVO.getId()));
}
return filterList(taskVOList, r -> StrUtil.isEmpty(r.getParentTaskId()));
}
default List<BpmTaskVO> buildTaskListByParentTaskId(List<Task> taskList,
Map<String, UserVO> userMap,
Map<String, Dept> deptMap) {
return convertList(taskList, task -> BeanUtils.toBean(task, BpmTaskVO.class, taskVO -> {
UserVO assignUser = userMap.get(task.getAssignee());
if (assignUser != null) {
taskVO.setAssigneeUser(BeanUtils.toBean(assignUser, BpmProcessInstanceVO.User.class));
Dept dept = deptMap.get(assignUser.getDeptId());
if (dept != null) {
taskVO.getAssigneeUser().setDeptName(dept.getName());
}
}
UserVO ownerUser = userMap.get(task.getOwner());
if (ownerUser != null) {
taskVO.setOwnerUser(BeanUtils.toBean(ownerUser, BpmProcessInstanceVO.User.class));
findAndThen(deptMap, ownerUser.getDeptId(), dept -> taskVO.getOwnerUser().setDeptName(dept.getName()));
}
}));
}
// default BpmMessageSendWhenTaskCreatedReqDTO convert(ProcessInstance processInstance, AdminUserRespDTO startUser,
// Task task) {
// BpmMessageSendWhenTaskCreatedReqDTO reqDTO = new BpmMessageSendWhenTaskCreatedReqDTO();
// reqDTO.setProcessInstanceId(processInstance.getProcessInstanceId())
// .setProcessInstanceName(processInstance.getName()).setStartUserId(startUser.getId())
// .setStartUserNickname(startUser.getNickname()).setTaskId(task.getId()).setTaskName(task.getName())
// .setAssigneeUserId(NumberUtils.parseLong(task.getAssignee()));
// return reqDTO;
// }
/**
* 将父任务的属性,拷贝到子任务(加签任务)
* <p>
* 为什么不使用 mapstruct 映射?因为 TaskEntityImpl 还有很多其他属性,这里我们只设置我们需要的。
* 使用 mapstruct 会将里面嵌套的各个属性值都设置进去,会出现意想不到的问题。
*
* @param parentTask 父任务
* @param childTask 加签任务
*/
default void copyTo(TaskEntityImpl parentTask, TaskEntityImpl childTask) {
childTask.setName(parentTask.getName());
childTask.setDescription(parentTask.getDescription());
childTask.setCategory(parentTask.getCategory());
childTask.setParentTaskId(parentTask.getId());
childTask.setProcessDefinitionId(parentTask.getProcessDefinitionId());
childTask.setProcessInstanceId(parentTask.getProcessInstanceId());
// childTask.setExecutionId(parentTask.getExecutionId()); // TODO 芋艿:新加的,不太确定;尴尬,不加时,子任务不通过会失败(报错);加了,子任务审批通过会失败(报错)
childTask.setTaskDefinitionKey(parentTask.getTaskDefinitionKey());
childTask.setTaskDefinitionId(parentTask.getTaskDefinitionId());
childTask.setPriority(parentTask.getPriority());
childTask.setCreateTime(new Date());
childTask.setTenantId(parentTask.getTenantId());
}
}

View File

@@ -25,8 +25,8 @@ public class FlowableUtils {
// ========== User 相关的工具方法 ==========
public static void setAuthenticatedUserId(Long userId) {
Authentication.setAuthenticatedUserId(String.valueOf(userId));
public static void setAuthenticatedUserId(String userId) {
Authentication.setAuthenticatedUserId(userId);
}
public static void clearAuthenticatedUserId() {