劉恩海 李 甜 陳媛媛(河北工業大學計算機科學與技術系 天津 300401)
工作流是業務流程在計算機應用環境下的自動化,是各操作步驟之間業務規則的抽象、概括描述。工作流技術是電子政務的核心,是企業管理以及政府部門工作中不可或缺的部分。工作流管理系統的目標是使企業中大量基于知識與規則的任務和活動能夠相互協調一致、高效運轉[1]。
工作流引擎是工作流管理系統的核心,它與企業核心利益息息相關[2]。目前國內外的開源工作流有JBPM、Activiti、OSWorkflow等。由于這些工作流大多結構復雜、靈活性差,流程變更頻繁,運維投入很大,在國內企業的使用情況并不理想,普及率也較低[3]。
本文基于工作流研究的現狀,通過借鑒傳統的工作流模型,開發了一套基于Web的跨部門工作流引擎。跨部門工作流引擎幫助企業解決各個部門和系統內部的任務自動化、數據集成、以及控制管理的難題,消除企業內各部門之間的隔閡,為跨部門的業務流程帶來了出色的效率、靈活度、合規性、以及可監控性。
本文從數據表和ER圖出發,對審核流程進行詳細介紹,使后續開發者可以根據自身不同需求進行二次開發,設計出更適合自身需求的工作流,其原型已在廊坊市計量信息管理服務平臺中應用。
工作流模型是對現實世界中業務過程的抽象,并用一種形式化的、計算機可處理的方式表示出來。工作流模型是工作流引擎執行的前提和基礎,在進行工作流設計前必須先選定相應的工作流模型。
本文所設計的工作流引擎模型由兩部分組成:工作流定義模塊和工作流引擎模塊。工作流引擎結構功能如圖1所示。

圖1 工作流引擎功能結構
在圖1中,工作流定義模塊負責工作流的定義、解釋及維護;工作流引擎模塊負責對整個工作流程及工作項的創建、激活、掛起、終止等行為進行監控, 控制工作項的狀態轉換邏輯[4]。
工作流定義是工作流引擎中至為重要的一部分[5]。工作流節點設計是工作流定義的核心部分,不同組織給出了各自的工作流節點模型,比較著名的有:WFMC,WIDE,WAMO,Active Workflow[6]。
本文基于關系型數據庫MySQL設計了數據模型,將區域、部門、崗位、節點、角色、用戶等工作流引擎要素以及各要素間的邏輯關系通過數據表的形式來展現。工作流引擎通常使用數據來控制流程[7]。工作流節點設計為雙向鏈表形式,以實現工作在工作流上能夠上下移動。數據模型設計如圖2所示。

圖2 工作流引擎E-R圖
本文所設計的工作流引擎模型中,工作流節點由工作流類型、區域類型、部門類型- 崗位共同決定,其中,為防止添加工作流節點時出現某部門沒有該崗位的情況,部門類型- 崗位又需要由部門和崗位共同決定。另外,部門類型- 崗位表和用戶- 部門- 崗位表為關聯表,其作用是將部門、崗位、用戶之間m∶n的邏輯關系處理為1∶n的邏輯關系,簡化實際的代碼編寫。工作流引擎負責維護工作流,當用戶修改工作流后,工作流引擎必須能夠及時將改動后的工作流存入數據表,并確保邏輯關系準確無誤。
申請人發起的申請從提交到審批的過程中,涉及到四種不同狀態之間的轉換:待辦、在辦、已辦和擱置,工作狀態由用戶的操作觸發得到轉換。當一個申請被創建時,該申請進入“未辦”狀態;審核員點擊查看工作,但未進行提交,該申請進入“在辦”狀態;審核人員進行擱置操作,進入“擱置”狀態;審核員進行辦結操作,申請進入“辦結”狀態[8]。工作的狀態轉換如圖3所示。

圖3 工作狀態圖
字段狀態如表1所示。

表1 字段狀態表
大部分開源工作流只提供同一部門審核功能,極少數工作流雖然可以實現跨部門審核功能,但又局限于同一主體。應用度最廣的JBPM工作流引擎,從設計上就沒有考慮“回退”、“取回”等業務場景。本文將不同主體視為同一主體下的部門,并結合擱置、退回、取回等實際情況,實現了跨主體審核的功能。本文中,每種申請類型對應不同主體,每個用戶對應多種申請類型。用戶提交申請之后,選擇相對應的審核人。無論申請人的部門崗位如何復雜,都能夠根據引擎模型準確查找到下一審核人。數據流圖如圖4所示。

