Я не ожидал, что рабочий процесс разработки Springboot + Flowable будет таким простым

Java MySQL
Я не ожидал, что рабочий процесс разработки Springboot + Flowable будет таким простым

Эта статья размещена в личном блоге:www.chengxy-nds.top, обмен техническими данными, с прогрессом

Программисты - это кирпичи, двигайтесь туда, где они должны быть

Система открытого доступа компании недавно была обновлена.Меня откомандировали из-за нехватки рабочей силы, но, честно говоря, я еще не выполнял эту функцию.Когда я впервые столкнулся с разработкой рабочего процесса, мне было немного любопытно, процесс. .

В основном используется в проектеSpringboot + FlowableРефакторинг исходного рабочего процесса,Flowableэто использованиеJavaЛегкий движок рабочего процесса, написанный на языке, относительно прост в использовании и обладает высокой эффективностью разработки.Давайте изучим этот фреймворк вместе.

Официальный адрес:https://www.flowable.org/docs/userguide/index.html, совместное использование — это всего лишь простое приложение, для углубленного исследования необходимо посмотреть официальную документацию.

Текучие основные зависимости

<!--flowable工作流依赖-->
<dependency>
	<groupId>org.flowable</groupId>
	<artifactId>flowable-spring-boot-starter</artifactId>
	<version>6.3.0</version>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
	<groupId>org.mybatis.spring.boot</groupId>
	<artifactId>mybatis-spring-boot-starter</artifactId>
	<version>1.3.2</version>
</dependency>
<dependency>
	<groupId>mysql</groupId>
	<artifactId>mysql-connector-java</artifactId>
	<scope>runtime</scope>
</dependency>

Разработка процесса

Ядром разработки рабочего процесса является проектирование потока задач.FlowableОфициальные рекомендованные отраслевые стандартыBPMN2.0изXMLдля описания рабочего процесса, который необходимо определить.

нам надоresourceСоздано в каталогеprocessesпуть к магазину связанныхXMLФайл конфигурации процесса.FlowableРамки будут загружать и анализировать файлы рабочего процесса в этом каталоге по умолчаниюXMLи сохраните проанализированную информацию о конфигурации процесса в базе данных.

FlowableЭто зависит от базы данных, но это не требует от нас создания таблицы вручную, а автоматически в программе при первом запуске программы.MySQLв наборе таблиц, необходимых для его создания.

spring:
  datasource:
    url: jdbc:mysql://47.93.6.5:3306/order?serverTimezone=UTC
    username: root
    password: 123455

Видя, что проект был успешно запущен, всего было сгенерировано 60 таблиц, что все еще довольно много, для хранения этих таблиц рабочего процесса рекомендуется использовать специальную базу данных.

Например, если процесс запроса на отпуск должен быть одобрен менеджером, запрос на отпуск вступит в силу.Если он отклоняет процесс, процесс завершается.

Далее мы используемXMLПереведите блок-схему подачи заявления на отпуск внизу.Все очень просто, если вы достаточно внимательны, давайте посмотрим, что означает каждая метка.

