文章来源:http://blog.csdn.net/danny_xcz/archive/2007/10/15/1824947.aspx
Tags: 工作流工作流
2007-10-22 16:51:16 | 编辑
一个真正符合中国国情的工作流设计参考(包括PHP实现)
开源的工作流很少有让人满意的,即便是国内用的比较多的jbpm,用起来也会觉得很便扭。再加上PHP中没有什么好用的工作流,于是干脆自己设计一个,设计的原则如下:
1 根据80/20原则,只使用wfmc模型中最符合自身应用的20%功能
2 充分吸收国内使用jbpm开发BOSS中遇到的问题,工作流引擎只负责参数的收集和流程的流转,具体和业务的控制,交给每个流程定制的控制类去实现。
3 表单采用简单的html+控制标签的方法实现
4 权限和模板引擎,以及其它辅助函数直接使用办公系统自带的框架
5 充分利用PHP语言的特点,流程设计是基于数据库的,程序上使用OO设计,但采用重对象的方法
6 不把可视化设计流程的工作交给最终客户,而且由设计时完成,因此不考虑流程版本更新的问题
一、工作流数据表设计
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已处理 |
二、常见流程
人工决策
领导传阅 部门领导审批 填写表单 结束 放弃 提交 同意 重填(退回) 不同意 完成
外部响应
发送支付信息 接收支付成功响应(外部WS触发该流程)
三、PHP设计
运行的函数由结点在设计时候决定,如果没有设定,就使用默认的函数。利用了PHP语言的以下特性
|
|
使用前可以用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: 等待外部响应