更新
This commit is contained in:
@@ -0,0 +1,474 @@
|
||||
import type { Group, GroupMember, Message } from '@tencentcloud/lite-chat/basic';
|
||||
import type { ITUIGroupService } from '../interface/service';
|
||||
import type {
|
||||
AddMemberParams,
|
||||
ChangGroupOwnerParams,
|
||||
CountersParams,
|
||||
CreateGroupParams,
|
||||
DeleteMemberParams,
|
||||
GetGroupProfileParams,
|
||||
GetMemberListParams,
|
||||
GetMemberProfileParams,
|
||||
GroupAttrParams,
|
||||
JoinGroupParams,
|
||||
KeyListParams,
|
||||
MarkMemberParams,
|
||||
SetCountersParams,
|
||||
SetMemberCustomFiledParams,
|
||||
SetMemberMuteParams,
|
||||
SetMemberNameCardParams,
|
||||
SetMemberRoleParams,
|
||||
UpdateGroupParams,
|
||||
handleGroupApplicationParams,
|
||||
} from '../type';
|
||||
import type GroupModel from '../model/group';
|
||||
import type { IGroupModel } from '../interface/model';
|
||||
import TUIBase from '../tui-base';
|
||||
import { StoreName } from '../const';
|
||||
import { isUndefined } from '../utils/common-utils';
|
||||
|
||||
export default class TUIGroupService extends TUIBase implements ITUIGroupService {
|
||||
static instance: TUIGroupService;
|
||||
private groupMap: Map<string, any>;
|
||||
constructor() {
|
||||
super();
|
||||
this.groupMap = new Map();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取 TUIGroupService 实例
|
||||
*/
|
||||
static getInstance() {
|
||||
if (!TUIGroupService.instance) {
|
||||
TUIGroupService.instance = new TUIGroupService();
|
||||
}
|
||||
return TUIGroupService.instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化 Service
|
||||
*/
|
||||
public init() {
|
||||
const chatEngine = this.getEngine();
|
||||
chatEngine.eventCenter.addEvent(chatEngine.EVENT.GROUP_LIST_UPDATED, this.onGroupListUpdated.bind(this));
|
||||
chatEngine.eventCenter.addEvent(chatEngine.EVENT.GROUP_ATTRIBUTES_UPDATED, this.onGroupAttributesUpdated.bind(this));
|
||||
chatEngine.eventCenter.addEvent(chatEngine.EVENT.GROUP_COUNTER_UPDATED, this.onGroupCounterUpdated.bind(this));
|
||||
chatEngine.eventCenter.addEvent(chatEngine.EVENT.MESSAGE_RECEIVED, this.onMessageReceived.bind(this));
|
||||
this.getGroupInitData();
|
||||
}
|
||||
|
||||
private onGroupListUpdated(groupList: Group[]) {
|
||||
const chatEngine = this.getEngine();
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'groupList', groupList);
|
||||
const currentGroupID = chatEngine.TUIStore.getData(StoreName.GRP, 'currentGroupID');
|
||||
groupList.forEach((item: Group) => {
|
||||
if (item.groupID === currentGroupID) {
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'currentGroup', item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private onGroupAttributesUpdated(data: any) {
|
||||
const chatEngine = this.getEngine();
|
||||
const currentGroupID = chatEngine.TUIStore.getData(StoreName.GRP, 'currentGroupID');
|
||||
let groupList = chatEngine.TUIStore.getData(StoreName.GRP, 'groupList');
|
||||
const { groupID, groupAttributes } = data;
|
||||
if (currentGroupID === groupID) {
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'currentGroupAttributes', groupAttributes);
|
||||
}
|
||||
groupList = groupList.map((item: GroupModel) => {
|
||||
if (item.groupID === groupID) {
|
||||
item.groupAttributes = groupAttributes;
|
||||
}
|
||||
return item;
|
||||
});
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'groupList', groupList);
|
||||
}
|
||||
|
||||
private onGroupCounterUpdated(data: any) {
|
||||
const chatEngine = this.getEngine();
|
||||
const currentGroupID = chatEngine.TUIStore.getData(StoreName.GRP, 'currentGroupID');
|
||||
const currentGroupCounters = chatEngine.TUIStore.getData(StoreName.GRP, 'currentGroupCounters') || {};
|
||||
let groupList = chatEngine.TUIStore.getData(StoreName.GRP, 'groupList');
|
||||
const { groupID, key, value } = data;
|
||||
if (currentGroupID === groupID) {
|
||||
currentGroupCounters[key] = value;
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'currentGroupCounters', currentGroupCounters);
|
||||
}
|
||||
groupList = groupList.map((item: GroupModel) => {
|
||||
if (item.groupID === groupID) {
|
||||
item.groupCounters = {
|
||||
...item.groupCounters,
|
||||
[key]: value,
|
||||
};
|
||||
}
|
||||
return item;
|
||||
});
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'groupList', groupList);
|
||||
}
|
||||
|
||||
private onMessageReceived(messageList: Message[]) {
|
||||
const chatEngine = this.getEngine();
|
||||
const groupSystemNoticeList: Message[] = [];
|
||||
messageList.forEach((message: Message) => {
|
||||
if (message.type === chatEngine.TYPES.MSG_GRP_TIP) {
|
||||
const { payload } = message;
|
||||
const { operationType, userIDList } = payload;
|
||||
switch (operationType) {
|
||||
case chatEngine.TYPES.GRP_TIP_MBR_JOIN:
|
||||
this.addMemberList(userIDList);
|
||||
break;
|
||||
case chatEngine.TYPES.GRP_TIP_MBR_QUIT:
|
||||
this.removeMemberList(userIDList);
|
||||
break;
|
||||
case chatEngine.TYPES.GRP_TIP_MBR_KICKED_OUT:
|
||||
this.removeMemberList(userIDList);
|
||||
break;
|
||||
case chatEngine.TYPES.GRP_TIP_MBR_SET_ADMIN:
|
||||
this.updateGroupMember(userIDList);
|
||||
break;
|
||||
case chatEngine.TYPES.GRP_TIP_MBR_CANCELED_ADMIN:
|
||||
this.updateGroupMember(userIDList);
|
||||
break;
|
||||
case chatEngine.TYPES.GRP_TIP_GRP_PROFILE_UPDATED:
|
||||
// v2.3.3, update currentGroup by GROUP_LIST_UPDATED when group profile is updated.
|
||||
break;
|
||||
case chatEngine.TYPES.GRP_TIP_MBR_PROFILE_UPDATED:
|
||||
this.updateGroupMember(userIDList);
|
||||
break;
|
||||
case chatEngine.TYPES.GRP_TIP_BAN_AVCHATROOM_MEMBER:
|
||||
this.updateGroupMember(userIDList);
|
||||
break;
|
||||
case chatEngine.TYPES.GRP_TIP_UNBAN_AVCHATROOM_MEMBER:
|
||||
this.updateGroupMember(userIDList);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (message.type === chatEngine.TYPES.MSG_GRP_SYS_NOTICE) {
|
||||
groupSystemNoticeList.push(message);
|
||||
}
|
||||
});
|
||||
if (groupSystemNoticeList.length > 0) {
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'groupSystemNoticeList', groupSystemNoticeList);
|
||||
}
|
||||
}
|
||||
|
||||
private getGroupInitData() {
|
||||
const chatEngine = this.getEngine();
|
||||
// TUIChatEngine 无 UI 集成时不需要执行此逻辑
|
||||
if (!chatEngine.chat.isReady()) {
|
||||
return;
|
||||
}
|
||||
chatEngine.chat.getGroupList().then((imResponse: any) => {
|
||||
const { groupList = [] } = imResponse.data;
|
||||
console.log(`TUIGroupService.init, getGroupList count:${groupList.length}`);
|
||||
if (groupList.length > 0) {
|
||||
this.onGroupListUpdated(groupList);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private async updateGroupMember(userIDList: string[]) {
|
||||
const groupID = this.getEngine().TUIStore.getData(StoreName.GRP, 'currentGroupID');
|
||||
if (groupID) {
|
||||
const imResponse = await this.getGroupMemberProfile({
|
||||
groupID,
|
||||
userIDList,
|
||||
});
|
||||
const { memberList } = imResponse.data;
|
||||
this.updateMemberList(memberList);
|
||||
}
|
||||
}
|
||||
|
||||
private resetCurrentStore() {
|
||||
const keyList = [
|
||||
'currentGroupID',
|
||||
'currentGroup',
|
||||
'currentGroupAttributes',
|
||||
'currentGroupCounters',
|
||||
'currentGroupMemberList',
|
||||
];
|
||||
this.getEngine().TUIStore.reset(StoreName.GRP, keyList, true);
|
||||
}
|
||||
|
||||
public async switchGroup(groupID: string) {
|
||||
const chatEngine = this.getEngine();
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'offset', 0);
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'isCompleted', false);
|
||||
|
||||
const conversation = chatEngine.TUIStore.getConversationModel(`GROUP${groupID}`);
|
||||
// operationType > 0 说明用户已经不在群组内了,直接返回
|
||||
if (conversation?.operationType > 0) {
|
||||
const currentGroup = chatEngine.TUIStore.getData(StoreName.GRP, 'currentGroup');
|
||||
return Promise.resolve(currentGroup);
|
||||
}
|
||||
const currentGroupID = chatEngine.TUIStore.getData(StoreName.GRP, 'currentGroupID');
|
||||
if (!groupID) {
|
||||
this.resetCurrentStore();
|
||||
return Promise.resolve({});
|
||||
}
|
||||
if (currentGroupID === groupID) {
|
||||
const currentGroup = chatEngine.TUIStore.getData(StoreName.GRP, 'currentGroup');
|
||||
return Promise.resolve(currentGroup);
|
||||
}
|
||||
this.resetCurrentStore();
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'currentGroupID', groupID);
|
||||
try {
|
||||
await this.getGroupInfo(groupID);
|
||||
} catch (error) {
|
||||
throw error
|
||||
}
|
||||
// 5s 后删除是为了解决快速反复切换到群管理操作面板是重复调用问题
|
||||
const timer = setTimeout(() => {
|
||||
this.groupMap.delete(groupID);
|
||||
clearTimeout(timer);
|
||||
}, 5000);
|
||||
const currentGroup = chatEngine.TUIStore.getData(StoreName.GRP, 'currentGroup');
|
||||
return Promise.resolve(currentGroup);
|
||||
}
|
||||
|
||||
private async getGroupInfo(groupID: string) {
|
||||
const chatEngine = this.getEngine();
|
||||
const currentGroupMap = this.groupMap.get(groupID);
|
||||
if (currentGroupMap) {
|
||||
this.updateMemberList(currentGroupMap?.memberList || []);
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'currentGroup', currentGroupMap.group);
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'currentGroupAttributes', currentGroupMap.groupAttributes || {});
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'currentGroupCounters', currentGroupMap.counters || {});
|
||||
return;
|
||||
}
|
||||
const groupInfo = {
|
||||
group: {},
|
||||
memberList: [],
|
||||
groupAttributes: undefined,
|
||||
counters: undefined,
|
||||
};
|
||||
const { data: { group } } = await this.getGroupProfile({ groupID });
|
||||
groupInfo.group = group;
|
||||
const { data: { memberList } } = await this.getGroupMemberList({ groupID });
|
||||
groupInfo.memberList = memberList;
|
||||
const attributesRes = await this.getGroupAttributes({ groupID, keyList: [] });
|
||||
const { groupAttributes } = attributesRes.data;
|
||||
groupInfo.groupAttributes = groupAttributes;
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'currentGroupAttributes', groupAttributes);
|
||||
try {
|
||||
const countersRes = await this.getGroupCounters({ groupID, keyList: [] });
|
||||
const { counters } = countersRes.data;
|
||||
groupInfo.counters = counters;
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'currentGroupCounters', counters);
|
||||
} catch (error: any) {
|
||||
console.warn(error?.message); // 旗舰功能,预防初次跑通(直接打印 error uni 打包小程序会报错)
|
||||
}
|
||||
this.groupMap.set(groupID, groupInfo);
|
||||
}
|
||||
|
||||
public getGroupProfile(options: GetGroupProfileParams) {
|
||||
const chatEngine = this.getEngine();
|
||||
return chatEngine.chat.getGroupProfile(options).then(async (imResponse: any) => {
|
||||
const currentGroupID = chatEngine.TUIStore.getData(StoreName.GRP, 'currentGroupID');
|
||||
if (currentGroupID === options.groupID) {
|
||||
const { group } = imResponse.data;
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'currentGroup', group);
|
||||
}
|
||||
return imResponse;
|
||||
});
|
||||
}
|
||||
|
||||
public updateGroupProfile(options: UpdateGroupParams) {
|
||||
return this.getEngine().chat.updateGroupProfile(options);
|
||||
}
|
||||
|
||||
public createGroup(options: CreateGroupParams) {
|
||||
return this.getEngine().chat.createGroup(options);
|
||||
}
|
||||
|
||||
public dismissGroup(groupID: string) {
|
||||
return this.getEngine().chat.dismissGroup(groupID);
|
||||
}
|
||||
|
||||
public searchGroupByID(groupID: string) {
|
||||
const chatEngine = this.getEngine();
|
||||
return chatEngine.chat.searchGroupByID(groupID).then((imResponse: any) => {
|
||||
const { group } = imResponse.data;
|
||||
const groupList = chatEngine.TUIStore.getData(StoreName.GRP, 'groupList');
|
||||
imResponse.data.group.isJoinedGroup = groupList.some((item: IGroupModel) => item.groupID === group.groupID);
|
||||
return imResponse;
|
||||
});
|
||||
}
|
||||
|
||||
public joinGroup(options: JoinGroupParams) {
|
||||
return this.getEngine().chat.joinGroup(options);
|
||||
}
|
||||
|
||||
public quitGroup(groupID: string) {
|
||||
return this.getEngine().chat.quitGroup(groupID);
|
||||
}
|
||||
|
||||
public getGroupApplicationList() {
|
||||
return this.getEngine().chat.getGroupApplicationList();
|
||||
}
|
||||
|
||||
public handleGroupApplication(options: handleGroupApplicationParams) {
|
||||
return this.getEngine().chat.handleGroupApplication(options);
|
||||
}
|
||||
|
||||
public getGroupOnlineMemberCount(groupID: string) {
|
||||
return this.getEngine().chat.getGroupOnlineMemberCount(groupID);
|
||||
}
|
||||
|
||||
public changeGroupOwner(options: ChangGroupOwnerParams) {
|
||||
return this.getEngine().chat.changeGroupOwner(options);
|
||||
}
|
||||
|
||||
public initGroupAttributes(options: GroupAttrParams) {
|
||||
return this.getEngine().chat.initGroupAttributes(options);
|
||||
}
|
||||
|
||||
public setGroupAttributes(options: GroupAttrParams) {
|
||||
return this.getEngine().chat.setGroupAttributes(options);
|
||||
}
|
||||
|
||||
public deleteGroupAttributes(options: KeyListParams) {
|
||||
return this.getEngine().chat.deleteGroupAttributes(options);
|
||||
}
|
||||
|
||||
public getGroupAttributes(options: KeyListParams) {
|
||||
return this.getEngine().chat.getGroupAttributes(options);
|
||||
}
|
||||
|
||||
public setGroupCounters(options: SetCountersParams) {
|
||||
return this.getEngine().chat.setGroupCounters(options);
|
||||
}
|
||||
|
||||
public increaseGroupCounter(options: CountersParams) {
|
||||
return this.getEngine().chat.increaseGroupCounter(options);
|
||||
}
|
||||
|
||||
public decreaseGroupCounter(options: CountersParams) {
|
||||
return this.getEngine().chat.decreaseGroupCounter(options);
|
||||
}
|
||||
|
||||
public getGroupCounters(options: KeyListParams) {
|
||||
return this.getEngine().chat.getGroupCounters(options);
|
||||
}
|
||||
|
||||
// group member
|
||||
private updateMemberList(memberList: GroupMember[]) {
|
||||
const chatEngine = this.getEngine();
|
||||
const currentGroupMemberList = chatEngine.TUIStore.getData(StoreName.GRP, 'currentGroupMemberList') || [];
|
||||
const filterMemberList = currentGroupMemberList.filter((currentMember: GroupMember) => {
|
||||
const isExist = memberList.find((member: GroupMember) => member.userID === currentMember.userID);
|
||||
return !isExist;
|
||||
});
|
||||
const newMemberList = [...filterMemberList, ...memberList];
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'currentGroupMemberList', newMemberList);
|
||||
}
|
||||
|
||||
private async addMemberList(userIDList: string[]) {
|
||||
const groupID = this.getEngine().TUIStore.getData(StoreName.GRP, 'currentGroupID');
|
||||
if (groupID) {
|
||||
try {
|
||||
const imResponse = await this.getGroupMemberProfile({
|
||||
groupID,
|
||||
userIDList,
|
||||
});
|
||||
const { memberList } = imResponse.data;
|
||||
this.updateMemberList(memberList);
|
||||
} catch (error) {
|
||||
const memberList: GroupMember[] = userIDList.map((userID: string) => {
|
||||
const GroupMember = {
|
||||
userID,
|
||||
avatar: '',
|
||||
nick: '',
|
||||
role: '',
|
||||
joinTime: 0,
|
||||
nameCard: '',
|
||||
muteUntil: 0,
|
||||
memberCustomField: [],
|
||||
};
|
||||
return GroupMember;
|
||||
});
|
||||
this.updateMemberList(memberList);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private removeMemberList(userIDList: string[]) {
|
||||
const chatEngine = this.getEngine();
|
||||
const currentGroupMemberList = chatEngine.TUIStore.getData(StoreName.GRP, 'currentGroupMemberList');
|
||||
const newMemberList = currentGroupMemberList.filter((member: GroupMember) => userIDList.indexOf(member.userID) === -1);
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'currentGroupMemberList', newMemberList);
|
||||
}
|
||||
|
||||
public getGroupMemberList(options: GetMemberListParams) {
|
||||
const chatEngine = this.getEngine();
|
||||
if (isUndefined(options.offset)) {
|
||||
const _offset = chatEngine.TUIStore.getData(StoreName.GRP, 'offset');
|
||||
options.offset = _offset;
|
||||
}
|
||||
return chatEngine.chat.getGroupMemberList(options).then((imResponse: any) => {
|
||||
const currentGroupID = chatEngine.TUIStore.getData(StoreName.GRP, 'currentGroupID');
|
||||
if (currentGroupID === options.groupID) {
|
||||
const { memberList, offset = 0 } = imResponse.data;
|
||||
this.updateMemberList(memberList);
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'offset', offset);
|
||||
if (offset === 0) {
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'isCompleted', true);
|
||||
}
|
||||
}
|
||||
return imResponse;
|
||||
});
|
||||
}
|
||||
|
||||
public getGroupMemberProfile(options: GetMemberProfileParams) {
|
||||
return this.getEngine().chat.getGroupMemberProfile(options);
|
||||
}
|
||||
|
||||
public addGroupMember(options: AddMemberParams) {
|
||||
const chatEngine = this.getEngine();
|
||||
return chatEngine.chat.addGroupMember(options).then(async (imResponse: any) => {
|
||||
const currentGroupID = chatEngine.TUIStore.getData(StoreName.GRP, 'currentGroupID');
|
||||
if (currentGroupID === options.groupID) {
|
||||
const { successUserIDList, group } = imResponse.data;
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'currentGroup', group);
|
||||
this.addMemberList(successUserIDList);
|
||||
}
|
||||
return imResponse;
|
||||
});
|
||||
}
|
||||
|
||||
public deleteGroupMember(options: DeleteMemberParams) {
|
||||
const chatEngine = this.getEngine();
|
||||
return chatEngine.chat.deleteGroupMember(options).then((imResponse: any) => {
|
||||
const currentGroupID = chatEngine.TUIStore.getData(StoreName.GRP, 'currentGroupID');
|
||||
if (currentGroupID === options.groupID) {
|
||||
const { userIDList, group } = imResponse.data;
|
||||
this.removeMemberList(userIDList);
|
||||
chatEngine.TUIStore.update(StoreName.GRP, 'currentGroup', group);
|
||||
}
|
||||
return imResponse;
|
||||
});
|
||||
}
|
||||
|
||||
public setGroupMemberMuteTime(options: SetMemberMuteParams) {
|
||||
return this.getEngine().chat.setGroupMemberMuteTime(options);
|
||||
}
|
||||
|
||||
public setGroupMemberRole(options: SetMemberRoleParams) {
|
||||
return this.getEngine().chat.setGroupMemberRole(options);
|
||||
}
|
||||
|
||||
public setGroupMemberNameCard(options: SetMemberNameCardParams) {
|
||||
return this.getEngine().chat.setGroupMemberNameCard(options);
|
||||
}
|
||||
|
||||
public setGroupMemberCustomField(options: SetMemberCustomFiledParams) {
|
||||
return this.getEngine().chat.setGroupMemberCustomField(options);
|
||||
}
|
||||
|
||||
public markGroupMemberList(options: MarkMemberParams) {
|
||||
return this.getEngine().chat.markGroupMemberList(options);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user