Обзор
-
Используйте flowable-ui, который поставляется вместе с flowable, чтобы создать блок-схему.
-
Используйте интерфейс, используемый процессом разработки Springboot, для выполнения бизнес-функций процесса.
1. Развертывание и работа Flowable-UI
flowable-6.6.0 запускает официальную демоверсию
Справочная документация:
1. Скачать flowable-6.6.0 с официального сайта:https://github.com/flowable/flowable-engine/releases/download/flowable-6.6.0/flowable-6.6.0.zip
2. Положить в сжатый пакетflowable-6.6.0\wars\flowable-ui.warБросьте его в Tomcat и запустите
3. Открытьhttp://localhost:8080/flowable-uiВойти под учетной записью: admin/test
4. Войдите в процесс создания APP.MODELER, а затем экспортируйте процесс в проект для использования или настройтеapache-tomcat-9.0.37\webapps\flowable-ui\WEB-INF\classes\flowable-default.propertiesподключиться к локальной базе данных
Примечание. JAR-файл драйвера Java (
mysql-connector-java-5.1.45.jar)скопировать вapache-tomcat-9.0.37\webapps\flowable-rest\WEB-INF\lib
Бэкэнд-программа процесса, созданная таким образом, может быть использована напрямую.
2. Нарисуйте блок-схему
Нарисуйте блок-схему в flowable-ui>APP.MODELER в соответствии с потребностями бизнеса, как показано в приведенном выше примере. Сначала объясните некоторые понятия.
-
событиеОбычно используется для моделирования того, что происходит в жизненном цикле процесса, на картинке есть две окружности [начало, конец].
-
поток последовательностиявляется связующим звеном между двумя элементами в процессе. На картинке показан [сегмент линии со стрелкой].
-
шлюзИспользуется для управления потоком выполнения. На картинке [ромб (с крестиком посередине)]
-
задача пользователяИспользуется для моделирования задач, требующих выполнения человеком. На картинке [прямоугольник].
Простые рабочие процессы, вероятно, состоят из этих элементов (есть еще много других, которые я не буду здесь подробно описывать). Ниже описано, как протекает рабочий процесс.
После первого запуска рабочего процесса узел [Старт] автоматически переходит к узлу [Студент], ожидая выполнения задачи. После выполнения задачи назначенным пользователем-учащимся она переходит к узлу [Учитель] и ожидает повторного выполнения задачи. После того, как назначенный пользователь-преподаватель выполнит ее, она перейдет к [Шлюзу]. Шлюз проверяет каждый выход и перейдет к задачам, которые соответствуют условиям. Например, когда учитель соглашается выполнить задачу, она перетекает к [Основному] node и ожидает выполнения задачи. После выполнения аналогично учителю, после согласования перетекает в узел [Конец], и здесь весь процесс заканчивается.
Детали чертежа:
1. Сохраняйте модель процесса
2. Поток последовательности может устанавливать условия потока, чтобы ограничить поток.Например, указанный выше выход шлюза устанавливает условия
3. Задача должна быть назначена исполняющему пользователю задачи, который может быть назначен группе кандидатов или непосредственно кандидату.
Наконец, экспортируйте файл рабочего процесса
содержание документа
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-insmtece" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:flowable="http://flowable.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef">
<process id="leave_approval" name="请假审批" isExecutable="true">
<startEvent id="start" name="开始" flowable:initiator="startuser" flowable:formFieldValidation="true"></startEvent>
<userTask id="stu_task" name="学生" flowable:candidateGroups="stu_group" flowable:formFieldValidation="true"></userTask>
<sequenceFlow id="flow1" sourceRef="start" targetRef="stu_task"></sequenceFlow>
<userTask id="te_task" name="老师" flowable:candidateGroups="te_group" flowable:formFieldValidation="true"></userTask>
<exclusiveGateway id="getway1" name="网关1"></exclusiveGateway>
<userTask id="mte_task" name="校长" flowable:candidateGroups="mte_group" flowable:formFieldValidation="true"></userTask>
<exclusiveGateway id="getway2" name="网关2"></exclusiveGateway>
<endEvent id="end" name="结束"></endEvent>
<sequenceFlow id="flow1" name="请假" sourceRef="stu_task" targetRef="te_task" skipExpression="${command=='agree'}"></sequenceFlow>
<sequenceFlow id="flow3_1" name="同意" sourceRef="getway1" targetRef="mte_task">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${command=='agree'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow2" name="审批" sourceRef="te_task" targetRef="getway1"></sequenceFlow>
<sequenceFlow id="flow3_2" name="拒绝" sourceRef="getway1" targetRef="stu_task">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${command=='refuse'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow4" name="审批" sourceRef="mte_task" targetRef="getway2"></sequenceFlow>
<sequenceFlow id="flow4_1" name="同意" sourceRef="getway2" targetRef="end" skipExpression="${command=='free'}">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${command=='agree'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow4_2" name="拒绝" sourceRef="getway2" targetRef="stu_task">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${command=='refuse'}]]></conditionExpression>
</sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_leave_approval">
这里先省略
</bpmndi:BPMNDiagram>
</definitions>
4, импорт файла bpmn
При необходимости вы можете загрузить этот файл процесса и импортировать его напрямую.
3. Фоновая конструкция проекта
Фоновый проект основан на jdk8 и использует структуру Springboot.
весенняя версия
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
Зависимости проекта pom.xml
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter</artifactId>
<version>6.6.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
application.yml конфигурации проекта
spring:
datasource:
url: jdbc:mysql://localhost:3306/flowable?useSSL=false&characterEncoding=UTF-8&serverTimezone=GMT%2B8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: 123456
В-четвертых, база данных
1. Все таблицы базы данных Flowable начинаются с ACT_. Вторая часть представляет собой двухсимвольный идентификатор, описывающий назначение таблицы. Именование сервисного API также примерно соответствует этому правилу.
2,ACT_RE_: RE означает репозиторий. Таблицы с этим префиксом содержат «статическую» информацию, такую как определения процессов и ресурсы процессов (изображения, правила и т. д.).
3.ACT_RU_: «RU» означает время выполнения. В этих таблицах хранится информация о времени выполнения, такая как экземпляры процессов, пользовательские задачи, переменные, задания и т. д. Flowable сохраняет данные времени выполнения только во время работы экземпляра процесса и удаляет записи, когда экземпляр процесса завершается. Это гарантирует, что рабочая таблица будет небольшой и быстрой.
4.ACT_HI_: 'HI' означает историю. В этих таблицах хранятся исторические данные, такие как завершенные экземпляры процессов, переменные, задачи и т. д.
5.ACT_GE_: Общие данные. Используется во многих местах.
1) Общий техпаспорт (2 шт.)
-
act_ge_bytearray: таблица двоичных данных, таких как определения процессов, шаблоны процессов и файлы потоковых диаграмм байтов;
-
act_ge_property: таблица данных свойств (обычно не используется);
2) Таблицы истории (8, таблицы, управляемые интерфейсом HistoryService)
-
act_hi_actinst: таблица исторических узлов, в которой хранится информация о каждом узле операции экземпляра процесса (включая незадачные узлы, такие как начало и конец);
-
act_hi_attachment: таблица исторических вложений, в которой хранится информация о вложениях, загруженная историческими узлами (обычно не используется);
-
act_hi_comment: таблица исторических комментариев;
-
act_hi_detail: таблица исторических подробностей, в которой хранится некоторая информация о работе узла (обычно не используется);
-
act_hi_identitylink: историческая таблица персонала процесса, в которой хранится информация о кандидатах и обрабатывается информация о персонале для каждого узла процесса, часто используемая для запроса выполненных задач человека или отдела;
-
act_hi_procinst: таблица исторических экземпляров процессов, в которой хранятся исторические данные экземпляров процессов (включая запущенные экземпляры процессов);
-
act_hi_taskinst: таблица исторических задач процесса, хранящая исторические узлы задач;
-
act_hi_varinst: таблица переменных истории процесса, в которой хранится переменная информация узлов истории процесса;
3) Пользовательские таблицы (4, таблицы, управляемые интерфейсом IdentityService)
-
act_id_group: таблица информации о группе пользователей, соответствующая информация о группе-кандидате, выбранной узлом;
-
act_id_info: таблица информации о расширении пользователя, в которой хранится информация о расширении пользователя;
-
act_id_membership: таблица отношений пользователя и группы пользователей;
-
act_id_user: таблица информации о пользователе, соответствующая диспетчеру выбора узла или информации о кандидате;
4) Определение процесса, таблицы, связанные с шаблоном процесса (3, операционная таблица интерфейса RepositoryService)
-
act_re_deployment: таблица информации о развертывании, в которой хранится определение процесса и информация о развертывании шаблона;
-
act_re_procdef: таблица информации об определении процесса, в которой хранится информация описания, связанная с определением процесса, но ее реальное содержимое хранится в таблице act_ge_bytearray, которая хранится в виде байтов;
-
act_re_model: информационная таблица шаблона процесса, в которой хранится информация описания шаблона процесса, но ее реальное содержимое хранится в таблице act_ge_bytearray, которая хранится в виде байтов;
5) Таблицы времени выполнения процессов (6, таблицы, управляемые интерфейсом RuntimeService)
-
act_ru_task: Таблица узла задач процесса выполнения, в которой хранится информация об узле задач запущенного процесса.Это важно и часто используется для запроса текущих задач человека или отдела;
-
act_ru_event_subscr: таблица с мониторинговой информацией, обычно не используется;
-
act_ru_execution: таблица экземпляров исполняемых процессов, в которую записывается информация о каждой ветке запущенного процесса (при отсутствии подпроцесса его данные находятся во взаимно однозначном соответствии с данными таблицы act_ru_task);
-
act_ru_identitylink: таблица персонала рабочего процесса, важная, часто используется для запроса текущих задач персонала или отделов;
-
act_ru_job: таблица данных о запланированных задачах во время выполнения, в которой хранится информация о запланированных задачах процесса;
-
act_ru_variable: таблица данных переменных процесса времени выполнения, в которой хранится переменная информация каждого узла запущенного процесса;
5. API и сервисы Process Engine
Engine API — наиболее распространенный способ взаимодействия с Flowable. Общая точка входа — ProcessEngine.
1. RepositoryService, вероятно, будет первым сервисом, который будет использоваться с движком Flowable. Эта служба предоставляет операции для управления и контроля развертываний и определений процессов. управлять статической информацией,
2. RuntimeService используется для запуска нового экземпляра процесса, определенного процессом.
3. IdentityService очень прост. Он используется для управления (создание, обновление, удаление, запрос...) группами и пользователями.
4. FormService — необязательный сервис. Тем не менее, Flowable может хорошо работать и без него, не жертвуя какой-либо функциональностью.
5. HistoryService предоставляет все исторические данные, собранные движком Flowable. Предоставить возможность запрашивать исторические данные.
6. ManagementService обычно не нужно использовать при написании пользовательских приложений с помощью Flowable. Он может считывать информацию из таблиц базы данных и необработанных данных таблиц, а также выполнять запросы и операции управления для заданий.
7. DynamicBpmnService можно использовать для изменения части определения процесса без его повторного развертывания. Например, вы можете изменить настройку человека пользовательской задачи в определении процесса или изменить имя класса в сервисной задаче.
Затем используйте предыдущую блок-схему отпуска и добавьте код
код
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.HistoryService;
import org.flowable.engine.RepositoryService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.Deployment;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.runtime.Execution;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.idm.api.Group;
import org.flowable.idm.api.User;
import org.flowable.task.api.Task;
import org.flowable.task.api.history.HistoricTaskInstance;
import org.springframework.beans.factory.annotation.Autowired;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipInputStream;
/**
* TestFlowable
*
* @Author
* @Date: 2021/10/17 23:35
* @Version 1.0
*/
@Slf4j
public class TestFlowable {
@Autowired
private RepositoryService repositoryService;
@Autowired
private RuntimeService runtimeService;
@Autowired
private HistoryService historyService;
@Autowired
private org.flowable.engine.TaskService taskService;
@Autowired
private org.flowable.engine.IdentityService identityService;
public void createDeploymentZip() {
/*
* @Date: 2021/10/17 23:38
* Step 1: 部署xml(压缩到zip形式,直接xml需要配置相对路径,麻烦,暂不用)
*/
try {
File zipTemp = new File("f:/leave_approval.bpmn20.zip");
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream(zipTemp));
Deployment deployment = repositoryService
.createDeployment()
.addZipInputStream(zipInputStream)
.deploy();
log.info("部署成功:{}", deployment.getId());
} catch (FileNotFoundException e) {
e.printStackTrace();
}
/*
* @Date: 2021/10/17 23:40
* Step 2: 查询部署的流程定义
*/
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().processDefinitionKey("leave_approval").list();
List<ProcessDefinition> pages = repositoryService.createProcessDefinitionQuery().processDefinitionKey("leave_approval").listPage(1, 30);
/*
* @Date: 2021/10/17 23:40
* Step 3: 启动流程,创建实例
*/
String processDefinitionKey = "leave_approval";//流程定义的key,对应请假的流程图
String businessKey = "schoolleave";//业务代码,根据自己的业务用
Map<String, Object> variablesDefinition = new HashMap<>();//流程变量,可以自定义扩充
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, businessKey, variablesDefinition);
log.info("启动成功:{}", processInstance.getId());
/*
* @Date: 2021/10/17 23:40
* Step 4: 查询指定流程所有启动的实例列表
* 列表,或 分页 删除
*/
List<Execution> executions = runtimeService.createExecutionQuery().processDefinitionKey("leave_approval").list();
List<Execution> executionPages = runtimeService.createExecutionQuery().processDefinitionKey("leave_approval").listPage(1, 30);
// runtimeService.deleteProcessInstance(processInstanceId, deleteReason); //删除实例
/*
* @Date: 2021/10/17 23:40
* Step 5: 学生查询可以操作的任务,并完成任务
*/
String candidateGroup = "stu_group"; //候选组 xml文件里面的 flowable:candidateGroups="stu_group"
List<Task> taskList = taskService.createTaskQuery().taskCandidateGroup(candidateGroup).orderByTaskCreateTime().desc().list();
for (Task task : taskList) {
// 申领任务
taskService.claim(task.getId(), "my");
// 完成
taskService.complete(task.getId());
}
/*
* @Date: 2021/10/17 23:40
* Step 6: 老师查询可以操作的任务,并完成任务
*/
String candidateGroupTe = "te_group"; //候选组 xml文件里面的 flowable:candidateGroups="te_group"
List<Task> taskListTe = taskService.createTaskQuery().taskCandidateGroup(candidateGroupTe).orderByTaskCreateTime().desc().list();
for (Task task : taskListTe) {
// 申领任务
taskService.claim(task.getId(), "myte");
// 完成
Map<String, Object> variables = new HashMap<>();
variables.put("command","agree"); //携带变量,用于网关流程的条件判定,这里的条件是同意
taskService.complete(task.getId(), variables);
}
/*
* @Date: 2021/10/18 0:17
* Step 7: 历史查询,因为一旦流程执行完毕,活动的数据都会被清空,上面查询的接口都查不到数据,但是提供历史查询接口
*/
// 历史流程实例
List<HistoricProcessInstance> historicProcessList = historyService.createHistoricProcessInstanceQuery().processDefinitionKey("leave_approval").list();
// 历史任务
List<HistoricTaskInstance> historicTaskList = historyService.createHistoricTaskInstanceQuery().processDefinitionKey("leave_approval").list();
// 实例历史变量 , 任务历史变量
// historyService.createHistoricVariableInstanceQuery().processInstanceId(processInstanceId);
// historyService.createHistoricVariableInstanceQuery().taskId(taskId);
// *****************************************************分隔符********************************************************************
// *****************************************************分隔符********************************************************************
// 可能还需要的API
// 移动任务,人为跳转任务
// runtimeService.createChangeActivityStateBuilder().processInstanceId(processInstanceId)
// .moveActivityIdTo(currentActivityTaskId, newActivityTaskId).changeState();
// 如果在数据库配置了分组和用户,还会用到
List<User> users = identityService.createUserQuery().list(); //用户查询,用户id对应xml 里面配置的用户
List<Group> groups = identityService.createGroupQuery().list(); //分组查询,分组id对应xml 里面配置的分组 如 stu_group,te_group 在表里是id的值
// 另外,每个查询后面都可以拼条件,内置恁多查询,包括模糊查询,大小比较都有
}
}
5. Ссылки
-
Доля крупного рогатого скота Текучий документ Китайский:GitHub.com/Ножи/Правовые…
-
Cat Seven Girls flowable-6.6.0 запускает официальную демоверсию
В этой статье используетсяПомощник по синхронизации статейСинхронизировать