1 根據(jù)80/20原則,只使用wfmc模型中最符合自身應(yīng)用的20%功能
2 充分吸收國內(nèi)使用jbpm開發(fā)BOSS中遇到的問題,工作流引擎只負(fù)責(zé)參數(shù)的收集和流程的流轉(zhuǎn),具體和業(yè)務(wù)的控制,交給每個流程定制的控制類去實現(xiàn)。
3 表單采用簡單的html+控制標(biāo)簽的方法實現(xiàn)
4 權(quán)限和模板引擎,以及其它輔助函數(shù)直接使用辦公系統(tǒng)自帶的框架
5 充分利用PHP語言的特點,流程設(shè)計是基于數(shù)據(jù)庫的,程序上使用OO設(shè)計,但采用重對象的方法
6 不把可視化設(shè)計流程的工作交給最終客戶,而且由設(shè)計時完成,因此不考慮流程版本更新的問題
一、工作流數(shù)據(jù)表設(shè)計
tbl_workflow_defination:工作流定義表
defination_id | 流程id |
| defination_name | 流程名稱 |
| defination_handler | 流程處理輔助文件,每個工作流一個文件 | 自定義處理文件,及其對象。例如workflow-proporsal-handler.php,其中定義對象proposal |
tbl_workflow_node:流程結(jié)點步驟表
node_id | 結(jié)點id |
| defination_id | 流程id |
| node_index | 結(jié)點序號 | 結(jié)點的step | node_name | 結(jié)點名稱 |
| node_type | 結(jié)點類型 | 1人為決策,2自動處理(直接執(zhí)行execute_function),3等待外部響應(yīng)(例如外部WS觸發(fā)),4分支,5匯總 6結(jié)束結(jié)點(此結(jié)點執(zhí)行時候自動終止進(jìn)程) | init_function | 流程初始函數(shù) |
| run_function | 流程運行函數(shù) |
| save_function | 流程保存函數(shù) |
| transit_function | 流程流轉(zhuǎn)函數(shù) |
| prev_node_index | 前結(jié)點序號 | 例如1。開始結(jié)點沒有 執(zhí)行前,通過此來校驗一下流程 | next_node_index | 后結(jié)點序號 | 例如[同意]3,[不同意]4。尾結(jié)點或要結(jié)束的結(jié)點沒有,若沒有,直接調(diào)用end | executor | 執(zhí)行角色,組,人 | role[1,2] group[1,2] user[1,2],為空由運行時決定 | execute_type | 執(zhí)行類型 | 0需所有人執(zhí)行 1只需一人執(zhí)行 | remind | 提醒 | 0不提醒 1郵件 2短信 3郵件和短信 | field | 可編輯的字段 | name,content | max_day | 最長時間(天) |
|
tbl_workflow_process:流程執(zhí)行進(jìn)程表
process_id | 進(jìn)程id |
| defination_id | 流程id |
| process_desc | 進(jìn)程描述 | 顯示在我的工作臺中 | context | 上下文 | 存放上下文變量,例如業(yè)務(wù)表的id | current_node_index | 當(dāng)前結(jié)點序號 |
| start_time | 流程啟動時間 | 如遇分支、匯合顯示為: 1=》3,4=》3,5=》6 | finish_time | 流程完成時間 |
| state | 狀態(tài) | 1運行 2結(jié)束 | start_user | 發(fā)起人 | 發(fā)起人,用于顯示自己的流程 |
tbl_workflow_thread :流程執(zhí)行線程表
thread_id | 線程id |
| process_id | 進(jìn)程id |
| process_desc | 進(jìn)程描述 |
| node_id | 結(jié)點id |
| node_name | 結(jié)點名稱 |
| executor | 執(zhí)行人 |
| start_time | 線程生成時間 |
| receive_time | 線程接收時間 |
| finish_time | 線程完成時間 |
| max_time | 結(jié)點規(guī)定的最長時間 |
| state | 狀態(tài) | 0未接收 1已接收 2已處理 |
二、常見流程
人工決策
領(lǐng)導(dǎo)傳閱 |
部門領(lǐng)導(dǎo)審批 |
填寫表單 |
結(jié)束 |
放棄 |
提交 |
同意 |
重填(退回) |
不同意 |
完成 |
外部響應(yīng)
發(fā)送支付信息 |
接收支付成功響應(yīng)(外部WS觸發(fā)該流程) |
三、PHP設(shè)計
運行的函數(shù)由結(jié)點在設(shè)計時候決定,如果沒有設(shè)定,就使用默認(rèn)的函數(shù)。利用了PHP語言的以下特性
<?phpclass Foo{ function Variable() { $name = 'Bar'; $this->$name(); // This calls the Bar() method } function Bar() { echo "This is Bar"; }}$foo = new Foo();$funcname = "Variable";$foo->$funcname(); // This calls $foo->Variable()?>
使用前可以用method_exists來檢查
WorkflowService.php
WorkflowService
$defination
$process
$node
$thread
$input 用戶輸入的和流程有關(guān)的變量
list_defination()
{
}
init_process(defination_id)
{ global user;
取得$defination,得到業(yè)務(wù)的handler,例如WorkflowProposalHandler
建立$process行記錄
}
start_process()
{ 調(diào)用WorkflowProposalHandler->start($process)//新建業(yè)務(wù)對象,并把業(yè)務(wù)類的參數(shù)例如proposal_id放到$process[‘context’]里面
init_thread(1); //默認(rèn)調(diào)用第一個結(jié)點
}
list_ my_thread ()
{ global user;
}
init_thread(node_index)
{
取得$node
取得$process
修改$process為運行到當(dāng)前結(jié)點
Switch($node[‘node_type’])
Case 1: 人工決策
建立$thread
WorkflowProposalHandler-> init_function ($process,$node,$thread)
發(fā)送提醒
Case 2: 自動處理
建立$thread
WorkflowProposalHandler-> init_function ($process,$node,$thread)
調(diào)用run_thread(thread_id)
Case 3: 等待外部響應(yīng)
建立$thread
WorkflowProposalHandler-> init_function ($process,$node,$thread)
Case 4: 分支
取得所有分支的子結(jié)點
init_thread(子結(jié)點)
Case 5: 匯總:
取得所有前結(jié)點,如果所有前結(jié)點的Thread都結(jié)束了,調(diào)出下一結(jié)點
調(diào)用init_thread(子結(jié)點)
Case 6: 結(jié)束:直接結(jié)束進(jìn)程process
end_process()
}
run_thread(thread_id)
{
取得$node
取得$process
取得$thread
Switch($node[‘node_type’])
Case 1: 人工決策
修改$thread為已接收
WorkflowProposalHandler-> run_function ($process,$node,$thread)顯示表單
Case 2: 自動處理
修改$thread為已接收
$next_node_id=WorkflowProposalHandler-> run_function ($process,$node,$thread)
調(diào)用transit_thread(thread_id, $next_node_id)
Case 3: 等待外部響應(yīng)
修改$thread為已接收
$next_node_id=WorkflowProposalHandler-> run_function ($process,$node,$thread)
transit_thread(thread_id, $next_node_id)
Case 4: 分支
Case 5: 匯總:
Case 6: 結(jié)束:
}
save_thread(thread_id)
{ //保存結(jié)點數(shù)據(jù)
取得$node
取得$process
取得$thread
Switch($node[‘node_type’])
Case 1: 人工決策
WorkflowProposalHandler-> save_function ($process,$node,$thread)保存表單
WorkflowProposalHandler-> run_function ($process,$node,$thread)顯示表單
Case 2: 自動處理
Case 3: 等待外部響應(yīng)
Case 4: 分支
Case 5: 匯總:
Case 6: 結(jié)束:
}
transit_thread(thread_id, $next_node_id)
{ 取得$node
取得$process
取得$thread
Switch($node[‘node_type’])
Case 1: 人工決策
WorkflowProposalHandler->transit_function($process,$node,$thread,$next_node_id)
修改$thread為已完成
If($next_node_id < $ cur_node_id) { //回退
刪除所有大于$next_node_id的Thread
}
init_thread($next_node_id)
Case 2: 自動處理
修改$thread為已完成
If($next_node_id < $ cur_node_id) { //回退
刪除所有大于$next_node_id的Thread
}
init _thread($next_node_id)
Case 3: 等待外部響應(yīng)
修改$thread為已完成
If($next_node_id < $ cur_node_id) { //回退
刪除所有大于$next_node_id的Thread
}
init _thread($next_node_id)
Case 4: 分支
Case 5: 匯總:
Case 6: 結(jié)束:
}
end_process()
list_my_process
view_process
workflow_proposal_handler.php
WorkflowProposalHandler
start()
prepare_input() 準(zhǔn)備用戶輸入變量,從$_POST收集
init_function () 線程建立后調(diào)用的默認(rèn)函數(shù),當(dāng)流程的執(zhí)行者由程序生成時,在此函數(shù)內(nèi)更改$thread的executor,例如直接賦值user[2]
run_function () 線程運行化時候調(diào)用的默認(rèn)函數(shù)
save_function () 保存運行信息
transit_function ()執(zhí)行流轉(zhuǎn)
sendmail 其它結(jié)點調(diào)用函數(shù)
workflow.php
switch(op)
case list_defination
參數(shù):無
WorkflowService->list_defination()
case start_process :啟動
參數(shù):defination_id
WorkflowService->init_process(defination_id)
WorkflowService->start_process()
case list_ my_thread :待處理的列表
WorkflowService->list_ my_thread()
case run_thread :
參數(shù):thread_id
WorkflowService->run_thread(thread_id)
case save_thread :
參數(shù):thread_id
把input收集起來(所有的變量以 f_開頭),賦給WorkflowService的Input,另外還要獲得thread_id
WorkflowService->save_thread(thread_id)
case transit_thread :
參數(shù):thread_id
把input收集起來,賦給WorkflowService的Input,另外還要獲得thread_id
$next_node_id = 得到用戶選擇的下一結(jié)點id
WorkflowService-> transit _thread(thread_id,$next_node_id)
case list_my_process:所有我發(fā)起的流程
case list_all_process:所有我發(fā)起的流程
case view_process :
在其它程序中初始化流程
1先自行建立好業(yè)務(wù)表單
2WorkflowService->init_process(defination_id)
3把建好的業(yè)務(wù)表單的ID放在process的context里面
4WorkflowService->init_thread(1)
WorkflowService->transit_thread(1,2)通過手動調(diào)用把前面的流程過掉
外部服務(wù)繼續(xù)流轉(zhuǎn)流程(只用于自動流程)
1 把input收集起來,賦給WorkflowService的Input,另外還要獲得thread_id
2 WorkflowService->run_thread(thread_id)
相關(guān)文章:
PHP 工作流 自定義表單解決方案
怎么簡單實現(xiàn)工作流?
通達(dá)OA2015版工作流插件和列表控件數(shù)據(jù)解析
鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。
新聞熱點
疑難解答
圖片精選