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

308 lines
13 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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.*;
import cn.palmte.work.pojo.ActHisTask;
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.IdentityLink;
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.data.jpa.repository.Modifying;
import org.springframework.stereotype.Service;
import top.jfunc.common.db.QueryHelper;
import top.jfunc.common.db.bean.Record;
import top.jfunc.common.db.utils.Pagination;
import javax.annotation.Resource;
import javax.persistence.EntityManager;
import javax.transaction.Transactional;
import java.lang.reflect.Method;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@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;
@Autowired
Pagination pagination;
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 procInsId = json.getString("procInsId");
String message = json.getString("message");
int type = json.getInteger("type");
String userId = InterfaceUtil.getAdminId() + "";
taskService.addComment(taskId, procInsId, message);
actTaskDefRepository.updateHiTaskAssign(userId, procInsId, taskId);
actTaskDefRepository.updateHiActAssign(userId, procInsId, taskId);
Task currentTask = taskService.createTaskQuery().taskId(taskId).singleResult();
ActTaskDef actTaskDef = findFirstByProcDefIdAndTaskKey(currentTask.getProcessDefinitionId(), currentTask.getTaskDefinitionKey());
if (ActConstant.TYPE_APPROVE == type) {
taskService.setAssignee(taskId, userId);
//审批通过
taskService.complete(taskId);
//执行配置的审批通过脚本
int endScript = actTaskDef.getEndScript();
if (endScript != 0) {
invokeEventScript(endScript, procInsId);
} 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, procInsId);
} 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);
}
public List<ActHisTask> hisTaskList(String procIncId) {
String select = "select ht.ID_ as hisInstanceId, ht.PROC_DEF_ID_ as procDefinitionId, ht.PROC_INST_ID_ as procInstanceId, ht.EXECUTION_ID_ as executionId," +
" ht.ACT_ID_ as actId, ht.TASK_ID_ as taskId, ht.CALL_PROC_INST_ID_ as callProcInstanceId, ht.ACT_NAME_ as actName, " +
"ht.ACT_TYPE_ as actType, ht.ASSIGNEE_ as assignee, ht.START_TIME_ as startTime, ht.END_TIME_ as endTime, " +
"ht.DURATION_ as duration, ht.DELETE_REASON_ as deleteReason, ht.TENANT_ID_ as tenantId, hc.MESSAGE_ AS comments";
QueryHelper queryHelper = new QueryHelper(select, " ACT_HI_ACTINST ht " +
" LEFT JOIN ACT_HI_COMMENT hc on ht.TASK_ID_ = hc.TASK_ID_ and hc.type_='comment' ");
queryHelper.addCondition("ht.TASK_ID_ is not null");
queryHelper.addCondition("ht.PROC_INST_ID_ =?", procIncId);
queryHelper.addOrderProperty("ht.start_time_", true);
List<ActHisTask> taskList = pagination.find(queryHelper.getSql(), ActHisTask.class);
for (ActHisTask actHisTask : taskList) {
if (StringUtils.isBlank(actHisTask.getAssign())) {
Task task = taskService.createTaskQuery().taskId(actHisTask.getTaskId()).singleResult();
if (task != null) {
if (StringUtils.isNotBlank(task.getAssignee())) {
actHisTask.setAssign(task.getAssignee());
} else {
List<IdentityLink> identityLinkList = taskService.getIdentityLinksForTask(task.getId());
if (identityLinkList != null && !identityLinkList.isEmpty()) {
String name = "";
for (IdentityLink identityLink : identityLinkList) {
if ("assignee".equals(identityLink.getType()) || "candidate".equals(identityLink.getType())) {
String assigneeUserId = identityLink.getUserId();
if (StringUtils.isNotBlank(name)) {
name = name + ",";
}
name += accountService.getNameById(Integer.parseInt(assigneeUserId));
}
}
actHisTask.setAssign(name);
}
}
}
}
String duration = actHisTask.getDuration();
/*Date startTime = actHisTask.getStartTime();
Date endTime = actHisTask.getEndTime();*/
if (StringUtils.isNotBlank(duration)) {
Long ztime = Long.parseLong(duration);
Long day = ztime / (1000 * 60 * 60 * 24);
Long hour = (ztime % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60);
Long minute = (ztime % (1000 * 60 * 60 * 24)) % (1000 * 60 * 60) / (1000 * 60);
Long second = (ztime % (1000 * 60 * 60 * 24)) % (1000 * 60 * 60) % (1000 * 60) / 1000;
actHisTask.setDuration(day + "天" + hour + "时" + minute + "分" + second + "秒");
} else {
actHisTask.setDuration("正在处理。。。");
}
}
return taskList;
}
}