Motor de flujo de trabajo de actividad

Tabla de contenido

1. Comprender el flujo de trabajo

1. ¿Qué es el flujo de trabajo?

2. Motor de flujo de trabajo

3. Motores de flujo de trabajo comunes

4. Resumen de Activiti7

4.1 Introducción a Activiti

4.2 Lenguaje de modelado BPMN

4.3, Proceso de uso de Activiti

dos, actividad7

1. Uso de Actividades

1.1, soporte de base de datos

1.2, Entorno de actividad

1.3, interfaz de servicio de servicio común de Activiti

1.4 Herramienta de diseño de procesos

2. Operación del proceso de actividad

2.1 Definición del proceso

2.2 Despliegue de definición de procesos

2.3 Iniciar la instancia del proceso

2.4 Tarea de consulta

2.5, procesando la tarea actual

2.6 Consulta de tareas procesadas

2.7 Otras interfaces (entender)

3. Ejemplo de proceso

3.1, qué es una instancia de proceso

3.2 Asociar el negocio real con la tabla de actividades (BusinessKey)

3.3 Suspender y activar la instancia de proceso

4. Asignación de tareas

4.1 Distribución fija

4.2 Asignación de expresiones

4.3 Asignación de oyentes

5. Variables de proceso

5.1, que es una variable de proceso

5.2, el alcance de las variables de proceso

5.3 Cómo utilizar variables de proceso

5.4, ​​establecer la variable global

5.5 Establecer variables locales

6. Grupo de trabajo

6.1, Candidatos-usuarios candidatos

6.2 Proceso de manejo de tareas grupales

6.3 Código clave

7. Puerta de enlace

7.1 Puerta de enlace exclusiva

7.2 Puerta de enlace paralela

7.3, incluida la puerta de enlace


1. Comprender el flujo de trabajo

1. ¿Qué es el flujo de trabajo?

Workflow (Workflow) consiste en automatizar la gestión de los procesos de negocio a través de las computadoras. Resuelve principalmente "el proceso de transferencia automática de documentos, información o tareas entre múltiples participantes de acuerdo con algunas reglas predefinidas , para lograr un determinado objetivo comercial esperado o promover la realización de este objetivo". En términos sencillos, es un proceso de aprobación completo en los negocios. Por ejemplo, licencias de empleados, viajes de negocios, compras fuera del hogar, revisión de contratos, etc., todos estos procesos son un flujo de trabajo.

2. Motor de flujo de trabajo

Para el procesamiento del flujo de trabajo, si usamos el método original, debemos llevar varios documentos a cada persona a cargo para que los firme, y deben ser aprobados continuamente por varios departamentos. Este método requiere mucho tiempo y es laborioso. Y podemos usar el sistema de software para que nos ayude a manejar estos procesos de aprobación, por lo que aparece un sistema de flujo de trabajo, que puede mejorar en gran medida la eficiencia del trabajo después de usar el sistema de flujo de trabajo.

En el proceso de aprendizaje del flujo de trabajo, debemos haber visto este modelo: completar el formulario de licencia -> aprobación del gerente de departamento -> aprobación del gerente general -> archivo de personal.

(1) Para realizar el proceso mencionado anteriormente, podemos lograr este efecto de aprobación a través de la identificación del campo y agregar un campo en la tabla de negocios, como completar el formulario de licencia con 1, gerente de departamento con 2, gerente general con 3 , personal El registro está marcado con 4. Parece que no hay problema, y ​​se ha logrado el efecto de aprobación. Pero una vez que cambia nuestro proceso, necesitamos cambiar nuestro código en este momento, lo que obviamente no es aconsejable, entonces, ¿hay alguna forma profesional de lograr la gestión del flujo de trabajo? Y se puede lograr que después de que cambie el proceso comercial, nuestro programa no necesite cambiarse.Si se puede lograr este efecto, entonces la adaptabilidad de nuestro sistema comercial mejorará en gran medida. En este contexto, surgió un motor de flujo de trabajo .

¿Por qué utilizar un motor de flujo de trabajo para lograr cambios en los procesos de negocio, sin modificar el código, y el proceso puede avanzar automáticamente?

(1) Primero hablemos de por qué el proceso cambia sin modificar el código: nuestro motor de flujo de trabajo ha implementado una especificación, que requiere que nuestra gestión de procesos no tenga nada que ver con el campo de estado, y siempre es el siguiente paso para leer el negocio nodo de diagrama de flujo. Cuando se actualiza el negocio, solo necesitamos actualizar el diagrama de flujo del negocio. Esto permite cambios en los procesos comerciales sin modificar el código.

(2) Hablemos del avance automático del proceso. Este principio es aún más simple. Tome el modelo de licencia anterior como ejemplo. El motor de flujo de trabajo utilizará una tabla para registrar el nodo actual. Después de llenar el formulario de baja, debe ser el turno del jefe de departamento para aprobarlo, por lo que una vez que completemos el formulario de baja, este registro se eliminará de este formulario, y la información del jefe de departamento del siguiente nodo se insertará en esta tabla, cuando usamos la información del gerente del departamento para consultar esta tabla, podemos encontrar la información de aprobación relevante del gerente del departamento, y así sucesivamente, para que se realice el envío automático del proceso.

3. Motores de flujo de trabajo comunes

Los marcos principales son: Activiti , jBPM, Camunda, Flowable y nuestro Pangu BPM doméstico, Yuncheng

4. Resumen de Activiti7

4.1 Introducción a Activiti

activiti es un motor de flujo de trabajo que puede extraer procesos comerciales complejos en sistemas comerciales, definirlos utilizando un lenguaje de modelado especial BPMN y ejecutar procesos comerciales de acuerdo con procesos predefinidos. El proceso del sistema es administrado por activiti, lo que reduce la carga de trabajo del sistema comercial para la actualización y transformación del sistema debido a cambios en el proceso, mejorando así la solidez del sistema y reduciendo el costo de desarrollo y mantenimiento del sistema.

Sitio web oficial: https://www.activiti.org

4.2 Lenguaje de modelado BPMN

BPM (gestión de procesos comerciales) es la gestión de procesos comerciales, que es una construcción estandarizada de procesos comerciales de extremo a extremo para mejorar continuamente la eficiencia comercial de la organización.

El software BPM es una herramienta de TI que promueve la organización y el ajuste de métodos y soluciones comerciales entre personas, entre personas y sistemas, y entre sistemas de acuerdo con los cambios en el entorno comercial de la empresa. El uso de software BPM para modelar, automatizar, administrar, monitorear y optimizar todo el ciclo de vida de los procesos comerciales internos y externos puede reducir los costos corporativos y aumentar las ganancias.

