642 lines
22 KiB
C#
642 lines
22 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using Kill.Bluetooth;
|
||
using Kill.Bluetooth.Protocol;
|
||
using Kill.Core;
|
||
using Kill.Managers;
|
||
using Kill.UI.Components;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
namespace Kill.UI.Pages
|
||
{
|
||
public class ScheduleSettingPage : MonoBehaviour
|
||
{
|
||
// 多语言Key
|
||
List<string> modeKeys = new List<string> { "100094", "100095", "100096" };
|
||
List<string> modeStrs = new List<string>();
|
||
List<string> weekStr = new List<string>();
|
||
List<string> weekStrKeys = new List<string> { "100130", "100124", "100125", "100126", "100127", "100128", "100129" };
|
||
|
||
// 定时任务UI列表
|
||
public OneSchedule[] scheduleItems;
|
||
|
||
// 编辑页面
|
||
public ScheduleEditPage scheduleEditPage;
|
||
|
||
// 新增按钮
|
||
public Button addButton;
|
||
public Button closeBtn;
|
||
// 缓存的定时任务列表
|
||
private List<ScheduleTask> _scheduleTasks = new List<ScheduleTask>();
|
||
|
||
// 最大任务数量
|
||
private const int MAX_SCHEDULE_COUNT = 5;
|
||
|
||
// 页面关闭回调(用于通知主页更新)
|
||
public System.Action OnPageClosed;
|
||
|
||
// 静态标志:是否有设置页面正在处理回调
|
||
private static bool _isSettingPageActive = false;
|
||
|
||
public GameObject noTip;
|
||
private void OnEnable()
|
||
{
|
||
// 设置标志位,表示设置页面正在处理
|
||
_isSettingPageActive = true;
|
||
|
||
// 订阅蓝牙事件
|
||
if (BLECommunicationManager.Instance != null)
|
||
{
|
||
BLECommunicationManager.Instance.OnScheduleTaskListReceived += OnScheduleTaskListReceived;
|
||
}
|
||
|
||
// 加载多语言
|
||
LoadLocalizedStrings();
|
||
|
||
// 绑定新增按钮事件
|
||
BindAddButton();
|
||
|
||
// 读取定时任务
|
||
ReadScheduleTasks();
|
||
}
|
||
|
||
private void OnDisable()
|
||
{
|
||
// 取消订阅蓝牙事件
|
||
if (BLECommunicationManager.Instance != null)
|
||
{
|
||
BLECommunicationManager.Instance.OnScheduleTaskListReceived -= OnScheduleTaskListReceived;
|
||
}
|
||
|
||
// 清除标志位
|
||
_isSettingPageActive = false;
|
||
|
||
// 通知主页更新定时任务状态
|
||
OnPageClosed?.Invoke();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 检查是否有设置页面正在处理回调
|
||
/// </summary>
|
||
public static bool IsSettingPageActive()
|
||
{
|
||
return _isSettingPageActive;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 加载多语言字符串
|
||
/// </summary>
|
||
private void LoadLocalizedStrings()
|
||
{
|
||
modeStrs.Clear();
|
||
foreach (var key in modeKeys)
|
||
{
|
||
modeStrs.Add(LanguageManager.Instance?.GetLanguage(key) ?? key);
|
||
}
|
||
|
||
weekStr.Clear();
|
||
foreach (var key in weekStrKeys)
|
||
{
|
||
weekStr.Add(LanguageManager.Instance?.GetLanguage(key) ?? key);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 读取定时任务
|
||
/// </summary>
|
||
public async void ReadScheduleTasks()
|
||
{
|
||
if (DataManager.Instance.hasWifi && !DataManager.Instance.hasBluetooth)
|
||
{
|
||
Debug.Log("[ScheduleSettingPage] WiFi模式读取定时任务...");
|
||
await DataManager.Instance.GetScheduleTasks(DataManager.Instance.selectedDevice.device_sn);
|
||
Debug.Log($"[ScheduleSettingPage] WiFi获取到 {DataManager.Instance.scheduleTaskDatas.Count} 条原始数据");
|
||
|
||
// 将API数据转换为ScheduleTask,过滤全0无效任务
|
||
var tasks = new List<ScheduleTask>();
|
||
foreach (var d in DataManager.Instance.scheduleTaskDatas)
|
||
{
|
||
// 过滤开始时间和结束时间都为0的无效任务(与BLE过滤规则一致)
|
||
bool isInvalid = d.start_hour == 0 && d.start_minute == 0 &&
|
||
d.end_hour == 0 && d.end_minute == 0;
|
||
if (isInvalid)
|
||
{
|
||
Debug.Log($"[ScheduleSettingPage] WiFi过滤无效任务 ID={d.task_id}");
|
||
continue;
|
||
}
|
||
tasks.Add(new ScheduleTask
|
||
{
|
||
TaskId = d.task_id,
|
||
Enabled = d.enabled,
|
||
StartHour = d.start_hour,
|
||
StartMinute = d.start_minute,
|
||
EndHour = d.end_hour,
|
||
EndMinute = d.end_minute,
|
||
Mode = (ScheduleTaskMode)System.Enum.Parse(typeof(ScheduleTaskMode), d.mode, true),
|
||
Repeat = d.repeat_mask
|
||
});
|
||
}
|
||
Debug.Log($"[ScheduleSettingPage] WiFi有效任务数: {tasks.Count}");
|
||
UpdateScheduleUI(tasks.ToArray());
|
||
return;
|
||
}
|
||
|
||
if (BLECommunicationManager.Instance != null && BluetoothManager.Instance.IsConnected)
|
||
{
|
||
Debug.Log("[ScheduleSettingPage] 开始读取定时任务...");
|
||
// 显示Loading
|
||
LoadingUI.Show();
|
||
BLECommunicationManager.Instance.ReadScheduleTasks();
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning("[ScheduleSettingPage] 蓝牙未连接,无法读取定时任务");
|
||
// 显示空列表
|
||
UpdateScheduleUI(new ScheduleTask[0]);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 收到定时任务列表回调
|
||
/// </summary>
|
||
private void OnScheduleTaskListReceived(ScheduleTaskListResponse response)
|
||
{
|
||
// WiFi模式下忽略BLE回调
|
||
if (DataManager.Instance.hasWifi && !DataManager.Instance.hasBluetooth)
|
||
{
|
||
Debug.Log("[ScheduleSettingPage] WiFi模式下忽略BLE定时任务回调");
|
||
return;
|
||
}
|
||
|
||
Loom.QueueOnMainThread(() =>
|
||
{
|
||
Debug.Log($"[ScheduleSettingPage] 收到定时任务列表,状态: {response.Status}");
|
||
|
||
// 隐藏Loading
|
||
LoadingUI.Hide();
|
||
|
||
if (response.IsSuccess)
|
||
{
|
||
// 过滤有效任务:开始时间和结束时间都为0的任务视为无效
|
||
var validTasks = FilterValidTasks(response.Tasks);
|
||
UpdateScheduleUI(validTasks);
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError($"[ScheduleSettingPage] 读取定时任务失败,状态码: {response.Status}");
|
||
UpdateScheduleUI(new ScheduleTask[0]);
|
||
}
|
||
});
|
||
}
|
||
|
||
/// <summary>
|
||
/// 过滤有效任务
|
||
/// 规则:开始时间和结束时间都为0的任务视为无效,从列表中剔除
|
||
/// </summary>
|
||
private ScheduleTask[] FilterValidTasks(ScheduleTask[] tasks)
|
||
{
|
||
if (tasks == null || tasks.Length == 0)
|
||
{
|
||
return new ScheduleTask[0];
|
||
}
|
||
|
||
var validTasks = tasks.Where(task =>
|
||
{
|
||
// 检查开始时间和结束时间是否都为0
|
||
bool isInvalid = task.StartHour == 0 && task.StartMinute == 0 &&
|
||
task.EndHour == 0 && task.EndMinute == 0;
|
||
|
||
if (isInvalid)
|
||
{
|
||
Debug.Log($"[ScheduleSettingPage] 过滤无效任务 ID={task.TaskId}: 开始时间和结束时间都为0");
|
||
}
|
||
|
||
return !isInvalid;
|
||
}).ToArray();
|
||
|
||
Debug.Log($"[ScheduleSettingPage] 原始任务数: {tasks.Length}, 有效任务数: {validTasks.Length}");
|
||
return validTasks;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 更新定时任务UI
|
||
/// </summary>
|
||
private void UpdateScheduleUI(ScheduleTask[] tasks)
|
||
{
|
||
_scheduleTasks.Clear();
|
||
|
||
if (tasks != null)
|
||
{
|
||
// 最多只取5个任务
|
||
int count = Mathf.Min(tasks.Length, MAX_SCHEDULE_COUNT);
|
||
for (int i = 0; i < count; i++)
|
||
{
|
||
_scheduleTasks.Add(tasks[i]);
|
||
}
|
||
}
|
||
|
||
// 更新UI显示
|
||
RefreshScheduleItems();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 刷新定时任务UI项
|
||
/// </summary>
|
||
private void RefreshScheduleItems()
|
||
{
|
||
if (scheduleItems == null)
|
||
{
|
||
Debug.LogWarning("[ScheduleSettingPage] scheduleItems 未设置");
|
||
return;
|
||
}
|
||
|
||
|
||
// 隐藏所有项
|
||
foreach (var item in scheduleItems)
|
||
{
|
||
if (item != null)
|
||
{
|
||
item.gameObject.SetActive(false);
|
||
}
|
||
}
|
||
noTip.SetActive(true);
|
||
|
||
// 显示有效任务
|
||
for (int i = 0; i < _scheduleTasks.Count && i < scheduleItems.Length; i++)
|
||
{
|
||
int index = i; // 捕获索引用于回调
|
||
var task = _scheduleTasks[i];
|
||
var item = scheduleItems[i];
|
||
|
||
if (item != null)
|
||
{
|
||
item.gameObject.SetActive(true);
|
||
|
||
string modeText = GetModeText(task.Mode);
|
||
string repeatText = GetRepeatText(task.Repeat);
|
||
|
||
// 使用 OneSchedule 的 Init 方法初始化
|
||
item.Init(index, task, modeText, repeatText, OnSwitchValueChanged);
|
||
|
||
// 绑定点击事件(用于编辑)
|
||
BindItemClick(item, index);
|
||
noTip.SetActive(false);
|
||
}
|
||
}
|
||
|
||
Debug.Log($"[ScheduleSettingPage] UI已更新,显示 {_scheduleTasks.Count} 个任务");
|
||
}
|
||
|
||
/// <summary>
|
||
/// 绑定新增按钮事件
|
||
/// </summary>
|
||
private void BindAddButton()
|
||
{
|
||
if (addButton != null)
|
||
{
|
||
addButton.onClick.RemoveAllListeners();
|
||
addButton.onClick.AddListener(OnAddButtonClick);
|
||
|
||
// 根据任务数量显示/隐藏新增按钮
|
||
addButton.gameObject.SetActive(_scheduleTasks.Count < MAX_SCHEDULE_COUNT);
|
||
}
|
||
if (closeBtn != null)
|
||
{
|
||
closeBtn.onClick.RemoveAllListeners();
|
||
closeBtn.onClick.AddListener(() =>
|
||
{
|
||
ClosePage();
|
||
});
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 新增按钮点击
|
||
/// </summary>
|
||
private void OnAddButtonClick()
|
||
{
|
||
Debug.Log("[ScheduleSettingPage] 点击新增任务");
|
||
|
||
if (scheduleEditPage != null)
|
||
{
|
||
scheduleEditPage.gameObject.SetActive(true);
|
||
scheduleEditPage.Init(-1, new ScheduleTask(), OnTaskSaved, null);
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("[ScheduleSettingPage] ScheduleEditPage 未设置");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 绑定任务项点击事件
|
||
/// </summary>
|
||
private void BindItemClick(OneSchedule item, int index)
|
||
{
|
||
// 获取按钮组件(假设 OneSchedule 有 Button 或者在父物体上)
|
||
Button button = item.GetComponent<Button>();
|
||
if (button == null)
|
||
{
|
||
button = item.GetComponentInChildren<Button>(true);
|
||
}
|
||
|
||
if (button != null && button != item.isOnSwitch?.GetComponent<Button>())
|
||
{
|
||
button.onClick.RemoveAllListeners();
|
||
int taskIndex = index;
|
||
button.onClick.AddListener(() => OnItemClick(taskIndex));
|
||
}
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 任务项点击(进入编辑)
|
||
/// </summary>
|
||
private void OnItemClick(int taskIndex)
|
||
{
|
||
if (taskIndex < 0 || taskIndex >= _scheduleTasks.Count)
|
||
{
|
||
Debug.LogWarning($"[ScheduleSettingPage] 无效的任务索引: {taskIndex}");
|
||
return;
|
||
}
|
||
|
||
Debug.Log($"[ScheduleSettingPage] 点击编辑任务 {taskIndex}");
|
||
|
||
if (scheduleEditPage != null)
|
||
{
|
||
var task = _scheduleTasks[taskIndex];
|
||
scheduleEditPage.gameObject.SetActive(true);
|
||
scheduleEditPage.Init(taskIndex, task, OnTaskSaved, OnTaskDeleted);
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("[ScheduleSettingPage] ScheduleEditPage 未设置");
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 任务保存回调
|
||
/// </summary>
|
||
private void OnTaskSaved(ScheduleTask task, int taskIndex)
|
||
{
|
||
if (taskIndex < 0)
|
||
{
|
||
// 新增任务
|
||
if (AddScheduleTask(task))
|
||
{
|
||
Debug.Log($"[ScheduleSettingPage] 新增任务成功");
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 编辑任务
|
||
if (taskIndex < _scheduleTasks.Count)
|
||
{
|
||
_scheduleTasks[taskIndex] = task;
|
||
RefreshScheduleItems();
|
||
Debug.Log($"[ScheduleSettingPage] 编辑任务 {taskIndex} 成功");
|
||
}
|
||
}
|
||
|
||
// 保存到设备
|
||
SaveScheduleTasks();
|
||
|
||
// 更新新增按钮状态
|
||
if (addButton != null)
|
||
{
|
||
addButton.gameObject.SetActive(_scheduleTasks.Count < MAX_SCHEDULE_COUNT);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 任务删除回调
|
||
/// </summary>
|
||
private void OnTaskDeleted(int taskIndex)
|
||
{
|
||
RemoveScheduleTask(taskIndex);
|
||
SaveScheduleTasks();
|
||
|
||
// 更新新增按钮状态
|
||
if (addButton != null)
|
||
{
|
||
addButton.gameObject.SetActive(_scheduleTasks.Count < MAX_SCHEDULE_COUNT);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 开关状态变化回调
|
||
/// </summary>
|
||
private void OnSwitchValueChanged(int taskIndex, bool isOn)
|
||
{
|
||
if (taskIndex < 0 || taskIndex >= _scheduleTasks.Count)
|
||
{
|
||
Debug.LogWarning($"[ScheduleSettingPage] 无效的任务索引: {taskIndex}");
|
||
return;
|
||
}
|
||
|
||
// 更新任务状态
|
||
var task = _scheduleTasks[taskIndex];
|
||
task.Enabled = isOn;
|
||
_scheduleTasks[taskIndex] = task;
|
||
|
||
Debug.Log($"[ScheduleSettingPage] 任务 {taskIndex} 开关状态变更为: {(isOn ? "启用" : "禁用")}");
|
||
|
||
// 保存到设备
|
||
SaveScheduleTasks();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取模式显示文本
|
||
/// </summary>
|
||
private string GetModeText(ScheduleTaskMode mode)
|
||
{
|
||
int index = mode switch
|
||
{
|
||
ScheduleTaskMode.Standby => 0,
|
||
ScheduleTaskMode.Scan => 1,
|
||
ScheduleTaskMode.Sterilize => 2,
|
||
_ => 0
|
||
};
|
||
|
||
if (index >= 0 && index < modeStrs.Count)
|
||
{
|
||
return modeStrs[index];
|
||
}
|
||
|
||
return mode.ToString();
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取重复时间显示文本
|
||
/// </summary>
|
||
private string GetRepeatText(byte repeat)
|
||
{
|
||
// 没有重复时返回空字符串
|
||
if (repeat == 0)
|
||
{
|
||
return string.Empty;
|
||
}
|
||
|
||
// 检查是否7天都重复
|
||
byte allDays = ScheduleTask.REPEAT_SUNDAY | ScheduleTask.REPEAT_MONDAY | ScheduleTask.REPEAT_TUESDAY |
|
||
ScheduleTask.REPEAT_WEDNESDAY | ScheduleTask.REPEAT_THURSDAY | ScheduleTask.REPEAT_FRIDAY |
|
||
ScheduleTask.REPEAT_SATURDAY;
|
||
if (repeat == allDays)
|
||
{
|
||
return LanguageManager.Instance?.GetLanguage("100138") ?? "Everyday"; // 每天
|
||
}
|
||
|
||
var days = new List<string>();
|
||
if ((repeat & ScheduleTask.REPEAT_SUNDAY) != 0) days.Add(weekStr[0]); // Sun
|
||
if ((repeat & ScheduleTask.REPEAT_MONDAY) != 0) days.Add(weekStr[1]); // Mon
|
||
if ((repeat & ScheduleTask.REPEAT_TUESDAY) != 0) days.Add(weekStr[2]); // Tue
|
||
if ((repeat & ScheduleTask.REPEAT_WEDNESDAY) != 0) days.Add(weekStr[3]); // Wed
|
||
if ((repeat & ScheduleTask.REPEAT_THURSDAY) != 0) days.Add(weekStr[4]); // Thu
|
||
if ((repeat & ScheduleTask.REPEAT_FRIDAY) != 0) days.Add(weekStr[5]); // Fri
|
||
if ((repeat & ScheduleTask.REPEAT_SATURDAY) != 0) days.Add(weekStr[6]); // Sat
|
||
return string.Join(", ", days);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 获取当前任务列表
|
||
/// </summary>
|
||
public List<ScheduleTask> GetScheduleTasks()
|
||
{
|
||
return _scheduleTasks;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 添加新任务
|
||
/// </summary>
|
||
public bool AddScheduleTask(ScheduleTask task)
|
||
{
|
||
if (_scheduleTasks.Count >= MAX_SCHEDULE_COUNT)
|
||
{
|
||
Debug.LogWarning($"[ScheduleSettingPage] 任务数量已达上限 {MAX_SCHEDULE_COUNT}");
|
||
return false;
|
||
}
|
||
|
||
_scheduleTasks.Add(task);
|
||
RefreshScheduleItems();
|
||
return true;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 删除任务
|
||
/// </summary>
|
||
public void RemoveScheduleTask(int index)
|
||
{
|
||
if (index >= 0 && index < _scheduleTasks.Count)
|
||
{
|
||
_scheduleTasks.RemoveAt(index);
|
||
RefreshScheduleItems();
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 保存定时任务到设备
|
||
/// 有效数据放在前面,后面补全0数据
|
||
/// </summary>
|
||
public async void SaveScheduleTasks()
|
||
{
|
||
if (DataManager.Instance.hasWifi && !DataManager.Instance.hasBluetooth)
|
||
{
|
||
LoadingUI.Show();
|
||
var tasksToSave = new List<ScheduleTask>();
|
||
for (int i = 0; i < _scheduleTasks.Count && i < MAX_SCHEDULE_COUNT; i++)
|
||
{
|
||
var task = _scheduleTasks[i];
|
||
task.TaskId = (byte)i;
|
||
tasksToSave.Add(task);
|
||
}
|
||
// 补齐到5个任务,空任务用全0填充(与BLE保持一致)
|
||
while (tasksToSave.Count < MAX_SCHEDULE_COUNT)
|
||
{
|
||
tasksToSave.Add(new ScheduleTask
|
||
{
|
||
TaskId = (byte)tasksToSave.Count,
|
||
Enabled = false,
|
||
StartHour = 0,
|
||
StartMinute = 0,
|
||
EndHour = 0,
|
||
EndMinute = 0,
|
||
Mode = ScheduleTaskMode.Standby,
|
||
Repeat = 0
|
||
});
|
||
}
|
||
await HomePageCtrl.Instance?.SaveScheduleTasksAsync(tasksToSave);
|
||
LoadingUI.Hide();
|
||
return;
|
||
}
|
||
|
||
if (BLECommunicationManager.Instance != null && BluetoothManager.Instance.IsConnected)
|
||
{
|
||
// 显示Loading
|
||
LoadingUI.Show();
|
||
|
||
// 创建保存列表,重新设置TaskId
|
||
var tasksToSave = new List<ScheduleTask>();
|
||
|
||
// 先添加有效任务,重新分配TaskId(0-4)
|
||
for (int i = 0; i < _scheduleTasks.Count && i < MAX_SCHEDULE_COUNT; i++)
|
||
{
|
||
var task = _scheduleTasks[i];
|
||
task.TaskId = (byte)i;
|
||
tasksToSave.Add(task);
|
||
}
|
||
|
||
// 补齐到5个任务,空任务用全0填充
|
||
while (tasksToSave.Count < MAX_SCHEDULE_COUNT)
|
||
{
|
||
tasksToSave.Add(new ScheduleTask
|
||
{
|
||
TaskId = (byte)tasksToSave.Count,
|
||
Enabled = false,
|
||
StartHour = 0,
|
||
StartMinute = 0,
|
||
EndHour = 0,
|
||
EndMinute = 0,
|
||
Mode = ScheduleTaskMode.Standby,
|
||
Repeat = 0
|
||
});
|
||
}
|
||
|
||
Debug.Log($"[ScheduleSettingPage] 保存定时任务,有效任务数: {_scheduleTasks.Count},总任务数: {tasksToSave.Count}");
|
||
|
||
BLECommunicationManager.Instance.WriteScheduleTasks(tasksToSave.ToArray(), (success) =>
|
||
{
|
||
Loom.QueueOnMainThread(() =>
|
||
{
|
||
// 隐藏Loading
|
||
LoadingUI.Hide();
|
||
|
||
if (success)
|
||
{
|
||
Debug.Log("[ScheduleSettingPage] 定时任务保存成功");
|
||
}
|
||
else
|
||
{
|
||
Debug.LogError("[ScheduleSettingPage] 定时任务保存失败");
|
||
}
|
||
});
|
||
});
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning("[ScheduleSettingPage] 蓝牙未连接,无法保存定时任务");
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 关闭页面
|
||
/// </summary>
|
||
public void ClosePage()
|
||
{
|
||
LoadingUI.Hide();
|
||
Destroy(gameObject);
|
||
}
|
||
}
|
||
|
||
}
|