当前位置 博文首页 > 大风起兮云飞扬:Activiti6--[7] 查询流程中当前节点办理人以及

    大风起兮云飞扬:Activiti6--[7] 查询流程中当前节点办理人以及

    作者:[db:作者] 时间:2021-08-08 10:17

    前提

    使用activiti的流程设计器指派任务时候,因为显示的时候要显示中文,存储要是用户的id,所以在这里进行了改造,在选择的时候,{nane:"",value:""}的格式存储指派信息。

    问题

    指派任务成功,并且成功让对应指派的人查到属于它们自己的任务。但是有一个问题,发起人希望看到自己发起的流程,如果是正在运行中的流程,希望能看到当前节点的办理人是谁。

    效果

    选择用户
    显示办理用户信息

    思路

    1. 正常分页查询历史流程,遍历历史流程中仍然在运行的流程
    2. 获取当前流程中需要做的任务节点
    3. 获取当前流程定义对应的流程model,遍历任务节点与当前待做的任务节点进行匹配
    4. 获取节点,遍历候选人,候选组将其作为当前审批人返回

    实现

        @Transactional(readOnly = true)
        @Override
        public PageDto<XKHistoryProcessInstanceDto> pageProcessHistory(PageQueryDto<XKHistoryProcessInstanceDto> pageQueryDto) {
    
            XKHistoryProcessInstanceDto xkHistoryProcessInstanceDto = pageQueryDto.genQueryObject(XKHistoryProcessInstanceDto.class);
    
            // 判断是否有发起人的信息
            if (xkHistoryProcessInstanceDto == null || StringUtils.isEmpty(xkHistoryProcessInstanceDto.getStartUserId())) {
                return null;
    
            }
    
            //查询
            List<HistoricProcessInstance> list =
                    historyService.createHistoricProcessInstanceQuery()
                            .startedBy(xkHistoryProcessInstanceDto.getStartUserId())
                            .orderByProcessInstanceEndTime().asc()
                            .orderByProcessInstanceStartTime().asc()
                            .listPage(pageQueryDto.getPageSize() * pageQueryDto.getPageIndex(),
                                    pageQueryDto.getPageSize());
            long count = historyService.createHistoricProcessInstanceQuery()
                    .startedBy(xkHistoryProcessInstanceDto.getStartUserId()).count();
    
    
            List<XKHistoryProcessInstanceDto> xkHistoryProcessInstanceDtos = BeanMapperUtils.mapList(list, HistoricProcessInstance.class, XKHistoryProcessInstanceDto.class);
    
            // 查询正在办理的流程中的当前节点的办理人
            for (XKHistoryProcessInstanceDto historicProcessInstance : xkHistoryProcessInstanceDtos) {
                if (historicProcessInstance.getEndTime() != null) {
                    continue;
                }
                String id = historicProcessInstance.getId();
                Task task = taskService.createTaskQuery().processInstanceId(id).singleResult();
                // 查询当前的执行节点
                ExecutionEntity ee = (ExecutionEntity) runtimeService.createExecutionQuery()
                        .executionId(task.getExecutionId())
                        .singleResult();
    	// 获取部署对应的model
                Model model = repositoryService.createModelQuery().deploymentId(historicProcessInstance.getDeploymentId()).singleResult();
                JsonNode childShapes = null;
                try {
                    ObjectNode editorJsonNode = (ObjectNode) objectMapper.readTree(
                            new String(repositoryService.getModelEditorSource(model.getId()), "utf-8"));
                    childShapes = editorJsonNode.get("childShapes");
                } catch (Exception e) {
                    LOGGER.error("Error creating model JSON", e);
                    throw new ActivitiException("Error creating model JSON", e);
                }
                    childShapes.forEach(e -> {
                        // 判断当前节点是否与当前任务的id一致
                        if (e.get("resourceId").asText().equals(ee.getActivityId())) {
                         // 获取model中关于该节点设置的相关候选组,候选角色
                            List<XKIdentityLinkDto> todoUser = new ArrayList<>();
                            JsonNode jsonNode = e.get("properties").get("usertaskassignment").get("assignment");
                            JsonNode candidateGroups = jsonNode.get("candidateGroups");
                            JsonNode candidateUsers = jsonNode.get("candidateUsers");
                            if (candidateGroups != null) {
                                candidateGroups.forEach(g -> {
                                    XKIdentityLinkDto xkIdentityLinkDto = new XKIdentityLinkDto(g.get("value").asText(), g.get("name").asText());
                                    todoUser.add(xkIdentityLinkDto);
                                });
                            }
    
                            if (candidateUsers != null) {
                                candidateUsers.forEach(u -> {
                                    XKIdentityLinkDto xkIdentityLinkDto = new XKIdentityLinkDto(u.get("value").asText(), u.get("name").asText());
                                    todoUser.add(xkIdentityLinkDto);
                                });
                            }
                            // 设置当前
                            historicProcessInstance.setTodoUser(todoUser);
                        }
                    });
            }
    
            PageDto<XKHistoryProcessInstanceDto> pd = new PageDto<XKHistoryProcessInstanceDto>(
                    xkHistoryProcessInstanceDtos,
                    count,
                    new Long(count % pageQueryDto.getPageSize() == 0 ? count / pageQueryDto.getPageSize() : count / pageQueryDto.getPageSize() + 1).intValue(),
                    pageQueryDto.getPageIndex() + 1);
            return pd;
        }
    

    问题

    • 在部署成功后,可以反向生成模型,但是此时应该没有必要重新生成模型了,因为一旦发布之后(部署),会自动生成一个旧版模型与该次部署绑定。
    • 如果通过开发人员设计了流程导入系统中,可能出现问题,因为上传的xml文件没有多余文字的信息,只有id,这是一个问题,待解决。
    • 实现方法里面有一些dto是为了方便前端操作而自定义的一个dto类,字段与activiti返回的类中字段保持一致,只保留了需要的属性。
    cs