diff --git a/src/main/java/com/noplanb/domain/quest/application/CalendarService.java b/src/main/java/com/noplanb/domain/quest/application/CalendarService.java index 7908e75..f1706a1 100644 --- a/src/main/java/com/noplanb/domain/quest/application/CalendarService.java +++ b/src/main/java/com/noplanb/domain/quest/application/CalendarService.java @@ -4,10 +4,13 @@ import com.noplanb.domain.character.repository.CharacterRepository; import com.noplanb.domain.quest.domain.DailyExperience; import com.noplanb.domain.quest.domain.Quest; +import com.noplanb.domain.quest.dto.req.CreateQuestAfterTodayReq; import com.noplanb.domain.quest.dto.res.RetrieveCalendarRes; import com.noplanb.domain.quest.repository.DailyExperienceRepository; +import com.noplanb.domain.quest.repository.QuestRepository; import com.noplanb.global.config.security.token.UserPrincipal; import com.noplanb.global.payload.ApiResponse; +import com.noplanb.global.payload.Message; import com.noplanb.global.payload.exception.CharacterNotFoundException; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; @@ -15,6 +18,7 @@ import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; +import java.time.LocalDateTime; import java.time.YearMonth; import java.util.List; import java.util.stream.Collectors; @@ -26,6 +30,7 @@ public class CalendarService { private final CharacterRepository characterRepository; private final DailyExperienceRepository dailyExperienceRepository; + private final QuestRepository questRepository; public ResponseEntity retrieveCalendar(YearMonth date, UserPrincipal userPrincipal) { LocalDate startDate = date.atDay(1); @@ -48,4 +53,26 @@ public ResponseEntity retrieveCalendar(YearMonth date, UserPrincipal userPrin return ResponseEntity.ok(apiResponse); } + @Transactional + public ResponseEntity createQuestAfterToday(CreateQuestAfterTodayReq createQuestAfterTodayReq, UserPrincipal userPrincipal) { + Character character = characterRepository.findById(userPrincipal.getId()).orElseThrow(CharacterNotFoundException::new); + //미리 추가하는 경우는 자정으로 설정한다. + LocalDateTime dateTimeAtMidnight = createQuestAfterTodayReq.getDate().atStartOfDay(); + Quest quest = Quest.builder() + .createdTime(dateTimeAtMidnight) + .contents(createQuestAfterTodayReq.getContents()) + .exp(createQuestAfterTodayReq.getExp()) + .character(character) + .isComplete(Boolean.FALSE) + .build(); + + questRepository.save(quest); + character.getQuests().add(quest); + + ApiResponse apiResponse = ApiResponse.builder() + .check(true) + .information((Message.builder().message("금일 기준 달력 퀘스트를 만들었습니다.").build())) + .build(); + return ResponseEntity.ok(apiResponse); + } } diff --git a/src/main/java/com/noplanb/domain/quest/application/QuestService.java b/src/main/java/com/noplanb/domain/quest/application/QuestService.java index 7a5d340..88591d1 100644 --- a/src/main/java/com/noplanb/domain/quest/application/QuestService.java +++ b/src/main/java/com/noplanb/domain/quest/application/QuestService.java @@ -26,6 +26,7 @@ import org.springframework.transaction.annotation.Transactional; import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.Comparator; import java.util.List; import java.util.stream.Collectors; @@ -43,6 +44,7 @@ public ResponseEntity createQuest(CreateQuestReq createQuestReq, UserPrincipa Character character = characterRepository.findById(userPrincipal.getId()).orElseThrow(CharacterNotFoundException::new); Quest quest = Quest.builder() + .createdTime(LocalDateTime.now()) .contents(createQuestReq.getContents()) .exp(createQuestReq.getExp()) .character(character) @@ -60,9 +62,9 @@ public ResponseEntity retrieveQuest(LocalDate localDate, UserPrincipal userPr List quests = character.getQuests(); // 특정 날짜에 해당하는 퀘스트 필터링 후 미완료 완료 로 정렬 후 생성순으로 정렬 List retrieveQuestResList = quests.stream() - .filter(quest -> quest.getCreatedAt().toLocalDate().isEqual(localDate)) + .filter(quest -> quest.getCreatedTime().toLocalDate().isEqual(localDate)) .sorted(Comparator.comparing(Quest::getIsComplete) - .thenComparing(Quest::getCreatedAt)) + .thenComparing(Quest::getCreatedTime)) .map(quest -> RetrieveQuestRes.builder() .id(quest.getId()) .contents(quest.getContents()) @@ -114,7 +116,7 @@ public ResponseEntity completeQuest(UserPrincipal userPrincipal, Long id) { //해금된 아이템들 이미지 반환 List unLockImages = unLockItems.stream() .map(item -> RetrieveLevelUpItemImage.builder() - .itemImageUrl(itemImageRepository.findItemImageByItem(item).getItemImageUrl()) + .itemImageUrl(item.getItemImage().getItemImageUrl()) .build()) .collect(Collectors.toList()); return createApiResponse(unLockImages); @@ -159,6 +161,7 @@ public ResponseEntity deleteQuest(UserPrincipal userPrincipal, Long id) { @Transactional @Scheduled(cron = "0 0 0 * * *") public void resetDailyExperience() { + System.out.println(" 하루 경험치 초기화 함수실행"); List characters = characterRepository.findAll(); for (Character character : characters) { // 어제 날짜로 DailyExperience 엔티티에 저장 diff --git a/src/main/java/com/noplanb/domain/quest/controller/CalendarController.java b/src/main/java/com/noplanb/domain/quest/controller/CalendarController.java index 60139e8..26733bd 100644 --- a/src/main/java/com/noplanb/domain/quest/controller/CalendarController.java +++ b/src/main/java/com/noplanb/domain/quest/controller/CalendarController.java @@ -1,6 +1,7 @@ package com.noplanb.domain.quest.controller; import com.noplanb.domain.quest.application.CalendarService; +import com.noplanb.domain.quest.dto.req.CreateQuestAfterTodayReq; import com.noplanb.domain.quest.dto.res.RetrieveCalendarRes; import com.noplanb.global.config.security.token.CurrentUser; import com.noplanb.global.config.security.token.UserPrincipal; @@ -16,10 +17,9 @@ import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.*; +import java.time.LocalDate; import java.time.YearMonth; @Controller @@ -39,4 +39,15 @@ public ResponseEntity retrieveCalendar( @Parameter(description = "Access Token을 입력해주세요.", required = true) @CurrentUser UserPrincipal userPrincipal){ return calendarService.retrieveCalendar(date,userPrincipal); } + @PostMapping + @Operation(summary = "달력 금일기준 이후 퀘스트생성", description = "달력 금일기준 이후 퀘스트생성") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "달력 금일기준 이후 퀘스트생성 성공", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = RetrieveCalendarRes.class))}), + @ApiResponse(responseCode = "400", description = "달력 금일기준 이후 퀘스트생성 실패", content = {@Content(mediaType = "application/json", schema = @Schema(implementation = ErrorResponse.class))}), + }) + public ResponseEntity createQuestAfterToday( + @Parameter(description = "달력 금일기준 이후 퀘스트생성 dto Req입니다.", required = true) @RequestBody CreateQuestAfterTodayReq createQuestAfterTodayReq, + @Parameter(description = "Access Token을 입력해주세요.", required = true) @CurrentUser UserPrincipal userPrincipal){ + return calendarService.createQuestAfterToday(createQuestAfterTodayReq,userPrincipal); + } } diff --git a/src/main/java/com/noplanb/domain/quest/domain/Quest.java b/src/main/java/com/noplanb/domain/quest/domain/Quest.java index df7bed5..0ea8d21 100644 --- a/src/main/java/com/noplanb/domain/quest/domain/Quest.java +++ b/src/main/java/com/noplanb/domain/quest/domain/Quest.java @@ -5,6 +5,8 @@ import jakarta.persistence.*; import lombok.*; +import java.time.LocalDateTime; + import static jakarta.persistence.GenerationType.IDENTITY; @Entity @@ -22,6 +24,8 @@ public class Quest extends BaseEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "character_id") private Character character; + private LocalDateTime createdTime; + public void updateCharacter(Character character) { this.character = character; diff --git a/src/main/java/com/noplanb/domain/quest/dto/req/CreateQuestAfterTodayReq.java b/src/main/java/com/noplanb/domain/quest/dto/req/CreateQuestAfterTodayReq.java new file mode 100644 index 0000000..aab9544 --- /dev/null +++ b/src/main/java/com/noplanb/domain/quest/dto/req/CreateQuestAfterTodayReq.java @@ -0,0 +1,18 @@ +package com.noplanb.domain.quest.dto.req; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import org.springframework.format.annotation.DateTimeFormat; + +import java.time.LocalDate; + +@Getter +public class CreateQuestAfterTodayReq { + @Schema(type = "LocalDate", example = "2024-08-29", description = "금일 기준 이후 날짜") + @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) + private LocalDate date; + @Schema(type = "String", example = "청소하기", description = "퀘스트 내용") + private String contents; + @Schema(type = "Long", example = "5", description = "퀘스트 경험치") + private Long exp; +} diff --git a/src/main/java/com/noplanb/domain/s3/application/AwsFileService.java b/src/main/java/com/noplanb/domain/s3/application/AwsFileService.java index 1cd29dd..e4c7f1d 100644 --- a/src/main/java/com/noplanb/domain/s3/application/AwsFileService.java +++ b/src/main/java/com/noplanb/domain/s3/application/AwsFileService.java @@ -71,62 +71,8 @@ private Optional convert(MultipartFile file) throws IOException { } return Optional.of(convertFile); } else { - log.error("Failed to create new file: " + convertFile.getAbsolutePath()); - } + log.error("Failed to create new file: " + convertFile.getAbsolutePath()); + } return Optional.empty(); } - - public void createDir(String bucketName, String folderName) { - amazonS3Client.putObject(bucketName, folderName + "/", new ByteArrayInputStream(new byte[0]), new ObjectMetadata()); - } -// public void deleteImage(String dirName, String imageUrl) { -// String fileName = extractFileNameFromUrl(imageUrl); -// -// if (fileName != null) { -// try { -// fileName = URLDecoder.decode(fileName, "UTF-8"); -// } catch (Exception e) { -// log.error("파일명 디코딩 중 오류 발생", e); -// return; -// } -// -// // 디렉토리명과 파일명을 조합하여 전체 객체 키 생성 -// String objectKey = dirName + "/" + fileName; -// -// // S3 파일 확인 -// if (isS3FileExists(objectKey)) { -// amazonS3Client.deleteObject(bucket, objectKey); -// log.info("S3 이미지 삭제가 완료되었습니다. 파일명: {}", objectKey); -// -// } else { -// log.warn("S3에 해당 파일이 존재하지 않습니다. 파일명: {}", objectKey); -// } -// -// } else { -// log.warn("유효하지 않은 S3 이미지 URL입니다. URL: {}", imageUrl); -// } -// -// } - - // S3에 해당 파일이 존재하는지 확인 -// private boolean isS3FileExists(String fileName) { -// try { -// ObjectMetadata objectMetadata = amazonS3Client.getObjectMetadata(bucket, fileName); -// return true; -// } catch (AmazonS3Exception e) { -// if (e.getStatusCode() == 404) { -// return false; // 파일이 존재하지 않음 -// } else { -// throw e; // 다른 예외는 다시 던짐 -// } -// } -// } -// -// private String extractFileNameFromUrl(String imageUrl) { -// try { -// return imageUrl.substring(imageUrl.lastIndexOf("/") + 1); -// } catch (Exception e) { -// return null; -// } -// } -} +} \ No newline at end of file