Sfoglia il codice sorgente

修改注释显示样式

zq 1 settimana fa
parent
commit
68d38b0e37

+ 0 - 6
src/components/RichText.vue

@@ -174,12 +174,6 @@ export default {
               isRendered = true;
               window.MathJax.typesetPromise([editor.getBody()]);
             }
-            if (e.target.classList.contains('rich-fill')) {
-              const noteId = e.target.getAttribute('data-annotation-id');
-              that.$emit('selectNote', noteId);
-            } else {
-              that.$emit('selectNote', '');
-            }
           });
 
           // 添加 MathJax 按钮

+ 0 - 54
src/views/book/courseware/create/components/base/rich_text/RichText.vue

@@ -13,7 +13,6 @@
           @selectContentSetMemo="selectContentSetMemo"
           @crateParsedTextInfoPinyin="crateParsedTextInfoPinyin"
           @compareAnnotationAndSave="compareAnnotationAndSave"
-          @selectNote="selectNote"
         />
         <el-divider v-if="isEnable(data.property.view_pinyin)" content-position="left">拼音效果</el-divider>
         <PinyinText
@@ -25,17 +24,6 @@
           @fillCorrectPinyin="fillCorrectPinyin"
         />
       </div>
-      <div v-if="data.note_list.length > 0" class="note-list">
-        <span>注释</span>
-        <ul>
-          <li v-for="note in data.note_list" :key="note.id">
-            <p :style="{ 'background-color': selectedNoteId == note.id ? '#FFF2C9' : '#CCC' }">
-              {{ note.selectText }}
-            </p>
-            <span v-html="sanitizeHTML(note.note)"></span>
-          </li>
-        </ul>
-      </div>
       <ExplanatoryNoteDialog
         ref="explanatoryNote"
         :open.sync="isViewExplanatoryNoteDialog"
@@ -69,7 +57,6 @@ export default {
       richId: '',
       isViewExplanatoryNoteDialog: false,
       oldRichData: {},
-      selectedNoteId: '',
     };
   },
   watch: {
@@ -150,9 +137,6 @@ export default {
         this.oldRichData = {};
       }
     },
-    selectNote(id) {
-      this.selectedNoteId = id;
-    },
     // 点击弹窗确认-保存
     confirmExplanatoryNote(text) {
       console.log(text);
@@ -201,41 +185,3 @@ export default {
   },
 };
 </script>
-<style lang="scss" scoped>
-:deep .module-content {
-  display: flex;
-  column-gap: 10px;
-
-  .note-list {
-    display: flex;
-    flex-direction: column;
-    width: 20%;
-
-    > span {
-      font-weight: bold;
-    }
-
-    li {
-      margin-top: 6px;
-      border-radius: 8px;
-      box-shadow: 1px 3px 2px rgba(0, 0, 0, 10%);
-
-      p {
-        padding: 4px;
-        margin: 0;
-        background-color: #ccc;
-        border-radius: 8px 8px 0 0;
-      }
-
-      span {
-        display: block;
-        padding: 8px;
-      }
-    }
-
-    p {
-      text-align: center;
-    }
-  }
-}
-</style>

+ 78 - 70
src/views/book/courseware/preview/components/rich_text/RichTextPreview.vue

@@ -12,18 +12,20 @@
         />
         <span v-else class="rich-text" @click="handleRichFillClick" v-html="sanitizeHTML(data.content)"></span>
       </div>
-      <div v-if="data.note_list.length > 0" ref="rightDiv" class="note-list" :style="{ height: divHeight + 'px' }">
-        <span>注释</span>
-        <ul>
-          <li v-for="note in data.note_list" :key="note.id" :ref="note.id">
-            <p :style="{ 'background-color': selectedNoteId == note.id ? '#FFF2C9' : '#CCC' }">
-              {{ note.selectText }}
-            </p>
-            <span v-html="sanitizeHTML(note.note)"></span>
-          </li>
-        </ul>
-      </div>
     </div>
+
+    <el-dialog
+      title=""
+      :visible.sync="noteDialogVisible"
+      width="680px"
+      ref="optimizedDialog"
+      :style="dialogStyle"
+      :close-on-click-modal="false"
+      destroy-on-close
+      @close="noteDialogVisible = false"
+    >
+      <span v-html="selectedNote"></span>
+    </el-dialog>
   </div>
 </template>
 
