前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Dubbo 分布式架构搭建教育 PC 站 - 前端:Vue 代码

Dubbo 分布式架构搭建教育 PC 站 - 前端:Vue 代码

作者头像
RendaZhang
发布2020-11-04 15:23:01
1.2K0
发布2020-11-04 15:23:01
举报
文章被收录于专栏:RendaRenda

src\router\index.js

代码语言:javascript
复制
import Vue from 'vue'
import VueRouter from 'vue-router'
import Vuex from 'vuex'
import Index from '../components/Index.vue'
import Course from '../components/Course.vue'


Vue.use(VueRouter)
Vue.use(Vuex)

const videoDetail = () => import('../components/videoDetail.vue');

const routes = [
  {
    path: '/',
    name: 'Index',
    component: Index,
    meta: {
      title: '首页'
    }
  },
  {
    path: '/Course',
    name: 'Course',
    component: Course,
    meta: {
      title: '课程简介页'
    }
  },
  {
    path: '/videoDetail',
    name: 'videoDetail',
    component: videoDetail,
    meta: {
      title: '视频播放页'
    }
  }
]

const router = new VueRouter({
  routes
})

export default router

首页显示全部课程和已购课程

src\components\Index.vue

代码语言:javascript
复制
<script>
import Header from "./Header/Header"; //顶部登录条
import Footer from "./Footer/index"; //顶部登录条
export default {
  name: "Index",
  components: {
    Header,
    Footer,
  },
  data() {
    return {
      activeName: "allLesson",
      courseList: [], // 课程集合
      myCourseList: [], // 我购买过的课程列表
      isLogin: false, //登录状态
      user: null, // 已登录的用户对象信息
    };
  },
  created() {
    this.user = JSON.parse(localStorage.getItem("user"));
    if (this.user != null) {
      this.isLogin = true; //已登录
      this.getMyCourseList(); // 调用查询我购买的课程方法
    }

    this.getCourseList(); //当组件创建完毕,就调用获取所有课程的方法
  },
  methods: {
    changeCourseTab(tabName) {
      this.classSelect = tabName;
      sessionStorage && sessionStorage.setItem("courseTab", tabName);
    },
    gotoDetail(item) {
      this.$router.push({ name: "Course", params: { course: item } });
    },
    getCourseList() {
      // 去dubbo服务获取全部课程的数据
      return this.axios
        .get("http://localhost:80/course/getAllCourse")
        .then((result) => {
          console.log(result);
          this.courseList = result.data;
        })
        .catch((error) => {
          this.$message.error("获取课程信息失败!");
        });
    },
    getMyCourseList() {
      return this.axios
        .get(
          "http://localhost:80/course/getCourseByUserId/" + this.user.content.id
        )
        .then((result) => {
          console.log(result);
          this.myCourseList = result.data;
        })
        .catch((error) => {
          this.$message.error("获取课程信息失败!");
        });
    },
  },
};
</script>
代码语言:javascript
复制
<!-- 课程信息展示开始 -->
<li
    class="course-li"
    v-for="(item, index) in courseList"
    :key="index"
    >
    <!-- 课程封面图 -->
    <img
         :src="item.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(item)"
                 >
                <span>
                    {{ item.courseName }}
                </span>
            </div>
            <!-- 作者和职称 -->
            <p class="p-title-buy text-overflow">
                <span class="p-author-span">
                    {{ item.teacher.teacherName }}
                </span>
                <span class="p-author-line" />
                <span class="p-author-span">
                    {{ item.teacher.position }}
                </span>
            </p>
            <p></p>
            <!-- 课程简单描述 -->
            <p class="p-describe" style="text-align: left">
                {{ item.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 item.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">{{
                    item.discounts
                    }}</span>
                <span class="current-price">
                    <span class="current-price-unite">¥</span>
                    {{ item.price }}
                </span>
                <span class="activity-name">成就自己</span>
                <span class="content-price-buy"
                      >{{ item.sales }}人购买</span
                    >
            </p>
            <div class="btn btn-green btn-offset">立即购买</div>
        </div>
    </div>
