zxl
2025-12-22 cc4a3ff932b1e768914a4aff0eeaa866d08f9b91
business/src/main/java/com/ycl/service/impl/FlowTaskServiceImpl.java
@@ -16,6 +16,8 @@
import com.ycl.common.core.domain.entity.SysRole;
import com.ycl.common.core.domain.entity.SysUser;
import com.ycl.common.enums.FlowComment;
import com.ycl.common.enums.business.AuditHistoryEnum;
import com.ycl.common.enums.business.AuditTypeEnum;
import com.ycl.common.enums.business.ProcessLogEventTypeEnum;
import com.ycl.common.enums.business.TaskStatusEnum;
import com.ycl.common.exception.CustomException;
@@ -29,6 +31,7 @@
import com.ycl.domain.entity.ProcessLog;
import com.ycl.domain.entity.ProjectProcess;
import com.ycl.domain.entity.SysForm;
import com.ycl.domain.form.AuditHistoryForm;
import com.ycl.domain.form.EditFinishedTaskForm;
import com.ycl.domain.json.RejectData;
import com.ycl.domain.query.ProcessLogQuery;
@@ -111,7 +114,7 @@
    private final ProcessLogService processLogService;
    private final ApplicationEventPublisher publisher;
    private final ProjectProcessMapper projectProcessMapper;
    private final AuditHistoryService auditHistoryService;
    @Value("${targetIp}")
    private String targetIp;
@@ -136,6 +139,21 @@
            taskService.setAssignee(taskVo.getTaskId(), userId.toString());
            taskService.complete(taskVo.getTaskId(), taskVo.getVariables());
        }
        ProjectProcess projectProcess = new LambdaQueryChainWrapper<>(projectProcessMapper)
                .eq(ProjectProcess::getProcessInsId, task.getProcessInstanceId())
                .eq(ProjectProcess::getProcessDefId, task.getProcessDefinitionId())
                .one();
        AuditHistoryForm auditHistoryForm =
                buildForm(task.getId(),
                        task.getTaskDefinitionKey(),
                        null,
                        SecurityUtils.getDeptId() + "",
                        AuditTypeEnum.Review.name(),
                        projectProcess.getProjectId(),
                        "t_project_info",
                        task.getName()
                );
        auditHistoryService.add(auditHistoryForm);
        return AjaxResult.success();
    }
@@ -175,6 +193,7 @@
            }
        }
        taskService.addComment(taskId, task.getProcessInstanceId(), FlowComment.SUBMIT.getType(), "完成提交");
        //判断是否是委派任务
        if (DelegationState.PENDING.equals(task.getDelegationState())) {
            taskService.resolveTask(taskId, newV);
        } else {
@@ -194,9 +213,45 @@
                    ProcessLogEventTypeEnum.FINISHED,
                    null));
        }
        //保存日志
        AuditHistoryForm auditHistoryForm =
                buildForm(taskId,
                task.getTaskDefinitionKey(),
                null,
                SecurityUtils.getDeptId() + "",
                AuditTypeEnum.Submit.name(),
                projectProcess.getProjectId(),
                "t_project_info",
                task.getName()
        );
        auditHistoryService.add(auditHistoryForm);
        return AjaxResult.success("提交成功");
    }
    public AuditHistoryForm buildForm(
            String taskId,
            String taskDefinitionKey,
            String viewer,
            String commitDept,
            String auditType,
            String businessKey,
            String businessTable,
            String content) {
        AuditHistoryForm auditHistoryForm = new AuditHistoryForm();
        auditHistoryForm.setTaskId(taskId);
        auditHistoryForm.setTaskDefinitionKey(taskDefinitionKey);
        auditHistoryForm.setViewer(viewer);
        auditHistoryForm.setCommitDept(commitDept);
        auditHistoryForm.setAuditType(auditType);
        auditHistoryForm.setBusinessKey(businessKey);
        auditHistoryForm.setBusinessTable(businessTable);
        auditHistoryForm.setContent(content);
        // 5. 特殊字段默认值:isRead 默认为 (未读)
        auditHistoryForm.setIsRead(AuditHistoryEnum.UN_READ.name());
        return auditHistoryForm;
    }
    /**
     * 容缺补交
@@ -498,6 +553,21 @@
                task.getName(),
                ProcessLogEventTypeEnum.REJECT,
                new RejectData(flowTaskVo.getComment())));
        //保存日志
        AuditHistoryForm auditHistoryForm =
                buildForm(task.getId(),
                        task.getTaskDefinitionKey(),
                        null,
                        SecurityUtils.getDeptId() + "",
                        AuditTypeEnum.Reject.name(),
                        projectProcess.getProjectId(),
                        "t_project_info",
                        task.getName()
                );
        auditHistoryService.add(auditHistoryForm);
    }
    /**
@@ -687,12 +757,24 @@
    @Transactional(rollbackFor = Exception.class)
    public void assignTask(FlowTaskVo flowTaskVo) {
        // 直接转派就可以覆盖掉之前的
        log.info("flowTaskVo:{}",flowTaskVo);
        taskService.setAssignee(flowTaskVo.getTaskId(), flowTaskVo.getAssignee());
//        // 删除指派人重新指派
//        taskService.deleteCandidateUser(flowTaskVo.getTaskId(),flowTaskVo.getAssignee());
//        taskService.addCandidateUser(flowTaskVo.getTaskId(),flowTaskVo.getAssignee());
//        // 如果要查询转给他人处理的任务,可以同时将OWNER进行设置:
//        taskService.setOwner(flowTaskVo.getTaskId(), flowTaskVo.getAssignee());
//        AuditHistoryForm auditHistoryForm =
//                buildForm(flowTaskVo.getTaskId(),
//                        task.getTaskDefinitionKey(),
//                        null,
//                        SecurityUtils.getDeptId() + "",
//                        AuditTypeEnum.Submit.name(),
//                        projectProcess.getProjectId(),
//                        "t_project_info",
//                        task.getName()
//                );
    }
@@ -1513,7 +1595,7 @@
    /**
     * 流程节点表单
     *
     * 点击办理进入
     * @param taskId 流程任务编号
     * @return
     */
