dedsudiyu 1 week ago
parent
commit
8d379ac4b4

+ 68 - 17
src/components/tinymceContainer/index.vue

@@ -73,10 +73,9 @@
             spellcheck="false"
             @input="onInputChange"
           />
-          <!-- 实时预览 -->
+          <!-- 实时预览:由 renderPreview 方法直接操作 DOM,避免 MathJax 缓存问题 -->
           <div class="fm-preview" ref="fmPreview">
-            <span v-if="latexInput">$${{ latexInput }}$$</span>
-            <span v-else class="fm-preview-empty">公式预览</span>
+            <span class="fm-preview-empty">公式预览</span>
           </div>
         </div>
 
@@ -141,9 +140,9 @@ export default {
     value: { type: String, default: '' },
     disabled: { type: Boolean, default: false },
     height: { type: [Number, String], default: 400 },
-    // 图片/附件上传接口地址
+    // 富文本纯文本内容最大长度,0 表示不限制
+    maxLength: { type: Number, default: 0 },
     uploadUrl: { type: String, default: '' },
-    // 上传请求头,如 { Authorization: 'Bearer xxx' }
     uploadHeaders: { type: Object, default: () => ({}) }
   },
   data() {
@@ -288,6 +287,12 @@ export default {
         toolbar_mode: 'wrap',
         quickbars_selection_toolbar: 'bold italic underline | quicklink h2 h3 blockquote',
         quickbars_insert_toolbar: false,
+        // 插入/编辑图片弹窗:隐藏上传 tab,只保留 URL 输入
+        image_uploadtab: false,
+        // 插入/编辑媒体弹窗:只保留"一般"tab,隐藏内嵌和高级
+        media_live_embeds: false,
+        media_alt_source: false,
+        media_poster: false,
         font_formats:
           '微软雅黑=Microsoft YaHei,Helvetica Neue,PingFang SC,sans-serif;' +
           '宋体=SimSun,serif;黑体=SimHei,sans-serif;楷体=KaiTi,serif;' +
@@ -336,6 +341,22 @@ export default {
             }
           }),
         setup: (editor) => {
+          // 字数限制:在 input 事件后检查纯文本长度
+          editor.on('input keydown', (e) => {
+            if (!this.maxLength) return
+            // keydown 时只拦截非删除类按键
+            if (e.type === 'keydown') {
+              const allowKeys = ['Backspace', 'Delete', 'ArrowLeft', 'ArrowRight', 'ArrowUp', 'ArrowDown']
+              if (allowKeys.includes(e.key) || e.ctrlKey || e.metaKey) return
+            }
+            const text = editor.getContent({ format: 'text' })
+            if (text.length >= this.maxLength) {
+              if (e.type === 'keydown') {
+                e.preventDefault()
+                if (this.$message) this.$message.warning(`内容长度不能超过 ${this.maxLength} 个字符`)
+              }
+            }
+          })
           editor.ui.registry.addButton('latex', {
             text: '公式',
             tooltip: '插入公式',
@@ -416,7 +437,25 @@ export default {
   computed: {
     editorContent: {
       get() { return this.value },
-      set(val) { this.$emit('input', val) }
+      set(val) {
+        if (this.maxLength > 0) {
+          const text = val.replace(/<[^>]*>/g, '')
+          if (text.length > this.maxLength) {
+            this.$nextTick(() => {
+              if (this._editor) {
+                this._editor.setContent(this.value)
+                this._editor.selection.select(this._editor.getBody(), true)
+                this._editor.selection.collapse(false)
+              }
+            })
+            if (this.$message) {
+              this.$message.warning(`内容长度不能超过 ${this.maxLength} 个字符`)
+            }
+            return
+          }
+        }
+        this.$emit('input', val)
+      }
     }
   },
   mounted() {
@@ -458,7 +497,15 @@ export default {
     renderPreview() {
       this.$nextTick(() => {
         const el = this.$refs.fmPreview
-        if (!el || !window.MathJax) return
+        if (!el) return
+        const latex = this.latexInput.trim()
+        if (!latex) {
+          el.innerHTML = '<span class="fm-preview-empty">公式预览</span>'
+          return
+        }
+        // 每次重置 innerHTML,强制 MathJax 重新解析,避免缓存导致预览不更新
+        el.innerHTML = `$$${latex}$$`
+        if (!window.MathJax) return
         window.MathJax.typesetClear([el])
         window.MathJax.typesetPromise([el]).catch(() => {})
       })
@@ -550,7 +597,7 @@ export default {
   background: #fff;
   border-radius: 6px;
   box-shadow: 0 6px 30px rgba(0,0,0,0.2);
-  width: 720px;
+  width: 1000px;
   max-width: 96vw;
   display: flex;
   flex-direction: column;
@@ -583,9 +630,9 @@ export default {
 .fm-toolbar {
   display: flex;
   align-items: center;
-  flex-wrap: wrap;
-  gap: 4px;
-  padding: 8px 12px;
+  flex-wrap: nowrap;
+  gap: 3px;
+  padding: 6px 10px;
   border-bottom: 1px solid #e4e4e4;
   background: #fafafa;
 }
@@ -637,10 +684,10 @@ export default {
 
 /* 符号格子 */
 .fm-symbol-grid {
-  display: grid;
-  grid-template-columns: repeat(9, 28px);
-  grid-template-rows: repeat(2, 26px);
+  display: flex;
+  flex-wrap: nowrap;
   gap: 2px;
+  flex-shrink: 0;
 }
 .fm-sym-btn {
   width: 28px;
@@ -661,20 +708,24 @@ export default {
 /* 分类按钮组 */
 .fm-category-row {
   display: flex;
-  gap: 4px;
-  flex-wrap: wrap;
+  gap: 3px;
+  flex-wrap: nowrap;
+  flex-shrink: 0;
 }
 .fm-cat-wrap { position: relative; }
 .fm-cat-btn {
   display: flex;
   flex-direction: column;
   align-items: center;
-  padding: 3px 8px;
+  justify-content: center;
+  padding: 0 8px;
   border: 1px solid #ccc;
   border-radius: 4px;
   background: #fff;
   cursor: pointer;
   min-width: 44px;
+  height: 60px;
+  box-sizing: border-box;
   user-select: none;
   gap: 1px;
 }

+ 5 - 1
src/views/safetyEducationExaminationNew/questionBankManagement/questionBankManagement/addPage.vue

@@ -65,11 +65,12 @@
           <p>题干</p>
           <p></p>
         </div>
-        <div class="editor-form-box edde">
+        <div class="editor-form-box">
           <el-form-item label="" prop="data5" label-width="0">
             <tinymce-container
               v-model="newData.data5"
               :height="300"
+              :max-length="500"
               :upload-url="editorUploadUrl"
               :upload-headers="editorUploadHeaders"
             />
@@ -292,6 +293,9 @@
           margin-top:19px;
         }
       }
+      .editor-form-box{
+        margin:0 40px;
+      }
     }
   }
 </style>