</li>
<!-- 课程信息结束 -->

登录

src\components\Header\Header.vue

代码语言:javascript
复制
<script>
// import wxlogin from 'vue-wxlogin'; // 引入

export default {
  name: "Header",
  components: {
    // wxlogin  // 声明引用的组件
  },
  props: {},
  data() {
    return {
      isLogin: false, // 登录状态,true:已登录,false:未登录
      userDTO: null, // 用来保存登录的用户信息
      isHasNewMessage: false, // 是否有新的推送消息
      dialogFormVisible: false, // 是否显示登录框,true:显示,false:隐藏
      phone: "", // 双向绑定表单 手机号
      password: "", // 双向绑定表单 密码
      // appid:"wxd99431bbff8305a0", // 应用唯一标识,在微信开放平台提交应用审核通过后获得
      // scope:"snsapi_login", // 应用授权作用域,网页应用目前仅填写snsapi_login即可
      // redirect_uri:"http://www.pinzhi365.com/user/wxlogin",  //重定向地址,(回调地址)
      x: null,
    };
  },
  computed: {},
  watch: {},
  mounted() {},
  created() {
    // 当刷新页面,组件创建成功之后,立刻检测本地储存中是否存在用户对象
    this.userDTO = JSON.parse(localStorage.getItem("user"));
    if (this.userDTO != null) {
      this.isLogin = true; // 已登录
    } else {
      // 去检测微信是否登录过
      this.axios
        .get("http://localhost:80/user/checkWxStatus")
        .then((result) => {
          this.userDTO = result.data;
          this.phone = this.userDTO.content.phone;
          this.password = this.userDTO.content.password;
          this.login(); // 走普通登录
        })
        .catch((error) => {
          //this.$message.error("登录失败!");
        });
    }

    !(function (a, b, c) {
      function d(a) {
        var c = "default";
        a.self_redirect === !0
          ? (c = "true")
          : a.self_redirect === !1 && (c = "false");
        var d = b.createElement("iframe"),
          e =
            "https://open.weixin.qq.com/connect/qrconnect?appid=" +
            a.appid +
            "&scope=" +
            a.scope +
            "&redirect_uri=" +
            a.redirect_uri +
            "&state=" +
            a.state +
            "&login_type=jssdk&self_redirect=" +
            c +
            "&styletype=" +
            (a.styletype || "") +
            "&sizetype=" +
            (a.sizetype || "") +
            "&bgcolor=" +
            (a.bgcolor || "") +
            "&rst=" +
            (a.rst || "");
        (e += a.style ? "&style=" + a.style : ""),
          (e += a.href ? "&href=" + a.href : ""),
          (d.src = e),
          (d.frameBorder = "0"),
          (d.allowTransparency = "true"),
          (d.sandbox = "allow-scripts allow-top-navigation allow-same-origin"), // 允许多种请求
          (d.scrolling = "no"),
          (d.width = "300px"),
          (d.height = "400px");
        var f = b.getElementById(a.id);
        (f.innerHTML = ""), f.appendChild(d);
      }
      a.WxLogin = d;
    })(window, document);
  },
  methods: {
    goToSetting() {
      this.$router.push("/setting"); // 跳转个人设置页面
    },
    goToLogin() {
      this.dialogFormVisible = true; // 显示登录框
    },
    login() {
      // 前去登录
      return this.axios
        .get("http://localhost:80/user/login", {
          params: {
            phone: this.phone,
            password: this.password,
            nickname: "",
            headimg: "",
          },
        })
        .then((result) => {
          console.log(result);
          this.dialogFormVisible = false; //关闭登录框
          this.userDTO = result.data; // 保存返回数据中的用户对象信息
          this.isLogin = true; // 更新登录状态
          localStorage.setItem("user", JSON.stringify(this.userDTO)); // 将登录成功的对象信息保存到本地储存中
        })
        .catch((error) => {
          this.$message.error("登录失败!");
        });
    },
    // 微信登录
    goToLoginWX() {
      // 普通的登录表单隐藏
      document.getElementById("loginForm").style.display = "none";
      // 显示二维码的容器
      document.getElementById("wxLoginForm").style.display = "block";

      // 生成二维码
      // 待dom更新之后再用二维码渲染其内容
      this.$nextTick(function () {
        this.createCode(); // 直接调用会报错:TypeError: Cannot read property 'appendChild' of null
      });
    },
    // 生成二维码
    createCode() {
      var obj = new WxLogin({
        id: "wxLoginForm", // 挂载点,二维码的容器
        appid: "wxd99431bbff8305a0", // 应用唯一标识,在微信开放平台提交应用审核通过后获得
        scope: "snsapi_login", // 应用授权作用域,网页应用目前仅填写snsapi_login即可
        redirect_uri: "http://www.pinzhi365.com/user/wxlogin", //重定向地址,(回调地址)
        href:
          "data:text/css;base64,LmltcG93ZXJCb3ggLnFyY29kZSB7d2lkdGg6IDIwMHB4O30NCi5pbXBvd2VyQm94IC50aXRsZSB7ZGlzcGxheTogbm9uZTt9DQouaW1wb3dlckJveCAuaW5mbyB7d2lkdGg6IDIwMHB4O30NCi5zdGF0dXNfaWNvbiB7ZGlzcGxheTogbm9uZX1jcw0KLmltcG93ZXJCb3ggLnN0YXR1cyB7dGV4dC1hbGlnbjogY2VudGVyO30=", // 加载修饰二维码的css样式
      });
    },
    toToIndex() {
      this.$router.push("/"); //回到首页
    },
    toToNotic() {},
    //登出
    logout() {
      localStorage.setItem("user", null); // 将登录成功的对象信息保存到本地储存中
      this.isLogin = false; // 更新登录状态
      // alert("谢谢使用,再见");
      // 去检测微信是否登录过
      this.axios
        .get("http://localhost:80/user/logout")
        .then((result) => {})
        .catch((error) => {
          //this.$message.error("登录失败!");
        });
    },
  },
};
</script>

