版本260406

This commit is contained in:
2026-04-06 22:04:05 +08:00
parent 7dc5e73af7
commit 0b150470be
216 changed files with 98993 additions and 33 deletions

View File

@@ -0,0 +1,295 @@
namespace OrpaonVision.Core.Production.Contracts;
/// <summary>
/// 产品会话详情。
/// </summary>
public sealed class ProductSessionDetailDto
{
/// <summary>
/// 会话ID。
/// </summary>
public Guid SessionId { get; init; }
/// <summary>
/// 产品序列号。
/// </summary>
public string ProductSerialNumber { get; init; } = string.Empty;
/// <summary>
/// 机种ID。
/// </summary>
public Guid ProductTypeId { get; init; }
/// <summary>
/// 机种编码。
/// </summary>
public string ProductTypeCode { get; init; } = string.Empty;
/// <summary>
/// 机种名称。
/// </summary>
public string ProductTypeName { get; init; } = string.Empty;
/// <summary>
/// 工位ID。
/// </summary>
public Guid WorkstationId { get; init; }
/// <summary>
/// 工位名称。
/// </summary>
public string WorkstationName { get; init; } = string.Empty;
/// <summary>
/// 开始时间UTC
/// </summary>
public DateTime StartedAtUtc { get; init; }
/// <summary>
/// 结束时间UTC
/// </summary>
public DateTime? EndedAtUtc { get; init; }
/// <summary>
/// 总耗时(秒)。
/// </summary>
public decimal? TotalDurationSeconds { get; init; }
/// <summary>
/// 最终结果。
/// </summary>
public string FinalResult { get; init; } = string.Empty;
/// <summary>
/// 最终NG类型。
/// </summary>
public string? FinalNgType { get; init; }
/// <summary>
/// 操作员ID。
/// </summary>
public Guid? OperatorId { get; init; }
/// <summary>
/// 操作员姓名。
/// </summary>
public string OperatorName { get; init; } = string.Empty;
/// <summary>
/// 班次。
/// </summary>
public string Shift { get; init; } = string.Empty;
/// <summary>
/// 当前模型版本。
/// </summary>
public string ModelVersion { get; init; } = string.Empty;
/// <summary>
/// 当前规则版本。
/// </summary>
public string RuleVersion { get; init; } = string.Empty;
/// <summary>
/// 层级结果列表。
/// </summary>
public IReadOnlyList<LayerResultDto> LayerResults { get; init; } = [];
/// <summary>
/// 异常记录列表。
/// </summary>
public IReadOnlyList<AbnormalRecordDto> AbnormalRecords { get; init; } = [];
/// <summary>
/// 关键截图列表。
/// </summary>
public IReadOnlyList<KeyScreenshotDto> KeyScreenshots { get; init; } = [];
}
/// <summary>
/// 层级结果。
/// </summary>
public sealed class LayerResultDto
{
/// <summary>
/// 层级结果ID。
/// </summary>
public Guid LayerResultId { get; init; }
/// <summary>
/// 层级ID。
/// </summary>
public Guid LayerId { get; init; }
/// <summary>
/// 层级名称。
/// </summary>
public string LayerName { get; init; } = string.Empty;
/// <summary>
/// 层级序号。
/// </summary>
public int LayerSequence { get; init; }
/// <summary>
/// 开始时间UTC
/// </summary>
public DateTime StartedAtUtc { get; init; }
/// <summary>
/// 结束时间UTC
/// </summary>
public DateTime? EndedAtUtc { get; init; }
/// <summary>
/// 层级结果。
/// </summary>
public string Result { get; init; } = string.Empty;
/// <summary>
/// NG类型。
/// </summary>
public string? NgType { get; init; }
/// <summary>
/// 检测次数。
/// </summary>
public int DetectionCount { get; init; }
/// <summary>
/// 平均检测时间(毫秒)。
/// </summary>
public decimal AverageDetectionTimeMs { get; init; }
/// <summary>
/// 应装部件数量。
/// </summary>
public int RequiredPartsCount { get; init; }
/// <summary>
/// 已装部件数量。
/// </summary>
public int InstalledPartsCount { get; init; }
/// <summary>
/// 到位部件数量。
/// </summary>
public int PositionedPartsCount { get; init; }
}
/// <summary>
/// 异常记录。
/// </summary>
public sealed class AbnormalRecordDto
{
/// <summary>
/// 异常记录ID。
/// </summary>
public Guid RecordId { get; init; }
/// <summary>
/// 异常类型。
/// </summary>
public string AbnormalType { get; init; } = string.Empty;
/// <summary>
/// 异常描述。
/// </summary>
public string Description { get; init; } = string.Empty;
/// <summary>
/// 发生时间UTC
/// </summary>
public DateTime OccurredAtUtc { get; init; }
/// <summary>
/// 相关层级ID。
/// </summary>
public Guid? LayerId { get; init; }
/// <summary>
/// 相关层级名称。
/// </summary>
public string? LayerName { get; init; }
/// <summary>
/// 严重程度。
/// </summary>
public string Severity { get; init; } = string.Empty;
/// <summary>
/// 是否已处理。
/// </summary>
public bool IsHandled { get; init; }
/// <summary>
/// 处理时间UTC
/// </summary>
public DateTime? HandledAtUtc { get; init; }
/// <summary>
/// 处理人。
/// </summary>
public string? HandledBy { get; init; }
/// <summary>
/// 处理备注。
/// </summary>
public string? HandlingRemark { get; init; }
}
/// <summary>
/// 关键截图。
/// </summary>
public sealed class KeyScreenshotDto
{
/// <summary>
/// 截图ID。
/// </summary>
public Guid ScreenshotId { get; init; }
/// <summary>
/// 截图类型。
/// </summary>
public string ScreenshotType { get; init; } = string.Empty;
/// <summary>
/// 截图描述。
/// </summary>
public string Description { get; init; } = string.Empty;
/// <summary>
/// 拍摄时间UTC
/// </summary>
public DateTime CapturedAtUtc { get; init; }
/// <summary>
/// 相关层级ID。
/// </summary>
public Guid? LayerId { get; init; }
/// <summary>
/// 相关层级名称。
/// </summary>
public string? LayerName { get; init; }
/// <summary>
/// 图片文件路径。
/// </summary>
public string ImageFilePath { get; init; } = string.Empty;
/// <summary>
/// 缩略图文件路径。
/// </summary>
public string ThumbnailPath { get; init; } = string.Empty;
/// <summary>
/// 检测结果JSON
/// </summary>
public string DetectionResultJson { get; init; } = string.Empty;
/// <summary>
/// 文件大小(字节)。
/// </summary>
public long FileSizeBytes { get; init; }
}

