Files
prism/backend/src/modules/conversations/conversations.service.ts

96 lines
3.8 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Injectable, NotFoundException, ForbiddenException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Conversation } from './entities/conversation.entity';
import { User } from '../users/entities/user.entity';
@Injectable()
export class ConversationsService {
constructor(
@InjectRepository(Conversation)
private conversationsRepository: Repository<Conversation>,
) {}
async create(participants: User[], name?: string, isGroup = false): Promise<Conversation> {
const conversation = this.conversationsRepository.create({
participants,
name,
isGroup,
});
return this.conversationsRepository.save(conversation);
}
async findAllForUser(userId: string): Promise<Conversation[]> {
return this.conversationsRepository
.createQueryBuilder('conversation')
.leftJoinAndSelect('conversation.participants', 'participants')
.leftJoinAndSelect('conversation.messages', 'messages')
.leftJoin('conversation.participants', 'user')
.where('user.id = :userId', { userId })
.orderBy('messages.createdAt', 'DESC')
.getMany();
}
async findOne(id: string, userId: string): Promise<Conversation> {
const conversation = await this.conversationsRepository
.createQueryBuilder('conversation')
.leftJoinAndSelect('conversation.participants', 'participants')
.leftJoinAndSelect('conversation.messages', 'messages')
.leftJoinAndSelect('messages.sender', 'sender')
.where('conversation.id = :id', { id })
.orderBy('messages.createdAt', 'ASC')
.getOne();
if (!conversation) {
throw new NotFoundException('Беседа не найдена');
}
const isParticipant = conversation.participants.some(p => p.id === userId);
if (!isParticipant) {
throw new ForbiddenException('Вы не являетесь участником этой беседы');
}
return conversation;
}
async findOrCreatePrivate(user1Id: string, user2Id: string): Promise<Conversation> {
// Проверяем существующую приватную беседу между двумя пользователями
const existingConversation = await this.conversationsRepository
.createQueryBuilder('conversation')
.leftJoinAndSelect('conversation.participants', 'participants')
.where('conversation.isGroup = false')
.andWhere((qb) => {
const subQuery = qb.subQuery()
.select('c.id')
.from('conversations', 'c')
.leftJoin('conversation_participants', 'cp1', 'cp1.conversationId = c.id')
.leftJoin('conversation_participants', 'cp2', 'cp2.conversationId = c.id')
.where('c.isGroup = false')
.andWhere('cp1.userId = :user1Id', { user1Id })
.andWhere('cp2.userId = :user2Id', { user2Id })
.andWhere('(SELECT COUNT(*) FROM conversation_participants WHERE conversationId = c.id) = 2')
.getQuery();
return 'conversation.id IN ' + subQuery;
})
.getOne();
if (existingConversation) {
return existingConversation;
}
// Создаем новую приватную беседу с двумя участниками
const participants = [{ id: user1Id }, { id: user2Id }] as any;
return this.create(participants, undefined, false);
}
async addParticipant(conversationId: string, userId: string, participantId: string): Promise<Conversation> {
const conversation = await this.findOne(conversationId, userId);
if (!conversation.isGroup) {
throw new ForbiddenException('Нельзя добавлять участников в приватные беседы');
}
// Добавляем участника
return conversation;
}
}