| | |
| | | <template> |
| | | |
| | | <view class="activity-container"> |
| | | <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}" |
| | |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 视频列表 --> |
| | | <view class="activity-list"> |
| | | <view v-if="currentTab === 0"> |
| | | <scroll-view scroll-y class="activity-list" style="height: 100vh;" @scrolltolower="loadMore" |
| | | :lower-threshold="100"> |
| | | <view v-if="videoCollects.length > 0"> |
| | | <view v-for="(item, idx) in videoCollects" :key="item.id" class="video-item"> |
| | | <!-- 视频封面+播放按钮 --> |
| | | <view class="video-cover-container" @click="jumpToPlay(idx)"> |
| | | <image :src="item.coverUrl" mode="aspectFill" class="video-cover" /> |
| | | <view class="play-icon"> |
| | | <u-icon name="play-circle-fill" size="60" color="#fff"></u-icon> |
| | | </view> |
| | | <view class="video-duration" v-if="item.duration">{{ item.duration }}</view> |
| | | </view> |
| | | |
| | | <!-- 视频信息 --> |
| | | <view class="video-info" @click="jumpToPlay(idx)"> |
| | | <view class="video-title">{{ item.authorName || '未知作者' }}</view> |
| | | <view class="video-meta"> |
| | | <text class="video-weight" v-if="item.weight > 0"> |
| | | <u-icon name="thumb-up-fill" size="24" color="#999"></u-icon> |
| | | {{ item.weight }} |
| | | </text> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 操作按钮 --> |
| | | <view class="video-actions"> |
| | | <button class="cancel-btn" @click.stop="handleCancelCollection(item,'video',idx)"> |
| | | 取消收藏 |
| | | </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="loading ? 'loading' : noMore ? 'nomore' : 'loadmore'" :load-text="{ |
| | | loadmore: '上拉加载更多', |
| | | loading: '正在加载', |
| | | nomore: '没有更多了' |
| | | }" /> |
| | | </view> |
| | | </scroll-view> |
| | | |
| | | |
| | | |
| | | </view> |
| | | |
| | | <view v-if="currentTab === 1"> |
| | | <scroll-view scroll-y class="activity-list" style="height: 100vh;" @scrolltolower="loadMore" |
| | | :lower-threshold="100"> |
| | | <view v-if="goodsCollects.length > 0"> |
| | | <view v-for="(item, idx) in goodsCollects" :key="item.id" class="activity-item"> |
| | | <!-- 封面区域 --> |
| | | <block> |
| | | <image :src="item.original" mode="aspectFill" class="activity-cover" /> |
| | | </block> |
| | | |
| | | <!-- 活动信息 --> |
| | | <view class="activity-info"> |
| | | <view class="activity-title">{{ item.goodsName }}</view> |
| | | <view class="activity-meta"> |
| | | <text class="activity-time">价格:{{ item.price }}元</text> |
| | | <text class="activity-location">{{ item.storeName || '暂无' }}</text> |
| | | </view> |
| | | </view> |
| | | |
| | | <!-- 操作区域 --> |
| | | <view class="action-container"> |
| | | <button class="cancel-btn" @click="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="loading ? 'loading' : noMore ? 'nomore' : 'loadmore'" :load-text="{ |
| | | loadmore: '上拉加载更多', |
| | | loading: '正在加载', |
| | | nomore: '没有更多了' |
| | | }" /> |
| | | </view> |
| | | </scroll-view> |
| | | </view> |
| | | |
| | | <view v-if="currentTab === 2"> |
| | | <scroll-view scroll-y class="activity-list" style="height: 80vh;" @scrolltolower="loadMore" |
| | | :lower-threshold="100"> |
| | | <view v-if="activityCollects.length > 0"> |
| | | <view v-for="(item, idx) in activityCollects" :key="item.id" class="activity-item"> |
| | | <!-- 封面区域 --> |
| | | <block v-if="item.coverType === '图片' || item.coverType === '视频'"> |
| | | <image :src="item.cover" mode="aspectFill" class="activity-cover" /> |
| | | </block> |
| | | <block v-if="item.coverType === '文字'"> |
| | | <view class="activity-cover text-cover">{{ item.cover }}</view> |
| | | </block> |
| | | <!-- 活动信息 --> |
| | | <view class="activity-info"> |
| | | <view class="activity-title">{{ item.activityName }}</view> |
| | | <view class="activity-meta"> |
| | | <text class="activity-time">{{ item.startTime }}</text> |
| | | <text class="activity-time"> {{ item.endTime }}</text> |
| | | <text class="activity-location">{{ item.activityLocation || '暂无' }}</text> |
| | | </view> |
| | | </view> |
| | | <!-- 操作区域 --> |
| | | <view class="action-container"> |
| | | <button class="cancel-btn" @click="handleCancelCollection(item,'activity', idx)" |
| | | hover-class="cancel-btn-hover"> |
| | | 取消收藏 |
| | | </button> |
| | | </view> |
| | | |
| | | <!-- 视频收藏列表 --> |
| | | <view v-if="currentTab === 0" class="list-container"> |
| | | <scroll-view scroll-y class="scroll-view" @scrolltolower="loadMore" :lower-threshold="100"> |
| | | <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> |
| | | <!-- <image :src="getVideoCover()" mode="aspectFill" class="cover-image" /> --> |
| | | <!-- <view v-if="item.duration" class="duration"> |
| | | {{ formatDuration(item.duration) }} |
| | | </view> --> |
| | | </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 v-else class="empty-tip"> |
| | | <text>暂无收藏活动</text> |
| | | </view> |
| | | <view class="load-more"> |
| | | <u-loadmore v-if="activityCollects.length > 0" |
| | | :status="loading ? 'loading' : noMore ? 'nomore' : 'loadmore'" :load-text="{ |
| | | loadmore: '上拉加载更多', |
| | | loading: '正在加载', |
| | | nomore: '没有更多了' |
| | | }" /> |
| | | </view> |
| | | <view style="height: 150rpx"></view> |
| | | </scroll-view> |
| | | |
| | | </view> |
| | | |
| | | |
| | | |
| | | </view> |
| | | <view v-else class="empty-tip"> |
| | | <image src="/static/empty.png" mode="aspectFit" /> |
| | | <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" @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.original" 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"> |
| | | <image src="/static/empty.png" mode="aspectFit" /> |
| | | <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" @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"> |
| | | <image src="/static/empty.png" mode="aspectFit" /> |
| | | <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 '@/components/uview-components/uview-ui'; |
| | | import storage from '@/utils/storage'; |
| | | import {getAuthorCollectVideoPage} from '@/api/user.js' |
| | | import { |
| | | getFilePreviewUrl |
| | | } from '@/api/common.js' |
| | | import { |
| | | changeCollect, |
| | | getMyCollectList |
| | | getMyCollectList, |
| | | changeCollect |
| | | } from '@/api/collect.js' |
| | | import { |
| | | ifError |
| | | } from 'assert' |
| | | export default { |
| | | import storage from '@/utils/storage' |
| | | |
| | | export default { |
| | | data() { |
| | | return { |
| | | total: 0, |
| | | loading: false, |
| | | noMore: false, |
| | | currentTab: 0, // 当前选中的tab索引 |
| | | currentTab: 0, |
| | | tabs: ['视频', '商品', '活动'], |
| | | // |
| | | videoCollects: [], // 收藏视频列表 |
| | | goodsCollects: [], // 收藏商品列表 |
| | | activityCollects: [], // 收藏活动列表 |
| | | collectForm: { |
| | | collectType: '', |
| | | refId: '', |
| | | }, |
| | | videoCollects: [], |
| | | goodsCollects: [], |
| | | activityCollects: [], |
| | | query: { |
| | | authorId: '', |
| | | type: 'video', |
| | | pageNumber: 1, |
| | | pageSize: 5, |
| | | } |
| | | pageSize: 5 |
| | | }, |
| | | loading: false, |
| | | noMore: false, |
| | | total: 0 |
| | | } |
| | | }, |
| | | computed: { |
| | | loadStatus() { |
| | | return this.loading ? 'loading' : this.noMore ? 'nomore' : 'loadmore' |
| | | } |
| | | }, |
| | | onLoad() { |
| | | this.currentTab = 0; |
| | | this.query.authorId = storage.getUserInfo().id |
| | | this.getintit() |
| | | this.loadData() |
| | | }, |
| | | onPullDownRefresh() { |
| | | this.query.pageNumber = 1 |
| | | this.noMore = false |
| | | this.videoCollects = [] |
| | | this.goodsCollects = [] |
| | | this.activityCollects = [] |
| | | this.loadData().finally(() => { |
| | | uni.stopPullDownRefresh() |
| | | }) |
| | | }, |
| | | methods: { |
| | | 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` |
| | | }); |
| | | async getVideoCover(videoPath) { |
| | | return null; |
| | | }, |
| | | /** |
| | | * 下拉刷新时 |
| | | */ |
| | | onPullDownRefresh() { |
| | | this.currentTab = 0; |
| | | this.query.pageNumber = 1; // 重置页码 |
| | | this.noMore = false; |
| | | this.videoCollects = []; |
| | | this.goodsCollects = []; // 收藏商品列表 |
| | | this.activityCollects = []; // 收藏活动列表// 清空数据 |
| | | this.getintit(); |
| | | }, |
| | | loadMore() { |
| | | this.loading = true; |
| | | // 延迟执行让UI有反应时间 |
| | | setTimeout(() => { |
| | | this.query.pageNumber += 1; |
| | | this.getintit(); |
| | | }, 300); |
| | | }, |
| | | |
| | | |
| | | // 跳转到视频播放页 |
| | | // 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) { |
| | | console.log(item) |
| | | this.collectForm.collectType = type; |
| | | this.collectForm.refId = item.id; |
| | | changeCollect(this.collectForm).then(res => { |
| | | if (res.data.code === 200) { |
| | | uni.showToast({ |
| | | title: res.data.msg, // 提示文字 |
| | | icon: 'none', // 图标类型(success/loading/none) |
| | | mask: true // 是否显示透明蒙层(防止触摸穿透) |
| | | }); |
| | | this.query.pageNumber = 1 |
| | | // 因为视频走的mq有延迟,前端直接删除该元素达到效果 |
| | | if (type === 'video') { |
| | | this.videoCollects.splice(index, 1) |
| | | } else { |
| | | this.noMore = false |
| | | this.getintit() |
| | | 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() |
| | | } |
| | | } |
| | | }) |
| | | } |
| | | } |
| | | }) |
| | | }, |
| | | |
| | | }) |
| | | }, |
| | | getUrl(params) { |
| | | getFilePreviewUrl(params).then(res => { |
| | | return res.data.data |
| | | }) |
| | | }, |
| | | // 切换tab |
| | | // 切换标签页 |
| | | switchTab(index) { |
| | | if (this.currentTab !== index) { |
| | | this.currentTab = index |
| | | //切换时页码归0 |
| | | this.query.pageNumber = 0; |
| | | // 清空数据 |
| | | this.videoCollects = []; |
| | | this.goodsCollects = []; |
| | | this.activityCollects = []; |
| | | // 实际项目中可以在这里添加加载数据的逻辑 |
| | | this.getintit() |
| | | this.query.pageNumber = 1 |
| | | this.query.type = ['video', 'goods', 'activity'][index] |
| | | this.videoCollects = [] |
| | | this.goodsCollects = [] |
| | | this.activityCollects = [] |
| | | this.loadData() |
| | | } |
| | | }, |
| | | async getintit() { |
| | | |
| | | // 加载更多 |
| | | loadMore() { |
| | | if (!this.loading && !this.noMore) { |
| | | this.query.pageNumber += 1 |
| | | this.loadData() |
| | | } |
| | | }, |
| | | |
| | | // 加载数据 |
| | | async loadData() { |
| | | if (this.loading) return |
| | | |
| | | this.loading = true |
| | | uni.showLoading({ |
| | | title: '加载中' |
| | | }); |
| | | if (this.currentTab === 0) { |
| | | this.query.type = 'video'; |
| | | getAuthorCollectVideoPage(this.query).then(res => { |
| | | uni.hideLoading(); |
| | | this.loading = false; |
| | | }) |
| | | |
| | | if (res.data.code === 200) { |
| | | const newData = res.data.data |
| | | this.total = res.data.total || 0; |
| | | // 追加或替换数据 |
| | | this.videoCollects = this.query.pageNumber === 1 ? |
| | | newData : |
| | | [...this.videoCollects, ...newData]; |
| | | // 判断是否还有更多数据 |
| | | this.noMore = newData.length < this.query.pageSize || |
| | | this.videoCollects.length >= this.total; |
| | | } |
| | | }) |
| | | } else if (this.currentTab === 1) { |
| | | this.query.type = 'goods'; |
| | | try { |
| | | getMyCollectList(this.query).then(res => { |
| | | uni.hideLoading(); |
| | | this.loading = false; |
| | | if (res.data.code === 200) { |
| | | const newData = res.data.data |
| | | this.total = res.data.total || 0; |
| | | this.total = res.data.total || 0 |
| | | |
| | | this.goodsCollects = this.query.pageNumber === 1 ? |
| | | newData : |
| | | [...this.goodsCollects, ...newData]; |
| | | // 判断是否还有更多数据 |
| | | this.noMore = newData.length < this.query.pageSize || |
| | | this.goodsCollects.length >= this.total; |
| | | } |
| | | }) |
| | | } else if (this.currentTab === 2) { |
| | | this.query.type = 'activity'; |
| | | getMyCollectList(this.query).then(res => { |
| | | uni.hideLoading(); |
| | | this.loading = false; |
| | | 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.activityCollects = this.query.pageNumber === 1 ? |
| | | newData : |
| | | [...this.activityCollects, ...newData]; |
| | | this.noMore = newData.length < this.query.pageSize || |
| | | this.activityCollects.length >= this.total; |
| | | (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"> |
| | | .text-cover { |
| | | 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; |
| | | .page-container { |
| | | padding: 20rpx; |
| | | background-color: #f5f5f5; |
| | | min-height: 100vh; |
| | | } |
| | | |
| | | /* 视频列表专用样式 */ |
| | | .video-item { |
| | | .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); |
| | | |
| | | .scroll-view { |
| | | height: calc(100vh - 200rpx); |
| | | } |
| | | } |
| | | |
| | | .collect-item { |
| | | display: flex; |
| | | padding: 24rpx 0; |
| | | border-bottom: 1rpx solid #f5f5f5; |
| | |
| | | } |
| | | } |
| | | |
| | | .video-cover-container { |
| | | .cover-container { |
| | | position: relative; |
| | | width: 240rpx; |
| | | height: 160rpx; |
| | | width: 250rpx; |
| | | height: 180rpx; |
| | | border-radius: 12rpx; |
| | | overflow: hidden; |
| | | margin-right: 24rpx; |
| | | flex-shrink: 0; |
| | | |
| | | .video-cover { |
| | | .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 { |
| | |
| | | opacity: 0.9; |
| | | } |
| | | |
| | | .video-duration { |
| | | .duration { |
| | | position: absolute; |
| | | right: 8rpx; |
| | | bottom: 8rpx; |
| | |
| | | } |
| | | } |
| | | |
| | | .video-info { |
| | | .info-container { |
| | | flex: 1; |
| | | height: 160rpx; |
| | | display: flex; |
| | | flex-direction: column; |
| | | justify-content: space-between; |
| | | height: 160rpx; |
| | | |
| | | .video-title { |
| | | .title { |
| | | font-size: 30rpx; |
| | | color: #333; |
| | | font-weight: bold; |
| | |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .video-meta { |
| | | .meta { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | font-size: 24rpx; |
| | | color: #999; |
| | | flex-wrap: wrap; |
| | | |
| | | |
| | | |
| | | .video-weight { |
| | | .meta-item { |
| | | display: flex; |
| | | align-items: center; |
| | | margin-right: 20rpx; |
| | | font-size: 24rpx; |
| | | color: #999; |
| | | } |
| | | } |
| | | } |
| | | |
| | | .video-actions { |
| | | .action-container { |
| | | margin-left: 20rpx; |
| | | flex-shrink: 0; |
| | | |
| | |
| | | |
| | | image { |
| | | width: 300rpx; |
| | | height: 300rpx; |
| | | margin-bottom: 30rpx; |
| | | opacity: 0.6; |
| | | } |
| | |
| | | } |
| | | } |
| | | |
| | | .activity-container { |
| | | padding: 20rpx; |
| | | background-color: #f5f5f5; |
| | | min-height: 100vh; |
| | | } |
| | | |
| | | /* Tab 导航样式 */ |
| | | .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; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /* 活动列表样式 */ |
| | | .activity-list { |
| | | background-color: #fff; |
| | | border-radius: 12rpx; |
| | | padding: 20rpx; |
| | | box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.05); |
| | | } |
| | | |
| | | .activity-item { |
| | | display: flex; |
| | | .load-more { |
| | | padding: 20rpx 0; |
| | | border-bottom: 1rpx solid #eee; |
| | | |
| | | &:last-child { |
| | | border-bottom: none; |
| | | } |
| | | } |
| | | |
| | | .activity-cover { |
| | | width: 200rpx; |
| | | height: 140rpx; |
| | | border-radius: 8rpx; |
| | | margin-right: 20rpx; |
| | | } |
| | | |
| | | .activity-info { |
| | | flex: 1; |
| | | position: relative; |
| | | } |
| | | |
| | | .activity-title { |
| | | font-size: 32rpx; |
| | | color: #333; |
| | | font-weight: bold; |
| | | margin-bottom: 12rpx; |
| | | display: -webkit-box; |
| | | -webkit-box-orient: vertical; |
| | | -webkit-line-clamp: 2; |
| | | overflow: hidden; |
| | | } |
| | | |
| | | .activity-meta { |
| | | font-size: 24rpx; |
| | | color: #999; |
| | | margin-bottom: 16rpx; |
| | | |
| | | text { |
| | | display: block; |
| | | margin-bottom: 8rpx; |
| | | } |
| | | } |
| | | |
| | | .activity-status { |
| | | position: absolute; |
| | | right: 0; |
| | | top: 0; |
| | | font-size: 24rpx; |
| | | padding: 4rpx 12rpx; |
| | | border-radius: 20rpx; |
| | | |
| | | &.signed { |
| | | color: #007AFF; |
| | | background-color: rgba(0, 122, 255, 0.1); |
| | | } |
| | | |
| | | &.ended { |
| | | color: #999; |
| | | background-color: rgba(153, 153, 153, 0.1); |
| | | } |
| | | |
| | | &.canceled { |
| | | color: #ff3b30; |
| | | background-color: rgba(255, 59, 48, 0.1); |
| | | } |
| | | } |
| | | |
| | | /* 空状态提示 */ |
| | | .empty-tip { |
| | | text-align: center; |
| | | padding: 100rpx 0; |
| | | |
| | | image { |
| | | width: 300rpx; |
| | | margin-bottom: 30rpx; |
| | | opacity: 0.6; |
| | | } |
| | | |
| | | text { |
| | | display: block; |
| | | font-size: 28rpx; |
| | | color: #999; |
| | | } |
| | | } |
| | | </style> |