723 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Vue
		
	
	
	
		
		
			
		
	
	
			723 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			Vue
		
	
	
	
|  | <template> | |||
|  |   <!-- 视频、图片 动态卡片 --> | |||
|  |   <view class="content-card"> | |||
|  |     <!-- 用户信息 --> | |||
|  |     <view class="user-info"> | |||
|  |       <image | |||
|  |         class="avatar" | |||
|  |         :src="cardData.user.avatar" | |||
|  |         mode="aspectFill" | |||
|  |       ></image> | |||
|  |       <view class="user-detail"> | |||
|  |         <text class="username">{{ cardData.user.name }}</text> | |||
|  |         <text class="user-meta">{{ cardData.user.meta }}</text> | |||
|  |       </view> | |||
|  |       <view class="follow-btn" @click="onFollow"> | |||
|  |         <u-icon name="plus" color="#666" size="14"></u-icon> | |||
|  |         <text>关注</text> | |||
|  |       </view> | |||
|  |     </view> | |||
|  | 
 | |||
|  |     <!-- 内容文本 --> | |||
|  |     <view class="content-text" @click="goContentDetail"> | |||
|  |       {{ cardData.content }} | |||
|  |     </view> | |||
|  | 
 | |||
|  |     <!-- 媒体内容 - 内部处理交互 --> | |||
|  |     <view class="media-content"> | |||
|  |       <!-- 视频内容 --> | |||
|  |       <view v-if="isVideo" class="video-container" @click="handleVideoPlay"> | |||
|  |         <image | |||
|  |           class="video-cover" | |||
|  |           :src="cardData.cover" | |||
|  |           mode="aspectFill" | |||
|  |         ></image> | |||
|  |         <view class="video-overlay"> | |||
|  |           <u-icon name="play-right" color="#fff" size="40"></u-icon> | |||
|  |           <text v-if="cardData.duration" class="video-duration">{{ | |||
|  |             formatDuration(cardData.duration) | |||
|  |           }}</text> | |||
|  |         </view> | |||
|  |       </view> | |||
|  | 
 | |||
|  |       <!-- 图片内容 --> | |||
|  |       <view v-else class="image-grid" :class="getImageLayoutClass()"> | |||
|  |         <image | |||
|  |           v-for="(img, index) in cardData.images" | |||
|  |           :key="index" | |||
|  |           class="grid-image" | |||
|  |           :src="img" | |||
|  |           mode="aspectFill" | |||
|  |           @click="handleImagePreview(index)" | |||
|  |         ></image> | |||
|  |       </view> | |||
|  |     </view> | |||
|  | 
 | |||
|  |     <!-- 互动栏 - 内部处理交互 --> | |||
|  |     <view class="interaction-bar"> | |||
|  |       <view  | |||
|  |         class="action-item"  | |||
|  |         v-for="(item, index) in actionButtons"  | |||
|  |         :key="index" | |||
|  |         @click="handleAction(item.action)" | |||
|  |       > | |||
|  |         <image | |||
|  |           :src="item.icon" | |||
|  |           mode="aspectFill" | |||
|  |           style="width: 40rpx; height: 40rpx" | |||
|  |         ></image> | |||
|  |         <text>{{ cardData.stats[item.stat] }}</text> | |||
|  |       </view> | |||
|  |     </view> | |||
|  |   </view> | |||
|  | </template> | |||
|  | 
 | |||
