jilu

来源:互联网 发布:电脑视频录像软件 编辑:程序博客网 时间:2024/05/16 10:50
package com.ld.sys.workflow;


import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;


import org.activiti.bpmn.converter.BpmnXMLConverter;
import org.activiti.bpmn.model.BpmnModel;
import org.activiti.editor.constants.ModelDataJsonConstants;
import org.activiti.editor.language.json.converter.BpmnJsonConverter;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.apache.commons.lang3.StringUtils;


import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import com.jfinal.aop.Before;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.activerecord.tx.Tx;
import com.ld.core.plugin.activiti.ActivitiPlugin;
import com.ld.core.plugin.shiro.ShiroKit;
import com.ld.core.tool.Constant;


public class WorkFlowService {
public static final WorkFlowService me = new WorkFlowService();
/**
* 创建新模型
* @throws UnsupportedEncodingException 
* */
public void createModel(ProcessEngine pe,String name,String key) throws UnsupportedEncodingException{
RepositoryService repositoryService = pe.getRepositoryService();
        ObjectMapper objectMapper = new ObjectMapper();
        ObjectNode editorNode = objectMapper.createObjectNode();
        editorNode.put("id", "canvas");
        editorNode.put("resourceId", "canvas");
        ObjectNode stencilSetNode = objectMapper.createObjectNode();
        stencilSetNode.put("namespace", "http://b3mn.org/stencilset/bpmn2.0#");
        editorNode.put("stencilset", stencilSetNode);
        Model modelData = repositoryService.newModel();


        ObjectNode modelObjectNode = objectMapper.createObjectNode();
        modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, name);
        modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, 1);
        String description = StringUtils.defaultString("模型描述信息");
        modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, description);
        modelData.setMetaInfo(modelObjectNode.toString());
        modelData.setName(name);
        modelData.setKey(StringUtils.defaultString(key));


        repositoryService.saveModel(modelData);
        repositoryService.addModelEditorSource(modelData.getId(), editorNode.toString().getBytes("utf-8"));
}

/***
* 部署模型
* @param id
* @return
*/
@Before(Tx.class)
public String deploy(String id) {
String message = "";
try {
ProcessEngine pe = ActivitiPlugin.buildProcessEngine();
RepositoryService repositoryService = pe.getRepositoryService();
org.activiti.engine.repository.Model modelData = repositoryService.getModel(id);
BpmnJsonConverter jsonConverter = new BpmnJsonConverter();
JsonNode editorNode = new ObjectMapper().readTree(repositoryService.getModelEditorSource(modelData.getId()));
BpmnModel bpmnModel = jsonConverter.convertToBpmnModel(editorNode);
BpmnXMLConverter xmlConverter = new BpmnXMLConverter();
byte[] bpmnBytes = xmlConverter.convertToXML(bpmnModel,"ISO-8859-1");

String processName = modelData.getName();
if (!StringUtils.endsWith(processName, ".bpmn20.xml")){
processName += ".bpmn20.xml";
}
// System.out.println("========="+processName+"============"+modelData.getName());
ByteArrayInputStream in = new ByteArrayInputStream(bpmnBytes);
Deployment deployment = repositoryService.createDeployment().name(modelData.getName())
.addInputStream(processName, in).deploy();
// .addString(processName, new String(bpmnBytes)).deploy();

// 设置流程分类
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().deploymentId(deployment.getId()).list();
for (ProcessDefinition processDefinition : list) {
repositoryService.setProcessDefinitionCategory(processDefinition.getId(), modelData.getCategory());
message = "部署成功";
}
if (list.size() == 0){
message = "部署失败,没有流程。";
}
} catch (Exception e) {
throw new ActivitiException("设计模型图不正确,检查模型正确性", e);
}
return message;
}

/***
* 删除模型
*/
@Before(Tx.class)
public void deleteModel(String id){
ActivitiPlugin.buildProcessEngine().getRepositoryService().deleteModel(id);
}

/***
* 挂起/激活
*/
@Before(Tx.class)
public String updateState(String state,String procDefId){
if (state.equals("active")) {
ActivitiPlugin.buildProcessEngine().getRepositoryService().activateProcessDefinitionById(procDefId, true, null);
return "激活成功";
} else if (state.equals("suspend")) {
ActivitiPlugin.buildProcessEngine().getRepositoryService().suspendProcessDefinitionById(procDefId, true, null);
return "挂起成功";
}
return "无操作";
}

/***
* 转化为模型
*/
@Before(Tx.class)
public Model convertToModel(String procDefId) throws UnsupportedEncodingException, XMLStreamException {
RepositoryService repositoryService = ActivitiPlugin.buildProcessEngine().getRepositoryService();
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId).singleResult();
InputStream bpmnStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(),
processDefinition.getResourceName());
XMLInputFactory xif = XMLInputFactory.newInstance();
InputStreamReader in = new InputStreamReader(bpmnStream, "UTF-8");
XMLStreamReader xtr = xif.createXMLStreamReader(in);
BpmnModel bpmnModel = new BpmnXMLConverter().convertToBpmnModel(xtr);

