Files
martial-mini/pages/event-info/event-info.vue
2025-12-12 01:44:41 +08:00

281 lines
7.8 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>
<view class="event-info-page">
<!-- 信息列表 -->
<view class="info-list">
<view class="info-item" v-for="(item, index) in infoList" :key="index" @click="handleItemClick(item)">
<view class="info-header">
<view class="info-tag" :class="item.type">{{ item.typeText }}</view>
<view class="info-time">{{ item.time }}</view>
</view>
<view class="info-title">{{ item.title }}</view>
<view class="info-desc">{{ item.desc }}</view>
</view>
</view>
<!-- 空状态 -->
<view class="empty-state" v-if="infoList.length === 0">
<text class="empty-text">暂无信息发布</text>
</view>
</view>
</template>
<script>
import infoAPI from '@/api/info.js'
export default {
data() {
return {
eventId: '',
infoList: []
};
},
onLoad(options) {
if (options.eventId) {
this.eventId = options.eventId
this.loadInfoList(options.eventId)
}
},
methods: {
/**
* 加载信息发布列表
*/
async loadInfoList(eventId) {
try {
const res = await infoAPI.getInfoPublishList({ competitionId: eventId })
let list = []
if (res.records) {
list = res.records
} else if (Array.isArray(res)) {
list = res
}
// 如果后端没有数据,使用模拟数据
if (list.length === 0) {
list = this.getMockData()
}
// 数据映射
this.infoList = list.map(item => ({
id: item.id,
type: this.getInfoType(item.infoType || item.info_type || item.type),
typeText: this.getInfoTypeText(item.infoType || item.info_type || item.type),
title: item.title || item.infoTitle,
desc: item.content || item.description || item.infoContent || '',
time: this.formatTime(item.publishTime || item.publish_time || item.createTime)
}))
} catch (err) {
console.error('加载信息列表失败:', err)
// 加载失败时使用模拟数据
const list = this.getMockData()
this.infoList = list.map(item => ({
id: item.id,
type: this.getInfoType(item.info_type || item.type),
typeText: this.getInfoTypeText(item.info_type || item.type),
title: item.title,
desc: item.content,
time: this.formatTime(item.publishTime)
}))
}
},
/**
* 获取模拟数据
*/
getMockData() {
return [
{
id: 1,
info_type: 3,
title: '重要通知:赛事报名截止时间变更',
content: '由于场馆调整本次赛事报名截止时间延长至2025年12月20日请各位选手抓紧时间报名。如有疑问请联系赛事组委会。',
publishTime: '2025-01-10 09:00:00'
},
{
id: 2,
info_type: 1,
title: '参赛选手须知',
content: '请各位参赛选手提前1小时到达比赛场地进行检录携带身份证原件及复印件。比赛期间请遵守赛场纪律服从裁判判决。',
publishTime: '2025-01-09 14:30:00'
},
{
id: 3,
info_type: 2,
title: '比赛场地及交通指引',
content: '本次赛事在市体育中心举行地址XX市XX区XX路100号。可乘坐地铁2号线至体育中心站下车或乘坐公交车88路、99路至体育中心站。场馆提供免费停车位。',
publishTime: '2025-01-08 16:00:00'
},
{
id: 4,
info_type: 1,
title: '赛前训练安排通知',
content: '为方便各位选手熟悉场地组委会安排在比赛前一天12月24日下午14:00-17:00开放场地供选手训练。请需要训练的选手提前联系组委会预约。',
publishTime: '2025-01-07 10:20:00'
},
{
id: 5,
info_type: 2,
title: '比赛流程及注意事项',
content: '比赛采用淘汰赛制分为预赛、半决赛和决赛三个阶段。每场比赛时长为5分钟选手需提前做好热身准备。比赛过程中严禁使用违禁器材。',
publishTime: '2025-01-06 11:45:00'
},
{
id: 6,
info_type: 1,
title: '医疗保障及安全提示',
content: '赛事现场配备专业医疗团队和救护车,设有医疗服务点。建议选手自备常用药品,如有特殊疾病请提前告知组委会。比赛前请充分热身,避免受伤。',
publishTime: '2025-01-05 15:10:00'
},
{
id: 7,
info_type: 3,
title: '关于赛事直播安排的通知',
content: '本次赛事将进行全程网络直播届时可通过官方网站和APP观看。精彩瞬间将在赛后剪辑发布敬请期待',
publishTime: '2025-01-04 13:00:00'
},
{
id: 8,
info_type: 2,
title: '志愿者招募公告',
content: '赛事组委会现招募志愿者50名负责现场引导、秩序维护、后勤保障等工作。有意者请扫描海报二维码报名报名截止时间为12月15日。',
publishTime: '2025-01-03 09:30:00'
}
]
},
/**
* 获取信息类型样式类名
*/
getInfoType(type) {
const typeMap = {
1: 'notice',
2: 'announcement',
3: 'important',
'notice': 'notice',
'announcement': 'announcement',
'important': 'important'
}
return typeMap[type] || 'notice'
},
/**
* 获取信息类型文本
*/
getInfoTypeText(type) {
const typeMap = {
1: '通知',
2: '公告',
3: '重要',
'notice': '通知',
'announcement': '公告',
'important': '重要'
}
return typeMap[type] || '通知'
},
/**
* 格式化时间
*/
formatTime(timeStr) {
if (!timeStr) return ''
const date = new Date(timeStr)
const year = date.getFullYear()
const month = String(date.getMonth() + 1).padStart(2, '0')
const day = String(date.getDate()).padStart(2, '0')
const hours = String(date.getHours()).padStart(2, '0')
const minutes = String(date.getMinutes()).padStart(2, '0')
return `${year}-${month}-${day} ${hours}:${minutes}`
},
handleItemClick(item) {
// 跳转到信息详情页
uni.navigateTo({
url: `/pages/event-info-detail/event-info-detail?id=${item.id}&type=${item.type}&typeText=${encodeURIComponent(item.typeText)}&title=${encodeURIComponent(item.title)}&content=${encodeURIComponent(item.desc)}&time=${encodeURIComponent(item.time)}`
})
}
}
};
</script>
<style lang="scss" scoped>
.event-info-page {
min-height: 100vh;
background-color: #f5f5f5;
padding: 20rpx 30rpx;
}
.info-list {
display: flex;
flex-direction: column;
gap: 20rpx;
}
.info-item {
background-color: #fff;
border-radius: 16rpx;
padding: 30rpx;
}
.info-header {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 15rpx;
}
.info-tag {
font-size: 24rpx;
padding: 8rpx 20rpx;
border-radius: 8rpx;
color: #fff;
}
.info-tag.notice {
background-color: #C93639;
}
.info-tag.announcement {
background-color: #FF8C00;
}
.info-tag.important {
background-color: #DC143C;
}
.info-time {
font-size: 24rpx;
color: #999999;
}
.info-title {
font-size: 32rpx;
font-weight: bold;
color: #333333;
margin-bottom: 10rpx;
line-height: 1.4;
}
.info-desc {
font-size: 26rpx;
color: #666666;
line-height: 1.6;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
.empty-state {
padding: 200rpx 0;
text-align: center;
}
.empty-text {
font-size: 28rpx;
color: #999999;
}
</style>