From 01a5cb6f77739630a88fc2f95be694b53ade0d41 Mon Sep 17 00:00:00 2001
From: Rodney Chen <rodney.chen@hotmail.com>
Date: 星期五, 19 七月 2024 14:14:47 +0800
Subject: [PATCH] 工步修改为支持并行执行行为,优化工步执行逻辑

---
 Tiger.Api/Language.db                                            |    0 
 Tiger.Business.MES/Transaction/CollectNode.cs                    |  304 ++++++----
 Tiger.Business.MES/Transaction/PackingNode.cs                    |  314 +++++++----
 Tiger.Business.MES/Transaction/Position.cs                       |  160 +++++
 Tiger.Model.Net/Entitys/MES/ParameterEntity/PositionParameter.cs |   46 +
 Tiger.Business/MES/Biz.WorkStep.cs                               |   32 
 Tiger.IBusiness/MES/Transaction/ITestNode.cs                     |    2 
 Tiger.Model.Net/Entitys/MES/MES_ROUTE_NODE_ACT.cs                |  194 +++---
 Tiger.Business.MES/Transaction/TestNode.cs                       |  302 ++++++----
 Tiger.IBusiness/MES/IWorkStep.cs                                 |   11 
 Tiger.Business.MES/WorkAction/IPQC.cs                            |  108 +++
 Tiger.Model.Net/Entitys/MES/MES_WO_NODE_ACT.cs                   |   13 
 Tiger.IBusiness/MES/Transaction/IPackingNode.cs                  |    2 
 Tiger.Business.MES/WorkAction/PrintLabel.cs                      |   43 +
 Tiger.IBusiness/MES/IWorkAction.cs                               |   14 
 Tiger.IBusiness/MES/Transaction/IPosition.cs                     |   15 
 Tiger.IBusiness/MES/Transaction/ICollectNode.cs                  |    2 
 Tiger.Business/Language/Biz.Language.cs                          |    8 
 18 files changed, 1,061 insertions(+), 509 deletions(-)

diff --git a/Tiger.Api/Language.db b/Tiger.Api/Language.db
index 462791f..6bede17 100644
--- a/Tiger.Api/Language.db
+++ b/Tiger.Api/Language.db
Binary files differ
diff --git a/Tiger.Business.MES/Transaction/CollectNode.cs b/Tiger.Business.MES/Transaction/CollectNode.cs
index 3516926..c9bc4ea 100644
--- a/Tiger.Business.MES/Transaction/CollectNode.cs
+++ b/Tiger.Business.MES/Transaction/CollectNode.cs
@@ -35,18 +35,18 @@
         /// </summary>
         /// <param name="input"></param>
         /// <returns></returns>
-        public async Task<ApiAction> Submit(SubmitInput input)
+        public async Task<ApiAction<SubmitOutput>> Submit(SubmitInput input)
         {
-            var action = new ApiAction();
+            var action = new ApiAction<SubmitOutput>();
             try
             {
-                //宸ユ鍒楄〃涓虹┖鏃讹紝璁や负闇�瑕佸厛鎵弿杩囩珯鏉$爜
-                if (Steps.IsNullOrEmpty())
+                //宸ユ鍒楄〃涓虹┖鎴栬�呭伐搴忚妭鐐瑰伐姝ユ湁鏈畬鎴愭椂锛屼紭鍏堝畬鎴愬伐搴忚妭鐐瑰伐姝�
+                if (Steps.IsNullOrEmpty() || !IsFinishNodeSteps)
                 {
                     //鍏堝垽鏂綋鍓嶅伐鍗曚笉涓虹┖涓斿綋鍓嶅矖浣嶅湪褰撳墠宸ュ崟鏄笉鏄绔欙紝濡傛灉鏄垯涓嶅厑璁稿彉鏇村綋鍓嶅伐鍗曪紝灏濊瘯鎶婃潯鐮佺粦瀹氬埌褰撳墠宸ュ崟
                     if (!CurBatch.IsNullOrEmpty() && CurBatch.IsFirstNode(PostCode))
                     {
-                        action = ScanSn(action, input);
+                        action = NodeSubmit(action, input);
                         return action;
                     }
                     //褰撳墠宀椾綅鍦ㄥ綋鍓嶅伐鍗曚笉鏄绔欙紝鍒欐煡鎵炬潯鐮佸凡缁戝畾鐨勫伐鍗曞綋浣滃綋鍓嶅伐鍗�
@@ -64,12 +64,13 @@
                                 var result = await SelectOrder(new() { AuthOption = input.AuthOption, OrderNo = wosn.Batch.ORDER_NO });
                                 if (!result.IsSuccessed)
                                 {
-                                    action = result;
+                                    action.IsSuccessed = result.IsSuccessed;
+                                    action.LocaleMsg = result.LocaleMsg;
                                     return action;
                                 }
                             }
                             //鏉$爜杩囩珯
-                            action = ScanSn(action, input);
+                            action = NodeSubmit(action, input);
                             return action;
                         }
                         //鏌ユ壘涓嶅埌鏉$爜宸茬粦瀹氱殑宸ュ崟
@@ -94,22 +95,47 @@
                         }
                     }
                 }
-                //瀹屾垚绗竴姝ワ紝鍚庡紑濮嬫墽琛屽綋鍓嶅伐搴忕殑琛屼负鍒楄〃
-                else if (Steps.First().IsFinished && !IsFinishAllSteps)
+                //瀹屾垚宸ュ簭鑺傜偣宸ユ鍚庯紝鍚庡紑濮嬫墽琛屽綋鍓嶅伐搴忕殑琛屼负宸ユ
+                else if (IsFinishNodeSteps && !IsFinishAllSteps)
                 {
-                    //var curStep = Steps.Where(q => !q.IsFinished).OrderBy(q => q.Sequence).First();
-                    var curStep = Steps.Where(q => q.ID == input.StepID).FirstOrDefault();
-                    if (!curStep.IsNullOrEmpty())
+                    var submitStep = Steps.Where(q => q.ID == input.CurStepID && !q.IsFinished).FirstOrDefault();
+                    if (submitStep.IsNullOrEmpty())
                     {
-                        var result = curStep.Submit(input);
-                        result.Data.StepID = curStep.ID;
-                        result.Data.IsFinished = IsFinishAllSteps;
-                        result.Data.CurStep = CurStep;
+                        action = BeginNextActionStep(input);
+                        return action;
+                    }
+                    else
+                    {
+                        var result = submitStep.Submit(input);
+                        //濡傛灉褰撳墠宸ユ宸插畬鎴愶紝寮�濮嬫墽琛屼笅涓�宸ユ
+                        if (result.IsSuccessed && submitStep.IsFinished)
+                        {
+                            result = BeginNextActionStep(input);
+                        }
+                        //濡傛灉褰撳墠宸ユ鏈畬鎴�
+                        else
+                        {
+                            //琛屼负鎵ц鍑洪敊锛屽伐姝ヨ閲嶇疆
+                            if (Steps.IsNullOrEmpty())
+                            {
+                                result.LocaleMsg = new(Biz.T(result.LocaleMsg, input.Locale) + Biz.T(Biz.L("MES.Transaction.Position.RescanSN"), input.Locale));
+                            }
+                            else
+                            {
+                                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;
+                            }
+                        }
+                        //濡傛灉鎵�鏈夊伐姝ラ兘瀹屾垚
                         if (IsFinishAllSteps)
                         {
-                            return DoIfFinishAllSteps(result.ToApiAction());
+                            return DoIfFinishAllSteps(result);
                         }
-                        return result.ToApiAction();
+                        return result;
                     }
                 }
                 //娌℃湁鍙墽琛岀殑宸ユ
@@ -126,130 +152,168 @@
         }
 
         /// <summary>
-        /// 鎵弿杩囩珯鏉$爜
+        /// 宸ュ簭鑺傜偣宸ユ鎻愪氦鏁版嵁
         /// </summary>
         /// <param name="action"></param>
         /// <param name="input"></param>
         /// <returns></returns>
