工做流設計參考(包括PHP實現)

工做流不多有讓人滿意的,即使是國內用的比較多的jbpm,用起來也會以爲很便扭。再加上PHP中沒有什麼好用的工做流,因而乾脆本身設計一個,設計的原則以下:php

1 根據80/20原則,只使用wfmc模型中最符合自身應用的20%功能html

2 充分吸取國內使用jbpm開發BOSS中遇到的問題,工做流引擎只負責參數的收集和流程的流轉,具體和業務的控制,交給每一個流程定製的控制類去實現。node

3 表單採用簡單的html+控制標籤的方法實現數據庫

4 權限和模板引擎,以及其它輔助函數直接使用辦公系統自帶的框架框架

5 充分利用PHP語言的特色,流程設計是基於數據庫的,程序上使用OO設計,但採用重對象的方法函數

6 不把可視化設計流程的工做交給最終客戶,並且由設計時完成,所以不考慮流程版本更新的問題this

 

1、工做流數據表設計spa

 

tbl_workflow_defination:工做流定義表線程

defination_id設計

流程id

 

defination_name

流程名稱

 

defination_handler

流程處理輔助文件,每一個工做流一個文件

自定義處理文件,及其對象。例如workflow-proporsal-handler.php,其中定義對象proposal

 

tbl_workflow_node:流程結點步驟表

node_id

結點id

 

defination_id

流程id

 

node_index

結點序號

結點的step

node_name

結點名稱

 

node_type

結點類型

1人爲決策,2自動處理(直接執行execute_function)3等待外部響應(例如外部WS觸發),4分支,5彙總 6結束結點(此結點執行時候自動終止進程)

init_function

流程初始函數

 

run_function

流程運行函數

 

save_function

流程保存函數

 

transit_function

流程流轉函數

 

prev_node_index

前結點序號

例如1。開始結點沒有

執行前,經過此來校驗一下流程

next_node_index

後結點序號

例如[贊成]3,[不一樣意]4。尾結點或要結束的結點沒有,若沒有,直接調用end

executor

執行角色,組,人

role[1,2] group[1,2] user[1,2],爲空由運行時決定

execute_type

執行類型

0需全部人執行 1只需一人執行

remind

提醒

0不提醒 1郵件 2短信 3郵件和短信

field

可編輯的字段

name,content

max_day

最長時間()

 

 

tbl_workflow_process :流程執行進程表

process_id

進程id

 

defination_id

流程id

 

process_desc

進程描述

顯示在個人工做臺中

context

上下文

存放上下文變量,例如業務表的id

current_node_index

當前結點序號

 

start_time

流程啓動時間

如遇分支、匯合顯示爲:

1=》3,4=》3,5=》6

finish_time

流程完成時間

 

state

狀態

1運行 2結束

start_user

發起人

發起人,用於顯示本身的流程

 

tbl_workflow_thread :流程執行線程表

thread_id

線程id

 

process_id

進程id

 

process_desc

進程描述

 

node_id

結點id

 

node_name

結點名稱

 

executor

執行人

 

start_time

線程生成時間

 

receive_time

線程接收時間

 

finish_time

線程完成時間

 

max_time

結點規定的最長時間

 

state

狀態

0未接收 1已接收 2已處理

 

2、常見流程

人工決策

 

領導傳閱

部門領導審批

填寫表單

結束

放棄

提交

贊成

重填(退回)

不一樣意

完成

 

外部響應

 

發送支付信息

接收支付成功響應(外部WS觸發該流程)

 

3、PHP設計

運行的函數由結點在設計時候決定,若是沒有設定,就使用默認的函數。利用了PHP語言的如下特性

<?php
class 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 用戶輸入的和流程有關的變量

list_defination()

{

}

init_process(defination_id)

{  global user;

取得$defination,獲得業務的handler,例如WorkflowProposalHandler

   創建$process行記錄

}

start_process()

