一、讲师列表页 - 前后端
1、Controller类
@RestController @CrossOrigin @RequestMapping("/eduservice/teacherfront") public class TeacherFrontController { @Autowired private EduTeacherService teacherService; @Autowired private EduCourseService courseService; //1.分页查询讲师的方法 @GetMapping("getTeacherFrontList/{page}/{limit}") public R getTeacherFrontList(@PathVariable long page,@PathVariable long limit){ Page <EduTeacher> teacherPage = new Page <>(page,limit); Map<String,Object> map= teacherService.getTeacherFrontList(teacherPage); return R.ok().data(map); } }
2、Service类
//查询讲师列表 带分页 @Override public Map <String, Object> getTeacherFrontList(Page <EduTeacher> page) { QueryWrapper <EduTeacher> wrapper = new QueryWrapper <>(); wrapper.orderByAsc("sort"); this.baseMapper.selectPage(page, wrapper); List <EduTeacher> records = page.getRecords(); long current = page.getCurrent(); long pages = page.getPages(); long size = page.getSize(); long total = page.getTotal(); boolean hasNext = page.hasNext(); boolean hasPrevious = page.hasPrevious(); Map <String, Object> map = new HashMap <>(); 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; }
3、使用Swagger测试
http://localhost:8001/swagger-ui.html
4、创建 api
创建文件夹api,api下创建teacher.js,用于封装讲师模块的请求
import request from '@/utils/request' export default { //分页查询讲师的方法 getTeacheList(page,limit){ return request({ url:`/eduservice/teacherfront/getTeacherFrontList/${page}/${limit}`, mehtod:'get' }) } }
5、讲师列表组件中调用api
pages/teacher/index.vue
<script> import teacherApi from '@/api/teacher' export default { // data() { // return { // data:[] // } // }, //异步调用(仅仅执行一次) //params:相当于之前 this.$route.params =>> this.$route.params.id==params.id asyncData({ params, error}) { return teacherApi.getTeacheList(1,8).then(response=>{ //this.data = response.data.data 和下面这行等价. return {data:response.data.data} }) }, methods: { gotoPage(page){ teacherApi.getTeacheList(page,8).then(response=>{ this.data = response.data.data }) } }, }; </script>
6、页面渲染
<template> <div id="aCoursesList" class="bg-fa of"> <!-- 讲师列表 开始 --> <section class="container"> <header class="comm-title all-teacher-title"> <h2 class="fl tac"> <span class="c-333">全部讲师</span> </h2> <section class="c-tab-title"> <a id="subjectAll" title="全部" href="#">全部</a> <!-- <c:forEach var="subject" items="${subjectList }"> <a id="${subject.subjectId}" title="${subject.subjectName }" href="javascript:void(0)" οnclick="submitForm(${subject.subjectId})">${subject.subjectName }</a> </c:forEach> --> </section> </header> <section class="c-sort-box unBr"> <div> <!-- /无数据提示 开始--> <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> <!-- /无数据提示 结束--> <article class="i-teacher-list" v-if="data.total > 0"> <ul class="of"> <li v-for="item in data.items" :key="item.id"> <section class="i-teach-wrap"> <div class="i-teach-pic"> <a :href="'/teacher/'+item.id" :title="item.name" target="_blank"> <img :src="item.avatar" :alt="item.name"> </a> </div> <div class="mt10 hLh30 txtOf tac"> <a :href="'/teacher/'+item.id" :title="item.name" target="_blank" class="fsize18 c-666">{{item.name}}</a> </div> <div class="hLh30 txtOf tac"> <span class="fsize14 c-999">{{item.intro}}</span> </div> <div class="mt15 i-q-txt"> <p class="c-999 f-fA">{{item.career}}</p> </div> </section> </li> </ul> <div class="clear"></div> </article> </div> <!-- 公共分页 开始 --> <div> <div class="paging"> <!-- undisable这个class是否存在,取决于数据属性hasPrevious --> <a :class="{undisable: !data.hasPrevious}" href="#" title="首页" @click.prevent="gotoPage(1)" disabled >首页</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> <!-- 公共分页 结束 --> </section> </section> <!-- /讲师列表 结束 --> </div> </template>
7、页面效果展示
二、讲师详情页 - 前后端
1、Controller 类
//2.讲师详情的功能 @GetMapping("getTeacherFrontInfo/{teacherId}") public R getTeacherFrontInfo(@PathVariable String teacherId){ //1.根据讲师id查询讲师基本信息 EduTeacher eduTeacher = teacherService.getById(teacherId); //2.根据讲师id查询讲师的所有课程 QueryWrapper <EduCourse> wrapper = new QueryWrapper <>(); wrapper.eq("teacher_id", teacherId); List <EduCourse> courseList = courseService.list(wrapper); return R.ok().data("teacher",eduTeacher).data("courseList",courseList); }
2、swagger测试
3、teacher api
api/teacher.js
//根据id获取讲师 getTeacherInfo(teacherId){ return request({ url:`/eduservice/teacherfront/getTeacherFrontInfo/${teacherId}`, mehtod:'get' }) }
4、讲师详情页中调用api
pages/teacher/_id.vue
<script> import teacherApi from '@/api/teacher' export default { asyncData({ params, error}) { //查询讲师详情信息 params.id==this.$route.params.id return teacherApi.getTeacherInfo(params.id).then(response=>{ return{ teacher:response.data.data.teacher, courseList:response.data.data.courseList } }) } }; </script>
5、页面渲染
(1)讲师基本信息模板
<!-- 讲师基本信息 --> <section class="fl t-infor-box c-desc-content"> <div class="mt20 ml20"> <section class="t-infor-pic"> <img :src="teacher.avatar"> </section> <h3 class="hLh30"> <span class="fsize24 c-333" v-if="teacher.level==1">{{teacher.name}} 高级讲师</span> <span class="fsize24 c-333" v-if="teacher.level==2">{{teacher.name}} 特级讲师</span> </h3> <section class="mt10"> <span class="t-tag-bg">{{teacher.career}}</span> </section> <section class="t-infor-txt"> <p class="mt20" >{{teacher.intro}}</p> </section> <div class="clear"></div> </div> </section>
(2)无数据提示
<!-- /无数据提示 开始--> <section class="no-data-wrap" v-if="courseList.length==0"> <em class="icon30 no-data-ico"> </em> <span class="c-666 fsize14 ml10 vam">没有相关数据,小编正在努力整理中...</span> </section>
(3)当前讲师课程列表
<article class="comm-course-list" v-if="courseList.length>0"> <ul class="of"> <li v-for="course in courseList" :key="course.id"> <div class="cc-l-wrap"> <section class="course-img"> <img :src="course.cover" class="img-responsive" > <div class="cc-mask"> <a :href="'/course/'+course.id" title="开始学习" target="_blank" class="comm-btn c-btn-1">开始学习</a> </div> </section> <h3 class="hLh30 txtOf mt10"> <a :href="'/course/'+course.id" :title="course.title" target="_blank" class="course-title fsize18 c-333">{{course.title}}</a> </h3> </div> </li> </ul> <div class="clear"></div> </article>
6、页面效果展示
点击讲师列表页面的任意一个讲师,可以进入讲师详情页面
三、课程列表页 - 前后端
1、Controller类
@RestController @CrossOrigin @RequestMapping("/eduservice/coursefront") public class CourseFrontController { @Autowired private EduCourseService courseService; @Autowired private EduChapterService chapterService; //1.条件查询带分页查询课程 @PostMapping("getFrontCourseList/{page}/{limit}") public R getFrontCourseList(@PathVariable long page, @PathVariable long limit, @RequestBody(required = false)CourseQueryVo courseQueryVo){ Page <EduCourse> coursePage = new Page <>(page, limit); Map <String,Object> map = courseService.getCourseFrontInfo(coursePage,courseQueryVo); //返回分页所有数据 return R.ok().data(map); } }
2、Service类
//条件查询带分页 @Override public Map <String, Object> getCourseFrontInfo(Page <EduCourse> coursePage, CourseQueryVo courseQueryVo) { QueryWrapper <EduCourse> wrapper = new QueryWrapper <>(); String buyCountSort = courseQueryVo.getBuyCountSort(); String gmtCreateSort = courseQueryVo.getGmtCreateSort(); String priceSort = courseQueryVo.getPriceSort(); String subjectParentId = courseQueryVo.getSubjectParentId(); String subjectId = courseQueryVo.getSubjectId(); if(!StringUtils.isEmpty(buyCountSort)){ if(buyCountSort.equals("1")){//1是降序 wrapper.orderByDesc("buy_count"); }else if(buyCountSort.equals("2")){//2是升序 wrapper.orderByAsc("buy_count"); } } if(!StringUtils.isEmpty(gmtCreateSort)){ if(gmtCreateSort.equals("1")){//1是降序 wrapper.orderByDesc("gmt_create"); }else if(gmtCreateSort.equals("2")){//2是升序 wrapper.orderByAsc("gmt_create"); } } if(!StringUtils.isEmpty(priceSort)){ if(priceSort.equals("1")){//1是降序 wrapper.orderByDesc("price"); }else if(priceSort.equals("2")){//2是升序 wrapper.orderByAsc("price"); } } if(!StringUtils.isEmpty(subjectParentId)){ wrapper.eq("subject_parent_id", subjectParentId); } if(!StringUtils.isEmpty(subjectId)){ wrapper.eq("subject_id", subjectId); } this.baseMapper.selectPage(coursePage, wrapper); List <EduCourse> records = coursePage.getRecords(); long current = coursePage.getCurrent(); long pages = coursePage.getPages(); long size = coursePage.getSize(); long total = coursePage.getTotal(); boolean hasNext = coursePage.hasNext(); boolean hasPrevious = coursePage.hasPrevious(); Map <String, Object> map = new HashMap <>(); 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; }
3、使用Swagger测试
4、编写course api
import request from '@/utils/request' export default { //1.条件查询带分页查询课程 getCourseList(page,limit,searchObj){ return request({ url:`/eduservice/coursefront/getFrontCourseList/${page}/${limit}`, method:'post', data:searchObj }) }, //2.查询所有课程分类 getAllSubject(){ return request({ url:`/eduservice/subject/getAllSubject`, method:'get' }) }, }