diff --git a/src/main/java/com/kusitms/website/domain/admin/AdminController.java b/src/main/java/com/kusitms/website/domain/admin/AdminController.java index 17e1a35..2db0631 100644 --- a/src/main/java/com/kusitms/website/domain/admin/AdminController.java +++ b/src/main/java/com/kusitms/website/domain/admin/AdminController.java @@ -29,6 +29,16 @@ public class AdminController { private final AdminService adminService; private final JwtTokenProvider jwtTokenProvider; + @GetMapping("/admin/introductions") + @Operation(summary = "학회 소개 정보 조회", description = "학회 소개 페이지의 현재 저장된 정보를 조회합니다.") + @ApiResponses(value = { + @ApiResponse(responseCode = "200", description = "조회 성공"), + @ApiResponse(responseCode = "500", description = "INTER SERVER ERROR", content = @Content(schema = @Schema(implementation = BaseResponse.class))), + }) + public ResponseEntity getIntroduction() { + return ResponseEntity.ok(new BaseResponse(introService.getAdminIntroduction())); + } + @Hidden @PostMapping(value = "/admin/introductions", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public ResponseEntity addIntroduction(@ModelAttribute IntroRequest request) { diff --git a/src/main/java/com/kusitms/website/domain/introduction/IntroService.java b/src/main/java/com/kusitms/website/domain/introduction/IntroService.java index 516f36d..f173002 100644 --- a/src/main/java/com/kusitms/website/domain/introduction/IntroService.java +++ b/src/main/java/com/kusitms/website/domain/introduction/IntroService.java @@ -1,28 +1,22 @@ package com.kusitms.website.domain.introduction; import com.kusitms.website.domain.file.S3Service; +import com.kusitms.website.domain.introduction.dto.request.ActivityRequest; import com.kusitms.website.domain.introduction.dto.request.ExpertLectureRequest; import com.kusitms.website.domain.introduction.dto.request.IntroRequest; import com.kusitms.website.domain.introduction.dto.request.ManagementTeamRequest; import com.kusitms.website.domain.introduction.dto.request.OBLectureRequest; -import com.kusitms.website.domain.introduction.dto.response.ExpertLectureResponse; -import com.kusitms.website.domain.introduction.dto.response.IntroResponse; -import com.kusitms.website.domain.introduction.dto.response.ManagementTeamResponse; -import com.kusitms.website.domain.introduction.dto.response.OBLectureResponse; -import com.kusitms.website.domain.introduction.entity.ExpertLecture; -import com.kusitms.website.domain.introduction.entity.Introduction; -import com.kusitms.website.domain.introduction.entity.ManageTeam; -import com.kusitms.website.domain.introduction.entity.OBLecture; -import com.kusitms.website.domain.introduction.repository.ExpertLectureRepository; -import com.kusitms.website.domain.introduction.repository.IntroRepository; -import com.kusitms.website.domain.introduction.repository.ManageTeamRepository; -import com.kusitms.website.domain.introduction.repository.OBLectureRepository; +import com.kusitms.website.domain.introduction.dto.response.*; +import com.kusitms.website.domain.introduction.entity.*; +import com.kusitms.website.domain.introduction.repository.*; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import java.util.List; import java.util.stream.Collectors; +import javax.persistence.EntityNotFoundException; @Service @RequiredArgsConstructor @@ -34,90 +28,241 @@ public class IntroService { private final ManageTeamRepository manageTeamRepository; private final ExpertLectureRepository expertLectureRepository; private final OBLectureRepository obLectureRepository; - + private final PartnerLogoRepository partnerLogoRepository; + private final IntroMeetupImageRepository introMeetupImageRepository; + private final ActivityRepository activityRepository; + private final SponsorRepository sponsorRepository; private final String dirName = "intro"; @Transactional(readOnly = true) public IntroResponse getIntroduction() { - // 학회 소개 페이지 정보는 단일 - Introduction intro = introRepository.findAll().get(0); + Introduction intro = introRepository.findAll().stream().findFirst() + .orElseThrow(() -> new EntityNotFoundException("학회 소개 정보가 존재하지 않습니다.")); List managementTeamResponses = intro.getManageTeam().stream() - .map(ManagementTeamResponse :: fromEntity) + .map(ManagementTeamResponse::fromEntity) .collect(Collectors.toList()); List expertLectureResponses = intro.getExpertLecture().stream() - .map(ExpertLectureResponse :: fromEntity) + .map(ExpertLectureResponse::fromEntity) .collect(Collectors.toList()); List obLectureResponses = intro.getObLecture().stream() - .map(OBLectureResponse :: fromEntity) + .map(OBLectureResponse::fromEntity) + .collect(Collectors.toList()); + + List partnerLogoUrls = intro.getPartnerLogos().stream() + .map(PartnerLogo::getImageUrl) .collect(Collectors.toList()); - return IntroResponse.fromEntity(intro, managementTeamResponses, expertLectureResponses, obLectureResponses); + List meetupImageUrls = intro.getMeetupImages().stream() + .map(IntroMeetupImage::getImageUrl) + .collect(Collectors.toList()); + + List activityResponses = intro.getActivities().stream() + .map(ActivityResponse::fromEntity) + .collect(Collectors.toList()); + + List sponsorImageUrls = intro.getSponsors().stream() + .map(Sponsor::getImageUrl) + .collect(Collectors.toList()); + + return IntroResponse.fromEntity(intro, partnerLogoUrls, meetupImageUrls, + managementTeamResponses, expertLectureResponses, obLectureResponses, + activityResponses, sponsorImageUrls); } - @Transactional() - public void save(IntroRequest request) { - String partnerImageUrl = s3Service.uploadFile(request.getPartnerLogoFile(), dirName); - Introduction introduction = IntroRequest.from(request, partnerImageUrl); - introRepository.save(introduction); + @Transactional(readOnly = true) + public AdminIntroResponse getAdminIntroduction() { + Introduction intro = introRepository.findAll().stream().findFirst() + .orElseThrow(() -> new EntityNotFoundException("학회 소개 정보가 존재하지 않습니다.")); + + List teams = intro.getManageTeam().stream() + .map(ManagementTeamResponse::fromEntity) + .collect(Collectors.toList()); - List manageTeam = request.getTeams().stream() - .map(team -> ManagementTeamRequest.from(team, s3Service.uploadFile(team.getImageFile(), dirName), introduction)) + List expertLectures = intro.getExpertLecture().stream() + .map(ExpertLectureResponse::fromEntity) .collect(Collectors.toList()); - List expertLecture = request.getExpertLecture().stream() - .map(lecture -> ExpertLectureRequest.from(lecture, s3Service.uploadFile(lecture.getImageFile(), dirName), introduction)) + List obLectures = intro.getObLecture().stream() + .map(OBLectureResponse::fromEntity) .collect(Collectors.toList()); - List obLecture = request.getObLecture().stream() - .map(lecture -> OBLectureRequest.from(lecture, s3Service.uploadFile(lecture.getImageFile(), dirName), introduction)) + List partnerLogoUrls = intro.getPartnerLogos().stream() + .map(PartnerLogo::getImageUrl) .collect(Collectors.toList()); - manageTeamRepository.saveAll(manageTeam); - expertLectureRepository.saveAll(expertLecture); - obLectureRepository.saveAll(obLecture); + List meetupImageUrls = intro.getMeetupImages().stream() + .map(IntroMeetupImage::getImageUrl) + .collect(Collectors.toList()); + + List activityResponses = intro.getActivities().stream() + .map(ActivityResponse::fromEntity) + .collect(Collectors.toList()); + + List sponsorImageUrls = intro.getSponsors().stream() + .map(Sponsor::getImageUrl) + .collect(Collectors.toList()); + + return AdminIntroResponse.fromEntity(intro, partnerLogoUrls, meetupImageUrls, + activityResponses, teams, expertLectures, obLectures, sponsorImageUrls); + } + + @Transactional + public void save(IntroRequest request) { + String bannerImageUrl = uploadIfPresent(request.getBannerImageFile()); + String planningImageUrl = uploadIfPresent(request.getPlanningImage()); + String designImageUrl = uploadIfPresent(request.getDesignImage()); + String frontendImageUrl = uploadIfPresent(request.getFrontendImage()); + String backendImageUrl = uploadIfPresent(request.getBackendImage()); + + Introduction introduction = IntroRequest.from(request, null, + bannerImageUrl, planningImageUrl, designImageUrl, frontendImageUrl, backendImageUrl); + introRepository.save(introduction); - return; + saveManageTeams(request, introduction); + saveExpertLectures(request, introduction); + saveOBLectures(request, introduction); + savePartnerLogos(request.getPartnerLogoFiles(), introduction); + saveMeetupImages(request.getMeetupImages(), introduction); + saveActivities(request.getActivities(), introduction); + saveSponsors(request.getSponsors(), introduction); } - @Transactional() + @Transactional public void updateIntroduction(IntroRequest request) { - String partnerImageUrl = s3Service.uploadFile(request.getPartnerLogoFile(), dirName); - Introduction introduction = introRepository.findAll().get(0); + Introduction introduction = introRepository.findAll().stream().findFirst() + .orElseThrow(() -> new EntityNotFoundException("학회 소개 정보가 존재하지 않습니다.")); + + String bannerImageUrl = uploadOrKeep(request.getBannerImageFile(), introduction.getBannerImageUrl()); + String planningImageUrl = uploadOrKeep(request.getPlanningImage(), introduction.getPlanningImageUrl()); + String designImageUrl = uploadOrKeep(request.getDesignImage(), introduction.getDesignImageUrl()); + String frontendImageUrl = uploadOrKeep(request.getFrontendImage(), introduction.getFrontendImageUrl()); + String backendImageUrl = uploadOrKeep(request.getBackendImage(), introduction.getBackendImageUrl()); + introduction.update(request.getBannerCardinal(), request.getBannerStatus(), + request.getSlogan(), + bannerImageUrl, request.getMemberCount(), request.getProjectCount(), request.getUniversityCount(), - partnerImageUrl, - request.getIntroYoutubeLink()); + null, + request.getIntroYoutubeLink(), + planningImageUrl, + designImageUrl, + frontendImageUrl, + backendImageUrl); introRepository.save(introduction); - manageTeamRepository.deleteAll(); - expertLectureRepository.deleteAll(); - obLectureRepository.deleteAll(); + manageTeamRepository.deleteByIntroduction(introduction); + expertLectureRepository.deleteByIntroduction(introduction); + obLectureRepository.deleteByIntroduction(introduction); + partnerLogoRepository.deleteByIntroduction(introduction); + introMeetupImageRepository.deleteByIntroduction(introduction); + activityRepository.deleteByIntroduction(introduction); + sponsorRepository.deleteByIntroduction(introduction); + + saveManageTeams(request, introduction); + saveExpertLectures(request, introduction); + saveOBLectures(request, introduction); + savePartnerLogos(request.getPartnerLogoFiles(), introduction); + saveMeetupImages(request.getMeetupImages(), introduction); + saveActivities(request.getActivities(), introduction); + saveSponsors(request.getSponsors(), introduction); + } + + private void saveManageTeams(IntroRequest request, Introduction introduction) { + if (request.getTeams() == null) return; + List manageTeams = request.getTeams().stream() + .map(team -> { + String imageUrl = uploadIfPresent(team.getImageFile()); + return ManagementTeamRequest.from(team, imageUrl, introduction); + }) + .collect(Collectors.toList()); + manageTeamRepository.saveAll(manageTeams); + } + + private void saveExpertLectures(IntroRequest request, Introduction introduction) { + if (request.getExpertLecture() == null) return; + List expertLectures = request.getExpertLecture().stream() + .map(lecture -> { + String imageUrl = uploadIfPresent(lecture.getImageFile()); + return ExpertLectureRequest.from(lecture, imageUrl, introduction); + }) + .collect(Collectors.toList()); + expertLectureRepository.saveAll(expertLectures); + } - List manageTeam = request.getTeams().stream() - .map(team -> ManagementTeamRequest.from(team, s3Service.uploadFile(team.getImageFile(), dirName), introduction)) + private void saveOBLectures(IntroRequest request, Introduction introduction) { + if (request.getObLecture() == null) return; + List obLectures = request.getObLecture().stream() + .map(lecture -> { + String imageUrl = uploadIfPresent(lecture.getImageFile()); + return OBLectureRequest.from(lecture, imageUrl, introduction); + }) .collect(Collectors.toList()); + obLectureRepository.saveAll(obLectures); + } - List expertLecture = request.getExpertLecture().stream() - .map(lecture -> ExpertLectureRequest.from(lecture, s3Service.uploadFile(lecture.getImageFile(), dirName), introduction)) + private void savePartnerLogos(List files, Introduction introduction) { + if (files == null) return; + List logos = files.stream() + .filter(f -> f != null && !f.isEmpty()) + .map(f -> PartnerLogo.builder() + .introduction(introduction) + .imageUrl(s3Service.uploadFile(f, dirName)) + .build()) .collect(Collectors.toList()); + partnerLogoRepository.saveAll(logos); + } - List obLecture = request.getObLecture().stream() - .map(lecture -> OBLectureRequest.from(lecture, s3Service.uploadFile(lecture.getImageFile(), dirName), introduction)) + private void saveMeetupImages(List files, Introduction introduction) { + if (files == null) return; + List images = files.stream() + .filter(f -> f != null && !f.isEmpty()) + .map(f -> IntroMeetupImage.builder() + .introduction(introduction) + .imageUrl(s3Service.uploadFile(f, dirName)) + .build()) .collect(Collectors.toList()); + introMeetupImageRepository.saveAll(images); + } - manageTeamRepository.saveAll(manageTeam); - expertLectureRepository.saveAll(expertLecture); - obLectureRepository.saveAll(obLecture); + private void saveActivities(List activityRequests, Introduction introduction) { + if (activityRequests == null) return; + List activities = activityRequests.stream() + .map(req -> { + String imageUrl1 = uploadIfPresent(req.getImageFile1()); + String imageUrl2 = uploadIfPresent(req.getImageFile2()); + return ActivityRequest.from(req, imageUrl1, imageUrl2, introduction); + }) + .collect(Collectors.toList()); + activityRepository.saveAll(activities); + } - return; + private void saveSponsors(List files, Introduction introduction) { + if (files == null) return; + List sponsors = files.stream() + .filter(f -> f != null && !f.isEmpty()) + .map(f -> Sponsor.builder() + .introduction(introduction) + .imageUrl(s3Service.uploadFile(f, dirName)) + .build()) + .collect(Collectors.toList()); + sponsorRepository.saveAll(sponsors); } -} + private String uploadIfPresent(MultipartFile file) { + if (file == null || file.isEmpty()) return null; + return s3Service.uploadFile(file, dirName); + } + + private String uploadOrKeep(MultipartFile file, String existingUrl) { + if (file == null || file.isEmpty()) return existingUrl; + return s3Service.uploadFile(file, dirName); + } +} \ No newline at end of file diff --git a/src/main/java/com/kusitms/website/domain/introduction/dto/request/ActivityRequest.java b/src/main/java/com/kusitms/website/domain/introduction/dto/request/ActivityRequest.java new file mode 100644 index 0000000..128dff5 --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/introduction/dto/request/ActivityRequest.java @@ -0,0 +1,36 @@ +package com.kusitms.website.domain.introduction.dto.request; + +import com.kusitms.website.domain.introduction.entity.Activity; +import com.kusitms.website.domain.introduction.entity.Introduction; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Getter; +import lombok.Setter; +import org.springframework.web.multipart.MultipartFile; + +@Getter +@Setter +@Schema +public class ActivityRequest { + @Schema(description = "활동명", example = "밋업데이") + private String name; + + @Schema(description = "활동 이미지 1") + private MultipartFile imageFile1; + + @Schema(description = "활동 이미지 2") + private MultipartFile imageFile2; + + @Schema(description = "활동 설명글", example = "밋업데이는 ~입니다.") + private String description; + + public static Activity from(ActivityRequest request, String imageUrl1, String imageUrl2, + Introduction introduction) { + return Activity.builder() + .name(request.getName()) + .imageUrl1(imageUrl1) + .imageUrl2(imageUrl2) + .description(request.getDescription()) + .introduction(introduction) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kusitms/website/domain/introduction/dto/request/IntroRequest.java b/src/main/java/com/kusitms/website/domain/introduction/dto/request/IntroRequest.java index 97d7ee7..cbdc618 100644 --- a/src/main/java/com/kusitms/website/domain/introduction/dto/request/IntroRequest.java +++ b/src/main/java/com/kusitms/website/domain/introduction/dto/request/IntroRequest.java @@ -7,20 +7,25 @@ import lombok.Setter; import org.springframework.web.multipart.MultipartFile; -import java.util.ArrayList; import java.util.List; @Getter @Setter -@Schema +@Schema(description = "학회 소개 요청") public class IntroRequest { @Schema(description = "배너 내에 삽입되는 기수", example = "27") private Long bannerCardinal; - @Schema(description = "배너 상태 (대문자 영문 코드)", example = "CLOSE/MANAGEMENT_RECRUIT/MEMBER_RECRUIT") + @Schema(description = "배너 상태 (대문자 영문 코드)", example = "CLOSE") private BannerStatus bannerStatus; - @Schema(description = "누적 학회원 수 ", example = "1432") + @Schema(description = "슬로건", example = "큐시즘, 함께 성장하는 IT 학회") + private String slogan; + + @Schema(description = "배너 이미지 파일") + private MultipartFile bannerImageFile; + + @Schema(description = "누적 학회원 수", example = "1432") private Long memberCount; @Schema(description = "누적 프로젝트 결과물 수", example = "322") @@ -32,27 +37,57 @@ public class IntroRequest { @Schema(description = "학회 소개 영상", example = "https://www.youtube.com/") private String introYoutubeLink; + @Schema(description = "기획 이미지 파일") + private MultipartFile planningImage; + + @Schema(description = "디자인 이미지 파일") + private MultipartFile designImage; + + @Schema(description = "프론트 이미지 파일") + private MultipartFile frontendImage; + + @Schema(description = "백엔드 이미지 파일") + private MultipartFile backendImage; + @Schema(description = "학회 운영진 소개") - private List teams = new ArrayList<>();; + private List teams; @Schema(description = "전문가 초청 강연자 소개") - private List expertLecture = new ArrayList<>(); + private List expertLecture; + + @Schema(description = "OB 초청 강연자 소개") + private List obLecture; + + @Schema(description = "파트너사 로고 이미지 파일 목록") + private List partnerLogoFiles; + + @Schema(description = "밋업 이미지 파일 목록") + private List meetupImages; - @Schema(description = "ob 초청 강연자 소개") - private List obLecture = new ArrayList<>(); + @Schema(description = "활동 소개 목록") + private List activities; - @Schema(description = "파트너사 소개 이미지 파일") - private MultipartFile partnerLogoFile; + @Schema(description = "후원사 이미지 파일 목록") + private List sponsors; - public static Introduction from(IntroRequest request, String partnerImageUrl) { + public static Introduction from(IntroRequest request, String partnerImageUrl, + String bannerImageUrl, + String planningImageUrl, String designImageUrl, + String frontendImageUrl, String backendImageUrl) { return Introduction.builder() .bannerCardinal(request.getBannerCardinal()) .bannerStatus(request.getBannerStatus()) + .slogan(request.getSlogan()) + .bannerImageUrl(bannerImageUrl) .memberCount(request.getMemberCount()) .projectCount(request.getProjectCount()) .universityCount(request.getUniversityCount()) .introYoutubeLink(request.getIntroYoutubeLink()) .partnerImageUrl(partnerImageUrl) + .planningImageUrl(planningImageUrl) + .designImageUrl(designImageUrl) + .frontendImageUrl(frontendImageUrl) + .backendImageUrl(backendImageUrl) .build(); } } diff --git a/src/main/java/com/kusitms/website/domain/introduction/dto/response/ActivityResponse.java b/src/main/java/com/kusitms/website/domain/introduction/dto/response/ActivityResponse.java new file mode 100644 index 0000000..ae39821 --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/introduction/dto/response/ActivityResponse.java @@ -0,0 +1,35 @@ +package com.kusitms.website.domain.introduction.dto.response; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.kusitms.website.domain.introduction.entity.Activity; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +@Schema +public class ActivityResponse { + @Schema(description = "활동명", example = "밋업데이") + private String name; + + @JsonProperty("image_url1") + @Schema(description = "활동 이미지 1 URL") + private String imageUrl1; + + @JsonProperty("image_url2") + @Schema(description = "활동 이미지 2 URL") + private String imageUrl2; + + @Schema(description = "활동 설명글") + private String description; + + public static ActivityResponse fromEntity(Activity activity) { + return ActivityResponse.builder() + .name(activity.getName()) + .imageUrl1(activity.getImageUrl1()) + .imageUrl2(activity.getImageUrl2()) + .description(activity.getDescription()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kusitms/website/domain/introduction/dto/response/AdminIntroResponse.java b/src/main/java/com/kusitms/website/domain/introduction/dto/response/AdminIntroResponse.java new file mode 100644 index 0000000..cb0d9a9 --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/introduction/dto/response/AdminIntroResponse.java @@ -0,0 +1,118 @@ +package com.kusitms.website.domain.introduction.dto.response; + +import com.fasterxml.jackson.annotation.JsonProperty; +import com.kusitms.website.domain.introduction.entity.Introduction; +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Builder; +import lombok.Getter; + +import java.util.List; + +@Getter +@Builder +@Schema +public class AdminIntroResponse { + @JsonProperty("banner_cardinal") + @Schema(description = "배너 기수") + private Long bannerCardinal; + + @JsonProperty("banner_status") + @Schema(description = "배너 상태") + private String bannerStatus; + + @Schema(description = "슬로건") + private String slogan; + + @JsonProperty("banner_image_url") + @Schema(description = "배너 이미지 URL") + private String bannerImageUrl; + + @JsonProperty("member_count") + @Schema(description = "누적 학회원 수") + private Long memberCount; + + @JsonProperty("project_count") + @Schema(description = "누적 프로젝트 수") + private Long projectCount; + + @JsonProperty("university_count") + @Schema(description = "참여 대학 수") + private Long universityCount; + + @JsonProperty("intro_youtube_link") + @Schema(description = "학회 소개 영상") + private String introYoutubeLink; + + @JsonProperty("planning_image_url") + @Schema(description = "기획 이미지 URL") + private String planningImageUrl; + + @JsonProperty("design_image_url") + @Schema(description = "디자인 이미지 URL") + private String designImageUrl; + + @JsonProperty("frontend_image_url") + @Schema(description = "프론트 이미지 URL") + private String frontendImageUrl; + + @JsonProperty("backend_image_url") + @Schema(description = "백엔드 이미지 URL") + private String backendImageUrl; + + @JsonProperty("partner_logo_urls") + @Schema(description = "파트너사 로고 이미지 URL 목록") + private List partnerLogoUrls; + + @JsonProperty("meetup_image_urls") + @Schema(description = "밋업 이미지 URL 목록") + private List meetupImageUrls; + + @Schema(description = "활동 소개 목록") + private List activities; + + @Schema(description = "운영진 소개") + private List teams; + + @JsonProperty("expert_lecture") + @Schema(description = "전문가 초청 강연자 소개") + private List expertLecture; + + @JsonProperty("ob_lecture") + @Schema(description = "OB 초청 강연자 소개") + private List obLecture; + + @JsonProperty("sponsor_image_urls") + @Schema(description = "후원사 이미지 URL 목록") + private List sponsorImageUrls; + + public static AdminIntroResponse fromEntity(Introduction intro, + List partnerLogoUrls, + List meetupImageUrls, + List activities, + List teams, + List expertLecture, + List obLecture, + List sponsorImageUrls) { + return AdminIntroResponse.builder() + .bannerCardinal(intro.getBannerCardinal()) + .bannerStatus(intro.getBannerStatus() != null ? intro.getBannerStatus().name() : null) + .slogan(intro.getSlogan()) + .bannerImageUrl(intro.getBannerImageUrl()) + .memberCount(intro.getMemberCount()) + .projectCount(intro.getProjectCount()) + .universityCount(intro.getUniversityCount()) + .introYoutubeLink(intro.getIntroYoutubeLink()) + .planningImageUrl(intro.getPlanningImageUrl()) + .designImageUrl(intro.getDesignImageUrl()) + .frontendImageUrl(intro.getFrontendImageUrl()) + .backendImageUrl(intro.getBackendImageUrl()) + .partnerLogoUrls(partnerLogoUrls) + .meetupImageUrls(meetupImageUrls) + .activities(activities) + .teams(teams) + .expertLecture(expertLecture) + .obLecture(obLecture) + .sponsorImageUrls(sponsorImageUrls) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/kusitms/website/domain/introduction/dto/response/IntroResponse.java b/src/main/java/com/kusitms/website/domain/introduction/dto/response/IntroResponse.java index 8220775..2a0c1c1 100644 --- a/src/main/java/com/kusitms/website/domain/introduction/dto/response/IntroResponse.java +++ b/src/main/java/com/kusitms/website/domain/introduction/dto/response/IntroResponse.java @@ -20,6 +20,13 @@ public class IntroResponse { @Schema(description = "배너 내용", example = "KUSITMS 27기 리크루팅 종료") private String bannerContent; + @Schema(description = "슬로건") + private String slogan; + + @JsonProperty("banner_image_url") + @Schema(description = "배너 이미지 URL") + private String bannerImageUrl; + @JsonProperty("member_count") @Schema(description = "누적 학회원 수", example = "1432") private Long memberCount; @@ -36,9 +43,29 @@ public class IntroResponse { @Schema(description = "학회 소개 영상", example = "https://www.youtube.com/") private String introYoutubeLink; - @JsonProperty("parent_logo_url") - @Schema(description = "파트너사 소개 이미지 URL") - private String partnerLogoUrl; + @JsonProperty("planning_image_url") + @Schema(description = "기획 이미지 URL") + private String planningImageUrl; + + @JsonProperty("design_image_url") + @Schema(description = "디자인 이미지 URL") + private String designImageUrl; + + @JsonProperty("frontend_image_url") + @Schema(description = "프론트 이미지 URL") + private String frontendImageUrl; + + @JsonProperty("backend_image_url") + @Schema(description = "백엔드 이미지 URL") + private String backendImageUrl; + + @JsonProperty("partner_logo_urls") + @Schema(description = "파트너사 로고 이미지 URL 목록") + private List partnerLogoUrls; + + @JsonProperty("meetup_image_urls") + @Schema(description = "밋업 이미지 URL 목록") + private List meetupImageUrls; @Schema(description = "학회 운영진 소개") private List teams; @@ -51,21 +78,43 @@ public class IntroResponse { @Schema(description = "ob 초청 강연자 소개") private List obLecture; - public static IntroResponse fromEntity(Introduction introduction, List managementTeam, - List expertLecture, List obLecture) { + @Schema(description = "활동 소개 목록") + private List activities; + + @JsonProperty("sponsor_image_urls") + @Schema(description = "후원사 이미지 URL 목록") + private List sponsorImageUrls; + + public static IntroResponse fromEntity(Introduction introduction, + List partnerLogoUrls, + List meetupImageUrls, + List managementTeam, + List expertLecture, + List obLecture, + List activities, + List sponsorImageUrls) { return IntroResponse.builder() - .bannerStatus(introduction.getBannerStatus().getName()) - .bannerContent("KUSITMS" - + introduction.getBannerCardinal() + "기 " - + introduction.getBannerStatus().getContent()) + .bannerStatus(introduction.getBannerStatus() != null ? introduction.getBannerStatus().getName() : null) + .bannerContent(introduction.getBannerStatus() != null + ? "KUSITMS" + introduction.getBannerCardinal() + "기 " + introduction.getBannerStatus().getContent() + : null) + .slogan(introduction.getSlogan()) + .bannerImageUrl(introduction.getBannerImageUrl()) .memberCount(introduction.getMemberCount()) .projectCount(introduction.getProjectCount()) .universityCount(introduction.getUniversityCount()) .introYoutubeLink(introduction.getIntroYoutubeLink()) - .partnerLogoUrl(introduction.getPartnerImageUrl()) + .planningImageUrl(introduction.getPlanningImageUrl()) + .designImageUrl(introduction.getDesignImageUrl()) + .frontendImageUrl(introduction.getFrontendImageUrl()) + .backendImageUrl(introduction.getBackendImageUrl()) + .partnerLogoUrls(partnerLogoUrls) + .meetupImageUrls(meetupImageUrls) .teams(managementTeam) .expertLecture(expertLecture) .obLecture(obLecture) + .activities(activities) + .sponsorImageUrls(sponsorImageUrls) .build(); } -} +} \ No newline at end of file diff --git a/src/main/java/com/kusitms/website/domain/introduction/entity/Activity.java b/src/main/java/com/kusitms/website/domain/introduction/entity/Activity.java new file mode 100644 index 0000000..fbaa757 --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/introduction/entity/Activity.java @@ -0,0 +1,44 @@ +package com.kusitms.website.domain.introduction.entity; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Activity { + @Id + @Column(name = "activity_id", nullable = false) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long activityId; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "introduction_id") + private Introduction introduction; + + @Column(nullable = false) + private String name; + + @Column(name = "image_url1") + private String imageUrl1; + + @Column(name = "image_url2") + private String imageUrl2; + + @Column(length = 500) + private String description; + + @Builder + public Activity(Introduction introduction, String name, String imageUrl1, + String imageUrl2, String description) { + this.introduction = introduction; + this.name = name; + this.imageUrl1 = imageUrl1; + this.imageUrl2 = imageUrl2; + this.description = description; + } +} \ No newline at end of file diff --git a/src/main/java/com/kusitms/website/domain/introduction/entity/IntroMeetupImage.java b/src/main/java/com/kusitms/website/domain/introduction/entity/IntroMeetupImage.java new file mode 100644 index 0000000..2ecc07a --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/introduction/entity/IntroMeetupImage.java @@ -0,0 +1,31 @@ +package com.kusitms.website.domain.introduction.entity; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class IntroMeetupImage { + @Id + @Column(name = "meetup_image_id", nullable = false) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long meetupImageId; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "introduction_id") + private Introduction introduction; + + @Column(name = "image_url") + private String imageUrl; + + @Builder + public IntroMeetupImage(Introduction introduction, String imageUrl) { + this.introduction = introduction; + this.imageUrl = imageUrl; + } +} \ No newline at end of file diff --git a/src/main/java/com/kusitms/website/domain/introduction/entity/Introduction.java b/src/main/java/com/kusitms/website/domain/introduction/entity/Introduction.java index 2ea8dd4..343e739 100644 --- a/src/main/java/com/kusitms/website/domain/introduction/entity/Introduction.java +++ b/src/main/java/com/kusitms/website/domain/introduction/entity/Introduction.java @@ -24,6 +24,10 @@ public class Introduction { @Column(name = "banner_status") @Enumerated(EnumType.STRING) private BannerStatus bannerStatus; + @Column(name = "slogan", length = 50) + private String slogan; + @Column(name = "banner_image_url") + private String bannerImageUrl; // 학회 정보 @Column(name = "member_count") @@ -37,10 +41,20 @@ public class Introduction { @Column(name = "intro_youtube_link") private String introYoutubeLink; - // 파트너사 이미지 + // 파트너사 이미지 (기존 단일 필드 유지 — 하위호환) @Column(name = "partner_image_url") private String partnerImageUrl; + // 함께하는 큐밀리 이미지 + @Column(name = "planning_image_url") + private String planningImageUrl; + @Column(name = "design_image_url") + private String designImageUrl; + @Column(name = "frontend_image_url") + private String frontendImageUrl; + @Column(name = "backend_image_url") + private String backendImageUrl; + // 운영진 소개 @OneToMany(mappedBy = "introduction", cascade = CascadeType.ALL) private List manageTeam = new ArrayList<>(); @@ -53,32 +67,62 @@ public class Introduction { @OneToMany(mappedBy = "introduction", cascade = CascadeType.ALL) private List obLecture = new ArrayList<>(); + // 파트너사 로고 목록 (배열) + @OneToMany(mappedBy = "introduction", cascade = CascadeType.ALL) + private List partnerLogos = new ArrayList<>(); + + // 밋업 이미지 목록 + @OneToMany(mappedBy = "introduction", cascade = CascadeType.ALL) + private List meetupImages = new ArrayList<>(); + + // 활동 소개 + @OneToMany(mappedBy = "introduction", cascade = CascadeType.ALL) + private List activities = new ArrayList<>(); + + // 후원사 + @OneToMany(mappedBy = "introduction", cascade = CascadeType.ALL) + private List sponsors = new ArrayList<>(); @Builder - public Introduction(Long bannerCardinal, BannerStatus bannerStatus, + public Introduction(Long bannerCardinal, BannerStatus bannerStatus, String slogan, String bannerImageUrl, Long memberCount, Long projectCount, Long universityCount, - String partnerImageUrl, String introYoutubeLink) + String partnerImageUrl, String introYoutubeLink, + String planningImageUrl, String designImageUrl, + String frontendImageUrl, String backendImageUrl) { this.bannerCardinal = bannerCardinal; this.bannerStatus = bannerStatus; + this.slogan = slogan; + this.bannerImageUrl = bannerImageUrl; this.memberCount = memberCount; this.projectCount = projectCount; this.universityCount = universityCount; this.partnerImageUrl = partnerImageUrl; this.introYoutubeLink = introYoutubeLink; + this.planningImageUrl = planningImageUrl; + this.designImageUrl = designImageUrl; + this.frontendImageUrl = frontendImageUrl; + this.backendImageUrl = backendImageUrl; } - public void update(Long bannerCardinal, BannerStatus bannerStatus, + public void update(Long bannerCardinal, BannerStatus bannerStatus, String slogan, String bannerImageUrl, Long memberCount, Long projectCount, Long universityCount, - String partnerImageUrl, String introYoutubeLink) + String partnerImageUrl, String introYoutubeLink, + String planningImageUrl, String designImageUrl, + String frontendImageUrl, String backendImageUrl) { this.bannerCardinal = bannerCardinal; this.bannerStatus = bannerStatus; + this.slogan = slogan; + this.bannerImageUrl = bannerImageUrl; this.memberCount = memberCount; this.projectCount = projectCount; this.universityCount = universityCount; this.partnerImageUrl = partnerImageUrl; this.introYoutubeLink = introYoutubeLink; + this.planningImageUrl = planningImageUrl; + this.designImageUrl = designImageUrl; + this.frontendImageUrl = frontendImageUrl; + this.backendImageUrl = backendImageUrl; } - -} +} \ No newline at end of file diff --git a/src/main/java/com/kusitms/website/domain/introduction/entity/PartnerLogo.java b/src/main/java/com/kusitms/website/domain/introduction/entity/PartnerLogo.java new file mode 100644 index 0000000..bfbeab4 --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/introduction/entity/PartnerLogo.java @@ -0,0 +1,31 @@ +package com.kusitms.website.domain.introduction.entity; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class PartnerLogo { + @Id + @Column(name = "partner_logo_id", nullable = false) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long partnerLogoId; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "introduction_id") + private Introduction introduction; + + @Column(name = "image_url") + private String imageUrl; + + @Builder + public PartnerLogo(Introduction introduction, String imageUrl) { + this.introduction = introduction; + this.imageUrl = imageUrl; + } +} \ No newline at end of file diff --git a/src/main/java/com/kusitms/website/domain/introduction/entity/Sponsor.java b/src/main/java/com/kusitms/website/domain/introduction/entity/Sponsor.java new file mode 100644 index 0000000..22d6277 --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/introduction/entity/Sponsor.java @@ -0,0 +1,31 @@ +package com.kusitms.website.domain.introduction.entity; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import javax.persistence.*; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Sponsor { + @Id + @Column(name = "sponsor_id", nullable = false) + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long sponsorId; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "introduction_id") + private Introduction introduction; + + @Column(name = "image_url") + private String imageUrl; + + @Builder + public Sponsor(Introduction introduction, String imageUrl) { + this.introduction = introduction; + this.imageUrl = imageUrl; + } +} \ No newline at end of file diff --git a/src/main/java/com/kusitms/website/domain/introduction/repository/ActivityRepository.java b/src/main/java/com/kusitms/website/domain/introduction/repository/ActivityRepository.java new file mode 100644 index 0000000..957bfc3 --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/introduction/repository/ActivityRepository.java @@ -0,0 +1,9 @@ +package com.kusitms.website.domain.introduction.repository; + +import com.kusitms.website.domain.introduction.entity.Activity; +import com.kusitms.website.domain.introduction.entity.Introduction; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface ActivityRepository extends JpaRepository { + void deleteByIntroduction(Introduction introduction); +} \ No newline at end of file diff --git a/src/main/java/com/kusitms/website/domain/introduction/repository/ExpertLectureRepository.java b/src/main/java/com/kusitms/website/domain/introduction/repository/ExpertLectureRepository.java index a1e210a..e91d0d7 100644 --- a/src/main/java/com/kusitms/website/domain/introduction/repository/ExpertLectureRepository.java +++ b/src/main/java/com/kusitms/website/domain/introduction/repository/ExpertLectureRepository.java @@ -1,7 +1,9 @@ package com.kusitms.website.domain.introduction.repository; import com.kusitms.website.domain.introduction.entity.ExpertLecture; +import com.kusitms.website.domain.introduction.entity.Introduction; import org.springframework.data.jpa.repository.JpaRepository; public interface ExpertLectureRepository extends JpaRepository { + void deleteByIntroduction(Introduction introduction); } diff --git a/src/main/java/com/kusitms/website/domain/introduction/repository/IntroMeetupImageRepository.java b/src/main/java/com/kusitms/website/domain/introduction/repository/IntroMeetupImageRepository.java new file mode 100644 index 0000000..cd141f6 --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/introduction/repository/IntroMeetupImageRepository.java @@ -0,0 +1,9 @@ +package com.kusitms.website.domain.introduction.repository; + +import com.kusitms.website.domain.introduction.entity.IntroMeetupImage; +import com.kusitms.website.domain.introduction.entity.Introduction; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface IntroMeetupImageRepository extends JpaRepository { + void deleteByIntroduction(Introduction introduction); +} \ No newline at end of file diff --git a/src/main/java/com/kusitms/website/domain/introduction/repository/ManageTeamRepository.java b/src/main/java/com/kusitms/website/domain/introduction/repository/ManageTeamRepository.java index 180c6b1..73a38fc 100644 --- a/src/main/java/com/kusitms/website/domain/introduction/repository/ManageTeamRepository.java +++ b/src/main/java/com/kusitms/website/domain/introduction/repository/ManageTeamRepository.java @@ -1,7 +1,9 @@ package com.kusitms.website.domain.introduction.repository; +import com.kusitms.website.domain.introduction.entity.Introduction; import com.kusitms.website.domain.introduction.entity.ManageTeam; import org.springframework.data.jpa.repository.JpaRepository; public interface ManageTeamRepository extends JpaRepository { + void deleteByIntroduction(Introduction introduction); } diff --git a/src/main/java/com/kusitms/website/domain/introduction/repository/OBLectureRepository.java b/src/main/java/com/kusitms/website/domain/introduction/repository/OBLectureRepository.java index 67231d2..9ce009f 100644 --- a/src/main/java/com/kusitms/website/domain/introduction/repository/OBLectureRepository.java +++ b/src/main/java/com/kusitms/website/domain/introduction/repository/OBLectureRepository.java @@ -1,7 +1,9 @@ package com.kusitms.website.domain.introduction.repository; +import com.kusitms.website.domain.introduction.entity.Introduction; import com.kusitms.website.domain.introduction.entity.OBLecture; import org.springframework.data.jpa.repository.JpaRepository; public interface OBLectureRepository extends JpaRepository { + void deleteByIntroduction(Introduction introduction); } diff --git a/src/main/java/com/kusitms/website/domain/introduction/repository/PartnerLogoRepository.java b/src/main/java/com/kusitms/website/domain/introduction/repository/PartnerLogoRepository.java new file mode 100644 index 0000000..ab2bc34 --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/introduction/repository/PartnerLogoRepository.java @@ -0,0 +1,9 @@ +package com.kusitms.website.domain.introduction.repository; + +import com.kusitms.website.domain.introduction.entity.Introduction; +import com.kusitms.website.domain.introduction.entity.PartnerLogo; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface PartnerLogoRepository extends JpaRepository { + void deleteByIntroduction(Introduction introduction); +} \ No newline at end of file diff --git a/src/main/java/com/kusitms/website/domain/introduction/repository/SponsorRepository.java b/src/main/java/com/kusitms/website/domain/introduction/repository/SponsorRepository.java new file mode 100644 index 0000000..d4f218a --- /dev/null +++ b/src/main/java/com/kusitms/website/domain/introduction/repository/SponsorRepository.java @@ -0,0 +1,9 @@ +package com.kusitms.website.domain.introduction.repository; + +import com.kusitms.website.domain.introduction.entity.Introduction; +import com.kusitms.website.domain.introduction.entity.Sponsor; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface SponsorRepository extends JpaRepository { + void deleteByIntroduction(Introduction introduction); +} \ No newline at end of file