BpmnJsonConverter converter = new BpmnJsonConverter();
ObjectNode modelNode = converter.convertToJson(bpmnModel);
org.activiti.engine.repository.Model modelData = repositoryService.newModel();
modelData.setKey(processDefinition.getKey());
modelData.setName(processDefinition.getName());
modelData.setCategory(processDefinition.getCategory());//.getDeploymentId());
modelData.setDeploymentId(processDefinition.getDeploymentId());
modelData.setVersion(Integer.parseInt(String.valueOf(repositoryService.createModelQuery().modelKey(modelData.getKey()).count()+1)));

ObjectNode modelObjectNode = new ObjectMapper().createObjectNode();
modelObjectNode.put(ModelDataJsonConstants.MODEL_NAME, processDefinition.getName());
modelObjectNode.put(ModelDataJsonConstants.MODEL_REVISION, modelData.getVersion());
modelObjectNode.put(ModelDataJsonConstants.MODEL_DESCRIPTION, processDefinition.getDescription());
modelData.setMetaInfo(modelObjectNode.toString());

repositoryService.saveModel(modelData);

repositoryService.addModelEditorSource(modelData.getId(), modelNode.toString().getBytes("utf-8"));

return modelData;
}

/**
* 读取资源,通过部署ID
* @param processDefinitionId  流程定义ID
* @param processInstanceId 流程实例ID
* @param resourceType 资源类型(xml|image)
*/
public InputStream resourceRead(String procDefId, String proInsId, String resType) throws Exception {
RuntimeService runtimeService = ActivitiPlugin.buildProcessEngine().getRuntimeService();
RepositoryService repositoryService = ActivitiPlugin.buildProcessEngine().getRepositoryService();
if (StringUtils.isBlank(procDefId)){
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(proInsId).singleResult();
procDefId = processInstance.getProcessDefinitionId();
}
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionId(procDefId).singleResult();

String resourceName = "";
if (resType.equals("image")) {
resourceName = processDefinition.getDiagramResourceName();
} else if (resType.equals("xml")) {
resourceName = processDefinition.getResourceName();
}

InputStream resourceAsStream = repositoryService.getResourceAsStream(processDefinition.getDeploymentId(), resourceName);
return resourceAsStream;
}
/***
* 删除正在运行的流程
*/
@Before(Tx.class)
public void deleteDeployment(String deploymentId) {
ActivitiPlugin.buildProcessEngine().getRepositoryService().deleteDeployment(deploymentId, true);
}

/***
* 启动流程
*/
@Before(Tx.class)
public String startProcess(String id,String defKey,Map<String, Object> var){
if(var==null){
var = new HashMap<String, Object>();
}
var.put(Constant.WORKFLOW_APPLY_USERNAME, ShiroKit.getUsername());
ProcessInstance procIns = ActivitiPlugin.buildProcessEngine().getRuntimeService().startProcessInstanceByKey(defKey,id,var);
return procIns.getId();
}


/***
* 查询流程待办任务
*/
public Record getTaskRecord(String id){
return Db.findFirst("SELECT * FROM v_tasklist t WHERE t.TASKID='"+id+"'");
}
/***
* 完成任务
*/
@Before(Tx.class)
public void completeTask(String taskid,Map<String,Object> var){
if(var!=null){
var = new HashMap<String,Object>();
}
ActivitiPlugin.buildProcessEngine().getTaskService().complete(taskid, var);
}
@Before(Tx.class)
public void completeTask(String taskid,String comment,Map<String,Object> var){
TaskService service = ActivitiPlugin.buildProcessEngine().getTaskService();
Record task = getTaskRecord(taskid);
String insid = task.getStr("INSID");
if(StrKit.notBlank(insid)&&StrKit.notBlank(comment)){
service.addComment(taskid, insid, comment);
}
if(var==null){
var = new HashMap<String,Object>();
}
service.complete(taskid, var);
}
/***
* 获取流转历史
*/
public List<Record> getHisTaskList(String insid){
return Db.find("SELECT t.assignee_,u.name,t.name_,t.end_time_,c.message_ FROMsys_user u ,act_hi_taskinst t LEFT JOIN act_hi_comment c ON t.id_ = c.task_id_ where t.end_time_ IS NOT NULL AND u.username=t.ASSIGNEE_ AND t.proc_inst_id_ = '"+insid+"' ");
}

