dusenyao 1 éve
szülő
commit
db24e841af

+ 2 - 2
package.json

@@ -34,8 +34,8 @@
     "vuex": "^3.6.2"
   },
   "devDependencies": {
-    "@babel/core": "^7.24.6",
-    "@babel/eslint-parser": "^7.24.6",
+    "@babel/core": "^7.24.7",
+    "@babel/eslint-parser": "^7.24.7",
     "@electron/fuses": "^1.8.0",
     "@rushstack/eslint-patch": "^1.10.3",
     "@types/md5": "^2.3.5",

+ 0 - 0
src/icons/svg/components/upload.svg → src/icons/svg/components/uploadControl.svg


+ 1 - 1
src/views/book/courseware/data/bookType.js

@@ -111,7 +111,7 @@ export const bookTypeOption = [
       {
         value: 'upload_control',
         label: '上传',
-        icon: 'upload',
+        icon: 'uploadControl',
         component: UploadControl,
         set: UploadControlSetting,
         preview: UploadControlPreview,

+ 22 - 0
src/views/book/courseware/preview/components/common/PreviewMixin.js

@@ -8,6 +8,8 @@ const mixin = {
   data() {
     return {
       answer: { answer_list: [] }, // 答案
+      isJudgingRightWrong: false, // 是否判断对错
+      isShowRightAnswer: false, // 是否显示正确答案
       disabled: false, // 是否禁用
       isEnable,
     };
@@ -37,6 +39,26 @@ const mixin = {
       );
     },
     /**
+     * 获取答案
+     * @returns {array} 答案
+     */
+    getAnswer() {
+      return this.answer;
+    },
+    /**
+     * 显示答案
+     * @param {boolean} isJudgingRightWrong 是否判断对错
+     * @param {boolean} isShowRightAnswer 是否显示正确答案
+     * @param {object} userAnswer 用户答案
+     * @param {boolean} disabled 是否禁用
+     */
+    showAnswer(isJudgingRightWrong, isShowRightAnswer, userAnswer, disabled) {
+      this.isJudgingRightWrong = isJudgingRightWrong;
+      this.isShowRightAnswer = isShowRightAnswer;
+      this.disabled = disabled;
+      if (userAnswer) this.answer = userAnswer;
+    },
+    /**
      * 得到序号外部样式
      */
     getAreaStyle() {

+ 69 - 7
src/views/book/courseware/preview/components/matching/MatchingPreview.vue

@@ -19,6 +19,17 @@
           </div>
         </li>
       </ul>
+
+      <div v-if="isShowRightAnswer" class="right-answer">
+        <div class="title">正确答案</div>
+        <ul ref="answerList" class="option-list">
+          <li v-for="(item, i) in data.option_list" :key="i" class="list-item">
+            <div v-for="{ content, mark } in item" :key="mark" :class="['item-wrapper', `answer-item-${mark}`]">
+              <span class="content rich-text" v-html="sanitizeHTML(content)"></span>
+            </div>
+          </li>
+        </ul>
+      </div>
     </div>
   </div>
 </template>
@@ -58,6 +69,22 @@ export default {
       },
       immediate: true,
     },
+    isJudgingRightWrong(cur) {
+      if (cur) {
+        this.clearLine();
+        this.circulateAnswerList();
+      } else {
+        this.clearLine();
+      }
+    },
+    isShowRightAnswer(cur) {
+      if (cur) {
+        this.$nextTick(() => {
+          this.circulateAnswerList(true);
+          this.judgeRichTextIsImgAndText(true);
+        });
+      }
+    },
   },
   created() {
     document.addEventListener('click', this.handleEventConnection);
@@ -201,15 +228,42 @@ export default {
       this.createLine(mark);
     },
 
+    // 循环答案列表
+    circulateAnswerList(isShowRightAnswer = false) {
+      let answer_list = isShowRightAnswer ? this.data.answer.answer_list : this.answer.answer_list;
+      answer_list.forEach((item) => {
+        item.forEach((mark, j) => {
+          if (mark.length <= 0 || j >= item.length - 1) return;
+
+          let cur = { i: -1, j: -1 }; // 当前连线点
+          this.answerList.findIndex((item, i) => {
+            return item.some((li, j) => {
+              if (li.mark === mark) {
+                cur = { i, j };
+                return true;
+              }
+            });
+          });
+          this.curConnectionPoint = { i: cur.i, j: cur.j, mark };
+          this.createLine(item[j + 1], false, isShowRightAnswer);
+        });
+      });
+    },
+
     /**
      * 创建连接线
      * @param {String} mark 选项标识
      * @param {Boolean} isDrag 是否是拖拽
+     * @param {Boolean} isShowRightAnswer 是否是显示正确答案
      */
-    createLine(mark, isDrag = false) {
-      let { offsetWidth, offsetLeft, offsetTop, offsetHeight } = document.getElementsByClassName(`item-${mark}`)[0];
-      const { curOffsetWidth, curOffsetLeft, curOffsetTop, curOffsetHeight, curMark } =
-        this.computedCurConnectionPoint(isDrag);
+    createLine(mark, isDrag = false, isShowRightAnswer = false) {
+      const { offsetWidth, offsetLeft, offsetTop, offsetHeight } = document.getElementsByClassName(
+        `${isShowRightAnswer ? 'answer-' : ''}item-${mark}`,
+      )[0];
+      const { curOffsetWidth, curOffsetLeft, curOffsetTop, curOffsetHeight, curMark } = this.computedCurConnectionPoint(
+        isDrag,
+        isShowRightAnswer,
+      );
       let top = Math.min(offsetTop + offsetHeight / 2, curOffsetTop + curOffsetHeight / 2);
       // 判断是否是同一行
       const isSameRow = Math.abs(offsetTop + offsetHeight / 2 - (curOffsetTop + curOffsetHeight / 2)) <= 2;
@@ -239,7 +293,7 @@ export default {
       path.setAttribute('d', `M ${size ? 0 : width} 0 L ${size ? width : 0} ${height}`); // 设置路径数据
       this.setPathAttr(path);
       svg.appendChild(path);
-      this.$refs.list.appendChild(svg); // 将SVG元素插入到文档中
+      this.$refs[isShowRightAnswer ? 'answerList' : 'list'].appendChild(svg); // 将SVG元素插入到文档中
 
       // 清除当前连线点
       this.resetCurConnectionPoint();
@@ -254,10 +308,12 @@ export default {
     /**
      * 计算当前连线点的位置
      * @param {Boolean} isDrag 是否是拖拽
+     * @param {Boolean} isShowRightAnswer 是否是显示正确答案
      */
-    computedCurConnectionPoint(isDrag = false) {
+    computedCurConnectionPoint(isDrag = false, isShowRightAnswer = false) {
       const { mark } = isDrag ? this.mousePointer : this.curConnectionPoint;
-      let dom = document.getElementsByClassName(`item-${mark}`)[0];
+      const dom = document.getElementsByClassName(`${isShowRightAnswer ? 'answer-' : ''}item-${mark}`)[0];
+
       return {
         curOffsetWidth: dom.offsetWidth,
         curOffsetLeft: dom.offsetLeft,
@@ -383,5 +439,11 @@ export default {
       }
     }
   }
+
+  .right-answer {
+    .title {
+      margin-bottom: 24px;
+    }
+  }
 }
 </style>

+ 35 - 1
src/views/book/courseware/preview/components/select/SelectPreview.vue

@@ -57,7 +57,20 @@ export default {
       }
     },
     computedAnswerClass(mark) {
-      return this.isAnswer(mark) ? ['active'] : [];
+      if (!this.isJudgingRightWrong && !this.isShowRightAnswer) {
+        return [];
+      }
+      let isHas = this.answer.answer_list.includes(mark); // 是否已选中的选项
+      let isRight = this.data.answer.answer_list.includes(mark); // 是否是正确答案
+
+      if (!isHas && this.isShowRightAnswer) {
+        return isRight ? ['answer-right'] : [];
+      }
+      // 判断是否是正确答案
+      if (this.isJudgingRightWrong) {
+        return isRight ? ['right'] : ['wrong'];
+      }
+      return [];
     },
   },
 };
@@ -123,6 +136,27 @@ export default {
           }
         }
       }
+
+      &.answer-right {
+        background-color: #e8f7f2;
+
+        &::after {
+          font-size: 14px;
+          color: $right-color;
+          content: '正确答案';
+        }
+      }
+
+      &.wrong {
+        background-color: $content-color;
+        box-shadow: 0 0 0 1px $error-color;
+
+        &::after {
+          font-size: 14px;
+          color: #a09fa6;
+          content: '已选';
+        }
+      }
     }
   }
 }

