工作流-Activiti 开发

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u012442381/article/details/81147599

工作流-Activiti 开发 

工作流概述

工作流(workflow)就是工作流程的计算模型,我们常见的请假电子流就是一个简单的工作流。

JavaWeb 工作流开发准备

使用Eclipse开发,需要安排工作流插件

     离线安装安装步骤:Eclipse插件安装

     new->other 检查安装是否成功

         

简单开发流程

1.新建一个项目

2.添加配置文件-创建数据库表

新建一个配置文件,名为activiti.cfg.xml

<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">
 <!-- 配置 ProcessEngineConfiguration  -->
 <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
   <!-- 配置数据库连接 -->
 <property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
 <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activitiDB?createDatabaseIfNotExist=true&amp;useUnicode=true&amp;characterEncoding=utf8"></property>
 <property name="jdbcUsername" value="root"></property>
 <property name="jdbcPassword" value="rootxxx"></property>
 
  <!-- 配置创建表策略 :没有表时,自动创建 测试方式 -->
  <property name="databaseSchemaUpdate" value="true"></property>
 
 </bean>

</beans>

数据库支持:需要创建的23张表

ACT_RE_*: 'RE'表示repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。
ACT_RU_*: 'RU'表示runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 Activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。
ACT_ID_*: 'ID'表示identity。 这些表包含身份信息,比如用户,组等等。
ACT_HI_*: 'HI'表示history。 这些表包含历史数据,比如历史流程实例, 变量,任务等等。
ACT_GE_*: 通用数据, 用于不同场景下,如存放资源文件。

生产环境采用手动创建-按如下路径获取相应数据库的脚本

建表并创建流程引擎

	public void createTableXml()
	{
		// 创建Activiti配置对象的实例-加载数据库-创建表
		//ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
		//默认获取类路径下的activiti.cfg.xml文件与上面等价
		ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResourceDefault();
		// 使用配置对象创建流程引擎实例
		ProcessEngine processEngine = configuration.buildProcessEngine();
		System.out.println(processEngine);
		
	}

3.流程图设计

线的设计:

4.部署

public void  deployMentProcess(){
	Deployment  deployment = processEngine.getRepositoryService()
	.createDeployment()
	.name("fristActive")
	.addClasspathResource("diagrams/fristActive.bpmn")
	.addClasspathResource("diagrams/fristActive.png")
	.deploy();
	
	System.out.println(deployment.getId()+":"+deployment.getName());
	
}
// ZIP 方式部署(将上面两个文件压缩为zip)
@Test
public void deployProcessDefiByZip(){
	InputStream in=getClass().getClassLoader().getResourceAsStream("fristActive.zip");
	Deployment deploy = processEngine.getRepositoryService()
			.createDeployment()
			.name("fristActive")
			.addZipInputStream(new ZipInputStream(in))
			.deploy();
	
	System.out.println("部署名称:"+deploy.getName());
	System.out.println("部署id:"+deploy.getId());
}

表操作

5.启动流程

public void statProcess(){
	
	// 当前流程的名称
	String processName = "fristActive";
	
	// 流程启动服务
	RuntimeService ru = processEngine.getRuntimeService();
    // 流程参数
	Map<String, Object> variables = new HashMap<String, Object>();
	variables.put("areaer", "区域主管");
	variables.put("Creater", "创建人");
	variables.put("leader", "直接主管");
	variables.put("caiwuyuan", "财务");
	variables.put("isPass", true);
	variables.put("day", 3);
    // 带参启动
	ProcessInstance pi = ru.startProcessInstanceByKey(processName,variables);

	System.out.println("流程实例id:"+pi.getId());//流程实例id
	System.out.println("流程定义id:"+pi.getProcessDefinitionId());//输出流程定义的id
}

操作表:act_ru_execution.ID_=act_ru_execution.Execution_ID_,一一对应关系、

       判断流程结束:act_ru_execution表中的proc_inst_id_ 不存在

6.审批

//执行任务
public void compileTask(String taskId){
	//taskId:任务id
	Map<String, Object> variables = new HashMap<String, Object>();
	variables.put("areaer", "区域主管");
	variables.put("Creater", "创建人");
	variables.put("leader", "直接主管");
	variables.put("caiwuyuan", "财务");
	variables.put("day", 4);
	variables.put("isPass", true);
	boolean haveDay = scan.nextBoolean();
	variables.put("haveDay", true);
	
	processEngine.getTaskService().complete(taskId,variables);
	System.out.println("当前任务执行完毕");
	queryTaskAll();
}

7.查询

