using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using FreeSql; using NPP.SmartSchedue.Api.Core.Repositories; using NPP.SmartSchedue.Api.Contracts.Domain.Integration; using NPP.SmartSchedue.Api.Contracts.Services.Integration.Output; using ZhonTai.Admin.Core.Db.Transaction; namespace NPP.SmartSchedue.Api.Repositories.Integration { /// /// 智能整合记录仓储实现类 /// /// 业务实现思考: /// 1. 充分利用FreeSql的强大功能,包括分页、索引优化、JSON查询等 /// 2. 考虑查询性能,合理使用索引和查询优化策略 /// 3. 实现完整的统计分析功能,为业务决策提供数据支持 /// 4. 处理大数据量场景,提供高效的分页和聚合查询 /// public class IntegrationRecordRepository : AppRepositoryBase, IIntegrationRecordRepository { public IntegrationRecordRepository(UnitOfWorkManagerCloud unitOfWorkManager) : base(unitOfWorkManager) { } #region 基础查询方法 /// /// 根据批次编码获取整合记录 /// 利用唯一索引,确保查询性能 /// public async Task GetByBatchCodeAsync(string batchCode) { if (string.IsNullOrWhiteSpace(batchCode)) return null; return await Select .Where(r => r.IntegrationBatchCode == batchCode) .FirstAsync(); } /// /// 获取指定时间范围内的整合记录 /// 使用时间索引优化查询性能 /// public async Task<(List Records, long Total)> GetByTimeRangeAsync( DateTime startTime, DateTime endTime, int pageIndex = 1, int pageSize = 20) { var query = Select .Where(r => r.IntegrationTime >= startTime && r.IntegrationTime <= endTime) .OrderByDescending(r => r.IntegrationTime); var total = await query.CountAsync(); var records = await query .Page(pageIndex, pageSize) .ToListAsync(); return (records, total); } /// /// 根据操作人员获取整合记录 /// 使用操作员索引优化查询 /// public async Task<(List Records, long Total)> GetByOperatorAsync( long operatorUserId, int pageIndex = 1, int pageSize = 20) { var query = Select .Where(r => r.OperatorUserId == operatorUserId) .OrderByDescending(r => r.IntegrationTime); var total = await query.CountAsync(); var records = await query .Page(pageIndex, pageSize) .ToListAsync(); return (records, total); } /// /// 根据项目编号获取相关整合记录 /// 使用字符串包含查询,注意性能优化 /// public async Task<(List Records, long Total)> GetByProjectNumberAsync( string projectNumber, int pageIndex = 1, int pageSize = 20) { if (string.IsNullOrWhiteSpace(projectNumber)) return (new List(), 0); var query = Select .Where(r => r.ProjectNumbers.Contains(projectNumber)) .OrderByDescending(r => r.IntegrationTime); var total = await query.CountAsync(); var records = await query .Page(pageIndex, pageSize) .ToListAsync(); return (records, total); } #endregion #region 复合查询方法 /// /// 多维度综合查询整合记录 /// 动态构建查询条件,支持灵活的业务查询需求 /// public async Task<(List Records, long Total)> GetByMultipleConditionsAsync( long? operatorUserId = null, string? projectNumber = null, string? integrationType = null, DateTime? startTime = null, DateTime? endTime = null, decimal? minSuccessRate = null, int pageIndex = 1, int pageSize = 20) { var query = Select; // 动态添加查询条件 if (operatorUserId.HasValue) { query = query.Where(r => r.OperatorUserId == operatorUserId.Value); } if (!string.IsNullOrWhiteSpace(projectNumber)) { query = query.Where(r => r.ProjectNumbers.Contains(projectNumber)); } if (!string.IsNullOrWhiteSpace(integrationType)) { query = query.Where(r => r.IntegrationType == integrationType); } if (startTime.HasValue) { query = query.Where(r => r.IntegrationTime >= startTime.Value); } if (endTime.HasValue) { query = query.Where(r => r.IntegrationTime <= endTime.Value); } if (minSuccessRate.HasValue) { // 使用计算字段进行筛选 query = query.Where(r => r.SuccessTaskCount + r.FailedTaskCount > 0) .Where(r => (decimal)r.SuccessTaskCount / (r.SuccessTaskCount + r.FailedTaskCount) * 100 >= minSuccessRate.Value); } var orderedQuery = query.OrderByDescending(r => r.IntegrationTime); var total = await orderedQuery.CountAsync(); var records = await orderedQuery .Page(pageIndex, pageSize) .ToListAsync(); return (records, total); } /// /// 获取包含指定任务的整合记录 /// 使用JSON查询功能,在TaskIdsJson中搜索任务ID /// public async Task> GetRecordsContainingTaskAsync(long taskId) { // 使用FreeSql的JSON查询功能,支持JSON数组格式 return await Select .Where(r => r.TaskIdsJson.Contains($"\"{taskId}\"") || r.TaskIdsJson.Contains($"{taskId}")) .OrderByDescending(r => r.IntegrationTime) .ToListAsync(); } #endregion #region 统计分析方法 /// /// 获取指定时间段的整合统计数据 /// 使用聚合查询生成统计报表 /// public async Task GetIntegrationStatisticsAsync(DateTime startTime, DateTime endTime) { var records = await Select .Where(r => r.IntegrationTime >= startTime && r.IntegrationTime <= endTime) .Where(r => !r.IsTestData) // 排除测试数据 .ToListAsync(); if (!records.Any()) { return new IntegrationStatistics { StartTime = startTime, EndTime = endTime }; } var totalTasks = records.Sum(r => r.SuccessTaskCount + r.FailedTaskCount); var successfulTasks = records.Sum(r => r.SuccessTaskCount); var failedTasks = records.Sum(r => r.FailedTaskCount); return new IntegrationStatistics { StartTime = startTime, EndTime = endTime, TotalIntegrations = records.Count, TotalTasks = totalTasks, SuccessfulTasks = successfulTasks, FailedTasks = failedTasks, AverageSuccessRate = totalTasks > 0 ? Math.Round((decimal)successfulTasks / totalTasks * 100, 2) : 0, AverageElapsedTime = records.Any() ? (long)records.Average(r => r.ElapsedMilliseconds) : 0, AveragePersonnelFairnessScore = records.Any() ? Math.Round((decimal)records.Average(r => r.PersonnelFairnessScore), 1) : 0, AverageEquipmentUtilizationRate = records.Any() ? Math.Round(records.Average(r => r.EquipmentUtilizationRate), 1) : 0, ActiveOperatorCount = records.Select(r => r.OperatorUserId).Distinct().Count(), InvolvedProjectCount = records .Where(r => !string.IsNullOrWhiteSpace(r.ProjectNumbers)) .SelectMany(r => r.GetProjectNumbers()) .Distinct() .Count() }; } /// /// 获取操作员整合统计数据 /// 针对特定操作员的详细统计分析 /// public async Task GetOperatorStatisticsAsync( long operatorUserId, DateTime startTime, DateTime endTime) { var records = await Select .Where(r => r.OperatorUserId == operatorUserId) .Where(r => r.IntegrationTime >= startTime && r.IntegrationTime <= endTime) .Where(r => !r.IsTestData) .OrderByDescending(r => r.IntegrationTime) .ToListAsync(); if (!records.Any()) { var operatorInfo = await Select .Where(r => r.OperatorUserId == operatorUserId) .OrderByDescending(r => r.IntegrationTime) .FirstAsync(); return new OperatorIntegrationStats { OperatorUserId = operatorUserId, OperatorUserName = operatorInfo?.OperatorUserName ?? "", OperatorRealName = operatorInfo?.OperatorRealName ?? "" }; } var totalTasks = records.Sum(r => r.SuccessTaskCount + r.FailedTaskCount); var successfulTasks = records.Sum(r => r.SuccessTaskCount); return new OperatorIntegrationStats { OperatorUserId = operatorUserId, OperatorUserName = records.First().OperatorUserName, OperatorRealName = records.First().OperatorRealName, IntegrationCount = records.Count, TotalTasks = totalTasks, AverageSuccessRate = totalTasks > 0 ? Math.Round((decimal)successfulTasks / totalTasks * 100, 2) : 0, TotalElapsedTime = records.Sum(r => r.ElapsedMilliseconds), AverageIntegrationTime = records.Any() ? (long)records.Average(r => r.ElapsedMilliseconds) : 0, LastOperationTime = records.Max(r => r.IntegrationTime) }; } /// /// 获取策略效果分析数据 /// 分析不同分配策略的效果,支持策略优化决策 /// public async Task> GetStrategyEffectivenessAsync( DateTime startTime, DateTime endTime) { var records = await Select .Where(r => r.IntegrationTime >= startTime && r.IntegrationTime <= endTime) .Where(r => !r.IsTestData) .ToListAsync(); if (!records.Any()) return new List(); // 解析策略配置并进行分组统计 var strategyGroups = records .Where(r => !string.IsNullOrWhiteSpace(r.StrategyConfigJson)) .GroupBy(r => r.StrategyConfigJson) // 按策略配置JSON分组 .Select(g => new StrategyEffectivenessStats { PersonnelStrategy = ExtractPersonnelStrategyFromJson(g.Key), EquipmentStrategy = ExtractEquipmentStrategyFromJson(g.Key), UsageCount = g.Count(), AverageSuccessRate = CalculateGroupSuccessRate(g.ToList()), AveragePersonnelFairnessScore = Math.Round((decimal)g.Average(r => r.PersonnelFairnessScore), 1), AverageEquipmentUtilizationRate = Math.Round(g.Average(r => r.EquipmentUtilizationRate), 1), AverageElapsedTime = (long)g.Average(r => r.ElapsedMilliseconds) }) .OrderByDescending(s => s.UsageCount) .ToList(); return strategyGroups; } /// /// 获取整合性能趋势数据 /// 生成性能趋势图表数据,支持性能监控 /// public async Task> GetPerformanceTrendAsync(int days = 30) { var startDate = DateTime.Today.AddDays(-days + 1); var endDate = DateTime.Today.AddDays(1); var records = await Select .Where(r => r.IntegrationTime >= startDate && r.IntegrationTime < endDate) .Where(r => !r.IsTestData) .ToListAsync(); var trends = records .GroupBy(r => r.IntegrationTime.Date) .Select(g => new IntegrationPerformanceTrend { Date = g.Key, IntegrationCount = g.Count(), AverageSuccessRate = CalculateGroupSuccessRate(g.ToList()), AverageElapsedTime = (long)g.Average(r => r.ElapsedMilliseconds), TotalTasks = g.Sum(r => r.SuccessTaskCount + r.FailedTaskCount) }) .OrderBy(t => t.Date) .ToList(); // 填充没有数据的日期 var allDates = Enumerable.Range(0, days) .Select(i => startDate.AddDays(i)) .ToList(); var completeTrends = allDates .Select(date => trends.FirstOrDefault(t => t.Date == date) ?? new IntegrationPerformanceTrend { Date = date, IntegrationCount = 0, AverageSuccessRate = 0, AverageElapsedTime = 0, TotalTasks = 0 }) .ToList(); return completeTrends; } #endregion #region 业务专用方法 /// /// 检查批次编码是否已存在 /// 利用唯一索引快速查询 /// public async Task BatchCodeExistsAsync(string batchCode) { if (string.IsNullOrWhiteSpace(batchCode)) return false; return await Select .Where(r => r.IntegrationBatchCode == batchCode) .AnyAsync(); } /// /// 获取最近的整合记录 /// 支持监控面板和快速状态查看 /// public async Task> GetRecentRecordsAsync(int count = 10) { return await Select .Where(r => !r.IsTestData) .OrderByDescending(r => r.IntegrationTime) .Take(count) .ToListAsync(); } /// /// 获取失败率高的整合记录 /// 支持质量监控和问题识别 /// public async Task> GetHighFailureRateRecordsAsync( decimal minFailureRate, DateTime startTime, DateTime endTime, int count = 50) { return await Select .Where(r => r.IntegrationTime >= startTime && r.IntegrationTime <= endTime) .Where(r => !r.IsTestData) .Where(r => r.SuccessTaskCount + r.FailedTaskCount > 0) // 确保有任务数据 .ToListAsync() .ContinueWith(task => { var records = task.Result; return records .Where(r => { var totalTasks = r.SuccessTaskCount + r.FailedTaskCount; var failureRate = totalTasks > 0 ? (decimal)r.FailedTaskCount / totalTasks * 100 : 0; return failureRate >= minFailureRate; }) .OrderByDescending(r => (decimal)r.FailedTaskCount / (r.SuccessTaskCount + r.FailedTaskCount)) .Take(count) .ToList(); }); } /// /// 软删除过期的测试数据 /// 定期数据清理,保持系统性能 /// public async Task SoftDeleteExpiredTestDataAsync(DateTime beforeDate) { var expiredRecords = await Select .Where(r => r.IsTestData && r.CreatedTime < beforeDate) .Where(r => !r.IsDeleted) .ToListAsync(); if (!expiredRecords.Any()) return 0; // 批量软删除 var deletedCount = await UpdateDiy .Set(r => r.IsDeleted, true) .Set(r => r.ModifiedTime, DateTime.Now) .Where(r => expiredRecords.Select(er => er.Id).Contains(r.Id)) .ExecuteAffrowsAsync(); return deletedCount; } #endregion #region 私有辅助方法 /// /// 从策略JSON中提取人员策略 /// private string ExtractPersonnelStrategyFromJson(string strategyConfigJson) { try { if (string.IsNullOrWhiteSpace(strategyConfigJson)) return "未知"; using var document = System.Text.Json.JsonDocument.Parse(strategyConfigJson); var root = document.RootElement; if (root.TryGetProperty("PersonnelStrategy", out var personnelStrategyProp)) { return personnelStrategyProp.GetString() ?? "未知"; } return "未知"; } catch { return "未知"; } } /// /// 从策略JSON中提取设备策略 /// private string ExtractEquipmentStrategyFromJson(string strategyConfigJson) { try { if (string.IsNullOrWhiteSpace(strategyConfigJson)) return "未知"; using var document = System.Text.Json.JsonDocument.Parse(strategyConfigJson); var root = document.RootElement; if (root.TryGetProperty("EquipmentStrategy", out var equipmentStrategyProp)) { return equipmentStrategyProp.GetString() ?? "未知"; } return "未知"; } catch { return "未知"; } } /// /// 计算分组的平均成功率 /// private decimal CalculateGroupSuccessRate(List records) { if (!records.Any()) return 0; var totalTasks = records.Sum(r => r.SuccessTaskCount + r.FailedTaskCount); var successfulTasks = records.Sum(r => r.SuccessTaskCount); return totalTasks > 0 ? Math.Round((decimal)successfulTasks / totalTasks * 100, 2) : 0; } #endregion } }