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
@@ -0,0 +1,32 @@
package com.example.smartair.controller.homecontroller;

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

import java.util.List;

@Controller
@RequiredArgsConstructor
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";
}
}
17 changes: 17 additions & 0 deletions src/main/java/com/example/smartair/dto/CourseDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.example.smartair.dto;

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

/**
* 교과목 정보를 담는 DTO
*/
@Getter
@Setter
@AllArgsConstructor // 모든 필드를 인자로 받는 생성자 자동 생성
public class CourseDto {

private String courseName; // 현재 과목명
private String courseAlias; // 과거 과목명 (없으면 null)
}
22 changes: 22 additions & 0 deletions src/main/java/com/example/smartair/dto/TrackProgressDto.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.example.smartair.dto;

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

/**
* 하나의 트랙에 대한 학생의 이수 진행 현황 정보를 담는 DTO
*/
@Getter
@Setter
public class TrackProgressDto {

private String trackName; // 트랙 이름 (예: "AI 콘텐츠")
private String department; // 소속 학과
private int completedCount; // 이수한 과목 수
private int requiredCount; // 이수 필요 과목 수 (예: 6)
private boolean isCompleted; // 트랙 이수 완료 여부

private List<CourseDto> completedCourses; // 이수한 과목 목록
private List<CourseDto> remainingCourses; // 이수해야 할 남은 과목 목록
}
17 changes: 17 additions & 0 deletions src/main/java/com/example/smartair/entity/StudentCourse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.example.smartair.entity;

import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import lombok.Getter;

@Entity
@Getter
public class StudentCourse {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private Long studentId; // 학생 ID (로그인 연동)
private String courseName;
}
25 changes: 25 additions & 0 deletions src/main/java/com/example/smartair/entity/Track.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.example.smartair.entity;

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

import java.util.ArrayList;
import java.util.List;

@Entity
@Getter @Setter
public class Track {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String department;

@OneToMany(mappedBy = "track", cascade = CascadeType.ALL)
private List<TrackCourse> courses = new ArrayList<>();
// public void addCourse(TrackCourse course) {
// courses.add(course);
// course.setTrack(this);
// }
}
19 changes: 19 additions & 0 deletions src/main/java/com/example/smartair/entity/TrackCourse.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.example.smartair.entity;

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

@Entity
@Getter
public class TrackCourse {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String courseName; // 현재 과목명
private String courseAlias; // 구(과거) 과목명

@ManyToOne
@JoinColumn(name = "track_id")
private Track track;
// Getters and Setters
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.example.smartair.repository;

import com.example.smartair.entity.StudentCourse;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

public interface StudentCourseRepository extends JpaRepository<StudentCourse, Long> {

List<StudentCourse> findByStudentId(Long studentId);

@Transactional
void deleteByStudentId(Long studentId); // 학생 ID로 이수과목 한번에 삭제
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package com.example.smartair.repository;

import com.example.smartair.entity.TrackCourse;
import org.springframework.data.jpa.repository.JpaRepository;

public interface TrackCourseRepository extends JpaRepository<TrackCourse, Long> {
}
12 changes: 12 additions & 0 deletions src/main/java/com/example/smartair/repository/TrackRepository.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.example.smartair.repository;

import com.example.smartair.entity.Track;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;

public interface TrackRepository extends JpaRepository<Track, Long> {

@Query("SELECT DISTINCT t FROM Track t LEFT JOIN FETCH t.courses")
List<Track> findAllWithCourses();
}
92 changes: 92 additions & 0 deletions src/main/java/com/example/smartair/service/TrackService.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.example.smartair.service;

import com.example.smartair.dto.CourseDto;
import com.example.smartair.dto.TrackProgressDto;
import com.example.smartair.entity.StudentCourse;
import com.example.smartair.entity.Track;
import com.example.smartair.entity.TrackCourse;
import com.example.smartair.repository.StudentCourseRepository;
import com.example.smartair.repository.TrackRepository;
import org.springframework.stereotype.Service;
import lombok.RequiredArgsConstructor;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class TrackService {

private final TrackRepository trackRepository;
private final StudentCourseRepository studentCourseRepository; // 기존 기능

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

/**
* 모든 트랙 정보를 학과별로 그룹화하여 반환하는 메서드
*/
public Map<String, List<Track>> getAllTracksGroupedByDepartment() {
// 1. DB에서 모든 트랙과 관련 과목들을 한번에 조회
List<Track> allTracks = trackRepository.findAllWithCourses();

// 2. 조회된 트랙 리스트를 '학과' 이름으로 그룹화하여 Map으로 변환 후 반환
return allTracks.stream()
.collect(Collectors.groupingBy(Track::getDepartment));
}

public List<TrackProgressDto> calculateTrackProgress(Long studentId) {
// 1. 학생의 이수 과목 목록 조회
Set<String> completedCourseNames = studentCourseRepository.findByStudentId(studentId)
.stream()
.map(StudentCourse::getCourseName)
.collect(Collectors.toSet());

// 2. 모든 트랙 정보 조회
List<Track> allTracks = trackRepository.findAllWithCourses();

List<TrackProgressDto> progressList = new ArrayList<>();

// 3. 각 트랙별로 진행 현황 계산
for (Track track : allTracks) {

// 현재 트랙에서 완료한 과목과 남은 과목을 담을 리스트 초기화
List<CourseDto> completedInThisTrack = new ArrayList<>();
List<CourseDto> remainingInThisTrack = new ArrayList<>();

// 현재 트랙에 속한 모든 교과목을 하나씩 확인
for (TrackCourse trackCourse : track.getCourses()) {

// 학생이 해당 과목을 이수했는지 확인 (현재 이름 또는 과거 이름으로 체크)
if (completedCourseNames.contains(trackCourse.getCourseName()) ||
(trackCourse.getCourseAlias() != null && completedCourseNames.contains(trackCourse.getCourseAlias()))) {
// 이수한 경우: 완료 리스트에 추가
completedInThisTrack.add(new CourseDto(trackCourse.getCourseName(), trackCourse.getCourseAlias()));
} else {
// 이수하지 않은 경우: 남은 과목 리스트에 추가
remainingInThisTrack.add(new CourseDto(trackCourse.getCourseName(), trackCourse.getCourseAlias()));
}
}

// 최종 결과를 담을 DTO 객체 생성 및 데이터 세팅
TrackProgressDto progressDto = new TrackProgressDto();
progressDto.setTrackName(track.getName());
progressDto.setDepartment(track.getDepartment());

int completedCount = completedInThisTrack.size();
progressDto.setCompletedCount(completedCount);
progressDto.setRequiredCount(6); // 트랙 이수 요구 과목 수는 6개
progressDto.setCompleted(completedCount >= 6); // 6개 이상이면 true

progressDto.setCompletedCourses(completedInThisTrack);
progressDto.setRemainingCourses(remainingInThisTrack);

// 완성된 DTO를 최종 결과 리스트에 추가
progressList.add(progressDto);
}

return progressList;
}
}
Loading