项目整合Activiti关联业务(二)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_27063119/article/details/76177563
项目整合Activiti关联业务(二)
1.说说怎样整合Activiti
    先提一下有个开源项目lemon(一款基于Java开发的开源OA),对于我的整合帮助很大,遇到的一些问题参考该项目源码都得到了解决,在此感谢一下!
    首先我的整合是基于maven的,所以没有配置maven的童鞋需要先配置一下,pom文件需要加入:

	<properties>
		<activiti.version>5.18.0</activiti.version>
	</properties>
		<dependency>
	        <groupId>org.activiti</groupId>
	        <artifactId>activiti-modeler</artifactId>
	        <version>${activiti.version}</version>
	    </dependency>
		<dependency>
			<groupId>org.activiti</groupId>
			<artifactId>activiti-spring</artifactId>
			<version>${activiti.version}</version>
		</dependency>
		<dependency>
	      <groupId>org.activiti</groupId>
	      <artifactId>activiti-json-converter</artifactId>
		  <version>${activiti.version}</version>
	    </dependency>

可以看出 使用的版本是5.18.0,为什么这样呢,其实为了少走坑,写这篇博客的时候 lemon 项目使用的Activiti也是5.18.0的,


与Spring整合需要增加配置文件至Resource文件夹下:activiti-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

	<!-- spring负责创建流程引擎的配置文件 -->
	<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
		<!-- 数据源 -->
		<property name="dataSource" ref="myDataSource" />
		<!-- 配置事务管理器,统一事务 -->
		<property name="transactionManager" ref="transactionManager" />
		<!-- 设置建表策略,如果没有表,自动创建表 -->
		<property name="databaseSchemaUpdate" value="true" />
		
		<!-- 用于更改流程节点的执行行为 -->  
    	<property name="activityBehaviorFactory" ref="activityBehaviorFactoryExt"/>
    	
    	<!-- 生成流程图的字体   解决图片中文不显示问题-->  
	    <property name="activityFontName" value="黑体"></property>
	    <property name="labelFontName" value="黑体"></property>
	</bean>
	
	<bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper"/>
	
	<!-- 创建流程引擎对象 -->
	<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
		<property name="processEngineConfiguration" ref="processEngineConfiguration" />
	</bean>
	
	<!-- 
	相当于下面的代码
	RepositoryServicie repositoryService = processEngine.getRepositoryService();
	RuntimeServicie repositoryService = processEngine.getRuntimeServicie();
	TaskServicie taskServicie = processEngine.getTaskServicie();
	HistoryServicie historyServicie = processEngine.getHistoryServicie();
	 -->
	<!-- 由流程引擎对象,提供的方法,创建项目中使用的Activiti工作流的Service -->
	<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="formService" factory-bean="processEngine" factory-method="getFormService" />
  	
</beans>


其中配置的数据源myDataSource 是使用SSH项目配置的,这里无需再次配置

最后在Spring配置文件中引入一下:
	<import resource="classpath*:/activiti-context.xml" />

到这里配置的就差不多了!


2.怎样关联业务的:

一句话:使用正在执行对象表中的一个字段BUSINESS_KEY(Activiti提供的一个字段),让启动的流程(流程实例)关联业务

具体怎样实现的呢,在启动流程实例时需要将提交的表单关联住工作流,这里有个小技巧,设计流程图时要将process ID(流程标识符)与表单类型标志人为设置成一样的,通过key进行启动流程实例,操作起来很方便,默认会使用最新版本的流程进行启动,看代码:

controller层:
@RequestMapping(value="/startProcess.do")
public void startProcess(HttpServletRequest request,HttpServletResponse response,String formKey,String formid){
	LogonInfo userinfo = (LogonInfo) request.getSession().getAttribute(SessionKey.UserInfoKey);
	if(actworkflowservice.startProcess(formKey, userinfo.getUserInfo().getId()+"", formid)){
		this.writeJson(response, true);
	}else{
		this.writeJson(response, false);
	}
}


