服务端的TigerApi 框架,基于.NET6 2024 版本
Rodney Chen
2024-07-25 3678120ac63c176b5f261ef12e67c4ce7f1b320f
Tiger.Business.MES/Transaction/Position.cs
@@ -10,9 +10,7 @@
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
{
@@ -41,6 +39,9 @@
            //if (CurFactory.IsNullOrEmpty()) throw new InvalidDataException($"MES.Transaction.Position.FactoryNotExistsException", new Exception($"{postCode}|{CurWorkshop.FTY_CODE}"));
            if (CurFactory.IsNullOrEmpty()) throw new InvalidDataException($"岗位[{postCode}]所属的工厂[{CurWorkshop.FTY_CODE}]不存在,请先设置所属工厂", new Exception($"{postCode}|{CurWorkshop.FTY_CODE}"));
            //加载当前产线的班制
            CurShiftSys = Biz.Db.Queryable<MES_SHIFT_SYS>().Where(q => q.SFTS_CODE == CurLine.SFTS_CODE).IncludesAllFirstLayer().IncludesAllSecondLayer(q => q.Shifts).First();
            return this;
        }
@@ -51,13 +52,17 @@
        public MES_WORKSHOP CurWorkshop { get; set; }
        public MES_LINE CurLine { get; set; }
        public MES_POSITION CurPosition { get; set; }
        public MES_SHIFT_SYS CurShiftSys { get; set; }
        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
@@ -120,6 +125,27 @@
        }
        /// <summary>
        /// 获取当前时间所属的班制班次时段
        /// </summary>
        public ShiftPeriod GetShiftPeriodForNow()
        {
            var time = DateTime.Now.ToString("HHmm").ToInt32();
            foreach (var shift in CurShiftSys.Shifts)
            {
                var period = shift.Periods.Where(q => q.PRD_BEGIN <= time && time <= q.PRD_END).FirstOrDefault();
                if (!period.IsNullOrEmpty())
                {
                    var result = new ShiftPeriod();
                    result.ShiftSys = CurShiftSys;
                    result.Shift = shift;
                    result.Period = period;
                    return result;
                }
            }
            return null;
        }
        /// <summary>
        /// 重置当前工步
        /// </summary>
        public void ResetSteps()
@@ -128,6 +154,159 @@
            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="parent"></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.Add(parent.NodeID);
                    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.Add(parent.NodeID);
                    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)