diff --git a/api-server/src/main/java/com/lastone/apiserver/controller/RecruitmentController.java b/api-server/src/main/java/com/lastone/apiserver/controller/RecruitmentController.java index 35db72a4..8e6673af 100644 --- a/api-server/src/main/java/com/lastone/apiserver/controller/RecruitmentController.java +++ b/api-server/src/main/java/com/lastone/apiserver/controller/RecruitmentController.java @@ -47,6 +47,14 @@ public ResponseEntity getRecruitmentListInMain() { return ResponseEntity.ok().body(CommonResponse.success(SuccessCode.RECRUITMENT_LIST_FOR_MAIN, recruitmentList)); } + @PreAuthorize("isAuthenticated()") + @GetMapping("/{recruitmentId}/application") + public ResponseEntity checkApplyStatusForMember(@PathVariable Long recruitmentId, + @AuthenticationPrincipal UserDetailsImpl userDetails) { + RecruitmentApplyStatusForMember applyStatus = recruitmentService.isAlreadyApplyRecruitment(recruitmentId, userDetails.getId()); + return ResponseEntity.ok().body(CommonResponse.success(SuccessCode.RECRUITMENT_APPLY_STATUS_FOR_MEMBER, applyStatus)); + } + @PreAuthorize("isAuthenticated()") @PostMapping public ResponseEntity createRecruitment(@AuthenticationPrincipal UserDetailsImpl userDetails, diff --git a/api-server/src/main/java/com/lastone/apiserver/oauth2/kakao/KakaoOauth2Service.java b/api-server/src/main/java/com/lastone/apiserver/oauth2/kakao/KakaoOauth2Service.java index 5906339c..e5d9194c 100644 --- a/api-server/src/main/java/com/lastone/apiserver/oauth2/kakao/KakaoOauth2Service.java +++ b/api-server/src/main/java/com/lastone/apiserver/oauth2/kakao/KakaoOauth2Service.java @@ -39,7 +39,8 @@ public TokenResponse createToken(Oauth2LoginRequestDto loginRequestDto, String r String token = getToken(loginRequestDto); KakaoOauth2UserInfo profile = getProfile(token); Optional member = memberRepository.findByEmail(profile.getEmail()); - if(member.isEmpty()) { + boolean isFirstSignUp = false; + if (member.isEmpty()) { Member newMember = Member.builder() .email(profile.getEmail()) .build(); @@ -49,8 +50,12 @@ public TokenResponse createToken(Oauth2LoginRequestDto loginRequestDto, String r Member saveMember = memberRepository.save(newMember); String nickname = "#" + saveMember.getId(); saveMember.initNickname(nickname); + isFirstSignUp = true; } TokenResponse tokens = jwtProvider.createToken(profile.getEmail(), requestURI); + if (isFirstSignUp) { + tokens.setFirstSignUp(); + } redisTemplate.opsForValue() .set("refresh_token:" + profile.getEmail(), tokens.getRefreshToken(), jwtProvider.getRefreshTokenDuration(), TimeUnit.MILLISECONDS); return tokens; diff --git a/api-server/src/main/java/com/lastone/apiserver/service/recruitment/RecruitmentService.java b/api-server/src/main/java/com/lastone/apiserver/service/recruitment/RecruitmentService.java index 4bf666e8..b367b571 100644 --- a/api-server/src/main/java/com/lastone/apiserver/service/recruitment/RecruitmentService.java +++ b/api-server/src/main/java/com/lastone/apiserver/service/recruitment/RecruitmentService.java @@ -1,9 +1,6 @@ package com.lastone.apiserver.service.recruitment; -import com.lastone.core.dto.recruitment.RecruitmentRequestDto; -import com.lastone.core.dto.recruitment.RecruitmentDetailDto; -import com.lastone.core.dto.recruitment.RecruitmentListDto; -import com.lastone.core.dto.recruitment.RecruitmentSearchCondition; +import com.lastone.core.dto.recruitment.*; import org.springframework.data.domain.Slice; import org.springframework.web.multipart.MultipartFile; import java.io.IOException; @@ -22,4 +19,6 @@ public interface RecruitmentService { void updateRecruitment(Long recruitmentId, Long memberId, RecruitmentRequestDto recruitment, List imgFiles) throws IOException; void deleteRecruitment(Long recruitmentId, Long id); + + RecruitmentApplyStatusForMember isAlreadyApplyRecruitment(Long recruitmentId, Long memberId); } diff --git a/api-server/src/main/java/com/lastone/apiserver/service/recruitment/RecruitmentServiceImpl.java b/api-server/src/main/java/com/lastone/apiserver/service/recruitment/RecruitmentServiceImpl.java index 2de9e531..c1ab373f 100644 --- a/api-server/src/main/java/com/lastone/apiserver/service/recruitment/RecruitmentServiceImpl.java +++ b/api-server/src/main/java/com/lastone/apiserver/service/recruitment/RecruitmentServiceImpl.java @@ -13,10 +13,7 @@ import com.lastone.core.domain.recruitment.Recruitment; import com.lastone.core.domain.recruitment_img.RecruitmentImg; import com.lastone.core.dto.gym.GymDto; -import com.lastone.core.dto.recruitment.RecruitmentDetailDto; -import com.lastone.core.dto.recruitment.RecruitmentListDto; -import com.lastone.core.dto.recruitment.RecruitmentRequestDto; -import com.lastone.core.dto.recruitment.RecruitmentSearchCondition; +import com.lastone.core.dto.recruitment.*; import com.lastone.core.util.mapper.GymMapper; import com.lastone.core.repository.gym.GymRepository; import com.lastone.core.repository.member.MemberRepository; @@ -113,6 +110,14 @@ public void deleteRecruitment(Long recruitmentId, Long memberId) { recruitment.delete(); } + @Override + public RecruitmentApplyStatusForMember isAlreadyApplyRecruitment(Long recruitmentId, Long memberId) { + Recruitment recruitment = recruitmentRepository.findById(recruitmentId).orElseThrow(RecruitmentNotFoundException::new); + boolean result = recruitment.getApplications().stream() + .anyMatch(application -> application.getApplicant().getId().equals(memberId)); + return new RecruitmentApplyStatusForMember(result); + } + private void updateImgFiles(Recruitment recruitment, List imgFiles) throws IOException { if (imgFileIsExist(imgFiles)) { return; diff --git a/core/src/main/java/com/lastone/core/common/response/SuccessCode.java b/core/src/main/java/com/lastone/core/common/response/SuccessCode.java index f3f76507..f6e63d89 100644 --- a/core/src/main/java/com/lastone/core/common/response/SuccessCode.java +++ b/core/src/main/java/com/lastone/core/common/response/SuccessCode.java @@ -25,6 +25,7 @@ public enum SuccessCode { RECRUITMENT_CREATE("모집글 작성이 완료되었습니다."), RECRUITMENT_UPDATE("모집글 수정이 완료되었습니다."), RECRUITMENT_DELETE("모집글 삭제가 완료되었습니다."), + RECRUITMENT_APPLY_STATUS_FOR_MEMBER("모집글 신청 여부 조회가 완료되었습니다."), /* 신청 */ APPLICATION_CREATE("신청 처리가 완료되었습니다."), @@ -42,7 +43,7 @@ public enum SuccessCode { NOTIFICATION_LIST("알림 목록 조회가 완료되었습니다."), NOTIFICATION_READ("알림 읽기 처리가 완료되었습니다."), NOTIFICATION_DELETE("알림 삭제 처리가 완료되었습니다."), - ; + ; private String message; diff --git a/core/src/main/java/com/lastone/core/domain/recruitment/PreferGender.java b/core/src/main/java/com/lastone/core/domain/recruitment/PreferGender.java index 5685738e..6768d4b7 100644 --- a/core/src/main/java/com/lastone/core/domain/recruitment/PreferGender.java +++ b/core/src/main/java/com/lastone/core/domain/recruitment/PreferGender.java @@ -6,11 +6,11 @@ public enum PreferGender { - BOTH("무관"), + BOTH("성별무관"), - MALE("남성"), + MALE("남성만"), - FEMALE("여성"); + FEMALE("여성만"); private final String text; diff --git a/core/src/main/java/com/lastone/core/dto/applicaation/ApplicationDto.java b/core/src/main/java/com/lastone/core/dto/applicaation/ApplicationDto.java index 9350f89d..5157e14d 100644 --- a/core/src/main/java/com/lastone/core/dto/applicaation/ApplicationDto.java +++ b/core/src/main/java/com/lastone/core/dto/applicaation/ApplicationDto.java @@ -3,14 +3,18 @@ import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.lastone.core.domain.application.Application; import com.lastone.core.domain.application.ApplicationStatus; -import com.querydsl.core.annotations.QueryProjection; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; import lombok.ToString; import java.time.LocalDateTime; @Getter +@Builder @ToString +@AllArgsConstructor public class ApplicationDto { private final Long applicationId; @@ -26,17 +30,18 @@ public class ApplicationDto { private ApplicationStatus status; @JsonDeserialize(using = LocalDateTimeDeserializer.class) - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy.MM.dd 'T' HH:mm") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy.MM.dd HH:mm") private LocalDateTime applicationDate; - @QueryProjection - public ApplicationDto(Long applicationId, Long applicantId, String nickname, String profileUrl, String gender, ApplicationStatus status, LocalDateTime applicationDate) { - this.applicationId = applicationId; - this.applicantId = applicantId; - this.nickname = nickname; - this.profileUrl = profileUrl; - this.gender = gender; - this.status = status; - this.applicationDate = applicationDate; + public static ApplicationDto toDto(Application application) { + return ApplicationDto.builder() + .applicantId(application.getId()) + .applicantId(application.getApplicant().getId()) + .nickname(application.getApplicant().getNickname()) + .profileUrl(application.getApplicant().getProfileUrl()) + .gender(application.getApplicant().getGender()) + .status(application.getStatus()) + .applicationDate(application.getCreatedAt()) + .build(); } } \ No newline at end of file diff --git a/core/src/main/java/com/lastone/core/dto/applicaation/ApplicationReceivedDto.java b/core/src/main/java/com/lastone/core/dto/applicaation/ApplicationReceivedDto.java index a64ec6bc..d71912b3 100644 --- a/core/src/main/java/com/lastone/core/dto/applicaation/ApplicationReceivedDto.java +++ b/core/src/main/java/com/lastone/core/dto/applicaation/ApplicationReceivedDto.java @@ -3,14 +3,19 @@ import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; -import com.querydsl.core.annotations.QueryProjection; +import com.lastone.core.domain.recruitment.Recruitment; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; import lombok.ToString; import java.time.LocalDateTime; import java.util.List; +import java.util.stream.Collectors; @Getter +@Builder @ToString +@AllArgsConstructor public class ApplicationReceivedDto { private final Long id; @@ -18,22 +23,20 @@ public class ApplicationReceivedDto { private final String title; @JsonDeserialize(using = LocalDateTimeDeserializer.class) - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy.MM.dd 'T' HH:mm") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy.MM.dd HH:mm") private final LocalDateTime startedAt; private final String gym; private List applications; - @QueryProjection - public ApplicationReceivedDto(Long id,String title, LocalDateTime startedAt, String gym) { - this.id = id; - this.title = title; - this.startedAt = startedAt; - this.gym = gym; - } - - public void includeApplicants(List applications) { - this.applications = applications; + public static ApplicationReceivedDto toDto(Recruitment recruitment) { + return ApplicationReceivedDto.builder() + .id(recruitment.getId()) + .title(recruitment.getTitle()) + .startedAt(recruitment.getStartedAt()) + .gym(recruitment.getGym().getName()) + .applications(recruitment.getApplications().stream().map(ApplicationDto::toDto).collect(Collectors.toList())) + .build(); } } diff --git a/core/src/main/java/com/lastone/core/dto/applicaation/ApplicationRequestedDto.java b/core/src/main/java/com/lastone/core/dto/applicaation/ApplicationRequestedDto.java index 601fadb9..3a400d5e 100644 --- a/core/src/main/java/com/lastone/core/dto/applicaation/ApplicationRequestedDto.java +++ b/core/src/main/java/com/lastone/core/dto/applicaation/ApplicationRequestedDto.java @@ -3,15 +3,18 @@ import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer; +import com.lastone.core.domain.application.Application; import com.lastone.core.domain.application.ApplicationStatus; -import com.querydsl.core.annotations.QueryProjection; +import lombok.AllArgsConstructor; +import lombok.Builder; import lombok.Getter; import lombok.ToString; - import java.time.LocalDateTime; @Getter @ToString +@Builder +@AllArgsConstructor public class ApplicationRequestedDto { private final Long applicationId; @@ -23,7 +26,7 @@ public class ApplicationRequestedDto { private final String gym; @JsonDeserialize(using = LocalDateTimeDeserializer.class) - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy.MM.dd 'T' HH:mm") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy.MM.dd HH:mm") private final LocalDateTime startedAt; private final Long memberId; @@ -37,24 +40,22 @@ public class ApplicationRequestedDto { private final ApplicationStatus status; @JsonDeserialize(using = LocalDateTimeDeserializer.class) - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy.MM.dd 'T' HH:mm") - private LocalDateTime applicationDate; - - @QueryProjection - public ApplicationRequestedDto(Long applicationId, Long recruitmentId, String title, String gym, - LocalDateTime startedAt, Long memberId, String profileUrl, - String nickName, String gender, ApplicationStatus status, - LocalDateTime applicationDate) { - this.applicationId = applicationId; - this.recruitmentId = recruitmentId; - this.title = title; - this.gym = gym; - this.startedAt = startedAt; - this.memberId = memberId; - this.profileUrl = profileUrl; - this.nickname = nickName; - this.gender = gender; - this.status = status; - this.applicationDate = applicationDate; + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy.MM.dd HH:mm") + private final LocalDateTime applicationDate; + + public static ApplicationRequestedDto toDto(Application application) { + return ApplicationRequestedDto.builder() + .applicationId(application.getId()) + .status(application.getStatus()) + .applicationDate(application.getCreatedAt()) + .recruitmentId(application.getRecruitment().getId()) + .title(application.getRecruitment().getTitle()) + .gym(application.getRecruitment().getGym().getName()) + .startedAt(application.getRecruitment().getStartedAt()) + .memberId(application.getApplicant().getId()) + .profileUrl(application.getApplicant().getProfileUrl()) + .nickname(application.getApplicant().getNickname()) + .gender(application.getApplicant().getGender()) + .build(); } } \ No newline at end of file diff --git a/core/src/main/java/com/lastone/core/dto/partner/TodayPartnerDto.java b/core/src/main/java/com/lastone/core/dto/partner/TodayPartnerDto.java index cb7fb302..33a03fad 100644 --- a/core/src/main/java/com/lastone/core/dto/partner/TodayPartnerDto.java +++ b/core/src/main/java/com/lastone/core/dto/partner/TodayPartnerDto.java @@ -22,7 +22,7 @@ public class TodayPartnerDto { private WorkoutPart workoutPart; @JsonDeserialize(using = LocalDateTimeDeserializer.class) - @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy.MM.dd 'T' HH:mm") + @JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy.MM.dd HH:mm") private LocalDateTime startedAt; private String gym; diff --git a/core/src/main/java/com/lastone/core/dto/recruitment/RecruitmentApplyStatusForMember.java b/core/src/main/java/com/lastone/core/dto/recruitment/RecruitmentApplyStatusForMember.java new file mode 100644 index 00000000..b51b16c5 --- /dev/null +++ b/core/src/main/java/com/lastone/core/dto/recruitment/RecruitmentApplyStatusForMember.java @@ -0,0 +1,13 @@ +package com.lastone.core.dto.recruitment; + +import lombok.Getter; + +@Getter +public class RecruitmentApplyStatusForMember { + + Boolean isApply; + + public RecruitmentApplyStatusForMember(boolean isApply) { + this.isApply = isApply; + } +} diff --git a/core/src/main/java/com/lastone/core/repository/application/ApplicationRepositoryImpl.java b/core/src/main/java/com/lastone/core/repository/application/ApplicationRepositoryImpl.java index 23ea1377..c2930851 100644 --- a/core/src/main/java/com/lastone/core/repository/application/ApplicationRepositoryImpl.java +++ b/core/src/main/java/com/lastone/core/repository/application/ApplicationRepositoryImpl.java @@ -2,6 +2,7 @@ import com.lastone.core.domain.application.Application; import com.lastone.core.domain.application.ApplicationStatus; +import com.lastone.core.domain.recruitment.Recruitment; import com.lastone.core.domain.recruitment.RecruitmentStatus; import com.lastone.core.dto.applicaation.*; import com.querydsl.jpa.impl.JPAQueryFactory; @@ -10,6 +11,7 @@ import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.stream.Collectors; import static com.lastone.core.domain.application.QApplication.application; import static com.lastone.core.domain.gym.QGym.gym; import static com.lastone.core.domain.member.QMember.member; @@ -29,13 +31,8 @@ public List getReceivedList(Long memberId) { LocalDateTime now = LocalDateTime.now(); - List applicationReceivedDtos = queryFactory - .select(new QApplicationReceivedDto( - recruitment.id, - recruitment.title, - recruitment.startedAt, - gym.name)) - .from(recruitment) + List recruitmentList = queryFactory + .selectFrom(recruitment) .where( recruitment.member.id.eq(memberId), recruitment.isDeleted.eq(false), @@ -45,34 +42,16 @@ public List getReceivedList(Long memberId) { .and(recruitment.startedAt.lt(now.plusDays(ONE_DAY)))), recruitment.startedAt.goe(now) ) - .leftJoin(recruitment.gym, gym) + .leftJoin(recruitment.gym, gym).fetchJoin() + .leftJoin(recruitment.applications, application).fetchJoin() + .leftJoin(application.applicant, member).fetchJoin() .orderBy(recruitment.startedAt.desc()) .fetch(); - List removeList = new ArrayList<>(); - for (ApplicationReceivedDto applicationReceivedDto : applicationReceivedDtos) { - Long recruitmentId = applicationReceivedDto.getId(); - List applicantions = queryFactory - .select(new QApplicationDto( - application.id, - application.applicant.id, - application.applicant.nickname, - application.applicant.profileUrl, - application.applicant.gender, - application.status, - application.createdAt)) - .from(application) - .where(application.recruitment.id.eq(recruitmentId)) - .leftJoin(application.applicant, member) - .orderBy(application.createdAt.desc()) - .fetch(); - if (applicantions.isEmpty()) { - removeList.add(applicationReceivedDto); - } - applicationReceivedDto.includeApplicants(applicantions); - } - applicationReceivedDtos.removeAll(removeList); - return applicationReceivedDtos; + return recruitmentList.stream() + .filter(r -> r.getApplications().size() > 0) + .map(ApplicationReceivedDto::toDto) + .collect(Collectors.toList()); } @Override @@ -80,20 +59,12 @@ public List getRequestedList(Long memberId) { LocalDateTime now = LocalDateTime.now(); - return queryFactory - .select(new QApplicationRequestedDto( - application.id, - application.recruitment.id, - application.recruitment.title, - application.recruitment.gym.name, - application.recruitment.startedAt, - application.recruitment.member.id, - application.recruitment.member.profileUrl, - application.recruitment.member.nickname, - application.recruitment.member.gender, - application.status, - application.createdAt)) - .from(application) + List applicationList = queryFactory + .selectFrom(application) + .leftJoin(application.applicant, member).fetchJoin() + .leftJoin(application.recruitment, recruitment).fetchJoin() + .leftJoin(recruitment.gym, gym).fetchJoin() + .leftJoin(recruitment.member, member).fetchJoin() .where( application.applicant.id.eq(memberId), application.status.eq(ApplicationStatus.WAITING) @@ -102,6 +73,8 @@ public List getRequestedList(Long memberId) { application.recruitment.startedAt.goe(now)) .orderBy(application.createdAt.desc()) .fetch(); + + return applicationList.stream().map(ApplicationRequestedDto::toDto).collect(Collectors.toList()); } @Override diff --git a/core/src/main/java/com/lastone/core/security/jwt/JwtProvider.java b/core/src/main/java/com/lastone/core/security/jwt/JwtProvider.java index d2f37f6e..298bdbda 100644 --- a/core/src/main/java/com/lastone/core/security/jwt/JwtProvider.java +++ b/core/src/main/java/com/lastone/core/security/jwt/JwtProvider.java @@ -58,6 +58,7 @@ public TokenResponse createToken(String email, String requestUri) { return TokenResponse.builder() .accessToken(accessToken) .refreshToken(refreshToken) + .isFirstSignUp(false) .build(); } diff --git a/core/src/main/java/com/lastone/core/security/jwt/TokenResponse.java b/core/src/main/java/com/lastone/core/security/jwt/TokenResponse.java index 5cb48ace..0625fd18 100644 --- a/core/src/main/java/com/lastone/core/security/jwt/TokenResponse.java +++ b/core/src/main/java/com/lastone/core/security/jwt/TokenResponse.java @@ -8,9 +8,16 @@ @Getter @Setter @AllArgsConstructor - @Builder public class TokenResponse { + private String accessToken; + private String refreshToken; + + private Boolean isFirstSignUp; + + public void setFirstSignUp() { + this.isFirstSignUp = true; + } }