课程详情和留言

src\components\Course.vue

代码语言:javascript
复制
<!-- 课程详情 -->
<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">
                    {{ totalLessons }} 讲 /
                    {{ course.totalDuration }} 课时
                  </div>
                  <div class="person-icon backgroun-img-set"></div>
                  <div class="person">{{ course.sales }}人已购买</div>
                </div>
              </div>

              <div class="content-right">
                <div class="button-wrap" @click="watchCourse(1)">
                  免费试看
                  <div class="small-arrows"></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: none; resize: none"
                      contenteditable="true"
                      placeholder="分享学习心得、思考感悟或者给自己一个小鼓励吧!"
                      class="edit-div pcStyle"
                      v-model="comment"
                    ></textarea>
                  </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>
                    <!-- 已赞 data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADgAAAA4BAMAAABaqCYtAAAAJFBMVEVHcEwAuI4AtIsAtIsAtIoAtYwAtIsAtYwAtowAx5kAtIsAs4qd4c1kAAAAC3RSTlMAGMfz3VGnbTYIhXtDq8EAAAETSURBVDjLldWhb8JAFAbwg8CGhGSGzNQtULNkWUioWbJkpmYKAQaBITPLLKZysmLz+xfolUL6/XM72msh9N2X8ImaX17vrq+vVeqU39XTuK/kdEMA01jGDY4ZyYWFIRPxp0S8u+8KeBJ+WDxIGFrMJbQm7qhVYSJgr8JUwNsKtYDtCiHgPavcsDVDstsuyDk7NeYDk6G8pM3bWXNawQUijWq8QyPPpQy+50ET9bF09go5pus3cMV0feFEc2DfieZRBU7Up7fjSkwZZgz3DA8MHxl6DP8YRgxjgokimDHcMdwyfGG4ZPjJMCKoY4KJIpgz3DHcMvQYFuPpk/005t1mffHlOs/ETvxXAA0Ul3oQHsp/xD93wxfHcC4VkwAAAABJRU5ErkJggg== -->
                    <div
                      @click="cancelzan(comment)"
                      v-if="
                        JSON.stringify(comment.favoriteRecords).indexOf(
                          user.content.id
                        ) >= 0
                      "
                      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
                      @click="zan(comment)"
                      v-else
                      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 class="message-list-content">
                    {{ comment.comment }}
                  </div>
                  <!--删除留言(必须登录才能删除自己的)-->
                  <!--
                  <div class="message-delete pointer">
                    <img class="message-delete-icon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADgAAAA4BAMAAABaqCYtAAAAD1BMVEWZmZn4+fqysrPu7/DS09OEJUPlAAAAf0lEQVQ4y+3VwQ2AIAwF0C9hAAUHgDgBToD7L2UiUMDiwQMXpQfS9B3ohQ+WVDtibTRCarRJKBzDGVQTQ59RMjSwoVEQDIF4lQYa2Oi6IR6qJ5Yr1Et9ExvnwIGv8A9vxdWmCzRFdMdIF4Se54wkVBwtYQ7/+hMIe643Fcc1PgEbl0u1B0v+VgAAAABJRU5ErkJggg==" alt="">删除
                  </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 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,
                          lesson.id,
                          index,
                          lesson.courseMedia
                        )
                      "
                      v-for="(lesson, index) in section.courseLessons"
                      :key="index"
                    >
                      <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-if="index > 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,
                          lesson.id,
                          index,
                          lesson.courseMedia
                        )
                      "
                      v-for="(lesson, index) in section.courseLessons"
                      :key="index"
                    >
                      <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>
            </el-tab-pane>
          </el-tabs>

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

  <!-- 微信支付二维码-->
  <el-dialog
    :visible.sync="dialogFormVisible"
    style="width: 800px; margin: 0px auto"
  >
    <h1 style="font-size: 30px; color: #00b38a">微信扫一扫支付</h1>
    <div id="qrcode" style="width: 210px; margin: 20px auto"></div>
    <h2 id="statusText"></h2>
    <p id="closeText"></p>
  </el-dialog>

  <!-- 底部购买 -->
  <div
    class="public-class-footer"
    slot="bottom"
    style="border: 1px solid #eee; height: 60px; text-align: left"
  >
    <span class="product-descript" style="font-size: 0.347rem"
      >成就自己</span
    >
    <span class="current-price" style="font-size: 28px">
      <span class="current-price-unite" style="font-size: 0.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>
