MyTetra Share
Делитесь знаниями!
Время создания: 18.11.2019 22:16
Раздел: INFO - JOB - CUBA - WorkFlow
Запись: wwwlir/Tetra/master/base/1569377804iznfs1vzkq/text.html на raw.githubusercontent.com

Обзор

Данный модуль для CUBA приложений предоставляет дополнительный функционал по реализации сложных рабочих процессов декларативным путем любых сущностей в системе (заявки, задачи и др.) для которых необходимо как последовательное выполнение определенных действий так и глубокое взаимодействие с пользователями на различных этапах.

Начало работы

Установка Workflow-STP Add-on

Для того, чтобы у пользователя появилась возможность использовать add-on в CUBA.platform приложении необходимо произвести установку add-on в локальный репозиторий пользователя. Рекомендуется делать эту процедуру в Cuba Studio, для этого импортируйте add-on в Cuba Studio и выполните Run -> Install app component.

Подключение Workflow-STP Add-on в CUBA.platform App

Данную операцию рекомендуется выполнять в Cuba Studio. Откройте проект в Cuba Studio и перейдите к редактированию его своств (Project properties -> Edit). Нажмите на + расположенный рядом с надписью Custom components. В выподающем спике (второе поле) должен быть доступен компонент с именем workflow-stp (в случае если вы выполнили его установку ранее). Выберите компонент, нажмите ok, сохраните настройки проекта. Workflow-STP Add-on подключен.

Так же необходимо указать настройку в файле app.properties в core модуле

wfstp.heartbeatMs = 300000

Означающую частоту обновления рабочих процессов (для поддержки таймаутов, своего рода некая допустимая задержка).

В случае если нет необходимости в этом функционале, в аддоне есть специальная надстройка:

workflow.heartbeatEnable = false

Так же модуль предусматривает отложенное обновление для облегчения и быстрого старта приложения. Настройка указывает какое количество "тиков" запланированной задачи система должна пропустить:

workflow.delayCallCount = 2

Описание предметной модели

Описание рабочего процесса состоит из нескольких основных и простых частей. Опишем каждую из них.

Обрабатываемая сущность (WorkflowEntity)

Под обрабатываемой сущностью подразумевается любая сущность в системе для которой необходимо реализовать рабочий процесс обработки. Сущность должна наследоваться от специального интерфейса:

com.groupstp.workflowstp.entity.WorkflowEntity

Которая предоставляет возможность сохранять связь с процессами, помечать текущий статус, а так же прослеживать прогресс обработки.

Рабочий процесс (Workflow)

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

  • Название(name): Название для быстрой идентификации пользователями.
  • Код (code): Машинный шифр для идентификации рабочего процесса системой.
  • Активен (active): Флажок означающий что рабочий процесс готов и может быть применен в работу.
  • Название применяемой сущности (entityName): Именование сущности для которой описан данный рабочий процесс.
  • Шаги (steps): Список определенных в рабочем процессе шагов.
  • Порядок (order): Общий порядок рабочего процесса в списке всех рабочих процессов.

Этап (Stage)