比如我提交的是请假单,那么在前台默认指定formKey就是LeaveBill,并且在先前设计流程图的时候就要指定process ID(流程标识符)也是 LeaveBill,同时将该表单的id也传过来。

service层:
	/**
	 * 启动流程实例
	 */
	@Override
	public boolean startProcess(String formKey,String userid,String formid) {
		
		//查找数据库来确定需要执行哪个
		String customBeanName = approvalBeanConfDao.getApprovalSerBeanById(formKey).getBeanName();
		IActWorkFlowCustomService customService = null;
		if(customBeanName!=null){
			WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
			customService = (IActWorkFlowCustomService)wac.getBean(customBeanName);
			customService.startRunTask(formid);
		}
		
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("userid", userid);
		
		//使用流程变量设置字符串(格式 : LeaveBill.Id 的形式)
		//使用正在执行对象表中的一个字段BUSINESS_KEY(Activiti提供的一个字段),让启动的流程(流程实例)关联业务
		String objId = formKey + "." +formid;
		map.put("objId", objId);
		
		runtimeService.startProcessInstanceByKey(formKey, objId, map);
		return true;
	}

关于service层有段代码,注释为:查找数据库来确定需要执行哪个 后面会说这是干什么的。
service层会将正在执行对象表中的BUSINESS_KEY字段写入   表单类型.表单ID,这样就起到了关联作用


3.怎样在Activiti审批中操作业务的:

1.使用反射机制,之前做过后来发现不支持事务就没用了
2.使用spring中的bean直接调用方法,现在使用的就是这种

首先需要新建一张表存放配置 (1).表单类型(唯一标志符,比如:LeaveBill),(2)该表单关联的业务service层的bean名称,(3)查看该表单的url地址,下面就是实体类:

import javax.persistence.Entity;
import javax.persistence.Id;

/**
 * 审批  个性化接口实现 bean 对照表
 * @author nuohy  
 * @Description: TODO   
 * @date 2017年7月21日
 */

@Entity(name="actself_approvalBeanConf")
public class ApprovalBeanConf {
	
	private String id;
	private String beanName;
	private String showFormUrl;
	
	@Id
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getBeanName() {
		return beanName;
	}
	public void setBeanName(String beanName) {
		this.beanName = beanName;
	}
	
	public String getShowFormUrl() {
		return showFormUrl;
	}
	public void setShowFormUrl(String showFormUrl) {
		this.showFormUrl = showFormUrl;
	}
	
	public ApprovalBeanConf(String id, String beanName) {
		super();
		this.id = id;
		this.beanName = beanName;
	}
	
	public ApprovalBeanConf() {
		super();
	}
	
	public ApprovalBeanConf(String id, String beanName, String showFormUrl) {
		super();
		this.id = id;
		this.beanName = beanName;
		this.showFormUrl = showFormUrl;
	}
	@Override
	public String toString() {
		return "ApprovalBeanConf [id=" + id + ", beanName=" + beanName + ", showFormUrl=" + showFormUrl + "]";
	}
	
}

通过向该表中添加一些配置数据后,如:
LeaveBill    leavebillservice activiti/leave/turnShowForm.do

并且业务层的service接口必须继承IActWorkFlowCustomService接口
IActWorkFlowCustomService.java:
import java.util.Map;

/**
 * 所有业务审批service 的接口 必须继承该接口 实现其方法
 * @author nuohy  
 * @Description: TODO   
 * @date 2017年7月21日
 */
public interface IActWorkFlowCustomService {
	
	
	/**
	 * 设置流程变量
	 * @param formid
	 * @return
	 */
	public Map<String, Object> setvariables(String formid);
	
	
	/**
	 * 整个流程开始时需要执行的任务
	 * @param formid
	 */
	public void startRunTask(String formid);
	
	
	/**
	 * 整个流程结束需要执行的任务
	 * @param formid
	 */
	public void endRunTask(String formid);


}