-        public ApiAction ScanSn(ApiAction action, SubmitInput input)
+        public ApiAction<SubmitOutput> NodeSubmit(ApiAction<SubmitOutput> action, SubmitInput input)
         {
             try
             {
-                //缁戝畾鏉$爜鍒板伐鍗�
-                if (!CurBatch.WoSNs.Any(q => q.SN == input.SN))
+                //褰撳伐姝ュ垪琛ㄤ负绌猴紝鍒欐墽琛屽綋鍓嶅伐搴忕殑蹇呰閫昏緫褰撲綔绗竴涓伐搴忚妭鐐癸紝瀹屾垚鍚庢寜闇�姹傚垱寤哄悗缁殑宸ユ鍒楄〃
+                if (Steps.IsNullOrEmpty())
                 {
-                    CurBatch.WoSNs.Add(new()
+                    //缁戝畾鏉$爜鍒板伐鍗�
+                    if (!CurBatch.WoSNs.Any(q => q.SN == input.SN))
                     {
-                        WORK_ORDER = CurBatch.Batch.ORDER_NO,
-                        SN = input.SN,
-                        STATUS = BIZ_MES_WO_SN.STATUSs.NotInput.GetValue(),
-                        BATCH_NO = CurBatch.Batch.BATCH_NO,
-                    });
-                }
-                var woSN = CurBatch.WoSNs.FirstOrDefault(q => q.SN == input.SN);
-                var curNode = CurBatch.GetNode(PostCode);
-
-                //鏉$爜杩囩珯
-                var wipSN = Biz.Db.Queryable<MES_WIP_DATA>().First(q => q.SN == input.SN && q.BATCH_NO == CurBatch.Batch.BATCH_NO) ?? new MES_WIP_DATA()
-                {
-                    SN = input.SN,
-                    STATUS = MES_WIP_DATA.STATUSs.Init.GetValue(),
-                    ITEM_CODE = CurBatch.WO.ITEM_CODE,
-                    WORK_ORDER = CurBatch.Batch.ORDER_NO,
-                    BATCH_NO = CurBatch.Batch.BATCH_NO,
-                    HOLD_FLAG = "N",
-                    REWORK_FLAG = CurBatch.WO.ORDER_TYPE == BIZ_MES_WO.ORDER_TYPEs.Rework.GetValue() ? "Y" : "N",
-                    FINISHED_FLAG = "N",
-                    INV_FLAG = "N",
-                    DFT_FLAG = "N",
-                    DFT_COUNT = 0,
-                };
-                wipSN.AUTH_PROD = CurLine.LINE_CODE;
-                wipSN.STATUS = wipSN.STATUS > 0 ? MES_WIP_DATA.STATUSs.OK.GetValue() : wipSN.STATUS;
-                wipSN.ROT_CODE = CurBatch.WO.ROUTE_CODE;
-                wipSN.NODE_ID = curNode.ID;
-                wipSN.NODE_NAME = curNode.NODE_NAME;
-                wipSN.FTY_CODE = CurFactory.FTY_CODE;
-                wipSN.WS_CODE = CurWorkshop.WS_CODE;
-                wipSN.LINE_CODE = CurLine.LINE_CODE;
-                wipSN.POST_CODE = CurPosition.POST_CODE;
-                wipSN.OPER_CODE = curNode.OPER_CODE;
-                wipSN.SEGMENT = curNode.SEGMENT;
-                wipSN.OPERATION_TIME = DateTime.Now;
-                wipSN.SFTS_CODE = CurLine.SFTS_CODE;
-                //wipSN.SFT_CODE = CurBatch.WO.ROUTE_CODE;
-                //wipSN.PRD_CODE = CurBatch.WO.ROUTE_CODE;
-                CurBatch.StartWorking(UserCode);
-
-                //濡傛灉鏄姇鍏ョ珯
-                if (curNode.IS_INPUT == "Y")
-                {
-                    woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Inputed.GetValue();
-                    wipSN.STATUS = MES_WIP_DATA.STATUSs.Input.GetValue();
-                    wipSN.INLINE_DATE = DateTime.Now;
-                }
-                //濡傛灉鏄骇鍑虹珯
-                if (curNode.IS_OUTPUT == "Y")
-                {
-                    woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Finished.GetValue();
-                    wipSN.STATUS = MES_WIP_DATA.STATUSs.Finished.GetValue();
-                    wipSN.OUTLINE_DATE = DateTime.Now;
-                }
-                //濡傛灉鏈夋彁浜や笉鑹�
-                if (!input.DFT_CODE.IsNullOrEmpty())
-                {
-                    wipSN.STATUS = MES_WIP_DATA.STATUSs.NG.GetValue();
-                    wipSN.DFT_FLAG = "Y";
-                    wipSN.DFT_COUNT++;
-                    wipSN.DFT_CODE = input.DFT_CODE;
-                }
-
-                CurWipSNHis = new MES_WIP_HIS(CurWipSN = wipSN, $"宸ュ崟[{wipSN.WORK_ORDER}]鏉$爜[{wipSN.SN}]鍦ㄥ矖浣峓{wipSN.POST_CODE}]杩囩珯宸ュ簭[{wipSN.NODE_NAME}]鎴愬姛");
-
-                //鍒濆鍖栧伐姝ュ垪琛�
-                Steps.Clear();
-                var curStep = new Biz.WorkStep(curNode.ID, IWorkStep.Types.Node)
-                {
-                    Sequence = Steps.Count + 1,
-                    Node = curNode,
-                    DBSubmitAction = () =>
-                    {
-                        var db = GetCommitDB();
-                        db.Storageable(woSN, UserCode).ExecuteCommand();
-                        db.Storageable(wipSN, UserCode).ExecuteCommand();
-                        db.Storageable(CurWipSNHis, UserCode).ExecuteCommand();
+                        CurBatch.WoSNs.Add(new()
+                        {
+                            WORK_ORDER = CurBatch.Batch.ORDER_NO,
+                            SN = input.SN,
+                            STATUS = BIZ_MES_WO_SN.STATUSs.NotInput.GetValue(),
+                            BATCH_NO = CurBatch.Batch.BATCH_NO,
+                        });
                     }
-                };
-                Steps.Add(curStep);
+                    var woSN = CurBatch.WoSNs.FirstOrDefault(q => q.SN == input.SN);
+                    var curNode = CurBatch.GetNode(PostCode);
 
-                //濡傛灉褰撳墠宸ュ簭鑺傜偣鏈夎涓哄垯娣诲姞鍒板伐姝ュ垪琛�
-                var acts = CurBatch.NodeActs.Where(q => q.NODE_ID == curNode.ID).ToList();
-                foreach (var act in acts)
-                {
-                    Steps.Add(new Biz.WorkStep(act.ID, IWorkStep.Types.Action)
+                    //鏉$爜杩囩珯
+                    var wipSN = Biz.Db.Queryable<MES_WIP_DATA>().First(q => q.SN == input.SN && q.BATCH_NO == CurBatch.Batch.BATCH_NO) ?? new MES_WIP_DATA()
                     {
+                        SN = input.SN,
+                        STATUS = MES_WIP_DATA.STATUSs.Init.GetValue(),
+                        ITEM_CODE = CurBatch.WO.ITEM_CODE,
+                        WORK_ORDER = CurBatch.Batch.ORDER_NO,
+                        BATCH_NO = CurBatch.Batch.BATCH_NO,
+                        HOLD_FLAG = "N",
+                        REWORK_FLAG = CurBatch.WO.ORDER_TYPE == BIZ_MES_WO.ORDER_TYPEs.Rework.GetValue() ? "Y" : "N",
+                        FINISHED_FLAG = "N",
+                        INV_FLAG = "N",
+                        DFT_FLAG = "N",
+                        DFT_COUNT = 0,
+                    };
+                    wipSN.AUTH_PROD = CurLine.LINE_CODE;
+                    wipSN.STATUS = wipSN.STATUS > 0 ? MES_WIP_DATA.STATUSs.OK.GetValue() : wipSN.STATUS;
+                    wipSN.ROT_CODE = CurBatch.WO.ROUTE_CODE;
+                    wipSN.NODE_ID = curNode.ID;
+                    wipSN.NODE_NAME = curNode.NODE_NAME;
+                    wipSN.FTY_CODE = CurFactory.FTY_CODE;
+                    wipSN.WS_CODE = CurWorkshop.WS_CODE;
+                    wipSN.LINE_CODE = CurLine.LINE_CODE;
+                    wipSN.POST_CODE = CurPosition.POST_CODE;
+                    wipSN.OPER_CODE = curNode.OPER_CODE;
+                    wipSN.SEGMENT = curNode.SEGMENT;
+                    wipSN.OPERATION_TIME = DateTime.Now;
+                    wipSN.SFTS_CODE = CurLine.SFTS_CODE;
+                    //wipSN.SFT_CODE = CurBatch.WO.ROUTE_CODE;
+                    //wipSN.PRD_CODE = CurBatch.WO.ROUTE_CODE;
+                    CurBatch.StartWorking(UserCode);
+
+                    //濡傛灉鏄姇鍏ョ珯
+                    if (curNode.IS_INPUT == "Y")
+                    {
+                        woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Inputed.GetValue();
+                        wipSN.STATUS = MES_WIP_DATA.STATUSs.Input.GetValue();
+                        wipSN.INLINE_DATE = DateTime.Now;
+                    }
+                    //濡傛灉鏄骇鍑虹珯
+                    if (curNode.IS_OUTPUT == "Y")
+                    {
+                        woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Finished.GetValue();
+                        wipSN.STATUS = MES_WIP_DATA.STATUSs.Finished.GetValue();
+                        wipSN.OUTLINE_DATE = DateTime.Now;
+                    }
+                    //濡傛灉鏈夋彁浜や笉鑹�
+                    if (!input.DFT_CODE.IsNullOrEmpty())
+                    {
+                        wipSN.STATUS = MES_WIP_DATA.STATUSs.NG.GetValue();
+                        wipSN.DFT_FLAG = "Y";
+                        wipSN.DFT_COUNT++;
+                        wipSN.DFT_CODE = input.DFT_CODE;
+                    }
+
+                    CurWipSNHis = new MES_WIP_HIS(CurWipSN = wipSN, $"宸ュ崟[{wipSN.WORK_ORDER}]鏉$爜[{wipSN.SN}]鍦ㄥ矖浣峓{wipSN.POST_CODE}]杩囩珯宸ュ簭[{wipSN.NODE_NAME}]鎴愬姛");
+
+                    //鍒濆鍖栧伐姝ュ垪琛�
+                    Steps.Clear();
+                    var curStep = new Biz.WorkStep(IWorkStep.Types.Node, this)
+                    {
+                        NodeID = curNode.ID,
                         Sequence = Steps.Count + 1,
                         Node = curNode,
-                        NodeAct = act,
-                        Setting = CurBatch.ActionSets.FirstOrDefault(q => q.ACT_ID == act.ID),
-                    });
+                        DBSubmitAction = () =>
+                        {
+                            var db = GetCommitDB();
+                            db.Storageable(woSN, UserCode).ExecuteCommand();
+                            db.Storageable(wipSN, UserCode).ExecuteCommand();
+                            db.Storageable(CurWipSNHis, UserCode).ExecuteCommand();
+                        }
+                    };
+                    Steps.Add(curStep);
+
+                    //鏈夐渶瑕佸垯娣诲姞宸ュ簭鑺傜偣鐨勫叾浠栧伐姝�
+
+                    //鏈�鍚庢坊鍔犲綋鍓嶅伐搴忕殑琛屼负宸ユ
+                    GenerateSteps(curStep);
+
+                    //瀹屾垚绗竴涓伐搴忚妭鐐瑰伐姝�
+                    curStep.IsFinished = true;
+                    CurStep = curStep;
+                }
+                else if (!IsFinishNodeSteps)
+                {
+                    var curStep = Steps.Where(q => q.Type == IWorkStep.Types.Node && !q.IsFinished).OrderBy(q => q.Sequence).First();
+
+                    //瀹屾垚褰撳墠宸ュ簭鑺傜偣宸ユ
+                    curStep.IsFinished = true;
+                    CurStep = curStep;
                 }
 
-                //瀹屾垚褰撳墠宸ュ簭鑺傜偣
-                curStep.IsFinished = true;
                 //鏈畬鎴愭墍鏈夊伐姝�
                 if (!IsFinishAllSteps)
                 {
-                    var next = Steps.Where(q => !q.IsFinished).OrderBy(q => q.Sequence).First();
-                    var result = next.Begin(this);
-                    result.Data.StepID = next.ID;
-                    result.Data.IsFinished = IsFinishAllSteps;
-                    result.Data.CurStep = CurStep;
-                    return result.ToApiAction();
+                    var result = new ApiAction<SubmitOutput>();
+                    //鏈畬鎴愭墍鏈夊伐搴忚妭鐐瑰伐姝�
+                    if (!IsFinishNodeSteps)
+                    {
+                        var next = Steps.Where(q => q.Type == IWorkStep.Types.Node && !q.IsFinished).OrderBy(q => q.Sequence).First();
+                        //璁剧疆鍚庣画鍙墽琛岀殑宸ユ鍒楄〃
+                        NextSteps.Clear();
+                        NextSteps.Add(next);
+                        //鏍规嵁鍚庣画宸ユ杩斿洖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.NextStepID = next.ID;
+
+                        //鏍规嵁宸ュ簭鑺傜偣宸ユ鐨勫簭鍙疯繑鍥炵浉搴旂殑鎿嶄綔鎻愮ず
+                        switch (next.Sequence)
+                        {
+                            case 2:
+                                //action.LocaleMsg = new($"璇锋墽琛岀浜屾");
+                                result.LocaleMsg = new("MES.Transaction.CollectNode.绗簩姝ユ搷浣滄彁绀�");
+                                break;
+                            default:
+                                break;
+                        }
+                    }
+                    //宸插畬鎴愭墍鏈夊伐搴忚妭鐐瑰伐姝ワ紝寮�濮嬫墽琛岃涓哄伐姝�
+                    else
+                    {
+                        result = BeginNextActionStep(input);
+                    }
+                    return result;
                 }
                 //宸插畬鎴愭墍鏈夊伐姝�
                 else
                 {
+                    action.Data.IsFinished = IsFinishAllSteps;
+                    action.Data.CurWO = CurBatch.WO.ORDER_NO;
+                    action.Data.CurBatch = CurBatch.Batch.BATCH_NO;
+                    action.Data.CurNode = CurStep.Node.NODE_NAME;
+                    action.Data.NextStepID = "";
                     action = DoIfFinishAllSteps(action);
                 }
             }
@@ -266,7 +330,7 @@
         /// </summary>
         /// <param name="action"></param>
         /// <returns></returns>
-        public ApiAction DoIfFinishAllSteps(ApiAction action)
+        public ApiAction<SubmitOutput> DoIfFinishAllSteps(ApiAction<SubmitOutput> action)
         {
             //淇濆瓨鏁版嵁搴�
             var dbTran = GetCommitDB().UseTran(() =>
diff --git a/Tiger.Business.MES/Transaction/PackingNode.cs b/Tiger.Business.MES/Transaction/PackingNode.cs
index d257d53..5be4048 100644
--- a/Tiger.Business.MES/Transaction/PackingNode.cs
+++ b/Tiger.Business.MES/Transaction/PackingNode.cs
@@ -35,18 +35,18 @@
         /// </summary>
         /// <param name="input"></param>
         /// <returns></returns>
-        public async Task<ApiAction> Submit(SubmitInput input)
+        public async Task<ApiAction<SubmitOutput>> Submit(SubmitInput input)
         {
-            var action = new ApiAction();
+            var action = new ApiAction<SubmitOutput>();
             try
             {
-                //宸ユ鍒楄〃涓虹┖鏃讹紝璁や负闇�瑕佸厛鎵弿杩囩珯鏉$爜
-                if (Steps.IsNullOrEmpty())
+                //宸ユ鍒楄〃涓虹┖鎴栬�呭伐搴忚妭鐐瑰伐姝ユ湁鏈畬鎴愭椂锛屼紭鍏堝畬鎴愬伐搴忚妭鐐瑰伐姝�
+                if (Steps.IsNullOrEmpty() || !IsFinishNodeSteps)
                 {
 	                //鍏堝垽鏂綋鍓嶅伐鍗曚笉涓虹┖涓斿綋鍓嶅矖浣嶅湪褰撳墠宸ュ崟鏄笉鏄绔欙紝濡傛灉鏄垯涓嶅厑璁稿彉鏇村綋鍓嶅伐鍗曪紝灏濊瘯鎶婃潯鐮佺粦瀹氬埌褰撳墠宸ュ崟
 	                if (!CurBatch.IsNullOrEmpty() && CurBatch.IsFirstNode(PostCode))
 	                {
-	                    action = ScanSn(action, input);
+	                    action = NodeSubmit(action, input);
 	                    return action;
 	                }
 	                //褰撳墠宀椾綅鍦ㄥ綋鍓嶅伐鍗曚笉鏄绔欙紝鍒欐煡鎵炬潯鐮佸凡缁戝畾鐨勫伐鍗曞綋浣滃綋鍓嶅伐鍗�
@@ -64,12 +64,13 @@
 	                            var result = await SelectOrder(new() { AuthOption = input.AuthOption, OrderNo = wosn.Batch.ORDER_NO });
 	                            if (!result.IsSuccessed)
 	                            {
-	                                action = result;
-	                                return action;
+	                                action.IsSuccessed = result.IsSuccessed;
+                                    action.LocaleMsg = result.LocaleMsg;
+                                    return action;
 	                            }
 	                        }
 	                        //鏉$爜杩囩珯
-	                        action = ScanSn(action, input);
+	                        action = NodeSubmit(action, input);
 	                        return action;
 	                    }
 	                    //鏌ユ壘涓嶅埌鏉$爜宸茬粦瀹氱殑宸ュ崟
@@ -94,22 +95,47 @@
 	                    }
 	                }
                 }
