Files
martial-mini/pages/event-detail/event-detail.vue
2025-12-26 10:20:46 +08:00

317 lines
9.0 KiB
Vue
Raw Permalink 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>
<view class="event-detail-page">
<!-- 赛事标题和信息 -->
<view class="event-header">
<view class="event-title">{{ eventInfo.title }}</view>
<view class="divider"></view>
<view class="event-info">
<text class="label">地点</text>
<text class="value">{{ eventInfo.location }}</text>
</view>
<view class="event-info">
<text class="label">报名时间</text>
<text class="value">{{ eventInfo.registerTime }}</text>
</view>
<view class="event-info">
<text class="label">比赛时间</text>
<text class="value">{{ eventInfo.matchTime }}</text>
</view>
<view class="event-info">
<text class="label">报名人数</text>
<text class="value">{{ eventInfo.registerCount }}</text>
</view>
<view class="divider"></view>
</view>
<!-- 功能网格 -->
<view class="function-grid">
<view class="function-item" @click="handleFunction('info')">
<image class="function-icon-img" src="/static/images/信息发布@3x.png" mode="aspectFit"></image>
<text class="function-text">信息发布</text>
</view>
<view class="function-item" @click="handleFunction('rules')">
<image class="function-icon-img" src="/static/images/赛事规程@3x.png" mode="aspectFit"></image>
<text class="function-text">赛事规程</text>
</view>
<view class="function-item" @click="handleFunction('schedule')">
<image class="function-icon-img" src="/static/images/活动日程@3x.png" mode="aspectFit"></image>
<text class="function-text">活动日程</text>
</view>
<view class="function-item" @click="handleFunction('players')">
<image class="function-icon-img" src="/static/images/参赛选手@3x.png" mode="aspectFit"></image>
<text class="function-text">参赛选手</text>
</view>
<view class="function-item" @click="handleFunction('match')">
<image class="function-icon-img" src="/static/images/比赛实况@3x.png" mode="aspectFit"></image>
<text class="function-text">比赛实况</text>
</view>
<view class="function-item" @click="handleFunction('lineup')">
<image class="function-icon-img" src="/static/images/出场顺序@3x.png" mode="aspectFit"></image>
<text class="function-text">出场顺序</text>
</view>
<view class="function-item" @click="handleFunction('score')">
<image class="function-icon-img" src="/static/images/成绩@3x.png" mode="aspectFit"></image>
<text class="function-text">成绩</text>
</view>
<view class="function-item" @click="handleFunction('awards')">
<image class="function-icon-img" src="/static/images/奖牌榜.png" mode="aspectFit"></image>
<text class="function-text">奖牌榜</text>
</view>
<view class="function-item" @click="handleFunction('photos')">
<image class="function-icon-img" src="/static/images/图片直播@3x.png" mode="aspectFit"></image>
<text class="function-text">图片直播</text>
</view>
</view>
<!-- 报名按钮 -->
<view class="register-btn-wrapper" v-if="eventInfo.status === 'open'">
<view class="register-btn" @click="goToRegister">去报名</view>
</view>
<!-- 报名已结束状态 -->
<view class="register-btn-wrapper" v-if="eventInfo.status === 'finished'">
<view class="register-btn disabled">报名已结束</view>
</view>
</view>
</template>
<script>
import competitionAPI from '@/api/competition.js'
export default {
data() {
return {
eventId: '',
eventInfo: {
id: '',
title: '',
location: '',
registerTime: '',
matchTime: '',
registerCount: '0',
status: 'open'
}
};
},
onLoad(options) {
if (options.id) {
this.eventId = options.id
this.loadEventDetail(options.id)
}
},
methods: {
/**
* 加载赛事详情
* @param {String|Number} id 赛事ID
*/
async loadEventDetail(id) {
try {
const res = await competitionAPI.getCompetitionDetail(id)
console.log('赛事详情API返回:', res)
// 尝试多个可能的时间字段
const regStartTime = res.registrationStartTime || res.registerStartTime || res.signUpStartTime
const regEndTime = res.registrationEndTime || res.registerEndTime || res.signUpEndTime
const startTime = res.startTime || res.competitionStartTime || res.beginTime || res.startDate
const endTime = res.endTime || res.competitionEndTime || res.finishTime || res.endDate
// 数据映射
this.eventInfo = {
id: res.id,
title: res.name || res.title || res.competitionName || '未命名赛事',
location: res.location || res.address || res.venue || '待定',
registerTime: this.formatTimeRange(regStartTime, regEndTime) ||
res.registerTime || res.registrationPeriod || '待定',
matchTime: this.formatTimeRange(startTime, endTime) ||
res.matchTime || res.competitionTime || '待定',
registerCount: res.registrationCount || res.registerCount || res.signUpCount || res.totalParticipants || '0',
status: this.getStatus(res.status)
}
console.log('格式化后的赛事信息:', this.eventInfo)
} catch (err) {
console.error('加载赛事详情失败:', err)
uni.showToast({
title: '加载失败,请重试',
icon: 'none'
})
}
},
/**
* 格式化时间范围
*/
formatTimeRange(startTime, endTime) {
if (!startTime || !endTime) return ''
const formatDate = (dateStr) => {
if (!dateStr) return ''
const date = new Date(dateStr)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
return `${year}.${month}.${day}`
}
return `${formatDate(startTime)}-${formatDate(endTime)}`
},
/**
* 获取赛事状态
*/
getStatus(status) {
// 1: 报名中, 2: 进行中, 3: 已结束
if (status === 3 || status === '3' || status === 'finished') {
return 'finished'
}
return 'open'
},
handleFunction(type) {
// 需要跳转到附件展示页面的类型
const attachmentTypes = ['info', 'rules', 'schedule', 'score', 'awards', 'photos']
if (attachmentTypes.includes(type)) {
// 跳转到通用附件展示页面
const name = encodeURIComponent(this.eventInfo.title)
uni.navigateTo({
url: `/pages/attachment-view/attachment-view?type=${type}&competitionId=${this.eventId}&name=${name}`
})
return
}
// 其他功能页面的路由映射
const routeMap = {
'players': '/pages/event-players/event-players',
'match': '/pages/event-live/event-live',
'lineup': '/pages/event-lineup/event-lineup'
};
const url = routeMap[type];
if (url) {
// 跳转时传递赛事ID
uni.navigateTo({
url: `${url}?eventId=${this.eventId}`
})
} else {
uni.showToast({
title: '功能开发中',
icon: 'none'
});
}
},
goToRegister() {
uni.navigateTo({
url: '/pages/register-type/register-type?id=' + this.eventInfo.id
});
}
}
};
</script>
<style lang="scss" scoped>
.event-detail-page {
min-height: 100vh;
background-color: #f5f5f5;
padding-bottom: 180rpx;
}
.event-header {
background-color: #fff;
padding: 30rpx;
margin-bottom: 20rpx;
}
.event-title {
font-size: 36rpx;
font-weight: bold;
color: #333333;
line-height: 1.5;
margin-bottom: 20rpx;
}
.divider {
height: 6rpx;
background-color: #C93639;
width: 120rpx;
margin: 30rpx 0;
}
.event-info {
display: flex;
margin-bottom: 15rpx;
}
.label {
font-size: 28rpx;
color: #666666;
flex-shrink: 0;
}
.value {
font-size: 28rpx;
color: #666666;
}
.function-grid {
background-color: #fff;
padding: 30rpx;
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 40rpx 30rpx;
}
.function-item {
display: flex;
flex-direction: column;
align-items: center;
gap: 15rpx;
}
.function-icon {
width: 120rpx;
height: 120rpx;
border-radius: 16rpx;
display: flex;
align-items: center;
justify-content: center;
font-size: 60rpx;
}
.function-icon-img {
width: 90rpx;
height: 90rpx;
}
.function-text {
font-size: 26rpx;
color: #333333;
text-align: center;
}
.register-btn-wrapper {
position: fixed;
bottom: 0;
left: 0;
right: 0;
padding: 30rpx;
background-color: #fff;
box-shadow: 0 -4rpx 20rpx rgba(0, 0, 0, 0.05);
}
.register-btn {
background-color: #C93639;
color: #fff;
text-align: center;
padding: 20rpx;
border-radius: 12rpx;
font-size: 28rpx;
font-weight: bold;
}
.register-btn.disabled {
background-color: #999999;
}
</style>