一、vo对象的定义

在项目中很多时候需要把model转换成dto用于网站信息的展示,按前端的需要传递对象的数据,保证model对外是隐私的,例如密码之类的属性能很好地避免暴露在外,同时也会减小数据传输的体积。
CourseWebVo.java

  1. package com.guli.edu.vo;
  2. @ApiModel(value="课程信息", description="网站课程详情页需要的相关字段")
  3. @Data
  4. public class CourseWebVo implements Serializable {
  5. private static final long serialVersionUID = 1L;
  6. private String id;
  7. @ApiModelProperty(value = "课程标题")
  8. private String title;
  9. @ApiModelProperty(value = "课程销售价格,设置为0则可免费观看")
  10. private BigDecimal price;
  11. @ApiModelProperty(value = "总课时")
  12. private Integer lessonNum;
  13. @ApiModelProperty(value = "课程封面图片路径")
  14. private String cover;
  15. @ApiModelProperty(value = "销售数量")
  16. private Long buyCount;
  17. @ApiModelProperty(value = "浏览数量")
  18. private Long viewCount;
  19. @ApiModelProperty(value = "课程简介")
  20. private String description;
  21. @ApiModelProperty(value = "讲师ID")
  22. private String teacherId;
  23. @ApiModelProperty(value = "讲师姓名")
  24. private String teacherName;
  25. @ApiModelProperty(value = "讲师资历,一句话说明讲师")
  26. private String intro;
  27. @ApiModelProperty(value = "讲师头像")
  28. private String avatar;
  29. @ApiModelProperty(value = "课程类别ID")
  30. private String subjectLevelOneId;
  31. @ApiModelProperty(value = "类别名称")
  32. private String subjectLevelOne;
  33. @ApiModelProperty(value = "课程类别ID")
  34. private String subjectLevelTwoId;
  35. @ApiModelProperty(value = "类别名称")
  36. private String subjectLevelTwo;
  37. }

二、课程和讲师信息的获取

1、Mapper中关联查询课程和讲师信息

CourseMapper.java

  1. CourseWebVo selectInfoWebById(String courseId);

CourseMapper.xml

  1. <select id="selectInfoWebById" resultType="com.guli.edu.vo.CourseWebVo">
  2. SELECT
  3. c.id,
  4. c.title,
  5. c.cover,
  6. CONVERT(c.price, DECIMAL(8,2)) AS price,
  7. c.lesson_num AS lessonNum,
  8. c.cover,
  9. c.buy_count AS buyCount,
  10. c.view_count AS viewCount,
  11. cd.description,
  12. t.id AS teacherId,
  13. t.name AS teacherName,
  14. t.intro,
  15. t.avatar,
  16. s1.id AS subjectLevelOneId,
  17. s1.title AS subjectLevelOne,
  18. s2.id AS subjectLevelTwoId,
  19. s2.title AS subjectLevelTwo
  20. FROM
  21. edu_course c
  22. LEFT JOIN edu_course_description cd ON c.id = cd.id
  23. LEFT JOIN edu_teacher t ON c.teacher_id = t.id
  24. LEFT JOIN edu_subject s1 ON c.subject_parent_id = s1.id
  25. LEFT JOIN edu_subject s2 ON c.subject_id = s2.id
  26. WHERE
  27. c.id = #{id}
  28. </select>

2、业务层获取数据并更新浏览量

CourseService
接口

/**
     * 获取课程信息
     * @param id
     * @return
     */
CourseWebVo selectInfoWebById(String id);
/**
     * 更新课程浏览数
     * @param id
     */

void updatePageViewCount(String id);

实现

@Override
public CourseWebVo selectInfoWebById(String id) {
    this.updatePageViewCount(id);
    return baseMapper.selectInfoWebById(id);
}

@Override
public void updatePageViewCount(String id) {
    Course course = baseMapper.selectById(id);
    course.setViewCount(course.getViewCount() + 1);
    baseMapper.updateById(course);

}

3、接口层

CourseController

@Autowired
private ChapterService chapterService;

@ApiOperation(value = "根据ID查询课程")
@GetMapping(value = "{courseId}")
public R getById(
    @ApiParam(name = "courseId", value = "课程ID", required = true)
    @PathVariable String courseId){


    //查询课程信息和讲师信息
    CourseWebVo courseWebVo = courseService.selectInfoWebById(courseId);


    //查询当前课程的章节信息
    List<ChapterVo> chapterVoList = chapterService.nestedList(courseId);


    return R.ok().data("course", courseWebVo).data("chapterVoList", chapterVoList);

}

4、swagger测试

三、前端js

1、api/course.js

getById(courseId) {
    return request({
        url: `${api_name}/${courseId}`,
        method: 'get'
    })

}