Под этапом подразумевается некое абстрактное атомарное состояние процесса обработки. Каждый этап можно разделить на определенный тип, определить действия, поведение и т.д.

  • Название(name): Название для быстрой идентификации пользователями.
  • Название применяемой сущности (entityName): Именование сущности для которой описан данный этап.
  • Тип этапа (type): Тип этапа. Возможные значения: ** Взаимодействие с пользователями (USERS_INTERACTION) - когда ожидается некоторые действия от пользователей в системе ** Архив(ARCHIVE) - состояние, которое не требует непосредственного взаимодействия от пользователей, однако помечает рабочий процесс как завершенный предоставляет возможность постоянного просмотра ** Выполнение алгоритма(ALGORITHM_EXECUTION) - этап подразумевает выполнение системы некоторой последовательности команд.
  • Участники (actors): В случае с типом USERS_INTERACTION можно указать конкретных пользователей, от которых ожидается действие.
  • Участники по ролям (actorsRoles): В случае с типом USERS_INTERACTION можно указать конкретные роли пользователей, от которых ожидается действие. И если пользователь обладает хоть одной ролью из перечисленных, он является полноправным участником данного этапа.
  • Наблюдатели (viewers): В случае с типом USERS_INTERACTION можно указать конкретных пользователей, которые имеют возможность взаимодействовать с этапом, но только в режиме просмотра (viewOnly).
  • Наблюдатели по ролям (viewersRoles): В случае с типом USERS_INTERACTION можно указать конкретныt роли пользователей, которые имеют возможность взаимодействовать с этапом, но только в режиме просмотра (viewOnly). И если пользователь обладает хоть одной ролью из перечисленных, он является полноправным наблюдателем данного этапа. В случае если пользователь и наблюдатель и участник - система воспримет его как участника.
  • Набор команд для выполнения (executionGroovyScript): В случае с типом ALGORITHM_EXECUTION необходимо предоставить набор команд, которые необходимо выполнить системе.
  • Системный сервис выполнения (executionBeanName): В случае с типом ALGORITHM_EXECUTION можно так же просто указать системный сервис для выполнения. Он должен имплементировать интерфейс com.groupstp.workflowstp.service.WorkflowExecutionDelegate. В системе так же предусмотрен базовый класс для com.groupstp.workflowstp.service.AbstractWorkflowExecutionDelegate.
  • Описание расширения экрана списков (browserScreenConstructor): В случае с типом USERS_INTERACTION или ARCHIVE можно декларативно задать главные элементы экрана для страницы со списоком.
  • Описание расширения экрана редактора (editorScreenConstructor): В случае с типом USERS_INTERACTION или ARCHIVE можно декларативно задать главные элементы экрана для страницы с редактором.
  • Общее расширение экрана (screenConstructor): В случае с типом USERS_INTERACTION или ARCHIVE можно декларативно задать общие элементы экранов как для списков так и для редактора.
  • Переменные направлений (directionVariables): Перечисление возможных переменных из этапа, которые будут подчищены при движении по одному из направлений.

Шаг (Step)

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

  • Порядок(order): Порядок шага для отображения в пользовательском интерфейсе.
  • Начальный(start): Является ли данный шаг начальным для рабочего процесса. Рабочий процесс может иметь только один начальный шаг.
  • Этап(stage): Связь шага с этапом. Шаг может иметь только один этап. Этап же может иметь несколько шагов.
  • Срок выполнения(timeoutSec): Можно задать максимальное время (в секуднах) при котором если данный шаг не будет выполнен, задача пометится как просроченная и рабочий процесс двинется дальше. При возникновении таймаута, в контекст экземпляра рабочего процесса будет помещена пометка 'wf_timeout' которая может быть легко обработана клиентским кодом.
  • Время повторения(repeatSec): Должен ли текущий шаг быть повторен через определенный промежуток времени (в секундах). В данном случае если скрипт шаг вернет отрицательный результат, процесс выполнения данного шага повторится.
  • Направления(directions): Возможные направления рабочего процесса на другие шаги от текущего.
  • Рабочий процесс(workflow): Связь шага с рабочим процессом.

Направления (StepDirection)

Данная сущность представляет собой условное направление рабочего процесса из одного шага в другой в пределах одного рабочего процесса.

  • Порядок(order): Порядок перебора направлений при определении следующего шага в рабочем процессе.
  • Откуда(from): Связь с шагом откуда происходит перемещение состояния рабочего процесса.
  • Куда(to): Связь с шагом куда происходит перемещение состояния рабочего процесса.
  • SQL условие(conditionSqlScript): SQL условие перехода. В данном условии можно описать SQL выражение применимое для обрабатываемой сущности.
  • Groovy условие(conditionGroovyScript): Groovy условие перехода. Здесь можно описать условие на высокоуровневом языке Groovy с Java-подобным синтаксисом.

Определение процесса (WorkflowDefinition)

