using BasicData;
using ConverterBytesAndStruct;
using DataLinkMesWork;
using DC_A95;
using DC_A95.MES_A95;
using ExternalDataSync;
using HslCommunication.WebSocket;
using Newtonsoft.Json;
using NPOI.HSSF.Record.Chart;
using NPOI.OpenXmlFormats.Dml.Diagram;
using NPOI.SS.Formula.Functions;
using NPOI.Util;
using Opc.Ua;
using OpcBasic;
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Reflection.Emit;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using System.Windows.Forms;
using System.Xml;
using SystemFramework;

/// <summary>
/// 
/// </summary>
namespace MesWork
{
    /// <summary>
    /// 质量数据的拆解和存储
    /// </summary>
    public class MesWork_QC
    {


        /// <summary>
        /// 全部数据列表
        /// </summary>
        public static DataTable BasicDataTagValue;
        /// <summary>
        /// MES_基本数据_测量范围
        /// </summary>
        public static DataTable BasicDataTagValueUpDown;



        /// <summary>
        /// MOM接口：保存过点数据(进站)
        /// </summary>
        /// <param name="opCode">工位名称</param>
        /// <param name="DataFlag">1、进站，2、离站</param>
        public static void ProcessData_PartOn(string opCode, string engineNo,int palletNo,string sortNo_PLC)
        {
            MES_QueryCache.Get_ProductPlan_ByEngineNo(engineNo, out string engineTypeNo, out string orderNum, out int orderNo, out int orderSum, out int if_codetest, out int if_hottest);
            MES_QueryCache.Get_ProductProcess_ByOP(opCode, out string processCode, out string processName, out string opName, out string AreaName);

            int QualityOk = 0;  //合格标志：1-合格；2-不合格
            int PassStatus = 1; //过站状态：1-正常工作；2-因为前序不合格没工作放行过去；3-工位被屏蔽
            var Operator = "";

            var optFlag = OptFlag.AddNew;
            var passAttr = PassAttr.OPStart;

            var upOrDown = -1;


            //保存过点数据
            ExecuteDB.Save_StationPass_Info(engineNo, engineTypeNo, palletNo, orderNum, orderNo, orderSum, processCode, processName,
            opCode, opName, passAttr, Operator, QualityOk, PassStatus, upOrDown, optFlag, sortNo_PLC);

        }
      
        public static void ProcessData_PartOff(string opCode, string engineNo, int palletNo,string sortNo_PLC)
        {

            MES_QueryCache.Get_ProductPlan_ByEngineNo(engineNo, out string engineTypeNo, out string orderNum, out int orderNo, out int orderSum, out int if_codetest, out int if_hottest);
            MES_QueryCache.Get_ProductProcess_ByOP(opCode, out string processCode, out string processName, out string opName, out string AreaName);

            var Operator = "";
            var QualityOk = 1;
            var PassStatus = 1;
            var optFlag = OptFlag.AddNew;
            var passAttr = PassAttr.OPEnd;
            var upOrDown = 3;
            //离站信息保存
            ExecuteDB.Save_StationPass_Info(engineNo, engineTypeNo, palletNo, orderNum, orderNo, orderSum, processCode, processName,
            opCode, opName, passAttr, Operator, QualityOk, PassStatus, upOrDown, optFlag, sortNo_PLC);

        }





        /// <summary>
        /// 允许保存(针对半自动和手动压装工位)
        /// </summary>
        /// <param name="OpName"></param>
        /// <param name="tagValue"></param>
        public static int MesRead(string opName, string tagValue, string tagid, bool isCheck = false)
        {
            return SaveQualityData(opName, Convert.ToInt32(tagValue), tagid, isCheck);
        }

        //public static string GetRealTimeQualityData(string opName)
        //{
        //    string message = "";
        //    DataTable dt1 = new DataTable();
        //    DataTable dt_WWW;
        //    DataTable dt_WWW_Copy1;
        //    DataTable dt_WWW_Copy2;
        //    Hashtable valueList;
        //    try
        //    {
        //        var tagValues = PLC_R.ReadPLC_OpName(opName); 
        //        //过滤出来质量数据 //获得带合格标志的质量数据
        //        valueList = ReadPLC_OpName_Qd(tagValues);
        //        //获得带基本信息的质量数据表
        //        GetQualityDataTable(valueList, opName, BasicDataTagValue, BasicDataTagValueUpDown, out dt_WWW);

