Activiti7 代码操作

Service总览

RepositoryService:activiti的资源管理类

RuntimeService:activiti的流程运行管理类

TaskService:activiti的任务管理类

HistoryService:activiti的历史管理类

ManagerService:activiti的引擎管理类

一、流程部署

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

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

1.1、单个文件部署方式

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

1.2、压缩包部署方式

    @Test
    public void deployProcessByZip() {
        // 定义zip输入流
        InputStream inputStream = this
                .getClass()
                .getClassLoader()
                .getResourceAsStream(
                        "bpmn/evection.zip");
        ZipInputStream zipInputStream = new ZipInputStream(inputStream);
        // 获取repositoryService
        RepositoryService repositoryService = processEngine
                .getRepositoryService();
        // 流程部署
        Deployment deployment = repositoryService.createDeployment()
                .addZipInputStream(zipInputStream)
                .deploy();
        System.out.println("流程部署id:" + deployment.getId());
        System.out.println("流程部署名称:" + deployment.getName());
    }

二、启动流程实例

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

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

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

三、任务查询

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

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

四、流程任务处理

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

    // 完成任务
    @Test
    public void completTask(){
        // 获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取taskService
        TaskService taskService = processEngine.getTaskService();
        // 根据流程key 和 任务的负责人 查询任务
        // 返回一个任务对象
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("myEvection") //流程Key
                .taskAssignee("zhangsan") //要查询的负责人
                .singleResult();
        // 完成任务,参数:任务id
        taskService.complete(task.getId());
    }

五、流程定义信息查询

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

    /**
     * 查询流程定义
     */
    @Test
    public void queryProcessDefinition(){
        // 获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // repositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        // 得到ProcessDefinitionQuery 对象
        ProcessDefinitionQuery processDefinitionQuery =
                repositoryService.createProcessDefinitionQuery();
        // 查询出当前所有的流程定义
        // 条件:processDefinitionKey =evection
        // orderByProcessDefinitionVersion 按照版本排序
        // desc倒叙
        // list 返回集合
        List<ProcessDefinition> definitionList =
                processDefinitionQuery.processDefinitionKey("myEvection")
                        .orderByProcessDefinitionVersion()
                        .desc()
                        .list();
        // 输出流程定义信息
        for (ProcessDefinition processDefinition : 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());
        }
    }

六、流程删除

说明:

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

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

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

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

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

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

七、流程资源下载

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

解决方案有:

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

2、使用activiti的api来实现

使用commons-io.jar 解决IO的操作 引入commons-io依赖包:commons-io

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

    @Test
    public void deleteDeployment(){
        // 获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取repositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        // 根据部署id 删除部署信息,如果想要级联删除,可以添加第二个参数,true
        repositoryService.deleteDeployment("1");
    }
    
    public void queryBpmnFile() throws IOException {
        // 1、得到引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2、获取repositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
        // 3、得到查询器:ProcessDefinitionQuery,设置查询条件,得到想要的流程定义
        ProcessDefinition processDefinition =
                repositoryService.createProcessDefinitionQuery()
                        .processDefinitionKey("myEvection")
                        .singleResult();
        // 4、通过流程定义信息,得到部署ID
        String deploymentId = processDefinition.getDeploymentId();
        // 5、通过repositoryService的方法,实现读取图片信息和bpmn信息
        // png图片的流
        InputStream pngInput = repositoryService.getResourceAsStream(deploymentId,
                processDefinition.getDiagramResourceName());
        // bpmn文件的流
        InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId,
                processDefinition.getResourceName());
        // 6、构造OutputStream流
        File file_png = new File("d:/evectionflow01.png");
        File file_bpmn = new File("d:/evectionflow01.bpmn");
        FileOutputStream bpmnOut = new FileOutputStream(file_bpmn);
        FileOutputStream pngOut = new FileOutputStream(file_png);
        // 7、输入流,输出流的转换
        IOUtils.copy(pngInput,pngOut);
        IOUtils.copy(bpmnInput,bpmnOut);
        // 8、关闭流
        pngOut.close();
        bpmnOut.close();
        pngInput.close();
        bpmnInput.close();
    }

说明:

1) deploymentId为流程部署ID

2) resource_name为act_ge_bytearray表中NAME_列的值

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

4) 使用repositoryService的getResourceAsStream方法传入部署ID和资源图片名称可以获取部署下指定名称文件的输入 流 最后的将输入流中的图片资源进行输出。

八、流程历史信息的查看

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

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

您好,Activiti 7 中的驳回操作可以通过以下代码实现: ```java public void rejectTask(String taskId) { // 获取当前任务 Task task = taskService.createTaskQuery() .taskId(taskId) .singleResult(); if (task == null) { throw new RuntimeException("任务不存在"); } // 获取当前任务的流程实例 String processInstanceId = task.getProcessInstanceId(); // 获取当前任务的历史任务实例列表 List<HistoricTaskInstance> historicTaskList = historyService.createHistoricTaskInstanceQuery() .processInstanceId(processInstanceId) .orderByHistoricTaskInstanceEndTime() .asc() .list(); // 获取需要驳回到的任务 HistoricTaskInstance targetTask = null; for (int i = 0; i < historicTaskList.size(); i++) { HistoricTaskInstance historicTask = historicTaskList.get(i); if (historicTask.getId().equals(taskId)) { if (i == 0) { throw new RuntimeException("该任务已经是第一个任务,无法驳回"); } targetTask = historicTaskList.get(i - 1); break; } } if (targetTask == null) { throw new RuntimeException("未找到驳回目标任务"); } // 驳回操作 BpmnModel bpmnModel = repositoryService.getBpmnModel(task.getProcessDefinitionId()); Process process = bpmnModel.getProcesses().get(0); FlowNode sourceNode = (FlowNode) process.getFlowElement(task.getTaskDefinitionKey()); FlowNode targetNode = (FlowNode) process.getFlowElement(targetTask.getTaskDefinitionKey()); List<Execution> executionList = runtimeService.createExecutionQuery() .processInstanceId(processInstanceId) .list(); for (Execution execution : executionList) { if (execution instanceof ExecutionEntity) { ExecutionEntity executionEntity = (ExecutionEntity) execution; executionEntity.setCurrentFlowElement(sourceNode); runtimeService.createChangeActivityStateBuilder() .processInstanceId(processInstanceId) .moveExecutionToActivityId(executionEntity.getId(), targetNode.getId()) .changeState(); } } } ``` 该代码实现了将当前任务驳回到上一步任务的操作,具体的实现过程请参考注释。需要注意的是,该代码中使用了 Activiti 7 中的一些 API,如 `BpmnModel`、`FlowNode` 等,如果您之前使用的是 Activiti 6,可能需要进行一些调整。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值