/***
* 获取流程经办人数据
*/
public List<Record> getHisTaskParter(String insid){
return Db.find("select i.*,u.name from act_hi_identitylink i,sys_user u where u.username=i.USER_ID_ AND PROC_INST_ID_='"+insid+"'");
}

}






Util

package com.ld.sys.workflow;


import java.util.HashMap;
import java.util.List;
import java.util.Map;


import org.activiti.engine.HistoryService;
import org.activiti.engine.IdentityService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.identity.Group;
import org.activiti.engine.identity.User;
import org.apache.commons.codec.binary.StringUtils;


import com.ld.core.plugin.activiti.ActivitiPlugin;
import com.ld.sys.model.SysRole;
import com.ld.sys.model.SysUser;
import com.ld.sys.role.SysRoleService;
import com.ld.sys.user.SysUserService;
/**
 * 工作流,通用工具类, 使用工作流都通过该方法;
* @ClassName: WorkFlowUtils 
* @Description:  工作流,通用工具类, 使用工作流都通过该方法;
* @author zhangdd
* @date 2017年7月7日 
*
 */
public abstract class WorkFlowUtils {

private static SysRoleService roleService = new SysRoleService();

private static SysUserService userService = new SysUserService();

private static ProcessEngine processEngine = ActivitiPlugin.buildProcessEngine();


private static RuntimeService runtimeService = processEngine.getRuntimeService();


private static RepositoryService repositoryService = processEngine.getRepositoryService();


private static HistoryService historyService = processEngine.getHistoryService();


private static TaskService taskService = processEngine.getTaskService();


private static IdentityService identityService = processEngine.getIdentityService();

/**
* 工作流系统创建用户/更新用户, SysUser.username==工作流的user.id, SysUser.name==工作流的user.firstName;<br>
* 如果发现工作流系统没有该用户,就先创建用户,然后同步用户信息,然后保存<br>
* 查询用户所在的Group,检查当前系统用户的Role,并对比差异,主要进行关系的同步(即:memberShip)
* @param oldUser 旧数据,可以为null
* @param user  sys_user表已经保存好的用户
*/
public static void createOrUpdateUser(SysUser oldUser,SysUser user) {
if(oldUser!=null) {
if(!StringUtils.equals(oldUser.getUsername(), user.getUsername())) {
//说明改了 用户标示符;
deleteUser(oldUser);
}
}
User u =identityService.createUserQuery().userId(user.getUsername()).singleResult();
if(u==null) {
u = identityService.newUser(user.getUsername());
}
u.setEmail(user.getEmail());
u.setFirstName(user.getName());
u.setPassword(user.getPassword());
//更新/添加
identityService.saveUser(u);
//查询当前用户所拥有的角色(用户所在的组)
List<Group> groupList = identityService.createGroupQuery().groupMember(u.getId()).list();
Map<String,Group> groupMap = new HashMap<String,Group>();
for(Group g:groupList) {
groupMap.put(g.getId(), g);
}
List<SysRole> roles = roleService.getAllRoleByUserid(user.getId());
Map<String,SysRole> roleMap = new HashMap<String,SysRole>();
for(SysRole r:roles) {
String key = r.getKey();
roleMap.put(key, r);
if(!groupMap.containsKey(key)) {//没有联系就建立联系
Group g = identityService.createGroupQuery().groupId(key).singleResult();
if(g==null) {//如果要建立关系的group不存在,则新增group,虽然这种情况应该不会发生;
g = identityService.newGroup(key);
g.setName(r.getName());
identityService.saveGroup(g);
}
identityService.createMembership(u.getId(), key);
}
}
for(Group g:groupList) {
String id = g.getId();
if(!roleMap.containsKey(id)) {
//需要删除了
identityService.deleteMembership(u.getId(), id);
}
}
}

/**
* 当系统角色发生增删改时调用;<br>
* 将系统角色 同 工作流 的角色, 进行同步, 系统角色===工作流的Group, role.key==group.id, role.name==group.name;<br>
* @param oldRole 旧数据,可以为null
* @param role 新数据
*/
public static void createOrUpdateGroup(SysRole oldRole,SysRole role) {
if(oldRole!=null) {
if(!StringUtils.equals(oldRole.getKey(), role.getKey())) {
//说明改了 角色标示符;
deleteGroup(oldRole);
}
}
Group group = identityService.createGroupQuery().groupId(role.getKey()).singleResult();
if(group==null) {
group = identityService.newGroup(role.getKey());
}
group.setName(role.getName());
//更新/添加
identityService.saveGroup(group);
//查询当前组下面的所有用户
List<User> userList = identityService.createUserQuery().memberOfGroup(group.getId()).list();
Map<String,User> userMap = new HashMap<String,User>();
for(User u:userList) {
userMap.put(u.getId(), u);
}
List<SysUser> uList = userService.getAllUserByRoleId(role.getId());
Map<String,SysUser> uMap = new HashMap<String,SysUser>();
for(SysUser u:uList) {
String id = u.getUsername();
uMap.put(id, u);
if(!userMap.containsKey(id)) {
User user = identityService.createUserQuery().userId(id).singleResult();
if(user==null) {//如果要建立关系的user不存在,则新增user,虽然这种情况应该不会发生;
user = identityService.newUser(id);
user.setFirstName(u.getName());
user.setEmail(u.getEmail());
user.setPassword(u.getPassword());
identityService.saveUser(user);
}
identityService.createMembership(u.getId(), group.getId());
}
}
for(User user:userList) {
String id = user.getId();
if(!uMap.containsKey(id)) {
//需要删除了
identityService.deleteMembership(id,group.getId());
}
}
}

/**
* 删除 工作流 中的 用户, (不涉及系统用户表)
* @param user 系统用户;当系统用户被删除时,调用此方法;
*/
public static void deleteUser(SysUser user) {
User u = identityService.createUserQuery().userId(user.getUsername()).singleResult();
if(u!=null) {
List<Group> groups = identityService.createGroupQuery().groupMember(u.getId()).list();
for(Group g:groups) {
identityService.deleteMembership(u.getId(),g.getId());
}
identityService.deleteUser(u.getId());
}
}

/**
* 删除  工作流中的 group (不涉及系统角色表) , 
* @param role 系统角色; 当系统角色被删除时调用此方法;
*/
public static void deleteGroup(SysRole role) {
Group group = identityService.createGroupQuery().groupId(role.getKey()).singleResult();
if(group!=null) {
List<User> userList = identityService.createUserQuery().memberOfGroup(group.getId()).list();
for(User u:userList) {
identityService.deleteMembership(u.getId(), group.getId());
}
identityService.deleteGroup(group.getId());
}
}


}



