/// <summary> /// 取消相邻分支节点 /// </summary> /// <param name="toActivity">退回到的节点</param> /// <param name="fromActivityInstance">退回前的运行节点</param> /// <param name="runner">运行者</param> /// <param name="session">数据会话</param> private void CancelBrothersNode(ActivityEntity toActivity, ActivityInstanceEntity fromActivityInstance, WfAppRunner runner, IDbSession session) { var processModel = this.SendBackOperation.ProcessModel; var activityList = processModel.GetNextActivityListWithoutCondition(toActivity.ActivityGUID); var brothersList = activityList.Where(a => a.ActivityGUID != fromActivityInstance.ActivityGUID).ToList(); foreach (var activity in brothersList) { var activityInstance = this.ActivityInstanceManager.GetActivityInstanceLatest(fromActivityInstance.ProcessInstanceID, activity.ActivityGUID, session); if (activityInstance != null && this.ActivityInstanceManager.IncludeRunningState(activityInstance) == true) { this.ActivityInstanceManager.Cancel(activityInstance.ID, runner, session); } } }
/// <summary> /// 插入连线实例的方法 /// </summary> /// <param name="processInstance">流程实例</param> /// <param name="transitionGUID">转移ID</param> /// <param name="fromActivityInstance">起始活动实例</param> /// <param name="toActivityInstance">到达活动实例</param> /// <param name="transitionType">转移类型</param> /// <param name="flyingType">跳跃类型</param> /// <param name="runner">执行者</param> /// <param name="session">Session</param> internal virtual void InsertTransitionInstance(ProcessInstanceEntity processInstance, String transitionGUID, ActivityInstanceEntity fromActivityInstance, ActivityInstanceEntity toActivityInstance, TransitionTypeEnum transitionType, TransitionFlyingTypeEnum flyingType, WfAppRunner runner, IDbSession session) { var tim = new TransitionInstanceManager(); var transitionInstanceObject = tim.CreateTransitionInstanceObject(processInstance, transitionGUID, fromActivityInstance, toActivityInstance, transitionType, flyingType, runner, (byte)ConditionParseResultEnum.Passed); tim.Insert(session.Connection, transitionInstanceObject, session.Transaction); }
/// <summary> /// 创建退回时的流转节点对象、任务和转移数据 /// </summary> /// <param name="processInstance">流程实例</param> /// <param name="fromActivityInstance">运行节点实例</param> /// <param name="backwardType">退回类型</param> /// <param name="transitionGUID">转移GUID</param> /// <param name="transitionType">转移类型</param> /// <param name="flyingType">跳跃类型</param> /// <param name="activityResource">资源</param> /// <param name="session">会话</param> internal void CreateBackwardActivityTaskTransitionInstance(ProcessInstanceEntity processInstance, ActivityInstanceEntity fromActivityInstance, BackwardTypeEnum backwardType, string transitionGUID, TransitionTypeEnum transitionType, TransitionFlyingTypeEnum flyingType, ActivityResource activityResource, IDbSession session) { //实例化Activity var toActivityInstance = base.CreateBackwardToActivityInstanceObject(processInstance, backwardType, fromActivityInstance.ID, base.BackwardContext.BackwardToTaskActivityInstance.ID, activityResource.AppRunner); //进入准备运行状态 toActivityInstance.ActivityState = (short)ActivityStateEnum.Ready; toActivityInstance = GenerateActivityAssignedUserInfo(toActivityInstance, activityResource); //插入活动实例数据 base.ActivityInstanceManager.Insert(toActivityInstance, session); base.ReturnDataContext.ActivityInstanceID = toActivityInstance.ID; base.ReturnDataContext.ProcessInstanceID = toActivityInstance.ProcessInstanceID; //插入任务数据 base.CreateNewTask(toActivityInstance, activityResource, session); //插入转移数据 base.InsertTransitionInstance(processInstance, transitionGUID, fromActivityInstance, toActivityInstance, transitionType, flyingType, activityResource.AppRunner, session); }
/// <summary> /// 创建退回时的流转节点对象、任务和转移数据 /// </summary> /// <param name="processInstance"></param> /// <param name="fromActivityInstance"></param> /// <param name="backMostPreviouslyActivityInstanceID"></param> /// <param name="transitionGUID"></param> /// <param name="transitionType"></param> /// <param name="flyingType"></param> /// <param name="activityResource"></param> /// <param name="session"></param> internal void CreateBackwardActivityTaskTransitionInstance(ProcessInstanceEntity processInstance, ActivityInstanceEntity fromActivityInstance, BackwardTypeEnum backwardType, int backMostPreviouslyActivityInstanceID, string transitionGUID, TransitionTypeEnum transitionType, TransitionFlyingTypeEnum flyingType, ActivityResource activityResource, IDbSession session) { //实例化Activity var toActivityInstance = base.CreateBackwardToActivityInstanceObject(processInstance, backwardType, backMostPreviouslyActivityInstanceID, activityResource.AppRunner); //进入准备运行状态 toActivityInstance.ActivityState = (short)ActivityStateEnum.Ready; toActivityInstance.AssignedToUserIDs = base.GenerateActivityAssignedUserIDs( activityResource.NextActivityPerformers[base.BackwardContext.BackwardToTaskActivity.ActivityGUID]); toActivityInstance.AssignedToUserNames = base.GenerateActivityAssignedUserNames( activityResource.NextActivityPerformers[base.BackwardContext.BackwardToTaskActivity.ActivityGUID]); //插入活动实例数据 base.ActivityInstanceManager.Insert(toActivityInstance, session); //插入任务数据 base.CreateNewTask(toActivityInstance, activityResource, session); //插入转移数据 base.InsertTransitionInstance(processInstance, transitionGUID, fromActivityInstance, toActivityInstance, transitionType, flyingType, activityResource.AppRunner, session); }
public GatewayExecutedResult CompleteAutomaticlly(ProcessInstanceEntity processInstance, TransitionEntity fromToTransition, ActivityInstanceEntity fromActivityInstance, ActivityResource activityResource, ISession session) { //开始节点没前驱信息 var toActivityInstance = base.CreateActivityInstanceObject(processInstance, activityResource.LogonUser); base.InsertActivityInstance(toActivityInstance, session); base.CompleteActivityInstance(toActivityInstance.ActivityInstanceGUID, activityResource, session); SyncActivityInstanceObjectState(NodeStateEnum.Completed); GatewayExecutedResult result = GatewayExecutedResult.CreateGatewayExecutedResult(GatewayExecutedStatus.Successed); return(result); }
/// <summary> /// 自动完成 /// </summary> /// <param name="processInstance">流程实例</param> /// <param name="transitionGUID">转移GUID</param> /// <param name="fromActivity">起始活动</param> /// <param name="fromActivityInstance">起始活动实例</param> /// <param name="runner">运行者</param> /// <param name="session">会话</param> /// <returns>网关执行结果</returns> public NodeAutoExecutedResult CompleteAutomaticlly(ProcessInstanceEntity processInstance, string transitionGUID, ActivityEntity fromActivity, ActivityInstanceEntity fromActivityInstance, WfAppRunner runner, IDbSession session) { NodeAutoExecutedResult result = NodeAutoExecutedResult.CreateGatewayExecutedResult(NodeAutoExecutedStatus.Unknown); //XOrJoin合并,直接置为完成状态,因为始终只有一个分支可以得到执行,其它分支被排斥 var gatewayActivityInstance = base.CreateActivityInstanceObject(base.GatewayActivity, processInstance, runner); gatewayActivityInstance.GatewayDirectionTypeID = (short)GatewayDirectionEnum.XOrJoin; base.InsertActivityInstance(gatewayActivityInstance, session); base.CompleteActivityInstance(gatewayActivityInstance.ID, runner, session); gatewayActivityInstance.ActivityState = (short)ActivityStateEnum.Completed; base.GatewayActivityInstance = gatewayActivityInstance; //写节点转移实例数据 base.InsertTransitionInstance(processInstance, transitionGUID, fromActivityInstance, gatewayActivityInstance, TransitionTypeEnum.Forward, TransitionFlyingTypeEnum.NotFlying, runner, session); result = NodeAutoExecutedResult.CreateGatewayExecutedResult(NodeAutoExecutedStatus.Successed); return(result); }
/// <summary> /// 生成活动用户分配信息 /// </summary> /// <param name="toActivityInstance">下一步活动实例</param> /// <param name="activityResource">活动资源</param> /// <returns>下一步活动实例</returns> protected ActivityInstanceEntity GenerateActivityAssignedUserInfo(ActivityInstanceEntity toActivityInstance, ActivityResource activityResource) { if (activityResource.AppRunner.NextPerformerType == NextPerformerIntTypeEnum.Specific && activityResource.NextActivityPerformers != null) { //前端显式指定下一步骤的执行用户列表 toActivityInstance.AssignedToUserIDs = PerformerBuilder.GenerateActivityAssignedUserIDs( activityResource.NextActivityPerformers[toActivityInstance.ActivityGUID]); toActivityInstance.AssignedToUserNames = PerformerBuilder.GenerateActivityAssignedUserNames( activityResource.NextActivityPerformers[toActivityInstance.ActivityGUID]); } else if (activityResource.AppRunner.NextPerformerType == NextPerformerIntTypeEnum.Definition) { //根据节点上的角色定义获取下一步骤的执行用户列表 var performers = ActivityForwardContext.ProcessModel.GetActivityPerformers(toActivityInstance.ActivityGUID); activityResource.NextActivityPerformers = performers; toActivityInstance.AssignedToUserIDs = PerformerBuilder.GenerateActivityAssignedUserIDs( performers[toActivityInstance.ActivityGUID]); toActivityInstance.AssignedToUserNames = PerformerBuilder.GenerateActivityAssignedUserNames( performers[toActivityInstance.ActivityGUID]); } else if (activityResource.AppRunner.NextPerformerType == NextPerformerIntTypeEnum.Single) { //用于测试使用的单一用户列表 activityResource.NextActivityPerformers = ActivityResource.CreateNextActivityPerformers(toActivityInstance.ActivityGUID, activityResource.AppRunner.UserID, activityResource.AppRunner.UserName); toActivityInstance.AssignedToUserIDs = activityResource.AppRunner.UserID; toActivityInstance.AssignedToUserNames = activityResource.AppRunner.UserName; } else { throw new ApplicationException(LocalizeHelper.GetEngineMessage("nodemediator.generateactivityassigneduserinfo.warn")); } return(toActivityInstance); }
/// <summary> /// 根据主节点复制子节点 /// </summary> /// <param name="main"></param> /// <returns></returns> internal ActivityInstanceEntity CreateActivityInstanceObject(ActivityInstanceEntity main) { ActivityInstanceEntity instance = new ActivityInstanceEntity(); instance.ActivityGUID = main.ActivityGUID; instance.ActivityName = main.ActivityName; instance.ActivityType = main.ActivityType; instance.GatewayDirectionTypeID = main.GatewayDirectionTypeID; instance.ProcessGUID = main.ProcessGUID; instance.AppName = main.AppName; instance.AppInstanceID = main.AppInstanceID; instance.ProcessInstanceID = main.ProcessInstanceID; instance.TokensRequired = 1; instance.TokensHad = 1; instance.CreatedByUserID = main.CreatedByUserID; instance.CreatedByUserName = main.CreatedByUserName; instance.CreatedDateTime = System.DateTime.Now; instance.ActivityState = (short)ActivityStateEnum.Ready; instance.CanRenewInstance = 0; return(instance); }
/// <summary> /// 获取活动节点实例 /// </summary> /// <param name="appInstanceID"></param> /// <param name="processGUID"></param> /// <param name="activityGUID"></param> /// <returns></returns> internal ActivityInstanceEntity GetActivityInstanceLatest(string appInstanceID, string processGUID, string activityGUID) { var sql = @"SELECT * FROM WfActivityInstance WHERE AppInstanceID = @appInstanceID AND ProcessGUID = @processGUID AND ActivityGUID = @activityGUID ORDER BY ID DESC"; ActivityInstanceEntity activityInstance = null; var conn = SessionFactory.CreateConnection(); try { var instanceList = Repository.Query <ActivityInstanceEntity>(conn, sql, new { appInstanceID = appInstanceID, processGUID = processGUID.ToString(), activityGUID = activityGUID.ToString() }).ToList(); if (instanceList.Count > 0) { activityInstance = instanceList[0]; } } finally { if (conn != null) { conn.Close(); } } return(activityInstance); }
/// <summary> /// 根据流程定义,创建新的流程实例 /// </summary> /// <param name="runner">运行者</param> /// <param name="processEntity">流程定义</param> /// <param name="parentProcessInstance">父流程实例</param> /// <param name="subProcessNode">子流程节点</param> /// <returns>流程实例的ID</returns> internal ProcessInstanceEntity CreateNewProcessInstanceObject(WfAppRunner runner, ProcessEntity processEntity, ProcessInstanceEntity parentProcessInstance = null, ActivityInstanceEntity subProcessNode = null) { ProcessInstanceEntity entity = new ProcessInstanceEntity(); entity.ProcessGUID = processEntity.ProcessGUID; entity.ProcessName = processEntity.ProcessName; entity.Version = processEntity.Version; entity.AppName = runner.AppName; entity.AppInstanceID = runner.AppInstanceID; entity.AppInstanceCode = runner.AppInstanceCode; entity.ProcessState = (int)ProcessStateEnum.Running; if (parentProcessInstance != null) { //流程的Parent信息 entity.ParentProcessInstanceID = parentProcessInstance.ID; entity.ParentProcessGUID = parentProcessInstance.ProcessGUID; entity.InvokedActivityInstanceID = subProcessNode.ID; entity.InvokedActivityGUID = subProcessNode.ActivityGUID; } entity.CreatedByUserID = runner.UserID; entity.CreatedByUserName = runner.UserName; entity.CreatedDateTime = System.DateTime.Now; //过期时间设置 if (processEntity.EndType == (short)ProcessEndTypeEnum.Timer) { entity.OverdueDateTime = CalculateOverdueDateTime(entity.CreatedDateTime, processEntity.EndExpression); } entity.LastUpdatedByUserID = runner.UserID; entity.LastUpdatedByUserName = runner.UserName; entity.LastUpdatedDateTime = System.DateTime.Now; return(entity); }
/// <summary> /// 插入活动实例 /// </summary> /// <param name="entity">实体</param> /// <param name="session">会话</param> /// <returns>新的自增长ID键值</returns> internal int Insert(ActivityInstanceEntity entity, IDbSession session) { //SET ActivityName When It Is NULL if (entity.ActivityType == (short)ActivityTypeEnum.GatewayNode && string.IsNullOrEmpty(entity.ActivityName)) { entity.ActivityName = "GATEWAY"; } try { var repository = session.GetRepository <ActivityInstanceEntity>(); var newEntity = repository.Insert(entity); session.SaveChanges(); int newID = newEntity.ID; return(newID); } catch (Exception ex) { string exstr = ex.ToString(); return(-1); } }
/// <summary> /// 插入连线实例的方法 /// </summary> /// <param name="processInstance">流程实例</param> /// <param name="fromActivityInstance">起始活动实例</param> /// <param name="toActivityInstance">到达活动实例</param> /// <param name="transitionType">转移类型</param> /// <param name="flyingType">跳跃类型</param> /// <param name="runner">执行者</param> /// <param name="session">Session</param> /// <returns>新转移实例ID</returns> internal virtual int InsertTransitionInstance(ProcessInstanceEntity processInstance, ActivityInstanceEntity fromActivityInstance, ActivityInstanceEntity toActivityInstance, TransitionTypeEnum transitionType, TransitionFlyingTypeEnum flyingType, WfAppRunner runner, IDbSession session) { var transition = SendBackOperation.ProcessModel.GetForwardTransition(toActivityInstance.ActivityGUID, fromActivityInstance.ActivityGUID); var transitionGUID = transition != null ? transition.TransitionGUID : WfDefine.WF_XPDL_SEND_BACK_UNKNOWN_GUID; var transitionInstanceObject = this.TransitionInstanceManager.CreateTransitionInstanceObject(processInstance, transitionGUID, fromActivityInstance, toActivityInstance, transitionType, flyingType, runner, (byte)ConditionParseResultEnum.Passed); var newID = this.TransitionInstanceManager.Insert(session.Connection, transitionInstanceObject, session.Transaction); return(newID); }
/// <summary> /// 自动完成 /// </summary> /// <param name="processInstance">流程实例</param> /// <param name="transitionGUID">转移GUID</param> /// <param name="fromActivityInstance">起始活动实例</param> /// <param name="activityResource">活动资源</param> /// <param name="session">会话</param> /// <returns>网关执行结果</returns> public GatewayExecutedResult CompleteAutomaticlly(ProcessInstanceEntity processInstance, string transitionGUID, ActivityInstanceEntity fromActivityInstance, ActivityResource activityResource, IDbSession session) { //插入实例数据 var gatewayActivityInstance = base.CreateActivityInstanceObject(base.GatewayActivity, processInstance, activityResource.AppRunner); gatewayActivityInstance.GatewayDirectionTypeID = (short)GatewayDirectionEnum.AndSplit; base.InsertActivityInstance(gatewayActivityInstance, session); base.CompleteActivityInstance(gatewayActivityInstance.ID, activityResource, session); gatewayActivityInstance.ActivityState = (short)ActivityStateEnum.Completed; base.GatewayActivityInstance = gatewayActivityInstance; //写节点转移实例数据 base.InsertTransitionInstance(processInstance, transitionGUID, fromActivityInstance, gatewayActivityInstance, TransitionTypeEnum.Forward, TransitionFlyingTypeEnum.NotFlying, activityResource.AppRunner, session); GatewayExecutedResult result = GatewayExecutedResult.CreateGatewayExecutedResult(GatewayExecutedStatus.Successed); return(result); }
/// <summary> /// 创建转移实例数据 /// </summary> /// <param name="processInstance">流程实例</param> /// <param name="transitionGUID">转移GUID</param> /// <param name="fromActivityInstance">来源活动实例</param> /// <param name="toActivityInstance">目的活动实例</param> /// <param name="transitionType">转移类型</param> /// <param name="flyingType">飞越类型</param> /// <param name="runner">执行者</param> /// <param name="conditionParseResult">条件解析结果</param> /// <returns>转移实例</returns> internal TransitionInstanceEntity CreateTransitionInstanceObject(ProcessInstanceEntity processInstance, String transitionGUID, ActivityInstanceEntity fromActivityInstance, ActivityInstanceEntity toActivityInstance, TransitionTypeEnum transitionType, TransitionFlyingTypeEnum flyingType, WfAppRunner runner, byte conditionParseResult) { var entity = new TransitionInstanceEntity(); entity.AppName = processInstance.AppName; entity.AppInstanceID = processInstance.AppInstanceID; entity.ProcessGUID = processInstance.ProcessGUID; entity.ProcessInstanceID = processInstance.ID; entity.TransitionGUID = transitionGUID; entity.TransitionType = (byte)transitionType; entity.FlyingType = (byte)flyingType; //构造活动节点数据 entity.FromActivityGUID = fromActivityInstance.ActivityGUID; entity.FromActivityInstanceID = fromActivityInstance.ID; entity.FromActivityType = fromActivityInstance.ActivityType; entity.FromActivityName = fromActivityInstance.ActivityName; entity.ToActivityGUID = toActivityInstance.ActivityGUID; entity.ToActivityInstanceID = toActivityInstance.ID; entity.ToActivityType = toActivityInstance.ActivityType; entity.ToActivityName = toActivityInstance.ActivityName; entity.ConditionParseResult = conditionParseResult; entity.CreatedByUserID = runner.UserID; entity.CreatedByUserName = runner.UserName; entity.CreatedDateTime = System.DateTime.Now; return(entity); }
/// <summary> /// 退回是会签情况下的处理: /// 要退回的节点是会签节点 /// 1) 全部实例化会签节点下的多实例节点 /// 2) 只取得办理完成的节点,而且保证CompleteOrder的唯一性 /// </summary> /// <param name="processInstance">流程实例</param> /// <param name="backwardToTaskActvity">退回到的活动节点</param> /// <param name="fromActivityInstance">运行节点</param> /// <param name="backwardType">退回类型</param> /// <param name="previousMainInstance">前主节点实例</param> /// <param name="transitionGUID">转移GUID</param> /// <param name="transitionType">转移类型</param> /// <param name="flyingType">跳跃类型</param> /// <param name="activityResource">资源</param> /// <param name="session">会话</param> internal void CreateBackwardActivityTaskRepeatedSignTogetherMultipleInstance(ProcessInstanceEntity processInstance, ActivityEntity backwardToTaskActvity, ActivityInstanceEntity fromActivityInstance, BackwardTypeEnum backwardType, ActivityInstanceEntity previousMainInstance, string transitionGUID, TransitionTypeEnum transitionType, TransitionFlyingTypeEnum flyingType, ActivityResource activityResource, IDbSession session) { //上一步节点是会签节点的退回处理 //需要重新实例化会签节点上的所有办理人的任务 //重新封装任务办理人为AssignedToUsers, AssignedToUsernames var performerList = AntiGenerateActivityPerformerList(previousMainInstance); activityResource.NextActivityPerformers.Clear(); activityResource.NextActivityPerformers = new Dictionary <string, PerformerList>(); activityResource.NextActivityPerformers.Add(backwardToTaskActvity.ActivityGUID, performerList); //重新生成会签节点的多实例数据 CreateMultipleInstance(backwardToTaskActvity, processInstance, fromActivityInstance, transitionGUID, transitionType, flyingType, activityResource, session); }
/// <summary> /// 自动完成 /// </summary> /// <param name="processInstance">流程实例</param> /// <param name="transitionGUID">转移GUID</param> /// <param name="fromActivity">起始活动</param> /// <param name="fromActivityInstance">起始活动实例</param> /// <param name="runner">运行者</param> /// <param name="session">会话</param> /// <returns>网关执行结果</returns> public NodeAutoExecutedResult CompleteAutomaticlly(ProcessInstanceEntity processInstance, string transitionGUID, ActivityEntity fromActivity, ActivityInstanceEntity fromActivityInstance, WfAppRunner runner, IDbSession session) { //检查是否有运行中的合并节点实例 ActivityInstanceEntity joinNode = base.ActivityInstanceManager.GetActivityRunning( processInstance.ID, base.GatewayActivity.ActivityGUID, session); int tokensRequired = 0; int tokensHad = 0; if (joinNode == null) { var joinActivityInstance = base.CreateActivityInstanceObject(base.GatewayActivity, processInstance, runner); //计算总需要的Token数目 joinActivityInstance.TokensRequired = GetTokensRequired(processInstance.AppInstanceID, processInstance.ID, base.GatewayActivity); joinActivityInstance.TokensHad = 1; tokensRequired = joinActivityInstance.TokensRequired; //进入运行状态 joinActivityInstance.ActivityState = (short)ActivityStateEnum.Running; joinActivityInstance.GatewayDirectionTypeID = (short)GatewayDirectionEnum.AndJoinMI; //写入默认第一次的预选步骤用户列表 joinActivityInstance.NextStepPerformers = NextStepUtility.SerializeNextStepPerformers(runner.NextActivityPerformers); base.InsertActivityInstance(joinActivityInstance, session); base.InsertTransitionInstance(processInstance, transitionGUID, fromActivityInstance, joinActivityInstance, TransitionTypeEnum.Forward, TransitionFlyingTypeEnum.NotFlying, runner, session); } else { //更新节点的活动实例属性 base.GatewayActivityInstance = joinNode; tokensRequired = base.GatewayActivityInstance.TokensRequired; tokensHad = base.GatewayActivityInstance.TokensHad; //更新Token数目 base.ActivityInstanceManager.IncreaseTokensHad(base.GatewayActivityInstance.ID, runner, session); base.InsertTransitionInstance(processInstance, transitionGUID, fromActivityInstance, joinNode, TransitionTypeEnum.Forward, TransitionFlyingTypeEnum.NotFlying, runner, session); } if ((tokensHad + 1) == tokensRequired) { //如果达到完成节点的Token数,则设置该节点状态为完成 base.CompleteActivityInstance(base.GatewayActivityInstance.ID, runner, session); base.GatewayActivityInstance.ActivityState = (short)ActivityStateEnum.Completed; } NodeAutoExecutedResult result = NodeAutoExecutedResult.CreateGatewayExecutedResult( NodeAutoExecutedStatus.Successed); return(result); }
/// <summary> /// 创建加签节点记录 /// </summary> /// <param name="activityResource"></param> private void CreateSignForwardTasks(ActivityResource activityResource) { SignForwardTypeEnum signForwardType = (SignForwardTypeEnum)Enum.Parse(typeof(SignForwardTypeEnum), base.ActivityForwardContext.ActivityResource.AppRunner.ControlParameterSheet.SignForwardType); //根据当前活动实例的记录为加签发起人创建一条新的记录,并修改CompleteOrder var newActivityInstance = base.ActivityInstanceManager.CreateActivityInstanceObject(base.ActivityForwardContext.FromActivityInstance); newActivityInstance.AssignedToUserIDs = activityResource.AppRunner.UserID; newActivityInstance.AssignedToUserNames = activityResource.AppRunner.UserName; newActivityInstance.MIHostActivityInstanceID = base.ActivityForwardContext.FromActivityInstance.ID; newActivityInstance.SignForwardType = (short)signForwardType; if (signForwardType == SignForwardTypeEnum.SignForwardParallel) { var controlParamSheet = base.ActivityForwardContext.ActivityResource.AppRunner.ControlParameterSheet; if (controlParamSheet.SignForwardCompareType.ToUpper() == "COUNT") { newActivityInstance.CompleteOrder = controlParamSheet.SignForwardCompleteOrder; } else { newActivityInstance.CompleteOrder = 1; } } newActivityInstance.ComplexType = (short)ComplexTypeEnum.SignForward; //获取加签人集合 var plist = activityResource.NextActivityPerformers[base.ActivityForwardContext.Activity.ActivityGUID]; //前加签是别人先审核,然后自己再审核 if (signForwardType == SignForwardTypeEnum.SignForwardBefore) { newActivityInstance.CompleteOrder = plist.Count + 1; newActivityInstance.ActivityState = (short)ActivityStateEnum.Suspended; } else if (signForwardType == SignForwardTypeEnum.SignForwardBehind) { //后加签是自己审批后,其他接收人再加签 newActivityInstance.CompleteOrder = 1; } else if (signForwardType == SignForwardTypeEnum.SignForwardParallel) { //并行加签子节点都为-1,与并行会签保持一致 newActivityInstance.CompleteOrder = -1; } //主节点挂起后,插入当前人的加签记录信息, 并插入任务记录 base.ActivityInstanceManager.Insert(newActivityInstance, base.Session); var signer = new Performer(base.ActivityForwardContext.ActivityResource.AppRunner.UserID, base.ActivityForwardContext.ActivityResource.AppRunner.UserName); base.TaskManager.Insert(newActivityInstance, signer, base.ActivityForwardContext.ActivityResource.AppRunner, base.Session); //创建新加签节点记录 var signforwardActivityInstance = new ActivityInstanceEntity(); for (var i = 0; i < plist.Count; i++) { signforwardActivityInstance = base.ActivityInstanceManager.CreateActivityInstanceObject(base.ActivityForwardContext.FromActivityInstance); signforwardActivityInstance.ComplexType = (short)ComplexTypeEnum.SignForward; signforwardActivityInstance.AssignedToUserIDs = plist[i].UserID; signforwardActivityInstance.AssignedToUserNames = plist[i].UserName; signforwardActivityInstance.MIHostActivityInstanceID = base.ActivityForwardContext.FromActivityInstance.ID; if (signForwardType == SignForwardTypeEnum.SignForwardBefore) { signforwardActivityInstance.CompleteOrder = (short)(i + 1); if (i > 0) { //加签是串行加签,逐次完成 signforwardActivityInstance.ActivityState = (short)ActivityStateEnum.Suspended; } } else if (signForwardType == SignForwardTypeEnum.SignForwardBehind) { signforwardActivityInstance.CompleteOrder = (short)(i + 2); signforwardActivityInstance.ActivityState = (short)ActivityStateEnum.Suspended; } else if (signForwardType == SignForwardTypeEnum.SignForwardParallel) { signforwardActivityInstance.CompleteOrder = -1; } signforwardActivityInstance.SignForwardType = (short)signForwardType; base.ActivityInstanceManager.Insert(signforwardActivityInstance, base.Session); base.TaskManager.Insert(signforwardActivityInstance, plist[i], activityResource.AppRunner, base.Session); } }
/// <summary> /// 根据不同退回场景创建运行时管理器 /// </summary> /// <param name="runningActivityInstanceList">运行节点列表</param> /// <param name="sendbackOperation">退回类型</param> /// <param name="runner">执行者</param> /// <param name="result">结果对象</param> /// <returns>运行时管理器</returns> private static WfRuntimeManager CreateRuntimeInstanceSendbackByCase( List <ActivityInstanceEntity> runningActivityInstanceList, SendbackOperationTypeEnum sendbackOperation, WfAppRunner runner, ref WfExecutedResult result) { WfRuntimeManager rmins = new WfRuntimeManagerSendBack(); rmins.WfExecutedResult = result = new WfExecutedResult(); ActivityInstanceEntity runningNode = runningActivityInstanceList.Where(x => x.ActivityState == (int)ActivityStateEnum.Running).OrderBy(x => x.ID).FirstOrDefault(); if (runningNode == null) { runningNode = runningActivityInstanceList[0]; } ProcessInstanceEntity processInstance = (new ProcessInstanceManager()).GetById(runningNode.ProcessInstanceID); IProcessModel processModel = ProcessModelFactory.Create(processInstance.ProcessGUID, processInstance.Version); var aim = new ActivityInstanceManager(); //以下处理,需要知道上一步是独立节点的信息 //获取上一步流转节点信息,可能经过And, Or等路由节点 var tim = new TransitionInstanceManager(); bool hasGatewayNode = false; var currentNode = runningNode; var lastActivityInstanceList = tim.GetPreviousActivityInstance(currentNode, true, out hasGatewayNode).ToList(); if (lastActivityInstanceList == null || lastActivityInstanceList.Count == 0 || lastActivityInstanceList.Count > 1) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Sendback_NullOrHasTooMany; result.Message = "当前没有可以退回的节点,或者有多个可以退回的节点,无法选择!"; return(rmins); } TransitionInstanceEntity lastTaskTransitionInstance = tim.GetLastTaskTransition(runner.AppName, runner.AppInstanceID, runner.ProcessGUID); if (lastTaskTransitionInstance.TransitionType == (short)TransitionTypeEnum.Loop) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Sendback_IsLoopNode; result.Message = "当前流转是自循环,无需退回!"; return(rmins); } //设置退回节点的相关信息 var previousActivityInstance = lastActivityInstanceList[0]; if (previousActivityInstance.ActivityType == (short)ActivityTypeEnum.StartNode) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Sendback_PreviousIsStartNode; result.Message = "上一步是开始节点,无需退回!"; return(rmins); } if (sendbackOperation == SendbackOperationTypeEnum.Normal) { //简单串行模式下的退回 rmins = new WfRuntimeManagerSendBack(); rmins.WfExecutedResult = result = new WfExecutedResult(); rmins.ProcessModel = processModel; rmins.BackwardContext.ProcessInstance = processInstance; rmins.BackwardContext.BackwardToTaskActivity = processModel.GetActivity(previousActivityInstance.ActivityGUID); rmins.BackwardContext.BackwardToTaskActivityInstance = previousActivityInstance; rmins.BackwardContext.BackwardToTargetTransitionGUID = hasGatewayNode == false ? lastTaskTransitionInstance.TransitionGUID : String.Empty; //如果中间有Gateway节点,则没有直接相连的TransitonGUID rmins.BackwardContext.BackwardFromActivity = processModel.GetActivity(runningNode.ActivityGUID); rmins.BackwardContext.BackwardFromActivityInstance = runningNode; rmins.BackwardContext.BackwardTaskReceiver = WfBackwardTaskReceiver.Instance(previousActivityInstance.ActivityName, previousActivityInstance.EndedByUserID, previousActivityInstance.EndedByUserName); //封装AppUser对象 rmins.AppRunner.AppName = runner.AppName; rmins.AppRunner.AppInstanceID = runner.AppInstanceID; rmins.AppRunner.ProcessGUID = runner.ProcessGUID; rmins.AppRunner.UserID = runner.UserID; rmins.AppRunner.UserName = runner.UserName; rmins.AppRunner.NextActivityPerformers = ActivityResource.CreateNextActivityPerformers(previousActivityInstance.ActivityGUID, previousActivityInstance.EndedByUserID, previousActivityInstance.EndedByUserName); rmins.ActivityResource = new ActivityResource(runner, rmins.AppRunner.NextActivityPerformers); return(rmins); } //如果有其它模式,没有处理到,则直接抛出异常 throw new WorkflowException("未知的退回场景,请报告给技术支持人员!"); }
/// <summary> /// 根据不同撤销场景创建运行时管理器 /// </summary> /// <param name="runningActivityInstanceList">运行节点列表</param> /// <param name="withdrawOperation">撤销类型</param> /// <param name="runner">执行者</param> /// <param name="result">结果对象</param> /// <returns>运行时管理器</returns> private static WfRuntimeManager CreateRuntimeInstanceWithdrawByCase( List <ActivityInstanceEntity> runningActivityInstanceList, WithdrawOperationTypeEnum withdrawOperation, WfAppRunner runner, ref WfExecutedResult result) { WfRuntimeManager rmins = new WfRuntimeManagerWithdraw(); rmins.WfExecutedResult = result = new WfExecutedResult(); //根据当前运行节点获取 ActivityInstanceEntity runningNode = runningActivityInstanceList[0]; ProcessInstanceEntity processInstance = (new ProcessInstanceManager()).GetById(runningNode.ProcessInstanceID); IProcessModel processModel = ProcessModelFactory.Create(processInstance.ProcessGUID, processInstance.Version); //不同撤销的分支场景处理 var aim = new ActivityInstanceManager(); //以下处理,需要知道上一步是独立节点的信息 //获取上一步流转节点信息,可能经过And, Or等路由节点 var tim = new TransitionInstanceManager(); bool hasGatewayNode = false; var currentNode = runningNode; if (runningNode.MIHostActivityInstanceID != null) { //如果当前运行节点是多实例子节点,则需要找到它的主节点的Transiton记录 currentNode = aim.GetById(runningNode.MIHostActivityInstanceID.Value); } var lastActivityInstanceList = tim.GetPreviousActivityInstance(currentNode, false, out hasGatewayNode).ToList(); if (lastActivityInstanceList == null || lastActivityInstanceList.Count > 1) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_HasTooMany; result.Message = "当前没有可以撤销回去的节点,或者有多个可以撤销回去的节点,无法选择!"; return(rmins); } TransitionInstanceEntity lastTaskTransitionInstance = null; if (hasGatewayNode == false) { lastTaskTransitionInstance = tim.GetLastTaskTransition(runner.AppName, runner.AppInstanceID, runner.ProcessGUID); if (lastTaskTransitionInstance.TransitionType == (short)TransitionTypeEnum.Loop) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_IsLoopNode; result.Message = "当前流转是自循环,无需撤销!"; return(rmins); } } var previousActivityInstance = lastActivityInstanceList[0]; if (previousActivityInstance.EndedByUserID != runner.UserID) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_NotCreatedByMine; result.Message = string.Format("上一步节点的任务办理人跟当前登录用户不一致,无法撤销回上一步!节点办理人:{0}", previousActivityInstance.EndedByUserName); return(rmins); } if (previousActivityInstance.ActivityType == (short)ActivityTypeEnum.EndNode) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Withdraw_PreviousIsEndNode; result.Message = "上一步是结束节点,无法撤销!"; return(rmins); } //当前运行节点是普通节点 if (withdrawOperation == WithdrawOperationTypeEnum.Normal) { //简单串行模式下的退回 rmins = new WfRuntimeManagerWithdraw(); rmins.WfExecutedResult = result = new WfExecutedResult(); rmins.ProcessModel = processModel; rmins.AppRunner.ProcessGUID = runner.ProcessGUID; rmins.BackwardContext.ProcessInstance = processInstance; rmins.BackwardContext.BackwardToTargetTransitionGUID = hasGatewayNode == false ? lastTaskTransitionInstance.TransitionGUID : String.Empty; rmins.BackwardContext.BackwardToTaskActivity = processModel.GetActivity(previousActivityInstance.ActivityGUID); rmins.BackwardContext.BackwardToTaskActivityInstance = previousActivityInstance; rmins.BackwardContext.BackwardFromActivity = processModel.GetActivity(runningNode.ActivityGUID); rmins.BackwardContext.BackwardFromActivityInstance = runningNode; //准备状态的接收节点 rmins.BackwardContext.BackwardTaskReceiver = WfBackwardTaskReceiver.Instance( previousActivityInstance.ActivityName, previousActivityInstance.EndedByUserID, previousActivityInstance.EndedByUserName); //封装AppUser对象 rmins.AppRunner.AppName = runner.AppName; rmins.AppRunner.AppInstanceID = runner.AppInstanceID; rmins.AppRunner.UserID = runner.UserID; rmins.AppRunner.UserName = runner.UserName; rmins.AppRunner.NextActivityPerformers = ActivityResource.CreateNextActivityPerformers( previousActivityInstance.ActivityGUID, runner.UserID, runner.UserName); rmins.ActivityResource = new ActivityResource(runner, rmins.AppRunner.NextActivityPerformers); return(rmins); } //如果有其它模式,没有处理到,则直接抛出异常 throw new WorkflowException("未知的撤销场景,请报告给技术支持人员!"); }
/// <summary> /// 自动完成 /// </summary> /// <param name="processInstance">流程实例</param> /// <param name="transitionGUID">转移GUID</param> /// <param name="fromActivityInstance">起始活动实例</param> /// <param name="activityResource">活动资源</param> /// <param name="session">数据上下文</param> /// <returns>网关执行结果</returns> public GatewayExecutedResult CompleteAutomaticlly(ProcessInstanceEntity processInstance, string transitionGUID, ActivityInstanceEntity fromActivityInstance, ActivityResource activityResource, IDbSession session) { GatewayExecutedResult result = GatewayExecutedResult.CreateGatewayExecutedResult(GatewayExecutedStatus.Unknown); bool canRenewInstance = false; //检查是否有运行中的合并节点实例 ActivityInstanceEntity joinNode = base.ActivityInstanceManager.GetActivityRunning( processInstance.ID, base.GatewayActivity.ActivityGUID, session); if (joinNode == null) { canRenewInstance = true; } else { //判断是否可以激活下一步节点 canRenewInstance = (joinNode.CanRenewInstance == 1); if (!canRenewInstance) { result = GatewayExecutedResult.CreateGatewayExecutedResult(GatewayExecutedStatus.FallBehindOfXOrJoin); return(result); } } if (canRenewInstance) { var gatewayActivityInstance = base.CreateActivityInstanceObject(base.GatewayActivity, processInstance, activityResource.AppRunner); gatewayActivityInstance.GatewayDirectionTypeID = (short)GatewayDirectionEnum.XOrJoin; base.InsertActivityInstance(gatewayActivityInstance, session); base.CompleteActivityInstance(gatewayActivityInstance.ID, activityResource, session); gatewayActivityInstance.ActivityState = (short)ActivityStateEnum.Completed; base.GatewayActivityInstance = gatewayActivityInstance; //写节点转移实例数据 base.InsertTransitionInstance(processInstance, transitionGUID, fromActivityInstance, gatewayActivityInstance, TransitionTypeEnum.Forward, TransitionFlyingTypeEnum.NotFlying, activityResource.AppRunner, session); result = GatewayExecutedResult.CreateGatewayExecutedResult(GatewayExecutedStatus.Successed); } return(result); }
/// <summary> /// 递归执行节点 /// 1)创建普通节点的任务 /// 2)创建会签节点的任务 /// </summary> /// <param name="fromActivity">起始活动</param> /// <param name="fromActivityInstance">起始活动实例</param> /// <param name="isJumpforward">是否跳跃</param> /// <param name="root">根节点</param> /// <param name="conditionKeyValuePair">条件key-value</param> protected void ContinueForwardCurrentNodeRecurisivly(ActivityEntity fromActivity, ActivityInstanceEntity fromActivityInstance, NextActivityComponent root, IDictionary <string, string> conditionKeyValuePair, Boolean isJumpforward) { foreach (NextActivityComponent comp in root) { if (comp.HasChildren) { //此节点类型为分支或合并节点类型:首先需要实例化当前节点(自动完成) NodeMediatorGateway gatewayNodeMediator = NodeMediatorGatewayFactory.CreateGatewayNodeMediator(comp.Activity, this.ActivityForwardContext.ProcessModel, Session); ICompleteAutomaticlly autoGateway = (ICompleteAutomaticlly)gatewayNodeMediator; GatewayExecutedResult gatewayResult = autoGateway.CompleteAutomaticlly( ActivityForwardContext.ProcessInstance, comp.Transition.TransitionGUID, fromActivityInstance, ActivityForwardContext.ActivityResource, Session); if (gatewayResult.Status == GatewayExecutedStatus.Successed) { //遍历后续子节点 ContinueForwardCurrentNodeRecurisivly(fromActivity, gatewayNodeMediator.GatewayActivityInstance, comp, conditionKeyValuePair, isJumpforward); } else { WfRuntimeException e = new WfRuntimeException("第一个满足条件的节点已经被成功执行,此后的节点被阻止在XOrJoin节点!"); LogManager.RecordLog("递归执行节点方法异常", LogEventType.Exception, LogPriority.Normal, null, e); } } else if (comp.Activity.ActivityType == ActivityTypeEnum.TaskNode) //普通任务节点 { //此节点类型为任务节点:根据fromActivityInstance的类型判断是否可以创建任务 if (fromActivityInstance.ActivityState == (short)ActivityStateEnum.Completed) { //创建新任务节点 NodeMediator taskNodeMediator = new NodeMediatorTask(Session); taskNodeMediator.CreateActivityTaskTransitionInstance(comp.Activity, ActivityForwardContext.ProcessInstance, fromActivityInstance, comp.Transition.TransitionGUID, comp.Transition.DirectionType == TransitionDirectionTypeEnum.Loop ? TransitionTypeEnum.Loop : TransitionTypeEnum.Forward, //根据Direction方向确定是否是自身循环 isJumpforward == true ? TransitionFlyingTypeEnum.ForwardFlying : TransitionFlyingTypeEnum.NotFlying, ActivityForwardContext.ActivityResource, Session); } else { //下一步的任务节点没有创建,需给出提示信息 if ((fromActivity.GatewayDirectionType | GatewayDirectionEnum.AllJoinType) == GatewayDirectionEnum.AllJoinType) { WfRuntimeException e = new WfRuntimeException("等待其它需要合并的分支!"); LogManager.RecordLog("递归执行节点方法异常", LogEventType.Exception, LogPriority.Normal, null, e); } } } else if (comp.Activity.ActivityType == ActivityTypeEnum.SubProcessNode) //子流程节点 { //节点类型为subprocessnode if (fromActivityInstance.ActivityState == (short)ActivityStateEnum.Completed) { //实例化subprocess节点数据 NodeMediator subNodeMediator = new NodeMediatorSubProcess(Session); subNodeMediator.CreateActivityTaskTransitionInstance(comp.Activity, ActivityForwardContext.ProcessInstance, fromActivityInstance, comp.Transition.TransitionGUID, comp.Transition.DirectionType == TransitionDirectionTypeEnum.Loop ? TransitionTypeEnum.Loop : TransitionTypeEnum.Forward, TransitionFlyingTypeEnum.NotFlying, ActivityForwardContext.ActivityResource, Session); } } else if (comp.Activity.ActivityType == ActivityTypeEnum.EndNode) //结束节点 { //此节点为完成结束节点,结束流程 NodeMediator endMediator = new NodeMediatorEnd(ActivityForwardContext, Session); endMediator.Linker.ToActivity = comp.Activity; //创建结束节点实例及转移数据 endMediator.CreateActivityTaskTransitionInstance(comp.Activity, ActivityForwardContext.ProcessInstance, fromActivityInstance, comp.Transition.TransitionGUID, TransitionTypeEnum.Forward, TransitionFlyingTypeEnum.NotFlying, ActivityForwardContext.ActivityResource, Session); //执行结束节点中的业务逻辑 endMediator.ExecuteWorkItem(); } else { WfRuntimeException e = new WfRuntimeException(string.Format("XML文件定义了未知的节点类型,执行失败,节点类型信息:{0}", comp.Activity.ActivityType.ToString())); LogManager.RecordLog("递归执行节点方法异常", LogEventType.Exception, LogPriority.Normal, null, e); } } }
/// <summary> /// 插入实例数据 /// </summary> /// <param name="activityInstance">活动资源</param> /// <param name="session">会话</param> internal virtual void InsertActivityInstance(ActivityInstanceEntity activityInstance, IDbSession session) { ActivityInstanceManager.Insert(activityInstance, session); }
/// <summary> /// OrJoin合并时的节点完成方法 /// 1. 如果有满足条件的OrJoin前驱转移,则会重新生成新的OrJoin节点实例 /// </summary> /// <param name="processInstance">流程实例</param> /// <param name="transitionGUID">转移GUID</param> /// <param name="fromActivityInstance">起始活动实例</param> /// <param name="activityResource">活动资源</param> /// <param name="session">会话</param> public GatewayExecutedResult CompleteAutomaticlly(ProcessInstanceEntity processInstance, string transitionGUID, ActivityInstanceEntity fromActivityInstance, ActivityResource activityResource, IDbSession session) { //检查是否有运行中的合并节点实例 ActivityInstanceEntity joinNode = base.ActivityInstanceManager.GetActivityRunning( processInstance.ID, base.GatewayActivity.ActivityGUID, session); int tokensRequired = 0; int tokensHad = 0; if (joinNode == null) { var joinActivityInstance = base.CreateActivityInstanceObject(base.GatewayActivity, processInstance, activityResource.AppRunner); //计算总需要的Token数目 joinActivityInstance.TokensRequired = GetTokensRequired(processInstance.ID); joinActivityInstance.TokensHad = 1; tokensRequired = joinActivityInstance.TokensRequired; //进入运行状态 joinActivityInstance.ActivityState = (short)ActivityStateEnum.Running; joinActivityInstance.GatewayDirectionTypeID = (short)GatewayDirectionEnum.AndJoin; base.InsertActivityInstance(joinActivityInstance, session); base.InsertTransitionInstance(processInstance, transitionGUID, fromActivityInstance, joinActivityInstance, TransitionTypeEnum.Forward, TransitionFlyingTypeEnum.NotFlying, activityResource.AppRunner, session); } else { //更新节点的活动实例属性 base.GatewayActivityInstance = joinNode; tokensRequired = base.GatewayActivityInstance.TokensRequired; tokensHad = base.GatewayActivityInstance.TokensHad; //更新Token数目 base.ActivityInstanceManager.IncreaseTokensHad(base.GatewayActivityInstance.ID, activityResource.AppRunner, session); base.InsertTransitionInstance(processInstance, transitionGUID, fromActivityInstance, joinNode, TransitionTypeEnum.Forward, TransitionFlyingTypeEnum.NotFlying, activityResource.AppRunner, session); } if ((tokensHad + 1) == tokensRequired) { //如果达到完成节点的Token数,则设置该节点状态为完成 base.CompleteActivityInstance(base.GatewayActivityInstance.ID, activityResource, session); base.GatewayActivityInstance.ActivityState = (short)ActivityStateEnum.Completed; } GatewayExecutedResult result = GatewayExecutedResult.CreateGatewayExecutedResult(GatewayExecutedStatus.Successed); return(result); }
/// <summary> /// 创建子流程节点数据以及子流程记录 /// </summary> /// <param name="toActivity">目的活动</param> /// <param name="processInstance">流程实例</param> /// <param name="fromActivityInstance">来源活动实例</param> /// <param name="transitionGUID">转移GUID</param> /// <param name="transitionType">转移类型</param> /// <param name="flyingType">飞跃类型</param> /// <param name="activityResource">活动资源</param> /// <param name="performer">执行者</param> /// <param name="session">会话</param> private void CreateSubProcessNode(ActivityEntity toActivity, ProcessInstanceEntity processInstance, ActivityInstanceEntity fromActivityInstance, string transitionGUID, TransitionTypeEnum transitionType, TransitionFlyingTypeEnum flyingType, ActivityResource activityResource, Performer performer, IDbSession session) { WfExecutedResult startedResult = WfExecutedResult.Default(); //实例化Activity var toActivityInstance = CreateActivityInstanceObject(toActivity, processInstance, activityResource.AppRunner); //进入运行状态 toActivityInstance.ActivityState = (short)ActivityStateEnum.Ready; if (performer != null) { //并行容器中的子流程节点,每个人发起一个子流程 toActivityInstance.AssignedToUserIDs = performer.UserID; toActivityInstance.AssignedToUserNames = performer.UserName; //插入活动实例数据 base.ActivityInstanceManager.Insert(toActivityInstance, session); //插入任务数据 this.TaskManager.Insert(toActivityInstance, performer, activityResource.AppRunner, session); } else { toActivityInstance = GenerateActivityAssignedUserInfo(toActivityInstance, activityResource); //插入活动实例数据 base.ActivityInstanceManager.Insert(toActivityInstance, session); //插入任务数据 base.CreateNewTask(toActivityInstance, activityResource, session); } //插入转移数据 var newTransitionInstanceID = InsertTransitionInstance(processInstance, transitionGUID, fromActivityInstance, toActivityInstance, transitionType, flyingType, activityResource.AppRunner, session); //启动子流程 var subProcessNode = (SubProcessNode)toActivity.Node; subProcessNode.ActivityInstance = toActivityInstance; WfAppRunner subRunner = null; var performerList = new PerformerList(); if (performer != null) { subRunner = CopyActivityForwardRunner(activityResource.AppRunner, new Performer(performer.UserID, performer.UserName), subProcessNode); performerList.Add(performer); } else { subRunner = CopyActivityForwardRunner(activityResource.AppRunner, new Performer(activityResource.AppRunner.UserID, activityResource.AppRunner.UserName), subProcessNode); performerList = activityResource.NextActivityPerformers[toActivity.ActivityGUID]; } var runtimeInstance = WfRuntimeManagerFactory.CreateRuntimeInstanceStartupSub(subRunner, processInstance, subProcessNode, performerList, session, ref startedResult); runtimeInstance.OnWfProcessExecuted += runtimeInstance_OnWfProcessStarted; runtimeInstance.Execute(session); void runtimeInstance_OnWfProcessStarted(object sender, WfEventArgs args) { startedResult = args.WfExecutedResult; } }
/// <summary> /// EOrJoin合并时的节点完成方法 /// 内部执行逻辑 /// </summary> /// <param name="processInstance">流程实例</param> /// <param name="transitionGUID">转移GUID</param> /// <param name="fromActivity">起始活动</param> /// <param name="fromActivityInstance">起始活动实例</param> /// <param name="tokensCountRequired">合并要求的Token数目</param> /// <param name="runner">运行者</param> /// <param name="session">会话</param> private NodeAutoExecutedResult CompleteAutomaticallyInternal(ProcessInstanceEntity processInstance, string transitionGUID, ActivityEntity fromActivity, ActivityInstanceEntity fromActivityInstance, int tokensCountRequired, WfAppRunner runner, IDbSession session) { NodeAutoExecutedResult result = NodeAutoExecutedResult.CreateGatewayExecutedResult(NodeAutoExecutedStatus.Unknown); //当前执行的分支就是强制分支 //检查是否有运行中的合并节点实例 ActivityInstanceEntity joinNode = base.ActivityInstanceManager.GetActivityRunning( processInstance.ID, base.GatewayActivity.ActivityGUID, session);; if (joinNode == null) { //第一个分支首次运行 joinNode = base.CreateActivityInstanceObject(base.GatewayActivity, processInstance, runner); //计算总需要的Token数目 joinNode.TokensRequired = tokensCountRequired; joinNode.TokensHad = 1; //进入运行状态 joinNode.ActivityState = (short)ActivityStateEnum.Running; joinNode.GatewayDirectionTypeID = (short)GatewayDirectionEnum.OrJoin; //写入默认第一次的预选步骤用户列表 joinNode.NextStepPerformers = NextStepUtility.SerializeNextStepPerformers(runner.NextActivityPerformers); base.InsertActivityInstance(joinNode, session); base.InsertTransitionInstance(processInstance, transitionGUID, fromActivityInstance, joinNode, TransitionTypeEnum.Forward, TransitionFlyingTypeEnum.NotFlying, runner, session); } else { //更新节点的活动实例属性 joinNode.TokensHad += 1; base.GatewayActivityInstance = joinNode; //更新Token数目 base.ActivityInstanceManager.IncreaseTokensHad(base.GatewayActivityInstance.ID, runner, session); base.InsertTransitionInstance(processInstance, transitionGUID, fromActivityInstance, joinNode, TransitionTypeEnum.Forward, TransitionFlyingTypeEnum.NotFlying, runner, session); } //判断是否到达合并节点的通过Token数目要求 if (joinNode.TokensHad == joinNode.TokensRequired) { //如果达到完成节点的Token数,则设置该节点状态为完成 base.CompleteActivityInstance(base.GatewayActivityInstance.ID, runner, session); base.GatewayActivityInstance.ActivityState = (short)ActivityStateEnum.Completed; //更新其它分支上的待办节点为阻止状态(CanRenewInstance = 0) base.ActivityInstanceManager.UpdateActivityInstanceBlockedBetweenSplitJoin(base.GatewayActivity, base.GatewayActivityInstance, base.ProcessModel, session); result = NodeAutoExecutedResult.CreateGatewayExecutedResult(NodeAutoExecutedStatus.Successed); } else if (joinNode.TokensHad < joinNode.TokensRequired) { result = NodeAutoExecutedResult.CreateGatewayExecutedResult(NodeAutoExecutedStatus.WaitingForOthersJoin); } return(result); }
/// <summary> /// 更新活动实例 /// </summary> /// <param name="entity">活动实例实体</param> /// <param name="session">会话</param> internal void Update(ActivityInstanceEntity entity, IDbSession session) { Repository.Update(session.Connection, entity, session.Transaction); }
/// <summary> /// 获取流程当前运行节点信息 /// </summary> /// <param name="runner">执行者</param> /// <param name="taskView">任务视图</param> /// <returns>活动实例</returns> internal ActivityInstanceEntity GetRunningNode(WfAppRunner runner, out TaskViewEntity taskView) { var appInstanceID = runner.AppInstanceID; var processGUID = runner.ProcessGUID; var taskID = runner.TaskID; taskView = null; ActivityInstanceEntity activityInstance = null; //如果流程在运行状态,则返回运行时信息 var tm = new TaskManager(); var aim = new ActivityInstanceManager(); var activityInstanceList = aim.GetRunningActivityInstanceList(runner.AppInstanceID, runner.ProcessGUID).ToList(); if ((activityInstanceList != null) && (activityInstanceList.Count == 1)) { activityInstance = activityInstanceList[0]; taskView = tm.GetTaskOfMine(activityInstance.ID, runner.UserID); } else if (activityInstanceList.Count > 0) { if (runner.TaskID != null && runner.TaskID.Value != 0) { taskView = tm.GetTaskView(taskID.Value); foreach (var ai in activityInstanceList) { if (ai.ID == taskView.ActivityInstanceID) { activityInstance = ai; break; } } } else { //并行模式处理 //根据当前执行者身份取出(他或她)要办理的活动实例(并行模式下有多个处于待办或运行状态的节点) foreach (var ai in activityInstanceList) { if (ai.AssignedToUserIDs == runner.UserID) { activityInstance = ai; break; } } if (activityInstance != null) { //获取taskview taskView = tm.GetTaskOfMine(activityInstance.ID, runner.UserID); } else { //当前用户的待办任务不唯一,抛出异常,需要TaskID唯一界定 var e = new WorkflowException("当前流程有多个运行节点,但没有TaskID传入,状态异常!"); LogManager.RecordLog("获取当前运行节点信息异常", LogEventType.Exception, LogPriority.Normal, null, e); throw e; } } } else { //当前没有运行状态的节点存在,流程不存在,或者已经结束或取消 var e = new WorkflowException("当前流程没有运行节点,状态异常!"); LogManager.RecordLog("获取当前运行节点信息异常", LogEventType.Exception, LogPriority.Normal, null, e); throw e; } return(activityInstance); }
/// <summary> /// 会签类型的主节点, 多实例节点处理 /// </summary> /// <param name="processInstance"></param> /// <param name="fromToTransition"></param> /// <param name="fromActivityInstance"></param> /// <param name="activityResource"></param> /// <param name="session"></param> internal void CreateMultipleInstance(ActivityEntity toActivity, ProcessInstanceEntity processInstance, ActivityInstanceEntity fromActivityInstance, String transitionGUID, TransitionTypeEnum transitionType, TransitionFlyingTypeEnum flyingType, ActivityResource activityResource, IDbSession session) { //实例化主节点Activity var toActivityInstance = CreateActivityInstanceObject(toActivity, processInstance, activityResource.AppRunner); //主节点实例数据 toActivityInstance.ActivityState = (short)ActivityStateEnum.Suspended; toActivityInstance.ComplexType = (short)ComplexTypeEnum.SignTogether; if (toActivity.ActivityTypeDetail.MergeType == MergeTypeEnum.Parallel) { toActivityInstance.CompleteOrder = toActivity.ActivityTypeDetail.CompleteOrder; } toActivityInstance.AssignedToUserIDs = GenerateActivityAssignedUserIDs( activityResource.NextActivityPerformers[toActivity.ActivityGUID]); //插入主节点实例数据 base.ActivityInstanceManager.Insert(toActivityInstance, session); //插入主节点转移数据 InsertTransitionInstance(processInstance, transitionGUID, fromActivityInstance, toActivityInstance, transitionType, flyingType, activityResource.AppRunner, session); //插入会签子节点实例数据 var plist = activityResource.NextActivityPerformers[toActivity.ActivityGUID]; ActivityInstanceEntity entity = new ActivityInstanceEntity(); for (short i = 0; i < plist.Count; i++) { entity = base.ActivityInstanceManager.CreateActivityInstanceObject(toActivityInstance); entity.AssignedToUserIDs = plist[i].UserID; entity.AssignedToUserNames = plist[i].UserName; entity.MIHostActivityInstanceID = toActivityInstance.ID; entity.CompleteOrder = (short)(i + 1); //只有第一个节点处于运行状态,其它节点挂起 if ((i > 0) && (toActivity.ActivityTypeDetail.MergeType == MergeTypeEnum.Sequence)) { entity.ActivityState = (short)ActivityStateEnum.Suspended; } //插入活动实例数据,并返回活动实例ID entity.ID = base.ActivityInstanceManager.Insert(entity, session); //插入任务数据 base.TaskManager.Insert(entity, plist[i], activityResource.AppRunner, session); //启动子流程 IDbSession subSession = SessionFactory.CreateSession(); WfExecutedResult startedResult = null; var subProcessNode = (SubProcessNode)toActivity.Node; subProcessNode.ActivityInstance = entity; //在流程实例表中记录激活子流程的活动节点ID WfAppRunner subRunner = CopyActivityForwardRunner(activityResource.AppRunner, plist[i], subProcessNode); var runtimeInstance = WfRuntimeManagerFactory.CreateRuntimeInstanceStartup(subRunner, processInstance, subProcessNode, ref startedResult); if (runtimeInstance.WfExecutedResult.Status == WfExecutedStatus.Exception) { throw new WfRuntimeException(runtimeInstance.WfExecutedResult.Message); } runtimeInstance.Execute(subSession); //如果是串行会签,只有第一个子流程可以运行,其它子流程处于挂起状态 if ((i > 0) && (toActivity.ActivityTypeDetail.MergeType == MergeTypeEnum.Sequence)) { var startResult = (WfExecutedResult)runtimeInstance.WfExecutedResult; base.ProcessInstanceManager.Suspend(startedResult.ProcessInstanceIDStarted, subRunner, subSession); } } }
private static WfRuntimeManager CreateRuntimeInstanceSendbackByCase(ActivityInstanceEntity runningNode, IProcessModel processModel, ProcessInstanceEntity processInstance, IList <ActivityEntity> sendbackPreviousActivityList, Boolean hasGatewayPassed, SendbackOperationTypeEnum sendbackOperation, WfAppRunner runner, ref WfExecutedResult result) { WfRuntimeManager rmins = new WfRuntimeManagerSendBack(); rmins.WfExecutedResult = result = new WfExecutedResult(); var aim = new ActivityInstanceManager(); //以下处理,需要知道上一步是独立节点的信息 var tim = new TransitionInstanceManager(); TransitionInstanceEntity lastTaskTransitionInstance = tim.GetLastTaskTransition(runner.AppName, runner.AppInstanceID, runner.ProcessGUID); if (lastTaskTransitionInstance.TransitionType == (short)TransitionTypeEnum.Loop) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Sendback_IsLoopNode; result.Message = "当前流转是自循环,无需退回!"; return(rmins); } //设置退回节点的相关信息 var previousActivityGUID = sendbackPreviousActivityList[0].ActivityGUID; var previousActivityInstance = aim.GetActivityInstanceLatest(runner.AppInstanceID, runner.ProcessGUID, previousActivityGUID); //普通模式的退回 if (sendbackOperation == SendbackOperationTypeEnum.Normal) { //简单串行模式下的退回 rmins = new WfRuntimeManagerSendBack(); rmins.WfExecutedResult = result = new WfExecutedResult(); rmins.ProcessModel = processModel; rmins.BackwardContext.ProcessInstance = processInstance; rmins.BackwardContext.BackwardToTaskActivity = processModel.GetActivity(previousActivityInstance.ActivityGUID); rmins.BackwardContext.BackwardToTaskActivityInstance = previousActivityInstance; rmins.BackwardContext.BackwardToTargetTransitionGUID = hasGatewayPassed == false ? lastTaskTransitionInstance.TransitionGUID : WfDefine.WF_XPDL_GATEWAY_BYPASS_GUID; //如果中间有Gateway节点,则没有直接相连的TransitonGUID rmins.BackwardContext.BackwardFromActivity = processModel.GetActivity(runningNode.ActivityGUID); rmins.BackwardContext.BackwardFromActivityInstance = runningNode; rmins.BackwardContext.BackwardTaskReceiver = WfBackwardTaskReceiver.Instance(previousActivityInstance.ActivityName, previousActivityInstance.EndedByUserID, previousActivityInstance.EndedByUserName); //封装AppUser对象 rmins.AppRunner.AppName = runner.AppName; rmins.AppRunner.AppInstanceID = runner.AppInstanceID; rmins.AppRunner.ProcessGUID = runner.ProcessGUID; rmins.AppRunner.UserID = runner.UserID; rmins.AppRunner.UserName = runner.UserName; rmins.AppRunner.NextActivityPerformers = ActivityResource.CreateNextActivityPerformers(previousActivityInstance.ActivityGUID, previousActivityInstance.EndedByUserID, previousActivityInstance.EndedByUserName); rmins.ActivityResource = new ActivityResource(runner, rmins.AppRunner.NextActivityPerformers); return(rmins); } //如果有其它模式,没有处理到,则直接抛出异常 throw new WorkflowException("未知的退回场景,请报告给技术支持人员!"); }
/// <summary> /// 创建活动任务转移实例数据 /// </summary> /// <param name="toActivity">活动</param> /// <param name="processInstance">流程实例</param> /// <param name="fromActivityInstance">开始活动实例</param> /// <param name="transitionGUID">转移GUID</param> /// <param name="transitionType">转移类型</param> /// <param name="flyingType">跳跃类型</param> /// <param name="activityResource">活动资源</param> /// <param name="session">会话</param> internal override void CreateActivityTaskTransitionInstance(ActivityEntity toActivity, ProcessInstanceEntity processInstance, ActivityInstanceEntity fromActivityInstance, string transitionGUID, TransitionTypeEnum transitionType, TransitionFlyingTypeEnum flyingType, ActivityResource activityResource, IDbSession session) { int newActivityInstanceID = 0; Boolean isParallel = false; if (fromActivityInstance.ActivityType == (short)ActivityTypeEnum.GatewayNode) { //并发多实例分支判断(AndSplit Multiple) var processModel = ProcessModelFactory.Create(processInstance.ProcessGUID, processInstance.Version); var activityNode = processModel.GetActivity(fromActivityInstance.ActivityGUID); isParallel = processModel.IsAndSplitMI(activityNode); } if (isParallel) { //并行多实例容器 var entity = new ActivityInstanceEntity(); var plist = activityResource.NextActivityPerformers[toActivity.ActivityGUID]; //创建并行多实例分支 for (var i = 0; i < plist.Count; i++) { entity = base.CreateActivityInstanceObject(toActivity, processInstance, activityResource.AppRunner); entity.AssignedToUserIDs = plist[i].UserID; entity.AssignedToUserNames = plist[i].UserName; entity.ActivityState = (short)ActivityStateEnum.Ready; //插入活动实例数据 entity.ID = base.ActivityInstanceManager.Insert(entity, session); //插入任务 base.TaskManager.Insert(entity, plist[i], activityResource.AppRunner, session); //插入转移数据 InsertTransitionInstance(processInstance, transitionGUID, fromActivityInstance, entity, transitionType, flyingType, activityResource.AppRunner, session); } } else { //普通任务节点 var toActivityInstance = base.CreateActivityInstanceObject(toActivity, processInstance, activityResource.AppRunner); //进入运行状态 toActivityInstance.ActivityState = (short)ActivityStateEnum.Ready; toActivityInstance = GenerateActivityAssignedUserInfo(toActivityInstance, activityResource); //插入活动实例数据 newActivityInstanceID = base.ActivityInstanceManager.Insert(toActivityInstance, session); //插入任务数据 base.CreateNewTask(toActivityInstance, activityResource, session); //插入转移数据 InsertTransitionInstance(processInstance, transitionGUID, fromActivityInstance, toActivityInstance, transitionType, flyingType, activityResource.AppRunner, session); //调用外部事件的注册方法 var delegateContext = new DelegateContext { AppInstanceID = processInstance.AppInstanceID, ProcessGUID = processInstance.ProcessGUID, ProcessInstanceID = processInstance.ID, ActivityGUID = toActivity.ActivityGUID, ActivityCode = toActivity.ActivityCode, ActivityResource = activityResource }; DelegateExecutor.InvokeExternalDelegate(session, EventFireTypeEnum.OnActivityCreated, activityResource.AppRunner.DelegateEventList, delegateContext); } }