1、二十六 .net工作流系统之扩展性.net工作流系统之扩展性最近为用户做工作流实施时,都无一例外的提出工作流系统的扩展性问题。事件一:eworkflow工作流系统预置了一些系统的条件,前置后置函数等。如果这些不能满足业务需要,用户需要定制自己的业务规则,业务过程,该如何做?解决方案:eworkflow系统预置了很多系统的条件类,前置后置函数类。简单一些的业务规则,可以直接用自定义脚本,写个表达式的方式来实现。如条件类的:判断用户是否有某个角色 .fcsoft.workflow.util.UserHasRoleCondition 判断是否是竞争型任务的签收人 .fcsoft.workflow.u
2、til.CompetitionTaskCondition . 事件类:将指定步骤的执行人保存到mostRecentCaller变量中 .fcsoft.workflow.util.MostRecentCaller . 打开我们的任意一个条件类 ,可以看到,条件类必须实现Condition接口,实现passesCondition()方法/ 判断调用者caller是否属于role参数所指的角色/ caller: userid role: roleid/ public class UserHasRoleCondition : Condition/ Methods /public virtual boo
3、l passesCondition(System.Collections.IDictionary transientVars, System.Collections.IDictionary args, PropertySet ps) . 流程的上下文、相关的业务参数、数据库连接、当前操作员id等,均可以在passesCondition的三个参数中获得。因 此在需要扩展业务规则的时候,可以扩展这种条件类,只需要在用户的应用系统中引用eworkflow.dll(java版的就是引入 eworkflow.jar),新建业务规则类,实现Condition接口,在passesCondition方法中写业
4、务规则就可以了,所有和流程相 关的信息,节点定义的属性,业务参数,均可以从passesCondition方法的三个参数中获得。将写好的条件类注册到 WF_DSN_CLASS表中,在流程定义的时候,从节点的属性页中选择出这些扩展的业务规则,挂接到流程的节点上。在流程实例运行到此节点的时候,就会执行这些节点上定义的业务规则类,作出规则判断。 下面是一个判断 当前操作员用户,是否属于某个区域的业务规则的判断-条件和事件的分隔线- 打开任意一个事件函数类,可以看到,事件函数类的,必须实现FunctionProvider接口,实现execute()方法 public class MostRecentCa
5、ller : FunctionProvider/ Methods /public virtual void execute(System.Collections.IDictionary transientVars, System.Collections.IDictionary args, PropertySet ps)和条件类的接口一样,流程的上下文、相关的业务参数、数据库连接、当前操作员id等,均可以在execute的三个参数中获得。集成开发文档中会有这三个参数的详细描述。在 需要扩展业务事件,业务过程的时候,只需要在用户的应用系统中引用eworkflow项目或者eworkflow.dll(
6、(java版的就是引入 eworkflow.jar),新建这种事件类,实现FunctionProvider接口,在execute()方法中写业务实现,所有和流程相关的信 息,节点定义的属性,业务参数,均可以从execute方法的三个参数中获得。将写好的类注册到 WF_DSN_CLASS 表中,在流程定义的时候,从节点的属性页中选择出这些扩展的业务事件类,挂接到流程上。这样流程实例运行的时候,流转到相应的节点,就会执行节点上定义的这些业务事件。例如将当前操作员信息保存到流程的上下文中:事件二:我们的eworkflow工作流系统的 待办任务列表 只有流程相关的信息,业务信息部分较少,集成到用户系统
7、时,用户希望能自定义一些业务列信息。解决方案:eworkflow工作流系统的任务表中,任务名称,是支持表达式的,在表达式中可以引入业务信息。例如任务名称为:审核 业务部 李明 的报销单。 业务部 李明 这两个信息均来自表达式,获取的是报销单中的记录信息。如果这样还是不能满足用户的需要,用户需要扩展列出多列业务表中的记录值。那就只能通过调用流程的获取待办任务列表的api函数来做了。具体过程如下:先通过调用工作流的api函数,获取待办任务列表ArrayList getCurrentTasks(System.String type, System.String wfId, System.String
8、 stepId);得到的是一个list,list的每一条是对应一条任务表的一个 IDictionary对象(java版的就是map对象),任务表的字段名为key,记录值为value。任务表中会记录任务信息关联的流程实例id, 通过流程实例id获得 和业务表的关联,找到业务表的记录,然后取出业务表中的多列信息,和任务信息 一起返回到页面显示,这样就获得了一个 包含多列具体业务信息的待办任务列表了。标签: java工作流, 自定义工作流, web工作流, 工作流引擎, dotnet工作流引擎, .net工作流, .net工作流系统二十七 .net工作流系统集成自定义表单.net工作流系统集成自定义
9、表单工作流系统一般都包含工作流引擎,工作流引擎是对业务流程的抽象,是实现流程自动化的微内核,利用工作流引擎的基本元素能搭建出各种各样的流程,但仅限于流程,不涉及到业务实现。流程的每个节点上可以挂接需要处理的业务模块,例如一个简单的报销流程,如下图:在填写报销单的流程节点上,就可以挂接上 填写报销单 这样一个业务模块;到审批的节点上,挂接 审批报销单模块。 工作流引擎是不负责这些具体业务模块的实现的,否则就不是对业务流程的抽象了。这些具体业务模块的实现,可以是开发人员做好的一些业务模块,也可以是用一些表单工具做的自定义业务表单。无论是定制的业务模块,还是利用表单工具做的自定义表单,都需要在这些模
10、块中集成流程。好的工作流引擎都应该是封装好的,对外仅提供调用的api函数。这样才能方便的将流程与业务模块集成在一起。工作流引擎对外提供的api应该包含:流程的初始化函数:给定一个具体的业务流程名称,启动流程,获得一个流程实例id.流程的执行函数 :给定一个具体的流程实例id, 执行他的任务,使得流程递进,达到流程的流转。获得与修改流程实例的状态:获得与修改一个具体流程实例的状态。指流程实例的 激活,挂起,与 完成 等状态。获得流程定义任意节点的信息:获得指定流程指定节点的任务信息,包括流程定义的属性,自定义信息等等。在业务模块中,嵌入流程引擎的api函数的调用,启动一个流程,或 通过给定的流程
11、实例id,去执行它的当前任务,将当前任务提交,使得流程流转。当然,业务模块的业务数据提交和流程的流转应该保持在一个事务中,达到流程的长事务一致性。下面以+为例,说明.net工作流系统与自定义表单系统的集成。还是以报销流程为例,先将业务流程转换成eworkflow的流程。(流程图如上图中简单报销流程)再设计好业务表,这里我们设计了两张表,报销主表和明细表。从上面的流程中可以看出,需要有报销单填写模块,和审核模块。用eform画好 报销单,如下:注:eworkflow .net工作流系统中已经集成好了eform .net自定义表单系统了。表单属性中 选择 工作流工具栏工作流工具栏也是用eform设
12、计的一个页面,此页面中已经做好了和流程的集成。在表单提交到后台保存的之后,再执行流程的相应动作,达到流程的递进。用eform画好 报销单的审核 如下:(同样在表单属性中,选择 工作流工具栏)画好的页面保存在workflowexample_dj目录中。在流程设计器中,打开报销流程,在相应节点上挂接好 业务表单。这样报销流程就设计好了,可以启动执行了。有更细一些的控制,就在流程设计器中打开报销流程,修改流程节点的属性,或修改流程的流转。在eform自定义表单系统的代码中已经有通用的模块集成了eworkflow .net工作流系统了,所以不需要再写代码调用流程api了。二十八 工作流系统实例演练工作
13、流系统实例演练有了工作流引擎,工作流设计器,工作流管理平台,自定义表单,然后业务流程确定之后,就可以快速的做好能运行的流程了。首先业务要确定,包括业务细节部分。以一个 问题跟踪流程为例,实战演练一下,如何快速的搭建一个可以运行的业务流程。业务需求:用户在使用 我们公司的产品时,经常会遇到一些问题,有的是不会使用的问题,有的是误解,有的是bug,也有的是对产品的建议等等。我们拟收集这些用户遇到的问题以及处理过程,所以设计如下流程:流程如上面过程,具体的细节要求:1、相关人员审核问题,通过则发送到技术人员解决问题,拒绝,则表示问题描述不够,打回原填写人继续填写。2、原填写人收到打回的问题,可以继续
14、完善,再次发送给审核,也可以直接作废问题,结束这次问题描述。3、技术人员解决问题,有个锁定问题的过程,即谁先锁定了问题,就由谁解决。4、解决的问题反馈给用户,用户查看处理结果,无异议则结束流程,也可以继续提出疑问,和技术人员继续沟通解决。分析需求:根据上面的需求描述,设计问题跟踪表如下:根据业务过程和表,得出,至少需要设计三张表单:用户提出问题表单技术人员处理问题表单反馈给用户时的,用户查看和继续提出疑问的表单流程设计过程:根据上面的业务流程:用户提出问题审核部门审核问题技术解决问题反馈给用户结束可以看出整个业务流程分为,4个环节,提出问题审核解决问题反馈所以用eworkflow的流程设计器,
15、新建一流程,流程属性页设置业务标签页面填写 问题跟踪表名 和主键字段名.然后画出,初始化动作。和4个步骤,每个步骤均带上动作。用连线连接好。流程的雏形就画好了,可以先保存一下。再根据流程的细节要求,细化每个节点的属性,业务流程如下:细化的过程:节点名称的修改拒绝后打回的动作结果连线,此连线为有条件结果,条件为业务表单中传来的通过还是拒绝的选项。因为表单还未制作,自定义条件中,可以先设置false,如这样设置false打回后的问题,可以直接作废的动作有条件结果连线,条件为业务表单中传来的 是否作废的 选择。表单未制作,自定义条件中,先设置成false设置任务信息:提出问题步骤,设置直接指派的任务
16、; 审核步骤:设置直接指派任务,任务参与人为相关的审核部门人员。 解决问题步骤:设置竞争型任务,任务执行人为技术部门的人员。 问题反馈步骤:设置直接指派任务,任务执行人为问题的填写人。注意:步骤动作设置完任务节点,再在步骤的动作中,选择相对应的动作条件。即:直接指派型任务 选择 判断直接指派任务的执行人竞争型任务 选择 判断竞争型任务的签收人动态会签型任务 选择 动态会签任务的可执行人判断条件平均分配型任务 选择 判断平均分配型任务的签收人问题反馈步骤,继续提出问题,返回的有条件结果连线的设置,以及条件脚本的设置。先设置成false,待表单制作好后,再将条件填上。审核步骤拒绝时,打回原填写人继
17、续填写的设置,问题反馈步骤,返回给问题的提出人查看处理结果。业务流程设计完成。业务表单的设计:将业务表建立。新建业务表单,拉下数据集,拉下grid控件。在数据集中添加好业务字段。拉下label控件,text控件,combox控件,将数据集中的字段,绑定到这些控件。业务表单的属性页中,设置好表单名称,引入工作流工具条。保存。则问题填写表单制作完成。细节的设置,因为审核步骤用的表单,和填写 是同一张表单,所以,审核 是否通过等信息,需要设置控件权限,在填写步骤不可见;审核的结果,作为条件送到流程中使用,则数据集中 审核结果字段,需要选择 流程用。是否作废的结果,作为条件送到流程中使用,数据集上问题
18、状态 字段,设置为 流程用。问题处理表单的设计:将表单挂接到流程节点上:打开流程:在相应动作节点属性页上,设置业务表单。再次设置条件结果,打开流程,在相应的动作有条件结果上修改条件。保存。整个流程设计完成,流程就可以运行了,当然之前的保存的业务流程也能运行,只是有些细节没有体现。在工作流管理平台,登录,找到流程,启动流程,就可以跑这个完整的业务流程了。启动一个流程实例,做一个登记,查看一下此流程运行的轨迹,运行到 审核步骤了。换成 审核部门的人员登录,从我的待办任务中,找到任务连接,审核通过,则提交到技术部门。技术部门处理问题,反馈给用户,直到问题关闭,结束一个流程实例。.对流程设计器,efo
19、rm表单熟悉的话,业务流程细节又很确定,最多2小时,就能完成这样一个能运行的业务流程了。当然需求是不断变化的,我们利用eworkflow+eform的设计也可以是不断变化的。在测试运行阶段,随时可以调整流程,随时可以调整业务表单;在正式运行后,可以通过流程版本的控制,随时调整需求,随时调整流程,随时随地的调整业务表单。二十九 详解工作流实例的一次流转通常在利用流程设计器给业务流程建模之后,会生成一个流程描述的xml文件,业务流程的每个环节步骤,需要执行的操作,自动的,手动的等等信息,都 被描述在这个流程建模的xml文件中。xml文件的内容,是一些规则的预先定义的抽象的节点信息,流程引擎负责这些
20、节点的定义,创建,解释,定位等等,业 务流程利用这些节点建模。建模完成的业务流程,挂接上业务表单后,就可以直接运行业务流程了。业务流程的运行,从启动流程实例开始,启动一个流程实例即代表开始了一次业务流程处理。每例业务流程的处理过程,都包含从创建,到激活,到处理,到 结束(当然中间也可以人为的直接终止,或挂起,再恢复),这样一个过程。流程实例创建后,就按照流程建模的xml文件,按照定义的节点路由顺序一步一步的 流转,相应业务也在相应的步骤中处理。流程实例按照节点路由顺序,每执行一次,代表一次流转。每次的流转包含流程节点的状态升迁和办理业务数据的提交,通过工作流的事务,控制这些状态升迁和业务数据达
21、到同步和一致性。一旦这个流程实例结束了或意外终止了,都代表业务办理完成了,就再也不能再次发生流转了。工作流实例的一次流转,会涉及到流程节点状态的升迁和办理业务数据的提交。下面示意图,抽取流程一次流转的定义示意:从步骤A环节到达步骤B当流程实例到达步骤A的时候,当前流程实例的状态步骤A步骤A的状态,当执行动作A的时候,通过 动作A的 结果导向 步骤B。当到达步骤B的时候,当前流程实例的状态步骤B 步骤B的状态。流程实例的状态通过执行动作A达到了升迁,当在动作A上面绑定了业务表单,业务数据也随着动作A的执行一起提交。业务数据的提交和流程状态 的升迁是在同一个事务中的,保证数据的一致性。从上面的分析
22、可以看出,流程的一次流转涉及到如下图中红色框中选中的部分。为什么步骤A和步骤B会分别是一半呢,下面我们来详细说明,流转过程中,每个流程基本元素的流转顺序。在工作流系统的基本元素中,有一些前置后置函数,可以挂接到流程的节点上。当流程实例到达这个节点的时候,会触发前置函数,离开这个节点会 触发后置函数,就象事件一样。事件的内容是可以自己任意发挥的,就像一个button的点击函数一样,点击后做什么事情,有编写程序的人来编写代码。这里 的前置后置函数也是一样,当触发了前置后置函数后,内容可以是预置的一些系统函数,也可以是业务流程建模者自定义做的一些业务模块,体现流程的扩展性。上图中只描述了动作的前置后
23、置,步骤的前置后置,实际上动作的结果,也有前置后置函数,便于做扩展用。实际上可以引入业务模块的不仅是前置后置函 数,动作的可执行条件也可以引入业务规则的判断。例如一个请假的流程,在审核请假是否通过时,可以引入一个判断规则,将请假申请人的总年假已经休的假 期可休年假天数,再和当前申请的天数比较,如果大于则申请通过,否则不通过。综合上面的描述,我们可以看出流程的一次流转的先后顺序为:步骤的后置函数动作的前置函数完成本步骤的任务检查动作结果中的条件(不成立则无条件结果)动作结果的前置创建新的当前步骤(执行新步骤的前置函数) 动作结果的后置 动作的后置函数因为执行动作后,会离开本步骤,所以首先是从本步
24、骤的后置函数开始的。其中,创建新的当前步骤,关联到任务信息,所以也有个处理过程顺序:本步骤标记完成,转到历史步骤下一步为当前步骤关闭当前步骤的所有未完成的任务到达新步骤,先生成新步骤的所有任务再执行新的当前步骤的前置函数。业务流程在建模的时候,可以利用一些流程的上下文中的变量等做一些控制,也可以引入一些关键的业务数据做判断用。这涉及到流程的持久变量和临时变量。例如,获取当前流程实例的创建者,作为一个变量,传递给接下来的第一个步骤作为第一个步骤任务的参与者。这可以用一个流程的临时变量来处理:在流程初始化动作(或动作结果)的前置函数中,将当前流程实例的创建者保存到变量caller中。然后在下一步骤
25、的任务参与人中,就可以引入caller变量,获取他的值了。因为caller变量是个临时变量,仅存在于流程的一次流转的中。当流程的这次流转结束了,这个变量就实效了。就像一个子函数一样,在子函数的开始,给变量caller赋值,在接下来的代码中就可以获取这个变量的值了。 所以在用流程的临时变量时候,通常都是在相应节点的前置函数中,给变量赋值,按照流程的流转顺序,在相应的后置节点中获取变量的值。同样的方式还适用于mostRecentCaller,mostRecentOwner 这两个变量,获取指定步骤的执行者和获取指定步骤的所有者,这两个变量都属于发生了的历史步骤才能获取到。流程的持久化变量,就与临时
26、变量不一样了,只要流程的任意节点中保存了值,在后续的任意节点中都可以获取到值。这个不局限于流程的一次流转,流程多次流转都可以。只要在任意一次流转中保存了变量的值了,后续的任意流转中就都可以取值了。例如一个报销流程中,报销申请是否通过,审核人将这个结果作为一个持久化的变量保存到流程中了。则在申请人查看审核结果的环节,就可以取出这个审核 结果了。审核的那次流转,和查看环节,这是流程的两个环节。不是流程的一次流转,但是审核的那次流转,必须先于查看环节,先将变量的值持久化进去,然后后 续的环节就能获取值了。三十 流程的静态分支与动态分支业务流程的流转过程中,经常会有需要并发处理的过程,即流程流转到下一
27、步,同时产生多个 当前需要处理的过程,这些过程不分先后处理顺序,只要都处理完成了,最后汇聚到一起,再接着主流程运行,就可以了。例如:一份报销单,填写完成后,同时启 动财务部门审核和本部门的审核,这两部分的审核不分先后顺序,只要都完成后,再将结果返回给报销单填写人,继续下面的流转。这种的并行处理的过程,就需要 流程引擎支持分支和聚合。分支又分为 静态的分支 和动态的分支。静态的分支,即在业务流程建模之初,就能确定好有多少个分支,每个分支的具体流转,具体处理过程。动态的分支,即在业务流程建模的时候,只能确定好一条分支的模版处理过程,在流程实例运行时,每流程实例根据自己的情况确定本次能产生多少个分支
28、,然后依据分支模版的处理过程,复制出n个并发的分支线路,每分支线路的运行轨迹根据动态分支参数的设置而不尽相同。聚合也分为 静态聚合 和 动态聚合静态聚合,和静态分支匹配,当有静态的分支并发流转发生后,需要用静态聚合来汇聚并发的线路。动态聚合,和动态分支匹配,当有动态的分支并发流转发生后,需要用动态聚合来汇聚并发的线路。静态分支模式:动态分支模式:静态分支里面可以嵌套 静态分支:动态分支里面也可以嵌套 动态分支:静态分支里面可以嵌套 动态分支 (暂未做示例)动态分支里面也可以嵌套 静态分支:注意:静态分支,必须用静态聚合来汇聚, 动态分支必须用动态聚合来汇聚。 为了 方便 设置汇聚条件,分支嵌套
29、的时候,避免 内层聚合到外层聚合 的 这种流程建模方式,如果业务流程中,确实是内层聚合到外层聚合 的流转,那就增加一个 自动步骤的 节点。即 内层聚合自动步骤外层聚合。此自动步骤,带有自动执行的方法,当流程流转到这里时,会自动完成此步骤。静态分支后产生的并发流程,在流程建模时候,和普通的流程节点一样设计。动态分支后产生的并发流程,有些参数需要在流程实例运行时设置,如动态分支的个数,每分支的步骤执行人等等。动态分支节点,在流程建模时,先定义好需要那些参数,在分支模版节点中,引入这些参数。流程实例运行时,各流程实例根据实际情况给参数赋值,分支节点中遇到参数表达式,解释并得到参数值,参与到流程的流转中。参见 web工作流管理系统开发之二十 动态创建流程多分支节点
©2010-2024 宁波自信网络信息技术有限公司 版权所有
客服电话:4008-655-100 投诉/维权电话:4009-655-100