luohairen
2024-12-10 b24e024f386e7f25a071b58e9267a2c19f20ba1e
Merge remote-tracking branch 'origin/master'
12个文件已修改
446 ■■■■ 已修改文件
business/src/main/java/com/ycl/controller/ProjectInfoController.java 20 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
business/src/main/java/com/ycl/domain/entity/ProjectInfo.java 4 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
business/src/main/java/com/ycl/domain/form/ProjectInfoForm.java 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
business/src/main/java/com/ycl/domain/vo/CustomerTaskVO.java 9 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
business/src/main/java/com/ycl/service/ProjectInfoService.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
business/src/main/java/com/ycl/service/impl/ProjectInfoServiceImpl.java 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java 135 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
flowable/src/main/java/com/ycl/common/constant/ProcessConstants.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
flowable/src/main/java/com/ycl/controller/FlowTaskController.java 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
flowable/src/main/java/com/ycl/service/IFlowTaskService.java 8 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
flowable/src/main/java/com/ycl/service/common/TaskCommonService.java 145 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
flowable/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java 91 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
business/src/main/java/com/ycl/controller/ProjectInfoController.java
@@ -44,12 +44,14 @@
    public Result add(@RequestBody @Validated(Add.class) ProjectInfoForm form) {
        return projectInfoService.add(form);
    }
    @PostMapping("/document")
    @ApiOperation(value = "添加相关文件", notes = "添加相关文件")
//    @PreAuthorize("hasAuthority('projectInfo:add')")
    public Result addDoc(@RequestBody @Validated(Add.class) DocumentInfoForm form) {
        return projectInfoService.addDoc(form);
    }
    @PutMapping
    @ApiOperation(value = "修改", notes = "修改")
//    @PreAuthorize("hasAuthority('projectInfo:edit')")
@@ -84,12 +86,14 @@
    public Result detail(@PathVariable("id") Integer id) {
        return projectInfoService.detail(id);
    }
    @GetMapping("/document/{id}")
    @ApiOperation(value = "相关文件详情", notes = "相关文件详情")
//    @PreAuthorize("hasAuthority('projectInfo:detail')")
    public Result docDetail(@PathVariable("id") Integer id) {
        return projectInfoService.docDetail(id);
    }
    @GetMapping("/list")
//    @PreAuthorize("hasAuthority('projectInfo:list')")
    @ApiOperation(value = "列表", notes = "列表")
