using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using OrpaonVision.Core.ManualOverride; using OrpaonVision.Core.Results; using OrpaonVision.Core.Common; using System.Collections.Concurrent; using System.Text.Json; using CoreAuditLevel = OrpaonVision.Core.ManualOverride.AuditLevel; namespace OrpaonVision.SiteApp.Runtime.Services; /// /// 人工复位放行服务最小实现。 /// public sealed class ManualOverrideService : IManualOverrideService { private readonly ILogger _logger; public ManualOverrideService(ILogger logger, IOptions options) { _logger = logger; _ = options; } public Task>> GetOverrideableSessionsAsync(DateTime startTime, DateTime endTime, string? productTypeCode = null, OverrideStatus? overrideStatus = null, CancellationToken cancellationToken = default) { IReadOnlyList sessions = Array.Empty(); return Task.FromResult(Result>.Success(sessions)); } public Task> GetOverridePermissionAsync(Guid sessionId, string operatorId, CancellationToken cancellationToken = default) { var permission = new OverridePermission { PermissionId = Guid.NewGuid(), SessionId = sessionId, OperatorId = operatorId, OperatorName = operatorId, OperatorPermissionLevel = OrpaonVision.Core.ManualOverride.OperatorPermissionLevel.Administrator, HasPermission = true, PermissionReason = "最小实现:默认允许" }; return Task.FromResult(Result.Success(permission)); } public Task> ValidateOverrideConditionsAsync(Guid sessionId, ManualOverrideRequest overrideRequest, CancellationToken cancellationToken = default) { var result = new OverrideValidationResult { ValidationId = Guid.NewGuid(), SessionId = sessionId, RequestId = overrideRequest.RequestId, IsValid = true, ValidationResult = ValidationResult.Pass, ValidationMessage = "最小实现:验证通过", ValidationTimeUtc = DateTime.UtcNow, ValidationElapsedMs = 0 }; return Task.FromResult(Result.Success(result)); } public Task> ExecuteManualOverrideAsync(ManualOverrideRequest overrideRequest, CancellationToken cancellationToken = default) { var result = new ManualOverrideResult { OverrideId = Guid.NewGuid(), RequestId = overrideRequest.RequestId, SessionId = overrideRequest.SessionId, OverrideResult = OverrideResult.Success, OverrideStatus = OverrideStatus.Overridden, OverrideMessage = "最小实现:执行成功", ExecutionTimeUtc = DateTime.UtcNow, ExecutionElapsedMs = 0, Executor = overrideRequest.OperatorName, AffectedSessionStatus = overrideRequest.TargetStatus }; return Task.FromResult(Result.Success(result)); } public async Task> ExecuteBatchManualOverrideAsync(IReadOnlyList overrideRequests, CancellationToken cancellationToken = default) { var results = new List(); foreach (var request in overrideRequests) { var one = await ExecuteManualOverrideAsync(request, cancellationToken); if (one.Data != null) { results.Add(one.Data); } } var batch = new BatchManualOverrideResult { BatchId = Guid.NewGuid(), TotalRequestCount = overrideRequests.Count, SuccessCount = results.Count, FailureCount = Math.Max(0, overrideRequests.Count - results.Count), Results = results, BatchMessage = "最小实现:批量执行完成", BatchExecutionTimeUtc = DateTime.UtcNow, BatchExecutionElapsedMs = 0 }; return Result.Success(batch); } public Task>> GetOverrideHistoryAsync(DateTime startTime, DateTime endTime, string? operatorId = null, OverrideResult? overrideResult = null, CancellationToken cancellationToken = default) { IReadOnlyList history = Array.Empty(); return Task.FromResult(Result>.Success(history)); } public Task> GetOverrideDetailAsync(Guid overrideId, CancellationToken cancellationToken = default) { var detail = new ManualOverrideDetail { OverrideId = overrideId, OverrideResult = new ManualOverrideResult { OverrideId = overrideId, RequestId = Guid.Empty, SessionId = Guid.Empty, OverrideResult = OverrideResult.Success, OverrideStatus = OverrideStatus.Overridden, OverrideMessage = "最小实现", ExecutionTimeUtc = DateTime.UtcNow, ExecutionElapsedMs = 0, Executor = string.Empty, AffectedSessionStatus = SessionStatus.Completed }, OverrideRequest = new ManualOverrideRequest() }; return Task.FromResult(Result.Success(detail)); } public Task> RevokeManualOverrideAsync(Guid overrideId, string revokeReason, string operatorId, CancellationToken cancellationToken = default) { var result = new OverrideRevokeResult { RevokeId = Guid.NewGuid(), OverrideId = overrideId, RevokeResult = RevokeResult.Success, RevokeReason = revokeReason, RevokeTimeUtc = DateTime.UtcNow, Revoker = operatorId, RevokeMessage = "最小实现:撤销成功" }; return Task.FromResult(Result.Success(result)); } public Task> GetOverrideStatisticsAsync(DateTime startTime, DateTime endTime, string? productTypeCode = null, CancellationToken cancellationToken = default) { var statistics = new ManualOverrideStatistics { TimeRange = new TimeRange { StartTime = startTime, EndTime = endTime }, ProductTypeCode = productTypeCode ?? string.Empty, TotalOverrideCount = 0, SuccessfulOverrideCount = 0, FailedOverrideCount = 0, OverridesByType = new Dictionary(), OverridesByOperator = new Dictionary(), ByDate = new Dictionary(), AverageOverrideElapsedMs = 0, MaxOverrideElapsedMs = 0, MinOverrideElapsedMs = 0 }; return Task.FromResult(Result.Success(statistics)); } public Task>> GetOverrideAuditLogsAsync(Guid? sessionId = null, Guid? overrideId = null, DateTime? startTime = null, DateTime? endTime = null, CoreAuditLevel? auditLevel = null, CancellationToken cancellationToken = default) { IReadOnlyList logs = Array.Empty(); return Task.FromResult(Result>.Success(logs)); } public Task> GenerateOverrideReportAsync(OverrideReportRequest reportRequest, CancellationToken cancellationToken = default) { var report = new ManualOverrideReport { ReportId = Guid.NewGuid(), ReportType = reportRequest.ReportType, ReportTitle = "最小实现报告", TimeRange = reportRequest.TimeRange, GeneratedAtUtc = DateTime.UtcNow, ExecutiveSummary = new ReportExecutiveSummary(), Statistics = new ManualOverrideStatistics(), TrendAnalysis = new OverrideTrendAnalysis(), ComplianceAnalysis = new OverrideComplianceAnalysis(), RiskAnalysis = new OverrideRiskAnalysis(), ImprovementSuggestions = Array.Empty() }; return Task.FromResult(Result.Success(report)); } public Task> CheckOverrideComplianceAsync(Guid sessionId, ManualOverrideRequest overrideRequest, CancellationToken cancellationToken = default) { var result = new OverrideComplianceCheck { CheckId = Guid.NewGuid(), SessionId = sessionId, CheckResult = ComplianceCheckResult.Pass, ComplianceScore = 1, CheckItems = Array.Empty(), Violations = Array.Empty(), CheckTimeUtc = DateTime.UtcNow, CheckElapsedMs = 0 }; return Task.FromResult(Result.Success(result)); } public Task> GetOverrideTemplateAsync(OverrideTemplateType templateType, CancellationToken cancellationToken = default) { var template = new OverrideTemplate { TemplateId = Guid.NewGuid(), TemplateType = templateType, TemplateName = "最小实现模板", TemplateDescription = string.Empty, IsEnabled = true, CreatedAtUtc = DateTime.UtcNow, Creator = string.Empty, TemplateContent = string.Empty, TemplateParameters = Array.Empty(), ApplicableConditions = Array.Empty() }; return Task.FromResult(Result.Success(template)); } public Task> SaveOverrideTemplateAsync(OverrideTemplate template, CancellationToken cancellationToken = default) { var result = new OverrideTemplateSaveResult { TemplateId = template.TemplateId, IsSuccess = true, SaveMessage = "最小实现:保存成功", SaveTimeUtc = DateTime.UtcNow }; _logger.LogDebug("最小实现:保存模板 {TemplateId}", template.TemplateId); return Task.FromResult(Result.Success(result)); } } #if false /// /// 人工复位放行服务实现。 /// public sealed class ManualOverrideService : IManualOverrideService { private readonly ILogger _logger; private readonly RuntimeOptions _options; private readonly ConcurrentDictionary _overrideCache = new(); private readonly object _lock = new(); /// /// 构造函数。 /// public ManualOverrideService(ILogger logger, IOptions options) { _logger = logger; _options = options.Value; _logger.LogInformation("人工复位放行服务已初始化"); } /// public async Task>> GetOverrideableSessionsAsync(DateTime startTime, DateTime endTime, string? productTypeCode = null, OverrideStatus? overrideStatus = null, CancellationToken cancellationToken = default) { try { _logger.LogInformation("获取可复位放行的会话列表:开始时间={StartTime},结束时间={EndTime},产品类型={ProductTypeCode},复位状态={OverrideStatus}", startTime, endTime, productTypeCode, overrideStatus); var cacheKey = $"overrideable_sessions_{startTime:yyyyMMddHHmm}_{endTime:yyyyMMddHHmm}_{productTypeCode}_{overrideStatus}"; if (_options.EnableHistoryTraceCache && _overrideCache.TryGetValue(cacheKey, out var cached)) { _logger.LogDebug("从缓存获取可复位放行的会话列表"); return Result.Success((IReadOnlyList)cached); } var overrideableSessions = await GenerateOverrideableSessionsAsync(startTime, endTime, productTypeCode, overrideStatus, cancellationToken); if (_options.EnableHistoryTraceCache) { _overrideCache.TryAdd(cacheKey, overrideableSessions); } _logger.LogInformation("可复位放行的会话列表获取完成:会话数量={SessionCount}", overrideableSessions.Count); return Result.Success(overrideableSessions); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "获取可复位放行的会话列表失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "GET_OVERRIDABLE_SESSIONS_FAILED", "获取可复位放行的会话列表失败", traceId); return Result.FailWithTrace>(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } /// public async Task> GetOverridePermissionAsync(Guid sessionId, string operatorId, CancellationToken cancellationToken = default) { try { _logger.LogInformation("获取会话复位放行权限:会话ID={SessionId},操作员ID={OperatorId}", sessionId, operatorId); var cacheKey = $"override_permission_{sessionId}_{operatorId}"; if (_options.EnableHistoryTraceCache && _overrideCache.TryGetValue(cacheKey, out var cached)) { _logger.LogDebug("从缓存获取复位放行权限"); return Result.Success((OverridePermission)cached); } var permission = await GenerateOverridePermissionAsync(sessionId, operatorId, cancellationToken); if (_options.EnableHistoryTraceCache) { _overrideCache.TryAdd(cacheKey, permission); } _logger.LogInformation("复位放行权限获取完成:会话ID={SessionId},操作员ID={OperatorId},是否有权限={HasPermission}", sessionId, operatorId, permission.HasPermission); return Result.Success(permission); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "获取复位放行权限失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "GET_OVERRIDE_PERMISSION_FAILED", "获取复位放行权限失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } /// public async Task> ValidateOverrideConditionsAsync(Guid sessionId, ManualOverrideRequest overrideRequest, CancellationToken cancellationToken = default) { try { _logger.LogInformation("验证复位放行条件:会话ID={SessionId},请求ID={RequestId}", sessionId, overrideRequest.RequestId); var validationResult = await GenerateOverrideValidationResultAsync(sessionId, overrideRequest, cancellationToken); _logger.LogInformation("复位放行条件验证完成:会话ID={SessionId},是否通过={IsValid},验证结果={ValidationResult}", sessionId, validationResult.IsValid, validationResult.ValidationResult); return Result.Success(validationResult); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "验证复位放行条件失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "VALIDATE_OVERRIDE_CONDITIONS_FAILED", "验证复位放行条件失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } /// public async Task> ExecuteManualOverrideAsync(ManualOverrideRequest overrideRequest, CancellationToken cancellationToken = default) { try { _logger.LogInformation("执行人工复位放行:请求ID={RequestId},会话ID={SessionId},操作员ID={OperatorId}", overrideRequest.RequestId, overrideRequest.SessionId, overrideRequest.OperatorId); var startTime = DateTime.UtcNow; var overrideResult = await GenerateManualOverrideResultAsync(overrideRequest, cancellationToken); var elapsed = DateTime.UtcNow - startTime; // 记录审计日志 await LogOverrideAuditAsync(overrideRequest, overrideResult, elapsed, cancellationToken); _logger.LogInformation("人工复位放行执行完成:请求ID={RequestId},复位结果={OverrideResult},耗时={ElapsedMs}ms", overrideRequest.RequestId, overrideResult.OverrideResult, elapsed.TotalMilliseconds); return Result.Success(overrideResult); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "执行人工复位放行失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "EXECUTE_MANUAL_OVERRIDE_FAILED", "执行人工复位放行失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } /// public async Task> ExecuteBatchManualOverrideAsync(IReadOnlyList overrideRequests, CancellationToken cancellationToken = default) { try { _logger.LogInformation("执行批量人工复位放行:请求数量={RequestCount}", overrideRequests.Count); var startTime = DateTime.UtcNow; var results = new List(); var successCount = 0; var failureCount = 0; foreach (var request in overrideRequests) { try { var result = await ExecuteManualOverrideAsync(request, cancellationToken); if (result.IsSuccess) { results.Add(result.Value); if (result.Value.OverrideResult == OverrideResult.Success) { successCount++; } else { failureCount++; } } else { failureCount++; _logger.LogWarning("批量复位中的单个请求失败:请求ID={RequestId},错误={Error}", request.RequestId, result.Message); } } catch (Exception ex) { failureCount++; _logger.LogError(ex, "批量复位中的单个请求异常:请求ID={RequestId}", request.RequestId); } } var elapsed = DateTime.UtcNow - startTime; var batchResult = new BatchManualOverrideResult { BatchId = Guid.NewGuid(), TotalRequestCount = overrideRequests.Count, SuccessCount = successCount, FailureCount = failureCount, Results = results.AsReadOnly(), BatchMessage = $"批量操作完成:成功{successCount}个,失败{failureCount}个", BatchExecutionTimeUtc = DateTime.UtcNow, BatchExecutionElapsedMs = (long)elapsed.TotalMilliseconds, ExtendedProperties = new Dictionary { ["generation_time_ms"] = elapsed.TotalMilliseconds, ["data_source"] = "simulated" } }; _logger.LogInformation("批量人工复位放行执行完成:请求数量={RequestCount},成功数={SuccessCount},失败数={FailureCount},耗时={ElapsedMs}ms", overrideRequests.Count, successCount, failureCount, elapsed.TotalMilliseconds); return Result.Success(batchResult); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "执行批量人工复位放行失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "EXECUTE_BATCH_MANUAL_OVERRIDE_FAILED", "执行批量人工复位放行失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } /// public async Task>> GetOverrideHistoryAsync(DateTime startTime, DateTime endTime, string? operatorId = null, OverrideResult? overrideResult = null, CancellationToken cancellationToken = default) { try { _logger.LogInformation("获取复位放行历史记录:开始时间={StartTime},结束时间={EndTime},操作员ID={OperatorId},复位结果={OverrideResult}", startTime, endTime, operatorId, overrideResult); var cacheKey = $"override_history_{startTime:yyyyMMddHHmm}_{endTime:yyyyMMddHHmm}_{operatorId}_{overrideResult}"; if (_options.EnableHistoryTraceCache && _overrideCache.TryGetValue(cacheKey, out var cached)) { _logger.LogDebug("从缓存获取复位放行历史记录"); return Result.Success((IReadOnlyList)cached); } var overrideHistory = await GenerateOverrideHistoryAsync(startTime, endTime, operatorId, overrideResult, cancellationToken); if (_options.EnableHistoryTraceCache) { _overrideCache.TryAdd(cacheKey, overrideHistory); } _logger.LogInformation("复位放行历史记录获取完成:记录数量={RecordCount}", overrideHistory.Count); return Result.Success(overrideHistory); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "获取复位放行历史记录失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "GET_OVERRIDE_HISTORY_FAILED", "获取复位放行历史记录失败", traceId); return Result.FailWithTrace>(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } /// public async Task> GetOverrideDetailAsync(Guid overrideId, CancellationToken cancellationToken = default) { try { _logger.LogInformation("获取复位放行详细信息:复位ID={OverrideId}", overrideId); var cacheKey = $"override_detail_{overrideId}"; if (_options.EnableHistoryTraceCache && _overrideCache.TryGetValue(cacheKey, out var cached)) { _logger.LogDebug("从缓存获取复位放行详细信息"); return Result.Success((ManualOverrideDetail)cached); } var overrideDetail = await GenerateOverrideDetailAsync(overrideId, cancellationToken); if (_options.EnableHistoryTraceCache) { _overrideCache.TryAdd(cacheKey, overrideDetail); } _logger.LogInformation("复位放行详细信息获取完成:复位ID={OverrideId},复位结果={OverrideResult}", overrideId, overrideDetail.OverrideResult.OverrideResult); return Result.Success(overrideDetail); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "获取复位放行详细信息失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "GET_OVERRIDE_DETAIL_FAILED", "获取复位放行详细信息失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } /// public async Task> RevokeManualOverrideAsync(Guid overrideId, string revokeReason, string operatorId, CancellationToken cancellationToken = default) { try { _logger.LogInformation("撤销人工复位放行:复位ID={OverrideId},撤销原因={RevokeReason},操作员ID={OperatorId}", overrideId, revokeReason, operatorId); var revokeResult = await GenerateOverrideRevokeResultAsync(overrideId, revokeReason, operatorId, cancellationToken); // 记录撤销审计日志 await LogRevokeAuditAsync(overrideId, revokeReason, operatorId, revokeResult, cancellationToken); _logger.LogInformation("人工复位放行撤销完成:复位ID={OverrideId},撤销结果={RevokeResult}", overrideId, revokeResult.RevokeResult); return Result.Success(revokeResult); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "撤销人工复位放行失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "REVOKE_MANUAL_OVERRIDE_FAILED", "撤销人工复位放行失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } /// public async Task> GetOverrideStatisticsAsync(DateTime startTime, DateTime endTime, string? productTypeCode = null, CancellationToken cancellationToken = default) { try { _logger.LogInformation("获取复位放行统计信息:开始时间={StartTime},结束时间={EndTime},产品类型={ProductTypeCode}", startTime, endTime, productTypeCode); var cacheKey = $"override_statistics_{startTime:yyyyMMddHHmm}_{endTime:yyyyMMddHHmm}_{productTypeCode}"; if (_options.EnableHistoryTraceCache && _overrideCache.TryGetValue(cacheKey, out var cached)) { _logger.LogDebug("从缓存获取复位放行统计信息"); return Result.Success((ManualOverrideStatistics)cached); } var statistics = await GenerateOverrideStatisticsAsync(startTime, endTime, productTypeCode, cancellationToken); if (_options.EnableHistoryTraceCache) { _overrideCache.TryAdd(cacheKey, statistics); } _logger.LogInformation("复位放行统计信息获取完成:总复位数={TotalCount},成功率={SuccessRate:F2}%,平均耗时={AvgElapsedMs:F2}ms", statistics.TotalOverrideCount, statistics.SuccessRate, statistics.AverageOverrideElapsedMs); return Result.Success(statistics); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "获取复位放行统计信息失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "GET_OVERRIDE_STATISTICS_FAILED", "获取复位放行统计信息失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } /// public async Task>> GetOverrideAuditLogsAsync(Guid? sessionId = null, Guid? overrideId = null, DateTime? startTime = null, DateTime? endTime = null, OrpaonVision.Core.ManualOverride.AuditLevel? auditLevel = null, CancellationToken cancellationToken = default) { try { _logger.LogInformation("获取复位放行审计日志:会话ID={SessionId},复位ID={OverrideId},开始时间={StartTime},结束时间={EndTime},审计级别={AuditLevel}", sessionId, overrideId, startTime, endTime, auditLevel); var auditLogs = await GenerateOverrideAuditLogsAsync(sessionId, overrideId, startTime, endTime, auditLevel, cancellationToken); _logger.LogInformation("复位放行审计日志获取完成:日志数量={LogCount}", auditLogs.Count); return Result.Success(auditLogs); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "获取复位放行审计日志失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "GET_OVERRIDE_AUDIT_LOGS_FAILED", "获取复位放行审计日志失败", traceId); return Result.FailWithTrace>(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } /// public async Task> GenerateOverrideReportAsync(OverrideReportRequest reportRequest, CancellationToken cancellationToken = default) { try { _logger.LogInformation("生成复位放行报告:请求ID={RequestId},报告类型={ReportType}", reportRequest.RequestId, reportRequest.ReportType); var report = await GenerateManualOverrideReportAsync(reportRequest, cancellationToken); _logger.LogInformation("复位放行报告生成完成:报告ID={ReportId},报告类型={ReportType},评分={OverallScore:F2}", report.ReportId, report.ReportType, report.ExecutiveSummary.OverallScore); return Result.Success(report); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "生成复位放行报告失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "GENERATE_OVERRIDE_REPORT_FAILED", "生成复位放行报告失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } /// public async Task> CheckOverrideComplianceAsync(Guid sessionId, ManualOverrideRequest overrideRequest, CancellationToken cancellationToken = default) { try { _logger.LogInformation("检查复位放行合规性:会话ID={SessionId},请求ID={RequestId}", sessionId, overrideRequest.RequestId); var complianceCheck = await GenerateOverrideComplianceCheckAsync(sessionId, overrideRequest, cancellationToken); _logger.LogInformation("复位放行合规性检查完成:会话ID={SessionId},检查结果={CheckResult},合规评分={ComplianceScore:F2}", sessionId, complianceCheck.CheckResult, complianceCheck.ComplianceScore); return Result.Success(complianceCheck); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "检查复位放行合规性失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "CHECK_OVERRIDE_COMPLIANCE_FAILED", "检查复位放行合规性失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } /// public async Task> GetOverrideTemplateAsync(OverrideTemplateType templateType, CancellationToken cancellationToken = default) { try { _logger.LogInformation("获取复位放行模板:模板类型={TemplateType}", templateType); var template = await GenerateOverrideTemplateAsync(templateType, cancellationToken); _logger.LogInformation("复位放行模板获取完成:模板ID={TemplateId},模板名称={TemplateName}", template.TemplateId, template.TemplateName); return Result.Success(template); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "获取复位放行模板失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "GET_OVERRIDE_TEMPLATE_FAILED", "获取复位放行模板失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } /// public async Task> SaveOverrideTemplateAsync(OverrideTemplate template, CancellationToken cancellationToken = default) { try { _logger.LogInformation("保存复位放行模板:模板ID={TemplateId},模板名称={TemplateName}", template.TemplateId, template.TemplateName); var saveResult = await GenerateOverrideTemplateSaveResultAsync(template, cancellationToken); _logger.LogInformation("复位放行模板保存完成:模板ID={TemplateId},保存结果={IsSuccess}", template.TemplateId, saveResult.IsSuccess); return Result.Success(saveResult); } catch (Exception ex) { var traceId = Guid.NewGuid().ToString("N"); _logger.LogError(ex, "保存复位放行模板失败。TraceId: {TraceId}", traceId); var result = Result.FromException(ex, "SAVE_OVERRIDE_TEMPLATE_FAILED", "保存复位放行模板失败", traceId); return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray()); } } #region 私有方法 /// /// 生成可复位放行的会话列表。 /// private async Task> GenerateOverrideableSessionsAsync(DateTime startTime, DateTime endTime, string? productTypeCode, OverrideStatus? overrideStatus, CancellationToken cancellationToken = default) { await Task.Delay(1, cancellationToken); var random = new Random(); var overrideableSessions = new List(); var current = startTime; while (current <= endTime) { var sessionCount = random.Next(3, 10); for (int i = 0; i < sessionCount; i++) { var status = overrideStatus ?? (OverrideStatus)random.Next(0, 6); var sessionStartTime = current.AddHours(random.Next(0, 24)).AddMinutes(random.Next(0, 60)); var sessionEndTime = status == OverrideStatus.Overridden ? sessionStartTime.AddMinutes(random.Next(30, 120)) : null; overrideableSessions.Add(new OverrideableSession { SessionId = Guid.NewGuid(), ProductSerialNumber = $"SN{random.Next(100000, 999999)}", ProductTypeCode = productTypeCode ?? $"PT{random.Next(1, 10)}", SessionStatus = SessionStatus.Completed, FinalJudgmentResult = FinalJudgmentResult.Fail, SessionStartTimeUtc = sessionStartTime, SessionEndTimeUtc = sessionEndTime, OverrideStatus = status, OverrideReasons = GenerateOverrideReasons(random), OverridePriority = (OverridePriority)random.Next(0, 4), RequiredPermissionLevel = (OperatorPermissionLevel)random.Next(1, 6), OperatorId = $"OP{random.Next(1, 10):D3}", OperatorName = $"操作员{random.Next(1, 10)}", StationId = $"ST{random.Next(1, 5):D3}", StationName = $"工位{random.Next(1, 5)}", TotalLayerCount = random.Next(3, 8), CompletedLayerCount = random.Next(0, 8), NGReasons = GenerateNGReasons(random), ExtendedProperties = new Dictionary { ["generation_time_ms"] = 25, ["data_source"] = "simulated" } }); } current = current.AddDays(1); } return overrideableSessions.AsReadOnly(); } /// /// 生成复位权限。 /// private async Task GenerateOverridePermissionAsync(Guid sessionId, string operatorId, CancellationToken cancellationToken = default) { await Task.Delay(1, cancellationToken); var random = new Random(); var operatorLevel = (OperatorPermissionLevel)random.Next(0, 6); var hasPermission = operatorLevel >= OperatorPermissionLevel.TeamLeader; return new OverridePermission { PermissionId = Guid.NewGuid(), SessionId = sessionId, OperatorId = operatorId, OperatorName = $"操作员{random.Next(1, 10)}", OperatorPermissionLevel = operatorLevel, HasPermission = hasPermission, PermissionReason = hasPermission ? "权限满足要求" : "权限不足", PermissionRestrictions = hasPermission ? new List() : new List { "需要班组长或更高级别权限" }, PermissionExpiryUtc = hasPermission ? DateTime.UtcNow.AddHours(8) : null, RequireSecondaryConfirmation = !hasPermission && operatorLevel == OperatorPermissionLevel.Technician, RequireApprovalProcess = !hasPermission, RequiredApprovers = !hasPermission ? new List { $"TL{random.Next(1, 3):D3}" } : new List(), ExtendedProperties = new Dictionary { ["generation_time_ms"] = 15, ["data_source"] = "simulated" } }; } /// /// 生成复位验证结果。 /// private async Task GenerateOverrideValidationResultAsync(Guid sessionId, ManualOverrideRequest overrideRequest, CancellationToken cancellationToken = default) { await Task.Delay(1, cancellationToken); var random = new Random(); var isValid = random.NextDouble() > 0.2; var validationResult = isValid ? ValidationResult.Pass : (random.NextDouble() > 0.5 ? ValidationResult.Warning : ValidationResult.Fail); return new OverrideValidationResult { ValidationId = Guid.NewGuid(), SessionId = sessionId, RequestId = overrideRequest.RequestId, IsValid = isValid, ValidationResult = validationResult, ValidationMessage = isValid ? "验证通过" : (validationResult == ValidationResult.Warning ? "验证通过但有警告" : "验证失败"), ValidationDetails = GenerateValidationDetails(random), ValidationWarnings = validationResult == ValidationResult.Warning ? new List { "警告1", "警告2" } : new List(), ValidationErrors = !isValid ? new List { "错误1", "错误2" } : new List(), ValidationTimeUtc = DateTime.UtcNow, ValidationElapsedMs = random.Next(100, 1000), ExtendedProperties = new Dictionary { ["generation_time_ms"] = 20, ["data_source"] = "simulated" } }; } /// /// 生成复位结果。 /// private async Task GenerateManualOverrideResultAsync(ManualOverrideRequest overrideRequest, CancellationToken cancellationToken = default) { await Task.Delay(1, cancellationToken); var random = new Random(); var isSuccess = random.NextDouble() > 0.1; var overrideResult = isSuccess ? OverrideResult.Success : (OverrideResult)random.Next(1, 6); return new ManualOverrideResult { OverrideId = Guid.NewGuid(), RequestId = overrideRequest.RequestId, SessionId = overrideRequest.SessionId, OverrideResult = overrideResult, OverrideStatus = isSuccess ? OverrideStatus.Overridden : (overrideResult == OverrideResult.Rejected ? OverrideStatus.Rejected : OverrideStatus.Pending), OverrideMessage = isSuccess ? "复位成功" : "复位失败", ExecutionTimeUtc = DateTime.UtcNow, ExecutionElapsedMs = random.Next(500, 5000), Executor = overrideRequest.OperatorName, ExecutionDetails = GenerateExecutionDetails(random), AffectedSessionStatus = isSuccess ? SessionStatus.Completed : SessionStatus.Failed, FollowUpActions = isSuccess ? new List { "记录日志", "通知相关人员" } : new List { "检查失败原因" }, ExtendedProperties = new Dictionary { ["generation_time_ms"] = 30, ["data_source"] = "simulated" } }; } /// /// 生成复位历史记录。 /// private async Task> GenerateOverrideHistoryAsync(DateTime startTime, DateTime endTime, string? operatorId, OverrideResult? overrideResult, CancellationToken cancellationToken = default) { await Task.Delay(1, cancellationToken); var random = new Random(); var overrideHistory = new List(); var historyCount = random.Next(10, 50); for (int i = 0; i < historyCount; i++) { var result = overrideResult ?? (OverrideResult)random.Next(0, 6); var overrideTime = startTime.AddMinutes(random.Next(0, (int)(endTime - startTime).TotalMinutes)); overrideHistory.Add(new ManualOverrideHistory { HistoryId = Guid.NewGuid(), OverrideId = Guid.NewGuid(), SessionId = Guid.NewGuid(), RequestId = Guid.NewGuid(), OverrideType = (OverrideType)random.Next(0, 8), OverrideResult = result, OverrideStatus = result == OverrideResult.Success ? OverrideStatus.Overridden : OverrideStatus.Pending, OperatorId = operatorId ?? $"OP{random.Next(1, 10):D3}", OperatorName = $"操作员{random.Next(1, 10)}", OverrideReason = $"复位原因{i + 1}", OverrideTimeUtc = overrideTime, OverrideElapsedMs = random.Next(500, 5000), OverrideMessage = result == OverrideResult.Success ? "复位成功" : "复位失败", ExtendedProperties = new Dictionary { ["generation_time_ms"] = 18, ["data_source"] = "simulated" } }); } return overrideHistory.AsReadOnly(); } /// /// 生成复位详细信息。 /// private async Task GenerateOverrideDetailAsync(Guid overrideId, CancellationToken cancellationToken = default) { await Task.Delay(1, cancellationToken); var random = new Random(); var overrideResult = new ManualOverrideResult { OverrideId = overrideId, RequestId = Guid.NewGuid(), SessionId = Guid.NewGuid(), OverrideResult = OverrideResult.Success, OverrideStatus = OverrideStatus.Overridden, OverrideMessage = "复位成功", ExecutionTimeUtc = DateTime.UtcNow.AddMinutes(-random.Next(10, 120)), ExecutionElapsedMs = random.Next(500, 5000), Executor = $"操作员{random.Next(1, 10)}", ExecutionDetails = GenerateExecutionDetails(random), AffectedSessionStatus = SessionStatus.Completed }; var overrideRequest = new ManualOverrideRequest { RequestId = overrideResult.RequestId, SessionId = overrideResult.SessionId, OperatorId = $"OP{random.Next(1, 10):D3}", OperatorName = overrideResult.Executor, OverrideType = (OverrideType)random.Next(0, 8), OverrideReason = "复位原因", OverrideDescription = "复位描述", OverridePriority = (OverridePriority)random.Next(0, 4), TargetStatus = SessionStatus.Completed, RequestTimeUtc = overrideResult.ExecutionTimeUtc.AddMinutes(-random.Next(5, 30)), IsUrgent = random.NextDouble() > 0.8, RequireApproval = random.NextDouble() > 0.7 }; return new ManualOverrideDetail { OverrideId = overrideId, OverrideResult = overrideResult, OverrideRequest = overrideRequest, ValidationResult = GenerateOverrideValidationResultAsync(overrideResult.SessionId, overrideRequest, cancellationToken).Result, Permission = GenerateOverridePermissionAsync(overrideResult.SessionId, overrideRequest.OperatorId, cancellationToken).Result, ApprovalInfos = GenerateApprovalInfos(random), ImpactAnalysis = GenerateOverrideImpactAnalysis(random), ComplianceCheck = GenerateOverrideComplianceCheckAsync(overrideResult.SessionId, overrideRequest, cancellationToken).Result, ExtendedProperties = new Dictionary { ["generation_time_ms"] = 40, ["data_source"] = "simulated" } }; } /// /// 生成复位撤销结果。 /// private async Task GenerateOverrideRevokeResultAsync(Guid overrideId, string revokeReason, string operatorId, CancellationToken cancellationToken = default) { await Task.Delay(1, cancellationToken); var random = new Random(); var revokeResult = random.NextDouble() > 0.1 ? RevokeResult.Success : (RevokeResult)random.Next(1, 5); return new OverrideRevokeResult { RevokeId = Guid.NewGuid(), OverrideId = overrideId, RevokeResult = revokeResult, RevokeReason = revokeReason, RevokeTimeUtc = DateTime.UtcNow, Revoker = $"操作员{random.Next(1, 10)}", RevokeMessage = revokeResult == RevokeResult.Success ? "撤销成功" : "撤销失败", ExtendedProperties = new Dictionary { ["generation_time_ms"] = 25, ["data_source"] = "simulated" } }; } /// /// 生成复位统计信息。 /// private async Task GenerateOverrideStatisticsAsync(DateTime startTime, DateTime endTime, string? productTypeCode, CancellationToken cancellationToken = default) { await Task.Delay(1, cancellationToken); var random = new Random(); var timeRange = new TimeRange { StartTimeUtc = startTime, EndTimeUtc = endTime }; var totalOverrideCount = random.Next(50, 200); var successfulOverrideCount = (int)(totalOverrideCount * (0.7 + random.NextDouble() * 0.25)); return new ManualOverrideStatistics { TimeRange = timeRange, ProductTypeCode = productTypeCode ?? "default", TotalOverrideCount = totalOverrideCount, SuccessfulOverrideCount = successfulOverrideCount, FailedOverrideCount = totalOverrideCount - successfulOverrideCount, OverridesByType = GenerateOverridesByType(random, totalOverrideCount), OverridesByOperator = GenerateOverridesByOperator(random), ByDate = GenerateDailyOverrideStatistics(startTime, endTime, random), AverageOverrideElapsedMs = 1000 + random.NextDouble() * 2000, MaxOverrideElapsedMs = 5000 + random.Next(0, 5000), MinOverrideElapsedMs = 500 + random.Next(0, 500), ExtendedProperties = new Dictionary { ["generation_time_ms"] = 35, ["data_source"] = "simulated" } }; } /// /// 生成审计日志。 /// private async Task> GenerateOverrideAuditLogsAsync(Guid? sessionId, Guid? overrideId, DateTime? startTime, DateTime? endTime, OrpaonVision.Core.ManualOverride.AuditLevel? auditLevel, CancellationToken cancellationToken = default) { await Task.Delay(1, cancellationToken); var random = new Random(); var auditLogs = new List(); var logCount = random.Next(20, 100); for (int i = 0; i < logCount; i++) { var level = auditLevel ?? (OrpaonVision.Core.ManualOverride.AuditLevel)random.Next(0, 5); var auditTime = startTime?.AddMinutes(random.Next(0, (int)(endTime - startTime).Value.TotalMinutes)) ?? DateTime.UtcNow.AddMinutes(-random.Next(10, 1440)); auditLogs.Add(new OverrideAuditLog { LogId = Guid.NewGuid(), SessionId = sessionId, OverrideId = overrideId, AuditLevel = level, AuditType = (AuditType)random.Next(0, 9), AuditMessage = $"审计消息{i + 1}", AuditDetails = $"审计详情{i + 1}", OperatorId = $"OP{random.Next(1, 10):D3}", OperatorName = $"操作员{random.Next(1, 10)}", AuditTimeUtc = auditTime, ClientIp = $"192.168.1.{random.Next(1, 255)}", UserAgent = $"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36", ExtendedProperties = new Dictionary { ["generation_time_ms"] = 12, ["data_source"] = "simulated" } }); } return auditLogs.AsReadOnly(); } /// /// 生成复位报告。 /// private async Task GenerateManualOverrideReportAsync(OverrideReportRequest reportRequest, CancellationToken cancellationToken = default) { await Task.Delay(1, cancellationToken); var random = new Random(); var statistics = await GenerateOverrideStatisticsAsync(reportRequest.TimeRange.StartTimeUtc, reportRequest.TimeRange.EndTimeUtc, reportRequest.ProductTypeCode, cancellationToken); return new ManualOverrideReport { ReportId = Guid.NewGuid(), ReportType = reportRequest.ReportType, ReportTitle = $"{reportRequest.ReportType}复位放行报告", TimeRange = reportRequest.TimeRange, GeneratedAtUtc = DateTime.UtcNow, ExecutiveSummary = GenerateReportExecutiveSummary(random), Statistics = statistics, TrendAnalysis = GenerateOverrideTrendAnalysis(random), ComplianceAnalysis = GenerateOverrideComplianceAnalysis(random), RiskAnalysis = GenerateOverrideRiskAnalysis(random), ImprovementSuggestions = GenerateOverrideImprovementSuggestions(random), ExtendedProperties = new Dictionary { ["generation_time_ms"] = 80, ["data_source"] = "simulated" } }; } /// /// 生成合规性检查。 /// private async Task GenerateOverrideComplianceCheckAsync(Guid sessionId, ManualOverrideRequest overrideRequest, CancellationToken cancellationToken = default) { await Task.Delay(1, cancellationToken); var random = new Random(); var checkResult = random.NextDouble() > 0.2 ? ComplianceCheckResult.Pass : (ComplianceCheckResult)random.Next(1, 4); return new OverrideComplianceCheck { CheckId = Guid.NewGuid(), SessionId = sessionId, CheckResult = checkResult, ComplianceScore = 70 + random.NextDouble() * 25, CheckItems = GenerateComplianceCheckItems(random), Violations = checkResult == ComplianceCheckResult.Fail ? GenerateComplianceViolations(random) : new List(), CheckTimeUtc = DateTime.UtcNow, CheckElapsedMs = random.Next(200, 2000), ExtendedProperties = new Dictionary { ["generation_time_ms"] = 30, ["data_source"] = "simulated" } }; } /// /// 生成复位模板。 /// private async Task GenerateOverrideTemplateAsync(OverrideTemplateType templateType, CancellationToken cancellationToken = default) { await Task.Delay(1, cancellationToken); var random = new Random(); return new OverrideTemplate { TemplateId = Guid.NewGuid(), TemplateType = templateType, TemplateName = $"{templateType}模板", TemplateDescription = $"{templateType}复位模板描述", TemplateContent = $"{templateType}复位模板内容", TemplateParameters = GenerateTemplateParameters(random), ApplicableConditions = GenerateTemplateConditions(random), CreatedAtUtc = DateTime.UtcNow.AddDays(-random.Next(1, 30)), Creator = $"创建者{random.Next(1, 5)}", IsEnabled = random.NextDouble() > 0.1, ExtendedProperties = new Dictionary { ["generation_time_ms"] = 20, ["data_source"] = "simulated" } }; } /// /// 生成模板保存结果。 /// private async Task GenerateOverrideTemplateSaveResultAsync(OverrideTemplate template, CancellationToken cancellationToken = default) { await Task.Delay(1, cancellationToken); var random = new Random(); var isSuccess = random.NextDouble() > 0.1; return new OverrideTemplateSaveResult { IsSuccess = isSuccess, TemplateId = template.TemplateId, SaveMessage = isSuccess ? "保存成功" : "保存失败", SaveTimeUtc = DateTime.UtcNow, ExtendedProperties = new Dictionary { ["generation_time_ms"] = 15, ["data_source"] = "simulated" } }; } /// /// 记录复位审计日志。 /// private async Task LogOverrideAuditAsync(ManualOverrideRequest request, ManualOverrideResult result, TimeSpan elapsed, CancellationToken cancellationToken = default) { try { var auditLog = new OverrideAuditLog { LogId = Guid.NewGuid(), SessionId = request.SessionId, OverrideId = result.OverrideId, AuditLevel = result.OverrideResult == OverrideResult.Success ? OrpaonVision.Core.ManualOverride.AuditLevel.Info : OrpaonVision.Core.ManualOverride.AuditLevel.Warning, AuditType = AuditType.OverrideExecuted, AuditMessage = $"执行复位放行:{result.OverrideResult}", AuditDetails = $"请求ID:{request.RequestId},耗时:{elapsed.TotalMilliseconds:F2}ms", OperatorId = request.OperatorId, OperatorName = request.OperatorName, AuditTimeUtc = DateTime.UtcNow, ClientIp = "127.0.0.1", UserAgent = "ManualOverrideService", ExtendedProperties = new Dictionary { ["request_id"] = request.RequestId, ["override_type"] = request.OverrideType, ["elapsed_ms"] = elapsed.TotalMilliseconds } }; // 简化处理:在实际实现中,这里应该将审计日志写入数据库或日志文件 _logger.LogInformation("记录复位审计日志:{AuditLog}", JsonSerializer.Serialize(auditLog)); } catch (Exception ex) { _logger.LogError(ex, "记录复位审计日志失败"); } } /// /// 记录撤销审计日志。 /// private async Task LogRevokeAuditAsync(Guid overrideId, string revokeReason, string operatorId, OverrideRevokeResult result, CancellationToken cancellationToken = default) { try { var auditLog = new OverrideAuditLog { LogId = Guid.NewGuid(), OverrideId = overrideId, AuditLevel = result.RevokeResult == RevokeResult.Success ? OrpaonVision.Core.ManualOverride.AuditLevel.Info : OrpaonVision.Core.ManualOverride.AuditLevel.Warning, AuditType = AuditType.OverrideRevoked, AuditMessage = $"撤销复位放行:{result.RevokeResult}", AuditDetails = $"撤销原因:{revokeReason}", OperatorId = operatorId, OperatorName = $"操作员{operatorId}", AuditTimeUtc = DateTime.UtcNow, ClientIp = "127.0.0.1", UserAgent = "ManualOverrideService", ExtendedProperties = new Dictionary { ["override_id"] = overrideId, ["revoke_reason"] = revokeReason, ["revoke_result"] = result.RevokeResult } }; // 简化处理:在实际实现中,这里应该将审计日志写入数据库或日志文件 _logger.LogInformation("记录撤销审计日志:{AuditLog}", JsonSerializer.Serialize(auditLog)); } catch (Exception ex) { _logger.LogError(ex, "记录撤销审计日志失败"); } } #endregion #region 辅助方法 /// /// 生成复位原因列表。 /// private IReadOnlyList GenerateOverrideReasons(Random random) { var reasons = new List(); var reasonCount = random.Next(1, 4); for (int i = 0; i < reasonCount; i++) { reasons.Add(new OverrideReason { ReasonId = Guid.NewGuid(), ReasonType = (OverrideReasonType)random.Next(0, 8), ReasonDescription = $"复位原因{i + 1}", ReasonSeverity = (OverrideSeverity)random.Next(0, 4), RecommendedAction = $"建议措施{i + 1}", ExtendedProperties = new Dictionary { ["reason_index"] = i } }); } return reasons.AsReadOnly(); } /// /// 生成NG原因列表。 /// private IReadOnlyList GenerateNGReasons(Random random) { var reasons = new List(); var reasonCount = random.Next(0, 5); for (int i = 0; i < reasonCount; i++) { reasons.Add($"NG原因{i + 1}"); } return reasons.AsReadOnly(); } /// /// 生成验证详情列表。 /// private IReadOnlyList GenerateValidationDetails(Random random) { var details = new List(); var detailCount = random.Next(3, 8); for (int i = 0; i < detailCount; i++) { details.Add(new ValidationDetail { DetailId = Guid.NewGuid(), ValidationItem = $"验证项{i + 1}", ValidationResult = random.NextDouble() > 0.2 ? ValidationResult.Pass : ValidationResult.Fail, ValidationMessage = $"验证消息{i + 1}", ValidationValue = random.Next(1, 100), ExpectedValue = random.Next(1, 100), ExtendedProperties = new Dictionary { ["detail_index"] = i } }); } return details.AsReadOnly(); } /// /// 生成执行详情列表。 /// private IReadOnlyList GenerateExecutionDetails(Random random) { var details = new List(); var detailCount = random.Next(3, 10); for (int i = 0; i < detailCount; i++) { details.Add(new ExecutionDetail { DetailId = Guid.NewGuid(), ExecutionStep = $"执行步骤{i + 1}", ExecutionResult = random.NextDouble() > 0.1, ExecutionMessage = $"执行消息{i + 1}", ExecutionTimeUtc = DateTime.UtcNow.AddSeconds(-random.Next(1, 60)), ExecutionElapsedMs = random.Next(50, 500), ExtendedProperties = new Dictionary { ["step_index"] = i } }); } return details.AsReadOnly(); } /// /// 生成审批信息列表。 /// private IReadOnlyList GenerateApprovalInfos(Random random) { var approvals = new List(); var approvalCount = random.Next(0, 3); for (int i = 0; i < approvalCount; i++) { approvals.Add(new ApprovalInfo { ApprovalId = Guid.NewGuid(), ApproverId = $"AP{random.Next(1, 5):D3}", ApproverName = $"审批人{random.Next(1, 5)}", ApprovalResult = (ApprovalResult)random.Next(0, 4), ApprovalComment = $"审批意见{i + 1}", ApprovalTimeUtc = DateTime.UtcNow.AddMinutes(-random.Next(10, 120)), ExtendedProperties = new Dictionary { ["approval_index"] = i } }); } return approvals.AsReadOnly(); } /// /// 生成复位影响分析。 /// private OverrideImpactAnalysis GenerateOverrideImpactAnalysis(Random random) { return new OverrideImpactAnalysis { AnalysisId = Guid.NewGuid(), ImpactLevel = (ImpactLevel)random.Next(0, 5), ImpactDescription = "影响分析描述", AffectedSessionCount = random.Next(1, 5), AffectedLayerCount = random.Next(3, 20), AffectedDetectionCount = random.Next(10, 100), RiskAssessment = new RiskAssessment { RiskLevel = (RiskLevel)random.Next(0, 5), RiskDescription = "风险评估描述", RiskProbability = random.NextDouble(), RiskImpact = random.NextDouble(), MitigationMeasures = new List { "缓解措施1", "缓解措施2" }, ExtendedProperties = new Dictionary { ["generation_time_ms"] = 10 } }, RecommendedActions = new List { "建议措施1", "建议措施2", "建议措施3" }, ExtendedProperties = new Dictionary { ["generation_time_ms"] = 15 } }; } /// /// 生成按类型分组的复位统计。 /// private Dictionary GenerateOverridesByType(Random random, int totalCount) { var overridesByType = new Dictionary(); var remainingCount = totalCount; foreach (OverrideType type in Enum.GetValues()) { if (remainingCount <= 0) break; var count = random.Next(0, remainingCount / 2 + 1); overridesByType[type] = count; remainingCount -= count; } return overridesByType; } /// /// 生成按操作员分组的复位统计。 /// private Dictionary GenerateOverridesByOperator(Random random) { var operatorStats = new Dictionary(); for (int i = 1; i <= 5; i++) { var overrideCount = random.Next(5, 30); var successCount = (int)(overrideCount * (0.7 + random.NextDouble() * 0.25)); operatorStats[$"OP{i:D3}"] = new OperatorOverrideStatistics { OperatorId = $"OP{i:D3}", OperatorName = $"操作员{i}", OverrideCount = overrideCount, SuccessCount = successCount, FailureCount = overrideCount - successCount, AverageElapsedMs = 1000 + random.NextDouble() * 2000, ExtendedProperties = new Dictionary { ["generation_time_ms"] = 8 } }; } return operatorStats; } /// /// 生成每日复位统计。 /// private Dictionary GenerateDailyOverrideStatistics(DateTime startTime, DateTime endTime, Random random) { var dailyStats = new Dictionary(); var current = startTime.Date; while (current <= endTime.Date) { var overrideCount = random.Next(5, 20); var successCount = (int)(overrideCount * (0.7 + random.NextDouble() * 0.25)); dailyStats[current] = new DailyOverrideStatistics { Date = current, OverrideCount = overrideCount, SuccessCount = successCount, FailureCount = overrideCount - successCount, ExtendedProperties = new Dictionary { ["generation_time_ms"] = 6 } }; current = current.AddDays(1); } return dailyStats; } /// /// 生成报告执行摘要。 /// private ReportExecutiveSummary GenerateReportExecutiveSummary(Random random) { return new ReportExecutiveSummary { OverallScore = 70 + random.NextDouble() * 25, KeyFindings = new[] { "关键发现1", "关键发现2", "关键发现3" }, MajorIssues = new[] { "主要问题1", "主要问题2" }, ImprovementOpportunities = new[] { "改进机会1", "改进机会2", "改进机会3" }, SummaryDescription = "复位放行报告执行摘要", ExtendedProperties = new Dictionary { ["generation_time_ms"] = 12 } }; } /// /// 生成复位趋势分析。 /// private OverrideTrendAnalysis GenerateOverrideTrendAnalysis(Random random) { return new OverrideTrendAnalysis { TrendDirection = (TrendDirection)random.Next(0, 4), ChangeRate = random.NextDouble() * 10 - 5, TrendDescription = "复位趋势分析", PredictedNextOverrideCount = random.Next(10, 50), Confidence = 0.6 + random.NextDouble() * 0.3, ExtendedProperties = new Dictionary { ["generation_time_ms"] = 10 } }; } /// /// 生成复位合规性分析。 /// private OverrideComplianceAnalysis GenerateOverrideComplianceAnalysis(Random random) { return new OverrideComplianceAnalysis { ComplianceScore = 75 + random.NextDouble() * 20, ComplianceViolationCount = random.Next(0, 10), Violations = GenerateComplianceViolations(random), ComplianceRecommendations = new[] { "合规建议1", "合规建议2" }, ExtendedProperties = new Dictionary { ["generation_time_ms"] = 15 } }; } /// /// 生成复位风险分析。 /// private OverrideRiskAnalysis GenerateOverrideRiskAnalysis(Random random) { return new OverrideRiskAnalysis { RiskScore = 20 + random.NextDouble() * 60, HighRiskOverrideCount = random.Next(0, 5), RiskFactors = new List { new RiskFactor { FactorId = Guid.NewGuid(), FactorName = "风险因素1", FactorDescription = "风险因素描述1", RiskLevel = (RiskLevel)random.Next(0, 5), ImpactLevel = random.NextDouble(), ExtendedProperties = new Dictionary { ["factor_index"] = 0 } } }, RiskMitigationRecommendations = new[] { "风险缓解建议1", "风险缓解建议2" }, ExtendedProperties = new Dictionary { ["generation_time_ms"] = 12 } }; } /// /// 生成复位改进建议。 /// private IReadOnlyList GenerateOverrideImprovementSuggestions(Random random) { var suggestions = new List(); for (int i = 0; i < random.Next(3, 8); i++) { suggestions.Add(new OverrideImprovementSuggestion { SuggestionId = Guid.NewGuid(), SuggestionCategory = (SuggestionCategory)random.Next(0, 8), SuggestionTitle = $"改进建议{i + 1}", SuggestionDescription = $"改进建议描述{i + 1}", Priority = random.Next(1, 5), ExpectedImpact = $"预期效果{i + 1}", ImplementationDifficulty = (ImplementationDifficulty)random.Next(0, 4), ExtendedProperties = new Dictionary { ["suggestion_index"] = i } }); } return suggestions.AsReadOnly(); } /// /// 生成合规性检查项。 /// private IReadOnlyList GenerateComplianceCheckItems(Random random) { var items = new List(); var itemCount = random.Next(5, 15); for (int i = 0; i < itemCount; i++) { items.Add(new ComplianceCheckItem { ItemId = Guid.NewGuid(), ItemName = $"检查项{i + 1}", ItemDescription = $"检查项描述{i + 1}", CheckResult = random.NextDouble() > 0.2 ? ComplianceCheckResult.Pass : ComplianceCheckResult.Fail, CheckValue = random.Next(1, 100), StandardValue = random.Next(1, 100), CheckMessage = $"检查消息{i + 1}", ExtendedProperties = new Dictionary { ["item_index"] = i } }); } return items.AsReadOnly(); } /// /// 生成合规违规。 /// private IReadOnlyList GenerateComplianceViolations(Random random) { var violations = new List(); var violationCount = random.Next(0, 5); for (int i = 0; i < violationCount; i++) { violations.Add(new ComplianceViolation { ViolationId = Guid.NewGuid(), ViolationType = $"违规类型{i + 1}", ViolationDescription = $"违规描述{i + 1}", ViolationSeverity = (ViolationSeverity)random.Next(0, 4), ViolationTimeUtc = DateTime.UtcNow.AddMinutes(-random.Next(10, 120)), ExtendedProperties = new Dictionary { ["violation_index"] = i } }); } return violations.AsReadOnly(); } /// /// 生成模板参数。 /// private IReadOnlyList GenerateTemplateParameters(Random random) { var parameters = new List(); var parameterCount = random.Next(3, 8); for (int i = 0; i < parameterCount; i++) { parameters.Add(new TemplateParameter { ParameterId = Guid.NewGuid(), ParameterName = $"参数{i + 1}", ParameterType = "string", ParameterDescription = $"参数描述{i + 1}", IsRequired = random.NextDouble() > 0.5, DefaultValue = $"默认值{i + 1}", ValidationRule = "required", ExtendedProperties = new Dictionary { ["parameter_index"] = i } }); } return parameters.AsReadOnly(); } /// /// 生成模板条件。 /// private IReadOnlyList GenerateTemplateConditions(Random random) { var conditions = new List(); var conditionCount = random.Next(0, 3); for (int i = 0; i < conditionCount; i++) { conditions.Add(new TemplateCondition { ConditionId = Guid.NewGuid(), ConditionName = $"条件{i + 1}", ConditionExpression = $"condition{i + 1} == true", ConditionDescription = $"条件描述{i + 1}", ExtendedProperties = new Dictionary { ["condition_index"] = i } }); } return conditions.AsReadOnly(); } #endregion } #endif