5、任务实例类(TaskInstanceClass)及主要方法函数 为方便读者理解,在阅读以下代码时,请参考本章(一)中对核心程序逻辑的分析。
......
using DataAccess;//引用数据访问组件
using UserResourceManagement;//用户及资源权限管理组件
using CommonTools;//工具类组件
namespace WFEngine
{
public class TaskInstanceClass
{
private string ErrDes = "";//记录操作异常的私有变量
public TaskInstanceClass(){}//空的构造函数
//记录异常的公共属性
public string TaskInstancesErrDes
{
get
{
return ErrDes;
}
}
//创建任务实例
public int CreateTaskInstance(string processinstanceid,string
taskdefinitionid,string starttime)
{
//插入一条新的任务实例记录
string strSql="insert into TaskInstance(ProcessInstanceID,
TaskDefinitionID,StartTime,TaskState) values("+processinstanceid
+","+taskdefinitionid+",'"+starttime+"','Just Created')";
Base basecode=new Base();
if(! basecode.SQLExeNonQuery(strSql))
{
ErrDes="创建任务实例失败!";
return -1;
}
//返回刚插入的任务实例编号
strSql="select TaskInstanceID from TaskInstance where ProcessInstanceID
="+processinstanceid+" and TaskDefinitionID="+taskdefinitionid;
DataSet ds=basecode.SQLExeDataSet(strSql);
string taskinstanceid=ds.Tables[0].Rows[0]["TaskInstanceID"].ToString();
return int.Parse(taskinstanceid);
}
//根据登录用户编号获取用户可以处理的任务实例列表
public DataSet getTaskListByUserID(string userID)
{
//获取分配给用户的所有角色
DataSet rolesds=new UserManagement().GetRoles(userID);
if(rolesds == null || rolesds.Tables[0].Rows.Count<1)
{
ErrDes=ErrDes+"用户未被赋予任何角色权限,请与管理员联系!";
return null;
}
//根据用户角色获取用户可以操作的任务实例集合,包括任务实例编号、对应的任务定
//义编号、所属过程实例编号、过程实例描述、任务名称、当前实例是否为回退的任
//务实例、任务实例的创建日期等字段.
string strSql="select TaskInstanceID,TaskDefinitionID,ProcessInstanceID,
(select Description from ProcessInstance where ProcessInstanceId
=a.ProcessInstanceId) as processdesc,(select TaskName from
TaskDefinition where TaskID=a.TaskDefinitionID) as taskname,
(case when NextTaskInstance is null then '' else '流程回退的任
务' end) as IsPostedBack,CONVERT(varchar(10), StartTime, 120)
as startdate from TaskInstance a where ((a.TaskState ='Just
Created' and (select AssignedRole from TaskDefinition where
TaskID=a.TaskDefinitionID)
in("+rolesds.Tables[0].Rows[0]["RoleID"].ToString();
for(int i=1;i<rolesds.Tables[0].Rows.Count;i++)
strSql=strSql+","+rolesds.Tables[0].Rows[i]["RoleID"].ToString();
strSql=strSql+")) or (a.TaskState='Running'and a.TaskUserID="+userID+"))
and (a.ProcessInstanceID in (select b.ProcessInstanceID from "
+"ProcessInstance b where (b.IsSuspended is null or
b.IsSuspended='') and b.IsCanceled is null))";
//sql语句将逐条查询任务实例记录. 部分为查询条件,判断当前记录是否是刚创建
//的任务实例而且登录用户具有对应的任务角色权限; 部分的查询条件则判断当前
//实例是否是正在运行的任务实例(已经被用户选择并正在处理的任务),而且登录
//用户是否正是拾起了该任务实例的用户; 则判断当前过程实例没有被冻结或取
//消(冻结或取消的过程实例不能再继续进行)。
DataSet ds=new Base().SQLExeDataSet(strSql);
return ds;
}
//获取任务ID
public string GetTaskDefinitionID(string taskInstanceID)
......
//获取流程实例ID
public string GetProcessInstanceID(string taskInstanceID)
......
//获取任务完成状态
public string GetTaskInsState(string taskInstanceID)
{
string strSql1="select TaskState from TaskInstance where
TaskInstanceID="+taskInstanceID;
......
}
//获取任务实例的前驱任务实例列表,供用户选择过程要回退到哪个任务环节(参考本章图
//4.3的程序逻辑)
public DataSet GetPreTaskInstancesList(string taskInstanceID,string
processInstanceID)
{
ErrDes="";
//判断当前任务实例是否存在前驱实例
if(! IfExistPreInstances(taskInstanceID))
return null;
//对以下sql语句的分析:在列表显示当前任务实例的前驱任务实例,供用户选择回退
//时,列表中要包含任务实例编号、任务名称加任务完成人的姓名两个字段。下面sql
//语句是以当前任务实例为样板得到一个数据集格式,并克隆出一个空的同构数据
//集,以存储后面语句将获得的当前任务实例的可回退前驱实例数据集。
string tasklist="select TaskInstanceID,(select TaskName from
TaskDefinition where TaskID=TaskDefinitionID)+' '+((select
EmployeeName from Employees where EmployeeID=(select EmployeeID from
Users where UserID=TaskUserID)) as taskuser from TaskInstance where
TaskInstanceID="+taskInstanceID+" and ProcessInstanceID="
+processInstanceID;
Base basecode=new Base();
DataSet tempds=basecode.SQLExeDataSet(tasklist);//临时数据集,作为样板
DataSet postedbackds=tempds.Clone();//根据样板克隆一个空的回退实例数据集
//设置临时变量
string tempinstance=taskInstanceID;//设置临时实例编号为当前实例
string tempdefine=GetTaskDefinitionID(taskInstanceID);//临时任务定义编号
string temppreinsids =null;//临时前驱实例编号
//初始化任务定义对象
TaskDefinitionClass task=new TaskDefinitionClass();
//从当前任务实例开始循环判断任务实例是否存在前驱实例
while(IfExistPreInstances(tempinstance))
{
//如果当前实例对应的任务包含过程路由属性(既是任务节点又是逻辑节点)
if(task.IsLogicNode(tempdefine))
{
//将早于当前实例创建的所有任务实例添加到回退实例列表中
tasklist="select TaskInstanceID,(select TaskName from
TaskDefinition where TaskID=TaskDefinitionID)+' '+((select
EmployeeName from Employees where EmployeeID=(select EmployeeID
fromUsers where UserID=TaskUserID)) as taskuser from TaskInstance
where TaskInstanceID<"+tempinstance+" and
ProcessInstanceID="+processInstanceID;
tempds=basecode.SQLExeDataSet(tasklist);//重新为临时数据集赋值
//将临时数据集的每一行添加到回退任务实例数据集中
for(int i=0;i<tempds.Tables[0].Rows.Count;i++)
{
//以postedbackds为样板初始化一个新数据行对象
DataRow newrow=postedbackds.Tables[0].NewRow();
newrow["TaskInstanceID"]=tempds.Tables[0].Rows[i]["TaskInstanceID"]
.ToString();
newrow["taskuser"]=tempds.Tables[0].Rows[i]["taskuser"].ToString();
postedbackds.Tables[0].Rows.Add(newrow);
}
//当前实例为逻辑节点则中断循环,结束程序
break;
}
//如果当前实例不是逻辑节点
else
{
//获取当前实例的前驱任务实例编号
temppreinsids=GetPreTaskinstancesID(tempinstance);
//获取临时实例的数据记录
tasklist="select TaskInstanceID,(select TaskName from
TaskDefinition where TaskID=TaskDefinitionID)+' '+((select
EmployeeName from Employees where EmployeeID=(select EmployeeID
fromUsers where UserID=TaskUserID)) as taskuser from
TaskInstance where TaskInstanceID="+temppreinsids;
tempds=basecode.SQLExeDataSet(tasklist);
//初始化新的数据行对象
DataRow newrow=postedbackds.Tables[0].NewRow();
//将临时实例记录赋值给数据行对象
newrow["TaskInstanceID"]=tempds.Tables[0].Rows[0]["TaskInstanceID"]
.ToString();
newrow["taskuser"]=tempds.Tables[0].Rows[0]["taskuser"].ToString();
//将数据行添加到回退列表中
postedbackds.Tables[0].Rows.Add(newrow);
//重新设置临时实例(当前实例)为前驱实例编号,以进入下一轮循环判断.
tempinstance=temppreinsids;
//获取临时实例(当前实例)的任务定义编号,用于再次循环判断节点逻辑属性.
tempdefine=GetTaskDefinitionID(tempinstance);
}
}//进行下一循环
return postedbackds;
}
//判断当前任务实例是否存在前驱实例
public bool IfExistPreInstances(string taskInstanceID)
{
string strSql="select isnull(PreTaskInstance,'') as pretaskins from
TaskInstance where TaskInstanceID="+taskInstanceID;
......
if(ds.Tables[0].Rows[0][0].ToString() != "")
return true;
else
return false;
}
//获取当前任务实例的前驱实例列表字串
public string GetPreTaskinstancesID(string taskInstanceID)
{
string strSql="select isnull(PreTaskInstance,'') as pretaskids from
TaskInstance where TaskInstanceID="+taskInstanceID;
......
return ds.Tables[0].Rows[0]["pretaskids"].ToString();
}
//获取当前任务实例的后继实例列表字串
public string GetNextTaskinstancesID(string taskInstanceID)
{
string strSql="select isnull(NextTaskInstance,'') as nexttaskids from
TaskInstance where TaskInstanceID="+taskInstanceID;
......
return ds.Tables[0].Rows[0]["nexttaskids"].ToString();
}
//获取为任务分配的角色ID
public string GetAssignedRole(string taskInstanceID)
{
TaskDefinitionClass taskdef=new TaskDefinitionClass();
return taskdef.GetAssignedRole(GetTaskDefinitionID(taskInstanceID));
}
//获取处理任务的用户
public string GetTaskUser(string taskInstanceID)
{
string assigneduser="select TaskUserID from TaskInstance where
TaskInstanceID="+taskInstanceID;
Base basecode=new Base();
DataSet userds=basecode.SQLExeDataSet(assigneduser);
if(userds.Tables[0].Rows[0]["TaskUserID"] == DBNull.Value)
return null;
else
return userds.Tables[0].Rows[0]["TaskUserID"].ToString();
}
//任务是否被拾起
public bool IfTaskIsPicked(string taskInstanceID)
{
string assigneduser="select TaskUserID from TaskInstance where
TaskInstanceID="+taskInstanceID;
......
if(userds.Tables[0].Rows[0]["TaskUserID"] == DBNull.Value)
return false;
else
return true;
}
//任务的抢占(拾起)
public bool PickTask(string userID,string taskInstanceID)
{
string assignuser="update TaskInstance set TaskUserID="+userID+",
TaskState='Running' where TaskInstanceID="+taskInstanceID;
Base basecode=new Base();
//使用事务处理,以保证立即提交事务.
if(! basecode.ExeSQLNoResultTransaction(assignuser))
{
ErrDes=basecode.BaseSqlErrDes;
return false;
}
return true;
}
//完成任务实例
public bool AchieveTask( string taskinsid)
{
string endtime=DateTime.Now.ToString();
string strSql="update TaskInstance set EndTime='"+endtime+"' where
TaskInstanceID="+taskinsid;
Base basecode=new Base();
if(! basecode.ExeSQLNoResultTransaction(strSql))
{
ErrDes=basecode.BaseSqlErrDes;;
return false;
}
return true;
}
//回退任务实例(为方便编程,该功能被放在任务处理页面aspx程序中完成)
public bool PostProcessBack()
......
//临时保存任务(为方便编程,该功能被放在任务处理页面aspx程序中完成)
public bool SaveTaskInstance()
......
//判断当前任务是否是回退任务
public bool IsPostedBackTask(string taskInstanceID)
{
string strSql="select isnull(NextTaskInstance,'') as nexttaskins,TaskState
from TaskInstance where TaskInstanceID="+taskInstanceID;
......
if(ds.Tables[0].Rows[0]["nexttaskins"].ToString().Trim() != "" & ds.
Tables[0].Rows[0]["TaskState"].ToString() == "Running")
return true;
else
return false;
}
//修改回退任务的下一任务实例的运行状态
public bool UpDateTaskInstanceState(string taskinstanceID,string taskstate)
{
string strSql="update TaskInstance set TaskState='"+taskstate+"' where
TaskInstanceID="+taskinstanceID;
......
}
//判断任务是否被实例化
public bool IsTaskInstantiatedAndCompleted(string taskID,string processinsID)
{
string strSql="select TaskInstanceID from TaskInstance where
TaskDefinitionID="+taskID+" and ProcessInstanceID="+processinsID+"
and TaskState='Completed'";
Base basecode=new Base();
if(basecode.IfExistRecord(strSql))
return true;
else
return false;
}