“虞渠成” e11d67df32 feat: 为多处UI交互添加防连点重入逻辑
1.  为WiFi配置、固件升级、设备信息页的多个设置页面添加防重复点击逻辑
2.  为定时任务、FOV/镜头/灯光/安全设置、消息页等主页功能添加防连点
3.  新增锁定指令、WiFi配置发送的状态标记避免重复触发
4.  所有页面打开时检查实例状态,避免重复创建页面实例
2026-08-14 08:35:38 +08:00

585 lines
22 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;
using System.Collections.Generic;
using Kill.Bluetooth;
using Kill.Bluetooth.Protocol;
using Kill.Core;
using Kill.Managers;
using Kill.UI.Components;
using UnityEngine;
using UnityEngine.UI;
using Kill.Network;
using System.Threading.Tasks;
namespace Kill.UI.Pages
{
public class DeviceInfoPage : MonoBehaviour
{
/// <summary>
/// 0所有者页面 1分享者页面
/// </summary>
public GameObject[] pages;
bool isOwner = false;
List<Action> initActions;
Managers.DeviceInfo deviceInfo;
public Switch[] fingerprintSwitchs;
Switch fingerprintSwitch;
public Text[] deviceNames;
Text deviceName;
public RGBlightSetting rGBlightSetting;
public Text[] rgbValues;
Text rgbValue;
RGBControl rGBControl;
public LCDSetting lcdSetting;
public ShareDevicePage shareDevicePage;
public DeviceSharedUserPage deviceSharedUserPage;
public AboutDevicePage aboutDevicePage;
string nowUserid;
private void Start()
{
Debug.Log("DeviceInfoPage初始化");
UIManager.Instance.RegisterBackAction(Back);
initActions = new List<Action>();
deviceInfo = DataManager.Instance.selectedDevice;
nowUserid = DataManager.Instance.userInfo.id;
if (nowUserid == deviceInfo.owner_id)
isOwner = true;
else
isOwner = false;
if (isOwner)
{
Debug.Log("打开所有者设置");
pages[0].SetActive(true);
pages[1].SetActive(false);
fingerprintSwitch = fingerprintSwitchs[0];
rgbValue = rgbValues[0];
deviceName = deviceNames[0];
}
else
{
Debug.Log("打开分享者设置");
pages[1].SetActive(true);
pages[0].SetActive(false);
fingerprintSwitch = fingerprintSwitchs[1];
deviceName = deviceNames[1];
rgbValue = rgbValues[1];
}
deviceName.text = deviceInfo.device_name;
initActions.Add(ReadFingerprint);
initActions.Add(ReadLightSettings);
LoadingUI.Show();
InitData();
}
bool isfingerOn = true;
public async void ReadFingerprint()
{
if (DataManager.Instance.hasWifi && !DataManager.Instance.hasBluetooth)
{
// WiFi模式从服务器指纹列表读取
await DataManager.Instance.GetFingerprints();
bool hasFp = false;
foreach (var user in DataManager.Instance.fingerprintUserDatas)
{
if (user.username == nowUserid)
{
hasFp = user.has_fingerprint;
break;
}
}
isfingerOn = hasFp;
initActions.Remove(ReadFingerprint);
fingerprintSwitch.Init(isfingerOn, SetFingerprintSwicth);
InitData();
return;
}
BLECommunicationManager.Instance.QueryUserList((UserListResponse) =>
{
Loom.QueueOnMainThread(() =>
{
// 将蓝牙用户列表同步到本地,供后续上传到服务器使用
DataManager.Instance.fingerprintUserDatas.Clear();
if (UserListResponse.Users != null)
{
foreach (var user in UserListResponse.Users)
{
DataManager.Instance.fingerprintUserDatas.Add(new FingerprintUserData
{
username = user.Username,
fingerprint_id = user.FingerprintId,
has_fingerprint = user.HasFingerprint
});
if (user.Username == nowUserid)
{
isfingerOn = user.HasFingerprint;
}
}
}
initActions.Remove(ReadFingerprint);
fingerprintSwitch.Init(isfingerOn, SetFingerprintSwicth);
InitData();
});
});
}
public void SetFingerprintSwicth(bool isOn)
{
if (DataManager.Instance.hasWifi && !DataManager.Instance.hasBluetooth)
{
// WiFi模式下不能通过WiFi控制指纹开关仅展示状态
ToastUI.Show("100293");
fingerprintSwitch.SetValue(!isOn);
return;
}
LoadingUI.Show();
BLECommunicationManager.Instance.SetFingerprintEnable(nowUserid, isOn, (response) =>
{
Loom.QueueOnMainThread(async () =>
{
if (response.IsSuccess)
{
if (isOn)
SetFingerprint();
else
{
// 禁用指纹成功,同步到服务器
await SyncFingerprintsToServerAsync();
LoadingUI.Hide();
}
}
else
{
fingerprintSwitch.SetValue(!isOn);
LoadingUI.Hide();
}
});
});
}
public GameObject fingerTip;
public void SetFingerprint()
{
BLECommunicationManager.Instance.StartFingerprintRecord(nowUserid, (response) =>
{
Loom.QueueOnMainThread(async () =>
{
if (response.IsSuccess)
{
fingerTip.SetActive(true);
// 录制成功,更新当前用户指纹状态并同步到服务器
UpdateLocalFingerprintState(nowUserid, true);
await SyncFingerprintsToServerAsync();
LoadingUI.Hide();
}
else
{
SetFingerprint();
}
});
});
}
/// <summary>
/// 更新本地 fingerprintUserDatas 中指定用户的指纹状态
/// </summary>
private void UpdateLocalFingerprintState(string username, bool hasFingerprint)
{
var list = DataManager.Instance.fingerprintUserDatas;
var existing = list.Find(u => u.username == username);
if (existing.username != null)
{
existing.has_fingerprint = hasFingerprint;
}
else
{
list.Add(new FingerprintUserData
{
username = username,
fingerprint_id = 0,
has_fingerprint = hasFingerprint
});
}
}
private async Task SyncFingerprintsToServerAsync()
{
if (!DataManager.Instance.hasWifi) return;
await DataManager.Instance.UpdateFingerprintsToServer(
DataManager.Instance.selectedDevice.ble_mac,
DataManager.Instance.fingerprintUserDatas);
}
/// <summary>
/// 读取RGB设置
/// </summary>
private void ReadLightSettings()
{
if (DataManager.Instance.hasWifi && !DataManager.Instance.hasBluetooth)
{
var config = DataManager.Instance.deviceConfig;
this.rGBControl = new RGBControl();
rGBControl.Enable = config?.rgb_enable ?? false;
rGBControl.SetColor(new Color((config?.rgb_red ?? 0) / 255f, (config?.rgb_green ?? 0) / 255f, (config?.rgb_blue ?? 0) / 255f));
rGBControl.Effect = DeviceConfig.ParseServerEnum(config?.rgb_effect, RGBEffectMode.Blinking);
rgbValue.text = GetOnOffValue(rGBControl.Enable);
initActions.Remove(ReadLightSettings);
InitData();
return;
}
// 读取rgb
BLECommunicationManager.Instance.ReadRGBControl((setting) =>
{
Loom.QueueOnMainThread(() =>
{
rGBControl = setting;
rgbValue.text = GetOnOffValue(rGBControl.Enable);
initActions.Remove(ReadLightSettings);
InitData();
});
});
}
public void InitData()
{
if (initActions != null && initActions.Count > 0)
{
initActions[0].Invoke();
}
else
{
LoadingUI.Hide();
}
}
public string GetOnOffValue(bool ison)
{
string value = ison ? LanguageManager.Instance.GetLanguage("100099") : LanguageManager.Instance.GetLanguage("100100");
return value;
}
/// <summary>当前已打开的RGB设置页实例(防连点重入)</summary>
private RGBlightSetting currentRgbSetting;
public void OpenRgbSetting()
{
// 防连点:页面已打开时忽略重复触发
if (currentRgbSetting != null) return;
currentRgbSetting = Instantiate(rGBlightSetting.gameObject, transform).GetComponent<RGBlightSetting>();
currentRgbSetting.gameObject.SetActive(true);
currentRgbSetting.Init(CloseRgbSetting, rGBControl);
}
public void CloseRgbSetting(RGBControl ct)
{
rGBControl = ct;
rgbValue.text = GetOnOffValue(rGBControl.Enable);
UIManager.Instance.RegisterBackAction(Back);
}
/// <summary>当前已打开的LCD设置页实例(防连点重入)</summary>
private LCDSetting currentLcdSetting;
public void OpenLCDSetting()
{
// 防连点:页面已打开时忽略重复触发
if (currentLcdSetting != null) return;
currentLcdSetting = Instantiate(lcdSetting.gameObject, transform).GetComponent<LCDSetting>();
currentLcdSetting.gameObject.SetActive(true);
currentLcdSetting.Init(CloseLCDSetting);
}
public void CloseLCDSetting()
{
UIManager.Instance.RegisterBackAction(Back);
}
public RenamePage renamePage;
/// <summary>当前已打开的重命名页实例(防连点重入)</summary>
private RenamePage currentRenamePage;
public void OpenRenamePage()
{
// 防连点:页面已打开时忽略重复触发
if (currentRenamePage != null) return;
currentRenamePage = Instantiate(renamePage.gameObject, transform).GetComponent<RenamePage>();
currentRenamePage.gameObject.SetActive(true);
currentRenamePage.Init(deviceInfo.device_name, CloseRenamePage);
}
public void CloseRenamePage(string newName)
{
UIManager.Instance.RegisterBackAction(Back);
deviceInfo.device_name = newName;
deviceName.text = newName;
DataManager.Instance.selectedDevice.device_name = newName;
}
public VideoAndSoundSetting videoAndSoundSetting;
/// <summary>当前已打开的音视频设置页实例(防连点重入)</summary>
private VideoAndSoundSetting currentVideoAndSoundSetting;
public void OpenVideoAndSoundSetting()
{
// 防连点:页面已打开时忽略重复触发
if (currentVideoAndSoundSetting != null) return;
currentVideoAndSoundSetting = Instantiate(videoAndSoundSetting.gameObject, transform).GetComponent<VideoAndSoundSetting>();
currentVideoAndSoundSetting.gameObject.SetActive(true);
currentVideoAndSoundSetting.Init(CloseVideoAndSoundSetting);
}
public void CloseVideoAndSoundSetting()
{
UIManager.Instance.RegisterBackAction(Back);
}
public void Back()
{
UIManager.Instance.OpenMainPage(UIManager.PageName.homePage);
}
public GameObject[] restoreSettingsTips;
public void RestoreSettings0()
{
restoreSettingsTips[0].gameObject.SetActive(true);
restoreSettingsTips[1].gameObject.SetActive(false);
restoreSettingsTips[2].gameObject.SetActive(false);
restoreSettingsTips[0].GetComponent<WindowTipCtrl>().Init(RestoreSettings1, null);
}
string password = "";
public void RestoreSettings1()
{
restoreSettingsTips[1].gameObject.SetActive(true);
restoreSettingsTips[0].gameObject.SetActive(false);
restoreSettingsTips[2].gameObject.SetActive(false);
restoreSettingsTips[1].GetComponent<WindowTipCtrl>().Init(CheckPassWord, null);
}
public void CheckPassWord()
{
password = restoreSettingsTips[1].transform.Find("框").GetComponentInChildren<InputField>().text;
if (password == "")
{
return;
}
LoadingUI.Show();
CheckPasswordAsync(password);
}
public void RestoreSettings2()
{
restoreSettingsTips[2].gameObject.SetActive(true);
restoreSettingsTips[0].gameObject.SetActive(false);
restoreSettingsTips[1].gameObject.SetActive(false);
restoreSettingsTips[2].GetComponent<WindowTipCtrl>().Init(ResetDeviceBluetooth, null);
}
/// <summary>
/// 验证密码
/// </summary>
private async void CheckPasswordAsync(string password)
{
try
{
// 构建请求数据
var requestData = new PasswordRequest
{
password = password
};
var response = await NetworkCtrl.Instance.Post<NoDataResponse>("/api/v1/auth/password/verify", requestData);
if (response.Data.code == 200)
{
Debug.Log("密码正确");
RestoreSettings2();
}
else
{
ToastUI.Show("100040");
}
LoadingUI.Hide();
}
catch (Exception ex)
{
ToastUI.Show("100040");
}
}
private async void ResetDeviceAsync()
{
LoadingUI.Show();
restoreSettingsTips[2].gameObject.SetActive(false);
try
{
// 构建请求数据
var requestData = new ResetDeviceRequest
{
device_sn = deviceInfo.ble_mac
};
var response = await NetworkCtrl.Instance.Post<NoDataResponse>("/api/v1/device/reset", requestData);
ResponseCodeHandler.HandleResponse(response,
onSuccess: (data) =>
{
Debug.Log(data.code);
if (data.code == 200)
{
StartCoroutine(BackToHomePage());
}
else
{
ToastUI.Show("100302");
}
LoadingUI.Hide();
},
onError: (code, message) =>
{
LoadingUI.Hide();
ToastUI.Show("100036");
}
);
}
catch (Exception ex)
{
ToastUI.Show("100036");
}
}
private async void ResetDeviceBluetooth()
{
LoadingUI.Show();
if (DataManager.Instance.hasWifi && !DataManager.Instance.hasBluetooth)
{
bool success = await HomePageCtrl.Instance.SendBleCommandByWifiAsync(BLEConstants.CMD_FACTORY_RESET, new byte[] { 0x01 });
if (success)
{
ResetDeviceAsync();
LoadingUI.Hide();
}
else
{
LoadingUI.Hide();
ToastUI.Show("100302");
}
return;
}
else if (DataManager.Instance.hasBluetooth)
{
BLECommunicationManager.Instance.FactoryReset((success) =>
{
Loom.QueueOnMainThread(() =>
{
if (success)
{
BluetoothManager.Instance.ChangeAimMac("");
BluetoothManager.Instance.Disconnect();
ResetDeviceAsync();
LoadingUI.Hide();
}
else
{
LoadingUI.Hide();
ToastUI.Show("100302");
}
});
});
}
}
/// <summary>当前已打开的分享设备页实例(防连点重入)</summary>
private ShareDevicePage currentShareDevicePage;
public void OpenShareDevicePage()
{
// 防连点:页面已打开时忽略重复触发
if (currentShareDevicePage != null) return;
currentShareDevicePage = Instantiate(shareDevicePage.gameObject, transform).GetComponent<ShareDevicePage>();
currentShareDevicePage.gameObject.SetActive(true);
}
/// <summary>当前已打开的共享用户页实例(防连点重入)</summary>
private DeviceSharedUserPage currentDeviceSharedUserPage;
public void OpenDeviceSharedUserPage()
{
// 防连点:页面已打开时忽略重复触发
if (currentDeviceSharedUserPage != null) return;
currentDeviceSharedUserPage = Instantiate(deviceSharedUserPage.gameObject, transform).GetComponent<DeviceSharedUserPage>();
currentDeviceSharedUserPage.gameObject.SetActive(true);
}
public void CancelShareBySharedUser()
{
CancelShareAsyncBySharedUser();
}
public async Task CancelShareAsyncBySharedUser()
{
string targetUserId = DataManager.Instance.userInfo.id;
// 调用后端接口共享设备
LoadingUI.Show();
var requestData = new ShareDeviceRequest
{
device_sn = DataManager.Instance.selectedDevice.ble_mac,
target_user_id = targetUserId,
owner_id = DataManager.Instance.selectedDevice.owner_id
};
try
{
var response = await NetworkCtrl.Instance.Post<NoDataResponse>("/api/v1/device/unshare", requestData);
ResponseCodeHandler.HandleResponse(response,
onSuccess: (data) =>
{
Debug.Log("取消设备共享成功");
ToastUI.Show("100206");
if (BluetoothManager.Instance.IsConnected)
{
BLECommunicationManager.Instance.UnregisterUser(targetUserId, (unregisterSuccess) =>
{
Loom.QueueOnMainThread(() =>
{
if (unregisterSuccess.IsSuccess)
{
BluetoothManager.Instance.Disconnect();
StartCoroutine(BackToHomePage());
}
else
{
Debug.LogError("取消设备共享成功,但蓝牙用户注销失败");
StartCoroutine(BackToHomePage());
}
});
});
}
else
{
StartCoroutine(BackToHomePage());
}
},
onError: (code, msg) =>
{
Debug.LogError($"取消设备共享失败: {code} - {msg}");
ToastUI.ShowText(code.ToString());
}
);
}
catch (Exception ex)
{
LoadingUI.Hide();
Debug.LogError("取消设备共享失败: " + ex.Message);
}
}
/// <summary>当前已打开的关于设备页实例(防连点重入)</summary>
private AboutDevicePage currentAboutDevicePage;
public void OpenAboutDevicePage()
{
// 防连点:页面已打开时忽略重复触发
if (currentAboutDevicePage != null) return;
currentAboutDevicePage = Instantiate(aboutDevicePage.gameObject, transform).GetComponent<AboutDevicePage>();
currentAboutDevicePage.gameObject.SetActive(true);
}
public IEnumerator BackToHomePage()
{
LoadingUI.Show();
yield return new WaitForSeconds(2);
LoadingUI.ForceHide();
UIManager.Instance.OpenMainPage(UIManager.PageName.homePage);
}
}
}