前端项目开发

1. 首页显示全部课程

 

<template>
  <div>
    <Header></Header>
    <div
      style="width: 850PX;display: inline-block; margin:0px auto;">
      <el-tabs v-model="activeName">
        <el-tab-pane label="选课" name="allLesson">
          <ul class="course-ul-pc">
            <!-- 课程信息展示开始 -->
            <li class="course-li"  v-for="(course,index) in courseList" :key="index">
              <!-- 课程封面图 -->
              <img
                src="course.courseImgUrl"
                class="teacher-portrait hover-pointer"
              />
              <!-- 课程文字信息 -->
              <div class="content-main">
                <!-- 课程标题 -->
                <div class="content-title hover-pointer">
                  <div
                    class="p-title"
                    style="text-align:left;"
                    @click="gotoDetail"
                  >
                    <span>
                     {{course.courseName}}
                    </span>
                  </div>
                  <!-- 作者和职称 -->
                  <p class="p-title-buy text-overflow">
                    <span class="p-author-span">
                      {{course.teacher.teacherName}}
                    </span>
                    <span class="p-author-line" />
                    <span class="p-author-span">
                       {{course.teacher.position}}
                    </span>
                  </p>
                  <p></p>
                  <!-- 课程简单描述 -->
                  <p class="p-describe" style="text-align:left;">
                    {{course.brief}}
                  </p>
                </div>
                <!-- 课程前两个章节信息 -->
                <ul class="content-course" style="text-align:left;">
                  <!-- 章节1 通常是第一章的前两节课-->
                  <li
                    class="content-course-lesson text-overflow"
                    style="width:300px" 
                    v-for="(lesson,index) in course.courseSections[0].courseLessons.slice(0,2)"
                    :key="index"
                  >
                    <!-- 免费试看图标 -->
                    <img
                      src="@/assets/course-list/free-course.png"
                      class="free-label hover-pointer"
                    />
                    <span class="theme-span hover-pointer">
                      {{lesson.theme}}
                      </span>
                  </li>
                </ul>
                <!-- 价格信息 -->
                <div class="content-price" style="text-align:left;">
                  <p class="content-price-p">
                    <span class="content-price-orange-sm">¥</span>
                    <span class="content-price-orange">{{course.discounts}}</span>
                    <span class="current-price">
                      <span class="current-price-unite">¥</span>
                      {{course.price}}
                    </span>
                    <span class="activity-name">成就自己</span>
                    <span class="content-price-buy">{{course.sales}}人购买</span>
                  </p>
                  <div class="btn btn-green btn-offset">立即购买</div>
                </div>
              </div>
            </li>
            <!-- 课程信息结束 -->
            
          </ul>
        </el-tab-pane>
        <el-tab-pane label="已购" name="hasPay">
          <img
            src="@/assets/course-list/no-login@2x.png"
            class="no-data-icon"
          />
          <div class="no-data-title">您还没有登录</div>
          <div class="no-data-title">登录后即可查看已购课程</div>
          <div class="btn btn-yellow btn-center">立即登录</div>
        </el-tab-pane>
      </el-tabs>
    </div>
    <Footer></Footer>
  </div>
</template>

<script>
import Header from "./Header/Header"; //顶部登录条
import Footer from "./Footer/index"; //顶部登录条
export default {
  name: "Index",
  components: {
    Header,
    Footer,
  },
  data() {
    return {
      activeName: "allLesson",
      courseList:[]// 选购课程信息

    };
  },
  created() {
    this.getCourseList();
  },
  methods: {
    changeCourseTab(tabName) {
      this.classSelect = tabName;
      sessionStorage && sessionStorage.setItem("courseTab", tabName);
    },
    gotoDetail() {
      this.$router.push({ name: "Course", params: { courseid: 1 } });
    },
    // 获取所有课程列表
    getCourseList(){
     return  this.axios.get("http://localhost:8002/course/getAllCourse")
     .then(res=>{
       this.courseList=res.data;
       console.log(res.data);
     }).catch(err=>{
       this.$message.error("获取失败");
     });
    }
  },
};
</script>

<style lang="less" scoped>
@import "../assets/less/common.less";

