Sfoglia il codice sorgente

删除组件边框与组件内容间距,优化填空题分割富文本

dsy 1 settimana fa
parent
commit
64bc7248e2

+ 0 - 1
src/styles/mixin.scss

@@ -41,7 +41,6 @@
 @mixin preview-base {
   display: grid;
   gap: 6px;
-  padding: $border-component-spacing;
 
   :deep .rich-text {
     @include rich-text;

+ 0 - 1
src/styles/variables.scss

@@ -30,6 +30,5 @@ $courseware-top-padding: 65px; // 教材顶部页边距
 $courseware-bottom-padding: 65px; // 教材底部页边距
 $component-spacing: 24px; // 组件间间距
 $title-content-spacing: 65px; // 标题与内容间距
-$border-component-spacing: 10px; // 组件边框与组件内容间距
 $catalogue-width: 300px; // 目录宽度
 $sidebar-width: 300px; // 工具栏宽度

+ 75 - 45
src/views/book/courseware/create/components/question/fill/Fill.vue

@@ -156,59 +156,89 @@ export default {
         });
       this.handleViewPinyin();
     },
-    // 分割富文本
+    /**
+     * 分割富文本
+     * @param {String} str 富文本字符串
+     * @returns {Array} 分割后的数组
+     */
     splitRichText(str) {
-      let _str = str;
-      let start = 0;
-      let index = 0;
-      let arr = [];
-      let matchNum = 0;
-      while (index !== -1) {
-        index = _str.indexOf('###', start);
-        if (index === -1) break;
-        matchNum += 1;
-        arr.push({
-          content: _str.slice(start, index),
-          type: 'text',
-          paragraph_list: [],
-          paragraph_list_parameter: {
-            text: '',
-            pinyin_proofread_word_list: [],
-          },
-        });
-        if (matchNum % 2 === 0 && arr.length > 0) {
-          arr[arr.length - 1].type = 'input';
-          arr[arr.length - 1].audio_answer_list = [];
-          let mark = getRandomNumber();
-          arr[arr.length - 1].mark = mark;
-          let content = arr[arr.length - 1].content;
-          // 设置答案数组
-          let isUnderline = /^_{3,}$/.test(content);
-          this.data.answer.answer_list.push({
-            value: isUnderline ? '' : content,
-            mark,
-            type: isUnderline ? 'any_one' : 'only_one',
-          });
+      const parts = String(str).split(/###/g);
+      const arr = [];
+
+      for (let i = 0; i < parts.length; i++) {
+        let content = parts[i] ?? '';
 
-          // 将 content 设置为空,为预览准备
-          arr[arr.length - 1].content = '';
+        // 偶数索引为普通文本段
+        if (i % 2 === 0) {
+          if (content === '') continue; // 跳过空文本块
+          // 判断 content 最前面是否是标签
+          const isStartWithTag = /^<[^>]+>/.test(content);
+
+          if (!isStartWithTag) {
+            content = this.setTag(i, parts, content);
+          }
+
+          arr.push({
+            content,
+            type: 'text',
+            paragraph_list: [],
+            paragraph_list_parameter: {
+              text: '',
+              pinyin_proofread_word_list: [],
+            },
+          });
+          continue;
         }
-        start = index + 3;
-      }
-      let last = _str.slice(start);
-      if (last) {
+
+        // 奇数索引为输入段(被 ### 包裹的内容)
+        const isUnderline = /^_{3,}$/.test(content);
+        const mark = getRandomNumber();
         arr.push({
-          content: last,
-          type: 'text',
-          paragraph_list: [],
-          paragraph_list_parameter: {
-            text: '',
-            pinyin_proofread_word_list: [],
-          },
+          content: isUnderline ? '' : content,
+          type: 'input',
+          audio_answer_list: [],
+          mark,
+        });
+
+        // 同步更新答案列表
+        this.data.answer.answer_list.push({
+          value: isUnderline ? '' : content,
+          mark,
+          type: isUnderline ? 'any_one' : 'only_one',
         });
+
+        // 将 content 设置为空,为预览准备
+        arr[arr.length - 1].content = '';
       }
       return arr;
     },
+
+    /**
+     * 设置前一个标签
+     * @param {Number} index 当前索引
+     * @param {Array} parts 分割后的数组
+     * @param {String} content 当前内容
+     * @returns {String} 包含前一个标签的内容
+     */
+    setTag(index, parts, content) {
+      let _content = content;
+      const isEndWithTag = /<\/[^>]+>$/.test(_content);
+      let startTag = '';
+      for (let j = index - 1; j >= 0; j--) {
+        const prev = parts[j] ?? '';
+        const m = prev.match(/^<[^>]+>/);
+        if (m) {
+          startTag = m[0];
+        }
+      }
+      _content = `${startTag}${_content}`;
+      if (!isEndWithTag) {
+        let tag = startTag.match(/^<([^>\s]+).*?>/);
+        tag = tag ? tag[1] : 'span';
+        _content += `</${tag}>`;
+      }
+      return _content;
+    },
     handleTone(value, i) {
       if (!/^[a-zA-Z0-9\s]+$/.test(value)) return;
       this.data.answer.answer_list[i].value = value