SharePoint 2010 自定义状态机工作流 (StateMachine Workflow) + InfoPath 实例part1 (工作流实现部分)

来源:互联网 发布:python算法教程百度云 编辑:程序博客网 时间:2024/05/01 21:11

SharePoint 2010 自定义状态机工作流(StateMachine Workflow) + InfoPath 实例part1 (工作流实现部分)

首先虚拟一个场景,某客户要求基于SharePoint 2010 实现一个招聘工作流。

招聘流程需求如下:   

a.      HR 助理从网络活猎头那里得到候选人的信息,如姓名,简历等,输入到SharePoint中的列表,同时指定HR审核人,电话面试官,F2F面试官,保存后工作流启动

b.     HR审核人将自动接到一个任务,对候选人的信息进行审核以及确认候选人是否有换工作的打算,如果审核通过,则工作流向下执行,否则需给出审核未通过的原因(工作流结束)

c.      电话面试官自动接到一个任务,对候选人进行电话面试,如果通过了则工作流继续向下执行,否则工作流结束

d.     F2F面试官自动接到一个任务,对候选人进行F2F面试,如果通过则该候选人最终状态为Approved,否则该候选人的最终状态为Rejected

数据权限:

a.      HR 助理可以输入候选人信息(姓名,简历),并指定HR审核人,电话面试官,F2F面试官

b.     HR审核人可以看到候选人信息(姓名,简历),可以为HR审核字段设置Approved或Rejected,可以填写HR审核备注

c.      电话面试官候选人信息(姓名,简历),可以为电话面试设置Approved或Rejected,可以填写电话面试备注

d.     F2F面试官候选人信息(姓名,简历),可以为F2F面试设置Approved或Rejected,可以填写F2F面试备注

分析:

流程控制可以使用状态工作流 (State Workflow)来实现, 数据权限使用infopath2010的规则来实现。

1.      在SharePoint中新建一个Recruitment自定义列表,包含以下字段

 Title  Single line of text  ,用于存放候选人姓名 ,该字段是系统自带字段,不需要另外添加

Resume  Multiple lines oftext  ,用于存放候选人简历

HRReviewer  Person orGroup  , 用于存放HR审核人

HRResult  Choice  ,用于存放HR审核结果(Approvedor Rejected)

HRComments  Multiple linesof text  ,用于存放HR审核备注

PhoneInterviewer  Personor Group  ,用于存放电话面试官

PhoneInterviewResult Choice  ,用于存放电话面试结果(Approvedor Rejected)

PhoneInterviewComments Multiple lines of text  ,用于存放电话面试备注

F2FInterviewer  Person orGroup  ,用于存放F2F面试官

F2FInterviewResult Choice  ,用于存放F2F面试结果(Approvedor Rejected)

F2FInterviewComments Multiple lines of text  ,用于存放F2F面试备注

 

2.      在网站的人员与群组里加入如下用户

 CCPC\f2finterviewer 

 CCPC\hrreviewer 

 CCPC\moss

 CCPC\phoneinterviewer

如果您的SharePoint 环境是域环境,请先到AD中添加对应的用户,如果是单机的,请先在我的电脑管理里添加对应的用户

 

3.      设计状态工作流 (State Workflow)

a.      新建SharePoint  State Workflow 项目

                              点击OK,选择Recruitment作为工作流绑定的对象

 

b.     在工作流设计界面上添加四个State activity(原本有个一,现在一共5个),并分别重命名为:RecruitmentInitialState, RecruitmentHRReview, RecruitmentPhoneInterview,RecruitmentF2FInterview, RecruitmentComplete

c.      选中RecruitmentInitialState右击,选择将其设置为” Set as Initial State”, 选中RecruitmentComplete右击,选择将其设置为”Set as completed state

d.     配置RecruitmentInitialState, 选中RecruitmentInitialState,双击其中的eventDrivenActivity1,选中onWorkflowActivated1,在它的属性Invoked中输入OnWorkflowActivated并按回车(VS将自动为您新建一个 OnWorkFlowActived(object sender, ExternalDataEventArgs e),该方法当onWorkflowActivated1执行时被调用),在该方法体内输入如下代码(该段代码的作用是拼接一个指向工作流当前项目记录的超链接):    

