natasha 1 سال پیش
والد
کامیت
85ea00f97e

+ 3 - 0
src/icons/svg/first-tone.svg

@@ -0,0 +1,3 @@
+<svg width="14" height="4" viewBox="0 0 14 4" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M2 2H12" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/>
+</svg>

+ 3 - 0
src/icons/svg/fourth-tone.svg

@@ -0,0 +1,3 @@
+<svg width="12" height="8" viewBox="0 0 12 8" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M1.75977 1.35059L10.2402 6.64978" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/>
+</svg>

+ 3 - 0
src/icons/svg/second-tone.svg

@@ -0,0 +1,3 @@
+<svg width="12" height="8" viewBox="0 0 12 8" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M1.75977 6.64941L10.2402 1.35022" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/>
+</svg>

+ 3 - 0
src/icons/svg/third-tone.svg

@@ -0,0 +1,3 @@
+<svg width="14" height="8" viewBox="0 0 14 8" fill="none" xmlns="http://www.w3.org/2000/svg">
+<path d="M2 2L6.2948 5.86532C6.69013 6.22111 7.29479 6.20521 7.67087 5.82913L12 1.5" stroke="currentColor" stroke-width="2.5" stroke-linecap="round"/>
+</svg>

+ 410 - 5
src/views/book/courseware/preview/components/pinyin_base/PinyinBasePreview.vue

@@ -3,7 +3,90 @@
   <div class="pinyin-preview" :style="getAreaStyle()">
     <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
 
-    <div class="main">拼音预览开发中</div>
+    <div class="main">
+      <AudioFill v-if="data.audio_file_id" :file-id="data.audio_file_id" />
+      <div
+        class="option-content"
+        :class="[isJudgingRightWrong ? (con_preview[0].all_right ? 'all-right' : 'has-error') : '']"
+      >
+        <span v-if="data.content_hz" class="items-hz">{{ data.content_hz }}</span>
+        <template v-if="data.property.answer_mode === 'select'">
+          <span
+            v-for="(itemc, indexc) in con_preview[0].item_con"
+            :key="indexc"
+            :class="[
+              'item-con',
+              active_index_str === 0 + '-' + indexc ? 'active' : '',
+              isJudgingRightWrong && !con_preview[0].user_answer[indexc].is_right ? 'error' : '',
+            ]"
+            @click="
+              con_preview[0].item_active_index = indexc;
+              active_index_str = 0 + '-' + indexc;
+            "
+          >
+            {{ itemc }}
+          </span>
+        </template>
+        <template v-else>
+          <span v-for="(itemc, indexc) in con_preview[0].item_con" :key="indexc" class="items-box">
+            <span
+              v-for="(itemi, indexi) in itemc"
+              :key="indexi"
+              :class="[
+                'items-con',
+                active_index_str === 0 + '-' + indexc + '-' + indexi ? 'active' : '',
+                isJudgingRightWrong &&
+                !con_preview[0].user_answer[indexc].is_right &&
+                con_preview[0].user_answer[indexc].select_index_submit === indexi
+                  ? 'error'
+                  : '',
+                isJudgingRightWrong &&
+                !con_preview[0].user_answer[indexc].is_right &&
+                con_preview[0].user_answer[indexc].right_index === indexi
+                  ? 'right'
+                  : '',
+              ]"
+              @click="handleSelectItemTone(0, indexc, indexi, con_preview[0].item_con_yuan[indexc][indexi])"
+              >{{ itemi }}</span
+            >
+          </span>
+        </template>
+      </div>
+      <span
+        v-for="({ img, value }, j) in toneList"
+        :key="j"
+        :class="[
+          'tone',
+          data.property.answer_mode === 'select' &&
+          con_preview[0].user_answer[con_preview[0].item_active_index] &&
+          con_preview[0].user_answer[con_preview[0].item_active_index].select_tone === value
+            ? 'active'
+            : data.property.answer_mode === 'label' &&
+                con_preview[0].user_answer[con_preview[0].item_active_index] &&
+                con_preview[0].user_answer[con_preview[0].item_active_index].select_tone === value &&
+                con_preview[0].user_answer[con_preview[0].item_active_index].select_letter === active_letter &&
+                select_item_index === 0
+              ? 'active'
+              : '',
+          (isJudgingRightWrong &&
+            con_preview[0].user_answer[con_preview[0].item_active_index].right_answer === value &&
+            con_preview[0].user_answer[con_preview[0].item_active_index].select_index_submit !==
+              con_preview[0].user_answer[con_preview[0].item_active_index].right_answer &&
+            data.property.answer_mode === 'select') ||
+          (isJudgingRightWrong &&
+            data.property.answer_mode === 'label' &&
+            con_preview[0].user_answer[con_preview[0].item_active_index].right_answer === value &&
+            con_preview[0].user_answer[con_preview[0].item_active_index].right_index ===
+              con_preview[0].user_answer[con_preview[0].item_active_index].select_index &&
+            select_item_index === 0)
+            ? 'right'
+            : '',
+        ]"
+        @click="chooseTone(con_preview[0], value)"
+      >
+        <SvgIcon :icon-class="img" />
+      </span>
+    </div>
   </div>
 </template>
 
