服务端的TigerApi 框架,基于.NET6 2024 版本
Rodney Chen
2024-08-04 0fdd0687f116ac43f7432227dfaa2ebc2f696575
增加扩展信息绑定工序
已修改8个文件
282 ■■■■■ 文件已修改
Tiger.Api/Controllers/Test/TestController.R.cs 6 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tiger.Api/Language.db 补丁 | 查看 | 原始文档 | blame | 历史
Tiger.Business.MES/Transaction/CollectNode.cs 18 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tiger.Business.MES/Transaction/PackingNode.cs 33 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tiger.Business.MES/Transaction/TestNode.cs 19 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tiger.Business.MES/WorkAction/Assembly.cs 7 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tiger.Business.MES/WorkAction/PackingAction.cs 14 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tiger.Business.MES/WorkAction/WipExtInfo.cs 185 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Tiger.Api/Controllers/Test/TestController.R.cs
@@ -325,8 +325,10 @@
        {
            var data = action.Data.Data;
            data?.ToString().JsonToObject<PackingActionInput>();
            var result = JsonConvert.DeserializeObject<PackingActionInput>(data?.ToString() ?? "");
            var act = Biz.Db.Queryable<MES_WO_ACTION>().First(q => q.ID == data);
            var result = act.OPTION_1?.ToString().JsonToObject<List<WipPkgItem>>();
            return Ok(result?.ToJson());
        }
Tiger.Api/Language.db
Binary files differ
Tiger.Business.MES/Transaction/CollectNode.cs
@@ -151,7 +151,8 @@
            }
            catch (Exception ex)
            {
                action.CatchExceptionWithLog(ex, $"采集工序:提交操作数据异常");
                //action.CatchExceptionWithLog(ex, $"采集工序:提交操作数据异常");
                action.CatchExceptionWithLog(ex, Biz.L("MES.Transaction.CollectNode.SubmitException"));
            }
            return action;
        }
@@ -164,9 +165,9 @@
        /// <returns></returns>
        public ApiAction<SubmitOutput> NodeSubmit(ApiAction<SubmitOutput> action, SubmitInput input)
        {
            var curNode = CurBatch.GetNode(PostCode);
            try
            {
                var curNode = CurBatch.GetNode(PostCode);
                //判断工单实时状态判断是否可以生产
                var woStatus = CurBatch.CheckCanProduce(curNode);
                if (!woStatus.IsSuccessed)
@@ -291,7 +292,16 @@
                    //有需要用户提交信息则添加工序节点的其他工步
                    //最后添加当前工序的行为工步
                    GenerateSteps(curStep);
                    try
                    {
                        GenerateSteps(curStep);
                    }
                    catch (System.Exception ex)
                    {
                        ResetNode();
                        //action.CatchExceptionWithLog(ex, $"{curNode.NODE_NAME}:工序行为工步生成异常,请检查工序行为设置");
                        action.CatchExceptionWithLog(ex, Biz.L("MES.Transaction.CollectNode.NodeSubmit.GenerateStepsException", curNode.NODE_NAME));
                    }
                    //完成第一个工序节点工步
                    curStep.IsFinished = true;
@@ -349,6 +359,8 @@
            {
                ResetNode();
                action.CatchExceptionWithLog(ex, $"采集工序:工序节点工步提交数据异常");
                //action.CatchExceptionWithLog(ex, $"{curNode.NODE_NAME}:工序节点工步提交数据异常,请检查工序节点设置");
                action.CatchExceptionWithLog(ex, Biz.L("MES.Transaction.CollectNode.NodeSubmitException", curNode.NODE_NAME));
            }
            return action;
        }
Tiger.Business.MES/Transaction/PackingNode.cs
@@ -175,7 +175,8 @@
            }
            catch (Exception ex)
            {
                action.CatchExceptionWithLog(ex, $"包装工序:提交操作数据异常");
                //action.CatchExceptionWithLog(ex, $"包装工序:提交操作数据异常");
                action.CatchExceptionWithLog(ex, Biz.L("MES.Transaction.PackingNode.SubmitException"));
            }
            return action;
        }
