[Human] chore(project): 初始化导入 91dj H5 客户端项目代码
从本地工程首次入库;.npmrc(含私有 npm 源 token)与 tsbuildinfo 已加入 .gitignore,不随仓库提交。
This commit is contained in:
@@ -0,0 +1,127 @@
|
||||
import { needsImageDecrypt, parseImageExtra, toBusinessImagePath } from '@/utils/im/message';
|
||||
|
||||
/** 消息中心私信列表的一行数据(纯 SDK 会话映射) */
|
||||
export type PrivateSessionItem = {
|
||||
id: string;
|
||||
/** 业务 uid;列表由 SDK 驱动时为 0,进会话前用 /im/user-id 反查 */
|
||||
userId: number;
|
||||
/** 对端 IM userId(= conv.receiverId) */
|
||||
friendImUserId: number;
|
||||
userName: string;
|
||||
userAvatar: string;
|
||||
preContent: string;
|
||||
createdAt: string | number;
|
||||
noReadNum: number;
|
||||
};
|
||||
|
||||
/** SDK conversation.subscribeList 推送的会话结构 */
|
||||
export type SdkConversation = {
|
||||
type?: string;
|
||||
receiverId?: number | string;
|
||||
unreadCount?: number;
|
||||
extra?: string;
|
||||
lastMessageTime?: number;
|
||||
updatedAt?: number;
|
||||
createdAt?: number;
|
||||
content?: string;
|
||||
chatMessageType?: string | number;
|
||||
user?: {
|
||||
id?: number;
|
||||
nickName?: string;
|
||||
nickname?: string;
|
||||
name?: string;
|
||||
avatar?: string;
|
||||
portrait?: string;
|
||||
imgUrl?: string;
|
||||
};
|
||||
remark?: string;
|
||||
};
|
||||
|
||||
// —— 展示文案 ——
|
||||
|
||||
/** blob/data 本地地址、http(s) 公网图无需再走 imgDecypt */
|
||||
export function isPublicImageUrl(url?: string): boolean {
|
||||
return !needsImageDecrypt(url);
|
||||
}
|
||||
|
||||
export function formatSessionPreview(content?: string): string {
|
||||
const text = (content || '').trim();
|
||||
if (!text) return '暂无消息';
|
||||
if (/^\[图片\]|^图片$|image/i.test(text)) return '[图片]';
|
||||
return text;
|
||||
}
|
||||
|
||||
export function formatSessionListTime(date: string | number): string {
|
||||
if (date == null || date === '') return '';
|
||||
const d = typeof date === 'number' ? new Date(date) : new Date(date);
|
||||
if (Number.isNaN(d.getTime()) || d.getFullYear() === 1) return '';
|
||||
return `${d.getFullYear()}-${d.getMonth() + 1}-${d.getDate()}`;
|
||||
}
|
||||
|
||||
export function buildMessagePreview(msg: {
|
||||
content?: string;
|
||||
chatMessageType?: string | number;
|
||||
extra?: unknown;
|
||||
}): string {
|
||||
const type = msg.chatMessageType;
|
||||
if (type === 'IMAGE' || type === 2 || parseImageExtra(msg.extra)) return '[图片]';
|
||||
return (msg.content || '').trim() || '暂无消息';
|
||||
}
|
||||
|
||||
// —— SDK 会话 → 列表行 ——
|
||||
|
||||
function toTimestamp(value: string | number | undefined): number {
|
||||
if (value == null || value === '') return 0;
|
||||
const ts = typeof value === 'number' ? value : new Date(value).getTime();
|
||||
return Number.isFinite(ts) ? ts : 0;
|
||||
}
|
||||
|
||||
function isDirectConversation(conv: SdkConversation): boolean {
|
||||
if (conv.type && conv.type !== 'direct') return false;
|
||||
const imId = Number(conv.receiverId);
|
||||
return Number.isFinite(imId) && imId > 0;
|
||||
}
|
||||
|
||||
/** IM 快照偶发幽灵会话(user 资料整体缺失),无法渲染也无法跳转,不展示 */
|
||||
function hasUserProfile(conv: SdkConversation): boolean {
|
||||
const user = conv.user;
|
||||
return !!(user?.nickName || user?.nickname || user?.name || user?.avatar || user?.portrait || user?.imgUrl);
|
||||
}
|
||||
|
||||
function toSessionItem(conv: SdkConversation): PrivateSessionItem {
|
||||
const imId = Number(conv.receiverId);
|
||||
const user = conv.user;
|
||||
|
||||
return {
|
||||
id: String(imId),
|
||||
userId: 0,
|
||||
friendImUserId: imId,
|
||||
userName: user?.nickName || user?.nickname || user?.name || conv.remark || '',
|
||||
userAvatar: toBusinessImagePath(user?.avatar || user?.portrait || user?.imgUrl || ''),
|
||||
preContent: parseImageExtra(conv.extra)
|
||||
? '[图片]'
|
||||
: buildMessagePreview({
|
||||
content: conv.content,
|
||||
chatMessageType: conv.chatMessageType,
|
||||
extra: conv.extra,
|
||||
}),
|
||||
createdAt: conv.lastMessageTime ?? conv.updatedAt ?? conv.createdAt ?? '',
|
||||
noReadNum: Number(conv.unreadCount ?? 0),
|
||||
};
|
||||
}
|
||||
|
||||
/** SDK 会话快照 → 私信列表(仅单聊;按最后消息时间倒序) */
|
||||
export function mapSdkConversations(conversations: SdkConversation[]): PrivateSessionItem[] {
|
||||
const seen = new Set<number>();
|
||||
const list: PrivateSessionItem[] = [];
|
||||
|
||||
for (const conv of conversations) {
|
||||
if (!isDirectConversation(conv) || !hasUserProfile(conv)) continue;
|
||||
const imId = Number(conv.receiverId);
|
||||
if (seen.has(imId)) continue;
|
||||
seen.add(imId);
|
||||
list.push(toSessionItem(conv));
|
||||
}
|
||||
|
||||
return list.sort((a, b) => toTimestamp(b.createdAt) - toTimestamp(a.createdAt));
|
||||
}
|
||||
Reference in New Issue
Block a user