于是可以在流程启动的时候操作一下业务层的方法,在结束的时候操作业务的方法,也可以在流程执行的中间操作业务的方法

放上一段请假业务层的代码:ILeaveBillService.java

import java.text.ParseException;
import java.util.Map;

public interface ILeaveBillService extends IActWorkFlowCustomService{

	public DataGrid<Map<String, Object>> getleavebills(String userid,PageInfo page);
	
	public boolean addLeave(LeaveBill leaveBill);
	
	public boolean delleave(LeaveBill leaveBill);
	
	public FLeaveBill getLeaveBill(String formid) throws ParseException;
	
}

业务实现层没啥可贴的了

说到这里还没有说到重点:activiti到底是怎样操作的呢,上代码,这里就解释了上面说的为什么在启动流程实例时会有段查找数据库进行确定执行哪个方法的代码:
流程开始时执行的方法上写过了就不重复了,接下来看看执行过程中以及执行结束时怎样调用业务层的:

/**
	 * 完成提交任务
	 */
	@Override
	public int completeProcess(String formtype,String remark, String taskId,String userId,String formid,String outcome) {
		
		//任务Id 查询任务对象
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		
		//任务对象  获取流程实例Id
		String processInstanceId = task.getProcessInstanceId();
		
		//设置审批人的userId
		Authentication.setAuthenticatedUserId(userId);
		
		//添加记录
		taskService.addComment(taskId, processInstanceId, remark);
		
		/**
		 * 如果连线的名称是'默认提交',那么就不需要设置,如果不是,就需要设置流程变量
		 * 在完成任务之前,设置流程变量,按照连线的名称,去完成任务
				 流程变量的名称:outcome
				 流程变量的值:连线的名称
		 */
		Map<String, Object> variables = new HashMap<String,Object>();
		if(outcome!=null && !outcome.equals("默认提交")){
			variables.put("outcome", outcome);
		}
		
		
		//设置流程变量  条件控制
		String customBean = null;
		
		//查找数据库来确定需要执行哪个
		customBean = approvalBeanConfDao.getApprovalSerBeanById(formtype).getBeanName();
		IActWorkFlowCustomService customService = null;
		if(customBean!=null){
			WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
			customService = (IActWorkFlowCustomService)wac.getBean(customBean);
		    if(customService!=null){
		    	Map<String, Object> map = customService.setvariables(formid);
		    	variables.putAll(map);
		    }
		}
		
	    //完成办理
	    taskService.complete(taskId,variables);
	    
	    
	    //执行结束  更改状态
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		if(processInstance==null&&customService!=null){
			if(customService!=null){
				customService.endRunTask(formid);
		    }
			return 2;
		}else{
			return 1;
		}
	}


以上就是怎样关联业务的解析:


为了更好的学习交流 贴上完整的service代码:ActWorkFlowCommServiceImpl.java

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;

import javax.annotation.Resource;

import org.activiti.engine.FormService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.history.HistoricVariableInstance;
import org.activiti.engine.impl.identity.Authentication;
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.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Comment;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;


/**
 * Activiti工作流引擎  核心 service
 * @author nuohy  
 * @Description: TODO   
 * @date 2017年7月21日
 */
@Service(value="actworkflowservice")
@Transactional
public class ActWorkFlowCommServiceImpl implements IActWorkFlowCommService{

	@Resource(name="repositoryService")
	private RepositoryService repositoryService;
	
	@Resource(name="runtimeService")
	private RuntimeService runtimeService;
	
	@Resource(name="taskService")
	private TaskService taskService;
	
	@Resource(name="formService")
	private FormService formService;
	
	@Resource(name="historyService")
	private HistoryService historyService;
	
	@Resource(name="leavebilldao")
	private ILeaveBillDao leavebilldao;

	@Resource(name="rebMoneyDao")
	private IRebMoneyDao rebMoneyDao;
	
