Jelajahi Sumber

Merge branch 'master' of http://gcls-git.helxsoft.cn/GCLS/eep_page

zq 3 minggu lalu
induk
melakukan
b90f124cc7

+ 1 - 1
.env

@@ -11,4 +11,4 @@ VUE_APP_BookWebSI = '/GCLSBookWebSI/ServiceInterface'
 VUE_APP_EepServer = '/EEPServer/SI'
 
 #version
-VUE_APP_VERSION = '2025.10.28'
+VUE_APP_VERSION = '2025.10.30'

+ 1 - 1
package.json

@@ -1,6 +1,6 @@
 {
   "name": "eep_page",
-  "version": "2025.10.28",
+  "version": "2025.10.30",
   "private": true,
   "main": "main.js",
   "description": "智慧梧桐数字教材编辑器",

+ 1 - 0
src/components/MathDialog.vue

@@ -172,6 +172,7 @@ export default {
       align-items: center;
       max-height: 300px;
       overflow: auto;
+      font-size: 14px;
 
       .macros-item {
         padding: 4px;

+ 19 - 21
src/components/RichText.vue

@@ -171,12 +171,10 @@ export default {
         branding: false, // 品牌
         statusbar: false, // 状态栏
         entity_encoding: 'raw', // raw不编码任何字符;named: 使用命名实体(如  );numeric: 使用数字实体(如  )
-
         setup: (editor) => {
-          var that = this;
-          editor.on('GetContent', function (e) {
+          editor.on('GetContent', (e) => {
             if (e.format === 'html') {
-              e.content = that.smartPreserveLineBreaks(editor, e.content);
+              e.content = this.smartPreserveLineBreaks(editor, e.content);
             }
           });
 
@@ -242,7 +240,7 @@ export default {
             if (e.keyCode === 8 || e.keyCode === 46) {
               // 延迟执行以确保删除已完成
               setTimeout(() => {
-                that.cleanupRemovedAnnotations(editor);
+                this.cleanupRemovedAnnotations(editor);
               }, 500);
             }
           });
@@ -250,7 +248,7 @@ export default {
           // 也可以监听剪切操作
           editor.on('Cut', () => {
             setTimeout(() => {
-              that.cleanupRemovedAnnotations(editor);
+              this.cleanupRemovedAnnotations(editor);
             }, 500);
           });
           // editor.on('NodeChange', function (e) {
@@ -262,7 +260,7 @@ export default {
           //   ) {
           //     const annotationId = e.element.getAttribute('data-annotation-id');
           //     e.element.parentNode.removeChild(e.element);
-          //     that.$emit('selectContentSetMemo', null, annotationId);
+          //     this.$emit('selectContentSetMemo', null, annotationId);
           //   }
           // });
         },
@@ -285,11 +283,13 @@ export default {
         file_picker_callback: this.filePickerCallback,
         init_instance_callback: this.isFill || this.isViewNote ? this.initInstanceCallback : '',
         paste_enable_default_filters: false, // 禁用默认的粘贴过滤器
+        paste_as_text: true, // 默认作为纯文本粘贴
         // 粘贴预处理
         paste_preprocess(plugin, args) {
           let content = args.content;
           // 使用正则表达式去掉 style 中的 background 属性
           content = content.replace(/background(-color)?:[^;]+;/g, '');
+          content = content.replace(/\t/g, '    '); // 将制表符替换为4个空格
           args.content = content;
         },
         // 指定在 WebKit 中粘贴时要保留的样式
@@ -377,20 +377,19 @@ export default {
   },
   methods: {
     smartPreserveLineBreaks(editor, content) {
-      var that = this;
-      var body = editor.getBody();
-      var originalParagraphs = Array.from(body.getElementsByTagName('p'));
+      let body = editor.getBody();
+      let originalParagraphs = Array.from(body.getElementsByTagName('p'));
 
-      var tempDiv = document.createElement('div');
+      let tempDiv = document.createElement('div');
       tempDiv.innerHTML = content;
-      var outputParagraphs = Array.from(tempDiv.getElementsByTagName('p'));
+      let outputParagraphs = Array.from(tempDiv.getElementsByTagName('p'));
 
-      outputParagraphs.forEach(function (outputP, index) {
-        var originalP = originalParagraphs[index];
+      outputParagraphs.forEach((outputP, index) => {
+        let originalP = originalParagraphs[index];
 
         if (originalP && outputP.innerHTML === '') {
           // 判断这个空段落是否应该包含 <br>
-          var shouldHaveBr = that.shouldPreserveLineBreak(originalP, index, originalParagraphs);
+          let shouldHaveBr = this.shouldPreserveLineBreak(originalP, index, originalParagraphs);
           if (shouldHaveBr) {
             outputP.innerHTML = '<br>';
           }
@@ -408,8 +407,8 @@ export default {
 
       // 规则2:如果段落位于内容中间(不是第一个或最后一个)
       if (index > 0 && index < allParagraphs.length - 1) {
-        var prevHasContent = allParagraphs[index - 1].textContent.trim() !== '';
-        var nextHasContent = allParagraphs[index + 1].textContent.trim() !== '';
+        let prevHasContent = allParagraphs[index - 1].textContent.trim() !== '';
+        let nextHasContent = allParagraphs[index + 1].textContent.trim() !== '';
 
         if (prevHasContent && nextHasContent) {
           return true;
@@ -417,7 +416,7 @@ export default {
       }
 
       // 规则3:如果段落是通过回车创建的(前后有内容)
-      var isBetweenContent = false;
+      let isBetweenContent = false;
       if (index > 0 && allParagraphs[index - 1].textContent.trim() !== '') {
         isBetweenContent = true;
       }
@@ -721,7 +720,7 @@ export default {
       let isHasPinyin = content
         .split(/<[^>]+>/g)
         .filter((item) => item)
-        .some((item) => item.match(/[a-zA-Z]+\d(\s|&nbsp;)*/));
+        .some((item) => item.match(/[a-zA-Z]+\d+(\s|&nbsp;)+/));
 
       if (!isHasPinyin) {
         return;
@@ -887,7 +886,6 @@ export default {
     },
     // 删除span里面的文字之后,会出现空 span 标签残留,需处理掉
     handleEmptySpan(editor) {
-      let that = this;
       const selection = editor.selection;
       const selectedNode = selection.getNode();
       // 如果选中的是注释span内的内容
@@ -902,7 +900,7 @@ export default {
           span.parentNode.replaceChild(document.createTextNode(''), span);
 
           // 从存储中移除注释
-          that.$emit('selectContentSetMemo', null, annotationId);
+          this.$emit('selectContentSetMemo', null, annotationId);
         }
       }
     },

+ 7 - 11
src/views/book/components/MultilingualFill.vue

@@ -97,20 +97,16 @@ export default {
     };
   },
   watch: {
-    translations: {
-      handler(newVal) {
-        if (!newVal || !Array.isArray(newVal) || newVal.length === 0) return;
-        this.selectedLangList = newVal.map(({ type, translation }) => ({
-          type,
-          translation,
-        }));
-      },
-      immediate: true,
-    },
     visible: {
       handler(newVal) {
-        if (newVal && this.langList.length === 0) {
+        if (newVal) {
           this.init();
+          if (this.translations.length > 0) {
+            this.selectedLangList = this.translations.map(({ type, translation }) => ({
+              type,
+              translation,
+            }));
+          }
         }
         if (!newVal && this.selectedLangList.length > 0) {
           this.selectedLangList = this.selectedLangList.map((item) => ({

+ 1 - 1
src/views/book/courseware/create/components/common/ModuleMixin.js

@@ -206,7 +206,7 @@ const mixin = {
      * @param {Array} multilingual
      */
     handleMultilingualTranslation(multilingual) {
-      this.data.multilingual = multilingual;
+      this.$set(this.data, 'multilingual', multilingual);
     },
     /**
      * 获取并设置拼音解析文本

+ 3 - 1
src/views/book/courseware/create/components/question/matching/Matching.vue

@@ -201,7 +201,9 @@ export default {
     openMultilingual(i, j) {
       this.curSelectRow = i;
       this.curSelectColumn = j;
-      this.multilingualVisible = true;
+      this.$nextTick(() => {
+        this.multilingualVisible = true;
+      });
     },
     handleMultilingualTranslation(translations) {
       this.$set(this.data.option_list[this.curSelectRow][this.curSelectColumn], 'multilingual', translations);

+ 3 - 0
src/views/book/courseware/data/richText.js

@@ -266,6 +266,9 @@ export const mathMacrosListByCategory = {
     'vee',
     'veebar',
     'wr',
+    'pm',
+    'mp',
+    'times',
   ],
   // 集合符号
   sets: [