瀏覽代碼

erge branch 'bencao' of ssh://gogs.hanyiyun.com:2222/xmnk/party into bencao

xvying 1 年之前
父節點
當前提交
efc2958a09

+ 45 - 0
src/router/index.js

@@ -373,6 +373,51 @@ export const asyncRoutes = [
         },
         hidden: true,
       },
+      {
+        path: "courseDetail",
+        name: "courseDetail",
+        component: () => import("@/views/video/course_detail"),
+        meta: {
+          title: "课程详情",
+          icon: "message",
+          roles: ["Super admin", "Admin", "Student"],
+        },
+        hidden: true,
+      },
+      {
+        path: "videoDetail",
+        name: "videoDetail",
+        component: () => import("@/views/video/video_detail"),
+        meta: {
+          title: "视频详情",
+          icon: "message",
+          roles: ["Super admin", "Admin", "Student"],
+        },
+        hidden: true,
+      },
+    ],
+    // Super admin
+  },
+  {
+    path: "/xuexi",
+    component: Layout,
+    redirect: "/xuexi",
+    meta: {
+      title: "课程学习",
+      icon: "dang",
+      roles: ["Student", "Super admin", "Admin"],
+    },
+    children: [
+      {
+        path: "index",
+        name: "index",
+        component: () => import("@/views/xuexi/index"),
+        meta: {
+          title: "课程学习",
+          icon: "admin",
+          roles: ["Super admin", "Admin"],
+        },
+      },
     ],
     // Super admin
   },

+ 42 - 0
src/views/video/api/course_detail.js

@@ -0,0 +1,42 @@
+/*
+ * @Description:
+ * @version:
+ * @Author: 小六
+ * @Date: 2022-01-22 17:07:20
+ * @LastEditors: king
+ * @LastEditTime: 2023-03-25 11:58:19
+ */
+
+import request from '@/utils/request'
+
+export function getCourse_detail(params) {
+  return request({
+    url: '/course',
+    method: 'get',
+    params,
+  })
+}
+// 订阅课程
+export function join(data) {
+  return request({
+    url: '/course/subscribe',
+    method: 'post',
+    data,
+  })
+}
+export function chapterList(params) {
+  return request({
+    url: '/course/chapters',
+    method: 'get',
+    params,
+  })
+}
+
+//收藏课程
+export function getShoucang(data) {
+  return request({
+    url: '/course/collection',
+    method: 'post',
+    data,
+  })
+}

+ 653 - 0
src/views/video/course_detail.vue

