소스 검색

富文本媒体插件 自定义上传文件逻辑

dusenyao 1 년 전
부모
커밋
692638c2a2

+ 34 - 20
src/components/common/RichText.vue

@@ -12,7 +12,7 @@
 </template>
 
 <script>
-import tinymce from 'tinymce/tinymce';
+import 'tinymce/tinymce';
 import Editor from '@tinymce/tinymce-vue';
 
 import 'tinymce/icons/default/icons';
@@ -88,6 +88,7 @@ export default {
         menubar: false,
         branding: false,
         statusbar: false,
+        // 字数限制
         ax_wordlimit_num: 500,
         ax_wordlimit_callback(editor) {
           editor.execCommand('undo');
@@ -114,29 +115,42 @@ export default {
               fail('上传失败');
             });
         },
+        file_picker_types: 'media', // 文件上传类型
+        /**
+         * 文件上传自定义逻辑函数
+         * @param {Function} callback
+         * @param {String} value
+         * @param {object} meta
+         */
+        file_picker_callback(callback, value, meta) {
+          if (meta.filetype === 'media') {
+            let filetype = '.mp3, .mp4';
+            let input = document.createElement('input');
+            input.setAttribute('type', 'file');
+            input.setAttribute('accept', filetype);
+            input.click();
+            input.addEventListener('change', () => {
+              let file = input.files[0];
+              const formData = new FormData();
+              formData.append(file.name, file, file.name);
+              fileUpload('Mid', formData)
+                .then(({ file_info_list }) => {
+                  if (file_info_list.length > 0) {
+                    callback(file_info_list[0].file_url);
+                  } else {
+                    callback('');
+                  }
+                })
+                .catch(() => {
+                  callback('');
+                });
+            });
+          }
+        },
       },
     };
   },
