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
20 changes: 5 additions & 15 deletions src/main/java/com/example/enjoy/controller/HomeController.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
package com.example.enjoy.controller;


import ch.qos.logback.core.model.Model;
import com.example.enjoy.dto.TrackProgressDto;
import com.example.enjoy.service.TrackService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

Expand All @@ -18,17 +15,10 @@ public class HomeController {
private final TrackService trackService;

@GetMapping("/home")
public String showMyProgress(Model model) { // 1. Model 객체를 파라미터로 추가
// TODO: 추후 Spring Security 등과 연동하여 실제 로그인한 사용자 ID를 가져와야 함
Long currentStudentId = 1L; // 2. 테스트용 임시 학생 ID 사용

// 3. 학생의 이수 현황을 계산하는 새로운 서비스 메서드 호출
List<TrackProgressDto> progressData = trackService.calculateTrackProgress(currentStudentId);

// 4. 조회된 데이터를 "progressData"라는 이름으로 모델에 추가
//model.addAttribute("progressData", progressData);

// 5. 데이터를 표시할 뷰(html)의 이름을 반환
return "home";
public List<TrackProgressDto> getProgress() {
// 1. 반환 타입을 List<TrackProgressDto>로 변경
Long currentStudentId = 1L;
// 2. 서비스 호출 후 데이터를 바로 반환
return trackService.calculateTrackProgress(currentStudentId);
}
}
28 changes: 28 additions & 0 deletions src/main/java/com/example/enjoy/controller/TrackController.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,32 @@
package com.example.enjoy.controller;

import com.example.enjoy.dto.TrackDetailDto;
import com.example.enjoy.service.TrackService;
import lombok.RequiredArgsConstructor;
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.RestController;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/tracks")
public class TrackController {

private final TrackService trackService;

/**
* 특정 트랙의 상세 정보를 조회하는 API
* @param trackId 조회할 트랙의 ID
* @return TrackDetailDto - 트랙의 상세 정보
*/
@GetMapping("/{trackId}")
public TrackDetailDto getTrackDetailsById(@PathVariable Long trackId) {

// TODO: 추후 Spring Security 연동 후 실제 로그인한 학생 ID를 가져와야 함
Long currentStudentId = 1L;

// 5. 서비스의 메서드를 호출하여 결과를 받아온 후, 그대로 반환
return trackService.getTrackDetails(currentStudentId, trackId);
}
}
5 changes: 3 additions & 2 deletions src/main/java/com/example/enjoy/dto/CourseStatusDto.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package com.example.enjoy.dto;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;

/**
* 과목 정보 DTO
* (title, year, semester, code, status)
*/
@Getter
@Setter

@Data
public class CourseStatusDto {

private String title; // 과목명 (기존 courseName)
Expand Down
18 changes: 8 additions & 10 deletions src/main/java/com/example/enjoy/dto/TrackDetailDto.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
package com.example.enjoy.dto;

import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import java.util.List;

/**
* 상세 UI 화면의 트랙 탭 하나의 전체 정보를 담는 DTO
* 새로 정의된 CourseStatusDto를 사용
*/
@Getter
@Setter
public class TrackDetailDto {

private String trackName; // 트랙 이름
private int completedCount; // 이수한 과목 수
private int requiredCount = 6; // 이수 필요 과목 수

// 리스트의 타입이 새로운 CourseStatusDto로 변경
private List<CourseStatusDto> courses;
@Data // 또는 @Getter, @Setter 등
public class TrackDetailDto {
private Long trackId;
private String trackName;
private String department;
private String description; // 트랙에 대한 설명 추가
private List<CourseStatusDto> courses; // 트랙에 포함된 과목 목록
}
2 changes: 1 addition & 1 deletion src/main/java/com/example/enjoy/entity/StudentCourse.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

@Entity
@Getter
public class StudentCourse {
public class StudentCourse { // 학생이 실제로 이수한 과목
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/example/enjoy/entity/TrackCourse.java
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package com.example.enjoy.entity;

import jakarta.persistence.*;
import lombok.Data;
import lombok.Getter;

@Entity
@Getter
@Data
public class TrackCourse {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Expand Down

This file was deleted.

This file was deleted.

11 changes: 11 additions & 0 deletions src/main/java/com/example/enjoy/repository/TrackRepository.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,21 @@
import com.example.enjoy.entity.Track;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

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

public interface TrackRepository extends JpaRepository<Track, Long> {

@Query("SELECT DISTINCT t FROM Track t LEFT JOIN FETCH t.courses")
List<Track> findAllWithCourses();

/**
* 특정 ID의 트랙을 과목 정보와 함께 조회합니다 (N+1 문제 해결).
* @param trackId 트랙 ID
* @return 트랙 정보 (Optional)
*/
@Query("SELECT t FROM Track t JOIN FETCH t.courses WHERE t.id = :trackId")
Optional<Track> findByIdWithCourses(@Param("trackId") Long trackId);
}

This file was deleted.

71 changes: 69 additions & 2 deletions src/main/java/com/example/enjoy/service/TrackService.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.example.enjoy.service;

import com.example.enjoy.dto.CourseDto;
import com.example.enjoy.dto.CourseStatusDto;
import com.example.enjoy.dto.TrackDetailDto;
import com.example.enjoy.dto.TrackProgressDto;
import com.example.enjoy.entity.StudentCourse;
import com.example.enjoy.entity.Track;
Expand All @@ -9,6 +11,7 @@
import com.example.enjoy.repository.TrackRepository;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
Expand All @@ -23,8 +26,6 @@ public class TrackService {
private final TrackRepository trackRepository;
private final StudentCourseRepository studentCourseRepository; // 기존 기능

// ... (기존의 saveStudentCoursesFromExcel, calculateTrackProgress 메서드) ...

/**
* 모든 트랙 정보를 학과별로 그룹화하여 반환하는 메서드
*/
Expand All @@ -37,6 +38,9 @@ public Map<String, List<Track>> getAllTracksGroupedByDepartment() {
.collect(Collectors.groupingBy(Track::getDepartment));
}

/**
* 학생이 이수한 과목 이름을 Set으로 반환하는 private 메서드
*/
public List<TrackProgressDto> calculateTrackProgress(Long studentId) {
// 1. 학생의 이수 과목 목록 조회
Set<String> completedCourseNames = studentCourseRepository.findByStudentId(studentId)
Expand Down Expand Up @@ -89,4 +93,67 @@ public List<TrackProgressDto> calculateTrackProgress(Long studentId) {

return progressList;
}

/**
* 학생이 이수한 과목 이름을 Set으로 반환하는 메서드
*/
@Transactional(readOnly = true)
public TrackDetailDto getTrackDetails(Long studentId, Long trackId) {

// 1. [리팩토링] 학생 이수 과목 조회 로직을 private 메서드로 호출
Set<String> completedCourseNames = getCompletedCourseNames(studentId);

// 2. ID로 트랙 정보와 소속 과목들을 한번에 조회
Track track = trackRepository.findByIdWithCourses(trackId)
.orElseThrow(() -> new IllegalArgumentException("존재하지 않는 트랙입니다."));

// 3. 트랙의 과목 목록을 CourseStatusDto 리스트로 변환
List<CourseStatusDto> courseStatusList = track.getCourses().stream()
.map(trackCourse -> {
// 4. [수정] DTO 객체 생성 및 실제 필드에 맞게 데이터 세팅
CourseStatusDto dto = new CourseStatusDto();
dto.setTitle(trackCourse.getCourseName());
// (TrackCourse 엔티티에 getCourseCode, getYear, getSemester가 있다고 가정합니다)
dto.setCode(trackCourse.getCourseCode());
dto.setYear(trackCourse.getAcademicYear());
dto.setSemester(trackCourse.getAcademicSemester());

// 5. [수정 & 리팩토링] 이수 여부를 판단하고, 그 결과에 따라 status(String) 값을 세팅
if (isCourseCompleted(trackCourse, completedCourseNames)) {
dto.setStatus("COMPLETED");
} else {
dto.setStatus("NONE");
}

return dto;
})
.collect(Collectors.toList());

// 6. 최종적으로 TrackDetailDto를 조립하여 반환
TrackDetailDto trackDetailDto = new TrackDetailDto();
trackDetailDto.setTrackId(track.getId());
trackDetailDto.setTrackName(track.getName());
trackDetailDto.setDepartment(track.getDepartment());
trackDetailDto.setCourses(courseStatusList);

return trackDetailDto;
}

/**
* 학생 ID로 해당 학생이 이수한 모든 과목명을 조회합니다.
*/
private Set<String> getCompletedCourseNames(Long studentId) {
return studentCourseRepository.findByStudentId(studentId)
.stream()
.map(StudentCourse::getCourseName)
.collect(Collectors.toSet());
}

/**
* 특정 과목이 이수 완료되었는지 확인합니다. (과목 별칭 포함)
*/
private boolean isCourseCompleted(TrackCourse course, Set<String> completedCourseNames) {
return completedCourseNames.contains(course.getCourseName()) ||
(course.getCourseAlias() != null && completedCourseNames.contains(course.getCourseAlias()));
}
}
Loading