• 博客园logo
  • 会员
  • 周边
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
鱼要的是海洋,鸟要的是天空,我要的是自由!
平凡的人不平凡的人生
博客园    首页    新随笔    联系   管理    订阅  订阅

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

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


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

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 (用户登陆)

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



    代码说明
    取得工作流结构

    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程序中控制的,其实也可以在工作流里控制,有情趣的可以自己改改)


    代码

    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 (财务)

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


    代码说明
    动态取得审批方式到下拉框的代码

    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 的流程,选择一个正在进行的流程确认以读取,动态取得审批方式到下拉框

说明
其实重财务以后的页面处理方式都基本是一样的,界面也都类似,不再多说...
posted @ 2007-10-09 02:05  伊凡  阅读(1416)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3