绿满眶商城微信小程序-uniapp
zxl
2025-07-29 9ac342cdebca34f39243d4d724709f55dc02baac
活动列表问题,视频主页图片显示问题
3个文件已修改
928 ■■■■ 已修改文件
pages/mine/activity/detail.vue 102 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/mine/myCollect/myCollect.vue 799 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/video/home-page.vue 27 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
pages/mine/activity/detail.vue
@@ -1,5 +1,5 @@
<template>
    <view class="container"  @touchstart="touchStart" @touchend="touchEnd">
    <view class="container" @touchstart="touchStart" @touchend="touchEnd">
        <!-- 顶部海报图 -->
        <!-- 动态封面区域 -->
        <view class="cover-container">
@@ -68,8 +68,13 @@
<script>
    import '@/components/uview-components/uview-ui';
    import {changeCollect} from '@/api/collect.js'
    import {getActivityDetail, activityReport} from '@/api/activity.js';
    import {
        changeCollect
    } from '@/api/collect.js'
    import {
        getActivityDetail,
        activityReport
    } from '@/api/activity.js';
    export default {
        data() {
            return {
@@ -182,7 +187,9 @@
                        this.activityInfo.startTime = res.data.data.startTime;
                        this.activityInfo.endTime = res.data.data.endTime;
                        this.activityInfo.activityLocation = res.data.data.activityLocation;
                        this.activityInfo.activityContent = '<h2>活动介绍</h2>' + res.data.data.activityContent;
                        this.activityInfo.activityContent = '<h2>活动介绍</h2>' + this.processRichText(res.data.data.activityContent);
                        this.activityInfo.activityType = res.data.data.activityType;
                        this.activityInfo.limitUserNum = res.data.data.limitUserNum;
                        this.reportBtn = res.data.data.isReport;
@@ -190,6 +197,26 @@
                        this.activityInfo.url = res.data.data.url;
                    }
                })
            },
            // 在获取富文本数据后处理
            processRichText(content) {
              // 处理图片
              content = content.replace(/<img[^>]*>/gi, (match) => {
                if (!/style=['"]/.test(match)) {
                  return match.replace(/<img/, '<img style="max-width:100% !important;height:auto !important;display:block;margin:10px auto;border-radius:8rpx;"');
                }
                return match;
              });
              // 处理视频
              content = content.replace(/<video[^>]*>/gi, (match) => {
                if (!/style=['"]/.test(match)) {
                  return match.replace(/<video/, '<video style="max-width:100% !important;height:auto !important;display:block;margin:10px auto;"');
                }
                return match;
              });
              return content;
            },
            loadDetailData() {
                //获得详情接口
@@ -281,14 +308,25 @@
        margin-bottom: 15rpx;
    }
    /* 修改后的样式 */
    .status-bar {
        position: absolute;
        bottom: 40rpx;
        position: fixed;
        bottom: 0;
        left: 0;
        right: 0;
        width: 100%;
        display: flex;
        align-items: center;
        padding: 10px 15px;
        padding: 20rpx 30rpx;
        justify-content: space-between;
        background-color: #fff;
        box-shadow: 0 -2rpx 10rpx rgba(0, 0, 0, 0.1);
        z-index: 100;
    }
    /* 调整容器底部内边距 */
    .container {
        padding-bottom: 120rpx;
    }
    .signup-btn {
@@ -344,53 +382,19 @@
    .rich-text-container {
        padding: 15px;
        overflow: hidden;
        /* 防止内容溢出 */
    }
    .rich-text-content {
        width: 100%;
        max-width: 100%;  /* 限制最大宽度 */
        line-height: 1.6;
        color: #333;
        font-size: 28rpx;
    }
    .rich-text-content img {
        max-width: 100%;
        height: auto;
        display: block;
        margin: 10px auto;
    }
    .rich-text-content video {
        max-width: 100%;
        height: auto;
        display: block;
        margin: 10px auto;
    }
    .rich-text-content p {
        margin-bottom: 10px;
    }
    .rich-text-content h1,
    .rich-text-content h2,
    .rich-text-content h3,
    .rich-text-content h4 {
        margin: 20px 0 10px;
        color: #222;
    }
    .rich-text-content h1 {
        font-size: 24px;
    }
    .rich-text-content h2 {
        font-size: 22px;
    }
    .rich-text-content h3 {
        font-size: 20px;
    }
    .rich-text-content h4 {
        font-size: 18px;
        word-wrap: break-word;
        /* 长单词换行 */
        overflow: hidden;
        /* 隐藏溢出内容 */
    }
</style>
pages/mine/myCollect/myCollect.vue
@@ -1,6 +1,5 @@
<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}"
@@ -9,355 +8,389 @@
            </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;
@@ -368,18 +401,31 @@
        }
    }
    .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 {
@@ -390,7 +436,7 @@
            opacity: 0.9;
        }
        .video-duration {
        .duration {
            position: absolute;
            right: 8rpx;
            bottom: 8rpx;
@@ -402,14 +448,14 @@
        }
    }
    .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;
@@ -419,22 +465,21 @@
            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;
@@ -458,6 +503,7 @@
        image {
            width: 300rpx;
            height: 300rpx;
            margin-bottom: 30rpx;
            opacity: 0.6;
        }
@@ -469,138 +515,7 @@
        }
    }
    .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>
pages/video/home-page.vue
@@ -74,6 +74,7 @@
                  v-for="(item, index) in videoList"
                  :key="item.id"
                >
                  <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">
@@ -103,7 +104,16 @@
                  :key="item.id"
                  @click="playCollectVideo(index)"
                >
                  <image class="video-cover" :src="item.videoContentType === 'video' ? item.coverUrl : item.imgs[0]" mode="aspectFill"></image>
                <image v-if="tem.videoContentType === 'img'" class="video-cover" :src="item.imgs[0]" mode="aspectFill"></image>
                    <video v-else class="video-cover"
                    :src="item.videoUrl"
                    initial-time='0.01'
                    muted
                    :controls="false"
                    :show-center-play-btn="false"
                    object-fit="cover"></video>
                  <!-- <image class="video-cover" :src="getCoverUrl(item)"></image> -->
                  <view class="video-info">
                    <view class="video-stats">
                      <view class="stat">
@@ -123,7 +133,13 @@
                  :key="item.id"
                  @click="playLikeVideo(index)"
                >
                  <image class="video-cover" :src="item.videoContentType === 'video' ? item.coverUrl : item.imgs[0]" mode="aspectFill"></image>
                  <video class="video-cover"
                  :src="item.videoContentType === 'video' ? item.videoUrl : item.imgs[0]" mode="aspectFill"
                  initial-time='0.01'
                  muted
                  :controls="false"
                  :show-center-play-btn="false"
                  object-fit="cover"></video>
                  <view class="video-info">
                    <view class="video-stats">
                      <view class="stat">
@@ -246,6 +262,13 @@
    this.getAuthorVideoPage();
  },
  methods: {
       getCoverUrl(item) {
            if (item.videoContentType === 'video') {
              // OSS视频封面参数(完整格式)
              return `${item.videoUrl}?x-oss-process=video/snapshot,t_1000,f_jpg,m_fast`
            }
            return item.imgs?.[0]
          },
    dialogClose() {
        this.opVideo = {
            id: '',