jwyu 2 年之前
父节点
当前提交
ad10e48c96
共有 6 个文件被更改,包括 576 次插入1 次删除
  1. 8 1
      src/api/common.js
  2. 31 0
      src/api/roadShow.js
  3. 二进制
      src/assets/leftNav/roadShowVideo-s.png
  4. 7 0
      src/layout/component/Aside.vue
  5. 21 0
      src/router/index.js
  6. 509 0
      src/views/roadShow/video/List.vue

+ 8 - 1
src/api/common.js

@@ -158,6 +158,13 @@ export const apiFICCPermissionList=()=>{
 /**
  * 获取标签树
  */
- export const apiGetTagTree = params=>{
+export const apiGetTagTree = params=>{
     return get('/public/get_variety_tag_tree',params)
+}
+
+/**
+ * 获取用户已绑定权限
+ */
+export const apiUserBindPermission=()=>{
+    return get('/company/permission/bind',{})
 }

+ 31 - 0
src/api/roadShow.js

@@ -0,0 +1,31 @@
+/**
+ * 线上路演模块
+ */
+import {get,post} from './http'
+
+/**
+ * 视频列表
+ * @param page_index
+ * @param page_size
+ * @param keywords
+ * @param video_id
+ * @param chart_permission_id
+ */
+export const apiRoadShowVideoList=params=>{
+    return get('/road/video/list',params)
+}
+
+/**
+ * 视频播放埋点
+ * @param video_id
+ * @param source_agent 来源平台:1:小程序、2:小程序(pc)、3:公众号、4:官网web(pc)
+ */
+export const apiVideoPlayLog=params=>{
+    let source_agent=2
+	if(window.__wxjs_environment === 'miniprogram'){
+		source_agent=2
+	}else{
+		source_agent=4
+	}
+    return post('/community/video/play_log',{...params,source_agent:source_agent})
+}

二进制
src/assets/leftNav/roadShowVideo-s.png


+ 7 - 0
src/layout/component/Aside.vue

@@ -45,6 +45,13 @@ let menuList = reactive([
     icon_path: new URL('../../assets/leftNav/report-s.png', import.meta.url).href,
     children: null,
   },
+  {
+    MenuId: 8,
+    name: "线上路演",
+    path: "/roadshow/video/list",
+    icon_path: new URL('../../assets/leftNav/roadShowVideo-s.png', import.meta.url).href,
+    children: null,
+  },
   {
     MenuId: 2,
     name: "价格驱动",

+ 21 - 0
src/router/index.js

@@ -386,6 +386,27 @@ const routes=[
       }
     ]
   },
+  //路演视频模块
+  {
+    path:'/roadshow',
+    name:"RoadShow",
+    component: () => import("@/layout/Index.vue"),
+    meta:{
+      title:"线上路演"
+    },
+    children:[
+      {
+        path:"video/list",
+        name:"RoadShowVideoList",
+        component:()=>import('@/views/roadShow/video/List.vue'),
+        meta: {
+          title: "线上路演",
+          keepAlive:true,
+          isRoot:true
+        }
+      }
+    ]
+  },
 
   {
     path: '/:pathMatch(.*)',

+ 509 - 0
src/views/roadShow/video/List.vue

@@ -0,0 +1,509 @@
+<script setup>
+import {ref,reactive,onMounted,onActivated} from 'vue'
+import { useElementSize } from '@vueuse/core'
+import { ElMessage, ElMessageBox } from 'element-plus'
+
+import {apiFICCPermissionList,apiGetWechatQRCode,apiUserBindPermission} from '@/api/common'
+import {apiVideoList,apiVideoPlayLog} from '@/api/video'
+
+import SelfList from '@/components/SelfList.vue'
+import { useRoute, useRouter } from 'vue-router'
+import { useStore } from 'vuex'
+
+const route=useRoute()
+const router=useRouter()
+const store=useStore()
+
+//分享进入的videoid 
+let videoId=ref(0)
+
+//监听列表页面版心宽度
+const listPageEl=ref('')
+const {width}=useElementSize(listPageEl)
+
+// 获取品种权限数据
+let permissionState=reactive({
+    firstNavList:[],
+    // 一进来默认选择全部
+    sFirst:'',
+    secNavList:[],
+    sSecond:-1//选择的品种id 
+})
+
+const getTagTreeList = async ()=>{
+    const res = await apiUserBindPermission()
+    if(res.code===200){
+        const result = res.data.permission_list||[]
+        permissionState.firstNavList = result.map((item)=>{
+            let obj = {}
+            obj.ClassifyName = item.classify_name
+            obj.Items = item.list.map((i)=>{
+                return {PermissionId:i.chart_permission_id,PermissionName:i.chart_permission_name}
+            })
+            return obj
+        })
+        permissionState.firstNavList.unshift({
+            ClassifyName:"全部",
+            Items:[]
+        })
+        if(route.query.videoId){
+            videoId.value=route.query.videoId
+            getVideoList()
+        }else{
+            handelChangeFirstNav(permissionState.firstNavList[0])
+        }
+        
+    }
+}
+getTagTreeList()
+//点击一级分类
+const handelChangeFirstNav=(item)=>{
+    permissionState.sFirst=item.ClassifyName
+    permissionState.secNavList=item.Items
+    handleChangeSecNav(item.Items[0])
+}
+
+//点击二级分类
+const handleChangeSecNav=(item)=>{
+    if(!item){
+        // 没有二级分类 全部
+        permissionState.sSecond=-1
+    }else{
+        permissionState.sSecond=item.PermissionId
+    }
+    refreshList()
+}
+
+//获取视频列表数据
+let listState = reactive({
+    loading:false,
+    finished:false,
+    page:1,
+    list:[],
+})
+
+let noAuth=ref(null)//无权限数据
+
+const getVideoList=async ()=>{
+    listState.loading=true
+    const res=await apiVideoList({
+        page_index:Number(listState.page),
+        page_size:20,
+        video_id:videoId.value,
+        variety_tag_id:Number(permissionState.sSecond)
+    })
+    listState.loading=false
+    if(listState.page===1){
+        document.body.scrollTop=document.documentElement.scrollTop=0
+    }
+    if(res.code===200){
+        let arr=res.data||[]
+        listState.list=[...listState.list,...arr]
+        if(arr.length===0||arr.length<20){
+            listState.finished=true
+        }
+        noAuth.value=null
+    }else if(res.code===403){
+        noAuth.value=res.data
+        handleAutoApply()
+    }
+}
+// getVideoList()
+
+//无权限时申请
+const handleAutoApply=()=>{
+    if(noAuth.value.type=='contact'&&!noAuth.value.customer_info.has_apply){
+        if(noAuth.value.customer_info.status=='冻结'||(noAuth.value.customer_info.status=='试用'&&noAuth.value.customer_info.is_suspend==1)){
+            apiApplyPermission({
+                company_name:noAuth.value.customer_info.company_name,
+                real_name:noAuth.value.customer_info.name,
+                source:9,
+                from_page:'视频社区'
+            }).then(res=>{
+                if(res.code===200){
+                    console.log('主动申请成功');
+                }
+            }) 
+        }
+    }
+}
+const handleApply=()=>{
+    if(store.state.userInfo.is_bind===0){
+        ElMessageBox({
+            title:`温馨提示`,
+            message:'为了优化您的用户体验,<br>请登录后查看更多信息!',
+            dangerouslyUseHTMLString: true,
+            center: true,
+            confirmButtonText:'去登录',
+            confirmButtonClass:'self-elmessage-confirm-btn',
+            showCancelButton:true,
+            cancelButtonText:'取消',
+            cancelButtonClass:'self-elmessage-cancel-btn'
+        }).then(res=>{
+            wx.miniProgram.reLaunch({url:'/pages/login'})
+        }).catch(()=>{})
+        return
+    }
+    if(noAuth.value.customer_info.has_apply){
+        const htmlStr=`<p>您已提交过申请,请耐心等待</p>`
+        ElMessageBox({
+            title:`视频社区`,
+            message:htmlStr,
+            center: true,
+            dangerouslyUseHTMLString: true,
+            confirmButtonText:'知道了',
+            confirmButtonClass:'self-elmessage-confirm-btn'
+        })
+    }else{
+        if (!noAuth.value.customer_info.status || noAuth.value.customer_info.status != '流失') {
+            console.log('跳转申请页');
+            router.push({
+                path:'/apply/permission',
+                query:{
+                    source:9,
+                    fromPage:'视频社区'
+                }
+            })
+        }else{
+            apiApplyPermission({
+                company_name:noAuth.value.customer_info.company_name,
+                real_name:noAuth.value.customer_info.name,
+                source:9,
+                from_page:'视频社区'
+            }).then(res=>{
+                onsole.log('主动申请成功');
+                const htmlStr=`<p>申请已提交</p><p>请等待销售人员与您联系</p>`
+                ElMessageBox({
+                    title:`视频社区`,
+                    message:htmlStr,
+                    center: true,
+                    dangerouslyUseHTMLString: true,
+                    confirmButtonText:'知道了',
+                    confirmButtonClass:'self-elmessage-confirm-btn'
+                })
+            })
+        }
+    }
+}
+
+//刷新列表
+const refreshList=()=>{
+    listState.finished=false
+    listState.page=1
+    listState.list=[]
+    videoId.value=0
+    curVideoId.value=0
+    getVideoList()
+}
+
+// 加载下一页
+const onLoad=()=>{
+    listState.page++
+    getVideoList()
+}
+
+//当前正在播放哪个
+let curVideoId=ref(0)
+const handelClickPlay=(item)=>{
+    curVideoId.value=item.community_video_id
+    //记录播放
+    apiVideoPlayLog({video_id:Number(item.community_video_id)}).then(res=>{
+        if(res.code===200){
+            console.log('视频埋点成功');
+        }
+    })
+}
+
+
+//获取视频单个对应的小程序二维码
+const handelGetQRCodeImg=async (item)=>{
+    if(item.QRCodeImg) return
+    const res=await apiGetWechatQRCode({
+        CodeScene:JSON.stringify({videoId:item.community_video_id}),
+        CodePage:'pages/video/videoList'
+    })
+    if(res.code===200){
+        item.QRCodeImg=res.data
+    }
+}
+
+onMounted(() => {
+  //向小程序发送消息
+  let postData = {
+    path: "/pages/video/videoList",
+    params:{},
+    title: "FICC视频社区",
+    shareImg:''
+  };
+  wx.miniProgram.postMessage({ data: postData });
+});
+
+onActivated(()=>{
+    curVideoId.value=0
+    //向小程序发送消息
+    let postData = {
+        path: "/pages/video/videoList",
+        params:{},
+        title: "FICC视频社区",
+        shareImg:''
+    };
+    wx.miniProgram.postMessage({ data: postData });
+    if(noAuth.value){
+        //无权限时每次进页面都刷新列表
+        getVideoList()
+    }
+})
+
+</script>
+
+<template>
+    <div class="voice-no-auth" v-if="noAuth">
+        <img :src="$store.state.globalImgUrls.activityNoAuth" alt="">
+        <p style="font-size:16px;margin-bottom: 0;">您暂无权限查看视频社区</p>
+        <template v-if="noAuth.type=='contact'">
+            <p style="font-size:16px;margin-top: 5px;margin-bottom: 62px;">若想查看,可以联系对口销售--{{noAuth.name}}:<span style="color:#F3A52F">{{noAuth.mobile}}</span></p>
+        </template>
+        <template v-else>
+            <p style="font-size:16px;margin-top: 5px;margin-bottom: 62px;">若想参加可以申请开通</p>
+            <div class="global-main-btn btn" @click="handleApply" style="margin-bottom: 20px;">立即申请</div>
+        </template>
+    </div>
+    <div class="video-list-page" ref="listPageEl" v-else>
+        <div class="top-nav-box" :style="{width:width+'px'}">
+            <div class="first-nav-box">
+                <span 
+                    v-for="item in permissionState.firstNavList" 
+                    :key="item.ClassifyName"
+                    :class="item.ClassifyName==permissionState.sFirst?'active':''"
+                    @click="handelChangeFirstNav(item)"
+                >{{item.ClassifyName}}</span>
+            </div>
+            <div class="sec-nav-box" v-show="permissionState.secNavList.length>0">
+                <span
+                    :class="['sec-item',item.PermissionId==permissionState.sSecond?'active':'']"
+                    v-for="item in permissionState.secNavList.slice(0,6)"
+                    :key="item.PermissionId"
+                    @click="handleChangeSecNav(item)"
+                >{{item.PermissionName}}</span>
+                <el-popover
+                    :width="500"
+                    trigger="click"
+                >
+                    <template #reference>
+                        <img v-if="permissionState.secNavList.length>6" style="width:16px;transform: rotate(90deg);cursor: pointer" src="@/assets/icon-more.png" alt="">
+                    </template>
+                    <template #default>
+                        <div class="flex top-nav-filter-box">
+                            <div 
+                                :class="['item',item.PermissionId == permissionState.sSecond&&'active']" 
+                                v-for="item in permissionState.secNavList.slice(6)" 
+                                :key="item.PermissionId"
+                                @click="handleChangeSecNav(item)"
+                            >{{item.PermissionName}}</div>
+                        </div>
+                    </template>
+                </el-popover>
+            </div>
+        </div>
+        <SelfList 
+            :finished="listState.finished" 
+            :isEmpty="listState.list.length===0&&listState.finished"
+            :loading="listState.loading"
+            :count="listState.list.length"
+            @listOnload="onLoad"
+        >
+            <div class="flex list-wrap">
+                <div class="flex video-item" v-for="item in listState.list" :key="item.community_video_id">
+                    <el-popover
+                        :width="200"
+                        trigger="hover"
+                        @show="handelGetQRCodeImg(item)"
+                    >
+                        <template #reference>
+                            <div class="icon-wechat"></div>
+                        </template>
+                        <template #default>
+                            <img style="width:100%" :src="item.QRCodeImg" alt="">
+                        </template>
+                    </el-popover>
+                    <div class="title">{{item.title}}</div>
+                    <div>
+                    <video 
+                        :src="item.video_url" 
+                        controls
+                        :poster="item.cover_img_url"
+                        controlslist="nodownload"
+                        disablePictureInPicture
+                        autoplay
+                        v-if="item.community_video_id==curVideoId"
+                        @ended="curVideoId=0"
+                    ></video>
+                    <div v-else class="poster-img" :style="'background-image:url('+item.cover_img_url+')'" @click="handelClickPlay(item)"></div>
+                    <div class="time">发布时间:{{item.publish_time}}</div>
+                    </div>
+                </div>
+                <div class="last-add-item"></div>
+                <div class="last-add-item"></div>
+            </div>
+        </SelfList>
+
+        <!-- 跳转去提问 -->
+        <div class="to-question-box-fixed" @click="$router.push({path:'/question/list',query:{isAutoQuestion:true}})">
+            <img src="@/assets/toquestion-icon.png" alt="">
+            <span>我要提问</span>
+        </div>
+    </div>
+</template>
+
+<style lang="scss" scoped>
+.icon-wechat{
+    cursor: pointer;
+    width: 24px;
+    height: 24px;
+    background-image: url('@/assets/icon-wechat.png');
+    background-size: cover;
+    position: absolute;
+    top: 30px;
+    right: 30px;
+    &:hover{
+        background-image: url('@/assets/icon-wechat2.png');
+    }
+}
+.top-nav-filter-box{
+    flex-wrap: wrap;
+    .item{
+        margin: 5px 10px;
+        width: 113px;
+        height: 40px;
+        display: flex;
+        justify-content: center;
+        align-items: center;
+        background-color: #f6f6f6;
+        border-radius: 4px;
+        font-size: 16px;
+        cursor: pointer;
+        :hover{
+            color: #fff;
+            background-color: #F3A52F;
+        }
+    }
+    .active{
+        color: #fff;
+        background-color: #F3A52F;
+    }
+}
+.video-list-page{
+    .top-nav-box{
+        padding: 30px 30px 12px 30px;
+        background: #FFFFFF;
+        box-shadow: 0px 4px 8px 1px rgba(0, 0, 0, 0.04);
+        position: sticky;
+        top: 60px;
+        width: 100%;
+        max-width: 1240px;
+        z-index: 10;
+        .first-nav-box{
+            span{
+                display: inline-block;
+                width: 140px;
+                line-height: 40px;
+                text-align: center;
+                border-radius: 20px;
+                background-color: #F6F6F6;
+                font-size: 16px;
+                margin-right: 30px;
+                margin-bottom:10px;
+                cursor: pointer;
+            }
+            .active{
+                background-color: #FFFBF5;
+                box-shadow: 0px 6px 7px 1px #FFF7EB;
+                color: #F3A52F;
+                border: 1px solid #F3A52F;
+            }
+        }
+        .sec-nav-box{
+            margin-top: 30px;
+            .sec-item{
+                color: #666;
+                margin-right: 30px;
+                cursor: pointer;
+                display: inline-block;
+            }
+            .active{
+                color: #F3A52F;
+            }
+        }
+    }
+
+    .list-wrap{
+        padding-top: 30px;
+        // border-left: 1px solid #E2E2E2;
+        // border-right: 1px solid #E2E2E2;
+        justify-content: center;
+        flex-wrap: wrap;
+        .video-item{
+            flex-direction: column;
+            justify-content: space-between;
+            width: 400px;
+            padding: 25px;
+            border: 1px solid #E2E2E2;
+            position: relative;
+            // &:nth-of-type(odd){
+            //     border-right: 1px solid #E2E2E2;
+            // }
+            .title{
+                font-size: 16px;
+                color: #666;
+                padding-right: 26px;
+            }
+            video{
+                width: 100%;
+                height: 200px;
+                object-fit: contain;
+                margin: 19px 0;
+            }
+            .poster-img{
+                width: 100%;
+                height: 200px;
+                margin: 19px 0;
+                position: relative;
+                background-size: cover;
+                background-position: center;
+                cursor: pointer;
+                &::after{
+                    content:'';
+                    display: block;
+                    position: absolute;
+                    width: 80px;
+                    height: 80px;
+                    top: 50%;
+                    left: 50%;
+                    transform: translate(-50%,-50%);
+                    background-image: url('@/assets/video-play-btn.png');
+                    background-size: cover;
+                }
+            }
+            .time{
+                color: #999;
+                font-size: 14px;
+            }
+        }
+        .last-add-item{
+            width: 400px;
+            height: 0;
+        }
+    }
+}
+.voice-no-auth{
+    text-align: center;
+    img{
+        width: 400px;
+    }
+    .btn{
+        width: 218px;
+        margin-left: auto;
+        margin-right: auto;
+    }
+}
+</style>