NetBPM工作流的一个示例-请假审批

本文介绍了一个基于NetBPM工作流引擎的请假审批流程示例,详细展示了processdefinition.xml和webinterface.xml的配置方法,以及关键动态委托类的设计思路。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 
  

NetBPM工作流的一个示例:请假审批

Made by LuBen:2007年8月12日


目录

请假流程描述

流程定义之processdefinition.xml

流程定义之webinterface.xml

流程定义之动态委托类

后记


流程定义包源码下载(注:par包就是zip格式压缩包)。原文地址:http://www.cnblogs.com/LuBen/archive/2007/08/11/852010.html(转载请保留)

请假流程描述

流程图:

 

假设:公司有两级领导,一级为主管(Chief),一级为老板(Boss),我们这里只是一个模拟,当然现实生活中情况比这个更加复杂;-)

描述:

  1. 在某公司中,部门员工休假需要主管(Chief)的批准。
  2. 如果休假天数大于10天,则 在部门主管同意后,还必须老板(Boss)批准。
  3. 如果是部门主管请假则直接提交老板批准。
  4. 在休假被批准之前,申请人可以撤销休假申请。
  5. 申请批准后,对休假天数进行修改(也可以是其他业务数据处理)。 每次休假申请结束之后,不管通过未通过或是否取消,都必须记录下来。
  6. 流程结束时,系统要把请假的结果信息Email给申请人。
  7. 对于大于10天的申请,如果部门主管已批准同意而上级主管还未批准,这时申请人撤销申请后,系统应发Email通知部门主管申请已撤销。
流程定义之processdefinition.xml