代码语言:javascript
复制
<script>
import Header from "./Header/Header"; //顶部登录条
import Footer from "./Footer/index"; //顶部登录条
import QRCode from "qrcodejs2"; // 引入qrcodejs

export default {
  name: "Course",
  components: {
    Header,
    Footer,
    QRCode, // 声明组件
  },
  data() {
    return {
      activeName: "intro",
      course: null,
      totalLessons: 0, // 本门课程的总节数
      commentList: null, // 所有留言
      isLogin: false, // false 未登录
      isBuy: false, // false 未购买
      user: null, // 当前用户
      myCourseList: [], // 当前用户购买过的所有课程
      comment: null, // 待发表的留言内容
      dialogFormVisible: false, //默认false:隐藏,true:显示
      time: null, // 计时对象
      orderNo: "", // 订单编号
    };
  },
  created() {
    this.course = this.$route.params.course; // 从路由中获得参数对象赋值给本组件的参数

    // 检测是否登陆
    this.user = JSON.parse(localStorage.getItem("user"));
    if (this.user != null) {
      this.isLogin = true; // 已登录
      this.getMyCourseList(); // 查询登录用户购买的所有课程
    }

    // 计算多少节课要讲
    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.totalLessons = x;

    // 获得所有留言
    this.getComment();
  },
  methods: {
    //播放视频 ( 章节,小节课编号,每节课的索引,每节课的视频对象)
    watchCourse(status, lessonid, index, media) {
      if (media == null || media == "") {
        this.$message.error("播放失败,暂无视频!");
      } else {
        // 试看的可以跳转播放页面
        if (status == 1 && index < 2) {
          this.$message.success("观看第【" + lessonid + "】节课程视频!");
          this.$router.push({
            name: "videoDetail",
            params: {
              course: this.course,
              lessonid: lessonid,
              isBuy: this.isBuy,
            },
          });
        } else {
          // 锁上的,先验证是否登录
          if (!this.isLogin) {
            this.$message.success("请先登录!");
          } else {
            // 登录后,再验证是否购买过
            if (!this.isBuy) {
              this.$message.warning("请购买并解锁,才能观看本视频!");
            } else {
              this.$message.success("观看第【" + lessonid + "】节课程视频!");
              this.$router.push({
                name: "videoDetail",
                params: {
                  course: this.course,
                  lessonid: lessonid,
                  isBuy: this.isBuy,
                },
              });
            }
          }
        }
      }
    },
    // 购买课程
    buy(courseid) {
      //alert("购买第【" + courseid + "】门课程成功,加油!");
      this.dialogFormVisible = true; //显示提示框

      // 待dom更新之后再用二维码渲染其内容
      this.$nextTick(function () {
        this.createCode(); // 直接调用会报错:TypeError: Cannot read property 'appendChild' of null
      });
    },
    // 生成二维码
    createCode() {
      // 去获取支付连接
      this.axios
        .get("http://localhost:80/order/createCode", {
          params: {
            courseid: this.course.id,
            coursename: this.course.courseName,
            price: 1, //测试支付金额固定为1分钱,真实上线环境再改回此真实价钱:this.course.discounts
          },
        })
        .then((result) => {
          console.log(result);
          // QRCode(存放二维码的dom元素id,二维码的属性参数)
          let qrcode = new QRCode("qrcode", {
            width: 200,
            height: 200,
            text: result.data.code_url, // 将返回的数据嵌入到二维码中
          });

          this.orderNo = result.data.orderId;

          // 保存订单, 状态为:已创建 0
          this.saveOrder();

          // 检查支付状态
          this.axios
            .get("http://localhost:80/order/checkOrderStatus", {
              params: {
                orderId: result.data.orderId, // 传递 订单编号 进行查询
              },
            })
            .then((result) => {
              if (result.data.trade_state == "SUCCESS") {
                document.getElementById("statusText").innerHTML =
                  "<i style='color:#00B38A' class='el-icon-success'></i> 支付成功!";
                // 支付成功
                this.updateOrder(20);
              }
              /*
              else if(result.data.trade_state=="NOTPAY"){
                document.getElementById("statusText").innerHTML = "<i style='color:#00B38A' class='el-icon-success'></i> 未支付!";
                this.updateOrder(10);
              }
              */

              // 3秒后关闭二维码窗口
              let s = 3;
              this.closeQRForm(s);
            })
            .catch((error) => {
              this.$message.error("查询订单失败!");
            });
        })
        .catch((error) => {
          this.$message.error("生成二维码失败!");
        });
    },
    // 倒计时关闭二维码窗口
    closeQRForm(s) {
      let that = this;
      that.time = setInterval(function () {
        document.getElementById("closeText").innerHTML =
          "( " + s-- + " ) 秒后关闭本窗口";
        if (s == 0) {
          clearInterval(that.time); // 停止计时器
          that.dialogFormVisible = false; // 二维码窗口隐藏
          that.isBuy = true; // 修改购买状态(已购买)
        }
      }, 1000);
    },
    // 保存订单
    saveOrder() {
      return this.axios
        .get("http://localhost:80/order/saveOrder", {
          params: {
            orderNo: this.orderNo,
            user_id: this.user.content.id,
            course_id: this.course.id,
            activity_course_id: this.course.id,
            source_type: 1,
          },
        })
        .then((result) => {
          // console.log(result);
          console.log("保存订单");
        })
        .catch((error) => {
          this.$message.error("保存订单失败!");
        });
    },
    // 更新订单的状态
    updateOrder(statusCode) {
      return this.axios
        .get("http://localhost:80/order/updateOrder", {
          params: {
            orderNo: this.orderNo,
            status: statusCode,
          },
        })
        .then((result) => {
          console.log("更新订单【" + this.orderNo + "】状态:" + statusCode);
        })
        .catch((error) => {
          this.$message.error("更新订单失败!");
        });
    },
    // 获取本课程的全部留言
    getComment() {
      return this.axios
        .get(
          "http://localhost:80/course/comment/getCourseCommentList/" +
            this.course.id +
            "/1/20"
        )
        .then((result) => {
          this.commentList = result.data;
          console.log("获取留言:");
          console.log(this.commentList);
        })
        .catch((error) => {
          this.$message.error("获取留言信息失败!");
        });
    },
    // 发表留言
    saveComment() {
      return this.axios
        .get("http://localhost:80/course/comment/saveCourseComment", {
          params: {
            courseid: this.course.id,
            userid: this.user.content.id,
            username: this.user.content.name,
            comment: this.comment,
          },
        })
        .then((result) => {
          // console.log(result);
          // 重新获取本门课的全部留言信息
          this.getComment();
        })
        .catch((error) => {
          this.$message.error("发表留言失败!");
        });
    },
    // 查询当前用户购买过的全部课程
    getMyCourseList() {
      return this.axios
        .get(
          "http://localhost:80/course/getCourseByUserId/" + this.user.content.id
        )
        .then((result) => {
          console.log(result);
          this.myCourseList = result.data;

          // 检测当前的课程是否购买过
          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("获取课程信息失败!");
        });
    },
    // 点赞
    zan(comment) {
      return this.axios
        .get(
          "http://localhost:80/course/comment/saveFavorite/" +
            comment.id +
            "/" +
            this.user.content.id
        )
        .then((result) => {
          // console.log(result);
          // 重新获取本门课的全部留言信息
          this.getComment();
        })
        .catch((error) => {
          this.$message.error("点赞失败!");
        });
    },
    // 取消赞
    cancelzan(comment) {
      return this.axios
        .get(
          "http://localhost:80/course/comment/cancelFavorite/" +
            comment.id +
            "/" +
            this.user.content.id
        )
        .then((result) => {
          // console.log(result);
          // 重新获取本门课的全部留言信息
          this.getComment();
        })
        .catch((error) => {
          this.$message.error("取消赞失败!");
        });
    },
  },
};
</script>

