diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java index 9eef45cd1c..46c1f8a7e9 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/BpmProcessInstanceController.java @@ -6,6 +6,7 @@ import cn.iocoder.yudao.framework.common.pojo.CommonResult; import cn.iocoder.yudao.framework.common.pojo.PageResult; import cn.iocoder.yudao.framework.common.util.json.JsonUtils; import cn.iocoder.yudao.framework.common.util.number.NumberUtils; +import cn.iocoder.yudao.module.bpm.controller.admin.base.user.UserSimpleBaseVO; import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.*; import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert; import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmCategoryDO; @@ -26,6 +27,7 @@ import jakarta.validation.Valid; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.task.api.Task; +import org.flowable.task.api.history.HistoricTaskInstance; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; @@ -34,9 +36,11 @@ import java.util.List; import java.util.Map; import java.util.Set; +import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception; import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.*; import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId; +import static cn.iocoder.yudao.module.bpm.enums.ErrorCodeConstants.PROCESS_INSTANCE_NOT_EXISTS; @Tag(name = "管理后台 - 流程实例") // 流程实例,通过流程定义创建的一次“申请” @RestController @@ -203,7 +207,19 @@ public class BpmProcessInstanceController { @PreAuthorize("@ss.hasPermission('bpm:process-instance:query')") public CommonResult getProcessInstancePrintData( @RequestParam("processInstanceId") String processInstanceId) { - return success(processInstanceService.getProcessInstancePrintData(getLoginUserId(), processInstanceId)); + HistoricProcessInstance historicProcessInstance = processInstanceService.getHistoricProcessInstance(processInstanceId); + if (historicProcessInstance == null) { + throw exception(PROCESS_INSTANCE_NOT_EXISTS); + } + AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(historicProcessInstance.getStartUserId())); + DeptRespDTO dept = deptApi.getDept(startUser.getDeptId()); + List tasks = taskService.getFinishedTaskListByProcessInstanceIdWithoutCancel(processInstanceId); + Set userIds = convertSet(tasks, item -> Long.valueOf(item.getAssignee())); + Map userMap = adminUserApi.getUserMap(userIds); + return success(BpmProcessInstanceConvert.INSTANCE.buildProcessInstancePrintData(historicProcessInstance, + processDefinitionService.getProcessDefinitionInfo(historicProcessInstance.getProcessDefinitionId()), + tasks, userMap, + new UserSimpleBaseVO().setNickname(startUser.getNickname()).setDeptName(dept.getName()))); } } diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessPrintDataRespVO.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessPrintDataRespVO.java index 5e21ae6a52..e5983c442a 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessPrintDataRespVO.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/controller/admin/task/vo/instance/BpmProcessPrintDataRespVO.java @@ -11,44 +11,29 @@ import java.util.Map; @Data public class BpmProcessPrintDataRespVO { + @Schema(description = "流程实例数据") + private BpmProcessInstanceRespVO processInstance; + + @Schema(description = "是否开启自定义打印模板") private Boolean printTemplateEnable; - // TODO @lesan:要不 processStatus、processInstanceId、processBusinessKey、processBusinessKey、startUser、endTime、processVariables 使用 BpmProcessInstanceRespVO ?虽然这个 VO 大了点,但是收一收字段。嘿嘿;进而只有 processInstance、tasks、formFields、printTemplateHtml 这些字段; - private Integer processStatus; - - private String processInstanceId; - - private String processBusinessKey; - - private String processName; - - private UserSimpleBaseVO startUser; - - private String startTime; - - private String endTime; - - // TODO @lesan:变量要不改成 tasks; - private List approveNodes; - - private List formFields; - + @Schema(description = "自定义打印模板HTML") private String printTemplateHtml; - private Map processVariables; + @Schema(description = "审批任务列表") + private List tasks; - // TODO @lesan:类名要不要改成 tasks ?然后 id、name、signUrl、description;感觉理解成本低点; @Data - public static class ApproveNode { + public static class ApproveTask { - private String nodeName; + private String id; - private String nodeDesc; + private String name; + + private String description; private String signUrl; - private String nodeId; - } } diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java index c82414b532..f41037945b 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/convert/task/BpmProcessInstanceConvert.java @@ -1,23 +1,29 @@ 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; @@ -35,10 +41,7 @@ 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 java.util.*; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList; import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet; @@ -292,4 +295,49 @@ public interface BpmProcessInstanceConvert { .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(); + processInstance.setStatus(FlowableUtils.getProcessInstanceStatus(historicProcessInstance)); + processInstance.setId(historicProcessInstance.getId()); + processInstance.setName(historicProcessInstance.getName()); + processInstance.setBusinessKey(historicProcessInstance.getBusinessKey()); + processInstance.setStartTime(DateUtils.of(historicProcessInstance.getStartTime())); + processInstance.setEndTime(DateUtils.of(historicProcessInstance.getEndTime())); + processInstance.setFormVariables(historicProcessInstance.getProcessVariables()); + processInstance.setStartUser(startUser); + processInstance.setProcessDefinition(BeanUtils.toBean(processDefinitionInfo, BpmProcessDefinitionRespVO.class)); + printData.setProcessInstance(processInstance); + // 审批历史 + List approveTasks = new ArrayList<>(tasks.size()); + tasks.forEach(item -> { + Map taskLocalVariables = item.getTaskLocalVariables(); + BpmProcessPrintDataRespVO.ApproveTask approveTask = new BpmProcessPrintDataRespVO.ApproveTask(); + approveTask.setName(item.getName()); + approveTask.setId(item.getId()); + approveTask.setSignUrl((String) taskLocalVariables.getOrDefault(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; + } + } diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java index fd0a2aaca8..abba2245e2 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceService.java @@ -113,14 +113,6 @@ public interface BpmProcessInstanceService { */ BpmProcessInstanceBpmnModelViewRespVO getProcessInstanceBpmnModelView(String id); - /** - * 获取流程打印所需数据 - * @param loginUserId 打印人 - * @param processInstanceId 流程实例id - * @return 打印所需数据 - */ - BpmProcessPrintDataRespVO getProcessInstancePrintData(Long loginUserId, String processInstanceId); - // ========== Update 写入相关方法 ========== /** diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java index 78961a38bf..109a84ac9b 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmProcessInstanceServiceImpl.java @@ -728,69 +728,6 @@ public class BpmProcessInstanceServiceImpl implements BpmProcessInstanceService userMap, deptMap); } - // TODO @lesan:这个可以放在 controller + convert 哇?保证 Service 只尽量处理写逻辑; - @Override - public BpmProcessPrintDataRespVO getProcessInstancePrintData(Long loginUserId, String processInstanceId) { - // 1 数据准备 - HistoricProcessInstance historicProcessInstance = getHistoricProcessInstance(processInstanceId); - if (historicProcessInstance == null) { - throw exception(PROCESS_INSTANCE_NOT_EXISTS); - } - BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService - .getProcessDefinitionInfo(historicProcessInstance.getProcessDefinitionId()); - BpmModelMetaInfoVO.PrintTemplateSetting printTemplateSetting = processDefinitionInfo.getPrintTemplateSetting(); - // 2 获取打印所需数据 - BpmProcessPrintDataRespVO printData = new BpmProcessPrintDataRespVO(); - // 2.1 打印模板是否开启 - printData.setPrintTemplateEnable(printTemplateSetting != null && Boolean.TRUE.equals(printTemplateSetting.getEnable())); - // 2.2 流程相关数据 - printData.setProcessStatus(FlowableUtils.getProcessInstanceStatus(historicProcessInstance)); - printData.setProcessInstanceId(historicProcessInstance.getId()); - printData.setProcessName(historicProcessInstance.getName()); - printData.setProcessBusinessKey(historicProcessInstance.getBusinessKey()); - printData.setStartTime(DatePattern.NORM_DATETIME_MINUTE_FORMAT.format(historicProcessInstance.getStartTime())); - printData.setEndTime(Objects.isNull(historicProcessInstance.getEndTime()) ? - "" : DatePattern.NORM_DATETIME_MINUTE_FORMAT.format(historicProcessInstance.getEndTime())); - printData.setProcessVariables(historicProcessInstance.getProcessVariables()); - // 2.3 发起人 - AdminUserRespDTO startUser = adminUserApi.getUser(Long.valueOf(historicProcessInstance.getStartUserId())); - DeptRespDTO dept = deptApi.getDept(startUser.getDeptId()); - printData.setStartUser(new UserSimpleBaseVO().setNickname(startUser.getNickname()).setDeptName(dept.getName())); - // 2.4 审批历史 - List tasks = historyService.createHistoricTaskInstanceQuery() - .finished() - .includeTaskLocalVariables() - .processInstanceId(processInstanceId) - .taskVariableValueNotEquals(BpmnVariableConstants.TASK_VARIABLE_STATUS, - BpmTaskStatusEnum.CANCEL.getStatus()) - .orderByHistoricTaskInstanceStartTime().asc().list(); - Set userIds = convertSet(tasks, item -> Long.valueOf(item.getAssignee())); - Map userMap = adminUserApi.getUserMap(userIds); - List approveNodes = new ArrayList<>(tasks.size()); - tasks.forEach(item -> { - Map taskLocalVariables = item.getTaskLocalVariables(); - BpmProcessPrintDataRespVO.ApproveNode approveNode = new BpmProcessPrintDataRespVO.ApproveNode(); - approveNode.setNodeName(item.getName()); - approveNode.setNodeId(item.getId()); - approveNode.setSignUrl((String) taskLocalVariables.getOrDefault(BpmnVariableConstants.TASK_SIGN_PIC_URL, "")); - approveNode.setNodeDesc(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))); - approveNodes.add(approveNode); - }); - printData.setApproveNodes(approveNodes); - // 2.5 表单数据 - printData.setFormFields(processDefinitionInfo.getFormFields()); - // 2.6 自定义模板 - if (printData.getPrintTemplateEnable() && printTemplateSetting != null) { - printData.setPrintTemplateHtml(printTemplateSetting.getTemplate()); - } - return printData; - } - // ========== Update 写入相关方法 ========== @Override diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java index 34db2876fa..f7d260ed13 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskService.java @@ -176,6 +176,14 @@ public interface BpmTaskService { */ List getHistoricActivityListByExecutionId(String executionId); + /** + * 获得指定流程实例的已完成的流程任务列表,不包含取消状态 + * + * @param processInstanceId 流程实例的编号 + * @return 流程任务列表 + */ + List getFinishedTaskListByProcessInstanceIdWithoutCancel(String processInstanceId); + // ========== Update 写入相关方法 ========== /** diff --git a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java index 60b435c6ce..9a5c9c159e 100644 --- a/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java +++ b/yudao-module-bpm/src/main/java/cn/iocoder/yudao/module/bpm/service/task/BpmTaskServiceImpl.java @@ -491,6 +491,17 @@ public class BpmTaskServiceImpl implements BpmTaskService { return historyService.createHistoricActivityInstanceQuery().executionId(executionId).list(); } + @Override + public List getFinishedTaskListByProcessInstanceIdWithoutCancel(String processInstanceId) { + return historyService.createHistoricTaskInstanceQuery() + .finished() + .includeTaskLocalVariables() + .processInstanceId(processInstanceId) + .taskVariableValueNotEquals(BpmnVariableConstants.TASK_VARIABLE_STATUS, + BpmTaskStatusEnum.CANCEL.getStatus()) + .orderByHistoricTaskInstanceStartTime().asc().list(); + } + /** * 判断指定用户,是否是当前任务的审批人 *