using Admin.Core.Common;
using Admin.Core.IService;
using Admin.Core.Model.Model_New;
using Admin.Core.Model;
using Admin.Core.Model.ViewModels;
using System.Text;
using System.Timers;
using Aucma.Core.HwPLc;

namespace Aucma.Core.SheetMetalTasks
{
    /// <summary>
    /// 任务列表
    /// </summary>
    public class AucamSheetMetalTaskService : IAucamSheetMetalTaskService
    {
        #region 刷新创建计划
        /// <summary>
        /// 刷新创建计划
        /// </summary>
        public delegate Task RefreshCretaePlanInfo();
        public static event RefreshCretaePlanInfo RefreshCreatePlanInfoEvent;
        #endregion

        #region 刷新图表
        /// <summary>
        /// 刷新创建计划
        /// </summary>
        public delegate Task RefreshChat();
        public static event RefreshChat RefreshChatEvent;
        #endregion

        #region 刷新创建计划
        /// <summary>
        /// 刷新创建计划
        /// </summary>
        public delegate void RefreshPlanInfo(SheetMetaSendPlanInfoView planInfo);
        public static event RefreshPlanInfo RefreshPlanInfoEvent;
        #endregion

        #region 刷新当前正在执行的计划
        /// <summary>
        /// 刷新当前正在执行的计划
        /// </summary>
        public delegate void RefreshCurrentPlanInfo();
        public static event RefreshCurrentPlanInfo RefreshCurrentPlanInfoEvent;

        #endregion

        #region 给设备监控模块显示
        /// <summary>
        /// 刷新当前正在执行的计划
        /// </summary>
        public delegate void RefreshExecInfo(string message, string color);
        public static event RefreshExecInfo RefreshExecInfoEvent;

        #endregion

        protected readonly IExecutePlanInfoServices? _executePlanInfoServices;
        protected readonly IRecordSidePanelComplateServices _sidePanelComplateServices;
        protected readonly IRecordBackPanelComplateServices _backPanelComplateServices;
        protected readonly IProductPlanInfoServices? _productPlanInfoServices;
        protected readonly ISysUserInfoServices? _sysUserInfoServices;
        protected readonly IMaterialCompletionServices? _materialCompletionServices;
        public HwPLc.PlcModel plc1 = null;
        bool flay = true;//方法完成标识

        #region 构造函数
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="executePlanInfoServices"></param>
        /// <param name="recordSidePanelComplateServices"></param>
        /// <param name="recordBackPanelComplateServices"></param>
        /// <param name="productPlanInfoServices"></param>
        /// <param name="sysUserInfoServices"></param>
        /// <param name="materialCompletionServices"></param>
        public AucamSheetMetalTaskService(IExecutePlanInfoServices executePlanInfoServices, IRecordSidePanelComplateServices recordSidePanelComplateServices,
        IRecordBackPanelComplateServices recordBackPanelComplateServices, IProductPlanInfoServices productPlanInfoServices,
        ISysUserInfoServices sysUserInfoServices, IMaterialCompletionServices materialCompletionServices)
        {
            _executePlanInfoServices = executePlanInfoServices;
            _sidePanelComplateServices = recordSidePanelComplateServices;
            _backPanelComplateServices = recordBackPanelComplateServices;
            _productPlanInfoServices = productPlanInfoServices;
            _sysUserInfoServices = sysUserInfoServices;
            _materialCompletionServices = materialCompletionServices;
        } 
        #endregion

        #region 更新钣金工位计划数


        public Task SheetMetalTasks()
        {
            //System.Timers.Timer timer = new System.Timers.Timer(5000);
            //timer.Elapsed += new System.Timers.ElapsedEventHandler(Run1);  //到达时间的时候执行事件;
            //timer.AutoReset = true;//设置是执行一次(false)还是一直执行(true); 
            //timer.Enabled = true;//需要调用 timer.Start()或者timer.Enabled = true来启动它,
            //timer.Start();//timer.Start()的内部原理还是设置timer.Enabled = true;
            Task.Run(() =>
            {
                InitSendBackPanelPlan();
            });
            Task.Run(() =>
            {
                InitSendSidePanelPlan();
            });
            Task.Run(() =>
            {
                UpdateComplatePlan();//更新计划数
            });
            return Task.CompletedTask;
        }

        private void Run1(object? sender, ElapsedEventArgs e)
        {
            if (flay)
            {
                flay = false;
                lock (string.Empty)
                {
                    
                }
            }
        }
        #endregion


        #region 下发多个计划同步执行

        /// <summary>
        /// 初始化下发生产计划,获取已拆分的计划进行下发——后板任务
        /// </summary>
        public async void InitSendBackPanelPlan()
        {
            Thread.Sleep(5000);
            var obj_backPanel = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("BackPanelPLC"));
            await Task.CompletedTask;
            while (true)
            {
                var planInfoList = await _executePlanInfoServices.QuerySheetMetalSendPlanData("1001");
                if (planInfoList == null || planInfoList.Count == 0) continue;
                planInfoList = planInfoList.Where(d => d.PlanAmount > d.SidePanelAmount).ToList();
                if (planInfoList == null || planInfoList.Count == 0) continue;
                planInfoList = planInfoList.Where(d => d.ExecuteStatus == 1 || d.ExecuteStatus == 2).ToList();
                if (planInfoList == null || planInfoList.Count == 0) continue;
                var planInfos = planInfoList.Where(d => d.PlanType == 3 || d.PlanType == 1).ToList();
                if (planInfos != null)
                {
                    if (planInfos.Count > 0)
                    {
                        SheetMetaSendPlanInfoView planInfo = planInfos.FirstOrDefault(d => d.BackPanelAmount != d.PlanAmount);
                        if (planInfo == null) continue;
                        if (planInfo.PlanType == 3 || planInfo.PlanType == 1)//如果为3或者为1 后板计划单独下发  以前板完成为主
                        {
                            //获取设置的型号查询对应的型号,下发计划

                            SendPlanTaskToBackPanel(planInfo, obj_backPanel);

                            UpdateBackPanelPlanTaskByComplate(planInfo);
                        }
                    }
                    else
                    {
                        Console.WriteLine("未获取到需要下发的任务");
                    }
                }
                Thread.Sleep(3000);
            }
        }

        /// <summary>
        /// 初始化下发生产计划,获取已拆分的计划进行下发——前板任务
        /// </summary>
        public async void InitSendSidePanelPlan()
        {
            Thread.Sleep(5000);
            var obj_sidePanel = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("SidePanelPlc"));

