アクティビティワークフローエンジン

目次

1. ワークフローを理解する

1. ワークフローとは

2. ワークフローエンジン

3. 一般的なワークフロー エンジン

4. Activiti7の概要

4.1 アクティビティの概要

4.2. モデリング言語 BPMN

4.3、アクティビティの利用プロセス

2、Activiti7

1. Activitiの利用

1.1、データベースのサポート

1.2、アクティビティ環境

1.3、Activiti共通サービスサービスインターフェース

1.4. プロセス設計ツール

2. アクティビティプロセスの操作

2.1. プロセス定義

2.2. プロセス定義のデプロイメント

2.3. プロセスインスタンスの起動

2.4. クエリタスク

2.5、現在のタスクの処理

2.6. 処理されたタスクのクエリ

2.7. その他のインターフェース (理解)

3. 処理例

3.1、プロセスインスタンスとは

3.2. 実際の業務とアクティビティテーブル(BusinessKey)を関連付ける

3.3. プロセスインスタンスの一時停止とアクティブ化

4. タスクの割り当て

4.1. 固定分布

4.2. 式の代入

4.3. リスナーの割り当て

5. プロセス変数

5.1、プロセス変数とは何ですか

5.2、プロセス変数の範囲

5.3. プロセス変数の使用方法

5.4、グローバル変数を設定する

5.5. ローカル変数の設定

6. タスクグループ

6.1、候補者 - ユーザー候補者

6.2. グループタスクの処理プロセス

6.3. キーコード

7. ゲートウェイ

7.1. 専用ゲートウェイ

7.2. パラレルゲートウェイ

7.3(ゲートウェイを含む)


1. ワークフローを理解する

1. ワークフローとは

ワークフロー(Workflow)とは、コンピュータを介して業務プロセスの管理を自動化することです。これは主に、「特定の予想されるビジネス目標を達成する、またはこの目標の実現を促進するために、事前に定義されたルールに従って複数の参加者間で文書、情報、またはタスクを自動的に転送するプロセス」を解決します。平たく言えば、ビジネスにおける完全な承認プロセスです。たとえば、従業員の休暇、出張、外出先での購入、契約のレビューなど、これらのプロセスはすべてワークフローです。

2. ワークフローエンジン

ワークフロー処理において、従来の方法だと、各担当者に各種書類を持って行ってサインをしてもらったり、複数の部門で継続的に承認を得る必要があり、時間と手間がかかります。そして、これらの承認プロセスの処理をソフトウェア システムを使用して支援できるワークフロー システムが登場し、ワークフロー システムの使用後は作業効率が大幅に向上します。

ワークフローを学ぶ過程で、休暇申請書の記入→部門長の承認→部長の承認→人事申請というモデルを見たことがあるはずです。

(1) 上記のプロセスを実現するには、フィールドの識別を通じてこの承認効果を実現し、休暇フォームに 1、部長に 2、部長に 3 を記入するように、業務テーブルにフィールドを追加します。 , 人事 記録は4とマークされており、問題なく承認効果が得られているようです。しかし、プロセスが変更されたら、その時点でコードを変更する必要がありますが、これは明らかにお勧めできません。では、ワークフロー管理を実現する専門的な方法はあるのでしょうか? また、業務プロセスが変わってもプログラムを変更する必要がなくなり、その効果が得られれば、業務システムの適応性は大幅に向上します。これに関連して、ワークフロー エンジンが登場しました

ワークフロー エンジンを使用すると、コードを変更せずにビジネス プロセスの変更を実現でき、プロセスを自動的に進めることができるのはなぜでしょうか?

(1) まず、コードを変更せずにプロセスが変更される理由について話しましょう。ワークフロー エンジンは、プロセス管理がステータス フィールドとは何の関係も持た​​ないことを要求する仕様を実装しており、常に次のステップでビジネスを読み取る必要があります。フローチャートのノード。業務を更新する際には、業務フローチャートを更新するだけで済みます。これにより、コードを変更せずにビジネス プロセスを変更できます。

