| | |
| | | package com.iailab.module.bpm.convert.task; |
| | | |
| | | import cn.hutool.core.collection.CollUtil; |
| | | import cn.hutool.core.util.StrUtil; |
| | | |
| | | import com.iailab.framework.common.pojo.PageResult; |
| | | import com.iailab.framework.common.util.collection.MapUtils; |
| | | import com.iailab.framework.common.util.collection.SetUtils; |
| | | import com.iailab.framework.common.util.number.NumberUtils; |
| | | import com.iailab.framework.common.util.object.BeanUtils; |
| | | import com.iailab.module.bpm.controller.admin.base.user.UserSimpleBaseVO; |
| | | import com.iailab.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; |
| | | import com.iailab.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO; |
| | | import com.iailab.module.bpm.controller.admin.task.vo.instance.BpmApprovalDetailRespVO; |
| | | import com.iailab.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceBpmnModelViewRespVO; |
| | | import com.iailab.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; |
| | | import com.iailab.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; |
| | | import com.iailab.module.bpm.convert.definition.BpmProcessDefinitionConvert; |
| | | import com.iailab.module.bpm.dal.dataobject.definition.BpmCategoryDO; |
| | | import com.iailab.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; |
| | | import com.iailab.module.bpm.event.BpmProcessInstanceStatusEvent; |
| | | import com.iailab.module.bpm.framework.flowable.core.util.BpmnModelUtils; |
| | | import com.iailab.module.bpm.framework.flowable.core.util.FlowableUtils; |
| | | import com.iailab.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO; |
| | | import com.iailab.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO; |
| | | import com.iailab.module.system.api.dept.dto.DeptRespDTO; |
| | | import com.iailab.module.system.api.user.dto.AdminUserRespDTO; |
| | | import org.flowable.bpmn.model.BpmnModel; |
| | | 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.flowable.task.api.history.HistoricTaskInstance; |
| | | import org.mapstruct.Mapper; |
| | | import org.mapstruct.Mapping; |
| | | import org.mapstruct.MappingTarget; |
| | | import org.mapstruct.factory.Mappers; |
| | | |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Map; |
| | | import java.util.Set; |
| | | |
| | | import static com.iailab.framework.common.util.collection.CollectionUtils.convertList; |
| | | import static com.iailab.framework.common.util.collection.CollectionUtils.convertSet; |
| | | |
| | | |
| | | /** |
| | | * 流程实例 Convert |
| | | * |
| | | * @author iailab |
| | | * @author 芋道源码 |
| | | */ |
| | | @Mapper |
| | | public interface BpmProcessInstanceConvert { |
| | |
| | | if (userMap != null) { |
| | | AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(pageResult.getList().get(i).getStartUserId())); |
| | | if (startUser != null) { |
| | | respVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class)); |
| | | respVO.setStartUser(BeanUtils.toBean(startUser, UserSimpleBaseVO.class)); |
| | | MapUtils.findAndThen(deptMap, startUser.getDeptId(), dept -> respVO.getStartUser().setDeptName(dept.getName())); |
| | | } |
| | | } |
| | |
| | | |
| | | default BpmProcessInstanceRespVO buildProcessInstance(HistoricProcessInstance processInstance, |
| | | ProcessDefinition processDefinition, |
| | | BpmProcessDefinitionInfoDO processDefinitionExt, |
| | | String bpmnXml, |
| | | BpmProcessDefinitionInfoDO processDefinitionInfo, |
| | | AdminUserRespDTO startUser, |
| | | DeptRespDTO dept) { |
| | | BpmProcessInstanceRespVO respVO = BeanUtils.toBean(processInstance, BpmProcessInstanceRespVO.class); |
| | | respVO.setStatus(FlowableUtils.getProcessInstanceStatus(processInstance)); |
| | | respVO.setFormVariables(FlowableUtils.getProcessInstanceFormVariable(processInstance)); |
| | | respVO.setStatus(FlowableUtils.getProcessInstanceStatus(processInstance)) |
| | | .setFormVariables(FlowableUtils.getProcessInstanceFormVariable(processInstance)); |
| | | // definition |
| | | respVO.setProcessDefinition(BeanUtils.toBean(processDefinition, BpmProcessDefinitionRespVO.class)); |
| | | copyTo(processDefinitionExt, respVO.getProcessDefinition()); |
| | | respVO.getProcessDefinition().setBpmnXml(bpmnXml); |
| | | copyTo(processDefinitionInfo, respVO.getProcessDefinition()); |
| | | // user |
| | | if (startUser != null) { |
| | | respVO.setStartUser(BeanUtils.toBean(startUser, BpmProcessInstanceRespVO.User.class)); |
| | | respVO.setStartUser(BeanUtils.toBean(startUser, UserSimpleBaseVO.class)); |
| | | if (dept != null) { |
| | | respVO.getStartUser().setDeptName(dept.getName()); |
| | | } |
| | |
| | | @Mapping(source = "from.id", target = "to.id", ignore = true) |
| | | void copyTo(BpmProcessDefinitionInfoDO from, @MappingTarget BpmProcessDefinitionRespVO to); |
| | | |
| | | default BpmProcessInstanceStatusEvent buildProcessInstanceStatusEvent(Object source, HistoricProcessInstance instance, Integer status) { |
| | | return new BpmProcessInstanceStatusEvent(source).setId(instance.getId()).setStatus(status) |
| | | .setProcessDefinitionKey(instance.getProcessDefinitionKey()).setBusinessKey(instance.getBusinessKey()); |
| | | } |
| | | |
| | | default BpmProcessInstanceStatusEvent buildProcessInstanceStatusEvent(Object source, ProcessInstance instance, Integer status) {; |
| | | default BpmProcessInstanceStatusEvent buildProcessInstanceStatusEvent(Object source, ProcessInstance instance, Integer status) { |
| | | return new BpmProcessInstanceStatusEvent(source).setId(instance.getId()).setStatus(status) |
| | | .setProcessDefinitionKey(instance.getProcessDefinitionKey()).setBusinessKey(instance.getBusinessKey()); |
| | | } |
| | |
| | | |
| | | default BpmMessageSendWhenProcessInstanceRejectReqDTO buildProcessInstanceRejectMessage(ProcessInstance instance, String reason) { |
| | | return new BpmMessageSendWhenProcessInstanceRejectReqDTO() |
| | | .setProcessInstanceName(instance.getName()) |
| | | .setProcessInstanceId(instance.getId()) |
| | | .setReason(reason) |
| | | .setStartUserId(NumberUtils.parseLong(instance.getStartUserId())); |
| | | .setProcessInstanceName(instance.getName()) |
| | | .setProcessInstanceId(instance.getId()) |
| | | .setReason(reason) |
| | | .setStartUserId(NumberUtils.parseLong(instance.getStartUserId())); |
| | | } |
| | | |
| | | default BpmProcessInstanceBpmnModelViewRespVO buildProcessInstanceBpmnModelView(HistoricProcessInstance processInstance, |
| | | List<HistoricTaskInstance> taskInstances, |
| | | BpmnModel bpmnModel, |
| | | BpmSimpleModelNodeVO simpleModel, |
| | | Set<String> unfinishedTaskActivityIds, |
| | | Set<String> finishedTaskActivityIds, |
| | | Set<String> finishedSequenceFlowActivityIds, |
| | | Set<String> rejectTaskActivityIds, |
| | | Map<Long, AdminUserRespDTO> userMap, |
| | | Map<Long, DeptRespDTO> deptMap) { |
| | | BpmProcessInstanceBpmnModelViewRespVO respVO = new BpmProcessInstanceBpmnModelViewRespVO(); |
| | | // 基本信息 |
| | | respVO.setProcessInstance(BeanUtils.toBean(processInstance, BpmProcessInstanceRespVO.class, o -> o |
| | | .setStatus(FlowableUtils.getProcessInstanceStatus(processInstance))) |
| | | .setStartUser(buildUser(processInstance.getStartUserId(), userMap, deptMap))); |
| | | respVO.setTasks(convertList(taskInstances, task -> BeanUtils.toBean(task, BpmTaskRespVO.class) |
| | | .setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task)) |
| | | .setAssigneeUser(buildUser(task.getAssignee(), userMap, deptMap)) |
| | | .setOwnerUser(buildUser(task.getOwner(), userMap, deptMap)))); |
| | | respVO.setBpmnXml(BpmnModelUtils.getBpmnXml(bpmnModel)); |
| | | respVO.setSimpleModel(simpleModel); |
| | | // 进度信息 |
| | | respVO.setUnfinishedTaskActivityIds(unfinishedTaskActivityIds) |
| | | .setFinishedTaskActivityIds(finishedTaskActivityIds) |
| | | .setFinishedSequenceFlowActivityIds(finishedSequenceFlowActivityIds) |
| | | .setRejectedTaskActivityIds(rejectTaskActivityIds); |
| | | return respVO; |
| | | } |
| | | |
| | | default UserSimpleBaseVO buildUser(String userIdStr, |
| | | Map<Long, AdminUserRespDTO> userMap, |
| | | Map<Long, DeptRespDTO> deptMap) { |
| | | if (StrUtil.isEmpty(userIdStr)) { |
| | | return null; |
| | | } |
| | | Long userId = NumberUtils.parseLong(userIdStr); |
| | | return buildUser(userId, userMap, deptMap); |
| | | } |
| | | |
| | | default UserSimpleBaseVO buildUser(Long userId, |
| | | Map<Long, AdminUserRespDTO> userMap, |
| | | Map<Long, DeptRespDTO> deptMap) { |
| | | if (userId == null) { |
| | | return null; |
| | | } |
| | | AdminUserRespDTO user = userMap.get(userId); |
| | | if (user == null) { |
| | | return null; |
| | | } |
| | | UserSimpleBaseVO userVO = BeanUtils.toBean(user, UserSimpleBaseVO.class); |
| | | DeptRespDTO dept = user.getDeptId() != null ? deptMap.get(user.getDeptId()) : null; |
| | | if (dept != null) { |
| | | userVO.setDeptName(dept.getName()); |
| | | } |
| | | return userVO; |
| | | } |
| | | |
| | | default BpmApprovalDetailRespVO.ActivityNodeTask buildApprovalTaskInfo(HistoricTaskInstance task) { |
| | | if (task == null) { |
| | | return null; |
| | | } |
| | | return BeanUtils.toBean(task, BpmApprovalDetailRespVO.ActivityNodeTask.class) |
| | | .setStatus(FlowableUtils.getTaskStatus(task)).setReason(FlowableUtils.getTaskReason(task)); |
| | | } |
| | | |
| | | default Set<Long> parseUserIds(HistoricProcessInstance processInstance, |
| | | List<BpmApprovalDetailRespVO.ActivityNode> activityNodes, |
| | | BpmTaskRespVO todoTask) { |
| | | Set<Long> userIds = new HashSet<>(); |
| | | if (processInstance != null) { |
| | | userIds.add(NumberUtils.parseLong(processInstance.getStartUserId())); |
| | | } |
| | | for (BpmApprovalDetailRespVO.ActivityNode activityNode : activityNodes) { |
| | | CollUtil.addAll(userIds, convertSet(activityNode.getTasks(), BpmApprovalDetailRespVO.ActivityNodeTask::getAssignee)); |
| | | CollUtil.addAll(userIds, convertSet(activityNode.getTasks(), BpmApprovalDetailRespVO.ActivityNodeTask::getOwner)); |
| | | CollUtil.addAll(userIds, activityNode.getCandidateUserIds()); |
| | | } |
| | | if (todoTask != null) { |
| | | CollUtil.addIfAbsent(userIds, todoTask.getAssignee()); |
| | | CollUtil.addIfAbsent(userIds, todoTask.getOwner()); |
| | | if (CollUtil.isNotEmpty(todoTask.getChildren())) { |
| | | CollUtil.addAll(userIds, convertSet(todoTask.getChildren(), BpmTaskRespVO::getAssignee)); |
| | | CollUtil.addAll(userIds, convertSet(todoTask.getChildren(), BpmTaskRespVO::getOwner)); |
| | | } |
| | | } |
| | | return userIds; |
| | | } |
| | | |
| | | default Set<Long> parseUserIds02(HistoricProcessInstance processInstance, |
| | | List<HistoricTaskInstance> tasks) { |
| | | Set<Long> userIds = SetUtils.asSet(Long.valueOf(processInstance.getStartUserId())); |
| | | tasks.forEach(task -> { |
| | | CollUtil.addIfAbsent(userIds, NumberUtils.parseLong((task.getAssignee()))); |
| | | CollUtil.addIfAbsent(userIds, NumberUtils.parseLong((task.getOwner()))); |
| | | }); |
| | | return userIds; |
| | | } |
| | | |
| | | default BpmApprovalDetailRespVO buildApprovalDetail(BpmnModel bpmnModel, |
| | | ProcessDefinition processDefinition, |
| | | BpmProcessDefinitionInfoDO processDefinitionInfo, |
| | | HistoricProcessInstance processInstance, |
| | | Integer processInstanceStatus, |
| | | List<BpmApprovalDetailRespVO.ActivityNode> activityNodes, |
| | | BpmTaskRespVO todoTask, |
| | | Map<String, String> formFieldsPermission, |
| | | Map<Long, AdminUserRespDTO> userMap, |
| | | Map<Long, DeptRespDTO> deptMap) { |
| | | // 1.1 流程实例 |
| | | BpmProcessInstanceRespVO processInstanceResp = null; |
| | | if (processInstance != null) { |
| | | AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(processInstance.getStartUserId())); |
| | | DeptRespDTO dept = startUser != null ? deptMap.get(startUser.getDeptId()) : null; |
| | | processInstanceResp = buildProcessInstance(processInstance, null, null, startUser, dept); |
| | | } |
| | | |
| | | // 1.2 流程定义 |
| | | BpmProcessDefinitionRespVO definitionResp = BpmProcessDefinitionConvert.INSTANCE.buildProcessDefinition( |
| | | processDefinition, null, processDefinitionInfo, null, null, bpmnModel); |
| | | |
| | | // 1.3 流程节点 |
| | | activityNodes.forEach(approveNode -> { |
| | | if (approveNode.getTasks() != null) { |
| | | approveNode.getTasks().forEach(task -> { |
| | | task.setAssigneeUser(buildUser(task.getAssignee(), userMap, deptMap)); |
| | | task.setOwnerUser(buildUser(task.getOwner(), userMap, deptMap)); |
| | | }); |
| | | } |
| | | approveNode.setCandidateUsers(convertList(approveNode.getCandidateUserIds(), userId -> buildUser(userId, userMap, deptMap))); |
| | | }); |
| | | |
| | | // 1.4 待办任务 |
| | | if (todoTask != null) { |
| | | todoTask.setAssigneeUser(buildUser(todoTask.getAssignee(), userMap, deptMap)); |
| | | todoTask.setOwnerUser(buildUser(todoTask.getOwner(), userMap, deptMap)); |
| | | if (CollUtil.isNotEmpty(todoTask.getChildren())) { |
| | | todoTask.getChildren().forEach(childTask -> { |
| | | childTask.setAssigneeUser(buildUser(childTask.getAssignee(), userMap, deptMap)); |
| | | childTask.setOwnerUser(buildUser(childTask.getOwner(), userMap, deptMap)); |
| | | }); |
| | | } |
| | | } |
| | | |
| | | // 2. 拼接起来 |
| | | return new BpmApprovalDetailRespVO().setStatus(processInstanceStatus) |
| | | .setProcessDefinition(definitionResp) |
| | | .setProcessInstance(processInstanceResp) |
| | | .setFormFieldsPermission(formFieldsPermission) |
| | | .setTodoTask(todoTask) |
| | | .setActivityNodes(activityNodes); |
| | | } |
| | | |
| | | } |