@@ -99,12 +103,15 @@
    /**
     * 生成项目编号
     *
     * @return 项目编号
     */
    @GetMapping("/getProjectCode")
    public Result generateProjectCode() {
        return Result.ok().data(ProjectCodeGenerator.generateProjectCode());
    };
    }
    ;
    @GetMapping("/getManagerFlag/{recordId}")
    public Result getManagerFlag(@PathVariable("recordId") Integer recordId) {
@@ -113,17 +120,19 @@
    /**
     * 导出模板
     *
     * @param response
     * @return
     */
    @PostMapping("/export/template")
    public void exportTemplate(HttpServletResponse response) throws IOException {
        List<String> fieldList = new ArrayList<>();
        OutputExcelUtils.export(response, "导入模板", "项目信息", null, ProjectExcelTemplate.class ,fieldList);
        OutputExcelUtils.export(response, "导入模板", "项目信息", null, ProjectExcelTemplate.class, fieldList);
    }
    /**
     * 项目导出
     *
     * @param response
     * @throws IOException
     */
@@ -131,4 +140,11 @@
    public void export(HttpServletResponse response, ProjectExportQuery query) throws IOException {
        projectInfoService.export(response, query);
    }
    @PutMapping("usedStatus/{id}/{usedStatus}")
    @ApiOperation(value = "修改使用状态", notes = "修改使用状态")
//    @PreAuthorize("hasAuthority('projectInfo:edit')")
    public Result updateUsedStatus(@PathVariable Integer id, @PathVariable Integer usedStatus) {
        return projectInfoService.updateUsedStatus(id, usedStatus);
    }
}
business/src/main/java/com/ycl/domain/entity/ProjectInfo.java
@@ -141,5 +141,7 @@
    /** 创建人 */
    private Long createBy;
    @TableField("used_status")
    /** 使用状态(0:草稿,1:提交,2:审核通过,-1:驳回) */
    private Integer usedStatus;
}
business/src/main/java/com/ycl/domain/form/ProjectInfoForm.java
@@ -121,6 +121,9 @@
    @ApiModelProperty("联系方式")
    private String contact;
    @ApiModelProperty("使用状态")
    private Integer usedStatus;
    public static ProjectInfo getEntityByForm(@NonNull ProjectInfoForm form, ProjectInfo entity) {
        if(entity == null) {
          entity = new ProjectInfo();
business/src/main/java/com/ycl/domain/vo/CustomerTaskVO.java
@@ -21,6 +21,11 @@
    private String taskId;
    /**
     * 任务定义id
     */
    private String taskDefinitionKey;
    /**
     * flowable流程实例id
     */
    private String processInsId;
@@ -53,7 +58,7 @@
    /**
     * 发起人id
     */
    private Long promoterId;
    private String promoterId;
    /**
     * 发起人姓名
@@ -63,7 +68,7 @@
    /**
     * 发起人单位
     */
    private Long promoterUnitId;
    private String promoterUnitId;
    /**
     * 发起人单位名称
business/src/main/java/com/ycl/service/ProjectInfoService.java
@@ -82,4 +82,6 @@
    Result getManagerFlag(Integer recordId);
    void export(HttpServletResponse response, ProjectExportQuery query) throws IOException;
    Result updateUsedStatus(Integer id, Integer usedStatus);
}
business/src/main/java/com/ycl/service/impl/ProjectInfoServiceImpl.java
@@ -464,12 +464,12 @@
                                //审批计划书
                                item.setApprovalPlan(file.getOriginalName());
                            }
                        }else if(FileTypeEnum.DOCUMENT_INFO.equals(file.getType())){
                        } else if (FileTypeEnum.DOCUMENT_INFO.equals(file.getType())) {
                            if (file.getBusId().equals(item.getId())) {
                                //相关文书
                                item.setDocuments(file.getOriginalName());
                            }
                        }else if(FileTypeEnum.INVEST_POLICY.equals(file.getType())){
                        } else if (FileTypeEnum.INVEST_POLICY.equals(file.getType())) {
                            if (file.getBusId().equals(item.getPolicyId())) {
                                //符合产业政策附件
                                item.setPolicyComplianceAttachment(file.getOriginalName());
@@ -536,4 +536,14 @@
            }
        }
    }
    @Override
    public Result updateUsedStatus(Integer id, Integer usedStatus) {
        ProjectInfo entity = baseMapper.selectById(id);
        // 为空抛IllegalArgumentException,做全局异常处理
        Assert.notNull(entity, "记录不存在");
        entity.setUsedStatus(usedStatus);
        baseMapper.updateById(entity);
        return Result.ok("删除成功");
    }
}
business/src/main/java/com/ycl/service/impl/ProjectProcessServiceImpl.java
@@ -29,6 +29,7 @@
import com.ycl.domain.form.ProjectProcessForm;
import com.ycl.domain.vo.ProjectProcessVO;
import com.ycl.domain.query.ProjectProcessQuery;
import com.ycl.service.common.TaskCommonService;
import com.ycl.system.service.ISysDeptService;
import com.ycl.system.service.ISysRoleService;
import com.ycl.system.service.ISysUserService;
@@ -78,6 +79,7 @@
    private final ISysUserService sysUserService;
    private final ISysRoleService sysRoleService;
    private final ISysDeptService sysDeptService;
    private final TaskCommonService taskCommonService;
    /**
     * 分页查询
@@ -113,14 +115,16 @@
        if (Objects.nonNull(pp.getProcessInsId())) {
            HistoricProcessInstance historicProcessInstance =
                    historyService.createHistoricProcessInstanceQuery().processInstanceId(pp.getProcessInsId()).singleResult();
            // 删除之前流程的数据
            if (historicProcessInstance.getEndTime() != null) {
                historyService.deleteHistoricProcessInstance(historicProcessInstance.getId());
            } else {
                // 删除流程实例
                runtimeService.deleteProcessInstance(pp.getProcessInsId(), "");
                // 删除历史流程实例
                historyService.deleteHistoricProcessInstance(pp.getProcessInsId());
            if (Objects.nonNull(historicProcessInstance)) {
                // 删除之前流程的数据
                if (historicProcessInstance.getEndTime() != null) {
                    historyService.deleteHistoricProcessInstance(historicProcessInstance.getId());
                } else {
                    // 删除流程实例
                    runtimeService.deleteProcessInstance(pp.getProcessInsId(), "");
                    // 删除历史流程实例
                    historyService.deleteHistoricProcessInstance(pp.getProcessInsId());
                }
            }
        }
        String processInsId = this.startPro(form.getProjectId(), form.getProcessDefId());
@@ -203,7 +207,7 @@
        taskStatistics.setTodoTaskNum(this.getTodoTaskNum(projectProcess.getProcessInsId()));
        taskStatistics.setRemainingTaskNum(this.getRemainingTaskNum(processDefId, projectProcess.getProcessInsId()));
//        taskStatistics.setCurrentTask(this.getCurrentNodeTaskList(projectProcess.getProcessInstanceId()));
        taskStatistics.setRemainingTaskNum(this.getNotFinishedTaskNum(projectProcess.getProcessInsId()));
        taskStatistics.setRemainingTaskNum(this.getRemainingTaskNum(projectProcess.getProcessDefId(), projectProcess.getProcessInsId()));
        detail.setStatistics(taskStatistics);
        Result result = Result.ok();
@@ -273,16 +277,11 @@
            taskVO.setDeployId(pd.getDeploymentId());
            taskVO.setProcessName(pd.getName());
            taskVO.setProcessInsId(task.getProcessInstanceId());
            taskVO.setTaskDefinitionKey(task.getTaskDefinitionKey());
            // 流程发起人信息
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(task.getProcessInstanceId())
                    .singleResult();
            SysUser startUser = sysUserService.selectUserById(Long.parseLong(historicProcessInstance.getStartUserId()));
            taskVO.setPromoterId(startUser.getUserId());
            taskVO.setPromoterName(startUser.getNickName());
            taskVO.setPromoterUnitName(Objects.nonNull(startUser.getDept()) ? startUser.getDept().getDeptName() : "");
            taskVO.setPromoterUnitId(Objects.nonNull(startUser.getDept()) ? startUser.getDept().getDeptId() : null);
            this.setPromoterInfo(taskVO);
            // 流程处理人信息
            List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(task.getId());
            for (IdentityLink identityLink : identityLinksForTask) {
@@ -341,26 +340,22 @@
    @Override
    public Result taskIsAuditing(String processDefinitionId, String taskId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinitionId);
        Collection<Process> processes = bpmnModel.getProcesses();
        Boolean needAuditing = Boolean.FALSE;
        for (Process process : processes) {
            Collection<FlowElement> flowElements = process.getFlowElements();
            for (FlowElement flowElement : flowElements) {
                if (flowElement instanceof UserTask) {
                if (flowElement instanceof UserTask && flowElement.getId().equals(task.getTaskDefinitionKey())) {
                    UserTask userTask = (UserTask) flowElement;
                    List<ExtensionElement> extensionElements = userTask.getExtensionElements().get("flowable:properties");
                    if (! CollectionUtils.isEmpty(extensionElements)) {
                        for (ExtensionElement extensionElement : extensionElements) {
                            String fieldName = extensionElement.getAttributeValue(taskId,"name");
                            String fieldValue = extensionElement.getAttributeValue(taskId,"value");
                            System.out.println("Field Name: " + fieldName + ", Field Value: " + fieldValue);
                        }
                    }
                    needAuditing = taskCommonService.checkTaskNeedAuditing(userTask.getExtensionElements().get("properties"));
                    break;
                }
            }
        }
        return null;
        return Result.ok().data(needAuditing);
    }
    /**
@@ -401,16 +396,11 @@
            taskVO.setDeployId(pd.getDeploymentId());
            taskVO.setProcessName(pd.getName());
            taskVO.setProcessInsId(task.getProcessInstanceId());
            taskVO.setTaskDefinitionKey(task.getTaskDefinitionKey());
            // 流程发起人信息
            HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                    .processInstanceId(task.getProcessInstanceId())
                    .singleResult();
            SysUser startUser = sysUserService.selectUserById(Long.parseLong(historicProcessInstance.getStartUserId()));
            taskVO.setPromoterId(startUser.getUserId());
            taskVO.setPromoterName(startUser.getNickName());
            taskVO.setPromoterUnitName(Objects.nonNull(startUser.getDept()) ? startUser.getDept().getDeptName() : "");
            taskVO.setPromoterUnitId(Objects.nonNull(startUser.getDept()) ? startUser.getDept().getDeptId() : null);
            this.setPromoterInfo(taskVO);
            // 流程处理人信息
            List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(task.getId());
            for (IdentityLink identityLink : identityLinksForTask) {
@@ -502,6 +492,8 @@
                        .includeIdentityLinks()
                        .singleResult();
                if (Objects.isNull(historicTask)) {
                    vo.setPromoterName("暂无");
                    vo.setPromoterUnitName("暂无");
                    // 未开始的任务,其关联的用户组这些都可以从UserTask中拿到,因为本身未开始的任务是没有task的,所以这里直接查
                    if (StringUtils.isNotBlank(userTask.getAssignee())) {
                        vo.setHandlerType(HandlerTypeEnum.USER);
@@ -552,6 +544,7 @@
                        vo.setHandlerId(handlerUserId);
                        vo.setHandlerName(handlerUser.getNickName());
                    }
                    vo.setTaskDefinitionKey(historicTask.getTaskDefinitionKey());
                    this.setPromoterAndHandler(vo, historicTask.getIdentityLinks());
                }
            } else {
@@ -559,6 +552,8 @@
                vo.setTaskId(task.getId());
                vo.setExecutionId(task.getExecutionId());
                vo.setCreateTime(task.getCreateTime());
                vo.setTaskDefinitionKey(task.getTaskDefinitionKey());
                this.setPromoterAndHandler(vo, null);
            }
            return vo;
@@ -695,22 +690,13 @@
    /**
     * 设置任务的发起人&处理人
     * 设置任务的发起人&处理人   只有待办任务和已完成任务才会掉这个方法
     *
     * @param taskVO
     * @param identityLinkInfos 如果是已完成的任务,用这个去取关联的用户/用户组
     */
    private void setPromoterAndHandler(CustomerTaskVO taskVO, List<? extends IdentityLinkInfo> identityLinkInfos) {
        // TODO 发起人是否应为上一节点的处理人
        // 流程发起人信息
        HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery()
                .processInstanceId(taskVO.getProcessInsId())
                .singleResult();
        SysUser startUser = sysUserService.selectUserById(Long.parseLong(historicProcessInstance.getStartUserId()));
        taskVO.setPromoterId(startUser.getUserId());
        taskVO.setPromoterName(startUser.getNickName());
        taskVO.setPromoterUnitId(Objects.nonNull(startUser.getDept()) ? startUser.getDept().getDeptId() : null);
        taskVO.setPromoterUnitName(Objects.nonNull(startUser.getDept()) ? startUser.getDept().getDeptName() : "");
        this.setPromoterInfo(taskVO);
        // 流程处理人信息
        if (TaskStatusEnum.TODO.equals(taskVO.getTaskStatus())) {
            List<IdentityLink> identityLinksForTask = taskService.getIdentityLinksForTask(taskVO.getTaskId());
@@ -719,6 +705,7 @@
                if (StringUtils.isNotBlank(identityLink.getUserId())) {
                    SysUser sysUser = sysUserService.selectUserById(Long.parseLong(identityLink.getUserId()));
                    if (Objects.nonNull(sysUser)) {
                        taskVO.setHandlerType(HandlerTypeEnum.USER);
                        taskVO.setHandlerId(sysUser.getUserId());
                        if (Objects.nonNull(sysUser.getDept())) {
                            taskVO.setHandlerUnitId(sysUser.getDept().getDeptId());
@@ -729,6 +716,7 @@
                    // 绑定的是角色或者是部门,需要根据id判断
                } else if (StringUtils.isNotBlank(identityLink.getGroupId())) {
                    if (identityLink.getGroupId().startsWith("dept")) {   // 部门的id是加了前缀的如:dept:1
                        taskVO.setHandlerType(HandlerTypeEnum.DEPT);
                        String[] split = identityLink.getGroupId().split(":");
                        if (split.length > 1) {
                            // 部门
@@ -741,6 +729,7 @@
                            }
                        }
                    } else {
                        taskVO.setHandlerType(HandlerTypeEnum.ROLE);
                        SysRole role = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId()));
                        if (Objects.nonNull(role)) {
                            taskVO.setHandlerUnitId(Long.parseLong(identityLink.getGroupId()));
@@ -755,6 +744,7 @@
            for (IdentityLinkInfo identityLink : identityLinkInfos) {
                // 绑定的是用户,查出用户姓名、部门
                if (StringUtils.isNotBlank(identityLink.getUserId())) {
                    taskVO.setHandlerType(HandlerTypeEnum.USER);
                    SysUser sysUser = sysUserService.selectUserById(Long.parseLong(identityLink.getUserId()));
                    if (Objects.nonNull(sysUser)) {
//                        taskVO.setHandlerId(sysUser.getUserId());
@@ -767,6 +757,7 @@
                    // 绑定的是角色,查出角色名称
                } else if (StringUtils.isNotBlank(identityLink.getGroupId())) {
                    if (identityLink.getGroupId().startsWith("dept")) {
                        taskVO.setHandlerType(HandlerTypeEnum.DEPT);
                        String[] split = identityLink.getGroupId().split(":");
                        if (split.length > 1) {
                            // 部门
@@ -776,18 +767,50 @@
                                taskVO.setHandlerUnitName(dept.getDeptName());
                            }
                        }
                    }
                    SysRole role = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId()));
                    if (Objects.nonNull(role)) {
                        taskVO.setHandlerUnitId(Long.parseLong(identityLink.getGroupId()));
                        taskVO.setHandlerUnitName("由拥有角色:【" + role.getRoleName() + "】的人处理");
                    } else {
                        taskVO.setHandlerType(HandlerTypeEnum.ROLE);
                        SysRole role = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId()));
                        if (Objects.nonNull(role)) {
                            taskVO.setHandlerUnitId(Long.parseLong(identityLink.getGroupId()));
                            taskVO.setHandlerUnitName("由拥有角色:【" + role.getRoleName() + "】的人处理");
//                        taskVO.setHandlerName(role.getRoleName());
//                        taskVO.setHandlerId(null);
                        }
                    }
                }
            }
        }
    }
    /**
     * 设置任务发起人
     *
     * @param taskVO
     */
    private void setPromoterInfo(CustomerTaskVO taskVO) {
        // 发起人应为上一节点的处理人
        List<String> beforeNodeKey = taskCommonService.getBeforeNodeInfo(taskVO.getProcessDefId(), taskVO.getTaskDefinitionKey());
        List<SysUser> userList = beforeNodeKey.stream().map(key -> {
            HistoricTaskInstance historicTaskInstance = historyService.createHistoricTaskInstanceQuery().taskDefinitionKey(key).singleResult();
            if (Objects.nonNull(historicTaskInstance)) {
                // 实际领取这个任务的人,也就是处理人
                String assignee = historicTaskInstance.getAssignee();
                SysUser startUser = sysUserService.selectUserById(Long.parseLong(assignee));
                return startUser;
            } else {
                return null;
            }
        }).filter(user -> Objects.nonNull(user)).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(userList)) {
            taskVO.setPromoterName("暂无");
            taskVO.setPromoterUnitName("暂无");
        } else {
            taskVO.setPromoterId(userList.stream().map(user -> { return user.getUserId() + ""; }).collect(Collectors.joining("、")));
            taskVO.setPromoterName(userList.stream().map(user -> { return user.getNickName(); }).collect(Collectors.joining("、")));
            taskVO.setPromoterUnitId(userList.stream().filter(user -> Objects.nonNull(user.getDept())).map(user -> { return user.getDept().getDeptId() + "";}).collect(Collectors.joining("、")));
            taskVO.setPromoterUnitName(userList.stream().filter(user -> Objects.nonNull(user.getDept())).map(user -> { return user.getDept().getDeptName() + "";}).collect(Collectors.joining("、")));
        }
    }
    /**
@@ -833,16 +856,6 @@
     */
    private Long getTotalTaskNum(String processDefinitionId) {
        return Long.valueOf(this.getAllUserTaskElement(processDefinitionId).size());
    }
    /**
     * 获取流程剩余未完成的任务数
     *
     * @param processInstanceId
     * @return
     */
    private Long getNotFinishedTaskNum(String processInstanceId) {
        return historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).processUnfinished().count();
    }
    /**
flowable/src/main/java/com/ycl/common/constant/ProcessConstants.java
@@ -90,4 +90,12 @@
    public static final String WIDGET_LIST = "widgetList";
    /**
     * 扩展属性中的:节点是否审批
     *
     */
    public static final String EXTENSION_PROPERTY_NEED_AUDITING_TEXT = "该节点是审批节点";
    public static final String EXTENSION_PROPERTY_NEED_AUDITING_VALUE = "是";
}
flowable/src/main/java/com/ycl/controller/FlowTaskController.java
@@ -7,6 +7,7 @@
import com.ycl.domain.dto.FlowTaskDto;
import com.ycl.domain.vo.FlowQueryVo;
import com.ycl.domain.vo.FlowTaskVo;
import com.ycl.domain.vo.FormDetailVO;
import com.ycl.service.IFlowTaskService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
@@ -97,6 +98,12 @@
        return flowTaskService.processVariables(taskId);
    }
    @ApiOperation(value = "查看任务", response = FormDetailVO.class)
    @GetMapping(value = "/detail/{taskId}")
    public AjaxResult detail(@ApiParam(value = "流程任务Id") @PathVariable(value = "taskId") String taskId) {
        return flowTaskService.detail(taskId);
    }
    @ApiOperation(value = "完成提交表单任务/普通提交")
    @Log(title = "完成提交表单任务/普通提交", businessType = BusinessType.INSERT)