@@ -188,9 +189,9 @@
        /// <returns></returns>
        public ApiAction<SubmitOutput> NodeSubmit(ApiAction<SubmitOutput> action, SubmitInput input)
        {
            var curNode = CurBatch.GetNode(PostCode);
            try
            {
                var curNode = CurBatch.GetNode(PostCode);
                //判断工单实时状态判断是否可以生产
                var woStatus = CurBatch.CheckCanProduce(curNode);
                if (!woStatus.IsSuccessed)
@@ -311,14 +312,23 @@
                        }
                    };
                    Steps.Add(curStep);
                    //有需要用户提交信息则添加工序节点的其他工步
                    //最后添加当前工序的行为工步
                    GenerateSteps(curStep);
                    //完成第一个工序节点工步
                    curStep.IsFinished = true;
                    //有需要用户提交信息则添加工序节点的其他工步
                    //最后添加当前工序的行为工步
                    try
                    {
                        GenerateSteps(curStep);
                    }
                    catch (System.Exception ex)
                    {
                        ResetNode();
                        //action.CatchExceptionWithLog(ex, $"{curNode.NODE_NAME}:工序行为工步生成异常,请检查工序行为设置");
                        action.CatchExceptionWithLog(ex, Biz.L("MES.Transaction.PackingNode.NodeSubmit.GenerateStepsException", curNode.NODE_NAME));
                    }
                    //完成第一个工序节点工步
                    curStep.IsFinished = true;
                    CurStep = curStep;
                } 
                else if (!IsFinishNodeSteps)
@@ -372,7 +382,8 @@
            catch (Exception ex)
            {
                ResetNode();
                action.CatchExceptionWithLog(ex, $"包装工序:工序节点工步提交数据异常");
                //action.CatchExceptionWithLog(ex, $"{curNode.NODE_NAME}:工序节点工步提交数据异常,请检查工序节点设置");
                action.CatchExceptionWithLog(ex, Biz.L("MES.Transaction.PackingNode.NodeSubmitException", curNode.NODE_NAME));
            }
            return action;
        }
Tiger.Business.MES/Transaction/TestNode.cs
@@ -152,7 +152,8 @@
            }
            catch (Exception ex)
            {
                action.CatchExceptionWithLog(ex, $"测试工序:提交操作数据异常");
                //action.CatchExceptionWithLog(ex, $"测试工序:提交操作数据异常");
                action.CatchExceptionWithLog(ex, Biz.L("MES.Transaction.TestNode.SubmitException"));
            }
            return action;
        }
@@ -165,9 +166,9 @@
        /// <returns></returns>
        public ApiAction<SubmitOutput> NodeSubmit(ApiAction<SubmitOutput> action, SubmitInput input)
        {
            var curNode = CurBatch.GetNode(PostCode);
            try
            {
                var curNode = CurBatch.GetNode(PostCode);
                //判断工单实时状态判断是否可以生产
                var woStatus = CurBatch.CheckCanProduce(curNode);
                if (!woStatus.IsSuccessed)
@@ -292,7 +293,16 @@
                    //有需要用户提交信息则添加工序节点的其他工步
                    //最后添加当前工序的行为工步
                    GenerateSteps(curStep);
                    try
                    {
                        GenerateSteps(curStep);
                    }
                    catch (System.Exception ex)
                    {
                        ResetNode();
                        //action.CatchExceptionWithLog(ex, $"{curNode.NODE_NAME}:工序行为工步生成异常,请检查工序行为设置");
                        action.CatchExceptionWithLog(ex, Biz.L("MES.Transaction.TestNode.NodeSubmit.GenerateStepsException", curNode.NODE_NAME));
                    }
                    //完成第一个工序节点工步
                    curStep.IsFinished = true;
@@ -349,7 +359,8 @@
            catch (Exception ex)
            {
                ResetNode();
                action.CatchExceptionWithLog(ex, $"测试工序:工序节点工步提交数据异常");
                //action.CatchExceptionWithLog(ex, $"{curNode.NODE_NAME}:工序节点工步提交数据异常,请检查工序节点设置");
                action.CatchExceptionWithLog(ex, Biz.L("MES.Transaction.TestNode.NodeSubmitException", curNode.NODE_NAME));
            }
            return action;
        }
Tiger.Business.MES/WorkAction/Assembly.cs
@@ -3,7 +3,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Tiger.IBusiness;
@@ -200,7 +199,7 @@
                        action.IsSuccessed = true;
                        action.Data.Data = CurAssembly;
                        action.LocaleMsg = new Locale($"扫描物料[{item.ItemInfo.ITEM_NAME}({item.ItemInfo.ITEM_CODE})的条码[{input.SN}]成功,请继续上料");
                        //action.LocaleMsg = new Locale($"扫描物料[{item.ItemInfo.ITEM_NAME}({item.ItemInfo.ITEM_CODE})的条码[{input.SN}]成功,请继续上料");
                        action.LocaleMsg = new Locale("MES.WorkAction.Assembly.LoadSuccess", item.ItemInfo.ITEM_NAME, item.ItemInfo.ITEM_CODE);
                        //上料完成
@@ -218,9 +217,9 @@
            }
            catch (System.Exception ex)
            {
                action.CatchExceptionWithLog(ex, $"上料行为:验证条码[{input.SN}]并保存数据失败");
                action.CatchExceptionWithLog(ex, $"上料行为:验证条码[{input.SN}]并保存数据异常");
                action.IsSuccessed = false;
                action.LocaleMsg = new($"验证条码[{input.SN}]并保存数据失败,工序已重置,请重新扫描进站产品条码");
                //action.LocaleMsg = new($"验证条码[{input.SN}]并保存数据异常,工序已重置,请重新扫描进站产品条码");
                action.LocaleMsg = new("MES.WorkAction.Assembly.SaveAssemblyException", input.SN);
                CurPosition.ResetNode();
            }
