feat(im): 优化 message 的导入

im
YunaiV 2026-04-28 08:48:38 +08:00
parent 56b0630847
commit 122b1ba748
6 changed files with 25 additions and 20 deletions

View File

@ -51,7 +51,7 @@
<script lang="ts" setup>
import { computed, onMounted, onUnmounted, watch } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { useMessage } from '@/hooks/web/useMessage'
import { DICT_TYPE, getDictLabel } from '@/utils/dict'
import { getSimpleUser } from '@/api/system/user'
@ -70,6 +70,7 @@ const conversationStore = useConversationStore()
const friendStore = useFriendStore()
const userStore = useUserStore()
const router = useRouter()
const message = useMessage()
const card = computed(() => uiStore.userInfoCard)
const user = computed(() => card.value.user)
@ -161,14 +162,14 @@ async function handleAddFriend() {
nickname: user.value.nickname,
avatar: user.value.avatar
})
ElMessage.success('已添加好友')
message.success('已添加好友')
} catch (e: any) {
console.error(
'[IM] 添加好友失败',
{ userId: user.value?.id, nickname: user.value?.nickname },
e
)
ElMessage.error(e?.message || '添加好友失败')
message.error(e?.message || '添加好友失败')
}
}
</script>

View File

@ -71,10 +71,10 @@
<script lang="ts" setup>
import { computed } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import dayjs from 'dayjs'
import Icon from '@/components/Icon/src/Icon.vue'
import { useMessage } from '@/hooks/web/useMessage'
import { useConversationStore } from '../../../../store/conversationStore'
import { useFriendStore } from '../../../../store/friendStore'
import { useGroupStore } from '../../../../store/groupStore'
@ -96,6 +96,7 @@ const conversationStore = useConversationStore()
const friendStore = useFriendStore()
const groupStore = useGroupStore()
const uiStore = useImUiStore()
const message = useMessage()
const isActive = computed(
() =>
@ -163,7 +164,7 @@ function handleMuted() {
: groupStore.setMuted(targetId, next)
sync.catch((e) => {
console.error('[IM] 切换免打扰失败', e)
ElMessage.error('切换免打扰失败')
message.error('切换免打扰失败')
conversationStore.setMuted(type, targetId, !next)
})
}
@ -171,9 +172,7 @@ function handleMuted() {
/** 删除会话:二次确认后软删(用户取消走 catch 静默) */
async function handleDelete() {
try {
await ElMessageBox.confirm(`确定删除与「${props.conversation.name}」的会话吗?`, '删除会话', {
type: 'warning'
})
await message.confirm(`确定删除与「${props.conversation.name}」的会话吗?`, '删除会话')
conversationStore.removeConversation(props.conversation.type, props.conversation.targetId)
} catch {
//

View File

@ -117,7 +117,7 @@
<script lang="ts" setup>
import { computed, onBeforeUnmount, onMounted, ref, useTemplateRef } from 'vue'
import { ElMessage } from 'element-plus'
import { useMessage } from '@/hooks/web/useMessage'
import Icon from '@/components/Icon/src/Icon.vue'
import { updateFile } from '@/api/infra/file'
@ -142,6 +142,7 @@ defineOptions({ name: 'ImMessageInput' })
const conversationStore = useConversationStore()
const groupStore = useGroupStore()
const { send, sendRaw } = useMessageSender()
const message = useMessage()
const editorRef = useTemplateRef<HTMLDivElement>('editorRef')
const imageInputRef = useTemplateRef<HTMLInputElement>('imageInputRef')
@ -627,7 +628,7 @@ async function uploadAndSendImage(file: File) {
await sendRaw(ImMessageType.IMAGE, serializeMessage<ImageMessage>({ url }))
} catch (err) {
console.error('[IM] 图片上传失败:', err)
ElMessage.error('图片上传失败')
message.error('图片上传失败')
}
}
@ -646,7 +647,7 @@ async function uploadAndSendFile(file: File) {
)
} catch (err) {
console.error('[IM] 文件上传失败:', err)
ElMessage.error('文件上传失败')
message.error('文件上传失败')
}
}
@ -689,7 +690,7 @@ async function onVoiceSend(payload: { blob: Blob; duration: number }) {
)
} catch (err) {
console.error('[IM] 语音上传失败:', err)
ElMessage.error('语音上传失败')
message.error('语音上传失败')
}
}
</script>

View File

@ -36,7 +36,7 @@
<script lang="ts" setup>
import { computed, onBeforeUnmount, ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { useMessage } from '@/hooks/web/useMessage'
import { formatSeconds } from '@/utils/formatTime'
defineOptions({ name: 'ImVoiceRecorder' })
@ -56,6 +56,8 @@ const emit = defineEmits<{
send: [payload: { blob: Blob; duration: number }] // Blob
}>()
const message = useMessage()
const visible = computed({
get: () => props.modelValue,
set: (v) => emit('update:modelValue', v)
@ -76,13 +78,13 @@ watch(visible, (v) => {
async function startRecord() {
if (!navigator.mediaDevices?.getUserMedia) {
ElMessage.error('当前浏览器不支持录音(需要 HTTPS 或 localhost')
message.error('当前浏览器不支持录音(需要 HTTPS 或 localhost')
return
}
try {
mediaStream = await navigator.mediaDevices.getUserMedia({ audio: true })
} catch (e) {
ElMessage.error('无法获取麦克风权限')
message.error('无法获取麦克风权限')
return
}
audioChunks = []

View File

@ -297,7 +297,7 @@
<script lang="ts" setup>
import { computed, ref, watch } from 'vue'
import { ElMessage } from 'element-plus'
import { useMessage } from '@/hooks/web/useMessage'
import dayjs from 'dayjs'
import Icon from '@/components/Icon/src/Icon.vue'
@ -338,6 +338,7 @@ const userStore = useUserStore()
const conversationStore = useConversationStore()
const groupStore = useGroupStore()
const { convertPrivateMessage, convertGroupMessage } = useMessagePuller()
const message = useMessage()
const visible = computed({
get: () => props.modelValue,
@ -568,7 +569,7 @@ async function loadEarlier() {
)
} catch (error) {
console.error('[IM] 加载更早历史消息失败', error)
ElMessage.error('加载历史消息失败')
message.error('加载历史消息失败')
} finally {
loadingMore.value = false
}

View File

@ -211,9 +211,8 @@
<script lang="ts" setup>
import { computed, onBeforeUnmount, ref } from 'vue'
import { ElMessageBox } from 'element-plus'
import Icon from '@/components/Icon/src/Icon.vue'
import { useMessage } from '@/hooks/web/useMessage'
import {
ImMessageType,
@ -254,6 +253,8 @@ const conversationStore = useConversationStore()
const groupStore = useGroupStore()
const uiStore = useImUiStore()
const { recall, sendRaw } = useMessageSender()
// confirm message props.message vue/no-dupe-keys
const { confirm: confirmDialog } = useMessage()
/** 是否已撤回pull / WS 两路都会调 recallMessage 把原消息更新为 type=RECALL渲染只需识别 type */
const isRecall = computed(() => props.message.type === ImMessageType.RECALL)
@ -527,7 +528,7 @@ async function handleContextMenu(e: MouseEvent) {
*/
async function handleRecall() {
try {
await ElMessageBox.confirm('确定要撤回这条消息吗?', '撤回消息', { type: 'warning' })
await confirmDialog('确定要撤回这条消息吗?', '撤回消息')
await recall(props.message)
} catch {
// ElMessageBox reject