using Assets.Framework.Tool; using Assets.MyGame.Scripts.Net; using Assets.MyGame.Scripts.Net.APIRequest.Params; using System.Collections.Generic; using TMPro; using UnityEngine; using UnityEngine.UI; /// /// 用户信息面板(设置已分离至 SettingPanel) /// public class UserInfoPanel : SubUIBase { public Toggle toggle_BaseUserInfo; //打开默认打开基础信息页面 [Header("基础信息")] public Image sprite_Avatar; // 显示已保存的用户头像(点使用后更新) public Image sprite_AvatarK; // 显示已保存的用户头像框(点使用后更新) public Button btn_ChangeUser; public TextMeshProUGUI tMPText_Name; public TextMeshProUGUI tMPText_ID; public TextMeshProUGUI tMPText_UserNumber; public TextMeshProUGUI tMPText_IP; public TextMeshProUGUI tMPText_VIPLeave; public TextMeshProUGUI tMPText_PhoneNumber; public TextMeshProUGUI tMPText_UserLevel; //这里显示的是当前等级 显示 LV.N public TextMeshProUGUI tMPText_Level; //这里显示的是n级奖励 n是下方next和up翻到的指定等级 public Slider slider_UserLevel; //经验进度条 public BackPackPropItem backPackPropItemPrefab; //奖励预制体 这里是预览next或者up到指定等级的奖励 public Transform backPackPropItemParent;//奖励预制体的父对象 public Button btn_LevelNext; //翻到下一级奖励 public Button btn_LevelUp; //翻到上一级奖励 [Header("换绑手机")] public TextMeshProUGUI tMPText_OldPhoneNumber; public TMP_InputField tMPText_NewPhoneNumber; public TMP_InputField tMPText_NewPhoneNumberQueRen; public TMP_InputField tMPText_YZM; public Button btn_GetYZM; //先不写获取验证码 public Button btn_ChangePhoneNumber; [Header("改个性签名")] public TMP_InputField tMPText_GeXingQianName; public Button btn_Change; [Header("改名")] public TMP_InputField tMPText_NewName; public Button btn_ChangeName; [Header("修改密码")] public TextMeshProUGUI tMPText_PhoneNumberXGMM; public TMP_InputField tMPText_NewPassword; public TMP_InputField tMPText_NewPasswordQueRen; public TMP_InputField tMPText_YZMXGMM; public Button btn_GetYZMXGMM; //先不写获取验证码 public Button btn_ChangePassword; [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); // 换绑手机 btn_ChangePhoneNumber.onClick.AddListener(OnClickChangePhone); // 改名 btn_ChangeName.onClick.AddListener(OnClickChangeName); // 修改密码 btn_ChangePassword.onClick.AddListener(OnClickChangePassword); // 改个性签名 btn_Change.onClick.AddListener(OnClickSaveSignature); } protected override void OnShow(object args = null) { base.OnShow(args); toggle_BaseUserInfo.isOn = true; 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); LoadAvatarFrameImage(sprite_AvatarK, 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; // 个性签名输入框 if (tMPText_GeXingQianName != null) tMPText_GeXingQianName.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); // 换绑手机 & 修改密码页面显示旧手机号 if (tMPText_OldPhoneNumber != null) tMPText_OldPhoneNumber.text = MaskPhone(gameManager.user.BaseInfo.mobile); if (tMPText_PhoneNumberXGMM != null) tMPText_PhoneNumberXGMM.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); LoadAvatarImage(sprite_Avatar, _pendingAvatarName); gameManager.ApplyAvatar(_pendingAvatarName); } if (frameChanged) { LoadAvatarFrameImage(img_ShowAvatarK, _pendingAvatarFrameName); LoadAvatarFrameImage(sprite_AvatarK, _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); } } // ==================== 换绑手机 ==================== private void OnClickChangePhone() { string oldPhone = gameManager.user.BaseInfo.mobile; string newPhone = tMPText_NewPhoneNumber?.text?.Trim(); string newPhoneConfirm = tMPText_NewPhoneNumberQueRen?.text?.Trim(); string code = tMPText_YZM?.text?.Trim(); if (string.IsNullOrEmpty(newPhone)) { UIManager.Instance.ShowBoardError("请输入新手机号"); return; } if (newPhone != newPhoneConfirm) { UIManager.Instance.ShowBoardError("两次输入的新手机号不一致"); return; } if (string.IsNullOrEmpty(code)) { UIManager.Instance.ShowBoardError("请输入验证码"); return; } APIRequestList.BindMobile(newPhone, code, (result) => { UIManager.Instance.ShowBoardError("手机号换绑成功"); // 刷新本地数据 gameManager.user.BaseInfo.mobile = newPhone; tMPText_OldPhoneNumber.text = MaskPhone(newPhone); tMPText_PhoneNumber.text = MaskPhone(newPhone); tMPText_NewPhoneNumber.text = ""; tMPText_NewPhoneNumberQueRen.text = ""; tMPText_YZM.text = ""; }); } private void OnClickChangeName() { // 检查是否有改名卡 var props = gameManager.user.props; bool hasNameCard = false; if (props != null) { foreach (var p in props) { if (p.count > 0 && (PropEnum)p.type == PropEnum.改名卡) { hasNameCard = true; break; } } } if (!hasNameCard) { UIManager.Instance.ShowBoardError("没有改名卡"); return; } string newName = tMPText_NewName?.text?.Trim(); if (string.IsNullOrEmpty(newName)) { UIManager.Instance.ShowBoardError("请输入新名字"); return; } APIRequestList.UpdateUserName(newName, (result) => { UIManager.Instance.ShowBoardError("改名成功"); gameManager.user.BaseInfo.userName = newName; tMPText_Name.text = newName; tMPText_NewName.text = ""; gameManager.UpdataUserData(gameManager.user); }); } // ==================== 修改密码 ==================== private void OnClickChangePassword() { string mobile = gameManager.user.BaseInfo.mobile; string newPwd = tMPText_NewPassword?.text?.Trim(); string newPwdConfirm = tMPText_NewPasswordQueRen?.text?.Trim(); string code = tMPText_YZMXGMM?.text?.Trim(); if (string.IsNullOrEmpty(newPwd)) { UIManager.Instance.ShowBoardError("请输入新密码"); return; } if (newPwd != newPwdConfirm) { UIManager.Instance.ShowBoardError("两次输入的密码不一致"); return; } if (string.IsNullOrEmpty(code)) { UIManager.Instance.ShowBoardError("请输入验证码"); return; } APIRequestList.ResetPassword(new ReSetPassWordParam { mobile = mobile, password = newPwd, code = code }, (result) => { UIManager.Instance.ShowBoardError("密码修改成功"); tMPText_NewPassword.text = ""; tMPText_NewPasswordQueRen.text = ""; tMPText_YZMXGMM.text = ""; }); } // ==================== 改个性签名 ==================== private void OnClickSaveSignature() { if (tMPText_GeXingQianName == null) return; string text = tMPText_GeXingQianName.text.Trim(); if (string.IsNullOrEmpty(text)) { UIManager.Instance.ShowBoardError("签名不能为空"); return; } PlayerPrefs.SetString("QM", text); PlayerPrefs.Save(); UIManager.Instance.ShowBoardError("签名保存成功"); } // ==================== 工具 ==================== public static string MaskPhone(string phone) { if (string.IsNullOrEmpty(phone) || phone.Length < 7) return phone; return phone.Substring(0, 3) + "****" + phone.Substring(phone.Length - 4); } }