|  | <script> | |||
|  | export default { | |||
|  |   name: "ContentCard", | |||
|  |   props: { | |||
|  |     cardData: { | |||
|  |       type: Object, | |||
|  |       required: true, | |||
|  |       default: () => ({ | |||
|  |         user: { | |||
|  |           avatar: "", | |||
|  |           name: "", | |||
|  |           meta: "", | |||
|  |         }, | |||
|  |         content: "", | |||
|  |         // 可以是视频或图片
 | |||
|  |         type: "image", // 'image' 或 'video'
 | |||
|  |         images: [], // 图片数组
 | |||
|  |         cover: "", // 视频封面
 | |||
|  |         videoUrl: "", // 视频地址
 | |||
|  |         duration: 0, // 视频时长(秒)
 | |||
|  |         stats: { | |||
|  |           forward: 0, | |||
|  |           comment: 0, | |||
|  |           like: 0, | |||
|  |           favorite: 0, | |||
|  |         }, | |||
|  |       }), | |||
|  |     }, | |||
|  |   }, | |||
|  |   data() { | |||
|  |     return { | |||
|  |       // 添加内部状态跟踪互动状态
 | |||
|  |       isLiked: false, | |||
|  |       isFavorited: false, | |||
|  |       isForwarded: false, | |||
|  |       videoContext: null, | |||
|  |       // 添加操作按钮配置
 | |||
|  |       actionButtons: [ | |||
|  |         { | |||
|  |           icon: "/static/common/img/homepage/reply.png", | |||
|  |           action: "forward", | |||
|  |           stat: "forward" | |||
|  |         }, | |||
|  |         { | |||
|  |           icon: "/static/common/img/homepage/comment.png", | |||
|  |           action: "comment", | |||
|  |           stat: "comment" | |||
|  |         }, | |||
|  |         { | |||
|  |           icon: "/static/common/img/homepage/like.png", | |||
|  |           action: "like", | |||
|  |           stat: "like" | |||
|  |         }, | |||
|  |         { | |||
|  |           icon: "/static/common/img/homepage/star.png", | |||
|  |           action: "favorite", | |||
|  |           stat: "favorite" | |||
|  |         } | |||
|  |       ] | |||
|  |     }; | |||
|  |   }, | |||
|  |   computed: { | |||
|  |     isVideo() { | |||
|  |       return this.cardData.type === "video"; | |||
|  |     }, | |||
|  |     // 根据状态动态改变图标和颜色
 | |||
|  |     likeIcon() { | |||
|  |       return this.isLiked ? "heart-fill" : "heart"; | |||
|  |     }, | |||
|  |     likeColor() { | |||
|  |       return this.isLiked ? "#ff5252" : "#999"; | |||
|  |     }, | |||
|  |     favoriteIcon() { | |||
|  |       return this.isFavorited ? "star-fill" : "star"; | |||
|  |     }, | |||
|  |     favoriteColor() { | |||
|  |       return this.isFavorited ? "#ffb700" : "#999"; | |||
|  |     }, | |||
|  |     forwardIcon() { | |||
|  |       return this.isForwarded ? "arrow-right-fill" : "arrow-right"; | |||
|  |     }, | |||
|  |     forwardColor() { | |||
|  |       return this.isForwarded ? "#2979ff" : "#999"; | |||
|  |     }, | |||
|  |     commentColor() { | |||
|  |       return "#999"; // 评论按钮颜色无变化
 | |||
|  |     }, | |||
|  |   }, | |||
|  |   methods: { | |||
|  |     // 处理关注点击
 | |||
|  |     onFollow() { | |||
|  |       this.$emit("follow", this.cardData.user); | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 跳转详情页
 | |||
|  |     goContentDetail() { | |||
|  |       console.log("this.cardData", this.cardData); | |||
|  |       this.$u.route({ | |||
|  |         url: "/pages/home/home/components/contentDetail/index", | |||
|  |         // params: {
 | |||
|  |         //   card,
 | |||
|  |         // },
 | |||
|  |       }); | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 格式化视频时长
 | |||
|  |     formatDuration(seconds) { | |||
|  |       const minutes = Math.floor(seconds / 60); | |||
|  |       const remainingSeconds = Math.floor(seconds % 60); | |||
|  |       return `${minutes.toString().padStart(2, "0")}:${remainingSeconds | |||
|  |         .toString() | |||
|  |         .padStart(2, "0")}`;
 | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 处理视频播放
 | |||
|  |     handleVideoPlay() { | |||
|  |       if (this.cardData.videoUrl) { | |||
|  |         // 记录播放历史
 | |||
|  |         this.savePlayHistory(); | |||
|  | 
 | |||
|  |         // 使用内置视频播放器播放
 | |||
|  |         try { | |||
|  |           // 先尝试使用内部视频播放器
 | |||
|  |           if (this.useInternalPlayer) { | |||
|  |             this.showVideoPlayer = true; | |||
|  |             this.$nextTick(() => { | |||
|  |               this.videoContext = uni.createVideoContext("video-player", this); | |||
|  |               this.videoContext.requestFullScreen(); | |||
|  |               this.videoContext.play(); | |||
|  |             }); | |||
|  |           } else { | |||
|  |             // 否则跳转到专门的播放页面
 | |||
|  |             uni.navigateTo({ | |||
|  |               url: `/pages/video/player?videoUrl=${encodeURIComponent( | |||
|  |                 this.cardData.videoUrl | |||
|  |               )}&title=${encodeURIComponent(this.cardData.content)}`,
 | |||
|  |             }); | |||
|  |           } | |||
|  | 
 | |||
|  |           // 触发播放事件,让父组件可以进行额外处理
 | |||
|  |           this.$emit("video-play", { | |||
|  |             videoUrl: this.cardData.videoUrl, | |||
|  |             title: this.cardData.content, | |||
|  |             cover: this.cardData.cover, | |||
|  |             cardId: this.cardData.id, | |||
|  |           }); | |||
|  | 
 | |||
|  |           // 更新播放统计
 | |||
|  |           this.updateVideoStats(); | |||
|  |         } catch (error) { | |||
|  |           console.error("视频播放失败:", error); | |||
|  |           uni.showToast({ | |||
|  |             title: "视频播放失败,请稍后再试", | |||
|  |             icon: "none", | |||
|  |           }); | |||
|  |         } | |||
|  |       } | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 处理图片预览
 | |||
|  |     handleImagePreview(index) { | |||
|  |       try { | |||
|  |         // 使用uni-app的图片预览API
 | |||
|  |         uni.previewImage({ | |||
|  |           current: index, | |||
|  |           urls: this.cardData.images, | |||
|  |           longPressActions: { | |||
|  |             itemList: ["保存图片", "分享图片"], | |||
|  |             success: (res) => { | |||
|  |               const { tapIndex } = res; | |||
|  |               if (tapIndex === 0) { | |||
|  |                 // 保存图片
 | |||
|  |                 this.saveImage(this.cardData.images[index]); | |||
|  |               } else if (tapIndex === 1) { | |||
|  |                 // 分享图片
 | |||
|  |                 this.shareImage(this.cardData.images[index]); | |||
|  |               } | |||
|  |             }, | |||
|  |           }, | |||
|  |         }); | |||
|  | 
 | |||
|  |         // 触发图片预览事件
 | |||
|  |         this.$emit("image-preview", { | |||
|  |           index, | |||
|  |           images: this.cardData.images, | |||
|  |           cardId: this.cardData.id, | |||
|  |         }); | |||
|  |       } catch (error) { | |||
|  |         console.error("图片预览失败:", error); | |||
|  |       } | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 保存图片
 | |||
|  |     saveImage(url) { | |||
|  |       uni.showLoading({ title: "正在保存..." }); | |||
|  |       uni.downloadFile({ | |||
|  |         url, | |||
|  |         success: (res) => { | |||
|  |           if (res.statusCode === 200) { | |||
|  |             uni.saveImageToPhotosAlbum({ | |||
|  |               filePath: res.tempFilePath, | |||
|  |               success: () => { | |||
|  |                 uni.showToast({ title: "保存成功" }); | |||
|  |               }, | |||
|  |               fail: (err) => { | |||
|  |                 console.error("保存失败:", err); | |||
|  |                 uni.showToast({ title: "保存失败", icon: "none" }); | |||
|  |               }, | |||
|  |             }); | |||
|  |           } | |||
|  |         }, | |||
|  |         fail: () => { | |||
|  |           uni.showToast({ title: "下载图片失败", icon: "none" }); | |||
|  |         }, | |||
|  |         complete: () => { | |||
|  |           uni.hideLoading(); | |||
|  |         }, | |||
|  |       }); | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 分享图片
 | |||
|  |     shareImage(url) { | |||
|  |       // 根据平台实现不同的分享逻辑
 | |||
|  |       // #ifdef APP-PLUS
 | |||
|  |       plus.share.sendWithSystem({ | |||
|  |         type: "image", | |||
|  |         pictures: [url], | |||
|  |       }); | |||
|  |       // #endif
 | |||
|  | 
 | |||
|  |       // #ifdef H5
 | |||
|  |       // H5环境可能需要调用其他API
 | |||
|  |       // #endif
 | |||
|  | 
 | |||
|  |       // #ifdef MP
 | |||
|  |       // 小程序环境使用小程序分享API
 | |||
|  |       uni.showToast({ title: "请使用右上角分享", icon: "none" }); | |||
|  |       // #endif
 | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 根据图片数量确定布局样式
 | |||
|  |     getImageLayoutClass() { | |||
|  |       const count = this.cardData.images.length; | |||
|  |       if (count === 1) return "single-image"; | |||
|  |       if (count === 2) return "double-image"; | |||
|  |       if (count === 3) return "triple-image"; | |||
|  |       if (count === 4) return "four-image"; | |||
|  |       if (count > 4) return "multi-image"; | |||
|  |       return ""; | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 处理转发
 | |||
|  |     handleForward() { | |||
|  |       this.isForwarded = !this.isForwarded; | |||
|  | 
 | |||
|  |       // 显示分享菜单
 | |||
|  |       uni.showShareMenu({ | |||
|  |         withShareTicket: true, | |||
|  |         menus: ["shareAppMessage", "shareTimeline"], | |||
|  |       }); | |||
|  | 
 | |||
|  |       // 触发转发事件
 | |||
|  |       this.$emit("forward", { | |||
|  |         cardData: this.cardData, | |||
|  |         isForwarded: this.isForwarded, | |||
|  |       }); | |||
|  | 
 | |||
|  |       // 如果在APP中,可以调用原生分享
 | |||
|  |       // #ifdef APP-PLUS
 | |||
|  |       uni.share({ | |||
|  |         provider: "weixin", | |||
|  |         scene: "WXSceneSession", | |||
|  |         type: 0, | |||
|  |         title: this.cardData.content, | |||
|  |         summary: this.cardData.content, | |||
|  |         imageUrl: this.isVideo ? this.cardData.cover : this.cardData.images[0], | |||
|  |         success: function (res) { | |||
|  |           console.log("分享成功:" + JSON.stringify(res)); | |||
|  |         }, | |||
|  |         fail: function (err) { | |||
|  |           console.log("分享失败:" + JSON.stringify(err)); | |||
|  |         }, | |||
|  |       }); | |||
|  |       // #endif
 | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 处理评论
 | |||
|  |     handleComment() { | |||
|  |       // 跳转到评论页面或打开评论弹窗
 | |||
|  |       this.$emit("comment", { | |||
|  |         cardData: this.cardData, | |||
|  |       }); | |||
|  | 
 | |||
|  |       // 这里可以实现自定义的评论交互
 | |||
|  |       uni.navigateTo({ | |||
|  |         url: `/pages/comment/index?id=${this.cardData.id}&type=${this.cardData.type}`, | |||
|  |       }); | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 处理点赞
 | |||
|  |     handleLike() { | |||
|  |       // 切换点赞状态
 | |||
|  |       this.isLiked = !this.isLiked; | |||
|  | 
 | |||
|  |       // 更新点赞数据
 | |||
|  |       const newStats = { ...this.cardData.stats }; | |||
|  |       if (this.isLiked) { | |||
|  |         newStats.like += 1; | |||
|  |       } else { | |||
|  |         newStats.like = Math.max(0, newStats.like - 1); | |||
|  |       } | |||
|  | 
 | |||
|  |       // 更新数据并触发事件
 | |||
|  |       this.$emit("like", { | |||
|  |         cardData: this.cardData, | |||
|  |         isLiked: this.isLiked, | |||
|  |         newStats, | |||
|  |       }); | |||
|  | 
 | |||
|  |       // 发送点赞请求到服务器
 | |||
|  |       this.updateLikeStatus(); | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 处理收藏
 | |||
|  |     handleFavorite() { | |||
|  |       // 切换收藏状态
 | |||
|  |       this.isFavorited = !this.isFavorited; | |||
|  | 
 | |||
|  |       // 更新收藏数据
 | |||
|  |       const newStats = { ...this.cardData.stats }; | |||
|  |       if (this.isFavorited) { | |||
|  |         newStats.favorite += 1; | |||
|  |       } else { | |||
|  |         newStats.favorite = Math.max(0, newStats.favorite - 1); | |||
|  |       } | |||
|  | 
 | |||
|  |       // 更新数据并触发事件
 | |||
|  |       this.$emit("favorite", { | |||
|  |         cardData: this.cardData, | |||
|  |         isFavorited: this.isFavorited, | |||
|  |         newStats, | |||
|  |       }); | |||
|  | 
 | |||
|  |       // 发送收藏请求到服务器
 | |||
|  |       this.updateFavoriteStatus(); | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 更新点赞状态到服务器
 | |||
|  |     updateLikeStatus() { | |||
|  |       // 调用API更新点赞状态
 | |||
|  |       // 示例代码,根据实际API调整
 | |||
|  |       const url = this.isLiked ? "/api/like/add" : "/api/like/cancel"; | |||
|  |       uni.request({ | |||
|  |         url, | |||
|  |         method: "POST", | |||
|  |         data: { | |||
|  |           contentId: this.cardData.id, | |||
|  |           contentType: this.cardData.type, | |||
|  |         }, | |||
|  |         success: (res) => { | |||
|  |           console.log("点赞状态更新成功", res); | |||
|  |         }, | |||
|  |         fail: (err) => { | |||
|  |           console.error("点赞状态更新失败", err); | |||
|  |           // 恢复原状态
 | |||
|  |           this.isLiked = !this.isLiked; | |||
|  |         }, | |||
|  |       }); | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 更新收藏状态到服务器
 | |||
|  |     updateFavoriteStatus() { | |||
|  |       // 调用API更新收藏状态
 | |||
|  |       // 示例代码,根据实际API调整
 | |||
|  |       const url = this.isFavorited | |||
|  |         ? "/api/favorite/add" | |||
|  |         : "/api/favorite/cancel"; | |||
|  |       uni.request({ | |||
|  |         url, | |||
|  |         method: "POST", | |||
|  |         data: { | |||
|  |           contentId: this.cardData.id, | |||
|  |           contentType: this.cardData.type, | |||
|  |         }, | |||
|  |         success: (res) => { | |||
|  |           console.log("收藏状态更新成功", res); | |||
|  |         }, | |||
|  |         fail: (err) => { | |||
|  |           console.error("收藏状态更新失败", err); | |||
|  |           // 恢复原状态
 | |||
|  |           this.isFavorited = !this.isFavorited; | |||
|  |         }, | |||
|  |       }); | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 记录视频播放历史
 | |||
|  |     savePlayHistory() { | |||
|  |       // 保存播放历史到本地存储或服务器
 | |||
|  |       try { | |||
|  |         const historyList = uni.getStorageSync("videoPlayHistory") || []; | |||
|  |         const now = new Date().getTime(); | |||
|  | 
 | |||
|  |         // 查找是否已有该视频记录
 | |||
|  |         const index = historyList.findIndex( | |||
|  |           (item) => item.id === this.cardData.id | |||
|  |         ); | |||
|  | 
 | |||
|  |         if (index > -1) { | |||
|  |           // 更新已有记录
 | |||
|  |           historyList[index].lastPlayTime = now; | |||
|  |           historyList[index].playCount += 1; | |||
|  |         } else { | |||
|  |           // 添加新记录
 | |||
|  |           historyList.push({ | |||
|  |             id: this.cardData.id, | |||
|  |             title: this.cardData.content, | |||
|  |             cover: this.cardData.cover, | |||
|  |             lastPlayTime: now, | |||
|  |             playCount: 1, | |||
|  |           }); | |||
|  |         } | |||
|  | 
 | |||
|  |         // 保存回本地存储
 | |||
|  |         uni.setStorageSync("videoPlayHistory", historyList); | |||
|  |       } catch (e) { | |||
|  |         console.error("保存播放历史失败", e); | |||
|  |       } | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 更新视频播放统计
 | |||
|  |     updateVideoStats() { | |||
|  |       // 调用API更新视频播放次数
 | |||
|  |       uni.request({ | |||
|  |         url: "/api/video/view", | |||
|  |         method: "POST", | |||
|  |         data: { | |||
|  |           videoId: this.cardData.id, | |||
|  |         }, | |||
|  |         success: (res) => { | |||
|  |           console.log("视频播放统计更新成功", res); | |||
|  |         }, | |||
|  |         fail: (err) => { | |||
|  |           console.error("视频播放统计更新失败", err); | |||
|  |         }, | |||
|  |       }); | |||
|  |     }, | |||
|  | 
 | |||
|  |     // 添加统一的操作处理方法
 | |||
|  |     handleAction(action) { | |||
|  |       switch(action) { | |||
|  |         case "forward": | |||
|  |           this.handleForward(); | |||
|  |           break; | |||
|  |         case "comment": | |||
|  |           this.handleComment(); | |||
|  |           break; | |||
|  |         case "like": | |||
|  |           this.handleLike(); | |||
|  |           break; | |||
|  |         case "favorite": | |||
|  |           this.handleFavorite(); | |||
|  |           break; | |||
|  |       } | |||
|  |     } | |||
|  |   }, | |||
|  | }; | |||
|  | </script> | |||
|  | 
 | |||
|  | <style scoped lang="scss"> | |||
|  | .content-card { | |||
|  |   background-color: #fff; | |||
|  |   border-radius: 24rpx; | |||
|  |   padding: 24rpx; | |||
|  |   margin-bottom: 24rpx; | |||
|  |   box-shadow: 0 2rpx 10rpx rgba(0, 0, 0, 0.05); | |||
|  | 
 | |||
|  |   .user-info { | |||
|  |     display: flex; | |||
|  |     align-items: center; | |||
|  |     margin-bottom: 24rpx; | |||
|  | 
 | |||
|  |     .avatar { | |||
|  |       width: 80rpx; | |||
|  |       height: 80rpx; | |||
|  |       border-radius: 50%; | |||
|  |       margin-right: 16rpx; | |||
|  |     } | |||
|  | 
 | |||
|  |     .user-detail { | |||
|  |       flex: 1; | |||
|  | 
 | |||
|  |       .username { | |||
|  |         font-size: 30rpx; | |||
|  |         font-weight: 500; | |||
|  |         color: #333; | |||
|  |         display: block; | |||
|  |         line-height: 1.2; | |||
|  |       } | |||
|  | 
 | |||
|  |       .user-meta { | |||
|  |         font-size: 24rpx; | |||
|  |         color: #999; | |||
|  |         display: block; | |||
|  |         line-height: 1.2; | |||
|  |         margin-top: 6rpx; | |||
|  |       } | |||
|  |     } | |||
|  | 
 | |||
|  |     .follow-btn { | |||
|  |       display: flex; | |||
|  |       align-items: center; | |||
|  |       justify-content: center; | |||
|  |       background-color: #f5f5f5; | |||
|  |       border-radius: 30rpx; | |||
|  |       padding: 8rpx 16rpx; | |||
|  | 
 | |||
|  |       text { | |||
|  |         font-size: 24rpx; | |||
|  |         color: #666; | |||
|  |         margin-left: 4rpx; | |||
|  |       } | |||
|  |     } | |||
|  |   } | |||
|  | 
 | |||
|  |   .content-text { | |||
|  |     font-size: 28rpx; | |||
|  |     color: #333; | |||
|  |     line-height: 1.5; | |||
|  |     margin-bottom: 24rpx; | |||
|  |   } | |||
|  | 
 | |||
|  |   .media-content { | |||
|  |     margin-bottom: 24rpx; | |||
|  |     width: 100%; | |||
|  | 
 | |||
|  |     // 视频容器样式
 | |||
|  |     .video-container { | |||
|  |       position: relative; | |||
|  |       width: 100%; | |||
|  |       border-radius: 8rpx; | |||
|  |       overflow: hidden; | |||
|  | 
 | |||
|  |       .video-cover { | |||
|  |         width: 100%; | |||
|  |         height: 400rpx; | |||
|  |         display: block; | |||
|  |       } | |||
|  | 
 | |||
|  |       .video-overlay { | |||
|  |         position: absolute; | |||
|  |         top: 0; | |||
|  |         left: 0; | |||
|  |         width: 100%; | |||
|  |         height: 100%; | |||
|  |         display: flex; | |||
|  |         align-items: center; | |||
|  |         justify-content: center; | |||
|  |         background-color: rgba(0, 0, 0, 0.2); | |||
|  | 
 | |||
|  |         .video-duration { | |||
|  |           position: absolute; | |||
|  |           right: 16rpx; | |||
|  |           bottom: 16rpx; | |||
|  |           color: #fff; | |||
|  |           font-size: 24rpx; | |||
|  |           background-color: rgba(0, 0, 0, 0.5); | |||
|  |           padding: 4rpx 8rpx; | |||
|  |           border-radius: 4rpx; | |||
|  |         } | |||
|  |       } | |||
|  |     } | |||
|  | 
 | |||
|  |     // 图片网格样式
 | |||
|  |     .image-grid { | |||
|  |       display: flex; | |||
|  |       flex-wrap: wrap; | |||
|  | 
 | |||
|  |       .grid-image { | |||
|  |         border-radius: 8rpx; | |||
|  |         background-color: #f5f5f5; | |||
|  |       } | |||
|  | 
 | |||
|  |       &.single-image { | |||
|  |         .grid-image { | |||
|  |           width: 100%; | |||
|  |           max-height: 400rpx; | |||
|  |         } | |||
|  |       } | |||
|  | 
 | |||
|  |       &.double-image { | |||
|  |         justify-content: space-between; | |||
|  | 
 | |||
|  |         .grid-image { | |||
|  |           width: 49%; | |||
|  |           height: 240rpx; | |||
|  |         } | |||
|  |       } | |||
|  | 
 | |||
|  |       &.triple-image { | |||
|  |         justify-content: space-between; | |||
|  | 
 | |||
|  |         .grid-image { | |||
|  |           width: 31%; | |||
|  |           height: 180rpx; | |||
|  |         } | |||
|  |       } | |||
|  | 
 | |||
|  |       &.four-image { | |||
|  |         justify-content: space-between; | |||
|  | 
 | |||
|  |         .grid-image { | |||
|  |           width: 49%; | |||
|  |           height: 180rpx; | |||
|  |           margin-bottom: 10rpx; | |||
|  |         } | |||
|  |       } | |||
|  | 
 | |||
|  |       &.multi-image { | |||
|  |         justify-content: space-between; | |||
|  | 
 | |||
|  |         .grid-image { | |||
|  |           width: 31%; | |||
|  |           height: 180rpx; | |||
|  |           margin-bottom: 10rpx; | |||
|  |         } | |||
|  |       } | |||
|  |     } | |||
|  |   } | |||
|  | 
 | |||
|  |   .interaction-bar { | |||
|  |     display: flex; | |||
|  |     justify-content: space-between; | |||
|  |     margin-top: 16rpx; | |||
|  |     padding: 0 20rpx; | |||
|  | 
 | |||
|  |     .action-item { | |||
|  |       display: flex; | |||
|  |       align-items: center; | |||
|  | 
 | |||
|  |       text { | |||
|  |         font-size: 24rpx; | |||
|  |         color: #999; | |||
|  |         margin-left: 8rpx; | |||
|  |       } | |||
|  |     } | |||
|  |   } | |||
|  | } | |||
|  | </style> |