-  mounted() {
-    this.addWheelEvent();
-  },
   methods: {
-    addText() {
-      tinymce.get(this.id).selection?.setContent('<strong>some</strong>');
-    },
-    addWheelEvent() {
-      let richText = this.$refs.richText;
-      if (!richText?.$el?.nextElementSibling?.getElementsByTagName('iframe')?.length) {
-        return setTimeout(this.addWheelEvent, 100);
-      }
-      richText.$el.nextElementSibling.getElementsByTagName('iframe')[0].contentDocument.addEventListener(
-        'wheel',
-        (e) => {
-          if (e.ctrlKey) e.preventDefault();
-        },
-        { passive: false },
-      );
-    },
     updateValue(data) {
       this.$emit('update:value', data);
     },

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

@@ -29,7 +29,7 @@
       <SelectQuestionType v-if="indexList.length > 0" :type="exerciseTypeList[indexList[curIndex].type]" />
       <template v-for="({ id }, i) in indexList">
         <KeepAlive :key="id">
-          <component :is="curExercisePage" v-if="i === curIndex" ref="exercise" :question-id="id" />
+          <component :is="curExercisePage" v-if="i === curIndex" ref="exercise" />
         </KeepAlive>
       </template>
     </div>
@@ -39,7 +39,7 @@
 <script>
 import { SaveQuestion } from '@/api/exercise';
 import { timeFormatConversion } from '@/utils/transform';
-import { scoreTypeList, exerciseTypeList } from '@/views/exercise_questions/data/common';
+import { exerciseTypeList } from '@/views/exercise_questions/data/common';
 
 import SelectQuestionType from './common/SelectQuestionType.vue';
 import SelectQuestion from './exercises/SelectQuestion.vue';

+ 0 - 6
src/views/exercise_questions/create/components/exercises/JudgeQuestion.vue

@@ -146,12 +146,6 @@ export default {
     RichText,
     UploadAudio,
   },
-  props: {
-    questionId: {
-      type: String,
-      required: true,
-    },
-  },
   data() {
     return {
       stemTypeList,

+ 70 - 0
src/views/exercise_questions/create/components/exercises/MatchingQuestion.vue

@@ -0,0 +1,70 @@
+<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="data.property.is_enable_description"
+          v-model="data.description"
+          rows="3"
+          resize="none"
+          type="textarea"
+          placeholder="输入描述"
+        />
+      </div>
+    </template>
+
+    <template #property></template>
+  </QuestionBase>
+</template>
+
+<script>
+import QuestionBase from '../common/QuestionBase.vue';
+import RichText from '@/components/common/RichText.vue';
+
+import {
+  stemTypeList,
+  switchOption,
+  scoreTypeList,
+  computedQuestionNumber,
+  changeOptionType,
+  questionNumberTypeList,
+} from '@/views/exercise_questions/data/common';
+import { matchingTypeList, matchingData } from '@/views/exercise_questions/data/matching';
+
+export default {
+  name: 'MatchingQuestion',
+  components: {
+    QuestionBase,
+    RichText,
+  },
+  data() {
+    return {
+      matchingTypeList,
+      data: JSON.parse(JSON.stringify(matchingData)),
+    };
+  },
+  methods: {
+    /**
+     * 设置题目内容
+     * @param {object} param
+     * @param {string} param.content 题目内容
+     */
+    setQuestion({ content }) {
+      this.data = JSON.parse(content);
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped></style>

+ 0 - 6
src/views/exercise_questions/create/components/exercises/SelectQuestion.vue

@@ -152,12 +152,6 @@ export default {
     RichText,
     UploadAudio,
   },
-  props: {
-    questionId: {
-      type: String,
-      required: true,
-    },
-  },
   data() {
     return {
       stemTypeList,

+ 3 - 0
src/views/exercise_questions/create/index.vue

@@ -145,6 +145,9 @@ export default {
           console.log(err);
         });
     },
+    /**
+     * 获取题目信息
+     */
     getQuestionInfo() {
       if (this.index_list.length === 0) return;
       GetQuestionInfo({ question_id: this.index_list[this.curIndex].id })

+ 1 - 1
src/views/exercise_questions/data/common.js

@@ -10,7 +10,7 @@ export const questionTypeOption = [
       { label: '判断题', value: 'judge' },
       { label: '填空题', value: 'fill' },
       { label: '排序题', value: 'sort' },
-      { label: '连线题', value: 'line' },
+      { label: '连线题', value: 'matching' },
       { label: '问答题', value: 'answer' },
       { label: '填表题', value: 'table' },
     ],

+ 1 - 1
src/views/exercise_questions/data/judge.js

@@ -21,7 +21,7 @@ export const judgeData = {
   option_number_show_mode: optionTypeList[0].value, // 选项类型
   option_list: [getOption(), getOption(), getOption()], // 选项
   file_id_list: [], // 文件 id 列表
-  answer: { select_list: [], score: 0, score_type: 0 }, // 答案
+  answer: { select_list: [], score: 0, score_type: scoreTypeList[0].value }, // 答案
   // 题型属性
   property: {
     stem_type: stemTypeList[0].value, // 题干类型

+ 31 - 0
src/views/exercise_questions/data/matching.js

@@ -0,0 +1,31 @@
+import { optionTypeList, stemTypeList, scoreTypeList, questionNumberTypeList } from './common';
+import { getRandomNumber } from '@/utils/index';
+
+// 连线类型列表
+export const matchingTypeList = [
+  { value: 2, label: '2列' },
+  { value: 3, label: '3列' },
+];
+
+// 连线题数据模板
+export const matchingData = {
+  type: 'matching', // 题型
+  stem: '', // 题干
+  option_number_show_mode: optionTypeList[0].value, // 选项类型
+  description: '', // 描述
+  option_list: [{ column_list: [{ content: '', mark: getRandomNumber() }] }], // 选项
+  answer: { column_list: [], score: 0, score_type: scoreTypeList[0].value }, // 答案
+  // 题型属性
+  property: {
+    stem_type: stemTypeList[0].value, // 题干类型
+    question_number: 1, // 题号
+    column_number: matchingTypeList[0].value, // 列数
+    is_enable_description: false, // 描述
+    score: 1, // 分值
+    score_type: scoreTypeList[0].value, // 分值类型
+  },
+  // 其他属性
+  other: {
+    question_number_type: questionNumberTypeList[0].value, // 题号类型
+  },
+};

+ 1 - 1
src/views/exercise_questions/data/select.js

@@ -13,7 +13,7 @@ export const selectData = {
     { content: '', mark: getRandomNumber() },
   ], // 选项
   file_id_list: [], // 文件 id 列表
-  answer: { select_list: [], score: 0, score_type: 0 }, // 答案
+  answer: { select_list: [], score: 0, score_type: scoreTypeList[0].value }, // 答案
   // 题型属性
   property: {
     stem_type: stemTypeList[0].value, // 题干类型