package cn.palmte.work.utils; import cn.palmte.work.config.activiti.ActConstant; import cn.palmte.work.config.activiti.DeleteTaskCommand; import cn.palmte.work.config.activiti.JumpCommand; import cn.palmte.work.model.ActScript; import cn.palmte.work.model.ActScriptRepository; import cn.palmte.work.model.ActTaskDef; import cn.palmte.work.service.AccountService; import org.activiti.bpmn.model.BpmnModel; import org.activiti.bpmn.model.FlowNode; import org.activiti.engine.ManagementService; import org.activiti.engine.ProcessEngine; import org.activiti.engine.RepositoryService; import org.activiti.engine.TaskService; import org.activiti.engine.repository.ProcessDefinition; import org.activiti.engine.runtime.ProcessInstance; import org.activiti.engine.task.IdentityLink; import org.activiti.engine.task.Task; import org.activiti.image.ProcessDiagramGenerator; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.ApplicationContext; import org.springframework.stereotype.Component; import top.jfunc.common.db.bean.Record; import top.jfunc.common.db.utils.Pagination; import top.jfunc.common.utils.IoUtil; import javax.annotation.Resource; import javax.servlet.http.HttpServletResponse; import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @Component public class ActUtil { private static final Logger logger = LoggerFactory.getLogger(ActUtil.class); @Autowired private ProcessEngine processEngine; @Autowired private RepositoryService repositoryService; @Autowired Pagination pagination; @Autowired private ActScriptRepository actScriptRepository; @Resource private ApplicationContext applicationContext; @Autowired private TaskService taskService; @Autowired private AccountService accountService; /** * 获取流程实例里的变量 * * @param variableName * @param procInsId * @return */ public Record getVariable(String variableName, String procInsId) { String sql = "select TEXT_ as text from ACT_HI_VARINST where NAME_=? and PROC_INST_ID_=?"; return pagination.findFirst(sql, variableName, procInsId); } public String getStartUserId(String procInsId) { Record record = getVariable(ActConstant.START_PROCESS_USERID, procInsId); if (record != null) { return record.getStr("text"); } return "0"; } /** * 获取流程实列里的所有变量 * * @param procInsId * @return */ public List getVariables(String procInsId) { String sql = "select NAME_ as name, TEXT_ as text from ACT_HI_VARINST where PROC_INST_ID_=?"; return pagination.find(sql, procInsId); } /** * 反射执行脚本 * * @param scriptId * @param procInsId */ public void invokeEventScript(int scriptId, String procInsId, ActTaskDef actTaskDef) { ActScript actScript = actScriptRepository.findOne(scriptId); if (actScript == null) { logger.info("脚本配置错误"); return; } Map map = new HashMap<>(); map.put(ActConstant.PROC_INS_ID, procInsId); map.put(ActConstant.PROC_DEF_KEY, actTaskDef.getProcDefKey()); List variables = getVariables(procInsId); for (Record variable : variables) { map.put(variable.getStr("name"), variable.get("text")); } //调用方法传递的参数 Object[] args = new Object[1]; args[0] = map; logger.info("invokeEventScript class:{}, methond:{}, param:{}", actScript.getClassName(), actScript.getClassMethod(), map); try { Class ownerClass = Class.forName(actScript.getClassName()); Object bean = applicationContext.getBean(ownerClass); Class[] paramsType = new Class[1]; paramsType[0] = Class.forName("java.util.Map"); //找到脚本方法对应的方法 注意:有且只有一个以Map为参数的方法 Method method = ownerClass.getDeclaredMethod(actScript.getClassMethod(), paramsType); method.invoke(bean, args); } catch (Exception e) { logger.error("", e); } } /** * 跳转到指定任务节点 * * @param currentTaskId 当前任务id * @param targetTaskDefKey 跳转目的任务key */ public void jumpToTargetTask(String currentTaskId, String targetTaskDefKey) { Task currentTask = taskService.createTaskQuery().taskId(currentTaskId).singleResult(); // 获取流程定义 org.activiti.bpmn.model.Process process = repositoryService.getBpmnModel(currentTask.getProcessDefinitionId()).getMainProcess(); //获取目标节点定义 FlowNode targetNode = (FlowNode) process.getFlowElement(targetTaskDefKey); ManagementService managementService = processEngine.getManagementService(); //删除当前运行任务 String executionEntityId = managementService.executeCommand(new DeleteTaskCommand(currentTask.getId())); //流程执行到来源节点 managementService.executeCommand(new JumpCommand(targetNode, executionEntityId)); Task singleResult = taskService.createTaskQuery().processInstanceId(currentTask.getProcessInstanceId()).singleResult(); singleResult.setParentTaskId(currentTask.getTaskDefinitionKey()); taskService.saveTask(singleResult); } /** * 响应图片 * * @param response * @param bpmnModel * @param executedActivityIdList * @param flowIds * @throws IOException */ public void responsePng(HttpServletResponse response, BpmnModel bpmnModel, List executedActivityIdList, List flowIds) throws IOException { try (InputStream inputStream = generateDiagramInputStream(bpmnModel, executedActivityIdList, flowIds)) { IoUtil.copy(inputStream, response.getOutputStream()); } } /** * 查看流程xml * * @param response * @param deploymentId * @throws IOException */ public void responseXml(HttpServletResponse response, String deploymentId) throws IOException { try (InputStream inputStream = getXmlStreamByDeploymentId(deploymentId)) { IoUtil.copy(new ByteArrayInputStream("".getBytes()), response.getOutputStream()); IoUtil.copy(inputStream, response.getOutputStream()); IoUtil.copy(new ByteArrayInputStream("".getBytes()), response.getOutputStream()); } } /** * 查询任务审批人 * * @param taskId * @return */ public String getAssigneeByIdentityLink(String taskId) { List identityLinkList = taskService.getIdentityLinksForTask(taskId); if (identityLinkList == null || identityLinkList.isEmpty()) { return ""; } StringBuilder namesBuilder = new StringBuilder(); for (IdentityLink identityLink : identityLinkList) { if ("assignee".equals(identityLink.getType()) || "candidate".equals(identityLink.getType())) { String assigneeUserId = identityLink.getUserId(); namesBuilder.append(accountService.getNameById(Integer.parseInt(assigneeUserId))); namesBuilder.append(","); } } String names = namesBuilder.toString(); if (names.endsWith(",")) { names = names.substring(0, names.length() - 1); } return names; } public List getAssignUserList(String taskId) { List userList = new ArrayList<>(); List identityLinkList = taskService.getIdentityLinksForTask(taskId); if (identityLinkList == null || identityLinkList.isEmpty()) { return userList; } for (IdentityLink identityLink : identityLinkList) { if ("assignee".equals(identityLink.getType()) || "candidate".equals(identityLink.getType())) { String assigneeUserId = identityLink.getUserId(); userList.add(assigneeUserId); } } return userList; } public static String filterNull(final Object str) { String rs = (str == null) ? "" : str.toString().trim(); return "null".equals(rs) ? "" : rs; } public static String filterNullToZero(final Object stro) { String s = filterNull(stro); if ("".equals(s)) { s = "0"; } return s; } public boolean isProjectProcessIns(ProcessInstance processInstance) { if (processInstance == null) { return false; } ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(processInstance.getProcessDefinitionId()).singleResult(); String procDefKey = processDefinition.getKey(); return isProjectProcessIns(procDefKey); } public boolean isProjectProcessIns(String procDefKey) { return procDefKey.equals(ActConstant.PROCESS_DEFKEY_ESTIMATE) || procDefKey.equals(ActConstant.PROCESS_DEFKEY_BUDGET) || procDefKey.equals(ActConstant.PROCESS_DEFKEY_SETTLE) || procDefKey.equals(ActConstant.PROCESS_DEFKEY_FINAL); } /** * 生成xml流 * * @param deploymentId * @return * @throws IOException */ private InputStream getXmlStreamByDeploymentId(String deploymentId) throws IOException { ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploymentId).singleResult(); return repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName()); } /** * 生成流程图片流 * * @param bpmnModel * @param executedActivityIdList * @param flowIds * @return */ private InputStream generateDiagramInputStream(BpmnModel bpmnModel, List executedActivityIdList, List flowIds) { try { ProcessDiagramGenerator processDiagramGenerator = processEngine.getProcessEngineConfiguration().getProcessDiagramGenerator(); return processDiagramGenerator.generateDiagram(bpmnModel, "png", executedActivityIdList, flowIds, "宋体", "微软雅黑", "黑体", null, 2.0); //使用默认配置获得流程图表生成器,并生成追踪图片字符流 } catch (Exception e) { logger.error("an exception happens in try catch statement", e); return null; } } }