+ 17 - 10
src/views/book/courseware/preview/components/voice_matrix/VoiceMatrixPreview.vue

@@ -50,7 +50,7 @@
               :key="`top-${i}`"
               :class="[
                 'matrix-top',
-                data.property.is_enable_column_play &&
+                isEnable(data.property.is_enable_column_play) &&
                 (selectColumn === i || (selectedLine.type === 'column' && selectedLine.index === i))
                   ? 'read'
                   : '',
@@ -58,7 +58,7 @@
               @mouseenter="checkboxMouseenter(selectColumn === i, 'column')"
             >
               <span
-                v-if="row.type !== 'connection' && data.property.is_enable_column_play"
+                v-if="row.type !== 'connection' && isEnable(data.property.is_enable_column_play)"
                 v-show="selectColumn === i || (selectedLine.type === 'column' && selectedLine.index === i)"
                 :class="[
                   `matrix-checkbox-row-${themeColor}`,
@@ -75,7 +75,7 @@
               :key="`start-${i}`"
               :class="[
                 'column-wrapper',
-                data.property.is_enable_row_play &&
+                isEnable(data.property.is_enable_row_play) &&
                 (selectRow === i || (selectedLine.type === 'row' && selectedLine.index === i))
                   ? 'read'
                   : '',
@@ -83,7 +83,7 @@
               @mouseenter="checkboxMouseenter(selectRow === i, 'row')"
             >
               <span