        //        dt_WWW_Copy1 = dt_WWW.Copy().Select("变量排序 = 1").CopyToDataTable();
        //        DataView dv1 = dt_WWW_Copy1.DefaultView;
        //        dv1.Sort = "列位置 DESC";
        //        dt_WWW_Copy1 = dv1.ToTable();

        //        dt_WWW_Copy2 = dt_WWW.Copy().Select("变量排序 = 2").CopyToDataTable();
        //        DataView dv2 = dt_WWW_Copy2.DefaultView;
        //        dv2.Sort = "列位置 DESC";
        //        dt_WWW_Copy2 = dv2.ToTable();

        //        dt1.Columns.Add("列位置", System.Type.GetType("System.String"));
        //        dt1.Columns.Add("测量项目1", System.Type.GetType("System.String"));
        //        dt1.Columns.Add("测量项目2", System.Type.GetType("System.String"));
        //        dt1.Columns.Add("合格标志", System.Type.GetType("System.String"));
        //        dt1.Columns.Add("名称", System.Type.GetType("System.String"));

        //        for (int i = 0; i < dt_WWW_Copy1.Rows.Count; i++)
        //        {
        //            if (dt_WWW_Copy1.Rows[i]["TagValue"].ToString() != "0" || dt_WWW_Copy2.Rows[i]["TagValue"].ToString() != "0")
        //            {
        //                var dr = dt1.NewRow();
        //                dr["列位置"] = dt_WWW_Copy1.Rows[i]["列位置"].ToString();
        //                dr["测量项目1"] = dt_WWW_Copy1.Rows[i]["TagValue"].ToString();
        //                dr["测量项目2"] = dt_WWW_Copy2.Rows[i]["TagValue"].ToString();
        //                dr["合格标志"] = dt_WWW_Copy1.Rows[i]["IsGoodBad"].ToString();
        //                dr["名称"] = dt_WWW_Copy1.Rows[i]["测量项目"].ToString();
        //                dt1.Rows.Add(dr);
        //            }
        //        }
        //    }
        //    catch (Exception err)
        //    {
        //    }
        //    message = CreateJsonParameters(dt1);

        //    return message;
        //}

