From 974d055dc1e261f1791e4d0cc0b2a1b14ca2acf2 Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Wed, 1 Jan 2025 20:48:37 +0900 Subject: [PATCH 01/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=EC=97=94=ED=8B=B0=ED=8B=B0=20type=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 백그라운드, 프로필 테마를 구분하기 위한 enum 클래스 정의 - 관련 : #425 --- .../namo/spring/db/mysql/domains/shop/enums/ThemeType.java | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/enums/ThemeType.java diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/enums/ThemeType.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/enums/ThemeType.java new file mode 100644 index 00000000..6f01ed64 --- /dev/null +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/enums/ThemeType.java @@ -0,0 +1,6 @@ +package com.namo.spring.db.mysql.domains.shop.enums; + +public enum ThemeType { + BACKGROUND, // 배경 테마 + PROFILE // 프로필 테마 +} From 14ab965a80fb60fbfddd6471388a0a04f0a05f00 Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Wed, 1 Jan 2025 20:50:34 +0900 Subject: [PATCH 02/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=EC=97=94=ED=8B=B0=ED=8B=B0=20=EA=B5=AC=ED=98=84=20Theme.cla?= =?UTF-8?q?ss?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 테마 저장용 엔티티 구현 - 관련 : #427 --- .../db/mysql/domains/shop/entity/Theme.java | 56 +++++++++++++++++++ 1 file changed, 56 insertions(+) create mode 100644 storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java new file mode 100644 index 00000000..e0fb3c5d --- /dev/null +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java @@ -0,0 +1,56 @@ +package com.namo.spring.db.mysql.domains.shop.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.EnumType; +import jakarta.persistence.Enumerated; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; + +import org.hibernate.annotations.DynamicInsert; + +import com.namo.spring.db.mysql.domains.shop.enums.ThemeType; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@DynamicInsert +public class Theme { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(nullable = false) + private String name; // 테마 이름 + + private String description; // 테마 설명 + + @Column(nullable = false) + private Integer price; // 테마 가격 + + private String previewImageUrl; // 미리보기 이미지 URL + + @Column(nullable = false) + private String detailImageUrl; // 상세 이미지 URL + + @Enumerated(EnumType.STRING) + private ThemeType type; // 테마 유형 (배경 테마, 프로필 테마 등) + + @Builder + public Theme(String name, String description, Integer price, String previewImageUrl, String detailImageUrl, ThemeType type) { + this.name = name; + this.description = description; + this.price = price; + this.previewImageUrl = previewImageUrl; + this.detailImageUrl = detailImageUrl; + this.type = type; + } + + +} From 4dd6408dc09c58a1d8a59af740036fd9fe3479ec Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Wed, 1 Jan 2025 20:55:08 +0900 Subject: [PATCH 03/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=EA=B5=AC=EB=A7=A4=20=EB=82=B4=EC=97=AD=20=EC=97=B0=EA=B2=B0?= =?UTF-8?q?=20=EC=97=94=ED=8B=B0=ED=8B=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 테마-Member 관계 구현 - 관련 : #427 --- .../domains/shop/entity/MemberTheme.java | 53 +++++++++++++++++++ .../db/mysql/domains/shop/entity/Theme.java | 3 +- .../db/mysql/domains/user/entity/Member.java | 4 ++ 3 files changed, 59 insertions(+), 1 deletion(-) create mode 100644 storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/MemberTheme.java diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/MemberTheme.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/MemberTheme.java new file mode 100644 index 00000000..b4e676d3 --- /dev/null +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/MemberTheme.java @@ -0,0 +1,53 @@ +package com.namo.spring.db.mysql.domains.shop.entity; + +import java.time.LocalDateTime; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; + +import org.hibernate.annotations.DynamicInsert; + +import com.namo.spring.db.mysql.common.model.BaseTimeEntity; +import com.namo.spring.db.mysql.domains.user.entity.Member; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@DynamicInsert +public class MemberTheme extends BaseTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + private Member member; // 사용자 + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + private Theme theme; // 테마 + + @Column(nullable = false) + private Boolean isActive; // 활성화 여부 + + @Column(nullable = false) + private LocalDateTime purchasedAt; // 구매 시점 + + @Builder + public MemberTheme(Member member, Theme theme, Boolean isActive, LocalDateTime purchasedAt) { + this.member = member; + this.theme = theme; + this.isActive = isActive; + this.purchasedAt = LocalDateTime.now(); + } + +} diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java index e0fb3c5d..59077255 100644 --- a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java @@ -10,6 +10,7 @@ import org.hibernate.annotations.DynamicInsert; +import com.namo.spring.db.mysql.common.model.BaseTimeEntity; import com.namo.spring.db.mysql.domains.shop.enums.ThemeType; import lombok.AccessLevel; @@ -21,7 +22,7 @@ @Entity @NoArgsConstructor(access = AccessLevel.PROTECTED) @DynamicInsert -public class Theme { +public class Theme extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/user/entity/Member.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/user/entity/Member.java index 6d9c2313..51c6a727 100644 --- a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/user/entity/Member.java +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/user/entity/Member.java @@ -36,6 +36,7 @@ import com.namo.spring.db.mysql.domains.notification.entity.Device; import com.namo.spring.db.mysql.domains.point.entity.Point; import com.namo.spring.db.mysql.domains.schedule.entity.Participant; +import com.namo.spring.db.mysql.domains.shop.entity.MemberTheme; import com.namo.spring.db.mysql.domains.user.type.MemberRole; import com.namo.spring.db.mysql.domains.user.type.MemberStatus; import com.namo.spring.db.mysql.domains.user.type.SocialType; @@ -133,6 +134,9 @@ public class Member extends BaseTimeEntity implements User { @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) private List participants; + @OneToMany(mappedBy = "member", cascade = CascadeType.ALL) + private List ownedThemes; + @Builder public Member(String name, String tag, LocalDate birthday, String authId, String email, SocialType socialType, String socialRefreshToken) { From b46dfaa6e5fc1a35c98d0703c8e2c8062fa10914 Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Wed, 1 Jan 2025 20:59:12 +0900 Subject: [PATCH 04/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=EC=83=81=EC=84=B8=20=EC=82=AC=EC=A7=84=20=EC=97=AC=EB=9F=AC?= =?UTF-8?q?=EC=9E=A5=20=EC=A0=80=EC=9E=A5=EC=9D=84=20=EC=9C=84=ED=95=9C=20?= =?UTF-8?q?=EC=97=94=ED=8B=B0=ED=8B=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ThemeDetailImage.class - 관련 : #427 --- .../db/mysql/domains/shop/entity/Theme.java | 12 ++++-- .../domains/shop/entity/ThemeDetailImage.java | 42 +++++++++++++++++++ 2 files changed, 50 insertions(+), 4 deletions(-) create mode 100644 storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/ThemeDetailImage.java diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java index 59077255..3b7c8f2c 100644 --- a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java @@ -1,5 +1,9 @@ package com.namo.spring.db.mysql.domains.shop.entity; +import java.util.ArrayList; +import java.util.List; + +import jakarta.persistence.CascadeType; import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.EnumType; @@ -7,6 +11,7 @@ import jakarta.persistence.GeneratedValue; import jakarta.persistence.GenerationType; import jakarta.persistence.Id; +import jakarta.persistence.OneToMany; import org.hibernate.annotations.DynamicInsert; @@ -37,19 +42,18 @@ public class Theme extends BaseTimeEntity { private String previewImageUrl; // 미리보기 이미지 URL - @Column(nullable = false) - private String detailImageUrl; // 상세 이미지 URL + @OneToMany(mappedBy = "theme", cascade = CascadeType.ALL) + private List detailImages; @Enumerated(EnumType.STRING) private ThemeType type; // 테마 유형 (배경 테마, 프로필 테마 등) @Builder - public Theme(String name, String description, Integer price, String previewImageUrl, String detailImageUrl, ThemeType type) { + public Theme(String name, String description, Integer price, String previewImageUrl, ThemeType type) { this.name = name; this.description = description; this.price = price; this.previewImageUrl = previewImageUrl; - this.detailImageUrl = detailImageUrl; this.type = type; } diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/ThemeDetailImage.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/ThemeDetailImage.java new file mode 100644 index 00000000..d4e8de99 --- /dev/null +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/ThemeDetailImage.java @@ -0,0 +1,42 @@ +package com.namo.spring.db.mysql.domains.shop.entity; + +import jakarta.persistence.Entity; +import jakarta.persistence.FetchType; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; + +import org.hibernate.annotations.DynamicInsert; + +import com.namo.spring.db.mysql.common.model.BaseTimeEntity; + +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Entity +@NoArgsConstructor(access = AccessLevel.PROTECTED) +@DynamicInsert +public class ThemeDetailImage extends BaseTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String imageUrl; // 상세 이미지 URL + private Integer orderIndex; // 이미지 순서 + + @ManyToOne(fetch = FetchType.LAZY, optional = false) + private Theme theme; // 연결된 테마 + + + @Builder + public ThemeDetailImage(String imageUrl, Integer orderIndex, Theme theme) { + this.imageUrl = imageUrl; + this.orderIndex = orderIndex; + this.theme = theme; + } +} From 33fe50028b39dbcf2c2ee211f8a81d0f018a400a Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Wed, 1 Jan 2025 21:02:54 +0900 Subject: [PATCH 05/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=EC=83=B5=20=EA=B4=80=EB=A0=A8=20JPA=20=EB=A0=88=ED=8C=8C?= =?UTF-8?q?=EC=A7=80=ED=86=A0=EB=A6=AC=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit JPA Repository 구현 - 관련 : #427 --- .../db/mysql/domains/shop/entity/ThemeDetailImage.java | 3 +++ .../mysql/domains/shop/exceptions/ThemeException.java | 10 ++++++++++ .../domains/shop/repository/MemberThemeRepository.java | 8 ++++++++ .../shop/repository/ThemeDetailImageRepository.java | 8 ++++++++ .../mysql/domains/shop/repository/ThemeRepository.java | 8 ++++++++ 5 files changed, 37 insertions(+) create mode 100644 storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/exceptions/ThemeException.java create mode 100644 storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/MemberThemeRepository.java create mode 100644 storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/ThemeDetailImageRepository.java create mode 100644 storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/ThemeRepository.java diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/ThemeDetailImage.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/ThemeDetailImage.java index d4e8de99..8e07a849 100644 --- a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/ThemeDetailImage.java +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/ThemeDetailImage.java @@ -1,5 +1,6 @@ package com.namo.spring.db.mysql.domains.shop.entity; +import jakarta.persistence.Column; import jakarta.persistence.Entity; import jakarta.persistence.FetchType; import jakarta.persistence.GeneratedValue; @@ -26,7 +27,9 @@ public class ThemeDetailImage extends BaseTimeEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; + @Column(nullable = false) private String imageUrl; // 상세 이미지 URL + private Integer orderIndex; // 이미지 순서 @ManyToOne(fetch = FetchType.LAZY, optional = false) diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/exceptions/ThemeException.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/exceptions/ThemeException.java new file mode 100644 index 00000000..d4e31b3d --- /dev/null +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/exceptions/ThemeException.java @@ -0,0 +1,10 @@ +package com.namo.spring.db.mysql.domains.shop.exceptions; + +import com.namo.spring.core.common.code.BaseErrorCode; +import com.namo.spring.core.common.exception.GeneralException; + +public class ThemeException extends GeneralException { + public ThemeException(BaseErrorCode code) { + super(code); + } +} diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/MemberThemeRepository.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/MemberThemeRepository.java new file mode 100644 index 00000000..b94ad24d --- /dev/null +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/MemberThemeRepository.java @@ -0,0 +1,8 @@ +package com.namo.spring.db.mysql.domains.shop.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.namo.spring.db.mysql.domains.shop.entity.MemberTheme; + +public interface MemberThemeRepository extends JpaRepository { +} diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/ThemeDetailImageRepository.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/ThemeDetailImageRepository.java new file mode 100644 index 00000000..139c46a1 --- /dev/null +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/ThemeDetailImageRepository.java @@ -0,0 +1,8 @@ +package com.namo.spring.db.mysql.domains.shop.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.namo.spring.db.mysql.domains.shop.entity.ThemeDetailImage; + +public interface ThemeDetailImageRepository extends JpaRepository { +} diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/ThemeRepository.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/ThemeRepository.java new file mode 100644 index 00000000..1f60434a --- /dev/null +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/ThemeRepository.java @@ -0,0 +1,8 @@ +package com.namo.spring.db.mysql.domains.shop.repository; + +import org.springframework.data.jpa.repository.JpaRepository; + +import com.namo.spring.db.mysql.domains.shop.entity.Theme; + +public interface ThemeRepository extends JpaRepository { +} From 759bd310f09bb7f1460c77e5669d53bd8994c9c2 Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Wed, 1 Jan 2025 21:05:47 +0900 Subject: [PATCH 06/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=EC=83=B5=20=EA=B4=80=EB=A0=A8=20=EB=8F=84=EB=A9=94=EC=9D=B8?= =?UTF-8?q?=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=EA=B5=AC=EC=A1=B0=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 관련 도메인 서비스 생성 - 관련 : #427 --- .../domains/shop/service/MemberThemeService.java | 14 ++++++++++++++ .../shop/service/ThemeDetailImageService.java | 14 ++++++++++++++ .../mysql/domains/shop/service/ThemeService.java | 14 ++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/MemberThemeService.java create mode 100644 storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/ThemeDetailImageService.java create mode 100644 storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/ThemeService.java diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/MemberThemeService.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/MemberThemeService.java new file mode 100644 index 00000000..4e8139ba --- /dev/null +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/MemberThemeService.java @@ -0,0 +1,14 @@ +package com.namo.spring.db.mysql.domains.shop.service; + +import com.namo.spring.core.common.annotation.DomainService; +import com.namo.spring.db.mysql.domains.shop.repository.MemberThemeRepository; + +import lombok.RequiredArgsConstructor; + +@DomainService +@RequiredArgsConstructor +public class MemberThemeService { + + private final MemberThemeRepository memberThemeRepository; + +} diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/ThemeDetailImageService.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/ThemeDetailImageService.java new file mode 100644 index 00000000..9885f744 --- /dev/null +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/ThemeDetailImageService.java @@ -0,0 +1,14 @@ +package com.namo.spring.db.mysql.domains.shop.service; + +import com.namo.spring.core.common.annotation.DomainService; +import com.namo.spring.db.mysql.domains.shop.repository.ThemeDetailImageRepository; + +import lombok.RequiredArgsConstructor; + +@DomainService +@RequiredArgsConstructor +public class ThemeDetailImageService { + + private final ThemeDetailImageRepository themeDetailImageRepository; + +} diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/ThemeService.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/ThemeService.java new file mode 100644 index 00000000..85556ee9 --- /dev/null +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/ThemeService.java @@ -0,0 +1,14 @@ +package com.namo.spring.db.mysql.domains.shop.service; + +import com.namo.spring.core.common.annotation.DomainService; +import com.namo.spring.db.mysql.domains.shop.repository.ThemeRepository; + +import lombok.RequiredArgsConstructor; + +@DomainService +@RequiredArgsConstructor +public class ThemeService { + + private final ThemeRepository themeRepository; + +} From 760bf23559ecabdb5a7e564e5d49225f78f87208 Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Thu, 2 Jan 2025 22:51:42 +0900 Subject: [PATCH 07/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C=20API=20=EB=AA=85=EC=84=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 테마 타입별 판매 화면 조회 API 컨트롤러 명세 - 관련 : #427 --- .../shop/controller/ShoppingController.java | 43 +++++++++++++++++++ .../external/api/shop/dto/ThemeResponse.java | 43 +++++++++++++++++++ 2 files changed, 86 insertions(+) create mode 100644 application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/controller/ShoppingController.java create mode 100644 application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/dto/ThemeResponse.java diff --git a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/controller/ShoppingController.java b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/controller/ShoppingController.java new file mode 100644 index 00000000..f783b496 --- /dev/null +++ b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/controller/ShoppingController.java @@ -0,0 +1,43 @@ +package com.namo.spring.application.external.api.shop.controller; + +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import com.namo.spring.application.external.api.shop.dto.ThemeResponse; +import com.namo.spring.application.external.api.shop.usecase.ShoppingUseCase; +import com.namo.spring.core.common.response.ResponseDto; +import com.namo.spring.db.mysql.domains.shop.enums.ThemeType; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.Parameter; +import io.swagger.v3.oas.annotations.tags.Tag; + +import lombok.RequiredArgsConstructor; + +@Tag(name = "12. 테마샵", description = "테마샵 쇼핑 관련 API ") +@RestController +@RequiredArgsConstructor +@RequestMapping("/api/themes") +public class ShoppingController { + + private final ShoppingUseCase shoppingUseCase; + + @GetMapping("") + @Operation(summary = "판매 중인 테마 조회", description = "판매 중인 테마 목록을 조회합니다.") + public ResponseDto getThemes( + @Parameter(description = "조회할 테마 타입입니다.", example = "background // profile") + @RequestParam("type") String type, + @Parameter(description = "1 부터 시작하는 페이지 번호입니다 (기본값 1)", example = "1") + @RequestParam(value = "page", defaultValue = "1") int page, + @Parameter(description = "한번에 조회할 테마 갯수 입니다 (기본값 6)", example = "6") + @RequestParam(value = "size", defaultValue = "6") int size) { + + ThemeType themeType = ThemeType.valueOf(type.toUpperCase()); + + return ResponseDto.onSuccess(shoppingUseCase + .getThemesByType(themeType, page, size)); + } +} diff --git a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/dto/ThemeResponse.java b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/dto/ThemeResponse.java new file mode 100644 index 00000000..f7163224 --- /dev/null +++ b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/dto/ThemeResponse.java @@ -0,0 +1,43 @@ +package com.namo.spring.application.external.api.shop.dto; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +public class ThemeResponse { + + @Builder + @Getter + @AllArgsConstructor + @NoArgsConstructor + public static class ThemeDtoList { + @Schema(description = "총 페이지 수", example = "5") + private int totalPages; + @Schema(description = "현재 페이지 번호", example = "1") + private int currentPage; + @Schema(description = "한 페이지당 항목 수", example = "20") + private int pageSize; + @Schema(description = "전체 항목 수", example = "100") + private long totalItems; + private List themes; + + } + + @Builder + @Getter + @AllArgsConstructor + @NoArgsConstructor + public static class ThemeResponseDto { + private Long id; + private String name; + private String description; + private Integer price; + private String previewImageUrl; + + } +} From e2cacfde2d9d77f69ccedd10ecdfa053d11ae06c Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Thu, 2 Jan 2025 22:58:22 +0900 Subject: [PATCH 08/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=ED=8C=90=EB=A7=A4=20=EC=83=81=ED=83=9C=20Enum=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 판매 상태 별 테마 저장을 위한 ThemeStatus 구현 - 관련 : #427 --- .../namo/spring/db/mysql/domains/shop/entity/Theme.java | 5 +++++ .../spring/db/mysql/domains/shop/enums/ThemeStatus.java | 8 ++++++++ 2 files changed, 13 insertions(+) create mode 100644 storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/enums/ThemeStatus.java diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java index 3b7c8f2c..27aea291 100644 --- a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java @@ -16,6 +16,7 @@ import org.hibernate.annotations.DynamicInsert; import com.namo.spring.db.mysql.common.model.BaseTimeEntity; +import com.namo.spring.db.mysql.domains.shop.enums.ThemeStatus; import com.namo.spring.db.mysql.domains.shop.enums.ThemeType; import lombok.AccessLevel; @@ -48,6 +49,10 @@ public class Theme extends BaseTimeEntity { @Enumerated(EnumType.STRING) private ThemeType type; // 테마 유형 (배경 테마, 프로필 테마 등) + @Enumerated(EnumType.STRING) + private ThemeStatus status; // 테마 판매 상태 + + @Builder public Theme(String name, String description, Integer price, String previewImageUrl, ThemeType type) { this.name = name; diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/enums/ThemeStatus.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/enums/ThemeStatus.java new file mode 100644 index 00000000..4e4c2162 --- /dev/null +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/enums/ThemeStatus.java @@ -0,0 +1,8 @@ +package com.namo.spring.db.mysql.domains.shop.enums; + +public enum ThemeStatus { + ACTIVE, // 판매중 + INACTIVE, // 판매중지 + DELETED, // 삭제처리 (soft delete) + PENDING // 판매대기 +} From a4c23b836928f0bf5c57b32b48aa7d5faf1ab1dd Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Thu, 2 Jan 2025 23:01:15 +0900 Subject: [PATCH 09/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=ED=8C=90=EB=A7=A4=20=EC=83=81=ED=83=9C=EC=99=80=20=EC=A2=85?= =?UTF-8?q?=EB=A5=98=20=EB=B3=84=20=EC=A1=B0=ED=9A=8C=20=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 테마의 status, type으로 페이징하여 조회하는 도메인 로직 구현 - 관련 : #427 --- .../mysql/domains/shop/repository/ThemeRepository.java | 6 ++++++ .../db/mysql/domains/shop/service/ThemeService.java | 9 +++++++++ 2 files changed, 15 insertions(+) diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/ThemeRepository.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/ThemeRepository.java index 1f60434a..faca0db6 100644 --- a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/ThemeRepository.java +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/ThemeRepository.java @@ -1,8 +1,14 @@ package com.namo.spring.db.mysql.domains.shop.repository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import com.namo.spring.db.mysql.domains.shop.entity.Theme; +import com.namo.spring.db.mysql.domains.shop.enums.ThemeStatus; +import com.namo.spring.db.mysql.domains.shop.enums.ThemeType; public interface ThemeRepository extends JpaRepository { + + Page findByTypeAndStatus(ThemeType themeType, Pageable pageable, ThemeStatus themeStatus); } diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/ThemeService.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/ThemeService.java index 85556ee9..7bf3a5b5 100644 --- a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/ThemeService.java +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/ThemeService.java @@ -1,6 +1,12 @@ package com.namo.spring.db.mysql.domains.shop.service; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + import com.namo.spring.core.common.annotation.DomainService; +import com.namo.spring.db.mysql.domains.shop.entity.Theme; +import com.namo.spring.db.mysql.domains.shop.enums.ThemeStatus; +import com.namo.spring.db.mysql.domains.shop.enums.ThemeType; import com.namo.spring.db.mysql.domains.shop.repository.ThemeRepository; import lombok.RequiredArgsConstructor; @@ -11,4 +17,7 @@ public class ThemeService { private final ThemeRepository themeRepository; + public Page findByTypeAndStatus(ThemeType themeType, Pageable pageable, ThemeStatus themeStatus) { + return themeRepository.findByTypeAndStatus(themeType, pageable, themeStatus); + } } From b5cedc87f22127b4ef3d8e9aaf6f134b9d844deb Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Thu, 2 Jan 2025 23:04:52 +0900 Subject: [PATCH 10/21] =?UTF-8?q?:sparkles:=20Feat:=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=EB=90=9C=20=ED=85=8C=EB=A7=88=EB=A5=BC=20dto=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=ED=99=98=ED=95=98=EB=8A=94=20Converter=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit builder 패턴 사용한 converter 구현 - 관련 : #427 --- .../api/shop/converter/ThemeConverter.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/converter/ThemeConverter.java diff --git a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/converter/ThemeConverter.java b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/converter/ThemeConverter.java new file mode 100644 index 00000000..94bc3d53 --- /dev/null +++ b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/converter/ThemeConverter.java @@ -0,0 +1,36 @@ +package com.namo.spring.application.external.api.shop.converter; + +import java.util.List; +import java.util.stream.Collectors; + +import org.springframework.data.domain.Page; + +import com.namo.spring.application.external.api.shop.dto.ThemeResponse; +import com.namo.spring.db.mysql.domains.shop.entity.Theme; + +public class ThemeConverter { + + public static ThemeResponse.ThemeDtoList toThemeDtoList(Page themes) { + List themeDtoList = themes.stream() + .map(ThemeConverter::toThemeResponseDto) + .collect(Collectors.toList()); + + return ThemeResponse.ThemeDtoList.builder() + .themes(themeDtoList) + .totalPages(themes.getTotalPages()) + .currentPage(themes.getNumber() + 1) + .pageSize(themes.getSize()) + .totalItems(themes.getTotalElements()) + .build(); + } + + public static ThemeResponse.ThemeResponseDto toThemeResponseDto(Theme theme) { + return ThemeResponse.ThemeResponseDto.builder() + .id(theme.getId()) + .name(theme.getName()) + .description(theme.getDescription()) + .price(theme.getPrice()) + .previewImageUrl(theme.getPreviewImageUrl()) + .build(); + } +} From 7ae826e955170ee38ecde24466f95b6e5b46c303 Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Thu, 2 Jan 2025 23:06:16 +0900 Subject: [PATCH 11/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=83=80=EC=9E=85?= =?UTF-8?q?=EB=B3=84=20=ED=8C=90=EB=A7=A4=EC=A4=91=EC=9D=B8=20=ED=85=8C?= =?UTF-8?q?=EB=A7=88=20=EC=A1=B0=ED=9A=8C=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 테마샵 메인 화면 및 타입별 조회에 사용될 API 구현 - 관련 : #427 --- .../shop/controller/ShoppingController.java | 2 +- .../api/shop/service/ThemeManageService.java | 26 +++++++++++++++++++ .../api/shop/usecase/ShoppingUseCase.java | 26 +++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/service/ThemeManageService.java create mode 100644 application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/usecase/ShoppingUseCase.java diff --git a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/controller/ShoppingController.java b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/controller/ShoppingController.java index f783b496..ede4d691 100644 --- a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/controller/ShoppingController.java +++ b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/controller/ShoppingController.java @@ -20,7 +20,7 @@ @Tag(name = "12. 테마샵", description = "테마샵 쇼핑 관련 API ") @RestController @RequiredArgsConstructor -@RequestMapping("/api/themes") +@RequestMapping("/api/v2/shop/themes") public class ShoppingController { private final ShoppingUseCase shoppingUseCase; diff --git a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/service/ThemeManageService.java b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/service/ThemeManageService.java new file mode 100644 index 00000000..192fe268 --- /dev/null +++ b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/service/ThemeManageService.java @@ -0,0 +1,26 @@ +package com.namo.spring.application.external.api.shop.service; + + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; + +import com.namo.spring.db.mysql.domains.shop.entity.Theme; +import com.namo.spring.db.mysql.domains.shop.enums.ThemeStatus; +import com.namo.spring.db.mysql.domains.shop.enums.ThemeType; +import com.namo.spring.db.mysql.domains.shop.service.ThemeService; + +import lombok.RequiredArgsConstructor; + +@Service +@RequiredArgsConstructor +public class ThemeManageService { + + private final ThemeService themeService; + + public Page getSellingThemesByType(ThemeType themeType, int page, int size) { + Pageable pageable = PageRequest.of(page - 1, size); + return themeService.findByTypeAndStatus(themeType, pageable, ThemeStatus.ACTIVE); + } +} diff --git a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/usecase/ShoppingUseCase.java b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/usecase/ShoppingUseCase.java new file mode 100644 index 00000000..9afdb754 --- /dev/null +++ b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/usecase/ShoppingUseCase.java @@ -0,0 +1,26 @@ +package com.namo.spring.application.external.api.shop.usecase; + +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import com.namo.spring.application.external.api.shop.converter.ThemeConverter; +import com.namo.spring.application.external.api.shop.dto.ThemeResponse; +import com.namo.spring.application.external.api.shop.service.ThemeManageService; +import com.namo.spring.db.mysql.domains.shop.entity.Theme; +import com.namo.spring.db.mysql.domains.shop.enums.ThemeType; + +import lombok.RequiredArgsConstructor; + +@Component +@RequiredArgsConstructor +public class ShoppingUseCase { + + private final ThemeManageService themeManageService; + + @Transactional(readOnly = true) + public ThemeResponse.ThemeDtoList getThemesByType(ThemeType themeType, int page, int size) { + Page themes = themeManageService.getSellingThemesByType(themeType, page, size); + return ThemeConverter.toThemeDtoList(themes); + } +} From 7e05b1b4faa60b790fbaaa424a7a9d8e291a9a94 Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Sat, 4 Jan 2025 22:05:12 +0900 Subject: [PATCH 12/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=EC=83=81=EC=84=B8=20=EC=A1=B0=ED=9A=8C=20API=20=EC=8A=A4?= =?UTF-8?q?=ED=8E=99=20=EB=AA=85=EC=84=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 테마 상세 조회를 위한 API 스펙 명세 - 관련 : #427 --- .../api/shop/controller/ShoppingController.java | 10 +++++++++- .../api/shop/converter/ThemeConverter.java | 6 +++--- .../external/api/shop/dto/ThemeResponse.java | 16 ++++++++++++++-- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/controller/ShoppingController.java b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/controller/ShoppingController.java index ede4d691..e164ed1f 100644 --- a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/controller/ShoppingController.java +++ b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/controller/ShoppingController.java @@ -1,6 +1,5 @@ package com.namo.spring.application.external.api.shop.controller; -import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; @@ -40,4 +39,13 @@ public ResponseDto getThemes( return ResponseDto.onSuccess(shoppingUseCase .getThemesByType(themeType, page, size)); } + + @GetMapping("{/themeId}") + @Operation(summary = "테마 상세 조회", description = "테마 상세 정보를 조회합니다.") + public ResponseDto getThemeDetail( + @Parameter(description = "조회할 테마 ID입니다.", example = "1") + @RequestParam("themeId") Long themeId) { + + return ResponseDto.onSuccess(shoppingUseCase.getThemeDetail(themeId)); + } } diff --git a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/converter/ThemeConverter.java b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/converter/ThemeConverter.java index 94bc3d53..a50a10bf 100644 --- a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/converter/ThemeConverter.java +++ b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/converter/ThemeConverter.java @@ -11,7 +11,7 @@ public class ThemeConverter { public static ThemeResponse.ThemeDtoList toThemeDtoList(Page themes) { - List themeDtoList = themes.stream() + List themeDtoList = themes.stream() .map(ThemeConverter::toThemeResponseDto) .collect(Collectors.toList()); @@ -24,8 +24,8 @@ public static ThemeResponse.ThemeDtoList toThemeDtoList(Page themes) { .build(); } - public static ThemeResponse.ThemeResponseDto toThemeResponseDto(Theme theme) { - return ThemeResponse.ThemeResponseDto.builder() + public static ThemeResponse.ThemePreviewDto toThemeResponseDto(Theme theme) { + return ThemeResponse.ThemePreviewDto.builder() .id(theme.getId()) .name(theme.getName()) .description(theme.getDescription()) diff --git a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/dto/ThemeResponse.java b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/dto/ThemeResponse.java index f7163224..349f914c 100644 --- a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/dto/ThemeResponse.java +++ b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/dto/ThemeResponse.java @@ -24,7 +24,7 @@ public static class ThemeDtoList { private int pageSize; @Schema(description = "전체 항목 수", example = "100") private long totalItems; - private List themes; + private List themes; } @@ -32,12 +32,24 @@ public static class ThemeDtoList { @Getter @AllArgsConstructor @NoArgsConstructor - public static class ThemeResponseDto { + public static class ThemePreviewDto { private Long id; private String name; private String description; private Integer price; private String previewImageUrl; + } + @Builder + @Getter + @AllArgsConstructor + @NoArgsConstructor + public static class ThemeInfoDto { + private Long id; + private String name; + private String description; + private Integer price; + private String type; + private List detailImages; } } From 6c6f9f547ed56c34f2755d652f9a70a87a9a9eb9 Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Sat, 4 Jan 2025 22:07:48 +0900 Subject: [PATCH 13/21] =?UTF-8?q?:recycle:=20Recycle:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=EC=83=81=EC=84=B8=20=EC=A1=B0=ED=9A=8C=EC=97=90=20=EB=B3=B4?= =?UTF-8?q?=EC=9C=A0=20=EC=97=AC=EB=B6=80=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 해당 테마에 대한 소유 여부 isOwned 추가 - 관련 : #427 --- .../spring/application/external/api/shop/dto/ThemeResponse.java | 1 + 1 file changed, 1 insertion(+) diff --git a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/dto/ThemeResponse.java b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/dto/ThemeResponse.java index 349f914c..6699f735 100644 --- a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/dto/ThemeResponse.java +++ b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/dto/ThemeResponse.java @@ -51,5 +51,6 @@ public static class ThemeInfoDto { private Integer price; private String type; private List detailImages; + private Boolean isOwned; // 테마 보유 여부 } } From b1ff6a5430acf294e61469daadccf38721f4d032 Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Sat, 4 Jan 2025 22:24:35 +0900 Subject: [PATCH 14/21] =?UTF-8?q?:recycle:=20Recycle:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=ED=8C=90=EB=A7=A4=20=EC=83=81=ED=83=9C=20=EC=84=B8=EB=B6=84?= =?UTF-8?q?=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 판매 상태 세분화를 위한 ThemeStatus 리팩토링 - 관련 : #427 --- .../db/mysql/domains/shop/enums/ThemeStatus.java | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/enums/ThemeStatus.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/enums/ThemeStatus.java index 4e4c2162..6a808623 100644 --- a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/enums/ThemeStatus.java +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/enums/ThemeStatus.java @@ -1,8 +1,10 @@ package com.namo.spring.db.mysql.domains.shop.enums; public enum ThemeStatus { - ACTIVE, // 판매중 - INACTIVE, // 판매중지 - DELETED, // 삭제처리 (soft delete) - PENDING // 판매대기 + SELLING, // 판매 중 + SOLD_OUT, // 품절 + DISCONTINUED, // 판매 중지 + DELETED, // 삭제 처리 (soft delete) + PENDING, // 판매 대기 + ARCHIVED // 과거 아카이브 상태 (사용자는 볼 수 있지만 판매되지 않음) } From cbf9f54f7d13fd42d912fd2b5d3a9afaf0665eef Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Sat, 4 Jan 2025 22:25:06 +0900 Subject: [PATCH 15/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=EC=83=81=ED=83=9C,=20id=EB=A1=9C=20=EC=A1=B0=ED=9A=8C?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EB=8F=84=EB=A9=94=EC=9D=B8=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit findByIdAndStatus() - 관련 : #427 --- .../db/mysql/domains/shop/repository/ThemeRepository.java | 4 ++++ .../spring/db/mysql/domains/shop/service/ThemeService.java | 6 ++++++ 2 files changed, 10 insertions(+) diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/ThemeRepository.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/ThemeRepository.java index faca0db6..9152b6a3 100644 --- a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/ThemeRepository.java +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/ThemeRepository.java @@ -1,5 +1,7 @@ package com.namo.spring.db.mysql.domains.shop.repository; +import java.util.Optional; + import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; @@ -11,4 +13,6 @@ public interface ThemeRepository extends JpaRepository { Page findByTypeAndStatus(ThemeType themeType, Pageable pageable, ThemeStatus themeStatus); + + Optional findByIdAndStatus(Long id, ThemeStatus themeStatus); } diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/ThemeService.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/ThemeService.java index 7bf3a5b5..cc5201e5 100644 --- a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/ThemeService.java +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/ThemeService.java @@ -1,5 +1,7 @@ package com.namo.spring.db.mysql.domains.shop.service; +import java.util.Optional; + import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; @@ -17,6 +19,10 @@ public class ThemeService { private final ThemeRepository themeRepository; + public Optional findByIdAndStatus(Long id, ThemeStatus themeStatus) { + return themeRepository.findByIdAndStatus(id, ThemeStatus.SELLING); + } + public Page findByTypeAndStatus(ThemeType themeType, Pageable pageable, ThemeStatus themeStatus) { return themeRepository.findByTypeAndStatus(themeType, pageable, themeStatus); } From d13b4c95763a8b2ca36095c5f1e9575ad04aa410 Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Sat, 4 Jan 2025 22:25:23 +0900 Subject: [PATCH 16/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=EA=B5=AC=EB=A7=A4=20=EC=A0=95=EB=B3=B4=EB=A5=BC=20=EB=B0=98?= =?UTF-8?q?=ED=99=98=ED=95=98=EB=8A=94=20=EB=8F=84=EB=A9=94=EC=9D=B8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit purchaseInfo() - 관련 : #427 --- .../mysql/domains/shop/repository/MemberThemeRepository.java | 1 + .../db/mysql/domains/shop/service/MemberThemeService.java | 3 +++ 2 files changed, 4 insertions(+) diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/MemberThemeRepository.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/MemberThemeRepository.java index b94ad24d..0c4d23a1 100644 --- a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/MemberThemeRepository.java +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/repository/MemberThemeRepository.java @@ -5,4 +5,5 @@ import com.namo.spring.db.mysql.domains.shop.entity.MemberTheme; public interface MemberThemeRepository extends JpaRepository { + boolean existsByMemberIdAndThemeId(Long memberId, Long themeId); } diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/MemberThemeService.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/MemberThemeService.java index 4e8139ba..eeef0131 100644 --- a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/MemberThemeService.java +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/service/MemberThemeService.java @@ -11,4 +11,7 @@ public class MemberThemeService { private final MemberThemeRepository memberThemeRepository; + public boolean purchaseInfo(Long memberId, Long themeId) { + return memberThemeRepository.existsByMemberIdAndThemeId(memberId, themeId); + } } From cb2fbce55b452ad33b5b82203c9b122644a8f576 Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Sat, 4 Jan 2025 22:25:43 +0900 Subject: [PATCH 17/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=20=EC=97=86=EC=9D=8C=EC=97=90=20=EB=8C=80?= =?UTF-8?q?=ED=95=9C=20error=20code?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit NOT_FOUND_THEME(NOT_FOUND, "테마를 찾을 수 없습니다.") - 관련 : #427 --- .../com/namo/spring/core/common/code/status/ErrorStatus.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/core-common/src/main/java/com/namo/spring/core/common/code/status/ErrorStatus.java b/core/core-common/src/main/java/com/namo/spring/core/common/code/status/ErrorStatus.java index 6294e4ab..f670f40d 100644 --- a/core/core-common/src/main/java/com/namo/spring/core/common/code/status/ErrorStatus.java +++ b/core/core-common/src/main/java/com/namo/spring/core/common/code/status/ErrorStatus.java @@ -156,6 +156,8 @@ public enum ErrorStatus implements BaseErrorCode { NOT_FOUND_FRIENDSHIP_REQUEST(NOT_FOUND, "친구 요청을 찾을 수 없습니다."), NOT_FOUND_POINT_REQUEST(NOT_FOUND, "대기중인 포인트 입금 요청을 찾을 수 없습니다."), + NOT_FOUND_THEME(NOT_FOUND, "테마를 찾을 수 없습니다."), + /** * 404 : 예외 상황 에러 */ From a770a8282dfa8ab950de693b0d8cadffa39dcd93 Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Sat, 4 Jan 2025 22:26:16 +0900 Subject: [PATCH 18/21] =?UTF-8?q?:sparkles:=20Feat:=20DB=EC=97=90=20?= =?UTF-8?q?=EC=A0=80=EC=9E=A5=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20?= =?UTF-8?q?=ED=85=8C=EB=A7=88=20=EC=86=8C=EC=9C=A0=20=EC=97=AC=EB=B6=80=20?= =?UTF-8?q?=ED=95=84=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit @Transient을 사용해 DB에 저장되지 않는 테마 소유 여부 필드 추가 - 관련 : #427 --- .../com/namo/spring/db/mysql/domains/shop/entity/Theme.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java index 27aea291..9c5c4c66 100644 --- a/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java +++ b/storage/db-mysql-v2/src/main/java/com/namo/spring/db/mysql/domains/shop/entity/Theme.java @@ -12,6 +12,7 @@ import jakarta.persistence.GenerationType; import jakarta.persistence.Id; import jakarta.persistence.OneToMany; +import jakarta.persistence.Transient; import org.hibernate.annotations.DynamicInsert; @@ -23,6 +24,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; @Getter @Entity @@ -52,6 +54,9 @@ public class Theme extends BaseTimeEntity { @Enumerated(EnumType.STRING) private ThemeStatus status; // 테마 판매 상태 + @Setter + @Transient // DB에 저장되지 않는 필드 + private boolean isOwned; @Builder public Theme(String name, String description, Integer price, String previewImageUrl, ThemeType type) { From fa86a1c6f6323b209a8cd4cd2e8e18c0bde27e1a Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Sat, 4 Jan 2025 22:26:55 +0900 Subject: [PATCH 19/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=EC=99=80=20=ED=95=B4=EB=8B=B9=20=ED=85=8C?= =?UTF-8?q?=EB=A7=88=EC=9D=98=20=EC=86=8C=EC=9C=A0=20=EC=97=AC=EB=B6=80?= =?UTF-8?q?=EB=A5=BC=20=EB=B0=98=ED=99=98=ED=95=98=EB=8A=94=20=EB=B9=84?= =?UTF-8?q?=EC=A6=88=EB=8B=88=EC=8A=A4=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 테마 정보와 소유 여부 반환 - 관련 : #427 --- .../api/shop/service/ThemeManageService.java | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/service/ThemeManageService.java b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/service/ThemeManageService.java index 192fe268..bc3b3101 100644 --- a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/service/ThemeManageService.java +++ b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/service/ThemeManageService.java @@ -6,9 +6,12 @@ import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; +import com.namo.spring.core.common.code.status.ErrorStatus; import com.namo.spring.db.mysql.domains.shop.entity.Theme; import com.namo.spring.db.mysql.domains.shop.enums.ThemeStatus; import com.namo.spring.db.mysql.domains.shop.enums.ThemeType; +import com.namo.spring.db.mysql.domains.shop.exceptions.ThemeException; +import com.namo.spring.db.mysql.domains.shop.service.MemberThemeService; import com.namo.spring.db.mysql.domains.shop.service.ThemeService; import lombok.RequiredArgsConstructor; @@ -18,9 +21,18 @@ public class ThemeManageService { private final ThemeService themeService; + private final MemberThemeService memberThemeService; public Page getSellingThemesByType(ThemeType themeType, int page, int size) { Pageable pageable = PageRequest.of(page - 1, size); - return themeService.findByTypeAndStatus(themeType, pageable, ThemeStatus.ACTIVE); + return themeService.findByTypeAndStatus(themeType, pageable, ThemeStatus.SELLING); + } + + public Theme getThemeByIdWithOwnership(Long memberId, Long themeId) { + Theme theme = themeService.findByIdAndStatus(themeId, ThemeStatus.SELLING) + .orElseThrow(() -> new ThemeException(ErrorStatus.NOT_FOUND_THEME)); + boolean isOwned = memberThemeService.purchaseInfo(memberId, themeId); + theme.setOwned(isOwned); + return theme; } } From 66bca3f034b59cc2f2dc42fdf5e55d795bf10b63 Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Sat, 4 Jan 2025 22:31:02 +0900 Subject: [PATCH 20/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=EC=A0=95=EB=B3=B4=20->=20DTO=20=EC=BB=A8=EB=B2=84=ED=84=B0?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Builder 패턴을 활용한 변환 코드 작성 - 관련 : #427 --- .../api/shop/converter/ThemeConverter.java | 16 ++++++++++++++++ .../api/shop/service/ThemeManageService.java | 13 +++++++++++++ 2 files changed, 29 insertions(+) diff --git a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/converter/ThemeConverter.java b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/converter/ThemeConverter.java index a50a10bf..d1c9786c 100644 --- a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/converter/ThemeConverter.java +++ b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/converter/ThemeConverter.java @@ -7,6 +7,7 @@ import com.namo.spring.application.external.api.shop.dto.ThemeResponse; import com.namo.spring.db.mysql.domains.shop.entity.Theme; +import com.namo.spring.db.mysql.domains.shop.entity.ThemeDetailImage; public class ThemeConverter { @@ -33,4 +34,19 @@ public static ThemeResponse.ThemePreviewDto toThemeResponseDto(Theme theme) { .previewImageUrl(theme.getPreviewImageUrl()) .build(); } + + public static ThemeResponse.ThemeInfoDto toThemeInfoDto(Theme theme) { + List detailImages = theme.getDetailImages().stream() + .map(ThemeDetailImage::getImageUrl) + .toList(); + + return ThemeResponse.ThemeInfoDto.builder() + .id(theme.getId()) + .name(theme.getName()) + .description(theme.getDescription()) + .price(theme.getPrice()) + .detailImages(detailImages) + .isOwned(theme.isOwned()) + .build(); + } } diff --git a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/service/ThemeManageService.java b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/service/ThemeManageService.java index bc3b3101..6476c261 100644 --- a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/service/ThemeManageService.java +++ b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/service/ThemeManageService.java @@ -23,11 +23,24 @@ public class ThemeManageService { private final ThemeService themeService; private final MemberThemeService memberThemeService; + /** + * 테마 타입에 따른 테마 목록을 반환 합니다. + * @param themeType (프로필, 배경) + * @param page + * @param size + * @return + */ public Page getSellingThemesByType(ThemeType themeType, int page, int size) { Pageable pageable = PageRequest.of(page - 1, size); return themeService.findByTypeAndStatus(themeType, pageable, ThemeStatus.SELLING); } + /** + * 테마 정보와 소유 여부를 반환 합니다. + * @param memberId + * @param themeId + * @return + */ public Theme getThemeByIdWithOwnership(Long memberId, Long themeId) { Theme theme = themeService.findByIdAndStatus(themeId, ThemeStatus.SELLING) .orElseThrow(() -> new ThemeException(ErrorStatus.NOT_FOUND_THEME)); From 13f4cfe55b0e24d0bc003447e4b5361728b85090 Mon Sep 17 00:00:00 2001 From: hosung-222 Date: Sat, 4 Jan 2025 22:31:44 +0900 Subject: [PATCH 21/21] =?UTF-8?q?:sparkles:=20Feat:=20=ED=85=8C=EB=A7=88?= =?UTF-8?q?=20=EC=83=81=EC=84=B8=20=EC=A0=95=EB=B3=B4=20(=EB=B3=B4?= =?UTF-8?q?=EC=9C=A0=EC=97=AC=EB=B6=80=20=ED=8F=AC=ED=95=A8)=20=EB=A5=BC?= =?UTF-8?q?=20=EC=A1=B0=ED=9A=8C=ED=95=98=EB=8A=94=20API=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 테마샵에서 테마 상세 정보 조회 API - 관련 : #427 --- .../api/shop/controller/ShoppingController.java | 10 ++++++++-- .../external/api/shop/usecase/ShoppingUseCase.java | 6 ++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/controller/ShoppingController.java b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/controller/ShoppingController.java index e164ed1f..fcc0a2a8 100644 --- a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/controller/ShoppingController.java +++ b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/controller/ShoppingController.java @@ -1,12 +1,15 @@ package com.namo.spring.application.external.api.shop.controller; +import org.springframework.security.core.annotation.AuthenticationPrincipal; 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.RequestParam; import org.springframework.web.bind.annotation.RestController; import com.namo.spring.application.external.api.shop.dto.ThemeResponse; import com.namo.spring.application.external.api.shop.usecase.ShoppingUseCase; +import com.namo.spring.application.external.global.common.security.authentication.SecurityUserDetails; import com.namo.spring.core.common.response.ResponseDto; import com.namo.spring.db.mysql.domains.shop.enums.ThemeType; @@ -27,6 +30,7 @@ public class ShoppingController { @GetMapping("") @Operation(summary = "판매 중인 테마 조회", description = "판매 중인 테마 목록을 조회합니다.") public ResponseDto getThemes( + @AuthenticationPrincipal SecurityUserDetails memberInfo, @Parameter(description = "조회할 테마 타입입니다.", example = "background // profile") @RequestParam("type") String type, @Parameter(description = "1 부터 시작하는 페이지 번호입니다 (기본값 1)", example = "1") @@ -43,9 +47,11 @@ public ResponseDto getThemes( @GetMapping("{/themeId}") @Operation(summary = "테마 상세 조회", description = "테마 상세 정보를 조회합니다.") public ResponseDto getThemeDetail( + @AuthenticationPrincipal SecurityUserDetails memberInfo, @Parameter(description = "조회할 테마 ID입니다.", example = "1") - @RequestParam("themeId") Long themeId) { + @PathVariable("themeId") Long themeId) { - return ResponseDto.onSuccess(shoppingUseCase.getThemeDetail(themeId)); + return ResponseDto.onSuccess(shoppingUseCase + .getThemeDetail(memberInfo.getUserId(), themeId)); } } diff --git a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/usecase/ShoppingUseCase.java b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/usecase/ShoppingUseCase.java index 9afdb754..0d14215f 100644 --- a/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/usecase/ShoppingUseCase.java +++ b/application/external-api-v2/src/main/java/com/namo/spring/application/external/api/shop/usecase/ShoppingUseCase.java @@ -23,4 +23,10 @@ public ThemeResponse.ThemeDtoList getThemesByType(ThemeType themeType, int page, Page themes = themeManageService.getSellingThemesByType(themeType, page, size); return ThemeConverter.toThemeDtoList(themes); } + + @Transactional(readOnly = true) + public ThemeResponse.ThemeInfoDto getThemeDetail(Long memberId, Long themeId) { + Theme theme = themeManageService.getThemeByIdWithOwnership(memberId, themeId); + return ThemeConverter.toThemeInfoDto(theme); + } }