|
@@ -0,0 +1,300 @@
|
|
|
+<script setup>
|
|
|
+import {ref,reactive, onMounted, watch} from 'vue'
|
|
|
+import {apiReportClassifyList} from '@/api/report'
|
|
|
+import {apiRoadShowVideoList} from '@/api/roadShow'
|
|
|
+import { useRouter } from 'vue-router'
|
|
|
+
|
|
|
+const props=defineProps({
|
|
|
+ defaultClassifyId:{
|
|
|
+ type:Number,
|
|
|
+ default:0
|
|
|
+ }
|
|
|
+})
|
|
|
+
|
|
|
+const router=useRouter()
|
|
|
+
|
|
|
+watch(
|
|
|
+ ()=>props.defaultClassifyId,
|
|
|
+ (n)=>{
|
|
|
+ if(n&&navList.value.length){
|
|
|
+ navList.value.forEach(item=>{
|
|
|
+ if(item.id==props.defaultClassifyId){
|
|
|
+ handleChangeFirstClassify(item)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+)
|
|
|
+
|
|
|
+let navList=ref([])
|
|
|
+async function getReportClassify(){
|
|
|
+ const res=await apiReportClassifyList({classify_type:1})
|
|
|
+ if(res.code===200){
|
|
|
+ const arr=res.data.list||[]
|
|
|
+ navList.value=[
|
|
|
+ {
|
|
|
+ id: 0,
|
|
|
+ classify_name: "ALL",
|
|
|
+ child: []
|
|
|
+ },
|
|
|
+ ...arr,
|
|
|
+ ]
|
|
|
+ if(props.defaultClassifyId){
|
|
|
+ navList.value.forEach(item=>{
|
|
|
+ if(item.id==props.defaultClassifyId){
|
|
|
+ handleChangeFirstClassify(item)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }else{
|
|
|
+ initList()
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+getReportClassify()
|
|
|
+
|
|
|
+let listState=reactive({
|
|
|
+ firstClassifyId:0,
|
|
|
+ secClassifyId:0,
|
|
|
+ secClassifyOpt:[],
|
|
|
+
|
|
|
+ page:1,
|
|
|
+ pageSize:20,
|
|
|
+ list:[],
|
|
|
+ loading:false,
|
|
|
+ finished:false
|
|
|
+})
|
|
|
+
|
|
|
+function handleChangeFirstClassify(item){
|
|
|
+ // if(listState.firstClassifyId===item.id) return
|
|
|
+ listState.firstClassifyId=item.id
|
|
|
+ listState.secClassifyId=0
|
|
|
+ listState.secClassifyOpt=item.child||[]
|
|
|
+ initList()
|
|
|
+}
|
|
|
+
|
|
|
+function handleChangeSecClassify(item){
|
|
|
+ if(listState.secClassifyId===item.id) return
|
|
|
+ listState.secClassifyId=item.id
|
|
|
+ initList()
|
|
|
+}
|
|
|
+
|
|
|
+//初始化列表
|
|
|
+function initList(){
|
|
|
+ listState.page=1
|
|
|
+ listState.finished=false
|
|
|
+ listState.list=[]
|
|
|
+ getVideoList()
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+async function getVideoList(){
|
|
|
+ listState.loading=true
|
|
|
+ const res=await apiRoadShowVideoList({
|
|
|
+ page_size:listState.pageSize,
|
|
|
+ current:listState.page,
|
|
|
+ classify_id_first:listState.firstClassifyId,
|
|
|
+ classify_id_second:listState.secClassifyId
|
|
|
+ })
|
|
|
+ setTimeout(() => {
|
|
|
+ listState.loading=false
|
|
|
+ }, 100);
|
|
|
+ if(res.code===200){
|
|
|
+ const arr=res.data.list||[]
|
|
|
+ listState.list=[...listState.list,...arr]
|
|
|
+ if(arr.length<listState.pageSize){
|
|
|
+ listState.finished=true
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+// 监听页面滚动
|
|
|
+function listenScroll(){
|
|
|
+ window.onscroll=(e)=>{
|
|
|
+ if(listState.loading||listState.finished) return
|
|
|
+ const scrollTop = document.documentElement.scrollTop||document.body.scrollTop;
|
|
|
+ const windowHeight = document.documentElement.clientHeight || document.body.clientHeight;
|
|
|
+ const scrollHeight = document.documentElement.scrollHeight||document.body.scrollHeight;
|
|
|
+ if(scrollTop+windowHeight>=scrollHeight){ //考虑到滚动的位置一般可能会大于一点可滚动的高度,所以这里不能用等于
|
|
|
+ console.log("距顶部"+scrollTop+"可视区高度"+windowHeight+"滚动条总高度"+scrollHeight);
|
|
|
+ listState.page++
|
|
|
+ getVideoList()
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+listenScroll()
|
|
|
+
|
|
|
+function goDetail(item){
|
|
|
+ const url=router.resolve({
|
|
|
+ path:'/roadshow/detail',
|
|
|
+ query:{
|
|
|
+ code:item.video_code
|
|
|
+ }
|
|
|
+ })
|
|
|
+ window.open(url.href,'_blank')
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div class="roadshow-list-page">
|
|
|
+ <div class="nav-warp">
|
|
|
+ <div class="first-nav-box">
|
|
|
+ <span
|
|
|
+ v-for="item in navList"
|
|
|
+ :key="item.id"
|
|
|
+ :class="item.id===listState.firstClassifyId?'active':''"
|
|
|
+ @click="handleChangeFirstClassify(item)"
|
|
|
+ >{{item.classify_name}}</span>
|
|
|
+ </div>
|
|
|
+ <div class="sec-nav-box">
|
|
|
+ <span
|
|
|
+ v-for="item in listState.secClassifyOpt"
|
|
|
+ :key="item.id"
|
|
|
+ :class="item.id===listState.secClassifyId?'active':''"
|
|
|
+ @click="handleChangeSecClassify(item)"
|
|
|
+ >{{item.classify_name}}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="video-list-wrap">
|
|
|
+ <div class="item" v-for="item in listState.list" :key="item.id" @click="goDetail(item)">
|
|
|
+ <div class="multi-ellipsis-l2 title">{{item.title}}</div>
|
|
|
+ <div class="img">
|
|
|
+ <img :src="item.video_cover_url" alt="">
|
|
|
+ </div>
|
|
|
+ <div class="time">{{item.publish_time}}</div>
|
|
|
+ </div>
|
|
|
+ <div class="last-item"></div>
|
|
|
+ <div class="last-item"></div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style lang="scss" scoped>
|
|
|
+.roadshow-list-page{
|
|
|
+ .first-nav-box{
|
|
|
+ padding: 20px 0 28px 0;
|
|
|
+ span{
|
|
|
+ display: inline-block;
|
|
|
+ margin-right: 40px;
|
|
|
+ cursor: pointer;
|
|
|
+ position: relative;
|
|
|
+ &.active::after{
|
|
|
+ display: block;
|
|
|
+ content: '';
|
|
|
+ position: absolute;
|
|
|
+ bottom: -10px;
|
|
|
+ width: 100%;
|
|
|
+ height: 4px;
|
|
|
+ background-color: var(--el-color-primary);
|
|
|
+ }
|
|
|
+ &:hover{
|
|
|
+ color: var(--el-color-primary);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .sec-nav-box{
|
|
|
+ span{
|
|
|
+ display: inline-block;
|
|
|
+ padding: 5px 20px;
|
|
|
+ cursor: pointer;
|
|
|
+ background: #F3F3F3;
|
|
|
+ border-radius: 4px;
|
|
|
+ color: #666;
|
|
|
+ margin-right: 20px;
|
|
|
+ &.active{
|
|
|
+ color: var(--el-color-primary);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .video-list-wrap{
|
|
|
+ margin-top: 30px;
|
|
|
+ display: flex;
|
|
|
+ flex-wrap: wrap;
|
|
|
+ justify-content: center;
|
|
|
+ .item{
|
|
|
+ width: 384px;
|
|
|
+ padding: 37px 12px 30px 12px;
|
|
|
+ border: 1px solid #E6E6E6;
|
|
|
+ .title{
|
|
|
+ min-height: 46px;
|
|
|
+ padding-bottom: 10px;
|
|
|
+ }
|
|
|
+ .time{
|
|
|
+ text-align: right;
|
|
|
+ margin-top: 10px ;
|
|
|
+ color: #999;
|
|
|
+ }
|
|
|
+ .img{
|
|
|
+ width: 358px;
|
|
|
+ height: 220px;
|
|
|
+ img{
|
|
|
+ object-fit: cover;
|
|
|
+ display: block;
|
|
|
+ cursor: pointer;
|
|
|
+ width: 100%;
|
|
|
+ height: 100%;
|
|
|
+ }
|
|
|
+
|
|
|
+ position: relative;
|
|
|
+ &::after{
|
|
|
+ content: '';
|
|
|
+ display: block;
|
|
|
+ width: 55px;
|
|
|
+ height: 55px;
|
|
|
+ background-image: url('@/assets/icon_play.png');
|
|
|
+ background-size: cover;
|
|
|
+ position: absolute;
|
|
|
+ left: 50%;
|
|
|
+ top: 50%;
|
|
|
+ transform: translate(-50%,-50%);
|
|
|
+ cursor: pointer;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .last-item{
|
|
|
+ width: 384px;
|
|
|
+ height: 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+@media (max-width: 768px){
|
|
|
+ .roadshow-list-page{
|
|
|
+ .first-nav-box{
|
|
|
+ padding: 15px 20px 10px 20px;
|
|
|
+ border-bottom: 1px solid #E6E6E6;
|
|
|
+ width: 100vw;
|
|
|
+ position: relative;
|
|
|
+ left: -20px;
|
|
|
+ display: flex;
|
|
|
+ overflow-x: auto;
|
|
|
+ margin-bottom: 10px;
|
|
|
+ span{
|
|
|
+ margin-right: 25px;
|
|
|
+ &.active::after{
|
|
|
+ bottom: -10px;
|
|
|
+ height: 2px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .video-list-wrap{
|
|
|
+ display: block;
|
|
|
+ .item{
|
|
|
+ width: 100%;
|
|
|
+ border-top: none;
|
|
|
+ border-left: none;
|
|
|
+ border-right: none;
|
|
|
+ padding: 15px 0;
|
|
|
+ .title{
|
|
|
+ min-height: 0;
|
|
|
+ padding-bottom: 5px;
|
|
|
+ }
|
|
|
+ .img{
|
|
|
+ width: 100%;
|
|
|
+ height: 200px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|