出处:http://www.cnblogs.com/flyskyer/archive/2009/03/11/1408578.html
最近因为接手离职同事的公文审批(没有使用工作流)维护,感觉很麻烦,于是在我开发的工作流平台上重新写了相关的功能,扩展同事的功能,同时可以支持固定流和任意流功能。希望大哥们给予指点。
固定流就是由发起人定义审批的步骤,流程按照既定步骤执行。
任意流就是由发起人发起,选择下一步审批人审批,然后审批再选择下一步审批人。
当然公文审批支持的电子签名的功能也有,但是不作为本篇讨论内容,还有界面美观。
1.服务代码。
Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Workflow.Runtime;
usingSystem.Workflow.Activities;
usingSystem.Workflow.ComponentModel;
namespaceStateMachineService
{
[Serializable]
publicclassDocFlowEventArgs:ExternalDataEventArgs
{
publicDocFlowEventArgs(stringuserID,Guiduninstand):base(uninstand)
{
this.uninstand=uninstand;
this.userID=userID;
}
privateGuiduninstand=Guid.Empty;
publicGuidUninstand
{
get{returnthis.uninstand;}
set{this.uninstand=value;}
}
privatestringuserID=string.Empty;
publicstringUserID
{
get{returnthis.userID;}
set{this.userID=value;}
}
}
[ExternalDataExchange]
publicinterfaceIDocFlowService
{
eventEventHandler<DocFlowEventArgs>Next;
eventEventHandler<DocFlowEventArgs>Jump;
eventEventHandler<DocFlowEventArgs>Stop;
voidSetFixNextApprover(intNextStpeID,stringuninstand);
voidSetFixEnableApprover(intCurrentStpeID,stringuninstand);
voidSetAutoNextApprover();
voidSetAutoEnableApprover(stringuninstand);
voidChangeStatus();
}
[Serializable]
publicclassDocFlowService:IDocFlowService
{
IDAL.IWFreeNodeiwfreenode;
GuidT;
stringUserID;
Dictionary<string,EventHandler<DocFlowEventArgs>>list=newDictionary<string,EventHandler<DocFlowEventArgs>>();
publicvoidRaiseEventer(stringeventName,Guiduninstand,stringuserID)
{
if(list[eventName]!=null)
{
try
{
EventHandler<DocFlowEventArgs>eventHandler=list[eventName];
DocFlowEventArgsargs=newDocFlowEventArgs(userID,uninstand);
args.WaitForIdle=true;
eventHandler.Invoke(null,args);
this.T=uninstand;
this.UserID=userID;
}
catch
{
}
}
}
IDocFlowService成员#regionIDocFlowService成员
publiceventEventHandler<DocFlowEventArgs>Next
{
add
{
this.list.Add("Next",value);
}
remove
{
this.list.Remove("Next");
}
}
publiceventEventHandler<DocFlowEventArgs>Jump
{add
{
this.list.Add("Jump",value);
}
remove
{
this.list.Remove("Jump");
}
}
publiceventEventHandler<DocFlowEventArgs>Stop
{
add
{
this.list.Add("Stop",value);
}
remove
{
this.list.Remove("Stop");
}
}
publicvoidChangeStatus()
{
thrownewNotImplementedException();
}
#endregion
IDocFlowService成员#regionIDocFlowService成员
publicvoidSetFixNextApprover(intNextStpeID,stringuninstand)
{
iwfreenode=DALFactory.WFreeNode.CreateInstance();
stringscript="updateWFreeNodeset[ExceteState]=1whereUninstand='"+uninstand+"'andStepID="+NextStpeID;
iwfreenode.Update(script);
//thrownewNotImplementedException();
}
#endregion
IDocFlowService成员#regionIDocFlowService成员
publicvoidSetFixEnableApprover(intCurrentStpeID,stringuninstand)
{
iwfreenode=DALFactory.WFreeNode.CreateInstance();
stringscript="updateWFreeNodeset[ExceteState]=2whereUninstand='"+uninstand+"'anduserID='"+this.UserID+"'andStepID="+CurrentStpeID;
iwfreenode.Update(script);
//thrownewNotImplementedException();
}
#endregion
IDocFlowService成员#regionIDocFlowService成员
publicvoidSetAutoNextApprover()
{
//thrownewNotImplementedException();
}
publicvoidSetAutoEnableApprover(stringuninstand)
{
iwfreenode=DALFactory.WFreeNode.CreateInstance();
stringscript="updateWFreeNodeset[ExceteState]=2whereUninstand='"+uninstand+"'anduserID='"+this.UserID+"'";
iwfreenode.Update(script);
}
#endregion
}
}
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->usingSystem;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Workflow.Runtime;
usingSystem.Workflow.Activities;
usingSystem.Workflow.ComponentModel;
namespaceStateMachineService
{
[Serializable]
publicclassDocFlowEventArgs:ExternalDataEventArgs
{
publicDocFlowEventArgs(stringuserID,Guiduninstand):base(uninstand)
{
this.uninstand=uninstand;
this.userID=userID;
}
privateGuiduninstand=Guid.Empty;
publicGuidUninstand
{
get{returnthis.uninstand;}
set{this.uninstand=value;}
}
privatestringuserID=string.Empty;
publicstringUserID
{
get{returnthis.userID;}
set{this.userID=value;}
}
}
[ExternalDataExchange]
publicinterfaceIDocFlowService
{
eventEventHandler<DocFlowEventArgs>Next;
eventEventHandler<DocFlowEventArgs>Jump;
eventEventHandler<DocFlowEventArgs>Stop;
voidSetFixNextApprover(intNextStpeID,stringuninstand);
voidSetFixEnableApprover(intCurrentStpeID,stringuninstand);
voidSetAutoNextApprover();
voidSetAutoEnableApprover(stringuninstand);
voidChangeStatus();
}
[Serializable]
publicclassDocFlowService:IDocFlowService
{
IDAL.IWFreeNodeiwfreenode;
GuidT;
stringUserID;
Dictionary<string,EventHandler<DocFlowEventArgs>>list=newDictionary<string,EventHandler<DocFlowEventArgs>>();
publicvoidRaiseEventer(stringeventName,Guiduninstand,stringuserID)
{
if(list[eventName]!=null)
{
try
{
EventHandler<DocFlowEventArgs>eventHandler=list[eventName];
DocFlowEventArgsargs=newDocFlowEventArgs(userID,uninstand);
args.WaitForIdle=true;
eventHandler.Invoke(null,args);
this.T=uninstand;
this.UserID=userID;
}
catch
{
}
}
}
IDocFlowService成员#regionIDocFlowService成员
publiceventEventHandler<DocFlowEventArgs>Next
{
add
{
this.list.Add("Next",value);
}
remove
{
this.list.Remove("Next");
}
}
publiceventEventHandler<DocFlowEventArgs>Jump
{add
{
this.list.Add("Jump",value);
}
remove
{
this.list.Remove("Jump");
}
}
publiceventEventHandler<DocFlowEventArgs>Stop
{
add
{
this.list.Add("Stop",value);
}
remove
{
this.list.Remove("Stop");
}
}
publicvoidChangeStatus()
{
thrownewNotImplementedException();
}
#endregion
IDocFlowService成员#regionIDocFlowService成员
publicvoidSetFixNextApprover(intNextStpeID,stringuninstand)
{
iwfreenode=DALFactory.WFreeNode.CreateInstance();
stringscript="updateWFreeNodeset[ExceteState]=1whereUninstand='"+uninstand+"'andStepID="+NextStpeID;
iwfreenode.Update(script);
//thrownewNotImplementedException();
}
#endregion
IDocFlowService成员#regionIDocFlowService成员
publicvoidSetFixEnableApprover(intCurrentStpeID,stringuninstand)
{
iwfreenode=DALFactory.WFreeNode.CreateInstance();
stringscript="updateWFreeNodeset[ExceteState]=2whereUninstand='"+uninstand+"'anduserID='"+this.UserID+"'andStepID="+CurrentStpeID;
iwfreenode.Update(script);
//thrownewNotImplementedException();
}
#endregion
IDocFlowService成员#regionIDocFlowService成员
publicvoidSetAutoNextApprover()
{
//thrownewNotImplementedException();
}
publicvoidSetAutoEnableApprover(stringuninstand)
{
iwfreenode=DALFactory.WFreeNode.CreateInstance();
stringscript="updateWFreeNodeset[ExceteState]=2whereUninstand='"+uninstand+"'anduserID='"+this.UserID+"'";
iwfreenode.Update(script);
}
#endregion
}
}
现在支持前进,抄送(平台功能)和终止,还不支持会退和跳批。
2.数据库结构
Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->CREATETABLE[dbo].[DocFlow](
[Uninstand][uniqueidentifier]NOTNULL,
[UserID][varchar](50)NOTNULL,
[Date][datetime]NULL,
[Title][varchar](400)NULL,
[Remark][varchar](500)NULL,
[DocLevel][varchar](50)NULL,
[FlowType][varchar](10)NULL,
[Depart][varchar](50)NULL
)
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->CREATETABLE[dbo].[DocFlow](
[Uninstand][uniqueidentifier]NOTNULL,
[UserID][varchar](50)NOTNULL,
[Date][datetime]NULL,
[Title][varchar](400)NULL,
[Remark][varchar](500)NULL,
[DocLevel][varchar](50)NULL,
[FlowType][varchar](10)NULL,
[Depart][varchar](50)NULL
)
3.流程图
a.
b.
2.
3.
4.
流程代码
Code
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->usingSystem;
usingSystem.ComponentModel;
usingSystem.ComponentModel.Design;
usingSystem.Collections;
usingSystem.Drawing;
usingSystem.Linq;
usingSystem.Workflow.ComponentModel.Compiler;
usingSystem.Workflow.ComponentModel.Serialization;
usingSystem.Workflow.ComponentModel;
usingSystem.Workflow.ComponentModel.Design;
usingSystem.Workflow.Runtime;
usingSystem.Workflow.Activities;
usingSystem.Workflow.Activities.Rules;
namespaceStateMachineLibrary
{
publicpartialclassDocFlow:StateMachineWorkflowActivity
{
publicstaticDependencyPropertyDocFlowTypeProperty=DependencyProperty.Register("DocFlowType",typeof(string),typeof(DocFlow));
publicstringDocFlowType
{
get{return(string)base.GetValue(DocFlow.DocFlowTypeProperty);}
set{base.SetValue(DocFlow.DocFlowTypeProperty,value);}
}
publicstaticDependencyPropertyStepIDListProperty=DependencyProperty.Register("StepIDList",typeof(System.Collections.Generic.List<int>),typeof(DocFlow));
publicSystem.Collections.Generic.List<int>StepIDList
<!--<br /><br />Code highlighting produced by Actipro CodeHighlighter (freeware)<br />http://www.CodeHighlighter.com/<br /><br />-->usingSystem;
usingSystem.ComponentModel;
usingSystem.ComponentModel.Design;
usingSystem.Collections;
usingSystem.Drawing;
usingSystem.Linq;
usingSystem.Workflow.ComponentModel.Compiler;
usingSystem.Workflow.ComponentModel.Serialization;
usingSystem.Workflow.ComponentModel;
usingSystem.Workflow.ComponentModel.Design;
usingSystem.Workflow.Runtime;
usingSystem.Workflow.Activities;
usingSystem.Workflow.Activities.Rules;
namespaceStateMachineLibrary
{
publicpartialclassDocFlow:StateMachineWorkflowActivity
{
publicstaticDependencyPropertyDocFlowTypeProperty=DependencyProperty.Register("DocFlowType",typeof(string),typeof(DocFlow));
publicstringDocFlowType
{
get{return(string)base.GetValue(DocFlow.DocFlowTypeProperty);}
set{base.SetValue(DocFlow.DocFlowTypeProperty,value);}
}
publicstaticDependencyPropertyStepIDListProperty=DependencyProperty.Register("StepIDList",typeof(System.Collections.Generic.List<int>),typeof(DocFlow));
publicSystem.Collections.Generic.List<int>StepIDList