BPMN (modelo y notación de procesos comerciales) es un modelo y una notación de procesos comerciales. Se trata de un conjunto de notaciones de modelado de procesos comerciales estándar. Los procesos comerciales se pueden crear utilizando las notaciones proporcionadas por BPMN. Activit utiliza BPMN para el modelado de procesos y la gestión de ejecución de procesos

BPMN2.0 es un acrónimo de Business Process Modeling Notation 2.0, que fue creado y desarrollado continuamente por Business Process Management Initiative, una asociación sin fines de lucro. BPMN2.0 es un conjunto de especificaciones de símbolos que utilizan algunos símbolos para aclarar el diagrama de flujo del diseño de procesos comerciales, lo que puede mejorar la eficiencia de la comunicación en el modelado comercial. Actualmente BPMN2.0 es la última versión, se utiliza para el diseño y la comunicación visual en el contexto de BPM

Los símbolos básicos de BPMN2.0 incluyen principalmente:

  • Evento Evento

Inicio: Indica el inicio de un proceso

Medio: entre los eventos de inicio y fin que ocurren, afectando el flujo de procesamiento

Fin: Indica el final del proceso

editar

  • Actividades Actividades

Actividad es un término general para trabajo o tarea. Una actividad puede ser una tarea o un subproceso del proceso actual; en segundo lugar, también puede especificar diferentes tipos para la actividad. Las actividades comunes son las siguientes:

editar

  • GatewayGateWay

Hay varias puertas de enlace de uso común que deben entenderse para representar la ramificación y la fusión de procesos:

    • Pasarela exclusiva: solo se elegirá una ruta

    • Puertas de enlace paralelas: se elegirá cada ruta

    • Puerta de enlace inclusiva: puede ejecutar varias líneas al mismo tiempo, también establecer condiciones en la puerta de enlace

    • Event Gateway: está especialmente configurado para eventos de captura intermedios, lo que permite que múltiples flujos de salida apunten a múltiples eventos de captura intermedios diferentes. Cuando el proceso se ejecuta en la puerta de enlace de eventos, el proceso está en un estado de espera y debe esperar a que se inicie un evento para convertir el estado de espera en un estado activo.

  • Flujo a flujo

Un flujo es una conexión entre dos nodos de proceso. Las direcciones de flujo comunes incluyen lo siguiente:

Flujo de secuencia: Representado por una línea sólida con una flecha sólida, se utiliza para especificar el orden en que se ejecutan las actividades.

Flujo de información: representado por una línea de puntos con una flecha, se utiliza para describir el flujo de mensajes enviados y recibidos entre dos participantes comerciales independientes (entidades comerciales/roles comerciales)

Asociación: representada por una línea de puntos con una flecha de línea, utilizada para asociar datos relacionados, texto y otros artefactos con objetos de flujo. Entradas y salidas para exhibir actividades

Ejemplo de proceso:

4.3, Proceso de uso de Activiti

Paso 1: Introducir dependencias e inicializar la base de datos

Dado que activiti es un marco, definitivamente debemos introducir las coordenadas del paquete jar correspondiente, consulte el código específico.

Paso 2: Dibuje un diagrama de flujo a través de herramientas

Use la herramienta de modelado de procesos activiti (diseñador de actividades) para definir procesos comerciales (archivos .bpmn)

El archivo .bpmn es el archivo de definición de procesos comerciales, que define el proceso comercial a través de xml.

El tercer paso : implementación de la definición del proceso;

Implemente la definición del proceso comercial (archivo .bpmn) en activiti, use la API proporcionada por activiti para implementar el archivo .bpmn en activiti,

En términos sencillos, es dejar que las actividades conozcan el proceso que se utilizará.

Paso 4: Inicie una instancia de proceso (ProcessInstance)

Iniciar una instancia de proceso significa iniciar una operación de proceso empresarial. Por ejemplo, se completa la implementación del proceso de licencia del empleado. Si Zhang San desea solicitar una licencia, puede iniciar una instancia de proceso. Si Li Si desea solicitar una licencia, debe también puede iniciar una instancia de proceso. La ejecución de los dos procesos no se afecta entre sí. , al igual que definir una clase java e instanciar dos objetos, el proceso de implementación es como una clase java, iniciar una instancia de proceso es como un objeto java nuevo

Paso 5: El usuario consulta las tareas pendientes (Task)

Debido a que el proceso comercial del sistema ha sido entregado a activiti para su administración, a través de activiti, puede consultar dónde se está ejecutando el proceso actual y qué tareas debe manejar el usuario actual Activiti nos ayuda a administrarlas. De hecho, cuando aprendemos activiti, solo aprendemos cómo usar su API, porque muchas funciones de activiti han sido empaquetadas y podemos llamarlas.

Paso 6: El usuario maneja las tareas

Después de que el usuario consulta las tareas pendientes, puede manejar una determinada tarea. Si la tarea se completa, otros usuarios deben manejarla. Por ejemplo, después de que se crea el formulario de licencia, el gerente del departamento lo revisará. Este proceso es también completado por activiti para nosotros, y no necesitamos escribir en el código Codificado para especificar el siguiente controlador de tareas

Paso Siete: Fin del Proceso

Cuando se completa el procesamiento de la tarea y no hay un nodo de tarea siguiente, la instancia de proceso se completa.

dos, actividad7

1. Uso de Actividades

1.1, soporte de base de datos

La operación de Activiti debe tener el soporte de la base de datos, las bases de datos soportadas son: mysql, oracle, postgres, mssql, db2, h2

1.2, Entorno de actividad

Explicamos directamente la introducción a Activiti en el proyecto actual: guigu-oa-parent

1.2.1 Introducción de dependencias

<!--引入activiti的springboot启动器 -->
<dependency>
    <groupId>org.activiti</groupId>
    <artifactId>activiti-spring-boot-starter</artifactId>
    <version>7.1.0.M6</version>
    <exclusions>
<!--除去mybatis依赖:如果你的项目中无mybatis或者mybatisPlus依赖可不加-->
        <exclusion>
            <artifactId>mybatis</artifactId>
            <groupId>org.mybatis</groupId>
        </exclusion>
    </exclusions>
</dependency>

Descripción: después de que Activiti7 se integre con SpringBoot, el marco de seguridad de SpringSecurity se integra de manera predeterminada. El marco de Activiti verificará si el usuario existe; de ​​lo contrario, se producirá una excepción.

