| | |
| | | <text class="stat-label">获赞</text> |
| | | </view> |
| | | </view> |
| | | |
| | | |
| | | <!-- 关注按钮 --> |
| | | <view class="follow-btn-container" v-if="!userInfo.self"> |
| | | <button |
| | | class="follow-btn" |
| | | :class="{followed: userInfo.hasSub}" |
| | | <button |
| | | class="follow-btn" |
| | | :class="{followed: userInfo.hasSub}" |
| | | @click="toggleFollow" |
| | | > |
| | | {{userInfo.hasSub ? '取消关注' : '关注'}} |
| | | </button> |
| | | </view> |
| | | |
| | | |
| | | <view class="edit-icon" @click="editInfo" v-if="userInfo.self"> |
| | | <uni-icons type="compose" size="20" color="#666"></uni-icons>编辑主页信息 |
| | | </view> |
| | | </view> |
| | | |
| | | |
| | | <!-- 作品/喜欢切换 --> |
| | | <view class="tab-bar"> |
| | | <view |
| | | class="tab-item" |
| | | :class="{active: currentTab === 'works'}" |
| | | <view |
| | | class="tab-item" |
| | | :class="{active: currentTab === 'works'}" |
| | | @click="switchTab('works')" |
| | | > |
| | | 作品{{`(${videoTotal})`}} |
| | | </view> |
| | | <view |
| | | class="tab-item" |
| | | :class="{active: currentTab === 'likes'}" |
| | | @click="switchTab('likes')" |
| | | <view |
| | | class="tab-item" |
| | | :class="{active: currentTab === 'collect'}" |
| | | @click="switchTab('collect')" |
| | | > |
| | | 喜欢 |
| | | 收藏 |
| | | </view> |
| | | <view |
| | | class="tab-item" |
| | | :class="{active: currentTab === 'likes'}" |
| | | @click="switchTab('likes')" |
| | | > |
| | | 喜欢 |
| | | </view> |
| | | </view> |
| | | |
| | | |
| | | <!-- 视频列表 --> |
| | | <scroll-view class="video-list" scroll-y :show-scrollbar="false" @scrolltolower="getPage" v-show="currentTab === 'works' && videoList.length > 0"> |
| | | <view class="video-container"> |
| | | <view |
| | | class="video-item" |
| | | v-for="(item, index) in videoList" |
| | | class="video-item" |
| | | v-for="(item, index) in videoList" |
| | | :key="item.id" |
| | | @click="playAuthorVideo(index)" |
| | | > |
| | | <image class="video-cover" :src="item.coverUrl" mode="aspectFill"></image> |
| | | <image class="video-cover" @click="playAuthorVideo(index)" :src="item.videoContentType === 'video' ? item.coverUrl : item.imgs[0]" mode="aspectFill"></image> |
| | | <view class="video-info"> |
| | | <view class="video-stats"> |
| | | <view class="stat"> |
| | | <uni-icons type="heart" size="16" color="#fff"></uni-icons> |
| | | <text>{{item.collectNum}}</text> |
| | | <view class="more-op" v-if="userInfo.self"> |
| | | <dropdown-menu |
| | | :options="item.options" |
| | | :data="{id: item.id, title: item.title}" |
| | | placement="top" |
| | | theme-color="#07C160" |
| | | @change="handleChange" |
| | | ></dropdown-menu> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </scroll-view> |
| | | <scroll-view class="video-list" scroll-y :show-scrollbar="false" @scrolltolower="getPage" v-show="currentTab === 'likes' && collectVideoList.length > 0"> |
| | | <scroll-view class="video-list" scroll-y :show-scrollbar="false" @scrolltolower="getPage" v-show="currentTab === 'collect' && collectVideoList.length > 0"> |
| | | <view class="video-container"> |
| | | <view |
| | | class="video-item" |
| | | v-for="(item, index) in collectVideoList" |
| | | class="video-item" |
| | | v-for="(item, index) in collectVideoList" |
| | | :key="item.id" |
| | | @click="playCollectVideo(index)" |
| | | > |
| | | <image class="video-cover" :src="item.coverUrl" mode="aspectFill"></image> |
| | | <image class="video-cover" :src="item.videoContentType === 'video' ? item.coverUrl : item.imgs[0]" mode="aspectFill"></image> |
| | | <view class="video-info"> |
| | | <view class="video-stats"> |
| | | <view class="stat"> |
| | |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </scroll-view> |
| | | |
| | | <scroll-view class="video-list" scroll-y :show-scrollbar="false" @scrolltolower="getPage" v-show="currentTab === 'likes' && likeVideoList.length > 0"> |
| | | <view class="video-container"> |
| | | <view |
| | | class="video-item" |
| | | v-for="(item, index) in likeVideoList" |
| | | :key="item.id" |
| | | @click="playLikeVideo(index)" |
| | | > |
| | | <image class="video-cover" :src="item.videoContentType === 'video' ? item.coverUrl : item.imgs[0]" mode="aspectFill"></image> |
| | | <view class="video-info"> |
| | | <view class="video-stats"> |
| | | <view class="stat"> |
| | | <uni-icons type="heart" size="16" color="#fff"></uni-icons> |
| | | <text>{{item.collectNum}}</text> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </view> |
| | | </scroll-view> |
| | | |
| | | <!-- 空状态 --> |
| | | <view class="empty-state" v-if="videoList.length === 0 && currentTab === 'works'"> |
| | | <!-- <image src="/static/images/empty.png" mode="aspectFit" class="empty-image"></image> --> |
| | | <text class="empty-text">还未发布作品哦~</text> |
| | | </view> |
| | | <!-- 空状态 --> |
| | | <view class="empty-state" v-if="collectVideoList.length === 0 && currentTab === 'likes'"> |
| | | <view class="empty-state" v-if="collectVideoList.length === 0 && currentTab === 'collect'"> |
| | | <!-- <image src="/static/images/empty.png" mode="aspectFit" class="empty-image"></image> --> |
| | | <text class="empty-text">还没有收藏作品哦~</text> |
| | | </view> |
| | | <!-- 空状态 --> |
| | | <view class="empty-state" v-if="likeVideoList.length === 0 && currentTab === 'likes'"> |
| | | <!-- <image src="/static/images/empty.png" mode="aspectFit" class="empty-image"></image> --> |
| | | <text class="empty-text">还没有点赞作品哦~</text> |
| | | </view> |
| | | |
| | | <!-- 删除视频提醒框 --> |
| | | <uni-popup ref="delDialog" type="dialog"> |
| | | <uni-popup-dialog type="error" cancelText="取消" confirmText="删除" title="提醒" :content="`您正在删除:${opVideo.title}`" @confirm="deleteVideo" |
| | | @close="dialogClose"></uni-popup-dialog> |
| | | </uni-popup> |
| | | |
| | | <!-- 下架视频提醒框 --> |
| | | <uni-popup ref="downDialog" type="dialog"> |
| | | <uni-popup-dialog type="error" cancelText="取消" confirmText="下架" title="提醒" :content="`您正在下架:${opVideo.title}`" @confirm="downVideo" |
| | | @close="dialogClose"></uni-popup-dialog> |
| | | </uni-popup> |
| | | </view> |
| | | </template> |
| | | |
| | | <script> |
| | | import {getAuthorInfo, getAuthorVideoPage, getAuthorCollectVideoPage} from '@/api/user.js' |
| | | import {subscribe, unSubscribe} from '@/api/video.js' |
| | | import DropdownMenu from '@/components/dropdown-menu.vue' |
| | | |
| | | import {getAuthorInfo, getAuthorVideoPage, getAuthorCollectVideoPage, getAuthorLikeVideoPage} from '@/api/user.js' |
| | | import {subscribe, unSubscribe, delVideo, updateVideo, userDownVideo} from '@/api/video.js' |
| | | export default { |
| | | components: {DropdownMenu}, |
| | | data() { |
| | | return { |
| | | options: [ |
| | | { command: 1, label: '北京' }, |
| | | { command: 2, label: '上海' }, |
| | | { command: 3, label: '广州' } |
| | | ], |
| | | opVideo: { // 正在操作的视频 |
| | | id: '', |
| | | title: '' |
| | | }, |
| | | currentTab: 'works', // works: 作品, likes: 喜欢 |
| | | authorId: '', |
| | | userInfo: { |
| | |
| | | pageNumber: 1, |
| | | pageSize: 10 |
| | | }, |
| | | likeVideoQuery: { |
| | | authorId: '', |
| | | pageNumber: 1, |
| | | pageSize: 10 |
| | | }, |
| | | videoTotal: 0, |
| | | videoList: [], // 作品 |
| | | collectVideoList: [], // 收藏 |
| | | likeVideoList: [], // 点赞 |
| | | nomoreVideo: false, |
| | | nomoreCollectVideo: false |
| | | nomoreCollectVideo: false, |
| | | nomoreLikeVideo: false, |
| | | } |
| | | }, |
| | | onShow() { |
| | | this.getAuthorInfo(); |
| | | if (this.authorId) { |
| | | this.getAuthorInfo(); |
| | | if (this.currentTab === 'works') { |
| | | this.videoQuery.pageNumber = 1 |
| | | this.nomoreVideo = false |
| | | this.getAuthorVideoPage(); |
| | | } else if (this.currentTab === 'collect') { |
| | | this.collectVideoQuery.pageNumber = 1 |
| | | this.nomoreCollectVideo = false |
| | | this.getAuthorCollectVideoPage() |
| | | } else if (this.currentTab === 'likes') { |
| | | this.likeVideoQuery.pageNumber = 1 |
| | | this.nomoreLikeVideo = false |
| | | this.getAuthorLikeVideoPage() |
| | | } |
| | | } |
| | | }, |
| | | onLoad(option) { |
| | | console.log("收到参数", option); |
| | | this.authorId = option.authorId; |
| | | this.getAuthorInfo(); |
| | | this.getAuthorVideoPage(); |
| | | }, |
| | | methods: { |
| | | dialogClose() { |
| | | this.opVideo = { |
| | | id: '', |
| | | title: '' |
| | | } |
| | | }, |
| | | // 下架视频 |
| | | downVideo() { |
| | | userDownVideo(this.opVideo.id).then(res => { |
| | | uni.showToast({ |
| | | title: '下架成功', |
| | | duration: 2000 |
| | | }); |
| | | // 刷新数据 |
| | | this.videoList = []; |
| | | this.videoQuery.pageNumber = 1; |
| | | this.getAuthorVideoPage(); |
| | | }) |
| | | }, |
| | | // 删除视频 |
| | | deleteVideo() { |
| | | delVideo(this.opVideo.id).then(res => { |
| | | uni.showToast({ |
| | | title: '删除成功', |
| | | duration: 2000 |
| | | }); |
| | | // 刷新数据 |
| | | this.videoList = []; |
| | | this.videoQuery.pageNumber = 1; |
| | | this.getAuthorVideoPage(); |
| | | }) |
| | | }, |
| | | // 触发视频操作 |
| | | handleChange(value, data) { |
| | | console.log('选中值:', value) |
| | | this.opVideo.id = data.id; |
| | | this.opVideo.title = data.title; |
| | | if (value === 'DELETE') { |
| | | this.$refs.delDialog.open() |
| | | } else if (value === 'DOWN') { |
| | | this.$refs.downDialog.open() |
| | | } else if (value === 'EDIT') { |
| | | // 跳转编辑视频页面 |
| | | uni.navigateTo({ |
| | | url: `/pages/video/video-edit?id=${this.opVideo.id}` |
| | | }); |
| | | } |
| | | }, |
| | | getPage() { |
| | | if(this.currentTab === 'works') { |
| | | if(this.nomoreVideo) { |
| | |
| | | this.videoQuery.pageNumber += 1; |
| | | } |
| | | }) |
| | | } else if(this.currentTab === 'likes') { |
| | | } else if(this.currentTab === 'collect') { |
| | | if(this.nomoreCollectVideo) { |
| | | return; |
| | | } |
| | |
| | | this.nomoreCollectVideo = true; |
| | | } else { |
| | | this.collectVideoQuery.pageNumber += 1; |
| | | } |
| | | }) |
| | | } else if(this.currentTab === 'likes') { |
| | | if(this.nomoreLikeVideo) { |
| | | return; |
| | | } |
| | | getAuthorLikeVideoPage(this.likeVideoQuery).then(res => { |
| | | if(this.likeVideoQuery.pageNumber === 1) { |
| | | this.likeVideoList = res.data.data |
| | | } else { |
| | | this.likeVideoList = [ |
| | | ...this.likeVideoList, |
| | | ...res.data.data.filter( |
| | | (newItem) => !this.likeVideoList.some((oldItem) => oldItem.id === newItem.id) |
| | | ), |
| | | ]; |
| | | } |
| | | if(res.data.data.length < this.likeVideoQuery.pageSize) { |
| | | this.nomoreLikeVideo = true; |
| | | } else { |
| | | this.likeVideoQuery.pageNumber += 1; |
| | | } |
| | | }) |
| | | } |
| | |
| | | this.currentTab = tab; |
| | | if(tab === 'works') { |
| | | this.collectVideoList = [] |
| | | this.likeVideoList = [] |
| | | this.videoQuery.pageNumber = 1 |
| | | this.nomoreVideo = false |
| | | this.getAuthorVideoPage() |
| | | } else if(tab === 'collect') { |
| | | this.videoList = [] |
| | | this.likeVideoList = [] |
| | | this.collectVideoQuery.pageNumber = 1 |
| | | this.nomoreCollectVideo = false |
| | | this.getAuthorCollectVideoPage() |
| | | } else if(tab === 'likes') { |
| | | this.videoList = [] |
| | | this.collectVideoQuery.pageNumber = 1 |
| | | this.getAuthorCollectVideoPage() |
| | | this.collectVideoList = [] |
| | | this.likeVideoQuery.pageNumber = 1 |
| | | this.nomoreLikeVideo = false |
| | | this.getAuthorLikeVideoPage() |
| | | } |
| | | }, |
| | | // 获取作者喜欢的视频 |
| | | async getAuthorLikeVideoPage() { |
| | | this.likeVideoQuery.authorId = this.authorId |
| | | getAuthorLikeVideoPage(this.likeVideoQuery).then(res => { |
| | | this.likeVideoList = res.data.data |
| | | if(res.data.data.length < this.likeVideoQuery.pageSize) { |
| | | this.nomoreLikeVideo = true; |
| | | } |
| | | }) |
| | | }, |
| | | // 获取作者的收藏视频 |
| | | async getAuthorCollectVideoPage() { |
| | | this.collectVideoQuery.authorId = this.authorId |
| | |
| | | }); |
| | | }, |
| | | // 播放收藏视频 |
| | | playAuthorVideo(index) { |
| | | playCollectVideo(index) { |
| | | const playInfo = { |
| | | videoList: this.collectVideoList, |
| | | nomore: this.nomoreCollectVideo, |
| | |
| | | url: `/pages/video/video-play?authorId=${this.authorId}&videoFrom=collect` |
| | | }); |
| | | }, |
| | | // 播放点赞视频 |
| | | playLikeVideo(index) { |
| | | const playInfo = { |
| | | videoList: this.likeVideoList, |
| | | nomore: this.nomoreLikeVideo, |
| | | pageNumber: this.likeVideoQuery.pageNumber, |
| | | playIndex: index |
| | | } |
| | | uni.setStorageSync("playInfo", playInfo) |
| | | uni.navigateTo({ |
| | | url: `/pages/video/video-play?authorId=${this.authorId}&videoFrom=like` |
| | | }); |
| | | }, |
| | | // 编辑个人资料 |
| | | editInfo() { |
| | | uni.navigateTo({ |
| | | url: `/pages/video/home-page-edit?authorId=${this.authorId}&avatar=${this.userInfo.avatar}&motto=${this.userInfo.motto || ''}&nickName=${this.userInfo.nickName}` |
| | | }); |
| | | }, |
| | | |
| | | |
| | | // 跳转到粉丝/关注列表 |
| | | navigateToFollow(type) { |
| | | uni.navigateTo({ |
| | | url: `/pages/user/follow?type=${type}` |
| | | }); |
| | | }, |
| | | |
| | | |
| | | // 跳转到点赞列表 |
| | | navigateToLike() { |
| | | uni.navigateTo({ |
| | |
| | | } |
| | | |
| | | .video-list { |
| | | width: calc(100% - 20rpx); |
| | | padding: 0 10rpx; |
| | | height: calc(100vh - 554rpx); |
| | | background-color: #fff; |
| | | width: 100%; |
| | | padding: 0 10rpx; |
| | | height: calc(100vh - 554rpx); |
| | | background-color: #fff; |
| | | } |
| | | |
| | | .video-container { |
| | | display: flex; |
| | | flex-wrap: wrap; |
| | | justify-content: space-between; |
| | | } |
| | | |
| | | .video-item { |
| | | width: 50%; |
| | | padding: 10rpx; |
| | | box-sizing: border-box; |
| | | width: 49%; |
| | | margin-bottom: 20rpx; |
| | | position: relative; |
| | | } |
| | | |
| | |
| | | |
| | | .video-info { |
| | | position: absolute; |
| | | bottom: 20rpx; |
| | | left: 20rpx; |
| | | right: 20rpx; |
| | | color: #fff; |
| | | font-size: 24rpx; |
| | | bottom: 10rpx; |
| | | left: 0; |
| | | right: 0; |
| | | padding: 0 10rpx; |
| | | box-sizing: border-box; |
| | | } |
| | | |
| | | .video-title { |
| | |
| | | |
| | | .video-stats { |
| | | display: flex; |
| | | width: 100%; |
| | | } |
| | | |
| | | .stat { |
| | | display: flex; |
| | | width: 100%; |
| | | align-items: center; |
| | | margin-right: 20rpx; |
| | | text-shadow: 0 0 5rpx rgba(0, 0, 0, 0.5); |
| | | position: relative; |
| | | } |
| | | |
| | | .more-op { |
| | | position: absolute; |
| | | right: 0; |
| | | } |
| | | |
| | | .stat text { |
| | | margin-left: 5rpx; |
| | | color: #fff; |
| | | font-size: 14px; |
| | | } |
| | | |
| | | .empty-state { |
| | |
| | | height: 70rpx; |
| | | line-height: 70rpx; |
| | | padding: 0 40rpx; |
| | | |
| | | |
| | | &::after { |
| | | border: none; |
| | | } |
| | | |
| | | |
| | | &.followed { |
| | | background-color: #f5f5f5; |
| | | color: #666; |
| | | } |
| | | } |
| | | |
| | | .video-container { |
| | | display: flex; |
| | | flex-wrap: wrap |
| | | } |
| | | </style> |
| | | </style> |