Skip to content

Commit

Permalink
Merge pull request #193 from sharemindteam/fix/192-realtime-counselor
Browse files Browse the repository at this point in the history
fix: 들을 준비가 된 상담사 리스트 수정
  • Loading branch information
aeyongdodam authored Jun 19, 2024
2 parents 4c0216a + 5b6da17 commit 9ac61bf
Show file tree
Hide file tree
Showing 5 changed files with 110 additions and 23 deletions.
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.example.sharemind.counselor.application;

import static com.example.sharemind.global.constants.Constants.REALTIME_COUNSELOR;

import com.example.sharemind.chat.domain.Chat;
import com.example.sharemind.counselor.content.Bank;
import com.example.sharemind.counselor.content.ConsultStyle;
Expand All @@ -23,11 +25,15 @@
import com.example.sharemind.wishList.application.WishListCounselorService;
import com.example.sharemind.wishList.domain.WishList;
import com.example.sharemind.wishList.dto.request.WishListGetRequest;
import java.time.LocalDate;
import java.time.LocalTime;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Page;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

Expand All @@ -40,10 +46,12 @@
public class CounselorServiceImpl implements CounselorService {

private static final int COUNSELOR_PAGE = 4;
private static final String SPLIT_HOURS = "~";

private final CounselorRepository counselorRepository;
private final CustomerService customerService;
private final WishListCounselorService wishListCounselorService;
private final RedisTemplate<String, List<Long>> redisTemplate;

@Override
public Counselor getCounselorByCounselorId(Long counselorId) {
Expand Down Expand Up @@ -107,7 +115,7 @@ public Boolean getRetryPermission(Long customerId) {
@Transactional
@Override
public void updateCounselorProfile(CounselorUpdateProfileRequest counselorUpdateProfileRequest,
Long customerId) {
Long customerId) {
Counselor counselor = getCounselorByCustomerId(customerId);
if ((counselor.getIsEducated() == null) || (!counselor.getIsEducated())) {
throw new CounselorException(CounselorErrorCode.COUNSELOR_NOT_EDUCATED);
Expand Down Expand Up @@ -198,7 +206,7 @@ private List<Counselor> getCounselorByCategoryWithPagination(
Pageable pageable = PageRequest.of(counselorGetRequest.getIndex(), COUNSELOR_PAGE,
Sort.by(sortColumn).descending());
if (counselorGetRequest.getConsultCategory() == null) {
return counselorRepository.findByLevelAndStatus(pageable).getContent();
return getRealtimeCounselors(counselorGetRequest.getIndex());
}

ConsultCategory consultCategory = ConsultCategory.getConsultCategoryByName(
Expand All @@ -207,6 +215,16 @@ private List<Counselor> getCounselorByCategoryWithPagination(
.getContent();
}

private List<Counselor> getRealtimeCounselors(int index) {
int start = index * COUNSELOR_PAGE;
List<Long> counselorIds = redisTemplate.opsForValue().get(REALTIME_COUNSELOR);

List<Long> counselorsSubList =
counselorIds != null && counselorIds.size() >= COUNSELOR_PAGE ? counselorIds.subList(start, start + COUNSELOR_PAGE)
: counselorIds;
return counselorRepository.findAllById(counselorsSubList);
}

@Override
public List<Counselor> getCounselorByWordWithPagination(
SearchWordCounselorFindRequest searchWordCounselorFindRequest,
Expand All @@ -223,34 +241,47 @@ public List<Counselor> getCounselorByWordWithPagination(

@Override
public List<CounselorGetListResponse> getCounselorsByCategoryAndCustomer(Long customerId,
String sortType, CounselorGetRequest counselorGetRequest) {
String sortType,
CounselorGetRequest counselorGetRequest) {
List<Counselor> counselors = getCounselorByCategoryWithPagination(counselorGetRequest,
sortType);

List<Long> counselorIds = redisTemplate.opsForValue().get(REALTIME_COUNSELOR);
Customer customer = customerService.getCustomerByCustomerId(customerId);
Set<Long> wishListCounselorIds = wishListCounselorService.getWishListCounselorIdsByCustomer(
customer);

if (counselorIds == null) {
return counselors.stream()
.map(counselor -> CounselorGetListResponse.of(counselor,
wishListCounselorIds.contains(counselor.getCounselorId()), false))
.toList();
}
return counselors.stream()
.map(counselor -> CounselorGetListResponse.of(counselor,
wishListCounselorIds.contains(counselor.getCounselorId())))
wishListCounselorIds.contains(counselor.getCounselorId()),
counselorIds.contains(counselor.getCounselorId())))
.toList();
}

@Override
public List<CounselorGetListResponse> getAllCounselorsByCategory(String sortType,
CounselorGetRequest counselorGetRequest) {
CounselorGetRequest counselorGetRequest) {
List<Counselor> counselors = getCounselorByCategoryWithPagination(counselorGetRequest,
sortType);

List<Long> counselorIds = redisTemplate.opsForValue().get(REALTIME_COUNSELOR);
if (counselorIds == null) {
return counselors.stream()
.map(counselor -> CounselorGetListResponse.of(counselor, false, false))
.toList();
}
return counselors.stream()
.map(counselor -> CounselorGetListResponse.of(counselor, false))
.map(counselor -> CounselorGetListResponse.of(counselor, false,
counselorIds.contains(counselor.getCounselorId())))
.toList();
}

@Override
public CounselorGetMinderProfileResponse getCounselorMinderProfileByCustomer(Long counselorId,
Long customerId) {
Long customerId) {
Customer customer = customerService.getCustomerByCustomerId(customerId);
Counselor counselor = getCounselorByCounselorId(counselorId);

Expand All @@ -268,7 +299,7 @@ public CounselorGetMinderProfileResponse getAllCounselorMinderProfile(Long couns
@Transactional
@Override
public void updateAccount(CounselorUpdateAccountRequest counselorUpdateAccountRequest,
Long customerId) {
Long customerId) {
Counselor counselor = getCounselorByCustomerId(customerId);
Bank.existsByDisplayName(counselorUpdateAccountRequest.getBank());
counselor.updateAccountInfo(counselorUpdateAccountRequest.getAccount(),
Expand Down Expand Up @@ -302,7 +333,7 @@ public CounselorGetInfoResponse getCounselorMyInfo(Long customerId) {

@Override
public CounselorGetForConsultResponse getCounselorForConsultCreation(Long counselorId,
String type) {
String type) {
Counselor counselor = getCounselorByCounselorId(counselorId);
ConsultType consultType = ConsultType.getConsultTypeByName(type);
if (!counselor.getConsultTypes().contains(consultType)) {
Expand Down Expand Up @@ -342,4 +373,38 @@ public void checkCounselorAndCustomerSame(Customer customer, Counselor counselor
customer.getCustomerId().toString());
}
}

@Scheduled(cron = "0 0 * * * *", zone = "Asia/Seoul")
public void updateRealtimeCounselors() {
List<Counselor> counselors = counselorRepository.findAllByIsEducatedIsTrueAndIsActivatedIsTrue();
String currentDay = LocalDate.now().getDayOfWeek().toString().substring(0, 3).toUpperCase();
int currentHour = LocalTime.now().getHour();

List<Counselor> realtimeCounselors = counselors.stream()
.filter(counselor -> isAvailableAtRealTime(counselor.getConsultTimes(), currentDay, currentHour))
.sorted((c1, c2) -> Long.compare(c2.getTotalConsult(), c1.getTotalConsult()))
.toList();

List<Long> counselorIds = realtimeCounselors.stream()
.map(Counselor::getCounselorId)
.toList();

redisTemplate.opsForValue().set(REALTIME_COUNSELOR, counselorIds);
}

private boolean isAvailableAtRealTime(Set<ConsultTime> consultTimes, String day, int hour) {
for (ConsultTime consultTime : consultTimes) {
if (Objects.equals(consultTime.getDay().toString(), day)) {
for (String timeRange : consultTime.getTimes()) {
String[] parts = timeRange.split(SPLIT_HOURS);
int startHour = Integer.parseInt(parts[0]);
int endHour = Integer.parseInt(parts[1]);
if (hour >= startHour && hour < endHour) {
return true;
}
}
}
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,24 @@ public class CounselorGetListResponse extends CounselorGetBaseResponse {
@Schema(description = "찜여부", example = "true")
private final Boolean isWishList;

private CounselorGetListResponse(Counselor counselor, Boolean isWishList) {
@Schema(description = "현재 접속 여부", example = "true")
private final Boolean isRealtime;

@Schema(description = "상담 완료 횟수")
private final Long totalConsult;

private CounselorGetListResponse(Counselor counselor, Boolean isWishList, Boolean isRealtime) {
super(counselor);
this.counselorId = counselor.getCounselorId();
this.level = counselor.getLevel();
this.totalReview = counselor.getTotalReview();
this.ratingAverage = counselor.getRatingAverage();
this.isWishList = isWishList;
this.isRealtime = isRealtime;
this.totalConsult = counselor.getTotalConsult();
}

public static CounselorGetListResponse of(Counselor counselor, Boolean isWishList) {
return new CounselorGetListResponse(counselor, isWishList);
public static CounselorGetListResponse of(Counselor counselor, Boolean isWishList, Boolean isRealtime) {
return new CounselorGetListResponse(counselor, isWishList, isRealtime);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public class CounselorController {
})
@PostMapping("/quiz")
public ResponseEntity<Void> updateIsEducated(@RequestParam Boolean isEducated,
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
@AuthenticationPrincipal CustomUserDetails customUserDetails) {
counselorService.updateIsEducated(isEducated,
customUserDetails.getCustomer().getCustomerId());
return ResponseEntity.ok().build();
Expand Down Expand Up @@ -201,7 +201,7 @@ public ResponseEntity<CounselorGetForConsultResponse> getCounselorForConsultCrea
- 들을 준비가 된 마인더들(상담사 전체 리스트)조회의 경우, RequestBody에서 consultCategory를 빼고 넘겨주시면 됩니다.""")
@ApiResponses({
@ApiResponse(responseCode = "200", description = "조회 성공"),
@ApiResponse(responseCode = "404", description = "1. sortType이 잘못된 경우 2. RequestBody의 카테고리가 잘못도니 경우",
@ApiResponse(responseCode = "404", description = "1. sortType이 잘못된 경우 2. RequestBody의 카테고리가 잘못된 경우",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = CustomExceptionResponse.class))
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ public class Constants {
public static final String CUSTOMER_CHATTING_PREFIX = "customer chatting: "; // 현재 접속중인 방
public static final String COUNSELOR_CHATTING_PREFIX = "counselor chatting: ";

public static final String REALTIME_COUNSELOR = "realtimeCounselors";

public static final Integer CUSTOMER_ONGOING_CONSULT = 1;
public static final Integer COUNSELOR_ONGOING_CONSULT = 3;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.example.sharemind.searchWord.application;

import static com.example.sharemind.global.constants.Constants.REALTIME_COUNSELOR;

import com.example.sharemind.counselor.application.CounselorService;
import com.example.sharemind.counselor.domain.Counselor;
import com.example.sharemind.counselor.dto.response.CounselorGetListResponse;
Expand Down Expand Up @@ -40,6 +42,7 @@ public class SearchWordServiceImpl implements SearchWordService {
private final PostScrapRepository postScrapRepository;

private final RedisTemplate<String, String> redisTemplate;
private final RedisTemplate<String, List<Long>> counselorRedisTemplate;

@Transactional
@Override
Expand All @@ -50,13 +53,18 @@ public List<CounselorGetListResponse> storeSearchWordAndGetCounselorsByCustomer(

List<Counselor> counselors = counselorService.getCounselorByWordWithPagination(searchWordCounselorFindRequest,
sortType);

List<Long> counselorIds = counselorRedisTemplate.opsForValue().get(REALTIME_COUNSELOR);
Customer customer = customerService.getCustomerByCustomerId(customerId);
Set<Long> wishListCounselorIds = wishListCounselorService.getWishListCounselorIdsByCustomer(customer);

if (counselorIds == null) {
return counselors.stream()
.map(counselor -> CounselorGetListResponse.of(counselor,
wishListCounselorIds.contains(counselor.getCounselorId()), false))
.toList();
}
return counselors.stream()
.map(counselor -> CounselorGetListResponse.of(counselor,
wishListCounselorIds.contains(counselor.getCounselorId())))
wishListCounselorIds.contains(counselor.getCounselorId()), counselorIds.contains(counselor.getCounselorId())))
.toList();
}

Expand All @@ -68,9 +76,14 @@ public List<CounselorGetListResponse> storeAllSearchWordAndGetCounselors(String

List<Counselor> counselors = counselorService.getCounselorByWordWithPagination(searchWordCounselorFindRequest,
sortType);

List<Long> counselorIds = counselorRedisTemplate.opsForValue().get(REALTIME_COUNSELOR);
if (counselorIds == null) {
return counselors.stream()
.map(counselor -> CounselorGetListResponse.of(counselor, false, false))
.toList();
}
return counselors.stream()
.map(counselor -> CounselorGetListResponse.of(counselor, false))
.map(counselor -> CounselorGetListResponse.of(counselor, false, counselorIds.contains(counselor.getCounselorId())))
.toList();
}

Expand All @@ -79,7 +92,6 @@ public List<CounselorGetListResponse> storeAllSearchWordAndGetCounselors(String
public List<PostGetPublicListResponse> storeAllSearchWordAndGetPosts(String sortType,
SearchWordPostFindRequest searchWordPostFindRequest) {
storeSearchWordInDB(searchWordPostFindRequest.getWord());

List<Post> posts = postService.getPostByWordWithPagination(searchWordPostFindRequest, sortType);

return posts.stream()
Expand Down

0 comments on commit 9ac61bf

Please sign in to comment.