<template>
|
<view class="page-container">
|
<!-- 顶部 Tab 导航 -->
|
<view class="tab-nav">
|
<view v-for="(tab, index) in tabs" :key="index" class="tab-item" :class="{active: currentTab === index}"
|
@click="switchTab(index)">
|
{{tab}}
|
</view>
|
</view>
|
|
<!-- 视频收藏列表 -->
|
<view v-if="currentTab === 0" class="list-container">
|
<scroll-view scroll-y :lower-threshold="100" class="scroll-view-container" @scrolltolower="loadMore" >
|
<view v-if="videoCollects.length > 0">
|
<view v-for="(item, idx) in videoCollects" :key="item.id" class="collect-item">
|
<!-- 视频封面 -->
|
<image v-if="tem.videoContentType === 'img'" class="cover-image" :src="item.imgs[0]" mode="aspectFill"></image>
|
|
<view v-else class="cover-container">
|
<video class="cover-image"
|
:src="item.videoUrl"
|
initial-time='0.01'
|
muted
|
:controls="false"
|
:show-center-play-btn="false"
|
object-fit="cover"></video>
|
</view>
|
|
<!-- 视频信息 -->
|
<view class="info-container">
|
<view class="title">{{ item.title || '无标题视频' }}</view>
|
<view class="meta">
|
<view class="meta-item">
|
<u-icon name="account-fill" size="24" color="#999"></u-icon>
|
{{ item.authorName || '未知作者' }}
|
</view>
|
<view class="meta-item" v-if="item.weight > 0">
|
<u-icon name="thumb-up-fill" size="24" color="#999"></u-icon>
|
{{ item.weight }}
|
</view>
|
</view>
|
</view>
|
|
<!-- 取消收藏按钮 -->
|
<view class="action-container">
|
<button class="cancel-btn" @click.stop="handleCancelCollection(item, 'video', idx)"
|
hover-class="cancel-btn-hover">
|
取消收藏
|
</button>
|
</view>
|
</view>
|
</view>
|
<view v-else class="empty-tip">
|
|
<text>暂无收藏视频</text>
|
</view>
|
<view class="load-more">
|
<u-loadmore v-if="videoCollects.length > 0" :status="loadStatus" :load-text="{
|
loadmore: '上拉加载更多',
|
loading: '正在加载',
|
nomore: '没有更多了'
|
}" />
|
</view>
|
</scroll-view>
|
</view>
|
|
<!-- 商品收藏列表 -->
|
<view v-if="currentTab === 1" class="list-container">
|
<scroll-view scroll-y class="scroll-view-container" @scrolltolower="loadMore" :lower-threshold="100">
|
<view v-if="goodsCollects.length > 0">
|
<view v-for="(item, idx) in goodsCollects" :key="item.id" class="collect-item">
|
<!-- 商品封面 -->
|
<view class="cover-container">
|
<image :src="item.image" mode="aspectFill" class="cover-image" />
|
</view>
|
|
<!-- 商品信息 -->
|
<view class="info-container">
|
<view class="title">{{ item.goodsName }}</view>
|
<view class="meta">
|
<view class="meta-item">
|
<u-icon name="rmb-circle-fill" size="24" color="#FF5500"></u-icon>
|
{{ item.price }}元
|
</view>
|
<!-- <view class="meta-item">
|
<u-icon name="home-fill" size="24" color="#999"></u-icon>
|
{{ item.storeName || '暂无' }}
|
</view> -->
|
</view>
|
</view>
|
|
<!-- 取消收藏按钮 -->
|
<view class="action-container">
|
<button class="cancel-btn" @click.stop="handleCancelCollection(item, 'goods', idx)"
|
hover-class="cancel-btn-hover">
|
取消收藏
|
</button>
|
</view>
|
</view>
|
</view>
|
<view v-else class="empty-tip">
|
<text>暂无收藏商品</text>
|
</view>
|
<view class="load-more">
|
<u-loadmore v-if="goodsCollects.length > 0" :status="loadStatus" :load-text="{
|
loadmore: '上拉加载更多',
|
loading: '正在加载',
|
nomore: '没有更多了'
|
}" />
|
</view>
|
</scroll-view>
|
</view>
|
|
<!-- 活动收藏列表 -->
|
<view v-if="currentTab === 2" class="list-container">
|
<scroll-view scroll-y class="scroll-view-container" @scrolltolower="loadMore" :lower-threshold="100">
|
<view v-if="activityCollects.length > 0">
|
<view v-for="(item, idx) in activityCollects" :key="item.id" class="collect-item">
|
<!-- 活动封面 -->
|
<view class="cover-container">
|
<image v-if="item.coverType === '图片' || item.coverType === '视频'" :src="item.cover"
|
mode="aspectFill" class="cover-image" />
|
<view v-else-if="item.coverType === '文字'" class="text-cover">
|
{{ item.cover }}
|
</view>
|
</view>
|
|
<!-- 活动信息 -->
|
<view class="info-container">
|
<view class="title">{{ item.activityName }}</view>
|
<view class="meta">
|
<view class="meta-item">
|
<u-icon name="calendar-fill" size="24" color="#999"></u-icon>
|
{{ item.startTime }} ~ {{ item.endTime }}
|
</view>
|
<view class="meta-item">
|
<u-icon name="map-pin-fill" size="24" color="#999"></u-icon>
|
{{ item.activityLocation || '暂无' }}
|
</view>
|
</view>
|
</view>
|
|
<!-- 取消收藏按钮 -->
|
<view class="action-container">
|
<button class="cancel-btn" @click.stop="handleCancelCollection(item, 'activity', idx)"
|
hover-class="cancel-btn-hover">
|
取消收藏
|
</button>
|
</view>
|
</view>
|
</view>
|
<view v-else class="empty-tip">
|
<text>暂无收藏活动</text>
|
</view>
|
<view class="load-more">
|
<u-loadmore v-if="activityCollects.length > 0" :status="loadStatus" :load-text="{
|
loadmore: '上拉加载更多',
|
loading: '正在加载',
|
nomore: '没有更多了'
|
}" />
|
</view>
|
</scroll-view>
|
</view>
|
</view>
|
</template>
|
|
<script>
|
import { onMounted } from "vue"
|
import {
|
getMyCollectList,
|
changeCollect
|
} from '@/api/collect.js'
|
import storage from '@/utils/storage'
|
|
export default {
|
name:'myCollect',
|
data() {
|
return {
|
currentTab: 0,
|
tabs: ['视频', '商品', '活动'],
|
videoCollects: [],
|
goodsCollects: [],
|
activityCollects: [],
|
query: {
|
authorId: '',
|
type: 'video',
|
pageNumber: 1,
|
pageSize: 5
|
},
|
loading: false,
|
noMore: false,
|
total: 0
|
}
|
},
|
computed: {
|
loadStatus() {
|
return this.loading ? 'loading' : this.noMore ? 'nomore' : 'loadmore'
|
}
|
},
|
mounted() {
|
this.query.authorId = storage.getUserInfo().id;
|
this.loadData();
|
},
|
onPullDownRefresh() {
|
this.query.pageNumber = 1
|
this.noMore = false
|
this.videoCollects = []
|
this.goodsCollects = []
|
this.activityCollects = []
|
this.loadData().finally(() => {
|
uni.stopPullDownRefresh()
|
})
|
},
|
methods: {
|
async getVideoCover(videoPath) {
|
return null;
|
},
|
|
|
// 跳转到视频播放页
|
// jumpToPlay(index) {
|
// const playInfo = {
|
// videoList: this.videoCollects,
|
// nomore: this.noMore,
|
// pageNumber: this.query.pageNumber,
|
// playIndex: index
|
// }
|
// uni.setStorageSync("playInfo", playInfo)
|
// uni.navigateTo({
|
// url: `/pages/video/video-play?authorId=${this.query.authorId}&videoFrom=collect`
|
// })
|
// },
|
|
// 取消收藏
|
handleCancelCollection(item, type, index) {
|
uni.showModal({
|
title: '提示',
|
content: '确定要取消收藏吗?',
|
success: (res) => {
|
if (res.confirm) {
|
changeCollect({
|
collectType: type,
|
refId: item.id
|
}).then(res => {
|
if (res.data.code === 200) {
|
uni.showToast({
|
title: res.data.msg,
|
icon: 'none'
|
})
|
if (type === 'video') {
|
this.videoCollects.splice(index, 1)
|
} else {
|
this.query.pageNumber = 1
|
this.noMore = false
|
this.loadData()
|
}
|
}
|
})
|
}
|
}
|
})
|
},
|
|
// 切换标签页
|
switchTab(index) {
|
if (this.currentTab !== index) {
|
this.currentTab = index
|
this.query.pageNumber = 1
|
this.query.type = ['video', 'goods', 'activity'][index]
|
this.videoCollects = []
|
this.goodsCollects = []
|
this.activityCollects = []
|
this.loadData()
|
}
|
},
|
|
// 加载更多
|
loadMore() {
|
if (!this.loading && !this.noMore) {
|
this.query.pageNumber += 1
|
this.loadData()
|
}
|
},
|
|
// 加载数据
|
async loadData() {
|
if (this.loading) return
|
|
this.loading = true
|
uni.showLoading({
|
title: '加载中'
|
})
|
|
try {
|
getMyCollectList(this.query).then(res => {
|
if (res.data.code === 200) {
|
const newData = res.data.data
|
this.total = res.data.total || 0
|
|
// 根据当前标签页更新对应数据
|
if (this.currentTab === 0) {
|
this.videoCollects = this.query.pageNumber === 1 ?
|
newData :
|
[...this.videoCollects, ...newData]
|
} else if (this.currentTab === 1) {
|
this.goodsCollects = this.query.pageNumber === 1 ?
|
newData :
|
[...this.goodsCollects, ...newData]
|
} else if (this.currentTab === 2) {
|
this.activityCollects = this.query.pageNumber === 1 ?
|
newData :
|
[...this.activityCollects, ...newData]
|
}
|
|
this.noMore = newData.length < this.query.pageSize ||
|
(this.currentTab === 0 ? this.videoCollects :
|
this.currentTab === 1 ? this.goodsCollects : this.activityCollects)
|
.length >= this.total
|
}
|
});
|
|
} catch (error) {
|
console.error(error)
|
uni.showToast({
|
title: '加载失败',
|
icon: 'none'
|
})
|
} finally {
|
this.loading = false
|
uni.hideLoading()
|
}
|
}
|
}
|
}
|
</script>
|
|
<style lang="scss">
|
.page-container {
|
padding: 20rpx;
|
background-color: #f5f5f5;
|
}
|
|
.tab-nav {
|
display: flex;
|
background-color: #fff;
|
border-radius: 12rpx;
|
margin-bottom: 20rpx;
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
|
.tab-item {
|
flex: 1;
|
text-align: center;
|
padding: 24rpx 0;
|
font-size: 28rpx;
|
color: #666;
|
position: relative;
|
|
&.active {
|
color: #007AFF;
|
font-weight: bold;
|
|
&::after {
|
content: '';
|
position: absolute;
|
bottom: 0;
|
left: 50%;
|
transform: translateX(-50%);
|
width: 80rpx;
|
height: 6rpx;
|
background-color: #007AFF;
|
border-radius: 3rpx;
|
}
|
}
|
}
|
}
|
|
.list-container {
|
background-color: #fff;
|
border-radius: 12rpx;
|
padding: 20rpx;
|
box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05);
|
height: 70vh;
|
|
}
|
/* 内容区域优化 */
|
.scroll-view-container {
|
width: 100%;
|
padding: 0 10rpx;
|
height: calc(100vh - 554rpx);
|
background-color: #fff;
|
overflow: hidden;
|
padding: 0 10rpx;
|
}
|
.collect-item {
|
display: flex;
|
padding: 24rpx 0;
|
border-bottom: 1rpx solid #f5f5f5;
|
align-items: center;
|
|
&:last-child {
|
border-bottom: none;
|
}
|
}
|
|
.cover-container {
|
position: relative;
|
width: 250rpx;
|
height: 180rpx;
|
border-radius: 12rpx;
|
overflow: hidden;
|
margin-right: 24rpx;
|
flex-shrink: 0;
|
|
.cover-image {
|
width: 100%;
|
height: 100%;
|
}
|
|
.text-cover {
|
width: 100%;
|
height: 100%;
|
display: flex;
|
align-items: center;
|
justify-content: center;
|
background: linear-gradient(135deg, #6a11cb 0%, #2575fc 100%);
|
color: #fff;
|
font-size: 28rpx;
|
padding: 16rpx;
|
line-height: 1.4;
|
}
|
|
.play-icon {
|
position: absolute;
|
top: 50%;
|
left: 50%;
|
transform: translate(-50%, -50%);
|
opacity: 0.9;
|
}
|
|
.duration {
|
position: absolute;
|
right: 8rpx;
|
bottom: 8rpx;
|
background: rgba(0, 0, 0, 0.6);
|
color: #fff;
|
font-size: 20rpx;
|
padding: 4rpx 12rpx;
|
border-radius: 20rpx;
|
}
|
}
|
|
.info-container {
|
flex: 1;
|
height: 160rpx;
|
display: flex;
|
flex-direction: column;
|
justify-content: space-between;
|
|
.title {
|
font-size: 30rpx;
|
color: #333;
|
font-weight: bold;
|
display: -webkit-box;
|
-webkit-box-orient: vertical;
|
-webkit-line-clamp: 2;
|
overflow: hidden;
|
}
|
|
.meta {
|
display: flex;
|
flex-wrap: wrap;
|
|
.meta-item {
|
display: flex;
|
align-items: center;
|
margin-right: 20rpx;
|
font-size: 24rpx;
|
color: #999;
|
}
|
}
|
}
|
|
.action-container {
|
margin-left: 20rpx;
|
flex-shrink: 0;
|
|
.cancel-btn {
|
background: #f5f5f5;
|
color: #666;
|
border: none;
|
font-size: 24rpx;
|
padding: 8rpx 20rpx;
|
border-radius: 20rpx;
|
|
&:active {
|
background: #eee;
|
}
|
}
|
}
|
|
.empty-tip {
|
text-align: center;
|
padding: 100rpx 0;
|
|
image {
|
width: 300rpx;
|
height: 300rpx;
|
margin-bottom: 30rpx;
|
opacity: 0.6;
|
}
|
|
text {
|
display: block;
|
font-size: 28rpx;
|
color: #999;
|
}
|
}
|
|
.load-more {
|
padding: 20rpx 0;
|
}
|
</style>
|