/* * 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.business.service.impl; import com.baomidou.mybatisplus.core.metadata.IPage; import com.vci.ubcs.flow.business.service.FlowBusinessService; import com.vci.ubcs.flow.core.constant.ProcessConstant; import com.vci.ubcs.flow.core.entity.BladeFlow; import com.vci.ubcs.flow.core.utils.TaskUtil; import com.vci.ubcs.flow.engine.constant.FlowEngineConstant; import com.vci.ubcs.flow.engine.entity.FlowProcess; import com.vci.ubcs.flow.engine.utils.FlowCache; import com.vci.ubcs.flow.engine.utils.FlowableUtils; import com.vci.ubcs.starter.web.util.VciDateUtil; import com.vci.ubcs.system.user.cache.UserCache; import com.vci.ubcs.system.user.entity.User; import lombok.AllArgsConstructor; import org.apache.commons.lang3.StringUtils; import org.flowable.engine.HistoryService; import org.flowable.engine.RuntimeService; import org.flowable.engine.TaskService; import org.flowable.engine.history.HistoricActivityInstance; import org.flowable.engine.history.HistoricProcessInstance; import org.flowable.engine.history.HistoricProcessInstanceQuery; import org.flowable.engine.runtime.Execution; import org.flowable.engine.task.Comment; import org.flowable.task.api.TaskQuery; import org.flowable.task.api.history.HistoricTaskInstance; import org.flowable.task.api.history.HistoricTaskInstanceQuery; import org.flowable.variable.api.history.HistoricVariableInstance; import org.springblade.core.secure.utils.AuthUtil; import org.springblade.core.tool.support.Kv; import org.springblade.core.tool.utils.Func; import org.springblade.core.tool.utils.StringPool; import org.springblade.core.tool.utils.StringUtil; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Map; /** * 流程业务实现类 * * @author Chill */ @Service @AllArgsConstructor public class FlowBusinessServiceImpl implements FlowBusinessService { private final TaskService taskService; private final HistoryService historyService; private final RuntimeService runtimeService; @Override public IPage selectClaimPage(IPage page, BladeFlow bladeFlow) { String taskUser = TaskUtil.getTaskUser(); String taskGroup = TaskUtil.getCandidateGroup(); List flowList = new LinkedList<>(); // 个人等待签收的任务 TaskQuery claimUserQuery = taskService.createTaskQuery().taskCandidateUser(taskUser) .includeProcessVariables().active().orderByTaskCreateTime().desc(); // 定制流程等待签收的任务 TaskQuery claimRoleWithTenantIdQuery = taskService.createTaskQuery().taskTenantId(AuthUtil.getTenantId()).taskCandidateGroupIn(Func.toStrList(taskGroup)) .includeProcessVariables().active().orderByTaskCreateTime().desc(); // 通用流程等待签收的任务 TaskQuery claimRoleWithoutTenantIdQuery = taskService.createTaskQuery().taskWithoutTenantId().taskCandidateGroupIn(Func.toStrList(taskGroup)) .includeProcessVariables().active().orderByTaskCreateTime().desc(); // 构建列表数据 buildFlowTaskList(bladeFlow, flowList, claimUserQuery, FlowEngineConstant.STATUS_CLAIM, page); buildFlowTaskList(bladeFlow, flowList, claimRoleWithTenantIdQuery, FlowEngineConstant.STATUS_CLAIM, page); buildFlowTaskList(bladeFlow, flowList, claimRoleWithoutTenantIdQuery, FlowEngineConstant.STATUS_CLAIM, page); // 计算总数 long count = claimUserQuery.count() + claimRoleWithTenantIdQuery.count() + claimRoleWithoutTenantIdQuery.count(); // 设置页数 page.setSize(count); // 设置总数 page.setTotal(count); // 设置数据 page.setRecords(flowList); return page; } @Override public IPage selectTodoPage(IPage page, BladeFlow bladeFlow) { String taskUser = TaskUtil.getTaskUser(); List flowList = new LinkedList<>(); // 已签收的任务 TaskQuery todoQuery = taskService.createTaskQuery().taskAssignee(taskUser).active() .includeProcessVariables().orderByTaskCreateTime().desc(); // 构建列表数据 buildFlowTaskList(bladeFlow, flowList, todoQuery, FlowEngineConstant.STATUS_TODO,page); // 计算总数 long count = todoQuery.count(); // 设置页数 page.setSize(count); // 设置总数 page.setTotal(count); // 设置数据 page.setRecords(flowList); return page; } @Override public IPage selectSendPage(IPage page, BladeFlow bladeFlow) { String taskUser = TaskUtil.getTaskUser(); List flowList = new LinkedList<>(); HistoricProcessInstanceQuery historyQuery = historyService.createHistoricProcessInstanceQuery().startedBy(taskUser).orderByProcessInstanceStartTime().desc(); if (StringUtils.isNotEmpty(bladeFlow.getCategory())) { historyQuery.processDefinitionCategory(bladeFlow.getCategory()); } if (bladeFlow.getProcessDefinitionName() != null) { historyQuery.processDefinitionName(bladeFlow.getProcessDefinitionName()); } if (bladeFlow.getBeginDate() != null) { historyQuery.startedAfter(bladeFlow.getBeginDate()); } if (bladeFlow.getEndDate() != null) { historyQuery.startedBefore(bladeFlow.getEndDate()); } // 查询列表 List historyList = historyQuery.listPage(Func.toInt((page.getCurrent() - 1) * page.getSize()), Func.toInt(page.getSize())); historyList.forEach(historicProcessInstance -> { BladeFlow flow = new BladeFlow(); // historicProcessInstance flow.setCreateTime(historicProcessInstance.getStartTime()); flow.setEndTime(historicProcessInstance.getEndTime()); flow.setVariables(historicProcessInstance.getProcessVariables()); String[] businessKey = Func.toStrArray(StringPool.COLON, historicProcessInstance.getBusinessKey()); if (businessKey.length > 1) { flow.setBusinessTable(businessKey[0]); flow.setBusinessId(businessKey.length>1?businessKey[1]:"1"); } flow.setHistoryActivityName(historicProcessInstance.getName()); flow.setProcessInstanceId(historicProcessInstance.getId()); flow.setHistoryProcessInstanceId(historicProcessInstance.getId()); // ProcessDefinition FlowProcess processDefinition = FlowCache.getProcessDefinition(historicProcessInstance.getProcessDefinitionId()); flow.setProcessDefinitionId(processDefinition.getId()); flow.setProcessDefinitionName(processDefinition.getName()); flow.setProcessDefinitionVersion(processDefinition.getVersion()); flow.setProcessDefinitionKey(processDefinition.getKey()); flow.setCategory(processDefinition.getCategory()); flow.setCategoryName(FlowCache.getCategoryName(processDefinition.getCategory())); flow.setProcessInstanceId(historicProcessInstance.getId()); // HistoricTaskInstance List historyTasks = historyService.createHistoricTaskInstanceQuery().processInstanceId(historicProcessInstance.getId()).orderByHistoricTaskInstanceEndTime().desc().list(); if (Func.isNotEmpty(historyTasks)) { HistoricTaskInstance historyTask = historyTasks.iterator().next(); flow.setTaskId(historyTask.getId()); flow.setTaskName(historyTask.getName()); flow.setTaskDefinitionKey(historyTask.getTaskDefinitionKey()); } // Status if (historicProcessInstance.getEndActivityId() != null) { flow.setProcessIsFinished(FlowEngineConstant.STATUS_FINISHED); } else { flow.setProcessIsFinished(FlowEngineConstant.STATUS_UNFINISHED); } flow.setStatus(FlowEngineConstant.STATUS_FINISH); //流程发起时间 flow.setProcessDefinitionStartTime(VciDateUtil.date2Str(historicProcessInstance.getStartTime(),VciDateUtil.DateTimeFormat)); //流程变量 List variableInstances = historyService.createHistoricVariableInstanceQuery().processInstanceId(historicProcessInstance.getId()).list(); Map variables = FlowableUtils.switchVariable(variableInstances); flow.setVariables(variables); //businessKey if (Func.isNotEmpty(historicProcessInstance)) { flow.setBusinessId(businessKey.length>1 && StringUtils.isNotEmpty(businessKey[1])?businessKey[1]:"1"); } flowList.add(flow); }); // 计算总数 long count = historyQuery.count(); // 设置总数 page.setTotal(count); page.setRecords(flowList); return page; } @Override public IPage selectDonePage(IPage page, BladeFlow bladeFlow) { String taskUser = TaskUtil.getTaskUser(); List flowList = new LinkedList<>(); HistoricTaskInstanceQuery doneQuery = historyService.createHistoricTaskInstanceQuery().taskAssignee(taskUser).finished() .includeProcessVariables().orderByHistoricTaskInstanceEndTime().desc(); if (StringUtils.isNotEmpty(bladeFlow.getCategory())) { doneQuery.processCategoryIn(Func.toStrList(bladeFlow.getCategory())); } if (bladeFlow.getProcessDefinitionName() != null) { doneQuery.processDefinitionName(bladeFlow.getProcessDefinitionName()); } if (bladeFlow.getBeginDate() != null) { doneQuery.taskCompletedAfter(bladeFlow.getBeginDate()); } if (bladeFlow.getEndDate() != null) { doneQuery.taskCompletedBefore(bladeFlow.getEndDate()); } // 查询列表 List doneList = doneQuery.listPage(Func.toInt((page.getCurrent() - 1) * page.getSize()), Func.toInt(page.getSize())); doneList.forEach(historicTaskInstance -> { BladeFlow flow = new BladeFlow(); flow.setTaskId(historicTaskInstance.getId()); flow.setTaskDefinitionKey(historicTaskInstance.getTaskDefinitionKey()); flow.setTaskName(historicTaskInstance.getName()); flow.setAssignee(historicTaskInstance.getAssignee()); flow.setCreateTime(historicTaskInstance.getCreateTime()); flow.setExecutionId(historicTaskInstance.getExecutionId()); flow.setHistoryTaskEndTime(historicTaskInstance.getEndTime()); flow.setVariables(historicTaskInstance.getProcessVariables()); FlowProcess processDefinition = FlowCache.getProcessDefinition(historicTaskInstance.getProcessDefinitionId()); flow.setProcessDefinitionId(processDefinition.getId()); flow.setProcessDefinitionName(processDefinition.getName()); flow.setProcessDefinitionKey(processDefinition.getKey()); flow.setProcessDefinitionVersion(processDefinition.getVersion()); flow.setCategory(processDefinition.getCategory()); flow.setCategoryName(FlowCache.getCategoryName(processDefinition.getCategory())); flow.setProcessInstanceId(historicTaskInstance.getProcessInstanceId()); flow.setHistoryProcessInstanceId(historicTaskInstance.getProcessInstanceId()); HistoricProcessInstance historicProcessInstance = getHistoricProcessInstance((historicTaskInstance.getProcessInstanceId())); if (Func.isNotEmpty(historicProcessInstance)) { String[] businessKey = Func.toStrArray(StringPool.COLON, historicProcessInstance.getBusinessKey()); flow.setBusinessTable(businessKey[0]); flow.setBusinessId(businessKey.length>1?businessKey[1]:"1"); if (historicProcessInstance.getEndActivityId() != null) { flow.setProcessIsFinished(FlowEngineConstant.STATUS_FINISHED); } else { flow.setProcessIsFinished(FlowEngineConstant.STATUS_UNFINISHED); } } flow.setStatus(FlowEngineConstant.STATUS_FINISH); flowList.add(flow); }); // 计算总数 long count = doneQuery.count(); // 设置总数 page.setTotal(count); page.setRecords(flowList); return page; } @Override public boolean completeTask(BladeFlow flow) { String taskId = flow.getTaskId(); String processInstanceId = flow.getProcessInstanceId(); String comment = Func.toStr(flow.getComment(), ProcessConstant.PASS_COMMENT); // 增加评论 if (StringUtil.isNoneBlank(processInstanceId, comment)) { taskService.addComment(taskId, processInstanceId, comment); } // 创建变量 Map variables = flow.getVariables(); if (variables == null) { variables = Kv.create(); } variables.put(ProcessConstant.PASS_KEY, flow.isPass()); // 完成任务 taskService.complete(taskId, variables); return true; } /** * 构建流程 * * @param bladeFlow 流程通用类 * @param flowList 流程列表 * @param taskQuery 任务查询类 * @param status 状态 * @param page */ private void buildFlowTaskList(BladeFlow bladeFlow, List flowList, TaskQuery taskQuery, String status, IPage page) { // if (bladeFlow.getCategory() != null) { if (StringUtils.isNotEmpty(bladeFlow.getCategory())) { taskQuery.processCategoryIn(Func.toStrList(bladeFlow.getCategory())); } if (bladeFlow.getProcessDefinitionName() != null) { taskQuery.processDefinitionName(bladeFlow.getProcessDefinitionName()); } if (bladeFlow.getBeginDate() != null) { taskQuery.taskCreatedAfter(bladeFlow.getBeginDate()); } if (bladeFlow.getEndDate() != null) { taskQuery.taskCreatedBefore(bladeFlow.getEndDate()); } int firstResult = (int) ((page.getCurrent()-1)* page.getSize()); int maxResult = (int) page.getSize(); taskQuery.listPage(firstResult,maxResult).forEach(task -> { BladeFlow flow = new BladeFlow(); flow.setTaskId(task.getId()); flow.setTaskDefinitionKey(task.getTaskDefinitionKey()); flow.setTaskName(task.getName()); flow.setAssignee(task.getAssignee()); flow.setCreateTime(task.getCreateTime()); flow.setClaimTime(task.getClaimTime()); flow.setExecutionId(task.getExecutionId()); flow.setVariables(task.getProcessVariables()); HistoricProcessInstance historicProcessInstance = getHistoricProcessInstance(task.getProcessInstanceId()); //获取上一任务信息 HistoricActivityInstance historicActivityInstance = getPrevHistoricActivityInstance(task.getProcessInstanceId(),task.getId()); flow.setHistoryActivityId(historicActivityInstance.getTaskId()); flow.setHistoryActivityName(historicActivityInstance.getActivityName()); //获取历史任务执行人 if(historicActivityInstance.getActivityType().equals(FlowEngineConstant.USR_TASK)){ User user = UserCache.getUser(TaskUtil.getUserId(historicActivityInstance.getAssignee())); flow.setHistoryActivityAssigne(historicActivityInstance.getAssignee()); flow.setHistoryActivityAssigneName(user.getName()); List commentList = taskService.getTaskComments(historicActivityInstance.getTaskId()); if (commentList.size() > 0) { flow.setHistoryActivityIdea(commentList.get(0).getFullMessage()); } } List processInstanceList = historyService.createHistoricProcessInstanceQuery() .processInstanceId(task.getProcessInstanceId()).orderByProcessInstanceStartTime().asc().list(); flow.setProcessDefinitionStartTime(VciDateUtil.date2Str(processInstanceList.get(0).getStartTime(),VciDateUtil.DateTimeFormat)); // 获取流程发起人名称 if (FlowEngineConstant.START_EVENT.equals(historicActivityInstance.getActivityType())) { if (processInstanceList.size() > 0) { if (StringUtil.isNotBlank(processInstanceList.get(0).getStartUserId())) { String taskUser = processInstanceList.get(0).getStartUserId(); User user = UserCache.getUser(TaskUtil.getUserId(taskUser)); if (user != null) { flow.setHistoryActivityAssigne(historicActivityInstance.getAssignee()); flow.setHistoryActivityAssigneName(user.getName()); } } } } if (Func.isNotEmpty(historicProcessInstance)) { String[] businessKey = new String[2]; if(historicProcessInstance.getBusinessKey().contains(StringPool.COLON)){ businessKey = Func.toStrArray(StringPool.COLON, historicProcessInstance.getBusinessKey()); }else{ businessKey[0] = historicProcessInstance.getBusinessKey(); } flow.setBusinessTable(businessKey[0]); flow.setBusinessId(businessKey.length>1 && StringUtils.isNotEmpty(businessKey[1])?businessKey[1]:"1"); } FlowProcess processDefinition = FlowCache.getProcessDefinition(task.getProcessDefinitionId()); flow.setCategory(processDefinition.getCategory()); flow.setCategoryName(FlowCache.getCategoryName(processDefinition.getCategory())); flow.setProcessDefinitionId(processDefinition.getId()); flow.setProcessDefinitionName(processDefinition.getName()); flow.setProcessDefinitionKey(processDefinition.getKey()); flow.setProcessDefinitionVersion(processDefinition.getVersion()); flow.setProcessInstanceId(task.getProcessInstanceId()); flow.setStatus(status); flowList.add(flow); }); } private HistoricActivityInstance getPrevHistoricActivityInstance(String processInstanceId, String taskDefinitionId) { List historicActivityInstanceList = historyService.createHistoricActivityInstanceQuery().processInstanceId(processInstanceId) .orderByHistoricActivityInstanceStartTime().asc() .orderByHistoricActivityInstanceEndTime().asc().list(); List tempList = new ArrayList<>(); int index = 0; for(HistoricActivityInstance historicActivityInstance : historicActivityInstanceList){ if (StringUtils.equals(FlowEngineConstant.USR_TASK, historicActivityInstance.getActivityType()) || FlowEngineConstant.START_EVENT.equals(historicActivityInstance.getActivityType()) || FlowEngineConstant.END_EVENT.equals(historicActivityInstance.getActivityType())) { tempList.add(historicActivityInstance); } if(StringUtils.isNotEmpty(historicActivityInstance.getTaskId()) && historicActivityInstance.getTaskId().equals(taskDefinitionId)){ index = tempList.indexOf(historicActivityInstance); break; } } if(index == 0){ return tempList.get(0); } return tempList.get(index-1); } /** * 获取历史流程 * * @param processInstanceId 流程实例id * @return HistoricProcessInstance */ private HistoricProcessInstance getHistoricProcessInstance(String processInstanceId) { return historyService.createHistoricProcessInstanceQuery().processInstanceId(processInstanceId).singleResult(); } public Object getVar(String processInstanceId,String key){ Object t = null; List list = runtimeService.createExecutionQuery().processInstanceId(processInstanceId).list(); for (Execution execution : list) { Object va = runtimeService.getVariable(execution.getId(),key); if(va!=null){ t=va; } } return t; } }