圖4 工作流引擎數據流圖
在應用本工作流引擎的系統中,申請人需要將信息上傳,選擇合適的工作流之后,系統自動獲取到正確的審核人供申請人選擇,審核成功或者失敗都需要將審核結果發送至申請員。如何獲取到適合該申請人的審核流程,和選擇審核流程之后如何精確查找下一審核人,是工作流引擎的關鍵所在。以本工作流引擎中已有的審核流程為例,如圖5所示。

圖5 審核流程交互活動圖
以圖示為例,省級管理部門受理工作申請時,根據情況判斷當前申請是否合格。如合格,則進行辦結操作,審核流程結束,消息反饋申請人;如不合格,則省級管理部門可選擇將申請回退給上一審核人或申請人,即市級管理部門或縣級技術機構,此時上級審核人修改審核意見或申請人修改申請,重新提交。
申請人發起申請后,流程具體如下:
(1) 申請人登錄系統后,首先選擇申請類型。系統根據用戶選擇的申請類型,獲取申請類型id(apply_type_id)。
(2) 根據申請類型id從工作類型- 申請類型表中獲得所有對應工作流類型id。
(3) 用戶選擇工作流類型,系統獲取工作流類型id(workflow_type_id)。
(4) 根據工作流類型id(workflow_type_id)從工作流節點表中獲取下一工作流節點。工作流節點表中每一條數據都記錄了包括工作流類型在內的區域類型id、部門類型id、崗位id、部門類型- 崗位id以及上一工作流節點和下一工作流節點,當系統獲取到工作流類型id時就能夠獲取到所有需要的信息。
(5) 由工作流節點獲取到用戶的區域類型,此時系統可以根據申請人當前區域類型獲取上級區域類型信息。
(6) 在申請人的上級區域信息中尋找工作流節點表中的部門類型- 崗位信息,分別由部門類型和崗位找到部門信息和崗位信息。
(7) 由部門崗位信息找到當前部門崗位下的所有用戶,如果有符合要求的審核人,則直接返回用戶id(user_id)。
(8) 獲取用戶提交的申請信息。
(9) 將這一申請提交至下一審核人處。
以應用本文所設計的工作流引擎的系統為例,工作流申請活動圖如圖6所示。申請人提交工作,下一審核人查看工作之后可進行退回、擱置、同意操作,同意申請之后系統會判斷是否存在下一審核人,若存在下一審核人,則同時更新本審核人工作記錄并生成下一審核人工作記錄,完成后將工作移交新的審核人,重復之前的判定步驟。

圖6 工作流申請活動圖
當審核申請提交之后,如果想要修改申請,申請人可以進行取回操作。發起取回申請時,首先判斷當前申請狀態,是否有人進行了審核,如果已有人審核則不能進行取回操作;只有當申請為待辦狀態時,即工作流狀態字段均為0的情況下才會進行取回操作。
取回過程代碼摘要如下:
//獲取USERID
$userId = get_user_id();
//獲取當前用戶下的待辦信息
$map[′isClicked′] =′0′;
$this->getMyJobByUserIdIsClickedIsCommitedIsShelved($userId, $map);
$this->assign(′YZBODY′,this->fetch(′unfinished′));
$this->display(YZTemplate);
//獲取當前工作流節點信息
$workflowNodeId = I(′get.id′);
if(!is_numeric($workflowLogId)‖empty($workflowNodeId))
{
$this->_empty();
return;
}
//判斷當前結點是否屬于用戶
if($workflowNode [′user_id′] !=$userId)
{
$this->error = ″當前結點并不屬于當前用戶″;
$this->_empty();
return;
}
//更新工作表
$workType=WorkflowType->where(workflowNodeId)->select();
$workflowType->is_clicked=’0’;
具體流程如下:
(1) 申請人發起取回申請。
(2) 判斷當前申請的工作狀態字段表信息,“is_clicked”是否為0,如果是,則記錄當前工作id。
(3) 根據工作id獲取當前申請的工作流節點id。
(4) 根據工作流節點id獲取當前工作流節點表信息。
(5) 將下一工作流節點信息置為0。
(6) 更新工作流表中鏈路信息。
工作流取回流程數據流圖如圖7所示。

