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
Expand Up @@ -46,6 +46,8 @@ public enum SuccessCode implements BaseCode { // 성공
MAJOR_LIST_VIEW_SUCCESS(HttpStatus.OK, "MAJOR_2007", "전공 전체 조회 완료."),
MAJOR_UNIV_LIKED_LIST_VIEW_SUCCESS(HttpStatus.OK, "MAJOR_UNIV_2006", "전공별 대학-전공 북마크 조회 완료"),
MAJOR_UNIV_LIST_BY_MAJOR_SUCCESS(HttpStatus.OK, "MAJOR_UNIV_2007", "전공 기준 대학 목록 조회 완료"),
FIELD_MAJOR_LIST_BY_FIELD_SUCCESS(HttpStatus.OK, "FIELD_MAJOR_2007", "계열 기준 전공 목록 조회 완료"),
MAJOR_UNIV_BOOKMARK_LIST_SUCCESS(HttpStatus.OK, "UNIV_MAJOR_2008", "전공+대학 북마크 목록 조회 완료"),

// 내가 추가한 코드
TOKEN_PROCESS_SUCCESS(HttpStatus.OK, "TOKEN_2001", "코인(토큰) 사용이 완료되었습니다.");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,16 +5,16 @@
import hackerthon.likelion13th.canfly.global.api.SuccessCode;
import hackerthon.likelion13th.canfly.login.auth.mapper.CustomUserDetails;
import hackerthon.likelion13th.canfly.login.service.UserService;
import hackerthon.likelion13th.canfly.search.dto.MajorDto;
import hackerthon.likelion13th.canfly.search.service.FieldService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Tag(name = "계열 북마크 관련 컨트롤러", description = "계열 북마크 컨트롤러입니다")
@RestController
Expand All @@ -38,4 +38,18 @@ public ApiResponse<Boolean> toggleLike(

return ApiResponse.onSuccess(SuccessCode.FIELD_LIKE_SUCCESS, true);
}

@Operation(summary = "계열에 포함된 전공 목록",
description = "계열(fieldId)에 속한 전공(major) 목록을 반환합니다.")
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.
ApiResponse(responseCode = "FIELD_MAJOR_2007", description = "계열 기준 전공 목록 조회 완료")
})
@GetMapping("/majors")
public ApiResponse<List<MajorDto>> getMajorsByField(
@PathVariable Long fieldId
) {
List<MajorDto> result = fieldService.getMajorsByField(fieldId);
return ApiResponse.onSuccess(SuccessCode.FIELD_MAJOR_LIST_BY_FIELD_SUCCESS, result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import hackerthon.likelion13th.canfly.login.auth.mapper.CustomUserDetails;
import hackerthon.likelion13th.canfly.login.service.UserService;
import hackerthon.likelion13th.canfly.search.dto.MajorDto;
import hackerthon.likelion13th.canfly.search.dto.UnivMajorTupleDto;
import hackerthon.likelion13th.canfly.search.service.MajorService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
Expand Down Expand Up @@ -54,4 +55,19 @@ public ApiResponse<List<MajorDto>> getMajors(

return ApiResponse.onSuccess(SuccessCode.MAJOR_LIST_VIEW_SUCCESS, majors);
}

@Operation(summary = "전공+대학 북마크 전체",
description = "로그인 사용자의 전공+대학 북마크 목록을 반환합니다. (univ_id IS NOT NULL)")
@ApiResponses({
@io.swagger.v3.oas.annotations.responses.
ApiResponse(responseCode = "MAJOR_UNIV_BOOKMARK_2008", description = "전공+대학 북마크 목록 조회 완료")
})
@GetMapping("/univ/list")
public ApiResponse<List<UnivMajorTupleDto>> getLikedMajorUnivList(
@AuthenticationPrincipal CustomUserDetails customUserDetails
) {
User user = userService.findUserByProviderId(customUserDetails.getUsername());
List<UnivMajorTupleDto> result = majorService.getAllBookmarkedMajorUnivPairs(user);
return ApiResponse.onSuccess(SuccessCode.MAJOR_UNIV_BOOKMARK_LIST_SUCCESS, result);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package hackerthon.likelion13th.canfly.search.dto;


import lombok.*;

import java.util.List;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class UnivMajorTupleDto {
private Long majorId;
private Long univId;
private List<String> name;
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import hackerthon.likelion13th.canfly.domain.field.Field;
import hackerthon.likelion13th.canfly.domain.field.FieldBookmark;
import hackerthon.likelion13th.canfly.domain.user.User;
import io.lettuce.core.dynamic.annotation.Param;
import org.springframework.data.repository.query.Param;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import hackerthon.likelion13th.canfly.domain.major.MajorBookmark;
import hackerthon.likelion13th.canfly.domain.university.University;
import hackerthon.likelion13th.canfly.domain.user.User;
import io.lettuce.core.dynamic.annotation.Param;
import org.springframework.data.repository.query.Param;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
Expand Down Expand Up @@ -50,4 +50,22 @@ ORDER BY COALESCE(MAX(mb.created_at), '1000-01-01 00:00:00') DESC,
MAX(mb.mb_id) DESC
""", nativeQuery = true)
List<Object[]> findAllLikedMajors(@Param("userId") String userId);

@Query(value = """
SELECT mb.m_id AS majorId,
mb.univ_id AS univId,
u.univ_name AS universityName,
m.m_name AS majorName,
MAX(mb.created_at) AS lastCreatedAt, -- 정렬용
MAX(mb.mb_id) AS lastMbId -- 보조 정렬
FROM major_bookmark mb
JOIN university u ON u.univ_id = mb.univ_id
JOIN major m ON m.m_id = mb.m_id
WHERE mb.uid = :userId
AND mb.univ_id IS NOT NULL
GROUP BY mb.m_id, mb.univ_id, u.univ_name, m.m_name
ORDER BY COALESCE(MAX(mb.created_at), '1000-01-01 00:00:00') DESC,
MAX(mb.mb_id) DESC
""", nativeQuery = true)
List<Object[]> findAllBookmarkedMajorUnivPairs(@Param("userId") String userId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,20 @@

import hackerthon.likelion13th.canfly.domain.major.Major;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import io.lettuce.core.dynamic.annotation.Param;

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

public interface MajorRepository extends JpaRepository<Major, Long> {
Optional<Major> findByCode(Integer code); // m_code == majorSeq

@Query(value = """
SELECT m.m_id AS id, m.m_name AS name
FROM major m
WHERE m.f_id = :fieldId
ORDER BY m.m_name
""", nativeQuery = true)
List<Object[]> findMajorsByFieldId(@Param("fieldId") Long fieldId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@
import hackerthon.likelion13th.canfly.global.api.ErrorCode;
import hackerthon.likelion13th.canfly.global.exception.GeneralException;
import hackerthon.likelion13th.canfly.search.dto.FieldDto;
import hackerthon.likelion13th.canfly.search.dto.MajorDto;
import hackerthon.likelion13th.canfly.search.repository.FieldBookmarkRepository;
import hackerthon.likelion13th.canfly.search.repository.FieldRepository;
import hackerthon.likelion13th.canfly.search.repository.MajorRepository;
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
Expand All @@ -20,6 +22,7 @@
public class FieldService {
private final FieldBookmarkRepository fieldBookmarkRepository;
private final FieldRepository fieldRepository;
private final MajorRepository majorRepository;

@Transactional
public Field toggleFieldLike(Long fieldId, User user) {
Expand Down Expand Up @@ -55,4 +58,14 @@ public List<FieldDto> getAllFields() {
.map(f -> new FieldDto(f.getId(), f.getName()))
.toList();
}

public List<MajorDto> getMajorsByField(Long fieldId) {
List<Object[]> rows = majorRepository.findMajorsByFieldId(fieldId);
return rows.stream()
.map(r -> new MajorDto(
((Number) r[0]).longValue(), // m_id
(String) r[1] // m_name
))
.toList();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import hackerthon.likelion13th.canfly.global.exception.GeneralException;
import hackerthon.likelion13th.canfly.search.dto.MajorDto;
import hackerthon.likelion13th.canfly.search.dto.UnivDto;
import hackerthon.likelion13th.canfly.search.dto.UnivMajorTupleDto;
import hackerthon.likelion13th.canfly.search.repository.MajorBookmarkRepository;
import hackerthon.likelion13th.canfly.search.repository.MajorRepository;
import hackerthon.likelion13th.canfly.university.repository.UniversityRepository;
Expand Down Expand Up @@ -80,4 +81,21 @@ public List<UnivDto> getUniversitiesByMajor(Long majorId) {
))
.toList();
}

public List<UnivMajorTupleDto> getAllBookmarkedMajorUnivPairs(User user) {
List<Object[]> rows = majorBookmarkRepository.findAllBookmarkedMajorUnivPairs(user.getUid());
return rows.stream()
.map(r -> {
Long mId = ((Number) r[0]).longValue();
Long univId = ((Number) r[1]).longValue();
String univName = (String) r[2];
String majorName= (String) r[3];
return UnivMajorTupleDto.builder()
.majorId(mId)
.univId(univId)
.name(List.of(univName, majorName))
.build();
})
.toList();
}
}