完善比赛状态显示
This commit is contained in:
12
index.html
12
index.html
@@ -4,6 +4,18 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<link rel="icon" href="/favicon.ico">
|
<link rel="icon" href="/favicon.ico">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<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>
|
<title>NBA在线</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<div class="team-info away-team">
|
<div class="team-info away-team">
|
||||||
<img :src="gameData.awayTeam.logo" :alt="gameData.awayTeam.name" />
|
<img :src="gameData.awayTeam.logo" :alt="gameData.awayTeam.name" />
|
||||||
<div class="team-details">
|
<div class="team-details">
|
||||||
<h3>{{ gameData.awayTeam.city }}</h3>
|
<!-- <h3>{{ gameData.awayTeam.city }}</h3> -->
|
||||||
<p>{{ gameData.awayTeam.name }}</p>
|
<p>{{ gameData.awayTeam.name }}</p>
|
||||||
<span>{{ gameData.awayTeam.record }}</span>
|
<span>{{ gameData.awayTeam.record }}</span>
|
||||||
</div>
|
</div>
|
||||||
@@ -14,12 +14,13 @@
|
|||||||
<div class="vs-circle">VS</div>
|
<div class="vs-circle">VS</div>
|
||||||
|
|
||||||
<div class="team-info home-team">
|
<div class="team-info home-team">
|
||||||
<img :src="gameData.homeTeam.logo" :alt="gameData.homeTeam.name" />
|
|
||||||
<div class="team-details">
|
<div class="team-details">
|
||||||
<h3>{{ gameData.homeTeam.city }}</h3>
|
<!-- <h3>{{ gameData.homeTeam.city }}</h3> -->
|
||||||
<p>{{ gameData.homeTeam.name }}</p>
|
<p>{{ gameData.homeTeam.name }}</p>
|
||||||
<span>{{ gameData.homeTeam.record }}</span>
|
<span>{{ gameData.homeTeam.record }}</span>
|
||||||
</div>
|
</div>
|
||||||
|
<img :src="gameData.homeTeam.logo" :alt="gameData.homeTeam.name" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -42,115 +43,169 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 返回按钮 -->
|
<!-- 返回按钮 -->
|
||||||
<button class="back-button" @click="goBack">
|
<button class="back-button" @click="goBack">← 返回赛程</button>
|
||||||
← 返回赛程
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, onMounted, onBeforeUnmount, computed } from 'vue'
|
import { ref, onMounted, onBeforeUnmount, computed } from "vue";
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from "vue-router";
|
||||||
import { useGameStore } from '@/stores/game'
|
import { useGameStore } from "@/stores/game";
|
||||||
import DPlayer from 'dplayer'
|
import DPlayer from "dplayer";
|
||||||
import Hls from 'hls.js'
|
import Hls from "hls.js";
|
||||||
import Flv from 'flv.js'
|
import Flv from "flv.js";
|
||||||
|
|
||||||
// 注册全局变量
|
// 注册全局变量
|
||||||
window.flvjs = Flv
|
window.flvjs = Flv;
|
||||||
window.Hls = Hls
|
window.Hls = Hls;
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter();
|
||||||
const gameStore = useGameStore()
|
const gameStore = useGameStore();
|
||||||
|
|
||||||
const dpInstance = ref(null)
|
const dpInstance = ref(null);
|
||||||
|
|
||||||
// 从store获取数据
|
// 从store获取数据
|
||||||
const gameData = computed(() => gameStore.currentGame)
|
const gameData = computed(() => gameStore.currentGame);
|
||||||
const allStreams = computed(() => gameStore.allStreams)
|
const allStreams = computed(() => gameStore.allStreams);
|
||||||
const currentStream = computed({
|
const currentStream = computed({
|
||||||
get: () => gameStore.currentStream,
|
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 = () => {
|
const initPlayer = () => {
|
||||||
|
if (!currentStream.value?.url) return;
|
||||||
|
|
||||||
|
// 销毁旧实例
|
||||||
if (dpInstance.value) {
|
if (dpInstance.value) {
|
||||||
dpInstance.value.destroy();
|
dpInstance.value.destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
dpInstance.value = new DPlayer({
|
dpInstance.value = new DPlayer({
|
||||||
container: document.getElementById('dplayer-live'),
|
container: document.getElementById("dplayer-live"),
|
||||||
live: true,
|
live: true,
|
||||||
autoplay: true,
|
autoplay: true,
|
||||||
|
airplay: true,
|
||||||
video: {
|
video: {
|
||||||
url: currentStream.value?.url || '',
|
url: currentStream.value.url,
|
||||||
type: 'auto'
|
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(() => {
|
setTimeout(() => {
|
||||||
const container = document.getElementById('dplayer-live');
|
const video = document
|
||||||
const video = container?.querySelector('video');
|
.getElementById("dplayer-live")
|
||||||
|
?.querySelector("video");
|
||||||
if (video) {
|
if (video) {
|
||||||
video.style.cssText = `
|
video.style.cssText = `
|
||||||
width: 100% !important;
|
width: 100% !important;
|
||||||
height: 100% !important;
|
height: 100% !important;
|
||||||
object-fit: contain !important;
|
object-fit: contain !important;
|
||||||
position: absolute !important;
|
|
||||||
top: 0 !important;
|
|
||||||
left: 0 !important;
|
|
||||||
`;
|
`;
|
||||||
// console.log('视频实际尺寸:', video.videoWidth, 'x', video.videoHeight);
|
|
||||||
}
|
}
|
||||||
}, 500);
|
}, 500);
|
||||||
};
|
};
|
||||||
|
|
||||||
// 切换直播源
|
// 切换直播源
|
||||||
const switchStream = (stream) => {
|
const switchStream = (stream) => {
|
||||||
currentStream.value = stream
|
currentStream.value = stream;
|
||||||
initPlayer()
|
initPlayer();
|
||||||
}
|
};
|
||||||
|
|
||||||
// 获取直播源名称
|
// 获取直播源名称
|
||||||
const getStreamName = (type) => {
|
const getStreamName = (type) => {
|
||||||
const names = {
|
const names = {
|
||||||
tx: '企鹅体育',
|
tx: "企鹅体育",
|
||||||
wl: '纬来体育',
|
wl: "纬来体育",
|
||||||
mg: '咪咕体育',
|
mg: "咪咕体育",
|
||||||
nba: '高清原声',
|
nba: "高清原声",
|
||||||
zb: '高清直播'
|
zb: "高清直播",
|
||||||
}
|
};
|
||||||
return names[type] || type
|
return names[type] || type;
|
||||||
}
|
};
|
||||||
|
|
||||||
// 返回赛程页
|
// 返回赛程页
|
||||||
const goBack = () => {
|
const goBack = () => {
|
||||||
gameStore.clearGameData()
|
gameStore.clearGameData();
|
||||||
router.go(-1)
|
router.go(-1);
|
||||||
}
|
};
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
// 默认选择第一个直播源
|
// 默认选择第一个直播源
|
||||||
if (allStreams.value.length > 0 && !currentStream.value) {
|
if (allStreams.value.length > 0 && !currentStream.value) {
|
||||||
currentStream.value = allStreams.value[0]
|
currentStream.value = allStreams.value[0];
|
||||||
}
|
}
|
||||||
initPlayer()
|
initPlayer();
|
||||||
})
|
});
|
||||||
|
|
||||||
onBeforeUnmount(() => {
|
onBeforeUnmount(() => {
|
||||||
if (dpInstance.value) {
|
if (dpInstance.value) {
|
||||||
dpInstance.value.destroy()
|
dpInstance.value.destroy();
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
.live-stream-container {
|
.live-stream-container {
|
||||||
max-width: 1200px;
|
max-width: 1200px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 20px;
|
// padding: 20px;
|
||||||
background: #f5f5f5;
|
background: #f5f5f5;
|
||||||
min-height: 100vh;
|
min-height: 100vh;
|
||||||
}
|
}
|
||||||
@@ -161,6 +216,7 @@ onBeforeUnmount(() => {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 40px;
|
gap: 40px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
margin-top: 20px;
|
||||||
background: white;
|
background: white;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
@@ -203,7 +259,7 @@ onBeforeUnmount(() => {
|
|||||||
.vs-circle {
|
.vs-circle {
|
||||||
width: 50px;
|
width: 50px;
|
||||||
height: 50px;
|
height: 50px;
|
||||||
background: #e74c3c;
|
background: #f29155;
|
||||||
color: white;
|
color: white;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
display: flex;
|
display: flex;
|
||||||
@@ -281,8 +337,40 @@ onBeforeUnmount(() => {
|
|||||||
|
|
||||||
@media (max-width: 768px) {
|
@media (max-width: 768px) {
|
||||||
.game-header {
|
.game-header {
|
||||||
flex-direction: column;
|
// flex-direction: column;
|
||||||
gap: 20px;
|
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 {
|
.vs-circle {
|
||||||
|
|||||||
@@ -122,10 +122,11 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="live-buttons">
|
<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)">
|
<template v-if="hasLiveStreams(game.gameId)">
|
||||||
<!-- 直播按钮 -->
|
|
||||||
<button
|
<button
|
||||||
v-for="stream in getLiveStreams(game.gameId)"
|
v-for="stream in getLiveStreams(game.gameId)"
|
||||||
:key="stream.type"
|
:key="stream.type"
|
||||||
@@ -138,9 +139,16 @@
|
|||||||
</template>
|
</template>
|
||||||
<div v-else class="no-live">无直播信号</div>
|
<div v-else class="no-live">无直播信号</div>
|
||||||
</template>
|
</template>
|
||||||
|
<!-- 非当天进行中比赛(理论上不应该存在) -->
|
||||||
|
<div v-else class="no-live">比赛进行中</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- 已结束的比赛(无论是否当天) -->
|
||||||
<div v-else-if="game.status === 3" class="no-live">
|
<div v-else-if="game.status === 3" class="no-live">
|
||||||
比赛已结束
|
比赛已结束
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- 未开始的比赛 -->
|
||||||
<div v-else class="no-live">未开始</div>
|
<div v-else class="no-live">未开始</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@@ -175,38 +183,26 @@ const gameStore = useGameStore();
|
|||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const urlsData = ref([]);
|
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 () => {
|
onMounted(async () => {
|
||||||
try {
|
try {
|
||||||
const response = await urls();
|
const response = await urls();
|
||||||
urlsData.value = response || [];
|
urlsData.value = response || [];
|
||||||
// console.log("获取的直播URL数据:", urlsData.value); // 检查数据是否正确
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("获取直播URL失败:", err);
|
console.error("获取直播URL失败:", err);
|
||||||
urlsData.value = [];
|
urlsData.value = [];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// 判断是否为当天进行中的比赛
|
// 判断是否为当天比赛(无论状态如何)
|
||||||
const isLiveGame = (game) => {
|
const isTodayGame = (game) => {
|
||||||
const isLive = game.status === 2; // 假设2表示进行中
|
// 获取今天的日期(北京时间)
|
||||||
const gameDate = new Date(game.dateTimeUtc);
|
|
||||||
const today = new Date();
|
const today = new Date();
|
||||||
const isToday = gameDate.toDateString() === today.toDateString();
|
const todayStr = `${today.getFullYear()}-${(today.getMonth() + 1)
|
||||||
return isLive && isToday;
|
.toString()
|
||||||
|
.padStart(2, "0")}-${today.getDate().toString().padStart(2, "0")}`;
|
||||||
|
|
||||||
|
// 直接比较 startDate(已经是北京时间)
|
||||||
|
return game.startDate === todayStr;
|
||||||
};
|
};
|
||||||
|
|
||||||
// 检查比赛是否有直播流
|
// 检查比赛是否有直播流
|
||||||
@@ -239,7 +235,6 @@ const getStreamName = (type) => {
|
|||||||
nba: "高清原声",
|
nba: "高清原声",
|
||||||
mg: "咪咕体育",
|
mg: "咪咕体育",
|
||||||
zb: "高清直播",
|
zb: "高清直播",
|
||||||
// 可以添加更多类型
|
|
||||||
};
|
};
|
||||||
return names[type] || type;
|
return names[type] || type;
|
||||||
};
|
};
|
||||||
@@ -299,7 +294,6 @@ const props = defineProps({
|
|||||||
|
|
||||||
const emit = defineEmits(["dateChange"]);
|
const emit = defineEmits(["dateChange"]);
|
||||||
|
|
||||||
// 当前显示日期
|
|
||||||
// 当前显示日期(带星期几)
|
// 当前显示日期(带星期几)
|
||||||
const currentDisplayDate = computed(() => {
|
const currentDisplayDate = computed(() => {
|
||||||
if (!props.scheduleData?.data?.start) return "加载中...";
|
if (!props.scheduleData?.data?.start) return "加载中...";
|
||||||
@@ -370,7 +364,7 @@ const isWinner = (game, teamType) => {
|
|||||||
if (game.status !== 3) return false;
|
if (game.status !== 3) return false;
|
||||||
|
|
||||||
// 比较比分
|
// 比较比分
|
||||||
if (teamType === 'away') {
|
if (teamType === "away") {
|
||||||
return game.awayTeamScore > game.homeTeamScore;
|
return game.awayTeamScore > game.homeTeamScore;
|
||||||
} else {
|
} else {
|
||||||
return game.homeTeamScore > game.awayTeamScore;
|
return game.homeTeamScore > game.awayTeamScore;
|
||||||
@@ -754,11 +748,11 @@ const isWinner = (game, teamType) => {
|
|||||||
/* 如果希望更明显的效果,可以调整样式 */
|
/* 如果希望更明显的效果,可以调整样式 */
|
||||||
.team.winner .team-name {
|
.team.winner .team-name {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #2E7D32; /* 深绿色文字 */
|
color: #2e7d32; /* 深绿色文字 */
|
||||||
}
|
}
|
||||||
|
|
||||||
.team.winner .team-score {
|
.team.winner .team-score {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: #2E7D32; /* 深绿色比分 */
|
color: #2e7d32; /* 深绿色比分 */
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user