{  調用WorkflowProposalHandler->start($process)//新建業務對象,並把業務類的參數例如proposal_id放到$process[‘context’]裏面

   init_thread(1);  //默認調用第一個結點

}

 

list_ my_thread ()

{  global user;

}

 

init_thread(node_index)

{

  取得$node

  取得$process

  修改$process爲運行到當前結點

  Switch($node[‘node_type’])

   Case 1: 人工決策

       創建$thread

       WorkflowProposalHandler-> init_function ($process,$node,$thread)

       發送提醒

Case 2: 自動處理

    創建$thread

    WorkflowProposalHandler-> init_function ($process,$node,$thread)

       調用run_thread(thread_id)

Case 3: 等待外部響應

    創建$thread

    WorkflowProposalHandler-> init_function ($process,$node,$thread)

Case 4: 分支

    取得全部分支的子結點

    init_thread(子結點)

Case 5: 彙總:

    取得全部前結點,若是全部前結點的Thread都結束了,調出下一結點

       調用init_thread(子結點)

Case 6: 結束:直接結束進程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)

       調用transit_thread(thread_id, $next_node_id)

Case 3: 等待外部響應

    修改$thread爲已接收

    $next_node_id=WorkflowProposalHandler-> run_function ($process,$node,$thread)

    transit_thread(thread_id, $next_node_id)

Case 4: 分支

Case 5: 彙總:

Case 6: 結束:

}

save_thread(thread_id)

{  //保存結點數據

取得$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: 等待外部響應

Case 4: 分支

Case 5: 彙總:

Case 6: 結束:

}

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_idThread

}

init_thread($next_node_id)

Case 2: 自動處理

修改$thread爲已完成

           If($next_node_id < $ cur_node_id) { //回退

刪除全部大於$next_node_idThread

}

       init _thread($next_node_id)

Case 3: 等待外部響應

    修改$thread爲已完成

           If($next_node_id < $ cur_node_id) { //回退

刪除全部大於$next_node_idThread

}

    init _thread($next_node_id)

Case 4: 分支

Case 5: 彙總:

Case 6: 結束:

 

}

 

end_process()

 

list_my_process

view_process

 

workflow_proposal_handler.php

WorkflowProposalHandler

  start()

  prepare_input() 準備用戶輸入變量,從$_POST收集

  init_function () 線程創建後調用的默認函數,當流程的執行者由程序生成時,在此函數內更改$threadexecutor,例如直接賦值user[2]

run_function () 線程運行化時候調用的默認函數

save_function () 保存運行信息

  transit_function () 執行流轉

  sendmail 其它結點調用函數

 

workflow.php

 switch(op)

   case list_defination

        參數:無

WorkflowService->list_defination()

case start_process : 啓動

       參數:defination_id

       WorkflowService->init_process(defination_id)

WorkflowService->start_process()

   case list_ my_thread : 待處理的列表

       WorkflowService->list_ my_thread()

   case run_thread :

       參數:thread_id

       WorkflowService->run_thread(thread_id)

case save_thread :

    參數:thread_id

    input收集起來(全部的變量以 f_ 開頭),賦給WorkflowServiceInput,另外還要得到thread_id

    WorkflowService->save_thread(thread_id)

   case transit_thread :

   參數:thread_id

input收集起來,賦給WorkflowServiceInput,另外還要得到thread_id

$next_node_id = 獲得用戶選擇的下一結點id

WorkflowService-> transit _thread(thread_id$next_node_id)

 

   case list_my_process: 全部我發起的流程

case list_all_process: 全部我發起的流程

case view_process :

 

在其它程序中初始化流程

    1先自行創建好業務表單

2WorkflowService->init_process(defination_id)

3把建好的業務表單的ID放在processcontext裏面

4WorkflowService->init_thread(1)

WorkflowService->transit_thread(12) 經過手動調用把前面的流程過掉

外部服務繼續流轉流程(只用於自動流程)

input收集起來,賦給WorkflowServiceInput,另外還要得到thread_id

2 WorkflowService->run_thread(thread_id)

相關文章
相關標籤/搜索