editar

1.2.2 Añadir configuración

Se ha agregado el proyecto de fuente de datos, solo necesita la siguiente configuración

spring:    
	activiti:
      #    false:默认,数据库表不变,但是如果版本不对或者缺失表会抛出异常(生产使用)
      #    true:表不存在,自动创建(开发使用)
      #    create_drop: 启动时创建,关闭时删除表(测试使用)
      #    drop_create: 启动时删除表,在创建表 (不需要手动关闭引擎)
      database-schema-update: true
      #监测历史表是否存在,activities7默认不开启历史表
      db-history-used: true
      #none:不保存任何历史数据,流程中这是最高效的
      #activity:只保存流程实例和流程行为
      #audit:除了activity,还保存全部的流程任务以及其属性,audit为history默认值
      #full:除了audit、还保存其他全部流程相关的细节数据,包括一些流程参数
      history-level: full
      #校验流程文件,默认校验resources下的process 文件夹的流程文件
      check-process-definitions: true

1.2.3, iniciar el proyecto

Inicie el proyecto para generar la tabla de la base de datos del proyecto.

1.2.4, introducción a la tabla de la base de datos

El soporte de operación de Activiti debe tener el soporte de estas 25 tablas, principalmente para registrar los sujetos de usuario que participan en el proceso, la información del grupo de usuarios, la definición del proceso, la información de ejecución del proceso y la información histórica del proceso durante la operación del proceso comercial, etc.

1. Reglas y funciones de nomenclatura de tablas

Al observar las tablas creadas, encontramos que todas las tablas de Activiti comienzan con act_, seguido de un identificador de dos letras que indica el propósito de la tabla, que también corresponde a la API del servicio proporcionado por Activiti:

  • ACT_RE: RE significa repositorio, la tabla de prefijos contiene la definición del proceso y los recursos estáticos del proceso (imágenes, reglas, etc.)
  • ACT_RU: RU representa el tiempo de ejecución. Cuando estas tablas se están ejecutando, contendrán datos en curso, como instancias de proceso, tareas, variables y tareas asíncronas. Activiti solo guarda estos datos durante la ejecución de la instancia del proceso y elimina estos registros al final del proceso. De esta manera, la mesa siempre se puede mantener pequeña y rápida.
  • ACT_HI: HI significa historial, estas tablas contienen algunos datos históricos, como instancias históricas de procesos, variables, tareas, etc.
  • ACT_GE: GE significa datos generales, generales

2. Introducción a la tabla de datos de Activiti

clasificación de tablas

Nombre de la tabla

explicar

informacion General

[ACT_GE_BYTEARRAY]

Definiciones genéricas de procesos y recursos de procesos

[ACT_GE_PROPIEDAD]

propiedades relacionadas con el sistema

Historial de procesos

[ACT_HI_ACTINST]

Ejemplos de procesos históricos

[ACT_HI_ATTACHMENT]

Archivos adjuntos de procesos históricos

[ACT_HI_COMMENT]

información histórica descriptiva

[ACT_HI_DETALLE]

Información detallada sobre las ejecuciones de procesos históricos

[ACT_HI_IDENTITYLINK]

Relación de usuario durante la ejecución del proceso histórico

[ACT_HI_PROCINST]

Ejemplos de procesos históricos

[ACT_HI_TASKINST]

Ejemplos de tareas históricas

[ACT_HI_VARINST]

Información variable en el proceso histórico en ejecución

Tabla de definición de procesos

[ACT_RE_Implementación]

Información de la unidad de implementación

[ACT_RE_MODELO]

información del modelo

[ACT_RE_PROCDEF]

Definición de proceso implementado

ejecutar tabla de instancias

[ACT_RU_EVENT_SUBSCR]

eventos de tiempo de ejecución

[ACT_RU_EJECUCIÓN]

Instancia de ejecución de proceso en tiempo de ejecución

[ACT_RU_IDENTITYLINK]

Información de relación de usuario en tiempo de ejecución, almacenamiento de información sobre participantes y nodos de tareas

[ACT_RU_JOB]

trabajo en tiempo de ejecución

[ACT_RU_TAREA]

tarea en tiempo de ejecución

[ACT_RU_VARIABLE]

tabla de variables de tiempo de ejecución

1.3, interfaz de servicio de servicio común de Activiti

Introduzca brevemente las clases de implementación de cada Servicio:

  • Servicio de repositorio

Clase de administración de recursos de Activiti, que es responsable de implementar definiciones de procesos y administrar recursos de procesos. Al usar Activiti, la implementación del proceso debe completarse primero y el diagrama de flujo comercial diseñado por la herramienta de modelado se implementará a través de RepositoryService.

  • RuntimeService

La clase de gestión de operaciones de procesos de Activiti se utiliza para iniciar una nueva instancia de proceso y obtener información relevante sobre la ejecución del proceso. La definición de proceso se utiliza para determinar la estructura y el comportamiento de cada nodo en un proceso, y la instancia de proceso es una ejecución de la definición de proceso correspondiente, que puede entenderse como la relación entre clases y objetos en Java.

  • Servicio de tareas

La clase de administración de tareas de Activiti se usa para manejar varias tareas en las operaciones comerciales, como consultar tareas asignadas a usuarios o grupos, crear nuevas tareas, asignar tareas, determinar y completar una tarea.

  • HistorialServicio

La clase de gestión de historial de Activiti puede consultar información histórica. Al ejecutar un proceso, el motor guardará una gran cantidad de datos, como la hora de inicio de la instancia del proceso, los participantes de la tarea, el tiempo para completar la tarea, la ruta de ejecución de cada instancia del proceso, etc. Este servicio obtiene principalmente estos datos a través de la función de consulta.

  • Servicio de Administracion

La clase de gestión del motor de Activiti proporciona funciones de gestión y mantenimiento para el motor de procesos de Activiti. Estas funciones no se utilizan en aplicaciones basadas en flujos de trabajo y se utilizan principalmente para el mantenimiento diario del sistema Activiti.

1.4 Herramienta de diseño de procesos

La versión de IDEA es inferior o igual a 2019, y se puede usar el complemento Activiti actiBPM. IDEA más grande que esta versión puede usar el complemento del visualizador Activiti BPMN para dibujar el diseño del proceso.

Hoy nuestra protagonista es: Activiti Modeler

Activiti Modeler es un complemento de front-end para el diseño de procesos en línea proporcionado oficialmente por Activiti. Los desarrolladores pueden diseñar fácilmente procesos en línea, guardar modelos de procesos, implementar definiciones de procesos, etc. Nuestros proyectos posteriores también integran Activiti Modeler para dibujar definiciones de procesos.

