activiti工作学习之spring整合activiti

       前言:博主之前对于工作流这一块的知识是空白的,也是因为前段时间公司的一个项目,然后其中有个审核环节需要用到工作流来开发比较简单,所以就各种找资料恶补了一番。现阶段博主也仅仅停留在会用,用过,有点校验的阶段,写这篇博客也是想把自己的经验写下来(ps:博主有个习惯,就是一些工作上的难点,或者是自己以前没有接触过的东西,博主就会自己用过之后会把它写下来,这样的话有助于自己巩固这个知识点),如果能帮助到那些正需要的童鞋的话,那是再好不过了~~

 

1.eclipse安装插件

    1)打开 Help -> Install New Software. 在如下面板中:

2)然后点击右上角的Add按钮,添加配置插件的地址,如下图:

3)对应的填入下面的值即可(下面的值我也是从网上找来的)

Name: Activiti BPMN 2.0 designer

Location: http://activiti.org/designer/update/

4)点击OK之后,勾选对应的选项即可:

5)然后新建工程的时候,如果有activiti相关的东西就证明插件安装成功

2.准备activiti的开发环境搭建----springmvc整合activiti

1)pom文件添加activiti相关jar包和spring整合包

                <!--工作流activiti  -->
  		<dependency>  
		    <groupId>org.activiti</groupId>  
		    <artifactId>activiti-engine</artifactId>  
		    <version>${activiti.version}</version>  
		</dependency>  
		<dependency>  
		    <groupId>org.activiti</groupId>  
		    <artifactId>activiti-spring</artifactId>  
		    <version>${activiti.version}</version>  
		</dependency>
<activiti.version>5.22.0</activiti.version>

2)xml中的相关配置

<!--    Activiti相关配置         -->
    <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
    	<property name="processEngineConfiguration" ref="processEngineConfiguration"></property>
    </bean>
    
    <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
    	<!--注入数据源  -->
    	<property name="dataSource" ref="dataSource"></property>
    	<!--配置事物管理  -->
    	<property name="transactionManager" ref="transactionManager"></property>
    	<!--没有表创建表  -->
    	<property name="databaseSchemaUpdate" value="true"></property>
		<property name="jobExecutorActivate" value="false"></property>
		
		<!--自动部署  -->
		<property name="deploymentResources">
			<list>
				<value>classpath*:activiti/OrderCheck.bpmn</value>
			</list>
		</property>
    </bean>
    
    <!--activiti的各种服务接口  -->
    <!-- 工作流仓储服务 -->
    <bean id="repositoryService" factory-bean="processEngine" factory-method="getRepositoryService" />
    <!--工作流运行服务  -->
    <bean id="runtimeService" factory-bean="processEngine" factory-method="getRuntimeService" />
    <!--工作流任务服务  -->
    <bean id="taskService" factory-bean="processEngine" factory-method="getTaskService" />
    <!--工作流历史数据服务  -->
    <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
    <!--工作流管理服务  -->
    <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
    <!--工作流唯一服务  -->
    <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />
    <bean id="formService" factory-bean="processEngine" factory-method="getFormService" />

以上配置配置完,启动你的服务时,就会去你配置的自动部署的路径下面去找bpmn结尾的activiti文件去自动创建核心流程引擎对象,也就是processEngine

3.activiti流程图的一些属性

上图就是我当时项目里的一个审核的流程,逻辑上来讲并不是很复杂,运用到的activiti知识点也不是很多,只有一个排他网关,接下来我就讲一下我认为学会用activiti必需要知道的一些东西(本人也不是很熟悉,只是了解)

1)首先要给你的流程processEngine设置一个id和name,这个id就是你的processEngine唯一标识,开启这个流程实例就需要用得到你的id作为key(因为用id开启流程实例activiti会根据你的最新版本的流程来开启),具体设置如下:

2)然后就是根据你的实际业务逻辑给你自己设计的流程的每个task设置一个当前task的待办人或者待办组,如下:

