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);


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


<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更新到业务表中,这样不管从业务还是流程都可以查询到对方!

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

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;每次部署一次流程定义就会添加一条数据,同名的版本号累加。

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

建议使用[color=red]startProcessInstanceByKey[/color],特殊情况需要使用以往的版本选择使用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("----------------------设置选人 结束--------------------------");
}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值