(2) プロセスの自動進行について話しましょう。この原理はさらに単純です。上記の休暇モデルを例にとると、ワークフロー エンジンはテーブルを使用して現在のノードを記録します。休暇フォームに記入した後は、部門マネージャーがそれを承認する必要があるため、休暇フォームに記入すると、このレコードはこのフォームから削除され、次のノードの部門マネージャーの情報が挿入されます。このテーブルを部門長の情報で問い合わせると、該当する部門長の承認情報などが分かり、プロセスの自動投入が実現します。

3. 一般的なワークフロー エンジン

主流のフレームワークは、Activiti、jBPM、Camunda、Flowable、および国内の Pangu BPM、Yunchengです。

4. Activiti7の概要

4.1 アクティビティの概要

activitiは、業務システム内の複雑な業務プロセスを抽出し、専用のモデリング言語BPMNを用いて定義し、あらかじめ定義されたプロセスに従って業務プロセスを実行できるワークフローエンジンです。システムのプロセスをActivitiで管理することで、プロセス変更に伴うシステム改修や業務システム変更の負荷を軽減し、システムの堅牢性向上とシステム開発・保守コストの削減を実現します。

公式ウェブサイト:https: //www.activiti.org

4.2. モデリング言語 BPMN

BPM (Business Process Management) はビジネスプロセス管理であり、組織のビジネス効率を継続的に向上させるためのエンドツーエンドのビジネスプロセスの標準化された構築です。

BPMソフトウェアとは、企業内のビジネス環境の変化に応じて、人と人、人とシステム、システム間のビジネス手法やソリューションの整理・調整を促進するITツールです。BPM ソフトウェアを使用して内部および外部のビジネス プロセスのライフサイクル全体をモデル化、自動化、管理、監視、最適化すると、企業コストを削減し、利益を増やすことができます。

BPMN (Business Process Model And Notation) は、ビジネス プロセス モデルと表記法です。標準的なビジネス プロセス モデリング表記法のセットです。BPMN が提供する表記法を使用してビジネス プロセスを作成できます。Activit はプロセス モデリングとプロセス実行管理に BPMN を使用します

BPMN2.0 は、Business Process Modeling Notation 2.0 の頭字語で、非営利団体である Business Process Management Initiative によって作成され、継続的に開発されています。BPMN2.0は、ビジネスプロセス設計のフローチャートを明確にするためにいくつかのシンボルを使用するシンボル仕様のセットであり、ビジネスモデリングにおけるコミュニケーション効率を向上させることができます。現在、BPMN2.0 が最新バージョンであり、BPM コンテキストでのレイアウトとビジュアルコミュニケーションに使用されます。

BPMN2.0 の基本シンボルには主に次のものがあります。

  • イベント イベント

開始: プロセスの開始を示します

中央: 開始イベントと終了イベントの間で、処理の流れに影響します。

End: プロセスの終了を示します

編集

  • 活動内容

アクティビティとは、仕事またはタスクを表す一般的な用語です。アクティビティは、タスクまたは現在のプロセスのサブプロセスにすることができます。次に、アクティビティにさまざまなタイプを指定することもできます。一般的なアクティビティは次のとおりです。

編集

  • ゲートウェイゲートウェイ

プロセスの分岐と結合を表すために理解する必要がある、一般的に使用されるゲートウェイがいくつかあります。

    • 排他的ゲートウェイ: パスは 1 つだけ選択されます

    • 並列ゲートウェイ: 各パスが選択されます

    • 包括的なゲートウェイ: 複数の行を同時に実行でき、ゲートウェイに条件を設定することもできます

    • イベント ゲートウェイ: 中間キャプチャ イベント用に特別に設定されており、複数の出力ストリームが複数の異なる中間キャプチャ イベントをポイントできるようにします。イベントゲートウェイに対してプロセスが実行されると、プロセスは待機状態になり、待機状態をアクティブ状態に変換するにはイベントがスローされるまで待機する必要があります。

  • フローからフローへ

フローは 2 つのプロセス ノード間の接続であり、一般的なフローの方向は次のとおりです。

シーケンス フロー: 実線と実線の矢印で表され、アクティビティが実行される順序を指定するために使用されます。

情報フロー: 矢印付きの点線で表され、2 つの独立したビジネス参加者 (ビジネス エンティティ/ビジネス ロール) 間で送受信されるメッセージ フローを説明するために使用されます。

