Skip to content

Commit

Permalink
feat : 정책 리스트 조회 API 에서 유저가 신청 가능한 정책을 조회하고, 마지막 페이지 인덱스 초과했을 때부터 신청 …
Browse files Browse the repository at this point in the history
…불가능한 정책을 조회 하도록 페이징 기능 구현
  • Loading branch information
LHS-11 committed Feb 10, 2024
1 parent 3e32701 commit fa655f7
Show file tree
Hide file tree
Showing 8 changed files with 276 additions and 390 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;
Expand All @@ -31,17 +30,17 @@ public class PolicyController {
// 정책 리스트 조회 API
@PostMapping
@Operation(summary = "정책 목록 조회 API", description = "정책 목록을 무한 스크롤해서 보여줍니다.")
public CommonResponse<Page<PolicyListResponseDto>> getPolices(@AuthUser User user, @RequestBody PolicyListRequestDto policyListRequestDto, @RequestParam int page, @RequestParam int size, @RequestParam String sortField,
@RequestParam String sortOrder) {
public CommonResponse<Page<PolicyListInfoDto>> getPolices(@AuthUser User user, @RequestBody PolicyListRequestDto policyListRequestDto, @RequestParam int page, @RequestParam int size, @RequestParam String sortField,
@RequestParam String sortOrder) {
Sort sort = Sort.by(Sort.Direction.fromString(sortOrder), sortField);
return CommonResponse.success(policyService.getPolicyList(user, policyListRequestDto, page, size, sort));
}

// 정책 검색 API
@PostMapping("/search")
@Operation(summary = "정책 검색 API", description = "키워드를 사용하여 해당하는 정책 목록을 무한 스크롤해서 보여줍니다.")
public CommonResponse<Slice<PolicyListResponseDto>> getSearchPolices(@AuthUser User user, @RequestBody SearchPolicyListRequestDto policyListRequestDto, @RequestParam int page, @RequestParam int size, @RequestParam String sortField,
@RequestParam String sortOrder) {
public CommonResponse<PolicyListResponseDto> getSearchPolices(@AuthUser User user, @RequestBody SearchPolicyListRequestDto policyListRequestDto, @RequestParam int page, @RequestParam int size, @RequestParam String sortField,
@RequestParam String sortOrder) {
Sort sort = Sort.by(Sort.Direction.fromString(sortOrder), sortField);
return CommonResponse.success(policyService.getSearchPolicyList(user, policyListRequestDto, page, size, sort));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package com.cmc.zenefitserver.domain.policy.application;

import com.cmc.zenefitserver.domain.policy.domain.Policy;
import com.cmc.zenefitserver.domain.policy.domain.enums.AreaCode;
import com.cmc.zenefitserver.domain.policy.domain.enums.DenialReasonType;
import com.cmc.zenefitserver.domain.policy.domain.enums.PolicyDateType;
import com.cmc.zenefitserver.domain.policy.domain.enums.PolicySplzType;
import com.cmc.zenefitserver.domain.user.domain.EducationType;
import com.cmc.zenefitserver.domain.user.domain.Gender;
import com.cmc.zenefitserver.domain.user.domain.JobType;
import com.cmc.zenefitserver.domain.user.domain.User;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.Collections;
import java.util.Set;

@RequiredArgsConstructor
Expand All @@ -23,7 +26,6 @@ public static DenialReasonType getDenialReasonType(User user, Policy policy) {
if (isDateDenial(user, policy)) {
return DenialReasonType.DATE;
}

// 장애인 12
if (isDisabledDenial(user, policy)) {
return DenialReasonType.SPECIAL_CONTENT_DISABLED;
Expand Down Expand Up @@ -75,8 +77,9 @@ private static boolean isDateDenial(User user, Policy policy) {
LocalDate now = LocalDate.now();
// 1. 현재 시각이 신청 시작일보다 이른 경우 or 2. 현재 시각이 신청 종료일보다 늦은 경우
if (policy.getPolicyDateType() != null && policy.getPolicyDateType().equals(PolicyDateType.PERIOD)
&& (policy.getApplyEndDate() != null && now.isAfter(policy.getApplyEndDate()))
|| (policy.getApplySttDate() != null && now.isBefore(policy.getApplySttDate()))) {
&& ((policy.getApplyEndDate() != null && now.isAfter(policy.getApplyEndDate()))
|| (policy.getApplySttDate() != null && now.isBefore(policy.getApplySttDate()))
|| (policy.getApplySttDate() == null && policy.getApplyEndDate() == null))) {
return true;
}
return false;
Expand Down Expand Up @@ -118,16 +121,23 @@ private static boolean isAgeDenial(User user, Policy policy) {
private static boolean isJobDenial(User user, Policy policy) {
Set<JobType> policyJobTypes = policy.getJobTypes();
Set<JobType> userJobTypes = user.getJobs();
userJobTypes.retainAll(policyJobTypes);
return userJobTypes.isEmpty();
userJobTypes.contains(policyJobTypes);
// userJobTypes.retainAll(policyJobTypes);
return Collections.disjoint(userJobTypes, policyJobTypes) && (!(policy.getJobTypes().contains(JobType.UNLIMITED) || policy.getJobTypes() == null));
}

private static boolean isEducationDenial(User user, Policy policy) {
return !policy.getEducationTypes().contains(user.getEducationType());
return !policy.getEducationTypes().contains(user.getEducationType()) && !policy.getEducationTypes().contains(EducationType.UNLIMITED);
}

/**
* 1. 정책의 지역코드가 중앙부처가 아니어야함
* 1-1. 정책의 지역코드와 유저의 지역코드가 틀려야함
* 1-2. 정책의
*/
private static boolean isLocalDenial(User user, Policy policy) {
return user.getAddress().getAreaCode() != policy.getAreaCode()
|| (policy.getCityCode() != null && policy.getCityCode() != user.getAddress().getCityCode());
return !policy.getAreaCode().equals(AreaCode.CENTRAL_GOVERNMENT)
&& (user.getAddress().getAreaCode() != policy.getAreaCode()
|| (policy.getCityCode() != null && policy.getCityCode() != user.getAddress().getCityCode()));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,14 @@ public class PolicyEmpmClassifier {
public Set<JobType> mapToJobTypesFromEmpmContent(String empmContent) {

Set<JobType> empmContentJobTypes = new HashSet<>();
if (empmContent.contains("재직자") || empmContent.contains("사회초년생") || (empmContent.contains("취업자") && empmContent.contains("미취업자")) || empmContent.contains("재직근로자")
|| empmContent.contains("근로/사업소득 월 50만 원 초과~220만 원 이하") || empmContent.contains("취업비자 취득, 단순 노무직종 제외, 연봉 1,700만원 이상, 근로계약기간 1년 이상, 취업 업체(다국적기업 등)")
|| empmContent.contains("중소기업 근로자")) {
empmContentJobTypes.add(JobType.EMPLOYED);
}
if (empmContent.contains("자영업자") || empmContent.contains("소상공인") || empmContent.contains("근로/사업소득 월 50만 원 초과~220만 원 이하")) {
empmContentJobTypes.add(JobType.SELF_EMPLOYED);
}
if (empmContent.contains("재직자") || empmContent.contains("사회초년생") || ((empmContent.contains("취업자") && !empmContent.contains("미취업")) || empmContent.contains("재직근로자")
|| empmContent.contains("근로/사업소득 월 50만 원 초과~220만 원 이하") || empmContent.contains("취업비자 취득, 단순 노무직종 제외, 연봉 1,700만원 이상, 근로계약기간 1년 이상, 취업 업체(다국적기업 등)")
|| empmContent.contains("중소기업 근로자"))) {
empmContentJobTypes.add(JobType.EMPLOYED);
}
if (empmContent.contains("미취업") || empmContent.contains("대학생") || empmContent.contains("취업준비생") || empmContent.contains("청년 구직자") || empmContent.contains("구직단념청년")
|| empmContent.contains("채용예정자") || empmContent.contains("구직급여 수급자") || empmContent.contains("정규직채용일로부터 6개월 이내")
|| empmContent.contains("산업체의 직원으로 소속되어 있지 않은 자")) {
Expand All @@ -33,7 +33,7 @@ public Set<JobType> mapToJobTypesFromEmpmContent(String empmContent) {
if (empmContent.contains("일용근로자")) {
empmContentJobTypes.add(JobType.DAILY_WORKER);
}
if (empmContent.contains("창업자") || empmContent.contains("창업기업") || empmContent.contains("창업") || empmContent.contains("근로/사업소득 월 50만 원 초과~220만 원 이하")) {
if (!empmContent.contains("미창업") && empmContent.contains("창업자") || empmContent.contains("창업기업") || empmContent.contains("창업") || empmContent.contains("근로/사업소득 월 50만 원 초과~220만 원 이하")) {
empmContentJobTypes.add(JobType.ENTREPRENEUR);
}
if (empmContent.contains("단기근로자")) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,28 +16,29 @@
import com.cmc.zenefitserver.global.error.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.*;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class PolicyService {


private final RedisTemplate redisTemplate;
private final PolicyQueryRepository policyQueryRepository;
private final PolicyRepository policyRepository;
private final UserPolicyRepository userPolicyRepository;
private final PolicyRecommender policyRecommender;

// 정책 리스트 조회 비즈니스 로직
public Page<PolicyListResponseDto> getPolicyList(User user, PolicyListRequestDto policyListRequestDto, int page, int size, Sort sort) {
public Page<PolicyListInfoDto> getPolicyList(User user, PolicyListRequestDto policyListRequestDto, int page, int size, Sort sort) {
PageRequest pageable = PageRequest.of(page, size, sort);
return policyQueryRepository.searchByPaging(user, policyListRequestDto.getSupportPolicyType(), policyListRequestDto.getPolicyType(), null, pageable)

return policyQueryRepository.searchByAppliedPaging(user, policyListRequestDto.getSupportPolicyType(), policyListRequestDto.getPolicyType(), null, pageable)
.map(dto -> {
Policy findPolicy = policyRepository.findById(dto.getPolicyId()).get();
DenialReasonType denialReasonType = PolicyDenialReasonClassifier.getDenialReasonType(user, findPolicy);
Expand All @@ -50,18 +51,74 @@ public Page<PolicyListResponseDto> getPolicyList(User user, PolicyListRequestDto
});
}

public Page<PolicyListResponseDto> getSearchPolicyList(User user, SearchPolicyListRequestDto searchPolicyDto, int page, int size, Sort sort) {
PageRequest pageable = PageRequest.of(page, size, sort);
return policyQueryRepository.searchByPaging(user, searchPolicyDto.getSupportPolicyType(), searchPolicyDto.getPolicyType(), searchPolicyDto.getKeyword(), pageable)
public PolicyListResponseDto getSearchPolicyList(User user, SearchPolicyListRequestDto searchPolicyDto, int page, int size, Sort sort) {
PageRequest appliedPageable = PageRequest.of(page, size, sort);

// 유저가 신청 가능한 정책 가져오기
Page<PolicyListInfoDto> appliedPolicyListInfo = policyQueryRepository.searchByAppliedPaging(user, searchPolicyDto.getSupportPolicyType(), searchPolicyDto.getPolicyType(), searchPolicyDto.getKeyword(), appliedPageable)
.map(dto -> {
Policy findPolicy = policyRepository.findById(dto.getPolicyId()).get();
dto.updatePolicyApplyDenialReason(PolicyDenialReasonClassifier.getDenialReasonType(user, findPolicy).getText());
DenialReasonType denialReasonType = PolicyDenialReasonClassifier.getDenialReasonType(user, findPolicy);
dto.updatePolicyApplyDenialReason(denialReasonType != null ? denialReasonType.getText() : null);
dto.updatePolicyDateTypeDescription(dto.getPolicyDateType());
dto.updateAreaCode(dto.getAreaCode());
dto.updateCityCode(dto.getCityCode());
dto.updatePolicyMethodType(dto.getPolicyMethodTypeDescription());
return dto;
});

// 신청할 수 있는 정책 총 페이지
int totalPages = appliedPolicyListInfo.getTotalPages();

// 신청할 수 있는 정책 리스트의 마지막 페이지 일때
if (totalPages - 1 < page) {

List<Long> savedPolicyIds = getPolicyIdsByRedis(user);

//신청 불가능한 정책 가져오기
PageRequest nonAppliedPageable = PageRequest.of(page - totalPages, size, sort);

Page<PolicyListInfoDto> nonAppliedPolicyListInfo = policyQueryRepository.searchByNonAppliedPaging(user, searchPolicyDto.getSupportPolicyType(), searchPolicyDto.getPolicyType(), searchPolicyDto.getKeyword(), nonAppliedPageable, savedPolicyIds)
.map(dto -> {
Policy findPolicy = policyRepository.findById(dto.getPolicyId()).get();
DenialReasonType denialReasonType = PolicyDenialReasonClassifier.getDenialReasonType(user, findPolicy);
dto.updatePolicyApplyDenialReason(denialReasonType != null ? denialReasonType.getText() : null);
dto.updatePolicyDateTypeDescription(dto.getPolicyDateType());
dto.updateAreaCode(dto.getAreaCode());
dto.updateCityCode(dto.getCityCode());
dto.updatePolicyMethodType(dto.getPolicyMethodTypeDescription());
return dto;
});

return PolicyListResponseDto.builder()
.policyListInfoResponseDto(nonAppliedPolicyListInfo)
.pageNumber(page)
.last(nonAppliedPolicyListInfo.isLast())
.build();
} else {
savePolicyIdsToRedis(user, appliedPolicyListInfo);
}

return PolicyListResponseDto.builder()
.policyListInfoResponseDto(appliedPolicyListInfo)
.pageNumber(page)
.last(false)
.build();

}

private void savePolicyIdsToRedis(User user, Page<PolicyListInfoDto> policyListResponseDtos) {
List<Long> policyIds = policyListResponseDtos.stream()
.map(PolicyListInfoDto::getPolicyId)
.collect(Collectors.toList());

redisTemplate.opsForSet().add(String.valueOf(user.getUserId()), policyIds.toArray(new Long[0]));
// redisTemplate.expire(user.getUserId(), 24, TimeUnit.HOURS);
}

private List<Long> getPolicyIdsByRedis(User user) {
Set<Long> policyIds = redisTemplate.opsForSet().members(user.getUserId().toString());
return policyIds.stream().collect(Collectors.toList());
}

public PolicyInfoResponseDto getPolicy(User user, Long policyId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public Set<PolicySplzType> mapToSplzCodeFromSplzContent(String splzContent) {
if (splzContent.contains("농업인") || splzContent.contains("농업") || splzContent.contains("창업농") || splzContent.contains("농어업") || splzContent.contains("영농종사자")) {
splzContentSplzCodes.add(PolicySplzType.FARMER);
}
if (splzContent.contains("제한없음") || splzContent.contains("null") || splzContent.contains("제한 없음")) {
if (splzContent.contains("제한없음") || splzContent.contains("null") || splzContent.contains("제한 없음") || splzContent.equals("-")) {
splzContentSplzCodes.add(PolicySplzType.UNLIMITED);
}
if (splzContent.contains("창업자") || splzContent.contains("스타트업") || splzContent.contains("예비창업자")
Expand Down
Loading

0 comments on commit fa655f7

Please sign in to comment.