feat: 优化消息发送逻辑和编辑器功能

- 在vite配置中启用vueDevTools工具
- 重构PanelFooter.vue中的图片消息发送逻辑,改为直接调用onSendMessage
- 修改CustomEditor.vue的消息发送逻辑,支持分类型处理消息内容
- 增加编辑器引用元素的检查逻辑,避免无效引用
- 优化图片上传后的URL替换逻辑,确保编辑器内容更新
This commit is contained in:
Phoenix 2025-06-06 11:52:55 +08:00
parent f279248a51
commit 17c1368346
3 changed files with 76 additions and 96 deletions

View File

@ -312,7 +312,16 @@ const handleKeydown = (event) => {
console.log('editorHtml.value', editorHtml.value) console.log('editorHtml.value', editorHtml.value)
// //
// handleInput editorContent.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() const messageData = parseEditorContent()
console.log('编辑器内容解析结果:', JSON.stringify(messageData, null, 2)) console.log('编辑器内容解析结果:', JSON.stringify(messageData, null, 2))
@ -335,9 +344,9 @@ const handleKeydown = (event) => {
const sendMessage = () => { const sendMessage = () => {
console.log('发送消息'); console.log('发送消息');
// //
if (!editorContent.value.trim()) { // if (!editorContent.value.trim()) {
return // return
} // }
console.log('发送消息1'); console.log('发送消息1');
const messageData = parseEditorContent() const messageData = parseEditorContent()
@ -353,38 +362,51 @@ const sendMessage = () => {
image: quoteData.value.image image: quoteData.value.image
} : null } : null
}) })
messageData.items.forEach(item => {
if (editingMessage.value) { //
// if (item.type === 1) {
emit('editor-event', { const data={
event: 'edit_message', items:[{
data: { content:item.content,
...messageData, type:1
msg_id: editingMessage.value.msg_id }],
}, mentionUids:messageData.mentionUids,
callBack: (success) => { mentions:[],
if (success) { quoteId:messageData.quoteId,
clearEditor()
editingMessage.value = null
}
} }
}) console.log('发送前',data)
} else { emit(
// 'editor-event',
const eventType = messageData.items.length > 1 ? 'mixed_event' : emitCall('text_event', data,(ok)=>{
messageData.items[0].type === 1 ? 'text_event' : console.log('发送后',ok)
messageData.items[0].type + '_event' })
console.log('发送消息2',eventType); )
emit('editor-event', { }else if(item.type === 2){
event: eventType, //
data: messageData, }else if(item.type === 3){
callBack: (success) => { console.log('发送图片消息')
if (success) { const data={
clearEditor() height:0,
width:0,
size:10000,
url:item.content,
} }
emit(
'editor-event',
emitCall(
'image_event',
data,
(ok) => {
//
}
)
)
}else if(item.type === 4){
} }
}) })
}
} }
// //
@ -505,7 +527,7 @@ const parseEditorContent = () => {
const result = { const result = {
items: items.length > 0 ? items : [{ type: 1, content: '' }], items: items.length > 0 ? items : [{ type: 1, content: '' }],
mentionUids, 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 // URL
uploadImg(form).then(({ code, data, message }) => { uploadImg(form).then(({ code, data, message }) => {
if (code == 0) { if (code == 0) {
// URLURL // URLURL
// URL使
console.log('图片上传成功:', data.ori_url); console.log('图片上传成功:', data.ori_url);
// srcURL
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 { } else {
window['$message'].error(message); window['$message'].error(message);
} }

View File

@ -10,13 +10,13 @@ import {
} from '@/store' } from '@/store'
import ws from '@/connect' import ws from '@/connect'
import { ServePublishMessage, ServeSendVote } from '@/api/chat' import { ServePublishMessage, ServeSendVote } from '@/api/chat'
import CustomEditor from '@/components/editor/CustomEditor.vue'
import { throttle, getVideoImage } from '@/utils/common' import { throttle, getVideoImage } from '@/utils/common'
import { parseTime } from '@/utils/datetime' import { parseTime } from '@/utils/datetime'
import Editor from '@/components/editor/Editor.vue' import Editor from '@/components/editor/Editor.vue'
import MultiSelectFooter from './MultiSelectFooter.vue' import MultiSelectFooter from './MultiSelectFooter.vue'
import HistoryRecord from '@/components/talk/HistoryRecord.vue' import HistoryRecord from '@/components/talk/HistoryRecord.vue'
import {scrollToBottom} from '@/utils/dom.ts' import {scrollToBottom} from '@/utils/dom.ts'
import CustomEditor from '@/components/editor/CustomEditor.vue'
const userStore = useUserStore() const userStore = useUserStore()
const talkStore = useTalkStore() const talkStore = useTalkStore()
const editorStore = useEditorStore() const editorStore = useEditorStore()
@ -61,11 +61,11 @@ const onSendMessage = (data = {}, callBack: any) => {
} }
ServePublishMessage(message) ServePublishMessage(message)
.then(({ code, message }) => { .then(({ code, message, msg }) => {
if (code == 200) { if (code == 200) {
callBack(true) callBack(true)
} else { } else {
window['$message'].warning(message) window['$message'].warning(message || msg)
} }
}) })
.catch(() => { .catch(() => {
@ -95,60 +95,8 @@ const onSendTextEvent = throttle((value: any) => {
}, 1000) }, 1000)
// //
const onSendImageEvent = ({ data }) => { const onSendImageEvent = ({ data, callBack }) => {
console.log('onSendImageEvent') onSendMessage({ type: 'image', ...data }, callBack)
// 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])
}
)
} }
// //

View File

@ -46,9 +46,9 @@ export default defineConfig(({ mode }) => {
vueJsx({}), vueJsx({}),
compressPlugin(), compressPlugin(),
UnoCSS(), UnoCSS(),
// vueDevTools({ vueDevTools({
// launchEditor: 'trae', launchEditor: 'trae',
// }) })
], ],
define: { define: {
__APP_ENV__: env.APP_ENV __APP_ENV__: env.APP_ENV