p {
  margin-top: 0;
}
li {
  list-style: none;
}
flex {
  display: flex;
}
.btn(@a, @b) {
  background-color: @a;
  color: @b;
  border: 1px solid @a;
}
.course-ads {
  margin-bottom: 20px;
  cursor: pointer;
  width: 100%;
  max-height: 280px;
  overflow: hidden;
  img {
    width: 100%;
    border-radius: 2px;
  }
}
.tab-container {
  width: 100%;
  height: 60px;
  background: #ffffff;
  border-bottom: 1px solid #ededed;
}
.vux-tab.course-tab {
  box-sizing: border-box;
  height: 60px;
  width: 200px;
  overflow: hidden;
  font-size: 20px;
  .vux-tab-container {
    width: 260px;
  }
  .vux-tab-item {
    cursor: pointer;
    background: none;
    line-height: 60px;
    font-size: 20px;
  }
  .vux-tab-ink-bar {
    bottom: -1px;
    .vux-tab-bar-inner {
      height: 2px;
    }
  }
}
.tab-container {
  width: 100%;
  height: 60px;
  background: #ffffff;
  border-bottom: 1px solid #ededed;
}
.course-ul {
  padding: 0 20px;
}
.hover-pointer {
  cursor: pointer;
}
.course-ul-pc .course-li {
  padding: 30px 0 40px 0;
  border-bottom: 1px solid #ededed;
  position: relative;
  &:last-child {
    border-bottom: 0;
  }
}
.current-price {
  font-size: 12px;
  color: #999;
  font-weight: 600;
  text-decoration: line-through;
}
.current-price-unite {
  font-size: 12px;
  margin-right: -4px;
}
.p-author-line {
  content: "";
  display: inline-block;
  width: 1px;
  height: 10px;
  position: absolute;
  background: #999;
  margin-left: 5px;
  top: 3px;
}
.teacher-portrait {
  width: 121px;
  height: 159px;
  border-radius: 4px;
  float: left;
}
.content-main {
  line-height: 1.4;
  margin-left: 141px;
  position: relative;
  height: 150px;
}
.content-main .p-title {
  font-size: 20px;
  color: #333;
  font-family: PingFangSC-Medium, PingFang SC;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  width: 350px;
}
.course-ul-pc .content-main .p-title-buy {
  font-size: 12px;
  color: #999;
  display: inline-block;
  margin-top: 6px;
  position: relative;
  float: right;
  top: -28px;
  font-weight: 400;
}
p {
  margin-top: 0;
}
.course-ul-pc .p-author-line {
  content: "";
  display: inline-block;
  width: 1px;
  height: 10px;
  position: absolute;
  background: #999;
  margin-left: 5px;
  top: 3px;
}
.text-overflow {
  word-wrap: normal;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
.course-ul-pc .content-main .p-describe {
  font-size: 14px;
  margin-top: 5px;
  color: #333;
  word-wrap: normal;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
.course-ul-pc .content-main .p-author-span:not(:first-child) {
  margin-left: 18px;
}
.course-ul-pc .content-main .content-course {
  font-size: 14px;
  padding-top: 25px;
  color: #666;
}

ol,
ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
* {
  -webkit-tap-highlight-color: transparent;
}
.course-ul-pc .content-main .content-course-lesson {
  display: inline-block;
  width: 304px;
  margin: 2px 40px 6px 0;
}
.course-ul-pc .content-main .content-course .free-label {
  width: 50px;
  height: 16px;
  margin: 1px 5px 0 0;
}
.course-ul-pc .content-main .content-course-lesson:nth-child(2n) {
  margin-right: 0;
}

.course-ul-pc .content-main .content-course-lesson {
  display: inline-block;
  width: 304px;
  margin: 2px 40px 6px 0;
}
.course-ul-pc .content-main .content-price {
  height: 28px;
  line-height: 28px;
  position: absolute;
  width: 100%;
  bottom: -4px;
}
.course-ul-pc .content-main .content-price-p {
  font-size: 0;
}
.course-ul-pc .content-main .content-price-orange-sm {
  color: #ff7452;
  font-size: 14px;
}

.content-course {
  font-size: 14px;
  padding-top: 25px;
  color: #666;
}
.content-course.free-label {
  width: 50px;
  height: 16px;
  margin: 1px 5px 0 0;
}

.content-course-lesson {
  display: inline-block;
  width: 304px;
  margin: 2px 40px 6px 0;
}
.content-course-lesson:nth-child(2n) {
  margin-right: 0;
}
.disabled-word {
  color: #999;
  cursor: default;
}
.theme-span :hover {
  color: #0abf89;
}

.content-price-p {
  font-size: 0;
}
.content-price-orange {
  color: #ff7452;
  font-size: 20px;
}
.content-price-buy {
  font-size: 14px;
  color: #999;
  margin-left: 20px;
  transform: translate(8px, -2px);
  display: inline-block;
}
.content-price-grey {
  color: #999;
  font-size: 12px;
  margin-left: 5px;
}
.content-price-buyed {
  color: #999;
  font-size: 14px;
}
.content-price {
  height: 28px;
  line-height: 28px;
  position: absolute;
  width: 100%;
  bottom: -4px;
}
.activity-name {
  font-size: 12px;
  line-height: 14px;
  color: rgba(255, 255, 255, 1);
  padding: 2px 4px;
  background: linear-gradient(
    180deg,
    rgba(255, 137, 110, 1) 0%,
    rgba(255, 123, 92, 1) 100%
  );
  border-radius: 2px;
  display: inline-block;
  transform: translate(6px, -3px);
}
.p-title {
  font-size: 20px;
  color: #333;
  font-family: PingFangSC-Medium, PingFang SC;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  width: 350px;
}
.p-title-dec {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
}
.p-title-buy {
  // .font(12px);
  font-size: 12px;
  color: #999;
  display: inline-block;
  margin-top: 6px;
  position: relative;
  // .fr;
  top: -28px;
  font-weight: normal;
}

.companion-reading {
  background: rgba(0, 179, 138, 0.06);
  border-radius: 2px;
  font-family: PingFangSC-Regular;
  font-size: 12px;
  color: #00b38a;
  display: inline-block;
  padding: 0 8px;
  height: 22px;
  line-height: 22px;
  margin-left: 10px;
  vertical-align: text-bottom;
  position: relative;

  .triangle {
    position: absolute;
    top: 12px;
    left: -3px;
    width: 0;
    height: 0;
    content: "";
    border: 5px solid;
    border-color: transparent transparent white white;
    transform: rotate(45deg);
    box-shadow: -2px 2px 2px rgba(0, 0, 0, 0.08);
  }
}
.companion-tip {
  display: none;
  position: absolute;
  font-family: HiraginoSansGB-W3;
  font-size: 14px;
  color: #777777;
  background: #ffffff;
  border: 1px solid #e3ebe9;
  box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.08);
  border-radius: 3px;
  line-height: 29px;
  top: -7px;
  word-break: keep-all;
  left: 80px;
  padding: 0 10px;
  width: 200px;
  z-index: 2;
}
.companion-reading:hover .companion-tip {
  display: inline-block;
}
.companion-reading:hover .companion-tip {
  display: block;
}
.p-describe {
  // .font(14px);
  font-size: 14px;
  margin-top: 5px;
  color: #333;
  // .text-overflow;
}
.p-author + p {
  margin-top: 0;
}
.p-author {
  margin: 10px 0 5px 0;
  // .font(12px);
  font-size: 12px;
  color: #999;
  position: relative;

  .p-author-line {
    content: "";
    display: inline-block;
    width: 1px;
    height: 10px;
    position: absolute;
    background: #999;
    margin-left: 5px;
    top: 3px;
  }
}
.p-author-span:not(:first-child) {
  margin-left: 18px;
}

.course-ul-container {
  width: 850px;
  display: inline-block;
  float: left;
}
.course-ul {
  padding: 0 20px;
}
.course-ul-pc {
  width: 790px;
  background-color: #fff;
  padding: 0 30px;
  // .fl;
}
.tag-icon {
  width: 57px;
  height: 18px;
  position: absolute;
  top: 30px;
  left: 0;
}

.more-icon {
  width: 10px;
  height: 10px;
  vertical-align: middle;
}
.btn {
  width: 94px;
  height: 34px;
  text-align: center;
  line-height: 34px;
  cursor: pointer;
  border-radius: 3px;
  font-size: 14px;
  box-sizing: content-box;
  &-green {
    .btn(#00b38a, #fff);
    &:hover {
      background: #00a57f;
      border-color: #00a57f;
    }
  }
  &-yellow {
    .btn(#fcd766, #fff);
    &:hover {
      background: #fcd766;
      border-color: #fcd766;
    }
  }
  &-white {
    .btn(#fff, #00b38a);
    border: 1px solid #00b38a;
    &:hover {
      color: #fff;
      border-color: #00b38a;
      background-color: #00b38a;
    }
  }
  &-offset {
    position: absolute;
    right: 0;
    top: -4px;
  }
}

.btn-center {
  margin: 10px auto;
}

.no-data-title {
  font-size: 20px;
  color: #333;
  font-weight: 500;
}
</style>

2. 登录

<template>
  <div class="header-pc-wrap">
    <!-- 登录框 开始-->
    <el-dialog
      style="width:800px;margin:0px auto;"
      title=""
      :visible.sync="dialogFormVisible"
    >
      <el-form>
        <el-form-item>
          <h1 style="font-size:30px;color:#00B38A">拉勾</h1>
        </el-form-item>
        <el-form-item>
          <el-input
            v-model="phone"
            placeholder="请输入常用手机号..."
          ></el-input>
        </el-form-item>
        <el-form-item>
          <el-input v-model="password" placeholder="请输入密码..."></el-input>
        </el-form-item>
      </el-form>
      <el-button
        style="width:100%;margin:0px auto;background-color: #00B38A;font-size:20px"
        type="primary"
        @click="login"
        >确 定</el-button
      >
      <p></p>
      <!-- 微信登录图标 -->
      <img
        @click="goToLoginWX"
        src="http://www.lgstatic.com/lg-passport-fed/static/pc/modules/common/img/icon-wechat@2x_68c86d1.png"
        alt=""
      />
    </el-dialog>
    <!-- 登录框 结束-->

    <!-- 顶部登录条 -->
    <div class="wrap-box">
      <div @click="toToIndex" class="edu-icon"></div>
      <div @click="toToIndex" class="text">拉勾教育</div>
      <div class="right-var-wrap" v-if="!isLogin">
        <div class="login-handler" @click="goToLogin">登录 | 注册</div>
      </div>
      <div class="right-var-wrap" v-if="isLogin">
        <div
          :class="{ 'tip-icon': true, 'has-new-message': isHasNewMessage }"
          @click="toToNotic"
        >
          <i class="el-icon-bell"></i>
        </div>
        <img :src="userDTO.content.portrait" class="avatar-wrap" />
        <div class="bar-wrap">
          <ul class="account-bar">
            <li class="user_dropdown" data-lg-tj-track-code="index_user">
              <span class="unick">{{ userDTO.content.name }}</span>
              <i />
              <ul style="">
                <li @click="goToSetting">
                  账号设置
                </li>
                <li @click="logout">
                  退出
                </li>
              </ul>
            </li>
          </ul>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "Header",

  props: {},
  data() {
    return {
      isLogin: false, // 登录状态,true:已登录,false:未登录
      userDTO: null, // 用来保存登录的用户信息
      isHasNewMessage: false, // 是否有新的推送消息
      dialogFormVisible: false, // 是否显示登录框,true:显示,false:隐藏
      phone: "", // 双向绑定表单 手机号
      password: "", // 双向绑定表单 密码
    };
  },
  computed: {},
  watch: {},
  mounted() {},
  created() {
    // 当刷新页面,组件创建成功之后,立刻检测本地储存中是否存在用户对象
    this.userDTO = JSON.parse(localStorage.getItem("user"));
    if (this.userDTO != null) {
      this.isLogin = true; // 已登录
    }
  },
  methods: {
    goToSetting() {
      this.$router.push("/setting"); // 跳转个人设置页面
    },
    goToLogin() {
      this.dialogFormVisible = true; // 显示登录框
    },
    goToLoginWX() {
      alert("微信登录");
    },
    toToIndex() {
      this.$router.push("/"); //回到首页
    },
    toToNotic() {},
    login() {
      return this.axios
        .get("http://localhost:8002/user/login", {
          params: {
            phone: this.phone,
            password: this.password,
          },
        })
        .then((res) => {
          console.log(res.data);
          this.dialogFormVisible = false; //关闭登录框
          this.userDTO = res.data; // 保存返回数据中的用户对象信息
          this.isLogin = true; // 更新登录状态
          localStorage.setItem("user", JSON.stringify(this.userDTO)); // 将登录成功的对象信息保存到本地储存中
        })
        .catch((err) => {
          this.$message.error("登录失败");
        });
    },
    logout() {
      // 登出
      localStorage.setItem("user", null); // 将登录成功的对象信息保存到本地储存中
      this.isLogin = false; // 更新登录状态
      alert("谢谢使用,再见!");
    },
  },
};
</script>

<style lang="less" scoped>
.header-pc-wrap {
  width: 100%;
  height: 40px;
  background: rgba(35, 39, 43, 1);
}
.wrap-box {
  width: 1200px;
  height: 100%;
  margin: 0 auto;
}
.edu-icon {
  float: left;
  width: 24px;
  height: 24px;
  background: url("./static/img/Icon@2x.png") no-repeat;
  background-size: 100% 100%;
  margin-top: 8px;
}
.text {
  font-size: 16px;
  font-weight: 500;
  color: rgba(255, 255, 255, 1);
  line-height: 40px;
  float: left;
  margin-left: 6px;
}
.login-handler {
  font-size: 12px;
  font-weight: 500;
  color: rgba(255, 255, 255, 1);
  line-height: 40px;
  float: left;
  cursor: pointer;
}
.right-var-wrap {
  float: right;
  font-size: 0;
  text-align: right;
}
.tip-icon,
.avatar-wrap,
.bar-wrap {
  display: inline-block;
  vertical-align: top;
}
.tip-icon {
  font-size: 16px;
  line-height: 40px;
  margin-right: 26px;
  color: #818895;
  cursor: pointer;
  &:hover {
    color: #fff;
  }
  &.has-new-message {
    position: relative;
    &:after {
      content: " ";
      display: inline-block;
      position: absolute;
      top: 50%;
      width: 6px;
      height: 6px;
      border-radius: 3px;
      background: red;
      right: 0;
      margin-top: -7px;
    }
  }
}
.user_dropdown {
  position: relative;
  cursor: pointer;
  font-size: 14px;
  text-align: center;
  &:hover {
    .unick {
      color: #fff;
    }
    i {
      -webkit-transform: rotate(180deg);
      -moz-transform: rotate(180deg);
      -ms-transform: rotate(180deg);
      -o-transform: rotate(180deg);
      transform: rotate(180deg);
      animation-fill-mode: forwards;
      border-color: #fff transparent transparent;
    }
    > ul {
      display: block;
      position: absolute;
      top: 40px;
      width: 100%;
      min-width: 80px;
      line-height: 30px;
      background-color: #32373e;
      z-index: 1000;
      list-style: none;
      margin: 0px;
      padding: 0px;
      > li {
        width: 100%;
        height: 30px;
        &:hover {
          background-color: #25282d;
          color: #fff;
        }
      }
    }
  }
  .unick {
    display: block;
    height: 40px;
    line-height: 40px;
    font-size: 14px;
    color: #afb5c0;
    max-width: 96px;
    margin: 0 9px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
    word-wrap: normal;
    &:hover {
      color: #fff;
    }
  }
  > i {
    position: absolute;
    top: 17px;
    right: 0;
    font-size: 0;
    height: 0;
    width: 0;
    border-width: 5px 4px 0;
    border-style: solid dashed;
    border-color: #afb5c0 transparent transparent;
    overflow: hidden;
    -webkit-transition: all 0.4s ease 0s;
    -moz-transition: all 0.4s ease 0s;
    -ms-transition: all 0.4s ease 0s;
    -o-transition: all 0.4s ease 0s;
    transition: all 0.4s ease 0s;
  }
  > ul {
    display: none;
    color: #afb5c0;
  }
}
.avatar-wrap {
  width: 24px;
  height: 24px;
  margin-top: 8px;
  border-radius: 50%;
}
</style>

3. 已购课程

<template>
  <div>
    <Header></Header>
    <div style="width: 850PX;display: inline-block; margin:0px auto;">
      <el-tabs v-model="activeName">
        <el-tab-pane label="选课" name="allLesson">
          <ul class="course-ul-pc">
            <!-- 课程信息展示开始 -->
            <li
              class="course-li"
              v-for="(course, index) in courseList"
              :key="index"
            >
              <!-- 课程封面图 -->
              <img
                src="course.courseImgUrl"
                class="teacher-portrait hover-pointer"
              />
              <!-- 课程文字信息 -->
              <div class="content-main">
                <!-- 课程标题 -->
                <div class="content-title hover-pointer">
                  <div
                    class="p-title"
                    style="text-align:left;"
                    @click="gotoDetail"
                  >
                    <span>
                      {{ course.courseName }}
                    </span>
                  </div>
                  <!-- 作者和职称 -->
                  <p class="p-title-buy text-overflow">
                    <span class="p-author-span">
                      {{ course.teacher.teacherName }}
                    </span>
                    <span class="p-author-line" />
                    <span class="p-author-span">
                      {{ course.teacher.position }}
                    </span>
                  </p>
                  <p></p>
                  <!-- 课程简单描述 -->
                  <p class="p-describe" style="text-align:left;">
                    {{ course.brief }}
                  </p>
                </div>
                <!-- 课程前两个章节信息 -->
                <ul class="content-course" style="text-align:left;">
                  <!-- 章节1 通常是第一章的前两节课-->
                  <li
                    class="content-course-lesson text-overflow"
                    style="width:300px"
                    v-for="(lesson,
                    index) in course.courseSections[0].courseLessons.slice(
                      0,
                      2
                    )"
                    :key="index"
                  >
                    <!-- 免费试看图标 -->
                    <img
                      src="@/assets/course-list/free-course.png"
                      class="free-label hover-pointer"
                    />
                    <span class="theme-span hover-pointer">
                      {{ lesson.theme }}
                    </span>
                  </li>
                </ul>
                <!-- 价格信息 -->
                <div class="content-price" style="text-align:left;">
                  <p class="content-price-p">
                    <span class="content-price-orange-sm"></span>
                    <span class="content-price-orange">{{
                      course.discounts
                    }}</span>
                    <span class="current-price">
                      <span class="current-price-unite"></span>
                      {{ course.price }}
                    </span>
                    <span class="activity-name">成就自己</span>
                    <span class="content-price-buy"
                      >{{ course.sales }}人购买</span
                    >
                  </p>
                  <div class="btn btn-green btn-offset">立即购买</div>
                </div>
              </div>
            </li>
            <!-- 课程信息结束 -->
          </ul>
        </el-tab-pane>
        <el-tab-pane label="已购" name="hasPay">
          <div v-if="!isLogin">
            <img
              src="@/assets/course-list/no-login@2x.png"
              class="no-data-icon"
            />
            <div class="no-data-title">您还没有登录</div>
            <div class="no-data-title">登录后即可查看已购课程</div>
            <div class="btn btn-yellow btn-center">立即登录</div>
          </div>

          <div v-if="isLogin">
            <ul class="course-ul-pc">
              <!-- 课程信息展示开始 -->
              <li
                class="course-li"
                v-for="(course, index) in myCourseList"
                :key="index"
              >
                <!-- 课程封面图 -->
                <img
                  src="course.courseImgUrl"
                  class="teacher-portrait hover-pointer"
                />
                <!-- 课程文字信息 -->
                <div class="content-main">
                  <!-- 课程标题 -->
                  <div class="content-title hover-pointer">
                    <div
                      class="p-title"
                      style="text-align:left;"
                      @click="gotoDetail"
                    >
                      <span>
                        {{ course.courseName }}
                      </span>
                    </div>
                    <!-- 作者和职称 -->
                    <p class="p-title-buy text-overflow">
                      <span class="p-author-span">
                        {{ course.teacher.teacherName }}
                      </span>
                      <span class="p-author-line" />
                      <span class="p-author-span">
                        {{ course.teacher.position }}
                      </span>
                    </p>
                    <p></p>
                    <!-- 课程简单描述 -->
                    <p class="p-describe" style="text-align:left;">
                      {{ course.brief }}
                    </p>
                  </div>
                  <!-- 课程前两个章节信息 -->
                  <ul class="content-course" style="text-align:left;">
                    <!-- 章节1 通常是第一章的前两节课-->
                    <li
                      class="content-course-lesson text-overflow"
                      style="width:300px"
                      v-for="(lesson,
                      index) in course.courseSections[0].courseLessons.slice(
                        0,
                        2
                      )"
                      :key="index"
                    >
                      <!-- 免费试看图标 -->
                      <img
                        src="@/assets/course-list/free-course.png"
                        class="free-label hover-pointer"
                      />
                      <span class="theme-span hover-pointer">
                        {{ lesson.theme }}
                      </span>
                    </li>
                  </ul>
                  <!-- 价格信息 -->
                  <div class="content-price" style="text-align:left;">
                    <p class="content-price-p">
                      <span class="content-price-orange-sm"></span>
                      <span class="content-price-orange">{{
                        course.discounts
                      }}</span>
                      <span class="current-price">
                        <span class="current-price-unite"></span>
                        {{ course.price }}
                      </span>
                      <span class="activity-name">成就自己</span>
                      <span class="content-price-buy"
                        >{{ course.sales }}人购买</span
                      >
                    </p>
                    <div class="btn btn-yellow btn-offset">开始学习</div>
                  </div>
                </div>
              </li>
              <!-- 课程信息结束 -->
            </ul>
          </div>
        </el-tab-pane>
      </el-tabs>
    </div>
    <Footer></Footer>
  </div>
</template>

<script>
import Header from "./Header/Header"; //顶部登录条
import Footer from "./Footer/index"; //顶部登录条
export default {
  name: "Index",
  components: {
    Header,
    Footer,
  },
  data() {
    return {
      activeName: "allLesson",
      courseList: [], // 选购课程信息
      isLogin: false, //登录状态
      user:null,// 登录的用户对象
      myCourseList:[]// 已登录用户购买的课程集合
    };
  },
  created() {
      this.getCourseList();//当组件创建完毕,就调用获取课程的方法
    this.user=JSON.parse(localStorage.getItem("user"));
    if(this.user!=null){
      this.isLogin=true;// 改变登录状态
      this.getMyCourseList();//查询已经用户购买过的课程列表
    }
  
  },
  methods: {
    changeCourseTab(tabName) {
      this.classSelect = tabName;
      sessionStorage && sessionStorage.setItem("courseTab", tabName);
    },
    gotoDetail() {
      this.$router.push({ name: "Course", params: { courseid: 1 } });
    },
    // 获取所有课程列表
    getCourseList() {
      return this.axios
        .get("http://localhost:8002/course/getAllCourse")
        .then((res) => {
          this.courseList = res.data;
          console.log(res.data);
        })
        .catch((err) => {
          this.$message.error("获取失败");
        });
    },
    getMyCourseList() {
      return this.axios
        .get("http://localhost:8002/course/getCourseByUserId/"+this.user.content.id)
        .then((res) => {
          this.myCourseList = res.data;
          console.log(res.data);
        })
        .catch((err) => {
          this.$message.error("获取失败");
        });
    },
  },
};
</script>

<style lang="less" scoped>
@import "../assets/less/common.less";

p {
  margin-top: 0;
}
li {
  list-style: none;
}
flex {
  display: flex;
}
.btn(@a, @b) {
  background-color: @a;
  color: @b;
  border: 1px solid @a;
}
.course-ads {
  margin-bottom: 20px;
  cursor: pointer;
  width: 100%;
  max-height: 280px;
  overflow: hidden;
  img {
    width: 100%;
    border-radius: 2px;
  }
}
.tab-container {
  width: 100%;
  height: 60px;
  background: #ffffff;
  border-bottom: 1px solid #ededed;
}
.vux-tab.course-tab {
  box-sizing: border-box;
  height: 60px;
  width: 200px;
  overflow: hidden;
  font-size: 20px;
  .vux-tab-container {
    width: 260px;
  }
  .vux-tab-item {
    cursor: pointer;
    background: none;
    line-height: 60px;
    font-size: 20px;
  }
  .vux-tab-ink-bar {
    bottom: -1px;
    .vux-tab-bar-inner {
      height: 2px;
    }
  }
}
.tab-container {
  width: 100%;
  height: 60px;
  background: #ffffff;
  border-bottom: 1px solid #ededed;
}
.course-ul {
  padding: 0 20px;
}
.hover-pointer {
  cursor: pointer;
}
.course-ul-pc .course-li {
  padding: 30px 0 40px 0;
  border-bottom: 1px solid #ededed;
  position: relative;
  &:last-child {
    border-bottom: 0;
  }
}
.current-price {
  font-size: 12px;
  color: #999;
  font-weight: 600;
  text-decoration: line-through;
}
.current-price-unite {
  font-size: 12px;
  margin-right: -4px;
}
.p-author-line {
  content: "";
  display: inline-block;
  width: 1px;
  height: 10px;
  position: absolute;
  background: #999;
  margin-left: 5px;
  top: 3px;
}
.teacher-portrait {
  width: 121px;
  height: 159px;
  border-radius: 4px;
  float: left;
}
.content-main {
  line-height: 1.4;
  margin-left: 141px;
  position: relative;
  height: 150px;
}
.content-main .p-title {
  font-size: 20px;
  color: #333;
  font-family: PingFangSC-Medium, PingFang SC;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  width: 350px;
}
.course-ul-pc .content-main .p-title-buy {
  font-size: 12px;
  color: #999;
  display: inline-block;
  margin-top: 6px;
  position: relative;
  float: right;
  top: -28px;
  font-weight: 400;
}
p {
  margin-top: 0;
}
.course-ul-pc .p-author-line {
  content: "";
  display: inline-block;
  width: 1px;
  height: 10px;
  position: absolute;
  background: #999;
  margin-left: 5px;
  top: 3px;
}
.text-overflow {
  word-wrap: normal;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
.course-ul-pc .content-main .p-describe {
  font-size: 14px;
  margin-top: 5px;
  color: #333;
  word-wrap: normal;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
.course-ul-pc .content-main .p-author-span:not(:first-child) {
  margin-left: 18px;
}
.course-ul-pc .content-main .content-course {
  font-size: 14px;
  padding-top: 25px;
  color: #666;
}

ol,
ul {
  margin: 0;
  padding: 0;
  list-style: none;
}
* {
  -webkit-tap-highlight-color: transparent;
}
.course-ul-pc .content-main .content-course-lesson {
  display: inline-block;
  width: 304px;
  margin: 2px 40px 6px 0;
}
.course-ul-pc .content-main .content-course .free-label {
  width: 50px;
  height: 16px;
  margin: 1px 5px 0 0;
}
.course-ul-pc .content-main .content-course-lesson:nth-child(2n) {
  margin-right: 0;
}

.course-ul-pc .content-main .content-course-lesson {
  display: inline-block;
  width: 304px;
  margin: 2px 40px 6px 0;
}
.course-ul-pc .content-main .content-price {
  height: 28px;
  line-height: 28px;
  position: absolute;
  width: 100%;
  bottom: -4px;
}
.course-ul-pc .content-main .content-price-p {
  font-size: 0;
}
.course-ul-pc .content-main .content-price-orange-sm {
  color: #ff7452;
  font-size: 14px;
}

.content-course {
  font-size: 14px;
  padding-top: 25px;
  color: #666;
}
.content-course.free-label {
  width: 50px;
  height: 16px;
  margin: 1px 5px 0 0;
}

.content-course-lesson {
  display: inline-block;
  width: 304px;
  margin: 2px 40px 6px 0;
}
.content-course-lesson:nth-child(2n) {
  margin-right: 0;
}
.disabled-word {
  color: #999;
  cursor: default;
}
.theme-span :hover {
  color: #0abf89;
}

.content-price-p {
  font-size: 0;
}
.content-price-orange {
  color: #ff7452;
  font-size: 20px;
}
.content-price-buy {
  font-size: 14px;
  color: #999;
  margin-left: 20px;
  transform: translate(8px, -2px);
  display: inline-block;
}
.content-price-grey {
  color: #999;
  font-size: 12px;
  margin-left: 5px;
}
.content-price-buyed {
  color: #999;
  font-size: 14px;
}
.content-price {
  height: 28px;
  line-height: 28px;
  position: absolute;
  width: 100%;
  bottom: -4px;
}
.activity-name {
  font-size: 12px;
  line-height: 14px;
  color: rgba(255, 255, 255, 1);
  padding: 2px 4px;
  background: linear-gradient(
    180deg,
    rgba(255, 137, 110, 1) 0%,
    rgba(255, 123, 92, 1) 100%
  );
  border-radius: 2px;
  display: inline-block;
  transform: translate(6px, -3px);
}
.p-title {
  font-size: 20px;
  color: #333;
  font-family: PingFangSC-Medium, PingFang SC;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  width: 350px;
}
.p-title-dec {
  display: -webkit-box;
  -webkit-box-orient: vertical;
  -webkit-line-clamp: 1;
  overflow: hidden;
}
.p-title-buy {
  // .font(12px);
  font-size: 12px;
  color: #999;
  display: inline-block;
  margin-top: 6px;
  position: relative;
  // .fr;
  top: -28px;
  font-weight: normal;
}

.companion-reading {
  background: rgba(0, 179, 138, 0.06);
  border-radius: 2px;
  font-family: PingFangSC-Regular;
  font-size: 12px;
  color: #00b38a;
  display: inline-block;
  padding: 0 8px;
  height: 22px;
  line-height: 22px;
  margin-left: 10px;
  vertical-align: text-bottom;
  position: relative;

  .triangle {
    position: absolute;
    top: 12px;
    left: -3px;
    width: 0;
    height: 0;
    content: "";
    border: 5px solid;
    border-color: transparent transparent white white;
    transform: rotate(45deg);
    box-shadow: -2px 2px 2px rgba(0, 0, 0, 0.08);
  }
}
.companion-tip {
  display: none;
  position: absolute;
  font-family: HiraginoSansGB-W3;
  font-size: 14px;
  color: #777777;
  background: #ffffff;
  border: 1px solid #e3ebe9;
  box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.08);
  border-radius: 3px;
  line-height: 29px;
  top: -7px;
  word-break: keep-all;
  left: 80px;
  padding: 0 10px;
  width: 200px;
  z-index: 2;
}
.companion-reading:hover .companion-tip {
  display: inline-block;
}
.companion-reading:hover .companion-tip {
  display: block;
}
.p-describe {
  // .font(14px);
  font-size: 14px;
  margin-top: 5px;
  color: #333;
  // .text-overflow;
}
.p-author + p {
  margin-top: 0;
}
.p-author {
  margin: 10px 0 5px 0;
  // .font(12px);
  font-size: 12px;
  color: #999;
  position: relative;

  .p-author-line {
    content: "";
    display: inline-block;
    width: 1px;
    height: 10px;
    position: absolute;
    background: #999;
    margin-left: 5px;
    top: 3px;
  }
}
.p-author-span:not(:first-child) {
  margin-left: 18px;
}

.course-ul-container {
  width: 850px;
  display: inline-block;
  float: left;
}
.course-ul {
  padding: 0 20px;
}
.course-ul-pc {
  width: 790px;
  background-color: #fff;
  padding: 0 30px;
  // .fl;
}
.tag-icon {
  width: 57px;
  height: 18px;
  position: absolute;
  top: 30px;
  left: 0;
}

.more-icon {
  width: 10px;
  height: 10px;
  vertical-align: middle;
}
.btn {
  width: 94px;
  height: 34px;
  text-align: center;
  line-height: 34px;
  cursor: pointer;
  border-radius: 3px;
  font-size: 14px;
  box-sizing: content-box;
  &-green {
    .btn(#00b38a, #fff);
    &:hover {
      background: #00a57f;
      border-color: #00a57f;
    }
  }
  &-yellow {
    .btn(#fcd766, #fff);
    &:hover {
      background: #fcd766;
      border-color: #fcd766;
    }
  }
  &-white {
    .btn(#fff, #00b38a);
    border: 1px solid #00b38a;
    &:hover {
      color: #fff;
      border-color: #00b38a;
      background-color: #00b38a;
    }
  }
  &-offset {
    position: absolute;
    right: 0;
    top: -4px;
  }
}

.btn-center {
  margin: 10px auto;
}

.no-data-title {
  font-size: 20px;
  color: #333;
  font-weight: 500;
}
</style>

 

4. 课程详情

  • 基本信息,课程信息描述,总课时
    Index.vue
     @click="gotoDetail(course)"  
    gotoDetail(course) {
          // 传入页面地址 页面参数应该是course
          this.$router.push({ name: "Course", params: {course:course } });
        },
    Course.vue
      <!-- 课程详情 -->
    <div style="position: relative;">
                    <div class="intro">
                      <div class="intro-content">
                        <img
                          class="course-img"
                          :src="course.courseImgUrl"
                          alt="课程图片"
                        />
                        <div class="conent-wrap">
                          <div class="name" style="text-align:left;">
                            {{course.courseName}}
                          </div>
                          <div class="des text-omit" style="text-align:left;">
                            {{course.brief}}
                          </div>
                          <div class="title">
                            <div class="teacher-name text-omit">
                              {{course.teacher.teacherName}}
                              <span class="line"></span>
                              {{course.teacher.position}}
                            </div>
                          </div>
                          <div class="lesson-info">
                            <div class="boook-icon backgroun-img-set"></div>
                            <div class="time">{{totalLesson}}讲 / {{course.totalDuration}}课时</div>
                            <div class="person-icon backgroun-img-set"></div>
                            <div class="person">{{course.sales}}人已购买</div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </div>
    
    
       <div class="public-class-container is-pc">
                    <el-tabs v-model="activeName">
                      <el-tab-pane label="课程信息" name="intro">
                        <div v-html="course.courseDescription" class="content-p pc-background">
                        </div>
        </el-tab-pane>
    
    
    data() {
        return {
          activeName: "intro",
          course:null,
          totalLesson:0,//总课时
        };
      },
      created(){
        // 获取上一个页面传递的参数
       this.course= this.$route.params.course;
       let x=0;
       for(let i=0;i<this.course.courseSections.length;i++){
         let section=this.course.courseSections[i];
         for(let j=0;j<section.courseLessons.length;j++){
           x++;
         }
       }
       this.totalLesson=x;
      
      }
  • 章节目录显示
      <!-- 目录框 -->
                      <el-tab-pane label="目录" name="directory">
                        <div
                          class="class-menu-contaniner list-page-container more-sections more-sections-padding"
                        >
                        <!-- 章 开始 -->
                          <div v-for="(section, index) in course.courseSections"
                              :key="index">
                            <div
                              class="section-name single-line"
                            >
                              {{ section.sectionName }}
                            </div>
                            <div class="class-menu-block">
                              <div
                                v-for="(lesson, index) in section.courseLessons"
                                :key="index"
                                class="class-level-one over-ellipsis"
                                @click="watchCourse(1)"
                              >
                                <div class="text-wrap">
                                  <div class="content">{{ lesson.theme }}</div>
                                  <div
                                    class="item-status-wrap item-status-wrap-list"
                                  >
                                    <div class="item-status test-watch">试看</div>
                                  </div>
                                </div>
                              </div>
                            </div>
                          </div>
                        </div>
                      </el-tab-pane>
  • 全部留言
    <script>
    data() {
    return {
    activeName: "intro",
    course:null,
    totalLessons:0, // 本门课程的总节数
    commentList:null, // 所有留言
    };
    },
    created(){
    this.course = this.$route.params.course; // 从路由中获得参数对象赋值给本组件的参
    // 计算多少节课要讲
    let x = 0;
    for(let i = 0; i< this.course.courseSections.length; i++){
    let section = this.course.courseSections[i]; //每一章
    for( let j = 0; j<section.courseLessons.length ; j++){
    x++;
    }} t
    his.totalLessons = x;
    // 获得所有留言
    this.getComment();
    },
    methods: {
    //播放视频
    watchCourse(index) {
    alert("观看第【" + index + "】节课程视频!");
    },
    buy(courseid) {
    alert("购买第【" + courseid + "】门课程成功,加油!");
    },
    getComment(){
    return this.axios
    .get("http://localhost:8002/course/comment/getCourseCommentList/"+this.course.id
    +"/1/20")
    .then((result) => {
    //console.log(result);
    this.commentList = result.data;
    }).catch( (error)=>{
    this.$message.error("获取留言信息失败!");
    } );
    }
    }
    </script>
    
    <!-- 留言板 开始-->
    <div class="message">
    <div class="message-topic">
    <div class="message-topic-title normal-font">精选留言</div>
    </div>
    <div>
    <div class="message-edit">
    <textarea rows="20" style="border:0px;resize: none;"
    contenteditable="true"
    placeholder="分享学习心得、思考感悟或者给自己一个小鼓励吧!"
    class="edit-div pcStyle"
    ></textarea>
    <div class="message-edit-count">
    <span class="message-edit-count-cur">0</span>
    <span class="message-edit-count-max">/2000</span>
    </div>
    </div>
    <div class="message-edit-footer flex">
    <button class="message-edit-btn disableBg" @click="saveComment">发表留言
    </button>
    </div>
    </div>
    <!-- 留言 开始 -->
    <div class="message-list" v-for="(comment , index) in commentList"
    :key="index"><div class="message-list-title">
    <div class="message-list-title-left">
    <div class="message-list-title-left-name">{{comment.userName}}</div>
    <div class="message-list-title-left-tag"></div>
    </div>
    <div class="message-list-title-right">
    <img class="message-list-title-right-icon"
    src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADgAAAA4BAMAAABaqCYtAAAAKlBMV
    EVHcExnZ2dzc3NmZmZqampmZmZmZmZnZ2dnZ2dnZ2dmZmZoaGhmZmZmZmZl+8SAAAAADXRSTlMA/AbsF
    tilbj5YwSqJPyESoQAAAZxJREFUOMt1lTtLA1EQha8xRhPTBEmhuKCCoNgoIlYLMcRKBG0sxIUgCDaBS
    DohEO0FEbQyIBZaBazERvAPWCwxPnP+i3tnrlGTmVPswn73NXNm7hrzq9m9kZ2ckTUUABifkOEBrK7li
    R7BMRFOA/uFc+BUgnV8mFisEW5IsIFi9FzBuwR91KJnAm8S9EIbxSBeBRZHk86MrBQJWjymJUC3nlugS
    yk+SQyhANfxos+s4krfM0DZvmbw2cuSCHNGi3PAfUygXYiU79ryyw1ibf0xZ9intBsz6SBadx24iiZXz
    8kPxCiTtYdLPzKTVFkkLQAZO/VikwYW/x/wHohcT/MiPQE8W9frxJrlbpiw4xvA0vbNmWyhj2Nrhmy+B
    7nEyTsN0rIaJAc0SDWqwX7rhAYfMa/Dui0bDZbwZAwUGNjWUWActnUUyN2hwDTaOkxRaSiwj6pRhjHKg
    TazSkWlwBK1jgIpBwrkHCgwyZ0oQ86BAjkHCjziG0KE8YBvCA/5KacOm6sgrHFAotouT6J23bkkLbsND
    jM9yt7yP+IbQYga5De+eBMAAAAASUVORK5CYII=" alt="">
    <div class="message-list-title-right-praise">{{comment.likeCount}}</div>
    </div>
    </div>
    <div class="message-list-content">
    {{comment.comment}}
    </div>
    </div>
    <!-- 留言 结束 -->
    </div>
    <!-- 留言板 结束-->
  • 章节状态
    <script>
    import Header from "./Header/Header"; //顶部登录条
    import Footer from "./Footer/index"; //顶部登录条
    export default {
    name: "Course",
    components: {
    Header,
    Footer,
    },
    data() {
    return {
    activeName: "intro",
    course:null,
    totalLessons:0, // 本门课程的总节数
    commentList:null, // 所有留言
    isLogin:false, // false 未登录
    myCourseList:[], // 我购买过的课程列表
    isBuy:false, // false 未购买
    user:null, // 登录的用户
    };
    },
    created(){this.course = this.$route.params.course; // 从路由中获得参数对象赋值给本组件的参
    // 检测是否登录
    this.user = JSON.parse( localStorage.getItem("user") );
    if( this.user != null ){
    this.isLogin = true; // 已登录
    this.getMyCourseList(); // 调用查询我购买的课程方法
    } /
    / 计算多少节课要讲,略。。。
    // 获得所有留言,略。。。
    },
    methods: {
    //章节,课程索引,文件播放地址
    watchCourse(i,index,file) {
    if(i==1 && (index==0||index==1)){
    alert("观看第【" + index + "】节课程视频!"+file);
    this.$router.push({name: "videoDetail",params: { file: file }});
    }else{
    if(!this.isLogin){
    alert("请先登录!");
    }else{
    if(!this.isBuy){
    alert("请购买解锁才能观看本视频!");
    }else{
    alert("观看第【" + index + "】节课程视频!"+file);
    this.$router.push({name: "videoDetail",params: { file: file }});
    }
    }
    }
    },
    buy(courseid) {
    alert("购买第【" + courseid + "】门课程成功,加油!");
    },
    getComment(){
    // 获取全部留言,省略。。。
    },
    saveComment(){},
    getMyCourseList(){
    return this.axios
    .get("http://localhost:8002/course/getCourseByUserId/"+this.user.content.id)
    .then((result) => {
    console.log("获得我的课程");
    console.log(result);
    this.myCourseList = result.data;
    // 检查我是否购买过本门课程
    console.log(this.myCourseList.length);
    for(let i = 0; i< this.myCourseList.length ; i++){
    if(this.myCourseList[i].id == this.course.id){
    this.isBuy = true;//标记购买过本次课程
    break;
    }
    }
    }).catch( (error)=>{
    this.$message.error("获取课程信息失败!");} );
    }
    },
    };
    </script>
    
    <el-tab-pane label="目录" name="directory">
    <div class="class-menu-contaniner list-page-container more-sections moresections-padding">
    <!-- 第一章 开始 -->
    <div v-for="section in course.courseSections.slice(0,1)" >
    <div class="section-name single-line">
    {{section.sectionName}}
    </div>
    <div class="class-menu-block">
    <!-- 每节课 开始 -->
    <div
    class="class-level-one over-ellipsis"
    @click="watchCourse(1,i,lesson.courseMedia.fileEdk)"
    v-for="(lesson , i) in section.courseLessons" :key="i">
    <div class="text-wrap">
    <div class="content">{{lesson.theme}}</div>
    <div class="item-status-wrap item-status-wrap-list">
    <!--第一章,前两节-->
    <div v-if="i == 0 || i==1">
    <!--未登录,试看-->
    <div v-if="!isLogin" class="item-status test-watch">试看</div>
    <!--已登录,未购买,试看-->
    <div v-else-if="isLogin && !isBuy" class="item-status test-watch">
    试看</div>
    <!--已登录,已购买,播放-->
    <div v-else class="item-status test-watch">播放</div>
    </div>
    <!--第一章,除了前两节后面的-->
    <div v-if="i != 0 && i!=1">
    <!--未登录,锁-->
    <div v-if="!isLogin" class="item-status lock"></div>
    <!--已登录,未购买,锁-->
    <div v-else-if="isLogin && !isBuy" class="item-status lock"></div>
    <!--已登录,已购买,播放-->
    <div v-else class="item-status test-watch">播放</div>
    </div>
    </div>
    </div>
    </div>
    <!-- 每节课 结束 -->
    </div>
    </div>
    <!-- 第一章 结束 -->
    <!-- 其余章 开始 -->
    <div v-for="section in
    course.courseSections.slice(1,course.courseSections.length)" >
    <div class="section-name single-line">
    {{section.sectionName}}
    </div>
    <div class="class-menu-block">
    <!-- 每节课 开始 -->
    <div
    class="class-level-one over-ellipsis"
    @click="watchCourse(2,j,lesson.courseMedia.fileEdk)"
    v-for="(lesson , j) in section.courseLessons" >
    <div class="text-wrap">
    <div class="content">{{lesson.theme}}</div>
    <div class="item-status-wrap item-status-wrap-list">
    <!--已登录,已购买,播放-->
    <div v-if="isLogin&&isBuy" class="item-status test-watch">播放</div>
    <!--未登录,锁-->
    <div v-else-if="!isLogin" class="item-status lock"></div>
    <!--已登录,未购买,锁-->
    <div v-if="isLogin && !isBuy" class="item-status lock"></div>
    </div>
    </div>
    </div>
    <!-- 每节课 结束 -->
    </div>
    </div>
    <!-- 其余章 结束 -->
    </div>
    </el-tab-pane>
  • 视频播放
 data() {
    return {
      myvideo: null, // 播放器对象
      isplay: false, //是否在播放
      nowTime: "00:00", //当前播放时间
      totalTime: "00:00", //总时长
      course:null,//课程信息
      lessonid:0,//课时ID
     
    };
  },
  created() { 
    // 接收课程课时
     this.course= this.$route.params.course;
     this.lessonid=this.$route.params.lessonid;

  },   



 // 初始播放的视频
    initPlay(){
      for(let i=0;i<this.course.courseSections.length;i++){
        let section=this.course.courseSections[i];
        for(let j=0;j<section.courseLessons.length;j++){
          let lesson=section.courseLessons[j];
          if(lesson.courseMedia!=null){if(this.lessonid==lesson.courseMedia.lessonId){
            this.myvideo.src=lesson.courseMedia.fileEdk;
            return;
          }}
          
        }
      }
    }

 

5. 播放页

  • 显示
    created() {
         // 获取用户登录信息
        this.user = JSON.parse(localStorage.getItem("user"));
        // 如果用户不为空,说明登录
        if (this.user != null) {
          this.isLogin = true;
        }
        // 接收课程课时
        this.course = this.$route.params.course;
        this.lessonid = this.$route.params.lessonid;
        this.isBuy=this.$route.params.isBuy;
        console.log(this.isBuy);
    
      },
    
    
      // 初始播放的视频
        initPlay() {
          for (let i = 0; i < this.course.courseSections.length; i++) {
            let section = this.course.courseSections[i];
            for (let j = 0; j < section.courseLessons.length; j++) {
              let lesson = section.courseLessons[j];
              if (lesson.courseMedia != null) {
                if (this.lessonid == lesson.courseMedia.lessonId) {
                  this.myvideo.src = lesson.courseMedia.fileEdk;
                  this.lessonName = lesson.theme;
                  return;
                }
              }
            }
          }
        },
    
    
              <!-- 章节目录 -->
              <div class="detail-part-content-pc calc detail-part-content">
                <div class="content-fold">
                  <div class="content-fold-img"></div>
                </div>
                <div class="content-container">
                  <div
                    v-for="(section, index) in course.courseSections"
                    :key="index"
                  >
                    <!-- 第一章节课时信息   -->
                    <div v-if="index<1">
                      <div class="content-label">
                        <div class="content-label-title single-line">
                          {{ section.sectionName }}
                        </div>
                        <img
                          class="arrow-icon"
                          src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAGFBMVEVHcEz///////////////////////////8dS1W+AAAAB3RSTlMAgwWyMeGgBsFrrQAAAFVJREFUKM9jYBiugMUBQ0i8EF2EsbxcAF1ReXkhuqJiczRl4uVGyqjKgIoUmFCVARUxMKAoAyliYEBRBlaEqiwcpAikrBShKglCqyFUMcEYCgwjBAAAeaoQrHtg6QoAAAAASUVORK5CYII="
                          alt=""
                        />
                      </div>
    
                      <div
                        class="content-sections"
                        v-for="(lesson, index) in section.courseLessons"
                        :key="index"
                      >
                        <!-- 前两节视频 -->
                        <div v-if="index < 2">
                          <!-- 未播放的视频 -->
                          <div class="content-section" @click="playLesson">
                            <div class="section-item clearfix">
                              <span class="kw-icon-video section-type-icon fl"
                                ><i class="el-icon-video-play"></i
                              ></span>
                              <span class="section-dec need-update">{{
                                lesson.theme
                              }}</span>
                            <!-- 课时状态 -->
                              <!-- 如果未登录,可以试看前两节课时 -->
                               <span  v-if="!isLogin" class="section-status-icon pause-play">试看</span>
                              <!-- 如果登录,且没有购买可以试看前两节课时 -->
                              <span  v-else-if="isLogin&&!isBuy" class="section-status-icon pause-play">试看</span>
                              <!-- 如果登录,且购买, 可以播放前两节课时 -->
                              <span v-else class="section-status-icon pause-play">可播放</span>
                            </div>
                            <div class="section-duration">
                              <span v-if="lesson.courseMedia!=null">时长:{{lesson.courseMedia.duration}}</span>
                              <span v-else>时长:暂无视频</span>
                            </div>
                          </div>
                        </div>
    
                        <!-- 其余课时视频 -->
                        <div v-else>
                          <!-- 未播放的视频 -->
                          <div class="content-section" @click="playLesson">
                            <div class="section-item clearfix">
                              <span class="kw-icon-video section-type-icon fl"
                                ><i class="el-icon-video-play"></i
                              ></span>
                              <span class="section-dec need-update">{{
                                lesson.theme
                              }}</span>
                            <!-- 课时状态 -->
                              <!-- 如果未登录,可以试看前两节课时 -->
                               <span  v-if="!isLogin" class="section-status-icon pause-play">未解锁</span>
                              <!-- 如果登录,且没有购买可以试看前两节课时 -->
                              <span  v-else-if="isLogin &&!isBuy" class="section-status-icon pause-play">未解锁</span>
                              <!-- 如果登录,且购买, 可以播放前两节课时 -->
                              <span v-else class="section-status-icon pause-play">可播放</span>
                            </div>
                            <div class="section-duration">
                              <span v-if="lesson.courseMedia!=null">时长:{{lesson.courseMedia.duration}}</span>
                              <span v-else>时长:暂无视频</span>
                            </div>
                          </div>
                        </div>
    
                        <!-- 正在播放的视频
                      <div
                        class="content-section content-section-choose"
                        style=" color: #00b38a;"
                        @click="playLesson"
                      >
                        <div class="section-item clearfix">
                          <span class="kw-icon-video section-type-icon fl"
                            ><i class="el-icon-video-play"></i
                          ></span>
                          <span class="section-dec">2.起步</span>
                          <span class="section-status-icon pause-play"></span>
                        </div>
                        <div class="section-duration">
                          <span>时长:0</span>
                        </div>
                      </div> -->
                      </div>
                    </div>
    
                    <!-- 其余章节 -->
                    <div v-else>
                      <div class="content-label">
                        <div class="content-label-title single-line">
                          {{ section.sectionName }}
                        </div>
                        <img
                          class="arrow-icon"
                          src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAGFBMVEVHcEz///////////////////////////8dS1W+AAAAB3RSTlMAgwWyMeGgBsFrrQAAAFVJREFUKM9jYBiugMUBQ0i8EF2EsbxcAF1ReXkhuqJiczRl4uVGyqjKgIoUmFCVARUxMKAoAyliYEBRBlaEqiwcpAikrBShKglCqyFUMcEYCgwjBAAAeaoQrHtg6QoAAAAASUVORK5CYII="
                          alt=""
                        />
                      </div>
    
                      <div
                        class="content-sections"
                        v-for="(lesson, index) in section.courseLessons"
                        :key="index"
                      >
                        <!-- 其余课时视频 -->  
                        <div >
                          <!-- 未播放的视频 -->
                          <div class="content-section" @click="playLesson">
                            <div class="section-item clearfix">
                              <span class="kw-icon-video section-type-icon fl"
                                ><i class="el-icon-video-play"></i
                              ></span>
                              <span class="section-dec need-update">{{
                                lesson.theme
                              }}</span>
                            <!-- 课时状态 -->
                              <!-- 如果未登录,可以试看前两节课时 -->
                               <span  v-if="!isLogin" class="section-status-icon pause-play">未解锁</span>
                              <!-- 如果登录,且没有购买可以试看前两节课时 -->
                              <span  v-else-if="isLogin && !isBuy" class="section-status-icon pause-play">未解锁</span>
                              <!-- 如果登录,且购买, 可以播放前两节课时 -->
                              <span v-else class="section-status-icon pause-play">可播放</span>
                            </div>
                            <div class="section-duration">
                              <span v-if="lesson.courseMedia!=null">时长:{{lesson.courseMedia.duration}}</span>
                              <span v-else>时长:暂无视频</span>
                            </div>
                          </div>
                        </div>
    
                        <!-- 正在播放的视频
                      <div
                        class="content-section content-section-choose"
                        style=" color: #00b38a;"
                        @click="playLesson"
                      >
                        <div class="section-item clearfix">
                          <span class="kw-icon-video section-type-icon fl"
                            ><i class="el-icon-video-play"></i
                          ></span>
                          <span class="section-dec">2.起步</span>
                          <span class="section-status-icon pause-play"></span>
                        </div>
                        <div class="section-duration">
                          <span>时长:0</span>
                        </div>
                      </div> -->
                      </div>
                    </div>
    
                  </div>
                </div>
              </div>
  • 当前视频高亮突出
    <div class="content-container">
                  <div
                    v-for="(section, index) in course.courseSections"
                    :key="index"
                  >
                    <!-- 第一章节课时信息   -->
                    <div v-if="index<1">
                      <div class="content-label">
                        <div class="content-label-title single-line">
                          {{ section.sectionName }}
                        </div>
                        <img
                          class="arrow-icon"
                          src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAGFBMVEVHcEz///////////////////////////8dS1W+AAAAB3RSTlMAgwWyMeGgBsFrrQAAAFVJREFUKM9jYBiugMUBQ0i8EF2EsbxcAF1ReXkhuqJiczRl4uVGyqjKgIoUmFCVARUxMKAoAyliYEBRBlaEqiwcpAikrBShKglCqyFUMcEYCgwjBAAAeaoQrHtg6QoAAAAASUVORK5CYII="
                          alt=""
                        />
                      </div>
    
                      <div
                        class="content-sections"
                        v-for="(lesson, index) in section.courseLessons"
                        :key="index"
                      >
                        <!-- 前两节视频 -->
                        <div v-if="index < 2">
                          <!-- 未播放的视频 -->
                          <div :class="{
                            'content-section content-section-choose':lesson.id==lessonid,
                            'content-section':lesson.id!=lessonid
                          }" @click="playLesson">
                            <div class="section-item clearfix">
                              <span :class="{
                                'kw-icon-video section-type-icon fl  lv':lesson.id==lessonid,
                                'kw-icon-video section-type-icon fl':lesson.id!=lessonid
                              }"
                              ><i class="el-icon-video-play"></i
                              ></span>
                              <span :class="{
                                'section-dec lv':lesson.id==lessonid,
                                'section-dec  ':lesson.id!=lessonid
                              }"
                            >{{
                                lesson.theme
                              }}</span>
                            <!-- 课时状态 -->
                            <span v-if="lesson.id!=lessonid">
                              <!-- 如果未登录,可以试看前两节课时 -->
                               <span  v-if="!isLogin" class="section-status-icon pause-play">试看</span>
                              <!-- 如果登录,且没有购买可以试看前两节课时 -->
                              <span  v-else-if="isLogin&&!isBuy" class="section-status-icon pause-play">试看</span>
                              <!-- 如果登录,且购买, 可以播放前两节课时 -->
                              <span v-else class="section-status-icon pause-play">可播放</span>
                            </span>
                            <span v-else class="section-status-icon pause-play"></span>
                            
                            </div>
                            <div class="section-duration">
                              <span v-if="lesson.courseMedia!=null">时长:{{lesson.courseMedia.duration}}</span>
                              <span v-else>时长:暂无视频</span>
                            </div>
                          </div>
                        </div>
    
                        <!-- 其余课时视频 -->
                        <div v-else>
                          <!-- 未播放的视频 -->
                          <div :class="{
                            'content-section content-section-choose':lesson.id==lessonid,
                            'content-section':lesson.id!=lessonid
                          }" @click="playLesson">
                            <div class="section-item clearfix">
                              <span :class="{
                                'kw-icon-video section-type-icon fl  lv':lesson.id==lessonid,
                                'kw-icon-video section-type-icon fl':lesson.id!=lessonid
                              }"
                                ><i class="el-icon-video-play"></i
                              ></span>
                              <span :class="{
                                'section-dec  lv':lesson.id==lessonid,
                                'section-dec ':lesson.id!=lessonid
                              }"
                             >{{
                                lesson.theme
                              }}</span>
                            <!-- 课时状态 -->
                              <!-- 如果未登录,锁-->
                               <span  v-if="!isLogin" class="section-status-icon pause-play">未解锁</span>
                              <!-- 如果登录,锁 -->
                              <span  v-else-if="isLogin &&!isBuy" class="section-status-icon pause-play">未解锁</span>
                              <!-- 如果登录,且购买, 可以播放前两节课时 -->
                              <span>
                               <span v-if="lesson.id==lessonid" class="section-status-icon pause-play"></span>
                              <span v-else class="section-status-icon pause-play">可播放</span>
                              </span>
                            </div>
                            <div class="section-duration">
                              <span v-if="lesson.courseMedia!=null">时长:{{lesson.courseMedia.duration}}</span>
                              <span v-else>时长:暂无视频</span>
                            </div>
                          </div>
                        </div>
    
                       
                      </div>
                    </div>
    
                    <!-- 其余章节 -->
                    <div v-else>
                      <div class="content-label">
                        <div class="content-label-title single-line">
                          {{ section.sectionName }}
                        </div>
                        <img
                          class="arrow-icon"
                          src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAGFBMVEVHcEz///////////////////////////8dS1W+AAAAB3RSTlMAgwWyMeGgBsFrrQAAAFVJREFUKM9jYBiugMUBQ0i8EF2EsbxcAF1ReXkhuqJiczRl4uVGyqjKgIoUmFCVARUxMKAoAyliYEBRBlaEqiwcpAikrBShKglCqyFUMcEYCgwjBAAAeaoQrHtg6QoAAAAASUVORK5CYII="
                          alt=""
                        />
                      </div>
    
                      <div
                        class="content-sections"
                        v-for="(lesson, index) in section.courseLessons"
                        :key="index"
                      >
                        <!-- 其余课时视频 -->  
                        <div >
                          <!-- 未播放的视频 -->
                          <div :class="{
                            'content-section content-section-choose':lesson.id==lessonid,
                            'content-section':lesson.id!=lessonid
                          }"  @click="playLesson">
                            <div class="section-item clearfix">
                              <span :class="{
                                'kw-icon-video section-type-icon fl  lv':lesson.id==lessonid,
                                'kw-icon-video section-type-icon fl':lesson.id!=lessonid
                              }"
                                ><i class="el-icon-video-play"></i
                              ></span>
                              <span :class="{
                                'section-dec  lv':lesson.id==lessonid,
                                'section-dec ':lesson.id!=lessonid
                              }">{{
                                lesson.theme
                              }}</span>
                            <!-- 课时状态 -->
                              <!-- 如果未登录,可以试看前两节课时 -->
                               <span  v-if="!isLogin" class="section-status-icon pause-play">未解锁</span>
                              <!-- 如果登录,且没有购买可以试看前两节课时 -->
                              <span  v-else-if="isLogin && !isBuy" class="section-status-icon pause-play">未解锁</span>
                              <!-- 如果登录,且购买, 可以播放前两节课时 -->
                               <span>
                               <span v-if="lesson.id==lessonid" class="section-status-icon pause-play"></span>
                              <span v-else class="section-status-icon pause-play">可播放</span>
                              </span>
                            </div>
                            <div class="section-duration">
                              <span v-if="lesson.courseMedia!=null">时长:{{lesson.courseMedia.duration}}</span>
                              <span v-else>时长:暂无视频</span>
                            </div>
                          </div>
                        </div>
    
                    
                      </div>
                    </div>
    
                  </div>
                </div>
  • 点击课标题切换视频并播放     

