1028 lines
26 KiB
C#
1028 lines
26 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using TMPro;
|
||
using Unity.VisualScripting;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
public class MainPanel : BasePanel
|
||
{
|
||
[Header("信息显示")]
|
||
// public TextMeshProUGUI PatientInfoText;
|
||
// public TextMeshProUGUI AlarmInfoText;
|
||
// public TextMeshProUGUI BatteryText;
|
||
public TextMeshProUGUI DateTimeText;
|
||
public TextMeshProUGUI BFIValueText;
|
||
public TextMeshProUGUI BFIValueLowThresholdText;
|
||
public TextMeshProUGUI BFIValueHighThresholdText;
|
||
public TextMeshProUGUI BloodFlowValueText;
|
||
|
||
[Header("音频组件")]
|
||
public AudioSource AlarmAudioSource;
|
||
public AudioClip AlarmAudioClip;
|
||
private float _audioVolume = 0.8f;
|
||
|
||
[Header("图表组件")]
|
||
public UIChartComponent BFIChart; // 使用UI兼容的图表组件
|
||
public UIChartComponent BloodFlowChart;
|
||
|
||
[Header("按钮")]
|
||
public Button HomeButton;
|
||
public Button AlarmMuteButton;
|
||
public Button SettingsButton;
|
||
public Button ExportButton;
|
||
private Button StartStopButton;
|
||
public Button PatientInfoButton;
|
||
public Button AlarmRecordButton;
|
||
private TextMeshProUGUI StartStopLabel;
|
||
public TextMeshProUGUI AlarmMuteLabel;
|
||
|
||
// [Header("报警灯")]
|
||
// public AlarmLightComponent AlarmLight;
|
||
|
||
// [Header("电量显示")]
|
||
// public Slider BatterySlider;
|
||
|
||
[Header("时间更新")]
|
||
public TimeUpdateComponent TimeUpdater;
|
||
|
||
[Header("模型显示")]
|
||
public GameObject BodyAndOrgans; // BodyAndOrgans模型对象
|
||
|
||
// [Header("闪烁设置")]
|
||
public Color normalColor = new Color(0.3f, 0.8f, 1f, 1f);
|
||
public float blinkInterval = 0.5f; // 500ms闪烁周期
|
||
private bool isBlinking = false;
|
||
private Coroutine blinkCoroutine;
|
||
|
||
private bool _isMuted = false;
|
||
private DateTime _muteEndTime = DateTime.MinValue;
|
||
private Coroutine _muteTimerCoroutine = null;
|
||
private float _bfiLowThreshold = 0f;
|
||
private float _bfiHighThreshold = 200f;
|
||
// private IDataService _dataService;
|
||
// private IPatientInfoService _patientInfoService;
|
||
|
||
public override void Init()
|
||
{
|
||
// _dataService = ServiceLocator.Get<IDataService>();
|
||
// _patientInfoService = ServiceLocator.Get<IPatientInfoService>();
|
||
SetAutoBFIRecordingEnabled(true, "进入主界面");
|
||
InitializeUI();
|
||
InitializeCharts();
|
||
InitializeTimeUpdater();
|
||
InitializeAudioVolume();
|
||
InitializeCurrentSettings();
|
||
|
||
// 启动/停止按钮已取消,改为自动记录
|
||
// UpdateStartStopButton();
|
||
|
||
// 初始化串口通信
|
||
InitializeDCSSerial();
|
||
|
||
// 初始化BodyAndOrgans控制器
|
||
InitializeBodyAndOrgansController();
|
||
|
||
// 订阅DCSAlarmManager的报警事件
|
||
DCSAlarmManager.OnAlarmRaised += OnDCSAlarmRaised;
|
||
// DCSAlarmManager.OnAlarmCleared += OnAllAlarmsCleared;
|
||
// DCSAlarmManager.OnMuteStateChanged += UpdateMuteButtonText;
|
||
// _patientInfoService.OnPatientInfoChanged += LoadPatientInfo;
|
||
BFIThresholdDialog.OnThresholdChanged += ApplyBFIThresholdChanges;
|
||
Debug.Log("MainPanel: 已订阅DCSAlarmManager.OnAlarmRaised事件");
|
||
}
|
||
private void InitializeUI()
|
||
{
|
||
if (HomeButton != null)
|
||
{
|
||
HomeButton.onClick.AddListener(() =>
|
||
{
|
||
ConfirmDialog.Show(
|
||
"退出确认",
|
||
"确定要返回登录界面吗?",
|
||
() =>
|
||
{
|
||
SetAutoBFIRecordingEnabled(false, "返回登录界面");
|
||
ClearCurrentPatientInfo();
|
||
|
||
ClosePanel();
|
||
UIManager.Instance.ShowPanel<LoginPanel>();
|
||
},
|
||
() => Debug.Log("MainPanel: 取消退出"),
|
||
"确认",
|
||
"取消",
|
||
true,
|
||
true);
|
||
});
|
||
}
|
||
if (AlarmMuteButton != null)
|
||
{
|
||
AlarmMuteButton.onClick.AddListener(() =>
|
||
{
|
||
ToggleMuteState();
|
||
});
|
||
}
|
||
|
||
if (SettingsButton != null)
|
||
{
|
||
SettingsButton.onClick.AddListener(() =>
|
||
{
|
||
UIManager.Instance.ShowPanel<SettingsPanel>();
|
||
});
|
||
}
|
||
|
||
if (ExportButton != null)
|
||
{
|
||
ExportButton.onClick.AddListener(() =>
|
||
{
|
||
Debug.Log("MainPanel: 打开BFI历史记录导出界面");
|
||
UIManager.Instance.ShowPanel<BFIHistoryExportPanel>();
|
||
});
|
||
}
|
||
|
||
// 启动/停止按钮已取消,改为自动记录
|
||
// if (StartStopButton != null)
|
||
// {
|
||
// StartStopButton.onClick.AddListener(OnStartStopClicked);
|
||
// }
|
||
|
||
// 隐藏启动/停止按钮
|
||
if (StartStopButton != null)
|
||
{
|
||
StartStopButton.gameObject.SetActive(false);
|
||
}
|
||
|
||
if (PatientInfoButton != null)
|
||
{
|
||
PatientInfoButton.onClick.AddListener(() =>
|
||
{
|
||
UIManager.Instance.ShowPanel<PatientInfoPanel>();
|
||
});
|
||
}
|
||
|
||
if (AlarmRecordButton != null)
|
||
{
|
||
AlarmRecordButton.onClick.AddListener(() =>
|
||
{
|
||
UIManager.Instance.ShowPanel<AlarmRecordPanel>();
|
||
});
|
||
}
|
||
|
||
// 为BFI文本添加点击事件
|
||
if (BFIValueText != null)
|
||
{
|
||
// 添加Button组件(如果不存在)
|
||
var button = BFIValueText.GetComponent<Button>();
|
||
if (button == null)
|
||
{
|
||
button = BFIValueText.gameObject.AddComponent<Button>();
|
||
// 设置为透明按钮
|
||
button.transition = Selectable.Transition.None;
|
||
// Debug.Log("MainPanel: 为BFI文本添加了Button组件");
|
||
}
|
||
|
||
button.onClick.AddListener(() =>
|
||
{
|
||
Debug.Log("MainPanel: 点击BFI文本,尝试打开BFI阈值设置对话框");
|
||
try
|
||
{
|
||
var dialog = UIManager.Instance.ShowPanel<BFIThresholdDialog>();
|
||
if (dialog != null)
|
||
{
|
||
Debug.Log("MainPanel: BFI阈值对话框打开成功");
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("MainPanel: BFI阈值对话框打开失败 - 返回null");
|
||
}
|
||
}
|
||
catch (System.Exception ex)
|
||
{
|
||
Debug.LogError($"MainPanel: 打开BFI阈值对话框时发生异常: {ex.Message}");
|
||
}
|
||
});
|
||
|
||
// 添加视觉提示,让用户知道这是可点击的
|
||
BFIValueText.color = normalColor; // 浅蓝色表示可点击
|
||
// Debug.Log("MainPanel: BFI文本点击功能已配置");
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning("MainPanel: BFIValueText组件为null,无法添加点击事件");
|
||
}
|
||
}
|
||
|
||
private void ClearCurrentPatientInfo()
|
||
{
|
||
try
|
||
{
|
||
var patientService = ServiceLocator.IsRegistered<IPatientInfoService>()
|
||
? ServiceLocator.Get<IPatientInfoService>()
|
||
: null;
|
||
|
||
patientService?.ClearCurrentPatient();
|
||
Debug.Log("MainPanel: 已清空当前患者信息");
|
||
}
|
||
catch (System.Exception ex)
|
||
{
|
||
Debug.LogWarning($"MainPanel: 清空当前患者信息失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
protected override void ClosePanel()
|
||
{
|
||
SetAutoBFIRecordingEnabled(false, "关闭主界面");
|
||
UIManager.Instance.HidePanel<MainPanel>();
|
||
}
|
||
|
||
private void SetAutoBFIRecordingEnabled(bool enabled, string reason)
|
||
{
|
||
var dataService = ServiceLocator.IsRegistered<IDataService>() ? ServiceLocator.Get<IDataService>() : null;
|
||
if (dataService is DataService ds)
|
||
{
|
||
ds.SetAutoBFIRecordingEnabled(enabled, reason);
|
||
return;
|
||
}
|
||
|
||
if (DataService.Instance != null)
|
||
{
|
||
DataService.Instance.SetAutoBFIRecordingEnabled(enabled, reason);
|
||
}
|
||
}
|
||
|
||
|
||
private void InitializeCharts()
|
||
{
|
||
// 优先使用UI图表组件
|
||
if (BFIChart != null)
|
||
{
|
||
BFIChart.SetTitle("BFI折线图");
|
||
BFIChart.SetValueRange(0f, 200f);
|
||
BFIChart.unit = "";
|
||
BFIChart.SetLineColor(Color.green);
|
||
}
|
||
|
||
if (BloodFlowChart != null)
|
||
{
|
||
BloodFlowChart.SetTitle("血流指数折线图");
|
||
BloodFlowChart.SetValueRange(0f, 200f);
|
||
BloodFlowChart.unit = "ml/min";
|
||
BloodFlowChart.SetLineColor(Color.red);
|
||
}
|
||
}
|
||
|
||
private void InitializeTimeUpdater()
|
||
{
|
||
// 如果没有手动分配TimeUpdater组件,尝试在当前GameObject上查找
|
||
if (TimeUpdater == null)
|
||
{
|
||
TimeUpdater = GetComponent<TimeUpdateComponent>();
|
||
if (TimeUpdater == null)
|
||
{
|
||
// 如果仍然没有找到,添加一个新的组件
|
||
TimeUpdater = gameObject.AddComponent<TimeUpdateComponent>();
|
||
}
|
||
}
|
||
|
||
// 设置时间显示组件的引用
|
||
if (TimeUpdater != null && DateTimeText != null)
|
||
{
|
||
TimeUpdater.DateTimeText = DateTimeText;
|
||
TimeUpdater.SetActive(true);
|
||
}
|
||
}
|
||
|
||
private void InitializeAudioVolume()
|
||
{
|
||
var settingsService = ServiceLocator.Get<ISystemSettingsService>();
|
||
int currentVolume = settingsService?.Volume ?? 80;
|
||
UpdateAudioVolume(currentVolume);
|
||
Debug.Log($"MainPanel: 初始化音量为 {currentVolume}%");
|
||
}
|
||
|
||
public void UpdateAudioVolume(int volumePercent)
|
||
{
|
||
volumePercent = Mathf.Clamp(volumePercent, 10, 100);
|
||
_audioVolume = volumePercent / 100f;
|
||
|
||
if (AlarmAudioSource != null)
|
||
{
|
||
AlarmAudioSource.volume = _audioVolume;
|
||
}
|
||
|
||
Debug.Log($"MainPanel: 更新音量为 {volumePercent}% (AudioSource音量: {_audioVolume:F2})");
|
||
}
|
||
|
||
private void InitializeCurrentSettings()
|
||
{
|
||
// 从配置服务加载当前阈值设置
|
||
var settingsService = ServiceLocator.Get<ISystemSettingsService>();
|
||
|
||
BFIThresholdSettings _settings = new BFIThresholdSettings
|
||
{
|
||
MinThreshold = settingsService?.BFILowThreshold ?? _bfiLowThreshold,
|
||
MaxThreshold = settingsService?.BFIHighThreshold ??_bfiHighThreshold,
|
||
// EnableLowAlarm = settingsService?.EnableBFIAlarm ?? true,
|
||
// EnableHighAlarm = settingsService?.EnableBFIAlarm ?? true,
|
||
AlarmPriority = (AlarmPriority)(settingsService?.BFIAlarmPriority ?? 2)
|
||
};
|
||
ApplyBFIThresholdChanges(_settings);
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 所有报警清除后显示健康状态
|
||
/// </summary>
|
||
private void OnAllAlarmsCleared()
|
||
{
|
||
// AlarmInfoText.text = "";
|
||
}
|
||
|
||
|
||
private void ApplyBFIThresholdChanges(BFIThresholdSettings settings)
|
||
{
|
||
BFIValueLowThresholdText.text = settings.MinThreshold.ToString("F1");
|
||
BFIValueHighThresholdText.text = settings.MaxThreshold.ToString("F1");
|
||
_bfiLowThreshold = settings.MinThreshold;
|
||
_bfiHighThreshold = settings.MaxThreshold;
|
||
}
|
||
|
||
private void UpdateMuteButtonText()
|
||
{
|
||
if (AlarmMuteLabel != null)
|
||
{
|
||
if (_isMuted)
|
||
{
|
||
// 计算剩余时间
|
||
var remainingTime = (_muteEndTime - DateTime.Now).TotalSeconds;
|
||
if (remainingTime > 0)
|
||
{
|
||
int minutes = (int)(remainingTime / 60);
|
||
int seconds = (int)(remainingTime % 60);
|
||
AlarmMuteLabel.text = $"静音中 {minutes:00}:{seconds:00}";
|
||
}
|
||
else
|
||
{
|
||
AlarmMuteLabel.text = "恢复报警";
|
||
}
|
||
}
|
||
else
|
||
{
|
||
AlarmMuteLabel.text = "报警静音";
|
||
}
|
||
}
|
||
}
|
||
|
||
private void UpdateMuteButtonText(bool isM)
|
||
{
|
||
UpdateMuteButtonText();
|
||
}
|
||
|
||
|
||
private void PlayAlarmAudio(AlarmPriority priority)
|
||
{
|
||
if (AlarmAudioSource == null || AlarmAudioClip == null)
|
||
return;
|
||
|
||
// 检查DCSAlarmManager的静音状态
|
||
// if (DCSAlarmManager.Instance != null && DCSAlarmManager.Instance.IsMuted)
|
||
// {
|
||
// Debug.Log("报警音频被DCSAlarmManager静音阻止");
|
||
// return;
|
||
// }
|
||
|
||
// 设置音量
|
||
float volumeMultiplier = GetVolumeMultiplierForPriority(priority);
|
||
AlarmAudioSource.volume = _audioVolume * volumeMultiplier;
|
||
|
||
// 播放音频
|
||
AlarmAudioSource.Play();
|
||
Debug.Log($"播放报警音频,优先级: {priority}, 音量: {AlarmAudioSource.volume:F2}");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据优先级获取音量倍数
|
||
/// </summary>
|
||
private float GetVolumeMultiplierForPriority(AlarmPriority priority)
|
||
{
|
||
return priority switch
|
||
{
|
||
AlarmPriority.High => 1.0f, // 高优先级最大音量
|
||
AlarmPriority.Medium => 0.8f, // 中优先级80%音量
|
||
AlarmPriority.Low => 0.6f, // 低优先级60%音量
|
||
_ => 0.8f
|
||
};
|
||
}
|
||
|
||
/// <summary>
|
||
/// 处理DCSAlarmManager的报警事件
|
||
/// </summary>
|
||
private void OnDCSAlarmRaised(AlarmPriority priority, string reason)
|
||
{
|
||
// if (AlarmInfoText != null)
|
||
// {
|
||
// var color = priority == AlarmPriority.High ? "#FF0000" : (priority == AlarmPriority.Medium ? "#FFFF00" : "#FFFFAA");
|
||
// AlarmInfoText.text = $"<color={color}>{reason}</color>";
|
||
// }
|
||
|
||
// 更新报警灯
|
||
// if (AlarmLight != null)
|
||
// {
|
||
// AlarmLight.SetAlarmState(priority, true);
|
||
// }
|
||
|
||
// 检查静音状态,决定是否播放音频
|
||
if (!_isMuted)
|
||
{
|
||
// 未静音,播放报警音频
|
||
PlayAlarmAudio(priority);
|
||
}
|
||
else
|
||
{
|
||
Debug.Log($"MainPanel: 报警被静音阻止 - [{priority}] {reason}");
|
||
}
|
||
|
||
Debug.Log($"MainPanel: 收到DCS报警 - [{priority}] {reason}");
|
||
}
|
||
|
||
|
||
private void OnBFIValueUpdated(float value)
|
||
{
|
||
if (BFIValueText != null)
|
||
{
|
||
BFIValueText.text = value.ToString("F1");
|
||
}
|
||
if(value > _bfiHighThreshold || value < _bfiLowThreshold)
|
||
{
|
||
SetBFIblink(true);
|
||
}
|
||
else
|
||
{
|
||
SetBFIblink(false);
|
||
}
|
||
// 优先使用UI图表组件
|
||
if (BFIChart != null)
|
||
{
|
||
BFIChart.AddDataPoint(value);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 设置报警状态
|
||
/// </summary>
|
||
public void SetBFIblink(bool isActive)
|
||
{
|
||
if (blinkCoroutine != null)
|
||
{
|
||
StopCoroutine(blinkCoroutine);
|
||
blinkCoroutine = null;
|
||
}
|
||
|
||
isBlinking = isActive;
|
||
|
||
if (!isActive)
|
||
{
|
||
ResetLight();
|
||
return;
|
||
}
|
||
else
|
||
{
|
||
blinkCoroutine = StartCoroutine(BlinkLight(Color.red));
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 闪烁协程
|
||
/// </summary>
|
||
private IEnumerator BlinkLight(Color color)
|
||
{
|
||
while (isBlinking)
|
||
{
|
||
BFIValueText.color = color;
|
||
yield return new WaitForSeconds(blinkInterval);
|
||
|
||
BFIValueText.color = normalColor;
|
||
yield return new WaitForSeconds(blinkInterval);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 重置灯光状态
|
||
/// </summary>
|
||
private void ResetLight()
|
||
{
|
||
if (BFIValueText != null)
|
||
BFIValueText.color = normalColor;
|
||
|
||
isBlinking = false;
|
||
}
|
||
|
||
|
||
// 已取消手动启动/停止功能,改为自动记录
|
||
// /// <summary>
|
||
// /// 启动/停止按钮点击处理
|
||
// /// </summary>
|
||
// private void OnStartStopClicked()
|
||
// {
|
||
// var dataService = ServiceLocator.Get<IDataService>();
|
||
// // var patientService = ServiceLocator.Get<IPatientInfoService>();
|
||
//
|
||
// // 检查是否正在录制BFI测试
|
||
// bool isRecording = false;
|
||
// if (dataService is DataService ds)
|
||
// {
|
||
// isRecording = ds.IsRecordingBFITest();
|
||
// }
|
||
//
|
||
// if (isRecording)
|
||
// {
|
||
// // 停止BFI测试记录
|
||
// if (dataService is DataService ds2)
|
||
// {
|
||
// ds2.StopBFITestRecording();
|
||
// }
|
||
// _dataService.StopDataCollection();
|
||
// Debug.Log("MainPanel: 停止BFI测试记录");
|
||
// }
|
||
// else
|
||
// {
|
||
// // 开始BFI测试记录
|
||
// // var patient = patientService?.GetCurrentPatient();
|
||
// // if (patient != null)
|
||
// // {
|
||
// // 有患者信息,开始测试
|
||
// string testName = $"BFI测试_{System.DateTime.Now:yyyyMMdd_HHmmss}";
|
||
// if (dataService is DataService ds3)
|
||
// {
|
||
// ds3.StartBFITestRecording(testName);
|
||
// }
|
||
// _dataService.StartDataCollection();
|
||
// // Debug.Log($"MainPanel: 开始BFI测试记录 - 患者: {patient.Name}");
|
||
// // }
|
||
// // else
|
||
// // {
|
||
// // // 没有患者信息,提示设置
|
||
// // ConfirmDialog.Show("提示", "请先设置患者信息再开始测试",
|
||
// // () => {
|
||
// // UIManager.Instance.ShowPanel<PatientInfoPanel>();
|
||
// // });
|
||
// // return;
|
||
// // }
|
||
// }
|
||
//
|
||
// UpdateStartStopButton();
|
||
// }
|
||
//
|
||
// /// <summary>
|
||
// /// 更新启停按钮状态
|
||
// /// </summary>
|
||
// private void UpdateStartStopButton()
|
||
// {
|
||
// if (StartStopLabel == null) return;
|
||
//
|
||
// var dataService = ServiceLocator.Get<IDataService>();
|
||
// // var patientService = ServiceLocator.Get<IPatientInfoService>();
|
||
//
|
||
// bool isRecording = false;
|
||
// if (dataService is DataService ds)
|
||
// {
|
||
// isRecording = ds.IsRecordingBFITest();
|
||
// }
|
||
//
|
||
// // bool hasPatientInfo = patientService?.GetCurrentPatient() != null;
|
||
//
|
||
// if (isRecording)
|
||
// {
|
||
// StartStopLabel.text = "停止测试";
|
||
// if (StartStopButton != null) StartStopButton.interactable = true;
|
||
// }
|
||
// else
|
||
// {
|
||
// StartStopLabel.text = "开始测试";
|
||
// if (StartStopButton != null) StartStopButton.interactable = true;
|
||
// }
|
||
// // else
|
||
// // {
|
||
// // StartStopLabel.text = "设置患者";
|
||
// // if (StartStopButton != null) StartStopButton.interactable = true;
|
||
// // }
|
||
// }
|
||
|
||
/// <summary>
|
||
/// 初始化DCS串口通信
|
||
/// </summary>
|
||
private void InitializeDCSSerial()
|
||
{
|
||
try
|
||
{
|
||
// 使用ServiceLocator获取SerialCommunicationService
|
||
var serialService = ServiceLocator.Get<ISerialCommunicationService>();
|
||
if (serialService != null)
|
||
{
|
||
// 订阅串口服务事件
|
||
serialService.OnDeviceStatusReceived += OnSerialDeviceStatusReceived;
|
||
|
||
Debug.Log("MainPanel: 串口通信服务事件订阅完成");
|
||
|
||
// 尝试连接串口(如果还没连接)
|
||
// if (!serialService.IsConnected)
|
||
// {
|
||
// bool connected = serialService.Connect("COM1", 115200);
|
||
// if (connected)
|
||
// {
|
||
// Debug.Log("MainPanel: 串口连接成功");
|
||
// }
|
||
// else
|
||
// {
|
||
// Debug.LogWarning("MainPanel: 串口连接失败");
|
||
// }
|
||
// }
|
||
// else
|
||
// {
|
||
// Debug.Log("MainPanel: 串口已连接");
|
||
// }
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("MainPanel: 无法获取串口通信服务");
|
||
}
|
||
}
|
||
catch (System.Exception ex)
|
||
{
|
||
Debug.LogError($"MainPanel: 初始化串口通信失败: {ex.Message}");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 处理串口设备状态数据(来自SerialCommunicationService)
|
||
/// </summary>
|
||
private void OnSerialDeviceStatusReceived(DeviceStatusData status)
|
||
{
|
||
// 更新BFI值
|
||
OnBFIValueUpdated(status.BFI);
|
||
|
||
// 更新电池显示
|
||
// if (BatteryText != null)
|
||
// {
|
||
// BatteryText.text = $"电量: {status.BatteryLevel}%";
|
||
// }
|
||
|
||
// if (BatterySlider != null)
|
||
// {
|
||
// BatterySlider.value = status.BatteryLevel / 100f;
|
||
// }
|
||
|
||
// 显示激光器状态
|
||
string laserStatusText = status.LaserStatus switch
|
||
{
|
||
0 => "工作",
|
||
1 => "工作",
|
||
2 => "异常",
|
||
_ => "未知"
|
||
};
|
||
|
||
// 显示电源类型
|
||
string powerTypeText = status.PowerType switch
|
||
{
|
||
0 => "AC",
|
||
1 => "电池",
|
||
_ => "未知"
|
||
};
|
||
|
||
Debug.Log($"MainPanel设备状态 - BFI:{status.BFI:F1}, 电量:{status.BatteryLevel}%, " +
|
||
$"激光器:{laserStatusText}, 电源:{powerTypeText}, 温度:{status.Temperature * 0.1f:F1}°C");
|
||
}
|
||
|
||
|
||
|
||
/// <summary>
|
||
/// 切换静音状态
|
||
/// </summary>
|
||
private void ToggleMuteState()
|
||
{
|
||
if (_isMuted)
|
||
{
|
||
// 当前已静音,点击取消静音
|
||
CancelMute();
|
||
}
|
||
else
|
||
{
|
||
// 当前未静音,点击开启静音
|
||
StartMute();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开启静音
|
||
/// </summary>
|
||
private void StartMute()
|
||
{
|
||
// 从SystemSettingsService获取静音时长设置
|
||
var settingsService = ServiceLocator.Get<ISystemSettingsService>();
|
||
int muteDurationMinutes = settingsService?.MuteDurationMinutes ?? 3;
|
||
|
||
_isMuted = true;
|
||
_muteEndTime = DateTime.Now.AddMinutes(muteDurationMinutes);
|
||
|
||
// 停止当前播放的报警音频
|
||
if (AlarmAudioSource != null && AlarmAudioSource.isPlaying)
|
||
{
|
||
AlarmAudioSource.Stop();
|
||
}
|
||
|
||
// 启动静音倒计时协程
|
||
if (_muteTimerCoroutine != null)
|
||
{
|
||
StopCoroutine(_muteTimerCoroutine);
|
||
}
|
||
_muteTimerCoroutine = StartCoroutine(MuteTimerCoroutine());
|
||
|
||
UpdateMuteButtonText();
|
||
|
||
// 记录用户操作日志
|
||
var authService = ServiceLocator.Get<IAuthenticationService>();
|
||
var logService = ServiceLocator.Get<UserLogService>();
|
||
logService?.LogUserOperation(
|
||
authService?.CurrentUsername ?? "system",
|
||
"开启报警静音",
|
||
$"静音时长: {muteDurationMinutes}分钟",
|
||
true);
|
||
|
||
Debug.Log($"MainPanel: 开启静音 {muteDurationMinutes} 分钟");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 取消静音
|
||
/// </summary>
|
||
private void CancelMute()
|
||
{
|
||
_isMuted = false;
|
||
_muteEndTime = DateTime.MinValue;
|
||
|
||
// 停止倒计时协程
|
||
if (_muteTimerCoroutine != null)
|
||
{
|
||
StopCoroutine(_muteTimerCoroutine);
|
||
_muteTimerCoroutine = null;
|
||
}
|
||
|
||
UpdateMuteButtonText();
|
||
|
||
// 记录用户操作日志
|
||
var authService = ServiceLocator.Get<IAuthenticationService>();
|
||
var logService = ServiceLocator.Get<UserLogService>();
|
||
logService?.LogUserOperation(
|
||
authService?.CurrentUsername ?? "system",
|
||
"取消报警静音",
|
||
"手动取消静音",
|
||
true);
|
||
|
||
Debug.Log("MainPanel: 取消静音");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 静音倒计时协程
|
||
/// </summary>
|
||
private IEnumerator MuteTimerCoroutine()
|
||
{
|
||
while (_isMuted && DateTime.Now < _muteEndTime)
|
||
{
|
||
// 每秒更新一次按钮文本
|
||
UpdateMuteButtonText();
|
||
yield return new WaitForSeconds(1f);
|
||
}
|
||
|
||
// 时间到,自动恢复报警
|
||
if (_isMuted)
|
||
{
|
||
_isMuted = false;
|
||
_muteEndTime = DateTime.MinValue;
|
||
UpdateMuteButtonText();
|
||
|
||
// 记录自动恢复日志
|
||
var authService = ServiceLocator.Get<IAuthenticationService>();
|
||
var logService = ServiceLocator.Get<UserLogService>();
|
||
logService?.LogUserOperation(
|
||
authService?.CurrentUsername ?? "system",
|
||
"报警静音到期",
|
||
"静音时长结束,自动恢复报警",
|
||
true);
|
||
|
||
Debug.Log("MainPanel: 静音时长到期,自动恢复报警");
|
||
}
|
||
|
||
_muteTimerCoroutine = null;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化BodyAndOrgans控制
|
||
/// </summary>
|
||
private void InitializeBodyAndOrgansController()
|
||
{
|
||
// 启动UI层级检测
|
||
StartCoroutine(MonitorUILayers());
|
||
}
|
||
|
||
/// <summary>
|
||
/// 监控UI层级变化的协程
|
||
/// </summary>
|
||
private IEnumerator MonitorUILayers()
|
||
{
|
||
string lastCanvasState = "";
|
||
|
||
while (true)
|
||
{
|
||
yield return new WaitForSeconds(0.1f); // 每0.1秒检查一次
|
||
|
||
// 获取当前所有Canvas的状态快照
|
||
string currentCanvasState = GetCanvasStateSnapshot();
|
||
|
||
// 检查是否有变化
|
||
if (currentCanvasState != lastCanvasState)
|
||
{
|
||
Canvas[] currentCanvases = FindObjectsOfType<Canvas>();
|
||
UpdateBodyAndOrgansVisibility(currentCanvases);
|
||
lastCanvasState = currentCanvasState;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取Canvas状态快照字符串
|
||
/// </summary>
|
||
private string GetCanvasStateSnapshot()
|
||
{
|
||
Canvas[] canvases = FindObjectsOfType<Canvas>();
|
||
System.Text.StringBuilder sb = new System.Text.StringBuilder();
|
||
|
||
// 按sortingOrder排序
|
||
System.Array.Sort(canvases, (a, b) => a.sortingOrder.CompareTo(b.sortingOrder));
|
||
|
||
foreach (var canvas in canvases)
|
||
{
|
||
if (canvas != null)
|
||
{
|
||
sb.Append($"{canvas.name}:{canvas.sortingOrder}:{canvas.gameObject.activeInHierarchy}:");
|
||
|
||
// 也检查Canvas下的UI组件状态
|
||
var panels = canvas.GetComponentsInChildren<BasePanel>();
|
||
foreach (var panel in panels)
|
||
{
|
||
if (panel != null)
|
||
{
|
||
sb.Append($"[{panel.GetType().Name}:{panel.gameObject.activeInHierarchy}]");
|
||
}
|
||
}
|
||
sb.Append("|");
|
||
}
|
||
}
|
||
|
||
return sb.ToString();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新BodyAndOrgans的可见性
|
||
/// </summary>
|
||
private void UpdateBodyAndOrgansVisibility(Canvas[] canvases)
|
||
{
|
||
if (BodyAndOrgans == null) return;
|
||
|
||
// 检查是否有其他面板覆盖在MainPanel上
|
||
bool shouldShow = IsMainPanelTopMost(canvases);
|
||
|
||
if (BodyAndOrgans.activeInHierarchy != shouldShow)
|
||
{
|
||
BodyAndOrgans.SetActive(shouldShow);
|
||
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查是否有其他Canvas覆盖在MainPanel上
|
||
/// </summary>
|
||
private bool IsMainPanelTopMost(Canvas[] canvases)
|
||
{
|
||
if (canvases == null || canvases.Length == 0) return true;
|
||
|
||
// 首先找到MainPanel所在的Canvas及其sortingOrder
|
||
Canvas mainPanelCanvas = null;
|
||
int mainPanelSortOrder = int.MinValue;
|
||
|
||
// 查找MainPanel所在的Canvas
|
||
Transform current = this.transform;
|
||
while (current != null)
|
||
{
|
||
Canvas canvas = current.GetComponent<Canvas>();
|
||
if (canvas != null)
|
||
{
|
||
mainPanelCanvas = canvas;
|
||
mainPanelSortOrder = canvas.sortingOrder;
|
||
break;
|
||
}
|
||
current = current.parent;
|
||
}
|
||
|
||
// 如果没找到MainPanel的Canvas,默认显示
|
||
if (mainPanelCanvas == null) return true;
|
||
|
||
// 检查是否有其他Canvas的sortingOrder高于MainPanel的Canvas
|
||
foreach (var canvas in canvases)
|
||
{
|
||
if (canvas != null && canvas.gameObject.activeInHierarchy && canvas != mainPanelCanvas)
|
||
{
|
||
// 如果有任何其他Canvas的sortingOrder大于等于MainPanel的Canvas,说明有覆盖
|
||
if (canvas.sortingOrder >= mainPanelSortOrder)
|
||
{
|
||
// 进一步检查这个Canvas是否真的有UI内容
|
||
if (HasActiveUIContent(canvas))
|
||
{
|
||
return false; // 有其他Canvas覆盖
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return true; // 没有其他Canvas覆盖,MainPanel应该显示
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查Canvas是否有活跃的UI内容
|
||
/// </summary>
|
||
private bool HasActiveUIContent(Canvas canvas)
|
||
{
|
||
if (canvas == null || !canvas.gameObject.activeInHierarchy) return false;
|
||
|
||
// 检查是否有活跃的BasePanel组件(排除MainPanel自己)
|
||
var panels = canvas.GetComponentsInChildren<BasePanel>();
|
||
foreach (var panel in panels)
|
||
{
|
||
if (panel != null && panel.gameObject.activeInHierarchy && !(panel is MainPanel))
|
||
{
|
||
return true; // 发现活跃的其他面板
|
||
}
|
||
}
|
||
|
||
// 检查是否有其他活跃的UI组件(Button, Image等)
|
||
var uiComponents = canvas.GetComponentsInChildren<Graphic>();
|
||
foreach (var ui in uiComponents)
|
||
{
|
||
if (ui != null && ui.gameObject.activeInHierarchy)
|
||
{
|
||
// 检查这个UI组件是否属于MainPanel
|
||
Transform uiCurrent = ui.transform;
|
||
bool belongsToMainPanel = false;
|
||
while (uiCurrent != null)
|
||
{
|
||
if (uiCurrent.GetComponent<MainPanel>() != null)
|
||
{
|
||
belongsToMainPanel = true;
|
||
break;
|
||
}
|
||
uiCurrent = uiCurrent.parent;
|
||
}
|
||
|
||
// 如果UI组件不属于MainPanel,说明有其他UI内容
|
||
if (!belongsToMainPanel)
|
||
{
|
||
return true;
|
||
}
|
||
}
|
||
}
|
||
|
||
return false; // 没有发现活跃的其他UI内容
|
||
}
|
||
|
||
|
||
void OnDestroy()
|
||
{
|
||
|
||
// 取消订阅DCSAlarmManager事件
|
||
DCSAlarmManager.OnAlarmRaised -= OnDCSAlarmRaised;
|
||
// DCSAlarmManager.OnAlarmCleared -= OnAllAlarmsCleared;
|
||
// DCSAlarmManager.OnMuteStateChanged -= UpdateMuteButtonText;
|
||
// _patientInfoService.OnPatientInfoChanged -= LoadPatientInfo;
|
||
|
||
// 清理SerialCommunicationService事件订阅
|
||
var serialService = ServiceLocator.Get<ISerialCommunicationService>();
|
||
if (serialService != null)
|
||
{
|
||
serialService.OnDeviceStatusReceived -= OnSerialDeviceStatusReceived;
|
||
}
|
||
if (blinkCoroutine != null)
|
||
{
|
||
StopCoroutine(blinkCoroutine);
|
||
}
|
||
|
||
// 清理静音协程
|
||
if (_muteTimerCoroutine != null)
|
||
{
|
||
StopCoroutine(_muteTimerCoroutine);
|
||
_muteTimerCoroutine = null;
|
||
}
|
||
|
||
}
|
||
|
||
}
|