<?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-instance"
             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" name="LeaveProcess" isExecutable="true">
        <userTask id="leaveTask" name="请假" flowable:assignee="${leaveTask}"/>
        <userTask id="managerTask" name="经理审核"/>
        <exclusiveGateway id="managerJudgeTask"/>
        <endEvent id="endLeave" name="结束"/>
        <startEvent id="startLeave" name="开始"/>
        <sequenceFlow id="modeFlow" sourceRef="leaveTask" targetRef="managerTask"/>
        <sequenceFlow id="flowStart" sourceRef="startLeave" targetRef="leaveTask"/>
        <sequenceFlow id="jugdeFlow" sourceRef="managerTask" targetRef="managerJudgeTask"/>
        <endEvent id="endLeave2"/>
        <sequenceFlow id="flowEnd" name="通过" sourceRef="managerJudgeTask" targetRef="endLeave">
            <conditionExpression xsi:type="tFormalExpression">
                <![CDATA[${checkResult=='通过'}]]>
            </conditionExpression>
        </sequenceFlow>
        <sequenceFlow id="rejectFlow" name="驳回" sourceRef="managerJudgeTask"
                      targetRef="endLeave2">
            <conditionExpression xsi:type="tFormalExpression">
                <![CDATA[${checkResult=='驳回'}]]>
            </conditionExpression>
        </sequenceFlow>
    </process>
    <bpmndi:BPMNDiagram id="BPMNDiagram_process">
        <bpmndi:BPMNPlane bpmnElement="Leave" id="BPMNPlane_process">
            <bpmndi:BPMNShape bpmnElement="leaveTask" id="BPMNShape_leaveTask">
                <omgdc:Bounds height="79.99999999999999" width="100.0" x="304.60807973558974" y="122.00000000000001"/>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="managerTask" id="BPMNShape_managerTask">
                <omgdc:Bounds height="80.0" width="100.0" x="465.0" y="122.0"/>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="managerJudgeTask" id="BPMNShape_managerJudgeTask">
                <omgdc:Bounds height="40.0" width="40.0" x="611.5" y="142.0"/>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="endLeave" id="BPMNShape_endLeave">
                <omgdc:Bounds height="28.0" width="28.0" x="696.5" y="148.0"/>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="startLeave" id="BPMNShape_startLeave">
                <omgdc:Bounds height="30.0" width="30.0" x="213.2256558149128" y="147.0"/>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNShape bpmnElement="endLeave2"
                              id="BPMNShape_endLeave2">
                <omgdc:Bounds height="28.0" width="28.0" x="617.5" y="73.32098285753572"/>
            </bpmndi:BPMNShape>
            <bpmndi:BPMNEdge bpmnElement="flowEnd" id="BPMNEdge_flowEnd">
                <omgdi:waypoint x="651.1217948717949" y="162.37820512820514"/>
                <omgdi:waypoint x="696.5002839785394" y="162.0891701657418"/>
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="rejectFlow" id="BPMNEdge_rejectFlow">
                <omgdi:waypoint x="631.866093577786" y="142.36609357778607" />
                <omgdi:waypoint x="631.5931090276993" y="101.32067323657485" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="modeFlow" id="BPMNEdge_modeFlow">
                <omgdi:waypoint x="404.60807973558974" y="162.0" />
                <omgdi:waypoint x="465.0" y="162.0" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="flowStart" id="BPMNEdge_flowStart">
                <omgdi:waypoint x="243.2256558149128" y="162.0" />
                <omgdi:waypoint x="304.60807973558974" y="162.0" />
            </bpmndi:BPMNEdge>
            <bpmndi:BPMNEdge bpmnElement="jugdeFlow" id="BPMNEdge_jugdeFlow">
                <omgdi:waypoint x="565.0" y="162.21367521367523" />
                <omgdi:waypoint x="611.9141630901288" y="162.41416309012877" />
            </bpmndi:BPMNEdge>
        </bpmndi:BPMNPlane>
    </bpmndi:BPMNDiagram>
</definitions>

На самом деле, это использование различных логических линий блок-схемы для использования разныхXMLЭтикетка изображена.

<process>: Представляет полный рабочий процесс

<documentation>: описание рабочего процесса

<startEvent>: Начальная позиция в рабочем процессе (начало)

<endEvent >: Конечная позиция в рабочем процессе (конец)

<userTask>: Аудиторский узел представляет задачу (руководитель группы, менеджер и другие роли)

<exclusiveGateway>: Узел логического суждения, эквивалентный ромбу на блок-схеме.

<sequenceFlow>: линии, соединяющие каждый узел,sourceRefатрибут представляет собой начальный узел линии,targetRefАтрибут представляет узел, на который указывает линия.