string listId = this.workflowProperties.Item.ParentList.ID.ToString();            string contentTypeId = this.workflowProperties.Item.ContentType.Id.ToString();            string itemId = this.workflowProperties.Item.ID.ToString();            string webUrl = this.workflowProperties.WebUrl;                        this.relatedItemUrl = webUrl + "/_layouts/listform.aspx?PageType=4&ListId={" + listId + "}&ID=" + itemId + "&ContentTypeID=" + contentTypeId;            this.relatedItemUrl = "<a href=" + this.relatedItemUrl + ">Go to check the task related item</a>";

在工作流类中添加如下成员 

private stringrelatedItemUrl = string.Empty;

回到工作流设计界面,从WF3.0的工具箱中拖拽一个setStateActivity放置在  onWorkflowActivated1的下方,命名为setStateActivity1,并将其目标状态(target state name)的名字设置为RecruitmentHRReview   

 

e.     配置RecruitmentHRReview,返回工作流全局设计视图,选中RecruitmentHRReview,右击选择  ”add state Initialization”,将新加的activity命名为stateInitializationForRecruitmentHRReview,双击进入详细配置,从SharePoint的工具箱中拖拽一个CreateTask并放置在stateInitializationForRecruitmentHRReview的区域内。将新加的activity命名为RecruitmentHRReviewTask, 在CorrelationToken中输入RecruitmentHRReviewToken展开该属性并将Owneractivity 设置为RecruitmentHRReview,点击TaskID属性的”…”,点击”bindto new member”, 选择”Create Filed”, 点击OK ,点击TaskProperties属性的”…”,点击”bind to new member”, 选择”CreateFiled”, 点击OK.在MethodInvoking中输入CreateRecruitmentHRReviewTask并回车(系统将自动创建该方法),在该方法体内添加如下代码(该代码的作用为HR审核创建一个Task):

 

