完善比赛状态显示

This commit is contained in:
2025-04-22 19:38:08 +08:00
parent 71550c35b5
commit 5f48a8a55e
3 changed files with 205 additions and 111 deletions

View File

@@ -4,6 +4,18 @@
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
html, body {
margin: 0;
padding: 0;
/* height: 100%; */
/* overflow: hidden; */
}
#app {
width: 100%;
height: 100%;
}
</style>
<title>NBA在线</title>
</head>
<body>

View File

@@ -5,7 +5,7 @@
<div class="team-info away-team">
<img :src="gameData.awayTeam.logo" :alt="gameData.awayTeam.name" />
<div class="team-details">
<h3>{{ gameData.awayTeam.city }}</h3>
<!-- <h3>{{ gameData.awayTeam.city }}</h3> -->
<p>{{ gameData.awayTeam.name }}</p>
<span>{{ gameData.awayTeam.record }}</span>
</div>
@@ -14,12 +14,13 @@
<div class="vs-circle">VS</div>
<div class="team-info home-team">
<img :src="gameData.homeTeam.logo" :alt="gameData.homeTeam.name" />
<div class="team-details">
<h3>{{ gameData.homeTeam.city }}</h3>
<!-- <h3>{{ gameData.homeTeam.city }}</h3> -->
<p>{{ gameData.homeTeam.name }}</p>
<span>{{ gameData.homeTeam.record }}</span>
</div>
<img :src="gameData.homeTeam.logo" :alt="gameData.homeTeam.name" />
</div>
</div>
@@ -42,115 +43,169 @@
</div>
<!-- 返回按钮 -->
<button class="back-button" @click="goBack">
返回赛程
</button>
<button class="back-button" @click="goBack"> 返回赛程</button>
</div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount, computed } from 'vue'
import { useRouter } from 'vue-router'
import { useGameStore } from '@/stores/game'
import DPlayer from 'dplayer'
import Hls from 'hls.js'
import Flv from 'flv.js'
import { ref, onMounted, onBeforeUnmount, computed } from "vue";
import { useRouter } from "vue-router";
import { useGameStore } from "@/stores/game";
import DPlayer from "dplayer";
import Hls from "hls.js";
import Flv from "flv.js";
// 注册全局变量
window.flvjs = Flv
window.Hls = Hls
window.flvjs = Flv;
window.Hls = Hls;
const router = useRouter()
const gameStore = useGameStore()
const router = useRouter();
const gameStore = useGameStore();
const dpInstance = ref(null)
const dpInstance = ref(null);
// 从store获取数据
const gameData = computed(() => gameStore.currentGame)
const allStreams = computed(() => gameStore.allStreams)
const gameData = computed(() => gameStore.currentGame);
const allStreams = computed(() => gameStore.allStreams);
const currentStream = computed({
get: () => gameStore.currentStream,
set: (val) => gameStore.currentStream = val
})
set: (val) => (gameStore.currentStream = val),
});
// 初始化播放器
// const initPlayer = () => {
// if (dpInstance.value) {
// dpInstance.value.destroy();
// }
// dpInstance.value = new DPlayer({
// container: document.getElementById('dplayer-live'),
// live: true,
// autoplay: true,
// video: {
// url: currentStream.value?.url || '',
// type: 'auto'
// }
// });
// // 强制设置视频尺寸
// setTimeout(() => {
// const container = document.getElementById('dplayer-live');
// const video = container?.querySelector('video');
// if (video) {
// video.style.cssText = `
// width: 100% !important;
// height: 100% !important;
// object-fit: contain !important;
// position: absolute !important;
// top: 0 !important;
// left: 0 !important;
// `;
// // console.log('视频实际尺寸:', video.videoWidth, 'x', video.videoHeight);
// }
// }, 500);
// };
// 改进的播放器初始化(核心修改点)
// 改进的播放器初始化(核心修改点)
const initPlayer = () => {
if (!currentStream.value?.url) return;
// 销毁旧实例
if (dpInstance.value) {
dpInstance.value.destroy();
}
dpInstance.value = new DPlayer({
container: document.getElementById('dplayer-live'),
container: document.getElementById("dplayer-live"),
live: true,
autoplay: true,
airplay: true,
video: {
url: currentStream.value?.url || '',
type: 'auto'
url: currentStream.value.url,
type: "custom", // 修改为custom类型
customType: {
custom: function (video, player) {
const url = video.src;
// 自动检测协议类型
if (url.includes(".m3u8") || url.endsWith("/hls")) {
const hls = new Hls();
hls.loadSource(url);
hls.attachMedia(video);
player.on("destroy", () => hls.destroy());
} else if (url.includes(".flv") || url.endsWith("/flv")) {
const flv = Flv.createPlayer({ type: "flv", url });
flv.attachMediaElement(video);
flv.load();
player.on("destroy", () => flv.destroy());
} else {
// 其他协议回退到DPlayer默认处理
video.src = url;
}
},
},
},
});
// 强制设置视频尺寸
// 保持原有尺寸调整逻辑
setTimeout(() => {
const container = document.getElementById('dplayer-live');
const video = container?.querySelector('video');
const video = document
.getElementById("dplayer-live")
?.querySelector("video");
if (video) {
video.style.cssText = `
width: 100% !important;
height: 100% !important;
object-fit: contain !important;
position: absolute !important;
top: 0 !important;
left: 0 !important;
`;
// console.log('视频实际尺寸:', video.videoWidth, 'x', video.videoHeight);
}
}, 500);
};
// 切换直播源
const switchStream = (stream) => {
currentStream.value = stream
initPlayer()
}
currentStream.value = stream;
initPlayer();
};
// 获取直播源名称
const getStreamName = (type) => {
const names = {
tx: '企鹅体育',
wl: '纬来体育',
mg: '咪咕体育',
nba: '高清原声',
zb: '高清直播'
}
return names[type] || type
}
tx: "企鹅体育",
wl: "纬来体育",
mg: "咪咕体育",
nba: "高清原声",
zb: "高清直播",
};
return names[type] || type;
};
// 返回赛程页
const goBack = () => {
gameStore.clearGameData()
router.go(-1)
}
gameStore.clearGameData();
router.go(-1);
};
onMounted(() => {
// 默认选择第一个直播源
if (allStreams.value.length > 0 && !currentStream.value) {
currentStream.value = allStreams.value[0]
currentStream.value = allStreams.value[0];
}
initPlayer()
})
initPlayer();
});
onBeforeUnmount(() => {
if (dpInstance.value) {
dpInstance.value.destroy()
dpInstance.value.destroy();
}
})
});
</script>
<style lang="scss" scoped>
.live-stream-container {
max-width: 1200px;
margin: 0 auto;
padding: 20px;
// padding: 20px;
background: #f5f5f5;
min-height: 100vh;
}
@@ -161,6 +216,7 @@ onBeforeUnmount(() => {
align-items: center;
gap: 40px;
margin-bottom: 20px;
margin-top: 20px;
background: white;
padding: 20px;
border-radius: 8px;
@@ -203,7 +259,7 @@ onBeforeUnmount(() => {
.vs-circle {
width: 50px;
height: 50px;
background: #e74c3c;
background: #f29155;
color: white;
border-radius: 50%;
display: flex;
@@ -281,8 +337,40 @@ onBeforeUnmount(() => {
@media (max-width: 768px) {
.game-header {
flex-direction: column;
// flex-direction: column;
gap: 20px;
.team-info {
display: flex;
align-items: center;
gap: 15px;
img {
width: 60px;
height: 60px;
object-fit: contain;
}
.team-details {
text-align: center;
h3 {
margin: 0;
font-size: 1.2rem;
color: #333;
}
p {
margin: 5px 0;
font-size: 1.1rem;
font-weight: bold;
}
span {
font-size: 0.9rem;
color: #666;
}
}
}
}
.vs-circle {

View File

@@ -122,10 +122,11 @@
</div>
<div class="live-buttons">
<!-- 只有当比赛未结束且是当天比赛时才显示直播区域 -->
<template v-if="game.status !== 3 && shouldShowLiveArea(game)">
<!-- 进行中的比赛 -->
<template v-if="game.status === 2">
<!-- 只对当天比赛显示直播按钮 -->
<template v-if="isTodayGame(game)">
<template v-if="hasLiveStreams(game.gameId)">
<!-- 直播按钮 -->
<button
v-for="stream in getLiveStreams(game.gameId)"
:key="stream.type"
@@ -138,9 +139,16 @@
</template>
<div v-else class="no-live">无直播信号</div>
</template>
<!-- 非当天进行中比赛理论上不应该存在 -->
<div v-else class="no-live">比赛进行中</div>
</template>
<!-- 已结束的比赛无论是否当天 -->
<div v-else-if="game.status === 3" class="no-live">
比赛已结束
</div>
<!-- 未开始的比赛 -->
<div v-else class="no-live">未开始</div>
</div>
@@ -175,38 +183,26 @@ const gameStore = useGameStore();
const router = useRouter();
const urlsData = ref([]);
const shouldShowLiveArea = (game) => {
// 1. 已结束的比赛不显示
if (game.status === 3) return false;
// 2. 获取今天的日期(北京时间)
const today = new Date();
const todayStr = `${today.getFullYear()}-${(today.getMonth() + 1)
.toString()
.padStart(2, "0")}-${today.getDate().toString().padStart(2, "0")}`;
// 3. 直接比较 startDate已经是北京时间
return game.startDate === todayStr;
};
onMounted(async () => {
try {
const response = await urls();
urlsData.value = response || [];
// console.log("获取的直播URL数据:", urlsData.value); // 检查数据是否正确
} catch (err) {
console.error("获取直播URL失败:", err);
urlsData.value = [];
}
});
// 判断是否为当天进行中的比赛
const isLiveGame = (game) => {
const isLive = game.status === 2; // 假设2表示进行中
const gameDate = new Date(game.dateTimeUtc);
// 判断是否为当天比赛(无论状态如何)
const isTodayGame = (game) => {
// 获取今天的日期(北京时间)
const today = new Date();
const isToday = gameDate.toDateString() === today.toDateString();
return isLive && isToday;
const todayStr = `${today.getFullYear()}-${(today.getMonth() + 1)
.toString()
.padStart(2, "0")}-${today.getDate().toString().padStart(2, "0")}`;
// 直接比较 startDate已经是北京时间
return game.startDate === todayStr;
};
// 检查比赛是否有直播流
@@ -239,7 +235,6 @@ const getStreamName = (type) => {
nba: "高清原声",
mg: "咪咕体育",
zb: "高清直播",
// 可以添加更多类型
};
return names[type] || type;
};
@@ -299,7 +294,6 @@ const props = defineProps({
const emit = defineEmits(["dateChange"]);
// 当前显示日期
// 当前显示日期(带星期几)
const currentDisplayDate = computed(() => {
if (!props.scheduleData?.data?.start) return "加载中...";
@@ -370,7 +364,7 @@ const isWinner = (game, teamType) => {
if (game.status !== 3) return false;
// 比较比分
if (teamType === 'away') {
if (teamType === "away") {
return game.awayTeamScore > game.homeTeamScore;
} else {
return game.homeTeamScore > game.awayTeamScore;
@@ -754,11 +748,11 @@ const isWinner = (game, teamType) => {
/* 如果希望更明显的效果,可以调整样式 */
.team.winner .team-name {
font-weight: bold;
color: #2E7D32; /* 深绿色文字 */
color: #2e7d32; /* 深绿色文字 */
}
.team.winner .team-score {
font-weight: bold;
color: #2E7D32; /* 深绿色比分 */
color: #2e7d32; /* 深绿色比分 */
}
</style>