Tiger.Business.MES/WorkAction/PackingAction.cs
@@ -56,11 +56,17 @@
                PkgRule = Biz.Db.Queryable<BAS_PKG_RULE>().Where(q => q.RULE_CODE == setting.PKG_CODE).IncludesAllFirstLayer().IncludesAllSecondLayer(q => q.Details).First();
            }
            //根据行为设置获取多层包装的标签打印模板字典
            for (int i = 1; i < 10; i++)
            //for (int i = 1; i < 10; i++)
            //{
            //    var code = Setting.GetType().GetProperty($"OPTION_{i}")?.GetValue(Setting)?.ToString() ?? "";
            //    var label = code.IsNullOrEmpty() ? null : Biz.Db.Queryable<BAS_LABEL_TEMP>().Where(q => q.LABEL_CODE == code).IncludesAllFirstLayer().First();
            //    LabelDic.Add(i, label);
            //}
            var codes = Setting.OPTION_1?.ToString().JsonToObject<List<WipPkgItem>>();
            foreach (var code in codes)
            {
                var code = Setting.GetType().GetProperty($"OPTION_{i}")?.GetValue(Setting)?.ToString() ?? "";
                var label = code.IsNullOrEmpty() ? null : Biz.Db.Queryable<BAS_LABEL_TEMP>().Where(q => q.LABEL_CODE == code).IncludesAllFirstLayer().First();
                LabelDic.Add(i, label);
                var label = code.LABEL_CODE.IsNullOrEmpty() ? null : Biz.Db.Queryable<BAS_LABEL_TEMP>().Where(q => q.LABEL_CODE == code.LABEL_CODE).IncludesAllFirstLayer().First();
                LabelDic.Add(code.PKG_LEVEL, label);
            }
            //如果工序上下文中没有包装记录则新建一个,有则获取当前的包装记录
            if (CurPosition.Context.ContainsKey("CurPackage") && !CurPosition.Context["CurPackage"].IsNullOrEmpty())
Tiger.Business.MES/WorkAction/WipExtInfo.cs
@@ -22,9 +22,8 @@
        public MES_WO_NODE_ACT NodeAct { get; set; }
        public MES_WO_ACTION Setting { get; set; }
        #endregion
        public List<BAS_PROD_BOM> Boms { get; set; } = new();
        public Dictionary<string, List<BAS_ITEM>> SubItemDic { get; set; } = new();
        public AssemblyInfo CurAssembly { get; set; } = new();
        public BAS_WIP_EXT ExtInfo { get; set; }
        public MES_WIP_EXT CurWipExt { get; set; }
        #endregion Propertys & Variables
        #region Functions
