Browse Source

表格增加勾叉选项

natasha 1 day ago
parent
commit
4b4464049f

+ 1 - 0
src/views/book/courseware/create/components/question/table/Table.vue

@@ -442,6 +442,7 @@ export default {
                 // .replace(/<span class="rich-fill".*?>(.*?)<\/span>|([_]{3,})/gi, '###$1$2###');
               });
           }
+          items.crossAnswer = 'normal';
           // text += `${items.content.replace(/<[^>]+>/g, '')}\n`;
           text += `${items.content}\n`;
         });

+ 257 - 190
src/views/book/courseware/preview/components/table/TablePreview.vue

@@ -51,158 +51,171 @@
                   height: data.property.height + 'px',
                 }"
               >
-                <div :style="[tdStyle, computedRichStyle(col.content)]" class="cell-wrap">
-                  <template v-if="isEnable(data.property.view_pinyin)">
-                    <div
-                      v-for="(item, index) in col.model_pinyin"
-                      :key="index"
-                      class="pinyin-text"
-                      :class="[index === 0 ? 'pinyin-text-left' : '']"
-                    >
-                      <template v-if="item.type === 'input'">
-                        <template v-if="data.property.fill_type === fillTypeList[0].value">
-                          <el-input
-                            :key="index"
-                            v-model="item.value"
-                            :disabled="disabled"
-                            :class="[...computedAnswerClass(item, i, j)]"
-                            :style="[{ width: Math.max(40, item.value.length * 21.3) + 'px' }]"
-                          />
-                        </template>
-                        <template v-else-if="data.property.fill_type === fillTypeList[1].value">
-                          <el-popover :key="index" placement="top" trigger="click">
-                            <div class="word-list">
-                              <span
-                                v-for="{ content, mark } in data.word_list"
-                                :key="mark"
-                                class="word-item"
-                                @click="handleSelectWord(content, mark, item)"
-                              >
-                                {{ convertText(content) }}
-                              </span>
-                            </div>
-
+                <div class="cell-wrap">
+                  <div class="cell-wrap-content" :style="[tdStyle, computedRichStyle(col.content)]">
+                    <template v-if="isEnable(data.property.view_pinyin)">
+                      <div
+                        v-for="(item, index) in col.model_pinyin"
+                        :key="index"
+                        class="pinyin-text"
+                        :class="[index === 0 ? 'pinyin-text-left' : '']"
+                      >
+                        <template v-if="item.type === 'input'">
+                          <template v-if="data.property.fill_type === fillTypeList[0].value">
                             <el-input
-                              slot="reference"
+                              :key="index"
                               v-model="item.value"
-                              :readonly="true"
+                              :disabled="disabled"
                               :class="[...computedAnswerClass(item, i, j)]"
                               :style="[{ width: Math.max(40, item.value.length * 21.3) + 'px' }]"
                             />
-                          </el-popover>
-                        </template>
+                          </template>
+                          <template v-else-if="data.property.fill_type === fillTypeList[1].value">
+                            <el-popover :key="index" placement="top" trigger="click">
+                              <div class="word-list">
+                                <span
+                                  v-for="{ content, mark } in data.word_list"
+                                  :key="mark"
+                                  class="word-item"
+                                  @click="handleSelectWord(content, mark, item)"
+                                >
+                                  {{ convertText(content) }}
+                                </span>
+                              </div>
 
-                        <template v-else-if="data.property.fill_type === fillTypeList[2].value">
-                          <span :key="j" class="write-click" @click="handleWriteClick(item)">
-                            <img
-                              v-show="item.write_base64"
-                              style="background-color: #f4f4f4"
-                              :src="item.write_base64"
-                              alt="write-show"
-                            />
-                          </span>
-                        </template>
+                              <el-input
+                                slot="reference"
+                                v-model="item.value"
+                                :readonly="true"
+                                :class="[...computedAnswerClass(item, i, j)]"
+                                :style="[{ width: Math.max(40, item.value.length * 21.3) + 'px' }]"
+                              />
+                            </el-popover>
+                          </template>
+
+                          <template v-else-if="data.property.fill_type === fillTypeList[2].value">
+                            <span :key="j" class="write-click" @click="handleWriteClick(item)">
+                              <img
+                                v-show="item.write_base64"
+                                style="background-color: #f4f4f4"
+                                :src="item.write_base64"
+                                alt="write-show"
+                              />
+                            </span>
+                          </template>
 
