SpringBoot集成工作流引擎

SpringBoot集成工作流引擎

一、Activiti簡介

Activiti5是由Alfresco軟件在2010年5月17日發佈的業務流程管理(BPM)框架,它是覆蓋了業務流程管理、工作流、服務協作等領域的一個開源的、靈活的、易擴展的可執行流程語言框架。Activiti基於Apache許可的開源BPM平臺,創始人Tom Baeyens是JBoss jBPM的項目架構師,它特色是提供了eclipse插件,開發人員可以通過插件直接繪畫出業務 流程圖。.

二、Activiti插件安裝

關於activiti建議在eclipse下安裝相關插件,idea下安裝的actiBPMN有很多問題,界面也不是很友好。

下圖是eclipse下繪製的一個流程圖:


SpringBoot集成工作流引擎

一個簡單的工作流包括開始節點,流程節點和結束節點。

三、SpringBoot集成Activiti

這裡我們用的是activiti6.0版本,主要需要如下包:

application.yml主要配置如下:

server:
port: 8801
spring:
datasource:
url: jdbc:mysql://10.168.xx.xx:8106/uaf_activiti?Unicode=true&characterEncoding=UTF-8
username: root
password: xxxxx
activiti:
database-schema-update: true
check-process-definitions: false

以上為基本配置,完成上述配置後我們啟動activiti服務系統會自動初始表到我們mysql庫。

四、監聽方式配置Activiti流程

我們一般配置activiti流程的時候代理人都是寫死的方式,這樣若修改代理人時需要重新部署流程。

activiti也支持靈活的方式配置代理人,主要有兩種方式:

  1. 動態參數方式。
  2. 監聽方式。

這裡我們介紹監聽方式,配置監聽方式首先我們需要定義activiti的監聽類:

public class ActProcessListener implements TaskListener {

\t/**流程監聽成員變量*/
\tprivate FixedValue processCode;

\t@Override
\tpublic void notify(DelegateTask delegateTask) {
\t\t//TODO 新建流程節點與審批用戶/角色關聯表,實現流程動態監聽
\t\tString process = String.valueOf(processCode.getValue(delegateTask));
\t\tMySlf4j.textInfo("進入{0}流程節點監聽.....", process);
\t\tif ("leaveApply".equals(process)) {
\t\t\tdelegateTask.addCandidateUser("will");
\t\t} else if ("deptManagerAppr".equals(process)) {
\t\t\tdelegateTask.addCandidateUser("deman");
\t\t} else if ("hrClerkAppr".equals(process)) {
\t\t\tdelegateTask.addCandidateUser("petty");
\t\t} else if ("hrManagerAppr".equals(process)) {
\t\t\tdelegateTask.addCandidateUser("may");
\t\t}

\t}
}

通過監聽方式,流程可以自動判斷下一節點的受理人,我們也可以將監聽配置放到數據庫管理,實現真正意義上的動態配置。

工作流需要管理相應的監聽類,並指定監聽成員變量。如下圖:


SpringBoot集成工作流引擎

五、工作流引擎執行

工作流程引擎一般包括如下步驟:


SpringBoot集成工作流引擎

相關接口代碼如下:

/**部署流程*/
ActProcessRespVo deployProcess(ActProcessReqVo actProcessReqVo);

/**啟動流程*/
ActWorkflowRespVo startWorkflow(ActWorkflowReqVo<labelinfo> actWorkflowReqVo);

/**簽收任務*/
boolean claimTask(ActClaimTaskReqVo actClaimTaskReqVo);

/**提交任務*/
boolean completeTask(ActCompleteTaskReqVo<labelinfo> actCompleteTaskReqVo);

/**查詢任務是否已簽收*/
boolean checkClaimTask(ActClaimTaskReqVo actClaimTaskReqVo);

/**釋放任務*/
boolean releaseTask(String taskId);

/**查詢待辦任務*/
ActProcessTaskRespVo queryTodoTasks(ActProcessTaskReqVo actProcessTaskReqVo);/<labelinfo>/<labelinfo>

測試類代碼如下:

