Quellcode durchsuchen

会话增加拖动

rkljw vor 2 Tagen
Ursprung
Commit
2478bcdfad

+ 91 - 12
src/layout/components/Chat/ChatFloatButton.vue

@@ -1,19 +1,99 @@
 <template>
-  <div class="chat-float-button" @click="handleClick">
+  <div
+    class="chat-float-button"
+    @mousedown="onDragStart"
+    @click="onButtonClick"
+  >
     <img class="chat-icon" src="@/assets/chat/chat_line.png" alt="在线会话" />
-    <span class="chat-label">在线会话</span>
+    <span class="chat-label" @click.stop="onLabelClick">在线会话</span>
   </div>
 </template>
 
 <script>
+let dragSuppressClick = false;
 export default {
   name: 'ChatFloatButton',
+  data() {
+    return {
+      isDragging: false,
+      fixedWidth: null,
+      fixedHeight: null,
+    };
+  },
   methods: {
-    handleClick() {
-      this.$emit('open');
-    }
-  }
-}
+    onLabelClick(e) {
+      if (!dragSuppressClick) {
+        this.$emit('open');
+      }
+    },
+    onButtonClick(e) {
+      if (dragSuppressClick) {
+        dragSuppressClick = false;
+        e.stopImmediatePropagation && e.stopImmediatePropagation();
+        e.stopPropagation();
+        e.preventDefault();
+      }
+    },
+    onDragStart(e) {
+      if (e.button !== 0) return;
+      const btn = this.$el;
+      const rect = btn.getBoundingClientRect();
+      const startX = e.clientX;
+      const startY = e.clientY;
+      const startLeft = rect.left;
+      const startTop = rect.top;
+      const width = rect.width;
+      const height = rect.height;
+
+      // 固定宽高,拖动过程中始终不变
+      btn.style.width = width + 'px';
+      btn.style.height = height + 'px';
+      this.fixedWidth = width;
+      this.fixedHeight = height;
+
+      btn.style.left = startLeft + 'px';
+      btn.style.top = startTop + 'px';
+      btn.style.right = '';
+      btn.style.bottom = '';
+      btn.style.position = 'fixed';
+      btn.style.cursor = 'move';
+      document.body.style.userSelect = 'none';
+
+      let moved = false;
+
+      const onMouseMove = (moveEvent) => {
+        const dx = moveEvent.clientX - startX;
+        const dy = moveEvent.clientY - startY;
+        if (!moved && (Math.abs(dx) > 2 || Math.abs(dy) > 2)) {
+          moved = true;
+        }
+        let newLeft = startLeft + dx;
+        let newTop = startTop + dy;
+        const maxLeft = window.innerWidth - width;
+        const maxTop = window.innerHeight - height;
+        newLeft = Math.max(0, Math.min(newLeft, maxLeft));
+        newTop = Math.max(0, Math.min(newTop, maxTop));
+        btn.style.left = newLeft + 'px';
+        btn.style.top = newTop + 'px';
+      };
+
+      const onMouseUp = () => {
+        document.removeEventListener('mousemove', onMouseMove);
+        document.removeEventListener('mouseup', onMouseUp);
+        document.body.style.userSelect = '';
+        btn.style.cursor = 'pointer';
+        // 拖动结束后,宽高依然保持固定,不恢复自适应
+        // btn.style.width/height 保持不变
+        if (moved) {
+          dragSuppressClick = true;
+          setTimeout(() => { dragSuppressClick = false; }, 100);
+        }
+      };
+      document.addEventListener('mousemove', onMouseMove);
+      document.addEventListener('mouseup', onMouseUp);
+    },
+  },
+};
 </script>
 
 <style scoped>
@@ -30,17 +110,16 @@ export default {
   cursor: pointer;
   z-index: 9999;
   border: 1px solid #eee;
+  /* 不设置 width/height,JS 控制 */
 }
 .chat-icon {
-  width: 32px;
-  height: 32px;
+  width: 24px;
+  height: 24px;
   margin-right: 8px;
-  border-radius: 50%;
-  border: 1px solid #e0e0e0;
-  object-fit: cover;
 }
 .chat-label {
   font-size: 16px;
   color: #333;
+  user-select: none;
 }
 </style>

+ 53 - 1
src/layout/components/Chat/ChatPanel.vue

@@ -927,7 +927,7 @@
                         <div class="fileWindowMessageItemName">用户名称</div>
                         <div class="fileWindowMessageItemTime">12:40</div>
                       </div>
-                      <div class="fileWindowMessageItemText">用用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息</div>
+                      <div class="fileWindowMessageItemText">用用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息用户消息</div>
                     </div>
                   </div>
                 </div>
@@ -3016,6 +3016,57 @@
           }, 50); // 动画结束后再修正一次
         });
       },
+      initDrag() {
+        const panel = this.$el;
+        const header = panel.querySelector('.chat-header');
+        if (!header) return;
+        let isDragging = false;
+        let startX, startY, startLeft, startTop;
+
+        header.style.cursor = 'move';
+
+        header.addEventListener('mousedown', (e) => {
+          // 只允许鼠标左键拖动
+          if (e.button !== 0) return;
+          isDragging = true;
+          startX = e.clientX;
+          startY = e.clientY;
+          const rect = panel.getBoundingClientRect();
+          startLeft = rect.left;
+          startTop = rect.top;
+          // 防止选中文字
+          document.body.style.userSelect = 'none';
+
+          const onMouseMove = (moveEvent) => {
+            if (!isDragging) return;
+            const dx = moveEvent.clientX - startX;
+            const dy = moveEvent.clientY - startY;
+            let newLeft = startLeft + dx;
+            let newTop = startTop + dy;
+
+            // 限制不拖出屏幕
+            const maxLeft = window.innerWidth - panel.offsetWidth;
+            const maxTop = window.innerHeight - panel.offsetHeight;
+            newLeft = Math.max(0, Math.min(newLeft, maxLeft));
+            newTop = Math.max(0, Math.min(newTop, maxTop));
+
+            panel.style.left = newLeft + 'px';
+            panel.style.top = newTop + 'px';
+            panel.style.right = '';
+            panel.style.bottom = '';
+          };
+
+          const onMouseUp = () => {
+            isDragging = false;
+            document.removeEventListener('mousemove', onMouseMove);
+            document.removeEventListener('mouseup', onMouseUp);
+            document.body.style.userSelect = '';
+          };
+
+          document.addEventListener('mousemove', onMouseMove);
+          document.addEventListener('mouseup', onMouseUp);
+        });
+      },
     },
     mounted() {
       console.log("=====fuck")
@@ -3103,6 +3154,7 @@
       //   `;
       //   document.head.appendChild(style);
       // }
+      this.initDrag();
     },
     beforeDestroy() {
       //页面销毁的时候清除定时器获取列表