From 8cca07cb4141d13fe3ce5373f912f5ef272e4e1c Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Thu, 25 May 2023 14:19:15 +0900 Subject: [PATCH 001/367] Delete application-secret.yml --- src/main/resources/application-secret.yml | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 src/main/resources/application-secret.yml diff --git a/src/main/resources/application-secret.yml b/src/main/resources/application-secret.yml deleted file mode 100644 index 39e345e7..00000000 --- a/src/main/resources/application-secret.yml +++ /dev/null @@ -1,5 +0,0 @@ -spring: - config: - activate: - on-profile: secret - From 293c2eeb9a638fb7b60e31cfce7e0c0fe0c80e19 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Thu, 25 May 2023 14:19:43 +0900 Subject: [PATCH 002/367] Update .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index c2065bc2..9980efe4 100644 --- a/.gitignore +++ b/.gitignore @@ -35,3 +35,6 @@ out/ ### VS Code ### .vscode/ + +### secret yml ### +src/main/resources/application-secret.yml From 5cfa9bc19500178f0e23e84e7db030692438b7f2 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Fri, 26 May 2023 18:01:58 +0900 Subject: [PATCH 003/367] feat(project init): MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 프로젝트 기본 설정 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d976019d..8a9501cb 100644 --- a/build.gradle +++ b/build.gradle @@ -66,7 +66,7 @@ dependencies { tasks.named('test') { useJUnitPlatform() } - +//sadsadsadasd jar { enabled = true; } \ No newline at end of file From 2bb29e2d56524ced4bacb2b1cac3b16bc795a5fb Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Fri, 26 May 2023 18:05:29 +0900 Subject: [PATCH 004/367] =?UTF-8?q?feat(project=20init):=20=ED=94=84?= =?UTF-8?q?=EB=A1=9C=EC=A0=9D=ED=8A=B8=20=EA=B8=B0=EB=B3=B8=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 프로젝트 기본 설정 --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8a9501cb..d976019d 100644 --- a/build.gradle +++ b/build.gradle @@ -66,7 +66,7 @@ dependencies { tasks.named('test') { useJUnitPlatform() } -//sadsadsadasd + jar { enabled = true; } \ No newline at end of file From af02772acbd1b08fd3b1314c74770fc7d1dffe3c Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Fri, 26 May 2023 18:56:50 +0900 Subject: [PATCH 005/367] docs: yml modify --- src/main/resources/application.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 98b3e6d1..9478edc6 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -5,16 +5,16 @@ spring: pathmatch: matching-strategy: ant_path_matcher datasource: - # H2 -# driver-class-name: org.h2.Driver -# url: jdbc:h2:tcp://localhost/~/db/TrendPick -# username: sa -# password: -# mariaDB - driver-class-name: org.mariadb.jdbc.Driver - url: jdbc:mariadb://127.0.0.1:3306/TrendPick__dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul - username: root - password: + # H2 + # driver-class-name: org.h2.Driver + # url: jdbc:h2:tcp://localhost/~/db/TrendPick + # username: sa + # password: + # mariaDB + driver-class-name: org.mariadb.jdbc.Driver + url: jdbc:mariadb://127.0.0.1:${maria.port}/TrendPick__dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul + username: root + password: ${maria.password} jpa: hibernate: ddl-auto: create From 81f640cae49e8b3aa71b83e456fe04d5430d257e Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 26 May 2023 19:15:09 +0900 Subject: [PATCH 006/367] =?UTF-8?q?chore:=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/answer/controller/AnswerController.java | 4 ++++ .../project/trendpick_pro/domain/answer/entity/Answer.java | 4 ++++ .../domain/answer/repository/AnswerRepository.java | 4 ++++ .../trendpick_pro/domain/answer/service/AnswerService.java | 4 ++++ .../trendpick_pro/domain/ask/controller/AskController.java | 4 ++++ .../java/project/trendpick_pro/domain/ask/entity/Ask.java | 4 ++++ .../trendpick_pro/domain/ask/entity/dto/AskRequestDto.java | 4 ++++ .../trendpick_pro/domain/ask/entity/dto/AskResponseDto.java | 4 ++++ .../trendpick_pro/domain/ask/repository/AskRepository.java | 4 ++++ .../project/trendpick_pro/domain/ask/service/AskService.java | 4 ++++ 10 files changed, 40 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java create mode 100644 src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java create mode 100644 src/main/java/project/trendpick_pro/domain/answer/repository/AnswerRepository.java create mode 100644 src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java create mode 100644 src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java create mode 100644 src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java create mode 100644 src/main/java/project/trendpick_pro/domain/ask/entity/dto/AskRequestDto.java create mode 100644 src/main/java/project/trendpick_pro/domain/ask/entity/dto/AskResponseDto.java create mode 100644 src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java create mode 100644 src/main/java/project/trendpick_pro/domain/ask/service/AskService.java diff --git a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java new file mode 100644 index 00000000..74b298e9 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.answer.controller; + +public class AnswerController { +} diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java b/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java new file mode 100644 index 00000000..2e384ec7 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.answer.entity; + +public class Answer { +} diff --git a/src/main/java/project/trendpick_pro/domain/answer/repository/AnswerRepository.java b/src/main/java/project/trendpick_pro/domain/answer/repository/AnswerRepository.java new file mode 100644 index 00000000..1ec55cfc --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/answer/repository/AnswerRepository.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.answer.repository; + +public class AnswerRepository { +} diff --git a/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java b/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java new file mode 100644 index 00000000..c606867b --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.answer.service; + +public class AnswerService { +} diff --git a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java new file mode 100644 index 00000000..e38aa495 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.ask.controller; + +public class AskController { +} diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java b/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java new file mode 100644 index 00000000..4c403885 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.ask.entity; + +public class Ask { +} diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/AskRequestDto.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/AskRequestDto.java new file mode 100644 index 00000000..3ae37f1e --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/AskRequestDto.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.ask.entity.dto; + +public class AskRequestDto { +} diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/AskResponseDto.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/AskResponseDto.java new file mode 100644 index 00000000..2aec82e4 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/AskResponseDto.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.ask.entity.dto; + +public class AskResponseDto { +} diff --git a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java new file mode 100644 index 00000000..dfba8912 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.ask.repository; + +public class AskRepository { +} diff --git a/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java b/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java new file mode 100644 index 00000000..f19aff9b --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.ask.service; + +public class AskService { +} From 805c2738391b4623834134dac50131129e36b200 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Fri, 26 May 2023 19:23:33 +0900 Subject: [PATCH 007/367] =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6b339a1d..83800fb9 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,3 @@ TrendPick -프로젝트 트렌드픽입니다. \ No newline at end of file +프로젝트 트렌드픽입니다. +test 입니다. \ No newline at end of file From cd8002698e3bcc43c6829b844a07d3a30e295807 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 26 May 2023 23:08:04 +0900 Subject: [PATCH 008/367] =?UTF-8?q?feat:=20ask,answer=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=EB=A7=B5=ED=95=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/answer/entity/QAnswer.java | 57 +++++++++++++++++++ .../trendpick_pro/domain/ask/entity/QAsk.java | 48 ++++++++++++++++ .../TrendPickProApplication.java | 3 +- .../domain/answer/entity/Answer.java | 31 ++++++++++ .../trendpick_pro/domain/ask/entity/Ask.java | 36 ++++++++++++ src/main/resources/application.yml | 18 +++--- 6 files changed, 183 insertions(+), 10 deletions(-) create mode 100644 src/main/generated/project/trendpick_pro/domain/answer/entity/QAnswer.java create mode 100644 src/main/generated/project/trendpick_pro/domain/ask/entity/QAsk.java diff --git a/src/main/generated/project/trendpick_pro/domain/answer/entity/QAnswer.java b/src/main/generated/project/trendpick_pro/domain/answer/entity/QAnswer.java new file mode 100644 index 00000000..1bcc8176 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/answer/entity/QAnswer.java @@ -0,0 +1,57 @@ +package project.trendpick_pro.domain.answer.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; + + +/** + * QAnswer is a Querydsl query type for Answer + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QAnswer extends EntityPathBase { + + private static final long serialVersionUID = -301394004L; + + private static final PathInits INITS = PathInits.DIRECT2; + + public static final QAnswer answer = new QAnswer("answer"); + + public final project.trendpick_pro.domain.ask.entity.QAsk ask; + + public final StringPath author = createString("author"); + + public final StringPath content = createString("content"); + + public final DateTimePath createDate = createDateTime("createDate", java.time.LocalDateTime.class); + + public final NumberPath id = createNumber("id", Long.class); + + public QAnswer(String variable) { + this(Answer.class, forVariable(variable), INITS); + } + + public QAnswer(Path path) { + this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); + } + + public QAnswer(PathMetadata metadata) { + this(metadata, PathInits.getFor(metadata, INITS)); + } + + public QAnswer(PathMetadata metadata, PathInits inits) { + this(Answer.class, metadata, inits); + } + + public QAnswer(Class type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + this.ask = inits.isInitialized("ask") ? new project.trendpick_pro.domain.ask.entity.QAsk(forProperty("ask")) : null; + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/ask/entity/QAsk.java b/src/main/generated/project/trendpick_pro/domain/ask/entity/QAsk.java new file mode 100644 index 00000000..0296ca92 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/ask/entity/QAsk.java @@ -0,0 +1,48 @@ +package project.trendpick_pro.domain.ask.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; + + +/** + * QAsk is a Querydsl query type for Ask + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QAsk extends EntityPathBase { + + private static final long serialVersionUID = -658585546L; + + public static final QAsk ask = new QAsk("ask"); + + public final ListPath answerList = this.createList("answerList", project.trendpick_pro.domain.answer.entity.Answer.class, project.trendpick_pro.domain.answer.entity.QAnswer.class, PathInits.DIRECT2); + + public final StringPath author = createString("author"); + + public final StringPath content = createString("content"); + + public final DateTimePath createDate = createDateTime("createDate", java.time.LocalDateTime.class); + + public final NumberPath id = createNumber("id", Long.class); + + public final StringPath title = createString("title"); + + public QAsk(String variable) { + super(Ask.class, forVariable(variable)); + } + + public QAsk(Path path) { + super(path.getType(), path.getMetadata()); + } + + public QAsk(PathMetadata metadata) { + super(Ask.class, metadata); + } + +} + diff --git a/src/main/java/project/trendpick_pro/TrendPickProApplication.java b/src/main/java/project/trendpick_pro/TrendPickProApplication.java index dd9f1c4e..b81d1c12 100644 --- a/src/main/java/project/trendpick_pro/TrendPickProApplication.java +++ b/src/main/java/project/trendpick_pro/TrendPickProApplication.java @@ -2,12 +2,13 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @SpringBootApplication +@EnableJpaAuditing public class TrendPickProApplication { public static void main(String[] args) { SpringApplication.run(TrendPickProApplication.class, args); } - } diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java b/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java index 2e384ec7..c58dfe1a 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java +++ b/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java @@ -1,4 +1,35 @@ package project.trendpick_pro.domain.answer.entity; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.hibernate.annotations.Fetch; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import project.trendpick_pro.domain.ask.entity.Ask; + +import java.time.LocalDateTime; + +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Getter +@EntityListeners(AuditingEntityListener.class) public class Answer { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "answer_id") + private Long id; + private String author; //멤버 엔티티와 맵핑 해줘야 한다. (임시 String) + @CreatedDate + private LocalDateTime createDate; + + @ManyToOne + @JoinColumn(name = "ask_id") + private Ask ask; + + private String content; } diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java b/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java index 4c403885..779df7a4 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java @@ -1,4 +1,40 @@ package project.trendpick_pro.domain.ask.entity; +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import project.trendpick_pro.domain.answer.entity.Answer; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Getter +@EntityListeners(AuditingEntityListener.class) public class Ask { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "ask_id") + private Long id; + private String author; //멤버 엔티티로 수정 필요 + private String brand; //브랜드 엔티티로 수정 필요 + @CreatedDate + private LocalDateTime createDate; + + private String title; + private String content; + + @OneToMany(mappedBy = "ask", cascade = CascadeType.ALL) + @Builder.Default + private List answerList = new ArrayList<>(); + } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 9478edc6..9956ef2b 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -5,16 +5,16 @@ spring: pathmatch: matching-strategy: ant_path_matcher datasource: - # H2 - # driver-class-name: org.h2.Driver - # url: jdbc:h2:tcp://localhost/~/db/TrendPick - # username: sa - # password: +# H2 + driver-class-name: org.h2.Driver + url: jdbc:h2:tcp://localhost/~/db/TrendPick + username: sa + password: # mariaDB - driver-class-name: org.mariadb.jdbc.Driver - url: jdbc:mariadb://127.0.0.1:${maria.port}/TrendPick__dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul - username: root - password: ${maria.password} +# driver-class-name: org.mariadb.jdbc.Driver +# url: jdbc:mariadb://127.0.0.1:${maria.port}/TrendPick__dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul +# username: root +# password: ${maria.password} jpa: hibernate: ddl-auto: create From 144e2bbc185ff76fb04a9ef060f1a07e3bd9f9ad Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 26 May 2023 23:17:26 +0900 Subject: [PATCH 009/367] =?UTF-8?q?feat:=20Q=20=ED=81=B4=EB=9E=98=EC=8A=A4?= =?UTF-8?q?=20=EC=9E=90=EB=8F=99=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../generated/project/trendpick_pro/domain/ask/entity/QAsk.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/generated/project/trendpick_pro/domain/ask/entity/QAsk.java b/src/main/generated/project/trendpick_pro/domain/ask/entity/QAsk.java index 0296ca92..4fc937b0 100644 --- a/src/main/generated/project/trendpick_pro/domain/ask/entity/QAsk.java +++ b/src/main/generated/project/trendpick_pro/domain/ask/entity/QAsk.java @@ -24,6 +24,8 @@ public class QAsk extends EntityPathBase { public final StringPath author = createString("author"); + public final StringPath brand = createString("brand"); + public final StringPath content = createString("content"); public final DateTimePath createDate = createDateTime("createDate", java.time.LocalDateTime.class); From f5c168258c80001763d57edbf134dff1a8abd7ee Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sat, 27 May 2023 00:46:48 +0900 Subject: [PATCH 010/367] =?UTF-8?q?feat:=20ask,=20answer=20=EC=BB=A8?= =?UTF-8?q?=ED=8A=B8=EB=A1=A4=EB=9F=AC=20=ED=8B=80=20=EB=A7=8C=EB=93=A4?= =?UTF-8?q?=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../answer/controller/AnswerController.java | 39 ++++++++++++++++++ .../answer/entity/dto/AnswerRequestDto.java | 4 ++ .../answer/entity/dto/AnswerResponseDto.java | 4 ++ .../domain/ask/controller/AskController.java | 40 +++++++++++++++++++ .../trendpick_pro/domain/ask/entity/Ask.java | 1 - 5 files changed, 87 insertions(+), 1 deletion(-) create mode 100644 src/main/java/project/trendpick_pro/domain/answer/entity/dto/AnswerRequestDto.java create mode 100644 src/main/java/project/trendpick_pro/domain/answer/entity/dto/AnswerResponseDto.java diff --git a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java index 74b298e9..f86eea54 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java +++ b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java @@ -1,4 +1,43 @@ package project.trendpick_pro.domain.answer.controller; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; +import project.trendpick_pro.domain.answer.entity.dto.AnswerRequestDto; +import project.trendpick_pro.domain.ask.entity.Ask; + +import java.util.List; + +@Controller +@RequiredArgsConstructor +@RequestMapping("/answer") public class AnswerController { + + @GetMapping("/list") + public String showAnswers(){ + + return "redirect:/ask/list"; + } + + @PostMapping("/{id}") + public String addAnswer(@PathVariable Long askId, + @Valid AnswerRequestDto answerRequestDto){ + + return "redirect:/ask/list"; + } + + @DeleteMapping("/{id}") + public String deleteAnswer(@PathVariable Long id){ + + return "redirect:/ask/list"; + } + + @PatchMapping("/{id}") + public String modifyAnswer(@PathVariable Long id){ + + return "redirect:/ask/list"; + } + + } diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/dto/AnswerRequestDto.java b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/AnswerRequestDto.java new file mode 100644 index 00000000..a67dce34 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/AnswerRequestDto.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.answer.entity.dto; + +public class AnswerRequestDto { +} diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/dto/AnswerResponseDto.java b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/AnswerResponseDto.java new file mode 100644 index 00000000..ad6d9e7d --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/AnswerResponseDto.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.answer.entity.dto; + +public class AnswerResponseDto { +} diff --git a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java index e38aa495..a844e6cd 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java +++ b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java @@ -1,4 +1,44 @@ package project.trendpick_pro.domain.ask.controller; +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; +import project.trendpick_pro.domain.answer.entity.dto.AnswerRequestDto; +import project.trendpick_pro.domain.ask.entity.dto.AskRequestDto; + +@Controller +@RequiredArgsConstructor +@RequestMapping("/ask") public class AskController { + + @GetMapping("/list") + public String showAsks(){ + + return "/ask/list"; + } + + @GetMapping("/detail/{id}") + public String showAsk(@PathVariable Long id){ + + return "/ask/detail"; + } + + @PostMapping("/delete/{id}") + public String deleteAsk(@PathVariable Long id){ + + return "redirect:/ask/get/%s".formatted(id); + } + + @PostMapping("/modify/{id}") + public String modifyAsk(@PathVariable Long id){ + + return "redirect:/ask/get/%s".formatted(id); + } + + @PostMapping("/add/{brandId}") + public String addAsk(@Valid AskRequestDto askRequestDto, @PathVariable Long brandId){ + + return "redirect:/ask/list"; + } } diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java b/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java index 779df7a4..cf4dc00b 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java @@ -36,5 +36,4 @@ public class Ask { @OneToMany(mappedBy = "ask", cascade = CascadeType.ALL) @Builder.Default private List answerList = new ArrayList<>(); - } From 0227c30f35c562b57d075da9dcec62ecd185ac4f Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Sat, 27 May 2023 14:04:04 +0900 Subject: [PATCH 011/367] docs: yml Modify --- src/main/resources/application.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 9956ef2b..88d90d8e 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -6,15 +6,15 @@ spring: matching-strategy: ant_path_matcher datasource: # H2 - driver-class-name: org.h2.Driver - url: jdbc:h2:tcp://localhost/~/db/TrendPick - username: sa - password: +# driver-class-name: org.h2.Driver +# url: jdbc:h2:tcp://localhost/~/db/TrendPick +# username: sa +# password: # mariaDB -# driver-class-name: org.mariadb.jdbc.Driver -# url: jdbc:mariadb://127.0.0.1:${maria.port}/TrendPick__dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul -# username: root -# password: ${maria.password} + driver-class-name: org.mariadb.jdbc.Driver + url: jdbc:mariadb://127.0.0.1:${maria.port}/TrendPick__dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul + username: ${maria.username} + password: ${maria.password} jpa: hibernate: ddl-auto: create From 407c434a13f58df9286bce4e06a22815a6279011 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 28 May 2023 00:50:01 +0900 Subject: [PATCH 012/367] =?UTF-8?q?docs:=20yml=20=EA=B5=AC=EC=A1=B0?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 88d90d8e..1590754a 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -6,10 +6,10 @@ spring: matching-strategy: ant_path_matcher datasource: # H2 -# driver-class-name: org.h2.Driver -# url: jdbc:h2:tcp://localhost/~/db/TrendPick -# username: sa -# password: +# driver-class-name: org.h2.Driver +# url: jdbc:h2:tcp://localhost/~/db/TrendPick +# username: sa +# password: # mariaDB driver-class-name: org.mariadb.jdbc.Driver url: jdbc:mariadb://127.0.0.1:${maria.port}/TrendPick__dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul From ca64bc8d14eca1ba4e317b519917465ccdc09ddf Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 28 May 2023 00:50:19 +0900 Subject: [PATCH 013/367] =?UTF-8?q?feat:=20=EA=B3=B5=ED=86=B5=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/common/base/BaseTimeEntity.java | 25 ++++++++++++++++ .../domain/common/file/CommonFile.java | 30 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/common/base/BaseTimeEntity.java create mode 100644 src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java diff --git a/src/main/java/project/trendpick_pro/domain/common/base/BaseTimeEntity.java b/src/main/java/project/trendpick_pro/domain/common/base/BaseTimeEntity.java new file mode 100644 index 00000000..8c9c03bd --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/common/base/BaseTimeEntity.java @@ -0,0 +1,25 @@ +package project.trendpick_pro.domain.common.base; + +import jakarta.persistence.Column; +import jakarta.persistence.EntityListeners; +import jakarta.persistence.MappedSuperclass; +import lombok.Getter; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.time.LocalDateTime; + +@Getter +@MappedSuperclass +@EntityListeners(AuditingEntityListener.class) // 생성일, 수정일 +public abstract class BaseTimeEntity { + + @CreatedDate + @Column(name = "create_date") + private LocalDateTime createdDate; + + @LastModifiedDate + @Column(name = "modify_date") + private LocalDateTime modifiedDate; +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java b/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java new file mode 100644 index 00000000..4e5cccd6 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java @@ -0,0 +1,30 @@ +package project.trendpick_pro.domain.common.file; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class CommonFile { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String FileName; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "PARENT_ID") + private CommonFile parent; + + @OneToMany(mappedBy = "parent") + private List child = new ArrayList<>(); + + // 여기서 파일 생성 삭제 지지고 볶고 할예정 + +} From 84338b0904425c27191f54cdcdb1e531db321546 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 28 May 2023 00:50:33 +0900 Subject: [PATCH 014/367] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20html=20?= =?UTF-8?q?=ED=8C=8C=EC=9D=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/trendpick/products/detailpage.html | 10 ++++++++++ .../resources/templates/trendpick/products/list.html | 10 ++++++++++ .../templates/trendpick/products/register.html | 10 ++++++++++ 3 files changed, 30 insertions(+) create mode 100644 src/main/resources/templates/trendpick/products/detailpage.html create mode 100644 src/main/resources/templates/trendpick/products/list.html create mode 100644 src/main/resources/templates/trendpick/products/register.html diff --git a/src/main/resources/templates/trendpick/products/detailpage.html b/src/main/resources/templates/trendpick/products/detailpage.html new file mode 100644 index 00000000..566549bd --- /dev/null +++ b/src/main/resources/templates/trendpick/products/detailpage.html @@ -0,0 +1,10 @@ + + + + + Title + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/products/list.html b/src/main/resources/templates/trendpick/products/list.html new file mode 100644 index 00000000..566549bd --- /dev/null +++ b/src/main/resources/templates/trendpick/products/list.html @@ -0,0 +1,10 @@ + + + + + Title + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/products/register.html b/src/main/resources/templates/trendpick/products/register.html new file mode 100644 index 00000000..566549bd --- /dev/null +++ b/src/main/resources/templates/trendpick/products/register.html @@ -0,0 +1,10 @@ + + + + + Title + + + + + \ No newline at end of file From d805b7e3e7eabfb560a7bee88dd892a50fb5015d Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 28 May 2023 00:50:52 +0900 Subject: [PATCH 015/367] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 56 +++++++++++ .../domain/product/entity/Product.java | 96 +++++++++++++++++++ .../dto/request/ProductSaveRequest.java | 43 +++++++++ .../entity/dto/response/ProductResponse.java | 73 ++++++++++++++ .../dto/response/ProductWithIdResponse.java | 27 ++++++ .../product/repository/ProductRepository.java | 7 ++ .../product/service/ProductService.java | 64 +++++++++++++ 7 files changed, 366 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java create mode 100644 src/main/java/project/trendpick_pro/domain/product/entity/Product.java create mode 100644 src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java create mode 100644 src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java create mode 100644 src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductWithIdResponse.java create mode 100644 src/main/java/project/trendpick_pro/domain/product/repository/ProductRepository.java create mode 100644 src/main/java/project/trendpick_pro/domain/product/service/ProductService.java diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java new file mode 100644 index 00000000..eebf5283 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -0,0 +1,56 @@ +package project.trendpick_pro.domain.product.controller; + +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; +import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; +import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; +import project.trendpick_pro.domain.product.service.ProductService; + +@Slf4j +@Controller +@RequiredArgsConstructor +@RequestMapping("trendpick/products") +public class ProductController { + + private ProductService productService; + + @PostMapping("/register") + public String registerProduct(@Valid ProductSaveRequest productSaveRequest, Model model) { + + ProductResponse productResponse = productService.register(productSaveRequest); + model.addAttribute("productResponse", productResponse); + + return "redirect:/trendpick/products/" + productResponse.getId(); + } + + @PostMapping("/edit/{productId}") + public String modifyProduct(@PathVariable Long productId, @Valid ProductSaveRequest productSaveRequest, Model model) { + + ProductResponse productResponse = productService.modify(productId, productSaveRequest); + model.addAttribute("productResponse", productResponse); + + return "redirect:/trendpick/products/" + productResponse.getId(); + } + + @DeleteMapping("/{productId}") + public String deleteProduct(@PathVariable Long productId) { + productService.delete(productId); + return "redirect:/trendpick/products/list"; + } + + @GetMapping("/{productId}") + public String showProduct(@PathVariable Long productId, Model model) { + model.addAttribute("productResponse", productService.show(productId)); + return "/trendpick/products/detailpage"; + } + + @GetMapping("/list") + public String showAllProduct(Model model) { + model.addAttribute("productResponse", productService.showAll()); + return "/trendpick/products/detailpage"; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java new file mode 100644 index 00000000..7f0801bd --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -0,0 +1,96 @@ +package project.trendpick_pro.domain.product.entity; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.web.multipart.MultipartFile; +import project.trendpick_pro.domain.common.base.BaseTimeEntity; +import project.trendpick_pro.domain.common.file.CommonFile; +import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; +import project.trendpick_pro.domain.tag.entity.Tag; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Product extends BaseTimeEntity { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "name", nullable = false) + private String name; + +// @ManyToOne(fetch = FetchType.LAZY) +// @JoinColumn(name = "main-category_id") + private String mainCategory; // Category + +// @ManyToOne(fetch = FetchType.LAZY) +// @JoinColumn(name = "sub-category_id") + @ElementCollection // 이거 빨간줄 때문에 예비로 추가한거라 보고 추가하시면 안되요!!! + private List subCategory = new ArrayList<>(); // Category + + +// @ManyToOne(fetch = FetchType.LAZY) +// @JoinColumn(name = "brand_id") + private String brand; // Brand + + @Column(name = "description", nullable = false) + private String description; + + @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @JoinColumn(name = "common_file_id") + private CommonFile commonFile; + + @Column(name = "price", nullable = false) + private int price; + + @Column(name = "stock", nullable = false) + private int stock; + + @OneToMany(mappedBy = "product", cascade = CascadeType.ALL) + private List tags = new ArrayList<>(); + + @Builder + public Product(String name, String mainCategory, List subCategory, String brand, + String description, CommonFile commonFile, int price, int stock, List tags) { + this.name = name; + this.mainCategory = mainCategory; + this.subCategory = subCategory; + this.brand = brand; + this.description = description; + this.commonFile = commonFile; + this.price = price; + this.stock = stock; + this.tags = tags; + } + + public static Product of(ProductSaveRequest request) { + return Product.builder() + .name(request.getName()) + .mainCategory(request.getMainCategory()) + .subCategory(request.getSubCategory()) + .brand(request.getBrand()) + .description(request.getDescription()) + .commonFile(makeFiles(request.getMainFile(), request.getSubFiles())) + .price(request.getPrice()) + .stock(request.getStock()) + .tags(request.getTags()) + .build(); + } + + public void update(ProductSaveRequest request) { + + // 여기서 파일 지지고 볶고 할 예정 + } + + private static CommonFile makeFiles(MultipartFile mainFile, List subFiles) { + return null; + + // 여기서 파일 지지고 볶고 할 예정 + } +} diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java new file mode 100644 index 00000000..083f838c --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java @@ -0,0 +1,43 @@ +package project.trendpick_pro.domain.product.entity.dto.request; + +import jakarta.validation.constraints.NotBlank; +import lombok.Data; +import org.springframework.web.multipart.MultipartFile; +import project.trendpick_pro.domain.tag.entity.Tag; + +import java.util.List; + +@Data +public class ProductSaveRequest { + + @NotBlank(message = "제목을 입력해주세요.") + private String name; + + @NotBlank(message = "내용을 입력해주세요.") + private String description; + + @NotBlank(message = "메인 카테고리를 정하세요.") + private String mainCategory; // Category + + @NotBlank(message = "서브 카테고리를 정하세요.") + private List subCategory; // Category + + @NotBlank(message = "브랜드를 입력해주세요.") + private String brand; // Brand + + @NotBlank(message = "메인 사진을 입력해주세요.") + private MultipartFile mainFile; + + @NotBlank(message = "서브 사진들을 입력해주세요.") + private List subFiles; + + @NotBlank(message = "가격을 입력해주세요.") + private int price; + + @NotBlank(message = "수량을 입력해주세요.") + private int stock; + + @NotBlank(message = "포함될 태그들을 추가해주세요.") + private List tags; + +} diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java new file mode 100644 index 00000000..f5a770aa --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java @@ -0,0 +1,73 @@ +package project.trendpick_pro.domain.product.entity.dto.response; + +import com.querydsl.core.annotations.QueryProjection; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.common.file.CommonFile; +import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.tag.entity.Tag; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ProductResponse { + + private Long id; + private String name; + private String mainCategory; // Category + private List subCategory; // Category + private String brand; // Brand + private String description; + private String mainFile; + private List subFiles; + private int price; + private int stock; + private List tags = new ArrayList<>(); + + @Builder + @QueryProjection + public ProductResponse(Long id, String name, String mainCategory, List subCategory, String brand, String description, + String mainFile, List subFiles, int price, int stock, List tags) { + this.id = id; + this.name = name; + this.mainCategory = mainCategory; + this.subCategory = subCategory; + this.brand = brand; + this.description = description; + this.mainFile = mainFile; + this.subFiles = subFiles; + this.price = price; + this.stock = stock; + this.tags = tags; + } + + public static ProductResponse of (Product product) { + return ProductResponse.builder() + .id(product.getId()) + .name(product.getName()) + .mainCategory(product.getMainCategory()) + .subCategory(product.getSubCategory()) + .brand(product.getBrand()) + .description(product.getDescription()) + .mainFile(product.getCommonFile().getFileName()) + .subFiles(subFiles(product.getCommonFile().getChild())) + .price(product.getPrice()) + .stock(product.getStock()) + .tags(product.getTags()) + .build(); + } + + private static List subFiles(List subFiles) { + List tmpList = new ArrayList<>(); + + for (CommonFile subFile : subFiles) { + tmpList.add(subFile.getFileName()); + } + return tmpList; + } +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductWithIdResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductWithIdResponse.java new file mode 100644 index 00000000..90558953 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductWithIdResponse.java @@ -0,0 +1,27 @@ +package project.trendpick_pro.domain.product.entity.dto.response; + +import com.querydsl.core.annotations.QueryProjection; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.common.file.CommonFile; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ProductWithIdResponse { + + private Long id; + private String name; + private String brand; + private CommonFile mainFile; + private int price; + + @QueryProjection + public ProductWithIdResponse(Long id, String name, String brand, CommonFile mainFile, int price) { + this.id = id; + this.name = name; + this.brand = brand; + this.mainFile = mainFile; + this.price = price; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepository.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepository.java new file mode 100644 index 00000000..be72db00 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepository.java @@ -0,0 +1,7 @@ +package project.trendpick_pro.domain.product.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.product.entity.Product; + +public interface ProductRepository extends JpaRepository { +} diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java new file mode 100644 index 00000000..4633c531 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -0,0 +1,64 @@ +package project.trendpick_pro.domain.product.service; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; +import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; +import project.trendpick_pro.domain.product.repository.ProductRepository; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class ProductService { + + private ProductRepository productRepository; + + @Transactional + public ProductResponse register(ProductSaveRequest productSaveRequest) { + Product product = Product.of(productSaveRequest); + productRepository.save(product); + return ProductResponse.of(product); + } + + @Transactional + public ProductResponse modify(Long productId, ProductSaveRequest productSaveRequest) { + + Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 + product.update(productSaveRequest); + + return ProductResponse.of(product); + } + + @Transactional + public void delete(Long productId) { + Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 + productRepository.delete(product); + } + + public ProductResponse show(Long product_id) { + + Product product = productRepository.findById(product_id).orElseThrow(null);// 임시. 나중에 테스트 + + return ProductResponse.of(product); + } + + public List showAll() { + + List all = productRepository.findAll();// 임시. 나중에 테스트 + List responses = new ArrayList<>(); + + for (Product product : all) { + responses.add(ProductResponse.of(product)); + } + + return responses; + } + +} From 14a0067f8f363d55df8ee74387992f0ef797e6f0 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 28 May 2023 00:50:59 +0900 Subject: [PATCH 016/367] =?UTF-8?q?feat:=20=ED=83=9C=EA=B7=B8=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trendpick_pro/domain/tag/entity/Tag.java | 26 +++++++++++++++++++ .../domain/tag/repository/TagRepository.java | 7 +++++ 2 files changed, 33 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java create mode 100644 src/main/java/project/trendpick_pro/domain/tag/repository/TagRepository.java diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java new file mode 100644 index 00000000..b31e2048 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java @@ -0,0 +1,26 @@ +package project.trendpick_pro.domain.tag.entity; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.product.entity.Product; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Tag { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String name; + + public Tag(String name) { + this.name = name; + } + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "product_id") + private Product product; +} diff --git a/src/main/java/project/trendpick_pro/domain/tag/repository/TagRepository.java b/src/main/java/project/trendpick_pro/domain/tag/repository/TagRepository.java new file mode 100644 index 00000000..fd9262b4 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/tag/repository/TagRepository.java @@ -0,0 +1,7 @@ +package project.trendpick_pro.domain.tag.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.tag.entity.Tag; + +public interface TagRepository extends JpaRepository { +} From 23f661d58332c0ac3fed17089ac45424fdf95361 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 28 May 2023 00:51:04 +0900 Subject: [PATCH 017/367] =?UTF-8?q?feat:=20=EC=A3=BC=EB=AC=B8=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/orders/entity/OrderState.java | 5 ++++ .../domain/orders/entity/Orders.java | 25 +++++++++++++++++++ .../orders/repository/OrdersRepository.java | 7 ++++++ 3 files changed, 37 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/orders/entity/OrderState.java create mode 100644 src/main/java/project/trendpick_pro/domain/orders/entity/Orders.java create mode 100644 src/main/java/project/trendpick_pro/domain/orders/repository/OrdersRepository.java diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderState.java b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderState.java new file mode 100644 index 00000000..2e48045e --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderState.java @@ -0,0 +1,5 @@ +package project.trendpick_pro.domain.orders.entity; + +public enum OrderState { + ORDERED, CANCELLED, COMPLETED; +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/Orders.java b/src/main/java/project/trendpick_pro/domain/orders/entity/Orders.java new file mode 100644 index 00000000..e3e84a12 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/Orders.java @@ -0,0 +1,25 @@ +package project.trendpick_pro.domain.orders.entity; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.common.base.BaseTimeEntity; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Orders extends BaseTimeEntity { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private int totalPrice; + private String status; + +// @ManyToOne(fetch = FetchType.LAZY) +// @JoinColumn(name = "member_id") + private String user; // User + + +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrdersRepository.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrdersRepository.java new file mode 100644 index 00000000..9086edbc --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrdersRepository.java @@ -0,0 +1,7 @@ +package project.trendpick_pro.domain.orders.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.orders.entity.Orders; + +public interface OrdersRepository extends JpaRepository { +} From e59ac9e7f9631488dbf5d9b0846b2e0b04cbf17c Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Sun, 28 May 2023 09:35:09 +0900 Subject: [PATCH 018/367] =?UTF-8?q?feat:=20User,=20Review=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=20=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 4 ++ .../domain/review/entity/Review.java | 34 +++++++++++++++ .../review/repository/ReviewRepository.java | 7 ++++ .../domain/review/service/ReviewService.java | 4 ++ .../user/controller/UserController.java | 4 ++ .../domain/user/entity/RoleType.java | 5 +++ .../domain/user/entity/User.java | 42 +++++++++++++++++++ .../user/repository/UserRepository.java | 7 ++++ .../domain/user/service/UserService.java | 4 ++ 9 files changed, 111 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java create mode 100644 src/main/java/project/trendpick_pro/domain/review/entity/Review.java create mode 100644 src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java create mode 100644 src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java create mode 100644 src/main/java/project/trendpick_pro/domain/user/controller/UserController.java create mode 100644 src/main/java/project/trendpick_pro/domain/user/entity/RoleType.java create mode 100644 src/main/java/project/trendpick_pro/domain/user/entity/User.java create mode 100644 src/main/java/project/trendpick_pro/domain/user/repository/UserRepository.java create mode 100644 src/main/java/project/trendpick_pro/domain/user/service/UserService.java diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java new file mode 100644 index 00000000..9cbe4622 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.review.controller; + +public class ReviewController { +} diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java new file mode 100644 index 00000000..98e1be6f --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -0,0 +1,34 @@ +package project.trendpick_pro.domain.review.entity; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.common.base.BaseTimeEntity; +import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.user.entity.User; + +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Getter +public class Review extends BaseTimeEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + //@ManyToOne + //@JoinColumn(name = "user_id") + private Long user_id; //User + + //@ManyToOne + //@JoinColumn(name = "product_id") + private Long product_id; //Product + + @Lob + private String content; + + private int rating; +} diff --git a/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java b/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java new file mode 100644 index 00000000..f2d441e9 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java @@ -0,0 +1,7 @@ +package project.trendpick_pro.domain.review.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.review.entity.Review; + +public interface ReviewRepository extends JpaRepository { +} diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java new file mode 100644 index 00000000..c0270877 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.review.service; + +public class ReviewService { +} diff --git a/src/main/java/project/trendpick_pro/domain/user/controller/UserController.java b/src/main/java/project/trendpick_pro/domain/user/controller/UserController.java new file mode 100644 index 00000000..abdb19e0 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/user/controller/UserController.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.user.controller; + +public class UserController { +} diff --git a/src/main/java/project/trendpick_pro/domain/user/entity/RoleType.java b/src/main/java/project/trendpick_pro/domain/user/entity/RoleType.java new file mode 100644 index 00000000..30bdf81d --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/user/entity/RoleType.java @@ -0,0 +1,5 @@ +package project.trendpick_pro.domain.user.entity; + +public enum RoleType{ + ADMIN, BRAND_ADMIN, USER +} diff --git a/src/main/java/project/trendpick_pro/domain/user/entity/User.java b/src/main/java/project/trendpick_pro/domain/user/entity/User.java new file mode 100644 index 00000000..a99bc111 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/user/entity/User.java @@ -0,0 +1,42 @@ +package project.trendpick_pro.domain.user.entity; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.tag.entity.Tag; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; + +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Builder +@Getter +public class User { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_id") + private Long id; + + private String email; + + private String password; + + private String name; + + private String phone_num; + + private Date birth; + + private RoleType role; + + //@OneToMany(mappedBy = "user") + private Long tag_id; //private List tags= new ArrayList<>(); Tag가 N쪽인데 연관관계를 어떻게 잡아야할까용...Tag가 User를 가지고 있을 필요는 없을 것 같은데 쓰읍 + private String bank_name; + private Long account; + + +} diff --git a/src/main/java/project/trendpick_pro/domain/user/repository/UserRepository.java b/src/main/java/project/trendpick_pro/domain/user/repository/UserRepository.java new file mode 100644 index 00000000..4be0cb6c --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/user/repository/UserRepository.java @@ -0,0 +1,7 @@ +package project.trendpick_pro.domain.user.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.user.entity.User; + +public interface UserRepository extends JpaRepository { +} diff --git a/src/main/java/project/trendpick_pro/domain/user/service/UserService.java b/src/main/java/project/trendpick_pro/domain/user/service/UserService.java new file mode 100644 index 00000000..72c1a7bf --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/user/service/UserService.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.user.service; + +public class UserService { +} From 59ba737519e6d7a511cb89f1f3f834b0d04d405d Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Sun, 28 May 2023 10:35:00 +0900 Subject: [PATCH 019/367] =?UTF-8?q?fix:=20@Enumerated=20=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 --- src/main/java/project/trendpick_pro/domain/user/entity/User.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/project/trendpick_pro/domain/user/entity/User.java b/src/main/java/project/trendpick_pro/domain/user/entity/User.java index a99bc111..39f3154e 100644 --- a/src/main/java/project/trendpick_pro/domain/user/entity/User.java +++ b/src/main/java/project/trendpick_pro/domain/user/entity/User.java @@ -31,6 +31,7 @@ public class User { private Date birth; + @Enumerated(EnumType.STRING) private RoleType role; //@OneToMany(mappedBy = "user") From 547c95455e23077a6cec7225c044a2c54828a107 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 28 May 2023 13:04:03 +0900 Subject: [PATCH 020/367] =?UTF-8?q?chore:=20request,=20response=20?= =?UTF-8?q?=ED=8C=A8=ED=82=A4=EC=A7=80=20=EA=B5=AC=EC=A1=B0=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/common/base/QBaseTimeEntity.java | 39 ++++++++++ .../domain/common/file/QCommonFile.java | 55 ++++++++++++++ .../domain/orders/entity/QOrders.java | 51 +++++++++++++ .../domain/product/entity/QProduct.java | 75 +++++++++++++++++++ .../entity/dto/response/QProductResponse.java | 21 ++++++ .../dto/response/QProductWithIdResponse.java | 21 ++++++ .../trendpick_pro/domain/tag/entity/QTag.java | 53 +++++++++++++ .../answer/controller/AnswerController.java | 7 +- .../answer/entity/dto/AnswerRequestDto.java | 4 - .../answer/entity/dto/AnswerResponseDto.java | 4 - .../entity/dto/request/AnswerRequest.java | 4 + .../entity/dto/response/AnswerResponse.java | 4 + .../domain/ask/controller/AskController.java | 11 ++- .../domain/ask/entity/dto/AskRequestDto.java | 4 - .../domain/ask/entity/dto/AskResponseDto.java | 4 - .../ask/entity/dto/request/AskRequest.java | 4 + .../ask/entity/dto/response/AskResponse.java | 4 + 17 files changed, 338 insertions(+), 27 deletions(-) create mode 100644 src/main/generated/project/trendpick_pro/domain/common/base/QBaseTimeEntity.java create mode 100644 src/main/generated/project/trendpick_pro/domain/common/file/QCommonFile.java create mode 100644 src/main/generated/project/trendpick_pro/domain/orders/entity/QOrders.java create mode 100644 src/main/generated/project/trendpick_pro/domain/product/entity/QProduct.java create mode 100644 src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductResponse.java create mode 100644 src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductWithIdResponse.java create mode 100644 src/main/generated/project/trendpick_pro/domain/tag/entity/QTag.java delete mode 100644 src/main/java/project/trendpick_pro/domain/answer/entity/dto/AnswerRequestDto.java delete mode 100644 src/main/java/project/trendpick_pro/domain/answer/entity/dto/AnswerResponseDto.java create mode 100644 src/main/java/project/trendpick_pro/domain/answer/entity/dto/request/AnswerRequest.java create mode 100644 src/main/java/project/trendpick_pro/domain/answer/entity/dto/response/AnswerResponse.java delete mode 100644 src/main/java/project/trendpick_pro/domain/ask/entity/dto/AskRequestDto.java delete mode 100644 src/main/java/project/trendpick_pro/domain/ask/entity/dto/AskResponseDto.java create mode 100644 src/main/java/project/trendpick_pro/domain/ask/entity/dto/request/AskRequest.java create mode 100644 src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java diff --git a/src/main/generated/project/trendpick_pro/domain/common/base/QBaseTimeEntity.java b/src/main/generated/project/trendpick_pro/domain/common/base/QBaseTimeEntity.java new file mode 100644 index 00000000..d5f22f2f --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/common/base/QBaseTimeEntity.java @@ -0,0 +1,39 @@ +package project.trendpick_pro.domain.common.base; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; + + +/** + * QBaseTimeEntity is a Querydsl query type for BaseTimeEntity + */ +@Generated("com.querydsl.codegen.DefaultSupertypeSerializer") +public class QBaseTimeEntity extends EntityPathBase { + + private static final long serialVersionUID = 1434919534L; + + public static final QBaseTimeEntity baseTimeEntity = new QBaseTimeEntity("baseTimeEntity"); + + public final DateTimePath createdDate = createDateTime("createdDate", java.time.LocalDateTime.class); + + public final DateTimePath modifiedDate = createDateTime("modifiedDate", java.time.LocalDateTime.class); + + public QBaseTimeEntity(String variable) { + super(BaseTimeEntity.class, forVariable(variable)); + } + + public QBaseTimeEntity(Path path) { + super(path.getType(), path.getMetadata()); + } + + public QBaseTimeEntity(PathMetadata metadata) { + super(BaseTimeEntity.class, metadata); + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/common/file/QCommonFile.java b/src/main/generated/project/trendpick_pro/domain/common/file/QCommonFile.java new file mode 100644 index 00000000..8c640492 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/common/file/QCommonFile.java @@ -0,0 +1,55 @@ +package project.trendpick_pro.domain.common.file; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; + + +/** + * QCommonFile is a Querydsl query type for CommonFile + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QCommonFile extends EntityPathBase { + + private static final long serialVersionUID = 30214313L; + + private static final PathInits INITS = PathInits.DIRECT2; + + public static final QCommonFile commonFile = new QCommonFile("commonFile"); + + public final ListPath child = this.createList("child", CommonFile.class, QCommonFile.class, PathInits.DIRECT2); + + public final StringPath FileName = createString("FileName"); + + public final NumberPath id = createNumber("id", Long.class); + + public final QCommonFile parent; + + public QCommonFile(String variable) { + this(CommonFile.class, forVariable(variable), INITS); + } + + public QCommonFile(Path path) { + this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); + } + + public QCommonFile(PathMetadata metadata) { + this(metadata, PathInits.getFor(metadata, INITS)); + } + + public QCommonFile(PathMetadata metadata, PathInits inits) { + this(CommonFile.class, metadata, inits); + } + + public QCommonFile(Class type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + this.parent = inits.isInitialized("parent") ? new QCommonFile(forProperty("parent"), inits.get("parent")) : null; + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrders.java b/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrders.java new file mode 100644 index 00000000..cdfd6ac1 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrders.java @@ -0,0 +1,51 @@ +package project.trendpick_pro.domain.orders.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; + + +/** + * QOrders is a Querydsl query type for Orders + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QOrders extends EntityPathBase { + + private static final long serialVersionUID = -2056827462L; + + public static final QOrders orders = new QOrders("orders"); + + public final project.trendpick_pro.domain.common.base.QBaseTimeEntity _super = new project.trendpick_pro.domain.common.base.QBaseTimeEntity(this); + + //inherited + public final DateTimePath createdDate = _super.createdDate; + + public final NumberPath id = createNumber("id", Long.class); + + //inherited + public final DateTimePath modifiedDate = _super.modifiedDate; + + public final StringPath status = createString("status"); + + public final NumberPath totalPrice = createNumber("totalPrice", Integer.class); + + public final StringPath user = createString("user"); + + public QOrders(String variable) { + super(Orders.class, forVariable(variable)); + } + + public QOrders(Path path) { + super(path.getType(), path.getMetadata()); + } + + public QOrders(PathMetadata metadata) { + super(Orders.class, metadata); + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/product/entity/QProduct.java b/src/main/generated/project/trendpick_pro/domain/product/entity/QProduct.java new file mode 100644 index 00000000..db12180b --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/product/entity/QProduct.java @@ -0,0 +1,75 @@ +package project.trendpick_pro.domain.product.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; + + +/** + * QProduct is a Querydsl query type for Product + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QProduct extends EntityPathBase { + + private static final long serialVersionUID = -674347658L; + + private static final PathInits INITS = PathInits.DIRECT2; + + public static final QProduct product = new QProduct("product"); + + public final project.trendpick_pro.domain.common.base.QBaseTimeEntity _super = new project.trendpick_pro.domain.common.base.QBaseTimeEntity(this); + + public final StringPath brand = createString("brand"); + + public final project.trendpick_pro.domain.common.file.QCommonFile commonFile; + + //inherited + public final DateTimePath createdDate = _super.createdDate; + + public final StringPath description = createString("description"); + + public final NumberPath id = createNumber("id", Long.class); + + public final StringPath mainCategory = createString("mainCategory"); + + //inherited + public final DateTimePath modifiedDate = _super.modifiedDate; + + public final StringPath name = createString("name"); + + public final NumberPath price = createNumber("price", Integer.class); + + public final NumberPath stock = createNumber("stock", Integer.class); + + public final ListPath subCategory = this.createList("subCategory", String.class, StringPath.class, PathInits.DIRECT2); + + public final ListPath tags = this.createList("tags", project.trendpick_pro.domain.tag.entity.Tag.class, project.trendpick_pro.domain.tag.entity.QTag.class, PathInits.DIRECT2); + + public QProduct(String variable) { + this(Product.class, forVariable(variable), INITS); + } + + public QProduct(Path path) { + this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); + } + + public QProduct(PathMetadata metadata) { + this(metadata, PathInits.getFor(metadata, INITS)); + } + + public QProduct(PathMetadata metadata, PathInits inits) { + this(Product.class, metadata, inits); + } + + public QProduct(Class type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + this.commonFile = inits.isInitialized("commonFile") ? new project.trendpick_pro.domain.common.file.QCommonFile(forProperty("commonFile"), inits.get("commonFile")) : null; + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductResponse.java b/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductResponse.java new file mode 100644 index 00000000..7c562c87 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductResponse.java @@ -0,0 +1,21 @@ +package project.trendpick_pro.domain.product.entity.dto.response; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.ConstructorExpression; +import javax.annotation.processing.Generated; + +/** + * project.trendpick_pro.domain.product.entity.dto.response.QProductResponse is a Querydsl Projection type for ProductResponse + */ +@Generated("com.querydsl.codegen.DefaultProjectionSerializer") +public class QProductResponse extends ConstructorExpression { + + private static final long serialVersionUID = -274979477L; + + public QProductResponse(com.querydsl.core.types.Expression id, com.querydsl.core.types.Expression name, com.querydsl.core.types.Expression mainCategory, com.querydsl.core.types.Expression> subCategory, com.querydsl.core.types.Expression brand, com.querydsl.core.types.Expression description, com.querydsl.core.types.Expression mainFile, com.querydsl.core.types.Expression> subFiles, com.querydsl.core.types.Expression price, com.querydsl.core.types.Expression stock, com.querydsl.core.types.Expression> tags) { + super(ProductResponse.class, new Class[]{long.class, String.class, String.class, java.util.List.class, String.class, String.class, String.class, java.util.List.class, int.class, int.class, java.util.List.class}, id, name, mainCategory, subCategory, brand, description, mainFile, subFiles, price, stock, tags); + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductWithIdResponse.java b/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductWithIdResponse.java new file mode 100644 index 00000000..27a77434 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductWithIdResponse.java @@ -0,0 +1,21 @@ +package project.trendpick_pro.domain.product.entity.dto.response; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.ConstructorExpression; +import javax.annotation.processing.Generated; + +/** + * project.trendpick_pro.domain.product.entity.dto.response.QProductWithIdResponse is a Querydsl Projection type for ProductWithIdResponse + */ +@Generated("com.querydsl.codegen.DefaultProjectionSerializer") +public class QProductWithIdResponse extends ConstructorExpression { + + private static final long serialVersionUID = 173412748L; + + public QProductWithIdResponse(com.querydsl.core.types.Expression id, com.querydsl.core.types.Expression name, com.querydsl.core.types.Expression brand, com.querydsl.core.types.Expression mainFile, com.querydsl.core.types.Expression price) { + super(ProductWithIdResponse.class, new Class[]{long.class, String.class, String.class, project.trendpick_pro.domain.common.file.CommonFile.class, int.class}, id, name, brand, mainFile, price); + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/tag/entity/QTag.java b/src/main/generated/project/trendpick_pro/domain/tag/entity/QTag.java new file mode 100644 index 00000000..07cea08f --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/tag/entity/QTag.java @@ -0,0 +1,53 @@ +package project.trendpick_pro.domain.tag.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; + + +/** + * QTag is a Querydsl query type for Tag + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QTag extends EntityPathBase { + + private static final long serialVersionUID = -1204291178L; + + private static final PathInits INITS = PathInits.DIRECT2; + + public static final QTag tag = new QTag("tag"); + + public final NumberPath id = createNumber("id", Long.class); + + public final StringPath name = createString("name"); + + public final project.trendpick_pro.domain.product.entity.QProduct product; + + public QTag(String variable) { + this(Tag.class, forVariable(variable), INITS); + } + + public QTag(Path path) { + this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); + } + + public QTag(PathMetadata metadata) { + this(metadata, PathInits.getFor(metadata, INITS)); + } + + public QTag(PathMetadata metadata, PathInits inits) { + this(Tag.class, metadata, inits); + } + + public QTag(Class type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + this.product = inits.isInitialized("product") ? new project.trendpick_pro.domain.product.entity.QProduct(forProperty("product"), inits.get("product")) : null; + } + +} + diff --git a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java index f86eea54..ec2a25e5 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java +++ b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java @@ -4,10 +4,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; -import project.trendpick_pro.domain.answer.entity.dto.AnswerRequestDto; -import project.trendpick_pro.domain.ask.entity.Ask; - -import java.util.List; +import project.trendpick_pro.domain.answer.entity.dto.request.AnswerRequest; @Controller @RequiredArgsConstructor @@ -22,7 +19,7 @@ public String showAnswers(){ @PostMapping("/{id}") public String addAnswer(@PathVariable Long askId, - @Valid AnswerRequestDto answerRequestDto){ + @Valid AnswerRequest answerRequestDto){ return "redirect:/ask/list"; } diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/dto/AnswerRequestDto.java b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/AnswerRequestDto.java deleted file mode 100644 index a67dce34..00000000 --- a/src/main/java/project/trendpick_pro/domain/answer/entity/dto/AnswerRequestDto.java +++ /dev/null @@ -1,4 +0,0 @@ -package project.trendpick_pro.domain.answer.entity.dto; - -public class AnswerRequestDto { -} diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/dto/AnswerResponseDto.java b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/AnswerResponseDto.java deleted file mode 100644 index ad6d9e7d..00000000 --- a/src/main/java/project/trendpick_pro/domain/answer/entity/dto/AnswerResponseDto.java +++ /dev/null @@ -1,4 +0,0 @@ -package project.trendpick_pro.domain.answer.entity.dto; - -public class AnswerResponseDto { -} diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/dto/request/AnswerRequest.java b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/request/AnswerRequest.java new file mode 100644 index 00000000..1caf3d8c --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/request/AnswerRequest.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.answer.entity.dto.request; + +public class AnswerRequest { +} diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/dto/response/AnswerResponse.java b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/response/AnswerResponse.java new file mode 100644 index 00000000..a4286ffe --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/response/AnswerResponse.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.answer.entity.dto.response; + +public class AnswerResponse { +} diff --git a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java index a844e6cd..ad706199 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java +++ b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java @@ -4,8 +4,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; -import project.trendpick_pro.domain.answer.entity.dto.AnswerRequestDto; -import project.trendpick_pro.domain.ask.entity.dto.AskRequestDto; +import project.trendpick_pro.domain.ask.entity.dto.request.AskRequest; @Controller @RequiredArgsConstructor @@ -13,13 +12,13 @@ public class AskController { @GetMapping("/list") - public String showAsks(){ + public String showAllAsk(){ return "/ask/list"; } - @GetMapping("/detail/{id}") - public String showAsk(@PathVariable Long id){ + @GetMapping("/{askId}}") + public String showAsk(@PathVariable Long askId){ return "/ask/detail"; } @@ -37,7 +36,7 @@ public String modifyAsk(@PathVariable Long id){ } @PostMapping("/add/{brandId}") - public String addAsk(@Valid AskRequestDto askRequestDto, @PathVariable Long brandId){ + public String addAsk(@Valid AskRequest askRequestDto, @PathVariable Long brandId){ return "redirect:/ask/list"; } diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/AskRequestDto.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/AskRequestDto.java deleted file mode 100644 index 3ae37f1e..00000000 --- a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/AskRequestDto.java +++ /dev/null @@ -1,4 +0,0 @@ -package project.trendpick_pro.domain.ask.entity.dto; - -public class AskRequestDto { -} diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/AskResponseDto.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/AskResponseDto.java deleted file mode 100644 index 2aec82e4..00000000 --- a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/AskResponseDto.java +++ /dev/null @@ -1,4 +0,0 @@ -package project.trendpick_pro.domain.ask.entity.dto; - -public class AskResponseDto { -} diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/request/AskRequest.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/request/AskRequest.java new file mode 100644 index 00000000..acdc413f --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/request/AskRequest.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.ask.entity.dto.request; + +public class AskRequest { +} diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java new file mode 100644 index 00000000..9a6ecd9c --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.ask.entity.dto.response; + +public class AskResponse { +} From a5229b82e174fdaacf60a7f3b149dec6f3df1b52 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 28 May 2023 14:28:09 +0900 Subject: [PATCH 021/367] =?UTF-8?q?feat:=20ask=20crud=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/answer/entity/QAnswer.java | 8 ++- .../trendpick_pro/domain/ask/entity/QAsk.java | 8 ++- .../ask/entity/dto/response/QAskResponse.java | 21 +++++++ .../domain/answer/entity/Answer.java | 6 +- .../answer/repository/AnswerRepository.java | 5 +- .../domain/ask/controller/AskController.java | 41 +++++++------ .../trendpick_pro/domain/ask/entity/Ask.java | 32 +++++++++-- .../ask/entity/dto/request/AskRequest.java | 11 ++++ .../ask/entity/dto/response/AskResponse.java | 44 ++++++++++++++ .../domain/ask/repository/AskRepository.java | 6 +- .../domain/ask/service/AskService.java | 57 +++++++++++++++++++ src/main/resources/application.yml | 18 +++--- .../trendpick/customerservice/ask/detail.html | 10 ++++ .../trendpick/customerservice/ask/list.html | 10 ++++ 14 files changed, 238 insertions(+), 39 deletions(-) create mode 100644 src/main/generated/project/trendpick_pro/domain/ask/entity/dto/response/QAskResponse.java create mode 100644 src/main/resources/templates/trendpick/customerservice/ask/detail.html create mode 100644 src/main/resources/templates/trendpick/customerservice/ask/list.html diff --git a/src/main/generated/project/trendpick_pro/domain/answer/entity/QAnswer.java b/src/main/generated/project/trendpick_pro/domain/answer/entity/QAnswer.java index 1bcc8176..65dd2c5f 100644 --- a/src/main/generated/project/trendpick_pro/domain/answer/entity/QAnswer.java +++ b/src/main/generated/project/trendpick_pro/domain/answer/entity/QAnswer.java @@ -22,16 +22,22 @@ public class QAnswer extends EntityPathBase { public static final QAnswer answer = new QAnswer("answer"); + public final project.trendpick_pro.domain.common.base.QBaseTimeEntity _super = new project.trendpick_pro.domain.common.base.QBaseTimeEntity(this); + public final project.trendpick_pro.domain.ask.entity.QAsk ask; public final StringPath author = createString("author"); public final StringPath content = createString("content"); - public final DateTimePath createDate = createDateTime("createDate", java.time.LocalDateTime.class); + //inherited + public final DateTimePath createdDate = _super.createdDate; public final NumberPath id = createNumber("id", Long.class); + //inherited + public final DateTimePath modifiedDate = _super.modifiedDate; + public QAnswer(String variable) { this(Answer.class, forVariable(variable), INITS); } diff --git a/src/main/generated/project/trendpick_pro/domain/ask/entity/QAsk.java b/src/main/generated/project/trendpick_pro/domain/ask/entity/QAsk.java index 4fc937b0..f96f456b 100644 --- a/src/main/generated/project/trendpick_pro/domain/ask/entity/QAsk.java +++ b/src/main/generated/project/trendpick_pro/domain/ask/entity/QAsk.java @@ -20,6 +20,8 @@ public class QAsk extends EntityPathBase { public static final QAsk ask = new QAsk("ask"); + public final project.trendpick_pro.domain.common.base.QBaseTimeEntity _super = new project.trendpick_pro.domain.common.base.QBaseTimeEntity(this); + public final ListPath answerList = this.createList("answerList", project.trendpick_pro.domain.answer.entity.Answer.class, project.trendpick_pro.domain.answer.entity.QAnswer.class, PathInits.DIRECT2); public final StringPath author = createString("author"); @@ -28,10 +30,14 @@ public class QAsk extends EntityPathBase { public final StringPath content = createString("content"); - public final DateTimePath createDate = createDateTime("createDate", java.time.LocalDateTime.class); + //inherited + public final DateTimePath createdDate = _super.createdDate; public final NumberPath id = createNumber("id", Long.class); + //inherited + public final DateTimePath modifiedDate = _super.modifiedDate; + public final StringPath title = createString("title"); public QAsk(String variable) { diff --git a/src/main/generated/project/trendpick_pro/domain/ask/entity/dto/response/QAskResponse.java b/src/main/generated/project/trendpick_pro/domain/ask/entity/dto/response/QAskResponse.java new file mode 100644 index 00000000..2ad79bb5 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/ask/entity/dto/response/QAskResponse.java @@ -0,0 +1,21 @@ +package project.trendpick_pro.domain.ask.entity.dto.response; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.ConstructorExpression; +import javax.annotation.processing.Generated; + +/** + * project.trendpick_pro.domain.ask.entity.dto.response.QAskResponse is a Querydsl Projection type for AskResponse + */ +@Generated("com.querydsl.codegen.DefaultProjectionSerializer") +public class QAskResponse extends ConstructorExpression { + + private static final long serialVersionUID = 1378042495L; + + public QAskResponse(com.querydsl.core.types.Expression id, com.querydsl.core.types.Expression author, com.querydsl.core.types.Expression brand, com.querydsl.core.types.Expression title, com.querydsl.core.types.Expression content, com.querydsl.core.types.Expression> answerList) { + super(AskResponse.class, new Class[]{long.class, String.class, String.class, String.class, String.class, java.util.List.class}, id, author, brand, title, content, answerList); + } + +} + diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java b/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java index c58dfe1a..8a58e85e 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java +++ b/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java @@ -9,6 +9,7 @@ import org.springframework.data.annotation.CreatedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import project.trendpick_pro.domain.ask.entity.Ask; +import project.trendpick_pro.domain.common.base.BaseTimeEntity; import java.time.LocalDateTime; @@ -17,15 +18,12 @@ @AllArgsConstructor @Builder @Getter -@EntityListeners(AuditingEntityListener.class) -public class Answer { +public class Answer extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "answer_id") private Long id; private String author; //멤버 엔티티와 맵핑 해줘야 한다. (임시 String) - @CreatedDate - private LocalDateTime createDate; @ManyToOne @JoinColumn(name = "ask_id") diff --git a/src/main/java/project/trendpick_pro/domain/answer/repository/AnswerRepository.java b/src/main/java/project/trendpick_pro/domain/answer/repository/AnswerRepository.java index 1ec55cfc..6192565e 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/repository/AnswerRepository.java +++ b/src/main/java/project/trendpick_pro/domain/answer/repository/AnswerRepository.java @@ -1,4 +1,7 @@ package project.trendpick_pro.domain.answer.repository; -public class AnswerRepository { +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.answer.entity.Answer; + +public interface AnswerRepository extends JpaRepository { } diff --git a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java index ad706199..09229997 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java +++ b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java @@ -3,41 +3,50 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import project.trendpick_pro.domain.ask.entity.dto.request.AskRequest; +import project.trendpick_pro.domain.ask.entity.dto.response.AskResponse; +import project.trendpick_pro.domain.ask.service.AskService; @Controller @RequiredArgsConstructor -@RequestMapping("/ask") +@RequestMapping("trendpick/asks") public class AskController { + private final AskService askService; @GetMapping("/list") - public String showAllAsk(){ - - return "/ask/list"; + public String showAllAsk(Model model) { + model.addAttribute("askResponse", askService.showAll()); + return "trendpick/customerservice/ask/list"; } @GetMapping("/{askId}}") - public String showAsk(@PathVariable Long askId){ - - return "/ask/detail"; + public String showAsk(@PathVariable Long askId, Model model) { + model.addAttribute("askResponse", askService.show(askId)); + return "trendpick/customerservice/ask/detail"; } - @PostMapping("/delete/{id}") - public String deleteAsk(@PathVariable Long id){ + @PostMapping("/delete/{askId}") + public String deleteAsk(@PathVariable Long askId) { + askService.delete(askId); - return "redirect:/ask/get/%s".formatted(id); + return "redirect:/trendpick/asks/list"; } - @PostMapping("/modify/{id}") - public String modifyAsk(@PathVariable Long id){ + @PostMapping("/edit/{askId}") + public String modifyAsk(@PathVariable Long askId, @Valid AskRequest askRequest, Model model) { + AskResponse askResponse = askService.modify(askId, askRequest); - return "redirect:/ask/get/%s".formatted(id); + model.addAttribute("askResponse", askResponse); + return "redirect:/trendpick/asks/%s".formatted(askId); } - @PostMapping("/add/{brandId}") - public String addAsk(@Valid AskRequest askRequestDto, @PathVariable Long brandId){ + @PostMapping("/register") + public String registerAsk(@Valid AskRequest askRequest, @RequestParam(value = "brand") Long brandId, Model model) { + AskResponse askResponse = askService.register(askRequest); - return "redirect:/ask/list"; + model.addAttribute("askResponse", askResponse); + return "redirect:/trendpick/asks/%s".formatted(askResponse.getId()); } } diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java b/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java index cf4dc00b..88dc18bf 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java @@ -8,6 +8,8 @@ import org.springframework.data.annotation.CreatedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import project.trendpick_pro.domain.answer.entity.Answer; +import project.trendpick_pro.domain.ask.entity.dto.request.AskRequest; +import project.trendpick_pro.domain.common.base.BaseTimeEntity; import java.time.LocalDateTime; import java.util.ArrayList; @@ -18,17 +20,20 @@ @AllArgsConstructor @Builder @Getter -@EntityListeners(AuditingEntityListener.class) -public class Ask { +public class Ask extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "ask_id") private Long id; - private String author; //멤버 엔티티로 수정 필요 - private String brand; //브랜드 엔티티로 수정 필요 - @CreatedDate - private LocalDateTime createDate; + + // @ManyToOne(fetch = FetchType.LAZY) + // @JoinColumn(name = "member_id") + private String author; //Member + + // @ManyToOne(fetch = FetchType.LAZY) + // @JoinColumn(name = "brand_id") + private String brand; //Brand private String title; private String content; @@ -36,4 +41,19 @@ public class Ask { @OneToMany(mappedBy = "ask", cascade = CascadeType.ALL) @Builder.Default private List answerList = new ArrayList<>(); + + public static Ask of(String member, String brand, AskRequest askRequest) { + return Ask.builder() + .author(member) + .brand(brand) + .title(askRequest.getTitle()) + .content(askRequest.getTitle()) + .build() + ; + } + + public void update(AskRequest askRequest) { + this.title = askRequest.getTitle(); + this.content = askRequest.getContent(); + } } diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/request/AskRequest.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/request/AskRequest.java index acdc413f..56661e88 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/request/AskRequest.java +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/request/AskRequest.java @@ -1,4 +1,15 @@ package project.trendpick_pro.domain.ask.entity.dto.request; + +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; + +@Getter public class AskRequest { + + @NotBlank + private String title; + + @NotBlank + private String content; } diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java index 9a6ecd9c..906d2b54 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java @@ -1,4 +1,48 @@ package project.trendpick_pro.domain.ask.entity.dto.response; +import com.querydsl.core.annotations.QueryProjection; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.answer.entity.Answer; +import project.trendpick_pro.domain.ask.entity.Ask; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class AskResponse { + + private Long id; + private String author; //Member + private String brand; //Brand + + private String title; + private String content; + private List answerList = new ArrayList<>(); + + + @Builder + @QueryProjection + public AskResponse(Long id, String author, String brand, String title, String content, List answerList) { + this.id = id; + this.author = author; + this.brand = brand; + this.title = title; + this.content = content; + this.answerList = answerList; + } + + public static AskResponse of (Ask ask) { + return AskResponse.builder() + .id(ask.getId()) + .author(ask.getAuthor()) + .brand(ask.getBrand()) + .title(ask.getTitle()) + .content(ask.getContent()) + .answerList(ask.getAnswerList()) + .build(); + } } diff --git a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java index dfba8912..faab5f2a 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java +++ b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java @@ -1,4 +1,8 @@ package project.trendpick_pro.domain.ask.repository; -public class AskRepository { + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.ask.entity.Ask; + +public interface AskRepository extends JpaRepository { } diff --git a/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java b/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java index f19aff9b..01cd3411 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java +++ b/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java @@ -1,4 +1,61 @@ package project.trendpick_pro.domain.ask.service; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.ask.entity.Ask; +import project.trendpick_pro.domain.ask.entity.dto.request.AskRequest; +import project.trendpick_pro.domain.ask.entity.dto.response.AskResponse; +import project.trendpick_pro.domain.ask.repository.AskRepository; + +import java.util.ArrayList; +import java.util.List; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor public class AskService { + + private final AskRepository askRepository; + + public List showAll() { + List askList = askRepository.findAll(); + List responses = new ArrayList<>(); + + for(Ask ask : askList){ + responses.add(AskResponse.of(ask)); + } + + return responses; + } + + public AskResponse show(Long askId) { + Ask ask = askRepository.findById(askId).orElseThrow(); + + return AskResponse.of(ask); + } + + @Transactional + public void delete(Long askId) { + askRepository.deleteById(askId); + } + + @Transactional + public AskResponse modify(Long askId, AskRequest askRequest) { + Ask ask = askRepository.findById(askId).orElseThrow(); + + ask.update(askRequest); + return AskResponse.of(ask); + } + + @Transactional + public AskResponse register(AskRequest askRequest) { + String member = "member"; //Member + String brand = "brand"; //Brand + + Ask ask = Ask.of(member, brand, askRequest); + + askRepository.save(ask); + return AskResponse.of(ask); + } } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 1590754a..e97315d9 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -6,15 +6,15 @@ spring: matching-strategy: ant_path_matcher datasource: # H2 -# driver-class-name: org.h2.Driver -# url: jdbc:h2:tcp://localhost/~/db/TrendPick -# username: sa -# password: - # mariaDB - driver-class-name: org.mariadb.jdbc.Driver - url: jdbc:mariadb://127.0.0.1:${maria.port}/TrendPick__dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul - username: ${maria.username} - password: ${maria.password} + driver-class-name: org.h2.Driver + url: jdbc:h2:tcp://localhost/~/db/TrendPick + username: sa + password: +# mariaDB +# driver-class-name: org.mariadb.jdbc.Driver +# url: jdbc:mariadb://127.0.0.1:${maria.port}/TrendPick__dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul +# username: ${maria.username} +# password: ${maria.password} jpa: hibernate: ddl-auto: create diff --git a/src/main/resources/templates/trendpick/customerservice/ask/detail.html b/src/main/resources/templates/trendpick/customerservice/ask/detail.html new file mode 100644 index 00000000..566549bd --- /dev/null +++ b/src/main/resources/templates/trendpick/customerservice/ask/detail.html @@ -0,0 +1,10 @@ + + + + + Title + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/customerservice/ask/list.html b/src/main/resources/templates/trendpick/customerservice/ask/list.html new file mode 100644 index 00000000..566549bd --- /dev/null +++ b/src/main/resources/templates/trendpick/customerservice/ask/list.html @@ -0,0 +1,10 @@ + + + + + Title + + + + + \ No newline at end of file From a3fd1e33309f8b15529bd620d9a014a80a0b3396 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 28 May 2023 16:24:55 +0900 Subject: [PATCH 022/367] =?UTF-8?q?feat:=20answer=20crud=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 --- .../entity/dto/response/QAnswerResponse.java | 21 ++++++++ .../ask/entity/dto/response/QAskResponse.java | 4 +- .../answer/controller/AnswerController.java | 36 +++++++------- .../domain/answer/entity/Answer.java | 19 +++++++ .../entity/dto/request/AnswerRequest.java | 8 +++ .../entity/dto/response/AnswerResponse.java | 49 +++++++++++++++++++ .../domain/answer/service/AnswerService.java | 39 +++++++++++++++ .../domain/ask/controller/AskController.java | 2 +- .../ask/entity/dto/response/AskResponse.java | 11 ++++- .../customerservice/{ask => asks}/detail.html | 0 .../customerservice/{ask => asks}/list.html | 0 11 files changed, 166 insertions(+), 23 deletions(-) create mode 100644 src/main/generated/project/trendpick_pro/domain/answer/entity/dto/response/QAnswerResponse.java rename src/main/resources/templates/trendpick/customerservice/{ask => asks}/detail.html (100%) rename src/main/resources/templates/trendpick/customerservice/{ask => asks}/list.html (100%) diff --git a/src/main/generated/project/trendpick_pro/domain/answer/entity/dto/response/QAnswerResponse.java b/src/main/generated/project/trendpick_pro/domain/answer/entity/dto/response/QAnswerResponse.java new file mode 100644 index 00000000..57ddb215 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/answer/entity/dto/response/QAnswerResponse.java @@ -0,0 +1,21 @@ +package project.trendpick_pro.domain.answer.entity.dto.response; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.ConstructorExpression; +import javax.annotation.processing.Generated; + +/** + * project.trendpick_pro.domain.answer.entity.dto.response.QAnswerResponse is a Querydsl Projection type for AnswerResponse + */ +@Generated("com.querydsl.codegen.DefaultProjectionSerializer") +public class QAnswerResponse extends ConstructorExpression { + + private static final long serialVersionUID = -2046614161L; + + public QAnswerResponse(com.querydsl.core.types.Expression id, com.querydsl.core.types.Expression author, com.querydsl.core.types.Expression ask, com.querydsl.core.types.Expression content, com.querydsl.core.types.Expression createdDate, com.querydsl.core.types.Expression modifiedDate) { + super(AnswerResponse.class, new Class[]{long.class, String.class, project.trendpick_pro.domain.ask.entity.Ask.class, String.class, java.time.LocalDateTime.class, java.time.LocalDateTime.class}, id, author, ask, content, createdDate, modifiedDate); + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/ask/entity/dto/response/QAskResponse.java b/src/main/generated/project/trendpick_pro/domain/ask/entity/dto/response/QAskResponse.java index 2ad79bb5..66b799b8 100644 --- a/src/main/generated/project/trendpick_pro/domain/ask/entity/dto/response/QAskResponse.java +++ b/src/main/generated/project/trendpick_pro/domain/ask/entity/dto/response/QAskResponse.java @@ -13,8 +13,8 @@ public class QAskResponse extends ConstructorExpression { private static final long serialVersionUID = 1378042495L; - public QAskResponse(com.querydsl.core.types.Expression id, com.querydsl.core.types.Expression author, com.querydsl.core.types.Expression brand, com.querydsl.core.types.Expression title, com.querydsl.core.types.Expression content, com.querydsl.core.types.Expression> answerList) { - super(AskResponse.class, new Class[]{long.class, String.class, String.class, String.class, String.class, java.util.List.class}, id, author, brand, title, content, answerList); + public QAskResponse(com.querydsl.core.types.Expression id, com.querydsl.core.types.Expression author, com.querydsl.core.types.Expression brand, com.querydsl.core.types.Expression title, com.querydsl.core.types.Expression content, com.querydsl.core.types.Expression> answerList, com.querydsl.core.types.Expression createdDate, com.querydsl.core.types.Expression modifiedDate) { + super(AskResponse.class, new Class[]{long.class, String.class, String.class, String.class, String.class, java.util.List.class, java.time.LocalDateTime.class, java.time.LocalDateTime.class}, id, author, brand, title, content, answerList, createdDate, modifiedDate); } } diff --git a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java index ec2a25e5..b30e9627 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java +++ b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java @@ -5,36 +5,34 @@ import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import project.trendpick_pro.domain.answer.entity.dto.request.AnswerRequest; +import project.trendpick_pro.domain.answer.service.AnswerService; @Controller @RequiredArgsConstructor -@RequestMapping("/answer") +@RequestMapping("/trendpick/customerservice/asks/{askId}/answers") public class AnswerController { + private final AnswerService answerService; - @GetMapping("/list") - public String showAnswers(){ + @PostMapping("/register") + public String registerAnswer(@PathVariable Long askId, + @Valid AnswerRequest answerRequest){ + String member = "member"; //Member + answerService.register(askId, member, answerRequest); - return "redirect:/ask/list"; + return "redirect:trendpick/customerservice/asks/{askId}".formatted(askId); } - @PostMapping("/{id}") - public String addAnswer(@PathVariable Long askId, - @Valid AnswerRequest answerRequestDto){ + @PostMapping("/delete/{answerId}") + public String deleteAnswer(@PathVariable Long askId, @PathVariable Long answerId){ + answerService.delete(answerId); - return "redirect:/ask/list"; + return "redirect:trendpick/asks/detail".formatted(askId); } - @DeleteMapping("/{id}") - public String deleteAnswer(@PathVariable Long id){ + @PostMapping("/moidfy/{answerId}") + public String modifyAnswer(@PathVariable Long askId, @PathVariable Long answerId, @Valid AnswerRequest answerRequest){ + answerService.modify(answerId, answerRequest); - return "redirect:/ask/list"; + return "redirect:trendpick/asks/detail".formatted(askId); } - - @PatchMapping("/{id}") - public String modifyAnswer(@PathVariable Long id){ - - return "redirect:/ask/list"; - } - - } diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java b/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java index 8a58e85e..b4d03c00 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java +++ b/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java @@ -8,7 +8,9 @@ import org.hibernate.annotations.Fetch; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; +import project.trendpick_pro.domain.answer.entity.dto.request.AnswerRequest; import project.trendpick_pro.domain.ask.entity.Ask; +import project.trendpick_pro.domain.ask.entity.dto.request.AskRequest; import project.trendpick_pro.domain.common.base.BaseTimeEntity; import java.time.LocalDateTime; @@ -30,4 +32,21 @@ public class Answer extends BaseTimeEntity { private Ask ask; private String content; + + public static Answer write(Ask ask, String member, AnswerRequest answerRequest) { + Answer answer = Answer + .builder() + .author(member) //Member + .ask(ask) + .content(answerRequest.getContent()) + .build() + ; + + ask.getAnswerList().add(answer); //양방향 + return answer; + } + + public void update(AnswerRequest answerRequest) { + this.content = content; + } } diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/dto/request/AnswerRequest.java b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/request/AnswerRequest.java index 1caf3d8c..353e99fd 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/entity/dto/request/AnswerRequest.java +++ b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/request/AnswerRequest.java @@ -1,4 +1,12 @@ package project.trendpick_pro.domain.answer.entity.dto.request; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; + +@Getter public class AnswerRequest { + + @NotBlank + private String content; + } diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/dto/response/AnswerResponse.java b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/response/AnswerResponse.java index a4286ffe..d3d139a6 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/entity/dto/response/AnswerResponse.java +++ b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/response/AnswerResponse.java @@ -1,4 +1,53 @@ package project.trendpick_pro.domain.answer.entity.dto.response; +import jakarta.persistence.*; +import lombok.Getter; + + +import com.querydsl.core.annotations.QueryProjection; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.answer.entity.Answer; +import project.trendpick_pro.domain.ask.entity.Ask; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class AnswerResponse { + + private Long id; + private String author; //Member //브렌드 매니저 권한을 가지고 있어야함. + private Ask ask; + private String content; + private LocalDateTime createdDate; + private LocalDateTime modifiedDate; + + @Builder + @QueryProjection + public AnswerResponse(Long id, String author, Ask ask, String content, LocalDateTime createdDate, LocalDateTime modifiedDate) { + this.id = id; + this.author = author; + this.ask = ask; + this.content = content; + this.createdDate = createdDate; + this.modifiedDate = modifiedDate; + } + + public static AnswerResponse of (Answer answer) { + return AnswerResponse.builder() + .id(answer.getId()) + .author(answer.getAuthor()) + .ask(answer.getAsk()) + .content(answer.getContent()) + .createdDate(answer.getCreatedDate()) + .modifiedDate(answer.getModifiedDate()) + .build(); + } + } + diff --git a/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java b/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java index c606867b..e48252b1 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java +++ b/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java @@ -1,4 +1,43 @@ package project.trendpick_pro.domain.answer.service; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.answer.entity.Answer; +import project.trendpick_pro.domain.answer.entity.dto.request.AnswerRequest; +import project.trendpick_pro.domain.answer.repository.AnswerRepository; +import project.trendpick_pro.domain.ask.entity.Ask; +import project.trendpick_pro.domain.ask.entity.dto.response.AskResponse; +import project.trendpick_pro.domain.ask.repository.AskRepository; +import project.trendpick_pro.domain.ask.service.AskService; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor public class AnswerService { + private final AnswerRepository answerRepository; + private final AskRepository askRepository; + + @Transactional + public void register(Long askId, String member, AnswerRequest answerRequest) { + Ask ask = askRepository.findById(askId).orElseThrow(); + + Answer answer = Answer.write(ask, member, answerRequest); + + answerRepository.save(answer); + } + + @Transactional + public void delete(Long answerId) { + Answer answer = answerRepository.findById(answerId).orElseThrow(); + + answerRepository.delete(answer); + answer.getAsk().getAnswerList().remove(answer); + } + + public void modify(Long answerId, AnswerRequest answerRequest) { + Answer answer = answerRepository.findById(answerId).orElseThrow(); + + answer.update(answerRequest); + } } diff --git a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java index 09229997..72c5e418 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java +++ b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java @@ -11,7 +11,7 @@ @Controller @RequiredArgsConstructor -@RequestMapping("trendpick/asks") +@RequestMapping("trendpick/customerservice/asks") public class AskController { private final AskService askService; diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java index 906d2b54..a4086b61 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java @@ -8,6 +8,8 @@ import project.trendpick_pro.domain.answer.entity.Answer; import project.trendpick_pro.domain.ask.entity.Ask; +import java.time.LocalDate; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -22,17 +24,21 @@ public class AskResponse { private String title; private String content; private List answerList = new ArrayList<>(); + private LocalDateTime createdDate; + private LocalDateTime modifiedDate; @Builder @QueryProjection - public AskResponse(Long id, String author, String brand, String title, String content, List answerList) { + public AskResponse(Long id, String author, String brand, String title, String content, List answerList, LocalDateTime createdDate, LocalDateTime modifiedDate) { this.id = id; this.author = author; this.brand = brand; this.title = title; this.content = content; this.answerList = answerList; + this.createdDate = createdDate; + this.modifiedDate = modifiedDate; } public static AskResponse of (Ask ask) { @@ -43,6 +49,9 @@ public static AskResponse of (Ask ask) { .title(ask.getTitle()) .content(ask.getContent()) .answerList(ask.getAnswerList()) + .createdDate(ask.getCreatedDate()) + .modifiedDate(ask.getModifiedDate()) .build(); } + } diff --git a/src/main/resources/templates/trendpick/customerservice/ask/detail.html b/src/main/resources/templates/trendpick/customerservice/asks/detail.html similarity index 100% rename from src/main/resources/templates/trendpick/customerservice/ask/detail.html rename to src/main/resources/templates/trendpick/customerservice/asks/detail.html diff --git a/src/main/resources/templates/trendpick/customerservice/ask/list.html b/src/main/resources/templates/trendpick/customerservice/asks/list.html similarity index 100% rename from src/main/resources/templates/trendpick/customerservice/ask/list.html rename to src/main/resources/templates/trendpick/customerservice/asks/list.html From afa0a3f59c3258e03cbc49f11c25d5687111f77a Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Sun, 28 May 2023 16:55:07 +0900 Subject: [PATCH 023/367] =?UTF-8?q?fix:=20ManyToOne=EC=97=90=20=EC=98=B5?= =?UTF-8?q?=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/project/trendpick_pro/domain/review/entity/Review.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java index 98e1be6f..2ad0855b 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -23,7 +23,7 @@ public class Review extends BaseTimeEntity { //@JoinColumn(name = "user_id") private Long user_id; //User - //@ManyToOne +// @ManyToOne(fetch = FetchType.LAZY) //@JoinColumn(name = "product_id") private Long product_id; //Product From 2954adc648f49eec96b3c0e08b27d7c4e3ff28cd Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 28 May 2023 17:16:22 +0900 Subject: [PATCH 024/367] =?UTF-8?q?feat:=20Delivery=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/delivery/entity/QDelivery.java | 63 +++++++++++++++++++ .../domain/orders/entity/QOrders.java | 20 +++++- .../domain/review/entity/QReview.java | 53 ++++++++++++++++ .../domain/user/entity/QUser.java | 55 ++++++++++++++++ .../domain/delivery/entity/Delivery.java | 24 +++++++ .../domain/delivery/entity/DeliveryState.java | 6 ++ .../repository/DeliveryRepository.java | 7 +++ .../domain/orders/entity/Orders.java | 5 +- 8 files changed, 229 insertions(+), 4 deletions(-) create mode 100644 src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java create mode 100644 src/main/generated/project/trendpick_pro/domain/review/entity/QReview.java create mode 100644 src/main/generated/project/trendpick_pro/domain/user/entity/QUser.java create mode 100644 src/main/java/project/trendpick_pro/domain/delivery/entity/Delivery.java create mode 100644 src/main/java/project/trendpick_pro/domain/delivery/entity/DeliveryState.java create mode 100644 src/main/java/project/trendpick_pro/domain/delivery/repository/DeliveryRepository.java diff --git a/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java b/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java new file mode 100644 index 00000000..c89841ed --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java @@ -0,0 +1,63 @@ +package project.trendpick_pro.domain.delivery.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; + + +/** + * QDelivery is a Querydsl query type for Delivery + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QDelivery extends EntityPathBase { + + private static final long serialVersionUID = 436500440L; + + private static final PathInits INITS = PathInits.DIRECT2; + + public static final QDelivery delivery = new QDelivery("delivery"); + + public final project.trendpick_pro.domain.common.base.QBaseTimeEntity _super = new project.trendpick_pro.domain.common.base.QBaseTimeEntity(this); + + public final StringPath address = createString("address"); + + //inherited + public final DateTimePath createdDate = _super.createdDate; + + public final NumberPath id = createNumber("id", Long.class); + + //inherited + public final DateTimePath modifiedDate = _super.modifiedDate; + + public final project.trendpick_pro.domain.orders.entity.QOrders order; + + public final EnumPath state = createEnum("state", DeliveryState.class); + + public QDelivery(String variable) { + this(Delivery.class, forVariable(variable), INITS); + } + + public QDelivery(Path path) { + this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); + } + + public QDelivery(PathMetadata metadata) { + this(metadata, PathInits.getFor(metadata, INITS)); + } + + public QDelivery(PathMetadata metadata, PathInits inits) { + this(Delivery.class, metadata, inits); + } + + public QDelivery(Class type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + this.order = inits.isInitialized("order") ? new project.trendpick_pro.domain.orders.entity.QOrders(forProperty("order")) : null; + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrders.java b/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrders.java index cdfd6ac1..f0f579e1 100644 --- a/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrders.java +++ b/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrders.java @@ -7,6 +7,7 @@ import com.querydsl.core.types.PathMetadata; import javax.annotation.processing.Generated; import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; /** @@ -17,6 +18,8 @@ public class QOrders extends EntityPathBase { private static final long serialVersionUID = -2056827462L; + private static final PathInits INITS = PathInits.DIRECT2; + public static final QOrders orders = new QOrders("orders"); public final project.trendpick_pro.domain.common.base.QBaseTimeEntity _super = new project.trendpick_pro.domain.common.base.QBaseTimeEntity(this); @@ -24,6 +27,8 @@ public class QOrders extends EntityPathBase { //inherited public final DateTimePath createdDate = _super.createdDate; + public final project.trendpick_pro.domain.delivery.entity.QDelivery delivery; + public final NumberPath id = createNumber("id", Long.class); //inherited @@ -36,15 +41,24 @@ public class QOrders extends EntityPathBase { public final StringPath user = createString("user"); public QOrders(String variable) { - super(Orders.class, forVariable(variable)); + this(Orders.class, forVariable(variable), INITS); } public QOrders(Path path) { - super(path.getType(), path.getMetadata()); + this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); } public QOrders(PathMetadata metadata) { - super(Orders.class, metadata); + this(metadata, PathInits.getFor(metadata, INITS)); + } + + public QOrders(PathMetadata metadata, PathInits inits) { + this(Orders.class, metadata, inits); + } + + public QOrders(Class type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + this.delivery = inits.isInitialized("delivery") ? new project.trendpick_pro.domain.delivery.entity.QDelivery(forProperty("delivery"), inits.get("delivery")) : null; } } diff --git a/src/main/generated/project/trendpick_pro/domain/review/entity/QReview.java b/src/main/generated/project/trendpick_pro/domain/review/entity/QReview.java new file mode 100644 index 00000000..9f071b6e --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/review/entity/QReview.java @@ -0,0 +1,53 @@ +package project.trendpick_pro.domain.review.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; + + +/** + * QReview is a Querydsl query type for Review + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QReview extends EntityPathBase { + + private static final long serialVersionUID = -687591072L; + + public static final QReview review = new QReview("review"); + + public final project.trendpick_pro.domain.common.base.QBaseTimeEntity _super = new project.trendpick_pro.domain.common.base.QBaseTimeEntity(this); + + public final StringPath content = createString("content"); + + //inherited + public final DateTimePath createdDate = _super.createdDate; + + public final NumberPath id = createNumber("id", Long.class); + + //inherited + public final DateTimePath modifiedDate = _super.modifiedDate; + + public final NumberPath product_id = createNumber("product_id", Long.class); + + public final NumberPath rating = createNumber("rating", Integer.class); + + public final NumberPath user_id = createNumber("user_id", Long.class); + + public QReview(String variable) { + super(Review.class, forVariable(variable)); + } + + public QReview(Path path) { + super(path.getType(), path.getMetadata()); + } + + public QReview(PathMetadata metadata) { + super(Review.class, metadata); + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/user/entity/QUser.java b/src/main/generated/project/trendpick_pro/domain/user/entity/QUser.java new file mode 100644 index 00000000..c3a4572b --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/user/entity/QUser.java @@ -0,0 +1,55 @@ +package project.trendpick_pro.domain.user.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; + + +/** + * QUser is a Querydsl query type for User + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QUser extends EntityPathBase { + + private static final long serialVersionUID = 350707846L; + + public static final QUser user = new QUser("user"); + + public final NumberPath account = createNumber("account", Long.class); + + public final StringPath bank_name = createString("bank_name"); + + public final DateTimePath birth = createDateTime("birth", java.util.Date.class); + + public final StringPath email = createString("email"); + + public final NumberPath id = createNumber("id", Long.class); + + public final StringPath name = createString("name"); + + public final StringPath password = createString("password"); + + public final StringPath phone_num = createString("phone_num"); + + public final EnumPath role = createEnum("role", RoleType.class); + + public final NumberPath tag_id = createNumber("tag_id", Long.class); + + public QUser(String variable) { + super(User.class, forVariable(variable)); + } + + public QUser(Path path) { + super(path.getType(), path.getMetadata()); + } + + public QUser(PathMetadata metadata) { + super(User.class, metadata); + } + +} + diff --git a/src/main/java/project/trendpick_pro/domain/delivery/entity/Delivery.java b/src/main/java/project/trendpick_pro/domain/delivery/entity/Delivery.java new file mode 100644 index 00000000..3df75728 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/delivery/entity/Delivery.java @@ -0,0 +1,24 @@ +package project.trendpick_pro.domain.delivery.entity; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.common.base.BaseTimeEntity; +import project.trendpick_pro.domain.orders.entity.Orders; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Delivery extends BaseTimeEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @OneToOne(mappedBy = "delivery", fetch = FetchType.LAZY) + private Orders order; + private String address; + @Enumerated(EnumType.STRING) + private DeliveryState state; +} diff --git a/src/main/java/project/trendpick_pro/domain/delivery/entity/DeliveryState.java b/src/main/java/project/trendpick_pro/domain/delivery/entity/DeliveryState.java new file mode 100644 index 00000000..d58f386f --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/delivery/entity/DeliveryState.java @@ -0,0 +1,6 @@ +package project.trendpick_pro.domain.delivery.entity; + +public enum DeliveryState { + READY, DELIVERY_ING, COMPLETED + //준비,배송중,배송완료 +} diff --git a/src/main/java/project/trendpick_pro/domain/delivery/repository/DeliveryRepository.java b/src/main/java/project/trendpick_pro/domain/delivery/repository/DeliveryRepository.java new file mode 100644 index 00000000..2dfb9b62 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/delivery/repository/DeliveryRepository.java @@ -0,0 +1,7 @@ +package project.trendpick_pro.domain.delivery.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.delivery.entity.Delivery; + +public interface DeliveryRepository extends JpaRepository { +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/Orders.java b/src/main/java/project/trendpick_pro/domain/orders/entity/Orders.java index e3e84a12..db718ee6 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/Orders.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/Orders.java @@ -5,6 +5,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import project.trendpick_pro.domain.common.base.BaseTimeEntity; +import project.trendpick_pro.domain.delivery.entity.Delivery; @Entity @Getter @@ -21,5 +22,7 @@ public class Orders extends BaseTimeEntity { // @JoinColumn(name = "member_id") private String user; // User - + @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) + @JoinColumn(name = "delivery_id") + private Delivery delivery; } From 2e25cdc4e438abce342c499469d81d7c0a590f23 Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Sun, 28 May 2023 17:33:48 +0900 Subject: [PATCH 025/367] =?UTF-8?q?feat:=20brand=20=EA=B8=B0=EB=B3=B8?= =?UTF-8?q?=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/brand/entity/Brand.java | 21 +++++++++++++++++++ .../brand/repository/BrandRepository.java | 7 +++++++ 2 files changed, 28 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/brand/entity/Brand.java create mode 100644 src/main/java/project/trendpick_pro/domain/brand/repository/BrandRepository.java diff --git a/src/main/java/project/trendpick_pro/domain/brand/entity/Brand.java b/src/main/java/project/trendpick_pro/domain/brand/entity/Brand.java new file mode 100644 index 00000000..3a0c6e8a --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/brand/entity/Brand.java @@ -0,0 +1,21 @@ +package project.trendpick_pro.domain.brand.entity; + +import jakarta.persistence.Column; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@jakarta.persistence.Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Brand { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "brand_id") + private Long id; + + private String name; +} diff --git a/src/main/java/project/trendpick_pro/domain/brand/repository/BrandRepository.java b/src/main/java/project/trendpick_pro/domain/brand/repository/BrandRepository.java new file mode 100644 index 00000000..6f9b02e9 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/brand/repository/BrandRepository.java @@ -0,0 +1,7 @@ +package project.trendpick_pro.domain.brand.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.brand.entity.Brand; + +public interface BrandRepository extends JpaRepository { +} From 68716a33849e21a5003dc9f5d1cf759dd3b21abc Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 28 May 2023 17:49:02 +0900 Subject: [PATCH 026/367] =?UTF-8?q?fix:=20url=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/delivery/entity/QDelivery.java | 2 +- .../domain/answer/controller/AnswerController.java | 6 +++--- .../domain/ask/controller/AskController.java | 10 +++++----- .../trendpick/customerservice/asks/detail.html | 2 +- .../templates/trendpick/customerservice/asks/list.html | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java b/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java index c89841ed..70e24c79 100644 --- a/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java +++ b/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java @@ -56,7 +56,7 @@ public QDelivery(PathMetadata metadata, PathInits inits) { public QDelivery(Class type, PathMetadata metadata, PathInits inits) { super(type, metadata, inits); - this.order = inits.isInitialized("order") ? new project.trendpick_pro.domain.orders.entity.QOrders(forProperty("order")) : null; + this.order = inits.isInitialized("order") ? new project.trendpick_pro.domain.orders.entity.QOrders(forProperty("order"), inits.get("order")) : null; } } diff --git a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java index b30e9627..eae51241 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java +++ b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java @@ -19,20 +19,20 @@ public String registerAnswer(@PathVariable Long askId, String member = "member"; //Member answerService.register(askId, member, answerRequest); - return "redirect:trendpick/customerservice/asks/{askId}".formatted(askId); + return "redirect:/trendpick/customerservice/asks/{askId}".formatted(askId); } @PostMapping("/delete/{answerId}") public String deleteAnswer(@PathVariable Long askId, @PathVariable Long answerId){ answerService.delete(answerId); - return "redirect:trendpick/asks/detail".formatted(askId); + return "redirect:/trendpick/customerservice/asks/%s".formatted(askId); } @PostMapping("/moidfy/{answerId}") public String modifyAnswer(@PathVariable Long askId, @PathVariable Long answerId, @Valid AnswerRequest answerRequest){ answerService.modify(answerId, answerRequest); - return "redirect:trendpick/asks/detail".formatted(askId); + return "redirect:/trendpick/customerservice/asks/%s".formatted(askId); } } diff --git a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java index 72c5e418..dcd6b7c2 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java +++ b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java @@ -18,20 +18,20 @@ public class AskController { @GetMapping("/list") public String showAllAsk(Model model) { model.addAttribute("askResponse", askService.showAll()); - return "trendpick/customerservice/ask/list"; + return "trendpick/customerservice/asks/list"; } @GetMapping("/{askId}}") public String showAsk(@PathVariable Long askId, Model model) { model.addAttribute("askResponse", askService.show(askId)); - return "trendpick/customerservice/ask/detail"; + return "trendpick/customerservice/asks/detail"; } @PostMapping("/delete/{askId}") public String deleteAsk(@PathVariable Long askId) { askService.delete(askId); - return "redirect:/trendpick/asks/list"; + return "redirect:/trendpick/customerservice/asks/list"; } @PostMapping("/edit/{askId}") @@ -39,7 +39,7 @@ public String modifyAsk(@PathVariable Long askId, @Valid AskRequest askRequest, AskResponse askResponse = askService.modify(askId, askRequest); model.addAttribute("askResponse", askResponse); - return "redirect:/trendpick/asks/%s".formatted(askId); + return "redirect:/trendpick/customerservice/asks/%s".formatted(askId); } @PostMapping("/register") @@ -47,6 +47,6 @@ public String registerAsk(@Valid AskRequest askRequest, @RequestParam(value = "b AskResponse askResponse = askService.register(askRequest); model.addAttribute("askResponse", askResponse); - return "redirect:/trendpick/asks/%s".formatted(askResponse.getId()); + return "redirect:/trendpick/customerservice/asks/%s".formatted(askResponse.getId()); } } diff --git a/src/main/resources/templates/trendpick/customerservice/asks/detail.html b/src/main/resources/templates/trendpick/customerservice/asks/detail.html index 566549bd..97efd723 100644 --- a/src/main/resources/templates/trendpick/customerservice/asks/detail.html +++ b/src/main/resources/templates/trendpick/customerservice/asks/detail.html @@ -5,6 +5,6 @@ Title - + 문의내역 상세페이지 \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/customerservice/asks/list.html b/src/main/resources/templates/trendpick/customerservice/asks/list.html index 566549bd..8ec0c3ac 100644 --- a/src/main/resources/templates/trendpick/customerservice/asks/list.html +++ b/src/main/resources/templates/trendpick/customerservice/asks/list.html @@ -5,6 +5,6 @@ Title - + 문의내역 \ No newline at end of file From 608e960797dc448e10bc85174ec815af8cca4f2c Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Sun, 28 May 2023 18:02:55 +0900 Subject: [PATCH 027/367] =?UTF-8?q?feat:=20cart=20=EA=B8=B0=EB=B3=B8?= =?UTF-8?q?=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cart/controller/CartController.java | 4 ++++ .../domain/cart/entity/Cart.java | 21 +++++++++++++++++++ .../cart/repository/CartRepository.java | 7 +++++++ .../domain/cart/service/CartService.java | 4 ++++ 4 files changed, 36 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java create mode 100644 src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java create mode 100644 src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java create mode 100644 src/main/java/project/trendpick_pro/domain/cart/service/CartService.java diff --git a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java new file mode 100644 index 00000000..31f4b3bc --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.cart.controller; + +public class CartController { +} diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java new file mode 100644 index 00000000..374f95a3 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java @@ -0,0 +1,21 @@ +package project.trendpick_pro.domain.cart.entity; + +import jakarta.persistence.*; + +import java.util.ArrayList; +import java.util.List; + +public class Cart { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "cart_id") + private Long id; + + private int totalCount; // 총 수량 + + // @ManyToOne(fetch = FetchType.LAZY) + // @JoinColumn(name = "user_id") + private String user_id; // user + + private int totalPrice; // 총 금액 +} diff --git a/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java b/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java new file mode 100644 index 00000000..eb61cf71 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java @@ -0,0 +1,7 @@ +package project.trendpick_pro.domain.cart.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.cart.entity.Cart; + +public interface CartRepository extends JpaRepository { +} diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java new file mode 100644 index 00000000..77312e6a --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.cart.service; + +public class CartService { +} From 9f99a0b74f821aa2d6bc5257b84d43470e630b9f Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Sun, 28 May 2023 18:45:03 +0900 Subject: [PATCH 028/367] =?UTF-8?q?feat:=20Notification=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/NotificationController.java | 4 ++++ .../notification/entity/Notification.java | 21 +++++++++++++++++++ .../repository/NotificationRepository.java | 7 +++++++ .../service/NotificationService.java | 4 ++++ 4 files changed, 36 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/notification/controller/NotificationController.java create mode 100644 src/main/java/project/trendpick_pro/domain/notification/entity/Notification.java create mode 100644 src/main/java/project/trendpick_pro/domain/notification/repository/NotificationRepository.java create mode 100644 src/main/java/project/trendpick_pro/domain/notification/service/NotificationService.java diff --git a/src/main/java/project/trendpick_pro/domain/notification/controller/NotificationController.java b/src/main/java/project/trendpick_pro/domain/notification/controller/NotificationController.java new file mode 100644 index 00000000..b7896843 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/notification/controller/NotificationController.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.notification.controller; + +public class NotificationController { +} diff --git a/src/main/java/project/trendpick_pro/domain/notification/entity/Notification.java b/src/main/java/project/trendpick_pro/domain/notification/entity/Notification.java new file mode 100644 index 00000000..1cc01437 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/notification/entity/Notification.java @@ -0,0 +1,21 @@ +package project.trendpick_pro.domain.notification.entity; + +import jakarta.persistence.*; +import lombok.*; + +import java.time.LocalDateTime; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Notification { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + private LocalDateTime creatDate; // 생성일 + + private String title; // 알림명 + + private String content; // 알림내용 +} diff --git a/src/main/java/project/trendpick_pro/domain/notification/repository/NotificationRepository.java b/src/main/java/project/trendpick_pro/domain/notification/repository/NotificationRepository.java new file mode 100644 index 00000000..334b6efa --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/notification/repository/NotificationRepository.java @@ -0,0 +1,7 @@ +package project.trendpick_pro.domain.notification.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.notification.entity.Notification; + +public interface NotificationRepository extends JpaRepository { +} diff --git a/src/main/java/project/trendpick_pro/domain/notification/service/NotificationService.java b/src/main/java/project/trendpick_pro/domain/notification/service/NotificationService.java new file mode 100644 index 00000000..08f194a2 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/notification/service/NotificationService.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.notification.service; + +public class NotificationService { +} From fd7616a858cf5a74cdd15673e9c0a7cc6b78f7cc Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 28 May 2023 18:50:48 +0900 Subject: [PATCH 029/367] =?UTF-8?q?style:=20=EC=97=94=ED=8B=B0=ED=8B=B0?= =?UTF-8?q?=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trendpick_pro/domain/delivery/entity/Delivery.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/delivery/entity/Delivery.java b/src/main/java/project/trendpick_pro/domain/delivery/entity/Delivery.java index 3df75728..a096f22a 100644 --- a/src/main/java/project/trendpick_pro/domain/delivery/entity/Delivery.java +++ b/src/main/java/project/trendpick_pro/domain/delivery/entity/Delivery.java @@ -5,7 +5,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import project.trendpick_pro.domain.common.base.BaseTimeEntity; -import project.trendpick_pro.domain.orders.entity.Orders; +import project.trendpick_pro.domain.orders.entity.Order; @Entity @Getter @@ -17,7 +17,7 @@ public class Delivery extends BaseTimeEntity { private Long id; @OneToOne(mappedBy = "delivery", fetch = FetchType.LAZY) - private Orders order; + private Order order; private String address; @Enumerated(EnumType.STRING) private DeliveryState state; From 006bd65d06f3be210491a2c408a02d0db043f300 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 28 May 2023 18:50:52 +0900 Subject: [PATCH 030/367] =?UTF-8?q?style:=20=EC=97=94=ED=8B=B0=ED=8B=B0?= =?UTF-8?q?=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/orders/entity/Order.java | 78 +++++++++++++++++++ .../orders/repository/OrderRepository.java | 7 ++ .../orders/repository/OrdersRepository.java | 7 -- 3 files changed, 85 insertions(+), 7 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/orders/entity/Order.java create mode 100644 src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java delete mode 100644 src/main/java/project/trendpick_pro/domain/orders/repository/OrdersRepository.java diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java new file mode 100644 index 00000000..6cadf829 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java @@ -0,0 +1,78 @@ +package project.trendpick_pro.domain.orders.entity; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.common.base.BaseTimeEntity; +import project.trendpick_pro.domain.delivery.entity.Delivery; +import project.trendpick_pro.domain.delivery.entity.DeliveryState; +import project.trendpick_pro.domain.user.entity.User; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@Table(name = "orders") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Order extends BaseTimeEntity { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "order_id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id") + private User user; + + @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) + private List orderItems = new ArrayList<>(); + + @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @JoinColumn(name = "delivery_id") + private Delivery delivery; + + @Enumerated(EnumType.STRING) + private OrderStatus status; + + @Column(name = "total_price", nullable = false) + private int totalPrice; + + public void connectUser(User user) { + this.user = user; + } + + public void connectDelivery(Delivery delivery) { + this.delivery = delivery; + } + + public void addOrderItem(OrderItem orderItem) { + orderItems.add(orderItem); + orderItem.connectOrder(this); + } + + public static Order createOrder(User user, Delivery delivery, OrderStatus status, List orderItems) { + Order order = new Order(); + order.connectUser(user); + order.connectDelivery(delivery); + for (OrderItem orderItem : orderItems) { + order.addOrderItem(orderItem); + order.totalPrice += orderItem.getTotalPrice(); + } + order.status = status; + + return order; + } + + public void cancel() { + if (delivery.getState() == DeliveryState.COMPLETED) { + throw new IllegalStateException("이미 배송완료된 상품은 취소가 불가능합니다."); + } + this.status = OrderStatus.CANCELLED; + + for (OrderItem orderItem : orderItems) { + orderItem.cancel(); + } + } +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java new file mode 100644 index 00000000..3342901a --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java @@ -0,0 +1,7 @@ +package project.trendpick_pro.domain.orders.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.orders.entity.Order; + +public interface OrderRepository extends JpaRepository { +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrdersRepository.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrdersRepository.java deleted file mode 100644 index 9086edbc..00000000 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrdersRepository.java +++ /dev/null @@ -1,7 +0,0 @@ -package project.trendpick_pro.domain.orders.repository; - -import org.springframework.data.jpa.repository.JpaRepository; -import project.trendpick_pro.domain.orders.entity.Orders; - -public interface OrdersRepository extends JpaRepository { -} From 787fddcd2e474b2a22c48d7e1bcbbf87821ebcc6 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 28 May 2023 18:50:55 +0900 Subject: [PATCH 031/367] =?UTF-8?q?style:=20=EC=97=94=ED=8B=B0=ED=8B=B0?= =?UTF-8?q?=EB=AA=85=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/orders/entity/Orders.java | 28 ------------------- 1 file changed, 28 deletions(-) delete mode 100644 src/main/java/project/trendpick_pro/domain/orders/entity/Orders.java diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/Orders.java b/src/main/java/project/trendpick_pro/domain/orders/entity/Orders.java deleted file mode 100644 index db718ee6..00000000 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/Orders.java +++ /dev/null @@ -1,28 +0,0 @@ -package project.trendpick_pro.domain.orders.entity; - -import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; -import project.trendpick_pro.domain.common.base.BaseTimeEntity; -import project.trendpick_pro.domain.delivery.entity.Delivery; - -@Entity -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class Orders extends BaseTimeEntity { - - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private int totalPrice; - private String status; - -// @ManyToOne(fetch = FetchType.LAZY) -// @JoinColumn(name = "member_id") - private String user; // User - - @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY) - @JoinColumn(name = "delivery_id") - private Delivery delivery; -} From e84926994157f27b31fa1c9e95e294d405ac81e4 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 28 May 2023 18:51:13 +0900 Subject: [PATCH 032/367] =?UTF-8?q?feat:=20=EC=A3=BC=EB=AC=B8=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orders/contoller/OrderController.java | 44 +++++++++++++ .../domain/orders/entity/OrderItem.java | 53 +++++++++++++++ .../entity/dto/request/OrderSaveRequest.java | 13 ++++ .../entity/dto/request/OrderSearchCond.java | 10 +++ .../entity/dto/response/OrderResponse.java | 35 ++++++++++ .../domain/orders/service/OrderService.java | 66 +++++++++++++++++++ 6 files changed, 221 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java create mode 100644 src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java create mode 100644 src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSaveRequest.java create mode 100644 src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSearchCond.java create mode 100644 src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java create mode 100644 src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java new file mode 100644 index 00000000..bc32105b --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -0,0 +1,44 @@ +package project.trendpick_pro.domain.orders.contoller; + +import jakarta.validation.Valid; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; +import project.trendpick_pro.domain.orders.entity.dto.request.OrderSaveRequest; +import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; +import project.trendpick_pro.domain.orders.service.OrderService; + +import java.util.List; + +@Slf4j +@Controller +@RequiredArgsConstructor +@RequestMapping("trendpick/order") +public class OrderController { + + private final OrderService orderService; + + @PostMapping("/order") + public String order(@Valid OrderSaveRequest... orderSaveRequests){ + + orderService.order(1L, orderSaveRequests); + return "redirect:/orders"; + } + + @GetMapping("/orders") + public String orderList(Model model) { + Page responses = orderService.findAll(1L); + model.addAttribute("orders", responses); + return "order/orderList"; + } + + @PostMapping("/orders/{orderId}/cancel") + public String cancelOrder(@PathVariable("orderId") Long orderId) { + orderService.cancel(orderId); + return "redirect:/orders"; + } + +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java new file mode 100644 index 00000000..74845639 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java @@ -0,0 +1,53 @@ +package project.trendpick_pro.domain.orders.entity; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.product.entity.Product; + +@Entity +@Getter +@Table(name = "order_item") +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class OrderItem { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "order_item_id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "order_id") + private Order order; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "product_id") + private Product product; + + @Column(name = "order_price", nullable = false) + private int orderPrice; + + @Column(name = "count", nullable = false) + private int count; + + public OrderItem(Product product, int orderPrice, int count) throws IllegalAccessException { + this.product = product; + this.orderPrice = orderPrice; + this.count = count; + + product.removeStock(count); + } + + public void connectOrder(Order order) { + this.order = order; + } + + public void cancel() { + this.product.addStock(count); + } + + public int getTotalPrice() { + return getOrderPrice() * getCount(); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSaveRequest.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSaveRequest.java new file mode 100644 index 00000000..287ab7bf --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSaveRequest.java @@ -0,0 +1,13 @@ +package project.trendpick_pro.domain.orders.entity.dto.request; + +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; + +@Getter +public class OrderSaveRequest { + + private Long productId; + + @NotBlank(message = "수량을 입력해주세요.") + private int quantity; +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSearchCond.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSearchCond.java new file mode 100644 index 00000000..0b03b59f --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSearchCond.java @@ -0,0 +1,10 @@ +package project.trendpick_pro.domain.orders.entity.dto.request; + +import lombok.Getter; + +@Getter +public class OrderSearchCond { + + private Long userId; + +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java new file mode 100644 index 00000000..c94150f2 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java @@ -0,0 +1,35 @@ +package project.trendpick_pro.domain.orders.entity.dto.response; + +import com.querydsl.core.annotations.QueryProjection; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.delivery.entity.DeliveryState; +import project.trendpick_pro.domain.orders.entity.Order; +import project.trendpick_pro.domain.orders.entity.OrderItem; + +import java.time.LocalDateTime; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class OrderResponse { + + private Long orderId; + private String brandName; + private String orderItemName; + private LocalDateTime order_date; + private int totalPrice; + private String deliveryStatus; + + @Builder + @QueryProjection + public OrderResponse(Long orderId, String brandName, String productName, LocalDateTime order_date, int totalPrice, String deliveryStatus) { + this.orderId = orderId; + this.brandName = brandName; + this.orderItemName = productName; + this.order_date = order_date; + this.totalPrice = totalPrice; + this.deliveryStatus = deliveryStatus; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java new file mode 100644 index 00000000..36ffdd62 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -0,0 +1,66 @@ +package project.trendpick_pro.domain.orders.service; + +import jakarta.persistence.EntityNotFoundException; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.delivery.entity.Delivery; +import project.trendpick_pro.domain.orders.entity.Order; +import project.trendpick_pro.domain.orders.entity.OrderItem; +import project.trendpick_pro.domain.orders.entity.OrderStatus; +import project.trendpick_pro.domain.orders.entity.dto.request.OrderSaveRequest; +import project.trendpick_pro.domain.orders.entity.dto.request.OrderSearchCond; +import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; +import project.trendpick_pro.domain.orders.repository.OrderRepository; +import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.product.repository.ProductRepository; +import project.trendpick_pro.domain.user.entity.User; +import project.trendpick_pro.domain.user.repository.UserRepository; + +import java.util.ArrayList; +import java.util.List; + +@Slf4j +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class OrderService { + + private final OrderRepository orderRepository; + private final UserRepository userRepository; + private final ProductRepository productRepository; + + @Transactional + public void order(Long userId, OrderSaveRequest... orderSaveRequests) throws IllegalAccessException { + + User user = userRepository.findById(userId).orElseThrow(() -> new EntityNotFoundException("존재하지 않는 유저 입니다."));// 임시 exception 설정 나중에 할 수도 있고 아닐수도 + + Delivery delivery = new Delivery(); + + List orderItemList = new ArrayList<>(); + for (OrderSaveRequest request: orderSaveRequests) { + Product product = productRepository.findById(request.getProductId()).orElseThrow(() -> new EntityNotFoundException("product is not found")); + if (product.getStock() < 0) { + throw new RuntimeException("stock is not enough"); // 임시. 나중에 사용자 exception 널을까말까 생각 + } + orderItemList.add(new OrderItem(product, product.getPrice(), request.getQuantity())); + } + + Order order = Order.createOrder(user, delivery, OrderStatus.ORDERED, orderItemList); + orderRepository.save(order); + } + + @Transactional + public void cancel(Long orderId) { + Order order = orderRepository.findById(orderId).orElseThrow(() -> new EntityNotFoundException("존재하지 않는 주문입니다.")); + order.cancel(); + } + + public Page findAll(OrderSearchCond cond) { + return orderRepository.findAll(cond.getUserId()); + } + + +} From 247d9a767814267188cadeb5c8898ba609a49f0a Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 28 May 2023 18:51:22 +0900 Subject: [PATCH 033/367] =?UTF-8?q?feat:=20=EC=A3=BC=EB=AC=B8=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trendpick_pro/domain/orders/entity/OrderState.java | 5 ----- .../trendpick_pro/domain/orders/entity/OrderStatus.java | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) delete mode 100644 src/main/java/project/trendpick_pro/domain/orders/entity/OrderState.java create mode 100644 src/main/java/project/trendpick_pro/domain/orders/entity/OrderStatus.java diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderState.java b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderState.java deleted file mode 100644 index 2e48045e..00000000 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderState.java +++ /dev/null @@ -1,5 +0,0 @@ -package project.trendpick_pro.domain.orders.entity; - -public enum OrderState { - ORDERED, CANCELLED, COMPLETED; -} diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderStatus.java b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderStatus.java new file mode 100644 index 00000000..7b103d4f --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderStatus.java @@ -0,0 +1,5 @@ +package project.trendpick_pro.domain.orders.entity; + +public enum OrderStatus { + ORDERED, CANCELLED; +} From e0282f226d447518f77aa4dc4bf4e019040630ae Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 28 May 2023 18:51:39 +0900 Subject: [PATCH 034/367] =?UTF-8?q?refactor:=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/product/entity/Product.java | 13 +++++++++++++ ...WithIdResponse.java => ProductListResponse.java} | 4 ++-- 2 files changed, 15 insertions(+), 2 deletions(-) rename src/main/java/project/trendpick_pro/domain/product/entity/dto/response/{ProductWithIdResponse.java => ProductListResponse.java} (81%) diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index 7f0801bd..e93d5c7b 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -83,6 +83,19 @@ public static Product of(ProductSaveRequest request) { .build(); } + public void addStock(int quantity) { + this.stock += quantity; + } + + public void removeStock(int quantity) throws IllegalAccessException { + int restStock = this.stock - quantity; + if (restStock < 0) { + throw new IllegalAccessException("need more stock"); + } + this.stock = restStock; + } + + public void update(ProductSaveRequest request) { // 여기서 파일 지지고 볶고 할 예정 diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductWithIdResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponse.java similarity index 81% rename from src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductWithIdResponse.java rename to src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponse.java index 90558953..f627b3b0 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductWithIdResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponse.java @@ -8,7 +8,7 @@ @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class ProductWithIdResponse { +public class ProductListResponse { private Long id; private String name; @@ -17,7 +17,7 @@ public class ProductWithIdResponse { private int price; @QueryProjection - public ProductWithIdResponse(Long id, String name, String brand, CommonFile mainFile, int price) { + public ProductListResponse(Long id, String name, String brand, CommonFile mainFile, int price) { this.id = id; this.name = name; this.brand = brand; From 7f1a9e91d0dfc7e7e339ba6b3ebd3be5b97c50a3 Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Sun, 28 May 2023 20:18:35 +0900 Subject: [PATCH 035/367] =?UTF-8?q?fix:=20brand,cart=20entity=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../project/trendpick_pro/domain/brand/entity/Brand.java | 7 ++----- .../project/trendpick_pro/domain/cart/entity/Cart.java | 8 ++++++-- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/brand/entity/Brand.java b/src/main/java/project/trendpick_pro/domain/brand/entity/Brand.java index 3a0c6e8a..71683a2d 100644 --- a/src/main/java/project/trendpick_pro/domain/brand/entity/Brand.java +++ b/src/main/java/project/trendpick_pro/domain/brand/entity/Brand.java @@ -1,14 +1,11 @@ package project.trendpick_pro.domain.brand.entity; -import jakarta.persistence.Column; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; -@jakarta.persistence.Entity +@Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Brand { diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java index 374f95a3..7380ef2e 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java @@ -1,10 +1,14 @@ package project.trendpick_pro.domain.cart.entity; import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; -import java.util.ArrayList; -import java.util.List; +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Cart { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) From e11fcfa7c021884e7e334051e78ad1bcac98f6cd Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Sun, 28 May 2023 21:08:13 +0900 Subject: [PATCH 036/367] =?UTF-8?q?chore:=20=ED=8C=A8=ED=82=A4=EC=A7=80?= =?UTF-8?q?=EB=AA=85=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - user -> member --- .../domain/{user => member}/entity/QUser.java | 2 +- .../domain/member/controller/UserController.java | 4 ++++ .../domain/{user => member}/entity/RoleType.java | 2 +- .../trendpick_pro/domain/{user => member}/entity/User.java | 7 ++----- .../domain/{user => member}/repository/UserRepository.java | 4 ++-- .../trendpick_pro/domain/member/service/UserService.java | 4 ++++ .../project/trendpick_pro/domain/orders/entity/Order.java | 2 +- .../trendpick_pro/domain/orders/service/OrderService.java | 4 ++-- .../project/trendpick_pro/domain/review/entity/Review.java | 4 +--- .../domain/user/controller/UserController.java | 4 ---- .../trendpick_pro/domain/user/service/UserService.java | 4 ---- 11 files changed, 18 insertions(+), 23 deletions(-) rename src/main/generated/project/trendpick_pro/domain/{user => member}/entity/QUser.java (96%) create mode 100644 src/main/java/project/trendpick_pro/domain/member/controller/UserController.java rename src/main/java/project/trendpick_pro/domain/{user => member}/entity/RoleType.java (50%) rename src/main/java/project/trendpick_pro/domain/{user => member}/entity/User.java (82%) rename src/main/java/project/trendpick_pro/domain/{user => member}/repository/UserRepository.java (54%) create mode 100644 src/main/java/project/trendpick_pro/domain/member/service/UserService.java delete mode 100644 src/main/java/project/trendpick_pro/domain/user/controller/UserController.java delete mode 100644 src/main/java/project/trendpick_pro/domain/user/service/UserService.java diff --git a/src/main/generated/project/trendpick_pro/domain/user/entity/QUser.java b/src/main/generated/project/trendpick_pro/domain/member/entity/QUser.java similarity index 96% rename from src/main/generated/project/trendpick_pro/domain/user/entity/QUser.java rename to src/main/generated/project/trendpick_pro/domain/member/entity/QUser.java index c3a4572b..f19d0383 100644 --- a/src/main/generated/project/trendpick_pro/domain/user/entity/QUser.java +++ b/src/main/generated/project/trendpick_pro/domain/member/entity/QUser.java @@ -1,4 +1,4 @@ -package project.trendpick_pro.domain.user.entity; +package project.trendpick_pro.domain.member.entity; import static com.querydsl.core.types.PathMetadataFactory.*; diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/UserController.java b/src/main/java/project/trendpick_pro/domain/member/controller/UserController.java new file mode 100644 index 00000000..5a03a431 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/member/controller/UserController.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.member.controller; + +public class UserController { +} diff --git a/src/main/java/project/trendpick_pro/domain/user/entity/RoleType.java b/src/main/java/project/trendpick_pro/domain/member/entity/RoleType.java similarity index 50% rename from src/main/java/project/trendpick_pro/domain/user/entity/RoleType.java rename to src/main/java/project/trendpick_pro/domain/member/entity/RoleType.java index 30bdf81d..88ac8344 100644 --- a/src/main/java/project/trendpick_pro/domain/user/entity/RoleType.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/RoleType.java @@ -1,4 +1,4 @@ -package project.trendpick_pro.domain.user.entity; +package project.trendpick_pro.domain.member.entity; public enum RoleType{ ADMIN, BRAND_ADMIN, USER diff --git a/src/main/java/project/trendpick_pro/domain/user/entity/User.java b/src/main/java/project/trendpick_pro/domain/member/entity/User.java similarity index 82% rename from src/main/java/project/trendpick_pro/domain/user/entity/User.java rename to src/main/java/project/trendpick_pro/domain/member/entity/User.java index 39f3154e..0dc04874 100644 --- a/src/main/java/project/trendpick_pro/domain/user/entity/User.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/User.java @@ -1,15 +1,12 @@ -package project.trendpick_pro.domain.user.entity; +package project.trendpick_pro.domain.member.entity; import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import project.trendpick_pro.domain.tag.entity.Tag; -import java.util.ArrayList; import java.util.Date; -import java.util.List; @Entity @NoArgsConstructor @@ -18,7 +15,7 @@ @Getter public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "user_id") + @Column(name = "member_id") private Long id; private String email; diff --git a/src/main/java/project/trendpick_pro/domain/user/repository/UserRepository.java b/src/main/java/project/trendpick_pro/domain/member/repository/UserRepository.java similarity index 54% rename from src/main/java/project/trendpick_pro/domain/user/repository/UserRepository.java rename to src/main/java/project/trendpick_pro/domain/member/repository/UserRepository.java index 4be0cb6c..94a24064 100644 --- a/src/main/java/project/trendpick_pro/domain/user/repository/UserRepository.java +++ b/src/main/java/project/trendpick_pro/domain/member/repository/UserRepository.java @@ -1,7 +1,7 @@ -package project.trendpick_pro.domain.user.repository; +package project.trendpick_pro.domain.member.repository; import org.springframework.data.jpa.repository.JpaRepository; -import project.trendpick_pro.domain.user.entity.User; +import project.trendpick_pro.domain.member.entity.User; public interface UserRepository extends JpaRepository { } diff --git a/src/main/java/project/trendpick_pro/domain/member/service/UserService.java b/src/main/java/project/trendpick_pro/domain/member/service/UserService.java new file mode 100644 index 00000000..394a4935 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/member/service/UserService.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.member.service; + +public class UserService { +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java index 6cadf829..3f0dfb0f 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java @@ -7,7 +7,7 @@ import project.trendpick_pro.domain.common.base.BaseTimeEntity; import project.trendpick_pro.domain.delivery.entity.Delivery; import project.trendpick_pro.domain.delivery.entity.DeliveryState; -import project.trendpick_pro.domain.user.entity.User; +import project.trendpick_pro.domain.member.entity.User; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 36ffdd62..f6f22cf6 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -16,8 +16,8 @@ import project.trendpick_pro.domain.orders.repository.OrderRepository; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; -import project.trendpick_pro.domain.user.entity.User; -import project.trendpick_pro.domain.user.repository.UserRepository; +import project.trendpick_pro.domain.member.entity.User; +import project.trendpick_pro.domain.member.repository.UserRepository; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java index 2ad0855b..7fbe836f 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -6,8 +6,6 @@ import lombok.Getter; import lombok.NoArgsConstructor; import project.trendpick_pro.domain.common.base.BaseTimeEntity; -import project.trendpick_pro.domain.product.entity.Product; -import project.trendpick_pro.domain.user.entity.User; @Entity @NoArgsConstructor @@ -20,7 +18,7 @@ public class Review extends BaseTimeEntity { private Long id; //@ManyToOne - //@JoinColumn(name = "user_id") + //@JoinColumn(name = "member_id") private Long user_id; //User // @ManyToOne(fetch = FetchType.LAZY) diff --git a/src/main/java/project/trendpick_pro/domain/user/controller/UserController.java b/src/main/java/project/trendpick_pro/domain/user/controller/UserController.java deleted file mode 100644 index abdb19e0..00000000 --- a/src/main/java/project/trendpick_pro/domain/user/controller/UserController.java +++ /dev/null @@ -1,4 +0,0 @@ -package project.trendpick_pro.domain.user.controller; - -public class UserController { -} diff --git a/src/main/java/project/trendpick_pro/domain/user/service/UserService.java b/src/main/java/project/trendpick_pro/domain/user/service/UserService.java deleted file mode 100644 index 72c1a7bf..00000000 --- a/src/main/java/project/trendpick_pro/domain/user/service/UserService.java +++ /dev/null @@ -1,4 +0,0 @@ -package project.trendpick_pro.domain.user.service; - -public class UserService { -} From e99e6dd0c7ce4a7f3aa3d61c76432d627ea7c9a6 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Sun, 28 May 2023 21:22:55 +0900 Subject: [PATCH 037/367] =?UTF-8?q?style:=20=EB=B3=80=EC=88=98=EB=AA=85=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - user -> member --- .../trendpick_pro/domain/member/entity/QUser.java | 8 ++++---- .../{UserController.java => MemberrController.java} | 2 +- .../domain/member/entity/{User.java => Member.java} | 2 +- .../domain/member/repository/UserRepository.java | 4 ++-- .../trendpick_pro/domain/orders/entity/Order.java | 12 ++++++------ .../domain/orders/service/OrderService.java | 6 +++--- 6 files changed, 17 insertions(+), 17 deletions(-) rename src/main/java/project/trendpick_pro/domain/member/controller/{UserController.java => MemberrController.java} (64%) rename src/main/java/project/trendpick_pro/domain/member/entity/{User.java => Member.java} (97%) diff --git a/src/main/generated/project/trendpick_pro/domain/member/entity/QUser.java b/src/main/generated/project/trendpick_pro/domain/member/entity/QUser.java index f19d0383..cdb35e11 100644 --- a/src/main/generated/project/trendpick_pro/domain/member/entity/QUser.java +++ b/src/main/generated/project/trendpick_pro/domain/member/entity/QUser.java @@ -13,7 +13,7 @@ * QUser is a Querydsl query type for User */ @Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QUser extends EntityPathBase { +public class QUser extends EntityPathBase { private static final long serialVersionUID = 350707846L; @@ -40,15 +40,15 @@ public class QUser extends EntityPathBase { public final NumberPath tag_id = createNumber("tag_id", Long.class); public QUser(String variable) { - super(User.class, forVariable(variable)); + super(Member.class, forVariable(variable)); } - public QUser(Path path) { + public QUser(Path path) { super(path.getType(), path.getMetadata()); } public QUser(PathMetadata metadata) { - super(User.class, metadata); + super(Member.class, metadata); } } diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/UserController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberrController.java similarity index 64% rename from src/main/java/project/trendpick_pro/domain/member/controller/UserController.java rename to src/main/java/project/trendpick_pro/domain/member/controller/MemberrController.java index 5a03a431..d04f0ed7 100644 --- a/src/main/java/project/trendpick_pro/domain/member/controller/UserController.java +++ b/src/main/java/project/trendpick_pro/domain/member/controller/MemberrController.java @@ -1,4 +1,4 @@ package project.trendpick_pro.domain.member.controller; -public class UserController { +public class MemberrController { } diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/User.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java similarity index 97% rename from src/main/java/project/trendpick_pro/domain/member/entity/User.java rename to src/main/java/project/trendpick_pro/domain/member/entity/Member.java index 0dc04874..6495555c 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/User.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -13,7 +13,7 @@ @AllArgsConstructor @Builder @Getter -public class User { +public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "member_id") private Long id; diff --git a/src/main/java/project/trendpick_pro/domain/member/repository/UserRepository.java b/src/main/java/project/trendpick_pro/domain/member/repository/UserRepository.java index 94a24064..95c01c7d 100644 --- a/src/main/java/project/trendpick_pro/domain/member/repository/UserRepository.java +++ b/src/main/java/project/trendpick_pro/domain/member/repository/UserRepository.java @@ -1,7 +1,7 @@ package project.trendpick_pro.domain.member.repository; import org.springframework.data.jpa.repository.JpaRepository; -import project.trendpick_pro.domain.member.entity.User; +import project.trendpick_pro.domain.member.entity.Member; -public interface UserRepository extends JpaRepository { +public interface UserRepository extends JpaRepository { } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java index 3f0dfb0f..6f6a3e89 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java @@ -7,7 +7,7 @@ import project.trendpick_pro.domain.common.base.BaseTimeEntity; import project.trendpick_pro.domain.delivery.entity.Delivery; import project.trendpick_pro.domain.delivery.entity.DeliveryState; -import project.trendpick_pro.domain.member.entity.User; +import project.trendpick_pro.domain.member.entity.Member; import java.util.ArrayList; import java.util.List; @@ -24,7 +24,7 @@ public class Order extends BaseTimeEntity { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id") - private User user; + private Member member; @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) private List orderItems = new ArrayList<>(); @@ -39,8 +39,8 @@ public class Order extends BaseTimeEntity { @Column(name = "total_price", nullable = false) private int totalPrice; - public void connectUser(User user) { - this.user = user; + public void connectUser(Member member) { + this.member = member; } public void connectDelivery(Delivery delivery) { @@ -52,9 +52,9 @@ public void addOrderItem(OrderItem orderItem) { orderItem.connectOrder(this); } - public static Order createOrder(User user, Delivery delivery, OrderStatus status, List orderItems) { + public static Order createOrder(Member member, Delivery delivery, OrderStatus status, List orderItems) { Order order = new Order(); - order.connectUser(user); + order.connectUser(member); order.connectDelivery(delivery); for (OrderItem orderItem : orderItems) { order.addOrderItem(orderItem); diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index f6f22cf6..f642f422 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -7,6 +7,7 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.delivery.entity.Delivery; +import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.orders.entity.Order; import project.trendpick_pro.domain.orders.entity.OrderItem; import project.trendpick_pro.domain.orders.entity.OrderStatus; @@ -16,7 +17,6 @@ import project.trendpick_pro.domain.orders.repository.OrderRepository; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; -import project.trendpick_pro.domain.member.entity.User; import project.trendpick_pro.domain.member.repository.UserRepository; import java.util.ArrayList; @@ -35,7 +35,7 @@ public class OrderService { @Transactional public void order(Long userId, OrderSaveRequest... orderSaveRequests) throws IllegalAccessException { - User user = userRepository.findById(userId).orElseThrow(() -> new EntityNotFoundException("존재하지 않는 유저 입니다."));// 임시 exception 설정 나중에 할 수도 있고 아닐수도 + Member member = userRepository.findById(userId).orElseThrow(() -> new EntityNotFoundException("존재하지 않는 유저 입니다."));// 임시 exception 설정 나중에 할 수도 있고 아닐수도 Delivery delivery = new Delivery(); @@ -48,7 +48,7 @@ public void order(Long userId, OrderSaveRequest... orderSaveRequests) throws Ill orderItemList.add(new OrderItem(product, product.getPrice(), request.getQuantity())); } - Order order = Order.createOrder(user, delivery, OrderStatus.ORDERED, orderItemList); + Order order = Order.createOrder(member, delivery, OrderStatus.ORDERED, orderItemList); orderRepository.save(order); } From 7898814fe56de8fa50215ca18ae037f95f0326a9 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Sun, 28 May 2023 22:20:39 +0900 Subject: [PATCH 038/367] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=5F=EC=97=84=EC=B2=AD=20=EC=98=A4=EB=A5=98=EB=82=98?= =?UTF-8?q?=EB=8A=94=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - user -> member --- .../domain/brand/entity/QBrand.java | 39 +++++++++++ .../domain/delivery/entity/QDelivery.java | 4 +- .../domain/member/entity/QMember.java | 55 +++++++++++++++ .../notification/entity/QNotification.java | 43 ++++++++++++ .../domain/orders/entity/QOrder.java | 68 +++++++++++++++++++ .../domain/orders/entity/QOrderItem.java | 58 ++++++++++++++++ .../entity/dto/response/QOrderResponse.java | 21 ++++++ .../dto/response/QProductListResponse.java | 21 ++++++ .../domain/common/base/rq/Rq.java | 65 ++++++++++++++++++ .../common/base/security/SecurityConfig.java | 31 +++++++++ .../member/controller/MemberController.java | 60 ++++++++++++++++ .../member/controller/MemberrController.java | 4 -- .../domain/member/entity/Member.java | 2 +- ...rRepository.java => MemberRepository.java} | 7 +- .../domain/member/service/MemberService.java | 34 ++++++++++ .../domain/member/service/UserService.java | 4 -- src/main/resources/application.yml | 16 ++--- .../trendpick/usr/layout/layout.html | 68 +++++++++++++++++++ .../templates/trendpick/usr/member/join.html | 63 +++++++++++++++++ .../templates/trendpick/usr/member/login.html | 62 +++++++++++++++++ 20 files changed, 704 insertions(+), 21 deletions(-) create mode 100644 src/main/generated/project/trendpick_pro/domain/brand/entity/QBrand.java create mode 100644 src/main/generated/project/trendpick_pro/domain/member/entity/QMember.java create mode 100644 src/main/generated/project/trendpick_pro/domain/notification/entity/QNotification.java create mode 100644 src/main/generated/project/trendpick_pro/domain/orders/entity/QOrder.java create mode 100644 src/main/generated/project/trendpick_pro/domain/orders/entity/QOrderItem.java create mode 100644 src/main/generated/project/trendpick_pro/domain/orders/entity/dto/response/QOrderResponse.java create mode 100644 src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductListResponse.java create mode 100644 src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java create mode 100644 src/main/java/project/trendpick_pro/domain/common/base/security/SecurityConfig.java create mode 100644 src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java delete mode 100644 src/main/java/project/trendpick_pro/domain/member/controller/MemberrController.java rename src/main/java/project/trendpick_pro/domain/member/repository/{UserRepository.java => MemberRepository.java} (53%) create mode 100644 src/main/java/project/trendpick_pro/domain/member/service/MemberService.java delete mode 100644 src/main/java/project/trendpick_pro/domain/member/service/UserService.java create mode 100644 src/main/resources/templates/trendpick/usr/layout/layout.html create mode 100644 src/main/resources/templates/trendpick/usr/member/join.html create mode 100644 src/main/resources/templates/trendpick/usr/member/login.html diff --git a/src/main/generated/project/trendpick_pro/domain/brand/entity/QBrand.java b/src/main/generated/project/trendpick_pro/domain/brand/entity/QBrand.java new file mode 100644 index 00000000..1dde8ecc --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/brand/entity/QBrand.java @@ -0,0 +1,39 @@ +package project.trendpick_pro.domain.brand.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; + + +/** + * QBrand is a Querydsl query type for Brand + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QBrand extends EntityPathBase { + + private static final long serialVersionUID = -1703904522L; + + public static final QBrand brand = new QBrand("brand"); + + public final NumberPath id = createNumber("id", Long.class); + + public final StringPath name = createString("name"); + + public QBrand(String variable) { + super(Brand.class, forVariable(variable)); + } + + public QBrand(Path path) { + super(path.getType(), path.getMetadata()); + } + + public QBrand(PathMetadata metadata) { + super(Brand.class, metadata); + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java b/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java index 70e24c79..cd1cbe01 100644 --- a/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java +++ b/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java @@ -34,7 +34,7 @@ public class QDelivery extends EntityPathBase { //inherited public final DateTimePath modifiedDate = _super.modifiedDate; - public final project.trendpick_pro.domain.orders.entity.QOrders order; + public final project.trendpick_pro.domain.orders.entity.QOrder order; public final EnumPath state = createEnum("state", DeliveryState.class); @@ -56,7 +56,7 @@ public QDelivery(PathMetadata metadata, PathInits inits) { public QDelivery(Class type, PathMetadata metadata, PathInits inits) { super(type, metadata, inits); - this.order = inits.isInitialized("order") ? new project.trendpick_pro.domain.orders.entity.QOrders(forProperty("order"), inits.get("order")) : null; + this.order = inits.isInitialized("order") ? new project.trendpick_pro.domain.orders.entity.QOrder(forProperty("order"), inits.get("order")) : null; } } diff --git a/src/main/generated/project/trendpick_pro/domain/member/entity/QMember.java b/src/main/generated/project/trendpick_pro/domain/member/entity/QMember.java new file mode 100644 index 00000000..836d8fb9 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/member/entity/QMember.java @@ -0,0 +1,55 @@ +package project.trendpick_pro.domain.member.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; + + +/** + * QMember is a Querydsl query type for Member + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QMember extends EntityPathBase { + + private static final long serialVersionUID = 1765768292L; + + public static final QMember member = new QMember("member1"); + + public final NumberPath account = createNumber("account", Long.class); + + public final StringPath bank_name = createString("bank_name"); + + public final DateTimePath birth = createDateTime("birth", java.util.Date.class); + + public final StringPath email = createString("email"); + + public final NumberPath id = createNumber("id", Long.class); + + public final StringPath password = createString("password"); + + public final StringPath phone_num = createString("phone_num"); + + public final EnumPath role = createEnum("role", RoleType.class); + + public final NumberPath tag_id = createNumber("tag_id", Long.class); + + public final StringPath username = createString("username"); + + public QMember(String variable) { + super(Member.class, forVariable(variable)); + } + + public QMember(Path path) { + super(path.getType(), path.getMetadata()); + } + + public QMember(PathMetadata metadata) { + super(Member.class, metadata); + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/notification/entity/QNotification.java b/src/main/generated/project/trendpick_pro/domain/notification/entity/QNotification.java new file mode 100644 index 00000000..56e465f2 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/notification/entity/QNotification.java @@ -0,0 +1,43 @@ +package project.trendpick_pro.domain.notification.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; + + +/** + * QNotification is a Querydsl query type for Notification + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QNotification extends EntityPathBase { + + private static final long serialVersionUID = 483531974L; + + public static final QNotification notification = new QNotification("notification"); + + public final StringPath content = createString("content"); + + public final DateTimePath creatDate = createDateTime("creatDate", java.time.LocalDateTime.class); + + public final NumberPath id = createNumber("id", Long.class); + + public final StringPath title = createString("title"); + + public QNotification(String variable) { + super(Notification.class, forVariable(variable)); + } + + public QNotification(Path path) { + super(path.getType(), path.getMetadata()); + } + + public QNotification(PathMetadata metadata) { + super(Notification.class, metadata); + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrder.java b/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrder.java new file mode 100644 index 00000000..faf466dd --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrder.java @@ -0,0 +1,68 @@ +package project.trendpick_pro.domain.orders.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; + + +/** + * QOrder is a Querydsl query type for Order + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QOrder extends EntityPathBase { + + private static final long serialVersionUID = 1734766041L; + + private static final PathInits INITS = PathInits.DIRECT2; + + public static final QOrder order = new QOrder("order1"); + + public final project.trendpick_pro.domain.common.base.QBaseTimeEntity _super = new project.trendpick_pro.domain.common.base.QBaseTimeEntity(this); + + //inherited + public final DateTimePath createdDate = _super.createdDate; + + public final project.trendpick_pro.domain.delivery.entity.QDelivery delivery; + + public final NumberPath id = createNumber("id", Long.class); + + public final project.trendpick_pro.domain.member.entity.QMember member; + + //inherited + public final DateTimePath modifiedDate = _super.modifiedDate; + + public final ListPath orderItems = this.createList("orderItems", OrderItem.class, QOrderItem.class, PathInits.DIRECT2); + + public final EnumPath status = createEnum("status", OrderStatus.class); + + public final NumberPath totalPrice = createNumber("totalPrice", Integer.class); + + public QOrder(String variable) { + this(Order.class, forVariable(variable), INITS); + } + + public QOrder(Path path) { + this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); + } + + public QOrder(PathMetadata metadata) { + this(metadata, PathInits.getFor(metadata, INITS)); + } + + public QOrder(PathMetadata metadata, PathInits inits) { + this(Order.class, metadata, inits); + } + + public QOrder(Class type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + this.delivery = inits.isInitialized("delivery") ? new project.trendpick_pro.domain.delivery.entity.QDelivery(forProperty("delivery"), inits.get("delivery")) : null; + this.member = inits.isInitialized("member") ? new project.trendpick_pro.domain.member.entity.QMember(forProperty("member")) : null; + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrderItem.java b/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrderItem.java new file mode 100644 index 00000000..50722e65 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrderItem.java @@ -0,0 +1,58 @@ +package project.trendpick_pro.domain.orders.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; + + +/** + * QOrderItem is a Querydsl query type for OrderItem + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QOrderItem extends EntityPathBase { + + private static final long serialVersionUID = 1350355084L; + + private static final PathInits INITS = PathInits.DIRECT2; + + public static final QOrderItem orderItem = new QOrderItem("orderItem"); + + public final NumberPath count = createNumber("count", Integer.class); + + public final NumberPath id = createNumber("id", Long.class); + + public final QOrder order; + + public final NumberPath orderPrice = createNumber("orderPrice", Integer.class); + + public final project.trendpick_pro.domain.product.entity.QProduct product; + + public QOrderItem(String variable) { + this(OrderItem.class, forVariable(variable), INITS); + } + + public QOrderItem(Path path) { + this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); + } + + public QOrderItem(PathMetadata metadata) { + this(metadata, PathInits.getFor(metadata, INITS)); + } + + public QOrderItem(PathMetadata metadata, PathInits inits) { + this(OrderItem.class, metadata, inits); + } + + public QOrderItem(Class type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + this.order = inits.isInitialized("order") ? new QOrder(forProperty("order"), inits.get("order")) : null; + this.product = inits.isInitialized("product") ? new project.trendpick_pro.domain.product.entity.QProduct(forProperty("product"), inits.get("product")) : null; + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/orders/entity/dto/response/QOrderResponse.java b/src/main/generated/project/trendpick_pro/domain/orders/entity/dto/response/QOrderResponse.java new file mode 100644 index 00000000..499b41b5 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/orders/entity/dto/response/QOrderResponse.java @@ -0,0 +1,21 @@ +package project.trendpick_pro.domain.orders.entity.dto.response; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.ConstructorExpression; +import javax.annotation.processing.Generated; + +/** + * project.trendpick_pro.domain.orders.entity.dto.response.QOrderResponse is a Querydsl Projection type for OrderResponse + */ +@Generated("com.querydsl.codegen.DefaultProjectionSerializer") +public class QOrderResponse extends ConstructorExpression { + + private static final long serialVersionUID = 695514566L; + + public QOrderResponse(com.querydsl.core.types.Expression orderId, com.querydsl.core.types.Expression brandName, com.querydsl.core.types.Expression productName, com.querydsl.core.types.Expression order_date, com.querydsl.core.types.Expression totalPrice, com.querydsl.core.types.Expression deliveryStatus) { + super(OrderResponse.class, new Class[]{long.class, String.class, String.class, java.time.LocalDateTime.class, int.class, String.class}, orderId, brandName, productName, order_date, totalPrice, deliveryStatus); + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductListResponse.java b/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductListResponse.java new file mode 100644 index 00000000..fc126ba1 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductListResponse.java @@ -0,0 +1,21 @@ +package project.trendpick_pro.domain.product.entity.dto.response; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.ConstructorExpression; +import javax.annotation.processing.Generated; + +/** + * project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse is a Querydsl Projection type for ProductListResponse + */ +@Generated("com.querydsl.codegen.DefaultProjectionSerializer") +public class QProductListResponse extends ConstructorExpression { + + private static final long serialVersionUID = -1483401431L; + + public QProductListResponse(com.querydsl.core.types.Expression id, com.querydsl.core.types.Expression name, com.querydsl.core.types.Expression brand, com.querydsl.core.types.Expression mainFile, com.querydsl.core.types.Expression price) { + super(ProductListResponse.class, new Class[]{long.class, String.class, String.class, project.trendpick_pro.domain.common.file.CommonFile.class, int.class}, id, name, brand, mainFile, price); + } + +} + diff --git a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java new file mode 100644 index 00000000..76dfbb33 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java @@ -0,0 +1,65 @@ +package project.trendpick_pro.domain.common.base.rq; + + +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jakarta.servlet.http.HttpSession; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.User; +import org.springframework.stereotype.Component; +import org.springframework.web.context.annotation.RequestScope; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.service.MemberService; + +import java.util.Date; + +@Component +@RequestScope //매 요청마다 생성됨 +public class Rq { + private final MemberService memberService; + private final HttpServletRequest req; + private final HttpServletResponse resp; + private final HttpSession session; + private final User user; + private Member member = null; // 레이지 로딩, 처음부터 넣지 않고, 요청이 들어올 때 넣는다. + + public Rq(MemberService memberService, HttpServletRequest req, HttpServletResponse resp, HttpSession session) { + this.memberService = memberService; + this.req = req; + this.resp = resp; + this.session = session; + + // 현재 로그인한 회원의 인증정보를 가져옴 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + if (authentication.getPrincipal() instanceof User) { + this.user = (User) authentication.getPrincipal(); + } else { + this.user = null; + } + } + + // 로그인 되어 있는지 체크 + public boolean isLogin() { + return user != null; + } + + // 로그아웃 되어 있는지 체크 + public boolean isLogout() { + return !isLogin(); + } + + // 로그인 된 회원의 객체 + public Member getMember() { + if (isLogout()) return null; + + // 데이터가 없는지 체크 + if (member == null) { + member = memberService.findByUsername(user.getUsername()).orElseThrow(); + } + + return member; + } + +} diff --git a/src/main/java/project/trendpick_pro/domain/common/base/security/SecurityConfig.java b/src/main/java/project/trendpick_pro/domain/common/base/security/SecurityConfig.java new file mode 100644 index 00000000..e2ee22ff --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/common/base/security/SecurityConfig.java @@ -0,0 +1,31 @@ +package project.trendpick_pro.domain.common.base.security; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; + +@Configuration +public class SecurityConfig { + @Bean + SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http + .formLogin( + formLogin -> formLogin + .loginPage("/member/login") + ) + .logout( + logout -> logout + .logoutUrl("/member/logout") + ); + + return http.build(); + } + + @Bean + PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java new file mode 100644 index 00000000..b19bf212 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java @@ -0,0 +1,60 @@ +package project.trendpick_pro.domain.member.controller; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.Size; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import project.trendpick_pro.domain.common.base.rq.Rq; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.service.MemberService; + +@Controller +@RequestMapping("/member") +@RequiredArgsConstructor +public class MemberController { + private final MemberService memberService; + + @PreAuthorize("isAnonymous()") + @GetMapping("/join") + public String showJoin() { + return "usr/member/join"; + } + + @AllArgsConstructor + @Getter + public static class JoinForm { + @NotBlank + @Size(min = 4, max = 30) + private final String username; + @NotBlank + @Size(min = 4, max = 30) + private final String password; + } + + @PreAuthorize("isAnonymous()") + @PostMapping("/join") + public String join(@Valid JoinForm joinForm) { + memberService.join(joinForm.getUsername(), joinForm.getPassword()); + + return "회원가입이 완료되었습니다"; + } + + @PreAuthorize("isAnonymous()") + @GetMapping("/login") + public String showLogin() { + return "usr/member/login"; + } + + @PreAuthorize("isAuthenticated()") + @GetMapping("/me") + public String showMe() { + return "usr/member/me"; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/MemberrController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberrController.java deleted file mode 100644 index d04f0ed7..00000000 --- a/src/main/java/project/trendpick_pro/domain/member/controller/MemberrController.java +++ /dev/null @@ -1,4 +0,0 @@ -package project.trendpick_pro.domain.member.controller; - -public class MemberrController { -} diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index 6495555c..efb30842 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -22,7 +22,7 @@ public class Member { private String password; - private String name; + private String username; private String phone_num; diff --git a/src/main/java/project/trendpick_pro/domain/member/repository/UserRepository.java b/src/main/java/project/trendpick_pro/domain/member/repository/MemberRepository.java similarity index 53% rename from src/main/java/project/trendpick_pro/domain/member/repository/UserRepository.java rename to src/main/java/project/trendpick_pro/domain/member/repository/MemberRepository.java index 95c01c7d..ba0e2f44 100644 --- a/src/main/java/project/trendpick_pro/domain/member/repository/UserRepository.java +++ b/src/main/java/project/trendpick_pro/domain/member/repository/MemberRepository.java @@ -3,5 +3,8 @@ import org.springframework.data.jpa.repository.JpaRepository; import project.trendpick_pro.domain.member.entity.Member; -public interface UserRepository extends JpaRepository { -} +import java.util.Optional; + +public interface MemberRepository extends JpaRepository { + Optional findByUsername(String username); +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java new file mode 100644 index 00000000..725c1bc1 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -0,0 +1,34 @@ +package project.trendpick_pro.domain.member.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.repository.MemberRepository; + +import java.util.Optional; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class MemberService { + private final PasswordEncoder passwordEncoder; + + private final MemberRepository memberRepository; + + public Optional findByUsername(String username) { + return memberRepository.findByUsername(username); + } + + @Transactional + public Member join(String username, String password) { + Member member = Member + .builder() + .username(username) + .password(passwordEncoder.encode(password)) + .build(); + + return memberRepository.save(member); + } +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/member/service/UserService.java b/src/main/java/project/trendpick_pro/domain/member/service/UserService.java deleted file mode 100644 index 394a4935..00000000 --- a/src/main/java/project/trendpick_pro/domain/member/service/UserService.java +++ /dev/null @@ -1,4 +0,0 @@ -package project.trendpick_pro.domain.member.service; - -public class UserService { -} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e97315d9..f4e69960 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -6,15 +6,15 @@ spring: matching-strategy: ant_path_matcher datasource: # H2 - driver-class-name: org.h2.Driver - url: jdbc:h2:tcp://localhost/~/db/TrendPick - username: sa - password: +# driver-class-name: org.h2.Driver +# url: jdbc:h2:tcp://localhost/~/db/TrendPick +# username: sa +# password: # mariaDB -# driver-class-name: org.mariadb.jdbc.Driver -# url: jdbc:mariadb://127.0.0.1:${maria.port}/TrendPick__dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul -# username: ${maria.username} -# password: ${maria.password} + driver-class-name: org.mariadb.jdbc.Driver + url: jdbc:mariadb://127.0.0.1:${maria.port}/TrendPick__dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul + username: ${maria.username} + password: ${maria.password} jpa: hibernate: ddl-auto: create diff --git a/src/main/resources/templates/trendpick/usr/layout/layout.html b/src/main/resources/templates/trendpick/usr/layout/layout.html new file mode 100644 index 00000000..c1afbd7d --- /dev/null +++ b/src/main/resources/templates/trendpick/usr/layout/layout.html @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/member/join.html b/src/main/resources/templates/trendpick/usr/member/join.html new file mode 100644 index 00000000..d9600373 --- /dev/null +++ b/src/main/resources/templates/trendpick/usr/member/join.html @@ -0,0 +1,63 @@ + + + + 회원가입 + + + + +
+ + +
+
+ +
+
+ +
+
+ +
+
+
+ + + + diff --git a/src/main/resources/templates/trendpick/usr/member/login.html b/src/main/resources/templates/trendpick/usr/member/login.html new file mode 100644 index 00000000..d2bc4f11 --- /dev/null +++ b/src/main/resources/templates/trendpick/usr/member/login.html @@ -0,0 +1,62 @@ + + + + 로그인 + + + + +
+ + +
+
+ +
+
+ +
+
+ +
+
+
+ + + \ No newline at end of file From 732b3f1888a08746b068ec7bf03d0a0e139956fd Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 28 May 2023 22:38:32 +0900 Subject: [PATCH 039/367] =?UTF-8?q?refactor:=20Delivery=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=EC=9E=90=20=EB=8F=84=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/brand/entity/QBrand.java | 39 +++++++++++++ .../domain/cart/entity/QCart.java | 43 ++++++++++++++ .../domain/delivery/entity/QDelivery.java | 7 ++- .../delivery/entity/embaded/QAddress.java | 41 +++++++++++++ .../notification/entity/QNotification.java | 43 ++++++++++++++ .../entity/{QOrders.java => QOrder.java} | 29 +++++----- .../domain/orders/entity/QOrderItem.java | 58 +++++++++++++++++++ .../entity/dto/response/QOrderResponse.java | 21 +++++++ .../dto/response/QProductListResponse.java | 21 +++++++ .../dto/response/QProductWithIdResponse.java | 21 ------- .../domain/delivery/entity/Delivery.java | 10 +++- .../delivery/entity/embaded/Address.java | 24 ++++++++ .../orders/contoller/OrderController.java | 10 ++-- .../orders/repository/OrderRepository.java | 4 ++ .../domain/orders/service/OrderService.java | 15 +++-- 15 files changed, 340 insertions(+), 46 deletions(-) create mode 100644 src/main/generated/project/trendpick_pro/domain/brand/entity/QBrand.java create mode 100644 src/main/generated/project/trendpick_pro/domain/cart/entity/QCart.java create mode 100644 src/main/generated/project/trendpick_pro/domain/delivery/entity/embaded/QAddress.java create mode 100644 src/main/generated/project/trendpick_pro/domain/notification/entity/QNotification.java rename src/main/generated/project/trendpick_pro/domain/orders/entity/{QOrders.java => QOrder.java} (59%) create mode 100644 src/main/generated/project/trendpick_pro/domain/orders/entity/QOrderItem.java create mode 100644 src/main/generated/project/trendpick_pro/domain/orders/entity/dto/response/QOrderResponse.java create mode 100644 src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductListResponse.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductWithIdResponse.java create mode 100644 src/main/java/project/trendpick_pro/domain/delivery/entity/embaded/Address.java diff --git a/src/main/generated/project/trendpick_pro/domain/brand/entity/QBrand.java b/src/main/generated/project/trendpick_pro/domain/brand/entity/QBrand.java new file mode 100644 index 00000000..1dde8ecc --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/brand/entity/QBrand.java @@ -0,0 +1,39 @@ +package project.trendpick_pro.domain.brand.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; + + +/** + * QBrand is a Querydsl query type for Brand + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QBrand extends EntityPathBase { + + private static final long serialVersionUID = -1703904522L; + + public static final QBrand brand = new QBrand("brand"); + + public final NumberPath id = createNumber("id", Long.class); + + public final StringPath name = createString("name"); + + public QBrand(String variable) { + super(Brand.class, forVariable(variable)); + } + + public QBrand(Path path) { + super(path.getType(), path.getMetadata()); + } + + public QBrand(PathMetadata metadata) { + super(Brand.class, metadata); + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/cart/entity/QCart.java b/src/main/generated/project/trendpick_pro/domain/cart/entity/QCart.java new file mode 100644 index 00000000..43b1b8a3 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/cart/entity/QCart.java @@ -0,0 +1,43 @@ +package project.trendpick_pro.domain.cart.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; + + +/** + * QCart is a Querydsl query type for Cart + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QCart extends EntityPathBase { + + private static final long serialVersionUID = 1014572976L; + + public static final QCart cart = new QCart("cart"); + + public final NumberPath id = createNumber("id", Long.class); + + public final NumberPath totalCount = createNumber("totalCount", Integer.class); + + public final NumberPath totalPrice = createNumber("totalPrice", Integer.class); + + public final StringPath user_id = createString("user_id"); + + public QCart(String variable) { + super(Cart.class, forVariable(variable)); + } + + public QCart(Path path) { + super(path.getType(), path.getMetadata()); + } + + public QCart(PathMetadata metadata) { + super(Cart.class, metadata); + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java b/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java index 70e24c79..fa37ed14 100644 --- a/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java +++ b/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java @@ -24,7 +24,7 @@ public class QDelivery extends EntityPathBase { public final project.trendpick_pro.domain.common.base.QBaseTimeEntity _super = new project.trendpick_pro.domain.common.base.QBaseTimeEntity(this); - public final StringPath address = createString("address"); + public final project.trendpick_pro.domain.delivery.entity.embaded.QAddress address; //inherited public final DateTimePath createdDate = _super.createdDate; @@ -34,7 +34,7 @@ public class QDelivery extends EntityPathBase { //inherited public final DateTimePath modifiedDate = _super.modifiedDate; - public final project.trendpick_pro.domain.orders.entity.QOrders order; + public final project.trendpick_pro.domain.orders.entity.QOrder order; public final EnumPath state = createEnum("state", DeliveryState.class); @@ -56,7 +56,8 @@ public QDelivery(PathMetadata metadata, PathInits inits) { public QDelivery(Class type, PathMetadata metadata, PathInits inits) { super(type, metadata, inits); - this.order = inits.isInitialized("order") ? new project.trendpick_pro.domain.orders.entity.QOrders(forProperty("order"), inits.get("order")) : null; + this.address = inits.isInitialized("address") ? new project.trendpick_pro.domain.delivery.entity.embaded.QAddress(forProperty("address")) : null; + this.order = inits.isInitialized("order") ? new project.trendpick_pro.domain.orders.entity.QOrder(forProperty("order"), inits.get("order")) : null; } } diff --git a/src/main/generated/project/trendpick_pro/domain/delivery/entity/embaded/QAddress.java b/src/main/generated/project/trendpick_pro/domain/delivery/entity/embaded/QAddress.java new file mode 100644 index 00000000..f68fa269 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/delivery/entity/embaded/QAddress.java @@ -0,0 +1,41 @@ +package project.trendpick_pro.domain.delivery.entity.embaded; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; + + +/** + * QAddress is a Querydsl query type for Address + */ +@Generated("com.querydsl.codegen.DefaultEmbeddableSerializer") +public class QAddress extends BeanPath
{ + + private static final long serialVersionUID = -588872866L; + + public static final QAddress address = new QAddress("address"); + + public final StringPath city = createString("city"); + + public final StringPath street = createString("street"); + + public final StringPath zipcode = createString("zipcode"); + + public QAddress(String variable) { + super(Address.class, forVariable(variable)); + } + + public QAddress(Path path) { + super(path.getType(), path.getMetadata()); + } + + public QAddress(PathMetadata metadata) { + super(Address.class, metadata); + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/notification/entity/QNotification.java b/src/main/generated/project/trendpick_pro/domain/notification/entity/QNotification.java new file mode 100644 index 00000000..56e465f2 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/notification/entity/QNotification.java @@ -0,0 +1,43 @@ +package project.trendpick_pro.domain.notification.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; + + +/** + * QNotification is a Querydsl query type for Notification + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QNotification extends EntityPathBase { + + private static final long serialVersionUID = 483531974L; + + public static final QNotification notification = new QNotification("notification"); + + public final StringPath content = createString("content"); + + public final DateTimePath creatDate = createDateTime("creatDate", java.time.LocalDateTime.class); + + public final NumberPath id = createNumber("id", Long.class); + + public final StringPath title = createString("title"); + + public QNotification(String variable) { + super(Notification.class, forVariable(variable)); + } + + public QNotification(Path path) { + super(path.getType(), path.getMetadata()); + } + + public QNotification(PathMetadata metadata) { + super(Notification.class, metadata); + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrders.java b/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrder.java similarity index 59% rename from src/main/generated/project/trendpick_pro/domain/orders/entity/QOrders.java rename to src/main/generated/project/trendpick_pro/domain/orders/entity/QOrder.java index f0f579e1..dead6577 100644 --- a/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrders.java +++ b/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrder.java @@ -11,16 +11,16 @@ /** - * QOrders is a Querydsl query type for Orders + * QOrder is a Querydsl query type for Order */ @Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QOrders extends EntityPathBase { +public class QOrder extends EntityPathBase { - private static final long serialVersionUID = -2056827462L; + private static final long serialVersionUID = 1734766041L; private static final PathInits INITS = PathInits.DIRECT2; - public static final QOrders orders = new QOrders("orders"); + public static final QOrder order = new QOrder("order1"); public final project.trendpick_pro.domain.common.base.QBaseTimeEntity _super = new project.trendpick_pro.domain.common.base.QBaseTimeEntity(this); @@ -34,31 +34,34 @@ public class QOrders extends EntityPathBase { //inherited public final DateTimePath modifiedDate = _super.modifiedDate; - public final StringPath status = createString("status"); + public final ListPath orderItems = this.createList("orderItems", OrderItem.class, QOrderItem.class, PathInits.DIRECT2); + + public final EnumPath status = createEnum("status", OrderStatus.class); public final NumberPath totalPrice = createNumber("totalPrice", Integer.class); - public final StringPath user = createString("user"); + public final project.trendpick_pro.domain.user.entity.QUser user; - public QOrders(String variable) { - this(Orders.class, forVariable(variable), INITS); + public QOrder(String variable) { + this(Order.class, forVariable(variable), INITS); } - public QOrders(Path path) { + public QOrder(Path path) { this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); } - public QOrders(PathMetadata metadata) { + public QOrder(PathMetadata metadata) { this(metadata, PathInits.getFor(metadata, INITS)); } - public QOrders(PathMetadata metadata, PathInits inits) { - this(Orders.class, metadata, inits); + public QOrder(PathMetadata metadata, PathInits inits) { + this(Order.class, metadata, inits); } - public QOrders(Class type, PathMetadata metadata, PathInits inits) { + public QOrder(Class type, PathMetadata metadata, PathInits inits) { super(type, metadata, inits); this.delivery = inits.isInitialized("delivery") ? new project.trendpick_pro.domain.delivery.entity.QDelivery(forProperty("delivery"), inits.get("delivery")) : null; + this.user = inits.isInitialized("user") ? new project.trendpick_pro.domain.user.entity.QUser(forProperty("user")) : null; } } diff --git a/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrderItem.java b/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrderItem.java new file mode 100644 index 00000000..50722e65 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrderItem.java @@ -0,0 +1,58 @@ +package project.trendpick_pro.domain.orders.entity; + +import static com.querydsl.core.types.PathMetadataFactory.*; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.PathMetadata; +import javax.annotation.processing.Generated; +import com.querydsl.core.types.Path; +import com.querydsl.core.types.dsl.PathInits; + + +/** + * QOrderItem is a Querydsl query type for OrderItem + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QOrderItem extends EntityPathBase { + + private static final long serialVersionUID = 1350355084L; + + private static final PathInits INITS = PathInits.DIRECT2; + + public static final QOrderItem orderItem = new QOrderItem("orderItem"); + + public final NumberPath count = createNumber("count", Integer.class); + + public final NumberPath id = createNumber("id", Long.class); + + public final QOrder order; + + public final NumberPath orderPrice = createNumber("orderPrice", Integer.class); + + public final project.trendpick_pro.domain.product.entity.QProduct product; + + public QOrderItem(String variable) { + this(OrderItem.class, forVariable(variable), INITS); + } + + public QOrderItem(Path path) { + this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); + } + + public QOrderItem(PathMetadata metadata) { + this(metadata, PathInits.getFor(metadata, INITS)); + } + + public QOrderItem(PathMetadata metadata, PathInits inits) { + this(OrderItem.class, metadata, inits); + } + + public QOrderItem(Class type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + this.order = inits.isInitialized("order") ? new QOrder(forProperty("order"), inits.get("order")) : null; + this.product = inits.isInitialized("product") ? new project.trendpick_pro.domain.product.entity.QProduct(forProperty("product"), inits.get("product")) : null; + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/orders/entity/dto/response/QOrderResponse.java b/src/main/generated/project/trendpick_pro/domain/orders/entity/dto/response/QOrderResponse.java new file mode 100644 index 00000000..499b41b5 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/orders/entity/dto/response/QOrderResponse.java @@ -0,0 +1,21 @@ +package project.trendpick_pro.domain.orders.entity.dto.response; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.ConstructorExpression; +import javax.annotation.processing.Generated; + +/** + * project.trendpick_pro.domain.orders.entity.dto.response.QOrderResponse is a Querydsl Projection type for OrderResponse + */ +@Generated("com.querydsl.codegen.DefaultProjectionSerializer") +public class QOrderResponse extends ConstructorExpression { + + private static final long serialVersionUID = 695514566L; + + public QOrderResponse(com.querydsl.core.types.Expression orderId, com.querydsl.core.types.Expression brandName, com.querydsl.core.types.Expression productName, com.querydsl.core.types.Expression order_date, com.querydsl.core.types.Expression totalPrice, com.querydsl.core.types.Expression deliveryStatus) { + super(OrderResponse.class, new Class[]{long.class, String.class, String.class, java.time.LocalDateTime.class, int.class, String.class}, orderId, brandName, productName, order_date, totalPrice, deliveryStatus); + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductListResponse.java b/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductListResponse.java new file mode 100644 index 00000000..fc126ba1 --- /dev/null +++ b/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductListResponse.java @@ -0,0 +1,21 @@ +package project.trendpick_pro.domain.product.entity.dto.response; + +import com.querydsl.core.types.dsl.*; + +import com.querydsl.core.types.ConstructorExpression; +import javax.annotation.processing.Generated; + +/** + * project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse is a Querydsl Projection type for ProductListResponse + */ +@Generated("com.querydsl.codegen.DefaultProjectionSerializer") +public class QProductListResponse extends ConstructorExpression { + + private static final long serialVersionUID = -1483401431L; + + public QProductListResponse(com.querydsl.core.types.Expression id, com.querydsl.core.types.Expression name, com.querydsl.core.types.Expression brand, com.querydsl.core.types.Expression mainFile, com.querydsl.core.types.Expression price) { + super(ProductListResponse.class, new Class[]{long.class, String.class, String.class, project.trendpick_pro.domain.common.file.CommonFile.class, int.class}, id, name, brand, mainFile, price); + } + +} + diff --git a/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductWithIdResponse.java b/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductWithIdResponse.java deleted file mode 100644 index 27a77434..00000000 --- a/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductWithIdResponse.java +++ /dev/null @@ -1,21 +0,0 @@ -package project.trendpick_pro.domain.product.entity.dto.response; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.ConstructorExpression; -import javax.annotation.processing.Generated; - -/** - * project.trendpick_pro.domain.product.entity.dto.response.QProductWithIdResponse is a Querydsl Projection type for ProductWithIdResponse - */ -@Generated("com.querydsl.codegen.DefaultProjectionSerializer") -public class QProductWithIdResponse extends ConstructorExpression { - - private static final long serialVersionUID = 173412748L; - - public QProductWithIdResponse(com.querydsl.core.types.Expression id, com.querydsl.core.types.Expression name, com.querydsl.core.types.Expression brand, com.querydsl.core.types.Expression mainFile, com.querydsl.core.types.Expression price) { - super(ProductWithIdResponse.class, new Class[]{long.class, String.class, String.class, project.trendpick_pro.domain.common.file.CommonFile.class, int.class}, id, name, brand, mainFile, price); - } - -} - diff --git a/src/main/java/project/trendpick_pro/domain/delivery/entity/Delivery.java b/src/main/java/project/trendpick_pro/domain/delivery/entity/Delivery.java index a096f22a..fd2b4f2d 100644 --- a/src/main/java/project/trendpick_pro/domain/delivery/entity/Delivery.java +++ b/src/main/java/project/trendpick_pro/domain/delivery/entity/Delivery.java @@ -5,6 +5,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import project.trendpick_pro.domain.common.base.BaseTimeEntity; +import project.trendpick_pro.domain.delivery.entity.embaded.Address; import project.trendpick_pro.domain.orders.entity.Order; @Entity @@ -18,7 +19,14 @@ public class Delivery extends BaseTimeEntity { @OneToOne(mappedBy = "delivery", fetch = FetchType.LAZY) private Order order; - private String address; + @Embedded + private Address address; @Enumerated(EnumType.STRING) private DeliveryState state; + + public Delivery(Address address){ + this.address = address; + state = DeliveryState.READY; //주문과 함께 생성시 초기에는 준비중. + } + } diff --git a/src/main/java/project/trendpick_pro/domain/delivery/entity/embaded/Address.java b/src/main/java/project/trendpick_pro/domain/delivery/entity/embaded/Address.java new file mode 100644 index 00000000..4118d691 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/delivery/entity/embaded/Address.java @@ -0,0 +1,24 @@ +package project.trendpick_pro.domain.delivery.entity.embaded; + +import jakarta.persistence.Embeddable; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Embeddable +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Address { + private String city; + private String street; + private String zipcode; + private Address(String city, String street, String zipcode) { + this.city = city; + this.street = street; + this.zipcode = zipcode; + } + + public static Address of(String city, String street, String zipcode){ + return new Address(city, street, zipcode); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index bc32105b..2d827cbc 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -7,11 +7,12 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; +import project.trendpick_pro.domain.orders.entity.Order; import project.trendpick_pro.domain.orders.entity.dto.request.OrderSaveRequest; +import project.trendpick_pro.domain.orders.entity.dto.request.OrderSearchCond; import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; import project.trendpick_pro.domain.orders.service.OrderService; -import java.util.List; @Slf4j @Controller @@ -22,15 +23,16 @@ public class OrderController { private final OrderService orderService; @PostMapping("/order") - public String order(@Valid OrderSaveRequest... orderSaveRequests){ + public String order(@Valid OrderSaveRequest... orderSaveRequests) throws IllegalAccessException { orderService.order(1L, orderSaveRequests); return "redirect:/orders"; } @GetMapping("/orders") - public String orderList(Model model) { - Page responses = orderService.findAll(1L); + public String orderList(Model model, @Valid OrderSearchCond orderSearchCond) { + Page responses = orderService.findAll(orderSearchCond); + model.addAttribute("orders", responses); return "order/orderList"; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java index 3342901a..1b76547a 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java @@ -1,7 +1,11 @@ package project.trendpick_pro.domain.orders.repository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import project.trendpick_pro.domain.orders.entity.Order; +import project.trendpick_pro.domain.user.entity.User; public interface OrderRepository extends JpaRepository { + Page findAllByUser(User member, Pageable pageable); } diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 36ffdd62..20887b32 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -4,9 +4,11 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.delivery.entity.Delivery; +import project.trendpick_pro.domain.delivery.entity.embaded.Address; import project.trendpick_pro.domain.orders.entity.Order; import project.trendpick_pro.domain.orders.entity.OrderItem; import project.trendpick_pro.domain.orders.entity.OrderStatus; @@ -37,12 +39,12 @@ public void order(Long userId, OrderSaveRequest... orderSaveRequests) throws Ill User user = userRepository.findById(userId).orElseThrow(() -> new EntityNotFoundException("존재하지 않는 유저 입니다."));// 임시 exception 설정 나중에 할 수도 있고 아닐수도 - Delivery delivery = new Delivery(); + Delivery delivery = new Delivery(Address.of("서울시", "강남대로", "222")); // 임의로 작성 List orderItemList = new ArrayList<>(); for (OrderSaveRequest request: orderSaveRequests) { Product product = productRepository.findById(request.getProductId()).orElseThrow(() -> new EntityNotFoundException("product is not found")); - if (product.getStock() < 0) { + if (product.getStock() < request.getQuantity()) { throw new RuntimeException("stock is not enough"); // 임시. 나중에 사용자 exception 널을까말까 생각 } orderItemList.add(new OrderItem(product, product.getPrice(), request.getQuantity())); @@ -58,8 +60,13 @@ public void cancel(Long orderId) { order.cancel(); } - public Page findAll(OrderSearchCond cond) { - return orderRepository.findAll(cond.getUserId()); + //임시 작성 + public Page findAll(OrderSearchCond cond) { + User user = userRepository.findById(cond.getUserId()).orElseThrow(); + + Page orderPage = orderRepository.findAllByUser(user, PageRequest.of(0, 10)); + + return orderPage; } From 78b90048bde3233bff71dfd2a0aa8a01c2ef17f4 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 28 May 2023 23:43:46 +0900 Subject: [PATCH 040/367] =?UTF-8?q?feat:=20=EC=B9=B4=ED=85=8C=EA=B3=A0?= =?UTF-8?q?=EB=A6=AC=20=EA=B8=B0=EB=B3=B8=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20(#36)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/category/entity/MainCategory.java | 23 ++++++++++++++++ .../domain/category/entity/SubCategory.java | 27 +++++++++++++++++++ .../repository/MainCategoryRepository.java | 8 ++++++ .../repository/SubCategoryRepository.java | 8 ++++++ 4 files changed, 66 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/category/entity/MainCategory.java create mode 100644 src/main/java/project/trendpick_pro/domain/category/entity/SubCategory.java create mode 100644 src/main/java/project/trendpick_pro/domain/category/repository/MainCategoryRepository.java create mode 100644 src/main/java/project/trendpick_pro/domain/category/repository/SubCategoryRepository.java diff --git a/src/main/java/project/trendpick_pro/domain/category/entity/MainCategory.java b/src/main/java/project/trendpick_pro/domain/category/entity/MainCategory.java new file mode 100644 index 00000000..61d0a400 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/category/entity/MainCategory.java @@ -0,0 +1,23 @@ +package project.trendpick_pro.domain.category.entity; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class MainCategory { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "name", nullable = false, unique = true) + private String name; + + public MainCategory(String name) { + this.name = name; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/category/entity/SubCategory.java b/src/main/java/project/trendpick_pro/domain/category/entity/SubCategory.java new file mode 100644 index 00000000..4af81ed4 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/category/entity/SubCategory.java @@ -0,0 +1,27 @@ +package project.trendpick_pro.domain.category.entity; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class SubCategory { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "name", nullable = false, unique = true) + private String name; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "category_id") + private MainCategory mainCategory; + + public SubCategory(String name, MainCategory mainCategory) { + this.name = name; + this.mainCategory = mainCategory; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/category/repository/MainCategoryRepository.java b/src/main/java/project/trendpick_pro/domain/category/repository/MainCategoryRepository.java new file mode 100644 index 00000000..835435c5 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/category/repository/MainCategoryRepository.java @@ -0,0 +1,8 @@ +package project.trendpick_pro.domain.category.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.category.entity.MainCategory; + +public interface MainCategoryRepository extends JpaRepository { + public MainCategory findByName(String name); +} diff --git a/src/main/java/project/trendpick_pro/domain/category/repository/SubCategoryRepository.java b/src/main/java/project/trendpick_pro/domain/category/repository/SubCategoryRepository.java new file mode 100644 index 00000000..42b27289 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/category/repository/SubCategoryRepository.java @@ -0,0 +1,8 @@ +package project.trendpick_pro.domain.category.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.category.entity.SubCategory; + +public interface SubCategoryRepository extends JpaRepository { + public SubCategory findByName(String name); +} From 786832ebc8abdec66f39ae31ecb71ff8a8049572 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 28 May 2023 23:44:08 +0900 Subject: [PATCH 041/367] =?UTF-8?q?refactor:=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EC=97=B0=EA=B4=80=EA=B4=80=EA=B3=84,=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0=20(#37)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/brand/entity/Brand.java | 1 + .../brand/repository/BrandRepository.java | 1 + .../domain/product/entity/Product.java | 32 ++++++++++--------- .../dto/request/ProductSaveRequest.java | 6 ++-- .../product/service/ProductService.java | 18 +++++++++-- 5 files changed, 38 insertions(+), 20 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/brand/entity/Brand.java b/src/main/java/project/trendpick_pro/domain/brand/entity/Brand.java index 71683a2d..57a4fbb3 100644 --- a/src/main/java/project/trendpick_pro/domain/brand/entity/Brand.java +++ b/src/main/java/project/trendpick_pro/domain/brand/entity/Brand.java @@ -14,5 +14,6 @@ public class Brand { @Column(name = "brand_id") private Long id; + @Column(name = "name", nullable = false, unique = true) private String name; } diff --git a/src/main/java/project/trendpick_pro/domain/brand/repository/BrandRepository.java b/src/main/java/project/trendpick_pro/domain/brand/repository/BrandRepository.java index 6f9b02e9..04df6f74 100644 --- a/src/main/java/project/trendpick_pro/domain/brand/repository/BrandRepository.java +++ b/src/main/java/project/trendpick_pro/domain/brand/repository/BrandRepository.java @@ -4,4 +4,5 @@ import project.trendpick_pro.domain.brand.entity.Brand; public interface BrandRepository extends JpaRepository { + public Brand findByName(String name); } diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index e93d5c7b..02686d3e 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -6,6 +6,9 @@ import lombok.Getter; import lombok.NoArgsConstructor; import org.springframework.web.multipart.MultipartFile; +import project.trendpick_pro.domain.brand.entity.Brand; +import project.trendpick_pro.domain.category.entity.MainCategory; +import project.trendpick_pro.domain.category.entity.SubCategory; import project.trendpick_pro.domain.common.base.BaseTimeEntity; import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; @@ -25,19 +28,18 @@ public class Product extends BaseTimeEntity { @Column(name = "name", nullable = false) private String name; -// @ManyToOne(fetch = FetchType.LAZY) -// @JoinColumn(name = "main-category_id") - private String mainCategory; // Category + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "main_category_id") + private MainCategory mainCategory; // Category -// @ManyToOne(fetch = FetchType.LAZY) -// @JoinColumn(name = "sub-category_id") - @ElementCollection // 이거 빨간줄 때문에 예비로 추가한거라 보고 추가하시면 안되요!!! - private List subCategory = new ArrayList<>(); // Category + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "sub_category_id") + private SubCategory subCategory; // Category -// @ManyToOne(fetch = FetchType.LAZY) -// @JoinColumn(name = "brand_id") - private String brand; // Brand + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "brand_id") + private Brand brand; @Column(name = "description", nullable = false) private String description; @@ -56,7 +58,7 @@ public class Product extends BaseTimeEntity { private List tags = new ArrayList<>(); @Builder - public Product(String name, String mainCategory, List subCategory, String brand, + public Product(String name, MainCategory mainCategory, SubCategory subCategory, Brand brand, String description, CommonFile commonFile, int price, int stock, List tags) { this.name = name; this.mainCategory = mainCategory; @@ -69,12 +71,12 @@ public Product(String name, String mainCategory, List subCategory, Strin this.tags = tags; } - public static Product of(ProductSaveRequest request) { + public static Product of(ProductSaveRequest request, MainCategory mainCategory, SubCategory subCategory, Brand brand) { return Product.builder() .name(request.getName()) - .mainCategory(request.getMainCategory()) - .subCategory(request.getSubCategory()) - .brand(request.getBrand()) + .mainCategory(mainCategory) + .subCategory(subCategory) + .brand(brand) .description(request.getDescription()) .commonFile(makeFiles(request.getMainFile(), request.getSubFiles())) .price(request.getPrice()) diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java index 083f838c..0a3b5b94 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java @@ -17,13 +17,13 @@ public class ProductSaveRequest { private String description; @NotBlank(message = "메인 카테고리를 정하세요.") - private String mainCategory; // Category + private String mainCategory; @NotBlank(message = "서브 카테고리를 정하세요.") - private List subCategory; // Category + private String subCategory; @NotBlank(message = "브랜드를 입력해주세요.") - private String brand; // Brand + private String brand; @NotBlank(message = "메인 사진을 입력해주세요.") private MultipartFile mainFile; diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 4633c531..b59bbefb 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -4,6 +4,12 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.brand.entity.Brand; +import project.trendpick_pro.domain.brand.repository.BrandRepository; +import project.trendpick_pro.domain.category.entity.MainCategory; +import project.trendpick_pro.domain.category.entity.SubCategory; +import project.trendpick_pro.domain.category.repository.MainCategoryRepository; +import project.trendpick_pro.domain.category.repository.SubCategoryRepository; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; @@ -18,11 +24,19 @@ @RequiredArgsConstructor public class ProductService { - private ProductRepository productRepository; + private final ProductRepository productRepository; + private final MainCategoryRepository mainCategoryRepository; + private final SubCategoryRepository subCategoryRepository; + private final BrandRepository brandRepository; @Transactional public ProductResponse register(ProductSaveRequest productSaveRequest) { - Product product = Product.of(productSaveRequest); + + MainCategory mainCategory = mainCategoryRepository.findByName(productSaveRequest.getMainCategory()); + SubCategory subCategory = subCategoryRepository.findByName(productSaveRequest.getSubCategory()); + Brand brand = brandRepository.findByName(productSaveRequest.getBrand()); + + Product product = Product.of(productSaveRequest, mainCategory, subCategory, brand); productRepository.save(product); return ProductResponse.of(product); } From b5512a96b7678d2a6e102e1488b894b2f6287810 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 29 May 2023 01:24:24 +0900 Subject: [PATCH 042/367] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/controller/MemberController.java | 10 +++++++--- .../domain/member/service/MemberService.java | 1 + .../resources/templates/trendpick/usr/member/join.html | 2 +- .../templates/trendpick/usr/member/login.html | 2 +- .../resources/templates/trendpick/usr/member/me.html | 3 +++ 5 files changed, 13 insertions(+), 5 deletions(-) create mode 100644 src/main/resources/templates/trendpick/usr/member/me.html diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java index b19bf212..937c66f4 100644 --- a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java +++ b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java @@ -24,7 +24,7 @@ public class MemberController { @PreAuthorize("isAnonymous()") @GetMapping("/join") public String showJoin() { - return "usr/member/join"; + return "trendpick/usr/member/join"; } @AllArgsConstructor @@ -41,6 +41,10 @@ public static class JoinForm { @PreAuthorize("isAnonymous()") @PostMapping("/join") public String join(@Valid JoinForm joinForm) { + if ( memberService.findByUsername(joinForm.getUsername()).isPresent() ) { + return "해당 아이디는 이미 사용중입니다."; + } + memberService.join(joinForm.getUsername(), joinForm.getPassword()); return "회원가입이 완료되었습니다"; @@ -49,12 +53,12 @@ public String join(@Valid JoinForm joinForm) { @PreAuthorize("isAnonymous()") @GetMapping("/login") public String showLogin() { - return "usr/member/login"; + return "trendpick/usr/member/login"; } @PreAuthorize("isAuthenticated()") @GetMapping("/me") public String showMe() { - return "usr/member/me"; + return "trendpick/usr/member/me"; } } diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index 725c1bc1..0b2dcf45 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -23,6 +23,7 @@ public Optional findByUsername(String username) { @Transactional public Member join(String username, String password) { + Member member = Member .builder() .username(username) diff --git a/src/main/resources/templates/trendpick/usr/member/join.html b/src/main/resources/templates/trendpick/usr/member/join.html index d9600373..7277ad6e 100644 --- a/src/main/resources/templates/trendpick/usr/member/join.html +++ b/src/main/resources/templates/trendpick/usr/member/join.html @@ -1,4 +1,4 @@ - + 회원가입 diff --git a/src/main/resources/templates/trendpick/usr/member/login.html b/src/main/resources/templates/trendpick/usr/member/login.html index d2bc4f11..fafc2e88 100644 --- a/src/main/resources/templates/trendpick/usr/member/login.html +++ b/src/main/resources/templates/trendpick/usr/member/login.html @@ -1,4 +1,4 @@ - + 로그인 diff --git a/src/main/resources/templates/trendpick/usr/member/me.html b/src/main/resources/templates/trendpick/usr/member/me.html new file mode 100644 index 00000000..fc30207d --- /dev/null +++ b/src/main/resources/templates/trendpick/usr/member/me.html @@ -0,0 +1,3 @@ + +
id :
+ \ No newline at end of file From 0ac312bbd8e394956fbe55c6a5e3de8c878a8a33 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 29 May 2023 02:05:43 +0900 Subject: [PATCH 043/367] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85/=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EA=B8=B0=EB=8A=A5=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/controller/MemberController.java | 20 +++++++++---------- .../domain/member/service/MemberService.java | 2 +- .../templates/trendpick/usr/member/info.html | 3 +++ .../templates/trendpick/usr/member/join.html | 13 ++++++++++++ .../templates/trendpick/usr/member/me.html | 3 --- 5 files changed, 26 insertions(+), 15 deletions(-) create mode 100644 src/main/resources/templates/trendpick/usr/member/info.html delete mode 100644 src/main/resources/templates/trendpick/usr/member/me.html diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java index 937c66f4..5235b0a9 100644 --- a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java +++ b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java @@ -11,18 +11,16 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; -import project.trendpick_pro.domain.common.base.rq.Rq; -import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.service.MemberService; @Controller -@RequestMapping("/member") +@RequestMapping("/trendpick/usr") @RequiredArgsConstructor public class MemberController { private final MemberService memberService; @PreAuthorize("isAnonymous()") - @GetMapping("/join") + @GetMapping("/register") public String showJoin() { return "trendpick/usr/member/join"; } @@ -39,26 +37,26 @@ public static class JoinForm { } @PreAuthorize("isAnonymous()") - @PostMapping("/join") - public String join(@Valid JoinForm joinForm) { + @PostMapping("/register") + public String register(@Valid JoinForm joinForm) { if ( memberService.findByUsername(joinForm.getUsername()).isPresent() ) { return "해당 아이디는 이미 사용중입니다."; } - memberService.join(joinForm.getUsername(), joinForm.getPassword()); + memberService.register(joinForm.getUsername(), joinForm.getPassword()); return "회원가입이 완료되었습니다"; } - @PreAuthorize("isAnonymous()") +// @PreAuthorize("isAnonymous()") @GetMapping("/login") public String showLogin() { - return "trendpick/usr/member/login"; + return "로그인에 성공하셨습니다"; } @PreAuthorize("isAuthenticated()") - @GetMapping("/me") + @GetMapping("/info") public String showMe() { - return "trendpick/usr/member/me"; + return "trendpick/usr/member/info"; } } diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index 0b2dcf45..85915568 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -22,7 +22,7 @@ public Optional findByUsername(String username) { } @Transactional - public Member join(String username, String password) { + public Member register(String username, String password) { Member member = Member .builder() diff --git a/src/main/resources/templates/trendpick/usr/member/info.html b/src/main/resources/templates/trendpick/usr/member/info.html new file mode 100644 index 00000000..ff843e7a --- /dev/null +++ b/src/main/resources/templates/trendpick/usr/member/info.html @@ -0,0 +1,3 @@ + +
회원 정보
+ \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/member/join.html b/src/main/resources/templates/trendpick/usr/member/join.html index 7277ad6e..9012ba78 100644 --- a/src/main/resources/templates/trendpick/usr/member/join.html +++ b/src/main/resources/templates/trendpick/usr/member/join.html @@ -41,6 +41,19 @@ return; } + form.password.value = form.password.value.trim(); // 입력란의 입력값에 있을지 모르는 좌우공백제거 + + if (form.password.value.length == 0) { + form.password.focus(); + toastWarning('비밀번호를 입력해주세요.'); + return; + } + + if (form.password.value.length < 4) { + toastWarning('비밀번호를 4자 이상 입력해주세요.'); + form.password.focus(); + return; + } form.submit(); // 폼 발송 } diff --git a/src/main/resources/templates/trendpick/usr/member/me.html b/src/main/resources/templates/trendpick/usr/member/me.html deleted file mode 100644 index fc30207d..00000000 --- a/src/main/resources/templates/trendpick/usr/member/me.html +++ /dev/null @@ -1,3 +0,0 @@ - -
id :
- \ No newline at end of file From 45521ba82fafb6d6011880a8008c0c96c0e2a7f6 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 29 May 2023 02:54:54 +0900 Subject: [PATCH 044/367] =?UTF-8?q?fix:=20=EB=B3=80=EC=88=98=EB=AA=85=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - user -> member --- .../trendpick_pro/domain/orders/entity/Order.java | 2 +- .../domain/orders/repository/OrderRepository.java | 4 ++-- .../domain/orders/service/OrderService.java | 11 ++++++----- 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java index 6f6a3e89..f5073b15 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java @@ -23,7 +23,7 @@ public class Order extends BaseTimeEntity { private Long id; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "user_id") + @JoinColumn(name = "member_id") private Member member; @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java index 1b76547a..4e374976 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java @@ -3,9 +3,9 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.orders.entity.Order; -import project.trendpick_pro.domain.user.entity.User; public interface OrderRepository extends JpaRepository { - Page findAllByUser(User member, Pageable pageable); + Page findAllByUser(Member member, Pageable pageable); } diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 8ce5e553..3b970bb1 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -9,6 +9,8 @@ import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.delivery.entity.Delivery; import project.trendpick_pro.domain.delivery.entity.embaded.Address; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.orders.entity.Order; import project.trendpick_pro.domain.orders.entity.OrderItem; import project.trendpick_pro.domain.orders.entity.OrderStatus; @@ -18,7 +20,6 @@ import project.trendpick_pro.domain.orders.repository.OrderRepository; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; -import project.trendpick_pro.domain.member.repository.UserRepository; import java.util.ArrayList; import java.util.List; @@ -30,13 +31,13 @@ public class OrderService { private final OrderRepository orderRepository; - private final UserRepository userRepository; + private final MemberRepository memberRepository; private final ProductRepository productRepository; @Transactional public void order(Long userId, OrderSaveRequest... orderSaveRequests) throws IllegalAccessException { - Member member = userRepository.findById(userId).orElseThrow(() -> new EntityNotFoundException("존재하지 않는 유저 입니다."));// 임시 exception 설정 나중에 할 수도 있고 아닐수도 + Member member = memberRepository.findById(userId).orElseThrow(() -> new EntityNotFoundException("존재하지 않는 유저 입니다."));// 임시 exception 설정 나중에 할 수도 있고 아닐수도 Delivery delivery = new Delivery(Address.of("서울시", "강남대로", "222")); // 임의로 작성 @@ -61,9 +62,9 @@ public void cancel(Long orderId) { //임시 작성 public Page findAll(OrderSearchCond cond) { - User user = userRepository.findById(cond.getUserId()).orElseThrow(); + Member member = memberRepository.findById(cond.getUserId()).orElseThrow(); - Page orderPage = orderRepository.findAllByUser(user, PageRequest.of(0, 10)); + Page orderPage = orderRepository.findAllByUser(member, PageRequest.of(0, 10)); return orderPage; } From c7d8d13febb41a0a9730e62702489ee466886d7b Mon Sep 17 00:00:00 2001 From: Hyeyoung Kwon <71963159+hye-0000@users.noreply.github.com> Date: Mon, 29 May 2023 03:08:36 +0900 Subject: [PATCH 045/367] =?UTF-8?q?Revert=20"fix:=20=EB=B3=80=EC=88=98?= =?UTF-8?q?=EB=AA=85=20=EC=88=98=EC=A0=95"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trendpick_pro/domain/orders/entity/Order.java | 2 +- .../domain/orders/repository/OrderRepository.java | 4 ++-- .../domain/orders/service/OrderService.java | 11 +++++------ 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java index f5073b15..6f6a3e89 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java @@ -23,7 +23,7 @@ public class Order extends BaseTimeEntity { private Long id; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") + @JoinColumn(name = "user_id") private Member member; @OneToMany(mappedBy = "order", cascade = CascadeType.ALL) diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java index 4e374976..1b76547a 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java @@ -3,9 +3,9 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; -import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.orders.entity.Order; +import project.trendpick_pro.domain.user.entity.User; public interface OrderRepository extends JpaRepository { - Page findAllByUser(Member member, Pageable pageable); + Page findAllByUser(User member, Pageable pageable); } diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 3b970bb1..8ce5e553 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -9,8 +9,6 @@ import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.delivery.entity.Delivery; import project.trendpick_pro.domain.delivery.entity.embaded.Address; -import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.orders.entity.Order; import project.trendpick_pro.domain.orders.entity.OrderItem; import project.trendpick_pro.domain.orders.entity.OrderStatus; @@ -20,6 +18,7 @@ import project.trendpick_pro.domain.orders.repository.OrderRepository; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; +import project.trendpick_pro.domain.member.repository.UserRepository; import java.util.ArrayList; import java.util.List; @@ -31,13 +30,13 @@ public class OrderService { private final OrderRepository orderRepository; - private final MemberRepository memberRepository; + private final UserRepository userRepository; private final ProductRepository productRepository; @Transactional public void order(Long userId, OrderSaveRequest... orderSaveRequests) throws IllegalAccessException { - Member member = memberRepository.findById(userId).orElseThrow(() -> new EntityNotFoundException("존재하지 않는 유저 입니다."));// 임시 exception 설정 나중에 할 수도 있고 아닐수도 + Member member = userRepository.findById(userId).orElseThrow(() -> new EntityNotFoundException("존재하지 않는 유저 입니다."));// 임시 exception 설정 나중에 할 수도 있고 아닐수도 Delivery delivery = new Delivery(Address.of("서울시", "강남대로", "222")); // 임의로 작성 @@ -62,9 +61,9 @@ public void cancel(Long orderId) { //임시 작성 public Page findAll(OrderSearchCond cond) { - Member member = memberRepository.findById(cond.getUserId()).orElseThrow(); + User user = userRepository.findById(cond.getUserId()).orElseThrow(); - Page orderPage = orderRepository.findAllByUser(member, PageRequest.of(0, 10)); + Page orderPage = orderRepository.findAllByUser(user, PageRequest.of(0, 10)); return orderPage; } From 8de97820dd4fac0d9135d56f5c366f56b8046c19 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 29 May 2023 08:35:33 +0900 Subject: [PATCH 046/367] =?UTF-8?q?fix:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 어노테이션 추가 --- .../security/CustomUserDetailsService.java | 25 +++++++++++++++++++ .../common/base/security/SecurityConfig.java | 6 ++++- .../member/controller/MemberController.java | 4 +-- .../domain/member/entity/Member.java | 19 ++++++++++++++ 4 files changed, 51 insertions(+), 3 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/common/base/security/CustomUserDetailsService.java diff --git a/src/main/java/project/trendpick_pro/domain/common/base/security/CustomUserDetailsService.java b/src/main/java/project/trendpick_pro/domain/common/base/security/CustomUserDetailsService.java new file mode 100644 index 00000000..66bf8b8e --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/common/base/security/CustomUserDetailsService.java @@ -0,0 +1,25 @@ +package project.trendpick_pro.domain.common.base.security; + +import lombok.RequiredArgsConstructor; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.repository.MemberRepository; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = false) +public class CustomUserDetailsService implements UserDetailsService { + private final MemberRepository memberRepository; + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + Member member = memberRepository.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException("username(%s) not found".formatted(username))); + + return new User(member.getUsername(), member.getPassword(), member.getGrantedAuthorities()); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/common/base/security/SecurityConfig.java b/src/main/java/project/trendpick_pro/domain/common/base/security/SecurityConfig.java index e2ee22ff..6a548112 100644 --- a/src/main/java/project/trendpick_pro/domain/common/base/security/SecurityConfig.java +++ b/src/main/java/project/trendpick_pro/domain/common/base/security/SecurityConfig.java @@ -2,19 +2,23 @@ import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; @Configuration +@EnableWebSecurity +@EnableMethodSecurity(prePostEnabled = true) public class SecurityConfig { @Bean SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .formLogin( formLogin -> formLogin - .loginPage("/member/login") + .loginPage("/trendpick/usr/login") ) .logout( logout -> logout diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java index 5235b0a9..a4de0f54 100644 --- a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java +++ b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java @@ -48,10 +48,10 @@ public String register(@Valid JoinForm joinForm) { return "회원가입이 완료되었습니다"; } -// @PreAuthorize("isAnonymous()") + @PreAuthorize("isAnonymous()") @GetMapping("/login") public String showLogin() { - return "로그인에 성공하셨습니다"; + return "/trendpick/usr/member/login"; } @PreAuthorize("isAuthenticated()") diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index efb30842..975db7e0 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -5,8 +5,12 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import java.util.ArrayList; import java.util.Date; +import java.util.List; @Entity @NoArgsConstructor @@ -36,5 +40,20 @@ public class Member { private String bank_name; private Long account; + // 이 함수 자체는 만들어야 한다. 스프링 시큐리티 규격 + public List getGrantedAuthorities() { + List grantedAuthorities = new ArrayList<>(); + + // 모든 멤버는 member 권한을 가진다. + grantedAuthorities.add(new SimpleGrantedAuthority("member")); + + // username이 admin인 회원은 추가로 admin 권한도 가진다. + if ("admin".equals(username)) { + grantedAuthorities.add(new SimpleGrantedAuthority("admin")); + } + + return grantedAuthorities; + } + } From d3ad05d2f1c3b5ffa76f6169194357f9d60cf5b7 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 29 May 2023 09:44:20 +0900 Subject: [PATCH 047/367] =?UTF-8?q?feat:=20=EB=B0=B0=EC=86=A1=EC=A7=80=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/controller/MemberController.java | 15 +++++++++++++++ .../domain/member/entity/Member.java | 9 ++++----- .../domain/member/service/MemberService.java | 6 ++++++ .../templates/trendpick/usr/member/address.html | 3 +++ 4 files changed, 28 insertions(+), 5 deletions(-) create mode 100644 src/main/resources/templates/trendpick/usr/member/address.html diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java index a4de0f54..bc47e799 100644 --- a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java +++ b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java @@ -11,13 +11,18 @@ import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; +import project.trendpick_pro.domain.common.base.rq.Rq; +import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.service.MemberService; +import java.security.Principal; + @Controller @RequestMapping("/trendpick/usr") @RequiredArgsConstructor public class MemberController { private final MemberService memberService; + private final Rq rq; @PreAuthorize("isAnonymous()") @GetMapping("/register") @@ -59,4 +64,14 @@ public String showLogin() { public String showMe() { return "trendpick/usr/member/info"; } + + @PreAuthorize("isAuthenticated()") + @PostMapping("/info/address-edit") + public String manageAddress(String address) { + Member actor = rq.getMember(); + memberService.manageAddress(actor, address); + + return "trendpick/usr/member/info"; + } + } diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index 975db7e0..ef69ccbe 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -1,10 +1,7 @@ package project.trendpick_pro.domain.member.entity; import jakarta.persistence.*; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; @@ -16,7 +13,7 @@ @NoArgsConstructor @AllArgsConstructor @Builder -@Getter +@Getter @Setter public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "member_id") @@ -40,6 +37,8 @@ public class Member { private String bank_name; private Long account; + private String address; + // 이 함수 자체는 만들어야 한다. 스프링 시큐리티 규격 public List getGrantedAuthorities() { List grantedAuthorities = new ArrayList<>(); diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index 85915568..544c099f 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -32,4 +32,10 @@ public Member register(String username, String password) { return memberRepository.save(member); } + @Transactional + + public void manageAddress(Member actor, String address){ + Member member = memberRepository.findByUsername(actor.getUsername()).orElseThrow(); + member.setAddress(address); + } } \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/member/address.html b/src/main/resources/templates/trendpick/usr/member/address.html new file mode 100644 index 00000000..ab1ed87b --- /dev/null +++ b/src/main/resources/templates/trendpick/usr/member/address.html @@ -0,0 +1,3 @@ + +
배송지 정보
+ \ No newline at end of file From 9d1a98533c23d9932546a5682e0838bc3964891c Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 29 May 2023 09:52:42 +0900 Subject: [PATCH 048/367] =?UTF-8?q?feat:=20=ED=99=98=EB=B6=88=EA=B3=84?= =?UTF-8?q?=EC=A2=8C=20=EA=B4=80=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/controller/MemberController.java | 8 ++++++++ .../domain/member/service/MemberService.java | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java index bc47e799..ad3982a2 100644 --- a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java +++ b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java @@ -74,4 +74,12 @@ public String manageAddress(String address) { return "trendpick/usr/member/info"; } + @PreAuthorize("isAuthenticated()") + @PostMapping("/info/account") + public String manageAccount(String bank_name, Long account) { + Member actor = rq.getMember(); + memberService.manageAccount(actor, bank_name, account); + + return "trendpick/usr/member/info"; + } } diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index 544c099f..18de32ad 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -38,4 +38,10 @@ public void manageAddress(Member actor, String address){ Member member = memberRepository.findByUsername(actor.getUsername()).orElseThrow(); member.setAddress(address); } + + public void manageAccount(Member actor, String bank_name, Long account){ + Member member = memberRepository.findByUsername(actor.getUsername()).orElseThrow(); + member.setBank_name(bank_name); + member.setAccount(account); + } } \ No newline at end of file From 23fb251fc0c6d01a59fe0c887e026681e25211ce Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 29 May 2023 11:10:49 +0900 Subject: [PATCH 049/367] =?UTF-8?q?feat:=20=EB=A6=AC=EB=B7=B0=20=EC=A1=B0?= =?UTF-8?q?=ED=9A=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 18 ++++++++ .../domain/review/entity/Review.java | 6 +-- .../entity/dto/request/ReviewRequest.java | 12 +++++ .../entity/dto/response/ReviewResponse.java | 44 +++++++++++++++++++ .../review/repository/ReviewRepository.java | 3 ++ .../domain/review/service/ReviewService.java | 24 ++++++++++ 6 files changed, 104 insertions(+), 3 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewRequest.java create mode 100644 src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index 9cbe4622..abcf675c 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -1,4 +1,22 @@ package project.trendpick_pro.domain.review.controller; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import project.trendpick_pro.domain.review.service.ReviewService; + +@Controller +@RequiredArgsConstructor +@RequestMapping("/trendpick/review") public class ReviewController { + private final ReviewService reviewService; + + @GetMapping("/list/{productId}") + public String showReview(@PathVariable Long reviewId, Model model){ + model.addAttribute("reviewRes", reviewService.showReview(reviewId)); + return ""; + } } diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java index 7fbe836f..64462d90 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -6,6 +6,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import project.trendpick_pro.domain.common.base.BaseTimeEntity; +import project.trendpick_pro.domain.member.entity.Member; @Entity @NoArgsConstructor @@ -17,9 +18,8 @@ public class Review extends BaseTimeEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - //@ManyToOne - //@JoinColumn(name = "member_id") - private Long user_id; //User + @ManyToOne + private Member member; //User // @ManyToOne(fetch = FetchType.LAZY) //@JoinColumn(name = "product_id") diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewRequest.java b/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewRequest.java new file mode 100644 index 00000000..9c4054a9 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewRequest.java @@ -0,0 +1,12 @@ +package project.trendpick_pro.domain.review.entity.dto.request; + + +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; + +@Getter +public class ReviewRequest { + @NotBlank + private String content; + private int rating; +} diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java b/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java new file mode 100644 index 00000000..92ba00cf --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java @@ -0,0 +1,44 @@ +package project.trendpick_pro.domain.review.entity.dto.response; + +import com.querydsl.core.annotations.QueryProjection; +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.review.entity.Review; + +import java.util.Optional; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ReviewResponse { + private Long id; + private Member member; //User + private Long product_id; //Product + @Lob + private String content; + + private int rating; + + @Builder + @QueryProjection + public ReviewResponse(Long id, Member member, Long product_id, String content, int rating) { + this.id = id; + this.member = member; + this.product_id = product_id; + this.content = content; + this.rating = rating; + } + + public static ReviewResponse of(Review review) { + return ReviewResponse.builder() + .id(review.getId()) + .member(review.getMember()) + .product_id(review.getProduct_id()) + .content(review.getContent()) + .rating(review.getRating()) + .build(); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java b/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java index f2d441e9..9a71b9f6 100644 --- a/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java +++ b/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java @@ -3,5 +3,8 @@ import org.springframework.data.jpa.repository.JpaRepository; import project.trendpick_pro.domain.review.entity.Review; +import java.util.List; + public interface ReviewRepository extends JpaRepository { + List findAll(Long productId); } diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index c0270877..64022f28 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -1,4 +1,28 @@ package project.trendpick_pro.domain.review.service; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.review.entity.Review; +import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; +import project.trendpick_pro.domain.review.repository.ReviewRepository; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor public class ReviewService { + private final ReviewRepository reviewRepository; + + public ReviewResponse showReview(Long productId) { + Review review = reviewRepository.findById(productId).orElseThrow(); + + return ReviewResponse.of(review); + } + + + } From d2499ac085bc17bc651a45bf27fa17bd749e2618 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 29 May 2023 11:32:15 +0900 Subject: [PATCH 050/367] =?UTF-8?q?feat:=20=EB=A6=AC=EB=B7=B0=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D/=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 30 ++++++++++++++++--- .../domain/review/entity/Review.java | 16 ++++++++-- .../entity/dto/response/ReviewResponse.java | 14 ++++----- .../domain/review/service/ReviewService.java | 18 +++++++++-- 4 files changed, 61 insertions(+), 17 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index abcf675c..72cd9db9 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -1,11 +1,15 @@ package project.trendpick_pro.domain.review.controller; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -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.*; +import project.trendpick_pro.domain.ask.entity.dto.response.AskResponse; +import project.trendpick_pro.domain.common.base.rq.Rq; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.review.entity.dto.request.ReviewRequest; +import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; import project.trendpick_pro.domain.review.service.ReviewService; @Controller @@ -13,10 +17,28 @@ @RequestMapping("/trendpick/review") public class ReviewController { private final ReviewService reviewService; + private final Rq rq; - @GetMapping("/list/{productId}") + @PostMapping("/write") + public String createReview(@Valid ReviewRequest reviewRequest, @RequestParam(value = "productId") Long productId, Model model) { + Member actor = rq.getMember(); + ReviewResponse reviewResponse = reviewService.createReview(actor, reviewRequest); + + model.addAttribute("reviewResponse", reviewResponse); + return ""; + + } + + @GetMapping("/list/{reviewId}") public String showReview(@PathVariable Long reviewId, Model model){ model.addAttribute("reviewRes", reviewService.showReview(reviewId)); return ""; } + + @PostMapping("/delete/{reviewId}") + public String deleteReview(@PathVariable Long reviewId) { + reviewService.delete(reviewId); + + return ""; + } } diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java index 64462d90..c400ab7e 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -7,6 +7,8 @@ import lombok.NoArgsConstructor; import project.trendpick_pro.domain.common.base.BaseTimeEntity; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.review.entity.dto.request.ReviewRequest; +import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; @Entity @NoArgsConstructor @@ -18,15 +20,23 @@ public class Review extends BaseTimeEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne - private Member member; //User + private String username; //User // @ManyToOne(fetch = FetchType.LAZY) //@JoinColumn(name = "product_id") - private Long product_id; //Product + private Long productId; //Product @Lob private String content; private int rating; + + public static Review of(String username, Long productId, ReviewRequest reviewRequest) { + return Review.builder() + .username(username) + .productId(productId) + .content(reviewRequest.getContent()) + .rating(reviewRequest.getRating()) + .build(); + } } diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java b/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java index 92ba00cf..6e987971 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java @@ -15,8 +15,8 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ReviewResponse { private Long id; - private Member member; //User - private Long product_id; //Product + private String username; //User + private Long productId; //Product @Lob private String content; @@ -24,10 +24,10 @@ public class ReviewResponse { @Builder @QueryProjection - public ReviewResponse(Long id, Member member, Long product_id, String content, int rating) { + public ReviewResponse(Long id, String username, Long productId, String content, int rating) { this.id = id; - this.member = member; - this.product_id = product_id; + this.username = username; + this.productId = productId; this.content = content; this.rating = rating; } @@ -35,8 +35,8 @@ public ReviewResponse(Long id, Member member, Long product_id, String content, i public static ReviewResponse of(Review review) { return ReviewResponse.builder() .id(review.getId()) - .member(review.getMember()) - .product_id(review.getProduct_id()) + .username(review.getUsername()) + .productId(review.getProductId()) .content(review.getContent()) .rating(review.getRating()) .build(); diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index 64022f28..4bb8855f 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -3,13 +3,13 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.common.base.rq.Rq; +import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.review.entity.Review; +import project.trendpick_pro.domain.review.entity.dto.request.ReviewRequest; import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; import project.trendpick_pro.domain.review.repository.ReviewRepository; -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; @Service @Transactional(readOnly = true) @@ -17,6 +17,8 @@ public class ReviewService { private final ReviewRepository reviewRepository; + + public ReviewResponse showReview(Long productId) { Review review = reviewRepository.findById(productId).orElseThrow(); @@ -24,5 +26,15 @@ public ReviewResponse showReview(Long productId) { } + public void delete(Long reviewId) { + reviewRepository.deleteById(reviewId); + } + + public ReviewResponse createReview(Member actor, ReviewRequest reviewRequest) { + String username = actor.getUsername(); + Long productId = 1L; + Review review = Review.of(username, productId, reviewRequest); + return ReviewResponse.of(review); + } } From 75db7d0a810bedd4b310f8ae7ce7384a203e428e Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 29 May 2023 11:36:22 +0900 Subject: [PATCH 051/367] =?UTF-8?q?feat:=20=EB=A6=AC=EB=B7=B0=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/review/controller/ReviewController.java | 9 +++++++++ .../trendpick_pro/domain/review/entity/Review.java | 5 +++++ .../domain/review/service/ReviewService.java | 7 +++++++ 3 files changed, 21 insertions(+) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index 72cd9db9..7059cafa 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -5,6 +5,7 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; +import project.trendpick_pro.domain.ask.entity.dto.request.AskRequest; import project.trendpick_pro.domain.ask.entity.dto.response.AskResponse; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; @@ -41,4 +42,12 @@ public String deleteReview(@PathVariable Long reviewId) { return ""; } + + @PostMapping("/edit/{reviewId}") + public String modifyAsk(@PathVariable Long reviewId, @Valid ReviewRequest reviewRequest, Model model) { + ReviewResponse reviewResponse = reviewService.modify(reviewId, reviewRequest); + + model.addAttribute("reviewResponse", reviewResponse); + return ""; + } } diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java index c400ab7e..bc6ca208 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -39,4 +39,9 @@ public static Review of(String username, Long productId, ReviewRequest reviewReq .rating(reviewRequest.getRating()) .build(); } + + public void update(ReviewRequest reviewRequest) { + this.content = reviewRequest.getContent(); + this.rating = reviewRequest.getRating(); + } } diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index 4bb8855f..02f772ac 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -37,4 +37,11 @@ public ReviewResponse createReview(Member actor, ReviewRequest reviewRequest) { Review review = Review.of(username, productId, reviewRequest); return ReviewResponse.of(review); } + + public ReviewResponse modify(Long reviewId, ReviewRequest reviewRequest) { + Review review = reviewRepository.findById(reviewId).orElseThrow(); + + review.update(reviewRequest); + return ReviewResponse.of(review); + } } From 7bfefb89cbe659a2d0f199969c06ecfd2b8a718f Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Mon, 29 May 2023 13:54:29 +0900 Subject: [PATCH 052/367] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20=EC=98=B5?= =?UTF-8?q?=EC=85=98=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/product/entity/ProductOption.java | 42 +++++++++++++++++++ .../dto/request/ProductOptionSaveRequest.java | 17 ++++++++ .../dto/response/ProductOptionResponse.java | 40 ++++++++++++++++++ .../repository/ProductOptionRepository.java | 7 ++++ 4 files changed, 106 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/product/entity/ProductOption.java create mode 100644 src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductOptionSaveRequest.java create mode 100644 src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductOptionResponse.java create mode 100644 src/main/java/project/trendpick_pro/domain/product/repository/ProductOptionRepository.java diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/ProductOption.java b/src/main/java/project/trendpick_pro/domain/product/entity/ProductOption.java new file mode 100644 index 00000000..243ff69c --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/entity/ProductOption.java @@ -0,0 +1,42 @@ +package project.trendpick_pro.domain.product.entity; + +import jakarta.persistence.*; +import lombok.*; +import project.trendpick_pro.domain.product.entity.dto.request.ProductOptionSaveRequest; + +@Entity +@Getter +@Setter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ProductOption { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn Product product; + + private String color; // 색상 + + private String size; // 사이즈 + private int count; // 수량 + + @Builder + public ProductOption(Product product,String color, String size, int count){ + this.product = product; + this.color = color; + this.size = size; + this.count = count; + } + + public static ProductOption of(Product product,ProductOptionSaveRequest request) { + return ProductOption.builder() + .product(product) + .color(request.getColor()) + .size(request.getSize()) + .count(request.getCount()) + .build(); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductOptionSaveRequest.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductOptionSaveRequest.java new file mode 100644 index 00000000..155fcd04 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductOptionSaveRequest.java @@ -0,0 +1,17 @@ +package project.trendpick_pro.domain.product.entity.dto.request; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import lombok.Data; + +@Data +public class ProductOptionSaveRequest { + @NotBlank(message = "상품색상을 선택해주세요.") + private String color; + + @NotBlank(message = "사이즈를 선택해주세요.") + private String size; + + @Min(1) + private int count; +} diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductOptionResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductOptionResponse.java new file mode 100644 index 00000000..517392c4 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductOptionResponse.java @@ -0,0 +1,40 @@ +package project.trendpick_pro.domain.product.entity.dto.response; + +import com.querydsl.core.annotations.QueryProjection; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.product.entity.ProductOption; + + + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ProductOptionResponse { + Product product; + private String color; + + private String size; + + private int count; + + @Builder + @QueryProjection + public ProductOptionResponse(Product product, String color, String size,int count) { + this.product=product; + this.color=color; + this.size=size; + this.count=count; + } + + public static ProductOptionResponse of (ProductOption productOption) { + return ProductOptionResponse.builder() + .product(productOption.getProduct()) + .color(productOption.getColor()) + .size(productOption.getSize()) + .count(productOption.getCount()) + .build(); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductOptionRepository.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductOptionRepository.java new file mode 100644 index 00000000..e0e5f53f --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductOptionRepository.java @@ -0,0 +1,7 @@ +package project.trendpick_pro.domain.product.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.product.entity.ProductOption; + +public interface ProductOptionRepository extends JpaRepository { +} From 97a0ea209f51879dcf73ac70c0f7a125a65a8fc3 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 29 May 2023 15:14:23 +0900 Subject: [PATCH 053/367] =?UTF-8?q?refactor:=20=EB=B3=80=EC=88=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/review/controller/ReviewController.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index 7059cafa..0efa5eac 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -32,7 +32,8 @@ public String createReview(@Valid ReviewRequest reviewRequest, @RequestParam(val @GetMapping("/list/{reviewId}") public String showReview(@PathVariable Long reviewId, Model model){ - model.addAttribute("reviewRes", reviewService.showReview(reviewId)); + ReviewResponse reviewResponse = reviewService.showReview(reviewId); + model.addAttribute("reviewResponse", reviewResponse); return ""; } From 96a0f218eb296bf615a124c2a7b274d4fd6d2406 Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Mon, 29 May 2023 15:35:30 +0900 Subject: [PATCH 054/367] =?UTF-8?q?feat:=20CartItem=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/cart/entity/CartItem.java | 40 +++++++++++++++++++ .../cart/repository/CartItemRepository.java | 7 ++++ 2 files changed, 47 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java create mode 100644 src/main/java/project/trendpick_pro/domain/cart/repository/CartItemRepository.java diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java new file mode 100644 index 00000000..ea359f94 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java @@ -0,0 +1,40 @@ +package project.trendpick_pro.domain.cart.entity; + +import jakarta.persistence.*; +import lombok.*; +import project.trendpick_pro.domain.product.entity.ProductOption; + +import java.util.Optional; + +@Entity +@Getter +@Setter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class CartItem { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "cart_id") + private Cart cart; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "product_option_id") + private ProductOption productOption; + + private int count; // 해당 상품 수량 + + private int price; // 해당 상품 금액 + + @Builder + public CartItem(Cart cart, ProductOption productOption, int count) { + this.cart = cart; + this.productOption = productOption; + this.count = count; + this.price = productOption.getProduct().getPrice(); + } + + +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/repository/CartItemRepository.java b/src/main/java/project/trendpick_pro/domain/cart/repository/CartItemRepository.java new file mode 100644 index 00000000..034fa1fe --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/cart/repository/CartItemRepository.java @@ -0,0 +1,7 @@ +package project.trendpick_pro.domain.cart.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.cart.entity.CartItem; + +public interface CartItemRepository extends JpaRepository { +} From 06fe9f95e2cc4869b52d1e28899683673e66ef45 Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Mon, 29 May 2023 15:39:50 +0900 Subject: [PATCH 055/367] =?UTF-8?q?feat:=20cart=20=EA=B8=B0=EB=B3=B8?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cart/controller/CartController.java | 44 ++++++++++- .../domain/cart/entity/Cart.java | 78 +++++++++++++++++-- .../cart/repository/CartRepository.java | 1 + .../domain/cart/service/CartService.java | 60 ++++++++++++++ 4 files changed, 176 insertions(+), 7 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java index 31f4b3bc..c1e2668d 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java +++ b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java @@ -1,4 +1,46 @@ package project.trendpick_pro.domain.cart.controller; +import jakarta.servlet.http.HttpSession; +import lombok.extern.slf4j.Slf4j; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import project.trendpick_pro.domain.cart.service.CartService; + +@Slf4j +@Controller +@RequestMapping("/trendpick/cart") public class CartController { -} + private final CartService cartService; + + public CartController(CartService cartService) { + this.cartService = cartService; + } + + @PostMapping("/add") + public String addItemToCart(@RequestParam("productOptionId") Long productOptionId, + @RequestParam("count") int count, + HttpSession session) { + // User user = (User) session.getAttribute("user"); + cartService.addItemToCart(user, productOptionId, count); + return "redirect:/trendpick/cart"; + } + + @PostMapping("/remove") + public String removeItemFromCart(@RequestParam("cartItemId") Long cartItemId, + HttpSession session) { + // User user = (User) session.getAttribute("user"); + cartService.removeItemFromCart(user, cartItemId); + return "redirect:/trendpick/cart"; + } + + @PostMapping("/update") + public String updateCartItemQuantity(@RequestParam("cartItemId") Long cartItemId, + @RequestParam("count") int count, + HttpSession session) { + // User user = (User) session.getAttribute("user"); + cartService.updateItemCount(user, cartItemId, count); + return "redirect:/trendpick/cart"; + } +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java index 7380ef2e..d80cfedb 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java @@ -4,10 +4,17 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import lombok.Setter; +import org.springframework.security.core.userdetails.User; +import project.trendpick_pro.domain.product.entity.ProductOption; + +import java.util.ArrayList; +import java.util.List; @Entity @Getter +@Setter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Cart { @Id @@ -15,11 +22,70 @@ public class Cart { @Column(name = "cart_id") private Long id; - private int totalCount; // 총 수량 + //@OneToOne(fetch = FetchType.LAZY) + // @JoinColumn(name = "user_id") + // private User user; + + @OneToMany(mappedBy = "cart", cascade = CascadeType.ALL, orphanRemoval = true) + private List cartItems = new ArrayList<>(); + + // 총 수량 필드 + private int totalCount; + + // 총 가격 필드 + private int totalPrice; + + public Cart(User user) { + //this.user = user; + } + + // CartItem 추가 + public void addItem(CartItem cartItem) { + cartItems.add(cartItem); + cartItem.setCart(this); + updateTotalCountAndPrice(); + } + + // CartItem 삭제 + public void removeItem(Long cartItemId) { + CartItem cartItem = findCartItemById(cartItemId); + if (cartItem != null) { + cartItems.remove(cartItem); + updateTotalCountAndPrice(); + } + } + + + // CartItem 수량 변경 + public void updateItemCount(Long cartItemId, int count) { + CartItem cartItem = findCartItemById(cartItemId); + if (cartItem != null) { + cartItem.setCount(count); + updateTotalCountAndPrice(); + } + } + + private CartItem findCartItemById(Long cartItemId) { + return cartItems.stream() + .filter(item -> item.getId().equals(cartItemId)) + .findFirst() + .orElse(null); + } + + private void updateTotalCountAndPrice() { + totalCount = cartItems.stream() + .mapToInt(CartItem::getCount) + .sum(); - // @ManyToOne(fetch = FetchType.LAZY) - // @JoinColumn(name = "user_id") - private String user_id; // user + totalPrice = cartItems.stream() + .mapToInt(CartItem::getPrice) + .sum(); + } - private int totalPrice; // 총 금액 -} + public CartItem findCartItemByProductOption(ProductOption productOption) { + return cartItems.stream() + .filter(item -> item.getProductOption().equals(productOption)) + .findFirst() + .orElse(null); + } +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java b/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java index eb61cf71..6263e279 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java +++ b/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java @@ -4,4 +4,5 @@ import project.trendpick_pro.domain.cart.entity.Cart; public interface CartRepository extends JpaRepository { + Cart findByUserId(Long userId); } diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index 77312e6a..43f43a2b 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -1,4 +1,64 @@ package project.trendpick_pro.domain.cart.service; +import org.springframework.security.core.userdetails.User; +import org.springframework.stereotype.Service; +import project.trendpick_pro.domain.cart.entity.Cart; +import project.trendpick_pro.domain.cart.entity.CartItem; +import project.trendpick_pro.domain.cart.repository.CartRepository; +import project.trendpick_pro.domain.product.entity.ProductOption; +import project.trendpick_pro.domain.product.repository.ProductOptionRepository; + + +@Service public class CartService { + + private final CartRepository cartRepository; + private final ProductOptionRepository productOptionRepository; + + public CartService(CartRepository cartRepository, ProductOptionRepository productOptionRepository) { + this.cartRepository = cartRepository; + this.productOptionRepository = productOptionRepository; + } + + public Cart createCart(User user) { + Cart cart = new Cart(user); + return cartRepository.save(cart); + } + + public void addItemToCart(User user, Long productOptionId, int count) { + Cart cart = getCartByUser(user); + ProductOption productOption = getProductOptionById(productOptionId); + + CartItem cartItem = cart.findCartItemByProductOption(productOption); + + + if (cartItem != null) { + // 이미 카트에 해당 상품이 존재하는 경우, 수량을 증가 + cartItem.setCount(cartItem.getCount() + count); + } else { + // 카트에 해당 상품이 없는 경우, 새로운 카트 아이템을 생성하여 추가 + cartItem = new CartItem(cart, productOption, count); + cart.addItem(cartItem); + } + } + + // 상품을 장바구니에서 제거 + public void removeItemFromCart(User user, Long cartItemId) { + Cart cart = getCartByUser(user); + cart.removeItem(cartItemId); + } + + // 상품의 수량 업데이트 + public void updateItemCount(User user, Long cartItemId, int count) { + Cart cart = getCartByUser(user); + cart.updateItemCount(cartItemId, count); + } + + public Cart getCartByUser(User user) { + // return cartRepository.findByUser(user); + } + + private ProductOption getProductOptionById(Long productOptionId) { + // return productOptionRepository.findById(productOptionId); + } } From 7c6f45349f581e0bdaac05bd886277435aa8b12b Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Mon, 29 May 2023 15:59:44 +0900 Subject: [PATCH 056/367] =?UTF-8?q?refactor:=20QFile=EC=9D=84=20ignore?= =?UTF-8?q?=ED=95=A9=EB=8B=88=EB=8B=A4.=20(#47)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 + .../domain/answer/entity/QAnswer.java | 63 ---------------- .../entity/dto/response/QAnswerResponse.java | 21 ------ .../trendpick_pro/domain/ask/entity/QAsk.java | 56 -------------- .../ask/entity/dto/response/QAskResponse.java | 21 ------ .../domain/brand/entity/QBrand.java | 39 ---------- .../domain/cart/entity/QCart.java | 43 ----------- .../domain/common/base/QBaseTimeEntity.java | 39 ---------- .../domain/common/file/QCommonFile.java | 55 -------------- .../domain/delivery/entity/QDelivery.java | 64 ---------------- .../delivery/entity/embaded/QAddress.java | 41 ---------- .../domain/member/entity/QMember.java | 55 -------------- .../domain/member/entity/QUser.java | 55 -------------- .../notification/entity/QNotification.java | 43 ----------- .../domain/orders/entity/QOrder.java | 68 ----------------- .../domain/orders/entity/QOrderItem.java | 58 -------------- .../entity/dto/response/QOrderResponse.java | 21 ------ .../domain/product/entity/QProduct.java | 75 ------------------- .../dto/response/QProductListResponse.java | 21 ------ .../entity/dto/response/QProductResponse.java | 21 ------ .../domain/review/entity/QReview.java | 53 ------------- .../trendpick_pro/domain/tag/entity/QTag.java | 53 ------------- 22 files changed, 3 insertions(+), 965 deletions(-) delete mode 100644 src/main/generated/project/trendpick_pro/domain/answer/entity/QAnswer.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/answer/entity/dto/response/QAnswerResponse.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/ask/entity/QAsk.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/ask/entity/dto/response/QAskResponse.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/brand/entity/QBrand.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/cart/entity/QCart.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/common/base/QBaseTimeEntity.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/common/file/QCommonFile.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/delivery/entity/embaded/QAddress.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/member/entity/QMember.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/member/entity/QUser.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/notification/entity/QNotification.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/orders/entity/QOrder.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/orders/entity/QOrderItem.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/orders/entity/dto/response/QOrderResponse.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/product/entity/QProduct.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductListResponse.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductResponse.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/review/entity/QReview.java delete mode 100644 src/main/generated/project/trendpick_pro/domain/tag/entity/QTag.java diff --git a/.gitignore b/.gitignore index 9980efe4..c4f58907 100644 --- a/.gitignore +++ b/.gitignore @@ -38,3 +38,6 @@ out/ ### secret yml ### src/main/resources/application-secret.yml + +### generated ### +src/main/generated diff --git a/src/main/generated/project/trendpick_pro/domain/answer/entity/QAnswer.java b/src/main/generated/project/trendpick_pro/domain/answer/entity/QAnswer.java deleted file mode 100644 index 65dd2c5f..00000000 --- a/src/main/generated/project/trendpick_pro/domain/answer/entity/QAnswer.java +++ /dev/null @@ -1,63 +0,0 @@ -package project.trendpick_pro.domain.answer.entity; - -import static com.querydsl.core.types.PathMetadataFactory.*; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.PathMetadata; -import javax.annotation.processing.Generated; -import com.querydsl.core.types.Path; -import com.querydsl.core.types.dsl.PathInits; - - -/** - * QAnswer is a Querydsl query type for Answer - */ -@Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QAnswer extends EntityPathBase { - - private static final long serialVersionUID = -301394004L; - - private static final PathInits INITS = PathInits.DIRECT2; - - public static final QAnswer answer = new QAnswer("answer"); - - public final project.trendpick_pro.domain.common.base.QBaseTimeEntity _super = new project.trendpick_pro.domain.common.base.QBaseTimeEntity(this); - - public final project.trendpick_pro.domain.ask.entity.QAsk ask; - - public final StringPath author = createString("author"); - - public final StringPath content = createString("content"); - - //inherited - public final DateTimePath createdDate = _super.createdDate; - - public final NumberPath id = createNumber("id", Long.class); - - //inherited - public final DateTimePath modifiedDate = _super.modifiedDate; - - public QAnswer(String variable) { - this(Answer.class, forVariable(variable), INITS); - } - - public QAnswer(Path path) { - this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); - } - - public QAnswer(PathMetadata metadata) { - this(metadata, PathInits.getFor(metadata, INITS)); - } - - public QAnswer(PathMetadata metadata, PathInits inits) { - this(Answer.class, metadata, inits); - } - - public QAnswer(Class type, PathMetadata metadata, PathInits inits) { - super(type, metadata, inits); - this.ask = inits.isInitialized("ask") ? new project.trendpick_pro.domain.ask.entity.QAsk(forProperty("ask")) : null; - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/answer/entity/dto/response/QAnswerResponse.java b/src/main/generated/project/trendpick_pro/domain/answer/entity/dto/response/QAnswerResponse.java deleted file mode 100644 index 57ddb215..00000000 --- a/src/main/generated/project/trendpick_pro/domain/answer/entity/dto/response/QAnswerResponse.java +++ /dev/null @@ -1,21 +0,0 @@ -package project.trendpick_pro.domain.answer.entity.dto.response; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.ConstructorExpression; -import javax.annotation.processing.Generated; - -/** - * project.trendpick_pro.domain.answer.entity.dto.response.QAnswerResponse is a Querydsl Projection type for AnswerResponse - */ -@Generated("com.querydsl.codegen.DefaultProjectionSerializer") -public class QAnswerResponse extends ConstructorExpression { - - private static final long serialVersionUID = -2046614161L; - - public QAnswerResponse(com.querydsl.core.types.Expression id, com.querydsl.core.types.Expression author, com.querydsl.core.types.Expression ask, com.querydsl.core.types.Expression content, com.querydsl.core.types.Expression createdDate, com.querydsl.core.types.Expression modifiedDate) { - super(AnswerResponse.class, new Class[]{long.class, String.class, project.trendpick_pro.domain.ask.entity.Ask.class, String.class, java.time.LocalDateTime.class, java.time.LocalDateTime.class}, id, author, ask, content, createdDate, modifiedDate); - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/ask/entity/QAsk.java b/src/main/generated/project/trendpick_pro/domain/ask/entity/QAsk.java deleted file mode 100644 index f96f456b..00000000 --- a/src/main/generated/project/trendpick_pro/domain/ask/entity/QAsk.java +++ /dev/null @@ -1,56 +0,0 @@ -package project.trendpick_pro.domain.ask.entity; - -import static com.querydsl.core.types.PathMetadataFactory.*; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.PathMetadata; -import javax.annotation.processing.Generated; -import com.querydsl.core.types.Path; -import com.querydsl.core.types.dsl.PathInits; - - -/** - * QAsk is a Querydsl query type for Ask - */ -@Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QAsk extends EntityPathBase { - - private static final long serialVersionUID = -658585546L; - - public static final QAsk ask = new QAsk("ask"); - - public final project.trendpick_pro.domain.common.base.QBaseTimeEntity _super = new project.trendpick_pro.domain.common.base.QBaseTimeEntity(this); - - public final ListPath answerList = this.createList("answerList", project.trendpick_pro.domain.answer.entity.Answer.class, project.trendpick_pro.domain.answer.entity.QAnswer.class, PathInits.DIRECT2); - - public final StringPath author = createString("author"); - - public final StringPath brand = createString("brand"); - - public final StringPath content = createString("content"); - - //inherited - public final DateTimePath createdDate = _super.createdDate; - - public final NumberPath id = createNumber("id", Long.class); - - //inherited - public final DateTimePath modifiedDate = _super.modifiedDate; - - public final StringPath title = createString("title"); - - public QAsk(String variable) { - super(Ask.class, forVariable(variable)); - } - - public QAsk(Path path) { - super(path.getType(), path.getMetadata()); - } - - public QAsk(PathMetadata metadata) { - super(Ask.class, metadata); - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/ask/entity/dto/response/QAskResponse.java b/src/main/generated/project/trendpick_pro/domain/ask/entity/dto/response/QAskResponse.java deleted file mode 100644 index 66b799b8..00000000 --- a/src/main/generated/project/trendpick_pro/domain/ask/entity/dto/response/QAskResponse.java +++ /dev/null @@ -1,21 +0,0 @@ -package project.trendpick_pro.domain.ask.entity.dto.response; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.ConstructorExpression; -import javax.annotation.processing.Generated; - -/** - * project.trendpick_pro.domain.ask.entity.dto.response.QAskResponse is a Querydsl Projection type for AskResponse - */ -@Generated("com.querydsl.codegen.DefaultProjectionSerializer") -public class QAskResponse extends ConstructorExpression { - - private static final long serialVersionUID = 1378042495L; - - public QAskResponse(com.querydsl.core.types.Expression id, com.querydsl.core.types.Expression author, com.querydsl.core.types.Expression brand, com.querydsl.core.types.Expression title, com.querydsl.core.types.Expression content, com.querydsl.core.types.Expression> answerList, com.querydsl.core.types.Expression createdDate, com.querydsl.core.types.Expression modifiedDate) { - super(AskResponse.class, new Class[]{long.class, String.class, String.class, String.class, String.class, java.util.List.class, java.time.LocalDateTime.class, java.time.LocalDateTime.class}, id, author, brand, title, content, answerList, createdDate, modifiedDate); - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/brand/entity/QBrand.java b/src/main/generated/project/trendpick_pro/domain/brand/entity/QBrand.java deleted file mode 100644 index 1dde8ecc..00000000 --- a/src/main/generated/project/trendpick_pro/domain/brand/entity/QBrand.java +++ /dev/null @@ -1,39 +0,0 @@ -package project.trendpick_pro.domain.brand.entity; - -import static com.querydsl.core.types.PathMetadataFactory.*; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.PathMetadata; -import javax.annotation.processing.Generated; -import com.querydsl.core.types.Path; - - -/** - * QBrand is a Querydsl query type for Brand - */ -@Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QBrand extends EntityPathBase { - - private static final long serialVersionUID = -1703904522L; - - public static final QBrand brand = new QBrand("brand"); - - public final NumberPath id = createNumber("id", Long.class); - - public final StringPath name = createString("name"); - - public QBrand(String variable) { - super(Brand.class, forVariable(variable)); - } - - public QBrand(Path path) { - super(path.getType(), path.getMetadata()); - } - - public QBrand(PathMetadata metadata) { - super(Brand.class, metadata); - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/cart/entity/QCart.java b/src/main/generated/project/trendpick_pro/domain/cart/entity/QCart.java deleted file mode 100644 index 43b1b8a3..00000000 --- a/src/main/generated/project/trendpick_pro/domain/cart/entity/QCart.java +++ /dev/null @@ -1,43 +0,0 @@ -package project.trendpick_pro.domain.cart.entity; - -import static com.querydsl.core.types.PathMetadataFactory.*; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.PathMetadata; -import javax.annotation.processing.Generated; -import com.querydsl.core.types.Path; - - -/** - * QCart is a Querydsl query type for Cart - */ -@Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QCart extends EntityPathBase { - - private static final long serialVersionUID = 1014572976L; - - public static final QCart cart = new QCart("cart"); - - public final NumberPath id = createNumber("id", Long.class); - - public final NumberPath totalCount = createNumber("totalCount", Integer.class); - - public final NumberPath totalPrice = createNumber("totalPrice", Integer.class); - - public final StringPath user_id = createString("user_id"); - - public QCart(String variable) { - super(Cart.class, forVariable(variable)); - } - - public QCart(Path path) { - super(path.getType(), path.getMetadata()); - } - - public QCart(PathMetadata metadata) { - super(Cart.class, metadata); - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/common/base/QBaseTimeEntity.java b/src/main/generated/project/trendpick_pro/domain/common/base/QBaseTimeEntity.java deleted file mode 100644 index d5f22f2f..00000000 --- a/src/main/generated/project/trendpick_pro/domain/common/base/QBaseTimeEntity.java +++ /dev/null @@ -1,39 +0,0 @@ -package project.trendpick_pro.domain.common.base; - -import static com.querydsl.core.types.PathMetadataFactory.*; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.PathMetadata; -import javax.annotation.processing.Generated; -import com.querydsl.core.types.Path; - - -/** - * QBaseTimeEntity is a Querydsl query type for BaseTimeEntity - */ -@Generated("com.querydsl.codegen.DefaultSupertypeSerializer") -public class QBaseTimeEntity extends EntityPathBase { - - private static final long serialVersionUID = 1434919534L; - - public static final QBaseTimeEntity baseTimeEntity = new QBaseTimeEntity("baseTimeEntity"); - - public final DateTimePath createdDate = createDateTime("createdDate", java.time.LocalDateTime.class); - - public final DateTimePath modifiedDate = createDateTime("modifiedDate", java.time.LocalDateTime.class); - - public QBaseTimeEntity(String variable) { - super(BaseTimeEntity.class, forVariable(variable)); - } - - public QBaseTimeEntity(Path path) { - super(path.getType(), path.getMetadata()); - } - - public QBaseTimeEntity(PathMetadata metadata) { - super(BaseTimeEntity.class, metadata); - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/common/file/QCommonFile.java b/src/main/generated/project/trendpick_pro/domain/common/file/QCommonFile.java deleted file mode 100644 index 8c640492..00000000 --- a/src/main/generated/project/trendpick_pro/domain/common/file/QCommonFile.java +++ /dev/null @@ -1,55 +0,0 @@ -package project.trendpick_pro.domain.common.file; - -import static com.querydsl.core.types.PathMetadataFactory.*; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.PathMetadata; -import javax.annotation.processing.Generated; -import com.querydsl.core.types.Path; -import com.querydsl.core.types.dsl.PathInits; - - -/** - * QCommonFile is a Querydsl query type for CommonFile - */ -@Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QCommonFile extends EntityPathBase { - - private static final long serialVersionUID = 30214313L; - - private static final PathInits INITS = PathInits.DIRECT2; - - public static final QCommonFile commonFile = new QCommonFile("commonFile"); - - public final ListPath child = this.createList("child", CommonFile.class, QCommonFile.class, PathInits.DIRECT2); - - public final StringPath FileName = createString("FileName"); - - public final NumberPath id = createNumber("id", Long.class); - - public final QCommonFile parent; - - public QCommonFile(String variable) { - this(CommonFile.class, forVariable(variable), INITS); - } - - public QCommonFile(Path path) { - this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); - } - - public QCommonFile(PathMetadata metadata) { - this(metadata, PathInits.getFor(metadata, INITS)); - } - - public QCommonFile(PathMetadata metadata, PathInits inits) { - this(CommonFile.class, metadata, inits); - } - - public QCommonFile(Class type, PathMetadata metadata, PathInits inits) { - super(type, metadata, inits); - this.parent = inits.isInitialized("parent") ? new QCommonFile(forProperty("parent"), inits.get("parent")) : null; - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java b/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java deleted file mode 100644 index fa37ed14..00000000 --- a/src/main/generated/project/trendpick_pro/domain/delivery/entity/QDelivery.java +++ /dev/null @@ -1,64 +0,0 @@ -package project.trendpick_pro.domain.delivery.entity; - -import static com.querydsl.core.types.PathMetadataFactory.*; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.PathMetadata; -import javax.annotation.processing.Generated; -import com.querydsl.core.types.Path; -import com.querydsl.core.types.dsl.PathInits; - - -/** - * QDelivery is a Querydsl query type for Delivery - */ -@Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QDelivery extends EntityPathBase { - - private static final long serialVersionUID = 436500440L; - - private static final PathInits INITS = PathInits.DIRECT2; - - public static final QDelivery delivery = new QDelivery("delivery"); - - public final project.trendpick_pro.domain.common.base.QBaseTimeEntity _super = new project.trendpick_pro.domain.common.base.QBaseTimeEntity(this); - - public final project.trendpick_pro.domain.delivery.entity.embaded.QAddress address; - - //inherited - public final DateTimePath createdDate = _super.createdDate; - - public final NumberPath id = createNumber("id", Long.class); - - //inherited - public final DateTimePath modifiedDate = _super.modifiedDate; - - public final project.trendpick_pro.domain.orders.entity.QOrder order; - - public final EnumPath state = createEnum("state", DeliveryState.class); - - public QDelivery(String variable) { - this(Delivery.class, forVariable(variable), INITS); - } - - public QDelivery(Path path) { - this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); - } - - public QDelivery(PathMetadata metadata) { - this(metadata, PathInits.getFor(metadata, INITS)); - } - - public QDelivery(PathMetadata metadata, PathInits inits) { - this(Delivery.class, metadata, inits); - } - - public QDelivery(Class type, PathMetadata metadata, PathInits inits) { - super(type, metadata, inits); - this.address = inits.isInitialized("address") ? new project.trendpick_pro.domain.delivery.entity.embaded.QAddress(forProperty("address")) : null; - this.order = inits.isInitialized("order") ? new project.trendpick_pro.domain.orders.entity.QOrder(forProperty("order"), inits.get("order")) : null; - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/delivery/entity/embaded/QAddress.java b/src/main/generated/project/trendpick_pro/domain/delivery/entity/embaded/QAddress.java deleted file mode 100644 index f68fa269..00000000 --- a/src/main/generated/project/trendpick_pro/domain/delivery/entity/embaded/QAddress.java +++ /dev/null @@ -1,41 +0,0 @@ -package project.trendpick_pro.domain.delivery.entity.embaded; - -import static com.querydsl.core.types.PathMetadataFactory.*; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.PathMetadata; -import javax.annotation.processing.Generated; -import com.querydsl.core.types.Path; - - -/** - * QAddress is a Querydsl query type for Address - */ -@Generated("com.querydsl.codegen.DefaultEmbeddableSerializer") -public class QAddress extends BeanPath
{ - - private static final long serialVersionUID = -588872866L; - - public static final QAddress address = new QAddress("address"); - - public final StringPath city = createString("city"); - - public final StringPath street = createString("street"); - - public final StringPath zipcode = createString("zipcode"); - - public QAddress(String variable) { - super(Address.class, forVariable(variable)); - } - - public QAddress(Path path) { - super(path.getType(), path.getMetadata()); - } - - public QAddress(PathMetadata metadata) { - super(Address.class, metadata); - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/member/entity/QMember.java b/src/main/generated/project/trendpick_pro/domain/member/entity/QMember.java deleted file mode 100644 index 836d8fb9..00000000 --- a/src/main/generated/project/trendpick_pro/domain/member/entity/QMember.java +++ /dev/null @@ -1,55 +0,0 @@ -package project.trendpick_pro.domain.member.entity; - -import static com.querydsl.core.types.PathMetadataFactory.*; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.PathMetadata; -import javax.annotation.processing.Generated; -import com.querydsl.core.types.Path; - - -/** - * QMember is a Querydsl query type for Member - */ -@Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QMember extends EntityPathBase { - - private static final long serialVersionUID = 1765768292L; - - public static final QMember member = new QMember("member1"); - - public final NumberPath account = createNumber("account", Long.class); - - public final StringPath bank_name = createString("bank_name"); - - public final DateTimePath birth = createDateTime("birth", java.util.Date.class); - - public final StringPath email = createString("email"); - - public final NumberPath id = createNumber("id", Long.class); - - public final StringPath password = createString("password"); - - public final StringPath phone_num = createString("phone_num"); - - public final EnumPath role = createEnum("role", RoleType.class); - - public final NumberPath tag_id = createNumber("tag_id", Long.class); - - public final StringPath username = createString("username"); - - public QMember(String variable) { - super(Member.class, forVariable(variable)); - } - - public QMember(Path path) { - super(path.getType(), path.getMetadata()); - } - - public QMember(PathMetadata metadata) { - super(Member.class, metadata); - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/member/entity/QUser.java b/src/main/generated/project/trendpick_pro/domain/member/entity/QUser.java deleted file mode 100644 index cdb35e11..00000000 --- a/src/main/generated/project/trendpick_pro/domain/member/entity/QUser.java +++ /dev/null @@ -1,55 +0,0 @@ -package project.trendpick_pro.domain.member.entity; - -import static com.querydsl.core.types.PathMetadataFactory.*; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.PathMetadata; -import javax.annotation.processing.Generated; -import com.querydsl.core.types.Path; - - -/** - * QUser is a Querydsl query type for User - */ -@Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QUser extends EntityPathBase { - - private static final long serialVersionUID = 350707846L; - - public static final QUser user = new QUser("user"); - - public final NumberPath account = createNumber("account", Long.class); - - public final StringPath bank_name = createString("bank_name"); - - public final DateTimePath birth = createDateTime("birth", java.util.Date.class); - - public final StringPath email = createString("email"); - - public final NumberPath id = createNumber("id", Long.class); - - public final StringPath name = createString("name"); - - public final StringPath password = createString("password"); - - public final StringPath phone_num = createString("phone_num"); - - public final EnumPath role = createEnum("role", RoleType.class); - - public final NumberPath tag_id = createNumber("tag_id", Long.class); - - public QUser(String variable) { - super(Member.class, forVariable(variable)); - } - - public QUser(Path path) { - super(path.getType(), path.getMetadata()); - } - - public QUser(PathMetadata metadata) { - super(Member.class, metadata); - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/notification/entity/QNotification.java b/src/main/generated/project/trendpick_pro/domain/notification/entity/QNotification.java deleted file mode 100644 index 56e465f2..00000000 --- a/src/main/generated/project/trendpick_pro/domain/notification/entity/QNotification.java +++ /dev/null @@ -1,43 +0,0 @@ -package project.trendpick_pro.domain.notification.entity; - -import static com.querydsl.core.types.PathMetadataFactory.*; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.PathMetadata; -import javax.annotation.processing.Generated; -import com.querydsl.core.types.Path; - - -/** - * QNotification is a Querydsl query type for Notification - */ -@Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QNotification extends EntityPathBase { - - private static final long serialVersionUID = 483531974L; - - public static final QNotification notification = new QNotification("notification"); - - public final StringPath content = createString("content"); - - public final DateTimePath creatDate = createDateTime("creatDate", java.time.LocalDateTime.class); - - public final NumberPath id = createNumber("id", Long.class); - - public final StringPath title = createString("title"); - - public QNotification(String variable) { - super(Notification.class, forVariable(variable)); - } - - public QNotification(Path path) { - super(path.getType(), path.getMetadata()); - } - - public QNotification(PathMetadata metadata) { - super(Notification.class, metadata); - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrder.java b/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrder.java deleted file mode 100644 index dead6577..00000000 --- a/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrder.java +++ /dev/null @@ -1,68 +0,0 @@ -package project.trendpick_pro.domain.orders.entity; - -import static com.querydsl.core.types.PathMetadataFactory.*; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.PathMetadata; -import javax.annotation.processing.Generated; -import com.querydsl.core.types.Path; -import com.querydsl.core.types.dsl.PathInits; - - -/** - * QOrder is a Querydsl query type for Order - */ -@Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QOrder extends EntityPathBase { - - private static final long serialVersionUID = 1734766041L; - - private static final PathInits INITS = PathInits.DIRECT2; - - public static final QOrder order = new QOrder("order1"); - - public final project.trendpick_pro.domain.common.base.QBaseTimeEntity _super = new project.trendpick_pro.domain.common.base.QBaseTimeEntity(this); - - //inherited - public final DateTimePath createdDate = _super.createdDate; - - public final project.trendpick_pro.domain.delivery.entity.QDelivery delivery; - - public final NumberPath id = createNumber("id", Long.class); - - //inherited - public final DateTimePath modifiedDate = _super.modifiedDate; - - public final ListPath orderItems = this.createList("orderItems", OrderItem.class, QOrderItem.class, PathInits.DIRECT2); - - public final EnumPath status = createEnum("status", OrderStatus.class); - - public final NumberPath totalPrice = createNumber("totalPrice", Integer.class); - - public final project.trendpick_pro.domain.user.entity.QUser user; - - public QOrder(String variable) { - this(Order.class, forVariable(variable), INITS); - } - - public QOrder(Path path) { - this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); - } - - public QOrder(PathMetadata metadata) { - this(metadata, PathInits.getFor(metadata, INITS)); - } - - public QOrder(PathMetadata metadata, PathInits inits) { - this(Order.class, metadata, inits); - } - - public QOrder(Class type, PathMetadata metadata, PathInits inits) { - super(type, metadata, inits); - this.delivery = inits.isInitialized("delivery") ? new project.trendpick_pro.domain.delivery.entity.QDelivery(forProperty("delivery"), inits.get("delivery")) : null; - this.user = inits.isInitialized("user") ? new project.trendpick_pro.domain.user.entity.QUser(forProperty("user")) : null; - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrderItem.java b/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrderItem.java deleted file mode 100644 index 50722e65..00000000 --- a/src/main/generated/project/trendpick_pro/domain/orders/entity/QOrderItem.java +++ /dev/null @@ -1,58 +0,0 @@ -package project.trendpick_pro.domain.orders.entity; - -import static com.querydsl.core.types.PathMetadataFactory.*; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.PathMetadata; -import javax.annotation.processing.Generated; -import com.querydsl.core.types.Path; -import com.querydsl.core.types.dsl.PathInits; - - -/** - * QOrderItem is a Querydsl query type for OrderItem - */ -@Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QOrderItem extends EntityPathBase { - - private static final long serialVersionUID = 1350355084L; - - private static final PathInits INITS = PathInits.DIRECT2; - - public static final QOrderItem orderItem = new QOrderItem("orderItem"); - - public final NumberPath count = createNumber("count", Integer.class); - - public final NumberPath id = createNumber("id", Long.class); - - public final QOrder order; - - public final NumberPath orderPrice = createNumber("orderPrice", Integer.class); - - public final project.trendpick_pro.domain.product.entity.QProduct product; - - public QOrderItem(String variable) { - this(OrderItem.class, forVariable(variable), INITS); - } - - public QOrderItem(Path path) { - this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); - } - - public QOrderItem(PathMetadata metadata) { - this(metadata, PathInits.getFor(metadata, INITS)); - } - - public QOrderItem(PathMetadata metadata, PathInits inits) { - this(OrderItem.class, metadata, inits); - } - - public QOrderItem(Class type, PathMetadata metadata, PathInits inits) { - super(type, metadata, inits); - this.order = inits.isInitialized("order") ? new QOrder(forProperty("order"), inits.get("order")) : null; - this.product = inits.isInitialized("product") ? new project.trendpick_pro.domain.product.entity.QProduct(forProperty("product"), inits.get("product")) : null; - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/orders/entity/dto/response/QOrderResponse.java b/src/main/generated/project/trendpick_pro/domain/orders/entity/dto/response/QOrderResponse.java deleted file mode 100644 index 499b41b5..00000000 --- a/src/main/generated/project/trendpick_pro/domain/orders/entity/dto/response/QOrderResponse.java +++ /dev/null @@ -1,21 +0,0 @@ -package project.trendpick_pro.domain.orders.entity.dto.response; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.ConstructorExpression; -import javax.annotation.processing.Generated; - -/** - * project.trendpick_pro.domain.orders.entity.dto.response.QOrderResponse is a Querydsl Projection type for OrderResponse - */ -@Generated("com.querydsl.codegen.DefaultProjectionSerializer") -public class QOrderResponse extends ConstructorExpression { - - private static final long serialVersionUID = 695514566L; - - public QOrderResponse(com.querydsl.core.types.Expression orderId, com.querydsl.core.types.Expression brandName, com.querydsl.core.types.Expression productName, com.querydsl.core.types.Expression order_date, com.querydsl.core.types.Expression totalPrice, com.querydsl.core.types.Expression deliveryStatus) { - super(OrderResponse.class, new Class[]{long.class, String.class, String.class, java.time.LocalDateTime.class, int.class, String.class}, orderId, brandName, productName, order_date, totalPrice, deliveryStatus); - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/product/entity/QProduct.java b/src/main/generated/project/trendpick_pro/domain/product/entity/QProduct.java deleted file mode 100644 index db12180b..00000000 --- a/src/main/generated/project/trendpick_pro/domain/product/entity/QProduct.java +++ /dev/null @@ -1,75 +0,0 @@ -package project.trendpick_pro.domain.product.entity; - -import static com.querydsl.core.types.PathMetadataFactory.*; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.PathMetadata; -import javax.annotation.processing.Generated; -import com.querydsl.core.types.Path; -import com.querydsl.core.types.dsl.PathInits; - - -/** - * QProduct is a Querydsl query type for Product - */ -@Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QProduct extends EntityPathBase { - - private static final long serialVersionUID = -674347658L; - - private static final PathInits INITS = PathInits.DIRECT2; - - public static final QProduct product = new QProduct("product"); - - public final project.trendpick_pro.domain.common.base.QBaseTimeEntity _super = new project.trendpick_pro.domain.common.base.QBaseTimeEntity(this); - - public final StringPath brand = createString("brand"); - - public final project.trendpick_pro.domain.common.file.QCommonFile commonFile; - - //inherited - public final DateTimePath createdDate = _super.createdDate; - - public final StringPath description = createString("description"); - - public final NumberPath id = createNumber("id", Long.class); - - public final StringPath mainCategory = createString("mainCategory"); - - //inherited - public final DateTimePath modifiedDate = _super.modifiedDate; - - public final StringPath name = createString("name"); - - public final NumberPath price = createNumber("price", Integer.class); - - public final NumberPath stock = createNumber("stock", Integer.class); - - public final ListPath subCategory = this.createList("subCategory", String.class, StringPath.class, PathInits.DIRECT2); - - public final ListPath tags = this.createList("tags", project.trendpick_pro.domain.tag.entity.Tag.class, project.trendpick_pro.domain.tag.entity.QTag.class, PathInits.DIRECT2); - - public QProduct(String variable) { - this(Product.class, forVariable(variable), INITS); - } - - public QProduct(Path path) { - this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); - } - - public QProduct(PathMetadata metadata) { - this(metadata, PathInits.getFor(metadata, INITS)); - } - - public QProduct(PathMetadata metadata, PathInits inits) { - this(Product.class, metadata, inits); - } - - public QProduct(Class type, PathMetadata metadata, PathInits inits) { - super(type, metadata, inits); - this.commonFile = inits.isInitialized("commonFile") ? new project.trendpick_pro.domain.common.file.QCommonFile(forProperty("commonFile"), inits.get("commonFile")) : null; - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductListResponse.java b/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductListResponse.java deleted file mode 100644 index fc126ba1..00000000 --- a/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductListResponse.java +++ /dev/null @@ -1,21 +0,0 @@ -package project.trendpick_pro.domain.product.entity.dto.response; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.ConstructorExpression; -import javax.annotation.processing.Generated; - -/** - * project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse is a Querydsl Projection type for ProductListResponse - */ -@Generated("com.querydsl.codegen.DefaultProjectionSerializer") -public class QProductListResponse extends ConstructorExpression { - - private static final long serialVersionUID = -1483401431L; - - public QProductListResponse(com.querydsl.core.types.Expression id, com.querydsl.core.types.Expression name, com.querydsl.core.types.Expression brand, com.querydsl.core.types.Expression mainFile, com.querydsl.core.types.Expression price) { - super(ProductListResponse.class, new Class[]{long.class, String.class, String.class, project.trendpick_pro.domain.common.file.CommonFile.class, int.class}, id, name, brand, mainFile, price); - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductResponse.java b/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductResponse.java deleted file mode 100644 index 7c562c87..00000000 --- a/src/main/generated/project/trendpick_pro/domain/product/entity/dto/response/QProductResponse.java +++ /dev/null @@ -1,21 +0,0 @@ -package project.trendpick_pro.domain.product.entity.dto.response; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.ConstructorExpression; -import javax.annotation.processing.Generated; - -/** - * project.trendpick_pro.domain.product.entity.dto.response.QProductResponse is a Querydsl Projection type for ProductResponse - */ -@Generated("com.querydsl.codegen.DefaultProjectionSerializer") -public class QProductResponse extends ConstructorExpression { - - private static final long serialVersionUID = -274979477L; - - public QProductResponse(com.querydsl.core.types.Expression id, com.querydsl.core.types.Expression name, com.querydsl.core.types.Expression mainCategory, com.querydsl.core.types.Expression> subCategory, com.querydsl.core.types.Expression brand, com.querydsl.core.types.Expression description, com.querydsl.core.types.Expression mainFile, com.querydsl.core.types.Expression> subFiles, com.querydsl.core.types.Expression price, com.querydsl.core.types.Expression stock, com.querydsl.core.types.Expression> tags) { - super(ProductResponse.class, new Class[]{long.class, String.class, String.class, java.util.List.class, String.class, String.class, String.class, java.util.List.class, int.class, int.class, java.util.List.class}, id, name, mainCategory, subCategory, brand, description, mainFile, subFiles, price, stock, tags); - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/review/entity/QReview.java b/src/main/generated/project/trendpick_pro/domain/review/entity/QReview.java deleted file mode 100644 index 9f071b6e..00000000 --- a/src/main/generated/project/trendpick_pro/domain/review/entity/QReview.java +++ /dev/null @@ -1,53 +0,0 @@ -package project.trendpick_pro.domain.review.entity; - -import static com.querydsl.core.types.PathMetadataFactory.*; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.PathMetadata; -import javax.annotation.processing.Generated; -import com.querydsl.core.types.Path; - - -/** - * QReview is a Querydsl query type for Review - */ -@Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QReview extends EntityPathBase { - - private static final long serialVersionUID = -687591072L; - - public static final QReview review = new QReview("review"); - - public final project.trendpick_pro.domain.common.base.QBaseTimeEntity _super = new project.trendpick_pro.domain.common.base.QBaseTimeEntity(this); - - public final StringPath content = createString("content"); - - //inherited - public final DateTimePath createdDate = _super.createdDate; - - public final NumberPath id = createNumber("id", Long.class); - - //inherited - public final DateTimePath modifiedDate = _super.modifiedDate; - - public final NumberPath product_id = createNumber("product_id", Long.class); - - public final NumberPath rating = createNumber("rating", Integer.class); - - public final NumberPath user_id = createNumber("user_id", Long.class); - - public QReview(String variable) { - super(Review.class, forVariable(variable)); - } - - public QReview(Path path) { - super(path.getType(), path.getMetadata()); - } - - public QReview(PathMetadata metadata) { - super(Review.class, metadata); - } - -} - diff --git a/src/main/generated/project/trendpick_pro/domain/tag/entity/QTag.java b/src/main/generated/project/trendpick_pro/domain/tag/entity/QTag.java deleted file mode 100644 index 07cea08f..00000000 --- a/src/main/generated/project/trendpick_pro/domain/tag/entity/QTag.java +++ /dev/null @@ -1,53 +0,0 @@ -package project.trendpick_pro.domain.tag.entity; - -import static com.querydsl.core.types.PathMetadataFactory.*; - -import com.querydsl.core.types.dsl.*; - -import com.querydsl.core.types.PathMetadata; -import javax.annotation.processing.Generated; -import com.querydsl.core.types.Path; -import com.querydsl.core.types.dsl.PathInits; - - -/** - * QTag is a Querydsl query type for Tag - */ -@Generated("com.querydsl.codegen.DefaultEntitySerializer") -public class QTag extends EntityPathBase { - - private static final long serialVersionUID = -1204291178L; - - private static final PathInits INITS = PathInits.DIRECT2; - - public static final QTag tag = new QTag("tag"); - - public final NumberPath id = createNumber("id", Long.class); - - public final StringPath name = createString("name"); - - public final project.trendpick_pro.domain.product.entity.QProduct product; - - public QTag(String variable) { - this(Tag.class, forVariable(variable), INITS); - } - - public QTag(Path path) { - this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); - } - - public QTag(PathMetadata metadata) { - this(metadata, PathInits.getFor(metadata, INITS)); - } - - public QTag(PathMetadata metadata, PathInits inits) { - this(Tag.class, metadata, inits); - } - - public QTag(Class type, PathMetadata metadata, PathInits inits) { - super(type, metadata, inits); - this.product = inits.isInitialized("product") ? new project.trendpick_pro.domain.product.entity.QProduct(forProperty("product"), inits.get("product")) : null; - } - -} - From ac272175b68e761e42f71fe3f0280e34b193d044 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Mon, 29 May 2023 16:00:09 +0900 Subject: [PATCH 057/367] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=20=EB=A1=9C=EC=A7=81=EC=9D=84=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=ED=95=A9=EB=8B=88=EB=8B=A4.=20(#47)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 5 +- .../domain/product/entity/Product.java | 6 +- .../entity/dto/request/ProductSearchCond.java | 15 ++++ .../dto/response/ProductListResponse.java | 4 +- .../entity/dto/response/ProductResponse.java | 6 +- .../product/repository/ProductRepository.java | 2 +- .../repository/ProductRepositoryCustom.java | 11 +++ .../repository/ProductRepositoryImpl.java | 81 +++++++++++++++++++ .../product/service/ProductService.java | 15 ++-- 9 files changed, 128 insertions(+), 17 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSearchCond.java create mode 100644 src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java create mode 100644 src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index eebf5283..80dc247b 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -49,8 +49,9 @@ public String showProduct(@PathVariable Long productId, Model model) { } @GetMapping("/list") - public String showAllProduct(Model model) { - model.addAttribute("productResponse", productService.showAll()); + public String showAllProduct(@RequestParam("page") int offset, @RequestParam("main-category") String mainCategory, + @RequestParam("sub-category") String subCategory, Model model) { + model.addAttribute("productResponse", productService.showAll(offset, mainCategory, mainCategory)); return "/trendpick/products/detailpage"; } } diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index 02686d3e..f0ef4461 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -29,16 +29,16 @@ public class Product extends BaseTimeEntity { private String name; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "main_category_id") + @JoinColumn(name = "main_category_id", nullable = false) private MainCategory mainCategory; // Category @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "sub_category_id") + @JoinColumn(name = "sub_category_id", nullable = false) private SubCategory subCategory; // Category @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "brand_id") + @JoinColumn(name = "brand_id", nullable = false) private Brand brand; @Column(name = "description", nullable = false) diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSearchCond.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSearchCond.java new file mode 100644 index 00000000..41b5c1b0 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSearchCond.java @@ -0,0 +1,15 @@ +package project.trendpick_pro.domain.product.entity.dto.request; + +import lombok.Getter; + +@Getter +public class ProductSearchCond { + + private final String mainCategory; + private final String subCategory; + + public ProductSearchCond(String mainCategory, String subCategory) { + this.mainCategory = mainCategory; + this.subCategory = subCategory; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponse.java index f627b3b0..564685e5 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponse.java @@ -13,11 +13,11 @@ public class ProductListResponse { private Long id; private String name; private String brand; - private CommonFile mainFile; + private String mainFile; private int price; @QueryProjection - public ProductListResponse(Long id, String name, String brand, CommonFile mainFile, int price) { + public ProductListResponse(Long id, String name, String brand, String mainFile, int price) { this.id = id; this.name = name; this.brand = brand; diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java index f5a770aa..8412ee10 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java @@ -50,9 +50,9 @@ public static ProductResponse of (Product product) { return ProductResponse.builder() .id(product.getId()) .name(product.getName()) - .mainCategory(product.getMainCategory()) - .subCategory(product.getSubCategory()) - .brand(product.getBrand()) + .mainCategory(product.getMainCategory().getName()) +// .subCategory(product.getSubCategory().getName()) + .brand(product.getBrand().getName()) .description(product.getDescription()) .mainFile(product.getCommonFile().getFileName()) .subFiles(subFiles(product.getCommonFile().getChild())) diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepository.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepository.java index be72db00..0cecec0a 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepository.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepository.java @@ -3,5 +3,5 @@ import org.springframework.data.jpa.repository.JpaRepository; import project.trendpick_pro.domain.product.entity.Product; -public interface ProductRepository extends JpaRepository { +public interface ProductRepository extends JpaRepository, ProductRepositoryCustom { } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java new file mode 100644 index 00000000..df530166 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java @@ -0,0 +1,11 @@ +package project.trendpick_pro.domain.product.repository; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; +import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; + +public interface ProductRepositoryCustom { + + Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable); +} diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java new file mode 100644 index 00000000..fb6cbcd9 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -0,0 +1,81 @@ +package project.trendpick_pro.domain.product.repository; + +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQuery; +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.support.PageableExecutionUtils; +import project.trendpick_pro.domain.brand.entity.QBrand; +import project.trendpick_pro.domain.category.entity.QMainCategory; +import project.trendpick_pro.domain.category.entity.QSubCategory; +import project.trendpick_pro.domain.common.file.QCommonFile; +import project.trendpick_pro.domain.product.entity.QProduct; +import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; +import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; +import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; +import project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse; + +import java.util.List; + +import static project.trendpick_pro.domain.brand.entity.QBrand.*; +import static project.trendpick_pro.domain.category.entity.QMainCategory.*; +import static project.trendpick_pro.domain.category.entity.QSubCategory.*; +import static project.trendpick_pro.domain.common.file.QCommonFile.commonFile; +import static project.trendpick_pro.domain.product.entity.QProduct.*; + +public class ProductRepositoryImpl implements ProductRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + public ProductRepositoryImpl(EntityManager em) { + this.queryFactory = new JPAQueryFactory(em); + } + + @Override + public Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable) { + List result = queryFactory + .select(new QProductListResponse( + product.id, + product.name, + brand.name, + product.commonFile.FileName, + product.price + )) + .from(product) + .leftJoin(product.mainCategory, mainCategory) + .leftJoin(product.subCategory, subCategory) + .leftJoin(product.brand, brand) + .leftJoin(product.commonFile, commonFile) + .where( + mainCategoryEq(cond), + subCategoryEq(cond) + ) + .offset(0) + .limit(18) + .fetch(); + + JPAQuery count = queryFactory + .select(product.count()) + .from(product) + .leftJoin(product.mainCategory, mainCategory) + .leftJoin(product.subCategory, subCategory) + .leftJoin(product.brand, brand) + .leftJoin(product.commonFile, commonFile) + .where( + mainCategoryEq(cond), + subCategoryEq(cond) + ); + + return PageableExecutionUtils.getPage(result, pageable, count::fetchOne); + } + + private static BooleanExpression mainCategoryEq(ProductSearchCond cond) { + return mainCategory.name.eq(cond.getMainCategory()); + } + + private static BooleanExpression subCategoryEq(ProductSearchCond cond) { + return subCategory.name.eq(cond.getSubCategory()); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index b59bbefb..9206f0da 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -2,6 +2,9 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.brand.entity.Brand; @@ -12,6 +15,8 @@ import project.trendpick_pro.domain.category.repository.SubCategoryRepository; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; +import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; +import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; import project.trendpick_pro.domain.product.repository.ProductRepository; @@ -63,16 +68,14 @@ public ProductResponse show(Long product_id) { return ProductResponse.of(product); } - public List showAll() { + public Page showAll(int offset, String mainCategory, String subCategory) { - List all = productRepository.findAll();// 임시. 나중에 테스트 List responses = new ArrayList<>(); - for (Product product : all) { - responses.add(ProductResponse.of(product)); - } + ProductSearchCond cond = new ProductSearchCond(mainCategory, subCategory); + PageRequest pageable = PageRequest.of(offset, 18); - return responses; + return productRepository.findAllByCategoryId(cond, pageable); } } From 2277662f75967783ab8a30eb5dae05aaafb8a8da Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Mon, 29 May 2023 16:00:30 +0900 Subject: [PATCH 058/367] =?UTF-8?q?refactor:=20=EC=A3=BC=EB=AC=B8=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B5=AC=EB=AC=B8=EC=98=A4=EB=A5=98?= =?UTF-8?q?=EB=A5=BC=20=EC=A3=BC=EC=84=9D=EC=B2=98=EB=A6=AC=ED=95=A9?= =?UTF-8?q?=EB=8B=88=EB=8B=A4.=20(#47)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/orders/contoller/OrderController.java | 8 ++++---- .../domain/orders/repository/OrderRepository.java | 4 ++-- .../domain/orders/service/OrderService.java | 12 ++++++------ .../templates/trendpick/usr/member/orders.html | 10 ++++++++++ 4 files changed, 22 insertions(+), 12 deletions(-) create mode 100644 src/main/resources/templates/trendpick/usr/member/orders.html diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 2d827cbc..23f80927 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -26,21 +26,21 @@ public class OrderController { public String order(@Valid OrderSaveRequest... orderSaveRequests) throws IllegalAccessException { orderService.order(1L, orderSaveRequests); - return "redirect:/orders"; + return "redirect:trendpick/usr/member/orders"; } - @GetMapping("/orders") + @GetMapping("/list") public String orderList(Model model, @Valid OrderSearchCond orderSearchCond) { Page responses = orderService.findAll(orderSearchCond); model.addAttribute("orders", responses); - return "order/orderList"; + return "trendpick/usr/member/orders"; } @PostMapping("/orders/{orderId}/cancel") public String cancelOrder(@PathVariable("orderId") Long orderId) { orderService.cancel(orderId); - return "redirect:/orders"; + return "redirect:trendpick/usr/member/orders"; } } diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java index 1b76547a..4e374976 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java @@ -3,9 +3,9 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.orders.entity.Order; -import project.trendpick_pro.domain.user.entity.User; public interface OrderRepository extends JpaRepository { - Page findAllByUser(User member, Pageable pageable); + Page findAllByUser(Member member, Pageable pageable); } diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 8ce5e553..2cebc813 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -9,16 +9,16 @@ import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.delivery.entity.Delivery; import project.trendpick_pro.domain.delivery.entity.embaded.Address; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.orders.entity.Order; import project.trendpick_pro.domain.orders.entity.OrderItem; import project.trendpick_pro.domain.orders.entity.OrderStatus; import project.trendpick_pro.domain.orders.entity.dto.request.OrderSaveRequest; import project.trendpick_pro.domain.orders.entity.dto.request.OrderSearchCond; -import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; import project.trendpick_pro.domain.orders.repository.OrderRepository; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; -import project.trendpick_pro.domain.member.repository.UserRepository; import java.util.ArrayList; import java.util.List; @@ -30,13 +30,13 @@ public class OrderService { private final OrderRepository orderRepository; - private final UserRepository userRepository; + private final MemberRepository memberRepository; private final ProductRepository productRepository; @Transactional public void order(Long userId, OrderSaveRequest... orderSaveRequests) throws IllegalAccessException { - Member member = userRepository.findById(userId).orElseThrow(() -> new EntityNotFoundException("존재하지 않는 유저 입니다."));// 임시 exception 설정 나중에 할 수도 있고 아닐수도 + Member member = memberRepository.findById(userId).orElseThrow(() -> new EntityNotFoundException("존재하지 않는 유저 입니다."));// 임시 exception 설정 나중에 할 수도 있고 아닐수도 Delivery delivery = new Delivery(Address.of("서울시", "강남대로", "222")); // 임의로 작성 @@ -61,9 +61,9 @@ public void cancel(Long orderId) { //임시 작성 public Page findAll(OrderSearchCond cond) { - User user = userRepository.findById(cond.getUserId()).orElseThrow(); + Member member = memberRepository.findById(cond.getUserId()).orElseThrow(); - Page orderPage = orderRepository.findAllByUser(user, PageRequest.of(0, 10)); + Page orderPage = orderRepository.findAllByUser(member, PageRequest.of(0, 10)); return orderPage; } diff --git a/src/main/resources/templates/trendpick/usr/member/orders.html b/src/main/resources/templates/trendpick/usr/member/orders.html new file mode 100644 index 00000000..566549bd --- /dev/null +++ b/src/main/resources/templates/trendpick/usr/member/orders.html @@ -0,0 +1,10 @@ + + + + + Title + + + + + \ No newline at end of file From f5275bb2afb85971bf8738af5a22a2f73bdfda00 Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Mon, 29 May 2023 16:46:18 +0900 Subject: [PATCH 059/367] =?UTF-8?q?feat:=20Cart=20Dto=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../entity/dto/request/CartItemRequest.java | 15 ++++++++ .../cart/entity/dto/request/CartRequest.java | 14 +++++++ .../entity/dto/response/CartItemResponse.java | 37 +++++++++++++++++++ .../entity/dto/response/CartResponse.java | 29 +++++++++++++++ 4 files changed, 95 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java create mode 100644 src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartRequest.java create mode 100644 src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java create mode 100644 src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java new file mode 100644 index 00000000..13fcfa77 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java @@ -0,0 +1,15 @@ +package project.trendpick_pro.domain.cart.entity.dto.request; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; + +@Getter +public class CartItemRequest { + @NotBlank + private Long productOptionId; + + @Min(1) + private int count; + +} diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartRequest.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartRequest.java new file mode 100644 index 00000000..efe0f263 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartRequest.java @@ -0,0 +1,14 @@ +package project.trendpick_pro.domain.cart.entity.dto.request; + +import jakarta.validation.constraints.Min; +import jakarta.validation.constraints.NotBlank; +import project.trendpick_pro.domain.product.entity.ProductOption; + +public class CartRequest { + @NotBlank + private Long cartItemId; + @NotBlank + private Long productOptionId; + @Min(1) + private int count; +} diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java new file mode 100644 index 00000000..7b8ae2cd --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java @@ -0,0 +1,37 @@ +package project.trendpick_pro.domain.cart.entity.dto.response; + +import com.querydsl.core.annotations.QueryProjection; +import lombok.Builder; +import lombok.Getter; +import project.trendpick_pro.domain.cart.entity.CartItem; + + + +@Getter +public class CartItemResponse { + private Long id; + private Long cartId; + private Long productOptionId; + private String productName; + private int count; + + @Builder + @QueryProjection + public CartItemResponse(Long id, Long cartId, Long productOptionId, String productName, int count) { + this.id = id; + this.cartId = cartId; + this.productOptionId = productOptionId; + this.productName = productName; + this.count = count; + } + + public static CartItemResponse of (CartItem cartItem) { + return CartItemResponse.builder() + .id(cartItem.getId()) + .cartId(cartItem.getCart().getId()) + .productOptionId(cartItem.getProductOption().getId()) + .productName(cartItem.getProductOption().getProduct().getName()) + .count(cartItem.getCount()) + .build(); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java new file mode 100644 index 00000000..6ca43cba --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java @@ -0,0 +1,29 @@ +package project.trendpick_pro.domain.cart.entity.dto.response; + +import com.querydsl.core.annotations.QueryProjection; +import lombok.Builder; +import lombok.Getter; +import project.trendpick_pro.domain.cart.entity.Cart; + +@Getter +public class CartResponse { + private Long id; + + private Long cartItemId; + + private Long productOptionId; + + private int count; + private int price; + + @Builder + @QueryProjection + public CartResponse(Long id, Long cartItemId, long productOptionId, int price, int count) { + this.id = id; + this.cartItemId = cartItemId; + this.productOptionId=productOptionId; + this.price=price; + this.count = count; + } + +} From e94139baf324a60e3654738252c9a5af78319f7d Mon Sep 17 00:00:00 2001 From: jooooonj Date: Mon, 29 May 2023 17:24:01 +0900 Subject: [PATCH 060/367] =?UTF-8?q?ask,=20answer=20=EC=A0=9C=EB=8C=80?= =?UTF-8?q?=EB=A1=9C=20=EB=A7=B5=ED=95=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../answer/controller/AnswerController.java | 5 ++++- .../domain/answer/entity/Answer.java | 4 +--- .../entity/dto/response/AnswerResponse.java | 12 +----------- .../domain/answer/service/AnswerService.java | 5 +++-- .../domain/ask/controller/AskController.java | 2 ++ .../trendpick_pro/domain/ask/entity/Ask.java | 18 ++++++++++-------- .../ask/entity/dto/response/AskResponse.java | 15 +++++++-------- src/main/resources/application.yml | 16 ++++++++-------- 8 files changed, 36 insertions(+), 41 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java index eae51241..40a296e7 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java +++ b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java @@ -6,17 +6,20 @@ import org.springframework.web.bind.annotation.*; import project.trendpick_pro.domain.answer.entity.dto.request.AnswerRequest; import project.trendpick_pro.domain.answer.service.AnswerService; +import project.trendpick_pro.domain.common.base.rq.Rq; +import project.trendpick_pro.domain.member.entity.Member; @Controller @RequiredArgsConstructor @RequestMapping("/trendpick/customerservice/asks/{askId}/answers") public class AnswerController { private final AnswerService answerService; + private final Rq rq; @PostMapping("/register") public String registerAnswer(@PathVariable Long askId, @Valid AnswerRequest answerRequest){ - String member = "member"; //Member + Member member = rq.getMember(); answerService.register(askId, member, answerRequest); return "redirect:/trendpick/customerservice/asks/{askId}".formatted(askId); diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java b/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java index b4d03c00..03bb678f 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java +++ b/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java @@ -25,7 +25,6 @@ public class Answer extends BaseTimeEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "answer_id") private Long id; - private String author; //멤버 엔티티와 맵핑 해줘야 한다. (임시 String) @ManyToOne @JoinColumn(name = "ask_id") @@ -33,10 +32,9 @@ public class Answer extends BaseTimeEntity { private String content; - public static Answer write(Ask ask, String member, AnswerRequest answerRequest) { + public static Answer write(Ask ask, AnswerRequest answerRequest) { Answer answer = Answer .builder() - .author(member) //Member .ask(ask) .content(answerRequest.getContent()) .build() diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/dto/response/AnswerResponse.java b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/response/AnswerResponse.java index d3d139a6..a44407bd 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/entity/dto/response/AnswerResponse.java +++ b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/response/AnswerResponse.java @@ -1,27 +1,19 @@ package project.trendpick_pro.domain.answer.entity.dto.response; -import jakarta.persistence.*; import lombok.Getter; - - import com.querydsl.core.annotations.QueryProjection; import lombok.AccessLevel; import lombok.Builder; import lombok.NoArgsConstructor; import project.trendpick_pro.domain.answer.entity.Answer; import project.trendpick_pro.domain.ask.entity.Ask; - -import java.time.LocalDate; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class AnswerResponse { private Long id; - private String author; //Member //브렌드 매니저 권한을 가지고 있어야함. private Ask ask; private String content; private LocalDateTime createdDate; @@ -29,9 +21,8 @@ public class AnswerResponse { @Builder @QueryProjection - public AnswerResponse(Long id, String author, Ask ask, String content, LocalDateTime createdDate, LocalDateTime modifiedDate) { + public AnswerResponse(Long id, Ask ask, String content, LocalDateTime createdDate, LocalDateTime modifiedDate) { this.id = id; - this.author = author; this.ask = ask; this.content = content; this.createdDate = createdDate; @@ -41,7 +32,6 @@ public AnswerResponse(Long id, String author, Ask ask, String content, LocalDate public static AnswerResponse of (Answer answer) { return AnswerResponse.builder() .id(answer.getId()) - .author(answer.getAuthor()) .ask(answer.getAsk()) .content(answer.getContent()) .createdDate(answer.getCreatedDate()) diff --git a/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java b/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java index e48252b1..91a47be9 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java +++ b/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java @@ -10,6 +10,7 @@ import project.trendpick_pro.domain.ask.entity.dto.response.AskResponse; import project.trendpick_pro.domain.ask.repository.AskRepository; import project.trendpick_pro.domain.ask.service.AskService; +import project.trendpick_pro.domain.member.entity.Member; @Service @Transactional(readOnly = true) @@ -19,10 +20,10 @@ public class AnswerService { private final AskRepository askRepository; @Transactional - public void register(Long askId, String member, AnswerRequest answerRequest) { + public void register(Long askId, Member member, AnswerRequest answerRequest) { Ask ask = askRepository.findById(askId).orElseThrow(); - Answer answer = Answer.write(ask, member, answerRequest); + Answer answer = Answer.write(ask, answerRequest); answerRepository.save(answer); } diff --git a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java index dcd6b7c2..7cfa5697 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java +++ b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java @@ -8,12 +8,14 @@ import project.trendpick_pro.domain.ask.entity.dto.request.AskRequest; import project.trendpick_pro.domain.ask.entity.dto.response.AskResponse; import project.trendpick_pro.domain.ask.service.AskService; +import project.trendpick_pro.domain.common.base.rq.Rq; @Controller @RequiredArgsConstructor @RequestMapping("trendpick/customerservice/asks") public class AskController { private final AskService askService; + private final Rq rq; @GetMapping("/list") public String showAllAsk(Model model) { diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java b/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java index 88dc18bf..4012022c 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java @@ -10,6 +10,8 @@ import project.trendpick_pro.domain.answer.entity.Answer; import project.trendpick_pro.domain.ask.entity.dto.request.AskRequest; import project.trendpick_pro.domain.common.base.BaseTimeEntity; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.product.entity.Product; import java.time.LocalDateTime; import java.util.ArrayList; @@ -27,13 +29,13 @@ public class Ask extends BaseTimeEntity { @Column(name = "ask_id") private Long id; - // @ManyToOne(fetch = FetchType.LAZY) - // @JoinColumn(name = "member_id") - private String author; //Member + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member author; - // @ManyToOne(fetch = FetchType.LAZY) - // @JoinColumn(name = "brand_id") - private String brand; //Brand + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "product_id") + private Product product; private String title; private String content; @@ -42,10 +44,10 @@ public class Ask extends BaseTimeEntity { @Builder.Default private List answerList = new ArrayList<>(); - public static Ask of(String member, String brand, AskRequest askRequest) { + public static Ask of(Member member, Product product, AskRequest askRequest) { return Ask.builder() .author(member) - .brand(brand) + .product(product) .title(askRequest.getTitle()) .content(askRequest.getTitle()) .build() diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java index a4086b61..aa978ba1 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java @@ -7,8 +7,8 @@ import lombok.NoArgsConstructor; import project.trendpick_pro.domain.answer.entity.Answer; import project.trendpick_pro.domain.ask.entity.Ask; - -import java.time.LocalDate; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.product.entity.Product; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; @@ -18,9 +18,8 @@ public class AskResponse { private Long id; - private String author; //Member - private String brand; //Brand - + private Member author; + private Product product; private String title; private String content; private List answerList = new ArrayList<>(); @@ -30,10 +29,10 @@ public class AskResponse { @Builder @QueryProjection - public AskResponse(Long id, String author, String brand, String title, String content, List answerList, LocalDateTime createdDate, LocalDateTime modifiedDate) { + public AskResponse(Long id, Member author, Product product, String title, String content, List answerList, LocalDateTime createdDate, LocalDateTime modifiedDate) { this.id = id; this.author = author; - this.brand = brand; + this.product = product; this.title = title; this.content = content; this.answerList = answerList; @@ -45,7 +44,7 @@ public static AskResponse of (Ask ask) { return AskResponse.builder() .id(ask.getId()) .author(ask.getAuthor()) - .brand(ask.getBrand()) + .product(ask.getProduct()) .title(ask.getTitle()) .content(ask.getContent()) .answerList(ask.getAnswerList()) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index f4e69960..e97315d9 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -6,15 +6,15 @@ spring: matching-strategy: ant_path_matcher datasource: # H2 -# driver-class-name: org.h2.Driver -# url: jdbc:h2:tcp://localhost/~/db/TrendPick -# username: sa -# password: + driver-class-name: org.h2.Driver + url: jdbc:h2:tcp://localhost/~/db/TrendPick + username: sa + password: # mariaDB - driver-class-name: org.mariadb.jdbc.Driver - url: jdbc:mariadb://127.0.0.1:${maria.port}/TrendPick__dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul - username: ${maria.username} - password: ${maria.password} +# driver-class-name: org.mariadb.jdbc.Driver +# url: jdbc:mariadb://127.0.0.1:${maria.port}/TrendPick__dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul +# username: ${maria.username} +# password: ${maria.password} jpa: hibernate: ddl-auto: create From 6ef9cd6786301fe883b3ca7907ebddece4ca9d78 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Mon, 29 May 2023 17:28:17 +0900 Subject: [PATCH 061/367] =?UTF-8?q?fix:=20AskService=20register=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/ask/controller/AskController.java | 4 ++-- .../domain/ask/service/AskService.java | 13 ++++++++----- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java index 7cfa5697..ba0fa12a 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java +++ b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java @@ -45,8 +45,8 @@ public String modifyAsk(@PathVariable Long askId, @Valid AskRequest askRequest, } @PostMapping("/register") - public String registerAsk(@Valid AskRequest askRequest, @RequestParam(value = "brand") Long brandId, Model model) { - AskResponse askResponse = askService.register(askRequest); + public String registerAsk(@RequestParam(value = "product") Long productId, @Valid AskRequest askRequest, Model model) { + AskResponse askResponse = askService.register(rq.getMember(), productId, askRequest); model.addAttribute("askResponse", askResponse); return "redirect:/trendpick/customerservice/asks/%s".formatted(askResponse.getId()); diff --git a/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java b/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java index 01cd3411..0849c24d 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java +++ b/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java @@ -7,6 +7,9 @@ import project.trendpick_pro.domain.ask.entity.dto.request.AskRequest; import project.trendpick_pro.domain.ask.entity.dto.response.AskResponse; import project.trendpick_pro.domain.ask.repository.AskRepository; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.product.repository.ProductRepository; import java.util.ArrayList; import java.util.List; @@ -17,12 +20,13 @@ public class AskService { private final AskRepository askRepository; + private final ProductRepository productRepository; public List showAll() { List askList = askRepository.findAll(); List responses = new ArrayList<>(); - for(Ask ask : askList){ + for (Ask ask : askList) { responses.add(AskResponse.of(ask)); } @@ -49,11 +53,10 @@ public AskResponse modify(Long askId, AskRequest askRequest) { } @Transactional - public AskResponse register(AskRequest askRequest) { - String member = "member"; //Member - String brand = "brand"; //Brand + public AskResponse register(Member member, Long productId, AskRequest askRequest) { + Product product = productRepository.findById(productId).orElseThrow(); - Ask ask = Ask.of(member, brand, askRequest); + Ask ask = Ask.of(member, product, askRequest); askRepository.save(ask); return AskResponse.of(ask); From ad2fd6af7dd298d7db70109d3c424b033c4da98a Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 29 May 2023 17:40:25 +0900 Subject: [PATCH 062/367] =?UTF-8?q?refactor:=20=EB=B6=88=ED=95=84=EC=9A=94?= =?UTF-8?q?=ED=95=9C=20=EB=A9=94=EC=86=8C=EB=93=9C=20=EC=A0=9C=EA=B1=B0/re?= =?UTF-8?q?direct=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/review/controller/ReviewController.java | 10 +++++----- .../domain/review/repository/ReviewRepository.java | 1 - .../domain/review/service/ReviewService.java | 3 +-- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index 0efa5eac..0128da01 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -23,10 +23,10 @@ public class ReviewController { @PostMapping("/write") public String createReview(@Valid ReviewRequest reviewRequest, @RequestParam(value = "productId") Long productId, Model model) { Member actor = rq.getMember(); - ReviewResponse reviewResponse = reviewService.createReview(actor, reviewRequest); + ReviewResponse reviewResponse = reviewService.createReview(actor, productId, reviewRequest); model.addAttribute("reviewResponse", reviewResponse); - return ""; + return "redirect:/trendpick/review"; } @@ -34,14 +34,14 @@ public String createReview(@Valid ReviewRequest reviewRequest, @RequestParam(val public String showReview(@PathVariable Long reviewId, Model model){ ReviewResponse reviewResponse = reviewService.showReview(reviewId); model.addAttribute("reviewResponse", reviewResponse); - return ""; + return "redirect:/trendpick/review"; } @PostMapping("/delete/{reviewId}") public String deleteReview(@PathVariable Long reviewId) { reviewService.delete(reviewId); - return ""; + return "redirect:/trendpick/review"; } @PostMapping("/edit/{reviewId}") @@ -49,6 +49,6 @@ public String modifyAsk(@PathVariable Long reviewId, @Valid ReviewRequest review ReviewResponse reviewResponse = reviewService.modify(reviewId, reviewRequest); model.addAttribute("reviewResponse", reviewResponse); - return ""; + return "redirect:/trendpick/review"; } } diff --git a/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java b/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java index 9a71b9f6..877db871 100644 --- a/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java +++ b/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java @@ -6,5 +6,4 @@ import java.util.List; public interface ReviewRepository extends JpaRepository { - List findAll(Long productId); } diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index 02f772ac..d5bc3421 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -30,9 +30,8 @@ public void delete(Long reviewId) { reviewRepository.deleteById(reviewId); } - public ReviewResponse createReview(Member actor, ReviewRequest reviewRequest) { + public ReviewResponse createReview(Member actor, Long productId, ReviewRequest reviewRequest) { String username = actor.getUsername(); - Long productId = 1L; Review review = Review.of(username, productId, reviewRequest); return ReviewResponse.of(review); From 9b759f9a2bcbf25ead8161821f71b299c7fa084e Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 29 May 2023 17:54:00 +0900 Subject: [PATCH 063/367] =?UTF-8?q?refactor:=20=EC=BB=AC=EB=9F=BC=EB=AA=85?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/review/controller/ReviewController.java | 2 +- .../java/project/trendpick_pro/domain/review/entity/Review.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index 0128da01..b059e331 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -45,7 +45,7 @@ public String deleteReview(@PathVariable Long reviewId) { } @PostMapping("/edit/{reviewId}") - public String modifyAsk(@PathVariable Long reviewId, @Valid ReviewRequest reviewRequest, Model model) { + public String modifyReview(@PathVariable Long reviewId, @Valid ReviewRequest reviewRequest, Model model) { ReviewResponse reviewResponse = reviewService.modify(reviewId, reviewRequest); model.addAttribute("reviewResponse", reviewResponse); diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java index bc6ca208..83ee326c 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -16,7 +16,7 @@ @Builder @Getter public class Review extends BaseTimeEntity { - @Id + @Id @Column(name = "review_id") @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; From f94c84d581dfba1b99e1a60cf3542a0234b2471e Mon Sep 17 00:00:00 2001 From: jooooonj Date: Mon, 29 May 2023 18:01:22 +0900 Subject: [PATCH 064/367] =?UTF-8?q?feat:=20ask=20querydsl=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/ask/controller/AskController.java | 4 +-- .../dto/response/AskByProductResponse.java | 25 +++++++++++++++++++ .../domain/ask/repository/AskRepository.java | 6 ++++- .../ask/repository/AskRepositoryCustom.java | 13 ++++++++++ .../ask/repository/AskRepositoryImpl.java | 15 +++++++++++ .../domain/ask/service/AskService.java | 11 ++++---- .../repository/ProductRepositoryCustom.java | 3 +-- 7 files changed, 66 insertions(+), 11 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskByProductResponse.java create mode 100644 src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryCustom.java create mode 100644 src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryImpl.java diff --git a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java index ba0fa12a..dd4ac382 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java +++ b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java @@ -18,8 +18,8 @@ public class AskController { private final Rq rq; @GetMapping("/list") - public String showAllAsk(Model model) { - model.addAttribute("askResponse", askService.showAll()); + public String showAsksByProduct(@RequestParam("page") int offset, @RequestParam("product") Long productId, Model model) { + model.addAttribute("askResponse", askService.showAsksByProduct(offset, productId)); return "trendpick/customerservice/asks/list"; } diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskByProductResponse.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskByProductResponse.java new file mode 100644 index 00000000..09c2dfdc --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskByProductResponse.java @@ -0,0 +1,25 @@ +package project.trendpick_pro.domain.ask.entity.dto.response; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; +import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; + +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +public class AskByProductResponse { + Long id; + String state; + String title; + String username; + String date; + + public AskByProductResponse(Long id, String state, String title, String username, LocalDateTime localDateTime) { + this.id = id; + this.state = state; + this.title = title; + this.username = username; + this.date = localDateTime.format(DateTimeFormatter.ofPattern("yyyy.MM.dd")); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java index faab5f2a..6d9eb01a 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java +++ b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java @@ -1,8 +1,12 @@ package project.trendpick_pro.domain.ask.repository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import project.trendpick_pro.domain.ask.entity.Ask; +import project.trendpick_pro.domain.product.entity.Product; + +public interface AskRepository extends JpaRepository, AskRepositoryCustom { -public interface AskRepository extends JpaRepository { } diff --git a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryCustom.java new file mode 100644 index 00000000..5d6ed31c --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryCustom.java @@ -0,0 +1,13 @@ +package project.trendpick_pro.domain.ask.repository; + + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import project.trendpick_pro.domain.ask.entity.dto.response.AskByProductResponse; +import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; +import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; + +public interface AskRepositoryCustom { + + public Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable); +} diff --git a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryImpl.java new file mode 100644 index 00000000..a5ff9c96 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryImpl.java @@ -0,0 +1,15 @@ +package project.trendpick_pro.domain.ask.repository; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; + +public class AskRepositoryImpl implements AskRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + public ProductRepositoryImpl(EntityManager em) { + this.queryFactory = new JPAQueryFactory(em); + } + + +} diff --git a/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java b/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java index 0849c24d..f1d85619 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java +++ b/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java @@ -1,6 +1,8 @@ package project.trendpick_pro.domain.ask.service; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.ask.entity.Ask; @@ -22,13 +24,10 @@ public class AskService { private final AskRepository askRepository; private final ProductRepository productRepository; - public List showAll() { - List askList = askRepository.findAll(); - List responses = new ArrayList<>(); + public List showAsksByProduct(int offset, Long productId) { + Pageable pageable = PageRequest.of(offset, 10); - for (Ask ask : askList) { - responses.add(AskResponse.of(ask)); - } + List responses = new ArrayList<>(); return responses; } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java index df530166..9fdc3091 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java @@ -6,6 +6,5 @@ import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; public interface ProductRepositoryCustom { - - Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable); + public Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable); } From 8624c37f853dd58c578b1ea22ce7b88f4449177d Mon Sep 17 00:00:00 2001 From: jooooonj Date: Mon, 29 May 2023 18:35:01 +0900 Subject: [PATCH 065/367] =?UTF-8?q?feat:=20ask=20crud=20=EC=A0=91=EA=B7=BC?= =?UTF-8?q?=EA=B6=8C=ED=95=9C=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/ask/controller/AskController.java | 8 +- .../dto/request/AskByProductRequest.java | 12 +++ .../domain/ask/repository/AskRepository.java | 3 - .../ask/repository/AskRepositoryCustom.java | 3 +- .../ask/repository/AskRepositoryImpl.java | 76 +++++++++++++++---- .../domain/ask/service/AskService.java | 21 ++++- 6 files changed, 99 insertions(+), 24 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/ask/entity/dto/request/AskByProductRequest.java diff --git a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java index dd4ac382..b6f08b14 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java +++ b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java @@ -2,6 +2,7 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; @@ -29,21 +30,24 @@ public String showAsk(@PathVariable Long askId, Model model) { return "trendpick/customerservice/asks/detail"; } + @PreAuthorize("isAuthenticated()") @PostMapping("/delete/{askId}") public String deleteAsk(@PathVariable Long askId) { - askService.delete(askId); + askService.delete(rq.getMember(), askId); return "redirect:/trendpick/customerservice/asks/list"; } + @PreAuthorize("isAuthenticated()") @PostMapping("/edit/{askId}") public String modifyAsk(@PathVariable Long askId, @Valid AskRequest askRequest, Model model) { - AskResponse askResponse = askService.modify(askId, askRequest); + AskResponse askResponse = askService.modify(rq.getMember(), askId, askRequest); model.addAttribute("askResponse", askResponse); return "redirect:/trendpick/customerservice/asks/%s".formatted(askId); } + @PreAuthorize("isAuthenticated()") @PostMapping("/register") public String registerAsk(@RequestParam(value = "product") Long productId, @Valid AskRequest askRequest, Model model) { AskResponse askResponse = askService.register(rq.getMember(), productId, askRequest); diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/request/AskByProductRequest.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/request/AskByProductRequest.java new file mode 100644 index 00000000..0621a09c --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/request/AskByProductRequest.java @@ -0,0 +1,12 @@ +package project.trendpick_pro.domain.ask.entity.dto.request; + +import lombok.Getter; + +@Getter +public class AskByProductRequest { + private Long productId; + + public AskByProductRequest(Long productId) { + this.productId = productId; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java index 6d9eb01a..f55c7530 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java +++ b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java @@ -1,11 +1,8 @@ package project.trendpick_pro.domain.ask.repository; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import project.trendpick_pro.domain.ask.entity.Ask; -import project.trendpick_pro.domain.product.entity.Product; public interface AskRepository extends JpaRepository, AskRepositoryCustom { diff --git a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryCustom.java index 5d6ed31c..68478c63 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryCustom.java +++ b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryCustom.java @@ -3,11 +3,12 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import project.trendpick_pro.domain.ask.entity.dto.request.AskByProductRequest; import project.trendpick_pro.domain.ask.entity.dto.response.AskByProductResponse; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; public interface AskRepositoryCustom { - public Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable); + public Page findAllByProduct(AskByProductRequest request, Pageable pageable); } diff --git a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryImpl.java index a5ff9c96..1731e509 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryImpl.java @@ -1,15 +1,61 @@ -package project.trendpick_pro.domain.ask.repository; - -import com.querydsl.jpa.impl.JPAQueryFactory; -import jakarta.persistence.EntityManager; - -public class AskRepositoryImpl implements AskRepositoryCustom { - - private final JPAQueryFactory queryFactory; - - public ProductRepositoryImpl(EntityManager em) { - this.queryFactory = new JPAQueryFactory(em); - } - - -} +//package project.trendpick_pro.domain.ask.repository; +// +//import com.querydsl.core.types.dsl.BooleanExpression; +//import com.querydsl.jpa.impl.JPAQuery; +//import com.querydsl.jpa.impl.JPAQueryFactory; +//import jakarta.persistence.EntityManager; +//import org.springframework.data.domain.Page; +//import org.springframework.data.domain.Pageable; +//import org.springframework.data.support.PageableExecutionUtils; +//import project.trendpick_pro.domain.ask.entity.QAsk; +//import project.trendpick_pro.domain.ask.entity.dto.request.AskByProductRequest; +//import project.trendpick_pro.domain.ask.entity.dto.response.AskByProductResponse; +//import project.trendpick_pro.domain.ask.entity.dto.response.QAskResponse; +//import project.trendpick_pro.domain.member.entity.QMember; +//import project.trendpick_pro.domain.product.entity.QProduct; +// +//import java.util.List; +// +//import static com.querydsl.core.QueryModifiers.offset; +//import static project.trendpick_pro.domain.ask.entity.QAsk.*; +//import static project.trendpick_pro.domain.brand.entity.QBrand.brand; +//import static project.trendpick_pro.domain.category.entity.QMainCategory.mainCategory; +//import static project.trendpick_pro.domain.category.entity.QSubCategory.subCategory; +//import static project.trendpick_pro.domain.common.file.QCommonFile.commonFile; +//import static project.trendpick_pro.domain.member.entity.QMember.*; +//import static project.trendpick_pro.domain.product.entity.QProduct.product; +// +//public class AskRepositoryImpl implements AskRepositoryCustom { +// +// private final JPAQueryFactory queryFactory; +// +// public AskRepositoryImpl(EntityManager em) { +// this.queryFactory = new JPAQueryFactory(em); +// } +// +// @Override +// public Page findAllByProduct(AskByProductRequest request, Pageable pageable) { +// List result = queryFactory +// .select(new QAskByProductResponse( +// ask.id, +// ask.title, +// ask.author.username, +// ask.createdDate +// )) +// .from(ask) +// .leftJoin(ask.product, product) +// .where( +// askByProductEq(request) +// ) +// .offset(0) +// .limit(10) +// .fetch(); +// +// +// return null; +// } +// +// private static BooleanExpression askByProductEq(AskByProductRequest request) { +// return ask.product.id.eq(request.getProductId()); +// } +//} diff --git a/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java b/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java index f1d85619..56f863c0 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java +++ b/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java @@ -39,14 +39,22 @@ public AskResponse show(Long askId) { } @Transactional - public void delete(Long askId) { - askRepository.deleteById(askId); + public void delete(Member member, Long askId) { + Ask ask = askRepository.findById(askId).orElseThrow(); + + if(validateAccess(member, ask)) + throw new RuntimeException("해당 문의에 대한 삭제 권한이 없습니다."); + + askRepository.delete(ask); } @Transactional - public AskResponse modify(Long askId, AskRequest askRequest) { + public AskResponse modify(Member member, Long askId, AskRequest askRequest) { Ask ask = askRepository.findById(askId).orElseThrow(); + if(validateAccess(member, ask)) + throw new RuntimeException("해당 문의에 대한 수정 권한이 없습니다."); + ask.update(askRequest); return AskResponse.of(ask); } @@ -60,4 +68,11 @@ public AskResponse register(Member member, Long productId, AskRequest askRequest askRepository.save(ask); return AskResponse.of(ask); } + + + private boolean validateAccess(Member member, Ask ask) { + if(ask.getAuthor().getId() == member.getId()) + return true; + return false; + } } From 1cba5837d5e8ff4c7483d67c20a1cb4d141f2a5f Mon Sep 17 00:00:00 2001 From: jooooonj Date: Mon, 29 May 2023 18:46:43 +0900 Subject: [PATCH 066/367] =?UTF-8?q?feat:=20answer=20=EC=A0=91=EA=B7=BC?= =?UTF-8?q?=EA=B6=8C=ED=95=9C=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../answer/controller/AnswerController.java | 25 +++++++++++-------- .../domain/answer/service/AnswerService.java | 18 +++++++++++-- 2 files changed, 30 insertions(+), 13 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java index 40a296e7..cdcd7ebd 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java +++ b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java @@ -2,40 +2,43 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.*; import project.trendpick_pro.domain.answer.entity.dto.request.AnswerRequest; +import project.trendpick_pro.domain.answer.entity.dto.response.AnswerResponse; import project.trendpick_pro.domain.answer.service.AnswerService; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.entity.RoleType; @Controller @RequiredArgsConstructor -@RequestMapping("/trendpick/customerservice/asks/{askId}/answers") +@RequestMapping("/trendpick/customerservice/answers") public class AnswerController { private final AnswerService answerService; private final Rq rq; + @PreAuthorize("isAuthenticated()") @PostMapping("/register") - public String registerAnswer(@PathVariable Long askId, - @Valid AnswerRequest answerRequest){ + public String registerAnswer(@RequestParam("ask") Long askId, @Valid AnswerRequest answerRequest){ Member member = rq.getMember(); answerService.register(askId, member, answerRequest); return "redirect:/trendpick/customerservice/asks/{askId}".formatted(askId); } - + @PreAuthorize("isAuthenticated()") @PostMapping("/delete/{answerId}") - public String deleteAnswer(@PathVariable Long askId, @PathVariable Long answerId){ - answerService.delete(answerId); + public String deleteAnswer(@PathVariable Long answerId){ + AnswerResponse res = answerService.delete(rq.getMember(), answerId); - return "redirect:/trendpick/customerservice/asks/%s".formatted(askId); + return "redirect:/trendpick/customerservice/asks/%s".formatted(res.getAsk().getId()); } - + @PreAuthorize("isAuthenticated()") @PostMapping("/moidfy/{answerId}") - public String modifyAnswer(@PathVariable Long askId, @PathVariable Long answerId, @Valid AnswerRequest answerRequest){ - answerService.modify(answerId, answerRequest); + public String modifyAnswer(@PathVariable Long answerId, @Valid AnswerRequest answerRequest){ + AnswerResponse res = answerService.modify(rq.getMember(), answerId, answerRequest); - return "redirect:/trendpick/customerservice/asks/%s".formatted(askId); + return "redirect:/trendpick/customerservice/asks/%s".formatted(res.getAsk().getId()); } } diff --git a/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java b/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java index 91a47be9..b3e256dc 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java +++ b/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java @@ -5,12 +5,14 @@ import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.answer.entity.Answer; import project.trendpick_pro.domain.answer.entity.dto.request.AnswerRequest; +import project.trendpick_pro.domain.answer.entity.dto.response.AnswerResponse; import project.trendpick_pro.domain.answer.repository.AnswerRepository; import project.trendpick_pro.domain.ask.entity.Ask; import project.trendpick_pro.domain.ask.entity.dto.response.AskResponse; import project.trendpick_pro.domain.ask.repository.AskRepository; import project.trendpick_pro.domain.ask.service.AskService; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.entity.RoleType; @Service @Transactional(readOnly = true) @@ -21,6 +23,9 @@ public class AnswerService { @Transactional public void register(Long askId, Member member, AnswerRequest answerRequest) { + if(member.getRole() != RoleType.ADMIN) + throw new RuntimeException("답글을 달 수 있는 권한이 없습니다."); + Ask ask = askRepository.findById(askId).orElseThrow(); Answer answer = Answer.write(ask, answerRequest); @@ -29,16 +34,25 @@ public void register(Long askId, Member member, AnswerRequest answerRequest) { } @Transactional - public void delete(Long answerId) { + public AnswerResponse delete(Member member, Long answerId) { + if(member.getRole() != RoleType.ADMIN) + throw new RuntimeException("답글을 달 수 있는 권한이 없습니다."); + Answer answer = answerRepository.findById(answerId).orElseThrow(); answerRepository.delete(answer); answer.getAsk().getAnswerList().remove(answer); + + return AnswerResponse.of(answer); } - public void modify(Long answerId, AnswerRequest answerRequest) { + public AnswerResponse modify(Member member, Long answerId, AnswerRequest answerRequest) { + if(member.getRole() != RoleType.ADMIN) + throw new RuntimeException("답글을 달 수 있는 권한이 없습니다."); + Answer answer = answerRepository.findById(answerId).orElseThrow(); answer.update(answerRequest); + return AnswerResponse.of(answer); } } From 6f7d8cc8a57722878bb4d04cfa7146616fe8b384 Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Mon, 29 May 2023 20:00:58 +0900 Subject: [PATCH 067/367] =?UTF-8?q?refactor:=20Cart,=20CartItem=20?= =?UTF-8?q?=EB=B6=80=EB=B6=84=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cart/controller/CartController.java | 14 ++++---- .../domain/cart/entity/Cart.java | 12 +++---- .../domain/cart/entity/CartItem.java | 7 ++-- .../entity/dto/request/CartItemRequest.java | 4 +-- .../entity/dto/response/CartItemResponse.java | 14 ++++---- .../entity/dto/response/CartResponse.java | 34 +++++++++++++------ .../cart/repository/CartRepository.java | 2 +- .../domain/cart/service/CartService.java | 26 +++++++------- .../orders/contoller/OrderController.java | 18 +++++----- .../domain/product/entity/ProductOption.java | 3 +- .../product/repository/ProductRepository.java | 1 + 11 files changed, 78 insertions(+), 57 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java index c1e2668d..d179b04d 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java +++ b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java @@ -7,6 +7,8 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import project.trendpick_pro.domain.cart.service.CartService; +import project.trendpick_pro.domain.member.entity.Member; + @Slf4j @Controller @@ -22,16 +24,16 @@ public CartController(CartService cartService) { public String addItemToCart(@RequestParam("productOptionId") Long productOptionId, @RequestParam("count") int count, HttpSession session) { - // User user = (User) session.getAttribute("user"); - cartService.addItemToCart(user, productOptionId, count); + Member member = (Member) session.getAttribute("member"); + cartService.addItemToCart(member, productOptionId, count); return "redirect:/trendpick/cart"; } @PostMapping("/remove") public String removeItemFromCart(@RequestParam("cartItemId") Long cartItemId, HttpSession session) { - // User user = (User) session.getAttribute("user"); - cartService.removeItemFromCart(user, cartItemId); + Member member = (Member) session.getAttribute("member"); + cartService.removeItemFromCart(member, cartItemId); return "redirect:/trendpick/cart"; } @@ -39,8 +41,8 @@ public String removeItemFromCart(@RequestParam("cartItemId") Long cartItemId, public String updateCartItemQuantity(@RequestParam("cartItemId") Long cartItemId, @RequestParam("count") int count, HttpSession session) { - // User user = (User) session.getAttribute("user"); - cartService.updateItemCount(user, cartItemId, count); + Member member = (Member) session.getAttribute("member"); + cartService.updateItemCount(member, cartItemId, count); return "redirect:/trendpick/cart"; } } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java index d80cfedb..fb620dcb 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java @@ -5,7 +5,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; -import org.springframework.security.core.userdetails.User; +import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.ProductOption; import java.util.ArrayList; @@ -22,9 +22,9 @@ public class Cart { @Column(name = "cart_id") private Long id; - //@OneToOne(fetch = FetchType.LAZY) - // @JoinColumn(name = "user_id") - // private User user; + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; @OneToMany(mappedBy = "cart", cascade = CascadeType.ALL, orphanRemoval = true) private List cartItems = new ArrayList<>(); @@ -35,8 +35,8 @@ public class Cart { // 총 가격 필드 private int totalPrice; - public Cart(User user) { - //this.user = user; + public Cart(Member member) { + this.member = member; } // CartItem 추가 diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java index ea359f94..4ad55e8e 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java @@ -3,7 +3,10 @@ import jakarta.persistence.*; import lombok.*; import project.trendpick_pro.domain.product.entity.ProductOption; +import project.trendpick_pro.domain.tag.entity.Tag; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; @Entity @@ -19,7 +22,6 @@ public class CartItem { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "cart_id") private Cart cart; - @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "product_option_id") private ProductOption productOption; @@ -29,12 +31,11 @@ public class CartItem { private int price; // 해당 상품 금액 @Builder - public CartItem(Cart cart, ProductOption productOption, int count) { + public CartItem(Cart cart, ProductOption productOption, int count) { this.cart = cart; this.productOption = productOption; this.count = count; this.price = productOption.getProduct().getPrice(); } - } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java index 13fcfa77..bf032f6b 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java @@ -6,10 +6,10 @@ @Getter public class CartItemRequest { + @NotBlank + private Long cartId; @NotBlank private Long productOptionId; - @Min(1) private int count; - } diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java index 7b8ae2cd..65508e62 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java @@ -6,23 +6,25 @@ import project.trendpick_pro.domain.cart.entity.CartItem; - @Getter public class CartItemResponse { private Long id; + private Long cartId; + private Long productOptionId; - private String productName; - private int count; + private int count; // 해당 상품 수량 + + private int price; // 해당 상품 금액; @Builder @QueryProjection - public CartItemResponse(Long id, Long cartId, Long productOptionId, String productName, int count) { + public CartItemResponse(Long id, Long cartId, Long productOptionId, int count, int price) { this.id = id; this.cartId = cartId; this.productOptionId = productOptionId; - this.productName = productName; this.count = count; + this.price = price; } public static CartItemResponse of (CartItem cartItem) { @@ -30,8 +32,8 @@ public static CartItemResponse of (CartItem cartItem) { .id(cartItem.getId()) .cartId(cartItem.getCart().getId()) .productOptionId(cartItem.getProductOption().getId()) - .productName(cartItem.getProductOption().getProduct().getName()) .count(cartItem.getCount()) + .price(cartItem.getPrice()) .build(); } } diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java index 6ca43cba..f091813a 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java @@ -4,26 +4,40 @@ import lombok.Builder; import lombok.Getter; import project.trendpick_pro.domain.cart.entity.Cart; +import project.trendpick_pro.domain.cart.entity.CartItem; + +import java.util.List; @Getter public class CartResponse { private Long id; - private Long cartItemId; + private Long memberId; + + private int totalCount; - private Long productOptionId; + private int totalPrice; + + private List cartItems; - private int count; - private int price; @Builder @QueryProjection - public CartResponse(Long id, Long cartItemId, long productOptionId, int price, int count) { + public CartResponse(Long id, Long memberId, int totalCount, int totalPrice, List cartItems) { this.id = id; - this.cartItemId = cartItemId; - this.productOptionId=productOptionId; - this.price=price; - this.count = count; + this.memberId = memberId; + this.totalCount=totalCount; + this.totalPrice=totalPrice; + this.cartItems=cartItems; } -} + public static CartResponse of (Cart cart) { + return CartResponse.builder() + .id(cart.getId()) + .memberId(cart.getMember().getId()) + .totalCount(cart.getTotalCount()) + .totalPrice(cart.getTotalPrice()) + .cartItems(cart.getCartItems()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java b/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java index 6263e279..9b1c9b21 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java +++ b/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java @@ -4,5 +4,5 @@ import project.trendpick_pro.domain.cart.entity.Cart; public interface CartRepository extends JpaRepository { - Cart findByUserId(Long userId); + Cart findByUser(Long memberId); } diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index 43f43a2b..09f1b465 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -1,14 +1,15 @@ package project.trendpick_pro.domain.cart.service; -import org.springframework.security.core.userdetails.User; import org.springframework.stereotype.Service; import project.trendpick_pro.domain.cart.entity.Cart; import project.trendpick_pro.domain.cart.entity.CartItem; import project.trendpick_pro.domain.cart.repository.CartRepository; +import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.ProductOption; import project.trendpick_pro.domain.product.repository.ProductOptionRepository; + @Service public class CartService { @@ -20,13 +21,13 @@ public CartService(CartRepository cartRepository, ProductOptionRepository produc this.productOptionRepository = productOptionRepository; } - public Cart createCart(User user) { - Cart cart = new Cart(user); + public Cart createCart(Member member) { + Cart cart = new Cart(member); return cartRepository.save(cart); } - public void addItemToCart(User user, Long productOptionId, int count) { - Cart cart = getCartByUser(user); + public void addItemToCart(Member member, Long productOptionId, int count) { + Cart cart = getCartByUser(member); ProductOption productOption = getProductOptionById(productOptionId); CartItem cartItem = cart.findCartItemByProductOption(productOption); @@ -43,22 +44,23 @@ public void addItemToCart(User user, Long productOptionId, int count) { } // 상품을 장바구니에서 제거 - public void removeItemFromCart(User user, Long cartItemId) { - Cart cart = getCartByUser(user); + public void removeItemFromCart(Member member, Long cartItemId) { + Cart cart = getCartByUser(member); cart.removeItem(cartItemId); } // 상품의 수량 업데이트 - public void updateItemCount(User user, Long cartItemId, int count) { - Cart cart = getCartByUser(user); + public void updateItemCount(Member member, Long cartItemId, int count) { + Cart cart = getCartByUser(member); cart.updateItemCount(cartItemId, count); } - public Cart getCartByUser(User user) { - // return cartRepository.findByUser(user); + public Cart getCartByUser(Member member) { + return cartRepository.findByUser(member.getId()); } private ProductOption getProductOptionById(Long productOptionId) { - // return productOptionRepository.findById(productOptionId); + return productOptionRepository.findById(productOptionId) + .orElseThrow(() -> new IllegalArgumentException("Product option not found")); } } diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 23f80927..bc32105b 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -7,12 +7,11 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; -import project.trendpick_pro.domain.orders.entity.Order; import project.trendpick_pro.domain.orders.entity.dto.request.OrderSaveRequest; -import project.trendpick_pro.domain.orders.entity.dto.request.OrderSearchCond; import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; import project.trendpick_pro.domain.orders.service.OrderService; +import java.util.List; @Slf4j @Controller @@ -23,24 +22,23 @@ public class OrderController { private final OrderService orderService; @PostMapping("/order") - public String order(@Valid OrderSaveRequest... orderSaveRequests) throws IllegalAccessException { + public String order(@Valid OrderSaveRequest... orderSaveRequests){ orderService.order(1L, orderSaveRequests); - return "redirect:trendpick/usr/member/orders"; + return "redirect:/orders"; } - @GetMapping("/list") - public String orderList(Model model, @Valid OrderSearchCond orderSearchCond) { - Page responses = orderService.findAll(orderSearchCond); - + @GetMapping("/orders") + public String orderList(Model model) { + Page responses = orderService.findAll(1L); model.addAttribute("orders", responses); - return "trendpick/usr/member/orders"; + return "order/orderList"; } @PostMapping("/orders/{orderId}/cancel") public String cancelOrder(@PathVariable("orderId") Long orderId) { orderService.cancel(orderId); - return "redirect:trendpick/usr/member/orders"; + return "redirect:/orders"; } } diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/ProductOption.java b/src/main/java/project/trendpick_pro/domain/product/entity/ProductOption.java index 243ff69c..883d2d44 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/ProductOption.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/ProductOption.java @@ -16,7 +16,8 @@ public class ProductOption { private Long id; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn Product product; + @JoinColumn(name = "product_id", nullable = false) + private Product product; private String color; // 색상 diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepository.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepository.java index 0cecec0a..e0afdfab 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepository.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepository.java @@ -4,4 +4,5 @@ import project.trendpick_pro.domain.product.entity.Product; public interface ProductRepository extends JpaRepository, ProductRepositoryCustom { + } From 07ffd8e1e9fa45bc0cc843dbad9ee4c35b152f26 Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Mon, 29 May 2023 20:01:51 +0900 Subject: [PATCH 068/367] =?UTF-8?q?refactor:=20CartRequest=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/cart/entity/dto/request/CartRequest.java | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartRequest.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartRequest.java index efe0f263..0119aaf7 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartRequest.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartRequest.java @@ -1,14 +1,9 @@ package project.trendpick_pro.domain.cart.entity.dto.request; -import jakarta.validation.constraints.Min; + import jakarta.validation.constraints.NotBlank; -import project.trendpick_pro.domain.product.entity.ProductOption; public class CartRequest { @NotBlank - private Long cartItemId; - @NotBlank - private Long productOptionId; - @Min(1) - private int count; + private Long memberId; } From 145e890f9f1f99266fb71a6812dbe1be30539f37 Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Mon, 29 May 2023 20:33:01 +0900 Subject: [PATCH 069/367] =?UTF-8?q?refactor:=20orderController=EC=9D=B4?= =?UTF-8?q?=EC=A0=84=EC=9C=BC=EB=A1=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/orders/contoller/OrderController.java | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index bc32105b..5b9c3f73 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -11,7 +11,6 @@ import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; import project.trendpick_pro.domain.orders.service.OrderService; -import java.util.List; @Slf4j @Controller @@ -28,17 +27,16 @@ public String order(@Valid OrderSaveRequest... orderSaveRequests){ return "redirect:/orders"; } - @GetMapping("/orders") + @GetMapping("/list") public String orderList(Model model) { Page responses = orderService.findAll(1L); model.addAttribute("orders", responses); - return "order/orderList"; + return "trendpick/usr/member/orders"; } @PostMapping("/orders/{orderId}/cancel") public String cancelOrder(@PathVariable("orderId") Long orderId) { orderService.cancel(orderId); - return "redirect:/orders"; + return "redirect:trendpick/usr/member/orders"; } - } From 62c9d1370335cb79022a65144baa1dd35b8f4313 Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Mon, 29 May 2023 22:55:34 +0900 Subject: [PATCH 070/367] =?UTF-8?q?feat:=20notification=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=EB=A1=9C=EC=A7=81=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/NotificationController.java | 34 +++++++++++++++++- .../notification/entity/Notification.java | 36 +++++++++++++++---- .../dto/request/NotificationRequest.java | 15 ++++++++ .../dto/response/NotificationResponse.java | 29 +++++++++++++++ .../service/NotificationService.java | 31 +++++++++++++++- 5 files changed, 137 insertions(+), 8 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/notification/entity/dto/request/NotificationRequest.java create mode 100644 src/main/java/project/trendpick_pro/domain/notification/entity/dto/response/NotificationResponse.java diff --git a/src/main/java/project/trendpick_pro/domain/notification/controller/NotificationController.java b/src/main/java/project/trendpick_pro/domain/notification/controller/NotificationController.java index b7896843..caa9aa73 100644 --- a/src/main/java/project/trendpick_pro/domain/notification/controller/NotificationController.java +++ b/src/main/java/project/trendpick_pro/domain/notification/controller/NotificationController.java @@ -1,4 +1,36 @@ package project.trendpick_pro.domain.notification.controller; +import javassist.NotFoundException; +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.*; +import project.trendpick_pro.domain.common.base.rq.Rq; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.notification.entity.Notification; +import project.trendpick_pro.domain.notification.entity.dto.request.NotificationRequest; +import project.trendpick_pro.domain.notification.service.NotificationService; + +@Controller +@RequiredArgsConstructor +@RequestMapping("/trendpick/notification") public class NotificationController { -} + private final NotificationService notificationService; + private final Rq rq; + + // 알림 생성 + @PreAuthorize("isAuthenticated()") + @PostMapping("/notification") + public String createNotification(@RequestBody NotificationRequest request) { + Member member=rq.getMember(); + notificationService.create(member, request); + return "redirect:/trendpick/notification"; + } + + // 알림 삭제 + @PreAuthorize("isAuthenticated()") + @DeleteMapping("/{notificationId}") + public void deleteNotification(@PathVariable Long notificationId) { + notificationService.delete(notificationId); + } +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/notification/entity/Notification.java b/src/main/java/project/trendpick_pro/domain/notification/entity/Notification.java index 1cc01437..f6b219b9 100644 --- a/src/main/java/project/trendpick_pro/domain/notification/entity/Notification.java +++ b/src/main/java/project/trendpick_pro/domain/notification/entity/Notification.java @@ -1,21 +1,45 @@ package project.trendpick_pro.domain.notification.entity; +import com.querydsl.core.types.Order; import jakarta.persistence.*; import lombok.*; - -import java.time.LocalDateTime; +import project.trendpick_pro.domain.answer.entity.Answer; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.notification.entity.dto.request.NotificationRequest; @Entity +@NoArgsConstructor +@AllArgsConstructor +@Builder @Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Notification { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - private LocalDateTime creatDate; // 생성일 - private String title; // 알림명 + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "answer_id") + private Answer answer; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + + //@ManyToOne(fetch = FetchType.LAZY) + // @JoinColumn(name = "order_id") + private Order order; + + private String title; // 제목 + + private String content; // 내용 - private String content; // 알림내용 + public static Notification of(Member member, NotificationRequest notificationRequest) { + return Notification.builder() + .member(member) + .title(notificationRequest.getTitle()) + .content(notificationRequest.getContent()) + .build() + ; + } } diff --git a/src/main/java/project/trendpick_pro/domain/notification/entity/dto/request/NotificationRequest.java b/src/main/java/project/trendpick_pro/domain/notification/entity/dto/request/NotificationRequest.java new file mode 100644 index 00000000..4ca13cb4 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/notification/entity/dto/request/NotificationRequest.java @@ -0,0 +1,15 @@ +package project.trendpick_pro.domain.notification.entity.dto.request; + +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; + +@Getter +public class NotificationRequest { + @NotBlank + private Long memberId; + @NotBlank + private String title; + @NotBlank + private String content; + +} diff --git a/src/main/java/project/trendpick_pro/domain/notification/entity/dto/response/NotificationResponse.java b/src/main/java/project/trendpick_pro/domain/notification/entity/dto/response/NotificationResponse.java new file mode 100644 index 00000000..a1d2b458 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/notification/entity/dto/response/NotificationResponse.java @@ -0,0 +1,29 @@ +package project.trendpick_pro.domain.notification.entity.dto.response; + +import com.querydsl.core.annotations.QueryProjection; +import lombok.Builder; +import project.trendpick_pro.domain.answer.entity.Answer; +import project.trendpick_pro.domain.answer.entity.dto.response.AnswerResponse; +import project.trendpick_pro.domain.ask.entity.Ask; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.notification.entity.Notification; +import project.trendpick_pro.domain.product.entity.Product; + +import java.time.LocalDateTime; +import java.util.List; + +public class NotificationResponse { + private Long id; + private LocalDateTime creatDate; + private String title; + private String content; + + @Builder + @QueryProjection + public NotificationResponse(Long id, LocalDateTime creatDate,String title, String content) { + this.id = id; + this.creatDate = creatDate; + this.title = title; + this.content = content; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/notification/service/NotificationService.java b/src/main/java/project/trendpick_pro/domain/notification/service/NotificationService.java index 08f194a2..6278f0a4 100644 --- a/src/main/java/project/trendpick_pro/domain/notification/service/NotificationService.java +++ b/src/main/java/project/trendpick_pro/domain/notification/service/NotificationService.java @@ -1,4 +1,33 @@ package project.trendpick_pro.domain.notification.service; +import javassist.NotFoundException; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.answer.entity.Answer; +import project.trendpick_pro.domain.answer.entity.dto.request.AnswerRequest; +import project.trendpick_pro.domain.ask.entity.Ask; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.entity.RoleType; +import project.trendpick_pro.domain.notification.entity.Notification; +import project.trendpick_pro.domain.notification.entity.dto.request.NotificationRequest; +import project.trendpick_pro.domain.notification.repository.NotificationRepository; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor public class NotificationService { -} + private final NotificationRepository notificationRepository; + + // 알림 생성 + @Transactional + public void create(Member member, NotificationRequest notificationRequest) { + Notification notification=Notification.of(member, notificationRequest); + notificationRepository.save(notification); + } + + // 알림 삭제 + public void delete(Long notificationId) { + notificationRepository.deleteById(notificationId); + } +} \ No newline at end of file From 6012ef7ce5b2582ba9074904577d07462ce51634 Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Mon, 29 May 2023 23:31:36 +0900 Subject: [PATCH 071/367] =?UTF-8?q?refactor:=20cart=20Rq=20=EB=8F=84?= =?UTF-8?q?=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cart/controller/CartController.java | 33 +++++++++---------- .../domain/cart/service/CartService.java | 9 +++-- 2 files changed, 19 insertions(+), 23 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java index d179b04d..09220579 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java +++ b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java @@ -1,47 +1,44 @@ package project.trendpick_pro.domain.cart.controller; -import jakarta.servlet.http.HttpSession; -import lombok.extern.slf4j.Slf4j; + +import lombok.RequiredArgsConstructor; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import project.trendpick_pro.domain.cart.service.CartService; +import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; -@Slf4j @Controller +@RequiredArgsConstructor @RequestMapping("/trendpick/cart") public class CartController { private final CartService cartService; - - public CartController(CartService cartService) { - this.cartService = cartService; - } - + private final Rq rq; + @PreAuthorize("isAuthenticated()") @PostMapping("/add") public String addItemToCart(@RequestParam("productOptionId") Long productOptionId, - @RequestParam("count") int count, - HttpSession session) { - Member member = (Member) session.getAttribute("member"); + @RequestParam("count") int count) { + Member member = rq.getMember(); cartService.addItemToCart(member, productOptionId, count); - return "redirect:/trendpick/cart"; + // 쇼핑을 계속 하시겠습니까? 띄우고 yes이면 main no면 cart로 + return "redirect:/trendprick/cart"; } @PostMapping("/remove") - public String removeItemFromCart(@RequestParam("cartItemId") Long cartItemId, - HttpSession session) { - Member member = (Member) session.getAttribute("member"); + public String removeItemFromCart(@RequestParam("cartItemId") Long cartItemId) { + Member member = rq.getMember(); cartService.removeItemFromCart(member, cartItemId); return "redirect:/trendpick/cart"; } @PostMapping("/update") public String updateCartItemQuantity(@RequestParam("cartItemId") Long cartItemId, - @RequestParam("count") int count, - HttpSession session) { - Member member = (Member) session.getAttribute("member"); + @RequestParam("count") int count) { + Member member = rq.getMember(); cartService.updateItemCount(member, cartItemId, count); return "redirect:/trendpick/cart"; } diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index 09f1b465..6090f3b9 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -1,6 +1,8 @@ package project.trendpick_pro.domain.cart.service; +import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.cart.entity.Cart; import project.trendpick_pro.domain.cart.entity.CartItem; import project.trendpick_pro.domain.cart.repository.CartRepository; @@ -11,16 +13,13 @@ @Service +@Transactional(readOnly = true) +@RequiredArgsConstructor public class CartService { private final CartRepository cartRepository; private final ProductOptionRepository productOptionRepository; - public CartService(CartRepository cartRepository, ProductOptionRepository productOptionRepository) { - this.cartRepository = cartRepository; - this.productOptionRepository = productOptionRepository; - } - public Cart createCart(Member member) { Cart cart = new Cart(member); return cartRepository.save(cart); From cf93053d7232ee9d602cde9c1468de3a359759f9 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 30 May 2023 00:17:44 +0900 Subject: [PATCH 072/367] =?UTF-8?q?feat:=20findAllByProduct=20=EC=83=81?= =?UTF-8?q?=ED=92=88=EC=97=90=20=EB=94=B0=EB=A5=B8=20asks=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 --- .../trendpick_pro/domain/ask/entity/Ask.java | 3 + .../dto/response/AskByProductResponse.java | 12 +- .../ask/repository/AskRepositoryImpl.java | 122 +++++++++--------- .../orders/contoller/OrderController.java | 26 ++-- 4 files changed, 84 insertions(+), 79 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java b/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java index 4012022c..5758a1e4 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java @@ -14,6 +14,7 @@ import project.trendpick_pro.domain.product.entity.Product; import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -39,6 +40,7 @@ public class Ask extends BaseTimeEntity { private String title; private String content; + private String state; @OneToMany(mappedBy = "ask", cascade = CascadeType.ALL) @Builder.Default @@ -50,6 +52,7 @@ public static Ask of(Member member, Product product, AskRequest askRequest) { .product(product) .title(askRequest.getTitle()) .content(askRequest.getTitle()) + .state("답변예정") .build() ; } diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskByProductResponse.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskByProductResponse.java index 09c2dfdc..a6bf146b 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskByProductResponse.java +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskByProductResponse.java @@ -1,13 +1,14 @@ package project.trendpick_pro.domain.ask.entity.dto.response; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; -import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; - +import com.querydsl.core.annotations.QueryProjection; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class AskByProductResponse { Long id; String state; @@ -15,6 +16,7 @@ public class AskByProductResponse { String username; String date; + @QueryProjection public AskByProductResponse(Long id, String state, String title, String username, LocalDateTime localDateTime) { this.id = id; this.state = state; diff --git a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryImpl.java index 1731e509..3a43805e 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryImpl.java @@ -1,61 +1,61 @@ -//package project.trendpick_pro.domain.ask.repository; -// -//import com.querydsl.core.types.dsl.BooleanExpression; -//import com.querydsl.jpa.impl.JPAQuery; -//import com.querydsl.jpa.impl.JPAQueryFactory; -//import jakarta.persistence.EntityManager; -//import org.springframework.data.domain.Page; -//import org.springframework.data.domain.Pageable; -//import org.springframework.data.support.PageableExecutionUtils; -//import project.trendpick_pro.domain.ask.entity.QAsk; -//import project.trendpick_pro.domain.ask.entity.dto.request.AskByProductRequest; -//import project.trendpick_pro.domain.ask.entity.dto.response.AskByProductResponse; -//import project.trendpick_pro.domain.ask.entity.dto.response.QAskResponse; -//import project.trendpick_pro.domain.member.entity.QMember; -//import project.trendpick_pro.domain.product.entity.QProduct; -// -//import java.util.List; -// -//import static com.querydsl.core.QueryModifiers.offset; -//import static project.trendpick_pro.domain.ask.entity.QAsk.*; -//import static project.trendpick_pro.domain.brand.entity.QBrand.brand; -//import static project.trendpick_pro.domain.category.entity.QMainCategory.mainCategory; -//import static project.trendpick_pro.domain.category.entity.QSubCategory.subCategory; -//import static project.trendpick_pro.domain.common.file.QCommonFile.commonFile; -//import static project.trendpick_pro.domain.member.entity.QMember.*; -//import static project.trendpick_pro.domain.product.entity.QProduct.product; -// -//public class AskRepositoryImpl implements AskRepositoryCustom { -// -// private final JPAQueryFactory queryFactory; -// -// public AskRepositoryImpl(EntityManager em) { -// this.queryFactory = new JPAQueryFactory(em); -// } -// -// @Override -// public Page findAllByProduct(AskByProductRequest request, Pageable pageable) { -// List result = queryFactory -// .select(new QAskByProductResponse( -// ask.id, -// ask.title, -// ask.author.username, -// ask.createdDate -// )) -// .from(ask) -// .leftJoin(ask.product, product) -// .where( -// askByProductEq(request) -// ) -// .offset(0) -// .limit(10) -// .fetch(); -// -// -// return null; -// } -// -// private static BooleanExpression askByProductEq(AskByProductRequest request) { -// return ask.product.id.eq(request.getProductId()); -// } -//} +package project.trendpick_pro.domain.ask.repository; + +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQuery; +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.support.PageableExecutionUtils; +import project.trendpick_pro.domain.ask.entity.QAsk; +import project.trendpick_pro.domain.ask.entity.dto.request.AskByProductRequest; +import project.trendpick_pro.domain.ask.entity.dto.response.AskByProductResponse; +import project.trendpick_pro.domain.ask.entity.dto.response.QAskByProductResponse; + +import java.util.List; + +import static project.trendpick_pro.domain.ask.entity.QAsk.ask; +import static project.trendpick_pro.domain.product.entity.QProduct.product; + +public class AskRepositoryImpl implements AskRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + public AskRepositoryImpl(EntityManager em) { + this.queryFactory = new JPAQueryFactory(em); + } + + @Override + public Page findAllByProduct(AskByProductRequest request, Pageable pageable) { + List result = queryFactory + .select(new QAskByProductResponse( + ask.id, + ask.state, + ask.title, + ask.author.username, + ask.createdDate + )) + .from(ask) + .leftJoin(ask.product, product) + .where( + askByProductEq(request) + ) + .offset(0) + .limit(10) + .fetch(); + + JPAQuery count = queryFactory + .select(ask.count()) + .from(ask) + .leftJoin(ask.product, product) + .where( + askByProductEq(request) + ); + + return PageableExecutionUtils.getPage(result, pageable, count::fetchOne); + } + + private static BooleanExpression askByProductEq(AskByProductRequest request) { + return ask.product.id.eq(request.getProductId()); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 5b9c3f73..f2603aac 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -20,19 +20,19 @@ public class OrderController { private final OrderService orderService; - @PostMapping("/order") - public String order(@Valid OrderSaveRequest... orderSaveRequests){ - - orderService.order(1L, orderSaveRequests); - return "redirect:/orders"; - } - - @GetMapping("/list") - public String orderList(Model model) { - Page responses = orderService.findAll(1L); - model.addAttribute("orders", responses); - return "trendpick/usr/member/orders"; - } +// @PostMapping("/order") +// public String order(@Valid OrderSaveRequest... orderSaveRequests){ +// +// orderService.order(1L, orderSaveRequests); +// return "redirect:/orders"; +// } + +// @GetMapping("/list") +// public String orderList(Model model) { +// Page responses = orderService.findAll(1L); +// model.addAttribute("orders", responses); +// return "trendpick/usr/member/orders"; +// } @PostMapping("/orders/{orderId}/cancel") public String cancelOrder(@PathVariable("orderId") Long orderId) { From df8b4d4b30e11ea7a07d9e0e18e2d2c73a49b01a Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 30 May 2023 00:25:45 +0900 Subject: [PATCH 073/367] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20=EB=AC=B8?= =?UTF-8?q?=EC=9D=98=EB=82=B4=EC=97=AD=20=EC=84=9C=EB=B9=84=EC=8A=A4=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/ask/controller/AskController.java | 1 + .../domain/ask/service/AskService.java | 19 ++++++++++++-- .../orders/contoller/OrderController.java | 26 +++++++++---------- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java index b6f08b14..93533df4 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java +++ b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java @@ -21,6 +21,7 @@ public class AskController { @GetMapping("/list") public String showAsksByProduct(@RequestParam("page") int offset, @RequestParam("product") Long productId, Model model) { model.addAttribute("askResponse", askService.showAsksByProduct(offset, productId)); + return "trendpick/customerservice/asks/list"; } diff --git a/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java b/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java index 56f863c0..ed992014 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java +++ b/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java @@ -1,12 +1,15 @@ package project.trendpick_pro.domain.ask.service; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.ask.entity.Ask; +import project.trendpick_pro.domain.ask.entity.dto.request.AskByProductRequest; import project.trendpick_pro.domain.ask.entity.dto.request.AskRequest; +import project.trendpick_pro.domain.ask.entity.dto.response.AskByProductResponse; import project.trendpick_pro.domain.ask.entity.dto.response.AskResponse; import project.trendpick_pro.domain.ask.repository.AskRepository; import project.trendpick_pro.domain.member.entity.Member; @@ -24,14 +27,26 @@ public class AskService { private final AskRepository askRepository; private final ProductRepository productRepository; - public List showAsksByProduct(int offset, Long productId) { + //상품 상세에서 문의 내역 볼 때 + public Page showAsksByProduct(int offset, Long productId) { Pageable pageable = PageRequest.of(offset, 10); + AskByProductRequest request = new AskByProductRequest(productId); - List responses = new ArrayList<>(); + Page responses = askRepository.findAllByProduct(request, pageable); return responses; } + //마이페이지 나의 문의 내역 볼 때 +// public Page showAsksByMyPage(int offset, Long productId) { +// Pageable pageable = PageRequest.of(offset, 10); +// AskByProductRequest request = new AskByProductRequest(productId); +// +// Page responses = askRepository.findAllByProduct(request, pageable); +// +// return responses; +// } + public AskResponse show(Long askId) { Ask ask = askRepository.findById(askId).orElseThrow(); diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index f2603aac..5b9c3f73 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -20,19 +20,19 @@ public class OrderController { private final OrderService orderService; -// @PostMapping("/order") -// public String order(@Valid OrderSaveRequest... orderSaveRequests){ -// -// orderService.order(1L, orderSaveRequests); -// return "redirect:/orders"; -// } - -// @GetMapping("/list") -// public String orderList(Model model) { -// Page responses = orderService.findAll(1L); -// model.addAttribute("orders", responses); -// return "trendpick/usr/member/orders"; -// } + @PostMapping("/order") + public String order(@Valid OrderSaveRequest... orderSaveRequests){ + + orderService.order(1L, orderSaveRequests); + return "redirect:/orders"; + } + + @GetMapping("/list") + public String orderList(Model model) { + Page responses = orderService.findAll(1L); + model.addAttribute("orders", responses); + return "trendpick/usr/member/orders"; + } @PostMapping("/orders/{orderId}/cancel") public String cancelOrder(@PathVariable("orderId") Long orderId) { From ca84b11f550f0e49b8063416f9ca8af6cb30507b Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Tue, 30 May 2023 15:00:24 +0900 Subject: [PATCH 074/367] =?UTF-8?q?refactor:=20file=20=EA=B4=80=EB=A0=A8?= =?UTF-8?q?=20=EB=82=B4=EC=9A=A9=20=EB=B0=98=EC=98=81=EB=90=98=EB=8F=84?= =?UTF-8?q?=EB=A1=9D=20=EA=B8=B0=EB=B3=B8=20=EB=A1=9C=EC=A7=81=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 13 +++-- .../domain/review/entity/Review.java | 50 +++++++++++++------ .../dto/request/ReviewCreateRequest.java | 24 +++++++++ .../entity/dto/request/ReviewRequest.java | 12 ----- .../dto/request/ReviewUpdateRequest.java | 17 +++++++ .../entity/dto/response/ReviewResponse.java | 34 ++++++++++--- .../domain/review/service/ReviewService.java | 18 ++++--- 7 files changed, 121 insertions(+), 47 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewCreateRequest.java delete mode 100644 src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewRequest.java create mode 100644 src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewUpdateRequest.java diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index b059e331..2c247e8b 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -5,11 +5,10 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; -import project.trendpick_pro.domain.ask.entity.dto.request.AskRequest; -import project.trendpick_pro.domain.ask.entity.dto.response.AskResponse; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.review.entity.dto.request.ReviewRequest; +import project.trendpick_pro.domain.review.entity.dto.request.ReviewCreateRequest; +import project.trendpick_pro.domain.review.entity.dto.request.ReviewUpdateRequest; import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; import project.trendpick_pro.domain.review.service.ReviewService; @@ -21,9 +20,9 @@ public class ReviewController { private final Rq rq; @PostMapping("/write") - public String createReview(@Valid ReviewRequest reviewRequest, @RequestParam(value = "productId") Long productId, Model model) { + public String createReview(@Valid ReviewCreateRequest reviewCreateRequest, @RequestParam(value = "product") Long productId, Model model) { Member actor = rq.getMember(); - ReviewResponse reviewResponse = reviewService.createReview(actor, productId, reviewRequest); + ReviewResponse reviewResponse = reviewService.createReview(actor, productId, reviewCreateRequest); model.addAttribute("reviewResponse", reviewResponse); return "redirect:/trendpick/review"; @@ -45,8 +44,8 @@ public String deleteReview(@PathVariable Long reviewId) { } @PostMapping("/edit/{reviewId}") - public String modifyReview(@PathVariable Long reviewId, @Valid ReviewRequest reviewRequest, Model model) { - ReviewResponse reviewResponse = reviewService.modify(reviewId, reviewRequest); + public String modifyReview(@PathVariable Long reviewId, ReviewUpdateRequest reviewUpdateRequest, Model model) { + ReviewResponse reviewResponse = reviewService.modify(reviewId, reviewUpdateRequest); model.addAttribute("reviewResponse", reviewResponse); return "redirect:/trendpick/review"; diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java index 83ee326c..0f2890a0 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -6,9 +6,11 @@ import lombok.Getter; import lombok.NoArgsConstructor; import project.trendpick_pro.domain.common.base.BaseTimeEntity; +import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.review.entity.dto.request.ReviewRequest; -import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; +import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.review.entity.dto.request.ReviewCreateRequest; +import project.trendpick_pro.domain.review.entity.dto.request.ReviewUpdateRequest; @Entity @NoArgsConstructor @@ -20,28 +22,48 @@ public class Review extends BaseTimeEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - private String username; //User + @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @JoinColumn(name = "member_id") + private Member writer; -// @ManyToOne(fetch = FetchType.LAZY) - //@JoinColumn(name = "product_id") - private Long productId; //Product + @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @JoinColumn(name = "common_file_id") + private CommonFile commonFile; + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "product_id") + private Product product; //Product + + private String title; @Lob private String content; private int rating; - public static Review of(String username, Long productId, ReviewRequest reviewRequest) { + @Builder + public Review(Member member, Product product, CommonFile commonFile, String title, String content, int rating){ + this.writer = member; + this.product = product; + this.commonFile = commonFile; + this.title = title; + this.content = content; + this.rating = rating; + } + + public static Review of(ReviewCreateRequest reviewCreateRequest, Member member, Product product) { return Review.builder() - .username(username) - .productId(productId) - .content(reviewRequest.getContent()) - .rating(reviewRequest.getRating()) + .writer(member) + .product(product) + //.commonFile(reviewRequest.getMainFile()); + .content(reviewCreateRequest.getContent()) + .rating(reviewCreateRequest.getRating()) .build(); } - public void update(ReviewRequest reviewRequest) { - this.content = reviewRequest.getContent(); - this.rating = reviewRequest.getRating(); + public void update(ReviewUpdateRequest reviewUpdateRequest){ + this.title = reviewUpdateRequest.getTitle(); + this.content = reviewUpdateRequest.getContent(); + //this.commonFile = reviewUpdateRequest.getMainFile(); + this.rating = reviewUpdateRequest.getRating(); } } diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewCreateRequest.java b/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewCreateRequest.java new file mode 100644 index 00000000..4b568fdc --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewCreateRequest.java @@ -0,0 +1,24 @@ +package project.trendpick_pro.domain.review.entity.dto.request; + + +import jakarta.validation.constraints.NotBlank; +import lombok.Data; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +@Data +public class ReviewCreateRequest { + @NotBlank(message = "제목을 입력해주세요") + private String title; + @NotBlank(message = "내용을 입력해주세요") + private String content; + + @NotBlank(message = "메인으로 사용하실 사진을 입력해주세요") + private MultipartFile mainFile; + + @NotBlank(message = "추가적으로 사용하실 사진을 입력해주세요") + private List subFiles; + + private int rating; +} diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewRequest.java b/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewRequest.java deleted file mode 100644 index 9c4054a9..00000000 --- a/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewRequest.java +++ /dev/null @@ -1,12 +0,0 @@ -package project.trendpick_pro.domain.review.entity.dto.request; - - -import jakarta.validation.constraints.NotBlank; -import lombok.Getter; - -@Getter -public class ReviewRequest { - @NotBlank - private String content; - private int rating; -} diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewUpdateRequest.java b/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewUpdateRequest.java new file mode 100644 index 00000000..642435c0 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewUpdateRequest.java @@ -0,0 +1,17 @@ +package project.trendpick_pro.domain.review.entity.dto.request; + +import jakarta.validation.constraints.NotBlank; +import lombok.Data; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +@Data +public class ReviewUpdateRequest { + private String title; + private String content; + private MultipartFile mainFile; + private List subFiles; + private int rating; + +} diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java b/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java index 6e987971..b42293fd 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java @@ -6,39 +6,61 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.review.entity.Review; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ReviewResponse { private Long id; - private String username; //User + private String writer; //User private Long productId; //Product - @Lob + private String mainFile; + private List subFiles; + private String title; + private String content; private int rating; @Builder @QueryProjection - public ReviewResponse(Long id, String username, Long productId, String content, int rating) { + public ReviewResponse(Long id, String writer, Long productId, String title, String content, + String mainFile, List subFiles, int rating) { this.id = id; - this.username = username; + this.writer = writer; this.productId = productId; + this.title = title; this.content = content; + this.mainFile = mainFile; + this.subFiles = subFiles; this.rating = rating; } public static ReviewResponse of(Review review) { return ReviewResponse.builder() .id(review.getId()) - .username(review.getUsername()) - .productId(review.getProductId()) + .writer(review.getWriter().getUsername()) + .productId(review.getProduct().getId()) + .title(review.getTitle()) .content(review.getContent()) + .mainFile(review.getCommonFile().getFileName()) + .subFiles(subFiles(review.getCommonFile().getChild())) .rating(review.getRating()) .build(); } + + private static List subFiles(List subFiles) { + List tmpList = new ArrayList<>(); + + for (CommonFile subFile : subFiles) { + tmpList.add(subFile.getFileName()); + } + return tmpList; + } } diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index d5bc3421..ddb17c64 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -3,10 +3,12 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.review.entity.Review; -import project.trendpick_pro.domain.review.entity.dto.request.ReviewRequest; +import project.trendpick_pro.domain.review.entity.dto.request.ReviewCreateRequest; +import project.trendpick_pro.domain.review.entity.dto.request.ReviewUpdateRequest; import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; import project.trendpick_pro.domain.review.repository.ReviewRepository; @@ -16,7 +18,7 @@ @RequiredArgsConstructor public class ReviewService { private final ReviewRepository reviewRepository; - + private final ProductRepository productRepository; public ReviewResponse showReview(Long productId) { @@ -30,17 +32,17 @@ public void delete(Long reviewId) { reviewRepository.deleteById(reviewId); } - public ReviewResponse createReview(Member actor, Long productId, ReviewRequest reviewRequest) { - String username = actor.getUsername(); + public ReviewResponse createReview(Member actor, Long productId, ReviewCreateRequest reviewCreateRequest) { + Product product = productRepository.findById(productId).orElseThrow(); - Review review = Review.of(username, productId, reviewRequest); + Review review = Review.of(reviewCreateRequest, actor, product); return ReviewResponse.of(review); } - public ReviewResponse modify(Long reviewId, ReviewRequest reviewRequest) { + public ReviewResponse modify(Long reviewId, ReviewUpdateRequest reviewUpdateRequest) { Review review = reviewRepository.findById(reviewId).orElseThrow(); - review.update(reviewRequest); + review.update(reviewUpdateRequest); return ReviewResponse.of(review); } } From 4f59feb91b3bec6b38fe3789489eb15d5a7f8891 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Tue, 30 May 2023 15:16:08 +0900 Subject: [PATCH 075/367] =?UTF-8?q?docs:=20spring=20=EB=B2=84=EC=A0=84=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index d976019d..20e166b7 100644 --- a/build.gradle +++ b/build.gradle @@ -1,6 +1,6 @@ plugins { id 'java' - id 'org.springframework.boot' version '3.1.0' + id 'org.springframework.boot' version '3.0.7' id 'io.spring.dependency-management' version '1.1.0' } @@ -32,13 +32,17 @@ dependencies { // thymeleaf implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' - implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' implementation group: 'com.github.zhanhb', name: 'thymeleaf-layout-dialect', version: '3.2.0' // lombok annotationProcessor 'org.projectlombok:lombok' compileOnly 'org.projectlombok:lombok' + // spring security + implementation 'com.fasterxml.jackson.datatype:jackson-datatype-hibernate5' + implementation 'org.thymeleaf.extras:thymeleaf-extras-springsecurity6' + testImplementation 'org.springframework.security:spring-security-test' + // 카카오 로그인, 구글 로그인, 네이버 로그인 implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' From e678b3e89ac3e381ca0a45940dab78ae002fb883 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Tue, 30 May 2023 20:03:33 +0900 Subject: [PATCH 076/367] =?UTF-8?q?feat:=20=EB=A6=AC=EB=B7=B0=20=EC=82=AC?= =?UTF-8?q?=EC=A7=84=20=ED=95=A8=EA=BB=98=20=EB=93=B1=EB=A1=9D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 8 +- .../domain/review/entity/Review.java | 75 ++++++++++++++++--- .../entity/dto/response/ReviewResponse.java | 15 +--- .../domain/review/service/ReviewService.java | 68 ++++++++++++++++- 4 files changed, 139 insertions(+), 27 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index 2c247e8b..332aa19f 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -5,6 +5,7 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.review.entity.dto.request.ReviewCreateRequest; @@ -12,6 +13,8 @@ import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; import project.trendpick_pro.domain.review.service.ReviewService; +import java.util.List; + @Controller @RequiredArgsConstructor @RequestMapping("/trendpick/review") @@ -20,9 +23,10 @@ public class ReviewController { private final Rq rq; @PostMapping("/write") - public String createReview(@Valid ReviewCreateRequest reviewCreateRequest, @RequestParam(value = "product") Long productId, Model model) { + public String createReview(@Valid ReviewCreateRequest reviewCreateRequest, @RequestParam(value = "product") Long productId, + @RequestPart("main-file") MultipartFile mainFile, @RequestPart("sub-file") List subFileList, Model model) throws Exception { Member actor = rq.getMember(); - ReviewResponse reviewResponse = reviewService.createReview(actor, productId, reviewCreateRequest); + ReviewResponse reviewResponse = reviewService.createReview(actor, productId, reviewCreateRequest, mainFile, subFileList); model.addAttribute("reviewResponse", reviewResponse); return "redirect:/trendpick/review"; diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java index 0f2890a0..3890209e 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -5,6 +5,8 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.common.base.BaseTimeEntity; import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.member.entity.Member; @@ -12,6 +14,12 @@ import project.trendpick_pro.domain.review.entity.dto.request.ReviewCreateRequest; import project.trendpick_pro.domain.review.entity.dto.request.ReviewUpdateRequest; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + @Entity @NoArgsConstructor @AllArgsConstructor @@ -22,13 +30,15 @@ public class Review extends BaseTimeEntity { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @ManyToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @JoinColumn(name = "member_id") - private Member writer; + private String writer; + + @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE) + @JoinColumn(name = "review_image_id") + private ReviewImage reviewImage; - @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @JoinColumn(name = "common_file_id") - private CommonFile commonFile; +// @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) +// @JoinColumn(name = "common_file_id") +// private CommonFile commonFile; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "product_id") @@ -41,20 +51,28 @@ public class Review extends BaseTimeEntity { private int rating; @Builder - public Review(Member member, Product product, CommonFile commonFile, String title, String content, int rating){ - this.writer = member; + public Review(Member member, Product product, String title, String content, int rating){ + this.writer = member.getUsername(); this.product = product; - this.commonFile = commonFile; this.title = title; this.content = content; this.rating = rating; } + @Builder + public Review(Member member, Product product, ReviewCreateRequest reviewCreateRequest){ + this.writer = member.getUsername(); + this.product = product; + this.title = reviewCreateRequest.getTitle(); + this.content = reviewCreateRequest.getContent(); + this.rating = reviewCreateRequest.getRating(); + } + public static Review of(ReviewCreateRequest reviewCreateRequest, Member member, Product product) { return Review.builder() - .writer(member) + .writer(member.getUsername()) .product(product) - //.commonFile(reviewRequest.getMainFile()); + //.commonFile(makeFile(reviewCreateRequest.getMainFile(), reviewCreateRequest.getSubFiles())); .content(reviewCreateRequest.getContent()) .rating(reviewCreateRequest.getRating()) .build(); @@ -66,4 +84,39 @@ public void update(ReviewUpdateRequest reviewUpdateRequest){ //this.commonFile = reviewUpdateRequest.getMainFile(); this.rating = reviewUpdateRequest.getRating(); } + + public void matchReviewImage(ReviewImage reviewImage){ + this.reviewImage = reviewImage; + } + +// @Value("${file.dir}") +// private static String filePath; +// +// private static String createStoreFileName(String originFileName){ +// String ext = extractExt(originFileName); +// String uuid = UUID.randomUUID().toString(); +// return uuid + "." + ext; +// } +// +// private static String extractExt(String originFileName) { +// int pos = originFileName.lastIndexOf("."); +// return originFileName.substring(pos + 1); +// } + +// private static CommonFile makeFile(MultipartFile mainFile, List subFiles) throws IOException { +// String mainFileName = createStoreFileName(mainFile.getOriginalFilename()); +// List subFileName = new ArrayList<>(); +// +// mainFile.transferTo(new File(filePath + mainFileName)); +// +// for(MultipartFile subFile : subFiles){ +// String savePath = createStoreFileName(subFile.getOriginalFilename()); +// subFileName.add(savePath); +// subFile.transferTo(new File(filePath + savePath)); +// } +// +// return null; +// +// +// } } diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java b/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java index b42293fd..458a71a8 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java @@ -45,22 +45,13 @@ public ReviewResponse(Long id, String writer, Long productId, String title, Stri public static ReviewResponse of(Review review) { return ReviewResponse.builder() .id(review.getId()) - .writer(review.getWriter().getUsername()) + .writer(review.getWriter()) .productId(review.getProduct().getId()) .title(review.getTitle()) .content(review.getContent()) - .mainFile(review.getCommonFile().getFileName()) - .subFiles(subFiles(review.getCommonFile().getChild())) + .mainFile(review.getReviewImage().getMainFileName()) + .subFiles(review.getReviewImage().getSubFileNames()) .rating(review.getRating()) .build(); } - - private static List subFiles(List subFiles) { - List tmpList = new ArrayList<>(); - - for (CommonFile subFile : subFiles) { - tmpList.add(subFile.getFileName()); - } - return tmpList; - } } diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index ddb17c64..98975dbb 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -1,17 +1,28 @@ package project.trendpick_pro.domain.review.service; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.review.entity.Review; +import project.trendpick_pro.domain.review.entity.ReviewImage; import project.trendpick_pro.domain.review.entity.dto.request.ReviewCreateRequest; import project.trendpick_pro.domain.review.entity.dto.request.ReviewUpdateRequest; import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; +import project.trendpick_pro.domain.review.repository.ReviewImageRepository; import project.trendpick_pro.domain.review.repository.ReviewRepository; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + @Service @Transactional(readOnly = true) @@ -19,6 +30,10 @@ public class ReviewService { private final ReviewRepository reviewRepository; private final ProductRepository productRepository; + private final ReviewImageRepository reviewImageRepository; + + @Value("${file.dir}") + private static String filePath; public ReviewResponse showReview(Long productId) { @@ -32,10 +47,21 @@ public void delete(Long reviewId) { reviewRepository.deleteById(reviewId); } - public ReviewResponse createReview(Member actor, Long productId, ReviewCreateRequest reviewCreateRequest) { + public ReviewResponse createReview(Member actor, Long productId, ReviewCreateRequest reviewCreateRequest, MultipartFile mainFile, List subFiles) throws Exception { Product product = productRepository.findById(productId).orElseThrow(); + //사진 없는 리뷰만 일단 저장 + Review review = new Review(actor, product, reviewCreateRequest); + reviewRepository.save(review); + + //메인 이미지 파일 저장 + String mainFileName = saveMainFile(mainFile); + ReviewImage reviewImage = new ReviewImage(mainFileName, review); + reviewImageRepository.save(reviewImage); + + //서브 이미지 파일 저장 + saveSubFiles(subFiles, reviewImage); + review.matchReviewImage(reviewImage); - Review review = Review.of(reviewCreateRequest, actor, product); return ReviewResponse.of(review); } @@ -45,4 +71,42 @@ public ReviewResponse modify(Long reviewId, ReviewUpdateRequest reviewUpdateRequ review.update(reviewUpdateRequest); return ReviewResponse.of(review); } + + public static String createStoreFileName(String originalFilename) { + String ext = extractExt(originalFilename); + String uuid = UUID.randomUUID().toString(); + return uuid + "." + ext; + } + + public static String extractExt(String originalFilename) { + int pos = originalFilename.lastIndexOf("."); + return originalFilename.substring(pos + 1); + } + + public static List saveSubImages(String filePath, List subFiles) throws IOException { + + List subFilePaths = new ArrayList<>(); + + for (MultipartFile subFile : subFiles) { + if (subFile.getOriginalFilename() != null) { + String savePath = createStoreFileName(subFile.getOriginalFilename()); + subFilePaths.add(savePath); + subFile.transferTo(new File(filePath + savePath)); + } + } + return subFilePaths; + } + + private String saveMainFile(MultipartFile mainFile) throws IOException{ + String mainFileName = createStoreFileName(mainFile.getOriginalFilename()); + mainFile.transferTo(new File(filePath + mainFileName)); + + return mainFileName; + } + + private void saveSubFiles(List subFiles, ReviewImage reviewImage) throws IOException{ + List subFilePaths = saveSubImages(filePath, subFiles); + reviewImage.saveSubFileNames(subFilePaths); + } + } From 95c00729a9b2f0f1ea884c9f7e19ec146a30568a Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Tue, 30 May 2023 20:10:14 +0900 Subject: [PATCH 077/367] =?UTF-8?q?feat:=20=EB=A6=AC=EB=B7=B0=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/review/entity/ReviewImage.java | 49 +++++++++++++++++++ .../repository/ReviewImageRepository.java | 9 ++++ .../domain/review/service/ReviewService.java | 5 +- 3 files changed, 62 insertions(+), 1 deletion(-) create mode 100644 src/main/java/project/trendpick_pro/domain/review/entity/ReviewImage.java create mode 100644 src/main/java/project/trendpick_pro/domain/review/repository/ReviewImageRepository.java diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/ReviewImage.java b/src/main/java/project/trendpick_pro/domain/review/entity/ReviewImage.java new file mode 100644 index 00000000..11893930 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/review/entity/ReviewImage.java @@ -0,0 +1,49 @@ +package project.trendpick_pro.domain.review.entity; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import org.springframework.web.multipart.MultipartFile; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ReviewImage { + @Id @GeneratedValue(strategy = GenerationType.AUTO) + @Column(name = "review_image_id") + private Long id; + + private String mainFileName; + + @ElementCollection(fetch = FetchType.LAZY) + private List subFileNames = new ArrayList<>(); + + @OneToOne(mappedBy = "reviewImage", fetch = FetchType.LAZY) + private Review review; + + public ReviewImage(String mainFileName, Review review){ + this.mainFileName = mainFileName; + this.review = review; + } + + public void deleteImage(String filePath){ + for(String subFile : subFileNames){ + File file = new File(filePath + subFile); + file.delete(); + } + File file = new File(filePath + mainFileName); + file.delete(); + } + + public void saveSubFileNames(List subFileNames) { + this.subFileNames = subFileNames; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/review/repository/ReviewImageRepository.java b/src/main/java/project/trendpick_pro/domain/review/repository/ReviewImageRepository.java new file mode 100644 index 00000000..40e20cb1 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/review/repository/ReviewImageRepository.java @@ -0,0 +1,9 @@ +package project.trendpick_pro.domain.review.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +import project.trendpick_pro.domain.review.entity.ReviewImage; + +@Repository +public interface ReviewImageRepository extends JpaRepository { +} diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index 98975dbb..0b61f45c 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -44,7 +44,10 @@ public ReviewResponse showReview(Long productId) { public void delete(Long reviewId) { - reviewRepository.deleteById(reviewId); + Review review = reviewRepository.findById(reviewId).orElseThrow(); + + review.getReviewImage().deleteImage(filePath); + reviewRepository.delete(review); } public ReviewResponse createReview(Member actor, Long productId, ReviewCreateRequest reviewCreateRequest, MultipartFile mainFile, List subFiles) throws Exception { From 972d9770c8025e77adf3f8b4f0390d34ba9cc8d9 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Tue, 30 May 2023 22:36:45 +0900 Subject: [PATCH 078/367] =?UTF-8?q?feat:=20=EB=A6=AC=EB=B7=B0=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 7 +++++-- .../domain/review/entity/ReviewImage.java | 17 +++++++++++++++++ .../domain/review/service/ReviewService.java | 13 ++++++++++++- 3 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index 332aa19f..7d5d95c5 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -1,6 +1,7 @@ package project.trendpick_pro.domain.review.controller; import jakarta.validation.Valid; +import jakarta.validation.constraints.NotBlank; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -13,6 +14,7 @@ import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; import project.trendpick_pro.domain.review.service.ReviewService; +import java.io.IOException; import java.util.List; @Controller @@ -48,8 +50,9 @@ public String deleteReview(@PathVariable Long reviewId) { } @PostMapping("/edit/{reviewId}") - public String modifyReview(@PathVariable Long reviewId, ReviewUpdateRequest reviewUpdateRequest, Model model) { - ReviewResponse reviewResponse = reviewService.modify(reviewId, reviewUpdateRequest); + public String updateReview(@PathVariable Long reviewId, ReviewUpdateRequest reviewUpdateRequest, + @RequestPart("main-file") @NotBlank MultipartFile mainImage, @RequestPart("sub-file") List subImages, Model model) throws IOException { + ReviewResponse reviewResponse = reviewService.update(reviewId, reviewUpdateRequest, mainImage, subImages); model.addAttribute("reviewResponse", reviewResponse); return "redirect:/trendpick/review"; diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/ReviewImage.java b/src/main/java/project/trendpick_pro/domain/review/entity/ReviewImage.java index 11893930..c76d6aeb 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/ReviewImage.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/ReviewImage.java @@ -46,4 +46,21 @@ public void deleteImage(String filePath){ public void saveSubFileNames(List subFileNames) { this.subFileNames = subFileNames; } + + public void changeMainFile(String filePath, String mainFilePath, MultipartFile mainFile) throws IOException { + File file = new File(filePath + mainFileName); + file.delete(); //원래 있던거 삭제 + + this.mainFileName = mainFilePath; + mainFile.transferTo(new File(filePath + mainFilePath)); + } + + public void changeSubFile(String filePath, List subFileNames) { + //음 우선 돌면서 지워야겠지?? + for(String subFile: subFileNames){ + File file = new File(filePath + subFile); + file.delete(); + } + this.subFileNames = subFileNames; + } } diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index 0b61f45c..cc6f7c93 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -68,8 +68,19 @@ public ReviewResponse createReview(Member actor, Long productId, ReviewCreateReq return ReviewResponse.of(review); } - public ReviewResponse modify(Long reviewId, ReviewUpdateRequest reviewUpdateRequest) { + public ReviewResponse update(Long reviewId, ReviewUpdateRequest reviewUpdateRequest, MultipartFile mainFile, List subFiles) throws IOException { Review review = reviewRepository.findById(reviewId).orElseThrow(); + ReviewImage reviewImage = review.getReviewImage(); + + //메인 파일 이름을 아예 있던거 없애고 바꿔버리기! + reviewImage.changeMainFile(filePath, createStoreFileName(mainFile.getOriginalFilename()), mainFile); + + //서브 파일도 같은 방식으로 + //비어있는 경우도 생각.,,? + //ReviewImage 엔티티에서 가능하니까 거기 메소드를 만들어보쟈 + //reviewImage.changeSubFile(filePath, subFiles); => List으로 만들어 보내야함 + List fileList = saveSubImages(filePath, subFiles); + reviewImage.changeSubFile(filePath, fileList); review.update(reviewUpdateRequest); return ReviewResponse.of(review); From 0b4a48f0571016276218805b8c68d85ac1bb9c49 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Tue, 30 May 2023 23:43:38 +0900 Subject: [PATCH 079/367] =?UTF-8?q?docs:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85,=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=ED=8F=BC=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(#67)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../security/CustomUserDetailsService.java | 25 ----- .../common/base/security/SecurityConfig.java | 35 ------- .../static/resource/common/common.css | 16 +++ .../static/resource/common/common.js | 50 ++++++++++ .../templates/trendpick/products/list.html | 1 + .../templates/trendpick/usr/member/join.html | 99 ++++++------------- .../templates/trendpick/usr/member/login.html | 70 +++---------- 7 files changed, 115 insertions(+), 181 deletions(-) delete mode 100644 src/main/java/project/trendpick_pro/domain/common/base/security/CustomUserDetailsService.java delete mode 100644 src/main/java/project/trendpick_pro/domain/common/base/security/SecurityConfig.java create mode 100644 src/main/resources/static/resource/common/common.css create mode 100644 src/main/resources/static/resource/common/common.js diff --git a/src/main/java/project/trendpick_pro/domain/common/base/security/CustomUserDetailsService.java b/src/main/java/project/trendpick_pro/domain/common/base/security/CustomUserDetailsService.java deleted file mode 100644 index 66bf8b8e..00000000 --- a/src/main/java/project/trendpick_pro/domain/common/base/security/CustomUserDetailsService.java +++ /dev/null @@ -1,25 +0,0 @@ -package project.trendpick_pro.domain.common.base.security; - -import lombok.RequiredArgsConstructor; -import org.springframework.security.core.userdetails.User; -import org.springframework.security.core.userdetails.UserDetails; -import org.springframework.security.core.userdetails.UserDetailsService; -import org.springframework.security.core.userdetails.UsernameNotFoundException; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.member.repository.MemberRepository; - -@Service -@RequiredArgsConstructor -@Transactional(readOnly = false) -public class CustomUserDetailsService implements UserDetailsService { - private final MemberRepository memberRepository; - - @Override - public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { - Member member = memberRepository.findByUsername(username).orElseThrow(() -> new UsernameNotFoundException("username(%s) not found".formatted(username))); - - return new User(member.getUsername(), member.getPassword(), member.getGrantedAuthorities()); - } -} diff --git a/src/main/java/project/trendpick_pro/domain/common/base/security/SecurityConfig.java b/src/main/java/project/trendpick_pro/domain/common/base/security/SecurityConfig.java deleted file mode 100644 index 6a548112..00000000 --- a/src/main/java/project/trendpick_pro/domain/common/base/security/SecurityConfig.java +++ /dev/null @@ -1,35 +0,0 @@ -package project.trendpick_pro.domain.common.base.security; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity; -import org.springframework.security.config.annotation.web.builders.HttpSecurity; -import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; -import org.springframework.security.crypto.password.PasswordEncoder; -import org.springframework.security.web.SecurityFilterChain; - -@Configuration -@EnableWebSecurity -@EnableMethodSecurity(prePostEnabled = true) -public class SecurityConfig { - @Bean - SecurityFilterChain filterChain(HttpSecurity http) throws Exception { - http - .formLogin( - formLogin -> formLogin - .loginPage("/trendpick/usr/login") - ) - .logout( - logout -> logout - .logoutUrl("/member/logout") - ); - - return http.build(); - } - - @Bean - PasswordEncoder passwordEncoder() { - return new BCryptPasswordEncoder(); - } -} \ No newline at end of file diff --git a/src/main/resources/static/resource/common/common.css b/src/main/resources/static/resource/common/common.css new file mode 100644 index 00000000..cc24c83e --- /dev/null +++ b/src/main/resources/static/resource/common/common.css @@ -0,0 +1,16 @@ +@font-face { + font-family: 'Pretendard-Regular'; + src: url('https://cdn.jsdelivr.net/gh/Project-Noonnu/noonfonts_2107@1.1/Pretendard-Regular.woff') format('woff'); + font-weight: 400; + font-style: normal; +} + +html > body { + font-family: "Pretendard-Regular", serif; + text-underline-position: under; + word-break: keep-all; +} + +html > body .label-text { + font-size: 1rem; +} \ No newline at end of file diff --git a/src/main/resources/static/resource/common/common.js b/src/main/resources/static/resource/common/common.js new file mode 100644 index 00000000..1049ca15 --- /dev/null +++ b/src/main/resources/static/resource/common/common.js @@ -0,0 +1,50 @@ +toastr.options = { + closeButton: true, + debug: false, + newestOnTop: true, + progressBar: true, + positionClass: "toast-top-right", + preventDuplicates: false, + onclick: null, + showDuration: "300", + hideDuration: "1000", + timeOut: "5000", + extendedTimeOut: "1000", + showEasing: "swing", + hideEasing: "linear", + showMethod: "fadeIn", + hideMethod: "fadeOut" +}; + +function parseMsg(msg) { + const [pureMsg, ttl] = msg.split(";ttl="); + + const currentJsUnixTimestamp = new Date().getTime(); + + if (ttl && parseInt(ttl) + 5000 < currentJsUnixTimestamp) { + return [pureMsg, false]; + } + + return [pureMsg, true]; +} + +function toastNotice(msg) { + const [pureMsg, needToShow] = parseMsg(msg); + + if (needToShow) { + toastr["success"](pureMsg, "알림"); + } +} + +function toastWarning(msg) { + const [pureMsg, needToShow] = parseMsg(msg); + + if (needToShow) { + toastr["warning"](pureMsg, "경고"); + } +} + +// 어떠한 기능을 살짝 늦게(0.1 초 미만) +function setTimeoutZero(callback) { + setTimeout(callback); +} diff --git a/src/main/resources/templates/trendpick/products/list.html b/src/main/resources/templates/trendpick/products/list.html index 566549bd..de01567a 100644 --- a/src/main/resources/templates/trendpick/products/list.html +++ b/src/main/resources/templates/trendpick/products/list.html @@ -5,6 +5,7 @@ Title + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/member/join.html b/src/main/resources/templates/trendpick/usr/member/join.html index 9012ba78..74b9bf89 100644 --- a/src/main/resources/templates/trendpick/usr/member/join.html +++ b/src/main/resources/templates/trendpick/usr/member/join.html @@ -1,76 +1,41 @@ - - + + - 회원가입 + 회원 가입 + + - - -
- - -
-
- +
+

회원 가입

+ +
+ + +

-
- +
+ + +

-
- +
+ + +

+
+ + +

+
+
+ + +

+
+ -
- + - diff --git a/src/main/resources/templates/trendpick/usr/member/login.html b/src/main/resources/templates/trendpick/usr/member/login.html index fafc2e88..f6449136 100644 --- a/src/main/resources/templates/trendpick/usr/member/login.html +++ b/src/main/resources/templates/trendpick/usr/member/login.html @@ -1,62 +1,24 @@ - - + + 로그인 + + - - -
- - -
-
- +
+

로그인

+ +
+ +
-
- -
-
- +
+ +
+ -
+ - - \ No newline at end of file + From 4051d846872e0866a675906430ea847daa992b29 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Tue, 30 May 2023 23:44:10 +0900 Subject: [PATCH 080/367] =?UTF-8?q?feat:=20=EC=98=88=EC=99=B8=EC=B2=98?= =?UTF-8?q?=EB=A6=AC=20=EA=B2=BD=EC=9A=B0=20=EC=B6=94=EA=B0=80,=20?= =?UTF-8?q?=EA=B8=80=EB=A1=9C=EB=B2=8C=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC?= =?UTF-8?q?=ED=97=A8=EB=93=A4=EB=9F=AC=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20(#67)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../MemberAlreadyExistException.java | 14 +++++++ .../exception/MemberNotFoundException.java | 14 +++++++ .../exception/MemberNotMatchException.java | 13 +++++++ .../global/exception/ErrorCode.java | 21 ++++++++++ .../global/exception/ErrorResponse.java | 4 ++ .../exception/GlobalExceptionAdvice.java | 38 +++++++++++++++++++ .../global/exception/baseException.java | 23 +++++++++++ 7 files changed, 127 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/member/exception/MemberAlreadyExistException.java create mode 100644 src/main/java/project/trendpick_pro/domain/member/exception/MemberNotFoundException.java create mode 100644 src/main/java/project/trendpick_pro/domain/member/exception/MemberNotMatchException.java create mode 100644 src/main/java/project/trendpick_pro/global/exception/ErrorCode.java create mode 100644 src/main/java/project/trendpick_pro/global/exception/ErrorResponse.java create mode 100644 src/main/java/project/trendpick_pro/global/exception/GlobalExceptionAdvice.java create mode 100644 src/main/java/project/trendpick_pro/global/exception/baseException.java diff --git a/src/main/java/project/trendpick_pro/domain/member/exception/MemberAlreadyExistException.java b/src/main/java/project/trendpick_pro/domain/member/exception/MemberAlreadyExistException.java new file mode 100644 index 00000000..136192d0 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/member/exception/MemberAlreadyExistException.java @@ -0,0 +1,14 @@ +package project.trendpick_pro.domain.member.exception; + +import org.springframework.http.HttpStatus; +import project.trendpick_pro.global.exception.ErrorCode; +import project.trendpick_pro.global.exception.baseException; + +public class MemberAlreadyExistException extends baseException { + + private static final ErrorCode code = ErrorCode.MEMBER_ALREADY_EXIST; + + public MemberAlreadyExistException(String message) { + super(code, HttpStatus.BAD_REQUEST, message); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotFoundException.java b/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotFoundException.java new file mode 100644 index 00000000..38cc0f1a --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotFoundException.java @@ -0,0 +1,14 @@ +package project.trendpick_pro.domain.member.exception; + +import org.springframework.http.HttpStatus; +import project.trendpick_pro.global.exception.ErrorCode; +import project.trendpick_pro.global.exception.baseException; + +public class MemberNotFoundException extends baseException { + + private static final ErrorCode code = ErrorCode.MEMBER_NOT_FOUND; + + public MemberNotFoundException(String message) { + super(code, HttpStatus.BAD_REQUEST, message); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotMatchException.java b/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotMatchException.java new file mode 100644 index 00000000..a13bfa7b --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotMatchException.java @@ -0,0 +1,13 @@ +package project.trendpick_pro.domain.member.exception; + +import org.springframework.http.HttpStatus; +import project.trendpick_pro.global.exception.ErrorCode; +import project.trendpick_pro.global.exception.baseException; + +public class MemberNotMatchException extends baseException { + private static final ErrorCode code = ErrorCode.MEMBER_NOT_MATCH; + + public MemberNotMatchException(String message) { + super(code, HttpStatus.BAD_REQUEST, message); + } +} diff --git a/src/main/java/project/trendpick_pro/global/exception/ErrorCode.java b/src/main/java/project/trendpick_pro/global/exception/ErrorCode.java new file mode 100644 index 00000000..072686ad --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/exception/ErrorCode.java @@ -0,0 +1,21 @@ +package project.trendpick_pro.global.exception; + +import lombok.Getter; + +@Getter +public enum ErrorCode { + + MEMBER_NOT_FOUND(404, "MEMBER-001", "멤버가 존재하지 않는 경우"), + MEMBER_NOT_MATCH(403, "MEMBER-002", "멤버 권한이 다를 경우"), + MEMBER_ALREADY_EXIST(409, "MEMBER-003", "같은 멤버가 이미 존재하는 경우"); + + private final int status; + private final String code; + private final String description; + + ErrorCode(int status, String code, String description) { + this.status = status; + this.code = code; + this.description = description; + } +} diff --git a/src/main/java/project/trendpick_pro/global/exception/ErrorResponse.java b/src/main/java/project/trendpick_pro/global/exception/ErrorResponse.java new file mode 100644 index 00000000..09765969 --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/exception/ErrorResponse.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.global.exception; + +public record ErrorResponse(String code, String message) { +} diff --git a/src/main/java/project/trendpick_pro/global/exception/GlobalExceptionAdvice.java b/src/main/java/project/trendpick_pro/global/exception/GlobalExceptionAdvice.java new file mode 100644 index 00000000..b3a4123a --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/exception/GlobalExceptionAdvice.java @@ -0,0 +1,38 @@ +package project.trendpick_pro.global.exception; + +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.bind.annotation.RestControllerAdvice; +import project.trendpick_pro.domain.member.exception.MemberAlreadyExistException; +import project.trendpick_pro.domain.member.exception.MemberNotFoundException; +import project.trendpick_pro.domain.member.exception.MemberNotMatchException; + +@Slf4j +@RestControllerAdvice +public class GlobalExceptionAdvice { + + @ExceptionHandler(MemberNotFoundException.class) + public ResponseEntity MEmberNotFoundHandleException(MemberNotFoundException e) { + ErrorCode errorCode = e.getErrorCode(); + log.error("[exceptionHandle] ex", e); + ErrorResponse errorResponse = new ErrorResponse(errorCode.getCode(), e.getMessage()); + return ResponseEntity.status(errorCode.getStatus()).body(errorResponse); + } + + @ExceptionHandler(MemberNotMatchException.class) + public ResponseEntity MemberNotMatchHandleException(MemberNotMatchException e) { + ErrorCode errorCode = e.getErrorCode(); + log.error("[exceptionHandle] ex", e); + ErrorResponse errorResponse = new ErrorResponse(errorCode.getCode(), e.getMessage()); + return ResponseEntity.status(errorCode.getStatus()).body(errorResponse); + } + + @ExceptionHandler(MemberAlreadyExistException.class) + public ResponseEntity MemberAlreadyExistHandleException(MemberAlreadyExistException e) { + ErrorCode errorCode = e.getErrorCode(); + log.error("[exceptionHandle] ex", e); + ErrorResponse errorResponse = new ErrorResponse(errorCode.getCode(), e.getMessage()); + return ResponseEntity.status(errorCode.getStatus()).body(errorResponse); + } +} diff --git a/src/main/java/project/trendpick_pro/global/exception/baseException.java b/src/main/java/project/trendpick_pro/global/exception/baseException.java new file mode 100644 index 00000000..d5e668da --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/exception/baseException.java @@ -0,0 +1,23 @@ +package project.trendpick_pro.global.exception; + +import org.springframework.http.HttpStatus; + +public abstract class baseException extends RuntimeException { + + private final ErrorCode errorCode; + private final HttpStatus httpStatus; + + protected baseException(ErrorCode errorCode, HttpStatus httpStatus, String message) { + super(message); + this.errorCode = errorCode; + this.httpStatus = httpStatus; + } + + public ErrorCode getErrorCode() { + return errorCode; + } + + public HttpStatus getHttpStatus() { + return httpStatus; + } +} From 453b76b4f4df5a5539840acad48673db0bb62771 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Tue, 30 May 2023 23:44:31 +0900 Subject: [PATCH 081/367] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85,=20=EB=A1=9C=EA=B7=B8=EC=9D=B8=20=EB=A1=9C=EC=A7=81?= =?UTF-8?q?=20=EA=B5=AC=ED=98=84(=EB=AF=B8=EC=99=84=EC=84=B1..)=20(#67)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TrendPickProApplication.java | 2 +- .../cart/repository/CartRepository.java | 2 +- .../domain/cart/service/CartService.java | 2 +- .../member/controller/MemberController.java | 50 ++++++++----------- .../domain/member/entity/Member.java | 36 +++++++++---- .../domain/member/entity/RoleType.java | 14 +++++- .../domain/member/entity/form/JoinForm.java | 11 ++++ .../member/repository/MemberRepository.java | 2 + .../domain/member/service/MemberService.java | 36 +++++++++---- .../orders/contoller/OrderController.java | 6 +-- .../entity/dto/request/OrderSearchCond.java | 2 +- .../orders/repository/OrderRepository.java | 2 +- .../domain/orders/service/OrderService.java | 7 +-- .../global/security/SecurityConfig.java | 42 ++++++++++++++++ .../global/security/UserSecurityService.java | 48 ++++++++++++++++++ 15 files changed, 201 insertions(+), 61 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java create mode 100644 src/main/java/project/trendpick_pro/global/security/SecurityConfig.java create mode 100644 src/main/java/project/trendpick_pro/global/security/UserSecurityService.java diff --git a/src/main/java/project/trendpick_pro/TrendPickProApplication.java b/src/main/java/project/trendpick_pro/TrendPickProApplication.java index b81d1c12..2f16c1ba 100644 --- a/src/main/java/project/trendpick_pro/TrendPickProApplication.java +++ b/src/main/java/project/trendpick_pro/TrendPickProApplication.java @@ -4,8 +4,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; -@SpringBootApplication @EnableJpaAuditing +@SpringBootApplication public class TrendPickProApplication { public static void main(String[] args) { diff --git a/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java b/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java index 9b1c9b21..a1d24b99 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java +++ b/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java @@ -4,5 +4,5 @@ import project.trendpick_pro.domain.cart.entity.Cart; public interface CartRepository extends JpaRepository { - Cart findByUser(Long memberId); + Cart findByMemberId(Long memberId); } diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index 6090f3b9..e9a712f0 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -55,7 +55,7 @@ public void updateItemCount(Member member, Long cartItemId, int count) { } public Cart getCartByUser(Member member) { - return cartRepository.findByUser(member.getId()); + return cartRepository.findByMemberId(member.getId()); } private ProductOption getProductOptionById(Long productOptionId) { diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java index ad3982a2..1418f449 100644 --- a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java +++ b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java @@ -1,61 +1,55 @@ package project.trendpick_pro.domain.member.controller; import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; -import jakarta.validation.constraints.Size; -import lombok.AllArgsConstructor; -import lombok.Getter; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.entity.form.JoinForm; +import project.trendpick_pro.domain.member.exception.MemberAlreadyExistException; import project.trendpick_pro.domain.member.service.MemberService; -import java.security.Principal; - +@Slf4j @Controller -@RequestMapping("/trendpick/usr") @RequiredArgsConstructor +@RequestMapping("/trendpick/member") public class MemberController { + private final MemberService memberService; private final Rq rq; @PreAuthorize("isAnonymous()") @GetMapping("/register") - public String showJoin() { + public String register(JoinForm joinForm, Model model) { + model.addAttribute("joinForm", joinForm); return "trendpick/usr/member/join"; } - @AllArgsConstructor - @Getter - public static class JoinForm { - @NotBlank - @Size(min = 4, max = 30) - private final String username; - @NotBlank - @Size(min = 4, max = 30) - private final String password; - } - @PreAuthorize("isAnonymous()") @PostMapping("/register") - public String register(@Valid JoinForm joinForm) { - if ( memberService.findByUsername(joinForm.getUsername()).isPresent() ) { - return "해당 아이디는 이미 사용중입니다."; + public String register(@Valid JoinForm joinForm, BindingResult bindingResult) { + if (bindingResult.hasErrors()) { + return "trendpick/usr/member/join"; } - - memberService.register(joinForm.getUsername(), joinForm.getPassword()); - - return "회원가입이 완료되었습니다"; + try { + memberService.register(joinForm); + } catch(MemberAlreadyExistException e) { + bindingResult.reject(e.getErrorCode().getCode(), e.getMessage()); + return "trendpick/usr/member/join"; + } + return "redirect:/trendpick/member/login"; } @PreAuthorize("isAnonymous()") @GetMapping("/login") - public String showLogin() { + public String login() { return "/trendpick/usr/member/login"; } @@ -76,7 +70,7 @@ public String manageAddress(String address) { @PreAuthorize("isAuthenticated()") @PostMapping("/info/account") - public String manageAccount(String bank_name, Long account) { + public String manageAccount(String bank_name, String account) { Member actor = rq.getMember(); memberService.manageAccount(actor, bank_name, account); diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index ef69ccbe..12719099 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -2,40 +2,49 @@ import jakarta.persistence.*; import lombok.*; +import org.hibernate.validator.constraints.Range; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; +import project.trendpick_pro.domain.tag.entity.Tag; +import java.time.LocalDate; import java.util.ArrayList; -import java.util.Date; import java.util.List; @Entity -@NoArgsConstructor -@AllArgsConstructor +@Getter @Builder -@Getter @Setter +@AllArgsConstructor +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Member { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "member_id") private Long id; + @Column(name = "email",unique = true, nullable = false) private String email; + @Column(name = "password", nullable = false) private String password; + @Column(name = "username", nullable = false) private String username; - private String phone_num; + @Column(name = "phone_number", nullable = false) + private String phoneNumber; - private Date birth; + private LocalDate birth; @Enumerated(EnumType.STRING) private RoleType role; - //@OneToMany(mappedBy = "user") - private Long tag_id; //private List tags= new ArrayList<>(); Tag가 N쪽인데 연관관계를 어떻게 잡아야할까용...Tag가 User를 가지고 있을 필요는 없을 것 같은데 쓰읍 - private String bank_name; - private Long account; + @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) + @JoinColumn(name = "member_id") + private List tags; + + private String bankName; + private String bankAccount; private String address; @@ -54,5 +63,12 @@ public List getGrantedAuthorities() { return grantedAuthorities; } + public void connectAddress(String address) { + this.address = address; + } + public void connectBank(String bankName, String bankAccount) { + this.bankName = bankName; + this.bankAccount = bankAccount; + } } diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/RoleType.java b/src/main/java/project/trendpick_pro/domain/member/entity/RoleType.java index 88ac8344..97111fa9 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/RoleType.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/RoleType.java @@ -1,5 +1,17 @@ package project.trendpick_pro.domain.member.entity; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter public enum RoleType{ - ADMIN, BRAND_ADMIN, USER + ADMIN("ADMIN"), + BRAND_ADMIN("BRAND_ADMIN"), + MEMBER("MEMBER"); + + private String value; + + RoleType(String value) { + this.value = value; + } } diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java b/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java new file mode 100644 index 00000000..f4dab0e5 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java @@ -0,0 +1,11 @@ +package project.trendpick_pro.domain.member.entity.form; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; + +public record JoinForm(@NotBlank(message = "email을 입력해주세요.") String emailtext, + @NotBlank(message = "password를 입력해주세요.") String password, + @NotBlank(message = "이름을 입력해주세요.") String username, + @NotBlank(message = "휴대폰 번호를 입력해주세요.") String phoneNumber, + @NotBlank(message = "권한을 입력해주세요.") String state) { +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/member/repository/MemberRepository.java b/src/main/java/project/trendpick_pro/domain/member/repository/MemberRepository.java index ba0e2f44..8b831b98 100644 --- a/src/main/java/project/trendpick_pro/domain/member/repository/MemberRepository.java +++ b/src/main/java/project/trendpick_pro/domain/member/repository/MemberRepository.java @@ -7,4 +7,6 @@ public interface MemberRepository extends JpaRepository { Optional findByUsername(String username); + Optional findByEmail(String email); + } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index 18de32ad..29ecb335 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -5,8 +5,12 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.entity.RoleType; +import project.trendpick_pro.domain.member.entity.form.JoinForm; +import project.trendpick_pro.domain.member.exception.MemberAlreadyExistException; import project.trendpick_pro.domain.member.repository.MemberRepository; +import java.util.Objects; import java.util.Optional; @Service @@ -22,26 +26,40 @@ public Optional findByUsername(String username) { } @Transactional - public Member register(String username, String password) { + public void register(JoinForm joinForm) { + + if (memberRepository.findByUsername(joinForm.emailtext()).isPresent()) { + throw new MemberAlreadyExistException("이미 존재하는 이름입니다."); + } + + RoleType roleType; + if (Objects.equals(joinForm.state(), RoleType.ADMIN.getValue())) { + roleType = RoleType.ADMIN; + } else if (joinForm.state().equals(RoleType.BRAND_ADMIN.getValue())) { + roleType = RoleType.BRAND_ADMIN; + } else { + roleType = RoleType.MEMBER; + } Member member = Member .builder() - .username(username) - .password(passwordEncoder.encode(password)) + .email(joinForm.emailtext()) + .password(passwordEncoder.encode(joinForm.password())) + .username(joinForm.username()) + .phoneNumber(joinForm.phoneNumber()) + .role(roleType) .build(); - return memberRepository.save(member); + memberRepository.save(member); } @Transactional - public void manageAddress(Member actor, String address){ Member member = memberRepository.findByUsername(actor.getUsername()).orElseThrow(); - member.setAddress(address); + member.connectAddress(address); } - public void manageAccount(Member actor, String bank_name, Long account){ + public void manageAccount(Member actor, String bank_name, String account){ Member member = memberRepository.findByUsername(actor.getUsername()).orElseThrow(); - member.setBank_name(bank_name); - member.setAccount(account); + member.connectBank(bank_name, account); } } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 5b9c3f73..b40b7709 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -23,14 +23,14 @@ public class OrderController { @PostMapping("/order") public String order(@Valid OrderSaveRequest... orderSaveRequests){ - orderService.order(1L, orderSaveRequests); +// orderService.order(1L, orderSaveRequests); return "redirect:/orders"; } @GetMapping("/list") public String orderList(Model model) { - Page responses = orderService.findAll(1L); - model.addAttribute("orders", responses); +// Page responses = orderService.findAll(1L); +// model.addAttribute("orders", responses); return "trendpick/usr/member/orders"; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSearchCond.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSearchCond.java index 0b03b59f..583c8385 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSearchCond.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSearchCond.java @@ -5,6 +5,6 @@ @Getter public class OrderSearchCond { - private Long userId; + private Long memberId; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java index 4e374976..81dee6f8 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java @@ -7,5 +7,5 @@ import project.trendpick_pro.domain.orders.entity.Order; public interface OrderRepository extends JpaRepository { - Page findAllByUser(Member member, Pageable pageable); + Page findAllByMember(Member member, Pageable pageable); } diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 2cebc813..8e58529a 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -61,11 +61,8 @@ public void cancel(Long orderId) { //임시 작성 public Page findAll(OrderSearchCond cond) { - Member member = memberRepository.findById(cond.getUserId()).orElseThrow(); - - Page orderPage = orderRepository.findAllByUser(member, PageRequest.of(0, 10)); - - return orderPage; + Member member = memberRepository.findById(cond.getMemberId()).orElseThrow(); + return orderRepository.findAllByMember(member, PageRequest.of(0, 10)); } diff --git a/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java b/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java new file mode 100644 index 00000000..1d70b8bf --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java @@ -0,0 +1,42 @@ +package project.trendpick_pro.global.security; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; + +@Configuration +@EnableWebSecurity +public class SecurityConfig { + + @Bean + SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + http + .formLogin( + formLogin -> formLogin + .loginPage("/trendpick/member/login") + .loginProcessingUrl("/login_proc") + .defaultSuccessUrl("/trendpick/product/list") + ) + .logout( + logout -> logout + .logoutUrl("/trendpick/member/logout") + ); + return http.build(); + } + + @Bean + PasswordEncoder passwordEncoder() { + return new BCryptPasswordEncoder(); + } + + @Bean + AuthenticationManager authenticationManager(AuthenticationConfiguration authenticationConfiguration) throws Exception { + return authenticationConfiguration.getAuthenticationManager(); + } +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/global/security/UserSecurityService.java b/src/main/java/project/trendpick_pro/global/security/UserSecurityService.java new file mode 100644 index 00000000..8e3d6810 --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/security/UserSecurityService.java @@ -0,0 +1,48 @@ +package project.trendpick_pro.global.security; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.entity.RoleType; +import project.trendpick_pro.domain.member.exception.MemberNotFoundException; +import project.trendpick_pro.domain.member.repository.MemberRepository; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Slf4j +@Service("userDetailsService") +@RequiredArgsConstructor +public class UserSecurityService implements UserDetailsService { + + private final MemberRepository memberRepository; + + @Override + public UserDetails loadUserByUsername(String username) throws MemberNotFoundException { + Optional member = this.memberRepository.findByEmail(username); + log.info("username : {}", username); + log.info("member : {}", member); + if (member.isEmpty()) { + throw new MemberNotFoundException("사용자를 찾을수 없습니다."); + } + Member siteUser = member.get(); + List authorities = new ArrayList<>(); + if ("admin".equals(siteUser.getUsername())) { + authorities.add(new SimpleGrantedAuthority(RoleType.ADMIN.getValue())); + } else if ("brand". equals(siteUser.getUsername())) { + authorities.add(new SimpleGrantedAuthority(RoleType.BRAND_ADMIN.getValue())); + } else { + authorities.add(new SimpleGrantedAuthority(RoleType.MEMBER.getValue())); + } + return new User(siteUser.getEmail(), siteUser.getPassword(), authorities); + } +} \ No newline at end of file From e6dbc34a97c9a464f81d8ad3ccbf3fdc92f3b01a Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 30 May 2023 23:44:34 +0900 Subject: [PATCH 082/367] =?UTF-8?q?feat:=20ProductFile=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/entity/file/ProductFile.java | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/product/entity/file/ProductFile.java diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/file/ProductFile.java b/src/main/java/project/trendpick_pro/domain/product/entity/file/ProductFile.java new file mode 100644 index 00000000..ea31a732 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/entity/file/ProductFile.java @@ -0,0 +1,46 @@ +package project.trendpick_pro.domain.product.entity.file; + +import jakarta.persistence.*; +import lombok.*; +import project.trendpick_pro.domain.product.entity.Product; + +import java.util.ArrayList; +import java.util.List; + +@Entity +@Getter +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Setter +public class ProductFile { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String originalFileName; + private String terminatedFileName; //실제 이미지 업로드에 사용할 이름 + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "main_file_id") + private ProductFile mainFile; + + //종속 + @OneToMany(mappedBy = "mainFile", cascade = CascadeType.ALL) + @Builder.Default + private List subFiles = new ArrayList<>(); + + @OneToOne(mappedBy = "productFile") + private Product product; + + public ProductFile(String originalFileName, String terminatedFileName) { + this.originalFileName = originalFileName; + this.terminatedFileName = terminatedFileName; + } + + //양방향 맵핑 + public void connectFile(ProductFile subFile){ + this.getSubFiles().add(subFile); + subFile.setMainFile(this); + } +} From f46dbe67158103775efcd2112d760b3abe353154 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 30 May 2023 23:51:09 +0900 Subject: [PATCH 083/367] =?UTF-8?q?feat:=20FileTerminator=20=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=EB=B3=80=ED=99=98=EA=B8=B0=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../base/fileterminator/FileTerminator.java | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/common/base/fileterminator/FileTerminator.java diff --git a/src/main/java/project/trendpick_pro/domain/common/base/fileterminator/FileTerminator.java b/src/main/java/project/trendpick_pro/domain/common/base/fileterminator/FileTerminator.java new file mode 100644 index 00000000..921ca5ee --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/common/base/fileterminator/FileTerminator.java @@ -0,0 +1,64 @@ +package project.trendpick_pro.domain.common.base.fileterminator; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; +import org.springframework.web.multipart.MultipartFile; +import project.trendpick_pro.domain.product.entity.file.ProductFile; + +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.UUID; + +@Component +public class FileTerminator { + + @Value("${file.dir}") + private String filePath; //저장경로 + + //이미지 업로드할때 url경로 + public String getFilePath(String filename) { + return filePath + filename; + } + + //단일 멀티파일 들어왔을때 저장하고 반환 + public ProductFile terminateFile(MultipartFile multipartFile) throws IOException { + if (multipartFile.isEmpty()) { + return null; + } + + String originalFilename = multipartFile.getOriginalFilename(); + String terminatedFileName = terminateFileName(originalFilename); + multipartFile.transferTo(new File(getFilePath(terminatedFileName))); + + return ProductFile + .builder() + .originalFileName(originalFilename) + .terminatedFileName(terminatedFileName) + .build() + ; + } + + //파일 여러개를 한 번에 묶어서 변환할때 + public List terminateFileList(List MultipartFiles) throws IOException { + List fileList = new ArrayList<>(); + for(MultipartFile multipartFile : MultipartFiles){ + if(!multipartFile.isEmpty()){ + fileList.add(terminateFile(multipartFile)); + } + } + return fileList; + } + + private String terminateFileName(String originalFilename) { + String ext = extractExt(originalFilename); + String uuid = UUID.randomUUID().toString(); + return uuid + "." + ext; + } + + private String extractExt(String originalFilename) { + int pos = originalFilename.lastIndexOf("."); + return originalFilename.substring(pos + 1); + } +} \ No newline at end of file From ed62876ba6c5127785a41b95ffc2b7df761f86ba Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 31 May 2023 00:03:18 +0900 Subject: [PATCH 084/367] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=EC=97=90=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 4 +++- .../domain/product/entity/Product.java | 16 +++++++--------- .../domain/product/service/ProductService.java | 15 +++++++++++++-- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 80dc247b..fd5507b8 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -10,6 +10,8 @@ import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; import project.trendpick_pro.domain.product.service.ProductService; +import java.io.IOException; + @Slf4j @Controller @RequiredArgsConstructor @@ -19,7 +21,7 @@ public class ProductController { private ProductService productService; @PostMapping("/register") - public String registerProduct(@Valid ProductSaveRequest productSaveRequest, Model model) { + public String registerProduct(@Valid ProductSaveRequest productSaveRequest, Model model) throws IOException { ProductResponse productResponse = productService.register(productSaveRequest); model.addAttribute("productResponse", productResponse); diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index f0ef4461..3df1a541 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -12,6 +12,7 @@ import project.trendpick_pro.domain.common.base.BaseTimeEntity; import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; +import project.trendpick_pro.domain.product.entity.file.ProductFile; import project.trendpick_pro.domain.tag.entity.Tag; import java.util.ArrayList; @@ -46,7 +47,7 @@ public class Product extends BaseTimeEntity { @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "common_file_id") - private CommonFile commonFile; + private ProductFile productFile; @Column(name = "price", nullable = false) private int price; @@ -59,26 +60,27 @@ public class Product extends BaseTimeEntity { @Builder public Product(String name, MainCategory mainCategory, SubCategory subCategory, Brand brand, - String description, CommonFile commonFile, int price, int stock, List tags) { + String description, ProductFile productFile, int price, int stock, List tags) { this.name = name; this.mainCategory = mainCategory; this.subCategory = subCategory; this.brand = brand; this.description = description; - this.commonFile = commonFile; + this.productFile = productFile; this.price = price; this.stock = stock; this.tags = tags; } - public static Product of(ProductSaveRequest request, MainCategory mainCategory, SubCategory subCategory, Brand brand) { + public static Product of(ProductSaveRequest request, MainCategory mainCategory + , SubCategory subCategory, Brand brand,ProductFile productFile) { return Product.builder() .name(request.getName()) .mainCategory(mainCategory) .subCategory(subCategory) .brand(brand) .description(request.getDescription()) - .commonFile(makeFiles(request.getMainFile(), request.getSubFiles())) + .productFile(productFile) .price(request.getPrice()) .stock(request.getStock()) .tags(request.getTags()) @@ -103,9 +105,5 @@ public void update(ProductSaveRequest request) { // 여기서 파일 지지고 볶고 할 예정 } - private static CommonFile makeFiles(MultipartFile mainFile, List subFiles) { - return null; - // 여기서 파일 지지고 볶고 할 예정 - } } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 9206f0da..0476f274 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -13,13 +13,16 @@ import project.trendpick_pro.domain.category.entity.SubCategory; import project.trendpick_pro.domain.category.repository.MainCategoryRepository; import project.trendpick_pro.domain.category.repository.SubCategoryRepository; +import project.trendpick_pro.domain.common.base.fileterminator.FileTerminator; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; +import project.trendpick_pro.domain.product.entity.file.ProductFile; import project.trendpick_pro.domain.product.repository.ProductRepository; +import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -33,15 +36,23 @@ public class ProductService { private final MainCategoryRepository mainCategoryRepository; private final SubCategoryRepository subCategoryRepository; private final BrandRepository brandRepository; + private final FileTerminator fileTerminator; @Transactional - public ProductResponse register(ProductSaveRequest productSaveRequest) { + public ProductResponse register(ProductSaveRequest productSaveRequest) throws IOException { + + ProductFile mainFile = fileTerminator.terminateFile(productSaveRequest.getMainFile()); + List subFiles = fileTerminator.terminateFileList(productSaveRequest.getSubFiles()); + + for(ProductFile productFile : subFiles){ + mainFile.connectFile(productFile); + } MainCategory mainCategory = mainCategoryRepository.findByName(productSaveRequest.getMainCategory()); SubCategory subCategory = subCategoryRepository.findByName(productSaveRequest.getSubCategory()); Brand brand = brandRepository.findByName(productSaveRequest.getBrand()); - Product product = Product.of(productSaveRequest, mainCategory, subCategory, brand); + Product product = Product.of(productSaveRequest, mainCategory, subCategory, brand, mainFile); productRepository.save(product); return ProductResponse.of(product); } From c7ed724d7d1c8fff164d1c74fbbee49bb16549b9 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 31 May 2023 00:13:03 +0900 Subject: [PATCH 085/367] =?UTF-8?q?refactor:=20productResponse=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/entity/dto/response/ProductResponse.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java index 8412ee10..ac40f53f 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java @@ -8,6 +8,7 @@ import lombok.NoArgsConstructor; import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.product.entity.file.ProductFile; import project.trendpick_pro.domain.tag.entity.Tag; import java.util.ArrayList; @@ -54,19 +55,19 @@ public static ProductResponse of (Product product) { // .subCategory(product.getSubCategory().getName()) .brand(product.getBrand().getName()) .description(product.getDescription()) - .mainFile(product.getCommonFile().getFileName()) - .subFiles(subFiles(product.getCommonFile().getChild())) + .mainFile(product.getProductFile().getOriginalFileName()) + .subFiles(subFiles(product.getProductFile().getSubFiles())) .price(product.getPrice()) .stock(product.getStock()) .tags(product.getTags()) .build(); } - private static List subFiles(List subFiles) { + private static List subFiles(List subFiles) { List tmpList = new ArrayList<>(); - for (CommonFile subFile : subFiles) { - tmpList.add(subFile.getFileName()); + for (ProductFile subFile : subFiles) { + tmpList.add(subFile.getOriginalFileName()); } return tmpList; } From 85ed7110ef8a5084aa4518dfb0267102b29d667c Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 31 May 2023 13:57:02 +0900 Subject: [PATCH 086/367] fix: terminate -> translate --- .../FileTranslator.java} | 14 +++++++------- .../domain/common/file/CommonFile.java | 3 ++- .../domain/product/service/ProductService.java | 9 ++++----- 3 files changed, 13 insertions(+), 13 deletions(-) rename src/main/java/project/trendpick_pro/domain/common/base/{fileterminator/FileTerminator.java => filetranslator/FileTranslator.java} (80%) diff --git a/src/main/java/project/trendpick_pro/domain/common/base/fileterminator/FileTerminator.java b/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java similarity index 80% rename from src/main/java/project/trendpick_pro/domain/common/base/fileterminator/FileTerminator.java rename to src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java index 921ca5ee..b3beaf15 100644 --- a/src/main/java/project/trendpick_pro/domain/common/base/fileterminator/FileTerminator.java +++ b/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java @@ -1,4 +1,4 @@ -package project.trendpick_pro.domain.common.base.fileterminator; +package project.trendpick_pro.domain.common.base.filetranslator; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; @@ -12,7 +12,7 @@ import java.util.UUID; @Component -public class FileTerminator { +public class FileTranslator { @Value("${file.dir}") private String filePath; //저장경로 @@ -23,13 +23,13 @@ public String getFilePath(String filename) { } //단일 멀티파일 들어왔을때 저장하고 반환 - public ProductFile terminateFile(MultipartFile multipartFile) throws IOException { + public ProductFile translateFile(MultipartFile multipartFile) throws IOException { if (multipartFile.isEmpty()) { return null; } String originalFilename = multipartFile.getOriginalFilename(); - String terminatedFileName = terminateFileName(originalFilename); + String terminatedFileName = translateFileName(originalFilename); multipartFile.transferTo(new File(getFilePath(terminatedFileName))); return ProductFile @@ -41,17 +41,17 @@ public ProductFile terminateFile(MultipartFile multipartFile) throws IOException } //파일 여러개를 한 번에 묶어서 변환할때 - public List terminateFileList(List MultipartFiles) throws IOException { + public List translateFileList(List MultipartFiles) throws IOException { List fileList = new ArrayList<>(); for(MultipartFile multipartFile : MultipartFiles){ if(!multipartFile.isEmpty()){ - fileList.add(terminateFile(multipartFile)); + fileList.add(translateFile(multipartFile)); } } return fileList; } - private String terminateFileName(String originalFilename) { + private String translateFileName(String originalFilename) { String ext = extractExt(originalFilename); String uuid = UUID.randomUUID().toString(); return uuid + "." + ext; diff --git a/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java b/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java index 4e5cccd6..5ee3061e 100644 --- a/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java +++ b/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java @@ -16,7 +16,8 @@ public class CommonFile { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - private String FileName; + private String originalFileName; // + private String translatedFileName; //실제 저장 경로, 업로드할때 이 경로로 이미지 불러옴. @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "PARENT_ID") diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 0476f274..dc1c8491 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -4,7 +4,6 @@ import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.brand.entity.Brand; @@ -13,7 +12,7 @@ import project.trendpick_pro.domain.category.entity.SubCategory; import project.trendpick_pro.domain.category.repository.MainCategoryRepository; import project.trendpick_pro.domain.category.repository.SubCategoryRepository; -import project.trendpick_pro.domain.common.base.fileterminator.FileTerminator; +import project.trendpick_pro.domain.common.base.filetranslator.FileTranslator; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; @@ -36,13 +35,13 @@ public class ProductService { private final MainCategoryRepository mainCategoryRepository; private final SubCategoryRepository subCategoryRepository; private final BrandRepository brandRepository; - private final FileTerminator fileTerminator; + private final FileTranslator fileTranslator; @Transactional public ProductResponse register(ProductSaveRequest productSaveRequest) throws IOException { - ProductFile mainFile = fileTerminator.terminateFile(productSaveRequest.getMainFile()); - List subFiles = fileTerminator.terminateFileList(productSaveRequest.getSubFiles()); + ProductFile mainFile = fileTranslator.translateFile(productSaveRequest.getMainFile()); + List subFiles = fileTranslator.translateFileList(productSaveRequest.getSubFiles()); for(ProductFile productFile : subFiles){ mainFile.connectFile(productFile); From 7fd5217ed632b7aba6d5f9d6a63ca0206ce20829 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 31 May 2023 14:15:34 +0900 Subject: [PATCH 087/367] refactor: ProductFile -> CommonFile --- .../base/filetranslator/FileTranslator.java | 17 ++++++----- .../domain/common/file/CommonFile.java | 28 +++++++++++++------ .../domain/product/entity/Product.java | 12 ++++---- .../entity/dto/response/ProductResponse.java | 8 +++--- .../product/service/ProductService.java | 9 +++--- 5 files changed, 43 insertions(+), 31 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java b/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java index b3beaf15..88920c8f 100644 --- a/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java +++ b/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java @@ -3,8 +3,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import org.springframework.web.multipart.MultipartFile; -import project.trendpick_pro.domain.product.entity.file.ProductFile; - +import project.trendpick_pro.domain.common.file.CommonFile; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -23,26 +22,26 @@ public String getFilePath(String filename) { } //단일 멀티파일 들어왔을때 저장하고 반환 - public ProductFile translateFile(MultipartFile multipartFile) throws IOException { + public CommonFile translateFile(MultipartFile multipartFile) throws IOException { if (multipartFile.isEmpty()) { return null; } String originalFilename = multipartFile.getOriginalFilename(); - String terminatedFileName = translateFileName(originalFilename); - multipartFile.transferTo(new File(getFilePath(terminatedFileName))); + String translatedFileName = translateFileName(originalFilename); + multipartFile.transferTo(new File(getFilePath(translatedFileName))); - return ProductFile + return CommonFile .builder() .originalFileName(originalFilename) - .terminatedFileName(terminatedFileName) + .translatedFileName(translatedFileName) .build() ; } //파일 여러개를 한 번에 묶어서 변환할때 - public List translateFileList(List MultipartFiles) throws IOException { - List fileList = new ArrayList<>(); + public List translateFileList(List MultipartFiles) throws IOException { + List fileList = new ArrayList<>(); for(MultipartFile multipartFile : MultipartFiles){ if(!multipartFile.isEmpty()){ fileList.add(translateFile(multipartFile)); diff --git a/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java b/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java index 5ee3061e..0f6bbce0 100644 --- a/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java +++ b/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java @@ -1,31 +1,43 @@ package project.trendpick_pro.domain.common.file; import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; +import project.trendpick_pro.domain.product.entity.file.ProductFile; import java.util.ArrayList; import java.util.List; @Entity @Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) +@AllArgsConstructor +@NoArgsConstructor +@Builder +@Setter public class CommonFile { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - private String originalFileName; // + private String originalFileName; //파일 업로드명 private String translatedFileName; //실제 저장 경로, 업로드할때 이 경로로 이미지 불러옴. @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "PARENT_ID") private CommonFile parent; - @OneToMany(mappedBy = "parent") + @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL) + @Builder.Default //이거없으면 리스트 초기화 된다. 붙여야됨 private List child = new ArrayList<>(); - // 여기서 파일 생성 삭제 지지고 볶고 할예정 - + //양방향 맵핑 + //parent : 메인파일 + //child : 서브파일 + public void connectFile(CommonFile childFile){ + this.getChild().add(childFile); + childFile.setParent(this); + } + + private void setParent(CommonFile parent) { + this.parent = parent; + } } diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index 3df1a541..c0629540 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -46,8 +46,8 @@ public class Product extends BaseTimeEntity { private String description; @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) - @JoinColumn(name = "common_file_id") - private ProductFile productFile; + @JoinColumn(name = "file_id") + private CommonFile file; @Column(name = "price", nullable = false) private int price; @@ -60,27 +60,27 @@ public class Product extends BaseTimeEntity { @Builder public Product(String name, MainCategory mainCategory, SubCategory subCategory, Brand brand, - String description, ProductFile productFile, int price, int stock, List tags) { + String description, CommonFile file, int price, int stock, List tags) { this.name = name; this.mainCategory = mainCategory; this.subCategory = subCategory; this.brand = brand; this.description = description; - this.productFile = productFile; + this.file = file; this.price = price; this.stock = stock; this.tags = tags; } public static Product of(ProductSaveRequest request, MainCategory mainCategory - , SubCategory subCategory, Brand brand,ProductFile productFile) { + , SubCategory subCategory, Brand brand,CommonFile file) { return Product.builder() .name(request.getName()) .mainCategory(mainCategory) .subCategory(subCategory) .brand(brand) .description(request.getDescription()) - .productFile(productFile) + .file(file) .price(request.getPrice()) .stock(request.getStock()) .tags(request.getTags()) diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java index ac40f53f..dd2c3705 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java @@ -55,18 +55,18 @@ public static ProductResponse of (Product product) { // .subCategory(product.getSubCategory().getName()) .brand(product.getBrand().getName()) .description(product.getDescription()) - .mainFile(product.getProductFile().getOriginalFileName()) - .subFiles(subFiles(product.getProductFile().getSubFiles())) + .mainFile(product.getFile().getOriginalFileName()) + .subFiles(subFiles(product.getFile().getChild())) .price(product.getPrice()) .stock(product.getStock()) .tags(product.getTags()) .build(); } - private static List subFiles(List subFiles) { + private static List subFiles(List subFiles) { List tmpList = new ArrayList<>(); - for (ProductFile subFile : subFiles) { + for (CommonFile subFile : subFiles) { tmpList.add(subFile.getOriginalFileName()); } return tmpList; diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index dc1c8491..62213887 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -13,6 +13,7 @@ import project.trendpick_pro.domain.category.repository.MainCategoryRepository; import project.trendpick_pro.domain.category.repository.SubCategoryRepository; import project.trendpick_pro.domain.common.base.filetranslator.FileTranslator; +import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; @@ -40,11 +41,11 @@ public class ProductService { @Transactional public ProductResponse register(ProductSaveRequest productSaveRequest) throws IOException { - ProductFile mainFile = fileTranslator.translateFile(productSaveRequest.getMainFile()); - List subFiles = fileTranslator.translateFileList(productSaveRequest.getSubFiles()); + CommonFile mainFile = fileTranslator.translateFile(productSaveRequest.getMainFile()); + List subFiles = fileTranslator.translateFileList(productSaveRequest.getSubFiles()); - for(ProductFile productFile : subFiles){ - mainFile.connectFile(productFile); + for(CommonFile subFile : subFiles){ + mainFile.connectFile(subFile); } MainCategory mainCategory = mainCategoryRepository.findByName(productSaveRequest.getMainCategory()); From fe9b85547344d7504e7b971ad20e019e7ebc2b17 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 31 May 2023 14:16:49 +0900 Subject: [PATCH 088/367] =?UTF-8?q?fix:=20ReviewImage=20generationType=20?= =?UTF-8?q?=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../project/trendpick_pro/domain/review/entity/ReviewImage.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/ReviewImage.java b/src/main/java/project/trendpick_pro/domain/review/entity/ReviewImage.java index c76d6aeb..0b23e98e 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/ReviewImage.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/ReviewImage.java @@ -17,7 +17,7 @@ @AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ReviewImage { - @Id @GeneratedValue(strategy = GenerationType.AUTO) + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "review_image_id") private Long id; From 5db5c87b2ed7c97725d7cc90ddc5c5901f4c6095 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 31 May 2023 14:25:07 +0900 Subject: [PATCH 089/367] =?UTF-8?q?refactor:=20CommonFile=20=EC=83=9D?= =?UTF-8?q?=EC=84=B1=20=EB=B0=A9=EB=B2=95=20of=EB=A1=9C=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../base/filetranslator/FileTranslator.java | 7 +----- .../domain/common/file/CommonFile.java | 24 +++++++++++++++---- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java b/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java index 88920c8f..cec8ca0e 100644 --- a/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java +++ b/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java @@ -31,12 +31,7 @@ public CommonFile translateFile(MultipartFile multipartFile) throws IOException String translatedFileName = translateFileName(originalFilename); multipartFile.transferTo(new File(getFilePath(translatedFileName))); - return CommonFile - .builder() - .originalFileName(originalFilename) - .translatedFileName(translatedFileName) - .build() - ; + return CommonFile.of(originalFilename, translatedFileName); } //파일 여러개를 한 번에 묶어서 변환할때 diff --git a/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java b/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java index 0f6bbce0..d1b09f96 100644 --- a/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java +++ b/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java @@ -9,9 +9,7 @@ @Entity @Getter -@AllArgsConstructor -@NoArgsConstructor -@Builder +@NoArgsConstructor(access = AccessLevel.PROTECTED) @Setter public class CommonFile { @@ -21,17 +19,17 @@ public class CommonFile { private String originalFileName; //파일 업로드명 private String translatedFileName; //실제 저장 경로, 업로드할때 이 경로로 이미지 불러옴. + //메인파일 @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "PARENT_ID") private CommonFile parent; + //서브파일 (만약 메인/서브 유형이 아니라면 그냥 여러개 생성해야한다. 전부 메인으로) @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL) @Builder.Default //이거없으면 리스트 초기화 된다. 붙여야됨 private List child = new ArrayList<>(); //양방향 맵핑 - //parent : 메인파일 - //child : 서브파일 public void connectFile(CommonFile childFile){ this.getChild().add(childFile); childFile.setParent(this); @@ -40,4 +38,20 @@ public void connectFile(CommonFile childFile){ private void setParent(CommonFile parent) { this.parent = parent; } + + @Builder + private CommonFile(String originalFileName, String translatedFileName){ + this.originalFileName = originalFileName; + this.translatedFileName = translatedFileName; + } + + public static CommonFile of(String originalFileName, String translatedFileName){ + return CommonFile + .builder() + .originalFileName(originalFileName) + .translatedFileName(translatedFileName) + .build() + ; + } + } From 4a7b538cbe8bceb7e9e264632f5f479fb963d83a Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 31 May 2023 14:38:20 +0900 Subject: [PATCH 090/367] =?UTF-8?q?fix:=20product=20querydsl=20=EB=B6=80?= =?UTF-8?q?=EB=B6=84=20file=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../base/filetranslator/FileTranslator.java | 7 ++++++- .../domain/common/file/CommonFile.java | 19 ++----------------- .../repository/ProductRepositoryImpl.java | 8 +++++--- 3 files changed, 13 insertions(+), 21 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java b/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java index cec8ca0e..88920c8f 100644 --- a/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java +++ b/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java @@ -31,7 +31,12 @@ public CommonFile translateFile(MultipartFile multipartFile) throws IOException String translatedFileName = translateFileName(originalFilename); multipartFile.transferTo(new File(getFilePath(translatedFileName))); - return CommonFile.of(originalFilename, translatedFileName); + return CommonFile + .builder() + .originalFileName(originalFilename) + .translatedFileName(translatedFileName) + .build() + ; } //파일 여러개를 한 번에 묶어서 변환할때 diff --git a/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java b/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java index d1b09f96..e16f71b7 100644 --- a/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java +++ b/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java @@ -2,14 +2,14 @@ import jakarta.persistence.*; import lombok.*; -import project.trendpick_pro.domain.product.entity.file.ProductFile; - import java.util.ArrayList; import java.util.List; @Entity @Getter +@AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) +@Builder @Setter public class CommonFile { @@ -39,19 +39,4 @@ private void setParent(CommonFile parent) { this.parent = parent; } - @Builder - private CommonFile(String originalFileName, String translatedFileName){ - this.originalFileName = originalFileName; - this.translatedFileName = translatedFileName; - } - - public static CommonFile of(String originalFileName, String translatedFileName){ - return CommonFile - .builder() - .originalFileName(originalFileName) - .translatedFileName(translatedFileName) - .build() - ; - } - } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index fb6cbcd9..1f8e045d 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -40,17 +40,18 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag product.id, product.name, brand.name, - product.commonFile.FileName, + product.file.translatedFileName, product.price )) .from(product) .leftJoin(product.mainCategory, mainCategory) .leftJoin(product.subCategory, subCategory) .leftJoin(product.brand, brand) - .leftJoin(product.commonFile, commonFile) + .leftJoin(product.file, commonFile) .where( mainCategoryEq(cond), subCategoryEq(cond) + ) .offset(0) .limit(18) @@ -62,7 +63,7 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag .leftJoin(product.mainCategory, mainCategory) .leftJoin(product.subCategory, subCategory) .leftJoin(product.brand, brand) - .leftJoin(product.commonFile, commonFile) + .leftJoin(product.file, commonFile) .where( mainCategoryEq(cond), subCategoryEq(cond) @@ -78,4 +79,5 @@ private static BooleanExpression mainCategoryEq(ProductSearchCond cond) { private static BooleanExpression subCategoryEq(ProductSearchCond cond) { return subCategory.name.eq(cond.getSubCategory()); } + } From 212307973fbf3f31a9f8463c184ef18ed58bb540 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Wed, 31 May 2023 21:50:04 +0900 Subject: [PATCH 091/367] =?UTF-8?q?refactor:=20productFile=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EC=A0=9C=EA=B1=B0=20(#75)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/product/entity/Product.java | 1 - .../entity/dto/response/ProductResponse.java | 1 - .../product/entity/file/ProductFile.java | 46 ------------------- .../product/service/ProductService.java | 1 - 4 files changed, 49 deletions(-) delete mode 100644 src/main/java/project/trendpick_pro/domain/product/entity/file/ProductFile.java diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index c0629540..9e3621d2 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -12,7 +12,6 @@ import project.trendpick_pro.domain.common.base.BaseTimeEntity; import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; -import project.trendpick_pro.domain.product.entity.file.ProductFile; import project.trendpick_pro.domain.tag.entity.Tag; import java.util.ArrayList; diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java index dd2c3705..a8db331f 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java @@ -8,7 +8,6 @@ import lombok.NoArgsConstructor; import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.product.entity.Product; -import project.trendpick_pro.domain.product.entity.file.ProductFile; import project.trendpick_pro.domain.tag.entity.Tag; import java.util.ArrayList; diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/file/ProductFile.java b/src/main/java/project/trendpick_pro/domain/product/entity/file/ProductFile.java deleted file mode 100644 index ea31a732..00000000 --- a/src/main/java/project/trendpick_pro/domain/product/entity/file/ProductFile.java +++ /dev/null @@ -1,46 +0,0 @@ -package project.trendpick_pro.domain.product.entity.file; - -import jakarta.persistence.*; -import lombok.*; -import project.trendpick_pro.domain.product.entity.Product; - -import java.util.ArrayList; -import java.util.List; - -@Entity -@Getter -@AllArgsConstructor -@NoArgsConstructor -@Builder -@Setter -public class ProductFile { - - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - private String originalFileName; - private String terminatedFileName; //실제 이미지 업로드에 사용할 이름 - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "main_file_id") - private ProductFile mainFile; - - //종속 - @OneToMany(mappedBy = "mainFile", cascade = CascadeType.ALL) - @Builder.Default - private List subFiles = new ArrayList<>(); - - @OneToOne(mappedBy = "productFile") - private Product product; - - public ProductFile(String originalFileName, String terminatedFileName) { - this.originalFileName = originalFileName; - this.terminatedFileName = terminatedFileName; - } - - //양방향 맵핑 - public void connectFile(ProductFile subFile){ - this.getSubFiles().add(subFile); - subFile.setMainFile(this); - } -} diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 62213887..863c8e95 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -19,7 +19,6 @@ import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; -import project.trendpick_pro.domain.product.entity.file.ProductFile; import project.trendpick_pro.domain.product.repository.ProductRepository; import java.io.IOException; From 64b254150367e87123fdc6606d3a1254fd2b5ddf Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Wed, 31 May 2023 21:50:22 +0900 Subject: [PATCH 092/367] =?UTF-8?q?refactor:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=20=EC=9C=A0=EC=A0=80=EC=9D=98=20=EA=B6=8C=ED=95=9C=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=EC=9D=84=20=EC=B6=94=EA=B0=80=ED=95=9C=EB=8B=A4.=20(#?= =?UTF-8?q?75)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trendpick_pro/global/security/UserSecurityService.java | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/java/project/trendpick_pro/global/security/UserSecurityService.java b/src/main/java/project/trendpick_pro/global/security/UserSecurityService.java index 8e3d6810..42a03423 100644 --- a/src/main/java/project/trendpick_pro/global/security/UserSecurityService.java +++ b/src/main/java/project/trendpick_pro/global/security/UserSecurityService.java @@ -29,16 +29,15 @@ public class UserSecurityService implements UserDetailsService { @Override public UserDetails loadUserByUsername(String username) throws MemberNotFoundException { Optional member = this.memberRepository.findByEmail(username); - log.info("username : {}", username); - log.info("member : {}", member); + if (member.isEmpty()) { throw new MemberNotFoundException("사용자를 찾을수 없습니다."); } Member siteUser = member.get(); List authorities = new ArrayList<>(); - if ("admin".equals(siteUser.getUsername())) { + if ("admin".equals(siteUser.getUsername().substring(0,5))) { authorities.add(new SimpleGrantedAuthority(RoleType.ADMIN.getValue())); - } else if ("brand". equals(siteUser.getUsername())) { + } else if ("brand". equals(siteUser.getUsername().substring(0,5))) { authorities.add(new SimpleGrantedAuthority(RoleType.BRAND_ADMIN.getValue())); } else { authorities.add(new SimpleGrantedAuthority(RoleType.MEMBER.getValue())); From faba4331041d74d18b059e59b8be6c62b4a3d1aa Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Wed, 31 May 2023 21:50:41 +0900 Subject: [PATCH 093/367] =?UTF-8?q?docs:=20=EA=B0=9C=EB=B0=9C=ED=99=98?= =?UTF-8?q?=EA=B2=BD=EC=97=90=EC=84=9C=EB=A7=8C=20=EC=93=B0=EC=9D=B4?= =?UTF-8?q?=EB=8A=94=20yml=20=ED=8C=8C=EC=9D=BC=EB=A1=9C=20=EA=B5=AC?= =?UTF-8?q?=EC=84=B1=ED=95=9C=EB=8B=A4.=20(#75)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application-dev.yml | 22 ++++++++++++++++++++++ src/main/resources/application.yml | 24 ++---------------------- 2 files changed, 24 insertions(+), 22 deletions(-) create mode 100644 src/main/resources/application-dev.yml diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml new file mode 100644 index 00000000..d2c0a4e0 --- /dev/null +++ b/src/main/resources/application-dev.yml @@ -0,0 +1,22 @@ +spring: + datasource: + # H2 + driver-class-name: org.h2.Driver + url: jdbc:h2:tcp://localhost/~/db/TrendPick + username: sa + password: + # mariaDB + # driver-class-name: org.mariadb.jdbc.Driver + # url: jdbc:mariadb://127.0.0.1:${maria.port}/TrendPick__dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul + # username: ${maria.username} + # password: ${maria.password} + jpa: + hibernate: + ddl-auto: create + properties: + hibernate: + format_sql: true + use_sql_comments: true +logging.level: + org: + hibernate.SQL: debug \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e97315d9..727e6d35 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,27 +1,7 @@ spring: profiles: + active: dev include: secret mvc: pathmatch: - matching-strategy: ant_path_matcher - datasource: -# H2 - driver-class-name: org.h2.Driver - url: jdbc:h2:tcp://localhost/~/db/TrendPick - username: sa - password: -# mariaDB -# driver-class-name: org.mariadb.jdbc.Driver -# url: jdbc:mariadb://127.0.0.1:${maria.port}/TrendPick__dev?useUnicode=true&characterEncoding=utf8&autoReconnect=true&serverTimezone=Asia/Seoul -# username: ${maria.username} -# password: ${maria.password} - jpa: - hibernate: - ddl-auto: create - properties: - hibernate: - format_sql: true - use_sql_comments: true -logging.level: - org: - hibernate.SQL: debug \ No newline at end of file + matching-strategy: ant_path_matcher \ No newline at end of file From 52175eed8ebb13201f7658f405835b7cda6cfcdd Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 31 May 2023 22:42:54 +0900 Subject: [PATCH 094/367] =?UTF-8?q?refactor:=20=EC=A0=91=EA=B7=BC=EA=B6=8C?= =?UTF-8?q?=ED=95=9C=20=EC=B2=B4=ED=81=AC=20=EB=A1=9C=EC=A7=81=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 --- .../product/controller/ProductController.java | 17 ++++++++++++++++- .../repository/ProductRepositoryImpl.java | 9 +-------- 2 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index fd5507b8..90c7125e 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -3,9 +3,13 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; +import project.trendpick_pro.domain.common.base.rq.Rq; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.entity.RoleType; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; import project.trendpick_pro.domain.product.service.ProductService; @@ -18,10 +22,14 @@ @RequestMapping("trendpick/products") public class ProductController { - private ProductService productService; + private final Rq rq; + private final ProductService productService; + @PreAuthorize("isAuthenticated()") @PostMapping("/register") public String registerProduct(@Valid ProductSaveRequest productSaveRequest, Model model) throws IOException { + if(!rq.getMember().getRole().equals(RoleType.BRAND_ADMIN)) + throw new RuntimeException("상품 등록 권한이 없습니다."); ProductResponse productResponse = productService.register(productSaveRequest); model.addAttribute("productResponse", productResponse); @@ -29,8 +37,11 @@ public String registerProduct(@Valid ProductSaveRequest productSaveRequest, Mode return "redirect:/trendpick/products/" + productResponse.getId(); } + @PreAuthorize("isAuthenticated()") @PostMapping("/edit/{productId}") public String modifyProduct(@PathVariable Long productId, @Valid ProductSaveRequest productSaveRequest, Model model) { + if(!rq.getMember().getRole().equals(RoleType.BRAND_ADMIN)) //추가로 해당 상품 브랜드 관리자인지도 체크 + throw new RuntimeException("상품 수정 권한이 없습니다."); ProductResponse productResponse = productService.modify(productId, productSaveRequest); model.addAttribute("productResponse", productResponse); @@ -38,8 +49,12 @@ public String modifyProduct(@PathVariable Long productId, @Valid ProductSaveRequ return "redirect:/trendpick/products/" + productResponse.getId(); } + @PreAuthorize("isAuthenticated()") @DeleteMapping("/{productId}") public String deleteProduct(@PathVariable Long productId) { + if(!rq.getMember().getRole().equals(RoleType.BRAND_ADMIN)) //추가로 해당 상품 브랜드 관리자인지도 체크 + throw new RuntimeException("상품 삭제 권한이 없습니다."); + productService.delete(productId); return "redirect:/trendpick/products/list"; } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 1f8e045d..8ba9cae5 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -7,14 +7,8 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.support.PageableExecutionUtils; -import project.trendpick_pro.domain.brand.entity.QBrand; -import project.trendpick_pro.domain.category.entity.QMainCategory; -import project.trendpick_pro.domain.category.entity.QSubCategory; -import project.trendpick_pro.domain.common.file.QCommonFile; -import project.trendpick_pro.domain.product.entity.QProduct; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; -import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; import project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse; import java.util.List; @@ -23,7 +17,7 @@ import static project.trendpick_pro.domain.category.entity.QMainCategory.*; import static project.trendpick_pro.domain.category.entity.QSubCategory.*; import static project.trendpick_pro.domain.common.file.QCommonFile.commonFile; -import static project.trendpick_pro.domain.product.entity.QProduct.*; +import static project.trendpick_pro.domain.product.entity.QProduct.product; public class ProductRepositoryImpl implements ProductRepositoryCustom { @@ -79,5 +73,4 @@ private static BooleanExpression mainCategoryEq(ProductSearchCond cond) { private static BooleanExpression subCategoryEq(ProductSearchCond cond) { return subCategory.name.eq(cond.getSubCategory()); } - } From 95b4d9c8978fc06b85fb3aeb3682626d6c07ba47 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 31 May 2023 23:02:15 +0900 Subject: [PATCH 095/367] =?UTF-8?q?refactor:=20=EC=83=81=ED=92=88=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8C=85=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=A0=95=EB=A0=AC=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EB=B0=9B=EC=9D=84=20=EC=88=98=20=EC=9E=88=EA=B2=8C=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 --- .../domain/product/controller/ProductController.java | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 90c7125e..0a77ac68 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -66,9 +66,12 @@ public String showProduct(@PathVariable Long productId, Model model) { } @GetMapping("/list") - public String showAllProduct(@RequestParam("page") int offset, @RequestParam("main-category") String mainCategory, - @RequestParam("sub-category") String subCategory, Model model) { - model.addAttribute("productResponse", productService.showAll(offset, mainCategory, mainCategory)); + public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") int offset, + @RequestParam(value = "main-category") String mainCategory, + @RequestParam(value = "sub-category") String subCategory, + @RequestParam(value = "sort", defaultValue = "1") Integer sortCode, + Model model) { + model.addAttribute("productResponse", productService.showAll(offset, mainCategory, subCategory, sortCode)); return "/trendpick/products/detailpage"; } } From e94381842a866d65a2362e6584ec18d85e297575 Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Wed, 31 May 2023 23:36:54 +0900 Subject: [PATCH 096/367] =?UTF-8?q?feat:=20=EB=82=98=EC=9D=98=20=EC=9E=A5?= =?UTF-8?q?=EB=B0=94=EA=B5=AC=EB=8B=88=20=EB=A6=AC=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/cart/entity/dto/response/CartResponse.java | 1 + .../domain/cart/repository/CartRepository.java | 4 ++++ .../domain/cart/service/CartService.java | 11 ++++++++++- .../entity/dto/response/ProductOptionResponse.java | 2 +- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java index f091813a..8ba9b682 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java @@ -7,6 +7,7 @@ import project.trendpick_pro.domain.cart.entity.CartItem; import java.util.List; +import java.util.stream.Collectors; @Getter public class CartResponse { diff --git a/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java b/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java index a1d24b99..38397e7c 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java +++ b/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java @@ -2,7 +2,11 @@ import org.springframework.data.jpa.repository.JpaRepository; import project.trendpick_pro.domain.cart.entity.Cart; +import project.trendpick_pro.domain.member.entity.Member; + +import java.util.List; public interface CartRepository extends JpaRepository { Cart findByMemberId(Long memberId); + List findByCartMemberId(Member member); } diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index e9a712f0..649204f5 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -1,15 +1,21 @@ package project.trendpick_pro.domain.cart.service; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.cart.entity.Cart; import project.trendpick_pro.domain.cart.entity.CartItem; +import project.trendpick_pro.domain.cart.entity.dto.request.CartRequest; +import project.trendpick_pro.domain.cart.entity.dto.response.CartResponse; import project.trendpick_pro.domain.cart.repository.CartRepository; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.ProductOption; import project.trendpick_pro.domain.product.repository.ProductOptionRepository; +import java.util.List; @Service @@ -20,6 +26,9 @@ public class CartService { private final CartRepository cartRepository; private final ProductOptionRepository productOptionRepository; + public List findByCartMember(Member member){ + return cartRepository.findByCartMemberId(member); + } public Cart createCart(Member member) { Cart cart = new Cart(member); return cartRepository.save(cart); @@ -60,6 +69,6 @@ public Cart getCartByUser(Member member) { private ProductOption getProductOptionById(Long productOptionId) { return productOptionRepository.findById(productOptionId) - .orElseThrow(() -> new IllegalArgumentException("Product option not found")); + .orElseThrow(() -> new IllegalArgumentException("상품 옵션을 찾을 수 없습니다.")); } } diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductOptionResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductOptionResponse.java index 517392c4..78855c5e 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductOptionResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductOptionResponse.java @@ -12,7 +12,7 @@ @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class ProductOptionResponse { +public class ProductOptionResponse { Product product; private String color; From 24dc5acf8a16dbf51dfa21e263f3caf1b11fa3e2 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 31 May 2023 23:39:46 +0900 Subject: [PATCH 097/367] =?UTF-8?q?fix:=20=EC=83=81=ED=92=88=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8C=85=20querydsl=EC=97=90=20=EC=A0=95=EB=A0=AC?= =?UTF-8?q?=EC=A1=B0=EA=B1=B4=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/product/entity/Product.java | 1 - .../entity/dto/request/ProductSearchCond.java | 4 ++- .../repository/ProductRepositoryImpl.java | 26 ++++++++++++++++--- .../product/service/ProductService.java | 4 +-- 4 files changed, 27 insertions(+), 8 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index 9e3621d2..e630ddc1 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -98,7 +98,6 @@ public void removeStock(int quantity) throws IllegalAccessException { this.stock = restStock; } - public void update(ProductSaveRequest request) { // 여기서 파일 지지고 볶고 할 예정 diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSearchCond.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSearchCond.java index 41b5c1b0..e53ef4ec 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSearchCond.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSearchCond.java @@ -7,9 +7,11 @@ public class ProductSearchCond { private final String mainCategory; private final String subCategory; + private final Integer sortCode; - public ProductSearchCond(String mainCategory, String subCategory) { + public ProductSearchCond(String mainCategory, String subCategory, Integer sortCode) { this.mainCategory = mainCategory; this.subCategory = subCategory; + this.sortCode = sortCode; } } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 8ba9cae5..7b6901a8 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -1,5 +1,7 @@ package project.trendpick_pro.domain.product.repository; +import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; @@ -30,11 +32,17 @@ public ProductRepositoryImpl(EntityManager em) { @Override public Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable) { List result = queryFactory +// .select(Projections.constructor(ProductListResponse.class, +// product.id, +// product.name, +// brand.name, +// product.file.translatedFileName, +// product.price)) .select(new QProductListResponse( product.id, product.name, brand.name, - product.file.translatedFileName, + commonFile.translatedFileName, product.price )) .from(product) @@ -43,12 +51,12 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag .leftJoin(product.brand, brand) .leftJoin(product.file, commonFile) .where( - mainCategoryEq(cond), - subCategoryEq(cond) - + mainCategoryEq(cond) + .and(subCategoryEq(cond)) ) .offset(0) .limit(18) + .orderBy(orderSelector(cond.getSortCode())) //정렬추가 .fetch(); JPAQuery count = queryFactory @@ -73,4 +81,14 @@ private static BooleanExpression mainCategoryEq(ProductSearchCond cond) { private static BooleanExpression subCategoryEq(ProductSearchCond cond) { return subCategory.name.eq(cond.getSubCategory()); } + + private static OrderSpecifier orderSelector(Integer sortCode) { + return switch (sortCode) { + case 2 -> product.id.asc(); +// case 3 -> product.getRatingAvg.desc(); //평점 +// case 4 -> product.getRatingAvg.asc();; +// case 5 -> product.totalSales.desc(); + default -> product.id.desc(); + }; + } } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 863c8e95..de024b4f 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -78,11 +78,11 @@ public ProductResponse show(Long product_id) { return ProductResponse.of(product); } - public Page showAll(int offset, String mainCategory, String subCategory) { + public Page showAll(int offset, String mainCategory, String subCategory, Integer sortCode) { List responses = new ArrayList<>(); - ProductSearchCond cond = new ProductSearchCond(mainCategory, subCategory); + ProductSearchCond cond = new ProductSearchCond(mainCategory, subCategory, sortCode); PageRequest pageable = PageRequest.of(offset, 18); return productRepository.findAllByCategoryId(cond, pageable); From ebe6b8c7ec7efdaff91acd18dc5f118ed50d42de Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Wed, 31 May 2023 23:54:17 +0900 Subject: [PATCH 098/367] =?UTF-8?q?feat:=20=EB=82=98=EC=9D=98=20=EC=9E=A5?= =?UTF-8?q?=EB=B0=94=EA=B5=AC=EB=8B=88=20=EB=A6=AC=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cart/controller/CartController.java | 21 ++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java index 09220579..30ae55c1 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java +++ b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java @@ -3,14 +3,19 @@ import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; +import project.trendpick_pro.domain.cart.entity.Cart; import project.trendpick_pro.domain.cart.service.CartService; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; +import java.util.List; + @Controller @RequiredArgsConstructor @@ -18,6 +23,14 @@ public class CartController { private final CartService cartService; private final Rq rq; + @PreAuthorize("isAuthenticated()") + @GetMapping("/list") + public String showCart(Model model) { + List carts=cartService.findByCartMember(rq.getMember()); + model.addAttribute("carts",carts); + return "redirect:/trendprick/list"; + } + @PreAuthorize("isAuthenticated()") @PostMapping("/add") public String addItemToCart(@RequestParam("productOptionId") Long productOptionId, @@ -25,21 +38,23 @@ public String addItemToCart(@RequestParam("productOptionId") Long productOptionI Member member = rq.getMember(); cartService.addItemToCart(member, productOptionId, count); // 쇼핑을 계속 하시겠습니까? 띄우고 yes이면 main no면 cart로 - return "redirect:/trendprick/cart"; + return "redirect:/trendprick/list"; } + @PreAuthorize("isAuthenticated()") @PostMapping("/remove") public String removeItemFromCart(@RequestParam("cartItemId") Long cartItemId) { Member member = rq.getMember(); cartService.removeItemFromCart(member, cartItemId); - return "redirect:/trendpick/cart"; + return "redirect:/trendpick/list"; } + @PreAuthorize("isAuthenticated()") @PostMapping("/update") public String updateCartItemQuantity(@RequestParam("cartItemId") Long cartItemId, @RequestParam("count") int count) { Member member = rq.getMember(); cartService.updateItemCount(member, cartItemId, count); - return "redirect:/trendpick/cart"; + return "redirect:/trendpick/list"; } } \ No newline at end of file From daac6c4e74495117628c247a7df196659a95e31c Mon Sep 17 00:00:00 2001 From: mmun <62290451+mmunkyeong@users.noreply.github.com> Date: Wed, 31 May 2023 23:55:21 +0900 Subject: [PATCH 099/367] =?UTF-8?q?Revert=20"feat:=20=EB=82=98=EC=9D=98=20?= =?UTF-8?q?=EC=9E=A5=EB=B0=94=EA=B5=AC=EB=8B=88=20=EB=A6=AC=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/cart/entity/dto/response/CartResponse.java | 1 - .../domain/cart/repository/CartRepository.java | 4 ---- .../domain/cart/service/CartService.java | 11 +---------- .../entity/dto/response/ProductOptionResponse.java | 2 +- 4 files changed, 2 insertions(+), 16 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java index 8ba9b682..f091813a 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java @@ -7,7 +7,6 @@ import project.trendpick_pro.domain.cart.entity.CartItem; import java.util.List; -import java.util.stream.Collectors; @Getter public class CartResponse { diff --git a/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java b/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java index 38397e7c..a1d24b99 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java +++ b/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java @@ -2,11 +2,7 @@ import org.springframework.data.jpa.repository.JpaRepository; import project.trendpick_pro.domain.cart.entity.Cart; -import project.trendpick_pro.domain.member.entity.Member; - -import java.util.List; public interface CartRepository extends JpaRepository { Cart findByMemberId(Long memberId); - List findByCartMemberId(Member member); } diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index 649204f5..e9a712f0 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -1,21 +1,15 @@ package project.trendpick_pro.domain.cart.service; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.cart.entity.Cart; import project.trendpick_pro.domain.cart.entity.CartItem; -import project.trendpick_pro.domain.cart.entity.dto.request.CartRequest; -import project.trendpick_pro.domain.cart.entity.dto.response.CartResponse; import project.trendpick_pro.domain.cart.repository.CartRepository; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.ProductOption; import project.trendpick_pro.domain.product.repository.ProductOptionRepository; -import java.util.List; @Service @@ -26,9 +20,6 @@ public class CartService { private final CartRepository cartRepository; private final ProductOptionRepository productOptionRepository; - public List findByCartMember(Member member){ - return cartRepository.findByCartMemberId(member); - } public Cart createCart(Member member) { Cart cart = new Cart(member); return cartRepository.save(cart); @@ -69,6 +60,6 @@ public Cart getCartByUser(Member member) { private ProductOption getProductOptionById(Long productOptionId) { return productOptionRepository.findById(productOptionId) - .orElseThrow(() -> new IllegalArgumentException("상품 옵션을 찾을 수 없습니다.")); + .orElseThrow(() -> new IllegalArgumentException("Product option not found")); } } diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductOptionResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductOptionResponse.java index 78855c5e..517392c4 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductOptionResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductOptionResponse.java @@ -12,7 +12,7 @@ @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) -public class ProductOptionResponse { +public class ProductOptionResponse { Product product; private String color; From 563f6e71385b110f4110e666b45156b4b93e1138 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 1 Jun 2023 00:01:55 +0900 Subject: [PATCH 100/367] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=EC=88=98,=20=ED=8F=89=EA=B7=A0=20=ED=8F=89=EC=A0=90?= =?UTF-8?q?=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trendpick_pro/domain/product/entity/Product.java | 10 ++++++++++ .../product/repository/ProductRepositoryImpl.java | 4 ++-- .../trendpick_pro/domain/review/entity/Review.java | 9 --------- .../domain/review/service/ReviewService.java | 4 +++- 4 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index e630ddc1..15744d17 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -57,6 +57,9 @@ public class Product extends BaseTimeEntity { @OneToMany(mappedBy = "product", cascade = CascadeType.ALL) private List tags = new ArrayList<>(); + public long reviewCount = 0; + public double rateAvg = 0; + @Builder public Product(String name, MainCategory mainCategory, SubCategory subCategory, Brand brand, String description, CommonFile file, int price, int stock, List tags) { @@ -98,6 +101,13 @@ public void removeStock(int quantity) throws IllegalAccessException { this.stock = restStock; } + public void addReview(int rating){ + double total = getRateAvg() * getReviewCount() + rating; + + this.reviewCount++; + this.rateAvg = Math.round(total / reviewCount * 10) / 10.0; + } + public void update(ProductSaveRequest request) { // 여기서 파일 지지고 볶고 할 예정 diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 7b6901a8..1630d010 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -85,8 +85,8 @@ private static BooleanExpression subCategoryEq(ProductSearchCond cond) { private static OrderSpecifier orderSelector(Integer sortCode) { return switch (sortCode) { case 2 -> product.id.asc(); -// case 3 -> product.getRatingAvg.desc(); //평점 -// case 4 -> product.getRatingAvg.asc();; +// case 3 -> product.getRateAvg.desc(); //평점 +// case 4 -> product.getRateAvg.asc();; // case 5 -> product.totalSales.desc(); default -> product.id.desc(); }; diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java index 3890209e..1ca514b2 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -50,15 +50,6 @@ public class Review extends BaseTimeEntity { private int rating; - @Builder - public Review(Member member, Product product, String title, String content, int rating){ - this.writer = member.getUsername(); - this.product = product; - this.title = title; - this.content = content; - this.rating = rating; - } - @Builder public Review(Member member, Product product, ReviewCreateRequest reviewCreateRequest){ this.writer = member.getUsername(); diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index cc6f7c93..d5c4ef80 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -53,7 +53,9 @@ public void delete(Long reviewId) { public ReviewResponse createReview(Member actor, Long productId, ReviewCreateRequest reviewCreateRequest, MultipartFile mainFile, List subFiles) throws Exception { Product product = productRepository.findById(productId).orElseThrow(); //사진 없는 리뷰만 일단 저장 - Review review = new Review(actor, product, reviewCreateRequest); + + Review review = Review.of(reviewCreateRequest, actor, product); + product.addReview(review.getRating()); //상품 리뷰수, 상품 평균 평점을 계산해서 저장 reviewRepository.save(review); //메인 이미지 파일 저장 From 78361f30ecd8c624899a482114bea8d0e206bcf4 Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Thu, 1 Jun 2023 00:04:21 +0900 Subject: [PATCH 101/367] =?UTF-8?q?feat:=20=EB=82=98=EC=9D=98=20=EC=9E=A5?= =?UTF-8?q?=EB=B0=94=EA=B5=AC=EB=8B=88=20=EB=A6=AC=EC=8A=A4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/cart/controller/CartController.java | 1 + .../domain/cart/entity/dto/request/CartRequest.java | 2 +- .../domain/cart/entity/dto/response/CartItemResponse.java | 1 + .../domain/cart/entity/dto/response/CartResponse.java | 1 - .../domain/cart/repository/CartRepository.java | 2 +- .../trendpick_pro/domain/cart/service/CartService.java | 6 +----- 6 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java index 30ae55c1..da937704 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java +++ b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java @@ -23,6 +23,7 @@ public class CartController { private final CartService cartService; private final Rq rq; + @PreAuthorize("isAuthenticated()") @GetMapping("/list") public String showCart(Model model) { diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartRequest.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartRequest.java index 0119aaf7..f5fa3ec9 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartRequest.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartRequest.java @@ -6,4 +6,4 @@ public class CartRequest { @NotBlank private Long memberId; -} +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java index 65508e62..fd0a624c 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java @@ -6,6 +6,7 @@ import project.trendpick_pro.domain.cart.entity.CartItem; + @Getter public class CartItemResponse { private Long id; diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java index 8ba9b682..f091813a 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java @@ -7,7 +7,6 @@ import project.trendpick_pro.domain.cart.entity.CartItem; import java.util.List; -import java.util.stream.Collectors; @Getter public class CartResponse { diff --git a/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java b/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java index 38397e7c..0eaa2290 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java +++ b/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java @@ -9,4 +9,4 @@ public interface CartRepository extends JpaRepository { Cart findByMemberId(Long memberId); List findByCartMemberId(Member member); -} +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index 649204f5..ad70cbb5 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -1,15 +1,10 @@ package project.trendpick_pro.domain.cart.service; import lombok.RequiredArgsConstructor; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.PageRequest; -import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.cart.entity.Cart; import project.trendpick_pro.domain.cart.entity.CartItem; -import project.trendpick_pro.domain.cart.entity.dto.request.CartRequest; -import project.trendpick_pro.domain.cart.entity.dto.response.CartResponse; import project.trendpick_pro.domain.cart.repository.CartRepository; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.ProductOption; @@ -29,6 +24,7 @@ public class CartService { public List findByCartMember(Member member){ return cartRepository.findByCartMemberId(member); } + public Cart createCart(Member member) { Cart cart = new Cart(member); return cartRepository.save(cart); From d627a02831b4215d1363200bc7bdaee352da262d Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 1 Jun 2023 00:05:30 +0900 Subject: [PATCH 102/367] =?UTF-8?q?refactor:=20=EC=83=81=ED=92=88=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8C=85=20=ED=8F=89=EA=B7=A0=ED=8F=89=EC=A0=90?= =?UTF-8?q?=EC=88=9C,=20=EB=A6=AC=EB=B7=B0=EC=88=98=EC=88=9C=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/product/repository/ProductRepositoryImpl.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 1630d010..87bb82f9 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -85,9 +85,9 @@ private static BooleanExpression subCategoryEq(ProductSearchCond cond) { private static OrderSpecifier orderSelector(Integer sortCode) { return switch (sortCode) { case 2 -> product.id.asc(); -// case 3 -> product.getRateAvg.desc(); //평점 -// case 4 -> product.getRateAvg.asc();; -// case 5 -> product.totalSales.desc(); + case 3 -> product.rateAvg.desc(); //평점 + case 4 -> product.rateAvg.asc(); + case 5 -> product.reviewCount.desc(); //리뷰수 default -> product.id.desc(); }; } From 11c8ce2348a8cf418b8cf297f6ce69376125adbb Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Thu, 1 Jun 2023 15:16:08 +0900 Subject: [PATCH 103/367] =?UTF-8?q?refactor:=20=EB=8F=99=EC=8B=9C=EC=84=B1?= =?UTF-8?q?=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BD=94=EB=93=9C=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20(#77)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/cart/entity/Cart.java | 2 +- .../cart/repository/CartRepository.java | 8 +- .../domain/cart/service/CartService.java | 6 +- .../delivery/service/DeliveryService.java | 18 +++ .../MemberAlreadyExistException.java | 4 +- .../exception/MemberNotFoundException.java | 4 +- .../exception/MemberNotMatchException.java | 4 +- .../domain/orders/entity/OrderItem.java | 2 +- .../entity/dto/request/OrderSaveRequest.java | 2 + .../domain/orders/service/OrderService.java | 11 +- .../domain/product/entity/Product.java | 6 +- .../exception/ProductNotFoundException.java | 14 ++ .../exception/ProductStockOutException.java | 14 ++ ...{baseException.java => BaseException.java} | 4 +- .../global/exception/ErrorCode.java | 4 +- .../exception/GlobalExceptionAdvice.java | 9 ++ .../orders/service/OrderServiceTest.java | 121 ++++++++++++++++++ 17 files changed, 212 insertions(+), 21 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/delivery/service/DeliveryService.java create mode 100644 src/main/java/project/trendpick_pro/domain/product/exception/ProductNotFoundException.java create mode 100644 src/main/java/project/trendpick_pro/domain/product/exception/ProductStockOutException.java rename src/main/java/project/trendpick_pro/global/exception/{baseException.java => BaseException.java} (78%) create mode 100644 src/test/java/project/trendpick_pro/domain/orders/service/OrderServiceTest.java diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java index fb620dcb..c1076e12 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java @@ -24,7 +24,7 @@ public class Cart { @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "member_id") - private Member member; + private Member member; @OneToMany(mappedBy = "cart", cascade = CascadeType.ALL, orphanRemoval = true) private List cartItems = new ArrayList<>(); diff --git a/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java b/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java index 29025855..799f49c5 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java +++ b/src/main/java/project/trendpick_pro/domain/cart/repository/CartRepository.java @@ -1,10 +1,14 @@ package project.trendpick_pro.domain.cart.repository; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import project.trendpick_pro.domain.cart.entity.Cart; +import project.trendpick_pro.domain.member.entity.Member; + +import java.util.List; public interface CartRepository extends JpaRepository { Cart findByMemberId(Long memberId); - List findByCartMemberId(Member member); + @Query("select c from Cart c where c.member = :member") + List findByCartMember(Member member); } - diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index ccb2e5e4..fc0e6f5d 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -7,9 +7,12 @@ import project.trendpick_pro.domain.cart.entity.CartItem; import project.trendpick_pro.domain.cart.repository.CartRepository; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.exception.MemberNotFoundException; +import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.product.entity.ProductOption; import project.trendpick_pro.domain.product.repository.ProductOptionRepository; +import java.util.List; @Service @@ -18,10 +21,11 @@ public class CartService { private final CartRepository cartRepository; + private final MemberRepository memberRepository; private final ProductOptionRepository productOptionRepository; public List findByCartMember(Member member){ - return cartRepository.findByCartMemberId(member); + return cartRepository.findByCartMember(member); } public Cart createCart(Member member) { diff --git a/src/main/java/project/trendpick_pro/domain/delivery/service/DeliveryService.java b/src/main/java/project/trendpick_pro/domain/delivery/service/DeliveryService.java new file mode 100644 index 00000000..a436ddd9 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/delivery/service/DeliveryService.java @@ -0,0 +1,18 @@ +package project.trendpick_pro.domain.delivery.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import project.trendpick_pro.domain.delivery.repository.DeliveryRepository; + +@Service +@RequiredArgsConstructor +public class DeliveryService { + + private final DeliveryRepository deliveryRepository; + + public void updateDeliveryStatus(Long deliveryId, String status) { +// deliveryRepository.updateDeliveryStatus(deliveryId, status); + } + + +} diff --git a/src/main/java/project/trendpick_pro/domain/member/exception/MemberAlreadyExistException.java b/src/main/java/project/trendpick_pro/domain/member/exception/MemberAlreadyExistException.java index 136192d0..673a950b 100644 --- a/src/main/java/project/trendpick_pro/domain/member/exception/MemberAlreadyExistException.java +++ b/src/main/java/project/trendpick_pro/domain/member/exception/MemberAlreadyExistException.java @@ -2,9 +2,9 @@ import org.springframework.http.HttpStatus; import project.trendpick_pro.global.exception.ErrorCode; -import project.trendpick_pro.global.exception.baseException; +import project.trendpick_pro.global.exception.BaseException; -public class MemberAlreadyExistException extends baseException { +public class MemberAlreadyExistException extends BaseException { private static final ErrorCode code = ErrorCode.MEMBER_ALREADY_EXIST; diff --git a/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotFoundException.java b/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotFoundException.java index 38cc0f1a..04fab731 100644 --- a/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotFoundException.java +++ b/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotFoundException.java @@ -2,9 +2,9 @@ import org.springframework.http.HttpStatus; import project.trendpick_pro.global.exception.ErrorCode; -import project.trendpick_pro.global.exception.baseException; +import project.trendpick_pro.global.exception.BaseException; -public class MemberNotFoundException extends baseException { +public class MemberNotFoundException extends BaseException { private static final ErrorCode code = ErrorCode.MEMBER_NOT_FOUND; diff --git a/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotMatchException.java b/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotMatchException.java index a13bfa7b..6b41ec42 100644 --- a/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotMatchException.java +++ b/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotMatchException.java @@ -2,9 +2,9 @@ import org.springframework.http.HttpStatus; import project.trendpick_pro.global.exception.ErrorCode; -import project.trendpick_pro.global.exception.baseException; +import project.trendpick_pro.global.exception.BaseException; -public class MemberNotMatchException extends baseException { +public class MemberNotMatchException extends BaseException { private static final ErrorCode code = ErrorCode.MEMBER_NOT_MATCH; public MemberNotMatchException(String message) { diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java index 74845639..26846ed7 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java @@ -31,7 +31,7 @@ public class OrderItem { @Column(name = "count", nullable = false) private int count; - public OrderItem(Product product, int orderPrice, int count) throws IllegalAccessException { + public OrderItem(Product product, int orderPrice, int count) { this.product = product; this.orderPrice = orderPrice; this.count = count; diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSaveRequest.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSaveRequest.java index 287ab7bf..fc85f115 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSaveRequest.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSaveRequest.java @@ -1,9 +1,11 @@ package project.trendpick_pro.domain.orders.entity.dto.request; import jakarta.validation.constraints.NotBlank; +import lombok.AllArgsConstructor; import lombok.Getter; @Getter +@AllArgsConstructor public class OrderSaveRequest { private Long productId; diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 8e58529a..594df606 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -10,14 +10,17 @@ import project.trendpick_pro.domain.delivery.entity.Delivery; import project.trendpick_pro.domain.delivery.entity.embaded.Address; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.orders.entity.Order; import project.trendpick_pro.domain.orders.entity.OrderItem; import project.trendpick_pro.domain.orders.entity.OrderStatus; import project.trendpick_pro.domain.orders.entity.dto.request.OrderSaveRequest; import project.trendpick_pro.domain.orders.entity.dto.request.OrderSearchCond; +import project.trendpick_pro.domain.product.exception.ProductStockOutException; import project.trendpick_pro.domain.orders.repository.OrderRepository; import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.product.exception.ProductNotFoundException; import project.trendpick_pro.domain.product.repository.ProductRepository; import java.util.ArrayList; @@ -34,17 +37,17 @@ public class OrderService { private final ProductRepository productRepository; @Transactional - public void order(Long userId, OrderSaveRequest... orderSaveRequests) throws IllegalAccessException { + public synchronized void order(Long userId, OrderSaveRequest... orderSaveRequests) { - Member member = memberRepository.findById(userId).orElseThrow(() -> new EntityNotFoundException("존재하지 않는 유저 입니다."));// 임시 exception 설정 나중에 할 수도 있고 아닐수도 + Member member = memberRepository.findById(userId).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 유저 입니다."));// 임시 exception 설정 나중에 할 수도 있고 아닐수도 Delivery delivery = new Delivery(Address.of("서울시", "강남대로", "222")); // 임의로 작성 List orderItemList = new ArrayList<>(); for (OrderSaveRequest request: orderSaveRequests) { - Product product = productRepository.findById(request.getProductId()).orElseThrow(() -> new EntityNotFoundException("product is not found")); + Product product = productRepository.findById(request.getProductId()).orElseThrow(() -> new ProductNotFoundException("존재하지 않는 상품 입니다.")); if (product.getStock() < request.getQuantity()) { - throw new RuntimeException("stock is not enough"); // 임시. 나중에 사용자 exception 널을까말까 생각 + throw new ProductStockOutException("재고가 부족합니다."); // 임시. 나중에 사용자 exception 널을까말까 생각 } orderItemList.add(new OrderItem(product, product.getPrice(), request.getQuantity())); } diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index 15744d17..9aaf75fa 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -5,12 +5,12 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.brand.entity.Brand; import project.trendpick_pro.domain.category.entity.MainCategory; import project.trendpick_pro.domain.category.entity.SubCategory; import project.trendpick_pro.domain.common.base.BaseTimeEntity; import project.trendpick_pro.domain.common.file.CommonFile; +import project.trendpick_pro.domain.product.exception.ProductStockOutException; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.tag.entity.Tag; @@ -93,10 +93,10 @@ public void addStock(int quantity) { this.stock += quantity; } - public void removeStock(int quantity) throws IllegalAccessException { + public void removeStock(int quantity) { int restStock = this.stock - quantity; if (restStock < 0) { - throw new IllegalAccessException("need more stock"); + throw new ProductStockOutException("재고가 부족합니다."); } this.stock = restStock; } diff --git a/src/main/java/project/trendpick_pro/domain/product/exception/ProductNotFoundException.java b/src/main/java/project/trendpick_pro/domain/product/exception/ProductNotFoundException.java new file mode 100644 index 00000000..d4d04f61 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/exception/ProductNotFoundException.java @@ -0,0 +1,14 @@ +package project.trendpick_pro.domain.product.exception; + +import org.springframework.http.HttpStatus; +import project.trendpick_pro.global.exception.BaseException; +import project.trendpick_pro.global.exception.ErrorCode; + +public class ProductNotFoundException extends BaseException { + + private static final ErrorCode code = ErrorCode.PRODUCT_NOT_FOUND; + + public ProductNotFoundException(String message) { + super(code, HttpStatus.BAD_REQUEST, message); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/product/exception/ProductStockOutException.java b/src/main/java/project/trendpick_pro/domain/product/exception/ProductStockOutException.java new file mode 100644 index 00000000..c6009196 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/exception/ProductStockOutException.java @@ -0,0 +1,14 @@ +package project.trendpick_pro.domain.product.exception; + +import org.springframework.http.HttpStatus; +import project.trendpick_pro.global.exception.BaseException; +import project.trendpick_pro.global.exception.ErrorCode; + +public class ProductStockOutException extends BaseException { + + private static final ErrorCode code = ErrorCode.ORDERITEM_OUT; + + public ProductStockOutException(String message) { + super(code, HttpStatus.BAD_REQUEST, message); + } +} diff --git a/src/main/java/project/trendpick_pro/global/exception/baseException.java b/src/main/java/project/trendpick_pro/global/exception/BaseException.java similarity index 78% rename from src/main/java/project/trendpick_pro/global/exception/baseException.java rename to src/main/java/project/trendpick_pro/global/exception/BaseException.java index d5e668da..2ab6762c 100644 --- a/src/main/java/project/trendpick_pro/global/exception/baseException.java +++ b/src/main/java/project/trendpick_pro/global/exception/BaseException.java @@ -2,12 +2,12 @@ import org.springframework.http.HttpStatus; -public abstract class baseException extends RuntimeException { +public abstract class BaseException extends RuntimeException { private final ErrorCode errorCode; private final HttpStatus httpStatus; - protected baseException(ErrorCode errorCode, HttpStatus httpStatus, String message) { + protected BaseException(ErrorCode errorCode, HttpStatus httpStatus, String message) { super(message); this.errorCode = errorCode; this.httpStatus = httpStatus; diff --git a/src/main/java/project/trendpick_pro/global/exception/ErrorCode.java b/src/main/java/project/trendpick_pro/global/exception/ErrorCode.java index 072686ad..d260e0d8 100644 --- a/src/main/java/project/trendpick_pro/global/exception/ErrorCode.java +++ b/src/main/java/project/trendpick_pro/global/exception/ErrorCode.java @@ -7,7 +7,9 @@ public enum ErrorCode { MEMBER_NOT_FOUND(404, "MEMBER-001", "멤버가 존재하지 않는 경우"), MEMBER_NOT_MATCH(403, "MEMBER-002", "멤버 권한이 다를 경우"), - MEMBER_ALREADY_EXIST(409, "MEMBER-003", "같은 멤버가 이미 존재하는 경우"); + MEMBER_ALREADY_EXIST(409, "MEMBER-003", "같은 멤버가 이미 존재하는 경우"), + PRODUCT_NOT_FOUND(404, "PRODUCT-001", "상품이 존재 하지 않을 경우"), + ORDERITEM_OUT(404, "ORDERITEM-001", "재고가 없을 경우"); private final int status; private final String code; diff --git a/src/main/java/project/trendpick_pro/global/exception/GlobalExceptionAdvice.java b/src/main/java/project/trendpick_pro/global/exception/GlobalExceptionAdvice.java index b3a4123a..7c588fbe 100644 --- a/src/main/java/project/trendpick_pro/global/exception/GlobalExceptionAdvice.java +++ b/src/main/java/project/trendpick_pro/global/exception/GlobalExceptionAdvice.java @@ -7,6 +7,7 @@ import project.trendpick_pro.domain.member.exception.MemberAlreadyExistException; import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.exception.MemberNotMatchException; +import project.trendpick_pro.domain.product.exception.ProductNotFoundException; @Slf4j @RestControllerAdvice @@ -35,4 +36,12 @@ public ResponseEntity MemberAlreadyExistHandleException(MemberAlr ErrorResponse errorResponse = new ErrorResponse(errorCode.getCode(), e.getMessage()); return ResponseEntity.status(errorCode.getStatus()).body(errorResponse); } + + @ExceptionHandler(ProductNotFoundException.class) + public ResponseEntity ProductNotFoundHandleException(ProductNotFoundException e) { + ErrorCode errorCode = e.getErrorCode(); + log.error("[exceptionHandle] ex", e); + ErrorResponse errorResponse = new ErrorResponse(errorCode.getCode(), e.getMessage()); + return ResponseEntity.status(errorCode.getStatus()).body(errorResponse); + } } diff --git a/src/test/java/project/trendpick_pro/domain/orders/service/OrderServiceTest.java b/src/test/java/project/trendpick_pro/domain/orders/service/OrderServiceTest.java new file mode 100644 index 00000000..fe324ba7 --- /dev/null +++ b/src/test/java/project/trendpick_pro/domain/orders/service/OrderServiceTest.java @@ -0,0 +1,121 @@ +package project.trendpick_pro.domain.orders.service; + +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.mockito.junit.jupiter.MockitoExtension; +import org.slf4j.LoggerFactory; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.security.crypto.password.PasswordEncoder; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.entity.RoleType; +import project.trendpick_pro.domain.member.repository.MemberRepository; +import project.trendpick_pro.domain.orders.entity.dto.request.OrderSaveRequest; +import project.trendpick_pro.domain.orders.repository.OrderRepository; +import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.product.repository.ProductRepository; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.*; +import java.util.logging.Logger; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.Mockito.when; + +public class OrderServiceTest { + + private static final org.slf4j.Logger logger = LoggerFactory.getLogger(OrderServiceTest.class); + + + @InjectMocks + OrderService orderService; + + @Mock + MemberRepository memberRepository; + + @Mock + ProductRepository productRepository; + + @Mock + OrderRepository orderRepository; + + @BeforeEach + public void setUp() { + MockitoAnnotations.openMocks(this); + + // 이 부분에서 테스트에 필요한 데이터를 설정하실 수 있습니다. +// Member member = new Member(); +// Product product = new Product(); // 적절한 Product 객체 생성 +// product.setStock(10); +// when(memberRepository.findById(any())).thenReturn(Optional.of(member)); +// when(productRepository.findById(any())).thenReturn(Optional.of(product)); + } + + @Test + @DisplayName("주문 재고 동시성 확인") + public void concurrencyTest() throws Exception { + ExecutorService executorService = Executors.newFixedThreadPool(10); + List> futures = new ArrayList<>(); + + for (int i = 1; i <= 11; i++) { + int finalI = i; + Future future = executorService.submit(() -> { + try { + orderService.order(1L, new OrderSaveRequest(1L, 1)); // 적절한 OrderSaveRequest 객체 사용 + logger.info(String.valueOf(finalI)); + } catch (Exception e) { + logger.error(String.valueOf(finalI)); + throw new IllegalStateException(e); + } + }); + futures.add(future); + } + + for (Future future : futures) { + future.get(); + } + + executorService.shutdown(); + if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) { + executorService.shutdownNow(); + } + } + + private long account = 100_000L; // 계좌 잔고 100,000원 + + @Test + void pay() throws InterruptedException { + // given + ExecutorService executor = Executors.newFixedThreadPool(2); + CountDownLatch countDownLatch = new CountDownLatch(2); + + // when + executor.submit(() -> execute("A", 40_000L, countDownLatch)); // A가 40,000원 결제 + executor.submit(() -> execute("B", 20_000L, countDownLatch)); // B가 20,000원 결제 + countDownLatch.await(); + + // then + assertThat(account).isEqualTo(40_000L); // 60,000원을 사용했으므로 예상 잔액은 40,000원 + } + + private void execute(String username, long money, CountDownLatch countDownLatch) { + try { + pay(username, money); + } finally { + countDownLatch.countDown(); + } + } + + private synchronized void pay(String username, long money) { + long result = account - money; + System.out.printf("%s가 %d원을 사용한 뒤 남은 금액은 %d 입니다.\n", username, money, result); + account = result; + } +} From 5bf4dd75e02c74699fb7dc3ab7940e3775f973fe Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Thu, 1 Jun 2023 16:49:06 +0900 Subject: [PATCH 104/367] =?UTF-8?q?feat:=20=EC=B4=88=EA=B8=B0=20=EC=84=A0?= =?UTF-8?q?=ED=98=B8=ED=83=9C=EA=B7=B8=20=EC=B6=94=EA=B0=80,=20=ED=9A=8C?= =?UTF-8?q?=EC=9B=90=EA=B0=80=EC=9E=85=EC=8B=9C=EC=97=90=20=EB=A9=A4?= =?UTF-8?q?=EB=B2=84=EC=97=90=EA=B2=8C=20=EC=84=A0=ED=83=9D=ED=95=9C=20?= =?UTF-8?q?=EC=84=A0=ED=83=9C=EA=B7=B8=20=EC=A0=80=EC=9E=A5=20(#89)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/controller/MemberController.java | 1 + .../domain/member/entity/Member.java | 6 ++-- .../domain/member/entity/form/JoinForm.java | 5 ++- .../domain/member/service/MemberService.java | 26 ++++++++++++++ .../tag/entity/dto/request/TagRequest.java | 11 ++++++ .../entity/dto/response/TagListResponse.java | 8 +++++ .../tag/entity/dto/response/TagResponse.java | 13 +++++++ .../domain/tag/repository/TagRepository.java | 3 ++ .../domain/tag/service/TagService.java | 20 +++++++++++ .../global/basedata/BaseData.java | 36 +++++++++++++++++++ src/main/resources/application-tag.yml | 15 ++++++++ src/main/resources/application.yml | 2 +- 12 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/tag/entity/dto/request/TagRequest.java create mode 100644 src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagListResponse.java create mode 100644 src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagResponse.java create mode 100644 src/main/java/project/trendpick_pro/domain/tag/service/TagService.java create mode 100644 src/main/java/project/trendpick_pro/global/basedata/BaseData.java create mode 100644 src/main/resources/application-tag.yml diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java index 1418f449..8ee7812a 100644 --- a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java +++ b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java @@ -29,6 +29,7 @@ public class MemberController { @GetMapping("/register") public String register(JoinForm joinForm, Model model) { model.addAttribute("joinForm", joinForm); +// model.addAttribute(memberService.) return "trendpick/usr/member/join"; } diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index 12719099..ee7079c4 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -34,8 +34,6 @@ public class Member { @Column(name = "phone_number", nullable = false) private String phoneNumber; - private LocalDate birth; - @Enumerated(EnumType.STRING) private RoleType role; @@ -71,4 +69,8 @@ public void connectBank(String bankName, String bankAccount) { this.bankName = bankName; this.bankAccount = bankAccount; } + + public void changeTags(List tags) { + this.tags = tags; + } } diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java b/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java index f4dab0e5..878ff7ca 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java @@ -3,9 +3,12 @@ import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; +import java.util.List; + public record JoinForm(@NotBlank(message = "email을 입력해주세요.") String emailtext, @NotBlank(message = "password를 입력해주세요.") String password, @NotBlank(message = "이름을 입력해주세요.") String username, @NotBlank(message = "휴대폰 번호를 입력해주세요.") String phoneNumber, - @NotBlank(message = "권한을 입력해주세요.") String state) { + @NotBlank(message = "권한을 입력해주세요.") String state, + @NotBlank(message = "선호하는 태그를 입력해주세요.")List tags) { } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index 29ecb335..b6078175 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -8,8 +8,14 @@ import project.trendpick_pro.domain.member.entity.RoleType; import project.trendpick_pro.domain.member.entity.form.JoinForm; import project.trendpick_pro.domain.member.exception.MemberAlreadyExistException; +import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.repository.MemberRepository; +import project.trendpick_pro.domain.tag.entity.Tag; +import project.trendpick_pro.domain.tag.entity.dto.request.TagRequest; +import project.trendpick_pro.domain.tag.repository.TagRepository; +import java.util.ArrayList; +import java.util.List; import java.util.Objects; import java.util.Optional; @@ -17,9 +23,11 @@ @RequiredArgsConstructor @Transactional(readOnly = true) public class MemberService { + private final PasswordEncoder passwordEncoder; private final MemberRepository memberRepository; + private final TagRepository tagRepository; public Optional findByUsername(String username) { return memberRepository.findByUsername(username); @@ -41,6 +49,11 @@ public void register(JoinForm joinForm) { roleType = RoleType.MEMBER; } + List tags = new ArrayList<>(); + for (String tag : joinForm.tags()) { + tagRepository.findByName(tag).ifPresent(tags::add); + } + Member member = Member .builder() .email(joinForm.emailtext()) @@ -48,10 +61,23 @@ public void register(JoinForm joinForm) { .username(joinForm.username()) .phoneNumber(joinForm.phoneNumber()) .role(roleType) + .tags(tags) .build(); memberRepository.save(member); } + + @Transactional + public void manageTag(String username, TagRequest tagRequest){ + Member member = memberRepository.findByUsername(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); + + List tags = new ArrayList<>(); + for (String s : tagRequest.getTags()) { + tagRepository.findByName(s).ifPresent(tags::add); + } + member.changeTags(tags); + } + @Transactional public void manageAddress(Member actor, String address){ Member member = memberRepository.findByUsername(actor.getUsername()).orElseThrow(); diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/dto/request/TagRequest.java b/src/main/java/project/trendpick_pro/domain/tag/entity/dto/request/TagRequest.java new file mode 100644 index 00000000..9daae94e --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/tag/entity/dto/request/TagRequest.java @@ -0,0 +1,11 @@ +package project.trendpick_pro.domain.tag.entity.dto.request; + +import lombok.Getter; + +import java.util.List; + +@Getter +public class TagRequest { + + List tags; +} diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagListResponse.java b/src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagListResponse.java new file mode 100644 index 00000000..283bb949 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagListResponse.java @@ -0,0 +1,8 @@ +package project.trendpick_pro.domain.tag.entity.dto.response; + +import lombok.Getter; + +@Getter +public class TagListResponse { + +} diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagResponse.java b/src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagResponse.java new file mode 100644 index 00000000..8403ca3d --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagResponse.java @@ -0,0 +1,13 @@ +package project.trendpick_pro.domain.tag.entity.dto.response; + +import lombok.Getter; + +@Getter +public class TagResponse { + + String tag; + + public TagResponse(String tag) { + this.tag = tag; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/tag/repository/TagRepository.java b/src/main/java/project/trendpick_pro/domain/tag/repository/TagRepository.java index fd9262b4..8b7d66e2 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/repository/TagRepository.java +++ b/src/main/java/project/trendpick_pro/domain/tag/repository/TagRepository.java @@ -3,5 +3,8 @@ import org.springframework.data.jpa.repository.JpaRepository; import project.trendpick_pro.domain.tag.entity.Tag; +import java.util.Optional; + public interface TagRepository extends JpaRepository { + public Optional findByName(String name); } diff --git a/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java b/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java new file mode 100644 index 00000000..70a3a760 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java @@ -0,0 +1,20 @@ +package project.trendpick_pro.domain.tag.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import project.trendpick_pro.domain.tag.entity.dto.response.TagResponse; +import project.trendpick_pro.domain.tag.repository.TagRepository; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class TagService { + + private final TagRepository tagRepository; + + public List getAllTags() { +// return TagResponse.of(tagRepository.findAll()); + return null; + } +} diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java new file mode 100644 index 00000000..d8c337e5 --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -0,0 +1,36 @@ +package project.trendpick_pro.global.basedata; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.Profile; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.member.service.MemberService; +import project.trendpick_pro.domain.tag.entity.Tag; +import project.trendpick_pro.domain.tag.repository.TagRepository; + +import java.util.List; + +@Configuration +@Profile({"dev", "test"}) +public class BaseData { + + @Value("${tag}") + List tags; + + @Bean + CommandLineRunner initData( + TagRepository tagRepository + ) { + return new CommandLineRunner() { + @Override + @Transactional + public void run(String... args) { + for (String tag : tags) { + tagRepository.save(new Tag(tag)); + } + } + }; + } +} diff --git a/src/main/resources/application-tag.yml b/src/main/resources/application-tag.yml new file mode 100644 index 00000000..c9bcd0ac --- /dev/null +++ b/src/main/resources/application-tag.yml @@ -0,0 +1,15 @@ +tag: + 오버핏청바지, 시티보이룩, 스포티캐주얼, 빈티지룩, 프레피스타일, + 모던미니멀리스트, 로맨틱룩, 로커룩, 힙합룩, 데님스타일, + 스트릿패션, 빅사이즈룩, 오가닉패션, 애슬레저룩, 비즈니스캐주얼, + 테일러드룩, 코지니트, 밀리터리룩, 고딕패션, 펑크룩, + 레트로스타일, 베이직룩, 컬러풀패션, 모노톤스타일, 럭셔리룩, + 블랙스타일, 루즈핏패션, 크롭트스타일, 블레이저룩, 코디로이패션, + 플레어팬츠, 파스텔룩, 파워드레싱, 스쿨룩, 체크패턴룩, + 스트라이프패션, 레이어드스타일, 프린트룩, 그래픽티룩, 라이더스자켓, + 보헤미안룩, 밴드티룩, 카모플라지패션, 바이커룩, 스커트스타일, 화이트룩, + 리넨룩, 폴로스타일, 트렌치룩, 카키스타일, 데일리룩, 캐릭터티룩, 유니크패션, + 파티룩, 브랜드룩, 플로럴패션, 캐주얼드레스룩, 점프수트스타일, 턱시도룩, + 글램룩, 키치패션, 스니커즈룩, 드레시룩, 레더스타일, 펑키패션, 스웨터룩, + 이브닝룩, 스포티룩, 캐주얼코트룩, 모헤어니트, 네온패션, 폴카닷스타일, + 롱코트룩, 블록패션, 밴딩팬츠룩, 야상룩, 플랫폼룩, 보이시룩, 하이웨스트스타일, 더블브레스티드룩, 펑크록룩 \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 727e6d35..93cff954 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,7 +1,7 @@ spring: profiles: active: dev - include: secret + include: secret, tag mvc: pathmatch: matching-strategy: ant_path_matcher \ No newline at end of file From 1b97a00f907bcf47b4482418510df48a6a55f21c Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Thu, 1 Jun 2023 17:02:26 +0900 Subject: [PATCH 105/367] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=EC=97=90=20commonfile=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 8 +- .../domain/review/entity/Review.java | 63 +++++-------- .../domain/review/service/ReviewService.java | 90 ++++++------------- 3 files changed, 51 insertions(+), 110 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index 7d5d95c5..06dfdb4d 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -26,9 +26,9 @@ public class ReviewController { @PostMapping("/write") public String createReview(@Valid ReviewCreateRequest reviewCreateRequest, @RequestParam(value = "product") Long productId, - @RequestPart("main-file") MultipartFile mainFile, @RequestPart("sub-file") List subFileList, Model model) throws Exception { + Model model) throws Exception { Member actor = rq.getMember(); - ReviewResponse reviewResponse = reviewService.createReview(actor, productId, reviewCreateRequest, mainFile, subFileList); + ReviewResponse reviewResponse = reviewService.createReview(actor, productId, reviewCreateRequest); model.addAttribute("reviewResponse", reviewResponse); return "redirect:/trendpick/review"; @@ -51,8 +51,8 @@ public String deleteReview(@PathVariable Long reviewId) { @PostMapping("/edit/{reviewId}") public String updateReview(@PathVariable Long reviewId, ReviewUpdateRequest reviewUpdateRequest, - @RequestPart("main-file") @NotBlank MultipartFile mainImage, @RequestPart("sub-file") List subImages, Model model) throws IOException { - ReviewResponse reviewResponse = reviewService.update(reviewId, reviewUpdateRequest, mainImage, subImages); + Model model) throws IOException { + ReviewResponse reviewResponse = reviewService.update(reviewId, reviewUpdateRequest); model.addAttribute("reviewResponse", reviewResponse); return "redirect:/trendpick/review"; diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java index 1ca514b2..fa62e667 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -32,13 +32,9 @@ public class Review extends BaseTimeEntity { private String writer; - @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.REMOVE) - @JoinColumn(name = "review_image_id") - private ReviewImage reviewImage; - -// @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) -// @JoinColumn(name = "common_file_id") -// private CommonFile commonFile; + @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) + @JoinColumn(name = "file_id") + private CommonFile file; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "product_id") @@ -51,19 +47,20 @@ public class Review extends BaseTimeEntity { private int rating; @Builder - public Review(Member member, Product product, ReviewCreateRequest reviewCreateRequest){ + public Review(Member member, Product product, CommonFile file, String title, String content, int rating){ this.writer = member.getUsername(); this.product = product; - this.title = reviewCreateRequest.getTitle(); - this.content = reviewCreateRequest.getContent(); - this.rating = reviewCreateRequest.getRating(); + this.file = file; + this.title = title; + this.content = content; + this.rating = rating; } - public static Review of(ReviewCreateRequest reviewCreateRequest, Member member, Product product) { + public static Review of(ReviewCreateRequest reviewCreateRequest, Member member, Product product, CommonFile file) { return Review.builder() .writer(member.getUsername()) .product(product) - //.commonFile(makeFile(reviewCreateRequest.getMainFile(), reviewCreateRequest.getSubFiles())); + .file(file) .content(reviewCreateRequest.getContent()) .rating(reviewCreateRequest.getRating()) .build(); @@ -76,38 +73,20 @@ public void update(ReviewUpdateRequest reviewUpdateRequest){ this.rating = reviewUpdateRequest.getRating(); } - public void matchReviewImage(ReviewImage reviewImage){ - this.reviewImage = reviewImage; - } - -// @Value("${file.dir}") -// private static String filePath; -// -// private static String createStoreFileName(String originFileName){ -// String ext = extractExt(originFileName); -// String uuid = UUID.randomUUID().toString(); -// return uuid + "." + ext; -// } +// public void changeMainFile(String filePath, String mainFilePath, MultipartFile mainFile) throws IOException { +// File file = new File(filePath + mainFileName); +// file.delete(); //원래 있던거 삭제 // -// private static String extractExt(String originFileName) { -// int pos = originFileName.lastIndexOf("."); -// return originFileName.substring(pos + 1); +// this.mainFileName = mainFilePath; +// mainFile.transferTo(new File(filePath + mainFilePath)); // } - -// private static CommonFile makeFile(MultipartFile mainFile, List subFiles) throws IOException { -// String mainFileName = createStoreFileName(mainFile.getOriginalFilename()); -// List subFileName = new ArrayList<>(); -// -// mainFile.transferTo(new File(filePath + mainFileName)); // -// for(MultipartFile subFile : subFiles){ -// String savePath = createStoreFileName(subFile.getOriginalFilename()); -// subFileName.add(savePath); -// subFile.transferTo(new File(filePath + savePath)); +// public void changeSubFile(String filePath, List subFileNames) { +// //음 우선 돌면서 지워야겠지?? +// for(String subFile: subFileNames){ +// File file = new File(filePath + subFile); +// file.delete(); // } -// -// return null; -// -// +// this.subFileNames = subFileNames; // } } diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index d5c4ef80..f178fd00 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -6,11 +6,12 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; +import project.trendpick_pro.domain.common.base.filetranslator.FileTranslator; +import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.review.entity.Review; -import project.trendpick_pro.domain.review.entity.ReviewImage; import project.trendpick_pro.domain.review.entity.dto.request.ReviewCreateRequest; import project.trendpick_pro.domain.review.entity.dto.request.ReviewUpdateRequest; import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; @@ -31,6 +32,7 @@ public class ReviewService { private final ReviewRepository reviewRepository; private final ProductRepository productRepository; private final ReviewImageRepository reviewImageRepository; + private final FileTranslator fileTranslator; @Value("${file.dir}") private static String filePath; @@ -46,83 +48,43 @@ public ReviewResponse showReview(Long productId) { public void delete(Long reviewId) { Review review = reviewRepository.findById(reviewId).orElseThrow(); - review.getReviewImage().deleteImage(filePath); + //review.getReviewImage().deleteImage(filePath); reviewRepository.delete(review); } - public ReviewResponse createReview(Member actor, Long productId, ReviewCreateRequest reviewCreateRequest, MultipartFile mainFile, List subFiles) throws Exception { + public ReviewResponse createReview(Member actor, Long productId, ReviewCreateRequest reviewCreateRequest) throws Exception { Product product = productRepository.findById(productId).orElseThrow(); - //사진 없는 리뷰만 일단 저장 - Review review = Review.of(reviewCreateRequest, actor, product); - product.addReview(review.getRating()); //상품 리뷰수, 상품 평균 평점을 계산해서 저장 - reviewRepository.save(review); + CommonFile mainFile = fileTranslator.translateFile(reviewCreateRequest.getMainFile()); + List subFiles = fileTranslator.translateFileList(reviewCreateRequest.getSubFiles()); - //메인 이미지 파일 저장 - String mainFileName = saveMainFile(mainFile); - ReviewImage reviewImage = new ReviewImage(mainFileName, review); - reviewImageRepository.save(reviewImage); + for(CommonFile subFile : subFiles){ + mainFile.connectFile(subFile); + } - //서브 이미지 파일 저장 - saveSubFiles(subFiles, reviewImage); - review.matchReviewImage(reviewImage); + Review review = Review.of(reviewCreateRequest, actor, product, mainFile); + product.addReview(review.getRating()); //상품 리뷰수, 상품 평균 평점을 계산해서 저장 + reviewRepository.save(review); return ReviewResponse.of(review); } - public ReviewResponse update(Long reviewId, ReviewUpdateRequest reviewUpdateRequest, MultipartFile mainFile, List subFiles) throws IOException { + public ReviewResponse update(Long reviewId, ReviewUpdateRequest reviewUpdateRequest) throws IOException { Review review = reviewRepository.findById(reviewId).orElseThrow(); - ReviewImage reviewImage = review.getReviewImage(); - - //메인 파일 이름을 아예 있던거 없애고 바꿔버리기! - reviewImage.changeMainFile(filePath, createStoreFileName(mainFile.getOriginalFilename()), mainFile); - - //서브 파일도 같은 방식으로 - //비어있는 경우도 생각.,,? - //ReviewImage 엔티티에서 가능하니까 거기 메소드를 만들어보쟈 - //reviewImage.changeSubFile(filePath, subFiles); => List으로 만들어 보내야함 - List fileList = saveSubImages(filePath, subFiles); - reviewImage.changeSubFile(filePath, fileList); + review.getFile(); +// ReviewImage reviewImage = review.getReviewImage(); +// +// //메인 파일 이름을 아예 있던거 없애고 바꿔버리기! +// reviewImage.changeMainFile(filePath, createStoreFileName(mainFile.getOriginalFilename()), mainFile); +// +// //서브 파일도 같은 방식으로 +// //비어있는 경우도 생각.,,? +// //ReviewImage 엔티티에서 가능하니까 거기 메소드를 만들어보쟈 +// //reviewImage.changeSubFile(filePath, subFiles); => List으로 만들어 보내야함 +// List fileList = saveSubImages(filePath, subFiles); +// reviewImage.changeSubFile(filePath, fileList); review.update(reviewUpdateRequest); return ReviewResponse.of(review); } - - public static String createStoreFileName(String originalFilename) { - String ext = extractExt(originalFilename); - String uuid = UUID.randomUUID().toString(); - return uuid + "." + ext; - } - - public static String extractExt(String originalFilename) { - int pos = originalFilename.lastIndexOf("."); - return originalFilename.substring(pos + 1); - } - - public static List saveSubImages(String filePath, List subFiles) throws IOException { - - List subFilePaths = new ArrayList<>(); - - for (MultipartFile subFile : subFiles) { - if (subFile.getOriginalFilename() != null) { - String savePath = createStoreFileName(subFile.getOriginalFilename()); - subFilePaths.add(savePath); - subFile.transferTo(new File(filePath + savePath)); - } - } - return subFilePaths; - } - - private String saveMainFile(MultipartFile mainFile) throws IOException{ - String mainFileName = createStoreFileName(mainFile.getOriginalFilename()); - mainFile.transferTo(new File(filePath + mainFileName)); - - return mainFileName; - } - - private void saveSubFiles(List subFiles, ReviewImage reviewImage) throws IOException{ - List subFilePaths = saveSubImages(filePath, subFiles); - reviewImage.saveSubFileNames(subFilePaths); - } - } From eb2eddbac0cf2482a5982b8915b160f1caaba04e Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 1 Jun 2023 17:22:11 +0900 Subject: [PATCH 106/367] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20=EC=A3=BC?= =?UTF-8?q?=EB=AC=B8=EC=8B=9C=20=ED=83=9C=EA=B7=B8=20=EC=A0=90=EC=88=98=20?= =?UTF-8?q?=EC=98=AC=EB=9D=BC=EA=B0=80=EB=8A=94=20=EB=A1=9C=EC=A7=81(#86)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/orders/service/OrderService.java | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 594df606..ee91d427 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -22,6 +22,7 @@ import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.exception.ProductNotFoundException; import project.trendpick_pro.domain.product.repository.ProductRepository; +import project.trendpick_pro.domain.tag.entity.Tag; import java.util.ArrayList; import java.util.List; @@ -49,9 +50,30 @@ public synchronized void order(Long userId, OrderSaveRequest... orderSaveRequest if (product.getStock() < request.getQuantity()) { throw new ProductStockOutException("재고가 부족합니다."); // 임시. 나중에 사용자 exception 널을까말까 생각 } + + List tagList = product.getTags(); + List tags = member.getTags(); + + //주문은 1유형이라고 가정 + for(Tag tagByProduct : tagList){ + boolean hasTag = false; + for(Tag tagByMember : tags){ + if(tagByProduct.getName().equals(tagByMember)){ //기존에 가지고 있던 태그에는 점수 부여 + tagByMember.increaseScore(1); + hasTag = true; + } + } + if(!hasTag) //태그를 가지고 있지 않다면 추가해준다. + tags.add(new Tag(tagByProduct.getName())); + } + orderItemList.add(new OrderItem(product, product.getPrice(), request.getQuantity())); } + + + + Order order = Order.createOrder(member, delivery, OrderStatus.ORDERED, orderItemList); orderRepository.save(order); } From 6af009c65015cfb4cfe4a076f4337447204d2d97 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 1 Jun 2023 17:24:36 +0900 Subject: [PATCH 107/367] =?UTF-8?q?feat:=20=ED=83=9C=EA=B7=B8=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EC=A0=90=EC=88=98=20=EC=98=AC=EB=9D=BC?= =?UTF-8?q?=EA=B0=80=EB=8A=94=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84(#8?= =?UTF-8?q?6)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/orders/service/OrderService.java | 5 ----- .../trendpick_pro/domain/tag/entity/Tag.java | 20 +++++++++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index ee91d427..3103c8ee 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -66,14 +66,9 @@ public synchronized void order(Long userId, OrderSaveRequest... orderSaveRequest if(!hasTag) //태그를 가지고 있지 않다면 추가해준다. tags.add(new Tag(tagByProduct.getName())); } - orderItemList.add(new OrderItem(product, product.getPrice(), request.getQuantity())); } - - - - Order order = Order.createOrder(member, delivery, OrderStatus.ORDERED, orderItemList); orderRepository.save(order); } diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java index b31e2048..909c626c 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java +++ b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java @@ -20,7 +20,27 @@ public Tag(String name) { this.name = name; } + public int score; //선호도 점수 + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "product_id") private Product product; + + public void increaseScore(int type){ + //유형에 따라 가중치 + switch (type){ + case 1 : score += 10; + break; + case 2: score += 7; + break; + case 3: score += 5; + break; + default: score += 1; + break; + } + } + + public void decreaseScore(){ + + } } From edf6895a7271a5b3b64218e9fe6980e834488f3d Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Thu, 1 Jun 2023 17:31:50 +0900 Subject: [PATCH 108/367] =?UTF-8?q?feat:=20product=20=EC=84=A0=ED=83=9D?= =?UTF-8?q?=ED=95=9C=20=ED=83=9C=EA=B7=B8=20=EC=A0=80=EC=9E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/product/entity/Product.java | 4 ++-- .../entity/dto/request/ProductSaveRequest.java | 2 +- .../domain/product/service/ProductService.java | 15 +++++++++++++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index 9aaf75fa..f63f86d1 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -75,7 +75,7 @@ public Product(String name, MainCategory mainCategory, SubCategory subCategory, } public static Product of(ProductSaveRequest request, MainCategory mainCategory - , SubCategory subCategory, Brand brand,CommonFile file) { + , SubCategory subCategory, Brand brand,CommonFile file,List tags) { return Product.builder() .name(request.getName()) .mainCategory(mainCategory) @@ -85,7 +85,7 @@ public static Product of(ProductSaveRequest request, MainCategory mainCategory .file(file) .price(request.getPrice()) .stock(request.getStock()) - .tags(request.getTags()) + .tags(tags) .build(); } diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java index 0a3b5b94..774b68e1 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java @@ -38,6 +38,6 @@ public class ProductSaveRequest { private int stock; @NotBlank(message = "포함될 태그들을 추가해주세요.") - private List tags; + private List tags; } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index de024b4f..c6f1989e 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -1,5 +1,6 @@ package project.trendpick_pro.domain.product.service; + import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -20,6 +21,8 @@ import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; import project.trendpick_pro.domain.product.repository.ProductRepository; +import project.trendpick_pro.domain.tag.entity.Tag; +import project.trendpick_pro.domain.tag.repository.TagRepository; import java.io.IOException; import java.util.ArrayList; @@ -37,21 +40,29 @@ public class ProductService { private final BrandRepository brandRepository; private final FileTranslator fileTranslator; + private final TagRepository tagRepository; + @Transactional public ProductResponse register(ProductSaveRequest productSaveRequest) throws IOException { CommonFile mainFile = fileTranslator.translateFile(productSaveRequest.getMainFile()); List subFiles = fileTranslator.translateFileList(productSaveRequest.getSubFiles()); - for(CommonFile subFile : subFiles){ + for (CommonFile subFile : subFiles) { mainFile.connectFile(subFile); } + List tags = new ArrayList<>(); // 상품에 포함시킬 태크 선택하여 저장 + for (String tag : productSaveRequest.getTags()) { + tags.add(tagRepository.findByName(tag).orElseThrow()); + } + MainCategory mainCategory = mainCategoryRepository.findByName(productSaveRequest.getMainCategory()); SubCategory subCategory = subCategoryRepository.findByName(productSaveRequest.getSubCategory()); Brand brand = brandRepository.findByName(productSaveRequest.getBrand()); - Product product = Product.of(productSaveRequest, mainCategory, subCategory, brand, mainFile); + Product product = Product.of(productSaveRequest, mainCategory, subCategory, brand, mainFile,tags); + productRepository.save(product); return ProductResponse.of(product); } From 6769901a0b0fd0c4010eff8a9be0c992c8faf676 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Thu, 1 Jun 2023 17:33:51 +0900 Subject: [PATCH 109/367] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=EC=8B=9C=EC=97=90=20=EC=84=A0=ED=98=B8=ED=83=9C?= =?UTF-8?q?=EA=B7=B8=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=ED=91=9C=EC=8B=9C=20?= =?UTF-8?q?(#91)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/controller/MemberController.java | 5 ++++- .../tag/entity/dto/response/TagListResponse.java | 10 +++++++++- .../trendpick_pro/domain/tag/service/TagService.java | 6 +++--- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java index 8ee7812a..ef982c5a 100644 --- a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java +++ b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java @@ -15,6 +15,7 @@ import project.trendpick_pro.domain.member.entity.form.JoinForm; import project.trendpick_pro.domain.member.exception.MemberAlreadyExistException; import project.trendpick_pro.domain.member.service.MemberService; +import project.trendpick_pro.domain.tag.service.TagService; @Slf4j @Controller @@ -23,13 +24,15 @@ public class MemberController { private final MemberService memberService; + private final TagService tagService; + private final Rq rq; @PreAuthorize("isAnonymous()") @GetMapping("/register") public String register(JoinForm joinForm, Model model) { model.addAttribute("joinForm", joinForm); -// model.addAttribute(memberService.) + model.addAttribute(tagService.getAllTags()); return "trendpick/usr/member/join"; } diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagListResponse.java b/src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagListResponse.java index 283bb949..4b1908c1 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagListResponse.java +++ b/src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagListResponse.java @@ -1,8 +1,16 @@ package project.trendpick_pro.domain.tag.entity.dto.response; import lombok.Getter; +import project.trendpick_pro.domain.tag.entity.Tag; + +import java.util.List; @Getter public class TagListResponse { -} + private final List tags; + + public TagListResponse(List tags) { + this.tags = tags.stream().map(Tag::getName).toList(); + } +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java b/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java index 70a3a760..9a4f6bdc 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java +++ b/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java @@ -2,6 +2,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import project.trendpick_pro.domain.tag.entity.dto.response.TagListResponse; import project.trendpick_pro.domain.tag.entity.dto.response.TagResponse; import project.trendpick_pro.domain.tag.repository.TagRepository; @@ -13,8 +14,7 @@ public class TagService { private final TagRepository tagRepository; - public List getAllTags() { -// return TagResponse.of(tagRepository.findAll()); - return null; + public TagListResponse getAllTags() { + return new TagListResponse(tagRepository.findAll()); } } From c162288bd63fca5cdafd4f06971b3e4a7c9ea36b Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 1 Jun 2023 18:07:48 +0900 Subject: [PATCH 110/367] =?UTF-8?q?feat:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=20=EB=8B=B4=EC=9C=BC=EB=A9=B4=20=ED=83=9C=EA=B7=B8=20?= =?UTF-8?q?=EC=A0=90=EC=88=98=20=EC=98=AC=EB=9D=BC=EA=B0=80=EB=8A=94=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80(#95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/cart/service/CartService.java | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index fc0e6f5d..cb960e7d 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -9,8 +9,10 @@ import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.repository.MemberRepository; +import project.trendpick_pro.domain.orders.entity.OrderItem; import project.trendpick_pro.domain.product.entity.ProductOption; import project.trendpick_pro.domain.product.repository.ProductOptionRepository; +import project.trendpick_pro.domain.tag.entity.Tag; import java.util.List; @@ -33,12 +35,29 @@ public Cart createCart(Member member) { return cartRepository.save(cart); } + @Transactional public void addItemToCart(Member member, Long productOptionId, int count) { Cart cart = getCartByUser(member); ProductOption productOption = getProductOptionById(productOptionId); CartItem cartItem = cart.findCartItemByProductOption(productOption); + List tagList = productOption.getProduct().getTags(); + List tags = member.getTags(); + + //장바구니는 2유형이라고 가정 + for(Tag tagByProduct : tagList){ + boolean hasTag = false; + for(Tag tagByMember : tags){ + if(tagByProduct.getName().equals(tagByMember)){ //기존에 가지고 있던 태그에는 점수 부여 + tagByMember.increaseScore(2); + hasTag = true; + break; + } + } + if(!hasTag) //태그를 가지고 있지 않다면 추가해준다. + tags.add(new Tag(tagByProduct.getName())); + } if (cartItem != null) { // 이미 카트에 해당 상품이 존재하는 경우, 수량을 증가 From e71fce309d8b2f0fcb2977dca1dfbd8fcbe10af4 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 1 Jun 2023 18:14:10 +0900 Subject: [PATCH 111/367] =?UTF-8?q?feat:=20=EC=A1=B0=ED=9A=8C=EC=8B=9C=20?= =?UTF-8?q?=ED=83=9C=EA=B7=B8=20=EC=A0=90=EC=88=98=20=EC=98=AC=EB=9D=BC?= =?UTF-8?q?=EA=B0=80=EB=8A=94=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80(#9?= =?UTF-8?q?5)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 6 ++++- .../product/service/ProductService.java | 23 +++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 0a77ac68..dbc75d26 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -61,7 +61,11 @@ public String deleteProduct(@PathVariable Long productId) { @GetMapping("/{productId}") public String showProduct(@PathVariable Long productId, Model model) { - model.addAttribute("productResponse", productService.show(productId)); + Member member = null; + if(rq.isLogin()) + member = rq.getMember(); + + model.addAttribute("productResponse", productService.show(member, productId)); return "/trendpick/products/detailpage"; } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index c6f1989e..55525d22 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -15,6 +15,7 @@ import project.trendpick_pro.domain.category.repository.SubCategoryRepository; import project.trendpick_pro.domain.common.base.filetranslator.FileTranslator; import project.trendpick_pro.domain.common.file.CommonFile; +import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; @@ -82,10 +83,28 @@ public void delete(Long productId) { productRepository.delete(product); } - public ProductResponse show(Long product_id) { - + public ProductResponse show(Member member, Long product_id) { Product product = productRepository.findById(product_id).orElseThrow(null);// 임시. 나중에 테스트 + if(member != null){ + List tagList = product.getTags(); + List tags = member.getTags(); + + //일반 조회는 3유형이라고 가정 + for(Tag tagByProduct : tagList){ + boolean hasTag = false; + for(Tag tagByMember : tags){ + if(tagByProduct.getName().equals(tagByMember)){ //기존에 가지고 있던 태그에는 점수 부여 + tagByMember.increaseScore(2); + hasTag = true; + break; + } + } + if(!hasTag) //태그를 가지고 있지 않다면 추가해준다. + tags.add(new Tag(tagByProduct.getName())); + } + } + return ProductResponse.of(product); } From 46dbe25a3c05fb21f3e757f40644cd69dd2a3a61 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 1 Jun 2023 18:29:49 +0900 Subject: [PATCH 112/367] =?UTF-8?q?refactor:=20=ED=83=9C=EA=B7=B8=EC=A0=90?= =?UTF-8?q?=EC=88=98=20=EC=98=AC=EB=A0=A4=EC=A3=BC=EB=8A=94=20=EA=B3=B5?= =?UTF-8?q?=ED=86=B5=EB=A1=9C=EC=A7=81=20TagService=EB=A1=9C=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81(#95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/cart/service/CartService.java | 20 +++----------- .../domain/orders/service/OrderService.java | 18 +++---------- .../product/service/ProductService.java | 20 +++----------- .../trendpick_pro/domain/tag/entity/Tag.java | 4 +-- .../domain/tag/service/TagService.java | 26 ++++++++++++++++++- 5 files changed, 35 insertions(+), 53 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index cb960e7d..07a77d3b 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -13,6 +13,7 @@ import project.trendpick_pro.domain.product.entity.ProductOption; import project.trendpick_pro.domain.product.repository.ProductOptionRepository; import project.trendpick_pro.domain.tag.entity.Tag; +import project.trendpick_pro.domain.tag.service.TagService; import java.util.List; @@ -25,6 +26,7 @@ public class CartService { private final CartRepository cartRepository; private final MemberRepository memberRepository; private final ProductOptionRepository productOptionRepository; + private final TagService tagService; public List findByCartMember(Member member){ return cartRepository.findByCartMember(member); @@ -39,25 +41,9 @@ public Cart createCart(Member member) { public void addItemToCart(Member member, Long productOptionId, int count) { Cart cart = getCartByUser(member); ProductOption productOption = getProductOptionById(productOptionId); - CartItem cartItem = cart.findCartItemByProductOption(productOption); - List tagList = productOption.getProduct().getTags(); - List tags = member.getTags(); - - //장바구니는 2유형이라고 가정 - for(Tag tagByProduct : tagList){ - boolean hasTag = false; - for(Tag tagByMember : tags){ - if(tagByProduct.getName().equals(tagByMember)){ //기존에 가지고 있던 태그에는 점수 부여 - tagByMember.increaseScore(2); - hasTag = true; - break; - } - } - if(!hasTag) //태그를 가지고 있지 않다면 추가해준다. - tags.add(new Tag(tagByProduct.getName())); - } + tagService.updateTag(member, productOption.getProduct(), 2); //장바구니에 넣었으니 해당 상품이 가진 태그점수 올리기 if (cartItem != null) { // 이미 카트에 해당 상품이 존재하는 경우, 수량을 증가 diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 3103c8ee..6621fe79 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -23,6 +23,7 @@ import project.trendpick_pro.domain.product.exception.ProductNotFoundException; import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tag.entity.Tag; +import project.trendpick_pro.domain.tag.service.TagService; import java.util.ArrayList; import java.util.List; @@ -36,6 +37,7 @@ public class OrderService { private final OrderRepository orderRepository; private final MemberRepository memberRepository; private final ProductRepository productRepository; + private final TagService tagService; @Transactional public synchronized void order(Long userId, OrderSaveRequest... orderSaveRequests) { @@ -51,21 +53,7 @@ public synchronized void order(Long userId, OrderSaveRequest... orderSaveRequest throw new ProductStockOutException("재고가 부족합니다."); // 임시. 나중에 사용자 exception 널을까말까 생각 } - List tagList = product.getTags(); - List tags = member.getTags(); - - //주문은 1유형이라고 가정 - for(Tag tagByProduct : tagList){ - boolean hasTag = false; - for(Tag tagByMember : tags){ - if(tagByProduct.getName().equals(tagByMember)){ //기존에 가지고 있던 태그에는 점수 부여 - tagByMember.increaseScore(1); - hasTag = true; - } - } - if(!hasTag) //태그를 가지고 있지 않다면 추가해준다. - tags.add(new Tag(tagByProduct.getName())); - } + tagService.updateTag(member, product, 1); orderItemList.add(new OrderItem(product, product.getPrice(), request.getQuantity())); } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 55525d22..cd43e625 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -24,6 +24,7 @@ import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tag.entity.Tag; import project.trendpick_pro.domain.tag.repository.TagRepository; +import project.trendpick_pro.domain.tag.service.TagService; import java.io.IOException; import java.util.ArrayList; @@ -40,8 +41,8 @@ public class ProductService { private final SubCategoryRepository subCategoryRepository; private final BrandRepository brandRepository; private final FileTranslator fileTranslator; - private final TagRepository tagRepository; + private final TagService tagService; @Transactional public ProductResponse register(ProductSaveRequest productSaveRequest) throws IOException { @@ -87,22 +88,7 @@ public ProductResponse show(Member member, Long product_id) { Product product = productRepository.findById(product_id).orElseThrow(null);// 임시. 나중에 테스트 if(member != null){ - List tagList = product.getTags(); - List tags = member.getTags(); - - //일반 조회는 3유형이라고 가정 - for(Tag tagByProduct : tagList){ - boolean hasTag = false; - for(Tag tagByMember : tags){ - if(tagByProduct.getName().equals(tagByMember)){ //기존에 가지고 있던 태그에는 점수 부여 - tagByMember.increaseScore(2); - hasTag = true; - break; - } - } - if(!hasTag) //태그를 가지고 있지 않다면 추가해준다. - tags.add(new Tag(tagByProduct.getName())); - } + tagService.updateTag(member, product, 3); } return ProductResponse.of(product); diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java index 909c626c..448c2fe0 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java +++ b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java @@ -31,9 +31,7 @@ public void increaseScore(int type){ switch (type){ case 1 : score += 10; break; - case 2: score += 7; - break; - case 3: score += 5; + case 2: score += 5; break; default: score += 1; break; diff --git a/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java b/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java index 9a4f6bdc..cafc9ad0 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java +++ b/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java @@ -2,6 +2,10 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.tag.entity.Tag; import project.trendpick_pro.domain.tag.entity.dto.response.TagListResponse; import project.trendpick_pro.domain.tag.entity.dto.response.TagResponse; import project.trendpick_pro.domain.tag.repository.TagRepository; @@ -10,11 +14,31 @@ @Service @RequiredArgsConstructor +@Transactional(readOnly = true) public class TagService { - private final TagRepository tagRepository; public TagListResponse getAllTags() { return new TagListResponse(tagRepository.findAll()); } + + @Transactional + public void updateTag(Member member, Product product, int type) { + List tagList = product.getTags(); + List tags = member.getTags(); + + //장바구니는 2유형이라고 가정 + for(Tag tagByProduct : tagList){ + boolean hasTag = false; + for(Tag tagByMember : tags){ + if(tagByProduct.getName().equals(tagByMember)){ //기존에 가지고 있던 태그에는 점수 부여 + tagByMember.increaseScore(2); + hasTag = true; + break; + } + } + if(!hasTag) //태그를 가지고 있지 않다면 추가해준다. + tags.add(new Tag(tagByProduct.getName())); + } + } } From ecd8de6899bb0c6dd731cbdb45f06b73e397cc24 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 1 Jun 2023 18:54:17 +0900 Subject: [PATCH 113/367] =?UTF-8?q?refactor:=20TagType=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80=20(#95)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/cart/service/CartService.java | 3 ++- .../domain/orders/service/OrderService.java | 3 ++- .../domain/product/service/ProductService.java | 3 ++- .../trendpick_pro/domain/tag/entity/Tag.java | 7 ++++--- .../domain/tag/entity/type/TagType.java | 13 +++++++++++++ .../domain/tag/service/TagService.java | 5 +++-- 6 files changed, 26 insertions(+), 8 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/tag/entity/type/TagType.java diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index 07a77d3b..3bfccc49 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -13,6 +13,7 @@ import project.trendpick_pro.domain.product.entity.ProductOption; import project.trendpick_pro.domain.product.repository.ProductOptionRepository; import project.trendpick_pro.domain.tag.entity.Tag; +import project.trendpick_pro.domain.tag.entity.type.TagType; import project.trendpick_pro.domain.tag.service.TagService; import java.util.List; @@ -43,7 +44,7 @@ public void addItemToCart(Member member, Long productOptionId, int count) { ProductOption productOption = getProductOptionById(productOptionId); CartItem cartItem = cart.findCartItemByProductOption(productOption); - tagService.updateTag(member, productOption.getProduct(), 2); //장바구니에 넣었으니 해당 상품이 가진 태그점수 올리기 + tagService.updateTag(member, productOption.getProduct(), TagType.CART); //장바구니에 넣었으니 해당 상품이 가진 태그점수 올리기 if (cartItem != null) { // 이미 카트에 해당 상품이 존재하는 경우, 수량을 증가 diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 6621fe79..3a233127 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -23,6 +23,7 @@ import project.trendpick_pro.domain.product.exception.ProductNotFoundException; import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tag.entity.Tag; +import project.trendpick_pro.domain.tag.entity.type.TagType; import project.trendpick_pro.domain.tag.service.TagService; import java.util.ArrayList; @@ -53,7 +54,7 @@ public synchronized void order(Long userId, OrderSaveRequest... orderSaveRequest throw new ProductStockOutException("재고가 부족합니다."); // 임시. 나중에 사용자 exception 널을까말까 생각 } - tagService.updateTag(member, product, 1); + tagService.updateTag(member, product, TagType.ORDER); orderItemList.add(new OrderItem(product, product.getPrice(), request.getQuantity())); } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index cd43e625..b55d1d5a 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -23,6 +23,7 @@ import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tag.entity.Tag; +import project.trendpick_pro.domain.tag.entity.type.TagType; import project.trendpick_pro.domain.tag.repository.TagRepository; import project.trendpick_pro.domain.tag.service.TagService; @@ -88,7 +89,7 @@ public ProductResponse show(Member member, Long product_id) { Product product = productRepository.findById(product_id).orElseThrow(null);// 임시. 나중에 테스트 if(member != null){ - tagService.updateTag(member, product, 3); + tagService.updateTag(member, product, TagType.SHOW); } return ProductResponse.of(product); diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java index 448c2fe0..50f267e2 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java +++ b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java @@ -5,6 +5,7 @@ import lombok.Getter; import lombok.NoArgsConstructor; import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.tag.entity.type.TagType; @Entity @Getter @@ -26,12 +27,12 @@ public Tag(String name) { @JoinColumn(name = "product_id") private Product product; - public void increaseScore(int type){ + public void increaseScore(TagType type){ //유형에 따라 가중치 switch (type){ - case 1 : score += 10; + case ORDER: score += 10; break; - case 2: score += 5; + case CART: score += 5; break; default: score += 1; break; diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/type/TagType.java b/src/main/java/project/trendpick_pro/domain/tag/entity/type/TagType.java new file mode 100644 index 00000000..af6beccf --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/tag/entity/type/TagType.java @@ -0,0 +1,13 @@ +package project.trendpick_pro.domain.tag.entity.type; + +public enum TagType { //타입에 따라 다른 태그점수 향상치 + ORDER("ORDER"), + CART("CART"), + SHOW("SHOW"); + + private String value; + + TagType(String value) { + this.value = value; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java b/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java index cafc9ad0..57a5e97e 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java +++ b/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java @@ -8,6 +8,7 @@ import project.trendpick_pro.domain.tag.entity.Tag; import project.trendpick_pro.domain.tag.entity.dto.response.TagListResponse; import project.trendpick_pro.domain.tag.entity.dto.response.TagResponse; +import project.trendpick_pro.domain.tag.entity.type.TagType; import project.trendpick_pro.domain.tag.repository.TagRepository; import java.util.List; @@ -23,7 +24,7 @@ public TagListResponse getAllTags() { } @Transactional - public void updateTag(Member member, Product product, int type) { + public void updateTag(Member member, Product product, TagType type) { List tagList = product.getTags(); List tags = member.getTags(); @@ -32,7 +33,7 @@ public void updateTag(Member member, Product product, int type) { boolean hasTag = false; for(Tag tagByMember : tags){ if(tagByProduct.getName().equals(tagByMember)){ //기존에 가지고 있던 태그에는 점수 부여 - tagByMember.increaseScore(2); + tagByMember.increaseScore(type); hasTag = true; break; } From cb526f0da6e2c339efef94fa8e2f6f12dcda2db7 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 1 Jun 2023 22:19:45 +0900 Subject: [PATCH 114/367] =?UTF-8?q?feat:=20RecommendProductEx=20=EC=9E=84?= =?UTF-8?q?=EC=8B=9C=EB=A1=9C=20=EC=B6=94=EA=B0=80(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/entity/RecommendProductEx.java | 24 +++++++++++++++++++ .../repository/ProductRepositoryCustom.java | 5 ++++ .../repository/ProductRepositoryImpl.java | 12 ++++++++-- 3 files changed, 39 insertions(+), 2 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/product/entity/RecommendProductEx.java diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/RecommendProductEx.java b/src/main/java/project/trendpick_pro/domain/product/entity/RecommendProductEx.java new file mode 100644 index 00000000..82dcea91 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/entity/RecommendProductEx.java @@ -0,0 +1,24 @@ +package project.trendpick_pro.domain.product.entity; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; + +//임시 +@Entity +@AllArgsConstructor +@NoArgsConstructor +@Getter +public class RecommendProductEx { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @OneToOne + @JoinColumn(name = "product_id") + private Product product; + + private int totalScore; +} diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java index 9fdc3091..5fb82268 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java @@ -2,9 +2,14 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.product.entity.RecommendProductEx; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; +import java.util.List; + public interface ProductRepositoryCustom { public Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable); + public List findAllRecommendProductEx(Member member); } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 87bb82f9..bb767e3e 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -9,6 +9,9 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.support.PageableExecutionUtils; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.product.entity.QRecommendProductEx; +import project.trendpick_pro.domain.product.entity.RecommendProductEx; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse; @@ -54,8 +57,8 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag mainCategoryEq(cond) .and(subCategoryEq(cond)) ) - .offset(0) - .limit(18) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) .orderBy(orderSelector(cond.getSortCode())) //정렬추가 .fetch(); @@ -74,6 +77,11 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag return PageableExecutionUtils.getPage(result, pageable, count::fetchOne); } + @Override + public List findAllRecommendProductEx(Member member) { + + } + private static BooleanExpression mainCategoryEq(ProductSearchCond cond) { return mainCategory.name.eq(cond.getMainCategory()); } From 2bce6c265a030409d14b657fde9325afbc318b8e Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 1 Jun 2023 22:57:17 +0900 Subject: [PATCH 115/367] =?UTF-8?q?refactor:=20tag,=20member=20=EC=97=B0?= =?UTF-8?q?=EA=B4=80=EA=B4=80=EA=B3=84=20=EC=88=98=EC=A0=95=20(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/entity/Member.java | 6 ++--- .../domain/product/entity/Product.java | 1 + .../product/entity/RecommendProductEx.java | 8 ++++-- .../repository/ProductRepositoryImpl.java | 26 +++++++++++++++++-- .../trendpick_pro/domain/tag/entity/Tag.java | 7 ++++- 5 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index ee7079c4..b789542b 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -37,9 +37,9 @@ public class Member { @Enumerated(EnumType.STRING) private RoleType role; - @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) - @JoinColumn(name = "member_id") - private List tags; + @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) + @Builder.Default + private List tags = new ArrayList<>(); private String bankName; private String bankAccount; diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index f63f86d1..6e5dfb8d 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -55,6 +55,7 @@ public class Product extends BaseTimeEntity { private int stock; @OneToMany(mappedBy = "product", cascade = CascadeType.ALL) + @Builder.Default private List tags = new ArrayList<>(); public long reviewCount = 0; diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/RecommendProductEx.java b/src/main/java/project/trendpick_pro/domain/product/entity/RecommendProductEx.java index 82dcea91..798d4ca0 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/RecommendProductEx.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/RecommendProductEx.java @@ -7,8 +7,6 @@ //임시 @Entity -@AllArgsConstructor -@NoArgsConstructor @Getter public class RecommendProductEx { @@ -21,4 +19,10 @@ public class RecommendProductEx { private Product product; private int totalScore; + + public RecommendProductEx(Product product, int totalScore) { + this.product = product; + this.totalScore = totalScore; + + } } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index bb767e3e..1be6070e 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -15,6 +15,7 @@ import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse; +import project.trendpick_pro.domain.tag.entity.QTag; import java.util.List; @@ -23,6 +24,7 @@ import static project.trendpick_pro.domain.category.entity.QSubCategory.*; import static project.trendpick_pro.domain.common.file.QCommonFile.commonFile; import static project.trendpick_pro.domain.product.entity.QProduct.product; +import static project.trendpick_pro.domain.tag.entity.QTag.*; public class ProductRepositoryImpl implements ProductRepositoryCustom { @@ -46,8 +48,8 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag product.name, brand.name, commonFile.translatedFileName, - product.price - )) + product.price) + ) .from(product) .leftJoin(product.mainCategory, mainCategory) .leftJoin(product.subCategory, subCategory) @@ -79,7 +81,27 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag @Override public List findAllRecommendProductEx(Member member) { + List list = queryFactory + .select(Projections.fields(RecommendProductEx.class, + product, + calcTotalScore() + ) + ) + .from(queryFactory. + select( + tag.score, tag.name) + .from(tag) + .leftJoin(tag, ) + + ) + .where() + .fetch(); + + return list; + } + private int calcTotalScore() { + return 0; } private static BooleanExpression mainCategoryEq(ProductSearchCond cond) { diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java index 50f267e2..7473bd25 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java +++ b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java @@ -4,6 +4,7 @@ import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.tag.entity.type.TagType; @@ -21,7 +22,11 @@ public Tag(String name) { this.name = name; } - public int score; //선호도 점수 + private int score; //선호도 점수 + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "product_id") From aaf6de67be08ecaa4c6385ae06c1dc48c0980a73 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 1 Jun 2023 23:39:49 +0900 Subject: [PATCH 116/367] =?UTF-8?q?feat:=20=EC=82=AC=EC=9A=A9=EC=9E=90?= =?UTF-8?q?=EB=B3=84=20=EC=B6=94=EC=B2=9C=EC=83=81=ED=92=88=20=EA=B0=80?= =?UTF-8?q?=EC=A0=B8=EC=98=A4=EB=8A=94=20=EB=A1=9C=EC=A7=81=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84=20(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/product/entity/Product.java | 1 - .../product/entity/RecommendProductEx.java | 8 ++--- .../repository/ProductRepositoryImpl.java | 31 +++++++++---------- 3 files changed, 19 insertions(+), 21 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index 6e5dfb8d..f63f86d1 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -55,7 +55,6 @@ public class Product extends BaseTimeEntity { private int stock; @OneToMany(mappedBy = "product", cascade = CascadeType.ALL) - @Builder.Default private List tags = new ArrayList<>(); public long reviewCount = 0; diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/RecommendProductEx.java b/src/main/java/project/trendpick_pro/domain/product/entity/RecommendProductEx.java index 798d4ca0..75e8708c 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/RecommendProductEx.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/RecommendProductEx.java @@ -1,13 +1,13 @@ package project.trendpick_pro.domain.product.entity; import jakarta.persistence.*; -import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; //임시 @Entity @Getter +@NoArgsConstructor public class RecommendProductEx { @Id @@ -20,9 +20,9 @@ public class RecommendProductEx { private int totalScore; - public RecommendProductEx(Product product, int totalScore) { + public RecommendProductEx(Product product) { this.product = product; - this.totalScore = totalScore; - } + + } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 1be6070e..8f2ca55c 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -3,6 +3,7 @@ import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; @@ -10,12 +11,11 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.support.PageableExecutionUtils; import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.product.entity.QRecommendProductEx; +import project.trendpick_pro.domain.member.entity.QMember; import project.trendpick_pro.domain.product.entity.RecommendProductEx; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse; -import project.trendpick_pro.domain.tag.entity.QTag; import java.util.List; @@ -23,8 +23,9 @@ import static project.trendpick_pro.domain.category.entity.QMainCategory.*; import static project.trendpick_pro.domain.category.entity.QSubCategory.*; import static project.trendpick_pro.domain.common.file.QCommonFile.commonFile; +import static project.trendpick_pro.domain.member.entity.QMember.*; import static project.trendpick_pro.domain.product.entity.QProduct.product; -import static project.trendpick_pro.domain.tag.entity.QTag.*; +import static project.trendpick_pro.domain.tag.entity.QTag.tag; public class ProductRepositoryImpl implements ProductRepositoryCustom { @@ -81,28 +82,26 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag @Override public List findAllRecommendProductEx(Member member) { - List list = queryFactory + List list = + queryFactory .select(Projections.fields(RecommendProductEx.class, - product, - calcTotalScore() + product ) ) - .from(queryFactory. - select( - tag.score, tag.name) - .from(tag) - .leftJoin(tag, ) - + .distinct() + .from(product) + .where(product.id.in( + JPAExpressions + .select(tag.product.id) + .from(tag) + .where(tag.member.id.eq(member.getId())) + ) ) - .where() .fetch(); return list; } - private int calcTotalScore() { - return 0; - } private static BooleanExpression mainCategoryEq(ProductSearchCond cond) { return mainCategory.name.eq(cond.getMainCategory()); From b2983f7b53ca4fad529607f2b2c923613fff7b46 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 1 Jun 2023 23:43:53 +0900 Subject: [PATCH 117/367] =?UTF-8?q?refactor:=20RecommendProductExResponse?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80=20(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../response/RecommendProductExResponse.java | 18 ++++++++++++++++++ .../repository/ProductRepositoryCustom.java | 3 ++- .../repository/ProductRepositoryImpl.java | 7 ++++--- 3 files changed, 24 insertions(+), 4 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java new file mode 100644 index 00000000..12dc3e54 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java @@ -0,0 +1,18 @@ +package project.trendpick_pro.domain.product.entity.dto.response; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.product.entity.Product; + +@Getter +@AllArgsConstructor +@NoArgsConstructor +public class RecommendProductExResponse { + + private Product productId; + + private int totalScore; + +} diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java index 5fb82268..78e9fcae 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java @@ -6,10 +6,11 @@ import project.trendpick_pro.domain.product.entity.RecommendProductEx; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; +import project.trendpick_pro.domain.product.entity.dto.response.RecommendProductExResponse; import java.util.List; public interface ProductRepositoryCustom { public Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable); - public List findAllRecommendProductEx(Member member); + public List findAllRecommendProductEx(Member member); } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 8f2ca55c..4d1128cf 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -16,6 +16,7 @@ import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse; +import project.trendpick_pro.domain.product.entity.dto.response.RecommendProductExResponse; import java.util.List; @@ -81,10 +82,10 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag } @Override - public List findAllRecommendProductEx(Member member) { - List list = + public List findAllRecommendProductEx(Member member) { + List list = queryFactory - .select(Projections.fields(RecommendProductEx.class, + .select(Projections.fields(RecommendProductExResponse.class, product ) ) From 00b41e85221aa9ba51d6f8aea68bd74681e3a29d Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Fri, 2 Jun 2023 01:09:43 +0900 Subject: [PATCH 118/367] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=EB=93=B1?= =?UTF-8?q?=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 2 +- .../domain/product/entity/Product.java | 6 ++-- .../product/service/ProductService.java | 28 ++++++++++++++++++- 3 files changed, 32 insertions(+), 4 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index dbc75d26..9099a60d 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -39,7 +39,7 @@ public String registerProduct(@Valid ProductSaveRequest productSaveRequest, Mode @PreAuthorize("isAuthenticated()") @PostMapping("/edit/{productId}") - public String modifyProduct(@PathVariable Long productId, @Valid ProductSaveRequest productSaveRequest, Model model) { + public String modifyProduct(@PathVariable Long productId, @Valid ProductSaveRequest productSaveRequest, Model model) throws IOException { if(!rq.getMember().getRole().equals(RoleType.BRAND_ADMIN)) //추가로 해당 상품 브랜드 관리자인지도 체크 throw new RuntimeException("상품 수정 권한이 없습니다."); diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index f63f86d1..1ef3820f 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -109,8 +109,10 @@ public void addReview(int rating){ } public void update(ProductSaveRequest request) { - - // 여기서 파일 지지고 볶고 할 예정 + this.name=request.getName(); + this.description=request.getDescription(); + this.price=request.getPrice(); + this.stock=request.getStock(); } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index b55d1d5a..85c01154 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -1,6 +1,7 @@ package project.trendpick_pro.domain.product.service; +import com.querydsl.core.util.FileUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -27,6 +28,7 @@ import project.trendpick_pro.domain.tag.repository.TagRepository; import project.trendpick_pro.domain.tag.service.TagService; +import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; @@ -71,9 +73,33 @@ public ProductResponse register(ProductSaveRequest productSaveRequest) throws IO } @Transactional - public ProductResponse modify(Long productId, ProductSaveRequest productSaveRequest) { + public ProductResponse modify(Long productId, ProductSaveRequest productSaveRequest) throws IOException { Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 + CommonFile mainFile=product.getFile(); + List subFiles=product.getFile().getChild(); + + if(productSaveRequest.getMainFile()!=null){ + // 기존 이미지 삭제 + if(mainFile!=null){ + FileUtils.delete(new File(mainFile.getTranslatedFileName())); + } + } + // 이미지 업데이트 + mainFile = fileTranslator.translateFile(productSaveRequest.getMainFile()); + + if(productSaveRequest.getSubFiles()!=null ){ + // 기존 이미지 삭제 + for(CommonFile subFile:subFiles){ + FileUtils.delete(new File(subFile.getTranslatedFileName())); + } + } + // 이미지 업데이트 + subFiles=fileTranslator.translateFileList(productSaveRequest.getSubFiles()); + + for (CommonFile subFile : subFiles) { + mainFile.connectFile(subFile); + } product.update(productSaveRequest); return ProductResponse.of(product); From 11f4aad18d52b6550642febb901bd716f3054b88 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 2 Jun 2023 01:50:10 +0900 Subject: [PATCH 119/367] =?UTF-8?q?fix:=20RecommendProductExResponse?= =?UTF-8?q?=EB=A5=BC=20querydsl=EC=9D=B4=20=EC=9D=B8=EC=8B=9D=ED=95=98?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EA=B0=9C=EC=84=A0(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/RecommendProductExResponse.java | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java index 12dc3e54..099ac24d 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java @@ -1,18 +1,23 @@ package project.trendpick_pro.domain.product.entity.dto.response; -import jakarta.persistence.*; +import com.querydsl.core.annotations.QueryProjection; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; -import project.trendpick_pro.domain.product.entity.Product; @Getter @AllArgsConstructor @NoArgsConstructor public class RecommendProductExResponse { - private Product productId; + private Long productId; private int totalScore; + @QueryProjection + public RecommendProductExResponse(Long productId){ + this.productId = productId; + totalScore = 0; + } + } From 01b2bc67359092cdade34048f3df8509914b55aa Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 2 Jun 2023 01:54:13 +0900 Subject: [PATCH 120/367] =?UTF-8?q?refactor:=20querydsl=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81=20(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/ProductRepositoryImpl.java | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 4d1128cf..1f49c54f 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -16,6 +16,7 @@ import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse; +import project.trendpick_pro.domain.product.entity.dto.response.QRecommendProductExResponse; import project.trendpick_pro.domain.product.entity.dto.response.RecommendProductExResponse; import java.util.List; @@ -81,23 +82,18 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag return PageableExecutionUtils.getPage(result, pageable, count::fetchOne); } + // select distinct T.product_id from tag T + // where T.member_id = 1; @Override public List findAllRecommendProductEx(Member member) { - List list = - queryFactory - .select(Projections.fields(RecommendProductExResponse.class, - product - ) - ) - .distinct() - .from(product) - .where(product.id.in( - JPAExpressions - .select(tag.product.id) - .from(tag) - .where(tag.member.id.eq(member.getId())) + List list = queryFactory + .select(new QRecommendProductExResponse( + tag.product.id ) ) + .from(tag) + .where(tag.member.id.eq(member.getId())) + .distinct() .fetch(); return list; From 72e314ed28453f6abd78f95bbad940aa6a43ea9b Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 2 Jun 2023 11:29:39 +0900 Subject: [PATCH 121/367] =?UTF-8?q?test:=20findAllRecommendProductEx=20?= =?UTF-8?q?=ED=85=8C=EC=8A=A4=ED=8A=B8=20=ED=99=98=EA=B2=BD(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../response/RecommendProductExResponse.java | 8 +++++++- .../product/service/ProductService.java | 20 +++++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java index 099ac24d..f00ef35e 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java @@ -11,13 +11,19 @@ public class RecommendProductExResponse { private Long productId; + private String tagName; private int totalScore; @QueryProjection - public RecommendProductExResponse(Long productId){ + public RecommendProductExResponse(Long productId, String tagName){ this.productId = productId; + this.tagName = tagName; totalScore = 0; } + public void plusTotalScore(int score){ + this.totalScore += score; + } + } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index b55d1d5a..65f74060 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -21,6 +21,7 @@ import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; +import project.trendpick_pro.domain.product.entity.dto.response.RecommendProductExResponse; import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tag.entity.Tag; import project.trendpick_pro.domain.tag.entity.type.TagType; @@ -105,4 +106,23 @@ public Page showAll(int offset, String mainCategory, String return productRepository.findAllByCategoryId(cond, pageable); } +// @Transactional +// public List extractRecommendProductExResponse(Member member){ +// List recommendProductExList = productRepository.findAllRecommendProductEx(member); +// +// List memberTags = member.getTags(); +// +// //회원의 선호태그가 하나라도 속한 상품 모두 뽑아와서 점수 부여 +// for (RecommendProductExResponse response : recommendProductExList) { +// for(Tag tag : memberTags){ +// if(tag.getName().equals(response.getTagName())){ +// response.plusTotalScore(tag.getScore()); +// } +// } +// } +// return recommendProductExList; +// } + + + } From 530d44196b4ae8f2691710d89be88c6573f7c57d Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 2 Jun 2023 14:38:05 +0900 Subject: [PATCH 122/367] =?UTF-8?q?refactor:=20=EC=B6=94=EC=B2=9C=EC=83=81?= =?UTF-8?q?=ED=92=88=20=EB=B0=98=ED=99=98=20=EC=84=B1=EA=B3=B5(=EC=A4=91?= =?UTF-8?q?=EB=B3=B5)=20(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/entity/Member.java | 8 +- .../product/controller/ProductController.java | 14 +++ .../domain/product/entity/Product.java | 14 +-- .../repository/ProductRepositoryCustom.java | 2 + .../repository/ProductRepositoryImpl.java | 79 +++++++++++++--- .../trendpick_pro/domain/tag/entity/Tag.java | 18 +++- .../global/basedata/BaseData.java | 91 ++++++++++++++++++- 7 files changed, 192 insertions(+), 34 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index b789542b..a636c819 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -22,16 +22,16 @@ public class Member { @Column(name = "member_id") private Long id; - @Column(name = "email",unique = true, nullable = false) + @Column(name = "email",unique = true) private String email; - @Column(name = "password", nullable = false) + @Column(name = "password") private String password; - @Column(name = "username", nullable = false) + @Column(name = "username") private String username; - @Column(name = "phone_number", nullable = false) + @Column(name = "phone_number") private String phoneNumber; @Enumerated(EnumType.STRING) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index dbc75d26..861e26cf 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -10,11 +10,16 @@ import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.RoleType; +import project.trendpick_pro.domain.member.repository.MemberRepository; +import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; +import project.trendpick_pro.domain.product.entity.dto.response.RecommendProductExResponse; +import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.product.service.ProductService; import java.io.IOException; +import java.util.List; @Slf4j @Controller @@ -22,6 +27,8 @@ @RequestMapping("trendpick/products") public class ProductController { + private final MemberRepository memberRepository; + private final ProductRepository productRepository; private final Rq rq; private final ProductService productService; @@ -78,4 +85,11 @@ public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") i model.addAttribute("productResponse", productService.showAll(offset, mainCategory, subCategory, sortCode)); return "/trendpick/products/detailpage"; } + + @GetMapping("/test") + @ResponseBody + public List test(){ + return productRepository.findAllRecommendProductEx(memberRepository.findById(1L).get() + ); + } } diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index f63f86d1..fd702064 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -25,33 +25,33 @@ public class Product extends BaseTimeEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(name = "name", nullable = false) + @Column(name = "name") private String name; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "main_category_id", nullable = false) + @JoinColumn(name = "main_category_id") private MainCategory mainCategory; // Category @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "sub_category_id", nullable = false) + @JoinColumn(name = "sub_category_id") private SubCategory subCategory; // Category @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "brand_id", nullable = false) + @JoinColumn(name = "brand_id") private Brand brand; - @Column(name = "description", nullable = false) + @Column(name = "description") private String description; @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "file_id") private CommonFile file; - @Column(name = "price", nullable = false) + @Column(name = "price") private int price; - @Column(name = "stock", nullable = false) + @Column(name = "stock") private int stock; @OneToMany(mappedBy = "product", cascade = CascadeType.ALL) diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java index 78e9fcae..88b0fcbd 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java @@ -3,6 +3,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.RecommendProductEx; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; @@ -13,4 +14,5 @@ public interface ProductRepositoryCustom { public Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable); public List findAllRecommendProductEx(Member member); + public List findByTag(String username); } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 1f49c54f..00c06c6f 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -3,6 +3,7 @@ import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.core.types.dsl.NumberExpression; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; @@ -12,12 +13,15 @@ import org.springframework.data.support.PageableExecutionUtils; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.QMember; -import project.trendpick_pro.domain.product.entity.RecommendProductEx; +import project.trendpick_pro.domain.member.repository.MemberRepository; +import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.product.entity.QProduct; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.QRecommendProductExResponse; import project.trendpick_pro.domain.product.entity.dto.response.RecommendProductExResponse; +import project.trendpick_pro.domain.tag.entity.QTag; import java.util.List; @@ -26,26 +30,20 @@ import static project.trendpick_pro.domain.category.entity.QSubCategory.*; import static project.trendpick_pro.domain.common.file.QCommonFile.commonFile; import static project.trendpick_pro.domain.member.entity.QMember.*; -import static project.trendpick_pro.domain.product.entity.QProduct.product; -import static project.trendpick_pro.domain.tag.entity.QTag.tag; +import static project.trendpick_pro.domain.product.entity.QProduct.*; +import static project.trendpick_pro.domain.tag.entity.QTag.*; public class ProductRepositoryImpl implements ProductRepositoryCustom { private final JPAQueryFactory queryFactory; - public ProductRepositoryImpl(EntityManager em) { + public ProductRepositoryImpl(EntityManager em, MemberRepository memberRepository) { this.queryFactory = new JPAQueryFactory(em); } @Override public Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable) { List result = queryFactory -// .select(Projections.constructor(ProductListResponse.class, -// product.id, -// product.name, -// brand.name, -// product.file.translatedFileName, -// product.price)) .select(new QProductListResponse( product.id, product.name, @@ -82,17 +80,68 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag return PageableExecutionUtils.getPage(result, pageable, count::fetchOne); } - // select distinct T.product_id from tag T - // where T.member_id = 1; + // select distinct T.product_id from tag T +// where T.member_id = 1; +// @Override +// public List findAllRecommendProductEx(Member member) { +// +// List list = queryFactory +// .select(new QRecommendProductExResponse( +// tag.product.id, +// tag.name +// ) +// ) +// .from(tag) +// .where(tag.member.id.eq(member.getId())) +// .fetch(); +// +// return list; +// } + + @Override + public List findByTag(String username) { + + Member findMember = queryFactory + .selectFrom(member) + .where(member.username.eq(username)) + .fetchOne(); + + NumberExpression sum = tag.score.sum(); + + assert findMember != null; + return queryFactory + .selectFrom(product) + .leftJoin(product.tags, tag) + .where(tag.in(findMember.getTags())) + .groupBy(product) + .orderBy(sum.desc()) + .fetch(); + } + +// select T_P.product_id +// from Tag T_P +// where T_P.name in( +// select T_M.name +// from Tag T_M +// where T_M.member_id = 1 +// ) @Override public List findAllRecommendProductEx(Member member) { + QTag tagByMember = new QTag("tagByMember"); + QTag tagByProduct = new QTag("tagByProduct"); + List list = queryFactory .select(new QRecommendProductExResponse( - tag.product.id + tagByProduct.product.id, + tagByProduct.name ) ) - .from(tag) - .where(tag.member.id.eq(member.getId())) + .from(tagByProduct) + .where(tagByProduct.name.in( + JPAExpressions.select(tagByMember.name) + .from(tagByMember) + .where(tagByMember.member.id.eq(member.getId())) + )) .distinct() .fetch(); diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java index 7473bd25..a9faab06 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java +++ b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java @@ -1,16 +1,18 @@ package project.trendpick_pro.domain.tag.entity; import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.tag.entity.type.TagType; @Entity @Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) +//@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Setter public class Tag { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -21,6 +23,14 @@ public class Tag { public Tag(String name) { this.name = name; } + public Tag(String name, Product product) { + this.name = name; + this.product = product; + } + public Tag(String name, Member member) { + this.name = name; + this.member = member; + } private int score; //선호도 점수 diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index d8c337e5..8f509ef8 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -6,10 +6,15 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.member.service.MemberService; +import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tag.entity.Tag; import project.trendpick_pro.domain.tag.repository.TagRepository; +import java.util.ArrayList; import java.util.List; @Configuration @@ -21,15 +26,93 @@ public class BaseData { @Bean CommandLineRunner initData( - TagRepository tagRepository + TagRepository tagRepository, + ProductRepository productRepository, + MemberRepository memberRepository ) { return new CommandLineRunner() { @Override @Transactional public void run(String... args) { - for (String tag : tags) { - tagRepository.save(new Tag(tag)); - } +// for (String tag : tags) { +// tagRepository.save(new Tag(tag)); +// } + + //member1은 태그1, 태그2, 태그3 을 각각 10점 5점 1점 가지고 있다 + //상품1은 태그1을 가지고 있다 + //상품2는 태그1, 태그2를 가지고 있다 + //상품3은 태그1, 태그2 태그3 모두 가지고 있다. + //상품4는 아무것도 가지고 있지 않다. + + Member member1 = memberRepository.save(Member.builder().username("member1").build()); + Product product1 = Product.builder().name("상품1").build(); + Product product2 = Product.builder().name("상품2").build(); + Product product3 = Product.builder().name("상품3").build(); + Product product4 = Product.builder().name("상품4").build(); + productRepository.save(product1); + productRepository.save(product2); + productRepository.save(product3); + productRepository.save(product4); + + + Tag tag1 = new Tag("태그1", member1); + tag1.setScore(10); + tagRepository.save(tag1); + Tag tag2 = new Tag("태그2", member1); + tag2.setScore(5); + tagRepository.save(tag2); + Tag tag3 = new Tag("태그3", member1); + tag3.setScore(1); + tagRepository.save(tag3); + + //상품1은 태그1을 가지고 있다 + Tag tag1ByProduct1 = new Tag("태그1", product1); + tagRepository.save(tag1ByProduct1); + + //상품2는 태그1, 태그2를 가지고 있다 + Tag tag2ByProduct1 = new Tag("태그1", product2); + Tag tag2ByProduct2 = new Tag("태그2", product2); + tagRepository.save(tag2ByProduct1); + tagRepository.save(tag2ByProduct2); + + //상품3은 태그1, 태그2 태그3 모두 가지고 있다. + Tag tag3ByProduct1 = new Tag("태그1", product3); + Tag tag3ByProduct2 = new Tag("태그2", product3); + Tag tag3ByProduct3 = new Tag("태그3", product3); + tagRepository.save(tag3ByProduct1); + tagRepository.save(tag3ByProduct2); + tagRepository.save(tag3ByProduct3); + + +// List tags1 = new ArrayList<>(); +// for(int i=0; i<10; i++){ +// Tag tag = new Tag("태그" + i, member1); +// tag.setScore(10); +// tagRepository.save(tag); +// tags1.add(tag); +// } +// List tags2 = new ArrayList<>(); +// for(int i=10; i<20; i++){ +// Tag tag = new Tag("태그" + i, member2); +// tag.setScore(10); +// tagRepository.save(tag); +// tags2.add(tag); +// } +// +// List tags3 = new ArrayList<>(); +// for(int i=1; i<5; i++){ +// Tag tag = new Tag("태그" + i, product1); +// tagRepository.save(tag); +// tags3.add(tag); +// } +// List tags4 = new ArrayList<>(); +// for(int i=5; i<10; i++){ +// Tag tag = new Tag("태그" + i, product1); +// tagRepository.save(tag); +// tags3.add(tag); +// } + + } }; } From b8ca91d6977293e52fa1956a2370e9f6270d7482 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 2 Jun 2023 14:46:35 +0900 Subject: [PATCH 123/367] =?UTF-8?q?refactor:=20=EC=B6=94=EC=B2=9C=EC=83=81?= =?UTF-8?q?=ED=92=88=20=EB=B0=98=ED=99=98=20=EA=B8=B0=EB=8A=A5=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81=20(null=EA=B0=92=20=EC=A0=9C?= =?UTF-8?q?=EA=B1=B0)=20(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/product/repository/ProductRepositoryImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 00c06c6f..73babb7b 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -141,7 +141,8 @@ public List findAllRecommendProductEx(Member member) JPAExpressions.select(tagByMember.name) .from(tagByMember) .where(tagByMember.member.id.eq(member.getId())) - )) + ) + .and(tagByProduct.product.id.isNotNull())) .distinct() .fetch(); From 5170a65b52525f9a677feeca0fb9b13b3db827ce Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Fri, 2 Jun 2023 15:40:31 +0900 Subject: [PATCH 124/367] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=EC=97=90=20commonfile=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 14 +++++-------- .../domain/review/entity/Review.java | 21 +++++-------------- ...ateRequest.java => ReviewSaveRequest.java} | 2 +- .../dto/request/ReviewUpdateRequest.java | 17 --------------- .../domain/review/service/ReviewService.java | 21 +++++++------------ 5 files changed, 18 insertions(+), 57 deletions(-) rename src/main/java/project/trendpick_pro/domain/review/entity/dto/request/{ReviewCreateRequest.java => ReviewSaveRequest.java} (94%) delete mode 100644 src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewUpdateRequest.java diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index 06dfdb4d..a4e05e59 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -1,21 +1,17 @@ package project.trendpick_pro.domain.review.controller; import jakarta.validation.Valid; -import jakarta.validation.constraints.NotBlank; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; -import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.review.entity.dto.request.ReviewCreateRequest; -import project.trendpick_pro.domain.review.entity.dto.request.ReviewUpdateRequest; +import project.trendpick_pro.domain.review.entity.dto.request.ReviewSaveRequest; import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; import project.trendpick_pro.domain.review.service.ReviewService; import java.io.IOException; -import java.util.List; @Controller @RequiredArgsConstructor @@ -25,8 +21,8 @@ public class ReviewController { private final Rq rq; @PostMapping("/write") - public String createReview(@Valid ReviewCreateRequest reviewCreateRequest, @RequestParam(value = "product") Long productId, - Model model) throws Exception { + public String createReview(@Valid ReviewSaveRequest reviewCreateRequest, @RequestParam(value = "product") Long productId, + Model model) throws Exception { Member actor = rq.getMember(); ReviewResponse reviewResponse = reviewService.createReview(actor, productId, reviewCreateRequest); @@ -50,9 +46,9 @@ public String deleteReview(@PathVariable Long reviewId) { } @PostMapping("/edit/{reviewId}") - public String updateReview(@PathVariable Long reviewId, ReviewUpdateRequest reviewUpdateRequest, + public String updateReview(@PathVariable Long reviewId, ReviewSaveRequest reviewSaveRequest, Model model) throws IOException { - ReviewResponse reviewResponse = reviewService.update(reviewId, reviewUpdateRequest); + ReviewResponse reviewResponse = reviewService.update(reviewId, reviewSaveRequest); model.addAttribute("reviewResponse", reviewResponse); return "redirect:/trendpick/review"; diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java index fa62e667..f1b85573 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -5,20 +5,11 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.common.base.BaseTimeEntity; import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; -import project.trendpick_pro.domain.review.entity.dto.request.ReviewCreateRequest; -import project.trendpick_pro.domain.review.entity.dto.request.ReviewUpdateRequest; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; -import java.util.UUID; +import project.trendpick_pro.domain.review.entity.dto.request.ReviewSaveRequest; @Entity @NoArgsConstructor @@ -56,7 +47,7 @@ public Review(Member member, Product product, CommonFile file, String title, Str this.rating = rating; } - public static Review of(ReviewCreateRequest reviewCreateRequest, Member member, Product product, CommonFile file) { + public static Review of(ReviewSaveRequest reviewCreateRequest, Member member, Product product, CommonFile file) { return Review.builder() .writer(member.getUsername()) .product(product) @@ -66,13 +57,11 @@ public static Review of(ReviewCreateRequest reviewCreateRequest, Member member, .build(); } - public void update(ReviewUpdateRequest reviewUpdateRequest){ - this.title = reviewUpdateRequest.getTitle(); - this.content = reviewUpdateRequest.getContent(); - //this.commonFile = reviewUpdateRequest.getMainFile(); - this.rating = reviewUpdateRequest.getRating(); + public void update(ReviewSaveRequest reviewSaveRequest) { + } + // public void changeMainFile(String filePath, String mainFilePath, MultipartFile mainFile) throws IOException { // File file = new File(filePath + mainFileName); // file.delete(); //원래 있던거 삭제 diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewCreateRequest.java b/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewSaveRequest.java similarity index 94% rename from src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewCreateRequest.java rename to src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewSaveRequest.java index 4b568fdc..c496dbcd 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewCreateRequest.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewSaveRequest.java @@ -8,7 +8,7 @@ import java.util.List; @Data -public class ReviewCreateRequest { +public class ReviewSaveRequest { @NotBlank(message = "제목을 입력해주세요") private String title; @NotBlank(message = "내용을 입력해주세요") diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewUpdateRequest.java b/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewUpdateRequest.java deleted file mode 100644 index 642435c0..00000000 --- a/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewUpdateRequest.java +++ /dev/null @@ -1,17 +0,0 @@ -package project.trendpick_pro.domain.review.entity.dto.request; - -import jakarta.validation.constraints.NotBlank; -import lombok.Data; -import org.springframework.web.multipart.MultipartFile; - -import java.util.List; - -@Data -public class ReviewUpdateRequest { - private String title; - private String content; - private MultipartFile mainFile; - private List subFiles; - private int rating; - -} diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index f178fd00..eed3d8bb 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -1,28 +1,22 @@ package project.trendpick_pro.domain.review.service; -import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.common.base.filetranslator.FileTranslator; import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.review.entity.Review; -import project.trendpick_pro.domain.review.entity.dto.request.ReviewCreateRequest; -import project.trendpick_pro.domain.review.entity.dto.request.ReviewUpdateRequest; +import project.trendpick_pro.domain.review.entity.dto.request.ReviewSaveRequest; import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; import project.trendpick_pro.domain.review.repository.ReviewImageRepository; import project.trendpick_pro.domain.review.repository.ReviewRepository; -import java.io.File; import java.io.IOException; -import java.util.ArrayList; import java.util.List; -import java.util.UUID; @Service @@ -52,26 +46,25 @@ public void delete(Long reviewId) { reviewRepository.delete(review); } - public ReviewResponse createReview(Member actor, Long productId, ReviewCreateRequest reviewCreateRequest) throws Exception { + public ReviewResponse createReview(Member actor, Long productId, ReviewSaveRequest reviewSaveRequest) throws Exception { Product product = productRepository.findById(productId).orElseThrow(); - CommonFile mainFile = fileTranslator.translateFile(reviewCreateRequest.getMainFile()); - List subFiles = fileTranslator.translateFileList(reviewCreateRequest.getSubFiles()); + CommonFile mainFile = fileTranslator.translateFile(reviewSaveRequest.getMainFile()); + List subFiles = fileTranslator.translateFileList(reviewSaveRequest.getSubFiles()); for(CommonFile subFile : subFiles){ mainFile.connectFile(subFile); } - Review review = Review.of(reviewCreateRequest, actor, product, mainFile); + Review review = Review.of(reviewSaveRequest, actor, product, mainFile); product.addReview(review.getRating()); //상품 리뷰수, 상품 평균 평점을 계산해서 저장 reviewRepository.save(review); return ReviewResponse.of(review); } - public ReviewResponse update(Long reviewId, ReviewUpdateRequest reviewUpdateRequest) throws IOException { + public ReviewResponse update(Long reviewId, ReviewSaveRequest reviewSaveRequest) throws IOException { Review review = reviewRepository.findById(reviewId).orElseThrow(); - review.getFile(); // ReviewImage reviewImage = review.getReviewImage(); // // //메인 파일 이름을 아예 있던거 없애고 바꿔버리기! @@ -84,7 +77,7 @@ public ReviewResponse update(Long reviewId, ReviewUpdateRequest reviewUpdateRequ // List fileList = saveSubImages(filePath, subFiles); // reviewImage.changeSubFile(filePath, fileList); - review.update(reviewUpdateRequest); + review.update(reviewSaveRequest); return ReviewResponse.of(review); } } From f1be1b0e419a88eb1c011dc37ea1cff2523d342f Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 2 Jun 2023 16:03:40 +0900 Subject: [PATCH 125/367] =?UTF-8?q?fix:=20=EC=B6=94=EC=B2=9C=EC=83=81?= =?UTF-8?q?=ED=92=88=20=EB=B0=98=ED=99=98=20=EB=A1=9C=EC=A7=81=20=EC=B4=9D?= =?UTF-8?q?=EC=A0=90=EC=88=98=20=EA=B0=B1=EC=8B=A0=EC=9D=B4=20=EC=95=88?= =?UTF-8?q?=EB=90=98=EB=8A=94=EA=B1=B0=20=EC=88=98=EC=A0=95=20(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 4 +- .../product/service/ProductService.java | 62 ++++++++++++++----- .../domain/product/ProductServiceTest.java | 4 ++ 3 files changed, 51 insertions(+), 19 deletions(-) create mode 100644 src/test/java/project/trendpick_pro/domain/product/ProductServiceTest.java diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 861e26cf..786d110c 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -28,7 +28,6 @@ public class ProductController { private final MemberRepository memberRepository; - private final ProductRepository productRepository; private final Rq rq; private final ProductService productService; @@ -89,7 +88,6 @@ public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") i @GetMapping("/test") @ResponseBody public List test(){ - return productRepository.findAllRecommendProductEx(memberRepository.findById(1L).get() - ); + return productService.extractRecommendProductExResponse(memberRepository.findById(1L).get()); } } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 65f74060..a75220f9 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -3,6 +3,7 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.slf4j.LoggerFactory; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; @@ -30,13 +31,17 @@ import java.io.IOException; import java.util.ArrayList; +import java.util.HashMap; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; @Slf4j @Service @Transactional(readOnly = true) @RequiredArgsConstructor public class ProductService { + private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ProductService.class); private final ProductRepository productRepository; private final MainCategoryRepository mainCategoryRepository; @@ -106,22 +111,47 @@ public Page showAll(int offset, String mainCategory, String return productRepository.findAllByCategoryId(cond, pageable); } -// @Transactional -// public List extractRecommendProductExResponse(Member member){ -// List recommendProductExList = productRepository.findAllRecommendProductEx(member); -// -// List memberTags = member.getTags(); -// -// //회원의 선호태그가 하나라도 속한 상품 모두 뽑아와서 점수 부여 -// for (RecommendProductExResponse response : recommendProductExList) { -// for(Tag tag : memberTags){ -// if(tag.getName().equals(response.getTagName())){ -// response.plusTotalScore(tag.getScore()); -// } -// } -// } -// return recommendProductExList; -// } + @Transactional + public List extractRecommendProductExResponse(Member member){ + List recommendProductExList = productRepository.findAllRecommendProductEx(member); + List memberTags = member.getTags(); + + + //일단 추천상품으로 뽑힌것들 중복제거 (한 상품이 여러 태그에 포함되있을 수 있다.) + Map> map = new HashMap<>(); + Map map2 = new HashMap<>(); + + for (RecommendProductExResponse response : recommendProductExList) { + logger.info(response.getTagName()); + if(!map.containsKey(response.getTagName())) + map.put(response.getTagName(), new ArrayList()); + + map.get(response.getTagName()).add(response.getProductId()); + } + + for (RecommendProductExResponse response : recommendProductExList) { + if(map2.containsKey(response.getProductId())) + continue; + + map2.put(response.getProductId(), response); + } + logger.info("점수 상승============================================================="); + for (Tag memberTag : memberTags) { + if(map.containsKey(memberTag.getName())){ + List productIdList = map.get(memberTag.getName()); + for (Long id : productIdList) { + logger.info("---------------------------------------"); + logger.info(String.valueOf(map2.get(id).getTotalScore())); + map2.get(id).plusTotalScore(memberTag.getScore()); + logger.info(String.valueOf(map2.get(id).getTotalScore())); + logger.info("---------------------------------------"); + } + } + } + logger.info("점수 상승============================================================="); + + return new ArrayList(map2.values()); + } diff --git a/src/test/java/project/trendpick_pro/domain/product/ProductServiceTest.java b/src/test/java/project/trendpick_pro/domain/product/ProductServiceTest.java new file mode 100644 index 00000000..f9ccbd91 --- /dev/null +++ b/src/test/java/project/trendpick_pro/domain/product/ProductServiceTest.java @@ -0,0 +1,4 @@ +package project.trendpick_pro.domain.product; + +public class ProductServiceTest { +} From ec2843cf30df32a55dbcf27dd0c71cbd3f980f4d Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Fri, 2 Jun 2023 16:32:51 +0900 Subject: [PATCH 126/367] =?UTF-8?q?feat:=20=EB=A7=8C=EB=93=A4=EC=96=B4?= =?UTF-8?q?=EC=A7=84=20=EC=B6=94=EC=B2=9C=20=EC=83=81=ED=92=88=EB=93=A4?= =?UTF-8?q?=EC=9D=84=20=EB=B3=B4=EC=97=AC=EC=A3=BC=EB=8A=94=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=20=EB=A1=9C=EC=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/RecommendController.java | 26 +++++++ .../domain/recommend/entity/Recommend.java | 65 ++++++++++++++++++ .../entity/dto/RecommendResponse.java | 23 +++++++ .../repository/RecommendRepository.java | 7 ++ .../repository/RecommendRepositoryCustom.java | 9 +++ .../repository/RecommendRepositoryImpl.java | 67 +++++++++++++++++++ .../recommend/service/RecommendService.java | 54 +++++++++++++++ 7 files changed, 251 insertions(+) create mode 100644 src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java create mode 100644 src/main/java/project/trendpick_pro/domain/recommend/entity/Recommend.java create mode 100644 src/main/java/project/trendpick_pro/domain/recommend/entity/dto/RecommendResponse.java create mode 100644 src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepository.java create mode 100644 src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryCustom.java create mode 100644 src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryImpl.java create mode 100644 src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java diff --git a/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java b/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java new file mode 100644 index 00000000..e51c7a86 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java @@ -0,0 +1,26 @@ +package project.trendpick_pro.domain.recommend.controller; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; +import project.trendpick_pro.domain.recommend.entity.Recommend; +import project.trendpick_pro.domain.recommend.service.RecommendService; + +@Controller +@RequiredArgsConstructor +public class RecommendController { + private final RecommendService recommendService; + + @GetMapping("/adming/getrecommendset") + public String getRecommend(Model model, @RequestParam("page") int offset){ + model.addAttribute("recommend", recommendService.getFindAll(offset)); + return "/main"; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/recommend/entity/Recommend.java b/src/main/java/project/trendpick_pro/domain/recommend/entity/Recommend.java new file mode 100644 index 00000000..7156f0aa --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/recommend/entity/Recommend.java @@ -0,0 +1,65 @@ +package project.trendpick_pro.domain.recommend.entity; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.brand.entity.Brand; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.product.entity.Product; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class Recommend { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @Column(name = "name", nullable = false) + private String name; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "brand_id") + private Brand brand; + + @Column(name = "main_file", nullable = false) + private String mainFile; + + @Column(name = "price", nullable = false) + private int price; + + @OneToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "product_id") + private Product product; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + + @Builder + public Recommend(String name, Brand brand, String mainFile, int price) { + this.name = name; + this.brand = brand; + this.mainFile = mainFile; + this.price = price; + } + + public void connectProduct(Product product) { + this.product = product; + } + + public void connectMember(Member member) { + this.member = member; + } + + public static Recommend of(Product product) { + return Recommend.builder() + .name(product.getName()) + .brand(product.getBrand()) + .mainFile(product.getFile().getTranslatedFileName()) + .price(product.getPrice()) + .build(); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/recommend/entity/dto/RecommendResponse.java b/src/main/java/project/trendpick_pro/domain/recommend/entity/dto/RecommendResponse.java new file mode 100644 index 00000000..9af84362 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/recommend/entity/dto/RecommendResponse.java @@ -0,0 +1,23 @@ +package project.trendpick_pro.domain.recommend.entity.dto; + +import com.querydsl.core.annotations.QueryProjection; +import lombok.Builder; +import project.trendpick_pro.domain.recommend.entity.Recommend; + +public record RecommendResponse(Long id, String name, String brand, String mainFile, int price) { + + @Builder + @QueryProjection + public RecommendResponse { + } + + public static RecommendResponse of(Recommend recommend) { + return RecommendResponse.builder() + .id(recommend.getProduct().getId()) + .name(recommend.getName()) + .brand(recommend.getBrand().getName()) + .mainFile(recommend.getMainFile()) + .price(recommend.getPrice()) + .build(); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepository.java b/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepository.java new file mode 100644 index 00000000..4da5d8bb --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepository.java @@ -0,0 +1,7 @@ +package project.trendpick_pro.domain.recommend.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.recommend.entity.Recommend; + +public interface RecommendRepository extends JpaRepository, RecommendRepositoryCustom { +} diff --git a/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryCustom.java new file mode 100644 index 00000000..d17a8405 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryCustom.java @@ -0,0 +1,9 @@ +package project.trendpick_pro.domain.recommend.repository; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import project.trendpick_pro.domain.recommend.entity.dto.RecommendResponse; + +public interface RecommendRepositoryCustom { + Page findAllByMemberName(String username, Pageable pageable); +} diff --git a/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryImpl.java new file mode 100644 index 00000000..aa944698 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryImpl.java @@ -0,0 +1,67 @@ +package project.trendpick_pro.domain.recommend.repository; + +import com.querydsl.core.QueryFactory; +import com.querydsl.jpa.impl.JPAQuery; +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.support.PageableExecutionUtils; +import project.trendpick_pro.domain.brand.entity.QBrand; +import project.trendpick_pro.domain.common.file.QCommonFile; +import project.trendpick_pro.domain.member.entity.QMember; +import project.trendpick_pro.domain.product.entity.QProduct; +import project.trendpick_pro.domain.recommend.entity.QRecommend; +import project.trendpick_pro.domain.recommend.entity.Recommend; +import project.trendpick_pro.domain.recommend.entity.dto.QRecommendResponse; +import project.trendpick_pro.domain.recommend.entity.dto.RecommendResponse; + +import java.util.List; + +import static project.trendpick_pro.domain.brand.entity.QBrand.*; +import static project.trendpick_pro.domain.common.file.QCommonFile.*; +import static project.trendpick_pro.domain.member.entity.QMember.*; +import static project.trendpick_pro.domain.product.entity.QProduct.*; +import static project.trendpick_pro.domain.recommend.entity.QRecommend.*; + +public class RecommendRepositoryImpl implements RecommendRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + public RecommendRepositoryImpl(EntityManager em) { + this.queryFactory = new JPAQueryFactory(em); + } + + @Override + public Page findAllByMemberName(String username, Pageable pageable) { + + List result = queryFactory + .select(new QRecommendResponse( + product.id, + product.name, + brand.name, + commonFile.translatedFileName, + product.price + )) + .from(recommend) + .leftJoin(recommend.member, member) + .leftJoin(recommend.product, product) + .leftJoin(recommend.brand, brand) + .leftJoin(recommend.product.file, commonFile) + .where(recommend.member.username.eq(username)) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + + JPAQuery count = queryFactory + .select(recommend.count()) + .from(recommend) + .leftJoin(recommend.member, member) + .leftJoin(recommend.product, product) + .leftJoin(recommend.brand, brand) + .leftJoin(recommend.product.file, commonFile) + .where(recommend.member.username.eq(username)); + + return PageableExecutionUtils.getPage(result, pageable, count::fetchOne); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java new file mode 100644 index 00000000..8fba4b40 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java @@ -0,0 +1,54 @@ +package project.trendpick_pro.domain.recommend.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.common.base.rq.Rq; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.exception.MemberNotFoundException; +import project.trendpick_pro.domain.member.repository.MemberRepository; +import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.product.repository.ProductRepository; +import project.trendpick_pro.domain.recommend.entity.Recommend; +import project.trendpick_pro.domain.recommend.entity.dto.RecommendResponse; +import project.trendpick_pro.domain.recommend.repository.RecommendRepository; + +import java.util.List; + +@Service +@Transactional(readOnly = true) +@RequiredArgsConstructor +public class RecommendService { + private final ProductRepository productRepository; + private final RecommendRepository recommendRepository; + + private final MemberRepository memberRepository; + private final Rq rq; + //recommend -> 태그 기반 추천 상품들이 있어야 함 + + @Transactional + @Scheduled(cron = "* * * 4 * *") //새벽 4시에 한 번씩 작동 + public void select(){ + String username = SecurityContextHolder.getContext().getAuthentication().getName(); + Member member = memberRepository.findByUsername(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); + recommendRepository.deleteAll(); + + List products = productRepository.findByTag(username); + for (Product product : products) { + Recommend recommend = Recommend.of(product); + recommend.connectProduct(product); + recommend.connectMember(member); + recommendRepository.save(recommend); + } + } + + public Page getFindAll(int offset){ + String username = SecurityContextHolder.getContext().getAuthentication().getName(); + PageRequest pageable = PageRequest.of(offset, 18); + return recommendRepository.findAllByMemberName(username, pageable); + } +} From 44a28e1dbfadf11034289286b6170174d24129fb Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 2 Jun 2023 16:42:49 +0900 Subject: [PATCH 127/367] =?UTF-8?q?refactor:=20=EC=B6=94=EC=B2=9C=EC=83=81?= =?UTF-8?q?=ED=92=88=20=EC=B4=9D=EC=A0=90=EC=88=98=20=EB=B6=80=EC=97=AC=20?= =?UTF-8?q?=EC=95=8C=EA=B3=A0=EB=A6=AC=EC=A6=98=20=EC=A3=BC=EC=84=9D?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20=EB=B3=80=EC=88=98=EB=AA=85=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD=20(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../TrendPickProApplication.java | 2 + .../response/RecommendProductExResponse.java | 2 +- .../product/service/ProductService.java | 40 ++++++++----------- .../global/basedata/BaseData.java | 1 - 4 files changed, 20 insertions(+), 25 deletions(-) diff --git a/src/main/java/project/trendpick_pro/TrendPickProApplication.java b/src/main/java/project/trendpick_pro/TrendPickProApplication.java index 2f16c1ba..b5d315a3 100644 --- a/src/main/java/project/trendpick_pro/TrendPickProApplication.java +++ b/src/main/java/project/trendpick_pro/TrendPickProApplication.java @@ -3,9 +3,11 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; +import org.springframework.scheduling.annotation.EnableScheduling; @EnableJpaAuditing @SpringBootApplication +@EnableScheduling public class TrendPickProApplication { public static void main(String[] args) { diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java index f00ef35e..0ee5f42b 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java @@ -18,7 +18,7 @@ public class RecommendProductExResponse { @QueryProjection public RecommendProductExResponse(Long productId, String tagName){ this.productId = productId; - this.tagName = tagName; + this.tagName = tagName; //리턴할때는 불필요한 데이터 totalScore = 0; } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index a75220f9..5b9ec203 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -34,7 +34,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.stream.Collectors; @Slf4j @Service @@ -117,42 +116,37 @@ public List extractRecommendProductExResponse(Member List memberTags = member.getTags(); - //일단 추천상품으로 뽑힌것들 중복제거 (한 상품이 여러 태그에 포함되있을 수 있다.) - Map> map = new HashMap<>(); - Map map2 = new HashMap<>(); + //태그명에 따라 가지고 있는 product_id + // : 멤버 태그명에 따라 해당 상품에 점수를 부여해야 하기 때문에 + Map> productIdListByTagName = new HashMap<>(); + + //상품 id 중복을 없애기 위함 + //맴버의 태그명과 여러개가 겹쳐서 여러개의 추천상품이 반환되었을것 그 중복을 없애야 한다. + Map recommendProductByProductId = new HashMap<>(); for (RecommendProductExResponse response : recommendProductExList) { - logger.info(response.getTagName()); - if(!map.containsKey(response.getTagName())) - map.put(response.getTagName(), new ArrayList()); + if(!productIdListByTagName.containsKey(response.getTagName())) + productIdListByTagName.put(response.getTagName(), new ArrayList()); - map.get(response.getTagName()).add(response.getProductId()); + productIdListByTagName.get(response.getTagName()).add(response.getProductId()); } for (RecommendProductExResponse response : recommendProductExList) { - if(map2.containsKey(response.getProductId())) + if(recommendProductByProductId.containsKey(response.getProductId())) continue; - map2.put(response.getProductId(), response); + recommendProductByProductId.put(response.getProductId(), response); } - logger.info("점수 상승============================================================="); + for (Tag memberTag : memberTags) { - if(map.containsKey(memberTag.getName())){ - List productIdList = map.get(memberTag.getName()); + if(productIdListByTagName.containsKey(memberTag.getName())){ + List productIdList = productIdListByTagName.get(memberTag.getName()); for (Long id : productIdList) { - logger.info("---------------------------------------"); - logger.info(String.valueOf(map2.get(id).getTotalScore())); - map2.get(id).plusTotalScore(memberTag.getScore()); - logger.info(String.valueOf(map2.get(id).getTotalScore())); - logger.info("---------------------------------------"); + recommendProductByProductId.get(id).plusTotalScore(memberTag.getScore()); } } } - logger.info("점수 상승============================================================="); - return new ArrayList(map2.values()); + return new ArrayList(recommendProductByProductId.values()); } - - - } diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index 8f509ef8..d7c0d5b5 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -42,7 +42,6 @@ public void run(String... args) { //상품1은 태그1을 가지고 있다 //상품2는 태그1, 태그2를 가지고 있다 //상품3은 태그1, 태그2 태그3 모두 가지고 있다. - //상품4는 아무것도 가지고 있지 않다. Member member1 = memberRepository.save(Member.builder().username("member1").build()); Product product1 = Product.builder().name("상품1").build(); From 4bdb15cbf4a65c9ca1f114353603e7971ad85356 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 2 Jun 2023 16:47:59 +0900 Subject: [PATCH 128/367] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=EC=BD=94=EB=93=9C=20=EC=A0=95?= =?UTF-8?q?=EB=A6=AC=20(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/ProductRepositoryCustom.java | 1 - .../repository/ProductRepositoryImpl.java | 46 ------------------- .../domain/product/ProductServiceTest.java | 4 -- 3 files changed, 51 deletions(-) delete mode 100644 src/test/java/project/trendpick_pro/domain/product/ProductServiceTest.java diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java index 88b0fcbd..c4abd16f 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java @@ -14,5 +14,4 @@ public interface ProductRepositoryCustom { public Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable); public List findAllRecommendProductEx(Member member); - public List findByTag(String username); } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 73babb7b..eb5fc3b2 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -80,51 +80,6 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag return PageableExecutionUtils.getPage(result, pageable, count::fetchOne); } - // select distinct T.product_id from tag T -// where T.member_id = 1; -// @Override -// public List findAllRecommendProductEx(Member member) { -// -// List list = queryFactory -// .select(new QRecommendProductExResponse( -// tag.product.id, -// tag.name -// ) -// ) -// .from(tag) -// .where(tag.member.id.eq(member.getId())) -// .fetch(); -// -// return list; -// } - - @Override - public List findByTag(String username) { - - Member findMember = queryFactory - .selectFrom(member) - .where(member.username.eq(username)) - .fetchOne(); - - NumberExpression sum = tag.score.sum(); - - assert findMember != null; - return queryFactory - .selectFrom(product) - .leftJoin(product.tags, tag) - .where(tag.in(findMember.getTags())) - .groupBy(product) - .orderBy(sum.desc()) - .fetch(); - } - -// select T_P.product_id -// from Tag T_P -// where T_P.name in( -// select T_M.name -// from Tag T_M -// where T_M.member_id = 1 -// ) @Override public List findAllRecommendProductEx(Member member) { QTag tagByMember = new QTag("tagByMember"); @@ -149,7 +104,6 @@ public List findAllRecommendProductEx(Member member) return list; } - private static BooleanExpression mainCategoryEq(ProductSearchCond cond) { return mainCategory.name.eq(cond.getMainCategory()); } diff --git a/src/test/java/project/trendpick_pro/domain/product/ProductServiceTest.java b/src/test/java/project/trendpick_pro/domain/product/ProductServiceTest.java deleted file mode 100644 index f9ccbd91..00000000 --- a/src/test/java/project/trendpick_pro/domain/product/ProductServiceTest.java +++ /dev/null @@ -1,4 +0,0 @@ -package project.trendpick_pro.domain.product; - -public class ProductServiceTest { -} From b5f335619896f31e68b6961e8834512f052f6ca1 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 2 Jun 2023 17:20:15 +0900 Subject: [PATCH 129/367] =?UTF-8?q?refactor:=20recommend=20=EB=8F=84?= =?UTF-8?q?=EB=A9=94=EC=9D=B8=EC=97=90=EC=84=9C=20=EB=B0=94=EB=A1=9C=20?= =?UTF-8?q?=EC=82=AC=EC=9A=A9=ED=95=A0=20=EC=88=98=20=EC=9E=88=EA=B2=8C?= =?UTF-8?q?=EB=81=94=20=EB=B3=91=ED=95=A9=20=EC=9E=91=EC=97=85=20(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 14 ++++------ .../product/entity/RecommendProductEx.java | 28 ------------------- ...esponse.java => ProductByRecommended.java} | 4 +-- .../repository/ProductRepositoryCustom.java | 6 ++-- .../repository/ProductRepositoryImpl.java | 20 ++++--------- .../product/service/ProductService.java | 12 ++++---- .../recommend/service/RecommendService.java | 15 ++++++++-- 7 files changed, 35 insertions(+), 64 deletions(-) delete mode 100644 src/main/java/project/trendpick_pro/domain/product/entity/RecommendProductEx.java rename src/main/java/project/trendpick_pro/domain/product/entity/dto/response/{RecommendProductExResponse.java => ProductByRecommended.java} (83%) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 484e7971..76845644 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -11,11 +11,9 @@ import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.RoleType; import project.trendpick_pro.domain.member.repository.MemberRepository; -import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; -import project.trendpick_pro.domain.product.entity.dto.response.RecommendProductExResponse; -import project.trendpick_pro.domain.product.repository.ProductRepository; +import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.product.service.ProductService; import java.io.IOException; @@ -85,9 +83,9 @@ public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") i return "/trendpick/products/detailpage"; } - @GetMapping("/test") - @ResponseBody - public List test(){ - return productService.extractRecommendProductExResponse(memberRepository.findById(1L).get()); - } +// @GetMapping("/test") +// @ResponseBody +// public List test(){ +// return productService.extractRecommendProductExResponse(memberRepository.findById(1L).get()); +// } } diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/RecommendProductEx.java b/src/main/java/project/trendpick_pro/domain/product/entity/RecommendProductEx.java deleted file mode 100644 index 75e8708c..00000000 --- a/src/main/java/project/trendpick_pro/domain/product/entity/RecommendProductEx.java +++ /dev/null @@ -1,28 +0,0 @@ -package project.trendpick_pro.domain.product.entity; - -import jakarta.persistence.*; -import lombok.Getter; -import lombok.NoArgsConstructor; - -//임시 -@Entity -@Getter -@NoArgsConstructor -public class RecommendProductEx { - - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - private Long id; - - @OneToOne - @JoinColumn(name = "product_id") - private Product product; - - private int totalScore; - - public RecommendProductEx(Product product) { - this.product = product; - } - - -} diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductByRecommended.java similarity index 83% rename from src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java rename to src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductByRecommended.java index 0ee5f42b..61b4338f 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/RecommendProductExResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductByRecommended.java @@ -8,7 +8,7 @@ @Getter @AllArgsConstructor @NoArgsConstructor -public class RecommendProductExResponse { +public class ProductByRecommended { private Long productId; private String tagName; @@ -16,7 +16,7 @@ public class RecommendProductExResponse { private int totalScore; @QueryProjection - public RecommendProductExResponse(Long productId, String tagName){ + public ProductByRecommended(Long productId, String tagName){ this.productId = productId; this.tagName = tagName; //리턴할때는 불필요한 데이터 totalScore = 0; diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java index c4abd16f..7985fcb9 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java @@ -3,15 +3,13 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.product.entity.Product; -import project.trendpick_pro.domain.product.entity.RecommendProductEx; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; +import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; -import project.trendpick_pro.domain.product.entity.dto.response.RecommendProductExResponse; import java.util.List; public interface ProductRepositoryCustom { public Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable); - public List findAllRecommendProductEx(Member member); + public List findProductByRecommended(Member member); } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index eb5fc3b2..7648ff41 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -1,9 +1,7 @@ package project.trendpick_pro.domain.product.repository; import com.querydsl.core.types.OrderSpecifier; -import com.querydsl.core.types.Projections; import com.querydsl.core.types.dsl.BooleanExpression; -import com.querydsl.core.types.dsl.NumberExpression; import com.querydsl.jpa.JPAExpressions; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; @@ -12,15 +10,11 @@ import org.springframework.data.domain.Pageable; import org.springframework.data.support.PageableExecutionUtils; import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.member.entity.QMember; -import project.trendpick_pro.domain.member.repository.MemberRepository; -import project.trendpick_pro.domain.product.entity.Product; -import project.trendpick_pro.domain.product.entity.QProduct; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; +import project.trendpick_pro.domain.product.entity.dto.response.QProductByRecommended; import project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse; -import project.trendpick_pro.domain.product.entity.dto.response.QRecommendProductExResponse; -import project.trendpick_pro.domain.product.entity.dto.response.RecommendProductExResponse; +import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.tag.entity.QTag; import java.util.List; @@ -29,15 +23,13 @@ import static project.trendpick_pro.domain.category.entity.QMainCategory.*; import static project.trendpick_pro.domain.category.entity.QSubCategory.*; import static project.trendpick_pro.domain.common.file.QCommonFile.commonFile; -import static project.trendpick_pro.domain.member.entity.QMember.*; import static project.trendpick_pro.domain.product.entity.QProduct.*; -import static project.trendpick_pro.domain.tag.entity.QTag.*; public class ProductRepositoryImpl implements ProductRepositoryCustom { private final JPAQueryFactory queryFactory; - public ProductRepositoryImpl(EntityManager em, MemberRepository memberRepository) { + public ProductRepositoryImpl(EntityManager em) { this.queryFactory = new JPAQueryFactory(em); } @@ -81,12 +73,12 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag } @Override - public List findAllRecommendProductEx(Member member) { + public List findProductByRecommended(Member member) { QTag tagByMember = new QTag("tagByMember"); QTag tagByProduct = new QTag("tagByProduct"); - List list = queryFactory - .select(new QRecommendProductExResponse( + List list = queryFactory + .select(new QProductByRecommended( tagByProduct.product.id, tagByProduct.name ) diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index bd15916c..f12da00d 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -21,9 +21,9 @@ import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; +import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; -import project.trendpick_pro.domain.product.entity.dto.response.RecommendProductExResponse; import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tag.entity.Tag; import project.trendpick_pro.domain.tag.entity.type.TagType; @@ -137,8 +137,8 @@ public Page showAll(int offset, String mainCategory, String } @Transactional - public List extractRecommendProductExResponse(Member member){ - List recommendProductExList = productRepository.findAllRecommendProductEx(member); + public List getRecommendProduct(Member member){ + List productByRecommendedList = productRepository.findProductByRecommended(member); List memberTags = member.getTags(); @@ -148,16 +148,16 @@ public List extractRecommendProductExResponse(Member //상품 id 중복을 없애기 위함 //맴버의 태그명과 여러개가 겹쳐서 여러개의 추천상품이 반환되었을것 그 중복을 없애야 한다. - Map recommendProductByProductId = new HashMap<>(); + Map recommendProductByProductId = new HashMap<>(); - for (RecommendProductExResponse response : recommendProductExList) { + for (ProductByRecommended response : productByRecommendedList) { if(!productIdListByTagName.containsKey(response.getTagName())) productIdListByTagName.put(response.getTagName(), new ArrayList()); productIdListByTagName.get(response.getTagName()).add(response.getProductId()); } - for (RecommendProductExResponse response : recommendProductExList) { + for (ProductByRecommended response : productByRecommendedList) { if(recommendProductByProductId.containsKey(response.getProductId())) continue; diff --git a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java index 8fba4b40..301623c6 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java @@ -12,11 +12,15 @@ import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; +import project.trendpick_pro.domain.product.exception.ProductNotFoundException; import project.trendpick_pro.domain.product.repository.ProductRepository; +import project.trendpick_pro.domain.product.service.ProductService; import project.trendpick_pro.domain.recommend.entity.Recommend; import project.trendpick_pro.domain.recommend.entity.dto.RecommendResponse; import project.trendpick_pro.domain.recommend.repository.RecommendRepository; +import java.util.ArrayList; import java.util.List; @Service @@ -25,7 +29,7 @@ public class RecommendService { private final ProductRepository productRepository; private final RecommendRepository recommendRepository; - + private final ProductService productService; private final MemberRepository memberRepository; private final Rq rq; //recommend -> 태그 기반 추천 상품들이 있어야 함 @@ -37,7 +41,14 @@ public void select(){ Member member = memberRepository.findByUsername(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); recommendRepository.deleteAll(); - List products = productRepository.findByTag(username); + //추천상품 ID값을 가지고 있는 ProductByRecommended 가져오기 (전달용) + List recommendProductList = productService.getRecommendProduct(member); + List products = new ArrayList<>(); + for (ProductByRecommended productByRecommended : recommendProductList) { + Product product = productRepository.findById(productByRecommended.getProductId()).orElseThrow(() -> new ProductNotFoundException("존재하지 않는 상품입니다.")); + products.add(product); + } + for (Product product : products) { Recommend recommend = Recommend.of(product); recommend.connectProduct(product); From 5739d6adaf16b3afd7348ee64a684b323d3066a1 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 2 Jun 2023 17:44:23 +0900 Subject: [PATCH 130/367] =?UTF-8?q?faet:=20=EC=B6=94=EC=B2=9C=EC=83=81?= =?UTF-8?q?=ED=92=88=20=EC=95=8C=EA=B3=A0=EB=A6=AC=EC=A6=98=EC=97=90=20?= =?UTF-8?q?=EC=A0=95=EB=A0=AC=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?(#98)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 10 +++++----- .../domain/product/service/ProductService.java | 13 ++++++++----- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 76845644..8de8f79e 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -83,9 +83,9 @@ public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") i return "/trendpick/products/detailpage"; } -// @GetMapping("/test") -// @ResponseBody -// public List test(){ -// return productService.extractRecommendProductExResponse(memberRepository.findById(1L).get()); -// } + @GetMapping("/test") + @ResponseBody + public List test(){ + return productService.getRecommendProduct(memberRepository.findById(1L).get()); + } } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index f12da00d..cb678039 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -32,10 +32,7 @@ import java.io.File; import java.io.IOException; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; @Slf4j @Service @@ -173,6 +170,12 @@ public List getRecommendProduct(Member member){ } } - return new ArrayList(recommendProductByProductId.values()); + List list = new ArrayList(recommendProductByProductId.values()); + + list = list.stream() + .sorted(Comparator.comparing(ProductByRecommended :: getTotalScore).reversed()) + .toList(); + + return list; } } From adee37450487eb84f94d6784a12e4dcc90ade7c3 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sat, 3 Jun 2023 22:10:04 +0900 Subject: [PATCH 131/367] =?UTF-8?q?Refactor:=20=EC=B6=94=EC=B2=9C=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=AF=B8=EC=99=84=EC=84=B1=20(#104)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 1 + .../trendpick_pro/domain/FavoriteTag.java | 57 +++++++ .../brand/entity/dto/BrandResponse.java | 10 ++ .../brand/repository/BrandRepository.java | 6 +- .../domain/brand/service/BrandService.java | 33 ++++ .../domain/category/entity/MainCategory.java | 5 +- .../dto/request/CategorySaveRequest.java | 19 +++ .../dto/response/MainCategoryResponse.java | 10 ++ .../dto/response/SubCategoryResponse.java | 10 ++ .../repository/MainCategoryRepository.java | 7 +- .../category/service/MainCategoryService.java | 43 +++++ .../category/service/SubCategoryService.java | 46 ++++++ .../repository/FavoriteTagRepository.java | 7 + .../member/controller/MemberController.java | 12 +- .../domain/member/entity/Member.java | 5 +- .../domain/member/entity/form/JoinForm.java | 6 +- .../exception/MemberNotMatchException.java | 1 + .../domain/member/service/MemberService.java | 36 ++-- .../product/controller/ProductController.java | 81 +++++---- .../domain/product/entity/Product.java | 18 +- .../dto/request/ProductSaveRequest.java | 61 +++---- .../dto/response/ProductListResponse.java | 3 +- .../repository/ProductRepositoryCustom.java | 5 +- .../repository/ProductRepositoryImpl.java | 61 ++++--- .../product/service/ProductService.java | 155 +++++++++++------- .../controller/RecommendController.java | 8 +- .../entity/dto/RecommendResponse.java | 23 --- .../repository/RecommendRepository.java | 3 + .../repository/RecommendRepositoryCustom.java | 4 +- .../repository/RecommendRepositoryImpl.java | 19 +-- .../recommend/service/RecommendService.java | 41 +++-- .../trendpick_pro/domain/tag/entity/Tag.java | 35 +--- .../domain/tag/service/TagService.java | 18 +- .../global/basedata/BaseData.java | 146 ++++++++--------- .../exception/GlobalExceptionAdvice.java | 34 ++-- .../global/security/SecurityConfig.java | 2 +- src/main/resources/application-data.yml | 15 ++ src/main/resources/application-tag.yml | 15 -- src/main/resources/application.yml | 2 +- .../templates/trendpick/products/list.html | 27 ++- .../templates/trendpick/usr/member/join.html | 27 ++- 41 files changed, 712 insertions(+), 405 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/FavoriteTag.java create mode 100644 src/main/java/project/trendpick_pro/domain/brand/entity/dto/BrandResponse.java create mode 100644 src/main/java/project/trendpick_pro/domain/brand/service/BrandService.java create mode 100644 src/main/java/project/trendpick_pro/domain/category/entity/dto/request/CategorySaveRequest.java create mode 100644 src/main/java/project/trendpick_pro/domain/category/entity/dto/response/MainCategoryResponse.java create mode 100644 src/main/java/project/trendpick_pro/domain/category/entity/dto/response/SubCategoryResponse.java create mode 100644 src/main/java/project/trendpick_pro/domain/category/service/MainCategoryService.java create mode 100644 src/main/java/project/trendpick_pro/domain/category/service/SubCategoryService.java create mode 100644 src/main/java/project/trendpick_pro/domain/favoritetag/repository/FavoriteTagRepository.java delete mode 100644 src/main/java/project/trendpick_pro/domain/recommend/entity/dto/RecommendResponse.java create mode 100644 src/main/resources/application-data.yml delete mode 100644 src/main/resources/application-tag.yml diff --git a/build.gradle b/build.gradle index 20e166b7..2d1df15d 100644 --- a/build.gradle +++ b/build.gradle @@ -25,6 +25,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-validation' implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.jetbrains:annotations:24.0.0' developmentOnly 'org.springframework.boot:spring-boot-devtools' // log diff --git a/src/main/java/project/trendpick_pro/domain/FavoriteTag.java b/src/main/java/project/trendpick_pro/domain/FavoriteTag.java new file mode 100644 index 00000000..b64f57be --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/FavoriteTag.java @@ -0,0 +1,57 @@ +package project.trendpick_pro.domain; + +import jakarta.persistence.*; +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.tag.entity.Tag; +import project.trendpick_pro.domain.tag.entity.type.TagType; + +@Entity +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class FavoriteTag { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String name; + + private int score = 0; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "member_id") + private Member member; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "tag_id") + private Tag tag; + + public FavoriteTag(Tag tag, String name) { + this.tag = tag; + this.name = name; + } + + public void connectMember(Member member) { + this.member = member; + } + + public void increaseScore(TagType type){ + //유형에 따라 가중치 + switch (type) { + case ORDER -> score += 10; + case CART -> score += 5; + default -> score += 1; + } + } + + public void decreaseScore(TagType type){ + //유형에 따라 가중치 + switch (type) { + case ORDER -> score -= 10; + case CART -> score -= 5; + default -> score -= 1; + } + } +} diff --git a/src/main/java/project/trendpick_pro/domain/brand/entity/dto/BrandResponse.java b/src/main/java/project/trendpick_pro/domain/brand/entity/dto/BrandResponse.java new file mode 100644 index 00000000..918a7e26 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/brand/entity/dto/BrandResponse.java @@ -0,0 +1,10 @@ +package project.trendpick_pro.domain.brand.entity.dto; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class BrandResponse { + private String name; +} diff --git a/src/main/java/project/trendpick_pro/domain/brand/repository/BrandRepository.java b/src/main/java/project/trendpick_pro/domain/brand/repository/BrandRepository.java index 04df6f74..32485d8c 100644 --- a/src/main/java/project/trendpick_pro/domain/brand/repository/BrandRepository.java +++ b/src/main/java/project/trendpick_pro/domain/brand/repository/BrandRepository.java @@ -2,7 +2,11 @@ import org.springframework.data.jpa.repository.JpaRepository; import project.trendpick_pro.domain.brand.entity.Brand; +import project.trendpick_pro.domain.brand.entity.dto.BrandResponse; public interface BrandRepository extends JpaRepository { - public Brand findByName(String name); + Brand findByName(String name); + + List findAllBy(); + } diff --git a/src/main/java/project/trendpick_pro/domain/brand/service/BrandService.java b/src/main/java/project/trendpick_pro/domain/brand/service/BrandService.java new file mode 100644 index 00000000..ea7534e5 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/brand/service/BrandService.java @@ -0,0 +1,33 @@ +package project.trendpick_pro.domain.brand.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.brand.entity.Brand; +import project.trendpick_pro.domain.brand.entity.dto.BrandResponse; +import project.trendpick_pro.domain.brand.repository.BrandRepository; + +import java.util.List; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class BrandService { + + private final BrandRepository brandRepository; + + @Transactional + public void save(String name){ + brandRepository.save(new Brand(name)); + } + + @Transactional + public void delete(Long id){ + Brand brand = brandRepository.findById(id).orElseThrow(); + brandRepository.delete(brand); + } + + public List findAll(){ + return brandRepository.findAllBy(); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/category/entity/MainCategory.java b/src/main/java/project/trendpick_pro/domain/category/entity/MainCategory.java index 61d0a400..bba3118c 100644 --- a/src/main/java/project/trendpick_pro/domain/category/entity/MainCategory.java +++ b/src/main/java/project/trendpick_pro/domain/category/entity/MainCategory.java @@ -5,7 +5,6 @@ import lombok.Getter; import lombok.NoArgsConstructor; - @Entity @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) @@ -20,4 +19,8 @@ public class MainCategory { public MainCategory(String name) { this.name = name; } + + public void modify(String name) { + this.name = name; + } } diff --git a/src/main/java/project/trendpick_pro/domain/category/entity/dto/request/CategorySaveRequest.java b/src/main/java/project/trendpick_pro/domain/category/entity/dto/request/CategorySaveRequest.java new file mode 100644 index 00000000..7485e50e --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/category/entity/dto/request/CategorySaveRequest.java @@ -0,0 +1,19 @@ +package project.trendpick_pro.domain.category.entity.dto.request; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +public class CategorySaveRequest { + private String name; + private String perent; + + public CategorySaveRequest(String name) { + this.name = name; + } + + public CategorySaveRequest(String name, String perent) { + this.name = name; + this.perent = perent; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/category/entity/dto/response/MainCategoryResponse.java b/src/main/java/project/trendpick_pro/domain/category/entity/dto/response/MainCategoryResponse.java new file mode 100644 index 00000000..29dcd2e1 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/category/entity/dto/response/MainCategoryResponse.java @@ -0,0 +1,10 @@ +package project.trendpick_pro.domain.category.entity.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class MainCategoryResponse { + private String name; +} diff --git a/src/main/java/project/trendpick_pro/domain/category/entity/dto/response/SubCategoryResponse.java b/src/main/java/project/trendpick_pro/domain/category/entity/dto/response/SubCategoryResponse.java new file mode 100644 index 00000000..462b0522 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/category/entity/dto/response/SubCategoryResponse.java @@ -0,0 +1,10 @@ +package project.trendpick_pro.domain.category.entity.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class SubCategoryResponse { + private String name; +} diff --git a/src/main/java/project/trendpick_pro/domain/category/repository/MainCategoryRepository.java b/src/main/java/project/trendpick_pro/domain/category/repository/MainCategoryRepository.java index 835435c5..7d78f329 100644 --- a/src/main/java/project/trendpick_pro/domain/category/repository/MainCategoryRepository.java +++ b/src/main/java/project/trendpick_pro/domain/category/repository/MainCategoryRepository.java @@ -2,7 +2,12 @@ import org.springframework.data.jpa.repository.JpaRepository; import project.trendpick_pro.domain.category.entity.MainCategory; +import project.trendpick_pro.domain.category.entity.dto.response.MainCategoryResponse; + +import java.util.List; public interface MainCategoryRepository extends JpaRepository { - public MainCategory findByName(String name); + MainCategory findByName(String name); + + List findAllBy(); } diff --git a/src/main/java/project/trendpick_pro/domain/category/service/MainCategoryService.java b/src/main/java/project/trendpick_pro/domain/category/service/MainCategoryService.java new file mode 100644 index 00000000..9febeb69 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/category/service/MainCategoryService.java @@ -0,0 +1,43 @@ +package project.trendpick_pro.domain.category.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.category.entity.MainCategory; +import project.trendpick_pro.domain.category.entity.dto.request.CategorySaveRequest; +import project.trendpick_pro.domain.category.entity.dto.response.MainCategoryResponse; +import project.trendpick_pro.domain.category.repository.MainCategoryRepository; + +import java.util.List; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class MainCategoryService { + + private final MainCategoryRepository mainCategoryRepository; + + @Transactional + public void save(String name) { + mainCategoryRepository.save(new MainCategory(name)); + } + + @Transactional + public void delete(Long id) { + MainCategory mainCategory = mainCategoryRepository.findById(id).orElseThrow(); + mainCategoryRepository.delete(mainCategory); + } + + public List findAll() { + return mainCategoryRepository.findAllBy(); + } + + public MainCategoryResponse findById(Long id) { + MainCategory mainCategory = mainCategoryRepository.findById(id).orElseThrow(); + return new MainCategoryResponse(mainCategory.getName()); + } + + public MainCategory findByName(String username) { + return mainCategoryRepository.findByName(username); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/category/service/SubCategoryService.java b/src/main/java/project/trendpick_pro/domain/category/service/SubCategoryService.java new file mode 100644 index 00000000..508b5774 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/category/service/SubCategoryService.java @@ -0,0 +1,46 @@ +package project.trendpick_pro.domain.category.service; + + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.category.entity.MainCategory; +import project.trendpick_pro.domain.category.entity.SubCategory; +import project.trendpick_pro.domain.category.entity.dto.request.CategorySaveRequest; +import project.trendpick_pro.domain.category.entity.dto.response.SubCategoryResponse;; +import project.trendpick_pro.domain.category.repository.SubCategoryRepository; + +import java.util.List; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class SubCategoryService { + + private final SubCategoryRepository subCategoryRepository; + + private final MainCategoryService mainCategoryService; + + @Transactional + public void save(String name, MainCategory mainCategory){ + subCategoryRepository.save(new SubCategory(name, mainCategory)); + } + + @Transactional + public void delete(Long id){ + SubCategory subCategory = subCategoryRepository.findById(id).orElseThrow(); + subCategoryRepository.delete(subCategory); + } + public List findAll() { + return subCategoryRepository.findAllBy(); + } + + public SubCategoryResponse findById(Long id){ + SubCategory subCategory=subCategoryRepository.findById(id).orElseThrow(); + return new SubCategoryResponse(subCategory.getName()); + } + + public SubCategory findByName(String username){ + return subCategoryRepository.findByName(username); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/favoritetag/repository/FavoriteTagRepository.java b/src/main/java/project/trendpick_pro/domain/favoritetag/repository/FavoriteTagRepository.java new file mode 100644 index 00000000..0a2f920e --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/favoritetag/repository/FavoriteTagRepository.java @@ -0,0 +1,7 @@ +package project.trendpick_pro.domain.favoritetag.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.FavoriteTag; + +public interface FavoriteTagRepository extends JpaRepository { +} diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java index ef982c5a..4b384e4d 100644 --- a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java +++ b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java @@ -32,22 +32,18 @@ public class MemberController { @GetMapping("/register") public String register(JoinForm joinForm, Model model) { model.addAttribute("joinForm", joinForm); - model.addAttribute(tagService.getAllTags()); + model.addAttribute("allTags", tagService.getAllTags()); return "trendpick/usr/member/join"; } @PreAuthorize("isAnonymous()") @PostMapping("/register") - public String register(@Valid JoinForm joinForm, BindingResult bindingResult) { + public String register(@Valid JoinForm joinForm, BindingResult bindingResult, Model model) { if (bindingResult.hasErrors()) { + model.addAttribute("allTags", tagService.getAllTags()); return "trendpick/usr/member/join"; } - try { - memberService.register(joinForm); - } catch(MemberAlreadyExistException e) { - bindingResult.reject(e.getErrorCode().getCode(), e.getMessage()); - return "trendpick/usr/member/join"; - } + memberService.register(joinForm); return "redirect:/trendpick/member/login"; } diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index a636c819..6fe4cc75 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -5,6 +5,7 @@ import org.hibernate.validator.constraints.Range; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; +import project.trendpick_pro.domain.FavoriteTag; import project.trendpick_pro.domain.tag.entity.Tag; import java.time.LocalDate; @@ -39,7 +40,7 @@ public class Member { @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) @Builder.Default - private List tags = new ArrayList<>(); + private List tags = new ArrayList<>(); private String bankName; private String bankAccount; @@ -70,7 +71,7 @@ public void connectBank(String bankName, String bankAccount) { this.bankAccount = bankAccount; } - public void changeTags(List tags) { + public void changeTags(List tags) { this.tags = tags; } } diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java b/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java index 878ff7ca..2fe292f9 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java @@ -1,14 +1,14 @@ package project.trendpick_pro.domain.member.entity.form; -import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotEmpty; import java.util.List; -public record JoinForm(@NotBlank(message = "email을 입력해주세요.") String emailtext, +public record JoinForm(@NotBlank(message = "email을 입력해주세요.") String email, @NotBlank(message = "password를 입력해주세요.") String password, @NotBlank(message = "이름을 입력해주세요.") String username, @NotBlank(message = "휴대폰 번호를 입력해주세요.") String phoneNumber, @NotBlank(message = "권한을 입력해주세요.") String state, - @NotBlank(message = "선호하는 태그를 입력해주세요.")List tags) { + @NotEmpty(message = "선호하는 태그를 입력해주세요.")List tags) { } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotMatchException.java b/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotMatchException.java index 6b41ec42..671f9895 100644 --- a/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotMatchException.java +++ b/src/main/java/project/trendpick_pro/domain/member/exception/MemberNotMatchException.java @@ -5,6 +5,7 @@ import project.trendpick_pro.global.exception.BaseException; public class MemberNotMatchException extends BaseException { + private static final ErrorCode code = ErrorCode.MEMBER_NOT_MATCH; public MemberNotMatchException(String message) { diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index b6078175..3461778c 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -1,9 +1,12 @@ package project.trendpick_pro.domain.member.service; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.FavoriteTag; +import project.trendpick_pro.domain.favoritetag.repository.FavoriteTagRepository; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.RoleType; import project.trendpick_pro.domain.member.entity.form.JoinForm; @@ -14,11 +17,9 @@ import project.trendpick_pro.domain.tag.entity.dto.request.TagRequest; import project.trendpick_pro.domain.tag.repository.TagRepository; -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; -import java.util.Optional; +import java.util.*; +@Slf4j @Service @RequiredArgsConstructor @Transactional(readOnly = true) @@ -36,7 +37,7 @@ public Optional findByUsername(String username) { @Transactional public void register(JoinForm joinForm) { - if (memberRepository.findByUsername(joinForm.emailtext()).isPresent()) { + if (memberRepository.findByEmail(joinForm.email()).isPresent()) { throw new MemberAlreadyExistException("이미 존재하는 이름입니다."); } @@ -49,31 +50,38 @@ public void register(JoinForm joinForm) { roleType = RoleType.MEMBER; } - List tags = new ArrayList<>(); - for (String tag : joinForm.tags()) { - tagRepository.findByName(tag).ifPresent(tags::add); - } - Member member = Member .builder() - .email(joinForm.emailtext()) + .email(joinForm.email()) .password(passwordEncoder.encode(joinForm.password())) .username(joinForm.username()) .phoneNumber(joinForm.phoneNumber()) .role(roleType) - .tags(tags) .build(); + List tags = new ArrayList<>(); + for (String tag : joinForm.tags()) { + Tag findTag = tagRepository.findByName(tag).orElseThrow(); + FavoriteTag favoriteTag = new FavoriteTag(findTag, findTag.getName()); + favoriteTag.connectMember(member); + tags.add(favoriteTag); + } + member.changeTags(tags); + memberRepository.save(member); } @Transactional public void manageTag(String username, TagRequest tagRequest){ + Member member = memberRepository.findByUsername(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); - List tags = new ArrayList<>(); + List tags = new ArrayList<>(); for (String s : tagRequest.getTags()) { - tagRepository.findByName(s).ifPresent(tags::add); + Tag tag = tagRepository.findByName(s).orElseThrow(); + FavoriteTag favoriteTag = new FavoriteTag(tag, tag.getName()); + favoriteTag.connectMember(member); + tags.add(favoriteTag); } member.changeTags(tags); } diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 8de8f79e..3219f2d4 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -3,10 +3,17 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.jetbrains.annotations.NotNull; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; +import project.trendpick_pro.domain.brand.service.BrandService; +import project.trendpick_pro.domain.category.entity.MainCategory; +import project.trendpick_pro.domain.category.service.MainCategoryService; +import project.trendpick_pro.domain.category.service.SubCategoryService; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.RoleType; @@ -15,6 +22,8 @@ import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.product.service.ProductService; +import project.trendpick_pro.domain.recommend.service.RecommendService; +import project.trendpick_pro.domain.tag.service.TagService; import java.io.IOException; import java.util.List; @@ -25,67 +34,75 @@ @RequestMapping("trendpick/products") public class ProductController { - private final MemberRepository memberRepository; - private final Rq rq; private final ProductService productService; + private final TagService tagService; + + private final MainCategoryService mainCategoryService; + private final SubCategoryService subCategoryService; + private final BrandService brandService; + private final RecommendService recommendService; + + @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") + @GetMapping("/register") + public String registerProduct(ProductSaveRequest productSaveRequest, Model model) { + model.addAttribute("productSaveRequest", productSaveRequest); + model.addAttribute("tags", tagService.getAllTags()); + model.addAttribute("mainCategories", mainCategoryService.findAll()); + model.addAttribute("subCategories", subCategoryService.findAll()); + model.addAttribute("brands", brandService.findAll()); + log.debug("gotoregister"); + return "/trendpick/products/register"; + } - @PreAuthorize("isAuthenticated()") + @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") @PostMapping("/register") - public String registerProduct(@Valid ProductSaveRequest productSaveRequest, Model model) throws IOException { - if(!rq.getMember().getRole().equals(RoleType.BRAND_ADMIN)) - throw new RuntimeException("상품 등록 권한이 없습니다."); - - ProductResponse productResponse = productService.register(productSaveRequest); + public String register(@ModelAttribute @Valid ProductSaveRequest productSaveRequest, + @RequestParam("mainFile") MultipartFile mainFile, + @RequestParam("subFiles") List subFiles, @NotNull Model model) throws IOException { + log.info("registerProduct: {}", productSaveRequest.toString()); + ProductResponse productResponse = productService.register(productSaveRequest, mainFile, subFiles); model.addAttribute("productResponse", productResponse); - return "redirect:/trendpick/products/" + productResponse.getId(); + return "redirect:/trendpick/products/detailpage"; } - @PreAuthorize("isAuthenticated()") + @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") @PostMapping("/edit/{productId}") - public String modifyProduct(@PathVariable Long productId, @Valid ProductSaveRequest productSaveRequest, Model model) throws IOException { - if(!rq.getMember().getRole().equals(RoleType.BRAND_ADMIN)) //추가로 해당 상품 브랜드 관리자인지도 체크 - throw new RuntimeException("상품 수정 권한이 없습니다."); + public String modifyProduct(@PathVariable Long productId, @Valid ProductSaveRequest productSaveRequest, @RequestParam("mainFile") MultipartFile mainFile, + @RequestParam("subFiles") List subFiles, Model model) throws IOException { - ProductResponse productResponse = productService.modify(productId, productSaveRequest); + ProductResponse productResponse = productService.modify(productId, productSaveRequest, mainFile, subFiles ); model.addAttribute("productResponse", productResponse); return "redirect:/trendpick/products/" + productResponse.getId(); } - @PreAuthorize("isAuthenticated()") + @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") @DeleteMapping("/{productId}") public String deleteProduct(@PathVariable Long productId) { - if(!rq.getMember().getRole().equals(RoleType.BRAND_ADMIN)) //추가로 해당 상품 브랜드 관리자인지도 체크 - throw new RuntimeException("상품 삭제 권한이 없습니다."); productService.delete(productId); return "redirect:/trendpick/products/list"; } + @PreAuthorize("isAnonymous()") @GetMapping("/{productId}") public String showProduct(@PathVariable Long productId, Model model) { - Member member = null; - if(rq.isLogin()) - member = rq.getMember(); - - model.addAttribute("productResponse", productService.show(member, productId)); + model.addAttribute("productResponse", productService.show(productId)); return "/trendpick/products/detailpage"; } + @PreAuthorize("isAnonymous()") @GetMapping("/list") public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") int offset, - @RequestParam(value = "main-category") String mainCategory, - @RequestParam(value = "sub-category") String subCategory, + @RequestParam(value = "main-category", defaultValue = "추천") String mainCategory, + @RequestParam(value = "sub-category", defaultValue = "전체") String subCategory, @RequestParam(value = "sort", defaultValue = "1") Integer sortCode, Model model) { - model.addAttribute("productResponse", productService.showAll(offset, mainCategory, subCategory, sortCode)); - return "/trendpick/products/detailpage"; - } - - @GetMapping("/test") - @ResponseBody - public List test(){ - return productService.getRecommendProduct(memberRepository.findById(1L).get()); + if (mainCategory.equals("추천")) { + model.addAttribute("productResponses", recommendService.getFindAll(offset)); + } else { + model.addAttribute("productResponses", productService.showAll(offset, mainCategory, subCategory, sortCode)); + } return "/trendpick/products/list"; } } diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index 50e45cf8..67d16fc6 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -77,14 +77,14 @@ public Product(String name, MainCategory mainCategory, SubCategory subCategory, public static Product of(ProductSaveRequest request, MainCategory mainCategory , SubCategory subCategory, Brand brand,CommonFile file,List tags) { return Product.builder() - .name(request.getName()) + .name(request.name()) .mainCategory(mainCategory) .subCategory(subCategory) .brand(brand) - .description(request.getDescription()) + .description(request.description()) .file(file) - .price(request.getPrice()) - .stock(request.getStock()) + .price(request.price()) + .stock(request.stock()) .tags(tags) .build(); } @@ -109,11 +109,9 @@ public void addReview(int rating){ } public void update(ProductSaveRequest request) { - this.name=request.getName(); - this.description=request.getDescription(); - this.price=request.getPrice(); - this.stock=request.getStock(); + this.name=request.name(); + this.description=request.description(); + this.price=request.price(); + this.stock=request.stock(); } - - } diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java index 774b68e1..7362a980 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java @@ -1,43 +1,32 @@ package project.trendpick_pro.domain.product.entity.dto.request; import jakarta.validation.constraints.NotBlank; -import lombok.Data; -import org.springframework.web.multipart.MultipartFile; -import project.trendpick_pro.domain.tag.entity.Tag; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; import java.util.List; -@Data -public class ProductSaveRequest { - - @NotBlank(message = "제목을 입력해주세요.") - private String name; - - @NotBlank(message = "내용을 입력해주세요.") - private String description; - - @NotBlank(message = "메인 카테고리를 정하세요.") - private String mainCategory; - - @NotBlank(message = "서브 카테고리를 정하세요.") - private String subCategory; - - @NotBlank(message = "브랜드를 입력해주세요.") - private String brand; - - @NotBlank(message = "메인 사진을 입력해주세요.") - private MultipartFile mainFile; - - @NotBlank(message = "서브 사진들을 입력해주세요.") - private List subFiles; - - @NotBlank(message = "가격을 입력해주세요.") - private int price; - - @NotBlank(message = "수량을 입력해주세요.") - private int stock; - - @NotBlank(message = "포함될 태그들을 추가해주세요.") - private List tags; - +public record ProductSaveRequest( + @NotBlank(message = "제목을 입력해주세요.") String name, + @NotBlank(message = "내용을 입력해주세요.") String description, + @NotBlank(message = "메인 카테고리를 정하세요.") String mainCategory, + @NotBlank(message = "서브 카테고리를 정하세요.") String subCategory, + @NotBlank(message = "브랜드를 입력해주세요.") String brand, + @NotNull(message = "가격을 입력해주세요.") Integer price, + @NotNull(message = "수량을 입력해주세요.") Integer stock, + @NotEmpty(message = "포함될 태그들을 추가해주세요.") List tags) { + @Override + public String toString() { + return "ProductSaveRequest{" + + "name='" + name + '\'' + + ", description='" + description + '\'' + + ", mainCategory='" + mainCategory + '\'' + + ", subCategory='" + subCategory + '\'' + + ", brand='" + brand + '\'' + + ", price=" + price + + ", stock=" + stock + + ", tags=" + tags + + '}'; + } } + diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponse.java index 564685e5..43933239 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponse.java @@ -2,11 +2,12 @@ import com.querydsl.core.annotations.QueryProjection; import lombok.AccessLevel; +import lombok.Data; import lombok.Getter; import lombok.NoArgsConstructor; import project.trendpick_pro.domain.common.file.CommonFile; -@Getter +@Data @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ProductListResponse { diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java index 7985fcb9..98170811 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java @@ -2,14 +2,17 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import project.trendpick_pro.domain.FavoriteTag; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; +import project.trendpick_pro.domain.recommend.entity.Recommend; import java.util.List; public interface ProductRepositoryCustom { public Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable); - public List findProductByRecommended(Member member); + public List findProductByRecommended(String username); } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 7648ff41..641419a9 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -1,5 +1,6 @@ package project.trendpick_pro.domain.product.repository; +import com.querydsl.core.Tuple; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.JPAExpressions; @@ -9,28 +10,32 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.support.PageableExecutionUtils; -import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; -import project.trendpick_pro.domain.product.entity.dto.response.QProductByRecommended; import project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse; -import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; -import project.trendpick_pro.domain.tag.entity.QTag; +import java.util.Comparator; import java.util.List; +import java.util.Optional; +import static project.trendpick_pro.domain.QFavoriteTag.*; import static project.trendpick_pro.domain.brand.entity.QBrand.*; import static project.trendpick_pro.domain.category.entity.QMainCategory.*; import static project.trendpick_pro.domain.category.entity.QSubCategory.*; import static project.trendpick_pro.domain.common.file.QCommonFile.commonFile; +import static project.trendpick_pro.domain.member.entity.QMember.*; import static project.trendpick_pro.domain.product.entity.QProduct.*; +import static project.trendpick_pro.domain.tag.entity.QTag.*; public class ProductRepositoryImpl implements ProductRepositoryCustom { private final JPAQueryFactory queryFactory; + private final JPAQuery subQuery; public ProductRepositoryImpl(EntityManager em) { this.queryFactory = new JPAQueryFactory(em); + this.subQuery = new JPAQuery<>(em); } @Override @@ -73,27 +78,33 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag } @Override - public List findProductByRecommended(Member member) { - QTag tagByMember = new QTag("tagByMember"); - QTag tagByProduct = new QTag("tagByProduct"); + public List findProductByRecommended(String username) { - List list = queryFactory - .select(new QProductByRecommended( - tagByProduct.product.id, - tagByProduct.name - ) - ) - .from(tagByProduct) - .where(tagByProduct.name.in( - JPAExpressions.select(tagByMember.name) - .from(tagByMember) - .where(tagByMember.member.id.eq(member.getId())) - ) - .and(tagByProduct.product.id.isNotNull())) - .distinct() + List sortProducts = queryFactory + .select(product.id, favoriteTag.score.sum()) + .from(product) + .leftJoin(member.tags, favoriteTag) + .leftJoin(product.tags, tag) + .leftJoin(favoriteTag.member, member) + .where(favoriteTag.name.in( + JPAExpressions.select(tag.name) + .from(tag) + .where(tag.product.eq(product) + )), + member.username.eq(username)) + .groupBy(product.id) + .orderBy(favoriteTag.score.sum().desc()) .fetch(); - return list; + return sortProducts.stream() + .sorted(Comparator.comparing( + tuple -> Optional.ofNullable(tuple.get(1, Long.class)).orElse(Long.MIN_VALUE), + Comparator.nullsLast(Comparator.naturalOrder()))) + .map(tuple -> queryFactory + .selectFrom(product) + .where(product.id.eq(tuple.get(0, Long.class))) + .fetchOne()) + .toList(); } private static BooleanExpression mainCategoryEq(ProductSearchCond cond) { @@ -101,7 +112,11 @@ private static BooleanExpression mainCategoryEq(ProductSearchCond cond) { } private static BooleanExpression subCategoryEq(ProductSearchCond cond) { - return subCategory.name.eq(cond.getSubCategory()); + if (cond.getSubCategory().equals("전체")) { + return null; + } else { + return subCategory.name.eq(cond.getSubCategory()); + } } private static OrderSpecifier orderSelector(Integer sortCode) { diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index cb678039..c1fc340b 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -4,11 +4,15 @@ import com.querydsl.core.util.FileUtils; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import project.trendpick_pro.domain.FavoriteTag; import project.trendpick_pro.domain.brand.entity.Brand; import project.trendpick_pro.domain.brand.repository.BrandRepository; import project.trendpick_pro.domain.category.entity.MainCategory; @@ -18,6 +22,10 @@ import project.trendpick_pro.domain.common.base.filetranslator.FileTranslator; import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.entity.RoleType; +import project.trendpick_pro.domain.member.exception.MemberNotFoundException; +import project.trendpick_pro.domain.member.exception.MemberNotMatchException; +import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; @@ -25,6 +33,7 @@ import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; import project.trendpick_pro.domain.product.repository.ProductRepository; +import project.trendpick_pro.domain.recommend.entity.Recommend; import project.trendpick_pro.domain.tag.entity.Tag; import project.trendpick_pro.domain.tag.entity.type.TagType; import project.trendpick_pro.domain.tag.repository.TagRepository; @@ -33,15 +42,16 @@ import java.io.File; import java.io.IOException; import java.util.*; +import java.util.stream.Collectors; @Slf4j @Service @Transactional(readOnly = true) @RequiredArgsConstructor public class ProductService { - private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ProductService.class); private final ProductRepository productRepository; + private final MemberRepository memberRepository; private final MainCategoryRepository mainCategoryRepository; private final SubCategoryRepository subCategoryRepository; private final BrandRepository brandRepository; @@ -49,24 +59,29 @@ public class ProductService { private final TagRepository tagRepository; private final TagService tagService; + @Value("${file.dir}") + private String filePath; + @Transactional - public ProductResponse register(ProductSaveRequest productSaveRequest) throws IOException { + public ProductResponse register(ProductSaveRequest productSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { + + CheckMember(); - CommonFile mainFile = fileTranslator.translateFile(productSaveRequest.getMainFile()); - List subFiles = fileTranslator.translateFileList(productSaveRequest.getSubFiles()); + CommonFile mainFile = fileTranslator.translateFile(requestMainFile); + List subFiles = fileTranslator.translateFileList(requestSubFiles); for (CommonFile subFile : subFiles) { mainFile.connectFile(subFile); } List tags = new ArrayList<>(); // 상품에 포함시킬 태크 선택하여 저장 - for (String tag : productSaveRequest.getTags()) { + for (String tag : productSaveRequest.tags()) { tags.add(tagRepository.findByName(tag).orElseThrow()); } - MainCategory mainCategory = mainCategoryRepository.findByName(productSaveRequest.getMainCategory()); - SubCategory subCategory = subCategoryRepository.findByName(productSaveRequest.getSubCategory()); - Brand brand = brandRepository.findByName(productSaveRequest.getBrand()); + MainCategory mainCategory = mainCategoryRepository.findByName(productSaveRequest.mainCategory()); + SubCategory subCategory = subCategoryRepository.findByName(productSaveRequest.subCategory()); + Brand brand = brandRepository.findByName(productSaveRequest.brand()); Product product = Product.of(productSaveRequest, mainCategory, subCategory, brand, mainFile,tags); @@ -75,29 +90,29 @@ public ProductResponse register(ProductSaveRequest productSaveRequest) throws IO } @Transactional - public ProductResponse modify(Long productId, ProductSaveRequest productSaveRequest) throws IOException { + public ProductResponse modify(Long productId, ProductSaveRequest productSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { + + CheckMember(); Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 CommonFile mainFile=product.getFile(); List subFiles=product.getFile().getChild(); - if(productSaveRequest.getMainFile()!=null){ + if(requestMainFile!=null){ // 기존 이미지 삭제 - if(mainFile!=null){ - FileUtils.delete(new File(mainFile.getTranslatedFileName())); - } + FileUtils.delete(new File(mainFile.getTranslatedFileName())); } // 이미지 업데이트 - mainFile = fileTranslator.translateFile(productSaveRequest.getMainFile()); + mainFile = fileTranslator.translateFile(requestMainFile); - if(productSaveRequest.getSubFiles()!=null ){ + if(requestSubFiles!=null ){ // 기존 이미지 삭제 for(CommonFile subFile:subFiles){ FileUtils.delete(new File(subFile.getTranslatedFileName())); } } // 이미지 업데이트 - subFiles=fileTranslator.translateFileList(productSaveRequest.getSubFiles()); + subFiles=fileTranslator.translateFileList(requestSubFiles); for (CommonFile subFile : subFiles) { mainFile.connectFile(subFile); @@ -109,73 +124,87 @@ public ProductResponse modify(Long productId, ProductSaveRequest productSaveRequ @Transactional public void delete(Long productId) { + + CheckMember(); + Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 productRepository.delete(product); } - public ProductResponse show(Member member, Long product_id) { + public ProductResponse show(Long product_id) { Product product = productRepository.findById(product_id).orElseThrow(null);// 임시. 나중에 테스트 - if(member != null){ - tagService.updateTag(member, product, TagType.SHOW); - } + Member member = CheckMember(); + tagService.updateTag(member, product, TagType.SHOW); return ProductResponse.of(product); } public Page showAll(int offset, String mainCategory, String subCategory, Integer sortCode) { - List responses = new ArrayList<>(); - ProductSearchCond cond = new ProductSearchCond(mainCategory, subCategory, sortCode); PageRequest pageable = PageRequest.of(offset, 18); - return productRepository.findAllByCategoryId(cond, pageable); - } - - @Transactional - public List getRecommendProduct(Member member){ - List productByRecommendedList = productRepository.findProductByRecommended(member); - List memberTags = member.getTags(); + Page listResponses = productRepository.findAllByCategoryId(cond, pageable); + List list = listResponses.getContent().stream() + .peek(product -> { + String updatedMainFile = filePath + product.getMainFile(); + product.setMainFile(updatedMainFile); + }).toList(); - //태그명에 따라 가지고 있는 product_id - // : 멤버 태그명에 따라 해당 상품에 점수를 부여해야 하기 때문에 - Map> productIdListByTagName = new HashMap<>(); - - //상품 id 중복을 없애기 위함 - //맴버의 태그명과 여러개가 겹쳐서 여러개의 추천상품이 반환되었을것 그 중복을 없애야 한다. - Map recommendProductByProductId = new HashMap<>(); - - for (ProductByRecommended response : productByRecommendedList) { - if(!productIdListByTagName.containsKey(response.getTagName())) - productIdListByTagName.put(response.getTagName(), new ArrayList()); + return new PageImpl<>(list, pageable, listResponses.getTotalElements()); + } - productIdListByTagName.get(response.getTagName()).add(response.getProductId()); - } + public List getRecommendProduct(Member member){ +// +// List tags = productRepository.findProductByRecommended(member.getUsername()); +// List memberTags = member.getTags(); +// +// +// //태그명에 따라 가지고 있는 product_id +// // : 멤버 태그명에 따라 해당 상품에 점수를 부여해야 하기 때문에 +// Map> productIdListByTagName = new HashMap<>(); +// +// //상품 id 중복을 없애기 위함 +// //맴버의 태그명과 여러개가 겹쳐서 여러개의 추천상품이 반환되었을것 그 중복을 없애야 한다. +// Map recommendProductByProductId = new HashMap<>(); +// +// for (FavoriteTag tag : tags) { +// if(!productIdListByTagName.containsKey(tag.getName())) +// productIdListByTagName.put(tag.getName(), new ArrayList<>()); +// productIdListByTagName.get(tag.getName()).add(tag.get); +// } +// +// for (ProductByRecommended response : tags) { +// if(recommendProductByProductId.containsKey(response.getProductId())) +// continue; +// recommendProductByProductId.put(response.getProductId(), response); +// } +// +// for (FavoriteTag memberTag : memberTags) { +// if(productIdListByTagName.containsKey(memberTag.getName())){ +// List productIdList = productIdListByTagName.get(memberTag.getName()); +// for (Long id : productIdList) { +// recommendProductByProductId.get(id).plusTotalScore(memberTag.getScore()); +// } +// } +// } +// +// return new ArrayList<>(recommendProductByProductId.values()).stream() +// .sorted(Comparator.comparing(ProductByRecommended :: getTotalScore).reversed()) +// .toList(); + return productRepository.findProductByRecommended(member.getUsername()); + } - for (ProductByRecommended response : productByRecommendedList) { - if(recommendProductByProductId.containsKey(response.getProductId())) - continue; + private Member CheckMember() { - recommendProductByProductId.put(response.getProductId(), response); - } + String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 + Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); - for (Tag memberTag : memberTags) { - if(productIdListByTagName.containsKey(memberTag.getName())){ - List productIdList = productIdListByTagName.get(memberTag.getName()); - for (Long id : productIdList) { - recommendProductByProductId.get(id).plusTotalScore(memberTag.getScore()); - } - } + if (member.getRole().equals(RoleType.MEMBER)) { + throw new MemberNotMatchException("허용된 권한이 아닙니다."); } - - List list = new ArrayList(recommendProductByProductId.values()); - - list = list.stream() - .sorted(Comparator.comparing(ProductByRecommended :: getTotalScore).reversed()) - .toList(); - - return list; + return member; } } diff --git a/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java b/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java index e51c7a86..3ee7050a 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java @@ -18,7 +18,13 @@ public class RecommendController { private final RecommendService recommendService; - @GetMapping("/adming/getrecommendset") + @GetMapping("/admin/caculate") + public String caculate(){ + recommendService.select(); + return "redirect:/trendpick/products/list"; + } + + @GetMapping("/admin/getrecommendset") public String getRecommend(Model model, @RequestParam("page") int offset){ model.addAttribute("recommend", recommendService.getFindAll(offset)); return "/main"; diff --git a/src/main/java/project/trendpick_pro/domain/recommend/entity/dto/RecommendResponse.java b/src/main/java/project/trendpick_pro/domain/recommend/entity/dto/RecommendResponse.java deleted file mode 100644 index 9af84362..00000000 --- a/src/main/java/project/trendpick_pro/domain/recommend/entity/dto/RecommendResponse.java +++ /dev/null @@ -1,23 +0,0 @@ -package project.trendpick_pro.domain.recommend.entity.dto; - -import com.querydsl.core.annotations.QueryProjection; -import lombok.Builder; -import project.trendpick_pro.domain.recommend.entity.Recommend; - -public record RecommendResponse(Long id, String name, String brand, String mainFile, int price) { - - @Builder - @QueryProjection - public RecommendResponse { - } - - public static RecommendResponse of(Recommend recommend) { - return RecommendResponse.builder() - .id(recommend.getProduct().getId()) - .name(recommend.getName()) - .brand(recommend.getBrand().getName()) - .mainFile(recommend.getMainFile()) - .price(recommend.getPrice()) - .build(); - } -} diff --git a/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepository.java b/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepository.java index 4da5d8bb..b99b8925 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepository.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepository.java @@ -1,7 +1,10 @@ package project.trendpick_pro.domain.recommend.repository; import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.recommend.entity.Recommend; public interface RecommendRepository extends JpaRepository, RecommendRepositoryCustom { + + void deleteAllByMemberId(Long memberId); } diff --git a/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryCustom.java index d17a8405..7840ceec 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryCustom.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryCustom.java @@ -2,8 +2,8 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import project.trendpick_pro.domain.recommend.entity.dto.RecommendResponse; +import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; public interface RecommendRepositoryCustom { - Page findAllByMemberName(String username, Pageable pageable); + Page findAllByMemberName(String username, Pageable pageable); } diff --git a/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryImpl.java index aa944698..9907d6fe 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryImpl.java @@ -1,20 +1,15 @@ package project.trendpick_pro.domain.recommend.repository; -import com.querydsl.core.QueryFactory; +import com.querydsl.core.types.Expression; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.support.PageableExecutionUtils; -import project.trendpick_pro.domain.brand.entity.QBrand; -import project.trendpick_pro.domain.common.file.QCommonFile; -import project.trendpick_pro.domain.member.entity.QMember; -import project.trendpick_pro.domain.product.entity.QProduct; -import project.trendpick_pro.domain.recommend.entity.QRecommend; -import project.trendpick_pro.domain.recommend.entity.Recommend; -import project.trendpick_pro.domain.recommend.entity.dto.QRecommendResponse; -import project.trendpick_pro.domain.recommend.entity.dto.RecommendResponse; +import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; +import project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse; import java.util.List; @@ -33,10 +28,10 @@ public RecommendRepositoryImpl(EntityManager em) { } @Override - public Page findAllByMemberName(String username, Pageable pageable) { + public Page findAllByMemberName(String username, Pageable pageable) { - List result = queryFactory - .select(new QRecommendResponse( + List result = queryFactory + .select(new QProductListResponse( product.id, product.name, brand.name, diff --git a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java index 301623c6..c2ddb2fa 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java @@ -1,7 +1,9 @@ package project.trendpick_pro.domain.recommend.service; import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; import org.springframework.scheduling.annotation.Scheduled; import org.springframework.security.core.context.SecurityContextHolder; @@ -12,42 +14,37 @@ import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.product.entity.Product; -import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; -import project.trendpick_pro.domain.product.exception.ProductNotFoundException; +import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.product.service.ProductService; import project.trendpick_pro.domain.recommend.entity.Recommend; -import project.trendpick_pro.domain.recommend.entity.dto.RecommendResponse; import project.trendpick_pro.domain.recommend.repository.RecommendRepository; -import java.util.ArrayList; import java.util.List; @Service @Transactional(readOnly = true) @RequiredArgsConstructor public class RecommendService { - private final ProductRepository productRepository; private final RecommendRepository recommendRepository; private final ProductService productService; private final MemberRepository memberRepository; - private final Rq rq; + + @Value("${file.dir}") + private String filePath; //recommend -> 태그 기반 추천 상품들이 있어야 함 @Transactional @Scheduled(cron = "* * * 4 * *") //새벽 4시에 한 번씩 작동 - public void select(){ - String username = SecurityContextHolder.getContext().getAuthentication().getName(); - Member member = memberRepository.findByUsername(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); - recommendRepository.deleteAll(); + public void select(){ // 둘다 테스트 해보기 + + String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 + Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); + + recommendRepository.deleteAllByMemberId(member.getId()); //추천상품 ID값을 가지고 있는 ProductByRecommended 가져오기 (전달용) - List recommendProductList = productService.getRecommendProduct(member); - List products = new ArrayList<>(); - for (ProductByRecommended productByRecommended : recommendProductList) { - Product product = productRepository.findById(productByRecommended.getProductId()).orElseThrow(() -> new ProductNotFoundException("존재하지 않는 상품입니다.")); - products.add(product); - } + List products = productService.getRecommendProduct(member); for (Product product : products) { Recommend recommend = Recommend.of(product); @@ -57,9 +54,17 @@ public void select(){ } } - public Page getFindAll(int offset){ + public Page getFindAll(int offset){ String username = SecurityContextHolder.getContext().getAuthentication().getName(); PageRequest pageable = PageRequest.of(offset, 18); - return recommendRepository.findAllByMemberName(username, pageable); + Page listResponses = recommendRepository.findAllByMemberName(username, pageable); + + List list = listResponses.getContent().stream() + .peek(product -> { + String updatedMainFile = filePath + product.getMainFile(); + product.setMainFile(updatedMainFile); + }).toList(); + + return new PageImpl<>(list, pageable, listResponses.getTotalElements()); } } diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java index a9faab06..4026e3c5 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java +++ b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java @@ -2,17 +2,16 @@ import jakarta.persistence.*; import lombok.*; +import project.trendpick_pro.domain.FavoriteTag; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.tag.entity.type.TagType; +import java.util.List; + @Entity @Getter -//@NoArgsConstructor(access = AccessLevel.PROTECTED) -@Builder -@AllArgsConstructor -@NoArgsConstructor -@Setter +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class Tag { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -29,32 +28,16 @@ public Tag(String name, Product product) { } public Tag(String name, Member member) { this.name = name; - this.member = member; } - private int score; //선호도 점수 - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "member_id") - private Member member; - @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "product_id") private Product product; - public void increaseScore(TagType type){ - //유형에 따라 가중치 - switch (type){ - case ORDER: score += 10; - break; - case CART: score += 5; - break; - default: score += 1; - break; - } - } - - public void decreaseScore(){ - + @Override + public String toString() { + return "Tag{" + + "name='" + name + '\'' + + '}'; } } diff --git a/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java b/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java index 57a5e97e..13dc41cd 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java +++ b/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java @@ -3,6 +3,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.FavoriteTag; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.tag.entity.Tag; @@ -17,29 +18,34 @@ @RequiredArgsConstructor @Transactional(readOnly = true) public class TagService { + private final TagRepository tagRepository; - public TagListResponse getAllTags() { - return new TagListResponse(tagRepository.findAll()); + public void save(String name) { + tagRepository.save(new Tag(name)); + } + + public List getAllTags() { + return tagRepository.findAll(); } @Transactional public void updateTag(Member member, Product product, TagType type) { List tagList = product.getTags(); - List tags = member.getTags(); + List tags = member.getTags(); //장바구니는 2유형이라고 가정 for(Tag tagByProduct : tagList){ boolean hasTag = false; - for(Tag tagByMember : tags){ - if(tagByProduct.getName().equals(tagByMember)){ //기존에 가지고 있던 태그에는 점수 부여 + for(FavoriteTag tagByMember : tags){ + if(tagByProduct.getName().equals(tagByMember.getName())){ //기존에 가지고 있던 태그에는 점수 부여 tagByMember.increaseScore(type); hasTag = true; break; } } if(!hasTag) //태그를 가지고 있지 않다면 추가해준다. - tags.add(new Tag(tagByProduct.getName())); + tags.add(new FavoriteTag(tagByProduct, tagByProduct.getName())); } } } diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index d7c0d5b5..3c8871a9 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -6,13 +6,15 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.transaction.annotation.Transactional; -import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.brand.service.BrandService; +import project.trendpick_pro.domain.category.entity.MainCategory; +import project.trendpick_pro.domain.category.service.MainCategoryService; +import project.trendpick_pro.domain.category.service.SubCategoryService; import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.member.service.MemberService; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; -import project.trendpick_pro.domain.tag.entity.Tag; -import project.trendpick_pro.domain.tag.repository.TagRepository; +import project.trendpick_pro.domain.tag.service.TagService; import java.util.ArrayList; import java.util.List; @@ -24,94 +26,88 @@ public class BaseData { @Value("${tag}") List tags; + @Value("${main-category}") + List mainCategories; + + @Value("${sub-category-1}") + List subCategories1; + + @Value("${brand}") + List brands; + @Bean CommandLineRunner initData( - TagRepository tagRepository, + TagService tagService, ProductRepository productRepository, - MemberRepository memberRepository + MemberRepository memberRepository, + MainCategoryService mainCategoryService, + SubCategoryService subCategoryService, + BrandService brandService ) { return new CommandLineRunner() { @Override @Transactional public void run(String... args) { -// for (String tag : tags) { -// tagRepository.save(new Tag(tag)); -// } - - //member1은 태그1, 태그2, 태그3 을 각각 10점 5점 1점 가지고 있다 - //상품1은 태그1을 가지고 있다 - //상품2는 태그1, 태그2를 가지고 있다 - //상품3은 태그1, 태그2 태그3 모두 가지고 있다. + for (String tag : tags) { + tagService.save(tag); + } - Member member1 = memberRepository.save(Member.builder().username("member1").build()); - Product product1 = Product.builder().name("상품1").build(); - Product product2 = Product.builder().name("상품2").build(); - Product product3 = Product.builder().name("상품3").build(); - Product product4 = Product.builder().name("상품4").build(); - productRepository.save(product1); - productRepository.save(product2); - productRepository.save(product3); - productRepository.save(product4); + for (String mainCategory : mainCategories) { + mainCategoryService.save(mainCategory); + } + for (String subCategory : subCategories1) { + MainCategory mainCategory = mainCategoryService.findByName("상의"); + subCategoryService.save(subCategory, mainCategory); + } - Tag tag1 = new Tag("태그1", member1); - tag1.setScore(10); - tagRepository.save(tag1); - Tag tag2 = new Tag("태그2", member1); - tag2.setScore(5); - tagRepository.save(tag2); - Tag tag3 = new Tag("태그3", member1); - tag3.setScore(1); - tagRepository.save(tag3); + for (String brand : brands) { + brandService.save(brand); + } + //member1은 태그1, 태그2, 태그3 을 각각 10점 5점 1점 가지고 있다 //상품1은 태그1을 가지고 있다 - Tag tag1ByProduct1 = new Tag("태그1", product1); - tagRepository.save(tag1ByProduct1); - //상품2는 태그1, 태그2를 가지고 있다 - Tag tag2ByProduct1 = new Tag("태그1", product2); - Tag tag2ByProduct2 = new Tag("태그2", product2); - tagRepository.save(tag2ByProduct1); - tagRepository.save(tag2ByProduct2); - //상품3은 태그1, 태그2 태그3 모두 가지고 있다. - Tag tag3ByProduct1 = new Tag("태그1", product3); - Tag tag3ByProduct2 = new Tag("태그2", product3); - Tag tag3ByProduct3 = new Tag("태그3", product3); - tagRepository.save(tag3ByProduct1); - tagRepository.save(tag3ByProduct2); - tagRepository.save(tag3ByProduct3); - - -// List tags1 = new ArrayList<>(); -// for(int i=0; i<10; i++){ -// Tag tag = new Tag("태그" + i, member1); -// tag.setScore(10); -// tagRepository.save(tag); -// tags1.add(tag); -// } -// List tags2 = new ArrayList<>(); -// for(int i=10; i<20; i++){ -// Tag tag = new Tag("태그" + i, member2); -// tag.setScore(10); -// tagRepository.save(tag); -// tags2.add(tag); -// } // -// List tags3 = new ArrayList<>(); -// for(int i=1; i<5; i++){ -// Tag tag = new Tag("태그" + i, product1); -// tagRepository.save(tag); -// tags3.add(tag); -// } -// List tags4 = new ArrayList<>(); -// for(int i=5; i<10; i++){ -// Tag tag = new Tag("태그" + i, product1); -// tagRepository.save(tag); -// tags3.add(tag); -// } - - +// Member member1 = memberRepository.save(Member.builder().username("member1").build()); +// Product product1 = Product.builder().name("상품1").build(); +// Product product2 = Product.builder().name("상품2").build(); +// Product product3 = Product.builder().name("상품3").build(); +// Product product4 = Product.builder().name("상품4").build(); +// productRepository.save(product1); +// productRepository.save(product2); +// productRepository.save(product3); +// productRepository.save(product4); +// +// +// Tag tag1 = new Tag("태그1", member1); +// tag1.changeScore(10); +// tagRepository.save(tag1); +// Tag tag2 = new Tag("태그2", member1); +// tag2.changeScore(5); +// tagRepository.save(tag2); +// Tag tag3 = new Tag("태그3", member1); +// tag3.changeScore(1); +// tagRepository.save(tag3); +// +// //상품1은 태그1을 가지고 있다 +// Tag tag1ByProduct1 = new Tag("태그1", product1); +// tagRepository.save(tag1ByProduct1); +// +// //상품2는 태그1, 태그2를 가지고 있다 +// Tag tag2ByProduct1 = new Tag("태그1", product2); +// Tag tag2ByProduct2 = new Tag("태그2", product2); +// tagRepository.save(tag2ByProduct1); +// tagRepository.save(tag2ByProduct2); +// +// //상품3은 태그1, 태그2 태그3 모두 가지고 있다. +// Tag tag3ByProduct1 = new Tag("태그1", product3); +// Tag tag3ByProduct2 = new Tag("태그2", product3); +// Tag tag3ByProduct3 = new Tag("태그3", product3); +// tagRepository.save(tag3ByProduct1); +// tagRepository.save(tag3ByProduct2); +// tagRepository.save(tag3ByProduct3); } }; } diff --git a/src/main/java/project/trendpick_pro/global/exception/GlobalExceptionAdvice.java b/src/main/java/project/trendpick_pro/global/exception/GlobalExceptionAdvice.java index 7c588fbe..77328323 100644 --- a/src/main/java/project/trendpick_pro/global/exception/GlobalExceptionAdvice.java +++ b/src/main/java/project/trendpick_pro/global/exception/GlobalExceptionAdvice.java @@ -1,47 +1,43 @@ package project.trendpick_pro.global.exception; import lombok.extern.slf4j.Slf4j; -import org.springframework.http.ResponseEntity; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; -import org.springframework.web.bind.annotation.RestControllerAdvice; import project.trendpick_pro.domain.member.exception.MemberAlreadyExistException; import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.exception.MemberNotMatchException; import project.trendpick_pro.domain.product.exception.ProductNotFoundException; @Slf4j -@RestControllerAdvice +@ControllerAdvice public class GlobalExceptionAdvice { @ExceptionHandler(MemberNotFoundException.class) - public ResponseEntity MEmberNotFoundHandleException(MemberNotFoundException e) { - ErrorCode errorCode = e.getErrorCode(); + public String MemberNotFoundHandleException(MemberNotFoundException e, Model model) { log.error("[exceptionHandle] ex", e); - ErrorResponse errorResponse = new ErrorResponse(errorCode.getCode(), e.getMessage()); - return ResponseEntity.status(errorCode.getStatus()).body(errorResponse); + model.addAttribute("errorMessage", e.getMessage()); + return "trendpick/usr/member/join"; } @ExceptionHandler(MemberNotMatchException.class) - public ResponseEntity MemberNotMatchHandleException(MemberNotMatchException e) { - ErrorCode errorCode = e.getErrorCode(); + public String MemberNotMatchHandleException(MemberNotMatchException e, Model model) { log.error("[exceptionHandle] ex", e); - ErrorResponse errorResponse = new ErrorResponse(errorCode.getCode(), e.getMessage()); - return ResponseEntity.status(errorCode.getStatus()).body(errorResponse); + model.addAttribute("errorMessage", e.getMessage()); + return "trendpick/usr/member/join"; } @ExceptionHandler(MemberAlreadyExistException.class) - public ResponseEntity MemberAlreadyExistHandleException(MemberAlreadyExistException e) { - ErrorCode errorCode = e.getErrorCode(); + public String MemberAlreadyExistHandleException(MemberAlreadyExistException e, Model model) { log.error("[exceptionHandle] ex", e); - ErrorResponse errorResponse = new ErrorResponse(errorCode.getCode(), e.getMessage()); - return ResponseEntity.status(errorCode.getStatus()).body(errorResponse); + model.addAttribute("errorMessage", e.getMessage()); + return "trendpick/usr/member/join"; } @ExceptionHandler(ProductNotFoundException.class) - public ResponseEntity ProductNotFoundHandleException(ProductNotFoundException e) { - ErrorCode errorCode = e.getErrorCode(); + public String ProductNotFoundHandleException(ProductNotFoundException e, Model model) { log.error("[exceptionHandle] ex", e); - ErrorResponse errorResponse = new ErrorResponse(errorCode.getCode(), e.getMessage()); - return ResponseEntity.status(errorCode.getStatus()).body(errorResponse); + model.addAttribute("errorMessage", e.getMessage()); + return "trendpick/usr/member/join"; } } diff --git a/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java b/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java index 1d70b8bf..002cdfd3 100644 --- a/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java +++ b/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java @@ -21,7 +21,7 @@ SecurityFilterChain filterChain(HttpSecurity http) throws Exception { formLogin -> formLogin .loginPage("/trendpick/member/login") .loginProcessingUrl("/login_proc") - .defaultSuccessUrl("/trendpick/product/list") + .defaultSuccessUrl("/trendpick/products/list") ) .logout( logout -> logout diff --git a/src/main/resources/application-data.yml b/src/main/resources/application-data.yml new file mode 100644 index 00000000..08e7b896 --- /dev/null +++ b/src/main/resources/application-data.yml @@ -0,0 +1,15 @@ +tag: + 오버핏청바지, 시티보이룩, 스포티캐주얼, 빈티지룩, 프레피스타일, + 모던미니멀리스트, 로맨틱룩, 로커룩, 힙합룩, 데님스타일, + 스트릿패션, 빅사이즈룩, 오가닉패션, 애슬레저룩, 비즈니스캐주얼, + 테일러드룩, 코지니트, 밀리터리룩, 고딕패션, 펑크룩, + 레트로스타일, 베이직룩, 컬러풀패션, 모노톤스타일, 럭셔리룩, + 블랙스타일, 루즈핏패션, 크롭트스타일, 블레이저룩, 코디로이패션 + +main-category: + 추천, 상의, 아우터, 하의, 신발, 가방, 악세서리 +sub-category-1: + 전체, 반소매 티셔츠, 긴소매 티셔츠, 피케/카라 티셔츠, 셔츠/블라우스, 니트/스웨터, 후드 티셔츠, 맨투맨/스웨트셔츠 + +brand: + 아디다스, 나이키, 버버리, 라퍼퍼 \ No newline at end of file diff --git a/src/main/resources/application-tag.yml b/src/main/resources/application-tag.yml deleted file mode 100644 index c9bcd0ac..00000000 --- a/src/main/resources/application-tag.yml +++ /dev/null @@ -1,15 +0,0 @@ -tag: - 오버핏청바지, 시티보이룩, 스포티캐주얼, 빈티지룩, 프레피스타일, - 모던미니멀리스트, 로맨틱룩, 로커룩, 힙합룩, 데님스타일, - 스트릿패션, 빅사이즈룩, 오가닉패션, 애슬레저룩, 비즈니스캐주얼, - 테일러드룩, 코지니트, 밀리터리룩, 고딕패션, 펑크룩, - 레트로스타일, 베이직룩, 컬러풀패션, 모노톤스타일, 럭셔리룩, - 블랙스타일, 루즈핏패션, 크롭트스타일, 블레이저룩, 코디로이패션, - 플레어팬츠, 파스텔룩, 파워드레싱, 스쿨룩, 체크패턴룩, - 스트라이프패션, 레이어드스타일, 프린트룩, 그래픽티룩, 라이더스자켓, - 보헤미안룩, 밴드티룩, 카모플라지패션, 바이커룩, 스커트스타일, 화이트룩, - 리넨룩, 폴로스타일, 트렌치룩, 카키스타일, 데일리룩, 캐릭터티룩, 유니크패션, - 파티룩, 브랜드룩, 플로럴패션, 캐주얼드레스룩, 점프수트스타일, 턱시도룩, - 글램룩, 키치패션, 스니커즈룩, 드레시룩, 레더스타일, 펑키패션, 스웨터룩, - 이브닝룩, 스포티룩, 캐주얼코트룩, 모헤어니트, 네온패션, 폴카닷스타일, - 롱코트룩, 블록패션, 밴딩팬츠룩, 야상룩, 플랫폼룩, 보이시룩, 하이웨스트스타일, 더블브레스티드룩, 펑크록룩 \ No newline at end of file diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 93cff954..e5718afc 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,7 +1,7 @@ spring: profiles: active: dev - include: secret, tag + include: secret, data mvc: pathmatch: matching-strategy: ant_path_matcher \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/products/list.html b/src/main/resources/templates/trendpick/products/list.html index de01567a..2329f591 100644 --- a/src/main/resources/templates/trendpick/products/list.html +++ b/src/main/resources/templates/trendpick/products/list.html @@ -1,11 +1,28 @@ - + - - Title + 게시물 목록 - +
+
+
+

+

Brand:

+

Main File:

+

Price:

+
+
+
+ + +
+ Previous + + + + Next +
- \ No newline at end of file + diff --git a/src/main/resources/templates/trendpick/usr/member/join.html b/src/main/resources/templates/trendpick/usr/member/join.html index 74b9bf89..6d6e3090 100644 --- a/src/main/resources/templates/trendpick/usr/member/join.html +++ b/src/main/resources/templates/trendpick/usr/member/join.html @@ -8,11 +8,12 @@

회원 가입

+

Error Message

- - -

+ + +

@@ -30,10 +31,26 @@

회원 가입

- - + +
+ +
+
+ +
+
+ +

+
+ +
+ + +
+

+
From 3a68f46af7d2660878e39d01d4bfc4ce12a2581e Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sat, 3 Jun 2023 22:10:40 +0900 Subject: [PATCH 132/367] Changes by hye_0000 --- .../java/project/trendpick_pro/global/basedata/BaseData.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index 3c8871a9..e51638ef 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -11,8 +11,6 @@ import project.trendpick_pro.domain.category.service.MainCategoryService; import project.trendpick_pro.domain.category.service.SubCategoryService; import project.trendpick_pro.domain.member.repository.MemberRepository; -import project.trendpick_pro.domain.member.service.MemberService; -import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tag.service.TagService; From b9df28be7450dbb0c4f32f699aa294147f974fb0 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sat, 3 Jun 2023 22:10:44 +0900 Subject: [PATCH 133/367] Changes by Jilra01 --- .../domain/brand/entity/Brand.java | 4 + .../brand/repository/BrandRepository.java | 2 + .../repository/SubCategoryRepository.java | 4 + .../trendpick/products/register.html | 74 ++++++++++++++++++- 4 files changed, 82 insertions(+), 2 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/brand/entity/Brand.java b/src/main/java/project/trendpick_pro/domain/brand/entity/Brand.java index 57a4fbb3..78dd0de1 100644 --- a/src/main/java/project/trendpick_pro/domain/brand/entity/Brand.java +++ b/src/main/java/project/trendpick_pro/domain/brand/entity/Brand.java @@ -16,4 +16,8 @@ public class Brand { @Column(name = "name", nullable = false, unique = true) private String name; + + public Brand(String name){ + this.name = name; + } } diff --git a/src/main/java/project/trendpick_pro/domain/brand/repository/BrandRepository.java b/src/main/java/project/trendpick_pro/domain/brand/repository/BrandRepository.java index 32485d8c..11e7d49b 100644 --- a/src/main/java/project/trendpick_pro/domain/brand/repository/BrandRepository.java +++ b/src/main/java/project/trendpick_pro/domain/brand/repository/BrandRepository.java @@ -4,6 +4,8 @@ import project.trendpick_pro.domain.brand.entity.Brand; import project.trendpick_pro.domain.brand.entity.dto.BrandResponse; +import java.util.List; + public interface BrandRepository extends JpaRepository { Brand findByName(String name); diff --git a/src/main/java/project/trendpick_pro/domain/category/repository/SubCategoryRepository.java b/src/main/java/project/trendpick_pro/domain/category/repository/SubCategoryRepository.java index 42b27289..7e812a69 100644 --- a/src/main/java/project/trendpick_pro/domain/category/repository/SubCategoryRepository.java +++ b/src/main/java/project/trendpick_pro/domain/category/repository/SubCategoryRepository.java @@ -2,7 +2,11 @@ import org.springframework.data.jpa.repository.JpaRepository; import project.trendpick_pro.domain.category.entity.SubCategory; +import project.trendpick_pro.domain.category.entity.dto.response.SubCategoryResponse; + +import java.util.List; public interface SubCategoryRepository extends JpaRepository { public SubCategory findByName(String name); + List findAllBy(); } diff --git a/src/main/resources/templates/trendpick/products/register.html b/src/main/resources/templates/trendpick/products/register.html index 566549bd..1d0be62d 100644 --- a/src/main/resources/templates/trendpick/products/register.html +++ b/src/main/resources/templates/trendpick/products/register.html @@ -1,10 +1,80 @@ - + - Title + + + 상품 등록 폼 + +
+
+ + +

+
+
+ + +
+

+
+ + +
+
+ +
+
+ + + +
+
+ +
+
+ + +
+
+ +
+
+ +
+ + +
+ +
+ + +
+ +
+ + +

+
+ +
+ + +

+
+ +
+ +
+ +
+

+
+ + +
\ No newline at end of file From dac65158076283a1c63718c350619ba2d774791b Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sat, 3 Jun 2023 22:10:48 +0900 Subject: [PATCH 134/367] Changes by nanna --- .../trendpick_pro/domain/category/entity/SubCategory.java | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/main/java/project/trendpick_pro/domain/category/entity/SubCategory.java b/src/main/java/project/trendpick_pro/domain/category/entity/SubCategory.java index 4af81ed4..3f3c74ca 100644 --- a/src/main/java/project/trendpick_pro/domain/category/entity/SubCategory.java +++ b/src/main/java/project/trendpick_pro/domain/category/entity/SubCategory.java @@ -20,8 +20,12 @@ public class SubCategory { @JoinColumn(name = "category_id") private MainCategory mainCategory; - public SubCategory(String name, MainCategory mainCategory) { + public SubCategory(String name, MainCategory mainCategory) { this.name = name; this.mainCategory = mainCategory; } + + public void modify(String name) { + this.name = name; + } } From d56623a6bcd906a1f9488652ea1aa8122394c681 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sat, 3 Jun 2023 23:55:13 +0900 Subject: [PATCH 135/367] =?UTF-8?q?Refactor:=20=EC=B6=94=EC=B2=9C=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=AF=B8=EC=99=84=EC=84=B1=20(#104)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../base/filetranslator/FileTranslator.java | 13 +++------ .../domain/common/file/CommonFile.java | 12 ++++---- .../{ => favoritetag/entity}/FavoriteTag.java | 2 +- .../repository/FavoriteTagRepository.java | 2 +- .../domain/member/entity/Member.java | 29 ++++++++++--------- .../domain/member/service/MemberService.java | 3 +- .../domain/product/entity/Product.java | 6 ++-- .../entity/dto/response/ProductResponse.java | 10 +++---- .../repository/ProductRepositoryCustom.java | 4 --- .../repository/ProductRepositoryImpl.java | 6 ++-- .../product/service/ProductService.java | 8 ++--- .../domain/recommend/entity/Recommend.java | 2 +- .../repository/RecommendRepositoryImpl.java | 2 +- .../trendpick_pro/domain/tag/entity/Tag.java | 4 --- .../domain/tag/service/TagService.java | 4 +-- 15 files changed, 43 insertions(+), 64 deletions(-) rename src/main/java/project/trendpick_pro/domain/{ => favoritetag/entity}/FavoriteTag.java (96%) diff --git a/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java b/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java index 88920c8f..9fdaea21 100644 --- a/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java +++ b/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java @@ -16,7 +16,6 @@ public class FileTranslator { @Value("${file.dir}") private String filePath; //저장경로 - //이미지 업로드할때 url경로 public String getFilePath(String filename) { return filePath + filename; } @@ -27,16 +26,12 @@ public CommonFile translateFile(MultipartFile multipartFile) throws IOException return null; } - String originalFilename = multipartFile.getOriginalFilename(); - String translatedFileName = translateFileName(originalFilename); + String translatedFileName = translateFileName(multipartFile.getOriginalFilename()); multipartFile.transferTo(new File(getFilePath(translatedFileName))); - return CommonFile - .builder() - .originalFileName(originalFilename) - .translatedFileName(translatedFileName) - .build() - ; + return CommonFile.builder() + .fileName(translatedFileName) + .build(); } //파일 여러개를 한 번에 묶어서 변환할때 diff --git a/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java b/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java index e16f71b7..a374e1b9 100644 --- a/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java +++ b/src/main/java/project/trendpick_pro/domain/common/file/CommonFile.java @@ -7,17 +7,13 @@ @Entity @Getter -@AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) -@Builder -@Setter public class CommonFile { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - private String originalFileName; //파일 업로드명 - private String translatedFileName; //실제 저장 경로, 업로드할때 이 경로로 이미지 불러옴. + private String fileName; //실제 저장 경로, 업로드할때 이 경로로 이미지 불러옴. //메인파일 @ManyToOne(fetch = FetchType.LAZY) @@ -26,9 +22,13 @@ public class CommonFile { //서브파일 (만약 메인/서브 유형이 아니라면 그냥 여러개 생성해야한다. 전부 메인으로) @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL) - @Builder.Default //이거없으면 리스트 초기화 된다. 붙여야됨 private List child = new ArrayList<>(); + @Builder + public CommonFile(String fileName) { + this.fileName = fileName; + } + //양방향 맵핑 public void connectFile(CommonFile childFile){ this.getChild().add(childFile); diff --git a/src/main/java/project/trendpick_pro/domain/FavoriteTag.java b/src/main/java/project/trendpick_pro/domain/favoritetag/entity/FavoriteTag.java similarity index 96% rename from src/main/java/project/trendpick_pro/domain/FavoriteTag.java rename to src/main/java/project/trendpick_pro/domain/favoritetag/entity/FavoriteTag.java index b64f57be..7ebd9762 100644 --- a/src/main/java/project/trendpick_pro/domain/FavoriteTag.java +++ b/src/main/java/project/trendpick_pro/domain/favoritetag/entity/FavoriteTag.java @@ -1,4 +1,4 @@ -package project.trendpick_pro.domain; +package project.trendpick_pro.domain.favoritetag.entity; import jakarta.persistence.*; import lombok.AccessLevel; diff --git a/src/main/java/project/trendpick_pro/domain/favoritetag/repository/FavoriteTagRepository.java b/src/main/java/project/trendpick_pro/domain/favoritetag/repository/FavoriteTagRepository.java index 0a2f920e..f8a7d7ec 100644 --- a/src/main/java/project/trendpick_pro/domain/favoritetag/repository/FavoriteTagRepository.java +++ b/src/main/java/project/trendpick_pro/domain/favoritetag/repository/FavoriteTagRepository.java @@ -1,7 +1,7 @@ package project.trendpick_pro.domain.favoritetag.repository; import org.springframework.data.jpa.repository.JpaRepository; -import project.trendpick_pro.domain.FavoriteTag; +import project.trendpick_pro.domain.favoritetag.entity.FavoriteTag; public interface FavoriteTagRepository extends JpaRepository { } diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index 6fe4cc75..b904088c 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -2,44 +2,37 @@ import jakarta.persistence.*; import lombok.*; -import org.hibernate.validator.constraints.Range; import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.authority.SimpleGrantedAuthority; -import project.trendpick_pro.domain.FavoriteTag; -import project.trendpick_pro.domain.tag.entity.Tag; - -import java.time.LocalDate; +import project.trendpick_pro.domain.favoritetag.entity.FavoriteTag; import java.util.ArrayList; import java.util.List; @Entity @Getter -@Builder -@AllArgsConstructor @NoArgsConstructor(access = AccessLevel.PROTECTED) public class Member { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "member_id") private Long id; - @Column(name = "email",unique = true) + @Column(name = "email",unique = true, nullable = false) private String email; - @Column(name = "password") + @Column(name = "password", nullable = false) private String password; - @Column(name = "username") + @Column(name = "username", nullable = false) private String username; - @Column(name = "phone_number") + @Column(name = "phone_number", nullable = false) private String phoneNumber; @Enumerated(EnumType.STRING) + @Column(name = "role", nullable = false) private RoleType role; @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) - @Builder.Default private List tags = new ArrayList<>(); private String bankName; @@ -47,7 +40,6 @@ public class Member { private String address; - // 이 함수 자체는 만들어야 한다. 스프링 시큐리티 규격 public List getGrantedAuthorities() { List grantedAuthorities = new ArrayList<>(); @@ -62,6 +54,15 @@ public List getGrantedAuthorities() { return grantedAuthorities; } + @Builder + public Member(String email, String password, String username, String phoneNumber, RoleType role) { + this.email = email; + this.password = password; + this.username = username; + this.phoneNumber = phoneNumber; + this.role = role; + } + public void connectAddress(String address) { this.address = address; } diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index 3461778c..39f386fc 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -5,8 +5,7 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import project.trendpick_pro.domain.FavoriteTag; -import project.trendpick_pro.domain.favoritetag.repository.FavoriteTagRepository; +import project.trendpick_pro.domain.favoritetag.entity.FavoriteTag; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.RoleType; import project.trendpick_pro.domain.member.entity.form.JoinForm; diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index 67d16fc6..340f6df9 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -41,17 +41,17 @@ public class Product extends BaseTimeEntity { @JoinColumn(name = "brand_id") private Brand brand; - @Column(name = "description") + @Column(name = "description", nullable = false) private String description; @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "file_id") private CommonFile file; - @Column(name = "price") + @Column(name = "price", nullable = false) private int price; - @Column(name = "stock") + @Column(name = "stock", nullable = false) private int stock; @OneToMany(mappedBy = "product", cascade = CascadeType.ALL) diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java index a8db331f..ba8ba634 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java @@ -20,7 +20,7 @@ public class ProductResponse { private Long id; private String name; private String mainCategory; // Category - private List subCategory; // Category + private String subCategory; // Category private String brand; // Brand private String description; private String mainFile; @@ -31,7 +31,7 @@ public class ProductResponse { @Builder @QueryProjection - public ProductResponse(Long id, String name, String mainCategory, List subCategory, String brand, String description, + public ProductResponse(Long id, String name, String mainCategory, String subCategory, String brand, String description, String mainFile, List subFiles, int price, int stock, List tags) { this.id = id; this.name = name; @@ -51,10 +51,10 @@ public static ProductResponse of (Product product) { .id(product.getId()) .name(product.getName()) .mainCategory(product.getMainCategory().getName()) -// .subCategory(product.getSubCategory().getName()) + .subCategory(product.getSubCategory().getName()) .brand(product.getBrand().getName()) .description(product.getDescription()) - .mainFile(product.getFile().getOriginalFileName()) + .mainFile(product.getFile().getFileName()) .subFiles(subFiles(product.getFile().getChild())) .price(product.getPrice()) .stock(product.getStock()) @@ -66,7 +66,7 @@ private static List subFiles(List subFiles) { List tmpList = new ArrayList<>(); for (CommonFile subFile : subFiles) { - tmpList.add(subFile.getOriginalFileName()); + tmpList.add(subFile.getFileName()); } return tmpList; } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java index 98170811..4f7b2061 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java @@ -2,13 +2,9 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import project.trendpick_pro.domain.FavoriteTag; -import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; -import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; -import project.trendpick_pro.domain.recommend.entity.Recommend; import java.util.List; diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 641419a9..1123b78c 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -19,11 +19,11 @@ import java.util.List; import java.util.Optional; -import static project.trendpick_pro.domain.QFavoriteTag.*; import static project.trendpick_pro.domain.brand.entity.QBrand.*; import static project.trendpick_pro.domain.category.entity.QMainCategory.*; import static project.trendpick_pro.domain.category.entity.QSubCategory.*; import static project.trendpick_pro.domain.common.file.QCommonFile.commonFile; +import static project.trendpick_pro.domain.favoritetag.entity.QFavoriteTag.favoriteTag; import static project.trendpick_pro.domain.member.entity.QMember.*; import static project.trendpick_pro.domain.product.entity.QProduct.*; import static project.trendpick_pro.domain.tag.entity.QTag.*; @@ -45,7 +45,7 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag product.id, product.name, brand.name, - commonFile.translatedFileName, + commonFile.fileName, product.price) ) .from(product) @@ -83,8 +83,6 @@ public List findProductByRecommended(String username) { List sortProducts = queryFactory .select(product.id, favoriteTag.score.sum()) .from(product) - .leftJoin(member.tags, favoriteTag) - .leftJoin(product.tags, tag) .leftJoin(favoriteTag.member, member) .where(favoriteTag.name.in( JPAExpressions.select(tag.name) diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index c1fc340b..36cf67d9 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -12,7 +12,6 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; -import project.trendpick_pro.domain.FavoriteTag; import project.trendpick_pro.domain.brand.entity.Brand; import project.trendpick_pro.domain.brand.repository.BrandRepository; import project.trendpick_pro.domain.category.entity.MainCategory; @@ -29,11 +28,9 @@ import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; -import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; import project.trendpick_pro.domain.product.repository.ProductRepository; -import project.trendpick_pro.domain.recommend.entity.Recommend; import project.trendpick_pro.domain.tag.entity.Tag; import project.trendpick_pro.domain.tag.entity.type.TagType; import project.trendpick_pro.domain.tag.repository.TagRepository; @@ -42,7 +39,6 @@ import java.io.File; import java.io.IOException; import java.util.*; -import java.util.stream.Collectors; @Slf4j @Service @@ -100,7 +96,7 @@ public ProductResponse modify(Long productId, ProductSaveRequest productSaveRequ if(requestMainFile!=null){ // 기존 이미지 삭제 - FileUtils.delete(new File(mainFile.getTranslatedFileName())); + FileUtils.delete(new File(mainFile.getFileName())); } // 이미지 업데이트 mainFile = fileTranslator.translateFile(requestMainFile); @@ -108,7 +104,7 @@ public ProductResponse modify(Long productId, ProductSaveRequest productSaveRequ if(requestSubFiles!=null ){ // 기존 이미지 삭제 for(CommonFile subFile:subFiles){ - FileUtils.delete(new File(subFile.getTranslatedFileName())); + FileUtils.delete(new File(subFile.getFileName())); } } // 이미지 업데이트 diff --git a/src/main/java/project/trendpick_pro/domain/recommend/entity/Recommend.java b/src/main/java/project/trendpick_pro/domain/recommend/entity/Recommend.java index 7156f0aa..3565b0de 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/entity/Recommend.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/entity/Recommend.java @@ -58,7 +58,7 @@ public static Recommend of(Product product) { return Recommend.builder() .name(product.getName()) .brand(product.getBrand()) - .mainFile(product.getFile().getTranslatedFileName()) + .mainFile(product.getFile().getFileName()) .price(product.getPrice()) .build(); } diff --git a/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryImpl.java index 9907d6fe..405cbf0e 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryImpl.java @@ -35,7 +35,7 @@ public Page findAllByMemberName(String username, Pageable p product.id, product.name, brand.name, - commonFile.translatedFileName, + commonFile.fileName, product.price )) .from(recommend) diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java index 4026e3c5..b7308fea 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java +++ b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java @@ -2,12 +2,8 @@ import jakarta.persistence.*; import lombok.*; -import project.trendpick_pro.domain.FavoriteTag; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; -import project.trendpick_pro.domain.tag.entity.type.TagType; - -import java.util.List; @Entity @Getter diff --git a/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java b/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java index 13dc41cd..78909600 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java +++ b/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java @@ -3,12 +3,10 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import project.trendpick_pro.domain.FavoriteTag; +import project.trendpick_pro.domain.favoritetag.entity.FavoriteTag; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.tag.entity.Tag; -import project.trendpick_pro.domain.tag.entity.dto.response.TagListResponse; -import project.trendpick_pro.domain.tag.entity.dto.response.TagResponse; import project.trendpick_pro.domain.tag.entity.type.TagType; import project.trendpick_pro.domain.tag.repository.TagRepository; From 62bb1a3b4b9d6876562561e914613412fb0e6640 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 4 Jun 2023 00:19:21 +0900 Subject: [PATCH 136/367] =?UTF-8?q?Refactor:=20=EC=B6=94=EC=B2=9C=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=AF=B8=EC=99=84=EC=84=B1=20(#104)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trendpick_pro/TrendPickProApplication.java | 2 +- .../trendpick_pro/domain/member/entity/Member.java | 14 -------------- .../domain/product/entity/Product.java | 9 +++++++++ .../product/repository/ProductRepositoryImpl.java | 2 +- .../domain/product/service/ProductService.java | 3 ++- .../domain/recommend/service/RecommendService.java | 9 +++++---- 6 files changed, 18 insertions(+), 21 deletions(-) diff --git a/src/main/java/project/trendpick_pro/TrendPickProApplication.java b/src/main/java/project/trendpick_pro/TrendPickProApplication.java index b5d315a3..99cccbe0 100644 --- a/src/main/java/project/trendpick_pro/TrendPickProApplication.java +++ b/src/main/java/project/trendpick_pro/TrendPickProApplication.java @@ -5,9 +5,9 @@ import org.springframework.data.jpa.repository.config.EnableJpaAuditing; import org.springframework.scheduling.annotation.EnableScheduling; +@EnableScheduling @EnableJpaAuditing @SpringBootApplication -@EnableScheduling public class TrendPickProApplication { public static void main(String[] args) { diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index b904088c..a5d64e7a 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -40,20 +40,6 @@ public class Member { private String address; - public List getGrantedAuthorities() { - List grantedAuthorities = new ArrayList<>(); - - // 모든 멤버는 member 권한을 가진다. - grantedAuthorities.add(new SimpleGrantedAuthority("member")); - - // username이 admin인 회원은 추가로 admin 권한도 가진다. - if ("admin".equals(username)) { - grantedAuthorities.add(new SimpleGrantedAuthority("admin")); - } - - return grantedAuthorities; - } - @Builder public Member(String email, String password, String username, String phoneNumber, RoleType role) { this.email = email; diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index 340f6df9..e3ea9e4d 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -114,4 +114,13 @@ public void update(ProductSaveRequest request) { this.price=request.price(); this.stock=request.stock(); } + + @Override + public String toString() { + return "Product{" + + "name='" + name + '\'' + + ", price=" + price + + ", stock=" + stock + + '}'; + } } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 1123b78c..a656e939 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -82,7 +82,7 @@ public List findProductByRecommended(String username) { List sortProducts = queryFactory .select(product.id, favoriteTag.score.sum()) - .from(product) + .from(favoriteTag, product) .leftJoin(favoriteTag.member, member) .where(favoriteTag.name.in( JPAExpressions.select(tag.name) diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 36cf67d9..875f0d8f 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -79,7 +79,7 @@ public ProductResponse register(ProductSaveRequest productSaveRequest, Multipart SubCategory subCategory = subCategoryRepository.findByName(productSaveRequest.subCategory()); Brand brand = brandRepository.findByName(productSaveRequest.brand()); - Product product = Product.of(productSaveRequest, mainCategory, subCategory, brand, mainFile,tags); + Product product = Product.of(productSaveRequest, mainCategory, subCategory, brand, mainFile, tags); productRepository.save(product); return ProductResponse.of(product); @@ -190,6 +190,7 @@ public List getRecommendProduct(Member member){ // return new ArrayList<>(recommendProductByProductId.values()).stream() // .sorted(Comparator.comparing(ProductByRecommended :: getTotalScore).reversed()) // .toList(); + log.debug("member : {}", member); return productRepository.findProductByRecommended(member.getUsername()); } diff --git a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java index c2ddb2fa..ddb30f19 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java @@ -1,6 +1,7 @@ package project.trendpick_pro.domain.recommend.service; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Value; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; @@ -9,19 +10,18 @@ import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; -import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.product.service.ProductService; import project.trendpick_pro.domain.recommend.entity.Recommend; import project.trendpick_pro.domain.recommend.repository.RecommendRepository; import java.util.List; +@Slf4j @Service @Transactional(readOnly = true) @RequiredArgsConstructor @@ -35,8 +35,8 @@ public class RecommendService { //recommend -> 태그 기반 추천 상품들이 있어야 함 @Transactional - @Scheduled(cron = "* * * 4 * *") //새벽 4시에 한 번씩 작동 - public void select(){ // 둘다 테스트 해보기 + @Scheduled(cron = "0 0 4 * * *") + public void select(){ String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); @@ -46,6 +46,7 @@ public void select(){ // 둘다 테스트 해보기 //추천상품 ID값을 가지고 있는 ProductByRecommended 가져오기 (전달용) List products = productService.getRecommendProduct(member); + for (Product product : products) { Recommend recommend = Recommend.of(product); recommend.connectProduct(product); From 0b6467f983543a875d5bb0cfece16ff3cb5c0952 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 4 Jun 2023 15:22:06 +0900 Subject: [PATCH 137/367] =?UTF-8?q?refactor:=20Tag=EA=B0=80=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=EB=90=98=EB=8A=94=20List=ED=83=80=EC=9E=85=20->=20Set?= =?UTF-8?q?=ED=83=80=EC=9E=85=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20(#1?= =?UTF-8?q?06)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../favoritetag/entity/FavoriteTag.java | 10 +------- .../domain/member/entity/Member.java | 6 +++-- .../domain/member/service/MemberService.java | 23 +++++++++---------- 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/favoritetag/entity/FavoriteTag.java b/src/main/java/project/trendpick_pro/domain/favoritetag/entity/FavoriteTag.java index 7ebd9762..b43e01d1 100644 --- a/src/main/java/project/trendpick_pro/domain/favoritetag/entity/FavoriteTag.java +++ b/src/main/java/project/trendpick_pro/domain/favoritetag/entity/FavoriteTag.java @@ -24,16 +24,8 @@ public class FavoriteTag { @JoinColumn(name = "member_id") private Member member; - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "tag_id") - private Tag tag; - - public FavoriteTag(Tag tag, String name) { - this.tag = tag; + public FavoriteTag(Member member, String name) { this.name = name; - } - - public void connectMember(Member member) { this.member = member; } diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index a5d64e7a..92bec7e6 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -6,7 +6,9 @@ import org.springframework.security.core.authority.SimpleGrantedAuthority; import project.trendpick_pro.domain.favoritetag.entity.FavoriteTag; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; @Entity @Getter @@ -33,7 +35,7 @@ public class Member { private RoleType role; @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) - private List tags = new ArrayList<>(); + private Set tags = new LinkedHashSet<>(); private String bankName; private String bankAccount; @@ -58,7 +60,7 @@ public void connectBank(String bankName, String bankAccount) { this.bankAccount = bankAccount; } - public void changeTags(List tags) { + public void changeTags(Set tags) { this.tags = tags; } } diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index 39f386fc..94ac6368 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -58,15 +58,14 @@ public void register(JoinForm joinForm) { .role(roleType) .build(); - List tags = new ArrayList<>(); + Set favoriteTags = new LinkedHashSet<>(); for (String tag : joinForm.tags()) { - Tag findTag = tagRepository.findByName(tag).orElseThrow(); - FavoriteTag favoriteTag = new FavoriteTag(findTag, findTag.getName()); - favoriteTag.connectMember(member); - tags.add(favoriteTag); +// Tag findTag = tagRepository.findByName(tag).orElseThrow(); +// favoriteTag.connectMember(member); + FavoriteTag favoriteTag = new FavoriteTag(member, tag); + favoriteTags.add(favoriteTag); } - member.changeTags(tags); - + member.changeTags(favoriteTags); memberRepository.save(member); } @@ -75,11 +74,11 @@ public void manageTag(String username, TagRequest tagRequest){ Member member = memberRepository.findByUsername(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); - List tags = new ArrayList<>(); - for (String s : tagRequest.getTags()) { - Tag tag = tagRepository.findByName(s).orElseThrow(); - FavoriteTag favoriteTag = new FavoriteTag(tag, tag.getName()); - favoriteTag.connectMember(member); + Set tags = new LinkedHashSet<>(); + for (String tag : tagRequest.getTags()) { +// Tag tag = tagRepository.findByName(s).orElseThrow(); +// favoriteTag.connectMember(member); + FavoriteTag favoriteTag = new FavoriteTag(member, tag); tags.add(favoriteTag); } member.changeTags(tags); From a4a0f5c1dd1ceda15be85232785fcf59a0fc2f42 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 4 Jun 2023 16:03:17 +0900 Subject: [PATCH 138/367] =?UTF-8?q?refactor:=20FavoiteTag=EC=99=80=20Tag?= =?UTF-8?q?=20=EB=B3=84=EB=8F=84=20=ED=81=B4=EB=9E=98=EC=8A=A4=EB=A1=9C=20?= =?UTF-8?q?=EB=A7=8C=EB=93=A4=EA=B8=B0=20(#106)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/FavoriteTagRepository.java | 6 +++ .../service/FavoriteTagService.java | 48 +++++++++++++++++++ .../domain/product/entity/Product.java | 8 ++-- .../entity/dto/response/ProductResponse.java | 2 +- .../product/service/ProductService.java | 7 +-- .../trendpick_pro/domain/tag/entity/Tag.java | 7 +-- .../domain/tag/service/TagService.java | 17 +++++-- 7 files changed, 80 insertions(+), 15 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/favoritetag/service/FavoriteTagService.java diff --git a/src/main/java/project/trendpick_pro/domain/favoritetag/repository/FavoriteTagRepository.java b/src/main/java/project/trendpick_pro/domain/favoritetag/repository/FavoriteTagRepository.java index f8a7d7ec..7e58fa4f 100644 --- a/src/main/java/project/trendpick_pro/domain/favoritetag/repository/FavoriteTagRepository.java +++ b/src/main/java/project/trendpick_pro/domain/favoritetag/repository/FavoriteTagRepository.java @@ -1,7 +1,13 @@ package project.trendpick_pro.domain.favoritetag.repository; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import project.trendpick_pro.domain.favoritetag.entity.FavoriteTag; +import project.trendpick_pro.domain.member.entity.Member; + +import java.util.List; public interface FavoriteTagRepository extends JpaRepository { + @Query("select t from FavoriteTag t where t.member = :member") + List findAllByMember(Member member); } diff --git a/src/main/java/project/trendpick_pro/domain/favoritetag/service/FavoriteTagService.java b/src/main/java/project/trendpick_pro/domain/favoritetag/service/FavoriteTagService.java new file mode 100644 index 00000000..cad61df4 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/favoritetag/service/FavoriteTagService.java @@ -0,0 +1,48 @@ +package project.trendpick_pro.domain.favoritetag.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.favoritetag.entity.FavoriteTag; +import project.trendpick_pro.domain.favoritetag.repository.FavoriteTagRepository; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.tag.entity.Tag; +import project.trendpick_pro.domain.tag.entity.type.TagType; + +import java.util.List; +import java.util.Set; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class FavoriteTagService { + private final FavoriteTagRepository favoriteTagRepository; + + public Set getAllTags(Member member) { + List list = favoriteTagRepository.findAll(); + return Set.copyOf(list); + } + + @Transactional + public void updateTag(Member member, Product product, TagType type) { + Set tagList = product.getTags(); + Set tags = member.getTags(); + + for(Tag tagByProduct : tagList){ + boolean hasTag = false; + for(FavoriteTag tagByMember : tags){ + if(tagByProduct.getName().equals(tagByMember.getName())){ //기존에 가지고 있던 태그에는 점수 부여 + tagByMember.increaseScore(type); + hasTag = true; + break; + } + } + if(!hasTag){ //태그를 가지고 있지 않다면 추가해준다. + FavoriteTag favoriteTag = new FavoriteTag(member, tagByProduct.getName()); + favoriteTag.increaseScore(type); + tags.add(favoriteTag); + } + } + } +} diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index e3ea9e4d..75082835 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -15,7 +15,9 @@ import project.trendpick_pro.domain.tag.entity.Tag; import java.util.ArrayList; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; @Entity @Getter @@ -55,14 +57,14 @@ public class Product extends BaseTimeEntity { private int stock; @OneToMany(mappedBy = "product", cascade = CascadeType.ALL) - private List tags = new ArrayList<>(); + private Set tags = new LinkedHashSet<>(); public long reviewCount = 0; public double rateAvg = 0; @Builder public Product(String name, MainCategory mainCategory, SubCategory subCategory, Brand brand, - String description, CommonFile file, int price, int stock, List tags) { + String description, CommonFile file, int price, int stock, Set tags) { this.name = name; this.mainCategory = mainCategory; this.subCategory = subCategory; @@ -75,7 +77,7 @@ public Product(String name, MainCategory mainCategory, SubCategory subCategory, } public static Product of(ProductSaveRequest request, MainCategory mainCategory - , SubCategory subCategory, Brand brand,CommonFile file,List tags) { + , SubCategory subCategory, Brand brand,CommonFile file,Set tags) { return Product.builder() .name(request.name()) .mainCategory(mainCategory) diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java index ba8ba634..01b6ffc5 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java @@ -58,7 +58,7 @@ public static ProductResponse of (Product product) { .subFiles(subFiles(product.getFile().getChild())) .price(product.getPrice()) .stock(product.getStock()) - .tags(product.getTags()) + .tags(new ArrayList<>(product.getTags())) .build(); } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 875f0d8f..148eeb6d 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -70,9 +70,10 @@ public ProductResponse register(ProductSaveRequest productSaveRequest, Multipart mainFile.connectFile(subFile); } - List tags = new ArrayList<>(); // 상품에 포함시킬 태크 선택하여 저장 - for (String tag : productSaveRequest.tags()) { - tags.add(tagRepository.findByName(tag).orElseThrow()); + Set tags = new LinkedHashSet<>(); // 상품에 포함시킬 태크 선택하여 저장 + for (String tagName : productSaveRequest.tags()) { +// tags.add(tagRepository.findByName(tag).orElseThrow()); + tags.add(new Tag(tagName)); } MainCategory mainCategory = mainCategoryRepository.findByName(productSaveRequest.mainCategory()); diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java index b7308fea..1a07496a 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java +++ b/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java @@ -18,12 +18,13 @@ public class Tag { public Tag(String name) { this.name = name; } - public Tag(String name, Product product) { + public Tag(Product product, String name) { this.name = name; this.product = product; } - public Tag(String name, Member member) { - this.name = name; + + public void connectProduct(Product product) { + this.product = product; } @ManyToOne(fetch = FetchType.LAZY) diff --git a/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java b/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java index 78909600..60f1d22e 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java +++ b/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java @@ -11,6 +11,7 @@ import project.trendpick_pro.domain.tag.repository.TagRepository; import java.util.List; +import java.util.Set; @Service @RequiredArgsConstructor @@ -23,16 +24,19 @@ public void save(String name) { tagRepository.save(new Tag(name)); } + public void save(String name, Product product) { + tagRepository.save(new Tag(product, name)); + } + public List getAllTags() { return tagRepository.findAll(); } @Transactional public void updateTag(Member member, Product product, TagType type) { - List tagList = product.getTags(); - List tags = member.getTags(); + Set tagList = product.getTags(); + Set tags = member.getTags(); - //장바구니는 2유형이라고 가정 for(Tag tagByProduct : tagList){ boolean hasTag = false; for(FavoriteTag tagByMember : tags){ @@ -42,8 +46,11 @@ public void updateTag(Member member, Product product, TagType type) { break; } } - if(!hasTag) //태그를 가지고 있지 않다면 추가해준다. - tags.add(new FavoriteTag(tagByProduct, tagByProduct.getName())); + if(!hasTag){ //태그를 가지고 있지 않다면 추가해준다. + FavoriteTag favoriteTag = new FavoriteTag(member, tagByProduct.getName()); + favoriteTag.increaseScore(type); + tags.add(favoriteTag); + } } } } From 40b8e48006b68f1a44f8b04f9b96d9071f7bd8ae Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 4 Jun 2023 16:46:59 +0900 Subject: [PATCH 139/367] =?UTF-8?q?chore:=20=ED=8C=A8=ED=82=A4=EC=A7=80=20?= =?UTF-8?q?=EA=B5=AC=EC=A1=B0=20=EB=B3=80=EA=B2=BD=20=20(#106)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/cart/entity/CartItem.java | 5 -- .../domain/cart/service/CartService.java | 11 ++-- .../member/controller/MemberController.java | 3 +- .../domain/member/entity/Member.java | 7 +-- .../domain/member/service/MemberService.java | 7 +-- .../domain/orders/service/OrderService.java | 9 +-- .../product/controller/ProductController.java | 9 +-- .../domain/product/entity/Product.java | 4 +- .../entity/dto/response/ProductResponse.java | 3 +- .../product/service/ProductService.java | 39 ++++++------- .../recommend/service/RecommendService.java | 1 - .../domain/tag/service/TagService.java | 56 ------------------- .../favoritetag/entity/FavoriteTag.java | 6 +- .../repository/FavoriteTagRepository.java | 4 +- .../service/FavoriteTagService.java | 10 ++-- .../domain/{ => tags}/tag/entity/Tag.java | 3 +- .../tag/entity/dto/request/TagRequest.java | 2 +- .../entity/dto/response/TagListResponse.java | 4 +- .../tag/entity/dto/response/TagResponse.java | 2 +- .../{ => tags}/tag/entity/type/TagType.java | 2 +- .../tag/repository/TagRepository.java | 4 +- .../domain/tags/tag/service/TagService.java | 31 ++++++++++ .../global/basedata/BaseData.java | 3 +- 23 files changed, 88 insertions(+), 137 deletions(-) delete mode 100644 src/main/java/project/trendpick_pro/domain/tag/service/TagService.java rename src/main/java/project/trendpick_pro/domain/{ => tags}/favoritetag/entity/FavoriteTag.java (86%) rename src/main/java/project/trendpick_pro/domain/{ => tags}/favoritetag/repository/FavoriteTagRepository.java (74%) rename src/main/java/project/trendpick_pro/domain/{ => tags}/favoritetag/service/FavoriteTagService.java (81%) rename src/main/java/project/trendpick_pro/domain/{ => tags}/tag/entity/Tag.java (88%) rename src/main/java/project/trendpick_pro/domain/{ => tags}/tag/entity/dto/request/TagRequest.java (62%) rename src/main/java/project/trendpick_pro/domain/{ => tags}/tag/entity/dto/response/TagListResponse.java (65%) rename src/main/java/project/trendpick_pro/domain/{ => tags}/tag/entity/dto/response/TagResponse.java (68%) rename src/main/java/project/trendpick_pro/domain/{ => tags}/tag/entity/type/TagType.java (78%) rename src/main/java/project/trendpick_pro/domain/{ => tags}/tag/repository/TagRepository.java (64%) create mode 100644 src/main/java/project/trendpick_pro/domain/tags/tag/service/TagService.java diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java index 4ad55e8e..52ad91f5 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java @@ -3,11 +3,6 @@ import jakarta.persistence.*; import lombok.*; import project.trendpick_pro.domain.product.entity.ProductOption; -import project.trendpick_pro.domain.tag.entity.Tag; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; @Entity @Getter diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index 3bfccc49..60e4689e 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -6,15 +6,12 @@ import project.trendpick_pro.domain.cart.entity.Cart; import project.trendpick_pro.domain.cart.entity.CartItem; import project.trendpick_pro.domain.cart.repository.CartRepository; +import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.repository.MemberRepository; -import project.trendpick_pro.domain.orders.entity.OrderItem; import project.trendpick_pro.domain.product.entity.ProductOption; import project.trendpick_pro.domain.product.repository.ProductOptionRepository; -import project.trendpick_pro.domain.tag.entity.Tag; -import project.trendpick_pro.domain.tag.entity.type.TagType; -import project.trendpick_pro.domain.tag.service.TagService; +import project.trendpick_pro.domain.tags.tag.entity.type.TagType; import java.util.List; @@ -27,7 +24,7 @@ public class CartService { private final CartRepository cartRepository; private final MemberRepository memberRepository; private final ProductOptionRepository productOptionRepository; - private final TagService tagService; + private final FavoriteTagService favoriteTagService; public List findByCartMember(Member member){ return cartRepository.findByCartMember(member); @@ -44,7 +41,7 @@ public void addItemToCart(Member member, Long productOptionId, int count) { ProductOption productOption = getProductOptionById(productOptionId); CartItem cartItem = cart.findCartItemByProductOption(productOption); - tagService.updateTag(member, productOption.getProduct(), TagType.CART); //장바구니에 넣었으니 해당 상품이 가진 태그점수 올리기 + favoriteTagService.updateTag(member, productOption.getProduct(), TagType.CART); //장바구니에 넣었으니 해당 상품이 가진 태그점수 올리기 if (cartItem != null) { // 이미 카트에 해당 상품이 존재하는 경우, 수량을 증가 diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java index 4b384e4d..65ecb17d 100644 --- a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java +++ b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java @@ -13,9 +13,8 @@ import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.form.JoinForm; -import project.trendpick_pro.domain.member.exception.MemberAlreadyExistException; import project.trendpick_pro.domain.member.service.MemberService; -import project.trendpick_pro.domain.tag.service.TagService; +import project.trendpick_pro.domain.tags.tag.service.TagService; @Slf4j @Controller diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index 92bec7e6..adb1b4be 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -2,12 +2,9 @@ import jakarta.persistence.*; import lombok.*; -import org.springframework.security.core.GrantedAuthority; -import org.springframework.security.core.authority.SimpleGrantedAuthority; -import project.trendpick_pro.domain.favoritetag.entity.FavoriteTag; -import java.util.ArrayList; +import project.trendpick_pro.domain.tags.favoritetag.entity.FavoriteTag; + import java.util.LinkedHashSet; -import java.util.List; import java.util.Set; @Entity diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index 94ac6368..14b44f0e 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -5,16 +5,15 @@ import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import project.trendpick_pro.domain.favoritetag.entity.FavoriteTag; +import project.trendpick_pro.domain.tags.favoritetag.entity.FavoriteTag; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.RoleType; import project.trendpick_pro.domain.member.entity.form.JoinForm; import project.trendpick_pro.domain.member.exception.MemberAlreadyExistException; import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.repository.MemberRepository; -import project.trendpick_pro.domain.tag.entity.Tag; -import project.trendpick_pro.domain.tag.entity.dto.request.TagRequest; -import project.trendpick_pro.domain.tag.repository.TagRepository; +import project.trendpick_pro.domain.tags.tag.entity.dto.request.TagRequest; +import project.trendpick_pro.domain.tags.tag.repository.TagRepository; import java.util.*; diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 3a233127..b9919ef8 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -9,6 +9,7 @@ import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.delivery.entity.Delivery; import project.trendpick_pro.domain.delivery.entity.embaded.Address; +import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.repository.MemberRepository; @@ -22,9 +23,8 @@ import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.exception.ProductNotFoundException; import project.trendpick_pro.domain.product.repository.ProductRepository; -import project.trendpick_pro.domain.tag.entity.Tag; -import project.trendpick_pro.domain.tag.entity.type.TagType; -import project.trendpick_pro.domain.tag.service.TagService; +import project.trendpick_pro.domain.tags.tag.entity.type.TagType; +import project.trendpick_pro.domain.tags.tag.service.TagService; import java.util.ArrayList; import java.util.List; @@ -39,6 +39,7 @@ public class OrderService { private final MemberRepository memberRepository; private final ProductRepository productRepository; private final TagService tagService; + private final FavoriteTagService favoriteTagService; @Transactional public synchronized void order(Long userId, OrderSaveRequest... orderSaveRequests) { @@ -54,7 +55,7 @@ public synchronized void order(Long userId, OrderSaveRequest... orderSaveRequest throw new ProductStockOutException("재고가 부족합니다."); // 임시. 나중에 사용자 exception 널을까말까 생각 } - tagService.updateTag(member, product, TagType.ORDER); + favoriteTagService.updateTag(member, product, TagType.ORDER); orderItemList.add(new OrderItem(product, product.getPrice(), request.getQuantity())); } diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 3219f2d4..033090d2 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -7,23 +7,16 @@ import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; -import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.brand.service.BrandService; -import project.trendpick_pro.domain.category.entity.MainCategory; import project.trendpick_pro.domain.category.service.MainCategoryService; import project.trendpick_pro.domain.category.service.SubCategoryService; -import project.trendpick_pro.domain.common.base.rq.Rq; -import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.member.entity.RoleType; -import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; -import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.product.service.ProductService; import project.trendpick_pro.domain.recommend.service.RecommendService; -import project.trendpick_pro.domain.tag.service.TagService; +import project.trendpick_pro.domain.tags.tag.service.TagService; import java.io.IOException; import java.util.List; diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index 75082835..898916ab 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -12,11 +12,9 @@ import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.product.exception.ProductStockOutException; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; -import project.trendpick_pro.domain.tag.entity.Tag; +import project.trendpick_pro.domain.tags.tag.entity.Tag; -import java.util.ArrayList; import java.util.LinkedHashSet; -import java.util.List; import java.util.Set; @Entity diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java index 01b6ffc5..07660137 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java @@ -1,14 +1,13 @@ package project.trendpick_pro.domain.product.entity.dto.response; import com.querydsl.core.annotations.QueryProjection; -import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.product.entity.Product; -import project.trendpick_pro.domain.tag.entity.Tag; +import project.trendpick_pro.domain.tags.tag.entity.Tag; import java.util.ArrayList; import java.util.List; diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 148eeb6d..a25fbac3 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -20,6 +20,7 @@ import project.trendpick_pro.domain.category.repository.SubCategoryRepository; import project.trendpick_pro.domain.common.base.filetranslator.FileTranslator; import project.trendpick_pro.domain.common.file.CommonFile; +import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.RoleType; import project.trendpick_pro.domain.member.exception.MemberNotFoundException; @@ -31,10 +32,9 @@ import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; import project.trendpick_pro.domain.product.repository.ProductRepository; -import project.trendpick_pro.domain.tag.entity.Tag; -import project.trendpick_pro.domain.tag.entity.type.TagType; -import project.trendpick_pro.domain.tag.repository.TagRepository; -import project.trendpick_pro.domain.tag.service.TagService; +import project.trendpick_pro.domain.tags.tag.entity.Tag; +import project.trendpick_pro.domain.tags.tag.entity.type.TagType; +import project.trendpick_pro.domain.tags.tag.service.TagService; import java.io.File; import java.io.IOException; @@ -52,7 +52,7 @@ public class ProductService { private final SubCategoryRepository subCategoryRepository; private final BrandRepository brandRepository; private final FileTranslator fileTranslator; - private final TagRepository tagRepository; + private final FavoriteTagService favoriteTagService; private final TagService tagService; @Value("${file.dir}") @@ -92,8 +92,8 @@ public ProductResponse modify(Long productId, ProductSaveRequest productSaveRequ CheckMember(); Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 - CommonFile mainFile=product.getFile(); - List subFiles=product.getFile().getChild(); + CommonFile mainFile = product.getFile(); + List subFiles = product.getFile().getChild(); if(requestMainFile!=null){ // 기존 이미지 삭제 @@ -132,7 +132,7 @@ public ProductResponse show(Long product_id) { Product product = productRepository.findById(product_id).orElseThrow(null);// 임시. 나중에 테스트 Member member = CheckMember(); - tagService.updateTag(member, product, TagType.SHOW); + favoriteTagService.updateTag(member, product, TagType.SHOW); return ProductResponse.of(product); } @@ -153,6 +153,18 @@ public Page showAll(int offset, String mainCategory, String return new PageImpl<>(list, pageable, listResponses.getTotalElements()); } + + private Member CheckMember() { + + String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 + Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); + + if (member.getRole().equals(RoleType.MEMBER)) { + throw new MemberNotMatchException("허용된 권한이 아닙니다."); + } + return member; + } + public List getRecommendProduct(Member member){ // // List tags = productRepository.findProductByRecommended(member.getUsername()); @@ -194,15 +206,4 @@ public List getRecommendProduct(Member member){ log.debug("member : {}", member); return productRepository.findProductByRecommended(member.getUsername()); } - - private Member CheckMember() { - - String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 - Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); - - if (member.getRole().equals(RoleType.MEMBER)) { - throw new MemberNotMatchException("허용된 권한이 아닙니다."); - } - return member; - } } diff --git a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java index ddb30f19..be26655f 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java @@ -46,7 +46,6 @@ public void select(){ //추천상품 ID값을 가지고 있는 ProductByRecommended 가져오기 (전달용) List products = productService.getRecommendProduct(member); - for (Product product : products) { Recommend recommend = Recommend.of(product); recommend.connectProduct(product); diff --git a/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java b/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java deleted file mode 100644 index 60f1d22e..00000000 --- a/src/main/java/project/trendpick_pro/domain/tag/service/TagService.java +++ /dev/null @@ -1,56 +0,0 @@ -package project.trendpick_pro.domain.tag.service; - -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; -import project.trendpick_pro.domain.favoritetag.entity.FavoriteTag; -import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.product.entity.Product; -import project.trendpick_pro.domain.tag.entity.Tag; -import project.trendpick_pro.domain.tag.entity.type.TagType; -import project.trendpick_pro.domain.tag.repository.TagRepository; - -import java.util.List; -import java.util.Set; - -@Service -@RequiredArgsConstructor -@Transactional(readOnly = true) -public class TagService { - - private final TagRepository tagRepository; - - public void save(String name) { - tagRepository.save(new Tag(name)); - } - - public void save(String name, Product product) { - tagRepository.save(new Tag(product, name)); - } - - public List getAllTags() { - return tagRepository.findAll(); - } - - @Transactional - public void updateTag(Member member, Product product, TagType type) { - Set tagList = product.getTags(); - Set tags = member.getTags(); - - for(Tag tagByProduct : tagList){ - boolean hasTag = false; - for(FavoriteTag tagByMember : tags){ - if(tagByProduct.getName().equals(tagByMember.getName())){ //기존에 가지고 있던 태그에는 점수 부여 - tagByMember.increaseScore(type); - hasTag = true; - break; - } - } - if(!hasTag){ //태그를 가지고 있지 않다면 추가해준다. - FavoriteTag favoriteTag = new FavoriteTag(member, tagByProduct.getName()); - favoriteTag.increaseScore(type); - tags.add(favoriteTag); - } - } - } -} diff --git a/src/main/java/project/trendpick_pro/domain/favoritetag/entity/FavoriteTag.java b/src/main/java/project/trendpick_pro/domain/tags/favoritetag/entity/FavoriteTag.java similarity index 86% rename from src/main/java/project/trendpick_pro/domain/favoritetag/entity/FavoriteTag.java rename to src/main/java/project/trendpick_pro/domain/tags/favoritetag/entity/FavoriteTag.java index b43e01d1..1a2701f9 100644 --- a/src/main/java/project/trendpick_pro/domain/favoritetag/entity/FavoriteTag.java +++ b/src/main/java/project/trendpick_pro/domain/tags/favoritetag/entity/FavoriteTag.java @@ -1,12 +1,11 @@ -package project.trendpick_pro.domain.favoritetag.entity; +package project.trendpick_pro.domain.tags.favoritetag.entity; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.Getter; import lombok.NoArgsConstructor; import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.tag.entity.Tag; -import project.trendpick_pro.domain.tag.entity.type.TagType; +import project.trendpick_pro.domain.tags.tag.entity.type.TagType; @Entity @Getter @@ -46,4 +45,5 @@ public void decreaseScore(TagType type){ default -> score -= 1; } } + } diff --git a/src/main/java/project/trendpick_pro/domain/favoritetag/repository/FavoriteTagRepository.java b/src/main/java/project/trendpick_pro/domain/tags/favoritetag/repository/FavoriteTagRepository.java similarity index 74% rename from src/main/java/project/trendpick_pro/domain/favoritetag/repository/FavoriteTagRepository.java rename to src/main/java/project/trendpick_pro/domain/tags/favoritetag/repository/FavoriteTagRepository.java index 7e58fa4f..5088683a 100644 --- a/src/main/java/project/trendpick_pro/domain/favoritetag/repository/FavoriteTagRepository.java +++ b/src/main/java/project/trendpick_pro/domain/tags/favoritetag/repository/FavoriteTagRepository.java @@ -1,8 +1,8 @@ -package project.trendpick_pro.domain.favoritetag.repository; +package project.trendpick_pro.domain.tags.favoritetag.repository; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; -import project.trendpick_pro.domain.favoritetag.entity.FavoriteTag; +import project.trendpick_pro.domain.tags.favoritetag.entity.FavoriteTag; import project.trendpick_pro.domain.member.entity.Member; import java.util.List; diff --git a/src/main/java/project/trendpick_pro/domain/favoritetag/service/FavoriteTagService.java b/src/main/java/project/trendpick_pro/domain/tags/favoritetag/service/FavoriteTagService.java similarity index 81% rename from src/main/java/project/trendpick_pro/domain/favoritetag/service/FavoriteTagService.java rename to src/main/java/project/trendpick_pro/domain/tags/favoritetag/service/FavoriteTagService.java index cad61df4..7b5b810b 100644 --- a/src/main/java/project/trendpick_pro/domain/favoritetag/service/FavoriteTagService.java +++ b/src/main/java/project/trendpick_pro/domain/tags/favoritetag/service/FavoriteTagService.java @@ -1,14 +1,14 @@ -package project.trendpick_pro.domain.favoritetag.service; +package project.trendpick_pro.domain.tags.favoritetag.service; import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import project.trendpick_pro.domain.favoritetag.entity.FavoriteTag; -import project.trendpick_pro.domain.favoritetag.repository.FavoriteTagRepository; +import project.trendpick_pro.domain.tags.favoritetag.entity.FavoriteTag; +import project.trendpick_pro.domain.tags.favoritetag.repository.FavoriteTagRepository; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; -import project.trendpick_pro.domain.tag.entity.Tag; -import project.trendpick_pro.domain.tag.entity.type.TagType; +import project.trendpick_pro.domain.tags.tag.entity.Tag; +import project.trendpick_pro.domain.tags.tag.entity.type.TagType; import java.util.List; import java.util.Set; diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java b/src/main/java/project/trendpick_pro/domain/tags/tag/entity/Tag.java similarity index 88% rename from src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java rename to src/main/java/project/trendpick_pro/domain/tags/tag/entity/Tag.java index 1a07496a..62ed6b67 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/entity/Tag.java +++ b/src/main/java/project/trendpick_pro/domain/tags/tag/entity/Tag.java @@ -1,8 +1,7 @@ -package project.trendpick_pro.domain.tag.entity; +package project.trendpick_pro.domain.tags.tag.entity; import jakarta.persistence.*; import lombok.*; -import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; @Entity diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/dto/request/TagRequest.java b/src/main/java/project/trendpick_pro/domain/tags/tag/entity/dto/request/TagRequest.java similarity index 62% rename from src/main/java/project/trendpick_pro/domain/tag/entity/dto/request/TagRequest.java rename to src/main/java/project/trendpick_pro/domain/tags/tag/entity/dto/request/TagRequest.java index 9daae94e..404d5d6e 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/entity/dto/request/TagRequest.java +++ b/src/main/java/project/trendpick_pro/domain/tags/tag/entity/dto/request/TagRequest.java @@ -1,4 +1,4 @@ -package project.trendpick_pro.domain.tag.entity.dto.request; +package project.trendpick_pro.domain.tags.tag.entity.dto.request; import lombok.Getter; diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagListResponse.java b/src/main/java/project/trendpick_pro/domain/tags/tag/entity/dto/response/TagListResponse.java similarity index 65% rename from src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagListResponse.java rename to src/main/java/project/trendpick_pro/domain/tags/tag/entity/dto/response/TagListResponse.java index 4b1908c1..e74274ff 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagListResponse.java +++ b/src/main/java/project/trendpick_pro/domain/tags/tag/entity/dto/response/TagListResponse.java @@ -1,7 +1,7 @@ -package project.trendpick_pro.domain.tag.entity.dto.response; +package project.trendpick_pro.domain.tags.tag.entity.dto.response; import lombok.Getter; -import project.trendpick_pro.domain.tag.entity.Tag; +import project.trendpick_pro.domain.tags.tag.entity.Tag; import java.util.List; diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagResponse.java b/src/main/java/project/trendpick_pro/domain/tags/tag/entity/dto/response/TagResponse.java similarity index 68% rename from src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagResponse.java rename to src/main/java/project/trendpick_pro/domain/tags/tag/entity/dto/response/TagResponse.java index 8403ca3d..e61ade17 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/entity/dto/response/TagResponse.java +++ b/src/main/java/project/trendpick_pro/domain/tags/tag/entity/dto/response/TagResponse.java @@ -1,4 +1,4 @@ -package project.trendpick_pro.domain.tag.entity.dto.response; +package project.trendpick_pro.domain.tags.tag.entity.dto.response; import lombok.Getter; diff --git a/src/main/java/project/trendpick_pro/domain/tag/entity/type/TagType.java b/src/main/java/project/trendpick_pro/domain/tags/tag/entity/type/TagType.java similarity index 78% rename from src/main/java/project/trendpick_pro/domain/tag/entity/type/TagType.java rename to src/main/java/project/trendpick_pro/domain/tags/tag/entity/type/TagType.java index af6beccf..04af2d0b 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/entity/type/TagType.java +++ b/src/main/java/project/trendpick_pro/domain/tags/tag/entity/type/TagType.java @@ -1,4 +1,4 @@ -package project.trendpick_pro.domain.tag.entity.type; +package project.trendpick_pro.domain.tags.tag.entity.type; public enum TagType { //타입에 따라 다른 태그점수 향상치 ORDER("ORDER"), diff --git a/src/main/java/project/trendpick_pro/domain/tag/repository/TagRepository.java b/src/main/java/project/trendpick_pro/domain/tags/tag/repository/TagRepository.java similarity index 64% rename from src/main/java/project/trendpick_pro/domain/tag/repository/TagRepository.java rename to src/main/java/project/trendpick_pro/domain/tags/tag/repository/TagRepository.java index 8b7d66e2..10c97e24 100644 --- a/src/main/java/project/trendpick_pro/domain/tag/repository/TagRepository.java +++ b/src/main/java/project/trendpick_pro/domain/tags/tag/repository/TagRepository.java @@ -1,7 +1,7 @@ -package project.trendpick_pro.domain.tag.repository; +package project.trendpick_pro.domain.tags.tag.repository; import org.springframework.data.jpa.repository.JpaRepository; -import project.trendpick_pro.domain.tag.entity.Tag; +import project.trendpick_pro.domain.tags.tag.entity.Tag; import java.util.Optional; diff --git a/src/main/java/project/trendpick_pro/domain/tags/tag/service/TagService.java b/src/main/java/project/trendpick_pro/domain/tags/tag/service/TagService.java new file mode 100644 index 00000000..995c48f6 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/tags/tag/service/TagService.java @@ -0,0 +1,31 @@ +package project.trendpick_pro.domain.tags.tag.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.tags.tag.entity.Tag; +import project.trendpick_pro.domain.tags.tag.repository.TagRepository; + +import java.util.List; + +@Service +@RequiredArgsConstructor +@Transactional(readOnly = true) +public class TagService { + + private final TagRepository tagRepository; + + public void save(String name) { + tagRepository.save(new Tag(name)); + } + + public void save(Product product, String name) { + tagRepository.save(new Tag(product, name)); + } + + public List getAllTags() { + return tagRepository.findAll(); + } + +} diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index e51638ef..32d38413 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -12,9 +12,8 @@ import project.trendpick_pro.domain.category.service.SubCategoryService; import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.product.repository.ProductRepository; -import project.trendpick_pro.domain.tag.service.TagService; +import project.trendpick_pro.domain.tags.tag.service.TagService; -import java.util.ArrayList; import java.util.List; @Configuration From c7df5d987690cbdcfc34aae67b9f5259e496f4af Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 4 Jun 2023 17:27:55 +0900 Subject: [PATCH 140/367] =?UTF-8?q?refactor:=20=EC=9C=A0=EC=A0=80=EC=9D=98?= =?UTF-8?q?=20=EC=84=A0=ED=98=B8=ED=83=9C=EA=B7=B8=EB=A5=BC=20=EA=B0=80?= =?UTF-8?q?=EC=A7=80=EA=B3=A0=20=EC=9E=88=EB=8A=94=20=EB=AA=A8=EB=93=A0=20?= =?UTF-8?q?=ED=83=9C=EA=B7=B8=EB=A5=BC=20=EB=B0=98=ED=99=98=ED=95=98?= =?UTF-8?q?=EB=8A=94=20findRecommendProduct(#106)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/ProductRepositoryCustom.java | 2 + .../repository/ProductRepositoryImpl.java | 37 +++++++-- .../product/service/ProductService.java | 83 ++++++++++--------- .../controller/RecommendController.java | 2 +- .../recommend/service/RecommendService.java | 38 ++++----- 5 files changed, 95 insertions(+), 67 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java index 4f7b2061..d3370cf7 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java @@ -4,11 +4,13 @@ import org.springframework.data.domain.Pageable; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; +import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import java.util.List; public interface ProductRepositoryCustom { public Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable); + public List findRecommendProduct(String username); public List findProductByRecommended(String username); } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index a656e939..9fb88135 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -12,8 +12,12 @@ import org.springframework.data.support.PageableExecutionUtils; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; +import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; +import project.trendpick_pro.domain.product.entity.dto.response.QProductByRecommended; import project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse; +import project.trendpick_pro.domain.tags.favoritetag.entity.QFavoriteTag; +import project.trendpick_pro.domain.tags.tag.entity.QTag; import java.util.Comparator; import java.util.List; @@ -23,10 +27,10 @@ import static project.trendpick_pro.domain.category.entity.QMainCategory.*; import static project.trendpick_pro.domain.category.entity.QSubCategory.*; import static project.trendpick_pro.domain.common.file.QCommonFile.commonFile; -import static project.trendpick_pro.domain.favoritetag.entity.QFavoriteTag.favoriteTag; import static project.trendpick_pro.domain.member.entity.QMember.*; import static project.trendpick_pro.domain.product.entity.QProduct.*; -import static project.trendpick_pro.domain.tag.entity.QTag.*; +import static project.trendpick_pro.domain.tags.favoritetag.entity.QFavoriteTag.favoriteTag; +import static project.trendpick_pro.domain.tags.tag.entity.QTag.tag; public class ProductRepositoryImpl implements ProductRepositoryCustom { @@ -77,6 +81,27 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag return PageableExecutionUtils.getPage(result, pageable, count::fetchOne); } + @Override + public List findRecommendProduct(String username) { + List list = queryFactory + .select(new QProductByRecommended( + tag.product.id, + tag.name + ) + ) + .from(tag) + .where(tag.name.in( + JPAExpressions.select(favoriteTag.name) + .from(favoriteTag) + .where(favoriteTag.member.username.eq(username)) + ) + ) + .distinct() + .fetch(); + + return list; + } + @Override public List findProductByRecommended(String username) { @@ -85,10 +110,10 @@ public List findProductByRecommended(String username) { .from(favoriteTag, product) .leftJoin(favoriteTag.member, member) .where(favoriteTag.name.in( - JPAExpressions.select(tag.name) - .from(tag) - .where(tag.product.eq(product) - )), + JPAExpressions.select(tag.name) + .from(tag) + .where(tag.product.eq(product) + )), member.username.eq(username)) .groupBy(product.id) .orderBy(favoriteTag.score.sum().desc()) diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index a25fbac3..77546c98 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -165,45 +165,46 @@ private Member CheckMember() { return member; } - public List getRecommendProduct(Member member){ -// -// List tags = productRepository.findProductByRecommended(member.getUsername()); -// List memberTags = member.getTags(); -// -// -// //태그명에 따라 가지고 있는 product_id -// // : 멤버 태그명에 따라 해당 상품에 점수를 부여해야 하기 때문에 -// Map> productIdListByTagName = new HashMap<>(); -// -// //상품 id 중복을 없애기 위함 -// //맴버의 태그명과 여러개가 겹쳐서 여러개의 추천상품이 반환되었을것 그 중복을 없애야 한다. -// Map recommendProductByProductId = new HashMap<>(); -// -// for (FavoriteTag tag : tags) { -// if(!productIdListByTagName.containsKey(tag.getName())) -// productIdListByTagName.put(tag.getName(), new ArrayList<>()); -// productIdListByTagName.get(tag.getName()).add(tag.get); -// } -// -// for (ProductByRecommended response : tags) { -// if(recommendProductByProductId.containsKey(response.getProductId())) -// continue; -// recommendProductByProductId.put(response.getProductId(), response); -// } -// -// for (FavoriteTag memberTag : memberTags) { -// if(productIdListByTagName.containsKey(memberTag.getName())){ -// List productIdList = productIdListByTagName.get(memberTag.getName()); -// for (Long id : productIdList) { -// recommendProductByProductId.get(id).plusTotalScore(memberTag.getScore()); -// } -// } -// } -// -// return new ArrayList<>(recommendProductByProductId.values()).stream() -// .sorted(Comparator.comparing(ProductByRecommended :: getTotalScore).reversed()) -// .toList(); - log.debug("member : {}", member); - return productRepository.findProductByRecommended(member.getUsername()); - } +// public List getRecommendProduct(Member member){ +//// +//// List tags = productRepository.findProductByRecommended(member.getUsername()); +//// List memberTags = member.getTags(); +//// +//// +//// //태그명에 따라 가지고 있는 product_id +//// // : 멤버 태그명에 따라 해당 상품에 점수를 부여해야 하기 때문에 +//// Map> productIdListByTagName = new HashMap<>(); +//// +//// //상품 id 중복을 없애기 위함 +//// //맴버의 태그명과 여러개가 겹쳐서 여러개의 추천상품이 반환되었을것 그 중복을 없애야 한다. +//// Map recommendProductByProductId = new HashMap<>(); +//// +//// for (FavoriteTag tag : tags) { +//// if(!productIdListByTagName.containsKey(tag.getName())) +//// productIdListByTagName.put(tag.getName(), new ArrayList<>()); +//// productIdListByTagName.get(tag.getName()).add(tag.get); +//// } +//// +//// for (ProductByRecommended response : tags) { +//// if(recommendProductByProductId.containsKey(response.getProductId())) +//// continue; +//// recommendProductByProductId.put(response.getProductId(), response); +//// } +//// +//// for (FavoriteTag memberTag : memberTags) { +//// if(productIdListByTagName.containsKey(memberTag.getName())){ +//// List productIdList = productIdListByTagName.get(memberTag.getName()); +//// for (Long id : productIdList) { +//// recommendProductByProductId.get(id).plusTotalScore(memberTag.getScore()); +//// } +//// } +//// } +//// +//// return new ArrayList<>(recommendProductByProductId.values()).stream() +//// .sorted(Comparator.comparing(ProductByRecommended :: getTotalScore).reversed()) +//// .toList(); +// log.debug("member : {}", member); +// return productRepository.findProductByRecommended(member.getUsername()); +// } + } diff --git a/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java b/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java index 3ee7050a..a1fb1efd 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java @@ -20,7 +20,7 @@ public class RecommendController { @GetMapping("/admin/caculate") public String caculate(){ - recommendService.select(); +// recommendService.select(); return "redirect:/trendpick/products/list"; } diff --git a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java index be26655f..1d2bf1cc 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java @@ -34,25 +34,25 @@ public class RecommendService { private String filePath; //recommend -> 태그 기반 추천 상품들이 있어야 함 - @Transactional - @Scheduled(cron = "0 0 4 * * *") - public void select(){ - - String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 - Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); - - recommendRepository.deleteAllByMemberId(member.getId()); - - //추천상품 ID값을 가지고 있는 ProductByRecommended 가져오기 (전달용) - List products = productService.getRecommendProduct(member); - - for (Product product : products) { - Recommend recommend = Recommend.of(product); - recommend.connectProduct(product); - recommend.connectMember(member); - recommendRepository.save(recommend); - } - } +// @Transactional +// @Scheduled(cron = "0 0 4 * * *") +// public void select(){ +// +// String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 +// Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); +// +// recommendRepository.deleteAllByMemberId(member.getId()); +// +// //추천상품 ID값을 가지고 있는 ProductByRecommended 가져오기 (전달용) +//// List products = productService.getRecommendProduct(member); +// +// for (Product product : products) { +// Recommend recommend = Recommend.of(product); +// recommend.connectProduct(product); +// recommend.connectMember(member); +// recommendRepository.save(recommend); +// } +// } public Page getFindAll(int offset){ String username = SecurityContextHolder.getContext().getAuthentication().getName(); From 00c5042fc8a9107961e0b7a3f0cc7547e860a650 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 4 Jun 2023 17:43:04 +0900 Subject: [PATCH 141/367] =?UTF-8?q?refactor:=20findRecommendProduct?= =?UTF-8?q?=EB=A1=9C=20=EC=96=BB=EC=96=B4=EC=98=A8=20=EA=B0=92=EC=9D=84=20?= =?UTF-8?q?=EC=A4=91=EB=B3=B5=EC=A0=9C=EA=B1=B0,=20=EC=B4=9D=EC=A0=90?= =?UTF-8?q?=EC=88=98=20=EA=B0=B1=EC=8B=A0,=20=EC=A0=95=EB=A0=AC=ED=95=98?= =?UTF-8?q?=EB=8A=94=20=EC=8B=A4=EC=A0=9C=20=EC=95=8C=EA=B3=A0=EB=A6=AC?= =?UTF-8?q?=EC=A6=98=20=EB=A1=9C=EC=A7=81(#106)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../repository/ProductRepositoryImpl.java | 2 +- .../product/service/ProductService.java | 87 ++++++++++--------- 2 files changed, 47 insertions(+), 42 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 9fb88135..fa96b90c 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -101,7 +101,7 @@ public List findRecommendProduct(String username) { return list; } - + @Override public List findProductByRecommended(String username) { diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 77546c98..c666bb7b 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -20,6 +20,8 @@ import project.trendpick_pro.domain.category.repository.SubCategoryRepository; import project.trendpick_pro.domain.common.base.filetranslator.FileTranslator; import project.trendpick_pro.domain.common.file.CommonFile; +import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; +import project.trendpick_pro.domain.tags.favoritetag.entity.FavoriteTag; import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.RoleType; @@ -165,46 +167,49 @@ private Member CheckMember() { return member; } -// public List getRecommendProduct(Member member){ -//// -//// List tags = productRepository.findProductByRecommended(member.getUsername()); -//// List memberTags = member.getTags(); -//// -//// -//// //태그명에 따라 가지고 있는 product_id -//// // : 멤버 태그명에 따라 해당 상품에 점수를 부여해야 하기 때문에 -//// Map> productIdListByTagName = new HashMap<>(); -//// -//// //상품 id 중복을 없애기 위함 -//// //맴버의 태그명과 여러개가 겹쳐서 여러개의 추천상품이 반환되었을것 그 중복을 없애야 한다. -//// Map recommendProductByProductId = new HashMap<>(); -//// -//// for (FavoriteTag tag : tags) { -//// if(!productIdListByTagName.containsKey(tag.getName())) -//// productIdListByTagName.put(tag.getName(), new ArrayList<>()); -//// productIdListByTagName.get(tag.getName()).add(tag.get); -//// } -//// -//// for (ProductByRecommended response : tags) { -//// if(recommendProductByProductId.containsKey(response.getProductId())) -//// continue; -//// recommendProductByProductId.put(response.getProductId(), response); -//// } -//// -//// for (FavoriteTag memberTag : memberTags) { -//// if(productIdListByTagName.containsKey(memberTag.getName())){ -//// List productIdList = productIdListByTagName.get(memberTag.getName()); -//// for (Long id : productIdList) { -//// recommendProductByProductId.get(id).plusTotalScore(memberTag.getScore()); -//// } -//// } -//// } -//// -//// return new ArrayList<>(recommendProductByProductId.values()).stream() -//// .sorted(Comparator.comparing(ProductByRecommended :: getTotalScore).reversed()) -//// .toList(); -// log.debug("member : {}", member); -// return productRepository.findProductByRecommended(member.getUsername()); -// } + public List getRecommendProduct(Member member){ + + List tags = productRepository.findRecommendProduct(member.getUsername()); + Set memberTags = member.getTags(); + + + //태그명에 따라 가지고 있는 product_id + // : 멤버 태그명에 따라 해당 상품에 점수를 부여해야 하기 때문에 + Map> productIdListByTagName = new HashMap<>(); + + //상품 id 중복을 없애기 위함 + //맴버의 태그명과 여러개가 겹쳐서 여러개의 추천상품이 반환되었을것 그 중복을 없애야 한다. + Map recommendProductByProductId = new HashMap<>(); + + //같은 태그명을 가지고 있지만 제각각 상품을 가르키는 productId는 다를 것이다. 그래서 태그명 별로 어떤 상품들을 가르키는지 모아보자 + for (ProductByRecommended tag : tags) { + if(!productIdListByTagName.containsKey(tag.getTagName())) + productIdListByTagName.put(tag.getTagName(), new ArrayList<>()); + productIdListByTagName.get(tag.getTagName()).add(tag.getProductId()); + } + + //마찬가지로 같은 상품을 가르키고 있지만 태그명은 제각각일 것이다. 우리가 뽑아내길 원하는 것은 추천상품이다. 즉 같은 상품이 중복되면 안된다. + //그래서 상품Id에 대한 중복을 없애서 하나에 몰아넣는 코드이다. + for (ProductByRecommended response : tags) { + if(recommendProductByProductId.containsKey(response.getProductId())) + continue; + recommendProductByProductId.put(response.getProductId(), response); + } + + //실제로직! member 선호태그에는 점수가 있을 것이다. + //그러니까 우리가 반환하려고 하는 추천상품이 점수가 몇점인지 갱신하는 코드이다. + for (FavoriteTag memberTag : memberTags) { + if(productIdListByTagName.containsKey(memberTag.getName())){ + List productIdList = productIdListByTagName.get(memberTag.getName()); + for (Long id : productIdList) { + recommendProductByProductId.get(id).plusTotalScore(memberTag.getScore()); + } + } + } + + return new ArrayList<>(recommendProductByProductId.values()).stream() + .sorted(Comparator.comparing(ProductByRecommended :: getTotalScore).reversed()) + .toList(); + } } From 92d72a800fafb9882a1f724819ab915a1b6b0e15 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 4 Jun 2023 18:04:21 +0900 Subject: [PATCH 142/367] =?UTF-8?q?refactor:=20=EC=B6=94=EC=B2=9C=20?= =?UTF-8?q?=EC=95=8C=EA=B3=A0=EB=A6=AC=EC=A6=98=EC=9D=84=20=ED=86=B5?= =?UTF-8?q?=ED=95=B4=20=EC=96=BB=EC=9D=80=20=EA=B0=92=EC=9D=84=20List=EB=A1=9C=20=EB=B3=80=ED=99=98=ED=95=98=EC=97=AC=20?= =?UTF-8?q?=EB=B0=98=ED=99=98=ED=95=98=EB=8F=84=EB=A1=9D=20=EC=88=98?= =?UTF-8?q?=EC=A0=95(#106)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/service/ProductService.java | 17 ++++++-- .../recommend/service/RecommendService.java | 40 ++++++++++--------- 2 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index c666bb7b..f9de10fa 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -21,6 +21,7 @@ import project.trendpick_pro.domain.common.base.filetranslator.FileTranslator; import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; +import project.trendpick_pro.domain.product.exception.ProductNotFoundException; import project.trendpick_pro.domain.tags.favoritetag.entity.FavoriteTag; import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; import project.trendpick_pro.domain.member.entity.Member; @@ -167,7 +168,7 @@ private Member CheckMember() { return member; } - public List getRecommendProduct(Member member){ + public List getRecommendProduct(Member member){ List tags = productRepository.findRecommendProduct(member.getUsername()); Set memberTags = member.getTags(); @@ -207,9 +208,19 @@ public List getRecommendProduct(Member member){ } } - return new ArrayList<>(recommendProductByProductId.values()).stream() - .sorted(Comparator.comparing(ProductByRecommended :: getTotalScore).reversed()) + List recommendProductList = new ArrayList<>(recommendProductByProductId.values()).stream() + .sorted(Comparator.comparing(ProductByRecommended::getTotalScore).reversed()) .toList(); + + //Product 변환해서 리턴 + List products = new ArrayList<>(); + for(ProductByRecommended recommendProduct : recommendProductList){ + products.add(productRepository.findById(recommendProduct.getProductId()).orElseThrow( + () -> new ProductNotFoundException("존재하지 않는 상품입니다.") + )); + } + + return products; } } diff --git a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java index 1d2bf1cc..fdde7864 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java @@ -14,11 +14,14 @@ import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.product.entity.Product; +import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; +import project.trendpick_pro.domain.product.exception.ProductNotFoundException; import project.trendpick_pro.domain.product.service.ProductService; import project.trendpick_pro.domain.recommend.entity.Recommend; import project.trendpick_pro.domain.recommend.repository.RecommendRepository; +import java.util.ArrayList; import java.util.List; @Slf4j @@ -34,25 +37,24 @@ public class RecommendService { private String filePath; //recommend -> 태그 기반 추천 상품들이 있어야 함 -// @Transactional -// @Scheduled(cron = "0 0 4 * * *") -// public void select(){ -// -// String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 -// Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); -// -// recommendRepository.deleteAllByMemberId(member.getId()); -// -// //추천상품 ID값을 가지고 있는 ProductByRecommended 가져오기 (전달용) -//// List products = productService.getRecommendProduct(member); -// -// for (Product product : products) { -// Recommend recommend = Recommend.of(product); -// recommend.connectProduct(product); -// recommend.connectMember(member); -// recommendRepository.save(recommend); -// } -// } + @Transactional + @Scheduled(cron = "0 0 4 * * *") + public void select(){ + + String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 + Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); + + recommendRepository.deleteAllByMemberId(member.getId()); + + List products = productService.getRecommendProduct(member); + + for (Product product : products) { + Recommend recommend = Recommend.of(product); + recommend.connectProduct(product); + recommend.connectMember(member); + recommendRepository.save(recommend); + } + } public Page getFindAll(int offset){ String username = SecurityContextHolder.getContext().getAuthentication().getName(); From b81f28b7176842a74cb1a06515d034991e55789e Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 4 Jun 2023 19:22:08 +0900 Subject: [PATCH 143/367] =?UTF-8?q?fix:=20=EC=96=91=EB=B0=A9=ED=96=A5?= =?UTF-8?q?=EA=B4=80=EA=B3=84=EC=97=90=EC=84=9C=20cascade=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95=ED=95=9C=20=EB=B6=80=EB=AA=A8=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=EC=A0=80=EC=9E=A5=ED=96=88=EC=9D=84=20=EB=95=8C,?= =?UTF-8?q?=20=EC=9E=90=EC=8B=9D=EC=97=94=ED=8B=B0=ED=8B=B0=EA=B0=80=20?= =?UTF-8?q?=EC=9E=90=EB=8F=99=EC=A0=80=EC=9E=A5=EC=9D=B4=20=EC=95=88?= =?UTF-8?q?=EB=90=98=EB=8A=94=20=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95(#1?= =?UTF-8?q?06)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../answer/controller/AnswerController.java | 1 - .../domain/member/entity/Member.java | 8 ++ .../domain/member/service/MemberService.java | 5 +- .../domain/product/entity/Product.java | 5 + .../tags/favoritetag/entity/FavoriteTag.java | 6 +- .../service/FavoriteTagService.java | 4 +- .../domain/tags/tag/entity/Tag.java | 6 +- .../domain/tags/tag/service/TagService.java | 5 - .../global/basedata/BaseData.java | 101 ++++++++++-------- 9 files changed, 81 insertions(+), 60 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java index cdcd7ebd..a126c9b5 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java +++ b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java @@ -10,7 +10,6 @@ import project.trendpick_pro.domain.answer.service.AnswerService; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.member.entity.RoleType; @Controller @RequiredArgsConstructor diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index adb1b4be..5073d5dc 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -59,5 +59,13 @@ public void connectBank(String bankName, String bankAccount) { public void changeTags(Set tags) { this.tags = tags; + for(FavoriteTag tag : tags) + tag.connectMember(this); + } + + //양방향 메서드 + public void addTag(FavoriteTag tag){ + getTags().add(tag); + tag.connectMember(this); } } diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index 14b44f0e..d4e62cd4 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -61,7 +61,7 @@ public void register(JoinForm joinForm) { for (String tag : joinForm.tags()) { // Tag findTag = tagRepository.findByName(tag).orElseThrow(); // favoriteTag.connectMember(member); - FavoriteTag favoriteTag = new FavoriteTag(member, tag); + FavoriteTag favoriteTag = new FavoriteTag(tag); favoriteTags.add(favoriteTag); } member.changeTags(favoriteTags); @@ -75,9 +75,10 @@ public void manageTag(String username, TagRequest tagRequest){ Set tags = new LinkedHashSet<>(); for (String tag : tagRequest.getTags()) { + //기존에 선택했던 태그들에 대한 가중치를 마이너스 (만약 0점 이하로 떨어지면 삭제) // Tag tag = tagRepository.findByName(s).orElseThrow(); // favoriteTag.connectMember(member); - FavoriteTag favoriteTag = new FavoriteTag(member, tag); + FavoriteTag favoriteTag = new FavoriteTag(tag); tags.add(favoriteTag); } member.changeTags(tags); diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index 898916ab..bd345c12 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -123,4 +123,9 @@ public String toString() { ", stock=" + stock + '}'; } + + public void addTag(Tag tag){ + getTags().add(tag); + tag.connectProduct(this); + } } diff --git a/src/main/java/project/trendpick_pro/domain/tags/favoritetag/entity/FavoriteTag.java b/src/main/java/project/trendpick_pro/domain/tags/favoritetag/entity/FavoriteTag.java index 1a2701f9..325444f0 100644 --- a/src/main/java/project/trendpick_pro/domain/tags/favoritetag/entity/FavoriteTag.java +++ b/src/main/java/project/trendpick_pro/domain/tags/favoritetag/entity/FavoriteTag.java @@ -23,8 +23,12 @@ public class FavoriteTag { @JoinColumn(name = "member_id") private Member member; - public FavoriteTag(Member member, String name) { + public FavoriteTag(String name) { this.name = name; + } + + //양방향 메서드 + public void connectMember(Member member){ this.member = member; } diff --git a/src/main/java/project/trendpick_pro/domain/tags/favoritetag/service/FavoriteTagService.java b/src/main/java/project/trendpick_pro/domain/tags/favoritetag/service/FavoriteTagService.java index 7b5b810b..688ed260 100644 --- a/src/main/java/project/trendpick_pro/domain/tags/favoritetag/service/FavoriteTagService.java +++ b/src/main/java/project/trendpick_pro/domain/tags/favoritetag/service/FavoriteTagService.java @@ -39,9 +39,9 @@ public void updateTag(Member member, Product product, TagType type) { } } if(!hasTag){ //태그를 가지고 있지 않다면 추가해준다. - FavoriteTag favoriteTag = new FavoriteTag(member, tagByProduct.getName()); + FavoriteTag favoriteTag = new FavoriteTag(tagByProduct.getName()); favoriteTag.increaseScore(type); - tags.add(favoriteTag); + member.addTag(favoriteTag); } } } diff --git a/src/main/java/project/trendpick_pro/domain/tags/tag/entity/Tag.java b/src/main/java/project/trendpick_pro/domain/tags/tag/entity/Tag.java index 62ed6b67..42090fc5 100644 --- a/src/main/java/project/trendpick_pro/domain/tags/tag/entity/Tag.java +++ b/src/main/java/project/trendpick_pro/domain/tags/tag/entity/Tag.java @@ -17,12 +17,8 @@ public class Tag { public Tag(String name) { this.name = name; } - public Tag(Product product, String name) { - this.name = name; - this.product = product; - } - public void connectProduct(Product product) { + public void connectProduct(Product product){ this.product = product; } diff --git a/src/main/java/project/trendpick_pro/domain/tags/tag/service/TagService.java b/src/main/java/project/trendpick_pro/domain/tags/tag/service/TagService.java index 995c48f6..abf38a3c 100644 --- a/src/main/java/project/trendpick_pro/domain/tags/tag/service/TagService.java +++ b/src/main/java/project/trendpick_pro/domain/tags/tag/service/TagService.java @@ -3,7 +3,6 @@ import lombok.RequiredArgsConstructor; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.tags.tag.entity.Tag; import project.trendpick_pro.domain.tags.tag.repository.TagRepository; @@ -20,10 +19,6 @@ public void save(String name) { tagRepository.save(new Tag(name)); } - public void save(Product product, String name) { - tagRepository.save(new Tag(product, name)); - } - public List getAllTags() { return tagRepository.findAll(); } diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index 32d38413..011fb4e4 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -10,11 +10,19 @@ import project.trendpick_pro.domain.category.entity.MainCategory; import project.trendpick_pro.domain.category.service.MainCategoryService; import project.trendpick_pro.domain.category.service.SubCategoryService; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.entity.RoleType; import project.trendpick_pro.domain.member.repository.MemberRepository; +import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; +import project.trendpick_pro.domain.tags.favoritetag.entity.FavoriteTag; +import project.trendpick_pro.domain.tags.tag.entity.Tag; +import project.trendpick_pro.domain.tags.tag.entity.type.TagType; import project.trendpick_pro.domain.tags.tag.service.TagService; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Set; @Configuration @Profile({"dev", "test"}) @@ -45,9 +53,10 @@ CommandLineRunner initData( @Override @Transactional public void run(String... args) { - for (String tag : tags) { - tagService.save(tag); - } + //원활한 테스트를 위해 잠깐 주석처리 +// for (String tag : tags) { +// tagService.save(tag); +// } for (String mainCategory : mainCategories) { mainCategoryService.save(mainCategory); @@ -62,49 +71,53 @@ public void run(String... args) { brandService.save(brand); } - //member1은 태그1, 태그2, 태그3 을 각각 10점 5점 1점 가지고 있다 - //상품1은 태그1을 가지고 있다 - //상품2는 태그1, 태그2를 가지고 있다 - //상품3은 태그1, 태그2 태그3 모두 가지고 있다. -// -// Member member1 = memberRepository.save(Member.builder().username("member1").build()); -// Product product1 = Product.builder().name("상품1").build(); -// Product product2 = Product.builder().name("상품2").build(); -// Product product3 = Product.builder().name("상품3").build(); -// Product product4 = Product.builder().name("상품4").build(); -// productRepository.save(product1); -// productRepository.save(product2); -// productRepository.save(product3); -// productRepository.save(product4); -// +// member1은 시티보이룩(10점), 빈티지룩(5점), 로멘틱룩(1점)을 선호 태그로 가지고 있다. +// 상품1은 시티보이룩을 가지고 있다 +// 상품2는 시티보이룩, 빈티지룩을 가지고 있다 +// 상품3은 시티보이룩, 빈티지룩, 로멘틱룩을 모두 가지고 있다. // -// Tag tag1 = new Tag("태그1", member1); -// tag1.changeScore(10); -// tagRepository.save(tag1); -// Tag tag2 = new Tag("태그2", member1); -// tag2.changeScore(5); -// tagRepository.save(tag2); -// Tag tag3 = new Tag("태그3", member1); -// tag3.changeScore(1); -// tagRepository.save(tag3); -// -// //상품1은 태그1을 가지고 있다 -// Tag tag1ByProduct1 = new Tag("태그1", product1); -// tagRepository.save(tag1ByProduct1); -// -// //상품2는 태그1, 태그2를 가지고 있다 -// Tag tag2ByProduct1 = new Tag("태그1", product2); -// Tag tag2ByProduct2 = new Tag("태그2", product2); -// tagRepository.save(tag2ByProduct1); -// tagRepository.save(tag2ByProduct2); + Member member1 = memberRepository.save(Member.builder().username("member1").email("jjj@naver.com").phoneNumber("01099999999").role(RoleType.MEMBER).password("111111").build()); + FavoriteTag favorTag1 = new FavoriteTag("시티보이룩"); + favorTag1.increaseScore(TagType.ORDER);//주문해서 10점 누적. + member1.addTag(favorTag1); + + FavoriteTag favorTag2 = new FavoriteTag("빈티지룩"); + favorTag2.increaseScore(TagType.CART);//장바구니 담아서 5점 누적. + member1.addTag(favorTag2); + + FavoriteTag favorTag3 = new FavoriteTag("로멘틱룩"); + favorTag3.increaseScore(TagType.ORDER);//상품 클릭해서 1점 누적. + member1.addTag(favorTag3); + +// 상품1은 시티보이룩을 가지고 있다 + Set tags1 = new LinkedHashSet<>(); + Product product1 = Product.builder().name("상품1").tags(tags1).description("설명1").price(500).stock(100).build(); + product1.addTag(new Tag("시티보이룩")); + +// 상품2는 시티보이룩, 빈티지룩을 가지고 있다 + Set tags2 = new LinkedHashSet<>(); + Product product2 = Product.builder().name("상품2").tags(tags2).description("설명2").price(500).stock(100).build(); + product2.addTag(new Tag("시티보이룩")); + product2.addTag(new Tag("빈지티룩")); + + Set tags3 = new LinkedHashSet<>(); + Product product3 = Product.builder().name("상품3").tags(tags3).description("설명3").price(500).stock(100).build(); + product3.addTag(new Tag("시티보이룩")); + product3.addTag(new Tag("빈지티룩")); + product3.addTag(new Tag("로멘틱룩")); + productRepository.save(product1); + productRepository.save(product2); + productRepository.save(product3); + +// 상품3은 시티보이룩, 빈티지룩, 로멘틱룩을 모두 가지고 있다. +// Set tags3 = new LinkedHashSet<>(); +// tags3.add(new Tag("시티보이룩")); +// tags3.add(new Tag("빈티지룩")); +// tags3.add(new Tag("로멘틱룩")); +// Product product3 = Product.builder().name("상품3").tags(tags3).description("설명3").price(500).stock(100).build(); // -// //상품3은 태그1, 태그2 태그3 모두 가지고 있다. -// Tag tag3ByProduct1 = new Tag("태그1", product3); -// Tag tag3ByProduct2 = new Tag("태그2", product3); -// Tag tag3ByProduct3 = new Tag("태그3", product3); -// tagRepository.save(tag3ByProduct1); -// tagRepository.save(tag3ByProduct2); -// tagRepository.save(tag3ByProduct3); + +// T } }; } From 1ea5b72e220ffae2eb2db86fa87a0a0ed844aed2 Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Sun, 4 Jun 2023 19:50:04 +0900 Subject: [PATCH 144/367] =?UTF-8?q?refactor:=20Cart=20=EB=B6=88=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EB=B6=80=EB=B6=84=20=EC=82=AD=EC=A0=9C=20?= =?UTF-8?q?=EB=B0=8F=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cart/controller/CartController.java | 16 +++---- .../domain/cart/entity/Cart.java | 25 ++++++----- .../domain/cart/entity/CartItem.java | 27 +++++++----- .../entity/dto/request/CartItemRequest.java | 13 +++--- .../entity/dto/response/CartItemResponse.java | 40 ----------------- .../cart/repository/CartItemRepository.java | 1 + .../domain/cart/service/CartService.java | 43 ++++++++++++------- .../templates/trendpick/usr/cart/list.html | 0 8 files changed, 71 insertions(+), 94 deletions(-) delete mode 100644 src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java create mode 100644 src/main/resources/templates/trendpick/usr/cart/list.html diff --git a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java index da937704..4f753e2a 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java +++ b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java @@ -1,18 +1,18 @@ package project.trendpick_pro.domain.cart.controller; +import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.*; import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RequestMapping; import project.trendpick_pro.domain.cart.entity.Cart; +import project.trendpick_pro.domain.cart.entity.dto.request.CartItemRequest; import project.trendpick_pro.domain.cart.service.CartService; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.orders.entity.dto.request.OrderSaveRequest; import java.util.List; @@ -33,11 +33,9 @@ public String showCart(Model model) { } @PreAuthorize("isAuthenticated()") - @PostMapping("/add") - public String addItemToCart(@RequestParam("productOptionId") Long productOptionId, - @RequestParam("count") int count) { - Member member = rq.getMember(); - cartService.addItemToCart(member, productOptionId, count); + @GetMapping("/add/{productId}") + public String addItemToCart(@PathVariable("productId") Long productId, @Valid CartItemRequest cartItemRequests) { + cartService.addItemToCart(rq.getMember(),productId,cartItemRequests); // 쇼핑을 계속 하시겠습니까? 띄우고 yes이면 main no면 cart로 return "redirect:/trendprick/list"; } diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java index c1076e12..8c9b1445 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java @@ -6,6 +6,7 @@ import lombok.NoArgsConstructor; import lombok.Setter; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.ProductOption; import java.util.ArrayList; @@ -35,6 +36,13 @@ public class Cart { // 총 가격 필드 private int totalPrice; + public static Cart createCart(Member member){ + Cart cart = new Cart(); + cart.member= member; + cart.totalCount = 0; + return cart; + } + public Cart(Member member) { this.member = member; } @@ -73,19 +81,10 @@ private CartItem findCartItemById(Long cartItemId) { } private void updateTotalCountAndPrice() { - totalCount = cartItems.stream() - .mapToInt(CartItem::getCount) - .sum(); - - totalPrice = cartItems.stream() - .mapToInt(CartItem::getPrice) - .sum(); + for(CartItem cartItem:cartItems){ + totalPrice+=(cartItem.getProduct().getPrice()*cartItem.getCount()); + } } - public CartItem findCartItemByProductOption(ProductOption productOption) { - return cartItems.stream() - .filter(item -> item.getProductOption().equals(productOption)) - .findFirst() - .orElse(null); - } + } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java index 4ad55e8e..1cb4a9af 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java @@ -2,6 +2,8 @@ import jakarta.persistence.*; import lombok.*; +import project.trendpick_pro.domain.cart.entity.dto.request.CartItemRequest; +import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.ProductOption; import project.trendpick_pro.domain.tag.entity.Tag; @@ -23,19 +25,24 @@ public class CartItem { @JoinColumn(name = "cart_id") private Cart cart; @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "product_option_id") - private ProductOption productOption; + @JoinColumn(name = "product_id") + private Product product; + private String color; // 해당 상품 색상 + private String size; // 해당 상품 사이즈 private int count; // 해당 상품 수량 - private int price; // 해당 상품 금액 - @Builder - public CartItem(Cart cart, ProductOption productOption, int count) { - this.cart = cart; - this.productOption = productOption; - this.count = count; - this.price = productOption.getProduct().getPrice(); + public static CartItem createCartItem(Cart cart, Product product, CartItemRequest cartItemRequest){ + CartItem cartItem = new CartItem(); + cartItem.setCart(cart); + cartItem.setProduct(product); + cartItem.setColor(cartItemRequest.getColor()); + cartItem.setSize(cartItemRequest.getSize()); + cartItem.setCount(cartItemRequest.getCount()); + return cartItem; + } + public void addCount(int count){ + this.count += count; } - } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java index bf032f6b..895f4353 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java @@ -1,15 +1,16 @@ package project.trendpick_pro.domain.cart.entity.dto.request; -import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotBlank; import lombok.Getter; @Getter public class CartItemRequest { - @NotBlank - private Long cartId; - @NotBlank - private Long productOptionId; - @Min(1) + @NotBlank(message = "해당 상품의 색상을 입력해주세요.") + private String color; + + @NotBlank(message ="해당 상품의 사이즈를 입력해주세요.") + private String size; + @NotBlank(message = "해당 상품 수량을 입력해주세요.") private int count; + } diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java deleted file mode 100644 index fd0a624c..00000000 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java +++ /dev/null @@ -1,40 +0,0 @@ -package project.trendpick_pro.domain.cart.entity.dto.response; - -import com.querydsl.core.annotations.QueryProjection; -import lombok.Builder; -import lombok.Getter; -import project.trendpick_pro.domain.cart.entity.CartItem; - - - -@Getter -public class CartItemResponse { - private Long id; - - private Long cartId; - - private Long productOptionId; - private int count; // 해당 상품 수량 - - private int price; // 해당 상품 금액; - - @Builder - @QueryProjection - public CartItemResponse(Long id, Long cartId, Long productOptionId, int count, int price) { - this.id = id; - this.cartId = cartId; - this.productOptionId = productOptionId; - this.count = count; - this.price = price; - } - - public static CartItemResponse of (CartItem cartItem) { - return CartItemResponse.builder() - .id(cartItem.getId()) - .cartId(cartItem.getCart().getId()) - .productOptionId(cartItem.getProductOption().getId()) - .count(cartItem.getCount()) - .price(cartItem.getPrice()) - .build(); - } -} diff --git a/src/main/java/project/trendpick_pro/domain/cart/repository/CartItemRepository.java b/src/main/java/project/trendpick_pro/domain/cart/repository/CartItemRepository.java index 034fa1fe..32eee117 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/repository/CartItemRepository.java +++ b/src/main/java/project/trendpick_pro/domain/cart/repository/CartItemRepository.java @@ -4,4 +4,5 @@ import project.trendpick_pro.domain.cart.entity.CartItem; public interface CartItemRepository extends JpaRepository { + CartItem findByCartIdAndProductId(Long cartId, long ProductId); } diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index 3bfccc49..00f51d83 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -5,13 +5,19 @@ import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.cart.entity.Cart; import project.trendpick_pro.domain.cart.entity.CartItem; +import project.trendpick_pro.domain.cart.entity.dto.request.CartItemRequest; +import project.trendpick_pro.domain.cart.entity.dto.request.CartRequest; +import project.trendpick_pro.domain.cart.repository.CartItemRepository; import project.trendpick_pro.domain.cart.repository.CartRepository; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.orders.entity.OrderItem; +import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.ProductOption; +import project.trendpick_pro.domain.product.exception.ProductNotFoundException; import project.trendpick_pro.domain.product.repository.ProductOptionRepository; +import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tag.entity.Tag; import project.trendpick_pro.domain.tag.entity.type.TagType; import project.trendpick_pro.domain.tag.service.TagService; @@ -27,32 +33,37 @@ public class CartService { private final CartRepository cartRepository; private final MemberRepository memberRepository; private final ProductOptionRepository productOptionRepository; + private final ProductRepository productRepository; + private final CartItemRepository cartItemRepository; private final TagService tagService; public List findByCartMember(Member member){ return cartRepository.findByCartMember(member); } - - public Cart createCart(Member member) { - Cart cart = new Cart(member); - return cartRepository.save(cart); - } @Transactional - public void addItemToCart(Member member, Long productOptionId, int count) { - Cart cart = getCartByUser(member); - ProductOption productOption = getProductOptionById(productOptionId); - CartItem cartItem = cart.findCartItemByProductOption(productOption); + public void addItemToCart(Member member, Long productId, CartItemRequest cartItemRequest) { + member=memberRepository.findById(member.getId()).orElseThrow(()->new MemberNotFoundException("존재하지 않는 유저입니다.")); + Cart cart = cartRepository.findByMemberId(member.getId()); + Product product=productRepository.findById(productId).orElseThrow(() -> new ProductNotFoundException("존재하지 않는 상품 입니다.")); + + if(cart==null){ + // 장바구니가 비어있다면 생성 + cart=Cart.createCart(member); + cartRepository.save(cart); + } + CartItem cartItem = cartItemRepository.findByCartIdAndProductId(cart.getId(), product.getId()); - tagService.updateTag(member, productOption.getProduct(), TagType.CART); //장바구니에 넣었으니 해당 상품이 가진 태그점수 올리기 + tagService.updateTag(member, product, TagType.CART); //장바구니에 넣었으니 해당 상품이 가진 태그점수 올리기 if (cartItem != null) { // 이미 카트에 해당 상품이 존재하는 경우, 수량을 증가 - cartItem.setCount(cartItem.getCount() + count); + cartItem.addCount(cartItem.getCount()); } else { // 카트에 해당 상품이 없는 경우, 새로운 카트 아이템을 생성하여 추가 - cartItem = new CartItem(cart, productOption, count); - cart.addItem(cartItem); + cartItem =CartItem.createCartItem(cart,product,cartItemRequest); + cartItemRepository.save(cartItem); + cart.setTotalCount(cart.getTotalCount()+1); } } @@ -72,8 +83,8 @@ public Cart getCartByUser(Member member) { return cartRepository.findByMemberId(member.getId()); } - private ProductOption getProductOptionById(Long productOptionId) { - return productOptionRepository.findById(productOptionId) - .orElseThrow(() -> new IllegalArgumentException("Product option not found")); + private Product getProductById(Long productId){ + return productRepository.findById(productId) + .orElseThrow(() -> new IllegalArgumentException("해당 상품을 찾을 수 없습니다.")); } } diff --git a/src/main/resources/templates/trendpick/usr/cart/list.html b/src/main/resources/templates/trendpick/usr/cart/list.html new file mode 100644 index 00000000..e69de29b From afa04d5f3ad9caf750254a3810caad1959ddbc11 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 4 Jun 2023 20:13:56 +0900 Subject: [PATCH 145/367] =?UTF-8?q?test:=20=EC=B6=94=EC=B2=9C=20=EC=95=8C?= =?UTF-8?q?=EA=B3=A0=EB=A6=AC=EC=A6=98=20=EB=A1=9C=EC=A7=81=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EB=A5=BC=20=EC=9C=84=ED=95=9C=20=EC=84=B8?= =?UTF-8?q?=ED=8C=85(#106)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 39 +++++++++++++++ .../product/service/ProductService.java | 50 ++++++++++++++++++- .../global/basedata/BaseData.java | 18 +++++-- 3 files changed, 102 insertions(+), 5 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 033090d2..16ad1aa5 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -1,5 +1,6 @@ package project.trendpick_pro.domain.product.controller; +import io.swagger.v3.core.util.Json; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; @@ -12,14 +13,21 @@ import project.trendpick_pro.domain.brand.service.BrandService; import project.trendpick_pro.domain.category.service.MainCategoryService; import project.trendpick_pro.domain.category.service.SubCategoryService; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.repository.MemberRepository; +import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; +import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; import project.trendpick_pro.domain.product.service.ProductService; import project.trendpick_pro.domain.recommend.service.RecommendService; import project.trendpick_pro.domain.tags.tag.service.TagService; import java.io.IOException; +import java.util.HashMap; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; @Slf4j @Controller @@ -34,6 +42,7 @@ public class ProductController { private final SubCategoryService subCategoryService; private final BrandService brandService; private final RecommendService recommendService; + private final MemberRepository memberRepository; @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") @GetMapping("/register") @@ -98,4 +107,34 @@ public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") i model.addAttribute("productResponses", productService.showAll(offset, mainCategory, subCategory, sortCode)); } return "/trendpick/products/list"; } + + //테스트용 + @GetMapping("/test1") + @ResponseBody + public List showTest1(){ + Member member = memberRepository.findById(1L).orElseThrow(); + return productService.getRecommendProductTest1(member); + } + + @GetMapping("/test2") + @ResponseBody + public List showTest2(){ + Member member = memberRepository.findById(1L).orElseThrow(); + return productService.getRecommendProductTest2(member); + } + + @GetMapping("/test3") + @ResponseBody + public Map showTest3(){ + Member member = memberRepository.findById(1L).orElseThrow(); + Map testMap = new LinkedHashMap<>(); + + List products = productService.getRecommendProduct(member); + + for (Product product : products) { + testMap.put(product.getId(), product.getName()+" "+product.getPrice()+" "+product.getStock()); + } + + return testMap; + } } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index f9de10fa..b6dca783 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -219,8 +219,56 @@ public List getRecommendProduct(Member member){ () -> new ProductNotFoundException("존재하지 않는 상품입니다.") )); } - return products; } + public List getRecommendProductTest1(Member member) { + return productRepository.findRecommendProduct(member.getUsername()); + } + + public List getRecommendProductTest2(Member member){ + + List tags = productRepository.findRecommendProduct(member.getUsername()); + Set memberTags = member.getTags(); + + //태그명에 따라 가지고 있는 product_id + // : 멤버 태그명에 따라 해당 상품에 점수를 부여해야 하기 때문에 + Map> productIdListByTagName = new HashMap<>(); + + //상품 id 중복을 없애기 위함 + //맴버의 태그명과 여러개가 겹쳐서 여러개의 추천상품이 반환되었을것 그 중복을 없애야 한다. + Map recommendProductByProductId = new HashMap<>(); + + //같은 태그명을 가지고 있지만 제각각 상품을 가르키는 productId는 다를 것이다. 그래서 태그명 별로 어떤 상품들을 가르키는지 모아보자 + for (ProductByRecommended tag : tags) { + if(!productIdListByTagName.containsKey(tag.getTagName())) + productIdListByTagName.put(tag.getTagName(), new ArrayList<>()); + productIdListByTagName.get(tag.getTagName()).add(tag.getProductId()); + } + + //마찬가지로 같은 상품을 가르키고 있지만 태그명은 제각각일 것이다. 우리가 뽑아내길 원하는 것은 추천상품이다. 즉 같은 상품이 중복되면 안된다. + //그래서 상품Id에 대한 중복을 없애서 하나에 몰아넣는 코드이다. + for (ProductByRecommended response : tags) { + if(recommendProductByProductId.containsKey(response.getProductId())) + continue; + recommendProductByProductId.put(response.getProductId(), response); + } + + //실제로직! member 선호태그에는 점수가 있을 것이다. + //그러니까 우리가 반환하려고 하는 추천상품이 점수가 몇점인지 갱신하는 코드이다. + for (FavoriteTag memberTag : memberTags) { + if(productIdListByTagName.containsKey(memberTag.getName())){ + List productIdList = productIdListByTagName.get(memberTag.getName()); + for (Long id : productIdList) { + recommendProductByProductId.get(id).plusTotalScore(memberTag.getScore()); + } + } + } + + List recommendProductList = new ArrayList<>(recommendProductByProductId.values()).stream() + .sorted(Comparator.comparing(ProductByRecommended::getTotalScore).reversed()) + .toList(); + return recommendProductList; + } + } diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index 011fb4e4..12a31e48 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -78,7 +78,7 @@ public void run(String... args) { // Member member1 = memberRepository.save(Member.builder().username("member1").email("jjj@naver.com").phoneNumber("01099999999").role(RoleType.MEMBER).password("111111").build()); FavoriteTag favorTag1 = new FavoriteTag("시티보이룩"); - favorTag1.increaseScore(TagType.ORDER);//주문해서 10점 누적. + favorTag1.increaseScore(TagType.SHOW);//상품클릭해서 1점 누적. member1.addTag(favorTag1); FavoriteTag favorTag2 = new FavoriteTag("빈티지룩"); @@ -86,7 +86,7 @@ public void run(String... args) { member1.addTag(favorTag2); FavoriteTag favorTag3 = new FavoriteTag("로멘틱룩"); - favorTag3.increaseScore(TagType.ORDER);//상품 클릭해서 1점 누적. + favorTag3.increaseScore(TagType.ORDER);//상품 주문해서 10점 누적. member1.addTag(favorTag3); // 상품1은 시티보이룩을 가지고 있다 @@ -98,17 +98,27 @@ public void run(String... args) { Set tags2 = new LinkedHashSet<>(); Product product2 = Product.builder().name("상품2").tags(tags2).description("설명2").price(500).stock(100).build(); product2.addTag(new Tag("시티보이룩")); - product2.addTag(new Tag("빈지티룩")); + product2.addTag(new Tag("빈티지룩")); Set tags3 = new LinkedHashSet<>(); Product product3 = Product.builder().name("상품3").tags(tags3).description("설명3").price(500).stock(100).build(); product3.addTag(new Tag("시티보이룩")); - product3.addTag(new Tag("빈지티룩")); + product3.addTag(new Tag("빈티지룩")); product3.addTag(new Tag("로멘틱룩")); productRepository.save(product1); productRepository.save(product2); productRepository.save(product3); + Set tags4 = new LinkedHashSet<>(); + Product product4 = Product.builder().name("상품4").tags(tags4).description("설명4").price(500).stock(100).build(); + product4.addTag(new Tag("원숭이룩")); + productRepository.save(product1); + productRepository.save(product2); + productRepository.save(product3); + productRepository.save(product4); + //member1의 추천상품을 가져오면 로멘틱룩, 빈티지룩, 시티보이룩 순서대로 가져와야 한다. + //상품 4는 member의 선호태그를 가지고 있지 않으므로 추천되지 않아야 한다. + // 상품3은 시티보이룩, 빈티지룩, 로멘틱룩을 모두 가지고 있다. // Set tags3 = new LinkedHashSet<>(); // tags3.add(new Tag("시티보이룩")); From f8a11ef6629a37535a641f088b45b65dd417233f Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Sun, 4 Jun 2023 22:10:59 +0900 Subject: [PATCH 146/367] =?UTF-8?q?refactor:=20common=20file=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/review/service/ReviewService.java | 42 ++++++++++++------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index eed3d8bb..4c36083d 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -1,9 +1,11 @@ package project.trendpick_pro.domain.review.service; +import com.querydsl.core.util.FileUtils; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.common.base.filetranslator.FileTranslator; import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.member.entity.Member; @@ -15,6 +17,7 @@ import project.trendpick_pro.domain.review.repository.ReviewImageRepository; import project.trendpick_pro.domain.review.repository.ReviewRepository; +import java.io.File; import java.io.IOException; import java.util.List; @@ -41,8 +44,6 @@ public ReviewResponse showReview(Long productId) { public void delete(Long reviewId) { Review review = reviewRepository.findById(reviewId).orElseThrow(); - - //review.getReviewImage().deleteImage(filePath); reviewRepository.delete(review); } @@ -63,21 +64,34 @@ public ReviewResponse createReview(Member actor, Long productId, ReviewSaveReque return ReviewResponse.of(review); } - public ReviewResponse update(Long reviewId, ReviewSaveRequest reviewSaveRequest) throws IOException { + public ReviewResponse update(Long reviewId, ReviewSaveRequest reviewSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { Review review = reviewRepository.findById(reviewId).orElseThrow(); -// ReviewImage reviewImage = review.getReviewImage(); -// -// //메인 파일 이름을 아예 있던거 없애고 바꿔버리기! -// reviewImage.changeMainFile(filePath, createStoreFileName(mainFile.getOriginalFilename()), mainFile); -// -// //서브 파일도 같은 방식으로 -// //비어있는 경우도 생각.,,? -// //ReviewImage 엔티티에서 가능하니까 거기 메소드를 만들어보쟈 -// //reviewImage.changeSubFile(filePath, subFiles); => List으로 만들어 보내야함 -// List fileList = saveSubImages(filePath, subFiles); -// reviewImage.changeSubFile(filePath, fileList); + + CommonFile mainFile = review.getFile(); + List subFiles = review.getFile().getChild(); + + if(requestMainFile!=null){ + // 기존 이미지 삭제 + FileUtils.delete(new File(mainFile.getFileName())); + } + // 이미지 업데이트 + mainFile = fileTranslator.translateFile(requestMainFile); + + if(requestSubFiles!=null ){ + // 기존 이미지 삭제 + for(CommonFile subFile:subFiles){ + FileUtils.delete(new File(subFile.getFileName())); + } + } + // 이미지 업데이트 + subFiles=fileTranslator.translateFileList(requestSubFiles); + + for (CommonFile subFile : subFiles) { + mainFile.connectFile(subFile); + } review.update(reviewSaveRequest); + return ReviewResponse.of(review); } } From edba75d09a5d0eb5a2bad966bd6e891d089be704 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 4 Jun 2023 22:49:25 +0900 Subject: [PATCH 147/367] =?UTF-8?q?refactor:=20=ED=83=9C=EA=B7=B8=20?= =?UTF-8?q?=EC=96=91=EB=B0=A9=ED=96=A5=20=EB=A9=94=EC=84=9C=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80,=20Review=20=EC=BB=B4=ED=8C=8C=EC=9D=BC=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=ED=95=B4=EA=B2=B0(#106)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/product/entity/Product.java | 14 ++++---- .../repository/ProductRepositoryCustom.java | 1 - .../repository/ProductRepositoryImpl.java | 35 ------------------- .../product/service/ProductService.java | 19 +++++----- .../review/controller/ReviewController.java | 2 ++ .../domain/review/entity/Review.java | 11 ++++-- .../entity/dto/response/ReviewResponse.java | 13 +++++-- .../domain/review/service/ReviewService.java | 14 ++++---- 8 files changed, 47 insertions(+), 62 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index bd345c12..7a72dce9 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -75,7 +75,7 @@ public Product(String name, MainCategory mainCategory, SubCategory subCategory, } public static Product of(ProductSaveRequest request, MainCategory mainCategory - , SubCategory subCategory, Brand brand,CommonFile file,Set tags) { + , SubCategory subCategory, Brand brand,CommonFile file) { return Product.builder() .name(request.name()) .mainCategory(mainCategory) @@ -85,7 +85,6 @@ public static Product of(ProductSaveRequest request, MainCategory mainCategory .file(file) .price(request.price()) .stock(request.stock()) - .tags(tags) .build(); } @@ -108,11 +107,12 @@ public void addReview(int rating){ this.rateAvg = Math.round(total / reviewCount * 10) / 10.0; } - public void update(ProductSaveRequest request) { - this.name=request.name(); - this.description=request.description(); - this.price=request.price(); - this.stock=request.stock(); + public void update(ProductSaveRequest request, CommonFile file) { + this.name = request.name(); + this.description = request.description(); + this.price = request.price(); + this.stock = request.stock(); + this.file = file; } @Override diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java index d3370cf7..25f552d0 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java @@ -12,5 +12,4 @@ public interface ProductRepositoryCustom { public Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable); public List findRecommendProduct(String username); - public List findProductByRecommended(String username); } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index fa96b90c..f15af106 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -1,6 +1,5 @@ package project.trendpick_pro.domain.product.repository; -import com.querydsl.core.Tuple; import com.querydsl.core.types.OrderSpecifier; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.JPAExpressions; @@ -10,24 +9,18 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.support.PageableExecutionUtils; -import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; import project.trendpick_pro.domain.product.entity.dto.response.QProductByRecommended; import project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse; -import project.trendpick_pro.domain.tags.favoritetag.entity.QFavoriteTag; -import project.trendpick_pro.domain.tags.tag.entity.QTag; -import java.util.Comparator; import java.util.List; -import java.util.Optional; import static project.trendpick_pro.domain.brand.entity.QBrand.*; import static project.trendpick_pro.domain.category.entity.QMainCategory.*; import static project.trendpick_pro.domain.category.entity.QSubCategory.*; import static project.trendpick_pro.domain.common.file.QCommonFile.commonFile; -import static project.trendpick_pro.domain.member.entity.QMember.*; import static project.trendpick_pro.domain.product.entity.QProduct.*; import static project.trendpick_pro.domain.tags.favoritetag.entity.QFavoriteTag.favoriteTag; import static project.trendpick_pro.domain.tags.tag.entity.QTag.tag; @@ -102,34 +95,6 @@ public List findRecommendProduct(String username) { return list; } - @Override - public List findProductByRecommended(String username) { - - List sortProducts = queryFactory - .select(product.id, favoriteTag.score.sum()) - .from(favoriteTag, product) - .leftJoin(favoriteTag.member, member) - .where(favoriteTag.name.in( - JPAExpressions.select(tag.name) - .from(tag) - .where(tag.product.eq(product) - )), - member.username.eq(username)) - .groupBy(product.id) - .orderBy(favoriteTag.score.sum().desc()) - .fetch(); - - return sortProducts.stream() - .sorted(Comparator.comparing( - tuple -> Optional.ofNullable(tuple.get(1, Long.class)).orElse(Long.MIN_VALUE), - Comparator.nullsLast(Comparator.naturalOrder()))) - .map(tuple -> queryFactory - .selectFrom(product) - .where(product.id.eq(tuple.get(0, Long.class))) - .fetchOne()) - .toList(); - } - private static BooleanExpression mainCategoryEq(ProductSearchCond cond) { return mainCategory.name.eq(cond.getMainCategory()); } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index b6dca783..cdefd095 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -75,7 +75,6 @@ public ProductResponse register(ProductSaveRequest productSaveRequest, Multipart Set tags = new LinkedHashSet<>(); // 상품에 포함시킬 태크 선택하여 저장 for (String tagName : productSaveRequest.tags()) { -// tags.add(tagRepository.findByName(tag).orElseThrow()); tags.add(new Tag(tagName)); } @@ -83,7 +82,9 @@ public ProductResponse register(ProductSaveRequest productSaveRequest, Multipart SubCategory subCategory = subCategoryRepository.findByName(productSaveRequest.subCategory()); Brand brand = brandRepository.findByName(productSaveRequest.brand()); - Product product = Product.of(productSaveRequest, mainCategory, subCategory, brand, mainFile, tags); + Product product = Product.of(productSaveRequest, mainCategory, subCategory, brand, mainFile); + for(Tag tag : tags) + product.addTag(tag); productRepository.save(product); return ProductResponse.of(product); @@ -101,23 +102,25 @@ public ProductResponse modify(Long productId, ProductSaveRequest productSaveRequ if(requestMainFile!=null){ // 기존 이미지 삭제 FileUtils.delete(new File(mainFile.getFileName())); + // 이미지 업데이트 } - // 이미지 업데이트 + mainFile = fileTranslator.translateFile(requestMainFile); - if(requestSubFiles!=null ){ + if(requestSubFiles!=null){ // 기존 이미지 삭제 for(CommonFile subFile:subFiles){ FileUtils.delete(new File(subFile.getFileName())); } } // 이미지 업데이트 - subFiles=fileTranslator.translateFileList(requestSubFiles); + subFiles = fileTranslator.translateFileList(requestSubFiles); for (CommonFile subFile : subFiles) { mainFile.connectFile(subFile); } - product.update(productSaveRequest); + + product.update(productSaveRequest, mainFile); return ProductResponse.of(product); } @@ -131,8 +134,8 @@ public void delete(Long productId) { productRepository.delete(product); } - public ProductResponse show(Long product_id) { - Product product = productRepository.findById(product_id).orElseThrow(null);// 임시. 나중에 테스트 + public ProductResponse show(Long productId) { + Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 Member member = CheckMember(); favoriteTagService.updateTag(member, product, TagType.SHOW); diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index a4e05e59..0395e631 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -5,6 +5,7 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.review.entity.dto.request.ReviewSaveRequest; @@ -12,6 +13,7 @@ import project.trendpick_pro.domain.review.service.ReviewService; import java.io.IOException; +import java.util.List; @Controller @RequiredArgsConstructor diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java index f1b85573..56f8f1ae 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -1,16 +1,20 @@ package project.trendpick_pro.domain.review.entity; import jakarta.persistence.*; +import jakarta.validation.constraints.NotBlank; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.common.base.BaseTimeEntity; import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.review.entity.dto.request.ReviewSaveRequest; +import java.util.List; + @Entity @NoArgsConstructor @AllArgsConstructor @@ -57,8 +61,11 @@ public static Review of(ReviewSaveRequest reviewCreateRequest, Member member, Pr .build(); } - public void update(ReviewSaveRequest reviewSaveRequest) { - + public void update(ReviewSaveRequest reviewSaveRequest, CommonFile file) { + this.title = reviewSaveRequest.getTitle(); + this.content = reviewSaveRequest.getContent(); + this.file = file; + this.rating = reviewSaveRequest.getRating(); } diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java b/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java index 458a71a8..0107a3c4 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java @@ -49,9 +49,18 @@ public static ReviewResponse of(Review review) { .productId(review.getProduct().getId()) .title(review.getTitle()) .content(review.getContent()) - .mainFile(review.getReviewImage().getMainFileName()) - .subFiles(review.getReviewImage().getSubFileNames()) + .mainFile(review.getFile().getFileName()) + .subFiles(subFiles(review.getFile().getChild())) .rating(review.getRating()) .build(); } + + private static List subFiles(List subFiles) { + List tmpList = new ArrayList<>(); + + for (CommonFile subFile : subFiles) { + tmpList.add(subFile.getFileName()); + } + return tmpList; + } } diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index 4c36083d..c7cc4758 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -64,33 +64,33 @@ public ReviewResponse createReview(Member actor, Long productId, ReviewSaveReque return ReviewResponse.of(review); } - public ReviewResponse update(Long reviewId, ReviewSaveRequest reviewSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { + public ReviewResponse update(Long reviewId, ReviewSaveRequest reviewSaveRequest) throws IOException { Review review = reviewRepository.findById(reviewId).orElseThrow(); CommonFile mainFile = review.getFile(); List subFiles = review.getFile().getChild(); - if(requestMainFile!=null){ + if(reviewSaveRequest.getMainFile() != null){ // 기존 이미지 삭제 FileUtils.delete(new File(mainFile.getFileName())); } // 이미지 업데이트 - mainFile = fileTranslator.translateFile(requestMainFile); + mainFile = fileTranslator.translateFile(reviewSaveRequest.getMainFile()); - if(requestSubFiles!=null ){ + if(reviewSaveRequest.getSubFiles() != null){ // 기존 이미지 삭제 - for(CommonFile subFile:subFiles){ + for(CommonFile subFile : subFiles){ FileUtils.delete(new File(subFile.getFileName())); } } // 이미지 업데이트 - subFiles=fileTranslator.translateFileList(requestSubFiles); + subFiles = fileTranslator.translateFileList(reviewSaveRequest.getSubFiles()); for (CommonFile subFile : subFiles) { mainFile.connectFile(subFile); } - review.update(reviewSaveRequest); + review.update(reviewSaveRequest, mainFile); return ReviewResponse.of(review); } From f403fab85ed267601f148703bc430bad37adb5a0 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 4 Jun 2023 22:52:38 +0900 Subject: [PATCH 148/367] =?UTF-8?q?refactor:=20=ED=85=8C=EC=8A=A4=ED=8A=B8?= =?UTF-8?q?=EC=9A=A9=EC=9C=BC=EB=A1=9C=20=EB=A7=8C=EB=93=A4=EC=97=88?= =?UTF-8?q?=EB=8D=98=EA=B1=B0=20=EC=82=AD=EC=A0=9C(#106)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 30 ----------- .../product/service/ProductService.java | 50 ------------------- 2 files changed, 80 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 16ad1aa5..662ba436 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -107,34 +107,4 @@ public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") i model.addAttribute("productResponses", productService.showAll(offset, mainCategory, subCategory, sortCode)); } return "/trendpick/products/list"; } - - //테스트용 - @GetMapping("/test1") - @ResponseBody - public List showTest1(){ - Member member = memberRepository.findById(1L).orElseThrow(); - return productService.getRecommendProductTest1(member); - } - - @GetMapping("/test2") - @ResponseBody - public List showTest2(){ - Member member = memberRepository.findById(1L).orElseThrow(); - return productService.getRecommendProductTest2(member); - } - - @GetMapping("/test3") - @ResponseBody - public Map showTest3(){ - Member member = memberRepository.findById(1L).orElseThrow(); - Map testMap = new LinkedHashMap<>(); - - List products = productService.getRecommendProduct(member); - - for (Product product : products) { - testMap.put(product.getId(), product.getName()+" "+product.getPrice()+" "+product.getStock()); - } - - return testMap; - } } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index cdefd095..a7f82c0d 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -224,54 +224,4 @@ public List getRecommendProduct(Member member){ } return products; } - - public List getRecommendProductTest1(Member member) { - return productRepository.findRecommendProduct(member.getUsername()); - } - - public List getRecommendProductTest2(Member member){ - - List tags = productRepository.findRecommendProduct(member.getUsername()); - Set memberTags = member.getTags(); - - //태그명에 따라 가지고 있는 product_id - // : 멤버 태그명에 따라 해당 상품에 점수를 부여해야 하기 때문에 - Map> productIdListByTagName = new HashMap<>(); - - //상품 id 중복을 없애기 위함 - //맴버의 태그명과 여러개가 겹쳐서 여러개의 추천상품이 반환되었을것 그 중복을 없애야 한다. - Map recommendProductByProductId = new HashMap<>(); - - //같은 태그명을 가지고 있지만 제각각 상품을 가르키는 productId는 다를 것이다. 그래서 태그명 별로 어떤 상품들을 가르키는지 모아보자 - for (ProductByRecommended tag : tags) { - if(!productIdListByTagName.containsKey(tag.getTagName())) - productIdListByTagName.put(tag.getTagName(), new ArrayList<>()); - productIdListByTagName.get(tag.getTagName()).add(tag.getProductId()); - } - - //마찬가지로 같은 상품을 가르키고 있지만 태그명은 제각각일 것이다. 우리가 뽑아내길 원하는 것은 추천상품이다. 즉 같은 상품이 중복되면 안된다. - //그래서 상품Id에 대한 중복을 없애서 하나에 몰아넣는 코드이다. - for (ProductByRecommended response : tags) { - if(recommendProductByProductId.containsKey(response.getProductId())) - continue; - recommendProductByProductId.put(response.getProductId(), response); - } - - //실제로직! member 선호태그에는 점수가 있을 것이다. - //그러니까 우리가 반환하려고 하는 추천상품이 점수가 몇점인지 갱신하는 코드이다. - for (FavoriteTag memberTag : memberTags) { - if(productIdListByTagName.containsKey(memberTag.getName())){ - List productIdList = productIdListByTagName.get(memberTag.getName()); - for (Long id : productIdList) { - recommendProductByProductId.get(id).plusTotalScore(memberTag.getScore()); - } - } - } - - List recommendProductList = new ArrayList<>(recommendProductByProductId.values()).stream() - .sorted(Comparator.comparing(ProductByRecommended::getTotalScore).reversed()) - .toList(); - return recommendProductList; - } - } From f6cf17b1026c61e29adf9df0b65f7cf9fa0f7714 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 4 Jun 2023 23:03:23 +0900 Subject: [PATCH 149/367] =?UTF-8?q?fix:=20cartService=20=EC=B6=A9=EB=8F=8C?= =?UTF-8?q?=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/cart/service/CartService.java | 54 ++++++++++++------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index 60e4689e..85d257ec 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -5,13 +5,22 @@ import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.cart.entity.Cart; import project.trendpick_pro.domain.cart.entity.CartItem; +import project.trendpick_pro.domain.cart.entity.dto.request.CartItemRequest; +import project.trendpick_pro.domain.cart.entity.dto.request.CartRequest; +import project.trendpick_pro.domain.cart.repository.CartItemRepository; import project.trendpick_pro.domain.cart.repository.CartRepository; -import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.repository.MemberRepository; +import project.trendpick_pro.domain.orders.entity.OrderItem; +import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.ProductOption; +import project.trendpick_pro.domain.product.exception.ProductNotFoundException; import project.trendpick_pro.domain.product.repository.ProductOptionRepository; -import project.trendpick_pro.domain.tags.tag.entity.type.TagType; +import project.trendpick_pro.domain.product.repository.ProductRepository; +import project.trendpick_pro.domain.tag.entity.Tag; +import project.trendpick_pro.domain.tag.entity.type.TagType; +import project.trendpick_pro.domain.tag.service.TagService; import java.util.List; @@ -24,32 +33,37 @@ public class CartService { private final CartRepository cartRepository; private final MemberRepository memberRepository; private final ProductOptionRepository productOptionRepository; - private final FavoriteTagService favoriteTagService; + private final ProductRepository productRepository; + private final CartItemRepository cartItemRepository; + private final TagService tagService; public List findByCartMember(Member member){ return cartRepository.findByCartMember(member); } - - public Cart createCart(Member member) { - Cart cart = new Cart(member); - return cartRepository.save(cart); - } @Transactional - public void addItemToCart(Member member, Long productOptionId, int count) { - Cart cart = getCartByUser(member); - ProductOption productOption = getProductOptionById(productOptionId); - CartItem cartItem = cart.findCartItemByProductOption(productOption); + public void addItemToCart(Member member, Long productId, CartItemRequest cartItemRequest) { + member=memberRepository.findById(member.getId()).orElseThrow(()->new MemberNotFoundException("존재하지 않는 유저입니다.")); + Cart cart = cartRepository.findByMemberId(member.getId()); + Product product=productRepository.findById(productId).orElseThrow(() -> new ProductNotFoundException("존재하지 않는 상품 입니다.")); + + if(cart==null){ + // 장바구니가 비어있다면 생성 + cart=Cart.createCart(member); + cartRepository.save(cart); + } + CartItem cartItem = cartItemRepository.findByCartIdAndProductId(cart.getId(), product.getId()); - favoriteTagService.updateTag(member, productOption.getProduct(), TagType.CART); //장바구니에 넣었으니 해당 상품이 가진 태그점수 올리기 + tagService.updateTag(member, product, TagType.CART); //장바구니에 넣었으니 해당 상품이 가진 태그점수 올리기 if (cartItem != null) { // 이미 카트에 해당 상품이 존재하는 경우, 수량을 증가 - cartItem.setCount(cartItem.getCount() + count); + cartItem.addCount(cartItem.getCount()); } else { // 카트에 해당 상품이 없는 경우, 새로운 카트 아이템을 생성하여 추가 - cartItem = new CartItem(cart, productOption, count); - cart.addItem(cartItem); + cartItem =CartItem.createCartItem(cart,product,cartItemRequest); + cartItemRepository.save(cartItem); + cart.setTotalCount(cart.getTotalCount()+1); } } @@ -69,8 +83,8 @@ public Cart getCartByUser(Member member) { return cartRepository.findByMemberId(member.getId()); } - private ProductOption getProductOptionById(Long productOptionId) { - return productOptionRepository.findById(productOptionId) - .orElseThrow(() -> new IllegalArgumentException("Product option not found")); + private Product getProductById(Long productId){ + return productRepository.findById(productId) + .orElseThrow(() -> new IllegalArgumentException("해당 상품을 찾을 수 없습니다.")); } -} +} \ No newline at end of file From cddc1b7348d3fca38f43f441ff7eafbc9e9eb728 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 4 Jun 2023 23:09:50 +0900 Subject: [PATCH 150/367] =?UTF-8?q?fix:=20git=20push=20=EC=B6=A9=EB=8F=8C?= =?UTF-8?q?=20=EC=BD=94=EB=93=9C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trendpick_pro/domain/cart/service/CartService.java | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index 85d257ec..f5264511 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -6,21 +6,17 @@ import project.trendpick_pro.domain.cart.entity.Cart; import project.trendpick_pro.domain.cart.entity.CartItem; import project.trendpick_pro.domain.cart.entity.dto.request.CartItemRequest; -import project.trendpick_pro.domain.cart.entity.dto.request.CartRequest; import project.trendpick_pro.domain.cart.repository.CartItemRepository; import project.trendpick_pro.domain.cart.repository.CartRepository; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.repository.MemberRepository; -import project.trendpick_pro.domain.orders.entity.OrderItem; import project.trendpick_pro.domain.product.entity.Product; -import project.trendpick_pro.domain.product.entity.ProductOption; import project.trendpick_pro.domain.product.exception.ProductNotFoundException; import project.trendpick_pro.domain.product.repository.ProductOptionRepository; import project.trendpick_pro.domain.product.repository.ProductRepository; -import project.trendpick_pro.domain.tag.entity.Tag; -import project.trendpick_pro.domain.tag.entity.type.TagType; -import project.trendpick_pro.domain.tag.service.TagService; +import project.trendpick_pro.domain.tags.tag.entity.type.TagType; +import project.trendpick_pro.domain.tags.tag.service.TagService; import java.util.List; From b10fc5612519e24441ea065fab0e3e3989ffd210 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 4 Jun 2023 23:16:37 +0900 Subject: [PATCH 151/367] =?UTF-8?q?fix:=20CartService=20=EC=BB=B4=ED=8C=8C?= =?UTF-8?q?=EC=9D=BC=20=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trendpick_pro/domain/cart/service/CartService.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index f5264511..9c0b0487 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -15,6 +15,8 @@ import project.trendpick_pro.domain.product.exception.ProductNotFoundException; import project.trendpick_pro.domain.product.repository.ProductOptionRepository; import project.trendpick_pro.domain.product.repository.ProductRepository; +import project.trendpick_pro.domain.tags.favoritetag.entity.FavoriteTag; +import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; import project.trendpick_pro.domain.tags.tag.entity.type.TagType; import project.trendpick_pro.domain.tags.tag.service.TagService; @@ -32,6 +34,7 @@ public class CartService { private final ProductRepository productRepository; private final CartItemRepository cartItemRepository; private final TagService tagService; + private final FavoriteTagService favoriteTagService; public List findByCartMember(Member member){ return cartRepository.findByCartMember(member); @@ -50,7 +53,7 @@ public void addItemToCart(Member member, Long productId, CartItemRequest cartIte } CartItem cartItem = cartItemRepository.findByCartIdAndProductId(cart.getId(), product.getId()); - tagService.updateTag(member, product, TagType.CART); //장바구니에 넣었으니 해당 상품이 가진 태그점수 올리기 + favoriteTagService.updateTag(member, product, TagType.CART); //장바구니에 넣었으니 해당 상품이 가진 태그점수 올리기 if (cartItem != null) { // 이미 카트에 해당 상품이 존재하는 경우, 수량을 증가 From d37467fa002c835ef57721987934ddfd7c421bd0 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 5 Jun 2023 14:03:34 +0900 Subject: [PATCH 152/367] =?UTF-8?q?refactor:=20form=20=ED=85=8C=EC=8A=A4?= =?UTF-8?q?=ED=8A=B8=20=EA=B0=80=EB=8A=A5=ED=95=98=EA=B2=8C=20=EB=A1=9C?= =?UTF-8?q?=EC=A7=81=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 11 +++---- .../domain/review/entity/Review.java | 27 ++++------------- .../entity/dto/request/ReviewSaveRequest.java | 30 ++++++++----------- .../domain/review/service/ReviewService.java | 17 ++++++----- 4 files changed, 33 insertions(+), 52 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index 0395e631..dc29b72b 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -24,9 +24,10 @@ public class ReviewController { @PostMapping("/write") public String createReview(@Valid ReviewSaveRequest reviewCreateRequest, @RequestParam(value = "product") Long productId, - Model model) throws Exception { + @RequestParam("mainFile") MultipartFile mainFile, + @RequestParam("subFiles") List subFiles, Model model) throws Exception { Member actor = rq.getMember(); - ReviewResponse reviewResponse = reviewService.createReview(actor, productId, reviewCreateRequest); + ReviewResponse reviewResponse = reviewService.createReview(actor, productId, reviewCreateRequest, mainFile, subFiles); model.addAttribute("reviewResponse", reviewResponse); return "redirect:/trendpick/review"; @@ -48,9 +49,9 @@ public String deleteReview(@PathVariable Long reviewId) { } @PostMapping("/edit/{reviewId}") - public String updateReview(@PathVariable Long reviewId, ReviewSaveRequest reviewSaveRequest, - Model model) throws IOException { - ReviewResponse reviewResponse = reviewService.update(reviewId, reviewSaveRequest); + public String updateReview(@PathVariable Long reviewId, ReviewSaveRequest reviewSaveRequest, @RequestParam("mainFile") MultipartFile mainFile, + @RequestParam("subFiles") List subFiles, Model model) throws IOException { + ReviewResponse reviewResponse = reviewService.modify(reviewId, reviewSaveRequest, mainFile, subFiles); model.addAttribute("reviewResponse", reviewResponse); return "redirect:/trendpick/review"; diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java index 56f8f1ae..3ec399df 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -56,33 +56,16 @@ public static Review of(ReviewSaveRequest reviewCreateRequest, Member member, Pr .writer(member.getUsername()) .product(product) .file(file) - .content(reviewCreateRequest.getContent()) - .rating(reviewCreateRequest.getRating()) + .content(reviewCreateRequest.content()) + .rating(reviewCreateRequest.rating()) .build(); } public void update(ReviewSaveRequest reviewSaveRequest, CommonFile file) { - this.title = reviewSaveRequest.getTitle(); - this.content = reviewSaveRequest.getContent(); + this.title = reviewSaveRequest.title(); + this.content = reviewSaveRequest.content(); + this.rating = reviewSaveRequest.rating(); this.file = file; - this.rating = reviewSaveRequest.getRating(); } - -// public void changeMainFile(String filePath, String mainFilePath, MultipartFile mainFile) throws IOException { -// File file = new File(filePath + mainFileName); -// file.delete(); //원래 있던거 삭제 -// -// this.mainFileName = mainFilePath; -// mainFile.transferTo(new File(filePath + mainFilePath)); -// } -// -// public void changeSubFile(String filePath, List subFileNames) { -// //음 우선 돌면서 지워야겠지?? -// for(String subFile: subFileNames){ -// File file = new File(filePath + subFile); -// file.delete(); -// } -// this.subFileNames = subFileNames; -// } } diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewSaveRequest.java b/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewSaveRequest.java index c496dbcd..9c404318 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewSaveRequest.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/dto/request/ReviewSaveRequest.java @@ -2,23 +2,19 @@ import jakarta.validation.constraints.NotBlank; -import lombok.Data; -import org.springframework.web.multipart.MultipartFile; +import jakarta.validation.constraints.NotNull; -import java.util.List; -@Data -public class ReviewSaveRequest { - @NotBlank(message = "제목을 입력해주세요") - private String title; - @NotBlank(message = "내용을 입력해주세요") - private String content; - - @NotBlank(message = "메인으로 사용하실 사진을 입력해주세요") - private MultipartFile mainFile; - - @NotBlank(message = "추가적으로 사용하실 사진을 입력해주세요") - private List subFiles; - - private int rating; +public record ReviewSaveRequest ( + @NotBlank(message = "제목을 입력해주세요") String title, + @NotBlank(message = "내용을 입력해주세요") String content, + @NotNull(message = "점수를 입력해주세요.")int rating){ + @Override + public String toString() { + return "ProductSaveRequest{" + + "title='" + title + '\'' + + ", content='" + content + '\'' + + ", rating='" + rating + + '}'; + } } diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index c7cc4758..55c5eadd 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -5,6 +5,7 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.common.base.filetranslator.FileTranslator; import project.trendpick_pro.domain.common.file.CommonFile; @@ -47,11 +48,11 @@ public void delete(Long reviewId) { reviewRepository.delete(review); } - public ReviewResponse createReview(Member actor, Long productId, ReviewSaveRequest reviewSaveRequest) throws Exception { + public ReviewResponse createReview(Member actor, Long productId, ReviewSaveRequest reviewSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws Exception { Product product = productRepository.findById(productId).orElseThrow(); - CommonFile mainFile = fileTranslator.translateFile(reviewSaveRequest.getMainFile()); - List subFiles = fileTranslator.translateFileList(reviewSaveRequest.getSubFiles()); + CommonFile mainFile = fileTranslator.translateFile(requestMainFile); + List subFiles = fileTranslator.translateFileList(requestSubFiles); for(CommonFile subFile : subFiles){ mainFile.connectFile(subFile); @@ -64,27 +65,27 @@ public ReviewResponse createReview(Member actor, Long productId, ReviewSaveReque return ReviewResponse.of(review); } - public ReviewResponse update(Long reviewId, ReviewSaveRequest reviewSaveRequest) throws IOException { + public ReviewResponse modify(Long reviewId, ReviewSaveRequest reviewSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { Review review = reviewRepository.findById(reviewId).orElseThrow(); CommonFile mainFile = review.getFile(); List subFiles = review.getFile().getChild(); - if(reviewSaveRequest.getMainFile() != null){ + if(requestMainFile != null){ // 기존 이미지 삭제 FileUtils.delete(new File(mainFile.getFileName())); } // 이미지 업데이트 - mainFile = fileTranslator.translateFile(reviewSaveRequest.getMainFile()); + mainFile = fileTranslator.translateFile(requestMainFile); - if(reviewSaveRequest.getSubFiles() != null){ + if(requestSubFiles != null){ // 기존 이미지 삭제 for(CommonFile subFile : subFiles){ FileUtils.delete(new File(subFile.getFileName())); } } // 이미지 업데이트 - subFiles = fileTranslator.translateFileList(reviewSaveRequest.getSubFiles()); + subFiles = fileTranslator.translateFileList(requestSubFiles); for (CommonFile subFile : subFiles) { mainFile.connectFile(subFile); From 5358138eb7e4f0ecc0568816ab000dd411aee87c Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 5 Jun 2023 14:08:59 +0900 Subject: [PATCH 153/367] =?UTF-8?q?refactor:=20=EC=82=AC=EC=9A=A9=ED=95=98?= =?UTF-8?q?=EC=A7=80=20=EC=95=8A=EB=8A=94=20=ED=8C=8C=EC=9D=BC=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/review/entity/ReviewImage.java | 66 ------------------- .../repository/ReviewImageRepository.java | 9 --- .../domain/review/service/ReviewService.java | 3 - 3 files changed, 78 deletions(-) delete mode 100644 src/main/java/project/trendpick_pro/domain/review/entity/ReviewImage.java delete mode 100644 src/main/java/project/trendpick_pro/domain/review/repository/ReviewImageRepository.java diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/ReviewImage.java b/src/main/java/project/trendpick_pro/domain/review/entity/ReviewImage.java deleted file mode 100644 index 0b23e98e..00000000 --- a/src/main/java/project/trendpick_pro/domain/review/entity/ReviewImage.java +++ /dev/null @@ -1,66 +0,0 @@ -package project.trendpick_pro.domain.review.entity; - -import jakarta.persistence.*; -import lombok.AccessLevel; -import lombok.AllArgsConstructor; -import lombok.Getter; -import lombok.NoArgsConstructor; -import org.springframework.web.multipart.MultipartFile; - -import java.io.File; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; - -@Entity -@Getter -@AllArgsConstructor -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class ReviewImage { - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "review_image_id") - private Long id; - - private String mainFileName; - - @ElementCollection(fetch = FetchType.LAZY) - private List subFileNames = new ArrayList<>(); - - @OneToOne(mappedBy = "reviewImage", fetch = FetchType.LAZY) - private Review review; - - public ReviewImage(String mainFileName, Review review){ - this.mainFileName = mainFileName; - this.review = review; - } - - public void deleteImage(String filePath){ - for(String subFile : subFileNames){ - File file = new File(filePath + subFile); - file.delete(); - } - File file = new File(filePath + mainFileName); - file.delete(); - } - - public void saveSubFileNames(List subFileNames) { - this.subFileNames = subFileNames; - } - - public void changeMainFile(String filePath, String mainFilePath, MultipartFile mainFile) throws IOException { - File file = new File(filePath + mainFileName); - file.delete(); //원래 있던거 삭제 - - this.mainFileName = mainFilePath; - mainFile.transferTo(new File(filePath + mainFilePath)); - } - - public void changeSubFile(String filePath, List subFileNames) { - //음 우선 돌면서 지워야겠지?? - for(String subFile: subFileNames){ - File file = new File(filePath + subFile); - file.delete(); - } - this.subFileNames = subFileNames; - } -} diff --git a/src/main/java/project/trendpick_pro/domain/review/repository/ReviewImageRepository.java b/src/main/java/project/trendpick_pro/domain/review/repository/ReviewImageRepository.java deleted file mode 100644 index 40e20cb1..00000000 --- a/src/main/java/project/trendpick_pro/domain/review/repository/ReviewImageRepository.java +++ /dev/null @@ -1,9 +0,0 @@ -package project.trendpick_pro.domain.review.repository; - -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; -import project.trendpick_pro.domain.review.entity.ReviewImage; - -@Repository -public interface ReviewImageRepository extends JpaRepository { -} diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index 55c5eadd..f72b15db 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -5,7 +5,6 @@ import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.common.base.filetranslator.FileTranslator; import project.trendpick_pro.domain.common.file.CommonFile; @@ -15,7 +14,6 @@ import project.trendpick_pro.domain.review.entity.Review; import project.trendpick_pro.domain.review.entity.dto.request.ReviewSaveRequest; import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; -import project.trendpick_pro.domain.review.repository.ReviewImageRepository; import project.trendpick_pro.domain.review.repository.ReviewRepository; import java.io.File; @@ -29,7 +27,6 @@ public class ReviewService { private final ReviewRepository reviewRepository; private final ProductRepository productRepository; - private final ReviewImageRepository reviewImageRepository; private final FileTranslator fileTranslator; @Value("${file.dir}") From 10112ef397f8001fd19fc60ea9b5823e8749cef9 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Mon, 5 Jun 2023 15:33:53 +0900 Subject: [PATCH 154/367] =?UTF-8?q?feat:=20=EC=A3=BC=EB=AC=B8=EC=84=9C=20?= =?UTF-8?q?=ED=8B=80=20=EC=9E=91=EC=84=B1(#112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/entity/dto/MemberInfoDto.java | 12 + .../orders/contoller/OrderController.java | 29 ++- .../orders/entity/dto/request/OrderForm.java | 18 ++ .../entity/dto/request/OrderSaveRequest.java | 4 + .../entity/dto/response/OrderItemDto.java | 10 + .../domain/orders/service/OrderService.java | 3 +- .../templates/trendpick/orders/list.html | 0 .../templates/trendpick/orders/order.html | 43 ++++ .../orders/service/OrderServiceTest.java | 242 +++++++++--------- 9 files changed, 230 insertions(+), 131 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java create mode 100644 src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java create mode 100644 src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java create mode 100644 src/main/resources/templates/trendpick/orders/list.html create mode 100644 src/main/resources/templates/trendpick/orders/order.html diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java b/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java new file mode 100644 index 00000000..26588b51 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java @@ -0,0 +1,12 @@ +package project.trendpick_pro.domain.member.entity.dto; + +import lombok.Getter; + +@Getter +public class MemberInfoDto { + + private String name; + private String email; + private String phone; + private String address; +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index b40b7709..b315a64c 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -1,29 +1,42 @@ package project.trendpick_pro.domain.orders.contoller; -import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.data.domain.Page; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; -import project.trendpick_pro.domain.orders.entity.dto.request.OrderSaveRequest; -import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; +import project.trendpick_pro.domain.member.entity.dto.MemberInfoDto; +import project.trendpick_pro.domain.orders.entity.OrderItem; +import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; import project.trendpick_pro.domain.orders.service.OrderService; +import java.util.List; + @Slf4j @Controller @RequiredArgsConstructor -@RequestMapping("trendpick/order") +@RequestMapping("trendpick/orders") public class OrderController { private final OrderService orderService; + @GetMapping("/order") + public String order(@ModelAttribute MemberInfoDto memberInfo, + @ModelAttribute List orderItems, + Model model){ + + + model.addAttribute("orderItems", orderItems); + model.addAttribute("memberInfo", memberInfo); + + return "trendpick/orders/order"; + } + @PostMapping("/order") - public String order(@Valid OrderSaveRequest... orderSaveRequests){ + public synchronized String order(){ + -// orderService.order(1L, orderSaveRequests); return "redirect:/orders"; } @@ -34,7 +47,7 @@ public String orderList(Model model) { return "trendpick/usr/member/orders"; } - @PostMapping("/orders/{orderId}/cancel") + @PostMapping("/{orderId}/cancel") public String cancelOrder(@PathVariable("orderId") Long orderId) { orderService.cancel(orderId); return "redirect:trendpick/usr/member/orders"; diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java new file mode 100644 index 00000000..5d493fcf --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java @@ -0,0 +1,18 @@ +package project.trendpick_pro.domain.orders.entity.dto.request; + +import jakarta.validation.constraints.NotBlank; +import project.trendpick_pro.domain.orders.entity.OrderItem; + +import java.util.List; + +//주문서 +public class OrderForm { + + private String username; + private String phoneNum; + private String address; + private String message; + private List orderItemList; + private String paymentMethod; + +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSaveRequest.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSaveRequest.java index fc85f115..d5ede146 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSaveRequest.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSaveRequest.java @@ -12,4 +12,8 @@ public class OrderSaveRequest { @NotBlank(message = "수량을 입력해주세요.") private int quantity; + private String color; // 해당 상품 색상 + + private String size; // 해당 상품 사이즈 + private int count; // 해당 상품 수량 } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java new file mode 100644 index 00000000..dd681693 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java @@ -0,0 +1,10 @@ +package project.trendpick_pro.domain.orders.entity.dto.response; + +import lombok.Getter; + +@Getter +public class OrderItemDto { + private String productName; + private int count; + private int price; +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index b9919ef8..83994d61 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -38,11 +38,10 @@ public class OrderService { private final OrderRepository orderRepository; private final MemberRepository memberRepository; private final ProductRepository productRepository; - private final TagService tagService; private final FavoriteTagService favoriteTagService; @Transactional - public synchronized void order(Long userId, OrderSaveRequest... orderSaveRequests) { + public void order(Long userId, OrderSaveRequest... orderSaveRequests) { Member member = memberRepository.findById(userId).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 유저 입니다."));// 임시 exception 설정 나중에 할 수도 있고 아닐수도 diff --git a/src/main/resources/templates/trendpick/orders/list.html b/src/main/resources/templates/trendpick/orders/list.html new file mode 100644 index 00000000..e69de29b diff --git a/src/main/resources/templates/trendpick/orders/order.html b/src/main/resources/templates/trendpick/orders/order.html new file mode 100644 index 00000000..f6a81000 --- /dev/null +++ b/src/main/resources/templates/trendpick/orders/order.html @@ -0,0 +1,43 @@ + + + + + + + 주문 폼 + + + +

주문서

+

회원 정보

+

회원 이름:

+

이메일:

+

번호:

+

주소:

+ +

주문 아이템 목록

+ + + + + + + + + + + +
상품명수량가격
+ +

결제 수단 선택

+
+ + +
+ + \ No newline at end of file diff --git a/src/test/java/project/trendpick_pro/domain/orders/service/OrderServiceTest.java b/src/test/java/project/trendpick_pro/domain/orders/service/OrderServiceTest.java index fe324ba7..60071960 100644 --- a/src/test/java/project/trendpick_pro/domain/orders/service/OrderServiceTest.java +++ b/src/test/java/project/trendpick_pro/domain/orders/service/OrderServiceTest.java @@ -1,121 +1,121 @@ -package project.trendpick_pro.domain.orders.service; - -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.DisplayName; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.mockito.InjectMocks; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.mockito.junit.jupiter.MockitoExtension; -import org.slf4j.LoggerFactory; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.security.crypto.password.PasswordEncoder; -import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.member.entity.RoleType; -import project.trendpick_pro.domain.member.repository.MemberRepository; -import project.trendpick_pro.domain.orders.entity.dto.request.OrderSaveRequest; -import project.trendpick_pro.domain.orders.repository.OrderRepository; -import project.trendpick_pro.domain.product.entity.Product; -import project.trendpick_pro.domain.product.repository.ProductRepository; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; -import java.util.concurrent.*; -import java.util.logging.Logger; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.when; - -public class OrderServiceTest { - - private static final org.slf4j.Logger logger = LoggerFactory.getLogger(OrderServiceTest.class); - - - @InjectMocks - OrderService orderService; - - @Mock - MemberRepository memberRepository; - - @Mock - ProductRepository productRepository; - - @Mock - OrderRepository orderRepository; - - @BeforeEach - public void setUp() { - MockitoAnnotations.openMocks(this); - - // 이 부분에서 테스트에 필요한 데이터를 설정하실 수 있습니다. -// Member member = new Member(); -// Product product = new Product(); // 적절한 Product 객체 생성 -// product.setStock(10); -// when(memberRepository.findById(any())).thenReturn(Optional.of(member)); -// when(productRepository.findById(any())).thenReturn(Optional.of(product)); - } - - @Test - @DisplayName("주문 재고 동시성 확인") - public void concurrencyTest() throws Exception { - ExecutorService executorService = Executors.newFixedThreadPool(10); - List> futures = new ArrayList<>(); - - for (int i = 1; i <= 11; i++) { - int finalI = i; - Future future = executorService.submit(() -> { - try { - orderService.order(1L, new OrderSaveRequest(1L, 1)); // 적절한 OrderSaveRequest 객체 사용 - logger.info(String.valueOf(finalI)); - } catch (Exception e) { - logger.error(String.valueOf(finalI)); - throw new IllegalStateException(e); - } - }); - futures.add(future); - } - - for (Future future : futures) { - future.get(); - } - - executorService.shutdown(); - if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) { - executorService.shutdownNow(); - } - } - - private long account = 100_000L; // 계좌 잔고 100,000원 - - @Test - void pay() throws InterruptedException { - // given - ExecutorService executor = Executors.newFixedThreadPool(2); - CountDownLatch countDownLatch = new CountDownLatch(2); - - // when - executor.submit(() -> execute("A", 40_000L, countDownLatch)); // A가 40,000원 결제 - executor.submit(() -> execute("B", 20_000L, countDownLatch)); // B가 20,000원 결제 - countDownLatch.await(); - - // then - assertThat(account).isEqualTo(40_000L); // 60,000원을 사용했으므로 예상 잔액은 40,000원 - } - - private void execute(String username, long money, CountDownLatch countDownLatch) { - try { - pay(username, money); - } finally { - countDownLatch.countDown(); - } - } - - private synchronized void pay(String username, long money) { - long result = account - money; - System.out.printf("%s가 %d원을 사용한 뒤 남은 금액은 %d 입니다.\n", username, money, result); - account = result; - } -} +//package project.trendpick_pro.domain.orders.service; +// +//import org.junit.jupiter.api.BeforeEach; +//import org.junit.jupiter.api.DisplayName; +//import org.junit.jupiter.api.Test; +//import org.junit.jupiter.api.extension.ExtendWith; +//import org.mockito.InjectMocks; +//import org.mockito.Mock; +//import org.mockito.MockitoAnnotations; +//import org.mockito.junit.jupiter.MockitoExtension; +//import org.slf4j.LoggerFactory; +//import org.springframework.boot.test.context.SpringBootTest; +//import org.springframework.security.crypto.password.PasswordEncoder; +//import project.trendpick_pro.domain.member.entity.Member; +//import project.trendpick_pro.domain.member.entity.RoleType; +//import project.trendpick_pro.domain.member.repository.MemberRepository; +//import project.trendpick_pro.domain.orders.entity.dto.request.OrderSaveRequest; +//import project.trendpick_pro.domain.orders.repository.OrderRepository; +//import project.trendpick_pro.domain.product.entity.Product; +//import project.trendpick_pro.domain.product.repository.ProductRepository; +// +//import java.util.ArrayList; +//import java.util.List; +//import java.util.Optional; +//import java.util.concurrent.*; +//import java.util.logging.Logger; +// +//import static org.assertj.core.api.Assertions.assertThat; +//import static org.mockito.ArgumentMatchers.any; +//import static org.mockito.Mockito.when; +// +//public class OrderServiceTest { +// +// private static final org.slf4j.Logger logger = LoggerFactory.getLogger(OrderServiceTest.class); +// +// +// @InjectMocks +// OrderService orderService; +// +// @Mock +// MemberRepository memberRepository; +// +// @Mock +// ProductRepository productRepository; +// +// @Mock +// OrderRepository orderRepository; +// +// @BeforeEach +// public void setUp() { +// MockitoAnnotations.openMocks(this); +// +// // 이 부분에서 테스트에 필요한 데이터를 설정하실 수 있습니다. +//// Member member = new Member(); +//// Product product = new Product(); // 적절한 Product 객체 생성 +//// product.setStock(10); +//// when(memberRepository.findById(any())).thenReturn(Optional.of(member)); +//// when(productRepository.findById(any())).thenReturn(Optional.of(product)); +// } +// +// @Test +// @DisplayName("주문 재고 동시성 확인") +// public void concurrencyTest() throws Exception { +// ExecutorService executorService = Executors.newFixedThreadPool(10); +// List> futures = new ArrayList<>(); +// +// for (int i = 1; i <= 11; i++) { +// int finalI = i; +// Future future = executorService.submit(() -> { +// try { +// orderService.order(1L, new OrderSaveRequest(1L, 1)); // 적절한 OrderSaveRequest 객체 사용 +// logger.info(String.valueOf(finalI)); +// } catch (Exception e) { +// logger.error(String.valueOf(finalI)); +// throw new IllegalStateException(e); +// } +// }); +// futures.add(future); +// } +// +// for (Future future : futures) { +// future.get(); +// } +// +// executorService.shutdown(); +// if (!executorService.awaitTermination(60, TimeUnit.SECONDS)) { +// executorService.shutdownNow(); +// } +// } +// +// private long account = 100_000L; // 계좌 잔고 100,000원 +// +// @Test +// void pay() throws InterruptedException { +// // given +// ExecutorService executor = Executors.newFixedThreadPool(2); +// CountDownLatch countDownLatch = new CountDownLatch(2); +// +// // when +// executor.submit(() -> execute("A", 40_000L, countDownLatch)); // A가 40,000원 결제 +// executor.submit(() -> execute("B", 20_000L, countDownLatch)); // B가 20,000원 결제 +// countDownLatch.await(); +// +// // then +// assertThat(account).isEqualTo(40_000L); // 60,000원을 사용했으므로 예상 잔액은 40,000원 +// } +// +// private void execute(String username, long money, CountDownLatch countDownLatch) { +// try { +// pay(username, money); +// } finally { +// countDownLatch.countDown(); +// } +// } +// +// private synchronized void pay(String username, long money) { +// long result = account - money; +// System.out.printf("%s가 %d원을 사용한 뒤 남은 금액은 %d 입니다.\n", username, money, result); +// account = result; +// } +//} From 10e0ab85f5ede5d6438d596ed598fe1bb15b60da Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 5 Jun 2023 15:50:15 +0900 Subject: [PATCH 155/367] =?UTF-8?q?refactor:=20@Transactional=20=EB=B6=99?= =?UTF-8?q?=EC=9D=B4=EA=B8=B0=20/=20of=EC=97=90=20title=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 --- .../review/controller/ReviewController.java | 25 ++++++++++++++----- .../domain/review/entity/Review.java | 1 + .../domain/review/service/ReviewService.java | 1 + 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index dc29b72b..3f09888e 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -2,12 +2,16 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.exception.MemberNotFoundException; +import project.trendpick_pro.domain.member.repository.MemberRepository; +import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.review.entity.dto.request.ReviewSaveRequest; import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; import project.trendpick_pro.domain.review.service.ReviewService; @@ -20,17 +24,25 @@ @RequestMapping("/trendpick/review") public class ReviewController { private final ReviewService reviewService; + private final MemberRepository memberRepository; private final Rq rq; + @GetMapping("/register") + public String registerReview() { + return "/trendpick/review/register"; + } + @PostMapping("/write") - public String createReview(@Valid ReviewSaveRequest reviewCreateRequest, @RequestParam(value = "product") Long productId, + public String createReview(@Valid ReviewSaveRequest reviewCreateRequest, @RequestParam("mainFile") MultipartFile mainFile, @RequestParam("subFiles") List subFiles, Model model) throws Exception { - Member actor = rq.getMember(); - ReviewResponse reviewResponse = reviewService.createReview(actor, productId, reviewCreateRequest, mainFile, subFiles); + String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 + Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); + //어떤 상품인지 받아와야 함 + ReviewResponse reviewResponse = reviewService.createReview(member, 1L, reviewCreateRequest, mainFile, subFiles); model.addAttribute("reviewResponse", reviewResponse); - return "redirect:/trendpick/review"; + return "redirect:/trendpick/review/list"; } @@ -41,11 +53,12 @@ public String showReview(@PathVariable Long reviewId, Model model){ return "redirect:/trendpick/review"; } - @PostMapping("/delete/{reviewId}") + @GetMapping("/delete/{reviewId}") public String deleteReview(@PathVariable Long reviewId) { reviewService.delete(reviewId); - return "redirect:/trendpick/review"; + //return "redirect:/trendpick/review/list"; + return "/trendpick/review/list"; } @PostMapping("/edit/{reviewId}") diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java index 3ec399df..3aedfeda 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -56,6 +56,7 @@ public static Review of(ReviewSaveRequest reviewCreateRequest, Member member, Pr .writer(member.getUsername()) .product(product) .file(file) + .title(reviewCreateRequest.title()) .content(reviewCreateRequest.content()) .rating(reviewCreateRequest.rating()) .build(); diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index f72b15db..630e8abe 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -40,6 +40,7 @@ public ReviewResponse showReview(Long productId) { } + @Transactional public void delete(Long reviewId) { Review review = reviewRepository.findById(reviewId).orElseThrow(); reviewRepository.delete(review); From 5954d6746b7e06ca178d565029a5e1efa2570d1d Mon Sep 17 00:00:00 2001 From: jooooonj Date: Mon, 5 Jun 2023 17:24:06 +0900 Subject: [PATCH 156/367] feat: test(#112) --- .../member/entity/dto/MemberInfoDto.java | 10 +++++ .../orders/contoller/OrderController.java | 32 ++++++++++---- .../orders/entity/dto/request/OrderForm.java | 18 +++++--- .../entity/dto/response/OrderItemDto.java | 8 ++++ .../templates/trendpick/orders/order.html | 43 ++++++++++--------- 5 files changed, 76 insertions(+), 35 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java b/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java index 26588b51..fed02098 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java @@ -1,12 +1,22 @@ package project.trendpick_pro.domain.member.entity.dto; import lombok.Getter; +import lombok.Setter; @Getter +@Setter public class MemberInfoDto { private String name; private String email; + + public MemberInfoDto(String name, String email, String phone, String address) { + this.name = name; + this.email = email; + this.phone = phone; + this.address = address; + } + private String phone; private String address; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index b315a64c..29d0cd74 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -6,10 +6,13 @@ import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import project.trendpick_pro.domain.member.entity.dto.MemberInfoDto; +import project.trendpick_pro.domain.orders.entity.Order; import project.trendpick_pro.domain.orders.entity.OrderItem; +import project.trendpick_pro.domain.orders.entity.dto.request.OrderForm; import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; import project.trendpick_pro.domain.orders.service.OrderService; +import java.util.ArrayList; import java.util.List; @@ -22,22 +25,35 @@ public class OrderController { private final OrderService orderService; @GetMapping("/order") - public String order(@ModelAttribute MemberInfoDto memberInfo, - @ModelAttribute List orderItems, - Model model){ + public String order(OrderForm orderForm, Model model){ + MemberInfoDto memberInfo = new MemberInfoDto("member1", "email", "000", "서울"); + List orderItems = new ArrayList<>(); + orderItems.add(new OrderItemDto("상품1", 5, 500)); + orderItems.add(new OrderItemDto("상품2", 1, 100)); + orderItems.add(new OrderItemDto("상품3", 2, 200)); - - model.addAttribute("orderItems", orderItems); - model.addAttribute("memberInfo", memberInfo); + orderForm = new OrderForm(memberInfo, orderItems); + model.addAttribute("orderForm", orderForm); return "trendpick/orders/order"; } @PostMapping("/order") - public synchronized String order(){ + public synchronized String processOrder(@ModelAttribute OrderForm orderForm, + @RequestParam("paymentMethod") String paymentMethod) { + // 예시: 주문 정보 출력 + System.out.println("회원 이름: " + orderForm.getMemberInfo().getName()); + System.out.println("이메일: " + orderForm.getMemberInfo().getEmail()); + System.out.println("주문 아이템 목록:"); + for (OrderItemDto orderItem : orderForm.getOrderItems()) { + System.out.println("상품명: " + orderItem.getProductName()); + System.out.println("수량: " + orderItem.getCount()); + System.out.println("가격: " + orderItem.getPrice()); + } + System.out.println("결제 수단: " + paymentMethod); - return "redirect:/orders"; + return "주문성공"; } @GetMapping("/list") diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java index 5d493fcf..df04dd6f 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java @@ -1,18 +1,24 @@ package project.trendpick_pro.domain.orders.entity.dto.request; import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; +import project.trendpick_pro.domain.member.entity.dto.MemberInfoDto; import project.trendpick_pro.domain.orders.entity.OrderItem; +import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; import java.util.List; //주문서 +@Getter +@Setter public class OrderForm { - private String username; - private String phoneNum; - private String address; - private String message; - private List orderItemList; - private String paymentMethod; + private MemberInfoDto memberInfo; + private List orderItems; + public OrderForm(MemberInfoDto memberInfo, List orderItems) { + this.memberInfo = memberInfo; + this.orderItems = orderItems; + } } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java index dd681693..fae0c743 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java @@ -1,10 +1,18 @@ package project.trendpick_pro.domain.orders.entity.dto.response; import lombok.Getter; +import lombok.Setter; @Getter +@Setter public class OrderItemDto { private String productName; private int count; private int price; + + public OrderItemDto(String productName, int count, int price) { + this.productName = productName; + this.count = count; + this.price = price; + } } diff --git a/src/main/resources/templates/trendpick/orders/order.html b/src/main/resources/templates/trendpick/orders/order.html index f6a81000..1d24ba9b 100644 --- a/src/main/resources/templates/trendpick/orders/order.html +++ b/src/main/resources/templates/trendpick/orders/order.html @@ -10,34 +10,35 @@

주문서

회원 정보

-

회원 이름:

-

이메일:

-

번호:

-

주소:

+
+

회원 이름:

+

이메일:

+

번호:

+

주소:

-

주문 아이템 목록

- - - - - - - - - - - -
상품명수량가격
+

주문 아이템 목록

+ + + + + + + + + + + +
상품명수량가격
-

결제 수단 선택

- +

결제 수단 선택

- + +
\ No newline at end of file From eb56c62b61966af972452b5f3da31c823b7dc634 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Mon, 5 Jun 2023 18:58:23 +0900 Subject: [PATCH 157/367] =?UTF-8?q?feat:=20=EC=A3=BC=EB=AC=B8=ED=8F=BC?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EC=9E=91=EC=84=B1=ED=95=9C=20=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=BB=A8=ED=8A=B8=EB=A1=A4=EB=9F=AC?= =?UTF-8?q?=EC=97=90=EC=84=9C=20=EB=B0=9B=EC=95=84=EC=A7=80=EB=8A=94?= =?UTF-8?q?=EA=B1=B0=20=ED=99=95=EC=9D=B8=EC=99=84=EB=A3=8C(#112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/entity/dto/MemberInfoDto.java | 3 +++ .../orders/contoller/OrderController.java | 8 ++++++-- .../orders/entity/dto/request/OrderForm.java | 3 +++ .../entity/dto/response/OrderItemDto.java | 3 +++ .../templates/trendpick/orders/order.html | 18 +++++++++--------- 5 files changed, 24 insertions(+), 11 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java b/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java index fed02098..6da69194 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java @@ -10,6 +10,9 @@ public class MemberInfoDto { private String name; private String email; + public MemberInfoDto() { + } + public MemberInfoDto(String name, String email, String phone, String address) { this.name = name; this.email = email; diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 29d0cd74..b410a810 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -2,9 +2,11 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; +import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.dto.MemberInfoDto; import project.trendpick_pro.domain.orders.entity.Order; import project.trendpick_pro.domain.orders.entity.OrderItem; @@ -23,6 +25,7 @@ public class OrderController { private final OrderService orderService; + private final Rq rq; @GetMapping("/order") public String order(OrderForm orderForm, Model model){ @@ -39,10 +42,11 @@ public String order(OrderForm orderForm, Model model){ } @PostMapping("/order") - public synchronized String processOrder(@ModelAttribute OrderForm orderForm, + @ResponseBody + public synchronized String processOrder(@ModelAttribute("orderForm") OrderForm orderForm, @RequestParam("paymentMethod") String paymentMethod) { - // 예시: 주문 정보 출력 + System.out.println("회원 이름: " + orderForm.getMemberInfo().getName()); System.out.println("이메일: " + orderForm.getMemberInfo().getEmail()); System.out.println("주문 아이템 목록:"); diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java index df04dd6f..ffe61d81 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java @@ -21,4 +21,7 @@ public OrderForm(MemberInfoDto memberInfo, List orderItems) { this.memberInfo = memberInfo; this.orderItems = orderItems; } + + public OrderForm() { + } } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java index fae0c743..5430d9f2 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java @@ -15,4 +15,7 @@ public OrderItemDto(String productName, int count, int price) { this.count = count; this.price = price; } + + public OrderItemDto() { + } } diff --git a/src/main/resources/templates/trendpick/orders/order.html b/src/main/resources/templates/trendpick/orders/order.html index 1d24ba9b..c6d408c9 100644 --- a/src/main/resources/templates/trendpick/orders/order.html +++ b/src/main/resources/templates/trendpick/orders/order.html @@ -11,10 +11,10 @@

주문서

회원 정보

-

회원 이름:

-

이메일:

-

번호:

-

주소:

+

회원 이름:

+

이메일:

+

번호:

+

주소:

주문 아이템 목록

@@ -23,10 +23,10 @@

주문 아이템 목록

- - - - + + + +
수량 가격
@@ -38,7 +38,7 @@

결제 수단 선택

- +
\ No newline at end of file From ad6578be9cf65e719be7a340e544b328459f9ac7 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 5 Jun 2023 18:59:14 +0900 Subject: [PATCH 158/367] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20=EB=93=B1?= =?UTF-8?q?=EB=A1=9D,=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B0=9C=EC=84=A0=20+=20=ED=94=84=EB=A1=A0=ED=8A=B8=20?= =?UTF-8?q?=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 상품명/상품 이미지 불러오면 오류 발생 --- .../review/controller/ReviewController.java | 16 ++++- .../domain/review/entity/Review.java | 8 +-- .../entity/dto/response/ReviewResponse.java | 8 +-- .../review/repository/ReviewRepository.java | 4 +- .../domain/review/service/ReviewService.java | 14 ++++ .../templates/trendpick/review/list.html | 64 +++++++++++++++++++ .../templates/trendpick/review/register.html | 41 ++++++++++++ 7 files changed, 144 insertions(+), 11 deletions(-) create mode 100644 src/main/resources/templates/trendpick/review/list.html create mode 100644 src/main/resources/templates/trendpick/review/register.html diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index 3f09888e..5f420cb4 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -2,6 +2,8 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Pageable; +import org.springframework.data.web.PageableDefault; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -42,7 +44,7 @@ public String createReview(@Valid ReviewSaveRequest reviewCreateRequest, ReviewResponse reviewResponse = reviewService.createReview(member, 1L, reviewCreateRequest, mainFile, subFiles); model.addAttribute("reviewResponse", reviewResponse); - return "redirect:/trendpick/review/list"; + return "/trendpick/review/list"; } @@ -69,4 +71,16 @@ public String updateReview(@PathVariable Long reviewId, ReviewSaveRequest review model.addAttribute("reviewResponse", reviewResponse); return "redirect:/trendpick/review"; } + +// @GetMapping("/list") +// public String showAllReview(@RequestParam(value = "page", defaultValue = "0")int offset, Model model){ +// model.addAttribute("reviewListResponse", reviewService.showAll(offset)); +// return "/trendpick/review/list"; +// } + + @GetMapping("/list") + public String showAllReview(@PageableDefault(size = 8)Pageable pageable, Model model){ + model.addAttribute("reviewResponses", reviewService.showAll(pageable)); + return "/trendpick/review/list"; + } } diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java index 3aedfeda..1caa1cba 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -51,14 +51,14 @@ public Review(Member member, Product product, CommonFile file, String title, Str this.rating = rating; } - public static Review of(ReviewSaveRequest reviewCreateRequest, Member member, Product product, CommonFile file) { + public static Review of(ReviewSaveRequest reviewSaveRequest, Member member, Product product, CommonFile file) { return Review.builder() .writer(member.getUsername()) .product(product) .file(file) - .title(reviewCreateRequest.title()) - .content(reviewCreateRequest.content()) - .rating(reviewCreateRequest.rating()) + .title(reviewSaveRequest.title()) + .content(reviewSaveRequest.content()) + .rating(reviewSaveRequest.rating()) .build(); } diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java b/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java index 0107a3c4..4299cd91 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/dto/response/ReviewResponse.java @@ -19,7 +19,7 @@ public class ReviewResponse { private Long id; private String writer; //User - private Long productId; //Product + private String productName; //Product private String mainFile; private List subFiles; private String title; @@ -30,11 +30,11 @@ public class ReviewResponse { @Builder @QueryProjection - public ReviewResponse(Long id, String writer, Long productId, String title, String content, + public ReviewResponse(Long id, String writer, String productName, String title, String content, String mainFile, List subFiles, int rating) { this.id = id; this.writer = writer; - this.productId = productId; + this.productName = productName; this.title = title; this.content = content; this.mainFile = mainFile; @@ -46,7 +46,7 @@ public static ReviewResponse of(Review review) { return ReviewResponse.builder() .id(review.getId()) .writer(review.getWriter()) - .productId(review.getProduct().getId()) + .productName(review.getProduct().getName()) .title(review.getTitle()) .content(review.getContent()) .mainFile(review.getFile().getFileName()) diff --git a/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java b/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java index 877db871..7aa8190b 100644 --- a/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java +++ b/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java @@ -1,9 +1,9 @@ package project.trendpick_pro.domain.review.repository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import project.trendpick_pro.domain.review.entity.Review; -import java.util.List; - public interface ReviewRepository extends JpaRepository { } diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index 630e8abe..2648c3bb 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -3,6 +3,9 @@ import com.querydsl.core.util.FileUtils; import lombok.RequiredArgsConstructor; import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -93,4 +96,15 @@ public ReviewResponse modify(Long reviewId, ReviewSaveRequest reviewSaveRequest, return ReviewResponse.of(review); } + + @Transactional + public Page showAll(Pageable pageable) { + return reviewRepository.findAll(pageable); + } + +// public Page showAll(int offset) { +// Pageable pageable = PageRequest.of(offset, 20); +// Page reviews = reviewRepository.findAllByPage(pageable); +// return reviews.map(ReviewResponse::of); +// } } diff --git a/src/main/resources/templates/trendpick/review/list.html b/src/main/resources/templates/trendpick/review/list.html new file mode 100644 index 00000000..fd2d63b8 --- /dev/null +++ b/src/main/resources/templates/trendpick/review/list.html @@ -0,0 +1,64 @@ + + + + 게시물 목록 + + + +리뷰리스트입니다 +
+
+
+

+

작성자:

+ + +

내용:

+

평점:

+
+
+
+ + +
+ Previous + + + + Next +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/templates/trendpick/review/register.html b/src/main/resources/templates/trendpick/review/register.html new file mode 100644 index 00000000..76780245 --- /dev/null +++ b/src/main/resources/templates/trendpick/review/register.html @@ -0,0 +1,41 @@ + + + + + + + 리뷰 등록 폼 + + + +
+
+ + +
+ +
+ + +
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+ + \ No newline at end of file From 9e858ab3deca77398b25ad76b0c2a731fa37962c Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Mon, 5 Jun 2023 20:14:13 +0900 Subject: [PATCH 159/367] =?UTF-8?q?feat:=20=ED=8E=98=EC=9D=B4=EC=A7=95=20?= =?UTF-8?q?=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 이미지 링크만 불러와지는 버그 해결해야 함 --- .../domain/review/controller/ReviewController.java | 6 ++++-- .../trendpick_pro/domain/review/service/ReviewService.java | 5 +++-- src/main/resources/templates/trendpick/review/list.html | 4 ++-- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index 5f420cb4..361f6cdb 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -2,6 +2,7 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.web.PageableDefault; import org.springframework.security.core.context.SecurityContextHolder; @@ -79,8 +80,9 @@ public String updateReview(@PathVariable Long reviewId, ReviewSaveRequest review // } @GetMapping("/list") - public String showAllReview(@PageableDefault(size = 8)Pageable pageable, Model model){ - model.addAttribute("reviewResponses", reviewService.showAll(pageable)); + public String showAllReview(Pageable pageable, Model model){ + Page reviewResponses = reviewService.showAll(pageable); + model.addAttribute("reviewResponses", reviewResponses); return "/trendpick/review/list"; } } diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index 2648c3bb..155edc12 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -98,8 +98,9 @@ public ReviewResponse modify(Long reviewId, ReviewSaveRequest reviewSaveRequest, } @Transactional - public Page showAll(Pageable pageable) { - return reviewRepository.findAll(pageable); + public Page showAll(Pageable pageable) { + Page reviewPage = reviewRepository.findAll(pageable); + return reviewPage.map(ReviewResponse::of); } // public Page showAll(int offset) { diff --git a/src/main/resources/templates/trendpick/review/list.html b/src/main/resources/templates/trendpick/review/list.html index fd2d63b8..2a805d0e 100644 --- a/src/main/resources/templates/trendpick/review/list.html +++ b/src/main/resources/templates/trendpick/review/list.html @@ -11,8 +11,8 @@

작성자:

- - +

상품명:

+

메인 파일:

내용:

평점:

From 825a756fa571b7527a894fc7150326faab37243e Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Mon, 5 Jun 2023 23:52:50 +0900 Subject: [PATCH 160/367] =?UTF-8?q?feat:=20=EA=B8=B0=EB=B3=B8=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80=20(#116)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/basedata/BaseData.java | 156 ++++++++++++------ .../basedata/tagname/entity/TagName.java | 31 ++++ .../tagname/entity/dto/TagNameResponse.java | 16 ++ .../tagname/repository/TagNameRepository.java | 13 ++ .../tagname/service/TagNameService.java | 29 ++++ src/main/resources/application-data.yml | 16 +- 6 files changed, 204 insertions(+), 57 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/global/basedata/tagname/entity/TagName.java create mode 100644 src/main/java/project/trendpick_pro/global/basedata/tagname/entity/dto/TagNameResponse.java create mode 100644 src/main/java/project/trendpick_pro/global/basedata/tagname/repository/TagNameRepository.java create mode 100644 src/main/java/project/trendpick_pro/global/basedata/tagname/service/TagNameService.java diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index 12a31e48..eef6dcde 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -6,6 +6,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Profile; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.brand.service.BrandService; import project.trendpick_pro.domain.category.entity.MainCategory; import project.trendpick_pro.domain.category.service.MainCategoryService; @@ -15,11 +16,14 @@ import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; +import project.trendpick_pro.domain.product.service.ProductService; import project.trendpick_pro.domain.tags.favoritetag.entity.FavoriteTag; import project.trendpick_pro.domain.tags.tag.entity.Tag; import project.trendpick_pro.domain.tags.tag.entity.type.TagType; -import project.trendpick_pro.domain.tags.tag.service.TagService; +import project.trendpick_pro.global.basedata.tagname.service.TagNameService; +import java.io.File; +import java.io.FileInputStream; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -34,16 +38,31 @@ public class BaseData { @Value("${main-category}") List mainCategories; - @Value("${sub-category-1}") - List subCategories1; + @Value("${top}") + List tops; + + @Value("${outer}") + List outers; + + @Value("${bottom}") + List bottoms; + + @Value("${shoes}") + List shoes; + + @Value("${bag}") + List bags; + + @Value("${accessory}") + List accessories; @Value("${brand}") List brands; @Bean CommandLineRunner initData( - TagService tagService, - ProductRepository productRepository, + TagNameService tagNameService, + ProductService productService, MemberRepository memberRepository, MainCategoryService mainCategoryService, SubCategoryService subCategoryService, @@ -54,68 +73,66 @@ CommandLineRunner initData( @Transactional public void run(String... args) { //원활한 테스트를 위해 잠깐 주석처리 -// for (String tag : tags) { -// tagService.save(tag); -// } + for (String tag : tags) { + tagNameService.save(tag); + } for (String mainCategory : mainCategories) { mainCategoryService.save(mainCategory); } - for (String subCategory : subCategories1) { - MainCategory mainCategory = mainCategoryService.findByName("상의"); - subCategoryService.save(subCategory, mainCategory); - } + CreateSubCategories(mainCategoryService, subCategoryService); for (String brand : brands) { brandService.save(brand); } + // member1은 시티보이룩(10점), 빈티지룩(5점), 로멘틱룩(1점)을 선호 태그로 가지고 있다. // 상품1은 시티보이룩을 가지고 있다 // 상품2는 시티보이룩, 빈티지룩을 가지고 있다 // 상품3은 시티보이룩, 빈티지룩, 로멘틱룩을 모두 가지고 있다. // - Member member1 = memberRepository.save(Member.builder().username("member1").email("jjj@naver.com").phoneNumber("01099999999").role(RoleType.MEMBER).password("111111").build()); - FavoriteTag favorTag1 = new FavoriteTag("시티보이룩"); - favorTag1.increaseScore(TagType.SHOW);//상품클릭해서 1점 누적. - member1.addTag(favorTag1); - - FavoriteTag favorTag2 = new FavoriteTag("빈티지룩"); - favorTag2.increaseScore(TagType.CART);//장바구니 담아서 5점 누적. - member1.addTag(favorTag2); - - FavoriteTag favorTag3 = new FavoriteTag("로멘틱룩"); - favorTag3.increaseScore(TagType.ORDER);//상품 주문해서 10점 누적. - member1.addTag(favorTag3); - -// 상품1은 시티보이룩을 가지고 있다 - Set tags1 = new LinkedHashSet<>(); - Product product1 = Product.builder().name("상품1").tags(tags1).description("설명1").price(500).stock(100).build(); - product1.addTag(new Tag("시티보이룩")); - -// 상품2는 시티보이룩, 빈티지룩을 가지고 있다 - Set tags2 = new LinkedHashSet<>(); - Product product2 = Product.builder().name("상품2").tags(tags2).description("설명2").price(500).stock(100).build(); - product2.addTag(new Tag("시티보이룩")); - product2.addTag(new Tag("빈티지룩")); - - Set tags3 = new LinkedHashSet<>(); - Product product3 = Product.builder().name("상품3").tags(tags3).description("설명3").price(500).stock(100).build(); - product3.addTag(new Tag("시티보이룩")); - product3.addTag(new Tag("빈티지룩")); - product3.addTag(new Tag("로멘틱룩")); - productRepository.save(product1); - productRepository.save(product2); - productRepository.save(product3); - - Set tags4 = new LinkedHashSet<>(); - Product product4 = Product.builder().name("상품4").tags(tags4).description("설명4").price(500).stock(100).build(); - product4.addTag(new Tag("원숭이룩")); - productRepository.save(product1); - productRepository.save(product2); - productRepository.save(product3); - productRepository.save(product4); +// Member member1 = memberRepository.save(Member.builder().username("member1").email("jjj@naver.com").phoneNumber("01099999999").role(RoleType.MEMBER).password("111111").build()); +// FavoriteTag favorTag1 = new FavoriteTag("시티보이룩"); +// favorTag1.increaseScore(TagType.SHOW);//상품클릭해서 1점 누적. +// member1.addTag(favorTag1); +// +// FavoriteTag favorTag2 = new FavoriteTag("빈티지룩"); +// favorTag2.increaseScore(TagType.CART);//장바구니 담아서 5점 누적. +// member1.addTag(favorTag2); +// +// FavoriteTag favorTag3 = new FavoriteTag("로멘틱룩"); +// favorTag3.increaseScore(TagType.ORDER);//상품 주문해서 10점 누적. +// member1.addTag(favorTag3); +// +//// 상품1은 시티보이룩을 가지고 있다 +// Set tags1 = new LinkedHashSet<>(); +// Product product1 = Product.builder().name("상품1").tags(tags1).description("설명1").price(500).stock(100).build(); +// product1.addTag(new Tag("시티보이룩")); +// +//// 상품2는 시티보이룩, 빈티지룩을 가지고 있다 +// Set tags2 = new LinkedHashSet<>(); +// Product product2 = Product.builder().name("상품2").tags(tags2).description("설명2").price(500).stock(100).build(); +// product2.addTag(new Tag("시티보이룩")); +// product2.addTag(new Tag("빈티지룩")); +// +// Set tags3 = new LinkedHashSet<>(); +// Product product3 = Product.builder().name("상품3").tags(tags3).description("설명3").price(500).stock(100).build(); +// product3.addTag(new Tag("시티보이룩")); +// product3.addTag(new Tag("빈티지룩")); +// product3.addTag(new Tag("로멘틱룩")); +// productService.save(product1); +// productService.save(product2); +// productService.save(product3); +// +// Set tags4 = new LinkedHashSet<>(); +// Product product4 = Product.builder().name("상품4").tags(tags4).description("설명4").price(500).stock(100).build(); +// product4.addTag(new Tag("원숭이룩")); +// productService.save(product1); +// productService.save(product2); +// productService.save(product3); +// productService.save(product4); //member1의 추천상품을 가져오면 로멘틱룩, 빈티지룩, 시티보이룩 순서대로 가져와야 한다. //상품 4는 member의 선호태그를 가지고 있지 않으므로 추천되지 않아야 한다. @@ -125,10 +142,39 @@ public void run(String... args) { // tags3.add(new Tag("빈티지룩")); // tags3.add(new Tag("로멘틱룩")); // Product product3 = Product.builder().name("상품3").tags(tags3).description("설명3").price(500).stock(100).build(); -// - -// T } }; } + + private void CreateSubCategories(MainCategoryService mainCategoryService, SubCategoryService subCategoryService) { + for (String top : tops) { + MainCategory mainCategory = mainCategoryService.findByName("상의"); + subCategoryService.save(top, mainCategory); + } + + for (String outer : outers) { + MainCategory mainCategory = mainCategoryService.findByName("아우터"); + subCategoryService.save(outer, mainCategory); + } + + for (String bottom : bottoms) { + MainCategory mainCategory = mainCategoryService.findByName("하의"); + subCategoryService.save(bottom, mainCategory); + } + + for (String shoe : shoes) { + MainCategory mainCategory = mainCategoryService.findByName("신발"); + subCategoryService.save(shoe, mainCategory); + } + + for (String bag : bags) { + MainCategory mainCategory = mainCategoryService.findByName("가방"); + subCategoryService.save(bag, mainCategory); + } + + for (String accessory : accessories) { + MainCategory mainCategory = mainCategoryService.findByName("악세서리"); + subCategoryService.save(accessory, mainCategory); + } + } } diff --git a/src/main/java/project/trendpick_pro/global/basedata/tagname/entity/TagName.java b/src/main/java/project/trendpick_pro/global/basedata/tagname/entity/TagName.java new file mode 100644 index 00000000..fe7bc085 --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/basedata/tagname/entity/TagName.java @@ -0,0 +1,31 @@ +package project.trendpick_pro.global.basedata.tagname.entity; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor(access = lombok.AccessLevel.PROTECTED) +public class TagName { + + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + private String name; + + public TagName(String name) { + this.name = name; + } + + @Override + public String toString() { + return "TagName{" + + "id=" + id + + ", name='" + name + '\'' + + '}'; + } +} diff --git a/src/main/java/project/trendpick_pro/global/basedata/tagname/entity/dto/TagNameResponse.java b/src/main/java/project/trendpick_pro/global/basedata/tagname/entity/dto/TagNameResponse.java new file mode 100644 index 00000000..66dc4303 --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/basedata/tagname/entity/dto/TagNameResponse.java @@ -0,0 +1,16 @@ +package project.trendpick_pro.global.basedata.tagname.entity.dto; + +import lombok.AccessLevel; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class TagNameResponse { + + private String name; + + public TagNameResponse(String name) { + this.name = name; + } +} diff --git a/src/main/java/project/trendpick_pro/global/basedata/tagname/repository/TagNameRepository.java b/src/main/java/project/trendpick_pro/global/basedata/tagname/repository/TagNameRepository.java new file mode 100644 index 00000000..84ea5f71 --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/basedata/tagname/repository/TagNameRepository.java @@ -0,0 +1,13 @@ +package project.trendpick_pro.global.basedata.tagname.repository; + +import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.global.basedata.tagname.entity.TagName; + +import java.util.List; + +public interface TagNameRepository extends JpaRepository { + + TagName findByName(String tagName); + + List findAllBy(); +} diff --git a/src/main/java/project/trendpick_pro/global/basedata/tagname/service/TagNameService.java b/src/main/java/project/trendpick_pro/global/basedata/tagname/service/TagNameService.java new file mode 100644 index 00000000..6609e4f9 --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/basedata/tagname/service/TagNameService.java @@ -0,0 +1,29 @@ +package project.trendpick_pro.global.basedata.tagname.service; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import project.trendpick_pro.global.basedata.tagname.entity.TagName; +import project.trendpick_pro.global.basedata.tagname.entity.dto.TagNameResponse; +import project.trendpick_pro.global.basedata.tagname.repository.TagNameRepository; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class TagNameService { + + private final TagNameRepository tagNameRepository; + + public void save(String name) { + tagNameRepository.save(new TagName(name)); + } + + public TagName findByName(String name) { + return tagNameRepository.findByName(name); + } + + public List findAll() { + List tags = tagNameRepository.findAllBy(); + return tags.stream().map(tagName -> new TagNameResponse(tagName.getName())).toList(); + } +} diff --git a/src/main/resources/application-data.yml b/src/main/resources/application-data.yml index 08e7b896..1e27b12e 100644 --- a/src/main/resources/application-data.yml +++ b/src/main/resources/application-data.yml @@ -8,8 +8,20 @@ tag: main-category: 추천, 상의, 아우터, 하의, 신발, 가방, 악세서리 -sub-category-1: - 전체, 반소매 티셔츠, 긴소매 티셔츠, 피케/카라 티셔츠, 셔츠/블라우스, 니트/스웨터, 후드 티셔츠, 맨투맨/스웨트셔츠 + +top: + 반소매티셔츠, 긴소매티셔츠, 피케/카라 티셔츠, 셔츠/블라우스, 니트/스웨터, 후드티셔츠, 맨투맨/스웨트셔츠 +outer: + 후드집업, 라이더자켓, 블루종, 싱글코드, 더블코드, 롱패딩, 숏패딩, 카디건, 플리스, 코치자켓, 기타아우터 +bottom: + 데님팬츠, 숏팬츠, 코튼팬츠, 레깅스, 슬랙스, 트레이닝팬츠, 기타바지 +shoes: + 구두, 샌들, 로퍼, 슬리퍼, 힐, 플랫슈즈, 부츠, 블로퍼 +bag: + 백팩, 웨이스트백, 메신저백, 캐리어, 숄더백, 토트백, 에코백, 더플백, 클러치백 +accessory: + 벨트, 장갑, 스카프, 키링, 넥타이, 머플러, 기타악세서리 + brand: 아디다스, 나이키, 버버리, 라퍼퍼 \ No newline at end of file From 50046b13b591c04e4a79360fb014c8b57e9c2d5e Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Tue, 6 Jun 2023 00:11:20 +0900 Subject: [PATCH 161/367] =?UTF-8?q?refactor:=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=20=ED=8F=BC=20=EA=B0=9C=EC=84=A0=20(#118)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/brand/service/BrandService.java | 4 ++ .../repository/SubCategoryRepository.java | 11 ++++- .../category/service/SubCategoryService.java | 12 +++-- .../base/filetranslator/FileTranslator.java | 2 +- .../member/controller/MemberController.java | 7 +-- .../product/controller/ProductController.java | 44 ++++++----------- .../domain/product/entity/Product.java | 24 ++++----- .../dto/request/ProductSaveRequest.java | 42 +++++++++++----- .../entity/dto/response/ProductResponse.java | 21 ++++---- .../product/service/ProductService.java | 49 ++++++++----------- .../recommend/service/RecommendService.java | 2 +- .../domain/review/service/ReviewService.java | 2 +- .../exception/GlobalExceptionAdvice.java | 8 ++- .../global/security/SecurityConfig.java | 41 ++++++++++++---- .../trendpick/products/detailpage.html | 44 +++++++++++++++-- .../trendpick/products/register.html | 36 ++++++++++++-- .../templates/trendpick/usr/member/join.html | 14 ++++-- 17 files changed, 238 insertions(+), 125 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/brand/service/BrandService.java b/src/main/java/project/trendpick_pro/domain/brand/service/BrandService.java index ea7534e5..f79595fc 100644 --- a/src/main/java/project/trendpick_pro/domain/brand/service/BrandService.java +++ b/src/main/java/project/trendpick_pro/domain/brand/service/BrandService.java @@ -30,4 +30,8 @@ public void delete(Long id){ public List findAll(){ return brandRepository.findAllBy(); } + + public Brand findByName(String name) { + return brandRepository.findByName(name); + } } diff --git a/src/main/java/project/trendpick_pro/domain/category/repository/SubCategoryRepository.java b/src/main/java/project/trendpick_pro/domain/category/repository/SubCategoryRepository.java index 7e812a69..1f332501 100644 --- a/src/main/java/project/trendpick_pro/domain/category/repository/SubCategoryRepository.java +++ b/src/main/java/project/trendpick_pro/domain/category/repository/SubCategoryRepository.java @@ -1,12 +1,19 @@ package project.trendpick_pro.domain.category.repository; +import org.hibernate.annotations.Parameter; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; +import project.trendpick_pro.domain.category.entity.MainCategory; import project.trendpick_pro.domain.category.entity.SubCategory; import project.trendpick_pro.domain.category.entity.dto.response.SubCategoryResponse; import java.util.List; public interface SubCategoryRepository extends JpaRepository { - public SubCategory findByName(String name); - List findAllBy(); + SubCategory findByName(String name); + + @Query("select c from SubCategory c where c.mainCategory.name=:mainCategory") + List findAllByMainCategory(@Param("mainCategory") String mainCategory); + List findAllBy(); } diff --git a/src/main/java/project/trendpick_pro/domain/category/service/SubCategoryService.java b/src/main/java/project/trendpick_pro/domain/category/service/SubCategoryService.java index 508b5774..4ddecd97 100644 --- a/src/main/java/project/trendpick_pro/domain/category/service/SubCategoryService.java +++ b/src/main/java/project/trendpick_pro/domain/category/service/SubCategoryService.java @@ -19,8 +19,6 @@ public class SubCategoryService { private final SubCategoryRepository subCategoryRepository; - private final MainCategoryService mainCategoryService; - @Transactional public void save(String name, MainCategory mainCategory){ subCategoryRepository.save(new SubCategory(name, mainCategory)); @@ -31,8 +29,14 @@ public void delete(Long id){ SubCategory subCategory = subCategoryRepository.findById(id).orElseThrow(); subCategoryRepository.delete(subCategory); } - public List findAll() { - return subCategoryRepository.findAllBy(); + public List findAll(String mainCategoryName) { + if (mainCategoryName.equals("전체")){ + List categories = subCategoryRepository.findAllBy(); + return categories.stream().map(subCategory -> new SubCategoryResponse(subCategory.getName())).toList(); + } else { + List categories = subCategoryRepository.findAllByMainCategory(mainCategoryName); + return categories.stream().map(subCategory -> new SubCategoryResponse(subCategory.getName())).toList(); + } } public SubCategoryResponse findById(Long id){ diff --git a/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java b/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java index 9fdaea21..d0e512d5 100644 --- a/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java +++ b/src/main/java/project/trendpick_pro/domain/common/base/filetranslator/FileTranslator.java @@ -13,7 +13,7 @@ @Component public class FileTranslator { - @Value("${file.dir}") + @Value("${file.path}") private String filePath; //저장경로 public String getFilePath(String filename) { diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java index 65ecb17d..523d10b7 100644 --- a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java +++ b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java @@ -15,6 +15,7 @@ import project.trendpick_pro.domain.member.entity.form.JoinForm; import project.trendpick_pro.domain.member.service.MemberService; import project.trendpick_pro.domain.tags.tag.service.TagService; +import project.trendpick_pro.global.basedata.tagname.service.TagNameService; @Slf4j @Controller @@ -23,7 +24,7 @@ public class MemberController { private final MemberService memberService; - private final TagService tagService; + private final TagNameService tagNameService; private final Rq rq; @@ -31,7 +32,7 @@ public class MemberController { @GetMapping("/register") public String register(JoinForm joinForm, Model model) { model.addAttribute("joinForm", joinForm); - model.addAttribute("allTags", tagService.getAllTags()); + model.addAttribute("allTags", tagNameService.findAll()); return "trendpick/usr/member/join"; } @@ -39,7 +40,7 @@ public String register(JoinForm joinForm, Model model) { @PostMapping("/register") public String register(@Valid JoinForm joinForm, BindingResult bindingResult, Model model) { if (bindingResult.hasErrors()) { - model.addAttribute("allTags", tagService.getAllTags()); + model.addAttribute("allTags", tagNameService.findAll()); return "trendpick/usr/member/join"; } memberService.register(joinForm); diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 662ba436..f35e6294 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -1,10 +1,8 @@ package project.trendpick_pro.domain.product.controller; -import io.swagger.v3.core.util.Json; import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.jetbrains.annotations.NotNull; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -13,21 +11,14 @@ import project.trendpick_pro.domain.brand.service.BrandService; import project.trendpick_pro.domain.category.service.MainCategoryService; import project.trendpick_pro.domain.category.service.SubCategoryService; -import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.member.repository.MemberRepository; -import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; -import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; import project.trendpick_pro.domain.product.service.ProductService; import project.trendpick_pro.domain.recommend.service.RecommendService; -import project.trendpick_pro.domain.tags.tag.service.TagService; +import project.trendpick_pro.global.basedata.tagname.service.TagNameService; import java.io.IOException; -import java.util.HashMap; -import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; @Slf4j @Controller @@ -36,23 +27,22 @@ public class ProductController { private final ProductService productService; - private final TagService tagService; + private final RecommendService recommendService; + + private final TagNameService tagNameService; + private final BrandService brandService; private final MainCategoryService mainCategoryService; private final SubCategoryService subCategoryService; - private final BrandService brandService; - private final RecommendService recommendService; - private final MemberRepository memberRepository; @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") @GetMapping("/register") - public String registerProduct(ProductSaveRequest productSaveRequest, Model model) { + public String registerProduct(ProductSaveRequest productSaveRequest, @RequestParam("main-category") String mainCategory, Model model) { model.addAttribute("productSaveRequest", productSaveRequest); - model.addAttribute("tags", tagService.getAllTags()); + model.addAttribute("tags", tagNameService.findAll()); model.addAttribute("mainCategories", mainCategoryService.findAll()); - model.addAttribute("subCategories", subCategoryService.findAll()); + model.addAttribute("subCategories", subCategoryService.findAll(mainCategory)); model.addAttribute("brands", brandService.findAll()); - log.debug("gotoregister"); return "/trendpick/products/register"; } @@ -60,29 +50,23 @@ public String registerProduct(ProductSaveRequest productSaveRequest, Model model @PostMapping("/register") public String register(@ModelAttribute @Valid ProductSaveRequest productSaveRequest, @RequestParam("mainFile") MultipartFile mainFile, - @RequestParam("subFiles") List subFiles, @NotNull Model model) throws IOException { + @RequestParam("subFiles") List subFiles) throws IOException { log.info("registerProduct: {}", productSaveRequest.toString()); - ProductResponse productResponse = productService.register(productSaveRequest, mainFile, subFiles); - model.addAttribute("productResponse", productResponse); - - return "redirect:/trendpick/products/detailpage"; + Long id = productService.register(productSaveRequest, mainFile, subFiles); + return "redirect:/trendpick/products/" + id; } @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") @PostMapping("/edit/{productId}") public String modifyProduct(@PathVariable Long productId, @Valid ProductSaveRequest productSaveRequest, @RequestParam("mainFile") MultipartFile mainFile, - @RequestParam("subFiles") List subFiles, Model model) throws IOException { - - ProductResponse productResponse = productService.modify(productId, productSaveRequest, mainFile, subFiles ); - model.addAttribute("productResponse", productResponse); - - return "redirect:/trendpick/products/" + productResponse.getId(); + @RequestParam("subFiles") List subFiles) throws IOException { + Long id = productService.modify(productId, productSaveRequest, mainFile, subFiles); + return "redirect:/trendpick/products/" + id; } @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") @DeleteMapping("/{productId}") public String deleteProduct(@PathVariable Long productId) { - productService.delete(productId); return "redirect:/trendpick/products/list"; } diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index 7a72dce9..473b39d4 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -77,14 +77,14 @@ public Product(String name, MainCategory mainCategory, SubCategory subCategory, public static Product of(ProductSaveRequest request, MainCategory mainCategory , SubCategory subCategory, Brand brand,CommonFile file) { return Product.builder() - .name(request.name()) + .name(request.getName()) .mainCategory(mainCategory) .subCategory(subCategory) .brand(brand) - .description(request.description()) + .description(request.getDescription()) .file(file) - .price(request.price()) - .stock(request.stock()) + .price(request.getPrice()) + .stock(request.getStock()) .build(); } @@ -108,10 +108,10 @@ public void addReview(int rating){ } public void update(ProductSaveRequest request, CommonFile file) { - this.name = request.name(); - this.description = request.description(); - this.price = request.price(); - this.stock = request.stock(); + this.name = request.getName(); + this.description = request.getDescription(); + this.price = request.getPrice(); + this.stock = request.getStock(); this.file = file; } @@ -124,8 +124,10 @@ public String toString() { '}'; } - public void addTag(Tag tag){ - getTags().add(tag); - tag.connectProduct(this); + public void addTag(Set tags){ + this.tags = tags; + for (Tag tag : tags) { + tag.connectProduct(this); + } } } diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java index 7362a980..1351ac1b 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java @@ -3,18 +3,39 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import lombok.*; +import project.trendpick_pro.domain.product.entity.Product; import java.util.List; -public record ProductSaveRequest( - @NotBlank(message = "제목을 입력해주세요.") String name, - @NotBlank(message = "내용을 입력해주세요.") String description, - @NotBlank(message = "메인 카테고리를 정하세요.") String mainCategory, - @NotBlank(message = "서브 카테고리를 정하세요.") String subCategory, - @NotBlank(message = "브랜드를 입력해주세요.") String brand, - @NotNull(message = "가격을 입력해주세요.") Integer price, - @NotNull(message = "수량을 입력해주세요.") Integer stock, - @NotEmpty(message = "포함될 태그들을 추가해주세요.") List tags) { +@Data +@NoArgsConstructor +@AllArgsConstructor +public class ProductSaveRequest { + @NotBlank(message = "제목을 입력해주세요.") + private String name; + + @NotBlank(message = "내용을 입력해주세요.") + private String description; + + @NotBlank(message = "메인 카테고리를 정하세요.") + private String mainCategory; + + @NotBlank(message = "서브 카테고리를 정하세요.") + private String subCategory; + + @NotBlank(message = "브랜드를 입력해주세요.") + private String brand; + + @NotNull(message = "가격을 입력해주세요.") + private Integer price; + + @NotNull(message = "수량을 입력해주세요.") + private Integer stock; + + @NotEmpty(message = "포함될 태그들을 추가해주세요.") + private List tags; + @Override public String toString() { return "ProductSaveRequest{" + @@ -28,5 +49,4 @@ public String toString() { ", tags=" + tags + '}'; } -} - +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java index 07660137..1c8bae12 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java @@ -18,20 +18,21 @@ public class ProductResponse { private Long id; private String name; - private String mainCategory; // Category - private String subCategory; // Category - private String brand; // Brand + private String mainCategory; + private String subCategory; + private String brand; private String description; private String mainFile; private List subFiles; private int price; private int stock; private List tags = new ArrayList<>(); + private String role; @Builder @QueryProjection public ProductResponse(Long id, String name, String mainCategory, String subCategory, String brand, String description, - String mainFile, List subFiles, int price, int stock, List tags) { + String mainFile, List subFiles, int price, int stock, List tags, String role) { this.id = id; this.name = name; this.mainCategory = mainCategory; @@ -43,9 +44,10 @@ public ProductResponse(Long id, String name, String mainCategory, String subCate this.price = price; this.stock = stock; this.tags = tags; + this.role = role; } - public static ProductResponse of (Product product) { + public static ProductResponse of (String filePath, Product product, String role) { return ProductResponse.builder() .id(product.getId()) .name(product.getName()) @@ -53,19 +55,20 @@ public static ProductResponse of (Product product) { .subCategory(product.getSubCategory().getName()) .brand(product.getBrand().getName()) .description(product.getDescription()) - .mainFile(product.getFile().getFileName()) - .subFiles(subFiles(product.getFile().getChild())) + .mainFile(filePath + product.getFile().getFileName()) + .subFiles(subFiles(filePath, product.getFile().getChild())) .price(product.getPrice()) .stock(product.getStock()) .tags(new ArrayList<>(product.getTags())) + .role(role) .build(); } - private static List subFiles(List subFiles) { + private static List subFiles(String filePath, List subFiles) { List tmpList = new ArrayList<>(); for (CommonFile subFile : subFiles) { - tmpList.add(subFile.getFileName()); + tmpList.add(filePath + subFile.getFileName()); } return tmpList; } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index a7f82c0d..8cb96452 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -13,11 +13,11 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.brand.entity.Brand; -import project.trendpick_pro.domain.brand.repository.BrandRepository; +import project.trendpick_pro.domain.brand.service.BrandService; import project.trendpick_pro.domain.category.entity.MainCategory; import project.trendpick_pro.domain.category.entity.SubCategory; -import project.trendpick_pro.domain.category.repository.MainCategoryRepository; -import project.trendpick_pro.domain.category.repository.SubCategoryRepository; +import project.trendpick_pro.domain.category.service.MainCategoryService; +import project.trendpick_pro.domain.category.service.SubCategoryService; import project.trendpick_pro.domain.common.base.filetranslator.FileTranslator; import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; @@ -37,7 +37,6 @@ import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tags.tag.entity.Tag; import project.trendpick_pro.domain.tags.tag.entity.type.TagType; -import project.trendpick_pro.domain.tags.tag.service.TagService; import java.io.File; import java.io.IOException; @@ -50,19 +49,20 @@ public class ProductService { private final ProductRepository productRepository; + private final MemberRepository memberRepository; - private final MainCategoryRepository mainCategoryRepository; - private final SubCategoryRepository subCategoryRepository; - private final BrandRepository brandRepository; + private final MainCategoryService mainCategoryService; + private final SubCategoryService subCategoryService; + private final BrandService brandService; + private final FileTranslator fileTranslator; private final FavoriteTagService favoriteTagService; - private final TagService tagService; - @Value("${file.dir}") + @Value("${file.path}") private String filePath; @Transactional - public ProductResponse register(ProductSaveRequest productSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { + public Long register(ProductSaveRequest productSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { CheckMember(); @@ -74,46 +74,42 @@ public ProductResponse register(ProductSaveRequest productSaveRequest, Multipart } Set tags = new LinkedHashSet<>(); // 상품에 포함시킬 태크 선택하여 저장 - for (String tagName : productSaveRequest.tags()) { + for (String tagName : productSaveRequest.getTags()) { tags.add(new Tag(tagName)); } - MainCategory mainCategory = mainCategoryRepository.findByName(productSaveRequest.mainCategory()); - SubCategory subCategory = subCategoryRepository.findByName(productSaveRequest.subCategory()); - Brand brand = brandRepository.findByName(productSaveRequest.brand()); + MainCategory mainCategory = mainCategoryService.findByName(productSaveRequest.getMainCategory()); + SubCategory subCategory = subCategoryService.findByName(productSaveRequest.getSubCategory()); + Brand brand = brandService.findByName(productSaveRequest.getBrand()); Product product = Product.of(productSaveRequest, mainCategory, subCategory, brand, mainFile); - for(Tag tag : tags) - product.addTag(tag); + product.addTag(tags); productRepository.save(product); - return ProductResponse.of(product); + return product.getId(); } @Transactional - public ProductResponse modify(Long productId, ProductSaveRequest productSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { + public Long modify(Long productId, ProductSaveRequest productSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { - CheckMember(); + Member member = CheckMember(); Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 CommonFile mainFile = product.getFile(); List subFiles = product.getFile().getChild(); if(requestMainFile!=null){ - // 기존 이미지 삭제 FileUtils.delete(new File(mainFile.getFileName())); - // 이미지 업데이트 } mainFile = fileTranslator.translateFile(requestMainFile); if(requestSubFiles!=null){ - // 기존 이미지 삭제 for(CommonFile subFile:subFiles){ FileUtils.delete(new File(subFile.getFileName())); } } - // 이미지 업데이트 + subFiles = fileTranslator.translateFileList(requestSubFiles); for (CommonFile subFile : subFiles) { @@ -121,15 +117,12 @@ public ProductResponse modify(Long productId, ProductSaveRequest productSaveRequ } product.update(productSaveRequest, mainFile); - - return ProductResponse.of(product); + return product.getId(); } @Transactional public void delete(Long productId) { - CheckMember(); - Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 productRepository.delete(product); } @@ -140,7 +133,7 @@ public ProductResponse show(Long productId) { Member member = CheckMember(); favoriteTagService.updateTag(member, product, TagType.SHOW); - return ProductResponse.of(product); + return ProductResponse.of(filePath, product, member.getRole().getValue()); } public Page showAll(int offset, String mainCategory, String subCategory, Integer sortCode) { diff --git a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java index fdde7864..185f1e3e 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java @@ -33,7 +33,7 @@ public class RecommendService { private final ProductService productService; private final MemberRepository memberRepository; - @Value("${file.dir}") + @Value("${file.path}") private String filePath; //recommend -> 태그 기반 추천 상품들이 있어야 함 diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index 630e8abe..fe1dbaff 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -29,7 +29,7 @@ public class ReviewService { private final ProductRepository productRepository; private final FileTranslator fileTranslator; - @Value("${file.dir}") + @Value("${file.path}") private static String filePath; diff --git a/src/main/java/project/trendpick_pro/global/exception/GlobalExceptionAdvice.java b/src/main/java/project/trendpick_pro/global/exception/GlobalExceptionAdvice.java index 77328323..c8badd64 100644 --- a/src/main/java/project/trendpick_pro/global/exception/GlobalExceptionAdvice.java +++ b/src/main/java/project/trendpick_pro/global/exception/GlobalExceptionAdvice.java @@ -1,5 +1,7 @@ package project.trendpick_pro.global.exception; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import lombok.extern.slf4j.Slf4j; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ControllerAdvice; @@ -14,10 +16,10 @@ public class GlobalExceptionAdvice { @ExceptionHandler(MemberNotFoundException.class) - public String MemberNotFoundHandleException(MemberNotFoundException e, Model model) { + public String MemberNotFoundHandleException(HttpServletRequest request, MemberNotFoundException e, Model model) { log.error("[exceptionHandle] ex", e); model.addAttribute("errorMessage", e.getMessage()); - return "trendpick/usr/member/join"; + return request.getRequestURI(); } @ExceptionHandler(MemberNotMatchException.class) @@ -40,4 +42,6 @@ public String ProductNotFoundHandleException(ProductNotFoundException e, Model m model.addAttribute("errorMessage", e.getMessage()); return "trendpick/usr/member/join"; } + + } diff --git a/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java b/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java index 002cdfd3..62a2622c 100644 --- a/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java +++ b/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java @@ -14,19 +14,40 @@ @EnableWebSecurity public class SecurityConfig { +// @Bean +// SecurityFilterChain filterChain(HttpSecurity http) throws Exception { +// http +// .formLogin( +// formLogin -> formLogin +// .loginPage("/trendpick/member/login") +// .loginProcessingUrl("/login_proc") +// .defaultSuccessUrl("/trendpick/products/list") +// ) +// .logout( +// logout -> logout +// .logoutUrl("/trendpick/member/logout") +// ); +// return http.build(); +// } + @Bean SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http - .formLogin( - formLogin -> formLogin - .loginPage("/trendpick/member/login") - .loginProcessingUrl("/login_proc") - .defaultSuccessUrl("/trendpick/products/list") - ) - .logout( - logout -> logout - .logoutUrl("/trendpick/member/logout") - ); + .csrf().disable() + .authorizeHttpRequests() + .requestMatchers("/register").hasAnyAuthority("ADMIN", "BRAND_ADMIN") + .requestMatchers("/admin/**").hasRole("ADMIN") + .anyRequest().authenticated() + .and() + .formLogin() + .loginPage("/trendpick/member/login") + .loginProcessingUrl("/login_proc") + .defaultSuccessUrl("/trendpick/products/list") + .permitAll() + .and() + .logout() + .logoutUrl("/trendpick/member/logout") + .permitAll(); return http.build(); } diff --git a/src/main/resources/templates/trendpick/products/detailpage.html b/src/main/resources/templates/trendpick/products/detailpage.html index 566549bd..086034cf 100644 --- a/src/main/resources/templates/trendpick/products/detailpage.html +++ b/src/main/resources/templates/trendpick/products/detailpage.html @@ -1,10 +1,46 @@ - + - Title + + 상품 상세 페이지 + + - + +
+

제품명

+
+
+ 메인 이미지 +
+ 서브 이미지 +
+
+ +
+

상품 설명

+

상품 설명

+ +

상세 정보

+
    +
  • 메인 카테고리: 메인 카테고리
  • +
  • 서브 카테고리: 서브 카테고리
  • +
  • 브랜드: 브랜드
  • +
  • 가격: 가격
  • +
  • 재고: 재고
  • +
  • 태그: +
      +
    • 태그
    • +
    +
  • +
+ + + +
+
+
- \ No newline at end of file + diff --git a/src/main/resources/templates/trendpick/products/register.html b/src/main/resources/templates/trendpick/products/register.html index 1d0be62d..b9be5961 100644 --- a/src/main/resources/templates/trendpick/products/register.html +++ b/src/main/resources/templates/trendpick/products/register.html @@ -8,7 +8,7 @@ -
+
@@ -24,12 +24,12 @@
+
-
@@ -68,8 +68,12 @@
-
- +
+
+ + +
+

@@ -77,4 +81,28 @@ + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/member/join.html b/src/main/resources/templates/trendpick/usr/member/join.html index 6d6e3090..3bbd6d43 100644 --- a/src/main/resources/templates/trendpick/usr/member/join.html +++ b/src/main/resources/templates/trendpick/usr/member/join.html @@ -43,14 +43,20 @@

회원 가입

+
- -
- - +

본인이 선호하는 태그를 선택 해주세요!

+
+
+ + +
+

+ +
From d46b3d9f2c0f1b68a4d92c35012b0480f0e145e3 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 6 Jun 2023 00:24:13 +0900 Subject: [PATCH 162/367] =?UTF-8?q?feat:=20=EC=A3=BC=EB=AC=B8=EC=8B=9C=20?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=A0=95=EC=83=81=EC=A0=81?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EC=A0=80=EC=9E=A5(#112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/common/base/rq/Rq.java | 5 +-- .../domain/delivery/entity/Delivery.java | 5 ++- .../member/entity/dto/MemberInfoDto.java | 4 ++- .../domain/member/service/MemberService.java | 5 +++ .../orders/contoller/OrderController.java | 33 +++++++++++++------ .../domain/orders/entity/Order.java | 5 ++- .../domain/orders/entity/OrderItem.java | 7 +++- .../orders/entity/dto/request/OrderForm.java | 1 + .../entity/dto/response/OrderItemDto.java | 8 ++++- .../domain/orders/service/OrderService.java | 20 +++++------ .../templates/trendpick/orders/order.html | 2 ++ 11 files changed, 66 insertions(+), 29 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java index 76dfbb33..6890edb3 100644 --- a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java +++ b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java @@ -10,6 +10,7 @@ import org.springframework.stereotype.Component; import org.springframework.web.context.annotation.RequestScope; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.service.MemberService; import java.util.Date; @@ -52,11 +53,11 @@ public boolean isLogout() { // 로그인 된 회원의 객체 public Member getMember() { - if (isLogout()) return null; // 데이터가 없는지 체크 if (member == null) { - member = memberService.findByUsername(user.getUsername()).orElseThrow(); + Member member = + memberService.findByEmail(SecurityContextHolder.getContext().getAuthentication().getName()); } return member; diff --git a/src/main/java/project/trendpick_pro/domain/delivery/entity/Delivery.java b/src/main/java/project/trendpick_pro/domain/delivery/entity/Delivery.java index fd2b4f2d..cd2e7b53 100644 --- a/src/main/java/project/trendpick_pro/domain/delivery/entity/Delivery.java +++ b/src/main/java/project/trendpick_pro/domain/delivery/entity/Delivery.java @@ -19,12 +19,11 @@ public class Delivery extends BaseTimeEntity { @OneToOne(mappedBy = "delivery", fetch = FetchType.LAZY) private Order order; - @Embedded - private Address address; + private String address; @Enumerated(EnumType.STRING) private DeliveryState state; - public Delivery(Address address){ + public Delivery(String address){ this.address = address; state = DeliveryState.READY; //주문과 함께 생성시 초기에는 준비중. } diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java b/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java index 6da69194..97dbb7cc 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java @@ -7,17 +7,19 @@ @Setter public class MemberInfoDto { + private Long memberId; private String name; private String email; public MemberInfoDto() { } - public MemberInfoDto(String name, String email, String phone, String address) { + public MemberInfoDto(Long memberId, String name, String email, String phone, String address) { this.name = name; this.email = email; this.phone = phone; this.address = address; + this.memberId = memberId; } private String phone; diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index d4e62cd4..f725797c 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -32,6 +32,11 @@ public Optional findByUsername(String username) { return memberRepository.findByUsername(username); } + public Member findByEmail(String username){ + return memberRepository.findByEmail(username) + .orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); + } + @Transactional public void register(JoinForm joinForm) { diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index b410a810..0d4bd2cb 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -2,17 +2,18 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; import project.trendpick_pro.domain.common.base.rq.Rq; +import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.dto.MemberInfoDto; -import project.trendpick_pro.domain.orders.entity.Order; -import project.trendpick_pro.domain.orders.entity.OrderItem; +import project.trendpick_pro.domain.member.service.MemberService; import project.trendpick_pro.domain.orders.entity.dto.request.OrderForm; import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; import project.trendpick_pro.domain.orders.service.OrderService; +import project.trendpick_pro.domain.product.repository.ProductRepository; import java.util.ArrayList; import java.util.List; @@ -26,14 +27,16 @@ public class OrderController { private final OrderService orderService; private final Rq rq; + private final MemberService memberService; + private final ProductRepository productRepository; @GetMapping("/order") public String order(OrderForm orderForm, Model model){ - MemberInfoDto memberInfo = new MemberInfoDto("member1", "email", "000", "서울"); + MemberInfoDto memberInfo = new MemberInfoDto(2L, "admin", "admin@naver.com", "000", "서울"); List orderItems = new ArrayList<>(); - orderItems.add(new OrderItemDto("상품1", 5, 500)); - orderItems.add(new OrderItemDto("상품2", 1, 100)); - orderItems.add(new OrderItemDto("상품3", 2, 200)); + orderItems.add(new OrderItemDto(1L, "상품1", 5, 500)); + orderItems.add(new OrderItemDto(2L, "상품2", 1, 100)); + orderItems.add(new OrderItemDto(3L, "상품3", 2, 200)); orderForm = new OrderForm(memberInfo, orderItems); model.addAttribute("orderForm", orderForm); @@ -43,8 +46,7 @@ public String order(OrderForm orderForm, Model model){ @PostMapping("/order") @ResponseBody - public synchronized String processOrder(@ModelAttribute("orderForm") OrderForm orderForm, - @RequestParam("paymentMethod") String paymentMethod) { + public synchronized String processOrder(@ModelAttribute("orderForm") OrderForm orderForm) { System.out.println("회원 이름: " + orderForm.getMemberInfo().getName()); @@ -55,8 +57,19 @@ public synchronized String processOrder(@ModelAttribute("orderForm") OrderForm o System.out.println("수량: " + orderItem.getCount()); System.out.println("가격: " + orderItem.getPrice()); } - System.out.println("결제 수단: " + paymentMethod); + System.out.println("결제 수단: " + orderForm.getPaymentMethod()); + Member member = memberService.findByEmail(SecurityContextHolder.getContext().getAuthentication().getName()); +// if(member.getId() != orderForm.getMemberInfo().getMemberId()) +// throw new RuntimeException("잘못된 접근입니다."); + + log.info(member.getUsername()); + log.info(String.valueOf(member.getId())); + log.info(orderForm.getMemberInfo().getName()); + log.info(orderForm.getOrderItems().get(0).getProductName()); + log.info(String.valueOf(orderForm.getOrderItems().get(0).getProductId())); + + orderService.order(member, orderForm); return "주문성공"; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java index 6f6a3e89..f0979c8d 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java @@ -32,6 +32,8 @@ public class Order extends BaseTimeEntity { @OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL) @JoinColumn(name = "delivery_id") private Delivery delivery; + @Column(name = "payment_method", nullable = false) + private String paymentMethod; @Enumerated(EnumType.STRING) private OrderStatus status; @@ -52,7 +54,7 @@ public void addOrderItem(OrderItem orderItem) { orderItem.connectOrder(this); } - public static Order createOrder(Member member, Delivery delivery, OrderStatus status, List orderItems) { + public static Order createOrder(Member member, Delivery delivery, OrderStatus status, List orderItems, String paymentMethod) { Order order = new Order(); order.connectUser(member); order.connectDelivery(delivery); @@ -61,6 +63,7 @@ public static Order createOrder(Member member, Delivery delivery, OrderStatus st order.totalPrice += orderItem.getTotalPrice(); } order.status = status; + order.paymentMethod = paymentMethod; return order; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java index 26846ed7..49317549 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java @@ -5,6 +5,7 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; import project.trendpick_pro.domain.product.entity.Product; @Entity @@ -31,7 +32,7 @@ public class OrderItem { @Column(name = "count", nullable = false) private int count; - public OrderItem(Product product, int orderPrice, int count) { + private OrderItem(Product product, int orderPrice, int count) { this.product = product; this.orderPrice = orderPrice; this.count = count; @@ -39,6 +40,10 @@ public OrderItem(Product product, int orderPrice, int count) { product.removeStock(count); } + public static OrderItem of(Product product, OrderItemDto orderItemDto) { + return new OrderItem(product, orderItemDto.getPrice(), orderItemDto.getCount()); + } + public void connectOrder(Order order) { this.order = order; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java index ffe61d81..2614b1f5 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java @@ -16,6 +16,7 @@ public class OrderForm { private MemberInfoDto memberInfo; private List orderItems; + private String paymentMethod; public OrderForm(MemberInfoDto memberInfo, List orderItems) { this.memberInfo = memberInfo; diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java index 5430d9f2..a0645377 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java @@ -6,16 +6,22 @@ @Getter @Setter public class OrderItemDto { + private Long productId; private String productName; private int count; private int price; - public OrderItemDto(String productName, int count, int price) { + public OrderItemDto(Long productId, String productName, int count, int price) { this.productName = productName; this.count = count; this.price = price; + this.productId = productId; } public OrderItemDto() { } + + public int getTotalPrice(){ + return getPrice() * count; + } } diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 83994d61..228fba2b 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -9,6 +9,8 @@ import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.delivery.entity.Delivery; import project.trendpick_pro.domain.delivery.entity.embaded.Address; +import project.trendpick_pro.domain.orders.entity.dto.request.OrderForm; +import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.exception.MemberNotFoundException; @@ -41,24 +43,22 @@ public class OrderService { private final FavoriteTagService favoriteTagService; @Transactional - public void order(Long userId, OrderSaveRequest... orderSaveRequests) { + public void order(Member member, OrderForm orderForm) { - Member member = memberRepository.findById(userId).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 유저 입니다."));// 임시 exception 설정 나중에 할 수도 있고 아닐수도 - - Delivery delivery = new Delivery(Address.of("서울시", "강남대로", "222")); // 임의로 작성 + Delivery delivery = new Delivery(orderForm.getMemberInfo().getAddress()); List orderItemList = new ArrayList<>(); - for (OrderSaveRequest request: orderSaveRequests) { - Product product = productRepository.findById(request.getProductId()).orElseThrow(() -> new ProductNotFoundException("존재하지 않는 상품 입니다.")); - if (product.getStock() < request.getQuantity()) { - throw new ProductStockOutException("재고가 부족합니다."); // 임시. 나중에 사용자 exception 널을까말까 생각 + for (OrderItemDto orderItemDto : orderForm.getOrderItems()) { + Product product = productRepository.findById(orderItemDto.getProductId()).orElseThrow(() -> new ProductNotFoundException("존재하지 않는 상품 입니다.")); + if (product.getStock() < orderItemDto.getCount()) { + throw new ProductStockOutException(product.getName()+"의 재고가 부족합니다."); // 임시. 나중에 사용자 exception 널을까말까 생각 } favoriteTagService.updateTag(member, product, TagType.ORDER); - orderItemList.add(new OrderItem(product, product.getPrice(), request.getQuantity())); + orderItemList.add(OrderItem.of(product, orderItemDto)); } - Order order = Order.createOrder(member, delivery, OrderStatus.ORDERED, orderItemList); + Order order = Order.createOrder(member, delivery, OrderStatus.ORDERED, orderItemList, orderForm.getPaymentMethod()); orderRepository.save(order); } diff --git a/src/main/resources/templates/trendpick/orders/order.html b/src/main/resources/templates/trendpick/orders/order.html index c6d408c9..f4692909 100644 --- a/src/main/resources/templates/trendpick/orders/order.html +++ b/src/main/resources/templates/trendpick/orders/order.html @@ -11,6 +11,7 @@

주문서

회원 정보

+

회원 이름:

이메일:

번호:

@@ -24,6 +25,7 @@

주문 아이템 목록

가격 + From 169f5e5ffd0b6a922994a3facb38723e340fe576 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 6 Jun 2023 00:33:37 +0900 Subject: [PATCH 163/367] =?UTF-8?q?fix:=20=ED=98=84=EC=9E=AC=20=EC=A0=80?= =?UTF-8?q?=EC=9E=A5=EB=90=98=EC=96=B4=20=EC=9E=88=EB=8A=94=20=EC=83=81?= =?UTF-8?q?=ED=92=88=EC=9D=B4=20=EC=97=86=EC=96=B4=EC=84=9C=20=ED=85=8C?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8=EC=BD=94=EB=93=9C=20=EC=A3=BC=EC=84=9D?= =?UTF-8?q?=EC=B2=98=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orders/contoller/OrderController.java | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 0d4bd2cb..c064d893 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -31,14 +31,15 @@ public class OrderController { private final ProductRepository productRepository; @GetMapping("/order") - public String order(OrderForm orderForm, Model model){ - MemberInfoDto memberInfo = new MemberInfoDto(2L, "admin", "admin@naver.com", "000", "서울"); - List orderItems = new ArrayList<>(); - orderItems.add(new OrderItemDto(1L, "상품1", 5, 500)); - orderItems.add(new OrderItemDto(2L, "상품2", 1, 100)); - orderItems.add(new OrderItemDto(3L, "상품3", 2, 200)); - - orderForm = new OrderForm(memberInfo, orderItems); + public String order(@ModelAttribute OrderForm orderForm, Model model){ +// MemberInfoDto memberInfo = new MemberInfoDto(2L, "admin", "admin@naver.com", "000", "서울"); +// List orderItems = new ArrayList<>(); +// orderItems.add(new OrderItemDto(1L, "상품1", 5, 500)); +// orderItems.add(new OrderItemDto(2L, "상품2", 1, 100)); +// orderItems.add(new OrderItemDto(3L, "상품3", 2, 200)); +// orderForm = new OrderForm(memberInfo, orderItems); + + //상품 상세 또는 장바구니에서 OrderForm으로 데이터가 날라오게끔 model.addAttribute("orderForm", orderForm); return "trendpick/orders/order"; From 5076146eba21eada419267847c9b6a663d40d974 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 6 Jun 2023 14:22:48 +0900 Subject: [PATCH 164/367] =?UTF-8?q?feat:=20OrderByMemberResponse=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EC=83=9D=EC=84=B1=20(=EB=82=98=EC=9D=98?= =?UTF-8?q?=EC=A3=BC=EB=AC=B8=EB=AA=A9=EB=A1=9D)(#112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orders/contoller/OrderController.java | 26 +++++++-------- .../dto/response/OrderByMemberResponse.java | 33 +++++++++++++++++++ .../entity/dto/response/OrderResponse.java | 3 -- 3 files changed, 46 insertions(+), 16 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderByMemberResponse.java diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index c064d893..9d7d20a8 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -31,7 +31,7 @@ public class OrderController { private final ProductRepository productRepository; @GetMapping("/order") - public String order(@ModelAttribute OrderForm orderForm, Model model){ + public String orderForm(@ModelAttribute OrderForm orderForm, Model model){ // MemberInfoDto memberInfo = new MemberInfoDto(2L, "admin", "admin@naver.com", "000", "서울"); // List orderItems = new ArrayList<>(); // orderItems.add(new OrderItemDto(1L, "상품1", 5, 500)); @@ -47,18 +47,18 @@ public String order(@ModelAttribute OrderForm orderForm, Model model){ @PostMapping("/order") @ResponseBody - public synchronized String processOrder(@ModelAttribute("orderForm") OrderForm orderForm) { - - - System.out.println("회원 이름: " + orderForm.getMemberInfo().getName()); - System.out.println("이메일: " + orderForm.getMemberInfo().getEmail()); - System.out.println("주문 아이템 목록:"); - for (OrderItemDto orderItem : orderForm.getOrderItems()) { - System.out.println("상품명: " + orderItem.getProductName()); - System.out.println("수량: " + orderItem.getCount()); - System.out.println("가격: " + orderItem.getPrice()); - } - System.out.println("결제 수단: " + orderForm.getPaymentMethod()); + public synchronized String order(@ModelAttribute("orderForm") OrderForm orderForm) { + + +// System.out.println("회원 이름: " + orderForm.getMemberInfo().getName()); +// System.out.println("이메일: " + orderForm.getMemberInfo().getEmail()); +// System.out.println("주문 아이템 목록:"); +// for (OrderItemDto orderItem : orderForm.getOrderItems()) { +// System.out.println("상품명: " + orderItem.getProductName()); +// System.out.println("수량: " + orderItem.getCount()); +// System.out.println("가격: " + orderItem.getPrice()); +// } +// System.out.println("결제 수단: " + orderForm.getPaymentMethod()); Member member = memberService.findByEmail(SecurityContextHolder.getContext().getAuthentication().getName()); // if(member.getId() != orderForm.getMemberInfo().getMemberId()) diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderByMemberResponse.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderByMemberResponse.java new file mode 100644 index 00000000..4eebfe73 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderByMemberResponse.java @@ -0,0 +1,33 @@ +package project.trendpick_pro.domain.orders.entity.dto.response; + +import com.querydsl.core.annotations.QueryProjection; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.time.LocalDateTime; + +@Getter +@NoArgsConstructor +public class OrderByMemberResponse { + + private String productImage; + private String brandName; + private String productName; + private String size; + private LocalDateTime orderDate; + private int totalPrice; + private String orderStatus; + private String deliveryStatus; + + @QueryProjection + public OrderByMemberResponse(String productImage, String brandName, String productName, String size, LocalDateTime orderDate, int totalPrice, String orderStatus, String deliveryStatus) { + this.productImage = productImage; + this.brandName = brandName; + this.productName = productName; + this.size = size; + this.orderDate = orderDate; + this.totalPrice = totalPrice; + this.orderStatus = orderStatus; + this.deliveryStatus = deliveryStatus; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java index c94150f2..3e8dd586 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java @@ -5,9 +5,6 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import project.trendpick_pro.domain.delivery.entity.DeliveryState; -import project.trendpick_pro.domain.orders.entity.Order; -import project.trendpick_pro.domain.orders.entity.OrderItem; import java.time.LocalDateTime; From a271a9d1a3718a749ab80fb1bd2c369711d890fb Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 6 Jun 2023 14:28:03 +0900 Subject: [PATCH 165/367] =?UTF-8?q?refactor:=20=EA=B8=B0=EC=A1=B4=EC=97=90?= =?UTF-8?q?=20=EC=9E=88=EB=8D=98=20OrderResponse=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81=ED=95=B4=EC=84=9C=20=EC=82=AC=EC=9A=A9(#112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../dto/response/OrderByMemberResponse.java | 33 ------------------- .../entity/dto/response/OrderResponse.java | 16 ++++++--- 2 files changed, 11 insertions(+), 38 deletions(-) delete mode 100644 src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderByMemberResponse.java diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderByMemberResponse.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderByMemberResponse.java deleted file mode 100644 index 4eebfe73..00000000 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderByMemberResponse.java +++ /dev/null @@ -1,33 +0,0 @@ -package project.trendpick_pro.domain.orders.entity.dto.response; - -import com.querydsl.core.annotations.QueryProjection; -import lombok.Getter; -import lombok.NoArgsConstructor; - -import java.time.LocalDateTime; - -@Getter -@NoArgsConstructor -public class OrderByMemberResponse { - - private String productImage; - private String brandName; - private String productName; - private String size; - private LocalDateTime orderDate; - private int totalPrice; - private String orderStatus; - private String deliveryStatus; - - @QueryProjection - public OrderByMemberResponse(String productImage, String brandName, String productName, String size, LocalDateTime orderDate, int totalPrice, String orderStatus, String deliveryStatus) { - this.productImage = productImage; - this.brandName = brandName; - this.productName = productName; - this.size = size; - this.orderDate = orderDate; - this.totalPrice = totalPrice; - this.orderStatus = orderStatus; - this.deliveryStatus = deliveryStatus; - } -} diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java index 3e8dd586..825eec83 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java @@ -13,20 +13,26 @@ public class OrderResponse { private Long orderId; + private String productFilePath; private String brandName; - private String orderItemName; - private LocalDateTime order_date; + private String productName; + private String size; + private LocalDateTime orderDate; private int totalPrice; + private String orderStatus; private String deliveryStatus; @Builder @QueryProjection - public OrderResponse(Long orderId, String brandName, String productName, LocalDateTime order_date, int totalPrice, String deliveryStatus) { + public OrderResponse(Long orderId, String productFilePath, String brandName, String productName, String size, LocalDateTime orderDate, int totalPrice, String orderStatus, String deliveryStatus) { this.orderId = orderId; + this.productFilePath = productFilePath; this.brandName = brandName; - this.orderItemName = productName; - this.order_date = order_date; + this.productName = productName; + this.size = size; + this.orderDate = orderDate; this.totalPrice = totalPrice; + this.orderStatus = orderStatus; this.deliveryStatus = deliveryStatus; } } From 4c5fc5035fa5fb862e460c8dce02ad22a5de79a8 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Tue, 6 Jun 2023 15:38:38 +0900 Subject: [PATCH 166/367] =?UTF-8?q?refactor:=20=EA=B8=B0=EB=B3=B8=20?= =?UTF-8?q?=EB=A9=A4=EB=B2=84=20=EC=B6=94=EA=B0=80(=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=EC=9E=90)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/entity/form/JoinForm.java | 4 ++- .../domain/member/service/MemberService.java | 13 +++++--- .../global/basedata/BaseData.java | 33 +++++++++++++++++-- 3 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java b/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java index 2fe292f9..b59727dc 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java @@ -2,13 +2,15 @@ import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotEmpty; +import lombok.Builder; import java.util.List; +@Builder public record JoinForm(@NotBlank(message = "email을 입력해주세요.") String email, @NotBlank(message = "password를 입력해주세요.") String password, @NotBlank(message = "이름을 입력해주세요.") String username, @NotBlank(message = "휴대폰 번호를 입력해주세요.") String phoneNumber, @NotBlank(message = "권한을 입력해주세요.") String state, - @NotEmpty(message = "선호하는 태그를 입력해주세요.")List tags) { + List tags) { } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index f725797c..6b3907eb 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -62,14 +62,17 @@ public void register(JoinForm joinForm) { .role(roleType) .build(); - Set favoriteTags = new LinkedHashSet<>(); - for (String tag : joinForm.tags()) { + if (!joinForm.tags().isEmpty()) { + Set favoriteTags = new LinkedHashSet<>(); + for (String tag : joinForm.tags()) { // Tag findTag = tagRepository.findByName(tag).orElseThrow(); // favoriteTag.connectMember(member); - FavoriteTag favoriteTag = new FavoriteTag(tag); - favoriteTags.add(favoriteTag); + FavoriteTag favoriteTag = new FavoriteTag(tag); + favoriteTags.add(favoriteTag); + } + member.changeTags(favoriteTags); } - member.changeTags(favoriteTags); + memberRepository.save(member); } diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index eef6dcde..c9c56299 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -13,7 +13,9 @@ import project.trendpick_pro.domain.category.service.SubCategoryService; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.RoleType; +import project.trendpick_pro.domain.member.entity.form.JoinForm; import project.trendpick_pro.domain.member.repository.MemberRepository; +import project.trendpick_pro.domain.member.service.MemberService; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.product.service.ProductService; @@ -62,8 +64,7 @@ public class BaseData { @Bean CommandLineRunner initData( TagNameService tagNameService, - ProductService productService, - MemberRepository memberRepository, + MemberService memberService, MainCategoryService mainCategoryService, SubCategoryService subCategoryService, BrandService brandService @@ -87,6 +88,34 @@ public void run(String... args) { brandService.save(brand); } + JoinForm admin = JoinForm.builder() + .email("admin@naver.com") + .password("12345") + .username("admin") + .phoneNumber("010-1234-1234") + .state("ADMIN") + .build(); + + JoinForm brand_admin = JoinForm.builder() + .email("brand@naver.com") + .password("12345") + .username("brand") + .phoneNumber("010-1234-1234") + .state("BRAND_ADMIN") + .build(); + + JoinForm member = JoinForm.builder() + .email("trendpick@naver.com") + .password("12345") + .username("sooho") + .phoneNumber("010-1234-1234") + .state("MEMBER") + .tags(List.of("오버핏청바지", "로맨틱룩")) + .build(); + + memberService.register(admin); + memberService.register(brand_admin); + memberService.register(member); // member1은 시티보이룩(10점), 빈티지룩(5점), 로멘틱룩(1점)을 선호 태그로 가지고 있다. // 상품1은 시티보이룩을 가지고 있다 From ea8e46944f520ebaefb7aa14d6a04733da175bb4 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Tue, 6 Jun 2023 15:44:03 +0900 Subject: [PATCH 167/367] =?UTF-8?q?refactor:=20=EA=B8=B0=EB=B3=B8=20?= =?UTF-8?q?=EB=A9=A4=EB=B2=84=20=EC=B6=94=EA=B0=80(=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=EC=9E=90)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trendpick_pro/domain/member/service/MemberService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index 6b3907eb..b64555f5 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -62,7 +62,7 @@ public void register(JoinForm joinForm) { .role(roleType) .build(); - if (!joinForm.tags().isEmpty()) { + if (joinForm.tags() != null) { Set favoriteTags = new LinkedHashSet<>(); for (String tag : joinForm.tags()) { // Tag findTag = tagRepository.findByName(tag).orElseThrow(); From 067ffb882b4ae61cd1ad0eecfd6080131ec2be72 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 6 Jun 2023 16:26:13 +0900 Subject: [PATCH 168/367] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EC=97=90=20?= =?UTF-8?q?=EB=94=B0=EB=A5=B8=20=EC=A3=BC=EB=AC=B8=EB=AA=A9=EB=A1=9D?= =?UTF-8?q?=EC=9D=84=20=EB=B0=98=ED=99=98=ED=95=98=EB=8A=94=20querydsl=20?= =?UTF-8?q?=EB=A1=9C=EC=A7=81=20=EA=B5=AC=ED=98=84(#112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/orders/entity/OrderItem.java | 3 + .../orders/repository/OrderRepository.java | 2 +- .../repository/OrderRepositoryCustom.java | 9 +++ .../repository/OrderRepositoryImpl.java | 65 +++++++++++++++++++ .../repository/ProductRepositoryImpl.java | 3 +- 5 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryCustom.java create mode 100644 src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java index 49317549..daee734d 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java @@ -31,6 +31,9 @@ public class OrderItem { @Column(name = "count", nullable = false) private int count; + @Column(name = "size", nullable = false) + + private String size; private OrderItem(Product product, int orderPrice, int count) { this.product = product; diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java index 81dee6f8..69762195 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java @@ -6,6 +6,6 @@ import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.orders.entity.Order; -public interface OrderRepository extends JpaRepository { +public interface OrderRepository extends JpaRepository, OrderRepositoryCustom { Page findAllByMember(Member member, Pageable pageable); } diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryCustom.java new file mode 100644 index 00000000..8fc266ff --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryCustom.java @@ -0,0 +1,9 @@ +package project.trendpick_pro.domain.orders.repository; + +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; + +public interface OrderRepositoryCustom { + public Page findAllByMember(Long memberId, Pageable pageable); +} diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java new file mode 100644 index 00000000..1126f715 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java @@ -0,0 +1,65 @@ +package project.trendpick_pro.domain.orders.repository; + +import com.querydsl.jpa.impl.JPAQuery; +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.support.PageableExecutionUtils; +import project.trendpick_pro.domain.brand.entity.QBrand; +import project.trendpick_pro.domain.delivery.entity.QDelivery; +import project.trendpick_pro.domain.member.entity.QMember; +import project.trendpick_pro.domain.orders.entity.QOrder; +import project.trendpick_pro.domain.orders.entity.QOrderItem; +import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; +import project.trendpick_pro.domain.orders.entity.dto.response.QOrderResponse; +import project.trendpick_pro.domain.product.entity.QProduct; + +import java.util.List; + +import static project.trendpick_pro.domain.delivery.entity.QDelivery.*; +import static project.trendpick_pro.domain.member.entity.QMember.*; +import static project.trendpick_pro.domain.orders.entity.QOrder.*; +import static project.trendpick_pro.domain.orders.entity.QOrderItem.*; +import static project.trendpick_pro.domain.product.entity.QProduct.*; + +public class OrderRepositoryImpl implements OrderRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + public OrderRepositoryImpl(EntityManager em) { + this.queryFactory = new JPAQueryFactory(em); + } + + //나의 주문목록 + @Override + public Page findAllByMember(Long memberId, Pageable pageable) { + List result = queryFactory + .select(new QOrderResponse( + product.id, + product.file.fileName, + product.brand.name, + product.name, + orderItem.size, + order.createdDate, + order.totalPrice, + order.status, + delivery.state) + ) + .from(order) + .join(order.member, member) + .on(member.id.eq(memberId)) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .orderBy(order.createdDate.asc()) + .fetch(); + + JPAQuery countQuery = queryFactory + .select(order.count()) + .from(order) + .join(order.member, member) + .on(member.id.eq(memberId)) + ; + return PageableExecutionUtils.getPage(result, pageable, countQuery::fetchOne); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index f15af106..b556214b 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -107,7 +107,8 @@ private static BooleanExpression subCategoryEq(ProductSearchCond cond) { } } - private static OrderSpecifier orderSelector(Integer sortCode) { + private static OrderSpecifier + orderSelector(Integer sortCode) { return switch (sortCode) { case 2 -> product.id.asc(); case 3 -> product.rateAvg.desc(); //평점 From d0894079d1174c09ece8505a54a745dd2daaab9c Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Tue, 6 Jun 2023 17:29:28 +0900 Subject: [PATCH 169/367] =?UTF-8?q?refactor:=20=EA=B8=B0=EB=B3=B8=20?= =?UTF-8?q?=EB=A9=A4=EB=B2=84=20=EC=B6=94=EA=B0=80(=EA=B4=80=EB=A6=AC?= =?UTF-8?q?=EC=9E=90)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/common/base/rq/Rq.java | 37 +++++++++++-------- .../domain/member/service/MemberService.java | 5 +-- .../orders/contoller/OrderController.java | 4 +- .../product/controller/ProductController.java | 18 +++++++-- .../product/service/ProductService.java | 34 ++++++++--------- .../templates/trendpick/products/list.html | 37 ++++++++++--------- 6 files changed, 76 insertions(+), 59 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java index 6890edb3..1b7a6fac 100644 --- a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java +++ b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java @@ -10,13 +10,15 @@ import org.springframework.stereotype.Component; import org.springframework.web.context.annotation.RequestScope; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.entity.RoleType; import project.trendpick_pro.domain.member.exception.MemberNotFoundException; +import project.trendpick_pro.domain.member.exception.MemberNotMatchException; import project.trendpick_pro.domain.member.service.MemberService; -import java.util.Date; +import java.util.Optional; @Component -@RequestScope //매 요청마다 생성됨 +@RequestScope public class Rq { private final MemberService memberService; private final HttpServletRequest req; @@ -41,26 +43,31 @@ public Rq(MemberService memberService, HttpServletRequest req, HttpServletRespon } } - // 로그인 되어 있는지 체크 - public boolean isLogin() { - return user != null; - } - - // 로그아웃 되어 있는지 체크 - public boolean isLogout() { - return !isLogin(); - } - // 로그인 된 회원의 객체 public Member getMember() { // 데이터가 없는지 체크 if (member == null) { - Member member = - memberService.findByEmail(SecurityContextHolder.getContext().getAuthentication().getName()); + member = memberService.findByEmail(SecurityContextHolder.getContext().getAuthentication().getName()) + .orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); } - return member; } + public Optional CheckMember() { + + String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 + Optional member = memberService.findByEmail(username); + + if (member.isPresent()) { + Member checkMember = member.get(); + if (checkMember.getRole().equals(RoleType.MEMBER)) { + throw new MemberNotMatchException("허용된 권한이 아닙니다."); + } + return Optional.of(checkMember); + } + else { + throw new MemberNotFoundException("존재하지 않는 회원입니다."); + } + } } diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index b64555f5..41c82170 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -32,9 +32,8 @@ public Optional findByUsername(String username) { return memberRepository.findByUsername(username); } - public Member findByEmail(String username){ - return memberRepository.findByEmail(username) - .orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); + public Optional findByEmail(String username){ + return memberRepository.findByEmail(username); } @Transactional diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index c064d893..9a1f748a 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -9,6 +9,7 @@ import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.dto.MemberInfoDto; +import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.service.MemberService; import project.trendpick_pro.domain.orders.entity.dto.request.OrderForm; import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; @@ -60,7 +61,8 @@ public synchronized String processOrder(@ModelAttribute("orderForm") OrderForm o } System.out.println("결제 수단: " + orderForm.getPaymentMethod()); - Member member = memberService.findByEmail(SecurityContextHolder.getContext().getAuthentication().getName()); + Member member = memberService.findByEmail(SecurityContextHolder.getContext().getAuthentication().getName()) + .orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); // if(member.getId() != orderForm.getMemberInfo().getMemberId()) // throw new RuntimeException("잘못된 접근입니다."); diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index f35e6294..3cfd468e 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -11,6 +11,8 @@ import project.trendpick_pro.domain.brand.service.BrandService; import project.trendpick_pro.domain.category.service.MainCategoryService; import project.trendpick_pro.domain.category.service.SubCategoryService; +import project.trendpick_pro.domain.common.base.rq.Rq; +import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; import project.trendpick_pro.domain.product.service.ProductService; @@ -19,6 +21,7 @@ import java.io.IOException; import java.util.List; +import java.util.Optional; @Slf4j @Controller @@ -35,6 +38,8 @@ public class ProductController { private final MainCategoryService mainCategoryService; private final SubCategoryService subCategoryService; + private final Rq rq; + @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") @GetMapping("/register") public String registerProduct(ProductSaveRequest productSaveRequest, @RequestParam("main-category") String mainCategory, Model model) { @@ -85,10 +90,17 @@ public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") i @RequestParam(value = "sub-category", defaultValue = "전체") String subCategory, @RequestParam(value = "sort", defaultValue = "1") Integer sortCode, Model model) { - if (mainCategory.equals("추천")) { - model.addAttribute("productResponses", recommendService.getFindAll(offset)); + Optional member = rq.CheckMember(); + + if (member.isPresent()) { + if (mainCategory.equals("추천")) { + model.addAttribute("productResponses", recommendService.getFindAll(offset)); + } else { + model.addAttribute("productResponses", productService.showAll(offset, mainCategory, subCategory, sortCode)); + } } else { model.addAttribute("productResponses", productService.showAll(offset, mainCategory, subCategory, sortCode)); - } return "/trendpick/products/list"; + } + return "/trendpick/products/list"; } } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 8cb96452..083fed93 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -19,9 +19,11 @@ import project.trendpick_pro.domain.category.service.MainCategoryService; import project.trendpick_pro.domain.category.service.SubCategoryService; import project.trendpick_pro.domain.common.base.filetranslator.FileTranslator; +import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.product.exception.ProductNotFoundException; +import project.trendpick_pro.domain.recommend.service.RecommendService; import project.trendpick_pro.domain.tags.favoritetag.entity.FavoriteTag; import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; import project.trendpick_pro.domain.member.entity.Member; @@ -50,7 +52,6 @@ public class ProductService { private final ProductRepository productRepository; - private final MemberRepository memberRepository; private final MainCategoryService mainCategoryService; private final SubCategoryService subCategoryService; private final BrandService brandService; @@ -58,13 +59,15 @@ public class ProductService { private final FileTranslator fileTranslator; private final FavoriteTagService favoriteTagService; + private final Rq rq; + @Value("${file.path}") private String filePath; @Transactional public Long register(ProductSaveRequest productSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { - CheckMember(); + rq.CheckMember(); CommonFile mainFile = fileTranslator.translateFile(requestMainFile); List subFiles = fileTranslator.translateFileList(requestSubFiles); @@ -92,7 +95,7 @@ public Long register(ProductSaveRequest productSaveRequest, MultipartFile reques @Transactional public Long modify(Long productId, ProductSaveRequest productSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { - Member member = CheckMember(); + rq.CheckMember(); Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 CommonFile mainFile = product.getFile(); @@ -122,7 +125,7 @@ public Long modify(Long productId, ProductSaveRequest productSaveRequest, Multip @Transactional public void delete(Long productId) { - CheckMember(); + rq.CheckMember(); Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 productRepository.delete(product); } @@ -130,10 +133,15 @@ public void delete(Long productId) { public ProductResponse show(Long productId) { Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 - Member member = CheckMember(); - favoriteTagService.updateTag(member, product, TagType.SHOW); + Optional member = rq.CheckMember(); - return ProductResponse.of(filePath, product, member.getRole().getValue()); + if (member.isPresent()){ + Member checkMember = member.get(); + favoriteTagService.updateTag(checkMember, product, TagType.SHOW); + return ProductResponse.of(filePath, product, checkMember.getRole().getValue()); + } else { + throw new MemberNotFoundException("존재하지 않는 회원입니다."); + } } public Page showAll(int offset, String mainCategory, String subCategory, Integer sortCode) { @@ -152,18 +160,6 @@ public Page showAll(int offset, String mainCategory, String return new PageImpl<>(list, pageable, listResponses.getTotalElements()); } - - private Member CheckMember() { - - String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 - Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); - - if (member.getRole().equals(RoleType.MEMBER)) { - throw new MemberNotMatchException("허용된 권한이 아닙니다."); - } - return member; - } - public List getRecommendProduct(Member member){ List tags = productRepository.findRecommendProduct(member.getUsername()); diff --git a/src/main/resources/templates/trendpick/products/list.html b/src/main/resources/templates/trendpick/products/list.html index 2329f591..ecf6a0d2 100644 --- a/src/main/resources/templates/trendpick/products/list.html +++ b/src/main/resources/templates/trendpick/products/list.html @@ -1,28 +1,29 @@ - 게시물 목록 + 상품 목록 -
- -
-

-

Brand:

-

Main File:

-

Price:

-
- +
+
+ +

+ Product Image +
+

Brand:

+

Price:

+
- -
- Previous - - - - Next +
+ +
+ Previous + + + + Next +
- From 1b898643e0a9c40fe9d8e13d23cd84884b4e5f17 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 6 Jun 2023 17:33:30 +0900 Subject: [PATCH 170/367] =?UTF-8?q?feat:=20MVC=20=EC=97=B0=EA=B2=B0,=20?= =?UTF-8?q?=EB=82=98=EC=9D=98=EC=A3=BC=EB=AC=B8=EB=AA=A9=EB=A1=9D=20?= =?UTF-8?q?=ED=8B=80=20=EC=9E=91=EC=84=B1(#112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orders/contoller/OrderController.java | 15 ++++++-- .../entity/dto/request/OrderSearchCond.java | 5 +++ .../orders/repository/OrderRepository.java | 1 - .../repository/OrderRepositoryCustom.java | 3 +- .../repository/OrderRepositoryImpl.java | 13 ++----- .../domain/orders/service/OrderService.java | 7 ++-- .../templates/trendpick/orders/list.html | 0 .../trendpick/usr/member/orders.html | 38 ++++++++++++++++++- 8 files changed, 62 insertions(+), 20 deletions(-) delete mode 100644 src/main/resources/templates/trendpick/orders/list.html diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 9d7d20a8..31270d3c 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -2,6 +2,8 @@ import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.data.domain.Page; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; @@ -11,7 +13,9 @@ import project.trendpick_pro.domain.member.entity.dto.MemberInfoDto; import project.trendpick_pro.domain.member.service.MemberService; import project.trendpick_pro.domain.orders.entity.dto.request.OrderForm; +import project.trendpick_pro.domain.orders.entity.dto.request.OrderSearchCond; import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; +import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; import project.trendpick_pro.domain.orders.service.OrderService; import project.trendpick_pro.domain.product.repository.ProductRepository; @@ -74,10 +78,15 @@ public synchronized String order(@ModelAttribute("orderForm") OrderForm orderFor return "주문성공"; } + + @PreAuthorize("isAuthenticated()") @GetMapping("/list") - public String orderList(Model model) { -// Page responses = orderService.findAll(1L); -// model.addAttribute("orders", responses); + public String orderListByMember(@RequestParam(value = "page", defaultValue = "0") int offset, + Model model) { + Member member = memberService.findByEmail(SecurityContextHolder.getContext().getAuthentication().getName()); + + Page orderList = orderService.findAllByMember(member, offset); + model.addAttribute("orderList", orderList); return "trendpick/usr/member/orders"; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSearchCond.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSearchCond.java index 583c8385..a9a56d4b 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSearchCond.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSearchCond.java @@ -1,10 +1,15 @@ package project.trendpick_pro.domain.orders.entity.dto.request; import lombok.Getter; +import lombok.NoArgsConstructor; @Getter +@NoArgsConstructor public class OrderSearchCond { private Long memberId; + public OrderSearchCond(Long memberId) { + this.memberId = memberId; + } } diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java index 69762195..b902d7fc 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepository.java @@ -7,5 +7,4 @@ import project.trendpick_pro.domain.orders.entity.Order; public interface OrderRepository extends JpaRepository, OrderRepositoryCustom { - Page findAllByMember(Member member, Pageable pageable); } diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryCustom.java index 8fc266ff..27f743d8 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryCustom.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryCustom.java @@ -2,8 +2,9 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; +import project.trendpick_pro.domain.orders.entity.dto.request.OrderSearchCond; import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; public interface OrderRepositoryCustom { - public Page findAllByMember(Long memberId, Pageable pageable); + public Page findAllByMember(OrderSearchCond orderSearchCond, Pageable pageable); } diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java index 1126f715..4af044c2 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java @@ -6,14 +6,9 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.support.PageableExecutionUtils; -import project.trendpick_pro.domain.brand.entity.QBrand; -import project.trendpick_pro.domain.delivery.entity.QDelivery; -import project.trendpick_pro.domain.member.entity.QMember; -import project.trendpick_pro.domain.orders.entity.QOrder; -import project.trendpick_pro.domain.orders.entity.QOrderItem; +import project.trendpick_pro.domain.orders.entity.dto.request.OrderSearchCond; import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; import project.trendpick_pro.domain.orders.entity.dto.response.QOrderResponse; -import project.trendpick_pro.domain.product.entity.QProduct; import java.util.List; @@ -33,7 +28,7 @@ public OrderRepositoryImpl(EntityManager em) { //나의 주문목록 @Override - public Page findAllByMember(Long memberId, Pageable pageable) { + public Page findAllByMember(OrderSearchCond orderSearchCond, Pageable pageable) { List result = queryFactory .select(new QOrderResponse( product.id, @@ -48,7 +43,7 @@ public Page findAllByMember(Long memberId, Pageable pageable) { ) .from(order) .join(order.member, member) - .on(member.id.eq(memberId)) + .on(member.id.eq(orderSearchCond.getMemberId())) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) .orderBy(order.createdDate.asc()) @@ -58,7 +53,7 @@ public Page findAllByMember(Long memberId, Pageable pageable) { .select(order.count()) .from(order) .join(order.member, member) - .on(member.id.eq(memberId)) + .on(member.id.eq(orderSearchCond.getMemberId())) ; return PageableExecutionUtils.getPage(result, pageable, countQuery::fetchOne); } diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 228fba2b..a333011d 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -11,6 +11,7 @@ import project.trendpick_pro.domain.delivery.entity.embaded.Address; import project.trendpick_pro.domain.orders.entity.dto.request.OrderForm; import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; +import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.exception.MemberNotFoundException; @@ -68,10 +69,8 @@ public void cancel(Long orderId) { order.cancel(); } - //임시 작성 - public Page findAll(OrderSearchCond cond) { - Member member = memberRepository.findById(cond.getMemberId()).orElseThrow(); - return orderRepository.findAllByMember(member, PageRequest.of(0, 10)); + public Page findAllByMember(Member member, int offset) { + return orderRepository.findAllByMember(new OrderSearchCond(member.getId()), PageRequest.of(offset, 10)); } diff --git a/src/main/resources/templates/trendpick/orders/list.html b/src/main/resources/templates/trendpick/orders/list.html deleted file mode 100644 index e69de29b..00000000 diff --git a/src/main/resources/templates/trendpick/usr/member/orders.html b/src/main/resources/templates/trendpick/usr/member/orders.html index 566549bd..8cba6459 100644 --- a/src/main/resources/templates/trendpick/usr/member/orders.html +++ b/src/main/resources/templates/trendpick/usr/member/orders.html @@ -1,10 +1,44 @@ - + - Title + 주문 목록 +

주문 목록

+ + + + + + + + + + + + + + + + + + + + + + + + +
주문 ID상품 이미지브랜드명상품명사이즈주문일시총 가격주문 상태배송 상태
+ +
+ +
\ No newline at end of file From b0ccf878208979e1b8acdf0f66c22ff213cfe99a Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Tue, 6 Jun 2023 17:38:31 +0900 Subject: [PATCH 171/367] =?UTF-8?q?refactor:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=20=ED=99=95=EC=9D=B8=20=EB=A1=9C=EC=A7=81=20=EC=9C=84=EC=B9=98?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EB=A1=9C=EC=A7=81=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0=20(#122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../project/trendpick_pro/domain/common/base/rq/Rq.java | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java index 1b7a6fac..84684f43 100644 --- a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java +++ b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java @@ -60,11 +60,7 @@ public Optional CheckMember() { Optional member = memberService.findByEmail(username); if (member.isPresent()) { - Member checkMember = member.get(); - if (checkMember.getRole().equals(RoleType.MEMBER)) { - throw new MemberNotMatchException("허용된 권한이 아닙니다."); - } - return Optional.of(checkMember); + return member; } else { throw new MemberNotFoundException("존재하지 않는 회원입니다."); From aeb433a590564251efaa50e27b5d607ca2d61e67 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Tue, 6 Jun 2023 17:43:08 +0900 Subject: [PATCH 172/367] =?UTF-8?q?refactor:=20=EB=A1=9C=EA=B7=B8=EC=9D=B8?= =?UTF-8?q?=20=ED=99=95=EC=9D=B8=20=EB=A1=9C=EC=A7=81=20=EC=9C=84=EC=B9=98?= =?UTF-8?q?=EB=B3=80=EA=B2=BD=20=EB=B0=8F=20=EB=A1=9C=EC=A7=81=20=EA=B0=9C?= =?UTF-8?q?=EC=84=A0=20(#122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/common/base/rq/Rq.java | 21 ++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java index 84684f43..06cce62f 100644 --- a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java +++ b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java @@ -54,7 +54,26 @@ public Member getMember() { return member; } + public Optional CheckAdmin() { + Optional member = CheckLogin(); + Member checkMember = member.get(); + if (checkMember.getRole().equals(RoleType.MEMBER)) { + throw new MemberNotMatchException("허용된 권한이 아닙니다."); + } + return member; + } + public Optional CheckMember() { + Optional member = CheckLogin(); + Member checkMember = member.get(); + if (checkMember.getRole().equals(RoleType.MEMBER)) { + return member; + + } + throw new MemberNotMatchException("허용된 권한이 아닙니다."); + } + + public Optional CheckLogin() { String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 Optional member = memberService.findByEmail(username); @@ -66,4 +85,4 @@ public Optional CheckMember() { throw new MemberNotFoundException("존재하지 않는 회원입니다."); } } -} +} \ No newline at end of file From 81c6f4672d32c6aa9cf2068732d72e95e95ad7ef Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Tue, 6 Jun 2023 18:18:45 +0900 Subject: [PATCH 173/367] =?UTF-8?q?feat:=20=EB=A6=AC=EB=B7=B0=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8/=20=EC=83=81=EC=84=B8=EB=B3=B4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 27 ++++++++---- .../domain/review/service/ReviewService.java | 5 +++ .../templates/trendpick/review/detail.html | 33 +++++++++++++++ .../templates/trendpick/review/list.html | 2 +- .../templates/trendpick/review/modify.html | 41 +++++++++++++++++++ 5 files changed, 100 insertions(+), 8 deletions(-) create mode 100644 src/main/resources/templates/trendpick/review/detail.html create mode 100644 src/main/resources/templates/trendpick/review/modify.html diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index 361f6cdb..fc11a5aa 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -15,12 +15,14 @@ import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; +import project.trendpick_pro.domain.review.entity.Review; import project.trendpick_pro.domain.review.entity.dto.request.ReviewSaveRequest; import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; import project.trendpick_pro.domain.review.service.ReviewService; import java.io.IOException; import java.util.List; +import java.util.Optional; @Controller @RequiredArgsConstructor @@ -53,7 +55,7 @@ public String createReview(@Valid ReviewSaveRequest reviewCreateRequest, public String showReview(@PathVariable Long reviewId, Model model){ ReviewResponse reviewResponse = reviewService.showReview(reviewId); model.addAttribute("reviewResponse", reviewResponse); - return "redirect:/trendpick/review"; + return "/trendpick/review/detail"; } @GetMapping("/delete/{reviewId}") @@ -64,20 +66,31 @@ public String deleteReview(@PathVariable Long reviewId) { return "/trendpick/review/list"; } +// @PostMapping("/edit/{reviewId}") +// public String updateReview(@PathVariable Long reviewId, ReviewSaveRequest reviewSaveRequest, @RequestParam("mainFile") MultipartFile mainFile, +// @RequestParam("subFiles") List subFiles, Model model) throws IOException { +// Long id = reviewService.modify(reviewId, reviewSaveRequest, mainFile, subFiles); +// +// return "redirect:/trendpick/review/list/" + id; +// } + + @GetMapping("/edit/{reviewId}") + public String showUpdateReview(@PathVariable Long reviewId, Model model){ + Review review = reviewService.findById(reviewId); + model.addAttribute("originReview", review); + + return "trendpick/review/modify"; + } + @PostMapping("/edit/{reviewId}") public String updateReview(@PathVariable Long reviewId, ReviewSaveRequest reviewSaveRequest, @RequestParam("mainFile") MultipartFile mainFile, @RequestParam("subFiles") List subFiles, Model model) throws IOException { ReviewResponse reviewResponse = reviewService.modify(reviewId, reviewSaveRequest, mainFile, subFiles); model.addAttribute("reviewResponse", reviewResponse); - return "redirect:/trendpick/review"; + return "redirect:/trendpick/review/list/" + reviewId; } -// @GetMapping("/list") -// public String showAllReview(@RequestParam(value = "page", defaultValue = "0")int offset, Model model){ -// model.addAttribute("reviewListResponse", reviewService.showAll(offset)); -// return "/trendpick/review/list"; -// } @GetMapping("/list") public String showAllReview(Pageable pageable, Model model){ diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index 65cdeac6..8c4659d9 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -22,6 +22,7 @@ import java.io.File; import java.io.IOException; import java.util.List; +import java.util.Optional; @Service @@ -42,6 +43,10 @@ public ReviewResponse showReview(Long productId) { return ReviewResponse.of(review); } + public Review findById(Long id) { + return reviewRepository.findById(id).orElseThrow(); + } + @Transactional public void delete(Long reviewId) { diff --git a/src/main/resources/templates/trendpick/review/detail.html b/src/main/resources/templates/trendpick/review/detail.html new file mode 100644 index 00000000..1f7371cc --- /dev/null +++ b/src/main/resources/templates/trendpick/review/detail.html @@ -0,0 +1,33 @@ + + + + + + 리뷰 상세 페이지 + + + + +
+

제품명

+

작성자

+ +
+
+ 메인 이미지 +
+ 서브 이미지 +
+
+ +
+

제목

+

제목

+ +

내용

+

후기내용

+
+
+
+ + diff --git a/src/main/resources/templates/trendpick/review/list.html b/src/main/resources/templates/trendpick/review/list.html index 2a805d0e..8b0ff55f 100644 --- a/src/main/resources/templates/trendpick/review/list.html +++ b/src/main/resources/templates/trendpick/review/list.html @@ -12,7 +12,7 @@

작성자:

상품명:

-

메인 파일:

+

메인 파일: 메인 이미지

내용:

평점:

diff --git a/src/main/resources/templates/trendpick/review/modify.html b/src/main/resources/templates/trendpick/review/modify.html new file mode 100644 index 00000000..00b2aa38 --- /dev/null +++ b/src/main/resources/templates/trendpick/review/modify.html @@ -0,0 +1,41 @@ + + + + + + + 리뷰 등록 + + + +
+
+ + +
+ +
+ + +
+
+ +
+ + +
+ +
+ + +
+ +
+ + +
+ + +
+ + \ No newline at end of file From 9b4d0e93aa1ed4b00a883d3bd0fcaa0360616cf6 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Tue, 6 Jun 2023 18:32:52 +0900 Subject: [PATCH 174/367] =?UTF-8?q?feat:=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=EC=A0=9C=EC=99=B8=20=ED=99=94=EB=A9=B4=20=EC=B6=9C=EB=A0=A5=20?= =?UTF-8?q?=ED=99=95=EC=9D=B8(#112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orders/contoller/OrderController.java | 24 +++++- .../domain/orders/entity/OrderStatus.java | 9 ++- .../repository/OrderRepositoryImpl.java | 4 +- .../trendpick/usr/member/orders.html | 74 ++++++++++++------- 4 files changed, 77 insertions(+), 34 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index ba474dac..49f6e298 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -13,6 +13,7 @@ import project.trendpick_pro.domain.member.entity.dto.MemberInfoDto; import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.service.MemberService; +import project.trendpick_pro.domain.orders.entity.OrderStatus; import project.trendpick_pro.domain.orders.entity.dto.request.OrderForm; import project.trendpick_pro.domain.orders.entity.dto.request.OrderSearchCond; import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; @@ -20,8 +21,10 @@ import project.trendpick_pro.domain.orders.service.OrderService; import project.trendpick_pro.domain.product.repository.ProductRepository; +import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Optional; @Slf4j @@ -83,11 +86,26 @@ public synchronized String order(@ModelAttribute("orderForm") OrderForm orderFor @PreAuthorize("isAuthenticated()") @GetMapping("/list") - public String orderListByMember(@RequestParam(value = "page", defaultValue = "0") int offset, + public String orderListByMember( +// @RequestParam(value = "page", defaultValue = "0") int offset, Model model) { - Member member = memberService.findByEmail(SecurityContextHolder.getContext().getAuthentication().getName()); - Page orderList = orderService.findAllByMember(member, offset); +// String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 +// Optional member = memberService.findByEmail(username); +// +// Page orderList = orderService.findAllByMember(member.get(), offset); + List orderList = new ArrayList<>(); + orderList.add(OrderResponse.builder() + .orderId(1L) + .brandName("나이키") + .productName("나이키모자") + .size("M") + .orderDate(LocalDateTime.now()) + .totalPrice(5000) + .orderStatus("주문중") + .deliveryStatus("배송중") + .build()); + model.addAttribute("orderList", orderList); return "trendpick/usr/member/orders"; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderStatus.java b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderStatus.java index 7b103d4f..7ac1ccde 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderStatus.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderStatus.java @@ -1,5 +1,12 @@ package project.trendpick_pro.domain.orders.entity; public enum OrderStatus { - ORDERED, CANCELLED; + ORDERED("ORDERED"), + CANCELLED("CANCELLED"); + + private String value; + + OrderStatus(String value) { + this.value = value; + } } diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java index 4af044c2..b877c046 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java @@ -38,8 +38,8 @@ public Page findAllByMember(OrderSearchCond orderSearchCond, Page orderItem.size, order.createdDate, order.totalPrice, - order.status, - delivery.state) + order.status.stringValue(), + delivery.state.stringValue()) ) .from(order) .join(order.member, member) diff --git a/src/main/resources/templates/trendpick/usr/member/orders.html b/src/main/resources/templates/trendpick/usr/member/orders.html index 8cba6459..36e199bb 100644 --- a/src/main/resources/templates/trendpick/usr/member/orders.html +++ b/src/main/resources/templates/trendpick/usr/member/orders.html @@ -3,42 +3,60 @@ 주문 목록 +

주문 목록

- +
+ - - - - - - - - - + + + + + + + + + - - - - - - - - - - - + + + + + + + + + + + + +
주문 ID상품 이미지브랜드명상품명사이즈주문일시총 가격주문 상태배송 상태주문번호브랜드명메인사진상품명사이즈주문일시주문금액주문상태배송상태
상품 이미지
-
- -
+ + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From e41f194259cee503fc3caebe15b124073a42fc08 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Tue, 6 Jun 2023 18:34:19 +0900 Subject: [PATCH 175/367] =?UTF-8?q?refactor:=20redirect=20=EB=A7=81?= =?UTF-8?q?=ED=81=AC=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 19 +++++-------------- .../domain/review/service/ReviewService.java | 1 + .../templates/trendpick/review/register.html | 2 +- 3 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index fc11a5aa..2d01860d 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -30,14 +30,14 @@ public class ReviewController { private final ReviewService reviewService; private final MemberRepository memberRepository; - private final Rq rq; + @GetMapping("/register") public String registerReview() { return "/trendpick/review/register"; } - @PostMapping("/write") + @PostMapping("/register") public String createReview(@Valid ReviewSaveRequest reviewCreateRequest, @RequestParam("mainFile") MultipartFile mainFile, @RequestParam("subFiles") List subFiles, Model model) throws Exception { @@ -47,11 +47,11 @@ public String createReview(@Valid ReviewSaveRequest reviewCreateRequest, ReviewResponse reviewResponse = reviewService.createReview(member, 1L, reviewCreateRequest, mainFile, subFiles); model.addAttribute("reviewResponse", reviewResponse); - return "/trendpick/review/list"; + return "redirect:/trendpick/review/list"; } - @GetMapping("/list/{reviewId}") + @GetMapping("/{reviewId}") public String showReview(@PathVariable Long reviewId, Model model){ ReviewResponse reviewResponse = reviewService.showReview(reviewId); model.addAttribute("reviewResponse", reviewResponse); @@ -62,18 +62,9 @@ public String showReview(@PathVariable Long reviewId, Model model){ public String deleteReview(@PathVariable Long reviewId) { reviewService.delete(reviewId); - //return "redirect:/trendpick/review/list"; - return "/trendpick/review/list"; + return "redirect:/trendpick/review/list"; } -// @PostMapping("/edit/{reviewId}") -// public String updateReview(@PathVariable Long reviewId, ReviewSaveRequest reviewSaveRequest, @RequestParam("mainFile") MultipartFile mainFile, -// @RequestParam("subFiles") List subFiles, Model model) throws IOException { -// Long id = reviewService.modify(reviewId, reviewSaveRequest, mainFile, subFiles); -// -// return "redirect:/trendpick/review/list/" + id; -// } - @GetMapping("/edit/{reviewId}") public String showUpdateReview(@PathVariable Long reviewId, Model model){ Review review = reviewService.findById(reviewId); diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index 8c4659d9..e1381937 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -71,6 +71,7 @@ public ReviewResponse createReview(Member actor, Long productId, ReviewSaveReque return ReviewResponse.of(review); } + @Transactional public ReviewResponse modify(Long reviewId, ReviewSaveRequest reviewSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { Review review = reviewRepository.findById(reviewId).orElseThrow(); diff --git a/src/main/resources/templates/trendpick/review/register.html b/src/main/resources/templates/trendpick/review/register.html index 76780245..3965ad91 100644 --- a/src/main/resources/templates/trendpick/review/register.html +++ b/src/main/resources/templates/trendpick/review/register.html @@ -8,7 +8,7 @@ -
+
From b12a3011718ca8b297f77d417f65720222bcb111 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Tue, 6 Jun 2023 18:46:40 +0900 Subject: [PATCH 176/367] =?UTF-8?q?refactor:=20redirect=20=EB=A7=81?= =?UTF-8?q?=ED=81=AC=20=EB=B3=80=EA=B2=BD,=20rq=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/review/controller/ReviewController.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index 2d01860d..b488709b 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -30,7 +30,7 @@ public class ReviewController { private final ReviewService reviewService; private final MemberRepository memberRepository; - + private final Rq rq; @GetMapping("/register") public String registerReview() { @@ -41,9 +41,8 @@ public String registerReview() { public String createReview(@Valid ReviewSaveRequest reviewCreateRequest, @RequestParam("mainFile") MultipartFile mainFile, @RequestParam("subFiles") List subFiles, Model model) throws Exception { - String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 - Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); - //어떤 상품인지 받아와야 함 + Member member = rq.getMember(); + ReviewResponse reviewResponse = reviewService.createReview(member, 1L, reviewCreateRequest, mainFile, subFiles); model.addAttribute("reviewResponse", reviewResponse); @@ -79,7 +78,7 @@ public String updateReview(@PathVariable Long reviewId, ReviewSaveRequest review ReviewResponse reviewResponse = reviewService.modify(reviewId, reviewSaveRequest, mainFile, subFiles); model.addAttribute("reviewResponse", reviewResponse); - return "redirect:/trendpick/review/list/" + reviewId; + return "redirect:/trendpick/review/" + reviewId; } From 2665c586bcffee31de7a771136087fddc88d7f1c Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Tue, 6 Jun 2023 20:08:39 +0900 Subject: [PATCH 177/367] =?UTF-8?q?refactor:=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D(=EB=AF=B8=EC=99=84=EC=84=B1)=20(#122)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 14 +++++++------- .../domain/product/service/ProductService.java | 8 ++++---- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 3cfd468e..aa57f14f 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -13,6 +13,7 @@ import project.trendpick_pro.domain.category.service.SubCategoryService; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.product.entity.dto.request.ProductSaveRequest; import project.trendpick_pro.domain.product.entity.dto.response.ProductResponse; import project.trendpick_pro.domain.product.service.ProductService; @@ -76,24 +77,23 @@ public String deleteProduct(@PathVariable Long productId) { return "redirect:/trendpick/products/list"; } - @PreAuthorize("isAnonymous()") + @PreAuthorize("permitAll()") @GetMapping("/{productId}") public String showProduct(@PathVariable Long productId, Model model) { model.addAttribute("productResponse", productService.show(productId)); return "/trendpick/products/detailpage"; } - @PreAuthorize("isAnonymous()") + @PreAuthorize("permitAll()") @GetMapping("/list") public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") int offset, - @RequestParam(value = "main-category", defaultValue = "추천") String mainCategory, + @RequestParam(value = "main-category") String mainCategory, @RequestParam(value = "sub-category", defaultValue = "전체") String subCategory, @RequestParam(value = "sort", defaultValue = "1") Integer sortCode, Model model) { - Optional member = rq.CheckMember(); - - if (member.isPresent()) { - if (mainCategory.equals("추천")) { + if (mainCategory.equals("추천")) { + Member member = rq.CheckLogin().orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); + if (member.getRole().getValue().equals("MEMBER")) { model.addAttribute("productResponses", recommendService.getFindAll(offset)); } else { model.addAttribute("productResponses", productService.showAll(offset, mainCategory, subCategory, sortCode)); diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 083fed93..76b0120e 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -67,7 +67,7 @@ public class ProductService { @Transactional public Long register(ProductSaveRequest productSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { - rq.CheckMember(); + rq.CheckAdmin(); CommonFile mainFile = fileTranslator.translateFile(requestMainFile); List subFiles = fileTranslator.translateFileList(requestSubFiles); @@ -95,7 +95,7 @@ public Long register(ProductSaveRequest productSaveRequest, MultipartFile reques @Transactional public Long modify(Long productId, ProductSaveRequest productSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { - rq.CheckMember(); + rq.CheckAdmin(); Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 CommonFile mainFile = product.getFile(); @@ -125,7 +125,7 @@ public Long modify(Long productId, ProductSaveRequest productSaveRequest, Multip @Transactional public void delete(Long productId) { - rq.CheckMember(); + rq.CheckAdmin(); Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 productRepository.delete(product); } @@ -133,7 +133,7 @@ public void delete(Long productId) { public ProductResponse show(Long productId) { Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 - Optional member = rq.CheckMember(); + Optional member = rq.CheckLogin(); if (member.isPresent()){ Member checkMember = member.get(); From 4e9d3ca777a7c27c4bbcd9ee9558dca9d35a4acb Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 7 Jun 2023 00:34:19 +0900 Subject: [PATCH 178/367] =?UTF-8?q?feat:=20baseData=EC=97=90=20=EC=83=81?= =?UTF-8?q?=ED=92=88=20=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=B6=94=EA=B0=80=20?= =?UTF-8?q?(#112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orders/contoller/OrderController.java | 26 +++++++----- .../domain/orders/entity/OrderItem.java | 5 ++- .../entity/dto/response/OrderItemDto.java | 4 +- .../global/basedata/BaseData.java | 42 ++++++++++++++++++- .../tagname/service/TagNameService.java | 4 ++ .../templates/trendpick/orders/order.html | 5 ++- 6 files changed, 71 insertions(+), 15 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 49f6e298..69efcf19 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -19,6 +19,7 @@ import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; import project.trendpick_pro.domain.orders.service.OrderService; +import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; import java.time.LocalDateTime; @@ -40,12 +41,17 @@ public class OrderController { @GetMapping("/order") public String orderForm(@ModelAttribute OrderForm orderForm, Model model){ -// MemberInfoDto memberInfo = new MemberInfoDto(2L, "admin", "admin@naver.com", "000", "서울"); -// List orderItems = new ArrayList<>(); -// orderItems.add(new OrderItemDto(1L, "상품1", 5, 500)); -// orderItems.add(new OrderItemDto(2L, "상품2", 1, 100)); -// orderItems.add(new OrderItemDto(3L, "상품3", 2, 200)); -// orderForm = new OrderForm(memberInfo, orderItems); + Member member = rq.CheckMember().get(); + MemberInfoDto memberInfo = new MemberInfoDto(member.getId(), member.getUsername(), member.getEmail(), member.getPhoneNumber(), member.getAddress()); + List orderItems = new ArrayList<>(); + Product product1 = productRepository.findById(1L).get(); + Product product2 = productRepository.findById(2L).get(); + Product product3 = productRepository.findById(3L).get(); + + orderItems.add(new OrderItemDto(product1.getId(), product1.getName(),"M", 5, product1.getPrice())); + orderItems.add(new OrderItemDto(product2.getId(), product2.getName(),"L", 1, product2.getPrice())); + orderItems.add(new OrderItemDto(product3.getId(), product3.getName(), "L", 7, product3.getPrice())); + orderForm = new OrderForm(memberInfo, orderItems); //상품 상세 또는 장바구니에서 OrderForm으로 데이터가 날라오게끔 model.addAttribute("orderForm", orderForm); @@ -68,10 +74,9 @@ public synchronized String order(@ModelAttribute("orderForm") OrderForm orderFor // } // System.out.println("결제 수단: " + orderForm.getPaymentMethod()); - Member member = memberService.findByEmail(SecurityContextHolder.getContext().getAuthentication().getName()) - .orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); -// if(member.getId() != orderForm.getMemberInfo().getMemberId()) -// throw new RuntimeException("잘못된 접근입니다."); + Member member = rq.CheckMember().get(); + if(member.getId()!=orderForm.getMemberInfo().getMemberId()) + throw new RuntimeException("잘못된 접근입니다."); log.info(member.getUsername()); log.info(String.valueOf(member.getId())); @@ -79,6 +84,7 @@ public synchronized String order(@ModelAttribute("orderForm") OrderForm orderFor log.info(orderForm.getOrderItems().get(0).getProductName()); log.info(String.valueOf(orderForm.getOrderItems().get(0).getProductId())); + //실제 상품이 없어서 오류 orderService.order(member, orderForm); return "주문성공"; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java index daee734d..f44ef683 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java @@ -35,16 +35,17 @@ public class OrderItem { private String size; - private OrderItem(Product product, int orderPrice, int count) { + private OrderItem(Product product,String size, int orderPrice, int count) { this.product = product; this.orderPrice = orderPrice; this.count = count; + this.size = size; product.removeStock(count); } public static OrderItem of(Product product, OrderItemDto orderItemDto) { - return new OrderItem(product, orderItemDto.getPrice(), orderItemDto.getCount()); + return new OrderItem(product, orderItemDto.getSize(), orderItemDto.getPrice(), orderItemDto.getCount()); } public void connectOrder(Order order) { diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java index a0645377..db489c8a 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java @@ -8,14 +8,16 @@ public class OrderItemDto { private Long productId; private String productName; + private String size; private int count; private int price; - public OrderItemDto(Long productId, String productName, int count, int price) { + public OrderItemDto(Long productId, String productName, String size, int count, int price) { this.productName = productName; this.count = count; this.price = price; this.productId = productId; + this.size = size; } public OrderItemDto() { diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index c9c56299..46752357 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -11,6 +11,7 @@ import project.trendpick_pro.domain.category.entity.MainCategory; import project.trendpick_pro.domain.category.service.MainCategoryService; import project.trendpick_pro.domain.category.service.SubCategoryService; +import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.RoleType; import project.trendpick_pro.domain.member.entity.form.JoinForm; @@ -22,10 +23,12 @@ import project.trendpick_pro.domain.tags.favoritetag.entity.FavoriteTag; import project.trendpick_pro.domain.tags.tag.entity.Tag; import project.trendpick_pro.domain.tags.tag.entity.type.TagType; +import project.trendpick_pro.global.basedata.tagname.entity.TagName; import project.trendpick_pro.global.basedata.tagname.service.TagNameService; import java.io.File; import java.io.FileInputStream; +import java.util.ArrayList; import java.util.LinkedHashSet; import java.util.List; import java.util.Set; @@ -67,7 +70,8 @@ CommandLineRunner initData( MemberService memberService, MainCategoryService mainCategoryService, SubCategoryService subCategoryService, - BrandService brandService + BrandService brandService, + ProductRepository productRepository ) { return new CommandLineRunner() { @Override @@ -117,6 +121,42 @@ public void run(String... args) { memberService.register(brand_admin); memberService.register(member); + for(int n=1; n<=10; n++) { + CommonFile mainFile = CommonFile.builder() + .fileName("355d1034-90ac-420b-ae02-6656eeebd707.jpg") + .build(); + List subFiles = new ArrayList<>(); + subFiles.add(CommonFile.builder() + .fileName("290ffec9-2da6-46dd-8779-86c27d48ef0c.jpg") + .build()); + + for (CommonFile subFile : subFiles) { + mainFile.connectFile(subFile); + } + + Product product = Product + .builder() + .name("멋쟁이 티셔츠"+n) + .description("이 상품은 멋쟁이 티셔츠입니다."+n) + .stock(50) + .price(20000) + .mainCategory(mainCategoryService.findByName("상의")) + .subCategory(subCategoryService.findByName("반소매티셔츠")) + .brand(brandService.findByName("나이키")) + .file(mainFile) + .build(); + + Set tags = new LinkedHashSet<>(); // 상품에 포함시킬 태크 선택하여 저장 + for (int i = 1; i <= 5; i++) { + TagName tagName = tagNameService.findById(Long.valueOf(i+n)); + tags.add(new Tag(tagName.getName())); + } + + product.addTag(tags); + productRepository.save(product); + } + + // member1은 시티보이룩(10점), 빈티지룩(5점), 로멘틱룩(1점)을 선호 태그로 가지고 있다. // 상품1은 시티보이룩을 가지고 있다 // 상품2는 시티보이룩, 빈티지룩을 가지고 있다 diff --git a/src/main/java/project/trendpick_pro/global/basedata/tagname/service/TagNameService.java b/src/main/java/project/trendpick_pro/global/basedata/tagname/service/TagNameService.java index 6609e4f9..dcbb40c3 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/tagname/service/TagNameService.java +++ b/src/main/java/project/trendpick_pro/global/basedata/tagname/service/TagNameService.java @@ -26,4 +26,8 @@ public List findAll() { List tags = tagNameRepository.findAllBy(); return tags.stream().map(tagName -> new TagNameResponse(tagName.getName())).toList(); } + + public TagName findById(Long id) { + return tagNameRepository.findById(id).get(); + } } diff --git a/src/main/resources/templates/trendpick/orders/order.html b/src/main/resources/templates/trendpick/orders/order.html index f4692909..480c03e0 100644 --- a/src/main/resources/templates/trendpick/orders/order.html +++ b/src/main/resources/templates/trendpick/orders/order.html @@ -11,7 +11,7 @@

주문서

회원 정보

-

+

회원 이름:

이메일:

번호:

@@ -20,13 +20,16 @@

회원 정보

주문 아이템 목록

+ + + From 04486ac68089bea688adee5122af20378e126283 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 7 Jun 2023 10:17:25 +0900 Subject: [PATCH 179/367] =?UTF-8?q?feat:=20BaseData=EC=97=90=20=EC=A3=BC?= =?UTF-8?q?=EB=AC=B8=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=A0=80=EC=9E=A5=20(#1?= =?UTF-8?q?12)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/entity/dto/MemberInfoDto.java | 20 +++-- .../orders/contoller/OrderController.java | 61 +++----------- .../entity/dto/response/OrderItemDto.java | 9 ++- .../repository/OrderRepositoryImpl.java | 21 ++--- .../global/basedata/BaseData.java | 79 +++++-------------- 5 files changed, 58 insertions(+), 132 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java b/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java index 97dbb7cc..5375faf6 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java @@ -1,25 +1,23 @@ package project.trendpick_pro.domain.member.entity.dto; import lombok.Getter; -import lombok.Setter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.member.entity.Member; @Getter -@Setter +@NoArgsConstructor public class MemberInfoDto { private Long memberId; private String name; private String email; - public MemberInfoDto() { - } - - public MemberInfoDto(Long memberId, String name, String email, String phone, String address) { - this.name = name; - this.email = email; - this.phone = phone; - this.address = address; - this.memberId = memberId; + public MemberInfoDto(Member member) { + this.memberId = member.getId(); + this.name = member.getUsername(); + this.email = member.getEmail(); + this.phone = member.getPhoneNumber(); + this.address = member.getAddress(); } private String phone; diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 69efcf19..342c0706 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -41,17 +41,17 @@ public class OrderController { @GetMapping("/order") public String orderForm(@ModelAttribute OrderForm orderForm, Model model){ - Member member = rq.CheckMember().get(); - MemberInfoDto memberInfo = new MemberInfoDto(member.getId(), member.getUsername(), member.getEmail(), member.getPhoneNumber(), member.getAddress()); - List orderItems = new ArrayList<>(); - Product product1 = productRepository.findById(1L).get(); - Product product2 = productRepository.findById(2L).get(); - Product product3 = productRepository.findById(3L).get(); - - orderItems.add(new OrderItemDto(product1.getId(), product1.getName(),"M", 5, product1.getPrice())); - orderItems.add(new OrderItemDto(product2.getId(), product2.getName(),"L", 1, product2.getPrice())); - orderItems.add(new OrderItemDto(product3.getId(), product3.getName(), "L", 7, product3.getPrice())); - orderForm = new OrderForm(memberInfo, orderItems); +// Member member = rq.CheckMember().get(); +// MemberInfoDto memberInfo = new MemberInfoDto(member.getId(), member.getUsername(), member.getEmail(), member.getPhoneNumber(), member.getAddress()); +// List orderItems = new ArrayList<>(); +// Product product1 = productRepository.findById(1L).get(); +// Product product2 = productRepository.findById(2L).get(); +// Product product3 = productRepository.findById(3L).get(); +// +// orderItems.add(new OrderItemDto(product1.getId(), product1.getName(),"M", 5, product1.getPrice())); +// orderItems.add(new OrderItemDto(product2.getId(), product2.getName(),"L", 1, product2.getPrice())); +// orderItems.add(new OrderItemDto(product3.getId(), product3.getName(), "L", 7, product3.getPrice())); +// orderForm = new OrderForm(memberInfo, orderItems); //상품 상세 또는 장바구니에서 OrderForm으로 데이터가 날라오게끔 model.addAttribute("orderForm", orderForm); @@ -62,31 +62,12 @@ public String orderForm(@ModelAttribute OrderForm orderForm, Model model){ @PostMapping("/order") @ResponseBody public synchronized String order(@ModelAttribute("orderForm") OrderForm orderForm) { - - -// System.out.println("회원 이름: " + orderForm.getMemberInfo().getName()); -// System.out.println("이메일: " + orderForm.getMemberInfo().getEmail()); -// System.out.println("주문 아이템 목록:"); -// for (OrderItemDto orderItem : orderForm.getOrderItems()) { -// System.out.println("상품명: " + orderItem.getProductName()); -// System.out.println("수량: " + orderItem.getCount()); -// System.out.println("가격: " + orderItem.getPrice()); -// } -// System.out.println("결제 수단: " + orderForm.getPaymentMethod()); - Member member = rq.CheckMember().get(); if(member.getId()!=orderForm.getMemberInfo().getMemberId()) throw new RuntimeException("잘못된 접근입니다."); - log.info(member.getUsername()); - log.info(String.valueOf(member.getId())); - log.info(orderForm.getMemberInfo().getName()); - log.info(orderForm.getOrderItems().get(0).getProductName()); - log.info(String.valueOf(orderForm.getOrderItems().get(0).getProductId())); - - //실제 상품이 없어서 오류 orderService.order(member, orderForm); - return "주문성공"; + return "redirect:/trendpick/orders/list"; } @@ -96,23 +77,7 @@ public String orderListByMember( // @RequestParam(value = "page", defaultValue = "0") int offset, Model model) { -// String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 -// Optional member = memberService.findByEmail(username); -// -// Page orderList = orderService.findAllByMember(member.get(), offset); - List orderList = new ArrayList<>(); - orderList.add(OrderResponse.builder() - .orderId(1L) - .brandName("나이키") - .productName("나이키모자") - .size("M") - .orderDate(LocalDateTime.now()) - .totalPrice(5000) - .orderStatus("주문중") - .deliveryStatus("배송중") - .build()); - - model.addAttribute("orderList", orderList); + model.addAttribute("orderList", orderService.findAllByMember(rq.CheckMember().get(), 0)); return "trendpick/usr/member/orders"; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java index db489c8a..83b5e796 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java @@ -2,6 +2,7 @@ import lombok.Getter; import lombok.Setter; +import project.trendpick_pro.domain.product.entity.Product; @Getter @Setter @@ -12,11 +13,11 @@ public class OrderItemDto { private int count; private int price; - public OrderItemDto(Long productId, String productName, String size, int count, int price) { - this.productName = productName; + public OrderItemDto(Product product, String size, int count) { + this.productId = product.getId(); + this.productName = product.getName(); + this.price = product.getPrice(); this.count = count; - this.price = price; - this.productId = productId; this.size = size; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java index b877c046..d86f6be6 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java @@ -31,22 +31,23 @@ public OrderRepositoryImpl(EntityManager em) { public Page findAllByMember(OrderSearchCond orderSearchCond, Pageable pageable) { List result = queryFactory .select(new QOrderResponse( - product.id, - product.file.fileName, - product.brand.name, - product.name, + orderItem.product.id, + orderItem.product.file.fileName, + orderItem.product.brand.name, + orderItem.product.name, orderItem.size, - order.createdDate, - order.totalPrice, - order.status.stringValue(), - delivery.state.stringValue()) + orderItem.order.createdDate, + orderItem.orderPrice, + orderItem.order.status.stringValue(), + orderItem.order.delivery.state.stringValue()) ) - .from(order) + .from(orderItem) + .join(orderItem.order, order) .join(order.member, member) .on(member.id.eq(orderSearchCond.getMemberId())) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) - .orderBy(order.createdDate.asc()) + .orderBy(orderItem.order.createdDate.asc()) .fetch(); JPAQuery countQuery = queryFactory diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index 46752357..b01c14ea 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -14,9 +14,13 @@ import project.trendpick_pro.domain.common.file.CommonFile; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.RoleType; +import project.trendpick_pro.domain.member.entity.dto.MemberInfoDto; import project.trendpick_pro.domain.member.entity.form.JoinForm; import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.member.service.MemberService; +import project.trendpick_pro.domain.orders.entity.dto.request.OrderForm; +import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; +import project.trendpick_pro.domain.orders.service.OrderService; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.product.service.ProductService; @@ -71,7 +75,8 @@ CommandLineRunner initData( MainCategoryService mainCategoryService, SubCategoryService subCategoryService, BrandService brandService, - ProductRepository productRepository + ProductRepository productRepository, + OrderService orderservice ) { return new CommandLineRunner() { @Override @@ -121,6 +126,7 @@ public void run(String... args) { memberService.register(brand_admin); memberService.register(member); + //==상품데이터==// for(int n=1; n<=10; n++) { CommonFile mainFile = CommonFile.builder() .fileName("355d1034-90ac-420b-ae02-6656eeebd707.jpg") @@ -138,79 +144,34 @@ public void run(String... args) { .builder() .name("멋쟁이 티셔츠"+n) .description("이 상품은 멋쟁이 티셔츠입니다."+n) - .stock(50) - .price(20000) + .stock(50+n) + .price(20000+n) .mainCategory(mainCategoryService.findByName("상의")) .subCategory(subCategoryService.findByName("반소매티셔츠")) .brand(brandService.findByName("나이키")) .file(mainFile) .build(); - Set tags = new LinkedHashSet<>(); // 상품에 포함시킬 태크 선택하여 저장 for (int i = 1; i <= 5; i++) { TagName tagName = tagNameService.findById(Long.valueOf(i+n)); tags.add(new Tag(tagName.getName())); } - product.addTag(tags); productRepository.save(product); } + //==주문데이터==// + Member findMember = memberService.findByEmail("trendpick@naver.com").get(); + MemberInfoDto memberInfo = new MemberInfoDto(findMember); + List orderItems = new ArrayList<>(); + + orderItems.add(new OrderItemDto(productRepository.findById(1L).get(), "M", 5)); + orderItems.add(new OrderItemDto(productRepository.findById(2L).get(), "L", 3)); + orderItems.add(new OrderItemDto(productRepository.findById(3L).get(), "S", 2)); -// member1은 시티보이룩(10점), 빈티지룩(5점), 로멘틱룩(1점)을 선호 태그로 가지고 있다. -// 상품1은 시티보이룩을 가지고 있다 -// 상품2는 시티보이룩, 빈티지룩을 가지고 있다 -// 상품3은 시티보이룩, 빈티지룩, 로멘틱룩을 모두 가지고 있다. -// -// Member member1 = memberRepository.save(Member.builder().username("member1").email("jjj@naver.com").phoneNumber("01099999999").role(RoleType.MEMBER).password("111111").build()); -// FavoriteTag favorTag1 = new FavoriteTag("시티보이룩"); -// favorTag1.increaseScore(TagType.SHOW);//상품클릭해서 1점 누적. -// member1.addTag(favorTag1); -// -// FavoriteTag favorTag2 = new FavoriteTag("빈티지룩"); -// favorTag2.increaseScore(TagType.CART);//장바구니 담아서 5점 누적. -// member1.addTag(favorTag2); -// -// FavoriteTag favorTag3 = new FavoriteTag("로멘틱룩"); -// favorTag3.increaseScore(TagType.ORDER);//상품 주문해서 10점 누적. -// member1.addTag(favorTag3); -// -//// 상품1은 시티보이룩을 가지고 있다 -// Set tags1 = new LinkedHashSet<>(); -// Product product1 = Product.builder().name("상품1").tags(tags1).description("설명1").price(500).stock(100).build(); -// product1.addTag(new Tag("시티보이룩")); -// -//// 상품2는 시티보이룩, 빈티지룩을 가지고 있다 -// Set tags2 = new LinkedHashSet<>(); -// Product product2 = Product.builder().name("상품2").tags(tags2).description("설명2").price(500).stock(100).build(); -// product2.addTag(new Tag("시티보이룩")); -// product2.addTag(new Tag("빈티지룩")); -// -// Set tags3 = new LinkedHashSet<>(); -// Product product3 = Product.builder().name("상품3").tags(tags3).description("설명3").price(500).stock(100).build(); -// product3.addTag(new Tag("시티보이룩")); -// product3.addTag(new Tag("빈티지룩")); -// product3.addTag(new Tag("로멘틱룩")); -// productService.save(product1); -// productService.save(product2); -// productService.save(product3); -// -// Set tags4 = new LinkedHashSet<>(); -// Product product4 = Product.builder().name("상품4").tags(tags4).description("설명4").price(500).stock(100).build(); -// product4.addTag(new Tag("원숭이룩")); -// productService.save(product1); -// productService.save(product2); -// productService.save(product3); -// productService.save(product4); - //member1의 추천상품을 가져오면 로멘틱룩, 빈티지룩, 시티보이룩 순서대로 가져와야 한다. - //상품 4는 member의 선호태그를 가지고 있지 않으므로 추천되지 않아야 한다. - -// 상품3은 시티보이룩, 빈티지룩, 로멘틱룩을 모두 가지고 있다. -// Set tags3 = new LinkedHashSet<>(); -// tags3.add(new Tag("시티보이룩")); -// tags3.add(new Tag("빈티지룩")); -// tags3.add(new Tag("로멘틱룩")); -// Product product3 = Product.builder().name("상품3").tags(tags3).description("설명3").price(500).stock(100).build(); + OrderForm orderForm = new OrderForm(memberInfo, orderItems); + orderForm.setPaymentMethod("신용카드"); + orderservice.order(findMember, orderForm); } }; } From 1c3d158d58b173e768bdad2ac92a0a56995fea8a Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 7 Jun 2023 10:19:23 +0900 Subject: [PATCH 180/367] =?UTF-8?q?feat:=20=EC=9D=B4=EB=AF=B8=EC=A7=80?= =?UTF-8?q?=EC=97=85=EB=A1=9C=EB=93=9C=20=EC=BB=A8=ED=8A=B8=EB=A1=A4?= =?UTF-8?q?=EB=9F=AC=20=EA=B5=AC=ED=98=84=20(#112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../common/controller/CommonController.java | 26 +++++++++++ .../trendpick/usr/member/orders.html | 46 +++++++++---------- 2 files changed, 49 insertions(+), 23 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/common/controller/CommonController.java diff --git a/src/main/java/project/trendpick_pro/domain/common/controller/CommonController.java b/src/main/java/project/trendpick_pro/domain/common/controller/CommonController.java new file mode 100644 index 00000000..addf6bbd --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/common/controller/CommonController.java @@ -0,0 +1,26 @@ +package project.trendpick_pro.domain.common.controller; + +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.core.io.Resource; +import org.springframework.core.io.UrlResource; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.ResponseBody; +import project.trendpick_pro.domain.common.base.filetranslator.FileTranslator; + +import java.net.MalformedURLException; + +@Slf4j +@Controller +@RequiredArgsConstructor +public class CommonController { + private final FileTranslator fileTranslator; + + @ResponseBody + @GetMapping("/images/{filename}") + public Resource downloadImage(@PathVariable String filename) throws MalformedURLException { + return new UrlResource("file:" + fileTranslator.getFilePath(filename)); + } +} diff --git a/src/main/resources/templates/trendpick/usr/member/orders.html b/src/main/resources/templates/trendpick/usr/member/orders.html index 36e199bb..727e8444 100644 --- a/src/main/resources/templates/trendpick/usr/member/orders.html +++ b/src/main/resources/templates/trendpick/usr/member/orders.html @@ -13,7 +13,7 @@

주문 목록

- + @@ -23,10 +23,10 @@

주문 목록

- - + + - + @@ -37,25 +37,25 @@

주문 목록

비고 상품명사이즈 수량 가격
주문번호 브랜드명메인사진상품이미지 상품명 사이즈 주문일시
상품 이미지
- - - - - - - - - - - - - - - - - - - +
+ +
From 3535cf05b60a62108d813626eed87688ccce56b5 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 7 Jun 2023 11:05:00 +0900 Subject: [PATCH 181/367] =?UTF-8?q?refactor:=20=EC=A3=BC=EB=AC=B8=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=EC=97=90=20=ED=91=9C=EC=8B=9C=EB=90=98=EB=8A=94=20?= =?UTF-8?q?=EC=83=81=ED=92=88=EA=B8=88=EC=95=A1=20->=20=EC=88=98=EB=9F=89?= =?UTF-8?q?=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EC=B4=9D=EA=B8=88=EC=95=A1?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD=20(#112)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/orders/contoller/OrderController.java | 4 ++-- .../domain/orders/entity/OrderItem.java | 1 - .../orders/entity/dto/response/OrderResponse.java | 12 +++++++++--- .../orders/repository/OrderRepositoryImpl.java | 3 ++- .../templates/trendpick/usr/member/orders.html | 6 ++++-- 5 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 342c0706..55420cfd 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -74,10 +74,10 @@ public synchronized String order(@ModelAttribute("orderForm") OrderForm orderFor @PreAuthorize("isAuthenticated()") @GetMapping("/list") public String orderListByMember( -// @RequestParam(value = "page", defaultValue = "0") int offset, + @RequestParam(value = "page", defaultValue = "0") int offset, Model model) { - model.addAttribute("orderList", orderService.findAllByMember(rq.CheckMember().get(), 0)); + model.addAttribute("orderList", orderService.findAllByMember(rq.CheckMember().get(), offset)); return "trendpick/usr/member/orders"; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java index f44ef683..409b0a10 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java @@ -2,7 +2,6 @@ import jakarta.persistence.*; import lombok.AccessLevel; -import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java index 825eec83..46a6ae07 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java @@ -17,22 +17,28 @@ public class OrderResponse { private String brandName; private String productName; private String size; + private int count; private LocalDateTime orderDate; - private int totalPrice; + private int productPrice; private String orderStatus; private String deliveryStatus; @Builder @QueryProjection - public OrderResponse(Long orderId, String productFilePath, String brandName, String productName, String size, LocalDateTime orderDate, int totalPrice, String orderStatus, String deliveryStatus) { + public OrderResponse(Long orderId, String productFilePath, String brandName, String productName, String size, int count,int productPrice, LocalDateTime orderDate, String orderStatus, String deliveryStatus) { this.orderId = orderId; this.productFilePath = productFilePath; this.brandName = brandName; this.productName = productName; this.size = size; + this.count = count; + this.productPrice = productPrice; this.orderDate = orderDate; - this.totalPrice = totalPrice; this.orderStatus = orderStatus; this.deliveryStatus = deliveryStatus; } + + public int getTotalPrice(){ + return productPrice * count; + } } diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java index d86f6be6..ae1caa23 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java @@ -36,8 +36,9 @@ public Page findAllByMember(OrderSearchCond orderSearchCond, Page orderItem.product.brand.name, orderItem.product.name, orderItem.size, - orderItem.order.createdDate, + orderItem.count, orderItem.orderPrice, + orderItem.order.createdDate, orderItem.order.status.stringValue(), orderItem.order.delivery.state.stringValue()) ) diff --git a/src/main/resources/templates/trendpick/usr/member/orders.html b/src/main/resources/templates/trendpick/usr/member/orders.html index 727e8444..1053a78e 100644 --- a/src/main/resources/templates/trendpick/usr/member/orders.html +++ b/src/main/resources/templates/trendpick/usr/member/orders.html @@ -16,8 +16,9 @@

주문 목록

상품이미지 상품명 사이즈 - 주문일시 + 주문수량 주문금액 + 주문일시 주문상태 배송상태 @@ -29,8 +30,9 @@

주문 목록


- + + From 9d7ae8da4d46d4a467d7dd2aadbcea27a2bb8e6e Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 7 Jun 2023 13:41:29 +0900 Subject: [PATCH 182/367] =?UTF-8?q?feat:=20=EC=A3=BC=EB=AC=B8=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=EC=97=90=20=EB=A6=AC=EB=B7=B0=EB=93=B1=EB=A1=9D=20?= =?UTF-8?q?=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80=20(#125)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/orders/entity/dto/response/OrderResponse.java | 6 +++--- .../resources/templates/trendpick/usr/member/orders.html | 6 ++++++ 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java index 46a6ae07..b615347e 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java @@ -12,7 +12,7 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class OrderResponse { - private Long orderId; + private Long productId; private String productFilePath; private String brandName; private String productName; @@ -25,8 +25,8 @@ public class OrderResponse { @Builder @QueryProjection - public OrderResponse(Long orderId, String productFilePath, String brandName, String productName, String size, int count,int productPrice, LocalDateTime orderDate, String orderStatus, String deliveryStatus) { - this.orderId = orderId; + public OrderResponse(Long productId, String productFilePath, String brandName, String productName, String size, int count,int productPrice, LocalDateTime orderDate, String orderStatus, String deliveryStatus) { + this.productId = productId; this.productFilePath = productFilePath; this.brandName = brandName; this.productName = productName; diff --git a/src/main/resources/templates/trendpick/usr/member/orders.html b/src/main/resources/templates/trendpick/usr/member/orders.html index 1053a78e..e46c961c 100644 --- a/src/main/resources/templates/trendpick/usr/member/orders.html +++ b/src/main/resources/templates/trendpick/usr/member/orders.html @@ -21,6 +21,7 @@

주문 목록

주문일시 주문상태 배송상태 + 리뷰 @@ -35,6 +36,11 @@

주문 목록

+ + + 리뷰등록 + + From 831e586862dfb4f607185a00aeebba3b040279d0 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Wed, 7 Jun 2023 13:55:39 +0900 Subject: [PATCH 183/367] =?UTF-8?q?feat:=20review=20list/detail/register?= =?UTF-8?q?=20=ED=94=84=EB=A1=A0=ED=8A=B8=20=EC=9E=91=EC=97=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/trendpick/review/detail.html | 6 +- .../trendpick/review/layout/layout.html | 68 ++++++++++++++++++ .../templates/trendpick/review/list.html | 71 +++++++------------ .../templates/trendpick/review/register.html | 59 +++++++++++---- 4 files changed, 139 insertions(+), 65 deletions(-) create mode 100644 src/main/resources/templates/trendpick/review/layout/layout.html diff --git a/src/main/resources/templates/trendpick/review/detail.html b/src/main/resources/templates/trendpick/review/detail.html index 1f7371cc..42199e25 100644 --- a/src/main/resources/templates/trendpick/review/detail.html +++ b/src/main/resources/templates/trendpick/review/detail.html @@ -14,9 +14,9 @@

작성자

- 메인 이미지 -
- 서브 이미지 +
+
+ 서브 이미지
diff --git a/src/main/resources/templates/trendpick/review/layout/layout.html b/src/main/resources/templates/trendpick/review/layout/layout.html new file mode 100644 index 00000000..c1afbd7d --- /dev/null +++ b/src/main/resources/templates/trendpick/review/layout/layout.html @@ -0,0 +1,68 @@ + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/review/list.html b/src/main/resources/templates/trendpick/review/list.html index 8b0ff55f..250bac9f 100644 --- a/src/main/resources/templates/trendpick/review/list.html +++ b/src/main/resources/templates/trendpick/review/list.html @@ -1,25 +1,34 @@ - 게시물 목록 + 리뷰 목록 + - -리뷰리스트입니다 -
- -
-

-

작성자:

-

상품명:

-

메인 파일: 메인 이미지

-

내용:

-

평점:

-
- +
+
+
+
+
+ +

제목:

+

상품명:

+

평점:

+
+
+
-
Previous @@ -30,35 +39,3 @@

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/main/resources/templates/trendpick/review/register.html b/src/main/resources/templates/trendpick/review/register.html index 3965ad91..1e830afc 100644 --- a/src/main/resources/templates/trendpick/review/register.html +++ b/src/main/resources/templates/trendpick/review/register.html @@ -9,32 +9,61 @@
-
- - + + + + +
+ +
-
- - -
+ + + + + +
+ +
-
- + + + + +
+
-
- - +
+ +
-
- - +
+ +
+ From 3413a2f98b86fc085293b322d5e0e678c769d859 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Wed, 7 Jun 2023 14:13:41 +0900 Subject: [PATCH 184/367] =?UTF-8?q?refactor:=20=EC=A3=BC=EB=AC=B8=EB=AA=A9?= =?UTF-8?q?=EB=A1=9D=EC=97=90=EC=84=9C=20=EB=A6=AC=EB=B7=B0=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=20=EA=B0=80=EB=8A=A5=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=EC=97=B0=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 12 +++++++----- .../templates/trendpick/review/register.html | 16 +--------------- 2 files changed, 8 insertions(+), 20 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index b488709b..a7a1adda 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -32,18 +32,20 @@ public class ReviewController { private final MemberRepository memberRepository; private final Rq rq; - @GetMapping("/register") - public String registerReview() { + @GetMapping("/register/{productId}") + public String registerReview(@PathVariable("productId") Long productId, Model model) { + model.addAttribute("productId", productId); return "/trendpick/review/register"; } - @PostMapping("/register") + @PostMapping("/register/{productId}") public String createReview(@Valid ReviewSaveRequest reviewCreateRequest, @RequestParam("mainFile") MultipartFile mainFile, - @RequestParam("subFiles") List subFiles, Model model) throws Exception { + @RequestParam("subFiles") List subFiles, + @PathVariable("productId") Long productId, Model model) throws Exception { Member member = rq.getMember(); - ReviewResponse reviewResponse = reviewService.createReview(member, 1L, reviewCreateRequest, mainFile, subFiles); + ReviewResponse reviewResponse = reviewService.createReview(member, productId, reviewCreateRequest, mainFile, subFiles); model.addAttribute("reviewResponse", reviewResponse); return "redirect:/trendpick/review/list"; diff --git a/src/main/resources/templates/trendpick/review/register.html b/src/main/resources/templates/trendpick/review/register.html index 1e830afc..5469dfe0 100644 --- a/src/main/resources/templates/trendpick/review/register.html +++ b/src/main/resources/templates/trendpick/review/register.html @@ -8,11 +8,7 @@ -
- - - - +
- - - - -
- - - -
-
From 813f5af6ebb2bb33ad9b97b54aaaf0c5284ee351 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Wed, 7 Jun 2023 15:25:51 +0900 Subject: [PATCH 185/367] =?UTF-8?q?refactor:=20=ED=8F=BC=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/trendpick/review/modify.html | 51 ++++++++++++------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/src/main/resources/templates/trendpick/review/modify.html b/src/main/resources/templates/trendpick/review/modify.html index 00b2aa38..66255e90 100644 --- a/src/main/resources/templates/trendpick/review/modify.html +++ b/src/main/resources/templates/trendpick/review/modify.html @@ -4,37 +4,54 @@ - 리뷰 등록 + 리뷰 수정
-
- - + +
+ +
-
- - -
+
+ +
-
- - +
+ +
-
- - +
+ +
-
- - +
+ +
+ From ef4c705fd9521bcf669c45fc72a1f30e97e006e7 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Wed, 7 Jun 2023 15:42:00 +0900 Subject: [PATCH 186/367] =?UTF-8?q?feat:=20=EB=82=B4=EA=B0=80=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1=ED=95=9C=20=EB=A6=AC=EB=B7=B0=EB=A7=8C=20=EB=B3=B4?= =?UTF-8?q?=EA=B8=B0/=20=EB=82=B4=EA=B0=80=20=EC=9E=91=EC=84=B1=ED=95=9C?= =?UTF-8?q?=20=EB=A6=AC=EB=B7=B0=EC=97=90=EB=A7=8C=20=EC=88=98=EC=A0=95?= =?UTF-8?q?=ED=95=98=EA=B8=B0=20=EB=B2=84=ED=8A=BC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/review/controller/ReviewController.java | 10 ++++++++++ .../domain/review/repository/ReviewRepository.java | 2 ++ .../domain/review/service/ReviewService.java | 6 ++++++ .../resources/templates/trendpick/review/detail.html | 3 +++ .../resources/templates/trendpick/review/list.html | 1 - 5 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index a7a1adda..a3bf5898 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -55,7 +55,9 @@ public String createReview(@Valid ReviewSaveRequest reviewCreateRequest, @GetMapping("/{reviewId}") public String showReview(@PathVariable Long reviewId, Model model){ ReviewResponse reviewResponse = reviewService.showReview(reviewId); + String currentUser = rq.getMember().getUsername(); model.addAttribute("reviewResponse", reviewResponse); + model.addAttribute("currentUser", currentUser); return "/trendpick/review/detail"; } @@ -90,4 +92,12 @@ public String showAllReview(Pageable pageable, Model model){ model.addAttribute("reviewResponses", reviewResponses); return "/trendpick/review/list"; } + + @GetMapping("/user") + public String showOwnReview(Pageable pageable, Model model){ + String writer = rq.getMember().getUsername(); + Page reviewResponses = reviewService.showOwnReview(writer, pageable); + model.addAttribute("reviewResponses", reviewResponses); + return "/trendpick/review/list"; + } } diff --git a/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java b/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java index 7aa8190b..7b3b2796 100644 --- a/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java +++ b/src/main/java/project/trendpick_pro/domain/review/repository/ReviewRepository.java @@ -3,7 +3,9 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.review.entity.Review; public interface ReviewRepository extends JpaRepository { + Page findByWriter(String writer, Pageable pageable); } diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index e1381937..fc966449 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -109,6 +109,12 @@ public Page showAll(Pageable pageable) { return reviewPage.map(ReviewResponse::of); } + @Transactional + public Page showOwnReview(String writer, Pageable pageable) { + Page reviewPage = reviewRepository.findByWriter(writer, pageable); + return reviewPage.map(ReviewResponse::of); + } + // public Page showAll(int offset) { // Pageable pageable = PageRequest.of(offset, 20); // Page reviews = reviewRepository.findAllByPage(pageable); diff --git a/src/main/resources/templates/trendpick/review/detail.html b/src/main/resources/templates/trendpick/review/detail.html index 42199e25..9ae4d666 100644 --- a/src/main/resources/templates/trendpick/review/detail.html +++ b/src/main/resources/templates/trendpick/review/detail.html @@ -27,6 +27,9 @@

제목

내용

후기내용

+ + 수정하기 +
diff --git a/src/main/resources/templates/trendpick/review/list.html b/src/main/resources/templates/trendpick/review/list.html index 250bac9f..4488b87e 100644 --- a/src/main/resources/templates/trendpick/review/list.html +++ b/src/main/resources/templates/trendpick/review/list.html @@ -20,7 +20,6 @@

-

제목:

상품명:

평점:

From a66a27dabada4363b5b73987eaa0e64dd53d7de3 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Wed, 7 Jun 2023 15:42:24 +0900 Subject: [PATCH 187/367] =?UTF-8?q?docs:=20basedata=20=EC=9C=A0=EC=A0=80?= =?UTF-8?q?=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/basedata/BaseData.java | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index b01c14ea..19ad4dfc 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -122,9 +122,19 @@ public void run(String... args) { .tags(List.of("오버핏청바지", "로맨틱룩")) .build(); + JoinForm member2 = JoinForm.builder() + .email("hye_0000@naver.com") + .password("12345") + .username("hye0000") + .phoneNumber("010-1234-1234") + .state("MEMBER") + .tags(List.of("오버핏청바지", "로맨틱룩")) + .build(); + memberService.register(admin); memberService.register(brand_admin); memberService.register(member); + memberService.register(member2); //==상품데이터==// for(int n=1; n<=10; n++) { @@ -161,7 +171,7 @@ public void run(String... args) { } //==주문데이터==// - Member findMember = memberService.findByEmail("trendpick@naver.com").get(); + Member findMember = memberService.findByEmail("hye_0000@naver.com").get(); MemberInfoDto memberInfo = new MemberInfoDto(findMember); List orderItems = new ArrayList<>(); @@ -172,6 +182,19 @@ public void run(String... args) { OrderForm orderForm = new OrderForm(memberInfo, orderItems); orderForm.setPaymentMethod("신용카드"); orderservice.order(findMember, orderForm); + + //==주문데이터2==// + Member findMember2 = memberService.findByEmail("trendpick@naver.com").get(); + MemberInfoDto memberInfo2 = new MemberInfoDto(findMember2); + List orderItems2 = new ArrayList<>(); + + orderItems2.add(new OrderItemDto(productRepository.findById(1L).get(), "M", 5)); + orderItems2.add(new OrderItemDto(productRepository.findById(2L).get(), "L", 3)); + orderItems2.add(new OrderItemDto(productRepository.findById(3L).get(), "S", 2)); + + OrderForm orderForm2 = new OrderForm(memberInfo2, orderItems2); + orderForm2.setPaymentMethod("신용카드"); + orderservice.order(findMember2, orderForm2); } }; } From eae3ee54b4db2957b16d6e43fdfb0052027e6885 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Wed, 7 Jun 2023 15:55:28 +0900 Subject: [PATCH 188/367] =?UTF-8?q?refactor:=20=EB=82=B4=20=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=EB=A7=8C=20=EB=B3=B4=EA=B8=B0=20=EB=B2=84=ED=8A=BC=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80/=20=EB=82=B4=20=EB=A6=AC=EB=B7=B0=EC=97=94?= =?UTF-8?q?=20=EC=88=98=EC=A0=95=ED=95=98=EA=B8=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 내 리뷰만 볼 수 있는 버튼 추가 - 내가 작성한 리뷰라면 list/detail 페이지에서 수정하기 버튼 생성 되도록 --- .../domain/review/controller/ReviewController.java | 2 ++ src/main/resources/templates/trendpick/review/list.html | 4 ++++ 2 files changed, 6 insertions(+) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index a3bf5898..f762d0a7 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -89,7 +89,9 @@ public String updateReview(@PathVariable Long reviewId, ReviewSaveRequest review @GetMapping("/list") public String showAllReview(Pageable pageable, Model model){ Page reviewResponses = reviewService.showAll(pageable); + String currentUser = rq.getMember().getUsername(); model.addAttribute("reviewResponses", reviewResponses); + model.addAttribute("currentUser", currentUser); return "/trendpick/review/list"; } diff --git a/src/main/resources/templates/trendpick/review/list.html b/src/main/resources/templates/trendpick/review/list.html index 4488b87e..b35efe4a 100644 --- a/src/main/resources/templates/trendpick/review/list.html +++ b/src/main/resources/templates/trendpick/review/list.html @@ -15,6 +15,9 @@ +
@@ -23,6 +26,7 @@

제목:

상품명:

평점:

+ 수정하기
From 3eceed8c8bd363929d024f9c08ec3d592c519669 Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Wed, 7 Jun 2023 16:31:36 +0900 Subject: [PATCH 189/367] =?UTF-8?q?feat:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=20=EC=83=81=ED=92=88=20=EC=B6=94=EA=B0=80=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cart/controller/CartController.java | 32 ++++++++++++---- .../domain/cart/entity/Cart.java | 1 + .../domain/cart/entity/CartItem.java | 25 ++++++++----- .../entity/dto/request/CartItemRequest.java | 5 ++- .../entity/dto/response/CartItemResponse.java | 37 +++++++++++++++++++ .../domain/cart/service/CartService.java | 23 +++++++++--- .../templates/trendpick/usr/cart/add.html | 32 ++++++++++++++++ .../templates/trendpick/usr/cart/list.html | 32 ++++++++++++++++ 8 files changed, 165 insertions(+), 22 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java create mode 100644 src/main/resources/templates/trendpick/usr/cart/add.html diff --git a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java index 4f753e2a..2a5eaeee 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java +++ b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java @@ -3,23 +3,29 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import org.springframework.stereotype.Controller; import project.trendpick_pro.domain.cart.entity.Cart; +import project.trendpick_pro.domain.cart.entity.CartItem; import project.trendpick_pro.domain.cart.entity.dto.request.CartItemRequest; +import project.trendpick_pro.domain.cart.entity.dto.response.CartItemResponse; +import project.trendpick_pro.domain.cart.entity.dto.response.CartResponse; import project.trendpick_pro.domain.cart.service.CartService; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.entity.form.JoinForm; import project.trendpick_pro.domain.orders.entity.dto.request.OrderSaveRequest; import java.util.List; - +@Slf4j @Controller @RequiredArgsConstructor -@RequestMapping("/trendpick/cart") +@RequestMapping("/trendpick/usr/cart") public class CartController { private final CartService cartService; private final Rq rq; @@ -29,15 +35,27 @@ public class CartController { public String showCart(Model model) { List carts=cartService.findByCartMember(rq.getMember()); model.addAttribute("carts",carts); - return "redirect:/trendprick/list"; + return "redirect:/trendpick/usr/cart/list"; } @PreAuthorize("isAuthenticated()") @GetMapping("/add/{productId}") - public String addItemToCart(@PathVariable("productId") Long productId, @Valid CartItemRequest cartItemRequests) { - cartService.addItemToCart(rq.getMember(),productId,cartItemRequests); - // 쇼핑을 계속 하시겠습니까? 띄우고 yes이면 main no면 cart로 - return "redirect:/trendprick/list"; + public String addItemToCart(@PathVariable("productId") Long productId,CartItemRequest cartItemRequests,Model model) { + model.addAttribute("cartItemRequest",cartItemRequests); + // 쇼핑을 계속 하시겠습니까? 띄우고 yes이면 main no면 cart로 + return "/trendpick/usr/cart/add"; + } + + + @PreAuthorize("isAuthenticated()") + @PostMapping("/add") + public String addItem(Long productId, @ModelAttribute @Valid CartItemRequest cartItemRequests,Model model) { + CartItemResponse cartItemResponse=cartService.addItemToCart(productId,cartItemRequests); + model.addAttribute("cartItemResponse",cartItemResponse); + // System.out.println(cartItemRequests.getCount()); + // System.out.println(cartItemRequests.getColor()); + // 쇼핑을 계속 하시겠습니까? 띄우고 yes이면 main no면 cart로 + return "/trendpick/usr/cart/list"; } @PreAuthorize("isAuthenticated()") diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java index 8c9b1445..013bd46c 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java @@ -40,6 +40,7 @@ public static Cart createCart(Member member){ Cart cart = new Cart(); cart.member= member; cart.totalCount = 0; + cart.totalPrice=0; return cart; } diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java index 024cf308..a468dc7d 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java @@ -27,15 +27,22 @@ public class CartItem { private String size; // 해당 상품 사이즈 private int count; // 해당 상품 수량 - - public static CartItem createCartItem(Cart cart, Product product, CartItemRequest cartItemRequest){ - CartItem cartItem = new CartItem(); - cartItem.setCart(cart); - cartItem.setProduct(product); - cartItem.setColor(cartItemRequest.getColor()); - cartItem.setSize(cartItemRequest.getSize()); - cartItem.setCount(cartItemRequest.getCount()); - return cartItem; + @Builder + public CartItem(Cart cart, Product product, String color, String size, int count) { + this.cart = cart; + this.product = product; + this.color = color; + this.size = size; + this.count = count; + } + public static CartItem of(Cart cart, Product product, CartItemRequest cartItemRequest){ + return CartItem.builder() + .cart(cart) + .product(product) + .color(cartItemRequest.getColor()) + .size(cartItemRequest.getSize()) + .count(cartItemRequest.getCount()) + .build(); } public void addCount(int count){ this.count += count; diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java index 895f4353..2e305ea5 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java @@ -1,16 +1,19 @@ package project.trendpick_pro.domain.cart.entity.dto.request; +import jakarta.validation.constraints.Min; import jakarta.validation.constraints.NotBlank; import lombok.Getter; +import lombok.Setter; @Getter +@Setter public class CartItemRequest { @NotBlank(message = "해당 상품의 색상을 입력해주세요.") private String color; @NotBlank(message ="해당 상품의 사이즈를 입력해주세요.") private String size; - @NotBlank(message = "해당 상품 수량을 입력해주세요.") + @Min(value=1,message = "한 개 이상 선택하세요.") private int count; } diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java new file mode 100644 index 00000000..19b5e159 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java @@ -0,0 +1,37 @@ +package project.trendpick_pro.domain.cart.entity.dto.response; + +import com.querydsl.core.annotations.QueryProjection; +import lombok.AccessLevel; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; +import project.trendpick_pro.domain.cart.entity.CartItem; + + + +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class CartItemResponse { + private Long id; + private String color; + private String size; + private int count; + + @Builder + @QueryProjection + public CartItemResponse(Long id, String color, String size, int count) { + this.id = id; + this.color = color; + this.size = size; + this.count = count; + } + + public static CartItemResponse of(CartItem cartItem) { + return CartItemResponse.builder() + .id(cartItem.getId()) + .color(cartItem.getColor()) + .size(cartItem.getSize()) + .count(cartItem.getCount()) + .build(); + } +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index 9c0b0487..eadc3a73 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -1,11 +1,14 @@ package project.trendpick_pro.domain.cart.service; import lombok.RequiredArgsConstructor; +import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.cart.entity.Cart; import project.trendpick_pro.domain.cart.entity.CartItem; import project.trendpick_pro.domain.cart.entity.dto.request.CartItemRequest; +import project.trendpick_pro.domain.cart.entity.dto.response.CartItemResponse; +import project.trendpick_pro.domain.cart.entity.dto.response.CartResponse; import project.trendpick_pro.domain.cart.repository.CartItemRepository; import project.trendpick_pro.domain.cart.repository.CartRepository; import project.trendpick_pro.domain.member.entity.Member; @@ -15,7 +18,6 @@ import project.trendpick_pro.domain.product.exception.ProductNotFoundException; import project.trendpick_pro.domain.product.repository.ProductOptionRepository; import project.trendpick_pro.domain.product.repository.ProductRepository; -import project.trendpick_pro.domain.tags.favoritetag.entity.FavoriteTag; import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; import project.trendpick_pro.domain.tags.tag.entity.type.TagType; import project.trendpick_pro.domain.tags.tag.service.TagService; @@ -41,8 +43,8 @@ public List findByCartMember(Member member){ } @Transactional - public void addItemToCart(Member member, Long productId, CartItemRequest cartItemRequest) { - member=memberRepository.findById(member.getId()).orElseThrow(()->new MemberNotFoundException("존재하지 않는 유저입니다.")); + public CartItemResponse addItemToCart(Long productId, CartItemRequest cartItemRequest) { + Member member=CheckMember(); Cart cart = cartRepository.findByMemberId(member.getId()); Product product=productRepository.findById(productId).orElseThrow(() -> new ProductNotFoundException("존재하지 않는 상품 입니다.")); @@ -60,10 +62,13 @@ public void addItemToCart(Member member, Long productId, CartItemRequest cartIte cartItem.addCount(cartItem.getCount()); } else { // 카트에 해당 상품이 없는 경우, 새로운 카트 아이템을 생성하여 추가 - cartItem =CartItem.createCartItem(cart,product,cartItemRequest); - cartItemRepository.save(cartItem); + cartItem =CartItem.of(cart,product,cartItemRequest); cart.setTotalCount(cart.getTotalCount()+1); + cart.setTotalPrice(product.getPrice()); + cart.addItem(cartItem); } + cartItemRepository.save(cartItem); + return CartItemResponse.of(cartItem); } // 상품을 장바구니에서 제거 @@ -86,4 +91,12 @@ private Product getProductById(Long productId){ return productRepository.findById(productId) .orElseThrow(() -> new IllegalArgumentException("해당 상품을 찾을 수 없습니다.")); } + + private Member CheckMember() { + + String username = SecurityContextHolder.getContext().getAuthentication().getName(); + Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); + return member; + } + } \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/cart/add.html b/src/main/resources/templates/trendpick/usr/cart/add.html new file mode 100644 index 00000000..8d130fe4 --- /dev/null +++ b/src/main/resources/templates/trendpick/usr/cart/add.html @@ -0,0 +1,32 @@ + + + + + 장바구니 + + + + +
+ +
+ + +

+
+
+ + +

+
+ +
+ + +

+
+ + +
+ + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/cart/list.html b/src/main/resources/templates/trendpick/usr/cart/list.html index e69de29b..2bfa3a11 100644 --- a/src/main/resources/templates/trendpick/usr/cart/list.html +++ b/src/main/resources/templates/trendpick/usr/cart/list.html @@ -0,0 +1,32 @@ + + + + + 장바구니 + + + + +

장바구니

+ + + + + + + + + + + + + + + + + + +
상품명색상사이즈수량
+ + + \ No newline at end of file From a515887e05fe4a5704fd434ad2ba17d6709f9fac Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Wed, 7 Jun 2023 16:34:34 +0900 Subject: [PATCH 190/367] =?UTF-8?q?feat:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=20=EB=A6=AC=EC=8A=A4=ED=8A=B8=20=EB=B0=8F=20=EC=82=AD?= =?UTF-8?q?=EC=A0=9C=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cart/controller/CartController.java | 44 ++++++++++------- .../domain/cart/entity/Cart.java | 26 +++++----- .../domain/cart/entity/CartItem.java | 1 + .../entity/dto/response/CartResponse.java | 5 +- .../domain/cart/service/CartService.java | 47 +++++++++++-------- .../domain/member/entity/Member.java | 3 ++ .../domain/member/service/MemberService.java | 4 ++ .../templates/trendpick/usr/cart/list.html | 27 ++++++++--- 8 files changed, 98 insertions(+), 59 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java index 2a5eaeee..49cdcdb7 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java +++ b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java @@ -13,12 +13,10 @@ import project.trendpick_pro.domain.cart.entity.CartItem; import project.trendpick_pro.domain.cart.entity.dto.request.CartItemRequest; import project.trendpick_pro.domain.cart.entity.dto.response.CartItemResponse; -import project.trendpick_pro.domain.cart.entity.dto.response.CartResponse; import project.trendpick_pro.domain.cart.service.CartService; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.member.entity.form.JoinForm; -import project.trendpick_pro.domain.orders.entity.dto.request.OrderSaveRequest; +import project.trendpick_pro.domain.member.service.MemberService; import java.util.List; @@ -28,20 +26,30 @@ @RequestMapping("/trendpick/usr/cart") public class CartController { private final CartService cartService; + private final MemberService memberService; private final Rq rq; @PreAuthorize("isAuthenticated()") @GetMapping("/list") public String showCart(Model model) { - List carts=cartService.findByCartMember(rq.getMember()); - model.addAttribute("carts",carts); - return "redirect:/trendpick/usr/cart/list"; + Cart carts = cartService.getCartByUser(rq.getMember().getId()); + List cartItems = cartService.CartView(carts); + + int totalPrice = 0; + for (CartItem cartItem : cartItems) { + totalPrice += (cartItem.getProduct().getPrice() * cartItem.getCount()); + } + + model.addAttribute("cartItems", cartItems); + model.addAttribute("totalPrice", totalPrice); + return "/trendPick/usr/cart/list"; } @PreAuthorize("isAuthenticated()") @GetMapping("/add/{productId}") - public String addItemToCart(@PathVariable("productId") Long productId,CartItemRequest cartItemRequests,Model model) { - model.addAttribute("cartItemRequest",cartItemRequests); + public String addItemToCart(@PathVariable("productId") Long productId, CartItemRequest cartItemRequests, Model model) { + Member member = rq.getMember(); + model.addAttribute("cartItemRequest", cartItemRequests); // 쇼핑을 계속 하시겠습니까? 띄우고 yes이면 main no면 cart로 return "/trendpick/usr/cart/add"; } @@ -49,21 +57,23 @@ public String addItemToCart(@PathVariable("productId") Long productId,CartItemRe @PreAuthorize("isAuthenticated()") @PostMapping("/add") - public String addItem(Long productId, @ModelAttribute @Valid CartItemRequest cartItemRequests,Model model) { - CartItemResponse cartItemResponse=cartService.addItemToCart(productId,cartItemRequests); - model.addAttribute("cartItemResponse",cartItemResponse); + public String addItem(Long productId, @ModelAttribute @Valid CartItemRequest cartItemRequests, Model model) { + CartItemResponse cartItemResponse = cartService.addItemToCart(productId, cartItemRequests); + model.addAttribute("cartItemResponse", cartItemResponse); // System.out.println(cartItemRequests.getCount()); // System.out.println(cartItemRequests.getColor()); // 쇼핑을 계속 하시겠습니까? 띄우고 yes이면 main no면 cart로 - return "/trendpick/usr/cart/list"; + return "redirect:/trendpick/usr/cart/list"; } + @PreAuthorize("isAuthenticated()") - @PostMapping("/remove") - public String removeItemFromCart(@RequestParam("cartItemId") Long cartItemId) { - Member member = rq.getMember(); - cartService.removeItemFromCart(member, cartItemId); - return "redirect:/trendpick/list"; + @GetMapping("{memberId}/{cartItemId}") + public String removeItem(@PathVariable("memberId") Long memberId,@PathVariable("cartItemId") Long cartItemId) { + Member member = memberService.findByMember(memberId); + member.getCart().setTotalCount(member.getCart().getTotalCount() - 1); + cartService.removeItemFromCart(cartItemId); + return "redirect:/trendpick/usr/cart/list"; } @PreAuthorize("isAuthenticated()") diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java index 013bd46c..74ffbe98 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java @@ -33,14 +33,10 @@ public class Cart { // 총 수량 필드 private int totalCount; - // 총 가격 필드 - private int totalPrice; - public static Cart createCart(Member member){ Cart cart = new Cart(); cart.member= member; cart.totalCount = 0; - cart.totalPrice=0; return cart; } @@ -52,7 +48,7 @@ public Cart(Member member) { public void addItem(CartItem cartItem) { cartItems.add(cartItem); cartItem.setCart(this); - updateTotalCountAndPrice(); + // updateTotalCountAndPrice(); } // CartItem 삭제 @@ -60,7 +56,6 @@ public void removeItem(Long cartItemId) { CartItem cartItem = findCartItemById(cartItemId); if (cartItem != null) { cartItems.remove(cartItem); - updateTotalCountAndPrice(); } } @@ -70,7 +65,7 @@ public void updateItemCount(Long cartItemId, int count) { CartItem cartItem = findCartItemById(cartItemId); if (cartItem != null) { cartItem.setCount(count); - updateTotalCountAndPrice(); + // updateTotalCountAndPrice(); } } @@ -80,12 +75,17 @@ private CartItem findCartItemById(Long cartItemId) { .findFirst() .orElse(null); } - - private void updateTotalCountAndPrice() { - for(CartItem cartItem:cartItems){ - totalPrice+=(cartItem.getProduct().getPrice()*cartItem.getCount()); +/* + public void updateTotalCountAndPrice() { + if (cartItems.isEmpty()) { + totalPrice = 0; + totalCount = 0; + } else { + for (CartItem cartItem : cartItems) { + totalPrice += (cartItem.getProduct().getPrice() * cartItem.getCount()); + } + totalCount = cartItems.size(); } } - - + */ } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java index a468dc7d..42a8aa15 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java @@ -47,4 +47,5 @@ public static CartItem of(Cart cart, Product product, CartItemRequest cartItemRe public void addCount(int count){ this.count += count; } + } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java index f091813a..3bdca328 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java @@ -16,18 +16,16 @@ public class CartResponse { private int totalCount; - private int totalPrice; private List cartItems; @Builder @QueryProjection - public CartResponse(Long id, Long memberId, int totalCount, int totalPrice, List cartItems) { + public CartResponse(Long id, Long memberId, int totalCount, List cartItems) { this.id = id; this.memberId = memberId; this.totalCount=totalCount; - this.totalPrice=totalPrice; this.cartItems=cartItems; } @@ -36,7 +34,6 @@ public static CartResponse of (Cart cart) { .id(cart.getId()) .memberId(cart.getMember().getId()) .totalCount(cart.getTotalCount()) - .totalPrice(cart.getTotalPrice()) .cartItems(cart.getCartItems()) .build(); } diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index eadc3a73..f9074a1a 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -22,6 +22,7 @@ import project.trendpick_pro.domain.tags.tag.entity.type.TagType; import project.trendpick_pro.domain.tags.tag.service.TagService; +import java.util.ArrayList; import java.util.List; @@ -35,22 +36,32 @@ public class CartService { private final ProductOptionRepository productOptionRepository; private final ProductRepository productRepository; private final CartItemRepository cartItemRepository; - private final TagService tagService; private final FavoriteTagService favoriteTagService; - public List findByCartMember(Member member){ - return cartRepository.findByCartMember(member); + + // 장바구니 조회 + public List CartView(Cart cart) { + List cartItems = cartItemRepository.findAll(); + List userItems = new ArrayList<>(); + + for (CartItem cartItem : cartItems) { + if (cartItem.getCart().getId() == cart.getId()) { + userItems.add(cartItem); + } + } + return userItems; } + // 장바구니 상품 추가 @Transactional public CartItemResponse addItemToCart(Long productId, CartItemRequest cartItemRequest) { - Member member=CheckMember(); + Member member = CheckMember(); Cart cart = cartRepository.findByMemberId(member.getId()); - Product product=productRepository.findById(productId).orElseThrow(() -> new ProductNotFoundException("존재하지 않는 상품 입니다.")); + Product product = getProductById(productId); - if(cart==null){ + if (cart == null) { // 장바구니가 비어있다면 생성 - cart=Cart.createCart(member); + cart = Cart.createCart(member); cartRepository.save(cart); } CartItem cartItem = cartItemRepository.findByCartIdAndProductId(cart.getId(), product.getId()); @@ -62,38 +73,36 @@ public CartItemResponse addItemToCart(Long productId, CartItemRequest cartItemRe cartItem.addCount(cartItem.getCount()); } else { // 카트에 해당 상품이 없는 경우, 새로운 카트 아이템을 생성하여 추가 - cartItem =CartItem.of(cart,product,cartItemRequest); - cart.setTotalCount(cart.getTotalCount()+1); - cart.setTotalPrice(product.getPrice()); - cart.addItem(cartItem); + cartItem = CartItem.of(cart, product, cartItemRequest); + cart.setTotalCount(cart.getTotalCount() + 1); } cartItemRepository.save(cartItem); return CartItemResponse.of(cartItem); } + // 상품을 장바구니에서 제거 - public void removeItemFromCart(Member member, Long cartItemId) { - Cart cart = getCartByUser(member); - cart.removeItem(cartItemId); + @Transactional + public void removeItemFromCart(Long cartItemId) { + cartItemRepository.deleteById(cartItemId); } // 상품의 수량 업데이트 public void updateItemCount(Member member, Long cartItemId, int count) { - Cart cart = getCartByUser(member); + Cart cart = getCartByUser(member.getId()); cart.updateItemCount(cartItemId, count); } - public Cart getCartByUser(Member member) { - return cartRepository.findByMemberId(member.getId()); + public Cart getCartByUser(Long memberId) { + return cartRepository.findByMemberId(memberId); } - private Product getProductById(Long productId){ + private Product getProductById(Long productId) { return productRepository.findById(productId) .orElseThrow(() -> new IllegalArgumentException("해당 상품을 찾을 수 없습니다.")); } private Member CheckMember() { - String username = SecurityContextHolder.getContext().getAuthentication().getName(); Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); return member; diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index 5073d5dc..bcc77dc7 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -2,6 +2,7 @@ import jakarta.persistence.*; import lombok.*; +import project.trendpick_pro.domain.cart.entity.Cart; import project.trendpick_pro.domain.tags.favoritetag.entity.FavoriteTag; import java.util.LinkedHashSet; @@ -31,6 +32,8 @@ public class Member { @Column(name = "role", nullable = false) private RoleType role; + @OneToOne(mappedBy = "member") + private Cart cart; @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) private Set tags = new LinkedHashSet<>(); diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index 41c82170..2642d366 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -36,6 +36,10 @@ public Optional findByEmail(String username){ return memberRepository.findByEmail(username); } + public Member findByMember(Long id){ + return memberRepository.findById(id).get(); + } + @Transactional public void register(JoinForm joinForm) { diff --git a/src/main/resources/templates/trendpick/usr/cart/list.html b/src/main/resources/templates/trendpick/usr/cart/list.html index 2bfa3a11..e62cc160 100644 --- a/src/main/resources/templates/trendpick/usr/cart/list.html +++ b/src/main/resources/templates/trendpick/usr/cart/list.html @@ -12,21 +12,36 @@

장바구니

+ + + - - - - - + + + + + + + +
번호상품ID 상품명 색상 사이즈 수량삭제
1삭제
- +
+
+
+
+

총 결제금액

+
+

+
+
+
\ No newline at end of file From a5f6ad8e28100fe397c38306a59bc09231ec7e9b Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Wed, 7 Jun 2023 16:39:37 +0900 Subject: [PATCH 191/367] =?UTF-8?q?feat:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=20=EA=B5=AC=EB=A7=A4=20=EB=B2=84=ED=8A=BC=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 --- src/main/resources/templates/trendpick/usr/cart/list.html | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main/resources/templates/trendpick/usr/cart/list.html b/src/main/resources/templates/trendpick/usr/cart/list.html index e62cc160..81a90ebc 100644 --- a/src/main/resources/templates/trendpick/usr/cart/list.html +++ b/src/main/resources/templates/trendpick/usr/cart/list.html @@ -39,7 +39,10 @@

장바구니

총 결제금액

-

+
+

+ +
From 94cfe6f12016b3d0204dc17f6a79d63ca1acfde6 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 7 Jun 2023 17:06:26 +0900 Subject: [PATCH 192/367] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20=EB=AC=B8?= =?UTF-8?q?=EC=9D=98=EC=99=80=20=EB=8B=B5=EB=B3=80=20=EB=A6=AC=ED=8C=A9?= =?UTF-8?q?=ED=86=A0=EB=A7=81=20(#125)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../answer/controller/AnswerController.java | 23 ++-- .../domain/answer/entity/Answer.java | 9 +- .../entity/dto/response/AnswerResponse.java | 42 +++--- .../domain/answer/entity/form/AnswerForm.java | 12 ++ .../domain/answer/service/AnswerService.java | 24 +--- .../domain/ask/controller/AskController.java | 38 +++--- .../trendpick_pro/domain/ask/entity/Ask.java | 18 ++- .../domain/ask/entity/AskStatus.java | 15 +++ .../domain/ask/entity/dto/form/AskForm.java | 18 +++ .../ask/entity/dto/request/AskRequest.java | 3 + .../dto/response/AskByProductResponse.java | 27 ---- .../ask/entity/dto/response/AskResponse.java | 49 +++---- .../domain/ask/repository/AskRepository.java | 10 +- .../ask/repository/AskRepositoryCustom.java | 9 +- .../ask/repository/AskRepositoryImpl.java | 122 +++++++++--------- .../domain/ask/service/AskService.java | 37 ++---- 16 files changed, 228 insertions(+), 228 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/answer/entity/form/AnswerForm.java create mode 100644 src/main/java/project/trendpick_pro/domain/ask/entity/AskStatus.java create mode 100644 src/main/java/project/trendpick_pro/domain/ask/entity/dto/form/AskForm.java delete mode 100644 src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskByProductResponse.java diff --git a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java index a126c9b5..e4e671c8 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java +++ b/src/main/java/project/trendpick_pro/domain/answer/controller/AnswerController.java @@ -7,6 +7,7 @@ import org.springframework.web.bind.annotation.*; import project.trendpick_pro.domain.answer.entity.dto.request.AnswerRequest; import project.trendpick_pro.domain.answer.entity.dto.response.AnswerResponse; +import project.trendpick_pro.domain.answer.entity.form.AnswerForm; import project.trendpick_pro.domain.answer.service.AnswerService; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; @@ -19,25 +20,27 @@ public class AnswerController { private final Rq rq; @PreAuthorize("isAuthenticated()") - @PostMapping("/register") - public String registerAnswer(@RequestParam("ask") Long askId, @Valid AnswerRequest answerRequest){ - Member member = rq.getMember(); - answerService.register(askId, member, answerRequest); + @PostMapping("register/{askId}") + public String register(@PathVariable Long askId, @Valid AnswerForm answerForm){ + rq.CheckAdmin().get(); + answerService.register(askId, answerForm); return "redirect:/trendpick/customerservice/asks/{askId}".formatted(askId); } @PreAuthorize("isAuthenticated()") @PostMapping("/delete/{answerId}") public String deleteAnswer(@PathVariable Long answerId){ - AnswerResponse res = answerService.delete(rq.getMember(), answerId); + rq.CheckAdmin().get(); + AnswerResponse answerResponse = answerService.delete(answerId); - return "redirect:/trendpick/customerservice/asks/%s".formatted(res.getAsk().getId()); + return "redirect:/trendpick/customerservice/asks/%s".formatted(answerResponse.getAskId()); } + @PreAuthorize("isAuthenticated()") @PostMapping("/moidfy/{answerId}") - public String modifyAnswer(@PathVariable Long answerId, @Valid AnswerRequest answerRequest){ - AnswerResponse res = answerService.modify(rq.getMember(), answerId, answerRequest); - - return "redirect:/trendpick/customerservice/asks/%s".formatted(res.getAsk().getId()); + public String modifyAnswer(@PathVariable Long answerId, @Valid AnswerForm answerForm){ + rq.CheckAdmin().get(); + AnswerResponse answerResponse = answerService.modify(answerId, answerForm); + return "redirect:/trendpick/customerservice/asks/%s".formatted(answerResponse.getAskId()); } } diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java b/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java index 03bb678f..95c309b7 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java +++ b/src/main/java/project/trendpick_pro/domain/answer/entity/Answer.java @@ -9,6 +9,7 @@ import org.springframework.data.annotation.CreatedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import project.trendpick_pro.domain.answer.entity.dto.request.AnswerRequest; +import project.trendpick_pro.domain.answer.entity.form.AnswerForm; import project.trendpick_pro.domain.ask.entity.Ask; import project.trendpick_pro.domain.ask.entity.dto.request.AskRequest; import project.trendpick_pro.domain.common.base.BaseTimeEntity; @@ -32,11 +33,11 @@ public class Answer extends BaseTimeEntity { private String content; - public static Answer write(Ask ask, AnswerRequest answerRequest) { + public static Answer write(Ask ask, AnswerForm answerForm) { Answer answer = Answer .builder() .ask(ask) - .content(answerRequest.getContent()) + .content(answerForm.getContent()) .build() ; @@ -44,7 +45,7 @@ public static Answer write(Ask ask, AnswerRequest answerRequest) { return answer; } - public void update(AnswerRequest answerRequest) { - this.content = content; + public void update(AnswerForm answerForm) { + this.content = answerForm.getContent(); } } diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/dto/response/AnswerResponse.java b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/response/AnswerResponse.java index a44407bd..8e52eb5c 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/entity/dto/response/AnswerResponse.java +++ b/src/main/java/project/trendpick_pro/domain/answer/entity/dto/response/AnswerResponse.java @@ -1,43 +1,43 @@ package project.trendpick_pro.domain.answer.entity.dto.response; -import lombok.Getter; +import lombok.*; import com.querydsl.core.annotations.QueryProjection; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.NoArgsConstructor; +import org.springframework.data.domain.Page; import project.trendpick_pro.domain.answer.entity.Answer; import project.trendpick_pro.domain.ask.entity.Ask; +import project.trendpick_pro.domain.ask.entity.dto.response.AskResponse; + import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; @Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) +@Builder +@NoArgsConstructor +@AllArgsConstructor public class AnswerResponse { - private Long id; - private Ask ask; + private Long answerId; + private Long askId; private String content; private LocalDateTime createdDate; - private LocalDateTime modifiedDate; - - @Builder - @QueryProjection - public AnswerResponse(Long id, Ask ask, String content, LocalDateTime createdDate, LocalDateTime modifiedDate) { - this.id = id; - this.ask = ask; - this.content = content; - this.createdDate = createdDate; - this.modifiedDate = modifiedDate; - } public static AnswerResponse of (Answer answer) { return AnswerResponse.builder() - .id(answer.getId()) - .ask(answer.getAsk()) + .answerId(answer.getId()) + .askId(answer.getAsk().getId()) .content(answer.getContent()) .createdDate(answer.getCreatedDate()) - .modifiedDate(answer.getModifiedDate()) .build(); } + public static List of(List answers){ + List answerResponseList = new ArrayList<>(); + for (Answer answer : answers) { + AnswerResponse answerResponse = AnswerResponse.of(answer); + answerResponseList.add(answerResponse); + } + return answerResponseList; + } } diff --git a/src/main/java/project/trendpick_pro/domain/answer/entity/form/AnswerForm.java b/src/main/java/project/trendpick_pro/domain/answer/entity/form/AnswerForm.java new file mode 100644 index 00000000..5065b454 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/answer/entity/form/AnswerForm.java @@ -0,0 +1,12 @@ +package project.trendpick_pro.domain.answer.entity.form; + +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class AnswerForm { + @NotBlank(message = "내용을 입력해주세요.") + private String content; +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java b/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java index b3e256dc..abc37e30 100644 --- a/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java +++ b/src/main/java/project/trendpick_pro/domain/answer/service/AnswerService.java @@ -6,6 +6,7 @@ import project.trendpick_pro.domain.answer.entity.Answer; import project.trendpick_pro.domain.answer.entity.dto.request.AnswerRequest; import project.trendpick_pro.domain.answer.entity.dto.response.AnswerResponse; +import project.trendpick_pro.domain.answer.entity.form.AnswerForm; import project.trendpick_pro.domain.answer.repository.AnswerRepository; import project.trendpick_pro.domain.ask.entity.Ask; import project.trendpick_pro.domain.ask.entity.dto.response.AskResponse; @@ -22,37 +23,24 @@ public class AnswerService { private final AskRepository askRepository; @Transactional - public void register(Long askId, Member member, AnswerRequest answerRequest) { - if(member.getRole() != RoleType.ADMIN) - throw new RuntimeException("답글을 달 수 있는 권한이 없습니다."); - + public void register(Long askId, AnswerForm answerForm) { Ask ask = askRepository.findById(askId).orElseThrow(); - - Answer answer = Answer.write(ask, answerRequest); - + Answer answer = Answer.write(ask, answerForm); answerRepository.save(answer); } @Transactional - public AnswerResponse delete(Member member, Long answerId) { - if(member.getRole() != RoleType.ADMIN) - throw new RuntimeException("답글을 달 수 있는 권한이 없습니다."); - + public AnswerResponse delete(Long answerId) { Answer answer = answerRepository.findById(answerId).orElseThrow(); - answerRepository.delete(answer); answer.getAsk().getAnswerList().remove(answer); return AnswerResponse.of(answer); } - public AnswerResponse modify(Member member, Long answerId, AnswerRequest answerRequest) { - if(member.getRole() != RoleType.ADMIN) - throw new RuntimeException("답글을 달 수 있는 권한이 없습니다."); - + public AnswerResponse modify(Long answerId, AnswerForm answerForm) { Answer answer = answerRepository.findById(answerId).orElseThrow(); - - answer.update(answerRequest); + answer.update(answerForm); return AnswerResponse.of(answer); } } diff --git a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java index 93533df4..4fa2ec9a 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java +++ b/src/main/java/project/trendpick_pro/domain/ask/controller/AskController.java @@ -6,6 +6,8 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; +import project.trendpick_pro.domain.answer.entity.form.AnswerForm; +import project.trendpick_pro.domain.ask.entity.dto.form.AskForm; import project.trendpick_pro.domain.ask.entity.dto.request.AskRequest; import project.trendpick_pro.domain.ask.entity.dto.response.AskResponse; import project.trendpick_pro.domain.ask.service.AskService; @@ -13,24 +15,38 @@ @Controller @RequiredArgsConstructor -@RequestMapping("trendpick/customerservice/asks") +@RequestMapping("/trendpick/customerservice/asks") public class AskController { private final AskService askService; private final Rq rq; - @GetMapping("/list") - public String showAsksByProduct(@RequestParam("page") int offset, @RequestParam("product") Long productId, Model model) { - model.addAttribute("askResponse", askService.showAsksByProduct(offset, productId)); + @PreAuthorize("isAuthenticated()") + @GetMapping("/register") + public String registerForm(@ModelAttribute AskForm askForm, Model model) { + askForm.setProductId(1L); + model.addAttribute("askForm", askForm); + return "trendpick/customerservice/asks/register"; + } - return "trendpick/customerservice/asks/list"; + @PreAuthorize("isAuthenticated()") + @PostMapping("/register") + public String registerAsk(@Valid AskForm askForm) { + AskResponse askResponse = askService.register(rq.CheckMember().get(), askForm); + return "redirect:/trendpick/customerservice/asks/%s".formatted(askResponse.getAskId()); } - @GetMapping("/{askId}}") - public String showAsk(@PathVariable Long askId, Model model) { + @GetMapping("/{askId}") + public String showAsk(@PathVariable Long askId, AnswerForm answerForm, Model model) { model.addAttribute("askResponse", askService.show(askId)); return "trendpick/customerservice/asks/detail"; } + @GetMapping("/list") + public String showAsksByProduct(@RequestParam("page") int offset, @RequestParam("product") Long productId, Model model) { + model.addAttribute("askResponse", askService.showAsksByProduct(productId, offset)); + return "trendpick/customerservice/asks/list"; + } + @PreAuthorize("isAuthenticated()") @PostMapping("/delete/{askId}") public String deleteAsk(@PathVariable Long askId) { @@ -48,12 +64,4 @@ public String modifyAsk(@PathVariable Long askId, @Valid AskRequest askRequest, return "redirect:/trendpick/customerservice/asks/%s".formatted(askId); } - @PreAuthorize("isAuthenticated()") - @PostMapping("/register") - public String registerAsk(@RequestParam(value = "product") Long productId, @Valid AskRequest askRequest, Model model) { - AskResponse askResponse = askService.register(rq.getMember(), productId, askRequest); - - model.addAttribute("askResponse", askResponse); - return "redirect:/trendpick/customerservice/asks/%s".formatted(askResponse.getId()); - } } diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java b/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java index 5758a1e4..ff897347 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/Ask.java @@ -5,16 +5,12 @@ import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import org.springframework.data.annotation.CreatedDate; -import org.springframework.data.jpa.domain.support.AuditingEntityListener; import project.trendpick_pro.domain.answer.entity.Answer; +import project.trendpick_pro.domain.ask.entity.dto.form.AskForm; import project.trendpick_pro.domain.ask.entity.dto.request.AskRequest; import project.trendpick_pro.domain.common.base.BaseTimeEntity; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.List; @@ -40,19 +36,21 @@ public class Ask extends BaseTimeEntity { private String title; private String content; - private String state; + + @Enumerated(EnumType.STRING) + private AskStatus status; @OneToMany(mappedBy = "ask", cascade = CascadeType.ALL) @Builder.Default private List answerList = new ArrayList<>(); - public static Ask of(Member member, Product product, AskRequest askRequest) { + public static Ask of(Member member, Product product, AskForm askForm) { return Ask.builder() .author(member) .product(product) - .title(askRequest.getTitle()) - .content(askRequest.getTitle()) - .state("답변예정") + .title(askForm.getTitle()) + .content(askForm.getContent()) + .status(AskStatus.YET) .build() ; } diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/AskStatus.java b/src/main/java/project/trendpick_pro/domain/ask/entity/AskStatus.java new file mode 100644 index 00000000..ca1673fa --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/AskStatus.java @@ -0,0 +1,15 @@ +package project.trendpick_pro.domain.ask.entity; + +import lombok.Getter; + +@Getter +public enum AskStatus { + YET("YET"), + COMPLETED("COMPLETED"); + + private String value; + + AskStatus(String value) { + this.value = value; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/form/AskForm.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/form/AskForm.java new file mode 100644 index 00000000..02cbb556 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/form/AskForm.java @@ -0,0 +1,18 @@ +package project.trendpick_pro.domain.ask.entity.dto.form; + +import jakarta.validation.constraints.NotBlank; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class AskForm { + + private Long productId; + + @NotBlank + private String title; + + @NotBlank + private String content; +} diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/request/AskRequest.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/request/AskRequest.java index 56661e88..ad30c873 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/request/AskRequest.java +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/request/AskRequest.java @@ -3,8 +3,11 @@ import jakarta.validation.constraints.NotBlank; import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; @Getter +@Setter public class AskRequest { @NotBlank diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskByProductResponse.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskByProductResponse.java deleted file mode 100644 index a6bf146b..00000000 --- a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskByProductResponse.java +++ /dev/null @@ -1,27 +0,0 @@ -package project.trendpick_pro.domain.ask.entity.dto.response; - -import com.querydsl.core.annotations.QueryProjection; -import lombok.AccessLevel; -import lombok.Getter; -import lombok.NoArgsConstructor; -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - -@Getter -@NoArgsConstructor(access = AccessLevel.PROTECTED) -public class AskByProductResponse { - Long id; - String state; - String title; - String username; - String date; - - @QueryProjection - public AskByProductResponse(Long id, String state, String title, String username, LocalDateTime localDateTime) { - this.id = id; - this.state = state; - this.title = title; - this.username = username; - this.date = localDateTime.format(DateTimeFormatter.ofPattern("yyyy.MM.dd")); - } -} diff --git a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java index aa978ba1..5d258b12 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java +++ b/src/main/java/project/trendpick_pro/domain/ask/entity/dto/response/AskResponse.java @@ -1,11 +1,10 @@ package project.trendpick_pro.domain.ask.entity.dto.response; import com.querydsl.core.annotations.QueryProjection; -import lombok.AccessLevel; -import lombok.Builder; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; +import org.springframework.data.domain.Page; import project.trendpick_pro.domain.answer.entity.Answer; +import project.trendpick_pro.domain.answer.entity.dto.response.AnswerResponse; import project.trendpick_pro.domain.ask.entity.Ask; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; @@ -15,42 +14,36 @@ @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) +@Builder +@AllArgsConstructor public class AskResponse { - private Long id; - private Member author; - private Product product; + private Long askId; + private Long productId; + private String memberName; + private Long memberId; private String title; private String content; - private List answerList = new ArrayList<>(); + private String status; private LocalDateTime createdDate; - private LocalDateTime modifiedDate; - - - @Builder - @QueryProjection - public AskResponse(Long id, Member author, Product product, String title, String content, List answerList, LocalDateTime createdDate, LocalDateTime modifiedDate) { - this.id = id; - this.author = author; - this.product = product; - this.title = title; - this.content = content; - this.answerList = answerList; - this.createdDate = createdDate; - this.modifiedDate = modifiedDate; - } + private List answerList; public static AskResponse of (Ask ask) { return AskResponse.builder() - .id(ask.getId()) - .author(ask.getAuthor()) - .product(ask.getProduct()) + .askId(ask.getId()) + .memberName(ask.getAuthor().getUsername()) + .memberId(ask.getAuthor().getId()) + .productId(ask.getProduct().getId()) .title(ask.getTitle()) .content(ask.getContent()) - .answerList(ask.getAnswerList()) + .status(ask.getStatus().getValue()) .createdDate(ask.getCreatedDate()) - .modifiedDate(ask.getModifiedDate()) + .answerList(AnswerResponse.of(ask.getAnswerList())) .build(); } + public static Page of(Page asks){ + return asks.map(ask -> AskResponse.of(ask)); + } + } diff --git a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java index f55c7530..85844952 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java +++ b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepository.java @@ -1,9 +1,17 @@ package project.trendpick_pro.domain.ask.repository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; import project.trendpick_pro.domain.ask.entity.Ask; +import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.product.entity.Product; public interface AskRepository extends JpaRepository, AskRepositoryCustom { - + @Query("select a from Ask a where a.product.id = :productId") + Page findAllByProductId(Long productId, Pageable pageable); + @Query("select a from Ask a where a.author = :member") + Page findAllByMember(Member member, Pageable pageable); } diff --git a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryCustom.java index 68478c63..453d63da 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryCustom.java +++ b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryCustom.java @@ -1,14 +1,7 @@ package project.trendpick_pro.domain.ask.repository; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import project.trendpick_pro.domain.ask.entity.dto.request.AskByProductRequest; -import project.trendpick_pro.domain.ask.entity.dto.response.AskByProductResponse; -import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; -import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; - public interface AskRepositoryCustom { - public Page findAllByProduct(AskByProductRequest request, Pageable pageable); +// public Page findAllByProduct(AskByProductRequest request, Pageable pageable); } diff --git a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryImpl.java index 3a43805e..3acf0528 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/ask/repository/AskRepositoryImpl.java @@ -1,61 +1,61 @@ -package project.trendpick_pro.domain.ask.repository; - -import com.querydsl.core.types.dsl.BooleanExpression; -import com.querydsl.jpa.impl.JPAQuery; -import com.querydsl.jpa.impl.JPAQueryFactory; -import jakarta.persistence.EntityManager; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; -import org.springframework.data.support.PageableExecutionUtils; -import project.trendpick_pro.domain.ask.entity.QAsk; -import project.trendpick_pro.domain.ask.entity.dto.request.AskByProductRequest; -import project.trendpick_pro.domain.ask.entity.dto.response.AskByProductResponse; -import project.trendpick_pro.domain.ask.entity.dto.response.QAskByProductResponse; - -import java.util.List; - -import static project.trendpick_pro.domain.ask.entity.QAsk.ask; -import static project.trendpick_pro.domain.product.entity.QProduct.product; - -public class AskRepositoryImpl implements AskRepositoryCustom { - - private final JPAQueryFactory queryFactory; - - public AskRepositoryImpl(EntityManager em) { - this.queryFactory = new JPAQueryFactory(em); - } - - @Override - public Page findAllByProduct(AskByProductRequest request, Pageable pageable) { - List result = queryFactory - .select(new QAskByProductResponse( - ask.id, - ask.state, - ask.title, - ask.author.username, - ask.createdDate - )) - .from(ask) - .leftJoin(ask.product, product) - .where( - askByProductEq(request) - ) - .offset(0) - .limit(10) - .fetch(); - - JPAQuery count = queryFactory - .select(ask.count()) - .from(ask) - .leftJoin(ask.product, product) - .where( - askByProductEq(request) - ); - - return PageableExecutionUtils.getPage(result, pageable, count::fetchOne); - } - - private static BooleanExpression askByProductEq(AskByProductRequest request) { - return ask.product.id.eq(request.getProductId()); - } -} +//package project.trendpick_pro.domain.ask.repository; +// +//import com.querydsl.core.types.dsl.BooleanExpression; +//import com.querydsl.jpa.impl.JPAQuery; +//import com.querydsl.jpa.impl.JPAQueryFactory; +//import jakarta.persistence.EntityManager; +//import org.springframework.data.domain.Page; +//import org.springframework.data.domain.Pageable; +//import org.springframework.data.support.PageableExecutionUtils; +//import project.trendpick_pro.domain.ask.entity.QAsk; +//import project.trendpick_pro.domain.ask.entity.dto.request.AskByProductRequest; +//import project.trendpick_pro.domain.ask.entity.dto.response.AskByProductResponse; +//import project.trendpick_pro.domain.ask.entity.dto.response.QAskByProductResponse; +// +//import java.util.List; +// +//import static project.trendpick_pro.domain.ask.entity.QAsk.ask; +//import static project.trendpick_pro.domain.product.entity.QProduct.product; +// +//public class AskRepositoryImpl implements AskRepositoryCustom { +// +// private final JPAQueryFactory queryFactory; +// +// public AskRepositoryImpl(EntityManager em) { +// this.queryFactory = new JPAQueryFactory(em); +// } +// +// @Override +// public Page findAllByProduct(AskByProductRequest request, Pageable pageable) { +// List result = queryFactory +// .select(new QAskByProductResponse( +// ask.id, +// ask.state, +// ask.title, +// ask.author.username, +// ask.createdDate +// )) +// .from(ask) +// .leftJoin(ask.product, product) +// .where( +// askByProductEq(request) +// ) +// .offset(0) +// .limit(10) +// .fetch(); +// +// JPAQuery count = queryFactory +// .select(ask.count()) +// .from(ask) +// .leftJoin(ask.product, product) +// .where( +// askByProductEq(request) +// ); +// +// return PageableExecutionUtils.getPage(result, pageable, count::fetchOne); +// } +// +// private static BooleanExpression askByProductEq(AskByProductRequest request) { +// return ask.product.id.eq(request.getProductId()); +// } +//} diff --git a/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java b/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java index ed992014..f7a1fe19 100644 --- a/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java +++ b/src/main/java/project/trendpick_pro/domain/ask/service/AskService.java @@ -7,18 +7,14 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.ask.entity.Ask; -import project.trendpick_pro.domain.ask.entity.dto.request.AskByProductRequest; +import project.trendpick_pro.domain.ask.entity.dto.form.AskForm; import project.trendpick_pro.domain.ask.entity.dto.request.AskRequest; -import project.trendpick_pro.domain.ask.entity.dto.response.AskByProductResponse; import project.trendpick_pro.domain.ask.entity.dto.response.AskResponse; import project.trendpick_pro.domain.ask.repository.AskRepository; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; -import java.util.ArrayList; -import java.util.List; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor @@ -28,28 +24,20 @@ public class AskService { private final ProductRepository productRepository; //상품 상세에서 문의 내역 볼 때 - public Page showAsksByProduct(int offset, Long productId) { + public Page showAsksByProduct(Long productId, int offset) { Pageable pageable = PageRequest.of(offset, 10); - AskByProductRequest request = new AskByProductRequest(productId); - - Page responses = askRepository.findAllByProduct(request, pageable); - - return responses; + Page asks = askRepository.findAllByProductId(productId, pageable); + return AskResponse.of(asks); } - //마이페이지 나의 문의 내역 볼 때 -// public Page showAsksByMyPage(int offset, Long productId) { -// Pageable pageable = PageRequest.of(offset, 10); -// AskByProductRequest request = new AskByProductRequest(productId); -// -// Page responses = askRepository.findAllByProduct(request, pageable); -// -// return responses; -// } + public Page showAsksByMyPage(Member member, int offset) { + Pageable pageable = PageRequest.of(offset, 10); + Page asks = askRepository.findAllByMember(member, pageable); + return AskResponse.of(asks); + } public AskResponse show(Long askId) { Ask ask = askRepository.findById(askId).orElseThrow(); - return AskResponse.of(ask); } @@ -75,10 +63,9 @@ public AskResponse modify(Member member, Long askId, AskRequest askRequest) { } @Transactional - public AskResponse register(Member member, Long productId, AskRequest askRequest) { - Product product = productRepository.findById(productId).orElseThrow(); - - Ask ask = Ask.of(member, product, askRequest); + public AskResponse register(Member member, AskForm askForm) { + Product product = productRepository.findById(askForm.getProductId()).orElseThrow(); + Ask ask = Ask.of(member, product, askForm); askRepository.save(ask); return AskResponse.of(ask); From bbeb6ff78b16b7ab5e7e9d5700a50d2c780fe6a0 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 7 Jun 2023 17:06:44 +0900 Subject: [PATCH 193/367] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20=EB=AC=B8?= =?UTF-8?q?=EC=9D=98=EC=99=80=20=EB=8B=B5=EB=B3=80=20=ED=99=94=EB=A9=B4=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84=20(#125)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../customerservice/asks/detail.html | 48 +++++++++++++++++-- .../trendpick/customerservice/asks/list.html | 9 ++-- .../customerservice/asks/register.html | 26 ++++++++++ 3 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 src/main/resources/templates/trendpick/customerservice/asks/register.html diff --git a/src/main/resources/templates/trendpick/customerservice/asks/detail.html b/src/main/resources/templates/trendpick/customerservice/asks/detail.html index 97efd723..7a097d06 100644 --- a/src/main/resources/templates/trendpick/customerservice/asks/detail.html +++ b/src/main/resources/templates/trendpick/customerservice/asks/detail.html @@ -1,10 +1,52 @@ - + - Title + + + 문의내용 + - 문의내역 상세페이지 +

+
+
+
+
+
+
+ +
+
+
+
+
+ +
+
+
+ + + +
+
+
+
+
+
+
+
+
+
+ + +
+ + + +
+
\ No newline at end of file diff --git a/src/main/resources/templates/trendpick/customerservice/asks/list.html b/src/main/resources/templates/trendpick/customerservice/asks/list.html index 8ec0c3ac..c8e54020 100644 --- a/src/main/resources/templates/trendpick/customerservice/asks/list.html +++ b/src/main/resources/templates/trendpick/customerservice/asks/list.html @@ -1,10 +1,13 @@ - + - Title + + + 문의하기 + - 문의내역 + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/customerservice/asks/register.html b/src/main/resources/templates/trendpick/customerservice/asks/register.html new file mode 100644 index 00000000..89e4a17f --- /dev/null +++ b/src/main/resources/templates/trendpick/customerservice/asks/register.html @@ -0,0 +1,26 @@ + + + + + + + 문의하기 + + + +
문의등록
+
+ + +
+ + +
+
+ + +
+ +
+ + \ No newline at end of file From 62855e0e80a32bfade97bde6e41868d67a464969 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Wed, 7 Jun 2023 17:43:03 +0900 Subject: [PATCH 194/367] =?UTF-8?q?refactor:=20=EC=83=81=ED=92=88=EC=98=B5?= =?UTF-8?q?=EC=85=98=20size=20=EC=A0=9C=EA=B1=B0=20(#125)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/orders/entity/OrderItem.java | 8 ++----- .../entity/dto/response/OrderItemDto.java | 4 +--- .../entity/dto/response/OrderResponse.java | 4 +--- .../repository/OrderRepositoryImpl.java | 1 - .../global/basedata/BaseData.java | 24 +++++++++---------- .../templates/trendpick/orders/order.html | 2 -- .../trendpick/usr/member/orders.html | 2 -- 7 files changed, 16 insertions(+), 29 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java index 409b0a10..8a0ae02f 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java @@ -30,21 +30,17 @@ public class OrderItem { @Column(name = "count", nullable = false) private int count; - @Column(name = "size", nullable = false) - private String size; - - private OrderItem(Product product,String size, int orderPrice, int count) { + private OrderItem(Product product, int orderPrice, int count) { this.product = product; this.orderPrice = orderPrice; this.count = count; - this.size = size; product.removeStock(count); } public static OrderItem of(Product product, OrderItemDto orderItemDto) { - return new OrderItem(product, orderItemDto.getSize(), orderItemDto.getPrice(), orderItemDto.getCount()); + return new OrderItem(product, orderItemDto.getPrice(), orderItemDto.getCount()); } public void connectOrder(Order order) { diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java index 83b5e796..916ec48b 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java @@ -9,16 +9,14 @@ public class OrderItemDto { private Long productId; private String productName; - private String size; private int count; private int price; - public OrderItemDto(Product product, String size, int count) { + public OrderItemDto(Product product, int count) { this.productId = product.getId(); this.productName = product.getName(); this.price = product.getPrice(); this.count = count; - this.size = size; } public OrderItemDto() { diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java index b615347e..2b61e8f9 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java @@ -16,7 +16,6 @@ public class OrderResponse { private String productFilePath; private String brandName; private String productName; - private String size; private int count; private LocalDateTime orderDate; private int productPrice; @@ -25,12 +24,11 @@ public class OrderResponse { @Builder @QueryProjection - public OrderResponse(Long productId, String productFilePath, String brandName, String productName, String size, int count,int productPrice, LocalDateTime orderDate, String orderStatus, String deliveryStatus) { + public OrderResponse(Long productId, String productFilePath, String brandName, String productName, int count,int productPrice, LocalDateTime orderDate, String orderStatus, String deliveryStatus) { this.productId = productId; this.productFilePath = productFilePath; this.brandName = brandName; this.productName = productName; - this.size = size; this.count = count; this.productPrice = productPrice; this.orderDate = orderDate; diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java index ae1caa23..d65a86d0 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java @@ -35,7 +35,6 @@ public Page findAllByMember(OrderSearchCond orderSearchCond, Page orderItem.product.file.fileName, orderItem.product.brand.name, orderItem.product.name, - orderItem.size, orderItem.count, orderItem.orderPrice, orderItem.order.createdDate, diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index 19ad4dfc..20ad2d2c 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -137,7 +137,7 @@ public void run(String... args) { memberService.register(member2); //==상품데이터==// - for(int n=1; n<=10; n++) { + for (int n = 1; n <= 10; n++) { CommonFile mainFile = CommonFile.builder() .fileName("355d1034-90ac-420b-ae02-6656eeebd707.jpg") .build(); @@ -152,10 +152,10 @@ public void run(String... args) { Product product = Product .builder() - .name("멋쟁이 티셔츠"+n) - .description("이 상품은 멋쟁이 티셔츠입니다."+n) - .stock(50+n) - .price(20000+n) + .name("멋쟁이 티셔츠" + n) + .description("이 상품은 멋쟁이 티셔츠입니다." + n) + .stock(50 + n) + .price(20000 + n) .mainCategory(mainCategoryService.findByName("상의")) .subCategory(subCategoryService.findByName("반소매티셔츠")) .brand(brandService.findByName("나이키")) @@ -163,7 +163,7 @@ public void run(String... args) { .build(); Set tags = new LinkedHashSet<>(); // 상품에 포함시킬 태크 선택하여 저장 for (int i = 1; i <= 5; i++) { - TagName tagName = tagNameService.findById(Long.valueOf(i+n)); + TagName tagName = tagNameService.findById(Long.valueOf(i + n)); tags.add(new Tag(tagName.getName())); } product.addTag(tags); @@ -175,9 +175,9 @@ public void run(String... args) { MemberInfoDto memberInfo = new MemberInfoDto(findMember); List orderItems = new ArrayList<>(); - orderItems.add(new OrderItemDto(productRepository.findById(1L).get(), "M", 5)); - orderItems.add(new OrderItemDto(productRepository.findById(2L).get(), "L", 3)); - orderItems.add(new OrderItemDto(productRepository.findById(3L).get(), "S", 2)); + orderItems.add(new OrderItemDto(productRepository.findById(1L).get(), 5)); + orderItems.add(new OrderItemDto(productRepository.findById(2L).get(), 3)); + orderItems.add(new OrderItemDto(productRepository.findById(3L).get(), 2)); OrderForm orderForm = new OrderForm(memberInfo, orderItems); orderForm.setPaymentMethod("신용카드"); @@ -188,9 +188,9 @@ public void run(String... args) { MemberInfoDto memberInfo2 = new MemberInfoDto(findMember2); List orderItems2 = new ArrayList<>(); - orderItems2.add(new OrderItemDto(productRepository.findById(1L).get(), "M", 5)); - orderItems2.add(new OrderItemDto(productRepository.findById(2L).get(), "L", 3)); - orderItems2.add(new OrderItemDto(productRepository.findById(3L).get(), "S", 2)); + orderItems2.add(new OrderItemDto(productRepository.findById(1L).get(), 5)); + orderItems2.add(new OrderItemDto(productRepository.findById(2L).get(), 3)); + orderItems2.add(new OrderItemDto(productRepository.findById(3L).get(), 2)); OrderForm orderForm2 = new OrderForm(memberInfo2, orderItems2); orderForm2.setPaymentMethod("신용카드"); diff --git a/src/main/resources/templates/trendpick/orders/order.html b/src/main/resources/templates/trendpick/orders/order.html index 480c03e0..bc52aa15 100644 --- a/src/main/resources/templates/trendpick/orders/order.html +++ b/src/main/resources/templates/trendpick/orders/order.html @@ -22,14 +22,12 @@

주문 아이템 목록

비고 상품명 - 사이즈 수량 가격 - diff --git a/src/main/resources/templates/trendpick/usr/member/orders.html b/src/main/resources/templates/trendpick/usr/member/orders.html index e46c961c..a86edf46 100644 --- a/src/main/resources/templates/trendpick/usr/member/orders.html +++ b/src/main/resources/templates/trendpick/usr/member/orders.html @@ -15,7 +15,6 @@

주문 목록

브랜드명 상품이미지 상품명 - 사이즈 주문수량 주문금액 주문일시 @@ -30,7 +29,6 @@

주문 목록


- From 5f8d58832b7e3694a5f67d4906e54a48f3afbcfa Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Wed, 7 Jun 2023 18:28:45 +0900 Subject: [PATCH 195/367] =?UTF-8?q?refactor:=20=ED=95=9C=20=ED=99=94?= =?UTF-8?q?=EB=A9=B4=EC=97=90=20=EB=82=98=EC=98=A4=EB=8A=94=20=EB=A6=AC?= =?UTF-8?q?=EB=B7=B0=20=EA=B0=9C=EC=88=98=20=EC=88=98=EC=A0=95/=20grid=20?= =?UTF-8?q?=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 1 + .../domain/review/service/ReviewService.java | 2 + .../templates/trendpick/review/list.html | 55 ++++++++++++------- 3 files changed, 37 insertions(+), 21 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index f762d0a7..973a5671 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -100,6 +100,7 @@ public String showOwnReview(Pageable pageable, Model model){ String writer = rq.getMember().getUsername(); Page reviewResponses = reviewService.showOwnReview(writer, pageable); model.addAttribute("reviewResponses", reviewResponses); + model.addAttribute("currentUser", writer); return "/trendpick/review/list"; } } diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index fc966449..bd8e157b 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -105,12 +105,14 @@ public ReviewResponse modify(Long reviewId, ReviewSaveRequest reviewSaveRequest, @Transactional public Page showAll(Pageable pageable) { + pageable = PageRequest.of(pageable.getPageNumber(), 6); Page reviewPage = reviewRepository.findAll(pageable); return reviewPage.map(ReviewResponse::of); } @Transactional public Page showOwnReview(String writer, Pageable pageable) { + pageable = PageRequest.of(pageable.getPageNumber(), 6); Page reviewPage = reviewRepository.findByWriter(writer, pageable); return reviewPage.map(ReviewResponse::of); } diff --git a/src/main/resources/templates/trendpick/review/list.html b/src/main/resources/templates/trendpick/review/list.html index b35efe4a..0bf4bb19 100644 --- a/src/main/resources/templates/trendpick/review/list.html +++ b/src/main/resources/templates/trendpick/review/list.html @@ -15,30 +15,43 @@ - -
-
-
-
-
-

제목:

-

상품명:

-

평점:

- 수정하기 + + + + + +
+
+ Trend Pick +
+
+
+ +
+
+
+ +

상품명:

+

제목:

+

평점: /5

+ 수정하기 +
- +
-
-
- Previous - - - - Next -
+
+ Previous + + + + Next +
From 5d2dd58690755b9db9588d270f22adc600ea3a69 Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Wed, 7 Jun 2023 21:58:29 +0900 Subject: [PATCH 196/367] =?UTF-8?q?feat:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=20=EC=83=81=ED=92=88=20=EC=88=98=EB=9F=89=20=EB=B3=80?= =?UTF-8?q?=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cart/controller/CartController.java | 10 +++--- .../domain/cart/entity/Cart.java | 17 ++-------- .../domain/cart/entity/CartItem.java | 3 ++ .../cart/repository/CartItemRepository.java | 2 ++ .../domain/cart/service/CartService.java | 9 ++--- .../templates/trendpick/usr/cart/list.html | 33 +++++++++++++++++-- 6 files changed, 49 insertions(+), 25 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java index 49cdcdb7..7e05abfd 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java +++ b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java @@ -4,6 +4,7 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; +import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.ui.Model; import org.springframework.validation.BindingResult; @@ -76,12 +77,13 @@ public String removeItem(@PathVariable("memberId") Long memberId,@PathVariable(" return "redirect:/trendpick/usr/cart/list"; } + // 장바구니에서 수량 변경 @PreAuthorize("isAuthenticated()") @PostMapping("/update") - public String updateCartItemQuantity(@RequestParam("cartItemId") Long cartItemId, - @RequestParam("count") int count) { + public String updateCount(@RequestParam("cartItemId") Long cartItemId, + @RequestParam("count") int newCount) { Member member = rq.getMember(); - cartService.updateItemCount(member, cartItemId, count); - return "redirect:/trendpick/list"; + cartService.updateItemCount(cartItemId, newCount); + return "redirect:/trendpick/usr/cart/list"; } } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java index 74ffbe98..b8d97b2f 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/Cart.java @@ -6,8 +6,7 @@ import lombok.NoArgsConstructor; import lombok.Setter; import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.product.entity.Product; -import project.trendpick_pro.domain.product.entity.ProductOption; + import java.util.ArrayList; import java.util.List; @@ -75,17 +74,5 @@ private CartItem findCartItemById(Long cartItemId) { .findFirst() .orElse(null); } -/* - public void updateTotalCountAndPrice() { - if (cartItems.isEmpty()) { - totalPrice = 0; - totalCount = 0; - } else { - for (CartItem cartItem : cartItems) { - totalPrice += (cartItem.getProduct().getPrice() * cartItem.getCount()); - } - totalCount = cartItems.size(); - } - } - */ + } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java index 42a8aa15..7e53c7e8 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java @@ -48,4 +48,7 @@ public void addCount(int count){ this.count += count; } + public void update(int count){ + this.count=count; + } } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/repository/CartItemRepository.java b/src/main/java/project/trendpick_pro/domain/cart/repository/CartItemRepository.java index 32eee117..afcb0bb2 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/repository/CartItemRepository.java +++ b/src/main/java/project/trendpick_pro/domain/cart/repository/CartItemRepository.java @@ -5,4 +5,6 @@ public interface CartItemRepository extends JpaRepository { CartItem findByCartIdAndProductId(Long cartId, long ProductId); + + CartItem findByCartId(Long cartItemID); } diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index f9074a1a..ad9490c0 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -88,9 +88,11 @@ public void removeItemFromCart(Long cartItemId) { } // 상품의 수량 업데이트 - public void updateItemCount(Member member, Long cartItemId, int count) { - Cart cart = getCartByUser(member.getId()); - cart.updateItemCount(cartItemId, count); + @Transactional + public void updateItemCount(Long cartItemId, int count) { + CartItem cartItem = cartItemRepository.findById(cartItemId).orElse(null); + cartItem.update(count); + cartItemRepository.save(cartItem); } public Cart getCartByUser(Long memberId) { @@ -107,5 +109,4 @@ private Member CheckMember() { Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); return member; } - } \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/cart/list.html b/src/main/resources/templates/trendpick/usr/cart/list.html index 81a90ebc..71906d8d 100644 --- a/src/main/resources/templates/trendpick/usr/cart/list.html +++ b/src/main/resources/templates/trendpick/usr/cart/list.html @@ -22,13 +22,23 @@

장바구니

- + 1 - + +
+ +
+ + + +
+ +
+ 삭제 @@ -46,5 +56,24 @@

+ + \ No newline at end of file From d505052f562f2bb6371d9c1a7493d5d07771466e Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Wed, 7 Jun 2023 22:08:54 +0900 Subject: [PATCH 197/367] =?UTF-8?q?refactor:=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EC=98=B5=EC=85=98=20=EC=88=98=EB=9F=89=EC=9E=85=EB=A0=A5?= =?UTF-8?q?=EC=9C=BC=EB=A1=9C=20=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trendpick_pro/domain/cart/entity/CartItem.java | 9 +-------- .../cart/entity/dto/request/CartItemRequest.java | 6 ------ .../cart/entity/dto/response/CartItemResponse.java | 8 +------- .../domain/cart/service/CartService.java | 6 +----- .../resources/templates/trendpick/usr/cart/add.html | 12 ------------ .../resources/templates/trendpick/usr/cart/list.html | 6 ++---- 6 files changed, 5 insertions(+), 42 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java index 7e53c7e8..28ce0fe2 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java @@ -4,7 +4,6 @@ import lombok.*; import project.trendpick_pro.domain.cart.entity.dto.request.CartItemRequest; import project.trendpick_pro.domain.product.entity.Product; -import project.trendpick_pro.domain.product.entity.ProductOption; @Entity @Getter @@ -22,25 +21,19 @@ public class CartItem { @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "product_id") private Product product; - private String color; // 해당 상품 색상 - private String size; // 해당 상품 사이즈 private int count; // 해당 상품 수량 @Builder - public CartItem(Cart cart, Product product, String color, String size, int count) { + public CartItem(Cart cart, Product product, int count) { this.cart = cart; this.product = product; - this.color = color; - this.size = size; this.count = count; } public static CartItem of(Cart cart, Product product, CartItemRequest cartItemRequest){ return CartItem.builder() .cart(cart) .product(product) - .color(cartItemRequest.getColor()) - .size(cartItemRequest.getSize()) .count(cartItemRequest.getCount()) .build(); } diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java index 2e305ea5..f7199ba7 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java @@ -1,18 +1,12 @@ package project.trendpick_pro.domain.cart.entity.dto.request; import jakarta.validation.constraints.Min; -import jakarta.validation.constraints.NotBlank; import lombok.Getter; import lombok.Setter; @Getter @Setter public class CartItemRequest { - @NotBlank(message = "해당 상품의 색상을 입력해주세요.") - private String color; - - @NotBlank(message ="해당 상품의 사이즈를 입력해주세요.") - private String size; @Min(value=1,message = "한 개 이상 선택하세요.") private int count; diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java index 19b5e159..6cb6e49f 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartItemResponse.java @@ -13,24 +13,18 @@ @NoArgsConstructor(access = AccessLevel.PROTECTED) public class CartItemResponse { private Long id; - private String color; - private String size; private int count; @Builder @QueryProjection - public CartItemResponse(Long id, String color, String size, int count) { + public CartItemResponse(Long id, int count) { this.id = id; - this.color = color; - this.size = size; this.count = count; } public static CartItemResponse of(CartItem cartItem) { return CartItemResponse.builder() .id(cartItem.getId()) - .color(cartItem.getColor()) - .size(cartItem.getSize()) .count(cartItem.getCount()) .build(); } diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index ad9490c0..78a1dc7f 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -8,19 +8,16 @@ import project.trendpick_pro.domain.cart.entity.CartItem; import project.trendpick_pro.domain.cart.entity.dto.request.CartItemRequest; import project.trendpick_pro.domain.cart.entity.dto.response.CartItemResponse; -import project.trendpick_pro.domain.cart.entity.dto.response.CartResponse; import project.trendpick_pro.domain.cart.repository.CartItemRepository; import project.trendpick_pro.domain.cart.repository.CartRepository; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.product.entity.Product; -import project.trendpick_pro.domain.product.exception.ProductNotFoundException; -import project.trendpick_pro.domain.product.repository.ProductOptionRepository; import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; import project.trendpick_pro.domain.tags.tag.entity.type.TagType; -import project.trendpick_pro.domain.tags.tag.service.TagService; + import java.util.ArrayList; import java.util.List; @@ -33,7 +30,6 @@ public class CartService { private final CartRepository cartRepository; private final MemberRepository memberRepository; - private final ProductOptionRepository productOptionRepository; private final ProductRepository productRepository; private final CartItemRepository cartItemRepository; private final FavoriteTagService favoriteTagService; diff --git a/src/main/resources/templates/trendpick/usr/cart/add.html b/src/main/resources/templates/trendpick/usr/cart/add.html index 8d130fe4..0fbd87e0 100644 --- a/src/main/resources/templates/trendpick/usr/cart/add.html +++ b/src/main/resources/templates/trendpick/usr/cart/add.html @@ -9,23 +9,11 @@
-
- - -

-
-
- - -

-
-

-
diff --git a/src/main/resources/templates/trendpick/usr/cart/list.html b/src/main/resources/templates/trendpick/usr/cart/list.html index 71906d8d..639980aa 100644 --- a/src/main/resources/templates/trendpick/usr/cart/list.html +++ b/src/main/resources/templates/trendpick/usr/cart/list.html @@ -15,8 +15,7 @@

장바구니

번호 상품ID 상품명 - 색상 - 사이즈 + 가격 수량 삭제 @@ -26,8 +25,7 @@

장바구니

1 - - +
From e0b10d2706e420501e13990742aab75cd5354893 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 8 Jun 2023 00:09:52 +0900 Subject: [PATCH 198/367] =?UTF-8?q?feat:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=EC=97=90=EC=84=9C=20=EC=A3=BC=EB=AC=B8=EC=8B=9C=20?= =?UTF-8?q?=EC=A3=BC=EB=AC=B8=EC=B2=98=EB=A6=AC=20=EB=A1=9C=EC=A7=81=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84(#136)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/cart/service/CartService.java | 12 ++++++-- .../member/entity/dto/MemberInfoDto.java | 6 +++- .../orders/contoller/OrderController.java | 24 ++++++---------- ...rderSaveRequest.java => OrderRequest.java} | 8 ++---- .../entity/dto/response/OrderItemDto.java | 27 ++++++++++++------ .../domain/orders/service/OrderService.java | 28 +++++++++++++++---- .../global/basedata/BaseData.java | 13 +++++---- 7 files changed, 73 insertions(+), 45 deletions(-) rename src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/{OrderSaveRequest.java => OrderRequest.java} (57%) diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index 78a1dc7f..64a1bf45 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -17,12 +17,9 @@ import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; import project.trendpick_pro.domain.tags.tag.entity.type.TagType; - - import java.util.ArrayList; import java.util.List; - @Service @Transactional(readOnly = true) @RequiredArgsConstructor @@ -105,4 +102,13 @@ private Member CheckMember() { Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); return member; } + + public List findCartItems(List cartItemIdList) { + List cartItemList = new ArrayList<>(); + for (Long id : cartItemIdList) { + cartItemList.add(cartItemRepository.findById(id). + orElseThrow(() -> new IllegalArgumentException("장바구니에 존재하지 않는 품목입니다."))); + } + return cartItemList; + } } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java b/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java index 5375faf6..d99c9c34 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java @@ -12,7 +12,7 @@ public class MemberInfoDto { private String name; private String email; - public MemberInfoDto(Member member) { + public MemberInfoDto (Member member) { this.memberId = member.getId(); this.name = member.getUsername(); this.email = member.getEmail(); @@ -20,6 +20,10 @@ public MemberInfoDto(Member member) { this.address = member.getAddress(); } + public static MemberInfoDto of(Member member){ + return new MemberInfoDto(member); + } + private String phone; private String address; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 55420cfd..6938d133 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -41,27 +41,13 @@ public class OrderController { @GetMapping("/order") public String orderForm(@ModelAttribute OrderForm orderForm, Model model){ -// Member member = rq.CheckMember().get(); -// MemberInfoDto memberInfo = new MemberInfoDto(member.getId(), member.getUsername(), member.getEmail(), member.getPhoneNumber(), member.getAddress()); -// List orderItems = new ArrayList<>(); -// Product product1 = productRepository.findById(1L).get(); -// Product product2 = productRepository.findById(2L).get(); -// Product product3 = productRepository.findById(3L).get(); -// -// orderItems.add(new OrderItemDto(product1.getId(), product1.getName(),"M", 5, product1.getPrice())); -// orderItems.add(new OrderItemDto(product2.getId(), product2.getName(),"L", 1, product2.getPrice())); -// orderItems.add(new OrderItemDto(product3.getId(), product3.getName(), "L", 7, product3.getPrice())); -// orderForm = new OrderForm(memberInfo, orderItems); - - //상품 상세 또는 장바구니에서 OrderForm으로 데이터가 날라오게끔 model.addAttribute("orderForm", orderForm); - return "trendpick/orders/order"; } @PostMapping("/order") @ResponseBody - public synchronized String order(@ModelAttribute("orderForm") OrderForm orderForm) { + public synchronized String processOrder(@ModelAttribute("orderForm") OrderForm orderForm) { Member member = rq.CheckMember().get(); if(member.getId()!=orderForm.getMemberInfo().getMemberId()) throw new RuntimeException("잘못된 접근입니다."); @@ -70,6 +56,14 @@ public synchronized String order(@ModelAttribute("orderForm") OrderForm orderFor return "redirect:/trendpick/orders/list"; } + @GetMapping("/cart") + public String cartToOrder(@RequestParam("selectedItems") List selectedItems, Model model){ + model.addAttribute("orderForm" + ,orderService.cartToOrder(rq.CheckMember().get(), selectedItems)); + + return "redirect:/trendpick/orders/order"; + } + @PreAuthorize("isAuthenticated()") @GetMapping("/list") diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSaveRequest.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderRequest.java similarity index 57% rename from src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSaveRequest.java rename to src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderRequest.java index d5ede146..84adcc6a 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSaveRequest.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderRequest.java @@ -6,14 +6,10 @@ @Getter @AllArgsConstructor -public class OrderSaveRequest { +public class OrderRequest { private Long productId; @NotBlank(message = "수량을 입력해주세요.") - private int quantity; - private String color; // 해당 상품 색상 - - private String size; // 해당 상품 사이즈 - private int count; // 해당 상품 수량 + private int count; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java index 916ec48b..c57d0255 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java @@ -1,25 +1,34 @@ package project.trendpick_pro.domain.orders.entity.dto.response; -import lombok.Getter; -import lombok.Setter; +import lombok.*; +import project.trendpick_pro.domain.cart.entity.Cart; +import project.trendpick_pro.domain.cart.entity.CartItem; +import project.trendpick_pro.domain.cart.entity.dto.request.CartItemRequest; import project.trendpick_pro.domain.product.entity.Product; @Getter @Setter +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class OrderItemDto { private Long productId; private String productName; private int count; private int price; - public OrderItemDto(Product product, int count) { - this.productId = product.getId(); - this.productName = product.getName(); - this.price = product.getPrice(); - this.count = count; + public static OrderItemDto of(Product product, int count) { + return OrderItemDto.builder() + .productId(product.getId()) + .productName(product.getName()) + .price(product.getPrice()) + .count(count) + .build(); } - - public OrderItemDto() { + @Builder + public OrderItemDto(Long productId, String productName, int price, int count) { + this.productId = productId; + this.productName = productName; + this.price = price; + this.count = count; } public int getTotalPrice(){ diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index a333011d..37c2e42b 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -7,19 +7,21 @@ import org.springframework.data.domain.PageRequest; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import project.trendpick_pro.domain.cart.entity.Cart; +import project.trendpick_pro.domain.cart.entity.CartItem; +import project.trendpick_pro.domain.cart.service.CartService; import project.trendpick_pro.domain.delivery.entity.Delivery; -import project.trendpick_pro.domain.delivery.entity.embaded.Address; +import project.trendpick_pro.domain.member.entity.dto.MemberInfoDto; +import project.trendpick_pro.domain.member.exception.MemberNotMatchException; import project.trendpick_pro.domain.orders.entity.dto.request.OrderForm; import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; import project.trendpick_pro.domain.member.entity.Member; -import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.repository.MemberRepository; import project.trendpick_pro.domain.orders.entity.Order; import project.trendpick_pro.domain.orders.entity.OrderItem; import project.trendpick_pro.domain.orders.entity.OrderStatus; -import project.trendpick_pro.domain.orders.entity.dto.request.OrderSaveRequest; import project.trendpick_pro.domain.orders.entity.dto.request.OrderSearchCond; import project.trendpick_pro.domain.product.exception.ProductStockOutException; import project.trendpick_pro.domain.orders.repository.OrderRepository; @@ -27,7 +29,6 @@ import project.trendpick_pro.domain.product.exception.ProductNotFoundException; import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tags.tag.entity.type.TagType; -import project.trendpick_pro.domain.tags.tag.service.TagService; import java.util.ArrayList; import java.util.List; @@ -37,7 +38,7 @@ @Transactional(readOnly = true) @RequiredArgsConstructor public class OrderService { - + private final CartService cartService; private final OrderRepository orderRepository; private final MemberRepository memberRepository; private final ProductRepository productRepository; @@ -73,5 +74,22 @@ public Page findAllByMember(Member member, int offset) { return orderRepository.findAllByMember(new OrderSearchCond(member.getId()), PageRequest.of(offset, 10)); } + public OrderForm cartToOrder(Member member, List selectedItems) { + List cartItems = cartService.findCartItems(selectedItems); + for (CartItem cartItem : cartItems) { + if(cartItem.getCart().getMember().getId() != member.getId()) + throw new MemberNotMatchException("현재 접속중인 사용자와 장바구니 사용자가 일치하지 않습니다."); + } + + return new OrderForm(MemberInfoDto.of(member) ,convertToOrderItemDto(cartItems)); + } + + private List convertToOrderItemDto(List cartItems) { + List orderItemDtoList = new ArrayList<>(); + for (CartItem cartItem : cartItems) { + orderItemDtoList.add(OrderItemDto.of(cartItem.getProduct(), cartItem.getCount())); + } + return orderItemDtoList; + } } diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index 20ad2d2c..76c07ae4 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -175,9 +175,9 @@ public void run(String... args) { MemberInfoDto memberInfo = new MemberInfoDto(findMember); List orderItems = new ArrayList<>(); - orderItems.add(new OrderItemDto(productRepository.findById(1L).get(), 5)); - orderItems.add(new OrderItemDto(productRepository.findById(2L).get(), 3)); - orderItems.add(new OrderItemDto(productRepository.findById(3L).get(), 2)); + orderItems.add(OrderItemDto.of(productRepository.findById(1L).get(), 5)); + orderItems.add(OrderItemDto.of(productRepository.findById(2L).get(), 3)); + orderItems.add(OrderItemDto.of(productRepository.findById(3L).get(), 2)); OrderForm orderForm = new OrderForm(memberInfo, orderItems); orderForm.setPaymentMethod("신용카드"); @@ -188,9 +188,10 @@ public void run(String... args) { MemberInfoDto memberInfo2 = new MemberInfoDto(findMember2); List orderItems2 = new ArrayList<>(); - orderItems2.add(new OrderItemDto(productRepository.findById(1L).get(), 5)); - orderItems2.add(new OrderItemDto(productRepository.findById(2L).get(), 3)); - orderItems2.add(new OrderItemDto(productRepository.findById(3L).get(), 2)); + orderItems2.add(OrderItemDto.of(productRepository.findById(1L).get(), 5)); + orderItems2.add(OrderItemDto.of(productRepository.findById(2L).get(), 3)); + orderItems2.add(OrderItemDto.of(productRepository.findById(3L).get(), 2)); + OrderForm orderForm2 = new OrderForm(memberInfo2, orderItems2); orderForm2.setPaymentMethod("신용카드"); From 2bf1c2233a17d7aa2f1b49ca485b3e331e307135 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 8 Jun 2023 00:18:27 +0900 Subject: [PATCH 199/367] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=EC=83=81?= =?UTF-8?q?=EC=84=B8=EC=97=90=EC=84=9C=20=EC=A3=BC=EB=AC=B8=EC=8B=9C=20?= =?UTF-8?q?=EC=A3=BC=EB=AC=B8=20=EC=B2=98=EB=A6=AC=20=EB=A1=9C=EC=A7=81(#1?= =?UTF-8?q?36)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/orders/contoller/OrderController.java | 6 ++++++ .../trendpick_pro/domain/orders/service/OrderService.java | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 6938d133..02389d2b 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -64,6 +64,12 @@ public String cartToOrder(@RequestParam("selectedItems") List selectedIte return "redirect:/trendpick/orders/order"; } + @GetMapping("/order/product") + public String orderProduct(@RequestParam("product") Long productId, + @RequestParam("count") int count, Model model){ + model.addAttribute("orderForm", orderService.productToOrder(rq.CheckMember().get(), productId, count)); + return "redirect:/trendpick/orders/order"; + } @PreAuthorize("isAuthenticated()") @GetMapping("/list") diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 37c2e42b..e4c0b7d1 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -32,6 +32,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; @Slf4j @Service @@ -92,4 +93,11 @@ private List convertToOrderItemDto(List cartItems) { return orderItemDtoList; } + public OrderForm productToOrder(Member member, Long productId, int count) { + Product product = productRepository.findById(productId) + .orElseThrow(() -> new ProductNotFoundException("존재하지 않는 상품입니다.")); + List orderItemDtoList = new ArrayList<>(); + orderItemDtoList.add(OrderItemDto.of(product, count)); + return new OrderForm(MemberInfoDto.of(member), orderItemDtoList); + } } From dacd09e8858b934ab0c7ebaedf8cc59b38dd4fa0 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 8 Jun 2023 02:22:12 +0900 Subject: [PATCH 200/367] =?UTF-8?q?feat:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=EC=97=90=EC=84=9C=20=EC=A3=BC=EB=AC=B8=EC=8B=9C=20?= =?UTF-8?q?=EC=A3=BC=EB=AC=B8=EC=B2=98=EB=A6=AC=20=EC=84=B1=EA=B3=B5(#136)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cart/controller/CartController.java | 2 +- .../entity/dto/request/CartItemRequest.java | 3 +- .../domain/cart/service/CartService.java | 3 +- .../member/entity/dto/MemberInfoDto.java | 5 +- .../orders/contoller/OrderController.java | 36 ++++-- .../entity/dto/response/OrderItemDto.java | 2 +- .../global/basedata/BaseData.java | 10 +- .../templates/trendpick/usr/cart/list.html | 106 +++++++++++------- 8 files changed, 107 insertions(+), 60 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java index 7e05abfd..2927a969 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java +++ b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java @@ -59,7 +59,7 @@ public String addItemToCart(@PathVariable("productId") Long productId, CartItemR @PreAuthorize("isAuthenticated()") @PostMapping("/add") public String addItem(Long productId, @ModelAttribute @Valid CartItemRequest cartItemRequests, Model model) { - CartItemResponse cartItemResponse = cartService.addItemToCart(productId, cartItemRequests); + CartItemResponse cartItemResponse = cartService.addItemToCart(rq.CheckMember().get(), productId, cartItemRequests); model.addAttribute("cartItemResponse", cartItemResponse); // System.out.println(cartItemRequests.getCount()); // System.out.println(cartItemRequests.getColor()); diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java index f7199ba7..cf420f0d 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java @@ -1,13 +1,14 @@ package project.trendpick_pro.domain.cart.entity.dto.request; import jakarta.validation.constraints.Min; +import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; @Getter @Setter +@AllArgsConstructor public class CartItemRequest { @Min(value=1,message = "한 개 이상 선택하세요.") private int count; - } diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index 64a1bf45..5102d05f 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -47,8 +47,7 @@ public List CartView(Cart cart) { // 장바구니 상품 추가 @Transactional - public CartItemResponse addItemToCart(Long productId, CartItemRequest cartItemRequest) { - Member member = CheckMember(); + public CartItemResponse addItemToCart(Member member, Long productId, CartItemRequest cartItemRequest) { Cart cart = cartRepository.findByMemberId(member.getId()); Product product = getProductById(productId); diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java b/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java index d99c9c34..ab08cb63 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java @@ -1,17 +1,18 @@ package project.trendpick_pro.domain.member.entity.dto; -import lombok.Getter; -import lombok.NoArgsConstructor; +import lombok.*; import project.trendpick_pro.domain.member.entity.Member; @Getter @NoArgsConstructor +@Setter public class MemberInfoDto { private Long memberId; private String name; private String email; + @Builder public MemberInfoDto (Member member) { this.memberId = member.getId(); this.name = member.getUsername(); diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 02389d2b..cad895c2 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -1,5 +1,6 @@ package project.trendpick_pro.domain.orders.contoller; +import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -8,6 +9,8 @@ import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; +import org.springframework.web.servlet.support.RequestContextUtils; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.dto.MemberInfoDto; @@ -25,6 +28,7 @@ import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Map; import java.util.Optional; @@ -40,42 +44,54 @@ public class OrderController { private final ProductRepository productRepository; @GetMapping("/order") - public String orderForm(@ModelAttribute OrderForm orderForm, Model model){ + public String orderForm(@RequestParam("orderForm") OrderForm orderForm, + HttpServletRequest req, + Model model) { +// Map flashMap = RequestContextUtils.getInputFlashMap(req); +// if (flashMap != null) { +// orderForm = (OrderForm) flashMap.get("orderForm"); +// model.addAttribute("orderForm", orderForm); +// } model.addAttribute("orderForm", orderForm); return "trendpick/orders/order"; } @PostMapping("/order") - @ResponseBody public synchronized String processOrder(@ModelAttribute("orderForm") OrderForm orderForm) { Member member = rq.CheckMember().get(); - if(member.getId()!=orderForm.getMemberInfo().getMemberId()) + log.info(member.getUsername()); + log.info(orderForm.getMemberInfo().getName()); + log.info(orderForm.getMemberInfo().getAddress()); + log.info(orderForm.getMemberInfo().getEmail()); + log.info(orderForm.getPaymentMethod()); + log.info(orderForm.getOrderItems().get(0).getProductName()); + if (member.getId() != orderForm.getMemberInfo().getMemberId()) throw new RuntimeException("잘못된 접근입니다."); orderService.order(member, orderForm); return "redirect:/trendpick/orders/list"; } - @GetMapping("/cart") - public String cartToOrder(@RequestParam("selectedItems") List selectedItems, Model model){ + @PostMapping("/cart") + public String cartToOrder(@RequestParam("selectedItems") List selectedItems, Model model) { model.addAttribute("orderForm" - ,orderService.cartToOrder(rq.CheckMember().get(), selectedItems)); + , orderService.cartToOrder(rq.CheckMember().get(), selectedItems)); - return "redirect:/trendpick/orders/order"; + return "trendpick/orders/order"; } @GetMapping("/order/product") public String orderProduct(@RequestParam("product") Long productId, - @RequestParam("count") int count, Model model){ + @RequestParam("count") int count, Model model) { model.addAttribute("orderForm", orderService.productToOrder(rq.CheckMember().get(), productId, count)); - return "redirect:/trendpick/orders/order"; + return "trendpick/orders/order"; } @PreAuthorize("isAuthenticated()") @GetMapping("/list") public String orderListByMember( @RequestParam(value = "page", defaultValue = "0") int offset, - Model model) { + Model model) { model.addAttribute("orderList", orderService.findAllByMember(rq.CheckMember().get(), offset)); return "trendpick/usr/member/orders"; diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java index c57d0255..e1c15c51 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderItemDto.java @@ -8,7 +8,7 @@ @Getter @Setter -@NoArgsConstructor(access = AccessLevel.PROTECTED) +@NoArgsConstructor public class OrderItemDto { private Long productId; private String productName; diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index 76c07ae4..db06dbe0 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -8,6 +8,8 @@ import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.brand.service.BrandService; +import project.trendpick_pro.domain.cart.entity.dto.request.CartItemRequest; +import project.trendpick_pro.domain.cart.service.CartService; import project.trendpick_pro.domain.category.entity.MainCategory; import project.trendpick_pro.domain.category.service.MainCategoryService; import project.trendpick_pro.domain.category.service.SubCategoryService; @@ -76,7 +78,8 @@ CommandLineRunner initData( SubCategoryService subCategoryService, BrandService brandService, ProductRepository productRepository, - OrderService orderservice + OrderService orderservice, + CartService cartService ) { return new CommandLineRunner() { @Override @@ -169,6 +172,10 @@ public void run(String... args) { product.addTag(tags); productRepository.save(product); } + //==장바구니 데이터==// + cartService.addItemToCart(memberService.findByEmail("trendpick@naver.com").get(),1L, new CartItemRequest(5)); + cartService.addItemToCart(memberService.findByEmail("trendpick@naver.com").get(),2L, new CartItemRequest(3)); + cartService.addItemToCart(memberService.findByEmail("trendpick@naver.com").get(),3L, new CartItemRequest(1)); //==주문데이터==// Member findMember = memberService.findByEmail("hye_0000@naver.com").get(); @@ -192,7 +199,6 @@ public void run(String... args) { orderItems2.add(OrderItemDto.of(productRepository.findById(2L).get(), 3)); orderItems2.add(OrderItemDto.of(productRepository.findById(3L).get(), 2)); - OrderForm orderForm2 = new OrderForm(memberInfo2, orderItems2); orderForm2.setPaymentMethod("신용카드"); orderservice.order(findMember2, orderForm2); diff --git a/src/main/resources/templates/trendpick/usr/cart/list.html b/src/main/resources/templates/trendpick/usr/cart/list.html index 639980aa..6ff8039c 100644 --- a/src/main/resources/templates/trendpick/usr/cart/list.html +++ b/src/main/resources/templates/trendpick/usr/cart/list.html @@ -8,52 +8,57 @@

장바구니

- - - - - - - - - - - - - - - - - - - - - - -
번호상품ID상품명가격수량삭제
1 - - -
- - - + + + + + + + + + + + + + + + + + + + + + + + + +
번호상품ID상품명가격수량삭제
1 + + +
+ + + +
+ + +
삭제
+
+
+
+
+

총 결제금액

- - -
삭제
-
-
-
-
-

총 결제금액

-
-

-
+
-
+ \ No newline at end of file From 8af5d803ac81dfe9107d39cec144b78bc724a354 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 8 Jun 2023 02:28:45 +0900 Subject: [PATCH 201/367] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=8B=A4=EC=9D=B4?= =?UTF-8?q?=EB=A0=89=ED=8A=B8=EB=A5=BC=20=ED=86=B5=ED=95=B4=20=ED=95=9C=20?= =?UTF-8?q?url=EC=97=90=EC=84=9C=20=EC=A3=BC=EB=AC=B8=ED=8F=BC=EC=9D=84=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=ED=95=98=EB=8F=84=EB=A1=9D=20=EB=A6=AC?= =?UTF-8?q?=ED=8C=A9=ED=86=A0=EB=A7=81(#136)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orders/contoller/OrderController.java | 32 ++++++++----------- 1 file changed, 13 insertions(+), 19 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index cad895c2..64f0abb3 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -44,14 +44,14 @@ public class OrderController { private final ProductRepository productRepository; @GetMapping("/order") - public String orderForm(@RequestParam("orderForm") OrderForm orderForm, + public String orderForm(@ModelAttribute OrderForm orderForm, HttpServletRequest req, Model model) { -// Map flashMap = RequestContextUtils.getInputFlashMap(req); -// if (flashMap != null) { -// orderForm = (OrderForm) flashMap.get("orderForm"); -// model.addAttribute("orderForm", orderForm); -// } + Map flashMap = RequestContextUtils.getInputFlashMap(req); + if (flashMap != null) { + orderForm = (OrderForm) flashMap.get("orderForm"); + model.addAttribute("orderForm", orderForm); + } model.addAttribute("orderForm", orderForm); return "trendpick/orders/order"; } @@ -59,12 +59,6 @@ public String orderForm(@RequestParam("orderForm") OrderForm orderForm, @PostMapping("/order") public synchronized String processOrder(@ModelAttribute("orderForm") OrderForm orderForm) { Member member = rq.CheckMember().get(); - log.info(member.getUsername()); - log.info(orderForm.getMemberInfo().getName()); - log.info(orderForm.getMemberInfo().getAddress()); - log.info(orderForm.getMemberInfo().getEmail()); - log.info(orderForm.getPaymentMethod()); - log.info(orderForm.getOrderItems().get(0).getProductName()); if (member.getId() != orderForm.getMemberInfo().getMemberId()) throw new RuntimeException("잘못된 접근입니다."); @@ -73,18 +67,18 @@ public synchronized String processOrder(@ModelAttribute("orderForm") OrderForm o } @PostMapping("/cart") - public String cartToOrder(@RequestParam("selectedItems") List selectedItems, Model model) { - model.addAttribute("orderForm" - , orderService.cartToOrder(rq.CheckMember().get(), selectedItems)); + public String cartToOrder(@RequestParam("selectedItems") List selectedItems, RedirectAttributes redirect) { + redirect.addFlashAttribute("orderForm" + ,orderService.cartToOrder(rq.CheckMember().get(), selectedItems)); - return "trendpick/orders/order"; + return "redirect:/trendpick/orders/order"; } @GetMapping("/order/product") public String orderProduct(@RequestParam("product") Long productId, - @RequestParam("count") int count, Model model) { - model.addAttribute("orderForm", orderService.productToOrder(rq.CheckMember().get(), productId, count)); - return "trendpick/orders/order"; + @RequestParam("count") int count, RedirectAttributes redirect) { + redirect.addFlashAttribute("orderForm", orderService.productToOrder(rq.CheckMember().get(), productId, count)); + return "redirect:/trendpick/orders/order"; } @PreAuthorize("isAuthenticated()") From 56ef7dcfab395bbaa83a03ee446f71fe6ba1d460 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Thu, 8 Jun 2023 02:46:09 +0900 Subject: [PATCH 202/367] =?UTF-8?q?refactor:=20=ED=94=84=EB=A1=A0=ED=8A=B8?= =?UTF-8?q?=20=EC=9E=91=EC=97=85=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/common/base/rq/Rq.java | 98 +++++++++- .../member/controller/MemberController.java | 9 +- .../product/controller/ProductController.java | 15 +- .../entity/dto/request/ProductSearchCond.java | 7 +- .../entity/dto/response/ProductResponse.java | 4 +- .../repository/ProductRepositoryImpl.java | 2 +- .../product/service/ProductService.java | 6 +- .../recommend/service/RecommendService.java | 2 +- .../i18nConfig/CustomMessageSource.java | 51 +++++ .../global/i18nConfig/I18nConfig.java | 34 ++++ .../trendpick_pro/global/rsData/RsData.java | 36 ++++ .../global/security/SecurityConfig.java | 11 +- .../project/trendpick_pro/global/util/Ut.java | 178 +++++++++++++++++ src/main/resources/application-data.yml | 2 +- src/main/resources/messages.properties | 38 ++++ src/main/resources/messages_en.properties | 0 src/main/resources/messages_ko.properties | 26 +++ .../templates/trendpick/common/js.html | 19 ++ .../templates/trendpick/common/layout.html | 80 ++++++++ .../templates/trendpick/products/list.html | 45 +++-- .../trendpick/usr/layout/layout.html | 126 ++++++------ .../templates/trendpick/usr/member/join.html | 181 +++++++++++++----- .../templates/trendpick/usr/member/login.html | 79 ++++++-- 23 files changed, 874 insertions(+), 175 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/global/i18nConfig/CustomMessageSource.java create mode 100644 src/main/java/project/trendpick_pro/global/i18nConfig/I18nConfig.java create mode 100644 src/main/java/project/trendpick_pro/global/rsData/RsData.java create mode 100644 src/main/java/project/trendpick_pro/global/util/Ut.java create mode 100644 src/main/resources/messages.properties create mode 100644 src/main/resources/messages_en.properties create mode 100644 src/main/resources/messages_ko.properties create mode 100644 src/main/resources/templates/trendpick/common/js.html create mode 100644 src/main/resources/templates/trendpick/common/layout.html diff --git a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java index 06cce62f..58528fdd 100644 --- a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java +++ b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java @@ -4,31 +4,45 @@ import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import jakarta.servlet.http.HttpSession; +import org.springframework.context.MessageSource; +import org.springframework.data.domain.Page; import org.springframework.security.core.Authentication; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.User; import org.springframework.stereotype.Component; import org.springframework.web.context.annotation.RequestScope; +import org.springframework.web.servlet.LocaleResolver; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.entity.RoleType; import project.trendpick_pro.domain.member.exception.MemberNotFoundException; import project.trendpick_pro.domain.member.exception.MemberNotMatchException; import project.trendpick_pro.domain.member.service.MemberService; +import project.trendpick_pro.global.rsData.RsData; +import project.trendpick_pro.global.util.Ut; +import java.util.Date; +import java.util.Locale; +import java.util.Map; import java.util.Optional; @Component @RequestScope public class Rq { private final MemberService memberService; + private final MessageSource messageSource; + private final LocaleResolver localeResolver; + private Locale locale; private final HttpServletRequest req; private final HttpServletResponse resp; private final HttpSession session; private final User user; private Member member = null; // 레이지 로딩, 처음부터 넣지 않고, 요청이 들어올 때 넣는다. - public Rq(MemberService memberService, HttpServletRequest req, HttpServletResponse resp, HttpSession session) { + public Rq(MemberService memberService, MessageSource messageSource, LocaleResolver localeResolver, HttpServletRequest req, + HttpServletResponse resp, HttpSession session) { this.memberService = memberService; + this.messageSource = messageSource; + this.localeResolver = localeResolver; this.req = req; this.resp = resp; this.session = session; @@ -43,14 +57,57 @@ public Rq(MemberService memberService, HttpServletRequest req, HttpServletRespon } } - // 로그인 된 회원의 객체 + public String historyBack(String msg) { + String referer = req.getHeader("referer"); + String key = "historyBackErrorMsg___" + referer; + req.setAttribute("localStorageKeyAboutHistoryBackErrorMsg", key); + req.setAttribute("historyBackErrorMsg", msg); + // 200 이 아니라 400 으로 응답코드가 지정되도록 + resp.setStatus(HttpServletResponse.SC_BAD_REQUEST); + return "common/js"; + } + + // 뒤로가기 + 메세지 + public String historyBack(RsData rsData) { + return historyBack(rsData.getMsg()); + } + + // 302 + 메세지 + public String redirectWithMsg(String url, RsData rsData) { + return redirectWithMsg(url, rsData.getMsg()); + } + + // 302 + 메세지 + public String redirectWithMsg(String url, String msg) { + return "redirect:" + urlWithMsg(url, msg); + } + + private String urlWithMsg(String url, String msg) { + // 기존 URL에 혹시 msg 파라미터가 있다면 그것을 지우고 새로 넣는다. + return Ut.url.modifyQueryParam(url, "msg", msgWithTtl(msg)); + } + + private String msgWithTtl(String msg) { + return Ut.url.encode(msg) + ";ttl=" + new Date().getTime(); + } + + public boolean isLogin() { + return user != null; + } + + // 로그아웃 되어 있는지 체크 + public boolean isLogout() { + return !isLogin(); + } + public Member getMember() { + if (isLogout()) return null; // 데이터가 없는지 체크 if (member == null) { - member = memberService.findByEmail(SecurityContextHolder.getContext().getAuthentication().getName()) - .orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); + member = memberService.findByUsername(user.getUsername()).orElseThrow(); } + return member; } @@ -85,4 +142,37 @@ public Optional CheckLogin() { throw new MemberNotFoundException("존재하지 않는 회원입니다."); } } + + public void setSessionAttr(String name, String value) { + session.setAttribute(name, value); + } + + public T getSessionAttr(String name, T defaultValue) { + try { + return (T) session.getAttribute(name); + } catch (Exception ignored) { + } + + return defaultValue; + } + + public void removeSessionAttr(String name) { + session.removeAttribute(name); + } + + public String getCText(String code, String... args) { + return messageSource.getMessage(code, args, getLocale()); + } + + private Locale getLocale() { + if (locale == null) locale = localeResolver.resolveLocale(req); + + return locale; + } + + public String getParamsJsonStr() { + Map parameterMap = req.getParameterMap(); + + return Ut.json.toStr(parameterMap); + } } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java index 523d10b7..2a6ce24c 100644 --- a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java +++ b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java @@ -8,6 +8,7 @@ import org.springframework.ui.Model; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import project.trendpick_pro.domain.common.base.rq.Rq; @@ -38,11 +39,7 @@ public String register(JoinForm joinForm, Model model) { @PreAuthorize("isAnonymous()") @PostMapping("/register") - public String register(@Valid JoinForm joinForm, BindingResult bindingResult, Model model) { - if (bindingResult.hasErrors()) { - model.addAttribute("allTags", tagNameService.findAll()); - return "trendpick/usr/member/join"; - } + public String register(@ModelAttribute @Valid JoinForm joinForm) { memberService.register(joinForm); return "redirect:/trendpick/member/login"; } @@ -50,7 +47,7 @@ public String register(@Valid JoinForm joinForm, BindingResult bindingResult, Mo @PreAuthorize("isAnonymous()") @GetMapping("/login") public String login() { - return "/trendpick/usr/member/login"; + return "trendpick/usr/member/login"; } @PreAuthorize("isAuthenticated()") diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index aa57f14f..bde8dd5d 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -89,18 +89,25 @@ public String showProduct(@PathVariable Long productId, Model model) { public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") int offset, @RequestParam(value = "main-category") String mainCategory, @RequestParam(value = "sub-category", defaultValue = "전체") String subCategory, - @RequestParam(value = "sort", defaultValue = "1") Integer sortCode, Model model) { - if (mainCategory.equals("추천")) { + if (mainCategory.equals("recommend")) { + mainCategory = "추천"; + } else if (mainCategory.equals("top")) { + mainCategory = "상의"; + } if (mainCategory.equals("추천")) { Member member = rq.CheckLogin().orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); if (member.getRole().getValue().equals("MEMBER")) { + model.addAttribute("mainCategoryName", mainCategory); model.addAttribute("productResponses", recommendService.getFindAll(offset)); } else { - model.addAttribute("productResponses", productService.showAll(offset, mainCategory, subCategory, sortCode)); + model.addAttribute("mainCategoryName", mainCategory); + model.addAttribute("productResponses", productService.showAll(offset, mainCategory, subCategory)); } } else { - model.addAttribute("productResponses", productService.showAll(offset, mainCategory, subCategory, sortCode)); + model.addAttribute("mainCategoryName", mainCategory); + model.addAttribute("productResponses", productService.showAll(offset, mainCategory, subCategory)); } return "/trendpick/products/list"; } } +// @RequestParam(value = "sort", defaultValue = "1"), Integer sortCode \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSearchCond.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSearchCond.java index e53ef4ec..7de19ba8 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSearchCond.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSearchCond.java @@ -7,11 +7,16 @@ public class ProductSearchCond { private final String mainCategory; private final String subCategory; - private final Integer sortCode; + private Integer sortCode; public ProductSearchCond(String mainCategory, String subCategory, Integer sortCode) { this.mainCategory = mainCategory; this.subCategory = subCategory; this.sortCode = sortCode; } + + public ProductSearchCond(String mainCategory, String subCategory) { + this.mainCategory = mainCategory; + this.subCategory = subCategory; + } } diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java index 1c8bae12..49c2a83c 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java @@ -55,7 +55,7 @@ public static ProductResponse of (String filePath, Product product, String role) .subCategory(product.getSubCategory().getName()) .brand(product.getBrand().getName()) .description(product.getDescription()) - .mainFile(filePath + product.getFile().getFileName()) + .mainFile(product.getFile().getFileName()) .subFiles(subFiles(filePath, product.getFile().getChild())) .price(product.getPrice()) .stock(product.getStock()) @@ -68,7 +68,7 @@ private static List subFiles(String filePath, List subFiles) List tmpList = new ArrayList<>(); for (CommonFile subFile : subFiles) { - tmpList.add(filePath + subFile.getFileName()); + tmpList.add(subFile.getFileName()); } return tmpList; } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index b556214b..63d4907b 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -56,7 +56,7 @@ public Page findAllByCategoryId(ProductSearchCond cond, Pag ) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) - .orderBy(orderSelector(cond.getSortCode())) //정렬추가 +// .orderBy(orderSelector(cond.getSortCode())) //정렬추가 .fetch(); JPAQuery count = queryFactory diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 76b0120e..6c4f1b98 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -144,16 +144,16 @@ public ProductResponse show(Long productId) { } } - public Page showAll(int offset, String mainCategory, String subCategory, Integer sortCode) { + public Page showAll(int offset, String mainCategory, String subCategory) { //, Integer sortCode - ProductSearchCond cond = new ProductSearchCond(mainCategory, subCategory, sortCode); + ProductSearchCond cond = new ProductSearchCond(mainCategory, subCategory); PageRequest pageable = PageRequest.of(offset, 18); Page listResponses = productRepository.findAllByCategoryId(cond, pageable); List list = listResponses.getContent().stream() .peek(product -> { - String updatedMainFile = filePath + product.getMainFile(); + String updatedMainFile = product.getMainFile(); product.setMainFile(updatedMainFile); }).toList(); diff --git a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java index 185f1e3e..fb8c1c1d 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java @@ -63,7 +63,7 @@ public Page getFindAll(int offset){ List list = listResponses.getContent().stream() .peek(product -> { - String updatedMainFile = filePath + product.getMainFile(); + String updatedMainFile = product.getMainFile(); product.setMainFile(updatedMainFile); }).toList(); diff --git a/src/main/java/project/trendpick_pro/global/i18nConfig/CustomMessageSource.java b/src/main/java/project/trendpick_pro/global/i18nConfig/CustomMessageSource.java new file mode 100644 index 00000000..4f8e5416 --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/i18nConfig/CustomMessageSource.java @@ -0,0 +1,51 @@ +package project.trendpick_pro.global.i18nConfig; + +import org.springframework.cache.annotation.Cacheable; +import org.springframework.context.support.ResourceBundleMessageSource; +import org.springframework.stereotype.Component; + +import java.text.MessageFormat; +import java.util.Locale; +import java.util.Objects; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +@Component +public class CustomMessageSource extends ResourceBundleMessageSource { + private static final Pattern VARIABLE_PATTERN = Pattern.compile("\\$\\[\\[(.+?)\\]\\]"); + + @Override + protected String resolveCodeWithoutArguments(String code, Locale locale) { + if (!code.startsWith("c.")) return super.resolveCodeWithoutArguments(code, locale); + + return replaceVariablesToString(super.resolveCodeWithoutArguments(code, locale), locale); + } + + @Override + protected MessageFormat resolveCode(String code, Locale locale) { + if (!code.startsWith("c.")) return super.resolveCode(code, locale); + + return replaceVariables(Objects.requireNonNull(super.resolveCode(code, locale)), locale); + } + + @Cacheable(cacheNames = "translation", key = "#code + ',' + #locale") + public String replaceVariablesToString(String code, Locale locale) { + StringBuilder result = new StringBuilder(); + Matcher matcher = VARIABLE_PATTERN.matcher(code); + + while (matcher.find()) { + String variable = matcher.group(1); + String replacement = getMessage(variable, null, locale); + matcher.appendReplacement(result, replacement); + } + matcher.appendTail(result); + + return result.toString(); + } + + private MessageFormat replaceVariables(MessageFormat messageFormat, Locale locale) { + String message = messageFormat.toPattern(); + + return new MessageFormat(replaceVariablesToString(message, locale), locale); + } +} diff --git a/src/main/java/project/trendpick_pro/global/i18nConfig/I18nConfig.java b/src/main/java/project/trendpick_pro/global/i18nConfig/I18nConfig.java new file mode 100644 index 00000000..b9d81acf --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/i18nConfig/I18nConfig.java @@ -0,0 +1,34 @@ +package project.trendpick_pro.global.i18nConfig; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.context.support.ResourceBundleMessageSource; +import org.springframework.web.servlet.LocaleResolver; +import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver; + +import java.util.Locale; + +@Configuration +public class I18nConfig { + + @Autowired private CustomMessageSource customMessageSource; + + @Bean + public MessageSource messageSource() { + ResourceBundleMessageSource messageSource = customMessageSource; + messageSource.setBasename("messages"); + messageSource.setDefaultEncoding("UTF-8"); + messageSource.setCacheMillis(0); + return messageSource; + } + + @Bean + public LocaleResolver localeResolver() { + AcceptHeaderLocaleResolver acceptHeaderLocaleResolver = new AcceptHeaderLocaleResolver(); + acceptHeaderLocaleResolver.setDefaultLocale(Locale.US); + + return acceptHeaderLocaleResolver; + } +} diff --git a/src/main/java/project/trendpick_pro/global/rsData/RsData.java b/src/main/java/project/trendpick_pro/global/rsData/RsData.java new file mode 100644 index 00000000..e3c5fbad --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/rsData/RsData.java @@ -0,0 +1,36 @@ +package project.trendpick_pro.global.rsData; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class RsData { + private String resultCode; + private String msg; + private T data; + + public static RsData of(String resultCode, String msg, T data) { + return new RsData<>(resultCode, msg, data); + } + + public static RsData of(String resultCode, String msg) { + return of(resultCode, msg, null); + } + + public static RsData successOf(T data) { + return of("S-1", "성공", data); + } + + public static RsData failOf(T data) { + return of("F-1", "실패", data); + } + + public boolean isSuccess() { + return resultCode.startsWith("S-"); + } + + public boolean isFail() { + return !isSuccess(); + } +} diff --git a/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java b/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java index 62a2622c..20f936b2 100644 --- a/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java +++ b/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java @@ -21,11 +21,12 @@ public class SecurityConfig { // formLogin -> formLogin // .loginPage("/trendpick/member/login") // .loginProcessingUrl("/login_proc") -// .defaultSuccessUrl("/trendpick/products/list") +// .defaultSuccessUrl("/trendpick/products/list?main-category=추천") // ) // .logout( // logout -> logout // .logoutUrl("/trendpick/member/logout") +// .logoutSuccessUrl("/trendpick/products/list?main-category=상의") // ); // return http.build(); // } @@ -35,18 +36,18 @@ SecurityFilterChain filterChain(HttpSecurity http) throws Exception { http .csrf().disable() .authorizeHttpRequests() - .requestMatchers("/register").hasAnyAuthority("ADMIN", "BRAND_ADMIN") + .requestMatchers("/register").anonymous() .requestMatchers("/admin/**").hasRole("ADMIN") - .anyRequest().authenticated() + .anyRequest().permitAll() .and() .formLogin() .loginPage("/trendpick/member/login") - .loginProcessingUrl("/login_proc") - .defaultSuccessUrl("/trendpick/products/list") + .defaultSuccessUrl("/trendpick/products/list?main-category=recommend") .permitAll() .and() .logout() .logoutUrl("/trendpick/member/logout") + .logoutSuccessUrl("/trendpick/products/list?main-category=top") .permitAll(); return http.build(); } diff --git a/src/main/java/project/trendpick_pro/global/util/Ut.java b/src/main/java/project/trendpick_pro/global/util/Ut.java new file mode 100644 index 00000000..ea0c8db1 --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/util/Ut.java @@ -0,0 +1,178 @@ +package project.trendpick_pro.global.util; + +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; +import java.util.Arrays; +import java.util.Base64; +import java.util.Map; + +public class Ut { + public static class json { + + public static String toStr(Map map) { + try { + return new ObjectMapper().writeValueAsString(map); + } catch (JsonProcessingException e) { + throw new RuntimeException(e); + } + } + } + + ; + + public static class time { + public static String diffFormat1Human(LocalDateTime time1, LocalDateTime time2) { + String suffix = time1.isAfter(time2) ? "전" : "후"; + + // 두개의 시간의 차이를 초로 환산 + long diff = Math.abs(ChronoUnit.SECONDS.between(time1, time2)); + + long diffSeconds = diff % 60; // 초 부분만 + long diffMinutes = diff / (60) % 60; // 분 부분만 + long diffHours = diff / (60 * 60) % 24; // 시간 부분만 + long diffDays = diff / (60 * 60 * 24); // 나머지는 일 부분으로 + + StringBuilder sb = new StringBuilder(); + + if (diffDays > 0) sb.append(diffDays).append("일 "); + if (diffHours > 0) sb.append(diffHours).append("시간 "); + if (diffMinutes > 0) sb.append(diffMinutes).append("분 "); + if (diffSeconds > 0) sb.append(diffSeconds).append("초 "); + + if (sb.isEmpty()) sb.append("1초 "); + + return sb.append(suffix).toString(); + } + } + + public static class reflection { + public static boolean setFieldValue(Object o, String fieldName, Object value) { + Field field = null; + + try { + field = o.getClass().getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + return false; + } + + field.setAccessible(true); + + try { + field.set(o, value); + } catch (IllegalAccessException e) { + return false; + } + + return true; + } + + public static T getFieldValue(Object o, String fieldName, T defaultValue) { + Field field = null; + + try { + field = o.getClass().getDeclaredField(fieldName); + } catch (NoSuchFieldException e) { + return defaultValue; + } + + field.setAccessible(true); + + try { + return (T) field.get(o); + } catch (IllegalAccessException e) { + return defaultValue; + } + } + + public static T call(Object obj, String methodName, Object... args) { + try { + Class[] argTypes = Arrays.stream(args) + .map(Object::getClass) + .toArray(Class[]::new); + + Method method = obj.getClass().getDeclaredMethod(methodName, argTypes); + method.setAccessible(true); + return (T) method.invoke(obj, args); + } catch (InvocationTargetException | NoSuchMethodException | IllegalAccessException e) { + throw new RuntimeException(e); + } + } + + public static T callArr(Object obj, String methodName, Object... args) { + return call(obj, methodName, new Object[]{args}); + } + } + + public static class hash { + private static final MessageDigest md; + + static { + try { + md = MessageDigest.getInstance("SHA-256"); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } + + public static String sha256(String str) { + // Convert the input string to bytes and update the MessageDigest + byte[] inputBytes = str.getBytes(StandardCharsets.UTF_8); + byte[] hashBytes = md.digest(inputBytes); + + // Convert the hashed bytes to a Base64 encoded string + return Base64.getEncoder().encodeToString(hashBytes); + } + } + + public static class url { + public static String encode(String str) { + return URLEncoder.encode(str, StandardCharsets.UTF_8); + } + + public static String modifyQueryParam(String url, String paramName, String paramValue) { + url = deleteQueryParam(url, paramName); + url = addQueryParam(url, paramName, paramValue); + + return url; + } + + public static String addQueryParam(String url, String paramName, String paramValue) { + if (!url.contains("?")) { + url += "?"; + } + + if (!url.endsWith("?") && !url.endsWith("&")) { + url += "&"; + } + + url += paramName + "=" + paramValue; + + return url; + } + + private static String deleteQueryParam(String url, String paramName) { + int startPoint = url.indexOf(paramName + "="); + if (startPoint == -1) return url; + + int endPoint = url.substring(startPoint).indexOf("&"); + + if (endPoint == -1) { + return url.substring(0, startPoint - 1); + } + + String urlAfter = url.substring(startPoint + endPoint + 1); + + return url.substring(0, startPoint) + urlAfter; + } + } +} diff --git a/src/main/resources/application-data.yml b/src/main/resources/application-data.yml index 1e27b12e..0a06ee1c 100644 --- a/src/main/resources/application-data.yml +++ b/src/main/resources/application-data.yml @@ -1,6 +1,6 @@ tag: 오버핏청바지, 시티보이룩, 스포티캐주얼, 빈티지룩, 프레피스타일, - 모던미니멀리스트, 로맨틱룩, 로커룩, 힙합룩, 데님스타일, + 미니멀리스트, 로맨틱룩, 로커룩, 힙합룩, 데님스타일, 스트릿패션, 빅사이즈룩, 오가닉패션, 애슬레저룩, 비즈니스캐주얼, 테일러드룩, 코지니트, 밀리터리룩, 고딕패션, 펑크룩, 레트로스타일, 베이직룩, 컬러풀패션, 모노톤스타일, 럭셔리룩, diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties new file mode 100644 index 00000000..45b85f0f --- /dev/null +++ b/src/main/resources/messages.properties @@ -0,0 +1,38 @@ +c.logoEmoji=💕 +c.logoTextStartEn=Trend +c.logoTextEndEn=Pick +c.logoTextStart=$[[c.logoTextStartEn]] +c.logoTextEnd=$[[c.logoTextEndEn]] +c.logoTextEn=$[[c.logoTextStartEn]]$[[c.logoTextEndEn]] +c.logoTextWithEmojiEn=$[[c.logoTextStartEn]]$[[c.logoTextEndEn]] +c.logoText=$[[c.logoTextStart]]$[[c.logoTextEnd]] +c.whatIsThisService=What is $[[c.logoTextWithEmojiEn]]? +c.iconStart= +c.iconAdmin= +c.iconPop= +c.iconLikesIReceived= +c.iconMyProfile= +c.iconGivingALike= +c.iconListOfLikes= +c.iconLinkingInstagram= +c.iconWhatIsThisService= +c.iconLogout= +c.pageNameStart=Start +c.pageNameAdmin=Admin +c.pageNamePop=My popularity +c.pageNameLikesIReceived=Likes I received +c.pageNameMyProfile=My profile +c.pageNameGivingALike=Giving a like +c.pageNameListOfLikes=List of likes +c.pageNameLinkingInstagram=Linking Instagram +c.pageNameLogout=Logout +c.loginFormUsername=Username +c.loginFormPassword=Password +c.startWithKakao=Start with Kakao +c.startWithGoogle=Start with Google +c.startWithFacebook=Start with Facebook +c.startWithNaver=Start with Naver +c.loginFormNeedInputUsername=Please enter your username. +c.loginFormNeedInputUsernameMoreThan=Please enter a username with at least {0} characters. +c.loginFormNeedInputPassword=Please enter your password. +c.loginFormNeedInputPasswordMoreThan=Please enter a password with at least {0} characters. \ No newline at end of file diff --git a/src/main/resources/messages_en.properties b/src/main/resources/messages_en.properties new file mode 100644 index 00000000..e69de29b diff --git a/src/main/resources/messages_ko.properties b/src/main/resources/messages_ko.properties new file mode 100644 index 00000000..a1222dda --- /dev/null +++ b/src/main/resources/messages_ko.properties @@ -0,0 +1,26 @@ +c.logoTextStartKo=트렌드 +c.logoTextEndKo=픽 +c.logoTextStart=$[[c.logoTextStartKo]] +c.logoTextEnd=$[[c.logoTextEndKo]] +c.logoTextWithEmojiKo=${c.logoTextStartKo} ${c.logoEmoji} ${c.logoTextEndKo} +c.whatIsThisService=$[[c.logoTextWithEmojiKo]]가 뭔가요? +c.pageNameStart=시작하기 +c.pageNameAdmin=관리자 +c.pageNamePop=내 인기 +c.pageNameLikesIReceived=내가 받은 호감 +c.pageNameMyProfile=내 정보 +c.pageNameGivingALike=호감표시 +c.pageNameListOfLikes=호감목록 +c.pageNamePullListOfLikes=호감 받은 목록 +c.pageNameLinkingInstagram=인스타 아이디 연결 +c.pageNameLogout=로그아웃 +c.loginFormUsername=아이디 +c.loginFormPassword=비밀번호 +c.startWithKakao=카카오로 시작하기 +c.startWithGoogle=구글로 시작하기 +c.startWithFacebook=페이스북으로 시작하기 +c.startWithNaver=네이버로 시작하기 +c.loginFormNeedInputUsername=아이디를 입력해주세요. +c.loginFormNeedInputUsernameMoreThan=아이디를 {0}자 이상 입력해주세요. +c.loginFormNeedInputPassword=비밀번호를 입력해주세요. +c.loginFormNeedInputPasswordMoreThan=비밀번호를 {0}자 이상 입력해주세요. \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/common/js.html b/src/main/resources/templates/trendpick/common/js.html new file mode 100644 index 00000000..91c2fc9c --- /dev/null +++ b/src/main/resources/templates/trendpick/common/js.html @@ -0,0 +1,19 @@ + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/common/layout.html b/src/main/resources/templates/trendpick/common/layout.html new file mode 100644 index 00000000..5e9d0f52 --- /dev/null +++ b/src/main/resources/templates/trendpick/common/layout.html @@ -0,0 +1,80 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ +
+
+ + + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/products/list.html b/src/main/resources/templates/trendpick/products/list.html index ecf6a0d2..e7273baa 100644 --- a/src/main/resources/templates/trendpick/products/list.html +++ b/src/main/resources/templates/trendpick/products/list.html @@ -1,29 +1,34 @@ - + - 상품 목록 + -
-
- -

- Product Image -
-

Brand:

-

Price:

+
+
+
+
+ Product Image +
+
+

+
Brand:
+
+
+ View More +
+
+
-
- -
- -
- Previous - - +
+
+ Previous + + - Next + Next +
-
+ diff --git a/src/main/resources/templates/trendpick/usr/layout/layout.html b/src/main/resources/templates/trendpick/usr/layout/layout.html index c1afbd7d..b56e9026 100644 --- a/src/main/resources/templates/trendpick/usr/layout/layout.html +++ b/src/main/resources/templates/trendpick/usr/layout/layout.html @@ -1,68 +1,82 @@ - - + + - - - - + - - - - - - + + + + + + TrendPick + - +
+ + + + + + + + + + + + +
+
- - \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/member/join.html b/src/main/resources/templates/trendpick/usr/member/join.html index 3bbd6d43..3c258b79 100644 --- a/src/main/resources/templates/trendpick/usr/member/join.html +++ b/src/main/resources/templates/trendpick/usr/member/join.html @@ -1,64 +1,139 @@ - - + 회원 가입 - - -
-

회원 가입

-

Error Message

-
-
- - -

-
-
- - -

-
-
- - -

-
-
- - -

-
-
- -
- +
+ + + +
+ +
+ +
-
- +
+ +
-
- +
+ +
-

-
- -
-

본인이 선호하는 태그를 선택 해주세요!

-
-
- - -
+
+ + +
+
+

+ 어떤 용도로 사용하시나요? +

+
+

+

+

+
+
+

+ 선호하는 태그를 선택 해주세요! +

+
+
+ + +
+
-

-
- - - - -
+ + + 이미 계정이 있나요? +
+
diff --git a/src/main/resources/templates/trendpick/usr/member/login.html b/src/main/resources/templates/trendpick/usr/member/login.html index f6449136..d7db706a 100644 --- a/src/main/resources/templates/trendpick/usr/member/login.html +++ b/src/main/resources/templates/trendpick/usr/member/login.html @@ -1,24 +1,67 @@ - - + 로그인 - - -
-

로그인

-
-
- - -
-
- - -
- -
-
+
+ + + +
+
+
+ + +
+
+ + +
+ +
+ 계정이 없으신가요? +
+
From ce1dd2931135353f7777f115d159ce0ce0818650 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Thu, 8 Jun 2023 03:07:52 +0900 Subject: [PATCH 203/367] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=ED=94=84=EB=A1=A0=ED=8A=B8=20=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/trendpick/review/detail.html | 54 +++++++++------ .../templates/trendpick/review/list.html | 68 +++++++++++++++---- .../templates/trendpick/review/modify.html | 2 +- .../templates/trendpick/review/register.html | 2 +- 4 files changed, 92 insertions(+), 34 deletions(-) diff --git a/src/main/resources/templates/trendpick/review/detail.html b/src/main/resources/templates/trendpick/review/detail.html index 9ae4d666..87fc2e44 100644 --- a/src/main/resources/templates/trendpick/review/detail.html +++ b/src/main/resources/templates/trendpick/review/detail.html @@ -6,31 +6,47 @@ 리뷰 상세 페이지 + + + + - -
-

제품명

-

작성자

- -
-
-
-
- 서브 이미지 -
+ +
+ Trend Pick +
+
+

제품명

+ +
+
+
+
+
+
+ +
+
+
-
-

제목

-

제목

+
+

작성자

+

-

내용

-

후기내용

-
+

별점

+

/5

- 수정하기 +

제목

+

+ +

내용

+

+
+
+
-
diff --git a/src/main/resources/templates/trendpick/review/list.html b/src/main/resources/templates/trendpick/review/list.html index 0bf4bb19..7ebb79ef 100644 --- a/src/main/resources/templates/trendpick/review/list.html +++ b/src/main/resources/templates/trendpick/review/list.html @@ -1,5 +1,5 @@ - + 리뷰 목록 - +
-
-
- Trend Pick +
+ +
@@ -32,15 +72,17 @@ 내 리뷰만 보기
-
+
- -

상품명:

-

제목:

-

평점: /5

- 수정하기 + + +

상품명:

+

제목:

+

평점: /5

+
+ 수정하기
@@ -53,5 +95,5 @@ Next
- + diff --git a/src/main/resources/templates/trendpick/review/modify.html b/src/main/resources/templates/trendpick/review/modify.html index 66255e90..a9507552 100644 --- a/src/main/resources/templates/trendpick/review/modify.html +++ b/src/main/resources/templates/trendpick/review/modify.html @@ -35,7 +35,7 @@ - +
diff --git a/src/main/resources/templates/trendpick/review/register.html b/src/main/resources/templates/trendpick/review/register.html index 5469dfe0..130fcc6d 100644 --- a/src/main/resources/templates/trendpick/review/register.html +++ b/src/main/resources/templates/trendpick/review/register.html @@ -34,7 +34,7 @@ - +
From 3d737db97b9c28d6b4252daa4b51da1d3ff0ce0c Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Thu, 8 Jun 2023 03:32:11 +0900 Subject: [PATCH 204/367] =?UTF-8?q?refactor:=20=ED=94=84=EB=A1=A0=ED=8A=B8?= =?UTF-8?q?=20=EC=9E=91=EC=97=85=20=EA=B0=9C=EC=84=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/basedata/BaseData.java | 25 ++++--- .../trendpick/products/detailpage.html | 72 +++++++++---------- .../templates/trendpick/products/list.html | 20 +++++- .../trendpick/usr/layout/layout.html | 14 ---- 4 files changed, 67 insertions(+), 64 deletions(-) diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index 20ad2d2c..5f9ea29b 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -41,32 +41,35 @@ @Profile({"dev", "test"}) public class BaseData { + @Value("${file.path}") + private String filePath; + @Value("${tag}") - List tags; + private List tags; @Value("${main-category}") - List mainCategories; + private List mainCategories; @Value("${top}") - List tops; + private List tops; @Value("${outer}") - List outers; + private List outers; @Value("${bottom}") - List bottoms; + private List bottoms; @Value("${shoes}") - List shoes; + private List shoes; @Value("${bag}") - List bags; + private List bags; @Value("${accessory}") - List accessories; + private List accessories; @Value("${brand}") - List brands; + private List brands; @Bean CommandLineRunner initData( @@ -139,11 +142,11 @@ public void run(String... args) { //==상품데이터==// for (int n = 1; n <= 10; n++) { CommonFile mainFile = CommonFile.builder() - .fileName("355d1034-90ac-420b-ae02-6656eeebd707.jpg") + .fileName("bamin.png") .build(); List subFiles = new ArrayList<>(); subFiles.add(CommonFile.builder() - .fileName("290ffec9-2da6-46dd-8779-86c27d48ef0c.jpg") + .fileName("dev-jeans.png") .build()); for (CommonFile subFile : subFiles) { diff --git a/src/main/resources/templates/trendpick/products/detailpage.html b/src/main/resources/templates/trendpick/products/detailpage.html index 086034cf..e51a4e95 100644 --- a/src/main/resources/templates/trendpick/products/detailpage.html +++ b/src/main/resources/templates/trendpick/products/detailpage.html @@ -1,46 +1,42 @@ - + - - - 상품 상세 페이지 - - + TrendPick - -
-

제품명

- -
-
- 메인 이미지 -
- 서브 이미지 + +
+
+
+
+ Product Image +
+ Sub Image +
+
+
+

+
Brand:
+

Product Description

+
    +
  • Main Category: Main Category
  • +
  • Sub Category: Sub Category
  • +
  • Brand: Brand
  • +
  • Price: Price
  • +
  • Stock: Stock
  • +
+
+ + +
+
+
- -
-

상품 설명

-

상품 설명

- -

상세 정보

-
    -
  • 메인 카테고리: 메인 카테고리
  • -
  • 서브 카테고리: 서브 카테고리
  • -
  • 브랜드: 브랜드
  • -
  • 가격: 가격
  • -
  • 재고: 재고
  • -
  • 태그: -
      -
    • 태그
    • -
    -
  • -
- - - -
-
+ diff --git a/src/main/resources/templates/trendpick/products/list.html b/src/main/resources/templates/trendpick/products/list.html index e7273baa..13fc86c0 100644 --- a/src/main/resources/templates/trendpick/products/list.html +++ b/src/main/resources/templates/trendpick/products/list.html @@ -1,14 +1,31 @@ - +
+ +
+
+ 새 상품 생성 +
+
Product Image +
+ +
+ +
+
+ + +
+

@@ -30,5 +47,6 @@

+ diff --git a/src/main/resources/templates/trendpick/usr/layout/layout.html b/src/main/resources/templates/trendpick/usr/layout/layout.html index b56e9026..e54cad5d 100644 --- a/src/main/resources/templates/trendpick/usr/layout/layout.html +++ b/src/main/resources/templates/trendpick/usr/layout/layout.html @@ -61,22 +61,8 @@

TrendPick

-
- - - - - - - - - - -
- -
\ No newline at end of file From 33cc3c05a19c7dd6e785df44960eb1ba51343a26 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Thu, 8 Jun 2023 09:21:39 +0900 Subject: [PATCH 205/367] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=ED=94=84=EB=A1=A0=ED=8A=B8=20=EC=9E=91=EC=97=85=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 17 +++-- .../templates/trendpick/review/list.html | 73 +++---------------- .../trendpick/usr/layout/layout.html | 2 + 3 files changed, 26 insertions(+), 66 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index 973a5671..ae6b784b 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -43,9 +43,10 @@ public String createReview(@Valid ReviewSaveRequest reviewCreateRequest, @RequestParam("mainFile") MultipartFile mainFile, @RequestParam("subFiles") List subFiles, @PathVariable("productId") Long productId, Model model) throws Exception { - Member member = rq.getMember(); + Optional member = rq.CheckLogin(); + Member checkMember = member.get(); - ReviewResponse reviewResponse = reviewService.createReview(member, productId, reviewCreateRequest, mainFile, subFiles); + ReviewResponse reviewResponse = reviewService.createReview(checkMember, productId, reviewCreateRequest, mainFile, subFiles); model.addAttribute("reviewResponse", reviewResponse); return "redirect:/trendpick/review/list"; @@ -55,7 +56,9 @@ public String createReview(@Valid ReviewSaveRequest reviewCreateRequest, @GetMapping("/{reviewId}") public String showReview(@PathVariable Long reviewId, Model model){ ReviewResponse reviewResponse = reviewService.showReview(reviewId); - String currentUser = rq.getMember().getUsername(); + Optional member = rq.CheckLogin(); + Member checkMember = member.get(); + String currentUser = checkMember.getUsername(); model.addAttribute("reviewResponse", reviewResponse); model.addAttribute("currentUser", currentUser); return "/trendpick/review/detail"; @@ -89,7 +92,9 @@ public String updateReview(@PathVariable Long reviewId, ReviewSaveRequest review @GetMapping("/list") public String showAllReview(Pageable pageable, Model model){ Page reviewResponses = reviewService.showAll(pageable); - String currentUser = rq.getMember().getUsername(); + Optional member = rq.CheckLogin(); + Member checkMember = member.get(); + String currentUser = checkMember.getUsername(); model.addAttribute("reviewResponses", reviewResponses); model.addAttribute("currentUser", currentUser); return "/trendpick/review/list"; @@ -97,7 +102,9 @@ public String showAllReview(Pageable pageable, Model model){ @GetMapping("/user") public String showOwnReview(Pageable pageable, Model model){ - String writer = rq.getMember().getUsername(); + Optional member = rq.CheckLogin(); + Member checkMember = member.get(); + String writer = checkMember.getUsername(); Page reviewResponses = reviewService.showOwnReview(writer, pageable); model.addAttribute("reviewResponses", reviewResponses); model.addAttribute("currentUser", writer); diff --git a/src/main/resources/templates/trendpick/review/list.html b/src/main/resources/templates/trendpick/review/list.html index 7ebb79ef..35246368 100644 --- a/src/main/resources/templates/trendpick/review/list.html +++ b/src/main/resources/templates/trendpick/review/list.html @@ -2,84 +2,35 @@ 리뷰 목록 + + -
- - - - - - diff --git a/src/main/resources/templates/trendpick/review/modify.html b/src/main/resources/templates/trendpick/review/modify.html index a9507552..f679a543 100644 --- a/src/main/resources/templates/trendpick/review/modify.html +++ b/src/main/resources/templates/trendpick/review/modify.html @@ -1,58 +1,59 @@ - - - - - - 리뷰 수정 - - - -
+ + + + + + 리뷰 수정 + + +
+
+ -
- - -
+
+ + +
-
- - -
+
+ + +
-
- - -
+
+ + +
-
- - -
+
+ + +
-
- - -
- - - - - +
+ + +
+ + +
+
\ No newline at end of file diff --git a/src/main/resources/templates/trendpick/review/register.html b/src/main/resources/templates/trendpick/review/register.html index 130fcc6d..7c1fc09d 100644 --- a/src/main/resources/templates/trendpick/review/register.html +++ b/src/main/resources/templates/trendpick/review/register.html @@ -1,56 +1,65 @@ - - - - - - 리뷰 등록 폼 - - - -
-
- - -
+ + + + + + 리뷰 등록 + + +
+
+ -
- - -
+
+ +
+ +
+
-
- - -
+
+ + +
-
- - -
+
+ + +
-
- - -
+
+ + +
- - - +
+ + +
+ + +
+
\ No newline at end of file From 9b1e267737586ce49b4ef335781cae3bcd3c4d97 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Thu, 8 Jun 2023 11:55:27 +0900 Subject: [PATCH 208/367] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=ED=94=84=EB=A1=A0=ED=8A=B8=20=EC=9D=B4=EB=AF=B8=EC=A7=80=20?= =?UTF-8?q?=ED=81=AC=EA=B8=B0=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/templates/trendpick/review/detail.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/trendpick/review/detail.html b/src/main/resources/templates/trendpick/review/detail.html index d2be2849..3cc5c4c9 100644 --- a/src/main/resources/templates/trendpick/review/detail.html +++ b/src/main/resources/templates/trendpick/review/detail.html @@ -36,7 +36,7 @@

내용

더 많은 후기 사진

- +
From f5691849ae39932643deb414540fa95c9f6bd2df Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Thu, 8 Jun 2023 11:56:10 +0900 Subject: [PATCH 209/367] =?UTF-8?q?fix:=20MySQL=EC=97=90=EC=84=9C=20@Lob?= =?UTF-8?q?=20=EC=96=B4=EB=85=B8=ED=85=8C=EC=9D=B4=EC=85=98=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20=EC=95=88=EB=90=98=EB=8A=94=20=EA=B2=83=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/project/trendpick_pro/domain/review/entity/Review.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java index 1caa1cba..1f3f61c7 100644 --- a/src/main/java/project/trendpick_pro/domain/review/entity/Review.java +++ b/src/main/java/project/trendpick_pro/domain/review/entity/Review.java @@ -36,7 +36,7 @@ public class Review extends BaseTimeEntity { private Product product; //Product private String title; - @Lob + @Column(columnDefinition = "LONGTEXT") private String content; private int rating; From 6ee81ce98fbd1d5ed473fd5790eb75b3098936ae Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Thu, 8 Jun 2023 13:36:46 +0900 Subject: [PATCH 210/367] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=ED=94=84=EB=A1=A0=ED=8A=B8=20=EC=A7=84=EC=A7=9C=20=EC=B5=9C?= =?UTF-8?q?=EC=A2=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/trendpick/review/detail.html | 24 ++++++++++++++++--- .../templates/trendpick/review/list.html | 23 +++++++++++++----- 2 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/main/resources/templates/trendpick/review/detail.html b/src/main/resources/templates/trendpick/review/detail.html index 3cc5c4c9..beaef420 100644 --- a/src/main/resources/templates/trendpick/review/detail.html +++ b/src/main/resources/templates/trendpick/review/detail.html @@ -2,11 +2,23 @@ 리뷰 상세 페이지 + +
+
@@ -22,7 +34,13 @@

작성자

별점

-

/5

+

+ + () +

+ +

제목

@@ -33,7 +51,7 @@

내용

-

더 많은 후기 사진

+

더 많은 후기 사진

diff --git a/src/main/resources/templates/trendpick/review/list.html b/src/main/resources/templates/trendpick/review/list.html index f24d41d7..85957b0e 100644 --- a/src/main/resources/templates/trendpick/review/list.html +++ b/src/main/resources/templates/trendpick/review/list.html @@ -9,6 +9,13 @@ grid-template-columns: repeat(3, 1fr); grid-gap: 10px; } + .star-icon { + color: gray; /* 비어있는 별 아이콘의 색상 */ + } + + .filled { + color: red; /* 채워진 별 아이콘의 색상 */ + }
@@ -18,18 +25,22 @@ 내 리뷰만 보기
-
From d83d776a7e3f4ab8010f9ca013492d6827ec2cb8 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Thu, 8 Jun 2023 13:48:56 +0900 Subject: [PATCH 211/367] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=ED=94=84=EB=A1=A0=ED=8A=B8=20=EC=A7=84=EC=A7=9C=20=EC=B5=9C?= =?UTF-8?q?=EC=A2=85/=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EC=83=81?= =?UTF-8?q?=EB=8B=A8=EC=97=90=20=EB=A6=AC=EB=B7=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/templates/trendpick/review/modify.html | 2 +- src/main/resources/templates/trendpick/review/register.html | 2 +- src/main/resources/templates/trendpick/usr/layout/layout.html | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/main/resources/templates/trendpick/review/modify.html b/src/main/resources/templates/trendpick/review/modify.html index f679a543..11619302 100644 --- a/src/main/resources/templates/trendpick/review/modify.html +++ b/src/main/resources/templates/trendpick/review/modify.html @@ -52,7 +52,7 @@
- +
diff --git a/src/main/resources/templates/trendpick/review/register.html b/src/main/resources/templates/trendpick/review/register.html index 7c1fc09d..33938ee1 100644 --- a/src/main/resources/templates/trendpick/review/register.html +++ b/src/main/resources/templates/trendpick/review/register.html @@ -58,7 +58,7 @@
- +
diff --git a/src/main/resources/templates/trendpick/usr/layout/layout.html b/src/main/resources/templates/trendpick/usr/layout/layout.html index 54af5092..83751260 100644 --- a/src/main/resources/templates/trendpick/usr/layout/layout.html +++ b/src/main/resources/templates/trendpick/usr/layout/layout.html @@ -36,6 +36,7 @@

TrendPick

  • 신발
  • 가방
  • 악세서리
  • +
  • 리뷰
  • - Add to Cart +
    + + + +
    - +
    Back to List @@ -41,20 +45,23 @@

    - diff --git a/src/main/resources/templates/trendpick/usr/cart/list.html b/src/main/resources/templates/trendpick/usr/cart/list.html index 6ff8039c..a3118e0c 100644 --- a/src/main/resources/templates/trendpick/usr/cart/list.html +++ b/src/main/resources/templates/trendpick/usr/cart/list.html @@ -34,7 +34,7 @@

    장바구니

    -
    diff --git a/src/main/resources/templates/trendpick/usr/layout/layout.html b/src/main/resources/templates/trendpick/usr/layout/layout.html index 54af5092..42589b23 100644 --- a/src/main/resources/templates/trendpick/usr/layout/layout.html +++ b/src/main/resources/templates/trendpick/usr/layout/layout.html @@ -55,7 +55,7 @@

    TrendPick

    + + +
    +
    +
    +
    + + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/cart/list.html b/src/main/resources/templates/trendpick/usr/cart/list.html index a3118e0c..be7c823a 100644 --- a/src/main/resources/templates/trendpick/usr/cart/list.html +++ b/src/main/resources/templates/trendpick/usr/cart/list.html @@ -1,5 +1,5 @@ - + 장바구니 From b74ad8851a6c07601872a1c3738aefe924afe34b Mon Sep 17 00:00:00 2001 From: mmun <62290451+mmunkyeong@users.noreply.github.com> Date: Thu, 8 Jun 2023 14:53:19 +0900 Subject: [PATCH 214/367] docs: .gitignore Modify --- .gitignore | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index d7d4f448..c4f58907 100644 --- a/.gitignore +++ b/.gitignore @@ -37,4 +37,7 @@ out/ .vscode/ ### secret yml ### -src/main/resources/application-secret.yml \ No newline at end of file +src/main/resources/application-secret.yml + +### generated ### +src/main/generated From 69a2cd3b9051a57643772891d6225409b8dcaf50 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Thu, 8 Jun 2023 16:31:12 +0900 Subject: [PATCH 215/367] =?UTF-8?q?refactor:=20=ED=95=84=EC=9A=94=EC=97=86?= =?UTF-8?q?=EB=8A=94=20=ED=8C=8C=EC=9D=BC=20=EC=A0=9C=EA=B1=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trendpick/review/layout/layout.html | 68 ------------------- 1 file changed, 68 deletions(-) delete mode 100644 src/main/resources/templates/trendpick/review/layout/layout.html diff --git a/src/main/resources/templates/trendpick/review/layout/layout.html b/src/main/resources/templates/trendpick/review/layout/layout.html deleted file mode 100644 index c1afbd7d..00000000 --- a/src/main/resources/templates/trendpick/review/layout/layout.html +++ /dev/null @@ -1,68 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - -
    - - - - \ No newline at end of file From 5e87c2c8923247c700a560a097f96d6098444820 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Thu, 8 Jun 2023 16:33:10 +0900 Subject: [PATCH 216/367] =?UTF-8?q?feat:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=20=EB=93=9C=EB=A1=AD=EB=8B=A4=EC=9A=B4=20?= =?UTF-8?q?=EB=A9=94=EB=89=B4=EB=A1=9C=20=EC=83=9D=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 주문목록 확인 가능 - 내 정보 확인 가능 - 계좌/배송지 등록 가능 --- .../member/controller/MemberController.java | 47 ++++++++++++---- .../member/entity/dto/MemberInfoDto.java | 5 ++ .../member/entity/form/AccountForm.java | 11 ++++ .../member/entity/form/AddressForm.java | 8 +++ .../domain/member/service/MemberService.java | 1 + .../trendpick/usr/layout/layout.html | 29 +++++++++- .../trendpick/usr/member/account.html | 56 +++++++++++++++++++ .../trendpick/usr/member/address.html | 41 +++++++++++++- .../templates/trendpick/usr/member/info.html | 19 ++++++- 9 files changed, 202 insertions(+), 15 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/member/entity/form/AccountForm.java create mode 100644 src/main/java/project/trendpick_pro/domain/member/entity/form/AddressForm.java create mode 100644 src/main/resources/templates/trendpick/usr/member/account.html diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java index 2a6ce24c..9f4322f5 100644 --- a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java +++ b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java @@ -13,11 +13,16 @@ import org.springframework.web.bind.annotation.RequestMapping; import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; +import project.trendpick_pro.domain.member.entity.dto.MemberInfoDto; +import project.trendpick_pro.domain.member.entity.form.AccountForm; +import project.trendpick_pro.domain.member.entity.form.AddressForm; import project.trendpick_pro.domain.member.entity.form.JoinForm; import project.trendpick_pro.domain.member.service.MemberService; import project.trendpick_pro.domain.tags.tag.service.TagService; import project.trendpick_pro.global.basedata.tagname.service.TagNameService; +import java.util.Optional; + @Slf4j @Controller @RequiredArgsConstructor @@ -52,25 +57,47 @@ public String login() { @PreAuthorize("isAuthenticated()") @GetMapping("/info") - public String showMe() { + public String showMe(Model model) { + Optional member = rq.CheckLogin(); + Member actor = member.get(); + model.addAttribute("MemberInfo", MemberInfoDto.of(actor)); return "trendpick/usr/member/info"; } @PreAuthorize("isAuthenticated()") - @PostMapping("/info/address-edit") - public String manageAddress(String address) { - Member actor = rq.getMember(); - memberService.manageAddress(actor, address); + @GetMapping("/info/address") + public String registerAddress(AddressForm addressForm, Model model) { + model.addAttribute("addressForm", addressForm); + return "trendpick/usr/member/address"; + } - return "trendpick/usr/member/info"; + @PreAuthorize("isAuthenticated()") + @PostMapping("/info/address") + public String manageAddress(@ModelAttribute @Valid AddressForm addressForm, Model model) { + Optional member = rq.CheckLogin(); + Member actor = member.get(); + memberService.manageAddress(actor, addressForm.address()); + model.addAttribute("MemberInfo", MemberInfoDto.of(actor)); + + + return "redirect:/trendpick/member/info"; + } + + @PreAuthorize("isAuthenticated()") + @GetMapping("/info/account") + public String registerAccount(AccountForm accountForm, Model model){ + model.addAttribute("accountForm", accountForm); + return "trendpick/usr/member/account"; } @PreAuthorize("isAuthenticated()") @PostMapping("/info/account") - public String manageAccount(String bank_name, String account) { - Member actor = rq.getMember(); - memberService.manageAccount(actor, bank_name, account); + public String manageAccount(@ModelAttribute @Valid AccountForm accountForm, Model model) { + Optional member = rq.CheckLogin(); + Member actor = member.get(); + memberService.manageAccount(actor, accountForm.bankName(), accountForm.bankAccount()); + model.addAttribute("MemberInfo", MemberInfoDto.of(actor)); - return "trendpick/usr/member/info"; + return "redirect:/trendpick/member/info"; } } diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java b/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java index ab08cb63..2ca4a1f4 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/dto/MemberInfoDto.java @@ -19,6 +19,8 @@ public MemberInfoDto (Member member) { this.email = member.getEmail(); this.phone = member.getPhoneNumber(); this.address = member.getAddress(); + this.bankName = member.getBankName(); + this.bankAccount = member.getBankAccount(); } public static MemberInfoDto of(Member member){ @@ -27,4 +29,7 @@ public static MemberInfoDto of(Member member){ private String phone; private String address; + + private String bankName; + private String bankAccount; } diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/form/AccountForm.java b/src/main/java/project/trendpick_pro/domain/member/entity/form/AccountForm.java new file mode 100644 index 00000000..2aabf7a2 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/member/entity/form/AccountForm.java @@ -0,0 +1,11 @@ +package project.trendpick_pro.domain.member.entity.form; + +import jakarta.validation.constraints.NotBlank; +import lombok.Builder; + +import java.util.List; + +@Builder +public record AccountForm(@NotBlank(message = "은행명을 입력해주세요.") String bankName, + @NotBlank(message = "계좌번호를 입력해주세요.") String bankAccount) { +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/form/AddressForm.java b/src/main/java/project/trendpick_pro/domain/member/entity/form/AddressForm.java new file mode 100644 index 00000000..14d2fc8a --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/member/entity/form/AddressForm.java @@ -0,0 +1,8 @@ +package project.trendpick_pro.domain.member.entity.form; + +import jakarta.validation.constraints.NotBlank; +import lombok.Builder; + +@Builder +public record AddressForm(@NotBlank(message = "주소를 입력해주세요.") String address) { +} \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java index 2642d366..2a1e8680 100644 --- a/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java +++ b/src/main/java/project/trendpick_pro/domain/member/service/MemberService.java @@ -101,6 +101,7 @@ public void manageAddress(Member actor, String address){ member.connectAddress(address); } + @Transactional public void manageAccount(Member actor, String bank_name, String account){ Member member = memberRepository.findByUsername(actor.getUsername()).orElseThrow(); member.connectBank(bank_name, account); diff --git a/src/main/resources/templates/trendpick/usr/layout/layout.html b/src/main/resources/templates/trendpick/usr/layout/layout.html index 83751260..e7e569b5 100644 --- a/src/main/resources/templates/trendpick/usr/layout/layout.html +++ b/src/main/resources/templates/trendpick/usr/layout/layout.html @@ -41,7 +41,6 @@

    TrendPick

    +
    diff --git a/src/main/resources/templates/trendpick/usr/member/account.html b/src/main/resources/templates/trendpick/usr/member/account.html new file mode 100644 index 00000000..7810de15 --- /dev/null +++ b/src/main/resources/templates/trendpick/usr/member/account.html @@ -0,0 +1,56 @@ + + + 계좌번호 관리 + + +
    + + + +
    + +
    + + +
    +
    + + +
    + + +
    +
    + + diff --git a/src/main/resources/templates/trendpick/usr/member/address.html b/src/main/resources/templates/trendpick/usr/member/address.html index ab1ed87b..d04be850 100644 --- a/src/main/resources/templates/trendpick/usr/member/address.html +++ b/src/main/resources/templates/trendpick/usr/member/address.html @@ -1,3 +1,40 @@ + + + 배송지 등록하기 + -
    배송지 정보
    - \ No newline at end of file +
    + + + +
    +
    +
    + + +
    + +
    +
    +
    + + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/member/info.html b/src/main/resources/templates/trendpick/usr/member/info.html index ff843e7a..123f7d66 100644 --- a/src/main/resources/templates/trendpick/usr/member/info.html +++ b/src/main/resources/templates/trendpick/usr/member/info.html @@ -1,3 +1,18 @@ + + + 계좌번호 관리 + -
    회원 정보
    - \ No newline at end of file +
    +
    +

    은행명:

    +
    +
    +

    계좌번호:

    +
    +
    +

    주소:

    +
    +
    + + From b83ba227124bd316d0a487a369a4ffd8739a5ef7 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 8 Jun 2023 16:34:02 +0900 Subject: [PATCH 217/367] =?UTF-8?q?feat:=20=EB=82=98=EC=9D=98=20=EC=A3=BC?= =?UTF-8?q?=EB=AC=B8=EB=AA=A9=EB=A1=9D=20=ED=8E=98=EC=9D=B4=EC=A7=80=20?= =?UTF-8?q?=EB=94=94=EC=9E=90=EC=9D=B8=20=EC=A0=81=EC=9A=A9(#141)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orders/contoller/OrderController.java | 9 +- .../entity/dto/response/OrderResponse.java | 9 +- .../repository/OrderRepositoryImpl.java | 2 +- .../trendpick/usr/member/orders.html | 126 +++++++++--------- 4 files changed, 81 insertions(+), 65 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 1ae72df4..f35f9383 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -86,8 +86,15 @@ public String orderProduct(@ModelAttribute ProductOptionForm productOptionForm, public String orderListByMember( @RequestParam(value = "page", defaultValue = "0") int offset, Model model) { + Page orderList = orderService.findAllByMember(rq.CheckMember().get(), offset); + int blockPage = 5; + int startPage = (offset / blockPage) * blockPage + 1; + int endPage = Math.min(startPage + blockPage - 1, orderList.getTotalPages()); + + model.addAttribute("orderList", orderList); + model.addAttribute("startPage", startPage); + model.addAttribute("endPage", endPage); - model.addAttribute("orderList", orderService.findAllByMember(rq.CheckMember().get(), offset)); return "trendpick/usr/member/orders"; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java index 2b61e8f9..46b4b836 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java @@ -6,12 +6,13 @@ import lombok.Getter; import lombok.NoArgsConstructor; +import java.text.NumberFormat; import java.time.LocalDateTime; +import java.util.Locale; @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class OrderResponse { - private Long productId; private String productFilePath; private String brandName; @@ -36,7 +37,9 @@ public OrderResponse(Long productId, String productFilePath, String brandName, S this.deliveryStatus = deliveryStatus; } - public int getTotalPrice(){ - return productPrice * count; + public String getTotalPrice(){ + int totalPrice = productPrice * count; + NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault()); + return numberFormat.format(totalPrice); } } diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java index d65a86d0..883f70a7 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java @@ -47,7 +47,7 @@ public Page findAllByMember(OrderSearchCond orderSearchCond, Page .on(member.id.eq(orderSearchCond.getMemberId())) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) - .orderBy(orderItem.order.createdDate.asc()) + .orderBy(orderItem.order.createdDate.desc()) .fetch(); JPAQuery countQuery = queryFactory diff --git a/src/main/resources/templates/trendpick/usr/member/orders.html b/src/main/resources/templates/trendpick/usr/member/orders.html index a86edf46..455a3167 100644 --- a/src/main/resources/templates/trendpick/usr/member/orders.html +++ b/src/main/resources/templates/trendpick/usr/member/orders.html @@ -1,68 +1,74 @@ - + 주문 목록 - -

    주문 목록

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    주문번호상품정보주문수량주문금액주문일시주문상태배송상태리뷰등록
    +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + 등록 + +
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    주문번호브랜드명상품이미지상품명주문수량주문금액주문일시주문상태배송상태리뷰

    - - 리뷰등록 - -
    - -
    - -
    - - - +
    +
    + Previous + + + + Next +
    +
    + +
    \ No newline at end of file From 353ecf387fbeb8f3b36f15fcad6f13fc3c01f11c Mon Sep 17 00:00:00 2001 From: jooooonj Date: Thu, 8 Jun 2023 18:22:19 +0900 Subject: [PATCH 218/367] =?UTF-8?q?refactor:=20=EC=A3=BC=EB=AC=B8=ED=8F=BC?= =?UTF-8?q?=20=EB=94=94=EC=9E=90=EC=9D=B8=20=EC=A0=81=EC=9A=A9(#141)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orders/contoller/OrderController.java | 8 +- .../orders/entity/dto/request/OrderForm.java | 14 +++ .../trendpick/orders/order-form.html | 113 ++++++++++++++++++ .../templates/trendpick/orders/order.html | 47 -------- .../trendpick/usr/member/orders.html | 5 +- 5 files changed, 133 insertions(+), 54 deletions(-) create mode 100644 src/main/resources/templates/trendpick/orders/order-form.html delete mode 100644 src/main/resources/templates/trendpick/orders/order.html diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index f35f9383..76ed94de 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -44,7 +44,7 @@ public class OrderController { private final MemberService memberService; private final ProductRepository productRepository; - @GetMapping("/order") + @GetMapping("/order-form") public String orderForm(@ModelAttribute OrderForm orderForm, HttpServletRequest req, Model model) { @@ -54,7 +54,7 @@ public String orderForm(@ModelAttribute OrderForm orderForm, model.addAttribute("orderForm", orderForm); } model.addAttribute("orderForm", orderForm); - return "trendpick/orders/order"; + return "trendpick/orders/order-form"; } @PostMapping("/order") @@ -72,13 +72,13 @@ public String cartToOrder(@RequestParam("selectedItems") List selectedItem redirect.addFlashAttribute("orderForm" ,orderService.cartToOrder(rq.CheckMember().get(), selectedItems)); - return "redirect:/trendpick/orders/order"; + return "redirect:/trendpick/orders/order-form"; } @PostMapping("/order/product") public String orderProduct(@ModelAttribute ProductOptionForm productOptionForm, RedirectAttributes redirect) { redirect.addFlashAttribute("orderForm", orderService.productToOrder(rq.CheckMember().get(), productOptionForm)); - return "redirect:/trendpick/orders/order"; + return "redirect:/trendpick/orders/order-form"; } @PreAuthorize("isAuthenticated()") diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java index 2614b1f5..08e0b1c8 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderForm.java @@ -7,22 +7,36 @@ import project.trendpick_pro.domain.orders.entity.OrderItem; import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; +import java.text.NumberFormat; import java.util.List; +import java.util.Locale; //주문서 @Getter @Setter public class OrderForm { + @NotBlank private MemberInfoDto memberInfo; + @NotBlank private List orderItems; + @NotBlank private String paymentMethod; + private int paymentPrice; public OrderForm(MemberInfoDto memberInfo, List orderItems) { this.memberInfo = memberInfo; this.orderItems = orderItems; + for (OrderItemDto orderItem : orderItems) { + this.paymentPrice += orderItem.getTotalPrice(); + } } public OrderForm() { } + + public String getFormattedPaymentPrice(){ + NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault()); + return numberFormat.format(paymentPrice) +"원"; + } } diff --git a/src/main/resources/templates/trendpick/orders/order-form.html b/src/main/resources/templates/trendpick/orders/order-form.html new file mode 100644 index 00000000..387855ee --- /dev/null +++ b/src/main/resources/templates/trendpick/orders/order-form.html @@ -0,0 +1,113 @@ + + + + + 주문 폼 + +
    + +

    주문서

    +
    +

    회원 정보

    +
    + + + + + + + + + + + + + + + + + + + + +
    회원 이름 + +
    이메일 + +
    번호 + +
    주소 + +
    +
    + +

    주문상품 정보

    +
    + + + + + + + + + + + + + + + + + + + +
    번호상품명주문수량주문금액
    1
    +
    + +

    결제 정보

    +
    + + + + + + + +
    결제 방법 +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    + + +
    +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    + +
    + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/orders/order.html b/src/main/resources/templates/trendpick/orders/order.html deleted file mode 100644 index bc52aa15..00000000 --- a/src/main/resources/templates/trendpick/orders/order.html +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - 주문 폼 - - - -

    주문서

    -

    회원 정보

    -
    -

    -

    회원 이름:

    -

    이메일:

    -

    번호:

    -

    주소:

    - -

    주문 아이템 목록

    - - - - - - - - - - - - - -
    비고상품명수량가격
    - -

    결제 수단 선택

    - - - -
    - - \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/member/orders.html b/src/main/resources/templates/trendpick/usr/member/orders.html index 455a3167..1057579f 100644 --- a/src/main/resources/templates/trendpick/usr/member/orders.html +++ b/src/main/resources/templates/trendpick/usr/member/orders.html @@ -3,7 +3,6 @@ 주문 목록 -
    @@ -11,7 +10,7 @@ 주문번호 - 상품정보 + 상품정보 주문수량 주문금액 주문일시 @@ -23,7 +22,7 @@ - +
    From 2d1f2ffa1bc72a0b881088d48131cdc360b2cae9 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Thu, 8 Jun 2023 19:54:21 +0900 Subject: [PATCH 219/367] =?UTF-8?q?refactor:=20=EB=A7=88=EC=9D=B4=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EC=A7=80=EC=97=90=20=EA=B3=84=EC=A2=8C=EC=A0=95?= =?UTF-8?q?=EB=B3=B4/=20=EC=A3=BC=EC=86=8C=20=ED=91=9C=EC=8B=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/trendpick/usr/member/info.html | 33 ++++++++++++++----- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/src/main/resources/templates/trendpick/usr/member/info.html b/src/main/resources/templates/trendpick/usr/member/info.html index 123f7d66..a078da13 100644 --- a/src/main/resources/templates/trendpick/usr/member/info.html +++ b/src/main/resources/templates/trendpick/usr/member/info.html @@ -3,15 +3,30 @@ 계좌번호 관리 -
    -
    -

    은행명:

    -
    -
    -

    계좌번호:

    -
    -
    -

    주소:

    +
    +
    +
    +
    +
    +

    회원님 반갑습니다!

    +
    +
    +
    + + + + + + + + + + + + + +
    은행명
    계좌번호
    주소
    +
    From c25c2cd3d96d2786cdc6377f01d1c93ee119d097 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Thu, 8 Jun 2023 20:08:20 +0900 Subject: [PATCH 220/367] =?UTF-8?q?feat:=20=EA=B3=84=EC=A2=8C=EC=A0=95?= =?UTF-8?q?=EB=B3=B4/=20=EC=A3=BC=EC=86=8C=20=EC=88=98=EC=A0=95=20?= =?UTF-8?q?=EA=B8=B0=EB=8A=A5=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../member/controller/MemberController.java | 37 +++++++++++++++++++ .../templates/trendpick/usr/member/info.html | 4 ++ 2 files changed, 41 insertions(+) diff --git a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java index 9f4322f5..9644e9c8 100644 --- a/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java +++ b/src/main/java/project/trendpick_pro/domain/member/controller/MemberController.java @@ -83,6 +83,24 @@ public String manageAddress(@ModelAttribute @Valid AddressForm addressForm, Mode return "redirect:/trendpick/member/info"; } + @PreAuthorize("isAuthenticated()") + @GetMapping("/edit/address") + public String editAddress(AddressForm addressForm, Model model) { + model.addAttribute("addressForm", addressForm); + return "trendpick/usr/member/address"; + } + + @PreAuthorize("isAuthenticated()") + @PostMapping("/edit/address") + public String updateAddress(@ModelAttribute @Valid AddressForm addressForm, Model model) { + Optional member = rq.CheckLogin(); + Member actor = member.get(); + memberService.manageAddress(actor, addressForm.address()); + model.addAttribute("MemberInfo", MemberInfoDto.of(actor)); + + return "redirect:/trendpick/member/info"; + } + @PreAuthorize("isAuthenticated()") @GetMapping("/info/account") public String registerAccount(AccountForm accountForm, Model model){ @@ -100,4 +118,23 @@ public String manageAccount(@ModelAttribute @Valid AccountForm accountForm, Mode return "redirect:/trendpick/member/info"; } + + @PreAuthorize("isAuthenticated()") + @GetMapping("/edit/account") + public String editAccount(AccountForm accountForm, Model model){ + model.addAttribute("accountForm", accountForm); + return "trendpick/usr/member/account"; + } + + @PreAuthorize("isAuthenticated()") + @PostMapping("/edit/account") + public String updateAccount(@ModelAttribute @Valid AccountForm accountForm, Model model) { + Optional member = rq.CheckLogin(); + Member actor = member.get(); + memberService.manageAccount(actor, accountForm.bankName(), accountForm.bankAccount()); + model.addAttribute("MemberInfo", MemberInfoDto.of(actor)); + + return "redirect:/trendpick/member/info"; + } + } diff --git a/src/main/resources/templates/trendpick/usr/member/info.html b/src/main/resources/templates/trendpick/usr/member/info.html index a078da13..167e061c 100644 --- a/src/main/resources/templates/trendpick/usr/member/info.html +++ b/src/main/resources/templates/trendpick/usr/member/info.html @@ -26,6 +26,10 @@ +
    From 60b693a07ff5080b01f18fd6545a74e78e8e01ee Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Thu, 8 Jun 2023 22:38:47 +0900 Subject: [PATCH 221/367] =?UTF-8?q?refactor:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=20=EB=A0=88=EC=9D=B4=EC=95=84=EC=9B=83=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9=20=EB=B0=8F=20=EC=A3=BC=EB=AC=B8=ED=8F=BC=20=EC=A0=84?= =?UTF-8?q?=EC=86=A1=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cart/controller/CartController.java | 5 +-- .../domain/cart/entity/CartItem.java | 2 +- .../trendpick/usr/cart/cartlayout.html | 14 +++---- .../templates/trendpick/usr/cart/list.html | 38 +++++++++---------- 4 files changed, 26 insertions(+), 33 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java index 7d4362ae..fe84822f 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java +++ b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java @@ -4,10 +4,8 @@ import jakarta.validation.Valid; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.http.ResponseEntity; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.ui.Model; -import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import org.springframework.stereotype.Controller; import project.trendpick_pro.domain.cart.entity.Cart; @@ -50,7 +48,6 @@ public String showCart(Model model) { @PreAuthorize("isAuthenticated()") @GetMapping("/add") public String addItemToCart(Long productId, CartItemRequest cartItemRequests, Model model) { - Member member = rq.getMember(); model.addAttribute("cartItemRequest", cartItemRequests); // 쇼핑을 계속 하시겠습니까? 띄우고 yes이면 main no면 cart로 return "/trendpick/usr/cart/add"; @@ -83,7 +80,7 @@ public String removeItem(@PathVariable("memberId") Long memberId, @PathVariable( @PostMapping("/update") public String updateCount(@RequestParam("cartItemId") Long cartItemId, @RequestParam("quantity") int newQuantity) { - Member member = rq.getMember(); + Member member = rq.CheckMember().get(); cartService.updateItemCount(cartItemId, newQuantity); return "redirect:/trendpick/usr/cart/list"; } diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java index ee17a7f3..3ecc9d37 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java @@ -41,7 +41,7 @@ public void addCount(int quantity){ this.quantity += quantity; } - public void update(int count){ + public void update(int quantity){ this.quantity=quantity; } } \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/cart/cartlayout.html b/src/main/resources/templates/trendpick/usr/cart/cartlayout.html index 732a2675..c9b986b0 100644 --- a/src/main/resources/templates/trendpick/usr/cart/cartlayout.html +++ b/src/main/resources/templates/trendpick/usr/cart/cartlayout.html @@ -44,18 +44,14 @@

    TrendPick

    - -
    + +
    +
    +
    + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/cart/list.html b/src/main/resources/templates/trendpick/usr/cart/list.html index be7c823a..30807cee 100644 --- a/src/main/resources/templates/trendpick/usr/cart/list.html +++ b/src/main/resources/templates/trendpick/usr/cart/list.html @@ -1,14 +1,12 @@ - + 장바구니 - -

    장바구니

    -
    +
    @@ -32,13 +30,11 @@

    장바구니

    - - - + +
    - - - + + + - + @@ -21,7 +21,11 @@ - + - @@ -54,11 +53,6 @@ -
    장바구니

    총 결제금액

    -

    - +
    + +

    + +
    - + \ No newline at end of file From 03c790de779afcadeb286ae477fc58bc13d206cf Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Thu, 8 Jun 2023 22:48:00 +0900 Subject: [PATCH 222/367] =?UTF-8?q?refactor:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=20=EC=A0=84=EC=B2=B4=20=EC=88=98=EB=9F=89=20=EC=97=85?= =?UTF-8?q?=EB=8D=B0=EC=9D=B4=ED=8A=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trendpick_pro/domain/cart/controller/CartController.java | 2 +- .../trendpick_pro/domain/cart/service/CartService.java | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java index fe84822f..ffd0e8f2 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java +++ b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java @@ -81,7 +81,7 @@ public String removeItem(@PathVariable("memberId") Long memberId, @PathVariable( public String updateCount(@RequestParam("cartItemId") Long cartItemId, @RequestParam("quantity") int newQuantity) { Member member = rq.CheckMember().get(); - cartService.updateItemCount(cartItemId, newQuantity); + cartService.updateItemCount(member,cartItemId, newQuantity); return "redirect:/trendpick/usr/cart/list"; } } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index ab2fd197..4d2d4a6f 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -86,8 +86,10 @@ public void removeItemFromCart(Long cartItemId) { // 상품의 수량 업데이트 @Transactional - public void updateItemCount(Long cartItemId, int quantity) { + public void updateItemCount(Member member,Long cartItemId, int quantity) { + Cart cart=member.getCart(); CartItem cartItem = cartItemRepository.findById(cartItemId).orElse(null); + cart.setTotalCount(cartItem.getQuantity()+quantity); cartItem.update(quantity); cartItemRepository.save(cartItem); } From 1e7805820fd25b999681a4fa74f18f23bec6ac6f Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Thu, 8 Jun 2023 22:59:14 +0900 Subject: [PATCH 223/367] =?UTF-8?q?refactor:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=20=EC=83=81=ED=92=88=EB=AA=85=20=ED=81=B4=EB=A6=AD?= =?UTF-8?q?=EC=8B=9C=20=EC=83=81=ED=92=88=EC=83=81=EC=84=B8=20=EC=9D=B4?= =?UTF-8?q?=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../resources/templates/trendpick/usr/cart/list.html | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/main/resources/templates/trendpick/usr/cart/list.html b/src/main/resources/templates/trendpick/usr/cart/list.html index 30807cee..726aa1c7 100644 --- a/src/main/resources/templates/trendpick/usr/cart/list.html +++ b/src/main/resources/templates/trendpick/usr/cart/list.html @@ -24,8 +24,12 @@
    1 + +
    @@ -51,7 +55,7 @@

    총 결제금액

    -

    +

    From 65e2387f6170f2087e514d47b5b206d75821dd74 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Thu, 8 Jun 2023 23:30:13 +0900 Subject: [PATCH 224/367] =?UTF-8?q?feat:=20=EC=83=81=ED=92=88=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=ED=8E=98=EC=9D=B4=EC=A7=80,=20=EC=B9=B4=ED=85=8C?= =?UTF-8?q?=EA=B3=A0=EB=A6=AC=20=EB=8F=99=EC=A0=81=20=ED=91=9C=EC=8B=9C=20?= =?UTF-8?q?=ED=99=94=EB=A9=B4=20=EC=B6=94=EA=B0=80=20(#150)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cart/controller/CartController.java | 18 ++- .../entity/dto/request/CartItemRequest.java | 3 + .../domain/cart/service/CartService.java | 4 +- .../controller/SubCategoryController.java | 23 +++ .../product/controller/ProductController.java | 33 +++- .../dto/request/ProductSaveRequest.java | 6 +- .../entity/dto/response/ProductResponse.java | 16 ++ .../product/service/ProductService.java | 14 +- .../controller/RecommendController.java | 3 + .../recommend/service/RecommendService.java | 17 ++ .../global/basedata/BaseData.java | 12 +- .../trendpick/products/detailpage.html | 26 ++-- .../templates/trendpick/products/list.html | 30 ++-- .../trendpick/products/register.html | 146 +++++++++--------- 14 files changed, 226 insertions(+), 125 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/category/controller/SubCategoryController.java diff --git a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java index ffd0e8f2..35324fde 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java +++ b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java @@ -24,11 +24,13 @@ @RequiredArgsConstructor @RequestMapping("/trendpick/usr/cart") public class CartController { + private final CartService cartService; private final MemberService memberService; + private final Rq rq; - @PreAuthorize("isAuthenticated()") + @PreAuthorize("hasAuthority('MEMBER')") @GetMapping("/list") public String showCart(Model model) { Member member = rq.CheckMember().get(); @@ -45,19 +47,19 @@ public String showCart(Model model) { return "/trendpick/usr/cart/list"; } - @PreAuthorize("isAuthenticated()") + @PreAuthorize("hasAuthority({'MEMBER'})") @GetMapping("/add") - public String addItemToCart(Long productId, CartItemRequest cartItemRequests, Model model) { + public String addItemToCart(CartItemRequest cartItemRequests, Model model) { model.addAttribute("cartItemRequest", cartItemRequests); // 쇼핑을 계속 하시겠습니까? 띄우고 yes이면 main no면 cart로 return "/trendpick/usr/cart/add"; } - @PreAuthorize("isAuthenticated()") + @PreAuthorize("hasAuthority({'MEMBER'})") @PostMapping("/add") - public String addItem(Long productId, @ModelAttribute @Valid CartItemRequest cartItemRequests, Model model) { - CartItemResponse cartItemResponse = cartService.addItemToCart(rq.CheckMember().get(), productId, cartItemRequests); + public String addItem(@ModelAttribute @Valid CartItemRequest cartItemRequests, Model model) { + CartItemResponse cartItemResponse = cartService.addItemToCart(rq.CheckMember().get(), cartItemRequests); model.addAttribute("cartItemResponse", cartItemResponse); // System.out.println(cartItemRequests.getCount()); // System.out.println(cartItemRequests.getColor()); @@ -66,7 +68,7 @@ public String addItem(Long productId, @ModelAttribute @Valid CartItemRequest car } - @PreAuthorize("isAuthenticated()") + @PreAuthorize("hasAuthority({'MEMBER'})") @GetMapping("{memberId}/{cartItemId}") public String removeItem(@PathVariable("memberId") Long memberId, @PathVariable("cartItemId") Long cartItemId) { Member member = memberService.findByMember(memberId); @@ -76,7 +78,7 @@ public String removeItem(@PathVariable("memberId") Long memberId, @PathVariable( } // 장바구니에서 수량 변경 - @PreAuthorize("isAuthenticated()") + @PreAuthorize("hasAuthority({'MEMBER'})") @PostMapping("/update") public String updateCount(@RequestParam("cartItemId") Long cartItemId, @RequestParam("quantity") int newQuantity) { diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java index fe7d78b4..f6f8daf2 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/request/CartItemRequest.java @@ -9,6 +9,9 @@ @Setter @AllArgsConstructor public class CartItemRequest { + + private Long productId; + @Min(value=1,message = "한 개 이상 선택하세요.") private int quantity; } diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index 4d2d4a6f..f35fd68e 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -52,9 +52,9 @@ public List CartView(Member member, Cart cart) { // 장바구니 상품 추가 @Transactional - public CartItemResponse addItemToCart(Member member, Long productId, CartItemRequest cartItemRequest) { + public CartItemResponse addItemToCart(Member member, CartItemRequest cartItemRequest) { Cart cart = cartRepository.findByMemberId(member.getId()); - Product product = getProductById(productId); + Product product = getProductById(cartItemRequest.getProductId()); if (cart == null) { // 장바구니가 비어있다면 생성 diff --git a/src/main/java/project/trendpick_pro/domain/category/controller/SubCategoryController.java b/src/main/java/project/trendpick_pro/domain/category/controller/SubCategoryController.java new file mode 100644 index 00000000..709a612d --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/category/controller/SubCategoryController.java @@ -0,0 +1,23 @@ +package project.trendpick_pro.domain.category.controller; + +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import project.trendpick_pro.domain.category.entity.SubCategory; +import project.trendpick_pro.domain.category.entity.dto.response.SubCategoryResponse; +import project.trendpick_pro.domain.category.service.SubCategoryService; + +import java.util.List; + +@Controller +@RequiredArgsConstructor +public class SubCategoryController { + + private final SubCategoryService subCategoryService; + + @GetMapping("/getSubCategories") + public List getSubCategories(@RequestParam String mainCategory) { + return subCategoryService.findAll(mainCategory); + } +} diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 268d7f6c..a1313613 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -9,6 +9,8 @@ import org.springframework.web.bind.annotation.*; import org.springframework.web.multipart.MultipartFile; import project.trendpick_pro.domain.brand.service.BrandService; +import project.trendpick_pro.domain.category.entity.dto.response.MainCategoryResponse; +import project.trendpick_pro.domain.category.entity.dto.response.SubCategoryResponse; import project.trendpick_pro.domain.category.service.MainCategoryService; import project.trendpick_pro.domain.category.service.SubCategoryService; import project.trendpick_pro.domain.common.base.rq.Rq; @@ -22,8 +24,7 @@ import project.trendpick_pro.global.basedata.tagname.service.TagNameService; import java.io.IOException; -import java.util.List; -import java.util.Optional; +import java.util.*; @Slf4j @Controller @@ -44,15 +45,23 @@ public class ProductController { @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") @GetMapping("/register") - public String registerProduct(ProductSaveRequest productSaveRequest, @RequestParam("main-category") String mainCategory, Model model) { - model.addAttribute("productSaveRequest", productSaveRequest); + public String registerProduct(@ModelAttribute("productSaveRequest") ProductSaveRequest productSaveRequest, Model model) { model.addAttribute("tags", tagNameService.findAll()); - model.addAttribute("mainCategories", mainCategoryService.findAll()); - model.addAttribute("subCategories", subCategoryService.findAll(mainCategory)); + + List MainCategories = mainCategoryService.findAll(); + model.addAttribute("mainCategories", MainCategories); + + Map> subCategoryList = new HashMap<>(); + for (MainCategoryResponse mainCategoryResponse : MainCategories) { + subCategoryList.put(mainCategoryResponse.getName(), subCategoryService.findAll(mainCategoryResponse.getName())); + } + + model.addAttribute("subCategoriesList", subCategoryList); model.addAttribute("brands", brandService.findAll()); return "/trendpick/products/register"; } + @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") @PostMapping("/register") public String register(@ModelAttribute @Valid ProductSaveRequest productSaveRequest, @@ -63,6 +72,13 @@ public String register(@ModelAttribute @Valid ProductSaveRequest productSaveRequ return "redirect:/trendpick/products/" + id; } + @GetMapping("/edit/{productId}") + public String modifyBefore(@PathVariable Long productId, @Valid ProductSaveRequest productSaveRequest, @RequestParam("mainFile") MultipartFile mainFile, + @RequestParam("subFiles") List subFiles) throws IOException { + Long id = productService.modify(productId, productSaveRequest, mainFile, subFiles); + return "redirect:/trendpick/products/" + id; + } + @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") @PostMapping("/edit/{productId}") public String modifyProduct(@PathVariable Long productId, @Valid ProductSaveRequest productSaveRequest, @RequestParam("mainFile") MultipartFile mainFile, @@ -101,15 +117,20 @@ public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") i if (member.getRole().getValue().equals("MEMBER")) { model.addAttribute("mainCategoryName", mainCategory); model.addAttribute("productResponses", recommendService.getFindAll(offset)); + model.addAttribute("subCategories", subCategoryService.findAll(mainCategory)); } else { model.addAttribute("mainCategoryName", mainCategory); model.addAttribute("productResponses", productService.showAll(offset, mainCategory, subCategory)); + model.addAttribute("subCategories", subCategoryService.findAll(mainCategory)); } } else { model.addAttribute("mainCategoryName", mainCategory); model.addAttribute("productResponses", productService.showAll(offset, mainCategory, subCategory)); + model.addAttribute("subCategories", subCategoryService.findAll(mainCategory)); } return "/trendpick/products/list"; } + + } // @RequestParam(value = "sort", defaultValue = "1"), Integer sortCode \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java index 1351ac1b..91f13fcf 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/request/ProductSaveRequest.java @@ -18,13 +18,13 @@ public class ProductSaveRequest { @NotBlank(message = "내용을 입력해주세요.") private String description; - @NotBlank(message = "메인 카테고리를 정하세요.") +// @NotBlank(message = "메인 카테고리를 정하세요.") private String mainCategory; - @NotBlank(message = "서브 카테고리를 정하세요.") +// @NotBlank(message = "서브 카테고리를 정하세요.") private String subCategory; - @NotBlank(message = "브랜드를 입력해주세요.") +// @NotBlank(message = "브랜드를 입력해주세요.") private String brand; @NotNull(message = "가격을 입력해주세요.") diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java index 49c2a83c..e24b893d 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductResponse.java @@ -64,6 +64,22 @@ public static ProductResponse of (String filePath, Product product, String role) .build(); } + public static ProductResponse of (String filePath, Product product) { + return ProductResponse.builder() + .id(product.getId()) + .name(product.getName()) + .mainCategory(product.getMainCategory().getName()) + .subCategory(product.getSubCategory().getName()) + .brand(product.getBrand().getName()) + .description(product.getDescription()) + .mainFile(product.getFile().getFileName()) + .subFiles(subFiles(filePath, product.getFile().getChild())) + .price(product.getPrice()) + .stock(product.getStock()) + .tags(new ArrayList<>(product.getTags())) + .build(); + } + private static List subFiles(String filePath, List subFiles) { List tmpList = new ArrayList<>(); diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 6c4f1b98..a4145136 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -131,16 +131,16 @@ public void delete(Long productId) { } public ProductResponse show(Long productId) { - Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 - - Optional member = rq.CheckLogin(); - if (member.isPresent()){ - Member checkMember = member.get(); + try { + Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 + Member checkMember = rq.CheckMember().get(); favoriteTagService.updateTag(checkMember, product, TagType.SHOW); return ProductResponse.of(filePath, product, checkMember.getRole().getValue()); - } else { - throw new MemberNotFoundException("존재하지 않는 회원입니다."); + } + catch(MemberNotMatchException | MemberNotFoundException e) { + Product product = productRepository.findById(productId).orElseThrow(null);// 임시. 나중에 테스트 + return ProductResponse.of(filePath, product); } } diff --git a/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java b/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java index a1fb1efd..8e9f4022 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java @@ -4,6 +4,7 @@ import lombok.RequiredArgsConstructor; import org.springframework.data.domain.Page; import org.springframework.scheduling.annotation.Scheduled; +import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; @@ -18,12 +19,14 @@ public class RecommendController { private final RecommendService recommendService; + @PreAuthorize("isAuthenticated()") @GetMapping("/admin/caculate") public String caculate(){ // recommendService.select(); return "redirect:/trendpick/products/list"; } + @PreAuthorize("isAuthenticated()") @GetMapping("/admin/getrecommendset") public String getRecommend(Model model, @RequestParam("page") int offset){ model.addAttribute("recommend", recommendService.getFindAll(offset)); diff --git a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java index fb8c1c1d..2f638b42 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java @@ -56,6 +56,23 @@ public void select(){ } } + @Transactional + public void select(String username){ + + Member member = memberRepository.findByEmail(username).orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); + + recommendRepository.deleteAllByMemberId(member.getId()); + + List products = productService.getRecommendProduct(member); + + for (Product product : products) { + Recommend recommend = Recommend.of(product); + recommend.connectProduct(product); + recommend.connectMember(member); + recommendRepository.save(recommend); + } + } + public Page getFindAll(int offset){ String username = SecurityContextHolder.getContext().getAuthentication().getName(); PageRequest pageable = PageRequest.of(offset, 18); diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index 4632b09c..a1473fcd 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -26,6 +26,7 @@ import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.product.service.ProductService; +import project.trendpick_pro.domain.recommend.service.RecommendService; import project.trendpick_pro.domain.tags.favoritetag.entity.FavoriteTag; import project.trendpick_pro.domain.tags.tag.entity.Tag; import project.trendpick_pro.domain.tags.tag.entity.type.TagType; @@ -82,7 +83,8 @@ CommandLineRunner initData( BrandService brandService, ProductRepository productRepository, OrderService orderservice, - CartService cartService + CartService cartService, + RecommendService recommendService ) { return new CommandLineRunner() { @Override @@ -176,9 +178,9 @@ public void run(String... args) { productRepository.save(product); } //==장바구니 데이터==// - cartService.addItemToCart(memberService.findByEmail("trendpick@naver.com").get(),1L, new CartItemRequest(5)); - cartService.addItemToCart(memberService.findByEmail("trendpick@naver.com").get(),2L, new CartItemRequest(3)); - cartService.addItemToCart(memberService.findByEmail("trendpick@naver.com").get(),3L, new CartItemRequest(1)); + cartService.addItemToCart(memberService.findByEmail("trendpick@naver.com").get(), new CartItemRequest(1L,5)); + cartService.addItemToCart(memberService.findByEmail("trendpick@naver.com").get(), new CartItemRequest(2L,3)); + cartService.addItemToCart(memberService.findByEmail("trendpick@naver.com").get(), new CartItemRequest(3L,1)); //==주문데이터==// Member findMember = memberService.findByEmail("hye_0000@naver.com").get(); @@ -205,6 +207,8 @@ public void run(String... args) { OrderForm orderForm2 = new OrderForm(memberInfo2, orderItems2); orderForm2.setPaymentMethod("신용카드"); orderservice.order(findMember2, orderForm2); + + recommendService.select(member.email()); } }; } diff --git a/src/main/resources/templates/trendpick/products/detailpage.html b/src/main/resources/templates/trendpick/products/detailpage.html index e342daff..6d708e67 100644 --- a/src/main/resources/templates/trendpick/products/detailpage.html +++ b/src/main/resources/templates/trendpick/products/detailpage.html @@ -29,18 +29,18 @@

    -
    +
    +
    - - + +
    - Back to List
    @@ -50,20 +50,18 @@

    function setQuantity() { var quantityInput = document.getElementById("quantity"); var addToCartQuantityInput = document.getElementById("addToCartQuantity"); - var orderQuantityInput = document.getElementById("orderQuantity"); addToCartQuantityInput.value = quantityInput.value; - orderQuantityInput.value = quantityInput.value; } - // Quantity 값이 변경될 때마다 setQuantity 함수를 호출 - var quantityInput = document.getElementById("quantity"); - quantityInput.addEventListener("change", setQuantity); + window.onload = function() { + setQuantity(); + + var quantityInput = document.getElementById("quantity"); + quantityInput.addEventListener("change", setQuantity); - // 폼 전송 시 setQuantity 함수를 호출하여 각각의 hiddenQuantity 값을 업데이트 - var addToCartForm = document.getElementById("addToCartForm"); - addToCartForm.addEventListener("submit", setQuantity); - var orderForm = document.getElementById("orderForm"); - orderForm.addEventListener("submit", setQuantity); + var addToCartForm = document.getElementById("addToCartForm"); + addToCartForm.addEventListener("submit", setQuantity); + } diff --git a/src/main/resources/templates/trendpick/products/list.html b/src/main/resources/templates/trendpick/products/list.html index 13fc86c0..ddebfbfe 100644 --- a/src/main/resources/templates/trendpick/products/list.html +++ b/src/main/resources/templates/trendpick/products/list.html @@ -6,8 +6,19 @@
    +
    + + + + +
    -
    새 상품 생성 @@ -17,14 +28,15 @@
    Product Image
    - -
    - -
    -
    - - -
    +
    +
    + +
    +
    + + +
    +
    diff --git a/src/main/resources/templates/trendpick/products/register.html b/src/main/resources/templates/trendpick/products/register.html index b9be5961..3769f73f 100644 --- a/src/main/resources/templates/trendpick/products/register.html +++ b/src/main/resources/templates/trendpick/products/register.html @@ -1,108 +1,110 @@ - + - - - 상품 등록 폼 - + Product Registration -
    -
    - - -

    + +
    + + + + +
    + +
    -
    - - -
    -

    +
    + +
    - -
    - -
    - +
    + +
    +
    + +
    - -
    -
    - +
    + +
    +
    - -
    +
    +
    - +
    + + +
    -
    - - +
    + +
    -
    - - +
    + +
    -
    - - -

    +
    + +
    -
    - - -

    +
    + +
    - -
    + +
    - - + +
    -

    - + +
    - - \ No newline at end of file + From 8a37c0021b0f05e7b69df9813f9b04d0108ec67a Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 9 Jun 2023 10:54:06 +0900 Subject: [PATCH 225/367] =?UTF-8?q?fix:=20=EC=B6=94=EC=B2=9C=EC=83=81?= =?UTF-8?q?=ED=92=88=20=EB=A6=AC=EC=8A=A4=ED=8C=85=EC=9D=B4=20=EC=A0=9C?= =?UTF-8?q?=EB=8C=80=EB=A1=9C=20=EB=90=98=EC=A7=80=20=EC=95=8A=EB=8A=94=20?= =?UTF-8?q?=EC=9D=B4=EC=8A=88=20=ED=95=B4=EA=B2=B0(#152)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/product/controller/ProductController.java | 2 +- .../domain/recommend/controller/RecommendController.java | 4 +++- .../domain/recommend/service/RecommendService.java | 6 +++--- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index a1313613..b4b83dff 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -116,7 +116,7 @@ public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") i Member member = rq.CheckLogin().orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); if (member.getRole().getValue().equals("MEMBER")) { model.addAttribute("mainCategoryName", mainCategory); - model.addAttribute("productResponses", recommendService.getFindAll(offset)); + model.addAttribute("productResponses", recommendService.getFindAll(member, offset)); model.addAttribute("subCategories", subCategoryService.findAll(mainCategory)); } else { model.addAttribute("mainCategoryName", mainCategory); diff --git a/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java b/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java index 8e9f4022..e0d858c0 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/controller/RecommendController.java @@ -11,6 +11,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; +import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.recommend.entity.Recommend; import project.trendpick_pro.domain.recommend.service.RecommendService; @@ -18,6 +19,7 @@ @RequiredArgsConstructor public class RecommendController { private final RecommendService recommendService; + private final Rq rq; @PreAuthorize("isAuthenticated()") @GetMapping("/admin/caculate") @@ -29,7 +31,7 @@ public String caculate(){ @PreAuthorize("isAuthenticated()") @GetMapping("/admin/getrecommendset") public String getRecommend(Model model, @RequestParam("page") int offset){ - model.addAttribute("recommend", recommendService.getFindAll(offset)); + model.addAttribute("recommend", recommendService.getFindAll(rq.CheckMember().get(), offset)); return "/main"; } } diff --git a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java index 2f638b42..d15c11a3 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java @@ -33,6 +33,7 @@ public class RecommendService { private final ProductService productService; private final MemberRepository memberRepository; + @Value("${file.path}") private String filePath; //recommend -> 태그 기반 추천 상품들이 있어야 함 @@ -73,10 +74,9 @@ public void select(String username){ } } - public Page getFindAll(int offset){ - String username = SecurityContextHolder.getContext().getAuthentication().getName(); + public Page getFindAll(Member member, int offset){ PageRequest pageable = PageRequest.of(offset, 18); - Page listResponses = recommendRepository.findAllByMemberName(username, pageable); + Page listResponses = recommendRepository.findAllByMemberName(member.getUsername(), pageable); List list = listResponses.getContent().stream() .peek(product -> { From bb8e22c30ba0ff1e8bb1246b0b02da909c0571b7 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 9 Jun 2023 13:43:43 +0900 Subject: [PATCH 226/367] =?UTF-8?q?refactor:=20Recommend=20=ED=95=84?= =?UTF-8?q?=EC=9A=94=ED=95=9C=20=EB=8D=B0=EC=9D=B4=ED=84=B0=EB=A7=8C=20?= =?UTF-8?q?=EB=82=A8=EA=B8=B0=EA=B3=A0=20=EC=A0=9C=EA=B1=B0(#152)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/recommend/entity/Recommend.java | 27 ++----------------- .../repository/RecommendRepositoryImpl.java | 8 ++---- .../recommend/service/RecommendService.java | 2 -- 3 files changed, 4 insertions(+), 33 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/recommend/entity/Recommend.java b/src/main/java/project/trendpick_pro/domain/recommend/entity/Recommend.java index 3565b0de..319bdb5f 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/entity/Recommend.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/entity/Recommend.java @@ -17,19 +17,6 @@ public class Recommend { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @Column(name = "name", nullable = false) - private String name; - - @ManyToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "brand_id") - private Brand brand; - - @Column(name = "main_file", nullable = false) - private String mainFile; - - @Column(name = "price", nullable = false) - private int price; - @OneToOne(fetch = FetchType.LAZY) @JoinColumn(name = "product_id") private Product product; @@ -39,14 +26,7 @@ public class Recommend { private Member member; @Builder - public Recommend(String name, Brand brand, String mainFile, int price) { - this.name = name; - this.brand = brand; - this.mainFile = mainFile; - this.price = price; - } - - public void connectProduct(Product product) { + public Recommend(Product product) { this.product = product; } @@ -56,10 +36,7 @@ public void connectMember(Member member) { public static Recommend of(Product product) { return Recommend.builder() - .name(product.getName()) - .brand(product.getBrand()) - .mainFile(product.getFile().getFileName()) - .price(product.getPrice()) + .product(product) .build(); } } diff --git a/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryImpl.java index 405cbf0e..54bc49b6 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/repository/RecommendRepositoryImpl.java @@ -34,15 +34,13 @@ public Page findAllByMemberName(String username, Pageable p .select(new QProductListResponse( product.id, product.name, - brand.name, - commonFile.fileName, + product.brand.name, + product.file.fileName, product.price )) .from(recommend) .leftJoin(recommend.member, member) .leftJoin(recommend.product, product) - .leftJoin(recommend.brand, brand) - .leftJoin(recommend.product.file, commonFile) .where(recommend.member.username.eq(username)) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -53,8 +51,6 @@ public Page findAllByMemberName(String username, Pageable p .from(recommend) .leftJoin(recommend.member, member) .leftJoin(recommend.product, product) - .leftJoin(recommend.brand, brand) - .leftJoin(recommend.product.file, commonFile) .where(recommend.member.username.eq(username)); return PageableExecutionUtils.getPage(result, pageable, count::fetchOne); diff --git a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java index d15c11a3..17f6388c 100644 --- a/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java +++ b/src/main/java/project/trendpick_pro/domain/recommend/service/RecommendService.java @@ -51,7 +51,6 @@ public void select(){ for (Product product : products) { Recommend recommend = Recommend.of(product); - recommend.connectProduct(product); recommend.connectMember(member); recommendRepository.save(recommend); } @@ -68,7 +67,6 @@ public void select(String username){ for (Product product : products) { Recommend recommend = Recommend.of(product); - recommend.connectProduct(product); recommend.connectMember(member); recommendRepository.save(recommend); } From 76612f47212c83ba372540139904e4bad1385ec8 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Fri, 9 Jun 2023 14:10:21 +0900 Subject: [PATCH 227/367] =?UTF-8?q?refactor:=20=EA=B4=80=EB=A6=AC=EC=9E=90?= =?UTF-8?q?=ED=8E=98=EC=9D=B4=EC=A7=80=EC=97=90=EC=84=9C=20=EC=88=98?= =?UTF-8?q?=EC=A0=95=20=EC=82=AD=EC=A0=9C=EB=B2=84=ED=8A=BC=20=ED=91=9C?= =?UTF-8?q?=EC=8B=9C=20(#156)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/common/base/rq/Rq.java | 13 ++++++ src/main/resources/application.yml | 5 ++- .../templates/trendpick/products/list.html | 40 ++++++++++--------- .../trendpick/products/register.html | 16 ++++---- .../trendpick/usr/layout/layout.html | 2 +- 5 files changed, 48 insertions(+), 28 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java index 58528fdd..fa3226e9 100644 --- a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java +++ b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java @@ -120,6 +120,11 @@ public Optional CheckAdmin() { return member; } + public Boolean CheckAdminHtml() { + Member checkMember = CheckLogin().get(); + return !checkMember.getRole().equals(RoleType.MEMBER); + } + public Optional CheckMember() { Optional member = CheckLogin(); Member checkMember = member.get(); @@ -130,6 +135,14 @@ public Optional CheckMember() { throw new MemberNotMatchException("허용된 권한이 아닙니다."); } + public Boolean CheckLoginHtml() { + + String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 + Optional member = memberService.findByEmail(username); + + return member.isPresent(); + } + public Optional CheckLogin() { String username = SecurityContextHolder.getContext().getAuthentication().getName(); // 둘다 테스트 해보기 diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index e5718afc..396987bb 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -4,4 +4,7 @@ spring: include: secret, data mvc: pathmatch: - matching-strategy: ant_path_matcher \ No newline at end of file + matching-strategy: ant_path_matcher + hiddenmethod: + filter: + enabled: true \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/products/list.html b/src/main/resources/templates/trendpick/products/list.html index ddebfbfe..66723d3d 100644 --- a/src/main/resources/templates/trendpick/products/list.html +++ b/src/main/resources/templates/trendpick/products/list.html @@ -19,31 +19,35 @@
    -
    -
    - 새 상품 생성 -
    -
    + +
    +
    + 새 상품 생성 +
    +
    +
    Product Image -
    -
    -
    - -
    -
    - - -
    -
    -

    Brand:
    +
    +
    +
    +
    + +
    +
    + + +
    +
    +
    +
    View More
    @@ -51,11 +55,11 @@

    diff --git a/src/main/resources/templates/trendpick/products/register.html b/src/main/resources/templates/trendpick/products/register.html index 3769f73f..a8b44aa0 100644 --- a/src/main/resources/templates/trendpick/products/register.html +++ b/src/main/resources/templates/trendpick/products/register.html @@ -10,22 +10,22 @@ @@ -45,7 +45,7 @@
    @@ -56,7 +56,7 @@
    diff --git a/src/main/resources/templates/trendpick/usr/layout/layout.html b/src/main/resources/templates/trendpick/usr/layout/layout.html index b8516a6b..f4130e30 100644 --- a/src/main/resources/templates/trendpick/usr/layout/layout.html +++ b/src/main/resources/templates/trendpick/usr/layout/layout.html @@ -23,7 +23,7 @@
    주문번호상품정보상품정보 주문수량 주문금액 주문일시
    + + +
    @@ -39,7 +43,7 @@
    - + From 5a2754be44a85b91549c424d3c7548c2e1924564 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 9 Jun 2023 17:27:38 +0900 Subject: [PATCH 232/367] =?UTF-8?q?feat:=20=EC=A3=BC=EB=AC=B8=20=EC=83=81?= =?UTF-8?q?=EC=84=B8=20=ED=8E=98=EC=9D=B4=EC=A7=80=20=EC=A0=9C=EC=9E=91(#1?= =?UTF-8?q?58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orders/contoller/OrderController.java | 4 +-- .../dto/response/OrderDetailResponse.java | 13 ++++++++ .../entity/dto/response/OrderResponse.java | 4 +-- .../domain/orders/service/OrderService.java | 1 + .../templates/trendpick/orders/detail.html | 32 +++++++++++++++---- 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 296e24ef..1ddeabfa 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -99,10 +99,10 @@ public String orderListByMember( return "trendpick/usr/member/orders"; } - @PostMapping("/{orderId}/cancel") + @PostMapping("/cancel/{orderId}") public String cancelOrder(@PathVariable("orderId") Long orderId) { orderService.cancel(orderId); - return "redirect:trendpick/usr/member/orders"; + return "redirect:trendpick/orders/list"; } @GetMapping("/{orderId}") diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderDetailResponse.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderDetailResponse.java index b8d50373..ba437e2a 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderDetailResponse.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderDetailResponse.java @@ -7,23 +7,36 @@ import lombok.Setter; import project.trendpick_pro.domain.orders.entity.Order; +import java.text.NumberFormat; +import java.time.LocalDateTime; import java.util.List; +import java.util.Locale; @Getter @NoArgsConstructor @AllArgsConstructor public class OrderDetailResponse { + private Long orderId; private List orderItems; private int totalPrice = 0; private String paymentMethod; + private LocalDateTime orderDate; public static OrderDetailResponse of(Order order, List orderItems){ OrderDetailResponse orderDetailResponse = new OrderDetailResponse(); + orderDetailResponse.orderId = order.getId(); orderDetailResponse.orderItems = orderItems; + orderDetailResponse.orderDate = order.getCreatedDate(); orderDetailResponse.paymentMethod = order.getPaymentMethod(); for (OrderResponse orderItem : orderItems) { orderDetailResponse.totalPrice += orderItem.getTotalPrice(); } return orderDetailResponse; } + + public String getFormattedPaymentPrice(){ + NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault()); + return numberFormat.format(getTotalPrice()); + } + } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java index e0108782..2958c1dc 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/response/OrderResponse.java @@ -26,7 +26,7 @@ public class OrderResponse { @Builder @QueryProjection - public OrderResponse(Long orderId, Long productId, String productFilePath, String brandName, String productName, int count,int productPrice, LocalDateTime orderDate, String orderStatus, String deliveryStatus, String paymentMethod) { + public OrderResponse(Long orderId, Long productId, String productFilePath, String brandName, String productName, int count,int productPrice, LocalDateTime orderDate, String orderStatus, String deliveryStatus) { this.orderId = orderId; this.productId = productId; this.productFilePath = productFilePath; @@ -41,7 +41,7 @@ public OrderResponse(Long orderId, Long productId, String productFilePath, Strin public String getFormattedTotalPrice(){ NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault()); - return numberFormat.format(getTotalPrice()); + return numberFormat.format(getTotalPrice())+"원"; } public int getTotalPrice(){ return productPrice * count; diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index bae264f3..f8a5c322 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -111,4 +111,5 @@ public OrderDetailResponse showOrderItems(Member member, Long orderId) { return OrderDetailResponse.of(order, orderRepository.findOrderItemsByOrderId(orderId)); } + } diff --git a/src/main/resources/templates/trendpick/orders/detail.html b/src/main/resources/templates/trendpick/orders/detail.html index ef3ae8c9..71e48577 100644 --- a/src/main/resources/templates/trendpick/orders/detail.html +++ b/src/main/resources/templates/trendpick/orders/detail.html @@ -2,7 +2,7 @@ - 주문 목록 + 주문 상세

    주문상품 정보

    @@ -10,7 +10,6 @@

    주문상품 정보

    - @@ -19,14 +18,35 @@

    주문상품 정보

    - - - - + + + +
    번호 상품명 주문수량
    +
    + + + + + + + + + + + + + + + +
    주문일시
    결제수단
    총 주문금액
    +
    +
    + +
    \ No newline at end of file From 9faee02d666e4dd3ed58b958df6de0d1e78a2673 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 9 Jun 2023 17:57:22 +0900 Subject: [PATCH 233/367] =?UTF-8?q?feat:=20=EB=B8=8C=EB=9E=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90=EC=9D=98=20=ED=8C=90=EB=A7=A4?= =?UTF-8?q?=EB=AA=A9=EB=A1=9D=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC=ED=98=84(#1?= =?UTF-8?q?58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/entity/Member.java | 5 ++ .../orders/contoller/OrderController.java | 17 +++++ .../entity/dto/request/OrderSearchCond.java | 7 ++ .../repository/OrderRepositoryCustom.java | 1 + .../repository/OrderRepositoryImpl.java | 35 +++++++++ .../domain/orders/service/OrderService.java | 4 ++ .../templates/trendpick/admin/orders.html | 71 ++++++++++++++++++- 7 files changed, 138 insertions(+), 2 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index bcc77dc7..8b18b211 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -32,6 +32,8 @@ public class Member { @Column(name = "role", nullable = false) private RoleType role; + private String brand; + @OneToOne(mappedBy = "member") private Cart cart; @OneToMany(mappedBy = "member", cascade = CascadeType.ALL, orphanRemoval = true) @@ -50,6 +52,9 @@ public Member(String email, String password, String username, String phoneNumber this.phoneNumber = phoneNumber; this.role = role; } + public void connectBrand(String brand){ + this.brand = brand; + } public void connectAddress(String address) { this.address = address; diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 1ddeabfa..7b70136a 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -99,6 +99,23 @@ public String orderListByMember( return "trendpick/usr/member/orders"; } + @PreAuthorize("isAuthenticated()") + @GetMapping("/list") + public String orderListBySeller( + @RequestParam(value = "page", defaultValue = "0") int offset, + Model model) { + Page orderList = orderService.findAllBySeller(rq.CheckAdmin().get(), offset); + int blockPage = 5; + int startPage = (offset / blockPage) * blockPage + 1; + int endPage = Math.min(startPage + blockPage - 1, orderList.getTotalPages()); + + model.addAttribute("orderList", orderList); + model.addAttribute("startPage", startPage); + model.addAttribute("endPage", endPage); + + return "trendpick/admin/orders"; + } + @PostMapping("/cancel/{orderId}") public String cancelOrder(@PathVariable("orderId") Long orderId) { orderService.cancel(orderId); diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSearchCond.java b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSearchCond.java index a9a56d4b..244c950e 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSearchCond.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/dto/request/OrderSearchCond.java @@ -8,8 +8,15 @@ public class OrderSearchCond { private Long memberId; + private String brand; public OrderSearchCond(Long memberId) { this.memberId = memberId; } + + public OrderSearchCond(String brand){ + this.brand = brand; + } + + } diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryCustom.java index a99867d2..7cb04bdb 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryCustom.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryCustom.java @@ -10,4 +10,5 @@ public interface OrderRepositoryCustom { public Page findAllByMember(OrderSearchCond orderSearchCond, Pageable pageable); public List findOrderItemsByOrderId(Long orderId); + Page findAllBySeller(OrderSearchCond orderSearchCond, Pageable pageable); } diff --git a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java index d7bf5973..677dd032 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/orders/repository/OrderRepositoryImpl.java @@ -6,6 +6,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.support.PageableExecutionUtils; +import project.trendpick_pro.domain.brand.entity.Brand; import project.trendpick_pro.domain.orders.entity.dto.request.OrderSearchCond; import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; import project.trendpick_pro.domain.orders.entity.dto.response.QOrderResponse; @@ -80,4 +81,38 @@ public List findOrderItemsByOrderId(Long orderId) { .where(order.id.eq(orderId)) .fetch(); } + + //나의 판매목록 + @Override + public Page findAllBySeller(OrderSearchCond orderSearchCond, Pageable pageable) { + List result = queryFactory + .select(new QOrderResponse( + orderItem.order.id, + orderItem.product.id, + orderItem.product.file.fileName, + orderItem.product.brand.name, + orderItem.product.name, + orderItem.count, + orderItem.orderPrice, + orderItem.order.createdDate, + orderItem.order.status.stringValue(), + orderItem.order.delivery.state.stringValue()) + ) + .from(orderItem) + .join(orderItem.order, order) + .join(order.member, member) + .on(orderItem.product.brand.name.eq(orderSearchCond.getBrand())) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .orderBy(orderItem.order.createdDate.desc()) + .fetch(); + + JPAQuery countQuery = queryFactory + .select(order.count()) + .from(order) + .join(order.member, member) + .on(orderItem.product.brand.name.eq(orderSearchCond.getBrand())) + ; + return PageableExecutionUtils.getPage(result, pageable, countQuery::fetchOne); + } } diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index f8a5c322..5bc50b64 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -112,4 +112,8 @@ public OrderDetailResponse showOrderItems(Member member, Long orderId) { return OrderDetailResponse.of(order, orderRepository.findOrderItemsByOrderId(orderId)); } + public Page findAllBySeller(Member member, int offset) { + return orderRepository.findAllBySeller( + new OrderSearchCond(member.getBrand()), PageRequest.of(offset, 10)); + } } diff --git a/src/main/resources/templates/trendpick/admin/orders.html b/src/main/resources/templates/trendpick/admin/orders.html index 630c6847..d61ae138 100644 --- a/src/main/resources/templates/trendpick/admin/orders.html +++ b/src/main/resources/templates/trendpick/admin/orders.html @@ -2,9 +2,76 @@ - 주문 목록 + 판매 목록
    - 판매자 상품중 주문된 목록 + + + + + + + + + + + + + + + + + + + + + + + + + + +
    주문번호상품정보주문수량주문금액주문일시주문상태배송상태리뷰등록
    + + + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + 등록 + +
    + +
    +
    + Previous + + + + Next +
    +
    +
    \ No newline at end of file From d9ec753c10ac7198a0a3d89233cfae7010d688a9 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Fri, 9 Jun 2023 22:57:29 +0900 Subject: [PATCH 234/367] =?UTF-8?q?feat:=20=ED=8C=90=EB=A7=A4=EC=9E=90?= =?UTF-8?q?=EA=B0=80=20=EC=98=AC=EB=A6=B0=20=EC=83=81=ED=92=88=20=EB=A6=AC?= =?UTF-8?q?=EC=8A=A4=ED=8A=B8(ProductListResponseBySeller)=20querydsl=20?= =?UTF-8?q?=EA=B5=AC=ED=98=84(#158)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orders/contoller/OrderController.java | 13 ++-- .../domain/orders/entity/Order.java | 9 +-- .../domain/orders/entity/OrderItem.java | 1 + .../domain/orders/service/OrderService.java | 8 ++- .../product/controller/ProductController.java | 10 ++- .../domain/product/entity/Product.java | 23 +++++- .../response/ProductListResponseBySeller.java | 40 +++++++++++ .../repository/ProductRepositoryCustom.java | 3 + .../repository/ProductRepositoryImpl.java | 43 +++++++++-- .../product/service/ProductService.java | 7 ++ .../templates/trendpick/admin/orders.html | 6 -- .../templates/trendpick/admin/products.html | 72 ++++++++++++++++++- .../templates/trendpick/orders/detail.html | 1 - 13 files changed, 211 insertions(+), 25 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponseBySeller.java diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 7b70136a..02fa36bd 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -26,6 +26,7 @@ import project.trendpick_pro.domain.product.entity.Product; import project.trendpick_pro.domain.product.entity.form.ProductOptionForm; import project.trendpick_pro.domain.product.repository.ProductRepository; +import project.trendpick_pro.global.rsData.RsData; import java.time.LocalDateTime; import java.util.ArrayList; @@ -83,7 +84,7 @@ public String orderProduct(@ModelAttribute ProductOptionForm productOptionForm, } @PreAuthorize("isAuthenticated()") - @GetMapping("/list") + @GetMapping("usr//list") public String orderListByMember( @RequestParam(value = "page", defaultValue = "0") int offset, Model model) { @@ -100,7 +101,7 @@ public String orderListByMember( } @PreAuthorize("isAuthenticated()") - @GetMapping("/list") + @GetMapping("admin/list") public String orderListBySeller( @RequestParam(value = "page", defaultValue = "0") int offset, Model model) { @@ -118,8 +119,12 @@ public String orderListBySeller( @PostMapping("/cancel/{orderId}") public String cancelOrder(@PathVariable("orderId") Long orderId) { - orderService.cancel(orderId); - return "redirect:trendpick/orders/list"; + RsData result = orderService.cancel(orderId); + + if(result.isFail()) + rq.historyBack(result); + + return rq.redirectWithMsg("/trendpick/orders/admin/list", result); } @GetMapping("/{orderId}") diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java index f0979c8d..f6d03a32 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java @@ -69,13 +69,14 @@ public static Order createOrder(Member member, Delivery delivery, OrderStatus st } public void cancel() { - if (delivery.getState() == DeliveryState.COMPLETED) { + if (delivery.getState() != DeliveryState.COMPLETED) { throw new IllegalStateException("이미 배송완료된 상품은 취소가 불가능합니다."); } - this.status = OrderStatus.CANCELLED; - for (OrderItem orderItem : orderItems) { - orderItem.cancel(); + if (delivery.getState() != DeliveryState.COMPLETED) { + throw new IllegalStateException("이미 배송을 시작하여 취소가 불가능합니다."); } + + this.status = OrderStatus.CANCELLED; } } diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java index 8a0ae02f..ce62d4e2 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/OrderItem.java @@ -37,6 +37,7 @@ private OrderItem(Product product, int orderPrice, int count) { this.count = count; product.removeStock(count); + product.increaseSaleCount(count); } public static OrderItem of(Product product, OrderItemDto orderItemDto) { diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 5bc50b64..09faa614 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -31,6 +31,7 @@ import project.trendpick_pro.domain.product.exception.ProductNotFoundException; import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tags.tag.entity.type.TagType; +import project.trendpick_pro.global.rsData.RsData; import java.util.ArrayList; import java.util.List; @@ -67,9 +68,14 @@ public void order(Member member, OrderForm orderForm) { } @Transactional - public void cancel(Long orderId) { + public RsData cancel(Long orderId) { Order order = orderRepository.findById(orderId).orElseThrow(() -> new EntityNotFoundException("존재하지 않는 주문입니다.")); + if(order.getStatus() == OrderStatus.CANCELLED) + return RsData.of("F-1", "이미 취소된 주문입니다."); + order.cancel(); + + return RsData.of("S-1", "환불 요청이 정상적으로 진행되었습니다."); } public Page findAllByMember(Member member, int offset) { diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index ae2ecc35..1bd22ee4 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -64,7 +64,6 @@ public String registerProduct(@ModelAttribute("productSaveRequest") ProductSaveR return "/trendpick/products/register"; } - @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") @PostMapping("/register") public String register(@ModelAttribute @Valid ProductSaveRequest productSaveRequest, @@ -149,6 +148,15 @@ public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") i return "/trendpick/products/list"; } + @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") + @GetMapping("admin/list") + public String showAllProductBySeller(@RequestParam("page") int offset, Model model) { + productService.findProductsBySeller(rq.CheckAdmin().get(), offset); + return "/trendpick/admin/products"; + } + + + } // @RequestParam(value = "sort", defaultValue = "1"), Integer sortCode \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index edbf146b..ef8c023a 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -75,8 +75,11 @@ public class Product extends BaseTimeEntity { @OneToOne(mappedBy = "product", cascade = CascadeType.ALL, orphanRemoval = true) private Recommend recommends; - public long reviewCount = 0; - public double rateAvg = 0; + + private int reviewCount = 0; + private double rateAvg = 0; + private int saleCount = 0; + private int askCount = 0; @Builder public Product(String name, MainCategory mainCategory, SubCategory subCategory, Brand brand, @@ -118,6 +121,20 @@ public void removeStock(int quantity) { this.stock = restStock; } + public void increaseSaleCount(int quantity){ + this.saleCount += quantity; + } + public void decreaseSaleCount(int quantity){ + this.saleCount -= quantity; + } + + public void increaseSaleCount(){ + this.askCount += 1; + } + public void decreaseSaleCount(){ + this.askCount -= 1; + } + public void addReview(int rating){ double total = getRateAvg() * getReviewCount() + rating; @@ -125,6 +142,8 @@ public void addReview(int rating){ this.rateAvg = Math.round(total / reviewCount * 10) / 10.0; } + + public void update(ProductSaveRequest request, CommonFile file) { this.name = request.getName(); this.description = request.getDescription(); diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponseBySeller.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponseBySeller.java new file mode 100644 index 00000000..b07562a1 --- /dev/null +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponseBySeller.java @@ -0,0 +1,40 @@ +package project.trendpick_pro.domain.product.entity.dto.response; + +import com.querydsl.core.annotations.QueryProjection; +import lombok.*; +import project.trendpick_pro.domain.tags.tag.entity.Tag; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; +@Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) +public class ProductListResponseBySeller { + + private Long id; + private String name; + private String mainFile; + private int price; + private int stock; + private LocalDateTime createdDate; + private int saleCount; + + private double rateAvg; + private int reviewCount; + private int ask; + + @Builder + @QueryProjection + public ProductListResponseBySeller(Long id, String name, String mainFile, int price, int stock, LocalDateTime createdDate, int saleCount, double rateAvg, int reviewCount, int ask) { + this.id = id; + this.name = name; + this.mainFile = mainFile; + this.price = price; + this.stock = stock; + this.createdDate = createdDate; + this.saleCount = saleCount; + this.rateAvg = rateAvg; + this.reviewCount = reviewCount; + this.ask = ask; + } +} diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java index 25f552d0..ccfcf564 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryCustom.java @@ -6,10 +6,13 @@ import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; +import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponseBySeller; import java.util.List; public interface ProductRepositoryCustom { public Page findAllByCategoryId(ProductSearchCond cond, Pageable pageable); public List findRecommendProduct(String username); + + public Page findAllBySeller(String brand, Pageable pageable); } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 63d4907b..b74dbc9b 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -9,15 +9,15 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.support.PageableExecutionUtils; +import project.trendpick_pro.domain.ask.entity.QAsk; import project.trendpick_pro.domain.product.entity.dto.request.ProductSearchCond; -import project.trendpick_pro.domain.product.entity.dto.response.ProductByRecommended; -import project.trendpick_pro.domain.product.entity.dto.response.ProductListResponse; -import project.trendpick_pro.domain.product.entity.dto.response.QProductByRecommended; -import project.trendpick_pro.domain.product.entity.dto.response.QProductListResponse; +import project.trendpick_pro.domain.product.entity.dto.response.*; import java.util.List; +import static project.trendpick_pro.domain.ask.entity.QAsk.*; import static project.trendpick_pro.domain.brand.entity.QBrand.*; +import static project.trendpick_pro.domain.brand.entity.QBrand.brand; import static project.trendpick_pro.domain.category.entity.QMainCategory.*; import static project.trendpick_pro.domain.category.entity.QSubCategory.*; import static project.trendpick_pro.domain.common.file.QCommonFile.commonFile; @@ -117,4 +117,39 @@ private static BooleanExpression subCategoryEq(ProductSearchCond cond) { default -> product.id.desc(); }; } + + @Override + public Page findAllBySeller(String brand, Pageable pageable) { + List list = queryFactory + .select(new QProductListResponseBySeller( + product.id, + product.name, + commonFile.fileName, + product.price, + product.stock, + product.createdDate, + product.saleCount, + product.rateAvg, + product.reviewCount, + product.askCount + )) + .from(product) + .leftJoin(product.file, commonFile) + .leftJoin(product, ask.product) + .where(product.brand.name.eq(brand)) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .orderBy(product.createdDate.desc()) //정렬추가 + .fetch(); + + JPAQuery count = queryFactory + .select(product.count()) + .from(product) + .from(product) + .leftJoin(product.file, commonFile) + .leftJoin(product, ask.product) + .where(product.brand.name.eq(brand)); + + return PageableExecutionUtils.getPage(list, pageable, count::fetchOne); + } } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 1bc425c1..b3638824 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -8,6 +8,7 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageImpl; import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -217,4 +218,10 @@ public List getRecommendProduct(Member member){ } return products; } + + public void findProductsBySeller(Member member, int offset) { + Pageable pageable = PageRequest.of(offset, 20); + + productRepository.findAllBySeller(member.getBrand(), pageable); + } } diff --git a/src/main/resources/templates/trendpick/admin/orders.html b/src/main/resources/templates/trendpick/admin/orders.html index d61ae138..4fb6a72f 100644 --- a/src/main/resources/templates/trendpick/admin/orders.html +++ b/src/main/resources/templates/trendpick/admin/orders.html @@ -16,7 +16,6 @@
    주문일시 주문상태 배송상태리뷰등록
    - - 등록 - -
    diff --git a/src/main/resources/templates/trendpick/admin/products.html b/src/main/resources/templates/trendpick/admin/products.html index 9a892aa9..9c2ad25a 100644 --- a/src/main/resources/templates/trendpick/admin/products.html +++ b/src/main/resources/templates/trendpick/admin/products.html @@ -2,9 +2,77 @@ - 주문 목록 + 판매상품 관리
    - 판매자가 올린 상품들 + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    상품번호상품정보상품금액상품재고등록일자판매개수상품평점상품리뷰문의내역
    + + + +
    +
    +
    + +
    +
    +
    +
    +
    +
    +
    +
    + + + + + + + + + + + + 등록 + +
    + +
    +
    + Previous + + + + Next +
    +
    +
    \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/orders/detail.html b/src/main/resources/templates/trendpick/orders/detail.html index 71e48577..65c6e521 100644 --- a/src/main/resources/templates/trendpick/orders/detail.html +++ b/src/main/resources/templates/trendpick/orders/detail.html @@ -47,6 +47,5 @@

    주문상품 정보

    - \ No newline at end of file From cae9d390df74fbdb776ca274d72f3d821e3de47a Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Fri, 9 Jun 2023 23:23:58 +0900 Subject: [PATCH 235/367] =?UTF-8?q?feat:=20=ED=86=A0=EC=8A=A4=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=EB=A8=BC=EC=B8=A0=20=EC=B6=94=EA=B0=80(=EB=AF=B8?= =?UTF-8?q?=EC=99=84=EC=84=B1)=20(#160)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../global/tosspayment/PaymentController.java | 95 +++++++++++ src/main/resources/static/bulma.min.css | 1 + src/main/resources/static/index.html | 158 ++++++++++++++++++ .../trendpick/orders/order-form.html | 78 ++++++--- 4 files changed, 311 insertions(+), 21 deletions(-) create mode 100644 src/main/java/project/trendpick_pro/global/tosspayment/PaymentController.java create mode 100644 src/main/resources/static/bulma.min.css create mode 100644 src/main/resources/static/index.html diff --git a/src/main/java/project/trendpick_pro/global/tosspayment/PaymentController.java b/src/main/java/project/trendpick_pro/global/tosspayment/PaymentController.java new file mode 100644 index 00000000..ddcaddb1 --- /dev/null +++ b/src/main/java/project/trendpick_pro/global/tosspayment/PaymentController.java @@ -0,0 +1,95 @@ +package project.trendpick_pro.global.tosspayment; + +import net.minidev.json.JSONObject; +import net.minidev.json.parser.JSONParser; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; + +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.Reader; +import java.net.HttpURLConnection; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +@Controller +public class PaymentController { + + @GetMapping(value = "/payment/success") + public String paymentResult( + Model model, + @RequestParam(value = "orderId") String orderId, + @RequestParam(value = "amount") Integer amount, + @RequestParam(value = "paymentKey") String paymentKey) throws Exception { + + String secretKey = "test_sk_4vZnjEJeQVxqjRyWaKOrPmOoBN0k"; + + Base64.Encoder encoder = Base64.getEncoder(); + byte[] encodedBytes = encoder.encode(secretKey.getBytes("UTF-8")); + String authorizations = "Basic " + new String(encodedBytes, 0, encodedBytes.length); + + URL url = new URL("https://api.tosspayments.com/v1/payments/" + paymentKey); + + HttpURLConnection connection = (HttpURLConnection) url.openConnection(); + connection.setRequestProperty("Authorization", authorizations); + connection.setRequestProperty("Content-Type", "application/json"); + connection.setRequestMethod("POST"); + connection.setDoOutput(true); + JSONObject obj = new JSONObject(); + obj.put("orderId", orderId); + obj.put("amount", amount); + + OutputStream outputStream = connection.getOutputStream(); + outputStream.write(obj.toString().getBytes("UTF-8")); + + int code = connection.getResponseCode(); + boolean isSuccess = code == 200; + model.addAttribute("isSuccess", isSuccess); + + InputStream responseStream = isSuccess ? connection.getInputStream() : connection.getErrorStream(); + + Reader reader = new InputStreamReader(responseStream, StandardCharsets.UTF_8); + JSONParser parser = new JSONParser(); + JSONObject jsonObject = (JSONObject) parser.parse(reader); + responseStream.close(); + model.addAttribute("responseStr", jsonObject.toJSONString()); + System.out.println(jsonObject.toJSONString()); + + model.addAttribute("method", (String) jsonObject.get("method")); + model.addAttribute("orderName", (String) jsonObject.get("orderName")); + + if (((String) jsonObject.get("method")) != null) { + if (((String) jsonObject.get("method")).equals("카드")) { + model.addAttribute("cardNumber", (String) ((JSONObject) jsonObject.get("card")).get("number")); + } else if (((String) jsonObject.get("method")).equals("가상계좌")) { + model.addAttribute("accountNumber", (String) ((JSONObject) jsonObject.get("virtualAccount")).get("accountNumber")); + } else if (((String) jsonObject.get("method")).equals("계좌이체")) { + model.addAttribute("bank", (String) ((JSONObject) jsonObject.get("transfer")).get("bank")); + } else if (((String) jsonObject.get("method")).equals("휴대폰")) { + model.addAttribute("customerMobilePhone", (String) ((JSONObject) jsonObject.get("mobilePhone")).get("customerMobilePhone")); + } + } else { + model.addAttribute("code", (String) jsonObject.get("code")); + model.addAttribute("message", (String) jsonObject.get("message")); + } + + return "redirect:/trendpick/member/orders/list"; + } + + @GetMapping(value = "/payment/fail") + public String paymentResult( + Model model, + @RequestParam(value = "message") String message, + @RequestParam(value = "code") Integer code + ) throws Exception { + + model.addAttribute("code", code); + model.addAttribute("message", message); + + return "trendpick/orders/order-form"; + } +} diff --git a/src/main/resources/static/bulma.min.css b/src/main/resources/static/bulma.min.css new file mode 100644 index 00000000..bcbbca86 --- /dev/null +++ b/src/main/resources/static/bulma.min.css @@ -0,0 +1 @@ +/*! bulma.io v0.9.0 | MIT License | github.com/jgthms/bulma */@-webkit-keyframes spinAround{from{transform:rotate(0)}to{transform:rotate(359deg)}}@keyframes spinAround{from{transform:rotate(0)}to{transform:rotate(359deg)}}.breadcrumb,.button,.delete,.file,.is-unselectable,.modal-close,.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous,.tabs{-webkit-touch-callout:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.navbar-link:not(.is-arrowless)::after,.select:not(.is-multiple):not(.is-loading)::after{border:3px solid transparent;border-radius:2px;border-right:0;border-top:0;content:" ";display:block;height:.625em;margin-top:-.4375em;pointer-events:none;position:absolute;top:50%;transform:rotate(-45deg);transform-origin:center;width:.625em}.block:not(:last-child),.box:not(:last-child),.breadcrumb:not(:last-child),.content:not(:last-child),.highlight:not(:last-child),.level:not(:last-child),.message:not(:last-child),.notification:not(:last-child),.pagination:not(:last-child),.progress:not(:last-child),.subtitle:not(:last-child),.table-container:not(:last-child),.table:not(:last-child),.tabs:not(:last-child),.title:not(:last-child){margin-bottom:1.5rem}.delete,.modal-close{-moz-appearance:none;-webkit-appearance:none;background-color:rgba(10,10,10,.2);border:none;border-radius:290486px;cursor:pointer;pointer-events:auto;display:inline-block;flex-grow:0;flex-shrink:0;font-size:0;height:20px;max-height:20px;max-width:20px;min-height:20px;min-width:20px;outline:0;position:relative;vertical-align:top;width:20px}.delete::after,.delete::before,.modal-close::after,.modal-close::before{background-color:#fff;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.delete::before,.modal-close::before{height:2px;width:50%}.delete::after,.modal-close::after{height:50%;width:2px}.delete:focus,.delete:hover,.modal-close:focus,.modal-close:hover{background-color:rgba(10,10,10,.3)}.delete:active,.modal-close:active{background-color:rgba(10,10,10,.4)}.is-small.delete,.is-small.modal-close{height:16px;max-height:16px;max-width:16px;min-height:16px;min-width:16px;width:16px}.is-medium.delete,.is-medium.modal-close{height:24px;max-height:24px;max-width:24px;min-height:24px;min-width:24px;width:24px}.is-large.delete,.is-large.modal-close{height:32px;max-height:32px;max-width:32px;min-height:32px;min-width:32px;width:32px}.button.is-loading::after,.control.is-loading::after,.loader,.select.is-loading::after{-webkit-animation:spinAround .5s infinite linear;animation:spinAround .5s infinite linear;border:2px solid #dbdbdb;border-radius:290486px;border-right-color:transparent;border-top-color:transparent;content:"";display:block;height:1em;position:relative;width:1em}.hero-video,.image.is-16by9 .has-ratio,.image.is-16by9 img,.image.is-1by1 .has-ratio,.image.is-1by1 img,.image.is-1by2 .has-ratio,.image.is-1by2 img,.image.is-1by3 .has-ratio,.image.is-1by3 img,.image.is-2by1 .has-ratio,.image.is-2by1 img,.image.is-2by3 .has-ratio,.image.is-2by3 img,.image.is-3by1 .has-ratio,.image.is-3by1 img,.image.is-3by2 .has-ratio,.image.is-3by2 img,.image.is-3by4 .has-ratio,.image.is-3by4 img,.image.is-3by5 .has-ratio,.image.is-3by5 img,.image.is-4by3 .has-ratio,.image.is-4by3 img,.image.is-4by5 .has-ratio,.image.is-4by5 img,.image.is-5by3 .has-ratio,.image.is-5by3 img,.image.is-5by4 .has-ratio,.image.is-5by4 img,.image.is-9by16 .has-ratio,.image.is-9by16 img,.image.is-square .has-ratio,.image.is-square img,.is-overlay,.modal,.modal-background{bottom:0;left:0;position:absolute;right:0;top:0}.button,.file-cta,.file-name,.input,.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous,.select select,.textarea{-moz-appearance:none;-webkit-appearance:none;align-items:center;border:1px solid transparent;border-radius:4px;box-shadow:none;display:inline-flex;font-size:1rem;height:2.5em;justify-content:flex-start;line-height:1.5;padding-bottom:calc(.5em - 1px);padding-left:calc(.75em - 1px);padding-right:calc(.75em - 1px);padding-top:calc(.5em - 1px);position:relative;vertical-align:top}.button:active,.button:focus,.file-cta:active,.file-cta:focus,.file-name:active,.file-name:focus,.input:active,.input:focus,.is-active.button,.is-active.file-cta,.is-active.file-name,.is-active.input,.is-active.pagination-ellipsis,.is-active.pagination-link,.is-active.pagination-next,.is-active.pagination-previous,.is-active.textarea,.is-focused.button,.is-focused.file-cta,.is-focused.file-name,.is-focused.input,.is-focused.pagination-ellipsis,.is-focused.pagination-link,.is-focused.pagination-next,.is-focused.pagination-previous,.is-focused.textarea,.pagination-ellipsis:active,.pagination-ellipsis:focus,.pagination-link:active,.pagination-link:focus,.pagination-next:active,.pagination-next:focus,.pagination-previous:active,.pagination-previous:focus,.select select.is-active,.select select.is-focused,.select select:active,.select select:focus,.textarea:active,.textarea:focus{outline:0}.button[disabled],.file-cta[disabled],.file-name[disabled],.input[disabled],.pagination-ellipsis[disabled],.pagination-link[disabled],.pagination-next[disabled],.pagination-previous[disabled],.select fieldset[disabled] select,.select select[disabled],.textarea[disabled],fieldset[disabled] .button,fieldset[disabled] .file-cta,fieldset[disabled] .file-name,fieldset[disabled] .input,fieldset[disabled] .pagination-ellipsis,fieldset[disabled] .pagination-link,fieldset[disabled] .pagination-next,fieldset[disabled] .pagination-previous,fieldset[disabled] .select select,fieldset[disabled] .textarea{cursor:not-allowed}/*! minireset.css v0.0.6 | MIT License | github.com/jgthms/minireset.css */blockquote,body,dd,dl,dt,fieldset,figure,h1,h2,h3,h4,h5,h6,hr,html,iframe,legend,li,ol,p,pre,textarea,ul{margin:0;padding:0}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:400}ul{list-style:none}button,input,select,textarea{margin:0}html{box-sizing:border-box}*,::after,::before{box-sizing:inherit}img,video{height:auto;max-width:100%}iframe{border:0}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}td:not([align]),th:not([align]){text-align:inherit}html{background-color:#fff;font-size:16px;-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;min-width:300px;overflow-x:hidden;overflow-y:scroll;text-rendering:optimizeLegibility;-webkit-text-size-adjust:100%;-moz-text-size-adjust:100%;-ms-text-size-adjust:100%;text-size-adjust:100%}article,aside,figure,footer,header,hgroup,section{display:block}body,button,input,select,textarea{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif}code,pre{-moz-osx-font-smoothing:auto;-webkit-font-smoothing:auto;font-family:monospace}body{color:#4a4a4a;font-size:1em;font-weight:400;line-height:1.5}a{color:#3273dc;cursor:pointer;text-decoration:none}a strong{color:currentColor}a:hover{color:#363636}code{background-color:#f5f5f5;color:#f14668;font-size:.875em;font-weight:400;padding:.25em .5em .25em}hr{background-color:#f5f5f5;border:none;display:block;height:2px;margin:1.5rem 0}img{height:auto;max-width:100%}input[type=checkbox],input[type=radio]{vertical-align:baseline}small{font-size:.875em}span{font-style:inherit;font-weight:inherit}strong{color:#363636;font-weight:700}fieldset{border:none}pre{-webkit-overflow-scrolling:touch;background-color:#f5f5f5;color:#4a4a4a;font-size:.875em;overflow-x:auto;padding:1.25rem 1.5rem;white-space:pre;word-wrap:normal}pre code{background-color:transparent;color:currentColor;font-size:1em;padding:0}table td,table th{vertical-align:top}table td:not([align]),table th:not([align]){text-align:inherit}table th{color:#363636}.box{background-color:#fff;border-radius:6px;box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);color:#4a4a4a;display:block;padding:1.25rem}a.box:focus,a.box:hover{box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px #3273dc}a.box:active{box-shadow:inset 0 1px 2px rgba(10,10,10,.2),0 0 0 1px #3273dc}.button{background-color:#fff;border-color:#dbdbdb;border-width:1px;color:#363636;cursor:pointer;justify-content:center;padding-bottom:calc(.5em - 1px);padding-left:1em;padding-right:1em;padding-top:calc(.5em - 1px);text-align:center;white-space:nowrap}.button strong{color:inherit}.button .icon,.button .icon.is-large,.button .icon.is-medium,.button .icon.is-small{height:1.5em;width:1.5em}.button .icon:first-child:not(:last-child){margin-left:calc(-.5em - 1px);margin-right:.25em}.button .icon:last-child:not(:first-child){margin-left:.25em;margin-right:calc(-.5em - 1px)}.button .icon:first-child:last-child{margin-left:calc(-.5em - 1px);margin-right:calc(-.5em - 1px)}.button.is-hovered,.button:hover{border-color:#b5b5b5;color:#363636}.button.is-focused,.button:focus{border-color:#3273dc;color:#363636}.button.is-focused:not(:active),.button:focus:not(:active){box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.button.is-active,.button:active{border-color:#4a4a4a;color:#363636}.button.is-text{background-color:transparent;border-color:transparent;color:#4a4a4a;text-decoration:underline}.button.is-text.is-focused,.button.is-text.is-hovered,.button.is-text:focus,.button.is-text:hover{background-color:#f5f5f5;color:#363636}.button.is-text.is-active,.button.is-text:active{background-color:#e8e8e8;color:#363636}.button.is-text[disabled],fieldset[disabled] .button.is-text{background-color:transparent;border-color:transparent;box-shadow:none}.button.is-white{background-color:#fff;border-color:transparent;color:#0a0a0a}.button.is-white.is-hovered,.button.is-white:hover{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.button.is-white.is-focused,.button.is-white:focus{border-color:transparent;color:#0a0a0a}.button.is-white.is-focused:not(:active),.button.is-white:focus:not(:active){box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.button.is-white.is-active,.button.is-white:active{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.button.is-white[disabled],fieldset[disabled] .button.is-white{background-color:#fff;border-color:transparent;box-shadow:none}.button.is-white.is-inverted{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted.is-hovered,.button.is-white.is-inverted:hover{background-color:#000}.button.is-white.is-inverted[disabled],fieldset[disabled] .button.is-white.is-inverted{background-color:#0a0a0a;border-color:transparent;box-shadow:none;color:#fff}.button.is-white.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-white.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-white.is-outlined.is-focused,.button.is-white.is-outlined.is-hovered,.button.is-white.is-outlined:focus,.button.is-white.is-outlined:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}.button.is-white.is-outlined.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-white.is-outlined.is-loading.is-focused::after,.button.is-white.is-outlined.is-loading.is-hovered::after,.button.is-white.is-outlined.is-loading:focus::after,.button.is-white.is-outlined.is-loading:hover::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-white.is-outlined[disabled],fieldset[disabled] .button.is-white.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-white.is-inverted.is-outlined.is-focused,.button.is-white.is-inverted.is-outlined.is-hovered,.button.is-white.is-inverted.is-outlined:focus,.button.is-white.is-inverted.is-outlined:hover{background-color:#0a0a0a;color:#fff}.button.is-white.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-white.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-white.is-inverted.is-outlined.is-loading:focus::after,.button.is-white.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-white.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-white.is-inverted.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black{background-color:#0a0a0a;border-color:transparent;color:#fff}.button.is-black.is-hovered,.button.is-black:hover{background-color:#040404;border-color:transparent;color:#fff}.button.is-black.is-focused,.button.is-black:focus{border-color:transparent;color:#fff}.button.is-black.is-focused:not(:active),.button.is-black:focus:not(:active){box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.button.is-black.is-active,.button.is-black:active{background-color:#000;border-color:transparent;color:#fff}.button.is-black[disabled],fieldset[disabled] .button.is-black{background-color:#0a0a0a;border-color:transparent;box-shadow:none}.button.is-black.is-inverted{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted.is-hovered,.button.is-black.is-inverted:hover{background-color:#f2f2f2}.button.is-black.is-inverted[disabled],fieldset[disabled] .button.is-black.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#0a0a0a}.button.is-black.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;color:#0a0a0a}.button.is-black.is-outlined.is-focused,.button.is-black.is-outlined.is-hovered,.button.is-black.is-outlined:focus,.button.is-black.is-outlined:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.button.is-black.is-outlined.is-loading::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-black.is-outlined.is-loading.is-focused::after,.button.is-black.is-outlined.is-loading.is-hovered::after,.button.is-black.is-outlined.is-loading:focus::after,.button.is-black.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-black.is-outlined[disabled],fieldset[disabled] .button.is-black.is-outlined{background-color:transparent;border-color:#0a0a0a;box-shadow:none;color:#0a0a0a}.button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-black.is-inverted.is-outlined.is-focused,.button.is-black.is-inverted.is-outlined.is-hovered,.button.is-black.is-inverted.is-outlined:focus,.button.is-black.is-inverted.is-outlined:hover{background-color:#fff;color:#0a0a0a}.button.is-black.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-black.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-black.is-inverted.is-outlined.is-loading:focus::after,.button.is-black.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #0a0a0a #0a0a0a!important}.button.is-black.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-black.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-light{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-light.is-hovered,.button.is-light:hover{background-color:#eee;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-light.is-focused,.button.is-light:focus{border-color:transparent;color:rgba(0,0,0,.7)}.button.is-light.is-focused:not(:active),.button.is-light:focus:not(:active){box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.button.is-light.is-active,.button.is-light:active{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-light[disabled],fieldset[disabled] .button.is-light{background-color:#f5f5f5;border-color:transparent;box-shadow:none}.button.is-light.is-inverted{background-color:rgba(0,0,0,.7);color:#f5f5f5}.button.is-light.is-inverted.is-hovered,.button.is-light.is-inverted:hover{background-color:rgba(0,0,0,.7)}.button.is-light.is-inverted[disabled],fieldset[disabled] .button.is-light.is-inverted{background-color:rgba(0,0,0,.7);border-color:transparent;box-shadow:none;color:#f5f5f5}.button.is-light.is-loading::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important}.button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;color:#f5f5f5}.button.is-light.is-outlined.is-focused,.button.is-light.is-outlined.is-hovered,.button.is-light.is-outlined:focus,.button.is-light.is-outlined:hover{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,.7)}.button.is-light.is-outlined.is-loading::after{border-color:transparent transparent #f5f5f5 #f5f5f5!important}.button.is-light.is-outlined.is-loading.is-focused::after,.button.is-light.is-outlined.is-loading.is-hovered::after,.button.is-light.is-outlined.is-loading:focus::after,.button.is-light.is-outlined.is-loading:hover::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important}.button.is-light.is-outlined[disabled],fieldset[disabled] .button.is-light.is-outlined{background-color:transparent;border-color:#f5f5f5;box-shadow:none;color:#f5f5f5}.button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);color:rgba(0,0,0,.7)}.button.is-light.is-inverted.is-outlined.is-focused,.button.is-light.is-inverted.is-outlined.is-hovered,.button.is-light.is-inverted.is-outlined:focus,.button.is-light.is-inverted.is-outlined:hover{background-color:rgba(0,0,0,.7);color:#f5f5f5}.button.is-light.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-light.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-light.is-inverted.is-outlined.is-loading:focus::after,.button.is-light.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #f5f5f5 #f5f5f5!important}.button.is-light.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-light.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);box-shadow:none;color:rgba(0,0,0,.7)}.button.is-dark{background-color:#363636;border-color:transparent;color:#fff}.button.is-dark.is-hovered,.button.is-dark:hover{background-color:#2f2f2f;border-color:transparent;color:#fff}.button.is-dark.is-focused,.button.is-dark:focus{border-color:transparent;color:#fff}.button.is-dark.is-focused:not(:active),.button.is-dark:focus:not(:active){box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.button.is-dark.is-active,.button.is-dark:active{background-color:#292929;border-color:transparent;color:#fff}.button.is-dark[disabled],fieldset[disabled] .button.is-dark{background-color:#363636;border-color:transparent;box-shadow:none}.button.is-dark.is-inverted{background-color:#fff;color:#363636}.button.is-dark.is-inverted.is-hovered,.button.is-dark.is-inverted:hover{background-color:#f2f2f2}.button.is-dark.is-inverted[disabled],fieldset[disabled] .button.is-dark.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#363636}.button.is-dark.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-dark.is-outlined{background-color:transparent;border-color:#363636;color:#363636}.button.is-dark.is-outlined.is-focused,.button.is-dark.is-outlined.is-hovered,.button.is-dark.is-outlined:focus,.button.is-dark.is-outlined:hover{background-color:#363636;border-color:#363636;color:#fff}.button.is-dark.is-outlined.is-loading::after{border-color:transparent transparent #363636 #363636!important}.button.is-dark.is-outlined.is-loading.is-focused::after,.button.is-dark.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-outlined.is-loading:focus::after,.button.is-dark.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-dark.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-outlined{background-color:transparent;border-color:#363636;box-shadow:none;color:#363636}.button.is-dark.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-dark.is-inverted.is-outlined.is-focused,.button.is-dark.is-inverted.is-outlined.is-hovered,.button.is-dark.is-inverted.is-outlined:focus,.button.is-dark.is-inverted.is-outlined:hover{background-color:#fff;color:#363636}.button.is-dark.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-dark.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-dark.is-inverted.is-outlined.is-loading:focus::after,.button.is-dark.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #363636 #363636!important}.button.is-dark.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-dark.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-primary{background-color:#00d1b2;border-color:transparent;color:#fff}.button.is-primary.is-hovered,.button.is-primary:hover{background-color:#00c4a7;border-color:transparent;color:#fff}.button.is-primary.is-focused,.button.is-primary:focus{border-color:transparent;color:#fff}.button.is-primary.is-focused:not(:active),.button.is-primary:focus:not(:active){box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.button.is-primary.is-active,.button.is-primary:active{background-color:#00b89c;border-color:transparent;color:#fff}.button.is-primary[disabled],fieldset[disabled] .button.is-primary{background-color:#00d1b2;border-color:transparent;box-shadow:none}.button.is-primary.is-inverted{background-color:#fff;color:#00d1b2}.button.is-primary.is-inverted.is-hovered,.button.is-primary.is-inverted:hover{background-color:#f2f2f2}.button.is-primary.is-inverted[disabled],fieldset[disabled] .button.is-primary.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#00d1b2}.button.is-primary.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-primary.is-outlined{background-color:transparent;border-color:#00d1b2;color:#00d1b2}.button.is-primary.is-outlined.is-focused,.button.is-primary.is-outlined.is-hovered,.button.is-primary.is-outlined:focus,.button.is-primary.is-outlined:hover{background-color:#00d1b2;border-color:#00d1b2;color:#fff}.button.is-primary.is-outlined.is-loading::after{border-color:transparent transparent #00d1b2 #00d1b2!important}.button.is-primary.is-outlined.is-loading.is-focused::after,.button.is-primary.is-outlined.is-loading.is-hovered::after,.button.is-primary.is-outlined.is-loading:focus::after,.button.is-primary.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-primary.is-outlined[disabled],fieldset[disabled] .button.is-primary.is-outlined{background-color:transparent;border-color:#00d1b2;box-shadow:none;color:#00d1b2}.button.is-primary.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-primary.is-inverted.is-outlined.is-focused,.button.is-primary.is-inverted.is-outlined.is-hovered,.button.is-primary.is-inverted.is-outlined:focus,.button.is-primary.is-inverted.is-outlined:hover{background-color:#fff;color:#00d1b2}.button.is-primary.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-primary.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-primary.is-inverted.is-outlined.is-loading:focus::after,.button.is-primary.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #00d1b2 #00d1b2!important}.button.is-primary.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-primary.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-primary.is-light{background-color:#ebfffc;color:#00947e}.button.is-primary.is-light.is-hovered,.button.is-primary.is-light:hover{background-color:#defffa;border-color:transparent;color:#00947e}.button.is-primary.is-light.is-active,.button.is-primary.is-light:active{background-color:#d1fff8;border-color:transparent;color:#00947e}.button.is-link{background-color:#3273dc;border-color:transparent;color:#fff}.button.is-link.is-hovered,.button.is-link:hover{background-color:#276cda;border-color:transparent;color:#fff}.button.is-link.is-focused,.button.is-link:focus{border-color:transparent;color:#fff}.button.is-link.is-focused:not(:active),.button.is-link:focus:not(:active){box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.button.is-link.is-active,.button.is-link:active{background-color:#2366d1;border-color:transparent;color:#fff}.button.is-link[disabled],fieldset[disabled] .button.is-link{background-color:#3273dc;border-color:transparent;box-shadow:none}.button.is-link.is-inverted{background-color:#fff;color:#3273dc}.button.is-link.is-inverted.is-hovered,.button.is-link.is-inverted:hover{background-color:#f2f2f2}.button.is-link.is-inverted[disabled],fieldset[disabled] .button.is-link.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#3273dc}.button.is-link.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-link.is-outlined{background-color:transparent;border-color:#3273dc;color:#3273dc}.button.is-link.is-outlined.is-focused,.button.is-link.is-outlined.is-hovered,.button.is-link.is-outlined:focus,.button.is-link.is-outlined:hover{background-color:#3273dc;border-color:#3273dc;color:#fff}.button.is-link.is-outlined.is-loading::after{border-color:transparent transparent #3273dc #3273dc!important}.button.is-link.is-outlined.is-loading.is-focused::after,.button.is-link.is-outlined.is-loading.is-hovered::after,.button.is-link.is-outlined.is-loading:focus::after,.button.is-link.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-link.is-outlined[disabled],fieldset[disabled] .button.is-link.is-outlined{background-color:transparent;border-color:#3273dc;box-shadow:none;color:#3273dc}.button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-link.is-inverted.is-outlined.is-focused,.button.is-link.is-inverted.is-outlined.is-hovered,.button.is-link.is-inverted.is-outlined:focus,.button.is-link.is-inverted.is-outlined:hover{background-color:#fff;color:#3273dc}.button.is-link.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-link.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-link.is-inverted.is-outlined.is-loading:focus::after,.button.is-link.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #3273dc #3273dc!important}.button.is-link.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-link.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-link.is-light{background-color:#eef3fc;color:#2160c4}.button.is-link.is-light.is-hovered,.button.is-link.is-light:hover{background-color:#e3ecfa;border-color:transparent;color:#2160c4}.button.is-link.is-light.is-active,.button.is-link.is-light:active{background-color:#d8e4f8;border-color:transparent;color:#2160c4}.button.is-info{background-color:#3298dc;border-color:transparent;color:#fff}.button.is-info.is-hovered,.button.is-info:hover{background-color:#2793da;border-color:transparent;color:#fff}.button.is-info.is-focused,.button.is-info:focus{border-color:transparent;color:#fff}.button.is-info.is-focused:not(:active),.button.is-info:focus:not(:active){box-shadow:0 0 0 .125em rgba(50,152,220,.25)}.button.is-info.is-active,.button.is-info:active{background-color:#238cd1;border-color:transparent;color:#fff}.button.is-info[disabled],fieldset[disabled] .button.is-info{background-color:#3298dc;border-color:transparent;box-shadow:none}.button.is-info.is-inverted{background-color:#fff;color:#3298dc}.button.is-info.is-inverted.is-hovered,.button.is-info.is-inverted:hover{background-color:#f2f2f2}.button.is-info.is-inverted[disabled],fieldset[disabled] .button.is-info.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#3298dc}.button.is-info.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-info.is-outlined{background-color:transparent;border-color:#3298dc;color:#3298dc}.button.is-info.is-outlined.is-focused,.button.is-info.is-outlined.is-hovered,.button.is-info.is-outlined:focus,.button.is-info.is-outlined:hover{background-color:#3298dc;border-color:#3298dc;color:#fff}.button.is-info.is-outlined.is-loading::after{border-color:transparent transparent #3298dc #3298dc!important}.button.is-info.is-outlined.is-loading.is-focused::after,.button.is-info.is-outlined.is-loading.is-hovered::after,.button.is-info.is-outlined.is-loading:focus::after,.button.is-info.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-info.is-outlined[disabled],fieldset[disabled] .button.is-info.is-outlined{background-color:transparent;border-color:#3298dc;box-shadow:none;color:#3298dc}.button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-info.is-inverted.is-outlined.is-focused,.button.is-info.is-inverted.is-outlined.is-hovered,.button.is-info.is-inverted.is-outlined:focus,.button.is-info.is-inverted.is-outlined:hover{background-color:#fff;color:#3298dc}.button.is-info.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-info.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-info.is-inverted.is-outlined.is-loading:focus::after,.button.is-info.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #3298dc #3298dc!important}.button.is-info.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-info.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-info.is-light{background-color:#eef6fc;color:#1d72aa}.button.is-info.is-light.is-hovered,.button.is-info.is-light:hover{background-color:#e3f1fa;border-color:transparent;color:#1d72aa}.button.is-info.is-light.is-active,.button.is-info.is-light:active{background-color:#d8ebf8;border-color:transparent;color:#1d72aa}.button.is-success{background-color:#48c774;border-color:transparent;color:#fff}.button.is-success.is-hovered,.button.is-success:hover{background-color:#3ec46d;border-color:transparent;color:#fff}.button.is-success.is-focused,.button.is-success:focus{border-color:transparent;color:#fff}.button.is-success.is-focused:not(:active),.button.is-success:focus:not(:active){box-shadow:0 0 0 .125em rgba(72,199,116,.25)}.button.is-success.is-active,.button.is-success:active{background-color:#3abb67;border-color:transparent;color:#fff}.button.is-success[disabled],fieldset[disabled] .button.is-success{background-color:#48c774;border-color:transparent;box-shadow:none}.button.is-success.is-inverted{background-color:#fff;color:#48c774}.button.is-success.is-inverted.is-hovered,.button.is-success.is-inverted:hover{background-color:#f2f2f2}.button.is-success.is-inverted[disabled],fieldset[disabled] .button.is-success.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#48c774}.button.is-success.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-success.is-outlined{background-color:transparent;border-color:#48c774;color:#48c774}.button.is-success.is-outlined.is-focused,.button.is-success.is-outlined.is-hovered,.button.is-success.is-outlined:focus,.button.is-success.is-outlined:hover{background-color:#48c774;border-color:#48c774;color:#fff}.button.is-success.is-outlined.is-loading::after{border-color:transparent transparent #48c774 #48c774!important}.button.is-success.is-outlined.is-loading.is-focused::after,.button.is-success.is-outlined.is-loading.is-hovered::after,.button.is-success.is-outlined.is-loading:focus::after,.button.is-success.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-success.is-outlined[disabled],fieldset[disabled] .button.is-success.is-outlined{background-color:transparent;border-color:#48c774;box-shadow:none;color:#48c774}.button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-success.is-inverted.is-outlined.is-focused,.button.is-success.is-inverted.is-outlined.is-hovered,.button.is-success.is-inverted.is-outlined:focus,.button.is-success.is-inverted.is-outlined:hover{background-color:#fff;color:#48c774}.button.is-success.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-success.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-success.is-inverted.is-outlined.is-loading:focus::after,.button.is-success.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #48c774 #48c774!important}.button.is-success.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-success.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-success.is-light{background-color:#effaf3;color:#257942}.button.is-success.is-light.is-hovered,.button.is-success.is-light:hover{background-color:#e6f7ec;border-color:transparent;color:#257942}.button.is-success.is-light.is-active,.button.is-success.is-light:active{background-color:#dcf4e4;border-color:transparent;color:#257942}.button.is-warning{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-hovered,.button.is-warning:hover{background-color:#ffdb4a;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-focused,.button.is-warning:focus{border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning.is-focused:not(:active),.button.is-warning:focus:not(:active){box-shadow:0 0 0 .125em rgba(255,221,87,.25)}.button.is-warning.is-active,.button.is-warning:active{background-color:#ffd83d;border-color:transparent;color:rgba(0,0,0,.7)}.button.is-warning[disabled],fieldset[disabled] .button.is-warning{background-color:#ffdd57;border-color:transparent;box-shadow:none}.button.is-warning.is-inverted{background-color:rgba(0,0,0,.7);color:#ffdd57}.button.is-warning.is-inverted.is-hovered,.button.is-warning.is-inverted:hover{background-color:rgba(0,0,0,.7)}.button.is-warning.is-inverted[disabled],fieldset[disabled] .button.is-warning.is-inverted{background-color:rgba(0,0,0,.7);border-color:transparent;box-shadow:none;color:#ffdd57}.button.is-warning.is-loading::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important}.button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;color:#ffdd57}.button.is-warning.is-outlined.is-focused,.button.is-warning.is-outlined.is-hovered,.button.is-warning.is-outlined:focus,.button.is-warning.is-outlined:hover{background-color:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,.7)}.button.is-warning.is-outlined.is-loading::after{border-color:transparent transparent #ffdd57 #ffdd57!important}.button.is-warning.is-outlined.is-loading.is-focused::after,.button.is-warning.is-outlined.is-loading.is-hovered::after,.button.is-warning.is-outlined.is-loading:focus::after,.button.is-warning.is-outlined.is-loading:hover::after{border-color:transparent transparent rgba(0,0,0,.7) rgba(0,0,0,.7)!important}.button.is-warning.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-outlined{background-color:transparent;border-color:#ffdd57;box-shadow:none;color:#ffdd57}.button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);color:rgba(0,0,0,.7)}.button.is-warning.is-inverted.is-outlined.is-focused,.button.is-warning.is-inverted.is-outlined.is-hovered,.button.is-warning.is-inverted.is-outlined:focus,.button.is-warning.is-inverted.is-outlined:hover{background-color:rgba(0,0,0,.7);color:#ffdd57}.button.is-warning.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-warning.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-warning.is-inverted.is-outlined.is-loading:focus::after,.button.is-warning.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #ffdd57 #ffdd57!important}.button.is-warning.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-warning.is-inverted.is-outlined{background-color:transparent;border-color:rgba(0,0,0,.7);box-shadow:none;color:rgba(0,0,0,.7)}.button.is-warning.is-light{background-color:#fffbeb;color:#947600}.button.is-warning.is-light.is-hovered,.button.is-warning.is-light:hover{background-color:#fff8de;border-color:transparent;color:#947600}.button.is-warning.is-light.is-active,.button.is-warning.is-light:active{background-color:#fff6d1;border-color:transparent;color:#947600}.button.is-danger{background-color:#f14668;border-color:transparent;color:#fff}.button.is-danger.is-hovered,.button.is-danger:hover{background-color:#f03a5f;border-color:transparent;color:#fff}.button.is-danger.is-focused,.button.is-danger:focus{border-color:transparent;color:#fff}.button.is-danger.is-focused:not(:active),.button.is-danger:focus:not(:active){box-shadow:0 0 0 .125em rgba(241,70,104,.25)}.button.is-danger.is-active,.button.is-danger:active{background-color:#ef2e55;border-color:transparent;color:#fff}.button.is-danger[disabled],fieldset[disabled] .button.is-danger{background-color:#f14668;border-color:transparent;box-shadow:none}.button.is-danger.is-inverted{background-color:#fff;color:#f14668}.button.is-danger.is-inverted.is-hovered,.button.is-danger.is-inverted:hover{background-color:#f2f2f2}.button.is-danger.is-inverted[disabled],fieldset[disabled] .button.is-danger.is-inverted{background-color:#fff;border-color:transparent;box-shadow:none;color:#f14668}.button.is-danger.is-loading::after{border-color:transparent transparent #fff #fff!important}.button.is-danger.is-outlined{background-color:transparent;border-color:#f14668;color:#f14668}.button.is-danger.is-outlined.is-focused,.button.is-danger.is-outlined.is-hovered,.button.is-danger.is-outlined:focus,.button.is-danger.is-outlined:hover{background-color:#f14668;border-color:#f14668;color:#fff}.button.is-danger.is-outlined.is-loading::after{border-color:transparent transparent #f14668 #f14668!important}.button.is-danger.is-outlined.is-loading.is-focused::after,.button.is-danger.is-outlined.is-loading.is-hovered::after,.button.is-danger.is-outlined.is-loading:focus::after,.button.is-danger.is-outlined.is-loading:hover::after{border-color:transparent transparent #fff #fff!important}.button.is-danger.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-outlined{background-color:transparent;border-color:#f14668;box-shadow:none;color:#f14668}.button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;color:#fff}.button.is-danger.is-inverted.is-outlined.is-focused,.button.is-danger.is-inverted.is-outlined.is-hovered,.button.is-danger.is-inverted.is-outlined:focus,.button.is-danger.is-inverted.is-outlined:hover{background-color:#fff;color:#f14668}.button.is-danger.is-inverted.is-outlined.is-loading.is-focused::after,.button.is-danger.is-inverted.is-outlined.is-loading.is-hovered::after,.button.is-danger.is-inverted.is-outlined.is-loading:focus::after,.button.is-danger.is-inverted.is-outlined.is-loading:hover::after{border-color:transparent transparent #f14668 #f14668!important}.button.is-danger.is-inverted.is-outlined[disabled],fieldset[disabled] .button.is-danger.is-inverted.is-outlined{background-color:transparent;border-color:#fff;box-shadow:none;color:#fff}.button.is-danger.is-light{background-color:#feecf0;color:#cc0f35}.button.is-danger.is-light.is-hovered,.button.is-danger.is-light:hover{background-color:#fde0e6;border-color:transparent;color:#cc0f35}.button.is-danger.is-light.is-active,.button.is-danger.is-light:active{background-color:#fcd4dc;border-color:transparent;color:#cc0f35}.button.is-small{border-radius:2px;font-size:.75rem}.button.is-normal{font-size:1rem}.button.is-medium{font-size:1.25rem}.button.is-large{font-size:1.5rem}.button[disabled],fieldset[disabled] .button{background-color:#fff;border-color:#dbdbdb;box-shadow:none;opacity:.5}.button.is-fullwidth{display:flex;width:100%}.button.is-loading{color:transparent!important;pointer-events:none}.button.is-loading::after{position:absolute;left:calc(50% - (1em / 2));top:calc(50% - (1em / 2));position:absolute!important}.button.is-static{background-color:#f5f5f5;border-color:#dbdbdb;color:#7a7a7a;box-shadow:none;pointer-events:none}.button.is-rounded{border-radius:290486px;padding-left:calc(1em + .25em);padding-right:calc(1em + .25em)}.buttons{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.buttons .button{margin-bottom:.5rem}.buttons .button:not(:last-child):not(.is-fullwidth){margin-right:.5rem}.buttons:last-child{margin-bottom:-.5rem}.buttons:not(:last-child){margin-bottom:1rem}.buttons.are-small .button:not(.is-normal):not(.is-medium):not(.is-large){border-radius:2px;font-size:.75rem}.buttons.are-medium .button:not(.is-small):not(.is-normal):not(.is-large){font-size:1.25rem}.buttons.are-large .button:not(.is-small):not(.is-normal):not(.is-medium){font-size:1.5rem}.buttons.has-addons .button:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.buttons.has-addons .button:not(:last-child){border-bottom-right-radius:0;border-top-right-radius:0;margin-right:-1px}.buttons.has-addons .button:last-child{margin-right:0}.buttons.has-addons .button.is-hovered,.buttons.has-addons .button:hover{z-index:2}.buttons.has-addons .button.is-active,.buttons.has-addons .button.is-focused,.buttons.has-addons .button.is-selected,.buttons.has-addons .button:active,.buttons.has-addons .button:focus{z-index:3}.buttons.has-addons .button.is-active:hover,.buttons.has-addons .button.is-focused:hover,.buttons.has-addons .button.is-selected:hover,.buttons.has-addons .button:active:hover,.buttons.has-addons .button:focus:hover{z-index:4}.buttons.has-addons .button.is-expanded{flex-grow:1;flex-shrink:1}.buttons.is-centered{justify-content:center}.buttons.is-centered:not(.has-addons) .button:not(.is-fullwidth){margin-left:.25rem;margin-right:.25rem}.buttons.is-right{justify-content:flex-end}.buttons.is-right:not(.has-addons) .button:not(.is-fullwidth){margin-left:.25rem;margin-right:.25rem}.container{flex-grow:1;margin:0 auto;position:relative;width:auto}.container.is-fluid{max-width:none;padding-left:32px;padding-right:32px;width:100%}@media screen and (min-width:1024px){.container{max-width:960px}}@media screen and (max-width:1215px){.container.is-widescreen{max-width:1152px}}@media screen and (max-width:1407px){.container.is-fullhd{max-width:1344px}}@media screen and (min-width:1216px){.container{max-width:1152px}}@media screen and (min-width:1408px){.container{max-width:1344px}}.content li+li{margin-top:.25em}.content blockquote:not(:last-child),.content dl:not(:last-child),.content ol:not(:last-child),.content p:not(:last-child),.content pre:not(:last-child),.content table:not(:last-child),.content ul:not(:last-child){margin-bottom:1em}.content h1,.content h2,.content h3,.content h4,.content h5,.content h6{color:#363636;font-weight:600;line-height:1.125}.content h1{font-size:2em;margin-bottom:.5em}.content h1:not(:first-child){margin-top:1em}.content h2{font-size:1.75em;margin-bottom:.5714em}.content h2:not(:first-child){margin-top:1.1428em}.content h3{font-size:1.5em;margin-bottom:.6666em}.content h3:not(:first-child){margin-top:1.3333em}.content h4{font-size:1.25em;margin-bottom:.8em}.content h5{font-size:1.125em;margin-bottom:.8888em}.content h6{font-size:1em;margin-bottom:1em}.content blockquote{background-color:#f5f5f5;border-left:5px solid #dbdbdb;padding:1.25em 1.5em}.content ol{list-style-position:outside;margin-left:2em;margin-top:1em}.content ol:not([type]){list-style-type:decimal}.content ol:not([type]).is-lower-alpha{list-style-type:lower-alpha}.content ol:not([type]).is-lower-roman{list-style-type:lower-roman}.content ol:not([type]).is-upper-alpha{list-style-type:upper-alpha}.content ol:not([type]).is-upper-roman{list-style-type:upper-roman}.content ul{list-style:disc outside;margin-left:2em;margin-top:1em}.content ul ul{list-style-type:circle;margin-top:.5em}.content ul ul ul{list-style-type:square}.content dd{margin-left:2em}.content figure{margin-left:2em;margin-right:2em;text-align:center}.content figure:not(:first-child){margin-top:2em}.content figure:not(:last-child){margin-bottom:2em}.content figure img{display:inline-block}.content figure figcaption{font-style:italic}.content pre{-webkit-overflow-scrolling:touch;overflow-x:auto;padding:1.25em 1.5em;white-space:pre;word-wrap:normal}.content sub,.content sup{font-size:75%}.content table{width:100%}.content table td,.content table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:.5em .75em;vertical-align:top}.content table th{color:#363636}.content table th:not([align]){text-align:inherit}.content table thead td,.content table thead th{border-width:0 0 2px;color:#363636}.content table tfoot td,.content table tfoot th{border-width:2px 0 0;color:#363636}.content table tbody tr:last-child td,.content table tbody tr:last-child th{border-bottom-width:0}.content .tabs li+li{margin-top:0}.content.is-small{font-size:.75rem}.content.is-medium{font-size:1.25rem}.content.is-large{font-size:1.5rem}.icon{align-items:center;display:inline-flex;justify-content:center;height:1.5rem;width:1.5rem}.icon.is-small{height:1rem;width:1rem}.icon.is-medium{height:2rem;width:2rem}.icon.is-large{height:3rem;width:3rem}.image{display:block;position:relative}.image img{display:block;height:auto;width:100%}.image img.is-rounded{border-radius:290486px}.image.is-fullwidth{width:100%}.image.is-16by9 .has-ratio,.image.is-16by9 img,.image.is-1by1 .has-ratio,.image.is-1by1 img,.image.is-1by2 .has-ratio,.image.is-1by2 img,.image.is-1by3 .has-ratio,.image.is-1by3 img,.image.is-2by1 .has-ratio,.image.is-2by1 img,.image.is-2by3 .has-ratio,.image.is-2by3 img,.image.is-3by1 .has-ratio,.image.is-3by1 img,.image.is-3by2 .has-ratio,.image.is-3by2 img,.image.is-3by4 .has-ratio,.image.is-3by4 img,.image.is-3by5 .has-ratio,.image.is-3by5 img,.image.is-4by3 .has-ratio,.image.is-4by3 img,.image.is-4by5 .has-ratio,.image.is-4by5 img,.image.is-5by3 .has-ratio,.image.is-5by3 img,.image.is-5by4 .has-ratio,.image.is-5by4 img,.image.is-9by16 .has-ratio,.image.is-9by16 img,.image.is-square .has-ratio,.image.is-square img{height:100%;width:100%}.image.is-1by1,.image.is-square{padding-top:100%}.image.is-5by4{padding-top:80%}.image.is-4by3{padding-top:75%}.image.is-3by2{padding-top:66.6666%}.image.is-5by3{padding-top:60%}.image.is-16by9{padding-top:56.25%}.image.is-2by1{padding-top:50%}.image.is-3by1{padding-top:33.3333%}.image.is-4by5{padding-top:125%}.image.is-3by4{padding-top:133.3333%}.image.is-2by3{padding-top:150%}.image.is-3by5{padding-top:166.6666%}.image.is-9by16{padding-top:177.7777%}.image.is-1by2{padding-top:200%}.image.is-1by3{padding-top:300%}.image.is-16x16{height:16px;width:16px}.image.is-24x24{height:24px;width:24px}.image.is-32x32{height:32px;width:32px}.image.is-48x48{height:48px;width:48px}.image.is-64x64{height:64px;width:64px}.image.is-96x96{height:96px;width:96px}.image.is-128x128{height:128px;width:128px}.notification{background-color:#f5f5f5;border-radius:4px;position:relative;padding:1.25rem 2.5rem 1.25rem 1.5rem}.notification a:not(.button):not(.dropdown-item){color:currentColor;text-decoration:underline}.notification strong{color:currentColor}.notification code,.notification pre{background:#fff}.notification pre code{background:0 0}.notification>.delete{right:.5rem;position:absolute;top:.5rem}.notification .content,.notification .subtitle,.notification .title{color:currentColor}.notification.is-white{background-color:#fff;color:#0a0a0a}.notification.is-black{background-color:#0a0a0a;color:#fff}.notification.is-light{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.notification.is-dark{background-color:#363636;color:#fff}.notification.is-primary{background-color:#00d1b2;color:#fff}.notification.is-primary.is-light{background-color:#ebfffc;color:#00947e}.notification.is-link{background-color:#3273dc;color:#fff}.notification.is-link.is-light{background-color:#eef3fc;color:#2160c4}.notification.is-info{background-color:#3298dc;color:#fff}.notification.is-info.is-light{background-color:#eef6fc;color:#1d72aa}.notification.is-success{background-color:#48c774;color:#fff}.notification.is-success.is-light{background-color:#effaf3;color:#257942}.notification.is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.notification.is-warning.is-light{background-color:#fffbeb;color:#947600}.notification.is-danger{background-color:#f14668;color:#fff}.notification.is-danger.is-light{background-color:#feecf0;color:#cc0f35}.progress{-moz-appearance:none;-webkit-appearance:none;border:none;border-radius:290486px;display:block;height:1rem;overflow:hidden;padding:0;width:100%}.progress::-webkit-progress-bar{background-color:#ededed}.progress::-webkit-progress-value{background-color:#4a4a4a}.progress::-moz-progress-bar{background-color:#4a4a4a}.progress::-ms-fill{background-color:#4a4a4a;border:none}.progress.is-white::-webkit-progress-value{background-color:#fff}.progress.is-white::-moz-progress-bar{background-color:#fff}.progress.is-white::-ms-fill{background-color:#fff}.progress.is-white:indeterminate{background-image:linear-gradient(to right,#fff 30%,#ededed 30%)}.progress.is-black::-webkit-progress-value{background-color:#0a0a0a}.progress.is-black::-moz-progress-bar{background-color:#0a0a0a}.progress.is-black::-ms-fill{background-color:#0a0a0a}.progress.is-black:indeterminate{background-image:linear-gradient(to right,#0a0a0a 30%,#ededed 30%)}.progress.is-light::-webkit-progress-value{background-color:#f5f5f5}.progress.is-light::-moz-progress-bar{background-color:#f5f5f5}.progress.is-light::-ms-fill{background-color:#f5f5f5}.progress.is-light:indeterminate{background-image:linear-gradient(to right,#f5f5f5 30%,#ededed 30%)}.progress.is-dark::-webkit-progress-value{background-color:#363636}.progress.is-dark::-moz-progress-bar{background-color:#363636}.progress.is-dark::-ms-fill{background-color:#363636}.progress.is-dark:indeterminate{background-image:linear-gradient(to right,#363636 30%,#ededed 30%)}.progress.is-primary::-webkit-progress-value{background-color:#00d1b2}.progress.is-primary::-moz-progress-bar{background-color:#00d1b2}.progress.is-primary::-ms-fill{background-color:#00d1b2}.progress.is-primary:indeterminate{background-image:linear-gradient(to right,#00d1b2 30%,#ededed 30%)}.progress.is-link::-webkit-progress-value{background-color:#3273dc}.progress.is-link::-moz-progress-bar{background-color:#3273dc}.progress.is-link::-ms-fill{background-color:#3273dc}.progress.is-link:indeterminate{background-image:linear-gradient(to right,#3273dc 30%,#ededed 30%)}.progress.is-info::-webkit-progress-value{background-color:#3298dc}.progress.is-info::-moz-progress-bar{background-color:#3298dc}.progress.is-info::-ms-fill{background-color:#3298dc}.progress.is-info:indeterminate{background-image:linear-gradient(to right,#3298dc 30%,#ededed 30%)}.progress.is-success::-webkit-progress-value{background-color:#48c774}.progress.is-success::-moz-progress-bar{background-color:#48c774}.progress.is-success::-ms-fill{background-color:#48c774}.progress.is-success:indeterminate{background-image:linear-gradient(to right,#48c774 30%,#ededed 30%)}.progress.is-warning::-webkit-progress-value{background-color:#ffdd57}.progress.is-warning::-moz-progress-bar{background-color:#ffdd57}.progress.is-warning::-ms-fill{background-color:#ffdd57}.progress.is-warning:indeterminate{background-image:linear-gradient(to right,#ffdd57 30%,#ededed 30%)}.progress.is-danger::-webkit-progress-value{background-color:#f14668}.progress.is-danger::-moz-progress-bar{background-color:#f14668}.progress.is-danger::-ms-fill{background-color:#f14668}.progress.is-danger:indeterminate{background-image:linear-gradient(to right,#f14668 30%,#ededed 30%)}.progress:indeterminate{-webkit-animation-duration:1.5s;animation-duration:1.5s;-webkit-animation-iteration-count:infinite;animation-iteration-count:infinite;-webkit-animation-name:moveIndeterminate;animation-name:moveIndeterminate;-webkit-animation-timing-function:linear;animation-timing-function:linear;background-color:#ededed;background-image:linear-gradient(to right,#4a4a4a 30%,#ededed 30%);background-position:top left;background-repeat:no-repeat;background-size:150% 150%}.progress:indeterminate::-webkit-progress-bar{background-color:transparent}.progress:indeterminate::-moz-progress-bar{background-color:transparent}.progress.is-small{height:.75rem}.progress.is-medium{height:1.25rem}.progress.is-large{height:1.5rem}@-webkit-keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}@keyframes moveIndeterminate{from{background-position:200% 0}to{background-position:-200% 0}}.table{background-color:#fff;color:#363636}.table td,.table th{border:1px solid #dbdbdb;border-width:0 0 1px;padding:.5em .75em;vertical-align:top}.table td.is-white,.table th.is-white{background-color:#fff;border-color:#fff;color:#0a0a0a}.table td.is-black,.table th.is-black{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.table td.is-light,.table th.is-light{background-color:#f5f5f5;border-color:#f5f5f5;color:rgba(0,0,0,.7)}.table td.is-dark,.table th.is-dark{background-color:#363636;border-color:#363636;color:#fff}.table td.is-primary,.table th.is-primary{background-color:#00d1b2;border-color:#00d1b2;color:#fff}.table td.is-link,.table th.is-link{background-color:#3273dc;border-color:#3273dc;color:#fff}.table td.is-info,.table th.is-info{background-color:#3298dc;border-color:#3298dc;color:#fff}.table td.is-success,.table th.is-success{background-color:#48c774;border-color:#48c774;color:#fff}.table td.is-warning,.table th.is-warning{background-color:#ffdd57;border-color:#ffdd57;color:rgba(0,0,0,.7)}.table td.is-danger,.table th.is-danger{background-color:#f14668;border-color:#f14668;color:#fff}.table td.is-narrow,.table th.is-narrow{white-space:nowrap;width:1%}.table td.is-selected,.table th.is-selected{background-color:#00d1b2;color:#fff}.table td.is-selected a,.table td.is-selected strong,.table th.is-selected a,.table th.is-selected strong{color:currentColor}.table td.is-vcentered,.table th.is-vcentered{vertical-align:middle}.table th{color:#363636}.table th:not([align]){text-align:inherit}.table tr.is-selected{background-color:#00d1b2;color:#fff}.table tr.is-selected a,.table tr.is-selected strong{color:currentColor}.table tr.is-selected td,.table tr.is-selected th{border-color:#fff;color:currentColor}.table thead{background-color:transparent}.table thead td,.table thead th{border-width:0 0 2px;color:#363636}.table tfoot{background-color:transparent}.table tfoot td,.table tfoot th{border-width:2px 0 0;color:#363636}.table tbody{background-color:transparent}.table tbody tr:last-child td,.table tbody tr:last-child th{border-bottom-width:0}.table.is-bordered td,.table.is-bordered th{border-width:1px}.table.is-bordered tr:last-child td,.table.is-bordered tr:last-child th{border-bottom-width:1px}.table.is-fullwidth{width:100%}.table.is-hoverable tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover{background-color:#fafafa}.table.is-hoverable.is-striped tbody tr:not(.is-selected):hover:nth-child(even){background-color:#f5f5f5}.table.is-narrow td,.table.is-narrow th{padding:.25em .5em}.table.is-striped tbody tr:not(.is-selected):nth-child(even){background-color:#fafafa}.table-container{-webkit-overflow-scrolling:touch;overflow:auto;overflow-y:hidden;max-width:100%}.tags{align-items:center;display:flex;flex-wrap:wrap;justify-content:flex-start}.tags .tag{margin-bottom:.5rem}.tags .tag:not(:last-child){margin-right:.5rem}.tags:last-child{margin-bottom:-.5rem}.tags:not(:last-child){margin-bottom:1rem}.tags.are-medium .tag:not(.is-normal):not(.is-large){font-size:1rem}.tags.are-large .tag:not(.is-normal):not(.is-medium){font-size:1.25rem}.tags.is-centered{justify-content:center}.tags.is-centered .tag{margin-right:.25rem;margin-left:.25rem}.tags.is-right{justify-content:flex-end}.tags.is-right .tag:not(:first-child){margin-left:.5rem}.tags.is-right .tag:not(:last-child){margin-right:0}.tags.has-addons .tag{margin-right:0}.tags.has-addons .tag:not(:first-child){margin-left:0;border-top-left-radius:0;border-bottom-left-radius:0}.tags.has-addons .tag:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.tag:not(body){align-items:center;background-color:#f5f5f5;border-radius:4px;color:#4a4a4a;display:inline-flex;font-size:.75rem;height:2em;justify-content:center;line-height:1.5;padding-left:.75em;padding-right:.75em;white-space:nowrap}.tag:not(body) .delete{margin-left:.25rem;margin-right:-.375rem}.tag:not(body).is-white{background-color:#fff;color:#0a0a0a}.tag:not(body).is-black{background-color:#0a0a0a;color:#fff}.tag:not(body).is-light{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.tag:not(body).is-dark{background-color:#363636;color:#fff}.tag:not(body).is-primary{background-color:#00d1b2;color:#fff}.tag:not(body).is-primary.is-light{background-color:#ebfffc;color:#00947e}.tag:not(body).is-link{background-color:#3273dc;color:#fff}.tag:not(body).is-link.is-light{background-color:#eef3fc;color:#2160c4}.tag:not(body).is-info{background-color:#3298dc;color:#fff}.tag:not(body).is-info.is-light{background-color:#eef6fc;color:#1d72aa}.tag:not(body).is-success{background-color:#48c774;color:#fff}.tag:not(body).is-success.is-light{background-color:#effaf3;color:#257942}.tag:not(body).is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.tag:not(body).is-warning.is-light{background-color:#fffbeb;color:#947600}.tag:not(body).is-danger{background-color:#f14668;color:#fff}.tag:not(body).is-danger.is-light{background-color:#feecf0;color:#cc0f35}.tag:not(body).is-normal{font-size:.75rem}.tag:not(body).is-medium{font-size:1rem}.tag:not(body).is-large{font-size:1.25rem}.tag:not(body) .icon:first-child:not(:last-child){margin-left:-.375em;margin-right:.1875em}.tag:not(body) .icon:last-child:not(:first-child){margin-left:.1875em;margin-right:-.375em}.tag:not(body) .icon:first-child:last-child{margin-left:-.375em;margin-right:-.375em}.tag:not(body).is-delete{margin-left:1px;padding:0;position:relative;width:2em}.tag:not(body).is-delete::after,.tag:not(body).is-delete::before{background-color:currentColor;content:"";display:block;left:50%;position:absolute;top:50%;transform:translateX(-50%) translateY(-50%) rotate(45deg);transform-origin:center center}.tag:not(body).is-delete::before{height:1px;width:50%}.tag:not(body).is-delete::after{height:50%;width:1px}.tag:not(body).is-delete:focus,.tag:not(body).is-delete:hover{background-color:#e8e8e8}.tag:not(body).is-delete:active{background-color:#dbdbdb}.tag:not(body).is-rounded{border-radius:290486px}a.tag:hover{text-decoration:underline}.subtitle,.title{word-break:break-word}.subtitle em,.subtitle span,.title em,.title span{font-weight:inherit}.subtitle sub,.title sub{font-size:.75em}.subtitle sup,.title sup{font-size:.75em}.subtitle .tag,.title .tag{vertical-align:middle}.title{color:#363636;font-size:2rem;font-weight:600;line-height:1.125}.title strong{color:inherit;font-weight:inherit}.title+.highlight{margin-top:-.75rem}.title:not(.is-spaced)+.subtitle{margin-top:-1.25rem}.title.is-1{font-size:3rem}.title.is-2{font-size:2.5rem}.title.is-3{font-size:2rem}.title.is-4{font-size:1.5rem}.title.is-5{font-size:1.25rem}.title.is-6{font-size:1rem}.title.is-7{font-size:.75rem}.subtitle{color:#4a4a4a;font-size:1.25rem;font-weight:400;line-height:1.25}.subtitle strong{color:#363636;font-weight:600}.subtitle:not(.is-spaced)+.title{margin-top:-1.25rem}.subtitle.is-1{font-size:3rem}.subtitle.is-2{font-size:2.5rem}.subtitle.is-3{font-size:2rem}.subtitle.is-4{font-size:1.5rem}.subtitle.is-5{font-size:1.25rem}.subtitle.is-6{font-size:1rem}.subtitle.is-7{font-size:.75rem}.heading{display:block;font-size:11px;letter-spacing:1px;margin-bottom:5px;text-transform:uppercase}.highlight{font-weight:400;max-width:100%;overflow:hidden;padding:0}.highlight pre{overflow:auto;max-width:100%}.number{align-items:center;background-color:#f5f5f5;border-radius:290486px;display:inline-flex;font-size:1.25rem;height:2em;justify-content:center;margin-right:1.5rem;min-width:2.5em;padding:.25rem .5rem;text-align:center;vertical-align:top}.input,.select select,.textarea{background-color:#fff;border-color:#dbdbdb;border-radius:4px;color:#363636}.input::-moz-placeholder,.select select::-moz-placeholder,.textarea::-moz-placeholder{color:rgba(54,54,54,.3)}.input::-webkit-input-placeholder,.select select::-webkit-input-placeholder,.textarea::-webkit-input-placeholder{color:rgba(54,54,54,.3)}.input:-moz-placeholder,.select select:-moz-placeholder,.textarea:-moz-placeholder{color:rgba(54,54,54,.3)}.input:-ms-input-placeholder,.select select:-ms-input-placeholder,.textarea:-ms-input-placeholder{color:rgba(54,54,54,.3)}.input:hover,.is-hovered.input,.is-hovered.textarea,.select select.is-hovered,.select select:hover,.textarea:hover{border-color:#b5b5b5}.input:active,.input:focus,.is-active.input,.is-active.textarea,.is-focused.input,.is-focused.textarea,.select select.is-active,.select select.is-focused,.select select:active,.select select:focus,.textarea:active,.textarea:focus{border-color:#3273dc;box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.input[disabled],.select fieldset[disabled] select,.select select[disabled],.textarea[disabled],fieldset[disabled] .input,fieldset[disabled] .select select,fieldset[disabled] .textarea{background-color:#f5f5f5;border-color:#f5f5f5;box-shadow:none;color:#7a7a7a}.input[disabled]::-moz-placeholder,.select fieldset[disabled] select::-moz-placeholder,.select select[disabled]::-moz-placeholder,.textarea[disabled]::-moz-placeholder,fieldset[disabled] .input::-moz-placeholder,fieldset[disabled] .select select::-moz-placeholder,fieldset[disabled] .textarea::-moz-placeholder{color:rgba(122,122,122,.3)}.input[disabled]::-webkit-input-placeholder,.select fieldset[disabled] select::-webkit-input-placeholder,.select select[disabled]::-webkit-input-placeholder,.textarea[disabled]::-webkit-input-placeholder,fieldset[disabled] .input::-webkit-input-placeholder,fieldset[disabled] .select select::-webkit-input-placeholder,fieldset[disabled] .textarea::-webkit-input-placeholder{color:rgba(122,122,122,.3)}.input[disabled]:-moz-placeholder,.select fieldset[disabled] select:-moz-placeholder,.select select[disabled]:-moz-placeholder,.textarea[disabled]:-moz-placeholder,fieldset[disabled] .input:-moz-placeholder,fieldset[disabled] .select select:-moz-placeholder,fieldset[disabled] .textarea:-moz-placeholder{color:rgba(122,122,122,.3)}.input[disabled]:-ms-input-placeholder,.select fieldset[disabled] select:-ms-input-placeholder,.select select[disabled]:-ms-input-placeholder,.textarea[disabled]:-ms-input-placeholder,fieldset[disabled] .input:-ms-input-placeholder,fieldset[disabled] .select select:-ms-input-placeholder,fieldset[disabled] .textarea:-ms-input-placeholder{color:rgba(122,122,122,.3)}.input,.textarea{box-shadow:inset 0 .0625em .125em rgba(10,10,10,.05);max-width:100%;width:100%}.input[readonly],.textarea[readonly]{box-shadow:none}.is-white.input,.is-white.textarea{border-color:#fff}.is-white.input:active,.is-white.input:focus,.is-white.is-active.input,.is-white.is-active.textarea,.is-white.is-focused.input,.is-white.is-focused.textarea,.is-white.textarea:active,.is-white.textarea:focus{box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.is-black.input,.is-black.textarea{border-color:#0a0a0a}.is-black.input:active,.is-black.input:focus,.is-black.is-active.input,.is-black.is-active.textarea,.is-black.is-focused.input,.is-black.is-focused.textarea,.is-black.textarea:active,.is-black.textarea:focus{box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.is-light.input,.is-light.textarea{border-color:#f5f5f5}.is-light.input:active,.is-light.input:focus,.is-light.is-active.input,.is-light.is-active.textarea,.is-light.is-focused.input,.is-light.is-focused.textarea,.is-light.textarea:active,.is-light.textarea:focus{box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.is-dark.input,.is-dark.textarea{border-color:#363636}.is-dark.input:active,.is-dark.input:focus,.is-dark.is-active.input,.is-dark.is-active.textarea,.is-dark.is-focused.input,.is-dark.is-focused.textarea,.is-dark.textarea:active,.is-dark.textarea:focus{box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.is-primary.input,.is-primary.textarea{border-color:#00d1b2}.is-primary.input:active,.is-primary.input:focus,.is-primary.is-active.input,.is-primary.is-active.textarea,.is-primary.is-focused.input,.is-primary.is-focused.textarea,.is-primary.textarea:active,.is-primary.textarea:focus{box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.is-link.input,.is-link.textarea{border-color:#3273dc}.is-link.input:active,.is-link.input:focus,.is-link.is-active.input,.is-link.is-active.textarea,.is-link.is-focused.input,.is-link.is-focused.textarea,.is-link.textarea:active,.is-link.textarea:focus{box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.is-info.input,.is-info.textarea{border-color:#3298dc}.is-info.input:active,.is-info.input:focus,.is-info.is-active.input,.is-info.is-active.textarea,.is-info.is-focused.input,.is-info.is-focused.textarea,.is-info.textarea:active,.is-info.textarea:focus{box-shadow:0 0 0 .125em rgba(50,152,220,.25)}.is-success.input,.is-success.textarea{border-color:#48c774}.is-success.input:active,.is-success.input:focus,.is-success.is-active.input,.is-success.is-active.textarea,.is-success.is-focused.input,.is-success.is-focused.textarea,.is-success.textarea:active,.is-success.textarea:focus{box-shadow:0 0 0 .125em rgba(72,199,116,.25)}.is-warning.input,.is-warning.textarea{border-color:#ffdd57}.is-warning.input:active,.is-warning.input:focus,.is-warning.is-active.input,.is-warning.is-active.textarea,.is-warning.is-focused.input,.is-warning.is-focused.textarea,.is-warning.textarea:active,.is-warning.textarea:focus{box-shadow:0 0 0 .125em rgba(255,221,87,.25)}.is-danger.input,.is-danger.textarea{border-color:#f14668}.is-danger.input:active,.is-danger.input:focus,.is-danger.is-active.input,.is-danger.is-active.textarea,.is-danger.is-focused.input,.is-danger.is-focused.textarea,.is-danger.textarea:active,.is-danger.textarea:focus{box-shadow:0 0 0 .125em rgba(241,70,104,.25)}.is-small.input,.is-small.textarea{border-radius:2px;font-size:.75rem}.is-medium.input,.is-medium.textarea{font-size:1.25rem}.is-large.input,.is-large.textarea{font-size:1.5rem}.is-fullwidth.input,.is-fullwidth.textarea{display:block;width:100%}.is-inline.input,.is-inline.textarea{display:inline;width:auto}.input.is-rounded{border-radius:290486px;padding-left:calc(calc(.75em - 1px) + .375em);padding-right:calc(calc(.75em - 1px) + .375em)}.input.is-static{background-color:transparent;border-color:transparent;box-shadow:none;padding-left:0;padding-right:0}.textarea{display:block;max-width:100%;min-width:100%;padding:calc(.75em - 1px);resize:vertical}.textarea:not([rows]){max-height:40em;min-height:8em}.textarea[rows]{height:initial}.textarea.has-fixed-size{resize:none}.checkbox,.radio{cursor:pointer;display:inline-block;line-height:1.25;position:relative}.checkbox input,.radio input{cursor:pointer}.checkbox:hover,.radio:hover{color:#363636}.checkbox[disabled],.radio[disabled],fieldset[disabled] .checkbox,fieldset[disabled] .radio{color:#7a7a7a;cursor:not-allowed}.radio+.radio{margin-left:.5em}.select{display:inline-block;max-width:100%;position:relative;vertical-align:top}.select:not(.is-multiple){height:2.5em}.select:not(.is-multiple):not(.is-loading)::after{border-color:#3273dc;right:1.125em;z-index:4}.select.is-rounded select{border-radius:290486px;padding-left:1em}.select select{cursor:pointer;display:block;font-size:1em;max-width:100%;outline:0}.select select::-ms-expand{display:none}.select select[disabled]:hover,fieldset[disabled] .select select:hover{border-color:#f5f5f5}.select select:not([multiple]){padding-right:2.5em}.select select[multiple]{height:auto;padding:0}.select select[multiple] option{padding:.5em 1em}.select:not(.is-multiple):not(.is-loading):hover::after{border-color:#363636}.select.is-white:not(:hover)::after{border-color:#fff}.select.is-white select{border-color:#fff}.select.is-white select.is-hovered,.select.is-white select:hover{border-color:#f2f2f2}.select.is-white select.is-active,.select.is-white select.is-focused,.select.is-white select:active,.select.is-white select:focus{box-shadow:0 0 0 .125em rgba(255,255,255,.25)}.select.is-black:not(:hover)::after{border-color:#0a0a0a}.select.is-black select{border-color:#0a0a0a}.select.is-black select.is-hovered,.select.is-black select:hover{border-color:#000}.select.is-black select.is-active,.select.is-black select.is-focused,.select.is-black select:active,.select.is-black select:focus{box-shadow:0 0 0 .125em rgba(10,10,10,.25)}.select.is-light:not(:hover)::after{border-color:#f5f5f5}.select.is-light select{border-color:#f5f5f5}.select.is-light select.is-hovered,.select.is-light select:hover{border-color:#e8e8e8}.select.is-light select.is-active,.select.is-light select.is-focused,.select.is-light select:active,.select.is-light select:focus{box-shadow:0 0 0 .125em rgba(245,245,245,.25)}.select.is-dark:not(:hover)::after{border-color:#363636}.select.is-dark select{border-color:#363636}.select.is-dark select.is-hovered,.select.is-dark select:hover{border-color:#292929}.select.is-dark select.is-active,.select.is-dark select.is-focused,.select.is-dark select:active,.select.is-dark select:focus{box-shadow:0 0 0 .125em rgba(54,54,54,.25)}.select.is-primary:not(:hover)::after{border-color:#00d1b2}.select.is-primary select{border-color:#00d1b2}.select.is-primary select.is-hovered,.select.is-primary select:hover{border-color:#00b89c}.select.is-primary select.is-active,.select.is-primary select.is-focused,.select.is-primary select:active,.select.is-primary select:focus{box-shadow:0 0 0 .125em rgba(0,209,178,.25)}.select.is-link:not(:hover)::after{border-color:#3273dc}.select.is-link select{border-color:#3273dc}.select.is-link select.is-hovered,.select.is-link select:hover{border-color:#2366d1}.select.is-link select.is-active,.select.is-link select.is-focused,.select.is-link select:active,.select.is-link select:focus{box-shadow:0 0 0 .125em rgba(50,115,220,.25)}.select.is-info:not(:hover)::after{border-color:#3298dc}.select.is-info select{border-color:#3298dc}.select.is-info select.is-hovered,.select.is-info select:hover{border-color:#238cd1}.select.is-info select.is-active,.select.is-info select.is-focused,.select.is-info select:active,.select.is-info select:focus{box-shadow:0 0 0 .125em rgba(50,152,220,.25)}.select.is-success:not(:hover)::after{border-color:#48c774}.select.is-success select{border-color:#48c774}.select.is-success select.is-hovered,.select.is-success select:hover{border-color:#3abb67}.select.is-success select.is-active,.select.is-success select.is-focused,.select.is-success select:active,.select.is-success select:focus{box-shadow:0 0 0 .125em rgba(72,199,116,.25)}.select.is-warning:not(:hover)::after{border-color:#ffdd57}.select.is-warning select{border-color:#ffdd57}.select.is-warning select.is-hovered,.select.is-warning select:hover{border-color:#ffd83d}.select.is-warning select.is-active,.select.is-warning select.is-focused,.select.is-warning select:active,.select.is-warning select:focus{box-shadow:0 0 0 .125em rgba(255,221,87,.25)}.select.is-danger:not(:hover)::after{border-color:#f14668}.select.is-danger select{border-color:#f14668}.select.is-danger select.is-hovered,.select.is-danger select:hover{border-color:#ef2e55}.select.is-danger select.is-active,.select.is-danger select.is-focused,.select.is-danger select:active,.select.is-danger select:focus{box-shadow:0 0 0 .125em rgba(241,70,104,.25)}.select.is-small{border-radius:2px;font-size:.75rem}.select.is-medium{font-size:1.25rem}.select.is-large{font-size:1.5rem}.select.is-disabled::after{border-color:#7a7a7a}.select.is-fullwidth{width:100%}.select.is-fullwidth select{width:100%}.select.is-loading::after{margin-top:0;position:absolute;right:.625em;top:.625em;transform:none}.select.is-loading.is-small:after{font-size:.75rem}.select.is-loading.is-medium:after{font-size:1.25rem}.select.is-loading.is-large:after{font-size:1.5rem}.file{align-items:stretch;display:flex;justify-content:flex-start;position:relative}.file.is-white .file-cta{background-color:#fff;border-color:transparent;color:#0a0a0a}.file.is-white.is-hovered .file-cta,.file.is-white:hover .file-cta{background-color:#f9f9f9;border-color:transparent;color:#0a0a0a}.file.is-white.is-focused .file-cta,.file.is-white:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(255,255,255,.25);color:#0a0a0a}.file.is-white.is-active .file-cta,.file.is-white:active .file-cta{background-color:#f2f2f2;border-color:transparent;color:#0a0a0a}.file.is-black .file-cta{background-color:#0a0a0a;border-color:transparent;color:#fff}.file.is-black.is-hovered .file-cta,.file.is-black:hover .file-cta{background-color:#040404;border-color:transparent;color:#fff}.file.is-black.is-focused .file-cta,.file.is-black:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(10,10,10,.25);color:#fff}.file.is-black.is-active .file-cta,.file.is-black:active .file-cta{background-color:#000;border-color:transparent;color:#fff}.file.is-light .file-cta{background-color:#f5f5f5;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-light.is-hovered .file-cta,.file.is-light:hover .file-cta{background-color:#eee;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-light.is-focused .file-cta,.file.is-light:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(245,245,245,.25);color:rgba(0,0,0,.7)}.file.is-light.is-active .file-cta,.file.is-light:active .file-cta{background-color:#e8e8e8;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-dark .file-cta{background-color:#363636;border-color:transparent;color:#fff}.file.is-dark.is-hovered .file-cta,.file.is-dark:hover .file-cta{background-color:#2f2f2f;border-color:transparent;color:#fff}.file.is-dark.is-focused .file-cta,.file.is-dark:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(54,54,54,.25);color:#fff}.file.is-dark.is-active .file-cta,.file.is-dark:active .file-cta{background-color:#292929;border-color:transparent;color:#fff}.file.is-primary .file-cta{background-color:#00d1b2;border-color:transparent;color:#fff}.file.is-primary.is-hovered .file-cta,.file.is-primary:hover .file-cta{background-color:#00c4a7;border-color:transparent;color:#fff}.file.is-primary.is-focused .file-cta,.file.is-primary:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(0,209,178,.25);color:#fff}.file.is-primary.is-active .file-cta,.file.is-primary:active .file-cta{background-color:#00b89c;border-color:transparent;color:#fff}.file.is-link .file-cta{background-color:#3273dc;border-color:transparent;color:#fff}.file.is-link.is-hovered .file-cta,.file.is-link:hover .file-cta{background-color:#276cda;border-color:transparent;color:#fff}.file.is-link.is-focused .file-cta,.file.is-link:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(50,115,220,.25);color:#fff}.file.is-link.is-active .file-cta,.file.is-link:active .file-cta{background-color:#2366d1;border-color:transparent;color:#fff}.file.is-info .file-cta{background-color:#3298dc;border-color:transparent;color:#fff}.file.is-info.is-hovered .file-cta,.file.is-info:hover .file-cta{background-color:#2793da;border-color:transparent;color:#fff}.file.is-info.is-focused .file-cta,.file.is-info:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(50,152,220,.25);color:#fff}.file.is-info.is-active .file-cta,.file.is-info:active .file-cta{background-color:#238cd1;border-color:transparent;color:#fff}.file.is-success .file-cta{background-color:#48c774;border-color:transparent;color:#fff}.file.is-success.is-hovered .file-cta,.file.is-success:hover .file-cta{background-color:#3ec46d;border-color:transparent;color:#fff}.file.is-success.is-focused .file-cta,.file.is-success:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(72,199,116,.25);color:#fff}.file.is-success.is-active .file-cta,.file.is-success:active .file-cta{background-color:#3abb67;border-color:transparent;color:#fff}.file.is-warning .file-cta{background-color:#ffdd57;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-warning.is-hovered .file-cta,.file.is-warning:hover .file-cta{background-color:#ffdb4a;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-warning.is-focused .file-cta,.file.is-warning:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(255,221,87,.25);color:rgba(0,0,0,.7)}.file.is-warning.is-active .file-cta,.file.is-warning:active .file-cta{background-color:#ffd83d;border-color:transparent;color:rgba(0,0,0,.7)}.file.is-danger .file-cta{background-color:#f14668;border-color:transparent;color:#fff}.file.is-danger.is-hovered .file-cta,.file.is-danger:hover .file-cta{background-color:#f03a5f;border-color:transparent;color:#fff}.file.is-danger.is-focused .file-cta,.file.is-danger:focus .file-cta{border-color:transparent;box-shadow:0 0 .5em rgba(241,70,104,.25);color:#fff}.file.is-danger.is-active .file-cta,.file.is-danger:active .file-cta{background-color:#ef2e55;border-color:transparent;color:#fff}.file.is-small{font-size:.75rem}.file.is-medium{font-size:1.25rem}.file.is-medium .file-icon .fa{font-size:21px}.file.is-large{font-size:1.5rem}.file.is-large .file-icon .fa{font-size:28px}.file.has-name .file-cta{border-bottom-right-radius:0;border-top-right-radius:0}.file.has-name .file-name{border-bottom-left-radius:0;border-top-left-radius:0}.file.has-name.is-empty .file-cta{border-radius:4px}.file.has-name.is-empty .file-name{display:none}.file.is-boxed .file-label{flex-direction:column}.file.is-boxed .file-cta{flex-direction:column;height:auto;padding:1em 3em}.file.is-boxed .file-name{border-width:0 1px 1px}.file.is-boxed .file-icon{height:1.5em;width:1.5em}.file.is-boxed .file-icon .fa{font-size:21px}.file.is-boxed.is-small .file-icon .fa{font-size:14px}.file.is-boxed.is-medium .file-icon .fa{font-size:28px}.file.is-boxed.is-large .file-icon .fa{font-size:35px}.file.is-boxed.has-name .file-cta{border-radius:4px 4px 0 0}.file.is-boxed.has-name .file-name{border-radius:0 0 4px 4px;border-width:0 1px 1px}.file.is-centered{justify-content:center}.file.is-fullwidth .file-label{width:100%}.file.is-fullwidth .file-name{flex-grow:1;max-width:none}.file.is-right{justify-content:flex-end}.file.is-right .file-cta{border-radius:0 4px 4px 0}.file.is-right .file-name{border-radius:4px 0 0 4px;border-width:1px 0 1px 1px;order:-1}.file-label{align-items:stretch;display:flex;cursor:pointer;justify-content:flex-start;overflow:hidden;position:relative}.file-label:hover .file-cta{background-color:#eee;color:#363636}.file-label:hover .file-name{border-color:#d5d5d5}.file-label:active .file-cta{background-color:#e8e8e8;color:#363636}.file-label:active .file-name{border-color:#cfcfcf}.file-input{height:100%;left:0;opacity:0;outline:0;position:absolute;top:0;width:100%}.file-cta,.file-name{border-color:#dbdbdb;border-radius:4px;font-size:1em;padding-left:1em;padding-right:1em;white-space:nowrap}.file-cta{background-color:#f5f5f5;color:#4a4a4a}.file-name{border-color:#dbdbdb;border-style:solid;border-width:1px 1px 1px 0;display:block;max-width:16em;overflow:hidden;text-align:inherit;text-overflow:ellipsis}.file-icon{align-items:center;display:flex;height:1em;justify-content:center;margin-right:.5em;width:1em}.file-icon .fa{font-size:14px}.label{color:#363636;display:block;font-size:1rem;font-weight:700}.label:not(:last-child){margin-bottom:.5em}.label.is-small{font-size:.75rem}.label.is-medium{font-size:1.25rem}.label.is-large{font-size:1.5rem}.help{display:block;font-size:.75rem;margin-top:.25rem}.help.is-white{color:#fff}.help.is-black{color:#0a0a0a}.help.is-light{color:#f5f5f5}.help.is-dark{color:#363636}.help.is-primary{color:#00d1b2}.help.is-link{color:#3273dc}.help.is-info{color:#3298dc}.help.is-success{color:#48c774}.help.is-warning{color:#ffdd57}.help.is-danger{color:#f14668}.field:not(:last-child){margin-bottom:.75rem}.field.has-addons{display:flex;justify-content:flex-start}.field.has-addons .control:not(:last-child){margin-right:-1px}.field.has-addons .control:not(:first-child):not(:last-child) .button,.field.has-addons .control:not(:first-child):not(:last-child) .input,.field.has-addons .control:not(:first-child):not(:last-child) .select select{border-radius:0}.field.has-addons .control:first-child:not(:only-child) .button,.field.has-addons .control:first-child:not(:only-child) .input,.field.has-addons .control:first-child:not(:only-child) .select select{border-bottom-right-radius:0;border-top-right-radius:0}.field.has-addons .control:last-child:not(:only-child) .button,.field.has-addons .control:last-child:not(:only-child) .input,.field.has-addons .control:last-child:not(:only-child) .select select{border-bottom-left-radius:0;border-top-left-radius:0}.field.has-addons .control .button:not([disabled]).is-hovered,.field.has-addons .control .button:not([disabled]):hover,.field.has-addons .control .input:not([disabled]).is-hovered,.field.has-addons .control .input:not([disabled]):hover,.field.has-addons .control .select select:not([disabled]).is-hovered,.field.has-addons .control .select select:not([disabled]):hover{z-index:2}.field.has-addons .control .button:not([disabled]).is-active,.field.has-addons .control .button:not([disabled]).is-focused,.field.has-addons .control .button:not([disabled]):active,.field.has-addons .control .button:not([disabled]):focus,.field.has-addons .control .input:not([disabled]).is-active,.field.has-addons .control .input:not([disabled]).is-focused,.field.has-addons .control .input:not([disabled]):active,.field.has-addons .control .input:not([disabled]):focus,.field.has-addons .control .select select:not([disabled]).is-active,.field.has-addons .control .select select:not([disabled]).is-focused,.field.has-addons .control .select select:not([disabled]):active,.field.has-addons .control .select select:not([disabled]):focus{z-index:3}.field.has-addons .control .button:not([disabled]).is-active:hover,.field.has-addons .control .button:not([disabled]).is-focused:hover,.field.has-addons .control .button:not([disabled]):active:hover,.field.has-addons .control .button:not([disabled]):focus:hover,.field.has-addons .control .input:not([disabled]).is-active:hover,.field.has-addons .control .input:not([disabled]).is-focused:hover,.field.has-addons .control .input:not([disabled]):active:hover,.field.has-addons .control .input:not([disabled]):focus:hover,.field.has-addons .control .select select:not([disabled]).is-active:hover,.field.has-addons .control .select select:not([disabled]).is-focused:hover,.field.has-addons .control .select select:not([disabled]):active:hover,.field.has-addons .control .select select:not([disabled]):focus:hover{z-index:4}.field.has-addons .control.is-expanded{flex-grow:1;flex-shrink:1}.field.has-addons.has-addons-centered{justify-content:center}.field.has-addons.has-addons-right{justify-content:flex-end}.field.has-addons.has-addons-fullwidth .control{flex-grow:1;flex-shrink:0}.field.is-grouped{display:flex;justify-content:flex-start}.field.is-grouped>.control{flex-shrink:0}.field.is-grouped>.control:not(:last-child){margin-bottom:0;margin-right:.75rem}.field.is-grouped>.control.is-expanded{flex-grow:1;flex-shrink:1}.field.is-grouped.is-grouped-centered{justify-content:center}.field.is-grouped.is-grouped-right{justify-content:flex-end}.field.is-grouped.is-grouped-multiline{flex-wrap:wrap}.field.is-grouped.is-grouped-multiline>.control:last-child,.field.is-grouped.is-grouped-multiline>.control:not(:last-child){margin-bottom:.75rem}.field.is-grouped.is-grouped-multiline:last-child{margin-bottom:-.75rem}.field.is-grouped.is-grouped-multiline:not(:last-child){margin-bottom:0}@media screen and (min-width:769px),print{.field.is-horizontal{display:flex}}.field-label .label{font-size:inherit}@media screen and (max-width:768px){.field-label{margin-bottom:.5rem}}@media screen and (min-width:769px),print{.field-label{flex-basis:0;flex-grow:1;flex-shrink:0;margin-right:1.5rem;text-align:right}.field-label.is-small{font-size:.75rem;padding-top:.375em}.field-label.is-normal{padding-top:.375em}.field-label.is-medium{font-size:1.25rem;padding-top:.375em}.field-label.is-large{font-size:1.5rem;padding-top:.375em}}.field-body .field .field{margin-bottom:0}@media screen and (min-width:769px),print{.field-body{display:flex;flex-basis:0;flex-grow:5;flex-shrink:1}.field-body .field{margin-bottom:0}.field-body>.field{flex-shrink:1}.field-body>.field:not(.is-narrow){flex-grow:1}.field-body>.field:not(:last-child){margin-right:.75rem}}.control{box-sizing:border-box;clear:both;font-size:1rem;position:relative;text-align:inherit}.control.has-icons-left .input:focus~.icon,.control.has-icons-left .select:focus~.icon,.control.has-icons-right .input:focus~.icon,.control.has-icons-right .select:focus~.icon{color:#4a4a4a}.control.has-icons-left .input.is-small~.icon,.control.has-icons-left .select.is-small~.icon,.control.has-icons-right .input.is-small~.icon,.control.has-icons-right .select.is-small~.icon{font-size:.75rem}.control.has-icons-left .input.is-medium~.icon,.control.has-icons-left .select.is-medium~.icon,.control.has-icons-right .input.is-medium~.icon,.control.has-icons-right .select.is-medium~.icon{font-size:1.25rem}.control.has-icons-left .input.is-large~.icon,.control.has-icons-left .select.is-large~.icon,.control.has-icons-right .input.is-large~.icon,.control.has-icons-right .select.is-large~.icon{font-size:1.5rem}.control.has-icons-left .icon,.control.has-icons-right .icon{color:#dbdbdb;height:2.5em;pointer-events:none;position:absolute;top:0;width:2.5em;z-index:4}.control.has-icons-left .input,.control.has-icons-left .select select{padding-left:2.5em}.control.has-icons-left .icon.is-left{left:0}.control.has-icons-right .input,.control.has-icons-right .select select{padding-right:2.5em}.control.has-icons-right .icon.is-right{right:0}.control.is-loading::after{position:absolute!important;right:.625em;top:.625em;z-index:4}.control.is-loading.is-small:after{font-size:.75rem}.control.is-loading.is-medium:after{font-size:1.25rem}.control.is-loading.is-large:after{font-size:1.5rem}.breadcrumb{font-size:1rem;white-space:nowrap}.breadcrumb a{align-items:center;color:#3273dc;display:flex;justify-content:center;padding:0 .75em}.breadcrumb a:hover{color:#363636}.breadcrumb li{align-items:center;display:flex}.breadcrumb li:first-child a{padding-left:0}.breadcrumb li.is-active a{color:#363636;cursor:default;pointer-events:none}.breadcrumb li+li::before{color:#b5b5b5;content:"\0002f"}.breadcrumb ol,.breadcrumb ul{align-items:flex-start;display:flex;flex-wrap:wrap;justify-content:flex-start}.breadcrumb .icon:first-child{margin-right:.5em}.breadcrumb .icon:last-child{margin-left:.5em}.breadcrumb.is-centered ol,.breadcrumb.is-centered ul{justify-content:center}.breadcrumb.is-right ol,.breadcrumb.is-right ul{justify-content:flex-end}.breadcrumb.is-small{font-size:.75rem}.breadcrumb.is-medium{font-size:1.25rem}.breadcrumb.is-large{font-size:1.5rem}.breadcrumb.has-arrow-separator li+li::before{content:"\02192"}.breadcrumb.has-bullet-separator li+li::before{content:"\02022"}.breadcrumb.has-dot-separator li+li::before{content:"\000b7"}.breadcrumb.has-succeeds-separator li+li::before{content:"\0227B"}.card{background-color:#fff;box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);color:#4a4a4a;max-width:100%;position:relative}.card-header{background-color:transparent;align-items:stretch;box-shadow:0 .125em .25em rgba(10,10,10,.1);display:flex}.card-header-title{align-items:center;color:#363636;display:flex;flex-grow:1;font-weight:700;padding:.75rem 1rem}.card-header-title.is-centered{justify-content:center}.card-header-icon{align-items:center;cursor:pointer;display:flex;justify-content:center;padding:.75rem 1rem}.card-image{display:block;position:relative}.card-content{background-color:transparent;padding:1.5rem}.card-footer{background-color:transparent;border-top:1px solid #ededed;align-items:stretch;display:flex}.card-footer-item{align-items:center;display:flex;flex-basis:0;flex-grow:1;flex-shrink:0;justify-content:center;padding:.75rem}.card-footer-item:not(:last-child){border-right:1px solid #ededed}.card .media:not(:last-child){margin-bottom:1.5rem}.dropdown{display:inline-flex;position:relative;vertical-align:top}.dropdown.is-active .dropdown-menu,.dropdown.is-hoverable:hover .dropdown-menu{display:block}.dropdown.is-right .dropdown-menu{left:auto;right:0}.dropdown.is-up .dropdown-menu{bottom:100%;padding-bottom:4px;padding-top:initial;top:auto}.dropdown-menu{display:none;left:0;min-width:12rem;padding-top:4px;position:absolute;top:100%;z-index:20}.dropdown-content{background-color:#fff;border-radius:4px;box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);padding-bottom:.5rem;padding-top:.5rem}.dropdown-item{color:#4a4a4a;display:block;font-size:.875rem;line-height:1.5;padding:.375rem 1rem;position:relative}a.dropdown-item,button.dropdown-item{padding-right:3rem;text-align:inherit;white-space:nowrap;width:100%}a.dropdown-item:hover,button.dropdown-item:hover{background-color:#f5f5f5;color:#0a0a0a}a.dropdown-item.is-active,button.dropdown-item.is-active{background-color:#3273dc;color:#fff}.dropdown-divider{background-color:#ededed;border:none;display:block;height:1px;margin:.5rem 0}.level{align-items:center;justify-content:space-between}.level code{border-radius:4px}.level img{display:inline-block;vertical-align:top}.level.is-mobile{display:flex}.level.is-mobile .level-left,.level.is-mobile .level-right{display:flex}.level.is-mobile .level-left+.level-right{margin-top:0}.level.is-mobile .level-item:not(:last-child){margin-bottom:0;margin-right:.75rem}.level.is-mobile .level-item:not(.is-narrow){flex-grow:1}@media screen and (min-width:769px),print{.level{display:flex}.level>.level-item:not(.is-narrow){flex-grow:1}}.level-item{align-items:center;display:flex;flex-basis:auto;flex-grow:0;flex-shrink:0;justify-content:center}.level-item .subtitle,.level-item .title{margin-bottom:0}@media screen and (max-width:768px){.level-item:not(:last-child){margin-bottom:.75rem}}.level-left,.level-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.level-left .level-item.is-flexible,.level-right .level-item.is-flexible{flex-grow:1}@media screen and (min-width:769px),print{.level-left .level-item:not(:last-child),.level-right .level-item:not(:last-child){margin-right:.75rem}}.level-left{align-items:center;justify-content:flex-start}@media screen and (max-width:768px){.level-left+.level-right{margin-top:1.5rem}}@media screen and (min-width:769px),print{.level-left{display:flex}}.level-right{align-items:center;justify-content:flex-end}@media screen and (min-width:769px),print{.level-right{display:flex}}.media{align-items:flex-start;display:flex;text-align:inherit}.media .content:not(:last-child){margin-bottom:.75rem}.media .media{border-top:1px solid rgba(219,219,219,.5);display:flex;padding-top:.75rem}.media .media .content:not(:last-child),.media .media .control:not(:last-child){margin-bottom:.5rem}.media .media .media{padding-top:.5rem}.media .media .media+.media{margin-top:.5rem}.media+.media{border-top:1px solid rgba(219,219,219,.5);margin-top:1rem;padding-top:1rem}.media.is-large+.media{margin-top:1.5rem;padding-top:1.5rem}.media-left,.media-right{flex-basis:auto;flex-grow:0;flex-shrink:0}.media-left{margin-right:1rem}.media-right{margin-left:1rem}.media-content{flex-basis:auto;flex-grow:1;flex-shrink:1;text-align:inherit}@media screen and (max-width:768px){.media-content{overflow-x:auto}}.menu{font-size:1rem}.menu.is-small{font-size:.75rem}.menu.is-medium{font-size:1.25rem}.menu.is-large{font-size:1.5rem}.menu-list{line-height:1.25}.menu-list a{border-radius:2px;color:#4a4a4a;display:block;padding:.5em .75em}.menu-list a:hover{background-color:#f5f5f5;color:#363636}.menu-list a.is-active{background-color:#3273dc;color:#fff}.menu-list li ul{border-left:1px solid #dbdbdb;margin:.75em;padding-left:.75em}.menu-label{color:#7a7a7a;font-size:.75em;letter-spacing:.1em;text-transform:uppercase}.menu-label:not(:first-child){margin-top:1em}.menu-label:not(:last-child){margin-bottom:1em}.message{background-color:#f5f5f5;border-radius:4px;font-size:1rem}.message strong{color:currentColor}.message a:not(.button):not(.tag):not(.dropdown-item){color:currentColor;text-decoration:underline}.message.is-small{font-size:.75rem}.message.is-medium{font-size:1.25rem}.message.is-large{font-size:1.5rem}.message.is-white{background-color:#fff}.message.is-white .message-header{background-color:#fff;color:#0a0a0a}.message.is-white .message-body{border-color:#fff}.message.is-black{background-color:#fafafa}.message.is-black .message-header{background-color:#0a0a0a;color:#fff}.message.is-black .message-body{border-color:#0a0a0a}.message.is-light{background-color:#fafafa}.message.is-light .message-header{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.message.is-light .message-body{border-color:#f5f5f5}.message.is-dark{background-color:#fafafa}.message.is-dark .message-header{background-color:#363636;color:#fff}.message.is-dark .message-body{border-color:#363636}.message.is-primary{background-color:#ebfffc}.message.is-primary .message-header{background-color:#00d1b2;color:#fff}.message.is-primary .message-body{border-color:#00d1b2;color:#00947e}.message.is-link{background-color:#eef3fc}.message.is-link .message-header{background-color:#3273dc;color:#fff}.message.is-link .message-body{border-color:#3273dc;color:#2160c4}.message.is-info{background-color:#eef6fc}.message.is-info .message-header{background-color:#3298dc;color:#fff}.message.is-info .message-body{border-color:#3298dc;color:#1d72aa}.message.is-success{background-color:#effaf3}.message.is-success .message-header{background-color:#48c774;color:#fff}.message.is-success .message-body{border-color:#48c774;color:#257942}.message.is-warning{background-color:#fffbeb}.message.is-warning .message-header{background-color:#ffdd57;color:rgba(0,0,0,.7)}.message.is-warning .message-body{border-color:#ffdd57;color:#947600}.message.is-danger{background-color:#feecf0}.message.is-danger .message-header{background-color:#f14668;color:#fff}.message.is-danger .message-body{border-color:#f14668;color:#cc0f35}.message-header{align-items:center;background-color:#4a4a4a;border-radius:4px 4px 0 0;color:#fff;display:flex;font-weight:700;justify-content:space-between;line-height:1.25;padding:.75em 1em;position:relative}.message-header .delete{flex-grow:0;flex-shrink:0;margin-left:.75em}.message-header+.message-body{border-width:0;border-top-left-radius:0;border-top-right-radius:0}.message-body{border-color:#dbdbdb;border-radius:4px;border-style:solid;border-width:0 0 0 4px;color:#4a4a4a;padding:1.25em 1.5em}.message-body code,.message-body pre{background-color:#fff}.message-body pre code{background-color:transparent}.modal{align-items:center;display:none;flex-direction:column;justify-content:center;overflow:hidden;position:fixed;z-index:40}.modal.is-active{display:flex}.modal-background{background-color:rgba(10,10,10,.86)}.modal-card,.modal-content{margin:0 20px;max-height:calc(100vh - 160px);overflow:auto;position:relative;width:100%}@media screen and (min-width:769px),print{.modal-card,.modal-content{margin:0 auto;max-height:calc(100vh - 40px);width:640px}}.modal-close{background:0 0;height:40px;position:fixed;right:20px;top:20px;width:40px}.modal-card{display:flex;flex-direction:column;max-height:calc(100vh - 40px);overflow:hidden;-ms-overflow-y:visible}.modal-card-foot,.modal-card-head{align-items:center;background-color:#f5f5f5;display:flex;flex-shrink:0;justify-content:flex-start;padding:20px;position:relative}.modal-card-head{border-bottom:1px solid #dbdbdb;border-top-left-radius:6px;border-top-right-radius:6px}.modal-card-title{color:#363636;flex-grow:1;flex-shrink:0;font-size:1.5rem;line-height:1}.modal-card-foot{border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:1px solid #dbdbdb}.modal-card-foot .button:not(:last-child){margin-right:.5em}.modal-card-body{-webkit-overflow-scrolling:touch;background-color:#fff;flex-grow:1;flex-shrink:1;overflow:auto;padding:20px}.navbar{background-color:#fff;min-height:3.25rem;position:relative;z-index:30}.navbar.is-white{background-color:#fff;color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link,.navbar.is-white .navbar-brand>.navbar-item{color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link.is-active,.navbar.is-white .navbar-brand .navbar-link:focus,.navbar.is-white .navbar-brand .navbar-link:hover,.navbar.is-white .navbar-brand>a.navbar-item.is-active,.navbar.is-white .navbar-brand>a.navbar-item:focus,.navbar.is-white .navbar-brand>a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-brand .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-burger{color:#0a0a0a}@media screen and (min-width:1024px){.navbar.is-white .navbar-end .navbar-link,.navbar.is-white .navbar-end>.navbar-item,.navbar.is-white .navbar-start .navbar-link,.navbar.is-white .navbar-start>.navbar-item{color:#0a0a0a}.navbar.is-white .navbar-end .navbar-link.is-active,.navbar.is-white .navbar-end .navbar-link:focus,.navbar.is-white .navbar-end .navbar-link:hover,.navbar.is-white .navbar-end>a.navbar-item.is-active,.navbar.is-white .navbar-end>a.navbar-item:focus,.navbar.is-white .navbar-end>a.navbar-item:hover,.navbar.is-white .navbar-start .navbar-link.is-active,.navbar.is-white .navbar-start .navbar-link:focus,.navbar.is-white .navbar-start .navbar-link:hover,.navbar.is-white .navbar-start>a.navbar-item.is-active,.navbar.is-white .navbar-start>a.navbar-item:focus,.navbar.is-white .navbar-start>a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-end .navbar-link::after,.navbar.is-white .navbar-start .navbar-link::after{border-color:#0a0a0a}.navbar.is-white .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-white .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-white .navbar-item.has-dropdown:hover .navbar-link{background-color:#f2f2f2;color:#0a0a0a}.navbar.is-white .navbar-dropdown a.navbar-item.is-active{background-color:#fff;color:#0a0a0a}}.navbar.is-black{background-color:#0a0a0a;color:#fff}.navbar.is-black .navbar-brand .navbar-link,.navbar.is-black .navbar-brand>.navbar-item{color:#fff}.navbar.is-black .navbar-brand .navbar-link.is-active,.navbar.is-black .navbar-brand .navbar-link:focus,.navbar.is-black .navbar-brand .navbar-link:hover,.navbar.is-black .navbar-brand>a.navbar-item.is-active,.navbar.is-black .navbar-brand>a.navbar-item:focus,.navbar.is-black .navbar-brand>a.navbar-item:hover{background-color:#000;color:#fff}.navbar.is-black .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-black .navbar-end .navbar-link,.navbar.is-black .navbar-end>.navbar-item,.navbar.is-black .navbar-start .navbar-link,.navbar.is-black .navbar-start>.navbar-item{color:#fff}.navbar.is-black .navbar-end .navbar-link.is-active,.navbar.is-black .navbar-end .navbar-link:focus,.navbar.is-black .navbar-end .navbar-link:hover,.navbar.is-black .navbar-end>a.navbar-item.is-active,.navbar.is-black .navbar-end>a.navbar-item:focus,.navbar.is-black .navbar-end>a.navbar-item:hover,.navbar.is-black .navbar-start .navbar-link.is-active,.navbar.is-black .navbar-start .navbar-link:focus,.navbar.is-black .navbar-start .navbar-link:hover,.navbar.is-black .navbar-start>a.navbar-item.is-active,.navbar.is-black .navbar-start>a.navbar-item:focus,.navbar.is-black .navbar-start>a.navbar-item:hover{background-color:#000;color:#fff}.navbar.is-black .navbar-end .navbar-link::after,.navbar.is-black .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-black .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-black .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-black .navbar-item.has-dropdown:hover .navbar-link{background-color:#000;color:#fff}.navbar.is-black .navbar-dropdown a.navbar-item.is-active{background-color:#0a0a0a;color:#fff}}.navbar.is-light{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.navbar.is-light .navbar-brand .navbar-link,.navbar.is-light .navbar-brand>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-light .navbar-brand .navbar-link.is-active,.navbar.is-light .navbar-brand .navbar-link:focus,.navbar.is-light .navbar-brand .navbar-link:hover,.navbar.is-light .navbar-brand>a.navbar-item.is-active,.navbar.is-light .navbar-brand>a.navbar-item:focus,.navbar.is-light .navbar-brand>a.navbar-item:hover{background-color:#e8e8e8;color:rgba(0,0,0,.7)}.navbar.is-light .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-light .navbar-burger{color:rgba(0,0,0,.7)}@media screen and (min-width:1024px){.navbar.is-light .navbar-end .navbar-link,.navbar.is-light .navbar-end>.navbar-item,.navbar.is-light .navbar-start .navbar-link,.navbar.is-light .navbar-start>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-light .navbar-end .navbar-link.is-active,.navbar.is-light .navbar-end .navbar-link:focus,.navbar.is-light .navbar-end .navbar-link:hover,.navbar.is-light .navbar-end>a.navbar-item.is-active,.navbar.is-light .navbar-end>a.navbar-item:focus,.navbar.is-light .navbar-end>a.navbar-item:hover,.navbar.is-light .navbar-start .navbar-link.is-active,.navbar.is-light .navbar-start .navbar-link:focus,.navbar.is-light .navbar-start .navbar-link:hover,.navbar.is-light .navbar-start>a.navbar-item.is-active,.navbar.is-light .navbar-start>a.navbar-item:focus,.navbar.is-light .navbar-start>a.navbar-item:hover{background-color:#e8e8e8;color:rgba(0,0,0,.7)}.navbar.is-light .navbar-end .navbar-link::after,.navbar.is-light .navbar-start .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-light .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-light .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-light .navbar-item.has-dropdown:hover .navbar-link{background-color:#e8e8e8;color:rgba(0,0,0,.7)}.navbar.is-light .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:rgba(0,0,0,.7)}}.navbar.is-dark{background-color:#363636;color:#fff}.navbar.is-dark .navbar-brand .navbar-link,.navbar.is-dark .navbar-brand>.navbar-item{color:#fff}.navbar.is-dark .navbar-brand .navbar-link.is-active,.navbar.is-dark .navbar-brand .navbar-link:focus,.navbar.is-dark .navbar-brand .navbar-link:hover,.navbar.is-dark .navbar-brand>a.navbar-item.is-active,.navbar.is-dark .navbar-brand>a.navbar-item:focus,.navbar.is-dark .navbar-brand>a.navbar-item:hover{background-color:#292929;color:#fff}.navbar.is-dark .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-dark .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-dark .navbar-end .navbar-link,.navbar.is-dark .navbar-end>.navbar-item,.navbar.is-dark .navbar-start .navbar-link,.navbar.is-dark .navbar-start>.navbar-item{color:#fff}.navbar.is-dark .navbar-end .navbar-link.is-active,.navbar.is-dark .navbar-end .navbar-link:focus,.navbar.is-dark .navbar-end .navbar-link:hover,.navbar.is-dark .navbar-end>a.navbar-item.is-active,.navbar.is-dark .navbar-end>a.navbar-item:focus,.navbar.is-dark .navbar-end>a.navbar-item:hover,.navbar.is-dark .navbar-start .navbar-link.is-active,.navbar.is-dark .navbar-start .navbar-link:focus,.navbar.is-dark .navbar-start .navbar-link:hover,.navbar.is-dark .navbar-start>a.navbar-item.is-active,.navbar.is-dark .navbar-start>a.navbar-item:focus,.navbar.is-dark .navbar-start>a.navbar-item:hover{background-color:#292929;color:#fff}.navbar.is-dark .navbar-end .navbar-link::after,.navbar.is-dark .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-dark .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-dark .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-dark .navbar-item.has-dropdown:hover .navbar-link{background-color:#292929;color:#fff}.navbar.is-dark .navbar-dropdown a.navbar-item.is-active{background-color:#363636;color:#fff}}.navbar.is-primary{background-color:#00d1b2;color:#fff}.navbar.is-primary .navbar-brand .navbar-link,.navbar.is-primary .navbar-brand>.navbar-item{color:#fff}.navbar.is-primary .navbar-brand .navbar-link.is-active,.navbar.is-primary .navbar-brand .navbar-link:focus,.navbar.is-primary .navbar-brand .navbar-link:hover,.navbar.is-primary .navbar-brand>a.navbar-item.is-active,.navbar.is-primary .navbar-brand>a.navbar-item:focus,.navbar.is-primary .navbar-brand>a.navbar-item:hover{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-primary .navbar-end .navbar-link,.navbar.is-primary .navbar-end>.navbar-item,.navbar.is-primary .navbar-start .navbar-link,.navbar.is-primary .navbar-start>.navbar-item{color:#fff}.navbar.is-primary .navbar-end .navbar-link.is-active,.navbar.is-primary .navbar-end .navbar-link:focus,.navbar.is-primary .navbar-end .navbar-link:hover,.navbar.is-primary .navbar-end>a.navbar-item.is-active,.navbar.is-primary .navbar-end>a.navbar-item:focus,.navbar.is-primary .navbar-end>a.navbar-item:hover,.navbar.is-primary .navbar-start .navbar-link.is-active,.navbar.is-primary .navbar-start .navbar-link:focus,.navbar.is-primary .navbar-start .navbar-link:hover,.navbar.is-primary .navbar-start>a.navbar-item.is-active,.navbar.is-primary .navbar-start>a.navbar-item:focus,.navbar.is-primary .navbar-start>a.navbar-item:hover{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-end .navbar-link::after,.navbar.is-primary .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-primary .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-primary .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-primary .navbar-item.has-dropdown:hover .navbar-link{background-color:#00b89c;color:#fff}.navbar.is-primary .navbar-dropdown a.navbar-item.is-active{background-color:#00d1b2;color:#fff}}.navbar.is-link{background-color:#3273dc;color:#fff}.navbar.is-link .navbar-brand .navbar-link,.navbar.is-link .navbar-brand>.navbar-item{color:#fff}.navbar.is-link .navbar-brand .navbar-link.is-active,.navbar.is-link .navbar-brand .navbar-link:focus,.navbar.is-link .navbar-brand .navbar-link:hover,.navbar.is-link .navbar-brand>a.navbar-item.is-active,.navbar.is-link .navbar-brand>a.navbar-item:focus,.navbar.is-link .navbar-brand>a.navbar-item:hover{background-color:#2366d1;color:#fff}.navbar.is-link .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-link .navbar-end .navbar-link,.navbar.is-link .navbar-end>.navbar-item,.navbar.is-link .navbar-start .navbar-link,.navbar.is-link .navbar-start>.navbar-item{color:#fff}.navbar.is-link .navbar-end .navbar-link.is-active,.navbar.is-link .navbar-end .navbar-link:focus,.navbar.is-link .navbar-end .navbar-link:hover,.navbar.is-link .navbar-end>a.navbar-item.is-active,.navbar.is-link .navbar-end>a.navbar-item:focus,.navbar.is-link .navbar-end>a.navbar-item:hover,.navbar.is-link .navbar-start .navbar-link.is-active,.navbar.is-link .navbar-start .navbar-link:focus,.navbar.is-link .navbar-start .navbar-link:hover,.navbar.is-link .navbar-start>a.navbar-item.is-active,.navbar.is-link .navbar-start>a.navbar-item:focus,.navbar.is-link .navbar-start>a.navbar-item:hover{background-color:#2366d1;color:#fff}.navbar.is-link .navbar-end .navbar-link::after,.navbar.is-link .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-link .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-link .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-link .navbar-item.has-dropdown:hover .navbar-link{background-color:#2366d1;color:#fff}.navbar.is-link .navbar-dropdown a.navbar-item.is-active{background-color:#3273dc;color:#fff}}.navbar.is-info{background-color:#3298dc;color:#fff}.navbar.is-info .navbar-brand .navbar-link,.navbar.is-info .navbar-brand>.navbar-item{color:#fff}.navbar.is-info .navbar-brand .navbar-link.is-active,.navbar.is-info .navbar-brand .navbar-link:focus,.navbar.is-info .navbar-brand .navbar-link:hover,.navbar.is-info .navbar-brand>a.navbar-item.is-active,.navbar.is-info .navbar-brand>a.navbar-item:focus,.navbar.is-info .navbar-brand>a.navbar-item:hover{background-color:#238cd1;color:#fff}.navbar.is-info .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-info .navbar-end .navbar-link,.navbar.is-info .navbar-end>.navbar-item,.navbar.is-info .navbar-start .navbar-link,.navbar.is-info .navbar-start>.navbar-item{color:#fff}.navbar.is-info .navbar-end .navbar-link.is-active,.navbar.is-info .navbar-end .navbar-link:focus,.navbar.is-info .navbar-end .navbar-link:hover,.navbar.is-info .navbar-end>a.navbar-item.is-active,.navbar.is-info .navbar-end>a.navbar-item:focus,.navbar.is-info .navbar-end>a.navbar-item:hover,.navbar.is-info .navbar-start .navbar-link.is-active,.navbar.is-info .navbar-start .navbar-link:focus,.navbar.is-info .navbar-start .navbar-link:hover,.navbar.is-info .navbar-start>a.navbar-item.is-active,.navbar.is-info .navbar-start>a.navbar-item:focus,.navbar.is-info .navbar-start>a.navbar-item:hover{background-color:#238cd1;color:#fff}.navbar.is-info .navbar-end .navbar-link::after,.navbar.is-info .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-info .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-info .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-info .navbar-item.has-dropdown:hover .navbar-link{background-color:#238cd1;color:#fff}.navbar.is-info .navbar-dropdown a.navbar-item.is-active{background-color:#3298dc;color:#fff}}.navbar.is-success{background-color:#48c774;color:#fff}.navbar.is-success .navbar-brand .navbar-link,.navbar.is-success .navbar-brand>.navbar-item{color:#fff}.navbar.is-success .navbar-brand .navbar-link.is-active,.navbar.is-success .navbar-brand .navbar-link:focus,.navbar.is-success .navbar-brand .navbar-link:hover,.navbar.is-success .navbar-brand>a.navbar-item.is-active,.navbar.is-success .navbar-brand>a.navbar-item:focus,.navbar.is-success .navbar-brand>a.navbar-item:hover{background-color:#3abb67;color:#fff}.navbar.is-success .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-success .navbar-end .navbar-link,.navbar.is-success .navbar-end>.navbar-item,.navbar.is-success .navbar-start .navbar-link,.navbar.is-success .navbar-start>.navbar-item{color:#fff}.navbar.is-success .navbar-end .navbar-link.is-active,.navbar.is-success .navbar-end .navbar-link:focus,.navbar.is-success .navbar-end .navbar-link:hover,.navbar.is-success .navbar-end>a.navbar-item.is-active,.navbar.is-success .navbar-end>a.navbar-item:focus,.navbar.is-success .navbar-end>a.navbar-item:hover,.navbar.is-success .navbar-start .navbar-link.is-active,.navbar.is-success .navbar-start .navbar-link:focus,.navbar.is-success .navbar-start .navbar-link:hover,.navbar.is-success .navbar-start>a.navbar-item.is-active,.navbar.is-success .navbar-start>a.navbar-item:focus,.navbar.is-success .navbar-start>a.navbar-item:hover{background-color:#3abb67;color:#fff}.navbar.is-success .navbar-end .navbar-link::after,.navbar.is-success .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-success .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-success .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-success .navbar-item.has-dropdown:hover .navbar-link{background-color:#3abb67;color:#fff}.navbar.is-success .navbar-dropdown a.navbar-item.is-active{background-color:#48c774;color:#fff}}.navbar.is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link,.navbar.is-warning .navbar-brand>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link.is-active,.navbar.is-warning .navbar-brand .navbar-link:focus,.navbar.is-warning .navbar-brand .navbar-link:hover,.navbar.is-warning .navbar-brand>a.navbar-item.is-active,.navbar.is-warning .navbar-brand>a.navbar-item:focus,.navbar.is-warning .navbar-brand>a.navbar-item:hover{background-color:#ffd83d;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-brand .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-burger{color:rgba(0,0,0,.7)}@media screen and (min-width:1024px){.navbar.is-warning .navbar-end .navbar-link,.navbar.is-warning .navbar-end>.navbar-item,.navbar.is-warning .navbar-start .navbar-link,.navbar.is-warning .navbar-start>.navbar-item{color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-end .navbar-link.is-active,.navbar.is-warning .navbar-end .navbar-link:focus,.navbar.is-warning .navbar-end .navbar-link:hover,.navbar.is-warning .navbar-end>a.navbar-item.is-active,.navbar.is-warning .navbar-end>a.navbar-item:focus,.navbar.is-warning .navbar-end>a.navbar-item:hover,.navbar.is-warning .navbar-start .navbar-link.is-active,.navbar.is-warning .navbar-start .navbar-link:focus,.navbar.is-warning .navbar-start .navbar-link:hover,.navbar.is-warning .navbar-start>a.navbar-item.is-active,.navbar.is-warning .navbar-start>a.navbar-item:focus,.navbar.is-warning .navbar-start>a.navbar-item:hover{background-color:#ffd83d;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-end .navbar-link::after,.navbar.is-warning .navbar-start .navbar-link::after{border-color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-warning .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-warning .navbar-item.has-dropdown:hover .navbar-link{background-color:#ffd83d;color:rgba(0,0,0,.7)}.navbar.is-warning .navbar-dropdown a.navbar-item.is-active{background-color:#ffdd57;color:rgba(0,0,0,.7)}}.navbar.is-danger{background-color:#f14668;color:#fff}.navbar.is-danger .navbar-brand .navbar-link,.navbar.is-danger .navbar-brand>.navbar-item{color:#fff}.navbar.is-danger .navbar-brand .navbar-link.is-active,.navbar.is-danger .navbar-brand .navbar-link:focus,.navbar.is-danger .navbar-brand .navbar-link:hover,.navbar.is-danger .navbar-brand>a.navbar-item.is-active,.navbar.is-danger .navbar-brand>a.navbar-item:focus,.navbar.is-danger .navbar-brand>a.navbar-item:hover{background-color:#ef2e55;color:#fff}.navbar.is-danger .navbar-brand .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-burger{color:#fff}@media screen and (min-width:1024px){.navbar.is-danger .navbar-end .navbar-link,.navbar.is-danger .navbar-end>.navbar-item,.navbar.is-danger .navbar-start .navbar-link,.navbar.is-danger .navbar-start>.navbar-item{color:#fff}.navbar.is-danger .navbar-end .navbar-link.is-active,.navbar.is-danger .navbar-end .navbar-link:focus,.navbar.is-danger .navbar-end .navbar-link:hover,.navbar.is-danger .navbar-end>a.navbar-item.is-active,.navbar.is-danger .navbar-end>a.navbar-item:focus,.navbar.is-danger .navbar-end>a.navbar-item:hover,.navbar.is-danger .navbar-start .navbar-link.is-active,.navbar.is-danger .navbar-start .navbar-link:focus,.navbar.is-danger .navbar-start .navbar-link:hover,.navbar.is-danger .navbar-start>a.navbar-item.is-active,.navbar.is-danger .navbar-start>a.navbar-item:focus,.navbar.is-danger .navbar-start>a.navbar-item:hover{background-color:#ef2e55;color:#fff}.navbar.is-danger .navbar-end .navbar-link::after,.navbar.is-danger .navbar-start .navbar-link::after{border-color:#fff}.navbar.is-danger .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-danger .navbar-item.has-dropdown:focus .navbar-link,.navbar.is-danger .navbar-item.has-dropdown:hover .navbar-link{background-color:#ef2e55;color:#fff}.navbar.is-danger .navbar-dropdown a.navbar-item.is-active{background-color:#f14668;color:#fff}}.navbar>.container{align-items:stretch;display:flex;min-height:3.25rem;width:100%}.navbar.has-shadow{box-shadow:0 2px 0 0 #f5f5f5}.navbar.is-fixed-bottom,.navbar.is-fixed-top{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom{bottom:0}.navbar.is-fixed-bottom.has-shadow{box-shadow:0 -2px 0 0 #f5f5f5}.navbar.is-fixed-top{top:0}body.has-navbar-fixed-top,html.has-navbar-fixed-top{padding-top:3.25rem}body.has-navbar-fixed-bottom,html.has-navbar-fixed-bottom{padding-bottom:3.25rem}.navbar-brand,.navbar-tabs{align-items:stretch;display:flex;flex-shrink:0;min-height:3.25rem}.navbar-brand a.navbar-item:focus,.navbar-brand a.navbar-item:hover{background-color:transparent}.navbar-tabs{-webkit-overflow-scrolling:touch;max-width:100vw;overflow-x:auto;overflow-y:hidden}.navbar-burger{color:#4a4a4a;cursor:pointer;display:block;height:3.25rem;position:relative;width:3.25rem;margin-left:auto}.navbar-burger span{background-color:currentColor;display:block;height:1px;left:calc(50% - 8px);position:absolute;transform-origin:center;transition-duration:86ms;transition-property:background-color,opacity,transform;transition-timing-function:ease-out;width:16px}.navbar-burger span:nth-child(1){top:calc(50% - 6px)}.navbar-burger span:nth-child(2){top:calc(50% - 1px)}.navbar-burger span:nth-child(3){top:calc(50% + 4px)}.navbar-burger:hover{background-color:rgba(0,0,0,.05)}.navbar-burger.is-active span:nth-child(1){transform:translateY(5px) rotate(45deg)}.navbar-burger.is-active span:nth-child(2){opacity:0}.navbar-burger.is-active span:nth-child(3){transform:translateY(-5px) rotate(-45deg)}.navbar-menu{display:none}.navbar-item,.navbar-link{color:#4a4a4a;display:block;line-height:1.5;padding:.5rem .75rem;position:relative}.navbar-item .icon:only-child,.navbar-link .icon:only-child{margin-left:-.25rem;margin-right:-.25rem}.navbar-link,a.navbar-item{cursor:pointer}.navbar-link.is-active,.navbar-link:focus,.navbar-link:focus-within,.navbar-link:hover,a.navbar-item.is-active,a.navbar-item:focus,a.navbar-item:focus-within,a.navbar-item:hover{background-color:#fafafa;color:#3273dc}.navbar-item{flex-grow:0;flex-shrink:0}.navbar-item img{max-height:1.75rem}.navbar-item.has-dropdown{padding:0}.navbar-item.is-expanded{flex-grow:1;flex-shrink:1}.navbar-item.is-tab{border-bottom:1px solid transparent;min-height:3.25rem;padding-bottom:calc(.5rem - 1px)}.navbar-item.is-tab:focus,.navbar-item.is-tab:hover{background-color:transparent;border-bottom-color:#3273dc}.navbar-item.is-tab.is-active{background-color:transparent;border-bottom-color:#3273dc;border-bottom-style:solid;border-bottom-width:3px;color:#3273dc;padding-bottom:calc(.5rem - 3px)}.navbar-content{flex-grow:1;flex-shrink:1}.navbar-link:not(.is-arrowless){padding-right:2.5em}.navbar-link:not(.is-arrowless)::after{border-color:#3273dc;margin-top:-.375em;right:1.125em}.navbar-dropdown{font-size:.875rem;padding-bottom:.5rem;padding-top:.5rem}.navbar-dropdown .navbar-item{padding-left:1.5rem;padding-right:1.5rem}.navbar-divider{background-color:#f5f5f5;border:none;display:none;height:2px;margin:.5rem 0}@media screen and (max-width:1023px){.navbar>.container{display:block}.navbar-brand .navbar-item,.navbar-tabs .navbar-item{align-items:center;display:flex}.navbar-link::after{display:none}.navbar-menu{background-color:#fff;box-shadow:0 8px 16px rgba(10,10,10,.1);padding:.5rem 0}.navbar-menu.is-active{display:block}.navbar.is-fixed-bottom-touch,.navbar.is-fixed-top-touch{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-touch{bottom:0}.navbar.is-fixed-bottom-touch.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,.1)}.navbar.is-fixed-top-touch{top:0}.navbar.is-fixed-top .navbar-menu,.navbar.is-fixed-top-touch .navbar-menu{-webkit-overflow-scrolling:touch;max-height:calc(100vh - 3.25rem);overflow:auto}body.has-navbar-fixed-top-touch,html.has-navbar-fixed-top-touch{padding-top:3.25rem}body.has-navbar-fixed-bottom-touch,html.has-navbar-fixed-bottom-touch{padding-bottom:3.25rem}}@media screen and (min-width:1024px){.navbar,.navbar-end,.navbar-menu,.navbar-start{align-items:stretch;display:flex}.navbar{min-height:3.25rem}.navbar.is-spaced{padding:1rem 2rem}.navbar.is-spaced .navbar-end,.navbar.is-spaced .navbar-start{align-items:center}.navbar.is-spaced .navbar-link,.navbar.is-spaced a.navbar-item{border-radius:4px}.navbar.is-transparent .navbar-link.is-active,.navbar.is-transparent .navbar-link:focus,.navbar.is-transparent .navbar-link:hover,.navbar.is-transparent a.navbar-item.is-active,.navbar.is-transparent a.navbar-item:focus,.navbar.is-transparent a.navbar-item:hover{background-color:transparent!important}.navbar.is-transparent .navbar-item.has-dropdown.is-active .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:focus-within .navbar-link,.navbar.is-transparent .navbar-item.has-dropdown.is-hoverable:hover .navbar-link{background-color:transparent!important}.navbar.is-transparent .navbar-dropdown a.navbar-item:focus,.navbar.is-transparent .navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar.is-transparent .navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#3273dc}.navbar-burger{display:none}.navbar-item,.navbar-link{align-items:center;display:flex}.navbar-item.has-dropdown{align-items:stretch}.navbar-item.has-dropdown-up .navbar-link::after{transform:rotate(135deg) translate(.25em,-.25em)}.navbar-item.has-dropdown-up .navbar-dropdown{border-bottom:2px solid #dbdbdb;border-radius:6px 6px 0 0;border-top:none;bottom:100%;box-shadow:0 -8px 8px rgba(10,10,10,.1);top:auto}.navbar-item.is-active .navbar-dropdown,.navbar-item.is-hoverable:focus .navbar-dropdown,.navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar-item.is-hoverable:hover .navbar-dropdown{display:block}.navbar-item.is-active .navbar-dropdown.is-boxed,.navbar-item.is-hoverable:focus .navbar-dropdown.is-boxed,.navbar-item.is-hoverable:focus-within .navbar-dropdown.is-boxed,.navbar-item.is-hoverable:hover .navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-item.is-active .navbar-dropdown,.navbar.is-spaced .navbar-item.is-hoverable:focus .navbar-dropdown,.navbar.is-spaced .navbar-item.is-hoverable:focus-within .navbar-dropdown,.navbar.is-spaced .navbar-item.is-hoverable:hover .navbar-dropdown{opacity:1;pointer-events:auto;transform:translateY(0)}.navbar-menu{flex-grow:1;flex-shrink:0}.navbar-start{justify-content:flex-start;margin-right:auto}.navbar-end{justify-content:flex-end;margin-left:auto}.navbar-dropdown{background-color:#fff;border-bottom-left-radius:6px;border-bottom-right-radius:6px;border-top:2px solid #dbdbdb;box-shadow:0 8px 8px rgba(10,10,10,.1);display:none;font-size:.875rem;left:0;min-width:100%;position:absolute;top:100%;z-index:20}.navbar-dropdown .navbar-item{padding:.375rem 1rem;white-space:nowrap}.navbar-dropdown a.navbar-item{padding-right:3rem}.navbar-dropdown a.navbar-item:focus,.navbar-dropdown a.navbar-item:hover{background-color:#f5f5f5;color:#0a0a0a}.navbar-dropdown a.navbar-item.is-active{background-color:#f5f5f5;color:#3273dc}.navbar-dropdown.is-boxed,.navbar.is-spaced .navbar-dropdown{border-radius:6px;border-top:none;box-shadow:0 8px 8px rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.1);display:block;opacity:0;pointer-events:none;top:calc(100% + (-4px));transform:translateY(-5px);transition-duration:86ms;transition-property:opacity,transform}.navbar-dropdown.is-right{left:auto;right:0}.navbar-divider{display:block}.container>.navbar .navbar-brand,.navbar>.container .navbar-brand{margin-left:-.75rem}.container>.navbar .navbar-menu,.navbar>.container .navbar-menu{margin-right:-.75rem}.navbar.is-fixed-bottom-desktop,.navbar.is-fixed-top-desktop{left:0;position:fixed;right:0;z-index:30}.navbar.is-fixed-bottom-desktop{bottom:0}.navbar.is-fixed-bottom-desktop.has-shadow{box-shadow:0 -2px 3px rgba(10,10,10,.1)}.navbar.is-fixed-top-desktop{top:0}body.has-navbar-fixed-top-desktop,html.has-navbar-fixed-top-desktop{padding-top:3.25rem}body.has-navbar-fixed-bottom-desktop,html.has-navbar-fixed-bottom-desktop{padding-bottom:3.25rem}body.has-spaced-navbar-fixed-top,html.has-spaced-navbar-fixed-top{padding-top:5.25rem}body.has-spaced-navbar-fixed-bottom,html.has-spaced-navbar-fixed-bottom{padding-bottom:5.25rem}.navbar-link.is-active,a.navbar-item.is-active{color:#0a0a0a}.navbar-link.is-active:not(:focus):not(:hover),a.navbar-item.is-active:not(:focus):not(:hover){background-color:transparent}.navbar-item.has-dropdown.is-active .navbar-link,.navbar-item.has-dropdown:focus .navbar-link,.navbar-item.has-dropdown:hover .navbar-link{background-color:#fafafa}}.hero.is-fullheight-with-navbar{min-height:calc(100vh - 3.25rem)}.pagination{font-size:1rem;margin:-.25rem}.pagination.is-small{font-size:.75rem}.pagination.is-medium{font-size:1.25rem}.pagination.is-large{font-size:1.5rem}.pagination.is-rounded .pagination-next,.pagination.is-rounded .pagination-previous{padding-left:1em;padding-right:1em;border-radius:290486px}.pagination.is-rounded .pagination-link{border-radius:290486px}.pagination,.pagination-list{align-items:center;display:flex;justify-content:center;text-align:center}.pagination-ellipsis,.pagination-link,.pagination-next,.pagination-previous{font-size:1em;justify-content:center;margin:.25rem;padding-left:.5em;padding-right:.5em;text-align:center}.pagination-link,.pagination-next,.pagination-previous{border-color:#dbdbdb;color:#363636;min-width:2.5em}.pagination-link:hover,.pagination-next:hover,.pagination-previous:hover{border-color:#b5b5b5;color:#363636}.pagination-link:focus,.pagination-next:focus,.pagination-previous:focus{border-color:#3273dc}.pagination-link:active,.pagination-next:active,.pagination-previous:active{box-shadow:inset 0 1px 2px rgba(10,10,10,.2)}.pagination-link[disabled],.pagination-next[disabled],.pagination-previous[disabled]{background-color:#dbdbdb;border-color:#dbdbdb;box-shadow:none;color:#7a7a7a;opacity:.5}.pagination-next,.pagination-previous{padding-left:.75em;padding-right:.75em;white-space:nowrap}.pagination-link.is-current{background-color:#3273dc;border-color:#3273dc;color:#fff}.pagination-ellipsis{color:#b5b5b5;pointer-events:none}.pagination-list{flex-wrap:wrap}@media screen and (max-width:768px){.pagination{flex-wrap:wrap}.pagination-next,.pagination-previous{flex-grow:1;flex-shrink:1}.pagination-list li{flex-grow:1;flex-shrink:1}}@media screen and (min-width:769px),print{.pagination-list{flex-grow:1;flex-shrink:1;justify-content:flex-start;order:1}.pagination-previous{order:2}.pagination-next{order:3}.pagination{justify-content:space-between}.pagination.is-centered .pagination-previous{order:1}.pagination.is-centered .pagination-list{justify-content:center;order:2}.pagination.is-centered .pagination-next{order:3}.pagination.is-right .pagination-previous{order:1}.pagination.is-right .pagination-next{order:2}.pagination.is-right .pagination-list{justify-content:flex-end;order:3}}.panel{border-radius:6px;box-shadow:0 .5em 1em -.125em rgba(10,10,10,.1),0 0 0 1px rgba(10,10,10,.02);font-size:1rem}.panel:not(:last-child){margin-bottom:1.5rem}.panel.is-white .panel-heading{background-color:#fff;color:#0a0a0a}.panel.is-white .panel-tabs a.is-active{border-bottom-color:#fff}.panel.is-white .panel-block.is-active .panel-icon{color:#fff}.panel.is-black .panel-heading{background-color:#0a0a0a;color:#fff}.panel.is-black .panel-tabs a.is-active{border-bottom-color:#0a0a0a}.panel.is-black .panel-block.is-active .panel-icon{color:#0a0a0a}.panel.is-light .panel-heading{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.panel.is-light .panel-tabs a.is-active{border-bottom-color:#f5f5f5}.panel.is-light .panel-block.is-active .panel-icon{color:#f5f5f5}.panel.is-dark .panel-heading{background-color:#363636;color:#fff}.panel.is-dark .panel-tabs a.is-active{border-bottom-color:#363636}.panel.is-dark .panel-block.is-active .panel-icon{color:#363636}.panel.is-primary .panel-heading{background-color:#00d1b2;color:#fff}.panel.is-primary .panel-tabs a.is-active{border-bottom-color:#00d1b2}.panel.is-primary .panel-block.is-active .panel-icon{color:#00d1b2}.panel.is-link .panel-heading{background-color:#3273dc;color:#fff}.panel.is-link .panel-tabs a.is-active{border-bottom-color:#3273dc}.panel.is-link .panel-block.is-active .panel-icon{color:#3273dc}.panel.is-info .panel-heading{background-color:#3298dc;color:#fff}.panel.is-info .panel-tabs a.is-active{border-bottom-color:#3298dc}.panel.is-info .panel-block.is-active .panel-icon{color:#3298dc}.panel.is-success .panel-heading{background-color:#48c774;color:#fff}.panel.is-success .panel-tabs a.is-active{border-bottom-color:#48c774}.panel.is-success .panel-block.is-active .panel-icon{color:#48c774}.panel.is-warning .panel-heading{background-color:#ffdd57;color:rgba(0,0,0,.7)}.panel.is-warning .panel-tabs a.is-active{border-bottom-color:#ffdd57}.panel.is-warning .panel-block.is-active .panel-icon{color:#ffdd57}.panel.is-danger .panel-heading{background-color:#f14668;color:#fff}.panel.is-danger .panel-tabs a.is-active{border-bottom-color:#f14668}.panel.is-danger .panel-block.is-active .panel-icon{color:#f14668}.panel-block:not(:last-child),.panel-tabs:not(:last-child){border-bottom:1px solid #ededed}.panel-heading{background-color:#ededed;border-radius:6px 6px 0 0;color:#363636;font-size:1.25em;font-weight:700;line-height:1.25;padding:.75em 1em}.panel-tabs{align-items:flex-end;display:flex;font-size:.875em;justify-content:center}.panel-tabs a{border-bottom:1px solid #dbdbdb;margin-bottom:-1px;padding:.5em}.panel-tabs a.is-active{border-bottom-color:#4a4a4a;color:#363636}.panel-list a{color:#4a4a4a}.panel-list a:hover{color:#3273dc}.panel-block{align-items:center;color:#363636;display:flex;justify-content:flex-start;padding:.5em .75em}.panel-block input[type=checkbox]{margin-right:.75em}.panel-block>.control{flex-grow:1;flex-shrink:1;width:100%}.panel-block.is-wrapped{flex-wrap:wrap}.panel-block.is-active{border-left-color:#3273dc;color:#363636}.panel-block.is-active .panel-icon{color:#3273dc}.panel-block:last-child{border-bottom-left-radius:6px;border-bottom-right-radius:6px}a.panel-block,label.panel-block{cursor:pointer}a.panel-block:hover,label.panel-block:hover{background-color:#f5f5f5}.panel-icon{display:inline-block;font-size:14px;height:1em;line-height:1em;text-align:center;vertical-align:top;width:1em;color:#7a7a7a;margin-right:.75em}.panel-icon .fa{font-size:inherit;line-height:inherit}.tabs{-webkit-overflow-scrolling:touch;align-items:stretch;display:flex;font-size:1rem;justify-content:space-between;overflow:hidden;overflow-x:auto;white-space:nowrap}.tabs a{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;color:#4a4a4a;display:flex;justify-content:center;margin-bottom:-1px;padding:.5em 1em;vertical-align:top}.tabs a:hover{border-bottom-color:#363636;color:#363636}.tabs li{display:block}.tabs li.is-active a{border-bottom-color:#3273dc;color:#3273dc}.tabs ul{align-items:center;border-bottom-color:#dbdbdb;border-bottom-style:solid;border-bottom-width:1px;display:flex;flex-grow:1;flex-shrink:0;justify-content:flex-start}.tabs ul.is-left{padding-right:.75em}.tabs ul.is-center{flex:none;justify-content:center;padding-left:.75em;padding-right:.75em}.tabs ul.is-right{justify-content:flex-end;padding-left:.75em}.tabs .icon:first-child{margin-right:.5em}.tabs .icon:last-child{margin-left:.5em}.tabs.is-centered ul{justify-content:center}.tabs.is-right ul{justify-content:flex-end}.tabs.is-boxed a{border:1px solid transparent;border-radius:4px 4px 0 0}.tabs.is-boxed a:hover{background-color:#f5f5f5;border-bottom-color:#dbdbdb}.tabs.is-boxed li.is-active a{background-color:#fff;border-color:#dbdbdb;border-bottom-color:transparent!important}.tabs.is-fullwidth li{flex-grow:1;flex-shrink:0}.tabs.is-toggle a{border-color:#dbdbdb;border-style:solid;border-width:1px;margin-bottom:0;position:relative}.tabs.is-toggle a:hover{background-color:#f5f5f5;border-color:#b5b5b5;z-index:2}.tabs.is-toggle li+li{margin-left:-1px}.tabs.is-toggle li:first-child a{border-top-left-radius:4px;border-bottom-left-radius:4px}.tabs.is-toggle li:last-child a{border-top-right-radius:4px;border-bottom-right-radius:4px}.tabs.is-toggle li.is-active a{background-color:#3273dc;border-color:#3273dc;color:#fff;z-index:1}.tabs.is-toggle ul{border-bottom:none}.tabs.is-toggle.is-toggle-rounded li:first-child a{border-bottom-left-radius:290486px;border-top-left-radius:290486px;padding-left:1.25em}.tabs.is-toggle.is-toggle-rounded li:last-child a{border-bottom-right-radius:290486px;border-top-right-radius:290486px;padding-right:1.25em}.tabs.is-small{font-size:.75rem}.tabs.is-medium{font-size:1.25rem}.tabs.is-large{font-size:1.5rem}.column{display:block;flex-basis:0;flex-grow:1;flex-shrink:1;padding:.75rem}.columns.is-mobile>.column.is-narrow{flex:none}.columns.is-mobile>.column.is-full{flex:none;width:100%}.columns.is-mobile>.column.is-three-quarters{flex:none;width:75%}.columns.is-mobile>.column.is-two-thirds{flex:none;width:66.6666%}.columns.is-mobile>.column.is-half{flex:none;width:50%}.columns.is-mobile>.column.is-one-third{flex:none;width:33.3333%}.columns.is-mobile>.column.is-one-quarter{flex:none;width:25%}.columns.is-mobile>.column.is-one-fifth{flex:none;width:20%}.columns.is-mobile>.column.is-two-fifths{flex:none;width:40%}.columns.is-mobile>.column.is-three-fifths{flex:none;width:60%}.columns.is-mobile>.column.is-four-fifths{flex:none;width:80%}.columns.is-mobile>.column.is-offset-three-quarters{margin-left:75%}.columns.is-mobile>.column.is-offset-two-thirds{margin-left:66.6666%}.columns.is-mobile>.column.is-offset-half{margin-left:50%}.columns.is-mobile>.column.is-offset-one-third{margin-left:33.3333%}.columns.is-mobile>.column.is-offset-one-quarter{margin-left:25%}.columns.is-mobile>.column.is-offset-one-fifth{margin-left:20%}.columns.is-mobile>.column.is-offset-two-fifths{margin-left:40%}.columns.is-mobile>.column.is-offset-three-fifths{margin-left:60%}.columns.is-mobile>.column.is-offset-four-fifths{margin-left:80%}.columns.is-mobile>.column.is-0{flex:none;width:0%}.columns.is-mobile>.column.is-offset-0{margin-left:0}.columns.is-mobile>.column.is-1{flex:none;width:8.33333%}.columns.is-mobile>.column.is-offset-1{margin-left:8.33333%}.columns.is-mobile>.column.is-2{flex:none;width:16.66667%}.columns.is-mobile>.column.is-offset-2{margin-left:16.66667%}.columns.is-mobile>.column.is-3{flex:none;width:25%}.columns.is-mobile>.column.is-offset-3{margin-left:25%}.columns.is-mobile>.column.is-4{flex:none;width:33.33333%}.columns.is-mobile>.column.is-offset-4{margin-left:33.33333%}.columns.is-mobile>.column.is-5{flex:none;width:41.66667%}.columns.is-mobile>.column.is-offset-5{margin-left:41.66667%}.columns.is-mobile>.column.is-6{flex:none;width:50%}.columns.is-mobile>.column.is-offset-6{margin-left:50%}.columns.is-mobile>.column.is-7{flex:none;width:58.33333%}.columns.is-mobile>.column.is-offset-7{margin-left:58.33333%}.columns.is-mobile>.column.is-8{flex:none;width:66.66667%}.columns.is-mobile>.column.is-offset-8{margin-left:66.66667%}.columns.is-mobile>.column.is-9{flex:none;width:75%}.columns.is-mobile>.column.is-offset-9{margin-left:75%}.columns.is-mobile>.column.is-10{flex:none;width:83.33333%}.columns.is-mobile>.column.is-offset-10{margin-left:83.33333%}.columns.is-mobile>.column.is-11{flex:none;width:91.66667%}.columns.is-mobile>.column.is-offset-11{margin-left:91.66667%}.columns.is-mobile>.column.is-12{flex:none;width:100%}.columns.is-mobile>.column.is-offset-12{margin-left:100%}@media screen and (max-width:768px){.column.is-narrow-mobile{flex:none}.column.is-full-mobile{flex:none;width:100%}.column.is-three-quarters-mobile{flex:none;width:75%}.column.is-two-thirds-mobile{flex:none;width:66.6666%}.column.is-half-mobile{flex:none;width:50%}.column.is-one-third-mobile{flex:none;width:33.3333%}.column.is-one-quarter-mobile{flex:none;width:25%}.column.is-one-fifth-mobile{flex:none;width:20%}.column.is-two-fifths-mobile{flex:none;width:40%}.column.is-three-fifths-mobile{flex:none;width:60%}.column.is-four-fifths-mobile{flex:none;width:80%}.column.is-offset-three-quarters-mobile{margin-left:75%}.column.is-offset-two-thirds-mobile{margin-left:66.6666%}.column.is-offset-half-mobile{margin-left:50%}.column.is-offset-one-third-mobile{margin-left:33.3333%}.column.is-offset-one-quarter-mobile{margin-left:25%}.column.is-offset-one-fifth-mobile{margin-left:20%}.column.is-offset-two-fifths-mobile{margin-left:40%}.column.is-offset-three-fifths-mobile{margin-left:60%}.column.is-offset-four-fifths-mobile{margin-left:80%}.column.is-0-mobile{flex:none;width:0%}.column.is-offset-0-mobile{margin-left:0}.column.is-1-mobile{flex:none;width:8.33333%}.column.is-offset-1-mobile{margin-left:8.33333%}.column.is-2-mobile{flex:none;width:16.66667%}.column.is-offset-2-mobile{margin-left:16.66667%}.column.is-3-mobile{flex:none;width:25%}.column.is-offset-3-mobile{margin-left:25%}.column.is-4-mobile{flex:none;width:33.33333%}.column.is-offset-4-mobile{margin-left:33.33333%}.column.is-5-mobile{flex:none;width:41.66667%}.column.is-offset-5-mobile{margin-left:41.66667%}.column.is-6-mobile{flex:none;width:50%}.column.is-offset-6-mobile{margin-left:50%}.column.is-7-mobile{flex:none;width:58.33333%}.column.is-offset-7-mobile{margin-left:58.33333%}.column.is-8-mobile{flex:none;width:66.66667%}.column.is-offset-8-mobile{margin-left:66.66667%}.column.is-9-mobile{flex:none;width:75%}.column.is-offset-9-mobile{margin-left:75%}.column.is-10-mobile{flex:none;width:83.33333%}.column.is-offset-10-mobile{margin-left:83.33333%}.column.is-11-mobile{flex:none;width:91.66667%}.column.is-offset-11-mobile{margin-left:91.66667%}.column.is-12-mobile{flex:none;width:100%}.column.is-offset-12-mobile{margin-left:100%}}@media screen and (min-width:769px),print{.column.is-narrow,.column.is-narrow-tablet{flex:none}.column.is-full,.column.is-full-tablet{flex:none;width:100%}.column.is-three-quarters,.column.is-three-quarters-tablet{flex:none;width:75%}.column.is-two-thirds,.column.is-two-thirds-tablet{flex:none;width:66.6666%}.column.is-half,.column.is-half-tablet{flex:none;width:50%}.column.is-one-third,.column.is-one-third-tablet{flex:none;width:33.3333%}.column.is-one-quarter,.column.is-one-quarter-tablet{flex:none;width:25%}.column.is-one-fifth,.column.is-one-fifth-tablet{flex:none;width:20%}.column.is-two-fifths,.column.is-two-fifths-tablet{flex:none;width:40%}.column.is-three-fifths,.column.is-three-fifths-tablet{flex:none;width:60%}.column.is-four-fifths,.column.is-four-fifths-tablet{flex:none;width:80%}.column.is-offset-three-quarters,.column.is-offset-three-quarters-tablet{margin-left:75%}.column.is-offset-two-thirds,.column.is-offset-two-thirds-tablet{margin-left:66.6666%}.column.is-offset-half,.column.is-offset-half-tablet{margin-left:50%}.column.is-offset-one-third,.column.is-offset-one-third-tablet{margin-left:33.3333%}.column.is-offset-one-quarter,.column.is-offset-one-quarter-tablet{margin-left:25%}.column.is-offset-one-fifth,.column.is-offset-one-fifth-tablet{margin-left:20%}.column.is-offset-two-fifths,.column.is-offset-two-fifths-tablet{margin-left:40%}.column.is-offset-three-fifths,.column.is-offset-three-fifths-tablet{margin-left:60%}.column.is-offset-four-fifths,.column.is-offset-four-fifths-tablet{margin-left:80%}.column.is-0,.column.is-0-tablet{flex:none;width:0%}.column.is-offset-0,.column.is-offset-0-tablet{margin-left:0}.column.is-1,.column.is-1-tablet{flex:none;width:8.33333%}.column.is-offset-1,.column.is-offset-1-tablet{margin-left:8.33333%}.column.is-2,.column.is-2-tablet{flex:none;width:16.66667%}.column.is-offset-2,.column.is-offset-2-tablet{margin-left:16.66667%}.column.is-3,.column.is-3-tablet{flex:none;width:25%}.column.is-offset-3,.column.is-offset-3-tablet{margin-left:25%}.column.is-4,.column.is-4-tablet{flex:none;width:33.33333%}.column.is-offset-4,.column.is-offset-4-tablet{margin-left:33.33333%}.column.is-5,.column.is-5-tablet{flex:none;width:41.66667%}.column.is-offset-5,.column.is-offset-5-tablet{margin-left:41.66667%}.column.is-6,.column.is-6-tablet{flex:none;width:50%}.column.is-offset-6,.column.is-offset-6-tablet{margin-left:50%}.column.is-7,.column.is-7-tablet{flex:none;width:58.33333%}.column.is-offset-7,.column.is-offset-7-tablet{margin-left:58.33333%}.column.is-8,.column.is-8-tablet{flex:none;width:66.66667%}.column.is-offset-8,.column.is-offset-8-tablet{margin-left:66.66667%}.column.is-9,.column.is-9-tablet{flex:none;width:75%}.column.is-offset-9,.column.is-offset-9-tablet{margin-left:75%}.column.is-10,.column.is-10-tablet{flex:none;width:83.33333%}.column.is-offset-10,.column.is-offset-10-tablet{margin-left:83.33333%}.column.is-11,.column.is-11-tablet{flex:none;width:91.66667%}.column.is-offset-11,.column.is-offset-11-tablet{margin-left:91.66667%}.column.is-12,.column.is-12-tablet{flex:none;width:100%}.column.is-offset-12,.column.is-offset-12-tablet{margin-left:100%}}@media screen and (max-width:1023px){.column.is-narrow-touch{flex:none}.column.is-full-touch{flex:none;width:100%}.column.is-three-quarters-touch{flex:none;width:75%}.column.is-two-thirds-touch{flex:none;width:66.6666%}.column.is-half-touch{flex:none;width:50%}.column.is-one-third-touch{flex:none;width:33.3333%}.column.is-one-quarter-touch{flex:none;width:25%}.column.is-one-fifth-touch{flex:none;width:20%}.column.is-two-fifths-touch{flex:none;width:40%}.column.is-three-fifths-touch{flex:none;width:60%}.column.is-four-fifths-touch{flex:none;width:80%}.column.is-offset-three-quarters-touch{margin-left:75%}.column.is-offset-two-thirds-touch{margin-left:66.6666%}.column.is-offset-half-touch{margin-left:50%}.column.is-offset-one-third-touch{margin-left:33.3333%}.column.is-offset-one-quarter-touch{margin-left:25%}.column.is-offset-one-fifth-touch{margin-left:20%}.column.is-offset-two-fifths-touch{margin-left:40%}.column.is-offset-three-fifths-touch{margin-left:60%}.column.is-offset-four-fifths-touch{margin-left:80%}.column.is-0-touch{flex:none;width:0%}.column.is-offset-0-touch{margin-left:0}.column.is-1-touch{flex:none;width:8.33333%}.column.is-offset-1-touch{margin-left:8.33333%}.column.is-2-touch{flex:none;width:16.66667%}.column.is-offset-2-touch{margin-left:16.66667%}.column.is-3-touch{flex:none;width:25%}.column.is-offset-3-touch{margin-left:25%}.column.is-4-touch{flex:none;width:33.33333%}.column.is-offset-4-touch{margin-left:33.33333%}.column.is-5-touch{flex:none;width:41.66667%}.column.is-offset-5-touch{margin-left:41.66667%}.column.is-6-touch{flex:none;width:50%}.column.is-offset-6-touch{margin-left:50%}.column.is-7-touch{flex:none;width:58.33333%}.column.is-offset-7-touch{margin-left:58.33333%}.column.is-8-touch{flex:none;width:66.66667%}.column.is-offset-8-touch{margin-left:66.66667%}.column.is-9-touch{flex:none;width:75%}.column.is-offset-9-touch{margin-left:75%}.column.is-10-touch{flex:none;width:83.33333%}.column.is-offset-10-touch{margin-left:83.33333%}.column.is-11-touch{flex:none;width:91.66667%}.column.is-offset-11-touch{margin-left:91.66667%}.column.is-12-touch{flex:none;width:100%}.column.is-offset-12-touch{margin-left:100%}}@media screen and (min-width:1024px){.column.is-narrow-desktop{flex:none}.column.is-full-desktop{flex:none;width:100%}.column.is-three-quarters-desktop{flex:none;width:75%}.column.is-two-thirds-desktop{flex:none;width:66.6666%}.column.is-half-desktop{flex:none;width:50%}.column.is-one-third-desktop{flex:none;width:33.3333%}.column.is-one-quarter-desktop{flex:none;width:25%}.column.is-one-fifth-desktop{flex:none;width:20%}.column.is-two-fifths-desktop{flex:none;width:40%}.column.is-three-fifths-desktop{flex:none;width:60%}.column.is-four-fifths-desktop{flex:none;width:80%}.column.is-offset-three-quarters-desktop{margin-left:75%}.column.is-offset-two-thirds-desktop{margin-left:66.6666%}.column.is-offset-half-desktop{margin-left:50%}.column.is-offset-one-third-desktop{margin-left:33.3333%}.column.is-offset-one-quarter-desktop{margin-left:25%}.column.is-offset-one-fifth-desktop{margin-left:20%}.column.is-offset-two-fifths-desktop{margin-left:40%}.column.is-offset-three-fifths-desktop{margin-left:60%}.column.is-offset-four-fifths-desktop{margin-left:80%}.column.is-0-desktop{flex:none;width:0%}.column.is-offset-0-desktop{margin-left:0}.column.is-1-desktop{flex:none;width:8.33333%}.column.is-offset-1-desktop{margin-left:8.33333%}.column.is-2-desktop{flex:none;width:16.66667%}.column.is-offset-2-desktop{margin-left:16.66667%}.column.is-3-desktop{flex:none;width:25%}.column.is-offset-3-desktop{margin-left:25%}.column.is-4-desktop{flex:none;width:33.33333%}.column.is-offset-4-desktop{margin-left:33.33333%}.column.is-5-desktop{flex:none;width:41.66667%}.column.is-offset-5-desktop{margin-left:41.66667%}.column.is-6-desktop{flex:none;width:50%}.column.is-offset-6-desktop{margin-left:50%}.column.is-7-desktop{flex:none;width:58.33333%}.column.is-offset-7-desktop{margin-left:58.33333%}.column.is-8-desktop{flex:none;width:66.66667%}.column.is-offset-8-desktop{margin-left:66.66667%}.column.is-9-desktop{flex:none;width:75%}.column.is-offset-9-desktop{margin-left:75%}.column.is-10-desktop{flex:none;width:83.33333%}.column.is-offset-10-desktop{margin-left:83.33333%}.column.is-11-desktop{flex:none;width:91.66667%}.column.is-offset-11-desktop{margin-left:91.66667%}.column.is-12-desktop{flex:none;width:100%}.column.is-offset-12-desktop{margin-left:100%}}@media screen and (min-width:1216px){.column.is-narrow-widescreen{flex:none}.column.is-full-widescreen{flex:none;width:100%}.column.is-three-quarters-widescreen{flex:none;width:75%}.column.is-two-thirds-widescreen{flex:none;width:66.6666%}.column.is-half-widescreen{flex:none;width:50%}.column.is-one-third-widescreen{flex:none;width:33.3333%}.column.is-one-quarter-widescreen{flex:none;width:25%}.column.is-one-fifth-widescreen{flex:none;width:20%}.column.is-two-fifths-widescreen{flex:none;width:40%}.column.is-three-fifths-widescreen{flex:none;width:60%}.column.is-four-fifths-widescreen{flex:none;width:80%}.column.is-offset-three-quarters-widescreen{margin-left:75%}.column.is-offset-two-thirds-widescreen{margin-left:66.6666%}.column.is-offset-half-widescreen{margin-left:50%}.column.is-offset-one-third-widescreen{margin-left:33.3333%}.column.is-offset-one-quarter-widescreen{margin-left:25%}.column.is-offset-one-fifth-widescreen{margin-left:20%}.column.is-offset-two-fifths-widescreen{margin-left:40%}.column.is-offset-three-fifths-widescreen{margin-left:60%}.column.is-offset-four-fifths-widescreen{margin-left:80%}.column.is-0-widescreen{flex:none;width:0%}.column.is-offset-0-widescreen{margin-left:0}.column.is-1-widescreen{flex:none;width:8.33333%}.column.is-offset-1-widescreen{margin-left:8.33333%}.column.is-2-widescreen{flex:none;width:16.66667%}.column.is-offset-2-widescreen{margin-left:16.66667%}.column.is-3-widescreen{flex:none;width:25%}.column.is-offset-3-widescreen{margin-left:25%}.column.is-4-widescreen{flex:none;width:33.33333%}.column.is-offset-4-widescreen{margin-left:33.33333%}.column.is-5-widescreen{flex:none;width:41.66667%}.column.is-offset-5-widescreen{margin-left:41.66667%}.column.is-6-widescreen{flex:none;width:50%}.column.is-offset-6-widescreen{margin-left:50%}.column.is-7-widescreen{flex:none;width:58.33333%}.column.is-offset-7-widescreen{margin-left:58.33333%}.column.is-8-widescreen{flex:none;width:66.66667%}.column.is-offset-8-widescreen{margin-left:66.66667%}.column.is-9-widescreen{flex:none;width:75%}.column.is-offset-9-widescreen{margin-left:75%}.column.is-10-widescreen{flex:none;width:83.33333%}.column.is-offset-10-widescreen{margin-left:83.33333%}.column.is-11-widescreen{flex:none;width:91.66667%}.column.is-offset-11-widescreen{margin-left:91.66667%}.column.is-12-widescreen{flex:none;width:100%}.column.is-offset-12-widescreen{margin-left:100%}}@media screen and (min-width:1408px){.column.is-narrow-fullhd{flex:none}.column.is-full-fullhd{flex:none;width:100%}.column.is-three-quarters-fullhd{flex:none;width:75%}.column.is-two-thirds-fullhd{flex:none;width:66.6666%}.column.is-half-fullhd{flex:none;width:50%}.column.is-one-third-fullhd{flex:none;width:33.3333%}.column.is-one-quarter-fullhd{flex:none;width:25%}.column.is-one-fifth-fullhd{flex:none;width:20%}.column.is-two-fifths-fullhd{flex:none;width:40%}.column.is-three-fifths-fullhd{flex:none;width:60%}.column.is-four-fifths-fullhd{flex:none;width:80%}.column.is-offset-three-quarters-fullhd{margin-left:75%}.column.is-offset-two-thirds-fullhd{margin-left:66.6666%}.column.is-offset-half-fullhd{margin-left:50%}.column.is-offset-one-third-fullhd{margin-left:33.3333%}.column.is-offset-one-quarter-fullhd{margin-left:25%}.column.is-offset-one-fifth-fullhd{margin-left:20%}.column.is-offset-two-fifths-fullhd{margin-left:40%}.column.is-offset-three-fifths-fullhd{margin-left:60%}.column.is-offset-four-fifths-fullhd{margin-left:80%}.column.is-0-fullhd{flex:none;width:0%}.column.is-offset-0-fullhd{margin-left:0}.column.is-1-fullhd{flex:none;width:8.33333%}.column.is-offset-1-fullhd{margin-left:8.33333%}.column.is-2-fullhd{flex:none;width:16.66667%}.column.is-offset-2-fullhd{margin-left:16.66667%}.column.is-3-fullhd{flex:none;width:25%}.column.is-offset-3-fullhd{margin-left:25%}.column.is-4-fullhd{flex:none;width:33.33333%}.column.is-offset-4-fullhd{margin-left:33.33333%}.column.is-5-fullhd{flex:none;width:41.66667%}.column.is-offset-5-fullhd{margin-left:41.66667%}.column.is-6-fullhd{flex:none;width:50%}.column.is-offset-6-fullhd{margin-left:50%}.column.is-7-fullhd{flex:none;width:58.33333%}.column.is-offset-7-fullhd{margin-left:58.33333%}.column.is-8-fullhd{flex:none;width:66.66667%}.column.is-offset-8-fullhd{margin-left:66.66667%}.column.is-9-fullhd{flex:none;width:75%}.column.is-offset-9-fullhd{margin-left:75%}.column.is-10-fullhd{flex:none;width:83.33333%}.column.is-offset-10-fullhd{margin-left:83.33333%}.column.is-11-fullhd{flex:none;width:91.66667%}.column.is-offset-11-fullhd{margin-left:91.66667%}.column.is-12-fullhd{flex:none;width:100%}.column.is-offset-12-fullhd{margin-left:100%}}.columns{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.columns:last-child{margin-bottom:-.75rem}.columns:not(:last-child){margin-bottom:calc(1.5rem - .75rem)}.columns.is-centered{justify-content:center}.columns.is-gapless{margin-left:0;margin-right:0;margin-top:0}.columns.is-gapless>.column{margin:0;padding:0!important}.columns.is-gapless:not(:last-child){margin-bottom:1.5rem}.columns.is-gapless:last-child{margin-bottom:0}.columns.is-mobile{display:flex}.columns.is-multiline{flex-wrap:wrap}.columns.is-vcentered{align-items:center}@media screen and (min-width:769px),print{.columns:not(.is-desktop){display:flex}}@media screen and (min-width:1024px){.columns.is-desktop{display:flex}}.columns.is-variable{--columnGap:0.75rem;margin-left:calc(-1 * var(--columnGap));margin-right:calc(-1 * var(--columnGap))}.columns.is-variable .column{padding-left:var(--columnGap);padding-right:var(--columnGap)}.columns.is-variable.is-0{--columnGap:0rem}@media screen and (max-width:768px){.columns.is-variable.is-0-mobile{--columnGap:0rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-0-tablet{--columnGap:0rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-0-tablet-only{--columnGap:0rem}}@media screen and (max-width:1023px){.columns.is-variable.is-0-touch{--columnGap:0rem}}@media screen and (min-width:1024px){.columns.is-variable.is-0-desktop{--columnGap:0rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-0-desktop-only{--columnGap:0rem}}@media screen and (min-width:1216px){.columns.is-variable.is-0-widescreen{--columnGap:0rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-0-widescreen-only{--columnGap:0rem}}@media screen and (min-width:1408px){.columns.is-variable.is-0-fullhd{--columnGap:0rem}}.columns.is-variable.is-1{--columnGap:0.25rem}@media screen and (max-width:768px){.columns.is-variable.is-1-mobile{--columnGap:0.25rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-1-tablet{--columnGap:0.25rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-1-tablet-only{--columnGap:0.25rem}}@media screen and (max-width:1023px){.columns.is-variable.is-1-touch{--columnGap:0.25rem}}@media screen and (min-width:1024px){.columns.is-variable.is-1-desktop{--columnGap:0.25rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-1-desktop-only{--columnGap:0.25rem}}@media screen and (min-width:1216px){.columns.is-variable.is-1-widescreen{--columnGap:0.25rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-1-widescreen-only{--columnGap:0.25rem}}@media screen and (min-width:1408px){.columns.is-variable.is-1-fullhd{--columnGap:0.25rem}}.columns.is-variable.is-2{--columnGap:0.5rem}@media screen and (max-width:768px){.columns.is-variable.is-2-mobile{--columnGap:0.5rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-2-tablet{--columnGap:0.5rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-2-tablet-only{--columnGap:0.5rem}}@media screen and (max-width:1023px){.columns.is-variable.is-2-touch{--columnGap:0.5rem}}@media screen and (min-width:1024px){.columns.is-variable.is-2-desktop{--columnGap:0.5rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-2-desktop-only{--columnGap:0.5rem}}@media screen and (min-width:1216px){.columns.is-variable.is-2-widescreen{--columnGap:0.5rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-2-widescreen-only{--columnGap:0.5rem}}@media screen and (min-width:1408px){.columns.is-variable.is-2-fullhd{--columnGap:0.5rem}}.columns.is-variable.is-3{--columnGap:0.75rem}@media screen and (max-width:768px){.columns.is-variable.is-3-mobile{--columnGap:0.75rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-3-tablet{--columnGap:0.75rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-3-tablet-only{--columnGap:0.75rem}}@media screen and (max-width:1023px){.columns.is-variable.is-3-touch{--columnGap:0.75rem}}@media screen and (min-width:1024px){.columns.is-variable.is-3-desktop{--columnGap:0.75rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-3-desktop-only{--columnGap:0.75rem}}@media screen and (min-width:1216px){.columns.is-variable.is-3-widescreen{--columnGap:0.75rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-3-widescreen-only{--columnGap:0.75rem}}@media screen and (min-width:1408px){.columns.is-variable.is-3-fullhd{--columnGap:0.75rem}}.columns.is-variable.is-4{--columnGap:1rem}@media screen and (max-width:768px){.columns.is-variable.is-4-mobile{--columnGap:1rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-4-tablet{--columnGap:1rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-4-tablet-only{--columnGap:1rem}}@media screen and (max-width:1023px){.columns.is-variable.is-4-touch{--columnGap:1rem}}@media screen and (min-width:1024px){.columns.is-variable.is-4-desktop{--columnGap:1rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-4-desktop-only{--columnGap:1rem}}@media screen and (min-width:1216px){.columns.is-variable.is-4-widescreen{--columnGap:1rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-4-widescreen-only{--columnGap:1rem}}@media screen and (min-width:1408px){.columns.is-variable.is-4-fullhd{--columnGap:1rem}}.columns.is-variable.is-5{--columnGap:1.25rem}@media screen and (max-width:768px){.columns.is-variable.is-5-mobile{--columnGap:1.25rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-5-tablet{--columnGap:1.25rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-5-tablet-only{--columnGap:1.25rem}}@media screen and (max-width:1023px){.columns.is-variable.is-5-touch{--columnGap:1.25rem}}@media screen and (min-width:1024px){.columns.is-variable.is-5-desktop{--columnGap:1.25rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-5-desktop-only{--columnGap:1.25rem}}@media screen and (min-width:1216px){.columns.is-variable.is-5-widescreen{--columnGap:1.25rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-5-widescreen-only{--columnGap:1.25rem}}@media screen and (min-width:1408px){.columns.is-variable.is-5-fullhd{--columnGap:1.25rem}}.columns.is-variable.is-6{--columnGap:1.5rem}@media screen and (max-width:768px){.columns.is-variable.is-6-mobile{--columnGap:1.5rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-6-tablet{--columnGap:1.5rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-6-tablet-only{--columnGap:1.5rem}}@media screen and (max-width:1023px){.columns.is-variable.is-6-touch{--columnGap:1.5rem}}@media screen and (min-width:1024px){.columns.is-variable.is-6-desktop{--columnGap:1.5rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-6-desktop-only{--columnGap:1.5rem}}@media screen and (min-width:1216px){.columns.is-variable.is-6-widescreen{--columnGap:1.5rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-6-widescreen-only{--columnGap:1.5rem}}@media screen and (min-width:1408px){.columns.is-variable.is-6-fullhd{--columnGap:1.5rem}}.columns.is-variable.is-7{--columnGap:1.75rem}@media screen and (max-width:768px){.columns.is-variable.is-7-mobile{--columnGap:1.75rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-7-tablet{--columnGap:1.75rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-7-tablet-only{--columnGap:1.75rem}}@media screen and (max-width:1023px){.columns.is-variable.is-7-touch{--columnGap:1.75rem}}@media screen and (min-width:1024px){.columns.is-variable.is-7-desktop{--columnGap:1.75rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-7-desktop-only{--columnGap:1.75rem}}@media screen and (min-width:1216px){.columns.is-variable.is-7-widescreen{--columnGap:1.75rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-7-widescreen-only{--columnGap:1.75rem}}@media screen and (min-width:1408px){.columns.is-variable.is-7-fullhd{--columnGap:1.75rem}}.columns.is-variable.is-8{--columnGap:2rem}@media screen and (max-width:768px){.columns.is-variable.is-8-mobile{--columnGap:2rem}}@media screen and (min-width:769px),print{.columns.is-variable.is-8-tablet{--columnGap:2rem}}@media screen and (min-width:769px) and (max-width:1023px){.columns.is-variable.is-8-tablet-only{--columnGap:2rem}}@media screen and (max-width:1023px){.columns.is-variable.is-8-touch{--columnGap:2rem}}@media screen and (min-width:1024px){.columns.is-variable.is-8-desktop{--columnGap:2rem}}@media screen and (min-width:1024px) and (max-width:1215px){.columns.is-variable.is-8-desktop-only{--columnGap:2rem}}@media screen and (min-width:1216px){.columns.is-variable.is-8-widescreen{--columnGap:2rem}}@media screen and (min-width:1216px) and (max-width:1407px){.columns.is-variable.is-8-widescreen-only{--columnGap:2rem}}@media screen and (min-width:1408px){.columns.is-variable.is-8-fullhd{--columnGap:2rem}}.tile{align-items:stretch;display:block;flex-basis:0;flex-grow:1;flex-shrink:1;min-height:-webkit-min-content;min-height:-moz-min-content;min-height:min-content}.tile.is-ancestor{margin-left:-.75rem;margin-right:-.75rem;margin-top:-.75rem}.tile.is-ancestor:last-child{margin-bottom:-.75rem}.tile.is-ancestor:not(:last-child){margin-bottom:.75rem}.tile.is-child{margin:0!important}.tile.is-parent{padding:.75rem}.tile.is-vertical{flex-direction:column}.tile.is-vertical>.tile.is-child:not(:last-child){margin-bottom:1.5rem!important}@media screen and (min-width:769px),print{.tile:not(.is-child){display:flex}.tile.is-1{flex:none;width:8.33333%}.tile.is-2{flex:none;width:16.66667%}.tile.is-3{flex:none;width:25%}.tile.is-4{flex:none;width:33.33333%}.tile.is-5{flex:none;width:41.66667%}.tile.is-6{flex:none;width:50%}.tile.is-7{flex:none;width:58.33333%}.tile.is-8{flex:none;width:66.66667%}.tile.is-9{flex:none;width:75%}.tile.is-10{flex:none;width:83.33333%}.tile.is-11{flex:none;width:91.66667%}.tile.is-12{flex:none;width:100%}}.has-text-white{color:#fff!important}a.has-text-white:focus,a.has-text-white:hover{color:#e6e6e6!important}.has-background-white{background-color:#fff!important}.has-text-black{color:#0a0a0a!important}a.has-text-black:focus,a.has-text-black:hover{color:#000!important}.has-background-black{background-color:#0a0a0a!important}.has-text-light{color:#f5f5f5!important}a.has-text-light:focus,a.has-text-light:hover{color:#dbdbdb!important}.has-background-light{background-color:#f5f5f5!important}.has-text-dark{color:#363636!important}a.has-text-dark:focus,a.has-text-dark:hover{color:#1c1c1c!important}.has-background-dark{background-color:#363636!important}.has-text-primary{color:#00d1b2!important}a.has-text-primary:focus,a.has-text-primary:hover{color:#009e86!important}.has-background-primary{background-color:#00d1b2!important}.has-text-primary-light{color:#ebfffc!important}a.has-text-primary-light:focus,a.has-text-primary-light:hover{color:#b8fff4!important}.has-background-primary-light{background-color:#ebfffc!important}.has-text-primary-dark{color:#00947e!important}a.has-text-primary-dark:focus,a.has-text-primary-dark:hover{color:#00c7a9!important}.has-background-primary-dark{background-color:#00947e!important}.has-text-link{color:#3273dc!important}a.has-text-link:focus,a.has-text-link:hover{color:#205bbc!important}.has-background-link{background-color:#3273dc!important}.has-text-link-light{color:#eef3fc!important}a.has-text-link-light:focus,a.has-text-link-light:hover{color:#c2d5f5!important}.has-background-link-light{background-color:#eef3fc!important}.has-text-link-dark{color:#2160c4!important}a.has-text-link-dark:focus,a.has-text-link-dark:hover{color:#3b79de!important}.has-background-link-dark{background-color:#2160c4!important}.has-text-info{color:#3298dc!important}a.has-text-info:focus,a.has-text-info:hover{color:#207dbc!important}.has-background-info{background-color:#3298dc!important}.has-text-info-light{color:#eef6fc!important}a.has-text-info-light:focus,a.has-text-info-light:hover{color:#c2e0f5!important}.has-background-info-light{background-color:#eef6fc!important}.has-text-info-dark{color:#1d72aa!important}a.has-text-info-dark:focus,a.has-text-info-dark:hover{color:#248fd6!important}.has-background-info-dark{background-color:#1d72aa!important}.has-text-success{color:#48c774!important}a.has-text-success:focus,a.has-text-success:hover{color:#34a85c!important}.has-background-success{background-color:#48c774!important}.has-text-success-light{color:#effaf3!important}a.has-text-success-light:focus,a.has-text-success-light:hover{color:#c8eed6!important}.has-background-success-light{background-color:#effaf3!important}.has-text-success-dark{color:#257942!important}a.has-text-success-dark:focus,a.has-text-success-dark:hover{color:#31a058!important}.has-background-success-dark{background-color:#257942!important}.has-text-warning{color:#ffdd57!important}a.has-text-warning:focus,a.has-text-warning:hover{color:#ffd324!important}.has-background-warning{background-color:#ffdd57!important}.has-text-warning-light{color:#fffbeb!important}a.has-text-warning-light:focus,a.has-text-warning-light:hover{color:#fff1b8!important}.has-background-warning-light{background-color:#fffbeb!important}.has-text-warning-dark{color:#947600!important}a.has-text-warning-dark:focus,a.has-text-warning-dark:hover{color:#c79f00!important}.has-background-warning-dark{background-color:#947600!important}.has-text-danger{color:#f14668!important}a.has-text-danger:focus,a.has-text-danger:hover{color:#ee1742!important}.has-background-danger{background-color:#f14668!important}.has-text-danger-light{color:#feecf0!important}a.has-text-danger-light:focus,a.has-text-danger-light:hover{color:#fabdc9!important}.has-background-danger-light{background-color:#feecf0!important}.has-text-danger-dark{color:#cc0f35!important}a.has-text-danger-dark:focus,a.has-text-danger-dark:hover{color:#ee2049!important}.has-background-danger-dark{background-color:#cc0f35!important}.has-text-black-bis{color:#121212!important}.has-background-black-bis{background-color:#121212!important}.has-text-black-ter{color:#242424!important}.has-background-black-ter{background-color:#242424!important}.has-text-grey-darker{color:#363636!important}.has-background-grey-darker{background-color:#363636!important}.has-text-grey-dark{color:#4a4a4a!important}.has-background-grey-dark{background-color:#4a4a4a!important}.has-text-grey{color:#7a7a7a!important}.has-background-grey{background-color:#7a7a7a!important}.has-text-grey-light{color:#b5b5b5!important}.has-background-grey-light{background-color:#b5b5b5!important}.has-text-grey-lighter{color:#dbdbdb!important}.has-background-grey-lighter{background-color:#dbdbdb!important}.has-text-white-ter{color:#f5f5f5!important}.has-background-white-ter{background-color:#f5f5f5!important}.has-text-white-bis{color:#fafafa!important}.has-background-white-bis{background-color:#fafafa!important}.is-clearfix::after{clear:both;content:" ";display:table}.is-pulled-left{float:left!important}.is-pulled-right{float:right!important}.is-radiusless{border-radius:0!important}.is-shadowless{box-shadow:none!important}.is-clipped{overflow:hidden!important}.is-relative{position:relative!important}.is-marginless{margin:0!important}.is-paddingless{padding:0!important}.mt-0{margin-top:0!important}.mr-0{margin-right:0!important}.mb-0{margin-bottom:0!important}.ml-0{margin-left:0!important}.mx-0{margin-left:0!important;margin-right:0!important}.my-0{margin-top:0!important;margin-bottom:0!important}.mt-1{margin-top:.25rem!important}.mr-1{margin-right:.25rem!important}.mb-1{margin-bottom:.25rem!important}.ml-1{margin-left:.25rem!important}.mx-1{margin-left:.25rem!important;margin-right:.25rem!important}.my-1{margin-top:.25rem!important;margin-bottom:.25rem!important}.mt-2{margin-top:.5rem!important}.mr-2{margin-right:.5rem!important}.mb-2{margin-bottom:.5rem!important}.ml-2{margin-left:.5rem!important}.mx-2{margin-left:.5rem!important;margin-right:.5rem!important}.my-2{margin-top:.5rem!important;margin-bottom:.5rem!important}.mt-3{margin-top:.75rem!important}.mr-3{margin-right:.75rem!important}.mb-3{margin-bottom:.75rem!important}.ml-3{margin-left:.75rem!important}.mx-3{margin-left:.75rem!important;margin-right:.75rem!important}.my-3{margin-top:.75rem!important;margin-bottom:.75rem!important}.mt-4{margin-top:1rem!important}.mr-4{margin-right:1rem!important}.mb-4{margin-bottom:1rem!important}.ml-4{margin-left:1rem!important}.mx-4{margin-left:1rem!important;margin-right:1rem!important}.my-4{margin-top:1rem!important;margin-bottom:1rem!important}.mt-5{margin-top:1.5rem!important}.mr-5{margin-right:1.5rem!important}.mb-5{margin-bottom:1.5rem!important}.ml-5{margin-left:1.5rem!important}.mx-5{margin-left:1.5rem!important;margin-right:1.5rem!important}.my-5{margin-top:1.5rem!important;margin-bottom:1.5rem!important}.mt-6{margin-top:3rem!important}.mr-6{margin-right:3rem!important}.mb-6{margin-bottom:3rem!important}.ml-6{margin-left:3rem!important}.mx-6{margin-left:3rem!important;margin-right:3rem!important}.my-6{margin-top:3rem!important;margin-bottom:3rem!important}.pt-0{padding-top:0!important}.pr-0{padding-right:0!important}.pb-0{padding-bottom:0!important}.pl-0{padding-left:0!important}.px-0{padding-left:0!important;padding-right:0!important}.py-0{padding-top:0!important;padding-bottom:0!important}.pt-1{padding-top:.25rem!important}.pr-1{padding-right:.25rem!important}.pb-1{padding-bottom:.25rem!important}.pl-1{padding-left:.25rem!important}.px-1{padding-left:.25rem!important;padding-right:.25rem!important}.py-1{padding-top:.25rem!important;padding-bottom:.25rem!important}.pt-2{padding-top:.5rem!important}.pr-2{padding-right:.5rem!important}.pb-2{padding-bottom:.5rem!important}.pl-2{padding-left:.5rem!important}.px-2{padding-left:.5rem!important;padding-right:.5rem!important}.py-2{padding-top:.5rem!important;padding-bottom:.5rem!important}.pt-3{padding-top:.75rem!important}.pr-3{padding-right:.75rem!important}.pb-3{padding-bottom:.75rem!important}.pl-3{padding-left:.75rem!important}.px-3{padding-left:.75rem!important;padding-right:.75rem!important}.py-3{padding-top:.75rem!important;padding-bottom:.75rem!important}.pt-4{padding-top:1rem!important}.pr-4{padding-right:1rem!important}.pb-4{padding-bottom:1rem!important}.pl-4{padding-left:1rem!important}.px-4{padding-left:1rem!important;padding-right:1rem!important}.py-4{padding-top:1rem!important;padding-bottom:1rem!important}.pt-5{padding-top:1.5rem!important}.pr-5{padding-right:1.5rem!important}.pb-5{padding-bottom:1.5rem!important}.pl-5{padding-left:1.5rem!important}.px-5{padding-left:1.5rem!important;padding-right:1.5rem!important}.py-5{padding-top:1.5rem!important;padding-bottom:1.5rem!important}.pt-6{padding-top:3rem!important}.pr-6{padding-right:3rem!important}.pb-6{padding-bottom:3rem!important}.pl-6{padding-left:3rem!important}.px-6{padding-left:3rem!important;padding-right:3rem!important}.py-6{padding-top:3rem!important;padding-bottom:3rem!important}.is-size-1{font-size:3rem!important}.is-size-2{font-size:2.5rem!important}.is-size-3{font-size:2rem!important}.is-size-4{font-size:1.5rem!important}.is-size-5{font-size:1.25rem!important}.is-size-6{font-size:1rem!important}.is-size-7{font-size:.75rem!important}@media screen and (max-width:768px){.is-size-1-mobile{font-size:3rem!important}.is-size-2-mobile{font-size:2.5rem!important}.is-size-3-mobile{font-size:2rem!important}.is-size-4-mobile{font-size:1.5rem!important}.is-size-5-mobile{font-size:1.25rem!important}.is-size-6-mobile{font-size:1rem!important}.is-size-7-mobile{font-size:.75rem!important}}@media screen and (min-width:769px),print{.is-size-1-tablet{font-size:3rem!important}.is-size-2-tablet{font-size:2.5rem!important}.is-size-3-tablet{font-size:2rem!important}.is-size-4-tablet{font-size:1.5rem!important}.is-size-5-tablet{font-size:1.25rem!important}.is-size-6-tablet{font-size:1rem!important}.is-size-7-tablet{font-size:.75rem!important}}@media screen and (max-width:1023px){.is-size-1-touch{font-size:3rem!important}.is-size-2-touch{font-size:2.5rem!important}.is-size-3-touch{font-size:2rem!important}.is-size-4-touch{font-size:1.5rem!important}.is-size-5-touch{font-size:1.25rem!important}.is-size-6-touch{font-size:1rem!important}.is-size-7-touch{font-size:.75rem!important}}@media screen and (min-width:1024px){.is-size-1-desktop{font-size:3rem!important}.is-size-2-desktop{font-size:2.5rem!important}.is-size-3-desktop{font-size:2rem!important}.is-size-4-desktop{font-size:1.5rem!important}.is-size-5-desktop{font-size:1.25rem!important}.is-size-6-desktop{font-size:1rem!important}.is-size-7-desktop{font-size:.75rem!important}}@media screen and (min-width:1216px){.is-size-1-widescreen{font-size:3rem!important}.is-size-2-widescreen{font-size:2.5rem!important}.is-size-3-widescreen{font-size:2rem!important}.is-size-4-widescreen{font-size:1.5rem!important}.is-size-5-widescreen{font-size:1.25rem!important}.is-size-6-widescreen{font-size:1rem!important}.is-size-7-widescreen{font-size:.75rem!important}}@media screen and (min-width:1408px){.is-size-1-fullhd{font-size:3rem!important}.is-size-2-fullhd{font-size:2.5rem!important}.is-size-3-fullhd{font-size:2rem!important}.is-size-4-fullhd{font-size:1.5rem!important}.is-size-5-fullhd{font-size:1.25rem!important}.is-size-6-fullhd{font-size:1rem!important}.is-size-7-fullhd{font-size:.75rem!important}}.has-text-centered{text-align:center!important}.has-text-justified{text-align:justify!important}.has-text-left{text-align:left!important}.has-text-right{text-align:right!important}@media screen and (max-width:768px){.has-text-centered-mobile{text-align:center!important}}@media screen and (min-width:769px),print{.has-text-centered-tablet{text-align:center!important}}@media screen and (min-width:769px) and (max-width:1023px){.has-text-centered-tablet-only{text-align:center!important}}@media screen and (max-width:1023px){.has-text-centered-touch{text-align:center!important}}@media screen and (min-width:1024px){.has-text-centered-desktop{text-align:center!important}}@media screen and (min-width:1024px) and (max-width:1215px){.has-text-centered-desktop-only{text-align:center!important}}@media screen and (min-width:1216px){.has-text-centered-widescreen{text-align:center!important}}@media screen and (min-width:1216px) and (max-width:1407px){.has-text-centered-widescreen-only{text-align:center!important}}@media screen and (min-width:1408px){.has-text-centered-fullhd{text-align:center!important}}@media screen and (max-width:768px){.has-text-justified-mobile{text-align:justify!important}}@media screen and (min-width:769px),print{.has-text-justified-tablet{text-align:justify!important}}@media screen and (min-width:769px) and (max-width:1023px){.has-text-justified-tablet-only{text-align:justify!important}}@media screen and (max-width:1023px){.has-text-justified-touch{text-align:justify!important}}@media screen and (min-width:1024px){.has-text-justified-desktop{text-align:justify!important}}@media screen and (min-width:1024px) and (max-width:1215px){.has-text-justified-desktop-only{text-align:justify!important}}@media screen and (min-width:1216px){.has-text-justified-widescreen{text-align:justify!important}}@media screen and (min-width:1216px) and (max-width:1407px){.has-text-justified-widescreen-only{text-align:justify!important}}@media screen and (min-width:1408px){.has-text-justified-fullhd{text-align:justify!important}}@media screen and (max-width:768px){.has-text-left-mobile{text-align:left!important}}@media screen and (min-width:769px),print{.has-text-left-tablet{text-align:left!important}}@media screen and (min-width:769px) and (max-width:1023px){.has-text-left-tablet-only{text-align:left!important}}@media screen and (max-width:1023px){.has-text-left-touch{text-align:left!important}}@media screen and (min-width:1024px){.has-text-left-desktop{text-align:left!important}}@media screen and (min-width:1024px) and (max-width:1215px){.has-text-left-desktop-only{text-align:left!important}}@media screen and (min-width:1216px){.has-text-left-widescreen{text-align:left!important}}@media screen and (min-width:1216px) and (max-width:1407px){.has-text-left-widescreen-only{text-align:left!important}}@media screen and (min-width:1408px){.has-text-left-fullhd{text-align:left!important}}@media screen and (max-width:768px){.has-text-right-mobile{text-align:right!important}}@media screen and (min-width:769px),print{.has-text-right-tablet{text-align:right!important}}@media screen and (min-width:769px) and (max-width:1023px){.has-text-right-tablet-only{text-align:right!important}}@media screen and (max-width:1023px){.has-text-right-touch{text-align:right!important}}@media screen and (min-width:1024px){.has-text-right-desktop{text-align:right!important}}@media screen and (min-width:1024px) and (max-width:1215px){.has-text-right-desktop-only{text-align:right!important}}@media screen and (min-width:1216px){.has-text-right-widescreen{text-align:right!important}}@media screen and (min-width:1216px) and (max-width:1407px){.has-text-right-widescreen-only{text-align:right!important}}@media screen and (min-width:1408px){.has-text-right-fullhd{text-align:right!important}}.is-capitalized{text-transform:capitalize!important}.is-lowercase{text-transform:lowercase!important}.is-uppercase{text-transform:uppercase!important}.is-italic{font-style:italic!important}.has-text-weight-light{font-weight:300!important}.has-text-weight-normal{font-weight:400!important}.has-text-weight-medium{font-weight:500!important}.has-text-weight-semibold{font-weight:600!important}.has-text-weight-bold{font-weight:700!important}.is-family-primary{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-secondary{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-sans-serif{font-family:BlinkMacSystemFont,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Fira Sans","Droid Sans","Helvetica Neue",Helvetica,Arial,sans-serif!important}.is-family-monospace{font-family:monospace!important}.is-family-code{font-family:monospace!important}.is-block{display:block!important}@media screen and (max-width:768px){.is-block-mobile{display:block!important}}@media screen and (min-width:769px),print{.is-block-tablet{display:block!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-block-tablet-only{display:block!important}}@media screen and (max-width:1023px){.is-block-touch{display:block!important}}@media screen and (min-width:1024px){.is-block-desktop{display:block!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-block-desktop-only{display:block!important}}@media screen and (min-width:1216px){.is-block-widescreen{display:block!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-block-widescreen-only{display:block!important}}@media screen and (min-width:1408px){.is-block-fullhd{display:block!important}}.is-flex{display:flex!important}@media screen and (max-width:768px){.is-flex-mobile{display:flex!important}}@media screen and (min-width:769px),print{.is-flex-tablet{display:flex!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-flex-tablet-only{display:flex!important}}@media screen and (max-width:1023px){.is-flex-touch{display:flex!important}}@media screen and (min-width:1024px){.is-flex-desktop{display:flex!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-flex-desktop-only{display:flex!important}}@media screen and (min-width:1216px){.is-flex-widescreen{display:flex!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-flex-widescreen-only{display:flex!important}}@media screen and (min-width:1408px){.is-flex-fullhd{display:flex!important}}.is-inline{display:inline!important}@media screen and (max-width:768px){.is-inline-mobile{display:inline!important}}@media screen and (min-width:769px),print{.is-inline-tablet{display:inline!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-inline-tablet-only{display:inline!important}}@media screen and (max-width:1023px){.is-inline-touch{display:inline!important}}@media screen and (min-width:1024px){.is-inline-desktop{display:inline!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-inline-desktop-only{display:inline!important}}@media screen and (min-width:1216px){.is-inline-widescreen{display:inline!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-inline-widescreen-only{display:inline!important}}@media screen and (min-width:1408px){.is-inline-fullhd{display:inline!important}}.is-inline-block{display:inline-block!important}@media screen and (max-width:768px){.is-inline-block-mobile{display:inline-block!important}}@media screen and (min-width:769px),print{.is-inline-block-tablet{display:inline-block!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-inline-block-tablet-only{display:inline-block!important}}@media screen and (max-width:1023px){.is-inline-block-touch{display:inline-block!important}}@media screen and (min-width:1024px){.is-inline-block-desktop{display:inline-block!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-inline-block-desktop-only{display:inline-block!important}}@media screen and (min-width:1216px){.is-inline-block-widescreen{display:inline-block!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-inline-block-widescreen-only{display:inline-block!important}}@media screen and (min-width:1408px){.is-inline-block-fullhd{display:inline-block!important}}.is-inline-flex{display:inline-flex!important}@media screen and (max-width:768px){.is-inline-flex-mobile{display:inline-flex!important}}@media screen and (min-width:769px),print{.is-inline-flex-tablet{display:inline-flex!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-inline-flex-tablet-only{display:inline-flex!important}}@media screen and (max-width:1023px){.is-inline-flex-touch{display:inline-flex!important}}@media screen and (min-width:1024px){.is-inline-flex-desktop{display:inline-flex!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-inline-flex-desktop-only{display:inline-flex!important}}@media screen and (min-width:1216px){.is-inline-flex-widescreen{display:inline-flex!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-inline-flex-widescreen-only{display:inline-flex!important}}@media screen and (min-width:1408px){.is-inline-flex-fullhd{display:inline-flex!important}}.is-hidden{display:none!important}.is-sr-only{border:none!important;clip:rect(0,0,0,0)!important;height:.01em!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:.01em!important}@media screen and (max-width:768px){.is-hidden-mobile{display:none!important}}@media screen and (min-width:769px),print{.is-hidden-tablet{display:none!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-hidden-tablet-only{display:none!important}}@media screen and (max-width:1023px){.is-hidden-touch{display:none!important}}@media screen and (min-width:1024px){.is-hidden-desktop{display:none!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-hidden-desktop-only{display:none!important}}@media screen and (min-width:1216px){.is-hidden-widescreen{display:none!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-hidden-widescreen-only{display:none!important}}@media screen and (min-width:1408px){.is-hidden-fullhd{display:none!important}}.is-invisible{visibility:hidden!important}@media screen and (max-width:768px){.is-invisible-mobile{visibility:hidden!important}}@media screen and (min-width:769px),print{.is-invisible-tablet{visibility:hidden!important}}@media screen and (min-width:769px) and (max-width:1023px){.is-invisible-tablet-only{visibility:hidden!important}}@media screen and (max-width:1023px){.is-invisible-touch{visibility:hidden!important}}@media screen and (min-width:1024px){.is-invisible-desktop{visibility:hidden!important}}@media screen and (min-width:1024px) and (max-width:1215px){.is-invisible-desktop-only{visibility:hidden!important}}@media screen and (min-width:1216px){.is-invisible-widescreen{visibility:hidden!important}}@media screen and (min-width:1216px) and (max-width:1407px){.is-invisible-widescreen-only{visibility:hidden!important}}@media screen and (min-width:1408px){.is-invisible-fullhd{visibility:hidden!important}}.hero{align-items:stretch;display:flex;flex-direction:column;justify-content:space-between}.hero .navbar{background:0 0}.hero .tabs ul{border-bottom:none}.hero.is-white{background-color:#fff;color:#0a0a0a}.hero.is-white a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-white strong{color:inherit}.hero.is-white .title{color:#0a0a0a}.hero.is-white .subtitle{color:rgba(10,10,10,.9)}.hero.is-white .subtitle a:not(.button),.hero.is-white .subtitle strong{color:#0a0a0a}@media screen and (max-width:1023px){.hero.is-white .navbar-menu{background-color:#fff}}.hero.is-white .navbar-item,.hero.is-white .navbar-link{color:rgba(10,10,10,.7)}.hero.is-white .navbar-link.is-active,.hero.is-white .navbar-link:hover,.hero.is-white a.navbar-item.is-active,.hero.is-white a.navbar-item:hover{background-color:#f2f2f2;color:#0a0a0a}.hero.is-white .tabs a{color:#0a0a0a;opacity:.9}.hero.is-white .tabs a:hover{opacity:1}.hero.is-white .tabs li.is-active a{opacity:1}.hero.is-white .tabs.is-boxed a,.hero.is-white .tabs.is-toggle a{color:#0a0a0a}.hero.is-white .tabs.is-boxed a:hover,.hero.is-white .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-white .tabs.is-boxed li.is-active a,.hero.is-white .tabs.is-boxed li.is-active a:hover,.hero.is-white .tabs.is-toggle li.is-active a,.hero.is-white .tabs.is-toggle li.is-active a:hover{background-color:#0a0a0a;border-color:#0a0a0a;color:#fff}.hero.is-white.is-bold{background-image:linear-gradient(141deg,#e6e6e6 0,#fff 71%,#fff 100%)}@media screen and (max-width:768px){.hero.is-white.is-bold .navbar-menu{background-image:linear-gradient(141deg,#e6e6e6 0,#fff 71%,#fff 100%)}}.hero.is-black{background-color:#0a0a0a;color:#fff}.hero.is-black a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-black strong{color:inherit}.hero.is-black .title{color:#fff}.hero.is-black .subtitle{color:rgba(255,255,255,.9)}.hero.is-black .subtitle a:not(.button),.hero.is-black .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-black .navbar-menu{background-color:#0a0a0a}}.hero.is-black .navbar-item,.hero.is-black .navbar-link{color:rgba(255,255,255,.7)}.hero.is-black .navbar-link.is-active,.hero.is-black .navbar-link:hover,.hero.is-black a.navbar-item.is-active,.hero.is-black a.navbar-item:hover{background-color:#000;color:#fff}.hero.is-black .tabs a{color:#fff;opacity:.9}.hero.is-black .tabs a:hover{opacity:1}.hero.is-black .tabs li.is-active a{opacity:1}.hero.is-black .tabs.is-boxed a,.hero.is-black .tabs.is-toggle a{color:#fff}.hero.is-black .tabs.is-boxed a:hover,.hero.is-black .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-black .tabs.is-boxed li.is-active a,.hero.is-black .tabs.is-boxed li.is-active a:hover,.hero.is-black .tabs.is-toggle li.is-active a,.hero.is-black .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#0a0a0a}.hero.is-black.is-bold{background-image:linear-gradient(141deg,#000 0,#0a0a0a 71%,#181616 100%)}@media screen and (max-width:768px){.hero.is-black.is-bold .navbar-menu{background-image:linear-gradient(141deg,#000 0,#0a0a0a 71%,#181616 100%)}}.hero.is-light{background-color:#f5f5f5;color:rgba(0,0,0,.7)}.hero.is-light a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-light strong{color:inherit}.hero.is-light .title{color:rgba(0,0,0,.7)}.hero.is-light .subtitle{color:rgba(0,0,0,.9)}.hero.is-light .subtitle a:not(.button),.hero.is-light .subtitle strong{color:rgba(0,0,0,.7)}@media screen and (max-width:1023px){.hero.is-light .navbar-menu{background-color:#f5f5f5}}.hero.is-light .navbar-item,.hero.is-light .navbar-link{color:rgba(0,0,0,.7)}.hero.is-light .navbar-link.is-active,.hero.is-light .navbar-link:hover,.hero.is-light a.navbar-item.is-active,.hero.is-light a.navbar-item:hover{background-color:#e8e8e8;color:rgba(0,0,0,.7)}.hero.is-light .tabs a{color:rgba(0,0,0,.7);opacity:.9}.hero.is-light .tabs a:hover{opacity:1}.hero.is-light .tabs li.is-active a{opacity:1}.hero.is-light .tabs.is-boxed a,.hero.is-light .tabs.is-toggle a{color:rgba(0,0,0,.7)}.hero.is-light .tabs.is-boxed a:hover,.hero.is-light .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-light .tabs.is-boxed li.is-active a,.hero.is-light .tabs.is-boxed li.is-active a:hover,.hero.is-light .tabs.is-toggle li.is-active a,.hero.is-light .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,.7);border-color:rgba(0,0,0,.7);color:#f5f5f5}.hero.is-light.is-bold{background-image:linear-gradient(141deg,#dfd8d9 0,#f5f5f5 71%,#fff 100%)}@media screen and (max-width:768px){.hero.is-light.is-bold .navbar-menu{background-image:linear-gradient(141deg,#dfd8d9 0,#f5f5f5 71%,#fff 100%)}}.hero.is-dark{background-color:#363636;color:#fff}.hero.is-dark a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-dark strong{color:inherit}.hero.is-dark .title{color:#fff}.hero.is-dark .subtitle{color:rgba(255,255,255,.9)}.hero.is-dark .subtitle a:not(.button),.hero.is-dark .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-dark .navbar-menu{background-color:#363636}}.hero.is-dark .navbar-item,.hero.is-dark .navbar-link{color:rgba(255,255,255,.7)}.hero.is-dark .navbar-link.is-active,.hero.is-dark .navbar-link:hover,.hero.is-dark a.navbar-item.is-active,.hero.is-dark a.navbar-item:hover{background-color:#292929;color:#fff}.hero.is-dark .tabs a{color:#fff;opacity:.9}.hero.is-dark .tabs a:hover{opacity:1}.hero.is-dark .tabs li.is-active a{opacity:1}.hero.is-dark .tabs.is-boxed a,.hero.is-dark .tabs.is-toggle a{color:#fff}.hero.is-dark .tabs.is-boxed a:hover,.hero.is-dark .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-dark .tabs.is-boxed li.is-active a,.hero.is-dark .tabs.is-boxed li.is-active a:hover,.hero.is-dark .tabs.is-toggle li.is-active a,.hero.is-dark .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#363636}.hero.is-dark.is-bold{background-image:linear-gradient(141deg,#1f191a 0,#363636 71%,#46403f 100%)}@media screen and (max-width:768px){.hero.is-dark.is-bold .navbar-menu{background-image:linear-gradient(141deg,#1f191a 0,#363636 71%,#46403f 100%)}}.hero.is-primary{background-color:#00d1b2;color:#fff}.hero.is-primary a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-primary strong{color:inherit}.hero.is-primary .title{color:#fff}.hero.is-primary .subtitle{color:rgba(255,255,255,.9)}.hero.is-primary .subtitle a:not(.button),.hero.is-primary .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-primary .navbar-menu{background-color:#00d1b2}}.hero.is-primary .navbar-item,.hero.is-primary .navbar-link{color:rgba(255,255,255,.7)}.hero.is-primary .navbar-link.is-active,.hero.is-primary .navbar-link:hover,.hero.is-primary a.navbar-item.is-active,.hero.is-primary a.navbar-item:hover{background-color:#00b89c;color:#fff}.hero.is-primary .tabs a{color:#fff;opacity:.9}.hero.is-primary .tabs a:hover{opacity:1}.hero.is-primary .tabs li.is-active a{opacity:1}.hero.is-primary .tabs.is-boxed a,.hero.is-primary .tabs.is-toggle a{color:#fff}.hero.is-primary .tabs.is-boxed a:hover,.hero.is-primary .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-primary .tabs.is-boxed li.is-active a,.hero.is-primary .tabs.is-boxed li.is-active a:hover,.hero.is-primary .tabs.is-toggle li.is-active a,.hero.is-primary .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#00d1b2}.hero.is-primary.is-bold{background-image:linear-gradient(141deg,#009e6c 0,#00d1b2 71%,#00e7eb 100%)}@media screen and (max-width:768px){.hero.is-primary.is-bold .navbar-menu{background-image:linear-gradient(141deg,#009e6c 0,#00d1b2 71%,#00e7eb 100%)}}.hero.is-link{background-color:#3273dc;color:#fff}.hero.is-link a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-link strong{color:inherit}.hero.is-link .title{color:#fff}.hero.is-link .subtitle{color:rgba(255,255,255,.9)}.hero.is-link .subtitle a:not(.button),.hero.is-link .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-link .navbar-menu{background-color:#3273dc}}.hero.is-link .navbar-item,.hero.is-link .navbar-link{color:rgba(255,255,255,.7)}.hero.is-link .navbar-link.is-active,.hero.is-link .navbar-link:hover,.hero.is-link a.navbar-item.is-active,.hero.is-link a.navbar-item:hover{background-color:#2366d1;color:#fff}.hero.is-link .tabs a{color:#fff;opacity:.9}.hero.is-link .tabs a:hover{opacity:1}.hero.is-link .tabs li.is-active a{opacity:1}.hero.is-link .tabs.is-boxed a,.hero.is-link .tabs.is-toggle a{color:#fff}.hero.is-link .tabs.is-boxed a:hover,.hero.is-link .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-link .tabs.is-boxed li.is-active a,.hero.is-link .tabs.is-boxed li.is-active a:hover,.hero.is-link .tabs.is-toggle li.is-active a,.hero.is-link .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#3273dc}.hero.is-link.is-bold{background-image:linear-gradient(141deg,#1577c6 0,#3273dc 71%,#4366e5 100%)}@media screen and (max-width:768px){.hero.is-link.is-bold .navbar-menu{background-image:linear-gradient(141deg,#1577c6 0,#3273dc 71%,#4366e5 100%)}}.hero.is-info{background-color:#3298dc;color:#fff}.hero.is-info a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-info strong{color:inherit}.hero.is-info .title{color:#fff}.hero.is-info .subtitle{color:rgba(255,255,255,.9)}.hero.is-info .subtitle a:not(.button),.hero.is-info .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-info .navbar-menu{background-color:#3298dc}}.hero.is-info .navbar-item,.hero.is-info .navbar-link{color:rgba(255,255,255,.7)}.hero.is-info .navbar-link.is-active,.hero.is-info .navbar-link:hover,.hero.is-info a.navbar-item.is-active,.hero.is-info a.navbar-item:hover{background-color:#238cd1;color:#fff}.hero.is-info .tabs a{color:#fff;opacity:.9}.hero.is-info .tabs a:hover{opacity:1}.hero.is-info .tabs li.is-active a{opacity:1}.hero.is-info .tabs.is-boxed a,.hero.is-info .tabs.is-toggle a{color:#fff}.hero.is-info .tabs.is-boxed a:hover,.hero.is-info .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-info .tabs.is-boxed li.is-active a,.hero.is-info .tabs.is-boxed li.is-active a:hover,.hero.is-info .tabs.is-toggle li.is-active a,.hero.is-info .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#3298dc}.hero.is-info.is-bold{background-image:linear-gradient(141deg,#159dc6 0,#3298dc 71%,#4389e5 100%)}@media screen and (max-width:768px){.hero.is-info.is-bold .navbar-menu{background-image:linear-gradient(141deg,#159dc6 0,#3298dc 71%,#4389e5 100%)}}.hero.is-success{background-color:#48c774;color:#fff}.hero.is-success a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-success strong{color:inherit}.hero.is-success .title{color:#fff}.hero.is-success .subtitle{color:rgba(255,255,255,.9)}.hero.is-success .subtitle a:not(.button),.hero.is-success .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-success .navbar-menu{background-color:#48c774}}.hero.is-success .navbar-item,.hero.is-success .navbar-link{color:rgba(255,255,255,.7)}.hero.is-success .navbar-link.is-active,.hero.is-success .navbar-link:hover,.hero.is-success a.navbar-item.is-active,.hero.is-success a.navbar-item:hover{background-color:#3abb67;color:#fff}.hero.is-success .tabs a{color:#fff;opacity:.9}.hero.is-success .tabs a:hover{opacity:1}.hero.is-success .tabs li.is-active a{opacity:1}.hero.is-success .tabs.is-boxed a,.hero.is-success .tabs.is-toggle a{color:#fff}.hero.is-success .tabs.is-boxed a:hover,.hero.is-success .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-success .tabs.is-boxed li.is-active a,.hero.is-success .tabs.is-boxed li.is-active a:hover,.hero.is-success .tabs.is-toggle li.is-active a,.hero.is-success .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#48c774}.hero.is-success.is-bold{background-image:linear-gradient(141deg,#29b342 0,#48c774 71%,#56d296 100%)}@media screen and (max-width:768px){.hero.is-success.is-bold .navbar-menu{background-image:linear-gradient(141deg,#29b342 0,#48c774 71%,#56d296 100%)}}.hero.is-warning{background-color:#ffdd57;color:rgba(0,0,0,.7)}.hero.is-warning a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-warning strong{color:inherit}.hero.is-warning .title{color:rgba(0,0,0,.7)}.hero.is-warning .subtitle{color:rgba(0,0,0,.9)}.hero.is-warning .subtitle a:not(.button),.hero.is-warning .subtitle strong{color:rgba(0,0,0,.7)}@media screen and (max-width:1023px){.hero.is-warning .navbar-menu{background-color:#ffdd57}}.hero.is-warning .navbar-item,.hero.is-warning .navbar-link{color:rgba(0,0,0,.7)}.hero.is-warning .navbar-link.is-active,.hero.is-warning .navbar-link:hover,.hero.is-warning a.navbar-item.is-active,.hero.is-warning a.navbar-item:hover{background-color:#ffd83d;color:rgba(0,0,0,.7)}.hero.is-warning .tabs a{color:rgba(0,0,0,.7);opacity:.9}.hero.is-warning .tabs a:hover{opacity:1}.hero.is-warning .tabs li.is-active a{opacity:1}.hero.is-warning .tabs.is-boxed a,.hero.is-warning .tabs.is-toggle a{color:rgba(0,0,0,.7)}.hero.is-warning .tabs.is-boxed a:hover,.hero.is-warning .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-warning .tabs.is-boxed li.is-active a,.hero.is-warning .tabs.is-boxed li.is-active a:hover,.hero.is-warning .tabs.is-toggle li.is-active a,.hero.is-warning .tabs.is-toggle li.is-active a:hover{background-color:rgba(0,0,0,.7);border-color:rgba(0,0,0,.7);color:#ffdd57}.hero.is-warning.is-bold{background-image:linear-gradient(141deg,#ffaf24 0,#ffdd57 71%,#fffa70 100%)}@media screen and (max-width:768px){.hero.is-warning.is-bold .navbar-menu{background-image:linear-gradient(141deg,#ffaf24 0,#ffdd57 71%,#fffa70 100%)}}.hero.is-danger{background-color:#f14668;color:#fff}.hero.is-danger a:not(.button):not(.dropdown-item):not(.tag):not(.pagination-link.is-current),.hero.is-danger strong{color:inherit}.hero.is-danger .title{color:#fff}.hero.is-danger .subtitle{color:rgba(255,255,255,.9)}.hero.is-danger .subtitle a:not(.button),.hero.is-danger .subtitle strong{color:#fff}@media screen and (max-width:1023px){.hero.is-danger .navbar-menu{background-color:#f14668}}.hero.is-danger .navbar-item,.hero.is-danger .navbar-link{color:rgba(255,255,255,.7)}.hero.is-danger .navbar-link.is-active,.hero.is-danger .navbar-link:hover,.hero.is-danger a.navbar-item.is-active,.hero.is-danger a.navbar-item:hover{background-color:#ef2e55;color:#fff}.hero.is-danger .tabs a{color:#fff;opacity:.9}.hero.is-danger .tabs a:hover{opacity:1}.hero.is-danger .tabs li.is-active a{opacity:1}.hero.is-danger .tabs.is-boxed a,.hero.is-danger .tabs.is-toggle a{color:#fff}.hero.is-danger .tabs.is-boxed a:hover,.hero.is-danger .tabs.is-toggle a:hover{background-color:rgba(10,10,10,.1)}.hero.is-danger .tabs.is-boxed li.is-active a,.hero.is-danger .tabs.is-boxed li.is-active a:hover,.hero.is-danger .tabs.is-toggle li.is-active a,.hero.is-danger .tabs.is-toggle li.is-active a:hover{background-color:#fff;border-color:#fff;color:#f14668}.hero.is-danger.is-bold{background-image:linear-gradient(141deg,#fa0a62 0,#f14668 71%,#f7595f 100%)}@media screen and (max-width:768px){.hero.is-danger.is-bold .navbar-menu{background-image:linear-gradient(141deg,#fa0a62 0,#f14668 71%,#f7595f 100%)}}.hero.is-small .hero-body{padding:1.5rem}@media screen and (min-width:769px),print{.hero.is-medium .hero-body{padding:9rem 1.5rem}}@media screen and (min-width:769px),print{.hero.is-large .hero-body{padding:18rem 1.5rem}}.hero.is-fullheight .hero-body,.hero.is-fullheight-with-navbar .hero-body,.hero.is-halfheight .hero-body{align-items:center;display:flex}.hero.is-fullheight .hero-body>.container,.hero.is-fullheight-with-navbar .hero-body>.container,.hero.is-halfheight .hero-body>.container{flex-grow:1;flex-shrink:1}.hero.is-halfheight{min-height:50vh}.hero.is-fullheight{min-height:100vh}.hero-video{overflow:hidden}.hero-video video{left:50%;min-height:100%;min-width:100%;position:absolute;top:50%;transform:translate3d(-50%,-50%,0)}.hero-video.is-transparent{opacity:.3}@media screen and (max-width:768px){.hero-video{display:none}}.hero-buttons{margin-top:1.5rem}@media screen and (max-width:768px){.hero-buttons .button{display:flex}.hero-buttons .button:not(:last-child){margin-bottom:.75rem}}@media screen and (min-width:769px),print{.hero-buttons{display:flex;justify-content:center}.hero-buttons .button:not(:last-child){margin-right:1.5rem}}.hero-foot,.hero-head{flex-grow:0;flex-shrink:0}.hero-body{flex-grow:1;flex-shrink:0;padding:3rem 1.5rem}.section{padding:3rem 1.5rem}@media screen and (min-width:1024px){.section.is-medium{padding:9rem 1.5rem}.section.is-large{padding:18rem 1.5rem}}.footer{background-color:#fafafa;padding:3rem 1.5rem 6rem} \ No newline at end of file diff --git a/src/main/resources/static/index.html b/src/main/resources/static/index.html new file mode 100644 index 00000000..97dc68f4 --- /dev/null +++ b/src/main/resources/static/index.html @@ -0,0 +1,158 @@ + + + + + 구매하기 + + + + + + + + + + + +
    +
    + + + + + + + +
    +
    + + + + + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/orders/order-form.html b/src/main/resources/templates/trendpick/orders/order-form.html index 387855ee..b1ef86d5 100644 --- a/src/main/resources/templates/trendpick/orders/order-form.html +++ b/src/main/resources/templates/trendpick/orders/order-form.html @@ -4,9 +4,11 @@ 주문 폼 -
    - -

    주문서

    + +
    + +

    +

    주문서

    회원 정보

    @@ -17,7 +19,8 @@

    회원 정보

    회원 이름 + readonly="readonly"/> @@ -45,8 +48,8 @@

    회원 정보

    주문상품 정보

    -
    - +
    +
    @@ -57,15 +60,21 @@

    주문상품 정보

    - + - + - +
    1 + + +
    +
    + 전체 총 가격: 원 +

    결제 정보

    @@ -88,26 +97,53 @@

    결제 정보

    -
    - - -
    +
    +
    -
    -
    -
    - -
    -
    + + + + +
    +
    - + + + \ No newline at end of file From 1e44de2efd5acc392344995cfb410103c6febcf2 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Fri, 9 Jun 2023 23:24:18 +0900 Subject: [PATCH 236/367] =?UTF-8?q?refactor:=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EB=93=B1=EB=A1=9D=EC=8B=9C=20=EC=83=88=EB=A1=9C=EC=9A=B4=20?= =?UTF-8?q?=EB=B8=8C=EB=9E=9C=EB=93=9C=EB=A9=B4=20=EC=B6=94=EA=B0=80=20(#1?= =?UTF-8?q?60)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/brand/service/BrandService.java | 6 +- .../global/security/SecurityConfig.java | 24 ++++- .../static/resource/common/common.css | 12 +-- .../trendpick/products/detailpage.html | 4 +- .../templates/trendpick/products/list.html | 50 +++++----- .../trendpick/products/register.html | 19 ++-- .../trendpick/usr/layout/layout.html | 94 ++++++++++--------- .../templates/trendpick/usr/member/join.html | 25 ++++- 8 files changed, 146 insertions(+), 88 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/brand/service/BrandService.java b/src/main/java/project/trendpick_pro/domain/brand/service/BrandService.java index f79595fc..56757c4b 100644 --- a/src/main/java/project/trendpick_pro/domain/brand/service/BrandService.java +++ b/src/main/java/project/trendpick_pro/domain/brand/service/BrandService.java @@ -32,6 +32,10 @@ public List findAll(){ } public Brand findByName(String name) { - return brandRepository.findByName(name); + try { + return brandRepository.findByName(name); + } catch (Exception e) { + return brandRepository.save(new Brand(name)); + } } } diff --git a/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java b/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java index 20f936b2..106ae1c5 100644 --- a/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java +++ b/src/main/java/project/trendpick_pro/global/security/SecurityConfig.java @@ -1,14 +1,23 @@ package project.trendpick_pro.global.security; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.authentication.AuthenticationManager; import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.authority.AuthorityUtils; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.AuthenticationSuccessHandler; + +import java.io.IOException; +import java.util.Set; @Configuration @EnableWebSecurity @@ -42,7 +51,20 @@ SecurityFilterChain filterChain(HttpSecurity http) throws Exception { .and() .formLogin() .loginPage("/trendpick/member/login") - .defaultSuccessUrl("/trendpick/products/list?main-category=recommend") + .successHandler(new AuthenticationSuccessHandler() { + @Override + public void onAuthenticationSuccess(HttpServletRequest request, HttpServletResponse response, + Authentication authentication) throws IOException, ServletException { + Set roles = AuthorityUtils.authorityListToSet(authentication.getAuthorities()); + if (roles.contains("ADMIN") || roles.contains("BRAND_ADMIN")) { + response.sendRedirect("/trendpick/products/list?main-category=top"); + } else if (roles.contains("MEMBER")) { + response.sendRedirect("/trendpick/products/list?main-category=recommend"); + } else { + throw new IllegalStateException(); + } + } + }) .permitAll() .and() .logout() diff --git a/src/main/resources/static/resource/common/common.css b/src/main/resources/static/resource/common/common.css index 3b653699..6978e0c2 100644 --- a/src/main/resources/static/resource/common/common.css +++ b/src/main/resources/static/resource/common/common.css @@ -18,16 +18,12 @@ html > body .label-text { .badge { display: inline-block; padding: .25em .4em; - font-size: 75%; font-weight: 700; line-height: 1; text-align: center; white-space: nowrap; vertical-align: baseline; border-radius: .25rem; - background-color: #f8f9fa; - color: #333; - border: 1px solid #dee2e6; } .badge-large { @@ -46,7 +42,11 @@ html > body .label-text { } .image-main { - width: 300px; - height: 300px; + width: 500px; + height: 500px; object-fit: cover; } + +.number-div { + width: 30px; /* Or whatever width you feel is appropriate */ +} \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/products/detailpage.html b/src/main/resources/templates/trendpick/products/detailpage.html index 11c134aa..f8d3ecc7 100644 --- a/src/main/resources/templates/trendpick/products/detailpage.html +++ b/src/main/resources/templates/trendpick/products/detailpage.html @@ -4,9 +4,9 @@ TrendPick -
    +
    -
    +
    Product Image
    diff --git a/src/main/resources/templates/trendpick/products/list.html b/src/main/resources/templates/trendpick/products/list.html index af1ae523..6972b8c1 100644 --- a/src/main/resources/templates/trendpick/products/list.html +++ b/src/main/resources/templates/trendpick/products/list.html @@ -6,9 +6,8 @@
    -
    - + @@ -19,34 +18,37 @@
    - -
    +
    새 상품 생성
    +
    +
    +
    +
    - -
    -
    - Product Image -
    -
    -

    -
    Brand:
    -
    -
    -
    -
    -
    - Edit - Delete - +
    +
    + Product Image +
    +
    +

    +
    Brand:
    +
    +
    +
    +
    +
    + Edit + Delete + +
    + View More
    - View More
    diff --git a/src/main/resources/templates/trendpick/products/register.html b/src/main/resources/templates/trendpick/products/register.html index b4e6d060..65498d76 100644 --- a/src/main/resources/templates/trendpick/products/register.html +++ b/src/main/resources/templates/trendpick/products/register.html @@ -2,7 +2,7 @@ - Product Registration + 상품 등록 @@ -45,7 +45,7 @@
    @@ -56,19 +56,20 @@
    -
    - -
    -
    - + +
    + +
    +
    +
    diff --git a/src/main/resources/templates/trendpick/usr/layout/layout.html b/src/main/resources/templates/trendpick/usr/layout/layout.html index adfda4e2..f045a0a9 100644 --- a/src/main/resources/templates/trendpick/usr/layout/layout.html +++ b/src/main/resources/templates/trendpick/usr/layout/layout.html @@ -29,7 +29,9 @@

    TrendPick

    +
    + +
    +
    + - -
    diff --git a/src/main/resources/templates/trendpick/usr/member/join.html b/src/main/resources/templates/trendpick/usr/member/join.html index 3c258b79..363efc7e 100644 --- a/src/main/resources/templates/trendpick/usr/member/join.html +++ b/src/main/resources/templates/trendpick/usr/member/join.html @@ -6,6 +6,18 @@
    +
    From bc604800ab19c031aba56b39e22ab4cb1521ee07 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sat, 10 Jun 2023 00:42:11 +0900 Subject: [PATCH 239/367] =?UTF-8?q?feat:=20=EB=B8=8C=EB=9E=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90=EC=9D=98=20=EB=B8=8C=EB=9E=9C?= =?UTF-8?q?=EB=93=9C=EB=A5=BC=20=EC=B0=BE=EC=9D=84=20=EC=88=98=20=EC=97=86?= =?UTF-8?q?=EC=9D=84=EB=95=8C=20=EC=98=88=EC=99=B8=EC=B2=98=EB=A6=AC(#158)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/common/base/rq/Rq.java | 11 +- .../product/controller/ProductController.java | 6 +- .../repository/ProductRepositoryImpl.java | 5 +- .../product/service/ProductService.java | 9 +- .../trendpick/usr/layout/layout.html | 178 ++++++++++-------- 5 files changed, 121 insertions(+), 88 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java index fa3226e9..1b82aa1d 100644 --- a/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java +++ b/src/main/java/project/trendpick_pro/domain/common/base/rq/Rq.java @@ -121,8 +121,17 @@ public Optional CheckAdmin() { } public Boolean CheckAdminHtml() { + return !CheckMemberHtml(); + } + + public Boolean CheckBrandAdminHtml() { + Member checkMember = CheckLogin().get(); + return checkMember.getRole().equals(RoleType.BRAND_ADMIN); + } + + public Boolean CheckMemberHtml() { Member checkMember = CheckLogin().get(); - return !checkMember.getRole().equals(RoleType.MEMBER); + return checkMember.getRole().equals(RoleType.MEMBER); } public Optional CheckMember() { diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 488976e7..ac021897 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -155,13 +155,9 @@ public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") i @GetMapping("admin/list") public String showAllProductBySeller(@RequestParam("page") int offset, Model model) { Page products = - productService.findProductsBySeller(rq.CheckAdmin().get(), offset); + productService.findProductsBySeller(rq.CheckAdmin().get(), offset).getData(); model.addAttribute("products", products); return "/trendpick/admin/products"; } - - - - } // @RequestParam(value = "sort", defaultValue = "1"), Integer sortCode \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index b74dbc9b..4b10918e 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -135,7 +135,7 @@ public Page findAllBySeller(String brand, Pageable )) .from(product) .leftJoin(product.file, commonFile) - .leftJoin(product, ask.product) + .leftJoin(ask.product, product) .where(product.brand.name.eq(brand)) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -145,9 +145,8 @@ public Page findAllBySeller(String brand, Pageable JPAQuery count = queryFactory .select(product.count()) .from(product) - .from(product) .leftJoin(product.file, commonFile) - .leftJoin(product, ask.product) + .leftJoin(ask.product, product) .where(product.brand.name.eq(brand)); return PageableExecutionUtils.getPage(list, pageable, count::fetchOne); diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 7845a395..099a75f4 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -41,6 +41,7 @@ import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tags.tag.entity.Tag; import project.trendpick_pro.domain.tags.tag.entity.type.TagType; +import project.trendpick_pro.global.rsData.RsData; import java.io.File; import java.io.IOException; @@ -220,8 +221,12 @@ public List getRecommendProduct(Member member){ return products; } - public Page findProductsBySeller(Member member, int offset) { + public RsData> findProductsBySeller(Member member, int offset) { + + if (member.getBrand() == null) + RsData.of("F-1", "브랜드 관리자의 브랜드를 알 수 없습니다. 브랜드를 설정하세요."); + Pageable pageable = PageRequest.of(offset, 20); - return productRepository.findAllBySeller(member.getBrand(), pageable); + return RsData.of("S-1", "성공", productRepository.findAllBySeller(member.getBrand(), pageable)); } } diff --git a/src/main/resources/templates/trendpick/usr/layout/layout.html b/src/main/resources/templates/trendpick/usr/layout/layout.html index f045a0a9..90073ba2 100644 --- a/src/main/resources/templates/trendpick/usr/layout/layout.html +++ b/src/main/resources/templates/trendpick/usr/layout/layout.html @@ -3,102 +3,126 @@ xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.w3.org/1999/xhtml"> - - - - - - - - - - + + + + + + + + + + - - TrendPick + + TrendPick
    From 2b94cee5ea0fe0a35ae69b549880f7af5873130b Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sat, 10 Jun 2023 00:53:33 +0900 Subject: [PATCH 240/367] =?UTF-8?q?feat:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=EC=8B=9C=20=ED=83=9C=EA=B7=B8=20=EC=A7=81=EC=A0=91?= =?UTF-8?q?=EC=84=A0=ED=83=9D=ED=96=88=EC=9D=84=20=EC=8B=9C=EC=97=90?= =?UTF-8?q?=EB=8F=84=20=EC=A0=90=EC=88=98=20=EC=B6=94=EA=B0=80(#158)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../project/trendpick_pro/domain/member/entity/Member.java | 5 ++++- .../domain/tags/favoritetag/entity/FavoriteTag.java | 1 + .../trendpick_pro/domain/tags/tag/entity/type/TagType.java | 3 ++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java index 8b18b211..3c2ded03 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/Member.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/Member.java @@ -4,6 +4,7 @@ import lombok.*; import project.trendpick_pro.domain.cart.entity.Cart; import project.trendpick_pro.domain.tags.favoritetag.entity.FavoriteTag; +import project.trendpick_pro.domain.tags.tag.entity.type.TagType; import java.util.LinkedHashSet; import java.util.Set; @@ -67,8 +68,10 @@ public void connectBank(String bankName, String bankAccount) { public void changeTags(Set tags) { this.tags = tags; - for(FavoriteTag tag : tags) + for(FavoriteTag tag : tags){ tag.connectMember(this); + tag.increaseScore(TagType.REGISTER); + } } //양방향 메서드 diff --git a/src/main/java/project/trendpick_pro/domain/tags/favoritetag/entity/FavoriteTag.java b/src/main/java/project/trendpick_pro/domain/tags/favoritetag/entity/FavoriteTag.java index 325444f0..32fc0ec8 100644 --- a/src/main/java/project/trendpick_pro/domain/tags/favoritetag/entity/FavoriteTag.java +++ b/src/main/java/project/trendpick_pro/domain/tags/favoritetag/entity/FavoriteTag.java @@ -37,6 +37,7 @@ public void increaseScore(TagType type){ switch (type) { case ORDER -> score += 10; case CART -> score += 5; + case REGISTER -> score += 30; default -> score += 1; } } diff --git a/src/main/java/project/trendpick_pro/domain/tags/tag/entity/type/TagType.java b/src/main/java/project/trendpick_pro/domain/tags/tag/entity/type/TagType.java index 04af2d0b..27cfaf0b 100644 --- a/src/main/java/project/trendpick_pro/domain/tags/tag/entity/type/TagType.java +++ b/src/main/java/project/trendpick_pro/domain/tags/tag/entity/type/TagType.java @@ -3,7 +3,8 @@ public enum TagType { //타입에 따라 다른 태그점수 향상치 ORDER("ORDER"), CART("CART"), - SHOW("SHOW"); + SHOW("SHOW"), + REGISTER("REGISTER"); private String value; From 569bb3503b352fb28267f120816b8402310e93b9 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sat, 10 Jun 2023 01:38:17 +0900 Subject: [PATCH 241/367] =?UTF-8?q?feat:=20=EB=B8=8C=EB=9E=9C=EB=93=9C=20?= =?UTF-8?q?=EA=B4=80=EB=A6=AC=EC=9E=90=EC=9D=98=20=ED=8C=90=EB=A7=A4?= =?UTF-8?q?=EB=82=B4=EC=97=AD=20=EA=B5=AC=ED=98=84=20=EC=99=84=EB=A3=8C(#1?= =?UTF-8?q?58)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/member/entity/form/JoinForm.java | 3 ++- .../response/ProductListResponseBySeller.java | 8 ++++++++ .../repository/ProductRepositoryImpl.java | 2 -- .../product/service/ProductService.java | 1 - .../global/basedata/BaseData.java | 1 + .../templates/trendpick/admin/products.html | 20 +++++++++++++++++-- .../admin/{orders.html => sales.html} | 10 +++++----- 7 files changed, 34 insertions(+), 11 deletions(-) rename src/main/resources/templates/trendpick/admin/{orders.html => sales.html} (90%) diff --git a/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java b/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java index b59727dc..cda06a5d 100644 --- a/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java +++ b/src/main/java/project/trendpick_pro/domain/member/entity/form/JoinForm.java @@ -12,5 +12,6 @@ public record JoinForm(@NotBlank(message = "email을 입력해주세요.") Strin @NotBlank(message = "이름을 입력해주세요.") String username, @NotBlank(message = "휴대폰 번호를 입력해주세요.") String phoneNumber, @NotBlank(message = "권한을 입력해주세요.") String state, - List tags) { + List tags, + String brand){ } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponseBySeller.java b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponseBySeller.java index b07562a1..2ed15f89 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponseBySeller.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/dto/response/ProductListResponseBySeller.java @@ -4,9 +4,12 @@ import lombok.*; import project.trendpick_pro.domain.tags.tag.entity.Tag; +import java.text.NumberFormat; import java.time.LocalDateTime; import java.util.ArrayList; import java.util.List; +import java.util.Locale; + @Getter @NoArgsConstructor(access = AccessLevel.PROTECTED) public class ProductListResponseBySeller { @@ -37,4 +40,9 @@ public ProductListResponseBySeller(Long id, String name, String mainFile, int pr this.reviewCount = reviewCount; this.ask = ask; } + + public String getFormattedPrice(){ + NumberFormat numberFormat = NumberFormat.getInstance(Locale.getDefault()); + return numberFormat.format(getPrice())+"원"; + } } diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java index 4b10918e..9b17a82b 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepositoryImpl.java @@ -135,7 +135,6 @@ public Page findAllBySeller(String brand, Pageable )) .from(product) .leftJoin(product.file, commonFile) - .leftJoin(ask.product, product) .where(product.brand.name.eq(brand)) .offset(pageable.getOffset()) .limit(pageable.getPageSize()) @@ -146,7 +145,6 @@ public Page findAllBySeller(String brand, Pageable .select(product.count()) .from(product) .leftJoin(product.file, commonFile) - .leftJoin(ask.product, product) .where(product.brand.name.eq(brand)); return PageableExecutionUtils.getPage(list, pageable, count::fetchOne); diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 099a75f4..463e1159 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -222,7 +222,6 @@ public List getRecommendProduct(Member member){ } public RsData> findProductsBySeller(Member member, int offset) { - if (member.getBrand() == null) RsData.of("F-1", "브랜드 관리자의 브랜드를 알 수 없습니다. 브랜드를 설정하세요."); diff --git a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java index a1473fcd..145c855a 100644 --- a/src/main/java/project/trendpick_pro/global/basedata/BaseData.java +++ b/src/main/java/project/trendpick_pro/global/basedata/BaseData.java @@ -119,6 +119,7 @@ public void run(String... args) { .username("brand") .phoneNumber("010-1234-1234") .state("BRAND_ADMIN") + .brand("나이키") .build(); JoinForm member = JoinForm.builder() diff --git a/src/main/resources/templates/trendpick/admin/products.html b/src/main/resources/templates/trendpick/admin/products.html index 1187bb55..39d32052 100644 --- a/src/main/resources/templates/trendpick/admin/products.html +++ b/src/main/resources/templates/trendpick/admin/products.html @@ -3,6 +3,17 @@ 판매상품 관리 + +
    @@ -10,7 +21,7 @@ 상품번호 - 상품정보 + 상품명 상품금액 상품재고 판매개수 @@ -31,9 +42,14 @@ th:text="${product.name}"> + - + + + () + diff --git a/src/main/resources/templates/trendpick/admin/orders.html b/src/main/resources/templates/trendpick/admin/sales.html similarity index 90% rename from src/main/resources/templates/trendpick/admin/orders.html rename to src/main/resources/templates/trendpick/admin/sales.html index e32923d3..b1900853 100644 --- a/src/main/resources/templates/trendpick/admin/orders.html +++ b/src/main/resources/templates/trendpick/admin/sales.html @@ -9,11 +9,11 @@ - + - - - + + + @@ -42,7 +42,7 @@
    주문번호판매번호 상품정보주문수량주문금액주문일시판매수량판매금액판매일시 주문상태 배송상태
    - + From 6fee366e425bec27b5b1bdc26a6f2c9ddf763f8e Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Sat, 10 Jun 2023 02:35:29 +0900 Subject: [PATCH 242/367] =?UTF-8?q?refactor:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=20=EC=88=98=EB=9F=89=20DB=20=EC=97=85=EB=8D=B0?= =?UTF-8?q?=EC=9D=B4=ED=8A=B8=20=EB=AC=B8=EC=A0=9C=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/cart/entity/CartItem.java | 11 +++ .../entity/dto/response/CartResponse.java | 10 ++- .../domain/cart/service/CartService.java | 12 ++- .../templates/trendpick/usr/cart/list.html | 74 +++++++++++++------ 4 files changed, 77 insertions(+), 30 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java index 3ecc9d37..623023e3 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/CartItem.java @@ -2,9 +2,12 @@ import jakarta.persistence.*; import lombok.*; +import org.springframework.format.annotation.DateTimeFormat; import project.trendpick_pro.domain.cart.entity.dto.request.CartItemRequest; import project.trendpick_pro.domain.product.entity.Product; +import java.time.LocalDate; + @Entity @Getter @Setter @@ -24,6 +27,14 @@ public class CartItem { private int quantity; // 해당 상품 수량 + @DateTimeFormat(pattern = "yyyy-mm-dd") + private LocalDate createDate; + + @PrePersist // DB에 INSERT 되기 직전에 실행. 즉 DB에 값을 넣으면 자동으로 실행 + public void createDate() { + this.createDate = LocalDate.now(); + } + @Builder public CartItem(Cart cart, Product product, int quantity) { this.cart = cart; diff --git a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java index 3bdca328..ef5853cf 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java +++ b/src/main/java/project/trendpick_pro/domain/cart/entity/dto/response/CartResponse.java @@ -1,30 +1,36 @@ package project.trendpick_pro.domain.cart.entity.dto.response; import com.querydsl.core.annotations.QueryProjection; +import lombok.AccessLevel; import lombok.Builder; import lombok.Getter; +import lombok.NoArgsConstructor; import project.trendpick_pro.domain.cart.entity.Cart; import project.trendpick_pro.domain.cart.entity.CartItem; import java.util.List; @Getter +@NoArgsConstructor(access = AccessLevel.PROTECTED) public class CartResponse { private Long id; private Long memberId; + private String productFilePath; + private String brandName; private int totalCount; - private List cartItems; @Builder @QueryProjection - public CartResponse(Long id, Long memberId, int totalCount, List cartItems) { + public CartResponse(Long id, Long memberId, String productFilePath, String brandName,int totalCount, List cartItems) { this.id = id; this.memberId = memberId; + this.productFilePath=productFilePath; + this.brandName = brandName; this.totalCount=totalCount; this.cartItems=cartItems; } diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index f35fd68e..5981d895 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -67,7 +67,8 @@ public CartItemResponse addItemToCart(Member member, CartItemRequest cartItemReq if (cartItem != null) { // 이미 카트에 해당 상품이 존재하는 경우, 수량을 증가 - cartItem.addCount(cartItem.getQuantity()); + cartItem.addCount(cartItemRequest.getQuantity()); + cart.setTotalCount(cart.getTotalCount()+ cartItemRequest.getQuantity()); } else { // 카트에 해당 상품이 없는 경우, 새로운 카트 아이템을 생성하여 추가 cartItem = CartItem.of(cart, product, cartItemRequest); @@ -87,11 +88,14 @@ public void removeItemFromCart(Long cartItemId) { // 상품의 수량 업데이트 @Transactional public void updateItemCount(Member member,Long cartItemId, int quantity) { - Cart cart=member.getCart(); + Cart cart=cartRepository.findByMemberId(member.getId()); CartItem cartItem = cartItemRepository.findById(cartItemId).orElse(null); - cart.setTotalCount(cartItem.getQuantity()+quantity); + + // quantity값이 수량에 있는 값 그대로 넘어옴 + // 수량이 1로 들어오는 게 아닌 해당 상품의 수량 값이 오기 때문에 + // 기존 해당 아이템의 수량값을 빼줌 + cart.setTotalCount(cart.getTotalCount()+(quantity-cartItem.getQuantity())); cartItem.update(quantity); - cartItemRepository.save(cartItem); } public Cart getCartByUser(Long memberId) { diff --git a/src/main/resources/templates/trendpick/usr/cart/list.html b/src/main/resources/templates/trendpick/usr/cart/list.html index 726aa1c7..21b583d0 100644 --- a/src/main/resources/templates/trendpick/usr/cart/list.html +++ b/src/main/resources/templates/trendpick/usr/cart/list.html @@ -1,52 +1,76 @@ - + 장바구니 -
    +
    +
    - - - - - - - + + + + + + + + - - - - + - - - + + + - + +
    번호상품ID상품명가격수량삭제번호상품ID상품정보가격수량담은날짜삭제
    1 - + + + 1 + + 1 + +
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    - +
    삭제 + + + 삭제 +
    +
    +
    +
    @@ -55,7 +79,9 @@

    총 결제금액

    -

    +

    + +

    @@ -100,6 +126,6 @@

    new MemberNotFoundException("존재하지 않는 회원입니다.")); - return member; - } - public List findCartItems(List cartItemIdList) { List cartItemList = new ArrayList<>(); for (Long id : cartItemIdList) { @@ -121,4 +113,17 @@ public List findCartItems(List cartItemIdList) { } return cartItemList; } -} \ No newline at end of file + + @Transactional + public void deleteCartItemsByOrder(Member member,List cartItemIdList) { + Cart cart = cartRepository.findByMemberId(member.getId()); + int quantity=0; + for(long id: cartItemIdList){ + CartItem cartItem = cartItemRepository.findById(id).orElse(null); + quantity+= cartItem.getQuantity(); + } + cartItemRepository.deleteAllByIdInBatch(cartItemIdList); + cart.totalCountUpdate(cart.getTotalCount()-quantity); + } +} + diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 6b429a67..7614ab9d 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -9,6 +9,7 @@ import org.springframework.transaction.annotation.Transactional; import project.trendpick_pro.domain.cart.entity.Cart; import project.trendpick_pro.domain.cart.entity.CartItem; +import project.trendpick_pro.domain.cart.repository.CartRepository; import project.trendpick_pro.domain.cart.service.CartService; import project.trendpick_pro.domain.delivery.entity.Delivery; import project.trendpick_pro.domain.member.entity.dto.MemberInfoDto; @@ -83,6 +84,12 @@ public OrderForm cartToOrder(Member member, List selectedItems) { throw new MemberNotMatchException("현재 접속중인 사용자와 장바구니 사용자가 일치하지 않습니다."); } + // 주문상품 장바구니에서 삭제 + List orderItemIds = new ArrayList<>(); + for (CartItem cartItem : cartItems) { + orderItemIds.add(cartItem.getId()); + } + cartService.deleteCartItemsByOrder(member,orderItemIds); return new OrderForm(MemberInfoDto.of(member) ,convertToOrderItemDto(cartItems)); } From 9a47802ec8bf612a05be3d59d5635d3ddead74ad Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Sat, 10 Jun 2023 02:47:10 +0900 Subject: [PATCH 244/367] =?UTF-8?q?fix:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88->=EC=A3=BC=EB=AC=B8=ED=8F=BC=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cart/controller/CartController.java | 6 +- .../cart/repository/CartItemRepository.java | 3 + .../domain/cart/service/CartService.java | 11 ++- .../domain/orders/service/OrderService.java | 4 +- .../templates/trendpick/usr/cart/list.html | 75 ++++++++++++++++--- 5 files changed, 82 insertions(+), 17 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java index 35324fde..46565446 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java +++ b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java @@ -32,16 +32,18 @@ public class CartController { @PreAuthorize("hasAuthority('MEMBER')") @GetMapping("/list") - public String showCart(Model model) { + public String showCart( Model model) { Member member = rq.CheckMember().get(); Cart carts = cartService.getCartByUser(rq.CheckMember().get().getId()); List cartItems = cartService.CartView(member, carts); - + //ListcartItemList=cartService.findCartItems(selectedItems); int totalPrice = 0; + /* for (CartItem cartItem : cartItems) { totalPrice += (cartItem.getProduct().getPrice() * cartItem.getQuantity()); } + */ model.addAttribute("cartItems", cartItems); model.addAttribute("totalPrice", totalPrice); return "/trendpick/usr/cart/list"; diff --git a/src/main/java/project/trendpick_pro/domain/cart/repository/CartItemRepository.java b/src/main/java/project/trendpick_pro/domain/cart/repository/CartItemRepository.java index afcb0bb2..e53f0558 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/repository/CartItemRepository.java +++ b/src/main/java/project/trendpick_pro/domain/cart/repository/CartItemRepository.java @@ -3,8 +3,11 @@ import org.springframework.data.jpa.repository.JpaRepository; import project.trendpick_pro.domain.cart.entity.CartItem; +import java.util.List; + public interface CartItemRepository extends JpaRepository { CartItem findByCartIdAndProductId(Long cartId, long ProductId); + List findByProductId(Long productId); CartItem findByCartId(Long cartItemID); } diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index 8f509ff6..0d92e652 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -105,11 +105,16 @@ private Product getProductById(Long productId) { .orElseThrow(() -> new IllegalArgumentException("해당 상품을 찾을 수 없습니다.")); } - public List findCartItems(List cartItemIdList) { + public List findCartItems(Member member,List cartItemIdList) { + Cart cart=getCartByUser(member.getId()); //현재 로그인되어 있는 cart 정보 List cartItemList = new ArrayList<>(); + for (Long id : cartItemIdList) { - cartItemList.add(cartItemRepository.findById(id). - orElseThrow(() -> new IllegalArgumentException("장바구니에 존재하지 않는 품목입니다."))); + for(CartItem item : cartItemRepository.findByProductId(id)) { + if(item.getCart().getId() == cart.getId()) { + cartItemList.add(item); + } + } } return cartItemList; } diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index 7614ab9d..212b262c 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -78,9 +78,9 @@ public Page findAllByMember(Member member, int offset) { } public OrderForm cartToOrder(Member member, List selectedItems) { - List cartItems = cartService.findCartItems(selectedItems); + List cartItems = cartService.findCartItems(member, selectedItems); for (CartItem cartItem : cartItems) { - if(cartItem.getCart().getMember().getId() != member.getId()) + if (cartItem.getCart().getMember().getId() != member.getId()) throw new MemberNotMatchException("현재 접속중인 사용자와 장바구니 사용자가 일치하지 않습니다."); } diff --git a/src/main/resources/templates/trendpick/usr/cart/list.html b/src/main/resources/templates/trendpick/usr/cart/list.html index 21b583d0..8f2b6885 100644 --- a/src/main/resources/templates/trendpick/usr/cart/list.html +++ b/src/main/resources/templates/trendpick/usr/cart/list.html @@ -11,7 +11,7 @@ - + @@ -24,12 +24,16 @@ +
    번호 상품ID 상품정보
    - 1 - 1 +
    @@ -78,17 +82,20 @@

    총 결제금액

    +

    -

    - -

    + +

    0 원

    + + + TrendPick From c5b3aa8c19a33d2be11b16d372f2950d47775575 Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Sat, 10 Jun 2023 19:56:02 +0900 Subject: [PATCH 258/367] =?UTF-8?q?refactor:=20=EC=9E=A5=EB=B0=94=EA=B5=AC?= =?UTF-8?q?=EB=8B=88=20UI=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/cart/service/CartService.java | 4 +- .../templates/trendpick/usr/cart/list.html | 56 ++++++++----------- 2 files changed, 25 insertions(+), 35 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index d3b5af1b..cce3899f 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -35,12 +35,14 @@ public class CartService { public List CartView(Member member, Cart cart) { List cartItems = cartItemRepository.findAll(); List userItems = new ArrayList<>(); - int totalCount=cart.getTotalCount(); + int totalCount=0; // 장바구니가 비어있는 경우 if (cart == null) { + totalCount=0; return userItems; } for (CartItem cartItem : cartItems) { + totalCount=cart.getTotalCount(); if (cartItem.getCart().getId() == cart.getId()) { userItems.add(cartItem); totalCount+=cartItem.getQuantity(); diff --git a/src/main/resources/templates/trendpick/usr/cart/list.html b/src/main/resources/templates/trendpick/usr/cart/list.html index c718a1d2..74eab97a 100644 --- a/src/main/resources/templates/trendpick/usr/cart/list.html +++ b/src/main/resources/templates/trendpick/usr/cart/list.html @@ -9,7 +9,7 @@
    - + @@ -67,32 +67,33 @@
    번호 삭제 + style="text-decoration: none; color: grey;">X
    -
    -
    -
    -
    -
    -

    총 결제금액

    -
    +
    + + + + + + + -

    - -

    0 원

    - + - + +
    총 주문금액
    +
    +

    0원

    +
    + +
    -
    - - diff --git a/src/main/resources/templates/trendpick/usr/layout/layout.html b/src/main/resources/templates/trendpick/usr/layout/layout.html index 5d766a12..80d01fb5 100644 --- a/src/main/resources/templates/trendpick/usr/layout/layout.html +++ b/src/main/resources/templates/trendpick/usr/layout/layout.html @@ -4,18 +4,31 @@ xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" xmlns:sec="http://www.w3.org/1999/xhtml"> - + + + + - + + + + - + + + + TrendPick @@ -126,6 +139,40 @@

    TrendPick

    +
    + + + + \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/member/join.html b/src/main/resources/templates/trendpick/usr/member/join.html index 932105ad..eefed4ba 100644 --- a/src/main/resources/templates/trendpick/usr/member/join.html +++ b/src/main/resources/templates/trendpick/usr/member/join.html @@ -4,9 +4,7 @@
    - +
    From cca9e72f93aa6d5c58ba32c8cdf54f9b14704be1 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Sat, 10 Jun 2023 20:45:57 +0900 Subject: [PATCH 264/367] =?UTF-8?q?refactor:=20RsData=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/controller/ReviewController.java | 16 +++++++++------- .../domain/review/service/ReviewService.java | 17 +++++------------ 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java index ae6b784b..49ae0e40 100644 --- a/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java +++ b/src/main/java/project/trendpick_pro/domain/review/controller/ReviewController.java @@ -19,6 +19,7 @@ import project.trendpick_pro.domain.review.entity.dto.request.ReviewSaveRequest; import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; import project.trendpick_pro.domain.review.service.ReviewService; +import project.trendpick_pro.global.rsData.RsData; import java.io.IOException; import java.util.List; @@ -46,11 +47,11 @@ public String createReview(@Valid ReviewSaveRequest reviewCreateRequest, Optional member = rq.CheckLogin(); Member checkMember = member.get(); - ReviewResponse reviewResponse = reviewService.createReview(checkMember, productId, reviewCreateRequest, mainFile, subFiles); + RsData reviewResponse = reviewService.createReview(checkMember, productId, reviewCreateRequest, mainFile, subFiles); model.addAttribute("reviewResponse", reviewResponse); - return "redirect:/trendpick/review/list"; - +// return "redirect:/trendpick/review/list"; + return rq.redirectWithMsg("/trendpick/review/list", reviewResponse); } @GetMapping("/{reviewId}") @@ -64,11 +65,11 @@ public String showReview(@PathVariable Long reviewId, Model model){ return "/trendpick/review/detail"; } - @GetMapping("/delete/{reviewId}") + @DeleteMapping("/delete/{reviewId}") public String deleteReview(@PathVariable Long reviewId) { reviewService.delete(reviewId); - return "redirect:/trendpick/review/list"; + return rq.redirectWithMsg("/trendpick/review/list", "삭제가 완료되었습니다."); } @GetMapping("/edit/{reviewId}") @@ -82,10 +83,11 @@ public String showUpdateReview(@PathVariable Long reviewId, Model model){ @PostMapping("/edit/{reviewId}") public String updateReview(@PathVariable Long reviewId, ReviewSaveRequest reviewSaveRequest, @RequestParam("mainFile") MultipartFile mainFile, @RequestParam("subFiles") List subFiles, Model model) throws IOException { - ReviewResponse reviewResponse = reviewService.modify(reviewId, reviewSaveRequest, mainFile, subFiles); + RsData reviewResponse = reviewService.modify(reviewId, reviewSaveRequest, mainFile, subFiles); model.addAttribute("reviewResponse", reviewResponse); - return "redirect:/trendpick/review/" + reviewId; +// return "redirect:/trendpick/review/" + reviewId; + return rq.redirectWithMsg("/trendpick/review/" + reviewId, reviewResponse); } diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index 3695e03d..799e04d7 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -19,6 +19,7 @@ import project.trendpick_pro.domain.review.entity.dto.response.ReviewProductResponse; import project.trendpick_pro.domain.review.entity.dto.response.ReviewResponse; import project.trendpick_pro.domain.review.repository.ReviewRepository; +import project.trendpick_pro.global.rsData.RsData; import java.io.File; import java.io.IOException; @@ -51,20 +52,12 @@ public Review findById(Long id) { } -// public Review findByAllProductId(Long id) { -// return reviewRepository.findAllByProductId(id); -// } public Page getProductReviews(Long productId, Pageable pageable) { pageable = PageRequest.of(pageable.getPageNumber(), 6); return reviewRepository.findAllByProductId(productId, pageable); } -// public ReviewResponse productReview(Long productId) { -// Review review = reviewRepository.findAllByProductId(productId); -// if(review == null) return ReviewResponse.of("현재 리뷰가 0건입니다!"); -// return ReviewResponse.of(review); -// } @Transactional @@ -73,7 +66,7 @@ public void delete(Long reviewId) { reviewRepository.delete(review); } - public ReviewResponse createReview(Member actor, Long productId, ReviewSaveRequest reviewSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws Exception { + public RsData createReview(Member actor, Long productId, ReviewSaveRequest reviewSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws Exception { Product product = productRepository.findById(productId).orElseThrow(); CommonFile mainFile = fileTranslator.translateFile(requestMainFile); @@ -87,11 +80,11 @@ public ReviewResponse createReview(Member actor, Long productId, ReviewSaveReque product.addReview(review.getRating()); //상품 리뷰수, 상품 평균 평점을 계산해서 저장 reviewRepository.save(review); - return ReviewResponse.of(review); + return RsData.of("S-1", "리뷰 등록이 완료되었습니다.", ReviewResponse.of(review)); } @Transactional - public ReviewResponse modify(Long reviewId, ReviewSaveRequest reviewSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { + public RsData modify(Long reviewId, ReviewSaveRequest reviewSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { Review review = reviewRepository.findById(reviewId).orElseThrow(); CommonFile mainFile = review.getFile(); @@ -119,7 +112,7 @@ public ReviewResponse modify(Long reviewId, ReviewSaveRequest reviewSaveRequest, review.update(reviewSaveRequest, mainFile); - return ReviewResponse.of(review); + return RsData.of("S-1", "리뷰 수정이 완료되었습니다.", ReviewResponse.of(review)); } @Transactional From f2930ac70103c717d52cbd89dc92a4279509f5f4 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Sat, 10 Jun 2023 20:59:48 +0900 Subject: [PATCH 265/367] =?UTF-8?q?fix:=20delete=20=EC=97=B0=EA=B2=B0=20?= =?UTF-8?q?=EC=95=88=EB=90=9C=EA=B2=83=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/trendpick/review/detail.html | 10 ++++++++-- .../resources/templates/trendpick/review/list.html | 14 +++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/main/resources/templates/trendpick/review/detail.html b/src/main/resources/templates/trendpick/review/detail.html index beaef420..98243928 100644 --- a/src/main/resources/templates/trendpick/review/detail.html +++ b/src/main/resources/templates/trendpick/review/detail.html @@ -17,8 +17,14 @@
    -
    - 수정하기 +
    diff --git a/src/main/resources/templates/trendpick/review/list.html b/src/main/resources/templates/trendpick/review/list.html index 85957b0e..161b9d43 100644 --- a/src/main/resources/templates/trendpick/review/list.html +++ b/src/main/resources/templates/trendpick/review/list.html @@ -40,9 +40,17 @@

    - 수정하기 + +
    From e3aaabacd41ba373b3b5306688bcf8783717478e Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Sat, 10 Jun 2023 21:01:49 +0900 Subject: [PATCH 266/367] =?UTF-8?q?refactor:=20=EC=95=84=EB=AC=B4=EA=B2=83?= =?UTF-8?q?=EB=8F=84=20=EC=97=86=EC=9D=84=EB=95=90=20=ED=8E=98=EC=9D=B4?= =?UTF-8?q?=EC=A7=95=20=EC=B2=98=EB=A6=AC=EB=90=9C=20=EA=B2=83=20=EC=95=88?= =?UTF-8?q?=EB=9C=A8=EA=B2=8C=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/templates/trendpick/review/list.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/trendpick/review/list.html b/src/main/resources/templates/trendpick/review/list.html index 161b9d43..da98dea1 100644 --- a/src/main/resources/templates/trendpick/review/list.html +++ b/src/main/resources/templates/trendpick/review/list.html @@ -55,7 +55,7 @@ -
    +
    Previous From 6c164c22f37e80fa4c04072f1a16abd5919e1f11 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Sat, 10 Jun 2023 22:46:28 +0900 Subject: [PATCH 267/367] =?UTF-8?q?refactor:=20RsData=20=EC=A0=81=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/product/controller/ProductController.java | 9 +++++---- .../domain/product/service/ProductService.java | 8 ++++---- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 3732c4e0..c6f359b2 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -28,6 +28,7 @@ import project.trendpick_pro.domain.review.entity.dto.response.ReviewProductResponse; import project.trendpick_pro.domain.review.service.ReviewService; import project.trendpick_pro.global.basedata.tagname.service.TagNameService; +import project.trendpick_pro.global.rsData.RsData; import java.io.IOException; import java.net.URLEncoder; @@ -77,8 +78,8 @@ public String register(@ModelAttribute @Valid ProductSaveRequest productSaveRequ @RequestParam("mainFile") MultipartFile mainFile, @RequestParam("subFiles") List subFiles) throws IOException { log.info("registerProduct: {}", productSaveRequest.toString()); - Long id = productService.register(productSaveRequest, mainFile, subFiles); - return "redirect:/trendpick/products/" + id; + RsData id = productService.register(productSaveRequest, mainFile, subFiles); + return rq.redirectWithMsg("/trendpick/products/" + id.getData(), String.valueOf(id.getData())); } @GetMapping("/edit/{productId}") @@ -105,8 +106,8 @@ public String modifyBefore(@PathVariable Long productId, Model model) throws IOE @PostMapping("/edit/{productId}") public String modifyProduct(@PathVariable Long productId, @Valid ProductSaveRequest productSaveRequest, @RequestParam("mainFile") MultipartFile mainFile, @RequestParam("subFiles") List subFiles) throws IOException { - Long id = productService.modify(productId, productSaveRequest, mainFile, subFiles); - return "redirect:/trendpick/products/" + id; + RsData id = productService.modify(productId, productSaveRequest, mainFile, subFiles); + return rq.redirectWithMsg("/trendpick/products/" + id.getData(), String.valueOf(id.getData())); } @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 463e1159..c6f56ca4 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -72,7 +72,7 @@ public Product findById(Long id) { } @Transactional - public Long register(ProductSaveRequest productSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { + public RsData register(ProductSaveRequest productSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { rq.CheckAdmin(); @@ -96,11 +96,11 @@ public Long register(ProductSaveRequest productSaveRequest, MultipartFile reques product.addTag(tags); productRepository.save(product); - return product.getId(); + return RsData.of("S-1", "상품 등록이 완료되었습니다.", product.getId()); } @Transactional - public Long modify(Long productId, ProductSaveRequest productSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { + public RsData modify(Long productId, ProductSaveRequest productSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws IOException { rq.CheckAdmin(); @@ -127,7 +127,7 @@ public Long modify(Long productId, ProductSaveRequest productSaveRequest, Multip } product.update(productSaveRequest, mainFile); - return product.getId(); + return RsData.of("S-1", "상품 수정 완료되었습니다.", product.getId()); } @Transactional From 245941d5c54c380e4b41b4b1fd5e49c28f1c53fc Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sat, 10 Jun 2023 23:53:20 +0900 Subject: [PATCH 268/367] =?UTF-8?q?refactor:=20=EA=B4=80=EB=A6=AC=EC=9E=90?= =?UTF-8?q?=20=ED=8C=90=EB=A7=A4=EB=82=B4=EC=97=AD=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=ED=8F=89=EC=A0=90=EC=97=90=20=EB=94=B0=EB=A5=B8=20=EB=B3=84?= =?UTF-8?q?=EA=B0=9C=EC=88=98=20=ED=91=9C=EC=8B=9C=20(=EB=B3=84=20?= =?UTF-8?q?=EB=B0=98=EA=B0=9C)=20=20(#171)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/review/service/ReviewService.java | 1 + .../templates/trendpick/admin/products.html | 23 ++++++++++++++----- .../templates/trendpick/admin/sales.html | 6 ++++- .../templates/trendpick/orders/detail.html | 10 ++++---- .../trendpick/usr/member/orders.html | 2 +- 5 files changed, 29 insertions(+), 13 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index 3695e03d..db8b7af8 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -73,6 +73,7 @@ public void delete(Long reviewId) { reviewRepository.delete(review); } + @Transactional public ReviewResponse createReview(Member actor, Long productId, ReviewSaveRequest reviewSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws Exception { Product product = productRepository.findById(productId).orElseThrow(); diff --git a/src/main/resources/templates/trendpick/admin/products.html b/src/main/resources/templates/trendpick/admin/products.html index 04fdb935..63ddfb07 100644 --- a/src/main/resources/templates/trendpick/admin/products.html +++ b/src/main/resources/templates/trendpick/admin/products.html @@ -48,8 +48,15 @@

    판매상품 관리

    - +
    +
    + + + +
    +
    ()
    @@ -64,7 +71,8 @@

    판매상품 관리

    @@ -74,11 +82,14 @@

    판매상품 관리

    - Previous + Previous - + - Next + Next
    diff --git a/src/main/resources/templates/trendpick/admin/sales.html b/src/main/resources/templates/trendpick/admin/sales.html index a1df956a..59a2f3f7 100644 --- a/src/main/resources/templates/trendpick/admin/sales.html +++ b/src/main/resources/templates/trendpick/admin/sales.html @@ -34,7 +34,11 @@

    판매내역

    -
    +
    + + +
    diff --git a/src/main/resources/templates/trendpick/orders/detail.html b/src/main/resources/templates/trendpick/orders/detail.html index edc64605..2ed78d63 100644 --- a/src/main/resources/templates/trendpick/orders/detail.html +++ b/src/main/resources/templates/trendpick/orders/detail.html @@ -44,10 +44,10 @@

    주문상세

    -
    - -
    + + + + +
    \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/member/orders.html b/src/main/resources/templates/trendpick/usr/member/orders.html index b54efde8..733f03d6 100644 --- a/src/main/resources/templates/trendpick/usr/member/orders.html +++ b/src/main/resources/templates/trendpick/usr/member/orders.html @@ -36,7 +36,7 @@

    나의 주문목록

    -
    +
    From cc2141c665fbf5e878bbcdd8579dd98a90ed873c Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sat, 10 Jun 2023 23:55:04 +0900 Subject: [PATCH 269/367] =?UTF-8?q?fix:=20git=20pull=20=EC=B6=A9=EB=8F=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trendpick_pro/domain/review/service/ReviewService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index db8b7af8..3695e03d 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -73,7 +73,6 @@ public void delete(Long reviewId) { reviewRepository.delete(review); } - @Transactional public ReviewResponse createReview(Member actor, Long productId, ReviewSaveRequest reviewSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws Exception { Product product = productRepository.findById(productId).orElseThrow(); From 62ae501db119914d5857360350644da39e0690d0 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sat, 10 Jun 2023 23:55:37 +0900 Subject: [PATCH 270/367] =?UTF-8?q?fix:=20git=20pull=20=EC=B6=A9=EB=8F=8C?= =?UTF-8?q?=20=ED=95=B4=EA=B2=B0=20=ED=9B=84=20=EB=B3=B5=EA=B5=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trendpick_pro/domain/review/service/ReviewService.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java index 799e04d7..249f1419 100644 --- a/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java +++ b/src/main/java/project/trendpick_pro/domain/review/service/ReviewService.java @@ -66,6 +66,7 @@ public void delete(Long reviewId) { reviewRepository.delete(review); } + @Transactional public RsData createReview(Member actor, Long productId, ReviewSaveRequest reviewSaveRequest, MultipartFile requestMainFile, List requestSubFiles) throws Exception { Product product = productRepository.findById(productId).orElseThrow(); From f851b0d59502736e841174d73f1074e97a4e53e7 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 11 Jun 2023 00:22:08 +0900 Subject: [PATCH 271/367] =?UTF-8?q?refactor:=20=EC=83=81=ED=92=88=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=EC=8B=9C=EC=97=90=20=EA=B8=B0=EC=A1=B4=20?= =?UTF-8?q?=EA=B0=92=20=EB=B6=88=EB=9F=AC=EC=98=A4=EA=B8=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orders/contoller/OrderController.java | 12 +-- .../domain/product/entity/Product.java | 11 +++ .../product/service/ProductService.java | 9 ++ .../domain/tags/tag/entity/Tag.java | 4 + .../domain/tags/tag/service/TagService.java | 7 ++ .../global/tosspayment/PaymentController.java | 2 +- .../trendpick/orders/order-form.html | 30 +----- .../trendpick/products/detailpage.html | 24 ++--- .../templates/trendpick/products/modify.html | 92 ++++++++++++++----- 9 files changed, 125 insertions(+), 66 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index efef34dc..c074bb35 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -28,10 +28,7 @@ import project.trendpick_pro.global.rsData.RsData; import java.time.LocalDateTime; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Optional; +import java.util.*; @Slf4j @@ -67,11 +64,12 @@ public String orderForm(@ModelAttribute OrderForm orderForm, @PostMapping("/order") public synchronized String processOrder(@ModelAttribute("orderForm") OrderForm orderForm) { Member member = rq.CheckMember().get(); - if (member.getId() != orderForm.getMemberInfo().getMemberId()) + if (!Objects.equals(member.getId(), orderForm.getMemberInfo().getMemberId())) throw new RuntimeException("잘못된 접근입니다."); orderService.order(member, orderForm); - return "redirect:/trendpick/orders/list"; + return "redirect:/trendpick/orders/usr/list"; } + @PreAuthorize("hasAuthority({'MEMBER'})") @PostMapping("/cart") public String cartToOrder(@RequestParam("selectedItems") List selectedItems, RedirectAttributes redirect) { @@ -88,7 +86,7 @@ public String orderProduct(@ModelAttribute ProductOptionForm productOptionForm, } @PreAuthorize("hasAuthority({'MEMBER'})") - @GetMapping("usr//list") + @GetMapping("usr/list") public String orderListByMember( @RequestParam(value = "page", defaultValue = "0") int offset, Model model) { diff --git a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java index fd2b264b..29ac1f7f 100644 --- a/src/main/java/project/trendpick_pro/domain/product/entity/Product.java +++ b/src/main/java/project/trendpick_pro/domain/product/entity/Product.java @@ -167,4 +167,15 @@ public void addTag(Set tags){ tag.connectProduct(this); } } + + public void modifyTag(Set tags){ + for (Tag tag : this.tags) { + tag.disconnectProduct(); + } + + this.tags = tags; + for (Tag tag : tags) { + tag.connectProduct(this); + } + } } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 463e1159..8a19fac7 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -41,6 +41,7 @@ import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tags.tag.entity.Tag; import project.trendpick_pro.domain.tags.tag.entity.type.TagType; +import project.trendpick_pro.domain.tags.tag.service.TagService; import project.trendpick_pro.global.rsData.RsData; import java.io.File; @@ -61,6 +62,7 @@ public class ProductService { private final FileTranslator fileTranslator; private final FavoriteTagService favoriteTagService; + private final TagService tagService; private final Rq rq; @@ -126,6 +128,13 @@ public Long modify(Long productId, ProductSaveRequest productSaveRequest, Multip mainFile.connectFile(subFile); } + Set tags = new LinkedHashSet<>(); // 상품에 포함시킬 태크 선택하여 저장 + for (String tagName : productSaveRequest.getTags()) { + tags.add(new Tag(tagName)); + } + + tagService.delete(product.getTags()); + product.modifyTag(tags); product.update(productSaveRequest, mainFile); return product.getId(); } diff --git a/src/main/java/project/trendpick_pro/domain/tags/tag/entity/Tag.java b/src/main/java/project/trendpick_pro/domain/tags/tag/entity/Tag.java index 42090fc5..07d63dab 100644 --- a/src/main/java/project/trendpick_pro/domain/tags/tag/entity/Tag.java +++ b/src/main/java/project/trendpick_pro/domain/tags/tag/entity/Tag.java @@ -22,6 +22,10 @@ public void connectProduct(Product product){ this.product = product; } + public void disconnectProduct(){ + this.product = null; + } + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "product_id") private Product product; diff --git a/src/main/java/project/trendpick_pro/domain/tags/tag/service/TagService.java b/src/main/java/project/trendpick_pro/domain/tags/tag/service/TagService.java index abf38a3c..6e703ee0 100644 --- a/src/main/java/project/trendpick_pro/domain/tags/tag/service/TagService.java +++ b/src/main/java/project/trendpick_pro/domain/tags/tag/service/TagService.java @@ -7,6 +7,7 @@ import project.trendpick_pro.domain.tags.tag.repository.TagRepository; import java.util.List; +import java.util.Set; @Service @RequiredArgsConstructor @@ -23,4 +24,10 @@ public List getAllTags() { return tagRepository.findAll(); } + public void delete(Set tags) { + for (Tag tag : tags) { + tagRepository.delete(tag); + } + } + } diff --git a/src/main/java/project/trendpick_pro/global/tosspayment/PaymentController.java b/src/main/java/project/trendpick_pro/global/tosspayment/PaymentController.java index 73b92877..d17a1238 100644 --- a/src/main/java/project/trendpick_pro/global/tosspayment/PaymentController.java +++ b/src/main/java/project/trendpick_pro/global/tosspayment/PaymentController.java @@ -82,7 +82,7 @@ public String paymentResult( model.addAttribute("message", (String) jsonObject.get("message")); } - return "redirect:/trendpick/member/orders/list"; + return "redirect:/trendpick/orders/usr/list"; } @GetMapping(value = "/payment/fail") diff --git a/src/main/resources/templates/trendpick/orders/order-form.html b/src/main/resources/templates/trendpick/orders/order-form.html index 399ec991..6b42a68b 100644 --- a/src/main/resources/templates/trendpick/orders/order-form.html +++ b/src/main/resources/templates/trendpick/orders/order-form.html @@ -117,7 +117,7 @@

    결제 정보

    diff --git a/src/main/resources/templates/trendpick/products/detailpage.html b/src/main/resources/templates/trendpick/products/detailpage.html index a5d0c5f3..6d37b298 100644 --- a/src/main/resources/templates/trendpick/products/detailpage.html +++ b/src/main/resources/templates/trendpick/products/detailpage.html @@ -35,17 +35,19 @@

    -
    -
    - - - -
    -
    - - - -
    +
    +
    +
    + + + +
    +
    + + + +
    +
    diff --git a/src/main/resources/templates/trendpick/products/modify.html b/src/main/resources/templates/trendpick/products/modify.html index b0ac2e16..244ddfec 100644 --- a/src/main/resources/templates/trendpick/products/modify.html +++ b/src/main/resources/templates/trendpick/products/modify.html @@ -2,14 +2,20 @@ - Product Registration + 상품 수정
    - + +
    @@ -37,46 +62,63 @@
    - +
    +
    +
    -
    - -
    -
    - + + +
    +
    +
    +
    +
    + Main Image +
    +
    +
    +
    + Sub Image +
    +
    +
    @@ -89,13 +131,21 @@
    - +
    + +
    +
    + + + +
    +



    +
    -
    -
    +

    From 9d24b42d5f6f5645595f5805bd67fe21e85c6825 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 11 Jun 2023 00:31:53 +0900 Subject: [PATCH 272/367] =?UTF-8?q?refactor:=20=ED=9A=8C=EC=9B=90=EA=B0=80?= =?UTF-8?q?=EC=9E=85=20=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=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 --- .../templates/trendpick/usr/member/join.html | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/src/main/resources/templates/trendpick/usr/member/join.html b/src/main/resources/templates/trendpick/usr/member/join.html index eefed4ba..48ce6967 100644 --- a/src/main/resources/templates/trendpick/usr/member/join.html +++ b/src/main/resources/templates/trendpick/usr/member/join.html @@ -20,15 +20,15 @@ From 77f93b9df14158ecc504b5d0f4d6eef9384e5923 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 11 Jun 2023 00:36:17 +0900 Subject: [PATCH 273/367] =?UTF-8?q?refactor:=20layout=EC=97=90=20=EC=95=8C?= =?UTF-8?q?=EB=A6=BC=20=EC=82=AD=EC=A0=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/trendpick/usr/layout/layout.html | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/main/resources/templates/trendpick/usr/layout/layout.html b/src/main/resources/templates/trendpick/usr/layout/layout.html index 80d01fb5..5244103e 100644 --- a/src/main/resources/templates/trendpick/usr/layout/layout.html +++ b/src/main/resources/templates/trendpick/usr/layout/layout.html @@ -63,16 +63,6 @@

    TrendPick

    -
    - -
    From 28db2c38075f1fbe13ef92441186d6f01ca31cc9 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Sun, 11 Jun 2023 00:45:50 +0900 Subject: [PATCH 275/367] =?UTF-8?q?refactor:=20redirect=EC=8B=9C=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/product/controller/ProductController.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index c6f359b2..c1b4cc62 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -79,7 +79,7 @@ public String register(@ModelAttribute @Valid ProductSaveRequest productSaveRequ @RequestParam("subFiles") List subFiles) throws IOException { log.info("registerProduct: {}", productSaveRequest.toString()); RsData id = productService.register(productSaveRequest, mainFile, subFiles); - return rq.redirectWithMsg("/trendpick/products/" + id.getData(), String.valueOf(id.getData())); + return rq.redirectWithMsg("/trendpick/products/" + id.getData(), id.getMsg()); } @GetMapping("/edit/{productId}") @@ -107,7 +107,7 @@ public String modifyBefore(@PathVariable Long productId, Model model) throws IOE public String modifyProduct(@PathVariable Long productId, @Valid ProductSaveRequest productSaveRequest, @RequestParam("mainFile") MultipartFile mainFile, @RequestParam("subFiles") List subFiles) throws IOException { RsData id = productService.modify(productId, productSaveRequest, mainFile, subFiles); - return rq.redirectWithMsg("/trendpick/products/" + id.getData(), String.valueOf(id.getData())); + return rq.redirectWithMsg("/trendpick/products/" + id.getData(), id.getMsg()); } @PreAuthorize("hasAuthority({'ADMIN', 'BRAND_ADMIN'})") From 6b7965806bd89179f6e4abd502244a8b16095aa7 Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Sun, 11 Jun 2023 00:46:02 +0900 Subject: [PATCH 276/367] =?UTF-8?q?refactor:=20redirect=EC=8B=9C=20?= =?UTF-8?q?=EB=A9=94=EC=8B=9C=EC=A7=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/trendpick/products/modify.html | 92 ++++++++++++++-- .../trendpick/products/register.html | 101 +++++++++++++++--- 2 files changed, 173 insertions(+), 20 deletions(-) diff --git a/src/main/resources/templates/trendpick/products/modify.html b/src/main/resources/templates/trendpick/products/modify.html index 244ddfec..b0120437 100644 --- a/src/main/resources/templates/trendpick/products/modify.html +++ b/src/main/resources/templates/trendpick/products/modify.html @@ -51,18 +51,94 @@ }); + -
    +
    - +
    - +
    @@ -110,7 +186,7 @@
    - +
    @@ -121,17 +197,17 @@
    - +
    - +
    - +
    @@ -153,7 +229,7 @@
    - +
    diff --git a/src/main/resources/templates/trendpick/products/register.html b/src/main/resources/templates/trendpick/products/register.html index 65498d76..b0e8c227 100644 --- a/src/main/resources/templates/trendpick/products/register.html +++ b/src/main/resources/templates/trendpick/products/register.html @@ -29,15 +29,92 @@ }); -
    + + +
    - - + +
    - +
    @@ -45,7 +122,7 @@
    @@ -56,7 +133,7 @@
    @@ -75,28 +152,28 @@
    - +
    - +
    - +
    - +
    -
    +

    @@ -104,7 +181,7 @@
    - +
    From 29f8a6c30c28a434908aa4668e9eca4c2d0c2d3a Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 11 Jun 2023 00:52:18 +0900 Subject: [PATCH 277/367] =?UTF-8?q?refactor:=20=EB=A6=AC=EB=B7=B0=20?= =?UTF-8?q?=EA=B2=80=EC=A6=9D=20=EB=A1=9C=EC=A7=81=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../templates/trendpick/review/register.html | 56 +++++++++++++++++-- 1 file changed, 50 insertions(+), 6 deletions(-) diff --git a/src/main/resources/templates/trendpick/review/register.html b/src/main/resources/templates/trendpick/review/register.html index 33938ee1..5f1fb3a2 100644 --- a/src/main/resources/templates/trendpick/review/register.html +++ b/src/main/resources/templates/trendpick/review/register.html @@ -1,15 +1,59 @@ - - - 리뷰 등록 - - +
    + + +
    -
    From 73c095384ebfdf5ece6d0b70404dc681f21c8838 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 11 Jun 2023 01:15:23 +0900 Subject: [PATCH 278/367] =?UTF-8?q?refactor:=20Order=EB=8F=84=EB=A9=94?= =?UTF-8?q?=EC=9D=B8=20=EB=B0=98=ED=99=98=EA=B0=92=20RsData=EB=A1=9C=20?= =?UTF-8?q?=EC=88=98=EC=A0=95=20(#181)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../orders/contoller/OrderController.java | 40 +++++++++----- .../domain/orders/entity/Order.java | 1 - .../domain/orders/service/OrderService.java | 52 ++++++++++++------- 3 files changed, 61 insertions(+), 32 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index c074bb35..776cf38a 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -19,6 +19,7 @@ import project.trendpick_pro.domain.orders.entity.OrderStatus; import project.trendpick_pro.domain.orders.entity.dto.request.OrderForm; import project.trendpick_pro.domain.orders.entity.dto.request.OrderSearchCond; +import project.trendpick_pro.domain.orders.entity.dto.response.OrderDetailResponse; import project.trendpick_pro.domain.orders.entity.dto.response.OrderItemDto; import project.trendpick_pro.domain.orders.entity.dto.response.OrderResponse; import project.trendpick_pro.domain.orders.service.OrderService; @@ -39,14 +40,13 @@ public class OrderController { private final OrderService orderService; private final Rq rq; - private final MemberService memberService; - private final ProductRepository productRepository; @PreAuthorize("hasAuthority({'MEMBER'})") @GetMapping("/order-form") public String orderForm(@ModelAttribute OrderForm orderForm, HttpServletRequest req, Model model) { Map flashMap = RequestContextUtils.getInputFlashMap(req); + if (flashMap != null) { orderForm = (OrderForm) flashMap.get("orderForm"); model.addAttribute("orderForm", orderForm); @@ -60,29 +60,42 @@ public String orderForm(@ModelAttribute OrderForm orderForm, model.addAttribute("SuperTotalPrice", totalPrice); return "trendpick/orders/order-form"; } + @PreAuthorize("hasAuthority({'MEMBER'})") @PostMapping("/order") public synchronized String processOrder(@ModelAttribute("orderForm") OrderForm orderForm) { Member member = rq.CheckMember().get(); if (!Objects.equals(member.getId(), orderForm.getMemberInfo().getMemberId())) throw new RuntimeException("잘못된 접근입니다."); - orderService.order(member, orderForm); - return "redirect:/trendpick/orders/usr/list"; + + RsData result = orderService.order(member, orderForm); + if(result.isFail()) + return rq.redirectWithMsg("/trendpick/products/list?main-category=상의", result); + return rq.redirectWithMsg("/trendpick/orders/%s".formatted(result.getData()), result); } @PreAuthorize("hasAuthority({'MEMBER'})") @PostMapping("/cart") public String cartToOrder(@RequestParam("selectedItems") List selectedItems, RedirectAttributes redirect) { - redirect.addFlashAttribute("orderForm" - ,orderService.cartToOrder(rq.CheckMember().get(), selectedItems)); - return "redirect:/trendpick/orders/order-form"; + RsData result = orderService.cartToOrder(rq.CheckMember().get(), selectedItems); + if(result.isFail()) + return rq.historyBack(result); + + redirect.addFlashAttribute("orderForm", result.getData()); + return rq.redirectWithMsg("/trendpick/orders/order-form", "주문폼을 확인하시고 결제 버튼을 눌러주세요."); +// return "redirect:/trendpick/orders/order-form"; + // addFlashAttribute 이거 때문에 그냥 리다이렉트 시켜야 할 수도 있습니다. } @PreAuthorize("hasAuthority({'MEMBER'})") @PostMapping("/order/product") public String orderProduct(@ModelAttribute ProductOptionForm productOptionForm, RedirectAttributes redirect) { - redirect.addFlashAttribute("orderForm", orderService.productToOrder(rq.CheckMember().get(), productOptionForm)); - return "redirect:/trendpick/orders/order-form"; + RsData result = orderService.productToOrder(rq.CheckMember().get(), productOptionForm); + if(result.isFail()) + return rq.historyBack(result); + redirect.addFlashAttribute("orderForm", result.getData()); + return rq.redirectWithMsg("/trendpick/orders/order-form", "주문폼을 확인하시고 결제 버튼을 눌러주세요."); +// return "redirect:/trendpick/orders/order-form"; } @PreAuthorize("hasAuthority({'MEMBER'})") @@ -120,15 +133,18 @@ public String orderListBySeller( public String cancelOrder(@PathVariable("orderId") Long orderId) { RsData result = orderService.cancel(orderId); if(result.isFail()) - rq.historyBack(result); - return rq.redirectWithMsg("/trendpick/orders/admin/list", result); + return rq.historyBack(result); + return rq.redirectWithMsg("/trendpick/orders/usr/list", result); } @PreAuthorize("hasAuthority({'MEMBER'})") @GetMapping("/{orderId}") public String showOrder(@PathVariable("orderId") Long orderId, Model model){ + RsData result = orderService.showOrderItems(rq.CheckMember().get(), orderId); + if(result.isFail()) rq.historyBack(result); + model.addAttribute("order", - orderService.showOrderItems(rq.CheckMember().get(), orderId)); + result.getData()); return "trendpick/orders/detail"; } } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java index 35b2cc07..006a06e0 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java @@ -70,6 +70,5 @@ public static Order createOrder(Member member, Delivery delivery, OrderStatus st public void cancel() { this.status = OrderStatus.CANCELLED; - } } diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index e21fa750..e991255c 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -51,16 +51,18 @@ public class OrderService { private final FavoriteTagService favoriteTagService; @Transactional - public void order(Member member, OrderForm orderForm) { + public RsData order(Member member, OrderForm orderForm) { - Delivery delivery = new Delivery(orderForm.getMemberInfo().getAddress()); + if(orderForm.getMemberInfo().getAddress().trim().length() == 0) + return RsData.of("F-1", "주소를 등록해주세요."); + Delivery delivery = new Delivery(orderForm.getMemberInfo().getAddress()); List orderItemList = new ArrayList<>(); Product product = null; for (OrderItemDto orderItemDto : orderForm.getOrderItems()) { product = productRepository.findById(orderItemDto.getProductId()).orElseThrow(() -> new ProductNotFoundException("존재하지 않는 상품 입니다.")); if (product.getStock() < orderItemDto.getCount()) { - throw new ProductStockOutException(product.getName()+"의 재고가 부족합니다."); // 임시. 나중에 사용자 exception 널을까말까 생각 + RsData.of("F-2", product.getName()+"의 재고가 부족합니다."); } favoriteTagService.updateTag(member, product, TagType.ORDER); @@ -77,22 +79,27 @@ public void order(Member member, OrderForm orderForm) { cartService.deleteCartItemsByOrder(member, orderItemIds); } Order order = Order.createOrder(member, delivery, OrderStatus.ORDERED, orderItemList, orderForm.getPaymentMethod()); - orderRepository.save(order); + Order savedOrder = orderRepository.save(order); + return RsData.of("S-1", "주문이 성공적으로 처리되었습니다.", savedOrder.getId()); } @Transactional public RsData cancel(Long orderId) { - Order order = orderRepository.findById(orderId).orElseThrow(() -> new EntityNotFoundException("존재하지 않는 주문입니다.")); + Order order = orderRepository.findById(orderId).orElse(null); + if(order==null) + return RsData.of("F-4", "존재하지 않는 주문입니다."); + if(order.getStatus() == OrderStatus.CANCELLED) return RsData.of("F-1", "이미 취소된 주문입니다."); if (order.getDelivery().getState() != DeliveryState.COMPLETED) { - throw new IllegalStateException("이미 배송완료된 상품은 취소가 불가능합니다."); + return RsData.of("F-2", "이미 배송완료된 상품은 취소가 불가능합니다."); } if (order.getDelivery().getState() != DeliveryState.COMPLETED) { - throw new IllegalStateException("이미 배송을 시작하여 취소가 불가능합니다."); + return RsData.of("F-3", "이미 배송을 시작하여 취소가 불가능합니다."); } + order.cancel(); return RsData.of("S-1", "환불 요청이 정상적으로 진행되었습니다. 환불까지는 최소 2일에서 최대 14일까지 소요될 수 있습니다."); } @@ -105,14 +112,14 @@ public int OrderSize() { return orderRepository.findAll().size(); } - public OrderForm cartToOrder(Member member, List selectedItems) { + public RsData cartToOrder(Member member, List selectedItems) { List cartItems = cartService.findCartItems(member, selectedItems); for (CartItem cartItem : cartItems) { if (cartItem.getCart().getMember().getId() != member.getId()) - throw new MemberNotMatchException("현재 접속중인 사용자와 장바구니 사용자가 일치하지 않습니다."); + return RsData.of("F-1","현재 접속중인 사용자와 장바구니 사용자가 일치하지 않습니다."); } - return new OrderForm(MemberInfoDto.of(member) ,convertToOrderItemDto(cartItems)); + return RsData.of("S-1", "리다이렉팅중...",new OrderForm(MemberInfoDto.of(member) ,convertToOrderItemDto(cartItems))); } private List convertToOrderItemDto(List cartItems) { @@ -123,20 +130,27 @@ private List convertToOrderItemDto(List cartItems) { return orderItemDtoList; } - public OrderForm productToOrder(Member member, ProductOptionForm productOptionForm) { - Product product = productRepository.findById(productOptionForm.getProductId()) - .orElseThrow(() -> new ProductNotFoundException("존재하지 않는 상품입니다.")); + public RsData productToOrder(Member member, ProductOptionForm productOptionForm) { + Product product = productRepository.findById(productOptionForm.getProductId()).orElse(null); + if(product==null) + return RsData.of("F-1", "존재하지 않는 상품입니다."); + List orderItemDtoList = new ArrayList<>(); orderItemDtoList.add(OrderItemDto.of(product, productOptionForm.getQuantity())); - return new OrderForm(MemberInfoDto.of(member), orderItemDtoList); + OrderForm orderForm = new OrderForm(MemberInfoDto.of(member), orderItemDtoList); + return RsData.of("S-1", "리다이렉팅중...", orderForm); } - public OrderDetailResponse showOrderItems(Member member, Long orderId) { - Order order = orderRepository.findById(orderId).orElseThrow( - () -> new IllegalArgumentException("잘못된 주문번호입니다.")); + public RsData showOrderItems(Member member, Long orderId) { + Order order = orderRepository.findById(orderId).orElse(null); + if (order == null) + return RsData.of("F-1", "잘못된 주문번호입니다. 다시 확인해주세요."); + if (order.getMember().getId() != member.getId()) - throw new IllegalArgumentException("다른 사용자의 주문에는 접근할 수 없습니다."); - return OrderDetailResponse.of(order, orderRepository.findOrderItemsByOrderId(orderId)); + return RsData.of("F-2", "다른 사용자의 주문에는 접근할 수 없습니다."); + OrderDetailResponse orderResponse = OrderDetailResponse.of(order, orderRepository.findOrderItemsByOrderId(orderId)); + return RsData.of("S-1", + orderResponse.getOrderItems().size()+"개의 주문 상품입니다.", orderResponse); } public Page findAllBySeller(Member member, int offset) { return orderRepository.findAllBySeller( From 56474cba386e61ba7938de3a29f1861e5ccaaefe Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 11 Jun 2023 01:21:54 +0900 Subject: [PATCH 279/367] =?UTF-8?q?feat:=20=EC=A3=BC=EB=AC=B8=EC=B7=A8?= =?UTF-8?q?=EC=86=8C=EC=8B=9C=20=ED=8C=90=EB=A7=A4=EB=9F=89=EA=B3=BC=20?= =?UTF-8?q?=EC=83=81=ED=92=88=EC=9E=AC=EA=B3=A0=20=EB=A1=A4=EB=B0=B1=20(#1?= =?UTF-8?q?81)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/orders/contoller/OrderController.java | 3 ++- .../project/trendpick_pro/domain/orders/entity/Order.java | 4 ++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java index 776cf38a..5813c59d 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java +++ b/src/main/java/project/trendpick_pro/domain/orders/contoller/OrderController.java @@ -141,7 +141,8 @@ public String cancelOrder(@PathVariable("orderId") Long orderId) { @GetMapping("/{orderId}") public String showOrder(@PathVariable("orderId") Long orderId, Model model){ RsData result = orderService.showOrderItems(rq.CheckMember().get(), orderId); - if(result.isFail()) rq.historyBack(result); + if(result.isFail()) + return rq.historyBack(result); model.addAttribute("order", result.getData()); diff --git a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java index 006a06e0..4a70b4ba 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java +++ b/src/main/java/project/trendpick_pro/domain/orders/entity/Order.java @@ -70,5 +70,9 @@ public static Order createOrder(Member member, Delivery delivery, OrderStatus st public void cancel() { this.status = OrderStatus.CANCELLED; + for (OrderItem orderItem : this.orderItems) { + orderItem.getProduct().decreaseSaleCount(orderItem.getCount()); + orderItem.getProduct().addStock(orderItem.getCount()); + } } } From 44d0a1fdc199290da24f9a251a5b217308a42863 Mon Sep 17 00:00:00 2001 From: jooooonj Date: Sun, 11 Jun 2023 01:38:20 +0900 Subject: [PATCH 280/367] =?UTF-8?q?fix:=20=EC=A3=BC=EB=AC=B8=20=EA=B8=B0?= =?UTF-8?q?=EB=B3=B8=EB=8D=B0=EC=9D=B4=ED=84=B0=20=EC=83=9D=EC=84=B1=20?= =?UTF-8?q?=EC=98=A4=EB=A5=98=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../trendpick_pro/domain/orders/service/OrderService.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index e991255c..3b1d2dc5 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -53,9 +53,6 @@ public class OrderService { @Transactional public RsData order(Member member, OrderForm orderForm) { - if(orderForm.getMemberInfo().getAddress().trim().length() == 0) - return RsData.of("F-1", "주소를 등록해주세요."); - Delivery delivery = new Delivery(orderForm.getMemberInfo().getAddress()); List orderItemList = new ArrayList<>(); Product product = null; From c84433568f89b475f953f8e83820f1ec961708e7 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 11 Jun 2023 01:40:02 +0900 Subject: [PATCH 281/367] =?UTF-8?q?refactor:=20=EC=A3=BC=EB=AC=B8=20?= =?UTF-8?q?=EC=B2=B4=ED=81=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/templates/trendpick/orders/order-form.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/templates/trendpick/orders/order-form.html b/src/main/resources/templates/trendpick/orders/order-form.html index 6b42a68b..e0f3bdb0 100644 --- a/src/main/resources/templates/trendpick/orders/order-form.html +++ b/src/main/resources/templates/trendpick/orders/order-form.html @@ -85,7 +85,7 @@

    결제 정보

    - +
    From e9770c8dad6075b4b6e6bc80ba36b460392f9b1e Mon Sep 17 00:00:00 2001 From: mmunkyeong Date: Sun, 11 Jun 2023 02:57:58 +0900 Subject: [PATCH 282/367] =?UTF-8?q?refactor:=20cart=20RsData=20=EC=A0=81?= =?UTF-8?q?=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../cart/controller/CartController.java | 39 +-- .../domain/cart/service/CartService.java | 40 ++- .../domain/orders/service/OrderService.java | 2 +- .../templates/trendpick/usr/cart/list.html | 264 ++++++++++++------ 4 files changed, 214 insertions(+), 131 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java index 8134e855..88190ece 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java +++ b/src/main/java/project/trendpick_pro/domain/cart/controller/CartController.java @@ -16,6 +16,7 @@ import project.trendpick_pro.domain.common.base.rq.Rq; import project.trendpick_pro.domain.member.entity.Member; import project.trendpick_pro.domain.member.service.MemberService; +import project.trendpick_pro.global.rsData.RsData; import java.util.List; @@ -34,19 +35,9 @@ public class CartController { @GetMapping("/list") public String showCart( Model model) { Member member = rq.CheckMember().get(); - Cart carts = cartService.getCartByUser(rq.CheckMember().get().getId()); - - List cartItems = cartService.CartView(member, carts); - /* - int totalPrice = 0; - - for (CartItem cartItem : cartItems) { - totalPrice += (cartItem.getProduct().getPrice() * cartItem.getQuantity()); - } - model.addAttribute("totalPrice", totalPrice); - */ + Cart carts = cartService.getCartByUser(member.getId()); + List cartItems = cartService.CartView(carts); model.addAttribute("cartItems", cartItems); - return "/trendpick/usr/cart/list"; } @@ -54,7 +45,6 @@ public String showCart( Model model) { @GetMapping("/add") public String addItemToCart(CartItemRequest cartItemRequests, Model model) { model.addAttribute("cartItemRequest", cartItemRequests); - // 쇼핑을 계속 하시겠습니까? 띄우고 yes이면 main no면 cart로 return "/trendpick/usr/cart/add"; } @@ -62,22 +52,21 @@ public String addItemToCart(CartItemRequest cartItemRequests, Model model) { @PreAuthorize("hasAuthority({'MEMBER'})") @PostMapping("/add") public String addItem(@ModelAttribute @Valid CartItemRequest cartItemRequests, Model model) { - CartItemResponse cartItemResponse = cartService.addItemToCart(rq.CheckMember().get(), cartItemRequests); + RsData cartItemResponse = cartService.addItemToCart(rq.CheckMember().get(), cartItemRequests); + if(cartItemResponse.isFail()){ + rq.redirectWithMsg("/trendpick/products/list?main-category=상의",cartItemResponse); + } model.addAttribute("cartItemResponse", cartItemResponse); - // System.out.println(cartItemRequests.getCount()); - // System.out.println(cartItemRequests.getColor()); // 쇼핑을 계속 하시겠습니까? 띄우고 yes이면 main no면 cart로 - return "redirect:/trendpick/usr/cart/list"; + return rq.redirectWithMsg("/trendpick/usr/cart/list", "상품이 추가되었습니다."); } @PreAuthorize("hasAuthority({'MEMBER'})") - @GetMapping("{memberId}/{cartItemId}") - public String removeItem(@PathVariable("memberId") Long memberId, @PathVariable("cartItemId") Long cartItemId) { - Member member = memberService.findByMember(memberId); - member.getCart().setTotalCount(member.getCart().getTotalCount() - 1); + @GetMapping("delete/{cartItemId}") + public String removeItem(@PathVariable("cartItemId") Long cartItemId) { cartService.removeItemFromCart(cartItemId); - return "redirect:/trendpick/usr/cart/list"; + return rq.redirectWithMsg("/trendpick/usr/cart/list", "상품이 삭제되었습니다."); } // 장바구니에서 수량 변경 @@ -85,8 +74,10 @@ public String removeItem(@PathVariable("memberId") Long memberId, @PathVariable( @PostMapping("/update") public String updateCount(@RequestParam("cartItemId") Long cartItemId, @RequestParam("quantity") int newQuantity) { - Member member = rq.CheckMember().get(); - cartService.updateItemCount(member,cartItemId, newQuantity); + RsData cartItems= cartService.updateItemCount(cartItemId, newQuantity); + if(cartItems.isFail()){ + rq.redirectWithMsg("/trendpick/usr/cart/list",cartItems); + } return "redirect:/trendpick/usr/cart/list"; } } \ No newline at end of file diff --git a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java index e6dd9809..9af9204b 100644 --- a/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java +++ b/src/main/java/project/trendpick_pro/domain/cart/service/CartService.java @@ -15,6 +15,7 @@ import project.trendpick_pro.domain.product.repository.ProductRepository; import project.trendpick_pro.domain.tags.favoritetag.service.FavoriteTagService; import project.trendpick_pro.domain.tags.tag.entity.type.TagType; +import project.trendpick_pro.global.rsData.RsData; import java.util.ArrayList; import java.util.List; @@ -32,7 +33,7 @@ public class CartService { // 장바구니 조회 - public List CartView(Member member, Cart cart) { + public List CartView(Cart cart) { List cartItems = cartItemRepository.findAll(); List userItems = new ArrayList<>(); // 장바구니가 비어있는 경우 @@ -49,10 +50,12 @@ public List CartView(Member member, Cart cart) { // 장바구니 상품 추가 @Transactional - public CartItemResponse addItemToCart(Member member, CartItemRequest cartItemRequest) { + public RsData addItemToCart(Member member, CartItemRequest cartItemRequest) { Cart cart = cartRepository.findByMemberId(member.getId()); - Product product = getProductById(cartItemRequest.getProductId()); - + Product product = productRepository.findById(cartItemRequest.getProductId()).orElse(null); + if (product == null) { + return RsData.of("F-1", "해당상품을 찾을 수 없습니다."); + } if (cart == null) { // 장바구니가 비어있다면 생성 cart = Cart.createCart(member); @@ -72,7 +75,7 @@ public CartItemResponse addItemToCart(Member member, CartItemRequest cartItemReq cart.setTotalCount(cart.getTotalCount() + 1); cartItemRepository.save(cartItem); } - return CartItemResponse.of(cartItem); + return RsData.of("S-1", "상품이 추가되었습니다.", CartItemResponse.of(cartItem)); } @@ -84,27 +87,26 @@ public void removeItemFromCart(Long cartItemId) { // 상품의 수량 업데이트 @Transactional - public void updateItemCount(Member member, Long cartItemId, int quantity) { + public RsData updateItemCount(Long cartItemId, int quantity) { CartItem cartItem = cartItemRepository.findById(cartItemId).orElse(null); + if (cartItem == null) { + return RsData.of("F-1", "해당 상품은 장바구니에 없습니다."); + } cartItem.update(quantity); + return RsData.of("S-1", "상품 수량이 업데이트 되었습니다.", cartItem); } public Cart getCartByUser(Long memberId) { return cartRepository.findByMemberId(memberId); } - private Product getProductById(Long productId) { - return productRepository.findById(productId) - .orElseThrow(() -> new IllegalArgumentException("해당 상품을 찾을 수 없습니다.")); - } - - public List findCartItems(Member member,List cartItemIdList) { - Cart cart=getCartByUser(member.getId()); //현재 로그인되어 있는 cart 정보 + public List findCartItems(Member member, List cartItemIdList) { + Cart cart = getCartByUser(member.getId()); //현재 로그인되어 있는 cart 정보 List cartItemList = new ArrayList<>(); for (Long id : cartItemIdList) { - for(CartItem item : cartItemRepository.findByProductId(id)) { - if(item.getCart().getId() == cart.getId()) { + for (CartItem item : cartItemRepository.findByProductId(id)) { + if (item.getCart().getId() == cart.getId()) { cartItemList.add(item); } } @@ -113,12 +115,8 @@ public List findCartItems(Member member,List cartItemIdList) { } @Transactional - public void deleteCartItemsByOrder(Member member,List cartItemIdList) { - Cart cart = cartRepository.findByMemberId(member.getId()); - for(long id: cartItemIdList){ - CartItem cartItem = cartItemRepository.findById(id).orElse(null); - } - cartItemRepository.deleteAllByIdInBatch(cartItemIdList); + public void deleteCartItemsByOrder(List cartItemIdList) { + cartItemRepository.deleteAllByIdInBatch(cartItemIdList); } } diff --git a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java index e21fa750..ec80da6f 100644 --- a/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java +++ b/src/main/java/project/trendpick_pro/domain/orders/service/OrderService.java @@ -74,7 +74,7 @@ public void order(Member member, OrderForm orderForm) { for (CartItem cartItem : cartItems) { orderItemIds.add(cartItem.getId()); } - cartService.deleteCartItemsByOrder(member, orderItemIds); + cartService.deleteCartItemsByOrder(orderItemIds); } Order order = Order.createOrder(member, delivery, OrderStatus.ORDERED, orderItemList, orderForm.getPaymentMethod()); orderRepository.save(order); diff --git a/src/main/resources/templates/trendpick/usr/cart/list.html b/src/main/resources/templates/trendpick/usr/cart/list.html index 10b65067..253f7f65 100644 --- a/src/main/resources/templates/trendpick/usr/cart/list.html +++ b/src/main/resources/templates/trendpick/usr/cart/list.html @@ -3,99 +3,193 @@ 장바구니 - + -
    +
    - - - - - - - - - - - - - - - - - - + + + + + + +
    번호상품ID상품정보가격수량담은날짜삭제
    - - - 1 - - - -
    -
    -
    - + + + + + + + + + + + + + + + + + + + - - - - - - -
    번호상품ID상품정보가격수량담은날짜삭제
    + + + 1 + + + +
    +
    +
    + +
    +
    +
    + +
    -
    - -
    -
    - -
    - - - -
    - - - -
    - -
    - - - X -
    +
    + +
    + +
    + + + +
    +
    +
    + + + X +
    +
    +
    + + + + + + + + + + + + + +
    총 주문금액
    -
    - - - - - - - - - - - - -
    총 주문금액
    -
    -

    0원

    -
    - -
    -
    +
    +

    0원

    +
    + +
    +
    - - - - - - - - - - - TrendPick - - - - - -
    -
    -
    - - - \ No newline at end of file diff --git a/src/main/resources/templates/trendpick/usr/cart/list.html b/src/main/resources/templates/trendpick/usr/cart/list.html index 253f7f65..a432d036 100644 --- a/src/main/resources/templates/trendpick/usr/cart/list.html +++ b/src/main/resources/templates/trendpick/usr/cart/list.html @@ -4,9 +4,6 @@ 장바구니 From c79e15f2d31fa41ca3df76522457fbdcb1eaa52c Mon Sep 17 00:00:00 2001 From: hye-0000 Date: Sun, 11 Jun 2023 16:33:26 +0900 Subject: [PATCH 296/367] =?UTF-8?q?feat:=20=EC=A0=84=EC=B2=B4=20=EC=B9=B4?= =?UTF-8?q?=ED=85=8C=EA=B3=A0=EB=A6=AC=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../product/controller/ProductController.java | 5 +++- .../product/repository/ProductRepository.java | 4 ++- .../product/service/ProductService.java | 17 +++++++++++++ .../templates/trendpick/products/list.html | 25 +++++++++++-------- .../trendpick/usr/layout/layout.html | 1 + 5 files changed, 40 insertions(+), 12 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 33962eb0..91119b77 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -140,7 +140,7 @@ public String showProduct(@PathVariable Long productId, Pageable pageable, Produ public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") int offset, @RequestParam(value = "main-category") String mainCategory, @RequestParam(value = "sub-category", defaultValue = "전체") String subCategory, - Model model) { + Pageable pageable, Model model) { if (mainCategory.equals("recommend")) { mainCategory = "추천"; } else if (mainCategory.equals("top")) { @@ -156,6 +156,9 @@ public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") i model.addAttribute("productResponses", productService.showAll(offset, mainCategory, subCategory)); model.addAttribute("subCategories", subCategoryService.findAll(mainCategory)); } + } if(mainCategory.equals("전체")){ + model.addAttribute("mainCategoryName", mainCategory); + model.addAttribute("productResponses", productService.getAllProducts(pageable)); } else { model.addAttribute("mainCategoryName", mainCategory); model.addAttribute("productResponses", productService.showAll(offset, mainCategory, subCategory)); diff --git a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepository.java b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepository.java index e0afdfab..b9692e7c 100644 --- a/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepository.java +++ b/src/main/java/project/trendpick_pro/domain/product/repository/ProductRepository.java @@ -1,8 +1,10 @@ package project.trendpick_pro.domain.product.repository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.data.jpa.repository.JpaRepository; import project.trendpick_pro.domain.product.entity.Product; public interface ProductRepository extends JpaRepository, ProductRepositoryCustom { - + Page findAll(Pageable pageable); } diff --git a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java index 6e235abc..a87f8cf0 100644 --- a/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java +++ b/src/main/java/project/trendpick_pro/domain/product/service/ProductService.java @@ -47,6 +47,7 @@ import java.io.File; import java.io.IOException; import java.util.*; +import java.util.stream.Collectors; @Slf4j @Service @@ -176,6 +177,12 @@ public Page showAll(int offset, String mainCategory, String return new PageImpl<>(list, pageable, listResponses.getTotalElements()); } + public Page getAllProducts(Pageable pageable) { + pageable = PageRequest.of(pageable.getPageNumber(), 18); + Page products = productRepository.findAll(pageable); + return products.map(this::convertToProductListResponse); + } + public List getRecommendProduct(Member member){ List tags = productRepository.findRecommendProduct(member.getUsername()); @@ -237,4 +244,14 @@ public RsData> findProductsBySeller(Member mem Pageable pageable = PageRequest.of(offset, 20); return RsData.of("S-1", "성공", productRepository.findAllBySeller(member.getBrand(), pageable)); } + + private ProductListResponse convertToProductListResponse(Product product) { + return new ProductListResponse( + product.getId(), + product.getName(), + product.getBrand().getName(), + product.getFile().getFileName(), + product.getPrice() + ); + } } diff --git a/src/main/resources/templates/trendpick/products/list.html b/src/main/resources/templates/trendpick/products/list.html index e4257332..6b9eb284 100644 --- a/src/main/resources/templates/trendpick/products/list.html +++ b/src/main/resources/templates/trendpick/products/list.html @@ -32,22 +32,27 @@ Product Image
    -

    -
    Brand:
    -
    + +

    +
    Brand:
    +
    +
    -
    - Edit - Delete - +
    +
    + Edit +
    +
    + Delete + +
    - View More
    diff --git a/src/main/resources/templates/trendpick/usr/layout/layout.html b/src/main/resources/templates/trendpick/usr/layout/layout.html index ae8c92d4..6b8225d2 100644 --- a/src/main/resources/templates/trendpick/usr/layout/layout.html +++ b/src/main/resources/templates/trendpick/usr/layout/layout.html @@ -46,6 +46,7 @@

    TrendPick

    +
  • 전체
  • 상의
  • 아우터
  • 하의
  • From 1e2f26913f7adcbd7d0dc44b8825cace5012bee8 Mon Sep 17 00:00:00 2001 From: SoohoLee Date: Sun, 11 Jun 2023 16:45:38 +0900 Subject: [PATCH 297/367] =?UTF-8?q?refactor:=20=EC=B6=94=EC=B2=9C=20?= =?UTF-8?q?=EC=B9=B4=ED=85=8C=EA=B3=A0=EB=A6=AC=20=EC=95=88=EB=9C=A8?= =?UTF-8?q?=EB=8A=94=20=EB=AC=B8=EC=A0=9C=20=ED=95=B4=EA=B2=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/product/controller/ProductController.java | 7 ++++--- .../resources/templates/trendpick/usr/layout/layout.html | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java index 91119b77..b72aaa61 100644 --- a/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java +++ b/src/main/java/project/trendpick_pro/domain/product/controller/ProductController.java @@ -138,14 +138,15 @@ public String showProduct(@PathVariable Long productId, Pageable pageable, Produ @PreAuthorize("permitAll()") @GetMapping("/list") public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") int offset, - @RequestParam(value = "main-category") String mainCategory, + @RequestParam(value = "main-category", defaultValue = "top") String mainCategory, @RequestParam(value = "sub-category", defaultValue = "전체") String subCategory, Pageable pageable, Model model) { if (mainCategory.equals("recommend")) { mainCategory = "추천"; } else if (mainCategory.equals("top")) { mainCategory = "상의"; - } if (mainCategory.equals("추천")) { + } + if (mainCategory.equals("추천")) { Member member = rq.CheckLogin().orElseThrow(() -> new MemberNotFoundException("존재하지 않는 회원입니다.")); if (member.getRole().getValue().equals("MEMBER")) { model.addAttribute("mainCategoryName", mainCategory); @@ -156,7 +157,7 @@ public String showAllProduct(@RequestParam(value = "page", defaultValue = "0") i model.addAttribute("productResponses", productService.showAll(offset, mainCategory, subCategory)); model.addAttribute("subCategories", subCategoryService.findAll(mainCategory)); } - } if(mainCategory.equals("전체")){ + } else if(mainCategory.equals("전체")){ model.addAttribute("mainCategoryName", mainCategory); model.addAttribute("productResponses", productService.getAllProducts(pageable)); } else { diff --git a/src/main/resources/templates/trendpick/usr/layout/layout.html b/src/main/resources/templates/trendpick/usr/layout/layout.html index 6b8225d2..be7ee57e 100644 --- a/src/main/resources/templates/trendpick/usr/layout/layout.html +++ b/src/main/resources/templates/trendpick/usr/layout/layout.html @@ -44,7 +44,7 @@

    TrendPick