<template>
  <div id="videoDetail">
    <div class="detail-container">
      <div class="left-container top-container">
        <nav class="nav">
          <div class="nav-back" @click="goBack">
            <span class="kw-icon-back"> &lt; </span>
            <span style="">&nbsp;返回</span>
          </div>
          <!-- 播放导航页显示 -->
          <span style="position:absolute;left:80px;">
            {{ course.courseName }} >{{ lessonName }}
          </span>
        </nav>
        <!-- 视频播放键 -->
        <div class="video-content calc">
          <div class="video-container">
            <div
              id="player-video-vontainer"
              class="player-container video-container"
            >
              <div
                style="min-width:750px;min-height:550px;"
                class="video"
                @click="play"
              >
                <video
                  style="width: 100%; height: 100%;"
                  id="myvideo"
                  src="https://video.pearvideo.com/mp4/adshort/20200901/cont-1693694-15359233_adpkg-ad_hd.mp4"
                  @canplay="getInit"
                  @timeupdate="handlerNowTime"
                />


                <!-- <div class="controls">
                  <div class="con_left"> -->
                    <!-- 播放 -->
                    <!-- <i
                      :class="{
                        'el-icon-video-play': !isplay,
                        'el-icon-video-pause': isplay,
                      }"
                      @click="play"
                      style="font-size:40px"
                    ></i>
                    <span>{{ nowTime }}/{{ totalTime }}</span>
                  </div>
                  <div class="con_right"> -->
                    <!-- 音量 -->
                    <!-- <i
                      class="el-icon-headset"
                      @click="play"
                      style="font-size:40px"
                    ></i> --> -->
                    <!-- 全屏 -->
                   <!-- <i
                      class="el-icon-monitor"
                      @click="play"
                      style="font-size:40px"
                    ></i>
                  </div>
                </div> -->


              </div>
            </div>
          </div>
        </div>

        
      </div>

      <!-- 右侧视频导航栏 -->
      <div class="right-container bottom-container">
        <div style="height: 100%;">
          <div class="detail-part-content-title">课程目录</div>
          <div class="study-percent-tip">
            <div class="week-progress">
              <img
                class="video-book"
                src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADgAAAA4CAYAAACohjseAAADHUlEQVRoQ+2a30sUURTHv3dMS60Xg8AIQV+ChCBmJqInqXAx6iXah6CghzCkiMz8C3qJfllRhNJDEEWwEUFFJBW9KMbMEAkWvbjgg0FRYO76o92dE1Ma686d8c4y7rrDncfdc+85n3t+zL1zD0PEHxZxPkjASvewsAd1XW8lohNE1A6gCcD6EsOnAEwwxgYZY3cNwxgT0b8sYDwer0kmk9eIqAuAIjJpCWRsxtid5ubmc4lE4refPl9AB258fPwlgD0lMLoYFW9bWlo6/CB9ATVNu0VEp4rRXKoxjLHbpmme9tLnCejknG3bo6soLL0YbEVRtnvlpCegpml9RHSWM2sGwCvG2KSIl4ioU0SuUIYxNpD/GxFtBhADUM2RvW6aZjdPjyegqqpOldpWMCijKEqbYRjDokarqkqisvlylmW5bNN1fbdt2+84kJ8sy2oNCjjNeRU8tyzrYBCDwwR09Kqq+gzAgQIbUpZlbQgK6Fp5J2xM0zxZTkBN0/p5Yc/zuGOnX4hKQBFPhh2i0oMFqx5qiNJIx5acbV8CoY1AjY6uXWd+iDjaJTNycyN33IUHqZkX7+frCv9c8RxcgPtIRA35ysMGvPgojafDcy74FQfMDsceEtGRQs3RARyKTS6GpYgH69b9y46ZOf4+wCtEy+bBzFA711KeB/fuqEH3ofq/gH1P0njzwX3iqUjApk1V6I3XQ9+6dDtpfMngciKNiW+5/86vKMC11QzH22txbF8t1lTxi2o2B9x/PYt7g7OYzxAqBvD8wDR6DtejsUHsY8DXnzauPk7jSid3a4lVl4NFvQR9BknAldrJeFVR6cGAKyBDVIbowgrwznF+J3qZgwFzzUtc5qDMQZmD/M+GssjIIiO2ArKKyioqq6isomLVokgpWWQCFJlAF6CletH39P/C0Jhzi77kKeoCNNAVdikAR5NZdN2YQs52xXfwK+ygTQj7d9Ycra5irlufIlPNNez7VA4jnzM8ODDGgjchRL6NxFnCSDcCOYCRb+VahIxsM15+pke2nTKsKliueZbtFy2XYWHplYBhrWS55vkDgsoDZgBZavwAAAAASUVORK5CYII="
                alt=""
              />
              <span class="progress-label">{{ course.courseName }}</span>
            </div>
          </div>

          <!-- 章节目录 -->
          <div class="detail-part-content-pc calc detail-part-content">
            <div class="content-fold">
              <div class="content-fold-img"></div>
            </div>
            <div class="content-container">
              <div
                v-for="(sectionindexin course.courseSections"
                :key="index"
              >
                <!-- 第一章节课时信息   -->
                <div v-if="index<1">
                  <div class="content-label">
                    <div class="content-label-title single-line">
                      {{ section.sectionName }}
                    </div>
                    <img
                      class="arrow-icon"
                      src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAGFBMVEVHcEz///////////////////////////8dS1W+AAAAB3RSTlMAgwWyMeGgBsFrrQAAAFVJREFUKM9jYBiugMUBQ0i8EF2EsbxcAF1ReXkhuqJiczRl4uVGyqjKgIoUmFCVARUxMKAoAyliYEBRBlaEqiwcpAikrBShKglCqyFUMcEYCgwjBAAAeaoQrHtg6QoAAAAASUVORK5CYII="
                      alt=""
                    />
                  </div>

                  <div
                    class="content-sections"
                    v-for="(lessonindexin section.courseLessons"
                    :key="index"
                  >
                    <!-- 前两节视频 -->
                    <div v-if="index < 2">
                      <!-- 未播放的视频 -->
                      <div :class="{
                        'content-section content-section-choose':lesson.id==lessonid,
                        'content-section':lesson.id!=lessonid
                      }" @click="playLesson(indexlesson1)">
                        <div class="section-item clearfix">
                          <span :class="{
                            'kw-icon-video section-type-icon fl  lv':lesson.id==lessonid,
                            'kw-icon-video section-type-icon fl':lesson.id!=lessonid
                          }"
                          ><i class="el-icon-video-play"></i
                          ></span>
                          <span :class="{
                            'section-dec lv':lesson.id==lessonid,
                            'section-dec  ':lesson.id!=lessonid
                          }"
                        >{{
                            lesson.theme
                          }}</span>
                        <!-- 课时状态 -->
                        <span v-if="lesson.id!=lessonid">
                          <!-- 如果未登录,可以试看前两节课时 -->
                           <span  v-if="!isLogin" class="section-status-icon pause-play">试看</span>
                          <!-- 如果登录,且没有购买可以试看前两节课时 -->
                          <span  v-else-if="isLogin&&!isBuy" class="section-status-icon pause-play">试看</span>
                          <!-- 如果登录,且购买, 可以播放前两节课时 -->
                          <span v-else class="section-status-icon pause-play">可播放</span>
                        </span>
                        <span v-else class="section-status-icon pause-play"></span>
                        
                        </div>
                        <div class="section-duration">
                          <span v-if="lesson.courseMedia!=null">时长:{{lesson.courseMedia.duration}}</span>
                          <span v-else>时长:暂无视频</span>
                        </div>
                      </div>
                    </div>

                    <!-- 其余课时视频 -->
                    <div v-else>
                      <!-- 未播放的视频 -->
                      <div :class="{
                        'content-section content-section-choose':lesson.id==lessonid,
                        'content-section':lesson.id!=lessonid
                      }" @click="playLesson(indexlesson1)">
                        <div class="section-item clearfix">
                          <span :class="{
                            'kw-icon-video section-type-icon fl  lv':lesson.id==lessonid,
                            'kw-icon-video section-type-icon fl':lesson.id!=lessonid
                          }"
                            ><i class="el-icon-video-play"></i
                          ></span>
                          <span :class="{
                            'section-dec  lv':lesson.id==lessonid,
                            'section-dec ':lesson.id!=lessonid
                          }"
                         >{{
                            lesson.theme
                          }}</span>
                        <!-- 课时状态 -->
                          <!-- 如果未登录,锁-->
                           <span  v-if="!isLogin" class="section-status-icon pause-play">未解锁</span>
                          <!-- 如果登录,锁 -->
                          <span  v-else-if="isLogin &&!isBuy" class="section-status-icon pause-play">未解锁</span>
                          <!-- 如果登录,且购买, 可以播放前两节课时 -->
                          <span>
                           <span v-if="lesson.id==lessonid" class="section-status-icon pause-play"></span>
                          <span v-else class="section-status-icon pause-play">可播放</span>
                          </span>
                        </div>
                        <div class="section-duration">
                          <span v-if="lesson.courseMedia!=null">时长:{{lesson.courseMedia.duration}}</span>
                          <span v-else>时长:暂无视频</span>
                        </div>
                      </div>
                    </div>

                   
                  </div>
                </div>

                <!-- 其余章节 -->
                <div v-else>
                  <div class="content-label">
                    <div class="content-label-title single-line">
                      {{ section.sectionName }}
                    </div>
                    <img
                      class="arrow-icon"
                      src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAGFBMVEVHcEz///////////////////////////8dS1W+AAAAB3RSTlMAgwWyMeGgBsFrrQAAAFVJREFUKM9jYBiugMUBQ0i8EF2EsbxcAF1ReXkhuqJiczRl4uVGyqjKgIoUmFCVARUxMKAoAyliYEBRBlaEqiwcpAikrBShKglCqyFUMcEYCgwjBAAAeaoQrHtg6QoAAAAASUVORK5CYII="
                      alt=""
                    />
                  </div>

                  <div
                    class="content-sections"
                    v-for="(lessonindexin section.courseLessons"
                    :key="index"
                  >
                    <!-- 其余课时视频 -->  
                    <div >
                      <!-- 未播放的视频 -->
                      <div :class="{
                        'content-section content-section-choose':lesson.id==lessonid,
                        'content-section':lesson.id!=lessonid
                      }"  @click="playLesson(indexlesson2)">
                        <div class="section-item clearfix">
                          <span :class="{
                            'kw-icon-video section-type-icon fl  lv':lesson.id==lessonid,
                            'kw-icon-video section-type-icon fl':lesson.id!=lessonid
                          }"
                            ><i class="el-icon-video-play"></i
                          ></span>
                          <span :class="{
                            'section-dec  lv':lesson.id==lessonid,
                            'section-dec ':lesson.id!=lessonid
                          }">{{
                            lesson.theme
                          }}</span>
                        <!-- 课时状态 -->
                          <!-- 如果未登录,可以试看前两节课时 -->
                           <span  v-if="!isLogin" class="section-status-icon pause-play">未解锁</span>
                          <!-- 如果登录,且没有购买可以试看前两节课时 -->
                          <span  v-else-if="isLogin && !isBuy" class="section-status-icon pause-play">未解锁</span>
                          <!-- 如果登录,且购买, 可以播放前两节课时 -->
                           <span>
                           <span v-if="lesson.id==lessonid" class="section-status-icon pause-play"></span>
                          <span v-else class="section-status-icon pause-play">可播放</span>
                          </span>
                        </div>
                        <div class="section-duration">
                          <span v-if="lesson.courseMedia!=null">时长:{{lesson.courseMedia.duration}}</span>
                          <span v-else>时长:暂无视频</span>
                        </div>
                      </div>
                    </div>

                
                  </div>
                </div>

              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "videoDetail",
  components: {},
  data() {
    return {
      myvideo: null// 播放器对象
      isplay: false//是否在播放
      nowTime: "00:00"//当前播放时间
      totalTime: "00:00"//总时长
      course: null//课程信息
      lessonid: 0//课时ID
      lessonName: ""//课时名称
      isLogin: false//是否登录
      isBuy: false//是否购买
    };
  },
  computed: {},
  created() {
     // 获取用户登录信息
    this.user = JSON.parse(localStorage.getItem("user"));
    // 如果用户不为空,说明登录
    if (this.user != null) {
      this.isLogin = true;
    }
    // 接收课程课时
    this.course = this.$route.params.course;
    this.lessonid = this.$route.params.lessonid;
    this.isBuy=this.$route.params.isBuy;
    console.log(this.isBuy);

  },
  mounted() {
    this.myvideo = document.getElementById("myvideo");
    //初始化控制视频模板
    this.myvideo.controls=true;
    this.initPlay();// 初始化播放的视频
  },
  methods: {
    play() {
      this.isplay = !this.isplay;
      if (this.isplay) {
        this.myvideo.play();
      } else {
        this.myvideo.pause();
      }
    },
    // 获取视频的时间是秒为单位,格式化城00:00的格式
    formatTime(time) {
      let mm = Math.floor((time % 3600) / 60);
      let ss = Math.floor(time % 60);
      mm = mm < 10 ? "0" + mm : mm;
      ss = ss < 10 ? "0" + ss : ss;
      return `${mm}:${ss}`;
    },
    //获取初始化信息
    getInit() {
      if (!this.myvideo) {
        //获取失败,显示0
        this.totalTime = this.formatTime(0);
      } else {
        //获取视频总时长
        this.totalTime = this.formatTime(this.myvideo.duration);
      }
    },
    //播放时显示当前播放时间和总时长
    handlerNowTime() {
      if (!this.myvideo) {
        this.nowTime = `${this.formatTime(0)}`;
      }
      this.nowTime = this.formatTime(this.myvideo.currentTime || 0);
    },
    //返回
    goBack() {
      this.$router.push({ name: "Course" ,params:{
        course:this.course
      }});
    },
    //播放课程
    playLesson(indexlessonstatus) {
        // status是否是第一章节
      if (status == 1 && index < 2) {
        this.playVideo(lesson);
      }
      // 是否是免费试看的章节
      else {
        //不是免费试看的章节
        //  先登录
        if (!this.isLogin) {
          this.$message.warning("请登录账号");
        } else {
          //  查看该章节是否被购买
          if (!this.isBuy) {
            this.$message.warning("请先购买");
          } else {
          this.playVideo(lesson);
          }
        }
      }
    
    },
    // 播放
    playVideo(lesson){
       // 判断是否有视频
      if(lesson.courseMedia==null){
        this.$message.error("暂无视频源");
      }
      else{
        // 视频ID
        this.lessonid=lesson.id;     
      // 视频地址
      this.myvideo.src=lesson.courseMedia.fileEdk;
      this.myvideo.play();
      // 视频切换状态
      this.isplay=true;
      }
    },
    // 初始播放的视频
    initPlay() {
      for (let i = 0i < this.course.courseSections.lengthi++) {
        let section = this.course.courseSections[i];
        for (let j = 0j < section.courseLessons.lengthj++) {
          let lesson = section.courseLessons[j];
          if (lesson.courseMedia != null) {
            if (this.lessonid == lesson.courseMedia.lessonId) {
              this.myvideo.src = lesson.courseMedia.fileEdk;
              this.myvideo.play();
              this.isplay=true;
              this.lessonName = lesson.theme;
              return;
            }
          }
        }
      }
    },
  },
};
</script>

