refactor(TiptapEditor): 重构消息转换逻辑以支持多消息分段处理

重构 tiptapToMessage 函数,将单条消息处理改为支持多条消息分段处理
优化消息内容处理流程,添加文本缓冲区和图片单独处理逻辑
简化消息发送逻辑,移除 msgType 判断改为直接处理不同类型消息
清理已注释的导航功能代码
This commit is contained in:
Phoenix 2025-07-02 13:34:23 +08:00
parent dd170cb50d
commit 8be8afc675

View File

@ -457,71 +457,106 @@ function onRecorderEvent(file) {
// Tiptap // Tiptap
function tiptapToMessage() { function tiptapToMessage() {
if (!editor.value) return { items: [], mentions: [], mentionUids: [], quoteId: '', msgType: 1 } if (!editor.value) return []
const json = editor.value.getJSON() const json = editor.value.getJSON()
const resp = { const messages = []
items: [], let quoteId = null
mentions: [], let currentTextBuffer = ''
mentionUids: [], let currentMentions = []
quoteId: '', let currentMentionUids = new Set()
msgType: 1
}
// const flushTextBuffer = () => {
const quoteNode = json.content?.find((node) => node.type === 'quote') const content = currentTextBuffer.trim()
if (quoteNode) { if (content) {
resp.quoteId = quoteNode.attrs.id const data = {
} items: [{ type: 1, content: content }],
mentions: [...currentMentions],
// mentionUids: Array.from(currentMentionUids)
let textContent = '' }
let hasImage = false if (quoteId) {
data.quoteId = quoteId
const processNode = (node) => { quoteId = null
if (node.type === 'text') { }
textContent += node.text messages.push({ type: 'text', data })
} else if (node.type === 'mention') {
textContent += ` @${node.attrs.label} `
resp.mentions.push({
name: `@${node.attrs.label}`,
atid: parseInt(node.attrs.id)
})
} else if (node.type === 'emoji') {
textContent += node.attrs.alt
} else if (node.type === 'image') {
hasImage = true
resp.items.push({
type: 3,
content: node.attrs.src
})
} else if (node.content) {
node.content.forEach(processNode)
} }
currentTextBuffer = ''
currentMentions = []
currentMentionUids.clear()
} }
if (json.content) { const processInlines = nodes => {
json.content.forEach(processNode) nodes.forEach(node => {
} if (node.type === 'text') {
currentTextBuffer += node.text
// items } else if (node.type === 'mention') {
if (textContent.trim()) { currentTextBuffer += `@${node.attrs.label} `
resp.items.unshift({ const uid = parseInt(node.attrs.id)
type: 1, if (!currentMentionUids.has(uid)) {
content: textContent.trim() currentMentionUids.add(uid)
currentMentions.push({ name: `@${node.attrs.label}`, atid: uid })
}
} else if (node.type === 'emoji') {
currentTextBuffer += node.attrs.alt
} else if (node.type === 'hardBreak') {
currentTextBuffer += '\n'
} else if (node.type === 'image') {
//
flushTextBuffer()
const data = {
...getImageInfo(node.attrs.src),
url: node.attrs.src
}
if (quoteId) {
data.quoteId = quoteId
quoteId = null
}
messages.push({ type: 'image', data })
}
}) })
} }
// if (json.content) {
if (resp.items.length > 1) { const quoteIndex = json.content.findIndex(node => node.type === 'quote')
resp.msgType = 12 // if (quoteIndex > -1) {
} else if (resp.items.length === 1) { quoteId = json.content[quoteIndex].attrs.id
resp.msgType = resp.items[0].type json.content.splice(quoteIndex, 1)
}
json.content.forEach(node => {
if (node.type === 'paragraph') {
if (node.content) {
processInlines(node.content)
}
currentTextBuffer += '\n' // Add newline after each paragraph
} else if (node.type === 'image') {
flushTextBuffer()
const data = {
...getImageInfo(node.attrs.src),
url: node.attrs.src
}
if (quoteId) {
data.quoteId = quoteId
quoteId = null
}
messages.push({ type: 'image', data })
}
})
} }
resp.mentionUids = resp.mentions.map((item) => item.atid) flushTextBuffer()
return resp if (messages.length > 0) {
const lastMessage = messages[messages.length - 1]
if (lastMessage.type === 'text') {
lastMessage.data.items[0].content = lastMessage.data.items[0].content.trim()
if (!lastMessage.data.items[0].content) {
messages.pop()
}
}
}
return messages
} }
// Tiptap // Tiptap
@ -550,52 +585,36 @@ function isEditorEmpty() {
* 根据编辑器内容类型发送不同类型的消息 * 根据编辑器内容类型发送不同类型的消息
*/ */
function onSendMessage() { function onSendMessage() {
if (!editor.value) return if (!editor.value || isEditorEmpty()) return
if (isEditorEmpty()) return const messages = tiptapToMessage()
const data = tiptapToMessage() if (messages.length === 0) {
return
if (data.items.length === 0 || (data.items[0].type === 1 && !data.items[0].content.trim())) {
return //
} }
switch (data.msgType) { let canClear = true
case 1: // messages.forEach(msg => {
if (data.items[0].content.length > 1024) { if (msg.type === 'text') {
return window['$message'].info('发送内容超长,请分条发送') if (msg.data.items[0].content.length > 1024) {
window['$message'].info('发送内容超长,请分条发送')
canClear = false
return
} }
emit('editor-event', emitCall('text_event', msg.data))
} else if (msg.type === 'image') {
const data = {
height: 0,
width: 0,
size: 10000,
url: msg.data.url,
}
emit('editor-event', emitCall('image_event', data))
}
})
// if (canClear) {
emit( editor.value?.commands.clearContent(true)
'editor-event',
emitCall('text_event', data, (ok) => {
ok && editor.value?.commands.clearContent(true) //
})
)
break
case 3: //
//
emit(
'editor-event',
emitCall(
'image_event',
{ ...getImageInfo(data.items[0].content), url: data.items[0].content, size: 10000 },
(ok) => {
ok && editor.value?.commands.clearContent(true) //
}
)
)
break
case 12: //
//
emit(
'editor-event',
emitCall('mixed_event', data, (ok) => {
ok && editor.value?.commands.clearContent(true) //
})
)
break
} }
} }
@ -728,45 +747,7 @@ const navs = reactive([
uploadFileRef.value.click() // uploadFileRef.value.click() //
} }
}, },
//
// {
// title: '',
// icon: markRaw(SourceCode),
// show: true,
// click: () => {
// isShowEditorCode.value = true
// }
// },
// {
// title: '',
// icon: markRaw(IconVoice),
// show: true,
// click: () => {
// isShowEditorRecorder.value = true
// }
// },
// {
// title: '',
// icon: markRaw(Local),
// show: true,
// click: () => {}
// },
// {
// title: '',
// icon: markRaw(Ranking),
// show: computed(() => props.vote),
// click: () => {
// isShowEditorVote.value = true
// }
// },
// {
// title: '',
// icon: markRaw(History),
// show: true,
// click: () => {
// emit('editor-event', emitCall('history_event'))
// }
// }
]) ])
// 稿 // 稿