From 303385043f7207ebc3b82407527332383eaf179a Mon Sep 17 00:00:00 2001 From: priverg163 Date: Tue, 10 Sep 2024 21:45:06 +0900 Subject: [PATCH 01/34] chore :: build.gradle change version --- build.gradle | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/build.gradle b/build.gradle index e084022f..a2dea612 100644 --- a/build.gradle +++ b/build.gradle @@ -36,11 +36,18 @@ dependencies { implementation 'io.jsonwebtoken:jjwt-api:0.12.3' runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.12.3' runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.12.3' - implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE' - implementation 'org.apache.poi:poi:3.11' - implementation 'org.apache.poi:poi-ooxml:3.11' // 엑셀 2007 이상 버전에서 사용 - implementation 'commons-io:commons-io:2.4' - + implementation 'io.awspring.cloud:spring-cloud-starter-aws:2.4.4' + + implementation group: 'org.apache.poi', name: 'poi', version: '5.3.0' + implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '5.3.0' + implementation 'commons-io:commons-io:2.7' + + implementation 'com.querydsl:querydsl-core:5.1.0' + implementation 'com.querydsl:querydsl-jpa:5.1.0:jakarta' + implementation 'com.querydsl:querydsl-apt:5.1.0:jakarta' + annotationProcessor 'com.querydsl:querydsl-apt:5.1.0:jakarta' + annotationProcessor 'jakarta.persistence:jakarta.persistence-api' + annotationProcessor 'jakarta.annotation:jakarta.annotation-api' } From 40ffff112af9addfd3e733c173d63b8997f1bdb3 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Tue, 10 Sep 2024 21:55:44 +0900 Subject: [PATCH 02/34] feat :: userInfo queryDSL --- .../domain/rent/service/RentServiceImpl.java | 6 +- .../returns/service/ReturnServiceImpl.java | 6 +- .../user/controller/UserController.java | 10 +-- .../domain/user/domain/entity/user/User.java | 14 +++- .../repository/user/UserQueryRepository.java | 7 ++ .../user/UserQueryRepositoryImpl.java | 71 +++++++++++++++++++ .../repository/user/UserRepository.java | 2 +- .../keepserver/domain/user/dto/UserDto.java | 16 +++++ .../request => dto}/UserProfileDto.java | 2 +- .../request/LoginRequest.java | 2 +- .../request/SignupRequest.java | 2 +- .../request/UserInfoRequest.java | 2 +- .../domain/user/service/user/UserService.java | 12 ++-- .../user/service/user/UserServiceImpl.java | 48 +++---------- .../global/common/S3/S3Uploader.java | 1 - 15 files changed, 135 insertions(+), 66 deletions(-) create mode 100644 src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepository.java create mode 100644 src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepositoryImpl.java create mode 100644 src/main/java/com/keepgoing/keepserver/domain/user/dto/UserDto.java rename src/main/java/com/keepgoing/keepserver/domain/user/{payload/request => dto}/UserProfileDto.java (89%) rename src/main/java/com/keepgoing/keepserver/domain/user/{payload => dto}/request/LoginRequest.java (70%) rename src/main/java/com/keepgoing/keepserver/domain/user/{payload => dto}/request/SignupRequest.java (76%) rename src/main/java/com/keepgoing/keepserver/domain/user/{payload => dto}/request/UserInfoRequest.java (69%) diff --git a/src/main/java/com/keepgoing/keepserver/domain/rent/service/RentServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/rent/service/RentServiceImpl.java index c251bb1e..e6558505 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/rent/service/RentServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/rent/service/RentServiceImpl.java @@ -1,13 +1,13 @@ package com.keepgoing.keepserver.domain.rent.service; -import com.keepgoing.keepserver.domain.book.domain.entity.enums.BookState; import com.keepgoing.keepserver.domain.book.domain.entity.Book; -import com.keepgoing.keepserver.domain.book.mapper.BookMapper; +import com.keepgoing.keepserver.domain.book.domain.entity.enums.BookState; import com.keepgoing.keepserver.domain.book.domain.repository.BookRepository; +import com.keepgoing.keepserver.domain.book.mapper.BookMapper; import com.keepgoing.keepserver.domain.device.domain.entity.Device; import com.keepgoing.keepserver.domain.device.domain.entity.enums.DeviceStatus; -import com.keepgoing.keepserver.domain.device.mapper.DeviceMapper; import com.keepgoing.keepserver.domain.device.domain.repository.DeviceRepository; +import com.keepgoing.keepserver.domain.device.mapper.DeviceMapper; import com.keepgoing.keepserver.domain.device.service.DeviceServiceImpl; import com.keepgoing.keepserver.domain.user.domain.entity.user.User; import com.keepgoing.keepserver.global.common.BaseResponse; diff --git a/src/main/java/com/keepgoing/keepserver/domain/returns/service/ReturnServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/returns/service/ReturnServiceImpl.java index 8c0b72a0..3a8dc1a7 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/returns/service/ReturnServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/returns/service/ReturnServiceImpl.java @@ -1,13 +1,13 @@ package com.keepgoing.keepserver.domain.returns.service; -import com.keepgoing.keepserver.domain.book.domain.entity.enums.BookState; import com.keepgoing.keepserver.domain.book.domain.entity.Book; -import com.keepgoing.keepserver.domain.book.mapper.BookMapper; +import com.keepgoing.keepserver.domain.book.domain.entity.enums.BookState; import com.keepgoing.keepserver.domain.book.domain.repository.BookRepository; +import com.keepgoing.keepserver.domain.book.mapper.BookMapper; import com.keepgoing.keepserver.domain.device.domain.entity.Device; import com.keepgoing.keepserver.domain.device.domain.entity.enums.DeviceStatus; -import com.keepgoing.keepserver.domain.device.mapper.DeviceMapper; import com.keepgoing.keepserver.domain.device.domain.repository.DeviceRepository; +import com.keepgoing.keepserver.domain.device.mapper.DeviceMapper; import com.keepgoing.keepserver.domain.device.service.DeviceServiceImpl; import com.keepgoing.keepserver.domain.user.domain.entity.user.User; import com.keepgoing.keepserver.global.common.BaseResponse; diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/controller/UserController.java b/src/main/java/com/keepgoing/keepserver/domain/user/controller/UserController.java index 80b8162e..cd4a22a1 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/controller/UserController.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/controller/UserController.java @@ -1,9 +1,9 @@ package com.keepgoing.keepserver.domain.user.controller; -import com.keepgoing.keepserver.domain.user.payload.request.LoginRequest; -import com.keepgoing.keepserver.domain.user.payload.request.SignupRequest; -import com.keepgoing.keepserver.domain.user.payload.request.UserInfoRequest; -import com.keepgoing.keepserver.domain.user.payload.request.UserProfileDto; +import com.keepgoing.keepserver.domain.user.dto.UserDto; +import com.keepgoing.keepserver.domain.user.dto.request.LoginRequest; +import com.keepgoing.keepserver.domain.user.dto.request.SignupRequest; +import com.keepgoing.keepserver.domain.user.dto.request.UserInfoRequest; import com.keepgoing.keepserver.domain.user.service.user.UserService; import com.keepgoing.keepserver.global.exception.BusinessException; import io.swagger.v3.oas.annotations.Operation; @@ -36,7 +36,7 @@ public ResponseEntity registerAndAuthenticateUser(@RequestBody SignupRequest @Operation(summary = "프로필", description = "토큰을 이용하여 유저 정보와 대여한 기자재 및 도서 목록을 조회합니다.") @GetMapping("/userinfo") - public UserProfileDto provideUserInfo(Authentication authentication) { + public UserDto provideUserInfo(Authentication authentication) { return userService.provideUserInfo(authentication); } diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/domain/entity/user/User.java b/src/main/java/com/keepgoing/keepserver/domain/user/domain/entity/user/User.java index 062d9a19..abd76e39 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/domain/entity/user/User.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/domain/entity/user/User.java @@ -1,15 +1,21 @@ package com.keepgoing.keepserver.domain.user.domain.entity.user; +import com.keepgoing.keepserver.domain.notice.domain.entity.notice.Notice; +import com.keepgoing.keepserver.domain.notice.domain.entity.notice.NoticeReception; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.ToString; import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import java.util.List; + @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @EntityListeners(AuditingEntityListener.class) +@ToString @Table(name = "users") public class User { @Id @@ -40,9 +46,11 @@ public class User { @Column(nullable = false) private boolean teacher; - public void hidePassword(String password) { - this.password = password; - } + @OneToMany(mappedBy = "teacher", fetch = FetchType.LAZY) + private List notices; + + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + private List noticeReceptions; public static User registerUser( String email, diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepository.java b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepository.java new file mode 100644 index 00000000..10e9214f --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepository.java @@ -0,0 +1,7 @@ +package com.keepgoing.keepserver.domain.user.domain.repository.user; + +import com.keepgoing.keepserver.domain.user.dto.UserDto; + +public interface UserQueryRepository { + UserDto getProfileByEmail(long id); +} diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepositoryImpl.java b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepositoryImpl.java new file mode 100644 index 00000000..8cc27cab --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepositoryImpl.java @@ -0,0 +1,71 @@ +package com.keepgoing.keepserver.domain.user.domain.repository.user; + +import com.keepgoing.keepserver.domain.book.payload.response.QBookResponseDto; +import com.keepgoing.keepserver.domain.device.payload.response.QDeviceResponseDto; +import com.keepgoing.keepserver.domain.user.dto.QUserDto; +import com.keepgoing.keepserver.domain.user.dto.UserDto; +import com.querydsl.core.group.GroupBy; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; + +import java.util.stream.Collectors; + +import static com.keepgoing.keepserver.domain.book.domain.entity.QBook.book; +import static com.keepgoing.keepserver.domain.device.domain.entity.QDevice.device; +import static com.keepgoing.keepserver.domain.notice.domain.entity.notice.QNoticeReception.noticeReception; +import static com.keepgoing.keepserver.domain.user.domain.entity.user.QUser.user; + +@RequiredArgsConstructor +public class UserQueryRepositoryImpl implements UserQueryRepository { + private final JPAQueryFactory factory; + + @Override + public UserDto getProfileByEmail(long id) { + var map = factory + .selectFrom(user) + .leftJoin(noticeReception).on(noticeReception.userId.id.eq(user.id)) + .leftJoin(device).on(device.borrower.id.eq(user.id)) + .leftJoin(book).on(book.borrower.id.eq(user.id)) + .where(user.id.eq(id)) + .distinct() + .transform( + GroupBy.groupBy(user.id).as(new QUserDto( + user.id, + user.email, + user.name, + user.teacher, + GroupBy.set( + new QDeviceResponseDto( + device.id, + device.deviceName, + device.imgUrl, + device.regDate, + device.rentDate, + device.status + ) + ), + GroupBy.set( + new QBookResponseDto( + book.id, + book.bookName, + book.writer, + book.imageUrl, + book.registrationDate, + book.rentDate, + book.state + ) + ) + )) + ); + + var dto = map.get(id); + return UserDto.builder() + .id(dto.id()) + .name(dto.name()) + .email(dto.email()) + .teacher(dto.teacher()) + .borrowedDevices(dto.borrowedDevices().stream().filter(r -> r.id() != 0).collect(Collectors.toSet())) + .borrowedBooks(dto.borrowedBooks().stream().filter(r -> r.id() != 0).collect(Collectors.toSet())) + .build(); + } +} diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserRepository.java b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserRepository.java index 5cc404aa..e0163065 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserRepository.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserRepository.java @@ -7,7 +7,7 @@ import java.util.Optional; @Repository -public interface UserRepository extends JpaRepository { +public interface UserRepository extends JpaRepository, UserQueryRepository { Optional findByEmail(String email); Boolean existsByEmail(String email); Optional findByEmailEquals(String email); diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/dto/UserDto.java b/src/main/java/com/keepgoing/keepserver/domain/user/dto/UserDto.java new file mode 100644 index 00000000..0429ceac --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/domain/user/dto/UserDto.java @@ -0,0 +1,16 @@ +package com.keepgoing.keepserver.domain.user.dto; + +import com.keepgoing.keepserver.domain.book.payload.response.BookResponseDto; +import com.keepgoing.keepserver.domain.device.payload.response.DeviceResponseDto; +import com.querydsl.core.annotations.QueryProjection; +import lombok.Builder; + +import java.util.Set; + +@Builder +public record UserDto(Long id, String email, String name, boolean teacher, Set borrowedDevices, Set borrowedBooks) { + // private List notices; + + @QueryProjection + public UserDto {} +} diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/payload/request/UserProfileDto.java b/src/main/java/com/keepgoing/keepserver/domain/user/dto/UserProfileDto.java similarity index 89% rename from src/main/java/com/keepgoing/keepserver/domain/user/payload/request/UserProfileDto.java rename to src/main/java/com/keepgoing/keepserver/domain/user/dto/UserProfileDto.java index eaaab5d4..6a75bd35 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/payload/request/UserProfileDto.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/dto/UserProfileDto.java @@ -1,4 +1,4 @@ -package com.keepgoing.keepserver.domain.user.payload.request; +package com.keepgoing.keepserver.domain.user.dto; import com.keepgoing.keepserver.domain.book.payload.response.BookResponseDto; import com.keepgoing.keepserver.domain.device.payload.response.DeviceResponseDto; diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/payload/request/LoginRequest.java b/src/main/java/com/keepgoing/keepserver/domain/user/dto/request/LoginRequest.java similarity index 70% rename from src/main/java/com/keepgoing/keepserver/domain/user/payload/request/LoginRequest.java rename to src/main/java/com/keepgoing/keepserver/domain/user/dto/request/LoginRequest.java index 3d74bc41..6ce0f271 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/payload/request/LoginRequest.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/dto/request/LoginRequest.java @@ -1,4 +1,4 @@ -package com.keepgoing.keepserver.domain.user.payload.request; +package com.keepgoing.keepserver.domain.user.dto.request; import lombok.Builder; import lombok.Data; diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/payload/request/SignupRequest.java b/src/main/java/com/keepgoing/keepserver/domain/user/dto/request/SignupRequest.java similarity index 76% rename from src/main/java/com/keepgoing/keepserver/domain/user/payload/request/SignupRequest.java rename to src/main/java/com/keepgoing/keepserver/domain/user/dto/request/SignupRequest.java index 2b92357e..c3d69d16 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/payload/request/SignupRequest.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/dto/request/SignupRequest.java @@ -1,4 +1,4 @@ -package com.keepgoing.keepserver.domain.user.payload.request; +package com.keepgoing.keepserver.domain.user.dto.request; import lombok.Builder; import lombok.Data; diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/payload/request/UserInfoRequest.java b/src/main/java/com/keepgoing/keepserver/domain/user/dto/request/UserInfoRequest.java similarity index 69% rename from src/main/java/com/keepgoing/keepserver/domain/user/payload/request/UserInfoRequest.java rename to src/main/java/com/keepgoing/keepserver/domain/user/dto/request/UserInfoRequest.java index 7029982d..dec4e6fe 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/payload/request/UserInfoRequest.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/dto/request/UserInfoRequest.java @@ -1,4 +1,4 @@ -package com.keepgoing.keepserver.domain.user.payload.request; +package com.keepgoing.keepserver.domain.user.dto.request; import lombok.Builder; import lombok.Data; diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserService.java b/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserService.java index dc5a225a..a6b99191 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserService.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserService.java @@ -1,10 +1,10 @@ package com.keepgoing.keepserver.domain.user.service.user; -import com.keepgoing.keepserver.domain.user.payload.request.SignupRequest; -import com.keepgoing.keepserver.domain.user.payload.request.UserInfoRequest; -import com.keepgoing.keepserver.domain.user.payload.request.UserProfileDto; -import com.keepgoing.keepserver.domain.user.payload.response.ApiResponse; -import com.keepgoing.keepserver.domain.user.payload.response.JwtResponse; +import com.keepgoing.keepserver.domain.user.dto.UserDto; +import com.keepgoing.keepserver.domain.user.dto.request.SignupRequest; +import com.keepgoing.keepserver.domain.user.dto.request.UserInfoRequest; +import com.keepgoing.keepserver.domain.user.dto.response.ApiResponse; +import com.keepgoing.keepserver.domain.user.dto.response.JwtResponse; import com.keepgoing.keepserver.global.exception.BusinessException; import org.springframework.http.ResponseEntity; import org.springframework.security.core.Authentication; @@ -12,6 +12,6 @@ public interface UserService { ApiResponse registerUser(SignupRequest signupRequest) throws BusinessException; ResponseEntity updateUserData(UserInfoRequest request, Authentication authentication); - UserProfileDto provideUserInfo(Authentication authentication); + UserDto provideUserInfo(Authentication authentication); JwtResponse authenticateAndGenerateJWT(String email, String password); } \ No newline at end of file diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserServiceImpl.java index e1a39c0b..194cc9c5 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserServiceImpl.java @@ -1,20 +1,12 @@ package com.keepgoing.keepserver.domain.user.service.user; -import com.keepgoing.keepserver.domain.book.domain.entity.Book; -import com.keepgoing.keepserver.domain.book.payload.response.BookResponseDto; -import com.keepgoing.keepserver.domain.book.mapper.BookMapper; -import com.keepgoing.keepserver.domain.book.service.BookServiceImpl; -import com.keepgoing.keepserver.domain.device.domain.entity.Device; -import com.keepgoing.keepserver.domain.device.mapper.DeviceMapper; -import com.keepgoing.keepserver.domain.device.payload.response.DeviceResponseDto; -import com.keepgoing.keepserver.domain.device.service.DeviceServiceImpl; import com.keepgoing.keepserver.domain.user.domain.entity.user.User; -import com.keepgoing.keepserver.domain.user.payload.request.SignupRequest; -import com.keepgoing.keepserver.domain.user.payload.request.UserInfoRequest; -import com.keepgoing.keepserver.domain.user.payload.request.UserProfileDto; -import com.keepgoing.keepserver.domain.user.payload.response.ApiResponse; -import com.keepgoing.keepserver.domain.user.payload.response.JwtResponse; import com.keepgoing.keepserver.domain.user.domain.repository.user.UserRepository; +import com.keepgoing.keepserver.domain.user.dto.UserDto; +import com.keepgoing.keepserver.domain.user.dto.request.SignupRequest; +import com.keepgoing.keepserver.domain.user.dto.request.UserInfoRequest; +import com.keepgoing.keepserver.domain.user.dto.response.ApiResponse; +import com.keepgoing.keepserver.domain.user.dto.response.JwtResponse; import com.keepgoing.keepserver.domain.user.security.jwt.JwtUtils; import com.keepgoing.keepserver.domain.user.security.service.UserDetailsImpl; import com.keepgoing.keepserver.global.exception.BusinessException; @@ -30,8 +22,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.List; - @Service @RequiredArgsConstructor public class UserServiceImpl implements UserService { @@ -40,10 +30,6 @@ public class UserServiceImpl implements UserService { private final PasswordEncoder encoder; private final AuthenticationManager authenticationManager; private final JwtUtils jwtUtils; - private final DeviceServiceImpl deviceService; - private final DeviceMapper deviceMapper; - private final BookServiceImpl bookService; - private final BookMapper bookMapper; @Override @Transactional @@ -65,13 +51,9 @@ public ResponseEntity updateUserData(UserInfoRequest request, Authentica } @Override - public UserProfileDto provideUserInfo(Authentication authentication) { - String userEmail = getNameByAuthentication(authentication); - User user = findUserByEmail(userEmail); - List borrowedDevicesDto = getBorrowedDevicesForUser(user); - List borrowedBooksDto = getBorrowedBooksForUser(user); - hideUserPassword(user); - return new UserProfileDto(user, borrowedDevicesDto, borrowedBooksDto); + public UserDto provideUserInfo(Authentication authentication) { + UserDetailsImpl ud = (UserDetailsImpl) authentication.getPrincipal(); + return userRepository.getProfileByEmail(ud.getId()); } /* 인증 및 JWT 토큰 생성 */ @@ -86,20 +68,6 @@ public JwtResponse authenticateAndGenerateJWT(String email, String password) { return JwtResponse.setJwtResponse(jwt, userDetails.getId(), userDetails.getEmail(), userDetails.getName(), userDetails.isTeacher()); } - private List getBorrowedDevicesForUser(User user) { - List borrowedDevices = deviceService.findDevicesBorrowedByUser(user); - return deviceMapper.convertDevicesToDtos(borrowedDevices); - } - - private List getBorrowedBooksForUser(User user) { - List borrowedBooks = bookService.findBooksBorrowedByUser(user); - return bookMapper.convertBooksToDtos(borrowedBooks); - } - - private void hideUserPassword(User user) { - user.hidePassword(""); - } - private String getNameByAuthentication(Authentication authentication) { return authentication.getName(); } diff --git a/src/main/java/com/keepgoing/keepserver/global/common/S3/S3Uploader.java b/src/main/java/com/keepgoing/keepserver/global/common/S3/S3Uploader.java index dea130a5..65bd9abc 100644 --- a/src/main/java/com/keepgoing/keepserver/global/common/S3/S3Uploader.java +++ b/src/main/java/com/keepgoing/keepserver/global/common/S3/S3Uploader.java @@ -1,7 +1,6 @@ package com.keepgoing.keepserver.global.common.S3; import com.amazonaws.services.s3.AmazonS3; -import com.amazonaws.services.s3.model.CannedAccessControlList; import com.amazonaws.services.s3.model.PutObjectRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; From 48fadf8fdc790f0fc62c9a18ebe4bedff9618d8b Mon Sep 17 00:00:00 2001 From: priverg163 Date: Tue, 10 Sep 2024 21:58:17 +0900 Subject: [PATCH 03/34] Feat :: notice #81 --- .../keepserver/KeepServerApplication.java | 7 +++ .../notice/domain/entity/notice/Notice.java | 45 +++++++++++++++++++ .../domain/entity/notice/NoticeReception.java | 33 ++++++++++++++ .../domain/repository/NoticeRepository.java | 9 ++++ .../notice/payload/req/noticeCreateDto.java | 12 +++++ .../notice/presentation/NoticeController.java | 42 +++++++++++++++++ .../domain/notice/service/NoticeService.java | 12 +++++ .../notice/service/NoticeServiceImpl.java | 34 ++++++++++++++ 8 files changed, 194 insertions(+) create mode 100644 src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/Notice.java create mode 100644 src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/NoticeReception.java create mode 100644 src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeRepository.java create mode 100644 src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/noticeCreateDto.java create mode 100644 src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java create mode 100644 src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java create mode 100644 src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java diff --git a/src/main/java/com/keepgoing/keepserver/KeepServerApplication.java b/src/main/java/com/keepgoing/keepserver/KeepServerApplication.java index 8c3ca1cd..2d4506c9 100644 --- a/src/main/java/com/keepgoing/keepserver/KeepServerApplication.java +++ b/src/main/java/com/keepgoing/keepserver/KeepServerApplication.java @@ -1,10 +1,17 @@ package com.keepgoing.keepserver; +import jakarta.annotation.PostConstruct; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import java.util.TimeZone; + @SpringBootApplication public class KeepServerApplication { + @PostConstruct + public void init() { + TimeZone.setDefault(TimeZone.getTimeZone("Asia/Seoul")); + } public static void main(String[] args) { SpringApplication.run(KeepServerApplication.class, args); diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/Notice.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/Notice.java new file mode 100644 index 00000000..965c81a6 --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/Notice.java @@ -0,0 +1,45 @@ +package com.keepgoing.keepserver.domain.notice.domain.entity.notice; + +import com.keepgoing.keepserver.domain.user.domain.entity.user.User; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.experimental.SuperBuilder; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.time.LocalDateTime; +import java.util.List; + +@Entity +@Getter +@Setter +@SuperBuilder +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@EntityListeners(AuditingEntityListener.class) +@Table(name = "notice") +public class Notice { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long idx; + @Lob + @Column(nullable = false) + private String message; + @ManyToOne + @JoinColumn(name = "teacher_id", nullable = false) + private User teacher; + @Column(nullable = false) + private char isGlobalYN; + @CreatedDate + @Column(nullable = false, updatable = false) + private LocalDateTime createTime; + + @LastModifiedDate + @Column + private LocalDateTime editTime; + @OneToMany(mappedBy = "notice", cascade = CascadeType.ALL) + private List noticeReceptions; +} diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/NoticeReception.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/NoticeReception.java new file mode 100644 index 00000000..26519252 --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/NoticeReception.java @@ -0,0 +1,33 @@ +package com.keepgoing.keepserver.domain.notice.domain.entity.notice; + +import com.keepgoing.keepserver.domain.user.domain.entity.user.User; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.time.LocalDateTime; + +@Entity +@Getter +@Setter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@EntityListeners(AuditingEntityListener.class) +@Table(name = "notice_reception") +public class NoticeReception { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private long idx; + @JoinColumn(name = "user_id", nullable = false) + @ManyToOne + private User user; + @JoinColumn(name = "notice_id", nullable = false) + @ManyToOne + private Notice notice; + @Column(nullable = false) + private boolean isRead; + private LocalDateTime read_at; + +} diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeRepository.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeRepository.java new file mode 100644 index 00000000..7bab4d0e --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeRepository.java @@ -0,0 +1,9 @@ +package com.keepgoing.keepserver.domain.notice.domain.repository; + +import com.keepgoing.keepserver.domain.notice.domain.entity.notice.Notice; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface NoticeRepository extends JpaRepository { +} diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/noticeCreateDto.java b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/noticeCreateDto.java new file mode 100644 index 00000000..cebc234c --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/noticeCreateDto.java @@ -0,0 +1,12 @@ +package com.keepgoing.keepserver.domain.notice.payload.req; + +import lombok.Builder; +import lombok.Data; + +@Builder +@Data +public class noticeCreateDto { + private final String content; + private final char isGlobalYN; + +} diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java b/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java new file mode 100644 index 00000000..f51603be --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java @@ -0,0 +1,42 @@ +package com.keepgoing.keepserver.domain.notice.presentation; + +import com.keepgoing.keepserver.domain.notice.payload.req.noticeCreateDto; +import com.keepgoing.keepserver.domain.notice.service.NoticeService; +import com.keepgoing.keepserver.global.common.BaseResponse; +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.Authentication; +import org.springframework.web.bind.annotation.*; + +@Tag(name = "공지", description = "공지 관련 api 입니다.") +@CrossOrigin(origins = "*", maxAge = 3600) +@RequestMapping("/notice") +@RequiredArgsConstructor +@RestController +public class NoticeController { + private final NoticeService noticeService; + @Operation(summary = "공지 등록", description = "공지 등록을 진행합니다.") + @PostMapping("/post") + public BaseResponse addNotice(@RequestBody noticeCreateDto noticeCreateDto, Authentication authentication) { + return noticeService.createNotice(noticeCreateDto,authentication); + } + @Operation(summary = "공지 수정", description = "등록된 공지를 수정합니다.") + @PatchMapping("/edit/{id}") + public BaseResponse editNotice(@PathVariable Long id, @RequestBody noticeCreateDto noticeCreateDto, Authentication authentication) { + return noticeService.updateNotice(id, noticeCreateDto,authentication); + } + + @Operation(summary = "공지 삭제", description = "등록된 공지를 삭제합니다.") + @DeleteMapping("/{id}") + public BaseResponse deleteNotice(@PathVariable Long id, Authentication authentication){ + return noticeService.deleteNotice(id,authentication); + } + + @Operation(summary = "공지 불러오기", description = "본인이 쓴 공지를 불러옵니다.") + @GetMapping("/my") + public BaseResponse myNotice(Authentication authentication){ + return noticeService.getNotice(authentication); + } + +} diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java new file mode 100644 index 00000000..ee6e2819 --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java @@ -0,0 +1,12 @@ +package com.keepgoing.keepserver.domain.notice.service; + +import com.keepgoing.keepserver.domain.notice.payload.req.noticeCreateDto; +import com.keepgoing.keepserver.global.common.BaseResponse; +import org.springframework.security.core.Authentication; + +public interface NoticeService { + BaseResponse createNotice(noticeCreateDto noticeCreateDto, Authentication authentication); + BaseResponse updateNotice(Long id, noticeCreateDto noticeCreateDto, Authentication authentication); + BaseResponse deleteNotice(Long id, Authentication authentication); + BaseResponse getNotice(Authentication authentication); +} diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java new file mode 100644 index 00000000..76e0a69d --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java @@ -0,0 +1,34 @@ +package com.keepgoing.keepserver.domain.notice.service; + +import com.keepgoing.keepserver.domain.notice.domain.repository.NoticeRepository; +import com.keepgoing.keepserver.domain.notice.payload.req.noticeCreateDto; +import com.keepgoing.keepserver.global.common.BaseResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.Authentication; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class NoticeServiceImpl implements NoticeService { + private final NoticeRepository noticeRepository; + + @Override + public BaseResponse createNotice(noticeCreateDto noticeCreateDto, Authentication authentication) { + return null; + } + + @Override + public BaseResponse updateNotice(Long id, noticeCreateDto noticeCreateDto, Authentication authentication) { + return null; + } + + @Override + public BaseResponse deleteNotice(Long id, Authentication authentication) { + return null; + } + + @Override + public BaseResponse getNotice(Authentication authentication) { + return null; + } +} From 1ca27206c546bc4ebe9f62c81ccc6c87cc5cc102 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Tue, 10 Sep 2024 21:59:49 +0900 Subject: [PATCH 04/34] Add :: @QueryProjection --- .../book/payload/response/BookResponseDto.java | 6 +++++- .../payload/response/DeviceResponseDto.java | 8 ++++++-- .../keepserver/global/config/JpaConfig.java | 17 +++++++++++++++++ 3 files changed, 28 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/keepgoing/keepserver/global/config/JpaConfig.java diff --git a/src/main/java/com/keepgoing/keepserver/domain/book/payload/response/BookResponseDto.java b/src/main/java/com/keepgoing/keepserver/domain/book/payload/response/BookResponseDto.java index 69b998e7..3d4678e9 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/book/payload/response/BookResponseDto.java +++ b/src/main/java/com/keepgoing/keepserver/domain/book/payload/response/BookResponseDto.java @@ -1,13 +1,14 @@ package com.keepgoing.keepserver.domain.book.payload.response; import com.keepgoing.keepserver.domain.book.domain.entity.enums.BookState; +import com.querydsl.core.annotations.QueryProjection; import lombok.Builder; import java.time.LocalDateTime; @Builder public record BookResponseDto( - Long id, + long id, String bookName, String writer, String imageUrl, @@ -15,4 +16,7 @@ public record BookResponseDto( LocalDateTime rentDate, BookState state ) { + @QueryProjection + public BookResponseDto { + } } \ No newline at end of file diff --git a/src/main/java/com/keepgoing/keepserver/domain/device/payload/response/DeviceResponseDto.java b/src/main/java/com/keepgoing/keepserver/domain/device/payload/response/DeviceResponseDto.java index bff153a3..becfce49 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/device/payload/response/DeviceResponseDto.java +++ b/src/main/java/com/keepgoing/keepserver/domain/device/payload/response/DeviceResponseDto.java @@ -1,17 +1,21 @@ package com.keepgoing.keepserver.domain.device.payload.response; import com.keepgoing.keepserver.domain.device.domain.entity.enums.DeviceStatus; +import com.querydsl.core.annotations.QueryProjection; import lombok.Builder; import java.time.LocalDateTime; @Builder -public record DeviceResponseDto ( - Long id, +public record DeviceResponseDto( + long id, String deviceName, String imgUrl, LocalDateTime regDate, LocalDateTime rentDate, DeviceStatus status ) { + @QueryProjection + public DeviceResponseDto { + } } diff --git a/src/main/java/com/keepgoing/keepserver/global/config/JpaConfig.java b/src/main/java/com/keepgoing/keepserver/global/config/JpaConfig.java new file mode 100644 index 00000000..e68768b4 --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/global/config/JpaConfig.java @@ -0,0 +1,17 @@ +package com.keepgoing.keepserver.global.config; + +import com.querydsl.jpa.JPQLTemplates; +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; + +@Configuration +@EnableJpaAuditing +public class JpaConfig { + @Bean + public JPAQueryFactory queryFactory(EntityManager em) { + return new JPAQueryFactory(JPQLTemplates.DEFAULT, em); + } +} From 09d563ab0e4257a983588336c27b365d686d82f6 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Tue, 10 Sep 2024 22:01:52 +0900 Subject: [PATCH 05/34] Edit :: BookService --- .../domain/book/service/BookServiceImpl.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/book/service/BookServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/book/service/BookServiceImpl.java index 32353130..22a36b8d 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/book/service/BookServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/book/service/BookServiceImpl.java @@ -1,10 +1,10 @@ package com.keepgoing.keepserver.domain.book.service; import com.keepgoing.keepserver.domain.book.domain.entity.Book; +import com.keepgoing.keepserver.domain.book.domain.repository.BookRepository; +import com.keepgoing.keepserver.domain.book.mapper.BookMapper; import com.keepgoing.keepserver.domain.book.payload.request.BookDto; import com.keepgoing.keepserver.domain.book.payload.request.BookRequestDto; -import com.keepgoing.keepserver.domain.book.mapper.BookMapper; -import com.keepgoing.keepserver.domain.book.domain.repository.BookRepository; import com.keepgoing.keepserver.domain.user.domain.entity.user.User; import com.keepgoing.keepserver.domain.user.domain.repository.user.UserRepository; import com.keepgoing.keepserver.global.common.BaseResponse; @@ -34,7 +34,7 @@ public BaseResponse bookRegister(BookDto bookDto) { @Override public BaseResponse selectAllBook() { - return new BaseResponse(HttpStatus.OK, "책 불러오기 성공", bookRepository.findAll()); + return new BaseResponse(HttpStatus.OK, "책 불러오기 성공", bookRepository.findAll().stream().map(bookMapper::entityToDto).toList()); } @Override @@ -55,7 +55,7 @@ public BaseResponse deleteBook(String nfcCode, Authentication auth) { public BaseResponse selectMyBook(Authentication auth) { User user = getUserByAuthentication(auth); List books = bookRepository.findByBorrower(user); - return new BaseResponse(HttpStatus.OK, "책 가져오기 성공", books); + return new BaseResponse(HttpStatus.OK, "책 가져오기 성공", books.stream().map(bookMapper::entityToDto).toList()); } @Override @@ -64,7 +64,7 @@ public BaseResponse alertMyBook(Authentication auth, String dateString) { DateRange dateRange = DateRange.fromDateString(dateString, "yyyyMMdd"); List books = bookRepository.findByBorrowerAndRentDateBetween(user, dateRange.getSt(), dateRange.getEnd()); - return new BaseResponse(HttpStatus.OK, "책 가져오기 성공", books); + return new BaseResponse(HttpStatus.OK, "책 가져오기 성공", books.stream().map(bookMapper::entityToDto).toList()); } @Override @@ -86,10 +86,6 @@ public BaseResponse editBook(String nfcCode, BookRequestDto bookRequest) { bookRepository.save(book); return new BaseResponse(HttpStatus.OK, "책 정보 수정 성공"); } - - public List findBooksBorrowedByUser(User user) { - return bookRepository.findByBorrower(user); - } public User getUserByAuthentication(Authentication auth) { if (auth == null) { throw BookException.userNotFound(); From 3f98a1b64de9db8b16c820adb9cf7b1c99906a33 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Tue, 10 Sep 2024 22:02:18 +0900 Subject: [PATCH 06/34] refactor :: refactoring --- .../keepserver/domain/device/domain/entity/Device.java | 2 +- .../keepgoing/keepserver/domain/device/mapper/DeviceMapper.java | 2 +- .../keepserver/domain/device/service/DeviceServiceImpl.java | 2 +- .../domain/user/{payload => dto}/response/ApiResponse.java | 2 +- .../domain/user/{payload => dto}/response/JwtResponse.java | 2 +- .../keepserver/global/response/ExceptionResponseEntity.java | 2 ++ 6 files changed, 7 insertions(+), 5 deletions(-) rename src/main/java/com/keepgoing/keepserver/domain/user/{payload => dto}/response/ApiResponse.java (89%) rename src/main/java/com/keepgoing/keepserver/domain/user/{payload => dto}/response/JwtResponse.java (91%) diff --git a/src/main/java/com/keepgoing/keepserver/domain/device/domain/entity/Device.java b/src/main/java/com/keepgoing/keepserver/domain/device/domain/entity/Device.java index 2c446340..3c7b3746 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/device/domain/entity/Device.java +++ b/src/main/java/com/keepgoing/keepserver/domain/device/domain/entity/Device.java @@ -29,7 +29,7 @@ public class Device { /* 기기 사진 */ - @Column(nullable = false) + @Column private String imgUrl; /* diff --git a/src/main/java/com/keepgoing/keepserver/domain/device/mapper/DeviceMapper.java b/src/main/java/com/keepgoing/keepserver/domain/device/mapper/DeviceMapper.java index 2d3ba9fa..e7f7a244 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/device/mapper/DeviceMapper.java +++ b/src/main/java/com/keepgoing/keepserver/domain/device/mapper/DeviceMapper.java @@ -2,8 +2,8 @@ import com.keepgoing.keepserver.domain.device.domain.entity.Device; import com.keepgoing.keepserver.domain.device.domain.entity.enums.DeviceStatus; -import com.keepgoing.keepserver.domain.device.payload.response.DeviceResponseDto; import com.keepgoing.keepserver.domain.device.payload.request.DeviceDto; +import com.keepgoing.keepserver.domain.device.payload.response.DeviceResponseDto; import org.springframework.stereotype.Component; import java.time.LocalDateTime; diff --git a/src/main/java/com/keepgoing/keepserver/domain/device/service/DeviceServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/device/service/DeviceServiceImpl.java index 0bdaf81b..1fd95640 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/device/service/DeviceServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/device/service/DeviceServiceImpl.java @@ -1,11 +1,11 @@ package com.keepgoing.keepserver.domain.device.service; import com.keepgoing.keepserver.domain.device.domain.entity.Device; +import com.keepgoing.keepserver.domain.device.domain.repository.DeviceRepository; import com.keepgoing.keepserver.domain.device.mapper.DeviceMapper; import com.keepgoing.keepserver.domain.device.payload.request.DeviceDto; import com.keepgoing.keepserver.domain.device.payload.request.DeviceEditRequest; import com.keepgoing.keepserver.domain.device.payload.response.DeviceResponseDto; -import com.keepgoing.keepserver.domain.device.domain.repository.DeviceRepository; import com.keepgoing.keepserver.domain.user.domain.entity.user.User; import com.keepgoing.keepserver.domain.user.domain.repository.user.UserRepository; import com.keepgoing.keepserver.global.common.BaseResponse; diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/payload/response/ApiResponse.java b/src/main/java/com/keepgoing/keepserver/domain/user/dto/response/ApiResponse.java similarity index 89% rename from src/main/java/com/keepgoing/keepserver/domain/user/payload/response/ApiResponse.java rename to src/main/java/com/keepgoing/keepserver/domain/user/dto/response/ApiResponse.java index 03af700c..f7cc228e 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/payload/response/ApiResponse.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/dto/response/ApiResponse.java @@ -1,4 +1,4 @@ -package com.keepgoing.keepserver.domain.user.payload.response; +package com.keepgoing.keepserver.domain.user.dto.response; import lombok.AccessLevel; import lombok.Getter; diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/payload/response/JwtResponse.java b/src/main/java/com/keepgoing/keepserver/domain/user/dto/response/JwtResponse.java similarity index 91% rename from src/main/java/com/keepgoing/keepserver/domain/user/payload/response/JwtResponse.java rename to src/main/java/com/keepgoing/keepserver/domain/user/dto/response/JwtResponse.java index 83c4b940..c97f15e2 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/payload/response/JwtResponse.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/dto/response/JwtResponse.java @@ -1,4 +1,4 @@ -package com.keepgoing.keepserver.domain.user.payload.response; +package com.keepgoing.keepserver.domain.user.dto.response; import lombok.AccessLevel; import lombok.Getter; diff --git a/src/main/java/com/keepgoing/keepserver/global/response/ExceptionResponseEntity.java b/src/main/java/com/keepgoing/keepserver/global/response/ExceptionResponseEntity.java index 0e9f38b5..f7444ba4 100644 --- a/src/main/java/com/keepgoing/keepserver/global/response/ExceptionResponseEntity.java +++ b/src/main/java/com/keepgoing/keepserver/global/response/ExceptionResponseEntity.java @@ -1,11 +1,13 @@ package com.keepgoing.keepserver.global.response; import lombok.Data; +import lombok.EqualsAndHashCode; import lombok.experimental.SuperBuilder; import org.springframework.http.HttpStatus; @Data @SuperBuilder +@EqualsAndHashCode(callSuper = true) public class ExceptionResponseEntity extends ResponseEntity { private HttpStatus error; private String message; From d97292fb5b4574a94c3885fe83d53de1dac339c5 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Wed, 11 Sep 2024 23:47:37 +0900 Subject: [PATCH 07/34] feat :: notice object in user dto --- .../user/UserQueryRepositoryImpl.java | 23 +++++++++++++++++-- .../keepserver/domain/user/dto/UserDto.java | 12 ++++++++-- 2 files changed, 31 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepositoryImpl.java b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepositoryImpl.java index 8cc27cab..f005abd9 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepositoryImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepositoryImpl.java @@ -2,6 +2,8 @@ import com.keepgoing.keepserver.domain.book.payload.response.QBookResponseDto; import com.keepgoing.keepserver.domain.device.payload.response.QDeviceResponseDto; +import com.keepgoing.keepserver.domain.notice.payload.res.QNoticeResponseDto; +import com.keepgoing.keepserver.domain.user.domain.entity.user.QUser; import com.keepgoing.keepserver.domain.user.dto.QUserDto; import com.keepgoing.keepserver.domain.user.dto.UserDto; import com.querydsl.core.group.GroupBy; @@ -14,16 +16,22 @@ import static com.keepgoing.keepserver.domain.device.domain.entity.QDevice.device; import static com.keepgoing.keepserver.domain.notice.domain.entity.notice.QNoticeReception.noticeReception; import static com.keepgoing.keepserver.domain.user.domain.entity.user.QUser.user; +import static com.keepgoing.keepserver.domain.notice.domain.entity.notice.QNotice.notice; @RequiredArgsConstructor public class UserQueryRepositoryImpl implements UserQueryRepository { + // teacher 별칭을 따로 설정 private final JPAQueryFactory factory; @Override public UserDto getProfileByEmail(long id) { + var teacher = new QUser("teacher"); var map = factory - .selectFrom(user) - .leftJoin(noticeReception).on(noticeReception.userId.id.eq(user.id)) + .select(user) + .from(user) + .leftJoin(noticeReception).on(noticeReception.user.id.eq(user.id)) + .leftJoin(noticeReception.notice, notice) + .leftJoin(notice.teacher, teacher) .leftJoin(device).on(device.borrower.id.eq(user.id)) .leftJoin(book).on(book.borrower.id.eq(user.id)) .where(user.id.eq(id)) @@ -54,10 +62,20 @@ public UserDto getProfileByEmail(long id) { book.rentDate, book.state ) + ), + GroupBy.set( + new QNoticeResponseDto( + notice.idx, + notice.message, + teacher.name, + notice.createTime, + notice.editTime + ) ) )) ); + System.out.println(map); var dto = map.get(id); return UserDto.builder() .id(dto.id()) @@ -66,6 +84,7 @@ public UserDto getProfileByEmail(long id) { .teacher(dto.teacher()) .borrowedDevices(dto.borrowedDevices().stream().filter(r -> r.id() != 0).collect(Collectors.toSet())) .borrowedBooks(dto.borrowedBooks().stream().filter(r -> r.id() != 0).collect(Collectors.toSet())) + .notices(dto.notices().stream().filter(r -> r.id() != 0).collect(Collectors.toSet())) .build(); } } diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/dto/UserDto.java b/src/main/java/com/keepgoing/keepserver/domain/user/dto/UserDto.java index 0429ceac..4b141c32 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/dto/UserDto.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/dto/UserDto.java @@ -2,14 +2,22 @@ import com.keepgoing.keepserver.domain.book.payload.response.BookResponseDto; import com.keepgoing.keepserver.domain.device.payload.response.DeviceResponseDto; +import com.keepgoing.keepserver.domain.notice.payload.res.NoticeResponseDto; import com.querydsl.core.annotations.QueryProjection; import lombok.Builder; import java.util.Set; @Builder -public record UserDto(Long id, String email, String name, boolean teacher, Set borrowedDevices, Set borrowedBooks) { - // private List notices; +public record UserDto( + Long id, + String email, + String name, + boolean teacher, + Set borrowedDevices, + Set borrowedBooks, + Set notices +) { @QueryProjection public UserDto {} From 125f4aec138d9780e496ce81d315ef40eb4645c6 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Wed, 11 Sep 2024 23:51:01 +0900 Subject: [PATCH 08/34] fix :: NoticeCreateDto typo --- .../domain/notice/domain/entity/notice/Notice.java | 2 -- .../domain/notice/payload/req/NoticeCreateDto.java | 14 ++++++++++++++ .../domain/notice/payload/req/noticeCreateDto.java | 12 ------------ .../notice/presentation/NoticeController.java | 8 ++++---- .../domain/notice/service/NoticeService.java | 6 +++--- .../domain/notice/service/NoticeServiceImpl.java | 6 +++--- 6 files changed, 24 insertions(+), 24 deletions(-) create mode 100644 src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java delete mode 100644 src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/noticeCreateDto.java diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/Notice.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/Notice.java index 965c81a6..037bc9f5 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/Notice.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/Notice.java @@ -40,6 +40,4 @@ public class Notice { @LastModifiedDate @Column private LocalDateTime editTime; - @OneToMany(mappedBy = "notice", cascade = CascadeType.ALL) - private List noticeReceptions; } diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java new file mode 100644 index 00000000..247868b6 --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java @@ -0,0 +1,14 @@ +package com.keepgoing.keepserver.domain.notice.payload.req; + +import lombok.Builder; +import lombok.Data; + +import java.util.List; + +@Builder +@Data +public class NoticeCreateDto { + private final String message; + private final boolean isGlobal; + private final List userIds; +} diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/noticeCreateDto.java b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/noticeCreateDto.java deleted file mode 100644 index cebc234c..00000000 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/noticeCreateDto.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.keepgoing.keepserver.domain.notice.payload.req; - -import lombok.Builder; -import lombok.Data; - -@Builder -@Data -public class noticeCreateDto { - private final String content; - private final char isGlobalYN; - -} diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java b/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java index f51603be..22e80f03 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java @@ -1,6 +1,6 @@ package com.keepgoing.keepserver.domain.notice.presentation; -import com.keepgoing.keepserver.domain.notice.payload.req.noticeCreateDto; +import com.keepgoing.keepserver.domain.notice.payload.req.NoticeCreateDto; import com.keepgoing.keepserver.domain.notice.service.NoticeService; import com.keepgoing.keepserver.global.common.BaseResponse; import io.swagger.v3.oas.annotations.Operation; @@ -16,14 +16,14 @@ @RestController public class NoticeController { private final NoticeService noticeService; - @Operation(summary = "공지 등록", description = "공지 등록을 진행합니다.") + @Operation(summary = "공지 등록", description = "공지 등록을 진행합니다. 전체 학생을 등록하고 싶으실 경우엔 global을 true로 해주시고, list는 빈값으로 보내시면 됩니다.") @PostMapping("/post") - public BaseResponse addNotice(@RequestBody noticeCreateDto noticeCreateDto, Authentication authentication) { + public BaseResponse addNotice(@RequestBody NoticeCreateDto noticeCreateDto, Authentication authentication) { return noticeService.createNotice(noticeCreateDto,authentication); } @Operation(summary = "공지 수정", description = "등록된 공지를 수정합니다.") @PatchMapping("/edit/{id}") - public BaseResponse editNotice(@PathVariable Long id, @RequestBody noticeCreateDto noticeCreateDto, Authentication authentication) { + public BaseResponse editNotice(@PathVariable Long id, @RequestBody NoticeCreateDto noticeCreateDto, Authentication authentication) { return noticeService.updateNotice(id, noticeCreateDto,authentication); } diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java index ee6e2819..44d51ce6 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java @@ -1,12 +1,12 @@ package com.keepgoing.keepserver.domain.notice.service; -import com.keepgoing.keepserver.domain.notice.payload.req.noticeCreateDto; +import com.keepgoing.keepserver.domain.notice.payload.req.NoticeCreateDto; import com.keepgoing.keepserver.global.common.BaseResponse; import org.springframework.security.core.Authentication; public interface NoticeService { - BaseResponse createNotice(noticeCreateDto noticeCreateDto, Authentication authentication); - BaseResponse updateNotice(Long id, noticeCreateDto noticeCreateDto, Authentication authentication); + BaseResponse createNotice(NoticeCreateDto noticeCreateDto, Authentication authentication); + BaseResponse updateNotice(Long id, NoticeCreateDto noticeCreateDto, Authentication authentication); BaseResponse deleteNotice(Long id, Authentication authentication); BaseResponse getNotice(Authentication authentication); } diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java index 76e0a69d..6c978c63 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java @@ -1,7 +1,7 @@ package com.keepgoing.keepserver.domain.notice.service; import com.keepgoing.keepserver.domain.notice.domain.repository.NoticeRepository; -import com.keepgoing.keepserver.domain.notice.payload.req.noticeCreateDto; +import com.keepgoing.keepserver.domain.notice.payload.req.NoticeCreateDto; import com.keepgoing.keepserver.global.common.BaseResponse; import lombok.RequiredArgsConstructor; import org.springframework.security.core.Authentication; @@ -13,12 +13,12 @@ public class NoticeServiceImpl implements NoticeService { private final NoticeRepository noticeRepository; @Override - public BaseResponse createNotice(noticeCreateDto noticeCreateDto, Authentication authentication) { + public BaseResponse createNotice(NoticeCreateDto noticeCreateDto, Authentication authentication) { return null; } @Override - public BaseResponse updateNotice(Long id, noticeCreateDto noticeCreateDto, Authentication authentication) { + public BaseResponse updateNotice(Long id, NoticeCreateDto noticeCreateDto, Authentication authentication) { return null; } From f183af029376bd4573819d141fedca01591d3f3f Mon Sep 17 00:00:00 2001 From: priverg163 Date: Thu, 12 Sep 2024 13:25:55 +0900 Subject: [PATCH 09/34] Feat :: post & getAll notice --- .../notice/domain/entity/notice/Notice.java | 3 +- .../domain/entity/notice/NoticeReception.java | 2 + .../notice/domain/mapper/NoticeMapper.java | 18 ++++++ .../repository/NoticeReceptionRepository.java | 7 +++ .../notice/payload/res/NoticeResponseDto.java | 19 ++++++ .../notice/service/NoticeServiceImpl.java | 63 ++++++++++++++++++- .../repository/user/UserRepository.java | 3 + .../global/exception/notice/NoticeError.java | 15 +++++ .../exception/notice/NoticeException.java | 16 +++++ 9 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 src/main/java/com/keepgoing/keepserver/domain/notice/domain/mapper/NoticeMapper.java create mode 100644 src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeReceptionRepository.java create mode 100644 src/main/java/com/keepgoing/keepserver/domain/notice/payload/res/NoticeResponseDto.java create mode 100644 src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeError.java create mode 100644 src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeException.java diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/Notice.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/Notice.java index 037bc9f5..63860074 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/Notice.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/Notice.java @@ -12,7 +12,6 @@ import org.springframework.data.jpa.domain.support.AuditingEntityListener; import java.time.LocalDateTime; -import java.util.List; @Entity @Getter @@ -32,7 +31,7 @@ public class Notice { @JoinColumn(name = "teacher_id", nullable = false) private User teacher; @Column(nullable = false) - private char isGlobalYN; + private boolean isGlobal; @CreatedDate @Column(nullable = false, updatable = false) private LocalDateTime createTime; diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/NoticeReception.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/NoticeReception.java index 26519252..9348a4ea 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/NoticeReception.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/NoticeReception.java @@ -6,6 +6,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; +import lombok.experimental.SuperBuilder; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import java.time.LocalDateTime; @@ -13,6 +14,7 @@ @Entity @Getter @Setter +@SuperBuilder @NoArgsConstructor(access = AccessLevel.PROTECTED) @EntityListeners(AuditingEntityListener.class) @Table(name = "notice_reception") diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/mapper/NoticeMapper.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/mapper/NoticeMapper.java new file mode 100644 index 00000000..343aac23 --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/mapper/NoticeMapper.java @@ -0,0 +1,18 @@ +package com.keepgoing.keepserver.domain.notice.domain.mapper; + +import com.keepgoing.keepserver.domain.notice.domain.entity.notice.Notice; +import com.keepgoing.keepserver.domain.notice.payload.res.NoticeResponseDto; +import org.springframework.stereotype.Component; + +@Component +public class NoticeMapper { + public NoticeResponseDto entityToDto(Notice notice){ + return NoticeResponseDto.builder() + .id(notice.getIdx()) + .message(notice.getMessage()) + .createTime(notice.getCreateTime()) + .editTime(notice.getEditTime()) + .teacherName(notice.getTeacher().getName()) + .build(); + } +} diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeReceptionRepository.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeReceptionRepository.java new file mode 100644 index 00000000..d32af6e9 --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeReceptionRepository.java @@ -0,0 +1,7 @@ +package com.keepgoing.keepserver.domain.notice.domain.repository; + +import com.keepgoing.keepserver.domain.notice.domain.entity.notice.NoticeReception; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface NoticeReceptionRepository extends JpaRepository { +} \ No newline at end of file diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/res/NoticeResponseDto.java b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/res/NoticeResponseDto.java new file mode 100644 index 00000000..359dc39e --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/res/NoticeResponseDto.java @@ -0,0 +1,19 @@ +package com.keepgoing.keepserver.domain.notice.payload.res; + +import com.querydsl.core.annotations.QueryProjection; +import lombok.Builder; + +import java.time.LocalDateTime; + +@Builder +public record NoticeResponseDto ( + long id, + String message, + String teacherName, + LocalDateTime createTime, + LocalDateTime editTime +) +{ + @QueryProjection + public NoticeResponseDto {} +} diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java index 6c978c63..b98fbf4c 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java @@ -1,20 +1,65 @@ package com.keepgoing.keepserver.domain.notice.service; +import com.keepgoing.keepserver.domain.notice.domain.entity.notice.Notice; +import com.keepgoing.keepserver.domain.notice.domain.entity.notice.NoticeReception; +import com.keepgoing.keepserver.domain.notice.domain.mapper.NoticeMapper; +import com.keepgoing.keepserver.domain.notice.domain.repository.NoticeReceptionRepository; import com.keepgoing.keepserver.domain.notice.domain.repository.NoticeRepository; import com.keepgoing.keepserver.domain.notice.payload.req.NoticeCreateDto; +import com.keepgoing.keepserver.domain.notice.payload.res.NoticeResponseDto; +import com.keepgoing.keepserver.domain.user.domain.entity.user.User; +import com.keepgoing.keepserver.domain.user.domain.repository.user.UserRepository; +import com.keepgoing.keepserver.domain.user.security.service.UserDetailsImpl; import com.keepgoing.keepserver.global.common.BaseResponse; +import com.keepgoing.keepserver.global.exception.notice.NoticeError; +import com.keepgoing.keepserver.global.exception.notice.NoticeException; import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Service; +import java.util.ArrayList; +import java.util.List; + @Service @RequiredArgsConstructor public class NoticeServiceImpl implements NoticeService { private final NoticeRepository noticeRepository; + private final UserRepository userRepository; + private final NoticeReceptionRepository noticeReceptionRepository; + private final NoticeMapper mapper; @Override public BaseResponse createNotice(NoticeCreateDto noticeCreateDto, Authentication authentication) { - return null; + var ud = (UserDetailsImpl) authentication.getPrincipal(); + // noinspection OptionalGetWithoutIsPresent + var teacher = userRepository.findById(ud.getId()).get(); // already checked + validateTeacher(teacher); + Notice notice = noticeRepository.save( + Notice.builder() + .isGlobal(noticeCreateDto.isGlobal()) + .teacher(teacher) + .message(noticeCreateDto.getMessage()) + .build() + ); + + List receptions = new ArrayList<>(); + List users = noticeCreateDto.isGlobal() ? + userRepository.findUsersByTeacherIs(false) : + userRepository.findUsersByIdIn(noticeCreateDto.getUserIds()); + for (User user : users) { + receptions.add( + NoticeReception + .builder() + .user(user) + .notice(notice) + .build() + ); + } + + noticeReceptionRepository.saveAll(receptions); + + return new BaseResponse(HttpStatus.ACCEPTED, "공지 등록 성공", mapper.entityToDto(notice)); } @Override @@ -24,11 +69,25 @@ public BaseResponse updateNotice(Long id, NoticeCreateDto noticeCreateDto, Authe @Override public BaseResponse deleteNotice(Long id, Authentication authentication) { + return null; } @Override public BaseResponse getNotice(Authentication authentication) { - return null; + List notices = noticeRepository.findAll(); + List dtoList = new ArrayList<>(); + + for (Notice n : notices) { + dtoList.add(mapper.entityToDto(n)); + } + return new BaseResponse(HttpStatus.ACCEPTED, "전체 공지: ", dtoList); } + + private void validateTeacher(User user) { + if (!user.isTeacher()) { + throw new NoticeException(NoticeError.USER_NOT_TEACHER); + } + } + } diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserRepository.java b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserRepository.java index e0163065..2b276224 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserRepository.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserRepository.java @@ -4,6 +4,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; import java.util.Optional; @Repository @@ -11,4 +12,6 @@ public interface UserRepository extends JpaRepository, UserQueryRepo Optional findByEmail(String email); Boolean existsByEmail(String email); Optional findByEmailEquals(String email); + List findUsersByIdIn(List ids); + List findUsersByTeacherIs(boolean isTeacher); } \ No newline at end of file diff --git a/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeError.java b/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeError.java new file mode 100644 index 00000000..4c60c1e3 --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeError.java @@ -0,0 +1,15 @@ +package com.keepgoing.keepserver.global.exception.notice; + +import com.keepgoing.keepserver.global.exception.error.ErrorProperty; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; + +@Getter +@RequiredArgsConstructor +public enum NoticeError implements ErrorProperty { + USER_NOT_TEACHER(HttpStatus.BAD_REQUEST, "선생님이 아닙니다."); + + private final HttpStatus status; + private final String message; +} diff --git a/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeException.java b/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeException.java new file mode 100644 index 00000000..f76c60da --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeException.java @@ -0,0 +1,16 @@ +package com.keepgoing.keepserver.global.exception.notice; + + +import com.keepgoing.keepserver.global.exception.BusinessException; + +public class NoticeException extends BusinessException { + private static final NoticeException USER_NOT_TEACHER = new NoticeException(NoticeError.USER_NOT_TEACHER); + + public NoticeException(NoticeError error) { + super(error); + } + + public static NoticeException userNotTeacher(){ + return USER_NOT_TEACHER; + } +} From 563d9361d707122355227b2cc2f5052d21049deb Mon Sep 17 00:00:00 2001 From: priverg163 Date: Thu, 12 Sep 2024 19:21:03 +0900 Subject: [PATCH 10/34] Feat :: Find My & All notices, Delete notices --- .../domain/entity/notice/NoticeReception.java | 4 + .../repository/NoticeReceptionRepository.java | 4 + .../domain/repository/NoticeRepository.java | 4 + .../notice/payload/req/NoticeCreateDto.java | 11 +- .../notice/presentation/NoticeController.java | 13 ++- .../domain/notice/service/NoticeService.java | 1 + .../notice/service/NoticeServiceImpl.java | 102 ++++++++++++------ .../domain/user/domain/entity/user/User.java | 2 +- .../user/UserQueryRepositoryImpl.java | 1 - .../global/exception/notice/NoticeError.java | 4 +- .../exception/notice/NoticeException.java | 6 ++ 11 files changed, 104 insertions(+), 48 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/NoticeReception.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/NoticeReception.java index 9348a4ea..b262f2a6 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/NoticeReception.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/NoticeReception.java @@ -7,6 +7,8 @@ import lombok.NoArgsConstructor; import lombok.Setter; import lombok.experimental.SuperBuilder; +import org.hibernate.annotations.OnDelete; +import org.hibernate.annotations.OnDeleteAction; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import java.time.LocalDateTime; @@ -23,9 +25,11 @@ public class NoticeReception { @GeneratedValue(strategy = GenerationType.IDENTITY) private long idx; @JoinColumn(name = "user_id", nullable = false) + @OnDelete(action = OnDeleteAction.CASCADE) @ManyToOne private User user; @JoinColumn(name = "notice_id", nullable = false) + @OnDelete(action = OnDeleteAction.CASCADE) @ManyToOne private Notice notice; @Column(nullable = false) diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeReceptionRepository.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeReceptionRepository.java index d32af6e9..826f6dbb 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeReceptionRepository.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeReceptionRepository.java @@ -1,7 +1,11 @@ package com.keepgoing.keepserver.domain.notice.domain.repository; +import com.keepgoing.keepserver.domain.notice.domain.entity.notice.Notice; import com.keepgoing.keepserver.domain.notice.domain.entity.notice.NoticeReception; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +@Repository public interface NoticeReceptionRepository extends JpaRepository { + void deleteByNotice(Notice notice); } \ No newline at end of file diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeRepository.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeRepository.java index 7bab4d0e..ef14b464 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeRepository.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeRepository.java @@ -4,6 +4,10 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface NoticeRepository extends JpaRepository { + Notice findNoticeByIdx(long idx); + List findNoticesByTeacher_Name(String name); } diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java index 247868b6..58cfe083 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java @@ -1,14 +1,13 @@ package com.keepgoing.keepserver.domain.notice.payload.req; import lombok.Builder; -import lombok.Data; import java.util.List; @Builder -@Data -public class NoticeCreateDto { - private final String message; - private final boolean isGlobal; - private final List userIds; +public record NoticeCreateDto ( + String message, + boolean isGlobal, + List userIds +) { } diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java b/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java index 22e80f03..75862d3c 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java @@ -16,7 +16,7 @@ @RestController public class NoticeController { private final NoticeService noticeService; - @Operation(summary = "공지 등록", description = "공지 등록을 진행합니다. 전체 학생을 등록하고 싶으실 경우엔 global을 true로 해주시고, list는 빈값으로 보내시면 됩니다.") + @Operation(summary = "공지 등록", description = "공지 등록을 진행합니다. 전체 학생을 등록하고 싶으실 경우엔 isGlobal을 true로 해주시고, list는 빈값으로 보내시면 됩니다.") @PostMapping("/post") public BaseResponse addNotice(@RequestBody NoticeCreateDto noticeCreateDto, Authentication authentication) { return noticeService.createNotice(noticeCreateDto,authentication); @@ -33,10 +33,15 @@ public BaseResponse deleteNotice(@PathVariable Long id, Authentication authentic return noticeService.deleteNotice(id,authentication); } - @Operation(summary = "공지 불러오기", description = "본인이 쓴 공지를 불러옵니다.") - @GetMapping("/my") - public BaseResponse myNotice(Authentication authentication){ + @Operation(summary = "전체 공지 불러오기", description = "존재하는 모든 공지를 불러옵니다.") + @GetMapping("/all") + public BaseResponse allNotice(Authentication authentication){ return noticeService.getNotice(authentication); } + @Operation(summary = "내 공지 불러오기", description = "본인의 공지를 불러옵니다.") + @GetMapping("/my") + public BaseResponse myNotice(Authentication authentication){ + return noticeService.getMyNotice(authentication); + } } diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java index 44d51ce6..2439bf5f 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java @@ -9,4 +9,5 @@ public interface NoticeService { BaseResponse updateNotice(Long id, NoticeCreateDto noticeCreateDto, Authentication authentication); BaseResponse deleteNotice(Long id, Authentication authentication); BaseResponse getNotice(Authentication authentication); + BaseResponse getMyNotice(Authentication authentication); } diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java index b98fbf4c..ea78a65a 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java @@ -17,9 +17,11 @@ import org.springframework.http.HttpStatus; import org.springframework.security.core.Authentication; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; +import java.util.Objects; @Service @RequiredArgsConstructor @@ -31,57 +33,59 @@ public class NoticeServiceImpl implements NoticeService { @Override public BaseResponse createNotice(NoticeCreateDto noticeCreateDto, Authentication authentication) { - var ud = (UserDetailsImpl) authentication.getPrincipal(); - // noinspection OptionalGetWithoutIsPresent - var teacher = userRepository.findById(ud.getId()).get(); // already checked - validateTeacher(teacher); - Notice notice = noticeRepository.save( - Notice.builder() - .isGlobal(noticeCreateDto.isGlobal()) - .teacher(teacher) - .message(noticeCreateDto.getMessage()) - .build() - ); - - List receptions = new ArrayList<>(); - List users = noticeCreateDto.isGlobal() ? - userRepository.findUsersByTeacherIs(false) : - userRepository.findUsersByIdIn(noticeCreateDto.getUserIds()); - for (User user : users) { - receptions.add( - NoticeReception - .builder() - .user(user) - .notice(notice) - .build() - ); - } - - noticeReceptionRepository.saveAll(receptions); + Notice notice = noticeRepository.save(Notice.builder().isGlobal(noticeCreateDto.isGlobal()).teacher(getTeacher(authentication)).message(noticeCreateDto.message()).build()); + getReception(noticeCreateDto, notice); return new BaseResponse(HttpStatus.ACCEPTED, "공지 등록 성공", mapper.entityToDto(notice)); } @Override + @Transactional public BaseResponse updateNotice(Long id, NoticeCreateDto noticeCreateDto, Authentication authentication) { - return null; + Notice notice = getNotice(id, getTeacher(authentication)); + + notice.setGlobal(noticeCreateDto.isGlobal()); + if (noticeCreateDto.message() != null) { + notice.setMessage(noticeCreateDto.message()); + } + noticeRepository.save(notice); + noticeReceptionRepository.deleteByNotice(notice); + getReception(noticeCreateDto, notice); + + return new BaseResponse(HttpStatus.ACCEPTED, "공지 수정 성공", mapper.entityToDto(notice)); + } + + private void getReception(NoticeCreateDto noticeCreateDto, Notice notice) { + List receptions = new ArrayList<>(); + List users = noticeCreateDto.isGlobal() ? userRepository.findUsersByTeacherIs(false) : userRepository.findUsersByIdIn(noticeCreateDto.userIds()); + + for (User user : users) { + receptions.add(NoticeReception.builder().user(user).notice(notice).build()); + } + + noticeReceptionRepository.saveAll(receptions); } @Override + @Transactional public BaseResponse deleteNotice(Long id, Authentication authentication) { - - return null; + noticeRepository.delete(getNotice(id, getTeacher(authentication))); + return new BaseResponse(HttpStatus.OK, "공지가 삭제었습니다."); } @Override + @Transactional public BaseResponse getNotice(Authentication authentication) { List notices = noticeRepository.findAll(); - List dtoList = new ArrayList<>(); + return new BaseResponse(HttpStatus.ACCEPTED, "전체 공지: ", getNoticeList(notices)); + } - for (Notice n : notices) { - dtoList.add(mapper.entityToDto(n)); - } - return new BaseResponse(HttpStatus.ACCEPTED, "전체 공지: ", dtoList); + @Override + @Transactional + public BaseResponse getMyNotice(Authentication authentication) { + List notices = noticeRepository.findNoticesByTeacher_Name(getTeacher(authentication).getName()); + getNoticeList(notices); + return new BaseResponse(HttpStatus.OK, "내가 쓴 글 불러오기", getNoticeList(notices)); } private void validateTeacher(User user) { @@ -90,4 +94,32 @@ private void validateTeacher(User user) { } } + private void validateMyNotice(User user, Notice notice) { + if (!Objects.equals(user.getName(), notice.getTeacher().getName())) { + throw new NoticeException(NoticeError.USER_CANNOT_DELETE); + } + } + + private User getTeacher(Authentication authentication) { + var ud = (UserDetailsImpl) authentication.getPrincipal(); + //noinspection OptionalGetWithoutIsPresent + var teacher = userRepository.findById(ud.getId()).get(); + validateTeacher(teacher); + return teacher; + } + + private Notice getNotice(long id, User teacher) { + Notice notice = noticeRepository.findNoticeByIdx(id); + validateMyNotice(teacher, notice); + return notice; + } + + private List getNoticeList(List notices){ + List dtoList = new ArrayList<>(); + + for(Notice n : notices){ + dtoList.add(mapper.entityToDto(n)); + } + return dtoList; + } } diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/domain/entity/user/User.java b/src/main/java/com/keepgoing/keepserver/domain/user/domain/entity/user/User.java index abd76e39..36c3b971 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/domain/entity/user/User.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/domain/entity/user/User.java @@ -49,7 +49,7 @@ public class User { @OneToMany(mappedBy = "teacher", fetch = FetchType.LAZY) private List notices; - @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @OneToMany(mappedBy = "user", fetch = FetchType.LAZY) private List noticeReceptions; public static User registerUser( diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepositoryImpl.java b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepositoryImpl.java index f005abd9..92455d96 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepositoryImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepositoryImpl.java @@ -20,7 +20,6 @@ @RequiredArgsConstructor public class UserQueryRepositoryImpl implements UserQueryRepository { - // teacher 별칭을 따로 설정 private final JPAQueryFactory factory; @Override diff --git a/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeError.java b/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeError.java index 4c60c1e3..bd6551c9 100644 --- a/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeError.java +++ b/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeError.java @@ -8,7 +8,9 @@ @Getter @RequiredArgsConstructor public enum NoticeError implements ErrorProperty { - USER_NOT_TEACHER(HttpStatus.BAD_REQUEST, "선생님이 아닙니다."); + USER_NOT_TEACHER(HttpStatus.BAD_REQUEST, "선생님이 아닙니다."), + USER_CANNOT_DELETE(HttpStatus.BAD_REQUEST, "본인 글이 아닙니다."); + private final HttpStatus status; private final String message; diff --git a/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeException.java b/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeException.java index f76c60da..5fb8fb73 100644 --- a/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeException.java +++ b/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeException.java @@ -5,6 +5,8 @@ public class NoticeException extends BusinessException { private static final NoticeException USER_NOT_TEACHER = new NoticeException(NoticeError.USER_NOT_TEACHER); + private static final NoticeException USER_CANNOT_DELETE = new NoticeException(NoticeError.USER_CANNOT_DELETE); + public NoticeException(NoticeError error) { super(error); @@ -13,4 +15,8 @@ public NoticeException(NoticeError error) { public static NoticeException userNotTeacher(){ return USER_NOT_TEACHER; } + + public static NoticeException userCannotDelete(){ + return USER_CANNOT_DELETE; + } } From 7bb1a85b59344448ee40d5c5bc94195d16805127 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Thu, 12 Sep 2024 20:23:26 +0900 Subject: [PATCH 11/34] refactor :: HttpStatus --- .../domain/notice/service/NoticeServiceImpl.java | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java index ea78a65a..20024c11 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java @@ -33,10 +33,15 @@ public class NoticeServiceImpl implements NoticeService { @Override public BaseResponse createNotice(NoticeCreateDto noticeCreateDto, Authentication authentication) { - Notice notice = noticeRepository.save(Notice.builder().isGlobal(noticeCreateDto.isGlobal()).teacher(getTeacher(authentication)).message(noticeCreateDto.message()).build()); + Notice notice = noticeRepository.save( + Notice.builder() + .isGlobal(noticeCreateDto.isGlobal()) + .teacher(getTeacher(authentication)) + .message(noticeCreateDto.message()).build() + ); getReception(noticeCreateDto, notice); - return new BaseResponse(HttpStatus.ACCEPTED, "공지 등록 성공", mapper.entityToDto(notice)); + return new BaseResponse(HttpStatus.OK, "공지 등록 성공", mapper.entityToDto(notice)); } @Override From a0261332a6bec8832b535ef2708beb0ad6f7122f Mon Sep 17 00:00:00 2001 From: priverg163 Date: Fri, 13 Sep 2024 11:41:27 +0900 Subject: [PATCH 12/34] chore :: change naming / reformat --- .../repository/NoticeReceptionRepository.java | 2 +- .../domain/repository/NoticeRepository.java | 3 +- .../notice/service/NoticeServiceImpl.java | 29 +++++++++++-------- 3 files changed, 20 insertions(+), 14 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeReceptionRepository.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeReceptionRepository.java index 826f6dbb..17d05eca 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeReceptionRepository.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeReceptionRepository.java @@ -7,5 +7,5 @@ @Repository public interface NoticeReceptionRepository extends JpaRepository { - void deleteByNotice(Notice notice); + void deleteAllByNotice(Notice notice); } \ No newline at end of file diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeRepository.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeRepository.java index ef14b464..36a10b4d 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeRepository.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeRepository.java @@ -1,6 +1,7 @@ package com.keepgoing.keepserver.domain.notice.domain.repository; import com.keepgoing.keepserver.domain.notice.domain.entity.notice.Notice; +import com.keepgoing.keepserver.domain.user.domain.entity.user.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @@ -9,5 +10,5 @@ @Repository public interface NoticeRepository extends JpaRepository { Notice findNoticeByIdx(long idx); - List findNoticesByTeacher_Name(String name); + List findNoticesByTeacher(User teacher); } diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java index 20024c11..f65ea165 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java @@ -35,11 +35,11 @@ public class NoticeServiceImpl implements NoticeService { public BaseResponse createNotice(NoticeCreateDto noticeCreateDto, Authentication authentication) { Notice notice = noticeRepository.save( Notice.builder() - .isGlobal(noticeCreateDto.isGlobal()) - .teacher(getTeacher(authentication)) - .message(noticeCreateDto.message()).build() + .isGlobal(noticeCreateDto.isGlobal()) + .teacher(getTeacher(authentication)) + .message(noticeCreateDto.message()).build() ); - getReception(noticeCreateDto, notice); + setReceptions(noticeCreateDto, notice); return new BaseResponse(HttpStatus.OK, "공지 등록 성공", mapper.entityToDto(notice)); } @@ -47,22 +47,26 @@ public BaseResponse createNotice(NoticeCreateDto noticeCreateDto, Authentication @Override @Transactional public BaseResponse updateNotice(Long id, NoticeCreateDto noticeCreateDto, Authentication authentication) { - Notice notice = getNotice(id, getTeacher(authentication)); + User teacher = getTeacher(authentication); + Notice notice = getNotice(id, teacher); notice.setGlobal(noticeCreateDto.isGlobal()); if (noticeCreateDto.message() != null) { notice.setMessage(noticeCreateDto.message()); } + noticeRepository.save(notice); - noticeReceptionRepository.deleteByNotice(notice); - getReception(noticeCreateDto, notice); + noticeReceptionRepository.deleteAllByNotice(notice); + setReceptions(noticeCreateDto, notice); return new BaseResponse(HttpStatus.ACCEPTED, "공지 수정 성공", mapper.entityToDto(notice)); } - private void getReception(NoticeCreateDto noticeCreateDto, Notice notice) { + private void setReceptions(NoticeCreateDto noticeCreateDto, Notice notice) { List receptions = new ArrayList<>(); - List users = noticeCreateDto.isGlobal() ? userRepository.findUsersByTeacherIs(false) : userRepository.findUsersByIdIn(noticeCreateDto.userIds()); + List users = noticeCreateDto.isGlobal() + ? userRepository.findUsersByTeacherIs(false) + : userRepository.findUsersByIdIn(noticeCreateDto.userIds()); for (User user : users) { receptions.add(NoticeReception.builder().user(user).notice(notice).build()); @@ -88,7 +92,8 @@ public BaseResponse getNotice(Authentication authentication) { @Override @Transactional public BaseResponse getMyNotice(Authentication authentication) { - List notices = noticeRepository.findNoticesByTeacher_Name(getTeacher(authentication).getName()); + User teacher = getTeacher(authentication); + List notices = noticeRepository.findNoticesByTeacher(teacher); getNoticeList(notices); return new BaseResponse(HttpStatus.OK, "내가 쓴 글 불러오기", getNoticeList(notices)); } @@ -119,10 +124,10 @@ private Notice getNotice(long id, User teacher) { return notice; } - private List getNoticeList(List notices){ + private List getNoticeList(List notices) { List dtoList = new ArrayList<>(); - for(Notice n : notices){ + for (Notice n : notices) { dtoList.add(mapper.entityToDto(n)); } return dtoList; From a49892a71f35c39967c85d926d0253d517cccbd2 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Sat, 14 Sep 2024 17:10:27 +0900 Subject: [PATCH 13/34] chore :: deviceException change naming / reformat --- .../keepserver/global/exception/device/DeviceException.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/global/exception/device/DeviceException.java b/src/main/java/com/keepgoing/keepserver/global/exception/device/DeviceException.java index b2bbdd1a..d4c863fa 100644 --- a/src/main/java/com/keepgoing/keepserver/global/exception/device/DeviceException.java +++ b/src/main/java/com/keepgoing/keepserver/global/exception/device/DeviceException.java @@ -4,7 +4,6 @@ public class DeviceException extends BusinessException { private static final DeviceException USER_NOT_FOUND = new DeviceException(DeviceError.USER_NOT_FOUND); - private static final DeviceException DEVICE_NOT_FOUND_EXCEPTION = new DeviceException(DeviceError.DEVICE_NOT_FOUND_EXCEPTION); private static final DeviceException DEVICE_NOT_AVAILABLE = new DeviceException(DeviceError.DEVICE_NOT_AVAILABLE); private static final DeviceException INVALID_BORROWER = new DeviceException(DeviceError.INVALID_BORROWER); @@ -20,10 +19,12 @@ public static DeviceException userNotFound() { public static DeviceException notFoundDevice() { return DEVICE_NOT_FOUND_EXCEPTION; } + public static DeviceException deviceNotAvailable() { return DEVICE_NOT_AVAILABLE; } - public static DeviceException invalidborrower() { + + public static DeviceException invalidBorrower() { return INVALID_BORROWER; } } From e8df4a8a4c2a7bbe56baa91c4a47a409af73f178 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Sat, 14 Sep 2024 17:22:07 +0900 Subject: [PATCH 14/34] refactor :: change validateTeacher to query --- .../domain/device/service/DeviceServiceImpl.java | 8 +------- .../domain/notice/service/NoticeServiceImpl.java | 11 +---------- 2 files changed, 2 insertions(+), 17 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/device/service/DeviceServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/device/service/DeviceServiceImpl.java index 1fd95640..e19749a3 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/device/service/DeviceServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/device/service/DeviceServiceImpl.java @@ -48,7 +48,7 @@ public BaseResponse deviceRead(Long id) { @Override public BaseResponse deleteDevice(Long id, Authentication authentication) { User user = findUserByEmail(authentication.getName()); - validateTeacher(user); + userRepository.findByIdAndTeacherIsTrue(user.getId()); deleteDeviceById(id); return new BaseResponse(HttpStatus.OK, "기기 삭제 성공"); } @@ -85,12 +85,6 @@ public List findDevicesBorrowedByUser(User user) { return deviceRepository.findByBorrower(user); } - private void validateTeacher(User user) { - if (!user.isTeacher()) { - throw new DeviceException(DeviceError.USER_NOT_FOUND); - } - } - private void deleteDeviceById(Long id) { if (!deviceRepository.existsById(id)) { throw new DeviceException(DeviceError.DEVICE_NOT_FOUND_EXCEPTION); diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java index f65ea165..bee253a8 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java @@ -98,12 +98,6 @@ public BaseResponse getMyNotice(Authentication authentication) { return new BaseResponse(HttpStatus.OK, "내가 쓴 글 불러오기", getNoticeList(notices)); } - private void validateTeacher(User user) { - if (!user.isTeacher()) { - throw new NoticeException(NoticeError.USER_NOT_TEACHER); - } - } - private void validateMyNotice(User user, Notice notice) { if (!Objects.equals(user.getName(), notice.getTeacher().getName())) { throw new NoticeException(NoticeError.USER_CANNOT_DELETE); @@ -112,10 +106,7 @@ private void validateMyNotice(User user, Notice notice) { private User getTeacher(Authentication authentication) { var ud = (UserDetailsImpl) authentication.getPrincipal(); - //noinspection OptionalGetWithoutIsPresent - var teacher = userRepository.findById(ud.getId()).get(); - validateTeacher(teacher); - return teacher; + return userRepository.findByIdAndTeacherIsTrue(ud.getId()); } private Notice getNotice(long id, User teacher) { From 4c201f67a9dbbdbd36d306beadc3cd5ded394b35 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Sat, 14 Sep 2024 17:24:27 +0900 Subject: [PATCH 15/34] refactor :: improved readability / delete unused column --- .../domain/notice/domain/entity/notice/Notice.java | 4 ++++ .../notice/domain/entity/notice/NoticeReception.java | 8 ++------ 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/Notice.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/Notice.java index 63860074..fa25c504 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/Notice.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/Notice.java @@ -24,14 +24,18 @@ public class Notice { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long idx; + @Lob @Column(nullable = false) private String message; + @ManyToOne @JoinColumn(name = "teacher_id", nullable = false) private User teacher; + @Column(nullable = false) private boolean isGlobal; + @CreatedDate @Column(nullable = false, updatable = false) private LocalDateTime createTime; diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/NoticeReception.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/NoticeReception.java index b262f2a6..019bf685 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/NoticeReception.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/entity/notice/NoticeReception.java @@ -11,8 +11,6 @@ import org.hibernate.annotations.OnDeleteAction; import org.springframework.data.jpa.domain.support.AuditingEntityListener; -import java.time.LocalDateTime; - @Entity @Getter @Setter @@ -24,16 +22,14 @@ public class NoticeReception { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long idx; + @JoinColumn(name = "user_id", nullable = false) @OnDelete(action = OnDeleteAction.CASCADE) @ManyToOne private User user; + @JoinColumn(name = "notice_id", nullable = false) @OnDelete(action = OnDeleteAction.CASCADE) @ManyToOne private Notice notice; - @Column(nullable = false) - private boolean isRead; - private LocalDateTime read_at; - } From b356ba2f3173e75600da8928087925d1f5195ac9 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Sat, 14 Sep 2024 17:26:39 +0900 Subject: [PATCH 16/34] refactor :: change validateTeacher to query --- .../domain/user/domain/repository/user/UserRepository.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserRepository.java b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserRepository.java index 2b276224..f8551d50 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserRepository.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserRepository.java @@ -14,4 +14,5 @@ public interface UserRepository extends JpaRepository, UserQueryRepo Optional findByEmailEquals(String email); List findUsersByIdIn(List ids); List findUsersByTeacherIs(boolean isTeacher); + User findByIdAndTeacherIsTrue(Long id); } \ No newline at end of file From de22321d558e24a64570bbfd8893996622a4430d Mon Sep 17 00:00:00 2001 From: priverg163 Date: Sat, 14 Sep 2024 17:27:34 +0900 Subject: [PATCH 17/34] refactor :: change validateNotice to query --- .../domain/repository/NoticeRepository.java | 2 +- .../notice/service/NoticeServiceImpl.java | 22 +++++-------------- 2 files changed, 6 insertions(+), 18 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeRepository.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeRepository.java index 36a10b4d..1ddcab3f 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeRepository.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/repository/NoticeRepository.java @@ -9,6 +9,6 @@ @Repository public interface NoticeRepository extends JpaRepository { - Notice findNoticeByIdx(long idx); + Notice findNoticeByIdxAndTeacher_Id(long idx, long tIdx); List findNoticesByTeacher(User teacher); } diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java index bee253a8..20c8856b 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java @@ -11,8 +11,6 @@ import com.keepgoing.keepserver.domain.user.domain.repository.user.UserRepository; import com.keepgoing.keepserver.domain.user.security.service.UserDetailsImpl; import com.keepgoing.keepserver.global.common.BaseResponse; -import com.keepgoing.keepserver.global.exception.notice.NoticeError; -import com.keepgoing.keepserver.global.exception.notice.NoticeException; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; import org.springframework.security.core.Authentication; @@ -21,7 +19,6 @@ import java.util.ArrayList; import java.util.List; -import java.util.Objects; @Service @RequiredArgsConstructor @@ -32,6 +29,7 @@ public class NoticeServiceImpl implements NoticeService { private final NoticeMapper mapper; @Override + @Transactional public BaseResponse createNotice(NoticeCreateDto noticeCreateDto, Authentication authentication) { Notice notice = noticeRepository.save( Notice.builder() @@ -48,7 +46,7 @@ public BaseResponse createNotice(NoticeCreateDto noticeCreateDto, Authentication @Transactional public BaseResponse updateNotice(Long id, NoticeCreateDto noticeCreateDto, Authentication authentication) { User teacher = getTeacher(authentication); - Notice notice = getNotice(id, teacher); + Notice notice = noticeRepository.findNoticeByIdxAndTeacher_Id(id, teacher.getId()); notice.setGlobal(noticeCreateDto.isGlobal()); if (noticeCreateDto.message() != null) { @@ -78,7 +76,9 @@ private void setReceptions(NoticeCreateDto noticeCreateDto, Notice notice) { @Override @Transactional public BaseResponse deleteNotice(Long id, Authentication authentication) { - noticeRepository.delete(getNotice(id, getTeacher(authentication))); + User teacher = getTeacher(authentication); + Notice notice = noticeRepository.findNoticeByIdxAndTeacher_Id(id, teacher.getId()); + noticeRepository.delete(notice); return new BaseResponse(HttpStatus.OK, "공지가 삭제었습니다."); } @@ -98,23 +98,11 @@ public BaseResponse getMyNotice(Authentication authentication) { return new BaseResponse(HttpStatus.OK, "내가 쓴 글 불러오기", getNoticeList(notices)); } - private void validateMyNotice(User user, Notice notice) { - if (!Objects.equals(user.getName(), notice.getTeacher().getName())) { - throw new NoticeException(NoticeError.USER_CANNOT_DELETE); - } - } - private User getTeacher(Authentication authentication) { var ud = (UserDetailsImpl) authentication.getPrincipal(); return userRepository.findByIdAndTeacherIsTrue(ud.getId()); } - private Notice getNotice(long id, User teacher) { - Notice notice = noticeRepository.findNoticeByIdx(id); - validateMyNotice(teacher, notice); - return notice; - } - private List getNoticeList(List notices) { List dtoList = new ArrayList<>(); From 9898b1630a128e1cbc8f6f65ef812b47dd556438 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Sat, 14 Sep 2024 19:59:35 +0900 Subject: [PATCH 18/34] Edit :: Add @QueryProjection / QueryDSL about Notice --- .../notice/payload/res/NoticeResponseDto.java | 5 +- .../user/controller/UserController.java | 10 ++-- .../repository/user/UserQueryRepository.java | 4 +- .../user/UserQueryRepositoryImpl.java | 53 +++++++++++++------ .../keepserver/domain/user/dto/UserDto.java | 5 +- .../domain/user/dto/UserNoticesDto.java | 15 ++++++ .../user/service/user/UserServiceImpl.java | 9 +++- 7 files changed, 72 insertions(+), 29 deletions(-) create mode 100644 src/main/java/com/keepgoing/keepserver/domain/user/dto/UserNoticesDto.java diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/res/NoticeResponseDto.java b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/res/NoticeResponseDto.java index 359dc39e..4b8a2957 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/res/NoticeResponseDto.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/res/NoticeResponseDto.java @@ -12,8 +12,7 @@ public record NoticeResponseDto ( String teacherName, LocalDateTime createTime, LocalDateTime editTime -) -{ +) { @QueryProjection - public NoticeResponseDto {} + public NoticeResponseDto{} } diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/controller/UserController.java b/src/main/java/com/keepgoing/keepserver/domain/user/controller/UserController.java index cd4a22a1..e8f487ea 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/controller/UserController.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/controller/UserController.java @@ -1,6 +1,5 @@ package com.keepgoing.keepserver.domain.user.controller; -import com.keepgoing.keepserver.domain.user.dto.UserDto; import com.keepgoing.keepserver.domain.user.dto.request.LoginRequest; import com.keepgoing.keepserver.domain.user.dto.request.SignupRequest; import com.keepgoing.keepserver.domain.user.dto.request.UserInfoRequest; @@ -36,8 +35,8 @@ public ResponseEntity registerAndAuthenticateUser(@RequestBody SignupRequest @Operation(summary = "프로필", description = "토큰을 이용하여 유저 정보와 대여한 기자재 및 도서 목록을 조회합니다.") @GetMapping("/userinfo") - public UserDto provideUserInfo(Authentication authentication) { - return userService.provideUserInfo(authentication); + public ResponseEntity provideUserInfo(Authentication authentication) { + return ResponseEntity.ok().body(userService.provideUserInfo(authentication)); } @Operation(summary = "프로필 수정", description = "유저 정보를 수정합니다.") @@ -45,4 +44,9 @@ public UserDto provideUserInfo(Authentication authentication) { public ResponseEntity updateUserData(@RequestBody UserInfoRequest request, Authentication authentication) { return userService.updateUserData(request, authentication); } + @Operation(summary = "학생이 받은 공지 불러오기", description = "본인의 공지를 불러옵니다.") + @GetMapping("/notices") + public ResponseEntity getNoticeByUser(Authentication authentication){ + return ResponseEntity.ok().body(userService.getNoticeByUser(authentication)); + } } \ No newline at end of file diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepository.java b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepository.java index 10e9214f..d3c39efd 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepository.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepository.java @@ -1,7 +1,9 @@ package com.keepgoing.keepserver.domain.user.domain.repository.user; import com.keepgoing.keepserver.domain.user.dto.UserDto; +import com.keepgoing.keepserver.domain.user.dto.UserNoticesDto; public interface UserQueryRepository { - UserDto getProfileByEmail(long id); + UserDto getProfileById(long id); + UserNoticesDto getNoticesById(long id); } diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepositoryImpl.java b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepositoryImpl.java index 92455d96..7ceb9c94 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepositoryImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserQueryRepositoryImpl.java @@ -5,7 +5,9 @@ import com.keepgoing.keepserver.domain.notice.payload.res.QNoticeResponseDto; import com.keepgoing.keepserver.domain.user.domain.entity.user.QUser; import com.keepgoing.keepserver.domain.user.dto.QUserDto; +import com.keepgoing.keepserver.domain.user.dto.QUserNoticesDto; import com.keepgoing.keepserver.domain.user.dto.UserDto; +import com.keepgoing.keepserver.domain.user.dto.UserNoticesDto; import com.querydsl.core.group.GroupBy; import com.querydsl.jpa.impl.JPAQueryFactory; import lombok.RequiredArgsConstructor; @@ -14,23 +16,19 @@ import static com.keepgoing.keepserver.domain.book.domain.entity.QBook.book; import static com.keepgoing.keepserver.domain.device.domain.entity.QDevice.device; -import static com.keepgoing.keepserver.domain.notice.domain.entity.notice.QNoticeReception.noticeReception; import static com.keepgoing.keepserver.domain.user.domain.entity.user.QUser.user; import static com.keepgoing.keepserver.domain.notice.domain.entity.notice.QNotice.notice; +import static com.keepgoing.keepserver.domain.notice.domain.entity.notice.QNoticeReception.noticeReception; @RequiredArgsConstructor public class UserQueryRepositoryImpl implements UserQueryRepository { private final JPAQueryFactory factory; @Override - public UserDto getProfileByEmail(long id) { - var teacher = new QUser("teacher"); + public UserDto getProfileById(long id) { var map = factory .select(user) .from(user) - .leftJoin(noticeReception).on(noticeReception.user.id.eq(user.id)) - .leftJoin(noticeReception.notice, notice) - .leftJoin(notice.teacher, teacher) .leftJoin(device).on(device.borrower.id.eq(user.id)) .leftJoin(book).on(book.borrower.id.eq(user.id)) .where(user.id.eq(id)) @@ -61,20 +59,10 @@ public UserDto getProfileByEmail(long id) { book.rentDate, book.state ) - ), - GroupBy.set( - new QNoticeResponseDto( - notice.idx, - notice.message, - teacher.name, - notice.createTime, - notice.editTime - ) ) )) ); - System.out.println(map); var dto = map.get(id); return UserDto.builder() .id(dto.id()) @@ -83,7 +71,38 @@ public UserDto getProfileByEmail(long id) { .teacher(dto.teacher()) .borrowedDevices(dto.borrowedDevices().stream().filter(r -> r.id() != 0).collect(Collectors.toSet())) .borrowedBooks(dto.borrowedBooks().stream().filter(r -> r.id() != 0).collect(Collectors.toSet())) - .notices(dto.notices().stream().filter(r -> r.id() != 0).collect(Collectors.toSet())) .build(); } + + @Override + public UserNoticesDto getNoticesById(long id) { + var teacher = new QUser("teacher"); + var map = factory + .select(user) + .from(user) + .leftJoin(noticeReception).on(noticeReception.user.id.eq(user.id)) + .leftJoin(noticeReception.notice, notice) + .leftJoin(notice.teacher, teacher) + .where(user.id.eq(id)) + .distinct() + .transform( + GroupBy.groupBy(user.id).as(new QUserNoticesDto( + GroupBy.set( + new QNoticeResponseDto( + notice.idx, + notice.message, + teacher.name, + notice.createTime, + notice.editTime + ) + ) + ) + ) + ); + UserNoticesDto dto = map.get(id); + return UserNoticesDto.builder() + .notices(dto.notices().stream().filter(r -> r.id() != 0).collect(Collectors.toSet())) + .build(); +// return null; + } } diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/dto/UserDto.java b/src/main/java/com/keepgoing/keepserver/domain/user/dto/UserDto.java index 4b141c32..c855339a 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/dto/UserDto.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/dto/UserDto.java @@ -2,7 +2,6 @@ import com.keepgoing.keepserver.domain.book.payload.response.BookResponseDto; import com.keepgoing.keepserver.domain.device.payload.response.DeviceResponseDto; -import com.keepgoing.keepserver.domain.notice.payload.res.NoticeResponseDto; import com.querydsl.core.annotations.QueryProjection; import lombok.Builder; @@ -15,10 +14,8 @@ public record UserDto( String name, boolean teacher, Set borrowedDevices, - Set borrowedBooks, - Set notices + Set borrowedBooks ) { - @QueryProjection public UserDto {} } diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/dto/UserNoticesDto.java b/src/main/java/com/keepgoing/keepserver/domain/user/dto/UserNoticesDto.java new file mode 100644 index 00000000..d72d16d6 --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/domain/user/dto/UserNoticesDto.java @@ -0,0 +1,15 @@ +package com.keepgoing.keepserver.domain.user.dto; + +import com.keepgoing.keepserver.domain.notice.payload.res.NoticeResponseDto; +import com.querydsl.core.annotations.QueryProjection; +import lombok.Builder; + +import java.util.Set; + +@Builder +public record UserNoticesDto ( + Set notices +) { + @QueryProjection + public UserNoticesDto{} +} diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserServiceImpl.java index 194cc9c5..86a12087 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserServiceImpl.java @@ -3,6 +3,7 @@ import com.keepgoing.keepserver.domain.user.domain.entity.user.User; import com.keepgoing.keepserver.domain.user.domain.repository.user.UserRepository; import com.keepgoing.keepserver.domain.user.dto.UserDto; +import com.keepgoing.keepserver.domain.user.dto.UserNoticesDto; import com.keepgoing.keepserver.domain.user.dto.request.SignupRequest; import com.keepgoing.keepserver.domain.user.dto.request.UserInfoRequest; import com.keepgoing.keepserver.domain.user.dto.response.ApiResponse; @@ -53,7 +54,13 @@ public ResponseEntity updateUserData(UserInfoRequest request, Authentica @Override public UserDto provideUserInfo(Authentication authentication) { UserDetailsImpl ud = (UserDetailsImpl) authentication.getPrincipal(); - return userRepository.getProfileByEmail(ud.getId()); + return userRepository.getProfileById(ud.getId()); + } + + @Override + public UserNoticesDto getNoticeByUser(Authentication authentication) { + var ud = (UserDetailsImpl) authentication.getPrincipal(); + return userRepository.getNoticesById(ud.getId()); } /* 인증 및 JWT 토큰 생성 */ From 438e91809c5d8d9a1c124e105a4b21bad7b72733 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Sat, 14 Sep 2024 20:01:10 +0900 Subject: [PATCH 19/34] Refactor :: delete @ToString / initialize List Collection --- .../keepserver/domain/user/domain/entity/user/User.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/domain/entity/user/User.java b/src/main/java/com/keepgoing/keepserver/domain/user/domain/entity/user/User.java index 36c3b971..6294d443 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/domain/entity/user/User.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/domain/entity/user/User.java @@ -6,16 +6,15 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.ToString; import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import java.util.ArrayList; import java.util.List; @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @EntityListeners(AuditingEntityListener.class) -@ToString @Table(name = "users") public class User { @Id @@ -47,10 +46,10 @@ public class User { private boolean teacher; @OneToMany(mappedBy = "teacher", fetch = FetchType.LAZY) - private List notices; + private List notices = new ArrayList<>(); @OneToMany(mappedBy = "user", fetch = FetchType.LAZY) - private List noticeReceptions; + private List noticeReceptions = new ArrayList<>(); public static User registerUser( String email, From 3c4468c30674691d3c14f737a7e51f25767a7a52 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Sat, 14 Sep 2024 20:02:16 +0900 Subject: [PATCH 20/34] Edit :: for each -> map method --- .../notice/service/NoticeServiceImpl.java | 24 +++++++------------ 1 file changed, 8 insertions(+), 16 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java index 20c8856b..cd00e99c 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java @@ -17,8 +17,8 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; @Service @RequiredArgsConstructor @@ -61,15 +61,15 @@ public BaseResponse updateNotice(Long id, NoticeCreateDto noticeCreateDto, Authe } private void setReceptions(NoticeCreateDto noticeCreateDto, Notice notice) { - List receptions = new ArrayList<>(); List users = noticeCreateDto.isGlobal() ? userRepository.findUsersByTeacherIs(false) : userRepository.findUsersByIdIn(noticeCreateDto.userIds()); - for (User user : users) { - receptions.add(NoticeReception.builder().user(user).notice(notice).build()); - } - + List receptions = users.stream().map(user -> + NoticeReception.builder() + .user(user) + .notice(notice) + .build()).collect(Collectors.toList()); noticeReceptionRepository.saveAll(receptions); } @@ -83,18 +83,15 @@ public BaseResponse deleteNotice(Long id, Authentication authentication) { } @Override - @Transactional public BaseResponse getNotice(Authentication authentication) { List notices = noticeRepository.findAll(); return new BaseResponse(HttpStatus.ACCEPTED, "전체 공지: ", getNoticeList(notices)); } @Override - @Transactional - public BaseResponse getMyNotice(Authentication authentication) { + public BaseResponse getNoticeOfTeacher(Authentication authentication) { User teacher = getTeacher(authentication); List notices = noticeRepository.findNoticesByTeacher(teacher); - getNoticeList(notices); return new BaseResponse(HttpStatus.OK, "내가 쓴 글 불러오기", getNoticeList(notices)); } @@ -104,11 +101,6 @@ private User getTeacher(Authentication authentication) { } private List getNoticeList(List notices) { - List dtoList = new ArrayList<>(); - - for (Notice n : notices) { - dtoList.add(mapper.entityToDto(n)); - } - return dtoList; + return notices.stream().map(mapper :: entityToDto).collect(Collectors.toList()); } } From 83f5a0c5e26830cce0f1e0c9636c86e0802b90c9 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Sat, 14 Sep 2024 20:02:58 +0900 Subject: [PATCH 21/34] Refactor :: change method name --- .../domain/notice/presentation/NoticeController.java | 8 ++++---- .../keepserver/domain/notice/service/NoticeService.java | 2 +- .../keepserver/domain/user/service/user/UserService.java | 2 ++ 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java b/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java index 75862d3c..d39c15f6 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java @@ -39,9 +39,9 @@ public BaseResponse allNotice(Authentication authentication){ return noticeService.getNotice(authentication); } - @Operation(summary = "내 공지 불러오기", description = "본인의 공지를 불러옵니다.") - @GetMapping("/my") - public BaseResponse myNotice(Authentication authentication){ - return noticeService.getMyNotice(authentication); + @Operation(summary = "선생님이 쓴 글 (본인 공지) 불러오기", description = "본인의 공지를 불러옵니다.") + @GetMapping("/teacher-my") + public BaseResponse getNoticeOfTeacher(Authentication authentication){ + return noticeService.getNoticeOfTeacher(authentication); } } diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java index 2439bf5f..385ed456 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java @@ -9,5 +9,5 @@ public interface NoticeService { BaseResponse updateNotice(Long id, NoticeCreateDto noticeCreateDto, Authentication authentication); BaseResponse deleteNotice(Long id, Authentication authentication); BaseResponse getNotice(Authentication authentication); - BaseResponse getMyNotice(Authentication authentication); + BaseResponse getNoticeOfTeacher(Authentication authentication); } diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserService.java b/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserService.java index a6b99191..f4c730a9 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserService.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserService.java @@ -1,6 +1,7 @@ package com.keepgoing.keepserver.domain.user.service.user; import com.keepgoing.keepserver.domain.user.dto.UserDto; +import com.keepgoing.keepserver.domain.user.dto.UserNoticesDto; import com.keepgoing.keepserver.domain.user.dto.request.SignupRequest; import com.keepgoing.keepserver.domain.user.dto.request.UserInfoRequest; import com.keepgoing.keepserver.domain.user.dto.response.ApiResponse; @@ -14,4 +15,5 @@ public interface UserService { ResponseEntity updateUserData(UserInfoRequest request, Authentication authentication); UserDto provideUserInfo(Authentication authentication); JwtResponse authenticateAndGenerateJWT(String email, String password); + UserNoticesDto getNoticeByUser(Authentication authentication); } \ No newline at end of file From a9241be836b23b2d5063f295521ce5fe6a7705a5 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Sun, 15 Sep 2024 23:36:34 +0900 Subject: [PATCH 22/34] Refactor :: get teacher method in notice -> in user service --- .../domain/notice/service/NoticeServiceImpl.java | 16 ++++++---------- .../domain/user/service/user/UserService.java | 9 ++++++++- .../user/service/user/UserServiceImpl.java | 5 +++++ 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java index cd00e99c..0999529e 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java @@ -9,7 +9,7 @@ import com.keepgoing.keepserver.domain.notice.payload.res.NoticeResponseDto; import com.keepgoing.keepserver.domain.user.domain.entity.user.User; import com.keepgoing.keepserver.domain.user.domain.repository.user.UserRepository; -import com.keepgoing.keepserver.domain.user.security.service.UserDetailsImpl; +import com.keepgoing.keepserver.domain.user.service.user.UserService; import com.keepgoing.keepserver.global.common.BaseResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.HttpStatus; @@ -27,6 +27,7 @@ public class NoticeServiceImpl implements NoticeService { private final UserRepository userRepository; private final NoticeReceptionRepository noticeReceptionRepository; private final NoticeMapper mapper; + private final UserService userService; @Override @Transactional @@ -34,7 +35,7 @@ public BaseResponse createNotice(NoticeCreateDto noticeCreateDto, Authentication Notice notice = noticeRepository.save( Notice.builder() .isGlobal(noticeCreateDto.isGlobal()) - .teacher(getTeacher(authentication)) + .teacher(userService.getTeacher(authentication)) .message(noticeCreateDto.message()).build() ); setReceptions(noticeCreateDto, notice); @@ -45,7 +46,7 @@ public BaseResponse createNotice(NoticeCreateDto noticeCreateDto, Authentication @Override @Transactional public BaseResponse updateNotice(Long id, NoticeCreateDto noticeCreateDto, Authentication authentication) { - User teacher = getTeacher(authentication); + User teacher = userService.getTeacher(authentication); Notice notice = noticeRepository.findNoticeByIdxAndTeacher_Id(id, teacher.getId()); notice.setGlobal(noticeCreateDto.isGlobal()); @@ -76,7 +77,7 @@ private void setReceptions(NoticeCreateDto noticeCreateDto, Notice notice) { @Override @Transactional public BaseResponse deleteNotice(Long id, Authentication authentication) { - User teacher = getTeacher(authentication); + User teacher = userService.getTeacher(authentication); Notice notice = noticeRepository.findNoticeByIdxAndTeacher_Id(id, teacher.getId()); noticeRepository.delete(notice); return new BaseResponse(HttpStatus.OK, "공지가 삭제었습니다."); @@ -90,16 +91,11 @@ public BaseResponse getNotice(Authentication authentication) { @Override public BaseResponse getNoticeOfTeacher(Authentication authentication) { - User teacher = getTeacher(authentication); + User teacher = userService.getTeacher(authentication); List notices = noticeRepository.findNoticesByTeacher(teacher); return new BaseResponse(HttpStatus.OK, "내가 쓴 글 불러오기", getNoticeList(notices)); } - private User getTeacher(Authentication authentication) { - var ud = (UserDetailsImpl) authentication.getPrincipal(); - return userRepository.findByIdAndTeacherIsTrue(ud.getId()); - } - private List getNoticeList(List notices) { return notices.stream().map(mapper :: entityToDto).collect(Collectors.toList()); } diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserService.java b/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserService.java index f4c730a9..5c39fa17 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserService.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserService.java @@ -1,5 +1,6 @@ package com.keepgoing.keepserver.domain.user.service.user; +import com.keepgoing.keepserver.domain.user.domain.entity.user.User; import com.keepgoing.keepserver.domain.user.dto.UserDto; import com.keepgoing.keepserver.domain.user.dto.UserNoticesDto; import com.keepgoing.keepserver.domain.user.dto.request.SignupRequest; @@ -12,8 +13,14 @@ public interface UserService { ApiResponse registerUser(SignupRequest signupRequest) throws BusinessException; + ResponseEntity updateUserData(UserInfoRequest request, Authentication authentication); + UserDto provideUserInfo(Authentication authentication); + JwtResponse authenticateAndGenerateJWT(String email, String password); + UserNoticesDto getNoticeByUser(Authentication authentication); -} \ No newline at end of file + + User getTeacher(Authentication authentication); +} diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserServiceImpl.java index 86a12087..a63738cb 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserServiceImpl.java @@ -106,4 +106,9 @@ private User findUserByEmail(String email) { private void updateUser(User user, UserInfoRequest request) { user.fixUserData(request.getEmail(), request.getName()); } + + public User getTeacher(Authentication authentication) { + var ud = (UserDetailsImpl) authentication.getPrincipal(); + return userRepository.findByIdAndTeacherIsTrue(ud.getId()); + } } From 8f2f5a77c0eb91f4131edb898c60a110994c05b4 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Sun, 15 Sep 2024 23:52:46 +0900 Subject: [PATCH 23/34] Refactor :: moved createDtoToEntity in NoticeServiceImpl to NoticeCreateDto --- .../domain/notice/payload/req/NoticeCreateDto.java | 11 +++++++++++ .../domain/notice/service/NoticeServiceImpl.java | 7 +------ 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java index 58cfe083..78df159e 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java @@ -1,5 +1,7 @@ package com.keepgoing.keepserver.domain.notice.payload.req; +import com.keepgoing.keepserver.domain.notice.domain.entity.notice.Notice; +import com.keepgoing.keepserver.domain.user.domain.entity.user.User; import lombok.Builder; import java.util.List; @@ -10,4 +12,13 @@ public record NoticeCreateDto ( boolean isGlobal, List userIds ) { + + public Notice toEntity(User teacher) { + return Notice.builder() + .isGlobal(isGlobal) + .teacher(teacher) + .message(message) + .build(); + } + } diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java index 0999529e..d2cbd9a2 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java @@ -32,12 +32,7 @@ public class NoticeServiceImpl implements NoticeService { @Override @Transactional public BaseResponse createNotice(NoticeCreateDto noticeCreateDto, Authentication authentication) { - Notice notice = noticeRepository.save( - Notice.builder() - .isGlobal(noticeCreateDto.isGlobal()) - .teacher(userService.getTeacher(authentication)) - .message(noticeCreateDto.message()).build() - ); + Notice notice = noticeRepository.save(noticeCreateDto.toEntity(userService.getTeacher(authentication))); setReceptions(noticeCreateDto, notice); return new BaseResponse(HttpStatus.OK, "공지 등록 성공", mapper.entityToDto(notice)); From 19a4aef47753842b0a9ea965837efbc17195d0ec Mon Sep 17 00:00:00 2001 From: priverg163 Date: Wed, 18 Sep 2024 11:58:13 +0900 Subject: [PATCH 24/34] Chore :: Add MapConstruct build.gradle --- build.gradle | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build.gradle b/build.gradle index a2dea612..8b36b90e 100644 --- a/build.gradle +++ b/build.gradle @@ -49,6 +49,8 @@ dependencies { annotationProcessor 'jakarta.persistence:jakarta.persistence-api' annotationProcessor 'jakarta.annotation:jakarta.annotation-api' + implementation 'org.mapstruct:mapstruct:1.5.5.Final' + annotationProcessor 'org.mapstruct:mapstruct-processor:1.5.5.Final' } tasks.named('test') { From 72f0c6f29071e842433362d1c26acb9c71d26696 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Wed, 18 Sep 2024 11:59:23 +0900 Subject: [PATCH 25/34] Edit :: NoticeMapper to mapstruct --- .../notice/domain/mapper/NoticeMapper.java | 27 ++++++++++--------- .../notice/payload/req/NoticeCreateDto.java | 11 -------- .../notice/service/NoticeServiceImpl.java | 2 +- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/mapper/NoticeMapper.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/mapper/NoticeMapper.java index 343aac23..c71b2aa5 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/mapper/NoticeMapper.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/mapper/NoticeMapper.java @@ -1,18 +1,21 @@ package com.keepgoing.keepserver.domain.notice.domain.mapper; import com.keepgoing.keepserver.domain.notice.domain.entity.notice.Notice; +import com.keepgoing.keepserver.domain.notice.payload.req.NoticeCreateDto; import com.keepgoing.keepserver.domain.notice.payload.res.NoticeResponseDto; -import org.springframework.stereotype.Component; +import com.keepgoing.keepserver.domain.user.domain.entity.user.User; +import org.mapstruct.Mapper; +import org.mapstruct.Mapping; + +@Mapper(componentModel = "spring") +public interface NoticeMapper { + @Mapping(source = "idx", target = "id") + @Mapping(source = "teacher.name", target = "teacherName") + NoticeResponseDto entityToDto(Notice notice); + + @Mapping(target = "teacher", source = "teacher") + @Mapping(target = "isGlobal", source = "noticeCreateDto.isGlobal") + @Mapping(target = "message", source = "noticeCreateDto.message") + Notice toEntity(NoticeCreateDto noticeCreateDto, User teacher); -@Component -public class NoticeMapper { - public NoticeResponseDto entityToDto(Notice notice){ - return NoticeResponseDto.builder() - .id(notice.getIdx()) - .message(notice.getMessage()) - .createTime(notice.getCreateTime()) - .editTime(notice.getEditTime()) - .teacherName(notice.getTeacher().getName()) - .build(); - } } diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java index 78df159e..58cfe083 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java @@ -1,7 +1,5 @@ package com.keepgoing.keepserver.domain.notice.payload.req; -import com.keepgoing.keepserver.domain.notice.domain.entity.notice.Notice; -import com.keepgoing.keepserver.domain.user.domain.entity.user.User; import lombok.Builder; import java.util.List; @@ -12,13 +10,4 @@ public record NoticeCreateDto ( boolean isGlobal, List userIds ) { - - public Notice toEntity(User teacher) { - return Notice.builder() - .isGlobal(isGlobal) - .teacher(teacher) - .message(message) - .build(); - } - } diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java index d2cbd9a2..054e7e69 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java @@ -32,7 +32,7 @@ public class NoticeServiceImpl implements NoticeService { @Override @Transactional public BaseResponse createNotice(NoticeCreateDto noticeCreateDto, Authentication authentication) { - Notice notice = noticeRepository.save(noticeCreateDto.toEntity(userService.getTeacher(authentication))); + Notice notice = noticeRepository.save(mapper.toEntity(noticeCreateDto, userService.getTeacher(authentication))); setReceptions(noticeCreateDto, notice); return new BaseResponse(HttpStatus.OK, "공지 등록 성공", mapper.entityToDto(notice)); From 41205147ca56ec3fec19a3db0ee5fe4ddfa8c556 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Wed, 18 Sep 2024 12:08:55 +0900 Subject: [PATCH 26/34] Chore :: add spring-boot-starter-validation --- build.gradle | 1 + 1 file changed, 1 insertion(+) diff --git a/build.gradle b/build.gradle index 8b36b90e..a256b9f6 100644 --- a/build.gradle +++ b/build.gradle @@ -22,6 +22,7 @@ repositories { } dependencies { + implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' From eb6278a34a3143d251865ee0e60c87faf0d69e13 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Wed, 18 Sep 2024 12:09:46 +0900 Subject: [PATCH 27/34] Add :: @Valid in NoticeController --- .../keepserver/domain/notice/payload/req/NoticeCreateDto.java | 4 ++++ .../domain/notice/presentation/NoticeController.java | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java index 58cfe083..7615511b 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java @@ -1,12 +1,16 @@ package com.keepgoing.keepserver.domain.notice.payload.req; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; import lombok.Builder; import java.util.List; @Builder public record NoticeCreateDto ( + @NotBlank(message = "메시지는 필수입니다.") String message, + @NotNull(message = "isGlobal 값은 필수입니다.") boolean isGlobal, List userIds ) { diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java b/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java index d39c15f6..77b90fc8 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java @@ -5,6 +5,7 @@ import com.keepgoing.keepserver.global.common.BaseResponse; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.security.core.Authentication; import org.springframework.web.bind.annotation.*; @@ -18,7 +19,7 @@ public class NoticeController { private final NoticeService noticeService; @Operation(summary = "공지 등록", description = "공지 등록을 진행합니다. 전체 학생을 등록하고 싶으실 경우엔 isGlobal을 true로 해주시고, list는 빈값으로 보내시면 됩니다.") @PostMapping("/post") - public BaseResponse addNotice(@RequestBody NoticeCreateDto noticeCreateDto, Authentication authentication) { + public BaseResponse addNotice(@Valid @RequestBody NoticeCreateDto noticeCreateDto, Authentication authentication) { return noticeService.createNotice(noticeCreateDto,authentication); } @Operation(summary = "공지 수정", description = "등록된 공지를 수정합니다.") From a03e23571a89e94d470a7464f064568ba997b611 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Wed, 18 Sep 2024 12:10:15 +0900 Subject: [PATCH 28/34] Add :: handleValidationExceptions --- .../global/exception/ExceptionAdvice.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/main/java/com/keepgoing/keepserver/global/exception/ExceptionAdvice.java b/src/main/java/com/keepgoing/keepserver/global/exception/ExceptionAdvice.java index c0116829..5acb27e6 100644 --- a/src/main/java/com/keepgoing/keepserver/global/exception/ExceptionAdvice.java +++ b/src/main/java/com/keepgoing/keepserver/global/exception/ExceptionAdvice.java @@ -1,10 +1,16 @@ package com.keepgoing.keepserver.global.exception; import lombok.Builder; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; +import org.springframework.validation.FieldError; +import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.RestControllerAdvice; +import java.util.HashMap; +import java.util.Map; + @RestControllerAdvice public class ExceptionAdvice { @@ -20,4 +26,13 @@ public ResponseEntity handleException(BusinessException ex) { .build(); return new ResponseEntity<>(response, ex.getError().getStatus()); } + + @ExceptionHandler(MethodArgumentNotValidException.class) + public ResponseEntity> handleValidationExceptions(MethodArgumentNotValidException ex) { + Map errors = new HashMap<>(); + for (FieldError error : ex.getBindingResult().getFieldErrors()) { + errors.put(error.getField(), error.getDefaultMessage()); + } + return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST); + } } \ No newline at end of file From ad72127f902b88d915beb2d8d0a4f9e4eae6a1f4 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Thu, 19 Sep 2024 12:09:43 +0900 Subject: [PATCH 29/34] Refactor :: renamed from NoticeCreateDto -> NoticeRequestDto --- .../notice/domain/mapper/NoticeMapper.java | 4 ++-- ...ceCreateDto.java => NoticeRequestDto.java} | 2 +- .../notice/presentation/NoticeController.java | 10 ++++---- .../domain/notice/service/NoticeService.java | 6 ++--- .../notice/service/NoticeServiceImpl.java | 24 +++++++++---------- 5 files changed, 23 insertions(+), 23 deletions(-) rename src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/{NoticeCreateDto.java => NoticeRequestDto.java} (92%) diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/mapper/NoticeMapper.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/mapper/NoticeMapper.java index c71b2aa5..5b744ded 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/mapper/NoticeMapper.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/mapper/NoticeMapper.java @@ -1,7 +1,7 @@ package com.keepgoing.keepserver.domain.notice.domain.mapper; import com.keepgoing.keepserver.domain.notice.domain.entity.notice.Notice; -import com.keepgoing.keepserver.domain.notice.payload.req.NoticeCreateDto; +import com.keepgoing.keepserver.domain.notice.payload.req.NoticeRequestDto; import com.keepgoing.keepserver.domain.notice.payload.res.NoticeResponseDto; import com.keepgoing.keepserver.domain.user.domain.entity.user.User; import org.mapstruct.Mapper; @@ -16,6 +16,6 @@ public interface NoticeMapper { @Mapping(target = "teacher", source = "teacher") @Mapping(target = "isGlobal", source = "noticeCreateDto.isGlobal") @Mapping(target = "message", source = "noticeCreateDto.message") - Notice toEntity(NoticeCreateDto noticeCreateDto, User teacher); + Notice toEntity(NoticeRequestDto noticeRequestDto, User teacher); } diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeRequestDto.java similarity index 92% rename from src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java rename to src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeRequestDto.java index 7615511b..511b54d3 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeCreateDto.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/payload/req/NoticeRequestDto.java @@ -7,7 +7,7 @@ import java.util.List; @Builder -public record NoticeCreateDto ( +public record NoticeRequestDto( @NotBlank(message = "메시지는 필수입니다.") String message, @NotNull(message = "isGlobal 값은 필수입니다.") diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java b/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java index 77b90fc8..32d13cae 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java @@ -1,6 +1,6 @@ package com.keepgoing.keepserver.domain.notice.presentation; -import com.keepgoing.keepserver.domain.notice.payload.req.NoticeCreateDto; +import com.keepgoing.keepserver.domain.notice.payload.req.NoticeRequestDto; import com.keepgoing.keepserver.domain.notice.service.NoticeService; import com.keepgoing.keepserver.global.common.BaseResponse; import io.swagger.v3.oas.annotations.Operation; @@ -19,13 +19,13 @@ public class NoticeController { private final NoticeService noticeService; @Operation(summary = "공지 등록", description = "공지 등록을 진행합니다. 전체 학생을 등록하고 싶으실 경우엔 isGlobal을 true로 해주시고, list는 빈값으로 보내시면 됩니다.") @PostMapping("/post") - public BaseResponse addNotice(@Valid @RequestBody NoticeCreateDto noticeCreateDto, Authentication authentication) { - return noticeService.createNotice(noticeCreateDto,authentication); + public BaseResponse addNotice(@Valid @RequestBody NoticeRequestDto noticeRequestDto, Authentication authentication) { + return noticeService.createNotice(noticeRequestDto, authentication); } @Operation(summary = "공지 수정", description = "등록된 공지를 수정합니다.") @PatchMapping("/edit/{id}") - public BaseResponse editNotice(@PathVariable Long id, @RequestBody NoticeCreateDto noticeCreateDto, Authentication authentication) { - return noticeService.updateNotice(id, noticeCreateDto,authentication); + public BaseResponse editNotice(@PathVariable Long id, @RequestBody NoticeRequestDto noticeRequestDto, Authentication authentication) { + return noticeService.updateNotice(id, noticeRequestDto, authentication); } @Operation(summary = "공지 삭제", description = "등록된 공지를 삭제합니다.") diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java index 385ed456..3c66710f 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java @@ -1,12 +1,12 @@ package com.keepgoing.keepserver.domain.notice.service; -import com.keepgoing.keepserver.domain.notice.payload.req.NoticeCreateDto; +import com.keepgoing.keepserver.domain.notice.payload.req.NoticeRequestDto; import com.keepgoing.keepserver.global.common.BaseResponse; import org.springframework.security.core.Authentication; public interface NoticeService { - BaseResponse createNotice(NoticeCreateDto noticeCreateDto, Authentication authentication); - BaseResponse updateNotice(Long id, NoticeCreateDto noticeCreateDto, Authentication authentication); + BaseResponse createNotice(NoticeRequestDto noticeRequestDto, Authentication authentication); + BaseResponse updateNotice(Long id, NoticeRequestDto noticeRequestDto, Authentication authentication); BaseResponse deleteNotice(Long id, Authentication authentication); BaseResponse getNotice(Authentication authentication); BaseResponse getNoticeOfTeacher(Authentication authentication); diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java index 054e7e69..fd3c198c 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java @@ -5,7 +5,7 @@ import com.keepgoing.keepserver.domain.notice.domain.mapper.NoticeMapper; import com.keepgoing.keepserver.domain.notice.domain.repository.NoticeReceptionRepository; import com.keepgoing.keepserver.domain.notice.domain.repository.NoticeRepository; -import com.keepgoing.keepserver.domain.notice.payload.req.NoticeCreateDto; +import com.keepgoing.keepserver.domain.notice.payload.req.NoticeRequestDto; import com.keepgoing.keepserver.domain.notice.payload.res.NoticeResponseDto; import com.keepgoing.keepserver.domain.user.domain.entity.user.User; import com.keepgoing.keepserver.domain.user.domain.repository.user.UserRepository; @@ -31,35 +31,35 @@ public class NoticeServiceImpl implements NoticeService { @Override @Transactional - public BaseResponse createNotice(NoticeCreateDto noticeCreateDto, Authentication authentication) { - Notice notice = noticeRepository.save(mapper.toEntity(noticeCreateDto, userService.getTeacher(authentication))); - setReceptions(noticeCreateDto, notice); + public BaseResponse createNotice(NoticeRequestDto noticeRequestDto, Authentication authentication) { + Notice notice = noticeRepository.save(mapper.toEntity(noticeRequestDto, userService.getTeacher(authentication))); + setReceptions(noticeRequestDto, notice); return new BaseResponse(HttpStatus.OK, "공지 등록 성공", mapper.entityToDto(notice)); } @Override @Transactional - public BaseResponse updateNotice(Long id, NoticeCreateDto noticeCreateDto, Authentication authentication) { + public BaseResponse updateNotice(Long id, NoticeRequestDto noticeRequestDto, Authentication authentication) { User teacher = userService.getTeacher(authentication); Notice notice = noticeRepository.findNoticeByIdxAndTeacher_Id(id, teacher.getId()); - notice.setGlobal(noticeCreateDto.isGlobal()); - if (noticeCreateDto.message() != null) { - notice.setMessage(noticeCreateDto.message()); + notice.setGlobal(noticeRequestDto.isGlobal()); + if (noticeRequestDto.message() != null) { + notice.setMessage(noticeRequestDto.message()); } noticeRepository.save(notice); noticeReceptionRepository.deleteAllByNotice(notice); - setReceptions(noticeCreateDto, notice); + setReceptions(noticeRequestDto, notice); return new BaseResponse(HttpStatus.ACCEPTED, "공지 수정 성공", mapper.entityToDto(notice)); } - private void setReceptions(NoticeCreateDto noticeCreateDto, Notice notice) { - List users = noticeCreateDto.isGlobal() + private void setReceptions(NoticeRequestDto noticeRequestDto, Notice notice) { + List users = noticeRequestDto.isGlobal() ? userRepository.findUsersByTeacherIs(false) - : userRepository.findUsersByIdIn(noticeCreateDto.userIds()); + : userRepository.findUsersByIdIn(noticeRequestDto.userIds()); List receptions = users.stream().map(user -> NoticeReception.builder() From 7a16384466e4f63d186250386c80b7f59f509225 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Thu, 19 Sep 2024 12:10:53 +0900 Subject: [PATCH 30/34] Refactor :: remove parameter in getAllNotice --- .../domain/notice/presentation/NoticeController.java | 4 ++-- .../keepserver/domain/notice/service/NoticeService.java | 2 +- .../keepserver/domain/notice/service/NoticeServiceImpl.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java b/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java index 32d13cae..8b5b6092 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/presentation/NoticeController.java @@ -36,8 +36,8 @@ public BaseResponse deleteNotice(@PathVariable Long id, Authentication authentic @Operation(summary = "전체 공지 불러오기", description = "존재하는 모든 공지를 불러옵니다.") @GetMapping("/all") - public BaseResponse allNotice(Authentication authentication){ - return noticeService.getNotice(authentication); + public BaseResponse allNotice(){ + return noticeService.getNotice(); } @Operation(summary = "선생님이 쓴 글 (본인 공지) 불러오기", description = "본인의 공지를 불러옵니다.") diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java index 3c66710f..6c969749 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeService.java @@ -8,6 +8,6 @@ public interface NoticeService { BaseResponse createNotice(NoticeRequestDto noticeRequestDto, Authentication authentication); BaseResponse updateNotice(Long id, NoticeRequestDto noticeRequestDto, Authentication authentication); BaseResponse deleteNotice(Long id, Authentication authentication); - BaseResponse getNotice(Authentication authentication); + BaseResponse getNotice(); BaseResponse getNoticeOfTeacher(Authentication authentication); } diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java index fd3c198c..6e32e37a 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/service/NoticeServiceImpl.java @@ -79,7 +79,7 @@ public BaseResponse deleteNotice(Long id, Authentication authentication) { } @Override - public BaseResponse getNotice(Authentication authentication) { + public BaseResponse getNotice() { List notices = noticeRepository.findAll(); return new BaseResponse(HttpStatus.ACCEPTED, "전체 공지: ", getNoticeList(notices)); } From 286d82aca3b5ccf38a3837af07cea3399139ee79 Mon Sep 17 00:00:00 2001 From: priverg163 Date: Thu, 19 Sep 2024 17:25:31 +0900 Subject: [PATCH 31/34] Refactor :: renamed from NoticeCreateDto -> NoticeRequestDto --- .../keepserver/domain/notice/domain/mapper/NoticeMapper.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/mapper/NoticeMapper.java b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/mapper/NoticeMapper.java index 5b744ded..f1759502 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/notice/domain/mapper/NoticeMapper.java +++ b/src/main/java/com/keepgoing/keepserver/domain/notice/domain/mapper/NoticeMapper.java @@ -14,8 +14,8 @@ public interface NoticeMapper { NoticeResponseDto entityToDto(Notice notice); @Mapping(target = "teacher", source = "teacher") - @Mapping(target = "isGlobal", source = "noticeCreateDto.isGlobal") - @Mapping(target = "message", source = "noticeCreateDto.message") + @Mapping(target = "isGlobal", source = "noticeRequestDto.isGlobal") + @Mapping(target = "message", source = "noticeRequestDto.message") Notice toEntity(NoticeRequestDto noticeRequestDto, User teacher); } From 3c11ecd3524f6d5818df7ce65ba3dcabb4a74c5a Mon Sep 17 00:00:00 2001 From: priverg163 Date: Thu, 19 Sep 2024 17:25:50 +0900 Subject: [PATCH 32/34] Add :: UserException --- .../global/exception/user/UserError.java | 14 ++++++++++++++ .../global/exception/user/UserException.java | 16 ++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/main/java/com/keepgoing/keepserver/global/exception/user/UserError.java create mode 100644 src/main/java/com/keepgoing/keepserver/global/exception/user/UserException.java diff --git a/src/main/java/com/keepgoing/keepserver/global/exception/user/UserError.java b/src/main/java/com/keepgoing/keepserver/global/exception/user/UserError.java new file mode 100644 index 00000000..8a866b64 --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/global/exception/user/UserError.java @@ -0,0 +1,14 @@ +package com.keepgoing.keepserver.global.exception.user; + +import com.keepgoing.keepserver.global.exception.error.ErrorProperty; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpStatus; + +@Getter +@RequiredArgsConstructor +public enum UserError implements ErrorProperty { + USER_NOT_TEACHER(HttpStatus.BAD_REQUEST, "선생님이 아닙니다."); + private final HttpStatus status; + private final String message; +} diff --git a/src/main/java/com/keepgoing/keepserver/global/exception/user/UserException.java b/src/main/java/com/keepgoing/keepserver/global/exception/user/UserException.java new file mode 100644 index 00000000..c4a7200d --- /dev/null +++ b/src/main/java/com/keepgoing/keepserver/global/exception/user/UserException.java @@ -0,0 +1,16 @@ +package com.keepgoing.keepserver.global.exception.user; + +import com.keepgoing.keepserver.global.exception.BusinessException; +import com.keepgoing.keepserver.global.exception.error.ErrorProperty; + +public class UserException extends BusinessException { + private static final UserException USER_NOT_TEACHER = new UserException(UserError.USER_NOT_TEACHER); + + public UserException(ErrorProperty error) { + super(error); + } + + public static UserException userNotTeacher() { + return USER_NOT_TEACHER; + } +} From a1c655dcb64a168a47b01a3d0a7564ce14815e2b Mon Sep 17 00:00:00 2001 From: priverg163 Date: Thu, 19 Sep 2024 17:26:36 +0900 Subject: [PATCH 33/34] Refactor :: remove unused errorCode in NoticeException --- .../keepserver/global/exception/notice/NoticeError.java | 2 -- .../keepserver/global/exception/notice/NoticeException.java | 6 ------ 2 files changed, 8 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeError.java b/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeError.java index bd6551c9..e6de885c 100644 --- a/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeError.java +++ b/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeError.java @@ -8,10 +8,8 @@ @Getter @RequiredArgsConstructor public enum NoticeError implements ErrorProperty { - USER_NOT_TEACHER(HttpStatus.BAD_REQUEST, "선생님이 아닙니다."), USER_CANNOT_DELETE(HttpStatus.BAD_REQUEST, "본인 글이 아닙니다."); - private final HttpStatus status; private final String message; } diff --git a/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeException.java b/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeException.java index 5fb8fb73..c6949a14 100644 --- a/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeException.java +++ b/src/main/java/com/keepgoing/keepserver/global/exception/notice/NoticeException.java @@ -4,18 +4,12 @@ import com.keepgoing.keepserver.global.exception.BusinessException; public class NoticeException extends BusinessException { - private static final NoticeException USER_NOT_TEACHER = new NoticeException(NoticeError.USER_NOT_TEACHER); private static final NoticeException USER_CANNOT_DELETE = new NoticeException(NoticeError.USER_CANNOT_DELETE); - public NoticeException(NoticeError error) { super(error); } - public static NoticeException userNotTeacher(){ - return USER_NOT_TEACHER; - } - public static NoticeException userCannotDelete(){ return USER_CANNOT_DELETE; } From 69e18737bedbb23e6704cd85f8bc6969b5fae62e Mon Sep 17 00:00:00 2001 From: priverg163 Date: Thu, 19 Sep 2024 17:28:37 +0900 Subject: [PATCH 34/34] Add :: exception handling for non-teacher users in method --- .../domain/device/service/DeviceServiceImpl.java | 5 ++++- .../domain/repository/user/UserRepository.java | 2 +- .../domain/user/service/user/UserServiceImpl.java | 15 ++++++++++----- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/src/main/java/com/keepgoing/keepserver/domain/device/service/DeviceServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/device/service/DeviceServiceImpl.java index e19749a3..e3018c2f 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/device/service/DeviceServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/device/service/DeviceServiceImpl.java @@ -11,6 +11,8 @@ import com.keepgoing.keepserver.global.common.BaseResponse; import com.keepgoing.keepserver.global.exception.device.DeviceError; import com.keepgoing.keepserver.global.exception.device.DeviceException; +import com.keepgoing.keepserver.global.exception.user.UserError; +import com.keepgoing.keepserver.global.exception.user.UserException; import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Sort; import org.springframework.http.HttpStatus; @@ -48,7 +50,8 @@ public BaseResponse deviceRead(Long id) { @Override public BaseResponse deleteDevice(Long id, Authentication authentication) { User user = findUserByEmail(authentication.getName()); - userRepository.findByIdAndTeacherIsTrue(user.getId()); + userRepository.findByIdAndTeacherIsTrue(user.getId()) + .orElseThrow(() -> new UserException(UserError.USER_NOT_TEACHER)); deleteDeviceById(id); return new BaseResponse(HttpStatus.OK, "기기 삭제 성공"); } diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserRepository.java b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserRepository.java index f8551d50..c3a76760 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserRepository.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/domain/repository/user/UserRepository.java @@ -14,5 +14,5 @@ public interface UserRepository extends JpaRepository, UserQueryRepo Optional findByEmailEquals(String email); List findUsersByIdIn(List ids); List findUsersByTeacherIs(boolean isTeacher); - User findByIdAndTeacherIsTrue(Long id); + Optional findByIdAndTeacherIsTrue(Long id); } \ No newline at end of file diff --git a/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserServiceImpl.java b/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserServiceImpl.java index a63738cb..e667d1fb 100644 --- a/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserServiceImpl.java +++ b/src/main/java/com/keepgoing/keepserver/domain/user/service/user/UserServiceImpl.java @@ -13,6 +13,8 @@ import com.keepgoing.keepserver.global.exception.BusinessException; import com.keepgoing.keepserver.global.exception.device.DeviceException; import com.keepgoing.keepserver.global.exception.error.ErrorCode; +import com.keepgoing.keepserver.global.exception.user.UserError; +import com.keepgoing.keepserver.global.exception.user.UserException; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.AuthenticationManager; @@ -63,6 +65,14 @@ public UserNoticesDto getNoticeByUser(Authentication authentication) { return userRepository.getNoticesById(ud.getId()); } + @Override + public User getTeacher(Authentication authentication) { + var ud = (UserDetailsImpl) authentication.getPrincipal(); + + return userRepository.findByIdAndTeacherIsTrue(ud.getId()) + .orElseThrow(() -> new UserException(UserError.USER_NOT_TEACHER)); + } + /* 인증 및 JWT 토큰 생성 */ public JwtResponse authenticateAndGenerateJWT(String email, String password) { Authentication authentication = authenticationManager.authenticate( @@ -106,9 +116,4 @@ private User findUserByEmail(String email) { private void updateUser(User user, UserInfoRequest request) { user.fixUserData(request.getEmail(), request.getName()); } - - public User getTeacher(Authentication authentication) { - var ud = (UserDetailsImpl) authentication.getPrincipal(); - return userRepository.findByIdAndTeacherIsTrue(ud.getId()); - } }