From 4047abc7d307585fc53f51bfffbbe8c2b529120e Mon Sep 17 00:00:00 2001 From: CMM <2198256324@qq.com> Date: Tue, 31 Jan 2023 08:57:27 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E5=BE=85=E5=8A=9E=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E5=BE=85=E6=88=91=E5=A4=84=E7=90=86=E5=A4=84=E7=90=86=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pmapi/common/model/FileBasicInfo.java | 27 ++ .../pmapi/todocenter/bean/entity/ProcessTask.java | 62 ++++ .../todocenter/bean/vo/ProcessProgressVo.java | 69 ++++ .../controller/TodoCenterController.java | 32 +- .../extension/cmd/BackToHisApprovalNodeCmd.java | 188 +++++++++++ .../pmapi/todocenter/manage/TodoCenterManage.java | 372 ++++++++++++++++++++- .../model/dto/req/ReqProcessHandlerDTO.java | 82 +++++ .../model/dto/res/ResToBeProcessedDTO.java | 3 +- .../model/dto/res/ResToBeProjectListExportDTO.java | 2 - 9 files changed, 815 insertions(+), 22 deletions(-) create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/common/model/FileBasicInfo.java create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProcessTask.java create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/vo/ProcessProgressVo.java create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/todocenter/extension/cmd/BackToHisApprovalNodeCmd.java create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqProcessHandlerDTO.java diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/common/model/FileBasicInfo.java b/pmapi/src/main/java/com/ningdatech/pmapi/common/model/FileBasicInfo.java new file mode 100644 index 0000000..86eb29b --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/common/model/FileBasicInfo.java @@ -0,0 +1,27 @@ +package com.ningdatech.pmapi.common.model; + +import io.swagger.annotations.ApiModel; +import io.swagger.annotations.ApiModelProperty; +import lombok.Data; + +/** + * @author liuxinxin + * @date 2022/7/25 下午1:55 + * 用于包装使用 + */ +@Data +@ApiModel("文件信息基类") +public class FileBasicInfo { + + @ApiModelProperty("文件id") + private Long fileId; + + @ApiModelProperty("文件名") + private String fileName; + + @ApiModelProperty("文件类型") + private Integer fileType; + + @ApiModelProperty("文件路径") + private String filePath; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProcessTask.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProcessTask.java new file mode 100644 index 0000000..61e7494 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProcessTask.java @@ -0,0 +1,62 @@ +package com.ningdatech.pmapi.todocenter.bean.entity; + +import com.wflow.workflow.bean.process.OrgUser; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; + +/** + * 流程任务实体 + * + * @author CMM + * @since 2023/01/30 16:57 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ProcessTask { + //任务ID + private String taskId; + //任务定义key + private String taskDefKey; + //流程定义ID + private String processDefId; + //流程执行ID + private String executionId; + //任务名称 + private String taskName; + //任务归属节点 + private String nodeId; + + //任务处理结果 + private String taskResult; + + //部署ID + private String deployId; + //流程定义名称 + private String processDefName; + //版本 + private Integer version; + //实例ID + private String instanceId; + + + //流程发起人 + private String ownerId; + private OrgUser owner; + //流程发起人部门ID + private String ownerDeptId; + //流程发起人部门名称 + private String ownerDeptName; + + //流程实例创建时间 + private Date createTime; + //task创建时间 + private Date taskCreateTime; + //task完成时间 + private Date taskEndTime; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/vo/ProcessProgressVo.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/vo/ProcessProgressVo.java new file mode 100644 index 0000000..26eda63 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/vo/ProcessProgressVo.java @@ -0,0 +1,69 @@ +package com.ningdatech.pmapi.todocenter.bean.vo; + +import com.wflow.workflow.bean.process.OrgUser; +import com.wflow.workflow.bean.process.form.Form; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 流程进展详情实体 + * + * @author CMM + * @since 2023/01/30 17:21 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ProcessProgressVo { + /** + * 审批实例ID + */ + private String instanceId; + /** + * 表单配置项 + */ + private List
formItems; + /** + * 表单值 + */ + private Map formData; + /** + * 流程进度步骤 + */ + private List progress; + /** + * 流程定义名称 + */ + private String processDefName; + /** + * 版本 + */ + private Integer version; + /** + * 流程状态 + */ + private String status; + /** + * 流程结果 + */ + private String result; + /** + * 发起人 + */ + private OrgUser staterUser; + /** + * 发起人部门 + */ + private String starterDept; + /** + * 发起时间 + */ + private Date startTime; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java index 1e8756d..d385fba 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java @@ -5,10 +5,10 @@ import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import com.ningdatech.pmapi.common.util.ExcelDownUtil; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.ModelAttribute; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import com.ningdatech.pmapi.todocenter.model.dto.req.ReqProcessHandlerDTO; +import com.wflow.utils.R; +import com.wflow.workflow.bean.vo.ProcessHandlerParamsVo; +import org.springframework.web.bind.annotation.*; import com.ningdatech.basic.model.ApiResponse; import com.ningdatech.basic.model.PageVo; @@ -40,7 +40,7 @@ public class TodoCenterController { * @param param * @return */ - @GetMapping("/NotAppendProjectList") + @GetMapping("/query-project-list") public ApiResponse> queryProjectList(@Valid @ModelAttribute ReqToBeProcessedDTO param){ PageVo result = todoCenterManage.queryProjectList(param); return ApiResponse.ofSuccess(result); @@ -58,4 +58,26 @@ public class TodoCenterController { ExcelDownUtil.downXlsx(response,param,todoCenterManage::exportProjectList); } + /** + * 查询流程表单数据及审批的进度步骤 + * @param instanceId 流程实例ID + * @param nodeId 当前获取流程人员关联的流程节点ID + * @return 流程进度及表单详情 + */ + @GetMapping("progress/{instanceId}/{nodeId}") + public ApiResponse getProcessDetail(@PathVariable String instanceId, + @PathVariable(required = false) String nodeId) { + return ApiResponse.ofSuccess(todoCenterManage.getProcessDetail(nodeId, instanceId)); + } + + /** + * 审核通过,盖章并通过、退回、撤回、驳回等操作 + * @param param 操作参数 + * @return 操作结果 + */ + @PostMapping("/handler") + public ApiResponse handler(@Valid @RequestBody ReqProcessHandlerDTO param) { + todoCenterManage.handler(param); + return ApiResponse.ofSuccess(); + } } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/extension/cmd/BackToHisApprovalNodeCmd.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/extension/cmd/BackToHisApprovalNodeCmd.java new file mode 100644 index 0000000..59ad0c0 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/extension/cmd/BackToHisApprovalNodeCmd.java @@ -0,0 +1,188 @@ +package com.ningdatech.pmapi.todocenter.extension.cmd; + +import java.io.Serializable; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.stream.Collectors; + +import org.assertj.core.util.Sets; +import org.flowable.bpmn.model.FlowNode; +import org.flowable.bpmn.model.Process; +import org.flowable.bpmn.model.UserTask; +import org.flowable.common.engine.api.FlowableException; +import org.flowable.common.engine.api.FlowableObjectNotFoundException; +import org.flowable.common.engine.impl.interceptor.Command; +import org.flowable.common.engine.impl.interceptor.CommandContext; +import org.flowable.engine.RuntimeService; +import org.flowable.engine.impl.delegate.ActivityBehavior; +import org.flowable.engine.impl.persistence.entity.ExecutionEntity; +import org.flowable.engine.impl.persistence.entity.ExecutionEntityManager; +import org.flowable.engine.impl.util.CommandContextUtil; +import org.flowable.engine.impl.util.ExecutionGraphUtil; +import org.flowable.engine.impl.util.ProcessDefinitionUtil; +import org.flowable.task.api.Task; +import org.flowable.task.service.impl.persistence.entity.TaskEntity; + +import com.wflow.workflow.utils.FlowableUtils; + +/** + * @author : willian fu + * @date : 2022/10/14 + */ +public class BackToHisApprovalNodeCmd implements Command, Serializable { + + private static final long serialVersionUID = -80075781855060928L; + + protected RuntimeService runtimeService; + protected String taskId; + protected String targetNodeId; + + public BackToHisApprovalNodeCmd(RuntimeService runtimeService, String taskId, String targetNodeId) { + this.runtimeService = runtimeService; + this.taskId = taskId; + this.targetNodeId = targetNodeId; + } + + @Override + public String execute(CommandContext commandContext) { + if (targetNodeId == null || targetNodeId.length() == 0) { + throw new FlowableException("退回的目标节点不能为空"); + } + TaskEntity task = CommandContextUtil.getProcessEngineConfiguration().getTaskServiceConfiguration().getTaskService().getTask(taskId); + if (task == null) { + throw new FlowableObjectNotFoundException(taskId + " 任务不能为空", Task.class); + } + String sourceNodeId = task.getTaskDefinitionKey(); + String processInstanceId = task.getProcessInstanceId(); + String processDefinitionId = task.getProcessDefinitionId(); + //获取流程定义 + Process process = ProcessDefinitionUtil.getProcess(processDefinitionId); + FlowNode sourceFlowElement = (FlowNode) process.getFlowElement(sourceNodeId, true); + // 只支持从用户任务退回 + if (!(sourceFlowElement instanceof UserTask)) { + throw new FlowableException("只能从审批节点进行回退"); + } + FlowNode targetFlowElement = (FlowNode) process.getFlowElement(targetNodeId, true); + // 退回节点到当前节点不可达到,不允许退回 + if (!ExecutionGraphUtil.isReachable(processDefinitionId, targetNodeId, sourceNodeId)) { + throw new FlowableException("无法回退到目标节点"); + } + //目标节点如果相对当前节点是在子流程内部,则无法直接退回,目前处理是只能退回到子流程开始节点 + String[] sourceAndTargetRealActivityId = FlowableUtils.getSourceAndTargetRealActivityId(sourceFlowElement, targetFlowElement); + // 实际应操作的当前节点ID + String sourceRealActivityId = sourceAndTargetRealActivityId[0]; + // 实际应操作的目标节点ID + String targetRealActivityId = sourceAndTargetRealActivityId[1]; + + Map> specialGatewayNodes = FlowableUtils.getSpecialGatewayElements(process); + // 当前节点处在的并行网关list + List sourceInSpecialGatewayList = new ArrayList<>(); + // 目标节点处在的并行网关list + List targetInSpecialGatewayList = new ArrayList<>(); + setSpecialGatewayList(sourceRealActivityId, targetRealActivityId, specialGatewayNodes, sourceInSpecialGatewayList, targetInSpecialGatewayList); + // 实际应筛选的节点ID + Set sourceRealAcitivtyIds = null; + // 若退回目标节点相对当前节点在并行网关中,则要找到相对当前节点最近的这个并行网关,后续做特殊处理 + String targetRealSpecialGateway = null; + + // 1.目标节点和当前节点都不在并行网关中 + if (targetInSpecialGatewayList.isEmpty() && sourceInSpecialGatewayList.isEmpty()) { + sourceRealAcitivtyIds = Sets.newLinkedHashSet(sourceRealActivityId); + } + // 2.目标节点不在并行网关中、当前节点在并行网关中 + else if (targetInSpecialGatewayList.isEmpty()) { + sourceRealAcitivtyIds = specialGatewayNodes.get(sourceInSpecialGatewayList.get(0)); + } + // 3.目标节点在并行网关中、当前节点不在并行网关中 + else if (sourceInSpecialGatewayList.isEmpty()) { + sourceRealAcitivtyIds = Sets.newLinkedHashSet(sourceRealActivityId); + targetRealSpecialGateway = targetInSpecialGatewayList.get(0); + } + // 4.目标节点和当前节点都在并行网关中 + else { + int diffSpecialGatewayLevel = FlowableUtils.getDiffLevel(sourceInSpecialGatewayList, targetInSpecialGatewayList); + // 在并行网关同一层且在同一分支 + if (diffSpecialGatewayLevel == -1) { + sourceRealAcitivtyIds = Sets.newLinkedHashSet(sourceRealActivityId); + } else { + // 当前节点最内层并行网关不被目标节点最内层并行网关包含 + // 或理解为当前节点相对目标节点在并行网关外 + // 只筛选当前节点的execution + if (sourceInSpecialGatewayList.size() == diffSpecialGatewayLevel) { + sourceRealAcitivtyIds = Sets.newLinkedHashSet(sourceRealActivityId); + } + // 当前节点相对目标节点在并行网关内,应筛选相对目标节点最近的并行网关的所有节点的execution + else { + sourceRealAcitivtyIds = specialGatewayNodes.get(sourceInSpecialGatewayList.get(diffSpecialGatewayLevel)); + } + // 目标节点最内层并行网关包含当前节点最内层并行网关 + // 或理解为目标节点相对当前节点在并行网关外 + // 不做处理 + if (targetInSpecialGatewayList.size() == diffSpecialGatewayLevel) { + } + // 目标节点相对当前节点在并行网关内 + else { + targetRealSpecialGateway = targetInSpecialGatewayList.get(diffSpecialGatewayLevel); + } + } + } + + // 筛选需要处理的execution + List realExecutions = this.getRealExecutions(commandContext, processInstanceId, + task.getExecutionId(), sourceRealActivityId, sourceRealAcitivtyIds); + // 执行退回,直接跳转到实际的 targetRealActivityId + List realExecutionIds = realExecutions.stream().map(ExecutionEntity::getId).collect(Collectors.toList()); + runtimeService.createChangeActivityStateBuilder().processInstanceId(processInstanceId).moveExecutionsToSingleActivityId(realExecutionIds, targetRealActivityId).changeState(); + // 目标节点相对当前节点处于并行网关内,需要特殊处理,需要手动生成并行网关汇聚节点(_end)的execution数据 + if (targetRealSpecialGateway != null) { + createTargetInSpecialGatewayEndExecutions(commandContext, realExecutions, process, targetInSpecialGatewayList, targetRealSpecialGateway); + } + return targetRealActivityId; + } + + private void setSpecialGatewayList(String sourceNodeId, String targetNodeId, Map> specialGatewayNodes, + List sourceInSpecialGatewayList, List targetInSpecialGatewayList) { + for (Map.Entry> entry : specialGatewayNodes.entrySet()) { + if (entry.getValue().contains(sourceNodeId)) { + sourceInSpecialGatewayList.add(entry.getKey()); + } + if (entry.getValue().contains(targetNodeId)) { + targetInSpecialGatewayList.add(entry.getKey()); + } + } + } + + private void createTargetInSpecialGatewayEndExecutions(CommandContext commandContext, List excutionEntitys, Process process, + List targetInSpecialGatewayList, String targetRealSpecialGateway) { + // 目标节点相对当前节点处于并行网关,需要手动生成并行网关汇聚节点(_end)的execution数据 + String parentExecutionId = excutionEntitys.iterator().next().getParentId(); + ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext); + ExecutionEntity parentExecutionEntity = executionEntityManager.findById(parentExecutionId); + + int index = targetInSpecialGatewayList.indexOf(targetRealSpecialGateway); + for (; index < targetInSpecialGatewayList.size(); index++) { + String targetInSpecialGateway = targetInSpecialGatewayList.get(index); + FlowNode targetInSpecialGatewayEnd = (FlowNode) process.getFlowElement(targetInSpecialGateway + "_end", true); + int nbrOfExecutionsToJoin = targetInSpecialGatewayEnd.getIncomingFlows().size(); + // 处理目标节点所处的分支以外的分支,即 总分枝数-1 = nbrOfExecutionsToJoin - 1 + for (int i = 0; i < nbrOfExecutionsToJoin - 1; i++) { + ExecutionEntity childExecution = executionEntityManager.createChildExecution(parentExecutionEntity); + childExecution.setCurrentFlowElement(targetInSpecialGatewayEnd); + ActivityBehavior activityBehavior = (ActivityBehavior) targetInSpecialGatewayEnd.getBehavior(); + activityBehavior.execute(childExecution); + } + } + } + + private List getRealExecutions(CommandContext commandContext, String processInstanceId, + String taskExecutionId, String sourceRealActivityId, Set activityIds) { + ExecutionEntityManager executionEntityManager = CommandContextUtil.getExecutionEntityManager(commandContext); + ExecutionEntity taskExecution = executionEntityManager.findById(taskExecutionId); + List executions = executionEntityManager.findChildExecutionsByProcessInstanceId(processInstanceId); + Set parentExecutionIds = FlowableUtils.getParentExecutionIdsByActivityId(executions, sourceRealActivityId); + String realParentExecutionId = FlowableUtils.getParentExecutionIdFromParentIds(taskExecution, parentExecutionIds); + return executionEntityManager.findExecutionsByParentExecutionAndActivityIds(realParentExecutionId, activityIds); + } +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java index 8268ac5..6e2e75b 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java @@ -1,28 +1,55 @@ package com.ningdatech.pmapi.todocenter.manage; import cn.hutool.core.collection.CollectionUtil; +import cn.hutool.core.util.ObjectUtil; +import cn.hutool.core.util.StrUtil; import com.alibaba.excel.EasyExcel; +import com.alibaba.fastjson.JSONObject; +import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ningdatech.basic.exception.BizException; import com.ningdatech.basic.util.NdDateUtils; import com.ningdatech.pmapi.common.constant.ProjectDeclareConstants; import com.ningdatech.pmapi.common.util.ExcelDownUtil; import com.ningdatech.pmapi.common.util.ExcelExportStyle; +import com.ningdatech.pmapi.todocenter.bean.entity.ProcessTask; import com.ningdatech.pmapi.todocenter.enums.ProcessStatusEnum; +import com.ningdatech.pmapi.todocenter.extension.cmd.BackToHisApprovalNodeCmd; +import com.ningdatech.pmapi.todocenter.model.dto.req.ReqProcessHandlerDTO; import com.ningdatech.pmapi.todocenter.model.dto.res.ResToBeProjectListExportDTO; import com.ningdatech.pmapi.user.util.LoginUserUtil; +import com.wflow.bean.do_.UserDo; +import com.wflow.bean.entity.WflowCcTasks; +import com.wflow.bean.entity.WflowModelHistorys; +import com.wflow.mapper.WflowCcTasksMapper; +import com.wflow.mapper.WflowModelHistorysMapper; +import com.wflow.service.OrgRepositoryService; import com.wflow.workflow.bean.dto.ProcessInstanceOwnerDto; import com.wflow.workflow.bean.process.OrgUser; +import com.wflow.workflow.bean.process.ProcessNode; +import com.wflow.workflow.bean.process.enums.ApprovalModeEnum; +import com.wflow.workflow.bean.process.enums.NodeTypeEnum; +import com.wflow.workflow.bean.process.form.Form; +import com.wflow.workflow.bean.process.props.ApprovalProps; +import com.wflow.workflow.bean.vo.ProcessHandlerParamsVo; import com.wflow.workflow.bean.vo.ProcessProgressVo; -import com.wflow.workflow.bean.vo.ProcessTaskVo; -import com.wflow.workflow.service.ProcessInstanceService; -import com.wflow.workflow.service.UserDeptOrLeaderService; -import org.flowable.engine.RepositoryService; -import org.flowable.engine.RuntimeService; -import org.flowable.engine.TaskService; +import com.wflow.workflow.bean.vo.TaskCommentVo; +import com.wflow.workflow.config.WflowGlobalVarDef; +import com.wflow.workflow.service.*; +import com.wflow.workflow.service.FormService; +import lombok.extern.slf4j.Slf4j; +import org.assertj.core.util.Lists; +import org.assertj.core.util.Maps; +import org.flowable.common.engine.impl.identity.Authentication; +import org.flowable.engine.*; +import org.flowable.engine.history.HistoricActivityInstance; +import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.repository.ProcessDefinition; +import org.flowable.engine.runtime.Execution; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.task.api.Task; import org.flowable.task.api.TaskQuery; +import org.flowable.variable.api.history.HistoricVariableInstance; import org.springframework.stereotype.Component; import com.ningdatech.basic.model.PageVo; @@ -33,10 +60,8 @@ import lombok.RequiredArgsConstructor; import javax.servlet.http.HttpServletResponse; import java.io.IOException; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.time.LocalDateTime; +import java.util.*; import java.util.stream.Collectors; /** @@ -45,6 +70,7 @@ import java.util.stream.Collectors; */ @Component @RequiredArgsConstructor +@Slf4j public class TodoCenterManage { private final TaskService taskService; @@ -52,6 +78,14 @@ public class TodoCenterManage { private final RuntimeService runtimeService; private final UserDeptOrLeaderService userDeptOrLeaderService; private final ProcessInstanceService processService; + private final FormService formService; + private final ManagementService managementService; + private final HistoryService historyService; + private final WflowModelHistorysMapper modelHistorysMapper; + private final ProcessNodeCatchService nodeCatchService; + private final OrgRepositoryService orgRepositoryService; + private final ProcessTaskService processTaskService; + private final WflowCcTasksMapper ccTasksMapper; public PageVo queryProjectList(ReqToBeProcessedDTO param) { // 获取登录用户ID Long userId = LoginUserUtil.getUserId(); @@ -82,7 +116,7 @@ public class TodoCenterManage { ProcessInstanceOwnerDto owner = runtimeService.getVariable(task.getExecutionId(), "owner", ProcessInstanceOwnerDto.class); ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult(); staterUsers.add(owner.getOwner()); - ProcessTaskVo processTaskVo = ProcessTaskVo.builder() + ProcessTask processTask = ProcessTask.builder() .taskId(task.getId()) .taskName(task.getName()) .taskDefKey(task.getTaskDefinitionKey()) @@ -99,7 +133,7 @@ public class TodoCenterManage { .createTime(processInstance.getStartTime()) .taskCreateTime(task.getCreateTime()) .build(); - res.setProcessTaskVo(processTaskVo); + res.setProcessTaskInfo(processTask); String projectName = (String) formData.get(ProjectDeclareConstants.BasicInformation.PROJECT_NAME); res.setProjectName(projectName); res.setReportUnitId(owner.getOwnerDeptId()); @@ -121,12 +155,11 @@ public class TodoCenterManage { //取用户信息,减少数据库查询,一次构建 if (CollectionUtil.isNotEmpty(staterUsers)) { Map userMap = userDeptOrLeaderService.getUserMapByIds(staterUsers); - page.setRecords(result.stream().peek(v -> v.getProcessTaskVo().setOwner(userMap.get(v.getProcessTaskVo().getOwnerId()))).collect(Collectors.toList())); + page.setRecords(result.stream().peek(v -> v.getProcessTaskInfo().setOwner(userMap.get(v.getProcessTaskInfo().getOwnerId()))).collect(Collectors.toList())); } return PageVo.of(resVos,page.getTotal()); } - public void exportProjectList(HttpServletResponse response, ReqToBeProcessedDTO param) { PageVo page = queryProjectList(param); @@ -149,4 +182,315 @@ public class TodoCenterManage { throw new RuntimeException(e); } } + + public void handler(ReqProcessHandlerDTO param) { + Long userId = LoginUserUtil.getUserId(); + Task task = taskService.createTaskQuery().taskId(param.getTaskId()).active().singleResult(); + HashMap formData = new HashMap<>(32); + String format = NdDateUtils.format(LocalDateTime.now(), "yyyy-MM-dd HH:mm"); + LocalDateTime auditTime = LocalDateTime.parse(format); + if (Objects.isNull(task)) { + throw new BizException("任务不存在"); + } + switch (param.getAction()) { + // 通过 + case pass: + formData.put("audit_pass_opinion",param.getAuditApprovalOpinion()); + formData.put("audit_pass_appendix",param.getAuditApprovalAppendix()); + formData.put("audit_pass_time", auditTime); + formService.updateInstanceFormData(param.getInstanceId(), formData); + doPass(task, param); + // 盖章并通过 + case seal_pass: + formData.put("seal_pass_opinion",param.getSealApprovalOpinion()); + formData.put("seal_pass_appendix",param.getSealApprovalAppendix()); + Date sealPassTime = NdDateUtils.localDateTime2Date(LocalDateTime.now()); + formData.put("seal_pass_time",sealPassTime); + formService.updateInstanceFormData(param.getInstanceId(), formData); + doSealPass(task, param); + // 驳回 + case reject: + formData.put("audit_reject_opinion",param.getAuditRejectOpinion()); + formData.put("audit_reject_appendix",param.getAuditRejectAppendix()); + formData.put("audit_reject_time", auditTime); + formService.updateInstanceFormData(param.getInstanceId(), formData); + doReject(task, param); + break; + // 退回 + case back: + formData.put("audit_back_opinion",param.getAuditBackOpinion()); + formData.put("audit_back_appendix",param.getAuditBackAppendix()); + formData.put("audit_back_time", auditTime); + formService.updateInstanceFormData(param.getInstanceId(), formData); + doBackTask(task.getTaskDefinitionKey(), userId, param); + break; + // 撤回 + case withdraw: + doWithDrawProcess(task); + break; + default: + throw new IllegalStateException("Unexpected value: " + param.getAction()); + } + Authentication.setAuthenticatedUserId(null); + } + + /** + * 审批任务:驳回 + * + * @param task 当前任务 + * @param param 参数 + */ + private void doReject(Task task, ReqProcessHandlerDTO param) { + Map var = new HashMap<>(16); + var.put("reject_" + task.getId(), param.getAction()); + // TODO 中止流程并使项目进入对应状态 + // TODO 给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被驳回,请及时处理。 + taskService.complete(param.getTaskId(), var); + } + + /** + * 审批任务:盖章并通过 + * + * @param task 当前任务 + * @param param 参数 + */ + private void doSealPass(Task task, ReqProcessHandlerDTO param) { + Map var = new HashMap<>(16); + var.put("seal_pass_" + task.getId(), param.getAction()); + // TODO 判断项目申报单位级别,区县单位申报有上级主管单位意见栏,市级单位没有 + // TODO 市级单位:为大数据局;区县单位:为大数据中心(根据附件区分?) + taskService.complete(param.getTaskId(), var); + } + + /** + * 审批任务:通过 + * + * @param task 当前任务 + * @param param 参数 + */ + private void doPass(Task task, ReqProcessHandlerDTO param) { + Map var = new HashMap<>(16); + var.put("pass_" + task.getId(), param.getAction()); + // TODO 获取流程下一个节点的审核人 + + // TODO 若有下一个审核人,向其发送浙政钉工作通知:标题:审核任务 内容:【单位名称】的【项目名称】需要您审核。 + + // TODO 若没有,向发起人发送浙政钉工作通知:【项目名称】已通过【流程名称】,请及时开始下一步操作。 + taskService.complete(param.getTaskId(), var); + } + + /** + * 撤销流程处理 + * + * @param task 当前任务 + */ + private void doWithDrawProcess(Task task) { + // TODO 若是流程发起人点击撤回,项目回到上一个状态,并删除当前审核人对应的待办记录 + // TODO 若是前一个审核人点击撤回,在审核记录中移除自己提交过的审核意见、待我处理中移除当前审核人的待办记录、待我处理中增加自己的待办记录、我已处理中去掉自己之前处理的记录 + List executions = runtimeService.createExecutionQuery() + .processInstanceId(task.getProcessInstanceId()) + .onlyChildExecutions().list(); + // 强制流程指向驳回 + runtimeService.createChangeActivityStateBuilder() + .processInstanceId(task.getProcessInstanceId()) + .moveActivityIdTo(task.getTaskDefinitionKey(), "cancel-end") + .moveExecutionsToSingleActivityId(executions.stream().map(Execution::getId) + .collect(Collectors.toList()), "cancel-end") + .changeState(); + } + + /** + * 退回流程处理 + * @param current 当前流程定义key + * @param userId 当前登录用户ID + * @param param 参数 + */ + private void doBackTask(String current, Long userId, ReqProcessHandlerDTO param) { + // TODO 流程变成【被退回】状态 + // TODO 待我处理中,为流程发起人增加一条待办记录 + // TODO 给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被退回,请及时处理。 + //执行自定义回退逻辑 + managementService.executeCommand(new BackToHisApprovalNodeCmd(runtimeService, param.getTaskId(), param.getTargetNode())); + runtimeService.setVariables(param.getInstanceId(), Maps.newHashMap("back_" + param.getTaskId(), param.getAction())); + log.info("用户[{}] 退回流程[{}] [{} -> {}]", userId, param.getInstanceId(), current, param.getTargetNode()); + } + + /** + * 查询流程表单数据及审批的进度步骤 + * @param instanceId 流程实例ID + * @param nodeId 当前获取流程人员关联的流程节点ID + * @return 流程进度及表单详情 + */ + public Object getProcessDetail(String nodeId, String instanceId) { + HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery().processInstanceId(instanceId).singleResult(); + // 取表单及表单数据 + HistoricVariableInstance forms = historyService.createHistoricVariableInstanceQuery() + .processInstanceId(instanceId).variableName(WflowGlobalVarDef.WFLOW_FORMS).singleResult(); + List formDatas = historyService.createHistoricVariableInstanceQuery() + .processInstanceId(instanceId).variableNameLike("field%").list(); + // 取节点设置 + HistoricVariableInstance nodeProps = historyService.createHistoricVariableInstanceQuery() + .processInstanceId(instanceId).variableName(WflowGlobalVarDef.WFLOW_NODE_PROPS).singleResult(); + Map nodePropsValue = (Map) nodeProps.getValue(); + + ProcessNode currentNode = null; + if (StrUtil.isNotBlank(nodeId)) { + // 搜索当前版本流程的配置 + WflowModelHistorys modelHistory = modelHistorysMapper.selectOne(new QueryWrapper<>(WflowModelHistorys.builder() + .processDefId(instance.getProcessDefinitionId()).version(instance.getProcessDefinitionVersion()).build())); + currentNode = nodeCatchService.reloadProcessByStr(modelHistory.getProcess()).get(nodeId); + } + UserDo users = orgRepositoryService.getUserById(instance.getStartUserId()); + OrgUser startUser = OrgUser.builder().id(users.getUserId()).name(users.getUserName()).avatar(users.getAvatar()).build(); + List taskRecords = getHisTaskRecords(instanceId, nodePropsValue); + taskRecords.addAll(getCcTaskRecords(instanceId)); + if (ObjectUtil.isNull(instance.getEndTime())) { + taskRecords.addAll(processTaskService.getFutureTask(instanceId)); + } + taskRecords = taskRecords.stream() + .sorted(Comparator.comparing(ProcessProgressVo.ProgressNode::getStartTime)) + .collect(Collectors.toList()); + taskRecords.add(0, ProcessProgressVo.ProgressNode.builder() + .nodeId("root") + .name("提交申请") + .user(startUser) + .nodeType(NodeTypeEnum.ROOT) + .startTime(instance.getStartTime()) + .finishTime(instance.getStartTime()) + .taskId("root") + .result(ProcessHandlerParamsVo.Action.agree) + .build()); + // 提取全量表单数据 + Map formData = formDatas.stream().collect(Collectors.toMap(HistoricVariableInstance::getVariableName, HistoricVariableInstance::getValue)); + HistoricVariableInstance variableInstance = historyService.createHistoricVariableInstanceQuery() + .processInstanceId(instanceId).variableName("owner").singleResult(); + ProcessInstanceOwnerDto owner = (ProcessInstanceOwnerDto) variableInstance.getValue(); + return ProcessProgressVo.builder() + .instanceId(instanceId) + .version(instance.getProcessDefinitionVersion()) + .formItems(formService.filterFormAndDataByPermConfig((List) forms.getValue(), formData, currentNode)) + .formData(formData) + .processDefName(instance.getProcessDefinitionName()) + .staterUser(startUser) + .starterDept(null == owner ? null : owner.getOwnerDeptName()) + .status(ObjectUtil.isNull(instance.getEndActivityId()) ? "RUNNING" : "COMPLETE") + .result(instance.getEndActivityId()) + .startTime(instance.getStartTime()) + .progress(taskRecords) + .build(); + } + + /** + * 获取抄送的流程实例信息 + * + * @param instanceId 实例ID + * @return 抄送我的流程 + */ + private List getCcTaskRecords(String instanceId) { + Set ccUsers = new HashSet<>(); + List ccList = ccTasksMapper.selectList(new QueryWrapper() + .eq("instance_id", instanceId)).stream().map(task -> { + ccUsers.add(task.getUserId()); + return ProcessProgressVo.ProgressNode.builder() + .nodeId(task.getNodeId()) + .nodeType(NodeTypeEnum.CC) + .name(task.getNodeName()) + .comment(Collections.emptyList()) + .user(OrgUser.builder().id(task.getUserId()).build()) + .startTime(task.getCreateTime()) + .finishTime(task.getCreateTime()) + .build(); + }).collect(Collectors.toList()); + if (CollectionUtil.isNotEmpty(ccUsers)) { + Map userMap = userDeptOrLeaderService.getUserMapByIds(ccUsers); + ccList.stream().peek(v -> v.setUser(userMap.get(v.getUser().getId()))).collect(Collectors.toList()); + } + return ccList; + } + + /** + * 获取流程的审批历史记录 + * + * @param instanceId 审批实例ID + * @param nodeProps 节点设置 + * @return 历史记录列表 + */ + private List getHisTaskRecords(String instanceId, Map nodeProps) { + List list = historyService.createHistoricActivityInstanceQuery() + .processInstanceId(instanceId).orderByHistoricActivityInstanceStartTime().asc().list(); + Set userSet = new HashSet<>(); + //获取节点处理结果 + Map varMap = historyService.createHistoricVariableInstanceQuery() + .processInstanceId(instanceId).variableNameLike("approve_%").list().stream() + .collect(Collectors.toMap(HistoricVariableInstance::getVariableName, v -> (ProcessHandlerParamsVo.Action) v.getValue())); + Map> commentMap = new HashMap<>(); + //统一处理所有评论数据,省的多次查询 + List cmvos = taskService.getProcessInstanceComments(instanceId).stream().map(comment -> { + userSet.add(comment.getUserId()); + TaskCommentVo commentVo = TaskCommentVo.builder() + .id(comment.getId()) + .taskId(comment.getTaskId()) + .commentType(comment.getType()) + .type("COMMENT") + .createTime(comment.getTime()) + .user(OrgUser.builder().id(comment.getUserId()).build()) + .build(); + ProcessHandlerParamsVo.ProcessComment processComment = JSONObject.parseObject(comment.getFullMessage(), ProcessHandlerParamsVo.ProcessComment.class); + commentVo.setText(processComment.getText()); + commentVo.setAttachments(processComment.getAttachments()); + return commentVo; + }).collect(Collectors.toList()); + cmvos.forEach(cm -> { + //把评论数据按照task进行归类 + String taskId = Optional.ofNullable(cm.getTaskId()).orElse(instanceId); + List vos = commentMap.computeIfAbsent(taskId, k -> new ArrayList<>()); + vos.add(cm); + }); + List progressNodes = list.stream().filter(his -> ObjectUtil.isNotNull(his.getTaskId())).map(his -> { + Object props = nodeProps.get(his.getActivityId()); + ApprovalModeEnum approvalMode = null; + if (props instanceof ApprovalProps) { + approvalMode = ((ApprovalProps) props).getMode(); + } + userSet.add(his.getAssignee()); + List commentVos = commentMap.getOrDefault(his.getTaskId(), Collections.emptyList()); + return ProcessProgressVo.ProgressNode.builder() + .nodeId(his.getActivityId()) + .name(his.getActivityName()) + .nodeType(NodeTypeEnum.APPROVAL) + .user(OrgUser.builder().id(his.getAssignee()).build()) + .startTime(his.getStartTime()) + .finishTime(his.getEndTime()) + .taskId(his.getTaskId()) + .approvalMode(approvalMode) + .comment(commentVos) + .result(varMap.get("approve_" + his.getTaskId())) + .build(); + }).collect(Collectors.toList()); + //将非任务类的评论转换成流程节点 + progressNodes.addAll(commentMap.getOrDefault(instanceId, Collections.emptyList()).stream().map(cm -> + ProcessProgressVo.ProgressNode.builder() + .nodeId(cm.getId()) + .name("参与评论") + .user(cm.getUser()) + .startTime(cm.getCreateTime()) + .finishTime(cm.getCreateTime()) + .taskId(cm.getId()) + .comment(Lists.list(cm)) + .result(ProcessHandlerParamsVo.Action.comment) + .build()).collect(Collectors.toList())); + if (CollectionUtil.isNotEmpty(userSet)) { + Map map = userDeptOrLeaderService.getUserMapByIds(userSet); + progressNodes.forEach(n -> { + if (WflowGlobalVarDef.WFLOW_TASK_AGRRE.equals(n.getUser().getId()) + || WflowGlobalVarDef.WFLOW_TASK_REFUSE.equals(n.getUser().getId())) { + n.setUser(WflowGlobalVarDef.SYS); + } else { + n.setUser(map.get(n.getUser().getId())); + n.getComment().forEach(c -> c.setUser(map.get(c.getUser().getId()))); + } + }); + } + return progressNodes; + } } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqProcessHandlerDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqProcessHandlerDTO.java new file mode 100644 index 0000000..db6eeb5 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqProcessHandlerDTO.java @@ -0,0 +1,82 @@ +package com.ningdatech.pmapi.todocenter.model.dto.req; +import com.ningdatech.pmapi.common.model.FileBasicInfo; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; +import java.time.LocalDateTime; + +/** + * 流程处理操作参数实体 + * + * @author CMM + * @since 2023/01/30 09:09 + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ReqProcessHandlerDTO { + + /** + * 实例ID + */ + private String instanceId; + /** + * 任务ID + */ + private String taskId; + /** + * 签名图片地址 + */ + private String signature; + /** + * 操作类型 + */ + private Action action; + /** + * 目标用户 + */ + private String targetUser; + /** + * 目标节点 + */ + private String targetNode; + /** + * 审核通过意见 + */ + private String auditApprovalOpinion; + + /** + * 审核通过附件 + */ + private FileBasicInfo auditApprovalAppendix; + /** + * 盖章通过意见 + */ + private String sealApprovalOpinion; + + /** + * 盖章通过附件 + */ + private FileBasicInfo sealApprovalAppendix; + /** + * 审核退回意见 + */ + private String auditBackOpinion; + /** + * 审核退回附件 + */ + private FileBasicInfo auditBackAppendix; + /** + * 审核驳回意见 + */ + private String auditRejectOpinion; + + /** + * 审核驳回附件 + */ + private FileBasicInfo auditRejectAppendix; + public enum Action{ + //通过、盖章并通过、退回、撤回、驳回 + pass, seal_pass ,back, withdraw, reject; + } +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProcessedDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProcessedDTO.java index a336779..be1bd57 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProcessedDTO.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProcessedDTO.java @@ -3,6 +3,7 @@ package com.ningdatech.pmapi.todocenter.model.dto.res; import java.io.Serializable; import java.time.LocalDateTime; +import com.ningdatech.pmapi.todocenter.bean.entity.ProcessTask; import com.wflow.workflow.bean.vo.ProcessTaskVo; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; @@ -49,5 +50,5 @@ public class ResToBeProcessedDTO implements Serializable { private LocalDateTime processLaunchTime; @ApiModelProperty("流程任务信息") - private ProcessTaskVo processTaskVo; + private ProcessTask processTaskInfo; } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProjectListExportDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProjectListExportDTO.java index 201bf7d..600eea6 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProjectListExportDTO.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProjectListExportDTO.java @@ -1,8 +1,6 @@ package com.ningdatech.pmapi.todocenter.model.dto.res; import com.alibaba.excel.annotation.ExcelProperty; -import com.wflow.workflow.bean.vo.ProcessTaskVo; -import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; From 4cefc73f611eb2f6dc7001cd5cd7422069f74990 Mon Sep 17 00:00:00 2001 From: CMM <2198256324@qq.com> Date: Tue, 31 Jan 2023 16:32:59 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=BE=85=E5=8A=9E=E4=B8=AD=E5=BF=83?= =?UTF-8?q?=E5=BE=85=E6=88=91=E5=A4=84=E7=90=86=E5=A4=84=E7=90=86=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../pmapi/todocenter/bean/entity/ProcessTask.java | 62 ---------- .../pmapi/todocenter/bean/entity/ProgressNode.java | 68 +++++++++++ .../bean/vo/ProcessProgressDetailVo.java | 70 +++++++++++ .../todocenter/bean/vo/ProcessProgressVo.java | 69 ----------- .../todocenter/constant/HisProInsEndActId.java | 25 ++++ .../controller/TodoCenterController.java | 5 +- .../pmapi/todocenter/enums/ProcessStatusEnum.java | 2 +- .../extension/cmd/BackToHisApprovalNodeCmd.java | 1 + .../pmapi/todocenter/manage/TodoCenterManage.java | 134 ++++++++------------- .../model/dto/req/ReqProcessHandlerDTO.java | 10 +- .../model/dto/res/ResToBeProcessedDTO.java | 3 +- 11 files changed, 224 insertions(+), 225 deletions(-) delete mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProcessTask.java create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProgressNode.java create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/vo/ProcessProgressDetailVo.java delete mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/vo/ProcessProgressVo.java create mode 100644 pmapi/src/main/java/com/ningdatech/pmapi/todocenter/constant/HisProInsEndActId.java diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProcessTask.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProcessTask.java deleted file mode 100644 index 61e7494..0000000 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProcessTask.java +++ /dev/null @@ -1,62 +0,0 @@ -package com.ningdatech.pmapi.todocenter.bean.entity; - -import com.wflow.workflow.bean.process.OrgUser; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.Date; - -/** - * 流程任务实体 - * - * @author CMM - * @since 2023/01/30 16:57 - */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class ProcessTask { - //任务ID - private String taskId; - //任务定义key - private String taskDefKey; - //流程定义ID - private String processDefId; - //流程执行ID - private String executionId; - //任务名称 - private String taskName; - //任务归属节点 - private String nodeId; - - //任务处理结果 - private String taskResult; - - //部署ID - private String deployId; - //流程定义名称 - private String processDefName; - //版本 - private Integer version; - //实例ID - private String instanceId; - - - //流程发起人 - private String ownerId; - private OrgUser owner; - //流程发起人部门ID - private String ownerDeptId; - //流程发起人部门名称 - private String ownerDeptName; - - //流程实例创建时间 - private Date createTime; - //task创建时间 - private Date taskCreateTime; - //task完成时间 - private Date taskEndTime; -} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProgressNode.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProgressNode.java new file mode 100644 index 0000000..baca90d --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/entity/ProgressNode.java @@ -0,0 +1,68 @@ +package com.ningdatech.pmapi.todocenter.bean.entity; + +import com.ningdatech.pmapi.todocenter.model.dto.req.ReqProcessHandlerDTO; +import com.wflow.workflow.bean.process.OrgUser; +import com.wflow.workflow.bean.process.enums.ApprovalModeEnum; +import com.wflow.workflow.bean.process.enums.NodeTypeEnum; +import com.wflow.workflow.bean.vo.ProcessHandlerParamsVo; +import com.wflow.workflow.bean.vo.TaskCommentVo; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; +import java.util.List; + +/** + * 流程节点实体 + * + * @author CMM + * @since 2023/01/31 12:24 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ProgressNode { + /** + * 节点ID + */ + private String nodeId; + /** + * 任务ID + */ + private String taskId; + /** + * 审批类型 + */ + private ApprovalModeEnum approvalMode; + /** + * 节点类型 + */ + private NodeTypeEnum nodeType; + /** + * 节点名称 + */ + private String name; + /** + * 节点相关人员 + */ + private OrgUser user; + /** + * 该节点动作操作类型 + */ + private ReqProcessHandlerDTO.Action action; + /** + * 处理结果 + */ + private ReqProcessHandlerDTO.Action result; + /** + * 开始时间 + */ + private Date startTime; + /** + * 结束时间 + */ + private Date finishTime; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/vo/ProcessProgressDetailVo.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/vo/ProcessProgressDetailVo.java new file mode 100644 index 0000000..502f292 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/vo/ProcessProgressDetailVo.java @@ -0,0 +1,70 @@ +package com.ningdatech.pmapi.todocenter.bean.vo; + +import com.ningdatech.pmapi.todocenter.bean.entity.ProgressNode; +import com.wflow.workflow.bean.process.OrgUser; +import com.wflow.workflow.bean.process.form.Form; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.util.Date; +import java.util.List; +import java.util.Map; + +/** + * 流程进展详情实体 + * + * @author CMM + * @since 2023/01/30 17:21 + */ +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +public class ProcessProgressDetailVo { + /** + * 审批实例ID + */ + private String instanceId; + /** + * 表单配置项 + */ + private List formItems; + /** + * 表单值 + */ + private Map formData; + /** + * 流程进度步骤 + */ + private List progress; + /** + * 流程定义名称 + */ + private String processDefName; + /** + * 版本 + */ + private Integer version; + /** + * 流程状态 + */ + private String status; + /** + * 流程结果 + */ + private String result; + /** + * 发起人 + */ + private OrgUser staterUser; + /** + * 发起人部门 + */ + private String starterDept; + /** + * 发起时间 + */ + private Date startTime; +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/vo/ProcessProgressVo.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/vo/ProcessProgressVo.java deleted file mode 100644 index 26eda63..0000000 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/bean/vo/ProcessProgressVo.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.ningdatech.pmapi.todocenter.bean.vo; - -import com.wflow.workflow.bean.process.OrgUser; -import com.wflow.workflow.bean.process.form.Form; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -import java.util.Date; -import java.util.List; -import java.util.Map; - -/** - * 流程进展详情实体 - * - * @author CMM - * @since 2023/01/30 17:21 - */ -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -public class ProcessProgressVo { - /** - * 审批实例ID - */ - private String instanceId; - /** - * 表单配置项 - */ - private List formItems; - /** - * 表单值 - */ - private Map formData; - /** - * 流程进度步骤 - */ - private List progress; - /** - * 流程定义名称 - */ - private String processDefName; - /** - * 版本 - */ - private Integer version; - /** - * 流程状态 - */ - private String status; - /** - * 流程结果 - */ - private String result; - /** - * 发起人 - */ - private OrgUser staterUser; - /** - * 发起人部门 - */ - private String starterDept; - /** - * 发起时间 - */ - private Date startTime; -} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/constant/HisProInsEndActId.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/constant/HisProInsEndActId.java new file mode 100644 index 0000000..b0900c5 --- /dev/null +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/constant/HisProInsEndActId.java @@ -0,0 +1,25 @@ +package com.ningdatech.pmapi.todocenter.constant; +/** + * 历史流程实例终点活跃ID状态 + * @author CMM + * @since 2023/01/31 15:13 + */ +public interface HisProInsEndActId { + /** + * 流程被驳回 + */ + public static final String REJECT = "refuse-end"; + /** + * 流程被退回 + */ + public static final String BACK = "back-end"; + /** + * 流程被撤回 + */ + public static final String WITHDRAW = "cancel-end"; + /** + * 流程结束 + */ + public static final String END = "process-end"; + +} diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java index d385fba..1b5863d 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/controller/TodoCenterController.java @@ -5,6 +5,7 @@ import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; import com.ningdatech.pmapi.common.util.ExcelDownUtil; +import com.ningdatech.pmapi.todocenter.bean.vo.ProcessProgressDetailVo; import com.ningdatech.pmapi.todocenter.model.dto.req.ReqProcessHandlerDTO; import com.wflow.utils.R; import com.wflow.workflow.bean.vo.ProcessHandlerParamsVo; @@ -65,8 +66,8 @@ public class TodoCenterController { * @return 流程进度及表单详情 */ @GetMapping("progress/{instanceId}/{nodeId}") - public ApiResponse getProcessDetail(@PathVariable String instanceId, - @PathVariable(required = false) String nodeId) { + public ApiResponse getProcessDetail(@PathVariable String instanceId, + @PathVariable(required = false) String nodeId) { return ApiResponse.ofSuccess(todoCenterManage.getProcessDetail(nodeId, instanceId)); } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/enums/ProcessStatusEnum.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/enums/ProcessStatusEnum.java index 66d3c73..822f5c8 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/enums/ProcessStatusEnum.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/enums/ProcessStatusEnum.java @@ -27,7 +27,7 @@ public enum ProcessStatusEnum { /** * 被退回 */ - BE_RETURNED(2, "被退回"), + BE_BACKED(2, "被退回"), /** * 被驳回 diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/extension/cmd/BackToHisApprovalNodeCmd.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/extension/cmd/BackToHisApprovalNodeCmd.java index 59ad0c0..34a7286 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/extension/cmd/BackToHisApprovalNodeCmd.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/extension/cmd/BackToHisApprovalNodeCmd.java @@ -47,6 +47,7 @@ public class BackToHisApprovalNodeCmd implements Command, Serializable { @Override public String execute(CommandContext commandContext) { + if (targetNodeId == null || targetNodeId.length() == 0) { throw new FlowableException("退回的目标节点不能为空"); } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java index 6e2e75b..ce658b9 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/manage/TodoCenterManage.java @@ -3,7 +3,6 @@ import cn.hutool.core.collection.CollectionUtil; import cn.hutool.core.util.ObjectUtil; import cn.hutool.core.util.StrUtil; import com.alibaba.excel.EasyExcel; -import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ningdatech.basic.exception.BizException; @@ -11,7 +10,9 @@ import com.ningdatech.basic.util.NdDateUtils; import com.ningdatech.pmapi.common.constant.ProjectDeclareConstants; import com.ningdatech.pmapi.common.util.ExcelDownUtil; import com.ningdatech.pmapi.common.util.ExcelExportStyle; -import com.ningdatech.pmapi.todocenter.bean.entity.ProcessTask; +import com.ningdatech.pmapi.todocenter.bean.entity.ProgressNode; +import com.ningdatech.pmapi.todocenter.bean.vo.ProcessProgressDetailVo; +import com.ningdatech.pmapi.todocenter.constant.HisProInsEndActId; import com.ningdatech.pmapi.todocenter.enums.ProcessStatusEnum; import com.ningdatech.pmapi.todocenter.extension.cmd.BackToHisApprovalNodeCmd; import com.ningdatech.pmapi.todocenter.model.dto.req.ReqProcessHandlerDTO; @@ -30,16 +31,13 @@ import com.wflow.workflow.bean.process.enums.ApprovalModeEnum; import com.wflow.workflow.bean.process.enums.NodeTypeEnum; import com.wflow.workflow.bean.process.form.Form; import com.wflow.workflow.bean.process.props.ApprovalProps; -import com.wflow.workflow.bean.vo.ProcessHandlerParamsVo; import com.wflow.workflow.bean.vo.ProcessProgressVo; -import com.wflow.workflow.bean.vo.TaskCommentVo; +import com.wflow.workflow.bean.vo.ProcessTaskVo; import com.wflow.workflow.config.WflowGlobalVarDef; import com.wflow.workflow.service.*; import com.wflow.workflow.service.FormService; import lombok.extern.slf4j.Slf4j; -import org.assertj.core.util.Lists; import org.assertj.core.util.Maps; -import org.flowable.common.engine.impl.identity.Authentication; import org.flowable.engine.*; import org.flowable.engine.history.HistoricActivityInstance; import org.flowable.engine.history.HistoricProcessInstance; @@ -116,7 +114,7 @@ public class TodoCenterManage { ProcessInstanceOwnerDto owner = runtimeService.getVariable(task.getExecutionId(), "owner", ProcessInstanceOwnerDto.class); ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(task.getProcessInstanceId()).singleResult(); staterUsers.add(owner.getOwner()); - ProcessTask processTask = ProcessTask.builder() + ProcessTaskVo processTaskVo = ProcessTaskVo.builder() .taskId(task.getId()) .taskName(task.getName()) .taskDefKey(task.getTaskDefinitionKey()) @@ -133,7 +131,7 @@ public class TodoCenterManage { .createTime(processInstance.getStartTime()) .taskCreateTime(task.getCreateTime()) .build(); - res.setProcessTaskInfo(processTask); + res.setProcessTaskInfo(processTaskVo); String projectName = (String) formData.get(ProjectDeclareConstants.BasicInformation.PROJECT_NAME); res.setProjectName(projectName); res.setReportUnitId(owner.getOwnerDeptId()); @@ -195,15 +193,15 @@ public class TodoCenterManage { switch (param.getAction()) { // 通过 case pass: - formData.put("audit_pass_opinion",param.getAuditApprovalOpinion()); - formData.put("audit_pass_appendix",param.getAuditApprovalAppendix()); + formData.put("audit_pass_opinion",param.getAuditPassOpinion()); + formData.put("audit_pass_appendix",param.getAuditPassAppendix()); formData.put("audit_pass_time", auditTime); formService.updateInstanceFormData(param.getInstanceId(), formData); doPass(task, param); // 盖章并通过 case seal_pass: - formData.put("seal_pass_opinion",param.getSealApprovalOpinion()); - formData.put("seal_pass_appendix",param.getSealApprovalAppendix()); + formData.put("seal_pass_opinion",param.getSealPassOpinion()); + formData.put("seal_pass_appendix",param.getSealPassAppendix()); Date sealPassTime = NdDateUtils.localDateTime2Date(LocalDateTime.now()); formData.put("seal_pass_time",sealPassTime); formService.updateInstanceFormData(param.getInstanceId(), formData); @@ -231,7 +229,6 @@ public class TodoCenterManage { default: throw new IllegalStateException("Unexpected value: " + param.getAction()); } - Authentication.setAuthenticatedUserId(null); } /** @@ -242,7 +239,7 @@ public class TodoCenterManage { */ private void doReject(Task task, ReqProcessHandlerDTO param) { Map var = new HashMap<>(16); - var.put("reject_" + task.getId(), param.getAction()); + var.put("approve_" + task.getId(), param.getAction()); // TODO 中止流程并使项目进入对应状态 // TODO 给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被驳回,请及时处理。 taskService.complete(param.getTaskId(), var); @@ -256,7 +253,7 @@ public class TodoCenterManage { */ private void doSealPass(Task task, ReqProcessHandlerDTO param) { Map var = new HashMap<>(16); - var.put("seal_pass_" + task.getId(), param.getAction()); + var.put("approve_" + task.getId(), param.getAction()); // TODO 判断项目申报单位级别,区县单位申报有上级主管单位意见栏,市级单位没有 // TODO 市级单位:为大数据局;区县单位:为大数据中心(根据附件区分?) taskService.complete(param.getTaskId(), var); @@ -270,7 +267,7 @@ public class TodoCenterManage { */ private void doPass(Task task, ReqProcessHandlerDTO param) { Map var = new HashMap<>(16); - var.put("pass_" + task.getId(), param.getAction()); + var.put("approve_" + task.getId(), param.getAction()); // TODO 获取流程下一个节点的审核人 // TODO 若有下一个审核人,向其发送浙政钉工作通知:标题:审核任务 内容:【单位名称】的【项目名称】需要您审核。 @@ -290,12 +287,12 @@ public class TodoCenterManage { List executions = runtimeService.createExecutionQuery() .processInstanceId(task.getProcessInstanceId()) .onlyChildExecutions().list(); - // 强制流程指向驳回 + // 强制流程指向撤回 runtimeService.createChangeActivityStateBuilder() .processInstanceId(task.getProcessInstanceId()) - .moveActivityIdTo(task.getTaskDefinitionKey(), "cancel-end") + .moveActivityIdTo(task.getTaskDefinitionKey(), HisProInsEndActId.WITHDRAW) .moveExecutionsToSingleActivityId(executions.stream().map(Execution::getId) - .collect(Collectors.toList()), "cancel-end") + .collect(Collectors.toList()), HisProInsEndActId.WITHDRAW) .changeState(); } @@ -311,7 +308,7 @@ public class TodoCenterManage { // TODO 给项目创建人、流程发起人发送浙政钉工作通知:【项目名称】的【流程名称】被退回,请及时处理。 //执行自定义回退逻辑 managementService.executeCommand(new BackToHisApprovalNodeCmd(runtimeService, param.getTaskId(), param.getTargetNode())); - runtimeService.setVariables(param.getInstanceId(), Maps.newHashMap("back_" + param.getTaskId(), param.getAction())); + runtimeService.setVariables(param.getInstanceId(), Maps.newHashMap("approve_" + param.getTaskId(), param.getAction())); log.info("用户[{}] 退回流程[{}] [{} -> {}]", userId, param.getInstanceId(), current, param.getTargetNode()); } @@ -321,7 +318,7 @@ public class TodoCenterManage { * @param nodeId 当前获取流程人员关联的流程节点ID * @return 流程进度及表单详情 */ - public Object getProcessDetail(String nodeId, String instanceId) { + public ProcessProgressDetailVo getProcessDetail(String nodeId, String instanceId) { HistoricProcessInstance instance = historyService.createHistoricProcessInstanceQuery().processInstanceId(instanceId).singleResult(); // 取表单及表单数据 HistoricVariableInstance forms = historyService.createHistoricVariableInstanceQuery() @@ -332,7 +329,6 @@ public class TodoCenterManage { HistoricVariableInstance nodeProps = historyService.createHistoricVariableInstanceQuery() .processInstanceId(instanceId).variableName(WflowGlobalVarDef.WFLOW_NODE_PROPS).singleResult(); Map nodePropsValue = (Map) nodeProps.getValue(); - ProcessNode currentNode = null; if (StrUtil.isNotBlank(nodeId)) { // 搜索当前版本流程的配置 @@ -342,15 +338,17 @@ public class TodoCenterManage { } UserDo users = orgRepositoryService.getUserById(instance.getStartUserId()); OrgUser startUser = OrgUser.builder().id(users.getUserId()).name(users.getUserName()).avatar(users.getAvatar()).build(); - List taskRecords = getHisTaskRecords(instanceId, nodePropsValue); + List taskRecords = getHisTaskRecords(instanceId, nodePropsValue); + // 获取添加抄送任务 taskRecords.addAll(getCcTaskRecords(instanceId)); if (ObjectUtil.isNull(instance.getEndTime())) { - taskRecords.addAll(processTaskService.getFutureTask(instanceId)); + // TODO 下版实现 获取等待中且还未开始的任务,如果存在条件则需要直接解析条件 + taskRecords.addAll(getFutureTask(instanceId)); } taskRecords = taskRecords.stream() - .sorted(Comparator.comparing(ProcessProgressVo.ProgressNode::getStartTime)) + .sorted(Comparator.comparing(ProgressNode::getStartTime)) .collect(Collectors.toList()); - taskRecords.add(0, ProcessProgressVo.ProgressNode.builder() + taskRecords.add(0, ProgressNode.builder() .nodeId("root") .name("提交申请") .user(startUser) @@ -358,14 +356,14 @@ public class TodoCenterManage { .startTime(instance.getStartTime()) .finishTime(instance.getStartTime()) .taskId("root") - .result(ProcessHandlerParamsVo.Action.agree) + .result(ReqProcessHandlerDTO.Action.pass) .build()); // 提取全量表单数据 Map formData = formDatas.stream().collect(Collectors.toMap(HistoricVariableInstance::getVariableName, HistoricVariableInstance::getValue)); HistoricVariableInstance variableInstance = historyService.createHistoricVariableInstanceQuery() .processInstanceId(instanceId).variableName("owner").singleResult(); ProcessInstanceOwnerDto owner = (ProcessInstanceOwnerDto) variableInstance.getValue(); - return ProcessProgressVo.builder() + ProcessProgressDetailVo res = ProcessProgressDetailVo.builder() .instanceId(instanceId) .version(instance.getProcessDefinitionVersion()) .formItems(formService.filterFormAndDataByPermConfig((List) forms.getValue(), formData, currentNode)) @@ -373,11 +371,20 @@ public class TodoCenterManage { .processDefName(instance.getProcessDefinitionName()) .staterUser(startUser) .starterDept(null == owner ? null : owner.getOwnerDeptName()) - .status(ObjectUtil.isNull(instance.getEndActivityId()) ? "RUNNING" : "COMPLETE") .result(instance.getEndActivityId()) .startTime(instance.getStartTime()) .progress(taskRecords) .build(); + if (Objects.isNull(instance.getEndActivityId())){ + res.setStatus(ProcessStatusEnum.UNDER_REVIEW.name()); + } else if (HisProInsEndActId.BACK.equals(instance.getEndActivityId())) { + res.setStatus(ProcessStatusEnum.BE_BACKED.name()); + } else if (HisProInsEndActId.REJECT.equals(instance.getEndActivityId())) { + res.setStatus(ProcessStatusEnum.BE_REJECTED.name()); + } else if (HisProInsEndActId.END.equals(instance.getEndActivityId())) { + res.setStatus(ProcessStatusEnum.APPROVED.name()); + } + return res; } /** @@ -386,16 +393,15 @@ public class TodoCenterManage { * @param instanceId 实例ID * @return 抄送我的流程 */ - private List getCcTaskRecords(String instanceId) { + private List getCcTaskRecords(String instanceId) { Set ccUsers = new HashSet<>(); - List ccList = ccTasksMapper.selectList(new QueryWrapper() + List ccList = ccTasksMapper.selectList(new QueryWrapper() .eq("instance_id", instanceId)).stream().map(task -> { ccUsers.add(task.getUserId()); - return ProcessProgressVo.ProgressNode.builder() + return ProgressNode.builder() .nodeId(task.getNodeId()) .nodeType(NodeTypeEnum.CC) .name(task.getNodeName()) - .comment(Collections.emptyList()) .user(OrgUser.builder().id(task.getUserId()).build()) .startTime(task.getCreateTime()) .finishTime(task.getCreateTime()) @@ -415,46 +421,22 @@ public class TodoCenterManage { * @param nodeProps 节点设置 * @return 历史记录列表 */ - private List getHisTaskRecords(String instanceId, Map nodeProps) { + private List getHisTaskRecords(String instanceId, Map nodeProps) { List list = historyService.createHistoricActivityInstanceQuery() .processInstanceId(instanceId).orderByHistoricActivityInstanceStartTime().asc().list(); Set userSet = new HashSet<>(); //获取节点处理结果 - Map varMap = historyService.createHistoricVariableInstanceQuery() + Map varMap = historyService.createHistoricVariableInstanceQuery() .processInstanceId(instanceId).variableNameLike("approve_%").list().stream() - .collect(Collectors.toMap(HistoricVariableInstance::getVariableName, v -> (ProcessHandlerParamsVo.Action) v.getValue())); - Map> commentMap = new HashMap<>(); - //统一处理所有评论数据,省的多次查询 - List cmvos = taskService.getProcessInstanceComments(instanceId).stream().map(comment -> { - userSet.add(comment.getUserId()); - TaskCommentVo commentVo = TaskCommentVo.builder() - .id(comment.getId()) - .taskId(comment.getTaskId()) - .commentType(comment.getType()) - .type("COMMENT") - .createTime(comment.getTime()) - .user(OrgUser.builder().id(comment.getUserId()).build()) - .build(); - ProcessHandlerParamsVo.ProcessComment processComment = JSONObject.parseObject(comment.getFullMessage(), ProcessHandlerParamsVo.ProcessComment.class); - commentVo.setText(processComment.getText()); - commentVo.setAttachments(processComment.getAttachments()); - return commentVo; - }).collect(Collectors.toList()); - cmvos.forEach(cm -> { - //把评论数据按照task进行归类 - String taskId = Optional.ofNullable(cm.getTaskId()).orElse(instanceId); - List vos = commentMap.computeIfAbsent(taskId, k -> new ArrayList<>()); - vos.add(cm); - }); - List progressNodes = list.stream().filter(his -> ObjectUtil.isNotNull(his.getTaskId())).map(his -> { + .collect(Collectors.toMap(HistoricVariableInstance::getVariableName, v -> (ReqProcessHandlerDTO.Action) v.getValue())); + List progressNodes = list.stream().filter(his -> ObjectUtil.isNotNull(his.getTaskId())).map(his -> { Object props = nodeProps.get(his.getActivityId()); ApprovalModeEnum approvalMode = null; if (props instanceof ApprovalProps) { approvalMode = ((ApprovalProps) props).getMode(); } userSet.add(his.getAssignee()); - List commentVos = commentMap.getOrDefault(his.getTaskId(), Collections.emptyList()); - return ProcessProgressVo.ProgressNode.builder() + return ProgressNode.builder() .nodeId(his.getActivityId()) .name(his.getActivityName()) .nodeType(NodeTypeEnum.APPROVAL) @@ -463,34 +445,18 @@ public class TodoCenterManage { .finishTime(his.getEndTime()) .taskId(his.getTaskId()) .approvalMode(approvalMode) - .comment(commentVos) .result(varMap.get("approve_" + his.getTaskId())) .build(); }).collect(Collectors.toList()); - //将非任务类的评论转换成流程节点 - progressNodes.addAll(commentMap.getOrDefault(instanceId, Collections.emptyList()).stream().map(cm -> - ProcessProgressVo.ProgressNode.builder() - .nodeId(cm.getId()) - .name("参与评论") - .user(cm.getUser()) - .startTime(cm.getCreateTime()) - .finishTime(cm.getCreateTime()) - .taskId(cm.getId()) - .comment(Lists.list(cm)) - .result(ProcessHandlerParamsVo.Action.comment) - .build()).collect(Collectors.toList())); if (CollectionUtil.isNotEmpty(userSet)) { Map map = userDeptOrLeaderService.getUserMapByIds(userSet); - progressNodes.forEach(n -> { - if (WflowGlobalVarDef.WFLOW_TASK_AGRRE.equals(n.getUser().getId()) - || WflowGlobalVarDef.WFLOW_TASK_REFUSE.equals(n.getUser().getId())) { - n.setUser(WflowGlobalVarDef.SYS); - } else { - n.setUser(map.get(n.getUser().getId())); - n.getComment().forEach(c -> c.setUser(map.get(c.getUser().getId()))); - } - }); + progressNodes.forEach(n -> n.setUser(map.get(n.getUser().getId()))); } return progressNodes; } + + private List getFutureTask(String instanceId) { + //根据流程遍历后续节点,期间要穿越后续包含并行网关和条件网关的节点 + return Collections.emptyList(); + } } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqProcessHandlerDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqProcessHandlerDTO.java index db6eeb5..1e9e424 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqProcessHandlerDTO.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/req/ReqProcessHandlerDTO.java @@ -43,21 +43,21 @@ public class ReqProcessHandlerDTO { /** * 审核通过意见 */ - private String auditApprovalOpinion; + private String auditPassOpinion; /** * 审核通过附件 */ - private FileBasicInfo auditApprovalAppendix; + private FileBasicInfo auditPassAppendix; /** * 盖章通过意见 */ - private String sealApprovalOpinion; + private String sealPassOpinion; /** * 盖章通过附件 */ - private FileBasicInfo sealApprovalAppendix; + private FileBasicInfo sealPassAppendix; /** * 审核退回意见 */ @@ -76,7 +76,7 @@ public class ReqProcessHandlerDTO { */ private FileBasicInfo auditRejectAppendix; public enum Action{ - //通过、盖章并通过、退回、撤回、驳回 + //通过、盖章并通过、退回、撤回、驳回,审核意见类型 pass, seal_pass ,back, withdraw, reject; } } diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProcessedDTO.java b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProcessedDTO.java index be1bd57..0df7691 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProcessedDTO.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/todocenter/model/dto/res/ResToBeProcessedDTO.java @@ -3,7 +3,6 @@ package com.ningdatech.pmapi.todocenter.model.dto.res; import java.io.Serializable; import java.time.LocalDateTime; -import com.ningdatech.pmapi.todocenter.bean.entity.ProcessTask; import com.wflow.workflow.bean.vo.ProcessTaskVo; import io.swagger.annotations.ApiModelProperty; import lombok.AllArgsConstructor; @@ -50,5 +49,5 @@ public class ResToBeProcessedDTO implements Serializable { private LocalDateTime processLaunchTime; @ApiModelProperty("流程任务信息") - private ProcessTask processTaskInfo; + private ProcessTaskVo processTaskInfo; } From e7ef4bc34876b0b6073c5f269a285e7561c0602c Mon Sep 17 00:00:00 2001 From: WendyYang Date: Tue, 31 Jan 2023 17:59:31 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=A1=AB=E5=85=85?= =?UTF-8?q?=E7=AD=96=E7=95=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/Notice.java | 9 +++++---- .../java/com/ningdatech/pmapi/sys/entity/req/NoticeListReq.java | 4 ++-- .../java/com/ningdatech/pmapi/sys/entity/req/NoticeSaveReq.java | 1 - 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/Notice.java b/pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/Notice.java index e098ce9..97131be 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/Notice.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/Notice.java @@ -1,9 +1,6 @@ package com.ningdatech.pmapi.sys.entity; -import com.baomidou.mybatisplus.annotation.IdType; -import com.baomidou.mybatisplus.annotation.TableId; -import com.baomidou.mybatisplus.annotation.TableLogic; -import com.baomidou.mybatisplus.annotation.TableName; +import com.baomidou.mybatisplus.annotation.*; import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; @@ -46,15 +43,19 @@ public class Notice implements Serializable { private String attachment; @ApiModelProperty("创建时间") + @TableField(fill = FieldFill.INSERT) private LocalDateTime createOn; @ApiModelProperty("创建人id") + @TableField(fill = FieldFill.INSERT) private Long createBy; @ApiModelProperty("最后修改时间") + @TableField(fill = FieldFill.INSERT_UPDATE) private LocalDateTime updateOn; @ApiModelProperty("最后修改人") + @TableField(fill = FieldFill.INSERT_UPDATE) private Long updateBy; @ApiModelProperty("是否删除") diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/req/NoticeListReq.java b/pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/req/NoticeListReq.java index e771094..50e4a0e 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/req/NoticeListReq.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/req/NoticeListReq.java @@ -8,14 +8,14 @@ import lombok.EqualsAndHashCode; /** *

- * DashboardNoticeListPo + * NoticeListReq *

* * @author WendyYang * @since 00:32 2022/7/23 */ @Data -@ApiModel("工作台消息列表查询") +@ApiModel("公告查询参数类") @EqualsAndHashCode(callSuper = true) public class NoticeListReq extends PagePo { diff --git a/pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/req/NoticeSaveReq.java b/pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/req/NoticeSaveReq.java index 9a5bf52..778b7da 100644 --- a/pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/req/NoticeSaveReq.java +++ b/pmapi/src/main/java/com/ningdatech/pmapi/sys/entity/req/NoticeSaveReq.java @@ -4,7 +4,6 @@ import io.swagger.annotations.ApiModel; import io.swagger.annotations.ApiModelProperty; import lombok.Data; -import javax.validation.Valid; import javax.validation.constraints.NotBlank; import javax.validation.constraints.NotNull;