ContractedBlock.gif ExpandedBlockStart.gif processdefinition.xml
  1None.gif<?xml version="1.0"?>
  2None.gif<!-- NOTE:在定义流程时,建议先画出流程图,然后再来定义,这样思维清晰,也不易于出错
  3None.gif    关于processdefiniton.xml如何定义,请严格按照nPdl规定 -->
  4None.gif<process-definition>
  5None.gif
  6None.gif  <!-- =================================== -->
  7None.gif  <!-- == PROCESS DEFINITION PROPERTIES == -->
  8None.gif  <!-- =================================== -->  
  9None.gif  <name>请假DEMO</name>
 10None.gif  <description>该流程模拟公司的请假流程, Made By LuBen</description>
 11None.gif  <responsible>ae</responsible>
 12None.gif
 13None.gif  <!-- ====================== -->
 14None.gif  <!-- == START & ENDSTATE == -->
 15None.gif  <!-- ====================== -->
 16None.gif  <start-state name="start leave request">
 17None.gif    <description>提交请假单</description>
 18None.gif    <!-- 定义了role,引擎在该start-state节点执行时,就会把执行者信息赋值给角色对应的属性“requester” -->
 19None.gif    <role>requester</role>
 20None.gif    <!-- 在这里定义start-state的field,它表示该filed相关联的属性,并且在该state,它对属性的访问权利。
 21None.gif         如果需要定义其在web表单上的操作界面,如何进行web表单显示等,需要在webinterface.xml文件对应节点补充该field -->
 22None.gif    <field attribute="start date" access="write-only-required" />
 23None.gif    <field attribute="end date"   access="write-only-required" />
 24None.gif    <field attribute="leave days"    access="write-only-required" />
 25None.gif    <field attribute="comment"    access="write-only" />
 26None.gif    <transition to="Is Cancel Fork" />
 27None.gif  </start-state>
 28None.gif  
 29None.gif  <!-- 结束节点除名称外不要定义其他-->
 30None.gif  <end-state name="end" />
 31None.gif
 32None.gif
 33None.gif  <!-- ====================== -->
 34None.gif  <!-- ==      Actions     == -->
 35None.gif  <!-- ====================== -->
 36None.gif  <!-- 解释:这里定义process-definition节点的action,有效的事件类型为:process-instance-start, process-instance-end and process-instance-cancel -->
 37None.gif  
 38None.gif  <!-- 此处具体为:在流程结束的时候, 发送E-Mail消息给申请者,记录请假日志 -->    
 39None.gif  <action event="process-instance-end" 
 40None.gif        handler="NetBpm.Example.LeaveOfAbsence.EmailAction, NetBpm.Example.LeaveOfAbsence"   on-exception="log">
 41None.gif        <!--定义action参数,供委托类实例化类调用方法时获取使用。如这里的EmailAction的run方法发送邮件,需要知道发给谁,邮件标题等等,那么
 42None.gif            参数可以提供辅助-->
 43None.gif        <parameter name="to">previousActor</parameter>
 44None.gif        <parameter name="subject">您提交了请假申请</parameter>
 45None.gif        <parameter name="message">you requested a holiday from ${start date} to ${end date} with comment ${comment}</parameter>
 46None.gif      </action>
 47None.gif    <!-- 此处具体为:在流程结束的时候记录请假日志, 此处Log模拟 注意:每个节点可以定义多个action -->
 48None.gif    <action event="process-instance-end" 
 49None.gif        handler="NetBpm.Example.LeaveOfAbsence.LogLeaveInfoAction, NetBpm.Example.LeaveOfAbsence"   on-exception="log">
 50None.gif    <parameter name="LogInfo">记录请假日志? :) </parameter>
 51None.gif  </action>
 52None.gif
 53None.gif  <!-- ================ -->
 54None.gif  <!-- == ATTRIBUTES == -->
 55None.gif  <!-- ================ -->
 56None.gif  <!-- 解释:定义属性值及其序列化方式。属性值一般包括3类 -->
 57None.gif  <!-- one:角色对应的属性 -->
 58None.gif  <attribute name="requester" type="actor" />
 59None.gif  <attribute name="chief" type="actor" />
 60None.gif  <attribute name="boss" type="actor" />
 61None.gif  
 62None.gif  <!-- two:所有acitivity-state(包括start-state)处需要更新的属性,和用户表单内容对应 -->
 63None.gif  <attribute name="start date" type="date" />
 64None.gif  <attribute name="end date" type="date" />
 65None.gif  <attribute name="leave days" type="integer" />
 66None.gif  <attribute name="comment" type="text" initial-value="请假理由或者备注" />
 67None.gif  <attribute name="Chief evaluation result" type="evaluation" />
 68None.gif  <attribute name="Boss evaluation result" type="evaluation" />
 69None.gif  
 70None.gif  <!-- three:标识属性,该属性不会在web界面上体现,主来用来存储流程标识信息,供后面的逻辑处理使用 -->
 71None.gif  <!-- 该属性不会在界面上呈现, 在具体流程路径中被设置以决定Decide Which Action如何走 -->
 72None.gif  <attribute name="RunTrace" type="text" />
 73None.gif  <!-- 该属性不会在界面上呈现, 该属性被用来设置流程结束将要发送给用户的邮件信息(邮件标题, 如果需要邮件内容可扩展) -->
 74None.gif  <attribute name="ToUserEmailSubject" type="text" />
 75None.gif
 76None.gif  <!-- =========== -->
 77None.gif  <!-- == NODES == -->
 78None.gif  <!-- =========== -->
 79None.gif  <!-- 定义流程包含的所有节点 -->
 80None.gif
 81None.gif  <!-- 定义decision节点, 从decision可以流出多条边(transition),这些边可以目的地相同,也可以不同。
 82None.gif       如下面,虽然decision分出了3条供选择的边,但是边的目的地都是end节点,只是边的名称不同 -->
 83None.gif  <decision name="Decide Which Action" 
 84None.gif  handler="NetBpm.Example.LeaveOfAbsence.WhichWayDecision, NetBpm.Example.LeaveOfAbsence">
 85None.gif    <parameter name="attribute">RunTrace</parameter>
 86None.gif    <transition name="approve"    to="end">        
 87None.gif      <action event="transition" handler="NetBpm.Example.LeaveOfAbsence.AutoSetAttributesAction, NetBpm.Example.LeaveOfAbsence" on-exception="log">
 88None.gif       <parameter name="attribute">ToUserEmailSubject</parameter>
 89None.gif       <parameter name="setValue">您的请假申请已经被批准 holiday from ${start date} to ${end date} with comment ${comment}</parameter>        
 90None.gif      </action>
 91None.gif    </transition>
 92None.gif
 93None.gif    <transition name="disapprove" to="end" >        
 94None.gif      <action event="transition" handler="NetBpm.Example.LeaveOfAbsence.AutoSetAttributesAction, NetBpm.Example.LeaveOfAbsence" on-exception="log">
 95None.gif         <parameter name="attribute">ToUserEmailSubject</parameter>
 96None.gif         <parameter name="setValue">您的请假申请没有获得批准, holiday from ${start date} to ${end date} with comment ${comment}</parameter>
 97None.gif      </action>
 98None.gif    </transition>
 99None.gif
