123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178 |
- <template>
- <div class="home">
- <h1>{{ currentTab === 2 ? '篮球直播' : '足球直播' }}</h1>
- <div class="tabs">
- <span :class="{ active: currentTab === 1 }" @click="changeTab(1)">足球</span>
- <span :class="{ active: currentTab === 2 }" @click="changeTab(2)">篮球</span>
- </div>
- <div v-if="loading" class="loading">加载中...</div>
- <div v-else-if="liveList.length" class="grid">
- <LiveCard
- v-for="item in liveList"
- :key="item._id"
- :live="item"
- @click="goToPlayer(item)"
- >
- <template #default>
- <div v-if="item.videoUrl">
- <!-- LiveCard 默认内容 -->
- </div>
- <div v-else>
- <!-- 检查 item.image 是否是 base64 字符串 -->
- <img :src="isBase64(item.image) ? item.image : item.image || 'https://via.placeholder.com/300x180?text=Live'" alt="动画预览" class="preview-img" />
- <p class="preview-text">播放动画中</p>
-
- </div>
- </template>
- </LiveCard>
- </div>
- <div v-else class="empty">暂无直播</div>
- </div>
- </template>
- <script setup>
- import { ref, onMounted } from 'vue'
- import LiveCard from '../components/LiveCard.vue'
- import { useRouter } from 'vue-router'
- import axios from 'axios'
- const router = useRouter()
- const liveList = ref([])
- const loading = ref(true)
- const currentTab = ref(1) // 1 足球 2 篮球
- // 判断是否是 base64 字符串
- // const isBase64 = (str) => {
- // const regex = /^data:image\/[a-z]+;base64,/i
- // return regex.test(str)
- // }
- const isBase64 = (str) => {
- return typeof str === 'string' && /^data:image\/[a-z]+;base64,/i.test(str)
- }
- const getCurrentDate = () => {
- const now = new Date()
- const year = now.getFullYear()
- const month = String(now.getMonth() + 1).padStart(2, '0')
- const day = String(now.getDate()).padStart(2, '0')
- return `${year}${month}${day}`
- }
- const fetchLiveList = async () => {
- loading.value = true
- try {
- // const res = await axios.post('/api/animation_new', {
- // authentication: 'd1c6b578c986f869000ec44e85091751',
- // date: getCurrentDate(),
- // lang: 1,
- // sportId: currentTab.value
- // })
- const type = currentTab.value === 1 ? 'live_football' : 'live_basketball'
- // console.log(type)
- const res = await axios.post('http://api.csqionghua.com/live_data.php?type='+type)
- //console.log('返回数据:', res.data.data)
- if (res.data.code === 200) {
- liveList.value = res.data.data
- .filter(item => item.videoUrl && item.videoUrl.trim() !== '') // 过滤掉没有 videoUrl 的项
- .sort((a, b) => new Date(b.matchTime) - new Date(a.matchTime)) // 按时间倒序
- .map(item => ({
- ...item,
- title: `${item.homeTeam} VS ${item.awayTeam}`,
- subtitle: item.competition,
- viewers: 0,
- image: item.thumb ? 'data:image/jpeg;base64,' + item.thumb : '' || 'https://via.placeholder.com/300x180?text=Live'
- }))
- }
- } catch (err) {
- console.error('Fetch error:', err)
- } finally {
- loading.value = false
- }
- }
- const changeTab = (tab) => {
- if (currentTab.value !== tab) {
- currentTab.value = tab
- fetchLiveList()
- }
- }
- const goToPlayer = (item) => {
- router.push({
- name: 'Player',
- params: { id: item._id },
- query: { title: item.title, videoUrl: item.videoUrl }
- })
- }
- onMounted(fetchLiveList)
- </script>
- <style>
- .grid {
- display: grid;
- flex-wrap: wrap;
- grid-template-columns: repeat(auto-fill, minmax(159px, 1fr));
- gap: 16px;
- }
- @media (max-width: 600px) {
- .grid {
- grid-template-columns: repeat(2, 1fr); /* 保证竖屏时至少2列 */
- }
- }
- .preview-img {
- width: 100%;
- height: 120px;
- object-fit: cover;
- border-radius: 8px;
- }
- .preview-text {
- text-align: center;
- margin-top: 8px;
- font-size: 14px;
- color: #999;
- }
- .empty {
- text-align: center;
- margin-top: 40px;
- font-size: 18px;
- color: #888;
- }
- .loading {
- text-align: center;
- margin-top: 40px;
- font-size: 18px;
- color: #555;
- }
- .tabs {
- display: flex;
- justify-content: flex-start;
- margin: 16px 0;
- padding-bottom: 8px;
- border-bottom: 1px dashed #f88;
- }
- .tabs span {
- margin-right: 24px;
- font-size: 18px;
- font-weight: 500;
- cursor: pointer;
- color: #333;
- position: relative;
- }
- .tabs span.active {
- color: #000;
- }
- .tabs span.active::after {
- content: '';
- position: absolute;
- bottom: -5px;
- left: 0;
- width: 100%;
- height: 3px;
- background: #000;
- border-radius: 2px;
- }
- </style>
|