diff --git a/src/admin/admin.controller.ts b/src/admin/admin.controller.ts index dbd8a3a..558f2ef 100644 --- a/src/admin/admin.controller.ts +++ b/src/admin/admin.controller.ts @@ -21,6 +21,11 @@ import { RequestCreateUserDto } from '../user/dto/RequestCreateUser.dto'; import { RequestUpdateUserDto } from 'src/user/dto/RequestUpdateUser.dto'; import { ResponseReadUserDto } from './dto/ResponseReadUser.dto'; import { ResponseGetUserATDto } from './dto/ResponseGetUserAT.dto'; +import { FriendsService } from 'src/friends/friends.service'; +import { RequestUpdateFriendRelationDto } from './dto/RequestUpdateFriendRelation.dto'; +import { RequestDeleteUserDto } from './dto/ReqeustDeleteUser.dto'; +import { ResponseGetAllFriendByAdminDto } from './dto/ResponseGetAllFriendByAdmin.dto'; +import { ResponseReadAllUserDto } from './dto/ResponseReadAllUser.dto'; @ApiTags('admin') @ApiBearerAuth() @@ -31,6 +36,7 @@ export class AdminController { constructor( private adminService: AdminService, private userService: UserService, + private friendsService: FriendsService, ) {} @Get('/all') @@ -48,7 +54,11 @@ export class AdminController { // 조회 @Get('/user/all') - @ApiCreatedResponse({ status: 200, type: ResponseReadUserDto, isArray: true }) + @ApiCreatedResponse({ + status: 200, + type: ResponseReadAllUserDto, + isArray: true, + }) @Roles([Role.Admin]) async getUserAll(): Promise { return await this.userService.findAll(); @@ -75,17 +85,49 @@ export class AdminController { // 수정 @Patch('/user') @Roles([Role.Admin]) - async patchUser( - @Query('user_id') userID: string, - @Body() updateData: RequestUpdateUserDto, - ) { - return await this.userService.update(userID, updateData); + async patchUser(@Body() body: RequestUpdateUserDto) { + return await this.userService.update(body.user_id, body); } // 삭제 @Delete('/user') @Roles([Role.Admin]) - async removeUser(@Query('user_id') userID: string) { - return await this.userService.delete(userID); + async removeUser(@Body() body: RequestDeleteUserDto) { + return await this.userService.delete(body.user_id); + } + + @Get('/friends/all') + @ApiCreatedResponse({ + status: 200, + type: ResponseGetAllFriendByAdminDto, + description: '모든 친구 요청 목록을 조회합니다.', + isArray: true, + }) + @Roles([Role.Admin]) + async getAllFriendList() { + return await this.friendsService.getAllFriendList(); + } + + @Patch('/friends') + @ApiCreatedResponse({ + status: 200, + description: '친구 목록에서 관계를 수정합니다.', + }) + @Roles([Role.Admin]) + async updateFriendRelation(@Body() body: RequestUpdateFriendRelationDto) { + return await this.friendsService.updateRelation( + body.friend_id, + body.relation_type, + ); + } + + @Delete('/friends') + @ApiCreatedResponse({ + status: 200, + description: '특정 친구 관계를 삭제합니다.', + }) + @Roles([Role.Admin]) + async deleteFriendRelation(@Body() body: RequestUpdateFriendRelationDto) { + return await this.friendsService.deleteFriendByFriendId(body.friend_id); } } diff --git a/src/admin/admin.module.ts b/src/admin/admin.module.ts index 6672f98..ece877b 100644 --- a/src/admin/admin.module.ts +++ b/src/admin/admin.module.ts @@ -8,6 +8,7 @@ import { User } from 'src/user/user.entity'; import { AuthModule } from 'src/auth/auth.module'; import { JwtModule } from '@nestjs/jwt'; import { ConfigService } from '@nestjs/config'; +import { FriendsModule } from 'src/friends/friends.module'; @Module({ imports: [ @@ -23,6 +24,7 @@ import { ConfigService } from '@nestjs/config'; TypeOrmModule.forFeature([Admin]), TypeOrmModule.forFeature([User]), UserModule, + FriendsModule, ], providers: [AdminService], controllers: [AdminController], diff --git a/src/admin/dto/ReqeustDeleteFriend.dto.ts b/src/admin/dto/ReqeustDeleteFriend.dto.ts new file mode 100644 index 0000000..e336bf1 --- /dev/null +++ b/src/admin/dto/ReqeustDeleteFriend.dto.ts @@ -0,0 +1,6 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class RequestDeleteFriendDto { + @ApiProperty() + friend_id: string; +} diff --git a/src/admin/dto/ReqeustDeleteUser.dto.ts b/src/admin/dto/ReqeustDeleteUser.dto.ts new file mode 100644 index 0000000..860c10b --- /dev/null +++ b/src/admin/dto/ReqeustDeleteUser.dto.ts @@ -0,0 +1,6 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class RequestDeleteUserDto { + @ApiProperty() + user_id: string; +} diff --git a/src/admin/dto/RequestUpdateFriendRelation.dto.ts b/src/admin/dto/RequestUpdateFriendRelation.dto.ts new file mode 100644 index 0000000..8f772ba --- /dev/null +++ b/src/admin/dto/RequestUpdateFriendRelation.dto.ts @@ -0,0 +1,9 @@ +import { ApiProperty } from '@nestjs/swagger'; + +export class RequestUpdateFriendRelationDto { + @ApiProperty() + friend_id: string; + + @ApiProperty() + relation_type: number; +} diff --git a/src/admin/dto/RequestUpdateUser.dto.ts b/src/admin/dto/RequestUpdateUser.dto.ts new file mode 100644 index 0000000..e69de29 diff --git a/src/admin/dto/ResponseGetAllFriendByAdmin.dto.ts b/src/admin/dto/ResponseGetAllFriendByAdmin.dto.ts new file mode 100644 index 0000000..28278ec --- /dev/null +++ b/src/admin/dto/ResponseGetAllFriendByAdmin.dto.ts @@ -0,0 +1,21 @@ +import { ApiProperty } from '@nestjs/swagger'; + +class UserInfoDto { + @ApiProperty() + name: string; +} + +export class ResponseGetAllFriendByAdminDto { + @ApiProperty({ + type: UserInfoDto, + }) + follower: UserInfoDto; + + @ApiProperty({ + type: UserInfoDto, + }) + following: UserInfoDto; + + @ApiProperty() + relation_type: number; +} diff --git a/src/admin/dto/ResponseReadAllUser.dto.ts b/src/admin/dto/ResponseReadAllUser.dto.ts index 0ac422d..cd0b833 100644 --- a/src/admin/dto/ResponseReadAllUser.dto.ts +++ b/src/admin/dto/ResponseReadAllUser.dto.ts @@ -13,6 +13,12 @@ export class ResponseReadAllUserDto { @ApiProperty() message: string; + @ApiProperty() + follower_count: number; + + @ApiProperty() + following_count: number; + @ApiProperty() created_at: Date; } diff --git a/src/admin/dto/ResponseReadUser.dto.ts b/src/admin/dto/ResponseReadUser.dto.ts index 7c6b4f2..832ea39 100644 --- a/src/admin/dto/ResponseReadUser.dto.ts +++ b/src/admin/dto/ResponseReadUser.dto.ts @@ -13,6 +13,12 @@ export class ResponseReadUserDto { @ApiProperty() message: string; + @ApiProperty() + follower_count: number; + + @ApiProperty() + following_count: number; + @ApiProperty() created_at: Date; } diff --git a/src/friends/dto/RequeestDeclineFriend.dto.ts b/src/friends/dto/RequestDeclineFriend.dto.ts similarity index 100% rename from src/friends/dto/RequeestDeclineFriend.dto.ts rename to src/friends/dto/RequestDeclineFriend.dto.ts diff --git a/src/friends/dto/ResponseGetAllFriend.dto.ts b/src/friends/dto/ResponseGetAllFriend.dto.ts index 576bb77..86bd04f 100644 --- a/src/friends/dto/ResponseGetAllFriend.dto.ts +++ b/src/friends/dto/ResponseGetAllFriend.dto.ts @@ -34,11 +34,13 @@ class FollowingArrayDto { export class ResponseGetAllFriendDto { @ApiProperty({ type: FollowerArrayDto, + isArray: true, }) follower: FollowerArrayDto; @ApiProperty({ type: FollowingArrayDto, + isArray: true, }) following: FollowingArrayDto; } diff --git a/src/friends/friends.controller.ts b/src/friends/friends.controller.ts index bfd1c18..c0a8f76 100644 --- a/src/friends/friends.controller.ts +++ b/src/friends/friends.controller.ts @@ -13,8 +13,7 @@ import { JwtAuthGuard } from 'src/auth/guards/jwt-auth.guard'; import { RolesGuard } from 'src/auth/guards/roles.guard'; import { Roles } from 'src/libs/decorators/roles.decorator'; import { Role } from 'src/libs/enums/role.enum'; -import { RequestUpdateUserDto } from 'src/user/dto/RequestUpdateUser.dto'; -import { RequestDeclineFriendDto } from './dto/RequeestDeclineFriend.dto'; +import { RequestDeclineFriendDto } from './dto/RequestDeclineFriend.dto'; import { RequestAcceptFriendDto } from './dto/RequestAcceptFriend.dto'; import { RequestCreateFriendDto } from './dto/RequestCreateFriend.dto'; import { RequestDeleteFriendDto } from './dto/RequestDeleteFriend.dto'; diff --git a/src/friends/friends.module.ts b/src/friends/friends.module.ts index 086ce41..770b179 100644 --- a/src/friends/friends.module.ts +++ b/src/friends/friends.module.ts @@ -6,11 +6,12 @@ import { Friends } from './friends.entity'; import { User } from 'src/user/user.entity'; @Module({ - imports: [TypeOrmModule.forFeature([Friends]), TypeOrmModule.forFeature([User])], + imports: [ + TypeOrmModule.forFeature([Friends]), + TypeOrmModule.forFeature([User]), + ], controllers: [FriendsController], - providers: [FriendsService] + providers: [FriendsService], + exports: [FriendsService], }) export class FriendsModule {} - - - diff --git a/src/friends/friends.service.ts b/src/friends/friends.service.ts index 17b7d90..f642e16 100644 --- a/src/friends/friends.service.ts +++ b/src/friends/friends.service.ts @@ -18,6 +18,25 @@ export class FriendsService { private userRepository: Repository, ) {} + async getAllFriendList() { + return await this.friendsRepository.find({ + relations: { + follower: true, + following: true, + }, + select: { + follower: { + name: true, + }, + following: { + name: true, + }, + friend_id: true, + relation_type: true, + }, + }); + } + //친구 신청 async createRelation(follower_uuid: string, following_uuid: string) { const follower = await this.userRepository.findOneBy({ @@ -222,7 +241,7 @@ export class FriendsService { friend_id, }); - //실제 존재하는 관계인지 조회 + //요청한 유저가 포함된 관계인지 조회 if (!isFollower && !isFollowing) throw new BadRequestException({ status: HttpStatus.BAD_REQUEST, @@ -233,4 +252,22 @@ export class FriendsService { friend_id, }); } + + async deleteFriendByFriendId(friend_id: string) { + return await this.friendsRepository.delete({ + friend_id, + }); + } + + async updateRelation(friend_id: string, relation_type: number) { + const relation = await this.friendsRepository.findOne({ + where: { + friend_id, + }, + }); + + relation.relation_type = relation_type; + + return await this.friendsRepository.save(relation); + } } diff --git a/src/user/dto/RequestUpdateUser.dto.ts b/src/user/dto/RequestUpdateUser.dto.ts index 1aab074..28db2b6 100644 --- a/src/user/dto/RequestUpdateUser.dto.ts +++ b/src/user/dto/RequestUpdateUser.dto.ts @@ -4,11 +4,11 @@ import { ApiProperty } from '@nestjs/swagger'; export class RequestUpdateUserDto { @ApiProperty() @IsString() - name: string; + user_id: string; @ApiProperty() - @IsEmail() - email: string; + @IsString() + name: string; @ApiProperty() @IsString() diff --git a/src/user/user.service.ts b/src/user/user.service.ts index c8bf2b1..27e146e 100644 --- a/src/user/user.service.ts +++ b/src/user/user.service.ts @@ -13,7 +13,22 @@ export class UserService { ) {} async findAll(): Promise { - return await this.usersRepository.find(); + return await this.usersRepository + .createQueryBuilder('user') + // .andWhere('following.relation_type = 1') + .loadRelationCountAndMap( + 'user.follower_count', + 'user.follower', + 'follower', + (qb) => qb.where('follower.relation_type = 1'), + ) + .loadRelationCountAndMap( + 'user.following_count', + 'user.following', + 'following', + (qb) => qb.where('following.relation_type = 1'), + ) + .getMany(); } async findOne(user_id: string): Promise {