玉溪市网站建设_网站建设公司_网站建设_seo优化
2025/12/17 21:54:23 网站建设 项目流程

文章目录

    • 1、流程定义
      • 1.1、概述
      • 1.2、.bpmn文件
    • 2、流程定义部署
      • 2.1、概述
      • 2.2、单个文件部署方式
      • 2.3、压缩包部署方式
      • 2.4、操作数据表
    • 3、启动流程实例
      • 3.1、概述
      • 3.2、操作数据表
    • 4、任务查询
    • 5、流程任务处理
    • 6、流程定义信息查询
    • 7、流程删除
    • 8、流程资源下载
    • 9、流程历史信息的查看

1、流程定义

1.1、概述

流程定义是线下按照bpmn2.0标准去描述 业务流程,通常使用idea中的插件对业务流程进行建模。

使用idea下的designer设计器绘制流程,并会生成两个文件:.bpmn和.png

1.2、.bpmn文件

使用activiti-desinger设计业务流程,会生成.bpmn文件,上面我们已经创建好了bpmn文件

BPMN 2.0根节点是definitions节点。 这个元素中,可以定义多个流程定义(不过我们建议每个文件只包含一个流程定义, 可以简化开发过程中的维护难度)。 注意,definitions元素 最少也要包含xmlns 和 targetNamespace的声明。 targetNamespace可以是任意值,它用来对流程实例进行分类。

流程定义部分:定义了流程每个结点的描述及结点之间的流程流转。

流程布局定义:定义流程每个结点在流程图上的位置坐标等信息。

2、流程定义部署

2.1、概述

将上面在设计器中定义的流程部署到activiti数据库中,就是流程定义部署。

通过调用activiti的api将流程定义的bpmn和png两个文件一个一个添加部署到activiti中,也可以将两个文件打成zip包进行部署。

执行此操作后activiti会将上边代码中指定的bpm文件和图片文件保存在activiti数据库。

2.2、单个文件部署方式

分别将bpmn文件和png图片文件部署。