Assignee:当前task的待办人,只有这个人才有权限看到当前任务,也只有这个人才能操作

users和groups:待办组,可以设置一组当前task的待办人,这里就可以集合role来做权限控制,只有某个role才能看到和操作当前任务

3)当前task默认执行的flow和flow的一些属性:每个task都有一个default flow属性设置,可有可无,但是如果有存在task提交之后会产生多个结果的情况下,最好需要设置,比如我在合同领取task设置了default flow为flow20,那么当当前task提交的时候,默认就会直接走flow,走到下一task

如果我想它走flow33,那么我就得需要再flow的main config属性里面设置condition的值,这里可以用表达式来做一个判断

当我在代码里设置的流程变量满足这个表达式,那么当提交当前task的时候,就会走flow33这条线。

4.activiti实战

1)开启一个流程:开启流程是通过runtimeService来实现的,activiti提供了各种service来满足用户的需求,在这里有一个很关键的点,流程关联业务。怎么样让流程和业务关联起来,其实activiti已经考虑到了 ,所以设计了一个businessKey,这个key就是流程关联业务的核心。

String processKey = "OrderCheck";
String businessTable = FtCustomerRecordOrder.class.getSimpleName();
//设置下一个任务办理人,也就是预约流程的办理人就是当前登录用户
Map<String,Object> vars = new HashMap<String, Object>();
vars.put("openUser", lud.getUid());
vars.put("checkType", 0);
String ObjId = businessTable + "." + orderNo;
//设置流程变量 让流程关联业务
vars.put("ObjId", ObjId);
//流程实例ID
String processInstanceId = actTaskService.startProcess(processKey, businessTable, orderNo, vars);
@Override
public String startProcess(String processKey,String businessTable,String businessId,Map<String, Object> vars) {
	 processInstanceByKey = 
			runtimeService.startProcessInstanceByKey(processKey,businessTable+"."+businessId,vars);
	//返回流程实例ID
	return processInstanceByKey.getProcessInstanceId();
}

开启流程的时候,我是用订单表实体类名.orderNo订单编号的形式拼接成一个businessKey,这样的话我开启的这个流程实例就跟我的这条orderNo绑定在一起了,等到我需要知道我这个流程实例是属于哪条订单的时候,取出businessKey就知道了

2)提交当前task。提交task的时候需要设置参数,参数包括下一个任务办理人,以及流程变量,判断走哪一条flow

@Override
public void complete(String taskId, Integer uid, String procInsId,String comment, String title, Map<String, Object> vars) {
	if (StringUtils.isNotBlank(procInsId) && StringUtils.isNotBlank(comment)){
		taskService.addComment(taskId, procInsId, comment);
	}
	// 设置流程变量
	if (vars == null){
		vars = new HashMap<String, Object>();
	}
	if(uid != null){
		taskService.setAssignee(taskId, String.valueOf(uid));
	}
		
	// 设置流程标题
	if (StringUtils.isNotBlank(title)){
		vars.put("title", title);
	}
	//taskService.setVariablesLocal(taskId, vars);
	// 提交任务
	taskService.complete(taskId,vars);
}

