239 lines
8.6 KiB
C#
239 lines
8.6 KiB
C#
using Assets.Framework.Tool;
|
||
using Assets.MyGame.Scripts.Net;
|
||
using System.Collections.Generic;
|
||
using TMPro;
|
||
using UnityEngine;
|
||
using UnityEngine.UI;
|
||
|
||
/// <summary>
|
||
/// 用户信息面板(设置已分离至 SettingPanel)
|
||
/// </summary>
|
||
public class UserInfoPanel : SubUIBase
|
||
{
|
||
[Header("基础信息")]
|
||
public Image sprite_Avatar; // 显示已保存的用户头像(点使用后更新)
|
||
public Button btn_ChangeUser;
|
||
public TextMeshProUGUI tMPText_Name;
|
||
public TextMeshProUGUI tMPText_ID;
|
||
public TextMeshProUGUI tMPText_UserNumber;
|
||
public TextMeshProUGUI tMPText_LabelQM;
|
||
public TextMeshProUGUI tMPText_IP;
|
||
public TextMeshProUGUI tMPText_VIPLeave;
|
||
public TextMeshProUGUI tMPText_PhoneNumber;
|
||
|
||
[Header("头像选择")]
|
||
public Image img_ShowAvatar; // 预览头像(选中即更新)
|
||
public Toggle prefab_AvatarItem; // 头像选项预制体(child0=Image, child2=选中对号)
|
||
public Button btn_UseAvatar; // 确认使用按钮
|
||
public Transform parent_AvatarList;
|
||
|
||
GameManager gameManager => GameManager.Instance;
|
||
private List<Toggle> _avatarToggles = new List<Toggle>();
|
||
private string _pendingAvatarName; // 选中的待确认头像名
|
||
|
||
public override void Awake()
|
||
{
|
||
base.Awake();
|
||
btn_ChangeUser.onClick.AddListener(() =>
|
||
{
|
||
gameManager.Logout();
|
||
});
|
||
btn_UseAvatar.onClick.AddListener(OnClickUseAvatar);
|
||
}
|
||
|
||
protected override void OnShow(object args = null)
|
||
{
|
||
base.OnShow(args);
|
||
InitInformation();
|
||
BuildAvatarList();
|
||
// 监听头像变更
|
||
gameManager.OnAvatarChanged += OnAvatarChanged;
|
||
}
|
||
|
||
protected override void OnHide()
|
||
{
|
||
base.OnHide();
|
||
gameManager.OnAvatarChanged -= OnAvatarChanged;
|
||
// 清理 toggle 列表
|
||
_avatarToggles.Clear();
|
||
}
|
||
|
||
// ==================== 基础信息 ====================
|
||
|
||
private void InitInformation()
|
||
{
|
||
tMPText_Name.color = gameManager.user.BaseInfo.isRedName ? Color.red : Color.white;
|
||
|
||
// 初始化两个头像(正式头像 和 预览头像)都为当前已保存的头像
|
||
LoadAvatarImage(sprite_Avatar, gameManager.user.BaseInfo.avatarUrl);
|
||
LoadAvatarImage(img_ShowAvatar, gameManager.user.BaseInfo.avatarUrl);
|
||
|
||
tMPText_Name.text = gameManager.user.BaseInfo.userName;
|
||
tMPText_ID.text = gameManager.user.BaseInfo.number;
|
||
tMPText_UserNumber.text = gameManager.user.BaseInfo.mobile;
|
||
tMPText_LabelQM.text = PlayerPrefs.GetString("QM", "我比较懒,什么都没写");
|
||
tMPText_IP.text = gameManager.user.@static.lastLoginIp;
|
||
tMPText_VIPLeave.text = gameManager.user.assets.vipLevel.ToString();
|
||
tMPText_PhoneNumber.text = MaskPhone(gameManager.user.BaseInfo.mobile);
|
||
}
|
||
|
||
// ==================== 头像加载 ====================
|
||
|
||
private void LoadAvatarImage(Image target, string avatarUrl)
|
||
{
|
||
if (target == null) return;
|
||
|
||
var sprite = gameManager.GetAvatarSprite(avatarUrl);
|
||
if (sprite != null)
|
||
{
|
||
target.sprite = sprite;
|
||
}
|
||
else if (!int.TryParse(avatarUrl, out _))
|
||
{
|
||
WebTool.DownImage(avatarUrl, (texture) =>
|
||
{
|
||
if (texture != null && target != null)
|
||
target.sprite = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), Vector2.one * 0.5f);
|
||
});
|
||
}
|
||
}
|
||
|
||
// ==================== 头像列表 ====================
|
||
|
||
private void BuildAvatarList()
|
||
{
|
||
if (prefab_AvatarItem == null || parent_AvatarList == null) return;
|
||
|
||
// 清空旧列表
|
||
for (int i = parent_AvatarList.childCount - 1; i >= 0; i--)
|
||
Destroy(parent_AvatarList.GetChild(i).gameObject);
|
||
_avatarToggles.Clear();
|
||
|
||
// 获取所有头像
|
||
gameManager.InitAvatarCache();
|
||
var allSprites = Resources.LoadAll<Sprite>("Avatar");
|
||
string currentAvatar = gameManager.user.BaseInfo.avatarUrl;
|
||
|
||
foreach (var sprite in allSprites)
|
||
{
|
||
var obj = Instantiate(prefab_AvatarItem, parent_AvatarList);
|
||
|
||
// 1. 设置列表项的小头像 (child0 = Image)
|
||
if (obj.transform.childCount > 0)
|
||
{
|
||
var img = obj.transform.GetChild(0).GetComponent<Image>();
|
||
if (img != null) img.sprite = sprite;
|
||
}
|
||
|
||
// 2. 获取对号图标 (child2)
|
||
Transform checkMark = null;
|
||
if (obj.transform.childCount > 2)
|
||
{
|
||
checkMark = obj.transform.GetChild(2);
|
||
// 初始隐藏
|
||
checkMark.gameObject.SetActive(false);
|
||
}
|
||
|
||
var toggle = obj.GetComponent<Toggle>();
|
||
if (toggle != null)
|
||
{
|
||
// 关键:禁用 Toggle 自动过渡,防止自动显示 Graphic
|
||
toggle.transition = Selectable.Transition.None;
|
||
|
||
_avatarToggles.Add(toggle);
|
||
string avatarName = sprite.name;
|
||
|
||
// 判断是否是当前已装备的头像
|
||
bool isCurrent = (avatarName == currentAvatar);
|
||
|
||
// 设置选中状态
|
||
toggle.isOn = isCurrent;
|
||
|
||
// 【修改点】只要 isOn 为 true,就显示对号
|
||
// 这里的逻辑是:如果是当前用户装备的头像,打开面板时默认是选中的,且有对号
|
||
if (isCurrent)
|
||
{
|
||
if (checkMark != null) checkMark.gameObject.SetActive(true);
|
||
_pendingAvatarName = avatarName;
|
||
}
|
||
|
||
// 监听点击事件
|
||
toggle.onValueChanged.AddListener(isOn =>
|
||
{
|
||
// 【修改点】对号显示完全跟随 isOn 状态
|
||
// 当点击这个 Toggle 变成 true 时,显示对号;变成 false 时,隐藏对号
|
||
if (checkMark != null)
|
||
{
|
||
checkMark.gameObject.SetActive(isOn);
|
||
}
|
||
|
||
if (isOn)
|
||
{
|
||
_pendingAvatarName = avatarName;
|
||
|
||
// 实时更新预览大图
|
||
if (img_ShowAvatar != null)
|
||
{
|
||
img_ShowAvatar.sprite = sprite;
|
||
}
|
||
|
||
// 手动单选逻辑:关闭其他 Toggle
|
||
foreach (var t in _avatarToggles)
|
||
{
|
||
if (t == toggle) continue;
|
||
t.SetIsOnWithoutNotify(false);
|
||
|
||
// 【修改点】强制隐藏其他 Toggle 的对号
|
||
// 虽然上面 SetIsOnWithoutNotify(false) 会触发各自的 onValueChanged=false,
|
||
// 但为了保险起见,或者防止逻辑冲突,这里显式隐藏一次。
|
||
var otherMark = t.transform.childCount > 2 ? t.transform.GetChild(2) : null;
|
||
if (otherMark != null) otherMark.gameObject.SetActive(false);
|
||
}
|
||
}
|
||
});
|
||
}
|
||
}
|
||
}
|
||
|
||
/// <summary>点击“使用”按钮 → 确认数据,更新主头像</summary>
|
||
private void OnClickUseAvatar()
|
||
{
|
||
if (string.IsNullOrEmpty(_pendingAvatarName))
|
||
{
|
||
Debug.Log("[UserInfoPanel] 未选中头像");
|
||
return;
|
||
}
|
||
|
||
// 1. 更新正式用户数据头像
|
||
LoadAvatarImage(sprite_Avatar, _pendingAvatarName);
|
||
|
||
// 2. 上传到服务器/更新本地缓存
|
||
gameManager.ApplyAvatar(_pendingAvatarName);
|
||
|
||
// 注意:这里不再需要遍历去更新对号了,因为对号在点击 Toggle 时已经跟着动了
|
||
// 点“使用”只是把当前的预览状态保存下来。
|
||
}
|
||
|
||
/// <summary>头像变更回调(网络返回后)</summary>
|
||
private void OnAvatarChanged(Sprite sprite)
|
||
{
|
||
if (sprite_Avatar != null && sprite != null)
|
||
sprite_Avatar.sprite = sprite;
|
||
|
||
if (img_ShowAvatar != null && sprite != null)
|
||
img_ShowAvatar.sprite = sprite;
|
||
}
|
||
|
||
// ==================== 工具 ====================
|
||
|
||
public static string MaskPhone(string phone)
|
||
{
|
||
if (string.IsNullOrEmpty(phone) || phone.Length <= 6)
|
||
return phone;
|
||
int prefix = 3;
|
||
int suffix = 3;
|
||
int maskCount = phone.Length - prefix - suffix;
|
||
return phone.Substring(0, prefix) + new string('*', maskCount) + phone.Substring(phone.Length - suffix);
|
||
}
|
||
}
|