flowable/src/main/java/com/ycl/service/IFlowTaskService.java
@@ -223,4 +223,12 @@
     * @return
     */
    AjaxResult completeSubmitForm(String taskId, Map<String, Object> variables);
    /**
     * 查看任务
     *
     * @param taskId
     * @return
     */
    AjaxResult detail(String taskId);
}
flowable/src/main/java/com/ycl/service/common/TaskCommonService.java
@@ -17,6 +17,7 @@
import org.springframework.util.StringUtils;
import java.util.*;
import java.util.stream.Collectors;
/**
 * @author:xp
@@ -30,13 +31,15 @@
    private final RepositoryService repositoryService;
    /**
     * 通过当前节点定义key,获取其上一个节点的定义id,如果前面是并行的会返回多个
     * 通过当前节点定义key,获取其上一个节点以及当前节点的信息,如果前面是并行的会返回多个
     *
     * @param processDefId 流程定义id
     * @param currentNodeDefId
     * @param currentNodeDefId 当前节点定义id
     * @param sysFormService 表单服务层
     * @param needInitCurrentForm 是否需要初始化当前节点的表单数据,一般查询已完成的任务详情需要
     * @return
     */
    public List<FormDetailVO> getBeforeNodeDefId(String processDefId, String currentNodeDefId, ISysFormService sysFormService) {
    public List<FormDetailVO> getBeforeNodeDefInfo(String processDefId, String currentNodeDefId, ISysFormService sysFormService, Boolean needInitCurrentForm) {
        // 获取流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(processDefId)
@@ -64,7 +67,7 @@
            }
        }
        if (Objects.isNull(currentElement)) {
            throw new RuntimeException("未找到改任务的流程定义节点");
            throw new RuntimeException("未找到该任务的流程定义节点");
        }
        // 获取当前节点的输入
