uniapp-app/pages_app/patientMsg/conversation-list/conversation-item-last-msg-content.vue
2025-09-24 11:37:39 +08:00

273 lines
6.3 KiB
Vue

<template>
<div>
<div
v-if="
props.lastMessage.lastMessageState ===
V2NIMConst.V2NIMLastMessageState.V2NIM_MESSAGE_STATUS_REVOKE
"
>
{{ t('recall') }}
</div>
<div
v-else-if="
props.lastMessage.messageType ===
V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_NOTIFICATION
"
>
{{ t('conversationNotificationText') }}
</div>
<div
v-else-if="
props.lastMessage.sendingState ===
V2NIMConst.V2NIMMessageSendingState.V2NIM_MESSAGE_SENDING_STATE_FAILED
"
>
{{ t('conversationSendFailText') }}
</div>
<div
v-else-if="
props.lastMessage.messageType ===
V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_FILE
"
>
{{ translateMsg('fileMsgText') }}
</div>
<div
v-else-if="
props.lastMessage.messageType ===
V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_IMAGE
"
>
{{ translateMsg('imgMsgText') }}
</div>
<div
v-else-if="
props.lastMessage.messageType ===
V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_CUSTOM
"
>
{{ props.lastMessage.text || translateMsg('customMsgText') }}
</div>
<div
v-else-if="
props.lastMessage.messageType ===
V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_AUDIO
"
>
{{ translateMsg('audioMsgText') }}
</div>
<div
v-else-if="
props.lastMessage.messageType ===
V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_CALL
"
>
{{ translateMsg('callMsgText') }}
</div>
<div
v-else-if="
props.lastMessage.messageType ===
V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_LOCATION
"
>
{{ translateMsg('geoMsgText') }}
</div>
<div
v-else-if="
props.lastMessage.messageType ===
V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_ROBOT
"
>
{{ translateMsg('robotMsgText') }}
</div>
<div
v-else-if="
props.lastMessage.messageType ===
V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_TIPS
"
>
{{ translateMsg('tipMsgText') }}
</div>
<div
v-else-if="
props.lastMessage.messageType ===
V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_VIDEO
"
>
{{ translateMsg('videoMsgText') }}
</div>
<div
v-else-if="
props.lastMessage.messageType ===
V2NIMConst.V2NIMMessageType.V2NIM_MESSAGE_TYPE_TEXT
"
class="msg-conversation-text-wrap"
>
<template v-for="item in textArr" :key="item.key">
<template v-if="item.type === 'text'">
<span class="msg-conversation-text">{{ item.value }}</span>
</template>
<template v-else-if="item.type === 'emoji'">
<span
:class="
isWxApp
? 'msg-conversation-text-emoji-wx'
: 'msg-conversation-text-emoji'
"
>
<Icon :type="EMOJI_ICON_MAP_CONFIG[item.value]" :size="16" />
</span>
</template>
</template>
</div>
</div>
</template>
<script lang="ts" setup>
/** 会话列表Item 外漏消息组件 */
import { computed } from 'vue'
import Icon from '@/components/Icon.vue'
import { V2NIMConst } from '@/utils/im/nim'
import { t } from '@/utils/im/i18n'
import { V2NIMLastMessage } from 'nim-web-sdk-ng/dist/esm/nim/src/V2NIMConversationService'
import { EMOJI_ICON_MAP_CONFIG, emojiRegExp } from '@/utils/im/emoji'
import { isWxApp } from '@/utils/im/index'
const props = withDefaults(
defineProps<{
lastMessage: V2NIMLastMessage
}>(),
{}
)
/** 筛选出文本和表情 */
const parseTextWithEmoji = (text: string) => {
if (!text) return []
const matches: {
type: 'emoji' | 'text'
value: string
index: number
}[] = []
let match
const regexEmoji = emojiRegExp
while ((match = regexEmoji.exec(text)) !== null) {
matches.push({
type: 'emoji',
value: match[0],
index: match.index,
})
const fillText = ' '.repeat(match[0].length)
text = text.replace(match[0], fillText)
}
text = text.replace(regexEmoji, ' ')
if (text) {
text
.split(' ')
.filter((item) => item.trim())
.map((item) => {
const index = text?.indexOf(item)
matches.push({
type: 'text',
value: item,
index,
})
const fillText = ' '.repeat(item.length)
text = text.replace(item, fillText)
})
}
return matches
.sort((a, b) => a.index - b.index)
.map((item, index) => {
return {
...item,
key: index + item.type,
}
})
}
/** 解析的消息数组 */
const textArr = computed(() => {
return parseTextWithEmoji(props.lastMessage.text as string)
})
/** 消息映射 */
const translateMsg = (key: string): string => {
const text =
{
textMsgText: t('textMsgText'),
customMsgText: t('customMsgText'),
audioMsgText: t('audioMsgText'),
videoMsgText: t('videoMsgText'),
fileMsgText: t('fileMsgText'),
callMsgText: t('callMsgText'),
geoMsgText: t('geoMsgText'),
imgMsgText: t('imgMsgText'),
notiMsgText: t('notiMsgText'),
robotMsgText: t('robotMsgText'),
tipMsgText: t('tipMsgText'),
unknowMsgText: t('unknowMsgText'),
}[key] || ''
if(text=='自定义消息'){
return JSON.parse(props.lastMessage.attachment.raw).gdxz_type
}else{
return `[${text}]`
}
}
</script>
<style scoped lang="scss">
.wrapper {
flex: 1;
font-size: 13px;
width: 100%;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.msg-conversation-text {
font-size: 13px !important;
height: 22px;
line-height: 22px;
width: 100%;
display: inline;
}
.msg-conversation-text-wrap {
width: 80%;
line-height: 22px;
height: 22px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-size: 14px;
overflow: hidden;
}
.msg-conversation-text-emoji {
display: inline-flex;
width: 18px;
height: 18px;
box-sizing: border-box;
align-items: center;
justify-content: center;
}
.msg-conversation-text-emoji-wx {
display: inline-flex;
width: 18px;
height: 18px;
box-sizing: border-box;
align-items: center;
justify-content: center;
position: relative;
bottom: 4px;
}
</style>