wewe
This commit is contained in:
parent
dcaa6a1f25
commit
7f62f4db8d
@ -5,10 +5,25 @@
|
|||||||
@change="onSelectUser" />
|
@change="onSelectUser" />
|
||||||
</div>
|
</div>
|
||||||
<div class="right-panel">
|
<div class="right-panel">
|
||||||
<div :class="['chat-body', { 'chat-body--loading': isLoadingMessages }]" ref="chatBody"
|
<div :class="['chat-body', { 'chat-body--loading': isLoadingMessages, 'chat-body--dragging': isDragging }]" ref="chatBody"
|
||||||
@scroll="handleScroll">
|
@scroll="handleScroll"
|
||||||
|
@dragover.prevent="handleDragOver"
|
||||||
|
@dragenter.prevent="handleDragEnter"
|
||||||
|
@dragleave.prevent="handleDragLeave"
|
||||||
|
@drop.prevent="handleDrop">
|
||||||
<!-- 加载更多提示 -->
|
<!-- 加载更多提示 -->
|
||||||
<div v-if="loadingMore" class="loading-more">加载中...</div>
|
<div v-if="loadingMore" class="loading-more">加载中...</div>
|
||||||
|
<!-- 拖拽提示 -->
|
||||||
|
<div v-if="isDragging" class="drag-overlay">
|
||||||
|
<div class="drag-hint">
|
||||||
|
<el-icon style="font-size: 48px; color: var(--el-color-primary);">
|
||||||
|
<svg class="icon" aria-hidden="true">
|
||||||
|
<use xlink:href="#icon-tupian1"></use>
|
||||||
|
</svg>
|
||||||
|
</el-icon>
|
||||||
|
<p>松开鼠标发送图片</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<WxChatRecord :msgList="messages" :sendeInfo="sendeInfo" msgType="user" @retry="handleRetry" />
|
<WxChatRecord :msgList="messages" :sendeInfo="sendeInfo" msgType="user" @retry="handleRetry" />
|
||||||
</div>
|
</div>
|
||||||
@ -92,6 +107,8 @@ const messageTimer = ref(null) // 定时器实例
|
|||||||
const isSending = ref(false) // 防止重复发送
|
const isSending = ref(false) // 防止重复发送
|
||||||
const lastSendTime = ref(0) // 最后发送时间,用于防抖
|
const lastSendTime = ref(0) // 最后发送时间,用于防抖
|
||||||
const isUploading = ref(false) // 防止重复上传
|
const isUploading = ref(false) // 防止重复上传
|
||||||
|
const isDragging = ref(false) // 拖拽状态
|
||||||
|
const dragCounter = ref(0) // 拖拽计数器,用于处理嵌套元素
|
||||||
// 小程序状态轮询定时器
|
// 小程序状态轮询定时器
|
||||||
const appStatusTimer = ref(null)
|
const appStatusTimer = ref(null)
|
||||||
|
|
||||||
@ -556,16 +573,28 @@ const triggerImageInput = () => {
|
|||||||
imageInput.value && imageInput.value.click()
|
imageInput.value && imageInput.value.click()
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleImageChange = (e) => {
|
// 提取图片上传逻辑为可复用函数
|
||||||
const file = e.target.files[0]
|
const uploadImageFile = (file) => {
|
||||||
if (!file) return
|
if (!file) return
|
||||||
|
|
||||||
|
// 检查是否有选中用户
|
||||||
|
if (!activeUser.value.sender_id) {
|
||||||
|
ElMessage({ type: 'warning', message: '请先选择用户' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 防止重复上传
|
// 防止重复上传
|
||||||
if (isUploading.value) {
|
if (isUploading.value) {
|
||||||
console.log('图片正在上传中,请稍候')
|
console.log('图片正在上传中,请稍候')
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 检查文件类型是否为图片
|
||||||
|
if (!file.type.startsWith('image/')) {
|
||||||
|
ElMessage({ type: 'error', message: '只能上传图片文件' })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
// 检查文件大小(限制为10MB)
|
// 检查文件大小(限制为10MB)
|
||||||
if (file.size > 10 * 1024 * 1024) {
|
if (file.size > 10 * 1024 * 1024) {
|
||||||
ElMessage({ type: 'error', message: '图片大小不能超过10MB' })
|
ElMessage({ type: 'error', message: '图片大小不能超过10MB' })
|
||||||
@ -592,7 +621,6 @@ const handleImageChange = (e) => {
|
|||||||
_tempImageFile: file // 保存文件信息用于匹配
|
_tempImageFile: file // 保存文件信息用于匹配
|
||||||
}
|
}
|
||||||
messages.value.push(msg)
|
messages.value.push(msg)
|
||||||
e.target.value = ''
|
|
||||||
|
|
||||||
// 滚动到底部
|
// 滚动到底部
|
||||||
setTimeout(() => scrollToBottom(), 100)
|
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 handleRetry = (id) => {
|
||||||
const msg = messages.value.find((m) => m._id === id)
|
const msg = messages.value.find((m) => m._id === id)
|
||||||
@ -1013,6 +1113,39 @@ watch(messages, async (newVal, oldVal) => {
|
|||||||
padding: 16px;
|
padding: 16px;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
background: #f5f7fa;
|
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 */
|
/* Hide scrollbar but keep scrolling functionality */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user