100None.gif    <transition name="requestercancel" to="end">    
101None.gif      <action event="transition" handler="NetBpm.Example.LeaveOfAbsence.AutoSetAttributesAction, NetBpm.Example.LeaveOfAbsence" on-exception="log">
102None.gif         <parameter name="attribute">ToUserEmailSubject</parameter>
103None.gif         <parameter name="setValue">您取消了请假申请, holiday from ${start date} to ${end date} with comment ${comment}</parameter>        
104None.gif      </action>
105None.gif      <!-- 请假人取消请假的时, 如果主管已经审批了, 则需要发邮件通知他 -->
106None.gif       <action event="transition" handler="NetBpm.Example.LeaveOfAbsence.EmailChiefAction, NetBpm.Example.LeaveOfAbsence" on-exception="log">
107None.gif        <!--- action的参数只能有3个, 切记切记, 调试的时候搞晕了-->
108None.gif        <parameter name="to">role(chief)</parameter>
109None.gif        <!--<parameter name="cancelMan">previousActor</parameter> -->
110None.gif        <parameter name="subject">请假申请被取消啦</parameter>
111None.gif        <parameter name="message"> requested a holiday from ${start date} to ${end date} with comment ${comment}</parameter>
112None.gif      </action>
113None.gif    </transition>    
114None.gif  </decision>  
115None.gif
116None.gif  
117None.gif  <!-- ====================== -->
118None.gif  <!-- == CONCURRENT BLOCK == -->
119None.gif  <!-- ====================== -->
120None.gif  <!-- 解释:定义并发块,concurrent-block一定包括一个fork,一个join,且边不可越出其界。concurrent-block是可以嵌套的 -->
121None.gif  <concurrent-block>
122None.gif    <!-- 定义fork,若没有定义forkhandler,那么其在fork flow时将按照默认行为执行 -->
123None.gif    <fork name="Is Cancel Fork">
124None.gif      <transition name="CancelLeaveRequest" to="Request Cancel" />
125None.gif      <transition name="evaluation" to="IsChiefDecision" />
126None.gif    </fork>
127None.gif    
128None.gif    <!-- 定义join,此处定义了joinhandler,则当有forked flow到达join时,将根据该委托判断是否要激活父flow,
129None.gif         若没有定义joinhandler,那么将按照默认行为(AndJoin委托类,也就是所有forked flow都汇聚到达Join才激活父flow)执行 -->
130None.gif    <join name="join before decided" handler="NetBpm.Example.LeaveOfAbsence.AnyOneJoin, NetBpm.Example.LeaveOfAbsence">
131None.gif      <transition to="Decide Which Action" />
132None.gif    </join>
133None.gif
134None.gif    <activity-state name="Request Cancel">
135None.gif      <description>在请假申请被最终审批前, 您可以在这里取消申请.</description>
136None.gif      <role>requester</role>
137None.gif      <!-- fields are optional. they limit the access to attributes in an activity -->
138None.gif      <field attribute="start date"        access="read-only" />
139None.gif      <field attribute="end date"          access="read-only" />
140None.gif
141None.gif        <!--eg。请假理由备注先不被看到    
142None.gif        <field attribute="leave days"    access="read-only" />
143None.gif        <field attribute="comment"             access="read-only" />
144None.gif        -->
145None.gif      <action event="perform-of-activity" handler="NetBpm.Example.LeaveOfAbsence.AutoSetAttributesAction, NetBpm.Example.LeaveOfAbsence" on-exception="log">
146None.gif        <parameter name="attribute">RunTrace</parameter>
147None.gif        <parameter name="setValue">requestercancel</parameter>
148None.gif      </action>
149None.gif      <transition to="join before decided" />
150None.gif    </activity-state>
151None.gif
152None.gif    <decision name="IsChiefDecision" handler="NetBpm.Example.LeaveOfAbsence.IsInRoleDecision, NetBpm.Example.LeaveOfAbsence">
153None.gif        <parameter name="checkrole">chief</parameter>
154None.gif        <transition name="isChief"    to="BossApprove" />
155None.gif        <transition name="isNotChief" to="ChiefApprove" />
156None.gif    </decision>
157None.gif
158None.gif    <activity-state name="ChiefApprove">
159None.gif      <description>您需要在这里对该请假单进行审批</description>
160None.gif      <assignment handler="NetBpm.Example.LeaveOfAbsence.AssignmentExpressionResolver, NetBpm.Example.LeaveOfAbsence">
161None.gif        <parameter name="expression" >role(requester)->group(hierarchy)->role(chief)</parameter>
162None.gif      </assignment>
163None.gif      <role>chief</role>    
164None.gif    <field attribute="requester"         access="read-only" />
165None.gif    <field attribute="start date"        access="read-only" />
166None.gif    <field attribute="end date"          access="read-only" />
167None.gif    <field attribute="Chief evaluation result" access="write-only" />
168None.gif      <action event="perform-of-activity" handler="NetBpm.Example.LeaveOfAbsence.EvluationResultAction, NetBpm.Example.LeaveOfAbsence" on-exception="log">
169None.gif        <parameter name="attribute">RunTrace</parameter>
170None.gif        <parameter name="setValueAttribute">Chief evaluation result</parameter>
171None.gif      </action>
172None.gif      <transition to="IsMoreTenDays" />
173None.gif    </activity-state>
174None.gif
175None.gif    <activity-state name="BossApprove">
176None.gif      <description>您需要在这里对该请假单进行审批</description>
177None.gif      <assignment handler="NetBpm.Example.LeaveOfAbsence.AssignmentExpressionResolver, NetBpm.Example.LeaveOfAbsence">
178None.gif        <parameter name="expression" >role(requester)->group(hierarchy)->role(boss)</parameter>
179None.gif      </assignment>
180None.gif      <role>boss</role>
181None.gif    <field attribute="requester"         access="read-only" />
182None.gif    <field attribute="chief"             access="read-only" />
183None.gif    <field attribute="start date"        access="read-only" />
184None.gif    <field attribute="end date"          access="read-only" />    
185None.gif    <!-- 理论上Boss不需要看到主管是否同意,因为不同意就不会到他这里来
186None.gif    <field attribute="leave days"    access="read-only" />
187None.gif    <field attribute="Chief evaluation result" access="read-only" /> 
188None.gif    -->
189None.gif    <field attribute="Boss evaluation result" access="write-only" />
190None.gif      <action event="perform-of-activity" handler="NetBpm.Example.LeaveOfAbsence.EvluationResultAction, NetBpm.Example.LeaveOfAbsence" on-exception="log">
191None.gif        <parameter name="attribute">RunTrace</parameter>
192None.gif        <parameter name="setValueAttribute">Boss evaluation result</parameter>
193None.gif      </action>
194None.gif      <transition to="join before decided" />
195None.gif    </activity-state>
196None.gif
197None.gif    <decision name="IsMoreTenDays" handler="NetBpm.Example.LeaveOfAbsence.IsMoreOrLessDecision, NetBpm.Example.LeaveOfAbsence">
198None.gif        <parameter name="attribute">leave days</parameter>
199None.gif        <parameter name="dividingDays">10</parameter>
200None.gif        <!--考虑扩展,形成对数值比较类的通用 <parameter name="datatype">float</parameter>        
201None.gif        <parameter name="compareType">More</parameter> -->
202None.gif        <transition name="IsMore"    to="BossApprove" />
203None.gif        <transition name="IsnotMore" to="join before decided" />
204None.gif    </decision>
205None.gif
206None.gif  </concurrent-block>
207None.gif  
208None.gif</process-definition>
209None.gif


