Skip to content

Commit 3f4244e

Browse files
authored
[feat] ArtistProfile 엔티티 생성 (#175)
1 parent 8b332bb commit 3f4244e

File tree

1 file changed

+271
-0
lines changed

1 file changed

+271
-0
lines changed
Lines changed: 271 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,271 @@
1+
package com.back.domain.artist.entity;
2+
3+
import com.back.domain.user.entity.User;
4+
import com.back.global.exception.ServiceException;
5+
import com.back.global.jpa.entity.BaseEntity;
6+
import jakarta.persistence.*;
7+
import lombok.AccessLevel;
8+
import lombok.Builder;
9+
import lombok.Getter;
10+
import lombok.NoArgsConstructor;
11+
12+
/**
13+
* 작가 프로필 엔티티
14+
* - 작가 신청 승인 시 생성됨
15+
* - User와 1:1 매핑
16+
*/
17+
@Entity
18+
@Getter
19+
@NoArgsConstructor(access = AccessLevel.PROTECTED)
20+
@Table(name = "artist_profiles")
21+
public class ArtistProfile extends BaseEntity {
22+
23+
// ==== 연관 관계 매핑 ==== //
24+
25+
@OneToOne(fetch = FetchType.LAZY)
26+
@JoinColumn(name = "user_id", nullable = false, unique = true)
27+
private User user;
28+
29+
@ManyToOne(fetch = FetchType.LAZY)
30+
@JoinColumn(name = "artist_application_id", nullable = false)
31+
private ArtistApplication artistApplication;
32+
33+
// ===== 작가 기본 정보 ===== //
34+
@Column(nullable = false, length = 20)
35+
private String artistName; // 작가명
36+
37+
@Column(nullable = false, length = 100)
38+
private String email;
39+
40+
@Column(nullable = false, length = 20)
41+
private String phone;
42+
43+
@Column(length = 500)
44+
private String mainProducts; // 주력 상품
45+
46+
@Column(length = 100)
47+
private String snsAccount; // SNS 계정
48+
49+
// ==== 사업자 정보 ==== //
50+
51+
@Column(length = 200)
52+
private String businessAddress; // 사업장 주소
53+
54+
@Column(length = 200)
55+
private String businessAddressDetail; // 사업장 상세주소(동/호수)
56+
57+
@Column(length = 10)
58+
private String businessZipCode; // 사업장 우편번호
59+
60+
@Column(length = 20)
61+
private String managerPhone; // 담당자 연락처
62+
63+
// ==== 은행 정보 ==== //
64+
65+
@Column(length = 50)
66+
private String bankName; // 은행명
67+
68+
@Column(length = 50)
69+
private String bankAccount; // 계좌번호
70+
71+
@Column(length = 20)
72+
private String accountName; // 예금주명
73+
74+
// ==== 작가 프로필 전용 정보 ==== //
75+
76+
@Column(length = 2000)
77+
private String description; // 작가 소개
78+
79+
@Column(length = 500)
80+
private String profileImageUrl; // 프로필 이미지 URL
81+
82+
// ==== 통계 정보 ==== //
83+
84+
@Column(nullable = false)
85+
private Integer followerCount = 0; // 팔로워 수
86+
87+
@Column(nullable = false)
88+
private Long totalSales = 0L; // 총 판매액
89+
90+
@Column(nullable = false)
91+
private Integer productCount = 0; // 등록 상품 수
92+
93+
@Builder
94+
public ArtistProfile(User user, ArtistApplication artistApplication,
95+
String artistName, String email, String phone,
96+
String mainProducts, String snsAccount,
97+
String businessAddress, String businessAddressDetail, String businessZipCode,
98+
String managerPhone,
99+
String bankName, String bankAccount, String accountName,
100+
String description, String profileImageUrl) {
101+
this.user = user;
102+
this.artistApplication = artistApplication;
103+
this.artistName = artistName;
104+
this.email = email;
105+
this.phone = phone;
106+
this.mainProducts = mainProducts;
107+
this.snsAccount = snsAccount;
108+
this.businessAddress = businessAddress;
109+
this.businessAddressDetail = businessAddressDetail;
110+
this.businessZipCode = businessZipCode;
111+
this.managerPhone = managerPhone;
112+
this.bankName = bankName;
113+
this.bankAccount = bankAccount;
114+
this.accountName = accountName;
115+
this.description = description;
116+
this.profileImageUrl = profileImageUrl;
117+
118+
// 통계 정보 초기화
119+
this.followerCount = 0;
120+
this.totalSales = 0L;
121+
this.productCount = 0;
122+
}
123+
124+
125+
126+
// ===== 정적 팩토리 메서드 ===== //
127+
128+
/**
129+
* ArtistApplication으로부터 ArtistProfile 생성
130+
*/
131+
public static ArtistProfile fromApplication(User user, ArtistApplication application) {
132+
return ArtistProfile.builder()
133+
.user(user)
134+
.artistApplication(application)
135+
.artistName(application.getArtistName())
136+
.email(application.getEmail())
137+
.phone(application.getPhone())
138+
.mainProducts(application.getMainProducts())
139+
.snsAccount(application.getSnsAccount())
140+
.businessAddress(application.getBusinessAddress())
141+
.businessAddressDetail(application.getBusinessAddressDetail())
142+
.businessZipCode(application.getBusinessZipCode())
143+
.managerPhone(application.getManagerPhone())
144+
.bankName(application.getBankName())
145+
.bankAccount(application.getBankAccount())
146+
.accountName(application.getAccountName())
147+
.build();
148+
}
149+
150+
// ==== 프로필 정보 업데이트 메서드 ==== //
151+
152+
public void updateProfile(String profileImageUrl, String artistName, String snsAccount,
153+
String description, String businessAddress, String businessAddressDetail,
154+
String businessZipCode, String accountName, String bankName,
155+
String bankAccount, String managerPhone) {
156+
// 프로필 이미지
157+
if (profileImageUrl != null && !profileImageUrl.isBlank()) {
158+
this.profileImageUrl = profileImageUrl;
159+
}
160+
161+
// 작가명
162+
if (artistName != null && !artistName.isBlank()) {
163+
this.artistName = artistName;
164+
}
165+
166+
// SNS 계정
167+
if (snsAccount != null && !snsAccount.isBlank()) {
168+
this.snsAccount = snsAccount;
169+
}
170+
171+
// 작가 소개
172+
if (description != null && !description.isBlank()) {
173+
this.description = description;
174+
}
175+
176+
// 사업장 주소
177+
if (businessAddress != null && !businessAddress.isBlank()) {
178+
this.businessAddress = businessAddress;
179+
}
180+
181+
if (businessAddressDetail != null && !businessAddressDetail.isBlank()) {
182+
this.businessAddressDetail = businessAddressDetail;
183+
}
184+
if (businessZipCode != null && !businessZipCode.isBlank()) {
185+
this.businessZipCode = businessZipCode;
186+
}
187+
188+
// 예금주
189+
if (accountName != null && !accountName.isBlank()) {
190+
this.accountName = accountName;
191+
}
192+
193+
// 은행명
194+
if (bankName != null && !bankName.isBlank()) {
195+
this.bankName = bankName;
196+
}
197+
198+
// 계좌번호
199+
if (bankAccount != null && !bankAccount.isBlank()) {
200+
this.bankAccount = bankAccount;
201+
}
202+
203+
// 연락처
204+
if (managerPhone != null && !managerPhone.isBlank()) {
205+
this.managerPhone = managerPhone;
206+
}
207+
}
208+
209+
// ==== 통계 정보 업데이트 메서드 ==== //
210+
211+
/**
212+
* 팔로워 수 증가
213+
*/
214+
public void increaseFollowerCount() {
215+
this.followerCount++;
216+
}
217+
218+
/**
219+
* 판매액 증가
220+
*/
221+
public void addSales(Long amount) {
222+
if (amount <= 0) {
223+
throw new ServiceException("400", "판매액은 0보다 커야 합니다.");
224+
}
225+
this.totalSales += amount;
226+
}
227+
228+
/**
229+
* 팔로워 수 감소
230+
*/
231+
public void decreaseFollowerCount() {
232+
if (this.followerCount > 0) {
233+
this.followerCount--;
234+
}
235+
}
236+
237+
/**
238+
* 상품 수 증가
239+
*/
240+
public void increaseProductCount() {
241+
this.productCount++;
242+
}
243+
244+
/**
245+
* 상품 수 감소
246+
*/
247+
public void decreaseProductCount() {
248+
if (this.productCount > 0) {
249+
this.productCount--;
250+
}
251+
}
252+
253+
// ==== 검증 메서드 ==== //
254+
255+
/**
256+
* 본인 프로필인지 확인
257+
*/
258+
public boolean isOwnedBy(Long userId) {
259+
return this.user.getId().equals(userId);
260+
}
261+
262+
/**
263+
* 본인 프로필이 아닌 경우 예외 발생
264+
*/
265+
public void validateOwnership(Long userId) {
266+
if (!isOwnedBy(userId)) {
267+
throw new ServiceException("403", "본인의 프로필만 수정할 수 있습니다.");
268+
}
269+
}
270+
271+
}

0 commit comments

Comments
 (0)