( 四 )、Activiti 流程定义操作

( 四 )、Activiti 流程定义操作

 

 

 

一、什么是流程定义

  流程定义是线下按照 bpmn2.0 标准去描述 业务流程,通常使用 activiti-explorer(web 控制台)或 activiti-eclipse-designer 插件对业务流程进行建模,这两种方式都遵循 bpmn2.0 标准。本教程使用activiti-eclipse-designer 插件完成流程建模。使用 designer 设计器绘制流程,会生成两个文件:.bpmn和.png。

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

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

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

二、流程定义部署

2.1、什么是流程定义部署

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

2.2、流程定义部署的方式

 1、单个文件部署:

 @Test
    public void deployProcess() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        Deployment deploy = repositoryService.createDeployment().
                addClasspathResource("bpmn/holiday.bpmn20.xml").
                addClasspathResource("bpmn/holiday.bpmn20.png").
                name("请假申请流程").deploy();
        System.out.println("流程部署id:"+deploy.getId());
        System.out.println("流程部署名称:"+deploy.getName());
        System.out.println("流程部署key:"+deploy.getKey());

    }

2、压缩包部署:

  @Test
    public void deployProcess2() {
        //1.创建ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.得到RepositoryService实例
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3.转化出ZipInputStream流对象
        InputStream is = this.getClass.getClassLoader().getResourceAsStream("diagram/holidayBPMN.zip");
        //将 inputstream流转化为ZipInputStream流
        ZipInputStream zipInputStream = new ZipInputStream(is);
        //3.进行部署
        Deployment deployment = repositoryService.createDeployment()
                .addZipInputStream(zipInputStream)
                .name("请假申请单流程")
                .deploy();
        //4.输出部署的一些信息
        System.out.println(deployment.getName());
        System.out.println(deployment.getId());
    }

3、启动项目时自动部署

spring:
 activiti:
    #默认true,效验流程文件,默认效验resources下的processes文件夹里的流程,为true自动部署流程,为false则不部署
      check-process-definitions: true
    # 流程文件存放目录
      process-definition-location-prefix: classpath:/processes/

 

三、流程定义查询

  @Test
    public void queryProcessDefinition(){
        //1.得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        //2.创建RepositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();

        //3.得到ProcessDefinitionQuery对象,可以认为它就是一个查询器
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();

        //4.设置条件,并查询出当前的所有流程定义   查询条件:流程定义的key=holiday
        //orderByProcessDefinitionVersion() 设置排序方式,根据流程定义的版本号进行排序
        List<ProcessDefinition> list = processDefinitionQuery.processDefinitionKey("holiday")
                .orderByProcessDefinitionVersion()
                .desc().list();

        //5.输出流程定义信息
        for(ProcessDefinition processDefinition :list){
            System.out.println("流程定义ID:"+processDefinition.getId());
            System.out.println("流程定义名称:"+processDefinition.getName());
            System.out.println("流程定义的Key:"+processDefinition.getKey());
            System.out.println("流程定义的版本号:"+processDefinition.getVersion());
            System.out.println("流程部署的ID:"+processDefinition.getDeploymentId());

        }
    }

 

四、流程定义删除

@Test
    /**
     * 删除已经部署的流程定义
     *
     * 背后影响的表:
     act_ge_bytearray
     act_re_deployment
     act_re_procdef
     */
    public void deleteProcessDefinition(){

        /*
        *   * 注意事项:
         *     1.当我们正在执行的这一套流程没有完全审批结束的时候,此时如果要删除流程定义信息就会失败
         *     2.如果公司层面要强制删除,可以使用repositoryService.deleteDeployment("1",true);
         *     参数true代表级联删除,此时就会先删除没有完成的流程结点,最后就可以删除流程定义信息  false的值代表不级联
         * */
        //1.得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.创建RepositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3.执行删除流程定义  参数代表流程部署的id
        repositoryService.deleteDeployment("1");
    }

 

五、流程定义资源查询