3)获取当前待办任务总条数

        @Override
	public int todoCount(Activiti act) {
		// TODO Auto-generated method stub
		// =============== 等待签收的任务  ===============
		TaskQuery toClaimQuery = taskService.createTaskQuery()
				.includeProcessVariables().active().orderByTaskCreateTime().desc();
		
		// 设置查询条件
		if (StringUtils.isNotBlank(act.getAssignee())) {
			toClaimQuery.taskAssignee(act.getAssignee());
		}
		if (StringUtils.isNotBlank(act.getTaskName())) {
			toClaimQuery.taskName(act.getTaskName());
		}
		if (StringUtils.isNotBlank(act.getCandidateUser())){
			toClaimQuery.taskCandidateUser(act.getCandidateUser());
		}
		if (StringUtils.isNotBlank(act.getCandidateGroup())){
			toClaimQuery.taskCandidateGroup(act.getCandidateGroup());
		}
		if (StringUtils.isNotBlank(act.getProcDefKey())){
			toClaimQuery.processDefinitionKey(act.getProcDefKey());
		}
		if (StringUtils.isNotBlank(act.getProcDefId())){
			toClaimQuery.processDefinitionId(act.getProcDefId());
		}
		if (act.getBeginDate() != null){
			toClaimQuery.taskCreatedAfter(act.getBeginDate());
		}
		if (act.getEndDate() != null){
			toClaimQuery.taskCreatedBefore(act.getEndDate());
		}
		// 根据流程变量查询
		Map<String,Object> vars = act.getVars();
		if (vars != null){
			for(Map.Entry<String, Object> entry : vars.entrySet()){
				Object v = entry.getValue();
				if(null != v && !v.equals("")){
					toClaimQuery.processVariableValueEquals(
							entry.getKey(), v);
				}
			}
		}
		return (int)toClaimQuery.count();
	}

4)获取当前待办任务分页数据

        @Override
	public List<Activiti> todoList(int firstResult, int maxResults, Activiti act) {
		// TODO Auto-generated method stub
		List<Activiti> result = new ArrayList<Activiti>();
		// =============== 等待签收的任务  ===============
		TaskQuery toClaimQuery = taskService.createTaskQuery()
				.includeProcessVariables().active().orderByTaskCreateTime().desc();
		// 设置查询条件
		if (StringUtils.isNotBlank(act.getAssignee())) {
			toClaimQuery.taskAssignee(act.getAssignee());
		}
		if (StringUtils.isNotBlank(act.getTaskName())) {
			toClaimQuery.taskName(act.getTaskName());
		}
		if (StringUtils.isNotBlank(act.getCandidateUser())){
			toClaimQuery.taskCandidateUser(act.getCandidateUser());
		}
		if (StringUtils.isNotBlank(act.getCandidateGroup())){
			toClaimQuery.taskCandidateGroup(act.getCandidateGroup());
		}
		if (StringUtils.isNotBlank(act.getProcDefKey())){
			toClaimQuery.processDefinitionKey(act.getProcDefKey());
		}
		if (StringUtils.isNotBlank(act.getProcDefId())){
			toClaimQuery.processDefinitionId(act.getProcDefId());
		}
		if (act.getBeginDate() != null){
			toClaimQuery.taskCreatedAfter(act.getBeginDate());
		}
		if (act.getEndDate() != null){
			toClaimQuery.taskCreatedBefore(act.getEndDate());
		}
		// 根据流程变量查询
		Map<String,Object> vars = act.getVars();
		if (vars != null){
			for(Map.Entry<String, Object> entry : vars.entrySet()){
				Object v = entry.getValue();
				if(null != v && !v.equals("")){
					toClaimQuery.processVariableValueEquals(
							entry.getKey(), v);
				}
			}
		}
		// 查询列表
		List<Task> toClaimList = toClaimQuery.listPage(firstResult, maxResults);
		for (Task task : toClaimList) {
			Activiti e = new Activiti();
			e.setTaskId(task.getId());
			e.setTaskName(task.getName());
			e.setProcInsId(task.getProcessInstanceId());
			e.setTaskName(task.getName());
			e.setVars(task.getProcessVariables());
			e.setStatus("claim");
			e.setBeginDate(task.getCreateTime());
			result.add(e);
		}
		return result;
	}

