Explorar o código

Merge branch 'master' of http://60.205.254.193:3000/GCLS/GCLS_Page_Exercise

dusenyao hai 1 ano
pai
achega
a2e8262f7e

+ 36 - 3
src/views/exercise_questions/create/components/exercises/ChineseQuestion.vue

@@ -27,7 +27,18 @@
         <label class="title-little">题目:</label>
         <ul>
           <li v-for="(item, i) in data.option_list" :key="i" class="content-item">
-            <el-input v-model="item.content" maxlength="1" placeholder="输入一个汉字" />
+            <span
+              class="question-number"
+              @dblclick="changeOptionType(data)"
+              v-if="data.property.learn_type === 'dictation'"
+            >
+              {{ computedQuestionNumber(i, data.option_number_show_mode) }}.
+            </span>
+            <el-input
+              v-model="item.content"
+              :maxlength="data.property.learn_type === 'dictation' ? null : 1"
+              :placeholder="data.property.learn_type === 'dictation' ? '输入汉字或词汇' : '输入一个汉字'"
+            />
             <el-input v-model="item.pinyin" placeholder="输入拼音" />
             <UploadAudio
               v-if="data.other.audio_generation_method === 'upload'"
@@ -43,8 +54,16 @@
               <span class="auto-btn" @click="handleMatically(item)">自动生成</span>
             </div>
             <SoundRecord v-else :wav-blob.sync="item.audio_file_id" />
-            <el-input v-if="data.property.learn_type !== 'learn'" v-model="item.definition" placeholder="输入释义" />
-            <el-input v-if="data.property.learn_type !== 'learn'" v-model="item.collocation" placeholder="输入搭配" />
+            <el-input
+              v-if="data.property.learn_type !== 'dictation'"
+              v-model="item.definition"
+              placeholder="输入释义"
+            />
+            <el-input
+              v-if="data.property.learn_type !== 'dictation'"
+              v-model="item.collocation"
+              placeholder="输入搭配"
+            />
             <SvgIcon icon-class="delete" class="delete pointer" @click="deleteOption(i, item.audio_file_id)" />
           </li>
         </ul>
@@ -110,10 +129,14 @@
             :key="value"
             v-model="data.property.learn_type"
             :label="value"
+            @change="handleChangeType"
           >
             {{ label }}
           </el-radio>
         </el-form-item>
+        <el-form-item label="田字格数" v-if="data.property.learn_type !== 'dictation'">
+          <el-input v-model="data.property.tian_number" type="number" />
+        </el-form-item>
         <el-form-item label="音频">
           <el-radio
             v-for="{ value, label } in audioGenerationMethodList"
@@ -189,6 +212,16 @@ export default {
         });
       }
     },
+    // 改变类型
+    handleChangeType() {
+      if (this.data.property.learn_type !== 'dictation') {
+        this.data.option_list.forEach((item) => {
+          if (item.content.trim()) {
+            item.content = item.content.substring(0, 1);
+          }
+        });
+      }
+    },
   },
 };
 </script>

+ 4 - 2
src/views/exercise_questions/data/chinese.js

