300 lines
11 KiB
Java
300 lines
11 KiB
Java
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<Record> 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<String, Object> map = new HashMap<>();
|
||
map.put(ActConstant.PROC_INS_ID, procInsId);
|
||
map.put(ActConstant.PROC_DEF_KEY, actTaskDef.getProcDefKey());
|
||
List<Record> 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<String> executedActivityIdList, List<String> 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("<xmp>".getBytes()), response.getOutputStream());
|
||
IoUtil.copy(inputStream, response.getOutputStream());
|
||
IoUtil.copy(new ByteArrayInputStream("</xmp>".getBytes()), response.getOutputStream());
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 查询任务审批人
|
||
*
|
||
* @param taskId
|
||
* @return
|
||
*/
|
||
public String getAssigneeByIdentityLink(String taskId) {
|
||
List<IdentityLink> 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<String> getAssignUserList(String taskId) {
|
||
List<String> userList = new ArrayList<>();
|
||
List<IdentityLink> 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<String> executedActivityIdList, List<String> 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;
|
||
}
|
||
}
|
||
|
||
|
||
}
|