圖7 工作流取回數據流程圖
當審核人在審核過程中發現申請存在問題時,可以將申請退回。申請被退回時,系統首先判斷是否存在上一審核人,如果存在,則審核人可以選擇退回上一審核人或退回申請人:選擇退回上一審核人,則工作流審核權交回上一審核人,上一審核人可以選擇提出修改意見提交給下一審核人;或者選擇退回申請人。
退回過程邏輯代碼摘要如下:
elseif($type == 1)
{if(!$WorkflowLogL->backToStart())
{
$this->error =$WorkflowLogL->getError();
$this->_empty();
return;
}
}
具體步驟如下:
(1) 獲取當前工作流的工作狀態表信息;
(2) 重置當前工作流的工作狀態表,將“is_clicked”和“is_commited”置為0;
(3) 獲取當前工作流節點表信息;
(4) 判斷上一工作流節點是否為根節點;
(5) 刪除當前工作流下一節點信息;
(6) 更新當前工作流節點表中當前節點信息為根節點。
工作流退回流程如圖8所示。

圖8 工作流退回數據流圖
當審核申請提交之后,申請人發現存在問題較為嚴重無法修改時,可以將工作流刪除,邏輯代碼摘要如下:
//判斷當用流程在當前用戶下未提交
if($workflowLog[′is_commited′] == 1)
{E(″當前用戶userId并不是當前審核結點id的待在辦人″);
}
//判斷申請人為當前用戶
if($project[′user_id′] !=$userId)
{E(″當前項目的申請人$project[user_id]非當前用戶userId″);
}
//刪除所有節點表信息
$WorkflowL->deleteByProjectId($projectId);
//刪除工作狀態信息
$WorkflowLogL->deleteByWorkflowId($workflowId);
具體流程如下:
(1) 獲取當前用戶信息;
(2) 獲取當前工作流狀態表信息,判斷當前狀態節點是否為當前用戶,“否”則無操作權限;
(3) 判斷當前工作流狀態,“is_committed”是否為0;
(4) 獲取工作流節點表信息,判斷當前節點是否為根節點,“否”則無操作權限;
(5) 刪除當前工作流中節點表信息;
(6) 刪除當前工作流中工作狀態信息;
(7) 重置當前工作流關聯數據表中信息為空。
刪除操作流程圖如9所示。

圖9 刪除流程圖
工作流提交之后,審核人可以對工作進行擱置、取消擱置、退回、提交下一審核人和辦結操作。審批流程涉及到整體數據的流向,是工作流中最為復雜的一部分。流程圖如10所示。