関連: 線矢印が付いた点線で表され、関連するデータ、テキスト、およびその他のアーティファクトをフロー オブジェクトに関連付けるために使用されます。活動を紹介するためのインプットとアウトプット

処理例:

4.3、アクティビティの利用プロセス

ステップ 1:依存関係を導入し、データベースを初期化する

activiti はフレームワークであるため、対応する jar パッケージの座標を導入する必要があります。特定のコードを参照してください。

ステップ 2:ツールを使用してフローチャートを作成する

アクティビティ プロセス モデリング ツール (アクティビティ デザイナー) を使用してビジネス プロセス (.bpmn ファイル) を定義します。

.bpmn ファイルはビジネス プロセス定義ファイルであり、xml を通じてビジネス プロセスを定義します。

3 番目のステップ: プロセス定義の展開。

ビジネス プロセス定義 (.bpmn ファイル) を activiti にデプロイし、activiti が提供する API を使用して .bpmn ファイルを activiti にデプロイします。

平たく言えば、使用するプロセスをアクティビティに知らせることです。

ステップ 4:プロセス インスタンス (ProcessInstance) を開始する

プロセス インスタンスの開始は、ビジネス プロセス操作の開始を意味します。たとえば、従業員の休暇プロセスの展開が完了しました。Zhang San が休暇を申請したい場合は、プロセス インスタンスを開始できます。Li Si が休暇を申請したい場合は、プロセス インスタンスを開始できます。プロセス インスタンスを開始することもできます。2 つのプロセスの実行は相互に影響しません。Java クラスを定義して 2 つのオブジェクトをインスタンス化するのと同じように、デプロイメント プロセスは Java クラスに似ており、プロセス インスタンスの開始は新しい Java オブジェクトに似ています。

ステップ 5:ユーザーが ToDo タスク (タスク) をクエリします。

システムのビジネス プロセスは管理のために activiti に引き渡されているため、activiti を通じて、現在のプロセスがどこで実行されているか、現在のユーザーが処理する必要があるタスクを照会することができ、Activiti はこれらの管理に役立ちます。実際、Activiti を学ぶときは、その API の使用方法を学ぶだけです。Activiti の多くの機能がパッケージ化されており、それらを呼び出すことができるからです。

ステップ 6:ユーザーがタスクを処理する

ユーザーが保留中のタスクをクエリした後、特定のタスクを処理できます。タスクが完了すると、他のユーザーがそのタスクを処理する必要があります。たとえば、休暇フォームが作成された後、部門マネージャーによってレビューされます。このプロセスは次のとおりです。これも activiti によって完了されるため、コードを記述する必要はありません。次のタスク ハンドラーを指定するためにハードコーディングされています。

ステップ 7:プロセスの終了

タスクの処理が完了し、次のタスクノードがなくなると、プロセスインスタンスは完了します。

2、Activiti7

1. Activitiの利用

1.1、データベースのサポート

Activiti 操作にはデータベースのサポートが必要です。サポートされるデータベースは次のとおりです: mysql、oracle、postgres、mssql、db2、h2

1.2、アクティビティ環境

現在のプロジェクト guigu-oa-parent で Activiti の導入を直接説明します。

1.2.1. 依存関係の導入

<!--引入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>

説明: Activiti7 が SpringBoot と統合された後、SpringSecurity セキュリティ フレームワークはデフォルトで統合され、Activiti フレームワークはユーザーが存在するかどうかを確認し、存在しない場合は例外が発生します。

編集

1.2.2. 設定の追加

データ ソース プロジェクトが追加されました。必要なのは次の構成だけです

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、プロジェクトを開始する

プロジェクトを開始してプロジェクト データベース テーブルを生成します

1.2.4、データベーステーブルの概要

Activiti の運用支援では、主にプロセスに参加するユーザー主体、ユーザーグループ情報、プロセス定義、プロセス実行情報、ビジネスプロセス運用時のプロセス履歴情報などを記録するために、これら 25 個のテーブルのサポートが必要です。

1. テーブルの命名規則と関数

