diff --git a/src/main/java/com/neighbors/tohero/application/baseResponse/BaseResponseMessage.java b/src/main/java/com/neighbors/tohero/application/baseResponse/BaseResponseMessage.java index bf8802f..a838556 100644 --- a/src/main/java/com/neighbors/tohero/application/baseResponse/BaseResponseMessage.java +++ b/src/main/java/com/neighbors/tohero/application/baseResponse/BaseResponseMessage.java @@ -25,6 +25,8 @@ public enum BaseResponseMessage { 이메일_형식이_올바르지_못합니다("이메일 형식이 올바르지 못합니다"), 유저가_성공적으로_인증되었습니다("유저가 성공적으로 인증되었습니다"), GUEST_유저_토큰이_정상적으로_생성되었습니다("GUEST 유저 토큰이 정상적으로 생성되었습니다"), + 로그아웃이_성공적으로_실행되었습니다("로그아웃이 성공적으로 실행되었습니다"), + 성공적으로_탈퇴했습니다("성공적으로 탈퇴했습니다"), //jwt error message JWT_토큰_오류입니다("JWT 토큰 오류입니다"), @@ -43,7 +45,13 @@ public enum BaseResponseMessage { //letter 편지가_성공적으로_생성_되었습니다("편지가 성공적으로 생성 되었습니다"), - 편지_생성이_실패_했습니다("편지 생성이 실패했습니다"); + 편지_생성이_실패_했습니다("편지 생성이 실패했습니다"), + 편지가_성공적으로_조회되었습니다("편지가 성공적으로 조회되었습니다"), + 일치하는_편지가_없습니다("일치하는 편지가 없습니다"), + + //news + 뉴스_조회가_성공했습니다("뉴스 조회가 성공했습니다"), + 뉴스_조회가_실패했습니다("뉴스 조회가 실패했습니다"); private final String message; diff --git a/src/main/java/com/neighbors/tohero/application/letter/dto/GetLetterDetailRequest.java b/src/main/java/com/neighbors/tohero/application/letter/dto/GetLetterDetailRequest.java new file mode 100644 index 0000000..f96044d --- /dev/null +++ b/src/main/java/com/neighbors/tohero/application/letter/dto/GetLetterDetailRequest.java @@ -0,0 +1,9 @@ +package com.neighbors.tohero.application.letter.dto; + +import jakarta.validation.constraints.NotNull; + +public record GetLetterDetailRequest( + @NotNull + long letterId +) { +} diff --git a/src/main/java/com/neighbors/tohero/application/letter/dto/GetLetterDetailResponse.java b/src/main/java/com/neighbors/tohero/application/letter/dto/GetLetterDetailResponse.java new file mode 100644 index 0000000..cfe3197 --- /dev/null +++ b/src/main/java/com/neighbors/tohero/application/letter/dto/GetLetterDetailResponse.java @@ -0,0 +1,18 @@ +package com.neighbors.tohero.application.letter.dto; + +import com.neighbors.tohero.domain.domain.mainPage.model.Letter; + +public record GetLetterDetailResponse( + LetterInfo letterInfo +) { + public record LetterInfo( + long letterId, + String content, + String from, + String to + ){} + + public static GetLetterDetailResponse from(Letter letter) { + return new GetLetterDetailResponse(new LetterInfo(letter.getLetterId(), letter.getLetterContent(), letter.getWriter(), letter.getTargetName())); + } +} diff --git a/src/main/java/com/neighbors/tohero/application/letter/service/LetterService.java b/src/main/java/com/neighbors/tohero/application/letter/service/LetterService.java index 1fdf98c..3901e66 100644 --- a/src/main/java/com/neighbors/tohero/application/letter/service/LetterService.java +++ b/src/main/java/com/neighbors/tohero/application/letter/service/LetterService.java @@ -5,12 +5,16 @@ import com.neighbors.tohero.application.baseResponse.BaseResponseStatus; import com.neighbors.tohero.application.letter.dto.CreateLetterRequest; import com.neighbors.tohero.application.letter.dto.CreateLetterResponse; +import com.neighbors.tohero.application.letter.dto.GetLetterDetailRequest; +import com.neighbors.tohero.application.letter.dto.GetLetterDetailResponse; import com.neighbors.tohero.common.enums.Role; import com.neighbors.tohero.common.exception.address.AddressException; import com.neighbors.tohero.common.exception.letter.LetterException; import com.neighbors.tohero.common.jwt.JwtUserDetails; import com.neighbors.tohero.domain.domain.address.service.GetAddress; import com.neighbors.tohero.domain.domain.letter.service.CreateLetter; +import com.neighbors.tohero.domain.domain.mainPage.model.Letter; +import com.neighbors.tohero.domain.domain.mainPage.service.GetLetter; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -22,6 +26,7 @@ public class LetterService { private final CreateLetter createLetter; + private final GetLetter getLetter; private final GetAddress getAddress; public BaseResponse createLetter(final JwtUserDetails jwtUserDetail, final CreateLetterRequest createLetterRequest) { @@ -46,6 +51,16 @@ public BaseResponse createLetter(final JwtUserDetails jwtU ); } + public BaseResponse getLetterDetail(GetLetterDetailRequest getLetterDetailRequest){ + Letter matchedLetter = getLetter.getLetterById(getLetterDetailRequest.letterId()); + + return new BaseResponse<>( + BaseResponseStatus.OK, + BaseResponseMessage.편지가_성공적으로_조회되었습니다.getMessage(), + GetLetterDetailResponse.from(matchedLetter) + ); + } + private BaseResponse createGuestLetter(final String nickname, final CreateLetterRequest createLetterRequest) { long createdLetterId = createLetter.createGuestLetter( nickname, diff --git a/src/main/java/com/neighbors/tohero/application/news/dto/GetPagedNewsResponse.java b/src/main/java/com/neighbors/tohero/application/news/dto/GetPagedNewsResponse.java new file mode 100644 index 0000000..07d9fe0 --- /dev/null +++ b/src/main/java/com/neighbors/tohero/application/news/dto/GetPagedNewsResponse.java @@ -0,0 +1,26 @@ +package com.neighbors.tohero.application.news.dto; + +import com.neighbors.tohero.domain.domain.news.model.News; + +import java.util.List; + +public record GetPagedNewsResponse( + List newsInfos +) { + public record NewsInfo( + long newsId, + String title, + String content + ){ + public static NewsInfo from(News news){ + return new NewsInfo(news.getNewsId(), news.getTitle(), news.getContent()); + } + } + + public static GetPagedNewsResponse from(List newsInfos) { + List newsInfoList = newsInfos.stream() + .map(NewsInfo::from) + .toList(); + return new GetPagedNewsResponse(newsInfoList); + } +} diff --git a/src/main/java/com/neighbors/tohero/application/news/service/NewsService.java b/src/main/java/com/neighbors/tohero/application/news/service/NewsService.java new file mode 100644 index 0000000..a2d6cbe --- /dev/null +++ b/src/main/java/com/neighbors/tohero/application/news/service/NewsService.java @@ -0,0 +1,30 @@ +package com.neighbors.tohero.application.news.service; + +import com.neighbors.tohero.application.baseResponse.BaseResponse; +import com.neighbors.tohero.application.baseResponse.BaseResponseMessage; +import com.neighbors.tohero.application.baseResponse.BaseResponseStatus; +import com.neighbors.tohero.application.news.dto.GetPagedNewsResponse; +import com.neighbors.tohero.domain.domain.news.model.News; +import com.neighbors.tohero.domain.domain.news.service.GetNews; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class NewsService { + + private final GetNews getNews; + + public BaseResponse getPagedNews(Pageable pageable){ + List news = getNews.getPagedNews(pageable); + + return new BaseResponse<>( + BaseResponseStatus.OK, + BaseResponseMessage.뉴스_조회가_성공했습니다.getMessage(), + GetPagedNewsResponse.from(news) + ); + } +} diff --git a/src/main/java/com/neighbors/tohero/application/user/service/UserService.java b/src/main/java/com/neighbors/tohero/application/user/service/UserService.java index 5cf626e..3ff2cc9 100644 --- a/src/main/java/com/neighbors/tohero/application/user/service/UserService.java +++ b/src/main/java/com/neighbors/tohero/application/user/service/UserService.java @@ -11,7 +11,9 @@ import com.neighbors.tohero.common.jwt.JwtUserDetails; import com.neighbors.tohero.domain.domain.user.model.User; import com.neighbors.tohero.domain.domain.user.service.CreateUser; +import com.neighbors.tohero.domain.domain.user.service.DeleteUser; import com.neighbors.tohero.domain.domain.user.service.UpdateUser; +import jakarta.servlet.http.HttpSession; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; @@ -21,6 +23,7 @@ public class UserService { private final UpdateUser updateUser; private final CreateUser createUser; + private final DeleteUser deleteUser; private final JwtProvider jwtProvider; public BaseResponse updateUserName(long userId, String nickname){ @@ -39,6 +42,26 @@ public BaseResponse authenticateUser(AuthenticateUserR return returnGuestUserToken(authenticateUserRequest); } + public BaseResponse logout(HttpSession httpSession){ + //todo : Redis record 삭제 + httpSession.invalidate(); + return new BaseResponse<>( + BaseResponseStatus.OK, + BaseResponseMessage.로그아웃이_성공적으로_실행되었습니다.getMessage() + ); + } + + public BaseResponse signout(JwtUserDetails jwtUserDetails, HttpSession httpSession){ + httpSession.invalidate(); + + deleteUser.signout(jwtUserDetails.getUserId()); + + return new BaseResponse<>( + BaseResponseStatus.OK, + BaseResponseMessage.성공적으로_탈퇴했습니다.getMessage() + ); + } + private BaseResponse returnLoginedUserToken(AuthenticateUserRequest authenticateUserRequest) { User createdUser = createUser.createUser(User.toEntity(authenticateUserRequest)); AuthTokens authTokens = jwtProvider.createToken(JwtUserDetails.from(createdUser)); diff --git a/src/main/java/com/neighbors/tohero/common/config/SecurityConfig.java b/src/main/java/com/neighbors/tohero/common/config/SecurityConfig.java index 276f762..904afd1 100644 --- a/src/main/java/com/neighbors/tohero/common/config/SecurityConfig.java +++ b/src/main/java/com/neighbors/tohero/common/config/SecurityConfig.java @@ -46,7 +46,9 @@ public WebSecurityCustomizer webSecurityCustomizer() { "/auth/refreshToken", "/address", "/notice/**", - "/mainPage/**" + "/mainPage/**", + "/letter/detail", + "/news" ); } @@ -64,7 +66,10 @@ SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { { exception.authenticationEntryPoint(customJwtAuthenticationEntryPoint); exception.accessDeniedHandler(customAccessDeniedHandler); - }); + }) + .authorizeHttpRequests(auth -> auth + .anyRequest().authenticated() + ); return http.build(); } diff --git a/src/main/java/com/neighbors/tohero/common/exception/address/AddressException.java b/src/main/java/com/neighbors/tohero/common/exception/address/AddressException.java index 3a9c034..4c09642 100644 --- a/src/main/java/com/neighbors/tohero/common/exception/address/AddressException.java +++ b/src/main/java/com/neighbors/tohero/common/exception/address/AddressException.java @@ -1,7 +1,9 @@ package com.neighbors.tohero.common.exception.address; import com.neighbors.tohero.application.baseResponse.BaseResponseStatus; +import lombok.Getter; +@Getter public class AddressException extends RuntimeException{ private final BaseResponseStatus status; private final String message; diff --git a/src/main/java/com/neighbors/tohero/common/exception/letter/LetterException.java b/src/main/java/com/neighbors/tohero/common/exception/letter/LetterException.java index 061397f..503db16 100644 --- a/src/main/java/com/neighbors/tohero/common/exception/letter/LetterException.java +++ b/src/main/java/com/neighbors/tohero/common/exception/letter/LetterException.java @@ -1,7 +1,9 @@ package com.neighbors.tohero.common.exception.letter; import com.neighbors.tohero.application.baseResponse.BaseResponseStatus; +import lombok.Getter; +@Getter public class LetterException extends RuntimeException { private final BaseResponseStatus status; diff --git a/src/main/java/com/neighbors/tohero/common/exception/news/NewsException.java b/src/main/java/com/neighbors/tohero/common/exception/news/NewsException.java new file mode 100644 index 0000000..5dfb009 --- /dev/null +++ b/src/main/java/com/neighbors/tohero/common/exception/news/NewsException.java @@ -0,0 +1,17 @@ +package com.neighbors.tohero.common.exception.news; + +import com.neighbors.tohero.application.baseResponse.BaseResponseStatus; +import lombok.Getter; + +@Getter +public class NewsException extends RuntimeException { + + private final BaseResponseStatus status; + private final String message; + + public NewsException(BaseResponseStatus status, String message) { + super(message); + this.status = status; + this.message = message; + } +} diff --git a/src/main/java/com/neighbors/tohero/common/exception/notice/NoticeException.java b/src/main/java/com/neighbors/tohero/common/exception/notice/NoticeException.java index c32cfdd..d7ae867 100644 --- a/src/main/java/com/neighbors/tohero/common/exception/notice/NoticeException.java +++ b/src/main/java/com/neighbors/tohero/common/exception/notice/NoticeException.java @@ -1,7 +1,9 @@ package com.neighbors.tohero.common.exception.notice; import com.neighbors.tohero.application.baseResponse.BaseResponseStatus; +import lombok.Getter; +@Getter public class NoticeException extends RuntimeException { private final BaseResponseStatus status; diff --git a/src/main/java/com/neighbors/tohero/domain/domain/mainPage/service/GetLetter.java b/src/main/java/com/neighbors/tohero/domain/domain/mainPage/service/GetLetter.java index d82310d..4a31fa5 100644 --- a/src/main/java/com/neighbors/tohero/domain/domain/mainPage/service/GetLetter.java +++ b/src/main/java/com/neighbors/tohero/domain/domain/mainPage/service/GetLetter.java @@ -21,4 +21,8 @@ public long getTotalLetterNumber(){ public List getPageableLetter(Pageable pageable){ return letterRepository.getPageableLetter(pageable); } + + public Letter getLetterById(long letterId){ + return letterRepository.getLetter(repo -> repo.findByIdAndPublic(letterId)); + } } diff --git a/src/main/java/com/neighbors/tohero/domain/domain/news/model/News.java b/src/main/java/com/neighbors/tohero/domain/domain/news/model/News.java new file mode 100644 index 0000000..da0dce9 --- /dev/null +++ b/src/main/java/com/neighbors/tohero/domain/domain/news/model/News.java @@ -0,0 +1,16 @@ +package com.neighbors.tohero.domain.domain.news.model; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class News { + private long newsId; + private String title; + private String content; + + public static News of(long newsId, String title, String content) { + return new News(newsId, title, content); + } +} diff --git a/src/main/java/com/neighbors/tohero/domain/domain/news/service/GetNews.java b/src/main/java/com/neighbors/tohero/domain/domain/news/service/GetNews.java new file mode 100644 index 0000000..bd0ba71 --- /dev/null +++ b/src/main/java/com/neighbors/tohero/domain/domain/news/service/GetNews.java @@ -0,0 +1,20 @@ +package com.neighbors.tohero.domain.domain.news.service; + +import com.neighbors.tohero.common.annotaion.DomainService; +import com.neighbors.tohero.domain.domain.news.model.News; +import com.neighbors.tohero.domain.query.NewsRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +@DomainService +@RequiredArgsConstructor +public class GetNews { + + private final NewsRepository newsRepository; + + public List getPagedNews(Pageable pageable){ + return newsRepository.getNewsList(repo -> repo.findAllByPagable(pageable)); + } +} diff --git a/src/main/java/com/neighbors/tohero/domain/domain/user/service/DeleteUser.java b/src/main/java/com/neighbors/tohero/domain/domain/user/service/DeleteUser.java new file mode 100644 index 0000000..30c4bc5 --- /dev/null +++ b/src/main/java/com/neighbors/tohero/domain/domain/user/service/DeleteUser.java @@ -0,0 +1,19 @@ +package com.neighbors.tohero.domain.domain.user.service; + +import com.neighbors.tohero.common.annotaion.DomainService; +import com.neighbors.tohero.domain.query.LetterRepository; +import com.neighbors.tohero.domain.query.UserRepository; +import lombok.RequiredArgsConstructor; + +@DomainService +@RequiredArgsConstructor +public class DeleteUser { + + private final UserRepository userRepository; + private final LetterRepository letterRepository; + + public void signout(long userId){ + letterRepository.remainLetterWithoutUser(userId); + userRepository.deleteUser(repo -> repo.deleteById(userId)); + } +} diff --git a/src/main/java/com/neighbors/tohero/domain/query/LetterRepository.java b/src/main/java/com/neighbors/tohero/domain/query/LetterRepository.java index 9694185..b035974 100644 --- a/src/main/java/com/neighbors/tohero/domain/query/LetterRepository.java +++ b/src/main/java/com/neighbors/tohero/domain/query/LetterRepository.java @@ -1,13 +1,19 @@ package com.neighbors.tohero.domain.query; import com.neighbors.tohero.domain.domain.mainPage.model.Letter; +import com.neighbors.tohero.infrastructure.entity.LetterEntity; +import com.neighbors.tohero.infrastructure.repository.LetterEntityRepository; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Repository; import java.util.List; +import java.util.Optional; +import java.util.function.Function; public interface LetterRepository { long getTotalLetterNumber(); List getPageableLetter(Pageable pageable); Letter createLetter(Letter letter); + void remainLetterWithoutUser(long userId); + Letter getLetter(Function> function); } diff --git a/src/main/java/com/neighbors/tohero/domain/query/NewsRepository.java b/src/main/java/com/neighbors/tohero/domain/query/NewsRepository.java new file mode 100644 index 0000000..292f372 --- /dev/null +++ b/src/main/java/com/neighbors/tohero/domain/query/NewsRepository.java @@ -0,0 +1,13 @@ +package com.neighbors.tohero.domain.query; + +import com.neighbors.tohero.domain.domain.news.model.News; +import com.neighbors.tohero.infrastructure.entity.NewsEntity; +import com.neighbors.tohero.infrastructure.repository.NewsEntityRepository; + +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +public interface NewsRepository { + public List getNewsList(Function>> function); +} diff --git a/src/main/java/com/neighbors/tohero/domain/query/UserRepository.java b/src/main/java/com/neighbors/tohero/domain/query/UserRepository.java index eb02c8c..9e767e7 100644 --- a/src/main/java/com/neighbors/tohero/domain/query/UserRepository.java +++ b/src/main/java/com/neighbors/tohero/domain/query/UserRepository.java @@ -5,10 +5,12 @@ import com.neighbors.tohero.infrastructure.repository.UserEntityRepository; import java.util.Optional; +import java.util.function.Consumer; import java.util.function.Function; public interface UserRepository { User createUser(User user); User updateUserName(Function> findUserFunction, String nickname); User getUser(Function> findUserFunction); + void deleteUser(Consumer findUserConsumer); } diff --git a/src/main/java/com/neighbors/tohero/infrastructure/entity/LetterEntity.java b/src/main/java/com/neighbors/tohero/infrastructure/entity/LetterEntity.java index 54b672d..17becb6 100644 --- a/src/main/java/com/neighbors/tohero/infrastructure/entity/LetterEntity.java +++ b/src/main/java/com/neighbors/tohero/infrastructure/entity/LetterEntity.java @@ -45,4 +45,9 @@ public class LetterEntity extends BaseEntity { @Column(name = "reading_alarm") private Boolean readingAlarm; + + public void remainLetterWithoutUser(){ + this.user = null; + this.isPublic = false; + } } diff --git a/src/main/java/com/neighbors/tohero/infrastructure/entity/NewsEntity.java b/src/main/java/com/neighbors/tohero/infrastructure/entity/NewsEntity.java new file mode 100644 index 0000000..2e7370e --- /dev/null +++ b/src/main/java/com/neighbors/tohero/infrastructure/entity/NewsEntity.java @@ -0,0 +1,21 @@ +package com.neighbors.tohero.infrastructure.entity; + +import com.neighbors.tohero.infrastructure.entity.base.BaseEntity; +import jakarta.persistence.*; +import lombok.Getter; + +@Entity +@Table(name = "`News`") +@Getter +public class NewsEntity extends BaseEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "news_id") + long newsId; + + @Column(name = "news_title") + String newsTitle; + + @Column(name = "news_content") + String newsContent; +} diff --git a/src/main/java/com/neighbors/tohero/infrastructure/mapper/NewsMapper.java b/src/main/java/com/neighbors/tohero/infrastructure/mapper/NewsMapper.java new file mode 100644 index 0000000..a4c065c --- /dev/null +++ b/src/main/java/com/neighbors/tohero/infrastructure/mapper/NewsMapper.java @@ -0,0 +1,13 @@ +package com.neighbors.tohero.infrastructure.mapper; + +import com.neighbors.tohero.domain.domain.news.model.News; +import com.neighbors.tohero.infrastructure.entity.NewsEntity; +import org.springframework.stereotype.Component; + +@Component +public class NewsMapper { + + public News toDomain(NewsEntity newsEntity) { + return News.of(newsEntity.getNewsId(), newsEntity.getNewsTitle(), newsEntity.getNewsContent()); + } +} diff --git a/src/main/java/com/neighbors/tohero/infrastructure/query/impl/LetterRepositoryImpl.java b/src/main/java/com/neighbors/tohero/infrastructure/query/impl/LetterRepositoryImpl.java index 912bd49..a85ee0c 100644 --- a/src/main/java/com/neighbors/tohero/infrastructure/query/impl/LetterRepositoryImpl.java +++ b/src/main/java/com/neighbors/tohero/infrastructure/query/impl/LetterRepositoryImpl.java @@ -1,5 +1,8 @@ package com.neighbors.tohero.infrastructure.query.impl; +import com.neighbors.tohero.application.baseResponse.BaseResponseMessage; +import com.neighbors.tohero.application.baseResponse.BaseResponseStatus; +import com.neighbors.tohero.common.exception.letter.LetterException; import com.neighbors.tohero.domain.domain.mainPage.model.Letter; import com.neighbors.tohero.domain.query.LetterRepository; import com.neighbors.tohero.infrastructure.entity.LetterEntity; @@ -10,6 +13,8 @@ import org.springframework.stereotype.Repository; import java.util.List; +import java.util.Optional; +import java.util.function.Function; @Repository @RequiredArgsConstructor @@ -38,4 +43,24 @@ public Letter createLetter(Letter letter) { LetterEntity createdLetterEntity = letterEntityRepository.save(newLetterEntity); return letterMapper.toDomain(createdLetterEntity); } + + @Override + public void remainLetterWithoutUser(long userId) { + letterEntityRepository.findAllByUserId(userId) + .forEach(letter -> { + letter.remainLetterWithoutUser(); + letterEntityRepository.save(letter); + }); + } + + @Override + public Letter getLetter(Function> function) { + LetterEntity letterEntity = function.apply(letterEntityRepository) + .orElseThrow(()-> new LetterException( + BaseResponseStatus.NO_RESULT, + BaseResponseMessage.일치하는_편지가_없습니다.getMessage() + )); + + return letterMapper.toDomain(letterEntity); + } } diff --git a/src/main/java/com/neighbors/tohero/infrastructure/query/impl/NewsRepositoryImpl.java b/src/main/java/com/neighbors/tohero/infrastructure/query/impl/NewsRepositoryImpl.java new file mode 100644 index 0000000..2ba03af --- /dev/null +++ b/src/main/java/com/neighbors/tohero/infrastructure/query/impl/NewsRepositoryImpl.java @@ -0,0 +1,38 @@ +package com.neighbors.tohero.infrastructure.query.impl; + +import com.neighbors.tohero.application.baseResponse.BaseResponseMessage; +import com.neighbors.tohero.application.baseResponse.BaseResponseStatus; +import com.neighbors.tohero.common.exception.news.NewsException; +import com.neighbors.tohero.domain.domain.news.model.News; +import com.neighbors.tohero.domain.query.NewsRepository; +import com.neighbors.tohero.infrastructure.entity.NewsEntity; +import com.neighbors.tohero.infrastructure.mapper.NewsMapper; +import com.neighbors.tohero.infrastructure.repository.NewsEntityRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Repository; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +@Repository +@RequiredArgsConstructor +public class NewsRepositoryImpl implements NewsRepository { + + private final NewsEntityRepository newsEntityRepository; + private final NewsMapper newsMapper; + + @Override + public List getNewsList(Function>> function) { + List newsEntities = function.apply(newsEntityRepository) + .orElseThrow(()-> new NewsException( + BaseResponseStatus.NO_RESULT, + BaseResponseMessage.뉴스_조회가_실패했습니다.getMessage() + )); + + return newsEntities.stream() + .map(newsMapper::toDomain) + .toList(); + } +} diff --git a/src/main/java/com/neighbors/tohero/infrastructure/query/impl/UserRepositoryImpl.java b/src/main/java/com/neighbors/tohero/infrastructure/query/impl/UserRepositoryImpl.java index 8b98412..4256d4f 100644 --- a/src/main/java/com/neighbors/tohero/infrastructure/query/impl/UserRepositoryImpl.java +++ b/src/main/java/com/neighbors/tohero/infrastructure/query/impl/UserRepositoryImpl.java @@ -12,6 +12,7 @@ import org.springframework.stereotype.Repository; import java.util.Optional; +import java.util.function.Consumer; import java.util.function.Function; @Repository @@ -61,4 +62,9 @@ public User getUser(Function> findUse return userMapper.toDomain(userEntity); } + + @Override + public void deleteUser(Consumer findUserConsumer) { + findUserConsumer.accept(userEntityRepository); + } } diff --git a/src/main/java/com/neighbors/tohero/infrastructure/repository/LetterEntityRepository.java b/src/main/java/com/neighbors/tohero/infrastructure/repository/LetterEntityRepository.java index 8131bc0..d6caeaa 100644 --- a/src/main/java/com/neighbors/tohero/infrastructure/repository/LetterEntityRepository.java +++ b/src/main/java/com/neighbors/tohero/infrastructure/repository/LetterEntityRepository.java @@ -1,18 +1,28 @@ package com.neighbors.tohero.infrastructure.repository; import com.neighbors.tohero.infrastructure.entity.LetterEntity; +import io.lettuce.core.dynamic.annotation.Param; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.Slice; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.stereotype.Repository; +import java.util.List; +import java.util.Optional; + @Repository public interface LetterEntityRepository extends JpaRepository { - @Query("SELECT n FROM LetterEntity n WHERE n.isPublic = true") + @Query("SELECT le FROM LetterEntity le WHERE le.isPublic = true") Slice findPagedLetterEntity(Pageable pageable); - @Query("SELECT COUNT(n) FROM LetterEntity n WHERE n.isPublic = true") + @Query("SELECT COUNT(le) FROM LetterEntity le WHERE le.isPublic = true") long countPublicLetter(); + + @Query("SELECT le FROM LetterEntity le WHERE le.user.userId = :userId") + List findAllByUserId(@Param("userId") Long userId); + + @Query("SELECT le FROM LetterEntity le WHERE le.letterId = :letterId AND le.isPublic = true") + Optional findByIdAndPublic(@Param("letterId") long letterId); } diff --git a/src/main/java/com/neighbors/tohero/infrastructure/repository/NewsEntityRepository.java b/src/main/java/com/neighbors/tohero/infrastructure/repository/NewsEntityRepository.java new file mode 100644 index 0000000..090f3df --- /dev/null +++ b/src/main/java/com/neighbors/tohero/infrastructure/repository/NewsEntityRepository.java @@ -0,0 +1,14 @@ +package com.neighbors.tohero.infrastructure.repository; + +import com.neighbors.tohero.infrastructure.entity.NewsEntity; +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; +import java.util.Optional; + +public interface NewsEntityRepository extends JpaRepository { + @Query("SELECT ne FROM NewsEntity ne") + Optional> findAllByPagable(Pageable pageable); +} diff --git a/src/main/java/com/neighbors/tohero/presentation/controller/LetterController.java b/src/main/java/com/neighbors/tohero/presentation/controller/LetterController.java index 7a36697..e8c6f92 100644 --- a/src/main/java/com/neighbors/tohero/presentation/controller/LetterController.java +++ b/src/main/java/com/neighbors/tohero/presentation/controller/LetterController.java @@ -2,26 +2,25 @@ import com.neighbors.tohero.application.baseResponse.BaseResponse; import com.neighbors.tohero.application.letter.dto.CreateLetterRequest; +import com.neighbors.tohero.application.letter.dto.GetLetterDetailRequest; import com.neighbors.tohero.application.letter.service.LetterService; import com.neighbors.tohero.common.jwt.JwtUserDetails; import io.swagger.v3.oas.annotations.Parameter; import lombok.RequiredArgsConstructor; +import org.springdoc.core.annotations.ParameterObject; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.validation.annotation.Validated; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController @RequiredArgsConstructor -@RequestMapping("") +@RequestMapping("/letter") public class LetterController { private final LetterService letterService; - @PostMapping("/letter") + @PostMapping("") public ResponseEntity createLetter( @Parameter(hidden=true) @AuthenticationPrincipal JwtUserDetails jwtUserDetail, @RequestBody @Validated CreateLetterRequest createLetterRequest @@ -29,4 +28,10 @@ public ResponseEntity createLetter( return ResponseEntity.ok() .body(letterService.createLetter(jwtUserDetail, createLetterRequest)); } + + @GetMapping("/detail") + public ResponseEntity getLetterDetail(@ParameterObject GetLetterDetailRequest getLetterDetailRequest){ + return ResponseEntity.ok() + .body(letterService.getLetterDetail(getLetterDetailRequest)); + } } diff --git a/src/main/java/com/neighbors/tohero/presentation/controller/NewsController.java b/src/main/java/com/neighbors/tohero/presentation/controller/NewsController.java new file mode 100644 index 0000000..26c0862 --- /dev/null +++ b/src/main/java/com/neighbors/tohero/presentation/controller/NewsController.java @@ -0,0 +1,26 @@ +package com.neighbors.tohero.presentation.controller; + +import com.neighbors.tohero.application.baseResponse.BaseResponse; +import com.neighbors.tohero.application.news.service.NewsService; +import lombok.RequiredArgsConstructor; +import org.springdoc.core.annotations.ParameterObject; +import org.springframework.data.domain.Pageable; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + + +@RestController +@RequiredArgsConstructor +@RequestMapping("/news") +public class NewsController { + + private final NewsService newsService; + + @GetMapping("") + public ResponseEntity getPagedNews(@ParameterObject Pageable pageable){ + return ResponseEntity.ok() + .body(newsService.getPagedNews(pageable)); + } +} diff --git a/src/main/java/com/neighbors/tohero/presentation/controller/UserController.java b/src/main/java/com/neighbors/tohero/presentation/controller/UserController.java index 3907728..a129096 100644 --- a/src/main/java/com/neighbors/tohero/presentation/controller/UserController.java +++ b/src/main/java/com/neighbors/tohero/presentation/controller/UserController.java @@ -7,6 +7,7 @@ import com.neighbors.tohero.common.jwt.JwtUserDetails; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Parameter; +import jakarta.servlet.http.HttpSession; import lombok.RequiredArgsConstructor; import org.springdoc.core.annotations.ParameterObject; import org.springframework.http.ResponseEntity; @@ -37,4 +38,21 @@ public ResponseEntity authenticateUser(@RequestBody @Validated Aut return ResponseEntity.ok() .body(userService.authenticateUser(authenticateUserRequest)); } + + @Operation(summary = "유저 API", description = "사용자 로그아웃 API입니다.") + @PostMapping("/logout") + public ResponseEntity logout(@Parameter(hidden=true) HttpSession httpSession){ + return ResponseEntity.ok() + .body(userService.logout(httpSession)); + } + + @Operation(summary = "유저 API", description = "사용자 탈퇴하기 API입니다.") + @PostMapping("/signout") + public ResponseEntity signout( + @Parameter(hidden=true) @AuthenticationPrincipal JwtUserDetails jwtUserDetail, + @Parameter(hidden=true) HttpSession httpSession + ){ + return ResponseEntity.ok() + .body(userService.signout(jwtUserDetail, httpSession)); + } } diff --git a/src/main/java/com/neighbors/tohero/presentation/exception_handler/AddressExceptionControllerAdvice.java b/src/main/java/com/neighbors/tohero/presentation/exception_handler/AddressExceptionControllerAdvice.java index 3a0c67f..615a08a 100644 --- a/src/main/java/com/neighbors/tohero/presentation/exception_handler/AddressExceptionControllerAdvice.java +++ b/src/main/java/com/neighbors/tohero/presentation/exception_handler/AddressExceptionControllerAdvice.java @@ -16,7 +16,7 @@ public class AddressExceptionControllerAdvice { @ExceptionHandler(AddressException.class) public ResponseEntity handle_NoticeException(AddressException e) { BaseResponse response = new BaseResponse( - BaseResponseStatus.NO_RESULT, + e.getStatus(), e.getMessage() ); diff --git a/src/main/java/com/neighbors/tohero/presentation/exception_handler/LetterExceptionControllerAdvice.java b/src/main/java/com/neighbors/tohero/presentation/exception_handler/LetterExceptionControllerAdvice.java new file mode 100644 index 0000000..ef10e93 --- /dev/null +++ b/src/main/java/com/neighbors/tohero/presentation/exception_handler/LetterExceptionControllerAdvice.java @@ -0,0 +1,26 @@ +package com.neighbors.tohero.presentation.exception_handler; + +import com.neighbors.tohero.application.baseResponse.BaseResponse; +import com.neighbors.tohero.application.baseResponse.BaseResponseStatus; +import com.neighbors.tohero.common.exception.letter.LetterException; +import com.neighbors.tohero.common.exception.notice.NoticeException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class LetterExceptionControllerAdvice { + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(LetterException.class) + public ResponseEntity handle_NoticeException(LetterException e) { + BaseResponse response = new BaseResponse( + e.getStatus(), + e.getMessage() + ); + + return ResponseEntity.badRequest() + .body(response); + } +} diff --git a/src/main/java/com/neighbors/tohero/presentation/exception_handler/NewsExceptionControllerAdvice.java b/src/main/java/com/neighbors/tohero/presentation/exception_handler/NewsExceptionControllerAdvice.java new file mode 100644 index 0000000..4e16c03 --- /dev/null +++ b/src/main/java/com/neighbors/tohero/presentation/exception_handler/NewsExceptionControllerAdvice.java @@ -0,0 +1,25 @@ +package com.neighbors.tohero.presentation.exception_handler; + +import com.neighbors.tohero.application.baseResponse.BaseResponse; +import com.neighbors.tohero.common.exception.letter.LetterException; +import com.neighbors.tohero.common.exception.news.NewsException; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.RestControllerAdvice; + +@RestControllerAdvice +public class NewsExceptionControllerAdvice { + @ResponseStatus(HttpStatus.BAD_REQUEST) + @ExceptionHandler(NewsException.class) + public ResponseEntity handle_NoticeException(NewsException e) { + BaseResponse response = new BaseResponse( + e.getStatus(), + e.getMessage() + ); + + return ResponseEntity.badRequest() + .body(response); + } +} diff --git a/src/main/java/com/neighbors/tohero/presentation/exception_handler/NoticeExceptionControllerAdvice.java b/src/main/java/com/neighbors/tohero/presentation/exception_handler/NoticeExceptionControllerAdvice.java index 397c6e0..4d7f319 100644 --- a/src/main/java/com/neighbors/tohero/presentation/exception_handler/NoticeExceptionControllerAdvice.java +++ b/src/main/java/com/neighbors/tohero/presentation/exception_handler/NoticeExceptionControllerAdvice.java @@ -16,7 +16,7 @@ public class NoticeExceptionControllerAdvice { @ExceptionHandler(NoticeException.class) public ResponseEntity handle_NoticeException(NoticeException e) { BaseResponse response = new BaseResponse( - BaseResponseStatus.NO_RESULT, + e.getStatus(), e.getMessage() );