package cn.palmte.work.service; import cn.palmte.work.bean.ApproveStatusEnum; import cn.palmte.work.config.activiti.ActConstant; import cn.palmte.work.config.activiti.ActTaskIndexEnum; import cn.palmte.work.model.ActTaskDefRepository; import cn.palmte.work.model.ProjectTaskRecord; import cn.palmte.work.pojo.ActProcIns; import cn.palmte.work.utils.ActUtil; import cn.palmte.work.utils.InterfaceUtil; import cn.palmte.work.utils.StrKit; import com.alibaba.fastjson.JSON; import org.activiti.bpmn.model.BpmnModel; import org.activiti.bpmn.model.FlowNode; import org.activiti.bpmn.model.SequenceFlow; import org.activiti.engine.HistoryService; import org.activiti.engine.RepositoryService; import org.activiti.engine.RuntimeService; import org.activiti.engine.TaskService; import org.activiti.engine.history.HistoricActivityInstance; import org.activiti.engine.history.HistoricProcessInstance; import org.activiti.engine.impl.identity.Authentication; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.Task; import org.apache.commons.lang.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import top.jfunc.common.db.QueryHelper; import top.jfunc.common.db.bean.Page; import top.jfunc.common.db.utils.Pagination; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; @Service public class ActProcInsService { private static final Logger logger = LoggerFactory.getLogger(ActProcInsService.class); @Autowired private RepositoryService repositoryService; //管理流程定义 与流程定义和部署对象相关的Service @Autowired private TaskService taskService; //任务管理 与正在执行的任务管理相关的Service @Autowired private AccountService accountService; @Autowired private RuntimeService runtimeService; //与正在执行的流程实例和执行对象相关的Service(执行管理,包括启动、推进、删除流程实例等操作) @Autowired Pagination pagination; @Autowired private ProjectTaskRecordService projectTaskRecordService; @Autowired private HistoryService historyService; //历史管理(执行完的数据的管理) @Autowired private ActTaskDefRepository actTaskDefRepository; @Autowired private ActUtil actUtil; /** * 正常启动流程实列 * * @param procDefKey * @param variables * @return */ public String startProcessInstance(String procDefKey, String businessKey, Map variables) throws Exception { List list = repositoryService.createProcessDefinitionQuery().processDefinitionKey(procDefKey).active().orderByProcessDefinitionVersion().desc().list(); if (list == null || list.isEmpty()) { throw new Exception("procDefKey(" + procDefKey + ")未定义"); } //取最新版本的流程定义进行启动流程实列 ProcessDefinition processDefinition = list.get(0); String adminId = InterfaceUtil.getAdminId() + ""; variables.put(ActConstant.START_PROCESS_USERID, adminId); //启动流程 ProcessInstance instance = runtimeService.startProcessInstanceById(processDefinition.getId(), businessKey, variables); logger.info("startProcessInstanceSuccess procInsId:{}, procDefKey:{}, procDefName:{}, variables:{}", instance.getId(), instance.getProcessDefinitionKey(), instance.getProcessDefinitionName(), JSON.toJSONString(variables)); String procInsId = instance.getProcessInstanceId(); Task task = taskService.createTaskQuery().processInstanceId(procInsId).singleResult(); if (task == null) { throw new Exception("procDefKey(" + procDefKey + ")启动异常"); } String taskId = task.getId(); String comment = "提交" + processDefinition.getName(); Authentication.setAuthenticatedUserId(adminId); taskService.addComment(taskId, procInsId, comment); //设置发起人为办理人 然后完成任务 任务转入下一个审批节点 taskService.setAssignee(taskId, adminId); taskService.complete(taskId); projectTaskRecordService.saveTaskRecord(Integer.parseInt(instance.getBusinessKey()), task, ApproveStatusEnum.APPROVAL_PENDING.getApproveStatus(), ActTaskIndexEnum.FIRST_USER_TASK.getIndex(), comment); return instance.getId(); } /** * 系统启动流程实列 * * @param procDefKey * @param businessKey * @param variables * @return * @throws Exception */ public String startProcessInstanceBySystem(String procDefKey, String businessKey, Map variables, ProjectTaskRecord taskRecord) throws Exception { List list = repositoryService.createProcessDefinitionQuery().processDefinitionKey(procDefKey).active().orderByProcessDefinitionVersion().desc().list(); if (list == null || list.isEmpty()) { throw new Exception("procDefKey(" + procDefKey + ")未定义"); } //取最新版本的流程定义进行启动流程实列 ProcessDefinition processDefinition = list.get(0); String adminId = "-1"; variables.put(ActConstant.START_PROCESS_USERID, adminId); //启动流程 ProcessInstance instance = runtimeService.startProcessInstanceById(processDefinition.getId(), businessKey, variables); logger.info("startProcessInstanceSuccess procInsId:{}, procDefKey:{}, procDefName:{}", instance.getId(), instance.getProcessDefinitionKey(), instance.getProcessDefinitionName()); String procInsId = instance.getProcessInstanceId(); Task task = taskService.createTaskQuery().processInstanceId(procInsId).singleResult(); if (task == null) { throw new Exception("procDefKey(" + procDefKey + ")启动异常"); } String taskId = task.getId(); String comment = "系统提交" + processDefinition.getName(); Authentication.setAuthenticatedUserId(adminId); taskService.addComment(taskId, procInsId, comment); taskService.setAssignee(taskId, taskRecord.getAssigneeId() + ""); return instance.getId(); } /** * 流程实列列表 * * @param searchInfo * @param pageNumber * @param pageSize * @return */ public Page list(ConcurrentHashMap searchInfo, int pageNumber, int pageSize) { String select = "select h.proc_inst_id_ as procInsId,h.proc_def_id_ as procDefId," + "h.start_time_ as startTime,h.end_time_ as endTime,p.key_ as procKey," + "p.name_ as procName,p.NAME_ as dgrmResourceName,p.version_ as version," + " GROUP_CONCAT(t.NAME_) as currentTask, GROUP_CONCAT(t.ID_) as currentTaskId," + " pjct.name as projectName,pp.project_title AS projectTitle"; QueryHelper queryHelper = new QueryHelper(select, " act_hi_procinst h " + "left join ACT_RE_PROCDEF p on h.PROC_DEF_ID_ =p.ID_ " + "LEFT JOIN act_ru_task t on t.PROC_INST_ID_=h.proc_inst_id_ " + "LEFT JOIN project pjct on pjct.id=h.BUSINESS_KEY_ " + "LEFT JOIN project_process pp on pp.id=h.BUSINESS_KEY_ "); String procDefKey = searchInfo.get("procDefKey"); queryHelper.addCondition(StrKit.notBlank(procDefKey), "p.key_=?", procDefKey); String projectName = searchInfo.get("projectName"); String projectNameLike = "%" + projectName + "%"; queryHelper.addCondition(StrKit.notBlank(projectName), " (pjct.name like ? or pp.project_title like ?) ", projectNameLike, projectNameLike); String projectId = searchInfo.get("projectId"); queryHelper.addCondition(StrKit.notBlank(projectId), "h.BUSINESS_KEY_ =? ", projectId); String procInsId = searchInfo.get("procInsId"); queryHelper.addCondition(StrKit.notBlank(procInsId), "h.proc_inst_id_ =? ", procInsId); queryHelper.addGroupProperty("h.PROC_INST_ID_"); queryHelper.addOrderProperty("h.start_time_", false); Page paginate = pagination.paginate(queryHelper.getSql(), ActProcIns.class, pageNumber, pageSize); List list = paginate.getList(); for (ActProcIns ins : list) { //查询流程发起人 String userId = actUtil.getStartUserId(ins.getProcInsId()); ins.setUser(accountService.getNameById(Integer.parseInt(userId))); //查询当前任务审批人 String currentTaskId = ins.getCurrentTaskId(); if (StringUtils.isNotBlank(currentTaskId)) { String[] split = currentTaskId.split(","); String candidateUsers = ""; for (String taskId : split) { candidateUsers += actUtil.getAssigneeByIdentityLink(taskId) + ","; } if (candidateUsers.endsWith(",")) { candidateUsers = candidateUsers.substring(0, candidateUsers.length() - 1); } ins.setCandidateUsers(candidateUsers); } } return paginate; } public void deleteProcessInstance(String procInsId, String reason) { runtimeService.deleteProcessInstance(procInsId, reason); } public void createProcInsPng(HttpServletResponse response, String procInsId) throws IOException { try { HistoricProcessInstance historicProcessInstance = historyService.createHistoricProcessInstanceQuery().processInstanceId(procInsId).singleResult(); //获取历史流程实例 //获取流程中已经执行的节点,按照执行先后顺序排序 List hai = historyService.createHistoricActivityInstanceQuery().processInstanceId(procInsId).orderByHistoricActivityInstanceStartTime().asc().list(); // 历史流程节点中 List newHisActInstanceList = new ArrayList(); List newHisTaskInstanceList = new ArrayList(); if (hai != null && hai.size() > 0) { for (int i = 0; i < hai.size(); i++) { HistoricActivityInstance historicActivityInstance = hai.get(i); String activityType = historicActivityInstance.getActivityType(); if (activityType.equals("startEvent") || activityType.equals("endEvent")) { newHisActInstanceList.add(historicActivityInstance); } else if (activityType.equals("serviceTask") || activityType.equals("userTask") || activityType.equals("exclusiveGateway") || activityType.equals("parallelGateway")) { if (newHisTaskInstanceList.size() > 0) { for (int j = 0; j < newHisTaskInstanceList.size(); j++) { HistoricActivityInstance historicTaskInstance = newHisTaskInstanceList.get(j); if (historicTaskInstance.getActivityId().equals(historicActivityInstance.getActivityId())) { //如果列表中已包括 newHisTaskInstanceList.clear(); newHisTaskInstanceList.add(historicActivityInstance); break; } else { newHisTaskInstanceList.add(historicActivityInstance); break; } } } else { newHisTaskInstanceList.add(historicActivityInstance); } } } } for (int i = 0; i < newHisActInstanceList.size(); i++) { HistoricActivityInstance historicActivityInstance = newHisActInstanceList.get(i); newHisTaskInstanceList.add(historicActivityInstance); } List executedActivityIdList = new ArrayList(); // 构造已执行的节点ID集合 for (HistoricActivityInstance activityInstance : newHisTaskInstanceList) { executedActivityIdList.add(activityInstance.getActivityId()); } BpmnModel bpmnModel = repositoryService.getBpmnModel(historicProcessInstance.getProcessDefinitionId()); // 获取bpmnModel List flowIds = this.getExecutedFlows(bpmnModel, newHisTaskInstanceList); // 获取流程已发生流转的线ID集合 actUtil.responsePng(response, bpmnModel, executedActivityIdList, flowIds); } catch (Exception e) { logger.error("an exception happens in try catch statement", e); } } public List getExecutedFlows(BpmnModel bpmnModel, List historicActivityInstances) { List flowIdList = new ArrayList(); //流转线ID集合 List historicFlowNodeList = new LinkedList(); //全部活动实例 List finishedActivityInstanceList = new LinkedList(); //已完成的历史活动节点 List list = new ArrayList(); for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) { historicFlowNodeList.add((FlowNode) bpmnModel.getMainProcess().getFlowElement(historicActivityInstance.getActivityId(), true)); if (historicActivityInstance.getEndTime() != null) { finishedActivityInstanceList.add(historicActivityInstance); } } for (int x = 0; x < historicActivityInstances.size(); x++) { HistoricActivityInstance historicActivityInstance = historicActivityInstances.get(x); String activityType = historicActivityInstance.getActivityType(); String activityId = historicActivityInstance.getActivityId(); if (!list.contains(activityId) && ("userTask".equals(activityType) || "serviceTask".equals(activityType) || "endEvent".equals(activityType) || "exclusiveGateway".equals(activityType) || "parallelGateway".equals(activityType))) { list.add(activityId); } } /**遍历已完成的活动实例,从每个实例的outgoingFlows中找到已执行的*/ FlowNode currentFlowNode = null; for (HistoricActivityInstance currentActivityInstance : finishedActivityInstanceList) { /**获得当前活动对应的节点信息及outgoingFlows信息*/ currentFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(currentActivityInstance.getActivityId(), true); List sequenceFlowList = currentFlowNode.getOutgoingFlows(); /** * 遍历outgoingFlows并找到已流转的 * 满足如下条件任务已流转: * 1.当前节点是并行网关或包含网关,则通过outgoingFlows能够在历史活动中找到的全部节点均为已流转 * 2.当前节点是以上两种类型之外的,通过outgoingFlows查找到的时间最近的流转节点视为有效流转 */ FlowNode targetFlowNode = null; if ("parallelGateway".equals(currentActivityInstance.getActivityType()) || "inclusiveGateway".equals(currentActivityInstance.getActivityType())) { for (SequenceFlow sequenceFlow : sequenceFlowList) { //遍历历史活动节点,找到匹配Flow目标节点的 targetFlowNode = (FlowNode) bpmnModel.getMainProcess().getFlowElement(sequenceFlow.getTargetRef(), true); if (historicFlowNodeList.contains(targetFlowNode)) { flowIdList.add(sequenceFlow.getId()); } } } else { List> tempMapList = new LinkedList>(); // for(SequenceFlow sequenceFlow : sequenceFlowList) { //遍历历史活动节点,找到匹配Flow目标节点的 for (int i = 0; i < sequenceFlowList.size(); i++) { //遍历历史活动节点,找到匹配Flow目标节点的 SequenceFlow sequenceFlow = sequenceFlowList.get(i); int taskSeq = list.indexOf(sequenceFlow.getSourceRef()); // 获取当前flow目标节点key在审批顺序 String nextTaskKey = ""; // 下一个任务节点 String beforeTaskKey = sequenceFlow.getSourceRef(); //上一个任务节点 if ((taskSeq + 1) < list.size()) { // 判断下一个任务节点是否存在 nextTaskKey = String.valueOf(list.get((taskSeq + 1))); } if (taskSeq == list.size() - 1) { nextTaskKey = String.valueOf(list.get((taskSeq))); } for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) { if (historicActivityInstance.getActivityId().equals(sequenceFlow.getTargetRef()) && sequenceFlow.getSourceRef().equals(beforeTaskKey) && sequenceFlow.getTargetRef().equals(nextTaskKey)) { Map map = new HashMap<>(); map.put("flowId", sequenceFlow.getId()); map.put("activityStartTime", String.valueOf(historicActivityInstance.getStartTime().getTime())); tempMapList.add(map); } } } String flowId = null; for (Map map : tempMapList) { flowId = map.get("flowId"); flowIdList.add(flowId); } } } return flowIdList; } }