-                //瀹屾垚绗竴姝ワ紝鍚庡紑濮嬫墽琛屽綋鍓嶅伐搴忕殑琛屼负鍒楄〃
-                else if(Steps.First().IsFinished && !IsFinishAllSteps)
+                //瀹屾垚宸ュ簭鑺傜偣宸ユ鍚庯紝鍚庡紑濮嬫墽琛屽綋鍓嶅伐搴忕殑琛屼负宸ユ
+                else if(IsFinishNodeSteps && !IsFinishAllSteps)
                 {
-                    //var curStep = Steps.Where(q => !q.IsFinished).OrderBy(q => q.Sequence).First();
-                    var curStep = Steps.Where(q => q.ID == input.StepID).FirstOrDefault();
-                    if (!curStep.IsNullOrEmpty())
+                    var submitStep = Steps.Where(q => q.ID == input.CurStepID && !q.IsFinished).FirstOrDefault();
+                    if (submitStep.IsNullOrEmpty())
                     {
-                        var result = curStep.Submit(input);
-                        result.Data.StepID = curStep.ID;
-                        result.Data.IsFinished = IsFinishAllSteps;
-                        result.Data.CurStep = CurStep;
+                        action = BeginNextActionStep(input);
+                        return action;
+                    }
+                    else
+                    {
+                        var result = submitStep.Submit(input);
+                        //濡傛灉褰撳墠宸ユ宸插畬鎴愶紝寮�濮嬫墽琛屼笅涓�宸ユ
+                        if (result.IsSuccessed && submitStep.IsFinished)
+                        {
+                            result = BeginNextActionStep(input);
+                        }
+                        //濡傛灉褰撳墠宸ユ鏈畬鎴�
+                        else
+                        {
+                            //琛屼负鎵ц鍑洪敊锛屽伐姝ヨ閲嶇疆
+                            if (Steps.IsNullOrEmpty())
+                            {
+                                result.LocaleMsg = new(Biz.T(result.LocaleMsg, input.Locale) + Biz.T(Biz.L("MES.Transaction.Position.RescanSN"), input.Locale));
+                            }
+                            else
+                            {
+                                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;
+                            }
+                        }
+                        //濡傛灉鎵�鏈夊伐姝ラ兘瀹屾垚
                         if (IsFinishAllSteps)
                         {
-                            return DoIfFinishAllSteps(result.ToApiAction());
+                            return DoIfFinishAllSteps(result);
                         }
-                        return result.ToApiAction();
+                        return result;
                     }
                 }
                 //娌℃湁鍙墽琛岀殑宸ユ
@@ -126,129 +152,168 @@
         }
 
         /// <summary>
-        /// 鎵弿杩囩珯鏉$爜
+        /// 宸ュ簭鑺傜偣宸ユ鎻愪氦鏁版嵁
         /// </summary>
         /// <param name="action"></param>
         /// <param name="input"></param>
         /// <returns></returns>
-        public ApiAction ScanSn(ApiAction action, SubmitInput input)
+        public ApiAction<SubmitOutput> NodeSubmit(ApiAction<SubmitOutput> action, SubmitInput input)
         {
             try
             {
-                //缁戝畾鏉$爜鍒板伐鍗�
-                if (!CurBatch.WoSNs.Any(q => q.SN == input.SN))
+                //褰撳伐姝ュ垪琛ㄤ负绌猴紝鍒欐墽琛屽綋鍓嶅伐搴忕殑蹇呰閫昏緫褰撲綔绗竴涓伐搴忚妭鐐癸紝瀹屾垚鍚庢寜闇�姹傚垱寤哄悗缁殑宸ユ鍒楄〃
+                if (Steps.IsNullOrEmpty())
                 {
-                    CurBatch.WoSNs.Add(new()
+	                //缁戝畾鏉$爜鍒板伐鍗�
+	                if (!CurBatch.WoSNs.Any(q => q.SN == input.SN))
+	                {
+	                    CurBatch.WoSNs.Add(new()
+	                    {
+	                        WORK_ORDER = CurBatch.Batch.ORDER_NO,
+	                        SN = input.SN,
+	                        STATUS = BIZ_MES_WO_SN.STATUSs.NotInput.GetValue(),
+	                        BATCH_NO = CurBatch.Batch.BATCH_NO,
+	                    });
+	                }
+	                var woSN = CurBatch.WoSNs.FirstOrDefault(q => q.SN == input.SN);
+	                var curNode = CurBatch.GetNode(PostCode);
+	
+	                //鏉$爜杩囩珯
+	                var wipSN = Biz.Db.Queryable<MES_WIP_DATA>().First(q => q.SN == input.SN && q.BATCH_NO == CurBatch.Batch.BATCH_NO) ?? new MES_WIP_DATA()
+	                {
+	                    SN = input.SN,
+	                    STATUS = MES_WIP_DATA.STATUSs.Init.GetValue(),
+	                    ITEM_CODE = CurBatch.WO.ITEM_CODE,
+	                    WORK_ORDER = CurBatch.Batch.ORDER_NO,
+	                    BATCH_NO = CurBatch.Batch.BATCH_NO,
+	                    HOLD_FLAG = "N",
+	                    REWORK_FLAG = CurBatch.WO.ORDER_TYPE == BIZ_MES_WO.ORDER_TYPEs.Rework.GetValue() ? "Y" : "N",
+	                    FINISHED_FLAG = "N",
+	                    INV_FLAG = "N",
+	                    DFT_FLAG = "N",
+	                    DFT_COUNT = 0,
+	                };
+	                wipSN.AUTH_PROD = CurLine.LINE_CODE;
+	                wipSN.STATUS = wipSN.STATUS > 0 ? MES_WIP_DATA.STATUSs.OK.GetValue() : wipSN.STATUS;
+	                wipSN.ROT_CODE = CurBatch.WO.ROUTE_CODE;
+	                wipSN.NODE_ID = curNode.ID;
+	                wipSN.NODE_NAME = curNode.NODE_NAME;
+	                wipSN.FTY_CODE = CurFactory.FTY_CODE;
+	                wipSN.WS_CODE = CurWorkshop.WS_CODE;
+	                wipSN.LINE_CODE = CurLine.LINE_CODE;
+	                wipSN.POST_CODE = CurPosition.POST_CODE;
+	                wipSN.OPER_CODE = curNode.OPER_CODE;
+	                wipSN.SEGMENT = curNode.SEGMENT;
+	                wipSN.OPERATION_TIME = DateTime.Now;
+	                wipSN.SFTS_CODE = CurLine.SFTS_CODE;
+	                //wipSN.SFT_CODE = CurBatch.WO.ROUTE_CODE;
+	                //wipSN.PRD_CODE = CurBatch.WO.ROUTE_CODE;
+	                CurBatch.StartWorking(UserCode);
+	
+	                //濡傛灉鏄姇鍏ョ珯
+	                if (curNode.IS_INPUT == "Y")
+	                {
+	                    woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Inputed.GetValue();
+	                    wipSN.STATUS = MES_WIP_DATA.STATUSs.Input.GetValue();
+	                    wipSN.INLINE_DATE = DateTime.Now;
+	                }
+	                //濡傛灉鏄骇鍑虹珯
+	                if (curNode.IS_OUTPUT == "Y")
+	                {
+	                    woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Finished.GetValue();
+	                    wipSN.STATUS = MES_WIP_DATA.STATUSs.Finished.GetValue();
+	                    wipSN.OUTLINE_DATE = DateTime.Now;
+	                }
+	                //濡傛灉鏈夋彁浜や笉鑹�
+	                if (!input.DFT_CODE.IsNullOrEmpty())
+	                {
+	                    wipSN.STATUS = MES_WIP_DATA.STATUSs.NG.GetValue();
+	                    wipSN.DFT_FLAG = "Y";
+	                    wipSN.DFT_COUNT++;
+	                    wipSN.DFT_CODE = input.DFT_CODE;
+	                }
+	
+	                CurWipSNHis = new MES_WIP_HIS(CurWipSN = wipSN, $"宸ュ崟[{wipSN.WORK_ORDER}]鐨勬潯鐮乕{wipSN.SN}]鍦ㄥ矖浣峓{wipSN.POST_CODE}]宸ュ簭[{wipSN.NODE_NAME}]杩囩珯鎴愬姛锛岀姸鎬乕{wipSN.STATUS.GetEnumDesc<MES_WIP_DATA.STATUSs>()}]");
+	
+	                //鍒濆鍖栧伐姝ュ垪琛�
+	                Steps.Clear();
+	                var curStep = new Biz.WorkStep(IWorkStep.Types.Node, this) 
                     {
-                        WORK_ORDER = CurBatch.Batch.ORDER_NO,
-                        SN = input.SN,
-                        STATUS = BIZ_MES_WO_SN.STATUSs.NotInput.GetValue(),
-                        BATCH_NO = CurBatch.Batch.BATCH_NO,
-                    });
-                }
-                var woSN = CurBatch.WoSNs.FirstOrDefault(q => q.SN == input.SN);
-                var curNode = CurBatch.GetNode(PostCode);
+	                    NodeID = curNode.ID,
+	                    Sequence = Steps.Count + 1,
+	                    Node = curNode,
+	                    DBSubmitAction = () =>
+	                    {
+	                        var db = GetCommitDB();
+	                        db.Storageable(woSN, UserCode).ExecuteCommand();
+	                        db.Storageable(wipSN, UserCode).ExecuteCommand();
+	                        db.Storageable(CurWipSNHis, UserCode).ExecuteCommand();
+	                    }
+	                };
+	                Steps.Add(curStep);
+	
+	                //鏈夐渶瑕佸垯娣诲姞宸ュ簭鑺傜偣鐨勫叾浠栧伐姝�
+	
+	                //鏈�鍚庢坊鍔犲綋鍓嶅伐搴忕殑琛屼负宸ユ
+	                GenerateSteps(curStep);
+	
+	                //瀹屾垚绗竴涓伐搴忚妭鐐瑰伐姝�
+	                curStep.IsFinished = true;
+					CurStep = curStep;
+                } 
+                else if (!IsFinishNodeSteps)
+                {
+                    var curStep = Steps.Where(q => q.Type == IWorkStep.Types.Node && !q.IsFinished).OrderBy(q => q.Sequence).First();
 
-                //鏉$爜杩囩珯
-                var wipSN = Biz.Db.Queryable<MES_WIP_DATA>().First(q => q.SN == input.SN && q.BATCH_NO == CurBatch.Batch.BATCH_NO) ?? new MES_WIP_DATA()
-                {
-                    SN = input.SN,
-                    STATUS = MES_WIP_DATA.STATUSs.Init.GetValue(),
-                    ITEM_CODE = CurBatch.WO.ITEM_CODE,
-                    WORK_ORDER = CurBatch.Batch.ORDER_NO,
-                    BATCH_NO = CurBatch.Batch.BATCH_NO,
-                    HOLD_FLAG = "N",
-                    REWORK_FLAG = CurBatch.WO.ORDER_TYPE == BIZ_MES_WO.ORDER_TYPEs.Rework.GetValue() ? "Y" : "N",
-                    FINISHED_FLAG = "N",
-                    INV_FLAG = "N",
-                    DFT_FLAG = "N",
-                    DFT_COUNT = 0,
-                };
-                wipSN.AUTH_PROD = CurLine.LINE_CODE;
-                wipSN.STATUS = wipSN.STATUS > 0 ? MES_WIP_DATA.STATUSs.OK.GetValue() : wipSN.STATUS;
-                wipSN.ROT_CODE = CurBatch.WO.ROUTE_CODE;
-                wipSN.NODE_ID = curNode.ID;
-                wipSN.NODE_NAME = curNode.NODE_NAME;
-                wipSN.FTY_CODE = CurFactory.FTY_CODE;
-                wipSN.WS_CODE = CurWorkshop.WS_CODE;
-                wipSN.LINE_CODE = CurLine.LINE_CODE;
-                wipSN.POST_CODE = CurPosition.POST_CODE;
-                wipSN.OPER_CODE = curNode.OPER_CODE;
-                wipSN.SEGMENT = curNode.SEGMENT;
-                wipSN.OPERATION_TIME = DateTime.Now;
-                wipSN.SFTS_CODE = CurLine.SFTS_CODE;
-                //wipSN.SFT_CODE = CurBatch.WO.ROUTE_CODE;
-                //wipSN.PRD_CODE = CurBatch.WO.ROUTE_CODE;
-                CurBatch.StartWorking(UserCode);
-
-                //濡傛灉鏄姇鍏ョ珯
-                if (curNode.IS_INPUT == "Y")
-                {
-                    woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Inputed.GetValue();
-                    wipSN.STATUS = MES_WIP_DATA.STATUSs.Input.GetValue();
-                    wipSN.INLINE_DATE = DateTime.Now;
-                }
-                //濡傛灉鏄骇鍑虹珯
-                if (curNode.IS_OUTPUT == "Y")
-                {
-                    woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Finished.GetValue();
-                    wipSN.STATUS = MES_WIP_DATA.STATUSs.Finished.GetValue();
-                    wipSN.OUTLINE_DATE = DateTime.Now;
-                }
-                //濡傛灉鏈夋彁浜や笉鑹�
-                if (!input.DFT_CODE.IsNullOrEmpty())
-                {
-                    wipSN.STATUS = MES_WIP_DATA.STATUSs.NG.GetValue();
-                    wipSN.DFT_FLAG = "Y";
-                    wipSN.DFT_COUNT++;
-                    wipSN.DFT_CODE = input.DFT_CODE;
+                    //瀹屾垚褰撳墠宸ュ簭鑺傜偣宸ユ
+                    curStep.IsFinished = true;
+                    CurStep = curStep;
                 }
 
-                CurWipSNHis = new MES_WIP_HIS(CurWipSN = wipSN, $"宸ュ崟[{wipSN.WORK_ORDER}]鐨勬潯鐮乕{wipSN.SN}]鍦ㄥ矖浣峓{wipSN.POST_CODE}]宸ュ簭[{wipSN.NODE_NAME}]杩囩珯鎴愬姛锛岀姸鎬乕{wipSN.STATUS.GetEnumDesc<MES_WIP_DATA.STATUSs>()}]");
-
-                //鍒濆鍖栧伐姝ュ垪琛�
-                Steps.Clear();
-                var curStep = new Biz.WorkStep(curNode.ID, IWorkStep.Types.Node) {
-                    Sequence = Steps.Count + 1,
-                    Node = curNode,
-                    DBSubmitAction = () =>
-                    {
-                        var db = GetCommitDB();
-                        db.Storageable(woSN, UserCode).ExecuteCommand();
-                        db.Storageable(wipSN, UserCode).ExecuteCommand();
-                        db.Storageable(CurWipSNHis, UserCode).ExecuteCommand();
-                    }
-                };
-                Steps.Add(curStep);
-
-                //濡傛灉褰撳墠宸ュ簭鑺傜偣鏈夎涓哄垯娣诲姞鍒板伐姝ュ垪琛�
-                var acts = CurBatch.NodeActs.Where(q => q.NODE_ID == curNode.ID).ToList();
-                foreach (var act in acts)
-                {
-                    Steps.Add(new Biz.WorkStep(act.ID, IWorkStep.Types.Action)
-                    {
-                        Sequence = Steps.Count + 1,
-                        Node = curNode,
-                        NodeAct = act,
-                        Setting = CurBatch.ActionSets.FirstOrDefault(q => q.ACT_ID == act.ID),
-                    });
-                }
-
-                //瀹屾垚褰撳墠宸ュ簭鑺傜偣
-                curStep.IsFinished = true;
                 //鏈畬鎴愭墍鏈夊伐姝�
                 if (!IsFinishAllSteps)
                 {
-                    var next = Steps.Where(q => !q.IsFinished).OrderBy(q => q.Sequence).First();
-                    var result = next.Begin(this);
-                    result.Data.StepID = next.ID;
-                    result.Data.IsFinished = IsFinishAllSteps;
-                    result.Data.CurStep = CurStep;
-                    return result.ToApiAction();
+                    var result = new ApiAction<SubmitOutput>();
+                    //鏈畬鎴愭墍鏈夊伐搴忚妭鐐瑰伐姝�
+                    if (!IsFinishNodeSteps)
+                    {
+                        var next = Steps.Where(q => q.Type == IWorkStep.Types.Node && !q.IsFinished).OrderBy(q => q.Sequence).First();
+                        //璁剧疆鍚庣画鍙墽琛岀殑宸ユ鍒楄〃
+                        NextSteps.Clear();
+                        NextSteps.Add(next);
+                        //鏍规嵁鍚庣画宸ユ杩斿洖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.NextStepID = next.ID;
+                        
+                        //鏍规嵁宸ュ簭鑺傜偣宸ユ鐨勫簭鍙疯繑鍥炵浉搴旂殑鎿嶄綔鎻愮ず
+                        switch (next.Sequence)
+                        {
+                            case 2:
+                                //action.LocaleMsg = new($"璇锋墽琛岀浜屾");
+                                result.LocaleMsg = new("MES.Transaction.PackingNode.绗簩姝ユ搷浣滄彁绀�");
+                                break;
+                            default:
+                                break;
+                        }
+                    }
+                    //宸插畬鎴愭墍鏈夊伐搴忚妭鐐瑰伐姝ワ紝寮�濮嬫墽琛岃涓哄伐姝�
+                    else
+                    {
+                        result = BeginNextActionStep(input);
+                    }
+                    return result;
                 }
                 //宸插畬鎴愭墍鏈夊伐姝�
                 else
                 {
+                    action.Data.IsFinished = IsFinishAllSteps;
+                    action.Data.CurWO = CurBatch.WO.ORDER_NO;
+                    action.Data.CurBatch = CurBatch.Batch.BATCH_NO;
+                    action.Data.CurNode = CurStep.Node.NODE_NAME;
+                    action.Data.NextStepID = "";
                     action = DoIfFinishAllSteps(action);
                 }
             }
