From 5dcfabe0149f196d718bed18e7e99f60d3181c94 Mon Sep 17 00:00:00 2001 From: moonrailgun Date: Wed, 14 Sep 2022 15:21:52 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=B6=E4=BB=B6=E7=AE=B1=E5=90=8E?= =?UTF-8?q?=E7=AB=AF=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 监听新的提及信息 --- server/models/chat/inbox.ts | 35 ++++- server/packages/sdk/src/services/base.ts | 8 +- server/packages/sdk/src/structs/events.ts | 5 + .../services/core/chat/inbox.service.dev.ts | 120 ++++++++++++++++-- server/services/core/chat/message.service.ts | 8 ++ 5 files changed, 156 insertions(+), 20 deletions(-) diff --git a/server/models/chat/inbox.ts b/server/models/chat/inbox.ts index 6a63023f..6161ea31 100644 --- a/server/models/chat/inbox.ts +++ b/server/models/chat/inbox.ts @@ -10,13 +10,16 @@ import type { Types } from 'mongoose'; import { User } from '../user/user'; import { Message } from './message'; -/** - * 收件箱管理 - */ -@index({ userId: 1 }) -export class Inbox extends TimeStamps implements Base { - _id: Types.ObjectId; - id: string; +class InboxMessage { + /** + * 消息所在群组Id + */ + groupId?: string; + + /** + * 消息所在会话Id + */ + converseId: string; @prop({ ref: () => Message, @@ -28,7 +31,15 @@ export class Inbox extends TimeStamps implements Base { */ @prop() messageSnippet: string; +} +/** + * 收件箱管理 + */ +@index({ userId: 1 }) +export class Inbox extends TimeStamps implements Base { + _id: Types.ObjectId; + id: string; /** * 接收方的id */ @@ -36,6 +47,16 @@ export class Inbox extends TimeStamps implements Base { ref: () => User, }) userId: Ref; + + @prop({ + type: () => String, + }) + type: 'message'; + + @prop({ + type: () => InboxMessage, + }) + message?: InboxMessage; } export type InboxDocument = DocumentType; diff --git a/server/packages/sdk/src/services/base.ts b/server/packages/sdk/src/services/base.ts index 20841447..4078ca12 100644 --- a/server/packages/sdk/src/services/base.ts +++ b/server/packages/sdk/src/services/base.ts @@ -315,7 +315,7 @@ export abstract class TcService extends Service { * 单播推送socket事件 */ unicastNotify( - ctx: TcContext, + ctx: TcPureContext, userId: string, eventName: string, eventData: unknown @@ -332,7 +332,7 @@ export abstract class TcService extends Service { * 列播推送socket事件 */ listcastNotify( - ctx: TcContext, + ctx: TcPureContext, userIds: string[], eventName: string, eventData: unknown @@ -349,7 +349,7 @@ export abstract class TcService extends Service { * 组播推送socket事件 */ roomcastNotify( - ctx: TcContext, + ctx: TcPureContext, roomId: string, eventName: string, eventData: unknown @@ -365,7 +365,7 @@ export abstract class TcService extends Service { * 群播推送socket事件 */ broadcastNotify( - ctx: TcContext, + ctx: TcPureContext, eventName: string, eventData: unknown ): Promise { diff --git a/server/packages/sdk/src/structs/events.ts b/server/packages/sdk/src/structs/events.ts index 8e62c765..e1ec3b22 100644 --- a/server/packages/sdk/src/structs/events.ts +++ b/server/packages/sdk/src/structs/events.ts @@ -8,12 +8,17 @@ export interface BuiltinEventMap { 'chat.message.updateMessage': | { type: 'add'; + groupId?: string; + converseId: string; messageId: string; content: string; meta: MessageMetaStruct; } | { type: 'recall' | 'delete'; + groupId?: string; + converseId: string; messageId: string; + meta: MessageMetaStruct; }; } diff --git a/server/services/core/chat/inbox.service.dev.ts b/server/services/core/chat/inbox.service.dev.ts index 4fc89f9d..b183ca67 100644 --- a/server/services/core/chat/inbox.service.dev.ts +++ b/server/services/core/chat/inbox.service.dev.ts @@ -1,6 +1,10 @@ -import { Types } from 'mongoose'; import type { InboxDocument, InboxModel } from '../../../models/chat/inbox'; -import { TcService, TcContext, TcDbService } from 'tailchat-server-sdk'; +import { + TcService, + TcContext, + TcDbService, + TcPureContext, +} from 'tailchat-server-sdk'; /** * 收件箱管理 @@ -16,34 +20,120 @@ class InboxService extends TcService { onInit(): void { this.registerLocalDb(require('../../../models/chat/inbox').default); - this.registerEventListener('chat.message.updateMessage', (payload) => { - // TODO - }); + this.registerEventListener( + 'chat.message.updateMessage', + async (payload, ctx) => { + if ( + Array.isArray(payload.meta.mentions) && + payload.meta.mentions.length > 0 + ) { + const mentions = payload.meta.mentions; + if (payload.type === 'add') { + await Promise.all( + mentions.map((userId) => { + return ctx.call('chat.inbox.appendMessage', { + userId, + groupId: payload.groupId, + converseId: payload.converseId, + messageId: payload.messageId, + messageSnippet: payload.content, + }); + }) + ); + } else if (payload.type === 'delete') { + await Promise.all( + mentions.map((userId) => { + return ctx.call('chat.inbox.removeMessage', { + userId, + groupId: payload.groupId, + converseId: payload.converseId, + messageId: payload.messageId, + }); + }) + ); + } + + this.notifyUsersInboxUpdate(ctx, mentions); + } + } + ); - this.registerAction('append', this.append, { + this.registerAction('appendMessage', this.appendMessage, { visibility: 'public', params: { userId: { type: 'string', optional: true }, + groupId: { type: 'string', optional: true }, + converseId: 'string', messageId: 'string', messageSnippet: 'string', }, }); + this.registerAction('removeMessage', this.removeMessage, { + visibility: 'public', + params: { + userId: { type: 'string', optional: true }, + groupId: { type: 'string', optional: true }, + converseId: 'string', + messageId: 'string', + }, + }); this.registerAction('all', this.all); } - async append( + async appendMessage( ctx: TcContext<{ userId?: string; + groupId?: string; + converseId: string; messageId: string; messageSnippet: string; }> ) { - const { userId = ctx.meta.userId, messageId, messageSnippet } = ctx.params; + const { + userId = ctx.meta.userId, + groupId, + converseId, + messageId, + messageSnippet, + } = ctx.params; await this.adapter.model.create({ userId, + type: 'message', + message: { + groupId, + converseId, + messageId, + messageSnippet, + }, + }); + + return true; + } + + async removeMessage( + ctx: TcContext<{ + userId?: string; + groupId?: string; + converseId: string; + messageId: string; + }> + ) { + const { + userId = ctx.meta.userId, + groupId, + converseId, messageId, - messageSnippet, + } = ctx.params; + + await this.adapter.model.remove({ + userId, + type: 'message', + message: { + groupId, + converseId, + messageId, + }, }); return true; @@ -61,6 +151,18 @@ class InboxService extends TcService { return await this.transformDocuments(ctx, {}, list); } + + /** + * 发送通知群组信息发生变更 + * + * 发送通知时会同时清空群组信息缓存 + */ + private async notifyUsersInboxUpdate( + ctx: TcPureContext, + userIds: string[] + ): Promise { + await this.listcastNotify(ctx, userIds, 'updated', {}); + } } export default InboxService; diff --git a/server/services/core/chat/message.service.ts b/server/services/core/chat/message.service.ts index 067edcb6..cfd88952 100644 --- a/server/services/core/chat/message.service.ts +++ b/server/services/core/chat/message.service.ts @@ -139,6 +139,8 @@ class MessageService extends TcService { ctx.emit('chat.message.updateMessage', { type: 'add', + groupId: String(groupId), + converseId: String(converseId), messageId: String(message._id), content, meta, @@ -204,7 +206,10 @@ class MessageService extends TcService { this.roomcastNotify(ctx, converseId, 'update', json); ctx.emit('chat.message.updateMessage', { type: 'recall', + groupId: String(groupId), + converseId: String(converseId), messageId: String(message._id), + meta: message.meta, }); return json; @@ -241,7 +246,10 @@ class MessageService extends TcService { this.roomcastNotify(ctx, converseId, 'delete', { converseId, messageId }); ctx.emit('chat.message.updateMessage', { type: 'delete', + groupId: String(groupId), + converseId: String(converseId), messageId: String(message._id), + meta: message.meta, }); return true;