After Width: | Height: | Size: 181 B |
After Width: | Height: | Size: 193 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 26 KiB |
After Width: | Height: | Size: 275 B |
After Width: | Height: | Size: 336 B |
After Width: | Height: | Size: 4.2 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 13 KiB |
@ -0,0 +1,505 @@ |
||||
<template> |
||||
<div class="wrap"> |
||||
<div class="search"> |
||||
<h6>精品课程,精彩讲解</h6> |
||||
<div class="input"> |
||||
<img src="@/assets/images/search.png" alt=""> |
||||
<input type="text" placeholder="请输入课程名称" v-model="keyword"> |
||||
</div> |
||||
</div> |
||||
|
||||
<div class="bg"> |
||||
<div class="inner"> |
||||
<el-tree v-if="hasChildren && !keyword" class="columns" ref="leftColumn" :data="columns" highlight-current |
||||
:expand-on-click-node="false" default-expand-all :props="defaultProps" node-key="id" |
||||
icon-class="el-icon-arrow-down" @node-click="(item) => columnClick(item, 1)" |
||||
@current-change="(item) => columnClick(item, 1)"> |
||||
<span class="custom-tree-node" slot-scope="{ node, data }" style="padding-left: 10px;"> |
||||
<span :title="node.label">{{ node.label }}</span> |
||||
</span> |
||||
</el-tree> |
||||
|
||||
<div class="right"> |
||||
<div class="filter"> |
||||
<dl> |
||||
<dt>课程分类:</dt> |
||||
<dd :class="{ active: form.categoryId === '' }" @click="changeCategory('')">不限</dd> |
||||
<dd v-for="(item, i) in categories" :key="i" :class="{ active: form.categoryId === item.categoryId }" |
||||
@click="changeCategory(item.categoryId)">{{ item.name }}</dd> |
||||
</dl> |
||||
<dl> |
||||
<dt>课程类型:</dt> |
||||
<dd :class="{ active: form.classificationTagId === '' }" @click="changeType('')">不限</dd> |
||||
<dd v-for="(item, i) in classifications" :key="i" |
||||
:class="{ active: form.classificationTagId === item.categoryId }" @click="changeType(item.categoryId)"> |
||||
{{ |
||||
item.name }}</dd> |
||||
</dl> |
||||
</div> |
||||
|
||||
<div class="courses"> |
||||
<!-- <div class="course-bg"></div> --> |
||||
<template v-if="list.length"> |
||||
<ul> |
||||
<li v-for="(item, index) in list" :key="index" @click="toDetail(item.id)"> |
||||
<img :src="item.coverImageUrl" alt="" /> |
||||
<div class="title">{{ item.name }}</div> |
||||
<div class="desc" v-html="item.introduction"></div> |
||||
<div class="metas"> |
||||
<div class="meta"> |
||||
<i class="el-icon-view"></i> |
||||
{{ item.totalBrowsing }} |
||||
</div> |
||||
<div class="meta"> |
||||
<i class="el-icon-user"></i> |
||||
{{ item.source }} |
||||
</div> |
||||
</div> |
||||
</li> |
||||
</ul> |
||||
<div class="pagination"> |
||||
<el-pagination background layout="total, prev, pager, next" :total="total" |
||||
@current-change="handleCurrentChange" :current-page="page" :page-size="pageSize"> |
||||
</el-pagination> |
||||
</div> |
||||
</template> |
||||
<template v-else> |
||||
<div class="empty"> |
||||
<div> |
||||
<img src="@/assets/images/none.png" alt=""> |
||||
<p>暂无课程</p> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</div> |
||||
</template> |
||||
|
||||
<script> |
||||
import { Loading } from "element-ui"; |
||||
export default { |
||||
data () { |
||||
return { |
||||
id: +this.$route.query.id, |
||||
columns: [], |
||||
defaultProps: { |
||||
value: 'id', |
||||
label: 'columnName' |
||||
}, |
||||
form: { |
||||
categoryId: '', |
||||
classificationTagId: '' |
||||
}, |
||||
categories: [], |
||||
classifications: [], |
||||
list: [], |
||||
keyword: '', |
||||
total: 0, |
||||
page: 1, |
||||
pageSize: window.innerWidth > 1700 ? 10 : 8, |
||||
searchTimer: null, |
||||
loadIns: null, |
||||
hasChildren: false, |
||||
}; |
||||
}, |
||||
mounted () { |
||||
this.getCategory() |
||||
this.getClassification() |
||||
this.getLeftColumn() |
||||
this.getData() |
||||
}, |
||||
computed: { |
||||
site () { |
||||
return this.$route.query.siteId || this.$store.state.content.site |
||||
} |
||||
}, |
||||
watch: { |
||||
keyword: function (val) { |
||||
clearTimeout(this.searchTimer); |
||||
this.searchTimer = setTimeout(() => { |
||||
if (val) { |
||||
this.form.categoryId = '' |
||||
this.form.classificationTagId = '' |
||||
} |
||||
this.initData() |
||||
}, 500) |
||||
} |
||||
}, |
||||
methods: { |
||||
getList () { |
||||
this.$post(this.api.courseProduct, { |
||||
...this.form, |
||||
siteId: this.site, |
||||
pageNum: this.page, |
||||
pageSize: this.pageSize, |
||||
columnId: this.id, |
||||
keyWord: this.keyword |
||||
}).then(({ data }) => { |
||||
this.list = data.records |
||||
this.total = +data.total |
||||
this.loadIns.close() |
||||
}).catch(res => { |
||||
this.loadIns.close() |
||||
}) |
||||
}, |
||||
getData () { |
||||
this.loadIns = Loading.service() |
||||
this.getList() |
||||
}, |
||||
initData () { |
||||
this.page = 1; |
||||
this.getData(); |
||||
}, |
||||
// 获取栏目详情 |
||||
getInfo () { |
||||
this.id && |
||||
this.$post(`${this.api.findColumn}?id=${this.id}`) |
||||
.then(({ data }) => { |
||||
this.columnClick(data); |
||||
this.info = data |
||||
this.pageSize = data.pageSize || 10 |
||||
this.getLeftColumn() |
||||
}) |
||||
.catch((res) => { }); |
||||
}, |
||||
// 左边栏目 |
||||
getLeftColumn () { |
||||
this.$post(`${this.api.oneLevelChecksThemAll}?id=${this.id}&isSort=1&siteId=${this.site}`).then(({ data }) => { |
||||
this.columns = data |
||||
this.hasChildren = data.length && data.find(n => n.children && n.children.length) // 是否有子级 |
||||
// 如果没上传banner |
||||
if (!this.info.columnBanner) { |
||||
this.getBanner(data); |
||||
this.info.columnBanner = this.columnBanner || require('@/assets/images/column-banner.png'); |
||||
} |
||||
this.$nextTick(() => { |
||||
const el = this.$refs.leftColumn |
||||
el && el.setCurrentKey(this.id) |
||||
}) |
||||
}) |
||||
.catch((err) => { }) |
||||
}, |
||||
// 获取分类 |
||||
async getCategory () { |
||||
const { data } = await this.$post(`${this.api.categoryList}?siteId=${this.site}&type=0`) |
||||
this.categories = data |
||||
}, |
||||
// 获取类型 |
||||
async getClassification () { |
||||
const { data } = await this.$post(`${this.api.categoryList}?siteId=${this.site}&type=1`) |
||||
this.classifications = data |
||||
}, |
||||
// 分类切换 |
||||
changeCategory (id) { |
||||
this.form.categoryId = id |
||||
this.initData() |
||||
}, |
||||
// 类型切换 |
||||
changeType (id) { |
||||
this.form.classificationTagId = id |
||||
this.initData() |
||||
}, |
||||
handleCurrentChange (val) { |
||||
this.page = val |
||||
this.getData() |
||||
}, |
||||
// 点击栏目回调 |
||||
columnClick (to, left) { |
||||
this.page = 1 |
||||
const { typeId } = to |
||||
// 判断是否是课程页 |
||||
this.$router.replace(`/${(typeId === 1 || typeId === 4) && to.templateId === 12 ? 'course' : 'column'}?id=${to.id}&siteId=${this.site}`).catch(() => { }) |
||||
}, |
||||
toDetail (id) { |
||||
this.$router.push(`/course/details?id=${id}`); |
||||
} |
||||
} |
||||
}; |
||||
</script> |
||||
|
||||
<style lang="scss" scoped> |
||||
.search { |
||||
position: relative; |
||||
padding: 100px 0 130px; |
||||
text-align: center; |
||||
background: url(../../assets/images/course/course-bg2.png) (73px 50px)/250px auto no-repeat, |
||||
url(../../assets/images/course/course-bg4.png) (top left) / auto no-repeat, |
||||
url(../../assets/images/course/course-bg3.png) (top right) / auto no-repeat, |
||||
url(../../assets/images/course/course-bg1.png) 0 0/100% 100% no-repeat; |
||||
|
||||
h6 { |
||||
margin-bottom: 25px; |
||||
font-size: 26px; |
||||
color: #fff; |
||||
} |
||||
|
||||
.input { |
||||
position: relative; |
||||
width: 700px; |
||||
margin: 0 auto; |
||||
} |
||||
|
||||
img { |
||||
position: absolute; |
||||
top: 19px; |
||||
left: 14px; |
||||
} |
||||
|
||||
input { |
||||
width: 100%; |
||||
height: 62px; |
||||
line-height: 62px; |
||||
padding: 0 50px; |
||||
font-size: 18px; |
||||
color: #333; |
||||
border: 0; |
||||
outline: none; |
||||
border-radius: 4px; |
||||
} |
||||
} |
||||
|
||||
.wrap { |
||||
.bg { |
||||
padding: 20px 0; |
||||
background: #f3f6fa url(../../assets/images/course/course3.png) 0 0 / auto no-repeat; |
||||
} |
||||
|
||||
.inner { |
||||
display: flex; |
||||
width: 1200px; |
||||
margin: 0 auto; |
||||
|
||||
} |
||||
|
||||
/deep/.columns { |
||||
width: 18%; |
||||
margin-right: 20px; |
||||
overflow: auto; |
||||
|
||||
span { |
||||
white-space: nowrap; |
||||
overflow: hidden; |
||||
text-overflow: ellipsis; |
||||
} |
||||
|
||||
&:after { |
||||
content: ''; |
||||
position: absolute; |
||||
top: 0; |
||||
right: 0; |
||||
width: 1px; |
||||
height: 100%; |
||||
background-color: #e1e6f2; |
||||
} |
||||
|
||||
.el-tree-node__content { |
||||
position: relative; |
||||
height: 2.4rem; |
||||
padding-left: 2rem; |
||||
margin-bottom: 1px; |
||||
font-size: 1.04rem; |
||||
color: #666; |
||||
background-color: #fff; |
||||
border-top: 1px solid #f8f9f9; |
||||
cursor: pointer; |
||||
|
||||
&:hover { |
||||
color: #0c84eb; |
||||
} |
||||
} |
||||
|
||||
.el-tree-node__label { |
||||
font-size: 1.28rem; |
||||
color: #666; |
||||
line-height: 22px; |
||||
} |
||||
|
||||
.el-tree-node__expand-icon.expanded { |
||||
transform: rotate(180deg); |
||||
} |
||||
|
||||
.el-tree-node__expand-icon { |
||||
position: absolute; |
||||
right: 10px; |
||||
} |
||||
|
||||
.is-current>.el-tree-node__content { |
||||
background-color: #e5edf8; |
||||
border-top: 0; |
||||
|
||||
&:after { |
||||
content: ''; |
||||
z-index: 2; |
||||
position: absolute; |
||||
top: 0; |
||||
right: 0; |
||||
width: 2px; |
||||
height: 100%; |
||||
background-color: #083a93; |
||||
} |
||||
|
||||
.el-tree-node__label, |
||||
.custom-tree-node { |
||||
font-weight: 600; |
||||
color: #1150ac; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.right { |
||||
flex: 1; |
||||
|
||||
&:only-child { |
||||
.courses li img { |
||||
height: 150px; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.filter { |
||||
width: 100%; |
||||
padding: 0 20px; |
||||
background-color: #fff; |
||||
|
||||
.filter-inner { |
||||
padding: 0 200px; |
||||
} |
||||
|
||||
dl { |
||||
display: flex; |
||||
align-items: center; |
||||
padding: 12px 0; |
||||
|
||||
dt { |
||||
color: #333; |
||||
font-size: 16px; |
||||
font-weight: 600; |
||||
white-space: nowrap; |
||||
} |
||||
|
||||
dd { |
||||
padding: 5px 15px; |
||||
color: #6a6a6a; |
||||
font-size: 16px; |
||||
white-space: nowrap; |
||||
cursor: pointer; |
||||
border-radius: 4px; |
||||
|
||||
&.active { |
||||
color: $main-color; |
||||
background-color: #e6f0ff; |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
.courses { |
||||
position: relative; |
||||
padding: 10px 0 20px; |
||||
|
||||
.course-bg { |
||||
position: absolute; |
||||
top: 0; |
||||
right: 0; |
||||
width: 602px; |
||||
height: 100%; |
||||
background: url(../../assets/images/course/course4.png) (0 -100px)/140% 140% no-repeat; |
||||
} |
||||
|
||||
ul { |
||||
position: relative; |
||||
display: flex; |
||||
flex-wrap: wrap; |
||||
margin: 0 -10px; |
||||
} |
||||
|
||||
li { |
||||
width: calc(25% - 20px); |
||||
overflow: hidden; |
||||
padding: 12px; |
||||
margin: 10px; |
||||
cursor: pointer; |
||||
border-radius: 8px; |
||||
background-color: #fff; |
||||
transition: all 0.3s; |
||||
|
||||
img { |
||||
width: 100%; |
||||
height: 115px; |
||||
transition: 0.3s; |
||||
object-fit: cover; |
||||
} |
||||
|
||||
.title { |
||||
margin: 10px 0 5px; |
||||
color: #0b1d30; |
||||
font-size: 16px; |
||||
word-wrap: break-word; |
||||
word-break: break-all; |
||||
overflow: hidden; |
||||
text-overflow: ellipsis; |
||||
white-space: nowrap; |
||||
} |
||||
|
||||
.desc span { |
||||
color: #f00; |
||||
font-size: 14px; |
||||
background-color: #f00; |
||||
} |
||||
|
||||
.desc { |
||||
color: #757f92; |
||||
font-size: 14px; |
||||
display: -webkit-box; |
||||
-webkit-box-orient: vertical; |
||||
-webkit-line-clamp: 2; |
||||
overflow: hidden; |
||||
|
||||
&.ie { |
||||
height: 80px; |
||||
text-overflow: ellipsis; |
||||
white-space: nowrap; |
||||
} |
||||
} |
||||
|
||||
.type { |
||||
display: inline-block; |
||||
padding: 2px 10px; |
||||
border-radius: 20px; |
||||
color: #1cdbb8; |
||||
border: 1px solid; |
||||
} |
||||
|
||||
.metas { |
||||
display: flex; |
||||
justify-content: space-between; |
||||
align-items: center; |
||||
margin-top: 10px; |
||||
} |
||||
|
||||
.meta { |
||||
color: #a9a9a9; |
||||
font-size: 12px; |
||||
} |
||||
|
||||
&:hover { |
||||
box-shadow: 0px 5px 12px 4px rgba(142, 123, 253, 0.09), 0px 3px 6px 0px rgba(142, 123, 253, 0.12), |
||||
0px 1px 2px -2px rgba(142, 123, 253, 0.16); |
||||
|
||||
img { |
||||
transform: scale(1.05); |
||||
} |
||||
} |
||||
} |
||||
|
||||
@media (max-width: 1700px) { |
||||
li { |
||||
width: calc(25% - 20px); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
</style> |
@ -0,0 +1,14 @@ |
||||
import BasicLayout from '@/layouts/home' |
||||
const name = 'course' |
||||
export default { |
||||
path: `/${name}`, |
||||
component: BasicLayout, |
||||
children: [ |
||||
{ |
||||
name, |
||||
path: `/${name}`, |
||||
component: () => import(`@/pages/${name}`), |
||||
meta: { title: '课程中心' } |
||||
} |
||||
] |
||||
}; |