<style lang="less">
.lv{
  color#00b38a;
}
.video {
  positionrelative;
  video {
    width100%;
    height100%;
  }
  .controls {
    width100%;
    height40px;
    positionabsolute;
    bottom0;
    left0;
    backgroundrgba(0000.5);
    displayflex;
    justify-contentspace-between;
    align-itemscenter;
    span {
      padding0 5px;
      color#fff;
    }
  }
}

.detail-container {
  height100%;
}
* {
  -webkit-tap-highlight-colortransparent;
}
* {
  margin0;
  padding0;
}
div {
  displayblock;
}
.left-container {
  margin-right380px;
  -webkit-transitionmargin-right 0.3s ease 0s;
  transitionmargin-right 0.3s ease 0s;
  height100%;
  overflow-yauto;
}
.left-container .nav {
  height60px;
  line-height60px;
  background#32373e;
  font-size14px;
  font-weight400;
  color#fff;
  padding-left80px;
  positionrelative;
}

.left-container .video-content {
  positionrelative;
  background#272c30;
  overflow-xhidden;
}
.calc {
  heightcalc(100% - 60px);
}
.left-container .nav-back {
  positionabsolute;
  top1px;
  left10px;
  cursorpointer;
  &:hover {
    color#00b38a;
  }
}
[class*=" kw-icon-"],
[class^="kw-icon-"] {
  font-familykw-icon !important;
  speaknone;
  font-stylenormal;
  font-weight400;
  -webkit-font-feature-settingsnormal;
  font-feature-settingsnormal;
  font-variantnormal;
  text-transformnone;
  line-height1;
  -webkit-font-smoothingantialiased;
  -moz-osx-font-smoothinggrayscale;
}
.video-container {
  positionrelative;
  height100%;
  background#272c30;
}
.right-container {
  positionabsolute;
  top0;
  right0;
  width380px;
  height100%;
  background-color#32373e;
  -webkit-transitionright 0.3s ease 0s;
  transitionright 0.3s ease 0s;
}
.detail-part-content-title {
  height60px;
  line-height60px;
  background#40464d;
  font-size18px;
  font-weight500;
  color#fff;
  padding-left20px;
  positionrelative;
  z-index10;
  text-alignleft;
}
.study-percent-tip {
  displaynone;
}
img {
  border0;
  vertical-aligntop;
  displayinline-block;
}
.detail-part-content-pc .content-fold {
  positionabsolute;
  left-24px;
  top50%;
  -webkit-transformtranslateY(-50%);
  transformtranslateY(-50%);
  width24px;
  height100px;
  background-colorrgba(5055620.7);
  border-radius8px 0 0 8px;
  z-index1;
}
.detail-part-content-pc .content-fold-img {
  backgroundurl(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkBAMAAAATLoWrAAAAGFBMV…AoAyliYEBRBlaEqiwcpAikrBShKglCqyFUMcEYCgwjBAAAeaoQrHtg6QoAAAAASUVORK5CYII=)
    no-repeat;
  width18px;
  height18px;
  positionabsolute;
  left50%;
  top50%;
  -webkit-transformtranslate(-50%-50%rotate(90deg);
  transformtranslate(-50%-50%rotate(90deg);
  background-sizecontain;
  -webkit-transitionall 0.3s ease 0s;
  transitionall 0.3s ease 0s;
}
.detail-part-content-pc .content-label {
  positionrelative;
  height60px;
  line-height60px;
  font-size14px;
  font-weight400;
  color#fff;
  padding0 10px;
  background#2b3035;
  border-radius4px;
  margin-top10px;

  text-alignleft;
  text-indent10px;
}
.detail-part-content-pc .content-label-title {
  width310px;
  height60px;
}
.single-line {
  overflowhidden;
  white-spacenowrap;
  text-overflowellipsis;
}
.detail-part-content-pc .arrow-icon {
  width18px;
  height18px;
  positionabsolute;
  top21px;
  right10px;
  -webkit-transitionall 0.3s ease;
  transitionall 0.3s ease;
  -webkit-transformrotate(180deg);
  transformrotate(180deg);
}
img {
  border0;
  vertical-aligntop;
  displayinline-block;
}
.detail-part-content-pc .content-sections {
  -webkit-transitionall 1s ease;
  transitionall 1s ease;
}
.detail-part-content-pc .content-section {
  padding15px 10px;
  color#fff;
  font-size14px;
  min-height40px;
  border-bottom1px solid #272c30;
  font-familynone;
  opacity0.7;
}
.detail-part-content-pc .section-item {
  positionrelative;
  text-alignleft;
}
.detail-part-content-pc .section-type-icon {
  font-size16px;
  vertical-alignmiddle;
  margin4px 10px 0 0;
}

.fl {
  floatleft;
}
.detail-part-content-pc .need-update {
  color#989b9e;
}

.detail-part-content-pc .section-dec {
  max-width270px;
  displayinline-block;
  vertical-alignbottom;
  word-breakbreak-all;
}
.detail-part-content-pc .section-status-icon {
  font-size12px;
  positionabsolute;
  right0;
  top1px;
  color#989b9e;
}
.detail-part-content-pc .section-duration {
  font-size12px;
  margin-top4px;
  padding-left26px;
  colorhsla(00%100%0.7);
  text-alignleft;
}
.detail-part-content-pc .content-section-choose .pause-play {
  width18px;
  height18px;
  backgroundurl(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAFoCAYAAABaAKtEAAAEPUlEQVR4Xu1dPW8TQRB9ZwLBTkF+AeIf0CMK6JAiGyr+A10UyU6gOmhCYomvAokCRAOFm0S6CEVponQUSCDRgpQCCYmCLwWRKIkPXcBRvN7zzk42x+5l3ObueWbu3tuZ2VkngqNP5AgHBQEt3B/HyPY3AA9Rb00Os364RQKUxa4/Rsl82hdYdowECGoI2MF2AtSJT6Fa21JpUxBpLTRGLDIHa3iMOveqqO7MAtEa6s0FUUhggIwibHzxT+bXkeIZGq07vXeLt4o4EbbMBCdAopBm4cm5IjTNTtMIiw/OYDvdwvWp3yErpCRauqfH1KP2O6D7AvXpdpmEzZlCvno0it3NTckh7YXSd4XUrKBUJ4dzjYpirI7YWW3hCpnMxahErzHRWhYZyenWOMnYnAmbM6DV+DQ2allC0dec8p39FiRVLxXXzMGzj9FqPIKNsYvo7nzC1Zsf9DJi/mIgp861t4gFpLuJBJS0nwNYQb35cs9LPhChoUmzSIA0XXf7PJsUbMqbXZJS1MJVe9IWGyP/c8i95bk6o2Zn7ipIDZI9RXKstAcicY2SHguQeVus2BhZyIZkbPbB8l1ql+5ewG765WBuSHVyuIywO6MUGclMXGpPopu+RaO1JsXx8SqOpcqmcnTgOt/1iO2YOoDiDEjVoyMXNiepHylhp0qtM4vUatzYq83bXS9p18+ZsDkDkp0atpCUQWrjuILzo2dRHf2JK1NfQ20f6p4hqcxSb9RV1Cwgdh9StYgNlCh71HwgaWgaG5psETmytEYsMjfrnMUoaV9Sd2Co2AVtiuvYn6393a0bh6+ySQpJSUYFyLf2obOnRuWDsRYRoAKFjZIfkUpRSloTKBCFIiTXBAglnRhP4hpQ+yXTPvbiXYYqm8V+i1DZb/iyLArjKMwe18Ye900FsfqQkoz6loxaUEK99NjISLgxWpg9d/g+JKkxTo2RcRfiyIB6M+wVLB+cDjefX8vLs9NoDo3mzP6frV3j79QQ+pCkp0ZNj42uhQkkE+NUtg1cVxbxN77Z1AiVAKi3TT/+YxOX4+yo2d+PtWv7wpbeRn06dgAUzaLevOUASPnhEr5rtkCikP+xx0Yl8UBRY3GjpMf2weKtIsncNVTSj5iYed/7yn4gdc4x7/iikf1hkpak2eKaeV2jxEhySHva/7uDx37N14UGFMZRmBI3NDPXluYX0Y0SNJpP9asIhf3OpJY0NEixKNAWK1tEZNqHErrQFDKcH5wwLkcU0voptX4ppDOp9Q+IJP4UmpPeIwEqcydCMzfJE39jcaxG0X370LrHRvjlCv/YLxaZN8WlymarNo/9xrSGbU9hCTt7tkZ1jQ0UbupnfPyFu6aevWHNH/kntZ3OCVTXd4aPMVKCTar7/SethYXHVtjCiNGbJyfx+fuE3U4N+7CgM4oIkO4/fNiPw5L0yL9gW3BLvdQ/PfoDa+yS8O1qaS0AAAAASUVORK5CYII=)
    no-repeat;
  background-sizecover;
  background-position0 0;
  color#00b38a;
}
.detail-part-content-pc .content-section:last-of-type {
  border-bottomnone;
  margin-bottom25px;
}
.detail-part-content-pc .content-section:hover {
  background#2b3035;
  cursorpointer;
}
.detail-part-content-pc .content-section-choose{
  color#00b38a;
}
.detail-part-content-pc .content-section-choose .section-status-icon{
  color#00b38a;
}

.kw-icon-video:before {
  // content: "\E903";
}
.detail-part-content-pc .content-section {
  padding15px 10px;
  color#fff;
  font-size14px;
  min-height40px;
  border-bottom1px solid #272c30;
  font-familynone;
  opacity0.7;
}
</style>
 

6. 留言点赞

  • 后端修改
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="mapper.CourseCommentDao">
    
        <resultMap type="entity.CourseComment" id="CourseCommentMap">
            <result property="id" column="cc_id" jdbcType="VARCHAR"/>
            <result property="courseId" column="course_id" jdbcType="INTEGER"/>
            <result property="sectionId" column="section_id" jdbcType="INTEGER"/>
            <result property="lessonId" column="lesson_id" jdbcType="INTEGER"/>
            <result property="userId" column="cc_user_id" jdbcType="INTEGER"/>
            <result property="userName" column="user_name" jdbcType="VARCHAR"/>
            <result property="parentId" column="parent_id" jdbcType="INTEGER"/>
            <result property="isTop" column="is_top" jdbcType="VARCHAR"/>
            <result property="comment" column="comment" jdbcType="VARCHAR"/>
            <result property="likeCount" column="like_count" jdbcType="INTEGER"/>
            <result property="isReply" column="is_reply" jdbcType="VARCHAR"/>
            <result property="type" column="type" jdbcType="INTEGER"/>
            <result property="status" column="status" jdbcType="INTEGER"/>
            <result property="createTime" column="cc_create_time" jdbcType="TIMESTAMP"/>
            <result property="updateTime" column="cc_update_time" jdbcType="TIMESTAMP"/>
            <result property="isDel" column="cc_is_del" jdbcType="VARCHAR"/>
            <result property="lastOperator" column="last_operator" jdbcType="INTEGER"/>
            <result property="isNotify" column="is_notify" jdbcType="VARCHAR"/>
            <result property="markBelong" column="mark_belong" jdbcType="VARCHAR"/>
            <result property="replied" column="replied" jdbcType="VARCHAR"/>
        <collection property="favoriteRecordList" ofType="entity.CourseCommentFavoriteRecord">
            <result property="id" column="ccfr_id" jdbcType="INTEGER"/>
            <result property="userId" column="ccfr_user_id" jdbcType="INTEGER"/>
            <result property="commentId" column="comment_id" jdbcType="INTEGER"/>
            <result property="isDel" column="ccfr_is_del" jdbcType="VARCHAR"/>
            <result property="createTime" column="ccfr_create_time" jdbcType="TIMESTAMP"/>
            <result property="updateTime" column="ccfr_update_time" jdbcType="TIMESTAMP"/>
        </collection>
        </resultMap>
    <insert id="saveCourseComment">
    --   `parent_id` int(11) DEFAULT NULL COMMENT '父级评论id',
    --   `is_top` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否置顶:0不置顶,1置顶',
    --  `like_count` int(11) NOT NULL DEFAULT '0' COMMENT '点赞数',
    --   `is_reply` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否回复留言:0普通留言,1回复留言',
    --   `type` int(1) NOT NULL COMMENT '留言类型:0用户留言,1讲师留言,2运营马甲 3讲师回复 4小编回复 5官方客服回复',
    --   `status` int(1) NOT NULL COMMENT '留言状态:0待审核,1审核通过,2审核不通过,3已删除',
    --   `is_del` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除',0未删除 1已删除
    -- `is_notify` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否发送了通知,1表示未发出,0表示已发出',
    --   `mark_belong` tinyint(1) DEFAULT '0' COMMENT '标记归属',
    --   `replied` tinyint(1) DEFAULT '0' COMMENT '回复状态 0 未回复 1 已回复',
          insert  into course_comment(course_id,section_id,lesson_id,user_id,user_name,parent_id,is_top,comment,like_count,is_reply,type,status,create_time,update_time,is_del,last_operator,is_notify,mark_belong,replied) values
        (#{courseId},#{sectionId},#{lessonId},#{userId},#{userName},#{parentId},0,#{comment},0,0,#{type},0,sysdate(),sysdate(),0,#{lastOperator},1,0,0)
    </insert>
    
    <select id="getCourseCommentList" resultMap="CourseCommentMap">
       select
    cc.id cc_id, cc.course_id, cc.section_id, cc.lesson_id, cc.user_id cc_user_id, cc.user_name, cc.parent_id, cc.is_top, cc.comment, cc.like_count, cc.is_reply, cc.type, cc.status, cc.create_time cc_create_time, cc.update_time cc_update_time, cc.is_del cc_is_del, cc.last_operator, cc.is_notify, cc.mark_belong, cc.replied,
    ccfr.id ccfr_id, ccfr.user_id ccfr_user_id, ccfr.comment_id, ccfr.is_del ccfr_is_del, ccfr.create_time ccfr_create_time, ccfr.update_time ccfr_update_time
    from course_comment cc
             left join (select * from course_comment_favorite_record where is_del=0) ccfr
    on cc.id=ccfr.comment_id
         where cc.course_id= #{courseId} and  cc.is_del= 0
    order by cc.is_top desc,cc.like_count desc,cc.create_time desc
        limit #{offset},#{pageSize}
    </select>
    
        <!--查看某个用户的某条留言是否存在点赞信息-->
    <select id="existsFavourite" resultType="int">
        select count(*) from course_comment_favorite_record
            where user_id=#{userId} and comment_id=#{commentId}
    </select>
    
        <!--没有点赞信息,保存点赞信息-->
        <insert id="saveCommentFavourite">
        insert into course_comment_favorite_record (user_id, comment_id, is_del, create_time, update_time)
            values (#{userId},#{commentId},0,sysdate(),sysdate())
        </insert>
        <!--修改点赞的状态,0表示点赞,1表示取消赞-->
        <update id="updateCommentFavourite">
        update course_comment_favorite_record set is_del=#{isDel} where comment_id=#{commentId} and user_id=#{userId}
        </update>
        <!--点赞之后,赞的数量+1;取消赞之后,赞的数量-1-->
       <update id="updateCommentLikeCount">
            update course_comment set like_count =like_count+ #{x} where id=#{commentId}
       </update>
    
    </mapper>
     @Test
        public void getComment(){
            List<CourseComment> list = courseCommentDao.getCourseCommentList(7, 0, 20);
            for(CourseComment comment : list){
                System.out.println("【"+comment.getUserName()+"】"+"留言:" +
                        comment.getComment());
                for(CourseCommentFavoriteRecord fr: comment.getFavoriteRecordList()){
                    System.out.println("--->" + fr.getUserId());
                }
            }
        }
    package controller;
    
    import com.alibaba.dubbo.config.annotation.Reference;
    import course.service.CourseCommentService;
    import entity.CourseComment;
    import org.springframework.web.bind.annotation.CrossOrigin;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import java.io.UnsupportedEncodingException;
    import java.util.List;
    
    
    /**
     * 课程留言表(CourseComment)表控制层
     *
     * @author rf
     * @since 2021-08-08 15:24:35
     */
    @RestController
    @CrossOrigin(origins = "*")
    @RequestMapping("/course/comment")
    public class CourseCommentController {
        @Reference
        private CourseCommentService courseCommentService;
    
        @RequestMapping("/saveCourseComment")
        public CourseComment saveCourseComment(Integer courseId,Integer userId,String username,String comment) throws UnsupportedEncodingException {
            username = new String( username.getBytes("ISO-8859-1"),"UTF-8" );
            comment = new String( comment.getBytes("ISO-8859-1"),"UTF-8" );
            CourseComment courseComment = new CourseComment();
            courseComment.setCourseId(courseId); // 课程编号
            courseComment.setSectionId(0); // 章节编号,保留版本
            courseComment.setLessonId(0);// 小节编号,保留版本
            courseComment.setUserId(userId); // 用户编号
            courseComment.setUserName(username); // 用户昵称
            courseComment.setParentId(0); //没有父id,保留版本
            courseComment.setComment(comment);// 留言内容
            courseComment.setType(0); // 0用户留言,保留版本
            courseComment.setLastOperator(userId); //最后操作的用户编号
            Integer i = courseCommentService.saveCourseComment(courseComment);
            System.out.println(i);
            return courseComment;
        }
    
        @RequestMapping("/getCourseCommentList/{courseid}/{pageIndex}/{pageSize}")
        public List<CourseComment> getCommentsByCourseId(@PathVariable("courseid") Integer courseid, @PathVariable("pageIndex")Integer pageIndex,@PathVariable("pageSize")Integer pageSize){
            int offset=(pageIndex-1)*pageSize;
            List<CourseComment> list =
                    courseCommentService.getCourseCommentList(courseid, offset, pageSize);
            return list;
        }
    
        // 点赞
        @RequestMapping("/saveFavorite/{commentid}/{userid}")
        public Integer saveFavorite(@PathVariable("commentid") Integer commentid,@PathVariable("userid") Integer userid){
            Integer integer = courseCommentService.saveFavorite(userid,commentid);
            return integer;
        }
        // 取消赞
        @RequestMapping("/cancelFavorite/{commentid}/{userid}")
        public Integer cancelFavorite(@PathVariable("commentid") Integer commentid,@PathVariable("userid") Integer userid){
            Integer integer = courseCommentService.cancelFavorite(userid, commentid);
            return integer;
        }
    }
  • 前端样式显示、点赞取消赞、发表留言
<template>
  <div>
    <Header></Header>
    <div style="background: #eee;">
      <!-- 面包屑导航 -->
      <div class="nav-wrap">
        <p class="nav-p-pc" style="margin-top:-25px;text-align:left;">
          <a href="#">课程列表</a>
          <span class="sharp-content">&gt;</span>
          <span class="nav-sec">{{ course.courseName }}</span>
        </p>
      </div>

      <!-- 课程详情 -->
      <div class="container">
        <div style="height: 100%;">
          <div class="weui-tab content-wrapper">
            <div
              id="vux_view_box_body"
              class="weui-tab__panel vux-fix-safari-overflow-scrolling"
            >
              <div style="position: relative;">
                <div class="intro">
                  <div class="intro-content">
                    <img
                      class="course-img"
                      :src="course.courseImgUrl"
                      alt="课程图片"
                    />
                    <div class="conent-wrap">
                      <div class="name" style="text-align:left;">
                        {{ course.courseName }}
                      </div>
                      <div class="des text-omit" style="text-align:left;">
                        {{ course.brief }}
                      </div>
                      <div class="title">
                        <div class="teacher-name text-omit">
                          {{ course.teacher.teacherName }}
                          <span class="line"></span>
                          {{ course.teacher.position }}
                        </div>
                      </div>
                      <div class="lesson-info">
                        <div class="boook-icon backgroun-img-set"></div>
                        <div class="time">
                          {{ totalLesson }}讲 / {{ course.totalDuration }}课时
                        </div>
                        <div class="person-icon backgroun-img-set"></div>
                        <div class="person">{{ course.sales }}人已购买</div>
                      </div>
                    </div>
                  </div>
                </div>
              </div>

              <!-- 课程信息 -->
              <div class="public-class-container is-pc">
                <el-tabs v-model="activeName">
                  <el-tab-pane label="课程信息" name="intro">
                    <div
                      v-html="course.courseDescription"
                      class="content-p pc-background"
                    ></div>

                    <!-- 留言板 -->
                    <!-- 留言板 开始-->
                    <div class="message">
                      <div class="message-topic">
                        <div class="message-topic-title normal-font">
                          精选留言
                        </div>
                      </div>
                      <div>
                        <div class="message-edit">
                          <textarea
                            rows="20"
                            style="border:0px;resize: none;"
                            contenteditable="true"
                            placeholder="分享学习心得、思考感悟或者给自己一个小鼓励吧!"
                            class="edit-div pcStyle"
                            v-model="comment"
                          ></textarea>
                          <div class="message-edit-count">
                            <span class="message-edit-count-cur">0</span>
                            <span class="message-edit-count-max">/2000</span>
                          </div>
                        </div>
                        <div class="message-edit-footer flex">
                          <button class="message-edit-btn disableBg" @click="saveComment">
                            发表留言
                          </button>
                        </div>
                      </div>

                      <!-- 显示留言 -->
                      <!-- 留言 开始 -->
                      <div
                        class="message-list"
                        v-for="(comment, index) in commentList"
                        :key="index"
                      >
                        <div class="message-list-title">
                          <div class="message-list-title-left">
                            <div class="message-list-title-left-name">
                              {{ comment.userName }}
                            </div>
                            <div class="message-list-title-left-tag"></div>
                          </div>
                          <!-- 没有点过赞 -->
                          <div
                            v-if="
                              JSON.stringify(
                                comment.favoriteRecordList
                              ).indexOf(user.content.id) < 0
                            "
                            @click="zan(comment)"
                          >
                            <div class="message-list-title-right">
                              <!-- 未点赞图标 -->
                              <img
                                class="message-list-title-right-icon"
                                src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADgAAAA4BAMAAABaqCYtAAAAKlBMVEVHcExnZ2dzc3NmZmZqampmZmZmZmZnZ2dnZ2dnZ2dmZmZoaGhmZmZmZmZl+8SAAAAADXRSTlMA/AbsFtilbj5YwSqJPyESoQAAAZxJREFUOMt1lTtLA1EQha8xRhPTBEmhuKCCoNgoIlYLMcRKBG0sxIUgCDaBSDohEO0FEbQyIBZaBazERvAPWCwxPnP+i3tnrlGTmVPswn73NXNm7hrzq9m9kZ2ckTUUABifkOEBrK7liR7BMRFOA/uFc+BUgnV8mFisEW5IsIFi9FzBuwR91KJnAm8S9EIbxSBeBRZHk86MrBQJWjymJUC3nlugSyk+SQyhANfxos+s4krfM0DZvmbw2cuSCHNGi3PAfUygXYiU79ryyw1ibf0xZ9intBsz6SBadx24iiZXz8kPxCiTtYdLPzKTVFkkLQAZO/VikwYW/x/wHohcT/MiPQE8W9frxJrlbpiw4xvA0vbNmWyhj2Nrhmy+B7nEyTsN0rIaJAc0SDWqwX7rhAYfMa/Dui0bDZbwZAwUGNjWUWActnUUyN2hwDTaOkxRaSiwj6pRhjHKgTazSkWlwBK1jgIpBwrkHCgwyZ0oQ86BAjkHCjziG0KE8YBvCA/5KacOm6sgrHFAotouT6J23bkkLbsNDjM9yt7yP+IbQYga5De+eBMAAAAASUVORK5CYII="
                                alt=""
                              />

                              <div class="message-list-title-right-praise">
                                {{ comment.likeCount }}
                              </div>
                            </div>
                          </div>
                          <!-- 点过赞 -->
                          <div v-else @click="cancelzan(comment)">
                            <!-- 点赞图标 -->
                            <div class="message-list-title-right">
                              <img
                                class="message-list-title-right-icon"
                                src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADgAAAA4BAMAAABaqCYtAAAAJFBMVEVHcEwAuI4AtIsAtIsAtIoAtYwAtIsAtYwAtowAx5kAtIsAs4qd4c1kAAAAC3RSTlMAGMfz3VGnbTYIhXtDq8EAAAETSURBVDjLldWhb8JAFAbwg8CGhGSGzNQtULNkWUioWbJkpmYKAQaBITPLLKZysmLz+xfolUL6/XM72msh9N2X8ImaX17vrq+vVeqU39XTuK/kdEMA01jGDY4ZyYWFIRPxp0S8u+8KeBJ+WDxIGFrMJbQm7qhVYSJgr8JUwNsKtYDtCiHgPavcsDVDstsuyDk7NeYDk6G8pM3bWXNawQUijWq8QyPPpQy+50ET9bF09go5pus3cMV0feFEc2DfieZRBU7Up7fjSkwZZgz3DA8MHxl6DP8YRgxjgokimDHcMdwyfGG4ZPjJMCKoY4KJIpgz3DHcMvQYFuPpk/005t1mffHlOs/ETvxXAA0Ul3oQHsp/xD93wxfHcC4VkwAAAABJRU5ErkJggg=="
                                alt=""
                              />

                              <div class="message-list-title-right-praise">
                                {{ comment.likeCount }}
                              </div>
                            </div>
                          </div>
                        </div>
                        <div class="message-list-content">
                          {{ comment.comment }}
                        </div>
                      </div>
                      <!-- 留言 结束 -->
                    </div>
                    <!-- 留言板 结束-->
                  </el-tab-pane>

                  <!-- 目录框 -->
                  <el-tab-pane label="目录" name="directory">
                    <div
                      class="class-menu-contaniner list-page-container more-sections more-sections-padding"
                    >
                      <!-- 章 开始 -->
                      <div
                        v-for="(section, index) in course.courseSections"
                        :key="index"
                      >
                        <div class="section-name single-line">
                          {{ section.sectionName }}
                        </div>

                        <!-- 第一章节课时信息 -->
                        <div v-if="index < 1">
                          <div class="class-menu-block">
                            <div
                              v-for="(lesson, index) in section.courseLessons"
                              :key="index"
                              class="class-level-one over-ellipsis"
                              @click="watchCourse(index, lesson, 1)"
                            >
                              <!-- 前两节课时 -->
                              <div class="text-wrap">
                                <div class="content">{{ lesson.theme }}</div>
                                <div
                                  class="item-status-wrap item-status-wrap-list"
                                >
                                  <!-- 前两节课时 -->
                                  <div v-if="index < 2">
                                    <!-- 如果未登录,可以试看前两节课时 -->
                                    <div
                                      v-if="!isLogin"
                                      class="item-status test-watch"
                                    >
                                      试看
                                    </div>
                                    <!-- 如果登录,且没有购买可以试看前两节课时 -->
                                    <div
                                      v-else-if="isLogin && !isBuy"
                                      class="item-status test-watch"
                                    >
                                      试看
                                    </div>
                                    <!-- 如果登录,且购买, 可以播放前两节课时 -->
                                    <div v-else class="item-status test-watch">
                                      播放
                                    </div>
                                  </div>

                                  <!-- 其余课时 -->
                                  <div v-else>
                                    <!-- 如果未登录,加锁 -->
                                    <div
                                      v-if="!isLogin"
                                      class="item-status lock"
                                    ></div>
                                    <!-- 如果登录,且没有购买加锁 -->
                                    <div
                                      v-else-if="isLogin && !isBuy"
                                      class="item-status lock"
                                    ></div>
                                    <!-- 如果登录,且购买, 可以播放 -->
                                    <div v-else class="item-status test-watch">
                                      播放
                                    </div>
                                  </div>
                                </div>
                              </div>
                            </div>
                          </div>
                        </div>

                        <!-- 其余章节课时信息 -->
                        <div v-else>
                          <div class="class-menu-block">
                            <div
                              v-for="(lesson, index) in section.courseLessons"
                              :key="index"
                              class="class-level-one over-ellipsis"
                              @click="watchCourse(index, lesson, 2)"
                            >
                              <div class="text-wrap">
                                <div class="content">{{ lesson.theme }}</div>
                                <div
                                  class="item-status-wrap item-status-wrap-list"
                                >
                                  <!-- 其余课时 -->
                                  <!-- 如果未登录,加锁 -->
                                  <div
                                    v-if="!isLogin"
                                    class="item-status lock"
                                  ></div>
                                  <!-- 如果登录,且没有购买加锁 -->
                                  <div
                                    v-else-if="isLogin && !isBuy"
                                    class="item-status lock"
                                  ></div>
                                  <!-- 如果登录,且购买, 可以播放 -->
                                  <div v-else class="item-status test-watch">
                                    播放
                                  </div>
                                </div>
                              </div>
                            </div>
                          </div>
                        </div>
                      </div>
                    </div>
                  </el-tab-pane>
                </el-tabs>

                <div class="tab-fix-wrap"></div>
                <div></div>
              </div>
            </div>
          </div>
        </div>

        <!-- 底部购买 -->
        <div
          class="public-class-footer"
          slot="bottom"
          style="border:1px solid #eee; height:60px; text-align:left;"
        >
          <span class="product-descript" style="font-size:.347rem"
            >成就自己</span
          >
          <span class="current-price" style="font-size:28px">
            <span class="current-price-unite" style="font-size:.347rem"></span
            >{{ course.discounts }}
          </span>
          <span class="current-price price">
            <span class="current-price-unite"></span>
            {{ course.price }}
          </span>
          <button
            @click="buy(7)"
            type="button"
            class="weui-btn purchase-button weui-btn_mini weui-btn_primary"
            style="width:155px;height:45px;font-size:17px;"
          >
            立即购买
            <!-- ::after -->
          </button>
        </div>
      </div>
    </div>

    <Footer></Footer>
  </div>
</template>

<script>
import Header from "./Header/Header"; //顶部登录条
import Footer from "./Footer/index"; //顶部登录条
export default {
  name: "Course",
  components: {
    Header,
    Footer,
  },
  data() {
    return {
      activeName: "intro",
      course: null,
      totalLesson: 0, //总课时
      commentList: null, // 留言列表
      isLogin: false, //是否登录
      user: null, //用户
      isBuy: false, //是否购买
      myCourseList: [], //已经购买的课程信息
      comment:null,//发表的留言信息
    };
  },
  created() {
    // 获取用户登录信息
    this.user = JSON.parse(localStorage.getItem("user"));
    // 如果用户不为空,说明登录
    if (this.user != null) {
      this.isLogin = true;
      // 获取已购课程信息
      this.getMyCourseList();
    }
    // 获取上一个页面传递的参数
    this.course = this.$route.params.course;
    // 获取总课时数
    let x = 0;
    for (let i = 0; i < this.course.courseSections.length; i++) {
      let section = this.course.courseSections[i];
      for (let j = 0; j < section.courseLessons.length; j++) {
        x++;
      }
    }
    this.totalLesson = x;
    // 获取留言信息
    this.getCommentList();
  },

  methods: {
    watchCourse(index, lesson, status) {
      // status是否是第一章节
      if (status == 1 && index < 2) {
        // status是第一章节且是免费试看的章节
        if (lesson.courseMedia == null) {
          // 是否有视频
          this.$message.error("视频暂未上传");
        } else {
          this.$message.success("观看第【" + lesson.id + "】节课程视频!");
          this.$router.push({
            name: "videoDetail",
            params: {
              course: this.course,
              lessonid: lesson.id,
              isBuy: this.isBuy,
            },
          });
        }
      }
      // 是否是免费试看的章节
      else {
        //不是免费试看的章节
        //  先登录
        if (!this.isLogin) {
          this.$message.warning("请登录账号");
        } else {
          //  查看该章节是否被购买
          if (!this.isBuy) {
            this.$message.warning("请先购买");
          } else {
            //  该章节购买
            if (lesson.courseMedia == null) {
              // 是否有视频
              this.$message.error("视频暂未上传");
            } else {
              this.$message.success("观看第【" + lesson.id + "】节课程视频!");
              this.$router.push({
                name: "videoDetail",
                params: {
                  course: this.course,
                  lessonid: lesson.id,
                  isBuy: this.isBuy,
                },
              });
            }
          }
        }
      }
    },
    buy(courseid) {
      alert("购买第【" + courseid + "】门课程成功,加油!");
    },
    // 获取留言列表
    getCommentList() {
      return this.axios
        .get(
          " http://localhost:8002/course/comment/getCourseCommentList/" +
            this.course.id +
            "/1/20"
        )
        .then((res) => {
          this.commentList = res.data;
          console.log(this.commentList);
        })
        .catch((err) => {
          this.$message.error("获取留言信息失败");
        });
    },

    //获取已购买的课程信息
    getMyCourseList() {
      return this.axios
        .get(
          "http://localhost:8002/course/getCourseByUserId/" +
            this.user.content.id
        )
        .then((res) => {
          this.myCourseList = res.data;
          // 遍历课程,如果有已经购买的课程,isbuy值为true
          for (let i = 0; i < this.myCourseList.length; i++) {
            if (this.course.id == this.myCourseList[i].id) {
              this.isBuy = true;
              break;
            }
          }
        })
        .catch((err) => {
          this.$message.error("获取已购课程失败");
        });
    },

    // 点赞
    zan(comment){
 return this.axios
        .get(
          "http://localhost:8002/course/comment/saveFavorite/"+comment.id+"/" +this.user.content.id
        )
        .then((res) => {
         this.getCommentList();       
        })
        .catch((err) => {
          this.$message.error("点赞失败");
        });

    },
    // 取消赞
    cancelzan(comment){
 return this.axios
        .get(
          "http://localhost:8002/course/comment/cancelFavorite/"+comment.id+"/" + this.user.content.id
        )
        .then((res) => {
        this.getCommentList();
        })
        .catch((err) => {
          this.$message.error("取消点赞失败");
        });

    },
    // 保存留言
    saveComment(){
        return this.axios
        .get(
          "http://localhost:8002/course/comment/saveCourseComment",{params:{
            courseId:this.course.id,
            userId:this.user.content.id,
            username:this.user.content.name,
            comment:this.comment
          }}
        )
        .then((res) => {
        this.getCommentList();
        this.comment=null;
        })
        .catch((err) => {
          this.$message.error("保存留言失败");
        });
    }


  },
};
</script>

<style scoped>
.message-edit-emojilist {
  position: absolute;
  top: 30px;
  left: 0;
  width: 415px;
  height: 180px;
  padding: 18px 10px;
  border: 1px solid #e2ebe8;
  box-shadow: 0 2px 3px 0 rgba(0, 0, 0, 0.08);
  background: #fff;
  border-radius: 5px;
  z-index: 9;
  margin-bottom: 1.067rem;
}
.message-edit-emoji {
  font-size: 14px;
  color: #666;
}
.message-edit-footer {
  display: -webkit-box;
  display: -webkit-flex;
  display: flex;
  -webkit-flex-wrap: wrap;
  flex-wrap: wrap;
  -webkit-box-pack: justify;
  -webkit-justify-content: space-between;
  justify-content: space-between;
  margin-top: 20px;
  position: relative;
}
.message-edit-count-cur {
  margin-right: -5px;
}
.message-edit-count {
  position: absolute;
  bottom: 5px;
  right: 10px;
  font-size: 14px;
  text-align: right;
  -webkit-box-flex: 1;
  -webkit-flex: 1;
  flex: 1;
  color: #ccc;
}
.pcStyle {
  box-sizing: border-box;
  position: relative;
  line-height: 30px;
  margin-top: 6px;
  height: 100%;
}
.edit-div {
  width: 100%;
  line-height: 1.267rem;
  margin-top: 0.267rem;
  word-break: break-all;
  outline: none;
  color: #666;
  -webkit-user-select: text;
  user-select: text;
  text-align: left;
  font-size: 0.427rem;
  caret-color: #00b38a;
  border-bottom: 4px solid #fff;
  overflow: hidden;
  overflow-y: auto;
}
.message-edit {
  font-size: 16px;
  position: relative;
  padding: 0 14px 34px;
  height: 190px;
  border: 1px solid #ebebeb;
  border-radius: 4px;
  box-sizing: border-box;
  margin-top: 10px;
}

.message-topic {
  display: -webkit-box;
  display: -webkit-flex;
  display: flex;
}
.message-topic .normal-font {
  font-weight: 400;
}
* {
  margin: 0;
  padding: 0;
}
div {
  display: block;
}
.nav-wrap {
  padding-top: 40px;
  height: 50px;
  background: #fff;
}
.nav-p-pc {
  font-size: 16px;
  margin: 17px auto;
  vertical-align: top;
  width: 750px;
}
.nav-p-pc a:active,
.nav-p-pc a:link,
.nav-p-pc a:visited {
  color: #666;
}
.nav-p-pc .sharp-content {
  color: #666;
  margin-left: 5px;
}
.nav-p-pc .nav-sec {
  margin-left: 5px;
  color: #999;
}

.container {
  width: 750px;
  margin: 0 auto;
}
.intro-content {
  overflow: hidden;
  padding: 30px;
  position: relative;
  min-height: 133px;
}
.intro {
  background: #5b5d6e;
  font-family: PingFangSC-Regular;
}
.weui-tab__panel {
  box-sizing: border-box;
  height: 100%;
  padding-bottom: 1.333rem;
  overflow: auto;
  -webkit-overflow-scrolling: touch;
}

.content-wrapper {
  box-sizing: border-box;
  min-height: 100%;
}
.weui-tab {
  position: relative;
  height: 100%;
}
.conent-wrap {
  float: left;
  max-width: 450px;
  position: relative;
}
.name {
  font-family: PingFangSC-Medium;
  font-size: 20px;
  color: #fff;
  font-weight: 700;
  margin-bottom: 53px;
}
.text-omit {
  word-wrap: normal;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
.des {
  font-size: 14px;
  color: #fff;
  position: absolute;
  width: 450px;
  top: 36px;
  left: 0;
}
.title {
  font-size: 12px;
  line-height: 12px;
  color: #fff;
  overflow: hidden;
  margin-bottom: 13px;
  font-weight: 400;
  font-family: PingFangSC-Regular;
}
.teacher-name {
  float: left;
}
.line {
  width: 1px;
  height: 8px;
  opacity: 0.5;
  display: inline-block;
  background: #fff;
  margin-left: 10px;
  margin-right: 10px;
}
.lesson-info {
  overflow: hidden;
  font-family: PingFangSC-Regular;
  font-size: 12px;
  line-height: 20px;
  color: #fff;
  font-weight: 400;
}

.boook-icon[data-v-dd02a830] {
  width: 18px;
  height: 18px;
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAAXNSR…gip3QVDYmQv3MNonYRxetQvIHgUR3EkqN76xV++qd/7MATlNn5zIhsuCEAAAAASUVORK5CYII=);
  float: left;
}
.backgroun-img-set {
  background-repeat: no-repeat;
  background-size: 100% 100%;
}
.time {
  margin-left: 8px;
  float: left;
}
.person-icon {
  width: 18px;
  height: 18px;
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACQAAAAkCAYAAADhAJiYAAAAAXNSR…JiFjKvv30ew3xoAZneN6xkDKPekFmAr5bL5fWApqD/vx34B1s5dQzzKE5bAAAAAElFTkSuQmCC);
  margin-left: 30px;
  float: left;
}

.backgroun-img-set {
  background-repeat: no-repeat;
  background-size: 100% 100%;
}
.person {
  margin-left: 4px;
  float: left;
}
.content-right {
  position: absolute;
  top: 118px;
  right: 40px;
}
.button-wrap {
  font-family: PingFangSC-Medium;
  font-size: 14px;
  color: #fff;
  height: 34px;
  padding: 0 22px;
  border: 1px solid hsla(0, 0%, 88%, 0.5);
  border-radius: 2px;
  line-height: 34px;
  font-weight: 700;
  cursor: pointer;
  position: relative;
  float: right;
}

.small-arrows {
  width: 10px;
  height: 10px;
  background-repeat: no-repeat;
  background-size: 100% 100%;
  background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAAAXNSR…Myh+5soGuoF47UNoy6yQboOuombFBkAQ2lXtaje+zT1EIAsuukPgcISt4AAAAASUVORK5CYII=);
  top: 12px;
  right: 12px;
  position: absolute;
}

.pc-background,
.public-class-container {
  background: #fff;
  min-height: calc(100vh - 4.4rem);
  content: "viewport-units-buggyfill; min-height: calc(100vh - 4.4rem)";
}

.course-img {
  width: 102px;
  max-height: 133px;
  overflow: hidden;
  box-shadow: 0 6px 10px 0 rgba(0, 0, 0, 0.1);
  border-radius: 2px;
  float: left;
  margin-right: 20px;
}

img {
  border: 0;
  vertical-align: top;
  display: inline-block;
}
.content-p {
  font-size: 0.873rem;
  color: #666;
  letter-spacing: 0;
  text-align: justify;
  line-height: 1.1rem;
}
.pc-background,
.public-class-container {
  background: #fff;
  min-height: calc(100vh - 4.4rem);
  content: "viewport-units-buggyfill; min-height: calc(100vh - 4.4rem)";
}

.pc-background {
  padding: 20px;
}

.public-class-footer {
  height: 1.733rem;
  width: 100%;
  line-height: 55px;
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 2;
  padding: 0 0.4rem;
  border-top: 1px solid #eee;
  background: #fff;
  box-sizing: border-box;
  max-width: 750px;
  margin: 0 auto;
}

.public-class-footer {
  position: fixed;
}

.public-class-footer .product-descript {
  font-size: 0.347rem;
  color: #333;
}
.public-class-footer .current-price {
  font-size: 0.533rem;
  color: #ff7452;
}
.public-class-footer .current-price.price {
  color: #999;
  text-decoration: line-through;
  padding-left: 0.027rem;
  font-size: 0.16rem;
}
.public-class-footer .current-price {
  font-size: 0.533rem;
  color: #ff7452;
}
.public-class-footer .purchase-button {
  width: 4.8rem;
  height: 1.2rem;
  text-align: center;
  display: inline-block;
  font-size: 0.427rem;
  color: #fff;
  border: none;
  position: absolute;
  right: 0.267rem;
  top: 0.267rem;
  cursor: pointer;
}
.public-class-footer .current-price-unite {
  font-size: 0.347rem;
  margin-right: -0.133rem;
}
button {
  -webkit-appearance: button;
  text-rendering: auto;
  color: buttontext;
  letter-spacing: normal;
  word-spacing: normal;
  text-transform: none;
  text-indent: 0px;
  text-shadow: none;
  display: inline-block;
  text-align: center;
  align-items: flex-start;
  cursor: default;
  background-color: buttonface;
  box-sizing: border-box;
  margin: 0em;
  font: 400 13.3333px Arial;
  padding: 1px 6px;
  border-width: 2px;
  border-style: outset;
  border-color: buttonface;
  border-image: initial;
}
button,
input,
optgroup,
select,
textarea {
  margin: 0;
  padding: 0;
  border: 1px solid #ededed;
  border-radius: 0;
  font-family: Hiragino Sans GB, Microsoft Yahei, SimSun, Arial, Helvetica Neue,
    Helvetica;
}
.weui-btn {
  position: relative;
  display: block;
  margin-left: auto;
  margin-right: auto;
  padding-left: 0.373rem;
  padding-right: 0.373rem;
  box-sizing: border-box;
  font-size: 0.48rem;
  text-align: center;
  text-decoration: none;
  color: #fff;
  line-height: 2.33333333;
  border-radius: 4px;
  -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
  overflow: hidden;
}
.weui-btn_primary {
  background-color: #00b38a;
}
.weui-btn_mini {
  display: inline-block;
  padding: 0 1.32em;
  line-height: 2.3;
  font-size: 0.347rem;
}
button.weui-btn,
input.weui-btn {
  width: 100%;
  border-width: 0;
  outline: 0;
  -webkit-appearance: none;
}
.public-class-footer .purchase-button {
  width: 4.8rem;
  height: 1.2rem;
  text-align: center;
  display: inline-block;
  font-size: 0.427rem;
  color: #fff;
  border: none;
  position: absolute;
  right: 0.267rem;
  top: 0.267rem;
  cursor: pointer;
}

.class-menu-contaniner.more-sections-padding {
  padding-bottom: 3.04rem;
}
.class-menu-contaniner.more-sections {
  padding: 0 20px 50px 30px;
}

.class-menu-contaniner.list-page-container {
  padding: 20px 15px;
  background: #fff;
}
.class-menu-contaniner {
  background: #f6f6f6;
}
div {
  box-sizing: border-box;
}

.section-name {
  font-size: 18px;
  color: #333;
  font-weight: 700;
  padding: 30px 0 20px;
  max-width: 540px;
  font-family: PingFangSC-Regular;
}

.single-line {
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
  margin: 0px;
  text-align: left;
  line-height: 18px;
}

.class-menu-contaniner.more-sections .class-menu-block {
  background: #fbfbfb;
  font-size: 0.187rem;
  color: #333;
}
.class-menu-block {
  font-family: PingFangSC-Regular;
  font-size: 16px;
  font-weight: 400;
}

.class-menu-contaniner .more-sections .class-level-one {
  padding-left: 20px;
  font-size: 14px;
  min-height: auto;
}
.class-menu-contaniner .list-page-container .class-level-one {
  border-right: none;
  font-size: 16px;
  color: #333;
  padding-left: 15px;
  min-height: 62px;
  cursor: pointer;
}
.class-menu-contaniner .class-level-one {
  /* border:1px solid red; */
  font-size: 14px;
  color: #666;
  position: relative;
  width: 100%;
  /* min-height: 90px; */
  line-height: 50px;
  height: 50px;
  padding-left: 30px;
  border-right: 1px solid #ededed;
  cursor: pointer;
}
.class-level-one:hover {
  background: rgba(207, 198, 196, 0.534);
}
.class-menu-contaniner .over-ellipsis {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.class-menu-contaniner .class-level-one:first-child .text-wrap {
  border-top: none;
}
.class-menu-contaniner.list-page-container
  .class-level-one
  .text-wrap
  .content {
  width: 600px;
  word-break: break-all;
  white-space: normal;
  text-align: left;
  float: left;
}
.class-menu-contaniner.more-sections .class-level-one .item-status-wrap-list {
  top: 15px;
}
.class-menu-contaniner .class-level-one .item-status.lock {
  width: 20px;
  height: 20px;
  background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAAXNSR0IArs4c6QAAAolJREFUWAntlztLA0EQx01ihIAW2om2VilCHoWN8dB0FpYi2PoNxMbaRvwGaieopaBWKlErIQ9SWNkqdlpoZSDxP5edY+9uk3snAbOwmd2d1y+zucvu2NioBatALJh7x7tWq6222+0N9GIsFpujVYzfMX5Ev8jlcnd+8wQCrNfrC61W6wgwy70AAPkQj8e3s9nsay87lc43YLVaXULAS8BNqwJb1wD5hbX1fD7/ZNX1msd7KbvpqHLQGXBI3kY/wtpiKpWaok5jWiMdxRFf5FL40pKrNu7KymIktpUr9wH1FipzbzF7xvwZlT6HPEWfJUjyxVhDd9U8bzE9EEhyS9FFdUoKOFNyQK5g4RaAej78HktuHxzPW4wkG1L2Yyc4shU2x+xnicHLSukHsMiRkOiEx05StsXYiOHk5xkQ26q/5ygwHoYXpwSsl23lGKzvJj0D4ttPcrB0Ov3DYycp28oxnPw8AzoFDFs/9IDK10yj0ZhvNpsHqIaGPht2VbrEo/dpOZlM7mYymTe2sQEKuAYMZtioz/ITkGDsQNq2WFRuUHBUixnBoNdF9Ven6Rp8JBKJNZxAbngepaxUKmuIfyVyaJzLVkEojN9cv+AIplAoXDOUzKAClOwGPxwBBt2D0CuIo9U++jfJoHDkHzogYu6I/9qdoQQE3ASBsQwKGUUFgzKZ/EeApnL4mIReQZyWf4mDpQ8mk0vogIh+CDg6aR+aMvmcqA4LPkN13HCD28OIeigtigqGAsZBRoBcCb9SVUG6G+hNHCJ5Gqm05DIYVA9JGSSbguYKjpGCdQle5nVbBelWBeUnGwxA0qWJGPRmA6TbFN2qoD1DN0rdMY/0k3KdyTe6SLP9m+B/vKTQX63cZOIAAAAASUVORK5CYII=)
    no-repeat;
  background-size: 100% 100%;
  margin-right: 14px;
  float: right;
  line-height: 20px;
  position: relative;
  top: 13px;
  right: 10px;
}
.class-menu-contaniner .class-level-one .item-status.test-watch {
  width: 46px;
  height: 20px;
  border: 1px solid rgba(0, 179, 138, 0.5);
  border-radius: 2px;
  font-size: 12px;
  text-align: center;
  display: table-cell;
  vertical-align: middle;
  color: #00b38a;
  line-height: 20px;
  position: relative;
  top: 13px;
  right: -25px;
}

.message {
  padding: 20px 20px 1.733rem;
  background: #fff;
  font-family: PingFangSC-Regular, PingFang SC;
  font-size: 16px;
}
.message-edit-emoji-icon {
  width: 20px;
  height: 20px;
}
img {
  border: 0;
  vertical-align: top;
  display: inline-block;
}

.disableBg {
  background: #ccc;
}

.message-edit-btn {
  background: #00b38a;
  color: #fff;
  font-size: 14px;
  width: 107px;
  height: 40px;
  line-height: 40px;
  border: none;
  border-radius: 4px;
}

.message-edit-emojilist em {
  margin-top: -29px;
  color: #e2ebe8;
  font-style: normal;
}
.message-edit-emojilist-tip {
  display: block;
  width: 30px;
  height: 16px;
  font-size: 12px;
  overflow: hidden;
  position: relative;
  margin-left: 15px;
}

em,
i {
  font-style: normal;
}

.emoji-icon {
  margin: 8px;
}
.emoji_1f600 {
  background: url(https://www.lgstatic.com/mds-pipline-fed/instantMessaging/common/img/emojiSprite.8c9eba9b.png) -108px -36px
    no-repeat;
  background-size: 216px auto;
}
[class*=" emoji_"],
[class^="emoji_"] {
  height: 18px;
  width: 18px;
  display: inline-block;
}
.message-list {
  color: #333;
  padding: 20px 0 30px;
}
.message-list-title-left,
.message-list-title {
  display: -webkit-box;
  display: -webkit-flex;
  display: flex;
}
.message-list-title-left {
  -webkit-box-flex: 1;
  -webkit-flex: 1;
  flex: 1;
  -webkit-box-align: center;
  -webkit-align-items: center;
  align-items: center;
  text-align: left;
}
.message-list-title-left-name {
  font-size: 0.373rem;
  margin-right: 0.133rem;
  font-weight: 700;
}
.message-list-title-left-tag {
  min-width: 26px;
  height: 16px;
  line-height: 16px;
  padding: 1px 5px;
  text-align: center;
  border-radius: 1px;
  font-size: 10px;
  border-radius: 2px;
  color: #fff;
}
.message-list-title-right {
  overflow: hidden;
  display: -webkit-box;
  display: -webkit-flex;
  display: flex;
  -webkit-box-align: center;
  -webkit-align-items: center;
  align-items: center;
}
.message-list-title-right-icon {
  width: 14px;
  height: 14px;
  margin-right: 4px;
}

img {
  border: 0;
  vertical-align: top;
  display: inline-block;
}
.message-list-title-right-praise {
  height: 10px;
  font-size: 14px;
  font-family: PingFangSC-Regular, PingFang SC;
  font-weight: 400;
  color: #666;
  line-height: 13px;
}
.message-list-content {
  color: #666;
  font-size: 16px;
  margin-top: 10px;
  word-wrap: break-word;
  word-break: break-all;
  overflow: hidden;
  line-height: 30px;
  text-align: left;
}
.pointer {
  cursor: pointer;
}
.message-delete {
  color: #999;
  font-size: 14px;
  display: -webkit-box;
  display: -webkit-flex;
  display: flex;
  -webkit-box-align: center;
  -webkit-align-items: center;
  align-items: center;
  padding-top: 8px;
  position: relative;
  width: 50px;
}

.message-delete-icon {
  width: 14px;
  height: 14px;
  margin-right: 5px;
}
</style>

 

 

 
posted @ 2021-08-09 11:46  forever_fate  阅读(147)  评论(0)    收藏  举报