            while (true)
            {
                List<SheetMetaSendPlanInfoView> planInfoList = await _executePlanInfoServices.QuerySheetMetalSendPlanData("1001");
                if (planInfoList == null || planInfoList.Count == 0) continue;
                planInfoList = planInfoList.Where(d => d.PlanAmount > d.SidePanelAmount).ToList();
                if (planInfoList == null || planInfoList.Count == 0) continue;
                planInfoList = planInfoList.Where(d => d.ExecuteStatus == 1 || d.ExecuteStatus == 2).ToList();
                if (planInfoList == null || planInfoList.Count == 0) continue;
                var planInfos = planInfoList.Where(d => d.PlanType == 2 || d.PlanType == 1).ToList();
                if (planInfos != null)
                {
                    if (planInfos.Count > 0)
                    {
                        SheetMetaSendPlanInfoView planInfo = planInfos.FirstOrDefault(d => d.SidePanelAmount != d.PlanAmount);
                        if (planInfo == null) continue;
                        if (planInfo.PlanType == 2 || planInfo.PlanType == 1)//如果为2或者为1 前板板计划单独下发  以前板完成为主
                        {
                            SendPlanTaskToSidPanel(planInfo, obj_sidePanel);

                            UpdateSidPanelPlanTaskByComplate(planInfo);
                        }
                    }
                    else
                    {
                        Console.WriteLine("未获取到需要下发的任务");
                    }
                }

                Thread.Sleep(5000);
            }
        }
        /// <summary>
        /// 下发前板生产计划
        /// </summary>
        /// <param name="planInfo"></param>
        /// <param name="obj"></param>
        public void SendPlanTaskToSidPanel(SheetMetaSendPlanInfoView planInfo, PlcModel obj_sidePanel)
        {
            try
            {
                Task.Run(() =>
                {
                    if (obj_sidePanel != null)
                    {
                        //计划编号10个字:D6000-D6009、物料编号10个字:D6010-D6019、计划数量1个字:D6020、应答字1个字D6021
                        obj_sidePanel.plc.WriteString("D6000", planInfo.TaskCode);
                        string processNumber = GetProcessNumberBy(planInfo.MaterialCode);
                        obj_sidePanel.plc.WriteString("D6010", planInfo.MaterialSpecificatons);
                        obj_sidePanel.plc.WriteInt32("D6020", planInfo.PlanAmount);
                        obj_sidePanel.plc.WriteInt32("D6021", 1);

                        Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>计划【{planInfo.TaskCode}】已下发,等待前板设备应答。。。。。。");
                        RefreshExecInfoEvent?.Invoke($"计划【{planInfo.TaskCode}】已下发,等待前板设备应答。。。。。。", "White");
                        #region PLC反馈信号逻辑处理
                        //循环读取PLC应答信号,PLC应答后复位应答信号、更新计划状态为执行中
                        bool isFlag = true;
                        DateTime startTime = DateTime.Now;
                        do
                        {

                            if (obj_sidePanel.plc.ReadInt32("D6021") == 2)
                            {
                                obj_sidePanel.plc.WriteInt32("D6021", 0);
                                Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>计划【{planInfo.TaskCode}】,收到前板设备应答信号,复位应答地址");
                                RefreshExecInfoEvent?.Invoke($"计划【{planInfo.TaskCode}】,收到前板板设备应答信号,复位应答地址", "White");
                                startTime = DateTime.Now;
                                isFlag = false;
                            }
                            Thread.Sleep(2000);
                        } while (isFlag);

                        //更新计划状态为2执行中
                        planInfo.ExecuteStatus = 2;
                        bool result = _executePlanInfoServices.UpdateSheetMetalExecutePlanInfo(planInfo.ObjId, planInfo.ExecuteStatus, startTime).Result;
                        if (result)
                        {
                            //更新前端展示图表
                            RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                            RefreshChatEvent?.Invoke();//刷新图表
                        }

                        #endregion

                        //读取设备进度,完成后再次下发新任务
                        ReadDeviceComplate_SidePanel(obj_sidePanel);

                        if (!isFlag)
                        {
                            //更新前端展示图表
                            RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                            RefreshChatEvent?.Invoke();//刷新图表
                            RefreshPlanInfoEvent?.Invoke(planInfo);//刷新计划执行
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                RefreshExecInfoEvent?.Invoke($"前板⽣产计划下发异常:{ex.Message}", "Red");
            }
        }

        /// <summary>
        /// 下发背板生产计划
        /// </summary>
        /// <param name="planInfo"></param>
        /// <param name="obj"></param>
        public void SendPlanTaskToBackPanel(SheetMetaSendPlanInfoView planInfo, PlcModel obj_backPanel)
        {
            try
            {
                Task.Run(() =>
                {
                    if (obj_backPanel != null)
                    {
                        //计划编号10个字:D6000-D6009、物料编号10个字:D6010-D6019、计划数量1个字:D6020、应答字1个字D6021
                        obj_backPanel.plc.WriteString("D4000", planInfo.TaskCode);
                        string processNumber = GetProcessNumberBy(planInfo.MaterialCode);
                        obj_backPanel.plc.WriteString("D4010", planInfo.MaterialSpecificatons);
                        obj_backPanel.plc.WriteInt32("D4020", planInfo.PlanAmount);
                        obj_backPanel.plc.WriteInt32("D4021", 1);

                        Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>计划【{planInfo.TaskCode}】已下发,等待背板设备应答。。。。。。");
                        RefreshExecInfoEvent?.Invoke($"计划【{planInfo.TaskCode}】已下发,等待背板设备应答。。。。。。", "White");
                        #region PLC反馈信号逻辑处理
                        //循环读取PLC应答信号,PLC应答后复位应答信号、更新计划状态为执行中
                        bool isFlag = true;
                        DateTime startTime = DateTime.Now;
                        do
                        {

                            if (obj_backPanel.plc.ReadInt32("D4021") == 2)
                            {
                                obj_backPanel.plc.WriteInt32("D4021", 0);
                                Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>收到背板板设备应答信号,复位应答地址");
                                RefreshExecInfoEvent?.Invoke($"收到背板板设备应答信号,复位应答地址", "White");
                                startTime = DateTime.Now;
                                isFlag = false;
                            }
                            Thread.Sleep(2000);
                        } while (isFlag);

                        //更新计划状态为2执行中
                        planInfo.ExecuteStatus = 2;
                        bool result = _executePlanInfoServices.UpdateSheetMetalExecutePlanInfo(planInfo.ObjId, planInfo.ExecuteStatus, startTime).Result;
                        if (result)
                        {
                            //更新前端展示图表
                            RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                            RefreshChatEvent?.Invoke();//刷新图表
                                                       //RefreshPlanInfoEvent?.Invoke(planInfo);
                        }

                        #endregion

                        //读取设备进度,完成后再次下发新任务
                        ReadDeviceComplate_BackPanel(obj_backPanel);

                        if (!isFlag)
                        {
                            //更新前端展示图表
                            RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                            RefreshChatEvent?.Invoke();//刷新图表
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                RefreshExecInfoEvent?.Invoke($"背板⽣产计划下发异常:{ex.Message}", "Red");
            }
        }

        /// <summary>
        /// 根据后板完成记录更新生产计划
        /// </summary>
        /// <param name="planInfo"></param>
        private void UpdateBackPanelPlanTaskByComplate(SheetMetaSendPlanInfoView planInfo)
        {
            try
            {
                lock (string.Empty)
                {
                    bool isComplate = true;

                    do
                    {
                        //等待计划执行完成
                        List<RecordSidePanelComplate> sidePanelComplates = _sidePanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planInfo.TaskCode);
                        int sumSidePanelAmount = sidePanelComplates.Sum(x => x.OutPutAmount);

                        List<RecordBackPanelComplate> backPanelComplates = _backPanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planInfo.TaskCode);
                        int sumBackPanelAmount = backPanelComplates.Sum(x => x.OutPutAmount);

                        Console.WriteLine($"当前计划:{planInfo.TaskCode};计划产量:{planInfo.PlanAmount};前板完成:{sumSidePanelAmount};背板完成:{sumBackPanelAmount}");
                        RefreshExecInfoEvent?.Invoke($"当前计划:{planInfo.TaskCode};计划产量:{planInfo.PlanAmount};前板完成:{sumSidePanelAmount};背板完成:{sumBackPanelAmount}", "White");
                        int sumAmount = 0;

                        if (planInfo.PlanType == 1)
                        {
                            if (planInfo.PlanAmount == sumBackPanelAmount)
                            {
                                if (sumSidePanelAmount == sumBackPanelAmount && sumSidePanelAmount != 0 && sumBackPanelAmount != 0)
                                {
                                    sumAmount = sumSidePanelAmount;
                                    planInfo.ExecuteStatus = 3;
                                }
                                if (sumSidePanelAmount < sumBackPanelAmount && sumBackPanelAmount == planInfo.PlanAmount)
                                {
                                    sumAmount = sumSidePanelAmount;
                                }
                                if (sumSidePanelAmount > sumBackPanelAmount && sumSidePanelAmount == planInfo.PlanAmount)
                                {
                                    sumAmount = sumBackPanelAmount;
                                }
                                if (sumSidePanelAmount == 0 && sumBackPanelAmount == 0) sumAmount = 0;
                                isComplate = false;

                            }
                            else
                            {
                                if (sumSidePanelAmount < sumBackPanelAmount && sumBackPanelAmount == planInfo.PlanAmount)
                                {
                                    sumAmount = sumSidePanelAmount;
                                }
                                if (sumSidePanelAmount > sumBackPanelAmount && sumSidePanelAmount == planInfo.PlanAmount)
                                {
                                    sumAmount = sumBackPanelAmount;
                                }
                                if (sumSidePanelAmount == 0 && sumBackPanelAmount == 0) sumAmount = 0;
                            }
                        }

                        if (planInfo.PlanType == 3)
                        {
                            sumAmount = sumBackPanelAmount;
                            if (planInfo.PlanAmount - sumAmount == 0)
                            {
                                planInfo.ExecuteStatus = 3;
                                isComplate = false;
                            }

                            planInfo.CompleteAmount = sumAmount;
                        }

                        var obj = _executePlanInfoServices.FirstAsync(d => d.ObjId == planInfo.ObjId).Result;

                        if (obj.PlanType == 1 && planInfo.ExecuteStatus == 3)
                        {
                            obj.CompleteAmount = sumAmount;
                            obj.EndTime = DateTime.Now;
                        }

                        if (obj.PlanType == 3 && planInfo.ExecuteStatus == 3)
                        {
                            obj.EndTime = DateTime.Now;
                        }

                        bool result = _executePlanInfoServices.UpdateExecutePlanInfo(obj).Result;
                        if (result)
                        {
                            //更新前端展示图表
                            // RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                            //if (planInfo.PlanType == 3)
                            //{
                            RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                            RefreshPlanInfoEvent?.Invoke(planInfo);
                            //}
                            RefreshChatEvent?.Invoke();//刷新图表
                        }

                        Thread.Sleep(5000);

                    } while (isComplate);

                    if (!isComplate)
                    {
                        RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                        RefreshPlanInfoEvent?.Invoke(planInfo);
                        RefreshChatEvent?.Invoke();//刷新图表
                    }
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"计划任务信息更新异常:{ex.Message}");
                RefreshExecInfoEvent?.Invoke($"计划任务信息更新异常:{ex.Message}", "Red");
            }
        }
        /// <summary>
        /// 根据前板完成记录更新生产计划
        /// </summary>
        /// <param name="planInfo"></param>
        private void UpdateSidPanelPlanTaskByComplate(SheetMetaSendPlanInfoView planInfo)
        {

            lock (string.Empty)
            {
                bool isComplate = true;

                do
                {
                    try
                    {
                        //等待计划执行完成
                        List<RecordSidePanelComplate> sidePanelComplates = _sidePanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planInfo.TaskCode);
                        int sumSidePanelAmount = sidePanelComplates.Sum(x => x.OutPutAmount);

                        List<RecordBackPanelComplate> backPanelComplates = _backPanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planInfo.TaskCode);
                        int sumBackPanelAmount = backPanelComplates.Sum(x => x.OutPutAmount);

                        Console.WriteLine($"当前计划:{planInfo.TaskCode};计划产量:{planInfo.PlanAmount};前板完成:{sumSidePanelAmount};背板完成:{sumBackPanelAmount}");
                        RefreshExecInfoEvent?.Invoke($"当前计划:{planInfo.TaskCode};计划产量:{planInfo.PlanAmount};前板完成:{sumSidePanelAmount};背板完成:{sumBackPanelAmount}", "White");
                        int sumAmount = 0;


                        if (planInfo.PlanType == 1)
                        {
                            if (planInfo.PlanAmount == sumSidePanelAmount)
                            {
                                if (sumSidePanelAmount == sumBackPanelAmount && sumSidePanelAmount != 0 && sumBackPanelAmount != 0)
                                {
                                    sumAmount = sumSidePanelAmount;
                                    planInfo.ExecuteStatus = 3;
                                }

                                if (sumSidePanelAmount < sumBackPanelAmount && sumBackPanelAmount == planInfo.PlanAmount)
                                {
                                    sumAmount = sumSidePanelAmount;
                                }
                                if (sumSidePanelAmount > sumBackPanelAmount && sumSidePanelAmount == planInfo.PlanAmount)
                                {
                                    sumAmount = sumBackPanelAmount;
                                }
                                if (sumSidePanelAmount == 0 && sumBackPanelAmount == 0) sumAmount = 0;

                                isComplate = false;
                            }
                            else
                            {
                                if (sumSidePanelAmount < sumBackPanelAmount && sumBackPanelAmount == planInfo.PlanAmount)
                                {
                                    sumAmount = sumSidePanelAmount;
                                }
                                if (sumSidePanelAmount > sumBackPanelAmount && sumSidePanelAmount == planInfo.PlanAmount)
                                {
                                    sumAmount = sumBackPanelAmount;
                                }
                                if (sumSidePanelAmount == 0 && sumBackPanelAmount == 0) sumAmount = 0;
                            }
                        }

                        if (planInfo.PlanType == 2)
                        {
                            sumAmount = sumBackPanelAmount;
                            if (planInfo.PlanAmount - sumAmount == 0)
                            {
                                planInfo.ExecuteStatus = 3;
                                isComplate = false;
                            }
                            planInfo.CompleteAmount = sumAmount;
                        }

                        planInfo.CompleteAmount = sumAmount;

                        var obj = _executePlanInfoServices.FirstAsync(d => d.ObjId == planInfo.ObjId).Result;
                        obj.CompleteAmount = planInfo.CompleteAmount;
                        obj.ExecuteStatus = planInfo.ExecuteStatus;
                        bool result = _executePlanInfoServices.UpdateExecutePlanInfo(obj).Result;
                        if (result)
                        {
                            //更新前端展示图表
                            //RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                            RefreshChatEvent?.Invoke();//刷新图表
                                                       //SheetMetaSendPlanInfoView planInfo = planInfoList.FirstOrDefault(d => d.TaskCode == planCode);
                            RefreshPlanInfoEvent?.Invoke(planInfo);//刷新计划执行
                        }
                        Thread.Sleep(5000);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine($"计划任务信息更新异常:{ex.Message}");
                        RefreshExecInfoEvent?.Invoke($"计划任务信息更新异常:{ex.Message}", "Red");
                    }
                } while (isComplate);

                if (!isComplate)
                {
                    //更新前端展示图表
                    //RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                    RefreshChatEvent?.Invoke();//刷新图表
                                               //SheetMetaSendPlanInfoView planInfo = planInfoList.FirstOrDefault(d => d.TaskCode == planCode);
                    RefreshPlanInfoEvent?.Invoke(planInfo);//刷新计划执行
                }
            }

        }

        #endregion

        #region 下发单个计划逻辑




        /// <summary>
        /// 初始化下发生产计划,获取已拆分的计划进行下发
        /// </summary>
        public void InitSendPlan()
        {
            Thread.Sleep(5000);
            var obj_sidePanel = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("SidePanelPlc"));
            var obj_backPanel = PlcHelper.melsecList.FirstOrDefault(d => d.EquipName.Equals("BackPanelPLC"));

            while (true)
            {
                var planInfos = _executePlanInfoServices.Query(d => d.ProductLineCode.Equals("1001") && d.ExecuteStatus == 1 || d.ExecuteStatus == 2);

                if (planInfos != null)
                {
                    if (planInfos.Count > 0)
                    {
                        ExecutePlanInfo planInfo = planInfos.First();
                        if (planInfo.PlanType == 1) //联合下发
                        {
                            SendPlanTask(planInfo, obj_sidePanel, obj_backPanel);

                            UpdatePlanTaskByComplate(planInfo);

                        }
                        else if (planInfo.PlanType == 2)
                        {
                            SendPlanTask_SidePanel(planInfo, obj_sidePanel);

                            UpdatePlanTaskByComplate(planInfo);

                        }
                        else if (planInfo.PlanType == 3)
                        {
                            SendPlanTaskTo_BackPanel(planInfo, obj_backPanel);

                            UpdatePlanTaskByComplate(planInfo);
                        }
                    }
                    else
                    {
                        Console.WriteLine("未获取到需要下发的任务");
                    }
                }

                Thread.Sleep(3000);
            }
        }

        /// <summary>
        /// 根据完成记录更新生产计划
        /// </summary>
        /// <param name="planInfo"></param>
        private void UpdatePlanTaskByComplate(ExecutePlanInfo planInfo)
        {
            try
            {
                lock (string.Empty)
                {
                    bool isComplate = true;

                    do
                    {
                        //等待计划执行完成
                        List<RecordSidePanelComplate> sidePanelComplates = _sidePanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planInfo.TaskCode);
                        int sumSidePanelAmount = sidePanelComplates.Sum(x => x.OutPutAmount);

                        List<RecordBackPanelComplate> backPanelComplates = _backPanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planInfo.TaskCode);
                        int sumBackPanelAmount = backPanelComplates.Sum(x => x.OutPutAmount);

                        Console.WriteLine($"当前计划:{planInfo.TaskCode};计划产量:{planInfo.PlanAmount};前板完成:{sumSidePanelAmount};背板完成:{sumBackPanelAmount}");
                        RefreshExecInfoEvent?.Invoke($"当前计划:{planInfo.TaskCode};计划产量:{planInfo.PlanAmount};前板完成:{sumSidePanelAmount};背板完成:{sumBackPanelAmount}", "White");
                        int sumAmount = 0;

                        if (planInfo.PlanType == 1)
                        {
                            if (sumSidePanelAmount >= sumBackPanelAmount)
                            {
                                sumAmount = sumBackPanelAmount;
                            }
                            else
                            {
                                sumAmount = sumSidePanelAmount;
                            }
                        }
                        else if (planInfo.PlanType == 2)
                        {
                            sumAmount = sumSidePanelAmount;
                        }
                        else
                        {
                            sumAmount = sumBackPanelAmount;
                        }

                        if (planInfo.PlanAmount - sumAmount == 0)
                        {
                            planInfo.ExecuteStatus = 3;
                            isComplate = false;
                        }

                        planInfo.CompleteAmount = sumAmount;

                        bool result = _executePlanInfoServices.UpdateExecutePlanInfo(planInfo).Result;
                        if (result)
                        {
                            //更新前端展示图表
                            RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                            RefreshChatEvent?.Invoke();//刷新图表
                        }
                        Thread.Sleep(5000);

                    } while (isComplate);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"计划任务信息更新异常:{ex.Message}");
                RefreshExecInfoEvent?.Invoke($"计划任务信息更新异常:{ex.Message}", "Red");
            }
        }

        /// <summary>
        /// 联合下发
        /// </summary>
        /// <param name="planInfo"></param>
        /// <param name="obj_sidePanel"></param>
        /// <param name="obj_backPanel"></param>
        private void SendPlanTask(ExecutePlanInfo planInfo, PlcModel obj_sidePanel, PlcModel obj_backPanel)
        {
            try
            {
                //前板
                Task.Run(() =>
                {
                    if (obj_sidePanel != null)
                    {
                        //计划编号10个字:D6000-D6009、物料编号10个字:D6010-D6019、计划数量1个字:D6020、应答字1个字D6021
                        obj_sidePanel.plc.WriteString("D6000", planInfo.TaskCode);
                        string processNumber = GetProcessNumberBy(planInfo.MaterialCode);
                        obj_sidePanel.plc.WriteString("D6010", planInfo.MaterialSpecificatons);
                        obj_sidePanel.plc.WriteInt32("D6020", planInfo.PlanAmount);
                        obj_sidePanel.plc.WriteInt32("D6021", 1);

                        Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待前板设备应答。。。。。。");
                        RefreshExecInfoEvent?.Invoke("等待前板设备应答......", "Red");
                        //下发完成后读取PLC应答,应答后复位应答信号

                        #region PLC反馈信号逻辑处理
                        //循环读取PLC应答信号,PLC应答后复位应答信号、更新计划状态为执行中
                        bool isFlag = true;
                        do
                        {
                            //开始做计划的时候给我
                            if (obj_sidePanel.plc.ReadInt32("D6021") == 2)
                            {
                                obj_sidePanel.plc.WriteInt32("D6021", 0);
                                Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>收到前板设备应答信号,复位应答地址");
                                RefreshExecInfoEvent?.Invoke("收到前板设备应答信号,复位应答地址", "White");
                                isFlag = false;
                            }
                            Thread.Sleep(2000);
                        } while (isFlag);

                        //更新计划状态为2执行中
                        planInfo.ExecuteStatus = 2;
                        bool result = _executePlanInfoServices.UpdateExecutePlanInfo(planInfo).Result;
                        if (result)
                        {
                            //更新前端展示图表
                            RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                            RefreshChatEvent?.Invoke();//刷新图表
                        }
                        #endregion
                        //读取设备进度,完成后再次下发新任务
                        ReadDeviceComplate_SidePanel(obj_sidePanel);
                        if (!isFlag)
                        {
                            //更新前端展示图表
                            RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                            RefreshChatEvent?.Invoke();//刷新图表
                        }
                    }
                });
                //背板
                Task.Run(() =>
                {
                    if (obj_backPanel != null)
                    {
                        //计划编号10个字:D6000-D6009、物料编号10个字:D6010-D6019、计划数量1个字:D6020、应答字1个字D6021
                        obj_backPanel.plc.WriteString("D4000", planInfo.TaskCode);
                        string processNumber = GetProcessNumberBy(planInfo.MaterialCode);
                        obj_backPanel.plc.WriteString("D4010", "BCD/310NF");
                        obj_backPanel.plc.WriteInt32("D4020", planInfo.PlanAmount);
                        obj_backPanel.plc.WriteInt32("D4021", 1);

                        Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待背板设备应答。。。。。。");
                        RefreshExecInfoEvent?.Invoke($"等待背板设备应答。。。。。。", "White");
                        #region PLC反馈信号逻辑处理
                        //循环读取PLC应答信号,PLC应答后复位应答信号、更新计划状态为执行中
                        bool isFlag = true;
                        do
                        {
                            if (obj_backPanel.plc.ReadInt32("D4021") == 2)
                            {
                                obj_backPanel.plc.WriteInt32("D4021", 0);
                                Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>收到背板板设备应答信号,复位应答地址");
                                RefreshExecInfoEvent?.Invoke("收到背板板设备应答信号,复位应答地址", "White");
                                isFlag = false;
                            }
                            Thread.Sleep(2000);
                        } while (isFlag);

                        //更新计划状态为2执行中
                        planInfo.ExecuteStatus = 2;
                        bool result = _executePlanInfoServices.UpdateExecutePlanInfo(planInfo).Result;
                        if (result)
                        {
                            //更新前端展示图表
                            RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                            RefreshChatEvent?.Invoke();//刷新图表
                        }
                        #endregion

                        //读取设备进度,完成后再次下发新任务
                        ReadDeviceComplate_BackPanel(obj_backPanel);
                        if (!isFlag)
                        {
                            //更新前端展示图表
                            RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                            RefreshChatEvent?.Invoke();//刷新图表
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine($"前板⽣产计划下发异常:{ex.Message}");
                RefreshExecInfoEvent?.Invoke($"前板⽣产计划下发异常:{ex.Message}", "Red");
            }
        }


        /// <summary>
        /// 下发前板生产计划
        /// </summary>
        /// <param name="planInfo"></param>
        /// <param name="obj"></param>
        public void SendPlanTask_SidePanel(ExecutePlanInfo planInfo, PlcModel obj_sidePanel)
        {
            try
            {
                Task.Run(() =>
                {
                    if (obj_sidePanel != null)
                    {
                        //计划编号10个字:D6000-D6009、物料编号10个字:D6010-D6019、计划数量1个字:D6020、应答字1个字D6021
                        obj_sidePanel.plc.WriteString("D6000", planInfo.TaskCode);
                        string processNumber = GetProcessNumberBy(planInfo.MaterialCode);
                        obj_sidePanel.plc.WriteString("D6010", planInfo.MaterialSpecificatons);
                        obj_sidePanel.plc.WriteInt32("D6020", planInfo.PlanAmount);
                        obj_sidePanel.plc.WriteInt32("D6021", 1);

                        Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待前板设备应答。。。。。。");
                        RefreshExecInfoEvent?.Invoke("等待前板设备应答......", "White");
                        //下发完成后读取PLC应答,应答后复位应答信号

                        #region PLC反馈信号逻辑处理
                        //循环读取PLC应答信号,PLC应答后复位应答信号、更新计划状态为执行中
                        bool isFlag = true;
                        do
                        {
                            if (obj_sidePanel.plc.ReadInt32("D6021") == 2)
                            {
                                obj_sidePanel.plc.WriteInt32("D6021", 0);
                                Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>收到前板设备应答信号,复位应答地址");
                                RefreshExecInfoEvent?.Invoke("收到前板设备应答信号......", "White");
                                isFlag = false;
                            }
                            Thread.Sleep(2000);
                        } while (isFlag);

                        //更新计划状态为2执行中
                        planInfo.ExecuteStatus = 2;
                        bool result = _executePlanInfoServices.UpdateExecutePlanInfo(planInfo).Result;
                        if (result)
                        {
                            //更新前端展示图表
                            RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                            RefreshChatEvent?.Invoke();//刷新图表
                            RefreshCurrentPlanInfoEvent?.Invoke();
                        }

                        #endregion
                        //读取设备进度,完成后再次下发新任务
                        ReadDeviceComplate_SidePanel(obj_sidePanel);
                        if (!isFlag)
                        {
                            //更新前端展示图表
                            RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                            RefreshChatEvent?.Invoke();//刷新图表
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine($"前板⽣产计划下发异常:{ex.Message}");
                RefreshExecInfoEvent?.Invoke($"前板⽣产计划下发异常:{ex.Message}", "Red");
            }
        }

        /// <summary>
        /// 读取前板生产数据
        /// </summary>
        /// <param name="obj"></param>
        public async void ReadDeviceComplate_SidePanel(PlcModel obj)
        {
            bool isFlag = true;


            do
            {
                try
                {
                    //D6030
                    //计划编号:D6030-D6039,物料编号:D6040-D6049,计划完成数:D6050,计划下线数:D6051,设备状态:D6052-D6056,生产节拍:D6057-D6058
                    byte[] info = obj.plc.Read("D6030", 59);

                    if (info == null)
                    {
                        Thread.Sleep(1000);
                        continue;
                    }

                    //计划编号
                    string planCode = Encoding.ASCII.GetString(info.Skip(0).Take(20).ToArray());
                    //物料编号
                    string materialCode = Encoding.ASCII.GetString(info.Skip(20).Take(20).ToArray());
                    //完成数量
                    int complateAmount = short.Parse(bytesToHexStr(info.Skip(40).Take(1).ToArray(), 1), System.Globalization.NumberStyles.HexNumber);
                    //下线数量
                    int offLineAmount = short.Parse(bytesToHexStr(info.Skip(41).Take(2).ToArray(), 2), System.Globalization.NumberStyles.HexNumber);
                    //设备状态
                    int deviceStatus = short.Parse(bytesToHexStr(info.Skip(43).Take(2).ToArray(), 2), System.Globalization.NumberStyles.HexNumber);
                    //生产节拍
                    int productionBeat = short.Parse(bytesToHexStr(info.Skip(51).Take(4).ToArray(), 4), System.Globalization.NumberStyles.HexNumber);

                    Console.WriteLine($"前板设备数据读取====>>>>当前计划:{planCode},物料编号:{materialCode},完成数量:{complateAmount},下线数量:{offLineAmount},设备状态:{deviceStatus},生产节拍:{productionBeat}");
                    RefreshExecInfoEvent?.Invoke($"前板设备数据读取====>>>>当前计划:{planCode},物料编号:{materialCode},完成数量:{complateAmount},下线数量:{offLineAmount},设备状态:{deviceStatus},生产节拍:{productionBeat}", "White");

                    //添加完工记录
                    RecordSidePanelComplate sidePanelComplate = new RecordSidePanelComplate()
                    {
                        ProductlineCode = "1001",
                        PlanCode = planCode.Substring(0, 16),
                        //MaterialCode = string.IsNullOrEmpty(materialCode) ? "" : materialCode,
                        MaterialCode = materialCode.Replace("\0", "").Trim(),//"BCD/310NF",
                        CompleteAmount = complateAmount,
                        OffLineAmount = offLineAmount,
                        DeviceStatus = deviceStatus,
                        ProductionBeat = productionBeat,
                        RecordTime = DateTime.Now,
                        IsFlag = 1
                    };

                    if (string.IsNullOrEmpty(planCode))
                    {
                        Thread.Sleep(5000);
                        continue;
                    }

                    //先查询该计划编号下的前一条完工记录,如果不存在本条记录产量为0
                    List<RecordSidePanelComplate> sidePanelComplates = _sidePanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planCode.Substring(0, 16));
                    int lastComplateAmount = 0; //前一条完成记录的计划完成数量
                    int sumComplateAmount = 0; //当前计划总产量
                    if (sidePanelComplates != null)
                    {
                        if (sidePanelComplates.Count > 0)
                        {
                            sidePanelComplates = sidePanelComplates.OrderByDescending(x => x.RecordTime).ToList();

                            lastComplateAmount = sidePanelComplates.First().CompleteAmount;
                            sidePanelComplate.OutPutAmount = complateAmount - lastComplateAmount;
                            sumComplateAmount = sidePanelComplates.Sum(x => x.OutPutAmount) + sidePanelComplate.OutPutAmount;

                            if (sidePanelComplate.OutPutAmount == 0)
                            {
                                Thread.Sleep(5000);
                                continue;
                            }
                            else
                            {
                                List<ExecutePlanInfo> planInfos = _executePlanInfoServices.Query(x => x.TaskCode.Equals(planCode.Substring(0, 16)) && x.ExecuteStatus == 2);
                                if (planInfos != null)
                                {
                                    if (planInfos.Count > 0)
                                    {
                                        ExecutePlanInfo planInfo = planInfos.First();
                                        if (planInfo != null)
                                        {
                                            if (planInfo.PlanAmount - sumComplateAmount == 0)
                                            {
                                                isFlag = false;
                                                Console.WriteLine($"前板计划执行完成,计划数量:{planInfo.PlanAmount};实际产量:{sumComplateAmount};差异值:{planInfo.PlanAmount - sumComplateAmount}");
                                                RefreshExecInfoEvent?.Invoke($"前板计划执行完成,计划数量:{planInfo.PlanAmount};实际产量:{sumComplateAmount};差异值:{planInfo.PlanAmount - sumComplateAmount}", "White");
                                            }
                                        }
                                    }

                                }
                            }
                        }
                    }

                    _sidePanelComplateServices.InsertSidePanelCimplate(sidePanelComplate);

                    if (complateAmount != lastComplateAmount)
                    {
                        //更新前端展示图表
                        RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                        RefreshChatEvent?.Invoke();//刷新图表
                        RefreshCreatePlanInfoEvent?.Invoke();
                        var planInfoList = await _executePlanInfoServices.QuerySheetMetalSendPlanData("1001");
                        if (planInfoList != null && planInfoList.Count != 0)
                        {
                            SheetMetaSendPlanInfoView planInfo = planInfoList.FirstOrDefault(d => d.TaskCode == planCode.Replace("\0", "").Trim());
                            RefreshPlanInfoEvent?.Invoke(planInfo);//刷新计划执行
                        }
                    }
                    Thread.Sleep(5000);
                }
                catch (Exception e)
                {
                    Console.WriteLine($"读取前板设备完成数据异常:{e.Message}");
                    RefreshExecInfoEvent?.Invoke($"读取前板设备完成数据异常:{e.Message}", "Red");
                }
            } while (isFlag);

            if (!isFlag)
            {
                //更新前端展示图表
                RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                RefreshChatEvent?.Invoke();//刷新图表

            }

        }



        /// <summary>
        /// 下发背板生产计划
        /// </summary>
        /// <param name="planInfo"></param>
        /// <param name="obj"></param>
        public void SendPlanTaskTo_BackPanel(ExecutePlanInfo planInfo, PlcModel obj_backPanel)
        {
            try
            {
                Task.Run(() =>
                {
                    if (obj_backPanel != null)
                    {
                        //计划编号10个字:D6000-D6009、物料编号10个字:D6010-D6019、计划数量1个字:D6020、应答字1个字D6021
                        obj_backPanel.plc.WriteString("D4000", planInfo.TaskCode);
                        string processNumber = GetProcessNumberBy(planInfo.MaterialCode);
                        obj_backPanel.plc.WriteString("D4010", planInfo.MaterialSpecificatons);
                        obj_backPanel.plc.WriteInt32("D4020", planInfo.PlanAmount);
                        obj_backPanel.plc.WriteInt32("D4021", 1);

                        Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>等待背板设备应答。。。。。。");
                        RefreshExecInfoEvent?.Invoke($"等待背板设备应答。。。。。。", "White");
                        #region PLC反馈信号逻辑处理
                        //循环读取PLC应答信号,PLC应答后复位应答信号、更新计划状态为执行中
                        bool isFlag = true;
                        do
                        {

                            if (obj_backPanel.plc.ReadInt32("D4021") == 2)
                            {
                                obj_backPanel.plc.WriteInt32("D4021", 0);
                                Console.WriteLine($"{DateTime.Now.ToString("HH:m:s")}===>收到背板板设备应答信号,复位应答地址");
                                RefreshExecInfoEvent?.Invoke($"收到背板板设备应答信号,复位应答地址", "White");
                                isFlag = false;
                            }
                            Thread.Sleep(2000);
                        } while (isFlag);

                        //更新计划状态为2执行中
                        planInfo.ExecuteStatus = 2;
                        bool result = _executePlanInfoServices.UpdateExecutePlanInfo(planInfo).Result;
                        if (result)
                        {
                            //更新前端展示图表
                            RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                            RefreshChatEvent?.Invoke();//刷新图表
                        }

                        #endregion

                        //读取设备进度,完成后再次下发新任务
                        ReadDeviceComplate_BackPanel(obj_backPanel);

                        if (!isFlag)
                        {
                            //更新前端展示图表
                            RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                            RefreshChatEvent?.Invoke();//刷新图表
                        }
                    }
                });
            }
            catch (Exception ex)
            {
                Console.WriteLine($"读取前板设备完成数据异常:{ex.Message}");
                RefreshExecInfoEvent?.Invoke($"背板⽣产计划下发异常:{ex.Message}", "Red");
            }
        }

        /// <summary>
        /// 读取背板生产数据
        /// </summary>
        /// <param name="obj"></param>
        public void ReadDeviceComplate_BackPanel(PlcModel obj)
        {
            bool isFlag = true;

            try
            {
                do
                {
                    //计划编号:D6030-D6039,物料编号:D6040-D6049,计划完成数:D6050,计划下线数:D6051,设备状态:D6052-D6056,生产节拍:D6057-D6058
                    byte[] info = obj.plc.Read("D4030", 59);

                    if (info == null)
                    {
                        Thread.Sleep(1000);
                        continue;
                    }

                    //计划编号
                    string planCode = Encoding.ASCII.GetString(info.Skip(0).Take(20).ToArray()).Replace("\0", "").Trim();
                    //物料编号
                    string materialCode = Encoding.ASCII.GetString(info.Skip(20).Take(20).ToArray()).Replace("\0", "").Trim();
                    //完成数量
                    int complateAmount = short.Parse(bytesToHexStr(info.Skip(40).Take(1).ToArray(), 1), System.Globalization.NumberStyles.HexNumber);
                    //下线数量
                    int offLineAmount = short.Parse(bytesToHexStr(info.Skip(41).Take(2).ToArray(), 2), System.Globalization.NumberStyles.HexNumber);
                    //设备状态
                    int deviceStatus = short.Parse(bytesToHexStr(info.Skip(43).Take(2).ToArray(), 2), System.Globalization.NumberStyles.HexNumber);
                    //生产节拍
                    int productionBeat = short.Parse(bytesToHexStr(info.Skip(51).Take(4).ToArray(), 4), System.Globalization.NumberStyles.HexNumber);

                    Console.WriteLine($"背板设备数据读取====>>>>当前计划:{planCode},物料编号:{materialCode},完成数量:{complateAmount},下线数量:{offLineAmount},设备状态:{deviceStatus},生产节拍:{productionBeat}");
                    RefreshExecInfoEvent?.Invoke($"当前计划:{planCode},物料编号:{materialCode},完成数量:{complateAmount},下线数量:{offLineAmount},设备状态:{deviceStatus},生产节拍:{productionBeat}", "White");
                    //添加完工记录
                    RecordBackPanelComplate backPanelComplate = new RecordBackPanelComplate()
                    {
                        ProductlineCode = "1001",
                        PlanCode = planCode.Replace("\0", "").Trim(),
                        MaterialCode = string.IsNullOrEmpty(materialCode) ? "" : materialCode.Replace("\0", "").Trim(),
                        //MaterialCode = materialCode.Replace("\0", "").Trim(),//"BCD/310NF",
                        CompleteAmount = complateAmount,
                        OffLineAmount = offLineAmount,
                        DeviceStatus = deviceStatus,
                        ProductionBeat = productionBeat,
                        RecordTime = DateTime.Now,
                        IsFlag = 1
                    };

                    if (string.IsNullOrEmpty(planCode))
                    {
                        Thread.Sleep(5000);
                        continue;
                    }

                    //先查询该计划编号下的前一条完工记录,如果不存在本条记录产量为0
                    List<RecordBackPanelComplate> backPanelComplates = _backPanelComplateServices.Query(x => x.ProductlineCode == "1001" && x.PlanCode == planCode.Substring(0, 16));
                    int lastComplateAmount = 0; //前一条完成记录的计划完成数量
                    int sumComplateAmount = 0; //当前计划总产量
                    if (backPanelComplates != null)
                    {
                        if (backPanelComplates.Count > 0)
                        {
                            backPanelComplates = backPanelComplates.OrderByDescending(x => x.RecordTime).ToList();

                            lastComplateAmount = backPanelComplates.First().CompleteAmount;
                            backPanelComplate.OutPutAmount = complateAmount - lastComplateAmount;
                            sumComplateAmount = backPanelComplates.Sum(x => x.OutPutAmount) + backPanelComplate.OutPutAmount;
                            if (backPanelComplate.OutPutAmount == 0)
                            {
                                Thread.Sleep(5000);
                                continue;
                            }
                            else
                            {
                                List<ExecutePlanInfo> planInfos = _executePlanInfoServices.Query(x => x.TaskCode == planCode && x.ExecuteStatus == 2);
                                if (planInfos != null)
                                {
                                    if (planInfos.Count > 0)
                                    {
                                        ExecutePlanInfo planInfo = planInfos.First();
                                        if (planInfo != null)
                                        {
                                            if (planInfo.PlanAmount - sumComplateAmount == 0)
                                            {
                                                isFlag = false;
                                                Console.WriteLine($"背板计划执行完成,计划数量:{planInfo.PlanAmount};实际产量:{sumComplateAmount};差异值:{planInfo.PlanAmount - sumComplateAmount}");
                                                RefreshExecInfoEvent?.Invoke($"背板计划执行完成,计划数量:{planInfo.PlanAmount};实际产量:{sumComplateAmount};差异值:{planInfo.PlanAmount - sumComplateAmount}", "White");
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    _backPanelComplateServices.InsertBackPanelCimplate(backPanelComplate);
                    if (complateAmount != lastComplateAmount)
                    {
                        //更新前端展示图表
                        RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                        RefreshChatEvent?.Invoke();//刷新图表
                    }
                    Thread.Sleep(5000);
                } while (isFlag);

                if (!isFlag)
                {
                    //更新前端展示图表
                    RefreshCreatePlanInfoEvent?.Invoke();//更新界面
                    RefreshChatEvent?.Invoke();//刷新图表
                }
            }
            catch (Exception e)
            {
                Console.WriteLine($"读取背板设备完成数据异常:{e.Message}");
                RefreshExecInfoEvent?.Invoke($"背板⽣产计划下发异常:{e.Message}", "Red");
            }
        }



        /// <summary>
        /// 通过物料编号获取工艺编号
        /// </summary>
        /// <param name="materialCode"></param>
        /// <returns></returns>
        private string GetProcessNumberBy(string materialCode)
        {
            return System.Guid.NewGuid().ToString("N").Substring(0, 20);
        }

        public static string bytesToHexStr(byte[] bytes, int iLen)//e.g. { 0x01, 0x01} ---> " 01 01"
        {
            string returnStr = "";
            if (bytes != null)
            {
                for (int i = 0; i < iLen; i++)
                {
                    returnStr += bytes[i].ToString("X2");
                }
            }
            return returnStr;
        }
        #endregion

        #region 更新计划列表数量
        /// <summary>
        /// 更新计划列表数量
        /// </summary>
        public void UpdateComplatePlan()
        {
            string stationCode = Appsettings.app("StationInfo", "StationCode");
            string productLineCode = Appsettings.app("StationInfo", "ProductLineCode");
            List<ProductPlanInfo> pPlanInfoList = new List<ProductPlanInfo>();
            while (true)
            {
                var planInfoList = _executePlanInfoServices.QueryAsync(d => d.ProductLineCode.Contains(stationCode)).Result;
                if (planInfoList == null || planInfoList.Count == 0) continue;

                var list = from d in planInfoList
                           select new
                           {
                               d.OrderCode,
                               d.CompleteAmount
                           };

                var grouplist = (from d in list
                                 group d by d.OrderCode into g
                                 select new
                                 {
                                     OrderCode = g.Key,
                                     CompleteAmount = g.Sum(d => d.CompleteAmount)
                                 }).OrderBy(t => t.OrderCode).ToList();

                var productPlanInfoList = _productPlanInfoServices.QueryAsync(d => d.ProductLineCode.Contains(stationCode) && d.CompleteAmount != d.PlanAmount).Result;


                productPlanInfoList.ForEach(async t =>
                {
                    var materialCompletionList = _materialCompletionServices.QueryAsync(d => d.ProductLineCode.Contains(productLineCode) && d.StationName.Equals(stationCode)).Result;
                    var obj = grouplist.FirstOrDefault(d => d.OrderCode.Equals(t.OrderCode));

                    if (obj != null)
                    {
                        ProductPlanInfo productPlanInfo = new ProductPlanInfo();

                        if (obj.CompleteAmount == 1 && t.CompleteAmount == 0)
                        {
                            productPlanInfo.EndTime = DateTime.Now;
                            _sysUserInfoServices.UpdateSapPlan(obj.OrderCode);//第一次执行更新日历表
                        }
                        if (t.PlanAmount == obj.CompleteAmount)
                        {
                            productPlanInfo.CompleteAmount = obj.CompleteAmount;
                            productPlanInfo.EndTime = DateTime.Now;
                        }
                        if (t.PlanAmount > obj.CompleteAmount)
                        {
                            productPlanInfo.CompleteAmount = obj.CompleteAmount;
                        }
                        else
                        {
                            productPlanInfo.CompleteAmount = t.PlanAmount;
                        }
                        int completeNum = materialCompletionList.Count();//过点完成数量
                        if ((obj.CompleteAmount - completeNum) > 0)
                        {
                            MaterialCompletion materialCompletion = new MaterialCompletion();
                            materialCompletion.OrderCode = t.OrderCode;
                            materialCompletion.ProductLineCode = productLineCode;
                            materialCompletion.MaterialCode = t.MaterialCode;
                            materialCompletion.MaterialName = t.MaterialName;
                            materialCompletion.StationName = stationCode;
                            materialCompletion.CompleteDate = DateTime.Now;
                            materialCompletion.planCode = t.PlanCode;
                            await _materialCompletionServices.AddAsync(materialCompletion);
                        }
                    }
                });
                if (pPlanInfoList.Count != 0 && pPlanInfoList != null)
                {
                    _productPlanInfoServices.UpdateAsync(pPlanInfoList);
                }
                Thread.Sleep(3000);
            }
        }

        #endregion

    }
}