@@ -265,7 +330,7 @@
         /// </summary>
         /// <param name="action"></param>
         /// <returns></returns>
-        public ApiAction DoIfFinishAllSteps(ApiAction action)
+        public ApiAction<SubmitOutput> DoIfFinishAllSteps(ApiAction<SubmitOutput> action)
         {
             //淇濆瓨鏁版嵁搴�
             var dbTran = GetCommitDB().UseTran(() =>
@@ -283,6 +348,7 @@
             //淇濆瓨鎴愬姛锛岃繑鍥炶繃绔欐秷鎭�
             //action.LocaleMsg = new($"宸ュ崟[{CurWipSN.WORK_ORDER}]鐨勬潯鐮乕{CurWipSN.SN}]鍦ㄥ矖浣峓{CurWipSN.POST_CODE}]宸ュ簭[{CurWipSN.NODE_NAME}]杩囩珯鎴愬姛锛岀姸鎬乕{CurWipSN.STATUS.GetEnumDesc<MES_WIP_DATA.STATUSs>()}]", CurWipSN.WORK_ORDER, CurWipSN.SN, CurWipSN.POST_CODE, CurWipSN.NODE_NAME, CurWipSN.STATUS.GetEnumDesc<MES_WIP_DATA.STATUSs>());
             action.LocaleMsg = new("MES.Transaction.PackingNode.ScanSn.PassSuccess", CurWipSN.WORK_ORDER, CurWipSN.SN, CurWipSN.POST_CODE, CurWipSN.NODE_NAME, CurWipSN.STATUS.GetEnumDesc<MES_WIP_DATA.STATUSs>());
+   
             return action;
         }
         #endregion Functions
diff --git a/Tiger.Business.MES/Transaction/Position.cs b/Tiger.Business.MES/Transaction/Position.cs
index 4d046eb..fd494ab 100644
--- a/Tiger.Business.MES/Transaction/Position.cs
+++ b/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
 {
@@ -56,8 +54,11 @@
         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
 
@@ -128,6 +129,157 @@
             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)
diff --git a/Tiger.Business.MES/Transaction/TestNode.cs b/Tiger.Business.MES/Transaction/TestNode.cs
index e704a65..3e2ad80 100644
--- a/Tiger.Business.MES/Transaction/TestNode.cs
+++ b/Tiger.Business.MES/Transaction/TestNode.cs
@@ -35,18 +35,18 @@
         /// </summary>
         /// <param name="input"></param>
         /// <returns></returns>
-        public async Task<ApiAction> Submit(SubmitInput input)
+        public async Task<ApiAction<SubmitOutput>> Submit(SubmitInput input)
         {
-            var action = new ApiAction();
+            var action = new ApiAction<SubmitOutput>();
             try
             {
-                //宸ユ鍒楄〃涓虹┖鏃讹紝璁や负闇�瑕佸厛鎵弿杩囩珯鏉$爜
-                if (Steps.IsNullOrEmpty())
+                //宸ユ鍒楄〃涓虹┖鎴栬�呭伐搴忚妭鐐瑰伐姝ユ湁鏈畬鎴愭椂锛屼紭鍏堝畬鎴愬伐搴忚妭鐐瑰伐姝�
+                if (Steps.IsNullOrEmpty() || !IsFinishNodeSteps)
                 {
                     //鍏堝垽鏂綋鍓嶅伐鍗曚笉涓虹┖涓斿綋鍓嶅矖浣嶅湪褰撳墠宸ュ崟鏄笉鏄绔欙紝濡傛灉鏄垯涓嶅厑璁稿彉鏇村綋鍓嶅伐鍗曪紝灏濊瘯鎶婃潯鐮佺粦瀹氬埌褰撳墠宸ュ崟
                     if (!CurBatch.IsNullOrEmpty() && CurBatch.IsFirstNode(PostCode))
                     {
-                        action = ScanSn(action, input);
+                        action = NodeSubmit(action, input);
                         return action;
                     }
                     //褰撳墠宀椾綅鍦ㄥ綋鍓嶅伐鍗曚笉鏄绔欙紝鍒欐煡鎵炬潯鐮佸凡缁戝畾鐨勫伐鍗曞綋浣滃綋鍓嶅伐鍗�
@@ -64,12 +64,13 @@
                                 var result = await SelectOrder(new() { AuthOption = input.AuthOption, OrderNo = wosn.Batch.ORDER_NO });
                                 if (!result.IsSuccessed)
                                 {
-                                    action = result;
+                                    action.IsSuccessed = result.IsSuccessed;
+                                    action.LocaleMsg = result.LocaleMsg;
                                     return action;
                                 }
                             }
                             //鏉$爜杩囩珯
-                            action = ScanSn(action, input);
+                            action = NodeSubmit(action, input);
                             return action;
                         }
                         //鏌ユ壘涓嶅埌鏉$爜宸茬粦瀹氱殑宸ュ崟
@@ -95,20 +96,47 @@
                     }
                 }
                 //瀹屾垚绗竴姝ワ紝鍚庡紑濮嬫墽琛屽綋鍓嶅伐搴忕殑琛屼负鍒楄〃
-                else if (Steps.First().IsFinished && !IsFinishAllSteps)
+                //瀹屾垚宸ュ簭鑺傜偣宸ユ鍚庯紝鍚庡紑濮嬫墽琛屽綋鍓嶅伐搴忕殑琛屼负宸ユ
+                else if (IsFinishNodeSteps && !IsFinishAllSteps)
                 {
-                    var curStep = Steps.Where(q => q.ID == input.StepID).FirstOrDefault();
-                    if (!curStep.IsNullOrEmpty())
+                    var submitStep = Steps.Where(q => q.ID == input.CurStepID && !q.IsFinished).FirstOrDefault();
+                    if (submitStep.IsNullOrEmpty())
                     {
-                        var result = curStep.Submit(input);
-                        result.Data.StepID = curStep.ID;
-                        result.Data.IsFinished = IsFinishAllSteps;
-                        result.Data.CurStep = CurStep;
+                        action = BeginNextActionStep(input);
+                        return action;
+                    }
+                    else
+                    {
+                        var result = submitStep.Submit(input);
+                        //濡傛灉褰撳墠宸ユ宸插畬鎴愶紝寮�濮嬫墽琛屼笅涓�宸ユ
+                        if (result.IsSuccessed && submitStep.IsFinished)
+                        {
+                            result = BeginNextActionStep(input);
+                        }
+                        //濡傛灉褰撳墠宸ユ鏈畬鎴�
+                        else
+                        {
+                            //琛屼负鎵ц鍑洪敊锛屽伐姝ヨ閲嶇疆
+                            if (Steps.IsNullOrEmpty())
+                            {
+                                result.LocaleMsg = new(Biz.T(result.LocaleMsg, input.Locale) + Biz.T(Biz.L("MES.Transaction.Position.RescanSN"), input.Locale));
+                            }
+                            else
+                            {
+                                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;
+                            }
+                        }
+                        //濡傛灉鎵�鏈夊伐姝ラ兘瀹屾垚
                         if (IsFinishAllSteps)
                         {
-                            return DoIfFinishAllSteps(result.ToApiAction());
+                            return DoIfFinishAllSteps(result);
                         }
-                        return result.ToApiAction();
+                        return result;
                     }
                 }
                 //娌℃湁鍙墽琛岀殑宸ユ
@@ -125,130 +153,168 @@
         }
 
         /// <summary>
-        /// 鎵弿杩囩珯鏉$爜
+        /// 宸ュ簭鑺傜偣宸ユ鎻愪氦鏁版嵁
         /// </summary>
         /// <param name="action"></param>
         /// <param name="input"></param>
         /// <returns></returns>
