| | |
| | | using System.Threading.Tasks; |
| | | using Tiger.Model; |
| | | using static Tiger.Business.Biz; |
| | | using Org.BouncyCastle.Ocsp; |
| | | using Tiger.Model.Entitys.MES.Position; |
| | | using MailKit.Search; |
| | | |
| | | namespace Tiger.Business.MES.Transaction |
| | | { |
| | |
| | | public WorkBatch CurBatch { get; set; } |
| | | public IWorkBatch WorkBatch => CurBatch; |
| | | public MES_WIP_DATA CurWipSN { get; set; } |
| | | public MES_WIP_HIS CurWipSNHis { get; set; } |
| | | public List<WorkStep> Steps { get; set; } = new(); |
| | | public bool IsFinishAllSteps => Steps.Any() && !Steps.Any(q => !q.IsFinished); |
| | | public int CurStep => Steps.Where(q => !q.IsFinished).OrderBy(q => q.Sequence).FirstOrDefault()?.Sequence ?? 0; |
| | | public WorkStep CurStep { get; set; } |
| | | public List<WorkStep> NextSteps { get; set; } = new(); |
| | | public bool IsFinishNodeSteps => !Steps.Any(q => q.Type == IWorkStep.Types.Node && !q.IsFinished); |
| | | public bool IsFinishAllSteps => !Steps.Any() || !Steps.Any(q => !q.IsFinished); |
| | | //public int CurStep => Steps.Where(q => !q.IsFinished).OrderBy(q => q.Sequence).FirstOrDefault()?.Sequence ?? 0; |
| | | private DbClient CommitDB; |
| | | #endregion Propertys & Variables |
| | | |
| | |
| | | CurWipSN = null; |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 生成传入工步后续的行为到工步列表 |
| | | /// </summary> |
| | | /// <param name="parent"></param> |
| | | public void GenerateSteps(WorkStep parent) |
| | | { |
| | | //递归添加所有工步 |
| | | AddNextActToSteps(parent); |
| | | //调整工步的序号 |
| | | //while (CurBatch.Edges.Any(q => Steps.First(s => s.NodeID == q.SRC_NODE).Sequence <= Steps.First(s => s.NodeID == q.TGT_NODE).Sequence)) |
| | | //{ |
| | | // var edges = CurBatch.Edges.Where(q => Steps.First(s => s.NodeID == q.SRC_NODE).Sequence >= Steps.First(s => s.NodeID == q.TGT_NODE).Sequence).ToList(); |
| | | // foreach (var edge in edges) |
| | | // { |
| | | // var source = Steps.First(s => s.NodeID == edge.SRC_NODE); |
| | | // var target = Steps.First(s => s.NodeID == edge.TGT_NODE); |
| | | // target.Sequence = source.Sequence + 1; |
| | | // } |
| | | //} |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 添加节点的下一个行为到工步列表 |
| | | /// </summary> |
| | | /// <param name="curNode"></param> |
| | | private void AddNextActToSteps(WorkStep parent) |
| | | { |
| | | var edges = CurBatch.Edges.Where(q => q.SRC_NODE == parent.NodeID && CurBatch.NodeActs.Any(a => a.NODE_ID == parent.Node.ID && a.ID == q.TGT_NODE)).ToList(); |
| | | foreach (var edge in edges) |
| | | { |
| | | var act = CurBatch.NodeActs.First(q => q.ID == edge.TGT_NODE); |
| | | if (Steps.Any(q => q.NodeID == act.ID)) |
| | | { |
| | | var next = Steps.First(q => q.NodeID == act.ID); |
| | | next.Sequence = next.Sequence > parent.Sequence ? next.Sequence : (parent.Sequence + 1); |
| | | next.PrepNodeIDs.AddRange(parent.PrepNodeIDs); |
| | | next.PrepNodeIDs = next.PrepNodeIDs.Distinct().ToList(); |
| | | AddNextActToSteps(next); |
| | | } |
| | | else |
| | | { |
| | | var next = new WorkStep(IWorkStep.Types.Action, this) |
| | | { |
| | | NodeID = act.ID, |
| | | Sequence = parent.Sequence + 1, |
| | | Node = parent.Node, |
| | | NodeAct = act, |
| | | Setting = CurBatch.ActionSets.FirstOrDefault(q => q.ACT_ID == act.ID), |
| | | }; |
| | | next.PrepNodeIDs.AddRange(parent.PrepNodeIDs); |
| | | next.PrepNodeIDs = next.PrepNodeIDs.Distinct().ToList(); |
| | | Steps.Add(next); |
| | | AddNextActToSteps(next); |
| | | } |
| | | } |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 根据传入的工步,返回下一步可执行的工步列表 |
| | | /// </summary> |
| | | /// <param name="curStep"></param> |
| | | public List<WorkStep> GetNextSteps(WorkStep curStep) |
| | | { |
| | | var result = new List<WorkStep>(); |
| | | var nextSteps = Steps.Where(q => !q.IsFinished |
| | | && CurBatch.Edges.Any(e => e.SRC_NODE == curStep.NodeID && e.TGT_NODE == q.NodeID) |
| | | ).ToList(); |
| | | //尝试将当前工步的后续工步添加到可以执行的工步列表 |
| | | foreach (var step in nextSteps) |
| | | { |
| | | //查找有没有前置工步未完成,若有则不允许继续执行 |
| | | if (!Steps.Any(q => step.PrepNodeIDs.Any(id => id == q.NodeID && !q.IsFinished))) |
| | | { |
| | | result.Add(step); |
| | | } |
| | | } |
| | | //如果当前工步没有可执行的后续工步,则在前置工步查找还有没有后续工步没完成的工步,有则执行 |
| | | if (!result.Any()) |
| | | { |
| | | //查找有没有前置工步未完成,若有则先完成未完成的前置工步 |
| | | var prepIDs = curStep.PrepNodeIDs.Where(id => CurBatch.Edges.Any(e => e.SRC_NODE == id && Steps.Any(q => !q.IsFinished && e.TGT_NODE == q.NodeID))).ToList(); |
| | | var prepSteps = Steps.Where(q => prepIDs.Contains(q.NodeID)).OrderByDescending(q => q.Sequence).ToList(); |
| | | while (prepSteps.Any() && !result.Any()) |
| | | { |
| | | var prep = prepSteps.First(); |
| | | var prepNext = GetNextSteps(prep); |
| | | if (prepNext.Any()) |
| | | { |
| | | result = prepNext; |
| | | } |
| | | else |
| | | { |
| | | prepSteps.Remove(prep); |
| | | } |
| | | } |
| | | |
| | | } |
| | | return result.OrderBy(q => q.NodeAct.ACT_NAME).ToList(); |
| | | } |
| | | |
| | | /// <summary> |
| | | /// 开始执行下一行为工步 |
| | | /// </summary> |
| | | /// <param name="input"></param> |
| | | public ApiAction<SubmitOutput> BeginNextActionStep(SubmitInput input) |
| | | { |
| | | var result = new ApiAction<SubmitOutput>(); |
| | | //设置后续可执行的工步列表 |
| | | NextSteps = GetNextSteps(CurStep); |
| | | //尝试有没有可以直接开始的后续工步 |
| | | foreach (var step in NextSteps) |
| | | { |
| | | var canBegin = step.TryBegin(input); |
| | | //如果后续工步可以直接开始则直接执行 |
| | | if (canBegin.IsSuccessed) |
| | | { |
| | | CurStep = step; |
| | | NextSteps = GetNextSteps(CurStep); |
| | | result = canBegin; |
| | | result.Data.IsFinished = IsFinishAllSteps; |
| | | result.Data.CurWO = CurBatch.WO.ORDER_NO; |
| | | result.Data.CurBatch = CurBatch.Batch.BATCH_NO; |
| | | result.Data.CurNode = CurStep.NodeAct.ACT_NAME; |
| | | result.Data.StepActCode = CurStep.NodeAct.ACT_CODE; |
| | | result.Data.NextStepID = CurStep.ID; |
| | | |
| | | return result; |
| | | } |
| | | } |
| | | |
| | | //根据后续工步返回ApiAction |
| | | result.Data.IsFinished = IsFinishAllSteps; |
| | | result.Data.CurWO = CurBatch.WO.ORDER_NO; |
| | | result.Data.CurBatch = CurBatch.Batch.BATCH_NO; |
| | | result.Data.CurNode = CurStep.Node.NODE_NAME; |
| | | result.Data.StepActCode = CurStep.NodeAct.ACT_CODE; |
| | | result.Data.NextStepID = ""; |
| | | |
| | | //根据后续可执行工步列表返回相应的操作提示 |
| | | if (NextSteps.Count == 1) |
| | | { |
| | | result.LocaleMsg = NextSteps.First().GetBeginMsg(); |
| | | } |
| | | else |
| | | { |
| | | result.LocaleMsg = new(T(L("MES.Transaction.Position.PleaseSelectNextStep"), input.Locale) + "\r\n" + |
| | | string.Join("\r\n", NextSteps.Select(q => " >> " + T(q.GetBeginMsg(), input.Locale)))); |
| | | } |
| | | return result; |
| | | } |
| | | |
| | | #endregion Functions |
| | | |
| | | public override bool Close(bool needSaveHistoryLog = false) |