using Assets.Framework.Tool;
using Assets.MyGame.Scripts.Net;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
///
/// 用户信息面板(设置已分离至 SettingPanel)
///
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 Image img_ShowAvatarK; // 预览头像框(选中即更新)
public Button btn_UseAvatar; // 确认使用按钮
[Header("头像选择")]
public Transform parent_AvatarList;
[Header("头像框选择")]
public Transform parent_AvatarKList;
public Toggle prefab_AvatarItem; // 头像/头像框选项预制体(child0=Image, child2=选中对号)
GameManager gameManager => GameManager.Instance;
private List _avatarToggles = new List();
private List _avatarFrameToggles = new List();
private string _pendingAvatarName; // 选中的待确认头像名
private string _pendingAvatarFrameName; // 选中的待确认头像框名
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();
BuildAvatarFrameList();
// 监听变更
gameManager.OnAvatarChanged += OnAvatarChanged;
gameManager.OnAvatarFrameChanged += OnAvatarFrameChanged;
}
protected override void OnHide()
{
base.OnHide();
gameManager.OnAvatarChanged -= OnAvatarChanged;
gameManager.OnAvatarFrameChanged -= OnAvatarFrameChanged;
// 清理 toggle 列表
_avatarToggles.Clear();
_avatarFrameToggles.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);
// 初始化头像框预览
LoadAvatarFrameImage(img_ShowAvatarK, gameManager.user.BaseInfo.avatarFrame);
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 LoadAvatarFrameImage(Image target, string avatarFrameName)
{
if (target == null) return;
var sprite = gameManager.GetAvatarFrameSprite(avatarFrameName);
if (sprite != null)
target.sprite = sprite;
}
// ==================== 头像列表 ====================
/// 当前装备的头像名(从服务器数据读取)
private string _equippedAvatarName;
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("Avatar");
_equippedAvatarName = gameManager.user.BaseInfo.avatarUrl;
_pendingAvatarName = _equippedAvatarName;
foreach (var sprite in allSprites)
{
var obj = Instantiate(prefab_AvatarItem, parent_AvatarList);
string avatarName = sprite.name;
// child(0) = 头像图片
if (obj.transform.childCount > 0)
{
var img = obj.transform.GetChild(0).GetComponent();
if (img != null) img.sprite = sprite;
}
// child(2) = 装备中对号(只在已装备的头像上显示,不跟随选中状态)
Transform checkMark = obj.transform.childCount > 2 ? obj.transform.GetChild(2) : null;
if (checkMark != null)
checkMark.gameObject.SetActive(avatarName == _equippedAvatarName);
var toggle = obj.GetComponent();
if (toggle == null) continue;
// 加入父对象的 ToggleGroup 实现单选
toggle.group = parent_AvatarList.GetComponent();
// 禁用 Toggle 自带的过渡效果
toggle.transition = Selectable.Transition.None;
// 初始选中已装备的头像
toggle.isOn = (avatarName == _equippedAvatarName);
_avatarToggles.Add(toggle);
toggle.onValueChanged.AddListener(isOn =>
{
if (!isOn) return;
_pendingAvatarName = avatarName;
// 预览头像实时更新
if (img_ShowAvatar != null)
img_ShowAvatar.sprite = sprite;
});
}
}
// ==================== 头像框列表 ====================
/// 当前装备的头像框名(从服务器数据读取)
private string _equippedAvatarFrameName;
private void BuildAvatarFrameList()
{
if (prefab_AvatarItem == null || parent_AvatarKList == null) return;
for (int i = parent_AvatarKList.childCount - 1; i >= 0; i--)
Destroy(parent_AvatarKList.GetChild(i).gameObject);
_avatarFrameToggles.Clear();
gameManager.InitAvatarFrameCache();
var allSprites = Resources.LoadAll("AvatarK");
_equippedAvatarFrameName = gameManager.user.BaseInfo.avatarFrame;
_pendingAvatarFrameName = _equippedAvatarFrameName;
foreach (var sprite in allSprites)
{
var obj = Instantiate(prefab_AvatarItem, parent_AvatarKList);
string frameName = sprite.name;
// child(0) = 头像框图片
if (obj.transform.childCount > 0)
{
var img = obj.transform.GetChild(0).GetComponent();
if (img != null) img.sprite = sprite;
// 头像框可以设置 SetNativeSize 保持比例
//if (img != null) img.SetNativeSize();
}
// child(2) = 装备中对号(只在已装备的头像框上显示)
Transform checkMark = obj.transform.childCount > 2 ? obj.transform.GetChild(2) : null;
if (checkMark != null)
checkMark.gameObject.SetActive(frameName == _equippedAvatarFrameName);
var toggle = obj.GetComponent();
if (toggle == null) continue;
// 加入父对象的 ToggleGroup 实现单选
toggle.group = parent_AvatarKList.GetComponent();
// 禁用 Toggle 自带的过渡效果
toggle.transition = Selectable.Transition.None;
// 初始选中已装备的头像框
toggle.isOn = (frameName == _equippedAvatarFrameName);
_avatarFrameToggles.Add(toggle);
toggle.onValueChanged.AddListener(isOn =>
{
if (!isOn) return;
_pendingAvatarFrameName = frameName;
// 预览头像框实时更新
if (img_ShowAvatarK != null)
img_ShowAvatarK.sprite = sprite;
});
}
}
// ==================== 确认使用 ====================
/// 点击"使用"按钮 → 确认切换装备头像/头像框
private void OnClickUseAvatar()
{
// 优先判断是否有头像更改
bool avatarChanged = !string.IsNullOrEmpty(_pendingAvatarName)
&& _pendingAvatarName != _equippedAvatarName;
// 判断是否有头像框更改
bool frameChanged = !string.IsNullOrEmpty(_pendingAvatarFrameName)
&& _pendingAvatarFrameName != _equippedAvatarFrameName;
if (avatarChanged)
{
LoadAvatarImage(sprite_Avatar, _pendingAvatarName);
gameManager.ApplyAvatar(_pendingAvatarName);
}
if (frameChanged)
{
LoadAvatarFrameImage(img_ShowAvatarK, _pendingAvatarFrameName);
gameManager.ApplyAvatarFrame(_pendingAvatarFrameName);
}
if (!avatarChanged && !frameChanged)
{
Debug.Log("[UserInfoPanel] 未改变头像或头像框");
}
}
// ==================== 变更回调 ====================
/// 头像变更回调(服务器返回后),同步预览和列表对号
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;
_equippedAvatarName = _pendingAvatarName;
// 切换对号:隐藏旧的、显示新的
foreach (var t in _avatarToggles)
{
if (t == null || t.transform.childCount <= 2) continue;
var img = t.transform.GetChild(0).GetComponent();
bool isEquipped = img != null && img.sprite != null && img.sprite.name == _equippedAvatarName;
t.transform.GetChild(2).gameObject.SetActive(isEquipped);
}
}
/// 头像框变更回调(服务器返回后),同步预览和列表对号
private void OnAvatarFrameChanged(Sprite sprite)
{
if (img_ShowAvatarK != null && sprite != null)
img_ShowAvatarK.sprite = sprite;
_equippedAvatarFrameName = _pendingAvatarFrameName;
// 切换对号:隐藏旧的、显示新的
foreach (var t in _avatarFrameToggles)
{
if (t == null || t.transform.childCount <= 2) continue;
var img = t.transform.GetChild(0).GetComponent();
bool isEquipped = img != null && img.sprite != null && img.sprite.name == _equippedAvatarFrameName;
t.transform.GetChild(2).gameObject.SetActive(isEquipped);
}
}
// ==================== 工具 ====================
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);
}
}