-        public ApiAction ScanSn(ApiAction action, SubmitInput input)
+        public ApiAction<SubmitOutput> NodeSubmit(ApiAction<SubmitOutput> action, SubmitInput input)
         {
             try
             {
-                //缁戝畾鏉$爜鍒板伐鍗�
-                if (!CurBatch.WoSNs.Any(q => q.SN == input.SN))
+                //褰撳伐姝ュ垪琛ㄤ负绌猴紝鍒欐墽琛屽綋鍓嶅伐搴忕殑蹇呰閫昏緫褰撲綔绗竴涓伐搴忚妭鐐癸紝瀹屾垚鍚庢寜闇�姹傚垱寤哄悗缁殑宸ユ鍒楄〃
+                if (Steps.IsNullOrEmpty())
                 {
-                    CurBatch.WoSNs.Add(new()
+                    //缁戝畾鏉$爜鍒板伐鍗�
+                    if (!CurBatch.WoSNs.Any(q => q.SN == input.SN))
                     {
-                        WORK_ORDER = CurBatch.Batch.ORDER_NO,
-                        SN = input.SN,
-                        STATUS = BIZ_MES_WO_SN.STATUSs.NotInput.GetValue(),
-                        BATCH_NO = CurBatch.Batch.BATCH_NO,
-                    });
-                }
-                var woSN = CurBatch.WoSNs.FirstOrDefault(q => q.SN == input.SN);
-                var curNode = CurBatch.GetNode(PostCode);
-
-                //鏉$爜杩囩珯
-                var wipSN = Biz.Db.Queryable<MES_WIP_DATA>().First(q => q.SN == input.SN && q.BATCH_NO == CurBatch.Batch.BATCH_NO) ?? new MES_WIP_DATA()
-                {
-                    SN = input.SN,
-                    STATUS = MES_WIP_DATA.STATUSs.Init.GetValue(),
-                    ITEM_CODE = CurBatch.WO.ITEM_CODE,
-                    WORK_ORDER = CurBatch.Batch.ORDER_NO,
-                    BATCH_NO = CurBatch.Batch.BATCH_NO,
-                    HOLD_FLAG = "N",
-                    REWORK_FLAG = CurBatch.WO.ORDER_TYPE == BIZ_MES_WO.ORDER_TYPEs.Rework.GetValue() ? "Y" : "N",
-                    FINISHED_FLAG = "N",
-                    INV_FLAG = "N",
-                    DFT_FLAG = "N",
-                    DFT_COUNT = 0,
-                };
-                wipSN.AUTH_PROD = CurLine.LINE_CODE;
-                wipSN.STATUS = wipSN.STATUS > 0 ? MES_WIP_DATA.STATUSs.OK.GetValue() : wipSN.STATUS;
-                wipSN.ROT_CODE = CurBatch.WO.ROUTE_CODE;
-                wipSN.NODE_ID = curNode.ID;
-                wipSN.NODE_NAME = curNode.NODE_NAME;
-                wipSN.FTY_CODE = CurFactory.FTY_CODE;
-                wipSN.WS_CODE = CurWorkshop.WS_CODE;
-                wipSN.LINE_CODE = CurLine.LINE_CODE;
-                wipSN.POST_CODE = CurPosition.POST_CODE;
-                wipSN.OPER_CODE = curNode.OPER_CODE;
-                wipSN.SEGMENT = curNode.SEGMENT;
-                wipSN.OPERATION_TIME = DateTime.Now;
-                wipSN.SFTS_CODE = CurLine.SFTS_CODE;
-                //wipSN.SFT_CODE = CurBatch.WO.ROUTE_CODE;
-                //wipSN.PRD_CODE = CurBatch.WO.ROUTE_CODE;
-                CurBatch.StartWorking(UserCode);
-
-                //濡傛灉鏄姇鍏ョ珯
-                if (curNode.IS_INPUT == "Y")
-                {
-                    woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Inputed.GetValue();
-                    wipSN.STATUS = MES_WIP_DATA.STATUSs.Input.GetValue();
-                    wipSN.INLINE_DATE = DateTime.Now;
-                }
-                //濡傛灉鏄骇鍑虹珯
-                if (curNode.IS_OUTPUT == "Y")
-                {
-                    woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Finished.GetValue();
-                    wipSN.STATUS = MES_WIP_DATA.STATUSs.Finished.GetValue();
-                    wipSN.OUTLINE_DATE = DateTime.Now;
-                }
-                //濡傛灉鏈夋彁浜や笉鑹�
-                if (!input.DFT_CODE.IsNullOrEmpty())
-                {
-                    wipSN.STATUS = MES_WIP_DATA.STATUSs.NG.GetValue();
-                    wipSN.DFT_FLAG = "Y";
-                    wipSN.DFT_COUNT++;
-                    wipSN.DFT_CODE = input.DFT_CODE;
-                }
-
-                CurWipSNHis = new MES_WIP_HIS(CurWipSN = wipSN, $"宸ュ崟[{wipSN.WORK_ORDER}]鏉$爜[{wipSN.SN}]鍦ㄥ矖浣峓{wipSN.POST_CODE}]杩囩珯宸ュ簭[{wipSN.NODE_NAME}]鎴愬姛");
-
-                //鍒濆鍖栧伐姝ュ垪琛�
-                Steps.Clear();
-                var curStep = new Biz.WorkStep(curNode.ID, IWorkStep.Types.Node)
-                {
-                    Sequence = Steps.Count + 1,
-                    Node = curNode,
-                    DBSubmitAction = () =>
-                    {
-                        var db = GetCommitDB();
-                        db.Storageable(woSN, UserCode).ExecuteCommand();
-                        db.Storageable(wipSN, UserCode).ExecuteCommand();
-                        db.Storageable(CurWipSNHis, UserCode).ExecuteCommand();
+                        CurBatch.WoSNs.Add(new()
+                        {
+                            WORK_ORDER = CurBatch.Batch.ORDER_NO,
+                            SN = input.SN,
+                            STATUS = BIZ_MES_WO_SN.STATUSs.NotInput.GetValue(),
+                            BATCH_NO = CurBatch.Batch.BATCH_NO,
+                        });
                     }
-                };
-                Steps.Add(curStep);
+                    var woSN = CurBatch.WoSNs.FirstOrDefault(q => q.SN == input.SN);
+                    var curNode = CurBatch.GetNode(PostCode);
 
-                //濡傛灉褰撳墠宸ュ簭鑺傜偣鏈夎涓哄垯娣诲姞鍒板伐姝ュ垪琛�
-                var acts = CurBatch.NodeActs.Where(q => q.NODE_ID == curNode.ID).ToList();
-                foreach (var act in acts)
-                {
-                    Steps.Add(new Biz.WorkStep(act.ID, IWorkStep.Types.Action)
+                    //鏉$爜杩囩珯
+                    var wipSN = Biz.Db.Queryable<MES_WIP_DATA>().First(q => q.SN == input.SN && q.BATCH_NO == CurBatch.Batch.BATCH_NO) ?? new MES_WIP_DATA()
                     {
+                        SN = input.SN,
+                        STATUS = MES_WIP_DATA.STATUSs.Init.GetValue(),
+                        ITEM_CODE = CurBatch.WO.ITEM_CODE,
+                        WORK_ORDER = CurBatch.Batch.ORDER_NO,
+                        BATCH_NO = CurBatch.Batch.BATCH_NO,
+                        HOLD_FLAG = "N",
+                        REWORK_FLAG = CurBatch.WO.ORDER_TYPE == BIZ_MES_WO.ORDER_TYPEs.Rework.GetValue() ? "Y" : "N",
+                        FINISHED_FLAG = "N",
+                        INV_FLAG = "N",
+                        DFT_FLAG = "N",
+                        DFT_COUNT = 0,
+                    };
+                    wipSN.AUTH_PROD = CurLine.LINE_CODE;
+                    wipSN.STATUS = wipSN.STATUS > 0 ? MES_WIP_DATA.STATUSs.OK.GetValue() : wipSN.STATUS;
+                    wipSN.ROT_CODE = CurBatch.WO.ROUTE_CODE;
+                    wipSN.NODE_ID = curNode.ID;
+                    wipSN.NODE_NAME = curNode.NODE_NAME;
+                    wipSN.FTY_CODE = CurFactory.FTY_CODE;
+                    wipSN.WS_CODE = CurWorkshop.WS_CODE;
+                    wipSN.LINE_CODE = CurLine.LINE_CODE;
+                    wipSN.POST_CODE = CurPosition.POST_CODE;
+                    wipSN.OPER_CODE = curNode.OPER_CODE;
+                    wipSN.SEGMENT = curNode.SEGMENT;
+                    wipSN.OPERATION_TIME = DateTime.Now;
+                    wipSN.SFTS_CODE = CurLine.SFTS_CODE;
+                    //wipSN.SFT_CODE = CurBatch.WO.ROUTE_CODE;
+                    //wipSN.PRD_CODE = CurBatch.WO.ROUTE_CODE;
+                    CurBatch.StartWorking(UserCode);
+
+                    //濡傛灉鏄姇鍏ョ珯
+                    if (curNode.IS_INPUT == "Y")
+                    {
+                        woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Inputed.GetValue();
+                        wipSN.STATUS = MES_WIP_DATA.STATUSs.Input.GetValue();
+                        wipSN.INLINE_DATE = DateTime.Now;
+                    }
+                    //濡傛灉鏄骇鍑虹珯
+                    if (curNode.IS_OUTPUT == "Y")
+                    {
+                        woSN.STATUS = BIZ_MES_WO_SN.STATUSs.Finished.GetValue();
+                        wipSN.STATUS = MES_WIP_DATA.STATUSs.Finished.GetValue();
+                        wipSN.OUTLINE_DATE = DateTime.Now;
+                    }
+                    //濡傛灉鏈夋彁浜や笉鑹�
+                    if (!input.DFT_CODE.IsNullOrEmpty())
+                    {
+                        wipSN.STATUS = MES_WIP_DATA.STATUSs.NG.GetValue();
+                        wipSN.DFT_FLAG = "Y";
+                        wipSN.DFT_COUNT++;
+                        wipSN.DFT_CODE = input.DFT_CODE;
+                    }
+
+                    CurWipSNHis = new MES_WIP_HIS(CurWipSN = wipSN, $"宸ュ崟[{wipSN.WORK_ORDER}]鏉$爜[{wipSN.SN}]鍦ㄥ矖浣峓{wipSN.POST_CODE}]杩囩珯宸ュ簭[{wipSN.NODE_NAME}]鎴愬姛");
+
+                    //鍒濆鍖栧伐姝ュ垪琛�
+                    Steps.Clear();
+                    var curStep = new Biz.WorkStep(IWorkStep.Types.Node, this)
+                    {
+                        NodeID = curNode.ID,
                         Sequence = Steps.Count + 1,
                         Node = curNode,
-                        NodeAct = act,
-                        Setting = CurBatch.ActionSets.FirstOrDefault(q => q.ACT_ID == act.ID),
-                    });
+                        DBSubmitAction = () =>
+                        {
+                            var db = GetCommitDB();
+                            db.Storageable(woSN, UserCode).ExecuteCommand();
+                            db.Storageable(wipSN, UserCode).ExecuteCommand();
+                            db.Storageable(CurWipSNHis, UserCode).ExecuteCommand();
+                        }
+                    };
+                    Steps.Add(curStep);
+
+                    //鏈夐渶瑕佸垯娣诲姞宸ュ簭鑺傜偣鐨勫叾浠栧伐姝�
+
+                    //鏈�鍚庢坊鍔犲綋鍓嶅伐搴忕殑琛屼负宸ユ
+                    GenerateSteps(curStep);
+
+                    //瀹屾垚绗竴涓伐搴忚妭鐐瑰伐姝�
+                    curStep.IsFinished = true;
+                    CurStep = curStep;
+                }
+                else if (!IsFinishNodeSteps)
+                {
+                    var curStep = Steps.Where(q => q.Type == IWorkStep.Types.Node && !q.IsFinished).OrderBy(q => q.Sequence).First();
+
+                    //瀹屾垚褰撳墠宸ュ簭鑺傜偣宸ユ
+                    curStep.IsFinished = true;
+                    CurStep = curStep;
                 }
 
-                //瀹屾垚褰撳墠宸ュ簭鑺傜偣
-                curStep.IsFinished = true;
                 //鏈畬鎴愭墍鏈夊伐姝�
                 if (!IsFinishAllSteps)
                 {
-                    var next = Steps.Where(q => !q.IsFinished).OrderBy(q => q.Sequence).First();
-                    var result = next.Begin(this);
-                    result.Data.StepID = next.ID;
-                    result.Data.IsFinished = IsFinishAllSteps;
-                    result.Data.CurStep = CurStep;
-                    return result.ToApiAction();
+                    var result = new ApiAction<SubmitOutput>();
+                    //鏈畬鎴愭墍鏈夊伐搴忚妭鐐瑰伐姝�
+                    if (!IsFinishNodeSteps)
+                    {
+                        var next = Steps.Where(q => q.Type == IWorkStep.Types.Node && !q.IsFinished).OrderBy(q => q.Sequence).First();
+                        //璁剧疆鍚庣画鍙墽琛岀殑宸ユ鍒楄〃
+                        NextSteps.Clear();
+                        NextSteps.Add(next);
+                        //鏍规嵁鍚庣画宸ユ杩斿洖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.NextStepID = next.ID;
+
+                        //鏍规嵁宸ュ簭鑺傜偣宸ユ鐨勫簭鍙疯繑鍥炵浉搴旂殑鎿嶄綔鎻愮ず
+                        switch (next.Sequence)
+                        {
+                            case 2:
+                                //action.LocaleMsg = new($"璇锋墽琛岀浜屾");
+                                result.LocaleMsg = new("MES.Transaction.TestNode.绗簩姝ユ搷浣滄彁绀�");
+                                break;
+                            default:
+                                break;
+                        }
+                    }
+                    //宸插畬鎴愭墍鏈夊伐搴忚妭鐐瑰伐姝ワ紝寮�濮嬫墽琛岃涓哄伐姝�
+                    else
+                    {
+                        result = BeginNextActionStep(input);
+                    }
+                    return result;
                 }
                 //宸插畬鎴愭墍鏈夊伐姝�
                 else
                 {
+                    action.Data.IsFinished = IsFinishAllSteps;
+                    action.Data.CurWO = CurBatch.WO.ORDER_NO;
+                    action.Data.CurBatch = CurBatch.Batch.BATCH_NO;
+                    action.Data.CurNode = CurStep.Node.NODE_NAME;
+                    action.Data.NextStepID = "";
                     action = DoIfFinishAllSteps(action);
                 }
             }