@@ -22,9 +105,18 @@ export default {
   },
   mixins: [PreviewMixin],
   watch: {
-    'data.content': {
+    data: {
       handler(val) {
-        console.log(this.data);
+        // if (!val || this.data.type !== 'choose_tone') return;
+        this.handleData();
+      },
+      deep: true,
+      immediate: true,
+    },
+    isJudgingRightWrong: {
+      handler(val) {
+        if (!val) return;
+        this.judgeRight();
       },
       immediate: true,
     },
@@ -34,12 +126,325 @@ export default {
       data: getPinyinBaseData(),
       arrangeTypeList,
       audioPositionList,
+      toneList: [
+        { value: '1', label: '一声', img: 'first-tone' },
+        { value: '2', label: '二声', img: 'second-tone' },
+        { value: '3', label: '三声', img: 'third-tone' },
+        { value: '4', label: '四声', img: 'fourth-tone' },
+        // { value: '0', label: '轻声', img: 'neutral-tone' },
+      ],
+      con_preview: [],
+      tone_data: [
+        ['ā', 'á', 'ǎ', 'à', 'a'],
+        ['ō', 'ó', 'ǒ', 'ò', 'o'],
+        ['ē', 'é', 'ě', 'è', 'e'],
+        ['ī', 'í', 'ǐ', 'ì', 'i'],
+        ['ū', 'ú', 'ǔ', 'ù', 'u'],
+        ['ǖ', 'ǘ', 'ǚ', 'ǜ', 'ü'],
+        ['ǖ', 'ǘ', 'ǚ', 'ǜ', 'ü'],
+        ['Ā', 'Á', 'Â', 'À', 'A'],
+        ['Ō', 'Ó', 'Ô', 'Ò', 'O'],
+        ['Ē', 'É', 'Ê', 'È', 'E'],
+        ['Ī', 'Í', 'Î', 'Ì', 'I'],
+        ['Ū', 'Ú', 'Û', 'Ù', 'U'],
+      ],
+      final_con: '',
+      active_index_str: '', // 高亮索引的字符串
+      active_letter: '', // 选中字母的值
+      active_letter_index: 0, // 选择字母索引
+      select_item_index: 0, // 小题索引
     };
   },
   created() {
-    console.log(this.data);
+    // console.log(this.data);
+  },
+  methods: {
+    chooseTone(item, value) {
+      if (this.disabled) return;
+      if (!this.active_letter && this.data.property.answer_mode === 'label') return;
+      if (
+        item.user_answer[item.item_active_index].select_tone &&
+        item.user_answer[item.item_active_index].select_tone === value &&
+        this.data.property.answer_mode === 'label' &&
+        item.user_answer[item.item_active_index].select_letter === this.active_letter
+      ) {
+        item.user_answer[item.item_active_index].select_tone = '';
+        this.handleReplaceTone(this.active_letter + 0);
+        setTimeout(() => {
+          let new_con = item.item_con_yuan[item.item_active_index].split(this.active_letter);
+          item.item_con[item.item_active_index] = new_con[0] + this.final_con + new_con[1];
+          this.$forceUpdate();
+          this.answer.answer_list[0].value[item.item_active_index] = new_con[0] + this.active_letter + new_con[1];
+        }, 100);
+      } else if (
+        item.user_answer[item.item_active_index].select_tone &&
+        item.user_answer[item.item_active_index].select_tone === value &&
+        this.data.property.answer_mode === 'select'
+      ) {
+        item.user_answer[item.item_active_index].select_tone = '';
+        this.handleReplaceTone(item.item_con_yuan[item.item_active_index] + 0);
+        setTimeout(() => {
+          item.item_con[item.item_active_index] = this.final_con;
+          this.$forceUpdate();
+        }, 100);
+        this.answer.answer_list[0].value[item.item_active_index] = '';
+      } else {
+        item.user_answer[item.item_active_index].select_tone = value;
+        if (this.data.property.answer_mode === 'label') {
+          item.user_answer[item.item_active_index].select_letter = this.active_letter;
+          this.active_index_str = `${0}-${item.item_active_index}-${this.active_letter_index}`;
+          this.handleReplaceTone(this.active_letter + value);
+          setTimeout(() => {
+            let new_con = item.item_con_yuan[item.item_active_index].split(this.active_letter);
+            item.item_con[item.item_active_index] = new_con[0] + this.final_con + new_con[1];
+            this.$forceUpdate();
+            this.answer.answer_list[0].value[item.item_active_index] =
+              new_con[0] + this.active_letter + value + new_con[1];
+          }, 100);
+        } else {
+          this.active_index_str = `${0}-${item.item_active_index}`;
+          this.handleReplaceTone(item.item_con_yuan[item.item_active_index] + value);
+          setTimeout(() => {
+            item.item_con[item.item_active_index] = this.final_con;
+            this.$forceUpdate();
+          }, 100);
+          this.answer.answer_list[0].value[item.item_active_index] = value;
+        }
+      }
+    },
+    // 处理数据
+    handleData() {
+      this.con_preview = [];
+      this.show_preview = false;
+      if (!this.isJudgingRightWrong) {
+        this.answer.answer_list = [];
+      }
+      // this.data.option_list.forEach((item) => {
+      let con_arr = JSON.parse(JSON.stringify(this.data.content_view));
+      let user_answer = [];
+      let user_submit = []; // 用户提交答案
+      con_arr.forEach((items) => {
+        user_answer.push({
+          select_tone: null,
+          select_letter: '',
+          select_index: '',
+        });
+        user_submit.push(this.data.property.answer_mode === 'label' ? items : '');
+      });
+      let obj = {
+        item_con: con_arr,
+        item_con_yuan: JSON.parse(JSON.stringify(con_arr)),
+        mark: this.data.mark,
+        user_answer,
+        item_active_index: 0,
+        active_letter: '',
+      };
+      if (!this.isJudgingRightWrong) {
+        let obj = {
+          mark: this.data.mark,
+          value: user_submit,
+        };
+        this.answer.answer_list.push(obj);
+      }
+      this.con_preview.push(obj);
+      // });
+      this.show_preview = true;
+    },
+    handleReplaceTone(e, arr, index, resArr) {
+      this.$nextTick(() => {
+        let value = e;
+        this.resArr = [];
+        if (value) {
+          let reg = /\s+/g;
+          let valueArr = value.split(reg);
+          valueArr.forEach((item) => {
+            this.handleValue(item, resArr);
+          });
+          let str = '';
+          setTimeout(() => {
+            if (resArr) {
+              resArr.forEach((item) => {
+                str += ' ';
+                item.forEach((sItem) => {
+                  if (sItem.number && sItem.con) {
+                    let number = Number(sItem.number);
+                    let con = sItem.con;
+                    let word = this.addTone(number, con);
+                    str += word;
+                  } else if (sItem.number) {
+                    str += sItem.number;
+                  } else if (sItem.con) {
+                    str += ` ${sItem.con} `;
+                  }
+                });
+              });
+              if (this.data.property.answer_mode === 'label') {
+                let number_index = e.search(/0|1|2|3|4/) + 1;
+                arr[index] = str.trim() + (number_index === 0 ? '' : e.substring(number_index));
+              } else {
+                arr[index] = str.trim();
+              }
+            } else {
+              this.resArr.forEach((item) => {
+                str += ' ';
+                item.forEach((sItem) => {
+                  if (sItem.number && sItem.con) {
+                    let number = Number(sItem.number);
+                    let con = sItem.con;
+                    let word = this.addTone(number, con);
+                    str += word;
+                  } else if (sItem.number) {
+                    str += sItem.number;
+                  } else if (sItem.con) {
+                    str += ` ${sItem.con} `;
+                  }
+                });
+              });
+              this.final_con = str.trim();
+            }
+          }, 10);
+        }
+      });
+    },
+    handleValue(valItem, resArr) {
+      let reg = /\d/;
+      let reg2 = /[A-Za-zü]+\d/g;
+      let numList = [];
+      let valArr = valItem.split('');
+      if (reg2.test(valItem)) {
+        for (let i = 0; i < valArr.length; i++) {
+          let item = valItem[i];
+          if (reg.test(item)) {
+            let numIndex = numList.length === 0 ? 0 : numList[numList.length - 1].index;
+            let con = valItem.substring(numIndex, i);
+            con = con.replace(/\d/g, '');
+            let obj = {
+              index: i,
+              number: item,
+              con,
+              isTran: true,
+            };
+            numList.push(obj);
+          }
+        }
+      } else {
+        numList = [];
+      }
+      if (resArr) {
+        if (numList.length === 0) {
+          resArr.push([{ con: valItem }]);
+        } else {
+          resArr.push(numList);
+        }
+      } else if (numList.length === 0) {
+        this.resArr.push([{ con: valItem }]);
+      } else {
+        this.resArr.push(numList);
+      }
+    },
+    addTone(number, con) {
+      let zmList = ['a', 'o', 'e', 'i', 'u', 'v', 'ü', 'A', 'O', 'E', 'I', 'U'];
+      let cons = con;
+      if (number) {
+        for (let i = 0; i < zmList.length; i++) {
+          let zm = zmList[i];
+          if (con.indexOf(zm) > -1) {
+            let zm2 = this.tone_data[i][number - 1];
+            if (con.indexOf('iu') > -1) {
+              zm2 = this.tone_data[4][number - 1];
+              cons = con.replace('u', zm2);
+            } else if (con.indexOf('ui') > -1) {
+              zm2 = this.tone_data[3][number - 1];
+              cons = con.replace('i', zm2);
+            } else if (
+              con.indexOf('yv') > -1 ||
+              con.indexOf('jv') > -1 ||
+              con.indexOf('qv') > -1 ||
+              con.indexOf('xv') > -1
+            ) {
+              zm2 = this.tone_data[4][number - 1];
+              cons = con.replace('v', zm2);
+            } else {
+              cons = con.replace(zm, zm2);
+            }
+
+            break;
+          }
+        }
+      }
+      return cons;
+    },
+    handleSelectItemTone(i, indexc, indexi, itemi) {
+      this.con_preview[0].item_active_index = indexc;
+      this.con_preview[0].user_answer[indexc].select_index = indexi;
+      this.active_index_str = `${i}-${indexc}-${indexi}`;
+      this.active_letter = itemi;
+      this.active_letter_index = indexi;
+      this.select_item_index = i;
+    },
+    // 判断对错
+    judgeRight() {
+      this.con_preview = [];
+      this.show_preview = false;
+      // this.data.option_list.forEach((item, index) => {
+      let con_arr = JSON.parse(JSON.stringify(this.data.content_view));
+      let user_answer = [];
+      let user_select = [];
+      let user_res_arr = [];
+
+      let answer_list_item = this.answer.answer_list.filter((items) => this.data.mark === items.mark);
+      con_arr.forEach((items, indexs) => {
+        user_answer.push({
+          select_tone: answer_list_item[0].value[indexs],
+          select_letter: '',
+          select_index: '',
+          is_right: answer_list_item[0].value[indexs] === this.data.answer.answer_list[0].value[indexs],
+          right_answer: this.data.answer.answer_list[0].value[indexs],
+        });
+        user_res_arr.push([]);
+        user_select.push('');
+        if (this.data.property.answer_mode === 'label') {
+          this.handleReplaceTone(answer_list_item[0].value[indexs], user_select, indexs, user_res_arr[indexs]);
+          if (
+            answer_list_item[0].value[indexs].match(/\d+/g) &&
+            answer_list_item[0].value[indexs].match(/\d+/g).length > 0
+          ) {
+            user_answer[indexs].select_tone = answer_list_item[0].value[indexs].match(/\d+/g)[0];
+            let letter_number = answer_list_item[0].value[indexs].match(/\d+/g)[0];
+            let letter_index = answer_list_item[0].value[indexs].indexOf(letter_number) - 1;
+            user_answer[indexs].select_letter = answer_list_item[0].value[indexs].substring(
+              letter_index,
+              letter_index + 1,
+            );
+            user_answer[indexs].select_index_submit = letter_index;
+          } else {
+            user_select[indexs] = items;
+          }
+          user_answer[indexs].right_answer = this.data.answer.answer_list[0].value[indexs].match(/0|1|2|3|4/)
+            ? this.data.answer.answer_list[index].value[indexs].match(/0|1|2|3|4/)[0]
+            : '';
+          user_answer[indexs].right_index = this.data.answer.answer_list[0].value[indexs].search(/0|1|2|3|4/) - 1;
+        } else {
+          this.handleReplaceTone(items + answer_list_item[0].value[indexs], user_select, indexs, user_res_arr[indexs]);
+        }
+      });
+      let obj = {
+        item_con: user_select,
+        item_con_yuan: JSON.parse(JSON.stringify(con_arr)),
+        mark: this.data.mark,
+        user_answer,
+        item_active_index: 0,
+        active_letter: '',
+        user_res_arr,
+        all_right: JSON.stringify(answer_list_item[0].value) === JSON.stringify(this.data.answer.answer_list[0].value),
+      };
+      this.con_preview.push(obj);
+      // });
+      setTimeout(() => {
+        this.show_preview = true;
+      }, 100);
+    },
   },
-  methods: {},
 };
 </script>