feat: preview emoji media in message list

This commit is contained in:
liuwei
2026-04-13 12:10:37 +08:00
parent ada1b656e0
commit 45d97b2989
2 changed files with 49 additions and 1 deletions

View File

@@ -87,6 +87,16 @@
<img v-else-if="scope.row.message_thumb" :src="scope.row.message_thumb" class="message-thumb" @click="showImage(scope.row)">
</div>
<div v-else-if="isEmojiMessage(scope.row)" class="message-media-preview">
<div class="message-media-label">【表情消息】</div>
<img
v-if="getEmojiPreviewUrl(scope.row)"
:src="getEmojiPreviewUrl(scope.row)"
class="message-thumb"
@click="showEmoji(scope.row)">
<div v-else class="message-text-preview is-muted">【表情消息】等待下载完成</div>
</div>
<div v-else-if="scope.row.message_type == 43" class="message-media-preview">
<div class="message-media-label">【视频消息】</div>
<img v-if="scope.row.message_thumb" :src="scope.row.message_thumb" class="message-thumb" @click="showVideo(scope.row)">
@@ -138,8 +148,9 @@
<el-descriptions-item label="消息类型">{% raw %}{{ getMessageTypeName(selectedMessage.message_type) }}{% endraw %}</el-descriptions-item>
<el-descriptions-item label="内容">{% raw %}{{ selectedMessage.content }}{% endraw %}</el-descriptions-item>
<el-descriptions-item v-if="selectedMessage.message_type == 3 || selectedMessage.message_type == 43" label="媒体内容">
<el-descriptions-item v-if="selectedMessage.message_type == 3 || selectedMessage.message_type == 43 || isEmojiMessage(selectedMessage)" label="媒体内容">
<img v-if="selectedMessage.message_type == 3 && selectedMessage.image_path" :src="getImageUrl(selectedMessage.image_path)" style="max-width: 100%; border-radius: 16px;">
<img v-else-if="isEmojiMessage(selectedMessage) && getEmojiPreviewUrl(selectedMessage)" :src="getEmojiPreviewUrl(selectedMessage)" style="max-width: 100%; border-radius: 16px;">
<img v-else-if="selectedMessage.message_type == 3 && selectedMessage.message_thumb" :src="selectedMessage.message_thumb" style="max-width: 100%; border-radius: 16px;">
<video v-if="selectedMessage.message_type == 43 && selectedMessage.attachment_url" :src="selectedMessage.attachment_url" controls style="max-width: 100%; border-radius: 16px;"></video>
</el-descriptions-item>
@@ -153,6 +164,7 @@
<el-dialog :visible.sync="imageDialogVisible" append-to-body width="80%" class="image-dialog">
<img v-if="selectedMessage && selectedMessage.image_path" :src="getImageUrl(selectedMessage.image_path)" style="max-width: 100%; border-radius: 18px;">
<img v-else-if="selectedMessage && getEmojiPreviewUrl(selectedMessage)" :src="getEmojiPreviewUrl(selectedMessage)" style="max-width: 100%; border-radius: 18px;">
<img v-else-if="selectedMessage && selectedMessage.message_thumb" :src="selectedMessage.message_thumb" style="max-width: 100%; border-radius: 18px;">
</el-dialog>
</div>
@@ -321,6 +333,10 @@
this.selectedMessage = message;
this.imageDialogVisible = true;
},
showEmoji(message) {
this.selectedMessage = message;
this.imageDialogVisible = true;
},
showQuotedImage(url) {
const resolvedUrl = this.getQuotedPreviewUrl(url);
if (!resolvedUrl) return;
@@ -341,6 +357,10 @@
};
return typeMap[type] || `未知类型(${type})`;
},
isEmojiMessage(message) {
if (!message) return false;
return ['47', '1048625', '1090519089'].includes(String(message.message_type));
},
getImageUrl(imagePath) {
if (!imagePath) return '';
@@ -367,6 +387,20 @@
return `/static/images/${fileName}`;
},
getEmojiPreviewUrl(message) {
if (!message) return '';
if (message.image_path) {
return this.getImageUrl(message.image_path);
}
const previewUrl = message.emoji_preview_url || '';
if (!previewUrl) {
return '';
}
if (previewUrl.startsWith('http://') || previewUrl.startsWith('https://')) {
return this.getMediaProxyUrl(previewUrl);
}
return this.getImageUrl(previewUrl);
},
getMediaProxyUrl(url) {
if (!url) return '';
if (url.startsWith('/api/messages/media_proxy')) {