流程定义之webinterface.xml

ContractedBlock.gif ExpandedBlockStart.gif webinterface.xml
  1None.gif<?xml version="1.0"?>
  2None.gif
  3None.gif<!-- 关于webinterface.xml如何定义,请严格按照nPdl规定
  4None.gif     只有需要人操作的节点, 也就是activity-state(包括StartState), 在该文件中才在需要进行定义,指定如何显示web表单等 -->
  5None.gif<web-interface>
  6None.gif  
  7None.gif  <!-- ==================== -->
  8None.gif  <!-- == PROCESS IMAGE  == -->
  9None.gif  <!-- ==================== -->
 10None.gif  <!-- 定义该流程的流程图片 -->
 11None.gif  <image name="web/leavedemo.gif" mime-type="image/gif" width="510" height="560" />
 12None.gif
 13None.gif  <!-- ================ -->
 14None.gif  <!-- == ACTIVITIES == -->
 15None.gif  <!-- ================ -->
 16None.gif  <activity-state name="start leave request">
 17None.gif    <!--定义该节点在流程图中的坐标-->
 18None.gif    <image-coordinates>
 19None.gif      <x1>285</x1>
 20None.gif      <y1>54</y1>
 21None.gif      <x2>307</x2>
 22None.gif      <y2>76</y2>
 23None.gif    </image-coordinates>
 24None.gif    <!--逐个定义该节点fields的web显示方式,htmlformatter是委托类,可以充分利用其委托类的特性-->
 25None.gif    <field attribute="start date">
 26None.gif      <name>开始时间</name>
 27None.gif      <description>在此处填写您想要在何时开始请假</description>
 28None.gif      <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.DateInput, NetBpm" >
 29None.gif        <parameter name="dateFormat">dd/MM/yyyy</parameter>
 30None.gif      </htmlformatter>
 31None.gif    </field>
 32None.gif    <field attribute="end date">
 33None.gif      <name>结束时间</name>
 34None.gif      <description>在此处填写您想要在何时结束请假</description>
 35None.gif      <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.DateInput, NetBpm" >
 36None.gif        <parameter name="dateFormat">dd/MM/yyyy</parameter>
 37None.gif      </htmlformatter>
 38None.gif    </field>
 39None.gif    <field attribute="leave days">
 40None.gif      <name>请假天数(单位:天)</name>
 41None.gif      <description>在此处填写您请假的天数(以后改进为系统自动计算)</description>
 42None.gif      <htmlformatter class="NetBpm.Example.LeaveOfAbsence.TextIntergerInput, NetBpm.Example.LeaveOfAbsence" >
 43None.gif      </htmlformatter>
 44None.gif    </field>
 45None.gif    <field attribute="comment">
 46None.gif      <name>请假理由</name>
 47None.gif      <description>在此处填写您请假的理由或者其他需要说明的信息</description>
 48None.gif      <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.TextAreaInput, NetBpm">
 49None.gif        <parameter name="rows">5</parameter>
 50None.gif        <parameter name="cols">20</parameter>
 51None.gif      </htmlformatter>
 52None.gif    </field>
 53None.gif  </activity-state>
 54None.gif
 55None.gif  <activity-state name="Request Cancel">
 56None.gif    <image-coordinates>
 57None.gif      <x1>287</x1>
 58None.gif      <y1>146</y1>
 59None.gif      <x2>420</x2>
 60None.gif      <y2>178</y2>
 61None.gif    </image-coordinates>
 62None.gif    <field attribute="start date">
 63None.gif      <name>开始时间</name>
 64None.gif      <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.DateLabel, NetBpm" >
 65None.gif        <parameter name="dateFormat">dd/MM/yyyy</parameter>
 66None.gif      </htmlformatter>
 67None.gif    </field>
 68None.gif    <field attribute="end date">
 69None.gif      <name>结束时间</name>
 70None.gif      <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.DateLabel, NetBpm" >
 71None.gif        <parameter name="dateFormat">dd/MM/yyyy</parameter>
 72None.gif      </htmlformatter>
 73None.gif    </field>
 74None.gif
 75None.gif  </activity-state>
 76None.gif
 77None.gif  <activity-state name="ChiefApprove">
 78None.gif    <image-coordinates>
 79None.gif      <x1>173</x1>
 80None.gif      <y1>220</y1>
 81None.gif      <x2>295</x2>
 82None.gif      <y2>253</y2>
 83None.gif    </image-coordinates>
 84None.gif    <field attribute="requester">
 85None.gif      <name>申请人</name>
 86None.gif      <description>提交请假申请的员工</description>
 87None.gif      <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.PersonLabel, NetBpm" />
 88None.gif    </field>
 89None.gif    <field attribute="start date">
 90None.gif      <name>开始时间</name>
 91None.gif      <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.DateLabel, NetBpm" >
 92None.gif        <parameter name="dateFormat">dd/MM/yyyy</parameter>
 93None.gif      </htmlformatter>
 94None.gif    </field>
 95None.gif    <field attribute="end date">
 96None.gif      <name>结束时间</name>
 97None.gif      <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.DateLabel, NetBpm" >
 98None.gif        <parameter name="dateFormat">dd/MM/yyyy</parameter>
 99None.gif      </htmlformatter>
