From 3fa0d33bd63bd194656e0d88f60451cd6b81b1a8 Mon Sep 17 00:00:00 2001 From: huangxianguo Date: Wed, 28 Aug 2024 15:58:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=B8=8A=E6=8A=A5=E7=94=9F?= =?UTF-8?q?=E4=BA=A7=E8=AE=B0=E5=BD=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataExporter/Model/ProductionRecord.cs | 17 +++ ...aferRecord.cs => ProductionWaferRecord.cs} | 2 +- .../DataExporter/Model/StrikeRecord.cs | 111 ++++++++++++++++-- .../DataExporter/Model/Substrate.cs | 69 +++++++++++ .../Model/SubstrateConsumeTime.cs | 54 +++++++++ .../DataExporter/Model/Wafer.cs | 53 +++++++++ .../DataExporter/Model/WaferConsumeTime.cs | 54 +++++++++ .../DataExporter/StrikeRecordService.cs | 91 +++++++++++++- 8 files changed, 436 insertions(+), 15 deletions(-) create mode 100644 MasstransferExporter/DataExporter/Model/ProductionRecord.cs rename MasstransferExporter/DataExporter/Model/{StrikeWaferRecord.cs => ProductionWaferRecord.cs} (93%) create mode 100644 MasstransferExporter/DataExporter/Model/Substrate.cs create mode 100644 MasstransferExporter/DataExporter/Model/SubstrateConsumeTime.cs create mode 100644 MasstransferExporter/DataExporter/Model/Wafer.cs create mode 100644 MasstransferExporter/DataExporter/Model/WaferConsumeTime.cs diff --git a/MasstransferExporter/DataExporter/Model/ProductionRecord.cs b/MasstransferExporter/DataExporter/Model/ProductionRecord.cs new file mode 100644 index 0000000..25cb44b --- /dev/null +++ b/MasstransferExporter/DataExporter/Model/ProductionRecord.cs @@ -0,0 +1,17 @@ +namespace MasstransferExporter.DataExporter.Model; + +/// +/// 动打记录 +/// 每次基板动打完成后进行触发上传 +/// +public class ProductionRecord +{ + public string BatchNumber { get; set; } + public string PcbNumber { get; set; } + public string ChipType { get; set; } + public string HitQuantity { get; set; } + public string PcbInputTimeCost { get; set; } + public string PcbScanTimeCost { get; set; } + public string PcbOutputTimeCost { get; set; } + public List Rounds { get; set; } +} \ No newline at end of file diff --git a/MasstransferExporter/DataExporter/Model/StrikeWaferRecord.cs b/MasstransferExporter/DataExporter/Model/ProductionWaferRecord.cs similarity index 93% rename from MasstransferExporter/DataExporter/Model/StrikeWaferRecord.cs rename to MasstransferExporter/DataExporter/Model/ProductionWaferRecord.cs index 97218ff..fa7e1b3 100644 --- a/MasstransferExporter/DataExporter/Model/StrikeWaferRecord.cs +++ b/MasstransferExporter/DataExporter/Model/ProductionWaferRecord.cs @@ -3,7 +3,7 @@ /// /// 每次动打期间用到的wafer记录 /// -public class StrikeWaferRecord +public class ProductionWaferRecord { public string WaferNumber { get; set; } public string ChipQuantity { get; set; } diff --git a/MasstransferExporter/DataExporter/Model/StrikeRecord.cs b/MasstransferExporter/DataExporter/Model/StrikeRecord.cs index dba48a5..ca5c04d 100644 --- a/MasstransferExporter/DataExporter/Model/StrikeRecord.cs +++ b/MasstransferExporter/DataExporter/Model/StrikeRecord.cs @@ -1,17 +1,104 @@ -namespace MasstransferExporter.DataExporter.Model; +using System.ComponentModel; +using MasstransferCommon.Model.Entity; +using MasstransferCommon.Utils; +using SQLite; + +namespace MasstransferExporter.DataExporter.Model; /// -/// 动打记录 -/// 每次基板动打完成后进行触发上传 +/// 动打过程记录 /// -public class StrikeRecord +[Table("strike_records"), Description("动打过程记录")] +public class StrikeRecord : Entity { - public string BatchNumber { get; set; } - public string PcbNumber { get; set; } - public string ChipType { get; set; } - public string HitQuantity { get; set; } - public string PcbInputTimeCost { get; set; } - public string PcbScanTimeCost { get; set; } - public string PcbOutputTimeCost { get; set; } - public List Rounds { get; set; } + [Column("batch_no"), Description("批次号")] + public string? BatchNo { get; set; } + + [Column("wafer_id"), Description("晶圆Id")] + public string? WaferId { get; set; } + + [Column("wafer_code"), Description("晶圆编号")] + public string? WaferCode { get; set; } + + [Column("jig_code"), Description("治具编号")] + public string? JigCode { get; set; } + + [Column("substrate_id"), Description("基板Id")] + public string? SubstrateId { get; set; } + + [Column("substrate_code"), Description("基板编号")] + public string? SubstrateCode { get; set; } + + [Column("start_time"), Description("开始时间")] + public DateTime? StartTime { get; set; } + + [Column("end_time"), Description("结束时间")] + public DateTime? EndTime { get; set; } + + [Column("strike_consume_time"), Description("动打耗时")] + public int StrikeConsumeTime { get; set; } + + [Column("strike_amount"), Description("动打芯片数量")] + public int StrikeAmount { get; set; } + + [Column("current_wafer_coords_json"), Description("当前晶圆坐标")] + public string? CurrentWaferCoordsJson { get; set; } + + [Column("current_needle_coords_json"), Description("当前针刺坐标")] + public string? CurrentNeedleCoordsJson { get; set; } + + [Column("current_needle_deep_json"), Description("当前针刺深度")] + public string? CurrentNeedleDeepJson { get; set; } + + [Column("origin_wafer_coords_json"), Description("当前动打原始晶圆坐标")] + public string? OriginWaferCoordsJson { get; set; } + + [Column("origin_needle_coords_json"), Description("当前动打原始针刺坐标")] + public string? OriginNeedleCoordsJson { get; set; } + + [Column("origin_needle_deep_json"), Description("当前动打原始针刺深度")] + public string? OriginNeedleDeepJson { get; set; } + + + [Ignore] + public List CurrentWaferCoords + { + get => CurrentWaferCoordsJson != null ? JsonUtil.FromJson>(CurrentWaferCoordsJson) : []; + set => CurrentWaferCoordsJson = value == null ? "[]" : JsonUtil.ToJson(value); + } + + [Ignore] + public List CurrentNeedleCoords + { + get => CurrentNeedleCoordsJson != null ? JsonUtil.FromJson>(CurrentNeedleCoordsJson) : []; + set => CurrentNeedleCoordsJson = value == null ? "[]" : JsonUtil.ToJson(value); + } + + [Ignore] + public List CurrentNeedleDeep + { + get => CurrentNeedleDeepJson != null ? JsonUtil.FromJson>(CurrentNeedleDeepJson) : []; + set => CurrentNeedleDeepJson = value == null ? "[]" : JsonUtil.ToJson(value); + } + + [Ignore] + public List OriginWaferCoords + { + get => OriginWaferCoordsJson != null ? JsonUtil.FromJson>(OriginWaferCoordsJson) : []; + set => OriginWaferCoordsJson = value == null ? "[]" : JsonUtil.ToJson(value); + } + + [Ignore] + public List OriginNeedleCoords + { + get => OriginNeedleCoordsJson != null ? JsonUtil.FromJson>(OriginNeedleCoordsJson) : []; + set => OriginNeedleCoordsJson = value == null ? "[]" : JsonUtil.ToJson(value); + } + + [Ignore] + public double[,] OriginNeedleDeep + { + get => OriginNeedleDeepJson != null ? JsonUtil.FromJson(OriginNeedleDeepJson) : new double[,] { }; + set => OriginNeedleDeepJson = value == null ? "[]" : JsonUtil.ToJson(value); + } } \ No newline at end of file diff --git a/MasstransferExporter/DataExporter/Model/Substrate.cs b/MasstransferExporter/DataExporter/Model/Substrate.cs new file mode 100644 index 0000000..c959c35 --- /dev/null +++ b/MasstransferExporter/DataExporter/Model/Substrate.cs @@ -0,0 +1,69 @@ +using System.ComponentModel; +using MasstransferCommon.Model.Entity; +using MasstransferCommon.Model.Enum; +using MasstransferCommon.Utils; +using Masuit.Tools; +using SQLite; + +namespace MasstransferExporter.DataExporter.Model; + +/// +/// 基板信息 +/// +[Table("substrates")] +public class Substrate : Entity +{ + [Column("context_id"), Description("上下文ID")] + public string? ContextId { get; set; } + + [Column("substrate_code"), Description("基板编号")] + public string? SubstrateCode { get; set; } + + [Column("jig_code"), Description("治具编号")] + public string? JigCode { get; set; } + + [Column("substrate_type"), Description("基板类型")] + public SubstrateTypeEnum SubstrateType { get; set; } + + [Column("row"), Description("基板行")] public int Row { get; set; } + + [Column("column"), Description("基板列")] public int Column { get; set; } + + [Column("batch_no"), Description("批次号")] + public string? BatchNo { get; set; } + + [Column("formula_id"), Description("配方ID")] + public string? FormulaId { get; set; } + + [Column("coordinate_json"), Description("焊点坐标信息")] + public string? CoordinateJson { get; set; } + + [Column("altimetry_json"), Description("基板测高信息")] + public string? AltimetryJson { get; set; } + + [Ignore] + public List Coordinates + { + get => !CoordinateJson.IsNullOrEmpty() ? JsonUtil.FromJson>(CoordinateJson) : []; + set + { + if (value != null) + { + CoordinateJson = JsonUtil.ToJson(value); + } + } + } + + [Ignore] + public double[,] Altimetry + { + get => !AltimetryJson.IsNullOrEmpty() ? JsonUtil.FromJson(AltimetryJson) : new double[,] { }; + set + { + if (value != null) + { + AltimetryJson = JsonUtil.ToJson(value); + } + } + } +} \ No newline at end of file diff --git a/MasstransferExporter/DataExporter/Model/SubstrateConsumeTime.cs b/MasstransferExporter/DataExporter/Model/SubstrateConsumeTime.cs new file mode 100644 index 0000000..7676f8c --- /dev/null +++ b/MasstransferExporter/DataExporter/Model/SubstrateConsumeTime.cs @@ -0,0 +1,54 @@ +using System.ComponentModel; +using MasstransferCommon.Model.Entity; +using SQLite; + +namespace MasstransferExporter.DataExporter.Model; + +/// +/// 基板耗时信息 +/// +[Table("substrate_consume_times"), Description("基板耗时信息")] +public class SubstrateConsumeTime : Entity +{ + [Column("substrate_code"), Description("基板编号")] + public string SubstrateCode { get; set; } + + [Column("substrate_id"), Description("基板ID")] + public string SubstrateId { get; set; } + + [Column("loading_start_time"), Description("开始上料时间")] + public DateTime LoadingStartTime { get; set; } + + [Column("loading_end_time"), Description("结束上料时间")] + public DateTime LoadingEndTime { get; set; } + + [Column("loading_consumed_time"), Description("上料耗时")] + public int LoadingConsumedTime { get; set; } + + [Column("unloading_start_time"), Description("开始下料时间")] + public DateTime UnloadingStartTime { get; set; } + + [Column("unloading_end_time"), Description("结束下料时间")] + public DateTime UnloadingEndTime { get; set; } + + [Column("unloading_consumed_time"), Description("下料耗时")] + public int UnloadingConsumedTime { get; set; } + + [Column("fly_start_time"), Description("开始飞拍时间")] + public DateTime FlyStartTime { get; set; } + + [Column("fly_end_time"), Description("结束飞拍时间")] + public DateTime FlyEndTime { get; set; } + + [Column("fly_consumed_time"), Description("飞拍耗时")] + public int FlyConsumedTime { get; set; } + + [Column("altimetry_start_time"), Description("开始测高时间")] + public DateTime AltimetryStartTime { get; set; } + + [Column("altimetry_end_time"), Description("结束测高时间")] + public DateTime AltimetryEndTime { get; set; } + + [Column("altimetry_consumed_time"), Description("测高耗时")] + public int AltimetryConsumedTime { get; set; } +} \ No newline at end of file diff --git a/MasstransferExporter/DataExporter/Model/Wafer.cs b/MasstransferExporter/DataExporter/Model/Wafer.cs new file mode 100644 index 0000000..b444362 --- /dev/null +++ b/MasstransferExporter/DataExporter/Model/Wafer.cs @@ -0,0 +1,53 @@ +using System.ComponentModel; +using MasstransferCommon.Model.Entity; +using MasstransferCommon.Utils; +using Masuit.Tools; +using SQLite; + +namespace MasstransferExporter.DataExporter.Model; + +[Table("wafers"), Description("晶环信息")] +public class Wafer : Entity +{ + [Column("wafer_code"), Description("晶片编号")] + public string? WaferCode { get; set; } + + [Column("batch_code"), Description("批次号")] + public string? BatchCode { get; set; } + + [Column("color"), Description("晶片颜色")] public ChipColorEnum Color { get; set; } + + [Column("context_id"), Description("上下文id")] + public string? ContextId { get; set; } + + [Column("column"), Description("列")] public int Column { get; set; } + + [Column("row"), Description("行")] public int Row { get; set; } + + [Column("layer"), Description("所在层")] public int Layer { get; set; } + + [Column("used"), Description("是否已使用")] public bool Used { get; set; } + + [Column("used_times"), Description("已使用次数")] + public int UsedTimes { get; set; } + + [Column("chip_amount"), Description("芯片数量")] + public int ChipAmount { get; set; } + + [Column("coordinate_json"), Description("芯片坐标信息")] + public string? CoordinateJson { get; set; } + + [Ignore] + public List Coordinates + { + get => !CoordinateJson.IsNullOrEmpty() ? JsonUtil.FromJson>(CoordinateJson) : []; + set + { + if (value != null) + { + CoordinateJson = JsonUtil.ToJson(value); + } + } + } + +} \ No newline at end of file diff --git a/MasstransferExporter/DataExporter/Model/WaferConsumeTime.cs b/MasstransferExporter/DataExporter/Model/WaferConsumeTime.cs new file mode 100644 index 0000000..1a68d11 --- /dev/null +++ b/MasstransferExporter/DataExporter/Model/WaferConsumeTime.cs @@ -0,0 +1,54 @@ +using System.ComponentModel; +using MasstransferCommon.Model.Entity; +using SQLite; + +namespace MasstransferExporter.DataExporter.Model; + +/// +/// 晶环耗时信息 +/// +[Table("wafer_consume_times"), Description("晶环耗时信息")] +public class WaferConsumeTime : Entity +{ + [Column("wafer_id"), Description("晶环ID")] + public string WaferId { get; set; } + + [Column("wafer_code"), Description("晶片编号")] + public string WaferCode { get; set; } + + [Column("loading_start_time"), Description("开始上料时间")] + public DateTime LoadingStartTime { get; set; } + + [Column("loading_end_time"), Description("结束上料时间")] + public DateTime LoadingEndTime { get; set; } + + [Column("loading_consumed_time"), Description("上料耗时")] + public int LoadingConsumedTime { get; set; } + + [Column("unloading_start_time"), Description("开始下料时间")] + public DateTime UnloadingStartTime { get; set; } + + [Column("unloading_end_time"), Description("结束下料时间")] + public DateTime UnloadingEndTime { get; set; } + + [Column("unloading_consumed_time"), Description("下料耗时")] + public int UnloadingConsumedTime { get; set; } + + [Column("rotate_start_time"), Description("开始旋转时间")] + public DateTime RotateStartTime { get; set; } + + [Column("rotate_end_time"), Description("结束旋转时间")] + public DateTime RotateEndTime { get; set; } + + [Column("rotate_consumed_time"), Description("旋转耗时")] + public int RotateConsumedTime { get; set; } + + [Column("fly_start_time"), Description("开始飞拍时间")] + public DateTime FlyStartTime { get; set; } + + [Column("fly_end_time"), Description("结束飞拍时间")] + public DateTime FlyEndTime { get; set; } + + [Column("fly_consumed_time"), Description("飞拍耗时")] + public int FlyConsumedTime { get; set; } +} \ No newline at end of file diff --git a/MasstransferExporter/DataExporter/StrikeRecordService.cs b/MasstransferExporter/DataExporter/StrikeRecordService.cs index b78c3db..712e04b 100644 --- a/MasstransferExporter/DataExporter/StrikeRecordService.cs +++ b/MasstransferExporter/DataExporter/StrikeRecordService.cs @@ -1,13 +1,100 @@ -namespace MasstransferExporter.DataExporter; +using MasstransferCommon.Model.Constant; +using MasstransferCommunicate.Mqtt.Client; +using MasstransferExporter.DataExporter.Model; +using MasstransferInfrastructure.Database.Sqlite; +using Masuit.Tools; +using Substrate = MasstransferCommon.Model.Entity.Substrate; + +namespace MasstransferExporter.DataExporter; public class StrikeRecordService { + private static readonly SqliteHelper Db = SqliteHelper.GetInstance(); + /// /// 上报动打记录 /// private static void ReportStrikeRecord() { // 根据这个基板编号,从记录中找到所有的跟基板有关的生产记录 - + } + + + /// + /// 上报基板动打 + /// + /// + private static async Task ReportStrikeRecord(string substrateId) + { + var sql = "select * from substrates where Id = ?"; + var substrate = Db.Query(sql, substrateId).FirstOrDefault(); + + if (substrate == null) return; + + var record = new ProductionRecord + { + BatchNumber = substrate.BatchNo, + PcbNumber = substrate.SubstrateCode, + ChipType = substrate.SubstrateType.ToString(), + HitQuantity = (substrate.Column * substrate.Row).ToString() + }; + + // 查询出跟当前的基板相关的所有生产记录 + var queryStrikeRecord = "select * from strike_records where substrate_id = ?"; + var strikeRecords = Db.Query(queryStrikeRecord, substrateId); + + var waferIds = strikeRecords.Select(r => r.WaferId).ToList(); + + // 查询出当前基板的耗时信息 + var querySubstrateConsumeTime = "select * from substrate_consume_times where substrate_id = ?"; + var substrateConsumeTime = + Db.Query(querySubstrateConsumeTime, substrateId).FirstOrDefault(); + if (substrateConsumeTime != null) + { + record.PcbInputTimeCost = substrateConsumeTime.LoadingConsumedTime.ToString(); + record.PcbOutputTimeCost = substrateConsumeTime.UnloadingConsumedTime.ToString(); + record.PcbScanTimeCost = substrateConsumeTime.FlyConsumedTime.ToString(); + } + + // 查询出当前的作业相关的晶环耗时信息 + var queryWaferConsumeTime = + "select * from wafer_consume_times where wafer_id in (" + string.Join(",", waferIds) + ")"; + + var waferConsumeTimes = Db.Query(queryWaferConsumeTime); + + // 查询出当前作业的所有晶环信息 + var queryWafer = "select * from wafer where Id in (" + string.Join(",", waferIds) + ")"; + var wafers = Db.Query(queryWafer); + + // 将晶环耗时信息与晶环信息关联 + var waferConsumeTimeDict = waferConsumeTimes.ToDictionary(time => time.WaferId); + + // 将生产记录转为以晶环为key的集合 + var strikeRecordDict = strikeRecords.ToDictionary(r => r.WaferId); + + // 封装晶环动打记录 + List waferRecords = []; + foreach (var wafer in wafers) + { + var consumeTime = waferConsumeTimeDict!.GetValueOrDefault(wafer.Id); + + var strikeRecord = strikeRecordDict.GetValueOrDefault(wafer.Id); + + var waferRecord = new ProductionWaferRecord + { + WaferNumber = wafer.WaferCode, + ChipQuantity = wafer.ChipAmount.ToString(), + WaferInputTimeCost = consumeTime.LoadingConsumedTime.ToString(), + WaferOutputTimeCost = consumeTime.UnloadingConsumedTime.ToString(), + ChipScanTimeCost = consumeTime.FlyConsumedTime.ToString(), + HitedQuantity = strikeRecord.StrikeAmount.ToString(), + }; + + waferRecords.Add(waferRecord); + } + + record.Rounds = waferRecords; + // 将结果上报 + await MessageQueueHelper.Publish(Topics.ReportProductRecord, record); } } \ No newline at end of file