Activiti学习总结

1.获得流程图乱码问题

修改源码
org.activiti.engine.impl.bpmn.diagram.ProcessDiagramCanvas

在构造方法
public ProcessDiagramCanvas(int width, int height)


中有一行代码是设置字体的,默认是用Arial字体,这就是乱码产生的原因,把字改为本地的中文字体即可,例如:

Font font = new Font("WenQuanYi Micro Hei", Font.BOLD, 11);


从5.12版本开始支持设置字体名称,在引擎中添加如下设置,在生成图片时即可使用微软雅黑设置图片中的文字。

<property name="activityFontName" value="微软雅黑"></property>


2.业务和流程的关联方式

runtimeService.startProcessInstanceByKey
javadoc对其说明:

startProcessInstanceByKey(String processDefinitionKey, Map variables) 
          Starts a new process instance in the latest version of the process definition with the given key


其中businessKey就是业务ID,例如要申请请假,那么先填写登记信息,然后(保存+启动流程),因为请假是单独设计的数据表,所以保存后得到实体ID就可以把它传给processInstanceBusinessKey方法启动流程。当需要根据businessKey查询流程的时候就可以通过API查询:

runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(processInstanceBusinessKey, processDefinitionKey)


建议数据库冗余设计:在业务表设计的时候添加一列:PROCESS_INSTANCE_ID varchar2(64),在流程启动之后把流程ID更新到业务表中,这样不管从业务还是流程都可以查询到对方!

特别说明: 此方法启动时自动选择最新版本的流程定义。

runtimeService.startProcessInstanceById

javadoc对其说明:

startProcessInstanceById(String processDefinitionId, String businessKey, Map variables) 
          Starts a new process instance in the exactly specified version of the process definition with the given id.


processDefinitionId:这个参数的值可以通过repositoryService.createProcessDefinitionQuery()方法查询,对应数据库:ACT_RE_PROCDEF;每次部署一次流程定义就会添加一条数据,同名的版本号累加。

特别说明: 此可以指定不同版本的流程定义,让用户多一层选择。

建议使用 startProcessInstanceByKey,特殊情况需要使用以往的版本选择使用startProcessInstanceById。

3.各种状态的任务查询以及和业务对象关联

我们目前分为4中状态:未签收、办理中、运行中、已完成。

3.1未签收(Task)
此类任务针对于把Task分配给一个角色时,例如部门领导,因为部门领导角色可以指定多个人所以需要先签收再办理,术语:抢占式

对应的API查询:

/**
 * 获取未签收的任务查询对象
 * @param userId    用户ID
 */
@Transactional(readOnly = true)
public TaskQuery createUnsignedTaskQuery(String userId) {
    TaskQuery taskCandidateUserQuery = taskService.createTaskQuery().processDefinitionKey(getProcessDefKey())
            .taskCandidateUser(userId);
    return taskCandidateUserQuery;
}


3.2 办理中(Task)

此类任务数据类源有两种:

签收后的,5.1中签收后就应该为办理中状态

节点指定的是具体到一个人,而不是角色

对应的API查询:

/**
 * 获取正在处理的任务查询对象
 * @param userId    用户ID
 */
@Transactional(readOnly = true)
public TaskQuery createTodoTaskQuery(String userId) {
    TaskQuery taskAssigneeQuery = taskService.createTaskQuery().processDefinitionKey(getProcessDefKey()).taskAssignee(userId);
    return taskAssigneeQuery;
}


3.3 运行中(ProcessInstance)

说白了就是没有结束的流程,所有参与过的人都应该可以看到这个实例,但是Activiti的API没有可以通过用户查询的方法,这个只能自己用hack的方式处理了,我目前还没有处理。

从表ACT_RU_EXECUTION中查询数据。

对应的API查询:

/**
 * 获取未经完成的流程实例查询对象
 * @param userId    用户ID
 */
@Transactional(readOnly = true)
public ProcessInstanceQuery createUnFinishedProcessInstanceQuery(String userId) {
    ProcessInstanceQuery unfinishedQuery = runtimeService.createProcessInstanceQuery().processDefinitionKey(getProcessDefKey())
            .active();
    return unfinishedQuery;
}


3.4 已完成(HistoricProcessInstance)

已经结束的流程实例。

从表ACT_HI_PROCINST中查询数据。

/**
 * 获取已经完成的流程实例查询对象
 * @param userId    用户ID
 */
@Transactional(readOnly = true)
public HistoricProcessInstanceQuery createFinishedProcessInstanceQuery(String userId) {
    HistoricProcessInstanceQuery finishedQuery = historyService.createHistoricProcessInstanceQuery()
            .processDefinitionKey(getProcessDefKey()).finished();
    return finishedQuery;
}


4.任务委派

activiti默认是不带有选人的功能的,它默认的是在调用complete 方法的时候自动根据下一个节点的 assignee属性或者candidate属性 设置下一节点的候选人或者 assginee。

package org.activiti.designer.test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;

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

import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.DelegationState;
import org.activiti.engine.task.Task;
import org.activiti.engine.test.ActivitiRule;
import org.activiti.engine.test.Deployment;
import org.junit.Rule;
import org.junit.Test;