100None.gif    </field>
101None.gif    <field attribute="Chief evaluation result">
102None.gif      <name>主管审批意见</name>
103None.gif      <description>请审批该员工的请假单</description>
104None.gif      <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.EvaluationInput" />
105None.gif    </field>
106None.gif  </activity-state>
107None.gif
108None.gif    <activity-state name="BossApprove">
109None.gif    <image-coordinates>
110None.gif      <x1>101</x1>
111None.gif      <y1>356</y1>
112None.gif      <x2>218</x2>
113None.gif      <y2>390</y2>
114None.gif    </image-coordinates>
115None.gif    <field attribute="requester">
116None.gif      <name>申请人</name>
117None.gif      <description>提交请假申请的员工</description>
118None.gif      <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.PersonLabel, NetBpm" />
119None.gif    </field>
120None.gif    <field attribute="chief">
121None.gif      <name>主管审批</name>
122None.gif      <description>同意该员工请假的主管领导</description>
123None.gif      <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.PersonLabel, NetBpm" />
124None.gif    </field>
125None.gif    <field attribute="start date">
126None.gif      <name>开始时间</name>
127None.gif      <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.DateLabel, NetBpm" >
128None.gif        <parameter name="dateFormat">dd/MM/yyyy</parameter>
129None.gif      </htmlformatter>
130None.gif    </field>
131None.gif    <field attribute="end date">
132None.gif      <name>结束时间</name>
133None.gif      <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.DateLabel, NetBpm" >
134None.gif        <parameter name="dateFormat">dd/MM/yyyy</parameter>
135None.gif      </htmlformatter>
136None.gif    </field>
137None.gif    <field attribute="Boss evaluation result">
138None.gif      <name>老板审批意见</name>
139None.gif      <description>该员工请假天数大于10天, 请您审批该员工的请假单</description>
140None.gif      <htmlformatter class="NetBpm.Workflow.Delegation.Impl.Htmlformatter.EvaluationInput" />
141None.gif    </field>
142None.gif  </activity-state> 
143None.gif</web-interface>
144None.gif

