1)概述
QuickFlow最新版本增加了任务代理功能。
所谓代理,指的是用户可以事先配置其他用户在指定的时间段来代替自己处理所有任务。
QuickFlow默认的代理配置采用一个列表实现,样式如下:
2)如何启用代理
默认情况下,代理没有启用,若要启用代理,首先建立一个如上图所示的列表,列表名QuickFlowDelegation,字段:
DelegatedUser,用户类型,不能为空;
DelegateUser,用户类型,不能为空;
BeginTime,时间类型,可以为空;
EndTime,时间类型,可以为空;
Enabled,bool类型,不能为空;
如果是英文站点,QuickFlow的安装包内有个列表模板文件QuickFlowDelegationListEng.stp,可以将这个文件上传到列表模板库,然后基于这个模板创建列表。
创建好列表后,打开C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\12\TEMPLATE\LAYOUTS\QuickFlow目录的global.config文件。将TaskDelegationProvider的注释取消,如下:
<?xml version="1.0" encoding="utf-8"?>
<GlobalConfiguration xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<CustomRoleUserProvider>QuickFlow.Core.SPRoleUserProvider,QuickFlow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e1745628</CustomRoleUserProvider>
<TaskDelegationProvider>QuickFlow.Core.DefaultTaskDelegationProvider,QuickFlow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e1745628</TaskDelegationProvider>
<!--if DelegationListSiteUrl is empty, system will use current site-->
<!--<DelegationListSiteUrl>http://codeartserver:81/sites/s1</DelegationListSiteUrl>-->
<DelegationListUrl>Lists/QuickFlowDelegation</DelegationListUrl>
<EventReceivers>
<Receiver Enabled="false" Name="Exception" Type="QuickFlow.EventBus.ExceptionEventReceiver,QuickFlow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e1745628" />
<Receiver Enabled="true" Name="Tracing" Type="QuickFlow.EventBus.TracingEventReceiver,QuickFlow, Version=1.0.0.0, Culture=neutral, PublicKeyToken=ec1e0fe6e1745628" />
</EventReceivers>
</GlobalConfiguration>
然后重启iis,代理功能就启用了。
如果已经部署了QuickFlow,安装最新版本wsp后,需要重新激活QuickFlow Feature。
启用代理后,在代理有效期内,发给被代理人的任务都会自动分配给代理人,但是被代理人依然具有操作任务的权限。在QF最新的默认任务页面上,系统的WorkflowHisboty控件也会显示代理情况:
3)代理配置的扩展和自定义
如果你要实现自己的代理配置逻辑,可以自己实现一个类,实现ITaskDelegationProvider接口,部署到GAC,然后修改配置即可。
自己实现代理逻辑,可以参考系统默认实现的代码:
public class DefaultTaskDelegationProvider : ITaskDelegationProvider
{
//public const string ListUrl = "Lists/QuickFlowDelegation";
static LookupQueryField fieldDelegatedUser = new LookupQueryField("DelegatedUser");
static TypedQueryField<DateTime> fieldBeginTime = new TypedQueryField<DateTime>("BeginTime");
static TypedQueryField<DateTime> fieldEndTime = new TypedQueryField<DateTime>("EndTime");
static QueryField fieldEnabled = new QueryField("Enabled");
DateTime GetDate(string date)
{
if (String.IsNullOrEmpty(date))
return DateTime.MinValue;
else
return Convert.ToDateTime(date);
}
#region ITasDelegateProvider Members
public TaskDelegate GetTaskDelegate(SPWorkflowActivationProperties prop, string delegatedUser)
{
var siteUrl = GlobalConfiguration.GetInstance().DelegationListSiteUrl;
if (siteUrl == null || String.IsNullOrEmpty(siteUrl.Value))
{
return this.GetTaskDeletate(prop.Web, delegatedUser);
}
else
{
using (SPSite site = new SPSite(siteUrl.Value))
{
using (SPWeb web2 = site.OpenWeb())
{
return this.GetTaskDeletate(web2, delegatedUser);
}
}
}
}
public TaskDelegate GetTaskDeletate(SPWeb web, string delegatedUser)
{
string fullUrl = web.Site.ServerRelativeUrl.TrimEnd('/') + "/" + GlobalConfiguration.GetInstance().DelegationListUrl.Value;
SPList list = null;
try
{
list = web.GetList(fullUrl);
}
catch(Exception ex)
{
throw new Exception("can't find the delegate confit list:" + fullUrl);
}
SPUser user = web.AllUsers[delegatedUser];
if (user == null)
{
throw new Exception("user doen't exist in the web: " + delegatedUser);
}
var now = DateTime.Now;
var items = ListQuery.Select(1).From(list).Where(fieldDelegatedUser == user.ID &&
(fieldBeginTime.IsNull || fieldBeginTime <= now) &&
(fieldEndTime.IsNull || fieldEndTime > now.AddDays(-1)) &&
(fieldEnabled == 1)
).GetItems();
if (items == null || items.Count == 0)
{
return null;
}
var item = items[0];
SPFieldUserValue userValue = item.Fields.GetField("DelegateUser").GetFieldValue(item["DelegateUser"].ToString()) as SPFieldUserValue;
var del = new TaskDelegate();
del.DelegateUser = userValue.User.LoginName;
del.BeginTime = this.GetDate("" + item["BeginTime"]);
del.EndTime = this.GetDate("" + item["EndTime"]);
return del;
}
#endregion
}
注:本文所述功能,需要QuickFlow.wsp(Build101031)之后版本支持。