播放页

src\components\videoDetail.vue

代码语言:javascript
复制
<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; max-height:940px"
              class="video"

            >
              <video
                style="width: 100%; height: 100%;max-height:920px"
                id="myvideo"
                src=""
                @canplay="getInit"
                @timeupdate="handlerNowTime"

                @click="play"
              />
              <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">--</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="section in course.courseSections.slice(0,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">
                <div :class="{ 
                  'content-section': lesson.id != lessonid, 
                  'content-section content-section-choose': lesson.id == lessonid, 
                  }"    
                    v-for="(lesson , index) in section.courseLessons" :key="index"
                    @click="playLesson(1,index,lesson)"
                    >
                  <!-- 第一章,前两节 -->
                  <div v-if="index<2">
                    <div class="section-item clearfix">
                      <span :class="{ 
                        'kw-icon-video section-type-icon': lesson.id != lessonid, 
                        'kw-icon-video section-type-icon lv': lesson.id == lessonid, 
                        }"><i class="el-icon-video-play"></i></span>
                      <span :class="{ 
                        'section-dec': lesson.id != lessonid, 
                        'section-dec lv': lesson.id == lessonid, 
                        }">{{lesson.theme}}</span>
                      <span v-if="lesson.id != lessonid" 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 v-if="index>1">
                    <div class="section-item clearfix">
                      <span :class="{ 
                        'kw-icon-video section-type-icon': lesson.id != lessonid, 
                        'kw-icon-video section-type-icon lv': lesson.id == lessonid, 
                        }"><i class="el-icon-video-play"></i></span>
                      <span :class="{ 
                        'section-dec': lesson.id != lessonid, 
                        'section-dec lv': 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 v-else-if="lesson.id != lessonid" class="section-status-icon pause-play">播放</span>
                      <span v-else-if="lesson.id == lessonid" 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;" >
                  <div class="section-item clearfix">
                    <span class="kw-icon-video section-type-icon lv"><i class="el-icon-video-play"></i></span>
                    <span class="section-dec lv">2.起步</span>
                    <span class="section-status-icon pause-play"></span>
                  </div>
                  <div class="section-duration">
                    <span>时长:0</span>
                  </div>
                </div>
                -->
              </div>

            </div>
            <!-- 第一章 结束 -->
            <!-- 其余章 开始 -->
            <div v-for="section in course.courseSections.slice(1,course.courseSections.length)">
              <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">
                <div :class="{ 
                    'content-section': lesson.id != lessonid, 
                    'content-section content-section-choose': lesson.id == lessonid, 
                    }"  
                    v-for="(lesson , index) in section.courseLessons" 
                    :key="index"
                    @click="playLesson(2,index,lesson)"
                  >
                  <div>
                    <div class="section-item clearfix">
                      <span :class="{ 
                        'kw-icon-video section-type-icon': lesson.id != lessonid, 
                        'kw-icon-video section-type-icon lv': lesson.id == lessonid, 
                        }"><i class="el-icon-video-play"></i></span>
                      <span :class="{ 
                        'section-dec': lesson.id != lessonid, 
                        'section-dec lv': 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 v-else-if="lesson.id != lessonid" class="section-status-icon pause-play">播放</span>
                      <span v-else-if="lesson.id == lessonid" 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>

            </div>
            <!-- 其余章 结束 -->

          </div>
        </div>
      </div>
    </div>
  </div>