        public static string CreateJsonParameters(DataTable dt)
        {
            StringBuilder JsonString = new StringBuilder();
            //Exception Handling        

            if (dt != null)
            {
                JsonString.Append("{ ");
                JsonString.Append("\"rows\":[ ");
                for (int i = 0; i < dt.Rows.Count; i++)
                {
                    JsonString.Append("{ ");
                    for (int j = 0; j < dt.Columns.Count; j++)
                    {
                        if (j < dt.Columns.Count - 1)
                        {
                            //if (dt.Rows[i][j] == DBNull.Value) continue;
                            if (dt.Columns[j].DataType == typeof(bool))
                            {
                                JsonString.Append("\"" + dt.Columns[j].ColumnName.ToLower() + "\":" +
                                                  dt.Rows[i][j].ToString().ToLower() + ",");
                            }
                            else if (dt.Columns[j].DataType == typeof(string))
                            {
                                JsonString.Append("\"" + dt.Columns[j].ColumnName.ToLower() + "\":" +
                                                      ObjectToJson(dt.Rows[i][j]).ToString() + ",");
                                //JsonString.Append("\"" + dt.Columns[j].ColumnName.ToLower() + "\":" + "\"" +
                                //                  dt.Rows[i][j].ToString().Replace("\"", "\\\"") + "\",");
                            }
                            else
                            {
                                JsonString.Append("\"" + dt.Columns[j].ColumnName.ToLower() + "\":" + "\"" + dt.Rows[i][j] + "\",");
                            }
                        }
                        else if (j == dt.Columns.Count - 1)
                        {
                            //if (dt.Rows[i][j] == DBNull.Value) continue;
                            if (dt.Columns[j].DataType == typeof(bool))
                            {
                                JsonString.Append("\"" + dt.Columns[j].ColumnName.ToLower() + "\":" +
                                                  dt.Rows[i][j].ToString().ToLower());
                            }
                            else if (dt.Columns[j].DataType == typeof(string))
                            {
                                JsonString.Append("\"" + dt.Columns[j].ColumnName.ToLower() + "\":" +
                                                      ObjectToJson(dt.Rows[i][j]).ToString());
                                //JsonString.Append("\"" + dt.Columns[j].ColumnName.ToLower() + "\":" + "\"" +
                                //                  dt.Rows[i][j].ToString().Replace("\"", "\\\"") + "\"");
                            }
                            else
                            {
                                JsonString.Append("\"" + dt.Columns[j].ColumnName.ToLower() + "\":" + "\"" + dt.Rows[i][j] + "\"");
                            }
                        }
                    }
                    /*end Of String*/
                    if (i == dt.Rows.Count - 1)
                    {
                        JsonString.Append("} ");
                    }
                    else
                    {
                        JsonString.Append("}, ");
                    }
                }
                JsonString.Append("]");

                JsonString.Append("}");
                return JsonString.ToString().Replace("\n", "");
            }
            else
            {
                return null;
            }
        }
        public static string ObjectToJson(object obj)
        {
            JavaScriptSerializer js = new JavaScriptSerializer();
            js.MaxJsonLength = Int32.MaxValue; // 定义JavaScriptSerializer接受字符串的最大长度 hdk 20180524
            try
            {
                return js.Serialize(obj);
            }
            catch (Exception exception)
            {

                throw new Exception(exception.Message);
            }
        }
        /// <summary>
        /// 返回合格标志
        /// </summary>
        /// <param name="opName"></param>
        /// <param name="tagValue"></param>
        /// <param name="tagID"></param>
        /// <returns></returns>
        private static int SaveQualityData(string opName, int tagValue, string tagID, bool isCheck = false)
        {
            int id_tagCF;
            int qualityMask = 0;
            int engineTypeID = 0;
            string engineID = "";
            string engineType = "";
            string partPallet = "";
            string orderFormPlc = "";
            DataTable dt_WWW;
            Hashtable valueList;
            try
            {
                var tagValues = PLC_R.ReadPLC_OpName(opName);
                //过滤出来质量数据 //获得带合格标志的质量数据
                valueList = ReadPLC_OpName_Qd(tagValues);

                engineTypeID = Convert.ToInt32(GetValueByTagTypeCodeID(tagValues, Convert.ToInt32(EnumTagTypeCodeID.EngineTypeID)));
                engineID = GetValueByTagTypeCodeID(tagValues, Convert.ToInt32(EnumTagTypeCodeID.EngineID)).ToString();
                engineType = GetValueByTagTypeCodeID(tagValues, Convert.ToInt32(EnumTagTypeCodeID.EngineType)).ToString();
                orderFormPlc = GetValueByTagTypeCodeID(tagValues, Convert.ToInt32(EnumTagTypeCodeID.OrderFormPLC)).ToString();
                qualityMask = Convert.ToInt32(GetValueByTagTypeCodeID(tagValues, Convert.ToInt32(EnumTagTypeCodeID.QualityMask)));

                //获得带基本信息的质量数据表
                GetQualityDataTable(valueList, opName, BasicDataTagValue,BasicDataTagValueUpDown, out dt_WWW);

                DateTime lastupdatetime = DateTime.Now;
                //保存质量数
                BaseData_tagTable_QualityData_B5A_IndexInsert(engineID, tagID, engineType, engineTypeID, opName, qualityMask, partPallet, out id_tagCF);
                BaseData_tagTable_QualityData_B5A_Insert(id_tagCF, engineTypeID, engineType, engineID, opName, dt_WWW, isCheck);
                MesWork_QC_upload.SyncTask_UploadMeasureData(id_tagCF.ToString());

                Material_Insert(opName, 1);
              
            }
            catch (Exception err)
            {
                LogRecord.LogRecord.Insert_Log(Type_Log.Alarm, "", $"SaveQualityData 报错！，，{err.Message}+{err.StackTrace }");
            }
            return qualityMask;
        }


        /// <summary>
        /// AMES_MES_装配数据_零部件追溯_增加
        /// </summary>
        /// <param name="opName"></param>
        /// <param name="m_ConfirmOkGo"></param>
        /// <returns></returns>
        public static bool Material_Insert(string opName, int m_ConfirmOkGo)
        {
            string produceName = "MES_装配数据_零部件追溯_增加";
            SqlParameter[] thisParms = new SqlParameter[2];
            thisParms[0] = new System.Data.SqlClient.SqlParameter("@工位号", opName);
            thisParms[1] = new System.Data.SqlClient.SqlParameter("@放行方式", m_ConfirmOkGo);
            return DataAccess.ExecuteStoredProcedure(produceName, ref thisParms);
        }