@@ -75,43 +78,135 @@
            formDetailVO.setBeforeNodeName(currentElement.getName());
            formDetailVO.setCurrent(Boolean.TRUE);
            SysForm sysForm = sysFormService.selectSysFormById(Long.parseLong(currentElement.getFormKey()));
            if (Objects.isNull(sysForm)) {
                throw new RuntimeException("该流程绑定的表单不存在或已被删除");
            }
            Map<String, Object> data = new HashMap<>(1);
            data.put(ProcessConstants.TASK_FORM_KEY, JSONObject.parseObject(sysForm.getFormContent()));
            if (needInitCurrentForm) {
                SysForm sysForm = sysFormService.selectSysFormById(Long.parseLong(currentElement.getFormKey()));
                if (Objects.isNull(sysForm)) {
                    throw new RuntimeException("该流程绑定的表单不存在或已被删除");
                }
                Map<String, Object> data = new HashMap<>(1);
                data.put(ProcessConstants.TASK_FORM_KEY, JSONObject.parseObject(sysForm.getFormContent()));
            formDetailVO.setFormJsonObj(data);
                formDetailVO.setFormJsonObj(data);
            }
            defKeys.add(formDetailVO);
        }
        this.before(currentElement, defKeys);
        this.beforeNodeInfo(currentElement, defKeys);
        return defKeys;
    }
    /**
     * 递归获取当前节点的前一个任务节点key
     * 递归获取当前节点的前一个任务节点信息
     *
     * @param currentElement
     * @param defKeys
     */
    private void before(UserTask currentElement, List<FormDetailVO> defKeys) {
        if (! CollectionUtils.isEmpty(currentElement.getIncomingFlows())) {
            for (SequenceFlow incomingFlow : currentElement.getIncomingFlows()) {
                if (! (incomingFlow.getSourceFlowElement() instanceof UserTask)) {
                    // 不包含开始节点
                    if (! (incomingFlow.getSourceFlowElement() instanceof StartEvent)) {
                        before((UserTask) (incomingFlow.getSourceFlowElement()), defKeys);
    private void beforeNodeInfo(FlowElement currentElement, List<FormDetailVO> defKeys) {
        if (currentElement instanceof UserTask) {
            UserTask userTask = (UserTask) currentElement;
            if (! CollectionUtils.isEmpty(userTask.getIncomingFlows())) {
                for (SequenceFlow incomingFlow : userTask.getIncomingFlows()) {
                    if (incomingFlow.getSourceFlowElement() instanceof UserTask) {
                        FormDetailVO formDetailVO = new FormDetailVO();
                        formDetailVO.setBeforeNodeDefId(incomingFlow.getSourceFlowElement().getId());
                        formDetailVO.setBeforeNodeName(incomingFlow.getSourceFlowElement().getName());
                        formDetailVO.setBeforeNodeName(((UserTask) incomingFlow.getSourceFlowElement()).getOwner());
                        defKeys.add(formDetailVO);
                    } else {
                        beforeNodeInfo(incomingFlow.getSourceFlowElement(), defKeys);
                    }
                } else {
                    FormDetailVO formDetailVO = new FormDetailVO();
                    formDetailVO.setBeforeNodeDefId(incomingFlow.getSourceFlowElement().getId());
                    formDetailVO.setBeforeNodeName(incomingFlow.getSourceFlowElement().getName());
                    defKeys.add(formDetailVO);
                }
            }
        } else if (currentElement instanceof Gateway ){
            Gateway gateway = (Gateway) currentElement;
            if (! CollectionUtils.isEmpty(gateway.getIncomingFlows())) {
                for (SequenceFlow incomingFlow : gateway.getIncomingFlows()) {
                    if (incomingFlow.getSourceFlowElement() instanceof UserTask) {
                        FormDetailVO formDetailVO = new FormDetailVO();
                        formDetailVO.setBeforeNodeDefId(incomingFlow.getSourceFlowElement().getId());
                        formDetailVO.setBeforeNodeName(incomingFlow.getSourceFlowElement().getName());
                        defKeys.add(formDetailVO);
                    } else {
                        beforeNodeInfo(incomingFlow.getSourceFlowElement(), defKeys);
                    }
                }
            }
        }
    }
    /**
     * 获取当前节点的上一节点id,不反悔当前节点信息,如果前面是并行,那么会返回多个
     *
     * @param processDefId 流程定义id
     * @param currentNodeDefId 当前节点定义id
     * @return
     */
    public List<String> getBeforeNodeInfo(String processDefId, String currentNodeDefId) {
        // 获取流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(processDefId)
                .singleResult();
        // 获取流程模型
        BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefId);
        if (bpmnModel == null) {
            throw new RuntimeException("BpmnModel not found for processDefinitionId: " + processDefId);
        }
        // 获取流程对象
        Process process = bpmnModel.getProcessById(processDefinition.getKey());
        if (process == null) {
            throw new RuntimeException("Process not found for processDefinitionId: " + processDefId);
        }
        // 遍历流程元素,找到对应的任务节点
        Collection<FlowElement> flowElements = process.getFlowElements();
        UserTask currentElement = null;
        for (FlowElement flowElement : flowElements) {
            if (flowElement instanceof UserTask && flowElement.getId().equals(currentNodeDefId)) {
                currentElement = (UserTask) flowElement;
                break;
            }
        }
        if (Objects.isNull(currentElement)) {
            throw new RuntimeException("未找到该任务的流程定义节点");
        }
        // 获取当前节点的输入
        List<FormDetailVO> defKeys = new ArrayList<>(2);
        this.beforeNodeInfo(currentElement, defKeys);
        return defKeys.stream().map(FormDetailVO::getBeforeNodeDefId).collect(Collectors.toList());
    }
    /**
     * 检查任务节点是否配置了:需要审核  的扩展属性
     *
     * @param extensionElements 扩展列表
     * @return
     */
    public Boolean checkTaskNeedAuditing(List<ExtensionElement> extensionElements) {
        if (CollectionUtils.isEmpty(extensionElements)) {
            return Boolean.FALSE;
        }
        for (ExtensionElement extensionElement : extensionElements) {
            if (CollectionUtils.isEmpty(extensionElement.getAttributes())) { // 如果本身没有属性,则递归child
                return checkTaskNeedAuditing(extensionElement.getChildElements().get("property"));
            } else {
                // 否则先查本身的属性有不有:需要审核 的属性,没有也是递归child
                if (extensionElement.getAttributes().get("name").stream().anyMatch(attribute -> ProcessConstants.EXTENSION_PROPERTY_NEED_AUDITING_TEXT.equals(attribute.getValue()))
                    && extensionElement.getAttributes().get("value").stream().anyMatch(attribute -> ProcessConstants.EXTENSION_PROPERTY_NEED_AUDITING_VALUE.equals(attribute.getValue()))
                ) {
                    return Boolean.TRUE;
                } else {
                    return checkTaskNeedAuditing(extensionElement.getChildElements().get("property"));
                }
            }
        }
        return Boolean.FALSE;
    }
}
flowable/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java
@@ -7,6 +7,7 @@
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ycl.common.constant.ProcessConstants;
import com.ycl.common.core.domain.AjaxResult;
import com.ycl.common.core.domain.entity.SysDept;
import com.ycl.common.core.domain.entity.SysRole;
import com.ycl.common.core.domain.entity.SysUser;
import com.ycl.common.enums.FlowComment;
@@ -28,6 +29,7 @@
import com.ycl.service.ISysDeployFormService;
import com.ycl.service.ISysFormService;
import com.ycl.service.common.TaskCommonService;
import com.ycl.system.service.ISysDeptService;
import com.ycl.system.service.ISysRoleService;
import com.ycl.system.service.ISysUserService;
import lombok.RequiredArgsConstructor;
@@ -80,6 +82,7 @@
    private final ISysUserService sysUserService;
    private final ISysRoleService sysRoleService;
    private final ISysDeptService sysDeptService;
    private final ISysDeployFormService sysInstanceFormService;
    private final ISysFormService sysFormService;
    private final TaskCommonService taskCommonService;
@@ -831,8 +834,14 @@
                                stringBuilder.append(sysUser.getNickName()).append(",");
                            }
                            if (StringUtils.isNotBlank(identityLink.getGroupId())) {
                                SysRole sysRole = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId()));
                                stringBuilder.append(sysRole.getRoleName()).append(",");
                                if (identityLink.getGroupId().contains("dept")) {
                                    SysDept sysDept = sysDeptService.selectDeptById(Long.parseLong(identityLink.getGroupId().split(":")[1]));
                                    stringBuilder.append(sysDept.getDeptName()).append(",");
                                } else {
                                    SysRole sysRole = sysRoleService.selectRoleById(Long.parseLong(identityLink.getGroupId()));
                                    stringBuilder.append(sysRole.getRoleName()).append(",");
                                }
                            }
                        }
                    }
