/// <summary> /// 构建步骤的链表信息 /// </summary> /// <param name="db"></param> /// <param name="ruleSteps"></param> /// <returns>多个链表</returns> private IList <RuleStepLinkedListNode <DmeRuleStep> > GetRuleStepNodeLinkedList(SqlSugarClient db, DmeModel model, DmeModelVersion modelVersion, IList <DmeRuleStep> ruleSteps) { IList <RuleStepLinkedListNode <DmeRuleStep> > newLinkedSteps = new List <RuleStepLinkedListNode <DmeRuleStep> >(); // 一次性构建步骤实体字典 IDictionary <int, RuleStepLinkedListNode <DmeRuleStep> > ruleStepDic = new Dictionary <int, RuleStepLinkedListNode <DmeRuleStep> >(); foreach (var subStep in ruleSteps) { ruleStepDic[subStep.Id] = new RuleStepLinkedListNode <DmeRuleStep>(subStep); newLinkedSteps.Add(ruleStepDic[subStep.Id]); } //IList<RuleStepLinkedListNode<DmeRuleStep>> multiLinkedList = new List<RuleStepLinkedListNode<DmeRuleStep>>(); IList <DmeRuleStepHop> hops = db.Queryable <DmeRuleStepHop>().Where(rsh => rsh.ModelId == model.Id && rsh.VersionId == modelVersion.Id).OrderBy(rsh => rsh.StepFromId).ToList(); if (0 == hops?.Count) { return(newLinkedSteps); } IDictionary <int, RuleStepLinkedListNode <DmeRuleStep> > newRuleStepLinkedNodeDic = new Dictionary <int, RuleStepLinkedListNode <DmeRuleStep> >(); // 已经使用的步骤id集合 IList <int> usedStepIds = new List <int>(); RuleStepLinkedListNode <DmeRuleStep> linkedStepFromNode = null; RuleStepLinkedListNode <DmeRuleStep> linkedStepToNode = null; // 反过来构建? foreach (var hop in hops) { if (!ruleStepDic.ContainsKey(hop.StepFromId) || !ruleStepDic.ContainsKey(hop.StepToId) || 0 == hop.Enabled) { continue; } linkedStepFromNode = ruleStepDic[hop.StepFromId]; linkedStepToNode = ruleStepDic[hop.StepToId]; linkedStepFromNode.Next.Add(linkedStepToNode); linkedStepToNode.Previous.Add(linkedStepFromNode); } return(newLinkedSteps); }
/// <summary> /// 运行步骤节点 /// </summary> /// <param name="db"></param> /// <param name="task"></param> /// <param name="node"></param> private void RunRuleStepNode(SqlSugarClient db, DmeTask task, RuleStepLinkedListNode <DmeRuleStep> node) { // 先计算前置节点 if (node.Previous?.Count > 0) { foreach (var item in node.Previous) { RunRuleStepNode(db, task, item); } } DmeTaskRuleStep dmeTaskRuleStep = null; try { // 先判断任务的状态,是否被停止 DmeTask taskStatus = db.Queryable <DmeTask>().Single(t => t.SysCode == task.SysCode); if (null == taskStatus || taskStatus.Status.Equals(EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_STOP))) { LOG.Info($"任务[{task.SysCode}]不存在或者已被停止"); return; } dmeTaskRuleStep = this.GetTaskRuleStep(db, task, node.Value, out string cacheKey); if (dmeTaskRuleStep != null && EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_SUCCESS).Equals(dmeTaskRuleStep.Status)) { // 释放 dmeTaskRuleStep = null; LOG.Info($"任务[{task.SysCode}]下的步骤[{node.Value.SysCode}]已被计算过,并且状态为[success]"); return; } // 如果前置节点没有了,则计算当前节点内容 DmeRuleStepType ruleStepTypeTemp = db.Queryable <DmeRuleStepType>().Single(rst => rst.Id == node.Value.StepTypeId); IRuleStepData ruleStepData = RuleStepFactory.GetRuleStepData(ruleStepTypeTemp.Code, this.Repository, task, node.Value); if (null == ruleStepData) { throw new BusinessException((int)EnumSystemStatusCode.DME_ERROR, $"步骤工厂无法创建编码为[{ruleStepTypeTemp.Code}]的流程实例节点"); } dmeTaskRuleStep = new DmeTaskRuleStep { SysCode = GuidUtil.NewGuid(), TaskId = task.Id, RuleStepId = node.Value.Id, Status = EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_RUNNING), CreateTime = DateUtil.CurrentTimeMillis, LastTime = DateUtil.CurrentTimeMillis }; dmeTaskRuleStep = db.Insertable <DmeTaskRuleStep>(dmeTaskRuleStep).ExecuteReturnEntity(); // 任务步骤创建成功后,把相关信息记录在缓存中 ServiceFactory.CacheService.AddAsync(cacheKey, dmeTaskRuleStep, 60); Result stepResult = ruleStepData.Run(); UpdateRuleStep(db, dmeTaskRuleStep, cacheKey, stepResult); // 然后计算下一个步骤 if (node?.Next.Count > 0) { foreach (var item in node.Next) { RunRuleStepNode(db, task, item); } } } catch (Exception ex) { dmeTaskRuleStep.Status = EnumUtil.GetEnumDisplayName(EnumSystemStatusCode.DME_ERROR); dmeTaskRuleStep.LastTime = DateUtil.CurrentTimeMillis; // 只更新状态和最后时间 db.Updateable <DmeTaskRuleStep>(dmeTaskRuleStep).UpdateColumns(ts => new { ts.Status, ts.LastTime }).ExecuteCommand(); this.LogService.AddLogAsync(Base.Common.Log.EnumLogType.ENTITY, EnumLogLevel.ERROR, nameof(DmeTaskRuleStep), dmeTaskRuleStep.SysCode, "", ex, "", NetAssist.GetLocalHost()); } }