	@Resource(name="approvalBeanConfDao")
	private IApprovalBeanConfDao approvalBeanConfDao;
	
	/**
	 * 部署流程定义
	 */
	@Override
	public boolean saveNewDeploy(String filepath,String filename) {
		boolean returnflag  = true;
		ZipInputStream zipInputStream;
		try {
			
			System.out.println(filepath);
			
			zipInputStream = new ZipInputStream(new FileInputStream(new File(filepath)));
			repositoryService.createDeployment()
				.name(filename)
				.addZipInputStream(zipInputStream)
				.deploy();
			System.out.println("部署完成!");
			return returnflag;
		} catch (FileNotFoundException e) {
			returnflag = false;
			e.printStackTrace();
		}
		return returnflag;
	}

	/**
	 * 查询部署对象信息
	 */
	@Override
	public List<FDeployment> findDeployList() {
		List<FDeployment> relist = null;
		List<Deployment> list = repositoryService.createDeploymentQuery().orderByDeploymenTime().desc().list();
		if(list!=null&&list.size()>0){
			relist = new ArrayList<FDeployment>();
			for (Deployment dm : list) {
				FDeployment fDeployment = new FDeployment(dm.getId(), dm.getName(), dm.getDeploymentTime(), dm.getCategory(), dm.getTenantId());
				relist.add(fDeployment);
				System.err.println(fDeployment.toString());
			}
		}
		return relist;
	}
	
	
	/**
	 * 删除部署信息 
	 */
	@Override
	public boolean deldeployment(String deploymentid) {
		try{
			repositoryService.deleteDeployment(deploymentid, true);
		}catch(Exception e){
			return false;
		}
		return true;
	}
	
	
	
	/**
	 * 启动流程实例
	 */
	@Override
	public boolean startProcess(String formKey,String userid,String formid) {
		
		//查找数据库来确定需要执行哪个
		String customBeanName = approvalBeanConfDao.getApprovalSerBeanById(formKey).getBeanName();
		IActWorkFlowCustomService customService = null;
		if(customBeanName!=null){
			WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
			customService = (IActWorkFlowCustomService)wac.getBean(customBeanName);
			customService.startRunTask(formid);
		}
		
		
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("userid", userid);
		
		//使用流程变量设置字符串(格式 : LeaveBill.Id 的形式)
		//使用正在执行对象表中的一个字段BUSINESS_KEY(Activiti提供的一个字段),让启动的流程(流程实例)关联业务
		String objId = formKey + "." +formid;
		map.put("objId", objId);
		
		runtimeService.startProcessInstanceByKey(formKey, objId, map);
		return true;
	}
	
	
	
	/**
	 * 查询流程定义信息
	 */
	@Override
	public List<FProcessDefinition> findProcessDefinitionList(){
		List<FProcessDefinition> relist = null;
		List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().orderByProcessDefinitionVersion().desc().list();
		if(list!=null&&list.size()>0){
			relist = new ArrayList<FProcessDefinition>();
			for (ProcessDefinition pd : list) {
				FProcessDefinition fProcessDefinition = new FProcessDefinition(pd.getId(), pd.getCategory(), pd.getName(), pd.getKey(), pd.getDescription(), pd.getVersion(), pd.getResourceName(), pd.getDeploymentId(),pd.getDiagramResourceName(), pd.hasStartFormKey(), pd.isSuspended(), pd.getTenantId());
				relist.add(fProcessDefinition);
				System.out.println(fProcessDefinition.toString());
			}
		}
		return relist;
	}
	

	
	/**
	 * 查看总体流程图
	 */
	@Override
	public InputStream lookProcessImage(String deploymentid, String imagename) {
		InputStream in = repositoryService.getResourceAsStream(deploymentid, imagename);
		return in;
	}

	
	/**
	 * 查看当前流程图(1)
	 * @param taskid
	 */
	@Override
	public ProcessDefinition lookCurrentProcessImage(String taskId) {
		//任务ID
		//1:获取任务ID,获取任务对象,使用任务对象获取流程定义ID,查询流程定义对象
		//使用任务ID,查询任务对象
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		//获取流程定义ID
		String processDefinitionId = task.getProcessDefinitionId();
		//查询流程定义的对象
		ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()//创建流程定义查询对象,对应表act_re_procdef 
							.processDefinitionId(processDefinitionId)//使用流程定义ID查询
							.singleResult();
		return pd;
	}
	
	
	
