-
Notifications
You must be signed in to change notification settings - Fork 0
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
기록하기 API #22
기록하기 API #22
Changes from all commits
7e7893a
26e8614
a3de591
97578d8
74d9608
6b937b3
da0fade
729382a
0eb8d41
8a55c1e
8f16ff7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
package com.dnd.dndtravel.map.controller.request; | ||
|
||
import java.time.LocalDate; | ||
import java.util.List; | ||
|
||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
import com.dnd.dndtravel.map.controller.request.validation.RegionCondition; | ||
import com.dnd.dndtravel.map.controller.request.validation.RegionEnum; | ||
import com.dnd.dndtravel.map.dto.RecordDto; | ||
|
||
import jakarta.validation.constraints.NotBlank; | ||
import jakarta.validation.constraints.NotNull; | ||
import jakarta.validation.constraints.Pattern; | ||
import jakarta.validation.constraints.Size; | ||
//todo 회의 후 제약조건 변경 필요 | ||
public record RecordRequest( | ||
@RegionEnum(enumClass = RegionCondition.class) | ||
String region, | ||
|
||
@NotBlank(message = "명소 이름은 필수 입력 사항입니다.") | ||
@Pattern(regexp = "^[가-힣]+$", message = "명소 이름은 한글만 입력 가능합니다.") | ||
@Size(max = 50, message = "명소 이름은 50자 이내여야 합니다.") | ||
String attractionName, | ||
|
||
@Size(max = 25, message = "메모는 25자 이내여야 합니다.") | ||
String memo, | ||
|
||
@NotNull(message = "날짜는 필수 입력 사항입니다.") | ||
LocalDate localDate | ||
Comment on lines
+29
to
+30
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 이거 포맷 프로토타입에서 기록할 때 날짜 형식은 2024년7월21일로 되어 있고, 기록 확인할 때는 24.07.21 되어 있네용 ?! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 클라에서 포맷팅 해줄겁니다 |
||
) { | ||
public RecordDto toDto(List<MultipartFile> photos) { | ||
return RecordDto.builder() | ||
.region(this.region) | ||
.attractionName(this.attractionName) | ||
.photos(photos) | ||
.memo(this.memo) | ||
.dateTime(this.localDate) | ||
.build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.dnd.dndtravel.map.controller.request.validation; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
import jakarta.validation.Constraint; | ||
|
||
@Constraint(validatedBy = {PhotoValidator.class}) | ||
@Target(ElementType.PARAMETER) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface PhotoValidation { | ||
String message() default "invalid photo size"; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.dnd.dndtravel.map.controller.request.validation; | ||
|
||
import java.util.List; | ||
|
||
import org.springframework.web.multipart.MultipartFile; | ||
|
||
import jakarta.validation.ConstraintValidator; | ||
import jakarta.validation.ConstraintValidatorContext; | ||
|
||
public class PhotoValidator implements ConstraintValidator<PhotoValidation, List<MultipartFile>> { | ||
|
||
@Override | ||
public boolean isValid(List<MultipartFile> photos, ConstraintValidatorContext context) { | ||
return photos.size() <= 3; | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package com.dnd.dndtravel.map.controller.request.validation; | ||
|
||
import java.util.Arrays; | ||
|
||
import lombok.Getter; | ||
|
||
@Getter | ||
public enum RegionCondition { | ||
서울("서울"), | ||
부산("부산"), | ||
대구("대구"), | ||
인천("인천"), | ||
광주("광주"), | ||
대전("대전"), | ||
울산("울산"), | ||
경기도("경기도"), | ||
강원도("강원도"), | ||
충청북도("충청북도"), | ||
충남세종("충남·세종"), | ||
전라북도("전라북도"), | ||
전라남도("전라남도"), | ||
경상북도("경상북도"), | ||
경상남도("경상남도"), | ||
제주도("제주도"); | ||
|
||
private final String value; | ||
|
||
RegionCondition(String value) { | ||
this.value = value; | ||
} | ||
|
||
public static boolean isMatch(String region) { | ||
return Arrays.stream(RegionCondition.values()) | ||
.anyMatch(regionCondition -> regionCondition.getValue().equals(region)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
package com.dnd.dndtravel.map.controller.request.validation; | ||
|
||
import java.lang.annotation.ElementType; | ||
import java.lang.annotation.Retention; | ||
import java.lang.annotation.RetentionPolicy; | ||
import java.lang.annotation.Target; | ||
|
||
import jakarta.validation.Constraint; | ||
|
||
@Constraint(validatedBy = {RegionValidator.class}) | ||
@Target(ElementType.FIELD) | ||
@Retention(RetentionPolicy.RUNTIME) | ||
public @interface RegionEnum { | ||
String message() default "invalid region"; | ||
Class<? extends java.lang.Enum<?>> enumClass(); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
package com.dnd.dndtravel.map.controller.request.validation; | ||
|
||
import java.util.Arrays; | ||
|
||
import jakarta.validation.ConstraintValidator; | ||
import jakarta.validation.ConstraintValidatorContext; | ||
|
||
public class RegionValidator implements ConstraintValidator<RegionEnum, String> { | ||
|
||
private RegionEnum annotation; | ||
|
||
@Override | ||
public void initialize(RegionEnum constraintAnnotation) { | ||
this.annotation = constraintAnnotation; | ||
} | ||
|
||
@Override | ||
public boolean isValid(String region, ConstraintValidatorContext context) { | ||
// 지역 입력안하면 예외 | ||
if (region == null) { | ||
return false; | ||
} | ||
|
||
Object[] enumValues = this.annotation.enumClass().getEnumConstants(); | ||
if (enumValues == null) { | ||
return false; | ||
} | ||
|
||
// 지역 Enum중 하나라도 해당되면 true | ||
return Arrays.stream(enumValues).anyMatch(enumValue -> RegionCondition.isMatch(region)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
package com.dnd.dndtravel.map.domain; | ||
|
||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.FetchType; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.JoinColumn; | ||
import jakarta.persistence.ManyToOne; | ||
import lombok.AccessLevel; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@Entity | ||
public class Attraction { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "region_id") | ||
private Region region; | ||
|
||
private String name; // 명소 이름 | ||
|
||
@Builder | ||
private Attraction(Region region, String name) { | ||
this.region = region; | ||
this.name = name; | ||
} | ||
|
||
public static Attraction of(Region region, String attraction) { | ||
return new Attraction(region, attraction); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,63 @@ | ||
package com.dnd.dndtravel.map.domain; | ||
|
||
import java.time.LocalDate; | ||
|
||
import com.dnd.dndtravel.member.domain.Member; | ||
|
||
import jakarta.persistence.Entity; | ||
import jakarta.persistence.FetchType; | ||
import jakarta.persistence.GeneratedValue; | ||
import jakarta.persistence.GenerationType; | ||
import jakarta.persistence.Id; | ||
import jakarta.persistence.JoinColumn; | ||
import jakarta.persistence.ManyToOne; | ||
import lombok.AccessLevel; | ||
import lombok.Builder; | ||
import lombok.Getter; | ||
import lombok.NoArgsConstructor; | ||
|
||
@Getter | ||
@NoArgsConstructor(access = AccessLevel.PROTECTED) | ||
@Entity | ||
public class MemberAttraction { | ||
|
||
@Id | ||
@GeneratedValue(strategy = GenerationType.IDENTITY) | ||
private Long id; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "member_id") | ||
private Member member; | ||
|
||
@ManyToOne(fetch = FetchType.LAZY) | ||
@JoinColumn(name = "attraction_id") | ||
private Attraction attraction; | ||
|
||
private String memo; // 방문기록 메모 | ||
private LocalDate localDate; // 방문 날짜 | ||
private String region; // 지역 | ||
private int photosCount; // 사진 개수, 필요한가? | ||
//todo 명소 이름도 필요할지도? | ||
|
||
@Builder | ||
private MemberAttraction(Member member, Attraction attraction, String memo, LocalDate localDate, String region, | ||
int photosCount) { | ||
this.member = member; | ||
this.attraction = attraction; | ||
this.memo = memo; | ||
this.localDate = localDate; | ||
this.region = region; | ||
this.photosCount = photosCount; | ||
} | ||
|
||
public static MemberAttraction of(Member member, Attraction attraction, String memo, LocalDate localDate, | ||
String region) { | ||
return MemberAttraction.builder() | ||
.member(member) | ||
.attraction(attraction) | ||
.memo(memo) | ||
.localDate(localDate) | ||
.region(region) | ||
.build(); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,15 +40,23 @@ private MemberRegion(Member member, Region region, int visitCount) { | |
this.visitCount = visitCount; | ||
} | ||
|
||
public static MemberRegion of(Member member, Region region, int visitCount) { | ||
public static MemberRegion of(Member member, Region region) { | ||
return MemberRegion.builder() | ||
.member(member) | ||
.region(region) | ||
.visitCount(visitCount) | ||
.visitCount(1) | ||
Comment on lines
-43
to
+47
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. visitCount을 지우신 이유가 있나용 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. MemberRegion 객체는 특정 지역에 방문했을때 최초로 생성이되고, 이후에는 visitCount가 add되는 형태라서 이 객체를 생성했을땐 1번 방문했다는거고, 임의의 visitCount를 받아 생성할 일은 없다고 판단했어요 |
||
.build(); | ||
} | ||
|
||
public boolean isVisited() { | ||
return this.visitCount > 0; | ||
} | ||
|
||
public boolean isEqualRegion(String regionName) { | ||
return this.region.getName().equals(regionName); | ||
} | ||
|
||
public void addVisitCount() { | ||
this.visitCount++; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
프로토타입에는 명소명 20자로 되어 있어요!