jwyu 2 tahun lalu
induk
melakukan
2752a8a8e2

+ 36 - 0
src/api/user.js

@@ -44,4 +44,40 @@ export const apiLastApplyRecord=(params)=>{
  */
 export const apiSetUserInfo=params=>{
 	return post('/user/set',params)
+}
+
+/**
+ * 收藏
+ * @param collection_type 收藏类型:1-研报; 2-视频社区; 3-微路演视频
+ * @param primary_id //收藏类型主ID(如报告id,视频id)
+ * @param extend_id //扩展ID-如研报章节ID
+ * @param source_agent //操作来源:1-小程序 2-小程序 PC 3-弘则研究公众号 4-Web PC
+ */
+export const apiSetCollect=params=>{
+	let source_agent=2
+	if(window.__wxjs_environment === 'miniprogram'){
+		source_agent=2
+	}else{
+		source_agent=4
+	}
+	return post('/collection/collect',{source_agent:source_agent,...params})
+}
+
+/**
+ * 取消收藏
+ * @param collection_id 收藏ID
+ */
+export const apiCancelCollect=params=>{
+	return post('/collection/cancel',params)
+}
+
+/**
+ * 我的收藏列表
+ * @param curr_page
+ * @param page_size
+ * @param keywords
+ * @param from_type 来源类型:0-全部; 1-研报; 2-线上路演; 3-视频社区
+ */
+export const apiMyCollectList=params=>{
+	return get('/collection/list',params)
 }

TEMPAT SAMPAH
src/assets/collect-s.png


TEMPAT SAMPAH
src/assets/collect.png


TEMPAT SAMPAH
src/assets/collect2-s.png


TEMPAT SAMPAH
src/assets/collect2.png


TEMPAT SAMPAH
src/assets/icon-start.png


+ 51 - 0
src/components/CollectBox.vue

@@ -0,0 +1,51 @@
+<script setup>
+import {apiSetCollect,apiCancelCollect} from '@/api/user'
+import { ElMessage } from 'element-plus'
+const emit=defineEmits(['change'])
+const props=defineProps({
+    type:{//收藏类型:1-研报; 2-视频社区; 3-微路演视频
+        type:Number,
+        default:0
+    },
+    primaryId:{// 藏类型主ID(如报告id,视频id)
+        default:0
+    },
+    extendId:{//扩展ID-如研报章节ID
+        default:0
+    },
+    collectId:{//收藏的id 大于0说明收藏了
+        default:0,
+    }
+})
+
+
+const handleCollect=()=>{
+    if(props.collectId>0){
+        apiCancelCollect({
+            collection_id:Number(props.collectId)
+        }).then(res=>{
+            if(res.code===200){
+                ElMessage.success('取消收藏!')
+                emit('change',0)
+            }
+        })
+    }else{
+        apiSetCollect({
+            collection_type:props.type,
+            primary_id:Number(props.primaryId),
+            extend_id:Number(props.extendId)
+        }).then(res=>{
+            if(res.code===200){
+                ElMessage.success('收藏成功!')
+                emit('change',res.data)
+            }
+        })  
+    }
+}
+</script>
+
+<template>
+    <div class="collect-box" @click.stop="handleCollect">
+        <slot></slot>
+    </div>
+</template>

+ 315 - 0
src/components/MyCollect.vue

@@ -0,0 +1,315 @@
+<script setup>
+import {onMounted,reactive} from 'vue'
+import {apiMyCollectList,apiCancelCollect} from '@/api/user'
+import { useRouter } from 'vue-router'
+import { ElMessage,ElMessageBox } from 'element-plus'
+import Search from '@/components/Search.vue'
+import moment from 'moment'
+
+const router=useRouter()
+
+
+const listState=reactive({
+    type:0,// 0-全部; 1-研报; 2-线上路演; 3-视频社区
+    list:[],
+    page:1,
+    pageSize:20,
+    loading:false,
+    finished:false,
+    keywords:''
+})
+const getCollectList=async ()=>{
+    listState.loading=true
+    const res=await apiMyCollectList({
+        from_type:Number(listState.type),
+        page_size:listState.pageSize,
+        curr_page:listState.page,
+        keywords:listState.keywords
+    })
+    listState.loading=false
+    if(res.code===200){
+        let arr=res.data.list||[]
+        listState.list=[...listState.list,...arr]
+        if(res.data.paging.is_end){
+            listState.finished=true
+        }
+    }
+}
+//加载更多
+const onLoad=()=>{
+    if(listState.loading) return
+    listState.page++
+    getCollectList()
+}
+
+// 类型切换
+const handleTypeChange=(type)=>{
+    listState.type=type 
+    listState.list=[]
+    listState.page=1
+    listState.keywords=''
+    listState.finished=false
+    getCollectList()
+}
+
+//搜索
+const handleSearch=(e)=>{
+    listState.type=0
+    listState.list=[]
+    listState.page=1
+    listState.keywords=e||''
+    listState.finished=false
+    getCollectList()
+}
+
+const getTime=(e)=>{
+    if(moment().isSame(e,'year')){//当年
+        return moment(e).format('MM-DD')
+    }else{
+        return moment(e).format('YYYY-MM-DD')
+    }
+}
+
+//跳转详情
+const goDetail=(item)=>{
+    if(item.CollectionType==1){// 报告
+        if(item.ExtendId>0){
+            router.push({
+                path:'/report/chapterdetail',
+                query:{
+                    chapterId:item.ExtendId
+                }
+            })
+        }else{
+            router.push({
+                path:'/report/detail',
+                query:{
+                    reportId:item.PrimaryId
+                }
+            })
+        }
+    }else if(item.CollectionType==2){//视频社区
+        router.push({
+            path:'/video/list',
+            query:{
+                videoId:item.PrimaryId
+            }
+        })
+    }else if(item.CollectionType==3){//路演视频
+        router.push({
+            path:'/roadshow/video/list',
+            query:{
+                videoId:item.PrimaryId
+            }
+        })
+    }
+}
+
+//取消收藏
+const handleCancelCollect=(item,index)=>{
+    const htmlStr=`<p>确认取消收藏?</p>`
+    ElMessageBox({
+        title:`操作提醒`,
+        message:htmlStr,
+        center: true,
+        dangerouslyUseHTMLString: true,
+        confirmButtonText:'确定',
+        confirmButtonClass:'self-elmessage-confirm-btn',
+        showCancelButton:true,
+        cancelButtonText:'取消',
+        cancelButtonClass:'self-elmessage-cancel-btn'
+    }).then(()=>{
+        apiCancelCollect({collection_id:Number(item.CollectionId)}).then(res=>{
+            if(res.code===200){
+                ElMessage.success('操作成功')
+                listState.list.splice(index,1)//删除数组中该数据
+            }
+        })
+    }).catch(()=>{
+        console.log('取消操作');
+    })
+}
+
+onMounted(() => {
+    getCollectList()
+})
+</script>
+
+<template>
+    <div class="my-collect-wrap">
+        <Search
+            placeholder="请输入标题/关键词"
+            @search="handleSearch"
+            @clean="handleSearch"
+        ></Search>
+        <div class="top-nav">
+            <span :class="listState.type==0&&'active'" @click="handleTypeChange(0)">全部</span>
+            <span :class="listState.type==1&&'active'" @click="handleTypeChange(1)">研报</span>
+            <span :class="listState.type==2&&'active'" @click="handleTypeChange(2)">线上路演</span>
+            <span :class="listState.type==3&&'active'" @click="handleTypeChange(3)">视频社区</span>
+        </div>
+        <div class="empty-box" v-if="listState.finished&&listState.list.length==0">
+            <img :src="$store.state.globalImgUrls.chartEmpty" alt="">
+            <p>暂无数据~</p>
+        </div>
+        <ul class="collect-list" v-else>
+            <li class="item" v-for="(item,index) in listState.list" :key="item.CollectionId">
+                <span class="c-item">{{getTime(item.CreateTime)}}</span>
+                <!-- 视频类别样式 -->
+                <div class="flex item-con video-box" v-if="[2,3].includes(item.CollectionType)" @click="goDetail(item)">
+                    <img class="img" :src="item.ImgUrl"/>
+                    <div class="con">
+                        <div class="multi-ellipsis-l2 title">{{item.Title}}</div>
+                        <div class="author">{{item.Author}}</div>
+                        <div class="time">发布时间:{{item.PublishTime}}</div>
+                    </div>
+                    <!-- 取消收藏 -->
+                    <div class="cancel-collect-btn" @click.stop="handleCancelCollect(item,index)">取消收藏</div>
+                </div>
+                <!-- 报告类型样式 -->
+                <div class="item-con report-box" v-if="item.CollectionType==1" @click="goDetail(item)">
+                    <div class="multi-ellipsis-l2 title">{{item.Title}}</div>
+                    <div class="con">
+                        <span v-if="item.ClassifyName">#{{item.ClassifyName}}</span>
+                        <span v-if="item.ClassifySecondName" style="margin-left:20px">#{{item.ClassifySecondName}}</span>
+                        <div class="time">发布时间:{{item.PublishTime}}</div>
+                    </div>
+                    <!-- 取消收藏 -->
+                    <div class="cancel-collect-btn" @click.stop="handleCancelCollect(item,index)">取消收藏</div>
+                </div>
+            </li>
+        </ul>
+
+    </div>
+</template>
+
+<style lang="scss" scoped>
+.my-collect-wrap{
+    :deep(.search-wrap){
+        width: 100%;
+    }
+    .top-nav{
+        margin-bottom: 20px;
+        margin-top: 20px;
+        span{
+            font-size: 18px;
+            display: inline-block;
+            margin-right: 50px;
+            cursor: pointer;
+            padding-bottom: 5px;
+            position: relative;
+        }
+        .active{
+            color: #F3A52F;
+            &::after{
+                content: '';
+                display: block;
+                width: 49px;
+                height: 2px;
+                background: #F3A52F;
+                border-radius: 6px 6px 6px 6px;
+                position: absolute;
+                bottom: 0px;
+                left: 50%;
+                transform: translateX(-50%);
+            }
+        }
+    }
+    .collect-list{
+        height: 500px;
+        overflow-y: auto;
+        &::-webkit-scrollbar{
+            display: none;
+        }
+        .item{
+            padding: 20px 0 10px 0;
+            border-bottom: 1px solid #F6F6F6;
+            .c-item{
+                display: inline-block;
+                background-color: #F6F6F6;
+                color: #666;
+                padding: 5px 10px;
+                border-radius: 4px;
+            }
+            .video-box{
+                margin-top: 22px;
+                .img{
+                    width: 113px;
+                    height: 98px;
+                    object-fit: cover;
+                    flex-shrink: 0;
+                    margin-right: 10px;
+                    border-radius: 4px;
+                }
+                .con{
+                    flex: 1;
+                    color: #666;
+                    .title{
+                        color: #000;
+                        font-size: 16px;
+                        min-height: 45px;
+                    }
+                    .author{
+                        min-height: 20px;
+                        margin: 5px 0;
+                    }
+                }
+            }
+            .report-box{
+                margin-top: 12px;
+                .title{
+                    color: #000;
+                    font-size: 16px;
+                    margin-bottom: 12px;
+                }
+                .con{
+                    span{
+                        display: inline-block;
+                        color: #666;
+
+                    }
+                    .time{
+                        float: right;
+                    }
+                }
+            }
+
+            .item-con{
+                padding: 7px 10px;
+                position: relative;
+                .cancel-collect-btn{
+                    position: absolute;
+                    right: 10px;
+                    top: 50%;
+                    transform: translateY(-50%);
+                    width: 89px;
+                    height: 31px;
+                    background: #FFFFFF;
+                    border-radius: 4px 4px 4px 4px;
+                    border: 1px solid #E5E5E5;
+                    text-align: center;
+                    line-height: 28px;
+                    color: #F3A52F;
+                    cursor: pointer;
+                    display: none;
+                }
+                &:hover{
+                    background: #FFFBF5;
+                    .cancel-collect-btn{
+                        display: block;
+                    }
+                }
+            }
+
+        }
+
+    }
+    .empty-box{
+        text-align: center;
+        color: #999;
+        img{
+            width: 50%;
+        }
+    }
+}
+</style>

+ 1 - 0
src/components/SharePoster.vue

@@ -94,6 +94,7 @@ onLongPress(imgDom, onLongPressImg)
         z-index: 1000;
         width: 50px;
         height: 50px;
+        display: block;
     }
     .chart-icon{
         float: right;

+ 10 - 0
src/layout/component/Header.vue

@@ -2,6 +2,7 @@
 import { useStore } from "vuex";
 import { computed, ref, watch } from "vue";
 import Notice from '@/components/Notice.vue'
+import MyCollect from '@/components/MyCollect.vue'
 import moment from "moment";
 import { apiGetPermissionList } from "@/api/common.js";
 import { ElMessageBox, ElMessage } from "element-plus";
@@ -186,6 +187,15 @@ const handleSetUserInfo=()=>{
       <span>弘则研报</span>
     </div>
     <div class="flex-col-center userinfo-wrap">
+      <!-- 我的收藏 -->
+      <el-popover trigger="click" :width="460" popper-style="box-shadow: rgb(14 18 22 / 35%) 0px 10px 38px -10px, rgb(14 18 22 / 20%) 0px 10px 20px -15px; padding: 20px;">
+        <template #reference>
+          <img v-if="userInfo" style="width:26px;height:25px;margin-right:21px;position: relative;top:-2px" src="@/assets/icon-start.png" alt="">
+        </template>
+        <template #default>
+          <MyCollect/>
+        </template>
+      </el-popover>
       <!-- 消息 -->
       <el-popover trigger="click" :width="439" popper-style="box-shadow: rgb(14 18 22 / 35%) 0px 10px 38px -10px, rgb(14 18 22 / 20%) 0px 10px 20px -15px; padding: 20px;">
         <template #reference>

+ 53 - 14
src/views/report/ChapterDetail.vue

@@ -18,6 +18,9 @@ import Comment from '@/components/Comment.vue'
 import preLoadImg from '@/utils/preLoadImg.js'
 import { useRoute,onBeforeRouteUpdate,useRouter } from 'vue-router';
 import { useStore } from 'vuex'
+import CollectBox from '@/components/CollectBox.vue'
+import collectIcon from '@/assets/collect2.png'
+import collectSIcon from '@/assets/collect2-s.png'
 import {useWaterMark} from '@/hooks/waterMark.js'
 
 const route=useRoute()
@@ -30,7 +33,6 @@ let chapterId=ref(route.query.chapterId||'') //章节id
 let frompage=ref(route.query.frompage||'')//如果来自报告详情页 则展示底部章节列表
 
 //获取报告对应的ppt图片
-const pptIcon=new URL('../../assets/ppt-icon.png', import.meta.url).href
 let pptImgs=ref([])
 let showPreViewPPT=ref(false)
 let preViewPPTIndex=ref(0)
@@ -389,13 +391,13 @@ const posterParams=computed(()=>{
                                 <span style="color:#F3A52F;margin-left:20px;cursor: pointer;" @click="showDisclaimers=true">免责声明</span>
                             </div>
                         </div>
-                        <el-image
+                        <!-- <el-image
                             style="width: 54px; height: 54px;position: fixed;right:33px;bottom:200px;z-index: 99;cursor: pointer;"
                             :src="pptIcon"
                             fit="cover"
                             v-if="pptImgs.length>0"
                             @click="showPreViewPPT=true"
-                        />
+                        /> -->
                     </div>
                     <AudioBox :data="audioData" v-if="info.report_chapter_item.video_url&&info.report_chapter_item.video_play_seconds>0"></AudioBox>
                     <!-- <div class="abstract" v-if="info.report_chapter_item.abstract">摘要:{{info.report_chapter_item.abstract}}</div> -->
@@ -457,6 +459,34 @@ const posterParams=computed(()=>{
                     }"
                 />
 
+                <!-- 右侧悬浮操作栏 -->
+                <div class="right-fix-opt-box">
+                    <!-- 收藏 -->
+                    <CollectBox
+                        :type="1"
+                        :primaryId="info.report_chapter_item.report_id"
+                        :collectId="info.collection_id"
+                        :extendId="info.report_chapter_item.report_chapter_id"
+                        @change="e=>info.collection_id=e"
+                        v-if="info&&info.auth_ok"
+                    >
+                        <img class="collect-icon" :src="info.collection_id>0?collectSIcon:collectIcon" alt="">
+                    </CollectBox>
+                    <!-- ppt -->
+                    <img class="ppt-icon" src="@/assets/ppt-icon.png" v-if="pptImgs.length>0" @click="showPreViewPPT=true" alt="">
+                    <!-- 生成海报 -->
+                    <SharePoster  
+                        :shareData="{
+                            type:'report_detail',
+                            code_page:'pages-report/chapterDetail',
+                            code_scene:code_scene,
+                            data:posterParams
+                        }"
+                        :style="{position:'static'}"
+                        v-if="info&&info.auth_ok"
+                    >
+                    </SharePoster>
+                </div>
             </div>
             <div class="right-aside-box" v-if="info.auth_ok&&frompage=='reportdetail'">
                 <div class="fix-top">
@@ -522,17 +552,6 @@ const posterParams=computed(()=>{
             <div style="margin-bottom:10px">4、在任何情况下,本公司不对客户/接受人/接受机构因使用报告中内容所引致的一切损失负责任,客户/接受人/接受机构需自行承担全部风险。</div>
         </div>
     </el-dialog>
-
-    <!-- 生成海报 -->
-    <SharePoster  
-        :shareData="{
-            type:'report_detail',
-            code_page:'pages-report/chapterDetail',
-            code_scene:code_scene,
-            data:posterParams
-        }"
-        v-if="info&&info.auth_ok"
-    ></SharePoster>
 </template>
 
 <style lang="scss" scoped>
@@ -624,6 +643,26 @@ const posterParams=computed(()=>{
             }
         }
     }
+    .right-fix-opt-box{
+            position: fixed;
+            right: 33px;
+            bottom: 150px;
+            z-index: 1000;
+            .ppt-icon{
+                width: 54px;
+                height: 54px;
+                object-fit: cover;
+                display: block;
+                margin: 0 auto;
+            }
+            .collect-icon{
+                width: 57px;
+                height: 57px;
+                object-fit: cover;
+                display: block;
+                margin: 0 auto;
+            }
+    }
     .no-auth-wrap{
         text-align: center;
         color: #F3A52F;

+ 50 - 18
src/views/report/Detail.vue

@@ -13,6 +13,9 @@ import preLoadImg from '@/utils/preLoadImg.js'
 import { useRoute , onBeforeRouteUpdate,useRouter} from 'vue-router';
 import { useStore } from 'vuex';
 import {useWaterMark} from '@/hooks/waterMark.js'
+import CollectBox from '@/components/CollectBox.vue'
+import collectIcon from '@/assets/collect2.png'
+import collectSIcon from '@/assets/collect2-s.png'
 moment.locale('zh-cn')
 
 const route=useRoute()
@@ -24,7 +27,6 @@ const waterMarkEl=ref('')//水印盒子
 let reportId=ref(route.query.reportId||'')
 
 //获取报告对应的ppt图片
-const pptIcon=new URL('../../assets/ppt-icon.png', import.meta.url).href
 let pptImgs=ref([])
 let showPreViewPPT=ref(false)
 let preViewPPTIndex=ref(0)
@@ -434,13 +436,6 @@ const formatTitle=(e)=>{
                                 <span style="color:#F3A52F;margin-left:20px;cursor: pointer;" @click="showDisclaimers=true">免责声明</span>
                             </div>
                         </div>
-                        <el-image
-                            style="width: 54px; height: 54px;position: fixed;right:33px;bottom:200px;z-index: 99;cursor: pointer;"
-                            :src="pptIcon"
-                            fit="cover"
-                            v-if="pptImgs.length>0"
-                            @click="showPreViewPPT=true"
-                        />
                     </div>
                     <!-- 音频模块 -->
                     <AudioBox :data="audioData" v-if="info.report_info.video_url&&info.report_info.video_play_seconds>0"></AudioBox>
@@ -476,16 +471,33 @@ const formatTitle=(e)=>{
                         </div>
                     </div>
 
-                    <!-- 生成海报 -->
-                    <SharePoster  
-                        :shareData="{
-                            type:'report_detail',
-                            code_page:'pages-report/reportDetail',
-                            code_scene:code_scene,
-                            data:posterParams
-                        }"
-                        v-if="info&&info.auth_ok"
-                    ></SharePoster>
+                    <!-- 右侧悬浮操作栏 -->
+                    <div class="right-fix-opt-box">
+                        <!-- 收藏 -->
+                        <CollectBox
+                            :type="1"
+                            :primaryId="info.report_info.report_id"
+                            :collectId="info.collection_id"
+                            @change="e=>info.collection_id=e"
+                            v-if="info&&info.auth_ok"
+                        >
+                            <img class="collect-icon" :src="info.collection_id>0?collectSIcon:collectIcon" alt="">
+                        </CollectBox>
+                        <!-- ppt -->
+                        <img class="ppt-icon" src="@/assets/ppt-icon.png" v-if="pptImgs.length>0" @click="showPreViewPPT=true" alt="">
+                        <!-- 生成海报 -->
+                        <SharePoster  
+                            :shareData="{
+                                type:'report_detail',
+                                code_page:'pages-report/reportDetail',
+                                code_scene:code_scene,
+                                data:posterParams
+                            }"
+                            :style="{position:'static'}"
+                            v-if="info&&info.auth_ok"
+                        >
+                        </SharePoster>
+                    </div>
                 </div>
             </div>
             <div class="right-aside-box" v-if="info.auth_ok&&!(['晨报','周报'].includes(info.report_info.classify_name_first))">
@@ -619,6 +631,26 @@ const formatTitle=(e)=>{
                 width: 100% !important;
             }
         }
+        .right-fix-opt-box{
+            position: fixed;
+            right: 33px;
+            bottom: 150px;
+            z-index: 1000;
+            .ppt-icon{
+                width: 54px;
+                height: 54px;
+                object-fit: cover;
+                display: block;
+                margin: 0 auto;
+            }
+            .collect-icon{
+                width: 57px;
+                height: 57px;
+                object-fit: cover;
+                display: block;
+                margin: 0 auto;
+            }
+        }
     }
     .no-auth-wrap{
         text-align: center;

+ 22 - 2
src/views/roadShow/video/List.vue

@@ -11,6 +11,10 @@ import SelfList from '@/components/SelfList.vue'
 import { useRoute, useRouter } from 'vue-router'
 import { useStore } from 'vuex'
 
+import CollectBox from '@/components/CollectBox.vue'
+import collectIcon from '@/assets/collect.png'
+import collectSIcon from '@/assets/collect-s.png'
+
 const route=useRoute()
 const router=useRouter()
 const store=useStore()
@@ -333,6 +337,14 @@ onActivated(()=>{
                             <img style="width:100%" :src="item.QRCodeImg" alt="">
                         </template>
                     </el-popover>
+                    <CollectBox
+                        :type="3"
+                        :primaryId="item.road_video_id"
+                        :collectId="item.collection_id"
+                        @change="e=>item.collection_id=e"
+                    >
+                        <img class="collect-icon" :src="item.collection_id>0?collectSIcon:collectIcon" alt="">
+                    </CollectBox>
                     <div class="title">{{item.title}}</div>
                     <div>
                     <video 
@@ -371,7 +383,7 @@ onActivated(()=>{
     background-image: url('@/assets/icon-wechat.png');
     background-size: cover;
     position: absolute;
-    top: 30px;
+    top: 26px;
     right: 30px;
     &:hover{
         background-image: url('@/assets/icon-wechat2.png');
@@ -463,7 +475,7 @@ onActivated(()=>{
             .title{
                 font-size: 16px;
                 color: #666;
-                padding-right: 26px;
+                padding-right: 75px;
             }
             video{
                 width: 100%;
@@ -502,6 +514,14 @@ onActivated(()=>{
                 color: #999;
                 font-size: 14px;
             }
+            .collect-icon{
+                position: absolute;
+                top: 26px;
+                right: 70px;
+                width: 24px;
+                height: 24px;
+                cursor: pointer;
+            }
         }
         .last-add-item{
             width: 400px;

+ 22 - 2
src/views/video/List.vue

@@ -11,6 +11,10 @@ import Comment from './components/Comment.vue'
 import { useRoute, useRouter } from 'vue-router'
 import { useStore } from 'vuex'
 
+import CollectBox from '@/components/CollectBox.vue'
+import collectIcon from '@/assets/collect.png'
+import collectSIcon from '@/assets/collect-s.png'
+
 const route=useRoute()
 const router=useRouter()
 const store=useStore()
@@ -320,6 +324,14 @@ onActivated(()=>{
         >
             <div class="flex list-wrap">
                 <div class="video-item" v-for="item in listState.list" :key="item.community_video_id">
+                    <CollectBox
+                        :type="2"
+                        :primaryId="item.community_video_id"
+                        :collectId="item.collection_id"
+                        @change="e=>item.collection_id=e"
+                    >
+                        <img class="collect-icon" :src="item.collection_id>0?collectSIcon:collectIcon" alt="">
+                    </CollectBox>
                     <el-popover
                         :width="200"
                         trigger="hover"
@@ -375,7 +387,7 @@ onActivated(()=>{
     background-image: url('@/assets/icon-wechat.png');
     background-size: cover;
     position: absolute;
-    top: 30px;
+    top: 26px;
     right: 30px;
     &:hover{
         background-image: url('@/assets/icon-wechat2.png');
@@ -467,7 +479,7 @@ onActivated(()=>{
             .title{
                 font-size: 16px;
                 color: #666;
-                padding-right: 26px;
+                padding-right: 70px;
             }
             video{
                 width: 100%;
@@ -503,6 +515,14 @@ onActivated(()=>{
                 font-size: 14px;
                 margin-top: 10px;
             }
+            .collect-icon{
+                position: absolute;
+                top: 26px;
+                right: 70px;
+                width: 24px;
+                height: 24px;
+                cursor: pointer;
+            }
         }
         .last-add-item{
             width: 400px;