try            {                //Create a new TaskId for the Task                this.RecruitmentHRReviewTask_TaskId1 = Guid.NewGuid();                //TaskProperties field is used to configure the Task Details.                this.RecruitmentHRReviewTask_TaskProperties1.Title = "HR Review Task for" + this.workflowProperties.Item["Title"];                //You can assign a Task to an user or to a group. Here we assign the task to HR-Group                this.RecruitmentHRReviewTask_TaskProperties1.AssignedTo = this.workflowProperties.Item["HRReviewer"].ToString().Split("#".ToCharArray()).Length == 2 ? this.workflowProperties.Item["HRReviewer"].ToString().Split("#".ToCharArray())[1] : this.workflowProperties.Item["HRReviewer"].ToString().Split("#".ToCharArray())[0];                this.RecruitmentHRReviewTask_TaskProperties1.TaskType = 1;                this.RecruitmentHRReviewTask_TaskProperties1.Description = this.relatedItemUrl;                this.RecruitmentHRReviewTask_TaskProperties1.DueDate = DateTime.Today.AddDays(1);            }            catch (Exception ex)            {                //Logging is used so that we can debug the errors in the workflow.                System.Diagnostics.EventLog.WriteEntry("Recruitment Workflow", ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);                LogToHistoryListActivity log = new LogToHistoryListActivity();                log.HistoryDescription = ex.StackTrace;            }

 

回到工作流设计界面,回到工作流全局设计界面,选中RecruitmentHRReview, 右击选择 ”add event driven”, 并将该活动命名为eventDrivenForRecruitmentHRReview,双击该活动,从SharePoint的工具箱中拖拽一个OnTaskChanged到eventDrivenForRecruitmentHRReview的区域,并命名为onTaskChangedForRecruitmentHRReview,选择RecruitmentHRReviewToken作为它的CorrelationToken(注意此处的token必须要与该活动要监控的task的token一致,否则onTaskChangedForRecruitmentHRReview就不知道是哪个task有变化该执行了),绑定AfterProperties和BeforeProperties,绑定方法和绑定TaskProperties的方法类似。点击TaskID的”…”选择RecruitmentHRReviewTask_TaskId1作为它的TaskID.从WF3.0的工具箱中拖拽一个IfElseActivity,点击它左边的那个分支,condition类型选择为 Code Condition,在 Condition中输入HRReviewResult并回车(VS将自动生成HRReviewResult方法)在方法体中添加如下代码:

  // HRResult            string hrResult = this.workflowProperties.Item["HRResult"].ToString();            if (hrResult.CompareTo("Approved") == 0)            {                e.Result = true;            }            else            {                e.Result = false;            }

 

该方法返回的结果为分支条件,返回true执行左边分支,返回false执行右边分支。

从WF3.0的工具箱中拖拽两个setStateActivity分别放置在 左边和右边的分支。

将左边分支的目标状态设置为RecruitmentPhoneInterview, 右边分支的目标状态设置为RecruitmentComplete

f.       配置RecruitmentPhoneInterview(由于在上步中已经详述了每一步,故下面的描述会稍微简练一点),回到工作流全局设计界面,选中RecruitmentPhoneInterview,为其添加event drivenstate Initialization并分别命名为eventDrivenForRecruitmentPhoneInterviewstateInitForRecruitmentPhoneInterview,双击stateInitForRecruitmentPhoneInterview,在其中添加一个CreateTask活动并命名为CreateTask_RecruitmentPhoneInterview,将其CorrelationToken设置为RecruitmentPhoneInterviewToken并展开该属性将其OwnerActivityName设置为RecruitmentPhoneInterview,绑定TaskID和TaskProperties, 在MethodInvoking中输入CreateRecruitmentPhoneInterviewTask并回车(VS将自动生成CreateRecruitmentPhoneInterviewTask方法),在该方法体内添加如下代码(该代码的作用为PhoneInterview创建一个Task):

  

   try            {                //Create a new TaskId for the Task                this.CreateTask_RecruitmentPhoneInterview_TaskId1 = Guid.NewGuid();                //TaskProperties field is used to configure the Task Details.                this.CreateTask_RecruitmentPhoneInterview_TaskProperties1.Title = "Phone Interview Task for" + this.workflowProperties.Item["Title"];                //You can assign a Task to an user or to a group. Here we assign the task to HR-Group                this.CreateTask_RecruitmentPhoneInterview_TaskProperties1.AssignedTo = this.workflowProperties.Item["PhoneInterviewer"].ToString().Split("#".ToCharArray()).Length == 2 ? this.workflowProperties.Item["PhoneInterviewer"].ToString().Split("#".ToCharArray())[1] : this.workflowProperties.Item["PhoneInterviewer"].ToString().Split("#".ToCharArray())[0];                this.CreateTask_RecruitmentPhoneInterview_TaskProperties1.TaskType = 1;                this.CreateTask_RecruitmentPhoneInterview_TaskProperties1.Description = this.relatedItemUrl;                // this.workflowProperties.Item.ParentList.I                this.CreateTask_RecruitmentPhoneInterview_TaskProperties1.DueDate = DateTime.Today.AddDays(1);            }            catch (Exception ex)            {                //Logging is used so that we can debug the errors in the workflow.                System.Diagnostics.EventLog.WriteEntry("Recruitment Workflow", ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);                LogToHistoryListActivity log = new LogToHistoryListActivity();                log.HistoryDescription = ex.StackTrace;            }

回到RecruitmentPhoneInterview的设计界面,双击eventDrivenForRecruitmentPhoneInterview,在其中添加一个OnTaskChanged活动并命名为onTaskChangedForRecruitmentPhoneInterview,将其CorrelationToken设置为RecruitmentPhoneInterviewToken,绑定AfterProperties和BeforeProperties,将TaskID设置为CreateTask_RecruitmentPhoneInterview_TaskId1,在onTaskChangedForRecruitmentPhoneInterview下添加一个分支活动(IfElseActivity)

点击它左边的那个分支,condition类型选择为 Code Condition,在 Condition中输入PhoneInterviewResult并回车(VS将自动生成PhoneInterviewResult方法)在方法体中添加如下代码:

string phoneInterviewResult = this.workflowProperties.Item["PhoneInterviewResult"].ToString();            if (phoneInterviewResult.CompareTo("Approved") == 0)            {                e.Result = true;            }            else            {                e.Result = false;            }

该方法返回的结果为分支条件,返回true执行左边分支,返回false执行右边分支。

从WF3.0的工具箱中拖拽两个setStateActivity分别放置在 左边和右边的分支。

将左边分支的目标状态设置为RecruitmentF2FInterview, 右边分支的目标状态设置为RecruitmentComplete

g.      配置RecruitmentF2FInterview,回到工作流全局设计界面,选中RecruitmentF2FInterview,为其添加event drivenstate Initialization并分别命名为eventDrivenForRecruitmentF2FInterviewstateInitForRecruitmentF2FInterview,双击stateInitForRecruitmentF2FInterview,在其中添加一个CreateTask活动并命名为createTaskForRecruitmentF2FInterview,将其CorrelationToken设置为RecruitmentF2FInterviewToken并展开该属性将其OwnerActivityName设置为RecruitmentF2FInterview, 绑定TaskID和TaskProperties,在MethodInvoking中输入CreateTask_RecruitmentF2FInterview并回车(VS将自动生成CreateTask_RecruitmentF2FInterview方法),在该方法体内添加如下代码(该代码的作用为F2FInterview创建一个Task):

    

    try            {                //Create a new TaskId for the Task                this.createTaskForRecruitmentF2FInterview_TaskId1 = Guid.NewGuid();                //TaskProperties field is used to configure the Task Details.                this.createTaskForRecruitmentF2FInterview_TaskProperties1.Title = "F2F Interview Task for" + this.workflowProperties.Item["Title"];                //You can assign a Task to an user or to a group. Here we assign the task to HR-Group                this.createTaskForRecruitmentF2FInterview_TaskProperties1.AssignedTo = this.workflowProperties.Item["F2FInterviewer"].ToString().Split("#".ToCharArray()).Length == 2 ? this.workflowProperties.Item["F2FInterviewer"].ToString().Split("#".ToCharArray())[1] : this.workflowProperties.Item["F2FInterviewer"].ToString().Split("#".ToCharArray())[0];                this.createTaskForRecruitmentF2FInterview_TaskProperties1.TaskType = 1;                this.createTaskForRecruitmentF2FInterview_TaskProperties1.Description = this.relatedItemUrl;                this.createTaskForRecruitmentF2FInterview_TaskProperties1.DueDate = DateTime.Today.AddDays(1);            }            catch (Exception ex)            {                //Logging is used so that we can debug the errors in the workflow.                System.Diagnostics.EventLog.WriteEntry("Recruitment Workflow", ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);                LogToHistoryListActivity log = new LogToHistoryListActivity();                log.HistoryDescription = ex.StackTrace;            }

回到RecruitmentF2FInterview设计界面,双击eventDrivenForRecruitmentF2FInterview在其中添加一个OnTaskChanged活动并命名为onTaskChangedForF2F,将其CorrelationToken设置为RecruitmentF2FInterviewToken,绑定AfterProperties和BeforeProperties,将TaskID设置为createTaskForRecruitmentF2FInterview_TaskId1onTaskChangedForF2F下添加一个分支活动(IfElseActivity),condition类型选择为 Code Condition,在 Condition中输入F2FResult并回车(VS将自动生成F2FResult方法)在方法体中添加如下代码: 

// Status            string f2fResult = this.workflowProperties.Item["F2FInterviewResult"].ToString();            if (f2fResult.CompareTo("Approved") == 0)            {                this.workflowProperties.Item["status"] = "Approved";                this.workflowProperties.Item.Update();                e.Result = true;            }            else            {                this.workflowProperties.Item["status"] = "Rejected";                this.workflowProperties.Item.Update();                e.Result = false;            }

该方法返回的结果为分支条件,返回true执行左边分支,返回false执行右边分支。

从WF3.0的工具箱中拖拽两个setStateActivity分别放置在 左边和右边的分支。

将左边分支的目标状态设置为RecruitmentComplete, 右边分支的目标状态设置为RecruitmentComplete

最终完成的Workflow为:

 

 

使用 VS2010 Deploy 该工作流(选中该项目->右键Deploy)

 如何用Infopath控制数据权限及效果演示将在下一篇博文中分享给大家。

有需要的朋友可以从这里下载源代码 http://download.csdn.net/detail/farawayplace613/3595317