@SpringBootTest(classes = ActivitiApplication.class)
@RunWith(SpringRunner.class)
public class ActivitiProcessTest {

\t@Autowired
\tprivate IActivitiService activitiService;
\t@Autowired
\tprivate IWorkflowService workflowService;

\t/**流程文件路徑*/
\tstatic String filePath = System.getProperty("user.dir") + "/src/main/resources/processes/leaveProcess.bpmn";

\t/**流程部署*/
\t@Test
\tpublic void testDeployProcess() throws IOException {
\t\tbyte[] b = Files.readAllBytes(Paths.get(filePath));
\t\tActProcessReqVo actProcessReqVo = new ActProcessReqVo();

\t\tactProcessReqVo.setProcessId("leaveProcess");
\t\tactProcessReqVo.setProcessName("請假流程");
\t\tactProcessReqVo.setProcessFileType("bpmn");
\t\tactProcessReqVo.setProcessBase64Str(Base64Utils.encode(b));
\t\tactivitiService.deployProcess(actProcessReqVo);
\t}

\t/**啟動流程*/
\t@Test
\tpublic void testStartWorkflow() {
\t\tActWorkflowReqVo<labelinfo> actWorkflowReqVo = new ActWorkflowReqVo<>();
\t\tactWorkflowReqVo.setBusinessId("201912020001");
\t\tactWorkflowReqVo.setProcessId("leaveProcess");

\t\tList<labelinfo> labelInfos = new ArrayList<>();
\t\tLabelInfo labelInfo1 = new LabelInfo();
\t\tlabelInfo1.setLabName("userName");
\t\tlabelInfo1.setLabType("S");
\t\tlabelInfo1.setLabValue("will");
\t\tlabelInfos.add(labelInfo1);
\t\tactWorkflowReqVo.setLabels(labelInfos);

\t\tActWorkflowRespVo actWorkflowRespVo = workflowService.startWorkflow(actWorkflowReqVo);
\t\tMySlf4j.textInfo("啟動流程輸出:{0}", JsonUtils.toJson(actWorkflowRespVo));
\t}

\t/** 提交任務-請假申請*/
\t@Test
\tpublic void testCompleteTask1() {
\t\tActCompleteTaskReqVo actCompleteTaskReqVo = new ActCompleteTaskReqVo();
\t\tactCompleteTaskReqVo.setComment("個人事務請假1天.....");
\t\tactCompleteTaskReqVo.setProcessInstanceId("5001");
\t\tactCompleteTaskReqVo.setUserId("will");
\t\tactCompleteTaskReqVo.setProcessId("leaveProcess");
\t\tboolean res = workflowService.completeTask(actCompleteTaskReqVo);
\t\tMySlf4j.textInfo("簽收任務流程輸出:{0}", res);
\t}

\t/** 提交任務-部門主管審批*/
\t@Test
\tpublic void testCompleteTask2() {
\t\tActCompleteTaskReqVo<labelinfo> actCompleteTaskReqVo = new ActCompleteTaskReqVo<>();
\t\tactCompleteTaskReqVo.setComment("同意");
\t\tactCompleteTaskReqVo.setProcessInstanceId("2501");
\t\tactCompleteTaskReqVo.setUserId("deman");
\t\tactCompleteTaskReqVo.setProcessId("leaveProcess");


\t\tList<labelinfo> labelInfos = new ArrayList<>();
\t\tLabelInfo labelInfo1 = new LabelInfo();
\t\tlabelInfo1.setLabName("opinion");
\t\tlabelInfo1.setLabType("S");
\t\tlabelInfo1.setLabValue("TH");

\t\tLabelInfo labelInfo2 = new LabelInfo();
\t\tlabelInfo2.setLabName("days");
\t\tlabelInfo2.setLabType("I");
\t\tlabelInfo2.setLabValue("1");

\t\tlabelInfos.add(labelInfo1);
\t\tlabelInfos.add(labelInfo2);
\t\tactCompleteTaskReqVo.setLabels(labelInfos);

\t\tboolean res = workflowService.completeTask(actCompleteTaskReqVo);
\t\tMySlf4j.textInfo("簽收任務流程輸出:{0}", res);
\t}

\t/** 提交任務-HR審批*/
\t@Test
\tpublic void testCompleteTask3() {
\t\tActCompleteTaskReqVo actCompleteTaskReqVo = new ActCompleteTaskReqVo();
\t\tactCompleteTaskReqVo.setComment("同意");
\t\tactCompleteTaskReqVo.setProcessInstanceId("2501");
\t\tactCompleteTaskReqVo.setUserId("petty");
\t\tactCompleteTaskReqVo.setProcessId("leaveProcess");

\t\tList<labelinfo> labelInfos = new ArrayList<>();
\t\tLabelInfo labelInfo1 = new LabelInfo();
\t\tlabelInfo1.setLabName("opinion");
\t\tlabelInfo1.setLabType("S");
\t\tlabelInfo1.setLabValue("TH");

\t\tlabelInfos.add(labelInfo1);
\t\tactCompleteTaskReqVo.setLabels(labelInfos);

\t\tboolean res = workflowService.completeTask(actCompleteTaskReqVo);
\t\tMySlf4j.textInfo("簽收任務流程輸出:{0}", res);
\t}

\t/** 查看任務是否簽收*/
\t@Test
\tpublic void testCheckClaimTask() {
\t\tActClaimTaskReqVo actClaimTaskReqVo = new ActClaimTaskReqVo();
\t\tactClaimTaskReqVo.setUserId("will");

\t\tactClaimTaskReqVo.setTaskId("2507");
\t\tboolean res = workflowService.checkClaimTask(actClaimTaskReqVo);
\t\tMySlf4j.textInfo("查看任務是否簽收輸出:{0}", res);
\t}

\t/** 查看待辦任務*/
\t@Test
\tpublic void testQueryTodoTasks() {
\t\tActProcessTaskReqVo actProcessTaskReqVo = new ActProcessTaskReqVo();
\t\tactProcessTaskReqVo.setProcessId("leaveProcess");
\t\tactProcessTaskReqVo.setUserId("will");
\t\tactProcessTaskReqVo.setStartNum(0);
\t\tactProcessTaskReqVo.setRecNum(10);
\t\tActProcessTaskRespVo actProcessTaskRespVo = workflowService.queryTodoTasks(actProcessTaskReqVo);
\t\tMySlf4j.textInfo("查詢待辦任務輸出:{0}", JsonUtils.toJson(actProcessTaskRespVo));
\t}/<labelinfo>/<labelinfo>/<labelinfo>/<labelinfo>/<labelinfo>

需要完整的代碼可以私信!!!


分享到:


相關文章: