Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,30 +1,89 @@
package com.back.domain.study.plan.controller;

import com.back.domain.study.plan.dto.StudyPlanCreateRequest;
import com.back.domain.study.plan.dto.StudyPlanRequest;
import com.back.domain.study.plan.dto.StudyPlanListResponse;
import com.back.domain.study.plan.dto.StudyPlanResponse;
import com.back.domain.study.plan.entity.StudyPlanException;
import com.back.domain.study.plan.service.StudyPlanService;
import com.back.global.common.dto.RsData;
import com.back.global.security.CustomUserDetails;
import lombok.RequiredArgsConstructor;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.List;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/plans")
public class StudyPlanController {
private final StudyPlanService studyPlanService;

// ==================== 생성 ===================
@PostMapping
public ResponseEntity<RsData<StudyPlanResponse>> createStudyPlan(
// 로그인 유저 정보 받기 @AuthenticationPrincipal CustomUserDetails user,
@RequestBody StudyPlanCreateRequest request) {
@RequestBody StudyPlanRequest request) {
//커스텀 디테일 구현 시 사용 int userId = user.getId();
Long userId = 1L; // 임시로 userId를 1로 설정
StudyPlanResponse response = studyPlanService.createStudyPlan(userId, request);
return ResponseEntity.ok(RsData.success("학습 계획이 성공적으로 생성되었습니다.", response));
}

// ==================== 조회 ===================
// 특정 날짜의 계획들 조회. date 형식: YYYY-MM-DD
@GetMapping("/date/{date}")
public ResponseEntity<RsData<StudyPlanListResponse>> getStudyPlansForDate(
@AuthenticationPrincipal CustomUserDetails user,
@PathVariable @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate date) {
// 유저 아이디 추출. 지금은 임시값 적용
// Long userId = user.getId();
Long userId = 1L; // 임시로 userId를 1로 설정

List<StudyPlanResponse> plans = studyPlanService.getStudyPlansForDate(userId, date);
StudyPlanListResponse response = new StudyPlanListResponse(date, plans, plans.size());

return ResponseEntity.ok(RsData.success("해당 날짜의 계획을 조회했습니다.", response));
}

// 기간별 계획 조회. start, end 형식: YYYY-MM-DD
@GetMapping
public ResponseEntity<RsData<List<StudyPlanResponse>>> getStudyPlansForPeriod(
// @AuthenticationPrincipal CustomUserDetails user,
@RequestParam("start") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate startDate,
@RequestParam("end") @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate endDate) {
// Long userId = user.getId();
Long userId = 1L; // 임시

List<StudyPlanResponse> plans = studyPlanService.getStudyPlansForPeriod(userId, startDate, endDate);

return ResponseEntity.ok(RsData.success("기간별 계획을 조회했습니다.", plans));
}



// ==================== 수정 ===================
// 플랜 아이디는 원본의 아이디를 받음
// 가상인지 원본인지는 서비스에서 원본과 날짜를 대조해 판단
// 수정 적용 범위를 쿼리 파라미터로 받음 (THIS_ONLY, FROM_THIS_DATE)
@PutMapping("/{planId}")
public ResponseEntity<RsData<StudyPlanResponse>> updateStudyPlan(
// @AuthenticationPrincipal CustomUserDetails user,
@PathVariable Long planId,
@RequestBody StudyPlanRequest request,
@RequestParam(required = false, defaultValue = "THIS_ONLY") StudyPlanException.ApplyScope applyScope) {
// Long userId = user.getId();
Long userId = 1L; // 임시

StudyPlanResponse response = studyPlanService.updateStudyPlan(userId, planId, request, applyScope);
return ResponseEntity.ok(RsData.success("학습 계획이 성공적으로 수정되었습니다.", response));
}



// ==================== 삭제 ===================
@DeleteMapping("/{planId}")
public ResponseEntity<RsData<Void>> deleteStudyPlan(@PathVariable Long planId) {
//studyPlanService.deleteStudyPlan(planId);
Expand All @@ -33,5 +92,4 @@ public ResponseEntity<RsData<Void>> deleteStudyPlan(@PathVariable Long planId) {




}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.back.domain.study.plan.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.time.LocalDate;
import java.util.List;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class StudyPlanListResponse {
private LocalDate date;
private List<StudyPlanResponse> plans;
private int totalCount;
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class StudyPlanCreateRequest {
public class StudyPlanRequest {
private String subject;

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;
Expand All @@ -31,9 +32,6 @@ public class StudyPlanResponse {

private Color color;

private Long parentPlanId;
private List<StudyPlanResponse> childPlans;

// RepeatRule 정보
private RepeatRuleResponse repeatRule;

Expand All @@ -47,14 +45,14 @@ public static class RepeatRuleResponse {
private String byDay; // "MON" 형태의 문자열

@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime until;
private LocalDate untilDate;

public RepeatRuleResponse(com.back.domain.study.plan.entity.RepeatRule repeatRule) {
if (repeatRule != null) {
this.frequency = repeatRule.getFrequency();
this.repeatInterval = repeatRule.getRepeatInterval();
this.byDay = repeatRule.getByDay();
this.until = repeatRule.getUntilDate();
this.untilDate = repeatRule.getUntilDate();
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.time.LocalDateTime;
import java.time.LocalDate;

@Entity
@Getter
Expand All @@ -25,10 +25,9 @@ public class RepeatRule extends BaseEntity {
@Column(name = "interval_value", nullable = false)
private int RepeatInterval;

//필요 시 요일 지정. 여러 요일 지정 시 ,로 구분
//현재는 요일 하나만 지정하는 형태로 구현
//요일은 계획 날짜에 따라 자동 설정
@Column(name = "by_day")
private String byDay;

private LocalDateTime untilDate;
private LocalDate untilDate;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.back.domain.study.plan.entity;

import jakarta.persistence.Embeddable;
import jakarta.persistence.EnumType;
import jakarta.persistence.Enumerated;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.time.LocalDate;

@Embeddable
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class RepeatRuleEmbeddable {
@Enumerated(EnumType.STRING)
private Frequency frequency;

private Integer intervalValue;
private String byDay;
private LocalDate untilDate; // LocalDateTime → LocalDate 변경
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.time.LocalDate;
import java.time.LocalDateTime;

@Entity
Expand Down Expand Up @@ -60,4 +61,13 @@ public enum ApplyScope {
THIS_ONLY, // 이 날짜만
FROM_THIS_DATE // 이 날짜부터 이후 모든 날짜
}

@Embedded
@AttributeOverrides({
@AttributeOverride(name = "frequency", column = @Column(name = "modified_frequency")),
@AttributeOverride(name = "intervalValue", column = @Column(name = "modified_repeat_interval")),
@AttributeOverride(name = "byDay", column = @Column(name = "modified_by_day")),
@AttributeOverride(name = "untilDate", column = @Column(name = "modified_until_date"))
})
private RepeatRuleEmbeddable modifiedRepeatRule;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
package com.back.domain.study.plan.repository;

import com.back.domain.study.plan.entity.StudyPlanException;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Repository
public interface StudyPlanExceptionRepository extends JpaRepository<StudyPlanException, Long> {
// FROM_THIS_DATE 범위의 예외들 중 특정 날짜 이전의 예외 조회
@Query("SELECT spe FROM StudyPlanException spe WHERE spe.studyPlan.id = :planId " +
"AND spe.applyScope = :applyScope " +
"AND spe.exceptionDate <= :targetDate " +
"ORDER BY spe.exceptionDate DESC")
List<StudyPlanException> findByStudyPlanIdAndApplyScopeAndExceptionDateBefore(
@Param("planId") Long planId,
@Param("applyScope") StudyPlanException.ApplyScope applyScope,
@Param("targetDate") LocalDateTime targetDate);
// 특정 계획의 특정 기간 동안(start~end)의 예외를 조회
@Query("SELECT spe FROM StudyPlanException spe WHERE spe.studyPlan.id = :planId " +
"AND spe.exceptionDate BETWEEN :startDate AND :endDate " +
"ORDER BY spe.exceptionDate")
List<StudyPlanException> findByStudyPlanIdAndExceptionDateBetween(@Param("planId") Long planId,
@Param("startDate") LocalDateTime startDate,
@Param("endDate") LocalDateTime endDate);
// 특정 계획의 특정 날짜 예외 조회
@Query("SELECT spe FROM StudyPlanException spe WHERE spe.studyPlan.id = :planId " +
"AND DATE(spe.exceptionDate) = DATE(:targetDate)")
Optional<StudyPlanException> findByPlanIdAndDate(@Param("planId") Long planId,
@Param("targetDate") LocalDateTime targetDate);
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface StudyPlanRepository extends JpaRepository<StudyPlan, Integer> {
import java.util.List;

@Repository
public interface StudyPlanRepository extends JpaRepository<StudyPlan, Long> {
List<StudyPlan> findByUserId(Long userId);
}
Loading
Loading