• 1. 北京传智播客教育 www.itcast.cnActiviti5.4工作流
  • 2. 北京传智播客教育 www.itcast.cnActiviti入门
  • 3. 北京传智播客教育 www.itcast.cnActiviti入门工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现”。 通俗的说,流程就是多个人在一起合作完成某件事情的步骤,把步骤变成计算机能理解的形式就是工作流。
  • 4. 北京传智播客教育 www.itcast.cnActiviti入门工作流管理系统(Workflow Management System, WfMS)是一个软件系统,它完成工作量的定义和管理,并按照在系统中预先定义好的工作流规则进行工作流实例的执行。工作流管理系统不是企业的业务系统,而是为企业的业务系统的运行提供了一个软件的支撑环境。 工作流管理联盟(WfMC,Workflow Management Coalition)给出的关于工作流管理系统的定义是:工作流管理系统是一个软件系统,它通过执行经过计算的流程定义去支持一批专门设定的业务流程。工作流管理系统被用来定义、管理、和执行工作流程。 1、定义工作流:包括具体的活动、规则等。 2、执行工作流:按照流程定义的规则执行,并由多个参与者进行控制。工作流主要实现功能一、定义工作流 二、执行工作流 eclipse或者myeclipse安装activiti插件 顺序、分支、聚合、并发…
  • 5. 北京传智播客教育 www.itcast.cnActiviti入门采用工作流管理系统的优点 1、提高系统的柔性,适应业务流程的变化  2、实现更好的业务过程控制,提高顾客服务质量 3、降低系统开发和维护成本 工作流框架有:Activiti、JBPM、OSWorkflow、ActiveBPEL、YAWL等。工作流系统的优点:
  • 6. 北京传智播客教育 www.itcast.cnActiviti入门Activiti5是由Alfresco软件在2010年5月17日发布的业务流程管理(BPM)框架,它是覆盖了业务流程管理、工作流、服务协作等领域的一个开源的、灵活的、易扩展的可执行流程语言框架。Activiti基于Apache许可的开源BPM平台,创始人Tom Baeyens是JBoss Activiti的项目架构师,它特色是提供了eclipse插件,开发人员可以通过插件直接绘画出业务流程图。 开源工作流Activiti5.4介绍:
  • 7. 北京传智播客教育 www.itcast.cnActiviti入门Activiti数据库支持: Activiti的后台是有数据库的支持,所有的表都以ACT_开头。 第二部分是表示表的用途的两个字母标识。 用途也和服务的API对应。 ACT_RE_*: 'RE'表示repository。 这个前缀的表包含了流程定义和流程静态资源 (图片,规则,等等)。 ACT_RU_*: 'RU'表示runtime。 这些运行时的表,包含流程实例,任务,变量,异步任务,等运行中的数据。 Activiti只在流程实例执行过程中保存这些数据, 在流程结束时就会删除这些记录。 这样运行时表可以一直很小速度很快。 ACT_ID_*: 'ID'表示identity。 这些表包含身份信息,比如用户,组等等。 ACT_HI_*: 'HI'表示history。 这些表包含历史数据,比如历史流程实例, 变量,任务等等。 ACT_GE_*: 通用数据, 用于不同场景下,如存放资源文件。
  • 8. 北京传智播客教育 www.itcast.cn准备Activiti环境
  • 9. 北京传智播客教育 www.itcast.cn准备Activiti环境activiti5 软件环境 JDK1.6或者更高版本 支持的数据库有:h2, mysql, oracle, postgres, mssql, db2等。 支持activiti5运行的jar包 开发环境为Eclipse3.7或者以上版本,myeclipse为8.6版本或以上版本 相关资源下载 JDK可以到sun的官网下载 http://www.oracle.com/technetwork/java/javase/downloads/index.html 数据库,例如:mysql可以在官网上下载。 http://www.mysql.com activiti也可以到Activiti官方网站下载得到。 http://activiti.org/download.html Eclipse3.7或者MyEclipse8.6也可以到相应的网站上获得下载。
  • 10. 北京传智播客教育 www.itcast.cn准备Activiti环境安装流程设计器(Eclipse插件 ) 在没有网络的情况下,安装流程设计器步骤如下: 解压老师发给大家的把压缩包中的内容放入eclipse根目录的dropins文件夹下
  • 11. 北京传智播客教育 www.itcast.cn准备Activiti环境重启eclipse,点击新建工程new->Other…打开面板,如果看到下图内容:
  • 12. 北京传智播客教育 www.itcast.cn准备Activiti环境准备JPBM的开发环境 1、${Activiti_HOME}/install/activiti-5.13/libs(核心包) 2、添加数据库对应的驱动的jar包 mysql-connector-java.jarJar包可以从: activiti-5.13\wars\activiti-rest\WEB-INF\lib中获取,可以去掉junit的jar包
  • 13. 北京传智播客教育 www.itcast.cn准备Activiti环境初始化数据库 方法一:执行sql脚本文件activiti-5.13\database\create\activiti.mysql.create.*.sql文件
  • 14. 北京传智播客教育 www.itcast.cn准备Activiti环境初始化数据库 方法二:使用代码: @Test public void createTable() { //1.创建Activiti配置对象的实例 ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration(); //2.设置数据库连接信息 // 设置数据库地址 configuration.setJdbcUrl("jdbc:mysql://localhost:3306/testactiviti?createDatabaseIfNotExist&useUnicode=true&characterEncoding=utf8"); // 数据库驱动 configuration.setJdbcDriver("com.mysql.jdbc.Driver"); // 用户名 configuration.setJdbcUsername("root"); // 密码 configuration.setJdbcPassword("root"); // 设置数据库建表策略 /** * DB_SCHEMA_UPDATE_TRUE:如果不存在表就创建表,存在就直接使用 * DB_SCHEMA_UPDATE_FALSE:如果不存在表就抛出异常 * DB_SCHEMA_UPDATE_CREATE_DROP:每次都先删除表,再创建新的表 */ configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); //3.使用配置对象创建流程引擎实例(检查数据库连接等环境信息是否正确) ProcessEngine processEngine = configuration.buildProcessEngine(); System.out.println(processEngine); }
  • 15. 北京传智播客教育 www.itcast.cn准备Activiti环境初始化数据库 方法三:使用配置文件:在类路径下创建Activiti.cfg.xml。
  • 16. 北京传智播客教育 www.itcast.cn准备Activiti环境初始化数据库 方法三:使用配置文件:在类路径下创建Activiti.cfg.xml。
  • 17. 北京传智播客教育 www.itcast.cn准备Activiti环境初始化数据库 方法三:使用配置文件:在类路径下创建Activiti.cfg.xml。 //测试流程引擎 @Test public void testDBByProperties() throws Exception { // 1。 加载classpath下名为activiti.cfg.xml文件,创建核心流程引擎对象 ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml").buildProcessEngine(); System.out.println(processEngine); }
  • 18. 北京传智播客教育 www.itcast.cn第一章:Activiti程序 ——HelloWorld
  • 19. 北京传智播客教育 www.itcast.cnJPBM程序——HelloWorld流程图
  • 20. 北京传智播客教育 www.itcast.cnActiviti程序——HelloWorld建表并创建流程引擎对象(核心对象) @Test public void testProcessEngine(){ // 获取流程引擎 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); System.out.println(processEngine); } 流程引擎(Activiti工作流核心对象)在前面看到了两种创建ProcessEngine(流程引擎)的方式,而这里要简化很多,调用ProcessEngines的getDefaultProceeEngine方法时会自动加载classpath下名为activiti.cfg.xml文件。
  • 21. 北京传智播客教育 www.itcast.cnActiviti程序——HelloWorld部署流程定义 @Test public void deploy() throws Exception { // 获取流程引擎 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); // 获取仓库服务的实例 Deployment deployment = processEngine.getRepositoryService()// .createDeployment()// .addClasspathResource("diagrams/Leave.bpmn")// .addClasspathResource("diagrams/Leave.png")// .deploy(); System.out.println(deployment.getId()+" "+deployment.getName()); }
  • 22. 北京传智播客教育 www.itcast.cnActiviti程序——HelloWorld启动流程实例 //2. 启动流程 @Test public void startProcess() throws Exception { // 获取流程引擎对象 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); // 启动流程 //使用流程定义的key启动流程实例,默认会按照最新版本启动流程实例 ProcessInstance pi = processEngine.getRuntimeService() .startProcessInstanceByKey("myProcess"); System.out.println("pid:" + pi.getId() +",activitiId:" + pi.getActivitiId()); }
  • 23. 北京传智播客教育 www.itcast.cnActiviti程序——HelloWorld查询我的任务列表(正在执行的任务) //3. 查看任务 @Test public void queryMyTask() throws Exception { // 指定任务办理者 String assignee = "张三"; // 获取流程引擎对象 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); // 查询任务的列表 List tasks = processEngine.getTaskService() .createTaskQuery()//创建任务查询对象 .taskAssignee(assignee)//指定个人任务办理人 .list(); // 遍历结合查看内容 for (Task task : tasks) { System.out.println("taskId:" + task.getId()+",taskName:" + task.getName()); System.out.println("*************************"); } }
  • 24. 北京传智播客教育 www.itcast.cnActiviti程序——HelloWorld办理任务 //4. 办理任务 @Test public void completeTask() throws Exception { String taskId = "104"; // 获取流程引擎对象 ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); // 完成任务 processEngine.getTaskService() .complete(taskId); System.out.println("完成任务!"); }
  • 25. 北京传智播客教育 www.itcast.cn第二章:流程定义管理CRUD
  • 26. 北京传智播客教育 www.itcast.cn流程定义管理CRUD流程图
  • 27. 北京传智播客教育 www.itcast.cn流程定义管理CRUD部署流程定义 // 部署(classpath) @Test public void deploy() throws Exception { // 获取仓库服务,完成部署 Deployment deployment = processEngine.getRepositoryService() .createDeployment() .name("请假流程")// 添加部署规则的显示别名 .addClasspathResource("diagrams/Leave.bpmn")// 添加定义的规则文件 .addClasspathResource("diagrams/Leave.png")// 添加定义的规则图片 .deploy();//完成发布 System.out.println(deployment.getId()+" "+deployment.getName()); } // 部署(zip) @Test public void testDeploy_zip() throws Exception { // 获得上传文件的输入流程 InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagrams/leave.zip"); ZipInputStream zipInputStream = new ZipInputStream(in); // 获取仓库服务,从类路径下完成部署 Deployment deployment = processEngine.getRepositoryService() .createDeployment() .name("请假流程")// 添加部署规则的显示别名 .addZipInputStream(zipInputStream)//使用zip的输入流完成部署 .deploy();//完成发布 System.out.println(deployment.getId()+" "+deployment.getName()); }
  • 28. 北京传智播客教育 www.itcast.cn流程定义管理CRUD查询流程定义 // 查询所有 @Test public void queryProcessDefinition() throws Exception { // 获取仓库服务对象,使用版本的升序排列,查询列表 List pdList = processEngine.getRepositoryService() .createProcessDefinitionQuery() //添加查询条件 //.processDefinitionName(processDefinitionName) //.processDefinitionId(processDefinitionId) //.processDefinitionKey(processDefinitionKey) //排序 .orderByProcessDefinitionVersion().asc() //查询的结果集 //.count()//返回结果集的数量 //.listPage(firstResult, maxResults)//分页查询 //.singleResult()//惟一结果集 .list();//总的结果集数量 // 遍历集合,查看内容 for (ProcessDefinition pd : pdList) { System.out.println("id:" + pd.getId()); System.out.println("name:" + pd.getName()); System.out.println("key:" + pd.getKey()); System.out.println("version:" + pd.getVersion()); System.out.println("resourceName:"+pd.getDiagramResourceName()); System.out.println("***************************************"); } }
  • 29. 北京传智播客教育 www.itcast.cn流程定义管理CRUD删除流程定义(使用部署流程定义ID) // 删除(使用流程定义ID) @Test public void deleteDeployment() throws Exception { // 删除发布信息 String deploymentId = "1"; // 获取仓库服务对象 RepositoryService repositoryService = processEngine.getRepositoryService(); // 普通删除,如果当前规则下有正在执行的流程,则抛异常 //repositoryService.deleteDeployment(deploymentId); // 级联删除,会删除和当前规则相关的所有信息,正在执行的信息,也包括历史信息 // 相当于:repositoryService.deleteDeploymentCascade(deploymentId); repositoryService.deleteDeployment(deploymentId, true); }
  • 30. 北京传智播客教育 www.itcast.cn流程定义管理CRUD查看流程定义的流程图 // 查看流程图(xxx.png) @Test public void showView() throws Exception { // 从仓库中找需要展示的文件 String deploymentId = "501"; List names = processEngine.getRepositoryService() .getDeploymentResourceNames(deploymentId); String imageName = ""; for (String name : names) { System.out.println("name:"+name); If(name.indexOf(".png")>=0){ imageName = name; } } System.out.println("imageName:"+imageName); if(imageName!=null){ //System.out.println(imageName); File f = new File("e:/"+ imageName); // 通过部署ID和文件名称得到文件的输入流 InputStream in = processEngine.getRepositoryService() .getResourceAsStream(deploymentId, imageName); FileUtils.copyInputStreamToFile(in, f); } }
  • 31. 北京传智播客教育 www.itcast.cn流程定义管理CRUD查询所有最新版本的流程定义 @Test public void queryAllLatestVersions() throws Exception { // 查询,把最大的版本都排到后面 List list = processEngine.getRepositoryService()// .createProcessDefinitionQuery()// .orderByProcessDefinitionVersion().asc()// .list(); // 过滤出最新的版本 Map map = new LinkedHashMap(); for (ProcessDefinition pd : list) { map.put(pd.getKey(), pd); } // 显示 for (ProcessDefinition pd : map.values()) { System.out.println("id:" + pd.getId()// 格式:{key}-{version} + ", name:" + pd.getName()// .jpdl.xml根元素的name属性的值 + ", key:" + pd.getKey()// .jpdl.xml根元素的key属性的值,如果不写,默认为name属性的值 + ", version:" + pd.getVersion()// 默认自动维护,第1个是1,以后相同key的都会自动加1 + ", deploymentId:" + pd.getDeploymentId()); // 所属的某个Deployment的对象 } }
  • 32. 北京传智播客教育 www.itcast.cn流程定义管理CRUD删除流程定义(删除key相同的所有不同版本的流程定义) @Test public void deleteByKey() throws Exception { // 1,查询指定key的所有版本的流程定义 List list = processEngine.getRepositoryService()// .createProcessDefinitionQuery()// .processDefinitionKey("myProcess")//指定流程定义的key查询 .list(); // 2,循环删除 for (ProcessDefinition pd : list) { processEngine.getRepositoryService()// .deleteDeployment(pd.getDeploymentId(), true); } System.out.println("删除成功!"); }
  • 33. 北京传智播客教育 www.itcast.cn流程定义管理CRUD流程定义中涉及到的Activiti表 Deployment 部署对象 1、一次部署的多个文件的信息。对于不需要的流程可以删除和修改。 2、对应的表: act_re_deployment:部署对象表 act_re_procdef:流程定义表 act_ge_bytearray:资源文件表 act_ge_property:主键生成策略表 ProcessDefinition 流程定义 1、解析.jpdl.xml后得到的流程定义规则的信息,工作流系统就是按照流程定义的规则执行的。
  • 34. 北京传智播客教育 www.itcast.cn第三章:流程实例、任务的执行
  • 35. 北京传智播客教育 www.itcast.cn流程实例的执行流程图
  • 36. 北京传智播客教育 www.itcast.cn流程实例的执行部署流程定义: @Test public void deployZIP() throws Exception { // 获得上传文件的输入流程 InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagrams/leave.zip"); ZipInputStream zipInputStream = new ZipInputStream(in); // 获取仓库服务,从类路径下完成部署 Deployment deployment = processEngine.getRepositoryService()// .createDeployment()// .name("请假流程")// 添加部署规则的显示别名 .addZipInputStream(zipInputStream)//使用zip的输入流完成部署 .deploy();//完成发布 System.out.println(deployment.getId()+" "+deployment.getName()); }
  • 37. 北京传智播客教育 www.itcast.cn流程实例的执行启动流程实例: // 启动流程实例 @Test public void startProcess() throws Exception { // 按照流程定义的id启动: myProcess:2:604 // runtimeService.startProcessInstanceById(processDefinitionId) // 通过流程定义的key启动流程,会启动版本最高的流程 ProcessInstance pi = ProcessEngines.getDefaultProcessEngine()// .getRuntimeService()//获取正在执行的Service .startProcessInstanceByKey("myProcess");//按照流程定义的key启动流程实例,默认按照最新版本启动 System.out.println("pid:" + pi.getId() +",activitiId:" + pi.getActivitiId()+",pdId:"+pi.getProcessDefinitionId()); }
  • 38. 北京传智播客教育 www.itcast.cn流程实例的执行查看我的任务列表: // 查看个人任务 @Test public void queryPersonalTask() throws Exception { // 配置查询对象 String assignee="张三"; // 创建任务查询对象,查询个人任务 List list = processEngine.getTaskService()// .createTaskQuery()// .taskAssignee(assignee)//指定个人任务的办理人查询任务 .orderByTaskCreateTime().desc()//按照任务创建时间升序排列 .list();//查询任务的所有记录 System.out.println("======================【"+assignee+"】的个人任务列表================="); for (Task task : list) { System.out.print("id:"+task.getId()+","); System.out.print("name:"+task.getName()+","); System.out.print("createTime:"+task.getCreateTime()+","); System.out.println("assignee:"+task.getAssignee()); } }
  • 39. 北京传智播客教育 www.itcast.cn流程实例的执行办理任务: // 办理任务 @Test public void complete() throws Exception { String taskId = "1102"; // 完成任务 processEngine.getTaskService()// .complete(taskId);//指定任务ID,完成任务 }
  • 40. 北京传智播客教育 www.itcast.cn流程实例的执行查看流程状态(判断流程是正在执行,还是已经结束): @Test public void queryProcessState() throws Exception { String processInstanceId="1201"; // 通过流程实例ID查询流程实例 ProcessInstance pi = processEngine.getRuntimeService() .createProcessInstanceQuery()//创建流程实例查询,查询正在执行的流程实例 .processInstanceId(processInstanceId)//按照流程实例ID查询 .singleResult();//返回惟一的结果集 if(pi!=null){ System.out.println("当前流程在:" + pi.getActivitiId()); }else{ System.out.println("流程已结束!!"); } }
  • 41. 北京传智播客教育 www.itcast.cn流程实例的执行查询历史任务: @Test public void queryHistoryTask() throws Exception { //历史任务办理人 String taskAssignee="张三"; // 使用办理人查询流程实例 List list = processEngine.getHistoryService()// .createHistoricTaskInstanceQuery()//创建历史任务查询 .taskAssignee(taskAssignee)//指定办理人查询历史任务 .list(); if(list!=null && list.size()>0){ for(HistoricTaskInstance task:list){ System.out.println("任务ID:"+task.getId()); System.out.println("流程实例ID:"+task.getProcessInstanceId()); System.out.println("任务的办理人:"+task.getAssignee()); System.out.println("执行对象ID:"+task.getExecutionId()); System.out.println(task.getStartTime()+" "+task.getEndTime()+" "+task.getDurationInMillis()); } } }
  • 42. 北京传智播客教育 www.itcast.cn流程实例的执行查询历史的流程实例: @Test public void queryHistoryProcessInstance() throws Exception { String processInstanceId = "1201"; HistoricProcessInstance hpi = processEngine.getHistoryService()// .createHistoricProcessInstanceQuery()//创建历史流程实例查询 .processInstanceId(processInstanceId)//使用流程实例ID查询 .singleResult(); System.out.println("流程定义ID:"+hpi.getProcessDefinitionId()); System.out.println("流程实例ID:"+hpi.getId()); System.out.println(hpi.getStartTime()+"    "+hpi.getEndTime()+" "+hpi.getDurationInMillis()); }
  • 43. 传智播客教育 www.itcast.cn流程实例的执行流程实例涉及的概念,及涉及到数据库表 Execution 执行对象 按流程定义的规则执行一次的过程. 对应的表: act_ru_execution: 正在执行的信息 act_hi_procinst:已经执行完的历史流程实例信息 act_hi_actinst:存放历史所有完成的活动 ProcessInstance 流程实例 特指流程从开始到结束的那个最大的执行分支,一个执行的流程中,流程实例只有1个。 注意 (1)如果是单例流程,执行对象ID就是流程实例ID (2)如果一个流程有分支和聚合,那么执行对象ID和流程实例ID就不相同 (3)一个流程中,流程实例只有1个,执行对象可以存在多个。 Task 任务 执行到某任务环节时生成的任务信息。 对应的表: act_ru_task:正在执行的任务信息 act_hi_taskinst:已经执行完的历史任务信息
  • 44. 北京传智播客教育 www.itcast.cn第四章:流程变量
  • 45. 北京传智播客教育 www.itcast.cn流程变量流程图
  • 46. 北京传智播客教育 www.itcast.cn流程变量概念 流程变量在整个工作流中扮演很重要的作用。 例如:请假流程中有请假天数、请假原因等一些参数都为流程变量的范围。 流程变量的作用域范围是流程实例。也就是说各个流程实例的流程变量是不相互影响的。 流程实例结束完成以后流程变量还保存在数据库中。 提交申请经理审批设置流程变量(名称/值) 获取流程变量 (针对流程变量的名称,获取流程变量的值
  • 47. 北京传智播客教育 www.itcast.cn流程变量输入流加载资源文件的3种方式 InputStream inputStream= this.getClass().getClassLoader().getResourceAsStream("diagrams/testVariables.bpmn"); InputStream inputStreamPng= this.getClass().getClassLoader().getResourceAsStream("diagrams/testVariables.png"); InputStream inputStream= this.getClass().getResourceAsStream("testVariables.bpmn"); InputStream inputStreamPng= this.getClass().getResourceAsStream("testVariables.png"); InputStream inputStream= this.getClass().getResourceAsStream("/diagrams/testVariables.bpmn"); InputStream inputStreamPng= this.getClass().getResourceAsStream("/diagrams/testVariables.png"); * this.getClass().getClassLoader().getResourceAsStream("testVariables.bpmn") 从classpath根目录下加载指定名称的文件 * this.getClass().getResourceAsStream("testVariables.bpmn") 从当前包下加载指定名称的文件 * this.getClass().getResourceAsStream("/testVariables.bpmn") 从classpath根目录下加载指定名称的文件
  • 48. 北京传智播客教育 www.itcast.cn流程变量/**部署流程定义*/ @Test public void deploy_inputstream() throws Exception { InputStream inputStream= this.getClass().getResourceAsStream("/diagrams/testVariables.bpmn"); InputStream inputStreamPng= this.getClass().getResourceAsStream("/diagrams/testVariables.png"); Deployment deployment = processEngine.getRepositoryService() .createDeployment() .name("审批流程(流程变量)") .addInputStream("testVariables.bpmn", inputStream) .addInputStream("testVariables.png", inputStreamPng) .deploy();// 发布流程 System.out.println(deployment.getId()+"   "+deployment.getName()); }部署流程定义:
  • 49. 北京传智播客教育 www.itcast.cn流程变量//启动流程 @Test public void startProcess() throws Exception { String processDefinitionKey ="myProcess"; // 在启动时设置流程变量 ProcessInstance pi = processEngine.getRuntimeService() .startProcessInstanceByKey(processDefinitionKey ); System.out.println("pid:" + pi.getId()); }启动流程实例:
  • 50. 北京传智播客教育 www.itcast.cn流程变量设置流程变量: /**设置流程变量*/ @Test public void setVariables(){ //获取执行的Service TaskService taskService = processEngine.getTaskService(); //指定办理人 String assigneeUser = "张三"; //流程实例ID String processInstanceId = "1701"; Task task = taskService.createTaskQuery()//创建任务查询 .taskAssignee(assigneeUser)//指定办理人 .processInstanceId(processInstanceId)//指定流程实例ID .singleResult(); /**一:变量中存放基本数据类型*/ //taskService.setVariable(task.getId(), "请假人", "张无忌");//使用流程变量的名称和流程变量的值设置流程变量,一次只能设置一个值 //taskService.setVariable(task.getId(), "请假天数", 3); //taskService.setVariable(task.getId(), "请假日期", new Date()); /**二:变量中存放javabean对象,前提:让javabean对象实现implements java.io.Serializable*/ Person p = new Person(); p.setId(1L); p.setName("翠花"); taskService.setVariable(task.getId(), "人员信息", p); }注意:Object对象需要实现: implements java.io.Serializable
  • 51. 北京传智播客教育 www.itcast.cn流程变量获取流程变量: /**获取流程变量*/ @Test public void getVariables(){ //获取执行的Service TaskService taskService = processEngine.getTaskService(); //指定办理人 String assigneeUser = "张三"; //流程实例ID String processInstanceId = "1701"; Task task = taskService.createTaskQuery()//创建任务查询 .taskAssignee(assigneeUser)//指定办理人 .processInstanceId(processInstanceId)//指定流程实例ID .singleResult(); /**一:变量中存放基本数据类型*/ //String stringValue = (String) taskService.getVariable(task.getId(), "请假人"); //Integer integerValue = (Integer) taskService.getVariable(task.getId(), "请假天数"); //Date dateValue = (Date) taskService.getVariable(task.getId(), "请假日期"); //System.out.println(stringValue+" "+integerValue+" "+dateValue); /**二:变量中存放javabean对象,前提:让javabean对象实现implements java.io.Serializable*/ /** * 获取流程变量时注意:流程变量如果是javabean对象,除了要求实现Serializable之外, * 同时要求流程变量对象的属性不能发生发生变化,否则抛出异常 * 解决方案:在设置流程变量的时候,在javabean的对象中使用: * private static final long serialVersionUID = -8065294171680448312L; */ Person p = (Person)taskService.getVariable(task.getId(), "人员信息"); System.out.println(p.getId()); System.out.println(p.getName()); }
  • 52. 北京传智播客教育 www.itcast.cn流程变量流程变量设置和获取实例场景: { RuntimeService runtimeService = processEngine.getRuntimeService(); TaskService taskService = processEngine.getTaskService(); // ======================================== // 设置变量的方法 // 通过Execution设置一个变量 runtimeService.setVariable(executionId, name, value); // 通过Execution设置多个变量 runtimeService.setVariables(executionId, variablesMap); // 通过Task设置一个变量 taskService.setVariable(taskId, variableName, value); // 通过Task设置多个变量 taskService.setVariables(taskId, variablesMap); // 在启动流程实例时,同时也设置一些流程变量 runtimeService.startProcessInstanceByKey(processDefinitionKey, variables); // 在完成任务时,同时也设置一些流程变量 taskService.complete(taskId, variables); // ======================================== // 获取变量的方法 // 通过Execution获取一个变量 runtimeService.getVariable(executionId, variableName); // 通过Execution获取所有变量的信息,存放到Map集合中 runtimeService.getVariables(executionId); // 通过Execution获取指定流程变量名称的变量值的信息,存放到Map集合中 runtimeService.getVariables(executionId, variableNames); // 通过Task获取一个变量 taskService.getVariable(taskId, variableName); // 通过Task获取所有变量的信息,存放到Map集合中 taskService.getVariables(taskId); // 通过Task获取指定流程变量名称的变量值的信息,存放到Map集合中 taskService.getVariables(taskId, variableNames); }
  • 53. 北京传智播客教育 www.itcast.cn流程变量扩展知识:setVariable和setVariableLocal的区别 setVariable:设置流程变量的时候,流程变量名称相同的时候,后一次的值替换前一次的值 setVariableLocal:设置流程变量的时候,针对当前活动的节点设置流程变量,如果一个流程中存在2个活动节点,对每个活动节点都设置流程变量,即使流程变量的名称相同,后一次的版本的值也不会替换前一次版本的值,它会使用不同的任务ID作为标识,存放2个流程变量值。 例如act_hi_varinst 表的数据:不同的任务节点,即使流程变量名称相同,存放的值也是不同的。获取历史流程变量值的方法: @Test public void getHisVariables(){ List list = processEngine.getHistoryService()// .createHistoricVariableInstanceQuery()// .variableName(“请假天数”)//指定流程变量名称查询 .list(); if(list!=null && list.size()>0){ for(HistoricVariableInstance hvi:list){ System.out.println(hvi.getVariableName()+" "+hvi.getValue()); } } }
  • 54. 北京传智播客教育 www.itcast.cn流程变量流程变量涉及的概念,及涉及到数据库表 流程变量 在流程执行或者任务执行的过程中,用于设置和获取变量,使用流程变量在流程传递的过程中传递业务参数。 对应的表: act_ru_variable:正在执行的流程变量表 act_hi_varinst:流程变量历史表
  • 55. 北京传智播客教育 www.itcast.cn第五章:查看流程历史记录
  • 56. 北京传智播客教育 www.itcast.cn查看流程历史记录查找按照某个流程定义的规则一共执行了多少次流程: //1 历史流程实例查看(查找按照某个规则一共执行了多少次流程) @Test public void queryHistoricProcessInstance() throws Exception { // 获取历史流程实例,返回历史流程实例的集合 List hpiList = processEngine.getHistoryService()// .createHistoricProcessInstanceQuery()//创建历史流程实例查询 .processDefinitionKey("myProcess")//按照流程定义的key查询 .orderByProcessInstanceStartTime().desc()//按照流程开始时间降序排列 .list();//返回结果集 // 遍历查看结果 for (HistoricProcessInstance hpi : hpiList) { System.out.print("pid:" + hpi.getId()+","); System.out.print("pdid:" + hpi.getProcessDefinitionId()+","); System.out.print("startTime:" + hpi.getStartTime()+","); System.out.print("endTime:" + hpi.getEndTime()+","); System.out.print("duration:" + hpi.getDurationInMillis()+","); System.out.println("------------------------"); } }
  • 57. 北京传智播客教育 www.itcast.cn查看流程历史记录某一次流程的执行一共经历的多少步 @Test public void queryHistoricActivitiInstance() throws Exception { String processInstanceId = "2401"; List haiList= processEngine.getHistoryService() .createHistoricActivitiInstanceQuery() // 创建历史活动实例查询 .processInstanceId(processInstanceId )// 使用流程实例id查询 //.listPage(firstResult, maxResults)// 分页条件 .orderByHistoricActivitiInstanceEndTime().asc()// 排序条件 .list();// 执行查询 for (HistoricActivitiInstance hai : haiList) { System.out.print("activitiId:" + hai.getActivitiId()+","); System.out.print("name:" + hai.getActivitiName()+","); System.out.print("type:" + hai.getActivitiType()+","); System.out.print("pid:" + hai.getProcessInstanceId()+","); System.out.print("assignee:" + hai.getAssignee()+","); System.out.print("startTime:" + hai.getStartTime()+","); System.out.print("endTime:" + hai.getEndTime()+","); System.out.println("duration:" + hai.getDurationInMillis()); } }
  • 58. 北京传智播客教育 www.itcast.cn查看流程历史记录某一次流程的执行经历的多少任务: //3 历史任务查看(某一次流程的执行经历的多少任务节点) @Test public void queryHistoricTask() throws Exception { String processInstanceId = "2401"; List htiList = processEngine.getHistoryService() .createHistoricTaskInstanceQuery()//创建历史任务的查询 .processInstanceId(processInstanceId )// 使用流程实例id查询 //.listPage(firstResult, maxResults)// 分页条件 .orderByHistoricTaskInstanceStartTime().asc()// 排序条件 .list();// 执行查询 for (HistoricTaskInstance hti : htiList) { System.out.print("taskId:" + hti.getId()+","); System.out.print("name:" + hti.getName()+","); System.out.print("pdId:" + hti.getProcessDefinitionId()+","); System.out.print("pid:" + hti.getProcessInstanceId()+","); System.out.print("assignee:" + hti.getAssignee()+","); System.out.print("startTime:" + hti.getStartTime()+","); System.out.print("endTime:" + hti.getEndTime()+","); System.out.println("duration:" + hti.getDurationInMillis()); } }
  • 59. 北京传智播客教育 www.itcast.cn查看流程历史记录某一次流程的执行时设置的流程变量: // 某一次流程的执行时设置的流程变量 @Test public void queryHistoricVariables(){ String processInstanceId = "2401"; List hviList = processEngine.getHistoryService()// .createHistoricVariableInstanceQuery()// 创建历史流程变量查询 .processInstanceId(processInstanceId) // 按照流程实例ID查询 .orderByVariableName().asc() // 排序条件 .list(); if(hviList!=null && hviList.size()>0){ for(HistoricVariableInstance hvi:hviList){ System.out.print("piId:"+hvi.getProcessInstanceId()+","); System.out.print("variablesName:"+hvi.getVariableName()+","); System.out.print("variablesValue:"+hvi.getValue()+","); } } }
  • 60. 北京传智播客教育 www.itcast.cn查看流程历史记录总结: 由于数据库中保存着历史信息以及正在运行的流程实例信息,在实际项目中对已完成任务的查看频率远不及对代办和可接任务的查看,所以在activiti采用分开管理,把正在运行的交给RuntimeService管理,而历史数据交给HistoryService来管理。
  • 61. 北京传智播客教育 www.itcast.cn第六章:连线
  • 62. 北京传智播客教育 www.itcast.cn连线流程图:
  • 63. 北京传智播客教育 www.itcast.cn注意:如果将流程图放置在和java类相同的路径,需要配置:在项目的target\classes下可以看到bpmn的文件:
  • 64. 北京传智播客教育 www.itcast.cn连线部署流程定义和启动流程实例: //部署流程定义,启动流程实例 @Test public void testSequenceFlow() throws Exception { // 1 发布流程 InputStream inputStreamBpmn = this.getClass().getResourceAsStream("sequenceProcess.bpmn"); InputStream inputStreamPng = this.getClass().getResourceAsStream("sequenceProcess.png"); processEngine.getRepositoryService()// .createDeployment()// .addInputStream("sequenceProcess.bpmn", inputStreamBpmn)// .addInputStream("sequenceProcess.png", inputStreamPng)// .deploy(); // 2 启动流程 ProcessInstance pi = processEngine.getRuntimeService()// .startProcessInstanceByKey("sequenceProcess"); System.out.println("pid:" + pi.getId()); }
  • 65. 北京传智播客教育 www.itcast.cn连线查询任务: @Test public void findMyTaskList(){ String userId = "赵六"; List list = processEngine.getTaskService()// .createTaskQuery()// .taskAssignee(userId)//指定个人任务查询 .list(); for(Task task:list ){ System.out.println("id="+task.getId()); System.out.println("name="+task.getName()); System.out.println("assinee="+task.getAssignee()); System.out.println("assinee="+task.getCreateTime()); System.out.println("executionId="+task.getExecutionId()); } }
  • 66. 北京传智播客教育 www.itcast.cn连线执行完第一个任务,使用流程变量,指定连线中定义的值,完成任务: //完成任务 @Test public void completeTask(){ String taskId = "6103"; //可以从页面上获取重要/不重要的选项,设置流程变量 Map variables = new HashMap(); variables.put("message", "重要"); processEngine.getTaskService()// .complete(taskId,variables);// System.out.println("完成任务"); }
  • 67. 北京传智播客教育 www.itcast.cn连线连线特点: 1、一个活动中可以指定一个或多个SequenceFlow(Start中有一个,End中没有)。 * 开始活动中有一个SequenceFlow 。 * 结束活动中没有SequenceFlow 。 * 其他活动中有1条或多条SequenceFlow 2、如果只有一个,则可以不使用流程变量设置codition的名称; 如果有多个,则需要使用流程变量设置codition的名称。message表示流程变量的名称,‘不重要’表示流程变量的值,${}中间的内容要使用boolean类型的表达式,用来判断应该执行的连线。
  • 68. 北京传智播客教育 www.itcast.cn第七章:活动节点*****
  • 69. 北京传智播客教育 www.itcast.cn活动(排他网关(ExclusiveGateWay) )流程图(判断):
  • 70. 北京传智播客教育 www.itcast.cn活动(排他网关(ExclusiveGateWay) )部署流程定义+启动流程实例: @Test public void testExclusiveGateWay() throws Exception { // 1 发布流程 InputStream inputStreamBpmn = this.getClass().getResourceAsStream("exclusiveProcess.bpmn"); InputStream inputStreamPng = this.getClass().getResourceAsStream("exclusiveProcess.png"); processEngine.getRepositoryService()// .createDeployment()// .addInputStream("exclusiveProcess.bpmn", inputStreamBpmn)// .addInputStream("exclusiveProcess.png", inputStreamPng)// .deploy(); // 2 启动流程 ProcessInstance pi = processEngine.getRuntimeService()// .startProcessInstanceByKey("exclusiveProcess"); System.out.println("pid:" + pi.getId()); }
  • 71. 北京传智播客教育 www.itcast.cn活动(排他网关(ExclusiveGateWay) )查询我的个人任务 //查询我的个人任务列表 @Test public void findMyTaskList(){ String userId = "王小五"; List list = processEngine.getTaskService()// .createTaskQuery()// .taskAssignee(userId)//指定个人任务查询 .list(); for(Task task:list ){ System.out.println("id="+task.getId()); System.out.println("name="+task.getName()); System.out.println("assinee="+task.getAssignee()); System.out.println("assinee="+task.getCreateTime()); System.out.println("executionId="+task.getExecutionId()); } }
  • 72. 北京传智播客教育 www.itcast.cn活动(排他网关(ExclusiveGateWay) )完成我的个人任务 //完成任务:使用流程变量设置报销的金额,由流程自动判断应该执行的哪条连线 @Test public void completeTask(){ String taskId = "7108"; //可以从页面上获取报销金额填写的值,设置流程变量,由流程判断应该执行哪条连线 Map variables = new HashMap(); variables.put("money", 200); processEngine.getTaskService()// .complete(taskId,variables);// System.out.println("完成任务"); }
  • 73. 北京传智播客教育 www.itcast.cn活动(并行网关(parallelGateWay) )流程图( 分支/聚合): 注意: 区分 执行对象ID 和 流程实例ID
  • 74. 北京传智播客教育 www.itcast.cn活动(并行网关(parallelGateWay) )分支/聚合: //部署流程定义,启动流程实例 @Test public void testParallelGateWay() throws Exception { // 1 发布流程 InputStream inputStreamBpmn = this.getClass().getResourceAsStream("parallelProcess.bpmn"); InputStream inputStreamPng = this.getClass().getResourceAsStream("parallelProcess.png"); processEngine.getRepositoryService()// .createDeployment()// .addInputStream("parallelProcess.bpmn", inputStreamBpmn)// .addInputStream("parallelProcess.png", inputStreamPng)// .deploy(); // 2 启动流程 ProcessInstance pi = processEngine.getRuntimeService()// .startProcessInstanceByKey("parallelProcess"); System.out.println("pid:" + pi.getId()); }
  • 75. 北京传智播客教育 www.itcast.cn活动(并行网关(parallelGateWay) )分支/聚合: //完成任务 @Test public void completeTask(){ String taskId = "7502"; processEngine.getTaskService()// .complete(taskId);// System.out.println("完成任务"); }
  • 76. 北京传智播客教育 www.itcast.cn活动开始活动节点:
  • 77. 北京传智播客教育 www.itcast.cn活动对于不需要查看流程图,只需装载流程的配置文件时: @Test public void testStart() throws Exception { InputStream inputStreamBPMN = this.getClass().getResourceAsStream("/diagrams/startProcess.bpmn"); InputStream inputStreamPNG = this.getClass().getResourceAsStream("/diagrams/startProcess.png"); //1.部署流程定义 processEngine.getRepositoryService()// .createDeployment()//创建部署对象 .addInputStream("startTest.bpmn", inputStreamBPMN)// 添加规则文件 .addInputStream("startTest.png", inputStreamPNG)// 添加规则图片 .deploy();// 发布流程 // 2 启动流程 String processDefinitionKey = "startTest"; ProcessInstance pi = processEngine.getRuntimeService()// .startProcessInstanceByKey(processDefinitionKey); System.out.println("pid:" +pi.getId()+",activitiId:" + pi.getActivitiId()+",ended:" + pi.isEnded()); String pid = pi.getId(); System.out.println("======="); //当流程已结束后,流程实例被删除,运行时服务对象不能查询 //pi = processEngine.getRuntimeService()// //.createProcessInstanceQuery()// //.processInstanceId(pid)// //.singleResult(); //System.out.println("pid:" +pi.getId()+",activitiId:" + pi.getActivitiId()+",ended:" + pi.isEnded()); //可以使用历史的记录查询 //HistoricProcessInstance hpi = processEngine.getHistoryService()// //.createHistoricProcessInstanceQuery()// //.processInstanceId(pid)// //.singleResult(); //System.out.println("pid:" +hpi.getId()); }
  • 78. 北京传智播客教育 www.itcast.cn活动总结: 1):结束节点没有出口 2):其他节点有一个或多个出口。 如果有一个出口,则代表是一个单线流程; 如果有多个出口,则代表是开启并发流程。
  • 79. 北京传智播客教育 www.itcast.cn活动接收任务节点 (receiveTask),即等待活动 :
  • 80. 北京传智播客教育 www.itcast.cn活动(receiveTask)测试代码: // 1 发布流程 InputStream inputStreamBpmn = this.getClass().getResourceAsStream("receiveTask.bpmn"); InputStream inputStreamPng = this.getClass().getResourceAsStream("receiveTask.png"); processEngine.getRepositoryService()// .createDeployment()// .addInputStream("receiveTask.bpmn", inputStreamBpmn)// .addInputStream("receiveTask.png", inputStreamPng)// .deploy(); // 2 启动流程 ProcessInstance pi = processEngine.getRuntimeService()// .startProcessInstanceByKey("receiveTaskDemo"); System.out.println("pid:" + pi.getId()); String pid = pi.getId();
  • 81. 北京传智播客教育 www.itcast.cn活动(receiveTask)测试代码: // 3查询是否有一个执行对象在描述”汇总当日销售额“ Execution e1 = processEngine.getRuntimeService()// .createExecutionQuery()// .processInstanceId(pid)// .ActivitiId("汇总当日销售额")// .singleResult(); // 4执行一堆逻辑,并设置流程变量 Map vars = new HashMap(); vars.put("当日销售额", 10000); // 5流程向后执行一步,同时设置流程变量:往后推移e1,使用signal给流程引擎信号,告诉他当前任务已经完成了,可以往后执行 processEngine.getRuntimeService() .signal(e1.getId(),vars);
  • 82. 北京传智播客教育 www.itcast.cn活动(receiveTask)测试代码: // 6判断当前流程是否在”给老板发短信“节点 Execution e2 = processEngine.getRuntimeService()// .createExecutionQuery()// .processInstanceId(pid)// .ActivitiId("给总经理发短信")// .singleResult(); // 7获取流程变量 Integer money = (Integer) processEngine.getRuntimeService()// .getVariable(e2.getId(), "当日销售额"); System.out.println("老板,今天赚了" +money); // 8向后执行一步:任务完成,往后推移”给老板发短信“任务 processEngine.getRuntimeService()// .signal(e2.getId()); // 9查询流程状态 pi = processEngine.getRuntimeService()// .createProcessInstanceQuery()// .processInstanceId(pid)// .singleResult(); if(pi==null){ System.out.println(“流程结束”); }
  • 83. 北京传智播客教育 www.itcast.cn活动个人任务流程图( personal):
  • 84. 北京传智播客教育 www.itcast.cn个人任务(personal)个人任务,方法一,指定办理人: //部署流程定义,启动流程实例 @Test public void test(){ URL url = this.getClass().getResource("test.jpdl.xml"); String deploymentID = processEngine.getRepositoryService()// .createDeployment()// .addResourceFromUrl(url)// .deploy(); System.out.println("部署流程定义成功!deploymentID"+deploymentID); ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("test"); System.out.println("启动流程实例成功!id="+pi.getId()); }
  • 85. 北京传智播客教育 www.itcast.cn个人任务(personal)个人任务,查询个人任务: //查询我的个人任务列表 @Test public void findMyTaskList(){ String userId = "张三丰"; List list = processEngine.getTaskService()// .createTaskQuery()// .taskAssignee(userId)//指定个人任务查询 .list(); for(Task task:list ){ System.out.println("id="+task.getId()); System.out.println("name="+task.getName()); System.out.println("assinee="+task.getAssignee()); System.out.println("assinee="+task.getCreateTime()); System.out.println("executionId="+task.getExecutionId()); } }
  • 86. 北京传智播客教育 www.itcast.cn个人任务(personal)个人任务,完成任务: //完成任务 @Test public void completeTask(){ String taskId = "3508"; processEngine.getTaskService()// .complete(taskId);// System.out.println("完成任务"); }
  • 87. 北京传智播客教育 www.itcast.cn个人任务(personal)个人任务,方法二,指定办理人: //部署流程定义,启动流程实例 @Test public void testTask() throws Exception { // 1 发布流程 InputStream inputStreamBpmn = this.getClass().getResourceAsStream("taskProcess.bpmn"); InputStream inputStreamPng = this.getClass().getResourceAsStream("taskProcess.png"); processEngine.getRepositoryService()// .createDeployment()// .addInputStream("userTask.bpmn", inputStreamBpmn)// .addInputStream("userTask.png", inputStreamPng)// .deploy(); // 2 启动流程 //启动流程实例的同时,设置流程变量,用来指定个人任务的办理人 Map variables = new HashMap(); variables.put(“userID”, “张翠山"); ProcessInstance pi = processEngine.getRuntimeService()// .startProcessInstanceByKey("taskProcess",variables); System.out.println("pid:" + pi.getId()); }
  • 88. 北京传智播客教育 www.itcast.cn个人任务(personal)个人任务,方法三,指定办理人: //部署流程定义,启动流程实例 @Test public void testTask() throws Exception { // 1 发布流程 InputStream inputStreamBpmn = this.getClass().getResourceAsStream("taskProcess.bpmn"); InputStream inputStreamPng = this.getClass().getResourceAsStream("taskProcess.png"); processEngine.getRepositoryService()// .createDeployment()// .addInputStream("userTask.bpmn", inputStreamBpmn)// .addInputStream("userTask.png", inputStreamPng)// .deploy(); // 2 启动流程 ProcessInstance pi = processEngine.getRuntimeService()// .startProcessInstanceByKey("taskProcess"); System.out.println("pid:" + pi.getId()); }
  • 89. 北京传智播客教育 www.itcast.cn个人任务(personal)个人任务,方法三,指定办理人: taskProcess.bpmn:
  • 90. 北京传智播客教育 www.itcast.cn个人任务(personal)个人任务,方法三,指定办理人: public class TaskListenerImpl implements TaskListener { /**指定个人任务和组任务的办理人*/ @Override public void notify(DelegateTask delegateTask) { String assignee = "张无忌"; //指定个人任务 delegateTask.setAssignee(assignee); } }
  • 91. 北京传智播客教育 www.itcast.cn个人任务(personal)可以分配个人任务从一个人到另一个人//可以分配个人任务从一个人到另一个人 @Test public void setAssigneeTask(){ //任务ID String taskId = "4108"; //指定任务的办理者 String userId = "周芷若"; processEngine.getTaskService()// .setAssignee(taskId, userId); }
  • 92. 北京传智播客教育 www.itcast.cn个人任务(personal)分配个人任务总结个人任务及三种分配方式: 1:在taskProcess.bpmn中直接写 assignee=“张三丰" 2:在taskProcess.bpmn中写 assignee=“#{userID}”,变量的值要是String的。 使用流程变量指定办理人 3,使用TaskListener接口,要使类实现该接口,在类中定义: delegateTask.setAssignee(assignee);// 指定个人任务的办理人 使用任务ID和办理人重新指定办理人: processEngine.getTaskService()// .setAssignee(taskId, userId);
  • 93. 北京传智播客教育 www.itcast.cn组任务(group)流程图(group):
  • 94. 北京传智播客教育 www.itcast.cn组任务(group)组任务,方法一,指定办理人: //部署流程定义,启动流程实例 @Test public void testTask() throws Exception { // 1 发布流程 InputStream inputStreamBpmn = this.getClass().getResourceAsStream("taskProcess.bpmn"); InputStream inputStreamPng = this.getClass().getResourceAsStream("taskProcess.png"); processEngine.getRepositoryService()// .createDeployment()// .addInputStream("userTask.bpmn", inputStreamBpmn)// .addInputStream("userTask.png", inputStreamPng)// .deploy(); // 2 启动流程 ProcessInstance pi = processEngine.getRuntimeService()// .startProcessInstanceByKey("taskProcess"); System.out.println("pid:" + pi.getId()); }
  • 95. 北京传智播客教育 www.itcast.cn组任务(group)查询个人任务列表: //查询我的个人任务列表 @Test public void findMyTaskList(){ String userId = "张翠三"; List list = processEngine.getTaskService()// .createTaskQuery()// .taskAssignee(userId)//指定个人任务查询 .list(); for(Task task:list ){ System.out.println("id="+task.getId()); System.out.println("name="+task.getName()); System.out.println("assinee="+task.getAssignee()); System.out.println("assinee="+task.getCreateTime()); System.out.println("executionId="+task.getExecutionId()); } }
  • 96. 北京传智播客教育 www.itcast.cn组任务(group)查询组任务列表: @Test public void findGroupList(){ String userId = "小A"; List list = processEngine.getTaskService()// .createTaskQuery()// .taskCandidateUser(userId)//指定组任务查询 .list(); for(Task task:list ){ System.out.println("id="+task.getId()); System.out.println("name="+task.getName()); System.out.println("assinee="+task.getAssignee()); System.out.println("assinee="+task.getCreateTime()); System.out.println("executionId="+task.getExecutionId()); } }
  • 97. 北京传智播客教育 www.itcast.cn组任务(group)查询组任务成员列表: //查询组任务成员列表 @Test public void findGroupUser(){ String taskId = "4408"; List list = processEngine.getTaskService()// .getIdentityLinksForTask(taskId); for(IdentityLink identityLink:list ){ System.out.println("userId="+identityLink.getUserId()); System.out.println("taskId="+identityLink.getTaskId()); System.out.println("piId="+identityLink.getProcessInstanceId()); System.out.println("######################"); } }
  • 98. 北京传智播客教育 www.itcast.cn组任务(group)查询组任务历史成员列表: //查询组任务成员历史列表 @Test public void findGroupHisUser(){ String taskId = "3709"; List list = processEngine.getHistoryService()// .getHistoricIdentityLinksForTask(taskId); for(HistoricIdentityLink identityLink:list ){ System.out.println("userId="+identityLink.getUserId()); System.out.println("taskId="+identityLink.getTaskId()); System.out.println("piId="+identityLink.getProcessInstanceId()); System.out.println("######################"); } }
  • 99. 北京传智播客教育 www.itcast.cn组任务(group)组任务,方法二,指定办理人: //部署流程定义,启动流程实例 @Test public void testTask() throws Exception { // 1 发布流程 InputStream inputStreamBpmn = this.getClass().getResourceAsStream("taskProcess.bpmn"); InputStream inputStreamPng = this.getClass().getResourceAsStream("taskProcess.png"); processEngine.getRepositoryService()// .createDeployment()// .addInputStream("userTask.bpmn", inputStreamBpmn)// .addInputStream("userTask.png", inputStreamPng)// .deploy(); // 2 启动流程 //启动流程实例,同时设置流程变量,用来指定组任务的办理人 Map variables = new HashMap(); variables.put("userIDs", "大大,小小,中中"); ProcessInstance pi = processEngine.getRuntimeService()// .startProcessInstanceByKey("taskProcess",variables); System.out.println("pid:" + pi.getId()); }
  • 100. 北京传智播客教育 www.itcast.cn组任务(group)组任务,方法三,指定办理人: //部署流程定义,启动流程实例 @Test public void testTask() throws Exception { // 1 发布流程 InputStream inputStreamBpmn = this.getClass().getResourceAsStream("taskProcess.bpmn"); InputStream inputStreamPng = this.getClass().getResourceAsStream("taskProcess.png"); processEngine.getRepositoryService()// .createDeployment()// .addInputStream("userTask.bpmn", inputStreamBpmn)// .addInputStream("userTask.png", inputStreamPng)// .deploy(); // 2 启动流程 ProcessInstance pi = processEngine.getRuntimeService()// .startProcessInstanceByKey("taskProcess"); System.out.println("pid:" + pi.getId()); }
  • 101. 北京传智播客教育 www.itcast.cn组任务(group)组任务,方法三,指定办理人: taskProcess.bpmn:
  • 102. 北京传智播客教育 www.itcast.cn组任务(group)组任务,方法三,指定办理人: @SuppressWarnings("serial") public class TaskListenerImpl implements TaskListener { /**指定个人任务和组任务的办理人*/ @Override public void notify(DelegateTask delegateTask) { String userId1 = "孙悟空"; String userId2 = "猪八戒"; //指定组任务 delegateTask.addCandidateUser(userId1); delegateTask.addCandidateUser(userId2); } }
  • 103. 北京传智播客教育 www.itcast.cn组任务(group)将组任务分配给个人任务(认领任务): //将组任务分配给个人任务(认领任务) @Test public void claimTask(){ String taskId = "5108"; //个人任务的办理人 String userId = "唐僧"; processEngine.getTaskService().claim(taskId, userId); }
  • 104. 北京传智播客教育 www.itcast.cn组任务(group)将个人任务分配给组任务: //可以分配个人任务回退到组任务,(前提:之前是个组任务) @Test public void setAssigneeTask(){ //任务ID String taskId = "5108"; processEngine.getTaskService()// .setAssignee(taskId, null); }
  • 105. 北京传智播客教育 www.itcast.cn组任务(group)向组任务中添加人员: @Test public void addUser(){ String taskId = "5108"; String userId = "沙和尚"; processEngine.getTaskService().addCandidateUser(taskId, userId); }向组任务中删除人员: @Test public void removeUser(){ String taskId = "5108"; String userId = "沙和尚"; processEngine.getTaskService().deleteCandidateUser(taskId, userId); }
  • 106. 北京传智播客教育 www.itcast.cn组任务(group)分配组任务总结组任务及三种分配方式: 1:在taskProcess.bpmn中直接写 candidate-users=“小A,小B,小C,小D" 2:在taskProcess.bpmn中写 candidate-users =“#{userIDs}”,变量的值要是String的。 使用流程变量指定办理人 Map variables = new HashMap(); variables.put("userIDs", "大大,小小,中中"); 3,使用TaskListener接口,使用类实现该接口,在类中定义: //添加组任务的用户 delegateTask.addCandidateUser(userId1); delegateTask.addCandidateUser(userId2); 组任务分配给个人任务(认领任务): processEngine.getTaskService().claim(taskId, userId); 个人任务分配给组任务: processEngine.getTaskService(). setAssignee(taskId, null); 向组任务添加人员: processEngine.getTaskService().addCandidateUser(taskId, userId); 向组任务删除人员: processEngine.getTaskService().deleteCandidateUser(taskId, userId); 组任务对应的表: #存放组任务的办理人:act_ru_identitylink #存放历史组任务的办理人:act_hi_identitylink
  • 107. 北京传智播客教育 www.itcast.cn组任务(group)activiti工作流的角色分配任务负责的组分配任务负责的组 使用 candidate groups 属性指定 任务负责组 代码:
  • 108. 北京传智播客教育 www.itcast.cn组任务(group)activiti工作流的角色分配任务负责的组代码: /**在部署流程定义和启动流程实例的中间,设置组任务的办理人,向Activiti表中存放组和用户的信息*/ IdentityService identityService = processEngine.getIdentityService();//认证:保存组和用户信息 identityService.saveGroup(new GroupEntity("部门经理"));//建立组 identityService.saveGroup(new GroupEntity("总经理"));//建立组 identityService.saveUser(new UserEntity(“小张”));//建立用户 identityService.saveUser(new UserEntity("小李")); //建立用户 identityService.saveUser(new UserEntity("小王")); //建立用户 identityService.createMembership("小张", "部门经理");//建立组和用户关系 identityService.createMembership("小李", "部门经理");//建立组和用户关系 identityService.createMembership(“小王”, “总经理”);//建立组和用户关系 表结构介绍 act_id_group:角色组表 act_id_user:用户表: act_id_membership:用户角色表 指定组任务的办理人 String userId = “小张”;//小张,小李可以查询结果,小王不可以,因为他不是部门经理角色 List list = processEngine.getTaskService()// .createTaskQuery()// .taskCandidateUser(userId)//指定组任务查询 .list();
  • 109. 北京传智播客教育 www.itcast.cnActiviti工作流结束