View File

@@ -0,0 +1,465 @@
namespace OrpaonVision.Core.Production.Contracts;
/// <summary>
/// 实时生产状态。
/// </summary>
public sealed class RealtimeProductionStatusDto
{
/// <summary>
/// 工位ID。
/// </summary>
public Guid WorkstationId { get; init; }
/// <summary>
/// 工位名称。
/// </summary>
public string WorkstationName { get; init; } = string.Empty;
/// <summary>
/// 当前状态。
/// </summary>
public string CurrentStatus { get; init; } = string.Empty;
/// <summary>
/// 当前产品序列号。
/// </summary>
public string? CurrentProductSerialNumber { get; init; }
/// <summary>
/// 当前机种编码。
/// </summary>
public string? CurrentProductTypeCode { get; init; }
/// <summary>
/// 当前层级名称。
/// </summary>
public string? CurrentLayerName { get; init; }
/// <summary>
/// 当前层级序号。
/// </summary>
public int? CurrentLayerSequence { get; init; }
/// <summary>
/// 当前操作员姓名。
/// </summary>
public string? CurrentOperatorName { get; init; }
/// <summary>
/// 当前班次。
/// </summary>
public string? CurrentShift { get; init; }
/// <summary>
/// 今日OK数量。
/// </summary>
public long TodayOkCount { get; init; }
/// <summary>
/// 今日NG数量。
/// </summary>
public long TodayNgCount { get; init; }
/// <summary>
/// 今日良率。
/// </summary>
public decimal TodayYieldRate { get; init; }
/// <summary>
/// 当前班次OK数量。
/// </summary>
public long ShiftOkCount { get; init; }
/// <summary>
/// 当前班次NG数量。
/// </summary>
public long ShiftNgCount { get; init; }
/// <summary>
/// 当前班次良率。
/// </summary>
public decimal ShiftYieldRate { get; init; }
/// <summary>
/// 平均节拍(秒)。
/// </summary>
public decimal AverageCycleTimeSeconds { get; init; }
/// <summary>
/// 设备运行状态。
/// </summary>
public string DeviceStatus { get; init; } = string.Empty;
/// <summary>
/// 最后更新时间UTC
/// </summary>
public DateTime LastUpdatedAtUtc { get; init; }
/// <summary>
/// 连续正常生产数量。
/// </summary>
public int ConsecutiveOkCount { get; init; }
/// <summary>
/// 最近一次NG时间UTC
/// </summary>
public DateTime? LastNgAtUtc { get; init; }
/// <summary>
/// 最近一次NG类型。
/// </summary>
public string? LastNgType { get; init; }
}
/// <summary>
/// 质量分析报告。
/// </summary>
public sealed class QualityAnalysisReportDto
{
/// <summary>
/// 报告时间范围开始UTC
/// </summary>
public DateTime StartTimeUtc { get; init; }
/// <summary>
/// 报告时间范围结束UTC
/// </summary>
public DateTime EndTimeUtc { get; init; }
/// <summary>
/// 工位名称。
/// </summary>
public string WorkstationName { get; init; } = string.Empty;
/// <summary>
/// 总体质量指标。
/// </summary>
public OverallQualityMetricsDto OverallMetrics { get; init; } = new();
/// <summary>
/// NG类型分析。
/// </summary>
public IReadOnlyList<NgTypeAnalysisDto> NgTypeAnalysis { get; init; } = [];
/// <summary>
/// 机种质量对比。
/// </summary>
public IReadOnlyList<ProductTypeQualityDto> ProductTypeQuality { get; init; } = [];
/// <summary>
/// 层级质量分析。
/// </summary>
public IReadOnlyList<LayerQualityAnalysisDto> LayerQualityAnalysis { get; init; } = [];
/// <summary>
/// 操作员质量分析。
/// </summary>
public IReadOnlyList<OperatorQualityAnalysisDto> OperatorQualityAnalysis { get; init; } = [];
/// <summary>
/// 时间趋势分析。
/// </summary>
public IReadOnlyList<QualityTrendDto> QualityTrends { get; init; } = [];
/// <summary>
/// 改进建议。
/// </summary>
public IReadOnlyList<ImprovementSuggestionDto> ImprovementSuggestions { get; init; } = [];
}
/// <summary>
/// 总体质量指标。
/// </summary>
public sealed class OverallQualityMetricsDto
{
/// <summary>
/// 总产品数量。
/// </summary>
public long TotalProducts { get; init; }
/// <summary>
/// OK产品数量。
/// </summary>
public long OkProducts { get; init; }
/// <summary>
/// NG产品数量。
/// </summary>
public long NgProducts { get; init; }
/// <summary>
/// 良率。
/// </summary>
public decimal YieldRate { get; init; }
/// <summary>
/// 目标良率。
/// </summary>
public decimal TargetYieldRate { get; init; }
/// <summary>
/// 良率达成率。
/// </summary>
public decimal YieldRateAchievement { get; init; }
/// <summary>
/// 平均节拍(秒)。
/// </summary>
public decimal AverageCycleTimeSeconds { get; init; }
/// <summary>
/// 目标节拍(秒)。
/// </summary>
public decimal TargetCycleTimeSeconds { get; init; }
/// <summary>
/// 节拍达成率。
/// </summary>
public decimal CycleTimeAchievement { get; init; }
/// <summary>
/// 质量评分0-100
/// </summary>
public decimal QualityScore { get; init; }
/// <summary>
/// 质量等级。
/// </summary>
public string QualityGrade { get; init; } = string.Empty;
}
/// <summary>
/// NG类型分析。
/// </summary>
public sealed class NgTypeAnalysisDto
{
/// <summary>
/// NG类型。
/// </summary>
public string NgType { get; init; } = string.Empty;
/// <summary>
/// NG类型描述。
/// </summary>
public string Description { get; init; } = string.Empty;
/// <summary>
/// NG数量。
/// </summary>
public long Count { get; init; }
/// <summary>
/// 占比。
/// </summary>
public decimal Percentage { get; init; }
/// <summary>
/// 严重程度。
/// </summary>
public string Severity { get; init; } = string.Empty;
/// <summary>
/// 主要发生层级。
/// </summary>
public string MainLayer { get; init; } = string.Empty;
/// <summary>
/// 趋势(上升/下降/稳定)。
/// </summary>
public string Trend { get; init; } = string.Empty;
/// <summary>
/// 趋势变化率。
/// </summary>
public decimal TrendChangeRate { get; init; }
}
/// <summary>
/// 机种质量对比。
/// </summary>
public sealed class ProductTypeQualityDto
{
/// <summary>
/// 机种编码。
/// </summary>
public string ProductTypeCode { get; init; } = string.Empty;
/// <summary>
/// 机种名称。
/// </summary>
public string ProductTypeName { get; init; } = string.Empty;
/// <summary>
/// 产品数量。
/// </summary>
public long ProductCount { get; init; }
/// <summary>
/// 良率。
/// </summary>
public decimal YieldRate { get; init; }
/// <summary>
/// 平均节拍(秒)。
/// </summary>
public decimal AverageCycleTimeSeconds { get; init; }
/// <summary>
/// 质量排名。
/// </summary>
public int QualityRanking { get; init; }
/// <summary>
/// 效率排名。
/// </summary>
public int EfficiencyRanking { init; get; }
}
/// <summary>
/// 层级质量分析。
/// </summary>
public sealed class LayerQualityAnalysisDto
{
/// <summary>
/// 层级名称。
/// </summary>
public string LayerName { get; init; } = string.Empty;
/// <summary>
/// 层级序号。
/// </summary>
public int LayerSequence { get; init; }
/// <summary>
/// 检测次数。
/// </summary>
public long DetectionCount { get; init; }
/// <summary>
/// NG次数。
/// </summary>
public long NgCount { get; init; }
/// <summary>
/// NG率。
/// </summary>
public decimal NgRate { get; init; }
/// <summary>
/// 平均检测时间(毫秒)。
/// </summary>
public decimal AverageDetectionTimeMs { get; init; }
/// <summary>
/// 风险等级。
/// </summary>
public string RiskLevel { get; init; } = string.Empty;
}
/// <summary>
/// 操作员质量分析。
/// </summary>
public sealed class OperatorQualityAnalysisDto
{
/// <summary>
/// 操作员姓名。
/// </summary>
public string OperatorName { get; init; } = string.Empty;
/// <summary>
/// 班次。
/// </summary>
public string Shift { get; init; } = string.Empty;
/// <summary>
/// 产品数量。
/// </summary>
public long ProductCount { get; init; }
/// <summary>
/// 良率。
/// </summary>
public decimal YieldRate { get; init; }
/// <summary>
/// 平均节拍(秒)。
/// </summary>
public decimal AverageCycleTimeSeconds { get; init; }
/// <summary>
/// 技能等级。
/// </summary>
public string SkillLevel { get; init; } = string.Empty;
/// <summary>
/// 绩效评分。
/// </summary>
public decimal PerformanceScore { get; init; }
}
/// <summary>
/// 质量趋势。
/// </summary>
public sealed class QualityTrendDto
{
/// <summary>
/// 时间点UTC
/// </summary>
public DateTime TimePointUtc { get; init; }
/// <summary>
/// 良率。
/// </summary>
public decimal YieldRate { get; init; }
/// <summary>
/// 产品数量。
/// </summary>
public long ProductCount { get; init; }
/// <summary>
/// 移动平均良率。
/// </summary>
public decimal MovingAverageYieldRate { get; init; }
}
/// <summary>
/// 改进建议。
/// </summary>
public sealed class ImprovementSuggestionDto
{
/// <summary>
/// 建议类型。
/// </summary>
public string SuggestionType { get; init; } = string.Empty;
/// <summary>
/// 建议标题。
/// </summary>
public string Title { get; init; } = string.Empty;
/// <summary>
/// 建议描述。
/// </summary>
public string Description { get; init; } = string.Empty;
/// <summary>
/// 优先级。
/// </summary>
public string Priority { get; init; } = string.Empty;
/// <summary>
/// 预期效果。
/// </summary>
public string ExpectedImpact { get; init; } = string.Empty;
/// <summary>
/// 实施难度。
/// </summary>
public string ImplementationDifficulty { get; init; } = string.Empty;
/// <summary>
/// 相关数据支持。
/// </summary>
public string SupportingData { get; init; } = string.Empty;
}

