fourcal/src/main/java/cn/palmte/work/service/ActTaskDefService.java

241 lines
9.3 KiB
Java
Raw Normal View History

2021-11-09 07:26:08 +00:00
package cn.palmte.work.service;
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.model.ActTaskDefRepository;
import cn.palmte.work.utils.InterfaceUtil;
import com.alibaba.fastjson.JSONObject;
import org.activiti.bpmn.model.FlowNode;
import org.activiti.engine.*;
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.context.ApplicationContext;
import org.springframework.stereotype.Service;
import top.jfunc.common.db.bean.Record;
import javax.annotation.Resource;
import java.lang.reflect.Method;
import java.util.*;
@Service
public class ActTaskDefService {
private static final Logger logger = LoggerFactory.getLogger(ActTaskDefService.class);
@Autowired
private RepositoryService repositoryService; //管理流程定义 与流程定义和部署对象相关的Service
@Autowired
private ProcessEngine processEngine; //流程引擎对象
@Autowired
private RuntimeService runtimeService; //与正在执行的流程实例和执行对象相关的Service(执行管理,包括启动、推进、删除流程实例等操作)
@Autowired
private TaskService taskService; //任务管理 与正在执行的任务管理相关的Service
@Autowired
private ActTaskDefRepository actTaskDefRepository;
@Autowired
private AccountService accountService;
@Autowired
private ActProcInsService actProcInsService;
@Resource
private ApplicationContext applicationContext;
@Autowired
private ActScriptRepository actScriptRepository;
public List<ActTaskDef> findByProcDefId(String procDefId) {
List<ActTaskDef> list = actTaskDefRepository.findByProcDefId(procDefId);
for (ActTaskDef actTaskDef : list) {
ids2List(actTaskDef);
}
return list;
}
public ActTaskDef findFirstByProcDefIdAndTaskKey(String procDefId, String taskKey) {
ActTaskDef def = actTaskDefRepository.findFirstByProcDefIdAndTaskKey(procDefId, taskKey);
ids2List(def);
return def;
}
public void saveConfig(ActTaskDef taskDef) {
ActTaskDef one = actTaskDefRepository.findOne(taskDef.getId());
one.setCandidateUsers(taskDef.getCandidateUsers());
one.setCandidateRoles(taskDef.getCandidateRoles());
one.setRollbackTaskKey(taskDef.getRollbackTaskKey());
one.setEndScript(taskDef.getEndScript());
one.setRollbackScript(taskDef.getRollbackScript());
one.setLastUpdatedTime(new Date());
actTaskDefRepository.save(one);
logger.info("saveTaskConfig uerId:{}, config:{}", InterfaceUtil.getAdminId(), JSONObject.toJSONString(one));
}
private void ids2List(ActTaskDef actTaskDef) {
String candidateUsers = actTaskDef.getCandidateUsers();
List<String> userIdList = new ArrayList<>();
if (StringUtils.isNotBlank(candidateUsers)) {
userIdList = Arrays.asList(candidateUsers.split("#"));
}
actTaskDef.setCandidateUserList(userIdList);
String candidateRoles = actTaskDef.getCandidateRoles();
List<String> roleIdList = new ArrayList<>();
if (StringUtils.isNotBlank(candidateRoles)) {
roleIdList = Arrays.asList(candidateRoles.split("#"));
}
actTaskDef.setCandidateRoleList(roleIdList);
}
public Set<String> findCandidateUsers(String procDefId, String procInsId, String taskDefKey) {
ActTaskDef taskDef = findFirstByProcDefIdAndTaskKey(procDefId, taskDefKey);
if (taskDef.getTaskIndex() == ActConstant.TASK_INDEX_FIRST_USER_TASK) {
String startUserId = actProcInsService.getStartUserId(procInsId);
Set<String> res = new HashSet<>(1);
logger.info("findCandidateUsers-0-task:{}, startUserId:{}", taskDef.getTaskName(), startUserId);
res.add(startUserId);
return res;
}
List<String> resList = new ArrayList<>();
List<String> candidateUserList = taskDef.getCandidateUserList();
logger.info("findCandidateUsers-1-task:{}, userList:{}", taskDef.getTaskName(), candidateUserList);
if (!candidateUserList.isEmpty()) {
resList.addAll(candidateUserList);
}
List<String> candidateRoleList = taskDef.getCandidateRoleList();
logger.info("findCandidateUsers-2-task:{}, roleList:{}", taskDef.getTaskName(), candidateRoleList);
List<String> list = accountService.getUserIsByRole(candidateRoleList);
logger.info("findCandidateUsers-3-task:{}, userIdListByRole:{}", taskDef.getTaskName(), list);
if (!list.isEmpty()) {
resList.addAll(list);
}
Set<String> res = new HashSet<>(resList);
logger.info("findCandidateUsers-4-task:{}, resIds:{}", taskDef.getTaskName(), res);
return res;
}
/**
*
* @param json
*/
public void completeTask(JSONObject json) {
String taskId = json.getString("taskId");
String procInstId = json.getString("procInsId");
String message = json.getString("message");
int type = json.getInteger("type");
taskService.addComment(taskId, procInstId, message);
Task currentTask = taskService.createTaskQuery().taskId(taskId).singleResult();
ActTaskDef actTaskDef = findFirstByProcDefIdAndTaskKey(currentTask.getProcessDefinitionId(), currentTask.getTaskDefinitionKey());
if (ActConstant.TYPE_APPROVE == type) {
//审批通过
taskService.complete(taskId);
//执行配置的审批通过脚本
int endScript = actTaskDef.getEndScript();
if (endScript != 0) {
invokeEventScript(endScript, procInstId);
} else {
logger.info("未配置审批通过脚本 task:{}", actTaskDef.getTaskName());
}
} else if (ActConstant.TYPE_ROLLBACK == type) {
//驳回
String rollbackTaskKey = actTaskDef.getRollbackTaskKey();
jumpToTargetTask(taskId, rollbackTaskKey);
//执行配置的驳回脚本
int rollbackScript = actTaskDef.getRollbackScript();
if (rollbackScript != 0) {
invokeEventScript(rollbackScript, procInstId);
} else {
logger.info("未配置驳回脚本 task:{}", actTaskDef.getTaskName());
}
}
}
/**
*
*
* @param scriptId
* @param procInsId
*/
private void invokeEventScript(int scriptId, String procInsId) {
ActScript actScript = actScriptRepository.findOne(scriptId);
if (actScript == null) {
logger.info("脚本配置错误");
return;
}
Map<String, Object> map = new HashMap<>();
map.put(ActConstant.PROC_INS_ID, procInsId);
List<Record> variables = actProcInsService.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);
}
}