流程结合业务封装数据

        @Override
	public List<FtOrderCheckDetailDto> queryTODOList(Map<String, Object> param) {
		Activiti act = new Activiti();
		if (param.get("role") != null) {
			act.setCandidateGroup(String.valueOf(param.get("role")));
		}
		if (param.get("openUser") != null) {
			act.setAssignee(String.valueOf(param.get("openUser")));
		}
		act.setProcDefKey("OrderCheck");
		act.setTaskName(String.valueOf(param.get("taskName")));
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			String startTime = String.valueOf(param.get("startTime"));
			String endTime = String.valueOf(param.get("endTime"));
			if (startTime != "null" || startTime.length() > 0) {
				act.setBeginDate(sf.parse(startTime));
			}
			if (endTime != "null" || endTime.length() > 0) {
				act.setEndDate(sf.parse(endTime));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		int firstResult = (int)param.get("firstResult");
		int maxResults = (int)param.get("pageSize");
		List<Activiti> activitis = actTaskService.todoList(firstResult,maxResults,act);
		List<FtOrderCheckDetailDto> tasks = new ArrayList<FtOrderCheckDetailDto>();
		if (!activitis.isEmpty()) {
			for (Activiti acti : activitis) {
				FtOrderCheckDetailDto task = new FtOrderCheckDetailDto();
				task.setTaskId(acti.getTaskId());
				task.setTaskName(acti.getTaskName());
				task.setProcessInstanceId(acti.getProcInsId());
				task.setStartTime(acti.getBeginDate());
				task.setEndTime(acti.getEndDate());
				
				ProcessInstance pi = runtimeService.createProcessInstanceQuery()
								.processInstanceId(acti.getProcInsId())
								.singleResult();
				//获取business_key 获取orderNo
				String businessKey = pi.getBusinessKey();
				if (StringUtils.isNotBlank(businessKey)) {
					//截取字符串,查询投资记录表信息
					int index = businessKey.indexOf(".");
					String orderNo = businessKey.substring(index+1);
					task.setOrderNo(orderNo);
					FtCustomerRecordOrder order = 
							customerRecordOrderMapper.queryByOrderNo(orderNo);
					if (order != null) {
						task.setCustomerId(order.getCustomerId());
						task.setOrderRemark(order.getRemark());
						FtMembers members = membersMapper.getMembersByUid(order.getUid());
						FtCustomer customer = customerMapper.selectFtCustomerByCustomerId(order.getCustomerId());
						FtProductMaster productMaster = 
								productMasterMapper.queryByProductCode(order.getProductCode());
						FtProductEarningsRule productEarningsRule = 
								productEarningsRuleMapper.selectByPrimaryKey(order.getProductEarningsRuleId());
						FtProductSeparateDetail productSeparateDetail 
								= productSeparateDetailMapper.selectByPrimaryKey(order.getProductSeparateId());
						task.setApplyAt(order.getCreateTime());
						task.setInvestmentAmount(order.getInvestmentAmount());
						task.setActualAmount(order.getActualAmount());
						task.setCheckStatus(order.getCheckStatus());
						if (members != null) {
							task.setUserNmae(members.getUserName());
						}
						if (customer != null) {
							task.setCustomerName(customer.getCustomerName());
							
						}
						if (productMaster != null) {
							task.setProductName(productMaster.getProductName());
							task.setProductCode(productMaster.getProductCode());
						}
						if (productEarningsRule != null) {
							task.setPerformanceBenchmark(productEarningsRule.getPerformanceBenchmark());
						}
						Calendar c = Calendar.getInstance();
						if (productSeparateDetail != null) {
							if (productSeparateDetail.getSeparateInterestAt() != null) {
								task.setSeparateInterestAt(productSeparateDetail.getSeparateInterestAt());
								//计算到期时间 =产品成立时间 + 期限
								c.setTime(productSeparateDetail.getSeparateInterestAt());
								c.add(Calendar.MONTH, productMaster.getInvestmentDeadline());
								Date endTime = c.getTime();
								task.setProductEndTime(endTime);
							}
						} 
					}
				}
				tasks.add(task);
			}
		}
		return tasks;
	}

获取待办任务的数据都是用的是runtimeService,如果是获取待办历史那么用的就是historyService

5)获取历史审核任务总数

        @Override
	public int historicCount(Activiti act) {
		HistoricTaskInstanceQuery histTaskQuery = historyService.createHistoricTaskInstanceQuery().finished()
				.includeProcessVariables().orderByHistoricTaskInstanceEndTime().desc();
		// 设置查询条件
		if (StringUtils.isNotBlank(act.getTaskName())) {
			histTaskQuery.taskName(act.getTaskName());
		}
		if(StringUtils.isNotBlank(act.getAssignee())){
			histTaskQuery.taskAssignee(act.getAssignee());
		}
		if (StringUtils.isNotBlank(act.getProcDefKey())){
			histTaskQuery.processDefinitionKey(act.getProcDefKey());
		}
		if (StringUtils.isNotBlank(act.getProcDefId())){
			histTaskQuery.processDefinitionId(act.getProcDefId());
		}
		if (act.getBeginDate() != null){
			histTaskQuery.taskCompletedAfter(act.getBeginDate());
		}
		if (act.getEndDate() != null){
			histTaskQuery.taskCompletedBefore(act.getEndDate());
		}
		// 根据流程变量查询
		Map<String,Object> vars = act.getVars();
		if (vars != null){
			for(Map.Entry<String, Object> entry : vars.entrySet()){
				Object v = entry.getValue();
				if(null != v && !v.equals("")){
					histTaskQuery.processVariableValueEquals(
							entry.getKey(), v);
				}
			}
		}
		return (int) histTaskQuery.count();
	}