View File

@@ -0,0 +1,297 @@
namespace OrpaonVision.Core.Production.Contracts;
/// <summary>
/// 生产统计详情。
/// </summary>
public sealed class ProductionStatisticsDto
{
/// <summary>
/// 统计时间范围开始UTC
/// </summary>
public DateTime StartTimeUtc { get; init; }
/// <summary>
/// 统计时间范围结束UTC
/// </summary>
public DateTime EndTimeUtc { get; init; }
/// <summary>
/// 工位ID。
/// </summary>
public Guid? WorkstationId { get; init; }
/// <summary>
/// 工位名称。
/// </summary>
public string WorkstationName { get; init; } = string.Empty;
/// <summary>
/// 班次。
/// </summary>
public string Shift { get; init; } = string.Empty;
/// <summary>
/// 总产品数量。
/// </summary>
public long TotalProducts { get; init; }
/// <summary>
/// OK产品数量。
/// </summary>
public long OkProducts { get; init; }
/// <summary>
/// NG产品数量。
/// </summary>
public long NgProducts { get; init; }
/// <summary>
/// 良率。
/// </summary>
public decimal YieldRate { get; init; }
/// <summary>
/// 平均节拍(秒)。
/// </summary>
public decimal AverageCycleTimeSeconds { get; init; }
/// <summary>
/// 最快节拍(秒)。
/// </summary>
public decimal FastestCycleTimeSeconds { get; init; }
/// <summary>
/// 最慢节拍(秒)。
/// </summary>
public decimal SlowestCycleTimeSeconds { get; init; }
/// <summary>
/// 按机种分组的统计。
/// </summary>
public IReadOnlyList<ProductTypeStatisticsDto> ProductTypeStatistics { get; init; } = [];
/// <summary>
/// 按NG类型分组的统计。
/// </summary>
public IReadOnlyList<NgTypeStatisticsDto> NgTypeStatistics { get; init; } = [];
/// <summary>
/// 按层级分组的统计。
/// </summary>
public IReadOnlyList<LayerStatisticsDto> LayerStatistics { get; init; } = [];
/// <summary>
/// 按小时分组的统计。
/// </summary>
public IReadOnlyList<HourlyProductionDto> HourlyStatistics { get; init; } = [];
/// <summary>
/// 操作员统计。
/// </summary>
public IReadOnlyList<OperatorStatisticsDto> OperatorStatistics { get; init; } = [];
}
/// <summary>
/// 机种统计。
/// </summary>
public sealed class ProductTypeStatisticsDto
{
/// <summary>
/// 机种ID。
/// </summary>
public Guid ProductTypeId { get; init; }
/// <summary>
/// 机种编码。
/// </summary>
public string ProductTypeCode { get; init; } = string.Empty;
/// <summary>
/// 机种名称。
/// </summary>
public string ProductTypeName { get; init; } = string.Empty;
/// <summary>
/// 产品数量。
/// </summary>
public long Count { get; init; }
/// <summary>
/// OK数量。
/// </summary>
public long OkCount { get; init; }
/// <summary>
/// NG数量。
/// </summary>
public long NgCount { get; init; }
/// <summary>
/// 良率。
/// </summary>
public decimal YieldRate { get; init; }
/// <summary>
/// 平均节拍(秒)。
/// </summary>
public decimal AverageCycleTimeSeconds { get; init; }
}
/// <summary>
/// NG类型统计。
/// </summary>
public sealed class NgTypeStatisticsDto
{
/// <summary>
/// NG类型。
/// </summary>
public string NgType { get; init; } = string.Empty;
/// <summary>
/// NG类型描述。
/// </summary>
public string NgTypeDescription { get; init; } = string.Empty;
/// <summary>
/// NG数量。
/// </summary>
public long Count { get; init; }
/// <summary>
/// 占比。
/// </summary>
public decimal Percentage { get; init; }
/// <summary>
/// 主要发生的层级。
/// </summary>
public string MainLayer { get; init; } = string.Empty;
}
/// <summary>
/// 层级统计。
/// </summary>
public sealed class LayerStatisticsDto
{
/// <summary>
/// 层级ID。
/// </summary>
public Guid LayerId { get; init; }
/// <summary>
/// 层级名称。
/// </summary>
public string LayerName { get; init; } = string.Empty;
/// <summary>
/// 层级序号。
/// </summary>
public int LayerSequence { get; init; }
/// <summary>
/// 检测次数。
/// </summary>
public long DetectionCount { get; init; }
/// <summary>
/// NG次数。
/// </summary>
public long NgCount { get; init; }
/// <summary>
/// NG率。
/// </summary>
public decimal NgRate { get; init; }
/// <summary>
/// 平均检测时间(毫秒)。
/// </summary>
public decimal AverageDetectionTimeMs { get; init; }
}
/// <summary>
/// 每小时生产统计。
/// </summary>
public sealed class HourlyProductionDto
{
/// <summary>
/// 小时0-23
/// </summary>
public int Hour { get; init; }
/// <summary>
/// 产品数量。
/// </summary>
public long ProductCount { get; init; }
/// <summary>
/// OK数量。
/// </summary>
public long OkCount { get; init; }
/// <summary>
/// NG数量。
/// </summary>
public long NgCount { get; init; }
/// <summary>
/// 良率。
/// </summary>
public decimal YieldRate { get; init; }
/// <summary>
/// 平均节拍(秒)。
/// </summary>
public decimal AverageCycleTimeSeconds { get; init; }
}
/// <summary>
/// 操作员统计。
/// </summary>
public sealed class OperatorStatisticsDto
{
/// <summary>
/// 操作员ID。
/// </summary>
public Guid OperatorId { get; init; }
/// <summary>
/// 操作员姓名。
/// </summary>
public string OperatorName { get; init; } = string.Empty;
/// <summary>
/// 班次。
/// </summary>
public string Shift { get; init; } = string.Empty;
/// <summary>
/// 产品数量。
/// </summary>
public long ProductCount { get; init; }
/// <summary>
/// OK数量。
/// </summary>
public long OkCount { get; init; }
/// <summary>
/// NG数量。
/// </summary>
public long NgCount { get; init; }
/// <summary>
/// 良率。
/// </summary>
public decimal YieldRate { get; init; }
/// <summary>
/// 平均节拍(秒)。
/// </summary>
public decimal AverageCycleTimeSeconds { get; init; }
/// <summary>
/// 工作时长(小时)。
/// </summary>
public decimal WorkingHours { get; init; }
}