2、pages/course/_id.vue

<script>
import course from "@/api/course"

export default {
  asyncData({ params, error }) {
    return course.getById(params.id).then(response => {
      console.log(response);
      return { 
        course: response.data.data.course,
        chapterList: response.data.data.chapterVoList
      }
    })
  }

}
</script>

四、页面模板

pages/course/_id.vue

1、template

<template>
  <div id="aCoursesList" class="bg-fa of">
    <!-- 课程详情 开始 -->
    <section class="container">


      <!-- 课程所属分类 开始 -->


      <!-- /课程所属分类 结束 -->


      <!-- 课程基本信息 开始 -->


      <!-- /课程基本信息 结束 -->


      <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">


                <!-- 课程详情介绍 开始 -->


                <!-- /课程详情介绍 结束 -->


                <!-- 课程大纲 开始-->


                <!-- /课程大纲 结束 -->
              </article>
            </div>
          </section>
        </article>
        <aside class="fl col-3">
          <div class="i-box">
            <!-- 主讲讲师 开始-->


            <!-- /主讲讲师 结束 -->
          </div>
        </aside>
        <div class="clear"/>
      </div>
    </section>
    <!-- /课程详情 结束 -->
  </div>

</template>

2、课程所属分类

<!-- 课程所属分类 开始 -->
<section class="path-wrap txtOf hLh30">
    <a href="#" title class="c-999 fsize14">首页</a>
    \
    <a href="/course" title class="c-999 fsize14">课程列表</a>
    \
    <span class="c-333 fsize14">{{ course.subjectLevelOne }}</span>
    \
    <span class="c-333 fsize14">{{ course.subjectLevelTwo }}</span>

</section>
<!-- /课程所属分类 结束 -->

3、课程基本信息

<!-- 课程基本信息 开始 -->
<div>
    <article class="c-v-pic-wrap" style="height: 357px;">
        <section id="videoPlay" class="p-h-video-box">
            <img :src="course.cover" :alt="course.title" class="dis c-v-pic">
        </section>
    </article>
    <aside class="c-attr-wrap">
        <section class="ml20 mr15">
            <h2 class="hLh30 txtOf mt15">
                <span class="c-fff fsize24">{{ course.title }}</span>
            </h2>
            <section class="c-attr-jg">
                <span class="c-fff">价格:</span>
                <b class="c-yellow" style="font-size:24px;">¥{{ course.price }}</b>
            </section>
            <section class="c-attr-mt c-attr-undis">
                <span class="c-fff fsize14">主讲: {{ course.teacherName }}&nbsp;&nbsp;&nbsp;</span>
            </section>
            <section class="c-attr-mt of">
                <span class="ml10 vam">
                    <em class="icon18 scIcon"/>
                    <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>&nbsp;</p>
                <aside>
                    <span class="c-fff f-fM">购买数</span>
                    <br>
                    <h6 class="c-fff f-fM mt10">{{ course.buyCount }}</h6>
                </aside>
            </li>
            <li>
                <p>&nbsp;</p>
                <aside>
                    <span class="c-fff f-fM">课时数</span>
                    <br>
                    <h6 class="c-fff f-fM mt10">{{ course.lessonNum }}</h6>
                </aside>
            </li>
            <li>
                <p>&nbsp;</p>
                <aside>
                    <span class="c-fff f-fM">浏览数</span>
                    <br>
                    <h6 class="c-fff f-fM mt10">{{ course.viewCount }}</h6>
                </aside>
            </li>
        </ol>
    </aside>
    <div class="clear"/>

</div>
<!-- /课程基本信息 结束 -->

4、课程详情介绍

<!-- 课程详情介绍 开始 -->
<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="course.description">{{ course.description }}</p>
        </section>
    </div>

</div>
<!-- /课程详情介绍 结束 -->

5、课程大纲

<!-- 课程大纲 开始-->
<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 chapterList" :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">&nbsp;</em>{{ video.title }}
                                </a>
                            </li>
                        </ol>
                    </li>
                </ul>
            </menu>
        </div>
    </section>

    <!-- /课程大纲 结束 -->

6、主讲讲师

<!-- 主讲讲师 开始-->
<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="'/teacher/'+course.teacherId" target="_blank">
                        <img :src="course.avatar" width="50" height="50" alt>
                    </a>
                </div>
                <section class="hLh30 txtOf">
                    <a :href="'/teacher/'+course.teacherId" class="c-333 fsize16 fl" target="_blank">{{ course.teacherName }}</a>
                </section>
                <section class="hLh20 txtOf">
                    <span class="c-999">{{ course.intro }}</span>
                </section>
            </li>
        </ul>
    </section>

</div>
<!-- /主讲讲师 结束 -->