        static public void GetQualityDataTable(Hashtable valuList, string opName, DataTable BasicDataTagValue, DataTable BasicDataTagValueUpDown, out DataTable dt)
        {
            //78 0：屏蔽MES；1：启用MES(必须MIS)
            //79 通过线体工位PC实现下达工位工作状态：工位有三种状态：在线、离线、屏蔽。在线;0正常状态，实现正常功能。1离线：2屏蔽。(必须MIS)
            //41 机体流向标志（1 BYTE）：0普通工位：1：上线（发动机上线）；2：下线（发动机下线）；(必须PLC)
            //51 返修工位，修改后的数据MES将数据写入PLC ，MES通知PLC数据修改完成。(YN)
            //8 只要返修，必须由mes发送此信号，plc接收此信号后才能放行
            //（暂时没用）用于有扳手拧紧工位。通知设备螺钉拧紧完成。PC已经将数据保存到数据库中。(B5A)

            QualityDataType qualityData;
            //是否有数据
            //bool isUsing;

            DataRow dr;
            DataRow[] dr_WWW;
            //MES_基本数据_测量范围
            DataRow[] dr_WWW_UpDown;

            dt = BuildDataTables_WWW();

            //测量位置
            string shaftID;
            //测量项目
            string item;
            //测量单位
            string unit;
            //机体类型
            //原始数据中的机型代码
            int engineTypeID_Source;
            //上限值
            string tagValueUp;
            //下限值
            string tagValueDown;
            //理论值
            string tagValeNormal;
            //TagValue
            // 合格标志
            //string IsGoodBad;

            foreach (DictionaryEntry valueItem in valuList) //ht为一个Hashtable实例 
            {
                try
                {
                    qualityData = (QualityDataType)valueItem.Value;


                    //if ((qualityData.tagProperty != 2) || (qualityData.tagProperty != 6))
                    //{
                    //    continue ;
                    //}
                    //if ((qualityData.tagProperty == 2) || (qualityData.tagProperty == 6))
                    {
                        //if (engineTypeID == 0)
                        //{
                        //    engineTypeID = 1;
                        //}
                        dr_WWW = BasicDataTagValue.Select("TagID = " + qualityData.tagID);
                        try
                        {
                            dr_WWW_UpDown = BasicDataTagValueUpDown.Select("TagID = " + qualityData.tagID);
                        }
                        catch { dr_WWW_UpDown = null; }


                        //if (dr_WWW.Length > 0)
                        //{
                        //    {
                        //        engineTypeID_Source = Convert.ToInt32(dr_WWW[0]["机体类型"]);
                        //        int temp;
                        //        temp = engineTypeID_Source & engineTypeID;
                        //        if (temp == 0)
                        //        {
                        //            continue;
                        //        }
                        //        if (qualityData.isGoodBad == -1)
                        //        {
                        //            continue;
                        //        }
                        //    }
                        //}
                        //else
                        //{
                        //    continue;

                        //}

                        try
                        {
                            shaftID = dr_WWW[0]["测量位置"].ToString();
                        }
                        catch
                        {
                            shaftID = "";
                        }
                        try
                        {
                            item = dr_WWW[0]["测量项目"].ToString();
                        }
                        catch
                        {
                            item = "";
                        }
                        try
                        {
                            unit = dr_WWW[0]["测量单位"].ToString();
                        }
                        catch
                        {
                            unit = "";
                        }
                        try
                        {
                            tagValueUp = "";
                            if (dr_WWW_UpDown != null && dr_WWW_UpDown.Length > 0)
                            {
                                tagValueUp = dr_WWW_UpDown[0]["值上限"].ToString();
                            }
                            else
                            {
                                tagValueUp = "";
                            }
                        }
                        catch
                        {
                            tagValueUp = "";
                        }
                        try
                        {
                            tagValueDown = "";
                            if (dr_WWW_UpDown != null && dr_WWW_UpDown.Length > 0)
                            {
                                tagValueDown = dr_WWW_UpDown[0]["值下限"].ToString();
                            }
                        }
                        catch
                        {
                            tagValueDown = "";
                        }
                        try
                        {
                            tagValeNormal = "";
                            if (dr_WWW_UpDown != null && dr_WWW_UpDown.Length > 0)
                            {
                                tagValeNormal = dr_WWW_UpDown[0]["理论值"].ToString();
                            }

                        }
                        catch
                        {
                            tagValeNormal = "";
                        }

                        dr = dt.NewRow();

                        dr["TagID"] = qualityData.tagID;
                        dr["测量位置"] = shaftID;
                        dr["测量项目"] = item;
                        dr["测量单位"] = unit;
                        dr["上限值"] = tagValueUp;
                        dr["下限值"] = tagValueDown;
                        dr["理论值"] = tagValeNormal;
                        dr["工位号"] = opName;
                        dr["列位置"] = qualityData.tagOrderBy;
                        dr["变量排序"] = qualityData.tagItemOrderBy;

                        dr["IsGoodBad"] = qualityData.isGoodBad;

                        switch (qualityData.tagTypeID)//
                        {
                            //合格标志数组
                            case 8203:
                                dr["TagValue"] = GetQualityData_GoodBad_String((bool[])qualityData.tagValue);
                                break;
                            case 8209:
                                dr["TagValue"] = "";
                                break;
                            //非标准REAL
                            case 8210:
                                dr["TagValue"] = GetNoNormalReal(qualityData.tagValue);
                                dt.Rows.Add(dr);
                                break;
                            default:
                                dr["TagValue"] = Convert.ToString(qualityData.tagValue);
                                dt.Rows.Add(dr);
                                break;
                        }

                        //福田对质量数据特殊处理，MA20保留4位小数点，其余保留两位
                        if (opName == "J07MA020")
                        {
                            dr["TagValue"] = Convert.ToDouble(dr["TagValue"]).ToString("0.####");
                        }
                        else
                        {
                            dr["TagValue"] = Convert.ToDouble(dr["TagValue"]).ToString("0.##");
                        }

                        if (opName == "J07MA150")
                        {
                            dr["变量排序"] = 1;
                            dr["IsGoodBad"] = 1;
                        }


                    }



                }
                catch (Exception err)
                {
                    //ApplicationLog.WriteLog(err, err.Message);
                }
            }
        }