/**
     *
     * 查询流程定义的资源
     * 需求:
     * 从Activiti的act_ge_bytearray表中读取两个资源文件 
     * 真实应用场景:用户想查看这个请假流程具体有哪些步骤要走?
     */
    @Test
    public void queryResources() throws  Exception{
        //1.得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.得到RepositoryService对象
        RepositoryService repositoryService = processEngine.getRepositoryService();
        //3.得到查询器:ProcessDefinitionQuery对象
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
        //4.设置查询条件
        processDefinitionQuery.processDefinitionKey("holiday2");//参数是流程定义的key
        //5.执行查询操作,查询出想要的流程定义
        ProcessDefinition processDefinition = processDefinitionQuery.singleResult();
        //6.通过流程定义信息,得到部署ID
        String deploymentId = processDefinition.getDeploymentId();

        //7.通过repositoryService的方法,实现读取图片信息及bpmn文件信息(输入流)
        //getResourceAsStream()方法的参数说明:第一个参数部署id,第二个参数代表资源名称
        //processDefinition.getDiagramResourceName() 代表获取png图片资源的名称
        //processDefinition.getResourceName()代表获取bpmn文件的名称
        InputStream pngIs = repositoryService
                .getResourceAsStream(deploymentId,processDefinition.getDiagramResourceName());
        InputStream bpmnIs = repositoryService
                .getResourceAsStream(deploymentId,processDefinition.getResourceName());

        //8.构建出OutputStream流
        OutputStream pngOs = new FileOutputStream("D:\\StudyProject\\"+processDefinition.getDiagramResourceName());
        OutputStream bpmnOs = new FileOutputStream("D:\\StudyProject\\"+processDefinition.getResourceName());

        //9.输入流,输出流的转换  commons-io-xx.jar中的方法
        IOUtils.copy(pngIs,pngOs);
        IOUtils.copy(bpmnIs,bpmnOs);
        //10.关闭流
        pngOs.close();
        bpmnOs.close();
        pngIs.close();
        bpmnIs.close();
    }

 

六、 流程历史信息的查看

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

 /**
     * 需求:
     *  *   历史数据的查看
     */
    @Test
    public void queryHistrory(){
        //1.得到ProcessEngine对象
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //2.得到HistoryService
        HistoryService historyService = processEngine.getHistoryService();
        //3.得到HistoricActivitiInstanceQuery对象
        HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
        historicActivityInstanceQuery.processInstanceId("2501");//设置流程实例的id
        //4.执行查询
        List<HistoricActivityInstance> list = historicActivityInstanceQuery
                .orderByHistoricActivityInstanceStartTime().asc().list();//排序StartTime

        //5.遍历查询结果
        for (HistoricActivityInstance instance :list){
            System.out.println(instance.getActivityId());
            System.out.println(instance.getActivityName());
            System.out.println(instance.getProcessDefinitionId());
            System.out.println(instance.getProcessInstanceId());
            System.out.println("=============================");
        }
    }

 

七、 流程定义查询

@RestController
@RequestMapping("activity")
public class ActivityApiController {


    @GetMapping("getProcessDefinition")
    public void getProcessDefinition(HttpServletResponse response, String processDefinitionId) throws IOException {
        // 获取流程定义
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionId(processDefinitionId)
                .singleResult();
        // 获取流程定义的部署ID
        String deploymentId = processDefinition.getDeploymentId();
        // 加载流程图资源
        InputStream inputStream = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName());
        response.setHeader("Content-Disposition", "attachment;filename=spring.jpg");
        OutputStream outputStream = response.getOutputStream();
        byte[] buf = new byte[1024];
        int len = 0;
        while ((len = inputStream.read(buf)) != -1) {
            outputStream.write(buf, 0, len);
        }
        //3.关闭资源
        outputStream.close();
        inputStream.close();
    }
}

 

 

 

 

 

 

posted @ 2022-04-09 14:25  邓维-java  阅读(511)  评论(0编辑  收藏  举报