|
@@ -1,11 +1,14 @@
|
|
<template>
|
|
<template>
|
|
- <div v-if="questionDetail" class="question-body" :key="examQuestionId">
|
|
|
|
|
|
+ <div v-if="questionDetail" class="question-body">
|
|
<div v-html="questionDetail.text"></div>
|
|
<div v-html="questionDetail.text"></div>
|
|
<div v-html="questionDetail.audio"></div>
|
|
<div v-html="questionDetail.audio"></div>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
</template>
|
|
|
|
|
|
<script>
|
|
<script>
|
|
|
|
+import { createNamespacedHelpers } from "vuex";
|
|
|
|
+const { mapMutations } = createNamespacedHelpers("examingHomeModule");
|
|
|
|
+
|
|
export default {
|
|
export default {
|
|
name: "QuestionBody",
|
|
name: "QuestionBody",
|
|
data() {
|
|
data() {
|
|
@@ -13,68 +16,83 @@ export default {
|
|
},
|
|
},
|
|
props: {
|
|
props: {
|
|
questionBody: String,
|
|
questionBody: String,
|
|
- examQuestionId: String
|
|
|
|
|
|
+ examQuestion: Object
|
|
},
|
|
},
|
|
mounted() {
|
|
mounted() {
|
|
- const audio = document.getElementsByTagName("audio")[0];
|
|
|
|
-
|
|
|
|
- audio &&
|
|
|
|
- audio.addEventListener("play", () => {
|
|
|
|
- console.log("开始播放");
|
|
|
|
-
|
|
|
|
- //FIXME: error
|
|
|
|
- this.$http
|
|
|
|
- .post("/api/exam_question_playtimes", {
|
|
|
|
- questionId: this.examQuestionId
|
|
|
|
- // mediaName: mediaName
|
|
|
|
- })
|
|
|
|
- .then(
|
|
|
|
- function() {
|
|
|
|
- console.log("保存播放次数成功");
|
|
|
|
- },
|
|
|
|
- function() {
|
|
|
|
- console.log("保存播放次数失败");
|
|
|
|
- }
|
|
|
|
- );
|
|
|
|
- });
|
|
|
|
-
|
|
|
|
this.parseQuestion();
|
|
this.parseQuestion();
|
|
},
|
|
},
|
|
methods: {
|
|
methods: {
|
|
|
|
+ ...mapMutations(["updateExamQuestion"]),
|
|
async parseQuestion() {
|
|
async parseQuestion() {
|
|
let question = {};
|
|
let question = {};
|
|
if (this.questionBody.includes("question-audio")) {
|
|
if (this.questionBody.includes("question-audio")) {
|
|
- const audioArray = this.questionBody.match(
|
|
|
|
- /<a.*?question-audio.*?\/a>/g
|
|
|
|
- );
|
|
|
|
|
|
+ let audioArray = this.questionBody.match(/<a.*?question-audio.*?\/a>/g);
|
|
|
|
+ if (!this.examQuestion.audioPlayTimes) {
|
|
|
|
+ // 初始化音频播放次数
|
|
|
|
+ this.examQuestion.audioPlayTimes = new Array(audioArray.length).fill(
|
|
|
|
+ 0
|
|
|
|
+ );
|
|
|
|
+ }
|
|
question.text = this.questionBody.replace(
|
|
question.text = this.questionBody.replace(
|
|
/<a.*?question-audio.*?\/a>/g,
|
|
/<a.*?question-audio.*?\/a>/g,
|
|
""
|
|
""
|
|
);
|
|
);
|
|
|
|
+ // 测试 v-html中含有directive是否生效。结论:不生效
|
|
|
|
+ // question.text += "<span v-html='<text>abc</text>'>empty</span>";
|
|
|
|
+ audioArray = audioArray.map((v, i) => {
|
|
|
|
+ const remainTimes =
|
|
|
|
+ this.examQuestion.limitedPlayTimes -
|
|
|
|
+ this.examQuestion.audioPlayTimes[i];
|
|
|
|
+ if (remainTimes <= 0) {
|
|
|
|
+ v = v.replace("<a", "<a disabled"); // disabled不生效,仅仅起标明作用
|
|
|
|
+ v = v.replace(/url=/g, "");
|
|
|
|
+ }
|
|
|
|
+ return `${v}<span>(剩余播放次数:${remainTimes})</span><br/>`;
|
|
|
|
+ });
|
|
question.audio = audioArray
|
|
question.audio = audioArray
|
|
.join("")
|
|
.join("")
|
|
.replace(/<a/g, "<audio controls controlsList='nodownload'")
|
|
.replace(/<a/g, "<audio controls controlsList='nodownload'")
|
|
.replace(/url=/g, "src=")
|
|
.replace(/url=/g, "src=")
|
|
.replace(/a>/g, "audio>");
|
|
.replace(/a>/g, "audio>");
|
|
|
|
|
|
- this.$http
|
|
|
|
- .get("/api/exam_question_playtimes", {
|
|
|
|
- params: {
|
|
|
|
- questionId: this.examQuestionId
|
|
|
|
- }
|
|
|
|
- })
|
|
|
|
- .then(res => {
|
|
|
|
- //FIXME: audio playtimes
|
|
|
|
- console.log(res.data);
|
|
|
|
- });
|
|
|
|
|
|
+ setTimeout(this.bindAudioPlay, 1000);
|
|
} else {
|
|
} else {
|
|
question.text = this.questionBody;
|
|
question.text = this.questionBody;
|
|
question.audio = "";
|
|
question.audio = "";
|
|
}
|
|
}
|
|
this.questionDetail = question;
|
|
this.questionDetail = question;
|
|
|
|
+ },
|
|
|
|
+ bindAudioPlay() {
|
|
|
|
+ const audios = document.getElementsByTagName("audio");
|
|
|
|
+ if (audios.length === 0) {
|
|
|
|
+ setTimeout(this.bindAudioPlay, 1000);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ [...audios].forEach((audio, index) => {
|
|
|
|
+ audio.addEventListener("play", () => {
|
|
|
|
+ console.log("开始播放");
|
|
|
|
+ if (
|
|
|
|
+ this.examQuestion.limitedPlayTimes -
|
|
|
|
+ this.examQuestion.audioPlayTimes[index] <=
|
|
|
|
+ 0
|
|
|
|
+ ) {
|
|
|
|
+ console.log("无剩余播放次数");
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ audio.addEventListener("ended", () => {
|
|
|
|
+ console.log("结束播放");
|
|
|
|
+ this.examQuestion.audioPlayTimes[index] =
|
|
|
|
+ this.examQuestion.audioPlayTimes[index] + 1;
|
|
|
|
+ this.updateExamQuestion({
|
|
|
|
+ order: this.examQuestion.order,
|
|
|
|
+ audioPlayTimes: this.examQuestion.audioPlayTimes
|
|
|
|
+ });
|
|
|
|
+ this.parseQuestion(); // 不会死循环,因为这个是音频播放触发的
|
|
|
|
+ });
|
|
|
|
+ });
|
|
}
|
|
}
|
|
},
|
|
},
|
|
- computed: {},
|
|
|
|
watch: {
|
|
watch: {
|
|
questionBody() {
|
|
questionBody() {
|
|
this.parseQuestion();
|
|
this.parseQuestion();
|