DCS/ruiyiweiUX/Assets/Scripts/Models/BFITestRecord.cs

377 lines
10 KiB
C#
Raw Normal View History

2026-06-09 13:59:11 +08:00
using System;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// BFI测试记录数据模型
/// 包含测试的基本信息、数据点和统计信息
/// </summary>
[System.Serializable]
public class BFITestRecord
{
[Header("基本信息")]
public string TestId; // 测试ID
public string TestName; // 测试名称
public DateTime StartTime; // 开始时间
public DateTime EndTime; // 结束时间
public long StartTimeTicks; // 开始时间Ticks用于JSON持久化
public long EndTimeTicks; // 结束时间Ticks用于JSON持久化
public string PatientId; // 患者ID
public string PatientName; // 患者姓名
public string PatientGender; // 患者性别
public int PatientAge; // 患者年龄
public float PatientHeight; // 患者身高cm
public float PatientWeight; // 患者体重kg
[Header("测试配置")]
public float LowThreshold; // 低阈值
public float HighThreshold; // 高阈值
public int AlarmPriority; // 报警优先级
public bool AlarmEnabled; // 是否启用报警
[Header("测试数据")]
public List<BFIDataPoint> DataPoints; // BFI数据点集合
[Header("统计信息")]
public BFIStatistics Statistics; // 统计数据
[Header("导出信息")]
public DateTime ExportTime; // 导出时间
public string ExportFormat; // 导出格式
public string FilePath; // 文件路径
/// <summary>
/// 构造函数
/// </summary>
public BFITestRecord()
{
TestId = System.Guid.NewGuid().ToString();
TestName = $"BFI测试_{DateTime.Now:yyyyMMdd_HHmmss}";
StartTime = DateTime.Now;
StartTimeTicks = StartTime.Ticks;
EndTime = DateTime.MinValue;
EndTimeTicks = 0;
PatientGender = string.Empty;
PatientAge = 0;
PatientHeight = 0f;
PatientWeight = 0f;
DataPoints = new List<BFIDataPoint>();
Statistics = new BFIStatistics();
}
/// <summary>
/// 构造函数(带参数)
/// </summary>
public BFITestRecord(string testName, string patientId = null)
{
TestId = System.Guid.NewGuid().ToString();
TestName = testName;
PatientId = patientId;
StartTime = DateTime.Now;
StartTimeTicks = StartTime.Ticks;
EndTime = DateTime.MinValue;
EndTimeTicks = 0;
PatientGender = string.Empty;
PatientAge = 0;
PatientHeight = 0f;
PatientWeight = 0f;
DataPoints = new List<BFIDataPoint>();
Statistics = new BFIStatistics();
}
/// <summary>
/// 添加数据点
/// </summary>
public void AddDataPoint(float bfiValue, string status = "正常", string notes = "")
{
var dataPoint = new BFIDataPoint
{
Timestamp = DateTime.Now,
TimestampTicks = DateTime.Now.Ticks,
BFI = bfiValue,
Status = status,
Notes = notes
};
DataPoints.Add(dataPoint);
UpdateStatistics();
}
/// <summary>
/// 结束测试
/// </summary>
public void EndTest()
{
EndTest(DateTime.Now);
}
/// <summary>
/// 使用指定时间结束测试
/// </summary>
public void EndTest(DateTime endTime)
{
EndTime = endTime;
EndTimeTicks = EndTime.Ticks;
UpdateStatistics();
}
/// <summary>
/// 重新计算统计信息
/// </summary>
public void RecalculateStatistics()
{
UpdateStatistics();
}
/// <summary>
/// 序列化前同步时间字段
/// </summary>
public void PrepareForSerialization()
{
if (StartTime > DateTime.MinValue)
{
StartTimeTicks = StartTime.Ticks;
}
EndTimeTicks = EndTime > DateTime.MinValue ? EndTime.Ticks : 0;
if (DataPoints != null)
{
foreach (var point in DataPoints)
{
point?.PrepareForSerialization();
}
}
}
/// <summary>
/// 反序列化后恢复时间字段
/// </summary>
public void RestoreAfterDeserialization()
{
if (StartTimeTicks > 0)
{
StartTime = new DateTime(StartTimeTicks, DateTimeKind.Local);
}
if (EndTimeTicks > 0)
{
EndTime = new DateTime(EndTimeTicks, DateTimeKind.Local);
}
if (DataPoints != null)
{
foreach (var point in DataPoints)
{
point?.RestoreAfterDeserialization();
}
}
// 兼容旧数据没有有效开始时间时使用当前时间避免出现公元1年
if (StartTime <= DateTime.MinValue)
{
StartTime = DateTime.Now;
StartTimeTicks = StartTime.Ticks;
}
// 避免结束时间早于开始时间导致负时长
if (EndTime > DateTime.MinValue && EndTime < StartTime)
{
EndTime = DateTime.MinValue;
EndTimeTicks = 0;
}
UpdateStatistics();
}
/// <summary>
/// 更新统计信息
/// </summary>
private void UpdateStatistics()
{
if (DataPoints == null || DataPoints.Count == 0)
{
Statistics = new BFIStatistics();
return;
}
var bfiValues = new List<float>();
foreach (var point in DataPoints)
{
bfiValues.Add(point.BFI);
}
Statistics.Count = DataPoints.Count;
Statistics.MinValue = bfiValues.Count > 0 ? Mathf.Min(bfiValues.ToArray()) : 0f;
Statistics.MaxValue = bfiValues.Count > 0 ? Mathf.Max(bfiValues.ToArray()) : 0f;
Statistics.Average = bfiValues.Count > 0 ? bfiValues.Average() : 0f;
// 计算标准差
if (bfiValues.Count > 1)
{
float variance = bfiValues.Sum(x => Mathf.Pow(x - Statistics.Average, 2)) / bfiValues.Count;
Statistics.StandardDeviation = Mathf.Sqrt(variance);
}
Statistics.Duration = EndTime > StartTime ? (EndTime - StartTime).TotalMinutes : 0;
Statistics.LastUpdated = DateTime.Now;
}
/// <summary>
/// 获取测试时长(分钟)
/// </summary>
public double GetDurationMinutes()
{
if (EndTime > StartTime)
{
return (EndTime - StartTime).TotalMinutes;
}
return (DateTime.Now - StartTime).TotalMinutes;
}
/// <summary>
/// 检查是否有异常数据
/// </summary>
public bool HasAbnormalData()
{
if (DataPoints == null) return false;
foreach (var point in DataPoints)
{
if (point.BFI < LowThreshold || point.BFI > HighThreshold)
{
return true;
}
}
return false;
}
/// <summary>
/// 获取异常数据点数量
/// </summary>
public int GetAbnormalDataCount()
{
if (DataPoints == null) return 0;
int count = 0;
foreach (var point in DataPoints)
{
if (point.BFI < LowThreshold || point.BFI > HighThreshold)
{
count++;
}
}
return count;
}
}
/// <summary>
/// BFI数据点
/// </summary>
[System.Serializable]
public class BFIDataPoint
{
public DateTime Timestamp; // 时间戳
public long TimestampTicks; // 时间戳Ticks用于JSON持久化
public float BFI; // BFI值
public string Status; // 状态(正常、异常、报警等)
public string Notes; // 备注
public int AlarmLevel; // 报警级别 (0=正常, 1=低, 2=中, 3=高)
public BFIDataPoint()
{
Timestamp = DateTime.Now;
TimestampTicks = Timestamp.Ticks;
Status = "正常";
Notes = "";
AlarmLevel = 0;
}
/// <summary>
/// 序列化前同步时间字段
/// </summary>
public void PrepareForSerialization()
{
if (Timestamp > DateTime.MinValue)
{
TimestampTicks = Timestamp.Ticks;
}
}
/// <summary>
/// 反序列化后恢复时间字段
/// </summary>
public void RestoreAfterDeserialization()
{
if (TimestampTicks > 0)
{
Timestamp = new DateTime(TimestampTicks, DateTimeKind.Local);
return;
}
if (Timestamp <= DateTime.MinValue)
{
Timestamp = DateTime.Now;
TimestampTicks = Timestamp.Ticks;
}
}
}
/// <summary>
/// BFI统计信息
/// </summary>
[System.Serializable]
public class BFIStatistics
{
public int Count; // 数据点总数
public float MinValue; // 最小值
public float MaxValue; // 最大值
public float Average; // 平均值
public float StandardDeviation; // 标准差
public double Duration; // 测试时长(分钟)
public DateTime LastUpdated; // 最后更新时间
public BFIStatistics()
{
Count = 0;
MinValue = 0f;
MaxValue = 0f;
Average = 0f;
StandardDeviation = 0f;
Duration = 0;
LastUpdated = DateTime.Now;
}
}
/// <summary>
/// 扩展方法
/// </summary>
public static class ListExtensions
{
public static float Average(this List<float> source)
{
if (source == null || source.Count == 0)
return 0f;
float sum = 0f;
foreach (float value in source)
{
sum += value;
}
return sum / source.Count;
}
public static float Sum(this List<float> source, System.Func<float, float> selector)
{
if (source == null || source.Count == 0)
return 0f;
float sum = 0f;
foreach (float value in source)
{
sum += selector(value);
}
return sum;
}
}