6)获取历史审核任务分页数据

        @Override
	public List<Activiti> historicList(int firstResult, int maxResults,
			Activiti act) {
		HistoricTaskInstanceQuery histTaskQuery = historyService.createHistoricTaskInstanceQuery().finished()
				.includeProcessVariables().includeTaskLocalVariables().orderByHistoricTaskInstanceEndTime().desc();
		// 设置查询条件
		if (StringUtils.isNotBlank(act.getTaskName())) {
			histTaskQuery.taskName(act.getTaskName());
		}
		if(StringUtils.isNotBlank(act.getAssignee())){
			histTaskQuery.taskAssignee(act.getAssignee());
		}
		if(StringUtils.isNotBlank(act.getProcInsId())){
			histTaskQuery.processInstanceId(act.getProcInsId());
		}
		if (StringUtils.isNotBlank(act.getProcDefKey())){
			histTaskQuery.processDefinitionKey(act.getProcDefKey());
		}
		if (StringUtils.isNotBlank(act.getProcDefId())){
			histTaskQuery.processDefinitionId(act.getProcDefId());
		}
		if (act.getBeginDate() != null){
			histTaskQuery.taskCompletedAfter(act.getBeginDate());
		}
		if (act.getEndDate() != null){
			histTaskQuery.taskCompletedBefore(act.getEndDate());
		}
		// 根据流程变量查询
		Map<String,Object> vars = act.getVars();
		if (vars != null){
			for(Map.Entry<String, Object> entry : vars.entrySet()){
				Object v = entry.getValue();
				if(null != v && !v.equals("")){
					histTaskQuery.processVariableValueEquals(
							entry.getKey(), v);
				}
			}
		}
		// 查询列表
		List<HistoricTaskInstance> histList = histTaskQuery.listPage(firstResult, maxResults);
		//处理分页问题
		List<Activiti> actList = new ArrayList<Activiti>();
		for (HistoricTaskInstance histTask : histList) {
			Activiti e = new Activiti();
			e.setTaskId(histTask.getId());
			e.setTaskName(histTask.getName());
			e.setAssignee(histTask.getAssignee());
			e.setProcInsId(histTask.getProcessInstanceId());
			e.setStatus("finish");
			e.setBeginDate(histTask.getStartTime());
			e.setEndDate(histTask.getEndTime());
			
			// 审批批注
			List<Comment> comment = taskService.getTaskComments(histTask.getId());
			if(!comment.isEmpty()){
				e.setComment(comment.get(0).getFullMessage());
			}
			
			// 流程变量
			e.setVars(histTask.getProcessVariables());
			
			// 任务变量
			List<HistoricVariableInstance> taskVars = historyService
					.createHistoricVariableInstanceQuery().taskId(histTask.getId()).list();
			Map<String,Object> mTaskVars = new HashMap<String, Object>();
			for(HistoricVariableInstance var : taskVars){
				mTaskVars.put(var.getVariableName(), var.getValue());
			}
			e.setTaskVars(mTaskVars);
			
			actList.add(e);
		}
		return actList;
	}