ActivitiUtil

package com.rd.tcx.util;


import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;


import org.activiti.bpmn.model.BpmnModel;
import org.activiti.engine.HistoryService;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.PvmTransition;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.image.impl.DefaultProcessDiagramGenerator;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.FileCopyUtils;


public class ActiviUtil {


private static Logger logger = Logger.getLogger(ActiviUtil.class);


@Autowired
private static ProcessEngine processEngine = ProcessEngines
.getDefaultProcessEngine();


@Autowired
private static RuntimeService runtimeService = processEngine
.getRuntimeService();


@Autowired
private static RepositoryService repositoryService = processEngine
.getRepositoryService();


@Autowired
private static HistoryService historyService = processEngine
.getHistoryService();


@Autowired
private static TaskService taskService = processEngine.getTaskService();


/**
* 发布流程 用于将画好的流程相关存入数据库
*/
public static String deploy(String path, String key) {
logger.debug("开始发布流程");
Deployment deployment = repositoryService.createDeploymentQuery()
.processDefinitionKey(key).singleResult();
if (deployment != null) {
repositoryService.deleteDeployment(deployment.getId());
repositoryService.createDeployment().addClasspathResource(path)
.deploy();
} else {
repositoryService.createDeployment().addClasspathResource(path)
.deploy();
}
logger.debug(deployment + "流程发布成功");
return deployment.getId();
}


/**
* 创建流程实例
*/
public static String startInstanceByKey(String instanceByKey) {
logger.debug("启用流程实例");
ProcessInstance instance = runtimeService
.startProcessInstanceByKey(instanceByKey);
String id = instance.getId();
logger.debug("已返回流程实例instance,id为:" + id);
return id;
}


/**

* @param instanceByKey
* @return
*/
public static String startInstanceByKeys(String instanceByKey,
Map<String, Object> variables) {
logger.debug("启用流程实例");
ProcessInstance instance = runtimeService.startProcessInstanceByKey(
instanceByKey, variables);
String id = instance.getId();
logger.debug("已返回流程实例instance,id为:" + id);
return id;
}


/**
* 获取流程图并显示

* @return
* @throws Exception
*/
public static boolean findProcessPic(String processInstanceId,
String filepath) throws Exception {
ProcessInstance processInstance = runtimeService
.createProcessInstanceQuery()
.processInstanceId(processInstanceId).singleResult();
HistoricProcessInstance historicProcessInstance = historyService
.createHistoricProcessInstanceQuery()
.processInstanceId(processInstanceId).singleResult();
if (processInstance == null && historicProcessInstance == null) {
return false;
}


ProcessDefinitionEntity processDefinition = (ProcessDefinitionEntity) repositoryService
.getProcessDefinition(processInstance == null ? historicProcessInstance
.getProcessDefinitionId() : processInstance
.getProcessDefinitionId());


BpmnModel bpmnModel = repositoryService.getBpmnModel(processDefinition
.getId());


List<String> activeActivityIds = new ArrayList<String>();
if (processInstance != null) {
activeActivityIds = runtimeService
.getActiveActivityIds(processInstance
.getProcessInstanceId());
} else {
activeActivityIds.add(historyService
.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId)
.activityType("endEvent").singleResult().getActivityId());
}


Context.setProcessEngineConfiguration((ProcessEngineConfigurationImpl) processEngine
.getProcessEngineConfiguration());
List<String> highLightedFlows = getHighLightedFlows(processDefinition,
processInstanceId);
/** 增加了对中文乱码的处理 */
InputStream imageStream = new DefaultProcessDiagramGenerator()
.generateDiagram(bpmnModel, "png", activeActivityIds,
highLightedFlows, processEngine
.getProcessEngineConfiguration()
.getActivityFontName(), processEngine
.getProcessEngineConfiguration()
.getLabelFontName(), processEngine
.getProcessEngineConfiguration()
.getClassLoader(), 1.0);


FileOutputStream out = new FileOutputStream(filepath);
FileCopyUtils.copy(imageStream, out);
out.flush();
out.close();
imageStream.close();
return true;
}


