86 lines
2.1 KiB
TypeScript
86 lines
2.1 KiB
TypeScript
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);
|
|
}
|
|
}
|
|
}
|