-                        <template v-else-if="data.property.fill_type === fillTypeList[3].value">
-                          <SoundRecordBox
-                            ref="record"
-                            :key="j"
-                            type="mini"
-                            :many-times="false"
-                            class="record-box"
-                            :answer-record-list="data.audio_answer_list"
-                            :task-model="isJudgingRightWrong ? 'ANSWER' : ''"
-                            :attrib="data.unified_attrib"
-                            @handleWav="handleMiniWav($event, item)"
-                          />
+                          <template v-else-if="data.property.fill_type === fillTypeList[3].value">
+                            <SoundRecordBox
+                              ref="record"
+                              :key="j"
+                              type="mini"
+                              :many-times="false"
+                              class="record-box"
+                              :answer-record-list="data.audio_answer_list"
+                              :task-model="isJudgingRightWrong ? 'ANSWER' : ''"
+                              :attrib="data.unified_attrib"
+                              @handleWav="handleMiniWav($event, item)"
+                            />
+                          </template>
+                          <span v-if="data.property.pinyin_position === 'bottom'" class="pinyin">&nbsp;</span>
                         </template>
-                        <span v-if="data.property.pinyin_position === 'bottom'" class="pinyin">&nbsp;</span>
-                      </template>
-                      <template v-else>
-                        <span v-if="data.property.pinyin_position === 'top'" class="pinyin">
-                          {{ item.pinyin.replace(/\s+/g, '') }}
-                        </span>
-                        <span :style="{ ...item.activeTextStyle }">
-                          {{ convertText(item.text) }}
-                        </span>
-                        <span v-if="data.property.pinyin_position === 'bottom'" class="pinyin">{{
-                          item.pinyin.replace(/\s+/g, '')
-                        }}</span>
-                      </template>
-                    </div>
-                  </template>
-                  <template v-else>
-                    <div v-for="(item, index) in col.model_essay" :key="index" :style="[tdStyle]">
-                      <span
-                        v-if="item.type === 'text'"
-                        :key="index"
-                        :style="{
-                          fontSize:
-                            data.unified_attrib && data.unified_attrib.font_size ? data.unified_attrib.font_size : '',
-                          fontFamily: data.unified_attrib && data.unified_attrib.font ? data.unified_attrib.font : '',
-                        }"
-                        v-html="convertText(sanitizeHTML(item.value))"
-                      ></span>
-                      <template v-if="item.type === 'input'">
-                        <template v-if="data.property.fill_type === fillTypeList[0].value">
-                          <el-input
-                            :key="index"
-                            v-model="item.value"
-                            :disabled="disabled"
-                            :class="[...computedAnswerClass(item, i, j)]"
-                            :style="[{ width: Math.max(40, item.value.length * 21.3) + 'px' }]"
-                          />
+                        <template v-else>
+                          <span v-if="data.property.pinyin_position === 'top'" class="pinyin">
+                            {{ item.pinyin.replace(/\s+/g, '') }}
+                          </span>
+                          <span :style="{ ...item.activeTextStyle }">
+                            {{ convertText(item.text) }}
+                          </span>
+                          <span v-if="data.property.pinyin_position === 'bottom'" class="pinyin">{{
+                            item.pinyin.replace(/\s+/g, '')
+                          }}</span>
                         </template>
