ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
Flowable 处理一个流程的步骤如下: <br/> **1. 定义流程** ![](https://img.kancloud.cn/29/02/29024480e2c69b430a9d441e1767364b_1156x215.png) **2. 部署流程** ```java @Test public void deploymentProcess() { //获取ProcessEngine ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //获取RepositoryService RepositoryService repositoryService = processEngine.getRepositoryService(); //部署流程 Deployment deployment = repositoryService.createDeployment() .addClasspathResource("bpmn/evectionProcess.bpmn") //部署资源 .name("出差申请流程") //部署名称 .deploy(); log.info("部署名:{}", deployment.getName()); //部署名:出差申请流程 log.info("部署id:{}", deployment.getId()); //部署id:1 } ``` 完成上面的部署后相关数据保存到如下3张表中: ```sql -- 流程部署表:每部署一次增加一条记录 mysql> select * from act_re_deployment; +-----+--------------+-----------+------+------------+---------------------+---------------+--------------------+-----------------+ | ID_ | NAME_ | CATEGORY_ | KEY_ | TENANT_ID_ | DEPLOY_TIME_ | DERIVED_FROM_ | DERIVED_FROM_ROOT_ | ENGINE_VERSION_ | +-----+--------------+-----------+------+------------+---------------------+---------------+--------------------+-----------------+ | 1 | 出差申请流程 | NULL | NULL | | 2021-10-28 17:09:50 | NULL | NULL | NULL | +-----+--------------+-----------+------+------------+---------------------+---------------+--------------------+-----------------+ -- 流程定义表:部署每个新的流程就会在这张表中增加一条记录 -- 注意,KEY_ 这个字段是用来唯一识别不同流程的关键字 mysql> select * from act_re_procdef; +---------------------+------+------------------------------+--------------+-----------------+----------+----------------+---------------------------+---------------------------------------... | ID_ | REV_ | CATEGORY_ | NAME_ | KEY_ | VERSION_ | DEPLOYMENT_ID_ | RESOURCE_NAME_ | DGRM_RESOURCE_NAME_ | DESCRI... +---------------------+------+------------------------------+--------------+-----------------+----------+----------------+---------------------------+---------------------------------------... | evectionProcess:1:4 | 1 | http://www.activiti.org/test | 出差申请流程 | evectionProcess | 1 | 1 | bpmn/evectionProcess.bpmn | bpmn/evectionProcess.evectionProcess.png | ... +---------------------+------+------------------------------+--------------+-----------------+----------+----------------+---------------------------+---------------------------------------... -- 流程资源表 mysql> select id_, rev_, name_, deployment_id_, left(bytes_, 30) as bytes_, generated_ from act_ge_bytearray; +-----+------+------------------------------------------+----------------+--------------------------------+------------+ | id_ | rev_ | name_ | deployment_id_ | bytes_ | generated_ | +-----+------+------------------------------------------+----------------+--------------------------------+------------+ | 2 | 1 | bpmn/evectionProcess.bpmn | 1 | <?xml version="1.0" encoding=" | 0 | | 3 | 1 | bpmn/evectionProcess.evectionProcess.png | 1 | Binary/Image | 1 | +-----+------+------------------------------------------+----------------+--------------------------------+------------+ act_re_deployment和act_re_procdef一对多关系,一次部署在流程部署表生成一条记录, 但一次部署可以部署多个流程定义,每个流程定义在流程定义表生成一条记录。 每一个流程定义在act_ge_bytearray会存在两个资源记录,bpmn和png。 建议:一次部署一个流程,这样部署表和流程定义表是一对一有关系,方便读取流程部署及流程定义信息。 ``` **3. 启动流程** ```java @Test public void runtimeProcess() { //获取ProcessEngine ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //获取RuntimeService RuntimeService runtimeService = processEngine.getRuntimeService(); //根据流程key启动对应的流程,创建流程实例 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("evectionProcess"); //流程部署id:1 log.info("流程部署id:{}", processInstance.getDeploymentId()); //流程定义id:evectionProcess:1:4 log.info("流程定义id:{}", processInstance.getProcessDefinitionId()); //流程实例id:2501 log.info("流程实例id:{}", processInstance.getId()); } ``` 完成上面的启动流程后相关数据保存到如下7张表中: ```sql act_hi_actinst 流程实例执行历史信息 act_hi_identitylink 流程参与用户的历史信息 act_hi_procinst 流程实例的历史信息 act_hi_taskinst 流程任务的历史信息 act_ru_execution 流程执行信息 act_ru_identitylink 流程的正在参与用户信息 act_ru_task 流程当前任务信息 ``` **4. 查询个人待办任务** ```java @Test public void queryTask() { //获取ProcessEngine ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //获取TaskService TaskService taskService = processEngine.getTaskService(); //根据流程Key与负责人查询 List<Task> taskList = taskService.createTaskQuery() .processDefinitionKey("evectionProcess") .taskAssignee("张三") .list(); taskList.forEach(task -> { log.info("任务id:{}", task.getId()); log.info("任务负责人:{}", task.getAssignee()); log.info("任务名称:{}", task.getName()); log.info("流程定义Id:{}", task.getProcessDefinitionId()); log.info("流程实例Id:{}", task.getProcessInstanceId()); log.info("任务节点Id:{}", task.getTaskDefinitionKey()); }); //任务id:2505 //任务负责人:张三 //任务名称:创建出差申请 //流程定义Id:evectionProcess:1:4 //流程实例Id:2501 //任务节点Id:_3 } ``` **5. 完成个人待办任务** ```java @Test public void completeTask() { //获取ProcessEngine ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //获取TaskService TaskService taskService = processEngine.getTaskService(); //根据流程key与负责人查询待办任务 Task task = taskService.createTaskQuery() .processDefinitionKey("evectionProcess") .taskAssignee("张三") .singleResult(); //根据任务id完成对应的任务 taskService.complete(task.getId()); log.info("任务负责人:{}", task.getAssignee()); //任务负责人:张三 log.info("任务Id:{}", task.getId()); //任务Id:2505 log.info("任务名称:{}", task.getName()); //任务名称:创建出差申请 log.info("流程实例Id:{}", task.getProcessInstanceId()); //流程实例Id:2501 log.info("流程定义Id:{}", task.getProcessDefinitionId()); //流程定义Id:evectionProcess:1:4 log.info("任务节点Id:{}", task.getTaskDefinitionKey()); //任务节点Id:_3 } ``` 完成对应的任务后,该任务从表`act_ru_task`中删除,并在如下表中插入下一个任务的相关数据: ```sql act_ru_task act_hi_taskinst act_hi_actinst act_hi_identitylink act_ru_identitylink ``` **6. 流程结束,后期的历史追踪与维护** ```java @Test public void queryHistory() { //获取ProcessEngine ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); //获取HistoryService HistoryService historyService = processEngine.getHistoryService(); List<HistoricActivityInstance> activities = historyService.createHistoricActivityInstanceQuery() .processInstanceId("2501") //根据流程实例id查询 .finished() //查询是已经完成的任务 .orderByHistoricActivityInstanceEndTime().asc() .list(); activities.forEach(activity -> { log.info("任务节点Id:{}", activity.getActivityId()); log.info("完成任务所花的时间:{}ms", activity.getDurationInMillis()); log.info("任务负责人:{}", activity.getAssignee()); log.info("流程定义Id:{}", activity.getProcessDefinitionId()); log.info("流程实例Id:{}", activity.getProcessInstanceId()); log.info("任务节点名称:{}", activity.getActivityName()); log.info("任务节点类型:{}", activity.getActivityType()); log.info("任务Id:{}\n", activity.getTaskId()); }); //任务节点Id:_2 //完成任务所花的时间:2ms //任务负责人:null //流程定义Id:evectionProcess:1:4 //流程实例Id:2501 //任务节点名称:StartEvent //任务节点类型:startEvent //任务Id:null //任务节点Id:_3 //完成任务所花的时间:1044753ms //任务负责人:张三 //流程定义Id:evectionProcess:1:4 //流程实例Id:2501 //任务节点名称:创建出差申请 //任务节点类型:userTask //任务Id:2505 } ```