```java/** * 部署流程定义 */@TestpublicvoidtestDeployment(){// 1、创建ProcessEngineProcessEngineprocessEngine=ProcessEngines.getDefaultProcessEngine();// 2、得到RepositoryService实例RepositoryServicerepositoryService=processEngine.getRepositoryService();// 3、使用RepositoryService进行部署Deploymentdeployment=repositoryService.createDeployment().addClasspathResource("bpmn/evection-uel.bpmn")// 添加bpmn资源//.addClasspathResource("bpmn/evection.png") // 添加png资源.name("请假申请流程uel").deploy();// 4、输出部署信息System.out.println("流程部署id:"+deployment.getId());System.out.println("流程部署名称:"+deployment.getName());}

2.3、压缩包部署方式

将evection.bpmn和evection.png压缩成zip包。

@TestpublicvoiddeployProcessByZip(){ProcessEngineprocessEngine=ProcessEngines.getDefaultProcessEngine();// 定义zip输入流InputStreaminputStream=this.getClass().getClassLoader().getResourceAsStream("bpmn/evection.zip");ZipInputStreamzipInputStream=newZipInputStream(inputStream);// 获取repositoryServiceRepositoryServicerepositoryService=processEngine.getRepositoryService();// 流程部署Deploymentdeployment=repositoryService.createDeployment().addZipInputStream(zipInputStream).deploy();System.out.println("流程部署id:"+deployment.getId());System.out.println("流程部署名称:"+deployment.getName());}

执行此操作后activiti会将上边代码中指定的bpm文件和图片文件保存在activiti数据库

2.4、操作数据表

流程定义部署后操作activiti的3张表如下:

流程定义部署操作的三张表名描述
act_re_deployment流程定义部署表,每部署一次增加一条记录
act_re_procdef流程定义表,部署每个新的流程定义都会在这张表中增加一条记录
act_ge_bytearray流程资源表
SELECT*FROMact_re_deployment#流程定义部署表,记录流程部署信息

结果:

SELECT*FROMact_re_procdef#流程定义表,记录流程定义信息

结果:

SELECT*FROMact_ge_bytearray#资源表

结果:

注意:act_re_deployment和act_re_procdef一对多关系,一次部署在流程部署表生成一条记录,但一次部署可以部署多个流程定义,每个流程定义在流程定义表生成一条记录。每一个流程定义在act_ge_bytearray会存在两个资源记录,bpmn和png。

建议:一次部署一个流程,这样部署表和流程定义表是一对一有关系,方便读取流程部署及流程定义信息。

3、启动流程实例

3.1、概述

流程定义部署在activiti后就可以通过工作流管理业务流程了,也就是说上边部署的出差申请流程可以使用了。

针对该流程,启动一个流程表示发起一个新的出差申请单,这就相当于java类与java对象的关系,类定义好后需要new创建一个对象使用,当然可以new多个对象。对于请出差申请流程,张三发起一个出差申请单需要启动一个流程实例,出差申请单发起一个出差单也需要启动一个流程实例。

代码如下:

/** * 启动流程实例 */@TestpublicvoidtestStartProcess(){// 1、创建ProcessEngineProcessEngineprocessEngine=ProcessEngines.getDefaultProcessEngine();// 2、获取RunTimeServiceRuntimeServiceruntimeService=processEngine.getRuntimeService();// 3、根据流程定义Id启动流程ProcessInstanceprocessInstance=runtimeService.startProcessInstanceByKey("myEvection");// 输出内容System.out.println("流程定义id:"+processInstance.getProcessDefinitionId());System.out.println("流程实例id:"+processInstance.getId());System.out.println("当前活动Id:"+processInstance.getActivityId());}

输出内容如下:

3.2、操作数据表

启动流程实例操作的7张表:

启动流程实例操作的7张表名描述
act_hi_actinst流程实例执行历史
act_hi_identitylink流程的参与用户历史信息
act_hi_procinst流程实例历史信息
act_hi_taskinst流程任务历史信息
act_ru_execution流程执行信息
act_ru_identitylink流程的参与用户信息
act_ru_task任务信息

4、任务查询

流程启动后,任务的负责人就可以查询自己当前需要处理的任务,查询出来的任务都是该用户的待办任务。

/** * 查询当前个人待执行的任务 */@TestpublicvoidtestFindPersonalTaskList(){// 任务负责人Stringassignee="zhangsan";ProcessEngineprocessEngine=ProcessEngines.getDefaultProcessEngine();// 创建TaskServiceTaskServicetaskService=processEngine.getTaskService();// 根据流程key 和 任务负责人 查询任务List<Task>list=taskService.createTaskQuery().processDefinitionKey("myEvection")//流程Key.taskAssignee(assignee)//只查询该任务负责人的任务.list();for(Tasktask:list){System.out.println("流程实例id:"+task.getProcessInstanceId());System.out.println("任务id:"+task.getId());System.out.println("任务负责人:"+task.getAssignee());System.out.println("任务名称:"+task.getName());}}

结果如下:

流程实例id:52501 任务id:52505 任务负责人:zhangsan 任务名称:创建出差申请

5、流程任务处理

任务负责人查询待办任务,选择任务进行处理,完成任务。

// 完成任务@TestpublicvoidcompletTask(){// 获取引擎ProcessEngineprocessEngine=ProcessEngines.getDefaultProcessEngine();// 获取taskServiceTaskServicetaskService=processEngine.getTaskService();// 根据流程key 和 任务的负责人 查询任务// 返回一个任务对象List<Task>list=taskService.createTaskQuery().processDefinitionKey("myEvection")//流程Key.taskAssignee("zhangsan")//要查询的负责人.list();for(Tasktask:list){// 完成任务,参数:任务idtaskService.complete(task.getId());}}

6、流程定义信息查询

查询流程相关信息,包含流程定义,流程部署,流程定义版本

/** * 查询流程定义 */@TestpublicvoidqueryProcessDefinition(){// 获取引擎ProcessEngineprocessEngine=ProcessEngines.getDefaultProcessEngine();// repositoryServiceRepositoryServicerepositoryService=processEngine.getRepositoryService();// 得到ProcessDefinitionQuery 对象ProcessDefinitionQueryprocessDefinitionQuery=repositoryService.createProcessDefinitionQuery();// 查询出当前所有的流程定义// 条件:processDefinitionKey =evection// orderByProcessDefinitionVersion 按照版本排序// desc倒叙// list 返回集合List<ProcessDefinition>definitionList=processDefinitionQuery.processDefinitionKey("myEvection").orderByProcessDefinitionVersion().desc().list();// 输出流程定义信息for(ProcessDefinitionprocessDefinition:definitionList){System.out.println("流程定义 id="+processDefinition.getId());System.out.println("流程定义 name="+processDefinition.getName());System.out.println("流程定义 key="+processDefinition.getKey());System.out.println("流程定义 Version="+processDefinition.getVersion());System.out.println("流程部署ID ="+processDefinition.getDeploymentId());}}

输出结果:

流程定义id=myEvection:2:27504 流程定义name=出差申请 流程定义key=myEvection 流程定义Version=2流程部署ID=27501流程定义id=myEvection:1:12504 流程定义name=出差申请 流程定义key=myEvection 流程定义Version=1流程部署ID=12501

7、流程删除

/** * 流程删除 */@TestpublicvoiddeleteDeployment(){// 流程部署idStringdeploymentId="7501";ProcessEngineprocessEngine=ProcessEngines.getDefaultProcessEngine();// 通过流程引擎获取repositoryServiceRepositoryServicerepositoryService=processEngine.getRepositoryService();//删除流程定义,如果该流程定义已有流程实例启动则删除时出错// repositoryService.deleteDeployment(deploymentId);//设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置为false非级别删除方式,如果流程repositoryService.deleteDeployment(deploymentId,true);}

说明:

  1. 使用repositoryService删除流程定义,历史表信息不会被删除

  2. 如果该流程定义下没有正在运行的流程,则可以用普通删除。

如果该流程定义下存在已经运行的流程,使用普通删除报错,可用级联删除方法将流程及相关记录全部删除。

先删除没有完成流程节点,最后就可以完全删除流程定义信息

项目开发中级联删除操作一般只开放给超级管理员使用.

8、流程资源下载

流程资源文件已经上传到数据库了,如果其他用户想要查看这些资源文件,可以从数据库中把资源文件下载到本地。

解决方案有:

  1. jdbc对blob类型,clob类型数据读取出来,保存到文件目录

  2. 使用activiti的api来实现

使用commons-io.jar 解决IO的操作

引入commons-io依赖包

<dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version></dependency>

通过流程定义对象获取流程定义资源,获取bpmn和png

/** * 流程资源下载 * @throws IOException */@TestpublicvoidqueryBpmnFile()throwsIOException{// 1、得到引擎ProcessEngineprocessEngine=ProcessEngines.getDefaultProcessEngine();// 2、获取repositoryServiceRepositoryServicerepositoryService=processEngine.getRepositoryService();// 3、得到查询器:ProcessDefinitionQuery,设置查询条件,得到想要的流程定义ProcessDefinitionprocessDefinition=repositoryService.createProcessDefinitionQuery().processDefinitionKey("myEvection").latestVersion().singleResult();// 4、通过流程定义信息,得到部署IDStringdeploymentId=processDefinition.getDeploymentId();// 5、通过repositoryService的方法,实现读取图片信息和bpmn信息// png图片的流InputStreampngInput=repositoryService.getResourceAsStream(deploymentId,processDefinition.getDiagramResourceName());// bpmn文件的流InputStreambpmnInput=repositoryService.getResourceAsStream(deploymentId,processDefinition.getResourceName());// 6、构造OutputStream流Filefile_png=newFile("g:/evectionflow01.png");Filefile_bpmn=newFile("g:/evectionflow01.bpmn");FileOutputStreambpmnOut=newFileOutputStream(file_bpmn);FileOutputStreampngOut=newFileOutputStream(file_png);// 7、输入流,输出流的转换IOUtils.copy(pngInput,pngOut);IOUtils.copy(bpmnInput,bpmnOut);// 8、关闭流pngOut.close();bpmnOut.close();pngInput.close();bpmnInput.close();}

说明:

  1. deploymentId为流程部署ID

  2. esource_name为act_ge_bytearray表中NAME_列的值

  3. 使用repositoryService的getDeploymentResourceNames方法可以获取指定部署下得所有文件的名称

  4. 使用repositoryService的getResourceAsStream方法传入部署ID和资源图片名称可以获取部署下指定名称文件的输入流

最后的将输入流中的图片资源进行输出。

9、流程历史信息的查看

即使流程定义已经删除了,流程执行的历史信息通过前面的分析,依然保存在activiti的act_hi_*相关的表中。所以我们还是可以查询流程执行的历史信息,可以通过HistoryService来查看相关的历史记录。

/** * 查看历史信息 */@TestpublicvoidfindHistoryInfo(){// 获取引擎ProcessEngineprocessEngine=ProcessEngines.getDefaultProcessEngine();// 获取HistoryServiceHistoryServicehistoryService=processEngine.getHistoryService();// 获取 actinst表的查询对象HistoricActivityInstanceQueryinstanceQuery=historyService.createHistoricActivityInstanceQuery();// 查询 actinst表,条件:根据 InstanceId 查询// instanceQuery.processInstanceId("2501");// 查询 actinst表,条件:根据 DefinitionId 查询instanceQuery.processDefinitionId("myEvection:1:12504");// 增加排序操作,orderByHistoricActivityInstanceStartTime 根据开始时间排序 asc 升序instanceQuery.orderByHistoricActivityInstanceStartTime().asc();// 查询所有内容List<HistoricActivityInstance>activityInstanceList=instanceQuery.list();// 输出for(HistoricActivityInstancehi:activityInstanceList){System.out.println(hi.getActivityId());System.out.println(hi.getActivityName());System.out.println(hi.getProcessDefinitionId());System.out.println(hi.getProcessInstanceId());System.out.println("<==========================>");}}

结果输出如下:

_2 StartEvent myEvection:1:1250415001<==========================>_3 创建出差申请 myEvection:1:1250415001<==========================>


“人的一生会经历很多痛苦,但回头想想,都是传奇”。


需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询