Import JC Web IM
This commit is contained in:
@@ -0,0 +1,651 @@
|
||||
import axios from 'axios';
|
||||
import { appConfig } from '@/config';
|
||||
|
||||
function randomId() {
|
||||
if (crypto && crypto.randomUUID) {
|
||||
return crypto.randomUUID().replaceAll('-', '');
|
||||
}
|
||||
return `${Date.now()}${Math.random().toString(16).slice(2)}`;
|
||||
}
|
||||
|
||||
function getAllowedDevice(mobile) {
|
||||
const allowedDevices = {
|
||||
'18301902119': '67072d37062c4f31b1165073552933ba',
|
||||
'18301902118': 'de89fb2f2a61480a8c381f6c16e28bd8',
|
||||
'18301902117': 'd117f480faa64145b6162107b1b49617'
|
||||
};
|
||||
return allowedDevices[mobile] || '';
|
||||
}
|
||||
|
||||
function getUniqueEquipment(mobile, fallback) {
|
||||
return getAllowedDevice(mobile) || localStorage.getItem('uniqueEquipment') || fallback;
|
||||
}
|
||||
|
||||
function normalizeStatus(message) {
|
||||
if (message.direction !== 0) {
|
||||
return 'sent';
|
||||
}
|
||||
if (message.status === 0 || message.status === 'sending') {
|
||||
return 'sending';
|
||||
}
|
||||
if (message.status === 2 || message.status === 'failed' || message.status === -1) {
|
||||
return 'failed';
|
||||
}
|
||||
return 'sent';
|
||||
}
|
||||
|
||||
function sendErrorText(errorCode) {
|
||||
const messages = {
|
||||
'-1': '连接不可用或发送超时',
|
||||
1: '密钥不匹配',
|
||||
2: '无效数据',
|
||||
4: '服务端错误',
|
||||
6: 'token错误',
|
||||
7: '账号被踢下线',
|
||||
8: '用户被禁用',
|
||||
9: '不在群组中',
|
||||
10: '无效消息',
|
||||
22: '服务未授权',
|
||||
28: 'WebSocket未配置',
|
||||
30: '服务器时间不同步',
|
||||
245: '用户被拉黑',
|
||||
246: '在黑名单中',
|
||||
247: '禁止发送消息',
|
||||
248: '无权限',
|
||||
249: '服务端超时',
|
||||
250: '发送过于频繁',
|
||||
251: '参数无效',
|
||||
253: '目标不存在',
|
||||
254: '服务未实现'
|
||||
};
|
||||
return messages[errorCode] || `错误码 ${errorCode}`;
|
||||
}
|
||||
|
||||
function resolveConversationTarget(conversation) {
|
||||
if (!conversation) {
|
||||
return '';
|
||||
}
|
||||
return conversation.target
|
||||
|| conversation.raw?.target
|
||||
|| String(conversation.id || '').replace(/^single-/, '').replace(/^0-/, '').replace(/-0$/, '');
|
||||
}
|
||||
|
||||
export class ImClient {
|
||||
constructor() {
|
||||
this.listeners = new Map();
|
||||
this.connected = false;
|
||||
this.currentUser = null;
|
||||
this.sdkReady = false;
|
||||
this.sdk = null;
|
||||
this.sdkModules = null;
|
||||
this.sdkEventsBound = false;
|
||||
this.pendingOutgoingMessages = new Map();
|
||||
this.loginClientId = '';
|
||||
}
|
||||
|
||||
getClientId() {
|
||||
if (this.sdkReady && this.sdk) {
|
||||
return this.sdk.getClientId();
|
||||
}
|
||||
let clientId = localStorage.getItem(appConfig.clientIdStorageKey);
|
||||
if (!clientId) {
|
||||
clientId = randomId();
|
||||
localStorage.setItem(appConfig.clientIdStorageKey, clientId);
|
||||
}
|
||||
return clientId;
|
||||
}
|
||||
|
||||
getSdkVersion() {
|
||||
if (!this.sdkReady || !this.sdk || typeof this.sdk.getVersion !== 'function') {
|
||||
return '';
|
||||
}
|
||||
return this.sdk.getVersion() || '';
|
||||
}
|
||||
|
||||
prepareClientIdForLogin(mobile) {
|
||||
const pinnedClientId = getAllowedDevice(mobile) || localStorage.getItem('uniqueEquipment') || '';
|
||||
if (pinnedClientId) {
|
||||
sessionStorage.setItem('clientId', pinnedClientId);
|
||||
localStorage.setItem('clientId', pinnedClientId);
|
||||
localStorage.setItem(appConfig.clientIdStorageKey, pinnedClientId);
|
||||
this.loginClientId = pinnedClientId;
|
||||
return pinnedClientId;
|
||||
}
|
||||
|
||||
this.loginClientId = this.getClientId();
|
||||
return this.loginClientId;
|
||||
}
|
||||
|
||||
restoreClientId(clientId) {
|
||||
if (!clientId) {
|
||||
return;
|
||||
}
|
||||
sessionStorage.setItem('clientId', clientId);
|
||||
localStorage.setItem('clientId', clientId);
|
||||
localStorage.setItem(appConfig.clientIdStorageKey, clientId);
|
||||
this.loginClientId = clientId;
|
||||
}
|
||||
|
||||
async loginWithPassword(mobile, password) {
|
||||
const deviceId = this.prepareClientIdForLogin(mobile);
|
||||
await this.ensureSdk();
|
||||
const url = `${appConfig.appServer}/login_pwd`;
|
||||
const sdkClientId = this.getClientId();
|
||||
if (sdkClientId !== deviceId) {
|
||||
console.warn('[im] clientId mismatch before login', { deviceId, sdkClientId });
|
||||
}
|
||||
const response = await axios.post(url, {
|
||||
mobile,
|
||||
password,
|
||||
platform: appConfig.platform,
|
||||
clientId: deviceId,
|
||||
uniqueEquipment: deviceId
|
||||
}, { withCredentials: false });
|
||||
|
||||
this.persistAppToken(url, response);
|
||||
if (response.data?.code !== 0) {
|
||||
throw new Error(response.data?.message || '登录失败');
|
||||
}
|
||||
return response.data.result;
|
||||
}
|
||||
|
||||
async requestAuthCode(mobile) {
|
||||
const response = await axios.post(`${appConfig.appServer}/send_code`, { mobile }, { withCredentials: false });
|
||||
if (response.data?.code !== 0) {
|
||||
throw new Error(response.data?.message || '验证码发送失败');
|
||||
}
|
||||
return response.data.result;
|
||||
}
|
||||
|
||||
async loginWithCode(mobile, code) {
|
||||
const deviceId = this.prepareClientIdForLogin(mobile);
|
||||
await this.ensureSdk();
|
||||
const url = `${appConfig.appServer}/login`;
|
||||
const sdkClientId = this.getClientId();
|
||||
if (sdkClientId !== deviceId) {
|
||||
console.warn('[im] clientId mismatch before login', { deviceId, sdkClientId });
|
||||
}
|
||||
const response = await axios.post(url, {
|
||||
mobile,
|
||||
code,
|
||||
platform: appConfig.platform,
|
||||
clientId: deviceId,
|
||||
uniqueEquipment: deviceId
|
||||
}, { withCredentials: false });
|
||||
|
||||
this.persistAppToken(url, response);
|
||||
if (response.data?.code !== 0) {
|
||||
throw new Error(response.data?.message || '登录失败');
|
||||
}
|
||||
return response.data.result;
|
||||
}
|
||||
|
||||
async connect(userId, token) {
|
||||
this.currentUser = { userId, token };
|
||||
await this.ensureSdk();
|
||||
console.info('[im] connect', {
|
||||
userId,
|
||||
clientId: this.getClientId(),
|
||||
configuredClientId: this.loginClientId || localStorage.getItem(appConfig.clientIdStorageKey) || ''
|
||||
});
|
||||
this.sdk.connect(userId, token);
|
||||
this.emit('connectionStatusChanged', { connected: false, statusText: '连接中' });
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
if (this.sdkReady && this.sdk) {
|
||||
this.sdk.disconnect();
|
||||
}
|
||||
this.connected = false;
|
||||
this.currentUser = null;
|
||||
this.emit('connectionStatusChanged', { connected: false });
|
||||
}
|
||||
|
||||
sendTextMessage(conversation, text, initialMessage = null) {
|
||||
const target = resolveConversationTarget(conversation);
|
||||
const rawConversation = conversation.raw || this.createRawSingleConversation(target);
|
||||
if (this.sdkReady && this.sdk && rawConversation) {
|
||||
const { TextMessageContent } = this.sdkModules;
|
||||
const content = new TextMessageContent(text);
|
||||
console.info('[im] send text', {
|
||||
conversationId: conversation.id,
|
||||
target: rawConversation.target,
|
||||
type: rawConversation.type,
|
||||
line: rawConversation.line,
|
||||
connected: this.connected
|
||||
});
|
||||
this.sdk.sendConversationMessage(
|
||||
rawConversation,
|
||||
content,
|
||||
[],
|
||||
(messageId, timestamp) => {
|
||||
if (initialMessage) {
|
||||
this.pendingOutgoingMessages.set(String(messageId), {
|
||||
...initialMessage,
|
||||
sdkMessageId: String(messageId),
|
||||
sdkTimestamp: Number(timestamp || Date.now())
|
||||
});
|
||||
}
|
||||
console.info('[im] send prepared', {
|
||||
conversationId: conversation.id,
|
||||
target: rawConversation.target,
|
||||
messageId,
|
||||
timestamp
|
||||
});
|
||||
if (!initialMessage) {
|
||||
this.emit('messageSent', this.mapOutgoingMessage(conversation.id, messageId, timestamp, text, 'sending'));
|
||||
}
|
||||
},
|
||||
null,
|
||||
(messageUid, timestamp) => {
|
||||
console.info('[im] send success', {
|
||||
conversationId: conversation.id,
|
||||
target: rawConversation.target,
|
||||
messageUid,
|
||||
timestamp
|
||||
});
|
||||
this.emit('messageStatusChanged', {
|
||||
...(initialMessage || {}),
|
||||
conversationId: conversation.id,
|
||||
id: initialMessage?.id || String(messageUid || randomId()),
|
||||
messageUid,
|
||||
timestamp: initialMessage?.timestamp || Number(timestamp || Date.now()),
|
||||
displayTimestamp: initialMessage?.displayTimestamp || initialMessage?.timestamp || Number(timestamp || Date.now()),
|
||||
status: 'sent'
|
||||
});
|
||||
},
|
||||
errorCode => {
|
||||
const failedMessage = {
|
||||
...(initialMessage || {}),
|
||||
conversationId: conversation.id,
|
||||
id: initialMessage?.id || randomId(),
|
||||
text,
|
||||
direction: 'out',
|
||||
type: 'text',
|
||||
status: 'failed',
|
||||
errorCode,
|
||||
error: sendErrorText(errorCode)
|
||||
};
|
||||
this.updatePendingOutgoingMessage(failedMessage);
|
||||
console.error('[im] send failed', {
|
||||
conversationId: conversation.id,
|
||||
target: rawConversation.target,
|
||||
connected: this.connected,
|
||||
errorCode,
|
||||
error: sendErrorText(errorCode)
|
||||
});
|
||||
this.emit('messageStatusChanged', failedMessage);
|
||||
}
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
const message = {
|
||||
id: randomId(),
|
||||
conversationId: conversation.id,
|
||||
from: this.currentUser?.userId || 'me',
|
||||
direction: 'out',
|
||||
type: 'text',
|
||||
text,
|
||||
status: 'failed',
|
||||
timestamp: Date.now(),
|
||||
error: rawConversation ? 'SDK未就绪' : `会话目标无效:${target || '空'}`
|
||||
};
|
||||
this.emit('messageSent', message);
|
||||
return message;
|
||||
}
|
||||
|
||||
getConversationList() {
|
||||
if (!this.sdkReady || !this.sdk) {
|
||||
return [];
|
||||
}
|
||||
const { ConversationType } = this.sdkModules;
|
||||
return this.sdk.getConversationList(
|
||||
[ConversationType.Single, ConversationType.Group, ConversationType.Channel],
|
||||
[0]
|
||||
).map(item => this.mapConversationInfo(item));
|
||||
}
|
||||
|
||||
refreshConversationList() {
|
||||
const conversations = this.getConversationList();
|
||||
this.emit('conversationsChanged', conversations);
|
||||
return conversations;
|
||||
}
|
||||
|
||||
getMessages(conversation, count = 30) {
|
||||
const rawConversation = conversation.raw || this.createRawSingleConversation(resolveConversationTarget(conversation));
|
||||
if (!this.sdkReady || !this.sdk || !rawConversation) {
|
||||
return [];
|
||||
}
|
||||
return this.sdk.getMessages(rawConversation, 0, true, count).map(message => this.mapMessage(message));
|
||||
}
|
||||
|
||||
async fetchRemoteMessages(conversation, limit = 50) {
|
||||
if (!conversation?.id || !this.currentUser?.userId) {
|
||||
return this.getMessages(conversation, limit);
|
||||
}
|
||||
const response = await axios.post(appConfig.messagesApi, {
|
||||
userId: this.currentUser.userId,
|
||||
target: resolveConversationTarget(conversation),
|
||||
limit
|
||||
}, { withCredentials: false });
|
||||
|
||||
if (response.data?.code !== 0) {
|
||||
throw new Error(response.data?.message || '消息同步失败');
|
||||
}
|
||||
|
||||
return (response.data?.result?.messages || []).map(message => ({
|
||||
...message,
|
||||
displayTimestamp: message.displayTimestamp || message.timestamp,
|
||||
conversationId: conversation.id
|
||||
}));
|
||||
}
|
||||
|
||||
on(eventName, handler) {
|
||||
if (!this.listeners.has(eventName)) {
|
||||
this.listeners.set(eventName, new Set());
|
||||
}
|
||||
this.listeners.get(eventName).add(handler);
|
||||
return () => this.off(eventName, handler);
|
||||
}
|
||||
|
||||
off(eventName, handler) {
|
||||
this.listeners.get(eventName)?.delete(handler);
|
||||
}
|
||||
|
||||
emit(eventName, payload) {
|
||||
this.listeners.get(eventName)?.forEach(handler => handler(payload));
|
||||
}
|
||||
|
||||
updatePendingOutgoingMessage(message) {
|
||||
if (!message?.id) {
|
||||
return;
|
||||
}
|
||||
this.pendingOutgoingMessages.forEach((pendingMessage, sdkMessageId) => {
|
||||
if (pendingMessage.id === message.id) {
|
||||
this.pendingOutgoingMessages.set(sdkMessageId, {
|
||||
...pendingMessage,
|
||||
...message,
|
||||
sdkMessageId
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
mapSdkStatusMessage(message) {
|
||||
const mappedMessage = this.mapMessage(message);
|
||||
if (message.direction !== 0 || !message.messageId) {
|
||||
return mappedMessage;
|
||||
}
|
||||
const sdkMessageId = String(message.messageId);
|
||||
const pendingMessage = this.pendingOutgoingMessages.get(sdkMessageId);
|
||||
if (!pendingMessage) {
|
||||
return mappedMessage;
|
||||
}
|
||||
const nextMessage = {
|
||||
...pendingMessage,
|
||||
...mappedMessage,
|
||||
id: pendingMessage.id,
|
||||
conversationId: pendingMessage.conversationId || mappedMessage.conversationId,
|
||||
text: pendingMessage.text || mappedMessage.text,
|
||||
timestamp: pendingMessage.timestamp || mappedMessage.timestamp,
|
||||
displayTimestamp: pendingMessage.displayTimestamp || mappedMessage.displayTimestamp,
|
||||
sdkMessageId,
|
||||
errorCode: mappedMessage.errorCode || pendingMessage.errorCode,
|
||||
error: mappedMessage.error || pendingMessage.error
|
||||
};
|
||||
this.pendingOutgoingMessages.set(sdkMessageId, nextMessage);
|
||||
if (nextMessage.status === 'sent') {
|
||||
window.setTimeout(() => this.pendingOutgoingMessages.delete(sdkMessageId), 60000);
|
||||
}
|
||||
return nextMessage;
|
||||
}
|
||||
|
||||
async ensureSdk() {
|
||||
if (this.sdkReady || appConfig.sdkMode !== 'wildfire') {
|
||||
return;
|
||||
}
|
||||
|
||||
const wfcModule = await import('legacy-wfc/client/wfc');
|
||||
const configModule = await import('legacy-config');
|
||||
const eventModule = await import('legacy-wfc/client/wfcEvent');
|
||||
const connectionStatusModule = await import('legacy-wfc/client/connectionStatus');
|
||||
const conversationTypeModule = await import('legacy-wfc/model/conversationType');
|
||||
const conversationModule = await import('legacy-wfc/model/conversation');
|
||||
const textMessageModule = await import('legacy-wfc/messages/textMessageContent');
|
||||
|
||||
const Config = configModule.default;
|
||||
Config.APP_SERVER = appConfig.appServer;
|
||||
Config.USE_WSS = appConfig.useWss;
|
||||
Config.ROUTE_PORT = appConfig.imRoutePort;
|
||||
Config.WS_PATH = appConfig.wsPath;
|
||||
Config.HTTP_IM_PREFIX_PATH = '';
|
||||
Config.HTTP_UPLOAD_PREFIX_PATH = '';
|
||||
Config.CLIENT_ID_STRATEGY = 2;
|
||||
|
||||
this.sdk = wfcModule.default;
|
||||
this.sdkModules = {
|
||||
EventType: eventModule.default,
|
||||
ConnectionStatus: connectionStatusModule.default,
|
||||
ConversationType: conversationTypeModule.default,
|
||||
Conversation: conversationModule.default,
|
||||
TextMessageContent: textMessageModule.default
|
||||
};
|
||||
|
||||
this.bindSdkEvents();
|
||||
this.sdk.init();
|
||||
this.sdkReady = true;
|
||||
}
|
||||
|
||||
bindSdkEvents() {
|
||||
if (this.sdkEventsBound) {
|
||||
return;
|
||||
}
|
||||
this.sdkEventsBound = true;
|
||||
const { EventType, ConnectionStatus } = this.sdkModules;
|
||||
this.sdk.eventEmitter.on(EventType.ConnectionStatusChanged, status => {
|
||||
const connected = status === ConnectionStatus.ConnectionStatusConnected;
|
||||
this.connected = connected;
|
||||
this.emit('connectionStatusChanged', {
|
||||
connected,
|
||||
status,
|
||||
statusText: ConnectionStatus.desc(status) || '连接状态变化'
|
||||
});
|
||||
if (connected || status === ConnectionStatus.ConnectionStatusReceiveing) {
|
||||
window.setTimeout(() => this.refreshConversationList(), 0);
|
||||
}
|
||||
});
|
||||
this.sdk.eventEmitter.on(EventType.ConversationInfoUpdate, () => {
|
||||
this.refreshConversationList();
|
||||
});
|
||||
this.sdk.eventEmitter.on(EventType.FriendListUpdate, () => {
|
||||
this.emit('contactsChanged', this.getContactList(true));
|
||||
});
|
||||
this.sdk.eventEmitter.on(EventType.UserInfosUpdate, () => {
|
||||
this.emit('contactsChanged', this.getContactList(false));
|
||||
});
|
||||
this.sdk.eventEmitter.on(EventType.MessageStatusUpdate, message => {
|
||||
this.emit('messageStatusChanged', this.mapSdkStatusMessage(message));
|
||||
});
|
||||
this.sdk.eventEmitter.on(EventType.ReceiveMessage, message => {
|
||||
this.emit('messageReceived', this.mapMessage(message));
|
||||
this.refreshConversationList();
|
||||
});
|
||||
}
|
||||
|
||||
mapConversationInfo(info) {
|
||||
const conversation = info.conversation;
|
||||
const id = `${conversation.type}-${conversation.target}-${conversation.line}`;
|
||||
const title = this.getConversationTitle(info);
|
||||
return {
|
||||
id,
|
||||
type: conversation.type,
|
||||
title,
|
||||
subtitle: info.lastMessage ? this.messageDigest(info.lastMessage) : '',
|
||||
unread: info.unreadCount?.unread || info.unreadCount || 0,
|
||||
avatarText: title.slice(0, 1).toUpperCase(),
|
||||
updatedAt: Number(info.timestamp || info.lastMessage?.timestamp || Date.now()),
|
||||
raw: conversation,
|
||||
rawInfo: info
|
||||
};
|
||||
}
|
||||
|
||||
getContactList(refresh = false) {
|
||||
if (!this.sdkReady || !this.sdk) {
|
||||
return [];
|
||||
}
|
||||
const friendIds = this.sdk.getMyFriendList(refresh) || [];
|
||||
if (!friendIds.length) {
|
||||
return [];
|
||||
}
|
||||
const userInfos = this.sdk.getUserInfos(friendIds, '') || [];
|
||||
return userInfos.map(userInfo => {
|
||||
return this.mapContact(userInfo.uid, null, userInfo);
|
||||
}).sort((a, b) => a.title.localeCompare(b.title, 'zh-CN'));
|
||||
}
|
||||
|
||||
async getServerContactList(userId) {
|
||||
if (!userId) {
|
||||
return [];
|
||||
}
|
||||
const response = await axios.post(appConfig.contactsApi, { userId }, { withCredentials: false });
|
||||
if (response.data?.code !== 0) {
|
||||
throw new Error(response.data?.message || '联系人加载失败');
|
||||
}
|
||||
return (response.data?.result?.contacts || []).map(item => {
|
||||
return this.mapContact(item.uid, { alias: item.alias }, {
|
||||
uid: item.uid,
|
||||
displayName: item.displayName,
|
||||
name: item.name,
|
||||
mobile: item.mobile,
|
||||
portrait: item.portrait,
|
||||
friendAlias: item.alias
|
||||
});
|
||||
}).sort((a, b) => a.title.localeCompare(b.title, 'zh-CN'));
|
||||
}
|
||||
|
||||
refreshContactList() {
|
||||
const contacts = this.getContactList(true);
|
||||
this.emit('contactsChanged', contacts);
|
||||
return contacts;
|
||||
}
|
||||
|
||||
createRawSingleConversation(userId) {
|
||||
if (!userId || !this.sdkModules?.Conversation || !this.sdkModules?.ConversationType) {
|
||||
return null;
|
||||
}
|
||||
const { Conversation, ConversationType } = this.sdkModules;
|
||||
return new Conversation(ConversationType.Single, userId, 0);
|
||||
}
|
||||
|
||||
createSingleConversation(userId) {
|
||||
if (!this.sdkReady || !this.sdk) {
|
||||
const title = userId;
|
||||
return {
|
||||
id: `single-${userId}`,
|
||||
type: 'single',
|
||||
target: userId,
|
||||
title,
|
||||
subtitle: '',
|
||||
unread: 0,
|
||||
avatarText: title.slice(0, 1).toUpperCase(),
|
||||
updatedAt: Date.now(),
|
||||
raw: null
|
||||
};
|
||||
}
|
||||
const { ConversationType } = this.sdkModules;
|
||||
const raw = this.createRawSingleConversation(userId);
|
||||
const info = this.sdk.getConversationInfo(raw);
|
||||
return info ? this.mapConversationInfo(info) : {
|
||||
id: `${ConversationType.Single}-${userId}-0`,
|
||||
type: ConversationType.Single,
|
||||
target: userId,
|
||||
title: this.sdk.getUserDisplayName(userId),
|
||||
subtitle: '',
|
||||
unread: 0,
|
||||
avatarText: this.sdk.getUserDisplayName(userId).slice(0, 1).toUpperCase(),
|
||||
updatedAt: Date.now(),
|
||||
raw
|
||||
};
|
||||
}
|
||||
|
||||
mapContact(userId, friend, userInfo) {
|
||||
const title = userInfo?.friendAlias || friend?.alias || userInfo?.displayName || userInfo?.name || userId;
|
||||
return {
|
||||
id: userId,
|
||||
uid: userId,
|
||||
title,
|
||||
subtitle: userInfo?.mobile || userInfo?.name || userId,
|
||||
portrait: userInfo?.portrait || '',
|
||||
avatarText: title.slice(0, 1).toUpperCase(),
|
||||
alias: friend?.alias || userInfo?.friendAlias || '',
|
||||
rawFriend: friend,
|
||||
rawUser: userInfo
|
||||
};
|
||||
}
|
||||
|
||||
getConversationTitle(info) {
|
||||
const conversation = info.conversation;
|
||||
if (conversation._target?._displayName) {
|
||||
return conversation._target._displayName;
|
||||
}
|
||||
if (conversation.type === this.sdkModules.ConversationType.Single) {
|
||||
return this.sdk.getUserDisplayName(conversation.target);
|
||||
}
|
||||
if (conversation.type === this.sdkModules.ConversationType.Group) {
|
||||
return this.sdk.getGroupInfo(conversation.target)?.name || conversation.target;
|
||||
}
|
||||
return conversation.target;
|
||||
}
|
||||
|
||||
mapMessage(message) {
|
||||
return {
|
||||
id: String(message.messageId || message.messageUid || randomId()),
|
||||
messageUid: message.messageUid,
|
||||
conversationId: message.conversation ? `${message.conversation.type}-${message.conversation.target}-${message.conversation.line}` : '',
|
||||
from: message.from,
|
||||
direction: message.direction === 0 ? 'out' : 'in',
|
||||
type: 'text',
|
||||
text: this.messageDigest(message),
|
||||
status: normalizeStatus(message),
|
||||
timestamp: Number(message.timestamp || Date.now()),
|
||||
displayTimestamp: Number(message.timestamp || Date.now()),
|
||||
raw: message
|
||||
};
|
||||
}
|
||||
|
||||
mapOutgoingMessage(conversationId, messageId, timestamp, text, status) {
|
||||
return {
|
||||
id: String(messageId || randomId()),
|
||||
conversationId,
|
||||
from: this.currentUser?.userId || 'me',
|
||||
direction: 'out',
|
||||
type: 'text',
|
||||
text,
|
||||
status,
|
||||
timestamp: Number(timestamp || Date.now())
|
||||
};
|
||||
}
|
||||
|
||||
messageDigest(message) {
|
||||
if (!message?.messageContent) {
|
||||
return '';
|
||||
}
|
||||
if (message.messageContent.content) {
|
||||
return message.messageContent.content;
|
||||
}
|
||||
if (typeof message.messageContent.digest === 'function') {
|
||||
return message.messageContent.digest(message);
|
||||
}
|
||||
return '[暂不支持的消息]';
|
||||
}
|
||||
|
||||
persistAppToken(url, response) {
|
||||
const appToken = response.headers?.authtoken || response.headers?.authToken;
|
||||
if (appToken) {
|
||||
localStorage.setItem(appConfig.authTokenStoragePrefix + new URL(url).host, appToken);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export const imClient = new ImClient();
|
||||
Reference in New Issue
Block a user