@@ -853,14 +862,14 @@
            }
            map.put("flowList", hisFlowList);
        }
        // 第一次申请获取初始化表单
        if (StringUtils.isNotBlank(deployId)) {
            SysForm sysForm = sysInstanceFormService.selectSysDeployFormByDeployId(deployId);
            if (Objects.isNull(sysForm)) {
                return AjaxResult.error("请先配置流程表单");
            }
            map.put("formData", JSONObject.parseObject(sysForm.getFormContent()));
        }
//        // 第一次申请获取初始化表单
//        if (StringUtils.isNotBlank(deployId)) {
//            SysForm sysForm = sysInstanceFormService.selectSysDeployFormByDeployId(deployId);
//            if (Objects.isNull(sysForm)) {
//                return AjaxResult.error("请先配置流程表单");
//            }
//            map.put("formData", JSONObject.parseObject(sysForm.getFormContent()));
//        }
        return AjaxResult.success(map);
    }
@@ -1149,10 +1158,46 @@
        } else {
            parameters = taskService.getVariables(taskId);
        }
        List<FormDetailVO> beforeNodes = this.getBeforeNodeForm(parameters, task.getFormKey(), task.getName(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), Boolean.FALSE);
        return AjaxResult.success(beforeNodes);
    }
    @Override
    public AjaxResult detail(String taskId) {
        Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
        // 流程变量
        Map<String, Object> parameters = new HashMap<>();
        if (Objects.isNull(task)) {
            // 如果为空,可能是任务已经结束
            HistoricTaskInstance hisTask = historyService.createHistoricTaskInstanceQuery().taskId(taskId).includeProcessVariables().singleResult();
            if (Objects.isNull(hisTask)) {
                throw new RuntimeException("该任务不存在");
            }
            parameters = hisTask.getProcessVariables();
            List<FormDetailVO> beforeNodes = this.getBeforeNodeForm(parameters, hisTask.getFormKey(), hisTask.getName(), hisTask.getProcessDefinitionId(), hisTask.getTaskDefinitionKey(), Boolean.TRUE);
            return AjaxResult.success(beforeNodes);
        } else {
            parameters = taskService.getVariables(taskId);
            List<FormDetailVO> beforeNodes = this.getBeforeNodeForm(parameters, task.getFormKey(), task.getName(), task.getProcessDefinitionId(), task.getTaskDefinitionKey(), Boolean.TRUE);
            return AjaxResult.success(beforeNodes);
        }
    }
    /**
     * 获取当前节点和上一节点的表单内容
     *
     * @param parameters 根据任务查找出来的参数
     * @param formKey task自身关联的表单id
     * @param taskName task自身的任务名
     * @param processDefId 流程定义id
     * @param processDefKey 流程实例id
     * @return
     */
    private List<FormDetailVO> getBeforeNodeForm(Map<String, Object> parameters, String formKey, String taskName, String processDefId, String processDefKey, Boolean currentNeedData) {
        if (! parameters.keySet().stream().anyMatch(key -> key.contains(ProcessConstants.TASK_FORM_KEY))) {
            // 如果是空的,使用formId去查
            if (StringUtils.isNotBlank(task.getFormKey())) {
                SysForm sysForm = sysFormService.selectSysFormById(Long.parseLong(task.getFormKey()));
            if (StringUtils.isNotBlank(formKey)) {
                SysForm sysForm = sysFormService.selectSysFormById(Long.parseLong(formKey));
                if (Objects.isNull(sysForm)) {
                    throw new RuntimeException("该流程绑定的表单不存在或已被删除");
                }
@@ -1160,24 +1205,25 @@
                Map<String, Object> data = new HashMap<>(1);
                data.put(ProcessConstants.TASK_FORM_KEY, JSONObject.parseObject(sysForm.getFormContent()));
                formDetailVO.setFormJsonObj(data);
                formDetailVO.setBeforeNodeName(task.getName());
                formDetailVO.setBeforeNodeName(taskName);
                formDetailVO.setCurrent(Boolean.TRUE);
                return AjaxResult.success(Arrays.asList(formDetailVO));
                return Arrays.asList(formDetailVO);
            } else {
                return AjaxResult.success(new ArrayList<>(1));
                return new ArrayList<>(1);
            }
        }
        // 这里只需要查自身以及上一个节点(如果并行的有多个)的表单数据
        List<FormDetailVO> beforeNodes = taskCommonService.getBeforeNodeDefId(task.getProcessDefinitionId(), task.getTaskDefinitionKey(), sysFormService);
        List<String> beforeNodeDefIds = beforeNodes.stream().filter(item -> !item.getCurrent()).map(FormDetailVO::getBeforeNodeDefId).collect(Collectors.toList());
        List<FormDetailVO> beforeNodes = taskCommonService.getBeforeNodeDefInfo(processDefId, processDefKey, sysFormService, Boolean.TRUE);
        List<String> beforeNodeDefIds = beforeNodes.stream().filter(item -> !item.getCurrent() || currentNeedData).map(FormDetailVO::getBeforeNodeDefId).collect(Collectors.toList());
        Map<String, Object> newP = new HashMap<>();
        if (CollectionUtils.isNotEmpty(beforeNodeDefIds)) {
            for (String key : parameters.keySet()) {
                // 过滤目标数据,将目标表单数据放到新map中
                // 过滤拿到目标数据,将目标表单数据放到新map中
                if (beforeNodeDefIds.stream().anyMatch(defId -> key.startsWith(defId))) {
                    if (key.contains(ProcessConstants.TASK_FORM_KEY)) {
                        newP.put(key, parameters.get(key));
                    } else {
                    }
                    else {
                        newP.put(key.split("&")[1], parameters.get(key));
                    }
                }
@@ -1186,8 +1232,8 @@
        // 拿到目标表单后,再处理每个表单的数据
        for (FormDetailVO formDetailVO : beforeNodes) {
            if (formDetailVO.getCurrent()) {
                continue;  // 跳过当前节点,因为当前节点在获取前置节点时已经设置过了
            if (formDetailVO.getCurrent() && !currentNeedData) {
                continue;  // 跳过当前节点,因为当前节点在获取前置节点时已经设置过了(但表单数据没有给)
            }
            Object form = newP.get(formDetailVO.getBeforeNodeDefId() + "&" + ProcessConstants.TASK_FORM_KEY);
            if (Objects.nonNull(form)) {
@@ -1224,8 +1270,7 @@
                formDetailVO.setFormJsonObj(newP);
            }
        }
        return AjaxResult.success(beforeNodes);
        return beforeNodes;
    }
    /**