工作流数据库设计
function Bar(){ echo "This is Bar";
} } $foo = new Foo(); $funcname = "Variable"; $foo-> $funcname(); // This calls $foo->Variable() ?>
使用前可以用 method_exists 来检查。
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_ 开头),赋给 WorkflowService 的 Input,另外还要获 得 thread_id WorkflowService->save_thread(thread_id); case transit_thread : 参数:thread_id 把 input 收集起来,赋给 WorkflowService 的 Input,另外还要获得 thread_id $next_node_id = 得到用户选择的下一结点 id WorkflowService-> transit _thread(thread_id,$next_node_id);
tbl_workflow_process :流程执行进程表
process_id
进程 id
defination_id
流程 id
process_desc
进程描述
context
上下文
current_node_index 当前结点序号
start_time
流程启动时间
finish_time state start_user
流程完成时间 状态 发起人
显示在我的工作台中 存放上下文变量,例如业务表的 id
如遇分支、汇合显示为: 1=》3,4=》3,5=》6
1 运行 2 结束 发起人,用于显示自己的流程
tbl_workflow_thread :流程执行线程表
thread_id
线程 id
process_id
进程 id
process_desc
next_node_index
流程初始函数 流程运行函数 流程保存函数 流程流转函数 前结点序号
后结点序号
结点的 step
1 人为决策,2 自动处理(直接执行 execute_function),3 等待外部响应(例如外部 WS 触发),4 分支,5 汇总 6 结束结点(此结点 执行时候自动终止进程)
进程描述
node_id
结点 id
node_name
结点名称
executor
执行人
start_time
线程生成时间
receive_time
线程接收时间
finish_time
线程完成时间
max_time
结点规定的最长时间
state
状态
0 未接收 1 已接收 2 已处理
二、常见流程 人工决策 领导传阅
部门领导审批
}
end_process();
list_my_process view_process
workflow_proposal_handler.php WorkflowProposalHandler
start() prepare_input() 准备用户输入变量,从$_POST 收集 init_function () 线程建立后调用的默认函数,当流程的执行者由程序生成时,在此函数内 更改$thread 的 executor,例如直接赋值 user[2] run_function () 线程运行化时候调用的默认函数 save_function () 保存运行信息 transit_function () 执行流转 sendmail 其它结点调用函数
填写表单
结束
放弃
提交
同意
重填(退回)
不同意
完成
外部响应
发送支付信息
接收支付成功响应(外部 WS 触发该流程)
三、PHP 设计 运行的函数由结点在设计时候决定,如果没有设定,就使用默认的函数。利用了 PHP 语言 的以下特性 <?php class Foo{
function Variable() { $name = 'Bar'; $this->$name(); / / This calls the Bar() method }
WorkflowService.php WorkflowService
$defination $process $node $thread $input 用户输入的和流程有关的变量 list_defination(){ } init_process(defination_id){ global user; 取得$defination,得到业务的 handler,例如 WorkflowProposalHandler
Case 2: 自动处理 建立$thread WorkflowProposalHandler-> init_function ($process,$node,$thread) 调用 run_thread(thread_id)
Case 3: 等待外部响应 建立$thread WorkflowProposalHandler-> init_function ($process,$node,$thread)
例如 1。开始结点没有 执行前,通过此来校验一下流程 例如[同意]3,[不同意]4。尾结点或要结束的结 点没有,若没有,直接调用 end
executor
execute_type remind field max_day
执行角色,组,人
执行类型 提醒 可编辑的字段 最长时间(天)
role[1,2] group[1,2] user[1,2],为 空由 运行 时决 定 0 需所有人执行 1 只需一人执行 0 不提醒 1 邮件 2 短信 3 邮件和短信 name,content
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 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
tbl_workflow_defination:工作流定义表
defination_id
流程 id
defination_name
流程名称
defination_handler 流程处理辅助文件,每 自 定 义 处 理 文 件 , 及 其 对 象 。 例 如
个工作流一个文件 workflow-proporsal-handler.php,其中定义对象
取得$process 取得$thread
Switch($node[‘node_type’]) Case 1: 人工决策
WorkflowProposalHandler->transit_function($process,$node,$thread,$next_node_id) 修改$thread 为已完成