流程定义之动态委托类
        委托类包含在lib文件夹下的程序集中。因为委托类数目众多,这里仅贴出几个典型的委托类, 其源码工程若需要请看这里
 1. NetBpm.Example.LeaveOfAbsence.AutoSetAttributionsAction:该委托类设计为一个通用委托类,这里用来设置表识属性,如流程经过用户取消请假路径,则把RunTrace属性设置为requestercancel,供WhichWayDicision作判断用。
ContractedBlock.gif ExpandedBlockStart.gif AutoSetAttributesAction
 1None.gifusing System;
 2None.gifusing System.Collections;
 3None.gifusing log4net;
 4None.gifusing NetBpm.Workflow.Organisation;
 5None.gifusing NetBpm.Workflow.Delegation;
 6None.gifusing NetBpm.Workflow.Delegation.Impl;
 7None.gif
 8None.gifnamespace NetBpm.Example.LeaveOfAbsence
 9ExpandedBlockStart.gifContractedBlock.gifdot.gif{
10ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary> 
11InBlock.gif    /// 通用Action类, 改类用来设置属性, 把值(action参数setValue)设置给属性(action参数attribute)
12InBlock.gif    /// by Luben
13ExpandedSubBlockEnd.gif    /// </summary>

14InBlock.gif    public class AutoSetAttributesAction : IActionHandler
15ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
16InBlock.gif        private static readonly ILog log = LogManager.GetLogger(typeof(AutoSetAttributesAction));
17InBlock.gif        private static readonly AttributeExpressionResolver _attributeExpressionResolver;
18InBlock.gif
19InBlock.gif        static AutoSetAttributesAction()
20ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
21InBlock.gif            _attributeExpressionResolver = AttributeExpressionResolver.Instance;            
22ExpandedSubBlockEnd.gif        }