Большая глыба вышеXMLВыглядит ли это очень хлопотно, если бы только был инструмент автоматической генерации, я обнаружил, чтоIDEAПоставляется с инструментами дизайна, но слишком сложен в использовании.

Как программист для программирования Baidu, возможность найти ответы в Интернете все еще в порядке, так как я чувствую, что писатьXMLБеда, так что если вы хотите прийти к официальному, вы должны были подумать об этом, может быть, есть готовые инструменты, и я просматривал официальный сайт.https://www.flowable.org/downloads.html, действительно нашел.

githubссылка для скачивания:GitHub.com/flowable/legal….......

Я нашел еще один онлайн-инструмент для редактирования:Эй, АРН, вкус: 8090 / home_online ...

Утверждение процесса

После завершения проектирования процесса остается утверждение рабочего процесса и создание блок-схемы.

Сначала запустите процесс отпуска с идентификатором сотрудникаstaffIdкак уникальный идентификатор,XMLПеременная будет получена в файлеleaveTask,FlowableСохранение базы данных внутри и возвращает идентификатор процессаprocessId, используйте его для запроса общей ситуации рабочего процесса, идентификатора задачиtaskОтдельные задачи в отпуске для сотрудников.

Уведомление: Процесс отпускаprocessIdможет содержать несколько задач отпускаtaskId.

/**
     * @author xiaofu
     * @description 启动流程
     * @date 2020/8/26 17:36
     */
    @RequestMapping(value = "startLeaveProcess")
    @ResponseBody
    public String startLeaveProcess(String staffId) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("leaveTask", staffId);
        ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("Leave", map);
        StringBuilder sb = new StringBuilder();
        sb.append("创建请假流程 processId:" + processInstance.getId());
        List<Task> tasks = taskService.createTaskQuery().taskAssignee(staffId).orderByTaskCreateTime().desc().list();
        for (Task task : tasks) {
            sb.append("任务taskId:" + task.getId());
        }
        return sb.toString();
    }

Когда вы начинаете с процесса возвратаprocessIdВзгляните на текущую блок-схему

http://localhost:4000/leave/createProcessDiagramPic?processId=37513

Далее заявление на отпуск будет отклонено, а соответствующееtaskIdПосле выполнения отклонения посмотрите на эффект всего рабочего процесса.

http://localhost:4000/leave/rejectTask?taskId=10086
 /**
     * @param taskId
     * @author xinzhifu
     * @description 驳回
     * @date 2020/8/27 14:30
     */
    @ResponseBody
    @RequestMapping(value = "rejectTask")
    public String rejectTask(String taskId) {
        HashMap<String, Object> map = new HashMap<>();
        map.put("checkResult", "驳回");
        taskService.complete(taskId, map);
        return "申请审核驳回~";
    }

Увидев, что весь процесс отпуска был успешно заблокирован после проверки менеджером.

http://localhost:4000/leave/createProcessDiagramPic?processId=37513

Суммировать

Рабочий процесс разработки обычно используется в традиционных проектах, таких как системы открытого доступа.Это первый раз, когда я пытался сделать такую ​​​​функцию, и я получил довольно много, и стек технологий вжался в точку знаний. Сегодня супер простоdemo, потому что это всего лишь начало контакта, когда я пользуюсь вором, я поделюсь больше зрелого и подробно с моими друзьями.

demoизgithubадрес:https://github.com/chengxy-nds/Springboot-Notebook/tree/master/springboot-work-flowable


Оригинальность не так проста, сжигание волос на выходе, если есть потеря, пожалуйста, дайте лайк, чтобы поощрить это!

Разобраны и розданы друзьям сотни различных технических электронных книг. Подпишитесь на официальный аккаунт, чтобы ответить【666] Самовывоз. Мы создали группу технического обмена с друзьями, чтобы обсуждать технологии и делиться технической информацией, стремясь вместе учиться и развиваться. Если вам интересно, присоединяйтесь к нам!