454 lines
15 KiB
C#
454 lines
15 KiB
C#
|
|
using UnityEngine;
|
|||
|
|
using UnityEngine.UI;
|
|||
|
|
using TMPro;
|
|||
|
|
using System;
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 时间设置面板
|
|||
|
|
/// 提供系统时间调节功能
|
|||
|
|
/// </summary>
|
|||
|
|
public class TimeSettingPanel : BasePanel
|
|||
|
|
{
|
|||
|
|
[Header("时间显示")]
|
|||
|
|
public TextMeshProUGUI CurrentTimeText;
|
|||
|
|
public TextMeshProUGUI DateDisplayText;
|
|||
|
|
|
|||
|
|
[Header("日期设置")]
|
|||
|
|
public TMP_Dropdown YearDropdown;
|
|||
|
|
public TMP_Dropdown MonthDropdown;
|
|||
|
|
public TMP_Dropdown DayDropdown;
|
|||
|
|
|
|||
|
|
[Header("时间设置")]
|
|||
|
|
public TMP_Dropdown HourDropdown;
|
|||
|
|
public TMP_Dropdown MinuteDropdown;
|
|||
|
|
public TMP_Dropdown SecondDropdown;
|
|||
|
|
|
|||
|
|
[Header("快捷按钮")]
|
|||
|
|
public Button SyncNetworkTimeButton;
|
|||
|
|
public Button ResetToNowButton;
|
|||
|
|
|
|||
|
|
[Header("控制按钮")]
|
|||
|
|
public Button HomeButton;
|
|||
|
|
public Button ConfirmButton;
|
|||
|
|
public Button BackButton;
|
|||
|
|
|
|||
|
|
private SettingsViewModel _vm;
|
|||
|
|
private DateTime _tempDateTime;
|
|||
|
|
private DateTime _baseConfigTime; // 配置的基准时间
|
|||
|
|
private DateTime _baseRealTime; // 真实的基准时间
|
|||
|
|
private bool _configTimeSet = false; // 是否已设置基准时间
|
|||
|
|
|
|||
|
|
public override void Init()
|
|||
|
|
{
|
|||
|
|
_vm = new SettingsViewModel();
|
|||
|
|
|
|||
|
|
// 从 TimeUpdateComponent 获取当前正在显示的时间
|
|||
|
|
var mainPanel = UIManager.Instance.GetPanel<MainPanel>();
|
|||
|
|
if (mainPanel != null && mainPanel.TimeUpdater != null)
|
|||
|
|
{
|
|||
|
|
// 直接使用 TimeUpdateComponent 的当前显示时间,确保完全同步
|
|||
|
|
_tempDateTime = mainPanel.TimeUpdater.GetCurrentDisplayTime();
|
|||
|
|
_baseConfigTime = _tempDateTime;
|
|||
|
|
_baseRealTime = DateTime.Now;
|
|||
|
|
_configTimeSet = true;
|
|||
|
|
Debug.Log($"TimeSettingPanel: 从TimeUpdateComponent获取当前显示时间: {_tempDateTime:yyyy-MM-dd HH:mm:ss}");
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
// 备用方案:使用配置时间或系统时间
|
|||
|
|
DateTime configTime = _vm.SystemTime;
|
|||
|
|
if (configTime == DateTime.MinValue)
|
|||
|
|
{
|
|||
|
|
_tempDateTime = DateTime.Now;
|
|||
|
|
}
|
|||
|
|
else
|
|||
|
|
{
|
|||
|
|
_tempDateTime = configTime;
|
|||
|
|
}
|
|||
|
|
_baseConfigTime = _tempDateTime;
|
|||
|
|
_baseRealTime = DateTime.Now;
|
|||
|
|
_configTimeSet = true;
|
|||
|
|
Debug.Log($"TimeSettingPanel: TimeUpdateComponent不可用,使用备用时间: {_tempDateTime:yyyy-MM-dd HH:mm:ss}");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
InitializeUI();
|
|||
|
|
PopulateDropdowns();
|
|||
|
|
UpdateTimeDisplay();
|
|||
|
|
|
|||
|
|
// 每秒更新时间显示和下拉框(让时间持续流动)
|
|||
|
|
InvokeRepeating(nameof(UpdateCurrentTimeDisplay), 0f, 1f);
|
|||
|
|
InvokeRepeating(nameof(UpdateDisplayedTime), 1f, 1f);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void InitializeUI()
|
|||
|
|
{
|
|||
|
|
// 下拉框事件监听
|
|||
|
|
if (YearDropdown != null) YearDropdown.onValueChanged.AddListener(OnYearOrMonthChanged);
|
|||
|
|
if (MonthDropdown != null) MonthDropdown.onValueChanged.AddListener(OnYearOrMonthChanged);
|
|||
|
|
if (DayDropdown != null) DayDropdown.onValueChanged.AddListener(OnDayChanged);
|
|||
|
|
if (HourDropdown != null) HourDropdown.onValueChanged.AddListener(OnTimeChanged);
|
|||
|
|
if (MinuteDropdown != null) MinuteDropdown.onValueChanged.AddListener(OnTimeChanged);
|
|||
|
|
if (SecondDropdown != null) SecondDropdown.onValueChanged.AddListener(OnTimeChanged);
|
|||
|
|
|
|||
|
|
// 快捷按钮
|
|||
|
|
// if (SyncNetworkTimeButton != null)
|
|||
|
|
// SyncNetworkTimeButton.onClick.AddListener(SyncWithNetworkTime);
|
|||
|
|
|
|||
|
|
if (ResetToNowButton != null)
|
|||
|
|
ResetToNowButton.onClick.AddListener(ResetToCurrentTime);
|
|||
|
|
|
|||
|
|
// 控制按钮
|
|||
|
|
if (HomeButton != null)
|
|||
|
|
{
|
|||
|
|
HomeButton.onClick.AddListener(() =>
|
|||
|
|
{
|
|||
|
|
ConfirmDialog.Show("确认", "是否返回主界面?", () =>
|
|||
|
|
{
|
|||
|
|
ReturnToHome();
|
|||
|
|
});
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (ConfirmButton != null)
|
|||
|
|
{
|
|||
|
|
ConfirmButton.onClick.AddListener(ApplyAndBack);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (BackButton != null)
|
|||
|
|
{
|
|||
|
|
BackButton.onClick.AddListener(() =>
|
|||
|
|
ConfirmDialog.Show("确认", "是否返回设置界面?", () =>
|
|||
|
|
{
|
|||
|
|
ClosePanel();
|
|||
|
|
ClosePanel();
|
|||
|
|
})
|
|||
|
|
);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void PopulateDropdowns()
|
|||
|
|
{
|
|||
|
|
_isRefreshingDropdowns = true; // 防止触发事件
|
|||
|
|
|
|||
|
|
// 年份下拉框 (当前年份前后10年)
|
|||
|
|
if (YearDropdown != null)
|
|||
|
|
{
|
|||
|
|
YearDropdown.options.Clear();
|
|||
|
|
int currentYear = DateTime.Now.Year;
|
|||
|
|
for (int year = currentYear - 10; year <= currentYear + 10; year++)
|
|||
|
|
{
|
|||
|
|
YearDropdown.options.Add(new TMP_Dropdown.OptionData(year.ToString()));
|
|||
|
|
}
|
|||
|
|
// 先设置value,这样PopulateDayDropdown能读取到正确的年份
|
|||
|
|
YearDropdown.SetValueWithoutNotify(_tempDateTime.Year - (currentYear - 10));
|
|||
|
|
YearDropdown.RefreshShownValue();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 月份下拉框
|
|||
|
|
if (MonthDropdown != null)
|
|||
|
|
{
|
|||
|
|
MonthDropdown.options.Clear();
|
|||
|
|
for (int month = 1; month <= 12; month++)
|
|||
|
|
{
|
|||
|
|
MonthDropdown.options.Add(new TMP_Dropdown.OptionData(month.ToString("00")));
|
|||
|
|
}
|
|||
|
|
// 先设置value,这样PopulateDayDropdown能读取到正确的月份
|
|||
|
|
MonthDropdown.SetValueWithoutNotify(_tempDateTime.Month - 1);
|
|||
|
|
MonthDropdown.RefreshShownValue();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 日期下拉框(现在能正确读取年月了)
|
|||
|
|
PopulateDayDropdown();
|
|||
|
|
|
|||
|
|
// 小时下拉框
|
|||
|
|
if (HourDropdown != null)
|
|||
|
|
{
|
|||
|
|
HourDropdown.options.Clear();
|
|||
|
|
for (int hour = 0; hour < 24; hour++)
|
|||
|
|
{
|
|||
|
|
HourDropdown.options.Add(new TMP_Dropdown.OptionData(hour.ToString("00")));
|
|||
|
|
}
|
|||
|
|
HourDropdown.SetValueWithoutNotify(_tempDateTime.Hour);
|
|||
|
|
HourDropdown.RefreshShownValue();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 分钟下拉框
|
|||
|
|
if (MinuteDropdown != null)
|
|||
|
|
{
|
|||
|
|
MinuteDropdown.options.Clear();
|
|||
|
|
for (int minute = 0; minute < 60; minute++)
|
|||
|
|
{
|
|||
|
|
MinuteDropdown.options.Add(new TMP_Dropdown.OptionData(minute.ToString("00")));
|
|||
|
|
}
|
|||
|
|
MinuteDropdown.SetValueWithoutNotify(_tempDateTime.Minute);
|
|||
|
|
MinuteDropdown.RefreshShownValue();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 秒钟下拉框
|
|||
|
|
if (SecondDropdown != null)
|
|||
|
|
{
|
|||
|
|
SecondDropdown.options.Clear();
|
|||
|
|
for (int second = 0; second < 60; second++)
|
|||
|
|
{
|
|||
|
|
SecondDropdown.options.Add(new TMP_Dropdown.OptionData(second.ToString("00")));
|
|||
|
|
}
|
|||
|
|
SecondDropdown.SetValueWithoutNotify(_tempDateTime.Second);
|
|||
|
|
SecondDropdown.RefreshShownValue();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_isRefreshingDropdowns = false;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void PopulateDayDropdown()
|
|||
|
|
{
|
|||
|
|
if (DayDropdown == null) return;
|
|||
|
|
|
|||
|
|
// 保存当前选择的日期(从1开始)
|
|||
|
|
int currentDay = _tempDateTime.Day;
|
|||
|
|
|
|||
|
|
DayDropdown.options.Clear();
|
|||
|
|
|
|||
|
|
// 获取当前选择的年月,计算该月的天数
|
|||
|
|
int year = GetSelectedYear();
|
|||
|
|
int month = GetSelectedMonth();
|
|||
|
|
int daysInMonth = DateTime.DaysInMonth(year, month);
|
|||
|
|
|
|||
|
|
for (int day = 1; day <= daysInMonth; day++)
|
|||
|
|
{
|
|||
|
|
DayDropdown.options.Add(new TMP_Dropdown.OptionData(day.ToString("00")));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 设置当前选择的日期,确保不超过该月的最大天数
|
|||
|
|
int selectedDay = Mathf.Min(currentDay, daysInMonth);
|
|||
|
|
|
|||
|
|
// 重要:设置value时不触发事件,然后手动刷新显示
|
|||
|
|
DayDropdown.SetValueWithoutNotify(selectedDay - 1);
|
|||
|
|
DayDropdown.RefreshShownValue();
|
|||
|
|
|
|||
|
|
// 更新_tempDateTime以反映可能的日期调整(例如从31号变为30号)
|
|||
|
|
if (currentDay != selectedDay)
|
|||
|
|
{
|
|||
|
|
_tempDateTime = new DateTime(year, month, selectedDay,
|
|||
|
|
_tempDateTime.Hour, _tempDateTime.Minute, _tempDateTime.Second);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private int GetSelectedYear()
|
|||
|
|
{
|
|||
|
|
if (YearDropdown == null) return DateTime.Now.Year;
|
|||
|
|
int currentYear = DateTime.Now.Year;
|
|||
|
|
return currentYear - 10 + YearDropdown.value;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private int GetSelectedMonth()
|
|||
|
|
{
|
|||
|
|
if (MonthDropdown == null) return DateTime.Now.Month;
|
|||
|
|
return MonthDropdown.value + 1;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private bool _isRefreshingDropdowns = false;
|
|||
|
|
|
|||
|
|
private void OnYearOrMonthChanged(int value)
|
|||
|
|
{
|
|||
|
|
// 防止下拉框更新时触发循环调用
|
|||
|
|
if (_isRefreshingDropdowns) return;
|
|||
|
|
|
|||
|
|
_isRefreshingDropdowns = true;
|
|||
|
|
|
|||
|
|
// 当年份或月份改变时,需要重新填充日期下拉框
|
|||
|
|
PopulateDayDropdown();
|
|||
|
|
|
|||
|
|
_isRefreshingDropdowns = false;
|
|||
|
|
|
|||
|
|
UpdateTempDateTime();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void OnDayChanged(int value)
|
|||
|
|
{
|
|||
|
|
// 防止下拉框更新时触发循环调用
|
|||
|
|
if (_isRefreshingDropdowns) return;
|
|||
|
|
|
|||
|
|
// 日期改变时只需要更新_tempDateTime,不需要重新填充下拉框
|
|||
|
|
UpdateTempDateTime();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void OnTimeChanged(int value)
|
|||
|
|
{
|
|||
|
|
UpdateTempDateTime();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void UpdateTempDateTime()
|
|||
|
|
{
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
int year = GetSelectedYear();
|
|||
|
|
int month = GetSelectedMonth();
|
|||
|
|
int day = DayDropdown != null ? DayDropdown.value + 1 : 1;
|
|||
|
|
int hour = HourDropdown != null ? HourDropdown.value : 0;
|
|||
|
|
int minute = MinuteDropdown != null ? MinuteDropdown.value : 0;
|
|||
|
|
int second = SecondDropdown != null ? SecondDropdown.value : 0;
|
|||
|
|
|
|||
|
|
_tempDateTime = new DateTime(year, month, day, hour, minute, second);
|
|||
|
|
|
|||
|
|
// 用户手动调整时,重置基准时间
|
|||
|
|
_baseConfigTime = _tempDateTime;
|
|||
|
|
_baseRealTime = DateTime.Now;
|
|||
|
|
_configTimeSet = true;
|
|||
|
|
|
|||
|
|
UpdateTimeDisplay();
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
Debug.LogError($"更新临时时间失败: {ex.Message}");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void UpdateTimeDisplay()
|
|||
|
|
{
|
|||
|
|
if (DateDisplayText != null)
|
|||
|
|
{
|
|||
|
|
DateDisplayText.text = _tempDateTime.ToString("yyyy年MM月dd日 HH:mm:ss");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void UpdateCurrentTimeDisplay()
|
|||
|
|
{
|
|||
|
|
if (CurrentTimeText != null)
|
|||
|
|
{
|
|||
|
|
// 显示真实的系统时间作为参考
|
|||
|
|
CurrentTimeText.text = $"当前系统时间: {DateTime.Now:yyyy-MM-dd HH:mm:ss}";
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 更新显示的时间(让时间持续流动,与 TimeUpdateComponent 保持一致)
|
|||
|
|
/// </summary>
|
|||
|
|
private void UpdateDisplayedTime()
|
|||
|
|
{
|
|||
|
|
if (!_configTimeSet) return;
|
|||
|
|
|
|||
|
|
// 计算从基准时间到现在的时间差
|
|||
|
|
TimeSpan elapsed = DateTime.Now - _baseRealTime;
|
|||
|
|
_tempDateTime = _baseConfigTime.Add(elapsed);
|
|||
|
|
|
|||
|
|
// 更新下拉框显示
|
|||
|
|
UpdateDropdownsFromDateTime(_tempDateTime);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// private void SyncWithNetworkTime()
|
|||
|
|
// {
|
|||
|
|
// Debug.Log("尝试与网络时间同步...");
|
|||
|
|
|
|||
|
|
// // 在实际实现中,这里应该连接NTP服务器获取网络时间
|
|||
|
|
// // 现在使用本地时间作为模拟
|
|||
|
|
// DateTime networkTime = DateTime.Now;
|
|||
|
|
|
|||
|
|
// _tempDateTime = networkTime;
|
|||
|
|
|
|||
|
|
// // 重置基准时间
|
|||
|
|
// _baseConfigTime = _tempDateTime;
|
|||
|
|
// _baseRealTime = DateTime.Now;
|
|||
|
|
// _configTimeSet = true;
|
|||
|
|
|
|||
|
|
// UpdateDropdownsFromDateTime(_tempDateTime);
|
|||
|
|
// UpdateTimeDisplay();
|
|||
|
|
|
|||
|
|
// Debug.Log($"已同步网络时间: {networkTime:yyyy-MM-dd HH:mm:ss}");
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
private void ResetToCurrentTime()
|
|||
|
|
{
|
|||
|
|
_tempDateTime = DateTime.Now;
|
|||
|
|
|
|||
|
|
// 重置基准时间
|
|||
|
|
_baseConfigTime = _tempDateTime;
|
|||
|
|
_baseRealTime = DateTime.Now;
|
|||
|
|
_configTimeSet = true;
|
|||
|
|
|
|||
|
|
UpdateDropdownsFromDateTime(_tempDateTime);
|
|||
|
|
UpdateTimeDisplay();
|
|||
|
|
|
|||
|
|
Debug.Log("时间已重置为当前系统时间");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void UpdateDropdownsFromDateTime(DateTime dateTime)
|
|||
|
|
{
|
|||
|
|
_isRefreshingDropdowns = true;
|
|||
|
|
|
|||
|
|
// 先更新_tempDateTime,这样PopulateDayDropdown可以使用正确的日期
|
|||
|
|
_tempDateTime = dateTime;
|
|||
|
|
|
|||
|
|
// 更新年份
|
|||
|
|
if (YearDropdown != null)
|
|||
|
|
{
|
|||
|
|
int currentYear = DateTime.Now.Year;
|
|||
|
|
int yearIndex = dateTime.Year - (currentYear - 10);
|
|||
|
|
if (yearIndex >= 0 && yearIndex < YearDropdown.options.Count)
|
|||
|
|
{
|
|||
|
|
YearDropdown.SetValueWithoutNotify(yearIndex);
|
|||
|
|
YearDropdown.RefreshShownValue();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 更新月份
|
|||
|
|
if (MonthDropdown != null)
|
|||
|
|
{
|
|||
|
|
MonthDropdown.SetValueWithoutNotify(dateTime.Month - 1);
|
|||
|
|
MonthDropdown.RefreshShownValue();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// 重新填充日期下拉框(会自动设置正确的日期值)
|
|||
|
|
PopulateDayDropdown();
|
|||
|
|
|
|||
|
|
// 更新时间
|
|||
|
|
if (HourDropdown != null)
|
|||
|
|
{
|
|||
|
|
HourDropdown.SetValueWithoutNotify(dateTime.Hour);
|
|||
|
|
HourDropdown.RefreshShownValue();
|
|||
|
|
}
|
|||
|
|
if (MinuteDropdown != null)
|
|||
|
|
{
|
|||
|
|
MinuteDropdown.SetValueWithoutNotify(dateTime.Minute);
|
|||
|
|
MinuteDropdown.RefreshShownValue();
|
|||
|
|
}
|
|||
|
|
if (SecondDropdown != null)
|
|||
|
|
{
|
|||
|
|
SecondDropdown.SetValueWithoutNotify(dateTime.Second);
|
|||
|
|
SecondDropdown.RefreshShownValue();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
_isRefreshingDropdowns = false;
|
|||
|
|
|
|||
|
|
// 最后更新显示
|
|||
|
|
UpdateTimeDisplay();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private void ApplyAndBack()
|
|||
|
|
{
|
|||
|
|
// 只更新显示时间,不修改安卓系统时间
|
|||
|
|
// 注意:这里只是保存到配置中用于UI显示,不会调用系统API修改实际系统时间
|
|||
|
|
_vm.SystemTime = _tempDateTime;
|
|||
|
|
|
|||
|
|
// 通知MainPanel的TimeUpdateComponent刷新显示
|
|||
|
|
var mainPanel = UIManager.Instance.GetPanel<MainPanel>();
|
|||
|
|
if (mainPanel != null && mainPanel.TimeUpdater != null)
|
|||
|
|
{
|
|||
|
|
mainPanel.TimeUpdater.RefreshConfigTime();
|
|||
|
|
Debug.Log("TimeSettingPanel: 已通知TimeUpdateComponent刷新时间显示");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Debug.Log($"UI显示时间已更新为: {_tempDateTime:yyyy-MM-dd HH:mm:ss}(不修改系统时间)");
|
|||
|
|
ClosePanel();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// public void ClosePanel()
|
|||
|
|
// {
|
|||
|
|
// CancelInvoke();
|
|||
|
|
// UIManager.Instance.HidePanel<TimeSettingPanel>();
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
void OnDestroy()
|
|||
|
|
{
|
|||
|
|
CancelInvoke();
|
|||
|
|
}
|
|||
|
|
}
|