@@ -0,0 +1,653 @@
+<!--
+ * @Description:
+ * @version:
+ * @Author: 小六
+ * @Date: 2022-01-21 10:44:04
+ * @LastEditors: king
+ * @LastEditTime: 2023-03-25 13:51:32
+-->
+<template>
+  <div class="class_container">
+    <!-- <el-page-header class="goback" content="课程详情" @back="goBack" /> -->
+    <div class="detail_header">
+      <el-page-header :content="detail.title" @back="goBack" />
+    </div>
+    <div class="course_title">
+      <div class="course_img">
+        <div class="img">
+          <img
+            alt=""
+            :src="
+              detail.thumb_resource
+                ? detail.thumb_resource.url
+                : '../../assets/index/course.jpg'
+            "
+          />
+        </div>
+        <!-- <div class="nums">
+          <div class="nums_left">
+            <i class="el-icon-s-custom"></i>
+            <span>{{ detail.user_count }}人</span>
+          </div>
+          <div class="nums_right" @click="shoucang">
+            <span v-if="!detail.is_collection_status">
+              <i class="el-icon-star-off"></i>
+              收藏
+            </span>
+            <span v-else class="yishoucang">
+              <i class="el-icon-star-on"></i>
+              已收藏
+            </span>
+          </div>
+        </div> -->
+      </div>
+      <div class="course_money">
+        <div class="money_top">
+          <p class="title">{{ detail.title }}</p>
+          <div class="des">
+            <!-- <div class="money">
+              分类:{{
+                detail.category ? detail.category.name : '--'
+              }}
+            </div> -->
+
+            <div v-if="detail.labels && detail.labels.length" class="time">
+              <span class="time_title">标签:</span>
+              <el-tag
+                v-for="(self, index3) in detail.labels"
+                :key="index3"
+                effect="dark"
+                :type="colorList[index3]"
+              >
+                {{ self }}
+              </el-tag>
+            </div>
+          </div>
+        </div>
+
+        <div class="join">
+          <div class="nums">
+            <div class="nums_left">
+              <i class="el-icon-s-custom"></i>
+              <span>{{ detail.user_count }}人</span>
+            </div>
+            <div class="nums_right" @click="shoucang">
+              <span v-if="!detail.is_collection_status">
+                <i class="el-icon-star-off"></i>
+                收藏
+              </span>
+              <span v-else class="yishoucang">
+                <i class="el-icon-star-on"></i>
+
+                已收藏
+              </span>
+            </div>
+          </div>
+          <span
+            class="course_join"
+            @click="to_sec_course"
+          >
+            去学习
+          </span>
+          <!-- <span
+            v-if="detail.watch_progress || detail.watch_progress === 0"
+            class="course_join"
+            @click="to_sec_course"
+          >
+            去学习
+          </span>
+          <span v-else class="course_join" @click="join_course">
+            订阅课程
+          </span> -->
+        </div>
+      </div>
+    </div>
+    <div class="course_content">
+      <div class="content_left">
+        <ul class="nav">
+          <li
+            :class="[current_sec_nav == 1 ? 'active' : '']"
+            @click="chang_sec_nav(1)"
+          >
+            <span>简介</span>
+          </li>
+          <li
+            :class="[current_sec_nav == 2 ? 'active' : '']"
+            @click="chang_sec_nav(2)"
+          >
+            <span>学习目录</span>
+          </li>
+        </ul>
+        <div class="content_wrap">
+          <div :class="['jianjie', current_sec_nav == 1 ? 'isShow' : '']">
+            <h3>简介</h3>
+            <div class="jianjie_wrap">
+              <div v-html="detail.description"></div>
+              <span>
+                学时:{{ detail.video_nums }}
+                学时
+              </span>
+            </div>
+          </div>
+          <div :class="['mulu', current_sec_nav == 2 ? 'isShow' : '']">
+            <h3>学习目录</h3>
+            <el-empty
+              v-if="course_zhangjie.length == 0"
+              description="暂无内容"
+            />
+            <div class="item_wrap">
+              <ul>
+                <li
+                  v-for="(item, index) in course_zhangjie"
+                  :key="index"
+                  class="out_wrap"
+                  @click="zhedie(item.id)"
+                >
+                  <div class="zhangjie">
+                    <div class="left">
+                      <i class="el-icon-s-unfold"></i>
+                      <span class="title">
+                        {{ item.title }}
+                      </span>
+                    </div>
+                    <div class="right">
+                      <i
+                        v-if="!current_zhedie.includes(item.id)"
+                        class="el-icon-minus"
+                      ></i>
+                      <i v-else class="el-icon-plus"></i>
+                    </div>
+                  </div>
+                  <ul
+                    :class="[
+                      'keshi',
+                      current_zhedie.includes(item.id) ? 'is_zhedie' : '',
+                    ]"
+                  >
+                    <li
+                      v-for="(item1, index1) in item.children"
+                      :key="index1"
+                      @click.stop="to_video(item1.id, item1.slug)"
+                    >
+                      <div class="left">
+                        <span v-if="item1.progress < 100" class="scrle"></span>
+                        <i
+                          v-else-if="item1.progress == 100"
+                          class="el-icon-success complate"
+                        ></i>
+                        <!-- <img
+                          v-else
+                          alt=""
+                          src="../../assets/index/circular.png"
+                        /> -->
+                        <span class="title">{{ item1.title }}</span>
+                      </div>
+                      <div class="right">
+                        <span>{{ item1.duration_text }}</span>
+                        <i class="el-icon-video-play complate"></i>
+                      </div>
+                    </li>
+                  </ul>
+                </li>
+              </ul>
+            </div>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+  import {
+    getCourse_detail,
+    join,
+    getShoucang,
+    chapterList,
+  } from './api/course_detail'
+
+  export default {
+    data() {
+      return {
+        value1: 0,
+        course_slug: '',
+        detail: {},
+        course_id: '',
+        course_zhangjie: [],
+        current_zhedie: [],
+        current_sec_nav: 1,
+        content: '',
+        queryForm: {
+          page: 1,
+          per_page: 15,
+        },
+        layout: 'total, sizes, prev, pager, next, jumper',
+        total: 0,
+        // 课程中标签的颜色数组
+        colorList: ['primary', 'warning', 'info', 'danger'],
+      }
+    },
+    created() {
+      console.log(this.$route.query, 'this.$route.query')
+      this.course_slug = this.$route.query.course_slug
+      this.course_id = this.$route.query.id
+      this.getCourse_detail()
+      this.chapterList()
+    },
+
+    methods: {
+      //返回上一页
+      goBack() {
+        this.$router.push({
+          path: '/video/index',
+          query: {
+            id: this.courseId,
+          },
+        })
+      },
+      //获取课程分类
+      async getCourse_detail() {
+        const { data } = await getCourse_detail({id:this.course_id})
+        console.log(data, 'xaingqing')
+        this.detail = data
+        // this.course_zhangjie = data.directory
+      },
+      //获取章节分类
+      async chapterList() {
+        const { data } = await chapterList({id:this.course_id})
+        console.log(data, 'zhangjie')
+        // this.detail = data
+        this.course_zhangjie = data.data
+      },
+      // 加入课程
+      async join_course() {
+        let params = {
+          course_id: this.course_id,
+        }
+        console.log(params, 'xaingqing')
+
+        const { message } = await join(params)
+        this.$message({
+          message: message,
+          type: 'success',
+        })
+        this.getCourse_detail()
+        // console.log(message, 'xaingqing')
+      },
+      //跳转到另一个详情页
+      to_sec_course() {
+        // 跳转到视频页
+        this.$router.push({
+          path: './videoDetail',
+          query: {
+            course_id: this.course_id,
+            course_slug: this.course_slug,
+          },
+        })
+      },
+
+      //章节折叠
+      zhedie(e) {
+        if (this.current_zhedie.includes(e)) {
+          this.current_zhedie = this.current_zhedie.filter((item) => {
+            return item != e
+          })
+        } else {
+          this.current_zhedie.push(e)
+        }
+      },
+      // 收藏课程
+      async shoucang() {
+        const { message } = await getShoucang({ course_id: this.detail.id })
+        this.$message({
+          message: message,
+          type: 'success',
+        })
+        this.getCourse_detail()
+      },
+      //分页
+      handleCurrentChange(val) {
+        this.queryForm.page = val
+      },
+      handleSizeChange(val) {
+        this.queryForm.pageSize = val
+      },
+      chang_sec_nav(e) {
+        this.current_sec_nav = e
+      },
+      to_video(video_id, video_slug) {
+        console.log(video_id, 'taiozhaun')
+        if (this.detail.watch_progress || this.detail.watch_progress === 0) {
+          // 跳转到视频页
+          this.$router.push({
+            path: './video',
+            query: {
+              video_id: video_id,
+              course_id: this.course_id,
+              course_slug: this.course_slug,
+              video_slug: video_slug,
+            },
+          })
+        } else {
+          this.$message({
+            message: '请先订阅课程',
+            type: 'warning',
+          })
+        }
+      },
+    },
+  }
+</script>
+
+<style lang="scss" scoped>
+  .class_container {
+    padding: 0 !important;
+    background: none !important;
+    width: 1200px;
+    margin: 0 auto 30px;
+    .detail_header {
+      // padding-top: 24px;
+      color: #919191;
+      cursor: pointer;
+      .sec {
+        display: inline-block;
+        vertical-align: middle;
+        max-width: 90%;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+    }
+    .course_title {
+      position: relative;
+      padding: 32px 32px 16px;
+      margin-top: 16px;
+      background-color: #fff;
+      display: flex;
+      justify-content: space-between;
+      .course_img {
+        width: 43.165%;
+        .img {
+          position: relative;
+          width: 100%;
+          img {
+            position: relative;
+            left: 0;
+            top: 0;
+            width: 100%;
+            height: 270px;
+            object-fit: cover;
+          }
+        }
+      }
+      .course_money {
+        position: relative;
+        width: 53.957%;
+        .money_top {
+          // min-height: 250px;
+
+          .title {
+            font-size: 30px;
+            color: #333;
+            font-weight: 500;
+            margin: 0 0 20px;
+            display: -webkit-box; /*将对象转为弹性盒模型展示*/
+            -webkit-box-orient: vertical; /*设置弹性盒模型子元素的排列方式*/
+            -webkit-line-clamp: 1; /*限制文本行数*/
+            overflow: hidden;
+          }
+
+          .des {
+            background-color: #f9f9f9;
+            padding: 10px;
+            min-height: 100px;
+          }
+          .money {
+            // margin-top: 12px;
+            // margin-bottom: 12px;
+            // padding-left: 12px;
+            height: 20px;
+            // background-color: #f9f9f9;
+            color: #666;
+            line-height: 20px;
+          }
+          .time {
+            margin-top: 16px;
+            .time_title {
+              margin-right: 6px;
+              width: 80px;
+              text-align: right;
+              color: #666;
+              &:last-child {
+                color: grey;
+                font-size: small;
+              }
+            }
+          }
+        }
+        .join {
+          // text-align: right;
+          // margin-left: 10px;
+          margin-top: 80px;
+          display: flex;
+          align-items: center;
+          justify-content: space-between;
+          .nums {
+            padding: 0;
+            // margin-top: 20px;
+            margin-bottom: 0;
+            list-style: none;
+            color: #999;
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            font-size: 14px;
+            width: 80%;
+            .nums_left {
+              i {
+                margin-right: 5px;
+              }
+            }
+            .nums_right {
+              cursor: pointer;
+              font-size: 14px;
+              // margin-top: 12px;
+              i {
+                margin-right: 5px;
+              }
+              .yishoucang {
+                color: #ff7e56;
+                i {
+                  font-size: 16px;
+                }
+              }
+            }
+          }
+          .course_join {
+            display: inline-block;
+            padding: 6px 24px;
+            height: 32px;
+            font-weight: 500;
+            color: #fff;
+            background-color: #ff7e56;
+            line-height: 20px;
+            cursor: pointer;
+            border-radius: 4px;
+            margin-left: 10px;
+          }
+        }
+      }
+    }
+    .course_content {
+      margin-top: 24px;
+      display: flex;
+      justify-content: space-between;
+      .content_left {
+        width: 74.49%;
+        .nav {
+          margin: 0;
+          position: relative;
+          padding: 16px 0;
+          margin-bottom: 0;
+          width: 100%;
+          height: 52px;
+          text-align: center;
+          list-style: none;
+          background-color: #fff;
+          border-bottom: 1px solid #ebebeb;
+          li {
+            display: inline-block;
+            margin: 0 80px;
+            cursor: pointer;
+            span {
+              position: relative;
+              color: #666;
+              transition: all 0.3s ease;
+            }
+          }
+          .active {
+            span {
+              font-size: 16px;
+              color: #46c37b;
+              &::after {
+                position: absolute;
+                bottom: -18px;
+                left: 0;
+                content: '';
+                width: 100%;
+                height: 3px;
+                background-color: #46c37b;
+                border-radius: 2px;
+              }
+            }
+          }
+        }
+        .content_wrap {
+          .jianjie {
+            padding: 32px 16px 16px;
+            margin-top: 0;
+            background-color: #fff;
+            display: none;
+            h3 {
+              position: relative;
+              margin: 0;
+              padding-left: 14px;
+              font-size: 18px;
+              font-weight: 500;
+              line-height: 24px;
+              color: #333;
+            }
+            .jianjie_wrap {
+              padding-left: 14px;
+              padding-top: 10px;
+              line-height: 22px;
+              font-size: 14px;
+            }
+          }
+          .mulu {
+            padding: 32px 16px 16px;
+            margin-top: 24px;
+            background-color: #fff;
+            display: none;
+            h3 {
+              position: relative;
+              margin: 0;
+              padding-left: 14px;
+              font-size: 18px;
+              font-weight: 500;
+              line-height: 24px;
+              color: #333;
+            }
+            .empty {
+              padding-left: 14px;
+              padding-top: 10px;
+              line-height: 22px;
+              font-size: 14px;
+              color: rgba(0, 0, 0, 0.56);
+            }
+            .item_wrap {
+              margin-top: 24px;
+              ul {
+                list-style: none;
+                padding: 0;
+                margin-bottom: 0;
+                .out_wrap {
+                  margin-bottom: 10px;
+                  cursor: pointer;
+
+                  .zhangjie {
+                    display: flex;
+                    justify-content: space-between;
+                    align-items: center;
+                    background-color: #f5f5f5;
+                    padding-right: 17px;
+                  }
+                  .keshi {
+                    li {
+                      display: flex;
+                      justify-content: space-between;
+                      align-items: center;
+                      margin-bottom: 10px;
+                      padding-right: 17px;
+
+                      cursor: pointer;
+                      // padding-right: 17px;
+                      &:hover {
+                        background-color: #f3fee8;
+                      }
+                    }
+                  }
+                  .is_zhedie {
+                    display: none;
+                  }
+                  i {
+                    font-size: 18px;
+                  }
+                  .left {
+                    padding: 0 0 0 17px;
+                    display: flex;
+                    align-items: center;
+                    .scrle {
+                      display: inline-block;
+                      width: 16px;
+                      height: 16px;
+                      border-radius: 50%;
+                      border: 2px solid #999;
+                      box-sizing: border-box;
+                    }
+                    img {
+                      width: 16px;
+                      height: 16px;
+                    }
+                    .complate {
+                      color: #46c37b;
+                    }
+                    .title {
+                      display: inline-block;
+                      padding: 15px 100px 15px 0;
+                      margin-left: 20px;
+                    }
+                  }
+                  .right {
+                    display: flex;
+                    align-items: center;
+                    color: #999;
+                    span {
+                      margin-right: 5px;
+                    }
+                  }
+                }
+              }
+            }
+          }
+          .noShow {
+            display: none;
+          }
+          .isShow {
+            display: block;
+          }
+        }
+      }
+    }
+  }
+</style>

+ 13 - 15
src/views/video/editvideo.vue

@@ -29,9 +29,9 @@
             :value="item.id"
           />
         </el-select>
-        <el-button style="margin-left: 10px" type="text" @click="chapterManage">
+        <!-- <el-button style="margin-left: 10px" type="text" @click="chapterManage">
           章节管理
-        </el-button>
+        </el-button> -->
       </el-form-item>
 
       <el-form-item label="上传视频:" prop="fileList">
@@ -220,7 +220,6 @@
           short_description: '',
           description: '',
           published_at: '',
-          is_rec: 1,
           status: 1,
           sort: 0,
           fileList: [],
@@ -295,15 +294,15 @@
         })
       },
       //章节管理