	/**  查看当前流程图(2)	--	公用
	 *   查看当前活动,获取当期活动对应的坐标x,y,width,height,将4个值存放到Map<String,Object>中
	 * 	 map集合的key:表示坐标x,y,width,height
	 * 	 map集合的value:表示坐标对应的值
	 */
	@Override
	public Map<String, Object> findCoordingByTask(String taskId) {
		//存放坐标
		Map<String, Object> map = new HashMap<String,Object>();
		//使用任务ID,查询任务对象
		Task task = taskService.createTaskQuery()//
					.taskId(taskId)//使用任务ID查询
					.singleResult();
		//获取流程定义的ID
		String processDefinitionId = task.getProcessDefinitionId();
		//获取流程定义的实体对象(对应.bpmn文件中的数据)
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity)repositoryService.getProcessDefinition(processDefinitionId);
		//流程实例ID
		String processInstanceId = task.getProcessInstanceId();
		//使用流程实例ID,查询正在执行的执行对象表,获取当前活动对应的流程实例对象
		ProcessInstance pi = runtimeService.createProcessInstanceQuery()//创建流程实例查询
					.processInstanceId(processInstanceId)//使用流程实例ID查询
					.singleResult();
		//获取当前活动的ID
		String activityId = pi.getActivityId();
		//获取当前活动对象
		ActivityImpl activityImpl = processDefinitionEntity.findActivity(activityId);//活动ID
		//获取坐标
		map.put("x", activityImpl.getX());
		map.put("y", activityImpl.getY());
		map.put("width", activityImpl.getWidth());
		map.put("height", activityImpl.getHeight());
		