        /// <summary>
        /// 29 工位具体零件合格标志
        /// </summary>
        /// <param name="QualityData_GoodBad"></param>
        static public string GetQualityData_GoodBad_String(bool[] QualityData_GoodBad)
        {
            string str;
            str = "";
            if (QualityData_GoodBad != null)
            {

                for (int i = 0; i < QualityData_GoodBad.Length; i++)
                {
                    str = str + (Convert.ToInt32(QualityData_GoodBad[i])).ToString() + "|";
                }

            }
            return str;

        }
        /// <summary>
        /// 返回非标准real
        /// </summary>
        /// <param name="vDataValue"></param>
        /// <returns></returns>
        static public string GetNoNormalReal(object vDataValue)
        {
            try
            {
                string real_a;
                string real_b;
                string groupValueString;
                int length;

                //int real_b_Int;

                length = ((System.Array)(vDataValue)).Length;
                groupValueString = "";
                if (length != 2)
                    return "0.0";

                real_a = Convert.ToUInt16((((System.Array)(vDataValue)).GetValue(0))).ToString();
                real_b = Convert.ToUInt16((((System.Array)(vDataValue)).GetValue(1))).ToString("00");
                groupValueString = real_a + "." + real_b;
                return groupValueString;
            }
            catch
            {
                ////ApplicationLog.WriteLog(err, "GetNoNormalReal");
                return "0.0";

            }
        }
        /// <summary>
        /// 数据表
        /// </summary>
        /// <returns></returns>
        static public DataTable BuildDataTables_WWW()
        {
            DataTable table;
            DataColumnCollection columns;
            table = new DataTable();
            columns = table.Columns;
            table.Columns.Add("TagID", typeof(System.String));
            table.Columns.Add("TagValue", typeof(System.String));
            table.Columns.Add("IsGoodBad", typeof(System.Int32));
            table.Columns.Add("测量位置", typeof(System.String));
            table.Columns.Add("测量项目", typeof(System.String));
            table.Columns.Add("工位号", typeof(System.String));
            table.Columns.Add("理论值", typeof(System.String));
            table.Columns.Add("上限值", typeof(System.String));
            table.Columns.Add("下限值", typeof(System.String));
            table.Columns.Add("测量单位", typeof(System.String));
            table.Columns.Add("列位置", typeof(System.Int32));
            table.Columns.Add("变量排序", typeof(System.Int32));

            return table;
        }