@@ -1627,7 +1709,9 @@
    @Override
    public AjaxResult detail(String processInsId, String taskId) {
        //查询运行时流程实例(含流程变量)
        ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().includeProcessVariables().processInstanceId(processInsId).singleResult();
        log.info("打印运行时:{}",processInstance);
        // 流程变量
        Map<String, Object> parameters = new HashMap<>();
        if (Objects.isNull(processInstance)) {
@@ -1637,7 +1721,7 @@
            if (Objects.isNull(historicProcessInstance)) {
                throw new RuntimeException("流程不存在");
            }
            //流程未结束 查询流程已完成的结点任务
            List<HistoricTaskInstance> hisTasks = historyService.createHistoricTaskInstanceQuery()
                    .taskId(taskId)
                    .finished()
@@ -1648,7 +1732,9 @@
            if (CollectionUtils.isNotEmpty(hisTasks) && Objects.isNull(hisTasks.get(0))) {
                throw new RuntimeException("该任务不存在");
            }
            //获得最新的任务节点
            HistoricTaskInstance hisTask = hisTasks.get(0);
            //获得参数
            parameters = historicProcessInstance.getProcessVariables();
            List<FormDetailVO> beforeNodes = this.getBeforeNodeForm(parameters,
                    hisTask.getFormKey(),
@@ -1657,12 +1743,14 @@
                    hisTask.getTaskDefinitionKey(),
                    Boolean.TRUE, Boolean.TRUE);
            List<FormDetailVO> dataList = new ArrayList<>(2);
            // 按执行流ID分组前置节点
            Map<String, List<FormDetailVO>> map = new HashMap<>(2);
            beforeNodes.stream().forEach(node -> {
                if (node.getCurrent()) {
                    node.setTaskId(taskId);
                    dataList.add(node);
                } else {
                    //前置节点:查询对应的最新历史任务
                    List<HistoricTaskInstance> beforeTasks = historyService.createHistoricTaskInstanceQuery()
                            .processInstanceId(hisTask.getProcessInstanceId())
                            .finished()
@@ -1670,6 +1758,7 @@
                            .orderByTaskCreateTime()
                            .desc()
                            .list();
                    if (CollectionUtils.isNotEmpty(beforeTasks) && Objects.nonNull(beforeTasks.get(0))) {
                        node.setTaskId(beforeTasks.get(0).getId());
                        List<FormDetailVO> l = map.get(beforeTasks.get(0));
@@ -1689,7 +1778,9 @@
            }
            List<DoFormDetailVO> vos = dataList.stream().map(node -> {
                if (node.getCurrent()) {
                    // 调用日志服务,查询该任务是否处于挂起状态(传入任务ID和流程实例ID)
                    if (processLogService.taskIsHangup(taskId, hisTask.getProcessInstanceId())) {
                        //若挂起,给节点设置“挂起”状态(前端会展示挂起标识)
                        node.setTaskStatus(TaskStatusEnum.HANGUP);
                    }
                }
@@ -1812,16 +1903,19 @@
        // 这里只需要查自身以及上一个节点(如果并行的有多个)的表单数据
        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());
        // 处理每个表单的数据
        for (FormDetailVO formDetailVO : beforeNodes) {
            // 跳过“当前节点且不需要其数据”的场景 并且 currentNeedData不需要当前节点数据的情况
            if (formDetailVO.getCurrent() && !currentNeedData) {
                // 当前节点的表单也要处理ip问题
                continue;  // 跳过当前节点,因为当前节点在获取前置节点时已经设置过了(但表单数据没有给)
            }
            Map<String, Object> newP = new HashMap<>();
            // 存储当前节点的表单数据
            if (CollectionUtils.isNotEmpty(beforeNodeDefIds)) {
                for (String key : parameters.keySet()) {
                    // 过滤拿到目标表单数据,将目标表单数据放到新map中
@@ -1834,7 +1928,7 @@
                    }
                }
            }
            //获得前置节点定义id,即任务key
            Object form = newP.get(formDetailVO.getBeforeNodeDefId() + "&" + ProcessConstants.TASK_FORM_KEY);
            if (Objects.nonNull(form)) {
                JSONObject formJson = JSONObject.parseObject(JSON.toJSONString(form));
@@ -1853,11 +1947,12 @@
                            options.put("uploadURL", String.format("http://%s:10076/common/upload", this.targetIp));
                        }
                    }
                    // 更新表单结构(已处理禁用和上传地址)
                    formJson.put(ProcessConstants.WIDGET_LIST, oldFields);
                    newP.put(ProcessConstants.TASK_FORM_KEY, formJson);
                    // 删除原始的“节点ID&TASK_FORM_KEY”键(避免冗余)
                    newP.remove(formDetailVO.getBeforeNodeDefId() + "&" + ProcessConstants.TASK_FORM_KEY);
                    // 处理已经上传的文件的ip地址
                    // 已上传文件的访问IP地址(前端预览/下载时指向正确地址)
                    for (String s : newP.keySet()) {
                        if (ProcessConstants.TASK_FORM_KEY.equals(s)) {
                            continue;