| | |
| | | @change="onSwiperChange" |
| | | > |
| | | <swiper-item v-for="(item, index) in videoList" :key="item.id"> |
| | | <!-- 播放按钮(仅当视频暂停时显示) --> |
| | | <view |
| | | class="play-icon" |
| | | @click="togglePlay(index)" |
| | | v-if="!currentVideoIsPlaying" |
| | | > |
| | | <image src="/static/video/play.png" style="width: 45px;height: 45px" mode="aspectFit"></image> |
| | | </view> |
| | | <video |
| | | :id="'video'+index" |
| | | :src="item.url" |
| | | :ref="'video'+index" |
| | | :src="item.videoUrl" |
| | | :autoplay="currentIndex === index" |
| | | :controls="false" |
| | | :loop="true" |
| | | :object-fit="item.objectFit" |
| | | class="video-item" |
| | | @play="onPlay(index)" |
| | | @play="onPlay(item.id, index)" |
| | | @pause="onPause(index)" |
| | | @ended="onEnded(index)" |
| | | @click="togglePlay(index)" |
| | | @timeupdate="onTimeUpdate($event)" |
| | | ></video> |
| | | |
| | | <!-- 悬挂商品链接层 --> |
| | |
| | | <view class="goods-link"> |
| | | <view class="goods-container"> |
| | | <!-- 商品图片 --> |
| | | <image class="goods-image" :src="item.goods.image" mode="aspectFill"></image> |
| | | <image class="goods-image" :src="item.goods.imageUrl" mode="aspectFill"></image> |
| | | |
| | | <!-- 商品信息 --> |
| | | <view class="goods-info"> |
| | |
| | | <text class="current-price">¥{{item.goods.price}}</text> |
| | | <text class="original-price" v-if="item.goods.originalPrice">¥{{item.goods.originalPrice}}</text> |
| | | </view> |
| | | <text class="sales-count">{{item.goods.sales}}人已购</text> |
| | | <text class="sales-count">{{item.goods.saleNum}}人已购</text> |
| | | </view> |
| | | |
| | | <!-- 购买按钮 --> |
| | |
| | | <!-- 视频信息层 --> |
| | | <view class="video-info"> |
| | | <view> |
| | | <text class="video-author">@{{item.author}}</text> |
| | | <text class="video-author">@{{item.authorName}}</text> |
| | | </view> |
| | | <view style="width: 100%;word-wrap: break-word;white-space: normal;overflow-wrap: break-word;"> |
| | | <text class="video-title">{{item.title}}</text> |
| | | <text class="video-tag" v-for="(tag, index) in item.tags" :key="tag">#{{tag}}</text> |
| | | <text class="video-tag" v-for="(tag, index) in item.tagList" :key="tag">#{{tag.tagName}}</text> |
| | | </view> |
| | | </view> |
| | | |
| | |
| | | <view class="avatar-container"> |
| | | <image class="avatar" :src="item.authorAvatar" mode="aspectFill"></image> |
| | | <!-- 关注图标 - 使用绝对定位 --> |
| | | <view class="follow-icon"> |
| | | <view v-if="!item.subscribeThisAuthor" class="follow-icon" @click="subscribeAuth(index, item.authorId)"> |
| | | <text class="iconfont"></text> |
| | | </view> |
| | | </view> |
| | | <view class="action-item" @click="toggleCollect(item)"> |
| | | <!-- <image :src="item.isCollected ? '/static/collected.png' : '/static/collect.png'"></image> --> |
| | | <view class="action-item" @click="toggleCollect(item, index)"> |
| | | <text class="iconfont" v-if="item.collected"></text> |
| | | <text class="iconfont" v-else></text> |
| | | <text style="font-size: 10px;font-weight: lighter;">{{item.collectCount}}</text> |
| | | <text style="font-size: 10px;font-weight: lighter;">{{item.collectNum}}</text> |
| | | </view> |
| | | <view class="action-item" @click="showComments(item)"> |
| | | <text class="iconfont"></text> |
| | | <text style="font-size: 10px;font-weight: lighter;">{{item.commentCount}}</text> |
| | | <text style="font-size: 10px;font-weight: lighter;">{{item.commentNum}}</text> |
| | | </view> |
| | | </view> |
| | | |
| | | </swiper-item> |
| | | </swiper> |
| | | |
| | | <!-- 评论弹窗 --> |
| | | <uni-popup ref="commentPopup" type="bottom" :is-mask-click="true" @maskClick="closeCommentPopup"> |
| | | <view class="comment-popup"> |
| | | <view class="popup-header"> |
| | | <text class="popup-title">评论({{commentsTotal}})</text> |
| | | <text class="iconfont close-icon" @click="closeCommentPopup"></text> |
| | | </view> |
| | | |
| | | <scroll-view class="comment-list" scroll-y :show-scrollbar="false" @scrolltolower="getCommentPage"> |
| | | <view v-if="commentLoading" class="loading"> |
| | | <uni-load-more status="loading"></uni-load-more> |
| | | </view> |
| | | |
| | | <view v-else-if="comments.length === 0" class="empty"> |
| | | 暂无评论,快来发表第一条评论吧~ |
| | | </view> |
| | | |
| | | <view v-else class="comment-item" v-for="comment in comments" :key="comment.id"> |
| | | <image class="avatar" :src="comment.userAvatar || '/static/default-avatar.png'"></image> |
| | | <view class="comment-content"> |
| | | <text class="nickname">{{comment.userNickname}}</text> |
| | | <text class="content">{{comment.commentContent}}</text> |
| | | <text class="time">{{formatTime(comment.createTime)}}</text> |
| | | </view> |
| | | </view> |
| | | </scroll-view> |
| | | |
| | | <view class="comment-input-area"> |
| | | <input |
| | | class="comment-input" |
| | | v-model="commentForm.commentContent" |
| | | placeholder="写下你的评论..." |
| | | placeholder-class="placeholder" |
| | | /> |
| | | <button class="submit-btn" @click="submitComment">发送</button> |
| | | </view> |
| | | </view> |
| | | </uni-popup> |
| | | |
| | | |
| | | <custom-tabbar bgColor="#333333" selected="index" selectedTextColor="#ffffff"></custom-tabbar> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import { getRecommendVideos, savePlayRecord, subscribe, getVideoComments, addVideoComment } from "@/api/video.js"; |
| | | import { changeCollect } from "@/api/collect.js"; |
| | | export default { |
| | | data() { |
| | | return { |
| | | isFullScreen: false, |
| | | windowHeight: 0, |
| | | currentIndex: 0, // 当前播放的视频索引 |
| | | videoList: [ |
| | | { |
| | | url: 'http://vjs.zencdn.net/v/oceans.mp4', |
| | | objectFit: 'contain', |
| | | title: '我了个', |
| | | author: 'xp', |
| | | authorAvatar: 'https://picsum.photos/200/200?random=2', |
| | | collected: true, |
| | | commentCount: 12, |
| | | collectCount: 45, |
| | | tags: ["五一", "爱美食", "士大夫速度和粉红色的恢复速度的口袋空空"], |
| | | goods: { |
| | | name: '推流', |
| | | price: '10', |
| | | originalPrice: '48.9', |
| | | sales: 1988, |
| | | image: 'https://picsum.photos/200/200?random=2' |
| | | } |
| | | }, |
| | | { |
| | | url: 'https://videos.pexels.com/video-files/30900524/13210612_1080_1920_30fps.mp4', |
| | | objectFit: 'cover', |
| | | title: '我了个', |
| | | author: 'xp', |
| | | authorAvatar: 'https://picsum.photos/200/200?random=2', |
| | | collected: false, |
| | | commentCount: 6, |
| | | collectCount: 45, |
| | | tags: ["我喜欢"], |
| | | goods: { |
| | | name: '推流', |
| | | price: '10', |
| | | originalPrice: '48.9', |
| | | sales: 1988, |
| | | image: 'https://picsum.photos/200/200?random=2' |
| | | } |
| | | }, |
| | | ], // 视频列表数据 |
| | | videoContexts: [], // 视频上下文对象集合 |
| | | loading: false, // 是否正在加载 |
| | | page: 1, // 当前页码 |
| | | pageSize: 10 // 每页数量 |
| | | commentNoMore: false, // 是否还有更多评论 |
| | | commentQuery: { |
| | | pageNumber: 1, |
| | | pageSize: 5, |
| | | videoId: '', |
| | | masterCommentId: '' |
| | | }, |
| | | commentForm: { // 评论表单数据 |
| | | id: null, |
| | | videoId: null, |
| | | commentContent: '', |
| | | replyId: null |
| | | }, |
| | | comments: [], // 评论列表 |
| | | commentsTotal: 0, // 评论总条数 |
| | | commentLoading: false, // 评论加载状态 |
| | | startHidenTime: 0, // 记录切换至其它页面的时间,用于计算视频观看时间减去的部分 |
| | | totalHidenTime: 0, // 总共隐藏页面的时间 |
| | | startPauseTime: 0, // 开始暂停的时间 |
| | | totalPauseTime: 0, // 总共暂停的时间 |
| | | playRecord: { |
| | | videoId: null, |
| | | viewDuration: 0, // 这个视频总共观看了多久 |
| | | playAt: 0 ,// 这个视频播放到哪了 |
| | | startPlayTime: 0 // 这个视频从什么时候开始播放的 |
| | | }, |
| | | currentVideoIsPlaying: true, // 当前视频是否正在播放 |
| | | isFullScreen: false, |
| | | windowHeight: 0, |
| | | currentIndex: 0, // 当前播放的视频索引 |
| | | videoList: [ |
| | | |
| | | ], // 视频列表数据 |
| | | videoContexts: [], // 视频上下文对象集合 |
| | | loading: false, // 是否正在加载 |
| | | page: 1, // 当前页码 |
| | | pageSize: 10 // 每页数量 |
| | | } |
| | | }, |
| | | onShow() { |
| | | this.loadVideos() |
| | | // 如果视频按下暂停后切换页面再回到页面时,只算暂停时间(因为暂停时间和离开页面时间是重复的,只算一个) |
| | | if(this.startHidenTime !== 0 && this.currentVideoIsPlaying) { |
| | | const duration = Date.now() - this.startHidenTime |
| | | this.totalHidenTime += duration |
| | | } |
| | | }, |
| | | onHide() { |
| | | this.startHidenTime = Date.now() |
| | | }, |
| | | onLoad() { |
| | | // this.loadVideos(); |
| | | this.loadVideos(); |
| | | }, |
| | | onReady() { |
| | | // 初始化视频上下文 |
| | | this.initVideoContexts(); |
| | | }, |
| | | methods: { |
| | | // 格式化时间 |
| | | formatTime(time) { |
| | | const date = new Date(time); |
| | | const now = new Date(); |
| | | const diff = Math.floor((now - date) / 1000); // 秒 |
| | | |
| | | if (diff < 60) return '刚刚'; |
| | | if (diff < 3600) return `${Math.floor(diff / 60)}分钟前`; |
| | | if (diff < 86400) return `${Math.floor(diff / 3600)}小时前`; |
| | | |
| | | return `${date.getMonth() + 1}月${date.getDate()}日`; |
| | | }, |
| | | // 提交评论 |
| | | async submitComment() { |
| | | if (!this.commentForm.commentContent.trim()) { |
| | | uni.showToast({ |
| | | title: '评论内容不能为空', |
| | | icon: 'none' |
| | | }); |
| | | return; |
| | | } |
| | | // 发表评论 |
| | | addVideoComment(this.commentForm).then(res => { |
| | | if(res.data.code === 200) { |
| | | this.commentForm = { |
| | | id: null, |
| | | videoId: null, |
| | | commentContent: '', |
| | | replyId: null |
| | | } |
| | | this.comments.unshift(res.data.data); |
| | | console.log("新增后",this.comments); |
| | | uni.showToast({ |
| | | title: '评论成功' |
| | | }); |
| | | // 当前视频评论数加一 |
| | | this.commentsTotal += 1; |
| | | this.videoList[this.currentIndex].commentNum += 1; |
| | | } else { |
| | | uni.showToast({ |
| | | title: res.data.msg, |
| | | icon: 'none' |
| | | }); |
| | | } |
| | | }).catch(() => { |
| | | uni.showToast({ |
| | | title: '评论失败', |
| | | icon: 'none' |
| | | }); |
| | | }) |
| | | }, |
| | | // 关闭评论弹窗 |
| | | closeCommentPopup() { |
| | | this.$refs.commentPopup.close() |
| | | this.showCommentPopup = false; |
| | | this.comments = []; |
| | | this.commentForm = { |
| | | id: null, |
| | | videoId: null, |
| | | commentContent: '', |
| | | replyId: null |
| | | } |
| | | this.commentQuery.pageNumber = 1; |
| | | this.commentNoMore = false; |
| | | }, |
| | | // 下滑评论区加载评论 |
| | | async getCommentPage() { |
| | | if(this.commentNoMore) { |
| | | return; |
| | | } |
| | | getVideoComments(this.commentQuery).then(res => { |
| | | if(this.commentQuery.pageNumber === 1) { |
| | | this.comments = res.data.data |
| | | } else { |
| | | this.comments = [ |
| | | ...this.comments, |
| | | ...res.data.data.filter( |
| | | (newItem) => !this.comments.some((oldItem) => oldItem.id === newItem.id) |
| | | ), |
| | | ]; |
| | | } |
| | | if (res.data.data.length < this.commentQuery.pageSize) { |
| | | this.commentNoMore = true; |
| | | return; |
| | | } |
| | | this.commentQuery.pageNumber++; |
| | | }) |
| | | }, |
| | | // 显示评论弹窗 |
| | | async showComments(item) { |
| | | this.commentForm.videoId = item.id; |
| | | this.$refs.commentPopup.open(); |
| | | this.commentLoading = true; |
| | | this.commentQuery.videoId = item.id |
| | | // 首次加载评论分页大小增加一倍,以产生滚动条,后续可触发 |
| | | this.commentQuery.pageSize *= 2; |
| | | getVideoComments(this.commentQuery).then(res => { |
| | | this.commentsTotal = res.data.total; |
| | | this.comments = res.data.data; |
| | | this.commentQuery.pageNumber += 2; |
| | | this.commentQuery.pageSize /= 2; |
| | | }).catch(() => { |
| | | uni.showToast({ |
| | | title: '获取评论失败', |
| | | icon: 'none' |
| | | }); |
| | | }).finally(() => { |
| | | this.commentLoading = false; |
| | | }) |
| | | }, |
| | | // 关注作者 |
| | | subscribeAuth(index, authorId) { |
| | | this.videoList.forEach(video => { |
| | | if(video.authorId === authorId) { |
| | | video.subscribeThisAuthor = true |
| | | } |
| | | }) |
| | | subscribe(authorId).then(res => { |
| | | if(res.data.code === 200) { |
| | | uni.showToast({ |
| | | title: '关注成功~', |
| | | icon: 'none' |
| | | }); |
| | | } else { |
| | | this.videoList.forEach(video => { |
| | | if(video.authorId === authorId) { |
| | | video.subscribeThisAuthor = false |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | }, |
| | | // 初始化视频上下文 |
| | | initVideoContexts() { |
| | | this.videoContexts = this.videoList.map((_, index) => { |
| | | let videoContent = uni.createVideoContext(`video${index}`, this); |
| | | // videoContent.requestFullScreen({ direction: 0 }); |
| | | return videoContent; |
| | | }); |
| | | }, |
| | |
| | | if (this.loading) return; |
| | | this.loading = true; |
| | | |
| | | try { |
| | | const res = await uni.request({ |
| | | url: 'https://your-api.com/videos', |
| | | data: { |
| | | page: this.page, |
| | | pageSize: this.pageSize |
| | | } |
| | | }); |
| | | |
| | | if (this.page === 1) { |
| | | this.videoList = res.data.list; |
| | | } else { |
| | | this.videoList = [...this.videoList, ...res.data.list]; |
| | | } |
| | | |
| | | this.page++; |
| | | this.$nextTick(() => { |
| | | this.initVideoContexts(); |
| | | }); |
| | | } catch (e) { |
| | | console.error('加载视频失败', e); |
| | | } finally { |
| | | this.loading = false; |
| | | } |
| | | getRecommendVideos({pageNumber: this.page, pageSize: this.pageSize}).then(res => { |
| | | console.log(res, "视频数据"); |
| | | if (this.page === 1) { |
| | | this.videoList = res.data.data; |
| | | } else { |
| | | this.videoList = [...this.videoList, ...res.data.data]; |
| | | } |
| | | |
| | | this.page++; |
| | | this.$nextTick(() => { |
| | | this.initVideoContexts(); |
| | | }); |
| | | this.loading = false; |
| | | }) |
| | | }, |
| | | |
| | | // 滑动切换视频 |
| | | onSwiperChange(e) { |
| | | const oldIndex = this.currentIndex; |
| | | this.currentIndex = e.detail.current; |
| | | |
| | | // 暂停上一个视频 |
| | | if (this.videoContexts[oldIndex]) { |
| | | this.videoContexts[oldIndex].pause(); |
| | | } |
| | | |
| | | // 播放当前视频 |
| | | if (this.videoContexts[this.currentIndex]) { |
| | | this.videoContexts[this.currentIndex].play(); |
| | | } |
| | | // 如果视频处于暂停状态往下刷视频,那么需要再计算一次暂停时间 |
| | | if(!this.currentVideoIsPlaying) { |
| | | if(this.startPauseTime !== 0) { |
| | | const duration = Date.now() - this.startPauseTime |
| | | this.totalPauseTime += duration |
| | | } |
| | | } |
| | | // 保存上一个视频的播放记录 |
| | | this.savePlayRecord() |
| | | const oldIndex = this.currentIndex; |
| | | this.currentIndex = e.detail.current; |
| | | |
| | | // 暂停上一个视频 |
| | | if (this.videoContexts[oldIndex]) { |
| | | this.videoContexts[oldIndex].pause(); |
| | | } |
| | | |
| | | this.startPauseTime = 0; |
| | | // 播放当前视频 |
| | | if (this.videoContexts[this.currentIndex]) { |
| | | this.videoContexts[this.currentIndex].play(); |
| | | } |
| | | }, |
| | | |
| | | // 点赞/取消点赞 |
| | | toggleLike(item) { |
| | | item.isLiked = !item.isLiked; |
| | | item.likeCount += item.isLiked ? 1 : -1; |
| | | |
| | | uni.request({ |
| | | url: `https://your-api.com/video/${item.id}/like`, |
| | | method: item.isLiked ? 'POST' : 'DELETE' |
| | | }); |
| | | // 收藏/取消收藏 |
| | | toggleCollect(item, index) { |
| | | let data = { |
| | | refId: item.id, |
| | | collectType: 'video' |
| | | } |
| | | const beforeCollected = item.collected |
| | | const beforeCollectNum = item.collectNum |
| | | if(item.collected) { |
| | | this.videoList[index].collected = false |
| | | this.videoList[index].collectNum -= 1 |
| | | } else { |
| | | this.videoList[index].collected = true |
| | | this.videoList[index].collectNum += 1 |
| | | } |
| | | changeCollect(data).then(res => { |
| | | if(res.data.code !== 200) { |
| | | this.videoList[index].collected = beforeCollected |
| | | this.videoList[index].collectNum = beforeCollectNum |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | // 单击屏幕:暂停或继续播放 |
| | | togglePlay(index) { |
| | | if(this.currentVideoIsPlaying) { |
| | | this.videoContexts[index].pause(); |
| | | } else { |
| | | this.videoContexts[index].play(); |
| | | } |
| | | }, |
| | | // 视频播放事件 |
| | | onPlay(index) { |
| | | console.log(`视频 ${index} 开始播放`); |
| | | onPlay(id, index) { |
| | | console.log(id, index, "触发播放"); |
| | | if(index === this.currentIndex) { |
| | | this.currentVideoIsPlaying = true; |
| | | } else { |
| | | this.currentVideoIsPlaying = false; |
| | | return |
| | | } |
| | | this.playRecord.videoId = id; |
| | | // 没初始化才赋值,因为一个视频重复播放onPlay会重复触发 |
| | | if(this.playRecord.startPlayTime === 0) { |
| | | this.playRecord.startPlayTime = Date.now(); |
| | | } |
| | | if(this.startPauseTime !== 0) { |
| | | const duration = Date.now() - this.startPauseTime |
| | | this.totalPauseTime += duration |
| | | } |
| | | }, |
| | | |
| | | // 视频暂停事件 |
| | | onPause(index) { |
| | | console.log(`视频 ${index} 暂停`); |
| | | console.log(index, "触发暂停"); |
| | | if(index === this.currentIndex) { |
| | | this.currentVideoIsPlaying = false; |
| | | } else { |
| | | this.currentVideoIsPlaying = true; |
| | | return |
| | | } |
| | | this.startPauseTime = Date.now() |
| | | }, |
| | | |
| | | // 视频结束事件 |
| | | onEnded(index) { |
| | | console.log(`视频 ${index} 播放结束`); |
| | | // 自动播放下一个(如果不在最后一个) |
| | | if (index < this.videoList.length - 1) { |
| | | this.currentIndex = index + 1; |
| | | } |
| | | } |
| | | // this.currentVideoIsPlaying = false; |
| | | }, |
| | | |
| | | // 记录播放时长 |
| | | onTimeUpdate(e) { |
| | | this.playRecord.playAt = e.detail.currentTime |
| | | }, |
| | | |
| | | // 保存播放记录 |
| | | async savePlayRecord() { |
| | | console.log(Date.now(), this.playRecord.startPlayTime, this.totalHidenTime); |
| | | |
| | | const data = { |
| | | videoId: this.playRecord.videoId, |
| | | viewDuration: Date.now() - this.playRecord.startPlayTime - this.totalHidenTime - this.totalPauseTime, |
| | | playAt: this.playRecord.playAt |
| | | } |
| | | this.playRecord = { |
| | | videoId: null, |
| | | viewDuration: 0, // 这个视频总共观看了多久 |
| | | playAt: 0 ,// 这个视频播放到哪了 |
| | | startPlayTime: 0 // 这个视频从什么时候开始播放的 |
| | | } |
| | | this.totalHidenTime = 0 |
| | | this.totalPauseTime = 0 |
| | | savePlayRecord(data) |
| | | } |
| | | } |
| | | } |
| | | </script> |
| | | |
| | | <style scoped> |
| | | ::v-deep .custom-tabbar { |
| | | border-top: none !important; |
| | | } |
| | | .video-container { |
| | | width: 100%; |
| | | height: 100vh; |
| | |
| | | height: 100%; |
| | | object-fit: cover; |
| | | } |
| | | .play-icon { |
| | | position: absolute; |
| | | top: 50%; |
| | | left: 50%; |
| | | transform: translate(-50%, -50%); |
| | | width: 45px; |
| | | height: 45px; |
| | | z-index: 10; |
| | | opacity: 0.6; |
| | | } |
| | | |
| | | .video-info { |
| | | width: 70%; |
| | | position: absolute; |
| | | bottom: 50px; |
| | | bottom: 70px; |
| | | left: 20px; |
| | | color: #f8f8f8; |
| | | z-index: 10; |
| | |
| | | /* 商品链接悬挂层样式 */ |
| | | .goods-link-warp { |
| | | position: absolute; |
| | | bottom: 100px; |
| | | bottom: 160px; |
| | | left: 20px; |
| | | color: #f8f8f8; |
| | | z-index: 10; |
| | |
| | | font-size: 26rpx; |
| | | font-weight: bold; |
| | | } |
| | | /* 评论弹窗样式 */ |
| | | .comment-popup { |
| | | background-color: #fff; |
| | | border-radius: 20rpx 20rpx 0 0; |
| | | padding-bottom: env(safe-area-inset-bottom); |
| | | height: 60vh; |
| | | display: flex; |
| | | flex-direction: column; |
| | | } |
| | | |
| | | .popup-header { |
| | | padding: 30rpx; |
| | | display: flex; |
| | | justify-content: space-between; |
| | | align-items: center; |
| | | border-bottom: 1rpx solid #f5f5f5; |
| | | } |
| | | |
| | | .popup-title { |
| | | font-size: 32rpx; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | .close-icon { |
| | | /* font-size: 36rpx; */ |
| | | color: #999; |
| | | } |
| | | |
| | | .comment-list { |
| | | flex: 1; |
| | | padding: 0rpx 20rpx 20rpx 20rpx; |
| | | box-sizing: border-box; |
| | | height: calc(60vh - 260rpx); |
| | | } |
| | | |
| | | .comment-item { |
| | | display: flex; |
| | | padding: 10rpx 0; |
| | | } |
| | | |
| | | .avatar { |
| | | width: 80rpx; |
| | | height: 80rpx; |
| | | border-radius: 50%; |
| | | margin-right: 20rpx; |
| | | } |
| | | |
| | | .comment-content { |
| | | flex: 1; |
| | | } |
| | | |
| | | .nickname { |
| | | font-size: 24rpx; |
| | | color: #666; |
| | | display: block; |
| | | margin-bottom: 10rpx; |
| | | } |
| | | |
| | | .content { |
| | | font-size: 24rpx; |
| | | color: #333; |
| | | display: block; |
| | | margin-bottom: 10rpx; |
| | | } |
| | | |
| | | .time { |
| | | font-size: 24rpx; |
| | | color: #999; |
| | | } |
| | | |
| | | .comment-input-area { |
| | | display: flex; |
| | | padding: 20rpx 30rpx; |
| | | align-items: center; |
| | | } |
| | | |
| | | .comment-input { |
| | | flex: 1; |
| | | background-color: #fff; |
| | | height: 80rpx; |
| | | border: 1px solid #dcdcdc; |
| | | border-radius: 40rpx; |
| | | padding: 0 30rpx; |
| | | font-size: 28rpx; |
| | | } |
| | | |
| | | .placeholder { |
| | | color: #ccc; |
| | | } |
| | | |
| | | .submit-btn { |
| | | margin-left: 20rpx; |
| | | background-color: #07c160; |
| | | color: #fff; |
| | | border-radius: 40rpx; |
| | | padding: 0 30rpx; |
| | | height: 80rpx; |
| | | line-height: 80rpx; |
| | | font-size: 28rpx; |
| | | } |
| | | |
| | | .loading, .empty { |
| | | padding: 40rpx 0; |
| | | text-align: center; |
| | | color: #999; |
| | | } |
| | | </style> |