//获取流程实例的状态
//判断流程结束:act_ru_execution表中的proc_inst_id_ 不存在
@Test
public void getProcessInstanceState(){
	 String processInstanceId="301";
	 ProcessInstance pi = processEngine.getRuntimeService()
	 .createProcessInstanceQuery()
	 .processInstanceId(processInstanceId)
	 .singleResult();//返回的数据要么是单行,要么是空 ,其他情况报错
	 //判断流程实例的状态
	 if(pi!=null){
		 System.out.println("该流程实例"+processInstanceId+"正在运行...  "+"当前活动的任务:"+pi.getActivityId());
	 }else{
		 System.out.println("当前的流程实例"+processInstanceId+" 已经结束!");
	 }
	 
}
//查询当前代办
public void queryTask(){
	//任务的办理人
	String assignee="创建人";
	//取得任务服务
	TaskService taskService = processEngine.getTaskService();
	//创建一个任务查询对象
	TaskQuery taskQuery = taskService.createTaskQuery();
	//办理人的任务列表
	List<Task> list = taskQuery.taskAssignee(assignee)//指定办理人
	.list();
	
	//遍历任务列表
	if(list!=null&&list.size()>0){
		for(Task task:list){
			System.out.println("任务的办理人:"+task.getAssignee());
			System.out.println("任务的id:"+task.getId());
			System.out.println("任务的名称:"+task.getName());
			
		}
	}
	
}
//查看历史执行流程任务信息
@Test
public void queryHistoryTask(){
	String processInstanceId="101";// 实例id
	List<HistoricTaskInstance> list = processEngine.getHistoryService()
			.createHistoricTaskInstanceQuery()
			.processInstanceId(processInstanceId)
			.list();
	if(list!=null&&list.size()>0){
		for(HistoricTaskInstance temp:list){
			System.out.print("历史流程实例任务id:"+temp.getId());
			System.out.print("历史流程定义的id:"+temp.getProcessDefinitionId());
			System.out.print("历史流程实例任务名称:"+temp.getName());
			System.out.println("历史流程实例任务处理人:"+temp.getAssignee());
		}
	}
}
//查看历史执行流程实例信息
@Test
public void queryHistoryProcInst(){
	List<HistoricProcessInstance> list = processEngine.getHistoryService()
	.createHistoricProcessInstanceQuery()
	.list();
	if(list!=null&&list.size()>0){
		for(HistoricProcessInstance temp:list){
			System.out.println("历史流程实例id:"+temp.getId());
			System.out.println("历史流程定义的id:"+temp.getProcessDefinitionId());
			System.out.println("历史流程实例开始时间--结束时间:"+temp.getStartTime()+"-->"+temp.getEndTime());
		}
	}
}
 

8.附加工能

(1)设置下一层处理人

  • 在bpmn 设计直接写死

      

  • 当前执行完指定下层审批人(配置如下,代码指定为步骤6)

      

  • 使用监听指定当前任务的当前处理人

    

public class TaskListenerImpl implements TaskListener {

	/**
	 * 不仅可以指定当前处理人,可以获取当前任务的参数
	 */
	private static final long serialVersionUID = 1L;

	/**指定个人任务和组任务的办理人*/
	@Override
	public void notify(DelegateTask delegateTask) {
		String assignee = "当前责任人";
		//指定个人任务
		delegateTask.setAssignee(assignee);
	}

}
  • 责任人转移
     //使用任务ID和办理人重新指定办理人:
     processEngine.getTaskService().setAssignee(taskId, userId);

SpringBoot整合

步骤1

pom.xml引入jar包(只引入主要的jar包,其他略)

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.xxx</groupId>
  <artifactId>xxx</artifactId>
  <version>0.0.1-SNAPSHOT</version>
   <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>
 
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter-basic</artifactId>
            <version>6.0.0</version>
        </dependency>
        
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

步骤2 主配置文件application,设计好bpmn流程图

spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/activity?characterEncoding=utf8&useSSL=true
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.show-sql=true
server.port=8081
server.context-path=/activity
server.session.timeout=10
server.tomcat.uri-encoding=UTF-8

3.实现简要代码,主类这里省略不写,主要写具体实现

(1)页面创建提交流程服务接口

@RestController
@RequestMapping("/submitService")
public interface ActivityConsumerService {
	/**
	 * 流程提交
	 * @return
	 */
	@RequestMapping(value="/submitActive",method=RequestMethod.GET)
    public boolean submitActive();
	
}

(2) 提交服务实现

@Service("submitService")
public class ActivityConsumerServiceImpl implements ActivityConsumerService {
 
	@Autowired
        private RuntimeService runtimeService;
	@Autowired
        private TaskService taskService;
	
	@Override
	public boolean submitActive() {
		System.out.println("method submitActivebegin....");
        Map<String,Object> map = new HashMap<String,Object>();
        map.put("apply","zhangsan");
        map.put("approve","lisi");
//流程启动
        ExecutionEntity pi1 = (ExecutionEntity) runtimeService.startProcessInstanceByKey("leave",map);
        String processId = pi1.getId();
        String taskId = pi1.getTasks().get(0).getId();
        taskService.complete(taskId, map);//完成第一步申请
        
        Task task = taskService.createTaskQuery().processInstanceId(processId).singleResult();
        String taskId2 = task.getId();
        map.put("pass", false);
        taskService.complete(taskId2, map);//驳回申请
        System.out.println("method submitActive end....");
        return false;
	}
}

测试一下就可以了

参考文献

Activiti 5.16 用户手册: http://www.mossle.com/docs/activiti/index.html#N1007D

猜你喜欢

转载自blog.csdn.net/u012442381/article/details/81147599