Explorar o código

添加ai助手移动

11wqe1 hai 3 semanas
pai
achega
57697e28a7
Modificáronse 1 ficheiros con 133 adicións e 8 borrados
  1. 133 8
      src/components/main/feedback.vue

+ 133 - 8
src/components/main/feedback.vue

@@ -4,13 +4,24 @@
             反馈
         </span>
         <br /> -->
-        <span @click="dialogVisible2 = true">
-            <el-icon>
-                <ChatRound />
-            </el-icon>
-            <br />
-            AI助手
-        </span>
+        <div class="draggable-window" 
+            v-draggable="{
+                updatePosition: handlePositionUpdate,
+                onClick: openxiaoKe
+            }"
+            :style="{ left: position.x + 'px', top: position.y + 'px' }"
+            @dragging="handleDragging">
+            <div class="window-header">
+                <span>
+                    <el-icon>
+                        <ChatRound />
+                    </el-icon>
+                    <br />
+                    AI助手
+                </span>
+            </div>
+        </div>
+       
     </div>
     <el-dialog v-model="dialogVisible" :before-close="handleClose" width=500>
         <template #header>
@@ -34,7 +45,7 @@
             </div>
         </template>
     </el-dialog>
-    <el-drawer v-model="dialogVisible2" width="100%" :direction="rtl" :size="Full_Screen ? '  100%' : '30%'">
+    <el-drawer v-model="dialogVisible2" width="100%" direction="rtl" :size="Full_Screen ? '  100%' : '30%'">
         <template #header="{ close, titleId, titleClass }">
             <div slot="title" style="display: flex; align-items: center;">
                 <img style="cursor: pointer;width: 24px;margin-left: 15px;" :src="!Full_Screen ? FullScreen : noFullScreen"
@@ -59,11 +70,102 @@ const dialogVisible = ref(false)
 const textarea1 = ref("")
 const dialogVisible2 = ref(false)
 const Full_Screen = ref(false)
+const vDraggable = {
+  mounted(el, binding) {
+    let isDragging = false;
+    let offsetX = 0;
+    let offsetY = 0;
+    let startTime = '';
+
+    const onMouseDown = (event) => {
+      
+      isDragging = true;
+      startTime = new Date().getTime();
+      offsetX = event.clientX - el.offsetLeft;
+      offsetY = event.clientY - el.offsetTop;
+
+      document.body.style.userSelect = "none";
+      document.addEventListener("mousemove", onMouseMove);
+      document.addEventListener("mouseup", onMouseUp);
+    };
+
+    const onMouseMove = (event) => {
+      let endTime = new Date().getTime();
+      if (isDragging && (endTime - startTime > 200)) {
+        el.style.left = `${event.clientX - offsetX}px`;
+        el.style.top = `${event.clientY - offsetY}px`;
+        
+        // Vue 3 中需要通过 binding.value 传递回调函数
+        if (binding.value?.updatePosition) {
+            binding.value.updatePosition({
+                x: event.clientX - offsetX,
+                y: event.clientY - offsetY
+            });
+        }
+      }
+    };
+
+    const onMouseUp = () => {
+      isDragging = false;
+      let endTime = new Date().getTime();
+      
+      if (endTime - startTime < 200) {
+        // 通过 binding.value 调用回调
+        if (binding.value && binding.value.onClick) {
+          binding.value.onClick();
+        }
+      }
+      
+      document.body.style.userSelect = "";
+      document.removeEventListener("mousemove", onMouseMove);
+      document.removeEventListener("mouseup", onMouseUp);
+    };
+
+    // 确保元素有 window-header 类
+    const headerEl = el.querySelector(".window-header");
+    if (headerEl) {
+      headerEl.addEventListener("mousedown", onMouseDown);
+    }
+
+    // 保存事件监听器引用以便卸载时清理
+    el._draggable = { onMouseDown, headerEl };
+  },
+  
+  unmounted(el) {
+    // 清理事件监听器
+    if (el._draggable) {
+      const { onMouseDown, headerEl } = el._draggable;
+      if (headerEl) {
+        headerEl.removeEventListener("mousedown", onMouseDown);
+      }
+    }
+  }
+};
+
+const position = ref({ 
+    x: window.innerWidth - 115, // 屏幕宽度减去元素宽度
+	y: window.innerHeight - 150, // 屏幕高度减去元素高度 
+});
+
+const handlePositionUpdate = (newPos) => {
+  // 直接修改 reactive 对象的属性
+  position.value.x = newPos.x;
+  position.value.y = newPos.y;
+  console.log('位置更新:', position);
+};
+const openxiaoKe = () => {
+  console.log('点击事件触发');
+  dialogVisible2.value = true
+};
 
 const goFeedback = () => {
     // top.location.href = "https://bbs.cocorobo.cn/"
     dialogVisible.value = true
 }
+
+const handleClose = (done) => {
+    done()
+}
 const CustomerService = () => {
     top.location.href = "https://bbs.cocorobo.cn/"
 }
@@ -102,4 +204,27 @@ const updateReduction = () => {
         font-size: 14px;
     }
 }
+.draggable-window {
+    position: fixed;
+    background: #fff;
+    padding: 10px 0;
+    border-radius: 30px;
+    text-align: center;
+    box-shadow: 1px 2px 1px 2px #f1f1f1;
+    z-index: 100;
+}
+
+.window-header {
+        position: relative;
+        span {
+            display: inline-block;
+            padding: 10px 8px;
+            cursor: pointer;
+            font-size: 14px;
+        }
+}
+
+.window-header:active {
+  cursor: grabbing;
+}
 </style>