`

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("----------------------设置选人 结束--------------------------");
	}

}
分享到:
评论

相关推荐

    002_activiti学习总结.zip

    这个"002_activiti学习总结.zip"文件显然包含了一份关于Activiti的学习笔记,可能涵盖了从基础到进阶的各种概念。以下是对这些知识点的详细说明: 1. **流程定义(Process Definition)**:流程定义是Activiti的...

    工作流Activiti5学习总结

    【工作流Activiti5学习总结】 工作流管理系统(Workflow Management System, WfMS)是企业信息化建设中的重要组成部分,它负责协调和管理业务流程。Activiti5是一款开源的工作流引擎,由Alfresco公司开发,它基于...

    工作流Activiti的学习总结(十二) activiti官方十分钟快速学习

    在本篇博客“工作流Activiti的学习总结(十二)activiti官方十分钟快速学习”中,作者分享了关于Activiti工作流引擎的快速学习经验。Activiti是一个开源的、基于Java的企业级工作流引擎,它被广泛应用于自动化业务...

    最详解!Activiti学习文档

    Activiti学习文档 #### 概述 Activiti是一个开源的工作流引擎,用于构建业务流程自动化应用。它支持完整的业务流程管理生命周期,并且提供了丰富的API来满足不同的应用场景需求。本文档将深入探讨Activiti的核心...

    activiti流程学习总结

    ### Activiti流程学习总结 #### 一、工作流的基本概念 在深入了解Activiti之前,我们需要先理解工作流的概念。工作流是一种将业务过程部分或全部自动化的方法,它可以帮助组织提高工作效率,减少错误,并且能够更...

    activiti工作流学习总结

    ### Activiti工作流学习总结 #### 一、Activiti学习资源汇总 - **官方网站**: 提供了Activiti的最新版本信息、文档和技术支持等。地址为:[http://www.activiti.org/](http://www.activiti.org/) - **下载页面**: ...

    工作流引擎Activiti使用总结

    工作流引擎Activiti是开源的工作流引擎,这是一份简单的使用总结,希望对大家有用。

    Activiti学习文档(二)之画流程图并部署流程

    总结来说,“Activiti学习文档(二)之画流程图并部署流程”会带你走过从设计到实施一个完整流程的整个过程,包括理解BPMN符号、使用工具绘制流程图、编写部署脚本,以及如何在实际环境中运行和管理流程实例。...

    工作流Activiti的学习总结(八)Activiti自动执行的应用

    标题中的“工作流Activiti的学习总结(八)Activiti自动执行的应用”表明本文将探讨如何在Activiti工作流引擎中实现任务的自动化执行。Activiti是一个开源的工作流和业务流程管理(BPM)系统,广泛应用于企业级应用...

    Activiti 使用总结

    以上是对Activiti使用的一些核心知识点的总结,对于学习和使用Activiti的朋友来说,这些都是理解和应用 Activiti 必不可少的基础。通过深入理解和实践,你可以利用Activiti构建出高效、灵活的业务流程管理系统。

    activiti学习资料

    总结,这个学习资料包提供了全面了解和掌握 Activiti 的资源,包括理论知识、实践操作以及与流行开发框架的集成。无论是新手还是经验丰富的开发者,都能从中受益,提升在业务流程自动化方面的技能。

    activiti学习资料文档

    这个“activiti学习资料文档”压缩包很可能是为那些希望深入理解Activiti工作流引擎和BPM概念的学习者准备的。下面,我们将详细探讨Activiti的相关知识点,以及如何通过这些资料进行学习。 一、Activiti简介 ...

    工作流Activiti的学习总结(九)Activiti手工执行的应用(ReceiveTask实现方式)

    总结,Activiti中的ReceiveTask是一个等待外部事件触发的节点,它使得流程能够灵活响应外部世界的变化。通过熟练掌握ReceiveTask的使用,开发者可以构建出更加动态和响应式的业务流程。同时,深入研究源码和利用提供...

    Activiti 学习笔记六:流程执行历史记录

    总结,理解并充分利用 Activiti 的流程执行历史记录功能,是深入掌握 Activiti 并提升业务流程管理效率的重要步骤。通过查询和分析历史数据,我们可以更好地了解流程运行状态,发现问题,优化流程,并为企业的决策...

    Activiti5学习笔记

    ### Activiti5学习笔记核心知识点解析 #### 一、Activiti5概述与环境搭建 **Activiti5**是一款开源的工作流引擎,基于Java语言开发,主要用于实现业务流程管理(BPM)和工作流自动化。其核心特性包括流程建模、...

    Activiti 学习笔记十:开始活动节点(判断流程是否结束及查询历史)

    总结,Activiti 的开始活动节点是流程的起点,而流程是否结束则需要通过查询流程实例和历史流程实例的状态来判断。理解并熟练掌握这些概念和操作,将有助于我们在实际项目中更有效地管理和优化业务流程。通过 ...

    Activiti 学习笔记九:并行网关(parallelGateWay)

    总结,Activiti 中的并行网关是构建复杂流程设计的重要工具,它可以提高流程执行的效率,适应多任务并行处理的需求。理解并熟练运用并行网关,能帮助我们更好地设计和优化业务流程。在实际应用中,应根据具体业务...

    Activiti 学习笔记14:工作流定义的角色组

    在本篇Activiti学习笔记中,我们将深入探讨工作流定义中的关键概念——角色组,以及它们在Activiti流程引擎中的应用。Activiti是一款强大的、开源的企业级工作流和业务自动化引擎,广泛应用于业务流程管理(BPM)...

Global site tag (gtag.js) - Google Analytics