</div>
代码语言:javascript
复制
<script>
export default {
  name: "videoDetail",
  components: {},
  data() {
    return {
      myvideo: null, // 播放器对象
      isplay: false, //是否在播放
      nowTime: "00:00", //当前播放时间
      totalTime: "00:00", //总时长
      course:null, // 课程
      lessonid:0, // 当前播放视频的课节id
      lessonName:null, // 当前播放的视频名称
      isLogin:false, // false 未登录
      isBuy:false, // 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;
  },
  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(status,index,lesson) {

      if(lesson.courseMedia == null){ 
          this.$message.error("播放失败,暂无视频!");
      }else{
        // 试看的可以跳转播放页面
        if(status == 1 && index < 2){
           this.playNow(lesson);
        }else{ // 锁上的,先验证是否登录
          if(!this.isLogin){
              this.$message.success("请先登录!");
          }else{ // 登录后,再验证是否购买过
            if(!this.isBuy){
              this.$message.warning("请购买并解锁,才能观看本视频!");
            }else{
              this.playNow(lesson);
            }
          }
        }
      }
    },
    playNow(lesson){
      this.lessonid = lesson.id; // 当前播放的视频,就是我点击的课
      this.myvideo.src = lesson.courseMedia.fileEdk; // 切换播放器的播放地址
      this.myvideo.play(); // 立刻播放
      this.isplay = true; // 按钮呈现为播放状态
    },
    // 初始化时播放的视频
    initplay(){
      //1.在课程信息中查找即将播放的小节视频的编号
      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){
                  console.log("视频地址:" + lesson.courseMedia.fileEdk);
                  this.lessonName = lesson.theme;
                  //2.将小节视频的地址 赋值 给播放器,进行播放
                  this.myvideo.src = lesson.courseMedia.fileEdk;
                  return;
                }
              }
          }
      }
    }
  },
};
</script>
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-10-29,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Renda 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 首页显示全部课程和已购课程
  • 登录
  • 课程详情和留言
  • 播放页
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档