using Bro.Common.Helper;
|
using Bro.Common.Interface;
|
using Bro.Common.Model;
|
using Bro.M135.DBManager;
|
using Newtonsoft.Json;
|
|
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_PRODUCT_DETAIL>(p.Details);
|
InitialDetailSpecs();
|
//Details.ForEach(d =>
|
//{
|
// if (!string.IsNullOrWhiteSpace(d.FAIData))
|
// {
|
// d.SpecList = JsonConvert.DeserializeObject<List<Spec>>(d.FAIData);
|
// }
|
// else
|
// {
|
// d.SpecList = new List<Spec>();
|
// }
|
|
// if (!string.IsNullOrWhiteSpace(d.DefectDesc))
|
// {
|
// d.DefectList = JsonConvert.DeserializeObject<List<string>>(d.DefectDesc);
|
// }
|
// else
|
// {
|
// d.DefectList = new List<string>();
|
// }
|
//});
|
}
|
|
public void InitialDetailSpecs()
|
{
|
Details.ForEach(d =>
|
{
|
if (!string.IsNullOrWhiteSpace(d.FAIData))
|
{
|
d.SpecList = JsonConvert.DeserializeObject<List<ISpec>>(d.FAIData);
|
}
|
else
|
{
|
d.SpecList = new List<ISpec>();
|
}
|
|
if (!string.IsNullOrWhiteSpace(d.DefectDesc))
|
{
|
d.DefectList = JsonConvert.DeserializeObject<List<string>>(d.DefectDesc);
|
}
|
else
|
{
|
d.DefectList = new List<string>();
|
}
|
});
|
}
|
#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<CountDownAndTimeoutModel> CountDownModelList = new List<CountDownAndTimeoutModel>();
|
public Dictionary<string, List<int>> PositionCheckList = new Dictionary<string, List<int>>();
|
|
public void Initial(string stationName, List<string> 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<DetectResult> 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<string> specHeadList, ref List<string> 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);
|
}
|
});
|
});
|
|
head = $"时间,PID,栏具码,物料码,条码,汇总检测结果,";
|
|
positionList = new List<string>();
|
Details = Details.OrderBy(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<string> specHeadList, List<string> 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<string> 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);
|
}
|
});
|
});
|
|
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<string> 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<int> checkTimes)
|
{
|
lock (_checkResultLock)
|
{
|
PositionCheckList[positionName] = new List<int>(checkTimes);
|
Details.RemoveAll(u => u.PositionName == positionName);
|
}
|
}
|
|
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;
|
}
|
}
|
}
|