搜索
首页php教程php手册介绍一个真正符合中国国情的工作流设计参考(包括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

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

发起人

发起人,用于显示自己的流程

process_id进程id defination_id流程id process_desc进程描述显示在我的工作台中context上下文存放上下文变量,例如业务表的idcurrent_node_index当前结点序号 start_time流程启动时间如遇分支、汇合显示为:1=》3,4=》3,5=》6finish_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已处理

thread_id

线程id

 


领导传阅


部门领导审批


填写表单


结束

process_id


放弃


提交


同意

进程id
 
process_desc 进程描述
node_id 结点id
node_name 结点名称  
执行人 执行人  
start_time 线程生成时间  
receive_time 线程接收时间  
finish_time 线程完成时间  
max_time 结点规定的最长时间  
状态 状态 0未接收 1已接收 2已处理
二、常见流程人工决策

领导传阅

部门领导肋


填写表单

结束

放弃

提交

同意


重填(退回)


不同意


完成

外部响应


发送支付信息



接收支付成功响应(外部WS触发该流程)

发送支付信息


接收支付成功响应(外部WS触发该流程)

三、PHP设计

运行的函数由结点在设计时候决定,如果没有设定,就使用默认的函数。利用了PHP语言的以下特性

<?php
class Foo
{
    function Variable()
    {
        $name = &#39;Bar&#39;;
        $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 回退

删除所有大于$next_node_idThread

}

init_thread($next_node_id)

Case 2: 自动处理

修改$thread为已完成

           If($next_node_id 回退

删除所有大于$next_node_idThread

}

       init _thread($next_node_id)

Case 3: 等待外部响应

    修改$thread为已完成

           If($next_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)通过手动调用把前面的流程过掉

外部服务继续流转流程(只用于自动流程)

1 input收集起来,赋给WorkflowServiceInput,另外还要获得thread_id

2 WorkflowService->run_thread(thread_id)

相关文章:

PHP 工作流 自定义表单解决方案

怎么简单实现工作流?

通达OA2015版工作流插件和列表控件数据解析

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

SublimeText3 英文版

SublimeText3 英文版

推荐:为Win版本,支持代码提示!

Dreamweaver Mac版

Dreamweaver Mac版

视觉化网页开发工具

螳螂BT

螳螂BT

Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具