Так как для одной сущности в системе могут существовать одновременно несколько различных рабочих процессов, можно динамически задать условия определения выбора того или иного рабочего процесса в зависимости от обрабатываемой сущности и др.

  • Наименование сущности(entityName): Уникальное именование сущности в системе для которой применим данный определитель.
  • Рабочий процесс(workflow): Связь с активным рабочим процессом который будет использован в случае удачного применения определителя.
  • Приоритет(priority): Приоритет определения. Чем выше приоритет, тем более первым он будет использован для вычисления.
  • SQL условие(conditionSqlScript): SQL условие для успешного применения определения.
  • Groovy условие(conditionGroovyScript): Groovy условие для успешного применения определения.

Экземпляр рабочего процесса (WorkflowInstance)

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

  • Рабочий процесс(workflow): Связь экземпляра рабочего процесса с самим рабочим процессом (шаблоном).
  • Наименование сущности(entityName): Уникальное имя сущности в системе.
  • Идентификатор сущности(entityId): Уникальный идентификатор конкретной обрабатываемой сущности.
  • Контекст переменных исполнения(context): Контекст исполнения экземпляра рабочего процесса содержащий в себе все требуемые переменные и данные которые могут быть сохранены в пределах всего времени выполнения экземпляра рабочего процесса.
  • Комментарии(comments): Список возникших комментариев при выполнении экземпляра рабочего процесса.
  • Задачи(tasks): Список задач возникших при выполнении экзепляра рабочего процесса, как активных так и завершенных.
  • Время начала(startDate): Время запуска рабочего процесса.
  • Время завершения(endDate): Время полного завершения текущего рабочего процесса.
  • Сообщение об ошибке(error): Сообщение об ошибке в случае неудачного завершения экземпляра рабочего процесса.
  • Ошибка получена при выполнении задачи(errorInTask): Возникла ли ошибка при выполнении задачи, или ошибка связана с иными случаями (например обрабатываемая сущность была удалена).

Комментарий (WorkflowInstanceComment)

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

  • Экземпляр рабочего процесс(instance): Связь комментария и выполняемого экземпляра рабочего процесса.
  • Задача (task): Связь комментария с выполняемой задачей рабочего процесса, при котором был создан комментарий.
  • Автор(author): Автор комментарий
  • Сообщение(comment): Само сообщение комментария
  • Вложение(attachment): При создании комментария есть возможность прикрепить любой файл или архив как вложение.

Задача (WorkflowInstanceTask)

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

  • Экземпляр рабочего процесс(instance): Связь задачи и выполняемого экземпляра рабочего процесса.
  • Задача (step): Связь задачи с выполняемым шагом описанным в рабочем процесса.
  • Время начала(startDate): Время начала задачи, когда экземпляр рабочего процесса изменил текущий шаг.
  • Время завершения(endDate): Время завершения задачи, когда экземпляр рабочего процесса выполнил описанный шаг и изменяет свое состояние.
  • Исполнитель(performer): Связь на пользователя исполнителя, который завершил текущую задачи и изменил состояние экземпляра рабочего процесса.

Расширение пользовательских экранов

Workflow-STP Add-on предоставляет возможность видоизменять динамически пользовательский интерфейс в зависимости от обрабатываемого шага. Пользователь может при описании рабочего процесса определить какие поля могут быть редактируемые, задать перечень отображаемых колонок, задать их редактируемость. А так же расширить представление экрана путем описания дополнительного Groovy кода.

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

По умолчанию расширяются стандартные экраны browse и edit обрабатываемых сущностей. Можно переопределить какие экраны необходимо расширять, достаточно поставить аннотацию над требуемой сущностью и определить экраны

com.groupstp.workflowstp.annotation.WorkflowDetails

Например:

@WorkflowDetails(browseId = "my-browse", editorId = "my-edit")
@Entity(name = "wfstpdemo$Ticket")
public class Ticket extends StandardEntity implements WorkflowEntity<UUID> {
    ...
}

Опишем основные моменты.

ScreenActionTemplate (Действия)

