天天看點

綜合應用WPF/WCF/WF/LINQ之四:建立一個StateMachineWorkflow

這裡,我們将實作最為簡單的一種情況:員工提出申請,然後先由員工的上司審批,再由上司的上司審批,依次類推,直到公司最高上司。

  對于這樣的一個請假審批的流程,我們實作Workflow的實質在于,由Workflow來确定審批人和請假單的狀态。從這個角度來考慮問題,則問題将會清晰很多:每次Workflow運作時,我們需要設定該請假單的後續審批人和狀态。是以,我們可以将Workflow分成四種狀态:初始狀态,設定狀态,等待狀态和結束狀态。其中設定狀态用于設定該請假單的後續審批人和狀态,等待狀态則用于接受外部使用者的審批請求。

  下面我們将一步一步的實作這個Workflow:

  1、在Eallies.OA.Workflow.Interface項目中添加一個Interface,由于該Workflow需要與外部使用者互動,我們需要處理外部事件和調用外部方法。在Workflow中,處理外部事件和調用外部方法時,都需要指定一個Interface。

  在這個Interface中,我們需要添加LeaveApprove事件以及UpdateLeaveApproverByLeaveId和UpdateLeaveStatusByLeaveId方法,分别用于處理外部審批事件以及更新請假單審批人和狀态。

    1 using System;

    2 using System.Collections.Generic;

    3 using System.Linq;

    4 using System.Text;

    5 using System.Workflow.Activities;

    6 using Eallies.OA.Workflow.Args;

    7 using Eallies.OA.Info;

    8 using Eallies.OA.Info.Enum;

    9 

   10 namespace Eallies.OA.Workflow.Interface

   11 {

   12     [ExternalDataExchange]

   13     public interface ILeaveInterface

   14     {

   15         event EventHandler<LeaveArgs> LeaveApprove;

   16 

   17         void UpdateLeaveApproverByLeaveId(int leaveId, int leaveApprover);

   18         void UpdateLeaveStatusByLeaveId(int leaveId, LeaveStatusEnum leaveStatus);

   19     }

   20 }

  2、在Eallies.OA.Workflow.Args項目中添加一個Class項目,用于實作自定義的EventArgs。實作自定義的EventArgs的意義在于,在我們審批請假單時,需要傳入請假單的審批人和狀态等資訊,但一個事件隻能接受sender和e兩個參數,實作這個自定義的EventArgs後,我們就可以将無限量的參數通過e這個參數傳入了。

    6 using Eallies.OA.Info;

    7 using Eallies.OA.Info.Enum;

    8 

    9 namespace Eallies.OA.Workflow.Args

   10 {

   11     [Serializable]

   12     public class LeaveArgs : ExternalDataEventArgs

   13     {

   14         private LeaveApproveResultEnum _LeaveApproveResult;

   15         private EmployeeInfo _EmployeeInfo;

   17         public LeaveApproveResultEnum LeaveApproveResult

   18         {

   19             get { return this._LeaveApproveResult; }

   20             set { this._LeaveApproveResult = value; }

   21         }

   22 

   23         public EmployeeInfo EmployeeInfo

   24         {

   25             get { return this._EmployeeInfo; }

   26             set { this._EmployeeInfo = value; }

   27         }

   28 

   29         public LeaveArgs(Guid instanceId, LeaveApproveResultEnum leaveApproveResult, EmployeeInfo employeeInfo)

   30             : base(instanceId)

   31         {

   32             this._LeaveApproveResult = leaveApproveResult;

   33             this._EmployeeInfo = employeeInfo;

   34         }

   35     }

   36 }

  3、在Eallies.OA.Workflow項目下添加一個State Machine Workflow項目。

  4、進入該Workflow的背景代碼編輯界面,添加LeaveId、EmployeeInfo和LeaveApproveResult屬性,分别用于儲存請假單号、目前操作人資訊和稽核結果資訊。

    1         public Int32 LeaveId

    2         {

    3             get { return (Int32)GetValue(LeaveIdProperty); }

    4             set { SetValue(LeaveIdProperty, value); }

    5         }

    6 

    7         public static readonly DependencyProperty LeaveIdProperty =

    8             DependencyProperty.Register("LeaveId", typeof(Int32), typeof(LeaveWorkflow));

   10         public EmployeeInfo EmployeeInfo

   11         {

   12             get { return (EmployeeInfo)GetValue(EmployeeInfoProperty); }

   13             set { SetValue(EmployeeInfoProperty, value); }

   14         }

   15 

   16         public static readonly DependencyProperty EmployeeInfoProperty =

   17             DependencyProperty.Register("EmployeeInfo", typeof(EmployeeInfo), typeof(LeaveWorkflow));

   18 

   19         public LeaveApproveResultEnum LeaveApproveResult

   20         {

   21             get { return (LeaveApproveResultEnum)GetValue(LeaveApproveResultProperty); }

   22             set { SetValue(LeaveApproveResultProperty, value); }

   23         }

   24 

   25         public static readonly DependencyProperty LeaveApproveResultProperty =

   26             DependencyProperty.Register("LeaveApproveResult", typeof(LeaveApproveResultEnum), typeof(LeaveWorkflow));

  5、回到該Workflow的設計界面中,從工具欄上拖入4個StateActivity,分别命名為Initial、Setting、Waiting和Completed。在名為Initial的StateActivity上右鍵,選擇Set as Initial State,在名為Completed的StateActivity上右鍵,選擇Set as Completed State。

  6、在名為Initial的StateActivity中,從工具欄中拖入一個StateInitializationActivity,并輕按兩下進入該Activity的設計界面。

  在這個設計界面中,從工具欄拖入一個SetStateActivity,并設定其TargetStateName屬性為Setting。這意味着,一啟動該Workflow,則首先進入設定狀态。

  7、在名為Setting的StateActivity中,從工具欄中拖入一個EventDrivenActivity,并輕按兩下進入該Activity的設計界面。

  在這個設計界面中,從工具欄拖入一個DelayActivity,在其下再拖入一個IfElseActivity。

  點選IfElseActivity的左邊分支,并設定其Condition屬性為Code Condition。這時,Condition屬性前面出現一個加号圖示,點選該圖示,設定下面的Condition為CheckEmployeeManager。這時進入背景代碼編輯器。

    1         private void CheckEmployeeManager(object sender, ConditionalEventArgs e)

    3             try

    4             {

    5                 e.Result = (this.EmployeeInfo.EmployeeManager.HasValue == true);

    6             }

    7             catch

    8             {

    9                 throw;

   10             }

   11         }

  上面的代碼意味着,如果該EmployeeInfo的EmployeeManager屬性有值,即不是最高上司,則執行IfElseActivity的左邊分支,否則執行右邊分支。

  8、回到前面的EventDrivenActivity的設計界面,從工具欄中拖入一個CallExternalMethodActivity到左邊分支,設定其IInterfaceType屬性為Eallies.OA.Workflow.Interface.ILeaveInterface,MethodName屬性為UpdateLeaveApproverByLeaveId,leaveId屬性為Activity=LeaveWorkflow, Path=LeaveId,leaveApprover屬性為Activity=LeaveWorkflow, Path=EmployeeInfo.EmployeeManager.Value。該CallExternalMethodActivity用于設定該請假單的審批人。

  與上面的操作相似,再拖入一個CallExternalMethodActivity,并設定屬性。該CallExternalMethodActivity用于設定該請假單的狀态。

  與前面的操作相似,再拖入一個SetStateActivity,并設定其TargetStateName屬性為Waiting。這意味着,設定完屬性後,等待下一次上司審批事件。

  右邊分支的設定類似。

  9、與上述7~8步驟類似,設定名為Waiting的StateActivity。

  10、至此Workflow設定完畢。

本文轉自 Eallies 51CTO部落格,原文連結:http://blog.51cto.com/eallies/79051,如需轉載請自行聯系原作者

繼續閱讀