Files
5.24BuYu/Assets/MyGame/aa/UI/Home/Sub/UIHome_BY_RankPanel.cs
T
2026-10-08 07:25:02 +08:00

211 lines
7.6 KiB
C#

using Assets.Framework.Tool;
using Assets.MyGame.Scripts.Net;
using Assets.MyGame.Scripts.Net.API;
using Assets.MyGame.Scripts.Net.API.GameConfig_SubClass;
using Assets.MyGame.Scripts.Net.API.UserData_SubClass;
using Assets.MyGame.Scripts.Net.APIRequest.Params;
using Assets.MyGame.Scripts.Net.APIResponses;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class UIHome_BY_RankPanel : SubUIBase
{
[Header("排行列表")]
public RankLineItem obj_LinePrefab; // 排行行 Prefab
public Transform prefabRankLineItem_parent; // 列表父节点
[Header("我的排行")]
public RankLineItem myobj_Line; // 底部"我的排行"固定行
[Header("Tab 切换")]
public Toggle toggle_GlodRank; // 金币排行
public Toggle toggle_LevelRank; // 等级排行
public Toggle toggle_CurrDayScroeRank; // 今日消耗排行
[Header("排行标题")]
public TextMeshProUGUI tmp_RankTitle; // 排行标题(可选)
// ---- 运行时数据 ----
/// <summary>当前排行类型 1=金币 2=等级 3=今日消耗</summary>
private int _currentRankType = 1;
private static readonly string[] RankTypeNames = { "", "金币排行", "等级排行", "今日消耗排行" };
private RankingRewardConfig _rankingRewardConfig;
protected override void OnShow(object args = null)
{
base.OnShow(args);
// 优先使用入口(UIHomeMain)预取的配置,避免重复请求
if (args is RankingRewardConfig cfg)
_rankingRewardConfig = cfg;
// 加载排名奖励配置
if (_rankingRewardConfig == null)
{
APIRequestList.GetRankingRewardConfig(config =>
{
_rankingRewardConfig = config;
SwitchRankType(_currentRankType);
});
}
// ---- Toggle 监听 ----
if (toggle_GlodRank != null)
toggle_GlodRank.onValueChanged.AddListener((isOn) => { if (isOn) SwitchRankType(1); });
if (toggle_LevelRank != null)
toggle_LevelRank.onValueChanged.AddListener((isOn) => { if (isOn) SwitchRankType(2); });
if (toggle_CurrDayScroeRank != null)
toggle_CurrDayScroeRank.onValueChanged.AddListener((isOn) => { if (isOn) SwitchRankType(3); });
// 初始化默认选中金币排行
SwitchRankType(1);
}
private void SwitchRankType(int type)
{
_currentRankType = type;
// 更新标题
if (tmp_RankTitle != null && type >= 1 && type <= 3)
tmp_RankTitle.text = RankTypeNames[type];
// 同步 Toggle 状态
SyncToggleState(type);
LoadRankData(type);
}
private void SyncToggleState(int type)
{
if (toggle_GlodRank != null) toggle_GlodRank.SetIsOnWithoutNotify(type == 1);
if (toggle_LevelRank != null) toggle_LevelRank.SetIsOnWithoutNotify(type == 2);
if (toggle_CurrDayScroeRank != null) toggle_CurrDayScroeRank.SetIsOnWithoutNotify(type == 3);
}
/// <summary>
/// 加载排行数据
/// </summary>
private void LoadRankData(int rankType)
{
APIRequestList.GetRanking(new GetRankingParam { type = rankType }, response =>
{
if (response == null) return;
// ---- 排行榜列表 ----
ClearRankList();
if (response.userList != null && response.userList.Count > 0)
{
for (int i = 0; i < response.userList.Count; i++)
{
var data = response.userList[i];
var item = Instantiate(obj_LinePrefab, prefabRankLineItem_parent);
var sprite = GameManager.Instance.GetAvatarSprite(data.avatarUrl);
var rewards = GetRankRewards(data.rank);
item.Init(
data.rank,
data.nickName ?? data.userName ?? "—",
data.level > 0 ? $"Lv.{data.level}" : "—",
FormatRankingValue(data.rankingValue),
sprite,
data.avatarUrl,
giftItems: rewards
);
}
}
// ---- 我的排行 ----
if (myobj_Line != null)
{
if (response.user != null)
{
var me = response.user;
var sprite = GameManager.Instance.GetAvatarSprite(me.avatarUrl);
var myRewards = GetRankRewards(me.rank);
myobj_Line.gameObject.SetActive(true);
myobj_Line.Init(
me.rank,
me.nickName ?? me.userName ?? "—",
me.level > 0 ? $"Lv.{me.level}" : "—",
FormatRankingValue(me.rankingValue),
sprite,
me.avatarUrl,
GameManager.Instance.user.BaseInfo.avatarFrame,
myRewards
);
}
else
{
// 当前用户未上榜
myobj_Line.gameObject.SetActive(false);
}
}
});
}
/// <summary>
/// 根据排行类型格式化排行数值
/// </summary>
private string FormatRankingValue(long value)
{
return _currentRankType switch
{
1 => FormatGold(value), // 金币排行
2 => $"Lv.{value}", // 等级排行
3 => FormatGold(value), // 今日消耗排行
_ => value.ToString(),
};
}
/// <summary>
/// 金币数值格式化(万/亿单位)
/// </summary>
private static string FormatGold(long gold)
{
if (gold >= 100000000) // 亿
return $"{(gold / 100000000f):F1}亿";
if (gold >= 10000) // 万
return $"{(gold / 10000f):F1}万";
return gold.ToString("N0");
}
/// <summary>根据排行类型和排名查找奖励道具(服务端gold/diamond在奖励层级而非items里,合成type=1/2条目与items合并显示)</summary>
private List<GiftConfig> GetRankRewards(int rank)
{
if (_rankingRewardConfig == null || !_rankingRewardConfig.isEnabled) return null;
var group = _rankingRewardConfig.groups?.Find(g => g.rankingType == _currentRankType);
if (group?.rewards == null) return null;
var match = group.rewards.Find(r => rank >= r.rankMin && rank <= r.rankMax);
if (match == null) return null;
var list = new List<GiftConfig>();
if (match.gold > 0)
list.Add(new GiftConfig { type = 1, isRandom = false, count = (int)match.gold });
if (match.diamond > 0)
list.Add(new GiftConfig { type = 2, isRandom = false, count = match.diamond });
if (match.items != null) list.AddRange(match.items);
return list.Count > 0 ? list : null;
}
private void ClearRankList()
{
if (prefabRankLineItem_parent == null) return;
for (int i = prefabRankLineItem_parent.childCount - 1; i >= 0; i--)
Destroy(prefabRankLineItem_parent.GetChild(i).gameObject);
}
private void OnDestroy()
{
// 清理 Toggle 监听避免内存泄漏
if (toggle_GlodRank != null) toggle_GlodRank.onValueChanged.RemoveAllListeners();
if (toggle_LevelRank != null) toggle_LevelRank.onValueChanged.RemoveAllListeners();
if (toggle_CurrDayScroeRank != null) toggle_CurrDayScroeRank.onValueChanged.RemoveAllListeners();
}
}