schangxiang@126.com
2024-12-19 4422008672f79f74841e11f20430c5e76686e293
DataCapture/iWare_SCADA_DataCapture/iWare_SCADA_BusinessLogical/DataCaptureHandlerV2/OP80QualityDataHandler.cs
@@ -28,6 +28,8 @@
        public static readonly string path = ConfigHelper.GetConfigString("OP80QualityData");//OP80的地址
        public static readonly string query_WorkingProcedureCurrent = "OP80";
        public static readonly string _DataCapturePointCode = "OP8002";
        public static readonly string _DataCapturePointName = "OP80质量数据采集";
        public static readonly string _EquipmentId = "EOP80";
        public static readonly LogType logType = LogType.PLCOP80_QC;
        public OP80QualityDataHandler()
@@ -88,8 +90,22 @@
                    threadStatusMonitor.ThreadId = Thread.CurrentThread.ManagedThreadId.ToString();
                    threadStatusMonitor.Threadlastmodifytime = DateTime.Now;
                    var time = DateTimeHelper.GetDateTime();
                    //OP80 需要扫描文件读取质量信息
                    //扫描修改时间在上次扫描时间之前30秒到当前时间的之间的文件
                    List<FileInfo> allFiles = new List<FileInfo>();
                    var newFiles = FileHelper.DetectNewFilesCSV(path, 300, time.AddDays(-30), time.AddDays(1));
                    foreach (var file in newFiles)
                    {
                        allFiles.Add((FileInfo)file);
                    }
                    //files = files.OrderByDescending(o => o.LastWriteTime).ToList();
                    allFiles = allFiles.OrderBy(o => o.LastWriteTime).ToList();//时间升序
                    Log4NetHelper.WriteInfoLog(logType, $"OP80下线完成读取到文件{allFiles.Count()}个");
                    var processList = db.WorkPieceProcess.Where(o => o.WorkingProcedureCurrent == query_WorkingProcedureCurrent && o.GetQcDataFlag == 0
                    ).OrderBy(x => x.CreatedTime).ToList();
                ).OrderBy(x => x.CreatedTime).ToList();
                    foreach (var item in processList)
                    {
                        var qualityData = db.QualityDataInfo.Where(o => o.WorkPieceID == item.WorkPieceID).FirstOrDefault();
@@ -105,286 +121,467 @@
                            continue;
                        }
                        Do_One(db, info, item, qualityData, WorkingProcedure);
                        var findFiles = allFiles.Where(x => x.Name.Contains(item.WorkPieceID)).OrderByDescending(x => x.LastWriteTime).ToList();
                        if (findFiles != null && findFiles.Count > 0)
                        {
                            var file = findFiles.First();
                        }
                        Do_One(false, false, false, allFiles, db, info, item, qualityData, findFiles);
                        Thread.Sleep(1000);
                    }
                    //处理剩余的文件
                    if (allFiles.Count() > 0)
                    {
                        Log4NetHelper.WriteErrorLog(logType, $" OP80质量数据采集异常:发现要处理剩余的文件{allFiles.Count()}件");
                        foreach (var otherFile in allFiles)
                        {
                            DoOtherFile(allFiles, otherFile, db);
                            Thread.Sleep(1000);
                        }
                    }
                    Thread.Sleep(1000);
                    WorkPieceInfoManager.ThreadMonitor(threadStatusMonitor);
                }
                catch (Exception e)
                {
                    Log4NetHelper.WriteErrorLog(logType, $" OP80质量数据采集异常:{e.Message} {e.StackTrace}");
                    Log4NetHelper.WriteErrorLog(logType, $" OP80质量数据采集异常:{e.Message} {e.StackTrace}", e);
                }
            }
        }
        private void Do_One(DbModel db, WorkPieceInfo info, WorkPieceProcess pieceProcess, QualityDataInfo qualityData, string WorkingProcedure)
        private void Do_One(bool isAdd_WorkPieceInfo, bool isAdd_WorkPieceProcess, bool isAdd_QualityDataInfo, List<FileInfo> allFiles, DbModel db, WorkPieceInfo info,
            WorkPieceProcess pieceProcess, QualityDataInfo qualityData,
             List<FileInfo> findFiles)
        {
            try
            {
                if (WorkingProcedure.Equals("OP80"))
                bool isGetQcSuccess = false;
                var file = findFiles.First();
                Log4NetHelper.WriteInfoLog(logType, $"OP80下线完成读取到文件{file.Name},是指定的工件{pieceProcess.WorkPieceID}");
                WorkPieceLogMiddle logMiddle = new WorkPieceLogMiddle();
                logMiddle.WorkPieceID = pieceProcess.WorkPieceID;
                logMiddle.WorkingProcedure = query_WorkingProcedureCurrent;
                logMiddle.Id = Yitter.IdGenerator.YitIdHelper.NextId();
                logMiddle.EquipmentID = _dataCaptureConfig.EquipmentID; ;
                logMiddle.Remarks = logMiddle.WorkingProcedure;
                logMiddle.MonitoringPoint = _DataCapturePointCode;
                //logMiddle.CreatedUserName = _DataCapturePointCode;
                SystemBussinessHelper.SetWorkPieceLogMiddleForCreatedUserName(ref logMiddle, DataCapturePointCode, DataCapturePointCname);
                logMiddle.CreatedTime = DateTimeHelper.GetDateTime();
                logMiddle.UpdatedTime = DateTimeHelper.GetDateTime();
                logMiddle.UpdatedUserName = Environment.MachineName + "自动" + Thread.CurrentThread.ManagedThreadId.ToString();
                logMiddle.IsDeleted = false;
                WorkPieceLog loginfo2 = new WorkPieceLog();
                loginfo2 = EntityPropHelper.Mapper<WorkPieceLog, WorkPieceLogMiddle>(logMiddle);
                loginfo2.DataCapturePointCname = "OP80质量采集";
                loginfo2.CreatedUserName = loginfo2.MonitoringPoint;
                var datatable = CSVHelper.ReadCSVList(file.FullName);
                List<string> rowFirst = new List<string>();
                List<string> rowSecond = new List<string>();
                if (datatable.Count == 2)
                {
                    var time = DateTimeHelper.GetDateTime();
                    //OP80 需要扫描文件读取质量信息
                    //扫描修改时间在上次扫描时间之前30秒到当前时间的之间的文件
                    List<FileInfo> files = new List<FileInfo>();
                    var newFiles = FileHelper.DetectNewFilesCSV(path, 300, time.AddDays(-7), time.AddDays(1));
                    foreach (var file in newFiles)
                    rowFirst = datatable[0].Split(',').ToList();
                    rowSecond = datatable[1].Split(',').ToList();
                    if (rowSecond.Count < 11)
                    {
                        files.Add((FileInfo)file);
                        return;
                    }
                    //files = files.OrderByDescending(o => o.LastWriteTime).ToList();
                    files = files.OrderBy(o => o.LastWriteTime).ToList();//时间升序
                    Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"OP80下线完成读取到文件{files.Count()}个工件{pieceProcess.WorkPieceID} ");
                    bool isGetQcSuccess = false;
                    foreach (var file in files)
                    {//取倒序匹配的文件名为工件号的文件
                        if (file.Name.Contains(pieceProcess.WorkPieceID))
                    //日期和时间   批号/标识号   嵌套号/主轴号   操作符   文本   测量机   过程参数   测量系统   过程参数值   序列号   零件识别号   1
                    OP80Info oP80Info = new OP80Info();
                    oP80Info.日期和时间 = rowSecond[0];
                    oP80Info.批号 = rowSecond[1];
                    oP80Info.嵌套号 = rowSecond[2];
                    oP80Info.操作符 = rowSecond[3];
                    oP80Info.文本 = rowSecond[4];
                    oP80Info.测量机 = rowSecond[5];
                    oP80Info.过程参数 = rowSecond[6];
                    oP80Info.测量系统 = rowSecond[7];
                    oP80Info.过程参数值 = rowSecond[8];
                    oP80Info.序列号 = rowSecond[9];
                    oP80Info.零件识别号 = rowSecond[10];
                    for (int i = 1; i <= (rowSecond.Count - 11) / 10; i++)
                    {
                        if (rowSecond.Count < (11 + i * 10))
                        {
                            Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"OP80下线完成读取到文件{file.Name},是指定的工件{pieceProcess.WorkPieceID}");
                            WorkPieceLogMiddle wplog = new WorkPieceLogMiddle();
                            wplog.WorkPieceID = pieceProcess.WorkPieceID;
                            wplog.WorkingProcedure = _DataCapturePointCode;
                            wplog.Id = Yitter.IdGenerator.YitIdHelper.NextId();
                            wplog.EquipmentID = _dataCaptureConfig.EquipmentID; ;
                            wplog.Remarks = wplog.WorkingProcedure;
                            wplog.MonitoringPoint = _DataCapturePointCode;
                            wplog.CreatedTime = DateTimeHelper.GetDateTime();
                            wplog.CreatedUserName = _DataCapturePointCode;
                            wplog.UpdatedTime = DateTimeHelper.GetDateTime();
                            wplog.UpdatedUserName = Environment.MachineName + "自动" + Thread.CurrentThread.ManagedThreadId.ToString();
                            wplog.IsDeleted = false;
                            WorkPieceLog loginfo2 = new WorkPieceLog();
                            loginfo2 = EntityPropHelper.Mapper<WorkPieceLog, WorkPieceLogMiddle>(wplog);
                            var datatable = CSVHelper.ReadCSVList(file.FullName);
                            List<string> rowFirst = new List<string>();
                            List<string> rowSecond = new List<string>();
                            if (datatable.Count == 2)
                            {
                                rowFirst = datatable[0].Split(',').ToList();
                                rowSecond = datatable[1].Split(',').ToList();
                                if (rowSecond.Count < 11)
                                {
                                    continue;
                                }
                                //日期和时间   批号/标识号   嵌套号/主轴号   操作符   文本   测量机   过程参数   测量系统   过程参数值   序列号   零件识别号   1
                                OP80Info oP80Info = new OP80Info();
                                oP80Info.日期和时间 = rowSecond[0];
                                oP80Info.批号 = rowSecond[1];
                                oP80Info.嵌套号 = rowSecond[2];
                                oP80Info.操作符 = rowSecond[3];
                                oP80Info.文本 = rowSecond[4];
                                oP80Info.测量机 = rowSecond[5];
                                oP80Info.过程参数 = rowSecond[6];
                                oP80Info.测量系统 = rowSecond[7];
                                oP80Info.过程参数值 = rowSecond[8];
                                oP80Info.序列号 = rowSecond[9];
                                oP80Info.零件识别号 = rowSecond[10];
                                for (int i = 1; i <= (rowSecond.Count - 11) / 10; i++)
                                {
                                    if (rowSecond.Count < (11 + i * 10))
                                    {
                                        break;
                                    }
                                    //名称 相对值 相对值单位 绝对值 绝对值单位 名义值 上限 下限  状态/等级 分隔符
                                    OP80ItemInfo item = new OP80ItemInfo();
                                    item.分隔符 = rowSecond[1 + i * 10];//例如:*   表头:状态
                                    item.名称 = rowSecond[2 + i * 10];//例如:Weight Big End    表头:*
                                    item.相对值 = rowSecond[3 + i * 10];//例如:-2.8    表头:简述
                                    item.相对值单位 = rowSecond[4 + i * 10];//例如:gr    表头:Weight Big End
                                    item.绝对值 = rowSecond[5 + i * 10];//例如:371.66    表头:测量单位
                                    item.绝对值单位 = rowSecond[6 + i * 10];//例如:gr    表头:绝对值
                                    item.名义值 = rowSecond[7 + i * 10];//例如:374.5    表头:绝对值测量单位(UoM)
                                    item.上限 = rowSecond[8 + i * 10];//例如:10.5    表头:名义值
                                    item.下限 = rowSecond[9 + i * 10];//例如:-10.5    表头:USL值
                                    item.状态 = rowSecond[10 + i * 10];//例如:3    表头:LSL值
                                    oP80Info.OP80ItemInfolist.Add(item);
                                    if (item.名称.Equals("Weight Class") || item.名称.Equals("Weight Small End")
                                        || item.名称.Equals("Weight Big End") || item.名称.Equals("Dime Small_End Class")
                                        || item.名称.Equals("Dime Big_End Class"))
                                    {
                                    }
                                    else
                                    {
                                        if (!string.IsNullOrEmpty(item.状态))
                                        {
                                            oP80Info.OP80ItemStatusInfolist.Add(item);
                                        }
                                    }
                                }
                                if (oP80Info.OP80ItemStatusInfolist.Count > 0)
                                {
                                    if (oP80Info.OP80ItemStatusInfolist.Any(o => !o.状态.Equals("OK")))
                                    {
                                        wplog.QualityStateStr = "NG";
                                    }
                                    else
                                    {
                                        wplog.QualityStateStr = "OK";
                                    }
                                }
                                else
                                {
                                    wplog.QualityStateStr = "OK";
                                }
                                wplog.OP80QualityFilePath = file.FullName;
                                wplog.OP80NewCode = oP80Info.批号?.Replace("#", "");
                                //大头重量
                                wplog.QualityOP80To1 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Weight Big End")).FirstOrDefault()?.绝对值;
                                //小头重量
                                wplog.QualityOP80To2 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Weight Small End")).FirstOrDefault()?.绝对值;
                                //总重
                                wplog.QualityOP80To3 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Total Weight")).FirstOrDefault()?.绝对值;
                                //弯曲
                                wplog.QualityOP80To4 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Bend to A")).FirstOrDefault()?.绝对值;
                                //扭度
                                wplog.QualityOP80To5 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Twist to A")).FirstOrDefault()?.绝对值;
                                //大头垂直度
                                wplog.QualityOP80To6 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_C_Squareness")).FirstOrDefault()?.绝对值;
                                //小头垂直度
                                wplog.QualityOP80To10 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Sma_End_C_Squareness")).FirstOrDefault()?.绝对值;
                                //大头孔分组级别
                                wplog.QualityOP80To7 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Dime Big_End Class")).FirstOrDefault()?.状态;
                                //小头孔分组级别
                                wplog.QualityOP80To8 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Dime Small_End Class")).FirstOrDefault()?.状态;
                                //重量组别
                                wplog.QualityOP80To9 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Weight Class")).FirstOrDefault()?.状态;
                                //wplog.Remarks = (wplog.Remarks ?? "") + $"OP80下线完成读取文件{file.FullName},数据【{wplog.OP80NewCode??"空"}】【{wplog.QualityOP80To1 ?? "空"}】【{wplog.QualityOP80To2 ?? "空"}】【{wplog.QualityOP80To3 ?? "空"}】【{wplog.QualityOP80To4 ?? "空"}】【{wplog.QualityOP80To5 ?? "空"}】";
                                //新增OP80的一些质量数据 【Editby shaocx,2024-06-13】
                                wplog.QualityOP80_Houdu = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Thickness")).FirstOrDefault()?.绝对值;
                                wplog.QualityOP80_ZXJ = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Distance of Two Head")).FirstOrDefault()?.绝对值;
                                wplog.QualityOP80_DTKYZD = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Cylindricity")).FirstOrDefault()?.绝对值;
                                wplog.QualityOP80_XTSMYD = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Top_Roundn")).FirstOrDefault()?.绝对值;
                                wplog.QualityOP80_XTXMYD = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Bot_Roundn")).FirstOrDefault()?.绝对值;
                                wplog.QualityOP80_D_S_X = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Top_X_Dia.")).FirstOrDefault()?.绝对值;
                                wplog.QualityOP80_D_S_Y = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Top_Y_Dia.")).FirstOrDefault()?.绝对值;
                                wplog.QualityOP80_D_X_X = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Bot_X_Dia.")).FirstOrDefault()?.绝对值;
                                wplog.QualityOP80_D_X_Y = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Bot_Y_Dia.")).FirstOrDefault()?.绝对值;
                                //计算大头孔直径,大头孔直径=(大头上面X方向直径+大头上面Y方向直径+大头下面X方向直径+大头下面Y方向直径)/4
                                List<decimal> valueList = new List<decimal>() {
                                                        SystemHelper.GetDecimal(wplog.QualityOP80_D_S_X),
                                                        SystemHelper.GetDecimal(wplog.QualityOP80_D_S_Y),
                                                        SystemHelper.GetDecimal(wplog.QualityOP80_D_X_X),
                                                        SystemHelper.GetDecimal(wplog.QualityOP80_D_X_Y),
                                                    };
                                wplog.QualityOP80_D_TKZJ = SystemHelper.CalcDecimalAvg(valueList, 3);
                                wplog.QualityOP80_X_S_X = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Top_X_Dia.")).FirstOrDefault()?.绝对值;
                                wplog.QualityOP80_X_S_Y = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Top_Y_Dia.")).FirstOrDefault()?.绝对值;
                                wplog.QualityOP80_X_X_X = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Bot_X_Dia.")).FirstOrDefault()?.绝对值;
                                wplog.QualityOP80_X_X_Y = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Bot_Y_Dia.")).FirstOrDefault()?.绝对值;
                                //计算小头孔直径,小头孔直径=(小头上面X方向直径+小头上面Y方向直径+小头下面X方向直径+小头下面Y方向直径)/4
                                valueList = new List<decimal>();
                                valueList = new List<decimal>() {
                                                        SystemHelper.GetDecimal(wplog.QualityOP80_X_S_X),
                                                        SystemHelper.GetDecimal(wplog.QualityOP80_X_S_Y),
                                                        SystemHelper.GetDecimal(wplog.QualityOP80_X_X_X),
                                                        SystemHelper.GetDecimal(wplog.QualityOP80_X_X_Y),
                                                    };
                                wplog.QualityOP80_X_TKZJ = SystemHelper.CalcDecimalAvg(valueList, 3);
                            }
                            else
                            {
                                wplog.Remarks = (wplog.Remarks ?? "") + $"OP80下线完成读取文件{file.FullName}异常,行数不是2行";
                            }
                            //更新WorkPieceInfo表以及插入WorkPieceLog表和WorkPieceInfoLog表
                            info.OP80NewCode = wplog.OP80NewCode;//更新成品吗
                            info.QualityState = (int)((wplog.QualityStateStr.Equals("OK") || wplog.QualityStateStr.Equals("0K")) ? QualityState.OK : QualityState.NG);
                            wplog.QualityState = info.QualityState;
                            info.QualityStateUpdateUser = wplog.UpdatedUserName;
                            info.QualityStateUpdateTime = wplog.UpdatedTime.Value.LocalDateTime;
                            info.QualityStateUpdateMode = QualityStateUpdateMode.Auto.ToString();
                            //var qualityData = db.QualityDataInfo.Where(o => o.WorkPieceID == wplog.WorkPieceID).FirstOrDefault();
                            //if (qualityData == null || qualityData.WorkPieceID.Length < 1 || qualityData.WorkingProcedure.Length < 1)
                            //{//插入QualityDataInfo表
                            //    qualityData = EntityPropHelper.Mapper<QualityDataInfo, WorkPieceLog>(wplog);
                            //    db.QualityDataInfo.Add(GetAddQualityDataInfo(qualityData));
                            //}
                            //修改QualityDataInfo表 //重复收到质量信息,会覆盖之前的
                            EntityPropHelper<WorkPieceLogMiddle, QualityDataInfo>.CopyProp(wplog, qualityData, WorkPieceInfoManager.GetQualityDataInfoUpdate(wplog.WorkingProcedure, wplog.MonitoringPoint));//指定修改字段
                            qualityData.QualityStateUpdateUser = info.UpdatedUserName;
                            qualityData.QualityReceiveTime = info.UpdatedTime.Value.LocalDateTime;
                            qualityData.QualityStateUpdateMode = info.QualityStateUpdateMode;
                            qualityData.OP80QualityState = wplog.QualityState.HasValue ? wplog.QualityState.Value.ToString() : "3";
                            qualityData.OP80QualityReceiveTime = DateTimeHelper.GetDateTime();
                            qualityData.OP80QualityFilePath = wplog.OP80QualityFilePath;
                            long op80id = qualityData.Id;
                            if (op80id > 0)
                            {
                                pieceProcess.QualityDataInfoID = op80id;
                            }
                            loginfo2.Remarks = (loginfo2.Remarks ?? "") + $"质量:{wplog.QualityStateStr ?? "空"}";
                            if (!info.QualityState.Equals(((int)QualityState.OK).ToString()))
                            {
                                info.QualityErrorInfo = $"{wplog.WorkingProcedure}工序质量采集数据不合格";
                            }
                            else
                            {
                                info.QualityErrorInfo = "";
                            }
                            pieceProcess.GetQcDataCount = (pieceProcess.GetQcDataCount ?? 0) + 1;
                            pieceProcess.GetQcDataFlag_Remark = "找到文件";
                            pieceProcess.GetQcDataFlag = 1;
                            db.WorkPieceLog.Add(WorkPieceInfoManager.GetAddWorkPieceLog(loginfo2));//插入工件采集日志表
                            db.QualityDataInfoLog.Add(WorkPieceInfoManager.GetAddQualityDataInfoLog(qualityData));//插入质量日志
                            //转移文件
                            var toPath = file.FullName.Replace("CA4GC20TD", "CA4GC20TD_COPY");
                            File.Move(file.FullName, toPath);//移动
                            db.SaveChanges();
                            isGetQcSuccess = true;
                            break;
                        }
                        //名称 相对值 相对值单位 绝对值 绝对值单位 名义值 上限 下限  状态/等级 分隔符
                        OP80ItemInfo item = new OP80ItemInfo();
                        item.分隔符 = rowSecond[1 + i * 10];//例如:*   表头:状态
                        item.名称 = rowSecond[2 + i * 10];//例如:Weight Big End    表头:*
                        item.相对值 = rowSecond[3 + i * 10];//例如:-2.8    表头:简述
                        item.相对值单位 = rowSecond[4 + i * 10];//例如:gr    表头:Weight Big End
                        item.绝对值 = rowSecond[5 + i * 10];//例如:371.66    表头:测量单位
                        item.绝对值单位 = rowSecond[6 + i * 10];//例如:gr    表头:绝对值
                        item.名义值 = rowSecond[7 + i * 10];//例如:374.5    表头:绝对值测量单位(UoM)
                        item.上限 = rowSecond[8 + i * 10];//例如:10.5    表头:名义值
                        item.下限 = rowSecond[9 + i * 10];//例如:-10.5    表头:USL值
                        item.状态 = rowSecond[10 + i * 10];//例如:3    表头:LSL值
                        oP80Info.OP80ItemInfolist.Add(item);
                        if (item.名称.Equals("Weight Class") || item.名称.Equals("Weight Small End")
                            || item.名称.Equals("Weight Big End") || item.名称.Equals("Dime Small_End Class")
                            || item.名称.Equals("Dime Big_End Class"))
                        {
                        }
                        else
                        {
                            if (!string.IsNullOrEmpty(item.状态))
                            {
                                oP80Info.OP80ItemStatusInfolist.Add(item);
                            }
                        }
                    }
                    if (isGetQcSuccess == false)
                    if (oP80Info.OP80ItemStatusInfolist.Count > 0)
                    {
                        pieceProcess.GetQcDataCount = (pieceProcess.GetQcDataCount ?? 0) + 1;
                        pieceProcess.GetQcDataFlag_Remark = "没有找到文件";
                        if (pieceProcess.GetQcDataCount >= 10)
                        if (oP80Info.OP80ItemStatusInfolist.Any(o => !o.状态.Equals("OK")))
                        {
                            pieceProcess.GetQcDataFlag = 2;
                            logMiddle.QualityStateStr = "NG";
                        }
                        db.SaveChanges();
                        Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"OP80下线完成读取文件没有找到指定工件{info.WorkPieceID}的文件");
                        else
                        {
                            logMiddle.QualityStateStr = "OK";
                        }
                    }
                    else
                    {
                        logMiddle.QualityStateStr = "OK";
                    }
                    logMiddle.OP80QualityFilePath = file.FullName;
                    logMiddle.OP80NewCode = oP80Info.批号?.Replace("#", "");
                    //大头重量
                    logMiddle.QualityOP80To1 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Weight Big End")).FirstOrDefault()?.绝对值;
                    //小头重量
                    logMiddle.QualityOP80To2 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Weight Small End")).FirstOrDefault()?.绝对值;
                    //总重
                    logMiddle.QualityOP80To3 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Total Weight")).FirstOrDefault()?.绝对值;
                    //弯曲
                    logMiddle.QualityOP80To4 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Bend to A")).FirstOrDefault()?.绝对值;
                    //扭度
                    logMiddle.QualityOP80To5 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Twist to A")).FirstOrDefault()?.绝对值;
                    //大头垂直度
                    logMiddle.QualityOP80To6 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_C_Squareness")).FirstOrDefault()?.绝对值;
                    //小头垂直度
                    logMiddle.QualityOP80To10 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Sma_End_C_Squareness")).FirstOrDefault()?.绝对值;
                    //大头孔分组级别
                    logMiddle.QualityOP80To7 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Dime Big_End Class")).FirstOrDefault()?.状态;
                    //小头孔分组级别
                    logMiddle.QualityOP80To8 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Dime Small_End Class")).FirstOrDefault()?.状态;
                    //重量组别
                    logMiddle.QualityOP80To9 = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Weight Class")).FirstOrDefault()?.状态;
                    //wplog.Remarks = (wplog.Remarks ?? "") + $"OP80下线完成读取文件{file.FullName},数据【{wplog.OP80NewCode??"空"}】【{wplog.QualityOP80To1 ?? "空"}】【{wplog.QualityOP80To2 ?? "空"}】【{wplog.QualityOP80To3 ?? "空"}】【{wplog.QualityOP80To4 ?? "空"}】【{wplog.QualityOP80To5 ?? "空"}】";
                    //新增OP80的一些质量数据 【Editby shaocx,2024-06-13】
                    logMiddle.QualityOP80_Houdu = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Thickness")).FirstOrDefault()?.绝对值;
                    logMiddle.QualityOP80_ZXJ = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Distance of Two Head")).FirstOrDefault()?.绝对值;
                    logMiddle.QualityOP80_DTKYZD = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Cylindricity")).FirstOrDefault()?.绝对值;
                    logMiddle.QualityOP80_XTSMYD = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Top_Roundn")).FirstOrDefault()?.绝对值;
                    logMiddle.QualityOP80_XTXMYD = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Bot_Roundn")).FirstOrDefault()?.绝对值;
                    logMiddle.QualityOP80_D_S_X = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Top_X_Dia.")).FirstOrDefault()?.绝对值;
                    logMiddle.QualityOP80_D_S_Y = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Top_Y_Dia.")).FirstOrDefault()?.绝对值;
                    logMiddle.QualityOP80_D_X_X = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Bot_X_Dia.")).FirstOrDefault()?.绝对值;
                    logMiddle.QualityOP80_D_X_Y = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Big_End_Bot_Y_Dia.")).FirstOrDefault()?.绝对值;
                    //计算大头孔直径,大头孔直径=(大头上面X方向直径+大头上面Y方向直径+大头下面X方向直径+大头下面Y方向直径)/4
                    List<decimal> valueList = new List<decimal>() {
                                                        SystemHelper.GetDecimal(logMiddle.QualityOP80_D_S_X),
                                                        SystemHelper.GetDecimal(logMiddle.QualityOP80_D_S_Y),
                                                        SystemHelper.GetDecimal(logMiddle.QualityOP80_D_X_X),
                                                        SystemHelper.GetDecimal(logMiddle.QualityOP80_D_X_Y),
                                                    };
                    logMiddle.QualityOP80_D_TKZJ = SystemHelper.CalcDecimalAvg(valueList, 3);
                    logMiddle.QualityOP80_X_S_X = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Top_X_Dia.")).FirstOrDefault()?.绝对值;
                    logMiddle.QualityOP80_X_S_Y = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Top_Y_Dia.")).FirstOrDefault()?.绝对值;
                    logMiddle.QualityOP80_X_X_X = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Bot_X_Dia.")).FirstOrDefault()?.绝对值;
                    logMiddle.QualityOP80_X_X_Y = oP80Info.OP80ItemInfolist.Where(o => o.名称.Equals("Small_End_Bot_Y_Dia.")).FirstOrDefault()?.绝对值;
                    //计算小头孔直径,小头孔直径=(小头上面X方向直径+小头上面Y方向直径+小头下面X方向直径+小头下面Y方向直径)/4
                    valueList = new List<decimal>();
                    valueList = new List<decimal>() {
                                                        SystemHelper.GetDecimal(logMiddle.QualityOP80_X_S_X),
                                                        SystemHelper.GetDecimal(logMiddle.QualityOP80_X_S_Y),
                                                        SystemHelper.GetDecimal(logMiddle.QualityOP80_X_X_X),
                                                        SystemHelper.GetDecimal(logMiddle.QualityOP80_X_X_Y),
                                                    };
                    logMiddle.QualityOP80_X_TKZJ = SystemHelper.CalcDecimalAvg(valueList, 3);
                }
                else
                {
                    logMiddle.Remarks = $"OP80下线完成读取文件{file.FullName}异常,行数不是2行";
                }
                //更新WorkPieceInfo表以及插入WorkPieceLog表和WorkPieceInfoLog表
                info.OP80NewCode = logMiddle.OP80NewCode;//更新成品吗
                //如果OP80下线,已经更改了质检状态,并且质检状态等于不合格,则这里就不要继续更改质检状态了 【Editby shaocx,2024-08-28】
                bool isNeedUpdateQualityState = true;
                var ooDateTime = Convert.ToDateTime("0001-01-01");
                if (pieceProcess.EndTime != ooDateTime && pieceProcess.QualityState == (int)QualityStateEnum.NG)
                {
                    isNeedUpdateQualityState = false;
                }
                if (isNeedUpdateQualityState)
                {
                    info.QualityState = (int)((logMiddle.QualityStateStr.Equals("OK") || logMiddle.QualityStateStr.Equals("0K")) ? QualityStateEnum.OK : QualityStateEnum.NG);
                    logMiddle.QualityState = info.QualityState;
                    //根据质量数据判断是否合格/不合格 【Editby shaocx,2024-06-25】
                    WorkPieceInfoManager.SetLogMiddleForQuality(ref logMiddle);
                    //赋值不合格原因
                    WorkPieceInfoManager.SetQualityNoOk_WorkPieceInfo(logMiddle, ref info);
                    info.QualityStateUpdateUser = logMiddle.UpdatedUserName;
                    info.QualityStateUpdateTime = logMiddle.UpdatedTime.Value.LocalDateTime;
                    info.QualityStateUpdateMode = QualityStateUpdateMode.Auto.ToString();
                }
                //var qualityData = db.QualityDataInfo.Where(o => o.WorkPieceID == wplog.WorkPieceID).FirstOrDefault();
                //if (qualityData == null || qualityData.WorkPieceID.Length < 1 || qualityData.WorkingProcedure.Length < 1)
                //{//插入QualityDataInfo表
                //    qualityData = EntityPropHelper.Mapper<QualityDataInfo, WorkPieceLog>(wplog);
                //    db.QualityDataInfo.Add(GetAddQualityDataInfo(qualityData));
                //}
                //修改QualityDataInfo表 //重复收到质量信息,会覆盖之前的
                EntityPropHelper<WorkPieceLogMiddle, QualityDataInfo>.CopyProp(logMiddle, qualityData, WorkPieceInfoManager.GetQualityDataInfoUpdate(logMiddle, logMiddle.WorkingProcedure, logMiddle.MonitoringPoint));//指定修改字段
                //单独处理 质量数据的状态
                if (isNeedUpdateQualityState)
                {
                    qualityData.QualityState = (int)((logMiddle.QualityStateStr.Equals("OK") || logMiddle.QualityStateStr.Equals("0K")) ? QualityStateEnum.OK : QualityStateEnum.NG);
                }
                else
                {//必然是不合格
                    qualityData.QualityState = (int)(QualityStateEnum.NG);
                }
                qualityData.OP80QualityState = qualityData.QualityState.ToString();
                qualityData.EquipmentID = _EquipmentId;
                qualityData.QualityStateUpdateUser = info.UpdatedUserName;
                qualityData.QualityReceiveTime = info.UpdatedTime.Value.LocalDateTime;
                qualityData.QualityStateUpdateMode = info.QualityStateUpdateMode;
                qualityData.OP80QualityReceiveTime = DateTimeHelper.GetDateTime();
                qualityData.OP80QualityFilePath = logMiddle.OP80QualityFilePath;
                long op80id = qualityData.Id;
                if (op80id > 0)
                {
                    pieceProcess.QualityDataInfoID = op80id;
                }
                loginfo2.Remarks = $"质量:{logMiddle.QualityStateStr ?? "空"}";
                if (!info.QualityState.Equals(((int)QualityStateEnum.OK).ToString()))
                {
                    info.QualityErrorInfo = $"{logMiddle.WorkingProcedure}工序质量采集数据不合格";
                }
                else
                {
                    info.QualityErrorInfo = "";
                }
                pieceProcess.GetQcDataCount = (pieceProcess.GetQcDataCount ?? 0) + 1;
                pieceProcess.GetQcDataFlag_Remark = "找到文件";
                pieceProcess.GetQcDataFlag = 1;
                if (isNeedUpdateQualityState)
                {
                    //不再默认赋值为合格 【Editby shaocx,2024-08-16】
                    pieceProcess.QualityState = WorkPieceInfoManager.GetQualityStateValue(info.QualityState);
                    //赋值不合格原因
                    //TODO:需要配置OP80质量不合格的原因是啥??
                    WorkPieceInfoManager.SetQualityNoOk_WorkPieceProcess(logMiddle, ref pieceProcess);
                }
                pieceProcess.EndTime = file.LastWriteTime;//下线时间改为 文件最后修改时间 【Editby shaocx,2024-06-17】
                db.WorkPieceLog.Add(WorkPieceInfoManager.GetAddWorkPieceLog(loginfo2));//插入工件采集日志表
                db.QualityDataInfoLog.Add(WorkPieceInfoManager.GetAddQualityDataInfoLog(qualityData));//插入质量日志
                //转移文件
                foreach (var item in findFiles)
                {
                    var toPath = item.FullName.Replace("CA4GC20TD", "CA4GC20TD_COPY");
                    File.Move(item.FullName, toPath);//移动
                    allFiles.Remove(item);//集合移除
                }
                if (isAdd_WorkPieceInfo)
                {
                    db.WorkPieceInfo.Add(info);
                }
                if (isAdd_WorkPieceProcess)
                {
                    db.WorkPieceProcess.Add(pieceProcess);
                }
                if (isAdd_QualityDataInfo)
                {
                    db.QualityDataInfo.Add(qualityData);
                }
                db.SaveChanges();
                isGetQcSuccess = true;
                Log4NetHelper.WriteInfoLog(logType, $"OP80下线完成读取文件,成功处理了指定工件{info.WorkPieceID}的文件");
                if (isGetQcSuccess == false)
                {
                    pieceProcess.GetQcDataCount = (pieceProcess.GetQcDataCount ?? 0) + 1;
                    pieceProcess.GetQcDataFlag_Remark = "没有找到文件";
                    if (pieceProcess.GetQcDataCount >= 10)
                    {
                        pieceProcess.GetQcDataFlag = 2;
                    }
                    db.SaveChanges();
                    Log4NetHelper.WriteErrorLog(logType, $"OP80下线完成读取文件没有找到指定工件{info.WorkPieceID}的文件");
                }
            }
            catch (Exception ex)
            {
                Log4NetHelper.WriteErrorLog(PLCManger.GetLogTypeForWorkingProcedure(WorkingProcedure), $"指定工件{info.WorkPieceID},OP80下线完成读取文件数据时异常,避免工序完成异常:", ex);
                Log4NetHelper.WriteErrorLog(logType, $"指定工件{info.WorkPieceID},OP80下线完成读取文件数据时异常,避免工序完成异常:", ex);
            }
        }
        private void DoOtherFile(List<FileInfo> allFiles, FileInfo file, DbModel db)
        {
            var arr = file.Name.Split('-');
            if (arr.Length > 0)
            {
                if (string.IsNullOrEmpty(arr[0]))
                {
                    MoveFileToNoNum(allFiles, file);
                    Log4NetHelper.WriteErrorLog(logType, $" OP80质量数据采集异常:处理剩余的文件,转移到没有单号文件夹中,{file.Name}");
                    return;
                }
                else
                {
                    if (file.LastWriteTime > DateTime.Now.AddDays(-1))
                    {
                        //当天内的文件暂不处理
                        return;
                    }
                    //如果是15天前的文件,则转移到错误文件夹中
                    if (file.LastWriteTime.AddDays(15) < DateTime.Now)
                    {
                        MoveFileToNoError(allFiles, file);
                        Log4NetHelper.WriteErrorLog(logType, $" OP80质量数据采集异常:处理剩余的文件,转移到错误文件夹中,{file.Name}");
                        return;
                    }
                    var pieceID = arr[0];
                    if (pieceID == "Err")
                    {
                        MoveFileToNoNum(allFiles, file);
                        Log4NetHelper.WriteErrorLog(logType, $" OP80质量数据采集异常:处理剩余的文件,转移到没有单号文件夹中,{file.Name}");
                        return;
                    }
                    //调用公共处理方法
                    bool isAdd_WorkPieceInfo = false;
                    bool isAdd_WorkPieceProcess = false;
                    bool isAdd_QualityDataInfo = false;
                    WorkPieceInfo info = db.WorkPieceInfo.Where(o => o.WorkPieceID == pieceID).FirstOrDefault();
                    if (info == null)
                    {
                        isAdd_WorkPieceInfo = true;
                        info = new WorkPieceInfo()
                        {
                            Id = Yitter.IdGenerator.YitIdHelper.NextId(),
                            WorkPieceID = pieceID,
                            WorkingProcedureCurrent = query_WorkingProcedureCurrent,
                            EquipmentID = _EquipmentId,
                            CreatedTime = DateTime.Now,
                            CreatedUserName = _DataCapturePointCode,
                            DataCapturePointCname = _DataCapturePointName
                        };
                    }
                    var qualityData = db.QualityDataInfo.Where(o => o.WorkPieceID == pieceID).FirstOrDefault();
                    if (qualityData == null || qualityData.WorkPieceID.Length < 1 || qualityData.WorkingProcedure.Length < 1)
                    {//插入QualityDataInfo表
                        isAdd_QualityDataInfo = true;
                        qualityData = new QualityDataInfo()
                        {
                            Id = Yitter.IdGenerator.YitIdHelper.NextId(),
                            WorkPieceID = pieceID,
                            WorkingProcedure = query_WorkingProcedureCurrent,
                            CreatedTime = DateTime.Now,
                            CreatedUserName = _DataCapturePointCode,
                            EquipmentID = _EquipmentId,
                        };
                    }
                    var process = db.WorkPieceProcess.Where(o => o.WorkPieceID == pieceID && o.WorkingProcedureCurrent == info.WorkingProcedureCurrent && o.OperationType == OperationType.生产.ToString()).OrderByDescending(o => o.StartTime).FirstOrDefault();
                    if (process == null)
                    {
                        isAdd_WorkPieceProcess = true;
                        process = new WorkPieceProcess();
                        process = EntityPropHelper.Mapper<WorkPieceProcess, WorkPieceInfo>(info);
                        QualityStateHelper.ResetQualityNoOkForNewProcess(ref process);
                        process.Id = Yitter.IdGenerator.YitIdHelper.NextId();
                        process.WorkingProcedureCurrent = query_WorkingProcedureCurrent;
                        process.StartTime = DateTimeHelper.GetDateTime();
                        process.EndTime = file.LastWriteTime;
                        process.CreatedUserName = _DataCapturePointCode;
                        process.JiaJuGongWei = "";
                        process.DataCapturePointCname = DataCapturePointCname;
                        process.CreatedTime = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local);
                        process.UpdatedUserName = _DataCapturePointCode;
                        process.UpdateDataCapturePointCname = DataCapturePointCname;
                        process.UpdatedTime = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local);
                        process.OperationType = OperationType.生产.ToString();
                        process.Remarks = "";
                    }
                    //调用方法
                    Do_One(isAdd_WorkPieceInfo, isAdd_WorkPieceProcess, isAdd_QualityDataInfo, allFiles, db, info, process, qualityData, new List<FileInfo>() { file });
                }
            }
            else
            {
                //移除该文件到CA4GC20TD_NoNum
                MoveFileToNoNum(allFiles, file);
                Log4NetHelper.WriteErrorLog(logType, $" OP80质量数据采集异常:处理剩余的文件,转移到没有单号文件夹中,{file.Name}");
            }
        }
        private void MoveFileToNoNum(List<FileInfo> allFiles, FileInfo file)
        {
            //移除该文件到CA4GC20TD_NoNum
            var toPath = file.FullName.Replace("CA4GC20TD", "CA4GC20TD_NoNum");
            File.Move(file.FullName, toPath);//移动
            allFiles.Remove(file);
        }
        private void MoveFileToNoError(List<FileInfo> allFiles, FileInfo file)
        {
            //移除该文件到CA4GC20TD_NoNum
            var toPath = file.FullName.Replace("CA4GC20TD", "CA4GC20TD_Error");
            File.Move(file.FullName, toPath);//移动
            allFiles.Remove(file);
        }
    }
}