-                v-if="data.property.is_enable_row_play"
+                v-if="isEnable(data.property.is_enable_row_play)"
                 v-show="selectRow === i || (selectedLine.type === 'row' && selectedLine.index === i)"
                 :class="[
                   `matrix-checkbox-column-${themeColor}`,
@@ -98,10 +98,14 @@
                 :key="`wrapper-${i}-${j}`"
                 :class="[
                   'column-wrapper',
-                  (data.property.is_enable_row_play && selectRow === i) ||
-                  (data.property.is_enable_column_play && selectColumn === j) ||
-                  (data.property.is_enable_column_play && selectedLine.type === 'column' && selectedLine.index === j) ||
-                  (data.property.is_enable_row_play && selectedLine.type === 'row' && selectedLine.index === i)
+                  (isEnable(data.property.is_enable_row_play) && selectRow === i) ||
+                  (isEnable(data.property.is_enable_column_play) && selectColumn === j) ||
+                  (isEnable(data.property.is_enable_column_play) &&
+                    selectedLine.type === 'column' &&
+                    selectedLine.index === j) ||
+                  (isEnable(data.property.is_enable_row_play) &&
+                    selectedLine.type === 'row' &&
+                    selectedLine.index === i)
                     ? 'read'
                     : '',
                 ]"
@@ -134,7 +138,7 @@
             <div
               :key="`end-${i}`"
               :class="[
-                data.property.is_enable_row_play &&
+                isEnable(data.property.is_enable_row_play) &&
                 (selectRow === i || (selectedLine.type === 'row' && selectedLine.index === i))
                   ? 'read'
                   : '',
@@ -149,7 +153,7 @@
               :key="`bottom-${i}`"
               :class="[
                 'matrix-bottom',
-                data.property.is_enable_column_play &&
+                isEnable(data.property.is_enable_column_play) &&
                 (selectColumn === i || (selectedLine.type === 'column' && selectedLine.index === i))
                   ? 'read'
                   : '',
@@ -272,6 +276,9 @@ export default {
     hasSelectedCell() {
       this.handleParentPlay();
     },
+    isShowRightAnswer() {
+      this.handleWave(this.answer.record_list);
+    },
   },
   created() {
     Bus.$on('audioPause', (id) => {

+ 1 - 0
src/views/book/setting.vue

@@ -530,6 +530,7 @@ export default {
       .brief-introduction {
         font-size: 14px;
         color: #666;
+        word-break: break-all;
       }
     }