状态机工作流.实列.报销审批流程(二)

接上篇文章 “状态机工作流.实列.报销审批流程(一) ” 有代码下载
本文主要讲述,在web上实际应用上篇文章中设计的工作流。。。。


涉及技术
  在Web.config 配置  
  取得工作流结构
  动态加签
  动态取得审批方式
  启动工作流流转等(这个好多列子中都有不再详细描述)

状态机工作流.实列.报销审批流程(二)_第1张图片

Web 项目文件主要功能描述

  1. Web.Config

      配置了一些工作流服务
      WorkflowRuntime 加载的,ManualWorkflowSchedulerService 和 ExternalDataExchangeService
      ExternalDataExchangeService 加载的,上篇文章中的 MyWorkflows.BillServer

  2. Global.asax,App_Code\Global.asax.cs

      启动 WorkflowRuntime,加载 FileWorkflowPersistenceService(自定义的状态保存服务,下篇文章详细讲解)

    代码

    protected   void  Application_Start( object  sender, EventArgs e)
        {
            Console.WriteLine(
    " Application_Start: " );
            System.Workflow.Runtime.WorkflowRuntime workflowRuntime 
    =   new  System.Workflow.Runtime.WorkflowRuntime(MyWorkHelpr.WorkflowRuntimeName);
        

            
    // 加载状态保持服务(自己的类),构造函数设置保存状态的路径
            FileWorkflowPersistenceService f28s  =   new  FileWorkflowPersistenceService(Server.MapPath( " ~/App_Data/XOM.WFDB/ " ));
            workflowRuntime.AddService(f28s);

            
            Application[MyWorkHelpr.WorkflowRuntimeName] 
    =  workflowRuntime;
            
    // 映射事件没用上
            workflowRuntime.WorkflowCompleted  +=   new  EventHandler < System.Workflow.Runtime.WorkflowCompletedEventArgs > (workflowRuntime_WorkflowCompleted);
            workflowRuntime.WorkflowTerminated 
    +=   new  EventHandler < System.Workflow.Runtime.WorkflowTerminatedEventArgs > (workflowRuntime_WorkflowTerminated);
            workflowRuntime.WorkflowSuspended 
    +=   new  EventHandler < System.Workflow.Runtime.WorkflowSuspendedEventArgs > (workflowRuntime_WorkflowSuspended);
            workflowRuntime.WorkflowPersisted 
    +=   new  EventHandler < System.Workflow.Runtime.WorkflowEventArgs > (workflowRuntime_WorkflowPersisted);
            workflowRuntime.StartRuntime();
            
            
    // 重状态保存读取所有没执行完的了类.
             foreach  (Guid id  in  f28s.GetAllWorkflows())
            {
                workflowRuntime.GetWorkflow(id);
            }

        }

  3. Default.aspx (用户登陆)

      导航页面,可以模拟各种角色登陆,可以显示全部正在进行的工作流信息、可以查看工作流的结构

    状态机工作流.实列.报销审批流程(二)_第2张图片

    代码说明
    取得工作流结构

    protected   void  GridView1_RowCommand( object  sender, GridViewCommandEventArgs e)
        {
            
    int  i  =   0 ;
            
    if  (e.CommandName.ToLower()  ==   " select " )
            {
    // 就想取两级就不递归了
            
                i 
    =  Convert.ToInt32(e.CommandArgument);
                
    string  sguid  =  GridView1.Rows[i].Cells[ 1 ].Text.Trim();
                Guid instanceId 
    =   new  Guid(sguid);
                
                WorkflowInstance workInstance 
    =  (Application[MyWorkHelpr.WorkflowRuntimeName]  as  WorkflowRuntime).GetWorkflow(instanceId);
                StateMachineWorkflowActivity MainActivity 
    =  workInstance.GetWorkflowDefinition()  as  StateMachineWorkflowActivity;
                TreeView1.Nodes.Clear();
                
                TreeNode MainNode 
    =   new  TreeNode();
                TreeNode NodeL1 
    =   null ;
                TreeNode NodeL2 
    =   null ;
                MainNode.Text 
    =  sguid;
                
    foreach (StateActivity state  in  MainActivity.Activities)
                {
                    
                    NodeL1 
    =   new  TreeNode();
                    NodeL1.NavigateUrl
    = " # " ;
                    NodeL1.Text 
    =  state.Name  +   " : "   + state.Description;
                    
    foreach (CompositeActivity cactive  in  state.Activities)
                    {
                        NodeL2 
    =   new  TreeNode();
                        NodeL2.NavigateUrl 
    =   " # " ;
                        NodeL2.Text 
    =  cactive.Name  +   " : "   +  cactive.Description;
                        NodeL1.ChildNodes.Add(NodeL2);
                        
                    }
                    MainNode.ChildNodes.Add(NodeL1);
                }
                MainNode.ExpandAll();
                TreeView1.Nodes.Add(MainNode);
                
                
    // btnReadGuid_Click(btnReadGuid, null);
            }
        }


  4. CreateBill.aspx (创建修改报销单)

      填写表单,根据金额判断跳转到老板,还是财务(跳转是在ASP.net程序中控制的,其实也可以在工作流里控制,有情趣的可以自己改改)

    状态机工作流.实列.报销审批流程(二)_第3张图片
    代码

    protected   void  btnOk_Click( object  sender, EventArgs e)
        {
            
    if (TextBox1.Text.Length > 0 )
            {
                Guid InstanceId 
    =   new  Guid(TextBox1.Text);
                BillServer billserver 
    =  (Application[MyWorkHelpr.WorkflowRuntimeName]  as  WorkflowRuntime).GetService < BillServer > ();

                ManualWorkflowSchedulerService scheduler 
    =  (Application[MyWorkHelpr.WorkflowRuntimeName]  as  WorkflowRuntime).GetService < ManualWorkflowSchedulerService > ();
                

                
    decimal  money  =   decimal .Parse(txt3.Text);
                
    if  (money  <   1 return ;



                
    string  wsPath  =  HttpContext.Current.Server.MapPath( " ~/App_Data/WorkflowSave/ " );
                
    // 如果已经有数据取得
                BillModel model  =  FileTools.XmlDeserializeObject(wsPath
                , InstanceId
                , 
    typeof (BillModel))  as  BillModel;

                
    if  (model == null ) model  =   new  BillModel();
                
                            
                model.BillId 
    =  txt1.Text;
                model.Money 
    =  money;
                model.UserName 
    =  txt2.Text;            
                
                
                
    if (model.Money  >   1000 )
                {
    // 流转到老板
                    billserver.RaiseEvent( " BillInitMoneyMax " , InstanceId);
                }
                
    else
                {
    // 流转到财务
                    billserver.RaiseEvent( " BillInitMoneyMin " ,InstanceId);
                }
                
                
    // 流转工作流
                scheduler.RunWorkflow(InstanceId);
                TextBox1.Text
    = "" ;
                
    // 保存更改的数据
                FileTools.XmlSerializeObject(wsPath
                , InstanceId
                , model);
                
    // this.Response.Redirect("default.aspx", false);
            }
        }

  5. Finance.aspx (财务)

       页面加载显示财务应该处理的流程,选择一个正在进行的流程进行审批,动态取得审批方式到下拉框(审批方式是工作流设计器上设计的)、如果需要可以动态增加一个老板加签

    状态机工作流.实列.报销审批流程(二)_第4张图片
    代码说明
    动态取得审批方式到下拉框的代码

    protected   void  btnReadGuid_Click( object  sender, EventArgs e)
        {
            
            
    string  s  =  txtGuid.Text.Trim();
            
    if (s.Length > 0 )
            {
                Guid instanceId 
    =   new  Guid(s);
                
    // 取得当前工作流里正在进行的 StateMachineWorkflow (这里是 stateFinance)
                StateMachineWorkflowInstance stateInstance  =   new  StateMachineWorkflowInstance(Application[MyWorkHelpr.WorkflowRuntimeName]  as  WorkflowRuntime, instanceId);
                
                
    using (DataTable dt  =   new  DataTable())
                {

                    
    // 创建一个下拉框用的 DataTable
                    dt.Columns.Add( " NID " typeof ( string ));  // 保存 EventDrivenActivity 的名字,在确定时使用
                    dt.Columns.Add( " NTEXT " typeof ( string ));  // 保存 EventDrivenActivity 的说明
                    dt.Rows.Add( " -1 " , " ==请选择== " );
                    
                    
    int  i = 0 ;
                    
                    
    foreach (Activity act  in  stateInstance.CurrentState.EnabledActivities)
                    {
    // 循环当前流程可以用的 Activitie (在本步骤就是设计器里的 stateFinance 中的那些 EventDrivenActivity)
                        
                        
    if  (act  is  EventDrivenActivity )
                        {
                            EventDrivenActivity edact 
    =  (EventDrivenActivity)act;
                            
                            
    if  (edact.EnabledActivities.Count  > 0   &&  edact.EnabledActivities[ 0 is  HandleExternalEventActivity)
                            {
    // 取得每个 EventDrivenActivity 中第一个 HandleExternalEventActivity 把名字和说明放到 dt 中
                                dt.Rows.Add(edact.Name, act.Description);
                            }
                        }
                        i
    ++ ;
                    }
                    
                    
    // DataBind
                    DropDownList1.DataValueField  =   " NID " ;
                    DropDownList1.DataTextField 
    =   " NTEXT " ;
                    DropDownList1.DataSource 
    =  dt;
                    DropDownList1.DataBind();
                    
                    
                }
            }
        }


    动态加签的代码

    protected   void  Button2_Click( object  sender, EventArgs e)
        {
            
    string  s  =  txtGuid.Text.Trim();
            
            
    if (s.Length > 0 )
            {
                Guid instanceId 
    =   new  Guid(s);
                WorkflowInstance workInstance 
    =  (Application[MyWorkHelpr.WorkflowRuntimeName]  as  WorkflowRuntime).GetWorkflow(instanceId);
                
    // 取得整个工作流对象
                StateMachineWorkflowActivity activity  =  (StateMachineWorkflowActivity)workInstance.GetWorkflowDefinition();
                
    // 用 WorkflowChanges 榜定 activity
                WorkflowChanges wfc  =   new  WorkflowChanges(activity);
                
    // 取得财务的 StateActivity
                StateActivity state  =  (StateActivity)wfc.TransientWorkflow.Activities[ " stateFinance " ];
                        
                
    if (state.Activities[ " eveToBoss " ] !=   null  )  return ;

            
                

                
    // 声明一个外部事件
                HandleExternalEventActivity externalEveTmp  =   new  HandleExternalEventActivity();
                externalEveTmp.EventName 
    =   " BillInsert " ;
                externalEveTmp.InterfaceType 
    =   typeof (MyWorkflows.IBILLService);
                externalEveTmp.Name 
    =   " externalEveTmp " ;
                
                
    // 设置一个跳转
                SetStateActivity setActTmp  =   new  SetStateActivity();
                setActTmp.Name 
    =   " setActTmp " ;
                setActTmp.TargetStateName 
    =   " stateBoss " ;
                
            

                EventDrivenActivity EventDrivenTmp 
    =   new  EventDrivenActivity();

                EventDrivenTmp.Activities.Add(externalEveTmp);
                EventDrivenTmp.Activities.Add(setActTmp);
                EventDrivenTmp.Description 
    =   " *老板加签* " ;
                EventDrivenTmp.Name 
    =   " eveToBoss " ;            
                
    // 挂起
                workInstance.Suspend( " 正在加签 " );


                
    // 财务的 StateActivity 中加入一个 EventDrivenActivity
                state.Activities.Add(EventDrivenTmp);
                
                ValidationErrorCollection err 
    =  wfc.Validate();
                
    // 应用更改
                workInstance.ApplyWorkflowChanges(wfc);
                
    // 恢复
                workInstance.Resume();
                
                btnReadGuid_Click(btnReadGuid,
    new  EventArgs());
                
            }
        }


    确定按扭时使用 下拉框 里的审批方式


    protected   void  Button1_Click( object  sender, EventArgs e)
        {
            
    string  s  =  txtGuid.Text.Trim();
            
    if  (s.Length  >   0   &&  DropDownList1.SelectedValue  !=   " -1 " )
            {
                
    // 取得下拉框选择的 value btnReadGuid_Click 中取得的
                 string  nid  =  DropDownList1.SelectedValue;
                
                Guid instanceId 
    =   new  Guid(s);

                BillServer billserver 
    =  (Application[MyWorkHelpr.WorkflowRuntimeName]  as  WorkflowRuntime).GetService < BillServer > ();
                ManualWorkflowSchedulerService scheduler 
    =  (Application[MyWorkHelpr.WorkflowRuntimeName]  as  WorkflowRuntime).GetService < ManualWorkflowSchedulerService > ();

                StateMachineWorkflowInstance stateInstance 
    =   new  StateMachineWorkflowInstance(Application[MyWorkHelpr.WorkflowRuntimeName]  as  WorkflowRuntime, instanceId);
                
    // 通过名称取得 EventDrivenActivity
                EventDrivenActivity edact  =  (EventDrivenActivity)stateInstance.CurrentState.Activities[nid];
                
    // 和第一个 HandleExternalEventActivity
                HandleExternalEventActivity heva  =  (HandleExternalEventActivity)edact.EnabledActivities[ 0 ];
                
                


                
    // WorkflowInstance workInstance = stateInstance.WorkflowInstance;
                
    // BillWorkflow act = stateInstance.WorkflowInstance.GetWorkflowDefinition() as BillWorkflow;

                
    string  wsPath  =  HttpContext.Current.Server.MapPath( " ~/App_Data/WorkflowSave/ " );
                BillModel model 
    =  FileTools.XmlDeserializeObject(wsPath
                , instanceId
                , 
    typeof (BillModel))  as  BillModel;

                model.LastRemark 
    =  model.Fremark  =   string .Concat( " 财务:  " , DropDownList1.SelectedItem.Text,  " : " , txtRemark.Text);
                
                

                
    // 通过  HandleExternalEventActivity.EventName 调用 BillServer.RaiseEvent 触发外部事件使工作流向前运行
                
    // 这就是我为上一章何在 BillServer 重写那些事件的原因
                billserver.RaiseEvent(heva.EventName, instanceId);
                
                
    // 工作流向下流转
                scheduler.RunWorkflow(instanceId);
                
                FileTools.XmlSerializeObject(wsPath,instanceId,model);
                DropDownList1.Items.Clear();
                txtGuid.Text 
    =   "" ;
                
    // stateInstance.CurrentStateName
                 return ;
            
    //      // 如果用过一次要删除
            
    //     if(edact.Name == "eveToBoss")  // 删除加签
            
    //     {
                    
            
    //          // WorkflowInstance workInstance = (Application[MyWorkHelpr.WorkflowRuntimeName] as WorkflowRuntime).GetWorkflow(instanceId);
            
    //         workInstance.Suspend("正在删除加签");

            
    //         StateMachineWorkflowActivity activity = workInstance.GetWorkflowDefinition() as StateMachineWorkflowActivity;

            
    //         WorkflowChanges wfc = new WorkflowChanges(activity);

            
    //          // StateActivity sa = wfc.TransientWorkflow.Activities["stateFinance"] as StateActivity;

            
    //         StateActivity state = (StateActivity)wfc.TransientWorkflow.Activities["stateFinance"];
            
    //         state.Activities.Remove(state.Activities["eveToBoss"]);
                                    
            
    //         ValidationErrorCollection err = wfc.Validate();
            
    //         workInstance.ApplyWorkflowChanges(wfc);
            
    //         workInstance.Resume();
                    
            
    //          // this.Response.Redirect("");
                    
            
    //     }            
                
            }
        }

  6. Boss.aspx (老板)

      页面加载显示老板应该处理的流程,选择一个正在进行的流程进行审批,动态取得审批方式到下拉框
  7. PayBox.aspx (出纳)

      页面加载显示出纳应该处理的流程,选择一个正在进行的流程进行审批,动态取得审批方式到下拉框
  8. OutMoney.aspx(取钱确认)

      页面加载子显示出纳审批Ok 的流程,选择一个正在进行的流程确认以读取,动态取得审批方式到下拉框

说明
其实重财务以后的页面处理方式都基本是一样的,界面也都类似,不再多说...

转载于:https://www.cnblogs.com/wayne-ivan/archive/2007/10/09/917656.html

你可能感兴趣的:(runtime)