作成されたテーブルを観察すると、Activiti のテーブルはすべて act_ で始まり、その後にテーブルの目的を示す 2 文字の識別子が続きます。これは、Activiti が提供するサービスの API にも対応しています。

  • ACT_RE: RE はリポジトリを意味し、プレフィックス テーブルにはプロセス定義とプロセスの静的リソース (ピクチャ、ルールなど) が含まれます。
  • ACT_RU: RU はランタイムを表します。これらのテーブルの実行中、テーブルにはプロセス インスタンス、タスク、変数、非同期タスクなどの進行中のデータが含まれます。Activiti はプロセス インスタンスの実行中にのみこれらのデータを保存し、プロセスの終了時にこれらのレコードを削除します。こうすることで、テーブルを常に小さく、高速に保つことができます。
  • ACT_HI: HI は履歴を意味し、これらのテーブルには履歴プロセス インスタンス、変数、タスクなどの履歴データが含まれます。
  • ACT_GE: GE は一般的な一般データを意味します

2. Activiti データテーブルの概要

テーブルの分類

テーブル名

説明

一般的なデータ

[ACT_GE_BYTEARRAY]

一般的なプロセス定義とプロセス リソース

[ACT_GE_PROPERTY]

システム関連のプロパティ

プロセス履歴

[ACT_HI_ACTINST]

過去のプロセスの例

[ACT_HI_ATTACHMENT]

履歴プロセスの添付ファイル

[ACT_HI_COMMENT]

歴史的な説明情報

[ACT_HI_DETAIL]

プロセス実行の履歴に関する詳細情報

[ACT_HI_IDENTITYLINK]

履歴プロセス実行中のユーザー関係

[ACT_HI_PROCINST]

過去のプロセスの例

[ACT_HI_TASKINST]

履歴タスクの例

[ACT_HI_VARINST]

実行中の履歴プロセスの可変情報

プロセス定義テーブル

[ACT_RE_DEPLOYMENT]

展開ユニット情報

[ACT_RE_MODEL]

機種情報

[ACT_RE_PROCDEF]

デプロイされたプロセス定義

インスタンステーブルを実行する

[ACT_RU_EVENT_SUBSCR]

ランタイムイベント

[ACT_RU_実行]

ランタイムプロセス実行インスタンス

[ACT_RU_IDENTITYLINK]

実行時のユーザー関係情報、タスク ノードと参加者に関する情報の保存

[ACT_RU_JOB]

ランタイムジョブ

[ACT_RU_TASK]

ランタイムタスク

[ACT_RU_VARIABLE]

ランタイム変数テーブル

1.3、Activiti共通サービスサービスインターフェース

各サービスの実装クラスを簡単に紹介します。

  • リポジトリサービス

Activiti のリソース管理クラス。プロセス定義のデプロイとプロセス リソースの管理を担当します。Activiti を使用する場合、最初にプロセスのデプロイを完了する必要があり、モデリング ツールで設計された業務フローチャートは RepositoryService を通じてデプロイされます。

  • ランタイムサービス

Activiti のプロセス操作管理クラスは、新しいプロセス インスタンスを開始し、プロセスの実行に関する関連情報を取得するために使用されます。プロセス定義はプロセス内の各ノードの構造と動作を決定するために使用され、プロセス インスタンスは対応するプロセス定義の実行であり、Java のクラスとオブジェクト間の関係として理解できます。

  • タスクサービス

Activiti のタスク管理クラスは、ユーザーまたはグループに割り当てられたタスクのクエリ、新しいタスクの作成、タスクの割り当て、タスクの決定と完了など、業務運営におけるさまざまなタスクを処理するために使用されます。

  • 歴史サービス

Activiti の履歴管理クラスは、履歴情報をクエリできます。プロセスを実行すると、エンジンはプロセス インスタンスの開始時刻、タスクの参加者、タスクの完了時間、各プロセス インスタンスの実行パスなどの大量のデータを保存します。このサービスは主にクエリ機能を通じてこれらのデータを取得します

  • 管理サービス

Activiti のエンジン管理クラスは、Activiti プロセス エンジンの管理およびメンテナンス機能を提供します。これらの機能は、ワークフロー駆動型アプリケーションでは使用されず、主に Activiti システムの日常メンテナンスに使用されます。

1.4. プロセス設計ツール