@@ -265,7 +331,7 @@
         /// </summary>
         /// <param name="action"></param>
         /// <returns></returns>
-        public ApiAction DoIfFinishAllSteps(ApiAction action)
+        public ApiAction<SubmitOutput> DoIfFinishAllSteps(ApiAction<SubmitOutput> action)
         {
             //淇濆瓨鏁版嵁搴�
             var dbTran = GetCommitDB().UseTran(() =>
diff --git a/Tiger.Business.MES/WorkAction/IPQC.cs b/Tiger.Business.MES/WorkAction/IPQC.cs
index 22cb3cb..3989998 100644
--- a/Tiger.Business.MES/WorkAction/IPQC.cs
+++ b/Tiger.Business.MES/WorkAction/IPQC.cs
@@ -23,20 +23,42 @@
 
         #region Functions
         /// <summary>
-        /// 寮�濮嬫墽琛屽伐搴忚涓�
+        /// 鍒濆鍖栧伐搴忚涓�
         /// </summary>
         /// <returns></returns>
-        public ApiAction<SubmitOutput> Begin(IWorkStep curStep, IPosition position, MES_WO_NODE_ACT nodeAct, MES_WO_ACTION setting)
+        public void Init(IWorkStep curStep, IPosition position, MES_WO_NODE_ACT nodeAct, MES_WO_ACTION setting)
         {
             CurStep = curStep;
             CurPosition = position;
             NodeAct = nodeAct;
             Setting = setting;
+        }
+
+        /// <summary>
+        /// 鑾峰彇琛屼负寮�濮嬬殑鎻愮ず淇℃伅
+        /// </summary>
+        /// <returns></returns>
+        public Locale GetBeginMsg()
+        {
+            //var msg = new Locale("MES.WorkAction.IPQC.BeginMsg");
+            var msg = new Locale($"璇锋彁浜ゆ祴璇曠粨鏋�");
+            return msg;
+        }
+
+        /// <summary>
+        /// 灏濊瘯寮�濮嬫墽琛屽伐搴忚涓�
+        /// </summary>
+        /// <returns></returns>
+        public ApiAction<SubmitOutput> TryBegin(SubmitInput input)
+        {
             var action = new ApiAction<SubmitOutput>();
 
 
             //action.LocaleMsg = new($"璇锋寜娴嬭瘯椤规彁浜ゆ祴璇曟暟鎹�");
             action.LocaleMsg = new("MES.WorkAction.IPQC.PleaseTest");
+
+            //濡傛灉鏍规嵁杈撳叆鍙互寮�濮嬫墽琛屽綋鍓嶈涓哄垯鏍囪涓烘垚鍔燂紝鍚﹀垯澶辫触
+            action.IsSuccessed = false;
             return action;
         }
         /// <summary>
@@ -46,6 +68,31 @@
         public ApiAction<SubmitOutput> Submit(SubmitInput input)
         {
             var action = new ApiAction<SubmitOutput>();
+
+            //鎻愪氦鏁版嵁鎵ц鎴愬姛
+            if (true)
+            {
+                action.IsSuccessed = true;
+                action.LocaleMsg = new($"鎵ц鎴愬姛");
+                //action.LocaleMsg = new("MES.WorkAction.IPQC.Success");
+                //琛屼负鎵ц瀹屾垚
+                if (false)
+                {
+                	action = End();
+                }
+            }
+            //鎻愪氦鏁版嵁鎵ц澶辫触
+            else
+            {
+                action.IsSuccessed = false;
+                //action.LocaleMsg = new($"鎵ц澶辫触");
+                action.LocaleMsg = new("MES.WorkAction.IPQC.Fail");
+                //濡傛灉琛屼负璁剧疆涓哄嚭閿欓渶瑕侀噸缃伐搴忔搷浣�
+                if (NodeAct.NEED_RESET == "Y")
+                {
+                    CurPosition.ResetSteps();
+                }
+            }
 
             return action;
         }
@@ -57,18 +104,55 @@
         {
             var action = new ApiAction<SubmitOutput>();
 
+            //璁板綍琛屼负鎿嶄綔璁板綍
+            var wipAct = new MES_WIP_ACT()
+            {
+                HIS_ID = CurPosition.CurWipSNHis.ID,
+                SN = CurPosition.CurWipSN.SN,
+                STATUS = CurPosition.CurWipSN.STATUS,
+                ITEM_CODE = CurPosition.CurWipSN.ITEM_CODE,
+                WORK_ORDER = CurPosition.CurWipSN.WORK_ORDER,
+                BATCH_NO = CurPosition.CurWipSN.BATCH_NO,
+                ROT_CODE = CurPosition.CurWipSN.ROT_CODE,
+                NODE_ID = CurPosition.CurWipSN.NODE_ID,
+                NODE_NAME = CurPosition.CurWipSN.NODE_NAME,
+                ACT_ID = NodeAct.ID,
+                ACT_NAME = NodeAct.ACT_NAME,
+                FTY_CODE = CurPosition.CurWipSN.FTY_CODE,
+                WS_CODE = CurPosition.CurWipSN.WS_CODE,
+                LINE_CODE = CurPosition.CurWipSN.LINE_CODE,
+                POST_CODE = CurPosition.CurWipSN.POST_CODE,
+                OPER_CODE = CurPosition.CurWipSN.OPER_CODE,
+                SEGMENT = CurPosition.CurWipSN.SEGMENT,
+                TRAY_SN = CurPosition.CurWipSN.TRAY_SN,
+                OPERATION_TIME = DateTime.Now,
+                SFTS_CODE = CurPosition.CurWipSN.SFTS_CODE,
+                SFT_CODE = CurPosition.CurWipSN.SFT_CODE,
+                PRD_CODE = CurPosition.CurWipSN.PRD_CODE,
+                ACT_TYPE = NodeAct.ACT_TYPE,
+                ACT_SN = CurPosition.CurWipSN.SN,
+                ACT_VALUE_1 = "",
+                ACT_VALUE_2 = "",
+                ACT_VALUE_3 = "",
+                ACT_VALUE_4 = "",
+                ACT_VALUE_5 = "",
+                ACT_RESULT = "Y",
+                TRACE_INFO = $"鎵ц鎴愬姛",
+            };
+
+            //淇濆瓨鏁版嵁
+            CurStep.DBSubmitAction = () =>
+            {
+                var db = CurPosition.GetCommitDB();
+                db.Storageable(wipAct, CurPosition.UserCode).ExecuteCommand();
+            };
+
+            IsFinished = true;
+            action.LocaleMsg = new($"琛屼负缁撴潫");
+            //action.LocaleMsg = new("MES.WorkAction.IPQC.Finish");
             return action;
         }
-        /// <summary>
-        /// 鑾峰彇琛屼负鎻愮ず淇℃伅
-        /// </summary>
-        /// <returns></returns>
-        public ApiAction GetPrompt()
-        {
-            var action = new ApiAction();
-            action.LocaleMsg = new($"寮�濮嬫墦鍗版潯鐮�");
-            return action;
-        }
+
 
         #endregion Functions
     }
diff --git a/Tiger.Business.MES/WorkAction/PrintLabel.cs b/Tiger.Business.MES/WorkAction/PrintLabel.cs
index 95e4ed6..bef9143 100644
--- a/Tiger.Business.MES/WorkAction/PrintLabel.cs
+++ b/Tiger.Business.MES/WorkAction/PrintLabel.cs
@@ -26,19 +26,39 @@
 
         #region Functions
         /// <summary>
-        /// 寮�濮嬫墽琛屽伐搴忚涓�
+        /// 鍒濆鍖栧伐搴忚涓�
         /// </summary>
         /// <returns></returns>
-        public ApiAction<SubmitOutput> Begin(IWorkStep curStep, IPosition position, MES_WO_NODE_ACT nodeAct, MES_WO_ACTION setting)
+        public void Init(IWorkStep curStep, IPosition position, MES_WO_NODE_ACT nodeAct, MES_WO_ACTION setting)
         {
             CurStep = curStep;
             CurPosition = position;
             NodeAct = nodeAct;
             Setting = setting;
-            var action = new ApiAction<SubmitOutput>();
 
             Label = Biz.Db.Queryable<BAS_LABEL_TEMP>().Where(q => q.LABEL_CODE == setting.LABEL_CODE).IncludesAllFirstLayer().First();
             LabelPV = Biz.Db.Queryable<BAS_LABEL_PV>().ToList();
+        }
+
+        /// <summary>
+        /// 鑾峰彇琛屼负寮�濮嬬殑鎻愮ず淇℃伅
+        /// </summary>
+        /// <returns></returns>
+        public Locale GetBeginMsg()
+        {
+            var msg = new Locale("MES.WorkAction.PrintLabel.BeginMsg", CurPosition.CurWipSN.SN, Label.LABEL_CODE, Label.LABEL_NAME);
+            //var msg = new Locale($"寮�濮嬫墦鍗版潯鐮乕{CurPosition.CurWipSN.SN}]鐨勬爣绛綶{Label.LABEL_CODE}: {Label.LABEL_NAME}]");
+            return msg;
+        }
+
+        /// <summary>
+        /// 灏濊瘯寮�濮嬫墽琛屽伐搴忚涓�
+        /// </summary>
+        /// <returns></returns>
+        public ApiAction<SubmitOutput> TryBegin(SubmitInput input)
+        {
+            var action = new ApiAction<SubmitOutput>();
+            
             foreach (var item in Label.Variables)
             {
                 switch (item.VAR_TYPE.GetEnum<BAS_LABEL_VAR.VAR_TYPEs>())
@@ -58,10 +78,13 @@
                         break;
                 }
             }
-            action.Data.StepActCode = nodeAct.Definition.ACT_CODE;
             action.Data.Data = Label;
+
+            //濡傛灉鏍规嵁杈撳叆鍙互寮�濮嬫墽琛屽綋鍓嶈涓哄垯鏍囪涓烘垚鍔燂紝鍚﹀垯澶辫触
+            action.IsSuccessed = true;
             return action;
         }
+
         /// <summary>
         /// 宸ュ簭琛屼负鎻愪氦鏁版嵁
         /// </summary>
@@ -69,17 +92,22 @@
         public ApiAction<SubmitOutput> Submit(SubmitInput input)
         {
             var action = new ApiAction<SubmitOutput>();
+            //鎻愪氦鏁版嵁鎵ц鎴愬姛
             if (input.Data.ToBoolean())
             {
                 action = End();
             }
+            //鎻愪氦鏁版嵁鎵ц澶辫触
             else
             {
-                //閲嶇疆褰撳墠宸ュ簭
-                CurPosition.ResetSteps();
                 action.IsSuccessed = false;
-                //action.LocaleMsg = new($"鏍囩{Label.LABEL_NAME}[{Label.LABEL_CODE}]鎵撳嵃澶辫触锛岃閲嶆柊鎵弿浜у搧鏉$爜", Label.LABEL_NAME);
+                //action.LocaleMsg = new($"鏍囩{Label.LABEL_NAME}[{Label.LABEL_CODE}]鎵撳嵃澶辫触", Label.LABEL_NAME);
                 action.LocaleMsg = new("MES.WorkAction.PrintLabel.PrintFail", Label.LABEL_NAME, Label.LABEL_CODE);
+                //濡傛灉琛屼负璁剧疆涓哄嚭閿欓渶瑕侀噸缃伐搴忔搷浣�
+                if (NodeAct.NEED_RESET == "Y")
+                {
+                    CurPosition.ResetSteps();
+                }
             }
             return action;
         }