Здесь можно задать некий шаблон действия (кнопку) в случае которого выполнится заранее определенная логика. Рассмотрим на примере создания общей кнопки экспорта в Excel.

  • Наименование действия(name): Название действия для быстрой идентификации. Например "Экспорт в Excel".
  • Действие всегда доступно(alwaysEnabled): Доступна ли всегда данное действие даже если оно открыто только для просмотра. Например "да".
  • Заголовок(caption): Заголовок действия который будет отображен на экране. Например "Excel".
  • Иконка(icon): Связь задачи и выполняемого экземпляра рабочего процесса. Например "⇪"
  • Стиль(style): Стиль отображения кнопки. При отсутствии будет использован стить по-умолчанию.
  • Код выпонения(script): Код на языке Groovy который необходимо выполнить системе для выполнения действия. Например
new com.haulmont.cuba.gui.components.actions.ExcelAction(target).actionPerform(target)

ScreenTableColumnTemplate (Колонки)

При расширении экрана с таблицами можно задать какие колонки будут отображены и в каком виде.

  • Наименование колонки(name): Название действия для быстрой идентификации. Например "Колонка аэропортов".
  • Заголовок(caption): Заголовок колонки который будет отображен. Например "Аэропорты".
  • Идентификатор колонки(columnId): Все колонки в таблице должны имень уникльный идентификатор. Например можно задать "Airport_column" или указать непосредственную связь "invoice.airport"
  • Скрипт генерации(generatorScript): Код генерации колонки на языке Groovy который должен вернуть класс:
com.groupstp.workflowstp.web.util.data.ColumnGenerator или com.haulmont.cuba.gui.components.Table.ColumnGenerator

ScreenExtensionTemplate (Экраны)

Модуль так же предоставляет возможность заранее полностью динамически определить отображение целого экрана.

  • Наименование экрана(name): Название экрана для быстрой идентификации. Например "Каталог телефонов".
  • Ключ экрана(key): Заранее определенный уникальный ключ расширение экрана, который используется для вызова построения. Например "phone-catalog".
  • Имя сущности(entityName): Идентификатор-имя обрабатываемой сущности.
  • Идентификатор экрана(screenId): Идентификатор экрана системы который может быть расширен.
  • Конструктор экрана(screenConstructor): Содержание расширения экрана

Подготовка проекта для интеграции обработки процессами.

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

1. Подготовка обрабатываемой сущности.

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

...
import com.groupstp.workflowstp.entity.Workflow;
import com.groupstp.workflowstp.entity.WorkflowEntity;
import com.groupstp.workflowstp.entity.WorkflowEntityStatus;
...

@Entity(name = "wfstpdemo$Ticket")
public class Ticket extends StandardEntity implements WorkflowEntity<UUID> {
    private static final long serialVersionUID = 7337017127753361381L;

    @Column(name = "STEP_NAME")
    private String stepName;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "WORKFLOW_ID")
    private Workflow workflow;

    @Column(name = "STATUS")
    private Integer status;

    ...
}

2. Подготовка экранов с обрабатываемой сущностью (для рабочих процессов с пользовательским взаимодействием)

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

Для указания позиции для действий достаточно подключить xsd схему к экрану и указать в корневом элементе XML экрана идентификатор контейнера действий.

<window xmlns="http://schemas.haulmont.com/cuba/window.xsd"
        xmlns:wf="http://schemas.groupstp.com/wf/0.1/wf-schema.xsd"
        wf:actions="bottomPanel">

        <hbox id="bottomPanel" spacing="true"/>
</window>

Для возможности задания редактирования свойств пожалуйста укажите у каждого идентификатор (id)

<fieldGroup id="fieldGroup"
                datasource="ds">
    <column width="250px">
        <field property="urgent" id="urgent"/>
    </column>
</fieldGroup>
<richTextArea datasource="ds" property="description" id="description" width="100%" required="true"/>

3. Интеграция с внешними системами

Управление рабочими процессами (отображение колонок, выполнение действий) может быть интегрированно с внешними системами через технологию REST. Сервис который предоставляет данный функционал описан в классе com.groupstp.workflowstp.rest.controller.WorkflowRestAPI В проекте есть дескриптор этого сервиса в формате raml:

#%RAML 0.8
title: REST сервис рабочих процессов
version: v1
baseUri: url_сервера:порт/app/rest/wf/workflow

