feat(消息组件): 优化图片消息上传体验并修复文件扩展名获取
1. 在图片消息组件中添加上传进度显示和加载状态 2. 重构图片上传逻辑,先显示本地预览再上传 3. 修复文件消息组件中从文件名获取扩展名改为从文件路径获取 4. 根据消息浮动方向调整提及文本颜色 重构了图片上传流程,现在会先显示本地预览图片,然后在上传过程中显示进度条。同时修复了文件扩展名获取逻辑,现在从文件路径而非文件名获取扩展名。优化了提及文本的颜色显示,使其根据消息浮动方向(左/右)显示不同颜色。
This commit is contained in:
parent
f511244d59
commit
ef0eb903a7
@ -363,22 +363,9 @@ async function onUploadFile(e: any) {
|
||||
console.log("文件类型"+file.type)
|
||||
if (file.type.indexOf('image/') === 0) {
|
||||
console.log("进入图片")
|
||||
// 处理图片文件
|
||||
const quill = getQuill()
|
||||
let index = getQuillSelectionIndex()
|
||||
|
||||
// 删除编辑器中多余的换行符
|
||||
if (index == 1 && quill.getLength() == 1 && quill.getText(0, 1) == '\n') {
|
||||
quill.deleteText(0, 1)
|
||||
index = 0
|
||||
}
|
||||
|
||||
// 上传图片并插入到编辑器中
|
||||
let src = await onUploadImage(file)
|
||||
if (src) {
|
||||
quill.insertEmbed(index, 'image', src)
|
||||
quill.setSelection(index + 1)
|
||||
}
|
||||
// 处理图片文件 - 立即显示临时消息,然后上传
|
||||
let fn = emitCall('image_event', file, () => {})
|
||||
emit('editor-event', fn)
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ const PPT_EXTENSIONS = ['PPT', 'PPTX', 'PPS', 'PPSX']
|
||||
|
||||
// 获取文件类型信息
|
||||
const fileInfo = computed(() => {
|
||||
const extension = getFileExtension(props.extra.name)
|
||||
const extension = getFileExtension(props.extra.path)
|
||||
if (EXCEL_EXTENSIONS.includes(extension)) {
|
||||
return fileTypes.EXCEL
|
||||
}
|
||||
@ -63,8 +63,8 @@ const fileInfo = computed(() => {
|
||||
})
|
||||
|
||||
// 获取文件扩展名
|
||||
function getFileExtension(filename) {
|
||||
const parts = filename.split('.')
|
||||
function getFileExtension(filepath) {
|
||||
const parts = filepath.split('.')
|
||||
return parts.length > 1 ? parts.pop().toUpperCase() : ''
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
<script lang="ts" setup>
|
||||
import { NImage } from 'naive-ui'
|
||||
import { NImage, NSpin } from 'naive-ui'
|
||||
import { getImageInfo } from '@/utils/functions'
|
||||
import { ITalkRecordExtraImage, ITalkRecord } from '@/types/chat'
|
||||
|
||||
defineProps<{
|
||||
const props = defineProps<{
|
||||
extra: ITalkRecordExtraImage
|
||||
data: ITalkRecord
|
||||
maxWidth?: Boolean
|
||||
@ -35,7 +35,13 @@ const img = (src: string, width = 200) => {
|
||||
:class="{ left: data.float === 'left' }"
|
||||
:style="img(extra.url, 350)"
|
||||
>
|
||||
<n-image class="h-149px" :src="extra.url" />
|
||||
<div class="image-container">
|
||||
<n-image class="h-149px" :src="extra.url" />
|
||||
<!-- 上传中的loading蒙版 -->
|
||||
<div v-if="props.extra.is_uploading" class="loading-overlay">
|
||||
<n-spin size="large" />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
||||
<style lang="less" scoped>
|
||||
@ -44,11 +50,32 @@ const img = (src: string, width = 200) => {
|
||||
padding: 5px;
|
||||
border-radius: 5px;
|
||||
background: var(--im-message-left-bg-color);
|
||||
height:149px
|
||||
height:149px;
|
||||
|
||||
&.left {
|
||||
background: var(--im-message-right-bg-color);
|
||||
}
|
||||
|
||||
.image-container {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.loading-overlay {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 5px;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
:deep(.n-image img) {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
@ -17,7 +17,7 @@ let textContent = props.extra?.content || ''
|
||||
textContent = textReplaceLink(textContent)
|
||||
|
||||
if (props.data.talk_type == 2) {
|
||||
textContent = textReplaceMention(textContent, '#462AA0')
|
||||
textContent = textReplaceMention(textContent, float==='right'?'#fff':'#462AA0')
|
||||
}
|
||||
|
||||
textContent = textReplaceEmoji(textContent)
|
||||
|
@ -94,8 +94,60 @@ const onSendTextEvent = throttle((value: any) => {
|
||||
}, 1000)
|
||||
|
||||
// 发送图片消息
|
||||
const onSendImageEvent = ({ data, callBack }) => {
|
||||
onSendMessage({ type: 'image', ...data }, callBack)
|
||||
const onSendImageEvent = ({ data }) => {
|
||||
console.log('onSendImageEvent')
|
||||
|
||||
// 先创建一个带有上传ID的临时消息对象,用于显示进度
|
||||
const uploadId = `image-${Date.now()}-${Math.floor(Math.random() * 1000)}`
|
||||
|
||||
// 创建本地预览URL
|
||||
const previewUrl = URL.createObjectURL(data)
|
||||
|
||||
// 创建临时消息记录
|
||||
const tempMessage = {
|
||||
msg_id: uploadId,
|
||||
sequence: Date.now(),
|
||||
talk_type: props.talk_type,
|
||||
msg_type: 3, // 图片消息类型
|
||||
user_id: props.uid,
|
||||
receiver_id: props.receiver_id,
|
||||
is_revoke: 0,
|
||||
is_mark: 0,
|
||||
is_read: 1,
|
||||
content: '',
|
||||
created_at: parseTime(new Date(), '{y}-{m}-{d} {h}:{i}'),
|
||||
extra: {
|
||||
url: previewUrl, // 使用本地预览URL
|
||||
size: data.size,
|
||||
is_uploading: true,
|
||||
upload_id: uploadId,
|
||||
percentage: 0
|
||||
},
|
||||
isCheck: false,
|
||||
send_status: 1,
|
||||
float: 'right' // 我发送的消息显示在右侧
|
||||
}
|
||||
|
||||
// 直接添加到对话记录中
|
||||
dialogueStore.addDialogueRecord(tempMessage)
|
||||
nextTick(()=>{
|
||||
scrollToBottom()
|
||||
})
|
||||
uploadsStore.initUploadFile(
|
||||
data,
|
||||
props.talk_type,
|
||||
props.receiver_id,
|
||||
uploadId,
|
||||
async (percentage) => {
|
||||
dialogueStore.updateUploadProgress(uploadId, percentage)
|
||||
},
|
||||
async () => {
|
||||
// 清理本地预览URL
|
||||
URL.revokeObjectURL(previewUrl)
|
||||
dialogueStore.batchDelDialogueRecord([uploadId])
|
||||
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
// 发送视频消息
|
||||
|
Loading…
Reference in New Issue
Block a user