23InBlock.gif
24InBlock.gif        public void Run(IActionContext actionContext)
25ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
26InBlock.gif            IDictionary configuration = actionContext.GetConfiguration();
27InBlock.gif
28InBlock.gif            String setAttributeName = (String)configuration["attribute"];
29InBlock.gif            String setValue = (String)configuration["setValue"];
30InBlock.gif            setValue = _attributeExpressionResolver.ResolveAttributeExpression(setValue, actionContext);
31InBlock.gif
32InBlock.gif            actionContext.SetAttribute(setAttributeName, setValue);
33InBlock.gif            log.Info("设置属性" + setAttributeName + "的值为:" + setValue); 
34ExpandedSubBlockEnd.gif        }

35ExpandedSubBlockEnd.gif    }

36ExpandedBlockEnd.gif}

37None.gif
38None.gif
39None.gif

 2. NetBpm.Example.LeaveOfAbsence.AnyOneJoin: 该委托主要用来设置激活父flow机制,这里是只要任何一条路径到达了join,则激活父flow,流程往下流。
ContractedBlock.gif ExpandedBlockStart.gif AnyOneJoin
 1None.gifusing log4net;
 2None.gifusing NetBpm.Workflow.Execution.Impl;
 3None.gifusing System.Collections;
 4None.gifusing NetBpm.Workflow.Delegation;
 5None.gifusing Nullables;
 6None.gif
 7None.gifnamespace NetBpm.Example.LeaveOfAbsence
 8ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 9ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
10InBlock.gif    /// 只要任何一个Subflow到达了该Join, 就激活Parent flow
11InBlock.gif    /// by Luben
12ExpandedSubBlockEnd.gif    /// </summary>

