本次提交包含以下核心更新: 1. 新增设备置顶功能,支持将设备在列表中优先展示 2. 实现设备重命名、分享、取消共享功能 3. 优化首页设备列表滑动交互,重构设备项UI菜单逻辑 4. 新增is_top设备字段并完善设备列表排序逻辑 5. 调整部分UI布局与服务器接口地址 6. 补充多语言文案与新增提示文本 7. 修复绑定设备错误提示适配逻辑
397 lines
17 KiB
C#
397 lines
17 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Threading.Tasks;
|
||
using Kill.Managers;
|
||
using Kill.Network;
|
||
using Kill.UI.Components;
|
||
using Kill.Bluetooth;
|
||
using Kill.Core;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
namespace Kill.UI.Pages
|
||
{
|
||
public class HomePageDevicePage : MonoBehaviour
|
||
{
|
||
public GameObject devicePrefab;
|
||
public GameObject typePrefab;
|
||
private string[] typeKey = new string[] { "100148", "100149" };
|
||
private string[] typeStr=new string[2];
|
||
public Transform deviceParent;
|
||
private List<GameObject> deviceList;
|
||
private List<GameObject> typeList;
|
||
public DeviceInfo lastSelectedDevice;
|
||
public DeviceInfo selectedDevice;
|
||
public Text selectedDeviceName;
|
||
public GameObject renamePagePrefab;
|
||
public ShareDevicePage shareDevicePagePrefab;
|
||
/// <summary>当前已打开的重命名页实例(防连点重入)</summary>
|
||
private RenamePage currentRenamePage;
|
||
/// <summary>当前已打开的分享页实例(防连点重入)</summary>
|
||
private ShareDevicePage currentShareDevicePage;
|
||
public void InitDeviceList(List<DeviceInfo> ownedDevices, List<DeviceInfo> sharedDevices, DeviceInfo selectedDevice)
|
||
{
|
||
typeStr[0]=LanguageManager.Instance.GetLanguage(typeKey[0]);
|
||
typeStr[1]=LanguageManager.Instance.GetLanguage(typeKey[1]);
|
||
lastSelectedDevice = selectedDevice;
|
||
this.selectedDevice = selectedDevice;
|
||
devicePrefab.SetActive(false);
|
||
typePrefab.SetActive(false);
|
||
if (deviceList != null && deviceList.Count > 0)
|
||
{
|
||
foreach (var item in deviceList)
|
||
{
|
||
Destroy(item);
|
||
}
|
||
deviceList.Clear();
|
||
}
|
||
if (typeList != null && typeList.Count > 0)
|
||
{
|
||
foreach (var item in typeList)
|
||
{
|
||
Destroy(item);
|
||
}
|
||
typeList.Clear();
|
||
}
|
||
|
||
deviceList = new List<GameObject>();
|
||
typeList=new List<GameObject>();
|
||
if(ownedDevices!=null&&ownedDevices.Count>0)
|
||
{
|
||
Text type=Instantiate(typePrefab, deviceParent).GetComponent<Text>();
|
||
type.text=typeStr[0].Replace("{0}",ownedDevices.Count.ToString());
|
||
type.gameObject.SetActive(true);
|
||
typeList.Add(type.gameObject);
|
||
}
|
||
foreach (var device in ownedDevices)
|
||
{
|
||
if (string.IsNullOrEmpty(device.ble_mac))
|
||
{
|
||
device.ble_mac=device.device_sn;
|
||
}
|
||
|
||
var deviceItem = Instantiate(devicePrefab, deviceParent);
|
||
deviceItem.SetActive(true);
|
||
deviceItem.GetComponent<HomePageDeviceItem>().InitDeviceItem(device,true);
|
||
BindMenuButtons(deviceItem.GetComponent<HomePageDeviceItem>());
|
||
deviceList.Add(deviceItem);
|
||
deviceItem.gameObject.SetActive(true);
|
||
deviceItem.GetComponent<Button>().onClick.AddListener(() =>
|
||
{
|
||
OnClickDeviceItem(deviceItem);
|
||
});
|
||
}
|
||
if(sharedDevices!=null&&sharedDevices.Count>0)
|
||
{
|
||
|
||
Text type=Instantiate(typePrefab, deviceParent).GetComponent<Text>();
|
||
type.text=typeStr[1].Replace("{0}",sharedDevices.Count.ToString());
|
||
type.gameObject.SetActive(true);
|
||
typeList.Add(type.gameObject);
|
||
}
|
||
foreach (var device in sharedDevices)
|
||
{
|
||
if (string.IsNullOrEmpty(device.ble_mac))
|
||
{
|
||
device.ble_mac=device.device_sn;
|
||
}
|
||
var deviceItem = Instantiate(devicePrefab, deviceParent);
|
||
deviceItem.SetActive(true);
|
||
deviceItem.GetComponent<HomePageDeviceItem>().InitDeviceItem(device,false);
|
||
BindMenuButtons(deviceItem.GetComponent<HomePageDeviceItem>());
|
||
deviceList.Add(deviceItem);
|
||
deviceItem.gameObject.SetActive(true);
|
||
deviceItem.GetComponent<Button>().onClick.AddListener(() =>
|
||
{
|
||
OnClickDeviceItem(deviceItem);
|
||
});
|
||
}
|
||
// 解析最终选中的设备:优先保持原选中;原选中设备不存在时,默认选中置顶设备;无置顶则选第一个设备
|
||
DeviceInfo effectiveSelected = null;
|
||
if (selectedDevice != null)
|
||
{
|
||
foreach (var deviceItem in deviceList)
|
||
{
|
||
if (deviceItem.GetComponent<HomePageDeviceItem>().deviceInfo.ble_mac == selectedDevice.ble_mac)
|
||
{
|
||
effectiveSelected = selectedDevice;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (effectiveSelected == null)
|
||
{
|
||
foreach (var deviceItem in deviceList)
|
||
{
|
||
if (deviceItem.GetComponent<HomePageDeviceItem>().deviceInfo.is_top)
|
||
{
|
||
effectiveSelected = deviceItem.GetComponent<HomePageDeviceItem>().deviceInfo;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
if (effectiveSelected == null && deviceList.Count > 0)
|
||
{
|
||
effectiveSelected = deviceList[0].GetComponent<HomePageDeviceItem>().deviceInfo;
|
||
}
|
||
|
||
if (effectiveSelected != null)
|
||
{
|
||
// 选中设备发生回退(原选中不存在或无选中)时,同步选中信息并持久化
|
||
if (selectedDevice == null || selectedDevice.ble_mac != effectiveSelected.ble_mac)
|
||
{
|
||
lastSelectedDevice = effectiveSelected;
|
||
DataManager.Instance.selectedDevice = effectiveSelected;
|
||
DataManager.Instance.SavaSelectedDeviceMac(effectiveSelected.ble_mac);
|
||
var ctrl = HomePageCtrl.Instance;
|
||
if (ctrl != null)
|
||
{
|
||
ctrl.selectedDevice = effectiveSelected;
|
||
if (ctrl.selectDeviceButton != null)
|
||
ctrl.selectDeviceButton.GetComponentInChildren<Text>().text = effectiveSelected.device_name;
|
||
}
|
||
}
|
||
this.selectedDevice = effectiveSelected;
|
||
selectedDeviceName.text = effectiveSelected.device_name;
|
||
|
||
foreach (var deviceItem in deviceList)
|
||
{
|
||
bool isSelected = deviceItem.GetComponent<HomePageDeviceItem>().deviceInfo.ble_mac == effectiveSelected.ble_mac;
|
||
deviceItem.GetComponent<HomePageDeviceItem>().SetSelectedState(isSelected);
|
||
if (isSelected)
|
||
{
|
||
Debug.Log("选中设备:" + deviceItem.GetComponent<HomePageDeviceItem>().deviceInfo.ble_mac);
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
selectedDeviceName.text = "";
|
||
}
|
||
}
|
||
|
||
public void OnClickDeviceItem(GameObject deviceItem)
|
||
{
|
||
foreach (var item in deviceList)
|
||
{
|
||
item.GetComponent<HomePageDeviceItem>().SetSelectedState(item == deviceItem);
|
||
}
|
||
selectedDevice = deviceItem.GetComponent<HomePageDeviceItem>().deviceInfo;
|
||
selectedDeviceName.text=selectedDevice.device_name;
|
||
}
|
||
public void AddNewDevice()
|
||
{
|
||
UIManager.Instance.OpenPage(UIManager.PageName.connectDevicePage);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 绑定菜单按钮事件(0=重命名 1=分享 2=删除 3=置顶 4=取消置顶)
|
||
/// </summary>
|
||
private void BindMenuButtons(HomePageDeviceItem item)
|
||
{
|
||
if (item.menuButtons == null || item.menuButtons.Length < 5) return;
|
||
item.menuButtons[0].onClick.AddListener(() => OpenRenamePage(item));
|
||
item.menuButtons[1].onClick.AddListener(() => OpenShareDevicePage(item));
|
||
item.menuButtons[2].onClick.AddListener(() => CancelShareBySharedUser(item.deviceInfo.ble_mac));
|
||
item.menuButtons[3].onClick.AddListener(() => ToggleTop(item, true));
|
||
item.menuButtons[4].onClick.AddListener(() => ToggleTop(item, false));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 打开设备分享页面
|
||
/// </summary>
|
||
public void OpenShareDevicePage(HomePageDeviceItem item)
|
||
{
|
||
// 防连点:页面已打开时忽略重复触发
|
||
if (shareDevicePagePrefab == null || item == null || item.deviceInfo == null) return;
|
||
if (currentShareDevicePage != null) return;
|
||
currentShareDevicePage = Instantiate(shareDevicePagePrefab, transform).GetComponent<ShareDevicePage>();
|
||
currentShareDevicePage.gameObject.SetActive(true);
|
||
// 关闭分享页时恢复设备列表页的返回事件
|
||
currentShareDevicePage.Init(item.deviceInfo.ble_mac, () => UIManager.Instance.RegisterBackAction(ClosePage));
|
||
}
|
||
|
||
/// <summary>
|
||
/// 打开设备重命名页面
|
||
/// </summary>
|
||
public void OpenRenamePage(HomePageDeviceItem item)
|
||
{
|
||
// 防连点:页面已打开时忽略重复触发
|
||
if (renamePagePrefab == null || item == null || item.deviceInfo == null) return;
|
||
if (currentRenamePage != null) return;
|
||
currentRenamePage = Instantiate(renamePagePrefab, transform).GetComponent<RenamePage>();
|
||
currentRenamePage.gameObject.SetActive(true);
|
||
currentRenamePage.Init(item.deviceInfo.device_name, (newName) => CloseRenamePage(item, newName), 0, item.deviceInfo.ble_mac);
|
||
}
|
||
|
||
/// <summary>
|
||
/// 重命名成功回调:更新本地名称并刷新UI
|
||
/// </summary>
|
||
public void CloseRenamePage(HomePageDeviceItem item, string newName)
|
||
{
|
||
currentRenamePage = null;
|
||
if (item == null || item.deviceInfo == null) return;
|
||
item.deviceInfo.device_name = newName;
|
||
if (item.deviceNameText != null) item.deviceNameText.text = newName;
|
||
// 重命名的是当前选中设备时,同步选中信息
|
||
if (selectedDevice != null && selectedDevice.ble_mac == item.deviceInfo.ble_mac)
|
||
{
|
||
selectedDevice.device_name = newName;
|
||
if (selectedDeviceName != null) selectedDeviceName.text = newName;
|
||
if (DataManager.Instance.selectedDevice != null &&
|
||
DataManager.Instance.selectedDevice.ble_mac == item.deviceInfo.ble_mac)
|
||
{
|
||
DataManager.Instance.selectedDevice.device_name = newName;
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 置顶/取消置顶:调用 /api/v1/device/top,成功后重新获取设备列表并刷新
|
||
/// 每种类型仅一个置顶设备,冲突置顶由后端自动处理
|
||
/// </summary>
|
||
public async void ToggleTop(HomePageDeviceItem item, bool isTop)
|
||
{
|
||
if (item == null || item.deviceInfo == null) return;
|
||
string mac = item.deviceInfo.ble_mac;
|
||
if (string.IsNullOrEmpty(mac))
|
||
{
|
||
Debug.LogError("[HomePageDevicePage] 置顶失败: 设备MAC为空");
|
||
return;
|
||
}
|
||
|
||
LoadingUI.Show();
|
||
try
|
||
{
|
||
var requestData = new { ble_mac = mac, is_top = isTop };
|
||
var response = await NetworkCtrl.Instance.Put<NoDataResponse>("/api/v1/device/top", requestData);
|
||
LoadingUI.Hide();
|
||
ResponseCodeHandler.HandleResponse(response,
|
||
onSuccess: async (data) =>
|
||
{
|
||
// 后端会自动处理同类型冲突置顶,重新获取设备列表刷新
|
||
var ctrl = HomePageCtrl.Instance;
|
||
if (ctrl == null) return;
|
||
await ctrl.FetchDeviceList();
|
||
ctrl.selectDevicePage.GetComponent<HomePageDevicePage>()
|
||
.InitDeviceList(ctrl.OwnedDevices, ctrl.SharedDevices, ctrl.selectedDevice);
|
||
});
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LoadingUI.Hide();
|
||
Debug.LogError($"[HomePageDevicePage] 置顶设置异常: {ex.Message}");
|
||
}
|
||
}
|
||
public void ClosePage()
|
||
{
|
||
// 设备可能在列表页被重命名,关闭时刷新主页显示的当前设备名
|
||
if (selectedDevice != null)
|
||
{
|
||
var ctrl = HomePageCtrl.Instance;
|
||
if (ctrl != null && ctrl.selectedDevice != null &&
|
||
ctrl.selectedDevice.ble_mac == selectedDevice.ble_mac)
|
||
{
|
||
ctrl.selectedDevice.device_name = selectedDevice.device_name;
|
||
if (ctrl.selectDeviceButton != null)
|
||
ctrl.selectDeviceButton.GetComponentInChildren<Text>().text = selectedDevice.device_name;
|
||
}
|
||
if (DataManager.Instance.selectedDevice != null &&
|
||
DataManager.Instance.selectedDevice.ble_mac == selectedDevice.ble_mac)
|
||
{
|
||
DataManager.Instance.selectedDevice.device_name = selectedDevice.device_name;
|
||
}
|
||
}
|
||
if(lastSelectedDevice==selectedDevice)
|
||
{
|
||
gameObject.SetActive(false);
|
||
}
|
||
else
|
||
{
|
||
DataManager.Instance.SavaSelectedDeviceMac(selectedDevice.ble_mac);
|
||
UIManager.Instance.OpenPage(UIManager.PageName.homePage,null,true);
|
||
}
|
||
}
|
||
string cancelShareDeviceMac="";
|
||
public WindowTipCtrl cancelShareTip;
|
||
public void CancelShareBySharedUser(string mac)
|
||
{
|
||
cancelShareDeviceMac=mac;
|
||
cancelShareTip.Init(()=>CancelShareAsyncBySharedUser(),()=>{
|
||
cancelShareTip.gameObject.SetActive(false);
|
||
});
|
||
cancelShareTip.gameObject.SetActive(true);
|
||
}
|
||
public async Task CancelShareAsyncBySharedUser()
|
||
{
|
||
cancelShareTip.gameObject.SetActive(false);
|
||
string targetUserId = DataManager.Instance.userInfo.id;
|
||
|
||
// 调用后端接口共享设备
|
||
LoadingUI.Show();
|
||
|
||
var requestData = new ShareDeviceRequest
|
||
{
|
||
device_sn = cancelShareDeviceMac,
|
||
target_user_id = targetUserId,
|
||
owner_id = "-1"
|
||
};
|
||
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}");
|
||
LoadingUI.Hide();
|
||
ToastUI.ShowText(code.ToString());
|
||
}
|
||
);
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
LoadingUI.Hide();
|
||
Debug.LogError("取消设备共享失败: " + ex.Message);
|
||
}
|
||
}
|
||
public IEnumerator BackToHomePage()
|
||
{
|
||
LoadingUI.Show();
|
||
yield return new WaitForSeconds(2);
|
||
LoadingUI.ForceHide();
|
||
UIManager.Instance.OpenMainPage(UIManager.PageName.homePage);
|
||
}
|
||
}
|
||
|
||
}
|