工作流概念
曾经在2001年做CRM产品的时候,因为CRM产品的客户状态升迁,每个具体用户的升迁规则可能会不一样,技术主管说要集成一个工作流软件工具......,那是我第一次听说工作流。当时很不理解,这工作流软件如何能做到将业务流程定义进去呢?当然,那时候工作流软件工具还不成熟和完善,也或者我们也没有达到那个层次,后来终究还是没有用上工作流。
工作流软件,顾名思义,就是业务信息数据在多个环节模块之间的流转。按照工作流管理联盟的定义,工作流指的是“业务过程的部分或全部在计算机应用环境下的自动化”。在实际应用过程中,为了实现对业务过程的工作流管理,需要对业务流程及其各个步骤之间业务规则的抽象,概括,做成一个统一通用的流程管理软件系统,这种软件系统就是工作流管理系统。
工作流管理系统的主要功能是通过计算机技术的支持去定义、执行和管理工作流,协调工作流执行过程工作之间以及群体成员之间的信息交互。工作流管理系统将业务流程中工作如何组织协调在一起的规则抽象出来,从而分离了具体工作的逻辑和流程组织的逻辑。实现对业务过程的抽象建模、业务过程仿真分析、业务过程优化、业务过程管理与集成。从而最终实现业务过程的流程自动化管理。
开发人员或者流程的应用人员遵从工作流管理系统的规则或约定,设计和实现具体的业务流程。
工作流系统结构图:
天蓝色蓝色:软件构件,完成工作流管理系统不同组成部分功能的实现;
黄色:系统控制数据,工作流管理系统中的一个或多个软件构件使用的数据;
棕色:应用与应用数据,对于工作流管理系统来说,它们不是工作流管理系统的组成部分,而是属于外部系统和数据,它们被工作流系统调用来完成整个和部分工作流管理的功能。
web工作流管理系统主要功能:
业务流程建模;
参与的用户,权限,角色设计;
工作流测试运行;
业务表单模块的建立;
流程发布运行;
流程管理和监控;
流程出错后的修复。
通常开发一个工作流管理系统主要包含如下几个部分:
工作流引擎开发
工作流定义工具
自定义表单模块
流程管理和监控
工作流引擎: 主要是实现业务流程的规则抽象,模型的建立,解释,以及为流程实例提供运行环境,并解释执行流程实例。
工作流定义工具:主要是实现工作流的描述文件的定义和建立,通过可视化的方式把复杂的流程定义以图形化的方式显示出来,并加以操作。
自定义模块:主要指自定义表单,实现业务模块的工具。
流程管理和监控:主要指组织机构、角色,流程实例等数据的维护管理和流程执行情况的监控;
工作流引擎
工作流引擎,主要是实现业务流程的规则抽象,模型的建立,解释,以及为流程实例提供运行环境,并解释执行流程实例。
工作流引擎必须要包含一个工作流模型的设计,工作流模型就是对业务流程抽象的一个模型,是整个工作流引擎的基础。所以模型设计的好坏决定引擎的功能是否灵活,也决定了工作流管理系统从设计实现到运行实施等诸多环节。
在信息管理自动化的环境下,工作流模型必须采用简单、直观、又具有较强描述能力的模型。我们公司的自定义工作流系统采用了有限状态机的数学模型来实现工作流模型,有限状态机(FSM)又称为有限状态自动机或简称状态机,是表示有限个状态以及这些状态之间的转移和动作等行为的数学模型。
状态转换图:
上图左数第一个图:为初始状态,用粗线圈表示;
SX,S0,S01,S011,S0110 为状态名称
U=0表示处于该状态的输入
连线箭头上的0或1表示导入状态转换时的输入
工作流模型正是利用这种状态和动作,动作的结果导致状态的转移来达到流程的流转。
工作流引擎的每一种状态(state)被描述成为一个步骤(step)和步骤的状态(status)。工作流实例从一种状态(state)升迁到另外一种状态是通过执行动作(action)来达到的,动作的结果(result)导向另外一种状态(state),这样达到流程的流转。在一个工作流实例的生命周期内通常有一个或者多个活动的状态(state)。这些简单的思想表现在工作流引擎的核心包里面,并且通过一个简单的XML文件来描述业务工作流程。
一个简单的流程描述xml文件是这样的:
上图xml流程的图解状态过程如下:开始节点-》初始化动作--》步骤节点-》动作节点--》结束
工作流引擎的基本元素:
步骤(step)
一个step描述的是工作流所处的位置。可能从一个step transtion到另外一个step,或者也可以在同一个step内流转(因为step可以通Status来细分,形成多个state)。一个流程里面可以有多个step。
状态(status)
状态status 是用来描述工作流程中具体step(步骤)状态的字符串。eWorkFlow中预置了三种步骤的状态
Underway(进行中)、Queued(等候处理中)、Finished(完成),用户可以任意扩展自己的状态。而工作流的状态state则是由step(步骤)+status(步骤的状态)组成的。工作流状态state的升迁来达到工作流实例的推进。
流转(transtion)
一个工作流实例状态state到另一个状态state的转移。
动作(action)
action 触发了发生在 step 内或 step 间的流转,或者说是基于 state 的流转。一个
step 里面可以有多个action。action 和step 之间的关系是,step 说明“在哪里”,action
说明“去哪里”。 一个 action 典型地由两部分组成:可以执行此action(动作)的condition(条件),以及执行此动作后的
result(结果)。
任务(task)
任务是当工作流状态发生转移的时候,产生的任务。任务可以指定为一个具体的角色,人,或者群组。任务具体,待办,已办,竞争办理,代理待办等多种功能。
条件(condition)
类似于逻辑判断,可包含“AND”和“OR”逻辑。比如一个请假流程中的“本部门审批阶段”,该阶段利用“AND”逻辑,判断流程状态是否为等候处理中,以及审批者是否为本部门主管。
结果(result)
Result 代表执行action(动作)后的结果,指向新的 step 及其 step status,也可能进入
split 或者 join。result 分为两种, contidional-result (有条件结果),只有条件为真时才使用该结果,和
unconditional-result(无条件结果),当条件不满足或没有条件时使用该结果。
分支/合并(split/join)
流程的分支和合并。分支是指流程下一步可以同时分发给多个步骤,分支split 提供多个unconditional-result(无条件结果);join
则判断多个current step 的状态提供一个 result(结果)。
子流程(subflow)
子流程,动作的结果可以指向一个子流程,子流程是一个独立的流程,可以单独启动也可以嵌套在另外的流程中启动,和主流程有同步或异步衔接的属性。
自由流 (free transtion)
自由流是指当一个步骤的动作执行完成后,需要跳转到任务的步骤。任意步骤,是指整个流程范围内的任意步骤,包含执行过的或未执行过的。
回退流(return transtion)
回退指当流程实例运行到某个步骤的时候,由于某些特殊原因需要回退到已经执行过的某个步骤上。回退是一种特殊的过程,只有在运行过程中才会明确指导要回退到那个步骤,回退往往需要执行业务补偿。回退和自由流不一样,会退会摸掉当前步骤到回退步骤之间的运行轨迹,就像初次运行到回退的步骤一样,同时需要辅助业务补偿来到达业务数据的回退。
工作流引擎核心包内,对这些基本元素做解释,并提供流程实例启动,动作执行,任务完成等等API,达到对业务流程的抽象。业务系统集成工作流后,做好业务流程建模,然后利用自定义表单做好相应业务数据的处理,将表单挂接到流程上。启动工作流系统,就可以实现业务系统了。
可视化流程设计器
在工作流管理系统中,引擎的所有的活动,驱动,和流转,都是以流程定义为基础而展开的。流程定义文件是流程能运行的先决条件,同时流程定义文件又是工作流引擎的设计基础,引擎必须要能生成,解释和获取到任意流程定义节点的信息。业务流程建模就是将一个具体的业务流程系统用流程定义文件来描述。而生成这个流程定义文件的可视化编辑工具就是流程设计器。
一般来说,只要是足够熟悉流程定义的各个步骤和节点的意义,流程描述文件可以用文本编辑器手动的输入来生成。但是这样做对用户的要求太高了。通常都会采用一个可视化的流程定义工具来实现。
工作流定义工具实现方式:
用java的图形界面包来实现:
生成一个java application,需要在客户端装jre,是c/s的应用,每个使用的客户端必须安装jre,安装这个可视化的编辑工具,这种方式根本不适合web管理系统的发布,每个客户端都需要安装,不理想;
用applet来实现:
这种方案虽然解决了每个使用的客户端安装程序的过程,但还是需要大量下载安装包,下载jre,也不是理想的实现方式。
用html+js+ajax来实现:
无须客户端安装,无须下载jre,只是第一次运行需要下载所有js的脚本,是理想的实现方式。
下面主要谈html+js+ajax的实现方式:
工作流流程定义,必须要图形化的实现流程的建模,使得流程建模变得简单和可操作,用户通过拖、拉、点、拽来实现流程的建模。
通过html和dhtml来实现界面的展示。
通过javascript和xml,dom分析实现动态的修改和编辑节点属性。
通过ajax来实现和后台的交互。
通过vml来实现图形化的操作,画线,画方框,拖动等等。
运用js, dhtml, xml, dom, vml 这些技术足可以将界面的编辑功能做得灵活简便,然后有ajax随时可以取得和后台交互,同时是web网页发布的,可以和应用程序一起集成发布,通过权限控制可以开放给最终端的用户使用。
一般来说流程定义文件的保存可以是保存成文件的形式,也可以保存到数据库的表中,因为采用ajax的方式来设计保存,这两种方式很容易都可以实现。同时通过文件方式的保存和数据库方式的保存,很容易做到流程的上传和下载,真是一举两得。
下面模拟一个业务流程建模工具操作界面:
前言:
osworkflow是个开源的工作流引擎,采用的是有限状态机的模型。内置有osuser这个用户系统,来处理用户权限相关的部分。但是功能很弱,只有用户表,用户组表,即简单的将用户划分给用户组。在定义流程的时候,可以将权限处理给一个具体的用户,也可以给一个用户组。
缺点:
功能太过简单,不利于扩展,也不利于和用户系统集成,还没有开源的源代码。
改造方案:
将osuser去掉,重新编写一套用户系统,此用户系统只在工作流系统中使用,因此数据权限等从简。
保留使用osuser.xml文件的配置,修改成fcuser.xml,此配置文件采用xml格式,配置具体执行和数据库交互的实现类,便于扩展各种数据库的个性化函数,sql,关键字的不同写法。
采用映射表的方式,和实际用户系统的表关联,因为用户系统要集成工作流,一般都有自己的用户组织机构管理系统。
工作流系统必须要和用户系统的用户权限系统无缝集成,所以没有必要再做一套用户系统,直接将用户系统的数据映射过来,达到集成的目的。如果不采用表数据的映射,也可以编写实现类,实现UserProvider接口,将用户系统已经有的方法关联过来实现。
用户映射表示意图:
表结构:
用户表,用户角色表,用户群组表
这几个表为演示系统使用,真正和用户系统集成的时候,采用映射表映射到用户系统的表。或者用户有自己编写好的用户权限等系统,也可以通过实现UserProvider接口的方式,将用户系统和工作流的用户系统集成到一起。
fcuser映射表:
一个简单的fcuser.xml映射表图例
cn.com.fcsoft.user.provider.jdbc.JDBCUserProvider
为UserProvider的指定实现类。
用户系统的UML图:
主要类功能描述:
UserManager为对外提供的用户系统的实现类,流程引擎实现类关联这个类,来实现用户系统的一切功能;
UserConfig为单例模式,主要读取fcuser.xml文件的内容
UserConfiguration获取映射表配置信息
UserProvider接口,提供所有的用户系统功能,实现类可以根据数据库的不同选择各自的个性化实现类,通用的为JDBCUserProvider。
用户不使用表结构映射时,可以编写自己的实现类,实现UserProvider接口来实现用户权限系统。
UserException,所有用户系统的抛出的异常。
User,UserImpl 用户接口,用户接口实现类
Role,RoleImpl 角色接口,角色接口实现类
Group,GroupImpl 用户群组,用户群组的实现类
通过改写这个用户系统集成到工作流引擎中,更利于和用户系统的结合。同时别忘记改写osworklfow的引擎包util中的各种和用户权限相关的类,调用userManage中的功能来做用户权限判断。
表单权限与流程的权限控制
在设计工作流系统的时候,常常会碰到这样的情况:
同一张表单需要在流程的多个环节中处理,且各环节的处理情况不一致,有的节点可写,有的节点之可读。
例如,同一张报销单:员工填写报销单时,只能填写报销单主体信息和明细部分,其它信息不可见;
经理审批时,只能填写审核结果和审核意见,报销单主体和明细部分只能查看;
财务审批时,报销单主体明细和经理审核信息都只能查看,只能设是否置领取费用的相关信息
这样就是同一张表单在流程的三个环节中流转,且各环节对表单的信息控制权限不一样。
处理过程:
1、在设计电子表单的时候,设置一张表单,包含报销单的所有的信息。并同时设置相关部分相关角色的权限。
员工--有填写报销单主体和明细信息的权限;
经理--有审核结果和审核意见的可写权限,报销单主体和明细信息只读的权限,财务的是否领取费用信息不可见;
财务人员--有是否领取费用信息的可写权限,其它所有信息只读;
2、设计流程的流转定义信息
设置流程的各个环节,以及流程个环节的动作,挂接上电子表单;
同时设置流程动作的权限;
员工填写动作--仅员工角色可执行;
经理审批动作--仅经理角色可执行;
财务审批动作--仅财务人员可执行;
3、启动流程,运行表单
当流程实例运行到填写报销单时候,仅员工角色可执行填写动作,打开表单,读取表单的权限控制,仅报销单主体和明细部分能填写。其它不可见;
流程实例流转到经理审批环节:经理角色能执行审批动作,打开表单,读取表单的权限控制,仅审批结果和审核意见可写,其它信息只读;
流转到财务审核环节;财务人员能执行审核动作,打开表单,读取表单的权限控制,仅是否领取费用信息可编辑,其它信息只读;
这样利用表单的权限控制和流程环节的权限控制相结合达到同一张表单在流程的多个环节中流转的效果。
问题:
如果有一个环节是员工查看报销单:即员工需要随时查看审核结果,此时只能查看,不再能修改报销单任何信息,且仍然是访问同一张表单。
利用上面的方法达不到这样的结果。
提示处理方案一:
员工随时查看审核结果,这种不应该设计为流程的一个环节,不是流程的环节,这种设计是错误的。应该设计一个查询的模块,输入查询条件去查询报销单,无论是进行的流程实例还是历史流程实例都可以查询出来,这样的方式去做到随时访问。
提示处理方案二:
如果业务需要,一张表单在第一个环节,同一用户可写,单据流转到后面的环节,即同一用户只可读的情况,则采用如下方法来处理:
1、在设计电子表单的时候,设置表单控件的可读和可写权限时,选择流程的环节动作,设置控件在流程的每个环节可读、可写、不可见等特性。设置完成后保存设置在表单中;
2、流程设计的时候,设置流程动作的权限,挂接好表单;
3、流程实例运行时,执行动作,装入电子表单,表单初始化的时候,装入控件的权限配置信息;校验其控件的权限,初始化控件的属性。达到只读、可写、不可见等特性;
开源osworkflow之任务管理
前言:
osworkflow的任务管理很简单,没有专门的任务表,也没有待办,已办,发出,处理任务等等。
只有很简单的查询用户可处理的动作和已经处理过的历史步骤。(注意这里只是可处理的动作和已经处理过的历史步骤,都不是任务)
这显然距任务管理差很多很多。
改造方案:
增加任务表,记录任务的相关属性,可执行人,任务处理人,任务发出时间,完成时间等。
流程定义模版文件中增加任务节点,定义任务的名称,从流程上下文中获取任务的内容和相关属性,定义任务的可执行人。
将产生任务记录和处理关闭任务的过程嵌入到工作流引擎的动作执行函数中。
当流程到达步骤后,根据流程定义模版文件中定义的任务节点,产生任务记录;
当动作执行时,检查任务是否可以执行完成,关闭任务。
因为单独出一张任务表,所以可以增加对任务的管理,查询得出待办任务列表,已办任务列表,做代理待办,催办,逾期未办等等的处理。
可以做到的任务管理:任务发起,待办,已办,催办,督办,收回等等。
任务表结构:
流程定义节点:
<tasks> <task name="审核员工:${oCaller.name} 的请假申请" classname="cn.com.fcsoft.workflow.util.MakeTask"> <arg name="taskDesc">内容:${remark}</arg> <arg name="rolename">部门经理</arg> <arg name="stepId">5110</arg> <arg name="role">ROL_0000003</arg> </task> </tasks> |
增加生成任务的类MakeTask:
增加descriptor中的任务定义类,并在相应的检查校验中增加对任务节点的校验:
总结:
通过增加任务,将任务的生成与处理嵌入到流程引擎中,任务的产生与完成跟流程的运行密切相关,在流程运行时会生成相应的任务,实例递进时完成相应的任务。同时任务记录单独抽出生成一张表,又可以很容易的做待办,已办,催办等等和任务相关的管理。
原来osworkflow是从流程引擎的核心表中去查太麻烦了,也很不灵活,功能太过简单,也不利于扩展。
|