Thêm tính năng bình luận ở mỗi điểm của chặng
This commit is contained in:
+85
-6
@@ -7,7 +7,9 @@ dotenv.config({ path: envPath });
|
||||
|
||||
import 'reflect-metadata';
|
||||
import { NestFactory } from '@nestjs/core';
|
||||
import { Module, Controller, Get, Post, Body, Param, Patch, Delete, ParseUUIDPipe, NotFoundException, BadRequestException, UnauthorizedException, UseGuards, Req, Query, ForbiddenException } from '@nestjs/common';
|
||||
import { Module, Controller, Get, Post, Body, Param, Patch, Delete, ParseUUIDPipe, NotFoundException, BadRequestException, UnauthorizedException, UseGuards, Req, Query, ForbiddenException, Injectable } from '@nestjs/common';
|
||||
import { WebSocketGateway, WebSocketServer, SubscribeMessage, OnGatewayConnection, OnGatewayDisconnect } from '@nestjs/websockets';
|
||||
import { Server, Socket } from 'socket.io';
|
||||
import { PrismaService } from '../prisma/prisma.service';
|
||||
import * as bcrypt from 'bcrypt';
|
||||
import { AdminGuard } from './auth/admin.guard';
|
||||
@@ -360,7 +362,10 @@ class TourController {
|
||||
legs: {
|
||||
orderBy: { sequence: 'asc' },
|
||||
include: {
|
||||
locations: { orderBy: { plannedStart: 'asc' } }
|
||||
locations: {
|
||||
orderBy: { plannedStart: 'asc' },
|
||||
include: { _count: { select: { comments: true } } }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -384,7 +389,10 @@ class TourController {
|
||||
legs: {
|
||||
orderBy: { sequence: 'asc' },
|
||||
include: {
|
||||
locations: { orderBy: { plannedStart: 'asc' } },
|
||||
locations: {
|
||||
orderBy: { plannedStart: 'asc' },
|
||||
include: { _count: { select: { comments: true } } }
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@@ -871,15 +879,86 @@ class UserController {
|
||||
}
|
||||
}
|
||||
|
||||
@WebSocketGateway({ cors: { origin: '*' } })
|
||||
export class CommentGateway implements OnGatewayConnection {
|
||||
@WebSocketServer() server: Server;
|
||||
|
||||
handleConnection(client: Socket) {
|
||||
console.log(`[WS] Client connected: ${client.id}`);
|
||||
}
|
||||
|
||||
@SubscribeMessage('joinTour')
|
||||
handleJoinTour(client: Socket, tourId: string) {
|
||||
client.join(`tour_${tourId}`);
|
||||
console.log(`[WS] Client ${client.id} joined room: tour_${tourId}`);
|
||||
}
|
||||
|
||||
notifyNewComment(tourId: string, data: any) {
|
||||
// Gửi thông báo tới tất cả client trong phòng của Tour này
|
||||
this.server.to(`tour_${tourId}`).emit('commentAdded', data);
|
||||
}
|
||||
}
|
||||
|
||||
@Controller('locations')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
class CommentController {
|
||||
constructor(
|
||||
private prisma: PrismaService,
|
||||
private commentGateway: CommentGateway
|
||||
) {}
|
||||
|
||||
@Get(':locationId/comments')
|
||||
async getComments(@Param('locationId', ParseUUIDPipe) locationId: string) {
|
||||
return this.prisma.comment.findMany({
|
||||
where: { locationId },
|
||||
include: {
|
||||
user: { select: { name: true } }
|
||||
},
|
||||
orderBy: { createdAt: 'asc' }
|
||||
});
|
||||
}
|
||||
|
||||
@Post(':locationId/comments')
|
||||
async addComment(
|
||||
@Param('locationId', ParseUUIDPipe) locationId: string,
|
||||
@Body() body: { content: string },
|
||||
@Req() req: any
|
||||
) {
|
||||
const comment = await this.prisma.comment.create({
|
||||
data: {
|
||||
content: body.content,
|
||||
locationId,
|
||||
userId: req.user.id
|
||||
},
|
||||
include: { user: { select: { name: true } } }
|
||||
});
|
||||
|
||||
// Tìm tourId để gửi thông báo vào đúng phòng
|
||||
const location = await this.prisma.location.findUnique({
|
||||
where: { id: locationId },
|
||||
include: { leg: { select: { tourId: true } } }
|
||||
});
|
||||
|
||||
if (location?.leg?.tourId) {
|
||||
this.commentGateway.notifyNewComment(location.leg.tourId, {
|
||||
...comment,
|
||||
locationId // Gửi kèm locationId để UI biết điểm nào cần tăng số lượng
|
||||
});
|
||||
}
|
||||
|
||||
return comment;
|
||||
}
|
||||
}
|
||||
|
||||
@Module({
|
||||
imports: [
|
||||
JwtModule.register({
|
||||
secret: process.env.JWT_SECRET || 'super-secret',
|
||||
signOptions: { expiresIn: '1d' },
|
||||
}),
|
||||
}) as any,
|
||||
],
|
||||
controllers: [AppController, AuthController, TourController, UserController, RoutingController, LegController, LocationController],
|
||||
providers: [PrismaService, JwtStrategy, TourRoleGuard, JwtAuthGuard, AdminGuard],
|
||||
controllers: [AppController, AuthController, TourController, UserController, RoutingController, LegController, LocationController, CommentController],
|
||||
providers: [PrismaService, JwtStrategy, TourRoleGuard, JwtAuthGuard, AdminGuard, CommentGateway],
|
||||
exports: [PrismaService]
|
||||
})
|
||||
class AppModule {}
|
||||
|
||||
Reference in New Issue
Block a user