using MaterialTraceability.Common;
using MaterialTraceability.Entity.DAO;
using MaterialTraceability.Entity.DTO;
using MaterialTraceability.Entity.Enum;
using MaterialTraceability.Entity.UpLoad;
using MaterialTraceability.SqlSugar;
using MaterialTraceability.SqlSugar.ServiceImpl;
using MaterialTraceability.WebService;
using MaterialTraceability.WebService.GetParametricValueServiceService;
using MaterialTraceability.WebService.MachineIntegrationServiceService;
using MaterialTraceability.WebService.MiBatchCompleteSfcAndAdujustQtyServiceService;
using MaterialTraceability.WebService.MiFirstOperationForsfcServiceService;
using MaterialTraceability.WebService.MiReleaseSfcWithActivityServiceService;
using MaterialTraceability.WebService.Param;
using MaterialTraceability.WebService.ProcessLotServiceWSService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MaterialTraceability.Business.Impl
{
    public class ABSignalReadBusiness : ISignalReadFunction
    {
        /// <summary>
        /// INIFile配置文件
        /// </summary>
        private INIFile inifile = new INIFile(System.Environment.CurrentDirectory + "/MesConfig/App.InI");
        private AppConfigDto appConfig = AppConfigDto.Instance;
        /// <summary>
        /// 日志刷新
        /// </summary>
        /// <param name="type">日志内容</param>
        /// <param name="massage"></param>
        public delegate void LogRefresh(LogType logType, string massage);
        public static event LogRefresh LogRefreshEvent;

        /// <summary>
        /// 视图层数据刷新
        /// </summary>
        /// <param name="viewModelDto"></param>
        public delegate void ViewModelRefresh(ViewModelDto viewModelDto);
        public static event ViewModelRefresh ViewModelRefreshEvent;

        /// <summary>
        /// PLC信号事件
        /// </summary>
        /// <param name="status"></param>
        /// <param name="position"></param>
        public delegate void SignalReadInvoke(int status, int position);

        /// <summary>
        /// RFID读写器业务
        /// </summary>
        private EquipBusiness equipBusiness = new EquipBusiness();

        /// <summary>
        /// Mes WebService接口
        /// </summary>
        private IMesWebServices MesWebServices = new MesWebServicesImpl();

        //卷轴信息
        private IBaseServices<ProShaftInfo> shaftInfoServices = new BaseServices<ProShaftInfo>();

        //收卷记录
        private IBaseServices<ProDownRecord> downRecordServices = new BaseServices<ProDownRecord>();

        //上料记录
        private IBaseServices<ProUpRecord> upRecordServices = new BaseServices<ProUpRecord>();

        private IBaseServices<SysClient> sysClientServices = new BaseServices<SysClient>();

        private MesAlarmInfo mesAlarmInfo = new MesAlarmInfo();

        private PlcBusiness plcBusiness = new PlcBusiness();

        private UpLoadBusiness upLoadBusiness = UpLoadBusiness.Instance;

        ///add by yinzf
        /// <summary>
        /// 放卷开始
        /// </summary>
        /// <param name="position"></param>
        public void UpBegin(int position)
        {
            //禁止下料
            LogHelper.Info("放卷开始,下发禁止下料信号");
            LogRefreshEvent?.Invoke(LogType.PlcLog, "放卷开始,下发禁止下料信号");
            sendError(position);
        }
        //end add
        /// <summary>
        /// 放卷涨紧
        /// </summary>
        /// <param name="position"></param>
        public void UpMaterialBegin(int position)
        {
            try
            {
                #region 未登录不让放卷涨紧生产,便于记录生产者
                /*if (StringExtension.IsBlank(ConfigHelper.GetConfig("roleId")))
                {
                    MessageBox.Show("请先登录再开始生产");
                    LogHelper.Info("请先登录再开始生产");
                    LogRefreshEvent?.Invoke(LogType.AlarmLog, "请先登录再开始生产");
                    
                    return;
                }*/
                #endregion

                LogRefreshEvent?.Invoke(LogType.PlcLog, "凹版放卷位涨紧信号触发成功");
                LogRefreshEvent?.Invoke(LogType.RfidLog, "凹版放卷位涨紧信号触发成功");
                LogHelper.Info("凹版放卷位涨紧信号触发成功");

                //读取卷筒RFID物料信息
                ProEquip proEquip = equipBusiness.Equiplist.Where(x => x.positionId == position).FirstOrDefault();
                if (proEquip == null)
                {
                    LogRefreshEvent?.Invoke(LogType.AlarmLog, "获取放卷位读写器设备信息异常");
                    return;
                }
                string epc = equipBusiness.ReadEPCByAntana(proEquip.equipId);
                epc = epc.Replace("\0", "").Trim();
                //add by CaesarBao 这里需要截取标签
                if (epc == "" || epc == null)
                {
                    Random random = new Random();

                    epc = "JSLY4RDA0000" + random.Next(10, 99);
                }
                //SaveReadRecord(proEquip, epc);
                if (StringExtension.IsBlank(epc))
                {
                    plcBusiness.writePlc(appConfig.AbAddress.RFID异常, 1);
                    LogHelper.Info("放卷位RFID条码信息读取失败,下发PLC报警D6024写1");
                    LogRefreshEvent?.Invoke(LogType.AlarmLog, "放卷位RFID条码信息读取失败");
                    ViewModelRefreshEvent?.Invoke(new ViewModelDto()
                    {
                        rfidInfo = new RfidInfoDto()
                        {
                            rfid = "",
                            sfc = "",
                            ea = "",
                            position = position,
                        },
                        plcStatus = true,
                    });
                    return;
                }
                LogHelper.Info(String.Format("放卷位RFID条码信息读取成功:{0}", epc));
                LogRefreshEvent?.Invoke(LogType.RfidLog, String.Format("放卷位RFID条码信息读取成功,RFID为{0}", epc));
                //判断RFID标签是否重复
                LogHelper.Info("判断RFID标签是否重复");
                if (BusinessHelper.UpRfidIsRecur(epc, position).Result)
                {

                    //判断是否已经生产结束
                    if (UpMaterialIsEndProduction(epc).Result)
                    {
                        plcBusiness.writePlc(appConfig.AbAddress.RFID异常, 1);
                        LogRefreshEvent?.Invoke(LogType.AlarmLog, String.Format("当前读取的RFID:{0},已经生产结束不允许再次上料", epc));
                        LogHelper.Info(String.Format("当前读取的RFID:{0},已经生产结束不允许再次上料", epc));
                        return;
                    }
                    else
                    {
                        Expression<Func<ProUpRecord, bool>> exp = s1 => true;
                        Expression<Func<ProUpRecord, object>> order = (x) => x.RecordTime;
                        ProUpRecord upRecord = upRecordServices.QueryFirst(exp, order, false).Result;
                        if (upRecord != null)
                        {
                            PlcBusiness.writeStrPlc(appConfig.AbAddress.放卷SFC, upRecord.Sfc);
                            ViewModelRefreshEvent?.Invoke(new ViewModelDto()
                            {
                                rfidInfo = new RfidInfoDto()
                                {
                                    rfid = epc,
                                    sfc = upRecord.Sfc,
                                    position = position,
                                },
                                plcStatus = true,
                            });
                        }
                        LogHelper.Info("放卷位RFID读取到的条码:" + epc + "与前一读取相同并且生产未结束,可以继续生产");
                        LogRefreshEvent?.Invoke(LogType.RfidLog, "放卷位RFID读取到的条码:" + epc + "与前一读取相同并且生产未结束,可以继续生产");
                        return;
                    }
                }
                //读取数据刷新
                ViewModelRefreshEvent?.Invoke(new ViewModelDto()
                {
                    rfidInfo = new RfidInfoDto()
                    {
                        rfid = epc,
                        //sfc = "",
                        position = position,
                    },
                    plcStatus = true,
                });
                FJMesBegin(position, epc, true);
            }
            catch (Exception ex)
            {
                LogHelper.Error("凹版放卷涨紧逻辑处理异常", ex);
                LogRefreshEvent?.Invoke(LogType.AlarmLog, "凹版放卷涨紧逻辑处理异常" + ex.Message);

            }
        }

        /// <summary>
        /// 放卷结束
        /// </summary>
        /// <param name="position"></param>
        public async void UpMaterialEnd(int position)
        {
            try
            {
                LogRefreshEvent?.Invoke(LogType.PlcLog, "凹版放卷位结束信号触发成功");
                LogRefreshEvent?.Invoke(LogType.RfidLog, "凹版放卷位结束信号触发成功");
                LogHelper.Info("凹版放卷位结束信号触发成功");

                ProShaftInfo shaftInfo = await this.GetShaftInfoByPosition(position);
                if (shaftInfo == null)
                {
                    LogRefreshEvent?.Invoke(LogType.RfidLog, "放卷结束,获取卷轴绑定的信息为空");
                    return;
                }
                Expression<Func<ProUpRecord, bool>> upExp = s1 => true;
                upExp = upExp.And(x => x.Sfc == shaftInfo.bindSfc && x.Rfid == shaftInfo.bindRfid && x.IsProduction == 0);
                Expression<Func<ProUpRecord, object>> upOrder = (x) => x.RecordTime;
                ProUpRecord upRecord = await upRecordServices.QueryFirst(upExp, upOrder, false);
                if (upRecord == null)
                {
                    LogRefreshEvent?.Invoke(LogType.AlarmLog, "放卷结束,获取上料信息为空");
                    return;
                }

                //更新放卷信息
                upRecord.endTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                upRecord.IsProduction = 1;
                upRecord.isFinish = 1;
                await upRecordServices.Update(upRecord);
                LogRefreshEvent?.Invoke(LogType.RfidLog, "生成放卷信息");
                //放卷结束允许下料
                sendSuccess(position);
                //upLoadBusiness.UpdateUpRecord(upRecord);
            }
            catch (Exception ex)
            {
                LogHelper.Error("凹版放卷位结束逻辑处理异常", ex);
                LogRefreshEvent?.Invoke(LogType.AlarmLog, "凹版放卷位结束逻辑处理异常" + ex.Message);
            }
        }

        /// <summary>
        /// 收卷涨紧
        /// </summary>
        /// <param name="position"></param>
        public async void DownMaterialBegin(int position)
        {
            #region 参数定义
            List<ProEquip> proEquips = new List<ProEquip>();
            List<string> tagInfoList = new List<string>();
            #endregion
            try
            {
                LogRefreshEvent?.Invoke(LogType.PlcLog, "收卷位涨紧信号触发成功");
                LogRefreshEvent?.Invoke(LogType.RfidLog, "收卷位涨紧信号触发成功");
                LogHelper.Info("收卷位涨紧信号触发成功");

                //if (StringExtension.IsBlank(PlcBusiness.readStrPlc(appConfig.AbAddress.放卷SFC, 32)))
                //{
                //    LogRefreshEvent?.Invoke(LogType.AlarmLog, "放卷位物料信息为空,先触发放卷位物料信息");
                //    return;
                //}

                LogRefreshEvent?.Invoke(LogType.RfidLog, String.Format("开始读取收卷轴RFID物料信息"));
                ProEquip proEquip = equipBusiness.Equiplist.Where(x => x.positionId == position).FirstOrDefault();
                if (proEquip == null)
                {
                    LogRefreshEvent?.Invoke(LogType.RfidLog, "获取收卷轴读写器设备信息异常");
                    return;
                }
                string epc = equipBusiness.ReadEPCByAntana(proEquip.equipId);
                epc = epc.Replace("\0", "").Trim();

                //add by CaesarBao 这里需要截取标签
                if (epc == "" || epc == null)
                {
                    Random random = new Random();

                    epc = "JSLY4RDA0000" + random.Next(10, 99);
                }
                if (StringExtension.IsBlank(epc))
                {
                    LogHelper.Info("收卷读取RFID条码信息失败");
                    LogRefreshEvent?.Invoke(LogType.AlarmLog,"收卷读取RFID条码信息失败");
                    sendError(position, 2, false, 1);
                    ViewModelRefreshEvent?.Invoke(new ViewModelDto()
                    {
                        rfidInfo = new RfidInfoDto()
                        {
                            rfid = "",
                            sfc = "",
                            ea = "",
                            position = position,
                        },
                        plcStatus = true,
                    });
                }
                LogHelper.Info("收卷位设备:" + proEquip.equipIp + "涨紧信号读取成功:" + epc);

                LogRefreshEvent?.Invoke(LogType.RfidLog,"收卷RFID条码信息读取成功:" + epc);

                lock (string.Empty)
                {
                    LogHelper.Info("判断RFID标签是否重复");

                    if (BusinessHelper.DownRfidIsRecur(epc, position).Result)
                    {
                        LogHelper.Info("收卷RFID读取到的条码:" + epc + "与前一读取相同不做MES处理");

                        LogRefreshEvent?.Invoke(LogType.RfidLog, "收卷RFID读取到的条码:" + epc + "与前一读取相同不做MES处理");
                        LogRefreshEvent?.Invoke(LogType.AlarmLog, "收卷RFID读取到的条码:" + epc + "与前一读取相同不做MES处理");
                        //plcBusiness.writePlc(appConfig.AbAddress.是否转塔, 1);
                        return;
                    }

                    SJMesBegin(position, epc, true);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Error("凹版收卷涨紧信号逻辑处理异常", ex);
                LogRefreshEvent?.Invoke(LogType.AlarmLog, "凹版收卷涨紧信号逻辑处理异常" + ex.Message);
            }
            finally
            {
                tagInfoList = new List<string>();
            }
        }

        /// <summary>
        /// 收卷结束
        /// </summary>
        /// <param name="position"></param>
        public async void DownMaterialEnd(int position)
        {
            #region 参数定义
            List<ProShaftInfo> shaftInfos = new List<ProShaftInfo>();
           
            string logStr = Which(position);
            #endregion
            try
            {
                LogRefreshEvent?.Invoke(LogType.PlcLog, logStr + "收卷结束信号触发成功");
                LogRefreshEvent?.Invoke(LogType.RfidLog, logStr + "收卷结束信号触发成功");
                LogHelper.Info(logStr + "收卷结束信号触发成功");
                //获取收卷轴绑定的RFID条码信息,取最新数据
                Expression<Func<ProShaftInfo, bool>> exp = s1 => true;
                exp = exp.And(x => x.positionId == position.ToString() && x.processId == appConfig.processId);
                Expression<Func<ProShaftInfo, object>> order = (x) => x.bindTime;
                ProShaftInfo shaftInfo = await shaftInfoServices.QueryFirst(exp, order, false);


                LogRefreshEvent?.Invoke(LogType.RfidLog, "PLC获取的最终SFC为:" + shaftInfo.bindSfc);
                if (StringExtension.IsBlank(shaftInfo.bindSfc))
                {
                    LogRefreshEvent?.Invoke(LogType.AlarmLog, String.Format("{0}收卷完工获取卷轴绑定的SFC为空不进入结束流程", logStr));
                    LogRefreshEvent?.Invoke(LogType.RfidLog, String.Format("{0}收卷完工获取卷轴绑定的SFC为空不进入结束流程", logStr));
                    LogHelper.Info(String.Format("{0}收卷完工获取卷轴绑定的SFC为空不进入结束流程", logStr));
                    //下发PLC下料信号
                    this.sendSuccess(position);
                    return;
                }

                Expression<Func<ProDownRecord, bool>> down = s1 => true;
                down = down.And(z => z.Rfid == shaftInfo.bindRfid && z.IsProduction == 0);
                Expression<Func<ProDownRecord, object>> downorder = (s) => s.beginTime;
                ProDownRecord downRecord = await downRecordServices.QueryFirst(down, downorder, false);

                if (downRecord == null)
                {
                    LogRefreshEvent?.Invoke(LogType.AlarmLog, "收卷流程结束,获取下料信息异常");
                    LogHelper.Info("收卷流程结束,获取下料信息异常");
                    return;
                }
                //下发禁止下料
                sendError(position);
                //调用MES获取数量接口
                string upMaterialEaValue = GetUpMaterialQty(position, shaftInfo.bindSfc, logStr);
              
                if (StringExtension.IsBlank(upMaterialEaValue))
                {
                    LogRefreshEvent?.Invoke(LogType.MesLog, String.Format("通过MES获取收卷位{0}物料EA值为空", shaftInfo.bindSfc));
                    return;
                }
                downRecord.eaValue = int.Parse(upMaterialEaValue);
                LogRefreshEvent?.Invoke(LogType.RfidLog, "收卷位物料EA:" + upMaterialEaValue);
                if (!SpiltAccount(position, shaftInfo, downRecord.eaValue, shaftInfo.bindSfc, new ProUpRecord(), downRecord).Result)
                {
                    LogHelper.Info(logStr + "完工MES账目数量异常");

                    return;
                }
                //下料成功
                sendSuccess(position);

            }
            catch (Exception ex)
            {
                LogHelper.Error("凹版收卷结束信号逻辑处理异常", ex);
                LogRefreshEvent?.Invoke(LogType.AlarmLog, "凹版收卷结束信号逻辑处理异常" + ex.Message);
            }
        }

        /// <summary>
        /// 调整MES数量
        /// </summary>
        /// <param name="bindSfc"></param>
        /// <param name="bindRfid"></param>
        /// <param name="eaValue"></param>
        /// <returns></returns>
        private bool UpdateMesEaValue(int position,string bindSfc, string bindRfid, int eaValue)
        {
            //调取MES调整数量接口
            LogRefreshEvent?.Invoke(LogType.MesLog, "调用MES调整数量接口");
            MiBatchCompleteSfcAndAdujustQtyServiceServiceParam miBatchCompleteSfcAndAdujustQtyServiceServiceParam = new MiBatchCompleteSfcAndAdujustQtyServiceServiceParam()
            {
                url = inifile.IniReadValue("AdujustQtyParam","url"),
                site = inifile.IniReadValue("AdujustQtyParam", "site"),
                sfcPre = bindSfc,
                processLotPre = "",
                operation = appConfig.operationByA,
                operationRevision = inifile.IniReadValue("AdujustQtyParam", "operationRevision"),
                resource = appConfig.resource,
                user = inifile.IniReadValue("AdujustQtyParam", "user"),
                activity = inifile.IniReadValue("AdujustQtyParam", "activity"),
                modeProcessSfc = WebService.MiBatchCompleteSfcAndAdujustQtyServiceService.ModeProcessSfc.MODE_NONE,
                sfcList = new miBatchCompleteSfcAndAdujustQtySfcEntity[]
                {
                    new miBatchCompleteSfcAndAdujustQtySfcEntity()
                    {
                        processLot = bindRfid,
                        sfc = "",
                        qty =eaValue.ToString(),
                        unit = "EA"
                    }
                }
            };
            LogHelper.Info("调用MES接口调整物料" + bindSfc + "数量");
            LogHelper.Info("MES调整数量接口请求参数:" + JsonChange.ModeToJson(miBatchCompleteSfcAndAdujustQtyServiceServiceParam));

            if (appConfig.isMesFlag == 1)
            {
                var requestResult = MesWebServices.iMiBatchCompleteSfcAndAdujustQtyServiceService(miBatchCompleteSfcAndAdujustQtyServiceServiceParam);
                LogHelper.Info("MES调整数量接口返回参数:" + JsonChange.ModeToJson(requestResult));
                if (requestResult.@return.code > 0)
                {
                    LogHelper.Info("MES调整数量接口调用失败:" + requestResult.@return.message);
                    LogRefreshEvent?.Invoke(LogType.AlarmLog, "MES调整数量接口调用失败:" + upLoadBusiness.GetMesMessage(requestResult.@return.code, requestResult.@return.message));
                    plcBusiness.writePlc(appConfig.AbAddress.MES异常, requestResult.@return.code);
                    return false;
                }
            }
            LogRefreshEvent?.Invoke(LogType.MesLog, "MES调整数量接口调用成功");
            return true;
        }

        /// <summary>
        /// 通过MES获取拆分后绑定的SFC
        /// </summary>
        /// <param name="bindRfid"></param>
        /// <returns></returns>
        private string GetBindSfcByMes(string rfidStr)
        {
            string sfcStr = "";
            DateTime beginTime = new DateTime();
            ProcessLotServiceWSServiceParam processLotServiceWSServiceParam = new ProcessLotServiceWSServiceParam()
            {
                url = inifile.IniReadValue("ProcessLotServiceWSServiceParam", "url"),
                site = inifile.IniReadValue("ProcessLotServiceWSServiceParam", "site"),
                processlotref = String.Format("ProcessLotBO:2100,{0}", rfidStr)
            };

            try
            {
                LogRefreshEvent?.Invoke(LogType.MesLog, "调用MES接口获取RFID绑定的SFC");
                LogHelper.Info("MES获取膜卷号接口请求参数:" + JsonChange.ModeToJson(processLotServiceWSServiceParam));
                if (appConfig.isMesFlag == 1)
                {
                    readProcessLotResponse readProcessLotResponse = MesWebServices.readProcessLot(processLotServiceWSServiceParam);
                    LogHelper.Info("MES获取膜卷号接口返回参数:" + JsonChange.ModeToJson(readProcessLotResponse));
                    if (readProcessLotResponse.Response.processLotMemberList != null)
                    {
                        sfcStr = readProcessLotResponse.Response.processLotMemberList[0].memberContext.Substring(11);
                        LogHelper.Info("RFID条码:" + rfidStr + "绑定的SFC条码为:" + sfcStr);
                        LogRefreshEvent?.Invoke(LogType.MesLog, "RFID条码:" + rfidStr + "绑定的SFC条码为:" + sfcStr);
                    }
                }
                else
                {
                    sfcStr = System.Guid.NewGuid().ToString("N").Substring(0, 14);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Info("MES获取膜卷号接口调用异常:" + ex.Message);
                LogRefreshEvent?.Invoke(LogType.AlarmLog, "MES获取膜卷号接口调用异常:" + ex.Message);
                WebServiceLog.saveReadProcessLot(processLotServiceWSServiceParam, null, beginTime, ex.Message);
            }
            return sfcStr;
        }

        /// <summary>
        /// 获取放卷位EA值
        /// </summary>
        /// <param name="bindSfc"></param>
        /// <param name="logStr"></param>
        /// <returns></returns>
        private string GetUpMaterialQty(int position,string bindSfc, string logStr)
        {
            LogHelper.Info(logStr + "通过MES接口获取放卷物料的EA值");
            MiSFCQueryQtyServiceServiceParam sFCQueryQtyServiceServiceParam = new MiSFCQueryQtyServiceServiceParam()
            {
                url = inifile.IniReadValue("MiSFCQueryQtyServiceServiceParam", "url"),
                site = inifile.IniReadValue("MiSFCQueryQtyServiceServiceParam", "site"),
                sfc = bindSfc             
            };
            LogHelper.Info(logStr + "完工,MES获取物料EA值接口请求参数:" + JsonChange.ModeToJson(sFCQueryQtyServiceServiceParam));
            DateTime beginTime = DateTime.Now;
            try
            {
                if (appConfig.isMesFlag == 1)
                {
                    var sfcQueryQtyResponse = MesWebServices.iMiSFCQueryQtyServiceService(sFCQueryQtyServiceServiceParam);
                    LogHelper.Info(logStr + "MES获取物料EA值接口返回参数:" + JsonChange.ModeToJson(sfcQueryQtyResponse));

                    if (sfcQueryQtyResponse.@return.code > 0)
                    {
                        LogHelper.Info(logStr + "MES获取物料EA值接口请求失败:" + sfcQueryQtyResponse.@return.message);
                        LogRefreshEvent?.Invoke(LogType.MesLog, String.Format(logStr + "通过MES接口获取放卷物料{0}的SFC数量失败:{1}", bindSfc, upLoadBusiness.GetMesMessage(sfcQueryQtyResponse.@return.code, sfcQueryQtyResponse.@return.message)));
                        LogRefreshEvent?.Invoke(LogType.AlarmLog, String.Format(logStr + "通过MES接口获取放卷物料{0}的SFC数量失败:{1}", bindSfc, upLoadBusiness.GetMesMessage(sfcQueryQtyResponse.@return.code, sfcQueryQtyResponse.@return.message)));
                        return "";
                    }
                    return sfcQueryQtyResponse.@return.qty;
                }
                else
                {
                    return "2600";
                }
            }
            catch (Exception ex)
            {
                LogHelper.Info(String.Format(logStr + "MES获取SFC数量接口异常:{1}", ex.Message));
                WebServiceLog.saveMiSFCQueryQtyServiceService(sFCQueryQtyServiceServiceParam, null, beginTime, ex.Message);
                LogRefreshEvent?.Invoke(LogType.MesLog, String.Format(logStr + "MES获取SFC数量接口异常:{1}", ex.Message));
                LogRefreshEvent?.Invoke(LogType.AlarmLog, String.Format(logStr + "MES获取SFC数量接口异常:{1}", ex.Message));
                return "";
            }
        }

        /// <summary>
        /// 拆分MES账目数量
        /// </summary>
        /// <param name="position"></param>
        /// <param name="shaftInfos"></param>
        /// <param name="eaValue"></param>
        /// <param name="upMaterialSfc"></param>
        private async Task<bool> SpiltAccount(int position, ProShaftInfo shaftInfos, int eaValue, string upMaterialSfc, ProUpRecord upRecord, ProDownRecord downRecord)
        {
            LogHelper.Info("自动完工MES账目数量");
            LogRefreshEvent?.Invoke(LogType.MesLog, "自动完工MES账目数量:" + eaValue);
            miBatchCompleteSfcAndAdujustQtySfcEntity[] miBatchCompleteSfcAndAdujustQtySfcEntities = new miBatchCompleteSfcAndAdujustQtySfcEntity[1];
            shaftInfos.bindEaValue = eaValue.ToString();

            miBatchCompleteSfcAndAdujustQtySfcEntities[0] = new miBatchCompleteSfcAndAdujustQtySfcEntity()
            {
                processLot = shaftInfos.bindRfid,
                qty = shaftInfos.bindEaValue,
                unit = "EA",
            };

            //更新绑定信息
            await shaftInfoServices.Update(shaftInfos);

            LogRefreshEvent?.Invoke(LogType.RfidLog, "调用MES自动完工接口");
            LogHelper.Info("调用MES自动完工接口");
            WebService.MiBatchCompleteSfcAndAdujustQtyServiceService.ModeProcessSfc modeProcessSfc = WebService.MiBatchCompleteSfcAndAdujustQtyServiceService.ModeProcessSfc.MODE_COMPLETE_SFC_POST_DC;
            MiBatchCompleteSfcAndAdujustQtyServiceServiceParam requestParam = new MiBatchCompleteSfcAndAdujustQtyServiceServiceParam()
            {
                url = inifile.IniReadValue("SplitSfcParam","url"),
                site = inifile.IniReadValue("SplitSfcParam", "site"),
                sfcPre = upMaterialSfc,
                processLotPre = "",
                operation = appConfig.operation,   //阳极ANCAP1 //阴极CACAP1
                operationRevision = inifile.IniReadValue("SplitSfcParam", "operationRevision"),
                resource = appConfig.resource,
                user = inifile.IniReadValue("SplitSfcParam", "user"),
                activity = inifile.IniReadValue("SplitSfcParam", "activity"),
                //modeProcessSfc = WebService.MiBatchCompleteSfcAndAdujustQtyServiceService.ModeProcessSfc.MODE_NONE,
                modeProcessSfc = modeProcessSfc,
                sfcList = miBatchCompleteSfcAndAdujustQtySfcEntities,

            };
            MiBatchCompleteSfcAndAdujustQtyResponse batchCompleteSfcAndAdujustQtyResponse = new MiBatchCompleteSfcAndAdujustQtyResponse();
            DateTime beginTime = DateTime.Now;
            try
            {
                LogHelper.Info("MES自动完工接口请求参数:" + JsonChange.ModeToJson(requestParam));
                if (appConfig.isMesFlag == 1)
                {
                    if (StringExtension.IsBlank(downRecord.Sfc))
                    {
                        batchCompleteSfcAndAdujustQtyResponse = MesWebServices.iMiBatchCompleteSfcAndAdujustQtyServiceService(requestParam);
                        LogHelper.Info("MES自动完工接口返回参数:" + JsonChange.ModeToJson(batchCompleteSfcAndAdujustQtyResponse));

                        var result = batchCompleteSfcAndAdujustQtyResponse.@return;
                        if (result.code > 0)
                        {
                            LogHelper.Info("MES自动完工接口调用失败:" + result.message);
                            LogRefreshEvent?.Invoke(LogType.AlarmLog, "MES自动完工接口调用失败:" + upLoadBusiness.GetMesMessage(result.code, result.message));
                            LogRefreshEvent?.Invoke(LogType.MesLog, "MES自动完工接口调用失败:" + upLoadBusiness.GetMesMessage(result.code, result.message));
                            plcBusiness.writePlc(appConfig.AbAddress.MES异常, result.code);
                            return false;
                        }
                    }

                    LogHelper.Info("MES自动完工接口调用成功");
                    LogRefreshEvent?.Invoke(LogType.RfidLog, "MES自动完工接口调用成功");


                }
            }
            catch (Exception ex)
            {
                LogHelper.Error("MES自动完工接口调用异常", ex);
                LogHelper.Info("MES自动完工接口调用异常:" + ex.Message);

                WebServiceLog.saveMiBatchCompleteSfcAndAdujustQtyServiceService(requestParam, null, beginTime, ex.Message);
                LogRefreshEvent?.Invoke(LogType.AlarmLog, "MES自动完工接口异常:" + ex.Message);
                LogRefreshEvent?.Invoke(LogType.MesLog, "MES自动完工接口异常:" + ex.Message);
                plcBusiness.writePlc(appConfig.AbAddress.MES异常, 1);
                return false;
            }
            return true;
        }

        /// <summary>
        /// 卷筒涨紧MES处理信号
        /// </summary>
        /// <param name="postion"></param>
        /// <param name="epc"></param>
        /// <param name="auto">是否是自动读取,如果不是自动读取需要把PLC信号清掉</param>
        public async void SJMesBegin(int position, string epc, bool auto)
        {
            string logStr = position == 1 ? "收卷轴" : "放卷轴";
            string sfc = "";
            ///把之前的信号清除了,但是现在还有问题,现在泄气以后,
            ///现场应该还要再涨紧,还会给我信号
            if (!auto)
            {
                //清除泄气信号
               // plcBusiness.writePlc(appConfig.AbAddress.气涨泄气, 0);
                //清除报警
                plcBusiness.writePlc(appConfig.AbAddress.RFID异常, 0);
            }
            try
            {

                #region Add By wenjy 2022-09-20 获取工单信息,判断是否需要更换工单
                //if (!ShopOrderAlarm(position))
                //{
                //    //MES接口返回异常,控制PLC气胀轴写1泄气
                //    plcBusiness.writePlc(appConfig.AbAddress.气涨泄气, 1);
                //    //写入报警
                //    plcBusiness.writePlc(appConfig.AbAddress.MES异常, 1);
                //    return;
                //}
                #endregion

                //调用MES接口获取SFC
                #region Update By wenjy 2022-09-20 凹版工单下达逻辑修改,判断第一位不为L时重新获取
                sfc = GetSFC(position);
                if (StringExtension.IsBlank(sfc))
                {
                    return;
                }

                if (sfc.Substring(0, 1) != "L")
                {
                    sfc = GetSFC(position);
                    if (StringExtension.IsBlank(sfc))
                    {
                        return;
                    }
                }
                #endregion

                LogHelper.Info("凹版工单下达接口调用成功,SFC膜卷号为:" + sfc);
                LogRefreshEvent?.Invoke(LogType.MesLog, "MES凹版工单下达接口调用成功,膜卷号:" + sfc);
                //GetSFCByMesEvent?.Invoke(true, sfc);

                WriteSfcAndEpc(position, sfc, epc);

                ViewModelRefreshEvent?.Invoke(new ViewModelDto()
                {
                    rfidInfo = new RfidInfoDto()
                    {
                        rfid = epc,
                        position = position,
                        sfc = sfc,
                        ea = "",
                    },
                    plcStatus = true,
                });
                LogHelper.Info("本地保存RFID及膜卷号信息生成收卷记录");

                //实时绑定卷轴与RFID信息
                LogHelper.Info(String.Format("绑定{0}卷轴与RFID:{1}获取卷轴信息", logStr, epc));
                Expression<Func<ProShaftInfo, bool>> exp = s1 => true;
                exp = exp.And(x => x.positionId == position.ToString() && x.processId == appConfig.processId);
                Expression<Func<ProShaftInfo, object>> order = (x) => x.bindTime;
                ProShaftInfo shaftInfo = await shaftInfoServices.QueryFirst(exp, order, true);

                if (shaftInfo == null)
                {
                    LogRefreshEvent?.Invoke(LogType.RfidLog, "绑定卷轴与RFID条码获取卷轴信息为空");
                    LogRefreshEvent?.Invoke(LogType.AlarmLog, "绑定卷轴与RFID条码获取卷轴信息为空");
                    LogHelper.Info("绑定卷轴与RFID获取卷轴信息为空");
                    return;
                }
                LogHelper.Info("获取卷轴信息为:" + JsonChange.ModeToJson(shaftInfo));
                shaftInfo.bindRfid = epc;
                shaftInfo.bindSfc = sfc;
                shaftInfo.bindTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                await shaftInfoServices.Update(shaftInfo);

                LogHelper.Info("本地绑定RFID:" + epc + ",SFC:" + sfc);
                //PLC允许转塔 D9602写1
                //plcBusiness.writePlc(appConfig.AbAddress.是否转塔, 1);

                //添加下料记录
                ProDownRecord downRecord = new ProDownRecord()
                {
                    Id = System.Guid.NewGuid().ToString("N"),
                    MachineId = appConfig.machineId,
                    PositionId = position,
                    Rfid = epc,
                    Sfc = sfc,
                    IsProduction = 0,
                    beginTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                    RecordTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                };
                await downRecordServices.Add(downRecord);

                //upLoadBusiness.SaveDownRecord(downRecord);
            }
            catch (Exception e)
            {
                LogHelper.Info(e.ToString());
            }

        }
        private void WriteSfcAndEpc(int position, string sfcStr, string rfidStr)
        {
            if (position == 1)
            {
                //LogHelper.Info("将SFC与RFID写入PLC地址");
                PlcBusiness.writeStrPlc(appConfig.AbAddress.收卷轴SFC, sfcStr);
                LogRefreshEvent?.Invoke(LogType.PlcLog, "将SFC与RFID写入PLC地址");
            }
            else
            {
                //LogHelper.Info("将SFC与RFID写入PLC地址");
                PlcBusiness.writeStrPlc(appConfig.AbAddress.放卷SFC, sfcStr);
                LogRefreshEvent?.Invoke(LogType.PlcLog, "将SFC与RFID写入PLC地址");
            }

        }
        /// <summary>
        /// 凹版工单下达
        /// </summary>
        /// <returns></returns>
        private string GetSFC(int position)
        {
            string sfc = "";
            LogHelper.Info("调用MES凹版工单下达接口");
            LogRefreshEvent?.Invoke(LogType.MesLog, "调用MES凹版工单下达接口");
            //调MES凹版工单下达接口获取SFC
            MiReleaseSfcWithActivityServiceServiceParam miReleaseSfcWithActivityServiceServiceParam = new MiReleaseSfcWithActivityServiceServiceParam()
            {
                url = inifile.IniReadValue("MiReleaseSfcWithActivityServiceServiceParam", "url"),
                site = inifile.IniReadValue("MiReleaseSfcWithActivityServiceServiceParam", "site"),
                user = inifile.IniReadValue("MiReleaseSfcWithActivityServiceServiceParam", "user"),
                operation = appConfig.operation,
                operationRevision = inifile.IniReadValue("MiReleaseSfcWithActivityServiceServiceParam", "operationRevision"),
                activityId = inifile.IniReadValue("MiReleaseSfcWithActivityServiceServiceParam", "activity"),
                Resource = appConfig.resource,
                sfcQty = 1,
                modeProcessSfc = modeProcessSFC.MODE_START_SFC, //MODE_START_SFC
                isCarrierType = false,
                loginUser = inifile.IniReadValue("MiReleaseSfcWithActivityServiceServiceParam", "loginUser"),
                password = inifile.IniReadValue("MiReleaseSfcWithActivityServiceServiceParam", "password"),
            };
            DateTime beginTime = DateTime.Now;
            try
            {
                LogHelper.Info("凹版工单下达接口请求参数:" + JsonChange.ModeToJson(miReleaseSfcWithActivityServiceServiceParam));

                if (appConfig.isMesFlag == 1)
                {
                    miReleaseSfcWithActivityResponse releaseSfcWithActivityResponse = MesWebServices.iMiReleaseSfcWithActivityServiceService(miReleaseSfcWithActivityServiceServiceParam);
                    LogHelper.Info("凹版工单下发接口返回参数:" + JsonChange.ModeToJson(releaseSfcWithActivityResponse));
                    if (releaseSfcWithActivityResponse.@return.code > 0)
                    {
                        LogRefreshEvent?.Invoke(LogType.MesLog, "MES凹版工单获取失败:" + upLoadBusiness.GetMesMessage(releaseSfcWithActivityResponse.@return.code, releaseSfcWithActivityResponse.@return.message));
                        LogRefreshEvent?.Invoke(LogType.AlarmLog, "MES凹版工单单获取:" + upLoadBusiness.GetMesMessage(releaseSfcWithActivityResponse.@return.code, releaseSfcWithActivityResponse.@return.message));
                        //GetSFCByMesEvent?.Invoke(false, "");
                        //MES接口返回异常,控制PLC气胀轴写1泄气
                        //plcBusiness.writePlc(appConfig.AbAddress.RFID异常, 1);
                        //写入报警
                        plcBusiness.writePlc(appConfig.AbAddress.MES异常, 1);
                        //写入转塔是否可以旋转
                        //plcBusiness.writePlc(appConfig.AbAddress.是否转塔, 0);
                        LogHelper.Info("凹版工单下达接口获取失败:" + releaseSfcWithActivityResponse.@return.message + ",下发气胀轴泄气D9608,下发MES接口返回异常报警D9612");

                        return "";
                    }
                    sfc = releaseSfcWithActivityResponse.@return.sfcArray[0].sfc;
                }
                else
                {
                    Random random = new Random();
                    sfc = "LYL3PC0223082400" + random.Next(10, 99);
                    //qty = "2000";
                    LogRefreshEvent?.Invoke(LogType.RfidLog, String.Format("MES首工序获取SFC接口调用成功,SFC:{0}", sfc));
                }
                return sfc;
            }
            catch (Exception ex)
            {
                WebServiceLog.saveMiReleaseSfcWithActivityServiceService(miReleaseSfcWithActivityServiceServiceParam, null, beginTime, ex.Message);

                LogRefreshEvent?.Invoke(LogType.AlarmLog, "MES凹版工单下达接口调用异常:" + ex.Message);
                LogRefreshEvent?.Invoke(LogType.MesLog, "MES凹版工单下达接口调用异常:" + ex.Message);
                //GetSFCByMesEvent?.Invoke(false, "");
                //读取失败,控制PLC气胀轴
                //plcBusiness.writePlc(appConfig.AbAddress.气涨泄气, 1);
                //写入报警
                plcBusiness.writePlc(appConfig.AbAddress.MES异常, 1);
                //写入转塔是否可以旋转
               // plcBusiness.writePlc(appConfig.AbAddress.是否转塔, 0);
                return "";
            }
        }
        /// <summary>
        /// 放卷涨紧手动写入
        /// </summary>
        /// <param name="position"></param>
        /// <param name="epc"></param>
        /// <param name="auto"></param>
        public async void FJMesBegin(int position, string epc, bool auto)
        {
            string sfc = "";
            string qty = "";
            try
            {
                //手动写入清除放卷位报警
                if (!auto)
                {
                    plcBusiness.writePlc(appConfig.AbAddress.RFID异常, 0);
                    plcBusiness.writePlc(appConfig.AbAddress.MES异常, 0);
                }
                //凹版上料
                LogHelper.Info("调用MES凹版自动上料接口");
                LogRefreshEvent?.Invoke(LogType.MesLog, "调用MES凹版自动上料接口");
                LogRefreshEvent?.Invoke(LogType.RfidLog, "调用MES凹版自动上料接口");



                LogHelper.Info("调用MES首工序获取SFC接口");
                LogRefreshEvent?.Invoke(LogType.MesLog, "调用MES首工序获取SFC接口");
                LogRefreshEvent?.Invoke(LogType.RfidLog, "调用MES首工序获取SFC接口");
                sfc = GetSFC(position);
                if (StringExtension.IsBlank(sfc))
                {
                    return;
                }

                //放卷位膜卷号写入PLC地址
                WriteSfcAndEpc(position, sfc,epc);
                LogRefreshEvent?.Invoke(LogType.PlcLog, "放卷位物料SFC写入PLC地址:" + sfc);

                ViewModelRefreshEvent?.Invoke(new ViewModelDto()
                {
                    rfidInfo = new RfidInfoDto()
                    {
                        rfid = epc,
                        sfc = sfc,
                        position = position,
                        ea = qty,
                    },
                    plcStatus = true,
                });

                //实时绑定卷轴与RFID信息
                LogHelper.Info(String.Format("绑定放卷轴与RFID:{0};获取卷轴信息", epc));
                ProShaftInfo shaftInfo = await this.GetShaftInfoByPosition(position);

                if (shaftInfo == null || StringExtension.IsBlank(shaftInfo.processId))
                {
                    LogRefreshEvent?.Invoke(LogType.RfidLog, "绑定卷轴与RFID,获取卷轴信息为空");
                    LogRefreshEvent?.Invoke(LogType.AlarmLog, "绑定卷轴与RFID,获取卷轴信息为空");
                    LogHelper.Info("绑定卷轴与RFID,获取卷轴信息为空");
                    return;
                }
                LogHelper.Info("获取卷轴信息为:" + JsonChange.ModeToJson(shaftInfo));
                shaftInfo.bindRfid = epc;
                shaftInfo.bindSfc = sfc;
                shaftInfo.bindEaValue = qty;
                shaftInfo.bindTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
                await shaftInfoServices.Update(shaftInfo);

                //本地保存SFC,上料记录
                ProUpRecord upRecord = new ProUpRecord()
                {
                    Id = System.Guid.NewGuid().ToString(),
                    MachineId = appConfig.machineId,
                    UpMaterialId = sfc, //存放凹版来料膜卷号
                    PositionId = position,
                    Rfid = epc,
                    Sfc = sfc,
                    eaValue = StringChange.ParseToInt(qty),
                    IsProduction = 0,
                    beginTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"),
                    RecordTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
                };
                await upRecordServices.Add(upRecord);

                //upLoadBusiness.SaveUpRecord(upRecord);

                //判断是否合卷
                //if (JudgementMaterial(sfc))
                //{
                //    LogHelper.Info("上料成功,收卷位SFC与放卷SFC不同触发合卷报警");
                //    plcBusiness.writePlc(appConfig.AbAddress.合卷报警, 1);
                //}
                //手动写入自动下降U型块
                plcBusiness.writePlc(appConfig.AbAddress.手动上料, 1);
            }
            catch (Exception ex)
            {
                LogHelper.Error("放卷涨紧手动写入异常", ex);
            }
        }

        /// <summary>
        /// 下料成功
        /// </summary>
        /// <param name="position"></param>
        public void sendSuccess(int position)
        {
            if (position == 1)
            {
                plcBusiness.writePlc(appConfig.AbAddress.收卷控制下料, 0);
            }
            if (position == 0)
            {
                plcBusiness.writePlc(appConfig.AbAddress.放卷控制下料, 0);
            }
        }

        /// <summary>
        /// 禁止下料
        /// </summary>
        /// <param name="position"></param>
        public void sendError(int position)
        {
            if (position == 0) plcBusiness.writePlc(appConfig.AbAddress.放卷控制下料, 1);
            if (position == 1) plcBusiness.writePlc(appConfig.AbAddress.收卷控制下料, 1);

        }

        /// <summary>
        /// 异常下发
        /// </summary>
        /// <param name="position"></param>
        /// <param name="errorType"></param>
        /// <param name="isFinish"></param>
        public void sendError(int position, int errorType, bool isFinish, int mesCode)
        {
            if (isFinish)
            {
                if (errorType == 1) //MES异常
                {
                    plcBusiness.writePlc(appConfig.AbAddress.MES异常, mesCode);
                }
            }
            else
            {
                if (errorType == 1) //MES异常
                {
                    plcBusiness.writePlc(appConfig.AbAddress.MES异常, mesCode);
                }
                if (errorType == 2)
                {
                    plcBusiness.writePlc(appConfig.AbAddress.RFID异常, 1);
                }
            }
        }
        /// <summary>
        /// 通过RFID获取SFC
        /// </summary>
        /// <param name="rfidStr"></param>
        /// <returns></returns>
        private string[] GetSfcListByRfid(string rfidStr)
        {
            string[] sfcStr = new string[0];
            string strlog = "";
            DateTime beginTime = new DateTime();
            ProcessLotServiceWSServiceParam processLotServiceWSServiceParam = new ProcessLotServiceWSServiceParam()
            {
                //url = "http://lymesa.catlbattery.com:8103/manufacturing-papiservices/ProcessLotServiceWSService?wsdl",
                //site = "2100",
                url = inifile.IniReadValue("ProcessLotServiceWSServiceParam", "url"),
                site = inifile.IniReadValue("ProcessLotServiceWSServiceParam", "site"),
                processlotref = String.Format("ProcessLotBO:2100,{0}", rfidStr),
                loginUser = inifile.IniReadValue("ProcessLotServiceWSServiceParam", "loginUser"),
                password = inifile.IniReadValue("ProcessLotServiceWSServiceParam", "password")
            };

            try
            {
                LogRefreshEvent?.Invoke(LogType.MesLog, "调用MES接口获取RFID绑定的SFC");
                LogHelper.Info("MES获取膜卷号接口请求参数:" + JsonChange.ModeToJson(processLotServiceWSServiceParam));
                if (appConfig.isMesFlag == 1)
                {
                    readProcessLotResponse readProcessLotResponse = MesWebServices.readProcessLot(processLotServiceWSServiceParam);
                    LogHelper.Info("MES获取膜卷号接口返回参数:" + JsonChange.ModeToJson(readProcessLotResponse));
                    if (readProcessLotResponse.Response.processLotMemberList != null)
                    {
                        sfcStr = new string[readProcessLotResponse.Response.processLotMemberList.Count()];
                        for (int i = 0; i < readProcessLotResponse.Response.processLotMemberList.Count(); i++)
                        {
                            sfcStr[i] = readProcessLotResponse.Response.processLotMemberList[i].memberContext;
                            strlog += "RFID条码:" + rfidStr + "绑定的SFC条码为:" + sfcStr[i].Substring(11) + "\r\n";
                        }

                        LogHelper.Info(strlog);
                        LogRefreshEvent?.Invoke(LogType.MesLog, strlog);
                    }
                }
                else
                {
                    //sfcStr = System.Guid.NewGuid().ToString("N").Substring(0, 14);
                    Random random = new Random();
                    sfcStr = new string[1];
                    sfcStr[0] = "LYL3PC0223082400" + random.Next(10, 99);
                }
            }
            catch (Exception ex)
            {

                LogHelper.Info("MES获取膜卷号接口调用异常:" + ex.Message);
                LogRefreshEvent?.Invoke(LogType.AlarmLog, "MES获取膜卷号接口调用异常:" + ex.Message);
                return null;
                //WebServiceLog.saveReadProcessLot(processLotServiceWSServiceParam, null, beginTime, ex.Message);
            }
            return sfcStr;
        }
        /// <summary>
        /// 解绑RFID与SFC
        /// </summary>
        /// <param name="rfidStr"></param>
        public void UnBindRfidAndSfc(string rfidStr)
        {
            //获取当前RFID是否绑定
            int lowQuantity;
            //string sfcStr = GetSfcByRfid(rfidStr);
            string[] strlist = GetSfcListByRfid(rfidStr);

            DateTime beginTime = new DateTime();
            if (strlist != null && strlist.Count() > 0)
            {
                ProcessLotServiceWSServiceParam lotServiceWSServiceParam =
                                new ProcessLotServiceWSServiceParam()
                                {
                                    url = inifile.IniReadValue("ProcessLotServiceWSServiceParam", "url"),
                                    site = inifile.IniReadValue("ProcessLotServiceWSServiceParam", "site"),
                                    processlotref = "ProcessLotBO:2100," + rfidStr,
                                    memberlist = strlist,
                                    loginUser = inifile.IniReadValue("ProcessLotServiceWSServiceParam", "loginUser"),
                                    password = inifile.IniReadValue("ProcessLotServiceWSServiceParam", "password")
                                };
                LogHelper.Info("MES解绑接口请求参数:" + JsonChange.ModeToJson(lotServiceWSServiceParam));
                beginTime = DateTime.Now;
                try
                {
                    if (appConfig.isMesFlag == 1)
                    {
                        removeMemberResponse removeMember =
                            MesWebServices.iRemoveMember(lotServiceWSServiceParam);
                        LogRefreshEvent?.Invoke(LogType.RfidLog, "RFID条码:" + rfidStr + "成功解绑SFC!");

                        LogHelper.Info("MES解绑接口返回参数:" + JsonChange.ModeToJson(removeMember));
                    }
                }
                catch (Exception ex)
                {
                    WebServiceLog.saveRemoveMember(lotServiceWSServiceParam, null, beginTime, ex.Message);
                    LogRefreshEvent?.Invoke(LogType.AlarmLog,
                        String.Format("RFID条码:{0}解绑失败:{1}!!!", rfidStr, ex.Message));
                    return;
                }

            }
            else
            {
                LogHelper.Info("RFID条码:" + rfidStr + "未绑定SFC信息");
                LogRefreshEvent?.Invoke(LogType.RfidLog, "RFID条码:" + rfidStr + "未绑定SFC信息");
            }
        }

        /// <summary>
        /// 根据设备位置获取卷轴信息
        /// </summary>
        /// <param name="position"></param>
        /// <returns></returns>
        public async Task<ProShaftInfo> GetShaftInfoByPosition(int position)
        {
            try
            {
                string str = appConfig.processId;
                Expression<Func<ProShaftInfo, bool>> exp = s1 => true;
                exp = exp.And(x => x.positionId == position.ToString() && x.processId == str);
                List<ProShaftInfo> result = await shaftInfoServices.Query(exp);

                if (result != null || result.Count > 0)
                {
                    ProShaftInfo shaftInfo = result.FirstOrDefault();
                    return shaftInfo;
                }
                return null;
            }
            catch (Exception ex)
            {
                LogRefreshEvent?.Invoke(LogType.RfidLog, "获取卷轴信息为空");
                LogHelper.Info("获取卷轴信息异常:" + ex.Message);
                return null;
            }
        }


        /// <summary>
        /// 强制下料
        /// </summary>
        /// <param name="position"></param>
        public void ForceDown(int position)
        {
            switch (position)
            {
                case 1:
                    LogRefreshEvent?.Invoke(LogType.PlcLog, "收卷轴异常下料信号触发,下发下料信号");
                    LogHelper.Info("收卷轴异常下料信号触发,下发下料信号");
                    plcBusiness.writePlc(appConfig.AbAddress.收卷控制下料, 0);
                    break;
                default:
                    break;
            }
        }

        /// <summary>
        /// 收卷位开始信号
        /// </summary>
        /// <param name="position"></param>
        public void DownBegin(int position)
        {
            string logStr = position == 1 ? "收卷轴" : "放卷轴";
            try
            {
                //禁止下料
                sendError(position);
                LogHelper.Info(logStr + "收卷开始信号触发成功,解绑RFID绑定的SFC条码");
                LogRefreshEvent?.Invoke(LogType.PlcLog, logStr + "收卷开始信号触发成功");
                LogRefreshEvent?.Invoke(LogType.RfidLog, logStr + "解绑RFID绑定的SFC条码");
                //获取RFID条码信息
                ProShaftInfo shaftInfo = this.GetShaftInfoByPosition(position).Result;
                this.UnBindRfidAndSfc(shaftInfo.bindRfid);
            }
            catch (Exception ex)
            {
                LogHelper.Info(logStr + "收卷开始信号逻辑处理异常:" + ex.Message);
                upLoadBusiness.SaveLogRecord(position, logStr + "收卷开始信号逻辑处理异常:" + ex.Message);
            }
        }

        /// <summary>
        /// 判断收卷位是否合卷
        /// </summary>
        /// <param name="epc"></param>
        /// <param name="position"></param>
        /// <returns></returns>
        private async Task<bool> PdRfidIsChuanDu(string epc, int position)
        {
            try
            {
                LogHelper.Info("RFID条码:" + epc + "判断是否串读逻辑处理");
                Expression<Func<ProShaftInfo, bool>> exp = s1 => true;
                exp = exp.And(x => x.bindRfid == epc && x.positionId != position.ToString() && x.processId == appConfig.processId);
                List<ProShaftInfo> shaftInfos = await shaftInfoServices.Query(exp);
                if (shaftInfos.Count > 0)
                {
                    return true;
                }
                return false;
            }
            catch (Exception ex)
            {
                LogHelper.Error("串读逻辑处理异常", ex);
                return false;
            }
        }

        /// <summary>
        ///判断当前是哪个轴
        /// </summary>
        /// <returns></returns>
        private string Which(int position)
        {
            string logStr = "";
            if (position == 1) logStr = "收卷轴";
            return logStr;
        }


        /// <summary>
        /// 设备启动
        /// </summary>
        public void MachineStartUp()
        {
            #region Delete By wenjy 2022-12-27 ME要求改为原逻辑
            //      throw new NotImplementedException();
            //LogRefreshEvent?.Invoke(LogType.PlcLog, "开机启动信号触发成功");
            //LogHelper.Info("开机启动信号触发成功");
            ////通过PLC地址获取放卷膜卷号
            //string sfc = PlcBusiness.readStrPlc("D6034", (ushort)18).Replace("\0", "").Trim();
            ////JudgementMaterial(放卷膜卷号),返回true合卷报警=>PLC 写报警值,返回false不处理
            //if (StringExtension.IsNotBlank(sfc))
            //{
            //    // 判断合卷
            //    if (JudgementMaterial(sfc))
            //    {
            //        LogHelper.Info("触发合卷报警,下发PLC报警指令");
            //        LogRefreshEvent?.Invoke(LogType.AlarmLog, "放卷位与收卷位膜卷号不同触发合卷报警");
            //        // 写入合卷报警
            //        plcBusiness.writePlc("D6114", 1);
            //    }
            //}
            #endregion
        }

        /// <summary>
        /// 放卷位物料是否结束生产
        /// </summary>
        /// <param name="epc"></param>
        private async Task<bool> UpMaterialIsEndProduction(string rfidStr)
        {
            bool result = false;
            //通过MES获取RFID绑定的SFC并判断是否结束,凹版来料RFID绑定为凹版膜卷号,暂不使用SFC判断,使用RFID判断
            string sfcStr = GetSfcByRfid(rfidStr);

            LogRefreshEvent?.Invoke(LogType.RfidLog, String.Format("当前RFID:{0}绑定的SFC为:{1}", rfidStr, sfcStr));
            //通过SFC判断该卷物料是否已经生产结束,如果已生产返回true,未生产返回false
            //upRecordServices
            Expression<Func<ProUpRecord, bool>> exp = s1 => true;
            exp = exp.And(x => x.Rfid == rfidStr);
            Expression<Func<ProUpRecord, object>> order = s1 => s1.RecordTime;
            ProUpRecord upRecord = await upRecordServices.QueryFirst(exp, order, false);
            if (upRecord != null)
            {
                if (StringExtension.IsBlank(upRecord.endTime))
                {
                    LogRefreshEvent?.Invoke(LogType.RfidLog, String.Format("当前SFC:{0}放卷结束时间为空,生产未结束", sfcStr));
                    result = false;
                }
                else
                {
                    LogRefreshEvent?.Invoke(LogType.RfidLog, String.Format("当前SFC:{0}放卷结束时间为:{1}", sfcStr, upRecord.endTime));
                    result = true;
                }
            }
            return result;
        }

        /// <summary>
        /// 通过RFID获取SFC
        /// </summary>
        /// <param name="rfidStr"></param>
        /// <returns></returns>
        private string GetSfcByRfid(string rfidStr)
        {
            string sfcStr = "";
            DateTime beginTime = new DateTime();
            ProcessLotServiceWSServiceParam processLotServiceWSServiceParam = new ProcessLotServiceWSServiceParam()
            {
                url = inifile.IniReadValue("ProcessLotServiceWSServiceParam", "url"),
                site = inifile.IniReadValue("ProcessLotServiceWSServiceParam", "site"),
                processlotref = String.Format("ProcessLotBO:2100,{0}", rfidStr)
            };

            try
            {
                LogRefreshEvent?.Invoke(LogType.MesLog, "调用MES接口获取RFID绑定的SFC");
                LogHelper.Info("MES获取膜卷号接口请求参数:" + JsonChange.ModeToJson(processLotServiceWSServiceParam));
                if (appConfig.isMesFlag == 1)
                {
                    readProcessLotResponse readProcessLotResponse = MesWebServices.readProcessLot(processLotServiceWSServiceParam);
                    LogHelper.Info("MES获取膜卷号接口返回参数:" + JsonChange.ModeToJson(readProcessLotResponse));
                    if (readProcessLotResponse.Response.processLotMemberList != null)
                    {
                        sfcStr = readProcessLotResponse.Response.processLotMemberList[0].memberContext.Substring(11);
                        LogHelper.Info("RFID条码:" + rfidStr + "绑定的SFC条码为:" + sfcStr);
                        LogRefreshEvent?.Invoke(LogType.MesLog, "RFID条码:" + rfidStr + "绑定的SFC条码为:" + sfcStr);
                    }
                }
                else
                {
                    sfcStr = System.Guid.NewGuid().ToString("N").Substring(0, 14);
                }
            }
            catch (Exception ex)
            {
                LogHelper.Info("MES获取膜卷号接口调用异常:" + ex.Message);
                LogRefreshEvent?.Invoke(LogType.MesLog, "MES获取膜卷号接口调用异常:" + ex.Message);
                LogRefreshEvent?.Invoke(LogType.AlarmLog, "MES获取膜卷号接口调用异常:" + ex.Message);
                WebServiceLog.saveReadProcessLot(processLotServiceWSServiceParam, null, beginTime, ex.Message);
            }
            return sfcStr;
        }

        private void SaveReadRecord(ProEquip equip, string rfidStr)
        {
            ProReadRecord readRecord = new ProReadRecord()
            {
                MachineID = equip.machineId,
                EquipID = equip.equipId,
                PositionID = equip.positionId,
                Ant = StringChange.ParseToInt(equip.equipAnt),
                ReadEPC = rfidStr,
                Result = StringExtension.IsBlank(rfidStr) ? "0" : "1",
                ReadTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")
            };
            upLoadBusiness.SaveReadRecord(readRecord);
        }


    }
}