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
}
}