        /// <summary>
        /// 数据表
        /// </summary>
        /// <returns></returns>
        private static object GetValueByTagTypeCodeID(ConcurrentDictionary<string, TagFormat> opTagList, int TagTypeCodeID)
        {
            try
            {
                return opTagList.Where(x => x.Value.TagTypeCodeID == TagTypeCodeID).ToList()[0].Value.TagValue;
            }
            catch (Exception err) { return "-3"; }
        }
        /// <summary>
        /// 根据工位名称，读取工位对应的质量数据，带合格标志
        /// </summary>
        /// <param name="opName"></param>
        /// <returns></returns>
        public static Hashtable ReadPLC_OpName_Qd(ConcurrentDictionary<string, TagFormat> tagValues)
        {
            //lock (l)
            {

                //var tagValues = DtWebApi.ReadWritePLC.ReadPLC_OpName(opName); //GetDbAndMaxLengthByOpNameByBytes(opName);

                var keyValues = tagValues.OrderBy(x => x.Key).ToDictionary(k => k.Key, v => v.Value);

                TagFormat tagFormatTemp;
                int tagIndex = 1;
                int isOK = 0;

                Hashtable ht = new Hashtable();


                foreach (KeyValuePair<string, TagFormat> _cd in keyValues)
                {
                    if (_cd.Key.ToString()[0].ToString() == "7")
                    {
                        tagFormatTemp = _cd.Value;
                        if (tagIndex % 3 == 1)
                        {
                            isOK = Convert.ToInt32(tagFormatTemp.TagValue);
                        }
                        else if (tagIndex % 3 == 2)
                        {
                            var TF = _cd.Value;

                            QualityDataType qualityDataType;
                            qualityDataType = GetQualityDataType(TF);
                            qualityDataType.isGoodBad = isOK;
                            ht.Add(qualityDataType.tagID, qualityDataType);
                        }
                        else if (tagIndex % 3 == 0)
                        {
                            var TF = (TagFormat)_cd.Value;

                            QualityDataType qualityDataType;
                            qualityDataType = GetQualityDataType(TF);
                            qualityDataType.isGoodBad = isOK;
                            ht.Add(qualityDataType.tagID, qualityDataType);
                        }

                        tagIndex++;
                    }
                    //Console.WriteLine($"key：{kv.Key} value：{kv.Value}");
                }
                return ht;
            }
        }

        public static QualityDataType GetQualityDataType(TagFormat TF)
        {
            QualityDataType qualityDataType;

            qualityDataType = new QualityDataType();

            qualityDataType.tagID = TF.TagID;
            qualityDataType.tagTypeID = TF.TagTypeID;//变量类型
            qualityDataType.opName = TF.OpName;
            // int.TryParse(TF.TagQuality.ToString(), out int TagQuality);
            var TagQuality = 192;
            qualityDataType.tagQuality = TagQuality;
            qualityDataType.tagValueType = TF.TagTypeCodeID;
            int.TryParse(TF.TagOrderBy, out int TagOrderBy);
            qualityDataType.tagOrderBy = TagOrderBy;
            int.TryParse(TF.TagItemOrderBy, out int TagItemOrderBy);
            qualityDataType.tagItemOrderBy = TagItemOrderBy;
            qualityDataType.tagProperty = Convert.ToInt32(TF.TagProperty);//变量特点
            qualityDataType.tagValue = TF.TagValue;//变量值

            return qualityDataType;
        }

