|
@@ -1,8 +1,8 @@
|
|
|
<template>
|
|
|
<div v-if="isSyncState" :key="answerDivKey" class="question-view">
|
|
|
<question-body
|
|
|
- :questionBody="question.body"
|
|
|
- :examQuestion="examQuestion"
|
|
|
+ :question-body="question.body"
|
|
|
+ :exam-question="examQuestion"
|
|
|
></question-body>
|
|
|
<div class="ops">
|
|
|
<div class="score">({{ examQuestion.questionScore }}分)</div>
|
|
@@ -53,12 +53,12 @@
|
|
|
ref="answerDiv"
|
|
|
ondragstart="return false"
|
|
|
ondrop="return false"
|
|
|
- @keydown="disableCtrl"
|
|
|
:contenteditable="true"
|
|
|
- v-html="originalStudentAnswer"
|
|
|
+ class="stu-answer"
|
|
|
+ @keydown="disableCtrl"
|
|
|
@input="$event => textInput($event)"
|
|
|
@blur="$event => textInput($event)"
|
|
|
- class="stu-answer"
|
|
|
+ v-html="originalStudentAnswer"
|
|
|
></div>
|
|
|
<div
|
|
|
style="margin-top: -25px; margin-bottom: 25px; width: 100%; max-width: 500px;"
|
|
@@ -84,7 +84,7 @@
|
|
|
}},并上传文件。
|
|
|
</div>
|
|
|
<div v-if="qrScanned" style="margin-top: 30px; font-size: 30px;">
|
|
|
- {{ this.examQuestion.studentAnswer ? "已上传" : "已扫描" }}
|
|
|
+ {{ examQuestion.studentAnswer ? "已上传" : "已扫描" }}
|
|
|
<Icon type="md-checkmark" />
|
|
|
</div>
|
|
|
</div>
|
|
@@ -98,11 +98,11 @@
|
|
|
>
|
|
|
<span class="audio-answer-line-height">答案:</span>
|
|
|
<audio
|
|
|
+ v-if="examQuestion.studentAnswer"
|
|
|
class="audio-answer-line-height"
|
|
|
- v-if="this.examQuestion.studentAnswer"
|
|
|
controls
|
|
|
controlsList="nodownload"
|
|
|
- :src="this.examQuestion.studentAnswer"
|
|
|
+ :src="examQuestion.studentAnswer"
|
|
|
/>
|
|
|
<span v-else class="audio-answer-line-height">未上传文件</span>
|
|
|
</div>
|
|
@@ -110,17 +110,17 @@
|
|
|
|
|
|
<div v-if="canAttachPhotos" style="padding-top: 1px;">
|
|
|
<UploadPhotos
|
|
|
- :defaultList="
|
|
|
+ :default-list="
|
|
|
photoAnswers.map(v => {
|
|
|
return v;
|
|
|
})
|
|
|
"
|
|
|
+ :qr-value="qrValue"
|
|
|
+ :exam-question="examQuestion"
|
|
|
+ style="margin-top: 20px; width: 350px;"
|
|
|
@on-photo-added="photoAdded"
|
|
|
@on-photo-removed="photoRemoved"
|
|
|
@on-photos-reseted="photosReseted"
|
|
|
- :qrValue="qrValue"
|
|
|
- :examQuestion="examQuestion"
|
|
|
- style="margin-top: 20px; width: 350px;"
|
|
|
/>
|
|
|
</div>
|
|
|
<div class="reset" style="padding-top: 20px;">
|
|
@@ -164,6 +164,25 @@ if (process.env.VUE_APP_CAN_UPLOAD_PHOTOS_FOR_TEST === "true") {
|
|
|
}
|
|
|
export default {
|
|
|
name: "TextQuestionView",
|
|
|
+ components: {
|
|
|
+ QuestionBody,
|
|
|
+ UploadPhotos,
|
|
|
+ qrcode: VueQrcode,
|
|
|
+ },
|
|
|
+ props: {
|
|
|
+ question: {
|
|
|
+ type: Object,
|
|
|
+ default() {
|
|
|
+ return {};
|
|
|
+ },
|
|
|
+ },
|
|
|
+ examQuestion: {
|
|
|
+ type: Object,
|
|
|
+ default() {
|
|
|
+ return {};
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
data() {
|
|
|
return {
|
|
|
studentAnswer: this.examQuestion.studentAnswer,
|
|
@@ -174,9 +193,118 @@ export default {
|
|
|
qrScanned: false,
|
|
|
};
|
|
|
},
|
|
|
- props: {
|
|
|
- question: Object,
|
|
|
- examQuestion: Object,
|
|
|
+ computed: {
|
|
|
+ ...mapState(["questionQrCode", "questionQrCodeScanned"]),
|
|
|
+ isSyncState() {
|
|
|
+ return this.examQuestion.order == this.$route.params.order;
|
|
|
+ },
|
|
|
+ rightAnswerTransform() {
|
|
|
+ return this.question.rightAnswer.join("");
|
|
|
+ },
|
|
|
+ answerWordCount() {
|
|
|
+ if (this.studentAnswer && this.$refs.answerDiv) {
|
|
|
+ return this.$refs.answerDiv.innerText.replace(/\s+/g, "").length;
|
|
|
+ } else {
|
|
|
+ const ele = document.createElement("div");
|
|
|
+ ele.innerHTML = this.studentAnswer;
|
|
|
+
|
|
|
+ return ele.innerText.replace(/\s+/g, "").length;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ isAudioAnswerType() {
|
|
|
+ return this.examQuestion.answerType === "SINGLE_AUDIO";
|
|
|
+ },
|
|
|
+ shouldFetchQrCode() {
|
|
|
+ const shouldFetch =
|
|
|
+ this.examQuestion.answerType === "SINGLE_AUDIO" ||
|
|
|
+ DOMAINS_CAN_UPLOAD_PHOTOS.includes(this.$store.state.user.schoolDomain);
|
|
|
+
|
|
|
+ return shouldFetch;
|
|
|
+ },
|
|
|
+ canAttachPhotos() {
|
|
|
+ return (
|
|
|
+ (this.$store.state.user.schoolDomain === "csu.ecs.qmth.com.cn" ||
|
|
|
+ DOMAINS_CAN_UPLOAD_PHOTOS.includes(
|
|
|
+ this.$store.state.user.schoolDomain
|
|
|
+ )) &&
|
|
|
+ !this.isAudioAnswerType
|
|
|
+ );
|
|
|
+ },
|
|
|
+ photoAnswers: {
|
|
|
+ get() {
|
|
|
+ if (!this.studentAnswer) return [];
|
|
|
+ const ele = document.createElement("div");
|
|
|
+ ele.innerHTML = this.studentAnswer;
|
|
|
+ const imgs = ele.querySelectorAll(".photo-answer");
|
|
|
+ // if()
|
|
|
+ return [...imgs].map(e => e.src.replace("!/both/200x200", ""));
|
|
|
+ },
|
|
|
+ set(pSrcs) {
|
|
|
+ let imageStr = pSrcs.map(
|
|
|
+ v =>
|
|
|
+ `<a href='${v}' target='_blank' ><img class='photo-answer' src='${v +
|
|
|
+ "!/both/200x200"}' /></a>`
|
|
|
+ );
|
|
|
+ const ele = document.createElement("div");
|
|
|
+ ele.innerHTML = this.studentAnswer || "";
|
|
|
+ const pEle = ele.querySelectorAll(".photo-answers-block");
|
|
|
+ if (pEle) [...pEle].forEach(v => v.remove());
|
|
|
+ // console.log(ele.innerHTML);
|
|
|
+
|
|
|
+ if (!ele.innerHTML && pSrcs.length === 0) {
|
|
|
+ // 完全为空则重置答案
|
|
|
+ this.studentAnswer = null;
|
|
|
+ // 更新answerDiv的内容
|
|
|
+ this.originalStudentAnswer = null;
|
|
|
+ } else {
|
|
|
+ this.studentAnswer =
|
|
|
+ ele.innerHTML +
|
|
|
+ `<div class='photo-answers-block'>${imageStr.join("")}</div>`;
|
|
|
+ // 更新answerDiv的内容
|
|
|
+ this.originalStudentAnswer = this.studentAnswer;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ },
|
|
|
+ },
|
|
|
+ watch: {
|
|
|
+ examQuestion() {
|
|
|
+ // console.log(this.examQuestion.studentAnswer);
|
|
|
+ this.studentAnswer = this.examQuestion.studentAnswer;
|
|
|
+ },
|
|
|
+ questionQrCode(value) {
|
|
|
+ // console.log(this.examQuestion.studentAnswer);
|
|
|
+ // console.log("watch", value);
|
|
|
+ if (value.order === this.examQuestion.order) {
|
|
|
+ this.qrValue = value.qrCode;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ questionQrCodeScanned(value) {
|
|
|
+ // console.log(this.examQuestion.studentAnswer);
|
|
|
+ // console.log("watch", value);
|
|
|
+ if (value.order === this.examQuestion.order) {
|
|
|
+ this.qrScanned = true;
|
|
|
+ }
|
|
|
+ },
|
|
|
+ studentAnswer() {
|
|
|
+ let realAnswer = null;
|
|
|
+ if (this.studentAnswer) {
|
|
|
+ // 如果有实际内容
|
|
|
+ realAnswer = this.studentAnswer
|
|
|
+ .replace(/<sup><\/sup>/gi, "")
|
|
|
+ .replace(/<sub><\/sub>/gi, "")
|
|
|
+ .replace(/<script/gi, "<script")
|
|
|
+ .replace(/script>/gi, "script>");
|
|
|
+ // .replace(/</gi, "<")
|
|
|
+ // .replace(/>/gi, ">")
|
|
|
+ // .replace(/<div><br><\/div>/gi, "<div><br></div>");
|
|
|
+ }
|
|
|
+ if (realAnswer !== this.examQuestion.studentAnswer) {
|
|
|
+ this.updateExamQuestion({
|
|
|
+ order: this.examQuestion.order,
|
|
|
+ studentAnswer: realAnswer,
|
|
|
+ });
|
|
|
+ }
|
|
|
+ },
|
|
|
},
|
|
|
created() {
|
|
|
this.fetchQRCode();
|
|
@@ -278,124 +406,6 @@ export default {
|
|
|
this.photoAnswers = [...urls];
|
|
|
},
|
|
|
},
|
|
|
- watch: {
|
|
|
- examQuestion() {
|
|
|
- // console.log(this.examQuestion.studentAnswer);
|
|
|
- this.studentAnswer = this.examQuestion.studentAnswer;
|
|
|
- },
|
|
|
- questionQrCode(value) {
|
|
|
- // console.log(this.examQuestion.studentAnswer);
|
|
|
- // console.log("watch", value);
|
|
|
- if (value.order === this.examQuestion.order) {
|
|
|
- this.qrValue = value.qrCode;
|
|
|
- }
|
|
|
- },
|
|
|
- questionQrCodeScanned(value) {
|
|
|
- // console.log(this.examQuestion.studentAnswer);
|
|
|
- // console.log("watch", value);
|
|
|
- if (value.order === this.examQuestion.order) {
|
|
|
- this.qrScanned = true;
|
|
|
- }
|
|
|
- },
|
|
|
- studentAnswer() {
|
|
|
- let realAnswer = null;
|
|
|
- if (this.studentAnswer) {
|
|
|
- // 如果有实际内容
|
|
|
- realAnswer = this.studentAnswer
|
|
|
- .replace(/<sup><\/sup>/gi, "")
|
|
|
- .replace(/<sub><\/sub>/gi, "")
|
|
|
- .replace(/<script/gi, "<script")
|
|
|
- .replace(/script>/gi, "script>");
|
|
|
- // .replace(/</gi, "<")
|
|
|
- // .replace(/>/gi, ">")
|
|
|
- // .replace(/<div><br><\/div>/gi, "<div><br></div>");
|
|
|
- }
|
|
|
- if (realAnswer !== this.examQuestion.studentAnswer) {
|
|
|
- this.updateExamQuestion({
|
|
|
- order: this.examQuestion.order,
|
|
|
- studentAnswer: realAnswer,
|
|
|
- });
|
|
|
- }
|
|
|
- },
|
|
|
- },
|
|
|
- computed: {
|
|
|
- ...mapState(["questionQrCode", "questionQrCodeScanned"]),
|
|
|
- isSyncState() {
|
|
|
- return this.examQuestion.order == this.$route.params.order;
|
|
|
- },
|
|
|
- rightAnswerTransform() {
|
|
|
- return this.question.rightAnswer.join("");
|
|
|
- },
|
|
|
- answerWordCount() {
|
|
|
- if (this.studentAnswer && this.$refs.answerDiv) {
|
|
|
- return this.$refs.answerDiv.innerText.replace(/\s+/g, "").length;
|
|
|
- } else {
|
|
|
- const ele = document.createElement("div");
|
|
|
- ele.innerHTML = this.studentAnswer;
|
|
|
-
|
|
|
- return ele.innerText.replace(/\s+/g, "").length;
|
|
|
- }
|
|
|
- },
|
|
|
- isAudioAnswerType() {
|
|
|
- return this.examQuestion.answerType === "SINGLE_AUDIO";
|
|
|
- },
|
|
|
- shouldFetchQrCode() {
|
|
|
- const shouldFetch =
|
|
|
- this.examQuestion.answerType === "SINGLE_AUDIO" ||
|
|
|
- DOMAINS_CAN_UPLOAD_PHOTOS.includes(this.$store.state.user.schoolDomain);
|
|
|
-
|
|
|
- return shouldFetch;
|
|
|
- },
|
|
|
- canAttachPhotos() {
|
|
|
- return (
|
|
|
- (this.$store.state.user.schoolDomain === "csu.ecs.qmth.com.cn" ||
|
|
|
- DOMAINS_CAN_UPLOAD_PHOTOS.includes(
|
|
|
- this.$store.state.user.schoolDomain
|
|
|
- )) &&
|
|
|
- !this.isAudioAnswerType
|
|
|
- );
|
|
|
- },
|
|
|
- photoAnswers: {
|
|
|
- get() {
|
|
|
- if (!this.studentAnswer) return [];
|
|
|
- const ele = document.createElement("div");
|
|
|
- ele.innerHTML = this.studentAnswer;
|
|
|
- const imgs = ele.querySelectorAll(".photo-answer");
|
|
|
- // if()
|
|
|
- return [...imgs].map(e => e.src.replace("!/both/200x200", ""));
|
|
|
- },
|
|
|
- set(pSrcs) {
|
|
|
- let imageStr = pSrcs.map(
|
|
|
- v =>
|
|
|
- `<a href='${v}' target='_blank' ><img class='photo-answer' src='${v +
|
|
|
- "!/both/200x200"}' /></a>`
|
|
|
- );
|
|
|
- const ele = document.createElement("div");
|
|
|
- ele.innerHTML = this.studentAnswer || "";
|
|
|
- const pEle = ele.querySelectorAll(".photo-answers-block");
|
|
|
- if (pEle) [...pEle].forEach(v => v.remove());
|
|
|
- // console.log(ele.innerHTML);
|
|
|
-
|
|
|
- if (!ele.innerHTML && pSrcs.length === 0) {
|
|
|
- // 完全为空则重置答案
|
|
|
- this.studentAnswer = null;
|
|
|
- // 更新answerDiv的内容
|
|
|
- this.originalStudentAnswer = null;
|
|
|
- } else {
|
|
|
- this.studentAnswer =
|
|
|
- ele.innerHTML +
|
|
|
- `<div class='photo-answers-block'>${imageStr.join("")}</div>`;
|
|
|
- // 更新answerDiv的内容
|
|
|
- this.originalStudentAnswer = this.studentAnswer;
|
|
|
- }
|
|
|
- },
|
|
|
- },
|
|
|
- },
|
|
|
- components: {
|
|
|
- QuestionBody,
|
|
|
- UploadPhotos,
|
|
|
- qrcode: VueQrcode,
|
|
|
- },
|
|
|
};
|
|
|
</script>
|
|
|
|