IDEA のバージョンは 2019 以下で、Activiti プラグイン actiBPM を使用できます。このバージョンより大きい IDEA では、Activiti BPMN ビジュアライザ プラグインを使用してプロセス設計を描画できます。

今日の主役はActiviti Modelerです。

Activiti Modeler は、Activiti が公式に提供するオンライン プロセス設計用のフロントエンド プラグインです。開発者はオンラインで簡単にプロセスを設計し、プロセス モデルを保存し、プロセス定義に展開することができます。その後のプロジェクトでは、プロセス定義を描画するために Activiti Modeler も統合されています。

1.4.1. activiti-explorer をダウンロードする

公式ウェブサイトのダウンロード:始めましょう | Activiti

1.4.2. 展開パッケージを解凍して入手します。

activiti-5.22.0.zip を解凍し、activiti-5.22.0\wars ディレクトリにある activiti-explorer.war を取得します。

1.4.3、部署activiti-explorer.war

activiti-explorer.war を Tomcat デプロイメント ディレクトリに置き、Tomcat を起動します。

1.4.4. activiti-explorer にアクセスする

http://localhost:8080/activiti-explorer

デフォルトのログインアカウント: kermit kermit

上記には多くの機能がありますが、次の図に示すように、プロセス設計に注意するだけで済みます。

上の画像をクリックしてください: プロセス --> 新しいモデル --> モデル名を入力 (そのまま) --> 作成

2. アクティビティプロセスの操作

2.1. プロセス定義

休暇プロセスを定義します

2.1.1. 新しいモデルの作成

2.1.2. 開始ノード

2.1.3. タスクノード

2.1.4. エンドノード

2.1.5. ノードのプロパティを設定する

ラベル名を指定します: Zhang San Approval、ノードタスクリーダー: zhangsan

ラベル名: Li Si Approval、ノードタスクリーダー: lisi を指定します。

2.1.5. プロセス定義キーの設定

2.1.6、プロセス定義モデルの保存

2.1.7. プロセス定義ファイルのダウンロード

ダウンロード ファイルは次のとおりです: 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. プロセス定義画面のダウンロード

上の画像を右クリックし、画像を qingjia.png という名前で保存します。

2.1.9. リソ​​ースファイルをプロジェクトに配置する

service-oa モジュールのリソースの下に新しいプロセス リソース フォルダーを作成します。

qingjia.bpmn20.xml と qingjia.png をプロセス ディレクトリに配置します。

2.2. プロセス定義のデプロイメント

デザイナーで上で定義したプロセスを Activiti データベースにデプロイすることは、プロセス定義のデプロイメントです。Activiti の API を呼び出して、プロセス定義の bpmn ファイルと png ファイルを 1 つずつ Activiti に追加してデプロイするか、2 つのファイルを zip パッケージに圧縮してデプロイします。

2.2.1. 単一ファイルのデプロイ方法

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. 圧縮パッケージの展開方法

@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. 運用データベーステーブル

プロセス定義のデプロイ後の操作アクティビティに関する 3 つのテーブルは次のとおりです。

act_re_deployment プロセスは、デプロイメント テーブルを定義し、デプロイメントごとにレコードを追加します。

act_re_procdef プロセス定義テーブル。新しいプロセス定義をデプロイするたびに、このテーブルにレコードが追加されます。

act_ge_bytearray プロセス リソース テーブル

2.3. プロセスインスタンスの起動

プロセス定義: Java のクラスのように、bpmn ファイルを activiti の 3 つのテーブルに配置します。

プロセス インスタンス: Java のインスタンス オブジェクトに似ています (プロセス定義は複数のプロセス インスタンスに対応できます)。Zhang San は Leave プロセス インスタンスを開始でき、Li Si も Leave プロセス インスタンスを開始できます。これらは互いに影響しません。

@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());
}

動作データシート

act_hi_actinst プロセス インスタンスの実行履歴

Act_hi_identitylink プロセス参加ユーザー履歴情報

act_hi_procinst プロセスインスタンスの履歴情報

act_hi_taskinst プロセスタスクの履歴情報

act_ru_execution プロセス実行情報

act_ru_identitylink処理の参加ユーザー情報

