hookehuyr

feat(课程详情): 添加音频播放器支持并优化课程类型显示

在课程详情页中增加对音频课程的支持,添加音频播放器组件。同时,优化课程类型显示逻辑,将课程类型统一为英文标识(video/audio),并在前端显示时转换为中文。此外,调整了音频播放器的样式和布局,以提升用户体验。
......@@ -11,7 +11,7 @@
<van-image :src="course.thumbnail" width="120" height="100%" fit="cover" class="item-cover">
<div class="absolute bg-white/80 px-2 py-0.5 text-xs rounded"
style="right: 0.25rem; bottom: 0.5rem">
{{ course.type }}
{{ course.type === 'video' ? '视频' : '音频' }}
</div>
</van-image>
</div>
......
......@@ -7,29 +7,27 @@
-->
<template>
<!-- 音频播放器主容器 -->
<div class="audio-player bg-white rounded-lg shadow-xl overflow-hidden max-w-md mx-auto p-4">
<div class="audio-player bg-white rounded-lg shadow-xl overflow-hidden max-w-md mx-auto p-2">
<!-- 封面与歌曲信息 -->
<div class="flex flex-col items-center mb-6">
<div class="flex flex-col items-center mb-4">
<!-- 歌曲封面 -->
<div class="w-48 h-48 rounded-lg overflow-hidden mb-4">
<div class="w-24 h-24 rounded-lg overflow-hidden mb-2">
<img :src="currentSong.cover" alt="封面" class="w-full h-full object-cover">
</div>
<!-- 歌曲信息 -->
<div class="text-center">
<h3 class="text-lg font-medium">{{ currentSong.title }}</h3>
<p class="text-sm text-gray-500">{{ currentSong.artist }}</p>
<h3 class="text-base font-medium">{{ currentSong.title }}</h3>
<p class="text-xs text-gray-500">{{ currentSong.artist }}</p>
</div>
</div>
<!-- 进度条与时间:显示当前播放时间、总时长和可拖动的进度条 -->
<div class="mt-4 mb-6">
<div class="flex items-center justify-between text-xs text-gray-400 mb-2">
<span>{{ formatTime(currentTime) }}</span>
<span>{{ formatTime(duration) }}</span>
</div>
<div class="progress-bar relative h-1 bg-gray-200 rounded-full">
<div class="flex items-center space-x-4">
<span class="text-xs text-gray-400 w-12 text-right">{{ formatTime(currentTime) }}</span>
<div class="progress-bar relative h-1 bg-gray-200 rounded-full flex-1">
<input
type="range"
:value="progress"
......@@ -42,21 +40,23 @@
class="progress-track absolute left-0 top-0 h-full rounded-full bg-gradient-to-r from-blue-500 to-purple-500 transition-all"
></div>
</div>
<span class="text-xs text-gray-400 w-12">{{ formatTime(duration) }}</span>
</div>
</div>
<!-- 播放控制按钮组:上一首、播放/暂停、下一首 -->
<div class="flex items-center space-x-16 mt-6" style="justify-content: space-evenly;">
<div class="flex items-center space-x-12 mt-4" style="justify-content: space-evenly;">
<button
@click="prevSong"
class="w-14 h-14 flex items-center justify-center rounded-full bg-gray-100 hover:bg-gray-200 transition-colors"
class="w-10 h-10 flex items-center justify-center rounded-full bg-gray-100 hover:bg-gray-200 transition-colors"
>
<font-awesome-icon icon="backward-step" class="text-2xl text-gray-600" />
<font-awesome-icon icon="backward-step" class="text-xl text-gray-600" />
</button>
<button
@click="togglePlay"
:class="{'paused': !isPlaying, 'opacity-50 cursor-not-allowed': isLoading}"
:disabled="isLoading"
class="w-14 h-14 flex items-center justify-center rounded-full bg-blue-500 hover:bg-blue-600 transition-colors shadow-lg"
class="w-12 h-12 flex items-center justify-center rounded-full bg-blue-500 hover:bg-blue-600 transition-colors shadow-lg"
>
<font-awesome-icon
:icon="['fas' , isPlaying ? 'pause' : 'play']"
......@@ -66,9 +66,9 @@
</button>
<button
@click="nextSong"
class="w-14 h-14 flex items-center justify-center rounded-full bg-gray-100 hover:bg-gray-200 transition-colors"
class="w-10 h-10 flex items-center justify-center rounded-full bg-gray-100 hover:bg-gray-200 transition-colors"
>
<font-awesome-icon icon="forward-step" class="text-2xl text-gray-600" />
<font-awesome-icon icon="forward-step" class="text-xl text-gray-600" />
</button>
</div>
......@@ -112,7 +112,7 @@
<div class="text-sm text-gray-500">{{ song.artist }}</div>
</div>
<font-awesome-icon
v-if="index === currentIndex"
v-if="index === currentIndex && isPlaying"
icon="volume-up"
class="text-blue-500 ml-2"
/>
......@@ -281,8 +281,13 @@ watch(() => props.songs, () => {
// 组件卸载时清理事件监听
onUnmounted(() => {
audio.value?.removeEventListener('timeupdate', updateProgress)
audio.value?.removeEventListener('ended', handleEnded)
if (audio.value) {
audio.value.pause();
audio.value.removeEventListener('timeupdate', updateProgress);
audio.value.removeEventListener('ended', handleEnded);
audio.value = null;
}
isPlaying.value = false;
})
// 播放列表相关方法
......
This diff is collapsed. Click to expand it.
......@@ -100,7 +100,7 @@ const columnCourses = ref([
{
id: 1,
title: "考前赋能冥想",
type: "视频",
type: "video",
thumbnail: "https://cdn.ipadbiz.cn/mlaj/images/zMRLZh40kms.jpg",
progress: 100,
duration: 1200, // 20分钟
......@@ -109,7 +109,7 @@ const columnCourses = ref([
{
id: 2,
title: "开学礼·让的智慧·心法老师·20241001(上)",
type: "视频",
type: "audio",
thumbnail: "https://cdn.ipadbiz.cn/mlaj/images/zMRLZh40kms.jpg",
progress: 1,
duration: 3600, // 1小时
......@@ -118,7 +118,7 @@ const columnCourses = ref([
{
id: 1,
title: "考前赋能冥想",
type: "视频",
type: "video",
thumbnail: "https://cdn.ipadbiz.cn/mlaj/images/zMRLZh40kms.jpg",
progress: 100,
duration: 1200, // 20分钟
......@@ -127,7 +127,7 @@ const columnCourses = ref([
{
id: 2,
title: "开学礼·让的智慧·心法老师·20241001(上)",
type: "视频",
type: "video",
thumbnail: "https://cdn.ipadbiz.cn/mlaj/images/zMRLZh40kms.jpg",
progress: 1,
duration: 3600, // 1小时
......@@ -139,7 +139,7 @@ const singleCourses = ref([
{
id: 3,
title: "冬季课·影响孩子命运的家族六要素·心法老师20250207",
type: "视频",
type: "video",
thumbnail: "https://cdn.ipadbiz.cn/mlaj/images/zMRLZh40kms.jpg",
progress: 1,
duration: 3600,
......