/**
* 根据执行人查询任务

* @author juhz
* @return
*/
public static List<Task> findTaskByAssignee(String assignee) {
logger.debug("开始查看任务...");
return taskService.createTaskQuery().taskAssignee(assignee).list();
}


/**
* 根据执行人分页查询任务

* @author shenwb
* @return
*/
public static List<Task> findTaskByAssignee(String assignee, Pager pager) {
logger.debug("开始查看任务...");
Integer page = pager.getPage();
Integer rows = pager.getRows();
Integer start = (page - 1) * rows ;
Integer end = page * rows;
List<Task> list = taskService.createTaskQuery().taskAssignee(assignee).list();
if(list != null){
list = list.subList(start, end);
}
return list;
}


/**
* 查询组任务

* @param assignee
* @return
*/
public static List<Task> findCandidateUser(String candidateUser) {
logger.debug("开始查看组任务...");
return taskService.createTaskQuery().taskCandidateUser(candidateUser)
.list();
}


/**
* 每步执行过程中添加注释

* @param taskId
* @param processInstancesId
* @param comment
*/
public static void addComment(String taskId, String processInstancesId,
String comment) {
logger.debug("开始插入注释...");
Comment comments = taskService.addComment(taskId, processInstancesId,
comment);
}


public static Task findTaskByid(String taskId) {
logger.debug("开始查看任务...");
return taskService.createTaskQuery().taskId(taskId).singleResult();
}


/**
* 设置任务执行人

* @author juhz
* @return
*/
public static boolean setTaskAssignee(String userid, String taskid) {
logger.debug("开始设置任务执行人...");
TaskService taskService = processEngine.getTaskService();
taskService.setAssignee(taskid, userid);
return true;
}


/**
* 执行任务

* @author juhz
* @return
*/
public static void takeCompleteTask(String taskid) {
logger.debug("结束后续没有分支判断的任务...");
taskService.complete(taskid);
}


public static void takeCompleteTasks(String taskid,
Map<String, Object> variables) {
logger.debug("结束后续有分支判断的任务...");
taskService.complete(taskid, variables);
}


/**
* 查询所有任务
*/
public static List<Task> findAllTask() {
logger.debug("开始查询当前任务");
List<Task> taskList = taskService.createTaskQuery().list();
return taskList;
}


/**
* 任务签收

* @param taskId
* @param userId
*/
public static void claimTask(String taskId, String userId) {
logger.debug("签收当前任务");
taskService.claim(taskId, userId);
}


/**
* 查询流程任务
*/
public static List<Task> findTaskbyprocess(String processId) {
logger.debug("开始查询下一任务");
return taskService.createTaskQuery().processInstanceId(processId)
.list();
}


public static Task findTaskbyprocessId(String processId) {
logger.debug("开始查询下一任务");
return taskService.createTaskQuery().processInstanceId(processId)
.singleResult();
}


/**
* 查询流程历史任务
*/
public static List<HistoricTaskInstance> findhiTaskbyprocessId(
String processId) {
logger.debug("开始查询下一任务");
return historyService.createHistoricTaskInstanceQuery()
.processInstanceId(processId).list();
}




/**
* 历史任务查询

* @param userId
* @param pager
* @return
*/
public static List<HistoricTaskInstance> findhiTask() {
logger.debug("开始根据用户查询历史任务");
/**
* 先查出所有的历史流程中的参数,然后通过userID去匹配所有的参数,如果有一条记录
*/
return historyService.createHistoricTaskInstanceQuery().list();
}


/** 内部工具方法 **/
// private static List<String> getHighLightedFlows(ProcessDefinitionEntity
// processDefinition, String processInstanceId) {
// List<String> highLightedFlows = new ArrayList<String>();
// List<HistoricActivityInstance> historicActivityInstances = historyService
// .createHistoricActivityInstanceQuery()
// .processInstanceId(processInstanceId)
// .orderByHistoricActivityInstanceStartTime()/** 按创建时间排序,
// 不能按结束时间排序,否则会有连线丢失<按结束时间排序的话,如果流程没有结束,则流程的当前的活动节点永远是排在第一个或最后一个>*/
// .asc().list();
// LinkedList<HistoricActivityInstance> hisActInstList = new
// LinkedList<HistoricActivityInstance>();
// hisActInstList.addAll(historicActivityInstances);
// getHighlightedFlows(processDefinition.getActivities(),
// hisActInstList,highLightedFlows);
// return highLightedFlows;
// }
//
// private static void getHighlightedFlows(List<ActivityImpl>
// activityList,LinkedList<HistoricActivityInstance>
// hisActInstList,List<String> highLightedFlows) {
//
// List<ActivityImpl> startEventActList = new ArrayList<ActivityImpl>();
// Map<String, ActivityImpl> activityMap = new HashMap<String,
// ActivityImpl>(
// activityList.size());
// for (ActivityImpl activity : activityList) {
//
// activityMap.put(activity.getId(), activity);
//
// String actType = (String) activity.getProperty("type");
// if (actType != null
// && actType.toLowerCase().indexOf("startevent") >= 0) {
// startEventActList.add(activity);
// }
// }
//
//
// HistoricActivityInstance firstHistActInst = hisActInstList.getFirst();
// String firstActType = (String) firstHistActInst.getActivityType();
// if (firstActType != null
// && firstActType.toLowerCase().indexOf("startevent") < 0) {
// PvmTransition startTrans = getStartTransaction(startEventActList,
// firstHistActInst);
// if (startTrans != null) {
// highLightedFlows.add(startTrans.getId());
// }
// }
//
// while (!hisActInstList.isEmpty()) {
// HistoricActivityInstance histActInst = hisActInstList.removeFirst();
// ActivityImpl activity = activityMap
// .get(histActInst.getActivityId());
// if (activity != null) {
// boolean isParallel = false;
// String type = histActInst.getActivityType();
// if ("parallelGateway".equals(type)
// || "inclusiveGateway".equals(type)) {
// isParallel = true;
// } else if ("subProcess".equals(histActInst.getActivityType())) {
// getHighlightedFlows(activity.getActivities(),
// hisActInstList, highLightedFlows);
// }
//
// List<PvmTransition> allOutgoingTrans = new ArrayList<PvmTransition>();
// allOutgoingTrans.addAll(activity.getOutgoingTransitions());
// allOutgoingTrans
// .addAll(getBoundaryEventOutgoingTransitions(activity));
// List<String> activityHighLightedFlowIds = getHighlightedFlows(
// allOutgoingTrans, hisActInstList, isParallel);
// highLightedFlows.addAll(activityHighLightedFlowIds);
// }
// }
// }
// private static PvmTransition getStartTransaction(List<ActivityImpl>
// startEventActList,HistoricActivityInstance firstActInst) {
// for (ActivityImpl startEventAct : startEventActList) {
// for (PvmTransition trans : startEventAct.getOutgoingTransitions()) {
// if (trans.getDestination().getId()
// .equals(firstActInst.getActivityId())) {
// return trans;
// }
// }
// }
// return null;
// }
// private static List<PvmTransition>
// getBoundaryEventOutgoingTransitions(ActivityImpl activity) {
// List<PvmTransition> boundaryTrans = new ArrayList<PvmTransition>();
// for (ActivityImpl subActivity : activity.getActivities()) {
// String type = (String) subActivity.getProperty("type");
// if (type != null && type.toLowerCase().indexOf("boundary") >= 0) {
// boundaryTrans.addAll(subActivity.getOutgoingTransitions());
// }
// }
// return boundaryTrans;
// }
//
// private static List<String> getHighlightedFlows(List<PvmTransition>
// pvmTransitionList,LinkedList<HistoricActivityInstance>
// hisActInstList,boolean isParallel) {
//
// List<String> highLightedFlowIds = new ArrayList<String>();
//
// PvmTransition earliestTrans = null;
// HistoricActivityInstance earliestHisActInst = null;
// for (PvmTransition pvmTransition : pvmTransitionList) {
// String destActId = pvmTransition.getDestination().getId();
// HistoricActivityInstance destHisActInst = findHisActInst(
// hisActInstList, destActId);
//
// if (destHisActInst != null) {
// if (isParallel) {
// highLightedFlowIds.add(pvmTransition.getId());
// } else if (destHisActInst.getActivityId().equals(
// hisActInstList.get(0).getActivityId())) {
// /** 解决互斥网关默认只显示一条流程连线问题,此处用互斥网关流出连线的目标活动节点与历史活动节点的第一个节点判断,取出它们之间的连线*/
// earliestTrans = pvmTransition;
// earliestHisActInst = destHisActInst;
// }
// }
// }
//
// if ((!isParallel) && earliestTrans != null) {
// highLightedFlowIds.add(earliestTrans.getId());
// }
// return highLightedFlowIds;
// }
//
// private static HistoricActivityInstance
// findHisActInst(LinkedList<HistoricActivityInstance> hisActInstList,
// String actId) {
// for (HistoricActivityInstance hisActInst : hisActInstList) {
// if (hisActInst.getActivityId().equals(actId)) {
// return hisActInst;
// }
// }
// return null;
// }
private static List<String> getHighLightedFlows(
ProcessDefinitionEntity processDefinition, String processInstanceId) {


List<String> highLightedFlows = new ArrayList<String>();


// List<HistoricActivityInstance> historicActivityInstances =
// historyService.createHistoricActivityInstanceQuery()
// .processInstanceId(processInstanceId)
// //order by startime asc is not correct. use default order is correct.
// //.orderByHistoricActivityInstanceStartTime().asc()/*.orderByActivityId().asc()*/
// .list();
// 上面注释掉的代码是官方的rest方法中提供的方案,可是我在实际测试中有Bug出现,所以做了一下修改。注意下面List内容的排序会影响流程走向红线丢失的问题
List<HistoricActivityInstance> historicActivityInstances = historyService
.createHistoricActivityInstanceQuery()
.processInstanceId(processInstanceId)
.orderByHistoricActivityInstanceStartTime()
.orderByHistoricActivityInstanceEndTime().asc().list();
LinkedList<HistoricActivityInstance> hisActInstList = new LinkedList<HistoricActivityInstance>();
hisActInstList.addAll(historicActivityInstances);


getHighlightedFlows(processDefinition.getActivities(), hisActInstList,
highLightedFlows);


return highLightedFlows;
}