1.4.1 Descargar activiti-explorer

Descarga del sitio web oficial: Empezar | Activiti

1.4.2 Descomprimir y obtener el paquete de implementación

Descomprima activiti-5.22.0.zip y obtenga activiti-explorer.war en el directorio activiti-5.22.0\wars

1.4.3, departamento activiti-explorer.war

Coloque activiti-explorer.war en el directorio de implementación de tomcat e inicie tomcat

1.4.4 Visita activiti-explorer

http://localhost:8080/activiti-explorador

Cuenta de inicio de sesión predeterminada: kermit kermit

Hay muchas funciones arriba, solo debemos prestar atención al diseño del proceso, como se muestra en la figura a continuación:

Haga clic en la imagen de arriba: Proceso --> Nuevo modelo --> Ingrese el nombre del modelo (salir) --> Crear

2. Operación del proceso de actividad

2.1 Definición del proceso

Definimos un proceso de salida

2.1.1 Crear un nuevo modelo

2.1.2 Nodo de inicio

2.1.3 Nodos de tareas

2.1.4 Nodo final

2.1.5 Establecer propiedades de nodo

Especifique el nombre de la etiqueta: Aprobación de Zhang San, líder de la tarea del nodo: zhangsan

Especifique el nombre de la etiqueta: Aprobación de Li Si, líder de la tarea del nodo: lisi

2.1.5 Establecer clave de definición de proceso

2.1.6, guarde el modelo de definición de proceso

2.1.7 Descargar archivo de definición de proceso

El archivo de descarga es: qingjia.bpmn20.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:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.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.activiti.org/processdef">
  <process id="qingjia" isExecutable="true">
    <startEvent id="sid-14A3E2A6-84E4-49E0-BF92-3DABD741430B"></startEvent>
    <userTask id="sid-38632C81-C407-4F0D-944D-FC30F90637A3" name="张三审批" activiti:assignee="zhangsan"></userTask>
    <sequenceFlow id="sid-081A176E-6756-4C4C-B36C-2649B12CFC5D" sourceRef="sid-14A3E2A6-84E4-49E0-BF92-3DABD741430B" targetRef="sid-38632C81-C407-4F0D-944D-FC30F90637A3"></sequenceFlow>
    <userTask id="sid-655780D5-8492-494F-9E30-2CFD6691E98D" name="李四审批" activiti:assignee="lisi"></userTask>
    <sequenceFlow id="sid-7DCE821D-4AE0-4F27-9811-80B575E7A758" sourceRef="sid-38632C81-C407-4F0D-944D-FC30F90637A3" targetRef="sid-655780D5-8492-494F-9E30-2CFD6691E98D"></sequenceFlow>
    <endEvent id="sid-7EE28419-BC61-49AC-8990-C63C4D2F7C0D"></endEvent>
    <sequenceFlow id="sid-2E583A5C-265A-4C05-B5E1-7F5DB98291F1" sourceRef="sid-655780D5-8492-494F-9E30-2CFD6691E98D" targetRef="sid-7EE28419-BC61-49AC-8990-C63C4D2F7C0D"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_qingjia">
    <bpmndi:BPMNPlane bpmnElement="qingjia" id="BPMNPlane_qingjia">
      <bpmndi:BPMNShape bpmnElement="sid-14A3E2A6-84E4-49E0-BF92-3DABD741430B" id="BPMNShape_sid-14A3E2A6-84E4-49E0-BF92-3DABD741430B">
        <omgdc:Bounds height="30.0" width="30.0" x="93.5" y="75.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-38632C81-C407-4F0D-944D-FC30F90637A3" id="BPMNShape_sid-38632C81-C407-4F0D-944D-FC30F90637A3">
        <omgdc:Bounds height="80.0" width="100.0" x="168.5" y="50.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-655780D5-8492-494F-9E30-2CFD6691E98D" id="BPMNShape_sid-655780D5-8492-494F-9E30-2CFD6691E98D">
        <omgdc:Bounds height="80.0" width="100.0" x="313.5" y="50.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="sid-7EE28419-BC61-49AC-8990-C63C4D2F7C0D" id="BPMNShape_sid-7EE28419-BC61-49AC-8990-C63C4D2F7C0D">
        <omgdc:Bounds height="28.0" width="28.0" x="458.5" y="76.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="sid-7DCE821D-4AE0-4F27-9811-80B575E7A758" id="BPMNEdge_sid-7DCE821D-4AE0-4F27-9811-80B575E7A758">
        <omgdi:waypoint x="268.5" y="90.0"></omgdi:waypoint>
        <omgdi:waypoint x="313.5" y="90.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-081A176E-6756-4C4C-B36C-2649B12CFC5D" id="BPMNEdge_sid-081A176E-6756-4C4C-B36C-2649B12CFC5D">
        <omgdi:waypoint x="123.5" y="90.0"></omgdi:waypoint>
        <omgdi:waypoint x="168.5" y="90.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="sid-2E583A5C-265A-4C05-B5E1-7F5DB98291F1" id="BPMNEdge_sid-2E583A5C-265A-4C05-B5E1-7F5DB98291F1">
        <omgdi:waypoint x="413.5" y="90.0"></omgdi:waypoint>
        <omgdi:waypoint x="458.5" y="90.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

2.1.8 Descargar imagen de definición de proceso

Haga clic derecho en la imagen de arriba, guarde la imagen como: qingjia.png

2.1.9 Poner archivos de recursos en el proyecto

Cree una nueva carpeta de recursos de proceso en los recursos del módulo service-oa

Coloque qingjia.bpmn20.xml y qingjia.png en el directorio de procesos

2.2 Despliegue de definición de procesos

La implementación del proceso definido anteriormente en el diseñador en la base de datos de actividades es la implementación de la definición del proceso. Agregue e implemente los archivos bpmn y png de la definición del proceso en activiti uno por uno llamando a la API de activiti, o empaquete los dos archivos en un paquete zip para su implementación.

2.2.1 Método de implementación de archivo único

package com.atguigu;

import org.activiti.engine.RepositoryService;
import org.activiti.engine.repository.Deployment;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;


@RunWith(SpringRunner.class)
@SpringBootTest
public class ProcessTest {

    @Autowired
    private RepositoryService repositoryService;