@@ -1,4 +1,4 @@
-import { stemTypeList, scoreTypeList, questionNumberTypeList } from './common';
+import { stemTypeList, scoreTypeList, questionNumberTypeList, optionTypeList } from './common';
 import { getRandomNumber } from '@/utils/index';
 
 export function getOption(content = '') {
@@ -15,7 +15,7 @@ export function getOption(content = '') {
 export const learnTypeList = [
   { value: 'paint', label: '描红' },
   { value: 'write', label: '书写' },
-  { value: 'learn', label: '笔画学习' },
+  { value: 'dictation', label: '听写' },
 ];
 
 // 音频生成方式类型
@@ -39,6 +39,7 @@ export const chineseData = {
   type: 'chinese', // 题型
   stem: '', // 题干
   description: '', // 描述
+  option_number_show_mode: optionTypeList[0].value, // 选项类型
   answer: { score: 0, score_type: scoreTypeList[0].value }, // 答案
   option_list: [getOption(), getOption(), getOption()], // 选项
   file_id_list: [],
@@ -50,6 +51,7 @@ export const chineseData = {
     score: 1, // 分值
     score_type: scoreTypeList[0].value, // 分值类型
     learn_type: learnTypeList[0].value,
+    tian_number: 8, // 田字格数
   },
   // 其他属性
   other: {

+ 191 - 57
src/views/exercise_questions/preview/ChinesePreview.vue

@@ -12,13 +12,10 @@
       <div v-for="(item, index) in data.option_list" :key="index" :class="['words-item']">
         <template v-if="item.content && item.content.trim() && item.strokes">
           <div
-            v-if="data.property.learn_type !== 'learn'"
+            v-if="data.property.learn_type !== 'dictation'"
             class="words-top"
             :style="{
-              width:
-                data.property.learn_type === 'paint'
-                  ? 64 * (writer_number + 6) + 'px'
-                  : 64 * (writer_number + 1) + 'px',
+              width: 64 * (writer_number + 1 > writer_number_yuan ? writer_number_yuan : writer_number + 1) + 'px',
             }"
           >
             <div class="words-left">
@@ -28,7 +25,7 @@
             <p class="words-right">{{ item.definition }}</p>
             <p class="words-right">{{ item.collocation }}</p>
           </div>
-          <template v-if="data.property.learn_type === 'paint'">
+          <div class="card-box" v-if="data.property.learn_type === 'paint'">
             <!-- 描红 -->
             <Strockplayredline
               :play-storkes="true"
@@ -38,16 +35,19 @@
               :class="['strock-chinese', 'border-right-none']"
             />
             <Strockred
-              v-for="itemI in 5"
+              v-for="itemI in writer_number"
               :key="itemI + data.property.learn_type"
               :book-text="item.content"
               :hanzi-color="hanzi_color"
               :reset="true"
               :target-div="'write-praT' + item.content + itemI + Math.random().toString(36).substring(2, 10)"
               :book-strokes="item.strokes"
-              :class="['strock-chinese', itemI !== 5 ? 'border-right-none' : '']"
+              :class="[
+                'strock-chinese',
+                (itemI + 1) % writer_number_yuan !== 0 && itemI !== writer_number ? 'border-right-none' : '',
+              ]"
             />
-            <div
+            <!-- <div
               v-for="(items, indexs) in item.imgArr"
               :key="indexs"
               :class="['strockplay-newWord border-left-none']"
@@ -60,9 +60,9 @@
                 :src="items.strokes_image_url"
                 alt=""
               />
-            </div>
-          </template>
-          <template v-else-if="data.property.learn_type === 'write'">
+            </div> -->
+          </div>
+          <div class="card-box" v-else-if="data.property.learn_type === 'write'">
             <!-- 书写 -->
             <Strockplayredline
               :play-storkes="true"
@@ -72,7 +72,10 @@
               :class="['strock-chinese']"
             />
             <div v-for="(items, indexs) in item.imgArr" :key="indexs" class="con-box">
-              <div :class="['strockplay-newWord border-left-none']" @click="freeWrite(items, index, indexs)">
+              <div
+                :class="['strockplay-newWord', (indexs + 1) % writer_number_yuan !== 0 ? 'border-left-none' : '']"
+                @click="freeWrite(items, index, indexs)"
+              >
                 <SvgIcon icon-class="hanzi-writer-bg" class="character-target-bg" />
                 <img
                   v-if="!play_status && items && items.strokes_image_url"
@@ -82,27 +85,35 @@
                 />
               </div>
             </div>
-          </template>
-          <template v-else>
-            <div class="words-info">
-              <AudioPlay :file-id="item.audio_file_id" theme-color="gray" />
-              <span class="pinyin">{{ item.pinyin }}</span>
-            </div>
-            <Strockplayredline
-              :play-storkes="true"
-              :book-text="item.content"
-              :target-div="'pre' + item.content + index"
-              :book-strokes="item.strokes"
-              class="strock-chinese"
-            />
-          </template>
+          </div>
         </template>
+        <div class="card-box" v-if="data.property.learn_type === 'dictation'">
+          <div class="words-info">
+            <span>{{ computeOptionMethods[data.option_number_show_mode](index) }}. </span>
+            <span class="pinyin">{{ item.pinyin }}</span>
+            <AudioPlay :file-id="item.audio_file_id" theme-color="white" />
+          </div>
+          <div class="words-dic-box">
+            <div class="words-dic-item" v-for="(itemc, indexc) in item.imgArr" :key="indexc">
+              <span class="pinyin">{{ item.pinyin_arr[indexc].pinyin_item }}</span>
+              <div :class="['strockplay-newWord']" @click="freeWrite(itemc, index, indexc)">
+                <SvgIcon icon-class="hanzi-writer-bg" class="character-target-bg" />
+                <img
+                  v-if="!play_status && itemc && itemc.strokes_image_url"
+                  class="hanzi-writer-img"
+                  :src="itemc.strokes_image_url"
+                  alt=""
+                />
+              </div>
+            </div>
+          </div>
+        </div>
       </div>
     </div>
     <div v-if="if_free_show" class="practiceBox practice-box-strock">
       <FreewriteLettle
         ref="freePaint"
-        :current-tree-i-d="'1234'"
+        :current-tree-i-d="'1234456'"
         :current-hz="current_hz"
         :curren-hz-data="current_hz_data"
         :row-index="active_index"
@@ -117,6 +128,7 @@
 </template>
 
 <script>
+import { computeOptionMethods } from '@/views/exercise_questions/data/common';
 import PreviewMixin from './components/PreviewMixin';
 import Strockplayredline from './components/common/Strockplayredline.vue';
 import Strockred from './components/common/Strockred.vue';
@@ -133,6 +145,7 @@ export default {
   mixins: [PreviewMixin],
   data() {
     return {
+      computeOptionMethods,
       hanzi_color: '#404040', // 描红汉字底色
       writer_number_yuan: 19,
       writer_number: null, // 书写个数
@@ -146,6 +159,45 @@ export default {
       current_hz: '', // 当前汉字
       current_hz_data: null, // 当前汉字数据
       play_status: false, // 播放状态
+      hz_data: [
+        '你',
+        '最',
+        '近',
+        '怎',
+        '么',
+        '样',
+        '我',
+        '很',
+        '好',
+        '再',
+        '见',
+        '吃',
+        '饭',
+        '天',
+        '启',
+        '扫',
+        '描',
+        '以',
+        '平',
+        '太',
+        '效',
+        '国',
+        '是',
+        '称',
+        '需',
+        '值',
+        '复',
+        '包',
+        '头',
+        '条',
+        '够',
+        '关',
+        '放',
+        '发',
+        '补',
+        '快',
+        '素',
+      ],
     };
   },
   watch: {
@@ -165,34 +217,53 @@ export default {
   methods: {
     // 初始化数据
     handleData() {
-      if (
-        document.getElementsByClassName('preview-content') &&
-        document.getElementsByClassName('preview-content')[0] &&
-        !this.writer_number
-      ) {
-        this.writer_number_yuan =
-          Math.floor((document.getElementsByClassName('preview-content')[0].clientWidth - 128) / 64) - 1;
-      }
-      if (this.data.property.learn_type === 'paint') {
-        this.writer_number = this.writer_number_yuan - 5;
-      } else {
-        this.writer_number = this.writer_number_yuan;
-      }
-      this.data.option_list.forEach((item) => {
-        if (item.content.trim()) {
-          let arr = [];
-          let MethodName = 'hz_resource_manager-GetHZStrokesContent';
-          let data = {
-            hz: item.content.trim(),
-          };
-          GetStaticResources(MethodName, data).then((res) => {
-            this.$set(item, 'strokes', res);
-          });
-          for (let i = 0; i < this.writer_number; i++) {
+      // if (
+      //   document.getElementsByClassName('preview-content') &&
+      //   document.getElementsByClassName('preview-content')[0] &&
+      //   !this.writer_number
+      // ) {
+      //   this.writer_number_yuan =
+      //     Math.floor((document.getElementsByClassName('preview-content')[0].clientWidth - 128) / 64) - 1;
+      // }
+      // if (this.data.property.learn_type === 'paint') {
+      //   this.writer_number = this.writer_number_yuan - 5;
+      // } else {
+      //   this.writer_number = this.writer_number_yuan;
+      // }
+      this.writer_number_yuan = Math.floor(
+        (document.getElementsByClassName('preview-content')[0].clientWidth - 128) / 64,
+      );
+      this.writer_number = this.data.property.tian_number ? this.data.property.tian_number * 1 : 8;
+      this.data.option_list.forEach((item, index) => {
+        let arr = [];
+        if (this.data.property.learn_type === 'dictation') {
+          item.pinyin_arr = [];
+          let pinyin_arr = item.pinyin.trim().split(' ');
+          pinyin_arr.forEach((itemp) => {
+            let obj = {
+              pinyin_item: itemp,
+            };
             arr.push(null);
-          }
+            item.pinyin_arr.push(obj);
+          });
           item.imgArr = arr;
-          this.answer_list.write_model[item.content] = arr;
+          this.answer_list.write_model[this.hz_data[index]] = arr;
+        } else {
+          if (item.content.trim()) {
+            let MethodName = 'hz_resource_manager-GetHZStrokesContent';
+            let data = {
+              hz: item.content.trim(),
+            };
+            GetStaticResources(MethodName, data).then((res) => {
+              this.$set(item, 'strokes', res);
+            });
+
+            for (let i = 0; i < this.writer_number; i++) {
+              arr.push(null);
+            }
+            item.imgArr = arr;
+            this.answer_list.write_model[item.content] = arr;
+          }
         }
       });
     },
@@ -209,7 +280,11 @@ export default {
       this.if_free_show = true;
       this.active_index = index;
       this.active_col_index = indexs;
-      this.current_hz = this.data.option_list[index].content;
+      if (this.data.property.learn_type === 'dictation') {
+        this.current_hz = this.hz_data[index];
+      } else {
+        this.current_hz = this.data.option_list[index].content;
+      }
       this.current_hz_data = imgUrl;
     },
     // 删除记录
@@ -254,7 +329,6 @@ export default {
       width: 100%;
       min-height: 30px;
       border: 1px solid #e81b1b;
-      border-bottom: none;
 
       .words-left {
         box-sizing: border-box;
@@ -301,7 +375,34 @@ export default {
       column-gap: 4px;
       align-items: center;
       justify-content: center;
-      margin-bottom: 9px;
+      width: max-content;
+      padding: 5px 16px;
+      margin: 0 auto 8px;
+      font-size: 14px;
+      line-height: 22px;
+      color: #fff;
+      background: #165dff;
+      border-radius: 20px;
+
+      .pinyin {
+        font-size: 14px;
+        color: #fff;
+      }
+
+      .audio-wrapper {
+        :deep .audio-play {
+          color: #fff;
+        }
+
+        :deep .audio-play.not-url {
+          color: #a1a1a1;
+        }
+      }
+    }
+
+    .card-box {
+      display: flex;
+      flex-wrap: wrap;
     }
 
     .pinyin {
@@ -313,6 +414,7 @@ export default {
 
     .strock-chinese {
       border: 1px solid #e81b1b;
+      border-top: none;
     }
 
     .strockplay-newWord {
@@ -322,6 +424,7 @@ export default {
       width: 64px;
       height: 64px;
       border: 1px solid #e81b1b;
+      border-top: none;
 
       .character-target-bg,
       .hanzi-writer-img {
@@ -356,6 +459,37 @@ export default {
     }
   }
 
+  .words-box-dictation {
+    display: flex;
+    flex-wrap: wrap;
+    column-gap: 24px;
+
+    .card-box {
+      display: block;
+    }
+
+    .words-dic-box {
+      display: flex;
+      column-gap: 6px;
+      width: max-content;
+      margin: 0 auto;
+    }
+
+    .words-dic-item {
+      text-align: center;
+
+      .pinyin {
+        line-height: 30px;
+      }
+    }
+  }
+
+  .words-dic-item {
+    .strockplay-newWord {
+      border-top: 1px solid #e81b1b;
+    }
+  }
+
   .practiceBox {
     position: fixed;
     top: 0;