Files
web-fusion/src/components/pk-mini/mine/PKRecord.vue
2026-02-26 13:15:19 +08:00

502 lines
11 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<!-- 我的PK记录 -->
<div class="pk-record">
<div class="pk-layout">
<div class="left-panel">
<div class="demo-panel">
<!-- 选项卡 -->
<div class="tab-header">
<div
class="tab-item"
v-for="item in tabOptions"
:key="item.value"
@click="switchTab(item.value)"
:class="{ active: activeTab === item.value }"
>
<img class="tab-icon" :src="activeTab === item.value ? item.selectedIcon : item.icon" alt="" />
<span class="tab-label">{{ item.label }}</span>
</div>
</div>
<!-- 列表 -->
<div class="record-list" v-if="list.length > 0">
<div
v-for="(item, index) in list"
:key="index"
class="record-item"
:class="{ selected: selectedData === item }"
@click="selectRecord(item)"
>
<!-- 左侧信息 -->
<div class="record-info">
<img class="record-avatar" :src="item.anchorIconA" alt="" />
<div class="record-detail">
<div class="record-name">{{ item.anchorIdA }}</div>
<div class="record-time">PK时间: {{ formatTime(item.pkTime * 1000) }}</div>
<div class="record-coins" v-if="item.userACoins != null">
<img class="coin-icon" src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/gold.png" alt="" />
<span>实际金币数: {{ formatCoin(item.userACoins) }}</span>
</div>
</div>
</div>
<!-- VS 图标 -->
<div class="vs-icon">
<img src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/session.png" alt="" />
</div>
<!-- 右侧信息 -->
<div class="record-info right">
<div class="record-detail">
<div class="record-name">{{ item.anchorIdB }}</div>
<div class="record-time">PK时间: {{ formatTime(item.pkTime * 1000) }}</div>
<div class="record-coins" v-if="item.userBCoins != null">
<img class="coin-icon" src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/gold.png" alt="" />
<span>实际金币数: {{ formatCoin(item.userBCoins) }}</span>
</div>
</div>
<img class="record-avatar" :src="item.anchorIconB" alt="" />
</div>
</div>
</div>
<div class="empty-tip" v-else>您还没有PK记录</div>
</div>
</div>
<!-- 右侧详情 -->
<div class="right-panel">
<div class="detail-panel" v-if="selectedData">
<!-- 双方头像 -->
<div class="detail-avatars">
<img class="detail-avatar" :src="selectedData.anchorIconA" alt="" />
<img class="detail-avatar" :src="selectedData.anchorIconB" alt="" />
</div>
<!-- 总计 -->
<div class="detail-total">
<div class="total-card">
<span class="total-num">总共{{ formatCoin(selectedData.userACoins) }}</span>
<img class="total-icon" src="https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/session.png" alt="" />
<span class="total-num">总共{{ formatCoin(selectedData.userBCoins) }}</span>
</div>
</div>
<!-- 每局详情 -->
<div class="detail-rounds">
<div class="rounds-column left">
<div
v-for="(item, index) in roundDetails"
:key="'a-' + index"
class="round-item"
:class="item.anchorCoinA > item.anchorCoinB ? 'win' : 'lose'"
>
{{ index + 1 }}: {{ formatCoin(item.anchorCoinA) }}
</div>
</div>
<div class="rounds-column right">
<div
v-for="(item, index) in roundDetails"
:key="'b-' + index"
class="round-item"
:class="item.anchorCoinB > item.anchorCoinA ? 'win' : 'lose'"
>
{{ index + 1 }}: {{ formatCoin(item.anchorCoinB) }}
</div>
</div>
</div>
</div>
<div class="empty-detail" v-else>
<span>选择右侧的记录可立即查看详细信息</span>
</div>
</div>
</div>
</div>
</template>
<script setup>
import { ref, onMounted } from 'vue'
import { getPkRecord, queryPkDetail } from '@/api/pk-mini'
import { getMainUserData } from '@/utils/pk-mini/storage'
import { TimestamptolocalTime } from '@/utils/pk-mini/timeConversion'
// 导入本地图片
import iconPublish from '@/assets/pk-mini/Publish.png'
import iconPublishSelected from '@/assets/pk-mini/PublishSelected.png'
import iconInvitation from '@/assets/pk-mini/Invitation.png'
import iconInvitationSelected from '@/assets/pk-mini/InvitationSelected.png'
// 获取用户 ID兼容不同的字段名
function getUserId(user) {
return user?.id || user?.userId || user?.uid || null
}
const currentUser = ref({})
const activeTab = ref(1)
const list = ref([])
const postedList = ref([]) // 发布的PK
const invitedList = ref([]) // 邀请的PK
const selectedData = ref(null)
const roundDetails = ref([])
const tabOptions = [
{
label: '发布的PK',
value: 1,
icon: iconPublish,
selectedIcon: iconPublishSelected
},
{
label: '邀请的PK',
value: 2,
icon: iconInvitation,
selectedIcon: iconInvitationSelected
}
]
const formatTime = TimestamptolocalTime
function formatCoin(value) {
if (value == null) return '0'
if (value >= 10000) {
return (value / 10000).toFixed(1) + 'w'
} else if (value >= 1000) {
return (value / 1000).toFixed(1) + 'k'
}
return String(value)
}
function switchTab(value) {
activeTab.value = value
selectedData.value = null
roundDetails.value = []
list.value = value === 1 ? postedList.value : invitedList.value
}
async function selectRecord(item) {
selectedData.value = item
try {
const res = await queryPkDetail({ id: item.id })
roundDetails.value = res || []
} catch (e) {
console.error('获取PK详情失败', e)
}
}
async function loadRecords(type) {
const userId = getUserId(currentUser.value)
if (!userId) return
try {
const res = await getPkRecord({
type: type,
userId: userId,
page: 0,
size: 50
})
if (type === 1) {
postedList.value = res || []
if (activeTab.value === 1) {
list.value = postedList.value
}
} else {
invitedList.value = res || []
if (activeTab.value === 2) {
list.value = invitedList.value
}
}
} catch (e) {
console.error('加载PK记录失败', e)
}
}
onMounted(() => {
currentUser.value = getMainUserData() || {}
const userId = getUserId(currentUser.value)
console.log('[PKRecord] 当前用户数据:', currentUser.value)
console.log('[PKRecord] 解析的用户 ID:', userId)
if (userId) {
loadRecords(1)
loadRecords(2)
} else {
console.warn('[PKRecord] 未找到用户 ID无法加载数据')
}
})
</script>
<style scoped lang="less">
.pk-record {
width: 100%;
height: 100%;
}
.pk-layout {
width: 100%;
height: 100%;
display: flex;
flex-direction: row;
}
.left-panel {
flex: 1;
min-width: 0;
height: 100%;
overflow: hidden;
}
.right-panel {
width: 380px;
flex-shrink: 0;
height: 100%;
overflow: hidden;
border-left: 1px solid #03aba82f;
}
.demo-panel {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
}
.tab-header {
display: flex;
padding: 20px 30px;
gap: 80px;
}
.tab-item {
display: flex;
align-items: center;
gap: 12px;
padding: 15px 30px;
cursor: pointer;
border-bottom: 3px solid transparent;
transition: all 0.3s;
}
.tab-item.active {
border-bottom-color: #03aba8;
}
.tab-icon {
width: 28px;
height: 28px;
}
.tab-label {
font-size: 20px;
color: #636363;
}
.tab-item.active .tab-label {
color: #03aba8;
}
.record-list {
flex: 1;
overflow: auto;
padding: 0 20px;
}
.record-item {
display: flex;
align-items: center;
justify-content: space-around;
padding: 20px;
margin-bottom: 15px;
background: url('https://vv-1317974657.cos.ap-shanghai.myqcloud.com/util/PKbackground.png') no-repeat center/cover;
border-radius: 16px;
box-shadow: 0 2px 8px rgba(0,0,0,0.1);
cursor: pointer;
transition: all 0.3s;
}
.record-item:hover {
transform: scale(1.02);
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
}
.record-item.selected {
background-color: #fffbfa;
border: 1px solid #f4d0c9;
}
.record-info {
display: flex;
align-items: center;
gap: 15px;
width: 40%;
}
.record-info.right {
justify-content: flex-end;
}
.record-avatar {
width: 80px;
height: 80px;
border-radius: 50%;
object-fit: cover;
}
.record-detail {
display: flex;
flex-direction: column;
gap: 8px;
}
.record-info.right .record-detail {
align-items: flex-end;
}
.record-name {
font-size: 16px;
font-weight: bold;
}
.record-time {
font-size: 13px;
color: #999;
}
.record-coins {
display: flex;
align-items: center;
gap: 8px;
font-size: 13px;
}
.coin-icon {
width: 24px;
height: 24px;
}
.vs-icon {
width: 40px;
height: 40px;
}
.vs-icon img {
width: 100%;
height: 100%;
}
.empty-tip {
flex: 1;
display: flex;
align-items: center;
justify-content: center;
font-size: 18px;
color: #03aba8;
}
// 右侧详情
.detail-panel {
width: 100%;
height: 100%;
display: flex;
flex-direction: column;
align-items: center;
padding: 15px;
box-sizing: border-box;
overflow: hidden;
}
.detail-avatars {
display: flex;
gap: 20px;
margin-bottom: 12px;
}
.detail-avatar {
width: 50px;
height: 50px;
border-radius: 50%;
object-fit: cover;
}
.detail-total {
width: 100%;
margin-bottom: 12px;
}
.total-card {
display: flex;
align-items: center;
justify-content: space-around;
padding: 10px;
background: linear-gradient(90deg, #e4ffff, #fff, #e4ffff);
border-radius: 30px;
}
.total-num {
font-size: 13px;
font-weight: bold;
color: #333;
}
.total-icon {
width: 28px;
height: 22px;
}
.detail-rounds {
flex: 1;
width: 100%;
display: flex;
gap: 10px;
overflow: hidden;
}
.rounds-column {
flex: 1;
display: flex;
flex-direction: column;
gap: 8px;
padding: 10px;
border-radius: 12px;
overflow: auto;
}
.rounds-column.left {
background: #dffefc;
border: 1px solid #86e1e3;
}
.rounds-column.right {
background: #fbece9;
border: 1px solid #f4d0c9;
}
.round-item {
padding: 8px 10px;
border-radius: 8px;
font-size: 13px;
font-weight: bold;
color: #03aba8;
text-align: center;
}
.round-item.win {
background: #d1f6f7;
}
.round-item.lose {
background: #f9dfd9;
}
.empty-detail {
width: 100%;
height: 100%;
display: flex;
align-items: center;
justify-content: center;
border-left: 1px solid #03aba82f;
font-size: 18px;
color: #03aba8;
}
</style>