第四章 工作流引擎的设计与实现(五)

来源:互联网 发布:荣耀盒子推荐软件 编辑:程序博客网 时间:2024/04/29 23:52
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;
              }

原创粉丝点击