Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️ refactor: 챌린지 성공 로직 수정 #190

Merged
merged 9 commits into from
Jan 14, 2025
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
Loading