Browse Source

看图说话

natasha 1 year ago
parent
commit
e8549277a0

+ 3 - 3
src/views/exercise_questions/create/components/create.vue

@@ -50,7 +50,7 @@ import ReadAloudQuestion from './exercises/ReadAloudQuestion.vue';
 import ChineseQuestion from './exercises/ChineseQuestion.vue';
 import WriteQuestion from './exercises/WriteQuestion.vue';
 import DialogueQuestion from './exercises/DialogueQuestion.vue';
-import TalkPicture from './exercises/TalkPicture.vue';
+import TalkPictureQuestion from './exercises/TalkPictureQuestion.vue';
 import ChooseToneQuestion from './exercises/ChooseToneQuestion.vue';
 import RepeatQuestion from './exercises/RepeatQuestion.vue';
 import ReadQuestion from './exercises/ReadQuestion.vue';
@@ -68,7 +68,7 @@ export default {
     ChineseQuestion,
     WriteQuestion,
     DialogueQuestion,
-    TalkPicture,
+    TalkPictureQuestion,
     ChooseToneQuestion,
     RepeatQuestion,
     ReadQuestion,
@@ -104,7 +104,7 @@ export default {
         chinese: ChineseQuestion,
         write: WriteQuestion,
         dialogue: DialogueQuestion,
-        talk_picture: TalkPicture,
+        talk_picture: TalkPictureQuestion,
         choose_tone: ChooseToneQuestion,
         repeat: RepeatQuestion,
         read: ReadQuestion,

+ 0 - 164
src/views/exercise_questions/create/components/exercises/TalkPicture.vue

@@ -1,164 +0,0 @@
-<template>
-  <QuestionBase>
-    <template #content>
-      <div class="stem">
-        <el-input
-          v-if="data.property.stem_type === stemTypeList[0].value"
-          v-model="data.stem"
-          rows="3"
-          resize="none"
-          type="textarea"
-          placeholder="输入题干"
-        />
-
-        <RichText v-if="data.property.stem_type === stemTypeList[1].value" v-model="data.stem" placeholder="输入题干" />
-
-        <el-input
-          v-show="isEnable(data.property.is_enable_description)"
-          v-model="data.description"
-          rows="3"
-          resize="none"
-          type="textarea"
-          placeholder="输入描述"
-        />
-      </div>
-
-      <div class="content">
-        <el-upload ref="upload" action="no" accept="image/*" drag :show-file-list="false">
-          <div>点击或拖拽图片到此上传</div>
-          <div>只有 jpg, png, gif 等格式文件可以上传,文件大小不得超过 5MB</div>
-        </el-upload>
-      </div>
-
-      <div v-if="data.property.is_enable_reference_answer" class="reference-answer">
-        <span class="subtitle">参考答案:</span>
-        <el-input v-model="data.reference_answer" type="textarea" rows="3" placeholder="输入参考答案" />
-      </div>
-    </template>
-
-    <template #property>
-      <el-form :model="data.property">
-        <el-form-item label="题干">
-          <el-radio
-            v-for="{ value, label } in stemTypeList"
-            :key="value"
-            v-model="data.property.stem_type"
-            :label="value"
-          >
-            {{ label }}
-          </el-radio>
-        </el-form-item>
-        <el-form-item label="题号">
-          <el-input v-model="data.property.question_number" />
-        </el-form-item>
-        <el-form-item label-width="45px">
-          <el-radio
-            v-for="{ value, label } in questionNumberTypeList"
-            :key="value"
-            v-model="data.other.question_number_type"
-            :label="value"
-          >
-            {{ label }}
-          </el-radio>
-        </el-form-item>
-        <el-form-item label="描述">
-          <el-radio
-            v-for="{ value, label } in switchOption"
-            :key="value"
-            v-model="data.property.is_enable_description"
-            :label="value"
-          >
-            {{ label }}
-          </el-radio>
-        </el-form-item>
-        <el-form-item label="分值">
-          <el-radio
-            v-for="{ value, label } in scoreTypeList"
-            :key="value"
-            v-model="data.property.score_type"
-            :label="value"
-          >
-            {{ label }}
-          </el-radio>
-        </el-form-item>
-        <el-form-item label-width="45px">
-          <el-input v-model="data.property.score" type="number" />
-        </el-form-item>
-        <el-form-item label="语音作答">
-          <el-radio
-            v-for="{ value, label } in switchOption"
-            :key="value"
-            v-model="data.property.is_enable_voice_answer"
-            :label="value"
-          >
-            {{ label }}
-          </el-radio>
-        </el-form-item>
-        <el-form-item label="参考答案">
-          <el-radio
-            v-for="{ value, label } in switchOption"
-            :key="value"
-            v-model="data.property.is_enable_reference_answer"
-            :label="value"
-          >
-            {{ label }}
-          </el-radio>
-        </el-form-item>
-      </el-form>
-    </template>
-  </QuestionBase>
-</template>
-
-<script>
-import QuestionMixin from '../common/QuestionMixin.js';
-
-import { talkPictrueData } from '@/views/exercise_questions/data/talkPicture';
-
-export default {
-  name: 'TalkPicture',
-  mixins: [QuestionMixin],
-  data() {
-    return {
-      data: JSON.parse(JSON.stringify(talkPictrueData)),
-    };
-  },
-  methods: {},
-};
-</script>
-
-<style lang="scss" scoped>
-.content {
-  :deep .el-upload {
-    width: 100%;
-
-    &-dragger {
-      display: flex;
-      flex-direction: column;
-      align-items: center;
-      justify-content: center;
-      width: 100%;
-      height: 90px;
-      font-size: 14px;
-
-      :first-child {
-        color: #000;
-      }
-
-      :last-child {
-        color: $text-color;
-      }
-    }
-  }
-}
-
-.reference-answer {
-  display: flex;
-  flex-direction: column;
-  row-gap: 8px;
-  margin-top: 8px;
-
-  .subtitle {
-    font-size: 14px;
-  }
-}
-</style>

+ 273 - 0
src/views/exercise_questions/create/components/exercises/TalkPictureQuestion.vue

@@ -0,0 +1,273 @@
+<template>
+  <QuestionBase>
+    <template #content>
+      <div class="stem">
+        <el-input
+          v-if="data.property.stem_type === stemTypeList[0].value"
+          v-model="data.stem"
+          rows="3"
+          resize="none"
+          type="textarea"
+          placeholder="输入题干"
+        />
+
+        <RichText v-if="data.property.stem_type === stemTypeList[1].value" v-model="data.stem" placeholder="输入题干" />
+
+        <el-input
+          v-show="isEnable(data.property.is_enable_description)"
+          v-model="data.description"
+          rows="3"
+          resize="none"
+          type="textarea"
+          placeholder="输入描述"
+        />
+      </div>
+
+      <div class="content">
+        <div v-for="(item, index) in data.option_list" :key="index" class="content-item">
+          <template v-if="pic_list[item.picture_file_id]">
+            <div class="item-left">
+              <el-image
+                style="width: 72px; height: 72px"
+                :src="pic_list[item.picture_file_id]"
+                :preview-src-list="[pic_list[item.picture_file_id]]"
+                fit="contain"
+              />
+              <el-button type="danger" plain @click="delectOption(index, item.picture_file_id)"
+                ><i class="el-icon-delete"></i>删除</el-button
+              >
+            </div>
+            <div class="item-right">
+              <div class="item-rich">
+                <label class="">图片标题</label>
+                <RichText v-model="item.picture_title" placeholder="输入图片标题" />
+              </div>
+              <div class="item-rich">
+                <label class="">图片信息</label>
+                <RichText v-model="item.picture_info" placeholder="输入图片信息" />
+              </div>
+              <div v-if="isEnable(data.property.is_enable_reference_answer)" class="item-rich">
+                <label class="">参考答案</label>
+                <RichText v-model="item.reference_answer" placeholder="输入参考答案" />
+              </div>
+            </div>
+          </template>
+        </div>
+        <el-upload
+          ref="upload"
+          action="no"
+          accept=".jpg,.png,.gif"
+          drag
+          :show-file-list="false"
+          :before-upload="beforeUpload"
+          :http-request="upload"
+          :on-exceed="handleExceed"
+        >
+          <div>点击或拖拽图片到此上传</div>
+          <div>只有 jpg, png, gif 等格式文件可以上传,文件大小不得超过 5MB</div>
+        </el-upload>
+      </div>
+    </template>
+
+    <template #property>
+      <el-form :model="data.property">
+        <el-form-item label="题干">
+          <el-radio
+            v-for="{ value, label } in stemTypeList"
+            :key="value"
+            v-model="data.property.stem_type"
+            :label="value"
+          >
+            {{ label }}
+          </el-radio>
+        </el-form-item>
+        <el-form-item label="题号">
+          <el-input v-model="data.property.question_number" />
+        </el-form-item>
+        <el-form-item label-width="45px">
+          <el-radio
+            v-for="{ value, label } in questionNumberTypeList"
+            :key="value"
+            v-model="data.other.question_number_type"
+            :label="value"
+          >
+            {{ label }}
+          </el-radio>
+        </el-form-item>
+        <el-form-item label="描述">
+          <el-radio
+            v-for="{ value, label } in switchOption"
+            :key="value"
+            v-model="data.property.is_enable_description"
+            :label="value"
+          >
+            {{ label }}
+          </el-radio>
+        </el-form-item>
+        <el-form-item label="分值">
+          <el-radio
+            v-for="{ value, label } in scoreTypeList"
+            :key="value"
+            v-model="data.property.score_type"
+            :label="value"
+          >
+            {{ label }}
+          </el-radio>
+        </el-form-item>
+        <el-form-item label-width="45px">
+          <el-input v-model="data.property.score" type="number" />
+        </el-form-item>
+        <el-form-item label="语音作答">
+          <el-radio
+            v-for="{ value, label } in switchOption"
+            :key="value"
+            v-model="data.property.is_enable_voice_answer"
+            :label="value"
+          >
+            {{ label }}
+          </el-radio>
+        </el-form-item>
+        <el-form-item label="参考答案">
+          <el-radio
+            v-for="{ value, label } in switchOption"
+            :key="value"
+            v-model="data.property.is_enable_reference_answer"
+            :label="value"
+          >
+            {{ label }}
+          </el-radio>
+        </el-form-item>
+      </el-form>
+    </template>
+  </QuestionBase>
+</template>
+
+<script>
+import QuestionMixin from '../common/QuestionMixin.js';
+
+import { talkPictrueData, getOption } from '@/views/exercise_questions/data/talkPicture';
+import { fileUpload, GetFileStoreInfo } from '@/api/app';
+
+export default {
+  name: 'TalkPicture',
+  mixins: [QuestionMixin],
+  data() {
+    return {
+      data: JSON.parse(JSON.stringify(talkPictrueData)),
+      pic_list: {},
+      is_first: true,
+    };
+  },
+  watch: {
+    'data.file_id_list': {
+      handler() {
+        if (this.is_first) {
+          this.handleData();
+        }
+      },
+      deep: true,
+    },
+  },
+  created() {},
+  mounted() {},
+  methods: {
+    // 初始化数据
+    handleData() {
+      this.data.file_id_list.forEach((item) => {
+        GetFileStoreInfo({ file_id: item }).then(({ file_id, file_url }) => {
+          this.$set(this.pic_list, file_id, file_url);
+        });
+      });
+      this.is_first = false;
+    },
+    // 删除
+    delectOption(i, id) {
+      this.$confirm('是否删除该条全部信息?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      })
+        .then(() => {
+          delete this.pic_list[id];
+          this.data.file_id_list.splice(this.data.file_id_list.indexOf(id), 1);
+          this.data.option_list.splice(i, 1);
+          console.log(this.data);
+        })
+        .catch(() => {});
+    },
+    beforeUpload(file) {
+      // 可以用来限制文件大小
+    },
+    upload(file) {
+      fileUpload('Mid', file).then(({ file_info_list }) => {
+        if (file_info_list.length > 0) {
+          const { file_id, file_url } = file_info_list[0];
+          this.data.file_id_list.push(file_id);
+          this.data.option_list.push(getOption());
+          this.data.option_list[this.data.option_list.length - 1].picture_file_id = file_id;
+          this.$set(this.pic_list, file_id, file_url);
+        }
+      });
+    },
+    handleExceed(files, fileList) {
+      this.$message.warning(
+        `当前限制选择 ${this.filleNumber ? this.filleNumber : 1} 个文件,本次选择了 ${files.length} 个文件,共选择了 ${
+          files.length + fileList.length
+        } 个文件`,
+      );
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.content {
+  :deep .el-upload {
+    width: 100%;
+
+    &-dragger {
+      display: flex;
+      flex-direction: column;
+      align-items: center;
+      justify-content: center;
+      width: 100%;
+      height: 90px;
+      font-size: 14px;
+
+      :first-child {
+        color: #000;
+      }
+
+      :last-child {
+        color: $text-color;
+      }
+    }
+  }
+
+  .content-item {
+    display: flex;
+    column-gap: 8px;
+    margin-bottom: 24px;
+  }
+
+  .item-left {
+    width: 72px;
+  }
+
+  .item-right {
+    flex: 1;
+
+    .item-rich {
+      display: flex;
+
+      > label {
+        flex-shrink: 0;
+        width: 64px;
+        font-size: 14px;
+        line-height: 32px;
+        color: #4e5969;
+      }
+    }
+  }
+}
+</style>

+ 10 - 7
src/views/exercise_questions/data/talkPicture.js

@@ -1,21 +1,24 @@
-import { stemTypeList, scoreTypeList, questionNumberTypeList } from './common';
-
+import { stemTypeList, scoreTypeList, questionNumberTypeList, switchOption } from './common';
+import { getRandomNumber } from '@/utils/index';
+export function getOption() {
+  return { picture_title: '', picture_info: '', reference_answer: '', picture_file_id: '', mark: getRandomNumber() };
+}
 // 看图说话数据模板
 export const talkPictrueData = {
   type: 'talk_picture', // 题型
   stem: '', // 题干
-  reference_answer: '', // 参考答案
   description: '', // 描述
-  option_list: '', // 选项
+  option_list: [], // 选项
+  file_id_list: [],
   answer: { score: 0, score_type: scoreTypeList[0].value }, // 答案
   // 题型属性
   property: {
     stem_type: stemTypeList[0].value, // 题干类型
     question_number: '1', // 题号
     score: 1, // 分值
-    is_enable_description: false, // 描述
-    is_enable_voice_answer: true, // 语音作答
-    is_enable_reference_answer: true, // 参考答案
+    is_enable_description: switchOption[1].value, // 描述
+    is_enable_voice_answer: switchOption[0].value, // 语音作答
+    is_enable_reference_answer: switchOption[0].value, // 参考答案
     score_type: scoreTypeList[0].value, // 分值类型
   },
   // 其他属性