		return map;
	}
	
	
	
	
	@Override
	public ProcessDefinition lookCurrentProcessImgByFormId(String formid, String formKey) {
		Task task = taskService.createTaskQuery().processInstanceBusinessKey(formKey+"."+formid).singleResult();
		String processDefinitionId = task.getProcessDefinitionId();
		ProcessDefinition pd = repositoryService.createProcessDefinitionQuery()//创建流程定义查询对象,对应表act_re_procdef 
				.processDefinitionId(processDefinitionId)//使用流程定义ID查询
				.singleResult();
		return pd;
	}
	
	
	
	@Override
	public Map<String, Object> findCoordingByTaskByFormId(String formid, String formKey) {
		
		//存放坐标
		Map<String, Object> map = new HashMap<String,Object>();
		
		Task task = taskService.createTaskQuery().processInstanceBusinessKey(formKey+"."+formid).singleResult();
		
		//获取流程定义的ID
		String processDefinitionId = task.getProcessDefinitionId();
		//获取流程定义的实体对象(对应.bpmn文件中的数据)
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity)repositoryService.getProcessDefinition(processDefinitionId);
		//流程实例ID
		String processInstanceId = task.getProcessInstanceId();
		//使用流程实例ID,查询正在执行的执行对象表,获取当前活动对应的流程实例对象
		ProcessInstance pi = runtimeService.createProcessInstanceQuery()//创建流程实例查询
					.processInstanceId(processInstanceId)//使用流程实例ID查询
					.singleResult();
		//获取当前活动的ID
		String activityId = pi.getActivityId();
		//获取当前活动对象
		ActivityImpl activityImpl = processDefinitionEntity.findActivity(activityId);//活动ID
		//获取坐标
		map.put("x", activityImpl.getX());
		map.put("y", activityImpl.getY());
		map.put("width", activityImpl.getWidth());
		map.put("height", activityImpl.getHeight());
		
		return map;
	}
	
	
	
	
	
	

	/**
	 * 查看个人任务列表
	 */
	@Override
	public DataGrid<Map<String, Object>> mytasklist(String userid,PageInfo page) {
		DataGrid<Map<String, Object>> dataGrid = new DataGrid<Map<String, Object>>();
		
		int pagenum = page.getPage();
		int rowsnum = page.getRows();
		
		int firstResult = (pagenum-1)*rowsnum;
		int maxResults = firstResult+rowsnum;
		
		TaskQuery taskQuery = taskService.createTaskQuery().taskAssignee(userid);
		long allcount = taskQuery.count();
		dataGrid.setTotal(allcount);
		
		List<Task> list = taskQuery.orderByTaskCreateTime().desc().listPage(firstResult, maxResults);
		
		List<Map<String, Object>> listmap = new ArrayList<Map<String, Object>>();
		for (Task task : list) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("id", task.getId());
			map.put("name", task.getName());
			map.put("description", task.getDescription());
			map.put("priority", task.getPriority());
			map.put("owner", task.getOwner());
			map.put("assignee", task.getAssignee());
			map.put("delegationState", task.getDelegationState());
			map.put("processInstanceId", task.getProcessInstanceId());
			map.put("executionId", task.getExecutionId());
			map.put("processDefinitionId", task.getProcessDefinitionId());
			map.put("createTime", task.getCreateTime());
			map.put("taskDefinitionKey", task.getTaskDefinitionKey());
			map.put("dueDate", task.getDueDate());
			map.put("category", task.getCategory());
			map.put("parentTaskId", task.getParentTaskId());
			map.put("tenantId", task.getTenantId());
			
			Map<String, Object> FormModel_map = findFormModelByTaskId(task.getId());
			//表单中避免使用 hfmx_actWorkFlow_formType 关键字
			/*map.put("hfmx_actWorkFlow_formType", FormModel_map.get("hfmx_actWorkFlow_formType"));
			map.put("formid", FormModel_map.get("id"));*/
			
			map.putAll(FormModel_map);
			
			List<Map<String,Object>> searchForMap = leavebilldao.searchForMap("select * from sysuser where id="+task.getAssignee());
			map.put("processUser", searchForMap.get(0).get("name"));
			
			listmap.add(map);
		}
		dataGrid.setRows(listmap);
		
		return dataGrid;
	}

	
	
	
	@Override
	public Map<String, Object> findFormModelByTaskId(String taskId) {
		//任务Id 查询任务对象
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		
		//任务对象  获取流程实例Id
		String processInstanceId = task.getProcessInstanceId();

		//流程实例Id 查询正在执行的执行对象表  返回流程实例对象
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		
		//流程实例对象 获取 BUSINESS_KEY ,从而获取表单对象
		String businessKey = processInstance.getBusinessKey();
		String[] split = businessKey.split("\\.");
		
		
		Map<String, Object> map = new HashMap<String,Object>();

		ApprovalBeanConf approvalBeanConf = approvalBeanConfDao.getApprovalSerBeanById(split[0]);
		map.put("hfmx_actWorkFlow_formType", split[0]);
		map.put("showFormUrl", approvalBeanConf.getShowFormUrl());
		map.put("formid", split[1]);
		
		return map;
	}
	
	

	/**
	 * 完成提交任务
	 */
	@Override
	public int completeProcess(String formtype,String remark, String taskId,String userId,String formid,String outcome) {
		
		//任务Id 查询任务对象
		Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
		
		//任务对象  获取流程实例Id
		String processInstanceId = task.getProcessInstanceId();
		
		//设置审批人的userId
		Authentication.setAuthenticatedUserId(userId);
		
		//添加记录
		taskService.addComment(taskId, processInstanceId, remark);
		
		/**
		 * 如果连线的名称是'默认提交',那么就不需要设置,如果不是,就需要设置流程变量
		 * 在完成任务之前,设置流程变量,按照连线的名称,去完成任务
				 流程变量的名称:outcome
				 流程变量的值:连线的名称
		 */
		Map<String, Object> variables = new HashMap<String,Object>();
		if(outcome!=null && !outcome.equals("默认提交")){
			variables.put("outcome", outcome);
		}
		
		
		//设置流程变量  条件控制
		String customBean = null;
		
		//查找数据库来确定需要执行哪个
		customBean = approvalBeanConfDao.getApprovalSerBeanById(formtype).getBeanName();
		IActWorkFlowCustomService customService = null;
		if(customBean!=null){
			WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
			customService = (IActWorkFlowCustomService)wac.getBean(customBean);
		    if(customService!=null){
		    	Map<String, Object> map = customService.setvariables(formid);
		    	variables.putAll(map);
		    }
		}
		
	    //完成办理
	    taskService.complete(taskId,variables);
	    
	    
	    //执行结束  更改状态
		ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
		if(processInstance==null&&customService!=null){
			if(customService!=null){
				customService.endRunTask(formid);
		    }
			return 2;
		}else{
			return 1;
		}
	}

	
	/**
	 * 通过当前任务Id 获取 批注时的备注信息
	 */
	@Override
	public List<FComment> getComment(String currenttaskId) {
		List<FComment> relist = new ArrayList<FComment>();
		List<Comment> list = new ArrayList<Comment>();
		Task task = taskService.createTaskQuery().taskId(currenttaskId).singleResult();
		
		String processInstanceId = task.getProcessInstanceId();
		
		List<HistoricTaskInstance> htilist = historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstanceId).list();
		if(htilist!=null&&htilist.size()>0){
			for (HistoricTaskInstance hti : htilist) {
				String htaskid = hti.getId();
				List<Comment> tasklist = taskService.getTaskComments(htaskid);
				list.addAll(tasklist);
			}
		}
		
		for (Comment com : list) {
			FComment fc = new FComment();
			fc.setId(com.getId());
			fc.setUserid(com.getUserId());
			List<Map<String,Object>> searchForMap = leavebilldao.searchForMap("select * from sysuser where id="+com.getUserId());
			fc.setUserName(searchForMap.get(0).get("name").toString());
			fc.setTime(com.getTime());
			fc.setTaskId(com.getTaskId());
			fc.setProcessInstanceId(com.getProcessInstanceId());
			fc.setType(com.getType());
			fc.setFullMessage(com.getFullMessage());
			relist.add(fc);
		}
		
		System.out.println(relist.toString());
		
		return relist;
	}

	
	
	
	
	/**
	 * 通过请假单id查找 批注信息
	 */
	@Override
	public List<FComment> getCommentByLeavebillId(String leaveBillId) {
		List<FComment> relist = new ArrayList<FComment>();
		LeaveBill leaveBill = new LeaveBill();
		String simpleName = leaveBill.getClass().getSimpleName();
		String objId = simpleName+"."+leaveBillId;
		HistoricVariableInstance hvi = historyService.createHistoricVariableInstanceQuery().variableValueEquals("objId", objId).orderByProcessInstanceId().asc().singleResult();
		String processInstanceId = hvi.getProcessInstanceId();
		List<Comment> list = taskService.getProcessInstanceComments(processInstanceId);
		
		for (Comment com : list) {
			FComment fc = new FComment();
			fc.setId(com.getId());
			fc.setUserid(com.getUserId());
			List<Map<String,Object>> searchForMap = leavebilldao.searchForMap("select * from sysuser where id="+com.getUserId());
			fc.setUserName(searchForMap.get(0).get("name").toString());
			fc.setTime(com.getTime());
			fc.setTaskId(com.getTaskId());
			fc.setProcessInstanceId(com.getProcessInstanceId());
			fc.setType(com.getType());
			fc.setFullMessage(com.getFullMessage());
			relist.add(fc);
		}
		Collections.reverse(relist);
		return relist;
	}

	
	/**
	 * 已知任务ID,查询ProcessDefinitionEntiy对象,从而获取当前任务完成之后的连线名称,并放置到List<String>集合中
	 */
	@Override
	public List<String> findOutComeListByTaskId(String taskId) {
		//返回存放连线的名称集合
		List<String> list = new ArrayList<String>();
		//1:使用任务ID,查询任务对象
		Task task = taskService.createTaskQuery()//
					.taskId(taskId)//使用任务ID查询
					.singleResult();
		//2:获取流程定义ID
		String processDefinitionId = task.getProcessDefinitionId();
		//3:查询ProcessDefinitionEntiy对象
		ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity) repositoryService.getProcessDefinition(processDefinitionId);
		//使用任务对象Task获取流程实例ID
		String processInstanceId = task.getProcessInstanceId();
		//使用流程实例ID,查询正在执行的执行对象表,返回流程实例对象
		ProcessInstance pi = runtimeService.createProcessInstanceQuery()//
					.processInstanceId(processInstanceId)//使用流程实例ID查询
					.singleResult();
		//获取当前活动的id
		String activityId = pi.getActivityId();
		//4:获取当前的活动
		ActivityImpl activityImpl = processDefinitionEntity.findActivity(activityId);
		//5:获取当前活动完成之后连线的名称
		List<PvmTransition> pvmList = activityImpl.getOutgoingTransitions();
		if(pvmList!=null && pvmList.size()>0){
			for(PvmTransition pvm:pvmList){
				String name = (String) pvm.getProperty("name");
				if(StringUtils.isNotBlank(name)){
					list.add(name);
				}else{
					list.add("默认提交");
				}
			}
		}
		return list;
	}

}


