From 27cd042df9aca0383a49f3514bc21958dd890912 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期一, 29 六月 2026 15:42:23 +0800
Subject: [PATCH] 银川 1.联调产品维护页面 2.添加IM即时通讯模块
---
src/views/im/utils/conversation.ts | 177 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 177 insertions(+), 0 deletions(-)
diff --git a/src/views/im/utils/conversation.ts b/src/views/im/utils/conversation.ts
new file mode 100644
index 0000000..f846705
--- /dev/null
+++ b/src/views/im/utils/conversation.ts
@@ -0,0 +1,177 @@
+// ====================================================================
+// IM 浼氳瘽 / 鎾ゅ洖灞曠ず utility
+// ====================================================================
+// 鍩轰簬 conversation 涓婁笅鏂� + sender 淇℃伅瀹炴椂绠�"灞曠ず鏂囨"銆�
+// 1. 鍙戦�佷汉鍚嶄竴寰嬬敱 utils/user.getSenderDisplayName 瀹炴椂绠楋紝鏈枃浠跺彧璐熻矗鎷�"鎾ゅ洖 tip / 鎽樿"绛夋枃妗堛��
+// 2. fallbackName 鐢辫皟鐢ㄦ柟浼犲叆锛堝吀鍨嬫潵婧愶細Conversation.lastSenderDisplayName 蹇収锛夛紝閫忎紶鍒� getSenderDisplayName 鍐呴儴锛岀畻涓嶅嚭鐪熷悕鏃跺厹搴�
+// ====================================================================
+
+import type { Message } from '../home/types'
+
+import { ImContentType, ImConversationType, isFriendChatTip, isGroupNotification, isRtcCallTip } from './constants'
+import {
+ type CardMessage,
+ type FaceMessage,
+ type FileMessage,
+ getCardLabelInfo,
+ type MaterialMessage,
+ parseMessage,
+ segmentsToText,
+ type TextMessage,
+ tipMention,
+ type TipSegment,
+ tipText
+} from './message'
+import { resolveFriendNotificationText, resolveGroupNotificationText, resolveRtcCallLastContent } from './message'
+import { getSenderDisplayName } from './user'
+
+/** 浼氳瘽涓婚敭锛歚type-targetId` 鎷兼垚绋冲畾瀛楃涓诧紝缁� v-for :key銆乤ctive 姣斿銆乵ap key 绛夊満鏅叡鐢� */
+export function getConversationKey(conversation: { targetId: number; type: number; }): string {
+ return `${conversation.type}-${conversation.targetId}`
+}
+
+/** 鎸夋樀绉版ā绯婅繃婊や細璇濆垪琛細绌� keyword 鍘熸牱杩斿洖锛屽懡涓蛋 toLowerCase 涓嶅尯鍒嗗ぇ灏忓啓 */
+export function filterConversationsByKeyword<T extends { name?: string }>(
+ list: T[],
+ keyword: string
+): T[] {
+ const trimmed = keyword.trim().toLowerCase()
+ if (!trimmed) {
+ return list
+ }
+ return list.filter((c) => (c.name || '').toLowerCase().includes(trimmed))
+}
+
+/**
+ * 琛ㄦ儏娑堟伅鐨勭粺涓�鏂囨湰棰勮锛氭憳瑕� / 鍘嗗彶鎼滅储 / 寮曠敤鍧� / 绠$悊鍚庡彴棰勮鍏辩敤涓�浠�
+ * 鏈� name 鏃惰蛋 `[琛ㄦ儏] name`锛堢郴缁熷寘锛夛紝鏃� name 鏃惰蛋 `[琛ㄦ儏]`锛堜釜浜鸿〃鎯呴�氬父鏃� name锛�
+ */
+export function buildFacePreviewText(facePayload: null | undefined | { name?: string }): string {
+ return facePayload?.name ? `[琛ㄦ儏] ${facePayload.name}` : '[琛ㄦ儏]'
+}
+
+/**
+ * 鎾ゅ洖鎻愮ず segments
+ *
+ * senderId 缂哄け鏃朵笉鎸� mention 娈碉紝閬垮厤鐐瑰嚭閿欏彿锛涚畻涓嶅嚭鐪熷悕闄嶇骇涓恒�屽鏂广�嶇函鏂囨湰
+ */
+export function buildRecallTipSegments(
+ senderId: number,
+ selfSend: boolean,
+ conversationType: number,
+ conversationTargetId: number,
+ fallbackName?: string
+): TipSegment[] {
+ if (selfSend) {
+ return [tipText('浣犳挙鍥炰簡涓�鏉℃秷鎭�')]
+ }
+ const senderDisplayName = getSenderDisplayName(
+ senderId,
+ conversationType,
+ conversationTargetId,
+ fallbackName
+ )
+ if (!senderId) {
+ return [tipText(`${senderDisplayName || '瀵规柟'} 鎾ゅ洖浜嗕竴鏉℃秷鎭痐)]
+ }
+ return [
+ tipMention(senderId, senderDisplayName || '瀵规柟'),
+ tipText(' 鎾ゅ洖浜嗕竴鏉℃秷鎭�')
+ ]
+}
+
+/** 鎾ゅ洖鎻愮ず鏂囨锛氳嚜宸辨挙鍥炲浐瀹氭枃妗堬紝瀵规柟鎾ゅ洖甯� sender 鍚嶏紙瀹炴椂绠� + fallbackName 鍏滃簳锛� */
+export function buildRecallTip(
+ senderId: number,
+ selfSend: boolean,
+ conversationType: number,
+ conversationTargetId: number,
+ fallbackName?: string
+): string {
+ return segmentsToText(
+ buildRecallTipSegments(senderId, selfSend, conversationType, conversationTargetId, fallbackName)
+ )
+}
+
+/**
+ * 鍗曟潯娑堟伅鐨勭函鏂囨湰鎽樿锛涗笉渚濊禆 conversation 涓婁笅鏂�
+ *
+ * - withFileName=true 鏃舵枃浠舵秷鎭檮甯︽枃浠跺悕锛堝悎骞惰浆鍙戣鎯呯敤锛�
+ * - 涓嶅鐞� RECALL / 缇ゅ箍鎾� / 濂藉弸閫氱煡锛岀敱璋冪敤鏂瑰寘涓�灞�
+ */
+export function summarizeMessageContent(
+ message: Pick<Message, 'content' | 'type'>,
+ opts?: { withFileName?: boolean }
+): string {
+ switch (message.type) {
+ case ImContentType.CARD: {
+ return `[${getCardLabelInfo(parseMessage<CardMessage>(message.content)).label}]`
+ }
+ case ImContentType.FACE: {
+ return buildFacePreviewText(parseMessage<FaceMessage>(message.content))
+ }
+ case ImContentType.FILE: {
+ if (opts?.withFileName) {
+ const file = parseMessage<FileMessage>(message.content)
+ return file?.name ? `[鏂囦欢] ${file.name}` : '[鏂囦欢]'
+ }
+ return '[鏂囦欢]'
+ }
+ case ImContentType.IMAGE: {
+ return '[鍥剧墖]'
+ }
+ case ImContentType.MATERIAL: {
+ const material = parseMessage<MaterialMessage>(message.content)
+ return material?.title ? `[棰戦亾] ${material.title}` : '[棰戦亾]'
+ }
+ case ImContentType.MERGE: {
+ return '[鑱婂ぉ璁板綍]'
+ }
+ case ImContentType.RTC_CALL_END:
+ case ImContentType.RTC_CALL_START: {
+ return '[璇煶閫氳瘽]'
+ }
+ case ImContentType.TEXT: {
+ return parseMessage<TextMessage>(message.content)?.content ?? ''
+ }
+ case ImContentType.VIDEO: {
+ return '[瑙嗛]'
+ }
+ case ImContentType.VOICE: {
+ return '[璇煶]'
+ }
+ default: {
+ return ''
+ }
+ }
+}
+
+/** 浼氳瘽鍒楄〃鏈�鍚庝竴鏉℃憳瑕侊細RECALL 璧� buildRecallTip + fallbackName锛涘叾瀹冩寜鍐呭绫诲瀷娲剧敓 */
+export function resolveConversationLastContent(
+ message: Message,
+ conversationType: number,
+ conversationTargetId: number,
+ fallbackName?: string
+): string {
+ if (message.type === ImContentType.RECALL) {
+ return buildRecallTip(
+ message.senderId,
+ message.selfSend,
+ conversationType,
+ conversationTargetId,
+ fallbackName
+ )
+ }
+ if (isFriendChatTip(message.type)) {
+ return resolveFriendNotificationText(message)
+ }
+ if (isGroupNotification(message.type)) {
+ return resolveGroupNotificationText(message, (id) =>
+ getSenderDisplayName(id, ImConversationType.GROUP, message.targetId ?? 0)
+ )
+ }
+ if (isRtcCallTip(message.type)) {
+ return resolveRtcCallLastContent(message, conversationType)
+ }
+ return summarizeMessageContent(message)
+}
--
Gitblit v1.9.3