Skip to content

Commit

Permalink
Merge pull request #190 from FOREGG-DEV/dev
Browse files Browse the repository at this point in the history
♻️ refactor: 챌린지 성공 로직 수정
  • Loading branch information
DongJun1110 authored Jan 14, 2025
2 parents 2fc5e0d + 8457132 commit 86e2635
Show file tree
Hide file tree
Showing 9 changed files with 154 additions and 83 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -90,15 +90,11 @@ public ApiResponse<String> quitChallenge(@PathVariable(name = "id") Long challen
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "CHALLENGE4005", description = "이미 성공한 날짜입니다"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "CHALLENGE4012", description = "오늘, 어제 날짜 이외에는 챌린지 성공 할 수 없습니다"),
})
public ApiResponse<MyChallengeDTO> complete(@PathVariable(name = "id") Long challengeId,
@RequestParam(name = "day") ChallengeSuccessDayType day,
public ApiResponse<String> complete(@PathVariable(name = "id") Long challengeId,
@RequestParam(name = "date") String date,
@RequestBody(required = false) ChallengeCompleteRequestDTO dto) {
if (day.equals(ChallengeSuccessDayType.TODAY)) {
MyChallengeDTO result = challengeService.success(challengeId, DateUtil.getTodayDayOfWeek(), dto);
return ApiResponse.onSuccess(result);
}
MyChallengeDTO result = challengeService.success(challengeId, DateUtil.getYesterdayDayOfWeek(), dto);
return ApiResponse.onSuccess(result);
challengeService.success(challengeId, date, dto);
return ApiResponse.onSuccess("성공입니다");
}

@Operation(summary = "해당 챌린지 수행 완료 취소 API")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import foregg.foreggserver.dto.challengeDTO.ChallengeResponseDTO.MyChallengeTotalDTO.MyChallengeDTO;
import lombok.RequiredArgsConstructor;

import java.util.List;
import java.util.Optional;

@RequiredArgsConstructor
Expand Down Expand Up @@ -39,20 +40,22 @@ public static ChallengeDTO toChallengeResponseDTO(Challenge challenge, User user
.isParticipating(isParticipating).build();
}

public static MyChallengeDTO toMyChallengeDTO(ChallengeParticipation cp, int participants) {
public static MyChallengeDTO toMyChallengeDTO(ChallengeParticipation cp, int participants, List<String> successDates) {
Challenge challenge = cp.getChallenge();
return MyChallengeDTO.builder()
.id(challenge.getId())
.name(challenge.getName())
.participants(participants)
.successDays(cp.getSuccessDays()).build();
.startDate(cp.getStartDate())
.firstDate(cp.getFirstDate())
.successDays(successDates).build();
}

public static ChallengeParticipantDTO toChallengeParticipantDTO(ChallengeParticipation challengeParticipations, boolean isSupported) {
public static ChallengeParticipantDTO toChallengeParticipantDTO(ChallengeParticipation challengeParticipations, boolean isSupported, String comment) {
return ChallengeParticipantDTO.builder()
.userId(challengeParticipations.getUser().getId())
.nickname(challengeParticipations.getUser().getChallengeName())
.thoughts(challengeParticipations.getThoughts())
.thoughts(comment)
.isSupported(isSupported).build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,26 +28,16 @@ public class ChallengeParticipation extends BaseEntity {

private boolean isOpen;

@Setter
private String thoughts;

@Setter
private boolean isParticipating;

@Builder.Default
private List<String> successDays = new ArrayList<>();

public void setSuccessDays(String today) {
this.successDays.add(today);
}
@Setter
private String startDate;

@PrePersist
@PostLoad
private void initializeSuccessDays() {
if (this.successDays == null) {
this.successDays = new ArrayList<>();
}
}
@Setter
private String firstDate;

@OneToMany(mappedBy = "challengeParticipation", cascade = CascadeType.ALL, orphanRemoval = true)
private List<ChallengeSuccess> challengeSuccesses;

}
30 changes: 30 additions & 0 deletions src/main/java/foregg/foreggserver/domain/ChallengeSuccess.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package foregg.foreggserver.domain;

import foregg.foreggserver.domain.common.BaseEntity;
import jakarta.persistence.*;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

@Entity
@Builder
@AllArgsConstructor
@NoArgsConstructor
@Getter
public class ChallengeSuccess extends BaseEntity {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "challenge_participation_id")
private ChallengeParticipation challengeParticipation;

@Column(nullable = false)
private String date;

private String comment;

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ public static class ChallengeDTO{
@NoArgsConstructor
public static class MyChallengeTotalDTO {

String firstDateOfWeek;
List<MyChallengeDTO> dtos;

@Getter
Expand All @@ -45,6 +44,8 @@ public static class MyChallengeDTO{
private Long id;
private String name;
private int participants;
private String startDate;
private String firstDate;
private List<String> successDays;
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package foregg.foreggserver.repository;

import foregg.foreggserver.domain.ChallengeParticipation;
import foregg.foreggserver.domain.ChallengeSuccess;
import org.springframework.data.jpa.repository.JpaRepository;

import java.util.Optional;

public interface ChallengeSuccessRepository extends JpaRepository<ChallengeSuccess, Long> {

Optional<ChallengeSuccess> findByDate(String date);

Optional<ChallengeSuccess> findByChallengeParticipationAndDate(ChallengeParticipation cp, String date);

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
import foregg.foreggserver.apiPayload.exception.handler.ChallengeHandler;
import foregg.foreggserver.apiPayload.exception.handler.PageHandler;
import foregg.foreggserver.converter.ChallengeConverter;
import foregg.foreggserver.domain.Challenge;
import foregg.foreggserver.domain.ChallengeParticipation;
import foregg.foreggserver.domain.Notification;
import foregg.foreggserver.domain.User;
import foregg.foreggserver.domain.*;
import foregg.foreggserver.domain.enums.NotificationType;
import foregg.foreggserver.dto.challengeDTO.ChallengeResponseDTO;
import foregg.foreggserver.dto.challengeDTO.ChallengeResponseDTO.ChallengeDTO;
import foregg.foreggserver.dto.challengeDTO.ChallengeResponseDTO.ChallengeParticipantsDTO;
import foregg.foreggserver.dto.challengeDTO.ChallengeResponseDTO.ChallengeParticipantsDTO.ChallengeParticipantDTO;
import foregg.foreggserver.dto.challengeDTO.ChallengeResponseDTO.MyChallengeTotalDTO;
import foregg.foreggserver.dto.challengeDTO.ChallengeResponseDTO.MyChallengeTotalDTO.MyChallengeDTO;
import foregg.foreggserver.repository.ChallengeSuccessRepository;
import foregg.foreggserver.repository.NotificationRepository;
import foregg.foreggserver.repository.ChallengeParticipationRepository;
import foregg.foreggserver.repository.ChallengeRepository;
Expand All @@ -38,6 +38,7 @@ public class ChallengeQueryService {
private final ChallengeParticipationRepository challengeParticipationRepository;
private final UserQueryService userQueryService;
private final NotificationRepository notificationRepository;
private final ChallengeSuccessRepository challengeSuccessRepository;

public ChallengeResponseDTO challengeMain() {
User user = userQueryService.getUser();
Expand Down Expand Up @@ -65,18 +66,21 @@ public ChallengeResponseDTO getAllChallenges() {
ChallengeDTO challengeResponseDTO = ChallengeConverter.toChallengeResponseDTO(challenge, user, cp);
resultList.add(challengeResponseDTO);
}

resultList.addAll(getCustomChallenge());
return ChallengeResponseDTO.builder().dtos(resultList).build();
}

public ChallengeResponseDTO.MyChallengeTotalDTO getMyChallenges() {
List<ChallengeResponseDTO.MyChallengeTotalDTO.MyChallengeDTO> result = new ArrayList<>();
public MyChallengeTotalDTO getMyChallenges() {
List<MyChallengeDTO> result = new ArrayList<>();
List<ChallengeParticipation> cp = getMyCParticipation();

for (ChallengeParticipation challengeParticipation : cp) {
result.add(ChallengeConverter.toMyChallengeDTO(challengeParticipation, getChallengeParticipants(challengeParticipation)));
String firstDate = DateUtil.getFirstDayOfWeek(challengeParticipation.getStartDate());
challengeParticipation.setFirstDate(firstDate);
List<String> successDates = getSuccessDates(challengeParticipation);
result.add(ChallengeConverter.toMyChallengeDTO(challengeParticipation, getChallengeParticipants(challengeParticipation), successDates));
}
return ChallengeResponseDTO.MyChallengeTotalDTO.builder().dtos(result).firstDateOfWeek(DateUtil.getFirstDayOfWeek()).build();
return MyChallengeTotalDTO.builder().dtos(result).build();
}

public ChallengeParticipantsDTO getParticipants(Long challengeId, boolean isSuccess, Pageable pageable) {
Expand All @@ -89,9 +93,9 @@ public ChallengeParticipantsDTO getParticipants(Long challengeId, boolean isSucc

challengeParticipations.removeIf(cp -> cp.getUser().equals(currentUser));
if (isSuccess) {
challengeParticipations.removeIf(cp -> !cp.getSuccessDays().contains(DateUtil.getTodayDayOfWeek()));
challengeParticipations.removeIf(cp -> challengeSuccessRepository.findByChallengeParticipationAndDate(cp,LocalDate.now().toString()).isEmpty());
} else {
challengeParticipations.removeIf(cp -> cp.getSuccessDays().contains(DateUtil.getTodayDayOfWeek()));
challengeParticipations.removeIf(cp -> challengeSuccessRepository.findByChallengeParticipationAndDate(cp,LocalDate.now().toString()).isPresent());
}

if (!challengeParticipations.isEmpty()) {
Expand All @@ -103,7 +107,12 @@ public ChallengeParticipantsDTO getParticipants(Long challengeId, boolean isSucc
notification = notificationRepository.findBySenderAndReceiverAndDateAndNotificationType(currentUser.getChallengeName(), cp.getUser(), LocalDate.now().toString(), NotificationType.SUPPORT);
}
boolean supported = notification != null;
result.add(ChallengeConverter.toChallengeParticipantDTO(cp, supported));
Optional<ChallengeSuccess> foundChallengeSuccess = challengeSuccessRepository.findByDate(LocalDate.now().toString());
String comment = null;
if (foundChallengeSuccess.isPresent()) {
comment = foundChallengeSuccess.get().getComment();
}
result.add(ChallengeConverter.toChallengeParticipantDTO(cp, supported, comment));
}
}

Expand All @@ -128,9 +137,6 @@ public ChallengeParticipantsDTO getParticipants(Long challengeId, boolean isSucc
.build();
}




//챌린지 검색 메서드
public ChallengeResponseDTO searchChallenge(String keyword) {
User user = userQueryService.getUser();
Expand Down Expand Up @@ -227,7 +233,6 @@ private List<ChallengeParticipation> getMyCParticipation() {
User user = userQueryService.getUser();
List<ChallengeParticipation> cParticipation = challengeParticipationRepository.findByUser(user).orElse(null);
cParticipation.removeIf(cp -> !cp.isParticipating());
List<Challenge> result = new ArrayList<>();
return cParticipation;
}

Expand All @@ -240,4 +245,17 @@ public int getChallengeParticipants(ChallengeParticipation cp) {
return 0;
}

private List<String> getSuccessDates(ChallengeParticipation challengeParticipation) {
List<String> intervalDates = DateUtil.getIntervalDates(challengeParticipation.getFirstDate());
List<String> result = new ArrayList<>();
for (String date : intervalDates) {
log.info("date"+date);
Optional<ChallengeSuccess> foundElement = challengeSuccessRepository.findByChallengeParticipationAndDate(challengeParticipation, date);
if (foundElement.isPresent()) {
result.add(date);
}
}
return result;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,11 @@
import foregg.foreggserver.apiPayload.exception.handler.ChallengeHandler;
import foregg.foreggserver.apiPayload.exception.handler.UserHandler;
import foregg.foreggserver.converter.ChallengeConverter;
import foregg.foreggserver.domain.Challenge;
import foregg.foreggserver.domain.ChallengeParticipation;
import foregg.foreggserver.domain.Notification;
import foregg.foreggserver.domain.User;
import foregg.foreggserver.domain.*;
import foregg.foreggserver.domain.enums.NavigationType;
import foregg.foreggserver.domain.enums.NotificationType;
import foregg.foreggserver.dto.challengeDTO.ChallengeResponseDTO.MyChallengeTotalDTO.MyChallengeDTO;
import foregg.foreggserver.repository.ChallengeParticipationRepository;
import foregg.foreggserver.repository.ChallengeRepository;
import foregg.foreggserver.repository.NotificationRepository;
import foregg.foreggserver.repository.UserRepository;
import foregg.foreggserver.repository.*;
import foregg.foreggserver.service.fcmService.FcmService;
import foregg.foreggserver.service.notificationService.NotificationService;
import foregg.foreggserver.service.userService.UserQueryService;
Expand Down Expand Up @@ -46,6 +40,7 @@ public class ChallengeService {
private final NotificationService notificationService;
private final NotificationRepository notificationRepository;
private final FcmService fcmService;
private final ChallengeSuccessRepository challengeSuccessRepository;

public void participate(Long id) {
User user = userQueryService.getUser();
Expand All @@ -55,6 +50,8 @@ public void participate(Long id) {
throw new ChallengeHandler(ALREADY_PARTICIPATING);
}
cp.setParticipating(true);
cp.setStartDate(LocalDate.now().toString());
cp.setFirstDate(LocalDate.now().toString());
}

public void quitChallenge(Long challengeId) {
Expand All @@ -71,11 +68,11 @@ public void deleteTodaySuccess(Long id) {
Challenge challenge = challengeRepository.findById(id).orElseThrow(() -> new ChallengeHandler(CHALLENGE_NOT_FOUND));
ChallengeParticipation challengeParticipation = challengeParticipationRepository.findByUserAndChallenge(user, challenge).
orElseThrow(() -> new ChallengeHandler(NO_PARTICIPATING_CHALLENGE));
List<String> successDays = challengeParticipation.getSuccessDays();
if (successDays == null) {
Optional<ChallengeSuccess> foundChallengeSuccess = challengeSuccessRepository.findByChallengeParticipationAndDate(challengeParticipation, LocalDate.now().toString());
if (foundChallengeSuccess.isEmpty()) {
throw new ChallengeHandler(NO_SUCCESS_DAY);
}
successDays.remove(DateUtil.formatLocalDateTime(LocalDate.now()));
challengeSuccessRepository.delete(foundChallengeSuccess.get());
}

public String createChallengeName(ChallengeNameRequestDTO dto) {
Expand Down Expand Up @@ -131,38 +128,40 @@ public void createChallenge(ChallengeCreateRequestDTO dto) {
challengeParticipationRepository.save(cp);
}

public MyChallengeDTO success(Long challengeId, String todayDayOfWeek, ChallengeCompleteRequestDTO dto) {
public void success(Long challengeId, String date, ChallengeCompleteRequestDTO dto) {
User user = userQueryService.getUser();
String thoughts = null;
if (dto != null) {
thoughts = dto.getThoughts();
}

Challenge challenge = challengeRepository.findById(challengeId).orElseThrow(() -> new ChallengeHandler(CHALLENGE_NOT_FOUND));
ChallengeParticipation cParticipation = challengeParticipationRepository.findByUserAndChallenge(user, challenge).orElseThrow(() -> new ChallengeHandler(NO_PARTICIPATING_CHALLENGE));
if (!cParticipation.isParticipating()) {
throw new ChallengeHandler(NO_PARTICIPATING_CHALLENGE);
}
if (cParticipation.getSuccessDays().contains(todayDayOfWeek)) {
throw new ChallengeHandler(DUPLICATED_SUCCESS_DATE);
}
cParticipation.getSuccessDays().add(todayDayOfWeek);
if (todayDayOfWeek.equals(DateUtil.getTodayDayOfWeek())) {

//오늘 날짜일때
if(date.equals(LocalDate.now().toString())){
if (challengeSuccessRepository.findByDate(LocalDate.now().toString()).isPresent()) {
throw new ChallengeHandler(DUPLICATED_SUCCESS_DATE);
}
ChallengeSuccess challengeSuccess = ChallengeSuccess.builder().date(LocalDate.now().toString())
.challengeParticipation(cParticipation).comment(thoughts).build();
challengeSuccessRepository.save(challengeSuccess);
user.addPoint(100);
cParticipation.setThoughts(dto.getThoughts());
} else if (todayDayOfWeek.equals(DateUtil.getYesterdayDayOfWeek())) {
} //어제 날짜일때
else if (date.equals(LocalDate.now().minusDays(1).toString())) {
if (challengeSuccessRepository.findByDate(LocalDate.now().minusDays(1).toString()).isPresent()) {
throw new ChallengeHandler(DUPLICATED_SUCCESS_DATE);
}
ChallengeSuccess challengeSuccess = ChallengeSuccess.builder().date(LocalDate.now().minusDays(1).toString())
.challengeParticipation(cParticipation).comment(thoughts).build();
challengeSuccessRepository.save(challengeSuccess);
user.addPoint(50);
} else {
}else{
throw new ChallengeHandler(OUT_OF_VALIDATE_DAYS);
}
return ChallengeConverter.toMyChallengeDTO(cParticipation, challengeQueryService.getChallengeParticipants(cParticipation));
}

//챌린지 성공 날짜 초기화 메서드
@Scheduled(cron = "0 0 0 * * SUN")
@Transactional
public void initSuccessDays() {
List<ChallengeParticipation> challengeParticipations = challengeParticipationRepository.findAll();
for (ChallengeParticipation cp : challengeParticipations) {
cp.getSuccessDays().clear(); // successDays 초기화
}
challengeParticipationRepository.saveAll(challengeParticipations); // 변경 사항 저장
}

public void cheer(Long receiverId, NotificationType type, Long challengeId) {
Expand Down Expand Up @@ -211,11 +210,11 @@ private void cheerAlarm(User receiver, User sender, NotificationType type, Long
}

private void catchCheerException(ChallengeParticipation challengeParticipation, NotificationType notificationType) {
if (challengeParticipation.getSuccessDays().contains(DateUtil.getTodayDayOfWeek()) && notificationType.equals(NotificationType.SUPPORT)) {
if (challengeSuccessRepository.findByChallengeParticipationAndDate(challengeParticipation, LocalDate.now().toString()).isPresent() && notificationType.equals(NotificationType.SUPPORT)) {
throw new ChallengeHandler(UNABLE_TO_SEND_SUPPORT);
}

if (!challengeParticipation.getSuccessDays().contains(DateUtil.getTodayDayOfWeek()) && notificationType.equals(NotificationType.CLAP)) {
if (challengeSuccessRepository.findByChallengeParticipationAndDate(challengeParticipation, LocalDate.now().toString()).isEmpty() && notificationType.equals(NotificationType.CLAP)) {
throw new ChallengeHandler(UNABLE_TO_SEND_CLAP);
}
}
Expand Down
Loading

0 comments on commit 86e2635

Please sign in to comment.