act_ru_task タスク情報

2.4. クエリタスク

各ノードには担当者が設定されており、プロセスの開始後、タスクの担当者は現在処理する必要があるタスクを問い合わせることができ、問い合わせられたタスクはすべてユーザーの To Do タスクです。

@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());
    }
}

例証します:

プロセス インスタンス ID: プロセスは 1 つだけ存在し、プロセスを識別します。

タスク ID: プロセスが特定のノードに到達するたびに、タスク ID がこのノードに割り当てられます。

出力は次のとおりです。

プロセス インスタンス ID: d969f534-825e-11ed-95b4-7c57581a7819

タスクID: d96c3f28-825e-11ed-95b4-7c57581a7819

タスクリーダー: zhangsan

タスク名: Zhang San による承認

2.5、現在のタスクの処理

タスク リーダーは、To Do タスクを照会し、処理するタスクを選択し、タスクを完了します。

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

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

タスクが完了すると、タスクは自動的に次のノードに進みます。

2.6. 処理されたタスクのクエリ

@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. その他のインターフェース (理解)

/**
 * 查询流程定义
 */
@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. 処理例

3.1、プロセスインスタンスとは

プロセス定義 ProcessDefinition とプロセス インスタンス ProcessInstance は、Java クラスと Java インスタンスの関係と同様、Activiti の重要な概念です。

プロセス インスタンスの開始は、ビジネス プロセス操作の開始を意味します。たとえば、従業員の休暇プロセスの展開が完了しました。Zhang San が休暇を申請したい場合は、プロセス インスタンスを開始できます。Li Si が休暇を申請したい場合は、プロセス インスタンスを開始できます。プロセス インスタンスを開始することもできます。2 つのプロセスの実行は相互に影響しません。Java クラスを定義して 2 つのオブジェクトをインスタンス化するのと同じように、デプロイメント プロセスは Java クラスに似ており、プロセス インスタンスの開始は新しい Java オブジェクトに似ています。

3.2. 実際の業務とアクティビティテーブル(BusinessKey)を関連付ける

たとえば、休暇フォームに記入する場合、休暇フォームの一意の ID が必要です。通常、この ID を使用してアクティビティを関連付けます。この ID は、アクティビティではビジネスキーと呼ばれます

BusinessKey: ビジネス識別子、通常はビジネスの主キー。ビジネス識別子とプロセス識別子は 1 対 1 に対応し、ビジネス識別子はビジネス システムから取得され、ビジネス識別子のストレージはデータの関連付けとクエリを行うためのものです。ビジネス識別子に応じたビジネスシステムの

例: 脱退プロセスがプロセス インスタンスを開始するとき、脱退リクエストの ID をビジネス識別子として activiti に保存できます。将来、脱退リクエストの ID は activiti のプロセス インスタンス情報をクエリすることで取得できます。ビジネス システム データベースにクエリを実行して休暇申請情報を取得するため

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

3.3. プロセスインスタンスの一時停止とアクティブ化

場合によっては、プロセスの変更により、現在実行中のプロセスを直接削除するのではなく、一時停止する必要がある場合があります。プロセスが一時停止されると、そのプロセスは実行されなくなります。

3.3.1. すべてのプロセスインスタンスが一時停止される

操作プロセスは一時停止状態として定義され、プロセス定義以下のすべてのプロセス インスタンスが一時停止されます。

プロセス定義は一時停止状態です。このプロセス定義では、新しいプロセス インスタンスを開始できません。同時に、このプロセス定義の下にあるすべてのプロセス インスタンスが一時停止され、一時停止されます。

@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. 単一プロセスインスタンスがハングする

プロセス インスタンス オブジェクトを操作し、単一プロセスの一時停止操作を実行します。プロセス インスタンスが一時停止された場合、プロセスは実行を継続せず、プロセス インスタンスの現在のタスクが完了すると例外が報告されます。

@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. タスクの割り当て

タスクを割り当てるには 3 つの方法があります

  1. 固定配分
  2. UEL 式の割り当て
  3. リスナーの割り当て

4.1. 固定分布

以前のビジネス プロセス モデリングで次のような固定タスク リーダーを指定します。担当者: zhangsan/lisi

4.2. 式の代入

