using iWare_SCADA_BusinessLogical.Utils; using iWare_SCADA_Model; using System; using System.Collections.Generic; using System.Data.Entity.Validation; using System.Linq; using System.Text; using System.Threading.Tasks; namespace iWare_SCADA_BusinessLogical.BLL.Important { public class ReadQRcodeManager { /// /// 读取二维码时逻辑 /// 校验工件是否跳序,质量是否合格 /// public static void ReadQRcode(WorkPieceLog loginfo, LogType type, PLCService plcService, int? IsFeedback) {//此处同时插入了WorkPieceLog,WorkPieceInfoLog表,并新增或修改WorkPieceInfo表 using (DbModel db = new DbModel()) { try { bool isAddWorkPieceInfo = false; if (loginfo.WorkPieceID.Length == 22) { WorkPieceInfo info = new WorkPieceInfo(); info = db.WorkPieceInfo.Where(o => o.WorkPieceID == loginfo.WorkPieceID).FirstOrDefault(); if (info == null || info.WorkPieceID.Length < 1) {//插入WorkPieceInfo表 loginfo = CommonManager.Instance.GetWorkPieceID(loginfo, type); info = EntityPropHelper.Mapper(loginfo); //EntityPropHelper.CopyProp(loginfo, info, loginfo.GetWorkPieceInfoDict()); if (!loginfo.WorkingProcedure.Equals("OP05")) {//当工件二维码第一次出现的工序不是OP05,则设置为可疑状态 info.QualityState = (int)QualityStateEnum.Suspected; info.QualityErrorInfo = $"工件二维码第一次出现的工序{loginfo.MonitoringPoint}不是OP05,数据缺失,请确认情况并做相应处理!"; info.Remarks = $"工件二维码第一次出现的工序{loginfo.WorkingProcedure}不是OP05,数据缺失,请确认情况并做相应处理!"; } else {//OP05工序 info.QualityState = (int)QualityStateEnum.OK;//此处需要注意,判断所有工序质量,然后再赋值 //默认合格,OP05默认是合格 info.Remarks = "OP05新增工件信息"; } info.WorkPieceinitOnlineTime = DateTimeHelper.GetDateTime(); info.WorkingProcedurePlan = ConfigHelper.GetConfigString("WorkingProcedureAllStr") ?? "OP05OP10OP20OP30OP35OP40OP50OP60OP70OP80"; info.CreatedUserName = loginfo.MonitoringPoint; info.WorkingProcedureCurrent = loginfo.WorkingProcedure;//工序赋值 SystemBussinessHelper.SetWorkPieceInfoMiddleForCreatedUserName(ref info, loginfo.DataCapturePointCname); info.CreatedTime = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local); info = WorkPieceInfoManager.ParseQRCode(info); isAddWorkPieceInfo = true; } else { //存在 表 WorkPieceInfo有,但是 WorkPieceProcess这个工序不存在的情况 【Editby shaocx,2024-09-06】 //if (info.WorkingProcedureCurrent.Equals("OP05")) //{ // loginfo.Remarks = $"读取二维码{loginfo.WorkPieceID ?? "空"} OP05工序重复读取了"; // return; //} } if ((loginfo.WorkingProcedure.Equals("OP05") && isAddWorkPieceInfo == false)) {//存在 表 WorkPieceInfo有,但是 WorkPieceProcess这个工序不存在的情况 //如果是OP05的,并且是 不需要新增 表WorkPieceInfo,那么就不需要更新表 WorkPieceInfo } else { info.WorkingProcedureStartTime = DateTimeHelper.GetDateTime();// info.WorkingProcedureEndTime = null; info.WorkPieceState = (int)WorkPieceState.WIP; info.EquipmentID = loginfo.EquipmentID; info.QualityStateUpdateUser = loginfo.UpdatedUserName; info.QualityStateUpdateTime = loginfo.UpdatedTime.Value.LocalDateTime; info.QualityStateUpdateMode = QualityStateUpdateMode.Auto.ToString(); info.UpdatedUserName = loginfo.MonitoringPoint; SystemBussinessHelper.SetWorkPieceInfoMiddleForUpdateDataCapturePointCname(ref info, loginfo.DataCapturePointCname); info.UpdatedTime = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local); info.WorkPieceCurrentPosition = loginfo.WorkingProcedure; info.WorkPieceCurrentPositionOrder = info.WorkingProcedurePlan.IndexOf(loginfo.WorkingProcedure) / 2; info.WorkingProcedureCurrent = loginfo.WorkingProcedure;//工序赋值 info.Remarks = $"{info.WorkingProcedureCurrent}工件上线"; } //修复下 op35 同一个件 下线时间跟下一个上线时间一模一样的问题 【Editby shaocx,2024-08-27】 var isNeedAddNewProcess = true; //特殊处理OP05上线,因为他是根据文本列表内容上线的 【Editby shaocx,2024-09-03】 if (loginfo.WorkingProcedure.Equals("OP05")) { var op05Proccss = db.WorkPieceProcess.Where(o => o.WorkPieceID == loginfo.WorkPieceID && o.WorkingProcedureCurrent == loginfo.WorkingProcedure).FirstOrDefault(); if (op05Proccss != null) { isNeedAddNewProcess = false;//不需要新增了 } } else { var pro = db.WorkPieceProcess.Where(o => o.WorkPieceID == loginfo.WorkPieceID && !o.OperationType.Equals("SPC") && (o.EndTime == null || o.EndTime <= DateTime.MinValue)).OrderByDescending(o => o.StartTime).FirstOrDefault(); if (pro != null && pro.WorkPieceID.Length > 1) { if (pro.WorkingProcedureCurrent == loginfo.WorkingProcedure) {//表示工序相同 isNeedAddNewProcess = false; pro.Remarks = "又一次上线,更新结束时间"; } else { pro.EndTime = DateTimeHelper.GetDateTime(); pro.UpdatedUserName = loginfo.MonitoringPoint; pro.UpdateDataCapturePointCname = loginfo.DataCapturePointCname; pro.UpdatedTime = DateTimeHelper.GetDateTime(); pro.Remarks = "又一次上线,更新结束时间"; } } } if (isNeedAddNewProcess) { WorkPieceProcess process_70 = WorkPieceProcessHelper.CreateWorkPieceProcessForOP70(loginfo, db, info); if (process_70 != null) {//创建OP70工序,当没有70工序时,才创建 【Editby shaocx,2024-08-29】 db.WorkPieceProcess.Add(process_70); } //每次扫描上线都插入追溯表 WorkPieceProcess new_process = new WorkPieceProcess(); new_process = EntityPropHelper.Mapper(info); QualityStateHelper.ResetQualityNoOkForNewProcess(ref new_process); new_process.StartTime = DateTimeHelper.GetDateTime(); //不再默认赋值为合格 【Editby shaocx,2024-08-16】 //process.QualityState = info.QualityState.HasValue ? info.QualityState.Value : (int)QualityState.OK;//默认合格,已处理 new_process.QualityState = WorkPieceInfoManager.GetQualityStateValue(info.QualityState); if (new_process.WorkingProcedureCurrent == WorkingProcedureForHMI.OP70.ToString()) { //特殊处理OP70,因为OP70没有测量,默认合格 [Editby shaocx,2024-07-03] new_process.QualityState = (int)QualityStateEnum.OK;//默认合格,OP70默认是合格 } new_process.Id = Yitter.IdGenerator.YitIdHelper.NextId(); new_process.CreatedUserName = loginfo.MonitoringPoint; new_process.DataCapturePointCname = loginfo.DataCapturePointCname; new_process.CreatedTime = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local); new_process.UpdatedUserName = loginfo.MonitoringPoint; new_process.UpdateDataCapturePointCname = loginfo.DataCapturePointCname; new_process.UpdatedTime = DateTime.SpecifyKind(DateTime.Now, DateTimeKind.Local); new_process.OperationType = OperationType.生产.ToString(); new_process.Remarks = ""; new_process.MyRemarks = "读码上线时,每次扫描上线都插入追溯表"; if (loginfo.WorkingProcedure.Equals("OP05")) {//特殊处理OP05工序 new_process.EndTime = new_process.StartTime; //如果已经存在其他工序,那么就必须要按照其他工序的时间往前推数据 【Editby shaocx,2024-09-05】 var op05OtherProccss = db.WorkPieceProcess.Where(o => o.WorkPieceID == loginfo.WorkPieceID).OrderBy(x => x.StartTime).FirstOrDefault(); if (op05OtherProccss != null) {//说明有,那么时间就按照这个时间往前推 var _time = op05OtherProccss.StartTime.AddHours(-1); new_process.StartTime = _time; new_process.EndTime = _time; new_process.CreatedTime = _time; new_process.UpdatedTime = _time; } } db.WorkPieceProcess.Add(new_process); } //db.Database.AutoTransactionsEnabled = false;// 同一个SaveChanges默认事务, 关闭默认事务:... 好像不能用啊,后面再研究吧 if (isAddWorkPieceInfo) { db.WorkPieceInfo.Add(info); } else {//不确定info是直接会修改还是需要再次查询,待测试 //info.Remarks = "修改,具体修改逻辑待定"; } #region 判断是否跳序,或质量不符合 然后反馈PLC /* if (IsFeedback.HasValue && IsFeedback.Value == (int)FeedbackMode.FeedbackPLC) { bool checkQualityInfoCompleteFlag = false; bool plcFlag = true;//反馈给PLC的标记 string message = ""; checkQualityInfoCompleteFlag = WorkPieceInfoManager.CheckQualityInfoComplete(info, loginfo, type); if (!checkQualityInfoCompleteFlag || info.QualityState != (int)QualityStateEnum.OK) { plcFlag = false; message = !checkQualityInfoCompleteFlag ? "跳序," : ""; message += info.QualityState != (int)QualityStateEnum.OK ? "质量不符合" : ""; } } else {//读码完成若工件质量不符合或发生跳序,不用管设备是否把工件放过去,数采系统都不变更当前工序,反馈设备PLC工件不符合, //若工序后续收集点收到相关工件信息再变更当前工序, 但质量信息不变 info.WorkingProcedureCurrent = loginfo.WorkingProcedure; } //*/ #endregion #region 更新设备实时表 bool isAddEquipmentCurrentMonitor = false; EquipmentCurrentMonitor equinfo = new EquipmentCurrentMonitor(); equinfo = db.EquipmentCurrentMonitor.Where(o => o.EquipmentID == loginfo.EquipmentID).FirstOrDefault(); if (equinfo == null || equinfo.Id < 1) {//没有工件信息,不做更新 Log4NetHelper.WriteErrorLog(type, $"设备{loginfo.EquipmentID} 告警监控{loginfo.WorkingProcedure} 没有获取到设备监控信息,现新增"); equinfo = EntityPropHelper.Mapper(loginfo); equinfo.OnlineTime = DateTime.Now; isAddEquipmentCurrentMonitor = true; } else {//更新工件 equinfo.WorkPieceID = loginfo.WorkPieceID; equinfo.UpdatedUserName = loginfo.MonitoringPoint; equinfo.UpdatedTime = DateTime.Now; equinfo.OnlineTime = DateTime.Now; } if (isAddEquipmentCurrentMonitor) { equinfo.Id = Yitter.IdGenerator.YitIdHelper.NextId(); db.EquipmentCurrentMonitor.Add(equinfo); } #endregion //db.WorkPieceLog.Add(GetAddWorkPieceLog(loginfo)); db.WorkPieceInfoLog.Add(WorkPieceInfoManager.GetAddWorkPieceInfoLog(info)); //UpdateKnifeToolLift(db, loginfo);//更新刀具寿命信息 } else { loginfo.Remarks = $"上线完成读取二维码{loginfo.WorkPieceID ?? "空"}异常"; Log4NetHelper.WriteErrorLog(type, $" {loginfo.WorkingProcedure}上线监控读码标记 读取工件码数据[{loginfo.WorkPieceID ?? "空"}]时异常:"); } } catch (Exception e) { loginfo.Remarks = $"读取二维码{loginfo.WorkPieceID ?? "空"}更新数据异常{e.Message}"; Log4NetHelper.WriteErrorLog(type, $" {loginfo.WorkingProcedure}上线监控读码标记 读取工件码数据[{loginfo.WorkPieceID ?? "空"}]时异常:", e); } finally { loginfo.Id = Yitter.IdGenerator.YitIdHelper.NextId(); db.WorkPieceLog.Add(loginfo); //保存数据库的异常捕捉 [Editby shaocx,2024-08-29] try { db.SaveChanges(); } catch (DbEntityValidationException exception) { var errorMessages = exception.EntityValidationErrors .SelectMany(validationResult => validationResult.ValidationErrors) .Select(m => m.ErrorMessage); var fullErrorMessage = string.Join(", ", errorMessages); var exceptionMessage = string.Concat(exception.Message, " 验证异常消息是:", fullErrorMessage); Log4NetHelper.WriteErrorLog(type, $" {loginfo.WorkingProcedure}上线监控读码标记 读取工件码数据[{loginfo.WorkPieceID ?? "空"}],保存数据库时异常:" + exceptionMessage, exception); throw new DbEntityValidationException(exceptionMessage, exception.EntityValidationErrors); } catch (Exception) { throw; } } } } } }