❤ 作者主页:Java技术一点通的博客
❀ 个人介绍:大家好,我是Java技术一点通!( ̄▽ ̄)~*
🍊 记得关注、点赞、收藏、评论⭐️⭐️⭐️
📣 认真学习,共同进步!!!🎉🎉
首页名师功能
一、名师页面静态效果整合
1. 列表页面
pages/teacher/index.vue
<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">
<em class="icon30 no-data-ico"> </em>
<span class="c-666 fsize14 ml10 vam"
>没有相关数据,小编正在努力整理 中...</span
>
</section>
<!-- /无数据提示 结束-->
<article class="i-teacher-list">
<ul class="of">
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="姚晨" target="_blank">
<img src="~/assets/photo/teacher/1442297885942.jpg" alt />
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a
href="/teacher/1"
title="姚晨"
target="_blank"
class="fsize18 c-666"
>姚晨</a
>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999"
>北京师范大学法学院副教授、清华大
学法学博士。自2004年至今已有9年的司法考试培训经验。长期从事司法考试辅导,深知命题规
律,了解解题技巧。内容把握准确,授课重点明确,层次分明,调理清晰,将法条法理与案例有机
融合,强调综合,深入浅出。</span
>
</div>
<div class="mt15 i-q-txt">
<p class="c-999 f-fA">北京师范大学法学院副教授</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="谢娜" target="_blank">
<img src="~/assets/photo/teacher/1442297919077.jpg" alt />
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a
href="/teacher/1"
title="谢娜"
target="_blank"
class="fsize18 c-666"
>谢娜</a
>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999"
>十年课程研发和培训咨询经验,曾任
国企人力资源经理、大型外企培训经理,负责企业大学和培训体系搭建;曾任专业培训机构高级顾
问、研发部总监,为包括广东移动、东莞移动、深圳移动、南方电网、工商银行、农业银行、民生
银行、邮储银行、TCL集团、清华大学继续教育学院、中天路桥、广西扬翔股份等超过200家企业
提供过培训与咨询服务,并担任近50个大型项目的总负责人。</span
>
</div>
<div class="mt15 i-q-txt">
<p class="c-999 f-fA">
资深课程设计专家,专注10年AACTP美国培训 协会认证导师
</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="刘德华" target="_blank">
<img src="~/assets/photo/teacher/1442297927029.jpg" alt />
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a
href="/teacher/1"
title="刘德华"
target="_blank"
class="fsize18 c-666"
>刘德华</a
>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999"
>上海师范大学法学院副教授、清华大
学法学博士。自2004年至今已有9年的司法考试培训经验。长期从事司法考试辅导,深知命题规
律,了解解题技巧。内容把握准确,授课重点明确,层次分明,调理清晰,将法条法理与案例有机
融合,强调综合,深入浅出。</span
>
</div>
<div class="mt15 i-q-txt">
<p class="c-999 f-fA">上海师范大学法学院副教授</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="周润发" target="_blank">
<img src="~/assets/photo/teacher/1442297935589.jpg" alt />
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a
href="/teacher/1"
title="周润发"
target="_blank"
class="fsize18 c-666"
>周润发</a
>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999"
>法学博士,北京师范大学马克思主义
学院副教授,专攻毛泽东思想概论、邓小平理论,长期从事考研辅导。出版著作两部,发表学术论
文30余篇,主持国家社会科学基金项目和教育部重大课题子课题各一项,参与中央实施马克思主
义理论研究和建设工程项目。</span
>
</div>
<div class="mt15 i-q-txt">
<p class="c-999 f-fA">
考研政治辅导实战派专家,全国考研政治命 题研究组核心成员。
</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="钟汉良" target="_blank">
<img src="~/assets/photo/teacher/1442298121626.jpg" alt />
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a
href="/teacher/1"
title="钟汉良"
target="_blank"
class="fsize18 c-666"
>钟汉良</a
>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999"
>具备深厚的数学思维功底、丰富的小
学教育经验,授课风格生动活泼,擅长用形象生动的比喻帮助理解、简单易懂的语言讲解难题,深
受学生喜欢</span
>
</div>
<div class="mt15 i-q-txt">
<p class="c-999 f-fA">
毕业于师范大学数学系,热爱教育事业,执 教数学思维6年有余
</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="唐嫣" target="_blank">
<img src="~/assets/photo/teacher/1442297957332.jpg" alt />
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a
href="/teacher/1"
title="唐嫣"
target="_blank"
class="fsize18 c-666"
>唐嫣</a
>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999"
>中国科学院数学与系统科学研究院应
用数学专业博士,研究方向为数字图像处理,中国工业与应用数学学会会员。参与全国教育科
学“十五”规划重点课题“信息化进程中的教育技术发展研究”的子课题“基与课程改革的资源开发与
应用”,以及全国“十五”科研规划全国重点项目“掌上型信息技术产品在教学中的运用和开发研
究”的子课题“用技术学数学”。</span
>
</div>
<div class="mt15 i-q-txt">
<p class="c-999 f-fA">中国人民大学附属中学数学一级教师</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="周杰伦" target="_blank">
<img src="~/assets/photo/teacher/1442297969808.jpg" alt />
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a
href="/teacher/1"
title="周杰伦"
target="_blank"
class="fsize18 c-666"
>周杰伦</a
>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999"
>中教一级职称。讲课极具亲和 力。</span
>
</div>
<div class="mt15 i-q-txt">
<p class="c-999 f-fA">毕业于北京大学数学系</p>
</div>
</section>
</li>
<li>
<section class="i-teach-wrap">
<div class="i-teach-pic">
<a href="/teacher/1" title="陈伟霆" target="_blank">
<img src="~/assets/photo/teacher/1442297977255.jpg" alt />
</a>
</div>
<div class="mt10 hLh30 txtOf tac">
<a
href="/teacher/1"
title="陈伟霆"
target="_blank"
class="fsize18 c-666"
>陈伟霆</a
>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999"
>政治学博士、管理学博士后,北京师范大学马克思主义学院副教授。多
年来总结出了一套行之有效的应试技巧与答题方法,针对性和实用性极强,能帮助考生在轻松中应
考,在激励的竞争中取得高分,脱颖而出。</span
>
</div>
<div class="mt15 i-q-txt">
<p class="c-999 f-fA">
长期从事考研政治课讲授和考研命题趋势与
应试对策研究。考研辅导新锐派的代表。
</p>
</div>
</section>
</li>
</ul>
<div class="clear"></div>
</article>
</div>
<!-- 公共分页 开始 -->
<div>
<div class="paging">
<!-- undisable这个class是否存在,取决于数据属性hasPrevious -->
<a href="#" title="首页">首</a>
<a href="#" title="前一页"><</a>
<a href="#" title="第1页" class="current undisable">1</a>
<a href="#" title="第2页">2</a>
<a href="#" title="后一页">></a>
<a href="#" title="末页">末</a>
<div class="clear"></div>
</div>
</div>
<!-- 公共分页 结束 -->
</section>
</section>
<!-- /讲师列表 结束 -->
</div>
</template>
<script>
export default {};
</script>
2. 详情页面
pages/teacher/_id.vue
<template>
<div id="aCoursesList" class="bg-fa of">
<!-- 讲师介绍 开始 -->
<section class="container">
<header class="comm-title">
<h2 class="fl tac">
<span class="c-333">讲师介绍</span>
</h2>
</header>
<div class="t-infor-wrap">
<!-- 讲师基本信息 -->
<section class="fl t-infor-box c-desc-content">
<div class="mt20 ml20">
<section class="t-infor-pic">
<img src="~/assets/photo/teacher/1442297885942.jpg" />
</section>
<h3 class="hLh30">
<span class="fsize24 c-333">姚晨 高级讲师</span>
</h3>
<section class="mt10">
<span class="t-tag-bg">北京师范大学法学院副教授</span>
</section>
<section class="t-infor-txt">
<p class="mt20">
北京师范大学法学院副教授、清华大学法学博士。自2004年至今已有9年的司法
考试培训经验。长期从事司法考试辅导,深知命题规律,了解解题技巧。内容把握准确,授课重点
明确,层次分明,调理清晰,将法条法理与案例有机融合,强调综合,深入浅出。
</p>
</section>
<div class="clear"></div>
</div>
</section>
<div class="clear"></div>
</div>
<section class="mt30">
<div>
<header class="comm-title all-teacher-title c-course-content">
<h2 class="fl tac">
<span class="c-333">主讲课程</span>
</h2>
<section class="c-tab-title">
<a href="javascript: void(0)"> </a>
</section>
</header>
<!-- /无数据提示 开始-->
<section class="no-data-wrap">
<em class="icon30 no-data-ico"> </em>
<span class="c-666 fsize14 ml10 vam"
>没有相关数据,小编正在努力整理 中...</span
>
</section>
<!-- /无数据提示 结束-->
<article class="comm-course-list">
<ul class="of">
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img
src="~/assets/photo/course/1442295455437.jpg"
class="img-responsive"
/>
<div class="cc-mask">
<a
href="#"
title="开始学习"
target="_blank"
class="comm- btn c-btn-1"
>开始学习</a
>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a
href="#"
title="零基础入门学习Python课程学习"
target="_blank"
class="course-title fsize18 c-333"
>零基础入门学习Python课程学 习</a
>
</h3>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img
src="~/assets/photo/course/1442295472860.jpg"
class="img-responsive"
/>
<div class="cc-mask">
<a
href="#"
title="开始学习"
target="_blank"
class="comm- btn c-btn-1"
>开始学习</a
>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a
href="#"
title="影想力摄影小课堂"
target="_blank"
class="course-title fsize18 c-333"
>影想力摄影小课堂</a
>
</h3>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img
src="~/assets/photo/course/1442302831779.jpg"
class="img-responsive"
/>
<div class="cc-mask">
<a
href="#"
title="开始学习"
target="_blank"
class="comm- btn c-btn-1"
>开始学习</a
>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a
href="#"
title="数学给宝宝带来的兴趣"
target="_blank"
class="course-title fsize18 c-333"
>数学给宝宝带来的兴趣</a
>
</h3>
</div>
</li>
<li>
<div class="cc-l-wrap">
<section class="course-img">
<img
src="~/assets/photo/course/1442295506745.jpg"
class="img-responsive"
/>
<div class="cc-mask">
<a
href="#"
title="开始学习"
target="_blank"
class="comm- btn c-btn-1"
>开始学习</a
>
</div>
</section>
<h3 class="hLh30 txtOf mt10">
<a
href="#"
title="国家教师资格考试专用"
target="_blank"
class="course-title fsize18 c-333"
>国家教师资格考试专用</a
>
</h3>
</div>
</li>
</ul>
<div class="clear"></div>
</article>
</div>
</section>
</section>
<!-- /讲师介绍 结束 -->
</div>
</template>
<script>
export default {};
</script>
二、讲师列表页
一、后端开发
1. controller层
TeacherFrontController
@RestController
@CrossOrigin
@RequestMapping("/eduservice/teacherfront")
public class TeacherFrontController {
@Autowired
private EduTeacherService teacherService;
// 分页查询讲师的方法
@PostMapping("getTeahcerFrontList/{page}/{limit}")
public R getTeacherFrontList(@PathVariable long page, @PathVariable long limit) {
Page<EduTeacher> pageTeacher = new Page<>(page,limit);
Map<String, Object> map = teacherService.getTeacherFrontList(pageTeacher);
// 返回分页所有数据
return R.ok().data(map);
}
}
2. service层
-
EduTeacherService
// 分页查询讲师的方法 Map<String, Object> getTeacherFrontList(Page<EduTeacher> pageTeacher);
-
EduTeacherServiceImpl
// 分页查询讲师的方法 @Override public Map<String, Object> getTeacherFrontList(Page<EduTeacher> pageTeacher) { QueryWrapper<EduTeacher> wrapper = new QueryWrapper<>(); wrapper.orderByDesc("id"); //把分页数据封装到pageTeacher对象 baseMapper.selectPage(pageTeacher, wrapper); // 把分页数据获取出来,放到map集合 Map<String, Object> map = new HashMap<>(); //总记录数 long total = pageTeacher.getTotal(); //当前页 long current = pageTeacher.getCurrent(); //每页记录数 long size = pageTeacher.getSize(); //查询到的对象 List<EduTeacher> teacherList = pageTeacher.getRecords(); //总页数 long pages = pageTeacher.getPages(); //是否有上一页 boolean hasPrevious = pageTeacher.hasPrevious(); //是否有下一页 boolean hasNext = pageTeacher.hasNext(); //将数据封装到map中返回 map.put("total", total); map.put("current", current); map.put("size", size); map.put("list", teacherList); map.put("hasPrevious", hasPrevious); map.put("hasNext", hasNext); map.put("pages", pages); return map; }
3. swagger测试
二、前端列表js
1. 创建api
创建文件夹api,api下创建teacher.js,用于封装讲师模块的请求
import request from '@/utils/request'
export default{
// 分页讲师查询的方法
getTeacherList(page, limit) {
return request({
url: `/eduservice/teacherfront/getTeahcerFrontList/${page}/${limit}`,
method: 'post'
})
}
}
2. 讲师列表组件中调用api
<script>
import teacherAPI from "@/api/teacher";
export default {
//异步调用,进页面调用,且只会调一次
//params:相当于之前的 this.$route.params.id 等价 params.id
//error:错误信息
asyncData({ params, error }) {
return teacherApi.getTeacherList(1, 8)
.then(response => {
//this.data = response.data.data
return { data: response.data.data }
});
},
};
</script>
三、页面渲染
1. 页面模板
<template>
<div id="aCoursesList" class="bg-fa of">
<!-- 讲师列表 开始 -->
<section class="container">
<section class="c-sort-box unBr">
<div>
<!-- 无数据提示 开始-->
<!-- /无数据提示 结束-->
<!-- 数据列表 开始-->
<!-- /数据列表 结束-->
</div>
<!-- 公共分页 开始 -->
<!-- /公共分页 结束 -->
</section>
</section>
<!-- /讲师列表 结束 -->
</div>
</template>
2. 无数据提示
添加: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>
<!-- /无数据提示 结束-->
3. 列表
<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/1" :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" class="fsize18 c-666">{{ item.name }}</a>
</div>
<div class="hLh30 txtOf tac">
<span class="fsize14 c-999" >{{ item.career }}</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>
4. 测试
四、分页
1. 分页方法
methods: {
// 分页切换的方法
//参数是页码数
gotoPage(page) {
teacherApi.getTeacherList(page, 8)
.then(response => {
this.data = response.data.data
})
}
}
2. 分页页面渲染
<!-- 公共分页 开始 -->
<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>
<!-- 公共分页 结束 -->
3. 测试
三、讲师详情页
一、后端开发
1. controller层
TeacherFrontController
@RestController
@CrossOrigin
@RequestMapping("/eduservice/teacherfront")
public class TeacherFrontController {
@Autowired
private EduTeacherService teacherService;
@Autowired
private EduCourseService courseService;
// 根据id查询讲师信息(讲师本身信息 + 讲师所讲课程信息)
@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测试
二、前端开发
1. 定义api
api/teacher.js
:
// 讲师详情的方法
getTeacherInfo(id) {
return request({
url: `/eduservice/teacherfront/getTeacherFrontInfo/${id}`,
method: 'get'
})
}
2. 讲师详情页中调用api
pages/teacher/_id.vue
:
import teacherApi from '@/api/teacher'
export default {
asyncData({ params, error }) {
return teacherApi.getTeacherInfo(params.id)
.then(response => {
// console.log(response)
return {
teacher: response.data.data.teacher,
courseList: response.data.data.courseList
}
})
}
}
</script>
三、页面渲染
1. 讲师基本信息模板
<template>
<div id="aCoursesList" class="bg-fa of">
<!-- 讲师介绍 开始 -->
<section class="container">
<header class="comm-title">
<h2 class="fl tac">
<span class="c-333">讲师介绍</span>
</h2>
</header>
<div class="t-infor-wrap">
<!-- 讲师基本信息 -->
<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">{{teacher.name}}
{{teacher.level ===1?'高级讲师':'首席讲师'}}
</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>
<div class="clear"></div>
</div>
<section class="mt30">
<div>
<header class="comm-title all-teacher-title c-course-content">
<h2 class="fl tac">
<span class="c-333">主讲课程</span>
</h2>
<section class="c-tab-title">
<a href="javascript: void(0)"> </a>
</section>
</header>
<!-- /无数据提示 开始-->
<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>
<!-- /无数据提示 结束-->
<article class="comm-course-list">
<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>
</div>
</section>
</section>
<!-- /讲师介绍 结束 -->
</div>
</template>
2. 讲师详情显示
<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">{{teacher.name}}
{{teacher.level ===1?'高级讲师':'首席讲师'}}
</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>
3. 无数据提示
<!-- /无数据提示 开始-->
<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>
<!-- /无数据提示 结束-->
4. 当前讲师课程列表
<!-- 课程列表 开始-->
<article class="comm-course-list">
<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>
5. 测试
-
讲师列表
-
有课程
-
没有课程
首页课程功能
课程列表页面
一、后端接口开发
1. 实体类
创建 frontvo
包,在改包下创建 CourseFrontVo
实体类:
@Data
public class CourseFrontVo {
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层
CourseFrontController
@RestController
@CrossOrigin
@RequestMapping("/eduservice/coursefront")
public class CourseFrontController {
@Autowired
private EduCourseService courseService;
// 条件查询带分页查询课程
@PostMapping("getFrontCourseList/{page}/{limit}")
public R getFrontCourseList(@PathVariable long page, @PathVariable long limit,
@RequestBody(required = false) CourseFrontVo courseFrontVo) {
Page<EduCourse> pageCourse = new Page<>(page, limit);
Map<String, Object> map = courseService.getCourseFrontList(pageCourse, courseFrontVo);
// 返回分页所有数据
return R.ok().data(map);
}
}
3. service层
EduCourseService
:
// 条件查询带分页查询课程
Map<String, Object> getCourseFrontList(Page<EduCourse> pageCourse, CourseFrontVo courseFrontVo);
EduCourseServiceImpl
:
// 条件查询带分页查询课程
@Override
public Map<String, Object> getCourseFrontList(Page<EduCourse> pageParam, CourseFrontVo courseFrontVo) {
QueryWrapper<EduCourse> wrapper = new QueryWrapper<>();
// 判断条件值是否为空,不为空则拼接
if (!StringUtils.isEmpty(courseFrontVo.getSubjectParentId())) { //一级分类
wrapper.eq("subject_parent_id", courseFrontVo.getSubjectId());
}
if (!StringUtils.isEmpty(courseFrontVo.getSubjectId())) { //二级分类
wrapper.eq("subject_id", courseFrontVo.getSubjectId());
}
if (!StringUtils.isEmpty(courseFrontVo.getBuyCountSort())) { //关注度
wrapper.orderByDesc("buy_count");
}
if (!StringUtils.isEmpty(courseFrontVo.getGmtCreateSort())) { //最新,创建时间
wrapper.orderByDesc("gmt_create");
}
if (!StringUtils.isEmpty(courseFrontVo.getPriceSort())) { //价格
wrapper.orderByDesc("price");
}
baseMapper.selectPage(pageParam, wrapper);
// 把分页数据获取出来,放到map集合
Map<String, Object> map = new HashMap<>();
//总记录数
long total = pageParam.getTotal();
//当前页
long current = pageParam.getCurrent();
//每页记录数
long size = pageParam.getSize();
//查询到的对象
List<EduCourse> records = pageParam.getRecords();
//总页数
long pages = pageParam.getPages();
//是否有上一页
boolean hasPrevious = pageParam.hasPrevious();
//是否有下一页
boolean hasNext = pageParam.hasNext();
//将数据封装到map中返回
map.put("total", total);
map.put("current", current);
map.put("size", size);
map.put("items", records);
map.put("hasPrevious", hasPrevious);
map.put("hasNext", hasNext);
map.put("pages", pages);
return map;
}
二、课程列表前端
1. 定义api
api/course.js
import request from '@/utils/request'
export default{
// 条件分页课程查询的方法
getCourseList(page, limit, searchObj) {
return request({
url: `/eduservice/coursefront/getFrontCourseList/${page}/${limit}`,
method: 'post',
data: searchObj
})
},
// 查询所有分类的方法
getAllSubject() {
return request({
url: `/eduservice/subject/getAllSubject`,
method: 'get'
})
}
}
2. 页面调用接口
pages/course/index.vue
<script>
import courseApi from '@/api/course'
export default {
data() {
return {
page:1, //当前页
data:{}, //课程列表
subjectNestedList: [], // 一级分类列表
subSubjectList: [], // 二级分类列表
searchObj: {}, // 查询表单对象
oneIndex:-1,
twoIndex:-1,
buyCountSort:"",
gmtCreateSort:"",
priceSort:""
}
},
created() {
//课程第一次查询
this.initCourseFirst()
//一级分类显示
this.initSubject()
},
methods:{
//1 查询第一页数据
initCourseFirst() {
courseApi.getCourseList(1,8,this.searchObj).then(response => {
this.data = response.data.data
})
},
//2 查询所有一级分类
initSubject() {
courseApi.getAllSubject()
.then(response => {
this.subjectNestedList = response.data.data.list
})
},
//3 分页切换的方法
gotoPage(page) {
courseApi.getCourseList(page,8,this.searchObj).then(response => {
this.data = response.data.data
})
},
//4 点击某个一级分类,查询对应二级分类
searchOne(subjectParentId,index) {
//把传递index值赋值给oneIndex,为了active样式生效
this.oneIndex = index
this.twoIndex = -1
this.searchObj.subjectId = ""
this.subSubjectList = []
//把一级分类点击id值,赋值给searchObj
this.searchObj.subjectParentId = subjectParentId
//点击某个一级分类进行条件查询
this.gotoPage(1)
//拿着点击一级分类id 和 所有一级分类id进行比较,
//如果id相同,从一级分类里面获取对应的二级分类
for(let i=0;i<this.subjectNestedList.length;i++) {
//获取每个一级分类
var oneSubject = this.subjectNestedList[i]
//比较id是否相同
if(subjectParentId == oneSubject.id) {
//从一级分类里面获取对应的二级分类
this.subSubjectList = oneSubject.children
}
}
},
//5 点击某个二级分类实现查询
searchTwo(subjectId, index) {
//把index赋值,为了样式生效
this.twoIndex = index
//把二级分类点击id值,赋值给searchObj
this.searchObj.subjectId = subjectId
//点击某个二级分类进行条件查询
this.gotoPage(1)
},
//6 根据销量排序
searchBuyCount() {
//设置对应变量值,为了样式生效
this.buyCountSort = "1"
this.gmtCreateSort = ""
this.priceSort = ""
//把值赋值到searchObj
this.searchObj.buyCountSort = this.buyCountSort
this.searchObj.gmtCreateSort = this.gmtCreateSort
this.searchObj.priceSort = this.priceSort
//调用方法查询
this.gotoPage(1)
},
//7 最新排序
searchGmtCreate() {
//设置对应变量值,为了样式生效
this.buyCountSort = ""
this.gmtCreateSort = "1"
this.priceSort = ""
//把值赋值到searchObj
this.searchObj.buyCountSort = this.buyCountSort
this.searchObj.gmtCreateSort = this.gmtCreateSort;
this.searchObj.priceSort = this.priceSort;
//调用方法查询
this.gotoPage(1)
},
//8 价格排序
searchPrice() {
//设置对应变量值,为了样式生效
this.buyCountSort = ""
this.gmtCreateSort = ""
this.priceSort = "1"
//把值赋值到searchObj
this.searchObj.buyCountSort = this.buyCountSort
this.searchObj.gmtCreateSort = this.gmtCreateSort;
this.searchObj.priceSort = this.priceSort;
//调用方法查询
this.gotoPage(1)
},
}
};
</script>
<style scoped>
.active {
background: #bdbdbd;
}
.hide {
display: none;
}
.show {
display: block;
}
</style>
3. 前端页面
<template>
<div id="aCoursesList" class="bg-fa of">
<!-- /课程列表 开始 -->
<section class="container">
<header class="comm-title">
<h2 class="fl tac">
<span class="c-333">全部课程</span>
</h2>
</header>
<section class="c-sort-box">
<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="#" >全部</a>
</li>
<li v-for="(item,index) in subjectNestedList" :key="index" :class="{active:oneIndex==index}">
<a :title="item.title" href="#" @click="searchOne(item.id,index)">{{item.title}}</a>
</li>
</ul>
</dd>
</dl>
<dl>
<dt>
<span class="c-999 fsize14"></span>
</dt>
<dd class="c-s-dl-li">
<ul class="clearfix">
<li v-for="(item,index) in subSubjectList" :key="index" :class="{active:twoIndex==index}">
<a :title="item.title" href="#" @click="searchTwo(item.id,index)">{{item.title}}</a>
</li>
</ul>
</dd>
</dl>
<div class="clear"></div>
</section>
<div class="js-wrap">
<section class="fr">
<span class="c-ccc">
<i class="c-master f-fM">1</i>/
<i class="c-666 f-fM">1</i>
</span>
</section>
<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>
</div>
<div class="mt40">
<!-- /无数据提示 开始-->
<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 v-if="data.total>0" class="comm-course-list">
<ul class="of" id="bna">
<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="item.title">
<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">9634人学习</i>
|
<i class="c-999 f-fA">9634评论</i>
</span>
</section>
</div>
</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)">首</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>
4. 测试
课程详情页
一、后端开发
1. 实体类
CourseWebVo
@Data
public class CourseWebVo {
private static final long serialVersionUID = 1L;
private String id;
@ApiModelProperty(value = "课程标题")
private String title;
@ApiModelProperty(value = "课程销售价格,设置为0则可免费观看")
private BigDecimal price;
@ApiModelProperty(value = "总课时")
private Integer lessonNum;
@ApiModelProperty(value = "课程封面图片路径")
private String cover;
@ApiModelProperty(value = "销售数量")
private Long buyCount;
@ApiModelProperty(value = "浏览数量")
private Long viewCount;
@ApiModelProperty(value = "课程简介")
private String description;
@ApiModelProperty(value = "讲师ID")
private String teacherId;
@ApiModelProperty(value = "讲师姓名")
private String teacherName;
@ApiModelProperty(value = "讲师资历,一句话说明讲师")
private String intro;
@ApiModelProperty(value = "讲师头像")
private String avatar;
@ApiModelProperty(value = "课程类别ID")
private String subjectLevelOneId;
@ApiModelProperty(value = "类别名称")
private String subjectLevelOne;
@ApiModelProperty(value = "课程类别ID")
private String subjectLevelTwoId;
@ApiModelProperty(value = "类别名称")
private String subjectLevelTwo;
}
2. controller层
CourseFrontController
//课程详情的方法
@GetMapping("getFrontCourseInfo/{courseId}")
public R getFrontCourseInfo(@PathVariable String courseId) {
//根据课程id,编写sql语句查询课程信息
CourseWebVo courseWebVo = courseService.getBaseCourseInfo(courseId);
//根据课程id查询章节和小节
List<ChapterVo> chapterVoList = chapterService.getChapterVideoByCourseId(courseId);
return R.ok().data("courseWebVo",courseWebVo).data("chapterVoList",chapterVoList);
}
3. service层
-
EduCourseService
//根据课程id,编写sql语句查询课程信息 CourseWebVo getBaseCourseInfo(String courseId);
-
EduCourseServiceImpl
//根据课程id,编写sql语句查询课程信息 @Override public CourseWebVo getBaseCourseInfo(String courseId) { return baseMapper.getBaseCourseInfo(courseId); }
4. dao层
@Mapper
public interface EduCourseMapper extends BaseMapper<EduCourse> {
public CoursePublishVo getPublishCourseInfo(String courseId);
//根据课程id,编写sql语句查询课程信息
CourseWebVo getBaseCourseInfo(String courseId);
}
EduCourseMapper.xml
:
<!--前台根据课程id,查询课程基础信息-->
<select id="getBaseCourseInfo" resultType="com.atguigu.eduservice.entity.frontvo.CourseWebVo">
SELECT
ec.id,
ec.title,
ec.cover,
ec.lesson_num AS lessonNum,
ec.price,
ec.cover,
ec.buy_count as buyCount,
ec.view_count as viewCount,
esd.description,
s1.title AS subjectLevelOne,
s1.id as subjectLevelOneId,
s2.id as subjectLevelTwoId,
s2.title AS subjectLevelTwo,
t.name AS teacherName,
t.id as teacherId,
t.avatar,
t.intro
FROM
edu_course ec
LEFT JOIN edu_teacher t ON ec.teacher_id = t.id
LEFT JOIN edu_subject s1 ON ec.subject_parent_id = s1.id
LEFT JOIN edu_subject s2 ON ec.id = s2.id
left join edu_course_description esd on ec.id = esd.id
WHERE
ec.id = #{id}
</select>
5. 测试
二、前端开发
1. 定义api
api/course.js
//课程详情的方法
getCourseInfo(courseId) {
return request({
url: `/eduservice/coursefront/getFrontCourseInfo/${courseId}`,
method: 'get'
})
}
2. 页面调用接口
pages/course/_id.vue
<script>
import courseApi from "@/api/course"
export default {
asyncData({ params, error }) {
return courseApi.getCourseInfo(params.id).then(response => {
return {
courseWebVo: response.data.data.courseWebVo,
chapterVideoList: response.data.data.chapterVideoList
}
})
}
};
</script>
3. 前端页面
<template>
<div id="aCoursesList" class="bg-fa of">
<!-- /课程详情 开始 -->
<section class="container">
<section class="path-wrap txtOf hLh30">
<a href="#" title class="c-999 fsize14">首页</a>
\
<a href="/course" title class="c-999 fsize14">{{courseWebVo.subjectLevelOne}}</a>
\
<span class="c-333 fsize14">{{ courseWebVo.subjectLevelTwo}}</span>
</section>
<div>
<article class="c-v-pic-wrap" style="height: 357px">
<section class="p-h-video-box" id="videoPlay">
<img
:src="courseWebVo.cover"
:alt="courseWebVo.title"
class="dis c-v-pic"
height="355px"
width="630px"
/>
</section>
</article>
<aside class="c-attr-wrap">
<section class="ml20 mr15">
<h2 class="hLh30 txtOf mt15">
<span class="c-fff fsize24">{{ courseWebVo.title }}</span>
</h2>
<section class="c-attr-jg">
<span class="c-fff">价格:</span>
<b class="c-yellow" style="font-size: 24px">¥{{ courseWebVo.price }}</b>
</section>
<section class="c-attr-mt c-attr-undis">
<span class="c-fff fsize14">主讲: {{ courseWebVo.teacherName }} </span>
</section>
<section class="c-attr-mt of">
<span class="ml10 vam">
<em class="icon18 scIcon"></em>
<a class="c-fff vam" title="收藏" href="#">收藏</a>
</span>
</section>
<section class="c-attr-mt">
<a href="#" title="立即观看" class="comm-btn c-btn-3"
>立即观 看</a
>
</section>
</section>
</aside>
<aside class="thr-attr-box">
<ol class="thr-attr-ol clearfix">
<li>
<p> </p>
<aside>
<span class="c-fff f-fM">购买数</span>
<br />
<h6 class="c-fff f-fM mt10">{{ courseWebVo.buyCount }}</h6>
</aside>
</li>
<li>
<p> </p>
<aside>
<span class="c-fff f-fM">课时数</span>
<br />
<h6 class="c-fff f-fM mt10">{{ courseWebVo.lessonNum }}</h6>
</aside>
</li>
<li>
<p> </p>
<aside>
<span class="c-fff f-fM">浏览数</span>
<br />
<h6 class="c-fff f-fM mt10">{{ courseWebVo.viewCount }}</h6>
</aside>
</li>
</ol>
</aside>
<div class="clear"></div>
</div>
<!-- /课程封面介绍 -->
<div class="mt20 c-infor-box">
<article class="fl col-7">
<section class="mr30">
<div class="i-box">
<div>
<section
id="c-i-tabTitle"
class="c-infor-tabTitle c-tab- title"
>
<a name="c-i" class="current" title="课程详情">课程详情</a>
</section>
</div>
<article class="ml10 mr10 pt20">
<div>
<h6 class="c-i-content c-infor-title">
<span>课程介绍</span>
</h6>
<div class="course-txt-body-wrap">
<section class="course-txt-body">
<!-- 将内容中的html翻译过来 -->
<p v-html="courseWebVo.description">{{ courseWebVo.description }}</p>
</section>
</div>
</div>
<!-- /课程介绍 -->
<div class="mt50">
<h6 class="c-g-content c-infor-title">
<span>课程大纲</span>
</h6>
<section class="mt20">
<div class="lh-menu-wrap">
<menu id="lh-menu" class="lh-menu mt10 mr10">
<ul>
<!-- 文件目录 -->
<!-- 课程章节目录 -->
<li v-for="chapter in chapterVideoList" :key="chapter.id" class="lh-menu-stair">
<a :title="chapter.title" href="javascript: void(0)" class="current-1">
<em class="lh-menu-i-1 icon18 mr10"/>{{ chapter.title }}
</a>
<ol class="lh-menu-ol" style="display: block;">
<li v-for="video in chapter.children" :key="video.id" class="lh-menu-second ml30">
<a href="#" title>
<span v-if="video.free === true" class="fr">
<i class="free-icon vam mr10">免费试听</i>
</span>
<em class="lh-menu-i-2 icon16 mr5"> </em>{{ video.title }}
</a>
</li>
</ol>
</li>
</ul>
</menu>
</div>
</section>
</div>
<!-- /课程大纲 -->
</article>
</div>
</section>
</article>
<aside class="fl col-3">
<div class="i-box">
<div>
<section class="c-infor-tabTitle c-tab-title">
<a title href="javascript:void(0)">主讲讲师</a>
</section>
<section class="stud-act-list">
<ul style="height: auto">
<li>
<div class="u-face">
<a href="#">
<img
:src="courseWebVo.avatar"
width="50"
height="50"
alt
/>
</a>
</div>
<section class="hLh30 txtOf">
<a class="c-333 fsize16 fl" href="#">{{courseWebVo.teacherName}}</a>
</section>
<section class="hLh20 txtOf">
<span class="c-999">{{courseWebVo.intro}}</span>
</section>
</li>
</ul>
</section>
</div>
</div>
</aside>
<div class="clear"></div>
</div>
</section>
<!-- /课程详情 结束 -->
</div>
</template>
4. 测试
视频播放测试
参考文档:https://help.aliyun.com/document_detail/61109.htmlspm=a2c4g.11186623.6.975.9ea624d8CwyqYN
1. 视频播放器介绍
阿里云播放器SDK(ApsaraVideo Player SDK)是阿里视频服务的重要一环,除了支持点播和直播的基础播放功能外,深度融合视频云业务,如支持视频的加密播放、安全下载、清晰度切换、直播答题等业务场景,为用户提供简单、快速、安全、稳定的视频播放服务。
2. 集成视频播放器
参考文档:https://help.aliyun.com/document_detail/51991.html
参考 【播放器简单使用说明】一节
-
引入脚本文件和css文件
<link rel="stylesheet" href="https://g.alicdn.com/de/prismplayer/2.8.1/skins/default/aliplayer-min.css" /> <script charset="utf-8" type="text/javascript" src="https://g.alicdn.com/de/prismplayer/2.8.1/aliplayer-min.js"></script>
-
初始化视频播放器
<body> <div class="prism-player" id="J_prismPlayer"></div> <script> var player = new Aliplayer({ id: 'J_prismPlayer', width: '100%', autoplay: false, cover: 'http://liveroom-img.oss-cn-qingdao.aliyuncs.com/logo.png', //播放配置 },function(player){ console.log('播放器创建好了。') }); </script> </body>
3. 播放地址播放
在Aliplayer的配置参数中添加如下属性:
//播放方式一:支持播放地址播放,此播放优先级最高,此种方式不能播放加密视频
source : '你的视频播放地址',
启动浏览器运行,测试视频的播放。
4. 播放凭证播放(推荐)
阿里云播放器支持通过播放凭证自动换取播放地址进行播放,接入方式更为简单,且安全性更高。播放凭证默认时效为100秒(最大为3000秒),只能用于获取指定视频的播放地址,不能混用或重复使用。如果凭证过期则无法获取播放地址,需要重新获取凭证。
encryptType:'1',//如果播放加密视频,则需设置encryptType=1,非加密视频无需设置此项
vid : '视频id',
playauth : '视频授权码',
注意:播放凭证有过期时间,默认值:100秒 。取值范围:100~3000。
设置播放凭证的有效期。
在获取播放凭证的测试用例中添加如下代码。
request.setAuthInfoTimeout(200L);
在线配置参考:https://player.alicdn.com/aliplayer/setting/setting.htmlspm=a2c4g.11186623.2.16.242c6782Kdc4Za
整合阿里云视频播放器
一、后端获取播放凭证
1. controller层
VodController
//根据视频id获取视频凭证
@GetMapping("/getPlayAuth/{id}")
public R getPlayAuth(@PathVariable String id){
try {
//初始化
DefaultAcsClient client = InitVodClient.initVodClient(ConstantVodUtils.ACCESS_KEY_ID, ConstantVodUtils.ACCESS_KEY_SECRET);
//请求
GetVideoPlayAuthRequest request = new GetVideoPlayAuthRequest();
request.setVideoId(id);
//响应
GetVideoPlayAuthResponse response = client.getAcsResponse(request);
//得到播放凭证
String playAuth = response.getPlayAuth();
return R.ok().data("playAuth", playAuth);
} catch (Exception e) {
throw new GuliException(20001,"获取视频凭证失败");
}
}
2. Swagger测试
二、前端播放器整合
1. 点击播放超链接
course/_id.vue
<a :href="'/player/'+video.videoSourceId" :title="video.title" target="_blank">
2. 定义api
api/vod.js
import request from '@/utils/request'
export default{
//根据视频id,获取视频凭证
getPlayAuthById(id){
return request({
url:`/eduvod/video/getPlayAuth/${id}`,
method: 'get'
})
}
}
3. 页面
<template>
<div>
<!-- 阿里云视频播放器样式 -->
<link
rel="stylesheet"
href="https://g.alicdn.com/de/prismplayer/2.8.1/skins/default/aliplayer-min.css"
/>
<!-- 阿里云视频播放器脚本 -->
<script
charset="utf-8"
type="text/javascript"
src="https://g.alicdn.com/de/prismplayer/2.8.1/aliplayer-min.js"
/>
<!-- 定义播放器dom -->
<div id="J_prismPlayer" class="prism-player" />
</div>
</template>
<script>
import vod from "@/api/vod"
export default {
layout: "video", //应用video布局
asyncData({ params, error }) {
return vod.getPlayAuthById(params.vid).then((response) => {
return {
playAuth: response.data.data.playAuth,
vid: params.vid
}
})
},
mounted() {
//页面渲染之后 created
new Aliplayer(
{
id: "J_prismPlayer",
vid: this.vid, // 视频id
playauth: this.playAuth, // 播放凭证
encryptType: "1", // 如果播放加密视频,则需设置encryptType=1,非加密视频无需设置此项
width: "100%",
height: "500px",
// 以下可选设置
cover: "http://guli.shop/photo/banner/1525939573202.jpg", // 封面
qualitySort: "asc", // 清晰度排序
mediaType: "video", // 返回音频还是视频
autoplay: false, // 自动播放
isLive: false, // 直播
rePlay: false, // 循环播放
preload: true,
controlBarVisibility: "hover", // 控制条的显示方式:鼠标悬停
useH5Prism: true, // 播放器类型:html5
},function (player) {
console.log("播放器创建成功");
}
)
}
}
</script>
<style>
html,body{
height:100%;
}
</style>
<style scoped>
.head {
height: 50px;
position: absolute;
top: 0;
left: 0;
width: 100%;
}
.head .logo{
height: 50px;
margin-left: 10px;
}
.body {
position: absolute;
top: 50px;
left: 0;
right: 0;
bottom: 0;
overflow: hidden;
}
</style>
4. 测试
创作不易,如果有帮助到你,请给文章点个赞和收藏,让更多的人看到!!!
关注博主不迷路,内容持续更新中。