    @Test
    public void deployProcess() {
        // 流程部署
        Deployment deploy = repositoryService.createDeployment()
                .addClasspathResource("process/qingjia.bpmn20.xml")
                .addClasspathResource("process/qingjia.png")
                .name("请假申请流程")
                .deploy();
        System.out.println(deploy.getId());
        System.out.println(deploy.getName());
    }
}

2.2.2 Método de implementación del paquete comprimido

@Test
public void deployProcessByZip() {
    // 定义zip输入流
    InputStream inputStream = this
            .getClass()
            .getClassLoader()
            .getResourceAsStream(
                    "process/qingjia.zip");
    ZipInputStream zipInputStream = new ZipInputStream(inputStream);

    // 流程部署
    Deployment deployment = repositoryService.createDeployment()
            .addZipInputStream(zipInputStream)
            .name("请假申请流程")
            .deploy();
    System.out.println("流程部署id:" + deployment.getId());
    System.out.println("流程部署名称:" + deployment.getName());
}

2.2.3 Tabla de la base de datos de operaciones

Las tres tablas para las actividades operativas después de implementar la definición del proceso son las siguientes:

El proceso act_re_deployment define la tabla de implementación, agregando un registro para cada implementación

tabla de definición de proceso act_re_procdef, la implementación de cada nueva definición de proceso agregará un registro a esta tabla

tabla de recursos del proceso act_ge_bytearray

2.3 Iniciar la instancia del proceso

Definición de proceso: coloque el archivo bpmn en las tres tablas de actividades, como una clase en Java

Instancia de proceso: es como un objeto de instancia en Java (una definición de proceso puede corresponder a múltiples instancias de proceso), Zhang San puede iniciar una instancia de proceso de licencia, Li Si también puede iniciar una instancia de proceso de licencia, no se afectan entre sí

@Autowired
private RuntimeService runtimeService;

@Test
public void startUpProcess() {
    //创建流程实例,我们需要知道流程定义的key
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("qingjia");
    //输出实例的相关信息
    System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
    System.out.println("流程实例id:" + processInstance.getId());
    System.out.println("当前活动Id:" + processInstance.getActivityId());
}

Hoja de datos operativos

act_hi_actinst historial de ejecución de la instancia del proceso

Act_hi_identitylink procesa la información del historial del usuario participante

act_hi_procinst información histórica de instancia de proceso

act_hi_taskinst información del historial de tareas del proceso

act_ru_execution información de ejecución del proceso

Información del usuario participante del proceso act_ru_identitylink

información de la tarea act_ru_task

2.4 Tarea de consulta

Cada nodo se configura con Asignatario, luego de iniciado el proceso, el responsable de la tarea puede consultar las tareas que necesita procesar actualmente, y las tareas que se consultan son todas tareas pendientes del usuario.

@Autowired
private TaskService taskService;

/**
 * 查询当前个人待执行的任务
 */
@Test
public void findPendingTaskList() {
    //任务负责人
    String assignee = "zhangsan";
    List<Task> list = taskService.createTaskQuery()
            .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());
    }
}

ilustrar:

ID de instancia de proceso: solo hay un proceso, que identifica el proceso

Identificación de la tarea: cada vez que el proceso llega a un determinado nodo, se le asignará una identificación de la tarea a este nodo

La salida es la siguiente:

ID de instancia de proceso: d969f534-825e-11ed-95b4-7c57581a7819

ID de tarea: d96c3f28-825e-11ed-95b4-7c57581a7819

Líder de tarea: zhangsan

Nombre de la tarea: Aprobación por Zhang San

2.5, procesando la tarea actual

El líder de la tarea consulta las tareas pendientes, selecciona las tareas para procesar y completa las tareas.

/**
 * 完成任务
 */
@Test
public void completTask(){
    Task task = taskService.createTaskQuery()
            .taskAssignee("zhangsan")  //要查询的负责人
            .singleResult();//返回一条

    //完成任务,参数:任务id
    taskService.complete(task.getId());
}

Una vez completada la tarea, la tarea pasa automáticamente al siguiente nodo

2.6 Consulta de tareas procesadas

@Autowired
private HistoryService historyService;

/**
 * 查询已处理历史任务
 */
@Test
public void findProcessedTaskList() {
    //张三已处理过的历史任务
    List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery().taskAssignee("zhangsan").finished().list();
    for (HistoricTaskInstance historicTaskInstance : list) {
        System.out.println("流程实例id:" + historicTaskInstance.getProcessInstanceId());
        System.out.println("任务id:" + historicTaskInstance.getId());
        System.out.println("任务负责人:" + historicTaskInstance.getAssignee());
        System.out.println("任务名称:" + historicTaskInstance.getName());
    }
}

2.7 Otras interfaces (entender)

/**
 * 查询流程定义
 */
@Test
public void findProcessDefinitionList(){
    List<ProcessDefinition> definitionList = repositoryService.createProcessDefinitionQuery()
            .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());
    }
}

/**
 * 删除流程定义
 */
public void deleteDeployment() {
    //部署id
    String deploymentId = "82e3bc6b-81da-11ed-8e03-7c57581a7819";
    //删除流程定义,如果该流程定义已有流程实例启动则删除时出错
    repositoryService.deleteDeployment(deploymentId);
    //设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置为false非级别删除方式
    //repositoryService.deleteDeployment(deploymentId, true);
}

3. Ejemplo de proceso

3.1, qué es una instancia de proceso

Definición de proceso ProcessDefinition e instancia de proceso ProcessInstance son conceptos importantes de Activiti, similares a la relación entre las clases de Java y las instancias de Java

Iniciar una instancia de proceso significa iniciar una operación de proceso empresarial. Por ejemplo, se completa la implementación del proceso de licencia del empleado. Si Zhang San desea solicitar una licencia, puede iniciar una instancia de proceso. Si Li Si desea solicitar una licencia, debe también puede iniciar una instancia de proceso. La ejecución de los dos procesos no se afecta entre sí. , al igual que definir una clase java e instanciar dos objetos, el proceso de implementación es como una clase java, iniciar una instancia de proceso es como un objeto java nuevo

3.2 Asociar el negocio real con la tabla de actividades (BusinessKey)

Por ejemplo, si llenamos un formulario de baja, debe haber una identificación única del formulario de baja, generalmente usamos esta identificación para asociar actividades, esta identificación se llama businesskey en activiti

BusinessKey: identificador comercial, generalmente la clave principal del negocio, el identificador comercial y el identificador de proceso se corresponden uno a uno, el identificador comercial proviene del sistema comercial y el almacenamiento del identificador comercial es para asociar y consultar los datos del sistema empresarial según el identificador empresarial

