袁 博 王慧敏 李 陽 陳明武
(中國電建集團西北勘測設計研究院有限公司,陜西 西安 710065)
目前各個企業(yè)在進行數(shù)字化轉(zhuǎn)型,新能源電站作為生產(chǎn)單位也需要從數(shù)字化的角度看待生產(chǎn)過程的管理,如何減少中間環(huán)節(jié)、節(jié)約成本、簡化業(yè)務流程等,這些問題都給新能源電站的數(shù)字化轉(zhuǎn)型提出了更高的要求。但就目前而言,新能源電站的生產(chǎn)管理工作仍然存在權責不明、過程記錄難以跟蹤、電子文檔缺失等問題,引入Activiti工作流引擎就是為了解決上述問題,通過標準流程、過程文檔電子化使每個人權責分明,降低電站生產(chǎn)管理工作復雜程度,進而提高整體工作效率,加快企業(yè)數(shù)字化轉(zhuǎn)型。
新能源電站大多地處偏遠,運行值班人員生活不便,上下班交通安全性差,也不符合企業(yè)對新能源電站“無人值班、少人值守”的管理要求。運維一體化的管理模式難以橫向?qū)耍瑹o法實現(xiàn)指標最優(yōu)化。這種情況下電站的運營維護效率低下,無法滿足高效管理與高效運維電站的理念。
新能源電站生產(chǎn)管理系統(tǒng)主要實現(xiàn)對下屬各電站的遠程監(jiān)視和統(tǒng)一管理,以促進子站維護質(zhì)量、提高管理和運營效率。新能源電站生產(chǎn)管理系統(tǒng)中使用了Activiti工作流實現(xiàn)對電站維護人員的協(xié)同工作提供技術支持,實現(xiàn)了新能源電站生產(chǎn)運行科學管理、流程管理、跟蹤管理及目標管理的需求,并達到企業(yè)規(guī)范化、精細化、數(shù)字化和集成化管理的目標。
在了解Activiti之前,我們先看一下什么是工作流。在計算機中,工作流屬于計算機支持的協(xié)同工作的一部分,是研究一個群體在計算機的輔助下系統(tǒng)工作。工作流協(xié)助解決的業(yè)務問題是:為了處理多人參與的流程問題,而使用某種預定規(guī)則自動傳遞信息或者任務。Activiti是一個執(zhí)行BPMN2.0規(guī)范的開源引擎,它可以發(fā)布設計過程并通過API實現(xiàn)編程。Activiti工作流引入到新能源電站生產(chǎn)管理系統(tǒng)中,可以利用其提供的服務接口,全程監(jiān)管新能源電站中的生產(chǎn)管理工作。通過Activiti工作流的規(guī)范化特性,可以使新能源電站日常業(yè)務規(guī)范化管理,更加具有條理性,很大程度降低電站日常業(yè)務出錯率。簡單來說,開發(fā)人員只需要把業(yè)務抽象為BPMN流程圖,然后將流程圖部署至Activiti工作流引擎按照流程定義逐步流轉(zhuǎn)即可,這樣不僅降低了業(yè)務的復雜程度,還減少了開發(fā)人員的工作量。
1)數(shù)據(jù)持久化。
Activiti秉承的設計思想是簡單快速。一般來說,應用軟件的性能瓶頸主要是如何快速實現(xiàn)與數(shù)據(jù)庫的數(shù)據(jù)交互,所以Activiti選擇MyBatis作為數(shù)據(jù)持久層框架,保證了數(shù)據(jù)交換的及時性。
2)引擎service接口。
Activiti核心API共有七個,每一項核心API都以服務接口的方式供相關開發(fā)技術人員使用。利用這些接口服務,相關技術開發(fā)人員能夠?qū)崿F(xiàn)功能豐富、輕便且并高效的工作流應用程序,這七大核心API內(nèi)容如表1所示。
表1 Activiti工作流引擎核心API
Activiti工作流引擎最核心的類是ProcessEngine,其他的核心API服務都是通過ProcessEngine獲取。Activiti服務架構如圖1所示。
3)原生支持Spring。
Activiti能夠快速集成Spring,通過Spring實現(xiàn)對Activiti的管理。
本節(jié)內(nèi)容以新能源電站生產(chǎn)管理系統(tǒng)中的危險點預控卡業(yè)務流程為例,對SpringBoot框架結(jié)合Activiti工作流引擎的應用進行解釋說明。
基于Spring Initializr創(chuàng)建一個標準的maven工程,在pom.xml文件中添加SpringBoot,Activiti穩(wěn)定版,如下所示:
項目啟動時,Activiti工作流引擎會自動創(chuàng)建需要的數(shù)據(jù)表,類型如表2所示。
表2 Activiti工作流引擎數(shù)據(jù)表類型
Activiti核心API的操作實際上就是對上面這些表的CRUD,而這些表數(shù)據(jù)的變化實際上代表的是整個流程的運轉(zhuǎn)。
繪制流程圖的過程就是流程定義,流程定義就是按照BPMN2.0標準去描述業(yè)務流程,比如業(yè)務的起始節(jié)點、審批節(jié)點、審批條件等等。Activiti流程圖的繪制方法有多種,如:IDEA+Activiti BPMN visualizer(插件)、Eclipse+ Activiti Designer(插件)、Activiti Modeler等,可以根據(jù)個人的運行環(huán)境自行選擇,危險點預控卡流程圖如圖2所示。
bpmn的根節(jié)點是definitions節(jié)點,在這個節(jié)點中可以定義多個流程定義,但是在實際使用過程中,definitions節(jié)點只包含一個流程定義,也就是一個流程文件只包含一個流程定義,這樣可以減小維護難度,也使得流程內(nèi)容清晰明了。bpmndi:BPMNDiagram節(jié)點中定義了每個節(jié)點在流程圖上的位置坐標等信息。
流程定義好以后需要部署,部署的本質(zhì)就是將流程定義寫入數(shù)據(jù)庫。部署流程圖的方法有多種,下面依次介紹。
4.3.1 InputStream部署
InputStream部署的原理是通過類加載器獲取流程圖文件的數(shù)據(jù)流,構造DeploymentBuilder實例對象,再調(diào)用該實例對象的deploy方法完成流程圖部署。
public void deployInputStreamTest() {
// 獲取流程圖文件流
InputStream inputStream = this.getClass().
getClassLoader().getResourceAsStream("flow/危險點預控卡.bpmn");
String resource = "test.bpmn";
// 構造DeploymentBuilder對象并進行部署操作
repositoryService.createDeployment()
.addInputStream(resource, inputStream)
.deploy();
}
4.3.2 classpath部署
public void deployClasspathTest() {
// 流程圖文件位置
String resource = "flow/危險點預控卡.bpmn";
// 構造DeploymentBuilder對象并進行部署操作
repositoryService.createDeployment().addClasspath
Resource(resource).deploy();
}
4.3.3 字符串部署
字符串部署是將文本內(nèi)容直接作為來源,把文本內(nèi)容轉(zhuǎn)化為字節(jié)流后進行部署。
public void deployStringTest() {
// 字符串
String resource = "
encoding=”UTF-8”?>
";
// 構造DeploymentBuilder對象并進行部署操作
repositoryService.createDeployment()
.addString("test.bpmn", resource)
.deploy();
}
4.3.4 ZipInputStream部署
以上方法都是針對單個流程圖文件部署,如果需要一次部署多個流程圖文件則需要將全部文件打包為zip或者bar格式的壓縮文件,然后再對其進行部署。
public void deployZipTest() {
// 獲取壓縮文件流
InputStream inputStream//壓縮文件流
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
// 構造DeploymentBuilder對象并進行部署操作
repositoryService.createDeployment()
.addZipInputStream(zipInputStream)
.deploy();
}
啟動流程表示開始一次具體的業(yè)務流程,比如請假流程,啟動流程表示發(fā)起一個新的請假申請,而開始的業(yè)務流程就會根據(jù)已經(jīng)部署的流程定義流轉(zhuǎn)。
public ProcessInstance submitApply(ActivitiEntity activiti) {
// 設置啟動流程的人員ID identityService.
setAuthenticatedUserId(activiti.getApplicant());
// 啟動流程時設置業(yè)務 key
ProcessInstance instance = runtimeService.startProcessInstanceByKey(activiti.getProcessKey(), activiti.getBusinessKey(), activiti.getProcessParams());
// 下一節(jié)點處理人待辦事項
activiti.setInstanceId(instance.getProcessInstanceId());
bizTodoItemService.insertTodoItem(activiti);
return instance;
}
其中,ActivitiEntity實體類部分代碼如下:
public class ActivitiEntity extends BaseEntity {
/** 申請事項 */
private String itemName;
/** 申請內(nèi)容 */
private String itemContent;
/** 申請人 */
private String applicant;
/** 流程實例ID */
private String instanceId;
/** 流程定義key */
private String processKey;
/** 創(chuàng)建人名稱 */
private String creatorName;
/** 流程實例狀態(tài) 1 激活 2 掛起 */
private String suspendState;
/** 流程的業(yè)務 key 業(yè)務流轉(zhuǎn) id:統(tǒng)一由業(yè)務 key+ id, eg: firstWorkTicket_1001 */
private String businessKey;
private String businessId;
…
}
上述實體類屬性最關鍵的就是businessKey(業(yè)務標識),businessKey是Activiti和業(yè)務系統(tǒng)整合時的連接點,businessKey相當于業(yè)務表中唯一標識。
流程啟動后,各個任務(節(jié)點)的負責人就可以查詢自己當前需要處理的待辦任務,部分關鍵代碼如下:
public void listPersonalTodoTasks() {
// 任務負責人名稱
String username = "jack";
List
// 危險點預控卡
.processDefinitionKey("dangerPrecontrolcCard")
// 任務負責人名稱
.taskAssignee(username)
.list();
for (Task task : taskList) {
log.info("流程實例id:" + task.getProcessInstanceId() + ",任務id:" + task.getId() + ",負責人:" + task.getAssignee() + ",名稱:" + task.getName());
}
}
任務負責人查詢待辦任務,選擇任務進行處理,完成對應(節(jié)點)任務,部分關鍵代碼如下:
public void completeTask() {
// 任務id
String taskId = "3859";
// 完成任務
taskService.complete(taskId);
}
新能源電站生產(chǎn)管理系統(tǒng)是完全基于光伏電站的實際業(yè)務管理需求而設計的,采用了SpringBoot框架結(jié)合Activiti工作流引擎在新能源電站生產(chǎn)管理系統(tǒng)中完成了設計與實現(xiàn),為新能源電站開展運行管理、設備管理、檢修管理、安全管理等提供信息服務和業(yè)務支撐平臺,提高生產(chǎn)效率和運營效率以及安全可靠性。然后詳細寫了基于Activiti工作流的新能源電站生產(chǎn)管理業(yè)務流程模塊的實現(xiàn)。本系統(tǒng)使新能源電站業(yè)務流程能輕松進行業(yè)務跟蹤,解決了新能源電站生產(chǎn)管理工作中權責不明、過程記錄難以跟蹤、電子文檔缺失等問題,實現(xiàn)生產(chǎn)記錄全過程跟蹤,加強新能源電站生產(chǎn)管理工作的規(guī)范化,也使新能源電站業(yè)務能在網(wǎng)上輕松處理,使新能源電站業(yè)務的自動化和無紙化辦公成為現(xiàn)實。改變了以往傳統(tǒng)的辦公模式,減輕了工作人員的工作壓力,為企業(yè)各部門工作人員之間工作上的溝通提供了一種新的解決方案,有效提升電站運維人員的工作效率,降低了新能源電站行業(yè)的生產(chǎn)成本,進一步加快新能源電站的數(shù)字化轉(zhuǎn)型。