/**
* getHighlightedFlows
* <p/>
* code logic: 1. Loop all activities by id asc order; 2. Check each
* activity's outgoing transitions and eventBoundery outgoing transitions,
* if outgoing transitions's destination.id is in other executed
* activityIds, add this transition to highLightedFlows List; 3. But if
* activity is not a parallelGateway or inclusiveGateway, only choose the
* earliest flow.

* @param activityList
* @param hisActInstList
* @param highLightedFlows
*/
private static void getHighlightedFlows(List<ActivityImpl> activityList,
LinkedList<HistoricActivityInstance> hisActInstList,
List<String> highLightedFlows) {


// check out startEvents in activityList
List<ActivityImpl> startEventActList = new ArrayList<ActivityImpl>();
Map<String, ActivityImpl> activityMap = new HashMap<String, ActivityImpl>(
activityList.size());
for (ActivityImpl activity : activityList) {


activityMap.put(activity.getId(), activity);


String actType = (String) activity.getProperty("type");
if (actType != null
&& actType.toLowerCase().indexOf("startevent") >= 0) {
startEventActList.add(activity);
}
}


// These codes is used to avoid a bug:
// ACT-1728 If the process instance was started by a callActivity, it
// will be not have the startEvent activity in ACT_HI_ACTINST table
// Code logic:
// Check the first activity if it is a startEvent, if not check out the
// startEvent's highlight outgoing flow.
HistoricActivityInstance firstHistActInst = hisActInstList.getFirst();
String firstActType = (String) firstHistActInst.getActivityType();
if (firstActType != null
&& firstActType.toLowerCase().indexOf("startevent") < 0) {
PvmTransition startTrans = getStartTransaction(startEventActList,
firstHistActInst);
if (startTrans != null) {
highLightedFlows.add(startTrans.getId());
}
}


while (!hisActInstList.isEmpty()) {
HistoricActivityInstance histActInst = hisActInstList.removeFirst();
ActivityImpl activity = activityMap
.get(histActInst.getActivityId());
if (activity != null) {
boolean isParallel = false;
String type = histActInst.getActivityType();
if ("parallelGateway".equals(type)
|| "inclusiveGateway".equals(type)) {
isParallel = true;
} else if ("subProcess".equals(histActInst.getActivityType())) {
getHighlightedFlows(activity.getActivities(),
hisActInstList, highLightedFlows);
}


List<PvmTransition> allOutgoingTrans = new ArrayList<PvmTransition>();
allOutgoingTrans.addAll(activity.getOutgoingTransitions());
allOutgoingTrans
.addAll(getBoundaryEventOutgoingTransitions(activity));
List<String> activityHighLightedFlowIds = getHighlightedFlows(
allOutgoingTrans, hisActInstList, isParallel);
highLightedFlows.addAll(activityHighLightedFlowIds);
}
}
}


