This commit is contained in:
Your Name
2026-03-11 09:49:47 +08:00
parent 02ae537b4c
commit 38ad60f4bb
290 changed files with 36917 additions and 123 deletions
@@ -0,0 +1,133 @@
import TUIBase from '../tui-base';
import type { IConversationModel } from '../interface/model';
import { isPrivateKey, isUrl, calculateTimeAgo, JSONToObject } from '../utils/common-utils';
import type { MuteConversationParams } from '../type';
import { AVATAR } from '../config';
import isEmpty from '../utils/is-empty';
import { IN_WX_MINI_APP } from '../utils/env';
const LAST_MSG_FOR_SHOW = [
'[图片]',
'[语音]',
'[视频]',
'[文件]',
'[位置]',
'[地理位置]',
'[动画表情]',
'[自定义消息]',
'[群提示消息]',
'[聊天记录]',
];
export default class ConversationModel extends TUIBase implements IConversationModel {
public conversationID!: string;
public type!: string;
public subType!: string;
public unreadCount!: number;
public lastMessage!: {
nick: string;
nameCard: string;
lastTime: number;
lastSequence: string;
fromAccount: string;
isRevoked: boolean;
revoker?: string | undefined;
isPeerRead: boolean;
messageForShow: string;
type: string;
payload: any;
};
public groupProfile?: any;
public userProfile?: any;
public groupAtInfoList!: any[];
public remark!: string;
public isPinned!: boolean;
public messageRemindType!: string;
public markList!: string[];
public customData!: string;
public conversationGroupList!: any[];
public draftText!: string;
public isMuted!: boolean;
public operationType!: number;
public _conversation: any;
constructor(options: any) {
super();
this.initProxy(options);
this.isMuted = (this.messageRemindType === this.getEngine().TYPES.MSG_REMIND_ACPT_NOT_NOTE)
|| (this.messageRemindType === this.getEngine().TYPES.MSG_REMIND_DISCARD);
this.operationType = 0;
this._conversation = options;
}
/**
* 初始化挂载 conversation 字段
*/
private initProxy(options: any) {
Object.keys(options).forEach((key) => {
if (!isPrivateKey(key)) {
(this as any)[key] = options[key];
}
});
}
updateProperties(options: any) {
Object.keys(options).forEach((key) => {
if (!isPrivateKey(key)) {
(this as any)[key] = options[key];
}
});
}
updateOperationType(operationType: number) {
this.operationType = operationType;
}
getConversation() {
return this._conversation;
}
setMessageRead() {
return this.getEngine().TUIConversation.setMessageRead(this.conversationID);
}
// 以下方法用于处理 conversation 需要展示的数据
getAvatar() {
const chatEngine = this.getEngine();
let avatar = '';
switch (this.type) {
case chatEngine.TYPES.CONV_C2C:
avatar = isUrl(this.userProfile?.avatar) ? this.userProfile?.avatar : AVATAR.C2C;
break;
case chatEngine.TYPES.CONV_GROUP:
avatar = isUrl(this.groupProfile?.avatar) ? this.groupProfile?.avatar : AVATAR.GROUP;
break;
case chatEngine.TYPES.CONV_SYSTEM:
avatar = isUrl(this.groupProfile?.avatar) ? this.groupProfile?.avatar : AVATAR.SYSTEM;
break;
default:
break;
}
return avatar;
}
getShowName() {
const chatEngine = this.getEngine();
let name = '';
switch (this.type) {
case chatEngine.TYPES.CONV_C2C:
name = this.remark || this.userProfile?.nick || this.userProfile?.userID || '';
break;
case chatEngine.TYPES.CONV_GROUP:
name = this.groupProfile?.name || this.groupProfile?.groupID || '';
break;
case chatEngine.TYPES.CONV_SYSTEM:
name = '系统通知';
break;
default:
break;
}
return name;
}
}
@@ -0,0 +1,59 @@
// @ts-nocheck
import type { Group } from '@tencentcloud/chat';
import type TencentCloudChat from '@tencentcloud/chat';
import type { IGroupModel } from '../interface/model';
import { isPrivateKey } from '../utils/common-utils';
export default class GroupModel implements IGroupModel {
public groupID!: string;
public name!: string;
public avatar!: string;
public type!: TencentCloudChat.TYPES.GRP_WORK
| TencentCloudChat.TYPES.GRP_PUBLIC
| TencentCloudChat.TYPES.GRP_MEETING
| TencentCloudChat.TYPES.GRP_AVCHATROOM
| TencentCloudChat.TYPES.GRP_COMMUNITY;
public introduction!: string;
public notification!: string;
public ownerID!: string;
public createTime!: number;
public infoSequence?: number | undefined;
public lastInfoTime?: number | undefined;
public selfInfo?: {
role?: string | undefined;
messageRemindType?: string | undefined;
joinTime?: number | undefined;
nameCard?: string | undefined;
userID?: string | undefined;
memberCustomField?: any[] | undefined;
} | undefined;
public lastMessage?: any;
public nextMessageSeq!: number;
public memberCount!: number;
public maxMemberCount!: number;
public muteAllMembers!: boolean;
public joinOption!: string;
public inviteOption!: string;
public groupCustomField?: any[] | undefined;
public isSupportTopic!: boolean;
public groupAttributes: any;
public groupCounters: any;
constructor(options: Group) {
this.groupAttributes = {};
this.groupCounters = {};
this.initProxy(options);
}
/**
* 初始化挂载 group 字段
*/
private initProxy(options: Group) {
Object.keys(options).forEach((key) => {
if (!isPrivateKey(key)) {
(this as any)[key] = options[key as keyof Group];
}
});
}
}
@@ -0,0 +1,177 @@
/* eslint-disable prefer-promise-reject-errors */
// @ts-nocheck
import type { Conversation, Message } from '@tencentcloud/chat';
import type TencentCloudChat from '@tencentcloud/chat';
import { ERROR_CODE_ENGINE, ERROR_MSG_ENGINE } from '../const';
import type { IConversationModel, IMessageModel } from '../interface/model';
import { isPrivateKey, isUndefined } from '../utils/common-utils';
import TUIBase from '../tui-base';
import type { ModifyMessageParams, ReactionInfo } from '../type';
export default class MessageModel extends TUIBase implements IMessageModel {
public ID!: string;
public type!: TencentCloudChat.TYPES;
payload: any;
conversationID!: string;
conversationType!: TencentCloudChat.TYPES;
to!: string;
from!: string;
flow!: string;
time!: number;
status!: string;
isRevoked!: boolean;
priority!: TencentCloudChat.TYPES;
nick!: string;
avatar!: string;
isPeerRead!: boolean;
nameCard!: string;
atUserList!: string[];
cloudCustomData!: string;
isDeleted!: boolean;
isModified!: boolean;
needReadReceipt!: boolean;
readReceiptInfo!: {
readCount?: number;
unreadCount?: number;
isPeerRead?: boolean;
};
isBroadcastMessage!: boolean;
isSupportExtension!: boolean;
receiverList!: string[];
revoker!: string;
sequence!: number;
progress!: number;
revokerInfo!: { userID: string; nick: string; avatar: string };
revokeReason!: string;
hasRiskContent!: boolean;
reactionList!: ReactionInfo[];
private _message: Message;
private _signalingInfo!: any; // 默认值 undefined_signalingInfo 的类型是 undefinednull|object,因为 getSignalingInfo 返回值是 null|object,枚举会引起编译报错,所以此处用 any 代替。
// 维护映射关系,方便使用
private messageHandlers = {
[this.getEngine().TYPES.MSG_TEXT]: (message: Message) => this.getEngine().TUIChat.messageHandler.handleTextMessage(message),
[this.getEngine().TYPES.MSG_FACE]: (message: Message) => this.getEngine().TUIChat.messageHandler.handleFaceMessage(message),
[this.getEngine().TYPES.MSG_LOCATION]: (message: Message) => this.getEngine().TUIChat.messageHandler.handleLocationMessage(message),
[this.getEngine().TYPES.MSG_IMAGE]: (message: Message) => this.getEngine().TUIChat.messageHandler.handleImageMessage(message),
[this.getEngine().TYPES.MSG_AUDIO]: (message: Message) => this.getEngine().TUIChat.messageHandler.handleAudioMessage(message),
[this.getEngine().TYPES.MSG_VIDEO]: (message: Message) => this.getEngine().TUIChat.messageHandler.handleVideoMessage(message),
[this.getEngine().TYPES.MSG_FILE]: (message: Message) => this.getEngine().TUIChat.messageHandler.handleFileMessage(message),
[this.getEngine().TYPES.MSG_CUSTOM]: (message: Message) => this.getEngine().TUIChat.messageHandler.handleCustomMessage(message),
[this.getEngine().TYPES.MSG_MERGER]: (message: Message) => this.getEngine().TUIChat.messageHandler.handleMergeMessage(message),
[this.getEngine().TYPES.MSG_GRP_TIP]: (message: Message) => this.getEngine().TUIChat.messageHandler.handleGroupTipsMessage(message),
};
constructor(options: Message) {
super();
this._message = options;
this._signalingInfo = undefined;
this.progress = 0;
this.reactionList = [];
this.initProperties(options);
}
/**
* 初始化 messageModel 属性
*/
private initProperties(options: Message): void {
Object.keys(options).forEach((key) => {
if (!isPrivateKey(key)) {
(this as any)[key] = options[key as keyof Message];
}
});
}
updateProperties(options: Message): void {
this._message = options;
Object.keys(options).forEach((key) => {
if (!isPrivateKey(key)) {
(this as any)[key] = options[key as keyof Message];
}
});
}
getMessage() {
return this._message;
}
modifyMessage(options: ModifyMessageParams) {
if (options.type && this._message.type !== options.type && !options.payload) {
return Promise.reject({
code: ERROR_CODE_ENGINE.MISMATCH_TYPE_AND_PAYLOAD,
message: ERROR_MSG_ENGINE.MISMATCH_TYPE_AND_PAYLOAD,
});
}
this._message.type = options.type || this._message.type;
this._message.payload = options.payload || this._message.payload;
this._message.cloudCustomData = options.cloudCustomData || this._message.cloudCustomData;
return this.getEngine().TUIChat.modifyMessage(this._message);
}
revokeMessage() {
return this.getEngine().TUIChat.revokeMessage(this._message);
}
resendMessage() {
return this.getEngine().TUIChat.resendMessage(this._message);
}
deleteMessage() {
return this.getEngine().TUIChat.deleteMessage([this._message]);
}
quoteMessage() {
return this.getEngine().TUIChat.quoteMessage(this._message);
}
replyMessage() {
return this.getEngine().TUIChat.replyMessage(this._message);
}
setMessageExtensions(extensions: Record<string, any>[]) {
return this.getEngine().TUIChat.setMessageExtensions(this._message, extensions);
}
getMessageExtensions() {
return this.getEngine().TUIChat.getMessageExtensions(this._message);
}
deleteMessageExtensions(keyList?: string[]) {
return this.getEngine().TUIChat.deleteMessageExtensions(this._message, keyList);
}
getSignalingInfo() {
if (this.type !== this.getEngine().TYPES.MSG_CUSTOM) {
return null;
}
if (isUndefined(this._signalingInfo)) {
this._signalingInfo = this.getEngine().chat.getSignalingInfo(this._message);
return this._signalingInfo;
}
return this._signalingInfo;
}
getMessageContent() {
const handler = this.messageHandlers[this.type as any];
if (isUndefined(handler)) {
return {};
}
// 群提示消息不支持 showName
if (this.type === this.getEngine().TYPES.MSG_GRP_TIP) {
return handler(this._message);
}
// 普通消息发送方名称显示优先级(对齐微信体验)
// C2C 会话:remark > nick > userID
// 群会话:remark > nameCard > nick > userID
// const friendRemark: any = this.getEngine().TUIFriend.getFriendRemark([this.from]);
return {
...handler(this._message),
showName: this.nick || this.from,
};
}
sendForwardMessage(conversationList: Conversation[] | IConversationModel[]) {
return this.getEngine().TUIChat.sendForwardMessage(conversationList, [this._message]);
}
}