677 lines
28 KiB
C#
677 lines
28 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Threading.Tasks;
|
||
using Microsoft.AspNetCore.Mvc;
|
||
using Microsoft.Extensions.Logging;
|
||
using NPP.SmartSchedue.Api.Contracts;
|
||
using ZhonTai.Admin.Services;
|
||
using ZhonTai.DynamicApi;
|
||
using ZhonTai.DynamicApi.Attributes;
|
||
using NPP.SmartSchedue.Api.Contracts.Services.Integration;
|
||
using NPP.SmartSchedue.Api.Contracts.Services.Integration.Input;
|
||
using NPP.SmartSchedue.Api.Contracts.Services.Integration.Output;
|
||
using NPP.SmartSchedue.Api.Contracts.Core.Enums;
|
||
using NPP.SmartSchedue.Api.Contracts.Domain.Work;
|
||
using NPP.SmartSchedue.Api.Contracts.Domain.Equipment;
|
||
using NPP.SmartSchedue.Api.Contracts.Domain.Personnel;
|
||
using NPP.SmartSchedue.Api.Contracts.Domain.Time;
|
||
using NPP.SmartSchedue.Api.Repositories.Work;
|
||
|
||
namespace NPP.SmartSchedue.Api.Services.Integration
|
||
{
|
||
/// <summary>
|
||
/// 任务验证服务
|
||
/// 职责:专门负责任务数据完整性验证、业务规则检查和需求分析
|
||
/// 架构思考:集中处理所有验证逻辑,确保数据质量和业务规则一致性
|
||
/// </summary>
|
||
[DynamicApi(Area = "app")]
|
||
public class TaskValidationService : BaseService, ITaskValidationService
|
||
{
|
||
private readonly WorkOrderRepository _workOrderRepository;
|
||
private readonly IShiftRuleMappingRepository _shiftRuleMappingRepository;
|
||
private readonly IShiftRepository _shiftRepository;
|
||
private readonly IEquipmentRepository _equipmentRepository;
|
||
private readonly ILogger<TaskValidationService> _logger;
|
||
|
||
public TaskValidationService(
|
||
WorkOrderRepository workOrderRepository,
|
||
IShiftRuleMappingRepository shiftRuleMappingRepository,
|
||
IShiftRepository shiftRepository,
|
||
IEquipmentRepository equipmentRepository,
|
||
ILogger<TaskValidationService> logger)
|
||
{
|
||
_workOrderRepository = workOrderRepository;
|
||
_shiftRuleMappingRepository = shiftRuleMappingRepository ?? throw new ArgumentNullException(nameof(shiftRuleMappingRepository));
|
||
_shiftRepository = shiftRepository ?? throw new ArgumentNullException(nameof(shiftRepository));
|
||
_equipmentRepository = equipmentRepository ?? throw new ArgumentNullException(nameof(equipmentRepository));
|
||
_logger = logger;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 分析任务需求
|
||
/// 深度业务思考:按照文档1.1步骤进行完整的任务需求分析
|
||
/// </summary>
|
||
[HttpPost]
|
||
public async Task<TaskRequirementAnalysisResult> AnalyzeTaskRequirementsAsync(List<WorkOrderEntity> tasks)
|
||
{
|
||
var result = new TaskRequirementAnalysisResult
|
||
{
|
||
ProcessRequirements = new List<TaskProcessRequirement>(),
|
||
ResourceRequirements = new ResourceRequirement(),
|
||
TimeDistribution = new TimeDistribution(),
|
||
AnalysisSummary = ""
|
||
};
|
||
|
||
try
|
||
{
|
||
// 1.1.1 工序需求提取
|
||
var processReqs = ExtractProcessRequirements(tasks);
|
||
result.ProcessRequirements = processReqs.Select(p => new TaskProcessRequirement
|
||
{
|
||
TaskId = p.TaskId,
|
||
ProcessId = p.ProcessId,
|
||
RequiredQualifications = p.RequiredQualifications,
|
||
EstimatedDuration = p.EstimatedDuration,
|
||
EquipmentTypeId = p.EquipmentTypeId
|
||
}).ToList();
|
||
|
||
// 1.1.2 资源需求统计
|
||
result.ResourceRequirements = await StatisticalResourceRequirementsAsync(tasks);
|
||
|
||
// 生成分析摘要
|
||
result.AnalysisSummary = GenerateRequirementAnalysisSummary(result, tasks.Count);
|
||
|
||
_logger.LogInformation("任务需求分析完成: 总任务数={TaskCount}, 工序类型数={ProcessTypes}",
|
||
tasks.Count, result.ProcessRequirements.Select(p => p.ProcessId).Distinct().Count());
|
||
|
||
return result;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "任务需求分析失败: {Message}", ex.Message);
|
||
result.AnalysisSummary = $"需求分析异常: {ex.Message}";
|
||
return result;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 验证任务数据完整性
|
||
/// 深度业务思考:按照文档1.2步骤进行全面的数据完整性检查
|
||
/// </summary>
|
||
[HttpPost]
|
||
public async Task<TaskDataValidationResult> ValidateTaskDataIntegrityAsync(List<WorkOrderEntity> tasks)
|
||
{
|
||
var result = new TaskDataValidationResult
|
||
{
|
||
IsValid = true,
|
||
ValidationIssues = new List<ValidationIssue>(),
|
||
BusinessRuleViolations = new List<BusinessRuleViolation>(),
|
||
ValidationSummary = ""
|
||
};
|
||
|
||
try
|
||
{
|
||
// 1.2.1 基础数据完整性检查
|
||
var dataIntegrityIssues = await ValidateBasicDataIntegrityAsync(tasks);
|
||
result.ValidationIssues.AddRange(dataIntegrityIssues);
|
||
|
||
// 1.2.2 业务规则预检查
|
||
var businessRuleViolations = await ValidateBusinessRulesAsync(tasks);
|
||
result.BusinessRuleViolations.AddRange(businessRuleViolations);
|
||
|
||
// 确定整体验证结果
|
||
result.IsValid = !result.ValidationIssues.Any() && !result.BusinessRuleViolations.Any();
|
||
result.ValidationSummary = GenerateValidationSummary(result, tasks.Count);
|
||
|
||
if (!result.IsValid)
|
||
{
|
||
_logger.LogWarning("任务数据验证发现问题: 完整性问题={IntegrityIssues}, 业务规则违反={BusinessRuleViolations}",
|
||
result.ValidationIssues.Count, result.BusinessRuleViolations.Count);
|
||
}
|
||
else
|
||
{
|
||
_logger.LogInformation("任务数据验证通过: 总任务数={TaskCount}", tasks.Count);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "任务数据验证失败: {Message}", ex.Message);
|
||
result.IsValid = false;
|
||
result.ValidationSummary = $"验证过程异常: {ex.Message}";
|
||
return result;
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载任务详细信息
|
||
/// 深度业务思考:按照文档1.3步骤优化关联数据加载和结构化处理
|
||
/// </summary>
|
||
[HttpPost]
|
||
public async Task<TaskDetailLoadResult> LoadTaskDetailedInfoAsync(List<WorkOrderEntity> tasks)
|
||
{
|
||
var result = new TaskDetailLoadResult
|
||
{
|
||
TaskDetails = new List<TaskDetailInfo>(),
|
||
LoadedDataStatistics = new LoadedDataStatistics(),
|
||
OptimizationSummary = ""
|
||
};
|
||
|
||
try
|
||
{
|
||
var taskIds = tasks.Select(t => t.Id).ToList();
|
||
|
||
// 1.3.1 关联数据加载策略
|
||
var taskDetails = await LoadTaskAssociatedDataAsync(taskIds);
|
||
|
||
// 1.3.2 数据结构优化
|
||
var optimizedData = await OptimizeDataStructuresAsync(taskDetails);
|
||
result.TaskDetails = optimizedData.TaskDetails;
|
||
result.LoadedDataStatistics = optimizedData.Statistics;
|
||
|
||
result.OptimizationSummary = GenerateLoadingSummary(result, tasks.Count);
|
||
|
||
_logger.LogInformation("任务详细信息加载完成: 任务数={TaskCount}, 关联数据项={AssociatedDataCount}",
|
||
tasks.Count, result.LoadedDataStatistics.TotalAssociatedRecords);
|
||
|
||
return result;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "任务详细信息加载失败: {Message}", ex.Message);
|
||
result.OptimizationSummary = $"加载过程异常: {ex.Message}";
|
||
return result;
|
||
}
|
||
}
|
||
|
||
#region 1.1 任务需求分析
|
||
|
||
/// <summary>
|
||
/// 内部工序需求结构
|
||
/// </summary>
|
||
private class InternalProcessRequirement
|
||
{
|
||
public long TaskId { get; set; }
|
||
public long ProcessId { get; set; }
|
||
public List<string> RequiredQualifications { get; set; } = new List<string>();
|
||
public TimeSpan? EstimatedDuration { get; set; }
|
||
public long? EquipmentTypeId { get; set; }
|
||
}
|
||
|
||
/// <summary>
|
||
/// 提取工序需求
|
||
/// 高级工程师修复:正确解析字符串格式的资质要求
|
||
/// ProcessEntity.QualificationRequirements 是逗号分隔的资质ID字符串
|
||
/// </summary>
|
||
private List<InternalProcessRequirement> ExtractProcessRequirements(List<WorkOrderEntity> tasks)
|
||
{
|
||
var result = new List<InternalProcessRequirement>(tasks.Count);
|
||
|
||
foreach (var task in tasks)
|
||
{
|
||
var requirement = new InternalProcessRequirement
|
||
{
|
||
TaskId = task.Id,
|
||
ProcessId = task.ProcessId,
|
||
RequiredQualifications = ParseQualificationIds(task.ProcessEntity?.QualificationRequirements),
|
||
EstimatedDuration = task.ProcessEntity?.EstimatedDuration,
|
||
EquipmentTypeId = task.ProcessEntity?.EquipmentTypeId
|
||
};
|
||
|
||
result.Add(requirement);
|
||
}
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 解析资质ID字符串
|
||
/// 高级工程师实现:严格的字符串解析和验证
|
||
/// </summary>
|
||
/// <param name="qualificationRequirements">逗号分隔的资质ID字符串,如 "1,2,3"</param>
|
||
/// <returns>资质ID列表(转换为字符串以保持兼容性)</returns>
|
||
private List<string> ParseQualificationIds(string qualificationRequirements)
|
||
{
|
||
if (string.IsNullOrWhiteSpace(qualificationRequirements))
|
||
return new List<string>();
|
||
|
||
try
|
||
{
|
||
return qualificationRequirements
|
||
.Split(QualificationIdSeparators, StringSplitOptions.RemoveEmptyEntries)
|
||
.Select(id => id.Trim())
|
||
.Where(id => !string.IsNullOrWhiteSpace(id) && long.TryParse(id, out var numId) && numId > 0)
|
||
.ToList();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogWarning(ex, "解析工序资质要求字符串失败: {QualificationRequirements}", qualificationRequirements);
|
||
return new List<string>();
|
||
}
|
||
}
|
||
|
||
/// <summary>资质ID分隔符数组</summary>
|
||
private static readonly char[] QualificationIdSeparators = { ',', ';', '|' };
|
||
|
||
/// <summary>
|
||
/// 统计资源需求
|
||
/// 高级工程师修复:正确解析字符串格式的资质要求进行统计
|
||
/// 修复异步警告:改为同步方法,因为没有异步操作
|
||
/// </summary>
|
||
private Task<ResourceRequirement> StatisticalResourceRequirementsAsync(List<WorkOrderEntity> tasks)
|
||
{
|
||
var qualificationStats = new Dictionary<long, int>();
|
||
var equipmentTypeStats = new Dictionary<string, double>();
|
||
|
||
foreach (var task in tasks)
|
||
{
|
||
// 人员资质需求统计 - 修复:从字符串解析资质ID
|
||
if (!string.IsNullOrWhiteSpace(task.ProcessEntity?.QualificationRequirements))
|
||
{
|
||
var qualificationIds = ParseQualificationIds(task.ProcessEntity.QualificationRequirements);
|
||
foreach (var qualificationIdStr in qualificationIds)
|
||
{
|
||
if (long.TryParse(qualificationIdStr, out var qualificationId))
|
||
{
|
||
qualificationStats[qualificationId] =
|
||
qualificationStats.GetValueOrDefault(qualificationId, 0) + 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 设备类型需求统计
|
||
if (!string.IsNullOrWhiteSpace(task.ProcessEntity?.EquipmentType) )
|
||
{
|
||
var equipmentType = task.ProcessEntity.EquipmentType;
|
||
var duration = (double)(task.ProcessEntity?.TheoreticalDuration ?? (decimal)DefaultTaskDurationHours);
|
||
equipmentTypeStats[equipmentType] =
|
||
equipmentTypeStats.GetValueOrDefault(equipmentType, 0) + duration;
|
||
}
|
||
}
|
||
|
||
_logger.LogDebug("资源需求统计完成: 资质类型 {QualificationCount} 个,设备类型 {EquipmentCount} 个",
|
||
qualificationStats.Count, equipmentTypeStats.Count);
|
||
|
||
return Task.FromResult(new ResourceRequirement
|
||
{
|
||
QualificationRequirements = qualificationStats,
|
||
EquipmentTypeRequirements = equipmentTypeStats
|
||
});
|
||
}
|
||
|
||
/// <summary>默认任务持续时间(小时)</summary>
|
||
private const double DefaultTaskDurationHours = 8.0;
|
||
#endregion
|
||
|
||
#region 1.2 任务数据完整性验证
|
||
|
||
/// <summary>
|
||
/// 验证基础数据完整性
|
||
/// </summary>
|
||
private async Task<List<ValidationIssue>> ValidateBasicDataIntegrityAsync(List<WorkOrderEntity> tasks)
|
||
{
|
||
var validationIssues = new List<ValidationIssue>();
|
||
|
||
foreach (var task in tasks)
|
||
{
|
||
// 检查工序信息完整性
|
||
if (task.ProcessEntity == null)
|
||
{
|
||
validationIssues.Add(new ValidationIssue
|
||
{
|
||
TaskId = task.Id,
|
||
IssueType = ValidationIssueType.MissingProcess,
|
||
Description = "工序信息缺失",
|
||
Severity = ValidationSeverity.Error
|
||
});
|
||
}
|
||
|
||
// 检查班次信息
|
||
if (!task.ShiftId.HasValue || task.ShiftId == 0)
|
||
{
|
||
validationIssues.Add(new ValidationIssue
|
||
{
|
||
TaskId = task.Id,
|
||
IssueType = ValidationIssueType.MissingShift,
|
||
Description = "班次信息缺失",
|
||
Severity = ValidationSeverity.Error
|
||
});
|
||
}
|
||
|
||
// 检查项目编号
|
||
if (string.IsNullOrWhiteSpace(task.ProjectNumber))
|
||
{
|
||
validationIssues.Add(new ValidationIssue
|
||
{
|
||
TaskId = task.Id,
|
||
IssueType = ValidationIssueType.MissingProjectNumber,
|
||
Description = "项目编号缺失",
|
||
Severity = ValidationSeverity.Warning
|
||
});
|
||
}
|
||
}
|
||
|
||
return validationIssues;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 验证业务规则
|
||
/// </summary>
|
||
private async Task<List<BusinessRuleViolation>> ValidateBusinessRulesAsync(List<WorkOrderEntity> tasks)
|
||
{
|
||
var violations = new List<BusinessRuleViolation>();
|
||
|
||
foreach (var task in tasks)
|
||
{
|
||
// 资质要求验证
|
||
if (!string.IsNullOrWhiteSpace(task.ProcessEntity?.QualificationRequirements))
|
||
{
|
||
var qualificationViolations = await ValidateQualificationRequirementsAsync(task);
|
||
violations.AddRange(qualificationViolations);
|
||
}
|
||
|
||
// 设备可用性预检
|
||
if (!string.IsNullOrWhiteSpace(task.ProcessEntity?.EquipmentType))
|
||
{
|
||
var equipmentViolations = await ValidateEquipmentAvailabilityAsync(task);
|
||
violations.AddRange(equipmentViolations);
|
||
}
|
||
}
|
||
|
||
return violations;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 验证班次规则
|
||
/// </summary>
|
||
private async Task<List<BusinessRuleViolation>> ValidateShiftRulesAsync(WorkOrderEntity task)
|
||
{
|
||
var violations = new List<BusinessRuleViolation>();
|
||
|
||
// 暂时注释班次规则验证,需要完善ShiftEntity导航属性
|
||
// if (task.ShiftEntity?.ShiftRules?.Any() == true)
|
||
// {
|
||
// foreach (var rule in task.ShiftEntity.ShiftRules)
|
||
// {
|
||
// // 检查任务时间是否符合班次规则
|
||
// if (rule.Type == ShiftRuleTypeEnum.WorkingHours)
|
||
// {
|
||
// var taskStartHour = task.PlannedStartTime.Hour;
|
||
// var taskEndHour = task.PlannedEndTime.Hour;
|
||
//
|
||
// if (taskStartHour < 6 || taskEndHour > 22) // 示例规则
|
||
// {
|
||
// violations.Add(new BusinessRuleViolation
|
||
// {
|
||
// TaskId = task.Id,
|
||
// RuleType = BusinessRuleType.ShiftRule,
|
||
// RuleDescription = $"任务时间超出班次工作时间范围",
|
||
// ViolationDetails = $"任务时间: {task.PlannedStartTime:HH:mm}-{task.PlannedEndTime:HH:mm}"
|
||
// });
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
|
||
return violations;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 验证资质要求
|
||
/// </summary>
|
||
private async Task<List<BusinessRuleViolation>> ValidateQualificationRequirementsAsync(WorkOrderEntity task)
|
||
{
|
||
var violations = new List<BusinessRuleViolation>();
|
||
|
||
if (!string.IsNullOrWhiteSpace(task.ProcessEntity?.QualificationRequirements))
|
||
{
|
||
// 解析资质ID字符串并验证
|
||
var qualificationIds = ParseQualificationIds(task.ProcessEntity.QualificationRequirements);
|
||
foreach (var qualificationIdStr in qualificationIds)
|
||
{
|
||
if (!long.TryParse(qualificationIdStr, out var qualificationId) || qualificationId <= 0)
|
||
{
|
||
violations.Add(new BusinessRuleViolation
|
||
{
|
||
TaskId = task.Id,
|
||
RuleType = BusinessRuleType.QualificationRequirement,
|
||
RuleDescription = "无效的资质要求配置",
|
||
ViolationDetails = $"资质ID: {qualificationIdStr}"
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
return violations;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 验证设备可用性
|
||
/// </summary>
|
||
private async Task<List<BusinessRuleViolation>> ValidateEquipmentAvailabilityAsync(WorkOrderEntity task)
|
||
{
|
||
var violations = new List<BusinessRuleViolation>();
|
||
|
||
if (!string.IsNullOrWhiteSpace(task.ProcessEntity?.EquipmentType))
|
||
{
|
||
// 使用 EquipmentRepository 检查指定设备类型是否有可用设备
|
||
var hasAvailableEquipment = await _equipmentRepository.HasAvailableEquipmentByTypeAsync(task.ProcessEntity.EquipmentType);
|
||
|
||
if (!hasAvailableEquipment)
|
||
{
|
||
violations.Add(new BusinessRuleViolation
|
||
{
|
||
TaskId = task.Id,
|
||
RuleType = BusinessRuleType.EquipmentAvailability,
|
||
RuleDescription = "所需设备类型暂无可用设备",
|
||
ViolationDetails = $"设备类型: {task.ProcessEntity.EquipmentType}"
|
||
});
|
||
}
|
||
}
|
||
|
||
return violations;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 1.3 任务详细信息加载
|
||
|
||
/// <summary>
|
||
/// 加载任务关联数据
|
||
/// 批量加载优化查询性能
|
||
/// </summary>
|
||
private async Task<List<TaskDetailInfo>> LoadTaskAssociatedDataAsync(List<long> taskIds)
|
||
{
|
||
var taskDetails = await _workOrderRepository.Select
|
||
.Where(w => taskIds.Contains(w.Id))
|
||
.IncludeMany(w => w.WorkOrderFLPersonnels)
|
||
.Include(w => w.ShiftEntity)
|
||
.Include(w => w.ProcessEntity)
|
||
.ToListAsync();
|
||
|
||
// 批量获取班次规则数据
|
||
var shiftIds = taskDetails.Where(t => t.ShiftId.HasValue).Select(t => t.ShiftId.Value).Distinct().ToList();
|
||
var shiftRulesMap = await _shiftRuleMappingRepository.GetBatchShiftRulesAsync(shiftIds);
|
||
|
||
return taskDetails.Select(task => new TaskDetailInfo
|
||
{
|
||
TaskId = task.Id,
|
||
TaskCode = task.Code,
|
||
ShiftRules = task.ShiftId.HasValue && shiftRulesMap.ContainsKey(task.ShiftId.Value)
|
||
? shiftRulesMap[task.ShiftId.Value]
|
||
: new List<ShiftRuleEntity>(),
|
||
QualificationRequirements = ConvertQualificationRequirements(task.ProcessEntity?.QualificationRequirements),
|
||
FLPersonnelRelations = task.WorkOrderFLPersonnels?.ToList() ?? new List<WorkOrderFLPersonnelEntity>()
|
||
}).ToList();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 优化数据结构
|
||
/// </summary>
|
||
private async Task<(List<TaskDetailInfo> TaskDetails, LoadedDataStatistics Statistics)> OptimizeDataStructuresAsync(
|
||
List<TaskDetailInfo> taskDetails)
|
||
{
|
||
var statistics = new LoadedDataStatistics
|
||
{
|
||
TotalTasks = taskDetails.Count,
|
||
TotalAssociatedRecords = 0,
|
||
ShiftRulesCount = 0,
|
||
QualificationRequirementsCount = 0,
|
||
FLPersonnelRelationsCount = 0,
|
||
SpecifiedConstraintsCount = 0
|
||
};
|
||
|
||
// 构建快速查询索引
|
||
var shiftRuleIndex = new Dictionary<long, List<ShiftRuleEntity>>();
|
||
var qualificationIndex = new Dictionary<long, List<NPP.SmartSchedue.Api.Contracts.Services.Integration.Output.QualificationRequirement>>();
|
||
|
||
foreach (var detail in taskDetails)
|
||
{
|
||
// 班次规则解析和索引
|
||
if (detail.ShiftRules.Any())
|
||
{
|
||
shiftRuleIndex[detail.TaskId] = detail.ShiftRules;
|
||
statistics.ShiftRulesCount += detail.ShiftRules.Count;
|
||
}
|
||
|
||
// 资质要求映射和索引
|
||
if (detail.QualificationRequirements.Any())
|
||
{
|
||
qualificationIndex[detail.TaskId] = detail.QualificationRequirements;
|
||
statistics.QualificationRequirementsCount += detail.QualificationRequirements.Count;
|
||
}
|
||
|
||
// FL人员关系计数
|
||
if (detail.FLPersonnelRelations.Any())
|
||
{
|
||
statistics.FLPersonnelRelationsCount += detail.FLPersonnelRelations.Count;
|
||
}
|
||
|
||
// 指定约束计数(暂时不统计,因为没有指定约束)
|
||
statistics.SpecifiedConstraintsCount = 0;
|
||
}
|
||
|
||
statistics.TotalAssociatedRecords = statistics.ShiftRulesCount +
|
||
statistics.QualificationRequirementsCount +
|
||
statistics.FLPersonnelRelationsCount +
|
||
statistics.SpecifiedConstraintsCount;
|
||
|
||
return (taskDetails, statistics);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 转换资质要求为输出格式
|
||
/// 深度业务思考:统一资质要求的数据格式,便于后续验证和分配使用
|
||
/// 高级工程师优化:
|
||
/// 1. 正确解析字符串格式的资质ID(逗号分隔)
|
||
/// 2. 严格的空值和异常处理
|
||
/// 3. 业务规则验证
|
||
/// 4. 性能优化
|
||
/// 5. 常量化硬编码值
|
||
/// </summary>
|
||
private List<QualificationRequirement> ConvertQualificationRequirements(
|
||
string qualificationRequirementsStr)
|
||
{
|
||
// 防御性编程:空字符串处理
|
||
if (string.IsNullOrWhiteSpace(qualificationRequirementsStr))
|
||
{
|
||
_logger.LogDebug("工序资质要求字符串为空,返回空结果");
|
||
return new List<QualificationRequirement>();
|
||
}
|
||
|
||
try
|
||
{
|
||
// 解析资质ID字符串
|
||
var qualificationIds = ParseQualificationIds(qualificationRequirementsStr);
|
||
if (!qualificationIds.Any())
|
||
{
|
||
_logger.LogDebug("工序资质要求字符串解析后为空: {QualificationRequirements}", qualificationRequirementsStr);
|
||
return new List<QualificationRequirement>();
|
||
}
|
||
|
||
var result = new List<QualificationRequirement>(qualificationIds.Count);
|
||
|
||
foreach (var qualificationIdStr in qualificationIds)
|
||
{
|
||
if (!long.TryParse(qualificationIdStr, out var qualificationId) || qualificationId <= 0)
|
||
{
|
||
_logger.LogWarning("发现无效的资质ID字符串: {QualificationId},已跳过", qualificationIdStr);
|
||
continue;
|
||
}
|
||
|
||
var qualification = new QualificationRequirement
|
||
{
|
||
QualificationId = qualificationId,
|
||
QualificationName = $"资质{qualificationId}", // 临时名称,实际应用中需要查询资质表
|
||
};
|
||
|
||
result.Add(qualification);
|
||
}
|
||
|
||
_logger.LogDebug("成功转换 {Count} 个工序资质要求", result.Count);
|
||
return result;
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
_logger.LogError(ex, "转换工序资质要求时发生异常: {QualificationRequirements}", qualificationRequirementsStr);
|
||
return new List<QualificationRequirement>();
|
||
}
|
||
}
|
||
|
||
#region 资质转换常量定义
|
||
|
||
/// <summary>默认资质等级</summary>
|
||
private const int DefaultQualificationLevel = 1;
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
|
||
#region 辅助方法和摘要生成
|
||
|
||
/// <summary>
|
||
/// 生成需求分析摘要
|
||
/// </summary>
|
||
private string GenerateRequirementAnalysisSummary(TaskRequirementAnalysisResult result, int totalTasks)
|
||
{
|
||
var processTypeCount = result.ProcessRequirements.Select(p => p.ProcessId).Distinct().Count();
|
||
var qualificationTypeCount = result.ResourceRequirements.QualificationRequirements.Count;
|
||
var equipmentTypeCount = result.ResourceRequirements.EquipmentTypeRequirements.Count;
|
||
|
||
return $"需求分析完成: 总任务{totalTasks}个, 涉及{processTypeCount}种工序, " +
|
||
$"{qualificationTypeCount}种资质需求, {equipmentTypeCount}种设备类型需求。";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成验证摘要
|
||
/// </summary>
|
||
private string GenerateValidationSummary(TaskDataValidationResult result, int totalTasks)
|
||
{
|
||
if (result.IsValid)
|
||
{
|
||
return $"数据验证通过: 总任务{totalTasks}个, 数据完整性和业务规则均符合要求。";
|
||
}
|
||
else
|
||
{
|
||
return $"数据验证发现问题: 总任务{totalTasks}个, " +
|
||
$"完整性问题{result.ValidationIssues.Count}个, " +
|
||
$"业务规则违反{result.BusinessRuleViolations.Count}个。";
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 生成加载摘要
|
||
/// </summary>
|
||
private string GenerateLoadingSummary(TaskDetailLoadResult result, int totalTasks)
|
||
{
|
||
return $"详细信息加载完成: 任务{totalTasks}个, " +
|
||
$"关联数据{result.LoadedDataStatistics.TotalAssociatedRecords}条, " +
|
||
$"包含班次规则{result.LoadedDataStatistics.ShiftRulesCount}条, " +
|
||
$"资质要求{result.LoadedDataStatistics.QualificationRequirementsCount}条。";
|
||
}
|
||
|
||
#endregion
|
||
}
|
||
} |