1027 lines
29 KiB
C#
1027 lines
29 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using NPP.SmartSchedue.Api.Contracts.Services.Integration.Models;
|
|
|
|
namespace NPP.SmartSchedue.Api.Contracts.Services.Integration.Output
|
|
{
|
|
/// <summary>
|
|
/// 人员分配生成结果
|
|
/// 智能分配算法第四层:结果生成阶段的核心数据模型
|
|
/// 包含成功分配、失败分配、质量评估、性能指标等完整业务信息
|
|
/// </summary>
|
|
public class AllocationGenerationResult
|
|
{
|
|
#region 核心分配结果
|
|
|
|
/// <summary>
|
|
/// 成功分配的任务与人员映射
|
|
/// Key: 工作任务ID, Value: 最佳匹配的人员候选人
|
|
/// </summary>
|
|
public Dictionary<long, PersonnelCandidate> SuccessfulAllocations { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// 分配失败的任务列表
|
|
/// 包含失败原因、类型和建议解决方案
|
|
/// </summary>
|
|
public List<FailedAllocation> FailedAllocations { get; set; } = new();
|
|
|
|
#endregion
|
|
|
|
#region 质量评估指标
|
|
|
|
/// <summary>
|
|
/// 整体质量评分 (0-100)
|
|
/// 综合考虑成功率、平均匹配分数、约束符合度等因素
|
|
/// </summary>
|
|
public double OverallQualityScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 分配成功率 (0-100)
|
|
/// 计算公式:成功分配数量 / 总任务数量 * 100
|
|
/// </summary>
|
|
public double SuccessRate => CalculateSuccessRate();
|
|
|
|
/// <summary>
|
|
/// 平均匹配质量分数 (0-100)
|
|
/// 所有成功分配的人员候选人平均评分
|
|
/// </summary>
|
|
public double AverageMatchQuality => CalculateAverageMatchQuality();
|
|
|
|
#endregion
|
|
|
|
#region 详细分析报告
|
|
|
|
/// <summary>
|
|
/// 详细分配报告
|
|
/// 包含统计信息、人员利用率、风险分析等详细数据
|
|
/// </summary>
|
|
public AllocationReport DetailedReport { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// 分配策略执行摘要
|
|
/// 人性化的分配结果描述,便于业务人员理解
|
|
/// </summary>
|
|
public string AllocationSummary { get; set; } = string.Empty;
|
|
|
|
#endregion
|
|
|
|
#region 性能监控指标
|
|
|
|
/// <summary>
|
|
/// 性能监控指标
|
|
/// 记录各个处理阶段的执行时间、资源消耗等性能数据
|
|
/// </summary>
|
|
public Dictionary<string, object> PerformanceMetrics { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// 算法执行总耗时(毫秒)
|
|
/// </summary>
|
|
public long TotalExecutionTimeMs => GetExecutionTime();
|
|
|
|
/// <summary>
|
|
/// 内存使用峰值(字节)
|
|
/// </summary>
|
|
public long PeakMemoryUsageBytes { get; set; }
|
|
|
|
#endregion
|
|
|
|
#region 业务洞察分析
|
|
|
|
/// <summary>
|
|
/// 人员工作负载分布
|
|
/// 分析各人员的任务分配数量和工作强度
|
|
/// </summary>
|
|
public Dictionary<long, PersonnelWorkloadInfo> PersonnelWorkloadDistribution => CalculateWorkloadDistribution();
|
|
|
|
/// <summary>
|
|
/// 技能匹配度分析
|
|
/// 评估整体技能匹配情况和资质覆盖度
|
|
/// </summary>
|
|
public SkillMatchAnalysis SkillMatchingAnalysis => AnalyzeSkillMatching();
|
|
|
|
/// <summary>
|
|
/// 约束冲突统计
|
|
/// 统计各类约束冲突的分布情况
|
|
/// </summary>
|
|
public Dictionary<string, int> ConstraintConflictStatistics => AnalyzeConstraintConflicts();
|
|
|
|
#endregion
|
|
|
|
#region 辅助计算方法
|
|
|
|
/// <summary>
|
|
/// 计算分配成功率
|
|
/// </summary>
|
|
private double CalculateSuccessRate()
|
|
{
|
|
var totalTasks = SuccessfulAllocations.Count + FailedAllocations.Count;
|
|
return totalTasks > 0 ? (double)SuccessfulAllocations.Count / totalTasks * 100 : 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 计算平均匹配质量
|
|
/// </summary>
|
|
private double CalculateAverageMatchQuality()
|
|
{
|
|
return SuccessfulAllocations.Any()
|
|
? SuccessfulAllocations.Values.Average(c => c.TotalScore)
|
|
: 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取执行时间
|
|
/// </summary>
|
|
private long GetExecutionTime()
|
|
{
|
|
return PerformanceMetrics.TryGetValue("TotalExecutionTime", out var time)
|
|
? Convert.ToInt64(time)
|
|
: 0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 计算人员工作负载分布
|
|
/// </summary>
|
|
private Dictionary<long, PersonnelWorkloadInfo> CalculateWorkloadDistribution()
|
|
{
|
|
return SuccessfulAllocations.Values
|
|
.GroupBy(c => c.PersonnelId)
|
|
.ToDictionary(
|
|
g => g.Key,
|
|
g => new PersonnelWorkloadInfo
|
|
{
|
|
PersonnelId = g.Key,
|
|
PersonnelName = g.First().PersonnelName,
|
|
AssignedTaskCount = g.Count(),
|
|
AverageMatchScore = g.Average(c => c.TotalScore),
|
|
TotalWorkload = g.Sum(c => c.EstimatedWorkload ?? 1.0)
|
|
});
|
|
}
|
|
|
|
/// <summary>
|
|
/// 分析技能匹配情况
|
|
/// </summary>
|
|
private SkillMatchAnalysis AnalyzeSkillMatching()
|
|
{
|
|
var analysis = new SkillMatchAnalysis();
|
|
|
|
if (SuccessfulAllocations.Any())
|
|
{
|
|
analysis.AverageSkillMatchScore = SuccessfulAllocations.Values
|
|
.Average(c => c.QualificationScore?.MatchScore ?? 0);
|
|
|
|
analysis.FullyQualifiedCount = SuccessfulAllocations.Values
|
|
.Count(c => (c.QualificationScore?.MatchScore ?? 0) >= 90);
|
|
|
|
analysis.PartiallyQualifiedCount = SuccessfulAllocations.Values
|
|
.Count(c => (c.QualificationScore?.MatchScore ?? 0) >= 70 &&
|
|
(c.QualificationScore?.MatchScore ?? 0) < 90);
|
|
|
|
analysis.MinimallyQualifiedCount = SuccessfulAllocations.Values
|
|
.Count(c => (c.QualificationScore?.MatchScore ?? 0) < 70);
|
|
}
|
|
|
|
return analysis;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 分析约束冲突分布
|
|
/// </summary>
|
|
private Dictionary<string, int> AnalyzeConstraintConflicts()
|
|
{
|
|
var conflicts = new Dictionary<string, int>();
|
|
|
|
foreach (var failure in FailedAllocations)
|
|
{
|
|
var conflictType = failure.FailureType.ToString();
|
|
conflicts[conflictType] = conflicts.GetValueOrDefault(conflictType, 0) + 1;
|
|
}
|
|
|
|
return conflicts;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 验证和健康检查
|
|
|
|
/// <summary>
|
|
/// 验证结果数据完整性
|
|
/// </summary>
|
|
public ValidationResult ValidateResultIntegrity()
|
|
{
|
|
var result = new ValidationResult { IsValid = true, Issues = new List<string>() };
|
|
|
|
// 检查基础数据完整性
|
|
if (SuccessfulAllocations == null)
|
|
{
|
|
result.IsValid = false;
|
|
result.Issues.Add("成功分配数据为空");
|
|
}
|
|
|
|
if (FailedAllocations == null)
|
|
{
|
|
result.IsValid = false;
|
|
result.Issues.Add("失败分配数据为空");
|
|
}
|
|
|
|
// 检查质量评分合理性
|
|
if (OverallQualityScore < 0 || OverallQualityScore > 100)
|
|
{
|
|
result.IsValid = false;
|
|
result.Issues.Add($"整体质量评分超出范围: {OverallQualityScore}");
|
|
}
|
|
|
|
// 检查性能指标
|
|
if (PerformanceMetrics == null || !PerformanceMetrics.Any())
|
|
{
|
|
result.Issues.Add("缺少性能监控数据");
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 获取结果健康状态
|
|
/// </summary>
|
|
public HealthStatus GetHealthStatus()
|
|
{
|
|
var successRate = SuccessRate;
|
|
var avgQuality = AverageMatchQuality;
|
|
|
|
if (successRate >= 90 && avgQuality >= 80)
|
|
return HealthStatus.Excellent;
|
|
else if (successRate >= 70 && avgQuality >= 70)
|
|
return HealthStatus.Good;
|
|
else if (successRate >= 50 && avgQuality >= 60)
|
|
return HealthStatus.Fair;
|
|
else
|
|
return HealthStatus.Poor;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
#region 支持类定义
|
|
|
|
/// <summary>
|
|
/// 人员候选人信息
|
|
/// 包含完整的评分体系和匹配详情
|
|
/// </summary>
|
|
public class PersonnelCandidate
|
|
{
|
|
/// <summary>
|
|
/// 人员ID
|
|
/// </summary>
|
|
public long PersonnelId { get; set; }
|
|
|
|
/// <summary>
|
|
/// 人员姓名
|
|
/// </summary>
|
|
public string PersonnelName { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// 资质评分详情
|
|
/// </summary>
|
|
public QualificationScore QualificationScore { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// 约束条件评分
|
|
/// </summary>
|
|
public ConstraintScore ConstraintScore { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// 优化决策评分
|
|
/// </summary>
|
|
public OptimizationScore OptimizationScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 综合总分 (0-100)
|
|
/// </summary>
|
|
public double TotalScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 是否为最优选择
|
|
/// </summary>
|
|
public bool IsOptimalChoice { get; set; }
|
|
|
|
/// <summary>
|
|
/// 候选人排名
|
|
/// </summary>
|
|
public int Rank { get; set; }
|
|
|
|
/// <summary>
|
|
/// 分配理由说明
|
|
/// </summary>
|
|
public string AllocationReason { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// 预估工作负载
|
|
/// </summary>
|
|
public double? EstimatedWorkload { get; set; }
|
|
|
|
/// <summary>
|
|
/// 风险评估等级
|
|
/// </summary>
|
|
public RiskLevel RiskLevel { get; set; } = RiskLevel.Low;
|
|
|
|
/// <summary>
|
|
/// 决策评分
|
|
/// </summary>
|
|
public DecisionScore DecisionScore { get; set; } = new();
|
|
|
|
public RecommendationLevel RecommendationLevel { get; set; } = RecommendationLevel.NotRecommended;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 资质评分详情
|
|
/// </summary>
|
|
public class QualificationScore
|
|
{
|
|
/// <summary>
|
|
/// 资质匹配分数 (0-100)
|
|
/// </summary>
|
|
public double MatchScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 是否资质有效
|
|
/// </summary>
|
|
public bool IsQualificationValid { get; set; }
|
|
|
|
/// <summary>
|
|
/// 匹配的资质列表
|
|
/// </summary>
|
|
public List<string> MatchedQualifications { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// 缺失的资质列表
|
|
/// </summary>
|
|
public List<string> MissingQualifications { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// 资质详细信息
|
|
/// </summary>
|
|
public string QualificationDetails { get; set; } = string.Empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 约束条件评分
|
|
/// 用于记录人员候选人在约束评估阶段的各项评分和详细信息
|
|
/// 包含时间可用性、工作限制、班次规则等多维度约束检查结果
|
|
/// </summary>
|
|
public class ConstraintScore
|
|
{
|
|
#region 核心评分指标
|
|
|
|
/// <summary>
|
|
/// 约束符合度分数 (0-100)
|
|
/// 综合各项约束检查的加权平均分数
|
|
/// </summary>
|
|
public double ComplianceScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 时间可用性分数 (0-100)
|
|
/// 基于人员在工作时间段的可用性评估
|
|
/// </summary>
|
|
public double TimeAvailabilityScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 工作限制符合度分数 (0-100)
|
|
/// 基于人员工作限制规则的符合程度评估
|
|
/// </summary>
|
|
public double WorkLimitComplianceScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 班次规则符合度分数 (0-100)
|
|
/// 基于班次规则和排班政策的符合程度评估
|
|
/// </summary>
|
|
public double ShiftRuleComplianceScore { get; set; }
|
|
|
|
#endregion
|
|
|
|
#region 约束检查结果
|
|
|
|
/// <summary>
|
|
/// 约束违规列表
|
|
/// 记录所有违反的约束规则和具体违规内容
|
|
/// </summary>
|
|
public List<ConstraintViolation> Violations { get; set; }
|
|
|
|
/// <summary>
|
|
/// 通过约束检查列表
|
|
/// 记录所有通过检查的约束规则
|
|
/// </summary>
|
|
public List<string> PassedConstraints { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// 约束评估详情
|
|
/// 包含详细的约束检查过程和结果说明
|
|
/// </summary>
|
|
public string ConstraintDetails { get; set; } = string.Empty;
|
|
|
|
#endregion
|
|
|
|
#region 扩展评分指标
|
|
|
|
/// <summary>
|
|
/// 地理位置约束分数 (0-100)
|
|
/// 基于人员与工作地点的距离和可达性评估
|
|
/// </summary>
|
|
public double LocationConstraintScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 设备可用性分数 (0-100)
|
|
/// 基于人员所需设备的可用性评估
|
|
/// </summary>
|
|
public double EquipmentAvailabilityScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 项目授权分数 (0-100)
|
|
/// 基于人员对特定项目的授权和访问权限评估
|
|
/// </summary>
|
|
public double ProjectAuthorizationScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 技能匹配约束分数 (0-100)
|
|
/// 基于人员技能与任务要求的匹配程度评估
|
|
/// </summary>
|
|
public double SkillMatchConstraintScore { get; set; }
|
|
|
|
#endregion
|
|
|
|
#region 风险评估
|
|
|
|
/// <summary>
|
|
/// 约束风险等级
|
|
/// 基于约束符合度评估的风险等级
|
|
/// </summary>
|
|
public RiskLevel RiskLevel => ComplianceScore switch
|
|
{
|
|
>= 90 => RiskLevel.Low,
|
|
>= 80 => RiskLevel.Low,
|
|
>= 70 => RiskLevel.Medium,
|
|
>= 60 => RiskLevel.Medium,
|
|
_ => RiskLevel.High
|
|
};
|
|
|
|
/// <summary>
|
|
/// 约束风险描述
|
|
/// 详细描述约束风险的具体内容和影响
|
|
/// </summary>
|
|
public string RiskDescription { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// 风险缓解建议
|
|
/// 针对识别出的约束风险提供的缓解措施建议
|
|
/// </summary>
|
|
public List<string> RiskMitigationSuggestions { get; set; } = new();
|
|
|
|
#endregion
|
|
|
|
#region 性能指标
|
|
|
|
/// <summary>
|
|
/// 约束检查执行时间(毫秒)
|
|
/// 记录约束评估过程的执行耗时
|
|
/// </summary>
|
|
public long ExecutionTimeMs { get; set; }
|
|
|
|
/// <summary>
|
|
/// 约束检查项目数量
|
|
/// 记录本次约束评估检查的约束项目总数
|
|
/// </summary>
|
|
public int TotalConstraintItems { get; set; }
|
|
|
|
/// <summary>
|
|
/// 约束检查通过率
|
|
/// 计算公式:通过项目数 / 总项目数 * 100
|
|
/// </summary>
|
|
public double PassRate => TotalConstraintItems > 0 ? (double)PassedConstraints.Count / TotalConstraintItems * 100 : 0;
|
|
|
|
#endregion
|
|
|
|
#region 构造函数
|
|
|
|
public ConstraintScore()
|
|
{
|
|
Violations = new List<ConstraintViolation>();
|
|
PassedConstraints = new List<string>();
|
|
RiskMitigationSuggestions = new List<string>();
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region 辅助方法
|
|
|
|
/// <summary>
|
|
/// 检查是否通过所有关键约束
|
|
/// </summary>
|
|
/// <returns>是否通过所有关键约束检查</returns>
|
|
public bool IsFullyCompliant => ComplianceScore >= 80 && Violations.Count == 0;
|
|
|
|
/// <summary>
|
|
/// 检查是否满足最低约束要求
|
|
/// </summary>
|
|
/// <returns>是否满足最低约束要求</returns>
|
|
public bool MeetsMinimumRequirements => ComplianceScore >= 60;
|
|
|
|
/// <summary>
|
|
/// 获取约束评估摘要
|
|
/// </summary>
|
|
/// <returns>约束评估的简要总结</returns>
|
|
public string GetConstraintSummary()
|
|
{
|
|
var summary = $"约束符合度:{ComplianceScore:F1}分,";
|
|
summary += $"通过检查:{PassedConstraints.Count}项,";
|
|
summary += $"违规项目:{Violations.Count}项,";
|
|
summary += $"风险等级:{RiskLevel}";
|
|
|
|
return summary;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 添加通过约束检查信息
|
|
/// </summary>
|
|
/// <param name="constraint">通过的约束描述</param>
|
|
public void AddPassedConstraint(string constraint)
|
|
{
|
|
if (!string.IsNullOrEmpty(constraint) && !PassedConstraints.Contains(constraint))
|
|
{
|
|
PassedConstraints.Add(constraint);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 计算综合约束评分
|
|
/// </summary>
|
|
/// <param name="weights">各维度权重配置</param>
|
|
/// <returns>加权综合评分</returns>
|
|
public double CalculateWeightedScore(Dictionary<string, double> weights)
|
|
{
|
|
if (weights == null || !weights.Any())
|
|
{
|
|
// 使用默认权重
|
|
weights = new Dictionary<string, double>
|
|
{
|
|
{ "TimeAvailability", 0.3 },
|
|
{ "WorkLimit", 0.25 },
|
|
{ "ShiftRule", 0.25 },
|
|
{ "Location", 0.1 },
|
|
{ "Equipment", 0.1 }
|
|
};
|
|
}
|
|
|
|
var weightedScore = 0.0;
|
|
var totalWeight = 0.0;
|
|
|
|
foreach (var kvp in weights)
|
|
{
|
|
var score = kvp.Key switch
|
|
{
|
|
"TimeAvailability" => TimeAvailabilityScore,
|
|
"WorkLimit" => WorkLimitComplianceScore,
|
|
"ShiftRule" => ShiftRuleComplianceScore,
|
|
"Location" => LocationConstraintScore,
|
|
"Equipment" => EquipmentAvailabilityScore,
|
|
_ => 0.0
|
|
};
|
|
|
|
weightedScore += score * kvp.Value;
|
|
totalWeight += kvp.Value;
|
|
}
|
|
|
|
return totalWeight > 0 ? weightedScore / totalWeight : 0;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
|
|
/// <summary>
|
|
/// 优化决策评分
|
|
/// </summary>
|
|
public class OptimizationScore
|
|
{
|
|
/// <summary>
|
|
/// 指定人员匹配分数
|
|
/// </summary>
|
|
public double AssignedPersonnelScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 项目FL人员优先分数
|
|
/// </summary>
|
|
public double ProjectFLScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 工作负载平衡分数
|
|
/// </summary>
|
|
public double WorkloadBalanceScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 班次连续性分数
|
|
/// </summary>
|
|
public double ShiftContinuityScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 技能匹配优化分数
|
|
/// </summary>
|
|
public double SkillOptimizationScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 协作历史分数
|
|
/// </summary>
|
|
public double CollaborationHistoryScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 优化总分 (0-100)
|
|
/// </summary>
|
|
public double TotalOptimizationScore { get; set; }
|
|
|
|
public double SkillMatchScore { get; set; }
|
|
public double EfficiencyScore { get; set; }
|
|
|
|
public double optimizationScore { get; set; }
|
|
|
|
public string OptimizationDetails { get; set; } = string.Empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 分配失败信息
|
|
/// </summary>
|
|
public class FailedAllocation
|
|
{
|
|
/// <summary>
|
|
/// 工作任务ID
|
|
/// </summary>
|
|
public long WorkOrderId { get; set; }
|
|
|
|
/// <summary>
|
|
/// 任务编码
|
|
/// </summary>
|
|
public string WorkOrderCode { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// 失败原因描述
|
|
/// </summary>
|
|
public string FailureReason { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// 失败类型
|
|
/// </summary>
|
|
public AllocationFailureType FailureType { get; set; }
|
|
|
|
/// <summary>
|
|
/// 建议解决方案
|
|
/// </summary>
|
|
public List<string> SuggestedSolutions { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// 详细错误信息
|
|
/// </summary>
|
|
public List<string> DetailedErrors { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// 冲突的人员列表
|
|
/// </summary>
|
|
public List<ConflictingPersonnel> ConflictingPersonnels { get; set; } = new();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 分配失败类型枚举
|
|
/// </summary>
|
|
public enum AllocationFailureType
|
|
{
|
|
/// <summary>
|
|
/// 无可用人员
|
|
/// </summary>
|
|
NoAvailablePersonnel = 1,
|
|
|
|
/// <summary>
|
|
/// 资质不匹配
|
|
/// </summary>
|
|
QualificationMismatch = 2,
|
|
|
|
/// <summary>
|
|
/// 时间冲突
|
|
/// </summary>
|
|
TimeConflict = 3,
|
|
|
|
/// <summary>
|
|
/// 工作量超限
|
|
/// </summary>
|
|
WorkloadExceeded = 4,
|
|
|
|
/// <summary>
|
|
/// 班次规则冲突
|
|
/// </summary>
|
|
ShiftRuleConflict = 5,
|
|
|
|
/// <summary>
|
|
/// 系统错误
|
|
/// </summary>
|
|
SystemError = 6,
|
|
|
|
/// <summary>
|
|
/// 业务规则冲突
|
|
/// </summary>
|
|
BusinessRuleConflict = 7
|
|
}
|
|
|
|
/// <summary>
|
|
/// 冲突人员信息
|
|
/// </summary>
|
|
public class ConflictingPersonnel
|
|
{
|
|
/// <summary>
|
|
/// 人员ID
|
|
/// </summary>
|
|
public long PersonnelId { get; set; }
|
|
|
|
/// <summary>
|
|
/// 人员姓名
|
|
/// </summary>
|
|
public string PersonnelName { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// 冲突类型
|
|
/// </summary>
|
|
public string ConflictType { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// 冲突描述
|
|
/// </summary>
|
|
public string ConflictDescription { get; set; } = string.Empty;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 详细分配报告
|
|
/// </summary>
|
|
public class AllocationReport
|
|
{
|
|
/// <summary>
|
|
/// 成功分配数量
|
|
/// </summary>
|
|
public int SuccessfulAllocationCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// 失败分配数量
|
|
/// </summary>
|
|
public int FailedAllocationCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// 成功率百分比
|
|
/// </summary>
|
|
public double SuccessRate { get; set; }
|
|
|
|
/// <summary>
|
|
/// 平均质量评分
|
|
/// </summary>
|
|
public double AverageQualityScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 人员利用率分析
|
|
/// Key: 人员ID, Value: 分配任务数量
|
|
/// </summary>
|
|
public Dictionary<long, double> PersonnelUtilizationRate { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// 风险分析报告
|
|
/// </summary>
|
|
public RiskAnalysis RiskAnalysis { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// 优化建议列表
|
|
/// </summary>
|
|
public List<string> OptimizationSuggestions { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// 报告生成时间
|
|
/// </summary>
|
|
public DateTime GeneratedAt { get; set; } = DateTime.Now;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 风险分析
|
|
/// </summary>
|
|
public class RiskAnalysis
|
|
{
|
|
/// <summary>
|
|
/// 整体风险评分 (0-100)
|
|
/// </summary>
|
|
public double OverallRiskScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 高风险任务数量
|
|
/// </summary>
|
|
public int HighRiskTaskCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// 中风险任务数量
|
|
/// </summary>
|
|
public int MediumRiskTaskCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// 低风险任务数量
|
|
/// </summary>
|
|
public int LowRiskTaskCount { get; set; }
|
|
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public Dictionary<RiskLevel, int> RiskDistribution { get; set; } = new();
|
|
|
|
/// <summary>
|
|
/// 主要风险因素
|
|
/// </summary>
|
|
public List<string> PrimaryRiskFactors { get; set; } = new();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 人员工作负载信息
|
|
/// </summary>
|
|
public class PersonnelWorkloadInfo
|
|
{
|
|
/// <summary>
|
|
/// 人员ID
|
|
/// </summary>
|
|
public long PersonnelId { get; set; }
|
|
|
|
/// <summary>
|
|
/// 人员姓名
|
|
/// </summary>
|
|
public string PersonnelName { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// 分配任务数量
|
|
/// </summary>
|
|
public int AssignedTaskCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// 平均匹配分数
|
|
/// </summary>
|
|
public double AverageMatchScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 总工作负载
|
|
/// </summary>
|
|
public double TotalWorkload { get; set; }
|
|
|
|
/// <summary>
|
|
/// 负载状态
|
|
/// </summary>
|
|
public WorkloadStatus LoadStatus => DetermineLoadStatus();
|
|
|
|
/// <summary>
|
|
/// 确定负载状态
|
|
/// </summary>
|
|
private WorkloadStatus DetermineLoadStatus()
|
|
{
|
|
if (TotalWorkload >= 8.0) return WorkloadStatus.Overloaded;
|
|
if (TotalWorkload >= 6.0) return WorkloadStatus.HighLoad;
|
|
if (TotalWorkload >= 4.0) return WorkloadStatus.NormalLoad;
|
|
if (TotalWorkload >= 2.0) return WorkloadStatus.LightLoad;
|
|
return WorkloadStatus.Idle;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 技能匹配分析
|
|
/// </summary>
|
|
public class SkillMatchAnalysis
|
|
{
|
|
/// <summary>
|
|
/// 平均技能匹配分数
|
|
/// </summary>
|
|
public double AverageSkillMatchScore { get; set; }
|
|
|
|
/// <summary>
|
|
/// 完全胜任人员数量
|
|
/// </summary>
|
|
public int FullyQualifiedCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// 部分胜任人员数量
|
|
/// </summary>
|
|
public int PartiallyQualifiedCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// 勉强胜任人员数量
|
|
/// </summary>
|
|
public int MinimallyQualifiedCount { get; set; }
|
|
|
|
/// <summary>
|
|
/// 技能覆盖度 (0-100)
|
|
/// </summary>
|
|
public double SkillCoverageRate => CalculateCoverageRate();
|
|
|
|
/// <summary>
|
|
/// 计算技能覆盖度
|
|
/// </summary>
|
|
private double CalculateCoverageRate()
|
|
{
|
|
var total = FullyQualifiedCount + PartiallyQualifiedCount + MinimallyQualifiedCount;
|
|
return total > 0 ? (double)(FullyQualifiedCount + PartiallyQualifiedCount) / total * 100 : 0;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 验证结果
|
|
/// </summary>
|
|
public class ValidationResult
|
|
{
|
|
/// <summary>
|
|
/// 验证是否通过
|
|
/// </summary>
|
|
public bool IsValid { get; set; }
|
|
|
|
/// <summary>
|
|
/// 问题列表
|
|
/// </summary>
|
|
public List<string> Issues { get; set; } = new();
|
|
|
|
public List<ValidationViolation> Violations { get; set; } = new List<ValidationViolation>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// 风险等级枚举
|
|
/// </summary>
|
|
public enum RiskLevel
|
|
{
|
|
/// <summary>
|
|
/// 低风险
|
|
/// </summary>
|
|
Low = 1,
|
|
|
|
/// <summary>
|
|
/// 中风险
|
|
/// </summary>
|
|
Medium = 2,
|
|
|
|
/// <summary>
|
|
/// 高风险
|
|
/// </summary>
|
|
High = 3,
|
|
|
|
/// <summary>
|
|
/// 极高风险
|
|
/// </summary>
|
|
Critical = 4
|
|
}
|
|
|
|
/// <summary>
|
|
/// 工作负载状态枚举
|
|
/// </summary>
|
|
public enum WorkloadStatus
|
|
{
|
|
/// <summary>
|
|
/// 空闲
|
|
/// </summary>
|
|
Idle = 0,
|
|
|
|
/// <summary>
|
|
/// 轻负载
|
|
/// </summary>
|
|
LightLoad = 1,
|
|
|
|
/// <summary>
|
|
/// 正常负载
|
|
/// </summary>
|
|
NormalLoad = 2,
|
|
|
|
/// <summary>
|
|
/// 高负载
|
|
/// </summary>
|
|
HighLoad = 3,
|
|
|
|
/// <summary>
|
|
/// 超负载
|
|
/// </summary>
|
|
Overloaded = 4
|
|
}
|
|
|
|
/// <summary>
|
|
/// 健康状态枚举
|
|
/// </summary>
|
|
public enum HealthStatus
|
|
{
|
|
/// <summary>
|
|
/// 优秀
|
|
/// </summary>
|
|
Excellent = 4,
|
|
|
|
/// <summary>
|
|
/// 良好
|
|
/// </summary>
|
|
Good = 3,
|
|
|
|
/// <summary>
|
|
/// 一般
|
|
/// </summary>
|
|
Fair = 2,
|
|
|
|
/// <summary>
|
|
/// 差
|
|
/// </summary>
|
|
Poor = 1
|
|
}
|
|
|
|
#endregion
|
|
} |