/* * Copyright (c) 2018-2028, Chill Zhuang All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, * this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * Neither the name of the dreamlu.net developer nor the names of its * contributors may be used to endorse or promote products derived from * this software without specific prior written permission. * Author: Chill 庄骞 (smallchill@163.com) */ package com.vci.ubcs.flow.engine.service.impl; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.vci.ubcs.flow.core.constant.ProcessConstant; import com.vci.ubcs.flow.core.dto.FlowTaskDTO; import com.vci.ubcs.flow.core.dto.ProcessStageAttrDTO; import com.vci.ubcs.flow.core.entity.BladeFlow; import com.vci.ubcs.flow.core.entity.FlowTaskUser; import com.vci.ubcs.flow.core.entity.ProcessStageAttr; import com.vci.ubcs.flow.core.utils.TaskUtil; import com.vci.ubcs.flow.engine.entity.*; import com.vci.ubcs.flow.engine.service.FlowEngineService; import com.vci.ubcs.flow.engine.service.FlowTaskUserService; import com.vci.ubcs.flow.engine.service.ProcessStageAttrService; import com.vci.ubcs.flow.engine.service.VICFlowService; import com.vci.ubcs.starter.web.util.BeanUtil; import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.flowable.bpmn.model.*; import org.flowable.engine.*; import org.flowable.engine.impl.persistence.entity.ExecutionEntity; import org.flowable.engine.repository.ProcessDefinition; import org.flowable.engine.runtime.ProcessInstance; import org.flowable.task.api.Task; import org.springblade.core.mp.support.Condition; import org.springblade.core.secure.utils.AuthUtil; import org.springblade.core.tool.api.R; import org.springblade.core.tool.support.Kv; import org.springframework.stereotype.Service; import java.util.*; /** * 工作流服务实现类 * * @author Chill */ @Slf4j @Service @AllArgsConstructor public class VCIFlowserviceImpl implements VICFlowService { private final RuntimeService runtimeService; private final IdentityService identityService; private final RepositoryService repositoryService; private final TaskService taskService; private final FlowTaskUserService flowTaskUserService; private final FlowEngineService flowEngineService; private final HistoryService historyService; private final ProcessStageAttrService processStageAttrService; private static String MODELKEY = "modelKey";//前端传过来的模型key private static String TASKID = "taskId";//前端传过来的模型key private static String PROCESSINSTANCEID = "processInstanceId";//前端传过来的模型key @Override public R startProcess(FlowTaskDTO flowTaskUserC){ Map kvv = flowTaskUserC.getVariables(); String modelKey = kvv.get(MODELKEY).toString(); Kv kv = Kv.create().set(ProcessConstant.TASK_VARIABLE_CREATE_USER, AuthUtil.getUserName()); // 设置流程启动用户 identityService.setAuthenticatedUserId(TaskUtil.getTaskUser()); // 开启流程 //查询最新的流程部署id ProcessDefinition latesDefinition = repositoryService.createProcessDefinitionQuery().latestVersion().processDefinitionKey(modelKey).singleResult(); String processDefinitionId = latesDefinition.getId(); //查询每一步审核人 List taskUsers = flowTaskUserC.getFlowTaskUsers(); // Set taskIdSet = new HashSet<>(); for (FlowTaskUser taskUser:taskUsers){ kv.put(taskUser.getTaskId(),TaskUtil.getTaskUser(taskUser.getUserId())); // taskIdSet.add(taskUser.getTaskId()); } //对比配置的审核人员和流程中节点是否一致,可能存在流程节点变更了,多了或者少了节点,但是配置审核人员的节点没有变 // List> processTasks = flowEngineService.getNodeByFlowableKey(modelKey); // for (Map mi:processTasks){ // String taskId = mi.get(flowEngineService.getTaskIdString()); // if(!taskIdSet.contains(taskId)){ // throw new ServiceException("流程已重新部署,节点已改变,请设置审核人员!"); // } // } // if(taskIdSet.size()!=processTasks.size()){ // throw new ServiceException("流程已重新部署,节点已改变,请设置审核人员!"); // } //流程中文件、变量等 if(kvv!=null&&!kvv.isEmpty()){ kv.putAll(kvv); } ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinitionId, modelKey, kv); // 组装流程通用类 BladeFlow flow = new BladeFlow(); flow.setProcessInstanceId(processInstance.getId()); // //设置下一步审核人 // Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).active().singleResult(); // String taskId = task.getTaskDefinitionKey(); // String assignee = null; // for (FlowTaskUser taskUser:taskUsers) { // if(taskId.equals(taskUser.getTaskId())){ // assignee = taskUser.getUserId(); // } // } // if(StringUtils.isEmpty(assignee)){ // throw new ServiceException(taskId+"没有配置审核人!"); // } // taskService.setAssignee(task.getId(),assignee); return R.data(flow); } public static String NODE_NOW = "now"; public static String NODE_NEXT = "next"; /** * 获取任务节点 * * @param node 查询节点选择 * @param processInstanceId 流程实例id */ public FlowTaskDTO nextFlowNode(String node, String processInstanceId) { FlowTaskDTO flowTaskDTO = new FlowTaskDTO(); List taskList = new ArrayList<>();//节点按钮 flowTaskDTO.setToTasks(taskList); Task task = taskService.createTaskQuery().processInstanceId(processInstanceId).active().singleResult(); ExecutionEntity ee = (ExecutionEntity) runtimeService.createExecutionQuery() .executionId(task.getExecutionId()).singleResult(); // 当前审批节点 String crruentActivityId = ee.getActivityId(); BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId()); FlowNode flowNode = (FlowNode) bpmnModel.getFlowElement(crruentActivityId); //这个实例的所有节点 ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); Map processVariables = processInstance.getProcessVariables();//所有参数 flowTaskDTO.setVariables(processVariables); String modelKey = processInstance.getProcessDefinitionKey(); List mis = flowEngineService.getNodeByFlowableKey(modelKey); Map taskMap = new HashMap<>(); mis.stream().forEach(e->{ String taskId = e.getTaskId(); String taskName = e.getTaskName(); taskMap.put(taskId,taskName); }); // 输出连线 List outFlows = flowNode.getOutgoingFlows(); for (SequenceFlow sequenceFlow : outFlows) { String toname = sequenceFlow.getName()==null?"同意":sequenceFlow.getName(); //当前审批节点 if (NODE_NOW.equals(node)) { FlowElement sourceFlowElement = sequenceFlow.getSourceFlowElement(); System.out.println("当前节点: id=" + sourceFlowElement.getId() + ",name=" + sourceFlowElement.getName()); } else if (NODE_NEXT.equals(node)) { // 下一个审批节点 FlowElement targetFlow = sequenceFlow.getTargetFlowElement(); if (targetFlow instanceof UserTask) { FlowTaskDTO flowTaskUserCi = new FlowTaskDTO(); //flowTaskUserCi.setConditionKey(null); //flowTaskUserCi.setConditionValue(null); flowTaskUserCi.setToName(toname); flowTaskUserCi.setToTaskId(targetFlow.getId()); String taskName = taskMap.get(targetFlow.getId()); flowTaskUserCi.setToTaskName(taskName); flowTaskUserCi.setTaskName(taskName); taskList.add(flowTaskUserCi); } //结束 if (targetFlow instanceof EndEvent) { FlowTaskDTO flowTaskUserCi = new FlowTaskDTO(); //flowTaskUserCi.setConditionKey(null); //flowTaskUserCi.setConditionValue(null); flowTaskUserCi.setToName("同意"); flowTaskUserCi.setToTaskId(targetFlow.getId()); flowTaskUserCi.setToTaskName(targetFlow.getName()); taskList.add(flowTaskUserCi); } // 如果下个审批节点为网关 if (targetFlow instanceof Gateway) { ExclusiveGateway exclusiveGateway = (ExclusiveGateway) targetFlow; List exclusiveGatewayOutgoingFlows = exclusiveGateway.getOutgoingFlows(); for (SequenceFlow nexti:exclusiveGatewayOutgoingFlows){ String conditionExpression = nexti.getConditionExpression();//condition String taskId = nexti.getTargetRef();//taskId String name = nexti.getName();//toName,驳回、同意 String taskName = taskMap.get(taskId); //ExclusiveGateway if(StringUtils.isEmpty(conditionExpression)){//此时排他网关没有配置流转条件 continue; } for (FlowTaskDTO flowTaskUserCi:mis){ if(taskId.equals(flowTaskUserCi.getTaskId())){ flowTaskUserCi.setCondition(conditionExpression); if(conditionExpression.contains("=")||conditionExpression.contains("<")||conditionExpression.contains(">")) { conditionExpression = conditionExpression.replace("${","").replace("}","").replaceAll("\"",""); String[] conditionExpressionStr = conditionExpression.split("=="); if(conditionExpression.contains("<")){ conditionExpressionStr = conditionExpression.split("<"); }else if(conditionExpression.contains("<=")){ conditionExpressionStr = conditionExpression.split("<="); }else if(conditionExpression.contains(">")){ conditionExpressionStr = conditionExpression.split(">"); }else if(conditionExpression.contains(">=")){ conditionExpressionStr = conditionExpression.split(">="); } flowTaskUserCi.setConditionKey(conditionExpressionStr.length>0?conditionExpressionStr[0]:null); flowTaskUserCi.setConditionValue(conditionExpressionStr.length>1?conditionExpressionStr[1]:null); } flowTaskUserCi.setToName(name); flowTaskUserCi.setToTaskId(taskId); flowTaskUserCi.setToTaskName(taskName); flowTaskUserCi.setTaskName(taskName); taskList.add(flowTaskUserCi); } } } } } } //流程常量 Map variables = runtimeService.getVariables(processInstanceId); if(!variables.isEmpty()){ flowTaskDTO.setVariables(variables); } //流程阶段 Map m = new HashMap<>(); String templateId = variables.get("templateId").toString(); m.put("template_id", templateId); m.put("task_id", crruentActivityId); m.put("model_key", modelKey); QueryWrapper q = Condition.getQueryWrapper(m, ProcessStageAttr.class) .select("attr_id attrId,attr_name attrName,attr_group attrGroup"); List stageAttrs = processStageAttrService.list(q); List stageAttrsDto = new ArrayList<>(); stageAttrs.stream().forEach(e->{ ProcessStageAttrDTO dto = new ProcessStageAttrDTO(); BeanUtil.convert(e,dto); stageAttrsDto.add(dto); }); flowTaskDTO.setStageAttrs(stageAttrsDto); //放入流程阶段、流程modelkey variables.put(TASKID,crruentActivityId); variables.put(PROCESSINSTANCEID,processInstanceId); return flowTaskDTO; } }