|
@@ -1307,10 +1307,14 @@
|
|
|
</p>
|
|
</p>
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
- <div class="right-box"></div>
|
|
|
|
|
|
|
+ <div class="right-box">
|
|
|
|
|
+ <video id="video" :src="stream"></video>
|
|
|
|
|
+ </div>
|
|
|
</div>
|
|
</div>
|
|
|
<div class="take-photo__footer">
|
|
<div class="take-photo__footer">
|
|
|
- <div class="take">拍照</div>
|
|
|
|
|
|
|
+ <el-button type="primary" class="take" @click="onPhoto"
|
|
|
|
|
+ >拍照</el-button
|
|
|
|
|
+ >
|
|
|
</div>
|
|
</div>
|
|
|
</div>
|
|
</div>
|
|
|
</el-dialog>
|
|
</el-dialog>
|
|
@@ -1334,7 +1338,10 @@ export default {
|
|
|
},
|
|
},
|
|
|
data() {
|
|
data() {
|
|
|
return {
|
|
return {
|
|
|
|
|
+ stream: null,
|
|
|
playSectionId: 0,
|
|
playSectionId: 0,
|
|
|
|
|
+ moduleId: 0,
|
|
|
|
|
+ chapterId: 0,
|
|
|
menuTab: [],
|
|
menuTab: [],
|
|
|
lectureShow: true,
|
|
lectureShow: true,
|
|
|
textarea: "",
|
|
textarea: "",
|
|
@@ -1376,6 +1383,7 @@ export default {
|
|
|
pageNum: 1,
|
|
pageNum: 1,
|
|
|
pageSize: 4,
|
|
pageSize: 4,
|
|
|
},
|
|
},
|
|
|
|
|
+ ossAvatarUrl: "", //照片地址
|
|
|
nowTime: 0,
|
|
nowTime: 0,
|
|
|
};
|
|
};
|
|
|
},
|
|
},
|
|
@@ -1383,14 +1391,82 @@ export default {
|
|
|
...mapGetters(["userInfo"]),
|
|
...mapGetters(["userInfo"]),
|
|
|
},
|
|
},
|
|
|
mounted() {
|
|
mounted() {
|
|
|
|
|
+ this.courseId = this.$route.query.courseId || "";
|
|
|
this.nowTime = Number(new Date().getTime() / 1000).toFixed(0);
|
|
this.nowTime = Number(new Date().getTime() / 1000).toFixed(0);
|
|
|
this.goodsId = this.$route.params.goodsId;
|
|
this.goodsId = this.$route.params.goodsId;
|
|
|
this.orderGoodsId = this.$route.query.orderGoodsId;
|
|
this.orderGoodsId = this.$route.query.orderGoodsId;
|
|
|
this.gradeId = this.$route.query.gradeId;
|
|
this.gradeId = this.$route.query.gradeId;
|
|
|
|
|
|
|
|
this.courseCourseList();
|
|
this.courseCourseList();
|
|
|
|
|
+ this.takePhotoModal = true;
|
|
|
|
|
+ this.$nextTick(() => {
|
|
|
|
|
+ if (
|
|
|
|
|
+ window.navigator.mediaDevices.getUserMedia ||
|
|
|
|
|
+ window.navigator.getUserMedia ||
|
|
|
|
|
+ window.navigator.webkitGetUserMedia ||
|
|
|
|
|
+ window.navigator.mozGetUserMedia
|
|
|
|
|
+ ) {
|
|
|
|
|
+ console.log(this.getUserMedia, "getUserMedia");
|
|
|
|
|
+ // 调用用户媒体设备, 访问摄像头
|
|
|
|
|
+ this.getUserMedia(
|
|
|
|
|
+ {
|
|
|
|
|
+ video: {
|
|
|
|
|
+ width: 400,
|
|
|
|
|
+ height: 300,
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ this.photographSuccess,
|
|
|
|
|
+ this.photographError
|
|
|
|
|
+ );
|
|
|
|
|
+ } else {
|
|
|
|
|
+ alert("不支持访问用户媒体");
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
},
|
|
},
|
|
|
methods: {
|
|
methods: {
|
|
|
|
|
+ // 点击拍照按钮
|
|
|
|
|
+ onPhoto() {
|
|
|
|
|
+ // if (this.isIE) {
|
|
|
|
|
+ // window.webcam.capture();
|
|
|
|
|
+ // } else {
|
|
|
|
|
+ const canvas = document.getElementById("canvas");
|
|
|
|
|
+ const context = canvas.getContext("2d");
|
|
|
|
|
+ const video = document.getElementById("video");
|
|
|
|
|
+ context.drawImage(video, 0, 0, 400, 300);
|
|
|
|
|
+ this.faceUrl = canvas.toDataURL("image/png");
|
|
|
|
|
+ // }
|
|
|
|
|
+ },
|
|
|
|
|
+ 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(res) {
|
|
|
|
|
+ // 兼容webkit核心浏览器
|
|
|
|
|
+ const video = document.getElementById("video");
|
|
|
|
|
+ // 将视频流设置为video元素的源
|
|
|
|
|
+ video.srcObject = stream;
|
|
|
|
|
+ this.mediaStreamTrack =
|
|
|
|
|
+ typeof stream.stop === "function" ? stream : stream.getTracks()[0];
|
|
|
|
|
+ video.play();
|
|
|
|
|
+ },
|
|
|
|
|
+ photographError(err) {
|
|
|
|
|
+ console.log(err);
|
|
|
|
|
+ },
|
|
|
/**
|
|
/**
|
|
|
* 切换科目
|
|
* 切换科目
|
|
|
*/
|
|
*/
|
|
@@ -1404,10 +1480,10 @@ export default {
|
|
|
this.vid = "";
|
|
this.vid = "";
|
|
|
this.vidzb = "";
|
|
this.vidzb = "";
|
|
|
this.nowTime = Number(new Date().getTime() / 1000).toFixed(0);
|
|
this.nowTime = Number(new Date().getTime() / 1000).toFixed(0);
|
|
|
- this.courseDetail();
|
|
|
|
|
- this.getGoodsDetail();
|
|
|
|
|
- this.getAnswerList();
|
|
|
|
|
- this.getMenuList();
|
|
|
|
|
|
|
+ this.courseDetail(); //课程详情
|
|
|
|
|
+ this.getGoodsDetail(); //商品详情
|
|
|
|
|
+ this.getAnswerList(); //答疑列表
|
|
|
|
|
+ this.getMenuList(); //学习目录
|
|
|
this.getReMenuList(); //获取重修目录
|
|
this.getReMenuList(); //获取重修目录
|
|
|
this.getNoteList(); //获取节笔记
|
|
this.getNoteList(); //获取节笔记
|
|
|
},
|
|
},
|
|
@@ -1602,22 +1678,206 @@ export default {
|
|
|
|
|
|
|
|
if (section.type != 2) {
|
|
if (section.type != 2) {
|
|
|
//播放视频
|
|
//播放视频
|
|
|
|
|
+ this.moduleId = section.moduleId;
|
|
|
|
|
+ this.chapterId = section.chapterId;
|
|
|
this.playSectionId = section.sectionId;
|
|
this.playSectionId = section.sectionId;
|
|
|
this.getNoteList();
|
|
this.getNoteList();
|
|
|
this.initVideo(section);
|
|
this.initVideo(section);
|
|
|
}
|
|
}
|
|
|
},
|
|
},
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 是否有上一章节
|
|
|
|
|
+ */
|
|
|
|
|
+ hasPreItem(rows, option) {
|
|
|
|
|
+ let moduleId = option.moduleId;
|
|
|
|
|
+ let chapterId = option.chapterId;
|
|
|
|
|
+ let sectionId = option.sectionId;
|
|
|
|
|
+ let index = 0;
|
|
|
|
|
+
|
|
|
|
|
+ for (let i = 0; i < rows.length; i++) {
|
|
|
|
|
+ if (
|
|
|
|
|
+ rows[i].moduleId == moduleId &&
|
|
|
|
|
+ rows[i].chapterId == chapterId &&
|
|
|
|
|
+ rows[i].sectionId == sectionId
|
|
|
|
|
+ ) {
|
|
|
|
|
+ index = i;
|
|
|
|
|
+ break;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (i == 0) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ return true;
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
async initVideo(option) {
|
|
async initVideo(option) {
|
|
|
- await this.clears();
|
|
|
|
|
- console.log(option);
|
|
|
|
|
- if (option.sectionType === 2) {
|
|
|
|
|
- this.vidzb = option.liveUrl;
|
|
|
|
|
- this.loadPlayerScriptzb(this.loadPlayerzb);
|
|
|
|
|
|
|
+ if (this.businessData.goodsLearningOrder == 2 && !option.isRebuild) {
|
|
|
|
|
+ //要按从头到尾顺序学习, 且不是重修课程
|
|
|
|
|
+
|
|
|
|
|
+ let rows = await this.studyRecordMenuAllList();
|
|
|
|
|
+ if (!this.hasPreItem(rows, option)) {
|
|
|
|
|
+ //判断是否有上一节
|
|
|
|
|
+ let newRows = [];
|
|
|
|
|
+ for (let i = 0; i < rows.length; i++) {
|
|
|
|
|
+ let moduleTrue =
|
|
|
|
|
+ rows[i].moduleId == option.menuId ||
|
|
|
|
|
+ rows[i].moduleId == option.moduleId;
|
|
|
|
|
+ let chapterTrue = rows[i].chapterId == option.chapterId;
|
|
|
|
|
+ let sectionTrue = rows[i].sectionId == option.sectionId;
|
|
|
|
|
+ if (moduleTrue && chapterTrue && sectionTrue) {
|
|
|
|
|
+ break;
|
|
|
|
|
+ } else {
|
|
|
|
|
+ if (rows[i].sectionType != 2) {
|
|
|
|
|
+ newRows.push(rows[i]);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ let isAllLearn = newRows.every((item) => {
|
|
|
|
|
+ return item.studyStatus == 1;
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ if (isAllLearn) {
|
|
|
|
|
+ this.playVideo(option);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ this.$message({
|
|
|
|
|
+ type: "warning",
|
|
|
|
|
+ message: "请按顺序学习视频课程",
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ //第一章第一节
|
|
|
|
|
+ this.playVideo(option);
|
|
|
|
|
+ }
|
|
|
} else {
|
|
} else {
|
|
|
|
|
+ this.playVideo(option);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ return;
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ async playVideo(option) {
|
|
|
|
|
+ if (option.sectionType == 1 || option.sectionType == 3) {
|
|
|
|
|
+ //录播
|
|
|
|
|
+
|
|
|
|
|
+ let learnNum = await this.goodsTodayStudySectionNum(option);
|
|
|
|
|
+ let hasLearn = await this.gradeCheckGoodsStudy(option);
|
|
|
|
|
+
|
|
|
|
|
+ if (this.goodsData.sectionMaxNum > 0) {
|
|
|
|
|
+ if (learnNum >= this.goodsData.sectionMaxNum && !hasLearn) {
|
|
|
|
|
+ this.$message({
|
|
|
|
|
+ type: "warning",
|
|
|
|
|
+ message: `每天最多学习${this.goodsData.sectionMaxNum}节`,
|
|
|
|
|
+ });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!option.recordingUrl) {
|
|
|
|
|
+ this.$message({
|
|
|
|
|
+ type: "warning",
|
|
|
|
|
+ message: `暂无播放地址数据`,
|
|
|
|
|
+ });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (this.playSectionId == option.section) {
|
|
|
|
|
+ //切换为同一频道
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (this.playSectionId > 0) {
|
|
|
|
|
+ //切换视频
|
|
|
|
|
+ // let oldSectionId = this.playSectionId;
|
|
|
|
|
+ // uni.$emit("changeSection", oldSectionId);
|
|
|
|
|
+ }
|
|
|
|
|
+ //设置播放的节ID
|
|
|
|
|
+ await this.clears();
|
|
|
|
|
+ this.playSectionId = option.sectionId;
|
|
|
this.vid = option.recordingUrl;
|
|
this.vid = option.recordingUrl;
|
|
|
this.duration = option.noteSecond || option.durationTime || 0;
|
|
this.duration = option.noteSecond || option.durationTime || 0;
|
|
|
this.loadPlayerScript(this.loadPlayer);
|
|
this.loadPlayerScript(this.loadPlayer);
|
|
|
|
|
+ // uni.$emit("levelId", this.levelId);
|
|
|
|
|
+ // uni.$emit("getSection", this.menuItem);
|
|
|
|
|
+ // uni.$emit("isRebuild", this.isRebuild);
|
|
|
}
|
|
}
|
|
|
|
|
+ if (option.sectionType == 2) {
|
|
|
|
|
+ //直播
|
|
|
|
|
+
|
|
|
|
|
+ let learnNum = await this.goodsTodayStudySectionNum(option);
|
|
|
|
|
+ let hasLearn = await this.gradeCheckGoodsStudy(option);
|
|
|
|
|
+
|
|
|
|
|
+ if (this.goodsData.sectionMaxNum > 0) {
|
|
|
|
|
+ if (learnNum >= this.goodsData.sectionMaxNum && !hasLearn) {
|
|
|
|
|
+ this.$message({
|
|
|
|
|
+ type: "warning",
|
|
|
|
|
+ message: `每天最多学习${this.sectionMaxNum}节`,
|
|
|
|
|
+ });
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ if (!option.liveUrl) {
|
|
|
|
|
+ this.$message({
|
|
|
|
|
+ type: "warning",
|
|
|
|
|
+ message: `暂无直播地址数据`,
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
|
|
+ if (this.playSectionId == option.section) {
|
|
|
|
|
+ //切换为同一频道
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
+ //设置播放的节ID
|
|
|
|
|
+ await this.clears();
|
|
|
|
|
+ this.playSectionId = option.sectionId;
|
|
|
|
|
+ this.vidzb = option.liveUrl;
|
|
|
|
|
+ this.loadPlayerScriptzb(this.loadPlayerzb);
|
|
|
|
|
+ // uni.$emit("levelId", this.levelId);
|
|
|
|
|
+ // uni.$emit("getChannel", this.menuItem);
|
|
|
|
|
+ // uni.$emit("isRebuild", this.isRebuild);
|
|
|
|
|
+ // console.log(this.menuItem, "menuItem");
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ gradeCheckGoodsStudy(option) {
|
|
|
|
|
+ return new Promise((resolve) => {
|
|
|
|
|
+ this.$request
|
|
|
|
|
+ .gradeCheckGoodsStudy({
|
|
|
|
|
+ goodsId: this.goodsId,
|
|
|
|
|
+ gradeId: this.gradeId,
|
|
|
|
|
+ moduleId: option.moduleId || 0,
|
|
|
|
|
+ chapterId: option.chapterId || 0,
|
|
|
|
|
+ sectionId: option.sectionId || option.menuId,
|
|
|
|
|
+ })
|
|
|
|
|
+ .then((res) => {
|
|
|
|
|
+ resolve(res.data);
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+ goodsTodayStudySectionNum(option) {
|
|
|
|
|
+ return new Promise((resolve) => {
|
|
|
|
|
+ this.$request
|
|
|
|
|
+ .goodsTodayStudySectionNum({
|
|
|
|
|
+ goodsId: this.goodsId,
|
|
|
|
|
+ gradeId: this.gradeId,
|
|
|
|
|
+ })
|
|
|
|
|
+ .then((res) => {
|
|
|
|
|
+ resolve(res.data);
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
|
|
+
|
|
|
|
|
+ studyRecordMenuAllList() {
|
|
|
|
|
+ return new Promise((resolve) => {
|
|
|
|
|
+ this.$request
|
|
|
|
|
+ .studyRecordMenuAllList({
|
|
|
|
|
+ courseId: this.courseId,
|
|
|
|
|
+ gradeId: this.gradeId,
|
|
|
|
|
+ goodsId: this.goodsId,
|
|
|
|
|
+ })
|
|
|
|
|
+ .then((res) => {
|
|
|
|
|
+ resolve(res.data);
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
},
|
|
},
|
|
|
loadPlayerzb() {
|
|
loadPlayerzb() {
|
|
|
const polyvLivePlayer = window.polyvLivePlayer;
|
|
const polyvLivePlayer = window.polyvLivePlayer;
|
|
@@ -1686,6 +1946,51 @@ export default {
|
|
|
resolve();
|
|
resolve();
|
|
|
});
|
|
});
|
|
|
},
|
|
},
|
|
|
|
|
+
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 提交观看记录
|
|
|
|
|
+ */
|
|
|
|
|
+ postStudyRecord(status = 0, sectionId = this.playSectionId) {
|
|
|
|
|
+ let currentTime = 0;
|
|
|
|
|
+ let PlayDuration = 0;
|
|
|
|
|
+ var polyvPlayerContext = this.player;
|
|
|
|
|
+ if (polyvPlayerContext) {
|
|
|
|
|
+ currentTime = polyvPlayerContext.j2s_getDuration(); //总的视频播放时刻
|
|
|
|
|
+ PlayDuration = polyvPlayerContext.j2s_getCurrentTime(); //本次看的时长
|
|
|
|
|
+ }
|
|
|
|
|
+ if (this.vidzb) {
|
|
|
|
|
+ currentTime = 2; //直播无法获取,无论开始结束都传2秒
|
|
|
|
|
+ }
|
|
|
|
|
+ let self = this;
|
|
|
|
|
+ let data = {
|
|
|
|
|
+ photo: self.ossAvatarUrl,
|
|
|
|
|
+ sectionId: parseInt(sectionId),
|
|
|
|
|
+ goodsId: parseInt(self.goodsId),
|
|
|
|
|
+ courseId: parseInt(self.courseId),
|
|
|
|
|
+ studyDuration: parseInt(PlayDuration > 0 ? PlayDuration : 0),
|
|
|
|
|
+ gradeId: parseInt(self.gradeId),
|
|
|
|
|
+ chapterId: parseInt(self.chapterId),
|
|
|
|
|
+ moduleId: parseInt(self.moduleId),
|
|
|
|
|
+ videoCurrentTime: parseInt(currentTime > 0 ? currentTime : 0),
|
|
|
|
|
+ };
|
|
|
|
|
+ if (status > 0) {
|
|
|
|
|
+ data.status = status;
|
|
|
|
|
+ }
|
|
|
|
|
+ this.$reqeust
|
|
|
|
|
+ .studyRecord(data)
|
|
|
|
|
+ .then((res) => {
|
|
|
|
|
+ if (status > 0) {
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ self.ossAvatarUrl = "";
|
|
|
|
|
+ })
|
|
|
|
|
+ .catch((err) => {
|
|
|
|
|
+ this.$message({
|
|
|
|
|
+ type: "warning",
|
|
|
|
|
+ message: err.msg,
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ },
|
|
|
getNoteList() {
|
|
getNoteList() {
|
|
|
let self = this;
|
|
let self = this;
|
|
|
self.noteList = [];
|
|
self.noteList = [];
|
|
@@ -1794,7 +2099,9 @@ export default {
|
|
|
this.param.gradeId = this.gradeId;
|
|
this.param.gradeId = this.gradeId;
|
|
|
this.$request.courseCourseList(this.param).then((res) => {
|
|
this.$request.courseCourseList(this.param).then((res) => {
|
|
|
this.courseList.push(...res.rows);
|
|
this.courseList.push(...res.rows);
|
|
|
- this.courseId = this.courseList[0].courseId;
|
|
|
|
|
|
|
+ if (!this.courseId) {
|
|
|
|
|
+ this.courseId = this.courseList[0].courseId;
|
|
|
|
|
+ }
|
|
|
this.param.total = res.total;
|
|
this.param.total = res.total;
|
|
|
this.courseChange();
|
|
this.courseChange();
|
|
|
});
|
|
});
|
|
@@ -2756,7 +3063,10 @@ export default {
|
|
|
width: 400px;
|
|
width: 400px;
|
|
|
height: 300px;
|
|
height: 300px;
|
|
|
|
|
|
|
|
- background: #000;
|
|
|
|
|
|
|
+ video {
|
|
|
|
|
+ width: 100%;
|
|
|
|
|
+ height: 100%;
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -2764,13 +3074,13 @@ export default {
|
|
|
height: 90px;
|
|
height: 90px;
|
|
|
border-top: 1px solid #eee;
|
|
border-top: 1px solid #eee;
|
|
|
.take {
|
|
.take {
|
|
|
|
|
+ display: block;
|
|
|
width: 200px;
|
|
width: 200px;
|
|
|
height: 40px;
|
|
height: 40px;
|
|
|
- background: #3f8dfd;
|
|
|
|
|
|
|
+ padding: 0;
|
|
|
border-radius: 20px;
|
|
border-radius: 20px;
|
|
|
text-align: center;
|
|
text-align: center;
|
|
|
line-height: 40px;
|
|
line-height: 40px;
|
|
|
- color: #fff;
|
|
|
|
|
margin: 24px auto;
|
|
margin: 24px auto;
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|