@@ -41,49 +40,16 @@
            Setting = setting;
            #endregion
            //获取产品BOM
            Boms = Biz.Db.Queryable<BAS_PROD_BOM>().Where(q => q.PROD_CODE == CurPosition.WorkBatch.WO.ITEM_CODE).ToList();
            //获取上料物料
            var assyList = new List<AssemblySetting>();
            try
            //获取扩展字段定义
            var seq = Setting.ITEM_CODE.ToInt32();
            ExtInfo = Biz.Db.Queryable<BAS_WIP_EXT>().Where(q => q.SEQ == seq).First();
            //获取当前SN的扩展信息
            CurWipExt = Biz.Db.Queryable<MES_WIP_EXT>().Where(q => q.SN == CurPosition.CurWipSN.SN).First() ?? new ()
            {
                assyList = setting.ITEM_CODE.JsonToObject<List<AssemblySetting>>();
            }
            catch (System.Exception ex)
            {
                var codeList = setting.ITEM_CODE.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                foreach (var code in codeList)
                {
                    assyList.Add(new() { ItemCode = code });
                }
            }
            var codes = assyList.Select(q => q.ItemCode).ToList();
            var items = Biz.Db.Queryable<BAS_ITEM>().Where(q => codes.Contains(q.ITEM_CODE) && q.AUTH_ORG == CurPosition.WorkBatch.WO.AUTH_ORG).ToList();
            //获取上料物料的替代料
            foreach (var assy in assyList)
            {
                var info = items.FirstOrDefault(q => q.ITEM_CODE == assy.ItemCode);
                if (!info.IsNullOrEmpty())
                {
                    var item = new AssemblyItem
                    {
                        ItemInfo = info,
                        RuleCode = assy.RuleCode,
                        LoadQty = assy.Qty,
                    };
                    var bom = Boms.FirstOrDefault(q => q.ITEM_CODE == assy.ItemCode);
                    if (!bom.IsNullOrEmpty())
                    {
                        var subs = bom.SUB_CODE.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
                        var surItems = Biz.Db.Queryable<BAS_ITEM>().Where(q => subs.Contains(q.ITEM_CODE) && q.AUTH_ORG == CurPosition.WorkBatch.WO.AUTH_ORG).ToList();
                        if (!SubItemDic.ContainsKey(assy.ItemCode))
                        {
                            SubItemDic.Add(assy.ItemCode, surItems);
                        }
                    }
                    CurAssembly.Items.Add(item);
                }
            }
                AUTH_ORG = CurPosition.CurWipSN.AUTH_ORG,
                AUTH_PROD = CurPosition.CurWipSN.AUTH_PROD,
                SN = CurPosition.CurWipSN.SN,
            };
        }
        /// <summary>
@@ -92,8 +58,8 @@
        /// <returns></returns>
        public Locale GetBeginMsg()
        {
            var msg = new Locale("MES.WorkAction.WipExtInfo.BeginMsg", string.Join(",", CurAssembly.Items.Select(q => $"{q.ItemInfo.ITEM_NAME}({q.ItemInfo.ITEM_CODE})")));
            //var msg = new Locale($"请扫描以下需要上料的物料条码:{string.Join(",", CurAssembly.Items.Select(q => $"{q.ItemInfo.ITEM_NAME}({q.ItemInfo.ITEM_CODE})"))}");
            var msg = new Locale("MES.WorkAction.WipExtInfo.BeginMsg", ExtInfo.FIELD_NAME);
            //var msg = new Locale($"请扫描产品[{CurPosition.CurWipSN.SN}]需要绑定的[{ExtInfo.FIELD_NAME}]标签条码");
            return msg;
        }
@@ -105,14 +71,10 @@
        {
            var action = new ApiAction<SubmitOutput>(new SubmitOutput());
            if (input.SN != CurPosition.CurWipSN.SN)
            {
                action = SaveAssembly(input, action);
                return action;
            }
            action.LocaleMsg = GetBeginMsg();
            //如果返回成功则认为当前行为可以开始执行,否则返回失败
            action.IsSuccessed = false;
            action.IsSuccessed = true;
            return action;
        }
