From 7f62f4db8de94787f203fd6273d05414dde4b40c Mon Sep 17 00:00:00 2001 From: "@zuopngfei" Date: Sun, 9 Nov 2025 13:22:31 +0800 Subject: [PATCH] wewe --- src/views/chat/index.vue | 143 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 138 insertions(+), 5 deletions(-) diff --git a/src/views/chat/index.vue b/src/views/chat/index.vue index be6bd8c..9c98efe 100644 --- a/src/views/chat/index.vue +++ b/src/views/chat/index.vue @@ -5,10 +5,25 @@ @change="onSelectUser" />
-
+
加载中...
+ +
+
+ + + +

松开鼠标发送图片

+
+
@@ -92,6 +107,8 @@ const messageTimer = ref(null) // 定时器实例 const isSending = ref(false) // 防止重复发送 const lastSendTime = ref(0) // 最后发送时间,用于防抖 const isUploading = ref(false) // 防止重复上传 +const isDragging = ref(false) // 拖拽状态 +const dragCounter = ref(0) // 拖拽计数器,用于处理嵌套元素 // 小程序状态轮询定时器 const appStatusTimer = ref(null) @@ -556,16 +573,28 @@ const triggerImageInput = () => { imageInput.value && imageInput.value.click() } -const handleImageChange = (e) => { - const file = e.target.files[0] +// 提取图片上传逻辑为可复用函数 +const uploadImageFile = (file) => { if (!file) return + // 检查是否有选中用户 + if (!activeUser.value.sender_id) { + ElMessage({ type: 'warning', message: '请先选择用户' }) + return + } + // 防止重复上传 if (isUploading.value) { console.log('图片正在上传中,请稍候') return } + // 检查文件类型是否为图片 + if (!file.type.startsWith('image/')) { + ElMessage({ type: 'error', message: '只能上传图片文件' }) + return + } + // 检查文件大小(限制为10MB) if (file.size > 10 * 1024 * 1024) { ElMessage({ type: 'error', message: '图片大小不能超过10MB' }) @@ -592,7 +621,6 @@ const handleImageChange = (e) => { _tempImageFile: file // 保存文件信息用于匹配 } messages.value.push(msg) - e.target.value = '' // 滚动到底部 setTimeout(() => scrollToBottom(), 100) @@ -650,6 +678,78 @@ const handleImageChange = (e) => { }) } +const handleImageChange = (e) => { + const file = e.target.files[0] + if (file) { + uploadImageFile(file) + } + // 清空input值,以便下次选择同一文件时也能触发change事件 + e.target.value = '' +} + +// 拖拽事件处理 +const handleDragEnter = (e) => { + e.preventDefault() + e.stopPropagation() + dragCounter.value++ + // 检查拖拽内容是否包含文件 + if (e.dataTransfer.types.includes('Files')) { + isDragging.value = true + } +} + +const handleDragOver = (e) => { + e.preventDefault() + e.stopPropagation() + // 设置拖拽效果为复制 + if (e.dataTransfer) { + e.dataTransfer.dropEffect = 'copy' + } +} + +const handleDragLeave = (e) => { + e.preventDefault() + e.stopPropagation() + dragCounter.value-- + // 只有当计数器为0时才取消拖拽状态(处理嵌套元素) + if (dragCounter.value === 0) { + isDragging.value = false + } +} + +const handleDrop = (e) => { + e.preventDefault() + e.stopPropagation() + dragCounter.value = 0 + isDragging.value = false + + // 检查是否有选中用户 + if (!activeUser.value.sender_id) { + ElMessage({ type: 'warning', message: '请先选择用户' }) + return + } + + // 获取拖拽的文件 + const files = Array.from(e.dataTransfer.files) + + if (files.length === 0) { + return + } + + // 过滤出图片文件 + const imageFiles = files.filter(file => file.type.startsWith('image/')) + + if (imageFiles.length === 0) { + ElMessage({ type: 'warning', message: '请拖拽图片文件' }) + return + } + + // 只处理第一个图片文件 + if (imageFiles.length > 0) { + uploadImageFile(imageFiles[0]) + } +} + // 重发消息 const handleRetry = (id) => { const msg = messages.value.find((m) => m._id === id) @@ -1013,6 +1113,39 @@ watch(messages, async (newVal, oldVal) => { padding: 16px; overflow: auto; background: #f5f7fa; + position: relative; +} + +.chat-body--dragging { + background: rgba(64, 158, 255, 0.05); +} + +.drag-overlay { + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + background: rgba(64, 158, 255, 0.1); + border: 2px dashed var(--el-color-primary); + border-radius: 8px; + display: flex; + align-items: center; + justify-content: center; + z-index: 1000; + pointer-events: none; +} + +.drag-hint { + text-align: center; + color: var(--el-color-primary); + font-size: 16px; + font-weight: 500; +} + +.drag-hint p { + margin-top: 12px; + margin-bottom: 0; } /* Hide scrollbar but keep scrolling functionality */