请假单实体类:LeaveBill.java
import java.util.Date;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

@Entity(name="actself_leavebill")
public class LeaveBill {
	
	private int id;
	private String days;
	private String content;
	private String remark;
	private Date leavedate;
	private int state;	//0-初始录入   1-开始审批     2-审批完成
	private String user_id;
	
	@Id
	@GeneratedValue
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getDays() {
		return days;
	}
	public void setDays(String days) {
		this.days = days;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getRemark() {
		return remark;
	}
	public void setRemark(String remark) {
		this.remark = remark;
	}
	public Date getLeavedate() {
		return leavedate;
	}
	public void setLeavedate(Date leavedate) {
		this.leavedate = leavedate;
	}
	public int getState() {
		return state;
	}
	public void setState(int state) {
		this.state = state;
	}
	public String getUser_id() {
		return user_id;
	}
	public void setUser_id(String user_id) {
		this.user_id = user_id;
	}
	
	public LeaveBill() {
		super();
	}
	public LeaveBill(int id, String days, String content, String remark, Date leavedate, int state, String user_id) {
		super();
		this.id = id;
		this.days = days;
		this.content = content;
		this.remark = remark;
		this.leavedate = leavedate;
		this.state = state;
		this.user_id = user_id;
	}
	public LeaveBill(String days, String content, String remark, Date leavedate, int state, String user_id) {
		super();
		this.days = days;
		this.content = content;
		this.remark = remark;
		this.leavedate = leavedate;
		this.state = state;
		this.user_id = user_id;
	}
	@Override
	public String toString() {
		return "LeaveBill [id=" + id + ", days=" + days + ", content=" + content + ", remark=" + remark + ", leavedate="
				+ leavedate + ", state=" + state + ", user_id=" + user_id + "]";
	}
}


下次说说怎样整合在线流程图设计器,以及遇到的问题和解决方法,感谢阅读!


猜你喜欢

转载自blog.csdn.net/qq_27063119/article/details/76177563
今日推荐