469 lines
13 KiB
C#
469 lines
13 KiB
C#
using OrpaonVision.Core.Results;
|
||
using OrpaonVision.Core.Common;
|
||
using OrpaonVision.Model.Production;
|
||
using OrpaonVision.Model.Configuration;
|
||
|
||
namespace OrpaonVision.Core.Production;
|
||
|
||
/// <summary>
|
||
/// 产品会话管理服务接口。
|
||
/// </summary>
|
||
public interface IProductionSessionManagerService
|
||
{
|
||
/// <summary>
|
||
/// 进站建会话。
|
||
/// </summary>
|
||
/// <param name="request">进站请求。</param>
|
||
/// <param name="cancellationToken">取消令牌。</param>
|
||
/// <returns>会话创建结果。</returns>
|
||
Task<Result<ProductionSessionModel>> CreateSessionOnArrivalAsync(CreateSessionOnArrivalRequest request, CancellationToken cancellationToken = default);
|
||
|
||
/// <summary>
|
||
/// 离站归档会话。
|
||
/// </summary>
|
||
/// <param name="sessionId">会话ID。</param>
|
||
/// <param name="result">最终结果。</param>
|
||
/// <param name="ngReason">NG原因。</param>
|
||
/// <param name="remark">备注。</param>
|
||
/// <param name="cancellationToken">取消令牌。</param>
|
||
/// <returns>归档结果。</returns>
|
||
Task<Result> ArchiveSessionOnDepartureAsync(Guid sessionId, ProductionSessionResult result, string? ngReason = null, string? remark = null, CancellationToken cancellationToken = default);
|
||
|
||
/// <summary>
|
||
/// 更新会话进度。
|
||
/// </summary>
|
||
/// <param name="sessionId">会话ID。</param>
|
||
/// <param name="currentLayer">当前层级。</param>
|
||
/// <param name="layerStatus">层级状态。</param>
|
||
/// <param name="cancellationToken">取消令牌。</param>
|
||
/// <returns>更新结果。</returns>
|
||
Task<Result> UpdateSessionProgressAsync(Guid sessionId, int currentLayer, ProductionSessionStatus layerStatus, CancellationToken cancellationToken = default);
|
||
|
||
/// <summary>
|
||
/// 暂停会话。
|
||
/// </summary>
|
||
/// <param name="sessionId">会话ID。</param>
|
||
/// <param name="reason">暂停原因。</param>
|
||
/// <param name="cancellationToken">取消令牌。</param>
|
||
/// <returns>暂停结果。</returns>
|
||
Task<Result> PauseSessionAsync(Guid sessionId, string reason, CancellationToken cancellationToken = default);
|
||
|
||
/// <summary>
|
||
/// 恢复会话。
|
||
/// </summary>
|
||
/// <param name="sessionId">会话ID。</param>
|
||
/// <param name="reason">恢复原因。</param>
|
||
/// <param name="cancellationToken">取消令牌。</param>
|
||
/// <returns>恢复结果。</returns>
|
||
Task<Result> ResumeSessionAsync(Guid sessionId, string reason, CancellationToken cancellationToken = default);
|
||
|
||
/// <summary>
|
||
/// 取消会话。
|
||
/// </summary>
|
||
/// <param name="sessionId">会话ID。</param>
|
||
/// <param name="reason">取消原因。</param>
|
||
/// <param name="cancellationToken">取消令牌。</param>
|
||
/// <returns>取消结果。</returns>
|
||
Task<Result> CancelSessionAsync(Guid sessionId, string reason, CancellationToken cancellationToken = default);
|
||
|
||
/// <summary>
|
||
/// 获取当前活动会话。
|
||
/// </summary>
|
||
/// <param name="stationId">工位ID。</param>
|
||
/// <param name="cancellationToken">取消令牌。</param>
|
||
/// <returns>当前会话。</returns>
|
||
Task<Result<ProductionSessionModel?>> GetCurrentActiveSessionAsync(string stationId, CancellationToken cancellationToken = default);
|
||
|
||
/// <summary>
|
||
/// 获取会话详情。
|
||
/// </summary>
|
||
/// <param name="sessionId">会话ID。</param>
|
||
/// <param name="cancellationToken">取消令牌。</param>
|
||
/// <returns>会话详情。</returns>
|
||
Task<Result<ProductionSessionModel?>> GetSessionAsync(Guid sessionId, CancellationToken cancellationToken = default);
|
||
|
||
/// <summary>
|
||
/// 获取会话历史记录。
|
||
/// </summary>
|
||
/// <param name="request">查询请求。</param>
|
||
/// <param name="cancellationToken">取消令牌。</param>
|
||
/// <returns>会话列表。</returns>
|
||
Task<Result<PagedResult<ProductionSessionModel>>> GetSessionHistoryAsync(GetSessionHistoryRequest request, CancellationToken cancellationToken = default);
|
||
|
||
/// <summary>
|
||
/// 获取会话统计信息。
|
||
/// </summary>
|
||
/// <param name="request">统计请求。</param>
|
||
/// <param name="cancellationToken">取消令牌。</param>
|
||
/// <returns>统计信息。</returns>
|
||
Task<Result<ProductionSessionStatistics>> GetSessionStatisticsAsync(GetSessionStatisticsRequest request, CancellationToken cancellationToken = default);
|
||
|
||
/// <summary>
|
||
/// 导出会话记录。
|
||
/// </summary>
|
||
/// <param name="request">导出请求。</param>
|
||
/// <param name="cancellationToken">取消令牌。</param>
|
||
/// <returns>导出数据。</returns>
|
||
Task<Result<byte[]>> ExportSessionsAsync(ExportSessionsRequest request, CancellationToken cancellationToken = default);
|
||
|
||
/// <summary>
|
||
/// 批量归档会话。
|
||
/// </summary>
|
||
/// <param name="sessionIds">会话ID列表。</param>
|
||
/// <param name="cancellationToken">取消令牌。</param>
|
||
/// <returns>归档结果。</returns>
|
||
Task<Result<BatchArchiveResult>> BatchArchiveSessionsAsync(IReadOnlyList<Guid> sessionIds, CancellationToken cancellationToken = default);
|
||
|
||
/// <summary>
|
||
/// 清理过期会话。
|
||
/// </summary>
|
||
/// <param name="retentionDays">保留天数。</param>
|
||
/// <param name="cancellationToken">取消令牌。</param>
|
||
/// <returns>清理结果。</returns>
|
||
Task<Result<CleanupResult>> CleanupExpiredSessionsAsync(int retentionDays, CancellationToken cancellationToken = default);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 进站建会话请求。
|
||
/// </summary>
|
||
public sealed class CreateSessionOnArrivalRequest
|
||
{
|
||
/// <summary>
|
||
/// 产品类型ID。
|
||
/// </summary>
|
||
public Guid ProductTypeId { get; set; }
|
||
|
||
/// <summary>
|
||
/// 产品类型编码。
|
||
/// </summary>
|
||
public string ProductTypeCode { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 产品类型名称。
|
||
/// </summary>
|
||
public string ProductTypeName { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 工位ID。
|
||
/// </summary>
|
||
public string StationId { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 工位名称。
|
||
/// </summary>
|
||
public string StationName { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 操作员ID。
|
||
/// </summary>
|
||
public string OperatorId { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 操作员姓名。
|
||
/// </summary>
|
||
public string OperatorName { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 班次ID。
|
||
/// </summary>
|
||
public string ShiftId { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 班次名称。
|
||
/// </summary>
|
||
public string ShiftName { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 总层级数。
|
||
/// </summary>
|
||
public int TotalLayers { get; set; }
|
||
|
||
/// <summary>
|
||
/// 产品序列号(可选)。
|
||
/// </summary>
|
||
public string? ProductSerialNumber { get; set; }
|
||
|
||
/// <summary>
|
||
/// 进站时间(UTC)。
|
||
/// </summary>
|
||
public DateTime ArrivalTimeUtc { get; set; } = DateTime.UtcNow;
|
||
|
||
/// <summary>
|
||
/// 创建人。
|
||
/// </summary>
|
||
public string CreatedBy { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 备注。
|
||
/// </summary>
|
||
public string? Remark { get; set; }
|
||
|
||
/// <summary>
|
||
/// 扩展属性。
|
||
/// </summary>
|
||
public Dictionary<string, object> ExtendedProperties { get; set; } = new();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取会话历史记录请求。
|
||
/// </summary>
|
||
public sealed class GetSessionHistoryRequest
|
||
{
|
||
/// <summary>
|
||
/// 产品类型编码(可选)。
|
||
/// </summary>
|
||
public string? ProductTypeCode { get; set; }
|
||
|
||
/// <summary>
|
||
/// 工位ID(可选)。
|
||
/// </summary>
|
||
public string? StationId { get; set; }
|
||
|
||
/// <summary>
|
||
/// 操作员ID(可选)。
|
||
/// </summary>
|
||
public string? OperatorId { get; set; }
|
||
|
||
/// <summary>
|
||
/// 会话状态(可选)。
|
||
/// </summary>
|
||
public ProductionSessionStatus? Status { get; set; }
|
||
|
||
/// <summary>
|
||
/// 会话结果(可选)。
|
||
/// </summary>
|
||
public ProductionSessionResult? Result { get; set; }
|
||
|
||
/// <summary>
|
||
/// 开始时间(UTC)。
|
||
/// </summary>
|
||
public DateTime? StartTimeUtc { get; set; }
|
||
|
||
/// <summary>
|
||
/// 结束时间(UTC)。
|
||
/// </summary>
|
||
public DateTime? EndTimeUtc { get; set; }
|
||
|
||
/// <summary>
|
||
/// 页码(从1开始)。
|
||
/// </summary>
|
||
public int PageIndex { get; set; } = 1;
|
||
|
||
/// <summary>
|
||
/// 每页大小。
|
||
/// </summary>
|
||
public int PageSize { get; set; } = 20;
|
||
|
||
/// <summary>
|
||
/// 排序字段。
|
||
/// </summary>
|
||
public SessionSortField SortField { get; set; } = SessionSortField.StartTimeUtc;
|
||
|
||
/// <summary>
|
||
/// 排序方向。
|
||
/// </summary>
|
||
public SortDirection SortDirection { get; set; } = SortDirection.Descending;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取会话统计信息请求。
|
||
/// </summary>
|
||
public sealed class GetSessionStatisticsRequest
|
||
{
|
||
/// <summary>
|
||
/// 产品类型编码(可选)。
|
||
/// </summary>
|
||
public string? ProductTypeCode { get; set; }
|
||
|
||
/// <summary>
|
||
/// 工位ID(可选)。
|
||
/// </summary>
|
||
public string? StationId { get; set; }
|
||
|
||
/// <summary>
|
||
/// 操作员ID(可选)。
|
||
/// </summary>
|
||
public string? OperatorId { get; set; }
|
||
|
||
/// <summary>
|
||
/// 统计开始时间(UTC)。
|
||
/// </summary>
|
||
public DateTime StartTimeUtc { get; set; }
|
||
|
||
/// <summary>
|
||
/// 统计结束时间(UTC)。
|
||
/// </summary>
|
||
public DateTime EndTimeUtc { get; set; }
|
||
|
||
/// <summary>
|
||
/// 统计维度。
|
||
/// </summary>
|
||
public List<StatisticsDimension> Dimensions { get; set; } = new();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 导出会话记录请求。
|
||
/// </summary>
|
||
public sealed class ExportSessionsRequest
|
||
{
|
||
/// <summary>
|
||
/// 产品类型编码(可选)。
|
||
/// </summary>
|
||
public string? ProductTypeCode { get; set; }
|
||
|
||
/// <summary>
|
||
/// 工位ID(可选)。
|
||
/// </summary>
|
||
public string? StationId { get; set; }
|
||
|
||
/// <summary>
|
||
/// 操作员ID(可选)。
|
||
/// </summary>
|
||
public string? OperatorId { get; set; }
|
||
|
||
/// <summary>
|
||
/// 会话状态(可选)。
|
||
/// </summary>
|
||
public ProductionSessionStatus? Status { get; set; }
|
||
|
||
/// <summary>
|
||
/// 会话结果(可选)。
|
||
/// </summary>
|
||
public ProductionSessionResult? Result { get; set; }
|
||
|
||
/// <summary>
|
||
/// 开始时间(UTC)。
|
||
/// </summary>
|
||
public DateTime? StartTimeUtc { get; set; }
|
||
|
||
/// <summary>
|
||
/// 结束时间(UTC)。
|
||
/// </summary>
|
||
public DateTime? EndTimeUtc { get; set; }
|
||
|
||
/// <summary>
|
||
/// 导出格式。
|
||
/// </summary>
|
||
public ExportFormat Format { get; set; } = ExportFormat.Excel;
|
||
|
||
/// <summary>
|
||
/// 是否包含详细信息。
|
||
/// </summary>
|
||
public bool IncludeDetails { get; set; } = true;
|
||
|
||
/// <summary>
|
||
/// 是否包含扩展属性。
|
||
/// </summary>
|
||
public bool IncludeExtendedProperties { get; set; } = false;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 批量归档结果。
|
||
/// </summary>
|
||
public sealed class BatchArchiveResult
|
||
{
|
||
/// <summary>
|
||
/// 总数量。
|
||
/// </summary>
|
||
public int TotalCount { get; init; }
|
||
|
||
/// <summary>
|
||
/// 成功数量。
|
||
/// </summary>
|
||
public int SuccessCount { get; init; }
|
||
|
||
/// <summary>
|
||
/// 失败数量。
|
||
/// </summary>
|
||
public int FailureCount { get; init; }
|
||
|
||
/// <summary>
|
||
/// 失败的会话ID列表。
|
||
/// </summary>
|
||
public List<Guid> FailedSessionIds { get; init; } = new();
|
||
|
||
/// <summary>
|
||
/// 错误信息。
|
||
/// </summary>
|
||
public List<string> Errors { get; init; } = new();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 清理结果。
|
||
/// </summary>
|
||
public sealed class CleanupResult
|
||
{
|
||
/// <summary>
|
||
/// 清理的会话数量。
|
||
/// </summary>
|
||
public int CleanedCount { get; init; }
|
||
|
||
/// <summary>
|
||
/// 释放的存储空间(字节)。
|
||
/// </summary>
|
||
public long FreedSpaceBytes { get; init; }
|
||
|
||
/// <summary>
|
||
/// 清理耗时(毫秒)。
|
||
/// </summary>
|
||
public long ElapsedMilliseconds { get; init; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 会话排序字段。
|
||
/// </summary>
|
||
public enum SessionSortField
|
||
{
|
||
/// <summary>
|
||
/// 开始时间。
|
||
/// </summary>
|
||
StartTimeUtc = 0,
|
||
|
||
/// <summary>
|
||
/// 结束时间。
|
||
/// </summary>
|
||
EndTimeUtc = 1,
|
||
|
||
/// <summary>
|
||
/// 会话ID。
|
||
/// </summary>
|
||
SessionId = 2,
|
||
|
||
/// <summary>
|
||
/// 产品类型编码。
|
||
/// </summary>
|
||
ProductTypeCode = 3,
|
||
|
||
/// <summary>
|
||
/// 工位ID。
|
||
/// </summary>
|
||
StationId = 4,
|
||
|
||
/// <summary>
|
||
/// 操作员姓名。
|
||
/// </summary>
|
||
OperatorName = 5,
|
||
|
||
/// <summary>
|
||
/// 当前层级。
|
||
/// </summary>
|
||
CurrentLayer = 6
|
||
}
|
||
|
||
/// <summary>
|
||
/// 排序方向。
|
||
/// </summary>
|
||
public enum SortDirection
|
||
{
|
||
/// <summary>
|
||
/// 升序。
|
||
/// </summary>
|
||
Ascending = 0,
|
||
|
||
/// <summary>
|
||
/// 降序。
|
||
/// </summary>
|
||
Descending = 1
|
||
}
|
||
|