View File

@@ -0,0 +1,203 @@
namespace OrpaonVision.Core.Production.Contracts.Queries;
/// <summary>
/// 产品会话查询条件。
/// </summary>
public sealed class ProductSessionQueryDto
{
/// <summary>
/// 产品序列号(精确匹配)。
/// </summary>
public string? ProductSerialNumber { get; init; }
/// <summary>
/// 产品序列号(模糊匹配)。
/// </summary>
public string? ProductSerialNumberLike { get; init; }
/// <summary>
/// 机种ID。
/// </summary>
public Guid? ProductTypeId { get; init; }
/// <summary>
/// 机种编码。
/// </summary>
public string? ProductTypeCode { get; init; }
/// <summary>
/// 工位ID。
/// </summary>
public Guid? WorkstationId { get; init; }
/// <summary>
/// 工位名称。
/// </summary>
public string? WorkstationName { get; init; }
/// <summary>
/// 操作员ID。
/// </summary>
public Guid? OperatorId { get; init; }
/// <summary>
/// 操作员姓名。
/// </summary>
public string? OperatorName { get; init; }
/// <summary>
/// 班次。
/// </summary>
public string? Shift { get; init; }
/// <summary>
/// 最终结果。
/// </summary>
public string? FinalResult { get; init; }
/// <summary>
/// 最终NG类型。
/// </summary>
public string? FinalNgType { get; init; }
/// <summary>
/// 开始时间范围开始UTC
/// </summary>
public DateTime? StartedAtUtcStart { get; init; }
/// <summary>
/// 开始时间范围结束UTC
/// </summary>
public DateTime? StartedAtUtcEnd { get; init; }
/// <summary>
/// 模型版本。
/// </summary>
public string? ModelVersion { get; init; }
/// <summary>
/// 规则版本。
/// </summary>
public string? RuleVersion { get; init; }
/// <summary>
/// 是否包含异常记录。
/// </summary>
public bool? HasAbnormalRecords { get; init; }
/// <summary>
/// 是否包含关键截图。
/// </summary>
public bool? HasKeyScreenshots { get; init; }
/// <summary>
/// 最小耗时(秒)。
/// </summary>
public decimal? MinDurationSeconds { get; init; }
/// <summary>
/// 最大耗时(秒)。
/// </summary>
public decimal? MaxDurationSeconds { get; init; }
/// <summary>
/// 页码从1开始
/// </summary>
public int PageIndex { get; init; } = 1;
/// <summary>
/// 每页大小。
/// </summary>
public int PageSize { get; init; } = 20;
/// <summary>
/// 排序字段。
/// </summary>
public string SortField { get; init; } = "StartedAtUtc";
/// <summary>
/// 排序方向ASC/DESC
/// </summary>
public string SortDirection { get; init; } = "DESC";
}
/// <summary>
/// 生产统计查询条件。
/// </summary>
public sealed class ProductionStatisticsQueryDto
{
/// <summary>
/// 统计时间范围开始UTC
/// </summary>
public DateTime StartTimeUtc { get; init; }
/// <summary>
/// 统计时间范围结束UTC
/// </summary>
public DateTime EndTimeUtc { get; init; }
/// <summary>
/// 工位ID。
/// </summary>
public Guid? WorkstationId { get; init; }
/// <summary>
/// 工位名称。
/// </summary>
public string? WorkstationName { get; init; }
/// <summary>
/// 机种ID。
/// </summary>
public Guid? ProductTypeId { get; init; }
/// <summary>
/// 机种编码。
/// </summary>
public string? ProductTypeCode { get; init; }
/// <summary>
/// 班次。
/// </summary>
public string? Shift { get; init; }
/// <summary>
/// 操作员ID。
/// </summary>
public Guid? OperatorId { get; init; }
/// <summary>
/// 操作员姓名。
/// </summary>
public string? OperatorName { get; init; }
/// <summary>
/// 是否包含详细统计。
/// </summary>
public bool IncludeDetailedStatistics { get; init; } = true;
/// <summary>
/// 统计粒度Hour/Day/Week/Month
/// </summary>
public string Granularity { get; init; } = "Hour";
/// <summary>
/// 是否按层级分组。
/// </summary>
public bool GroupByLayer { get; init; } = true;
/// <summary>
/// 是否按NG类型分组。
/// </summary>
public bool GroupByNgType { get; init; } = true;
/// <summary>
/// 是否按操作员分组。
/// </summary>
public bool GroupByOperator { get; init; } = true;
/// <summary>
/// 最小样本数(用于统计过滤)。
/// </summary>
public int? MinSampleCount { get; init; }
}