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

377 lines
10 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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