@@ -41,10 +43,17 @@ export default {
     return {
       isEnable,
       data: getRichTextData(),
-      selectedNoteId: '',
       isPreview: true,
       divHeight: 'auto',
       observer: null,
+      noteDialogVisible: false,
+      selectedNote: '',
+      dialogStyle: {
+        position: 'fixed',
+        top: '0',
+        left: '0',
+        margin: '0',
+      },
     };
   },
   mounted() {
@@ -62,24 +71,61 @@ export default {
       const richFillElement = event.target.closest('.rich-fill');
       if (richFillElement) {
         // 处理点击事件
-        this.selectedNoteId = richFillElement.dataset.annotationId;
-
-        const sectionRef = this.$refs[`${this.selectedNoteId}`][0];
-        const rightDiv = this.$refs.rightDiv;
-
-        // 计算滚动位置
-        const rightDivTop = rightDiv.getBoundingClientRect().top;
-        const sectionTop = sectionRef.getBoundingClientRect().top;
-        const scrollPosition = sectionTop - rightDivTop + rightDiv.scrollTop;
-
-        // 平滑滚动
-        rightDiv.scrollTo({
-          top: scrollPosition,
-          behavior: 'smooth',
-        });
+        let selectedNoteId = richFillElement.dataset.annotationId;
+        if (this.data.note_list.some((p) => p.id === selectedNoteId)) {
+          this.noteDialogVisible = true;
+          this.selectedNote = this.data.note_list.find((p) => p.id === selectedNoteId).note;
+        }
       } else {
-        this.selectedNoteId = '';
+        this.selectedNote = '';
+        this.noteDialogVisible = false;
       }
+      this.$nextTick(() => {
+        const dialogElement = this.$refs.optimizedDialog;
+        // 确保对话框DOM已渲染
+        if (!dialogElement) {
+          return;
+        }
+        // 获取对话框内容区域的DOM元素
+        const dialogContent = dialogElement.$el.querySelector('.el-dialog');
+        if (!dialogContent) {
+          return;
+        }
+        const dialogRect = dialogContent.getBoundingClientRect();
+        const dialogWidth = dialogRect.width;
+        const dialogHeight = dialogRect.height;
+        const padding = 10; // 安全边距
+
+        const clickX = event.clientX;
+        const clickY = event.clientY;
+
+        const windowWidth = window.innerWidth;
+        const windowHeight = window.innerHeight;
+
+        // 水平定位 - 中心对齐
+        let left = clickX - dialogWidth / 2;
+        // 边界检查
+        left = Math.max(padding, Math.min(left, windowWidth - dialogWidth - padding));
+
+        // 垂直定位 - 点击位置作为下边界中心
+        let top = clickY - dialogHeight;
+        // 上方空间不足时,改为向下展开
+        if (top < padding) {
+          top = clickY + padding;
+          // 如果向下展开会超出屏幕,则贴底部显示
+          if (top + dialogHeight > windowHeight - padding) {
+            top = windowHeight - dialogHeight - padding;
+          }
+        }
+
+        this.dialogStyle = {
+          position: 'fixed',
+          top: `${top - 20}px`,
+          left: `${left}px`,
+          margin: '0',
+          transform: 'none',
+        };
+      });
     },
     updateHeight() {
       this.$nextTick(() => {
@@ -101,48 +147,10 @@ export default {
 .describe-preview {
   @include preview-base;
 
-  .main {
-    display: flex;
-    column-gap: 10px;
-    justify-content: space-between;
-
-    .note-list {
-      display: flex;
-      flex-direction: column;
-      width: 20%;
-      min-height: 150px;
-      overflow: auto;
-
-      > span {
-        font-weight: bold;
-      }
-
-      li {
-        margin-top: 6px;
-        border-radius: 8px;
-        box-shadow: 1px 3px 2px rgba(0, 0, 0, 10%);
-
-        p {
-          padding: 4px;
-          margin: 0;
-          background-color: #ccc;
-          border-radius: 8px 8px 0 0;
-        }
-
-        span {
-          display: block;
-          padding: 8px;
-
-          :deep p {
-            margin: 0 !important;
-          }
-        }
-      }
-
-      p {
-        text-align: center;
-      }
-    }
+  :deep .el-dialog {
+    position: fixed;
+    margin: 0 !important;
+    transition: all 0.2s; /* 添加平滑过渡效果 */
   }
 }
 </style>