/**
* Check out the outgoing transition connected to firstActInst from
* startEventActList

* @param startEventActList
* @param firstActInst
* @return
*/
private static PvmTransition getStartTransaction(
List<ActivityImpl> startEventActList,
HistoricActivityInstance firstActInst) {
for (ActivityImpl startEventAct : startEventActList) {
for (PvmTransition trans : startEventAct.getOutgoingTransitions()) {
if (trans.getDestination().getId()
.equals(firstActInst.getActivityId())) {
return trans;
}
}
}
return null;
}


/**
* getBoundaryEventOutgoingTransitions

* @param activity
* @return
*/
private static List<PvmTransition> getBoundaryEventOutgoingTransitions(
ActivityImpl activity) {
List<PvmTransition> boundaryTrans = new ArrayList<PvmTransition>();
for (ActivityImpl subActivity : activity.getActivities()) {
String type = (String) subActivity.getProperty("type");
if (type != null && type.toLowerCase().indexOf("boundary") >= 0) {
boundaryTrans.addAll(subActivity.getOutgoingTransitions());
}
}
return boundaryTrans;
}


/**
* find out single activity's highlighted flowIds

* @param pvmTransitionList
* @param hisActInstList
* @param isParallel
* @return
*/
private static List<String> getHighlightedFlows(
List<PvmTransition> pvmTransitionList,
LinkedList<HistoricActivityInstance> hisActInstList,
boolean isParallel) {


List<String> highLightedFlowIds = new ArrayList<String>();


PvmTransition earliestTrans = null;
HistoricActivityInstance earliestHisActInst = null;


for (PvmTransition pvmTransition : pvmTransitionList) {


String destActId = pvmTransition.getDestination().getId();
HistoricActivityInstance destHisActInst = findHisActInst(
hisActInstList, destActId);
if (destHisActInst != null) {
if (isParallel) {
highLightedFlowIds.add(pvmTransition.getId());
} else if (earliestHisActInst == null
|| (earliestHisActInst.getId().compareTo(
destHisActInst.getId()) > 0)) {
earliestTrans = pvmTransition;
earliestHisActInst = destHisActInst;
}
}
}


if ((!isParallel) && earliestTrans != null) {
highLightedFlowIds.add(earliestTrans.getId());
}


return highLightedFlowIds;
}


private static HistoricActivityInstance findHisActInst(
LinkedList<HistoricActivityInstance> hisActInstList, String actId) {
for (HistoricActivityInstance hisActInst : hisActInstList) {
if (hisActInst.getActivityId().equals(actId)) {
return hisActInst;
}
}
return null;
}
}





Plugin

package com.ld.core.plugin.activiti;


import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration;


import com.jfinal.plugin.IPlugin;
import com.jfinal.plugin.activerecord.DbKit;


/**
 * @author Lion
 * @date 2017年1月24日 下午12:02:35
 * @qq 439635374
 */
public class ActivitiPlugin implements IPlugin{


private static ProcessEngine processEngine = null;
private static ProcessEngineConfiguration processEngineConfiguration = null;
private boolean isStarted = false;
@Override
public boolean start(){
try {
createProcessEngine();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}


@Override
public boolean stop() {
ProcessEngines.destroy(); 
isStarted = false;
return true;
}


private Boolean createProcessEngine() throws Exception{
if (isStarted) {
return true;
}
StandaloneProcessEngineConfiguration conf = (StandaloneProcessEngineConfiguration) ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
conf.setDataSource(DbKit.getConfig().getDataSource());
conf.setEnableDatabaseEventLogging(false);
conf.setDatabaseSchemaUpdate(ProcessEngineConfigurationImpl.DB_SCHEMA_UPDATE_TRUE);//更新
// conf.setDatabaseSchemaUpdate(ProcessEngineConfigurationImpl.DB_SCHEMA_UPDATE_DROP_CREATE);//重置数据库!!!调试用!!!请勿打开!!!
conf.setDbHistoryUsed(true);
conf.setTransactionsExternallyManaged(true);//使用托管事务工厂
conf.setTransactionFactory(new ActivitiTransactionFactory());
UuidGenerator uuidG = new UuidGenerator();
conf.setIdGenerator(uuidG);
conf.setActivityFontName("宋体");
conf.setLabelFontName("宋体");
conf.setAnnotationFontName("宋体");

ActivitiPlugin.processEngine = conf.buildProcessEngine();
isStarted = true;
//开启流程引擎
System.out.println("启动流程引擎.......");
return isStarted;
}


// 开启流程服务引擎
public static ProcessEngine buildProcessEngine() {
if (processEngine == null)
if (processEngineConfiguration != null) {
processEngine = processEngineConfiguration.buildProcessEngine();
}
return processEngine;
}

}

原创粉丝点击