/**
 * 任务委派
 * 
 * @author henryyan
 */
public class ProcessTestDelegateTask {

	@Rule
	public ActivitiRule activitiRule = new ActivitiRule();

	@Test
	@Deployment(resources = { "diagrams/AutoAssignee.bpmn" })
	public void startProcess() throws Exception {
		RuntimeService runtimeService = activitiRule.getRuntimeService();
		Map<String, Object> variableMap = new HashMap<String, Object>();
		variableMap.put("name", "Activiti");
		ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("AutoAssignee", variableMap);
		assertNotNull(processInstance.getId());
		System.out.println("id " + processInstance.getId() + " " + processInstance.getProcessDefinitionId());

		TaskService taskService = activitiRule.getTaskService();

		Task task = taskService.createTaskQuery().singleResult();
		assertNull(task.getAssignee());

		// 签收
		taskService.claim(task.getId(), "user1");
		task = taskService.createTaskQuery().singleResult();
		assertNotNull(task.getAssignee());

		// 委派
		taskService.delegateTask(task.getId(), "henryyan");

		// 查询被委派的任务
		task = taskService.createTaskQuery().taskAssignee("henryyan").taskDelegationState(DelegationState.PENDING).singleResult();
		assertNotNull(task);

		// 被委派人完成任务
		taskService.resolveTask(task.getId());

		// 查询已完成的委派任务
		task = taskService.createTaskQuery().taskDelegationState(DelegationState.RESOLVED).singleResult();
		assertNotNull(task);
		assertEquals("user1", task.getAssignee());
		assertEquals("user1", task.getOwner());
		//		taskService.complete(task.getId(), Collections.singletonMap("taskTwoAssignee", "user2"));
	}
}


同样也可以用TaskListener来实现

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.TaskListener;
import org.apache.ibatis.annotations.Delete;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TaskUserQuery implements TaskListener{

	
	  /**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private static Logger logger = LoggerFactory.getLogger(TaskUserQuery.class);

	protected DataSource dataSource;

	
	
	private org.activiti.engine.impl.el.FixedValue orgLevel ;
	private org.activiti.engine.impl.el.FixedValue dutyNo ;
	public DataSource getDataSource() {
		return dataSource;
	}
	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
	}
	/**
	 * 审批过程中找人的方法
	 * @param str 组名
	 * @return
	 * @throws SQLException
	 */
	public String getTaskUser(String str) throws SQLException {
		logger.debug("-------------------自定义找人----------------------------getTaskUser");
		
		Connection conn = dataSource.getConnection();
		
		Statement state = conn.createStatement();
		String queryTaskUserSql = "select id_ from act_id_user aiu where exists (select 1 from act_id_membership aim where aim.user_id_ = aiu.id_ and  aim.group_id_='"+str+"' )";
		
		ResultSet rs = state.executeQuery(queryTaskUserSql);
		rs.next();
		logger.debug("-------------------自定义找人----------------------------:返回的人是"+rs.getString(1));
		
		conn.close();
		state.close();
		return rs.getString(1);
		
	} 
	
	public List<String> getTaskUserList(String str) throws SQLException {
		logger.debug("-------------------自定义找人----------------------------getTaskUserList");
		List<String> taskUser = new ArrayList<String>();
		
		Connection conn = dataSource.getConnection();
		
		Statement state = conn.createStatement();
		String queryTaskUserSql = "select id_ from act_id_user aiu where exists (select 1 from act_id_membership aim where aim.user_id_ = aiu.id_ and  aim.group_id_='"+str+"' )";
		
		ResultSet rs = state.executeQuery(queryTaskUserSql);
		while(rs.next()) {
			taskUser.add(rs.getString(1));
		}
		logger.debug("------------------- 自定义找人----------------------------:返回的人是"+taskUser.toString());
		
		conn.close();
		state.close();
		return taskUser;
		
	} 
	@Override
	public void notify(DelegateTask delegateTask) {
		
		
		Map<String,Object> map = delegateTask.getVariables();
		String taskId = delegateTask.getId();
		
		System.out.println("in taskUserQuer class variable is:"+map.toString());
		System.out.println("in taskUserQuer class taskid is:"+taskId);
		System.out.println("in taskUserQuer class orgLevel is:"+orgLevel.getExpressionText());
		
		
		
		String id = delegateTask.getId();
		String s = delegateTask.getAssignee();
		//根据流程变量的内容设置下一个节点的审批人
		delegateTask.setAssignee(map.get("nextUser").toString());
		
		Map<String,Object> m1 = delegateTask.getExecution().getVariables();
		Map<String,Object> m2 = delegateTask.getVariablesLocal();
		
		
		
//		logger.debug("-----------------------------------------id is:"+id);
//	//	logger.debug("-----------------------------------------arg is:"+dutyNo.getExpressionText());
//		delegateTask.setAssignee(dutyNo.getExpressionText());
		
		// TODO Auto-generated method stub
//		logger.debug("----------------------设置选人 开始--------------------------");
//		delegateTask.setAssignee("admin");  
//		logger.debug("----------------------设置选人 结束--------------------------");
	}

}

你可能感兴趣的:(Activiti)