feat: 优化消息发送逻辑和编辑器功能
- 在vite配置中启用vueDevTools工具 - 重构PanelFooter.vue中的图片消息发送逻辑,改为直接调用onSendMessage - 修改CustomEditor.vue的消息发送逻辑,支持分类型处理消息内容 - 增加编辑器引用元素的检查逻辑,避免无效引用 - 优化图片上传后的URL替换逻辑,确保编辑器内容更新
This commit is contained in:
parent
f279248a51
commit
17c1368346
@ -312,7 +312,16 @@ const handleKeydown = (event) => {
|
||||
console.log('editorHtml.value', editorHtml.value)
|
||||
// 确保编辑器内容不为空(文本、图片、文件或表情)
|
||||
// 由于我们已经在 handleInput 中处理了表情文本,editorContent.value 应该包含表情文本
|
||||
if (editorContent.value.trim()) {
|
||||
// if (editorContent.value.trim()) {
|
||||
if (true) {
|
||||
// 检查引用元素是否存在,如果不存在但 quoteData 有值,则清除 quoteData
|
||||
const editor = editorRef.value
|
||||
const quoteElement = editor?.querySelector('.editor-quote')
|
||||
if (!quoteElement && quoteData.value) {
|
||||
console.log('引用元素已被删除,但 quoteData 仍有值,清除 quoteData')
|
||||
quoteData.value = null
|
||||
}
|
||||
|
||||
// 解析并输出编辑器内容
|
||||
const messageData = parseEditorContent()
|
||||
console.log('编辑器内容解析结果:', JSON.stringify(messageData, null, 2))
|
||||
@ -335,9 +344,9 @@ const handleKeydown = (event) => {
|
||||
const sendMessage = () => {
|
||||
console.log('发送消息');
|
||||
// 检查编辑器是否有内容:文本内容(包括表情文本)
|
||||
if (!editorContent.value.trim()) {
|
||||
return
|
||||
}
|
||||
// if (!editorContent.value.trim()) {
|
||||
// return
|
||||
// }
|
||||
console.log('发送消息1');
|
||||
const messageData = parseEditorContent()
|
||||
|
||||
@ -353,38 +362,51 @@ const sendMessage = () => {
|
||||
image: quoteData.value.image
|
||||
} : null
|
||||
})
|
||||
messageData.items.forEach(item => {
|
||||
// 处理文本内容
|
||||
if (item.type === 1) {
|
||||
const data={
|
||||
items:[{
|
||||
content:item.content,
|
||||
type:1
|
||||
}],
|
||||
mentionUids:messageData.mentionUids,
|
||||
mentions:[],
|
||||
quoteId:messageData.quoteId,
|
||||
}
|
||||
console.log('发送前',data)
|
||||
emit(
|
||||
'editor-event',
|
||||
emitCall('text_event', data,(ok)=>{
|
||||
console.log('发送后',ok)
|
||||
})
|
||||
)
|
||||
}else if(item.type === 2){
|
||||
//图片消息
|
||||
}else if(item.type === 3){
|
||||
console.log('发送图片消息')
|
||||
const data={
|
||||
height:0,
|
||||
width:0,
|
||||
size:10000,
|
||||
url:item.content,
|
||||
}
|
||||
emit(
|
||||
'editor-event',
|
||||
emitCall(
|
||||
'image_event',
|
||||
data,
|
||||
(ok) => {
|
||||
// 成功发送后清空编辑器
|
||||
}
|
||||
)
|
||||
)
|
||||
}else if(item.type === 4){
|
||||
|
||||
if (editingMessage.value) {
|
||||
// 编辑消息
|
||||
emit('editor-event', {
|
||||
event: 'edit_message',
|
||||
data: {
|
||||
...messageData,
|
||||
msg_id: editingMessage.value.msg_id
|
||||
},
|
||||
callBack: (success) => {
|
||||
if (success) {
|
||||
clearEditor()
|
||||
editingMessage.value = null
|
||||
}
|
||||
}
|
||||
})
|
||||
} else {
|
||||
// 发送新消息
|
||||
const eventType = messageData.items.length > 1 ? 'mixed_event' :
|
||||
messageData.items[0].type === 1 ? 'text_event' :
|
||||
messageData.items[0].type + '_event'
|
||||
console.log('发送消息2',eventType);
|
||||
emit('editor-event', {
|
||||
event: eventType,
|
||||
data: messageData,
|
||||
callBack: (success) => {
|
||||
if (success) {
|
||||
clearEditor()
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// 解析编辑器内容
|
||||
@ -505,7 +527,7 @@ const parseEditorContent = () => {
|
||||
const result = {
|
||||
items: items.length > 0 ? items : [{ type: 1, content: '' }],
|
||||
mentionUids,
|
||||
quoteId: quoteData.value?.msg_id || 0
|
||||
quoteId: quoteElements.length > 0 && quoteData.value ? quoteData.value.msg_id ||'' : ''
|
||||
}
|
||||
|
||||
// 如果有引用信息,添加到结果中
|
||||
@ -632,9 +654,19 @@ async function onUploadFile(e) {
|
||||
// 上传图片并获取永久URL
|
||||
uploadImg(form).then(({ code, data, message }) => {
|
||||
if (code == 0) {
|
||||
// 上传成功后,可以将临时URL替换为永久URL
|
||||
// 但这里我们不做替换,因为临时URL在当前会话中已足够使用
|
||||
// 上传成功后,将临时URL替换为永久URL
|
||||
console.log('图片上传成功:', data.ori_url);
|
||||
|
||||
// 查找编辑器中刚插入的图片元素并替换其src为永久URL
|
||||
const editorImages = editorRef.value.querySelectorAll('img.editor-image');
|
||||
// 查找最后插入的图片(通常是最近添加的那个)
|
||||
const lastImage = editorImages[editorImages.length - 1];
|
||||
if (lastImage && lastImage.src === tempUrl) {
|
||||
// 替换为永久URL
|
||||
lastImage.src = data.ori_url;
|
||||
// 触发输入事件更新编辑器内容
|
||||
handleInput({ target: editorRef.value });
|
||||
}
|
||||
} else {
|
||||
window['$message'].error(message);
|
||||
}
|
||||
|
@ -10,13 +10,13 @@ import {
|
||||
} from '@/store'
|
||||
import ws from '@/connect'
|
||||
import { ServePublishMessage, ServeSendVote } from '@/api/chat'
|
||||
import CustomEditor from '@/components/editor/CustomEditor.vue'
|
||||
import { throttle, getVideoImage } from '@/utils/common'
|
||||
import { parseTime } from '@/utils/datetime'
|
||||
import Editor from '@/components/editor/Editor.vue'
|
||||
import MultiSelectFooter from './MultiSelectFooter.vue'
|
||||
import HistoryRecord from '@/components/talk/HistoryRecord.vue'
|
||||
import {scrollToBottom} from '@/utils/dom.ts'
|
||||
import CustomEditor from '@/components/editor/CustomEditor.vue'
|
||||
const userStore = useUserStore()
|
||||
const talkStore = useTalkStore()
|
||||
const editorStore = useEditorStore()
|
||||
@ -61,11 +61,11 @@ const onSendMessage = (data = {}, callBack: any) => {
|
||||
}
|
||||
|
||||
ServePublishMessage(message)
|
||||
.then(({ code, message }) => {
|
||||
.then(({ code, message, msg }) => {
|
||||
if (code == 200) {
|
||||
callBack(true)
|
||||
} else {
|
||||
window['$message'].warning(message)
|
||||
window['$message'].warning(message || msg)
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
@ -95,60 +95,8 @@ const onSendTextEvent = throttle((value: any) => {
|
||||
}, 1000)
|
||||
|
||||
// 发送图片消息
|
||||
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])
|
||||
|
||||
}
|
||||
)
|
||||
const onSendImageEvent = ({ data, callBack }) => {
|
||||
onSendMessage({ type: 'image', ...data }, callBack)
|
||||
}
|
||||
|
||||
// 发送视频消息
|
||||
|
@ -46,9 +46,9 @@ export default defineConfig(({ mode }) => {
|
||||
vueJsx({}),
|
||||
compressPlugin(),
|
||||
UnoCSS(),
|
||||
// vueDevTools({
|
||||
// launchEditor: 'trae',
|
||||
// })
|
||||
vueDevTools({
|
||||
launchEditor: 'trae',
|
||||
})
|
||||
],
|
||||
define: {
|
||||
__APP_ENV__: env.APP_ENV
|
||||
|
Loading…
Reference in New Issue
Block a user