-                        <template v-else-if="data.property.fill_type === fillTypeList[1].value">
-                          <el-popover :key="index" placement="top" trigger="click">
-                            <div class="word-list">
-                              <span
-                                v-for="{ content, mark } in data.word_list"
-                                :key="mark"
-                                class="word-item"
-                                @click="handleSelectWord(content, mark, item)"
-                              >
-                                {{ convertText(content) }}
-                              </span>
-                            </div>
-
+                      </div>
+                    </template>
+                    <template v-else>
+                      <div v-for="(item, index) in col.model_essay" :key="index" :style="[tdStyle]">
+                        <span
+                          v-if="item.type === 'text'"
+                          :key="index"
+                          :style="{
+                            fontSize:
+                              data.unified_attrib && data.unified_attrib.font_size ? data.unified_attrib.font_size : '',
+                            fontFamily: data.unified_attrib && data.unified_attrib.font ? data.unified_attrib.font : '',
+                          }"
+                          v-html="convertText(sanitizeHTML(item.value))"
+                        ></span>
+                        <template v-if="item.type === 'input'">
+                          <template v-if="data.property.fill_type === fillTypeList[0].value">
                             <el-input
-                              slot="reference"
+                              :key="index"
                               v-model="item.value"
-                              :readonly="true"
+                              :disabled="disabled"
                               :class="[...computedAnswerClass(item, i, j)]"
                               :style="[{ width: Math.max(40, item.value.length * 21.3) + 'px' }]"
                             />
-                          </el-popover>
-                        </template>
+                          </template>
+                          <template v-else-if="data.property.fill_type === fillTypeList[1].value">
+                            <el-popover :key="index" placement="top" trigger="click">
+                              <div class="word-list">
+                                <span
+                                  v-for="{ content, mark } in data.word_list"
+                                  :key="mark"
+                                  class="word-item"
+                                  @click="handleSelectWord(content, mark, item)"
+                                >
+                                  {{ convertText(content) }}
+                                </span>
+                              </div>
+
+                              <el-input
+                                slot="reference"
+                                v-model="item.value"
+                                :readonly="true"
+                                :class="[...computedAnswerClass(item, i, j)]"
+                                :style="[{ width: Math.max(40, item.value.length * 21.3) + 'px' }]"
+                              />
+                            </el-popover>
+                          </template>
 
-                        <template v-else-if="data.property.fill_type === fillTypeList[2].value">
-                          <span :key="j" class="write-click" @click="handleWriteClick(item)">
-                            <img
-                              v-show="item.write_base64"
-                              style="background-color: #f4f4f4"
-                              :src="item.write_base64"
-                              alt="write-show"
+                          <template v-else-if="data.property.fill_type === fillTypeList[2].value">
+                            <span :key="j" class="write-click" @click="handleWriteClick(item)">
+                              <img
+                                v-show="item.write_base64"
+                                style="background-color: #f4f4f4"
+                                :src="item.write_base64"
+                                alt="write-show"
+                              />
+                            </span>
+                          </template>
+
+                          <template v-else-if="data.property.fill_type === fillTypeList[3].value">
+                            <SoundRecordBox
+                              ref="record"
+                              :key="j"
+                              type="mini"
+                              :many-times="false"
+                              class="record-box"
+                              :answer-record-list="data.audio_answer_list"
+                              :task-model="isJudgingRightWrong ? 'ANSWER' : ''"
+                              :attrib="data.unified_attrib"
+                              @handleWav="handleMiniWav($event, item)"
                             />
-                          </span>
+                          </template>
                         </template>
+                      </div>
+                    </template>
+                  </div>
 