/all:
  get:
    description: |
      Получить все доступные рабочие процессы с их настройками (действиями, отображаемыми колонками-свойствами, редактируемые поля и т.д.)

    responses:
      200:
        body:
          application/json:
              example: |
                [
                    {
                        "id": "920a5902-061e-76b5-882e-91ccca1bccc7",
                        "name": "Обработка задач",
                        "code": "A1",
                        "entity_name": "test$Task",
                        "steps": [
                            {
                                "id": "b55f895e-4bfa-c6df-ceb6-3806261979d0",
                                "name": "Финансовый контроль",
                                "entity_name": "test$Task",
                                "permission": "FULL",  //Может быть FULL (полный доступ к шагу), READ_ONLY (шаг доступен только на чтение)
                                "actions": [//список действий
                                    {
                                        "id": "60131a32-4d64-1b1f-48df-a118049c7163",
                                        "caption": "Согласование",
                                        "icon": "fa-check",
                                        "always_enabled": false,
                						"style": "primary",
                                        "order": 1
                                    },
                                    {
                                        "id": "f8fc2022-5434-4572-6c5d-757d39a8778b",
                                        "caption": "Excel",
                                        "icon": "fa-file-excel-o",
                                        "always_enabled": true,
                                        "order": 4
                                    },
                                ],
                                "browser_columns": [//список отображаемых колонок
                                    {
                                        "id": "number",
                                        "caption": "Номер",
                                        "order": 1
                                    },
                                    {
                                        "id": "amount",
                                        "caption": "Сумма",
                                        "order": 2
                                    }
                                ],
                                "editor_fields": [//список редактируемых свойств
                                    {
                                        "id": "images",
                                        "caption": "Вложения"
                                    },
                                    {
                                        "id": "taxNumber",
                                        "caption": "ИНН"
                                    },
                                    {
                                        "id": "company",
                                        "caption": "Компания"
                                    }
                                ],
                                "order": 1
                            },
                            {
                                "id": "565ce6a3-fb01-44a0-9ed7-9f3761dcc909",
                                "name": "Согласование с директором",
                                "entity_name": "test$Task",
                                "permission": "READ_ONLY",
                                "actions": [
                                    {
                                        "id": "0acfa67a-f0dc-53c1-1879-4e53dab154ca",
                                        "caption": "Согласование",
                                        "icon": "fa-check",
                                        "always_enabled": false,
                						"style": "primary",
                                        "order": 1
                                    },
                                    {
                                        "id": "71399dbc-59a8-036f-744f-eb20db015e72",
                                        "caption": "Excel",
                                        "icon": "fa-file-excel-o",
                                        "always_enabled": true,
                                        "order": 2
                                    }
                                ],
                                "browser_columns": [
                                    {
                                        "id": "number",
                                        "caption": "Номер",
                                        "order": 1
                                    },
                                    {
                                        "id": "amount",
                                        "caption": "Сумма",
                                        "order": 2
                                    }
                                ],
                                "editor_fields": [
                                    {
                                        "id": "urgent",
                                        "caption": "Срочность"
                                    }
                                ],
                                "order": 2
                            }
                        ],
                        "order": 1
                    },
                    {
                        "id": "e49e98c9-de58-ecaf-0289-62cf2c4309d2",
                        "name": "Двойное согласование",
                        "code": "A2",
                        "entity_name": "test$Task",
                        "steps": [],
                        "order": 2
                    }
                ]

/start:
  post:
    description: |
      Запустить рабочий процесс для указанной сущности и получить идентификатор запущенного процесса

    queryParameters:
      entityId:
        type: текст
        description: идентификатор сущности
        example: e49e98c9-de58-ecaf-0289-62cf2c4309d2
        required: true
      entityName:
        type: текст
        description: имя сущности
        example: 'test$Task'
        required: true

    responses:
      200:
        body:
          application/json:
            example: |
                {
                    "result": "b34c8ad4-1e05-4119-ee14-1fb30e86fc8c"
                }

/processing:
  get:
    description: |
      Получить информацию запущена ли сущность в рабочий процесс, и если да, система вернет идентификатор запущенного процесса

    queryParameters:
      entityId:
        type: текст
        description: идентификатор сущности
        example: e49e98c9-de58-ecaf-0289-62cf2c4309d2
        required: true
      entityName:
        type: текст
        description: имя сущности
        example: 'test$Task'
        required: true

    responses:
      200:
        body:
          application/json:
            example: |
                {
                    "result": "b34c8ad4-1e05-4119-ee14-1fb30e86fc8c"
                }