        public static bool BaseData_tagTable_QualityData_B5A_IndexInsert(string EngineID, string tagID, string EngineType, int EngineTypeID, string opName, int isGoodBad, string PartPalletCode, out int Id_tagCF)
        {
            string procedureName;
            procedureName = "测量数据合格索引_增加";
            Id_tagCF = 0;
            SqlParameter[] thisParms = new SqlParameter[8];
            thisParms[0] = new System.Data.SqlClient.SqlParameter("@EngineID", EngineID);
            thisParms[1] = new System.Data.SqlClient.SqlParameter("@TagID_CF", Convert.ToInt32(tagID));
            thisParms[2] = new System.Data.SqlClient.SqlParameter("@EngineType", EngineType);
            thisParms[3] = new System.Data.SqlClient.SqlParameter("@EngineTypeID", EngineTypeID);
            thisParms[4] = new System.Data.SqlClient.SqlParameter("@工位号", opName);
            thisParms[5] = new System.Data.SqlClient.SqlParameter("@托盘编号", PartPalletCode);
            thisParms[6] = new System.Data.SqlClient.SqlParameter("@合格标志", isGoodBad);
            thisParms[7] = new System.Data.SqlClient.SqlParameter("@Id_tagCF", Id_tagCF) 
            { Direction = ParameterDirection.Output };

            if (DataAccess.ExecuteStoredProcedure(procedureName, ref thisParms))
            {
                Id_tagCF = Convert.ToInt32(thisParms[7].Value.ToString());
                return true;
            }
            return false;
        }
        public static bool BaseData_tagTable_QualityData_B5A_Insert(int Id_tagCF, int engineTypeID, string engineType, string engineID, string opName, DataTable dt, bool IsCheck = false)
        {
            string procedureName;
            procedureName = "测量数据合格_增加";
            SqlParameter[] thisParms = new SqlParameter[7];
            thisParms[0] = new System.Data.SqlClient.SqlParameter("@Id_tagCF", Id_tagCF);
            thisParms[1] = new System.Data.SqlClient.SqlParameter("@EngineTypeID", engineTypeID);
            //thisParms[2] = new System.Data.SqlClient.SqlParameter("@EngineType", engineType);
            thisParms[2] = new System.Data.SqlClient.SqlParameter("@EngineID", engineID);
            thisParms[3] = new System.Data.SqlClient.SqlParameter("@TagID", SqlDbType.Int, 4, "TagID");
            thisParms[4] = new System.Data.SqlClient.SqlParameter("@TagValue", SqlDbType.NVarChar, 100, "TagValue");
            thisParms[5] = new System.Data.SqlClient.SqlParameter("@IsGoodBad", SqlDbType.Int, 4, "IsGoodBad");
            //是否保存无合格标志数据数据
            thisParms[6] = new System.Data.SqlClient.SqlParameter("@IsCheck", IsCheck);
            //thisParms[6] = new System.Data.SqlClient.SqlParameter("@测量位置", SqlDbType.NVarChar, 50, "测量位置");
            //thisParms[7] = new System.Data.SqlClient.SqlParameter("@测量项目", SqlDbType.NVarChar, 50, "测量项目");
            //thisParms[8] = new System.Data.SqlClient.SqlParameter("@工位号", opName);  //为了给J07MA020 保留四位精度而设置
            //thisParms[9] = new System.Data.SqlClient.SqlParameter("@理论值", SqlDbType.NVarChar, 50, "理论值");
            //thisParms[10] = new System.Data.SqlClient.SqlParameter("@上限值", SqlDbType.NVarChar, 50, "上限值");
            //thisParms[11] = new System.Data.SqlClient.SqlParameter("@下限值", SqlDbType.NVarChar, 50, "下限值");
            //thisParms[12] = new System.Data.SqlClient.SqlParameter("@测量单位", SqlDbType.NVarChar, 50, "测量单位");
            //thisParms[13] = new System.Data.SqlClient.SqlParameter("@列位置", SqlDbType.Int, 4, "列位置");
            //thisParms[14] = new System.Data.SqlClient.SqlParameter("@变量排序", SqlDbType.Int, 4, "变量排序");
            //table.Columns.Add("TagID", typeof(System.Int32));
            //table.Columns.Add("TagValue", typeof(System.String));
            //table.Columns.Add("IsGoodBad", typeof(System.Int32));
            //table.Columns.Add("测量位置", typeof(System.String));
            //table.Columns.Add("测量项目", typeof(System.String));
            //table.Columns.Add("工位号", typeof(System.String));
            //table.Columns.Add("理论值", typeof(System.String));
            //table.Columns.Add("上限值", typeof(System.String));
            //table.Columns.Add("下限值", typeof(System.String));
            //table.Columns.Add("测量单位", typeof(System.String));
            //table.Columns.Add("列位置", typeof(System.Int32));
            //table.Columns.Add("变量排序", typeof(System.Int32));
            return DataAccess.ExecuteStoredProcedure(procedureName, ref thisParms, dt);
        }


        //public static int MesRead_J07MA150(string opName, string tagValue, string tagid)
        //{
        //    int qualityMask = 0;

