|
|
@@ -1,3573 +1,129 @@
|
|
|
<template>
|
|
|
<div class="course-detail">
|
|
|
<Header></Header>
|
|
|
- <section class="section">
|
|
|
- <div class="container">
|
|
|
- <div class="section__header">
|
|
|
- <div class="container">
|
|
|
- <el-breadcrumb separator="/">
|
|
|
- <el-breadcrumb-item :to="{ path: '/index' }"
|
|
|
- >首页</el-breadcrumb-item
|
|
|
- >
|
|
|
- <el-breadcrumb-item>课程详情</el-breadcrumb-item>
|
|
|
- </el-breadcrumb>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="section__body">
|
|
|
- <div class="container">
|
|
|
- <div class="course-info">
|
|
|
- <div class="course-info__header clearfix">
|
|
|
- <div class="title">
|
|
|
- <span>{{ goodsData.goodsName }}</span>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- class="left-box"
|
|
|
- :style="{
|
|
|
- backgroundImage: `url(${$tools.splitImgHost(
|
|
|
- goodsData.coverUrl,
|
|
|
- false
|
|
|
- )})`
|
|
|
- }"
|
|
|
- >
|
|
|
- <div
|
|
|
- :class="switchBox ? 'smallBox' : ''"
|
|
|
- :style="switchBox && hideBox ? 'display:none;' : ''"
|
|
|
- v-show="vid"
|
|
|
- id="player"
|
|
|
- ></div>
|
|
|
- <div
|
|
|
- v-if="ShowAlist !== ''"
|
|
|
- :class="!switchBox ? 'smallBox overStyle' : 'switchPdf'"
|
|
|
- :style="!switchBox && hideBox ? 'display:none;' : ''"
|
|
|
- >
|
|
|
- <div v-if="ShowAlist !== ''">
|
|
|
- <vue-office-docx
|
|
|
- style="width:808px;height: 452px!important;"
|
|
|
- v-if="ShowAlist === 'docx'"
|
|
|
- :src="readerResult"
|
|
|
- />
|
|
|
- <vue-office-excel
|
|
|
- style="width:808px;height: 452px!important;overflow: hidden;"
|
|
|
- v-else-if="ShowAlist === 'xlsx'"
|
|
|
- :src="readerResult"
|
|
|
- />
|
|
|
- <vue-office-pdf
|
|
|
- style="width:808px;height: 452px!important;"
|
|
|
- v-else-if="ShowAlist === 'pdf'"
|
|
|
- :src="readerResult"
|
|
|
- />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <i
|
|
|
- v-if="!hideBox && ShowAlist !== ''"
|
|
|
- class="switch el-icon-monitor"
|
|
|
- @click="switchBoxFunc"
|
|
|
- ></i>
|
|
|
- <i
|
|
|
- v-if="ShowAlist !== ''"
|
|
|
- class="hideSwitchBox el-icon-view"
|
|
|
- @click="hideBox = !hideBox"
|
|
|
- ></i>
|
|
|
- <div v-show="vidzb" id="playerzb"></div>
|
|
|
- <div
|
|
|
- class="recordStyle"
|
|
|
- v-if="showRecordStatus && !switchBox"
|
|
|
- >
|
|
|
- 您上次看{{
|
|
|
- $tools.secondToTime(recordObj.videoCurrentTime)
|
|
|
- }},正在自动续播
|
|
|
- <span
|
|
|
- style="
|
|
|
- display: inline-block;
|
|
|
- width: 50px;
|
|
|
- text-align: center;
|
|
|
- "
|
|
|
- >|</span
|
|
|
- >
|
|
|
- <span class="btn_sty" @click="backLI">从头播放</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="right-box">
|
|
|
- <div class="right-box__header">
|
|
|
- <div class="tabs">
|
|
|
- <el-tabs
|
|
|
- v-model="courseTabIndex"
|
|
|
- @tab-click="handleClick"
|
|
|
- >
|
|
|
- <el-tab-pane
|
|
|
- :name="tab.name"
|
|
|
- v-for="(tab, index) in menuTab"
|
|
|
- :key="index"
|
|
|
- >
|
|
|
- <div slot="label">
|
|
|
- <span class="label">{{ tab.label }}</span>
|
|
|
- </div>
|
|
|
- <!-- 章节目录 -->
|
|
|
- <template v-if="tab.name == '1' && courseList.length">
|
|
|
- <Course-tree
|
|
|
- ref="courseTree"
|
|
|
- :courseList="courseList"
|
|
|
- :goodsLearningOrder="
|
|
|
- businessData.goodsLearningOrder
|
|
|
- "
|
|
|
- :sectionItem.sync="sectionItem"
|
|
|
- :sectionMaxNum="goodsData.sectionMaxNum"
|
|
|
- @getResource="getResource"
|
|
|
- >
|
|
|
- </Course-tree>
|
|
|
- </template>
|
|
|
- <!-- 重修目录 -->
|
|
|
- <template
|
|
|
- v-if="tab.name == '2' && rebuildCourseList.length"
|
|
|
- >
|
|
|
- <Course-tree
|
|
|
- ref="courseTree"
|
|
|
- :courseList="rebuildCourseList"
|
|
|
- :goodsLearningOrder="
|
|
|
- businessData.goodsLearningOrder
|
|
|
- "
|
|
|
- :rebuild="1"
|
|
|
- :sectionItem.sync="sectionItem"
|
|
|
- :sectionMaxNum="goodsData.sectionMaxNum"
|
|
|
- @getResource="getResource"
|
|
|
- >
|
|
|
- </Course-tree>
|
|
|
- </template>
|
|
|
- <template v-if="tab.name == '3'">
|
|
|
- <Answer-questions
|
|
|
- ref="answerQuestions"
|
|
|
- :goodsId="goodsId"
|
|
|
- :courseId="courseId"
|
|
|
- :orderGoodsId="orderGoodsId"
|
|
|
- ></Answer-questions>
|
|
|
- </template>
|
|
|
- <template v-if="tab.name == '4'">
|
|
|
- <Notes
|
|
|
- ref="notes"
|
|
|
- :gradeId="gradeId"
|
|
|
- :goodsId="goodsId"
|
|
|
- :courseId="courseId"
|
|
|
- :moduleId="moduleId"
|
|
|
- :chapterId="chapterId"
|
|
|
- :isPlayRebuild="isPlayRebuild"
|
|
|
- :playSectionId="playSectionId"
|
|
|
- :vidzb="vidzb"
|
|
|
- :player="player"
|
|
|
- ></Notes>
|
|
|
- </template>
|
|
|
- <template v-if="tab.name == '5'">
|
|
|
- <Hand-out
|
|
|
- ref="handOut"
|
|
|
- :goodsData="goodsData"
|
|
|
- @backSwitchOfficeData="backSwitchOfficeData"
|
|
|
- ></Hand-out>
|
|
|
- </template>
|
|
|
- </el-tab-pane>
|
|
|
- </el-tabs>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="course-info__body">
|
|
|
- <el-tabs v-model="activeName">
|
|
|
- <el-tab-pane
|
|
|
- v-for="(item, index) in tabList"
|
|
|
- :key="index"
|
|
|
- :name="item.name"
|
|
|
- :label="item.label"
|
|
|
- >
|
|
|
- <template v-if="item.label == '学员须知'">
|
|
|
- <div class="course-menu clearfix">
|
|
|
- <div class="left-box">
|
|
|
- <div class="left-box__body">
|
|
|
- <div
|
|
|
- class="buy-note"
|
|
|
- v-html="
|
|
|
- goodsData.buyNote &&
|
|
|
- goodsData.buyNote.replace(/\n|\r\n/g, '<br>')
|
|
|
- "
|
|
|
- ></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- <template v-else-if="item.label == '讲义资料'">
|
|
|
- <p
|
|
|
- v-if="compyRecommend(handoutList).length === 0"
|
|
|
- style="text-align: center;"
|
|
|
- >
|
|
|
- 暂未拥有其他讲义资料
|
|
|
- </p>
|
|
|
- <ul class="list">
|
|
|
- <li
|
|
|
- class="course-item"
|
|
|
- v-for="(itemy, index) in compyRecommend(handoutList)"
|
|
|
- :key="index"
|
|
|
- >
|
|
|
- <HandoutItem :item="itemy"></HandoutItem>
|
|
|
- </li>
|
|
|
- </ul>
|
|
|
- </template>
|
|
|
- <template v-else-if="item.label == '推荐课程'">
|
|
|
- <p
|
|
|
- v-if="
|
|
|
- compyRecommend(recommendList.goodsList).length === 0
|
|
|
- "
|
|
|
- style="text-align: center;"
|
|
|
- >
|
|
|
- 暂无推荐课程
|
|
|
- </p>
|
|
|
- <ul class="list">
|
|
|
- <li
|
|
|
- class="course-item"
|
|
|
- v-for="(itemy, index) in compyRecommend(
|
|
|
- recommendList.goodsList
|
|
|
- )"
|
|
|
- :key="index"
|
|
|
- >
|
|
|
- <GoodsItem :item="itemy"></GoodsItem>
|
|
|
- </li>
|
|
|
- </ul>
|
|
|
- </template>
|
|
|
- </el-tab-pane>
|
|
|
- </el-tabs>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
+ <section class="section_box">
|
|
|
+ <!-- 面包屑START -->
|
|
|
+ <div class="breadcrumb">
|
|
|
+ <el-breadcrumb separator="/">
|
|
|
+ <el-breadcrumb-item :to="{ path: '/index' }">首页</el-breadcrumb-item>
|
|
|
+ <el-breadcrumb-item>课程详情</el-breadcrumb-item>
|
|
|
+ </el-breadcrumb>
|
|
|
</div>
|
|
|
+ <!-- 标题START -->
|
|
|
+ <h2 class="title">{{ goodsData.goodsName }}</h2>
|
|
|
+ <coreContent></coreContent>
|
|
|
+ <!-- 底部Tab START -->
|
|
|
+ <FooterTab></FooterTab>
|
|
|
</section>
|
|
|
-
|
|
|
- <el-dialog
|
|
|
- width="800px"
|
|
|
- class="take-photo"
|
|
|
- :visible.sync="takePhotoModal"
|
|
|
- :close-on-click-modal="false"
|
|
|
- :close-on-press-escape="false"
|
|
|
- :show-close="false"
|
|
|
- >
|
|
|
- <div class="take-photo__content">
|
|
|
- <!-- <div class="take-photo__close" @click="takePhotoModal = false">X</div> -->
|
|
|
- <div class="take-photo__header">人脸验证</div>
|
|
|
- <div class="take-photo__body clearfix">
|
|
|
- <div class="left-box">
|
|
|
- <div class="title">重要提示:</div>
|
|
|
- <div class="content">
|
|
|
- <p>1、请保证摄像头正对自己,避免头像偏左或者偏右。</p>
|
|
|
- <p>
|
|
|
- 2、请保证拍照环境光线充足(照片太暗或曝光会降低验证通过率)。
|
|
|
- </p>
|
|
|
- <p>
|
|
|
- 3、请保证整个头像在人脸识别区域内,脸部无遮挡装饰物(佩戴眼镜会降低通过率)。
|
|
|
- </p>
|
|
|
- <p>
|
|
|
- 4、如果下面视频中出现黑屏,摄像头可能被其他进程占用,请关闭其他调用摄像头的程序,重新刷新当前页面重新拍照识别。
|
|
|
- </p>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="right-box">
|
|
|
- <img v-show="!isTaking" :src="faceUrl" alt="" />
|
|
|
- <video v-show="isTaking" id="video" :src="stream"></video>
|
|
|
- <div v-show="isTaking" class="mask"></div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="take-photo__footer">
|
|
|
- <el-button
|
|
|
- type="primary"
|
|
|
- v-if="isTaking"
|
|
|
- class="take"
|
|
|
- @click="onPhoto"
|
|
|
- >拍照</el-button
|
|
|
- >
|
|
|
- <el-button
|
|
|
- type="primary"
|
|
|
- v-if="!isTaking"
|
|
|
- class="take"
|
|
|
- :loading="loading"
|
|
|
- @click="reTake"
|
|
|
- >重拍</el-button
|
|
|
- >
|
|
|
- <el-button
|
|
|
- type="primary"
|
|
|
- v-if="!isTaking"
|
|
|
- :loading="loading"
|
|
|
- class="take"
|
|
|
- @click="takeOk"
|
|
|
- >确认</el-button
|
|
|
- >
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </el-dialog>
|
|
|
-
|
|
|
- <el-dialog
|
|
|
- title="提示"
|
|
|
- :close-on-click-modal="false"
|
|
|
- :close-on-press-escape="false"
|
|
|
- :show-close="false"
|
|
|
- :visible.sync="errorCodeDialog"
|
|
|
- width="400px"
|
|
|
- >
|
|
|
- <span>{{ errorCodeMsg }}</span>
|
|
|
- <span slot="footer" class="dialog-footer">
|
|
|
- <el-button type="primary" @click="$router.back(-1)"
|
|
|
- >返回上一页</el-button
|
|
|
- >
|
|
|
- </span>
|
|
|
- </el-dialog>
|
|
|
- <dataReview ref="dataReview" @callbackDataReview="callbackDataReview" />
|
|
|
- <div id="printTable"></div>
|
|
|
- <!-- <ToolBar></ToolBar> -->
|
|
|
<Footer></Footer>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script>
|
|
|
-import dataReview from "@/components/dataReview";
|
|
|
-import { Loading } from "element-ui";
|
|
|
-import axios from "axios";
|
|
|
import Footer from "@/components/footer/index";
|
|
|
import Header from "@/components/header/index";
|
|
|
-import ToolBar from "@/components/toolbar/index";
|
|
|
-import HandoutItem from "@/components/handoutItem/index";
|
|
|
-import GoodsItem from "@/components/goodsItem/index";
|
|
|
-import * as imageConversion from "image-conversion";
|
|
|
-import { mapGetters, mapMutations, mapActions } from "vuex";
|
|
|
-import CourseTree from "./components/CourseTree.vue";
|
|
|
-import AnswerQuestions from "./components/AnswerQuestions.vue";
|
|
|
-import Notes from "./components/Notes.vue";
|
|
|
-import HandOut from "./components/HandOut.vue";
|
|
|
-//引入VueOfficeDocx组件
|
|
|
-import VueOfficeDocx from "@vue-office/docx";
|
|
|
-//引入VueOfficeExcel组件
|
|
|
-import VueOfficeExcel from "@vue-office/excel";
|
|
|
-//引入VueOfficePdf组件
|
|
|
-import VueOfficePdf from "@vue-office/pdf";
|
|
|
-//引入相关样式
|
|
|
-import "@vue-office/docx/lib/index.css";
|
|
|
-import "@vue-office/excel/lib/index.css";
|
|
|
+import FooterTab from "./components/footerTab";
|
|
|
+import coreContent from "./components/coreContent.vue";
|
|
|
+import { Loading } from "element-ui";
|
|
|
export default {
|
|
|
name: "CourseDetail",
|
|
|
components: {
|
|
|
Footer,
|
|
|
Header,
|
|
|
- ToolBar,
|
|
|
- HandoutItem,
|
|
|
- GoodsItem,
|
|
|
- CourseTree,
|
|
|
- AnswerQuestions,
|
|
|
- Notes,
|
|
|
- HandOut,
|
|
|
- VueOfficeDocx,
|
|
|
- VueOfficeExcel,
|
|
|
- VueOfficePdf,
|
|
|
- dataReview
|
|
|
+ FooterTab,
|
|
|
+ coreContent
|
|
|
},
|
|
|
- data() {
|
|
|
+ provide() {
|
|
|
return {
|
|
|
- errorCodeDialog: false,
|
|
|
- errorCodeMsg: "",
|
|
|
- hideBox: false, //隐藏窗口
|
|
|
- switchBox: false, //切换窗口
|
|
|
- switchPdf: {}, //pdf数据
|
|
|
- liveDuration: 0,
|
|
|
- numPages: 0,
|
|
|
- showPdf: false,
|
|
|
- // 总页数
|
|
|
- pdfPages: 10,
|
|
|
- // 当前页数
|
|
|
- pageNum: 1,
|
|
|
- // 加载进度
|
|
|
- loadedRatio: 10,
|
|
|
- // 页面加载完成
|
|
|
- curPageNum: 0,
|
|
|
- // 放大系数 默认百分百
|
|
|
- scale: 100,
|
|
|
- // 旋转角度 ‘90’的倍数才有效
|
|
|
- pageRotate: 0,
|
|
|
- // 单击内部链接时触发 (目前我没有遇到使用场景)
|
|
|
- page: 0,
|
|
|
- bgColor: "#ccc",
|
|
|
- answerTimer: null,
|
|
|
- recordObj: {},
|
|
|
- isTaking: true, //是否正在拍照
|
|
|
- photoConfig: false,
|
|
|
- stream: null,
|
|
|
- photoNum: 0,
|
|
|
- playSectionId: 0,
|
|
|
- photoIndex: 0, //当前位于拍照的区间下标 从0开始
|
|
|
- photoHistoryList: [], //已拍照历史的下标点
|
|
|
- moduleId: 0,
|
|
|
- chapterId: 0,
|
|
|
- lectureShow: true,
|
|
|
- textarea: "",
|
|
|
- textareaNote: "",
|
|
|
- takePhotoModal: false,
|
|
|
- activeName: "1",
|
|
|
- courseId: "",
|
|
|
- courseTabIndex: "1",
|
|
|
- goodsId: "",
|
|
|
- orderGoodsId: "",
|
|
|
- gradeId: "",
|
|
|
- livingTimer: null,
|
|
|
- sectionItem: {},
|
|
|
- gradeDetail: {},
|
|
|
- autoplay: false,
|
|
|
- isAllowSeek: "on",
|
|
|
- playbackRate: false,
|
|
|
- goodsPlayConfig: null,
|
|
|
- playTime: 0, //页面播放时长,不含暂停
|
|
|
- postTimer: null, //提交视频观看记录定时器
|
|
|
- lockTimer: null,
|
|
|
- courseList: [],
|
|
|
- businessData: {},
|
|
|
- courseHandoutsData: "",
|
|
|
- // menuList: [],
|
|
|
- goodsData: {},
|
|
|
- tabList: [],
|
|
|
- vid: "",
|
|
|
- vidzb: "",
|
|
|
- player: "",
|
|
|
- playerzb: "",
|
|
|
- vodPlayerJs: "https://player.polyv.net/script/player.js",
|
|
|
- playerJs:
|
|
|
- "https://player.polyv.net/resp/live-h5-player/latest/liveplayer.min.js",
|
|
|
- uidzb: "egsxlptzdq",
|
|
|
- menuList: [],
|
|
|
- reMenuList: [],
|
|
|
- answerList: [{ newArraysAnswerList: [] }],
|
|
|
- noteList: [],
|
|
|
- photoList: [],
|
|
|
- noteTotal: 0,
|
|
|
- duration: 0,
|
|
|
- answerTimer: null,
|
|
|
- noteParams: {
|
|
|
- pageNum: 1
|
|
|
- // pageSize: 4,
|
|
|
- },
|
|
|
- ossAvatarUrl: "", //照片地址
|
|
|
- nowTime: 0,
|
|
|
- faceUrl: "",
|
|
|
- loading: null,
|
|
|
- listData: [],
|
|
|
- listDataStamp: [],
|
|
|
- remark: "",
|
|
|
- remarkStatus: false,
|
|
|
- remarkStamp: "",
|
|
|
- remarkStatusStamp: false,
|
|
|
- errorType: ["message"],
|
|
|
- stampForm: {
|
|
|
- commitment_seal: ""
|
|
|
- },
|
|
|
- timer: null,
|
|
|
- recommendList: [],
|
|
|
- isPlayRebuild: false,
|
|
|
- showRecordStatus: false,
|
|
|
- hasStart: false,
|
|
|
- needOpen: true, //是否需要展开第一章节
|
|
|
- menuIndex: [],
|
|
|
- clickLock: false,
|
|
|
- liveLast: null,
|
|
|
- apply_post_disabled: false,
|
|
|
- disName: false, // 姓名是否禁止输入
|
|
|
- disCard: false, // 身份证是否禁止输入
|
|
|
- clickSectionItem: {}, // 点击节的内容
|
|
|
- teaIndex: 0,
|
|
|
- sectionExamList: [], //节试卷集合
|
|
|
- sectionExam: [], //节试卷集合
|
|
|
- compareFaceData: 0, // 拍照匹配相似度
|
|
|
- rebuildCourseList: [],
|
|
|
- playTabIndex: "",
|
|
|
- takeSetInt: null,
|
|
|
- videoPause: null,
|
|
|
- confirmStatus: false,
|
|
|
- failToRegister: false, //报名是否不通过
|
|
|
- openPhotoStatus: 0,
|
|
|
- readerResult: null,
|
|
|
- handoutList: []
|
|
|
+ getGoodsData: () => this.goodsData,
|
|
|
+ getBusinessData: () => this.businessData
|
|
|
};
|
|
|
},
|
|
|
- watch: {
|
|
|
- takePhotoModal(val, oldVal) {
|
|
|
- if (val) {
|
|
|
- if (this.sectionItem.learning != 1 && this.goodsData.erJianErZao) {
|
|
|
- this.takeSetInt = setTimeout(() => {
|
|
|
- if (this.isFullScreen()) {
|
|
|
- this.exitFullscreen();
|
|
|
- }
|
|
|
- this.$confirm("检测拍照停留时间过长,刷新当前页面", "提示", {
|
|
|
- confirmButtonText: "确定",
|
|
|
- cancelButtonText: "取消",
|
|
|
- showCancelButton: false,
|
|
|
- closeOnClickModal: false,
|
|
|
- closeOnPressEscape: false,
|
|
|
- showClose: false,
|
|
|
- type: "warning"
|
|
|
- })
|
|
|
- .then(() => {
|
|
|
- this.$router.go(0);
|
|
|
- })
|
|
|
- .catch(() => {});
|
|
|
- }, 300000);
|
|
|
- }
|
|
|
- } else {
|
|
|
- clearTimeout(this.takeSetInt);
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- computed: {
|
|
|
- ...mapGetters(["userInfo"]),
|
|
|
- compyRecommend: function() {
|
|
|
- return function(array) {
|
|
|
- let ary = [];
|
|
|
- if (array && array.length > 0) {
|
|
|
- ary = array.filter((i, index) => index < 5);
|
|
|
- }
|
|
|
- return ary;
|
|
|
- };
|
|
|
- },
|
|
|
- ShowAlist() {
|
|
|
- if (this.switchPdf.urlName) {
|
|
|
- console.log(
|
|
|
- this.switchPdf.urlName.slice(this.switchPdf.urlName.indexOf(".") + 1)
|
|
|
- );
|
|
|
- return this.switchPdf.urlName.slice(
|
|
|
- this.switchPdf.urlName.indexOf(".") + 1
|
|
|
- );
|
|
|
- }
|
|
|
- return "";
|
|
|
- },
|
|
|
- menuTab() {
|
|
|
- let menuTab = [
|
|
|
- {
|
|
|
- name: "1",
|
|
|
- label: "章节目录"
|
|
|
- },
|
|
|
- {
|
|
|
- name: "3",
|
|
|
- label: "答疑"
|
|
|
- },
|
|
|
- {
|
|
|
- name: "4",
|
|
|
- label: "笔记"
|
|
|
- },
|
|
|
- {
|
|
|
- name: "5",
|
|
|
- label: "讲义"
|
|
|
- }
|
|
|
- ];
|
|
|
- if (this.rebuildCourseList.length) {
|
|
|
- menuTab.splice(1, 0, {
|
|
|
- name: "2",
|
|
|
- label: "重修目录"
|
|
|
- });
|
|
|
- }
|
|
|
- return menuTab;
|
|
|
- }
|
|
|
+ data() {
|
|
|
+ return {
|
|
|
+ routerData: {}, //路由代入数据
|
|
|
+ goodsData: {}, //商品详情
|
|
|
+ businessData: {}, //培训项目
|
|
|
+ goodsPlayConfig: {}, //播放设置
|
|
|
+ goodsPhotographConfig: {} //拍照设置
|
|
|
+ };
|
|
|
},
|
|
|
created() {
|
|
|
Loading.service().close();
|
|
|
},
|
|
|
- async mounted() {
|
|
|
- this.courseId = this.$route.query.courseId || "";
|
|
|
- this.goodsId = this.$route.params.goodsId;
|
|
|
- this.orderGoodsId = this.$route.query.orderGoodsId;
|
|
|
- this.gradeId = this.$route.query.gradeId;
|
|
|
- this.sectionItem = this.$route.query;
|
|
|
- let isOther = this.$route.query.isOther || "";
|
|
|
- this.nowTime = Number(new Date().getTime() / 1000).toFixed(0);
|
|
|
- if (isOther) {
|
|
|
- this.isOtherFunc();
|
|
|
- }
|
|
|
- if (this.$route.query.rebuild) {
|
|
|
- this.courseTabIndex = "2";
|
|
|
- }
|
|
|
- await this.getGoodsDetail(); //商品详情
|
|
|
-
|
|
|
- this.getUserHandOutList();
|
|
|
- this.getRecommend();
|
|
|
- this.$refs.dataReview.init({
|
|
|
- goodsId: this.goodsId,
|
|
|
- orderGoodsId: this.orderGoodsId,
|
|
|
- gradeId: this.gradeId,
|
|
|
- goodsName: this.goodsData.goodsName
|
|
|
- });
|
|
|
- // this.getbaseprofiletplists().then(async res => {
|
|
|
- // await this.courseCourseList();
|
|
|
- // this.getRebuildCourse();
|
|
|
- // });
|
|
|
- document.addEventListener("visibilitychange", this.pauseVideo);
|
|
|
- console.log(3);
|
|
|
- },
|
|
|
- beforeDestroy() {
|
|
|
- clearTimeout(this.takeSetInt);
|
|
|
- clearTimeout(this.videoPause);
|
|
|
- clearInterval(this.answerTimer);
|
|
|
- clearInterval(this.postTimer);
|
|
|
- clearInterval(this.livingTimer);
|
|
|
- document.removeEventListener("visibilitychange", this.pauseVideo);
|
|
|
- try {
|
|
|
- console.log("自动关闭");
|
|
|
- this.$msgbox.close();
|
|
|
- } catch (err) {}
|
|
|
- if (this.playSectionId && this.hasStart) {
|
|
|
- this.postStudyRecord();
|
|
|
- }
|
|
|
-
|
|
|
- // if (this.lockTimer) {
|
|
|
- // clearInterval(this.lockTimer);
|
|
|
- // this.$request
|
|
|
- // .lockDelLock({
|
|
|
- // action: "jxjy",
|
|
|
- // })
|
|
|
- // .then((res) => {});
|
|
|
- // }
|
|
|
- this.clears();
|
|
|
+ mounted() {
|
|
|
+ this.routerData = {
|
|
|
+ ...this.$route.query,
|
|
|
+ ...this.$route.params
|
|
|
+ };
|
|
|
+ this.getInit();
|
|
|
},
|
|
|
methods: {
|
|
|
- ...mapMutations(["getCartCount"]),
|
|
|
- ...mapActions(["getUserInfo"]),
|
|
|
- async callbackDataReview() {
|
|
|
- if (this.gradeId > 0) {
|
|
|
- //提交完资料返回判断是否已开班
|
|
|
- await this.getGradeInfo();
|
|
|
- //继教七大员公共课程同步
|
|
|
- if (this.gradeDetail.sevenYear) {
|
|
|
- await this.sevenCommonCourse();
|
|
|
- }
|
|
|
- }
|
|
|
- await this.courseCourseList();
|
|
|
- this.getRebuildCourse();
|
|
|
- },
|
|
|
- async sevenCommonCourse() {
|
|
|
- return new Promise(resolve => {
|
|
|
- this.$request
|
|
|
- .syncSevenPublicClass({ orderGoodsId: this.orderGoodsId })
|
|
|
- .then(res => {
|
|
|
- if (res.code == 200) {
|
|
|
- resolve();
|
|
|
- } else {
|
|
|
- reject();
|
|
|
- }
|
|
|
- })
|
|
|
- .catch(() => {
|
|
|
- reject();
|
|
|
- });
|
|
|
- });
|
|
|
- },
|
|
|
- /**
|
|
|
- *
|
|
|
- 获取用户讲义列表
|
|
|
- */
|
|
|
- getUserHandOutList() {
|
|
|
- this.$request
|
|
|
- .courseGoodsHandoutsList({ pageSize: 99, pageNum: 1 })
|
|
|
- .then(res => {
|
|
|
- this.handoutList = res.rows;
|
|
|
- });
|
|
|
- },
|
|
|
- isOtherFunc() {
|
|
|
- const confirmText = [
|
|
|
- "您的学习账号已经开通,请按照步骤操作,进行学习。",
|
|
|
- "1.点击【跳转学习网址】按钮",
|
|
|
- "2.打开学习网址后,选择【个人用户】进行登录",
|
|
|
- "(1)账号:您个人的身份证号码",
|
|
|
- "(2)密码:身份证号码,再加111111"
|
|
|
- ];
|
|
|
- const newDatas = [];
|
|
|
- const h = this.$createElement;
|
|
|
- for (const i in confirmText) {
|
|
|
- newDatas.push(h("p", null, confirmText[i]));
|
|
|
- }
|
|
|
- this.$confirm(h("div", null, newDatas), "温馨提示", {
|
|
|
- beforeClose: type => {
|
|
|
- if (type == "confirm") {
|
|
|
- window.open("http://admin.zhujianpeixun.com/", "_blank");
|
|
|
- } else if (type == "cancel") {
|
|
|
- this.$router.back(-1);
|
|
|
- }
|
|
|
- },
|
|
|
- confirmButtonText: "跳转学习网址",
|
|
|
- cancelButtonText: "关闭",
|
|
|
- closeOnClickModal: false,
|
|
|
- closeOnPressEscape: false,
|
|
|
- distinguishCancelAndClose: false,
|
|
|
- showClose: false
|
|
|
- });
|
|
|
- return;
|
|
|
- },
|
|
|
- switchBoxFunc() {
|
|
|
- this.switchBox = !this.switchBox;
|
|
|
- },
|
|
|
- backSwitchOfficeData(item) {
|
|
|
- this.switchPdf = item;
|
|
|
- this.readerResult = null;
|
|
|
- this.officeRender(this.$tools.splitImgHost(item.url));
|
|
|
- },
|
|
|
- //渲染xlsx
|
|
|
- officeRender(url, fileName) {
|
|
|
- axios({
|
|
|
- method: "get",
|
|
|
- responseType: "blob", // 设置响应文件格式
|
|
|
- url: url
|
|
|
- }).then(({ data }) => {
|
|
|
- var file = new File([data], fileName, {
|
|
|
- type: "application/json",
|
|
|
- lastModified: Date.now()
|
|
|
- });
|
|
|
- this.beforeUpload(file);
|
|
|
- });
|
|
|
- },
|
|
|
- beforeUpload(file) {
|
|
|
- let reader = new FileReader();
|
|
|
- reader.readAsArrayBuffer(file);
|
|
|
- reader.onload = loadEvent => {
|
|
|
- let arrayBuffer = loadEvent.target.result;
|
|
|
- this.readerResult = arrayBuffer;
|
|
|
- };
|
|
|
- return false;
|
|
|
- },
|
|
|
- pauseVideo() {
|
|
|
- if (this.takePhotoModal || this.confirmStatus || this.failToRegister) {
|
|
|
- return;
|
|
|
- }
|
|
|
- let _p = this.player;
|
|
|
- if (document.visibilityState === "hidden") {
|
|
|
- _p && _p.j2s_pauseVideo();
|
|
|
- } else {
|
|
|
- if (_p) {
|
|
|
- if (parseInt(_p.j2s_getCurrentTime()) < _p.j2s_getDuration()) {
|
|
|
- this.player.j2s_resumeVideo();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- handleClick(tab) {
|
|
|
- if (tab.name == "3") {
|
|
|
- this.$refs.answerQuestions[0].getAnswerList(); //答疑列表
|
|
|
- }
|
|
|
- },
|
|
|
- /**
|
|
|
- * 获取上次观看的直播
|
|
|
- */
|
|
|
- studyRecordGetLastLive() {
|
|
|
- this.$request
|
|
|
- .studyRecordGetLastLive({
|
|
|
- orderGoodsId: this.orderGoodsId,
|
|
|
- courseId: this.courseId
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- this.liveLast = res.data;
|
|
|
- });
|
|
|
- },
|
|
|
- /**
|
|
|
- * 获取观看记录
|
|
|
- */
|
|
|
- studyRecordQueryLiveLast() {
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
- this.$request
|
|
|
- .studyRecordQueryLiveLast({
|
|
|
- orderGoodsId: this.orderGoodsId,
|
|
|
- courseId: this.courseId
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- console.log(res, "couse");
|
|
|
- if (res.data) {
|
|
|
- if (res.data.sectionType == 1) {
|
|
|
- //视频
|
|
|
- this.chapterId = res.data.chapterId;
|
|
|
- this.moduleId = res.data.moduleId;
|
|
|
- this.playSectionId = res.data.sectionId;
|
|
|
- this.vid = res.data.recordingUrl;
|
|
|
- this.sectionItem = res.data;
|
|
|
- console.log("================sectionItem", this.sectionItem);
|
|
|
- this.playVideo(res.data);
|
|
|
- } else if (res.data.sectionType == 2) {
|
|
|
- //直播
|
|
|
- this.studyRecordGetLastLive();
|
|
|
- } else if (res.data.sectionType == 3) {
|
|
|
- //回放
|
|
|
- this.chapterId = res.data.chapterId;
|
|
|
- this.moduleId = res.data.moduleId;
|
|
|
- this.playSectionId = res.data.sectionId;
|
|
|
- this.vid = res.data.recordingUrl;
|
|
|
- this.sectionItem = res.data;
|
|
|
- this.playVideo(res.data);
|
|
|
- }
|
|
|
- if (res.data.sectionId > 0) {
|
|
|
- resolve(true);
|
|
|
- } else {
|
|
|
- resolve(false);
|
|
|
- }
|
|
|
- } else {
|
|
|
- resolve(false);
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
- },
|
|
|
- /**
|
|
|
- *
|
|
|
- 获取推荐列表
|
|
|
- */
|
|
|
- getRecommend() {
|
|
|
- this.$request
|
|
|
- .appCommonActivityRecommendList({
|
|
|
- businessId: this.goodsData.businessId,
|
|
|
- type: 1
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- if (res.rows.length) {
|
|
|
- this.recommendList = res.rows[0];
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
- addCart(status, goodsId) {
|
|
|
- this.$request
|
|
|
- .addCart({ goodsId: status ? goodsId : this.goodsId })
|
|
|
- .then(res => {
|
|
|
- this.getCartCount();
|
|
|
- this.$message({
|
|
|
- message: "加入购物车成功",
|
|
|
- type: "success"
|
|
|
- });
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- if (err.code == 500) {
|
|
|
- this.$message({
|
|
|
- message: err.msg,
|
|
|
- type: "warning"
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
- toGoodsDetail(item) {
|
|
|
- this.$router.push({
|
|
|
- path: "/course-detail/" + item.goodsId
|
|
|
- });
|
|
|
- },
|
|
|
- async takeOk() {
|
|
|
- this.loading = true;
|
|
|
- let compareFaceData = await this.faceRecognition();
|
|
|
- this.compareFaceData = compareFaceData;
|
|
|
- if (compareFaceData >= 80) {
|
|
|
- const waitYS = await this.imageInfos();
|
|
|
- this.postCoursePhotoRecord()
|
|
|
- .then(res => {
|
|
|
- this.photoHistoryList.push(this.photoIndex);
|
|
|
- this.postStudyRecord(); //提交记录
|
|
|
- //恢复播放
|
|
|
-
|
|
|
- this.$message({
|
|
|
- type: "success",
|
|
|
- message: "拍照成功"
|
|
|
- });
|
|
|
- this.takePhotoModal = false;
|
|
|
- this.isTaking = false;
|
|
|
- this.loading = false;
|
|
|
- var polyvPlayerContext = this.player;
|
|
|
- if (polyvPlayerContext && this.openPhotoStatus !== 1) {
|
|
|
- polyvPlayerContext.j2s_resumeVideo();
|
|
|
- }
|
|
|
- var polyvPlayerContext = this.playerzb;
|
|
|
- if (polyvPlayerContext) {
|
|
|
- polyvPlayerContext.j2s_resumeVideo();
|
|
|
- }
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- this.loading = false;
|
|
|
- console.log(err, "err");
|
|
|
- this.$message({
|
|
|
- type: "warning",
|
|
|
- message: "上传接口报错,请重新拍照上传"
|
|
|
- });
|
|
|
- this.reTake();
|
|
|
- });
|
|
|
- } else {
|
|
|
- this.$message({
|
|
|
- type: "warning",
|
|
|
- message: "人脸匹配不通过,请重新拍照上传"
|
|
|
- });
|
|
|
-
|
|
|
- setTimeout(() => {
|
|
|
- this.loading = false;
|
|
|
- this.reTake();
|
|
|
- }, 2000);
|
|
|
- return;
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- backLI() {
|
|
|
- this.player.j2s_seekVideo(0);
|
|
|
- this.showRecordStatus = false;
|
|
|
- },
|
|
|
-
|
|
|
- convertBase64UrlToBlob(urlData) {
|
|
|
- var localData = urlData; //dataUrl为base64位
|
|
|
- let base = atob(localData.substring(localData.indexOf(",") + 1)); // base是将base64编码解码,去掉data:image/png;base64部分
|
|
|
- let length = base.length;
|
|
|
- let url = new Uint8Array(length);
|
|
|
- while (length--) {
|
|
|
- url[length] = base.charCodeAt(length);
|
|
|
- }
|
|
|
- let file = new File([url], "a.jpg", {
|
|
|
- type: "image/jpg"
|
|
|
- });
|
|
|
- //最后将file,通过ajax请求做为参数传给服务器就可以了
|
|
|
- return file;
|
|
|
- },
|
|
|
-
|
|
|
- imageInfos() {
|
|
|
- var self = this;
|
|
|
- return new Promise(async (resolve, reject) => {
|
|
|
- const waitUpload = await self.uploadFile(self.faceUrl, 0);
|
|
|
- resolve(waitUpload);
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- getGradeInfo() {
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
- let self = this;
|
|
|
- this.$request.goodsGradeInfo(this.gradeId).then(res => {
|
|
|
- if (res.code == 200) {
|
|
|
- self.gradeDetail = res.data;
|
|
|
- if (self.needProfileModal) {
|
|
|
- return reject();
|
|
|
- }
|
|
|
- /**
|
|
|
- * 补充条件 Start
|
|
|
- */
|
|
|
- console.log(
|
|
|
- "补充条件:",
|
|
|
- res.data.interfaceAccountId,
|
|
|
- res.data.learnStatus
|
|
|
- );
|
|
|
- if (res.data.interfaceAccountId > 0 && res.data.learnStatus > 0) {
|
|
|
- const confirmText = [
|
|
|
- "您的学习账号已经开通,请按照步骤操作,进行学习。",
|
|
|
- "1.点击【跳转学习网址】按钮",
|
|
|
- "2.打开学习网址后,选择【个人用户】进行登录",
|
|
|
- "(1)账号:您个人的身份证号码",
|
|
|
- "(2)密码:身份证号码,再加111111"
|
|
|
- ];
|
|
|
- const newDatas = [];
|
|
|
- const h = this.$createElement;
|
|
|
- for (const i in confirmText) {
|
|
|
- newDatas.push(h("p", null, confirmText[i]));
|
|
|
- }
|
|
|
- this.$confirm(h("div", null, newDatas), "温馨提示", {
|
|
|
- beforeClose: (type, y, done) => {
|
|
|
- if (type == "confirm") {
|
|
|
- window.open("http://admin.zhujianpeixun.com/", "_blank");
|
|
|
- } else if (type == "cancel") {
|
|
|
- this.$router.back(-1);
|
|
|
- }
|
|
|
- },
|
|
|
- confirmButtonText: "跳转学习网址",
|
|
|
- cancelButtonText: "关闭",
|
|
|
- closeOnClickModal: false,
|
|
|
- closeOnPressEscape: false,
|
|
|
- distinguishCancelAndClose: false,
|
|
|
- showClose: false
|
|
|
- });
|
|
|
- return;
|
|
|
- }
|
|
|
- /**
|
|
|
- * 补充条件 End
|
|
|
- */
|
|
|
- if (self.gradeDetail.learningStatus == 2) {
|
|
|
- this.$confirm(
|
|
|
- `当前课程正在申请中,正式开班后方可进行学习,请耐心等候!`,
|
|
|
- "提示",
|
|
|
- {
|
|
|
- confirmButtonText: "确定",
|
|
|
- closeOnClickModal: false,
|
|
|
- closeOnPressEscape: false,
|
|
|
- showCancelButton: false,
|
|
|
- distinguishCancelAndClose: false,
|
|
|
- showClose: false
|
|
|
- }
|
|
|
- )
|
|
|
- .then(_ => {
|
|
|
- this.$router.back(-1);
|
|
|
- })
|
|
|
- .catch(_ => {});
|
|
|
- }
|
|
|
- if (
|
|
|
- self.gradeDetail.learningStatus == 3 &&
|
|
|
- Number(self.gradeDetail.learningTimeStart) >
|
|
|
- Number(new Date() / 1000)
|
|
|
- ) {
|
|
|
- this.$confirm(
|
|
|
- `当前课程正在申请中,正式开班后方可进行学习,请耐心等候!`,
|
|
|
- "提示",
|
|
|
- {
|
|
|
- confirmButtonText: "返回",
|
|
|
- closeOnClickModal: false,
|
|
|
- closeOnPressEscape: false,
|
|
|
- showCancelButton: false,
|
|
|
- distinguishCancelAndClose: false,
|
|
|
- showClose: false
|
|
|
- }
|
|
|
- )
|
|
|
- .then(_ => {
|
|
|
- this.$router.back(-1);
|
|
|
- })
|
|
|
- .catch(_ => {});
|
|
|
- }
|
|
|
- if (
|
|
|
- (res.data.interfaceAccountId > 0 && res.data.learnStatus > 0) ||
|
|
|
- self.gradeDetail.learningStatus == 2 ||
|
|
|
- (self.gradeDetail.learningStatus == 3 &&
|
|
|
- Number(self.gradeDetail.learningTimeStart) >
|
|
|
- Number(new Date() / 1000))
|
|
|
- ) {
|
|
|
- reject();
|
|
|
- } else {
|
|
|
- resolve();
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- this.$store.state.allowLoading = true;
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- uploadFile(options, int) {
|
|
|
- var self = this;
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
- var data = {
|
|
|
- imageStatus: int,
|
|
|
- gradeId: this.gradeId,
|
|
|
- orderGoodsId: this.orderGoodsId
|
|
|
- };
|
|
|
- self.$request
|
|
|
- .getPolicy(data)
|
|
|
- .then(res => {
|
|
|
- var ossToken = res.data.resultContent;
|
|
|
- if (ossToken.host == null || ossToken.host == undefined) {
|
|
|
- this.$message({
|
|
|
- type: "warning",
|
|
|
- message: "上传路径报错" + JSON.stringify(res.data)
|
|
|
- });
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- let data = this.$tools.convertBase64UrlToBlob(this.faceUrl);
|
|
|
-
|
|
|
- this.$upload
|
|
|
- .upload(data, 0)
|
|
|
- .then(res => {
|
|
|
- this.ossAvatarUrl = res;
|
|
|
- resolve(res);
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- this.$message({
|
|
|
- type: "warning",
|
|
|
- message: "上传接口报错,请重新拍照上传"
|
|
|
- });
|
|
|
- this.reTake();
|
|
|
- });
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- this.$message({
|
|
|
- type: "warning",
|
|
|
- message: "签名错误" + JSON.stringify(err)
|
|
|
- });
|
|
|
- return;
|
|
|
- });
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- faceRecognition() {
|
|
|
- return new Promise(resolve => {
|
|
|
- this.$request
|
|
|
- .faceCertificationCompareFace({
|
|
|
- imageA: this.faceUrl,
|
|
|
- orderGoodsId: this.orderGoodsId,
|
|
|
- gradeId: this.gradeId
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- resolve(res.data);
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- if (err.toString().indexOf("timeout") != -1) {
|
|
|
- err = {
|
|
|
- msg: "拍照超时,请重新拍照"
|
|
|
- };
|
|
|
- }
|
|
|
- this.loading = false;
|
|
|
- this.$message({
|
|
|
- type: "warning",
|
|
|
- message: err.msg
|
|
|
- });
|
|
|
- });
|
|
|
- });
|
|
|
- },
|
|
|
- /**
|
|
|
- * 点击重拍
|
|
|
- */
|
|
|
- reTake() {
|
|
|
- this.faceUrl = "";
|
|
|
- this.isTaking = true;
|
|
|
- this.getUserMedia({
|
|
|
- video: {
|
|
|
- width: 400,
|
|
|
- height: 400
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
- // 点击拍照按钮
|
|
|
- onPhoto() {
|
|
|
- // if (this.isIE) {
|
|
|
- // window.webcam.capture();
|
|
|
- // } else {
|
|
|
- const canvas = document.createElement("canvas");
|
|
|
- canvas.width = 400;
|
|
|
- canvas.height = 400;
|
|
|
- const context = canvas.getContext("2d");
|
|
|
- const video = document.getElementById("video");
|
|
|
- context.drawImage(video, 0, 0, 400, 400);
|
|
|
- this.faceUrl = canvas.toDataURL("image/png");
|
|
|
- this.isTaking = false;
|
|
|
- // }
|
|
|
- },
|
|
|
- getUserMedia(constraints, success, error) {
|
|
|
- if (window.navigator.mediaDevices.getUserMedia) {
|
|
|
- // 最新的标准API
|
|
|
- window.navigator.mediaDevices
|
|
|
- .getUserMedia(constraints)
|
|
|
- .then(success)
|
|
|
- .catch(error);
|
|
|
- } else if (window.navigator.webkitGetUserMedia) {
|
|
|
- // webkit核心浏览器
|
|
|
- window.navigator.webkitGetUserMedia(constraints, success, error);
|
|
|
- } else if (window.navigator.mozGetUserMedia) {
|
|
|
- // firfox浏览器
|
|
|
- window.navigator.mozGetUserMedia(constraints, success, error);
|
|
|
- } else if (window.navigator.getUserMedia) {
|
|
|
- // 旧版API
|
|
|
- window.navigator.getUserMedia(constraints, success, error);
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- photographSuccess(stream) {
|
|
|
- // 兼容webkit核心浏览器
|
|
|
- if (this.isVirtualCamera(stream)) {
|
|
|
- return;
|
|
|
- }
|
|
|
- this.isTaking = true;
|
|
|
- this.takePhotoModal = true;
|
|
|
-
|
|
|
- this.$nextTick(() => {
|
|
|
- const video = document.getElementById("video");
|
|
|
- // 将视频流设置为video元素的源
|
|
|
- console.dir(video);
|
|
|
- video.srcObject = stream;
|
|
|
- this.mediaStreamTrack =
|
|
|
- typeof stream.stop === "function" ? stream : stream.getTracks()[0];
|
|
|
- video.play();
|
|
|
- });
|
|
|
- },
|
|
|
- photographError(err) {
|
|
|
- this.$confirm(
|
|
|
- "课程学习需要开启摄像头进行拍照,经检测您的设备无摄像头可使用,请检测环境是否支持。",
|
|
|
- "提示",
|
|
|
- {
|
|
|
- confirmButtonText: "返回",
|
|
|
- showConfirmButton: true,
|
|
|
- closeOnClickModal: false,
|
|
|
- showCancelButton: false,
|
|
|
- closeOnPressEscape: false,
|
|
|
- distinguishCancelAndClose: false,
|
|
|
- showClose: false
|
|
|
- }
|
|
|
- ).then(() => {
|
|
|
- this.$router.back(-1);
|
|
|
- });
|
|
|
- },
|
|
|
- isVirtualCamera(stream) {
|
|
|
- const list = [
|
|
|
- "VCam",
|
|
|
- "ManyCam",
|
|
|
- "OBS",
|
|
|
- "ClassInCam",
|
|
|
- "Ev",
|
|
|
- "Video2Webcam"
|
|
|
- ];
|
|
|
- let isT = list.some(e => {
|
|
|
- return stream.getTracks()[0].label.indexOf(e) != -1;
|
|
|
- });
|
|
|
- if (isT) {
|
|
|
- this.$confirm("检测到你使用虚拟摄像头,无法继续学习。", "提示", {
|
|
|
- confirmButtonText: "返回",
|
|
|
- showConfirmButton: true,
|
|
|
- closeOnClickModal: false,
|
|
|
- showCancelButton: false,
|
|
|
- closeOnPressEscape: false,
|
|
|
- distinguishCancelAndClose: false,
|
|
|
- showClose: false
|
|
|
- }).then(() => {
|
|
|
- this.$router.go(-1);
|
|
|
- });
|
|
|
- }
|
|
|
- return isT;
|
|
|
- },
|
|
|
- /**
|
|
|
- * 切换科目
|
|
|
- */
|
|
|
- courseChange() {
|
|
|
- return new Promise(resolve => {
|
|
|
- this.needOpen = true;
|
|
|
- this.noteParams = {
|
|
|
- pageNum: 1
|
|
|
- // pageSize: 4,
|
|
|
- };
|
|
|
- this.duration = 0;
|
|
|
- this.playSectionId = 0;
|
|
|
- this.vid = "";
|
|
|
- if (this.player) {
|
|
|
- this.player.destroy();
|
|
|
- }
|
|
|
- this.player = "";
|
|
|
- if (this.playerzb) {
|
|
|
- this.playerzb.destroy();
|
|
|
- }
|
|
|
- this.playerzb = "";
|
|
|
- this.vidzb = "";
|
|
|
- this.nowTime = Number(new Date().getTime() / 1000).toFixed(0);
|
|
|
- this.$refs.answerQuestions[0].getAnswerList(); //答疑列表
|
|
|
- this.$refs.notes[0].getNoteList(); //获取节笔记
|
|
|
- resolve();
|
|
|
- });
|
|
|
- },
|
|
|
- openModule(menuItem, status = false, isAuto = false) {
|
|
|
- menuItem.showList = !menuItem.showList;
|
|
|
- let { list, isRebuild, id, courseId } = menuItem;
|
|
|
- if (list.length) return;
|
|
|
- return this.$request
|
|
|
- .reChapterList({
|
|
|
- moduleId: id,
|
|
|
- gradeId: this.gradeId,
|
|
|
- courseId: courseId,
|
|
|
- rebuild: isRebuild ? 1 : undefined
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- for (let i = 0; i < res.data.length; i++) {
|
|
|
- let item = res.data[i];
|
|
|
- item.id = item.chapterId;
|
|
|
- item.showList = false;
|
|
|
- item.list = [];
|
|
|
- item.parent = menuItem;
|
|
|
- isRebuild ? (item.isRebuild = 1) : (item.menuType = 2);
|
|
|
- }
|
|
|
- menuItem.list = res.data;
|
|
|
- if (isAuto) {
|
|
|
- return Promise.resolve(res.data);
|
|
|
- }
|
|
|
- if (isRebuild) return;
|
|
|
- if (status) {
|
|
|
- const FindIndexs = menuItem.list.findIndex(item => {
|
|
|
- return item.chapterId == this.sectionItem.chapterId;
|
|
|
- });
|
|
|
- if (FindIndexs != -1) {
|
|
|
- this.openChapter(menuItem.list[FindIndexs]);
|
|
|
- } else {
|
|
|
- this.$message.warning("章列表定位失败");
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (this.needOpen) {
|
|
|
- this.openChapter(menuItem.list[0]);
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
- openChapter(chapter) {
|
|
|
- chapter.showList = !chapter.showList;
|
|
|
- console.log(chapter.showList, this.courseList);
|
|
|
- //获取节试卷列表
|
|
|
- let {
|
|
|
- chapterId,
|
|
|
- menuId,
|
|
|
- list,
|
|
|
- moduleId,
|
|
|
- id,
|
|
|
- isRebuild,
|
|
|
- courseId
|
|
|
- } = chapter;
|
|
|
- this.$request
|
|
|
- .reSectionExamList({
|
|
|
- chapterId: chapterId || menuId,
|
|
|
- courseId: this.courseId,
|
|
|
- gradeId: this.gradeId
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- this.sectionExam = [...this.sectionExam, ...res.data];
|
|
|
- });
|
|
|
- if (list.length) {
|
|
|
- return;
|
|
|
- }
|
|
|
- return this.$request
|
|
|
- .reSectionList({
|
|
|
- chapterId: id,
|
|
|
- gradeId: this.gradeId,
|
|
|
- courseId: courseId,
|
|
|
- rebuild: isRebuild ? 1 : undefined,
|
|
|
- moduleId: moduleId || 0
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- let newArr = res.data.filter(item => {
|
|
|
- return item.type != 2;
|
|
|
- });
|
|
|
- chapter.canLearn = newArr.every(item => item.learning == 1);
|
|
|
- res.data.forEach(section => {
|
|
|
- section.parent = chapter;
|
|
|
- let { sectionId, moduleId, chapterId } = this.sectionItem;
|
|
|
- if (
|
|
|
- section.sectionId == sectionId &&
|
|
|
- section.moduleId == moduleId &&
|
|
|
- section.chapterId == chapterId
|
|
|
- ) {
|
|
|
- this.sectionItem = section;
|
|
|
- }
|
|
|
- });
|
|
|
- chapter.list = res.data;
|
|
|
- if (this.needOpen) {
|
|
|
- this.needOpen = false;
|
|
|
- }
|
|
|
- return Promise.resolve(chapter.list);
|
|
|
- });
|
|
|
- },
|
|
|
- getGoodsDetail() {
|
|
|
- return new Promise(resolve => {
|
|
|
- let self = this;
|
|
|
- this.$request.goodsDetail(this.goodsId).then(res => {
|
|
|
- self.goodsData = res.data;
|
|
|
- self.gradeId = self.goodsData.gradeId;
|
|
|
- if (this.goodsData.buyNote) {
|
|
|
- this.tabList = [
|
|
|
- { name: "1", label: "讲义资料" },
|
|
|
- { name: "2", label: "推荐课程" },
|
|
|
- { name: "3", label: "学员须知" }
|
|
|
- ];
|
|
|
- } else {
|
|
|
- this.tabList = [
|
|
|
- { name: "1", label: "讲义资料" },
|
|
|
- { name: "2", label: "推荐课程" }
|
|
|
- ];
|
|
|
- }
|
|
|
- this.courseBusiness();
|
|
|
- if (self.goodsData.goodsPlayConfig) {
|
|
|
- self.goodsPlayConfig = JSON.parse(self.goodsData.goodsPlayConfig);
|
|
|
- if (self.goodsPlayConfig.autoPlay > 0) {
|
|
|
- self.autoplay = true;
|
|
|
- }
|
|
|
- if (self.goodsPlayConfig.drag > 0) {
|
|
|
- self.isAllowSeek = "off";
|
|
|
- }
|
|
|
- if (self.goodsPlayConfig.speed > 0) {
|
|
|
- self.playbackRate = true;
|
|
|
- }
|
|
|
- }
|
|
|
- if (self.goodsData.goodsPhotographConfig) {
|
|
|
- self.goodsPhotographConfig = JSON.parse(
|
|
|
- self.goodsData.goodsPhotographConfig
|
|
|
- );
|
|
|
- if (self.goodsPhotographConfig.photoNum > 0) {
|
|
|
- self.photoNum = self.goodsPhotographConfig.photoNum;
|
|
|
- }
|
|
|
- }
|
|
|
- resolve();
|
|
|
- });
|
|
|
- });
|
|
|
- },
|
|
|
- // 新增用户视频学习日志
|
|
|
- studyLog(moduleId, chapterId, sectionId) {
|
|
|
- this.$axios({
|
|
|
- url: "/user/study/log",
|
|
|
- method: "post",
|
|
|
- data: {
|
|
|
- goodsId: this.goodsId,
|
|
|
- courseId: this.courseId,
|
|
|
- moduleId: moduleId || 0,
|
|
|
- chapterId: chapterId || 0,
|
|
|
- sectionId: sectionId || 0,
|
|
|
- fromPlat: 2, //来源平台 1小程序 2PC网站
|
|
|
- goodsType: 1, // 商品类型 1视频2题库 3补考 4前培 5虚拟赠送题库 6直播
|
|
|
- orderGoodsId: this.orderGoodsId
|
|
|
- }
|
|
|
- }).then(res => {});
|
|
|
- },
|
|
|
- /**
|
|
|
- * 点击节
|
|
|
- */
|
|
|
- async getResource(section, index) {
|
|
|
- this.clickSectionItem = section;
|
|
|
- if (this.clickLock) {
|
|
|
- return;
|
|
|
- }
|
|
|
- this.clickLock = true;
|
|
|
- this.initVideo(section);
|
|
|
- this.playTabIndex = index;
|
|
|
- },
|
|
|
- initVideo(option) {
|
|
|
- this.playVideo(option);
|
|
|
- },
|
|
|
- /**
|
|
|
- * 判断是否是当前播放的节
|
|
|
- */
|
|
|
- isActive(section) {
|
|
|
- let moduleId = section.moduleId || 0;
|
|
|
- let chapterId = section.chapterId || 0;
|
|
|
- let sectionId = section.sectionId || section.menuId;
|
|
|
- if (
|
|
|
- moduleId == this.moduleId &&
|
|
|
- chapterId == this.chapterId &&
|
|
|
- sectionId == this.playSectionId
|
|
|
- ) {
|
|
|
- return true;
|
|
|
- } else {
|
|
|
- return false;
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- async playVideo(option) {
|
|
|
- if (option.sectionType == 3) {
|
|
|
- // 回放
|
|
|
- if (Object.keys(this.clickSectionItem).length) {
|
|
|
- //this.clickSectionItem 判断点击节才跳转, 不判断的话一进来页面到这里就直接跳转了
|
|
|
- this.$router.push({
|
|
|
- path: "/living-room/" + option.liveUrl,
|
|
|
- query: {
|
|
|
- goodsId: this.goodsId,
|
|
|
- courseId: this.courseId,
|
|
|
- gradeId: this.gradeId,
|
|
|
- orderGoodsId: this.orderGoodsId,
|
|
|
- sectionId: option.sectionId || option.menuId,
|
|
|
- chapterId: option.chapterId || 0,
|
|
|
- moduleId: option.moduleId || 0,
|
|
|
- sectionType: 3,
|
|
|
- goodsName: option.name,
|
|
|
- vid: option.recordingUrl // 回放vid
|
|
|
- }
|
|
|
- });
|
|
|
- this.clickSectionItem = {};
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- if (option.sectionType == 1) {
|
|
|
- let query = {
|
|
|
- goodsId: this.goodsId,
|
|
|
- courseId: this.courseId,
|
|
|
- gradeId: this.gradeId,
|
|
|
- orderGoodsId: this.orderGoodsId,
|
|
|
- moduleId: option.moduleId || 0,
|
|
|
- chapterId: option.chapterId || 0,
|
|
|
- sectionId: option.sectionId || option.menuId || 0,
|
|
|
- sectionType: 1
|
|
|
- };
|
|
|
- this.$router.replace({ path: this.$route.path, query });
|
|
|
- //提交保存观看历史
|
|
|
- if (this.playSectionId) {
|
|
|
- this.postStudyRecord(0, this.playSectionId);
|
|
|
- }
|
|
|
- this.player &&
|
|
|
- this.player.HTML5.video.removeEventListener(
|
|
|
- "timeupdate",
|
|
|
- this.timeEvent
|
|
|
- );
|
|
|
- //播放视频
|
|
|
- this.showRecordStatus = false; //隐藏播放记录提示
|
|
|
- this.openPhotoStatus = 0;
|
|
|
- this.sectionItem = option;
|
|
|
- this.isPlayRebuild = option.rebuild;
|
|
|
- this.moduleId = option.moduleId || 0;
|
|
|
- this.chapterId = option.chapterId || 0;
|
|
|
- this.playSectionId = option.sectionId || option.menuId;
|
|
|
- await this.getPhotoLastRecord();
|
|
|
- this.recordObj = await this.getRecordLast();
|
|
|
- this.$refs.notes[0].getNoteList();
|
|
|
- await this.clears();
|
|
|
-
|
|
|
- this.vid = option.recordingUrl;
|
|
|
- this.historyChatMsgList = [];
|
|
|
- this.loadPlayerScript(this.loadPlayer);
|
|
|
- setTimeout(() => {
|
|
|
- this.clickLock = false;
|
|
|
- }, 3000);
|
|
|
- this.studyLog(this.moduleId, this.chapterId, this.playSectionId);
|
|
|
- }
|
|
|
- if (option.sectionType == 2) {
|
|
|
- //直播
|
|
|
-
|
|
|
- //提交保存观看历史
|
|
|
- if (this.playSectionId) {
|
|
|
- this.postStudyRecord(0, this.playSectionId);
|
|
|
- }
|
|
|
-
|
|
|
- this.player &&
|
|
|
- this.player.HTML5.video.removeEventListener(
|
|
|
- "timeupdate",
|
|
|
- this.timeEvent
|
|
|
- );
|
|
|
- //播放视频
|
|
|
- this.showRecordStatus = false; //隐藏播放记录提示
|
|
|
- this.sectionItem = option;
|
|
|
- console.log(option, "option");
|
|
|
- this.isPlayRebuild = option.rebuild;
|
|
|
- this.moduleId = option.moduleId || 0;
|
|
|
- this.chapterId = option.chapterId || 0;
|
|
|
- this.playSectionId = option.sectionId || option.menuId;
|
|
|
- // console.log(this.moduleId, this.chapterId, this.playSectionId);
|
|
|
- await this.getPhotoLastRecord();
|
|
|
- this.recordObj = await this.getRecordLast();
|
|
|
- this.$refs.notes[0].getNoteList();
|
|
|
- //设置播放的节ID
|
|
|
- await this.clears();
|
|
|
- this.vidzb = option.liveUrl;
|
|
|
- this.$router.push({
|
|
|
- path: "/living-room/" + option.liveUrl,
|
|
|
- query: {
|
|
|
- goodsId: this.goodsId,
|
|
|
- courseId: this.courseId,
|
|
|
- gradeId: this.gradeId,
|
|
|
- orderGoodsId: this.orderGoodsId,
|
|
|
- sectionId: option.sectionId || option.menuId,
|
|
|
- chapterId: option.chapterId || 0,
|
|
|
- moduleId: option.moduleId || 0,
|
|
|
- sectionType: 2
|
|
|
- }
|
|
|
- });
|
|
|
- // this.loadPlayerScriptzb(this.loadPlayerzb);
|
|
|
- // setTimeout(() => {
|
|
|
- // this.clickLock = false;
|
|
|
- // }, 3000);
|
|
|
- }
|
|
|
- },
|
|
|
- studyRecordMenuAllList() {
|
|
|
- return new Promise(resolve => {
|
|
|
- this.$request
|
|
|
- .studyRecordMenuAllListWithExam({
|
|
|
- courseId: this.courseId,
|
|
|
- gradeId: this.gradeId,
|
|
|
- goodsId: this.goodsId
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- resolve(res.data);
|
|
|
- });
|
|
|
- });
|
|
|
- },
|
|
|
- loadPlayerzb() {
|
|
|
- var self = this;
|
|
|
- const polyvLivePlayer = window.polyvLivePlayer;
|
|
|
- this.playerzb = polyvLivePlayer({
|
|
|
- wrap: "#playerzb",
|
|
|
- width: 810,
|
|
|
- height: 455,
|
|
|
- showLine: "off",
|
|
|
- uid: this.uidzb,
|
|
|
- vid: this.vidzb
|
|
|
- });
|
|
|
-
|
|
|
- this.playerzb.on("s2j_onStartPlay", () => {
|
|
|
- console.log("s2j_onStartPlay");
|
|
|
- this.hasStart = true;
|
|
|
- this.livingTimer = setInterval(self.timeEventLiving, 1000);
|
|
|
- });
|
|
|
-
|
|
|
- this.playerzb.on("s2j_onOver", () => {
|
|
|
- console.log("s2j_onOver");
|
|
|
- clearInterval(this.livingTimer);
|
|
|
- this.hasStart = false;
|
|
|
- this.$message({
|
|
|
- type: "success",
|
|
|
- message: "播放完毕"
|
|
|
- });
|
|
|
- this.postStudyRecord(1);
|
|
|
- });
|
|
|
- },
|
|
|
- // 播放视频
|
|
|
- loadPlayer() {
|
|
|
- var self = this;
|
|
|
- const polyvPlayer = window.polyvPlayer;
|
|
|
- self.$request.obtainpolyvvideosign(self.vid).then(res => {
|
|
|
- self.player = polyvPlayer({
|
|
|
- wrap: "#player",
|
|
|
- width: 810,
|
|
|
- showLine: "off",
|
|
|
- height: 455,
|
|
|
- ban_history_time: "on",
|
|
|
- vid: self.vid,
|
|
|
- autoplay: this.autoplay,
|
|
|
- ban_seek: this.isAllowSeek,
|
|
|
- speed: this.playbackRate,
|
|
|
- teaser_show: 1,
|
|
|
- tail_show: 1,
|
|
|
- hideSwitchPlayer: true,
|
|
|
- watchStartTime: this.recordObj.videoCurrentTime,
|
|
|
- ts: res.data.ts,
|
|
|
- sign: res.data.sign,
|
|
|
- // adMatter: [
|
|
|
- // {
|
|
|
- // // 广告参数详细配置
|
|
|
- // location: 1, //广告位置: 1 片头广告,2 暂停广告,3 片尾广告,4 弹窗广告
|
|
|
- // adtype: 2, //广告资源类型: 1 图片广告,2 视频广告,3 swf广告(flash播放器生效)
|
|
|
- // matterurl: "https://www.runoob.com/try/demo_source/movie.mp4", //广告资源URL
|
|
|
- // timesize: 5, //广告时长,单位:秒
|
|
|
- // skipenabled: false, //是否显示跳过按钮
|
|
|
- // },
|
|
|
- // {
|
|
|
- // // 广告参数详细配置
|
|
|
- // location: 3, //广告位置: 1 片头广告,2 暂停广告,3 片尾广告,4 弹窗广告
|
|
|
- // adtype: 2, //广告资源类型: 1 图片广告,2 视频广告,3 swf广告(flash播放器生效)
|
|
|
- // matterurl: "https://www.runoob.com/try/demo_source/movie.mp4", //广告资源URL
|
|
|
- // timesize: 5, //广告时长,单位:秒
|
|
|
- // skipenabled: false, //是否显示跳过按钮
|
|
|
- // },
|
|
|
- // ],
|
|
|
- playsafe: function(vid, next) {
|
|
|
- self.$request.obtainpolyvvideopcsign(vid).then(res => {
|
|
|
- next(res.data);
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
- this.player.HTML5.video.addEventListener("timeupdate", self.timeEvent);
|
|
|
- this.player.on("s2j_onPlayStart", () => {
|
|
|
- //开始播放每5秒提交一次观看时间
|
|
|
- this.hasStart = true;
|
|
|
- clearInterval(this.postTimer);
|
|
|
- this.postTimer = setInterval(() => {
|
|
|
- this.postStudyRecord(0, this.playSectionId, 5);
|
|
|
- }, 30000);
|
|
|
- if (this.recordObj.videoCurrentTime) {
|
|
|
- this.showRecordStatus = true;
|
|
|
- setTimeout(() => {
|
|
|
- this.showRecordStatus = false;
|
|
|
- }, 5000);
|
|
|
- } else {
|
|
|
- //新视频直接提交一条观看记录
|
|
|
- // this.postStudyRecord(0);
|
|
|
- this.showRecordStatus = false;
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- this.player.on("s2j_onVideoPause", () => {
|
|
|
- clearInterval(this.postTimer);
|
|
|
- if (this.sectionItem.learning != 1 && this.goodsData.erJianErZao) {
|
|
|
- console.log(123);
|
|
|
- this.videoPause = setTimeout(() => {
|
|
|
- if (!this.takePhotoModal) {
|
|
|
- if (this.isFullScreen()) {
|
|
|
- this.exitFullscreen();
|
|
|
- }
|
|
|
- this.confirmStatus = true;
|
|
|
- this.$confirm("检测暂停时间过长,刷新当前页面", "提示", {
|
|
|
- confirmButtonText: "确定",
|
|
|
- cancelButtonText: "取消",
|
|
|
- showCancelButton: false,
|
|
|
- closeOnClickModal: false,
|
|
|
- closeOnPressEscape: false,
|
|
|
- showClose: false,
|
|
|
- type: "warning"
|
|
|
- })
|
|
|
- .then(() => {
|
|
|
- this.$router.go(0);
|
|
|
- this.confirmStatus = false;
|
|
|
- })
|
|
|
- .catch(() => {
|
|
|
- this.confirmStatus = false;
|
|
|
- });
|
|
|
- }
|
|
|
- }, 300000);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- this.player.on("s2j_onVideoPlay", () => {
|
|
|
- if (this.postTimer) {
|
|
|
- this.postTimer = setInterval(() => {
|
|
|
- this.postStudyRecord(0, this.playSectionId, 5);
|
|
|
- }, 30000);
|
|
|
- }
|
|
|
- if (this.sectionItem.learning != 1 && this.videoPause) {
|
|
|
- clearTimeout(this.videoPause);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- this.player.on("s2j_onPlayOver", () => {
|
|
|
- this.hasStart = false;
|
|
|
- clearInterval(this.postTimer);
|
|
|
- this.$message({
|
|
|
- type: "success",
|
|
|
- message: "播放完毕"
|
|
|
- });
|
|
|
-
|
|
|
- if (this.isFullScreen()) {
|
|
|
- this.exitFullscreen();
|
|
|
- }
|
|
|
- this.postStudyRecord(1);
|
|
|
- });
|
|
|
- });
|
|
|
+ async getInit() {
|
|
|
+ await this.getGoodsData(); //获取商品详情
|
|
|
+ await this.courseBusiness(); //获取培训项目详情
|
|
|
},
|
|
|
- timeEventLiving() {
|
|
|
- var polyvPlayerContext = this.playerzb;
|
|
|
- if (polyvPlayerContext) {
|
|
|
- this.liveDuration = this.liveDuration + 1; //每隔1秒
|
|
|
- console.log(this.liveDuration);
|
|
|
- if (this.liveDuration == 2) {
|
|
|
- //直播第2秒拍照
|
|
|
- if (
|
|
|
- this.goodsPhotographConfig &&
|
|
|
- this.goodsPhotographConfig.livephotograph == 1 &&
|
|
|
- this.sectionItem.learning != 1 &&
|
|
|
- this.photoHistoryList.length == 0
|
|
|
- ) {
|
|
|
- //开启直播拍照
|
|
|
- polyvPlayerContext.j2s_pauseVideo();
|
|
|
- this.openPhoto();
|
|
|
- } else {
|
|
|
- this.postStudyRecord();
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- timeEvent() {
|
|
|
- let self = this;
|
|
|
- this.timer && clearInterval(this.timer);
|
|
|
- var polyvPlayerContext = this.player;
|
|
|
- if (polyvPlayerContext) {
|
|
|
- this.playTime = polyvPlayerContext.j2s_getCurrentTime(); //播放时刻
|
|
|
- if (
|
|
|
- this.sectionItem.learning != 1 &&
|
|
|
- (this.goodsData.erJianErZao || this.photoNum > 0)
|
|
|
- ) {
|
|
|
- this.configPhoto();
|
|
|
- let photoTime = 0; //获取拍照秒数
|
|
|
- for (let i = 0; i < this.photoList.length; i++) {
|
|
|
- photoTime = Number(this.photoList[i]); //获取拍照秒数
|
|
|
- if (photoTime < this.playTime && photoTime > this.playTime - 8) {
|
|
|
- //3秒区间内才触发拍照,避免拉动滚动条
|
|
|
- if (
|
|
|
- this.photoHistoryList.indexOf(i) < 0 &&
|
|
|
- this.sectionItem.learning != 1
|
|
|
- ) {
|
|
|
- //不存在拍照历史,没有重修过,没有学过,则拍照
|
|
|
- //启动拍照
|
|
|
- //暂停
|
|
|
|
|
|
- polyvPlayerContext.j2s_pauseVideo();
|
|
|
- this.photoIndex = i;
|
|
|
- this.openPhoto();
|
|
|
- } else {
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- getPhotoLastRecord() {
|
|
|
- clearTimeout(this.videoPause);
|
|
|
+ //获取培训项目详情
|
|
|
+ courseBusiness() {
|
|
|
return new Promise(resolve => {
|
|
|
- let self = this;
|
|
|
- this.photoConfig = false;
|
|
|
- let data = {
|
|
|
- sectionId: parseInt(self.playSectionId),
|
|
|
- goodsId: parseInt(self.goodsId),
|
|
|
- courseId: parseInt(self.courseId),
|
|
|
- gradeId: self.gradeId,
|
|
|
- chapterId: parseInt(self.chapterId),
|
|
|
- moduleId: parseInt(self.moduleId)
|
|
|
- };
|
|
|
- this.$request.getPhotoLastRecord(data).then(res => {
|
|
|
- //清空历史数据
|
|
|
- self.photoHistoryList = [];
|
|
|
- this.photoIndex = 0;
|
|
|
- self.photoList = [];
|
|
|
- for (let i = 0; i < res.data.length; i++) {
|
|
|
- //-2存储随机拍照数组
|
|
|
- if (res.data[i].photoIndex == -2 && res.data[i].timeInterval) {
|
|
|
- self.photoList = res.data[i].timeInterval.split(",");
|
|
|
- } else {
|
|
|
- self.photoHistoryList.push(res.data[i].photoIndex);
|
|
|
- }
|
|
|
- }
|
|
|
+ this.$request.courseBusiness(this.goodsData.businessId).then(res => {
|
|
|
+ this.businessData = res.data;
|
|
|
resolve();
|
|
|
});
|
|
|
});
|
|
|
},
|
|
|
-
|
|
|
- //拍照
|
|
|
- openPhoto() {
|
|
|
- var polyvPlayerContext = this.player;
|
|
|
- if (polyvPlayerContext) {
|
|
|
- if (this.isFullScreen()) {
|
|
|
- this.exitFullscreen();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- var polyvPlayerContext = this.playerzb;
|
|
|
- if (polyvPlayerContext) {
|
|
|
- if (this.isFullScreen()) {
|
|
|
- this.exitFullscreen();
|
|
|
- }
|
|
|
- }
|
|
|
- this.$nextTick(() => {
|
|
|
- if (
|
|
|
- (window.navigator.mediaDevices &&
|
|
|
- window.navigator.mediaDevices.getUserMedia) ||
|
|
|
- window.navigator.getUserMedia ||
|
|
|
- window.navigator.webkitGetUserMedia ||
|
|
|
- window.navigator.mozGetUserMedia
|
|
|
- ) {
|
|
|
- // 调用用户媒体设备, 访问摄像头
|
|
|
- this.getUserMedia(
|
|
|
- {
|
|
|
- video: {
|
|
|
- width: 400,
|
|
|
- height: 400
|
|
|
- }
|
|
|
- },
|
|
|
- this.photographSuccess,
|
|
|
- this.photographError
|
|
|
- );
|
|
|
- } else {
|
|
|
- this.photographError();
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 退出全屏
|
|
|
- */
|
|
|
- exitFullscreen() {
|
|
|
- try {
|
|
|
- var de = document;
|
|
|
- console.log(de);
|
|
|
- if (de.exitFullscreen) {
|
|
|
- de.exitFullscreen();
|
|
|
- } else if (de.mozCancelFullScreen) {
|
|
|
- de.mozCancelFullScreen();
|
|
|
- } else if (de.webkitCancelFullScreen) {
|
|
|
- de.webkitCancelFullScreen();
|
|
|
- }
|
|
|
- } catch (err) {}
|
|
|
- },
|
|
|
-
|
|
|
- fullele() {
|
|
|
- return (
|
|
|
- document.fullscreenElement ||
|
|
|
- document.webkitFullscreenElement ||
|
|
|
- document.msFullscreenElement ||
|
|
|
- document.mozFullScreenElement ||
|
|
|
- null
|
|
|
- );
|
|
|
- },
|
|
|
-
|
|
|
- //判断是否全屏
|
|
|
- isFullScreen() {
|
|
|
- return !!(document.webkitIsFullScreen || this.fullele());
|
|
|
- },
|
|
|
-
|
|
|
- //配置随机拍照时间
|
|
|
- configPhoto() {
|
|
|
- if (this.photoList.length) {
|
|
|
- return;
|
|
|
- }
|
|
|
- var polyvPlayerContext = this.player;
|
|
|
- let totalVideoTime = polyvPlayerContext.j2s_getDuration();
|
|
|
- let duration = polyvPlayerContext.j2s_getCurrentTime();
|
|
|
- let photoNum = this.photoNum;
|
|
|
- if (!this.photoConfig) {
|
|
|
- this.photoConfig = true;
|
|
|
- if (this.goodsData.erJianErZao) {
|
|
|
- this.photoList = this.randomConfig(totalVideoTime, duration);
|
|
|
- console.log("拍摄时间组:(秒)", this.photoList);
|
|
|
- return;
|
|
|
- }
|
|
|
- //没有历史拍照间隔数据
|
|
|
- if (this.photoList.length == 0) {
|
|
|
- if (totalVideoTime >= 900) {
|
|
|
- //大于15分钟
|
|
|
- if (photoNum == 1) {
|
|
|
- //开头拍1张
|
|
|
- this.photoList.push(1);
|
|
|
- } else if (photoNum == 3) {
|
|
|
- //拍3张
|
|
|
- this.photoList.push(0); //开头拍一张
|
|
|
- let centerTime = Math.floor(totalVideoTime / 2); //获取中间时间
|
|
|
- let centerMinTime = centerTime - 300; //前后5分钟
|
|
|
- let centerMaxTime = centerTime + 300;
|
|
|
- let centerTakeTime = this.randomNum(centerMinTime, centerMaxTime);
|
|
|
- this.photoList.push(centerTakeTime); //中间拍一张
|
|
|
- let endMaxTime = totalVideoTime - 60;
|
|
|
- let endMinTime = totalVideoTime - 300;
|
|
|
- let endTakeTime = this.randomNum(endMinTime, endMaxTime);
|
|
|
- this.photoList.push(endTakeTime); //最后拍一张
|
|
|
- }
|
|
|
- } else {
|
|
|
- //小于15分钟,只拍前后各一张
|
|
|
- if (photoNum == 1) {
|
|
|
- //开头拍1张
|
|
|
- this.photoList.push(1);
|
|
|
- } else if (photoNum == 3) {
|
|
|
- this.photoList.push(1);
|
|
|
- let centerTime = this.randomNum(
|
|
|
- (1 / 3) * totalVideoTime,
|
|
|
- (2 / 3) * totalVideoTime
|
|
|
- );
|
|
|
- this.photoList.push(centerTime);
|
|
|
- let endTakeTime = this.randomNum(
|
|
|
- (2 / 3) * totalVideoTime,
|
|
|
- totalVideoTime
|
|
|
- );
|
|
|
- this.photoList.push(endTakeTime);
|
|
|
- }
|
|
|
- }
|
|
|
- console.log("拍摄时间组:(秒)", this.photoList);
|
|
|
- this.postCoursePhotoRecord(true); //提交随机拍照时间数组
|
|
|
- }
|
|
|
- console.log(this.photoList, "随机拍照时间数组");
|
|
|
- //兼容已有观看历史
|
|
|
- for (let i = 0; i < this.photoList.length - 1; i++) {
|
|
|
- if (
|
|
|
- this.photoList[i] < duration &&
|
|
|
- this.photoList[i + 1] > duration
|
|
|
- ) {
|
|
|
- this.photoIndex = i + 1;
|
|
|
- // console.log("我的修改了photoIndex")
|
|
|
- break;
|
|
|
- }
|
|
|
- if (duration > this.photoList[this.photoList.length - 1]) {
|
|
|
- this.photoIndex = this.photoList.length - 1; //取最后一个下标
|
|
|
- // console.log("我的修改了photoIndex")
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
- // 随机拍摄时间
|
|
|
- randomConfig(totalVideoTime, duration) {
|
|
|
- this.photoHistoryList = [];
|
|
|
- let photoList = [duration];
|
|
|
- let pre = duration;
|
|
|
- if (totalVideoTime > 300) {
|
|
|
- while (pre <= totalVideoTime) {
|
|
|
- pre += this.randomNum(780, 900);
|
|
|
- pre <= totalVideoTime && photoList.push(pre);
|
|
|
- }
|
|
|
- if (totalVideoTime - 300 > photoList.slice(-1)[0]) {
|
|
|
- photoList.push(this.randomNum(totalVideoTime - 180, totalVideoTime));
|
|
|
- }
|
|
|
- }
|
|
|
- if (this.recordObj.videoCurrentTime) {
|
|
|
- photoList[0] = this.recordObj.videoCurrentTime || 0;
|
|
|
- }
|
|
|
- return photoList;
|
|
|
- },
|
|
|
- randomNum(minNum, maxNum) {
|
|
|
- switch (arguments.length) {
|
|
|
- case 1:
|
|
|
- return parseInt(Math.random() * minNum + 1, 10);
|
|
|
- break;
|
|
|
- case 2:
|
|
|
- return parseInt(Math.random() * (maxNum - minNum + 1) + minNum, 10);
|
|
|
- break;
|
|
|
- default:
|
|
|
- return 0;
|
|
|
- break;
|
|
|
- }
|
|
|
- },
|
|
|
- //postTime 只提交随机时间
|
|
|
- postCoursePhotoRecord(postTime = false) {
|
|
|
+ //获取商品详情
|
|
|
+ getGoodsData() {
|
|
|
return new Promise((resolve, reject) => {
|
|
|
- let currentTime = 0;
|
|
|
- var polyvPlayerContext = this.player;
|
|
|
- if (polyvPlayerContext) {
|
|
|
- currentTime = polyvPlayerContext.j2s_getCurrentTime();
|
|
|
- }
|
|
|
- let self = this;
|
|
|
- let photoIndex = self.photoIndex;
|
|
|
- let { courseId, chapterId, moduleId, sectionId, id } = this.sectionItem;
|
|
|
- let data = {
|
|
|
- photo: self.ossAvatarUrl,
|
|
|
- sectionId: sectionId || id,
|
|
|
- goodsId: parseInt(self.goodsId),
|
|
|
- courseId,
|
|
|
- photoTime: parseInt(currentTime > 0 ? currentTime : 0),
|
|
|
- gradeId: parseInt(self.gradeId),
|
|
|
- photoIndex: postTime ? -2 : parseInt(photoIndex), //从0算起,-2只提交随机时间
|
|
|
- photoNum: parseInt(self.photoNum),
|
|
|
- chapterId,
|
|
|
- moduleId,
|
|
|
- timeInterval: postTime ? self.photoList.join(",") : ""
|
|
|
- };
|
|
|
- console.log("提交接口", data);
|
|
|
- this.$request
|
|
|
- .coursePhotoRecord(data)
|
|
|
- .then(res => {
|
|
|
- console.log(res, "res");
|
|
|
- resolve();
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- console.log(err, "err");
|
|
|
- reject();
|
|
|
- });
|
|
|
- });
|
|
|
- },
|
|
|
- /**
|
|
|
- * @param {String} 直播预览
|
|
|
- */
|
|
|
- loadPlayerScriptzb(callback) {
|
|
|
- if (!window.polyvLivePlayer) {
|
|
|
- const myScript = document.createElement("script");
|
|
|
- myScript.setAttribute("src", this.playerJs);
|
|
|
- myScript.onload = callback;
|
|
|
- document.body.appendChild(myScript);
|
|
|
- } else {
|
|
|
- callback();
|
|
|
- }
|
|
|
- },
|
|
|
- loadPlayerScript(callback) {
|
|
|
- if (!window.polyvPlayer) {
|
|
|
- const myScript = document.createElement("script");
|
|
|
- myScript.setAttribute("src", this.vodPlayerJs);
|
|
|
- myScript.onload = callback;
|
|
|
- document.body.appendChild(myScript);
|
|
|
- } else {
|
|
|
- callback();
|
|
|
- }
|
|
|
- },
|
|
|
- clears() {
|
|
|
- return new Promise((resolve, reject) => {
|
|
|
- this.vid = "";
|
|
|
- this.vidzb = "";
|
|
|
- if (this.player) {
|
|
|
- this.player.destroy();
|
|
|
- }
|
|
|
- if (this.playerzb) {
|
|
|
- this.playerzb.destroy();
|
|
|
- }
|
|
|
- resolve();
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 提交观看记录
|
|
|
- */
|
|
|
- postStudyRecord(status = 0) {
|
|
|
- let currentTime = 0;
|
|
|
- let PlayDuration = 0;
|
|
|
- var polyvPlayerContext = this.player;
|
|
|
- if (polyvPlayerContext) {
|
|
|
- currentTime = polyvPlayerContext.j2s_getCurrentTime(); //当前视频播放时刻
|
|
|
- PlayDuration = polyvPlayerContext.j2s_realPlayVideoTime(); //本次看的时长
|
|
|
- }
|
|
|
- if (this.vidzb) {
|
|
|
- currentTime = 2; //直播无法获取,无论开始结束都传2秒
|
|
|
- }
|
|
|
- if (currentTime == 0) {
|
|
|
- return;
|
|
|
- }
|
|
|
- let { courseId, chapterId, moduleId, sectionId, id } = this.sectionItem;
|
|
|
- let self = this;
|
|
|
- let data = {
|
|
|
- fromPlat: 2, //来源平台 1小程序 2网站
|
|
|
- photo: self.ossAvatarUrl,
|
|
|
- sectionId: sectionId || id,
|
|
|
- goodsId: parseInt(this.goodsId),
|
|
|
- courseId,
|
|
|
- studyDuration: parseInt(PlayDuration > 0 ? PlayDuration : 0),
|
|
|
- gradeId: parseInt(this.gradeId),
|
|
|
- chapterId,
|
|
|
- moduleId,
|
|
|
- videoCurrentTime: parseInt(currentTime > 0 ? currentTime : 0),
|
|
|
- erJianErZao: this.goodsData.erJianErZao,
|
|
|
- orderGoodsId: parseInt(this.orderGoodsId)
|
|
|
- };
|
|
|
-
|
|
|
- if (this.ossAvatarUrl) {
|
|
|
- data.similarity = this.compareFaceData; // 相似度
|
|
|
- }
|
|
|
- if (status > 0) {
|
|
|
- data.status = status;
|
|
|
- }
|
|
|
- // /study/record 学习记录
|
|
|
- this.$request
|
|
|
- .studyRecord(data)
|
|
|
- .then(res => {
|
|
|
- if (status > 0) {
|
|
|
- this.openPhotoStatus = 0;
|
|
|
- if (this.playTabIndex == this.courseTabIndex - 1) {
|
|
|
- this.$refs["courseTree"][
|
|
|
- this.playTabIndex
|
|
|
- ].dialogPalyVisible = true;
|
|
|
- clearTimeout(this.videoPause);
|
|
|
- }
|
|
|
- //看完视频刷新父级列表
|
|
|
- // let rebuildObj = this.getSameObj(this.sectionItem);
|
|
|
- // this.refreshParentList(this.sectionItem, rebuildObj);
|
|
|
- this.$refs["courseTree"][0].refreshList();
|
|
|
- }
|
|
|
- self.ossAvatarUrl = "";
|
|
|
- if (this.openPhotoStatus === 1) {
|
|
|
- this.postStudyRecord(1);
|
|
|
- }
|
|
|
- })
|
|
|
- .catch(err => {
|
|
|
- if (err.code === 600) {
|
|
|
- polyvPlayerContext.j2s_pauseVideo();
|
|
|
- this.failToRegister = true;
|
|
|
- this.errorCodeDialog = true;
|
|
|
- this.errorCodeMsg = err.msg;
|
|
|
- return;
|
|
|
- }
|
|
|
- if (err.code === 559) {
|
|
|
- this.$message.error(err.msg);
|
|
|
- console.log("拍照不够触发");
|
|
|
- this.openPhotoStatus = 1;
|
|
|
- this.openPhoto();
|
|
|
- }
|
|
|
- if (err.code === 558) {
|
|
|
- this.$message.error(err.msg);
|
|
|
- return;
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
- /**
|
|
|
- * 获取重修列表中是否有相同对象
|
|
|
- */
|
|
|
- getSameObj(metaObj) {
|
|
|
- console.log("看完视频后----", metaObj, this.reMenuList);
|
|
|
- let newObj = false;
|
|
|
- if (this.reMenuList.length) {
|
|
|
- console.log(this.reMenuList, "this.reMenuList");
|
|
|
- this.reMenuList.forEach(menu => {
|
|
|
- if (menu.type == 3) {
|
|
|
- let isSame = this.contrast(metaObj, menu);
|
|
|
- if (isSame) {
|
|
|
- newObj = isSame;
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (menu.list && menu.list.length) {
|
|
|
- menu.list.forEach(menuItem => {
|
|
|
- if (menuItem.type == 1) {
|
|
|
- console.log(menuItem, metaObj);
|
|
|
- let isSame = this.contrast(metaObj, menuItem);
|
|
|
- if (isSame) {
|
|
|
- newObj = isSame;
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (menuItem.list && menuItem.list.length) {
|
|
|
- menuItem.list.forEach(menuChild => {
|
|
|
- if (menuChild.type == 1) {
|
|
|
- let isSame = this.contrast(metaObj, menuChild);
|
|
|
- if (isSame) {
|
|
|
- newObj = isSame;
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- return newObj;
|
|
|
- } else {
|
|
|
- return false;
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- contrast(obj1, obj2) {
|
|
|
- let moduleId1 = obj1.moduleId || 0;
|
|
|
- let chapterId1 = obj1.chapterId || 0;
|
|
|
- let sectionId1 = obj1.sectionId || obj1.menuId;
|
|
|
- let moduleId2 = obj2.moduleId || 0;
|
|
|
- let chapterId2 = obj2.chapterId || 0;
|
|
|
- let sectionId2 = obj2.sectionId || obj2.menuId;
|
|
|
- //转字符串后对比是否一致
|
|
|
- return moduleId1 == moduleId2 &&
|
|
|
- chapterId1 == chapterId2 &&
|
|
|
- sectionId1 == sectionId2
|
|
|
- ? obj2
|
|
|
- : false;
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 刷新父级列表
|
|
|
- */
|
|
|
- refreshParentList(sectionItem, rebuildObj) {
|
|
|
- let self = this;
|
|
|
- if (sectionItem.menuId) {
|
|
|
- //最外层节有menuid
|
|
|
- //普通章节目录
|
|
|
- this.$request
|
|
|
- .reMenuList({ courseId: this.courseId, gradeId: this.gradeId })
|
|
|
- .then(res => {
|
|
|
- for (let i = 0; i < res.rows.length; i++) {
|
|
|
- let item = res.rows[i];
|
|
|
- if (item.type == 3) {
|
|
|
- self.menuList[i].learning = item.learning;
|
|
|
- self.menuList[i].rebuild = item.rebuild;
|
|
|
- }
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- if (this.menuTab.length > 1) {
|
|
|
- //有重修目录
|
|
|
- this.$request
|
|
|
- .reMenuList({
|
|
|
- courseId: this.courseId,
|
|
|
- gradeId: this.gradeId,
|
|
|
- rebuild: 1
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- if (res.rows.length > 0) {
|
|
|
- for (let i = 0; i < res.rows.length; i++) {
|
|
|
- let item = res.rows[i];
|
|
|
- item.id = item.menuId;
|
|
|
- item.name = item.menuName;
|
|
|
- item.menuType = item.type;
|
|
|
- item.showList = false;
|
|
|
- item.list = [];
|
|
|
- item.isRebuild = 1;
|
|
|
- }
|
|
|
- self.reMenuList = self.reMenuList.filter(reMenu => {
|
|
|
- //筛选剩下的选项
|
|
|
- return res.rows.find(row => row.menuId == reMenu.menuId);
|
|
|
- });
|
|
|
- } else {
|
|
|
- this.menuTab = [
|
|
|
- {
|
|
|
- name: "1",
|
|
|
- label: "章节目录"
|
|
|
- },
|
|
|
- {
|
|
|
- name: "3",
|
|
|
- label: "答疑"
|
|
|
- },
|
|
|
- {
|
|
|
- name: "4",
|
|
|
- label: "笔记"
|
|
|
- },
|
|
|
- {
|
|
|
- name: "5",
|
|
|
- label: "讲义"
|
|
|
- }
|
|
|
- ];
|
|
|
- this.courseTabIndex = "1";
|
|
|
- self.reMenuList = [];
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- } else if (!sectionItem.moduleId) {
|
|
|
- //第二层节没有moduleid
|
|
|
- this.$request
|
|
|
- .reSectionList({
|
|
|
- chapterId: sectionItem.chapterId,
|
|
|
- gradeId: this.gradeId,
|
|
|
- courseId: this.courseId,
|
|
|
- moduleId: 0
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- let newArr = res.data.filter(item => {
|
|
|
- return item.type != 2;
|
|
|
- });
|
|
|
- if (sectionItem.parent) {
|
|
|
- sectionItem.parent.canLearn = newArr.every(
|
|
|
- item => item.learning == 1
|
|
|
- );
|
|
|
- res.data.forEach(section => {
|
|
|
- section.isRebuild = 1;
|
|
|
- section.parent = sectionItem.parent;
|
|
|
- });
|
|
|
- }
|
|
|
- this.menuList.forEach(menu => {
|
|
|
- if (menu.menuId == sectionItem.chapterId) {
|
|
|
- menu.list = res.data;
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- if (this.menuTab.length > 1 && rebuildObj) {
|
|
|
- this.$request
|
|
|
- .reSectionList({
|
|
|
- chapterId: rebuildObj.chapterId,
|
|
|
- gradeId: this.gradeId,
|
|
|
- courseId: this.courseId,
|
|
|
- moduleId: 0,
|
|
|
- rebuild: 1
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- let newArr = res.data.filter(item => {
|
|
|
- return item.type != 2;
|
|
|
- });
|
|
|
- if (rebuildObj.parent) {
|
|
|
- rebuildObj.parent.canLearn = newArr.every(
|
|
|
- item => item.learning == 1
|
|
|
- );
|
|
|
- res.data.forEach(section => {
|
|
|
- section.parent = rebuildObj.parent;
|
|
|
- });
|
|
|
- }
|
|
|
- this.reMenuList.forEach(menu => {
|
|
|
- if (menu.menuId == rebuildObj.chapterId) {
|
|
|
- menu.list = res.data;
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- this.$request
|
|
|
- .reMenuList({
|
|
|
- courseId: this.courseId,
|
|
|
- gradeId: this.gradeId,
|
|
|
- rebuild: 1
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- if (res.rows.length > 0) {
|
|
|
- for (let i = 0; i < res.rows.length; i++) {
|
|
|
- let item = res.rows[i];
|
|
|
- item.id = item.menuId;
|
|
|
- item.name = item.menuName;
|
|
|
- item.menuType = item.type;
|
|
|
- item.showList = false;
|
|
|
- item.list = [];
|
|
|
- item.isRebuild = 1;
|
|
|
- }
|
|
|
- self.reMenuList = self.reMenuList.filter(reMenu => {
|
|
|
- //筛选剩下的选项
|
|
|
- return res.rows.find(row => row.menuId == reMenu.menuId);
|
|
|
- });
|
|
|
- } else {
|
|
|
- this.menuTab = [
|
|
|
- {
|
|
|
- name: "1",
|
|
|
- label: "章节目录"
|
|
|
- },
|
|
|
- {
|
|
|
- name: "3",
|
|
|
- label: "答疑"
|
|
|
- },
|
|
|
- {
|
|
|
- name: "4",
|
|
|
- label: "笔记"
|
|
|
- },
|
|
|
- {
|
|
|
- name: "5",
|
|
|
- label: "讲义"
|
|
|
- }
|
|
|
- ];
|
|
|
- this.courseTabIndex = "1";
|
|
|
- self.reMenuList = [];
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- } else {
|
|
|
- //第三层节有moduleid和chapterid都有
|
|
|
- this.$request
|
|
|
- .reSectionList({
|
|
|
- chapterId: sectionItem.chapterId,
|
|
|
- gradeId: this.gradeId,
|
|
|
- courseId: this.courseId,
|
|
|
- moduleId: sectionItem.moduleId
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- let newArr = res.data.filter(item => {
|
|
|
- return item.type != 2;
|
|
|
- });
|
|
|
- if (sectionItem.parent) {
|
|
|
- sectionItem.parent.canLearn = newArr.every(
|
|
|
- item => item.learning == 1
|
|
|
- );
|
|
|
- res.data.forEach(section => {
|
|
|
- section.parent = sectionItem.parent;
|
|
|
- });
|
|
|
- }
|
|
|
- this.menuList.forEach(menu => {
|
|
|
- if (menu.list && menu.list.length) {
|
|
|
- menu.list.forEach(chapter => {
|
|
|
- if (
|
|
|
- chapter.moduleId == sectionItem.moduleId &&
|
|
|
- chapter.chapterId == sectionItem.chapterId
|
|
|
- ) {
|
|
|
- chapter.list = res.data;
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- if (this.menuTab.length > 1 && rebuildObj) {
|
|
|
- this.$request
|
|
|
- .reSectionList({
|
|
|
- chapterId: rebuildObj.chapterId,
|
|
|
- gradeId: this.gradeId,
|
|
|
- courseId: this.courseId,
|
|
|
- moduleId: rebuildObj.moduleId,
|
|
|
- rebuild: 1
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- let newArr = res.data.filter(item => {
|
|
|
- return item.type != 2;
|
|
|
- });
|
|
|
- if (sectionItem.parent) {
|
|
|
- rebuildObj.parent.canLearn = newArr.every(
|
|
|
- item => item.learning == 1
|
|
|
- );
|
|
|
-
|
|
|
- res.data.forEach(section => {
|
|
|
- section.parent = rebuildObj.parent;
|
|
|
- });
|
|
|
- }
|
|
|
- this.reMenuList.forEach(menu => {
|
|
|
- if (menu.list && menu.list.length) {
|
|
|
- menu.list.forEach(chapter => {
|
|
|
- if (
|
|
|
- chapter.moduleId == rebuildObj.moduleId &&
|
|
|
- chapter.chapterId == rebuildObj.chapterId
|
|
|
- ) {
|
|
|
- chapter.learning = res.data[0].learning;
|
|
|
- chapter.list = res.data;
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- });
|
|
|
- });
|
|
|
-
|
|
|
- this.$request
|
|
|
- .reMenuList({
|
|
|
- courseId: this.courseId,
|
|
|
- gradeId: this.gradeId,
|
|
|
- rebuild: 1
|
|
|
- })
|
|
|
- .then(res => {
|
|
|
- if (res.rows.length > 0) {
|
|
|
- for (let i = 0; i < res.rows.length; i++) {
|
|
|
- let item = res.rows[i];
|
|
|
- item.id = item.menuId;
|
|
|
- item.name = item.menuName;
|
|
|
- item.menuType = item.type;
|
|
|
- item.showList = false;
|
|
|
- item.list = [];
|
|
|
- item.isRebuild = 1;
|
|
|
- }
|
|
|
- self.reMenuList = self.reMenuList.filter(reMenu => {
|
|
|
- //筛选剩下的选项
|
|
|
- return res.rows.find(row => row.menuId == reMenu.menuId);
|
|
|
- });
|
|
|
- } else {
|
|
|
- this.menuTab = [
|
|
|
- {
|
|
|
- name: "1",
|
|
|
- label: "章节目录"
|
|
|
- },
|
|
|
- {
|
|
|
- name: "3",
|
|
|
- label: "答疑"
|
|
|
- },
|
|
|
- {
|
|
|
- name: "4",
|
|
|
- label: "笔记"
|
|
|
- },
|
|
|
- {
|
|
|
- name: "5",
|
|
|
- label: "讲义"
|
|
|
- }
|
|
|
- ];
|
|
|
- this.courseTabIndex = "1";
|
|
|
- self.reMenuList = [];
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- getRecordLast() {
|
|
|
- let self = this;
|
|
|
- return new Promise(resolve => {
|
|
|
- let data = {
|
|
|
- gradeId: Number(self.gradeId),
|
|
|
- goodsId: Number(self.goodsId),
|
|
|
- sectionId: Number(self.playSectionId),
|
|
|
- courseId: Number(self.courseId),
|
|
|
- chapterId: parseInt(self.chapterId),
|
|
|
- moduleId: parseInt(self.moduleId)
|
|
|
- };
|
|
|
- self.$request.recordLast(data).then(res => {
|
|
|
- resolve(res.data);
|
|
|
- });
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- noteClick(note) {
|
|
|
- if (this.vid) {
|
|
|
- //切换视频
|
|
|
- if (this.vid == note.recordingUrl) {
|
|
|
- var polyvPlayerContext = this.player;
|
|
|
- if (polyvPlayerContext) {
|
|
|
- polyvPlayerContext.j2s_seekVideo(note.noteSecond);
|
|
|
- }
|
|
|
- } else {
|
|
|
- var polyvPlayerContext = this.player;
|
|
|
- if (polyvPlayerContext) {
|
|
|
- polyvPlayerContext.changeVid(note.recordingUrl);
|
|
|
- }
|
|
|
- }
|
|
|
- } else {
|
|
|
- var polyvPlayerContext = this.player;
|
|
|
- console.log(polyvPlayerContext);
|
|
|
- if (polyvPlayerContext) {
|
|
|
- polyvPlayerContext.changeVid(note.recordingUrl);
|
|
|
- } else {
|
|
|
- this.vid = note.recordingUrl;
|
|
|
- console.log(note.recordingUrl);
|
|
|
- this.moduleId = note.moduleId;
|
|
|
- this.chapterId = note.chapterId;
|
|
|
- this.playSectionId = note.sectionId;
|
|
|
- note.sectionType = 3;
|
|
|
- this.loadPlayerScript(this.loadPlayer);
|
|
|
- }
|
|
|
- }
|
|
|
- this.recordObj = { videoCurrentTime: note.noteSecond };
|
|
|
- },
|
|
|
- getRebuildCourse() {
|
|
|
- this.$request
|
|
|
- .getRebuildCourse({
|
|
|
- goodsId: this.goodsId,
|
|
|
- rebuild: 1,
|
|
|
- gradeId: this.gradeId
|
|
|
- })
|
|
|
- .then(async res => {
|
|
|
- if (res.data.length > 0) {
|
|
|
- this.rebuildCourseList = [res.data[0]];
|
|
|
- }
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- /**
|
|
|
- * 获取培训项目详情
|
|
|
- */
|
|
|
- courseBusiness() {
|
|
|
- this.$request.courseBusiness(this.goodsData.businessId).then(res => {
|
|
|
- this.businessData = res.data;
|
|
|
- });
|
|
|
- },
|
|
|
- courseCourseList() {
|
|
|
- return new Promise(async (resolve, reject) => {
|
|
|
- if (this.goodsData.erJianErZao) {
|
|
|
- let info = await this.$request.userConfirmInfoDetail({
|
|
|
- orderGoodsId: this.orderGoodsId
|
|
|
- });
|
|
|
- if (!info.data || info.data.pushInfo !== 1) {
|
|
|
- this.errorCodeDialog = true;
|
|
|
- this.errorCodeMsg = "开通信息推送不成功,无法进入学习!";
|
|
|
- return;
|
|
|
+ this.$request.goodsDetail(this.routerData.goodsId).then(res => {
|
|
|
+ res.data.orderGoodsId = this.routerData.orderGoodsId;
|
|
|
+ this.goodsData = res.data;
|
|
|
+ //播放设置
|
|
|
+ if (this.goodsData.goodsPlayConfig) {
|
|
|
+ this.goodsPlayConfig = JSON.parse(this.goodsData.goodsPlayConfig);
|
|
|
+ this.goodsPlayConfig.autoplay =
|
|
|
+ this.goodsPlayConfig.autoPlay > 0 ? true : false;
|
|
|
+ this.goodsPlayConfig.isAllowSeek =
|
|
|
+ this.goodsPlayConfig.drag > 0 ? "off" : "on";
|
|
|
+ this.goodsPlayConfig.playbackRate =
|
|
|
+ this.goodsPlayConfig.speed > 0 ? true : false;
|
|
|
+ }
|
|
|
+ //拍照设置
|
|
|
+ if (this.goodsData.goodsPhotographConfig) {
|
|
|
+ this.goodsPhotographConfig = JSON.parse(
|
|
|
+ this.goodsData.goodsPhotographConfig
|
|
|
+ );
|
|
|
+ this.goodsPhotographConfig.photoNum =
|
|
|
+ this.goodsPhotographConfig.photoNum || 0;
|
|
|
}
|
|
|
- }
|
|
|
- this.$request
|
|
|
- .courseCourseList({ goodsId: this.goodsId, gradeId: this.gradeId })
|
|
|
- .then(async res => {
|
|
|
- this.courseList = res.rows;
|
|
|
- console.error("res.rows", res.rows);
|
|
|
- if (!this.courseId) {
|
|
|
- this.courseId = this.courseList[0].courseId;
|
|
|
- }
|
|
|
- await this.courseChange();
|
|
|
- resolve();
|
|
|
- });
|
|
|
- });
|
|
|
- },
|
|
|
-
|
|
|
- download(url, fileName) {
|
|
|
- let xhr = new XMLHttpRequest();
|
|
|
- xhr.open("get", url, true);
|
|
|
- xhr.setRequestHeader("Content-Type", `application/pdf`);
|
|
|
- xhr.responseType = "blob";
|
|
|
- let that = this;
|
|
|
- xhr.onload = function() {
|
|
|
- if (this.status == 200) {
|
|
|
- //接受二进制文件流
|
|
|
- var blob = this.response;
|
|
|
- that.downloadExportFile(blob, fileName);
|
|
|
- }
|
|
|
- };
|
|
|
- xhr.send();
|
|
|
- },
|
|
|
-
|
|
|
- downloadExportFile(blob, tagFileName) {
|
|
|
- let downloadElement = document.createElement("a");
|
|
|
- let href = "";
|
|
|
- if (typeof blob == "string") {
|
|
|
- downloadElement.target = "_blank";
|
|
|
- } else {
|
|
|
- href = window.URL.createObjectURL(blob); //创建下载的链接
|
|
|
- }
|
|
|
- downloadElement.href = href;
|
|
|
- downloadElement.download = tagFileName;
|
|
|
- //下载后文件名
|
|
|
- document.body.appendChild(downloadElement);
|
|
|
- downloadElement.click(); //点击下载
|
|
|
- document.body.removeChild(downloadElement); //下载完成移除元素
|
|
|
- if (typeof blob != "string") {
|
|
|
- window.URL.revokeObjectURL(href); //释放掉blob对象
|
|
|
- }
|
|
|
- },
|
|
|
-
|
|
|
- print() {
|
|
|
- document.getElementById("printIframe").contentWindow.print();
|
|
|
- },
|
|
|
-
|
|
|
- previvew(url) {
|
|
|
- this.showPdf = true;
|
|
|
- },
|
|
|
- noteSubmit() {
|
|
|
- let self = this;
|
|
|
- if (!(this.playSectionId > 0)) {
|
|
|
- this.$message({
|
|
|
- message: "目前无播放视频",
|
|
|
- type: "warning"
|
|
|
- });
|
|
|
- return;
|
|
|
- }
|
|
|
- if (!this.textareaNote) {
|
|
|
- this.$message({
|
|
|
- message: "请输入内容",
|
|
|
- type: "warning"
|
|
|
- });
|
|
|
- return;
|
|
|
- }
|
|
|
- if (!this.gradeId) {
|
|
|
- this.$message({
|
|
|
- message: "暂无班级数据",
|
|
|
- type: "warning"
|
|
|
- });
|
|
|
- return;
|
|
|
- }
|
|
|
- var polyvPlayerContext = this.player;
|
|
|
- let noteDate = this.$tools.getZeroTime();
|
|
|
- let noteSecond = polyvPlayerContext.j2s_getCurrentTime();
|
|
|
- console.log(noteSecond, "noteSecond");
|
|
|
- if (!noteSecond) {
|
|
|
- if (noteSecond == 0) {
|
|
|
- //播放结束
|
|
|
- noteSecond = polyvPlayerContext.j2s_getCurrentTime();
|
|
|
- }
|
|
|
- if (!noteSecond) {
|
|
|
- this.$message({
|
|
|
- message: "视频暂未开始",
|
|
|
- type: "warning"
|
|
|
- });
|
|
|
- return;
|
|
|
- }
|
|
|
- }
|
|
|
- let data = {
|
|
|
- gradeId: this.gradeId,
|
|
|
- goodsId: this.goodsId,
|
|
|
- sectionId: this.playSectionId,
|
|
|
- courseId: this.courseId,
|
|
|
- noteText: this.textareaNote,
|
|
|
- noteDate: noteDate,
|
|
|
- noteSecond: noteSecond,
|
|
|
- moduleId: this.moduleId,
|
|
|
- chapterId: this.chapterId
|
|
|
- };
|
|
|
- this.$request.postNote(data).then(res => {
|
|
|
- this.$message({
|
|
|
- message: "发布成功",
|
|
|
- type: "success"
|
|
|
+ resolve();
|
|
|
});
|
|
|
- self.$refs.notes[0].getNoteList();
|
|
|
- this.textareaNote = "";
|
|
|
- });
|
|
|
- },
|
|
|
- /**
|
|
|
- * 打印
|
|
|
- */
|
|
|
- printView(url) {
|
|
|
- console.log("触发打印", url);
|
|
|
- printJS({
|
|
|
- printable: url,
|
|
|
- type: "pdf",
|
|
|
- header: null,
|
|
|
- targetStyles: ["*"],
|
|
|
- style: "@page {margin:0 10mm}"
|
|
|
});
|
|
|
- // this.print(url);
|
|
|
- },
|
|
|
- // 打印方法
|
|
|
- print(filePath) {
|
|
|
- console.log("执行打印");
|
|
|
- let iframe = document.createElement("iframe");
|
|
|
- iframe.style.border = "0px";
|
|
|
- iframe.style.position = "absolute";
|
|
|
- iframe.style.width = "0px";
|
|
|
- iframe.style.height = "0px";
|
|
|
- iframe.style.right = "0px";
|
|
|
- iframe.style.top = "0px";
|
|
|
- iframe.setAttribute("src", filePath);
|
|
|
- iframe.onload = () => {
|
|
|
- iframe.contentWindow.print();
|
|
|
- // setTimeout(() => {
|
|
|
- // document.body.removeChild(iframe);
|
|
|
- // });
|
|
|
- };
|
|
|
- document.body.append(iframe);
|
|
|
}
|
|
|
- }
|
|
|
+ },
|
|
|
+ beforeDestroy() {}
|
|
|
};
|
|
|
</script>
|
|
|
|
|
|
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
|
<style scoped lang="scss">
|
|
|
-.course-item {
|
|
|
- float: left;
|
|
|
- margin-bottom: 6px;
|
|
|
-}
|
|
|
-/deep/ .docx-wrapper {
|
|
|
- padding: 0px;
|
|
|
-}
|
|
|
-/deep/ .docx-wrapper > section.docx {
|
|
|
- padding: 4px !important;
|
|
|
- width: auto !important;
|
|
|
- min-height: auto !important;
|
|
|
-}
|
|
|
-.course-detail {
|
|
|
- .section {
|
|
|
- padding-bottom: 30px;
|
|
|
-
|
|
|
- &__header {
|
|
|
- height: 40px;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- padding: 0 20px;
|
|
|
- }
|
|
|
-
|
|
|
- &__body {
|
|
|
- .course-info {
|
|
|
- &__header {
|
|
|
- .title {
|
|
|
- height: 40px;
|
|
|
- border-bottom: 1px solid #999;
|
|
|
- // color: #fff;
|
|
|
-
|
|
|
- /deep/ .el-input__icon {
|
|
|
- width: 20px;
|
|
|
- height: 20px;
|
|
|
- border: 1px solid #eee;
|
|
|
- border-radius: 4px;
|
|
|
- margin-top: 10px;
|
|
|
- line-height: 20px;
|
|
|
- }
|
|
|
-
|
|
|
- /deep/ .el-input__inner {
|
|
|
- // color: #fff;
|
|
|
- font-size: 16px;
|
|
|
- background: none;
|
|
|
- border: 0;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .left-box {
|
|
|
- width: 810px;
|
|
|
- height: 455px;
|
|
|
- float: left;
|
|
|
- background-size: cover;
|
|
|
- background-position: center center;
|
|
|
- background-repeat: no-repeat;
|
|
|
- position: relative;
|
|
|
- .smallBox {
|
|
|
- position: absolute;
|
|
|
- width: 162px;
|
|
|
- height: 91px;
|
|
|
- border-radius: 4px;
|
|
|
- background: #fff;
|
|
|
- right: 20px;
|
|
|
- bottom: 75px;
|
|
|
- z-index: 1998;
|
|
|
- overflow: hidden;
|
|
|
- /deep/ .pv-video-player {
|
|
|
- // width: 100%!important;
|
|
|
- // height: 100%!important;
|
|
|
- transform-origin: 0 0;
|
|
|
- transform: scale(0.2);
|
|
|
- }
|
|
|
- }
|
|
|
- .overStyle {
|
|
|
- overflow: auto !important;
|
|
|
- }
|
|
|
- .switch {
|
|
|
- position: absolute;
|
|
|
- right: 22px;
|
|
|
- bottom: 77px;
|
|
|
- z-index: 1999;
|
|
|
- font-size: 30px;
|
|
|
- transition: all 0.3;
|
|
|
- border-radius: 50%;
|
|
|
- overflow: hidden;
|
|
|
- padding: 4px;
|
|
|
- cursor: pointer;
|
|
|
- &:hover {
|
|
|
- color: #000;
|
|
|
- background-color: rgba(225, 225, 225, 0.8);
|
|
|
- }
|
|
|
- }
|
|
|
- .hideSwitchBox {
|
|
|
- position: absolute;
|
|
|
- right: 22px;
|
|
|
- bottom: 126px;
|
|
|
- z-index: 1999;
|
|
|
- font-size: 30px;
|
|
|
- transition: all 0.3;
|
|
|
- border-radius: 50%;
|
|
|
- overflow: hidden;
|
|
|
- padding: 4px;
|
|
|
- cursor: pointer;
|
|
|
- opacity: 0.5;
|
|
|
- &:hover {
|
|
|
- opacity: 1;
|
|
|
- color: #000;
|
|
|
- background-color: rgba(225, 225, 225, 0.9);
|
|
|
- }
|
|
|
- }
|
|
|
- .switchPdf {
|
|
|
- width: 810px;
|
|
|
- height: 455px;
|
|
|
- overflow: auto;
|
|
|
- border: 1px solid #666;
|
|
|
- }
|
|
|
- .video {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .recordStyle {
|
|
|
- position: absolute;
|
|
|
- bottom: 90px;
|
|
|
- padding: 6px 12px;
|
|
|
- left: 8px;
|
|
|
- background-color: rgba(0, 0, 0, 0.4);
|
|
|
- color: #fff;
|
|
|
- border-radius: 24px;
|
|
|
- user-select: none;
|
|
|
-
|
|
|
- .btn_sty {
|
|
|
- cursor: pointer;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .right-box {
|
|
|
- width: 462px;
|
|
|
- height: 455px;
|
|
|
- background: #3f4449;
|
|
|
- border-radius: 0px;
|
|
|
- float: right;
|
|
|
-
|
|
|
- &__header {
|
|
|
- .tabs {
|
|
|
- /deep/.el-tabs__nav-wrap::after {
|
|
|
- background-color: #999;
|
|
|
- }
|
|
|
-
|
|
|
- /deep/ .el-tabs__header {
|
|
|
- margin: 0;
|
|
|
- }
|
|
|
-
|
|
|
- .label {
|
|
|
- color: #fff;
|
|
|
- height: 40px;
|
|
|
- line-height: 40px;
|
|
|
- padding: 0 20px;
|
|
|
- }
|
|
|
-
|
|
|
- .item {
|
|
|
- &__title {
|
|
|
- padding-left: 12px;
|
|
|
- height: 40px;
|
|
|
- line-height: 40px;
|
|
|
- cursor: pointer;
|
|
|
- font-size: 14px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: bold;
|
|
|
- color: #fff;
|
|
|
-
|
|
|
- .el-icon-caret-right,
|
|
|
- .el-icon-caret-bottom {
|
|
|
- color: #999;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .title {
|
|
|
- height: 40px;
|
|
|
- border-bottom: 1px solid #999;
|
|
|
- color: #fff;
|
|
|
-
|
|
|
- .select {
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
-
|
|
|
- /deep/ .el-input__icon {
|
|
|
- width: 20px;
|
|
|
- height: 20px;
|
|
|
- border: 1px solid #fff;
|
|
|
- border-radius: 4px;
|
|
|
- margin-top: 10px;
|
|
|
- line-height: 20px;
|
|
|
- }
|
|
|
-
|
|
|
- /deep/ .el-input__inner {
|
|
|
- color: #fff;
|
|
|
- font-size: 16px;
|
|
|
- background: none;
|
|
|
- border: 0;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- &__body {
|
|
|
- height: 374px;
|
|
|
- overflow-y: scroll;
|
|
|
-
|
|
|
- &::-webkit-scrollbar {
|
|
|
- // width: 6px;
|
|
|
- display: none;
|
|
|
- }
|
|
|
-
|
|
|
- &::-webkit-scrollbar-track {
|
|
|
- background-color: #060e1a;
|
|
|
- -webkit-border-radius: 2em;
|
|
|
- -moz-border-radius: 2em;
|
|
|
- border-radius: 2em;
|
|
|
- }
|
|
|
-
|
|
|
- &::-webkit-scrollbar-thumb {
|
|
|
- background-color: #eeeeee;
|
|
|
- -webkit-border-radius: 2em;
|
|
|
- -moz-border-radius: 2em;
|
|
|
- border-radius: 2em;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- &__body {
|
|
|
- /deep/ .el-tabs__item {
|
|
|
- padding: 0 20px !important;
|
|
|
- height: 80px;
|
|
|
- line-height: 80px;
|
|
|
- }
|
|
|
-
|
|
|
- .course-img {
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
-
|
|
|
- .course-menu {
|
|
|
- margin-top: 25px;
|
|
|
-
|
|
|
- .left-box {
|
|
|
- width: 948px;
|
|
|
- float: left;
|
|
|
-
|
|
|
- &__header {
|
|
|
- padding-right: 50px;
|
|
|
- position: relative;
|
|
|
-
|
|
|
- .item {
|
|
|
- width: auto;
|
|
|
- margin-right: 24px;
|
|
|
- font-size: 16px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: 400;
|
|
|
- color: #333333;
|
|
|
- background: #eeeeee;
|
|
|
- border-radius: 8px;
|
|
|
- padding: 12px;
|
|
|
- position: relative;
|
|
|
-
|
|
|
- &.canlearn {
|
|
|
- background: #3f8dfd;
|
|
|
- color: #fff;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- &__body {
|
|
|
- .buy-note {
|
|
|
- margin-right: 50px;
|
|
|
- }
|
|
|
-
|
|
|
- .item {
|
|
|
- margin-top: 24px;
|
|
|
- padding: 16px;
|
|
|
- background: #eee;
|
|
|
- border-radius: 10px;
|
|
|
-
|
|
|
- &__title {
|
|
|
- font-size: 16px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: bold;
|
|
|
- color: #333333;
|
|
|
-
|
|
|
- .note {
|
|
|
- display: inline-block;
|
|
|
- margin-left: 20px;
|
|
|
- width: 40px;
|
|
|
- height: 24px;
|
|
|
- border: 1px solid #ff3b30;
|
|
|
- border-radius: 8px;
|
|
|
- line-height: 22px;
|
|
|
- color: #ff3b30;
|
|
|
- text-align: center;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- &__content {
|
|
|
- margin-top: 12px;
|
|
|
- background: #f5f7fa;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .right-box {
|
|
|
- width: 255px;
|
|
|
- float: right;
|
|
|
-
|
|
|
- .title {
|
|
|
- font-size: 16px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: 400;
|
|
|
- color: #333333;
|
|
|
- text-shadow: 0px 6px 6px rgba(85, 158, 255, 0.08);
|
|
|
- position: relative;
|
|
|
-
|
|
|
- .more {
|
|
|
- font-size: 16px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: 400;
|
|
|
- color: #999999;
|
|
|
- position: absolute;
|
|
|
- right: 0;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .answer-question {
|
|
|
- &__header {
|
|
|
- border-bottom: 1px solid #eee;
|
|
|
-
|
|
|
- .textarea-wrap {
|
|
|
- background: #f9f9f9;
|
|
|
- border: 1px solid #eeeeee;
|
|
|
- border-radius: 8px;
|
|
|
-
|
|
|
- .textarea {
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .submit {
|
|
|
- padding: 10px 20px;
|
|
|
- border-radius: 20px;
|
|
|
- text-align: center;
|
|
|
- font-size: 16px;
|
|
|
- margin: 10px 0;
|
|
|
- float: right;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- &__body {
|
|
|
- .question-list {
|
|
|
- &__item {
|
|
|
- padding: 20px 0;
|
|
|
- display: flex;
|
|
|
-
|
|
|
- &__avatar {
|
|
|
- width: 40px;
|
|
|
- height: 40px;
|
|
|
- display: table-cell;
|
|
|
- border-radius: 50%;
|
|
|
- text-align: center;
|
|
|
-
|
|
|
- img {
|
|
|
- display: inline-block;
|
|
|
- vertical-align: middle;
|
|
|
- max-width: 100%;
|
|
|
- max-height: 100%;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- &__content {
|
|
|
- flex: 1;
|
|
|
- border-bottom: 1px solid #ccc;
|
|
|
- margin-left: 10px;
|
|
|
-
|
|
|
- .nickname {
|
|
|
- font-size: 14px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: bold;
|
|
|
- color: #fff;
|
|
|
- line-height: 24px;
|
|
|
- }
|
|
|
-
|
|
|
- .desc {
|
|
|
- font-size: 14px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: 400;
|
|
|
- color: #666666;
|
|
|
- line-height: 24px;
|
|
|
- }
|
|
|
-
|
|
|
- .time {
|
|
|
- font-size: 14px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: 400;
|
|
|
- color: #999999;
|
|
|
- line-height: 24px;
|
|
|
-
|
|
|
- .replay {
|
|
|
- float: right;
|
|
|
- font-size: 14px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: 400;
|
|
|
- color: #3f8dfd;
|
|
|
- line-height: 24px;
|
|
|
- margin-right: 20px;
|
|
|
- }
|
|
|
-
|
|
|
- .del {
|
|
|
- float: right;
|
|
|
- cursor: pointer;
|
|
|
- font-size: 14px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: 400;
|
|
|
- color: #ff3b30;
|
|
|
- line-height: 24px;
|
|
|
- margin-right: 20px;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .reply-list {
|
|
|
- margin: 20px 0;
|
|
|
- width: 100%;
|
|
|
- background: #f9f9f9;
|
|
|
- border-radius: 8px;
|
|
|
- padding: 0 0 0 20px;
|
|
|
-
|
|
|
- &__item {
|
|
|
- padding: 20px 0;
|
|
|
- display: flex;
|
|
|
- border-bottom: 1px solid #ccc;
|
|
|
-
|
|
|
- &:nth-last-of-type(1) {
|
|
|
- border: 0;
|
|
|
- }
|
|
|
-
|
|
|
- &__avatar {
|
|
|
- width: 40px;
|
|
|
- height: 40px;
|
|
|
- display: table-cell;
|
|
|
- border-radius: 50%;
|
|
|
- text-align: center;
|
|
|
-
|
|
|
- img {
|
|
|
- display: inline-block;
|
|
|
- vertical-align: middle;
|
|
|
- max-width: 100%;
|
|
|
- max-height: 100%;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- &__content {
|
|
|
- border-radius: 8px;
|
|
|
- flex: 1;
|
|
|
- margin-left: 10px;
|
|
|
-
|
|
|
- .nickname {
|
|
|
- font-size: 14px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: bold;
|
|
|
- color: #fff;
|
|
|
- line-height: 24px;
|
|
|
- }
|
|
|
-
|
|
|
- .desc {
|
|
|
- font-size: 14px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: 400;
|
|
|
- color: #666666;
|
|
|
- line-height: 24px;
|
|
|
- }
|
|
|
-
|
|
|
- .time {
|
|
|
- font-size: 14px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: 400;
|
|
|
- color: #999999;
|
|
|
- line-height: 24px;
|
|
|
-
|
|
|
- .reply {
|
|
|
- float: right;
|
|
|
- font-size: 14px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: 400;
|
|
|
- color: #3f8dfd;
|
|
|
- line-height: 24px;
|
|
|
- margin-right: 20px;
|
|
|
- cursor: pointer;
|
|
|
- user-select: none;
|
|
|
- }
|
|
|
-
|
|
|
- .del {
|
|
|
- cursor: pointer;
|
|
|
- margin-right: 20px;
|
|
|
- float: right;
|
|
|
- font-size: 14px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: 400;
|
|
|
- color: #ff3b30;
|
|
|
- line-height: 24px;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .lecture-notes {
|
|
|
- &__content {
|
|
|
- .left-box {
|
|
|
- float: left;
|
|
|
- width: 462px;
|
|
|
-
|
|
|
- .textarea {
|
|
|
- border-bottom: 1px solid #eee;
|
|
|
-
|
|
|
- .submit {
|
|
|
- float: right;
|
|
|
- width: 138px;
|
|
|
- padding: 10px 0;
|
|
|
- margin: 10px 0 25px 0;
|
|
|
- border-radius: 20px;
|
|
|
- text-align: center;
|
|
|
- font-size: 16px;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .note-list {
|
|
|
- &__content {
|
|
|
- border-bottom: 1px solid #eee;
|
|
|
-
|
|
|
- &__title {
|
|
|
- width: 216px;
|
|
|
- height: 24px;
|
|
|
- background: #ccc;
|
|
|
- border-radius: 24px;
|
|
|
- font-size: 14px;
|
|
|
- color: #666666;
|
|
|
- text-align: center;
|
|
|
- line-height: 24px;
|
|
|
- margin: 20px 0;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- &__item {
|
|
|
- display: flex;
|
|
|
- padding: 15px;
|
|
|
-
|
|
|
- .el-icon-video-play {
|
|
|
- cursor: pointer;
|
|
|
- font-size: 20px;
|
|
|
- color: #3f8dfd;
|
|
|
- }
|
|
|
-
|
|
|
- &__content {
|
|
|
- flex: 1;
|
|
|
- margin-left: 10px;
|
|
|
-
|
|
|
- .title {
|
|
|
- cursor: pointer;
|
|
|
- font-size: 14px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: bold;
|
|
|
- color: #3f8dfd;
|
|
|
- line-height: 24px;
|
|
|
- }
|
|
|
-
|
|
|
- .desc {
|
|
|
- font-size: 14px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: 400;
|
|
|
- color: #666666;
|
|
|
- line-height: 24px;
|
|
|
- }
|
|
|
-
|
|
|
- .time {
|
|
|
- font-size: 14px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: 400;
|
|
|
- color: #999999;
|
|
|
- line-height: 24px;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .pagination {
|
|
|
- margin-top: 30px;
|
|
|
- text-align: center;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .right-box {
|
|
|
- width: 786px;
|
|
|
- float: right;
|
|
|
-
|
|
|
- .lecture-list {
|
|
|
- background: #f5f7fa;
|
|
|
- border-radius: 8px;
|
|
|
-
|
|
|
- &__header {
|
|
|
- padding: 0 16px;
|
|
|
- height: 40px;
|
|
|
- line-height: 40px;
|
|
|
- font-size: 18px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: bold;
|
|
|
- color: #333333;
|
|
|
-
|
|
|
- .slide-btn {
|
|
|
- cursor: pointer;
|
|
|
- float: right;
|
|
|
- font-size: 14px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: 400;
|
|
|
- color: #999999;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- &__body {
|
|
|
- .list {
|
|
|
- &__item {
|
|
|
- border-top: 1px solid #fff;
|
|
|
- padding: 0 8px 0 16px;
|
|
|
- height: 56px;
|
|
|
- line-height: 55px;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
-
|
|
|
- .title {
|
|
|
- flex: 1;
|
|
|
- font-size: 16px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: 400;
|
|
|
- color: #333333;
|
|
|
- }
|
|
|
-
|
|
|
- .btns {
|
|
|
- .btn {
|
|
|
- cursor: pointer;
|
|
|
- display: inline-block;
|
|
|
- vertical-align: middle;
|
|
|
- width: 80px;
|
|
|
- height: 32px;
|
|
|
- background: #ffffff;
|
|
|
- border: 1px solid #3f8dfd;
|
|
|
- border-radius: 16px;
|
|
|
- text-align: center;
|
|
|
- line-height: 30px;
|
|
|
- color: #3f8dfd;
|
|
|
- margin: 0 8px;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- &__footer {
|
|
|
- margin-top: 24px;
|
|
|
-
|
|
|
- .lecture-scan {
|
|
|
- background: #f5f7fa;
|
|
|
- border-radius: 8px;
|
|
|
- overflow: hidden;
|
|
|
-
|
|
|
- &__header {
|
|
|
- height: 40px;
|
|
|
- line-height: 40px;
|
|
|
- padding: 0 16px;
|
|
|
- font-size: 16px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: bold;
|
|
|
- color: #333333;
|
|
|
- }
|
|
|
-
|
|
|
- &__body {
|
|
|
- height: 800px;
|
|
|
- text-align: center;
|
|
|
- overflow-y: scroll;
|
|
|
-
|
|
|
- .iframe {
|
|
|
- width: 100%;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+.section_box {
|
|
|
+ width: 1200px;
|
|
|
+ margin: 0 auto;
|
|
|
+ & > .breadcrumb {
|
|
|
+ padding: 14px 0px 0px;
|
|
|
+ /deep/ .el-breadcrumb__inner {
|
|
|
+ font-size: 14px;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- .take-photo {
|
|
|
- /deep/ .el-dialog__header {
|
|
|
- display: none;
|
|
|
- }
|
|
|
-
|
|
|
- /deep/ .el-dialog__body {
|
|
|
- padding: 0;
|
|
|
- overflow: unset;
|
|
|
- }
|
|
|
-
|
|
|
- &__close {
|
|
|
- cursor: pointer;
|
|
|
- position: absolute;
|
|
|
- right: 0;
|
|
|
- top: -28px;
|
|
|
- width: 24px;
|
|
|
- height: 24px;
|
|
|
- line-height: 24px;
|
|
|
- text-align: center;
|
|
|
- color: #eee;
|
|
|
- border: 1px solid #eee;
|
|
|
- border-radius: 50%;
|
|
|
- }
|
|
|
-
|
|
|
- &__header {
|
|
|
- height: 40px;
|
|
|
- border-bottom: 1px solid #eee;
|
|
|
- line-height: 40px;
|
|
|
- font-size: 16px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: bold;
|
|
|
- color: #333333;
|
|
|
- padding-left: 24px;
|
|
|
- }
|
|
|
-
|
|
|
- &__body {
|
|
|
- // height: 400px;
|
|
|
- padding: 40px 24px;
|
|
|
-
|
|
|
- .left-box {
|
|
|
- width: 336px;
|
|
|
- float: left;
|
|
|
-
|
|
|
- .title {
|
|
|
- font-size: 16px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: bold;
|
|
|
- color: #ff3b30;
|
|
|
- line-height: 24px;
|
|
|
- }
|
|
|
-
|
|
|
- .content {
|
|
|
- font-size: 14px;
|
|
|
- font-family: Microsoft YaHei;
|
|
|
- font-weight: 400;
|
|
|
- color: #333333;
|
|
|
- line-height: 28px;
|
|
|
- margin-top: 32px;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .right-box {
|
|
|
- float: right;
|
|
|
- width: 400px;
|
|
|
- height: 400px;
|
|
|
- position: relative;
|
|
|
- overflow: hidden;
|
|
|
-
|
|
|
- video {
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- }
|
|
|
-
|
|
|
- .mask {
|
|
|
- width: 55%;
|
|
|
- height: 200px;
|
|
|
- position: absolute;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- right: 0;
|
|
|
- bottom: 0;
|
|
|
- margin: 30px auto 0;
|
|
|
- box-shadow: 0 0 0 2000px rgba(0, 0, 0, 0.4);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- &__footer {
|
|
|
- height: 90px;
|
|
|
- border-top: 1px solid #eee;
|
|
|
- text-align: center;
|
|
|
-
|
|
|
- .take {
|
|
|
- display: inline-block;
|
|
|
- width: 200px;
|
|
|
- height: 40px;
|
|
|
- padding: 0;
|
|
|
- border-radius: 20px;
|
|
|
- text-align: center;
|
|
|
- line-height: 40px;
|
|
|
- margin: 24px auto;
|
|
|
- }
|
|
|
- }
|
|
|
+ & > .title {
|
|
|
+ font-size: 18px;
|
|
|
+ font-weight: bold;
|
|
|
+ padding: 14px 0px;
|
|
|
}
|
|
|
-
|
|
|
- .info {
|
|
|
- &__content {
|
|
|
- height: 67vh;
|
|
|
- overflow-y: scroll;
|
|
|
-
|
|
|
- .handCenter {
|
|
|
- border-radius: 8px;
|
|
|
- // width: 600px;
|
|
|
- background: #fff;
|
|
|
- }
|
|
|
-
|
|
|
- .upload-box {
|
|
|
- display: inline-block;
|
|
|
- vertical-align: top;
|
|
|
-
|
|
|
- .el-icon-error {
|
|
|
- cursor: pointer;
|
|
|
- z-index: 99;
|
|
|
- position: absolute;
|
|
|
- left: 60px;
|
|
|
- font-size: 20px;
|
|
|
- color: red;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ & > .el-main {
|
|
|
+ padding: 0;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
-/deep/ textarea {
|
|
|
- background: #65696d;
|
|
|
- color: #c7c7c7;
|
|
|
- border-color: transparent;
|
|
|
-}
|
|
|
-
|
|
|
-/deep/ .el-input__count {
|
|
|
- color: #999;
|
|
|
- background: transparent;
|
|
|
-}
|
|
|
</style>
|