Por ejemplo: cuando el proceso de licencia inicia una instancia de proceso, la identificación de la solicitud de licencia se puede almacenar en activiti como un identificador comercial. En el futuro, la identificación de la solicitud de licencia se puede obtener consultando la información de la instancia de proceso de activiti, para consultar la base de datos del sistema empresarial para obtener la información de solicitud de licencia

/**
 * 启动流程实例,添加businessKey
 */
@Test
public void startUpProcessAddBusinessKey(){
    String businessKey = "1";
    // 启动流程实例,指定业务标识businessKey,也就是请假申请单id
    ProcessInstance processInstance = runtimeService.
            startProcessInstanceByKey("qingjia",businessKey);
    // 输出
    System.out.println("业务id:"+processInstance.getBusinessKey());
}

3.3 Suspender y activar la instancia de proceso

En algunos casos, puede ser necesario suspender el proceso que se está ejecutando actualmente en lugar de eliminarlo directamente debido a cambios en el proceso.Después de suspender el proceso, no se ejecutará;

3.3.1 Se suspenden todas las instancias de proceso

El proceso de operación se define como un estado suspendido y todas las instancias de proceso debajo de la definición del proceso están suspendidas:

La definición de proceso está en un estado suspendido. Esta definición de proceso no permitirá que se inicien nuevas instancias de proceso. Al mismo tiempo, todas las instancias de proceso bajo esta definición de proceso se suspenderán y suspenderán.

@Test
public void suspendProcessInstance() {
    ProcessDefinition qingjia = repositoryService.createProcessDefinitionQuery().processDefinitionKey("qingjia").singleResult();
    // 获取到当前流程定义是否为暂停状态 suspended方法为true是暂停的,suspended方法为false是运行的
    boolean suspended = qingjia.isSuspended();
    if (suspended) {
        // 暂定,那就可以激活
        // 参数1:流程定义的id  参数2:是否激活    参数3:时间点
        repositoryService.activateProcessDefinitionById(qingjia.getId(), true, null);
        System.out.println("流程定义:" + qingjia.getId() + "激活");
    } else {
        repositoryService.suspendProcessDefinitionById(qingjia.getId(), true, null);
        System.out.println("流程定义:" + qingjia.getId() + "挂起");
    }
}

3.3.2 Una sola instancia de proceso se cuelga

Opere el objeto de instancia de proceso, ejecute la operación de suspensión para un solo proceso, si se suspende una instancia de proceso, el proceso no continuará ejecutándose y se informará una excepción cuando se complete la tarea actual de la instancia de proceso;

@Test
public void SingleSuspendProcessInstance() {
    String processInstanceId = "8bdff984-ab53-11ed-9b17-f8e43b734677";
    ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
    //获取到当前流程定义是否为暂停状态   suspended方法为true代表为暂停   false就是运行的
    boolean suspended = processInstance.isSuspended();
    if (suspended) {
        runtimeService.activateProcessInstanceById(processInstanceId);
        System.out.println("流程实例:" + processInstanceId + "激活");
    } else {
        runtimeService.suspendProcessInstanceById(processInstanceId);
        System.out.println("流程实例:" + processInstanceId + "挂起");
    }
}

4. Asignación de tareas

Hay tres formas de asignar tareas

  1. asignación fija
  2. asignación de expresión UEL
  3. asignación de oyentes

4.1 Distribución fija

Especifique un líder de tarea fijo en el modelo de proceso comercial anterior, como: Asignatario: zhangsan/lisi

4.2 Asignación de expresiones

activiti usa expresiones UEL. UEL es parte de la especificación java EE6. UEL es el lenguaje de expresión unificado. activiti admite dos expresiones UEL: valor UEL y método UEL.

4.2.1、Valor UEL

Nuevo: un proceso de horas extras

Como se muestra en la imagen:

asignado1 Esta variable es una variable de proceso de activiti

Iniciamos la instancia del proceso, el método para iniciar la instancia es básicamente el mismo que el método anterior, la única diferencia es que se agrega un parámetro al inicio

@Test
public void deployProcess01() {
    // 流程部署
    Deployment deploy = repositoryService.createDeployment()
        .addClasspathResource("process/jiaban01.bpmn20.xml")
        .name("加班申请流程")
        .deploy();
    System.out.println(deploy.getId());
    System.out.println(deploy.getName());
}

/**
 * 启动流程实例
 */
@Test
public void startUpProcess01() {
    Map<String, Object> variables = new HashMap<>();
    variables.put("assignee1","zhangsan");
    variables.put("assignee2","lisi");
    //创建流程实例,我们需要知道流程定义的key
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("qingjia01", variables);
    //输出实例的相关信息
    System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
    System.out.println("流程实例id:" + processInstance.getId());
}

4.2.2, método UEL

Como se muestra en la imagen:

userBean es un bean en el contenedor de primavera, lo que significa llamar al método getUsername(int id) del bean.

Aprobación del administrador: ${userBean.getUsername(1)}

Aprobación del personal: ${userBean.getUsername(2)}

package com.atguigu.process.bean;

import org.springframework.stereotype.Component;

@Component
public class UserBean {

    public String getUsername(int id) {
        if(id == 1) {
            return "zhangsan";
        }
        if(id == 2) {
            return "lisi";
        }
        return "admin";
    }
}

Implementar y comenzar

@Test
public void deployProcess02() {
    // 流程部署
    Deployment deploy = repositoryService.createDeployment()
        .addClasspathResource("process/jiaban02.bpmn20.xml")
        .name("加班申请流程")
        .deploy();
    System.out.println(deploy.getId());
    System.out.println(deploy.getName());
}

/**
 * 启动流程实例
 */
@Test
public void startUpProcess02() {
    //创建流程实例,我们需要知道流程定义的key
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("qingjia02");
    //输出实例的相关信息
    System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
    System.out.println("流程实例id:" + processInstance.getId());
}

Cuando se inicia la instancia de proceso, se llamará al método bean, el parámetro es: 1, después de que el administrador lo apruebe, se llamará al método bean, el parámetro es: 2

4.3 Asignación de oyentes

Utilice el método de escucha para especificar la persona a cargo, por lo que no necesita especificar el asignado al diseñar el proceso.

El detector de tareas debe ejecutar una lógica o expresión Java personalizada cuando se produce el evento relacionado con la tarea correspondiente.

Las opciones de eventos incluyen:

Create:任务创建后触发
Assignment:任务分配后触发
Delete:任务完成后触发
All:所有事件发生都触发

