/// <summary> /// EOrJoin合并时的节点完成方法 /// 根据前置转移上定义的是否强制分支来判断完成合并节点 /// </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> private NodeAutoExecutedResult CompleteAutomaticallyByForcedBranchesCount(ProcessInstanceEntity processInstance, string transitionGUID, ActivityEntity fromActivity, ActivityInstanceEntity fromActivityInstance, WfAppRunner runner, IDbSession session) { NodeAutoExecutedResult result = NodeAutoExecutedResult.CreateGatewayExecutedResult(NodeAutoExecutedStatus.Unknown); IList <TransitionEntity> forcedTransitionList = null; var tokensCountRequired = base.ProcessModel.GetForcedBranchesCountBeforeEOrJoin(GatewayActivity, out forcedTransitionList); if (tokensCountRequired == 0) { result = NodeAutoExecutedResult.CreateGatewayExecutedResult(NodeAutoExecutedStatus.Failed); throw new WfXpdlException(LocalizeHelper.GetEngineMessage("nodemediatoreorjoin.CompleteAutomaticallyByForcedBranchesCount.error")); } //根据强制分支的数目和具体分支来完成增强合并节点 var forcedCount = forcedTransitionList.Where(t => t.TransitionGUID == transitionGUID).Count(); if (forcedCount == 0) { //当前执行的分支不是强制分支,直接返回就可以 result = NodeAutoExecutedResult.CreateGatewayExecutedResult(NodeAutoExecutedStatus.NotForcedBrancheWhenEOrJoin); } else if (forcedCount == 1) { result = CompleteAutomaticallyInternal(processInstance, transitionGUID, fromActivity, fromActivityInstance, tokensCountRequired, runner, session); } return(result); }
/// <summary> /// 执行外部方法 /// SetVariable: /// https://stackoverflow.com/questions/26426955/setting-and-getting-variables-in-net-hosted-ironpython-script/45734097 /// </summary> /// <param name="service">Action实体</param> /// <param name="delegateService">委托服务</param> private static void ExecutePythonMethod(ServiceEntity service, IDelegateService delegateService) { try { if (service.CodeInfo != null && !string.IsNullOrEmpty(service.CodeInfo.CodeText)) { // var pythonScript = action.Expression; var pythonScript = service.CodeInfo.CodeText; //modified by Besley in 12/26/2019, body is nodetext rather than attribute var engine = Python.CreateEngine(); var scope = engine.CreateScope(); var dictionary = CompositeKeyValue(service.Arguments, delegateService); foreach (var item in dictionary) { scope.SetVariable(item.Key, item.Value); } var source = engine.CreateScriptSourceFromString(pythonScript); source.Execute(scope); } else { throw new WorkflowException(LocalizeHelper.GetEngineMessage("actionexecutor.ExecutePythonMethod.warn")); } } catch (System.Exception ex) { throw new WorkflowException(LocalizeHelper.GetEngineMessage("actionexecutor.ExecutePythonMethod.exception", ex.Message)); } }
/// <summary> /// 设置变量 /// </summary> /// <param name="conn">链接</param> /// <param name="entity">流程变量实体</param> /// <param name="trans">事务</param> /// <returns>实体ID</returns> internal int SaveVariable(IDbConnection conn, ProcessVariableEntity entity, IDbTransaction trans) { if (string.IsNullOrEmpty(entity.AppInstanceID) || entity.ProcessInstanceID == 0) { throw new WorkflowException(LocalizeHelper.GetEngineMessage("processvariablemanager.savevariable.error")); } int entityID = 0; var query = new ProcessVariableQuery { VariableType = EnumHelper.ParseEnum <ProcessVariableTypeEnum>(entity.VariableType.ToString()), ProcessInstanceID = entity.ProcessInstanceID, ActivityGUID = entity.ActivityGUID, Name = entity.Name }; var item = Query(conn, query, trans); if (item == null) { entityID = Insert(conn, entity, trans); } else { entityID = item.ID; Update(conn, entity, trans); } return(entityID); }
/// <summary> /// 根据版本选择流程 /// </summary> /// <param name="conn">数据库链接</param> /// <param name="processGUID">流程GUID</param> /// <param name="version">版本</param> /// <param name="throwException">抛出异常</param> /// <param name="trans">交易</param> /// <returns>流程实体</returns> internal ProcessEntity GetByVersion(IDbConnection conn, string processGUID, string version, bool throwException = true, IDbTransaction trans = null) { ProcessEntity entity = null; var sql = @"SELECT * FROM WfProcess WHERE ProcessGUID=@processGUID AND VERSION=@version"; var list = Repository.Query <ProcessEntity>(conn, sql, new { processGUID = processGUID, version = version }, trans).ToList <ProcessEntity>(); if (list.Count() == 1) { entity = list[0]; } else { if (throwException == true) { throw new ApplicationException(LocalizeHelper.GetEngineMessage("processmanager.getbyversion.error", string.Format("ProcessGUID: {0}, Version: {1}", processGUID, version) )); } } return(entity); }
/// <summary> /// 创建节点执行器的抽象类 /// </summary> /// <param name="forwardContext">活动上下文</param> /// <param name="session">会话</param> /// <returns></returns> internal static NodeMediator CreateNodeMediator(ActivityForwardContext forwardContext, IDbSession session) { if (forwardContext.Activity.ActivityType == ActivityTypeEnum.StartNode) //开始节点 { return(new NodeMediatorStart(forwardContext, session)); } else if (forwardContext.Activity.ActivityType == ActivityTypeEnum.TaskNode) //任务节点 { return(new NodeMediatorTask(forwardContext, session)); } else if (forwardContext.Activity.ActivityType == ActivityTypeEnum.SubProcessNode) { return(new NodeMediatorSubProcess(forwardContext, session)); } else if (forwardContext.Activity.ActivityType == ActivityTypeEnum.EndNode) { return(new NodeMediatorEnd(forwardContext, session)); } else { throw new ApplicationException(LocalizeHelper.GetEngineMessage("nodemediatorfactory.CreateNodeMediator.uncertain.warn", forwardContext.Activity.ActivityType.ToString())); } }
/// <summary> /// 创建方法 /// </summary> /// <param name="sendbackOperation">退回选项</param> /// <param name="session">会话</param> /// <returns>退回器</returns> internal static NodeSendBack CreateNodeReverter(SendBackOperation sendbackOperation, IDbSession session) { NodeSendBack nodeSendBack = null; if (sendbackOperation.CurrentNodeOperationType == SendBackOperationTypeEnum.Normal) { if (sendbackOperation.PreviousNodeOperationType == SendBackOperationTypeEnum.Normal) { nodeSendBack = new NodeSendBackTask(sendbackOperation, session); } else { //如果有其它模式,没有处理到,则直接抛出异常 throw new WorkflowException(LocalizeHelper.GetEngineMessage("nodesendbackfactory.CreateNodeReverter.error", sendbackOperation.PreviousNodeOperationType.ToString())); } } else if (sendbackOperation.CurrentNodeOperationType == SendBackOperationTypeEnum.MultipleInstance) { //如果有其它模式,没有处理到,则直接抛出异常 throw new WorkflowException(LocalizeHelper.GetEngineMessage("nodesendbackfactory.CreateNodeReverter.error", sendbackOperation.CurrentMultipleInstanceDetailType.ToString())); } return(nodeSendBack); }
/// <summary> /// 执行子流程节点 /// </summary> internal override void ExecuteWorkItem() { try { if (base.Linker.FromActivity.ActivityType == ActivityTypeEnum.SubProcessNode) { //检查子流程是否结束 var pim = new ProcessInstanceManager(); bool isCompleted = pim.CheckSubProcessInstanceCompleted(Session.Connection, base.Linker.FromActivityInstance.ID, base.Linker.FromActivityInstance.ActivityGUID, Session.Transaction); if (isCompleted == false) { throw new WfRuntimeException(LocalizeHelper.GetEngineMessage("nodemediatorsubprocess.ExecuteWorkItem.notcompleted.warn", string.Format("Activity:{0}", base.Linker.FromActivity.ActivityName))); } } //完成当前的任务节点 bool canContinueForwardCurrentNode = CompleteWorkItem(ActivityForwardContext.TaskID, ActivityForwardContext.ActivityResource, this.Session); //获取下一步节点列表:并继续执行 if (canContinueForwardCurrentNode) { ContinueForwardCurrentNode(ActivityForwardContext.IsNotParsedByTransition, this.Session); } } catch (System.Exception ex) { throw; } }
/// <summary> /// 根据流程名称和版本标识获取流程 /// </summary> /// <param name="processCode">流程代码</param> /// <param name="version">流程版本</param> /// <returns>流程实体</returns> public ProcessEntity GetByCode(string processCode, string version = null) { ProcessEntity entity = null; if (string.IsNullOrEmpty(version)) { version = "1"; } var sql = @"SELECT * FROM WfProcess WHERE ProcessCode=@processCode AND VERSION=@version"; var list = Repository.Query <ProcessEntity>(sql, new { processCode = processCode, version = version }) .ToList <ProcessEntity>(); if (list.Count() == 1) { entity = list[0]; } else if (list.Count() == 0) { ; } else { throw new ApplicationException(LocalizeHelper.GetEngineMessage("processmanager.getbycode.error")); } return(entity); }
/// <summary> /// 按照版本获取流程记录 /// </summary> /// <param name="processGUID">流程GUID</param> /// <param name="version">版本</param> /// <returns>流程实体</returns> internal ProcessEntity GetByVersionInternal(string processGUID, string version) { ProcessEntity entity = null; string sql = @"SELECT * FROM WfProcess WHERE ProcessGUID=@processGUID AND VERSION=@version"; var list = Repository.Query <ProcessEntity>(sql, new { processGUID = processGUID, version = version }) .ToList <ProcessEntity>(); if (list != null) { if (list.Count() > 1) { throw new ApplicationException(LocalizeHelper.GetEngineMessage("processmanager.getbyversioninternal.error")); } else if (list.Count() == 1) { entity = list[0]; } } return(entity); }
/// <summary> /// 根据AppType获取流程记录 /// </summary> /// <param name="appType"></param> /// <param name="session"></param> /// <returns></returns> public ProcessEntity GetSingleByAppType(string appType, IDbSession session) { ProcessEntity entity = null; var sql = @"SELECT * FROM WfProcess WHERE AppType=@appType"; var list = Repository.Query <ProcessEntity>(session.Connection, sql, new { appType = appType }, session.Transaction) .ToList <ProcessEntity>(); if (list.Count() == 1) { entity = list[0]; } else { throw new ApplicationException(LocalizeHelper.GetEngineMessage("processmanager.getsinglebyapptype.error")); } return(entity); }
/// <summary> /// 获取当前使用的流程版本 /// </summary> /// <param name="processGUID">流程GUID</param> /// <returns>流程实体</returns> public ProcessEntity GetVersionUsing(string processGUID) { ProcessEntity entity = null; var sql = @"SELECT * FROM WfProcess WHERE ProcessGUID=@processGUID AND IsUsing=1 ORDER BY ID DESC"; //current using process definition record var list = Repository.Query <ProcessEntity>(sql, new { processGUID = processGUID }).ToList <ProcessEntity>(); if (list.Count() == 1) { entity = list[0]; } else { throw new ApplicationException(LocalizeHelper.GetEngineMessage("processmanager.getbyversion.error", string.Format("ProcessGUID: {0}", processGUID) )); } return(entity); }
/// <summary> /// 执行外部服务实现类 /// </summary> /// <param name="service">操作</param> /// <param name="delegateService">委托服务类</param> private static void Execute(ServiceEntity service, IDelegateService delegateService) { if (service.Method == ServiceMethodEnum.LocalService) { ExecuteLocalService(service, delegateService); } else if (service.Method == ServiceMethodEnum.CSharpLibrary) { ExecuteCSharpLibraryMethod(service, delegateService); } else if (service.Method == ServiceMethodEnum.WebApi) { ExecuteWebApiMethod(service, delegateService); } else if (service.Method == ServiceMethodEnum.SQL) { ExecuteSQLMethod(service, delegateService); } else if (service.Method == ServiceMethodEnum.StoreProcedure) { ExecuteStoreProcedureMethod(service, delegateService); } else if (service.Method == ServiceMethodEnum.Python) { ExecutePythonMethod(service, delegateService); } else { throw new WorkflowException(LocalizeHelper.GetEngineMessage("actionexecutor.Execute.exception", service.Method.ToString())); } }
/// <summary> /// 根据消息主题获取流程 /// </summary> /// <param name="topic">消息表达式</param> /// <returns>流程实体</returns> public ProcessEntity GetByMessage(string topic) { ProcessEntity entity = null; //StartType:2 --- message //var sql = @"SELECT // * // FROM WfProcess // WHERE StartType=2 // AND StartExpression=@startExpression"; //var list = Repository.Query<ProcessEntity>(sql, new { startExpression = topic}) // .ToList<ProcessEntity>(); var sqlQuery = (from p in Repository.GetAll <ProcessEntity>() where p.StartType == 2 && p.StartExpression == topic select p ); var list = sqlQuery.ToList <ProcessEntity>(); if (list.Count() > 1) { throw new ApplicationException(LocalizeHelper.GetEngineMessage("processmanager.getbymessage.error")); } else if (list.Count() == 1) { entity = list[0]; } return(entity); }
/// <summary> /// 按照版本获取流程记录 /// </summary> /// <param name="processGUID">流程GUID</param> /// <param name="version">版本</param> /// <returns>流程实体</returns> internal ProcessEntity GetByVersionInternal(string processGUID, string version) { ProcessEntity entity = null; //string sql = @"SELECT // * // FROM WfProcess // WHERE ProcessGUID=@processGUID // AND VERSION=@version"; //var list = Repository.Query<ProcessEntity>(sql, new { processGUID = processGUID, version = version }) // .ToList<ProcessEntity>(); var sqlQuery = (from p in Repository.GetAll <ProcessEntity>() where p.ProcessGUID == processGUID && p.Version == version select p ); var list = sqlQuery.ToList <ProcessEntity>(); if (list.Count() > 1) { throw new ApplicationException(LocalizeHelper.GetEngineMessage("processmanager.getbyversioninternal.error")); } else if (list.Count() == 1) { entity = list[0]; } return(entity); }
/// <summary> /// 恢复子流程 /// </summary> /// <param name="invokedActivityInstanceID">激活活动实例ID</param> /// <param name="runner">运行者</param> /// <param name="session">会话</param> internal void RecallSubProcess(int invokedActivityInstanceID, WfAppRunner runner, IDbSession session) { var list = Repository.Query <ProcessInstanceEntity>( session.Connection, @"SELECT * FROM WfProcessInstance WHERE InvokedActivityInstanceID=@invokedActivityInstanceID AND ProcessState=5 ORDER BY CreatedDateTime DESC", new { invokedActivityInstanceID = invokedActivityInstanceID }, session.Transaction).ToList(); if (list != null && list.Count() == 1) { var bEntity = list[0]; bEntity.ProcessState = (short)ProcessStateEnum.Running; bEntity.LastUpdatedDateTime = System.DateTime.Now; bEntity.LastUpdatedByUserID = runner.UserID; bEntity.LastUpdatedByUserName = runner.UserName; Update(bEntity, session); } else { throw new ProcessInstanceException(LocalizeHelper.GetEngineMessage("processinstancemanager.recallsubprocess.error")); } }
/// <summary> /// 根据消息主题获取流程 /// </summary> /// <param name="topic">消息表达式</param> /// <returns>流程实体</returns> public ProcessEntity GetByMessage(string topic) { //StartType:2 --- message var sql = @"SELECT * FROM WfProcess WHERE StartType=2 AND StartExpression=@startExpression"; ProcessEntity entity = null; var list = Repository.Query <ProcessEntity>(sql, new { startExpression = topic }) .ToList <ProcessEntity>(); if (list.Count() == 1) { entity = list[0]; } else if (list.Count() == 0) { ; } else { throw new ApplicationException(LocalizeHelper.GetEngineMessage("processmanager.getbymessage.error")); } return(entity); }
/// <summary> /// 读取任务,设置任务为已读状态 /// </summary> /// <param name="taskRunner">运行者实体</param> internal void SetTaskRead(WfAppRunner taskRunner) { IDbSession session = SessionFactory.CreateSession(); try { session.BeginTrans(); //置任务为处理状态 var task = GetTask(taskRunner.TaskID.Value); SetTaskState(task, taskRunner.UserID, taskRunner.UserName, TaskStateEnum.Reading, session); //置活动为运行状态 (new ActivityInstanceManager()).Read(task.ActivityInstanceID, taskRunner, session); session.Commit(); } catch (System.Exception e) { session.Rollback(); throw new WorkflowException(LocalizeHelper.GetEngineMessage("taskmanager.settaskread.error", e.Message), e); } finally { session.Dispose(); } }
/// <summary> /// 执行插件方法 /// </summary> /// <param name="service">Action实体</param> /// <param name="delegateService">委托服务</param> private static void ExecuteCSharpLibraryMethod(ServiceEntity service, IDelegateService delegateService) { try { //取出当前应用程序执行路径 var methodInfo = service.MethodInfo; var assemblyFullName = methodInfo.AssemblyFullName; var methodName = methodInfo.MethodName; var executingPath = ConfigHelper.GetExecutingDirectory(); var pluginAssemblyName = string.Format("{0}\\{1}\\{2}.dll", executingPath, "plugin", assemblyFullName); var pluginAssemblyTypes = Assembly.LoadFile(pluginAssemblyName).GetTypes(); Type outerClass = pluginAssemblyTypes .Single(t => !t.IsInterface && t.FullName == methodInfo.TypeFullName); //object instance = Activator.CreateInstance(outerClass, parameters.ConstructorParameters); object instance = Activator.CreateInstance(outerClass); System.Reflection.MethodInfo mi = outerClass.GetMethod(methodName); object[] methodParams = null; if (!string.IsNullOrEmpty(service.Arguments.Trim())) { methodParams = CompositeParameterValues(service.Arguments, delegateService); } var result = mi.Invoke(instance, methodParams); } catch (System.Exception ex) { throw new WorkflowException(LocalizeHelper.GetEngineMessage("actionexecutor.ExecuteCSharpLibraryMethod.exception", ex.Message)); } }
/// <summary> /// 创建流程模型实例 /// </summary> /// <param name="conn">链接</param> /// <param name="processGUID">流程GUID</param> /// <param name="version">版本</param> /// <param name="trans">事务</param> /// <returns>流程模型</returns> internal static IProcessModel Create(IDbConnection conn, string processGUID, string version, IDbTransaction trans) { ProcessEntity entity = null; var pm = new ProcessManager(); if (!string.IsNullOrEmpty(version)) { entity = pm.GetByVersion(conn, processGUID, version, false, trans); } else { //如果版本信息缺省,默认取当前IsUsing=1的流程记录 entity = pm.GetVersionUsing(conn, processGUID, trans); } if (entity == null) { throw new WfXpdlException(LocalizeHelper.GetEngineMessage("processmodel.factory.processnullexception")); } IProcessModel processModel = new ProcessModel(entity); return(processModel); }
/// <summary> /// 遍历执行当前节点后面的节点 /// 正常运行:需要走Transition的解析流转 /// 其它方式为直接指定:比如跳转,返送等,不需要解析,不能等同于正常流转解析 /// </summary> /// <param name="isNotParsedByTransition">不需要走解析流转</param> /// <param name="session">数据会话</param> internal void ContinueForwardCurrentNode(bool isNotParsedByTransition, IDbSession session) { try { var mediatorResult = new List <WfNodeMediatedResult>(); var activityResource = ActivityForwardContext.ActivityResource; if (isNotParsedByTransition == true) { //跳转模式时,直接流转运行 var root = NextActivityComponentFactory.CreateNextActivityComponent(); var nextActivityComponent = NextActivityComponentFactory.CreateNextActivityComponent( this.Linker.FromActivity, this.Linker.ToActivity); root.Add(nextActivityComponent); ContinueForwardCurrentNodeRecurisivly(this.Linker.FromActivity, this.Linker.FromActivityInstance, root, activityResource.ConditionKeyValuePair, isNotParsedByTransition, ref mediatorResult); } else { //普通正常运行 var nextActivityMatchedResult = this.ActivityForwardContext.ProcessModel.GetNextActivityList( this.Linker.FromActivityInstance.ActivityGUID, ActivityForwardContext.TaskID, activityResource.ConditionKeyValuePair, activityResource, (a, b) => a.NextActivityPerformers.ContainsKey(b.ActivityGUID), session); if (nextActivityMatchedResult.MatchedType != NextActivityMatchedType.Successed || nextActivityMatchedResult.Root.HasChildren == false) { throw new WfRuntimeException(LocalizeHelper.GetEngineMessage("nodemediator.ContinueForwardCurrentNode.warn")); } ContinueForwardCurrentNodeRecurisivly(this.Linker.FromActivity, this.Linker.FromActivityInstance, nextActivityMatchedResult.Root, activityResource.ConditionKeyValuePair, isNotParsedByTransition, ref mediatorResult); } if (mediatorResult.Count() > 0) { this.WfNodeMediatedResult = mediatorResult[0]; } } catch (System.Exception ex) { throw new WfRuntimeException(LocalizeHelper.GetEngineMessage("nodemediator.ContinueForwardCurrentNode.error", ex.Message), ex); } }
/// <summary> /// 创建上一步根显示节点 /// </summary> /// <returns>根节点</returns> internal static NextActivityComponent CreatePreviousActivityComponent() { //上一步步骤列表 NextActivityComponent root = new NextActivityGateway(LocalizeHelper.GetEngineMessage("nextactivitycomponentfactory.previoussteplist"), null, null); return(root); }
/// <summary> /// 根据应用实例、流程GUID,办理用户Id获取任务列表 /// </summary> /// <param name="conn">链接</param> /// <param name="appInstanceID">App实例ID</param> /// <param name="processGUID">流程定义GUID</param> /// <param name="userID">用户Id</param> /// <param name="taskID">任务ID</param> /// <param name="trans">事务</param> /// <returns>任务实体</returns> internal TaskViewEntity GetTaskOfMine(IDbConnection conn, string appInstanceID, string processGUID, string userID, Nullable <int> taskID, IDbTransaction trans) { TaskViewEntity taskView = null; if (taskID != null) { taskView = GetTaskView(conn, taskID.Value, trans); } else { //processState:2 -running 流程处于运行状态 //activityType:4 -表示“任务”类型的节点 //activityState: 1-ready(准备), 2-running()运行; //2015.09.10 besley //将ActivityType 修改为 WorkItemType,以处理多类型的任务节点,包括普通任务,多实例,子流程节点 //string sql = @"SELECT // TOP 1 * // FROM vwWfActivityInstanceTasks // WHERE AppInstanceID=@appInstanceID // AND ProcessGUID=@processGUID // AND AssignedToUserID=@userID // AND ProcessState=2 // AND (ActivityType=4 OR ActivityType=5 OR ActivityType=6 OR WorkItemType=1) // AND (ActivityState=1 OR ActivityState=2) // ORDER BY TASKID DESC"; var taskList = Repository.GetAll <TaskViewEntity>(conn, trans).Where <TaskViewEntity>(e => e.AppInstanceID == appInstanceID && e.ProcessGUID == processGUID && e.AssignedToUserID == userID && e.ProcessState == 2 && (e.ActivityType == 4 || e.ActivityType == 5 || e.ActivityType == 6 || e.WorkItemType == 1) && (e.ActivityState == 1 || e.ActivityState == 2)) .OrderByDescending(e => e.TaskID) .ToList(); if (taskList.Count == 0) { var message = LocalizeHelper.GetEngineMessage("taskmanager.gettaskofmine.error"); throw new WorkflowException( string.Format("{0},AppInstanceID: {1}", message, appInstanceID.ToString()) ); } else if (taskList.Count > 1) { throw new WorkflowException(LocalizeHelper.GetEngineMessage("taskmanager.gettaskofmine.toomoretasks.error")); } else { taskView = taskList[0]; } } return(taskView); }
/// <summary> /// 启动流程 /// </summary> /// <param name="runner">执行者</param> /// <param name="result">结果对象</param> /// <returns>运行时实例对象</returns> public static WfRuntimeManager CreateRuntimeInstanceStartup(WfAppRunner runner, ref WfExecutedResult result) { //检查流程是否可以被启动 var rmins = new WfRuntimeManagerStartup(); rmins.WfExecutedResult = result = new WfExecutedResult(); //正常流程启动 var pim = new ProcessInstanceManager(); ProcessInstanceEntity processInstance = pim.GetProcessInstanceCurrent(runner.AppInstanceID, runner.ProcessGUID); //不能同时启动多个主流程 if (processInstance != null && processInstance.ParentProcessInstanceID == null && processInstance.ProcessState == (short)ProcessStateEnum.Running) { result.Status = WfExecutedStatus.Exception; result.ExceptionType = WfExceptionType.Started_IsRunningAlready; result.Message = LocalizeHelper.GetEngineMessage("wfruntimemanagerfactory.CreateRuntimeInstanceStartup.error"); return(rmins); } rmins.AppRunner = runner; //获取流程第一个可办理节点 rmins.ProcessModel = ProcessModelFactory.Create(runner.ProcessGUID, runner.Version); var startActivity = rmins.ProcessModel.GetStartActivity(); var firstActivity = rmins.ProcessModel.GetFirstActivity(); //var firstActivityList = rmins.ProcessModel.GetFirstActivityList(startActivity, runner.Conditions); if (startActivity.ActivityTypeDetail.TriggerType == TriggerTypeEnum.None) { rmins.AppRunner.NextActivityPerformers = ActivityResource.CreateNextActivityPerformers(firstActivity.ActivityGUID, runner.UserID, runner.UserName); } else if (startActivity.ActivityTypeDetail.TriggerType == TriggerTypeEnum.Timer || startActivity.ActivityTypeDetail.TriggerType == TriggerTypeEnum.Message) { if (!string.IsNullOrEmpty(runner.UserID)) { rmins.AppRunner.NextActivityPerformers = ActivityResource.CreateNextActivityPerformers(firstActivity.ActivityGUID, runner.UserID, runner.UserName); } else { rmins.AppRunner.NextActivityPerformers = rmins.ProcessModel.GetActivityPerformers(firstActivity.ActivityGUID); } } rmins.ActivityResource = new ActivityResource(runner, rmins.AppRunner.NextActivityPerformers); return(rmins); }
/// <summary> /// 废弃单据下所有流程的信息 /// </summary> /// <param name="runner">运行者</param> /// <returns>设置成功标识</returns> internal bool Discard(WfAppRunner runner) { var isDiscarded = false; IDbConnection conn = SessionFactory.CreateConnection(); var transaction = conn.BeginTransaction(); try { //process state:7--discard status //record status:1 --invalid status //string updSql = @"UPDATE WfProcessInstance // SET [ProcessState] = 7, // [RecordStatusInvalid] = 1, // [LastUpdatedDateTime] = GETDATE(), // [LastUpdatedByUserID] = @userID, // [LastUpdatedByUserName] = @userName // WHERE AppInstanceID = @appInstanceID // AND ProcessGUID = @processGUID // AND Version = @version"; //int result = Repository.Execute(conn, updSql, new //{ // appInstanceID = runner.AppInstanceID, // processGUID = runner.ProcessGUID, // version = runner.Version, // userID = runner.UserID, // userName = runner.UserName //}, //transaction); var sqlQuery = (from pi in Repository.GetAll <ProcessInstanceEntity>(conn, transaction) where pi.AppInstanceID == runner.AppInstanceID && pi.ProcessGUID == runner.ProcessGUID && pi.Version == runner.Version select pi); var list = sqlQuery.ToList <ProcessInstanceEntity>(); var entity = EnumHelper.GetFirst <ProcessInstanceEntity>(list); entity.ProcessState = 7; entity.RecordStatusInvalid = 1; entity.LastUpdatedByUserID = runner.UserID; entity.LastUpdatedByUserName = runner.UserName; entity.LastUpdatedDateTime = System.DateTime.Now; isDiscarded = Repository.Update <ProcessInstanceEntity>(conn, entity, transaction); transaction.Commit(); } catch (System.Exception e) { transaction.Rollback(); throw new WorkflowException(LocalizeHelper.GetEngineMessage("processinstancemanager.discard.error", e.Message)); } finally { conn.Close(); } return(isDiscarded); }
/// <summary> /// 创建退回时的流转节点对象、任务和转移数据 /// </summary> /// <param name="processInstance">流程实例</param> /// <param name="fromActivityInstance">运行节点实例</param> /// <param name="backwardToTaskActivity">退回到的节点</param> /// <param name="backwardType">退回类型</param> /// <param name="transitionType">转移类型</param> /// <param name="flyingType">跳跃类型</param> /// <param name="activityResource">资源</param> /// <param name="session">会话</param> internal void CreateBackwardActivityTaskTransitionInstance(ProcessInstanceEntity processInstance, ActivityInstanceEntity fromActivityInstance, ActivityEntity backwardToTaskActivity, BackwardTypeEnum backwardType, TransitionTypeEnum transitionType, TransitionFlyingTypeEnum flyingType, ActivityResource activityResource, IDbSession session) { var previousActivityInstance = this.ActivityInstanceManager.GetPreviousActivityInstanceSimple(fromActivityInstance, backwardToTaskActivity.ActivityGUID, session); if (previousActivityInstance == null) { throw new WorkflowException(LocalizeHelper.GetEngineMessage("nodesendback.CreateBackwardActivityTaskTransitionInstance.error")); } //实例化Activity var toActivityInstance = this.ActivityInstanceManager.CreateBackwardActivityInstanceObject( processInstance.AppName, processInstance.AppInstanceID, processInstance.AppInstanceCode, processInstance.ID, backwardToTaskActivity, backwardType, fromActivityInstance.ID, previousActivityInstance.ID, activityResource.AppRunner); //进入准备运行状态 toActivityInstance.ActivityState = (short)ActivityStateEnum.Ready; //人员来自步骤列表的用户数据 toActivityInstance.AssignedToUserIDs = SendBackOperation.BackwardToTaskPerformer.UserID; toActivityInstance.AssignedToUserNames = SendBackOperation.BackwardToTaskPerformer.UserName; //插入活动实例数据 this.ActivityInstanceManager.Insert(toActivityInstance, session); //插入任务数据 this.TaskManager.Insert(toActivityInstance, SendBackOperation.BackwardToTaskPerformer, activityResource.AppRunner, session); //插入转移数据 InsertTransitionInstance(processInstance, fromActivityInstance, toActivityInstance, TransitionTypeEnum.Backward, TransitionFlyingTypeEnum.NotFlying, this.SendBackOperation.ActivityResource.AppRunner, session); }
/// <summary> /// 创建子流程时,重新生成runner信息 /// </summary> /// <param name="runner">运行者</param> /// <param name="performer">下一步执行者</param> /// <param name="subProcessNode">子流程节点</param> /// <param name="session">会话</param> /// <returns></returns> private WfAppRunner CreateSubProcessRunner(WfAppRunner runner, Performer performer, SubProcessNode subProcessNode, IDbSession session) { WfAppRunner subRunner = new WfAppRunner(); subRunner.AppInstanceCode = runner.AppInstanceCode; subRunner.AppInstanceID = runner.AppInstanceID; subRunner.AppName = runner.AppName; subRunner.UserID = performer.UserID; subRunner.UserName = performer.UserName; //如果是动态调用子流程,则需要获取具体子流程实体对象 var isSubProcessNotExisted = false; if (subProcessNode.SubProcessType == SubProcessTypeEnum.Dynamic) { var subProcessId = runner.DynamicVariables[subProcessNode.SubVarName]; if (!string.IsNullOrEmpty(subProcessId)) { int processID = 0; int.TryParse(subProcessId, out processID); if (processID > 0) { var pm = new ProcessManager(); var process = pm.GetByID(session.Connection, processID, session.Transaction); if (process != null) { subProcessNode.SubProcessGUID = process.ProcessGUID; } else { isSubProcessNotExisted = true; } } else { isSubProcessNotExisted = true; } } else { isSubProcessNotExisted = true; } } if (isSubProcessNotExisted == true) { throw new WfRuntimeException(LocalizeHelper.GetEngineMessage("nodemediatorsubprocess.CreateSubProcessRunner.nonevariableparamsvalue.warn")); } subRunner.ProcessGUID = subProcessNode.SubProcessGUID; return(subRunner); }
/// <summary> /// 获取最后的转移实体数据 /// </summary> /// <param name="appName">应用名称</param> /// <param name="appInstanceID">应用实例ID</param> /// <param name="processGUID">流程GUID</param> /// <returns>转移实体数据</returns> internal TransitionInstanceEntity GetLastTaskTransition(string appName, string appInstanceID, string processGUID) { var nodeList = GetWorkItemTransitonInstance(appInstanceID, processGUID).ToList(); if (nodeList.Count == 0) { throw new WorkflowException(LocalizeHelper.GetEngineMessage("transitioninstancemanager.getlasttasktransition.error")); } return(nodeList[0]); }
/// <summary> /// 新增流程记录 /// </summary> /// <param name="conn"></param> /// <param name="entity"></param> /// <param name="trans"></param> public int Insert(IDbConnection conn, ProcessEntity entity, IDbTransaction trans) { var entityExisted = GetByVersionInternal(entity.ProcessGUID, entity.Version); if (entityExisted != null) { throw new ApplicationException(LocalizeHelper.GetEngineMessage("processmanager.insert.error")); } return(Repository.Insert <ProcessEntity>(conn, entity, trans)); }
/// <summary> /// 根据Transition,获取下一步节点列表 /// </summary> /// <param name="forwardTransition">转移实体</param> /// <param name="conditionKeyValuePair">条件kv对</param> /// <param name="session">会话</param> /// <param name="resultType">结果类型</param> protected NextActivityComponent GetNextActivityListFromGatewayCore(TransitionEntity forwardTransition, IDictionary <string, string> conditionKeyValuePair, IDbSession session, out NextActivityMatchedType resultType) { NextActivityComponent child = null; if (XPDLHelper.IsSimpleComponentNode(forwardTransition.ToActivity.ActivityType) == true) //可流转简单类型节点 { child = NextActivityComponentFactory.CreateNextActivityComponent(forwardTransition, forwardTransition.ToActivity); resultType = NextActivityMatchedType.Successed; } else if (forwardTransition.ToActivity.ActivityType == ActivityTypeEnum.GatewayNode) { child = GetNextActivityListFromGateway(forwardTransition, forwardTransition.ToActivity, conditionKeyValuePair, session, out resultType); } else if (forwardTransition.ToActivity.ActivityType == ActivityTypeEnum.IntermediateNode) { if (forwardTransition.ToActivity.ActivityTypeDetail.TriggerType == TriggerTypeEnum.Timer) { child = NextActivityComponentFactory.CreateNextActivityComponent(forwardTransition, forwardTransition.ToActivity); resultType = NextActivityMatchedType.Successed; } else { NextActivityScheduleBase activitySchedule = NextActivityScheduleFactory.CreateActivityScheduleIntermediate(this.ProcessModel); child = activitySchedule.GetNextActivityListFromGateway(forwardTransition, forwardTransition.ToActivity, conditionKeyValuePair, session, out resultType); } } else if (forwardTransition.ToActivity.ActivityType == ActivityTypeEnum.ServiceNode) { NextActivityScheduleBase activitySchedule = NextActivityScheduleFactory.CreateActivityScheduleIntermediate(this.ProcessModel); child = activitySchedule.GetNextActivityListFromGateway(forwardTransition, forwardTransition.ToActivity, conditionKeyValuePair, session, out resultType); } else { resultType = NextActivityMatchedType.Failed; throw new XmlDefinitionException(LocalizeHelper.GetEngineMessage("nextactivityschedulebase.unknownnodetype", forwardTransition.ToActivity.ActivityType.ToString())); } return(child); }
/// <summary> /// 下一步活动 /// </summary> /// <param name="activityGUID">活动节点GUID</param> /// <param name="performerList">执行用户列表</param> /// <returns>服务类</returns> public IWorkflowService NextStep(string activityGUID, PerformerList performerList) { if (performerList != null && performerList.Count() > 0) { _wfAppRunner.NextActivityPerformers.Add(activityGUID, performerList); } else { throw new ApplicationException(LocalizeHelper.GetEngineMessage("workflowservice.nextstep.error")); } return(this); }