一、课程后端接口
1、课程列表
(1)课程列表vo类
@ApiModel(value = "课程查询对象", description = "课程查询对象封装")
@Data
public class CourseQueryVo implements Serializable {
private static final long serialVersionUID = 1L;
@ApiModelProperty(value = "课程名称")
private String title;
@ApiModelProperty(value = "讲师id")
private String teacherId;
@ApiModelProperty(value = "一级类别id")
private String subjectParentId;
@ApiModelProperty(value = "二级类别id")
private String subjectId;
@ApiModelProperty(value = "销量排序")
private String buyCountSort;
@ApiModelProperty(value = "最新时间排序")
private String gmtCreateSort;
@ApiModelProperty(value = "价格排序")
private String priceSort;
}
(2)课程列表controller
@ApiOperation(value = "分页课程列表")
@PostMapping(value = "{page}/{limit}")
public R pageList(
@ApiParam(name = "page", value = "当前页码", required = true)
@PathVariable Long page,
@ApiParam(name = "limit", value = "每页记录数", required = true)
@PathVariable Long limit,
@ApiParam(name = "courseQuery", value = "查询对象", required = false)
@RequestBody(required = false) CourseQueryVo courseQuery){
Page<EduCourse> pageParam = new Page<EduCourse>(page, limit);
Map<String, Object> map = courseService.pageListWeb(pageParam, courseQuery);
return R.ok().data(map);
}
(3)课程列表service
@Override
public Map<String, Object> pageListWeb(Page<EduCourse> pageParam, CourseQueryVo courseQuery) {
QueryWrapper<EduCourse> queryWrapper = new QueryWrapper<>();
if (!StringUtils.isEmpty(courseQuery.getSubjectParentId())) {
queryWrapper.eq("subject_parent_id", courseQuery.getSubjectParentId());
}
if (!StringUtils.isEmpty(courseQuery.getSubjectId())) {
queryWrapper.eq("subject_id", courseQuery.getSubjectId());
}
if (!StringUtils.isEmpty(courseQuery.getBuyCountSort())) {
queryWrapper.orderByDesc("buy_count");
}
if (!StringUtils.isEmpty(courseQuery.getGmtCreateSort())) {
queryWrapper.orderByDesc("gmt_create");
}
if (!StringUtils.isEmpty(courseQuery.getPriceSort())) {
queryWrapper.orderByDesc("price");
}
baseMapper.selectPage(pageParam, queryWrapper);
List<EduCourse> records = pageParam.getRecords();
long current = pageParam.getCurrent();
long pages = pageParam.getPages();
long size = pageParam.getSize();
long total = pageParam.getTotal();
boolean hasNext = pageParam.hasNext();
boolean hasPrevious = pageParam.hasPrevious();
Map<String, Object> map = new HashMap<String, Object>();
map.put("items", records);
map.put("current", current);
map.put("pages", pages);
map.put("size", size);
map.put("total", total);
map.put("hasNext", hasNext);
map.put("hasPrevious", hasPrevious);
return map;
}
**
二、课程列表前端
1、定义api
api/course.js
import request from '@/utils/request'
export default {
getPageList(page, limit, searchObj) {
return request({
url: `/eduservice/edu/course/${page}/${limit}`,
method: 'post',
data: searchObj
})
},
// 获取课程二级分类
getNestedTreeList2() {
return request({
url: `/eduservice/edu/course/list2`,
method: 'get'
})
}
}
2、页面调用接口
pages/course/index.vue
<script>
import course from '@/api/course'
export default {
data () {
return {
page:1,
data:{},
subjectNestedList: [], // 一级分类列表
subSubjectList: [], // 二级分类列表
searchObj: {}, // 查询表单对象
oneIndex:-1,
twoIndex:-1,
buyCountSort:"",
gmtCreateSort:"",
priceSort:""
}
},
//加载完渲染时
created () {
//获取课程列表
this.initCourse()
//获取分类
this.initSubject()
},
methods: {
//查询课程列表
initCourse(){
course.getPageList(1, 8,this.searchObj).then(response => {
this.data = response.data.data
})
},
//查询所有一级分类
initSubject(){
//debugger
course.getNestedTreeList2().then(response => {
this.subjectNestedList = response.data.data.items
})
},
//点击一级分类,显示对应的二级分类,查询数据
searchOne(subjectParentId, index) {
//debugger
this.oneIndex = index
this.twoIndex = -1
this.searchObj.subjectId = "";
this.subSubjectList = [];
this.searchObj.subjectParentId = subjectParentId;
this.gotoPage(this.page)
for (let i = 0; i < this.subjectNestedList.length; i++) {
if (this.subjectNestedList[i].id === subjectParentId) {
this.subSubjectList = this.subjectNestedList[i].children
}
}
},
//点击二级分类,查询数据
searchTwo(subjectId, index) {
this.twoIndex = index
this.searchObj.subjectId = subjectId;
this.gotoPage(this.page)
},
//购买量查询
searchBuyCount() {
this.buyCountSort = "1";
this.gmtCreateSort = "";
this.priceSort = "";
this.searchObj.buyCountSort = this.buyCountSort;
this.searchObj.gmtCreateSort = this.gmtCreateSort;
this.searchObj.priceSort = this.priceSort;
this.gotoPage(this.page)
},
//更新时间查询
searchGmtCreate() {
debugger
this.buyCountSort = "";
this.gmtCreateSort = "1";
this.priceSort = "";
this.searchObj.buyCountSort = this.buyCountSort;
this.searchObj.gmtCreateSort = this.gmtCreateSort;
this.searchObj.priceSort = this.priceSort;
this.gotoPage(this.page)
},
//价格查询
searchPrice() {
this.buyCountSort = "";
this.gmtCreateSort = "";
this.priceSort = "1";
this.searchObj.buyCountSort = this.buyCountSort;
this.searchObj.gmtCreateSort = this.gmtCreateSort;
this.searchObj.priceSort = this.priceSort;
this.gotoPage(this.page)
},
//分页查询
gotoPage(page) {
this.page = page
course.getPageList(page, 8, this.searchObj).then(response => {
this.data = response.data.data
})
}
}
}
</script>
<style scoped>
.active {
background: #bdbdbd;
}
.hide {
display: none;
}
.show {
display: block;
}
</style>
三、课程列表渲染
1、课程类别显示
<section class="c-s-dl">
<dl>
<dt>
<span class="c-999 fsize14">课程类别</span>
</dt>
<dd class="c-s-dl-li">
<ul class="clearfix">
<li>
<a title="全部" href="javascript:void(0);" @click="searchOne('')">全部</a>
</li>
<li v-for="(item,index) in subjectNestedList" v-bind:key="index" :class="{active:oneIndex==index}">
<a :title="item.title" href="javascript:void(0);" @click="searchOne(item.id, index)">{{item.title}}</a>
</li>
</ul>
</dd>
</dl>
<dl>
<dt>
<span class="c-999 fsize14"/>
</dt>
<dd class="c-s-dl-li">
<ul class="clearfix">
<li v-for="(item,index) in subSubjectList" v-bind:key="index" :class="{active:twoIndex==index}">
<a :title="item.title" href="javascript:void(0);" @click="searchTwo(item.id, index)">{{item.title}}</a>
</li>
</ul>
</dd>
</dl>
<div class="clear"/>
</section>
2、排序方式显示
<section class="fl">
<ol class="js-tap clearfix">
<li :class="{'current bg-orange':buyCountSort!=''}">
<a title="销量" href="javascript:void(0);" @click="searchBuyCount()">销量
<span :class="{hide:buyCountSort==''}">↓</span>
</a>
</li>
<li :class="{'current bg-orange':gmtCreateSort!=''}">
<a title="最新" href="javascript:void(0);" @click="searchGmtCreate()">最新
<span :class="{hide:gmtCreateSort==''}">↓</span>
</a>
</li>
<li :class="{'current bg-orange':priceSort!=''}">
<a title="价格" href="javascript:void(0);" @click="searchPrice()">价格
<span :class="{hide:priceSort==''}">↓</span>
</a>
</li>
</ol>
</section>
3、无数据提示
添加:v-if=”data.total==0”
<!-- /无数据提示 开始-->
<section class="no-data-wrap" v-if="data.total==0">
<em class="icon30 no-data-ico"> </em>
<span class="c-666 fsize14 ml10 vam">没有相关数据,小编正在努力整理中...</span>
</section>
<!-- /无数据提示 结束-->
4、列表
<!-- 数据列表 开始-->
<article v-if="data.total>0" class="comm-course-list">
<ul id="bna" class="of">
<li v-for="item in data.items" :key="item.id">
<div class="cc-l-wrap">
<section class="course-img">
<img :src="item.cover" class="img-responsive" alt="听力口语">
<div class="cc-mask">
<a :href="'/course/'+item.id" title="开始学习" class="comm-btn c-btn-1">开始学习</a>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a :href="'/course/'+item.id" :title="item.title" class="course-title fsize18 c-333">{{ item.title }}</a>
</h3>
<section class="mt10 hLh20 of">
<span v-if="Number(item.price) === 0" class="fr jgTag bg-green">
<i class="c-fff fsize12 f-fA">免费</i>
</span>
<span class="fl jgAttr c-ccc f-fA">
<i class="c-999 f-fA">{{ item.viewCount }}人学习</i>
|
<i class="c-999 f-fA">9634评论</i>
</span>
</section>
</div>
</li>
</ul>
<div class="clear"/>
</article>
<!-- /数据列表 结束-->
5、分页页面渲染
<div>
<div class="paging">
<!-- undisable这个class是否存在,取决于数据属性hasPrevious -->
<a
:class="{undisable: !data.hasPrevious}"
href="#"
title="首页"
@click.prevent="gotoPage(1)">首</a>
<a
:class="{undisable: !data.hasPrevious}"
href="#"
title="前一页"
@click.prevent="gotoPage(data.current-1)"><</a>
<a
v-for="page in data.pages"
:key="page"
:class="{current: data.current == page, undisable: data.current == page}"
:title="'第'+page+'页'"
href="#"
@click.prevent="gotoPage(page)">{{ page }}</a>
<a
:class="{undisable: !data.hasNext}"
href="#"
title="后一页"
@click.prevent="gotoPage(data.current+1)">></a>
<a
:class="{undisable: !data.hasNext}"
href="#"
title="末页"
@click.prevent="gotoPage(data.pages)">末</a>
<div class="clear"/>
</div>
</div>