13InBlock.gif    public class AnyOneJoin : IJoinHandler
14ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
15InBlock.gif        private static readonly ILog log = LogManager.GetLogger(typeof(AnyOneJoin));
16InBlock.gif
17InBlock.gif        public bool Join(IJoinContext joinContext)
18ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
19InBlock.gif            bool reactivateParent = true;
20InBlock.gif
21InBlock.gif            log.Debug("flow " + joinContext.GetFlow().Name + " is joining : " + reactivateParent);
22InBlock.gif
23InBlock.gif            // 取消其他并行的flow。这里存在一个同步问题,如果此时在flow的执行者正在performacitivity,那么要考虑flow的锁定
24InBlock.gif            IEnumerator iter = joinContext.GetOtherActiveConcurrentFlows().GetEnumerator();
25InBlock.gif            while (iter.MoveNext())
26ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
27InBlock.gif                FlowImpl concurrentFlow = (FlowImpl)iter.Current;
28InBlock.gif                concurrentFlow.ActorId = null;
29InBlock.gif                concurrentFlow.EndNullable = System.DateTime.Now;
30ExpandedSubBlockEnd.gif            }

31InBlock.gif
32InBlock.gif            return reactivateParent;
33ExpandedSubBlockEnd.gif        }

34ExpandedSubBlockEnd.gif    }

35ExpandedBlockEnd.gif}

36None.gif

 3. NetBpm.Example.LeaveOfAbsence.WhichWayDecision:该委托根据流程实际流过路径,根据标识属性RunTrace等进行走哪条边的抉择,如注释。

ContractedBlock.gif ExpandedBlockStart.gif WhichWayDecision
 1None.gifusing System;
 2None.gifusing NetBpm.Workflow.Delegation;
 3None.gif
 4None.gif
 5None.gifnamespace NetBpm.Example.LeaveOfAbsence
 6ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 7ExpandedSubBlockStart.gifContractedSubBlock.gif    /**//// <summary>
 8InBlock.gif    /// 根据流程走的路径,    
 9InBlock.gif    /// 1)“主管或者老板批准”-‘approve’:修改员工休假的总天数,设定发给用户E-Mail的信息。
10InBlock.gif    /// 2)“主管或者老板否决”-“disapprove”:设定发给用户E-Mail的信息。
11InBlock.gif    /// 3)“撤销”-"cancel"-设定发给用户E-Mail的信息。如果主管批准,要发给主管消息说明已经撤销。
12InBlock.gif    /// 判断走哪一条路
13InBlock.gif    /// by LuBen
14ExpandedSubBlockEnd.gif    /// </summary>

15InBlock.gif    public class WhichWayDecision : IDecisionHandler
16ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
17InBlock.gif        public String Decide(IDecisionContext decisionContext)
18ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
19InBlock.gif            // 默认为apprvoe
20InBlock.gif            String transitionName = "approve";           
21InBlock.gif
22InBlock.gif            // runtrace是表示属性,在前面的流过的路径action中被设置
23InBlock.gif            String runtrace = (String)decisionContext.GetAttribute("RunTrace");
24InBlock.gif
25InBlock.gif            if (runtrace.IndexOf("disapprove"!= -1)
26ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
27InBlock.gif                transitionName = "disapprove";
28ExpandedSubBlockEnd.gif            }

29InBlock.gif            else if (runtrace.Equals("requestercancel"))
30ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
31InBlock.gif                transitionName = "requestercancel";
32ExpandedSubBlockEnd.gif            }

33InBlock.gif            return transitionName;
34ExpandedSubBlockEnd.gif        }

35ExpandedSubBlockEnd.gif    }

36ExpandedBlockEnd.gif}

37None.gif
38None.gif

后记

    本文仅仅是一个示例,给大家提供一个运用nPdl定义NetBPM流程的参考,如果要把该流程投入现实中使用显然还需要做很多优化。该示例更多的是给大家展示流程定义中action可以定义多个, decision出来的transition可以到达同一条目的节点但名字却不一样等等. 示例中委托类的耦合性太高, 很多地方并不需要那样做, 如一个decision里面进行了2个判断: 判断是否大于10天, 判断是否审批同意, 这个完全可以拆分为两个独立的decision来做. 委托类设计成为高度可重用的, 耦合性低的通用类, 才是我们的目标.

    待写:NetBPM实现会签;NetBPM Q&A(不断更新)

转载于:https://www.cnblogs.com/LuBen/archive/2007/08/12/852010.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值