|
@@ -0,0 +1,247 @@
|
|
|
+<script setup>
|
|
|
+import { onMounted , ref , watch} from 'vue';
|
|
|
+import { useRoute , useRouter} from "vue-router";
|
|
|
+import {apiClassifyList,apiTagList,apiVideoList} from '@/api/trainingVideoApi';
|
|
|
+import { Search } from '@element-plus/icons-vue'
|
|
|
+
|
|
|
+const route = useRoute()
|
|
|
+const router = useRouter()
|
|
|
+
|
|
|
+let classifyList = ref([]) //分类列表
|
|
|
+let choosedClassify = ref({ClassifyId:0}) //所选分类
|
|
|
+let isClassifyListExpand = ref(false) //分类列表是否展开
|
|
|
+let tagList = ref([]) //标签列表
|
|
|
+let choosedTags = ref([]) //所选标签
|
|
|
+let isTagListExpand = ref(false) //标签列表是否展开
|
|
|
+let videoList = ref([]) //视频列表
|
|
|
+let total = ref(0) //视频总数
|
|
|
+let currentIndex = ref(1) //列表页
|
|
|
+let keyword = ref('') //搜索词
|
|
|
+let selectValue = ref('New') //select筛选项
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+let beforeMounted = ref(false)
|
|
|
+
|
|
|
+function getClassifyList(){
|
|
|
+ apiClassifyList().then(res=>{
|
|
|
+ if(res.code!==200) return
|
|
|
+ classifyList.value = res.data&&res.data.List||[]
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function changeClassify(classify){
|
|
|
+ choosedClassify.value = classify
|
|
|
+ handleCurrentChange(1)
|
|
|
+}
|
|
|
+
|
|
|
+function changeTags(tag){
|
|
|
+ const {TagId} = tag
|
|
|
+ const index = choosedTags.value.findIndex(i=>i.TagId===TagId)
|
|
|
+ if(index!==-1){
|
|
|
+ choosedTags.value.splice(index,1)
|
|
|
+ }else{
|
|
|
+ choosedTags.value.push(tag)
|
|
|
+ }
|
|
|
+}
|
|
|
+watch(
|
|
|
+ ()=>choosedTags.value.length,
|
|
|
+ ()=>{
|
|
|
+ handleCurrentChange(1)
|
|
|
+ }
|
|
|
+)
|
|
|
+
|
|
|
+function getTagList(){
|
|
|
+ apiTagList().then(res=>{
|
|
|
+ if(res.code!==200) return
|
|
|
+ tagList.value = res.data||[]
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+function getVideoList(){
|
|
|
+ apiVideoList({
|
|
|
+ page_size:15,
|
|
|
+ current_index:currentIndex.value,
|
|
|
+ keyword:keyword.value,
|
|
|
+ is_new:selectValue.value==='New',
|
|
|
+ is_hot:selectValue.value==='Hot',
|
|
|
+ classify_id:choosedClassify.value.ClassifyId||0,
|
|
|
+ tag_ids:choosedTags.value.map(i=>i.TagId).join(',')
|
|
|
+ }).then(res=>{
|
|
|
+ if(res.code!==200) return
|
|
|
+ if(res.data){
|
|
|
+ videoList.value = res.data.list||[]
|
|
|
+ total.value = res.data.page.total||0
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+function handleCurrentChange(page){
|
|
|
+ currentIndex.value = page
|
|
|
+ getVideoList()
|
|
|
+}
|
|
|
+
|
|
|
+function gotoVideoDetail(video){
|
|
|
+ const { VideoCode } = video
|
|
|
+ const {bus_code} = route.query
|
|
|
+ router.push({
|
|
|
+ path:'/video/detail',
|
|
|
+ query:{
|
|
|
+ video_code:VideoCode,
|
|
|
+ bus_code:bus_code||''
|
|
|
+ }
|
|
|
+ })
|
|
|
+}
|
|
|
+
|
|
|
+onMounted(()=>{
|
|
|
+ getClassifyList()
|
|
|
+ getTagList()
|
|
|
+ getVideoList()
|
|
|
+ beforeMounted.value = true
|
|
|
+
|
|
|
+})
|
|
|
+
|
|
|
+
|
|
|
+</script>
|
|
|
+
|
|
|
+<template>
|
|
|
+ <div class="video-list-wrap">
|
|
|
+ <div class="classify-box select">
|
|
|
+ <span style="align-self:center;">分类:</span>
|
|
|
+ <div class="list">
|
|
|
+ <span class="list-item" :class="{'active':choosedClassify.ClassifyId===0}"
|
|
|
+ @click="changeClassify({ClassifyId:0})">全部</span>
|
|
|
+ <span class="list-item" :class="{'active':choosedClassify.ClassifyId===item.ClassifyId}"
|
|
|
+ v-for="item in classifyList" :key="item.ClassifyId" @click="changeClassify(item)">{{item.ClassifyName}}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="tag-box select">
|
|
|
+ <span style="align-self:center;">标签:</span>
|
|
|
+ <div class="list">
|
|
|
+ <span class="list-item" :class="{'active':choosedTags.length===0}"
|
|
|
+ @click="choosedTags = []">全部</span>
|
|
|
+ <span class="list-item" :class="{'active':choosedTags.findIndex(i=>i.TagId===item.TagId)!==-1}"
|
|
|
+ v-for="item in tagList" :key="item.TagId" @click="changeTags(item)">{{item.TagName}}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="select-box">
|
|
|
+ <el-select v-model="selectValue" placeholder="Select" size="large" @change="handleCurrentChange(1)">
|
|
|
+ <el-option label="最新" value="New"/>
|
|
|
+ <el-option label="最热" value="Hot"/>
|
|
|
+ </el-select>
|
|
|
+ </div>
|
|
|
+ <div class="list-box">
|
|
|
+ <div class="list-item" v-for="item in videoList" :key="item.VideoId" @click="gotoVideoDetail(item)">
|
|
|
+ <div class="list-image" :style="{background:`no-repeat top/contain url('${item.CoverImg}')`}"></div>
|
|
|
+ <h4 class="word-ellipsis">{{item.Title}}</h4>
|
|
|
+ <div class="tag-box">
|
|
|
+ <span class="tag-item" v-for="tag in item.Tags" :key="tag.TagId">{{tag.TagName}}</span>
|
|
|
+ </div>
|
|
|
+ <p class="word-ellipsis" style="flex:1;color:#999999;text-overflow: ellipsis;">{{item.Introduce||'暂无简介'}}</p>
|
|
|
+ <div class="other">
|
|
|
+ <span>{{item.PublishTime}}</span>
|
|
|
+ <el-icon style="margin-left: auto;margin-right:5px;"><VideoPlay /></el-icon>{{item.ViewTotal}}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="empty-hint" v-if="videoList.length===0" style="width:100%;text-align: center;color: #999999;">
|
|
|
+ <img src="~@/assets/img/nodata.png" alt="" style="width: 200px;"/>
|
|
|
+ <p>{{keyword?`没有找到与${keyword}相关的课程`:'暂无课程'}}</p>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class="page-box">
|
|
|
+ <el-pagination
|
|
|
+ v-model:current-page="currentIndex"
|
|
|
+ layout="total,->,prev,pager,next,jumper"
|
|
|
+ :page-size="15"
|
|
|
+ :total="total"
|
|
|
+ @current-change="handleCurrentChange"
|
|
|
+ >
|
|
|
+ </el-pagination>
|
|
|
+ </div>
|
|
|
+ <!-- teleport search -->
|
|
|
+ <Teleport to=".layout-header-other" v-if="beforeMounted">
|
|
|
+ <div class="search-box">
|
|
|
+ <el-input placeholder="请输入视频名称" size="large" clearable style="width:280px;"
|
|
|
+ :prefix-icon="Search" v-model.trim="keyword" @input="handleCurrentChange(1)"></el-input>
|
|
|
+ </div>
|
|
|
+ </Teleport>
|
|
|
+ </div>
|
|
|
+</template>
|
|
|
+
|
|
|
+<style scoped lang="scss">
|
|
|
+.video-list-wrap{
|
|
|
+ padding:30px 120px 30px 120px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ background-color:#F2F6FA;
|
|
|
+ height: calc(100vh - 60px);
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ .select{
|
|
|
+ display: flex;
|
|
|
+ margin-bottom:20px;
|
|
|
+ .list{
|
|
|
+ display: flex;
|
|
|
+ margin-left: 15px;
|
|
|
+ gap: 10px;
|
|
|
+ .list-item{
|
|
|
+ box-sizing: border-box;
|
|
|
+ padding: 8px;
|
|
|
+ background-color: #fff;
|
|
|
+ border-radius: 4px;
|
|
|
+ cursor: pointer;
|
|
|
+ &.active,&:hover{
|
|
|
+ color:#fff;
|
|
|
+ background-color:#0052D9;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .list-box{
|
|
|
+ margin-top: 20px;
|
|
|
+ flex: 1;
|
|
|
+ overflow-y: auto;
|
|
|
+ width:100%;
|
|
|
+ display: flex;
|
|
|
+ gap: 20px;
|
|
|
+ .list-item{
|
|
|
+ width:19%;
|
|
|
+ height: 345px;
|
|
|
+ box-sizing: border-box;
|
|
|
+ padding:10px;
|
|
|
+ background-color: #fff;
|
|
|
+ border-radius:8px;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ cursor: pointer;
|
|
|
+ .list-image{
|
|
|
+ width:100%;
|
|
|
+ height:0;
|
|
|
+ padding-bottom:67%;
|
|
|
+ }
|
|
|
+ h4{
|
|
|
+ margin:10px 0;
|
|
|
+ }
|
|
|
+ .tag-box{
|
|
|
+ .tag-item{
|
|
|
+ background-color: #ECF2FE;
|
|
|
+ color:#0052D9;
|
|
|
+ padding:4px;
|
|
|
+ text-align: center;
|
|
|
+ margin-right:10px;
|
|
|
+ border-radius: 4px;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .other{
|
|
|
+ display: flex;
|
|
|
+ justify-content: space-between;
|
|
|
+ align-items: center;
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+ }
|
|
|
+ .page-box{
|
|
|
+ background-color: #fff;
|
|
|
+ box-sizing: border-box;
|
|
|
+ padding:12px;
|
|
|
+ }
|
|
|
+}
|
|
|
+</style>
|