8.2 启动与执行业务流程
8.2.2 TaskInstance.aspx.cs文件代码:
......(续前页)
//完成任务
private void Button2_Click(object sender, System.EventArgs e)
{
//获取业务表名称、标识字段名、标识字段值等
string relatedtable=ds.Tables[1].Rows[0]["RelatedTable"].ToString();
string identityfield=identityname.Tables[0].Rows[0]["IdentifiedField"].ToString();
string fieldvalue=ds.Tables[1].Rows[0]["IdentityFieldValue"].ToString();
string processinstanceid=ds.Tables[1].Rows[0]["ProcessInstanceID"].ToString();
string processdefid=ds.Tables[1].Rows[0]["ProcessDefinitionID"].ToString();
//保存可编辑字段的值
if(! Savefields(relatedtable,identityfield,fieldvalue,processinstanceid))
return;
//保存留言
if(! saveMessage(processinstanceid))
return;
//处理附件上传
if(ds.Tables[0].Rows[0]["AboutAttached"].ToString().Trim() == "L"
|| ds.Tables[0].Rows[0]["AboutAttached"].ToString().Trim() == "LR")
{
if(! SaveAttached(processinstanceid,relatedtable,identityfield,fieldvalue))
return;
}
//判断流程是否已经被冻结(防止在此时管理员刚进行了冻结操作),如果已经冻结则不再执
//行后续操作。
string strSql="select IsSuspended from ProcessInstance where ProcessInstanceID="
+processinstanceid;
Base basecode=new Base();
DataSet suspendds=basecode.SQLExeDataSet(strSql);
if(suspendds.Tables[0].Rows[0]["IsSuspended"].ToString()=="Y")
Response.Redirect("TaskInstanceList.aspx");
//当前节点的逻辑类型
string nodelogic=ViewState["NodeLogic"].ToString();
//当前节点ID
string nodedefid=ViewState["taskID"].ToString();
//当前节点名称
TaskDefinitionClass taskdefobject=new TaskDefinitionClass();
string taskname=taskdefobject.GetTaskNameByID(nodedefid);
//判断当前任务是否是回退任务(有后续任务实例)
TaskInstanceClass taskins=new TaskInstanceClass();
string taskinstanceid=ViewState["taskinstanceid"].ToString();
if(taskins.IsPostedBackTask(taskinstanceid))
{
//OrSplit节点会隐藏"完成任务"按钮,不调用当前方法.其它节点类型执行下面代码.
//获取当前实例的所有后继
string [] nextinsIDs=new Tools().StringSplit(taskins
.GetNextTaskinstancesID(taskinstanceid),",");
//不需判断当前任务实例的类型,只需判断其后继是否是并行连接节点(如果是,则后继
//只有一个,因此只需取第一个后继判断)。如果是,还要判断连接节点的其它前驱是否已
//完成.
string tempnexttaskid=taskins.GetTaskDefinitionID(nextinsIDs[0]);
string tempnexttasklogic=taskdefobject.GetLogicTypeOfNode(tempnexttaskid);
//如果后继实例是并行分支的连接节点,则判断该连接节点的所有前驱是否都完成
if(tempnexttasklogic == "AndJoin" || tempnexttasklogic == "AndJoin&AndSplit"
|| tempnexttasklogic == "AndJoin&OrSplit")
{
string[] preinsids=new Tools().StringSplit(taskins
.GetPreTaskinstancesID(nextinsIDs[0]),",");
bool othercompleted=true;
for(int i=0;i<preinsids.Length;i++)
{
//如果除当前实例之外,并行节点还有未完成的前驱实例
if(preinsids[i] != taskinstanceid
& taskins.GetTaskInsState(preinsids[i]) != "Completed")
{
othercompleted=false;
break;
}
}
//如果连接节点其它前驱都已完成,修改并行节点任务实例状态
if(othercompleted)
taskins.UpDateTaskInstanceState(nextinsIDs[0],"Running");
//修改当前实例状态,结束当前回退任务的执行.
taskins.UpDateTaskInstanceState(taskinstanceid,"Completed");
}
//如果后继不是并行连接节点则修改所有后继的状态(如andsplit就有多个后继)
else
{
for(int i=0;i<nextinsIDs.Length;i++)
{
//修改后继实例状态,是后继任务得以重新被执行.
taskins.UpDateTaskInstanceState(nextinsIDs[i],"Running");
}
//修改当前实例状态,结束当前回退任务的执行.
taskins.UpDateTaskInstanceState(taskinstanceid,"Completed");
}
}
//不是回退任务的情况(实际上,以下代码可以参照回退任务处理方法精简,即只判断其第一
//个后继,根据后继为并行连接节点和结束节点两种情况处理。当然下面代码更容易理解)
else
{
//OrSplit节点执行迁移按钮方法,不在此处理
//如果当前是一般任务节点
Transition trans=new Transition();
DataSet nextnodeds=null;
string nextnodename="";
if(nodelogic == "")
{
//获取当前节点的下一节点
nextnodeds=trans.GetNextNodesName(taskname,processdefid);
//判断当前节点的下一节点类型.一般任务节点只能有一个后继.
nextnodename=nextnodeds.Tables[0].Rows[0]["ToNodeName"].ToString();
//如果是结束节点
if(taskdefobject.IsEndNode(nextnodename,processdefid))
{