添加上报生产记录功能

This commit is contained in:
huangxianguo 2024-08-28 15:58:01 +08:00
parent e9dfd46e1d
commit 3fa0d33bd6
8 changed files with 436 additions and 15 deletions

View File

@ -0,0 +1,17 @@
namespace MasstransferExporter.DataExporter.Model;
/// <summary>
/// 动打记录
/// 每次基板动打完成后进行触发上传
/// </summary>
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<ProductionWaferRecord> Rounds { get; set; }
}

View File

@ -3,7 +3,7 @@
/// <summary>
/// 每次动打期间用到的wafer记录
/// </summary>
public class StrikeWaferRecord
public class ProductionWaferRecord
{
public string WaferNumber { get; set; }
public string ChipQuantity { get; set; }

View File

@ -1,17 +1,104 @@
namespace MasstransferExporter.DataExporter.Model;
using System.ComponentModel;
using MasstransferCommon.Model.Entity;
using MasstransferCommon.Utils;
using SQLite;
namespace MasstransferExporter.DataExporter.Model;
/// <summary>
/// 动打记录
/// 每次基板动打完成后进行触发上传
/// 动打过程记录
/// </summary>
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<StrikeWaferRecord> 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<double[]> CurrentWaferCoords
{
get => CurrentWaferCoordsJson != null ? JsonUtil.FromJson<List<double[]>>(CurrentWaferCoordsJson) : [];
set => CurrentWaferCoordsJson = value == null ? "[]" : JsonUtil.ToJson(value);
}
[Ignore]
public List<double[]> CurrentNeedleCoords
{
get => CurrentNeedleCoordsJson != null ? JsonUtil.FromJson<List<double[]>>(CurrentNeedleCoordsJson) : [];
set => CurrentNeedleCoordsJson = value == null ? "[]" : JsonUtil.ToJson(value);
}
[Ignore]
public List<double> CurrentNeedleDeep
{
get => CurrentNeedleDeepJson != null ? JsonUtil.FromJson<List<double>>(CurrentNeedleDeepJson) : [];
set => CurrentNeedleDeepJson = value == null ? "[]" : JsonUtil.ToJson(value);
}
[Ignore]
public List<double[]> OriginWaferCoords
{
get => OriginWaferCoordsJson != null ? JsonUtil.FromJson<List<double[]>>(OriginWaferCoordsJson) : [];
set => OriginWaferCoordsJson = value == null ? "[]" : JsonUtil.ToJson(value);
}
[Ignore]
public List<double[]> OriginNeedleCoords
{
get => OriginNeedleCoordsJson != null ? JsonUtil.FromJson<List<double[]>>(OriginNeedleCoordsJson) : [];
set => OriginNeedleCoordsJson = value == null ? "[]" : JsonUtil.ToJson(value);
}
[Ignore]
public double[,] OriginNeedleDeep
{
get => OriginNeedleDeepJson != null ? JsonUtil.FromJson<double[,]>(OriginNeedleDeepJson) : new double[,] { };
set => OriginNeedleDeepJson = value == null ? "[]" : JsonUtil.ToJson(value);
}
}

View File

@ -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;
/// <summary>
/// 基板信息
/// </summary>
[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<double[]> Coordinates
{
get => !CoordinateJson.IsNullOrEmpty() ? JsonUtil.FromJson<List<double[]>>(CoordinateJson) : [];
set
{
if (value != null)
{
CoordinateJson = JsonUtil.ToJson(value);
}
}
}
[Ignore]
public double[,] Altimetry
{
get => !AltimetryJson.IsNullOrEmpty() ? JsonUtil.FromJson<double[,]>(AltimetryJson) : new double[,] { };
set
{
if (value != null)
{
AltimetryJson = JsonUtil.ToJson(value);
}
}
}
}

View File

@ -0,0 +1,54 @@
using System.ComponentModel;
using MasstransferCommon.Model.Entity;
using SQLite;
namespace MasstransferExporter.DataExporter.Model;
/// <summary>
/// 基板耗时信息
/// </summary>
[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; }
}

View File

@ -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<double[]> Coordinates
{
get => !CoordinateJson.IsNullOrEmpty() ? JsonUtil.FromJson<List<double[]>>(CoordinateJson) : [];
set
{
if (value != null)
{
CoordinateJson = JsonUtil.ToJson(value);
}
}
}
}

View File

@ -0,0 +1,54 @@
using System.ComponentModel;
using MasstransferCommon.Model.Entity;
using SQLite;
namespace MasstransferExporter.DataExporter.Model;
/// <summary>
/// 晶环耗时信息
/// </summary>
[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; }
}

View File

@ -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();
/// <summary>
/// 上报动打记录
/// </summary>
private static void ReportStrikeRecord()
{
// 根据这个基板编号,从记录中找到所有的跟基板有关的生产记录
}
/// <summary>
/// 上报基板动打
/// </summary>
/// <param name="substrateId"></param>
private static async Task ReportStrikeRecord(string substrateId)
{
var sql = "select * from substrates where Id = ?";
var substrate = Db.Query<Substrate>(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<StrikeRecord>(queryStrikeRecord, substrateId);
var waferIds = strikeRecords.Select(r => r.WaferId).ToList();
// 查询出当前基板的耗时信息
var querySubstrateConsumeTime = "select * from substrate_consume_times where substrate_id = ?";
var substrateConsumeTime =
Db.Query<SubstrateConsumeTime>(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<WaferConsumeTime>(queryWaferConsumeTime);
// 查询出当前作业的所有晶环信息
var queryWafer = "select * from wafer where Id in (" + string.Join(",", waferIds) + ")";
var wafers = Db.Query<Wafer>(queryWafer);
// 将晶环耗时信息与晶环信息关联
var waferConsumeTimeDict = waferConsumeTimes.ToDictionary(time => time.WaferId);
// 将生产记录转为以晶环为key的集合
var strikeRecordDict = strikeRecords.ToDictionary(r => r.WaferId);
// 封装晶环动打记录
List<ProductionWaferRecord> 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);
}
}