activiti は UEL 式を使用します。UEL は Java EE6 仕様の一部です。UEL は統一された式言語です。activiti は、UEL 値と UEL メソッドという 2 つの UEL 式をサポートします。

4.2.1、UEL値

新機能: 時間外プロセス

図に示すように:

assignee1 この変数はアクティビティのプロセス変数です

プロセスインスタンスを起動します インスタンスの起動方法は基本的に先ほどと同じですが、起動時にパラメータが追加される点が異なります

@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、UEL メソッド

図に示すように:

userBean は Spring コンテナ内の Bean です。これは、Bean の getUsername(int id) メソッドを呼び出すことを意味します。

マネージャーの承認: ${userBean.getUsername(1)}

担当者の承認: ${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";
    }
}

デプロイして開始する

@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());
}

プロセス インスタンスが開始されると、Bean メソッドが呼び出されます。パラメータは 1 です。マネージャーが承認した後、Bean メソッドが呼び出されます。パラメータは 2 です。

4.3. リスナーの割り当て

リスナーメソッドを使用して担当者を指定することで、プロセス設計時に担当者を指定する必要がありません。

タスク リスナーは、対応するタスク関連のイベントが発生したときにカスタム Java ロジックまたは式を実行します。

イベントのオプションは次のとおりです。

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

タスク・リスニング・クラスを定義します。このクラスは 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");
        }
    }
}

リスナーを構成する

管理者承認と人事承認を同じモニターに設定可能

デプロイとテスト

@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());
}

プロセス インスタンスが開始されると、MyTaskListener リスニング メソッドが呼び出されます。

5. プロセス変数

5.1、プロセス変数とは何ですか

プロセス変数はアクティビティにおいて非常に重要な役割を果たします。プロセスの動作はプロセス変数、ビジネス システム、アクティビティに依存することがあります。

プロセス変数は組み合わせが必須であり、プロセス変数はワークフローを管理する際に、アクティビティが管理ニーズに応じて設定する変数です。

例:休暇申請フローでは、休暇日数が2日を超える場合は部長が審査し、それ以外の場合は部長が直接審査します。

この数値はプロセス変数として設定し、プロセス フロー中に使用できます。

5.2、プロセス変数の範囲

プロセス変数の役割はプロセス インスタンスである場合もありますが、タスク (タスク) または実行インスタンスである場合もあります。

5.2.1、グローバル変数

プロセス変数のデフォルトのスコープはプロセス インスタンスです。プロセス変数のスコープがプロセス インスタンスである場合、それをグローバル変数と呼ぶことができます。

グローバル変数内の変数名は重複できませんので、同じ名前の変数を設定すると、後に設定した値で前に設定した変数の値が上書きされます。

5.2.2、ローカル変数

タスクと実行インスタンスは 1 つのタスクと 1 つの実行インスタンスの範囲のみであり、その範囲はローカル変数と呼ばれるプロセス インスタンスほど大きくありません。

ローカル変数のスコープは、異なるタスクや異なる実行インスタンスにおいて相互に影響を及ぼさないため、変数名が同じであっても影響はありません。ローカル変数名はグローバル変数名と同じにすることもできますが、効果はありません。

5.3. プロセス変数の使用方法

UEL 式によるプロセス変数の使用

1. 以前は、${assignee1} などの UEL 式を使用してタスク ハンドラーを設定しました。Activiti は UEL 式の値、つまりプロセス変数 assignee1 の値を取得し、その値をユーザーとして割り当てます。任務の担当

2. タスク間の接続に UEL 式を使用して、${day > 2 } や ${day <= 2} などのプロセスの方向を決定することもできます。day はプロセス変数名であり、UEL の実行式 結果はブール値です

5.4、グローバル変数を設定する

5.4.1. プロセス開始時の変数の設定

プロセスの開始時にプロセス変数を設定します。変数のスコープはプロセス インスタンス全体です。

Map<key,value> を通じてプロセス変数を設定します。マップには複数の変数を設定できます。このキーはプロセス変数の名前です

これは前のサンプルコードです

@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. タスク処理時のプロセス変数の設定