        //    if (tagValue == "0")
        //    {
        //        MIS_BASE.Write_TagTypeID(20, opName, false);
        //    }
        //    else
        //    {
        //        qualityMask = SaveQualityData_J07MA150(opName, Convert.ToInt32(tagValue), tagid);
        //        MIS_BASE.Write_TagTypeID(20, opName, true);
        //    }
        //    return qualityMask;
        //}
        /// <summary>
        /// 返回合格标志, 注油工位 质量数据为字符串，读取备用点 变量类型代码 = 41
        /// </summary>
        /// <param name="opName"></param>
        /// <param name="tagValue"></param>
        /// <param name="tagID"></param>
        /// <returns></returns>
        private static int SaveQualityData_J07MA150(string opName, int tagValue, string tagID)
        {
            int id_tagCF;
            int qualityMask = 0;
            int engineTypeID = 0;
            string engineID = "";
            string engineType = "";
            string partPallet = "";
            string orderFormPlc = "";
            DataTable dt_WWW;
            Hashtable valueList;
            try
            {

                //过滤出来质量数据 //获得带合格标志的质量数据
                var tagValues = PLC_R.ReadPLC_OpName(opName);
                valueList = ReadPLC_OpName_Qd_J07MA150(tagValues);
                //valueList = ReadPLC_OpName_Qd(tagValues);

                engineTypeID = Convert.ToInt32(GetValueByTagTypeCodeID(tagValues, Convert.ToInt32(EnumTagTypeCodeID.EngineTypeID)));
                engineID = GetValueByTagTypeCodeID(tagValues, Convert.ToInt32(EnumTagTypeCodeID.EngineID)).ToString();
                engineType = GetValueByTagTypeCodeID(tagValues, Convert.ToInt32(EnumTagTypeCodeID.EngineType)).ToString();
                orderFormPlc = GetValueByTagTypeCodeID(tagValues, Convert.ToInt32(EnumTagTypeCodeID.OrderFormPLC)).ToString();
                engineID = GetValueByTagTypeCodeID(tagValues, Convert.ToInt32(EnumTagTypeCodeID.EngineID)).ToString();
                qualityMask = Convert.ToInt32(GetValueByTagTypeCodeID(tagValues, Convert.ToInt32(EnumTagTypeCodeID.QualityMask)));





                //获得带基本信息的质量数据表
                GetQualityDataTable(valueList, opName, BasicDataTagValue,
                                    BasicDataTagValueUpDown, out dt_WWW);


                DateTime lastupdatetime = DateTime.Now;
                //保存质量数
                BaseData_tagTable_QualityData_B5A_IndexInsert(engineID, tagID, engineType, engineTypeID, opName, qualityMask, partPallet, out id_tagCF);
                BaseData_tagTable_QualityData_B5A_Insert(id_tagCF, engineTypeID, engineType, engineID, opName, dt_WWW);

                // }
                Material_Insert(opName, 1);
            }
            catch (Exception err)
            {
            }
            return qualityMask;
        }
        public static Hashtable ReadPLC_OpName_Qd_J07MA150(ConcurrentDictionary<string, TagFormat> tagValues)
        {
            //lock (l)
            {

                //var tagValues = DtWebApi.ReadWritePLC.ReadPLC_OpName(opName); //GetDbAndMaxLengthByOpNameByBytes(opName);

                var keyValues = tagValues.OrderBy(x => x.Key).ToDictionary(k => k.Key, v => v.Value);

                TagFormat tagFormatTemp;
                int tagIndex = 1;
                int isOK = 1;

                Hashtable ht = new Hashtable();


                //var TF = _cd.Value;
                ////var TF = Read_TagTypeID(39, opName, out OrderForm);

                //QualityDataType qualityDataType;
                //qualityDataType = GetQualityDataType(TF);
                //qualityDataType.isGoodBad = isOK;
                //ht.Add(qualityDataType.tagID, qualityDataType);


                foreach (KeyValuePair<string, TagFormat> _cd in keyValues)
                {

                    if (_cd.Value.TagTypeCodeID.ToString() == "41")
                    {
                        tagFormatTemp = _cd.Value;

                        var TF = _cd.Value;

                        QualityDataType qualityDataType;
                        qualityDataType = GetQualityDataType(TF);
                        qualityDataType.isGoodBad = isOK;
                        qualityDataType.tagItemOrderBy = 1;
                        qualityDataType.tagOrderBy = 1;
                        ht.Add(qualityDataType.tagID, qualityDataType);
                    }
                    //Console.WriteLine($"key：{kv.Key} value：{kv.Value}");
                }
                return ht;
            }
        }
















    }
}