-      chapterManage() {
-        this.$router.push({
-          path: '/course/chapter',
-          query: {
-            courseId: this.courseId,
-            videoId: this.videoId,
-          },
-        })
-      },
+      // chapterManage() {
+      //   this.$router.push({
+      //     path: '/course/chapter',
+      //     query: {
+      //       courseId: this.courseId,
+      //       videoId: this.videoId,
+      //     },
+      //   })
+      // },
       //获取章节列表
       async getChapterList() {
         const { data } = await chapterList({
@@ -311,7 +310,7 @@
           status: 1,
         })
         console.log(data, '章节列表')
-        this.chapterData = data.list
+        this.chapterData = data.data
       },
       //视频上传成功
       videoSuccess(response, file) {
@@ -373,7 +372,7 @@
         console.log(this.hours, '时')
         console.log(this.minute, '时')
         console.log(this.second, '时')
-        this.form.id = this.courseId
+        this.form.course_id = this.courseId
         this.form.duration = this.hours * 3600 + this.minute * 60 + this.second
         if (this.form.duration == 0) {
           this.$message.error('视频时长不能为0')
@@ -397,7 +396,6 @@
               short_description: '',
               description: '',
               published_at: '',
-              is_rec: 1,
               status: 1,
             }
             this.$refs.upload.clearFiles()

+ 3 - 3
src/views/video/index.vue

@@ -67,7 +67,7 @@
           </el-tag>
         </template>
       </el-table-column>
-      <el-table-column
+      <!-- <el-table-column
         align="center"
         label="课程类型"
         show-overflow-tooltip
@@ -76,7 +76,7 @@
           <el-tag v-if="row.category != null">{{ row.category.name }}</el-tag>
           <span v-else>--</span>
         </template>
-      </el-table-column>
+      </el-table-column> -->
       <el-table-column
         align="center"
         label="视频数量"
@@ -301,7 +301,7 @@
       courseDetail(row) {
         console.log(row.id, '课程列表页跳转到课程详情页row.id就是课程id')
         this.$router.push({
-          path: '/video/video',
+          path: '/video/courseDetail',
           query: {
             id: row.id,
           },

+ 897 - 0
src/views/video/video_detail.vue

@@ -0,0 +1,897 @@
+
+<template>
+  <div class="video_container">
+    <div :class="['left_video', isNav ? 'all' : '']">
+      <div class="video_header">
+        <span class="back" @click="back">
+          <i class="el-icon-arrow-left"></i>
+          返回课程
+        </span>
+        <span>{{ videoTitle }}</span>
+      </div>
+      <div class="video_body">
+        <video id="myVideo" class="video-js">
+          <!--<source src="" type="video/mp4" />-->
+          <!-- ../../assets/video/ce.mp4 -->
+        </video>
+      </div>
+      <div class="video_footer"></div>
+    </div>
+    <div :class="['right_nav', isNav ? 'chuxian' : '']">
+      <div class="btn" @click="change_nav">
+        <i class="el-icon-d-arrow-right"></i>
+      </div>
+      <div class="nav">
+        <ul>
+          <li>
+            目录
+          </li>
+        </ul>
+      </div>
+      <div v-if="index == 1" class="nav_item">
+        <div class="item_wrap">
+          <ul>
+            <li
+              v-for="(item, key) in course_zhangjie"
+              :key="key"
+              class="out_wrap"
+              @click="zhedie(item.id)"
+            >
+              <div class="zhangjie">
+                <div class="left">
+                  <i class="el-icon-s-unfold"></i>
+                  <span class="title">
+                    {{ item.title }}
+                  </span>
+                </div>
+                <div class="right">
+                  <i
+                    v-if="!current_zhedie.includes(item.id)"
+                    class="el-icon-minus"
+                  ></i>
+                  <i v-else class="el-icon-plus"></i>
+                </div>
+              </div>
+              <ul
+                :class="[
+                  'keshi',
+                  current_zhedie.includes(item.id) ? 'is_zhedie' : '',
+                ]"
+              >
+                <li
+                  v-for="(item1, index1) in item.children"
+                  :key="index1"
+                  :class="isLearn == item1.id ? 'li-active' : ''"
+                  @click.stop="clickVideo(item1, vIndex, cIndex)"
+                >
+                  <div class="left">
+                    <span v-if="item1.progress < 100" class="scrle"></span>
+                    <i
+                      v-else-if="item1.progress == 100"
+                      class="el-icon-success complate"
+                    ></i>
+                    <span class="title">{{ item1.title }}</span>
+                  </div>
+                  <div class="right">
+                    <span>{{ item1.duration_text }}</span>
+                    <i class="el-icon-video-play complate"></i>
+                  </div>
+                </li>
+              </ul>
+            </li>
+          </ul>
+        </div>
+      </div>
+    </div>
+  </div>
+</template>
+<script>
+  import {
+    getCourseDetail,
+    videoDetail,
+    lookRecord,
+    saveBiji,
+  } from './api/video'
+  import { getCourse_detail } from './api/course_detail'
+
+  var myPlayer = ''
+  var playTimeInterval = '' //播放事件定时器
+  export default {
+    data() {
+      return {
+        value1: 3.5,
+        index: 1,
+        isNav: true,
+        biji_text: '', //笔记内容
+        isText: false,
+        course_zhangjie: [],
+        video_slug: '',
+        current_zhedie: [],
+
+        ban_drag: 0, //当前播放视频是否禁止拖动
+        time: 3, //倒计时
+        isFull: false, //是否全屏
+        loading: true,
+        vIndex: 0, //当前播放视频索引
+        cIndex: 0, //当前播放视频所属章节索引
+        zhUrl: '', //中文字幕地址
+        enUrl: '', //英文字幕地址
+        nextVideo: false,
+        dialogVisible: false,
+        activeName: 'zero',
+
+        directory: [], //章节视频列表
+        videoList: [], //当前章节的视频列表
+        isLearn: '', //是否正在学习中
+        courseId: '', //课程id
+        videoId: '', //正在学习的视频id
+        isWatch: 0, //是否完成学习
+        videoTitle: '', //正在播放的视频名称
+        playTime: 0, //视频播放秒数
+        queryForm: {
+          page: 1,
+          per_page: 15,
+        },
+        show: false,
+        form: {
+          danmu: 'admin-pro',
+        },
+        activeNames: ['first'],
+        player: null,
+        biji_title: '',
+        question_title: '',
+        question_text: '',
+      }
+    },
+    watch: {
+      $route: 'getCourseDetail',
+    },
+    // computed: {
+    //   ...mapGetters({
+    //     token: 'user/token',
+    //   }),
+    // },
+    mounted() {
+      // this.player = this.$refs.player.dp
+      this.nextVideo = false
+      console.log('测试')
+      this.initVideo()
+      // clearInterval(this.playTimeInterval)
+      // console.log(this.player.video.paused, 'ppppp')
+    },
+    beforeDestroy() {
+      //  组件销毁时,清除播放器
+      myPlayer.dispose() // 该方法会重置videojs的内部状态并移除dom
+      clearInterval(playTimeInterval)
+
+      if (myPlayer) {
+        console.log('清除视频播放组件')
+        myPlayer.dispose() // 该方法会重置videojs的内部状态并移除dom
+      }
+    },
+    destroyed() {
+      clearInterval(playTimeInterval)
+
+      console.log('清除视频播放组件')
+    },
+    created() {
+      let route = this.$route
+      this.courseId = route.query.course_id
+      this.video_slug = route.query.video_slug
+      this.course_slug = route.query.course_slug
+      this.isLearn = this.videoId = route.query.video_id
+      console.log(this.videoId, this.courseId, this.video_slug, '123')
+      this.getCourse_detail()
+      this.nextVideo = false
+      console.log(this.vIndex, 'YYYYYYYYYYYYYY')
+      clearInterval(playTimeInterval)
+      this.getCourseDetail()
+      this.show = false
+      this.$nextTick(() => {
+        this.show = true
+      })
+    },
+    methods: {
+      getTnyMac(res) {
+        this.biji_text = res
+      },
+      getTnyMac_question(res) {
+        this.question_text = res
+      },
+      //取消提问
+      cancle_question() {
+        this.question_title = ''
+        this.question_text = ''
+      },
+      //提问
+      async save_question() {
+        if (!this.question_title) {
+          this.$message({
+            message: '请输入问答标题',
+            type: 'warning',
+          })
+          return
+        }
+        if (!this.question_text) {
+          this.$message({
+            message: '请输入问答内容',
+            type: 'warning',
+          })
+          return
+        }
+        let params = {
+          type: 1,
+          title: this.question_title,
+          body: this.question_text,
+          course_id: this.courseId,
+          course_video_id: this.videoId,
+        }
+        const { message } = await saveBiji(params)
+        this.$message({
+          message: message,
+          type: 'success',
+        })
+        this.question_text = ''
+        this.question_title = ''
+      },
+      // 保存笔记
+      async seve_biji() {
+        if (!this.biji_title) {
+          this.$message({
+            message: '请输入笔记标题',
+            type: 'warning',
+          })
+          return
+        }
+        if (!this.biji_text) {
+          this.$message({
+            message: '请输入笔记内容',
+            type: 'warning',
+          })
+          return
+        }
+        let params = {
+          type: 0,
+          title: this.biji_title,
+          body: this.biji_text,
+          course_id: this.courseId,
+          course_video_id: this.videoId,
+        }
+        const { message } = await saveBiji(params)
+        this.$message({
+          message: message,
+          type: 'success',
+        })
+        this.biji_title = ''
+        this.biji_text = ''
+        // },
+      },
+      //获取课程章节
+      async getCourse_detail() {
+        const { data } = await getCourse_detail(this.course_slug)
+        console.log(data, 'xaingqing')
+        this.course_zhangjie = this.directory = data.directory
+        // this.course_fenlei = data
+      },
+      //章节折叠
+      zhedie(e) {
+        if (this.current_zhedie.includes(e)) {
+          this.current_zhedie = this.current_zhedie.filter((item) => {
+            return item != e
+          })
+        } else {
+          this.current_zhedie.push(e)
+        }
+      },
+      //点击重新播放
+      refLook() {
+        this.cIndex = 0
+        this.vIndex = 0
+        this.videoList = this.directory[this.cIndex].children
+        console.log(this.video_list, 'list')
+        //let video_list = this.directory[this.cIndex].children
+        this.isLearn = this.videoId = this.videoList[this.vIndex].id
+        // this.isLearn = this.video_slug = this.videoList[this.vIndex].slug
+        this.lookVideo()
+        //this.videoComments()
+      },
+      initVideo() {
+        let that = this
+        //初始化视频方法
+        myPlayer = this.$video(document.getElementById('myVideo'), {
+          language: 'zh-CN',
+          //确定播放器是否具有用户可以与之交互的控件。没有控件,启动视频播放的唯一方法是使用autoplay属性或通过Player API。
+          controls: true,
+          //自动播放属性,muted:静音播放
+          autoplay: 'autoplay',
+          //建议浏览器是否应在<video>加载元素后立即开始下载视频数据。
+          preload: 'auto',
+        })
+
+        myPlayer.ready(function () {
+          myPlayer.volume(0.5)
+          myPlayer.play()
+        })
+        console.log(myPlayer, 'document.getElementById')
+        //监听视频播放完成
+        myPlayer.on('ended', function () {
+          console.log(this.course_slug, 'YYYYYYYYYYYYYY---视频播放结束')
+          clearInterval(playTimeInterval)
+          that.isWatch = 1
+          that.playTime = parseInt(myPlayer.currentTime())
+          that.lookRecord()
+          that.playTime = 0
+          // let params = {
+          //   course_id: that.courseId,
+          // }
+          // debugger
+          // getCourseDetail(params).then((res) => {
+          //   console.log(res, '刷新章节列表')
+          //   that.directory = res.data.directory
+          // })
+          myPlayer.exitFullscreen()
+          // that.getCourseDetail()
+          setTimeout(function () {
+            that.autoPlayNext()
+          }, 3000)
+
+          console.log('视频播放结束')
+        })
+        //监听视频暂停
+        myPlayer.on('pause', function () {
+          console.log('YYYYYYYYYYYYYY---视频播放暂停')
+          clearInterval(playTimeInterval)
+          console.log(parseInt(myPlayer.currentTime()), '视频播放进度暂停')
+          if (this.ban_drag == 0) {
+            let time = parseInt(myPlayer.currentTime())
+            if (time - this.playTime > 10) {
+              myPlayer.currentTime(this.playTime)
+            }
+          }
+          console.log(that.playTime, '视频播放时长')
+          console.log('用户点击了暂停')
+        })
+        //监听视频播放
+        myPlayer.on('play', function () {
+          that.time = 0
+          that.nextVideo = false
+          console.log('YYYYYYYYYYYYYY---视频播放')
+          that.getPlayTime()
+          console.log('视频播放')
+        })
+      },
+      //获取视频播放事件每秒加一
+      //自动播放下一章节事件
+      autoPlayNext() {
+        //获取视频判断当前视频是不是本章节的最后一条
+        console.log(this.directory, this.cIndex, 'this.directory')
+
+        this.videoList = this.directory[this.cIndex].children
+        this.vIndex = Number(this.vIndex)
+        console.log(typeof this.vIndex + 1, 'vIndex')
+        let vIndexnum = this.vIndex + 1
+        console.log(vIndexnum == this.videoList.length, 'length')
+        if (vIndexnum == this.videoList.length) {
+          //是---判断章节是不是最后一张
+          this.cIndex = Number(this.cIndex)
+          let cIndexnum = this.cIndex + 1
+          if (cIndexnum == this.directory.length) {
+            clearInterval(playTimeInterval)
+            this.nextVideo = true
+            return
+            //是最后一张-----提示用户本课程视频已学完
+          } else {
+            //不是最后一张---播放下一章节的第一条视频
+            console.log(' //不是最后一张---播放下一章节的第一条视频')
+            this.cIndex = this.cIndex + 1
+            this.vIndex = 0
+            let video_list = this.directory[this.cIndex].children
+            this.isLearn = this.videoId = video_list[this.vIndex].id
+            this.video_slug = video_list[this.vIndex].slug
+
+            this.lookVideo()
+            /// this.videoComments()
+          }
+        } else {
+          //不是---视频索引+1播放下一条
+          console.log(' // //不是---视频索引+1播放下一条')
+          this.vIndex = this.vIndex + 1
+          let video_list = this.directory[this.cIndex].children
+          console.log(video_list, 'video_list')
+          this.isLearn = this.videoId = video_list[this.vIndex].id
+          this.video_slug = video_list[this.vIndex].slug
+          console.log(this.videoId, 'this.videoId')
+          this.lookVideo()
+          //  this.videoComments()
+        }
+      },
+      getPlayTime() {
+        clearInterval(playTimeInterval)
+        let that = this
+        playTimeInterval = setInterval(function () {
+          that.playTime = parseInt(myPlayer.currentTime())
+          if (Math.floor(that.playTime / 10) > 0 && that.playTime % 10 == 0) {
+            that.lookRecord()
+            console.log(that.playTime, 'that.playTime')
+          }
+        }, 1000)
+      },
+      //定时发送视频播放记录
+      async lookRecord() {
+        let data = {
+          video_id: this.videoId,
+          //video_slug: this.video_slug,
+          watch_seconds: this.playTime,
+          is_watched: this.isWatch,
+          course_id: this.courseId,
+        }
+        const { message } = await lookRecord(data)
+        console.log(message, 'ooooooooo')
+      },
+      //获取课程详情章节列表和视频列表
+      async getCourseDetail() {
+        let slug = this.$route.query.course_slug
+        console.log(slug, 'getCourseDetail')
+        const { data } = await getCourseDetail(slug)
+
+        this.directory = data.directory
+
+        if (this.videoId) {
+          this.isLearn = this.videoId
+          //this.isLearn = this.video_slug
+          let route = this.$route
+          this.vIndex = route.query.v_index
+          this.cIndex = route.query.c_index
+        } else {
+          console.log(data, 'YYYYY YYY')
+          this.isLearn = this.videoId = data.directory[0].children[0].id
+          //this.isLearn = this.video_slug = data.directory[0].children[0].slug
+          this.videoList = this.directory[0].children
+        }
+
+        this.lookVideo()
+        //   this.videoComments()
+        console.log(data.directory, '课程详情')
+      },
+      //选择需要播放的视频
+      async clickVideo(item, vIndex, cIndex) {
+        this.vIndex = vIndex
+        this.cIndex = cIndex
+        clearInterval(playTimeInterval)
+        console.log(vIndex, 'vIndex, cIndex')
+        console.log(cIndex, 'vIndex, cIndex')
+        this.nextVideo = false
+        this.isWatch = 0
+        console.log(item, '点击时间点')
+        this.isLearn = item.id
+        this.videoTitle = item.title
+        this.videoId = item.id
+        this.video_slug = item.slug
+        this.playTime = 0
+        this.lookVideo()
+        //  this.videoComments()
+      },
+      async lookVideo() {
+        var oldTracks = myPlayer.remoteTextTracks()
+        var i = oldTracks.length
+        while (i--) {
+          myPlayer.removeRemoteTextTrack(oldTracks[i])
+        }
+        // const { data } = await videoDetail({ id: this.videoId })
+        const { data } = await videoDetail(this.video_slug)
+        console.log(this.video_slug, 'this.video_slug')
+        this.videoTitle = data.video.title
+        myPlayer.src(data.video.url_resource.url)
+
+        this.attaches = data.attaches
+        this.videoDescription = data.video.description
+        this.loading = false
+        this.ban_drag = data.video.ban_drag
+        let enurl = data.video.subtitle_en_path_resource.url
+        let url = data.video.subtitle_zh_path_resource.url
+        var zhurl = {
+          kind: 'subtitles',
+          label: '中文简体',
+          src: url,
+          default: 'true',
+        }
+        //https://platform.site.ximengnaikang.com/storage/course_video/hKy5X404wDrRAuAS8gZxfZIDbx6sFkAW.webvtt
+        // this.enUrl = data.video.subtitle_en_path_resource
+        myPlayer.addRemoteTextTrack(zhurl, true)
+        console.log(myPlayer, 'myPlayer')
+        console.log(data.video.subtitle_zh_path_resource, 'myPlayer')
+        if (enurl) {
+          var enUrl = {
+            kind: 'subtitles',
+            label: 'English',
+            src: enurl,
+            default: 'true',
+          }
+          myPlayer.addRemoteTextTrack(enUrl, true)
+        }
+
+        console.log(data.video.subtitle_en_path_resource, '视频详情')
+      },
+
+      change(e) {
+        this.index = e
+      },
+      change_nav() {
+        this.isNav = !this.isNav
+      },
+      back() {
+        // this.$router.go(-1)
+        this.$router.push({
+          path: 'courseDetail',
+          query: {
+            course_slug: this.course_slug,
+            course_id: this.courseId,
+          },
+        })
+      },
+    },
+  }
+</script>
+<style lang="scss" scoped>
+  .video_container {
+    ul,
+    li {
+      margin: 0;
+      padding: 0;
+    }
+    position: fixed;
+    width: 100%;
+    background-color: #e5e5e5;
+    height: 100%;
+    .left_video {
+      position: absolute;
+      left: 26px;
+      right: 35px;
+      top: 0;
+      padding-top: 54px;
+      bottom: 70px;
+      transition: 0.5s;
+      .video_header {
+        position: absolute;
+        top: 0;
+        left: 0;
+        right: 0;
+        height: 54px;
+        line-height: 54px;
+        color: #999;
+        font-size: 16px;
+        z-index: 1;
+        overflow: hidden;
+        .back {
+          color: #666;
+          padding-right: 20px;
+          border-right: 1px solid #c1c1c1;
+          margin-right: 20px;
+          cursor: pointer;
+        }
+      }
+      .video_body {
+        position: relative;
+        background-color: #000;
+        height: 88%;
+        overflow: hidden;
+        .my_video {
+          width: 100%;
+          // height: calc(100vh - 300px);
+        }
+        .vjs-error .vjs-error-display:before {
+          content: none !important;
+        }
+        .video-js .vjs-big-play-button {
+          /*对播放按钮的样式进行设置*/
+          width: 100%;
+          // height: calc(100vh - 300px);
+          border-radius: 50%;
+        }
+        .video-js {
+          width: 100% !important;
+          height: 100% !important;
+        }
+        .video-js .vjs-big-play-button {
+          position: absolute !important;
+          top: 50% !important;
+          left: 50% !important;
+          display: block;
+          width: 50px !important;
+          height: 50px !important;
+          padding: 0;
+          margin-top: -25px !important;
+          margin-left: -25px !important;
+          font-size: 3em;
+          line-height: 42px !important;
+          cursor: pointer;
+          background-color: #2b333f;
+          background-color: rgba(43, 51, 63, 0.7);
+          border: 0.06666em solid #fff;
+          border-radius: 50% !important;
+          opacity: 1;
+          -webkit-transition: all 0.4s;
+          transition: all 0.4s;
+        }
+      }
+      .video_footer {
+      }
+    }
+    .all {
+      right: 395px;
+    }
+    .right_nav {
+      position: absolute;
+      right: 0;
+      top: 0;
+      bottom: 0;
+      width: 360px;
+      right: -360px;
+      background-color: #fff;
+      box-shadow: -1px 0 5px rgba(0, 0, 0, 0.1);
+      transition: 0.5s;
+
+      .btn {
+        position: absolute;
+        top: 50%;
+        left: -32px;
+        margin-top: -24px;
+        width: 32px;
+        text-align: center;
+        line-height: 48px;
+        height: 48px;
+        border-radius: 100px 0 0 100px;
+        cursor: pointer;
+        background: #46c37b;
+        color: #fff;
+        font-size: 18px;
+      }
+      .nav {
+        ul {
+          padding: 0;
+          margin: 0;
+          height: 56px;
+          list-style: none;
+          text-align: center;
+          border-bottom: 1px solid #f5f5f5;
+          font-size: 16px;
+          font-weight: 500;
+          color: #666;
+          line-height: 56px;
+          display: flex;
+          justify-content: space-around;
+          align-items: center;
+          position: relative;
+          cursor: pointer;
+          li {
+            position: relative;
+          }
+          .active {
+            &::after {
+              content: '';
+              display: block;
+              position: absolute;
+              bottom: 0;
+              left: 50%;
+              transform: translateX(-50%);
+              width: 36px;
+              height: 2px;
+              border-radius: 1px;
+              background: #46c37b;
+            }
+          }
+        }
+      }
+      .nav_item {
+        position: absolute;
+        top: 57px;
+        bottom: 0;
+        width: 100%;
+        // overflow-y: hidden;
+        overflow-x: hidden;
+        margin-bottom: 20px;
+        overflow-y: scroll;
+        .item_wrap {
+          margin-top: 24px;
+          ul {
+            list-style: none;
+            padding: 0;
+            margin-bottom: 0;
+            .out_wrap {
+              margin-bottom: 10px;
+              cursor: pointer;
+
+              .zhangjie {
+                display: flex;
+                justify-content: space-between;
+                background-color: #f5f5f5;
+                padding-right: 17px;
+
+                align-items: center;
+              }
+              .keshi {
+                li {
+                  display: flex;
+                  justify-content: space-between;
+                  align-items: center;
+                  margin-bottom: 10px;
+                  cursor: pointer;
+                  padding-right: 17px;
+                  &:hover {
+                    background-color: #f3fee8;
+                  }
+                }
+                .li-active {
+                  background-color: #f3fee8;
+                }
+              }
+              .is_zhedie {
+                display: none;
+              }
+              i {
+                font-size: 18px;
+              }
+              .left {
+                padding: 0 0 0 17px;
+                display: flex;
+                align-items: center;
+                width: calc(100% - 60px);
+                .scrle {
+                  display: inline-block;
+                  width: 16px;
+                  height: 16px;
+                  border-radius: 50%;
+                  border: 2px solid #999;
+                  box-sizing: border-box;
+                  flex-shrink: 0;
+                }
+                img {
+                  width: 16px;
+                  height: 16px;
+                }
+                .complate {
+                  color: #46c37b;
+                }
+                .title {
+                  display: inline-block;
+                  padding: 15px 10px 15px 0;
+                  margin-left: 20px;
+                  // width: calc(100% - 20px);
+                }
+              }
+              .right {
+                display: flex;
+                align-items: center;
+                color: #999;
+                span {
+                  margin-right: 5px;
+                }
+              }
+            }
+          }
+        }
+      }
+      .biji {
+        height: 100%;
+        overflow: hidden;
+        padding: 15px;
+        .text {
+          margin-bottom: 15px;
+          height: 70vh;
+          ::v-deep .menu-management-container {
+            height: 65vh;
+          }
+          ::v-deep .tox-tinymce {
+            height: 65vh !important;
+          }
+          ::v-deep .tox-editor-container {
+            height: 65vh;
+          }
+          .input_wrap {
+            width: 100%;
+            height: 34px;
+            padding: 6px 12px;
+            background-color: #fff;
+            background-image: none;
+            border: 1px solid #ccc;
+            border-radius: 4px;
+            -webkit-transition: border-color 0.15s ease-in-out,
+              box-shadow 0.15s ease-in-out;
+            -o-transition: border-color ease-in-out 0.15s,
+              box-shadow ease-in-out 0.15s;
+            transition: border-color 0.15s ease-in-out,
+              box-shadow 0.15s ease-in-out;
+            margin-bottom: 10px;
+            input {
+              width: 100%;
+              height: 100%;
+              outline: none;
+              margin: 0;
+              padding: 0;
+              color: #666;
+              border-color: #e1e1e1;
+              border: none;
+            }
+          }
+        }
+        .biji_btn {
+          text-align: right;
+          margin-bottom: 15px;
+          cursor: pointer;
+
+          span {
+            display: inline-block;
+            border-color: #34a263;
+            background-color: #46c37b;
+            color: #fff;
+            padding: 6px 12px;
+            font-size: 14px;
+            border-radius: 4px;
+          }
+        }
+      }
+      .question {
+        height: 100%;
+        overflow: hidden;
+        .question_body {
+          margin-bottom: 0;
+          padding: 15px;
+          .input_wrap {
+            width: 100%;
+            height: 34px;
+            padding: 6px 12px;
+            background-color: #fff;
+            background-image: none;
+            border: 1px solid #ccc;
+            border-radius: 4px;
+            -webkit-transition: border-color 0.15s ease-in-out,
+              box-shadow 0.15s ease-in-out;
+            -o-transition: border-color ease-in-out 0.15s,
+              box-shadow ease-in-out 0.15s;
+            transition: border-color 0.15s ease-in-out,
+              box-shadow 0.15s ease-in-out;
+            input {
+              width: 100%;
+              height: 100%;
+              outline: none;
+              margin: 0;
+              padding: 0;
+              color: #666;
+              border-color: #e1e1e1;
+              border: none;
+            }
+          }
+          .question_detail {
+            margin: 10px 0 15px;
+          }
+          .question_btn {
+            margin: 10px 0 15px;
+            text-align: right;
+            font-size: 12px;
+
+            .cancle {
+              display: inline-block;
+              margin-right: 5px;
+              cursor: pointer;
+            }
+            .asck {
+              display: inline-block;
+              border-color: #34a263;
+              background-color: #46c37b;
+              color: #fff;
+              border-radius: 2px;
+              cursor: pointer;
+              background-image: none;
+              border: 1px solid transparent;
+              white-space: nowrap;
+              padding: 5px;
+            }
+          }
+        }
+      }
+    }
+    .chuxian {
+      right: 0px;
+    }
+  }
+</style>

+ 18 - 0
src/views/xuexi/api/course_all.js

@@ -0,0 +1,18 @@
+
+import request from '@/utils/request'
+
+export function getCourse(params) {
+  return request({
+    url: '/course',
+    method: 'get',
+    params,
+  })
+}
+//获取班级
+export function getClass(params) {
+  return request({
+    url: '/course/organization',
+    method: 'get',
+    params,
+  })
+}

+ 35 - 0
src/views/xuexi/api/index.js

@@ -0,0 +1,35 @@
+
+import request from '@/utils/request'
+
+export function getHome(params) {
+  return request({
+    url: '/home',
+    method: 'get',
+    params,
+  })
+}
+
+export function getSwiper(params) {
+  return request({
+    url: '/banner?position=home&is_user=1',
+    method: 'get',
+    params,
+  })
+}
+
+// 课程分类
+export function getCourse_fenlei(params) {
+  return request({
+    url: '/course/categories',
+    method: 'get',
+    params,
+  })
+}
+// 课程
+export function getCourse(params) {
+  return request({
+    url: '/course',
+    method: 'get',
+    params,
+  })
+}

+ 648 - 0
src/views/xuexi/index.vue

@@ -0,0 +1,648 @@
+
+<template>
+  <div v-loading="loading" class="course_all_container">
+    <div class="content">
+      <div class="course_all_header">
+        <div class="title">
+          {{isclass ? '课程列表' : '班级列表'}}
+        </div>
+        <div class="header_btn">
+          <span v-if="isclass" @click="check_class">
+            查看班级
+          </span>
+          <span v-else @click="check_course">
+            查看课程
+          </span>
+          <!-- <span>查看公开课</span> -->
+        </div>
+      </div>
+      <div v-if="isclass">
+        <div class="nav">
+          <div class="nav_title">分类:</div>
+          <ul>
+            <li
+              :class="[current_fenlei == -1 ? 'active' : '']"
+              @click="check_fenlei(-1)"
+            >
+              全部
+            </li>
+            <li
+              v-for="(item, index) in course_fenlei"
+              :key="index"
+              :class="[current_fenlei == item.id ? 'active' : '']"
+              @click="check_fenlei(item.id)"
+            >
+              {{ item.name }}
+            </li>
+            <!-- <li>中医基础理论</li> -->
+          </ul>
+        </div>
+        <div class="sec_nav">
+          <ul>
+            <li
+              :class="[
+                queryForm.tag == 'new' || current_tag == 'new' ? 'active' : '',
+              ]"
+              @click="check_tag('new')"
+            >
+              最新
+            </li>
+            <li
+              :class="[
+                queryForm.tag == 'hot' || current_tag == 'hot' ? 'active' : '',
+              ]"
+              @click="check_tag('hot')"
+            >
+              最热
+            </li>
+            <li
+              :class="[
+                queryForm.tag == 'rec' || current_tag == 'rec' ? 'active' : '',
+              ]"
+              @click="check_tag('rec')"
+            >
+             推荐
+            </li>
+          </ul>
+        </div>
+      </div>
+      <!-- 课程列表 -->
+      <div v-if="isclass" class="list_wrap">
+        <el-empty
+          v-if="course_list.length == 0"
+          description="暂无内容"
+        />
+        <div
+          v-for="(item, index) in course_list"
+          :key="index"
+          class="item_wrap"
+          @click="toDetail(item)"
+        >
+          <div class="item">
+            <div class="course_img">
+              <img
+                alt=""
+                :src="
+                  item.thumb_resource
+                    ? item.thumb_resource.url
+                    : '../../assets/index/course.jpg'
+                "
+              />
+            </div>
+            <div class="course_info">
+              <div class="title">{{ item.title }}</div>
+              <div class="course_nums">
+                <div class="left">
+                  <span>
+                    <i class="el-icon-s-custom"></i>
+                    {{ item.user_count }}
+                  </span>
+                </div>
+                <div class="right">
+                  <span>
+                    <i class="el-icon-video-camera"></i>
+                    {{ item.video_nums }}
+                  </span>
+                </div>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- 班级列表 -->
+      <div v-else class="list_wrap_class">
+        <el-empty
+          v-if="class_list.length == 0"
+          description="暂无内容"
+        />
+        <div
+          v-for="(item, index) in class_list"
+          :key="index"
+          class="item_wrap"
+          @click="toDetail_class(item)"
+        >
+          <div class="item">
+            <div class="course_img">
+              <img
+                alt=""
+                :src="
+                  item.cover_resource
+                    ? item.cover_resource.url
+                    : '../../assets/index/course.jpg'
+                "
+              />
+            </div>
+            <div class="course_info">
+              <div class="title">
+                {{ item.name }}
+              </div>
+              <div class="right">
+                <span class="free">
+                  {{ item.coordinator ? item.coordinator.name : '--' }}
+                </span>
+                <!-- <span v-else>元</span> -->
+              </div>
+            </div>
+            <div class="course_nums">
+              <div class="num_wrap">
+                <span class="left">
+                  <i class="el-icon-collection"></i>
+                  {{ item.course_nums }}
+                </span>
+                <span>
+                  <i class="el-icon-s-custom"></i>
+                  {{ item.student_nums }}
+                </span>
+              </div>
+              <div class="btn">
+                <span>查看详情</span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </div>
+      <el-pagination
+        background
+        :current-page="queryForm.page"
+        :layout="layout"
+        :page-size="queryForm.per_page"
+        :page-sizes="[15, 20, 30, 40, 50, 100]"
+        :total="total"
+        @current-change="handleCurrentChange"
+        @size-change="handleSizeChange"
+      />
+    </div>
+  </div>
+</template>
+<script>
+  // import PageHeader from './components/PageHeader'
+  import { getCourse, getClass } from './api/course_all'
+  import { getCourse_fenlei } from './api/index'
+
+  export default {
+    name: 'Index',
+    // components: {
+    //   PageHeader,
+    // },
+    data() {
+      return {
+        course_fenlei: [],
+        course_list: [],
+        class_list: [],
+        current_fenlei: -1,
+        form: {},
+        queryForm: {
+          page: 1,
+          per_page: 15,
+          is_release: 1,
+        },
+        layout: 'total, sizes, prev, pager, next, jumper',
+        total: 0,
+        isclass: true, //是否是班级列表
+        loading: true,
+      }
+    },
+    computed: {
+
+    },
+
+    created() {
+      this.current_fenlei = this.$route.query.fenlei_id
+      console.log(this.$route.query.isclass, 'isclass')
+      if (this.$route.query.isclass == 'isclass') {
+        this.isclass = false
+        this.getClass()
+      } else {
+        this.getCourse()
+      }
+      if (!this.current_fenlei) this.current_fenlei = -1
+      this.current_tag = this.$route.query.course_tag
+
+      if (this.current_fenlei != -1)
+        this.queryForm.category_id = this.current_fenlei
+      this.getCourse_fenlei()
+      console.log(this.role_id, 'role_id')
+    },
+    methods: {
+      // 获取课程
+      async getCourse() {
+        this.loading = true
+        const { data } = await getCourse(this.queryForm)
+        this.loading = false
+        const { list, meta } = data
+        this.total = meta.pagination.total
+        this.course_list = list
+
+        console.log(this.course_list, 'course_list')
+      },
+      // 获取班级
+      async getClass() {
+        this.loading = true
+        const { data } = await getClass(this.queryForm)
+        this.loading = false
+        const { list, meta } = data
+        this.total = meta.pagination.total
+        this.class_list = list
+
+        console.log(data, 'class_list')
+      },
+      //获取课程分类
+      async getCourse_fenlei() {
+        const { data } = await getCourse_fenlei()
+        console.log(data, 'fenlei')
+        this.course_fenlei = data
+      },
+      // 切换课程分类
+      check_fenlei(item) {
+        this.current_fenlei = item
+        this.queryForm.page = 1
+        if (item == -1) {
+          delete this.queryForm.category_id
+          this.getCourse()
+          return
+        }
+        this.queryForm.category_id = item
+        this.getCourse()
+      },
+      check_tag(e) {
+        this.queryForm.tag = e
+        this.getCourse()
+      },
+      // 点击查看班级
+      check_class() {
+        console.log(this.isclass, 'class')
+        this.isclass = false
+        this.queryForm.page = 1
+        this.getClass()
+      },
+      // 点击查看课程
+      check_course() {
+        console.log(this.isclass, 'class')
+        this.queryForm.page = 1
+
+        this.isclass = true
+        this.getCourse()
+      },
+      toDetail(e) {
+        // 跳转到课程详情页
+        this.$router.push({
+          path: '/courseDetail/course_detail',
+          query: {
+            course_slug: e.slug,
+            course_id: e.id,
+          },
+        })
+      },
+      // 跳转到班级详情
+      toDetail_class(item) {
+        console.log(item, 'item')
+        if (this.role_id == 1) {
+          this.$router.push({
+            path: '/sclass/sclass',
+            query: {
+              class_slug: item.slug,
+              class_id: item.id,
+            },
+          })
+        } else {
+          //如果加入班级则直接跳转到sclass页面否则跳转到sclassJian页面
+          if (item.is_member_status) {
+            this.$router.push({
+              path: '/sclass/sclass',
+              query: {
+                class_slug: item.slug,
+                class_id: item.id,
+              },
+            })
+          } else {
+            this.$router.push({
+              path: '/sclass/sclassJian',
+              query: {
+                class_slug: item.slug,
+                class_id: item.id,
+              },
+            })
+          }
+        }
+      },
+      //分页
+      handleCurrentChange(val) {
+        this.queryForm.page = val
+        if (this.isclass) {
+          this.getCourse()
+        } else {
+          this.getClass()
+        }
+      },
+      handleSizeChange(val) {
+        this.queryForm.pageSize = val
+        if (this.isclass) {
+          this.getCourse()
+        } else {
+          this.getClass()
+        }
+      },
+    },
+  }
+</script>
+<style lang="scss" scoped>
+  .course_all_container {
+    ul,
+    li {
+      list-style: none;
+      padding: 0;
+      margin: 0;
+    }
+    .content {
+      width: 1200px;
+      margin: 0 auto;
+      .course_all_header {
+        position: relative;
+        height: 80px;
+        padding: 20px 0;
+        // background-color: #f5f5f5;
+        letter-spacing: 1px;
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        .title {
+          text-transform: uppercase;
+          padding: 6px 0;
+          font-size: 20px;
+        }
+        .header_btn {
+          span {
+            border-color: #0e6834;
+            background-color: #14954b;
+            color: #fff;
+            font-size: 14px;
+            padding: 12px 35px;
+            margin-right: 5px;
+            border-radius: 4px;
+            cursor: pointer;
+            &:hover {
+              background: #0f7139;
+            }
+          }
+        }
+      }
+      .nav {
+        border: 1px solid #e4ecf3;
+        border-radius: 4px;
+        margin-bottom: 30px;
+        background-color: #fff;
+        padding: 0 60px 0 15px;
+        position: relative;
+        overflow-y: hidden;
+        display: flex;
+        align-items: center;
+        margin-top: 20px;
+        .nav_title {
+          padding: 15px 0;
+          width: 60px;
+          display: block;
+          overflow: hidden;
+          text-overflow: ellipsis;
+          white-space: nowrap;
+          word-wrap: normal;
+        }
+        ul {
+          list-style: none;
+          padding: 0;
+
+          display: flex;
+          align-items: center;
+          li {
+            padding: 10px 12px;
+            cursor: pointer;
+            color: #999;
+            transition: all 0.3s ease;
+            &:hover {
+              color: #14954b;
+            }
+          }
+          .active {
+            color: #14954b;
+          }
+        }
+      }
+      .sec_nav {
+        position: relative;
+        background-color: #fafafa;
+        border-radius: 4px;
+        margin-bottom: 30px;
+        line-height: 22px;
+        ul {
+          display: flex;
+          align-items: center;
+          padding: 0;
+          li {
+            height: 40px;
+            padding: 10px 15px;
+            color: #666;
+            cursor: pointer;
+            &:hover {
+              color: #14954b;
+            }
+          }
+          .active {
+            color: #fff;
+            background-color: #14954b;
+            &:hover {
+              color: #fff;
+            }
+          }
+        }
+      }
+      .list_wrap {
+        display: flex;
+        flex-wrap: wrap;
+        margin: -15px;
+        min-height: 500px;
+        .el-empty {
+          margin: 0 auto;
+        }
+        .item_wrap {
+          width: 25%;
+          padding: 15px;
+          flex-shrink: 0;
+          .item {
+            box-shadow: 0 1px 6px 0 rgba(0, 0, 0, 0.08);
+            border: none;
+            width: 100%;
+            position: relative;
+            margin-bottom: 30px;
+            border-radius: 4px;
+            border: 1px solid #e4ecf3;
+            background-color: #fff;
+            transition: 0.3s;
+            &:hover {
+              transform: translateY(-6px);
+              -webkit-transform: translateY(-6px);
+              -moz-transform: translateY(-6px);
+              box-shadow: 0 26px 40px -24px rgba(0, 36, 100, 0.3);
+              -webkit-box-shadow: 0 26px 40px -24px rgba(0, 36, 100, 0.3);
+              -moz-box-shadow: 0 26px 40px -24px rgba(0, 36, 100, 0.3);
+            }
+            .course_img {
+              position: relative;
+              overflow: hidden;
+              border-top-left-radius: 4px;
+              border-top-right-radius: 4px;
+              width: 100%;
+              cursor: pointer;
+              img {
+                width: 100%;
+                height: 152px;
+              }
+            }
+            .course_info {
+              padding: 16px 8px;
+              .title {
+                margin-top: 0;
+                margin-bottom: 12px;
+                padding: 0;
+                line-height: 20px;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+                word-wrap: normal;
+              }
+              .course_nums {
+                padding: 0;
+                line-height: 20px;
+                position: relative;
+                color: #c1c1c1;
+                display: flex;
+                align-items: center;
+                justify-content: space-between;
+                .left {
+                  span {
+                    margin-right: 12px;
+                  }
+                }
+                .right {
+                  // color: #fe4040;
+                  font-size: 14px;
+                  margin-right: 0;
+                  .free {
+                    color: #43bc60;
+                  }
+                }
+              }
+            }
+          }
+        }
+      }
+      .list_wrap_class {
+        display: flex;
+        flex-wrap: wrap;
+        margin: -15px;
+        min-height: 500px;
+        .el-empty {
+          margin: 0 auto;
+        }
+        .item_wrap {
+          width: 33.3%;
+          padding: 15px;
+          flex-shrink: 0;
+          .item {
+            box-shadow: 0 1px 6px 0 rgba(0, 0, 0, 0.08);
+            border: none;
+            width: 100%;
+            position: relative;
+            margin-bottom: 30px;
+            border-radius: 4px;
+            border: 1px solid #e4ecf3;
+            background-color: #fff;
+            transition: 0.3s;
+            &:hover {
+              transform: translateY(-6px);
+              -webkit-transform: translateY(-6px);
+              -moz-transform: translateY(-6px);
+              box-shadow: 0 26px 40px -24px rgba(0, 36, 100, 0.3);
+              -webkit-box-shadow: 0 26px 40px -24px rgba(0, 36, 100, 0.3);
+              -moz-box-shadow: 0 26px 40px -24px rgba(0, 36, 100, 0.3);
+            }
+            .course_img {
+              position: relative;
+              overflow: hidden;
+              border-top-left-radius: 4px;
+              border-top-right-radius: 4px;
+              width: 100%;
+              cursor: pointer;
+              img {
+                width: 100%;
+                height: 204px;
+              }
+            }
+            .course_info {
+              padding: 16px 8px;
+              display: flex;
+              // text-align: center;
+              justify-content: space-between;
+              .title {
+                margin-top: 0;
+                margin-bottom: 12px;
+                padding: 0;
+                line-height: 20px;
+                overflow: hidden;
+                text-overflow: ellipsis;
+                white-space: nowrap;
+                word-wrap: normal;
+                margin-right: 10px;
+                color: rgb(85, 83, 83);
+                font-size: 15px;
+              }
+              .right {
+                // color: #fe4040;
+                font-size: 15px;
+                margin-right: 0;
+                flex-shrink: 0;
+                .free {
+                  color: #43bc60;
+                }
+              }
+            }
+            .course_nums {
+              padding: 15px 0;
+              line-height: 20px;
+              position: relative;
+              color: #999;
+              display: flex;
+              align-items: center;
+              justify-content: space-between;
+              background-color: #f5f5f5;
+              border-bottom-left-radius: 4px;
+              border-bottom-right-radius: 4px;
+              line-height: 40px;
+              .num_wrap {
+                width: 67%;
+              }
+              span {
+                width: 50%;
+                font-size: 16px;
+                display: inline-block;
+                text-align: center;
+              }
+              .left {
+                border-right: 1px solid #e1e1e1;
+              }
+              .btn {
+                width: 33%;
+                text-align: center;
+                cursor: pointer;
+                span {
+                  font-size: 13px;
+                  // padding: 10px 16px;
+                  // background-color: ;
+                }
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+</style>