スコープはプロセス インスタンス全体です。設定したプロセス変数のキーがプロセス インスタンス内ですでに同じ名前である場合、後で設定した変数が以前に設定した変数を置き換えます。

シミュレーションのコード例:

@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、現在のプロセスインスタンス設定による

グローバル変数はプロセス インスタンス ID を通じて設定され、そのスコープはプロセス インスタンス全体であり、完了する必要はありません。

シミュレーションのコード例:

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

5.5. ローカル変数の設定

ローカル プロセス変数のスコープは、現在のタスク ノードでのみ使用できます。

タスクが処理されると、ローカル プロセス変数が設定されます。現在実行中のプロセス インスタンスは、タスクの終了前にのみ使用できます。タスクの終了後は、現在のプロセス インスタンスで変数を使用できません。

シミュレーションのコード例:

@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. タスクグループ

6.1、候補者 - ユーザー候補者

1. 需要

プロセス定義では、タスクリーダーはタスクノードの担当者に固定されており、参加者はプロセス定義時に.bpmnファイルに固定されていますが、一時的にタスクリーダーを変更したい場合はプロセスを変更する必要がありますシステムの拡張性が非常に悪いため、タスクの候補を複数設定し、その中から参加者を選択してタスクを完了することができます。

2. タスク候補を設定する

6.2. グループタスクの処理プロセス

ステップ 1: グループタスクのクエリ

候補者を指定し、候補者の現在の To Do タスクをクエリする

候補者はタスクを処理できません

ステップ 2: タスクをピックアップ (請求)

このグループのクエストのすべての候補者が選択できます

候補者のグループタスクを個人タスクに変更すると、元の候補者がタスクの責任者になります

タスクを受け取った後に処理したくない場合

拾う必要がある

ステップ 3: 個人タスクをクエリする

問い合わせ方法は個人タスク部分と同じで、担当者に応じてユーザーが担当する個人タスクを問い合わせます。

ステップ 4: 個人的なタスクを処理する

6.3. キーコード

6.3.1、展開と開始

@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. グループタスクのクエリ

@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. グループタスクを選択する

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

Zhang San 01 はタスクを取得しましたが、Zhang San 02 はタスクを取得できません

6.3.3. 個人の To Do タスクのクエリ

クエリ方法は個人タスククエリと同じです

@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. 個人的なタスクを処理する

個人的なタスクで

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

6.3.5. グループタスクを返す

個人がグループ タスクを処理したくない場合は、グループ タスクを返却することができます。その後、そのユーザーはタスクの担当者ではなくなります。

@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. タスクの引き継ぎ

タスクの引き継ぎ。タスク リーダーは、タスクを処理する他の候補者にタスクを引き継ぎます。

@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. ゲートウェイ

ゲートウェイはプロセスのフローを制御するために使用され、通常はプロセス変数と一緒に使用されます。

7.1. 専用ゲートウェイ

  • 排他的ゲートウェイ: パスは 1 つだけ選択されます

プロセスに次のようなシナリオがある場合: 2 日以内に申請を取り消し、部門長の承認プロセスが終了し、2 日後に部長が直接承認する必要があります。このとき、専用のゲートウェイが必要です。

7.2. パラレルゲートウェイ

  • パラレル (並列) ゲートウェイ: すべてのパスが同時に選択されます

このようなシナリオが発生した場合、休暇申請は部長と部長の両方の承認が必要ですが、前後がない場合は両方の承認が必要となり、次の人事承認ノードに進みます。現時点では、パラレルゲートウェイが必要です

排他的ゲートウェイとの主な違いは、並列ゲートウェイは条件を解決しないことです。シーケンスフロー内に条件を定義しても無視されます。

7.3(ゲートウェイを含む)

包含ゲートウェイ:複数のルートを同時に実行でき、ゲートウェイに条件を設定することもでき、排他ゲートウェイと並列ゲートウェイを組み合わせたものと考えることができます。

このようなシナリオが発生した場合: 休暇申請は 2 日以上の場合は部門の部長によって承認され、2 日未満の場合は部門マネージャーによって承認され、休暇申請は人事マネージャーによって承認されなければなりません。現時点では、ゲートウェイを含める必要があります

おすすめ

転載: blog.csdn.net/qq_61544409/article/details/129719335