package cn.iocoder.yudao.module.bpm.convert.task; import cn.hutool.core.collection.CollUtil; import cn.hutool.core.date.DateUtil; import cn.hutool.core.util.StrUtil; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.collection.MapUtils; import cn.iocoder.yudao.framework.common.util.collection.SetUtils; import cn.iocoder.yudao.framework.common.util.date.DateUtils; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; import cn.iocoder.yudao.framework.common.util.object.BeanUtils; import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.BpmModelMetaInfoVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.model.simple.BpmSimpleModelNodeVO; import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmApprovalDetailRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceBpmnModelViewRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessPrintDataRespVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskRespVO; import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO; import cn.iocoder.yudao.module.bpm.api.event.BpmProcessInstanceStatusEvent; import cn.iocoder.yudao.module.bpm.enums.task.BpmTaskStatusEnum; import cn.iocoder.yudao.module.bpm.framework.flowable.core.enums.BpmnVariableConstants; import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils; import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils; import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceApproveReqDTO; import cn.iocoder.yudao.module.bpm.service.message.dto.BpmMessageSendWhenProcessInstanceRejectReqDTO; import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO; import cn.iocoder.yudao.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.*; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; /** * 流程实例 Convert * * @author 芋道源码 */ @Mapper public interface BpmProcessInstanceConvert { BpmProcessInstanceConvert INSTANCE = Mappers.getMapper(BpmProcessInstanceConvert.class); default PageResult buildProcessInstancePage(PageResult pageResult, Map processDefinitionMap, Map categoryMap, Map> taskMap, Map userMap, Map deptMap, Map processDefinitionInfoMap) { PageResult vpPageResult = BeanUtils.toBean(pageResult, BpmProcessInstanceRespVO.class); for (int i = 0; i < pageResult.getList().size(); i++) { BpmProcessInstanceRespVO respVO = vpPageResult.getList().get(i); respVO.setStatus(FlowableUtils.getProcessInstanceStatus(pageResult.getList().get(i))); MapUtils.findAndThen(processDefinitionMap, respVO.getProcessDefinitionId(), processDefinition -> respVO.setCategory(processDefinition.getCategory()) .setProcessDefinition(BeanUtils.toBean(processDefinition, BpmProcessDefinitionRespVO.class))); MapUtils.findAndThen(categoryMap, respVO.getCategory(), category -> respVO.setCategoryName(category.getName())); respVO.setTasks(BeanUtils.toBean(taskMap.get(respVO.getId()), BpmProcessInstanceRespVO.Task.class)); // user if (userMap != null) { AdminUserRespDTO startUser = userMap.get(NumberUtils.parseLong(pageResult.getList().get(i).getStartUserId())); if (startUser != null) { respVO.setStartUser(BeanUtils.toBean(startUser, UserSimpleBaseVO.class)); MapUtils.findAndThen(deptMap, startUser.getDeptId(), dept -> respVO.getStartUser().setDeptName(dept.getName())); } if (CollUtil.isNotEmpty(respVO.getTasks())) { respVO.getTasks().forEach(task -> { AdminUserRespDTO assigneeUser = userMap.get(task.getAssignee()); if (assigneeUser!= null) { task.setAssigneeUser(BeanUtils.toBean(assigneeUser, UserSimpleBaseVO.class)); MapUtils.findAndThen(deptMap, assigneeUser.getDeptId(), dept -> task.getAssigneeUser().setDeptName(dept.getName())); } }); } } // 摘要 respVO.setSummary(FlowableUtils.getSummary(processDefinitionInfoMap.get(respVO.getProcessDefinitionId()), pageResult.getList().get(i).getProcessVariables())); // 表单 respVO.setFormVariables(pageResult.getList().get(i).getProcessVariables()); } return vpPageResult; } default BpmProcessInstanceRespVO buildProcessInstance(HistoricProcessInstance processInstance, ProcessDefinition processDefinition, BpmProcessDefinitionInfoDO processDefinitionInfo, AdminUserRespDTO startUser, DeptRespDTO dept) { BpmProcessInstanceRespVO respVO = BeanUtils.toBean(processInstance, BpmProcessInstanceRespVO.class); respVO.setStatus(FlowableUtils.getProcessInstanceStatus(processInstance)) .setFormVariables(FlowableUtils.getProcessInstanceFormVariable(processInstance)); // definition respVO.setProcessDefinition(BeanUtils.toBean(processDefinition, BpmProcessDefinitionRespVO.class)); copyTo(processDefinitionInfo, respVO.getProcessDefinition()); // user if (startUser != null) { respVO.setStartUser(BeanUtils.toBean(startUser, UserSimpleBaseVO.class)); if (dept != null) { respVO.getStartUser().setDeptName(dept.getName()); } } return respVO; } @Mapping(source = "from.id", target = "to.id", ignore = true) void copyTo(BpmProcessDefinitionInfoDO from, @MappingTarget BpmProcessDefinitionRespVO to); default BpmProcessInstanceStatusEvent buildProcessInstanceStatusEvent(Object source, ProcessInstance instance, Integer status, String reason) { return new BpmProcessInstanceStatusEvent(source).setId(instance.getId()).setStatus(status).setReason(reason) .setProcessDefinitionKey(instance.getProcessDefinitionKey()).setBusinessKey(instance.getBusinessKey()); } default BpmMessageSendWhenProcessInstanceApproveReqDTO buildProcessInstanceApproveMessage(ProcessInstance instance) { return new BpmMessageSendWhenProcessInstanceApproveReqDTO() .setStartUserId(NumberUtils.parseLong(instance.getStartUserId())) .setProcessInstanceId(instance.getId()) .setProcessInstanceName(instance.getName()); } default BpmMessageSendWhenProcessInstanceRejectReqDTO buildProcessInstanceRejectMessage(ProcessInstance instance, String reason) { return new BpmMessageSendWhenProcessInstanceRejectReqDTO() .setProcessInstanceName(instance.getName()) .setProcessInstanceId(instance.getId()) .setReason(reason) .setStartUserId(NumberUtils.parseLong(instance.getStartUserId())); } default BpmProcessInstanceBpmnModelViewRespVO buildProcessInstanceBpmnModelView(HistoricProcessInstance processInstance, List taskInstances, BpmnModel bpmnModel, BpmSimpleModelNodeVO simpleModel, Set unfinishedTaskActivityIds, Set finishedTaskActivityIds, Set finishedSequenceFlowActivityIds, Set rejectTaskActivityIds, Map userMap, Map 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 userMap, Map deptMap) { if (StrUtil.isEmpty(userIdStr)) { return null; } Long userId = NumberUtils.parseLong(userIdStr); return buildUser(userId, userMap, deptMap); } default UserSimpleBaseVO buildUser(Long userId, Map userMap, Map 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)) .setSignPicUrl(FlowableUtils.getTaskSignPicUrl(task)); } default Set parseUserIds(HistoricProcessInstance processInstance, List activityNodes, BpmTaskRespVO todoTask) { Set 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 parseUserIds02(HistoricProcessInstance processInstance, List tasks) { Set 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 activityNodes, BpmTaskRespVO todoTask, Map formFieldsPermission, Map userMap, Map 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); } default BpmProcessPrintDataRespVO buildProcessInstancePrintData(HistoricProcessInstance historicProcessInstance, BpmProcessDefinitionInfoDO processDefinitionInfo, List tasks, Map userMap, UserSimpleBaseVO startUser) { BpmModelMetaInfoVO.PrintTemplateSetting printTemplateSetting = processDefinitionInfo.getPrintTemplateSetting(); BpmProcessPrintDataRespVO printData = new BpmProcessPrintDataRespVO(); // 打印模板是否开启 printData.setPrintTemplateEnable(printTemplateSetting != null && Boolean.TRUE.equals(printTemplateSetting.getEnable())); // 流程相关数据 BpmProcessInstanceRespVO processInstance = new BpmProcessInstanceRespVO() .setId(historicProcessInstance.getId()).setName(historicProcessInstance.getName()) .setBusinessKey(historicProcessInstance.getBusinessKey()) .setStartTime(DateUtils.of(historicProcessInstance.getStartTime())) .setEndTime(DateUtils.of(historicProcessInstance.getEndTime())) .setStartUser(startUser).setStatus(FlowableUtils.getProcessInstanceStatus(historicProcessInstance)) .setFormVariables(historicProcessInstance.getProcessVariables()) .setProcessDefinition(BeanUtils.toBean(processDefinitionInfo, BpmProcessDefinitionRespVO.class)); printData.setProcessInstance(processInstance); // 审批历史 List approveTasks = new ArrayList<>(tasks.size()); tasks.forEach(item -> { Map taskLocalVariables = item.getTaskLocalVariables(); BpmProcessPrintDataRespVO.Task approveTask = new BpmProcessPrintDataRespVO.Task(); approveTask.setName(item.getName()); approveTask.setId(item.getId()); approveTask.setSignPicUrl((String) taskLocalVariables.get(BpmnVariableConstants.TASK_SIGN_PIC_URL)); approveTask.setDescription(StrUtil.format("{} / {} / {} / {} / {}", userMap.get(Long.valueOf(item.getAssignee())).getNickname(), item.getName(), DateUtil.formatDateTime(item.getEndTime()), BpmTaskStatusEnum.valueOf((Integer) taskLocalVariables.get(BpmnVariableConstants.TASK_VARIABLE_STATUS)).getName(), taskLocalVariables.get(BpmnVariableConstants.TASK_VARIABLE_REASON))); approveTasks.add(approveTask); }); printData.setTasks(approveTasks); // 自定义模板 if (printData.getPrintTemplateEnable() && printTemplateSetting != null) { printData.setPrintTemplateHtml(printTemplateSetting.getTemplate()); } return printData; } }