/performable:
  get:
    description: |
      Получить информацию о том возможно ли выполнить указанное действие для указанных сущностей в текущий момент или нет

    queryParameters:
      entityId:
        type: список
        description: идентификаторы сущностей
        example: e49e98c9-de58-ecaf-0289-62cf2c4309d2
        required: true
      workflowId:
        type: текст
        description: идентификатор рабочего процесса
        example: e49e98c9-de58-ecaf-0289-62cf2c4309d2
        required: true
      stepId:
        type: текст
        description: идентификаторы выполняемого шага
        example: e49e98c9-de58-ecaf-0289-62cf2c4309d2
        required: true
      actionId:
        type: список
        description: идентификаторы проверяемых действий
        example: e49e98c9-de58-ecaf-0289-62cf2c4309d2
        required: true

    responses:
      200:
        body:
          application/json:
            example: |
                {
                    "result": {
                        "cb6ee232-d82d-43b2-6775-ad4e91613523": true,
                        "c5896b1d-bb27-7c50-2bd7-debc0bab0ec2": true
                    }
                }

/perform:
  post:
    description: |
      Произвести выполнение указанного действия текущим пользователем для указанных сущностей

    queryParameters:
      entityId:
        type: список
        description: идентификаторы сущностей
        example: e49e98c9-de58-ecaf-0289-62cf2c4309d2
        required: true
      workflowId:
        type: текст
        description: идентификатор рабочего процесса
        example: e49e98c9-de58-ecaf-0289-62cf2c4309d2
        required: true
      stepId:
        type: текст
        description: идентификаторы выполняемого шага
        example: e49e98c9-de58-ecaf-0289-62cf2c4309d2
        required: true
      actionId:
        type: текст
        description: идентификатор действия
        example: e49e98c9-de58-ecaf-0289-62cf2c4309d2
        required: true
    body: |
        Любая полезная нагрузка

    responses:
      200:
        body:
          application/json:
            example: |
                {
                    "result": "Success"
                }

Дополнение A: Свойства модуля.

Основные свойства

workflow.showSelection

  • Description: Показывать ли дополнительную колонку выбора при расширении таблиц экрана.
  • Default value: true
  • Type: Используется на web уровне
  • Interface: WorkflowWebConfig

workflow.printScreenExtensionScripts

  • Description: Выводить ли в лог файл сгенерированные Groovy коды экранов расширений.
  • Default value: false
  • Type: Используется на web уровне
  • Interface: WorkflowWebConfig

Дополнение Б: Основная логика.

Вся основная логика рабочих процессов обрабатывается в Spring контекстах в двух модулях. Рекомендуется ознакомится с ними.

На core модуле сервис отвечающий за работоспособность рабочих процессов:

com.groupstp.workflowstp.service.WorkflowService

На web модуле сервис отвечающий за расширение экранов и действий:

com.groupstp.workflowstp.web.bean.WorkflowWebBean

Дополнение В: Вспомогательные классы-помощники.

Workflow-STP Add-on поставляется с заранее определенным набором вспомогательных классов для быстрого описания рабочих процессов. При написании кода выполнения рабочих процессов рекомендуется с ними ознакомиться и, в случае необходимости, расширить.

com.groupstp.workflowstp.web.util.MapHelper

Класс для быстрого создания структур типа Ключ-Значение

com.groupstp.workflowstp.web.util.WebUiHelper

Класс для выполнения и обработки рабочих процессов на web модуле приложения.

com.groupstp.workflowstp.web.util.WorkflowInstanceHelper

Класс для работы с экземплярами рабочих процессов.

com.groupstp.workflowstp.rest.util.RestUiHelper

Класс для выполнения и обработки рабочих процессов на rest модуле приложения.

Дополнение Г: Тестовый проект

Самый простой проект использующий данный модуль.

 
MyTetra Share v.0.59
Яндекс индекс цитирования