hookehuyr

feat(播放器): 实现音视频互斥播放功能并优化默认封面

在VideoPlayer和AudioPlayer组件中添加互斥播放逻辑,当播放视频时自动暂停音频,反之亦然
为音频播放器添加默认封面图片
更新所有测试图片和音频资源URL为正式CDN地址
添加组件卸载时的清理逻辑
1 <!-- 1 <!--
2 * @Date: 2025-04-07 12:35:35 2 * @Date: 2025-04-07 12:35:35
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-05-16 16:50:23 4 + * @LastEditTime: 2025-05-30 15:26:15
5 * @FilePath: /mlaj/src/components/ui/AudioPlayer.vue 5 * @FilePath: /mlaj/src/components/ui/AudioPlayer.vue
6 * @Description: 音频播放器组件,支持播放控制、进度条调节、音量控制、播放列表等功能 6 * @Description: 音频播放器组件,支持播放控制、进度条调节、音量控制、播放列表等功能
7 --> 7 -->
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
12 <div class="flex flex-col items-center mb-4"> 12 <div class="flex flex-col items-center mb-4">
13 <!-- 歌曲封面 --> 13 <!-- 歌曲封面 -->
14 <div class="w-24 h-24 rounded-lg overflow-hidden mb-2"> 14 <div class="w-24 h-24 rounded-lg overflow-hidden mb-2">
15 - <img :src="currentSong?.cover" alt="封面" class="w-full h-full object-cover"> 15 + <img :src="currentSong?.cover ? currentSong?.cover : 'https://cdn.ipadbiz.cn/mlaj/images/audio_d_cover.jpg'" alt="封面" class="w-full h-full object-cover">
16 </div> 16 </div>
17 17
18 <!-- 歌曲信息 --> 18 <!-- 歌曲信息 -->
...@@ -105,7 +105,7 @@ ...@@ -105,7 +105,7 @@
105 > 105 >
106 <div class="absolute top-0 left-0 right-0 h-[1px] bg-gray-200"></div> 106 <div class="absolute top-0 left-0 right-0 h-[1px] bg-gray-200"></div>
107 <div class="w-16 h-16 rounded-lg overflow-hidden mr-4 flex-shrink-0"> 107 <div class="w-16 h-16 rounded-lg overflow-hidden mr-4 flex-shrink-0">
108 - <img :src="song?.cover" alt="封面" class="w-full h-full object-cover"> 108 + <img :src="song?.cover ? song?.cover : 'https://cdn.ipadbiz.cn/mlaj/images/audio_d_cover.jpg'" alt="封面" class="w-full h-full object-cover">
109 </div> 109 </div>
110 <div class="flex-1"> 110 <div class="flex-1">
111 <div class="font-medium">{{ song?.title }}</div> 111 <div class="font-medium">{{ song?.title }}</div>
...@@ -177,6 +177,9 @@ const loadAudio = async () => { ...@@ -177,6 +177,9 @@ const loadAudio = async () => {
177 } 177 }
178 } 178 }
179 179
180 +// 定义组件事件
181 +const emit = defineEmits(['play', 'pause'])
182 +
180 // 播放控制:切换播放/暂停状态 183 // 播放控制:切换播放/暂停状态
181 const togglePlay = async () => { 184 const togglePlay = async () => {
182 if (isLoading.value) return 185 if (isLoading.value) return
...@@ -186,8 +189,10 @@ const togglePlay = async () => { ...@@ -186,8 +189,10 @@ const togglePlay = async () => {
186 } 189 }
187 if (isPlaying.value) { 190 if (isPlaying.value) {
188 await audio.value?.pause() 191 await audio.value?.pause()
192 + emit('pause', audio.value)
189 } else { 193 } else {
190 await audio.value?.play() 194 await audio.value?.play()
195 + emit('play', audio.value)
191 } 196 }
192 isPlaying.value = !isPlaying.value 197 isPlaying.value = !isPlaying.value
193 } catch (error) { 198 } catch (error) {
...@@ -195,6 +200,19 @@ const togglePlay = async () => { ...@@ -195,6 +200,19 @@ const togglePlay = async () => {
195 } 200 }
196 } 201 }
197 202
203 +// 暴露给父组件的方法
204 +defineExpose({
205 + togglePlay,
206 + pause: () => {
207 + if (isPlaying.value && audio.value) {
208 + audio.value.pause();
209 + isPlaying.value = false;
210 + emit('pause', audio.value);
211 + }
212 + },
213 + isPlaying: () => isPlaying.value
214 +})
215 +
198 // 进度更新 216 // 进度更新
199 const updateProgress = () => { 217 const updateProgress = () => {
200 if (!audio.value) return 218 if (!audio.value) return
...@@ -223,6 +241,8 @@ const prevSong = async () => { ...@@ -223,6 +241,8 @@ const prevSong = async () => {
223 const normalizedVolume = Math.pow(volume.value / 100, 2) 241 const normalizedVolume = Math.pow(volume.value / 100, 2)
224 audio.value.volume = normalizedVolume 242 audio.value.volume = normalizedVolume
225 isPlaying.value = true 243 isPlaying.value = true
244 + // 发射播放事件
245 + emit('play', audio.value)
226 } 246 }
227 } 247 }
228 248
...@@ -241,6 +261,8 @@ const nextSong = async () => { ...@@ -241,6 +261,8 @@ const nextSong = async () => {
241 const normalizedVolume = Math.pow(volume.value / 100, 2) 261 const normalizedVolume = Math.pow(volume.value / 100, 2)
242 audio.value.volume = normalizedVolume 262 audio.value.volume = normalizedVolume
243 isPlaying.value = true 263 isPlaying.value = true
264 + // 发射播放事件
265 + emit('play', audio.value)
244 } 266 }
245 } 267 }
246 268
...@@ -312,6 +334,8 @@ const selectSong = async (index) => { ...@@ -312,6 +334,8 @@ const selectSong = async (index) => {
312 if (audio.value) { 334 if (audio.value) {
313 await audio.value.play() 335 await audio.value.play()
314 isPlaying.value = true 336 isPlaying.value = true
337 + // 发射播放事件
338 + emit('play', audio.value)
315 // 关闭播放列表 339 // 关闭播放列表
316 isPlaylistVisible.value = false 340 isPlaylistVisible.value = false
317 // 滚动到当前播放的音频 341 // 滚动到当前播放的音频
......
...@@ -119,12 +119,12 @@ onBeforeUnmount(() => { ...@@ -119,12 +119,12 @@ onBeforeUnmount(() => {
119 defineExpose({ 119 defineExpose({
120 pause() { 120 pause() {
121 if (player.value) { 121 if (player.value) {
122 - player.value.pause(); 122 + player.value?.pause();
123 } 123 }
124 }, 124 },
125 play() { 125 play() {
126 if (player.value) { 126 if (player.value) {
127 - player.value.play(); 127 + player.value?.play();
128 } 128 }
129 }, 129 },
130 }); 130 });
......
1 <!-- 1 <!--
2 * @Date: 2025-05-29 15:34:17 2 * @Date: 2025-05-29 15:34:17
3 * @LastEditors: hookehuyr hookehuyr@gmail.com 3 * @LastEditors: hookehuyr hookehuyr@gmail.com
4 - * @LastEditTime: 2025-05-30 15:11:36 4 + * @LastEditTime: 2025-05-30 15:54:33
5 * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue 5 * @FilePath: /mlaj/src/views/checkin/IndexCheckInPage.vue
6 * @Description: 文件描述 6 * @Description: 文件描述
7 --> 7 -->
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
38 <van-progress :percentage="progress2" color="#4caf50" :show-pivot="false" /> 38 <van-progress :percentage="progress2" color="#4caf50" :show-pivot="false" />
39 </div> 39 </div>
40 <div style="padding: 0.75rem 1rem;"> 40 <div style="padding: 0.75rem 1rem;">
41 - <van-image round width="2.8rem" height="2.8rem" src="https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg" 41 + <van-image round width="2.8rem" height="2.8rem" src="https://cdn.ipadbiz.cn/space/816560/大国少年_FhnF8lsFMPnTDNTBlM6hYa-UFBlW.jpg"
42 v-for="(item, index) in teamAvatars" :key="index" 42 v-for="(item, index) in teamAvatars" :key="index"
43 :style="{ marginLeft: index > 0 ? '-0.5rem' : '', border: '2px solid #FFF' }" /> 43 :style="{ marginLeft: index > 0 ? '-0.5rem' : '', border: '2px solid #FFF' }" />
44 </div> 44 </div>
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
86 <!-- 视频封面和播放按钮 --> 86 <!-- 视频封面和播放按钮 -->
87 <div v-if="post.video && !post.isPlaying" class="relative w-full rounded-lg overflow-hidden" 87 <div v-if="post.video && !post.isPlaying" class="relative w-full rounded-lg overflow-hidden"
88 style="aspect-ratio: 16/9;"> 88 style="aspect-ratio: 16/9;">
89 - <img :src="post.videoCover || 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg'" 89 + <img :src="post.videoCover || 'https://cdn.ipadbiz.cn/space/816560/大国少年_FhnF8lsFMPnTDNTBlM6hYa-UFBlW.jpg'"
90 :alt="post.content" class="w-full h-full object-cover" /> 90 :alt="post.content" class="w-full h-full object-cover" />
91 <div class="absolute inset-0 flex items-center justify-center cursor-pointer bg-black/20" 91 <div class="absolute inset-0 flex items-center justify-center cursor-pointer bg-black/20"
92 @click="startPlay(post)"> 92 @click="startPlay(post)">
...@@ -98,9 +98,31 @@ ...@@ -98,9 +98,31 @@
98 </div> 98 </div>
99 <!-- 视频播放器 --> 99 <!-- 视频播放器 -->
100 <VideoPlayer v-if="post.video && post.isPlaying" :video-url="post.video" 100 <VideoPlayer v-if="post.video && post.isPlaying" :video-url="post.video"
101 - class="post-video rounded-lg overflow-hidden" ref="(el) => { if(el) videoPlayers.value.push(el) }" 101 + class="post-video rounded-lg overflow-hidden"
102 - @onPlay="(player) => handleVideoPlay(player, post)" @onPause="() => handleVideoPause(post)" /> 102 + :ref="el => {
103 - <AudioPlayer v-if="post.audio.length" :songs="post.audio" class="post-audio" /> 103 + if(el) {
104 + // 确保不重复添加
105 + if (!videoPlayers?.includes(el)) {
106 + videoPlayers?.push(el);
107 + }
108 + }
109 + }"
110 + @onPlay="(player) => handleVideoPlay(player, post)"
111 + @onPause="() => handleVideoPause(post)" />
112 + <AudioPlayer
113 + v-if="post.audio.length"
114 + :songs="post.audio"
115 + class="post-audio"
116 + :ref="el => {
117 + if(el) {
118 + // 确保不重复添加
119 + if (!audioPlayers?.includes(el)) {
120 + audioPlayers?.push(el);
121 + }
122 + }
123 + }"
124 + @play="(player) => handleAudioPlay(player, post)"
125 + />
104 </div> 126 </div>
105 </div> 127 </div>
106 <div class="post-footer"> 128 <div class="post-footer">
...@@ -116,7 +138,7 @@ ...@@ -116,7 +138,7 @@
116 </template> 138 </template>
117 139
118 <script setup> 140 <script setup>
119 -import { ref } from 'vue' 141 +import { ref, onBeforeUnmount } from 'vue'
120 import { useRoute, useRouter } from 'vue-router' 142 import { useRoute, useRouter } from 'vue-router'
121 import AppLayout from "@/components/layout/AppLayout.vue"; 143 import AppLayout from "@/components/layout/AppLayout.vue";
122 import FrostedGlass from "@/components/ui/FrostedGlass.vue"; 144 import FrostedGlass from "@/components/ui/FrostedGlass.vue";
...@@ -126,17 +148,43 @@ import AudioPlayer from "@/components/ui/AudioPlayer.vue"; ...@@ -126,17 +148,43 @@ import AudioPlayer from "@/components/ui/AudioPlayer.vue";
126 // 存储所有视频播放器的引用 148 // 存储所有视频播放器的引用
127 const videoPlayers = ref([]); 149 const videoPlayers = ref([]);
128 150
151 +// 存储所有音频播放器的引用
152 +const audioPlayers = ref([]);
153 +
154 +// 组件卸载前清理播放器引用
155 +onBeforeUnmount(() => {
156 + // 停止所有视频和音频播放
157 + if (videoPlayers.value) {
158 + videoPlayers.value.forEach(player => {
159 + if (player && typeof player.pause === 'function') {
160 + player.pause();
161 + }
162 + });
163 + }
164 +
165 + stopAllAudio();
166 +
167 + // 清空引用数组
168 + if (videoPlayers.value) videoPlayers.value = [];
169 + if (audioPlayers.value) audioPlayers.value = [];
170 +
171 +});
172 +
173 +
129 /** 174 /**
130 * 开始播放指定帖子的视频 175 * 开始播放指定帖子的视频
131 * @param {Object} post - 要播放视频的帖子对象 176 * @param {Object} post - 要播放视频的帖子对象
132 */ 177 */
133 const startPlay = (post) => { 178 const startPlay = (post) => {
179 + // 确保mockPosts.value是一个数组
180 + if (mockPosts.value) {
134 // 先暂停所有其他视频 181 // 先暂停所有其他视频
135 mockPosts.value.forEach(p => { 182 mockPosts.value.forEach(p => {
136 if (p.id !== post.id) { 183 if (p.id !== post.id) {
137 p.isPlaying = false; 184 p.isPlaying = false;
138 } 185 }
139 }); 186 });
187 + }
140 188
141 // 设置当前视频为播放状态 189 // 设置当前视频为播放状态
142 post.isPlaying = true; 190 post.isPlaying = true;
...@@ -167,12 +215,15 @@ const handleVideoPause = (post) => { ...@@ -167,12 +215,15 @@ const handleVideoPause = (post) => {
167 * @param {Object} currentPost - 当前播放的帖子对象 215 * @param {Object} currentPost - 当前播放的帖子对象
168 */ 216 */
169 const stopOtherVideos = (currentPlayer, currentPost) => { 217 const stopOtherVideos = (currentPlayer, currentPost) => {
218 + // 确保videoPlayers.value是一个数组
219 + if (videoPlayers.value) {
170 // 暂停其他视频播放器 220 // 暂停其他视频播放器
171 videoPlayers.value.forEach(player => { 221 videoPlayers.value.forEach(player => {
172 if (player !== currentPlayer && player.pause) { 222 if (player !== currentPlayer && player.pause) {
173 player.pause(); 223 player.pause();
174 } 224 }
175 }); 225 });
226 + }
176 227
177 // 更新其他帖子的播放状态 228 // 更新其他帖子的播放状态
178 mockPosts.value.forEach(post => { 229 mockPosts.value.forEach(post => {
...@@ -180,6 +231,91 @@ const stopOtherVideos = (currentPlayer, currentPost) => { ...@@ -180,6 +231,91 @@ const stopOtherVideos = (currentPlayer, currentPost) => {
180 post.isPlaying = false; 231 post.isPlaying = false;
181 } 232 }
182 }); 233 });
234 +
235 + // 同时暂停所有音频播放器
236 + stopAllAudio();
237 +};
238 +
239 +/**
240 + * 处理音频播放事件
241 + * @param {Object} player - 音频播放器实例
242 + * @param {Object} post - 包含音频的帖子对象
243 + */
244 +const handleAudioPlay = (player, post) => {
245 + // 停止其他音频播放
246 + stopOtherAudio(player, post);
247 +
248 + // 同时暂停所有视频
249 + if (videoPlayers.value) {
250 + videoPlayers.value.forEach(videoPlayer => {
251 + if (videoPlayer.pause) {
252 + videoPlayer.pause();
253 + }
254 + });
255 + }
256 +
257 + // 更新所有视频的播放状态为false
258 + mockPosts.value.forEach(p => {
259 + p.isPlaying = false;
260 + });
261 +};
262 +
263 +/**
264 + * 停止除当前播放器外的所有其他音频
265 + * @param {Object} currentPlayer - 当前播放的音频播放器实例
266 + * @param {Object} currentPost - 当前播放的帖子对象
267 + */
268 +const stopOtherAudio = (currentPlayer, currentPost) => {
269 + // 确保audioPlayers.value是一个数组
270 + if (!audioPlayers.value) return;
271 +
272 + // 暂停其他音频播放器
273 + audioPlayers.value.forEach(player => {
274 + // 只处理不是当前播放器的实例
275 + if (player !== currentPlayer) {
276 + // 使用组件暴露的pause方法
277 + if (typeof player.pause === 'function') {
278 + player.pause();
279 + }
280 + // 如果没有pause方法,尝试使用togglePlay方法
281 + else if (typeof player.togglePlay === 'function' && player.isPlaying && player.isPlaying()) {
282 + player.togglePlay();
283 + }
284 + // 最后尝试直接操作DOM
285 + else if (player.$el && player.$el.querySelector('audio')) {
286 + const audioElement = player.$el.querySelector('audio');
287 + if (audioElement) {
288 + audioElement.pause();
289 + }
290 + }
291 + }
292 + });
293 +};
294 +
295 +/**
296 + * 停止所有音频播放
297 + */
298 +const stopAllAudio = () => {
299 + // 确保audioPlayers.value是一个数组
300 + if (!audioPlayers.value) return;
301 +
302 + audioPlayers.value.forEach(player => {
303 + // 使用组件暴露的pause方法
304 + if (typeof player.pause === 'function') {
305 + player.pause();
306 + }
307 + // 如果没有pause方法,尝试使用togglePlay方法
308 + else if (typeof player.togglePlay === 'function' && player.isPlaying && player.isPlaying()) {
309 + player.togglePlay();
310 + }
311 + // 最后尝试直接操作DOM
312 + else if (player.$el && player.$el.querySelector('audio')) {
313 + const audioElement = player.$el.querySelector('audio');
314 + if (audioElement) {
315 + audioElement.pause();
316 + }
317 + }
318 + });
183 }; 319 };
184 320
185 // Mock数据 321 // Mock数据
...@@ -187,8 +323,8 @@ const mockPosts = ref([ ...@@ -187,8 +323,8 @@ const mockPosts = ref([
187 { 323 {
188 id: 1, 324 id: 1,
189 user: { 325 user: {
190 - name: '小林', 326 + name: '图片预览',
191 - avatar: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg', 327 + avatar: 'https://cdn.ipadbiz.cn/space/816560/大国少年_FhnF8lsFMPnTDNTBlM6hYa-UFBlW.jpg',
192 time: '2小时前' 328 time: '2小时前'
193 }, 329 },
194 content: '今天完成了React基础课程的学习,收获满满!', 330 content: '今天完成了React基础课程的学习,收获满满!',
...@@ -208,13 +344,13 @@ const mockPosts = ref([ ...@@ -208,13 +344,13 @@ const mockPosts = ref([
208 id: 2, 344 id: 2,
209 user: { 345 user: {
210 name: '小林', 346 name: '小林',
211 - avatar: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg', 347 + avatar: 'https://cdn.ipadbiz.cn/space/816560/大国少年_FhnF8lsFMPnTDNTBlM6hYa-UFBlW.jpg',
212 time: '2小时前' 348 time: '2小时前'
213 }, 349 },
214 content: '今天完成了React基础课程的学习,收获满满!', 350 content: '今天完成了React基础课程的学习,收获满满!',
215 images: [], 351 images: [],
216 video: 'https://cdn.ipadbiz.cn/space/lk3DmvLO02dUC2zPiFwiClDe3nKL.mp4', 352 video: 'https://cdn.ipadbiz.cn/space/lk3DmvLO02dUC2zPiFwiClDe3nKL.mp4',
217 - videoCover: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg', 353 + videoCover: 'https://cdn.ipadbiz.cn/space/816560/大国少年_FhnF8lsFMPnTDNTBlM6hYa-UFBlW.jpg',
218 isPlaying: false, 354 isPlaying: false,
219 audio: [], 355 audio: [],
220 likes: 12 356 likes: 12
...@@ -223,7 +359,7 @@ const mockPosts = ref([ ...@@ -223,7 +359,7 @@ const mockPosts = ref([
223 id: 3, 359 id: 3,
224 user: { 360 user: {
225 name: '小林', 361 name: '小林',
226 - avatar: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg', 362 + avatar: 'https://cdn.ipadbiz.cn/space/816560/大国少年_FhnF8lsFMPnTDNTBlM6hYa-UFBlW.jpg',
227 time: '2小时前' 363 time: '2小时前'
228 }, 364 },
229 content: '今天完成了React基础课程的学习,收获满满!', 365 content: '今天完成了React基础课程的学习,收获满满!',
...@@ -235,8 +371,8 @@ const mockPosts = ref([ ...@@ -235,8 +371,8 @@ const mockPosts = ref([
235 { 371 {
236 title: '学习心得分享', 372 title: '学习心得分享',
237 artist: '小林', 373 artist: '小林',
238 - url: 'https://example.com/audio.mp3', 374 + url: 'https://cdn.ipadbiz.cn/space/816560/双手合十迎客来_Fs2W-5mnQSFL8S5CDsHho-_xcvaY.mp3',
239 - cover: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg' 375 + cover: 'https://cdn.ipadbiz.cn/space/816560/大国少年_FhnF8lsFMPnTDNTBlM6hYa-UFBlW.jpg'
240 } 376 }
241 ], 377 ],
242 likes: 12 378 likes: 12
...@@ -245,17 +381,39 @@ const mockPosts = ref([ ...@@ -245,17 +381,39 @@ const mockPosts = ref([
245 id: 4, 381 id: 4,
246 user: { 382 user: {
247 name: '小林', 383 name: '小林',
248 - avatar: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg', 384 + avatar: 'https://cdn.ipadbiz.cn/space/816560/大国少年_FhnF8lsFMPnTDNTBlM6hYa-UFBlW.jpg',
249 time: '2小时前' 385 time: '2小时前'
250 }, 386 },
251 content: '今天完成了React基础课程的学习,收获满满!', 387 content: '今天完成了React基础课程的学习,收获满满!',
252 images: [], 388 images: [],
253 video: 'https://cdn.ipadbiz.cn/space/lk3DmvLO02dUC2zPiFwiClDe3nKL.mp4', 389 video: 'https://cdn.ipadbiz.cn/space/lk3DmvLO02dUC2zPiFwiClDe3nKL.mp4',
254 - videoCover: 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg', 390 + videoCover: 'https://cdn.ipadbiz.cn/space/816560/大国少年_FhnF8lsFMPnTDNTBlM6hYa-UFBlW.jpg',
255 isPlaying: false, 391 isPlaying: false,
256 audio: [], 392 audio: [],
257 likes: 12 393 likes: 12
258 }, 394 },
395 + {
396 + id: 5,
397 + user: {
398 + name: '小林',
399 + avatar: 'https://cdn.ipadbiz.cn/space/816560/大国少年_FhnF8lsFMPnTDNTBlM6hYa-UFBlW.jpg',
400 + time: '2小时前'
401 + },
402 + content: '今天完成了React基础课程的学习,收获满满!',
403 + images: [],
404 + video: '',
405 + videoCover: '',
406 + isPlaying: false,
407 + audio: [
408 + {
409 + title: '学习心得分享',
410 + artist: '小林',
411 + url: 'https://cdn.ipadbiz.cn/space/816560/双手合十迎客来_Fs2W-5mnQSFL8S5CDsHho-_xcvaY.mp3',
412 + cover: 'https://cdn.ipadbiz.cn/space/816560/大国少年_FhnF8lsFMPnTDNTBlM6hYa-UFBlW.jpg'
413 + }
414 + ],
415 + likes: 12
416 + },
259 ]); 417 ]);
260 418
261 const themeVars = { 419 const themeVars = {
...@@ -266,10 +424,10 @@ const progress1 = ref(50); ...@@ -266,10 +424,10 @@ const progress1 = ref(50);
266 const progress2 = ref(76); 424 const progress2 = ref(76);
267 425
268 const teamAvatars = ref([ 426 const teamAvatars = ref([
269 - 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg', 427 + 'https://cdn.ipadbiz.cn/space/816560/大国少年_FhnF8lsFMPnTDNTBlM6hYa-UFBlW.jpg',
270 - 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg', 428 + 'https://cdn.ipadbiz.cn/space/816560/大国少年_FhnF8lsFMPnTDNTBlM6hYa-UFBlW.jpg',
271 - 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg', 429 + 'https://cdn.ipadbiz.cn/space/816560/大国少年_FhnF8lsFMPnTDNTBlM6hYa-UFBlW.jpg',
272 - 'https://fastly.jsdelivr.net/npm/@vant/assets/cat.jpeg' 430 + 'https://cdn.ipadbiz.cn/space/816560/大国少年_FhnF8lsFMPnTDNTBlM6hYa-UFBlW.jpg'
273 ]) 431 ])
274 432
275 // 图片预览相关 433 // 图片预览相关
......