@@ -124,7 +86,7 @@
        {
            var action = new ApiAction<SubmitOutput>(new SubmitOutput());
            action = SaveAssembly(input, action);
            action = SaveExtInfo(input, action);
            //上料数据保存失败
            if (!action.IsSuccessed)
            {
@@ -137,91 +99,41 @@
            return action;
        }
        public ApiAction<SubmitOutput> SaveAssembly(SubmitInput input, ApiAction<SubmitOutput> action)
        public ApiAction<SubmitOutput> SaveExtInfo(SubmitInput input, ApiAction<SubmitOutput> action)
        {
            try
            {
                foreach (var item in CurAssembly.Items.Where(q => !q.IsFinished))
                var isOK = true;
                //验证扫描的条码是否SN的扩展信息的标签
                if (input.SN.IsNullOrEmpty())
                {
                    var isOK = true;
                    //根据条码规则验证上料是否正确
                    if (!item.RuleCode.IsNullOrEmpty())
                    {
                        if (!Biz.CodeRule[item.RuleCode].IsNullOrEmpty())
                        {
                            var result = Biz.CodeRule[item.RuleCode].Verify(input.SN);
                            if (!result.IsSuccessed)
                            {
                                isOK = false;
                            }
                        }
                        //不存在条码规则,则判断是否有自定义规则,没有则返回失败
                        else
                        {
                            switch (item.RuleCode)
                            {
                                case "自行验证":
                                    break;
                                default:
                                    isOK = false;
                                    break;
                            }
                        }
                    }
                    //验证通过则保存上料信息
                    if (isOK)
                    {
                        var record = new MES_WIP_ASSY()
                        {
                            AUTH_ORG = CurPosition.WorkBatch.WO.AUTH_ORG,
                            AUTH_PROD = CurPosition.CurLine.LINE_CODE,
                            SN = input.SN,
                            PROD_SN = CurPosition.CurWipSN.SN,
                            ITEM_CODE = item.ItemInfo.ITEM_CODE,
                            QTY = 1,
                            UNIT = item.ItemInfo.UNIT,
                            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,
                            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,
                        };
                        item.Records.Add(record);
                        if (item.Records.Sum(q => q.QTY) >= item.LoadQty)
                        {
                            item.IsFinished = true;
                        }
                        action.IsSuccessed = true;
                        action.Data.Data = CurAssembly;
                        action.LocaleMsg = new Locale($"扫描物料[{item.ItemInfo.ITEM_NAME}({item.ItemInfo.ITEM_CODE})的条码[{input.SN}]成功,请继续上料");
                        action.LocaleMsg = new Locale("MES.WorkAction.WipExtInfo.LoadSuccess", item.ItemInfo.ITEM_NAME, item.ItemInfo.ITEM_CODE);
                        //上料完成
                        if (CurAssembly.IsFinished)
                        {
                            action = End();
                        }
                        return action;
                    }
                    action.IsSuccessed = isOK = false;
                    //action.LocaleMsg = new Locale($"错误:[{ExtInfo.FIELD_NAME}]标签条码不能为空,请重新扫描");
                    action.LocaleMsg = new Locale("MES.WorkAction.WipExtInfo.SnEmptyError", ExtInfo.FIELD_NAME);
                }
                if (input.SN == CurPosition.CurWipSN.SN)
                {
                    action.IsSuccessed = isOK = false;
                    //action.LocaleMsg = new Locale($"错误:扫描到产品条码[{input.SN}],请重新扫描[{ExtInfo.FIELD_NAME}]标签条码");
                    action.LocaleMsg = new Locale("MES.WorkAction.WipExtInfo.ScanProdSnError", input.SN, ExtInfo.FIELD_NAME);
                }
                //验证通过则保存上料信息
                if (isOK)
                {
                    CurWipExt.GetType().GetProperty($"FIELD_{ExtInfo.SEQ.ToString("00")}")?.SetValue(CurWipExt, input.SN);
                    action = End();
                }
                //都没有物料验证通过,则返回错误信息
                action.IsSuccessed = false;
                //action.LocaleMsg = new($"条码[{input.SN}]验证失败,不是以下物料的条码:{string.Join(",", CurAssembly.Items.Where(q => !q.IsFinished).Select(q => $"{q.ItemInfo.ITEM_NAME}({q.ItemInfo.ITEM_CODE})"))}");
                action.LocaleMsg = new("MES.WorkAction.WipExtInfo.LoadFail", input.SN, string.Join(",", CurAssembly.Items.Where(q => !q.IsFinished).Select(q => $"{q.ItemInfo.ITEM_NAME}({q.ItemInfo.ITEM_CODE})")));
            }
            catch (System.Exception ex)
            {
                action.CatchExceptionWithLog(ex, $"上料行为:验证条码[{input.SN}]并保存数据失败");
                action.CatchExceptionWithLog(ex, $"扩展信息绑定行为:产品[{CurPosition.CurWipSN.SN}]绑定[{ExtInfo.FIELD_NAME}]标签条码[{input.SN}]保存异常");
                action.IsSuccessed = false;
                action.LocaleMsg = new($"验证条码[{input.SN}]并保存数据失败,工序已重置,请重新扫描进站产品条码");
                action.LocaleMsg = new("MES.WorkAction.WipExtInfo.SaveAssemblyException", input.SN);
                //action.LocaleMsg = new($"产品[{CurPosition.CurWipSN.SN}]绑定[{ExtInfo.FIELD_NAME}]标签条码[{input.SN}]保存异常,工序已重置,请重新扫描进站产品条码");
                action.LocaleMsg = new("MES.WorkAction.WipExtInfo.SaveExtInfoException", CurPosition.CurWipSN.SN, ExtInfo.FIELD_NAME, input.SN);
                CurPosition.ResetNode();
            }
            return action;
@@ -264,27 +176,22 @@
                PRD_CODE = CurPosition.CurWipSN.PRD_CODE,
                ACT_TYPE = NodeAct.ACT_TYPE,
                ACT_SN = CurPosition.CurWipSN.SN,
                ACT_VALUE_1 = CurAssembly.ToJson(),
                ACT_VALUE_1 = CurWipExt.ToJson(),
                ACT_RESULT = "Y",
                TRACE_INFO = $"以下物料上料完成:{string.Join(",", CurAssembly.Items.Select(q => $"{q.ItemInfo.ITEM_NAME}({q.ItemInfo.ITEM_CODE})"))}",
                TRACE_INFO = $"产品[{CurPosition.CurWipSN.SN}]绑定[{ExtInfo.FIELD_NAME}]标签条码[{CurWipExt.GetType().GetProperty($"FIELD_{ExtInfo.SEQ.ToString("00")}")?.GetValue(CurWipExt)?.ToString()}]保存成功",
            };
            var records = new List<MES_WIP_ASSY>();
            foreach (var item in CurAssembly.Items)
            {
                records.AddRange(item.Records);
            }
            //保存数据
            CurStep.DBSubmitAction = () =>
            {
                var db = CurPosition.GetCommitDB();
                db.Storageable(wipAct, CurPosition.UserCode).ExecuteCommand();
                db.Insertable(records, CurPosition.UserCode).ExecuteCommand();
                db.Storageable(CurWipExt, CurPosition.UserCode).ExecuteCommand();
            };
            IsFinished = true;
            //action.LocaleMsg = new($"以下物料上料完成:{string.Join(",", CurAssembly.Items.Select(q => $"{q.ItemInfo.ITEM_NAME}({q.ItemInfo.ITEM_CODE})"))}");
            action.LocaleMsg = new("MES.WorkAction.WipExtInfo.LoadFinish", string.Join(",", CurAssembly.Items.Select(q => $"{q.ItemInfo.ITEM_NAME}({q.ItemInfo.ITEM_CODE})")));
            //action.LocaleMsg = new($"产品[{CurPosition.CurWipSN.SN}]绑定[{ExtInfo.FIELD_NAME}]标签条码[{CurWipExt.GetType().GetProperty($"FIELD_{ExtInfo.SEQ.ToString("00")}")?.GetValue(CurWipExt)?.ToString()}]保存成功");
            action.LocaleMsg = new("MES.WorkAction.WipExtInfo.SaveSuccess", CurPosition.CurWipSN.SN, ExtInfo.FIELD_NAME, CurWipExt.GetType().GetProperty($"FIELD_{ExtInfo.SEQ.ToString("00")}")?.GetValue(CurWipExt)?.ToString());
            return action;
        }