using Bro.Common.Helper; using Bro.Common.Interface; using Bro.Common.Model; using Bro.M135.DBManager; using Newtonsoft.Json; using static System.Windows.Forms.VisualStyles.VisualStyleElement.ListView; namespace Bro.M135.Common { public class ProductModel : P_PRODUCT { #region 构造函数 public ProductModel() { } public ProductModel(P_PRODUCT p) { ID = p.ID; CREATE_TIME = p.CREATE_TIME; PID = p.PID; SN = p.SN; SEQUENCE = p.SEQUENCE; Result = p.Result; Details = new List(p.Details); InitialDetailSpecs(); //Details.ForEach(d => //{ // if (!string.IsNullOrWhiteSpace(d.FAIData)) // { // d.SpecList = JsonConvert.DeserializeObject>(d.FAIData); // } // else // { // d.SpecList = new List(); // } // if (!string.IsNullOrWhiteSpace(d.DefectDesc)) // { // d.DefectList = JsonConvert.DeserializeObject>(d.DefectDesc); // } // else // { // d.DefectList = new List(); // } //}); } public void InitialDetailSpecs() { Details.ForEach(d => { if (!string.IsNullOrWhiteSpace(d.FAIData)) { d.SpecList = JsonConvert.DeserializeObject>(d.FAIData); } else { d.SpecList = new List(); } if (!string.IsNullOrWhiteSpace(d.DefectDesc)) { d.DefectList = JsonConvert.DeserializeObject>(d.DefectDesc); } else { d.DefectList = new List(); } }); } #endregion public bool IsPreStationOK { get; set; } = false; public DateTime? EndTime { get; set; } = null; object _checkResultLock = new object(); public object DataTag { get; set; } = null; //[NotMapped] //public List CountDownModelList = new List(); public Dictionary> PositionCheckList = new Dictionary>(); public void Initial(string stationName, List positionNames) { Details.RemoveAll(u => u.STATION_CODE == stationName); Details.AddRange(positionNames.Select(n => { P_PRODUCT_DETAIL detail = new P_PRODUCT_DETAIL(); detail.CREATE_USER = stationName; detail.PositionName = n; detail.PID = PID; detail.SN = SN; detail.IsDone = false; detail.STATION_CODE = stationName; return detail; })); } public void ClearPositionResult(string stationName, string positionName) { lock (_checkResultLock) { Details.RemoveAll(u => u.PositionName == positionName && u.STATION_CODE == stationName); } } public void AddNewDetectResults(string stationName, string positionName, List results) { lock (_checkResultLock) { var detail = Details.FirstOrDefault(u => u.PositionName == positionName && u.STATION_CODE == stationName); if (detail == null) { detail = new P_PRODUCT_DETAIL(); detail.STATION_CODE = stationName; detail.PositionName = positionName; detail.PID = PID; detail.IsDone = false; Details.Add(detail); } detail.ResultList.AddRange(results); } } public bool GetPositionResult(string stationName, string positionName, out P_PRODUCT_DETAIL detail) { detail = Details.FirstOrDefault(u => u.STATION_CODE == stationName && u.PositionName == positionName); if (detail == null) { return false; } if (!detail.IsDone) { return false; } if (detail.ResultList.Count > 0) { detail.SpecList.Clear(); detail.DefectList.Clear(); detail.ResultList.ForEach(r => r.SetResult()); var defects = detail.ResultList.GetDefectDescList(); if (defects.Count > 0) { return false; } else { return detail.ResultList.All(u => u.ResultState == EnumHelper.ResultState.OK); } } else { if (detail.SpecList.Count > 0 && detail.SpecList.Any(u => u.MeasureResult != true)) { return false; } if (detail.DefectList.Count > 0) { return false; } } return false; } #region whole product public string GetCSVHead(ref List specHeadList, ref List positionList) { string head = ""; var allSpecs = Details.SelectMany(u => u.ResultList.SelectMany(r => r.Specs)).ToList(); Details.ForEach(d => { d.SpecList.ForEach(s => { if (!allSpecs.Any(u => u.Code == s.Code)) { allSpecs.Add(s); } }); }); allSpecs.RemoveAll(u => (u.Code.ToLower() == "ngspec" || u.Code == "检测TBD")); head = $"时间,PID,栏具码,物料码,条码,汇总检测结果,"; positionList = new List(); Details = Details.OrderBy(u => u.STATION_CODE).ThenBy(u => u.PositionName).ToList(); foreach (var d in Details) { positionList.Add($"{d.STATION_CODE}_{d.PositionName}"); head += $"{d.STATION_CODE}_{d.PositionName}检测明细,"; } if (specHeadList == null || specHeadList.Count == 0) { specHeadList = allSpecs.OrderBy(x => x.Code).Select(u => u.Code).ToList(); } head += String.Join(",", specHeadList); return head; } public string GetCSVData(List specHeadList, List positionList, string specificPosition = "") { var positionDetail = Details; if (!string.IsNullOrWhiteSpace(specificPosition)) { positionDetail = positionDetail.Where(u => u.PositionName == specificPosition).ToList(); } var allSpecs = positionDetail.SelectMany(u => u.ResultList.SelectMany(r => r.Specs)).ToList(); positionDetail.ForEach(d => { d.SpecList.ForEach(s => { if (!allSpecs.Any(u => u.Code == s.Code)) { allSpecs.Add(s); } }); }); //时间,PID,栏具码,物料码,条码,汇总检测结果,"; string data = $"{DateTime.Now.ToString("yyyyMMddHHmmss")}T,{PID},{BasketCode},{SEQUENCE},{SN},{Result},"; positionList.ForEach(pName => { var detail = Details.FirstOrDefault(u => $"{u.STATION_CODE}_{u.PositionName}" == pName); if (!detail.IsDone) { data += "TBD,"; } else { var defects = detail.ResultList.GetDefectDescList(); var ngSpecCodes = detail.SpecList.Where(u => u.MeasureResult != true).Select(u => u.Code); defects.AddRange(ngSpecCodes); defects.AddRange(detail.DefectList); defects = defects.Distinct().ToList(); if (defects.Count > 0) { data += $"{string.Join(" ", defects)},"; } else { data += "OK,"; } } }); specHeadList.ForEach(s => { var spec = allSpecs.FirstOrDefault(u => u.Code == s); if (spec != null) { data += $"{spec.GetMeasureValueStr()},"; } else { data += "NA,"; } }); return data; } #endregion #region for position public string GetCSVHead(ref List specHeadList, string specificPosition) { string head = ""; var positionDetail = Details; if (!string.IsNullOrWhiteSpace(specificPosition)) { positionDetail = positionDetail.Where(u => u.PositionName == specificPosition).ToList(); } var allSpecs = positionDetail.SelectMany(u => u.ResultList.SelectMany(r => r.Specs)).ToList(); positionDetail.ForEach(d => { d.SpecList.ForEach(s => { if (!allSpecs.Any(u => u.Code == s.Code)) { allSpecs.Add(s); } }); }); allSpecs.RemoveAll(u => u.Code.ToLower() == "ngspec" || u.Code == "检测TBD"); head = $"时间,栏具码,PID,序号,条码,"; foreach (var d in positionDetail) { head += $"{d.PositionName}检测明细,"; } if (specHeadList == null || specHeadList.Count == 0) { specHeadList = allSpecs.Select(u => u.Code).OrderBy(u => u).ToList(); } head += String.Join(",", specHeadList); return head; } public string GetCSVData(List specHeadList, string specificPosition) { var positionDetail = Details; if (!string.IsNullOrWhiteSpace(specificPosition)) { positionDetail = positionDetail.Where(u => u.PositionName == specificPosition).ToList(); } var allSpecs = positionDetail.SelectMany(u => u.ResultList.SelectMany(r => r.Specs)).ToList(); positionDetail.ForEach(d => { d.SpecList.ForEach(s => { if (!allSpecs.Any(u => u.Code == s.Code)) { allSpecs.Add(s); } }); }); string data = $"{DateTime.Now.ToString("HH:mm:ss.fff")}T,{BasketCode},{PID},{SEQUENCE},{SN},"; positionDetail.ForEach(detail => { if (!detail.IsDone) { data += "TBD,"; } else { var defects = detail.ResultList.GetDefectDescList(); var ngSpecCodes = detail.SpecList.Where(u => u.MeasureResult != true).Select(u => u.Code); defects.AddRange(ngSpecCodes); defects.AddRange(detail.DefectList); defects = defects.Distinct().ToList(); if (defects.Count > 0) { data += $"{string.Join(" ", defects)},"; } else { data += "OK,"; } } }); specHeadList.ForEach(s => { var spec = allSpecs.FirstOrDefault(u => u.Code == s); if (spec != null) { data += $"{spec.GetMeasureValueStr()},"; } else { data += "NA,"; } }); //positionDetail.ForEach(detail => //{ // if (detail.IsDone) // { // var results = detail.ResultList; // var list = results.Where((DetectResult u) => u.ResultState != EnumHelper.ResultState.OK).SelectMany((DetectResult u) => u.NetResults.Where((NetResult m) => !m.IsAbandoned && m.CurResult != EnumHelper.ResultState.OK).SelectMany((NetResult m) => from n in m.DetectDetails where !n.IsAbandoned && n.FinalResult != EnumHelper.ResultState.OK select n)).ToList(); // list.ForEach(d => // { // data += $"{(d.Rect.Height * d.PixelSize).ToString("f4")},"; // data += $"{(d.Rect.Width * d.PixelSize).ToString("f4")},"; // }); // } //}); return data; } #endregion #region PositionCheckTimes public void InitialPositionCheckList(string positionName, List checkTimes,string stationName) { lock (_checkResultLock) { PositionCheckList[positionName] = new List(checkTimes); Details.RemoveAll(u => u.PositionName == positionName); P_PRODUCT_DETAIL detail = new P_PRODUCT_DETAIL(); detail.STATION_CODE = stationName; detail.PositionName = positionName; detail.PID = PID; detail.IsDone = false; Details.Add(detail); } } public bool PositoinCheckDone(string positionName, int checkIndex, out string msg) { msg = ""; lock (_checkResultLock) { if (!PositionCheckList.ContainsKey(positionName)) { msg = $"未能获取工位{positionName}的检测清单"; return false; } else { PositionCheckList[positionName].RemoveAll(u => u == checkIndex); if (PositionCheckList[positionName].Count == 0) { var detail = Details.FirstOrDefault(u => u.PositionName == positionName); if (detail == null) { msg = $"产品{PID}未能获取工位{positionName}检测结果"; CommonLogger.LogAsync(DateTime.Now, EnumHelper.LogLevel.Exception, msg); return false; } detail.IsDone = true; return true; } else { msg = $"工位{positionName}检测尚未完成,剩余{string.Join(",", PositionCheckList[positionName])}"; return false; } } } } #endregion } public class CountDownAndTimeoutModel : IDisposable { public int CountDownNum; public bool IsActionDone = false; public object CountDownLock = new object(); public System.Threading.Timer TimeoutTimer { get; set; } = null; public string PositionName { get; set; } = ""; public void Dispose() { TimeoutTimer?.Dispose(); TimeoutTimer = null; } } }