流程集合业务查询分页数据

        @Override
	public List<FtOrderCheckDetailDto> queryHistoryList(
			Map<String, Object> param) {
		Activiti act = new Activiti();
		act.setAssignee(String.valueOf(param.get("uid")));
		act.setProcDefKey("OrderCheck");
		act.setTaskName(String.valueOf(param.get("taskName")));
		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
		try {
			String startTime = String.valueOf(param.get("startTime"));
			String endTime = String.valueOf(param.get("endTime"));
			if (startTime != "null" || startTime.length() > 0) {
				act.setBeginDate(sf.parse(startTime));
			}
			if (endTime != "null" || endTime.length() > 0) {
				act.setEndDate(sf.parse(endTime));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		int firstResult = (int)param.get("firstResult");
		int maxResults = (int)param.get("pageSize");
		List<Activiti> activitis = actTaskService.historicList(firstResult,maxResults,act);
		List<FtOrderCheckDetailDto> tasks = new ArrayList<FtOrderCheckDetailDto>();
		if (!activitis.isEmpty()) {
			for (Activiti acti : activitis) {
				FtOrderCheckDetailDto task = new FtOrderCheckDetailDto();
				task.setTaskId(acti.getTaskId());
				task.setTaskName(acti.getTaskName());
				task.setProcessInstanceId(acti.getProcInsId());
				task.setStartTime(acti.getBeginDate());
				task.setEndTime(acti.getEndDate());
				
				FtOrderCheckDetail result = mapper.queryByTaskId(acti.getTaskId());
				if (result != null) {
					task.setType(result.getType());
					task.setHandler(result.getHandler());
					task.setRemark(result.getRemark());
					task.setDisposeAt(result.getDisposeAt());
				}
				ProcessInstanceHistoryLog pi = historyService
						.createProcessInstanceHistoryLogQuery(acti.getProcInsId())
						.singleResult();
				/*ProcessInstance pi = runtimeService.createProcessInstanceQuery()
								.processInstanceId(acti.getProcInsId())
								.singleResult();*/
				//获取business_key
				if (pi != null) {
					String businessKey = pi.getBusinessKey();
					if (StringUtils.isNotBlank(businessKey)) {
						//截取字符串,查询投资记录表信息
						int index = businessKey.indexOf(".");
						String orderNo = businessKey.substring(index+1);
						task.setOrderNo(orderNo);
						FtCustomerRecordOrder order = 
								customerRecordOrderMapper.queryHistoryByOrderNo(orderNo);
						if (order != null) {
							FtMembers members = membersMapper.getMembersByUid(order.getUid());
							FtProductMaster productMaster = 
									productMasterMapper.queryHistoryByProductCode(order.getProductCode());
							task.setCustomerId(order.getCustomerId());
							task.setUserNmae(members.getUserName());
							task.setCustomerName("");
							task.setApplyAt(order.getCreateTime());
							task.setProductName(productMaster.getProductName());
							task.setInvestmentAmount(order.getInvestmentAmount());
							task.setActualAmount(order.getActualAmount());
						}
					}
				}
				tasks.add(task);
			}
		}
		return tasks;
	}

以上就是博主学习运用activiti的所有干货,希望能帮助到有需要的童鞋~~

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值