Defina la clase de escucha de tareas, y la clase debe implementar la interfaz org.activiti.engine.delegate.TaskListener

package com.atguigu.process.bean;

import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;

public class MyTaskListener implements TaskListener {

    @Override
    public void notify(DelegateTask delegateTask) {
        if(delegateTask.getName().equals("经理审批")){
            //这里指定任务负责人
            delegateTask.setAssignee("zhangsan");
        } else if(delegateTask.getName().equals("人事审批")){
            //这里指定任务负责人
            delegateTask.setAssignee("lisi");
        }
    }
}

Configurar el oyente

Tanto la aprobación del gerente como la aprobación del personal se pueden configurar en el mismo monitor

Implementar y probar

@Test
public void deployProcess03() {
    // 流程部署
    Deployment deploy = repositoryService.createDeployment()
            .addClasspathResource("process/jiaban03.bpmn20.xml")
            .name("加班申请流程")
            .deploy();
    System.out.println(deploy.getId());
    System.out.println(deploy.getName());
}

/**
 * 启动流程实例
 */
@Test
public void startUpProcess03() {
    //创建流程实例,我们需要知道流程定义的key
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("jiaban03");
    //输出实例的相关信息
    System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
    System.out.println("流程实例id:" + processInstance.getId());
}

Cuando se inicia la instancia del proceso, se llamará al método de escucha MyTaskListener

5. Variables de proceso

5.1, que es una variable de proceso

Las variables del proceso juegan un papel muy importante en las actividades. La operación del proceso a veces depende de las variables del proceso, los sistemas comerciales y las actividades.

Las variables de proceso son indispensables en combinación, y las variables de proceso son variables que se establecen de acuerdo con las necesidades de gestión al administrar el flujo de trabajo.

Por ejemplo: cuando fluye el proceso de solicitud de licencia, si el número de días de licencia es mayor a 2 días, será revisado por el gerente general, de lo contrario, será revisado directamente por el gerente del departamento.

El número puede establecerse como una variable de proceso y usarse durante el flujo del proceso.

5.2, el alcance de las variables de proceso

El rol de una variable de proceso puede ser una instancia de proceso, pero también puede ser una tarea (task) o una instancia de ejecución

5.2.1, variables globales

El ámbito predeterminado de las variables de proceso es la instancia de proceso. Cuando el alcance de una variable de proceso es la instancia de proceso, se puede llamar una variable global

No se permite repetir el nombre de la variable en la variable global. Si establece una variable con el mismo nombre, el valor establecido más tarde sobrescribirá el valor de la variable establecido antes.

5.2.2, variable local

Las tareas y las instancias de ejecución son solo para una tarea y un rango de instancia de ejecución, y el alcance no es tan grande como la instancia del proceso, que se denomina variables locales.

Debido a que el alcance de las variables locales no se afecta entre sí en diferentes tareas o diferentes instancias de ejecución, los nombres de las variables pueden ser los mismos sin ninguna influencia. El nombre de la variable local también puede ser el mismo que el nombre de la variable global, no tiene ningún efecto.

5.3 Cómo utilizar variables de proceso

Uso de variables de proceso a través de expresiones UEL

1. También hemos usado expresiones UEL para configurar el controlador de tareas antes, como ${asignado1}, activiti obtiene el valor de la expresión UEL, es decir, el valor de la variable de proceso asignado1, y asigna el valor como la persona en cargo de la tarea

2. También podemos usar expresiones UEL en la conexión entre tareas para determinar la dirección del proceso, como ${day > 2 } y ${day <= 2}, day es un nombre de variable de proceso y la ejecución de UEL expresiones el resultado es booleano

5.4, ​​establecer la variable global

5.4.1 Establecer variables al iniciar el proceso

Establezca la variable de proceso al iniciar el proceso, y el alcance de la variable es la instancia de proceso completa.

Configure la variable de proceso a través de Map<key,value>, se pueden configurar múltiples variables en el mapa, esta clave es el nombre de la variable de proceso

Este es el código de ejemplo anterior.

@Test
public void startUpProcess() {
    Map<String, Object> variables = new HashMap<>();
    variables.put("assignee1", "zhangsan");
    variables.put("assignee2", "lisi");
    //创建流程实例,我们需要知道流程定义的key
    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("qingjia", variables);
    //输出实例的相关信息
    System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
    System.out.println("流程实例id:" + processInstance.getId());
}

5.4.2 Establecer variables de proceso al manejar tareas

Su alcance es toda la instancia de proceso , si la clave de la variable de proceso configurada ya tiene el mismo nombre en la instancia de proceso, la variable configurada más tarde reemplazará a la variable configurada anteriormente.

Código de ejemplo de simulación:

@Test
public void completTask() {
    Task task = taskService.createTaskQuery()
            .taskAssignee("zhangsan")  //要查询的负责人
            .singleResult();//返回一条

    Map<String, Object> variables = new HashMap<>();
    variables.put("assignee2", "zhao");
    //完成任务,参数:任务id
    taskService.complete(task.getId(), variables);
}

5.4.3, a través de la configuración de la instancia de proceso actual

La variable global se establece a través del ID de la instancia del proceso y su alcance es la instancia del proceso completa , que no debe completarse.

Código de ejemplo de simulación:

@Test
public void processInstanceIdSetVariables() {
    Map<String, Object> variables = new HashMap<>();
    variables.put("assignee2", "wang");
    runtimeService.setVariables("1c347a90-82c6-11ed-96ca-7c57581a7819", variables);
}

5.5 Establecer variables locales

El alcance de las variables de proceso locales solo está disponible en el nodo de tarea actual

Cuando se procesa una tarea, se establece una variable de proceso local. La instancia de proceso que se está ejecutando actualmente solo se puede usar antes del final de la tarea. La variable no se puede usar en la instancia de proceso actual después de que finalice la tarea.

Código de ejemplo de simulación:

@Test
public void completLocalTask() {
    Task task = taskService.createTaskQuery()
            .taskAssignee("zhangsan")  //要查询的负责人
            .singleResult();//返回一条

    // 设置local变量,作用域为该任务
    taskService.setVariableLocal(task.getId(),"assignee2","li");
    // 查看local变量
    System.out.println(taskService.getVariableLocal(task.getId(), "assignee2"));
    //完成任务,参数:任务id
    taskService.complete(task.getId());
}

6. Grupo de trabajo

6.1, Candidatos-usuarios candidatos

1. Demanda

