869 lines
23 KiB
Vue
869 lines
23 KiB
Vue
<script setup>
|
||
import { computed, ref } from "vue";
|
||
import { onShow } from "@dcloudio/uni-app";
|
||
import Container from "@/components/Container.vue";
|
||
import Avatar from "@/components/Avatar.vue";
|
||
import { topThreeColors } from "@/constants";
|
||
import {
|
||
getSeasonList,
|
||
getSeasonStats,
|
||
getScoreRankList,
|
||
getTenRingRankList,
|
||
getMvpRankList,
|
||
} from "@/apis";
|
||
import { canEenter } from "@/util";
|
||
import useStore from "@/store";
|
||
import { storeToRefs } from "pinia";
|
||
|
||
const store = useStore();
|
||
const { user, device, online, game } = storeToRefs(store);
|
||
const { getLvlName } = store;
|
||
|
||
const defaultSeasonStats = {
|
||
nickName: "",
|
||
avatar: "",
|
||
season: "",
|
||
seasonId: 0,
|
||
score: 0,
|
||
rankName: "",
|
||
rankLvl: 0,
|
||
rankIcon: "",
|
||
avgRing: 0,
|
||
winRate: 0,
|
||
modeStats: [],
|
||
};
|
||
|
||
const defaultModeStats = {
|
||
"1v1": { modeName: "", count: 0, winRate: 0, mvpCount: 0, scoreRate: 0 },
|
||
"2v2": { modeName: "", count: 0, winRate: 0, mvpCount: 0, scoreRate: 0 },
|
||
"3v3": { modeName: "", count: 0, winRate: 0, mvpCount: 0, scoreRate: 0 },
|
||
"5m": { modeName: "", count: 0, winRate: 0, mvpCount: 0, scoreRate: 0 },
|
||
"10m": { modeName: "", count: 0, winRate: 0, mvpCount: 0, scoreRate: 0 },
|
||
};
|
||
|
||
const RANK_PAGE = 1;
|
||
const RANK_PAGE_SIZE = 10;
|
||
|
||
const selectedIndex = ref(0);
|
||
const seasonName = ref("");
|
||
const seasonData = ref([]);
|
||
const currentSeasonId = ref();
|
||
const seasonStats = ref({ ...defaultSeasonStats });
|
||
const showSeasonList = ref(false);
|
||
const currentSeasonData = ref({ ...defaultModeStats });
|
||
const rankLoading = ref(false);
|
||
const scoreRankList = ref([]);
|
||
const mvpRankList = ref([]);
|
||
const tenRingRankList = ref([]);
|
||
|
||
// 根据接口返回结构提取榜单数组,兼容数组和对象两种返回形式。
|
||
const getRankListFromResponse = (result) => {
|
||
if (Array.isArray(result)) return result;
|
||
if (Array.isArray(result?.list)) return result.list;
|
||
if (Array.isArray(result?.items)) return result.items;
|
||
return [];
|
||
};
|
||
|
||
// 把赛季统计接口里的 modeStats 转成页面当前使用的结构,同时保留后端返回的 modeName。
|
||
const buildModeStats = (modeStats = []) => {
|
||
const nextStats = {
|
||
"1v1": { ...defaultModeStats["1v1"] },
|
||
"2v2": { ...defaultModeStats["2v2"] },
|
||
"3v3": { ...defaultModeStats["3v3"] },
|
||
"5m": { ...defaultModeStats["5m"] },
|
||
"10m": { ...defaultModeStats["10m"] },
|
||
};
|
||
|
||
modeStats.forEach((item) => {
|
||
if (item.mode === 1) nextStats["1v1"] = { ...nextStats["1v1"], ...item };
|
||
if (item.mode === 2) nextStats["2v2"] = { ...nextStats["2v2"], ...item };
|
||
if (item.mode === 3) nextStats["3v3"] = { ...nextStats["3v3"], ...item };
|
||
if (item.mode === 4) nextStats["5m"] = { ...nextStats["5m"], ...item };
|
||
if (item.mode === 5) nextStats["10m"] = { ...nextStats["10m"], ...item };
|
||
});
|
||
|
||
return nextStats;
|
||
};
|
||
|
||
// 当前选中榜单的数据,只用于统一处理加载态和空态。
|
||
const currentRankList = computed(() => {
|
||
if (selectedIndex.value === 0) return scoreRankList.value;
|
||
if (selectedIndex.value === 1) return mvpRankList.value;
|
||
return tenRingRankList.value;
|
||
});
|
||
|
||
const latestSeasonId = computed(() => seasonData.value[0]?.seasonId);
|
||
const isLatestSeasonSelected = computed(() => {
|
||
if (!currentSeasonId.value || !latestSeasonId.value) return true; // 默认显示,防止数据未加载时闪烁
|
||
return currentSeasonId.value === latestSeasonId.value;
|
||
});
|
||
|
||
const toMatchPage = async (gameType, teamSize) => {
|
||
if (!canEenter(user.value, device.value, online.value)) return;
|
||
if (game.value.inBattle) {
|
||
uni.$showHint(1);
|
||
return;
|
||
}
|
||
await uni.$checkAudio();
|
||
uni.navigateTo({
|
||
url: `/pages/match-page?gameType=${gameType}&teamSize=${teamSize}`,
|
||
});
|
||
};
|
||
|
||
const toMyGrowthPage = () => {
|
||
uni.navigateTo({
|
||
url: "/pages/my-growth",
|
||
});
|
||
};
|
||
|
||
const toRankListPage = () => {
|
||
const tabMap = ["score", "mvp", "tenRing"];
|
||
uni.navigateTo({
|
||
url: `/pages/rank-list?tab=${tabMap[selectedIndex.value] || "score"}`,
|
||
});
|
||
};
|
||
|
||
// 组装榜单副标题,统一处理段位和场次展示。
|
||
const formatRankSubTitle = (item = {}) => {
|
||
const levelName = item.rankName || getLvlName(item.rankLvl) || "-";
|
||
const totalGames = item.totalGames ?? item.TotalGames ?? 0;
|
||
return `${levelName},${totalGames}场`;
|
||
};
|
||
|
||
// 组装顶部赛季统计文案,区分胜率和得分率。
|
||
const formatSeasonText = (stats = {}, rateKey = "winRate", rateLabel = "胜率") => {
|
||
const totalGames = stats.count || 0;
|
||
const rateValue = stats[rateKey] || 0;
|
||
let text = `${totalGames}场 ${rateLabel} ${rateValue}%`;
|
||
|
||
// 只有当 2V2 (mode=2) 或 3V3 (mode=3) 时,在胜率后面新增 MVP 次数
|
||
if (stats.mode === 2 || stats.mode === 3) {
|
||
const mvpCount = stats.mvpCount || 0;
|
||
text += `,MVP次数 ${mvpCount}`;
|
||
}
|
||
|
||
return text;
|
||
};
|
||
|
||
// 统一处理顶部统计展示,避免数值为 0 时被误显示成占位符。
|
||
const formatTopStatValue = (value, suffix = "") => {
|
||
if (value === undefined || value === null || value === "") return "-";
|
||
return `${value}${suffix}`;
|
||
};
|
||
|
||
// 请求赛季统计接口,并更新顶部展示和各模式数据。
|
||
const loadSeasonStats = async (seasonId = currentSeasonId.value) => {
|
||
const result = await getSeasonStats(seasonId);
|
||
seasonStats.value = {
|
||
...defaultSeasonStats,
|
||
...(result || {}),
|
||
};
|
||
|
||
currentSeasonId.value = seasonStats.value.seasonId || seasonId;
|
||
seasonName.value = seasonStats.value.season || seasonName.value;
|
||
currentSeasonData.value = buildModeStats(seasonStats.value.modeStats);
|
||
};
|
||
|
||
// 根据当前 tab 请求对应榜单,每次切换都重新获取最新数据,不走缓存。
|
||
const loadRankList = async (
|
||
index = selectedIndex.value,
|
||
seasonId = currentSeasonId.value
|
||
) => {
|
||
if (!seasonId) return;
|
||
|
||
rankLoading.value = true;
|
||
try {
|
||
if (index === 0) {
|
||
const result = await getScoreRankList(seasonId, RANK_PAGE, RANK_PAGE_SIZE);
|
||
scoreRankList.value = getRankListFromResponse(result);
|
||
return;
|
||
}
|
||
|
||
if (index === 1) {
|
||
const result = await getMvpRankList(seasonId, RANK_PAGE, RANK_PAGE_SIZE);
|
||
mvpRankList.value = getRankListFromResponse(result);
|
||
return;
|
||
}
|
||
|
||
const result = await getTenRingRankList(
|
||
seasonId,
|
||
RANK_PAGE,
|
||
RANK_PAGE_SIZE
|
||
);
|
||
tenRingRankList.value = getRankListFromResponse(result);
|
||
} catch (error) {
|
||
if (index === 0) scoreRankList.value = [];
|
||
else if (index === 1) mvpRankList.value = [];
|
||
else tenRingRankList.value = [];
|
||
|
||
uni.showToast({
|
||
title: "排行榜加载失败",
|
||
icon: "none",
|
||
});
|
||
console.error("load rank list error", error);
|
||
} finally {
|
||
rankLoading.value = false;
|
||
}
|
||
};
|
||
|
||
// 切换榜单时更新选中态,并重新请求对应的榜单数据。
|
||
const handleSelect = async (index) => {
|
||
selectedIndex.value = index;
|
||
await loadRankList(index);
|
||
};
|
||
|
||
// 切换赛季时同时刷新顶部统计和当前榜单数据。
|
||
const onChangeSeason = async (seasonId, name) => {
|
||
showSeasonList.value = false;
|
||
if (seasonId === currentSeasonId.value) return;
|
||
|
||
currentSeasonId.value = seasonId;
|
||
seasonName.value = name;
|
||
|
||
try {
|
||
await loadSeasonStats(seasonId);
|
||
await loadRankList(selectedIndex.value, seasonId);
|
||
} catch (error) {
|
||
uni.showToast({
|
||
title: "赛季数据加载失败",
|
||
icon: "none",
|
||
});
|
||
console.error("change season error", error);
|
||
}
|
||
};
|
||
|
||
// 页面显示时先拿赛季列表,再拉当前赛季统计和默认榜单数据。
|
||
onShow(async () => {
|
||
try {
|
||
const seasonResult = await getSeasonList();
|
||
seasonData.value = seasonResult.list || [];
|
||
|
||
if (!seasonData.value.length) {
|
||
seasonStats.value = { ...defaultSeasonStats };
|
||
currentSeasonData.value = { ...defaultModeStats };
|
||
scoreRankList.value = [];
|
||
mvpRankList.value = [];
|
||
tenRingRankList.value = [];
|
||
showSeasonList.value = false;
|
||
return;
|
||
}
|
||
|
||
const currentSeason =
|
||
seasonData.value.find((item) => item.seasonId === currentSeasonId.value) ||
|
||
seasonData.value[0];
|
||
|
||
currentSeasonId.value = currentSeason.seasonId;
|
||
seasonName.value = currentSeason.seasonName;
|
||
showSeasonList.value = false;
|
||
|
||
await Promise.all([
|
||
loadSeasonStats(currentSeasonId.value),
|
||
loadRankList(selectedIndex.value, currentSeasonId.value),
|
||
]);
|
||
} catch (error) {
|
||
uni.showToast({
|
||
title: "页面数据加载失败",
|
||
icon: "none",
|
||
});
|
||
console.error("ranking page load error", error);
|
||
}
|
||
});
|
||
</script>
|
||
|
||
<template>
|
||
<Container title="排位赛" :showBackToGame="true" :bgType="6">
|
||
<view class="battle-types-box">
|
||
<view class="battle-types">
|
||
<view class="first">
|
||
<image src="../static/rank/battle-choose.png" mode="widthFix" />
|
||
<image class="star" src="../static/rank/star.png" mode="widthFix" />
|
||
</view>
|
||
<image
|
||
src="../static/rank/battle1v1.svg"
|
||
mode="widthFix"
|
||
@click.stop="() => toMatchPage(1, 2)"
|
||
/>
|
||
<image
|
||
src="../static/rank/battle2v2.svg"
|
||
mode="widthFix"
|
||
@click.stop="() => toMatchPage(2, 4)"
|
||
/>
|
||
<image
|
||
src="../static/rank/battle3v3.svg"
|
||
mode="widthFix"
|
||
@click.stop="() => toMatchPage(3, 6)"
|
||
/>
|
||
<image
|
||
src="../static/rank/battle5.svg"
|
||
mode="widthFix"
|
||
@click.stop="() => toMatchPage(4, 5)"
|
||
/>
|
||
<image
|
||
src="../static/rank/battle10.svg"
|
||
mode="widthFix"
|
||
@click.stop="() => toMatchPage(5, 10)"
|
||
/>
|
||
</view>
|
||
</view>
|
||
<view class="container" @click="() => (showSeasonList = false)">
|
||
<view class="ranking-my-data" v-if="user.id">
|
||
<view>
|
||
<view class="user-info">
|
||
<Avatar
|
||
:src="user.avatar"
|
||
:rankLvl="seasonStats.rankLvl"
|
||
:size="30"
|
||
/>
|
||
<text>{{ seasonStats.nickName || user.nickName }}</text>
|
||
</view>
|
||
<view
|
||
class="ranking-season"
|
||
v-show="seasonData.length"
|
||
@click.stop="() => (showSeasonList = true)"
|
||
>
|
||
<text>{{ seasonName }}</text>
|
||
<image
|
||
v-show="seasonData.length > 1"
|
||
src="../static/rank/triangle.png"
|
||
mode="widthFix"
|
||
/>
|
||
<view class="season-list" v-if="showSeasonList">
|
||
<view
|
||
v-for="(item, index) in seasonData"
|
||
:key="index"
|
||
@click.stop="
|
||
() => onChangeSeason(item.seasonId, item.seasonName)
|
||
"
|
||
>
|
||
<text
|
||
:style="{
|
||
color: item.seasonName === seasonName ? '#E7BA80' : '#FFFFFF',
|
||
}"
|
||
>
|
||
{{ item.seasonName }}
|
||
</text>
|
||
<image
|
||
v-if="item.seasonName === seasonName"
|
||
src="../static/rank/triangle.png"
|
||
mode="widthFix"
|
||
/>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="my-data">
|
||
<view>
|
||
<text>段位</text>
|
||
<text :style="{ color: '#E7BA80' }">
|
||
{{ seasonStats.rankName || getLvlName(seasonStats.rankLvl) || "-" }}
|
||
</text>
|
||
</view>
|
||
<view>
|
||
<text>赛季平均环数</text>
|
||
<text :style="{ color: '#E7BA80' }">
|
||
{{ formatTopStatValue(seasonStats.avgRing, "环") }}
|
||
</text>
|
||
</view>
|
||
<view>
|
||
<text>赛季胜率</text>
|
||
<text :style="{ color: '#E7BA80' }">
|
||
{{ formatTopStatValue(seasonStats.winRate, "%") }}
|
||
</text>
|
||
</view>
|
||
<view class="my-rank-score">
|
||
<image src="../static/rank/bubble-tip.png" mode="widthFix" />
|
||
<text>积分:{{ seasonStats.score }}</text>
|
||
</view>
|
||
</view>
|
||
<view class="data-progress">
|
||
<view class="data-name-box">
|
||
<text class="data-name">{{ currentSeasonData["1v1"].modeName || "1V1" }} </text>
|
||
<text>{{ formatSeasonText(currentSeasonData["1v1"], "winRate", "胜率") }}</text>
|
||
</view>
|
||
<view class="data-progress-line">
|
||
<view
|
||
:style="{ width: `${currentSeasonData['1v1'].winRate}%` }"
|
||
/>
|
||
</view>
|
||
</view>
|
||
<view class="data-progress">
|
||
<view class="data-name-box">
|
||
<text class="data-name">{{ currentSeasonData["2v2"].modeName || "2V2" }} </text>
|
||
<text>{{ formatSeasonText(currentSeasonData["2v2"], "winRate", "胜率") }}</text>
|
||
</view>
|
||
<view class="data-progress-line">
|
||
<view
|
||
:style="{ width: `${currentSeasonData['2v2'].winRate}%` }"
|
||
/>
|
||
</view>
|
||
</view>
|
||
<view class="data-progress">
|
||
<view class="data-name-box">
|
||
<text class="data-name">{{ currentSeasonData["3v3"].modeName || "3V3" }} </text>
|
||
<text>{{ formatSeasonText(currentSeasonData["3v3"], "winRate", "胜率") }}</text>
|
||
</view>
|
||
<view class="data-progress-line">
|
||
<view
|
||
:style="{ width: `${currentSeasonData['3v3'].winRate}%` }"
|
||
/>
|
||
</view>
|
||
</view>
|
||
<view class="data-progress">
|
||
<view class="data-name-box">
|
||
<text class="data-name">{{ currentSeasonData["5m"].modeName || "5V5" }} </text>
|
||
<text>{{ formatSeasonText(currentSeasonData["5m"], "scoreRate", "得分率") }}</text>
|
||
</view>
|
||
<view class="data-progress-line">
|
||
<view
|
||
:style="{ width: `${currentSeasonData['5m'].scoreRate}%` }"
|
||
/>
|
||
</view>
|
||
</view>
|
||
<view class="data-progress">
|
||
<view class="data-name-box">
|
||
<text class="data-name">{{ currentSeasonData["10m"].modeName || "10人大乱斗" }} </text>
|
||
<text>{{ formatSeasonText(currentSeasonData["10m"], "scoreRate", "得分率") }}</text>
|
||
</view>
|
||
<view class="data-progress-line">
|
||
<view
|
||
:style="{ width: `${currentSeasonData['10m'].scoreRate}%` }"
|
||
/>
|
||
</view>
|
||
</view>
|
||
<view class="growth-btn" @click.stop="toMyGrowthPage">
|
||
查看我的比赛记录
|
||
<image
|
||
style="width: 30rpx; vertical-align: -2px"
|
||
src="../static/enter.png"
|
||
mode="widthFix"
|
||
/>
|
||
</view>
|
||
</view>
|
||
<view class="ranking-data">
|
||
<view>
|
||
<view
|
||
v-for="(rankType, index) in ['积分榜', 'MVP榜', '十环榜']"
|
||
:key="index"
|
||
:style="{
|
||
color: '#fff',
|
||
opacity: index === selectedIndex ? '1' : '0.7',
|
||
background:
|
||
index === selectedIndex
|
||
? 'linear-gradient(133deg, #FFD19A 0%, #A17636 100%)'
|
||
: 'rgba(255,255,255,0.1)',
|
||
}"
|
||
@tap="handleSelect(index)"
|
||
>
|
||
{{ rankType }}
|
||
</view>
|
||
</view>
|
||
|
||
<view
|
||
v-if="selectedIndex === 0"
|
||
v-for="(item, index) in scoreRankList"
|
||
:key="`score-${index}`"
|
||
:style="{ backgroundColor: index % 2 === 0 ? '#9898981f' : 'transparent' }"
|
||
class="rank-item"
|
||
>
|
||
<image v-if="index === 0" src="../static/champ1.png" mode="widthFix" />
|
||
<image v-if="index === 1" src="../static/champ2.png" mode="widthFix" />
|
||
<image v-if="index === 2" src="../static/champ3.png" mode="widthFix" />
|
||
<view v-if="index > 2">{{ index + 1 }}</view>
|
||
<image
|
||
:src="item.avatar || '../static/user-icon.png'"
|
||
mode="widthFix"
|
||
:style="{ borderColor: index < 3 ? topThreeColors[index] : '' }"
|
||
/>
|
||
<view>
|
||
<text class="truncate">{{ item.name }}</text>
|
||
<text>{{ formatRankSubTitle(item) }}</text>
|
||
</view>
|
||
<text>{{ item.totalScore || 0 }}<text>分</text></text>
|
||
</view>
|
||
|
||
<view
|
||
v-if="selectedIndex === 1"
|
||
v-for="(item, index) in mvpRankList"
|
||
:key="`mvp-${index}`"
|
||
:style="{ backgroundColor: index % 2 === 0 ? '#9898981f' : 'transparent' }"
|
||
class="rank-item"
|
||
>
|
||
<image v-if="index === 0" src="../static/champ1.png" mode="widthFix" />
|
||
<image v-if="index === 1" src="../static/champ2.png" mode="widthFix" />
|
||
<image v-if="index === 2" src="../static/champ3.png" mode="widthFix" />
|
||
<view v-if="index > 2">{{ index + 1 }}</view>
|
||
<image
|
||
:src="item.avatar || '../static/user-icon.png'"
|
||
mode="widthFix"
|
||
:style="{ borderColor: index < 3 ? topThreeColors[index] : '' }"
|
||
/>
|
||
<view>
|
||
<text class="truncate">{{ item.name }}</text>
|
||
<text>{{ formatRankSubTitle(item) }}</text>
|
||
</view>
|
||
<text>{{ item.mvpCount || 0 }}<text>次</text></text>
|
||
</view>
|
||
|
||
<view
|
||
v-if="selectedIndex === 2"
|
||
v-for="(item, index) in tenRingRankList"
|
||
:key="`ten-ring-${index}`"
|
||
:style="{ backgroundColor: index % 2 === 0 ? '#9898981f' : 'transparent' }"
|
||
class="rank-item"
|
||
>
|
||
<image v-if="index === 0" src="../static/champ1.png" mode="widthFix" />
|
||
<image v-if="index === 1" src="../static/champ2.png" mode="widthFix" />
|
||
<image v-if="index === 2" src="../static/champ3.png" mode="widthFix" />
|
||
<view v-if="index > 2">{{ index + 1 }}</view>
|
||
<image
|
||
:src="item.avatar || '../static/user-icon.png'"
|
||
mode="widthFix"
|
||
:style="{ borderColor: index < 3 ? topThreeColors[index] : '' }"
|
||
/>
|
||
<view>
|
||
<text class="truncate">{{ item.name }}</text>
|
||
<text>{{ formatRankSubTitle(item) }}</text>
|
||
</view>
|
||
<text>{{ item.tenRings ?? item.TenRings ?? 0 }}<text>次</text></text>
|
||
</view>
|
||
|
||
<view v-if="rankLoading" class="no-data">
|
||
<text>加载中...</text>
|
||
</view>
|
||
<view v-else-if="!currentRankList.length" class="no-data">
|
||
<text>暂无数据</text>
|
||
</view>
|
||
<view v-if="isLatestSeasonSelected" class="see-more" @click.stop="toRankListPage">点击查看更多</view>
|
||
</view>
|
||
</view>
|
||
</Container>
|
||
</template>
|
||
|
||
<style scoped>
|
||
.container {
|
||
width: 100%;
|
||
padding-bottom: 40rpx;
|
||
}
|
||
|
||
.ranking-my-data,
|
||
.ranking-data {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
background: rgba(84, 67, 29, 0.3);
|
||
border: 2rpx solid rgba(255, 217, 71, 0.2);
|
||
border-radius: 24rpx;
|
||
margin: 0 15px;
|
||
margin-bottom: 20px;
|
||
}
|
||
|
||
.ranking-my-data {
|
||
padding: 30rpx 30rpx 38rpx 30rpx;
|
||
margin-bottom: 16rpx;
|
||
}
|
||
|
||
.ranking-my-data > view:first-of-type {
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
width: 100%;
|
||
padding-bottom: 15px;
|
||
}
|
||
|
||
.user-info {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
color: #fff;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.user-info > text {
|
||
margin-left: 15px;
|
||
}
|
||
|
||
.ranking-season {
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
position: relative;
|
||
}
|
||
|
||
.ranking-season > image {
|
||
width: 12px;
|
||
height: 12px;
|
||
}
|
||
|
||
.ranking-season > text {
|
||
color: #e7ba80;
|
||
font-size: 14px;
|
||
margin-right: 5px;
|
||
}
|
||
|
||
.my-data {
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: space-around;
|
||
color: #b3b3b3;
|
||
width: 110%;
|
||
margin-top: 15px;
|
||
position: relative;
|
||
transform: translateX(-5%);
|
||
}
|
||
|
||
.my-data > view {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
justify-content: space-around;
|
||
width: 32%;
|
||
height: 60px;
|
||
position: relative;
|
||
}
|
||
|
||
.my-data > view:nth-child(2) {
|
||
border-left: 1px solid #48494e;
|
||
border-right: 1px solid #48494e;
|
||
padding: 0 15px;
|
||
}
|
||
|
||
.my-data > view > text:first-child {
|
||
font-size: 14px;
|
||
}
|
||
|
||
.my-data > view > text:last-child {
|
||
font-size: 18px;
|
||
}
|
||
|
||
.battle-types-box {
|
||
width: 100%;
|
||
padding: 28rpx;
|
||
box-sizing: border-box;
|
||
}
|
||
|
||
.battle-types {
|
||
display: grid;
|
||
grid-template-columns: repeat(3, 1fr);
|
||
row-gap: 8px;
|
||
column-gap: 8px;
|
||
}
|
||
|
||
.battle-types > image {
|
||
width: 220rpx;
|
||
height: 108rpx;
|
||
}
|
||
|
||
.battle-types .first {
|
||
width: 220rpx;
|
||
height: 108rpx;
|
||
position: relative;
|
||
}
|
||
|
||
.battle-types .first > image {
|
||
width: 220rpx;
|
||
height: 108rpx;
|
||
}
|
||
|
||
.battle-types .first .star {
|
||
width: 94rpx;
|
||
height: 98rpx;
|
||
position: absolute;
|
||
left: -22rpx;
|
||
bottom: 0;
|
||
}
|
||
|
||
.data-progress {
|
||
width: 100%;
|
||
color: #b3b3b3;
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: flex-start;
|
||
margin-top: 15px;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.data-progress .data-name {
|
||
color: #ffffff;
|
||
}
|
||
|
||
.data-progress .data-progress-line {
|
||
width: 100%;
|
||
height: 5px;
|
||
border-radius: 10px;
|
||
background-color: #696969;
|
||
margin-top: 10px;
|
||
}
|
||
|
||
.data-progress .data-progress-line > view {
|
||
background: linear-gradient(133deg, #ffd19a 0%, #a17636 100%);
|
||
height: 5px;
|
||
border-radius: 10px;
|
||
transition: width 0.3s ease;
|
||
}
|
||
|
||
.growth-btn {
|
||
color: #999999;
|
||
font-size: 14px;
|
||
text-align: center;
|
||
width: 100%;
|
||
padding-top: 15px;
|
||
}
|
||
|
||
.ranking-data > view:first-of-type {
|
||
width: calc(100% - 30px);
|
||
display: flex;
|
||
justify-content: space-around;
|
||
font-size: 15px;
|
||
padding: 15px;
|
||
}
|
||
|
||
.ranking-data > view:first-of-type > view {
|
||
width: 25%;
|
||
text-align: center;
|
||
border-radius: 20px;
|
||
font-size: 30rpx;
|
||
word-break: keep-all;
|
||
line-height: 70rpx;
|
||
}
|
||
|
||
.rank-item {
|
||
width: calc(100% - 30px);
|
||
height: 55px;
|
||
padding: 0 15px;
|
||
display: flex;
|
||
justify-content: space-between;
|
||
align-items: center;
|
||
}
|
||
|
||
.rank-item > view:first-child {
|
||
width: 24px;
|
||
height: 24px;
|
||
border-radius: 12px;
|
||
background-color: #767676;
|
||
color: #fff;
|
||
text-align: center;
|
||
line-height: 24px;
|
||
font-size: 14px;
|
||
}
|
||
|
||
.rank-item > image:first-child {
|
||
width: 24px;
|
||
height: 24px;
|
||
}
|
||
|
||
.rank-item > image:nth-child(2) {
|
||
width: 35px;
|
||
min-height: 35px;
|
||
max-height: 35px;
|
||
border-radius: 50%;
|
||
border: 1px solid transparent;
|
||
}
|
||
|
||
.rank-item > view:nth-child(3) {
|
||
display: flex;
|
||
flex-direction: column;
|
||
width: 50%;
|
||
}
|
||
|
||
.rank-item > view:nth-child(3) > text:first-child {
|
||
color: #fff9;
|
||
font-size: 14px;
|
||
width: 120px;
|
||
}
|
||
|
||
.rank-item > view:nth-child(3) > text:last-child {
|
||
color: #fff4;
|
||
font-size: 13px;
|
||
}
|
||
|
||
.rank-item > text:last-child {
|
||
color: #fff;
|
||
width: 56px;
|
||
text-align: right;
|
||
}
|
||
|
||
.rank-item > text:last-child text {
|
||
color: #fff4;
|
||
font-size: 13px;
|
||
margin-left: 3px;
|
||
}
|
||
|
||
.see-more {
|
||
color: #39a8ff;
|
||
font-size: 14px;
|
||
text-align: center;
|
||
width: 100%;
|
||
margin-top: 5px;
|
||
margin-bottom: 10px;
|
||
}
|
||
|
||
.no-data {
|
||
width: 100%;
|
||
height: 200px;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
color: #fff9;
|
||
}
|
||
|
||
.season-list {
|
||
background-color: #000c;
|
||
border-radius: 15px;
|
||
color: #fff;
|
||
font-size: 12px;
|
||
padding: 5px 0;
|
||
position: absolute;
|
||
width: 220rpx;
|
||
height: auto;
|
||
max-height: 400rpx;
|
||
overflow: hidden;
|
||
overflow-y: auto;
|
||
top: -44rpx;
|
||
right: -30rpx;
|
||
letter-spacing: 2px;
|
||
z-index: 10;
|
||
text-align: center;
|
||
}
|
||
|
||
.season-list > view {
|
||
display: flex;
|
||
align-items: center;
|
||
word-break: keep-all;
|
||
padding: 20rpx 0;
|
||
}
|
||
|
||
.season-list > view > text {
|
||
width: 140rpx;
|
||
text-align: right;
|
||
}
|
||
|
||
.season-list > view > image {
|
||
width: 24rpx;
|
||
height: 24rpx;
|
||
min-width: 24rpx;
|
||
min-height: 24rpx;
|
||
margin-left: 20rpx;
|
||
}
|
||
|
||
.my-rank-score {
|
||
position: absolute !important;
|
||
color: #333333;
|
||
width: 80px !important;
|
||
display: flex;
|
||
justify-content: center;
|
||
top: -34px;
|
||
left: 20px;
|
||
}
|
||
|
||
.my-rank-score > image {
|
||
position: absolute;
|
||
width: 100%;
|
||
}
|
||
|
||
.my-rank-score > text {
|
||
position: relative;
|
||
font-size: 10px !important;
|
||
margin-bottom: 7px;
|
||
}
|
||
</style>
|