zoukankan      html  css  js  c++  java
  • SharePoint工作流解决方案QuickFlow系列(5)—会签(MultiTask and GroupTask)

    会签可能会有很多解释或定义,本文讲的会签是指在一个流程中的某一步操作有多个用户同时参与,这些用户的操作界面一般是一样的。

    QuickFlow的会签是通过MultiTask实现的,MultiTask实现了多个任务同时分配的逻辑,它具有以下控制属性:

    image

    1)ExecutionType--指定任务的分配是串行还是并行,如果是串行,则上一个用户完成任务后才会给下一个用户分配任务,如果是并行,则所有任务同时分配。

    2)CompletionMode--任务的完成模式,可以为RequireOne和RequireAll,如果RequireOne,则无论这一步分配了几个任务,只要一个用户完成,步骤即结束,未完成的任务会被自动取消,如果是RequireAll,并且没有指定CompleteRule,则要求所有用户都完成任务。

    3)CompleteRule--CompleteRule是一个Condition类型的属性,可以为CodeConditon或DeclareRuleConditon。当CompletionMode为RequireAll时,可以利用CompleteRule进一步控制审批步骤何时结束。我们经常碰到的如下的业务场景:当多个人参与审批,所有人都同意则到下一步,如果只要有一个用户不同意,则流程退回或结束,即使其他用户还没有审批。这种情况即可利用CompleteRule。

    下面看一个示例:

    流程很简单,第一步多人会签审批,如果有一人不同意则结束流程,如果所有人都同意则到经理审批。

    Step1)画出如下的流程图

    其中“开始”节点对应Start活动,“会签审批”对应MultiTask活动,“经理审批”对应Task活动,“结束”对应End活动。

    image

    注意:如果你已经画好了流程图中的线,然后改了活动的名字,可能需要将画好的线删掉重新画线,不然会出现活动找不到错误。

    Step2)处理“会签审批”

    指定会签审批的CompletionMode为RequireAll,ExecutionType为Parallel。

    将“会签审批”的TaskOutcomes属性绑定到工作流的字段:

    image

    处理“会签审批”的Initialized事件:

    private void 会签审批_Initialized(object sender, EventArgs e)
           {
               this.会签审批.Users.Add("dc\\user1");
               this.会签审批.Users.Add("dc\\user2");
               this.会签审批.Users.Add("dc\\user3");
               //如果是串行分配任务,这里的顺序就决定了任务分配的顺序
           }

    设置“会签审批”的CompleteRule:

    image 

    说明:只要有一个人的审批结果是Reject,则此条件为true。

    Step3)设置“会签审批”后的路由判断

    设置decision的Conditon为code conditon:

    private void allAgree(object sender, ConditionalEventArgs e)
           {
               e.Result = this.会签审批.TaskOutcomes.Filter("Reject") == 0; //没有reject的
           }

    Step4) 处理“经理审批”,设置其TaskCreating事件:

    private void managerTaskCreating(object sender, QuickFlow.TaskEventArgs e)
           {
               e.TaskProperties.AssignedTo = "dc\\manager";
           }

    完成!

     

    关于GroupTask

    每次使用MulitiTask时都要写代码指定审批人,这是一个不好的习惯,通常,审批人可以按照某些规则来获取,比如来自SharePoint组,来自AD组,来自第三方的角色管理系统,很显然我们应该将这些常用的用户获取逻辑做个封装。

    GroupTask继承于MultiTask,它的代码很简单,只是在MultiTask的Initialized事件中将用户从某个组中取出来添加到Users集合中,这样,如果我们要将任务分配给SharePoint用户组中的用户,直接用GroupTask,设置一下它的Group属性即可:

    //GroupTask获取用户的代码

    void GroupTask_Initialized(object sender, EventArgs e)
            {

                if (this.WorkflowProperties == null)
                    throw new Exception("WorkflowProperties is null , please bind it to correct field");

                SPRoleUserProvider up = new SPRoleUserProvider();

                IList<User> users = null;
                try
                {
                    if (this.DeptInherits)
                    {
                        User user = up.GetUser( this.WorkflowProperties.Web , this.WorkflowProperties.Originator);
                        users = up.GetRoleUsers( this.WorkflowProperties.Web, this.Group,user.Department );
                    }
                    else
                    {
                        users = up.GetRoleUsers(this.WorkflowProperties.Web, this.Group);
                    }
                }
                catch (Exception ex)
                {
                    ActivityUtil.Log(this, SPWorkflowHistoryEventType.WorkflowError, null, "获取组用户出错[" + this.Group + "]", ex.Message);
                    throw ex;
                }

                foreach (User u in users)
                {
                    this.Users.Add(u.LoginName);
                }
            }

    GroupTask有个DeptInherit属性,这个是来做什么的呢?

    假设有一步审批是“部门经理审批”,而这个公司是一个有多个部门的大公司,每个提交人发起的审批,都需要“他所在的部门的经理”进行审批,如何实现?
    一种方式是将部门经理作为用户的AD属性,在AD中进行维护,那么只要用Task活动,写代码从用户的AD属性中获取即可,这种方式的一个缺点是维护工作量太大了。

    还有个简单的方式:在网站建个部门经理的组,SharePoing中每个用户都有个“部门”属性,提交人和“本部门经理”的部门属性一定是一样的,那么用提交人的部门属性从部门经理组中进行一下过滤,即可取到“本部门经理”,当DeptInerit设置为true时,GroupTask即会进行这个操作。当然这个方法要求AD中用户的“部门”属性一定要维护正确,然后正确同步到UserProfile中(AD中维护后1小时)。

    这两种方法是不开发专门的“用户角色管理系统”的前提下的,如果您有完善的角色管理系统,可能实现的就更“优美”了。

     

    用过K2的朋友可以比较下,这个MultiTask和GroupTask跟K2的ClientEvent是很类似的。

     

    示例代码下载:

    https://files.cnblogs.com/jianyi0115/QuickFlowExample_%E4%BC%9A%E7%AD%BE.zip

    注意:此代码并没有经过测试,只能作为参考。

  • 相关阅读:
    leetcode Super Ugly Number
    leetcode Find Median from Data Stream
    leetcode Remove Invalid Parentheses
    leetcode Range Sum Query
    leetcode Range Sum Query
    leetcode Minimum Height Trees
    hdu 3836 Equivalent Sets
    hdu 1269 迷宫城堡
    hud 2586 How far away ?
    poj 1330 Nearest Common Ancestors
  • 原文地址:https://www.cnblogs.com/jianyi0115/p/1562132.html
Copyright © 2011-2022 走看看