-                        <template v-else-if="data.property.fill_type === fillTypeList[3].value">
-                          <SoundRecordBox
-                            ref="record"
-                            :key="j"
-                            type="mini"
-                            :many-times="false"
-                            class="record-box"
-                            :answer-record-list="data.audio_answer_list"
-                            :task-model="isJudgingRightWrong ? 'ANSWER' : ''"
-                            :attrib="data.unified_attrib"
-                            @handleWav="handleMiniWav($event, item)"
-                          />
-                        </template>
-                      </template>
-                    </div>
-                  </template>
+                  <i
+                    v-if="col.cell.isCross"
+                    @click="toggle(col)"
+                    :class="[
+                      { 'el-icon-check': col.crossAnswer === statusList[1] },
+                      { 'el-icon-close': col.crossAnswer === statusList[2] },
+                      ...computedAnswerCrossClass(col, i, j),
+                    ]"
+                    :style="{ display: 'block', width: '18px', height: '18px', border: '1px solid #000' }"
+                  />
                 </div>
                 <span v-if="showLang" class="multilingual" :style="[tdStyle, computedRichStyle(col.content)]">
                   {{
@@ -284,16 +297,17 @@
                     height: data.property.height + 'px',
                   }"
                 >
-                  <div :style="[tdStyle, computedRichStyle(col.content)]" class="cell-wrap">
-                    <template v-if="isEnable(data.property.view_pinyin)">
-                      <div
-                        v-for="(item, index) in col.model_pinyin"
-                        :key="index"
-                        class="pinyin-text"
-                        :class="[index === 0 ? 'pinyin-text-left' : '']"
-                      >
-                        <template v-if="item.type === 'input'">
-                          <!-- <template v-if="data.property.fill_type === fillTypeList[0].value">
+                  <div class="cell-wrap">
+                    <div class="cell-wrap-content" :style="[tdStyle, computedRichStyle(col.content)]">
+                      <template v-if="isEnable(data.property.view_pinyin)">
+                        <div
+                          v-for="(item, index) in col.model_pinyin"
+                          :key="index"
+                          class="pinyin-text"
+                          :class="[index === 0 ? 'pinyin-text-left' : '']"
+                        >
+                          <template v-if="item.type === 'input'">
+                            <!-- <template v-if="data.property.fill_type === fillTypeList[0].value">
                             <el-input
                               :key="index"
                               v-model="item.value"
@@ -349,42 +363,45 @@
                               @handleWav="handleMiniWav($event, item)"
                             />
                           </template> -->
-                          <span v-if="data.property.pinyin_position === 'bottom'" class="pinyin">&nbsp;</span>
-                        </template>
-                        <template v-else>
-                          <span v-if="data.property.pinyin_position === 'top'" class="pinyin">
-                            {{ item.pinyin.replace(/\s+/g, '') }}
-                          </span>
-                          <span :style="{ ...item.activeTextStyle }">
-                            {{ convertText(item.text) }}
+                            <span v-if="data.property.pinyin_position === 'bottom'" class="pinyin">&nbsp;</span>
+                          </template>
+                          <template v-else>
+                            <span v-if="data.property.pinyin_position === 'top'" class="pinyin">
+                              {{ item.pinyin.replace(/\s+/g, '') }}
+                            </span>
+                            <span :style="{ ...item.activeTextStyle }">
+                              {{ convertText(item.text) }}
+                            </span>
+                            <span v-if="data.property.pinyin_position === 'bottom'" class="pinyin">{{
+                              item.pinyin.replace(/\s+/g, '')
+                            }}</span>
+                          </template>
+                          <span
+                            :key="`answer-${j}`"
+                            class="right-answer"
+                            v-show="computedAnswerText(item, i, j).length > 0"
+                          >
+                            {{ convertText(computedAnswerText(item, i, j)) }}
                           </span>
-                          <span v-if="data.property.pinyin_position === 'bottom'" class="pinyin">{{
-                            item.pinyin.replace(/\s+/g, '')
-                          }}</span>
-                        </template>
-                        <span
-                          :key="`answer-${j}`"
-                          class="right-answer"
-                          v-show="computedAnswerText(item, i, j).length > 0"
-                        >
-                          {{ convertText(computedAnswerText(item, i, j)) }}
-                        </span>
-                      </div>
-                    </template>
-                    <template v-else>
-                      <div v-for="(item, index) in col.model_essay" :key="index" :style="[tdStyle]">
-                        <span
-                          v-if="item.type === 'text'"
-                          :key="index"
-                          :style="{
-                            fontSize:
-                              data.unified_attrib && data.unified_attrib.font_size ? data.unified_attrib.font_size : '',
-                            fontFamily: data.unified_attrib && data.unified_attrib.font ? data.unified_attrib.font : '',
-                          }"
-                          v-html="convertText(sanitizeHTML(item.value))"
-                        ></span>
-                        <template v-if="item.type === 'input'">
-                          <!-- <template v-if="data.property.fill_type === fillTypeList[0].value">
+                        </div>
+                      </template>
+                      <template v-else>
+                        <div v-for="(item, index) in col.model_essay" :key="index" :style="[tdStyle]">
+                          <span
+                            v-if="item.type === 'text'"
+                            :key="index"
+                            :style="{
+                              fontSize:
+                                data.unified_attrib && data.unified_attrib.font_size
+                                  ? data.unified_attrib.font_size
+                                  : '',
+                              fontFamily:
+                                data.unified_attrib && data.unified_attrib.font ? data.unified_attrib.font : '',
+                            }"
+                            v-html="convertText(sanitizeHTML(item.value))"
+                          ></span>
+                          <template v-if="item.type === 'input'">
+                            <!-- <template v-if="data.property.fill_type === fillTypeList[0].value">
                             <el-input
                               :key="index"
                               v-model="item.value"