圖10 審批流程圖
具體流程如下:
(1) 獲取當前用戶信息(user-id);
(2) 獲取當前工作流節點表信息;
(3) 判斷當前用戶所在節點是否為根節點,是則當前用戶為提交人,否則當前用戶為審核人。
根據當前用戶信息,系統判斷用戶可執行的下一步操作:
1) 當用戶為申請人,步驟如下:
(1) 獲取當前工作流適用的工作流類型表信息;
(2) 獲取當前申請類型表信息;
(3) 根據申請類型和工作流類型信息獲取工作流節點表信息;
(4) 選擇下一工作流節點,生成工作流節點信息存入工作流節點表;
(5) 生成工作信息存入工作表。
2) 當用戶為審核人,審核人可以對工作流進行提交、擱置、退回、辦結等操作,根據不同操作,進行如下分類:
(1) 如果用戶進行同意或辦結操作:
① 獲取工作流節點表信息。
② 判斷是否為終節點:若為終節點,則獲取工作表信息,將工作表中 “is_commited”字段置為1并存入工作表;若非終節點,則進行如下操作。
③ 獲取當前工作流審核信息,判斷當前用戶是否在審核用戶列表,如果“否”則提示無權限操作。
④ 獲取當前工作流節點信息,將當前工作流節點存入下一節點信息。
⑤ 獲取當前工作信息,將當前用戶id存入工作信息表。
⑥ 更新工作信息表,將工作狀態“is_commited”字段置為1。
(2) 如果用戶進行的是擱置操作,邏輯代碼摘要如下:
//查詢是否為在辦
$map = array();
$map[′id′] =$workflowLogId;
$map[′is_commited′] = ′0′;
if($WorkflowLogM->where($map)->find() == null)
{$this->error =″該流程已辦結,不適用擱置操作″;
$this->_empty();
}
//更新擱置數據
$data = array();
$data[′id′] = workflowLogId;
$data[′is_shelved′] = ″1″;
$data[′commit′] = I(′post.commit′);
$WorkflowLogM->data($data)->save();
具體步驟如下:
① 判斷當前申請的工作狀態是否為完結,即工作狀態表中“is_commited”字段是否為1,若為1則證明工作已完結,返回提示信息。
② 如果“is_commited”字段為 “0”,更新當前工作流日志信息,即將“is_ abeyanced”字段置為“1”。
(3) 如果用戶進行取消擱置操作,邏輯代碼摘要如下:
//查詢是否為待辦,且已擱置
$map = array();
$map[′id′] =$workflowLogId;
$map[′is_commited′] = ′0′;
$map[′is_shelved′] = ′1′;
if($WorkflowLogM->where($map)->find() == null)
{$this->error = ″該流程已辦結,不適用擱置操作″;
$this->_empty();
return false;
}
//更新擱置數據
$data = array();
$data[′id′] = workflowLogId;
$data[′is_shelved′] = ″0″;
$data[′commit′] = I(′post.commit′);
$WorkflowLogM->data($data)->save();
具體步驟如下:
① 判斷當前申請的工作狀態是否為擱置,即工作狀態表中“is_ abeyanced”字段是否為1,如果為“0”則返回不存在擱置的提示信息;
② 更新當前工作流日志信息,將“is_ abeyanced”字段置為“0”。
一直以來工作流問題都是企業管理中的核心,良好的工作流能夠使各部門在工作處理、審批過程中節省更多的人力,釋放更多的資源,提高企業管理的工作效率[9]。目前跨部門工作流在國外已經有廣泛應用,例如醫療系統中的掛號預約流程,啟用工作流模型的預約系統相較普通預約系統效率提升40%~45%[10]。目前跨部門工作流還是以應用的方式集成于系統中,更長遠的說,相同的工作流方法可以被應用于任何基于互聯網的基礎應用程序中[11]。
本文從數據流出發,詳細闡述了整個申請流程中的數據轉移情況,更加直觀地將工作流問題以計算機形式說明,使工作流不再單純地局限于書面表達。通過閱讀本文,能夠更加清晰地理解工作流的申請審核流程。在應用了本工作流的系統中,實現了對跨越不同部門和主體的業務流程的靈活控制,縮減了跨部門業務的響應時間,極大地降低了工作流的實現難度,簡化了業務流程操作。本工作流適用于非常廣泛的審核情況,并能夠根據不同需求進行二次開發,方便對工作項目進行管理、分派,提高了工作效率。
[1] 蔡孝武, 韓永國, 藍科. 一種輕量級工作流引擎的研究與設計[J]. 計算機工程, 2010, 36(20):78- 79.
[2] 楊明順, 韓周鵬, 余婷,等. 一種輕型工作流引擎的設計與實現[J]. 西安理工大學學報, 2013, 29(1):20- 26.
[3] 徐新權,孟江濤,劉宏志,等. 基于 SAP 工作流引擎的應用[J].計算機應用, 2013,33( S2) : 251- 255.
[4] 路春光, 孟麗麗, 郝立文,等. 基于WEB的柔性工作流引擎的設計[J]. 微計算機信息, 2006, 22(15):21- 23.
[5] 葛中澤. 工作流引擎設計關鍵技術的實現[J]. 鄂州大學學報, 2015(5):107- 109.
[6] 徐亮, 張莉, 樊志強. 一種基于UML的實時工作流建模方法研究[J]. 計算機研究與發展, 2010, 47(7):1184- 1191.
[7] 侯培文, 劉軍利. 輕型工作流引擎在工作流管理系統中的應用[J]. 電腦開發與應用, 2010, 23(2):46- 48.
[8] 朱春旭, 王小剛, 殷振華. JBPM4工作流引擎在科研項目管理系統中的應用研究[J]. 電子技術與軟件工程, 2017(1):193- 195.
[9] 羅海濱, 范玉順, 吳澄. 工作流技術綜述[J]. 軟件學報, 2000, 11(7):899- 907.
[10] Rahman M, Maccaull W. An Application Suite for Service Enabled Workflow[J]. Procedia Computer Science, 2016, 83:480- 487.
[11] George S, David K. Workflow Enabled data Processing in a Concurrent Engineering Environment[J]. Procedia Technology, 2016, 24:1643- 1650.