@@ -91,6 +119,7 @@
         {
             var action = new ApiAction<SubmitOutput>();
 
+            //璁板綍琛屼负鎿嶄綔璁板綍
             var wipAct = new MES_WIP_ACT()
             {
                 HIS_ID = CurPosition.CurWipSNHis.ID,
diff --git a/Tiger.Business/Language/Biz.Language.cs b/Tiger.Business/Language/Biz.Language.cs
index 1e17b51..154016c 100644
--- a/Tiger.Business/Language/Biz.Language.cs
+++ b/Tiger.Business/Language/Biz.Language.cs
@@ -17,6 +17,7 @@
 using System.Xml.Linq;
 using Tiger.IBusiness;
 using System.Data;
+using Tiger.Model.Entitys.MES.Position;
 
 namespace Tiger.Business
 {
@@ -30,6 +31,13 @@
         /// <returns></returns>
         public static string T(string key, params object?[] args) => new Locale(key, args).Default();
         /// <summary>
+        /// 澶氳瑷�缈昏瘧锛屾寜浼犲叆鐨勮瑷�缈昏瘧锛屼紶鍏ヨ瑷�涓虹┖鍒欐寜BizSettings璁剧疆鐨勯粯璁よ瑷�(DefaultLanguage)缈昏瘧
+        /// </summary>
+        /// <param name="locale"></param>
+        /// <param name="language"></param>
+        /// <returns></returns>
+        public static string T(Locale locale, string language) => language.IsNullOrEmpty() ? locale.Default() : locale[language];
+        /// <summary>
         /// 澶氳瑷�瀵硅薄(鏈炕璇�)
         /// </summary>
         /// <param name="key"></param>
diff --git a/Tiger.Business/MES/Biz.WorkStep.cs b/Tiger.Business/MES/Biz.WorkStep.cs
index de8c0f2..5ac5564 100644
--- a/Tiger.Business/MES/Biz.WorkStep.cs
+++ b/Tiger.Business/MES/Biz.WorkStep.cs
@@ -22,14 +22,15 @@
         /// </summary>
         public partial class WorkStep : IWorkStep
         {
-            public WorkStep(string id, IWorkStep.Types type)
+            public WorkStep(IWorkStep.Types type, IPosition position)
             {
-                ID = id;
                 Type = type;
+                CurPosition = position;
             }
 
             #region Propertys & Variables
             public string ID { get; set; } = Guid.NewGuid().ToString("N");
+            public string NodeID { get; set; } 
             public IWorkStep.Types Type { get; set; }
             public int Sequence { get; set; }
             public MES_WO_NODE Node { get; set; }
@@ -37,6 +38,7 @@
             public MES_WO_ACTION Setting { get; set; }
             public IPosition CurPosition { get; set; }
             public IWorkAction CurAction { get; set; }
+            public List<string> PrepNodeIDs { get; set; } = new();
             private bool _IsFinished = false;
             public bool IsFinished
             {
@@ -48,16 +50,32 @@
 
             #region Functions
             /// <summary>
-            /// 寮�濮嬫墽琛屽伐姝�
+            /// 鍒濆鍖栧伐姝�
             /// </summary>
-            /// <param name="position"></param>
             /// <returns></returns>
-            public ApiAction<SubmitOutput> Begin(IPosition position)
+            public void Init()
             {
-                CurPosition = position;
                 CurAction = DI.Resolve(NodeAct.Definition.SERVICE_TYPE) as IWorkAction;
                 //CurAction = DI.Resolve("Tiger.IBusiness.IPrintLabel,Tiger.IBusiness") as IWorkAction;
-                return CurAction.Begin(this, position, NodeAct, Setting);
+                CurAction.Init(this, CurPosition, NodeAct, Setting);
+            }
+
+            /// <summary>
+            /// 灏濊瘯寮�濮嬫墽琛屽伐姝�
+            /// </summary>
+            /// <returns></returns>
+            public ApiAction<SubmitOutput> TryBegin(SubmitInput input)
+            {
+                return CurAction.TryBegin(input);
+            }
+
+            /// <summary>
+            /// 鑾峰彇琛屼负寮�濮嬬殑鎻愮ず淇℃伅
+            /// </summary>
+            /// <returns></returns>
+            public Locale GetBeginMsg()
+            {
+                return CurAction.GetBeginMsg();
             }
 
             /// <summary>
diff --git a/Tiger.IBusiness/MES/IWorkAction.cs b/Tiger.IBusiness/MES/IWorkAction.cs
index 19a4772..965bedc 100644
--- a/Tiger.IBusiness/MES/IWorkAction.cs
+++ b/Tiger.IBusiness/MES/IWorkAction.cs
@@ -21,10 +21,20 @@
 
         #region Functions
         /// <summary>
-        /// 寮�濮嬫墽琛屽伐搴忚涓�
+        /// 鍒濆鍖栧伐搴忚涓�
         /// </summary>
         /// <returns></returns>
-        public ApiAction<SubmitOutput> Begin(IWorkStep curStep, IPosition position, MES_WO_NODE_ACT nodeAct, MES_WO_ACTION setting);
+        public void Init(IWorkStep curStep, IPosition position, MES_WO_NODE_ACT nodeAct, MES_WO_ACTION setting);
+        /// <summary>
+        /// 鑾峰彇琛屼负寮�濮嬬殑鎻愮ず淇℃伅
+        /// </summary>
+        /// <returns></returns>
+        public Locale GetBeginMsg();
+        /// <summary>
+        /// 灏濊瘯寮�濮嬫墽琛屽伐搴忚涓�
+        /// </summary>
+        /// <returns></returns>
+        public ApiAction<SubmitOutput> TryBegin(SubmitInput input);
         /// <summary>
         /// 宸ュ簭琛屼负鎻愪氦鏁版嵁
         /// </summary>
diff --git a/Tiger.IBusiness/MES/IWorkStep.cs b/Tiger.IBusiness/MES/IWorkStep.cs
index 148de53..f5441dc 100644
--- a/Tiger.IBusiness/MES/IWorkStep.cs
+++ b/Tiger.IBusiness/MES/IWorkStep.cs
@@ -21,6 +21,7 @@
         public MES_WO_ACTION Setting { get; set; }
         public IPosition CurPosition { get; set; }
         public IWorkAction CurAction { get; set; }
+        public List<string> PrepNodeIDs { get; set; }
         public bool IsFinished { get; set; }
         public Action DBSubmitAction { get; set; }
         #endregion Propertys & Variables
@@ -28,11 +29,15 @@
 
         #region Functions
         /// <summary>
-        /// 寮�濮嬫墽琛屽伐姝�
+        /// 灏濊瘯寮�濮嬫墽琛屽伐姝�
         /// </summary>
-        /// <param name="position"></param>
         /// <returns></returns>
-        public ApiAction<SubmitOutput> Begin(IPosition position);
+        public ApiAction<SubmitOutput> TryBegin(SubmitInput input);
+        /// <summary>
+        /// 鑾峰彇琛屼负寮�濮嬬殑鎻愮ず淇℃伅
+        /// </summary>
+        /// <returns></returns>
+        public Locale GetBeginMsg();
         /// <summary>
         /// 宸ユ鎻愪氦鏁版嵁
         /// </summary>
diff --git a/Tiger.IBusiness/MES/Transaction/ICollectNode.cs b/Tiger.IBusiness/MES/Transaction/ICollectNode.cs
index 0099442..90fa9e2 100644
--- a/Tiger.IBusiness/MES/Transaction/ICollectNode.cs
+++ b/Tiger.IBusiness/MES/Transaction/ICollectNode.cs
@@ -32,6 +32,6 @@
         /// </summary>
         /// <param name="input"></param>
         /// <returns></returns>
-        public Task<ApiAction> Submit(SubmitInput input);
+        public Task<ApiAction<SubmitOutput>> Submit(SubmitInput input);
     }
 }
diff --git a/Tiger.IBusiness/MES/Transaction/IPackingNode.cs b/Tiger.IBusiness/MES/Transaction/IPackingNode.cs
index e0289ae..ec6c475 100644
--- a/Tiger.IBusiness/MES/Transaction/IPackingNode.cs
+++ b/Tiger.IBusiness/MES/Transaction/IPackingNode.cs
@@ -32,6 +32,6 @@
         /// </summary>
         /// <param name="input"></param>
         /// <returns></returns>
-        public Task<ApiAction> Submit(SubmitInput input);
+        public Task<ApiAction<SubmitOutput>> Submit(SubmitInput input);
     }
 }
diff --git a/Tiger.IBusiness/MES/Transaction/IPosition.cs b/Tiger.IBusiness/MES/Transaction/IPosition.cs
index 2233a4e..49739a2 100644
--- a/Tiger.IBusiness/MES/Transaction/IPosition.cs
+++ b/Tiger.IBusiness/MES/Transaction/IPosition.cs
@@ -20,12 +20,23 @@
         public IWorkBatch WorkBatch { get; }
         public MES_WIP_DATA CurWipSN { get; set; }
         public MES_WIP_HIS CurWipSNHis { get; set; }
-        public IPosition Init(string id, string apiHost, string userCode, string postCode);
-        public void ResetSteps();
         #endregion Propertys & Variables
 
         #region Functions
         /// <summary>
+        /// 鍒濆鍖栧矖浣�
+        /// </summary>
+        /// <param name="id"></param>
+        /// <param name="apiHost"></param>
+        /// <param name="userCode"></param>
+        /// <param name="postCode"></param>
+        /// <returns></returns>
+        public IPosition Init(string id, string apiHost, string userCode, string postCode);
+        /// <summary>
+        /// 閲嶇疆宸ユ鍒楄〃
+        /// </summary>
+        public void ResetSteps();
+        /// <summary>
         /// 鑾峰彇鎻愪氦鏁版嵁鐨凞bClient瀵硅薄
         /// </summary>
         /// <returns></returns>
diff --git a/Tiger.IBusiness/MES/Transaction/ITestNode.cs b/Tiger.IBusiness/MES/Transaction/ITestNode.cs
index 6c91887..d840f78 100644
--- a/Tiger.IBusiness/MES/Transaction/ITestNode.cs
+++ b/Tiger.IBusiness/MES/Transaction/ITestNode.cs
@@ -32,7 +32,7 @@
         /// </summary>
         /// <param name="input"></param>
         /// <returns></returns>
-        public Task<ApiAction> Submit(SubmitInput input);
+        public Task<ApiAction<SubmitOutput>> Submit(SubmitInput input);
         /// <summary>
         /// 娴嬭瘯宸ュ簭锛氳幏鍙栧伐搴忎笉鑹唬鐮�
         /// </summary>
diff --git a/Tiger.Model.Net/Entitys/MES/MES_ROUTE_NODE_ACT.cs b/Tiger.Model.Net/Entitys/MES/MES_ROUTE_NODE_ACT.cs
index c43709b..e1dd128 100644
--- a/Tiger.Model.Net/Entitys/MES/MES_ROUTE_NODE_ACT.cs
+++ b/Tiger.Model.Net/Entitys/MES/MES_ROUTE_NODE_ACT.cs
@@ -6,42 +6,43 @@
 
 namespace Tiger.Model
 {
-	/// <summary>
-	/// 瀹炰綋锛氬伐搴忚涓�
-	/// </summary>
-	[Description("Primary:ID")]
-	[Serializable]
-	[SugarTable("MES_ROUTE_NODE_ACT")]
-	public class MES_ROUTE_NODE_ACT : DbEntityWithAuth
-	{
-		#region 鏋勯�犲嚱鏁�
-		/// <summary>
-		/// 瀹炰綋锛氬伐搴忚涓�
-		/// </summary>
-		public MES_ROUTE_NODE_ACT() {}
-		#endregion
+    /// <summary>
+    /// 瀹炰綋锛氬伐鑹鸿涓鸿妭鐐�
+    /// </summary>
+    [Description("Primary:ID")]
+    [DisplayName("宸ヨ壓琛屼负鑺傜偣")]
+    [Serializable]
+    [SugarTable("MES_ROUTE_NODE_ACT")]
+    public class MES_ROUTE_NODE_ACT : DbEntityWithAuth
+    {
+        #region 鏋勯�犲嚱鏁�
+        /// <summary>
+        /// 瀹炰綋锛氬伐鑹鸿涓鸿妭鐐�
+        /// </summary>
+        public MES_ROUTE_NODE_ACT() { }
+        #endregion
 
-		#region 鍏叡灞炴��
-		/// <summary>
-		/// 琛屼负鍚嶇О
-		/// </summary>
-		public string ACT_NAME { get; set; }
-		/// <summary>
-		/// 宸ヨ壓璺嚎ID
-		/// </summary>
-		public string ROT_ID { get; set; }
-		/// <summary>
-		/// 宸ヨ壓璺嚎鑺傜偣ID
-		/// </summary>
-		public string NODE_ID { get; set; }
-		/// <summary>
-		/// 宸ュ簭缂栫爜
-		/// </summary>
-		//public string OPER_CODE { get; set; }
-		/// <summary>
-		/// 琛屼负绫诲瀷(0Normal榛樿琛屼负|1Scan鎵爜楠岃瘉|2Assy缁勮涓婃枡|3Test浜у搧娴嬭瘯|4Audit浜у搧鎶芥|5Print鏍囩鎵撳嵃|6Package鍖呰瑙勫垯)
-		/// </summary>
-		public int ACT_TYPE { get; set; }
+        #region 鍏叡灞炴��
+        /// <summary>
+        /// 琛屼负鍚嶇О
+        /// </summary>
+        [DisplayName("琛屼负鍚嶇О")]
+        public string ACT_NAME { get; set; }
+        /// <summary>
+        /// 宸ヨ壓璺嚎ID
+        /// </summary>
+        [DisplayName("宸ヨ壓璺嚎ID")]
+        public string ROT_ID { get; set; }
+        /// <summary>
+        /// 宸ュ簭鑺傜偣ID
+        /// </summary>
+        [DisplayName("宸ュ簭鑺傜偣ID")]
+        public string NODE_ID { get; set; }
+        /// <summary>
+        /// 琛屼负绫诲瀷(0Normal榛樿琛屼负|1Scan鎵爜楠岃瘉|2Assy缁勮涓婃枡|3Test浜у搧娴嬭瘯|4Audit浜у搧鎶芥|5Print鏍囩鎵撳嵃|6Package鍖呰瑙勫垯)
+        /// </summary>
+        [DisplayName("琛屼负绫诲瀷(0Normal榛樿琛屼负|1Scan鎵爜楠岃瘉|2Assy缁勮涓婃枡|3Test浜у搧娴嬭瘯|4Audit浜у搧鎶芥|5Print鏍囩鎵撳嵃|6Package鍖呰瑙勫垯)")]
+        public int ACT_TYPE { get; set; }
         /// <summary>
         /// 琛屼负缂栫爜
         /// </summary>
@@ -50,26 +51,32 @@
         /// <summary>
         /// 缁樺浘灞炴�э細type
         /// </summary>
+        [DisplayName("缁樺浘灞炴�э細type")]
         public string GPH_TYPE { get; set; }
-		/// <summary>
-		/// 缁樺浘灞炴�э細x
-		/// </summary>
-		public double GPH_X { get; set; }
-		/// <summary>
-		/// 缁樺浘灞炴�э細y
-		/// </summary>
-		public double GPH_Y { get; set; }
-		/// <summary>
-		/// 缁樺浘灞炴�э細properties
-		/// </summary>
-		public string GPH_PROP { get; set; }
-		/// <summary>
-		/// 缁樺浘灞炴�э細text
-		/// </summary>
-		public string GPH_TEXT { get; set; }
+        /// <summary>
+        /// 缁樺浘灞炴�э細x
+        /// </summary>
+        [DisplayName("缁樺浘灞炴�э細x")]
+        public double GPH_X { get; set; }
+        /// <summary>
+        /// 缁樺浘灞炴�э細y
+        /// </summary>
+        [DisplayName("缁樺浘灞炴�э細y")]
+        public double GPH_Y { get; set; }
+        /// <summary>
+        /// 缁樺浘灞炴�э細properties
+        /// </summary>
+        [DisplayName("缁樺浘灞炴�э細properties")]
+        public string GPH_PROP { get; set; }
+        /// <summary>
+        /// 缁樺浘灞炴�э細text
+        /// </summary>
+        [DisplayName("缁樺浘灞炴�э細text")]
+        public string GPH_TEXT { get; set; }
         /// <summary>
         /// 鏄惁鍚敤(Y/N)
         /// </summary>
+        [DisplayName("鏄惁鍚敤(Y/N)")]
         public string IS_ACTIVE { get; set; }
         /// <summary>
         /// 鏄惁璁剧疆鎵嶈兘涓嬪彂鐢熶骇(Y/N)
@@ -77,45 +84,40 @@
         [DisplayName("鏄惁璁剧疆鎵嶈兘涓嬪彂鐢熶骇(Y/N)")]
         public string NEED_SETUP { get; set; }
         /// <summary>
-        /// 鑷畾涔夋柟娉曠被鍨�(0ServerMethod鏈嶅姟绔柟娉晐1WebApiWebApi鏂规硶|2StoredProcedure瀛樺偍杩囩▼)
+        /// 鎵ц鍑洪敊鏃讹紝鏄惁閲嶇疆鏁翠釜宸ュ簭鐨勬搷浣�(Y/N)
         /// </summary>
-  //      public int DO_TYPE { get; set; }
-		///// <summary>
-		///// 鑷畾涔夋柟娉�(璋冪敤鏂规硶鐨勫叏鍚�)
-		///// </summary>
-		//public string DO_METHOD { get; set; }
-		///// <summary>
-		///// 閫氳繃鏃舵墽琛�(璋冪敤鏂规硶鐨勫叏鍚�)
-		///// </summary>
-		//public string DO_IF_PASS { get; set; }
-		///// <summary>
-		///// 澶辫触鏃舵墽琛�(璋冪敤鏂规硶鐨勫叏鍚�)
-		///// </summary>
-		//public string DO_IF_FAIL { get; set; }
-		/// <summary>
-		/// 璁剧疆鍊�1
-		/// </summary>
-		public string OPTION_1 { get; set; }
-		/// <summary>
-		/// 璁剧疆鍊�2
-		/// </summary>
-		public string OPTION_2 { get; set; }
-		/// <summary>
-		/// 璁剧疆鍊�3
-		/// </summary>
-		public string OPTION_3 { get; set; }
-		/// <summary>
-		/// 璁剧疆鍊�4
-		/// </summary>
-		public string OPTION_4 { get; set; }
-		/// <summary>
-		/// 璁剧疆鍊�5
-		/// </summary>
-		public string OPTION_5 { get; set; }
-		/// <summary>
-		/// 澶囨敞
-		/// </summary>
-		public string REMARK { get; set; }
+        [DisplayName("鎵ц鍑洪敊鏃讹紝鏄惁閲嶇疆鏁翠釜宸ュ簭鐨勬搷浣�(Y/N)")]
+        public string NEED_RESET { get; set; }
+        /// <summary>
+        /// 璁剧疆鍊�1
+        /// </summary>
+        [DisplayName("璁剧疆鍊�1")]
+        public string OPTION_1 { get; set; }
+        /// <summary>
+        /// 璁剧疆鍊�2
+        /// </summary>
+        [DisplayName("璁剧疆鍊�2")]
+        public string OPTION_2 { get; set; }
+        /// <summary>
+        /// 璁剧疆鍊�3
+        /// </summary>
+        [DisplayName("璁剧疆鍊�3")]
+        public string OPTION_3 { get; set; }
+        /// <summary>
+        /// 璁剧疆鍊�4
+        /// </summary>
+        [DisplayName("璁剧疆鍊�4")]
+        public string OPTION_4 { get; set; }
+        /// <summary>
+        /// 璁剧疆鍊�5
+        /// </summary>
+        [DisplayName("璁剧疆鍊�5")]
+        public string OPTION_5 { get; set; }
+        /// <summary>
+        /// 澶囨敞
+        /// </summary>
+        [DisplayName("澶囨敞")]
+        public string REMARK { get; set; }
         #endregion
 
         #region 铏氭嫙灞炴��
@@ -154,6 +156,10 @@
 			Enum1,
 		}
 		*/
+
+        /// <summary>
+        /// 鏋氫妇锛氳涓虹被鍨�(0Normal榛樿琛屼负|1Scan鎵爜楠岃瘉|2Assy缁勮涓婃枡|3Test浜у搧娴嬭瘯|4Audit浜у搧鎶芥|5Print鏍囩鎵撳嵃|6Package鍖呰瑙勫垯)
+        /// </summary>
         public enum ACT_TYPEs
         {
             [Description("鑷畾涔夎涓�")]
@@ -170,16 +176,6 @@
             Print = 5,
             [Description("鍖呰瑙勫垯")]
             Package = 6,
-        }
-
-        public enum DO_TYPEs
-        {
-            [Description("鏈嶅姟绔柟娉�")]
-            ServerMethod,
-            [Description("WebApi鏂规硶")]
-            WebApi,
-            [Description("瀛樺偍杩囩▼")]
-            StoredProcedure,
         }
         #endregion
 
diff --git a/Tiger.Model.Net/Entitys/MES/MES_WO_NODE_ACT.cs b/Tiger.Model.Net/Entitys/MES/MES_WO_NODE_ACT.cs
index 39f8306..f609fae 100644
--- a/Tiger.Model.Net/Entitys/MES/MES_WO_NODE_ACT.cs
+++ b/Tiger.Model.Net/Entitys/MES/MES_WO_NODE_ACT.cs
@@ -98,10 +98,15 @@
 		/// </summary>
 		[DisplayName("鏄惁璁剧疆鎵嶈兘涓嬪彂鐢熶骇(Y/N)")]
 		public string NEED_SETUP { get; set; }
-		/// <summary>
-		/// 璁剧疆鍊�1
-		/// </summary>
-		[DisplayName("璁剧疆鍊�1")]
+        /// <summary>
+        /// 鎵ц鍑洪敊鏃讹紝鏄惁閲嶇疆鏁翠釜宸ュ簭鐨勬搷浣�(Y/N)
+        /// </summary>
+        [DisplayName("鎵ц鍑洪敊鏃讹紝鏄惁閲嶇疆鏁翠釜宸ュ簭鐨勬搷浣�(Y/N)")]
+        public string NEED_RESET { get; set; }
+        /// <summary>
+        /// 璁剧疆鍊�1
+        /// </summary>
+        [DisplayName("璁剧疆鍊�1")]
 		public string OPTION_1 { get; set; }
 		/// <summary>
 		/// 璁剧疆鍊�2
diff --git a/Tiger.Model.Net/Entitys/MES/ParameterEntity/PositionParameter.cs b/Tiger.Model.Net/Entitys/MES/ParameterEntity/PositionParameter.cs
index 4d24f47..d42ab64 100644
--- a/Tiger.Model.Net/Entitys/MES/ParameterEntity/PositionParameter.cs
+++ b/Tiger.Model.Net/Entitys/MES/ParameterEntity/PositionParameter.cs
@@ -19,19 +19,57 @@
 
     public class SubmitInput : ApiInput
     {
-        public int CurStep { get; set; }
-        public string StepID { get; set; }
+        /// <summary>
+        /// 瀹㈡埛绔樉绀虹殑璇█
+        /// </summary>
+        public string Locale {  get; set; }
+        /// <summary>
+        /// 褰撳墠鎿嶄綔鐨勫伐姝D锛屽鏋滄湭鎸囧畾鍒欑暀绌�
+        /// </summary>
+        public string CurStepID { get; set; }
+        /// <summary>
+        /// 褰撳墠鎵弿鐨勫唴瀹癸紝涓嶉檺浜庢潯鐮�
+        /// </summary>
         public string SN { get; set; }
+        /// <summary>
+        /// 褰撳墠鎿嶄綔鎻愪氦鐨勪笉鑹唬鐮侊紝娌℃湁鍒欑暀绌�
+        /// </summary>
         public string DFT_CODE { get; set; }
+        /// <summary>
+        /// 褰撳墠鎿嶄綔闇�瑕佹彁浜ょ殑鏁版嵁
+        /// </summary>
         public string Data { get; set; }
     }
 
     public class SubmitOutput
     {
+        /// <summary>
+        /// 鏁翠釜宸ュ簭鎿嶄綔鏄惁瀹屾垚
+        /// </summary>
         public bool IsFinished { get; set; }
-        public int CurStep { get; set; }
-        public string StepID { get; set; }
+        /// <summary>
+        /// 褰撳墠鎿嶄綔鐨勫伐鍗�
+        /// </summary>
+        public string CurWO { get; set; }
+        /// <summary>
+        /// 褰撳墠鎿嶄綔鐨勫伐鍗曟壒娆�
+        /// </summary>
+        public string CurBatch { get; set; }
+        /// <summary>
+        /// 褰撳墠鎿嶄綔鐨勮妭鐐瑰悕绉�
+        /// </summary>
+        public string CurNode { get; set; }
+        /// <summary>
+        /// 濡傛灉褰撳墠鑺傜偣涓哄伐搴忚涓鸿妭鐐癸紝鍒欒涓哄畾涔夌紪鐮侊紝鍚﹀垯鐣欑┖
+        /// </summary>
         public string StepActCode { get; set; }
+        /// <summary>
+        /// 涓嬩竴涓搷浣滅殑宸ユID
+        /// </summary>
+        public string NextStepID { get; set; }
+        /// <summary>
+        /// 褰撳墠鎿嶄綔杩斿洖鐨勬暟鎹�
+        /// </summary>
         public object Data { get; set; }
     }
 

--
Gitblit v1.9.3