refactor(FirmwareUpdatePage): 重构固件升级流程逻辑

1. 拆分同步和异步点击处理方法,优化防连点逻辑
2. 简化等待设备重启的流程,不再轮询设备版本
3. 调整升级状态的清理和恢复时机
This commit is contained in:
“虞渠成” 2026-08-27 14:18:31 +08:00
parent a95b257b0d
commit b43121d2ec

View File

@ -116,18 +116,25 @@ namespace Kill.UI.Pages
Destroy(gameObject); Destroy(gameObject);
Screen.sleepTimeout = SleepTimeout.SystemSetting; Screen.sleepTimeout = SleepTimeout.SystemSetting;
} }
public async void OnUpdateButtonClick() public void OnUpdateButtonClick()
{ {
// 防连点升级流程进行中忽略重复触发避免并发启动两个OTA // 防连点升级流程进行中忽略重复触发避免并发启动两个OTA
if (isUpdating) return; if (isUpdating) return;
isUpdating = true; isUpdating = true;
// 立刻隐藏更新按钮,防止连点期间按钮仍可点
updateButton.gameObject.SetActive(false);
Screen.sleepTimeout = SleepTimeout.NeverSleep; Screen.sleepTimeout = SleepTimeout.NeverSleep;
OnUpdateButtonClickAsync();
}
private async void OnUpdateButtonClickAsync()
{
// 仅蓝牙连接不支持直接OTA提示先配置WiFi // 仅蓝牙连接不支持直接OTA提示先配置WiFi
if (DataManager.Instance.hasBluetooth && !DataManager.Instance.hasWifi) if (DataManager.Instance.hasBluetooth && !DataManager.Instance.hasWifi)
{ {
ToastUI.Show("100333"); ToastUI.Show("100333");
isUpdating = false; isUpdating = false;
updateButton.gameObject.SetActive(true);
return; return;
} }
@ -192,6 +199,7 @@ namespace Kill.UI.Pages
{ {
ToastUI.Show("100224"); ToastUI.Show("100224");
isUpdating = false; isUpdating = false;
updateButton.gameObject.SetActive(true);
return; return;
} }
string md5 = NetworkCtrl.Instance.CalculateMD5(savePath); string md5 = NetworkCtrl.Instance.CalculateMD5(savePath);
@ -201,12 +209,14 @@ namespace Kill.UI.Pages
Debug.LogError("下载的文件MD5校验失败"); Debug.LogError("下载的文件MD5校验失败");
File.Delete(savePath); File.Delete(savePath);
isUpdating = false; isUpdating = false;
updateButton.gameObject.SetActive(true);
return; return;
} }
LoadFirmwareFile(savePath); LoadFirmwareFile(savePath);
if (_selectedFirmwareData == null) if (_selectedFirmwareData == null)
{ {
isUpdating = false; isUpdating = false;
updateButton.gameObject.SetActive(true);
return; return;
} }
ToastUI.Show("100225"); ToastUI.Show("100225");
@ -381,70 +391,20 @@ namespace Kill.UI.Pages
} }
/// <summary> /// <summary>
/// 传输完成后等待设备重启+重连:轮询设备列表直到当前设备以新版本号上线,否则按持久化的绝对截止时间超时退出 /// 传输完成后的过渡等3s → 提示 100226 → 返回主页
/// 期间保持 transferId 持久化、保留页内进度条显示「升级中」文案,重新进入页面也能继续等待(截止时间不会重置) /// 设备重启/版本号刷新由后台下次进入页面或下次 OTA 拉取时再处理
/// </summary> /// </summary>
private IEnumerator WaitDeviceRebootAndFinish(string transferId) private IEnumerator WaitDeviceRebootAndFinish(string transferId)
{ {
const float pollInterval = 3f; // 轮询间隔
long deadline = LoadWaitDeadline();
// 兜底:若没设置过截止时间,立即设置一个
if (deadline <= 0)
{
SetWaitDeadline();
deadline = LoadWaitDeadline();
}
// 已超过绝对截止时间:直接走超时分支并清掉 transferId避免每次进入都重复提示
if (DateTimeOffset.UtcNow.ToUnixTimeSeconds() >= deadline)
{
ClearTransferId();
HideProgressPanel();
updateButton.gameObject.SetActive(true);
ToastUI.Show("ota_update_failed");
yield break;
}
ShowProgressPanelWaitingForDevice(); ShowProgressPanelWaitingForDevice();
ToastUI.Show("100226"); // 传输完成提示 // 等3s 提示传输完成(给用户缓冲),然后返回主页
string targetVersion = otaData != null ? otaData.version : ""; yield return new WaitForSeconds(3f);
bool rebooted = false;
while (DateTimeOffset.UtcNow.ToUnixTimeSeconds() < deadline)
{
yield return new WaitForSeconds(pollInterval);
if (gameObject == null) yield break; // 页面已销毁
// 仅当持久化的还是同一个 transferId 时才继续等待(用户重新点击/切换设备会清掉)
if (LoadTransferId() != transferId) yield break;
string nowVersion = null;
yield return FetchDeviceFirmwareVersion(r => nowVersion = r);
if (!string.IsNullOrEmpty(nowVersion) && IsVersionGE(nowVersion, targetVersion))
{
rebooted = true;
break;
}
// 期间截止时间可能被重置(用户重新点击升级等),以最新值为准
long currentDeadline = LoadWaitDeadline();
if (currentDeadline > 0 && currentDeadline != deadline) deadline = currentDeadline;
}
if (gameObject == null) yield break; if (gameObject == null) yield break;
// 仅当持久化的还是同一个 transferId 时再继续(用户可能已点过别的)
if (LoadTransferId() != transferId) yield break; if (LoadTransferId() != transferId) yield break;
if (rebooted) ToastUI.Show("100226");
{ // 返回主页transferId 保留,下次进入页面仍能识别为「传输已完成、待重启确认」
// 设备已用新版本上线,更新本地版本并清理状态 UIManager.Instance.OpenMainPage(UIManager.PageName.homePage);
if (DataManager.Instance.selectedDevice != null && !string.IsNullOrEmpty(targetVersion))
{
DataManager.Instance.selectedDevice.firmware_version = targetVersion;
}
ClearTransferId();
HideProgressPanel();
InitOtaUI(); // 重新判断:已是最新 / 又有新版本
}
else
{
// 超时:升级失败,提示并清理 transferId避免下次进入页面再触发
ToastUI.Show("ota_update_failed");
ClearTransferId();
HideProgressPanel();
updateButton.gameObject.SetActive(true);
}
} }
/// <summary> /// <summary>
@ -551,11 +511,12 @@ namespace Kill.UI.Pages
currentTransferId = savedId; currentTransferId = savedId;
currentTransferStatus = savedStatus; currentTransferStatus = savedStatus;
updateButton.gameObject.SetActive(false); updateButton.gameObject.SetActive(false);
// 已经传输完成等待设备重启:直接走轮询分支,不重新订阅 SSE // 已经传输完成等待设备重启:直接清理状态、恢复更新按钮(实际设备升级由下次进入主页/下次 OTA 拉取时确认)
if (savedStatus == "waiting_reboot") if (savedStatus == "waiting_reboot")
{ {
ShowProgressPanelWaitingForDevice(); ClearTransferId();
StartCoroutine(WaitDeviceRebootAndFinish(savedId)); HideProgressPanel();
updateButton.gameObject.SetActive(true);
return; return;
} }
ShowProgressPanel(0); ShowProgressPanel(0);