@@ -441,16 +458,25 @@
                             />
                           </template> -->
 
-                          <span
-                            :key="`answer-${j}`"
-                            class="right-answer"
-                            v-show="computedAnswerText(item, i, j).length > 0"
-                          >
-                            {{ convertText(computedAnswerText(item, i, j)) }}
-                          </span>
-                        </template>
-                      </div>
-                    </template>
+                            <span
+                              :key="`answer-${j}`"
+                              class="right-answer"
+                              v-show="computedAnswerText(item, i, j).length > 0"
+                            >
+                              {{ convertText(computedAnswerText(item, i, j)) }}
+                            </span>
+                          </template>
+                        </div>
+                      </template>
+                    </div>
+                    <i
+                      v-if="col.cell.isCross"
+                      :class="[
+                        { 'el-icon-check': data.answer_lists[i][j].crossAnswer === statusList[1] },
+                        { 'el-icon-close': data.answer_lists[i][j].crossAnswer === statusList[2] },
+                      ]"
+                      style="display: block; width: 18px; height: 18px; border: 1px solid #30a47d"
+                    />
                   </div>
                   <span v-if="showLang" class="multilingual" :style="[tdStyle, computedRichStyle(col.content)]">
                     {{
@@ -500,6 +526,7 @@ export default {
       writeVisible: false,
       writeMark: '',
       isHasInput: false,
+      statusList: ['normal', 'tick', 'cross'],
     };
   },
   computed: {
@@ -549,6 +576,10 @@ export default {
     this.handleData();
   },
   methods: {
+    toggle(status) {
+      const index = this.statusList.findIndex((item) => status.crossAnswer === item);
+      status.crossAnswer = index === this.statusList.length - 1 ? this.statusList[0] : this.statusList[index + 1];
+    },
     handleData() {
       this.table_width = 0;
       this.isHasInput = false;
@@ -617,6 +648,25 @@ export default {
       }
       return classList;
     },
+    computedAnswerCrossClass(item, i, j) {
+      if (!this.isJudgingRightWrong && !this.isShowRightAnswer) {
+        return '';
+      }
+      let answerOption =
+        this.data.answer_lists[i] && this.data.answer_lists[i][j] ? this.data.answer_lists[i][j].crossAnswer : '';
+      if (!item) return '';
+      let selectValue = item.crossAnswer;
+      let classList = [];
+      let isRight = answerOption === selectValue;
+      if (this.isJudgingRightWrong && answerOption) {
+        isRight ? classList.push('right') : classList.push('wrong');
+      }
+
+      if (this.isShowRightAnswer && !isRight) {
+        classList.push('show-right-answer');
+      }
+      return classList;
+    },
     /**
      * 处理小音频录音
      * @param {Object} data 音频数据
@@ -759,7 +809,16 @@ $border-color: #e6e6e6;
       display: flex;
       flex-flow: wrap;
       grid-area: fill;
-      align-items: end;
+
+      // align-items: end;
+      align-items: center; // 为了勾选框居中对齐
+      &-content {
+        display: flex;
+        flex: 1;
+        flex-flow: wrap;
+        grid-area: fill;
+        align-items: end;
+      }
 
       p {
         flex-grow: 1; // 为了常规模式时设置居中显示撑满整个单元格
@@ -833,6 +892,14 @@ $border-color: #e6e6e6;
         }
       }
 
+      .right {
+        border-color: $right-color !important;
+      }
+
+      .wrong {
+        border-color: $error-color !important;
+      }
+
       &-normal {
         p {
           width: 100%; // 为了解决换行问题