En la definición del proceso, el líder de la tarea se fija en el asignado del nodo de la tarea, y el participante se fija en el archivo .bpmn cuando se define el proceso. Si desea cambiar temporalmente el líder de la tarea, debe modificar el proceso definición. La escalabilidad del sistema es muy pobre. En respuesta a esta situación, podemos establecer múltiples candidatos para la tarea y seleccionar participantes de los candidatos para completar la tarea

2. Establecer candidatos para tareas

6.2 Proceso de manejo de tareas grupales

Paso 1: Tareas del grupo de consultas

Especifique un candidato y consulte las tareas pendientes actuales del candidato

Los candidatos no pueden manejar las tareas.

Paso 2: Recoger (reclamar) tareas

Todos los candidatos para este grupo de misiones pueden recoger

Convierta la tarea grupal del candidato en una tarea personal, y el candidato original se convierte en la persona a cargo de la tarea

Si no desea manejar la tarea después de recogerla

necesito recoger

Paso 3: consulta de tareas personales

El método de consulta es el mismo que el de la parte de la tarea personal, y la tarea personal de la que el usuario es responsable se consulta de acuerdo con el asignado

Paso cuatro: manejar tareas personales

6.3 Código clave

6.3.1, despliegue e inicio

@Test
public void deployProcess04() {
    // 流程部署
    Deployment deploy = repositoryService.createDeployment()
            .addClasspathResource("process/jiaban04.bpmn20.xml")
            .name("请假申请流程")
            .deploy();
    System.out.println(deploy.getId());
    System.out.println(deploy.getName());

    ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("jiaban04");
    System.out.println(processInstance.getId());
}

6.3.2 Tareas del grupo de consulta

@Test
public void findGroupTaskList() {
    //查询组任务
    List<Task> list = taskService.createTaskQuery()
            .taskCandidateUser("zhangsan01")//根据候选人查询
            .list();
    for (Task task : list) {
        System.out.println("----------------------------");
        System.out.println("流程实例id:" + task.getProcessInstanceId());
        System.out.println("任务id:" + task.getId());
        System.out.println("任务负责人:" + task.getAssignee());
        System.out.println("任务名称:" + task.getName());
    }
}

6.3.2 Recoger tareas grupales

@Test
public void claimTask(){
    //拾取任务,即使该用户不是候选人也能拾取(建议拾取时校验是否有资格)
    //校验该用户有没有拾取任务的资格
    Task task = taskService.createTaskQuery()
            .taskCandidateUser("zhangsan01")//根据候选人查询
            .singleResult();
    if(task!=null){
        //拾取任务
        taskService.claim(taskId, "zhangsan01");
        System.out.println("任务拾取成功");
    }
}

Zhang San 01 ha asumido la tarea, pero Zhang San 02 no puede hacerlo

6.3.3 Consulta de tareas pendientes personales

El método de consulta es el mismo que la consulta de tareas personales.

@Test
public void findGroupPendingTaskList() {
    //任务负责人
    String assignee = "zhangsan01";
    List<Task> list = taskService.createTaskQuery()
            .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());
    }
}

6.3.4 Manejar tareas personales

con tareas personales

@Test
public void completGroupTask() {
    Task task = taskService.createTaskQuery()
            .taskAssignee("zhangsan01")  //要查询的负责人
            .singleResult();//返回一条
    taskService.complete(task.getId());
}

6.3.5 Tareas del grupo de retorno

Si un individuo no quiere manejar la tarea grupal, puede devolver la tarea grupal, después de lo cual el usuario ya no es la persona a cargo de la tarea.

@Test
public void assigneeToGroupTask() {
    String taskId = "d96c3f28-825e-11ed-95b4-7c57581a7819";
    // 任务负责人
    String userId = "zhangsan01";
    // 校验userId是否是taskId的负责人,如果是负责人才可以归还组任务
    Task task = taskService
            .createTaskQuery()
            .taskId(taskId)
            .taskAssignee(userId)
            .singleResult();
    if (task != null) {
        // 如果设置为null,归还组任务,该 任务没有负责人
        taskService.setAssignee(taskId, null);
    }
}

6.3.6 Entrega de tareas

Entrega de la tarea, el líder de la tarea entrega la tarea a otros candidatos para que se encarguen de la tarea

@Test
public void assigneeToCandidateUser() {
    // 当前待办任务
    String taskId = "d96c3f28-825e-11ed-95b4-7c57581a7819";
    // 校验zhangsan01是否是taskId的负责人,如果是负责人才可以归还组任务
    Task task = taskService
            .createTaskQuery()
            .taskId(taskId)
            .taskAssignee("zhangsan01")
            .singleResult();
    if (task != null) {
        // 将此任务交给其它候选人zhangsan02办理该 任务
        taskService.setAssignee(taskId, "zhangsan02");
    }
}

7. Puerta de enlace

Las puertas de enlace se utilizan para controlar el flujo de procesos y, por lo general, se utilizan junto con variables de proceso.

7.1 Puerta de enlace exclusiva

  • Pasarela exclusiva: solo se elegirá una ruta

Cuando hay tal escenario en su proceso: deje la solicitud, dentro de dos días, el proceso de aprobación del gerente del departamento ha terminado, y el gerente general debe aprobarlo directamente después de dos días, en este momento, se necesita una puerta de enlace exclusiva

7.2 Puerta de enlace paralela

  • Pasarelas paralelas (paralelas): todas las rutas se seleccionarán al mismo tiempo

Cuando ocurre tal escenario: la solicitud de licencia debe ser aprobada tanto por el gerente del departamento como por el gerente general. Si no hay un antes y un después de los dos, ambas personas deben aprobarla antes de pasar al siguiente nodo para la aprobación del personal. En este momento, se requiere una puerta de enlace paralela

La principal diferencia con las puertas de enlace exclusivas es que las puertas de enlace paralelas no resuelven las condiciones. Incluso si se define una condición en el flujo de secuencia, se ignorará.

7.3, incluida la puerta de enlace

Puerta de enlace inclusiva: se pueden ejecutar varias rutas al mismo tiempo y también se pueden establecer condiciones en la puerta de enlace, que se puede considerar como una combinación de puerta de enlace exclusiva y puerta de enlace paralela.

Cuando ocurre tal escenario: la solicitud de licencia debe ser aprobada por el gerente general del departamento por más de o igual a 2 días, y el gerente del departamento por menos de 2 días, y la solicitud de licencia debe ser aprobada por el gerente de recursos humanos. En este momento, la puerta de enlace debe incluirse

Supongo que te gusta

Origin blog.csdn.net/qq_61544409/article/details/129719335
Recomendado
Clasificación