oa_based/src/modules/sse/sse.service.ts

86 lines
2.1 KiB
TypeScript
Raw Normal View History

2024-02-28 08:32:35 +08:00
import { Injectable } from '@nestjs/common'
import { Subscriber } from 'rxjs'
import { In } from 'typeorm'
import { ROOT_ROLE_ID } from '~/constants/system.constant'
import { RoleEntity } from '~/modules/system/role/role.entity'
import { UserEntity } from '~/modules/user/user.entity'
export interface MessageEvent {
data?: string | object
id?: string
type?: 'ping' | 'close' | 'updatePermsAndMenus'
retry?: number
}
const clientMap: Map<number, Subscriber<MessageEvent>> = new Map()
@Injectable()
export class SseService {
addClient(uid: number, subscriber: Subscriber<MessageEvent>) {
clientMap.set(uid, subscriber)
}
removeClient(uid: number): void {
const client = clientMap.get(uid)
client?.complete()
clientMap.delete(uid)
}
sendToClient(uid: number, data: MessageEvent): void {
const client = clientMap.get(uid)
client?.next?.(data)
}
sendToAll(data: MessageEvent): void {
clientMap.forEach((client) => {
client.next(data)
})
}
/**
*
* @param uid
* @constructor
*/
async noticeClientToUpdateMenusByUserIds(uid: number | number[]) {
const userIds = [].concat(uid) as number[]
userIds.forEach((uid) => {
this.sendToClient(uid, { type: 'updatePermsAndMenus' })
})
}
/**
* menuIds通知用户更新权限菜单
*/
async noticeClientToUpdateMenusByMenuIds(menuIds: number[]): Promise<void> {
const roleMenus = await RoleEntity.find({
where: {
menus: {
id: In(menuIds),
},
},
})
const roleIds = roleMenus.map(n => n.id).concat(ROOT_ROLE_ID)
await this.noticeClientToUpdateMenusByRoleIds(roleIds)
}
/**
* roleIds通知用户更新权限菜单
*/
async noticeClientToUpdateMenusByRoleIds(roleIds: number[]): Promise<void> {
const users = await UserEntity.find({
where: {
roles: {
id: In(roleIds),
},
},
})
if (users) {
const userIds = users.map(n => n.id)
await this.noticeClientToUpdateMenusByUserIds(userIds)
}
}
}