721 lines
26 KiB
C#
721 lines
26 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.ComponentModel.DataAnnotations;
|
||
using System.Linq;
|
||
using FreeSql.DataAnnotations;
|
||
using ZhonTai.Admin.Core.Entities;
|
||
|
||
namespace NPP.SmartSchedue.Api.Contracts.Domain.Integration
|
||
{
|
||
/// <summary>
|
||
/// 智能整合记录实体
|
||
/// 用于记录每次智能任务整合的完整过程和结果
|
||
///
|
||
/// 业务思考:
|
||
/// 1. 作为重要的业务审计数据,需要完整记录整合的全过程
|
||
/// 2. 支持多租户模式,确保数据安全隔离
|
||
/// 3. 提供丰富的查询维度,支持历史分析和决策支持
|
||
/// 4. 考虑JSON存储复杂结果数据,平衡存储效率和查询性能
|
||
/// </summary>
|
||
[Table(Name = "sse_integration_record")]
|
||
[Index("idx_integration_batch_code", "IntegrationBatchCode", true)] // 批次编码唯一索引
|
||
[Index("idx_integration_time", "IntegrationTime")] // 时间索引,支持时间范围查询
|
||
[Index("idx_operator", "OperatorUserId")] // 操作员索引
|
||
[Index("idx_tenant_time", "TenantId,IntegrationTime")] // 租户+时间组合索引
|
||
public class IntegrationRecordEntity : EntityTenant
|
||
{
|
||
/// <summary>
|
||
/// 整合批次编码
|
||
/// 格式:INT + yyyyMMddHHmmss + XXX,如:INT20240314143025123
|
||
/// 业务意义:唯一标识一次整合操作,便于追踪和关联
|
||
/// </summary>
|
||
[Column(StringLength = 30)]
|
||
[Required(ErrorMessage = "整合批次编码不能为空")]
|
||
public string IntegrationBatchCode { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 整合执行时间
|
||
/// 记录实际执行整合操作的时间点
|
||
/// </summary>
|
||
[Required]
|
||
public DateTime IntegrationTime { get; set; } = DateTime.Now;
|
||
|
||
/// <summary>
|
||
/// 操作人员用户ID
|
||
/// 关联到系统用户表,记录执行整合的操作员
|
||
/// </summary>
|
||
[Required(ErrorMessage = "操作人员ID不能为空")]
|
||
public long OperatorUserId { get; set; }
|
||
|
||
/// <summary>
|
||
/// 操作人员用户名
|
||
/// 冗余存储,提高查询性能,避免频繁关联用户表
|
||
/// </summary>
|
||
[Column(StringLength = 50)]
|
||
[Required(ErrorMessage = "操作人员用户名不能为空")]
|
||
public string OperatorUserName { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 操作人员真实姓名
|
||
/// 用于业务场景下的可读性显示
|
||
/// </summary>
|
||
[Column(StringLength = 50)]
|
||
[Required(ErrorMessage = "操作人员姓名不能为空")]
|
||
public string OperatorRealName { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 整合的任务ID列表(JSON格式存储)
|
||
/// 存储格式:[1,2,3,4,5]
|
||
/// 业务意义:记录本次整合涉及的所有任务,支持反向查询
|
||
/// </summary>
|
||
[Column(DbType = "longtext")]
|
||
[Required(ErrorMessage = "任务ID列表不能为空")]
|
||
public string TaskIdsJson { get; set; } = "[]";
|
||
|
||
/// <summary>
|
||
/// 整合策略配置(JSON格式存储)
|
||
/// 包含:人员分配策略、设备分配策略、各种配置参数
|
||
/// 业务价值:记录决策依据,支持策略效果分析和优化
|
||
/// </summary>
|
||
[Column(DbType = "json")]
|
||
[Required]
|
||
public string StrategyConfigJson { get; set; } = "{}";
|
||
|
||
/// <summary>
|
||
/// 人员分配结果详情(JSON格式存储)
|
||
/// 包含:成功匹配列表、失败原因、工作负载分析等
|
||
/// 存储完整的PersonnelAllocationResult对象
|
||
/// </summary>
|
||
[Column(DbType = "json")]
|
||
public string PersonnelAllocationResultJson { get; set; } = "{}";
|
||
|
||
/// <summary>
|
||
/// 设备分配结果详情(JSON格式存储)
|
||
/// 包含:成功匹配列表、失败原因、利用率分析等
|
||
/// 存储完整的EquipmentAllocationResult对象
|
||
/// </summary>
|
||
[Column(DbType = "json")]
|
||
public string EquipmentAllocationResultJson { get; set; } = "{}";
|
||
|
||
/// <summary>
|
||
/// 成功分配的任务数量
|
||
/// 统计字段,提高查询性能
|
||
/// </summary>
|
||
[Required]
|
||
public int SuccessTaskCount { get; set; } = 0;
|
||
|
||
/// <summary>
|
||
/// 分配失败的任务数量
|
||
/// 统计字段,用于成功率计算和分析
|
||
/// </summary>
|
||
[Required]
|
||
public int FailedTaskCount { get; set; } = 0;
|
||
|
||
/// <summary>
|
||
/// 整合执行总耗时(毫秒)
|
||
/// 性能监控指标,用于系统优化分析
|
||
/// </summary>
|
||
[Required]
|
||
public long ElapsedMilliseconds { get; set; } = 0;
|
||
|
||
/// <summary>
|
||
/// 人员分配公平性评分(0-100)
|
||
/// 业务指标,评估人员工作负载分配的公平程度
|
||
/// </summary>
|
||
public int PersonnelFairnessScore { get; set; } = 0;
|
||
|
||
/// <summary>
|
||
/// 设备整体利用率(百分比,保留1位小数)
|
||
/// 业务指标,评估设备资源利用效率
|
||
/// </summary>
|
||
[Column(DbType = "decimal(5,1)")]
|
||
public decimal EquipmentUtilizationRate { get; set; } = 0.0m;
|
||
|
||
/// <summary>
|
||
/// 整合结果摘要描述
|
||
/// 简洁的文本描述,便于快速了解整合结果
|
||
/// 示例:总任务数: 25, 成功: 23, 失败: 2, 成功率: 92%
|
||
/// </summary>
|
||
[Column(StringLength = 500)]
|
||
public string ResultSummary { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 失败原因分类统计(JSON格式存储)
|
||
/// 格式:{"PersonnelAllocationFailed": 2, "EquipmentAllocationFailed": 1}
|
||
/// 业务价值:支持失败原因分析和系统改进
|
||
/// </summary>
|
||
[Column(DbType = "json")]
|
||
public string FailureReasonStats { get; set; } = "{}";
|
||
|
||
/// <summary>
|
||
/// 涉及的项目编号列表(逗号分隔)
|
||
/// 便于按项目查询整合历史,支持项目级别的数据分析
|
||
/// 示例:PRJ001,PRJ002,PRJ003
|
||
/// </summary>
|
||
[Column(StringLength = 500)]
|
||
public string ProjectNumbers { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 整合类型
|
||
/// 标识整合的触发方式:Manual-手动触发, Scheduled-定时触发, Auto-自动触发
|
||
/// </summary>
|
||
[Column(StringLength = 20)]
|
||
[Required]
|
||
public string IntegrationType { get; set; } = "Manual";
|
||
|
||
/// <summary>
|
||
/// 业务备注信息
|
||
/// 操作员填写的备注,记录特殊情况或业务背景
|
||
/// </summary>
|
||
[Column(StringLength = 1000)]
|
||
public string Remarks { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 是否为测试数据
|
||
/// 区分生产数据和测试数据,便于数据清理和分析
|
||
/// </summary>
|
||
[Required]
|
||
public bool IsTestData { get; set; } = false;
|
||
|
||
/// <summary>
|
||
/// 数据版本号
|
||
/// 支持数据结构演进和向后兼容
|
||
/// </summary>
|
||
[Required]
|
||
public int DataVersion { get; set; } = 1;
|
||
|
||
/// <summary>
|
||
/// 整合记录发布状态
|
||
/// 控制整合记录的生命周期管理
|
||
/// Draft-草稿, Published-已发布, Completed-已完成, Cancelled-已撤销
|
||
/// </summary>
|
||
[Column(StringLength = 20)]
|
||
[Required]
|
||
public string PublishStatus { get; set; } = IntegrationRecordPublishStatus.Draft;
|
||
|
||
/// <summary>
|
||
/// 发布时间
|
||
/// 记录正式发布生效的时间点
|
||
/// </summary>
|
||
public DateTime? PublishedTime { get; set; }
|
||
|
||
/// <summary>
|
||
/// 发布操作员用户ID
|
||
/// 记录执行发布操作的用户,可能与创建者不同
|
||
/// </summary>
|
||
public long? PublishedByUserId { get; set; }
|
||
|
||
/// <summary>
|
||
/// 发布操作员用户名
|
||
/// </summary>
|
||
[Column(StringLength = 50)]
|
||
public string PublishedByUserName { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 发布操作员真实姓名
|
||
/// </summary>
|
||
[Column(StringLength = 50)]
|
||
public string PublishedByRealName { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 发布说明
|
||
/// 记录发布时的业务说明或特殊情况备注
|
||
/// </summary>
|
||
[Column(StringLength = 500)]
|
||
public string PublishRemarks { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 完成时间
|
||
/// 所有任务执行完毕的时间点
|
||
/// </summary>
|
||
public DateTime? CompletedTime { get; set; }
|
||
|
||
/// <summary>
|
||
/// 撤销时间
|
||
/// 记录被撤销的时间点
|
||
/// </summary>
|
||
public DateTime? CancelledTime { get; set; }
|
||
|
||
/// <summary>
|
||
/// 撤销操作员用户ID
|
||
/// </summary>
|
||
public long? CancelledByUserId { get; set; }
|
||
|
||
/// <summary>
|
||
/// 撤销操作员用户名
|
||
/// </summary>
|
||
[Column(StringLength = 50)]
|
||
public string CancelledByUserName { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 撤销原因
|
||
/// 记录撤销的具体原因和说明
|
||
/// </summary>
|
||
[Column(StringLength = 500)]
|
||
public string CancelReason { get; set; } = string.Empty;
|
||
|
||
#region 版本管理和变更追踪扩展字段
|
||
|
||
/// <summary>
|
||
/// 当前版本号
|
||
/// 每次修改后自增,用于版本管理和冲突检测
|
||
/// </summary>
|
||
[Required]
|
||
public int CurrentVersion { get; set; } = 1;
|
||
|
||
/// <summary>
|
||
/// 父版本ID
|
||
/// 指向上一个版本的整合记录,构建版本链
|
||
/// null表示这是初始版本
|
||
/// </summary>
|
||
public long? ParentVersionId { get; set; }
|
||
|
||
/// <summary>
|
||
/// 根版本ID
|
||
/// 指向版本链的根节点,用于快速定位同一整合记录的所有版本
|
||
/// </summary>
|
||
[Required]
|
||
public long RootVersionId { get; set; }
|
||
|
||
/// <summary>
|
||
/// 版本创建原因
|
||
/// 记录为什么创建这个新版本:TaskModified-任务修改, ManualAdjustment-手动调整, SystemReallocation-系统重新分配
|
||
/// </summary>
|
||
[Column(StringLength = 50)]
|
||
public string VersionReason { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 变更摘要
|
||
/// 简述本版本相对于上一版本的主要变更内容
|
||
/// </summary>
|
||
[Column(StringLength = 1000)]
|
||
public string ChangeSummary { get; set; } = string.Empty;
|
||
|
||
/// <summary>
|
||
/// 变更详情JSON
|
||
/// 存储详细的变更信息,包括变更类型、影响的任务、前后对比等
|
||
/// 格式:{"changedTasks": [...], "modifications": [...], "affectedPersonnel": [...]}
|
||
/// </summary>
|
||
[Column(DbType = "json")]
|
||
public string ChangeDetailsJson { get; set; } = "{}";
|
||
|
||
/// <summary>
|
||
/// 是否为活跃版本
|
||
/// true表示这是当前生效的版本,每个根版本只能有一个活跃版本
|
||
/// </summary>
|
||
[Required]
|
||
public bool IsActiveVersion { get; set; } = true;
|
||
|
||
/// <summary>
|
||
/// 变更触发源
|
||
/// 记录变更的触发来源:TaskChange-任务变更, UserModification-用户修改, SystemOptimization-系统优化
|
||
/// </summary>
|
||
[Column(StringLength = 30)]
|
||
public string ChangeTriggerSource { get; set; } = "Initial";
|
||
|
||
/// <summary>
|
||
/// 原始任务数量
|
||
/// 记录初始分配时的任务数量,用于对比分析
|
||
/// </summary>
|
||
public int OriginalTaskCount { get; set; } = 0;
|
||
|
||
/// <summary>
|
||
/// 变更影响评分
|
||
/// 0-100分,评估本次变更对整体分配方案的影响程度
|
||
/// </summary>
|
||
public int ChangeImpactScore { get; set; } = 0;
|
||
|
||
/// <summary>
|
||
/// 自动重新分配标志
|
||
/// 标记是否可以自动进行重新分配,还是需要人工干预
|
||
/// </summary>
|
||
[Required]
|
||
public bool AllowAutoReallocation { get; set; } = true;
|
||
|
||
/// <summary>
|
||
/// 上次检查变更时间
|
||
/// 用于变更检测和增量更新机制
|
||
/// </summary>
|
||
public DateTime? LastChangeCheckTime { get; set; }
|
||
|
||
/// <summary>
|
||
/// 快照数据JSON
|
||
/// 存储关键业务数据的快照,用于版本对比和回滚
|
||
/// 包含:任务分配快照、人员工作负载快照、设备利用率快照等
|
||
/// </summary>
|
||
[Column(DbType = "json")]
|
||
public string SnapshotDataJson { get; set; } = "{}";
|
||
|
||
#endregion
|
||
|
||
#region 计算属性
|
||
|
||
/// <summary>
|
||
/// 整合成功率(计算属性)
|
||
/// 返回成功率百分比,保留1位小数
|
||
/// </summary>
|
||
[Navigate(nameof(SuccessTaskCount))]
|
||
public decimal SuccessRate
|
||
{
|
||
get
|
||
{
|
||
var totalTasks = SuccessTaskCount + FailedTaskCount;
|
||
return totalTasks > 0 ? Math.Round((decimal)SuccessTaskCount / totalTasks * 100, 1) : 0;
|
||
}
|
||
set { } // FreeSql需要set访问器,但这是计算属性,所以提供空实现
|
||
}
|
||
|
||
/// <summary>
|
||
/// 任务总数(计算属性)
|
||
/// </summary>
|
||
[Navigate(nameof(SuccessTaskCount))]
|
||
public int TotalTaskCount
|
||
{
|
||
get => SuccessTaskCount + FailedTaskCount;
|
||
set { } // FreeSql需要set访问器,但这是计算属性,所以提供空实现
|
||
}
|
||
|
||
/// <summary>
|
||
/// 整体匹配成功率(计算属性)
|
||
/// </summary>
|
||
public decimal OverallMatchSuccessRate => SuccessRate / 100;
|
||
|
||
/// <summary>
|
||
/// 平均任务复杂度(计算属性)
|
||
/// </summary>
|
||
public decimal AverageTaskComplexity => 2.5m; // 暂时使用固定值
|
||
|
||
/// <summary>
|
||
/// 平均每任务耗时(计算属性)
|
||
/// 返回毫秒数,用于性能分析
|
||
/// </summary>
|
||
[Navigate(nameof(ElapsedMilliseconds))]
|
||
public long AverageTimePerTask
|
||
{
|
||
get
|
||
{
|
||
var totalTasks = TotalTaskCount;
|
||
return totalTasks > 0 ? ElapsedMilliseconds / totalTasks : 0;
|
||
}
|
||
set { } // FreeSql需要set访问器,但这是计算属性,所以提供空实现
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region 业务方法
|
||
|
||
/// <summary>
|
||
/// 反序列化任务ID列表
|
||
/// 将JSON格式的TaskIdsJson转换为List<long>
|
||
/// </summary>
|
||
public List<long> GetTaskIds()
|
||
{
|
||
try
|
||
{
|
||
if (string.IsNullOrWhiteSpace(TaskIdsJson))
|
||
return new List<long>();
|
||
|
||
// 优先尝试JSON反序列化
|
||
try
|
||
{
|
||
return System.Text.Json.JsonSerializer.Deserialize<List<long>>(TaskIdsJson) ?? new List<long>();
|
||
}
|
||
catch
|
||
{
|
||
// 兼容旧格式(逗号分隔)
|
||
return TaskIdsJson.Split(',', StringSplitOptions.RemoveEmptyEntries)
|
||
.Select(p => p.Trim())
|
||
.Where(p => !string.IsNullOrEmpty(p))
|
||
.Select(long.Parse)
|
||
.ToList();
|
||
}
|
||
}
|
||
catch
|
||
{
|
||
return new List<long>();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置任务ID列表
|
||
/// 将List<long>序列化为JSON存储
|
||
/// </summary>
|
||
public void SetTaskIds(List<long> taskIds)
|
||
{
|
||
TaskIdsJson = System.Text.Json.JsonSerializer.Serialize(taskIds ?? new List<long>());
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取项目编号列表
|
||
/// 将逗号分隔的项目编号字符串转换为列表
|
||
/// </summary>
|
||
public List<string> GetProjectNumbers()
|
||
{
|
||
if (string.IsNullOrWhiteSpace(ProjectNumbers))
|
||
return new List<string>();
|
||
|
||
return ProjectNumbers.Split(',', StringSplitOptions.RemoveEmptyEntries)
|
||
.Select(p => p.Trim())
|
||
.Where(p => !string.IsNullOrEmpty(p))
|
||
.ToList();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置项目编号列表
|
||
/// 将列表转换为逗号分隔的字符串存储
|
||
/// </summary>
|
||
public void SetProjectNumbers(List<string> projectNumbers)
|
||
{
|
||
if (projectNumbers == null || !projectNumbers.Any())
|
||
{
|
||
ProjectNumbers = string.Empty;
|
||
return;
|
||
}
|
||
|
||
ProjectNumbers = string.Join(",", projectNumbers.Where(p => !string.IsNullOrWhiteSpace(p)));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新统计信息
|
||
/// 根据分配结果更新各项统计字段
|
||
/// </summary>
|
||
public void UpdateStatistics(int successCount, int failedCount, long elapsedMs, int fairnessScore, decimal utilizationRate)
|
||
{
|
||
SuccessTaskCount = successCount;
|
||
FailedTaskCount = failedCount;
|
||
ElapsedMilliseconds = elapsedMs;
|
||
PersonnelFairnessScore = fairnessScore;
|
||
EquipmentUtilizationRate = utilizationRate;
|
||
|
||
ResultSummary = $"总任务数: {TotalTaskCount}, 成功: {SuccessTaskCount}, 失败: {FailedTaskCount}, 成功率: {SuccessRate}%";
|
||
}
|
||
|
||
#region 版本管理业务方法
|
||
|
||
/// <summary>
|
||
/// 创建新版本
|
||
/// 基于当前版本创建一个新的版本记录,用于变更追踪
|
||
/// </summary>
|
||
/// <param name="reason">版本创建原因</param>
|
||
/// <param name="changeSummary">变更摘要</param>
|
||
/// <param name="operatorUserId">操作员用户ID</param>
|
||
/// <param name="operatorName">操作员姓名</param>
|
||
/// <returns>新版本的整合记录实体</returns>
|
||
public IntegrationRecordEntity CreateNewVersion(string reason, string changeSummary, long operatorUserId, string operatorName)
|
||
{
|
||
var newVersion = new IntegrationRecordEntity
|
||
{
|
||
// 继承基本信息
|
||
IntegrationBatchCode = this.IntegrationBatchCode,
|
||
TenantId = this.TenantId,
|
||
RootVersionId = this.RootVersionId == 0 ? this.Id : this.RootVersionId,
|
||
ParentVersionId = this.Id,
|
||
CurrentVersion = this.CurrentVersion + 1,
|
||
|
||
// 版本变更信息
|
||
VersionReason = reason,
|
||
ChangeSummary = changeSummary,
|
||
ChangeTriggerSource = reason,
|
||
IsActiveVersion = true, // 新版本为活跃版本
|
||
|
||
// 操作员信息
|
||
OperatorUserId = operatorUserId,
|
||
OperatorUserName = operatorName,
|
||
OperatorRealName = operatorName,
|
||
IntegrationTime = DateTime.Now,
|
||
|
||
// 继承配置信息
|
||
StrategyConfigJson = this.StrategyConfigJson,
|
||
IntegrationType = this.IntegrationType,
|
||
|
||
// 继承发布状态相关信息
|
||
PublishStatus = this.PublishStatus,
|
||
PublishedTime = this.PublishedTime,
|
||
PublishedByUserId = this.PublishedByUserId,
|
||
PublishedByUserName = this.PublishedByUserName,
|
||
PublishedByRealName = this.PublishedByRealName,
|
||
PublishRemarks = this.PublishRemarks,
|
||
|
||
// 初始化新版本的其他字段
|
||
TaskIdsJson = "[]",
|
||
PersonnelAllocationResultJson = "{}",
|
||
EquipmentAllocationResultJson = "{}",
|
||
FailureReasonStats = "{}",
|
||
ChangeDetailsJson = "{}",
|
||
SnapshotDataJson = "{}",
|
||
DataVersion = this.DataVersion,
|
||
AllowAutoReallocation = true,
|
||
LastChangeCheckTime = DateTime.Now
|
||
};
|
||
|
||
// 当前版本标记为非活跃
|
||
this.IsActiveVersion = false;
|
||
|
||
return newVersion;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取变更详情
|
||
/// 解析ChangeDetailsJson并返回结构化的变更详情
|
||
/// </summary>
|
||
public IntegrationChangeDetails GetChangeDetails()
|
||
{
|
||
try
|
||
{
|
||
if (string.IsNullOrWhiteSpace(ChangeDetailsJson) || ChangeDetailsJson == "{}")
|
||
return new IntegrationChangeDetails();
|
||
|
||
return System.Text.Json.JsonSerializer.Deserialize<IntegrationChangeDetails>(ChangeDetailsJson)
|
||
?? new IntegrationChangeDetails();
|
||
}
|
||
catch
|
||
{
|
||
return new IntegrationChangeDetails();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置变更详情
|
||
/// 将变更详情对象序列化为JSON存储
|
||
/// </summary>
|
||
public void SetChangeDetails(IntegrationChangeDetails changeDetails)
|
||
{
|
||
ChangeDetailsJson = System.Text.Json.JsonSerializer.Serialize(changeDetails ?? new IntegrationChangeDetails());
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取快照数据
|
||
/// 解析SnapshotDataJson并返回快照数据对象
|
||
/// </summary>
|
||
public IntegrationSnapshot GetSnapshotData()
|
||
{
|
||
try
|
||
{
|
||
if (string.IsNullOrWhiteSpace(SnapshotDataJson) || SnapshotDataJson == "{}")
|
||
return new IntegrationSnapshot();
|
||
|
||
return System.Text.Json.JsonSerializer.Deserialize<IntegrationSnapshot>(SnapshotDataJson)
|
||
?? new IntegrationSnapshot();
|
||
}
|
||
catch
|
||
{
|
||
return new IntegrationSnapshot();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置快照数据
|
||
/// 将快照数据对象序列化为JSON存储
|
||
/// </summary>
|
||
public void SetSnapshotData(IntegrationSnapshot snapshotData)
|
||
{
|
||
SnapshotDataJson = System.Text.Json.JsonSerializer.Serialize(snapshotData ?? new IntegrationSnapshot());
|
||
}
|
||
|
||
/// <summary>
|
||
/// 计算变更影响评分
|
||
/// 基于变更的任务数量、人员影响、设备影响等计算影响评分
|
||
/// </summary>
|
||
public int CalculateChangeImpactScore(IntegrationChangeDetails changeDetails)
|
||
{
|
||
if (changeDetails == null) return 0;
|
||
|
||
int score = 0;
|
||
int totalTasks = TotalTaskCount > 0 ? TotalTaskCount : 1;
|
||
|
||
// 基于变更任务比例计算基础分数 (40%)
|
||
var changedTaskRatio = (double)changeDetails.ChangedTaskIds.Count / totalTasks;
|
||
score += (int)(changedTaskRatio * 40);
|
||
|
||
// 基于人员变更数量计算分数 (30%)
|
||
var personnelChangeRatio = Math.Min(1.0, (double)changeDetails.AffectedPersonnelIds.Count / 10);
|
||
score += (int)(personnelChangeRatio * 30);
|
||
|
||
// 基于设备变更数量计算分数 (20%)
|
||
var equipmentChangeRatio = Math.Min(1.0, (double)changeDetails.AffectedEquipmentIds.Count / 10);
|
||
score += (int)(equipmentChangeRatio * 20);
|
||
|
||
// 基于变更类型的严重程度 (10%)
|
||
var severityScore = changeDetails.ChangeTypes.Contains("TaskTimeConflict") ? 10 :
|
||
changeDetails.ChangeTypes.Contains("PersonnelUnavailable") ? 8 :
|
||
changeDetails.ChangeTypes.Contains("EquipmentUnavailable") ? 6 : 2;
|
||
score += severityScore;
|
||
|
||
return Math.Min(100, Math.Max(0, score));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查是否需要重新分配
|
||
/// 基于变更影响评分和业务规则判断是否需要重新分配
|
||
/// </summary>
|
||
public bool ShouldTriggerReallocation()
|
||
{
|
||
// 如果不允许自动重新分配,返回false
|
||
if (!AllowAutoReallocation) return false;
|
||
|
||
// 如果变更影响评分超过阈值,需要重新分配
|
||
if (ChangeImpactScore >= 30) return true;
|
||
|
||
// 如果有任务时间冲突,必须重新分配
|
||
var changeDetails = GetChangeDetails();
|
||
if (changeDetails.ChangeTypes.Contains("TaskTimeConflict")) return true;
|
||
|
||
// 如果有关键人员不可用,需要重新分配
|
||
if (changeDetails.ChangeTypes.Contains("PersonnelUnavailable")) return true;
|
||
|
||
return false;
|
||
}
|
||
|
||
#endregion
|
||
|
||
#endregion
|
||
}
|
||
|
||
/// <summary>
|
||
/// 整合类型枚举
|
||
/// </summary>
|
||
public static class IntegrationType
|
||
{
|
||
/// <summary>
|
||
/// 手动触发
|
||
/// </summary>
|
||
public const string Manual = "Manual";
|
||
|
||
/// <summary>
|
||
/// 定时触发
|
||
/// </summary>
|
||
public const string Scheduled = "Scheduled";
|
||
|
||
/// <summary>
|
||
/// 自动触发
|
||
/// </summary>
|
||
public const string Auto = "Auto";
|
||
}
|
||
|
||
/// <summary>
|
||
/// 整合记录发布状态枚举
|
||
/// 定义整合记录的生命周期状态
|
||
/// </summary>
|
||
public static class IntegrationRecordPublishStatus
|
||
{
|
||
/// <summary>
|
||
/// 草稿状态 - 刚生成的整合记录,未正式生效
|
||
/// </summary>
|
||
public const string Draft = "Draft";
|
||
|
||
/// <summary>
|
||
/// 已发布状态 - 已发布生效,任务开始执行
|
||
/// </summary>
|
||
public const string Published = "Published";
|
||
|
||
/// <summary>
|
||
/// 已完成状态 - 所有任务执行完毕
|
||
/// </summary>
|
||
public const string Completed = "Completed";
|
||
|
||
/// <summary>
|
||
/// 已撤销状态 - 发布后被撤销
|
||
/// </summary>
|
||
public const string Cancelled = "Cancelled";
|
||
}
|
||
} |