diff --git a/src/main/generated/kw/zeropick/registration/domain/QRegistration.java b/src/main/generated/kw/zeropick/registration/domain/QRegistration.java new file mode 100644 index 0000000..c8974bb --- /dev/null +++ b/src/main/generated/kw/zeropick/registration/domain/QRegistration.java @@ -0,0 +1,75 @@ +package kw.zeropick.registration.domain; + +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; + + +/** + * QRegistration is a Querydsl query type for Registration + */ +@Generated("com.querydsl.codegen.DefaultEntitySerializer") +public class QRegistration extends EntityPathBase { + + private static final long serialVersionUID = -1263438447L; + + private static final PathInits INITS = PathInits.DIRECT2; + + public static final QRegistration registration = new QRegistration("registration"); + + public final kw.zeropick.common.domain.QBaseEntity _super = new kw.zeropick.common.domain.QBaseEntity(this); + + public final StringPath additional = createString("additional"); + + public final StringPath brand = createString("brand"); + + public final EnumPath category = createEnum("category", kw.zeropick.product.domain.Category.class); + + //inherited + public final DateTimePath createdAt = _super.createdAt; + + public final NumberPath id = createNumber("id", Long.class); + + public final ListPath imageUrls = this.createList("imageUrls", String.class, StringPath.class, PathInits.DIRECT2); + + public final StringPath ingredient = createString("ingredient"); + + public final kw.zeropick.member.domain.QMember member; + + public final StringPath productName = createString("productName"); + + public final EnumPath registrationStatus = createEnum("registrationStatus", RegistrationStatus.class); + + public final StringPath rejectionReason = createString("rejectionReason"); + + //inherited + public final DateTimePath updatedAt = _super.updatedAt; + + public QRegistration(String variable) { + this(Registration.class, forVariable(variable), INITS); + } + + public QRegistration(Path path) { + this(path.getType(), path.getMetadata(), PathInits.getFor(path.getMetadata(), INITS)); + } + + public QRegistration(PathMetadata metadata) { + this(metadata, PathInits.getFor(metadata, INITS)); + } + + public QRegistration(PathMetadata metadata, PathInits inits) { + this(Registration.class, metadata, inits); + } + + public QRegistration(Class type, PathMetadata metadata, PathInits inits) { + super(type, metadata, inits); + this.member = inits.isInitialized("member") ? new kw.zeropick.member.domain.QMember(forProperty("member")) : null; + } + +} + diff --git a/src/main/java/kw/zeropick/ZeropickApplication.java b/src/main/java/kw/zeropick/ZeropickApplication.java index 278715d..7729ca3 100644 --- a/src/main/java/kw/zeropick/ZeropickApplication.java +++ b/src/main/java/kw/zeropick/ZeropickApplication.java @@ -2,8 +2,10 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @SpringBootApplication +@EnableJpaAuditing public class ZeropickApplication { public static void main(String[] args) { diff --git a/src/main/java/kw/zeropick/member/domain/Member.java b/src/main/java/kw/zeropick/member/domain/Member.java index f5f0ead..02fbe04 100644 --- a/src/main/java/kw/zeropick/member/domain/Member.java +++ b/src/main/java/kw/zeropick/member/domain/Member.java @@ -4,9 +4,11 @@ import jakarta.persistence.*; import jakarta.validation.constraints.NotNull; import kw.zeropick.common.converter.StringListToStringConverter; +import kw.zeropick.registration.domain.Registration; import lombok.*; import java.time.LocalDate; +import java.util.ArrayList; import java.util.List; @Entity diff --git a/src/main/java/kw/zeropick/registration/controller/RegistrationController.java b/src/main/java/kw/zeropick/registration/controller/RegistrationController.java new file mode 100644 index 0000000..62b1eb9 --- /dev/null +++ b/src/main/java/kw/zeropick/registration/controller/RegistrationController.java @@ -0,0 +1,61 @@ +package kw.zeropick.registration.controller; + +import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.tags.Tag; +import kw.zeropick.common.LoginUser; +import kw.zeropick.member.domain.Member; +import kw.zeropick.member.service.MemberService; +import kw.zeropick.payload.ApiResponse; +import kw.zeropick.registration.controller.response.RegistrationResponse; +import kw.zeropick.registration.dto.RegistrationRequestDto; +import kw.zeropick.registration.service.RegistrationService; +import kw.zeropick.review.dto.request.ReviewRequestDto; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.multipart.MultipartFile; + +import java.util.List; + +@Tag(name = "registration", description = "상품 등록 요청 API") +@RestController +@RequestMapping("/registration") +@RequiredArgsConstructor +public class RegistrationController { + + private final RegistrationService registrationService; + private final MemberService memberService; + + @PostMapping + @Operation(summary = "제품 등록 요청 생성") + public ResponseEntity registerProduct( + @RequestPart(value = "registration") RegistrationRequestDto requestDto, + @RequestPart(value = "files", required = false) List files) { + + Long memberId = 1L; + Member requestMember = memberService.getById(memberId); + RegistrationResponse response = registrationService.registerProduct(requestMember, requestDto, files); + + return ResponseEntity.ok( + ApiResponse.builder() + .check(true) + .information(response) + .build() + ); + } + + @GetMapping + @Operation(summary = "제품 등록 요청 조회") + public ResponseEntity getAllRegistrations() { + Long memberId = 1L; + Member requestMember = memberService.getById(memberId); + List responseList = registrationService.getAllRegistrations(requestMember); + + return ResponseEntity.ok( + ApiResponse.builder() + .check(true) + .information(responseList) + .build() + ); + } +} diff --git a/src/main/java/kw/zeropick/registration/controller/response/RegistrationResponse.java b/src/main/java/kw/zeropick/registration/controller/response/RegistrationResponse.java new file mode 100644 index 0000000..88981e1 --- /dev/null +++ b/src/main/java/kw/zeropick/registration/controller/response/RegistrationResponse.java @@ -0,0 +1,36 @@ +package kw.zeropick.registration.controller.response; + +import kw.zeropick.registration.domain.Registration; +import kw.zeropick.registration.domain.RegistrationStatus; +import lombok.Getter; + +import java.time.LocalDateTime; +import java.util.ArrayList; +import java.util.List; + +@Getter +public class RegistrationResponse { + private final Long id; + private final String brand; + private final String productName; + private final String category; + private final String ingredient; + private final String additional; + private final RegistrationStatus registrationStatus; + private final String rejectionReason; + private List imageUrls = new ArrayList<>(); + private LocalDateTime createdAt; + + public RegistrationResponse(Registration registration) { + this.id = registration.getId(); + this.brand = registration.getBrand(); + this.productName = registration.getProductName(); + this.category = registration.getCategory().name(); + this.ingredient = registration.getIngredient(); + this.additional = registration.getAdditional(); + this.registrationStatus = registration.getRegistrationStatus(); + this.rejectionReason = registration.getRejectionReason(); + this.imageUrls = registration.getImageUrls(); + this.createdAt = registration.getCreatedAt(); + } +} diff --git a/src/main/java/kw/zeropick/registration/domain/Registration.java b/src/main/java/kw/zeropick/registration/domain/Registration.java new file mode 100644 index 0000000..b29a93e --- /dev/null +++ b/src/main/java/kw/zeropick/registration/domain/Registration.java @@ -0,0 +1,87 @@ +package kw.zeropick.registration.domain; + +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import kw.zeropick.common.converter.StringListToStringConverter; +import kw.zeropick.common.domain.BaseEntity; +import kw.zeropick.member.domain.Member; +import kw.zeropick.product.domain.Category; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@Entity +public class Registration extends BaseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "registration_id") + private Long id; + + @ManyToOne(fetch = FetchType.LAZY)//단방향 연결 + @JoinColumn(name = "member_id", nullable = false) + private Member member; + + @NotNull + private String brand; + + @NotNull + private String productName; + + @NotNull + private Category category; + + private String ingredient; + + @Convert(converter = StringListToStringConverter.class) + private List imageUrls = new ArrayList<>(); + + private String additional; + + private RegistrationStatus registrationStatus; // 등록 요청 처리 상태 + + private String rejectionReason; // 반려 사유 + + public void setId(Long id) { + this.id = id; + } + + public void setBrand(String brand) { + this.brand = brand; + } + + public void setProductName(String productName) { + this.productName = productName; + } + + public void setCategory(Category category) { + this.category = category; + } + + public void setIngredient(String ingredient) { + this.ingredient = ingredient; + } + + public void setImageUrls(List imageUrls) { + this.imageUrls = imageUrls; + } + public void setAdditional(String additional) { + this.additional = additional; + } + + public void setRegistrationStatus(RegistrationStatus registrationStatus) { + this.registrationStatus = registrationStatus; + } + + public void setRejectionReason(String rejectionReason) { + this.rejectionReason = rejectionReason; + } +} diff --git a/src/main/java/kw/zeropick/registration/domain/RegistrationStatus.java b/src/main/java/kw/zeropick/registration/domain/RegistrationStatus.java new file mode 100644 index 0000000..d9639ee --- /dev/null +++ b/src/main/java/kw/zeropick/registration/domain/RegistrationStatus.java @@ -0,0 +1,7 @@ +package kw.zeropick.registration.domain; + +public enum RegistrationStatus { + PENDING, // 대기중 + REJECTED, // 반려 + COMPLETED // 등록 완료 +} diff --git a/src/main/java/kw/zeropick/registration/dto/RegistrationRequestDto.java b/src/main/java/kw/zeropick/registration/dto/RegistrationRequestDto.java new file mode 100644 index 0000000..24540b0 --- /dev/null +++ b/src/main/java/kw/zeropick/registration/dto/RegistrationRequestDto.java @@ -0,0 +1,29 @@ +package kw.zeropick.registration.dto; + +import jakarta.validation.constraints.NotNull; +import kw.zeropick.product.domain.Category; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@Builder +@NoArgsConstructor +public class RegistrationRequestDto { + @NotNull + private String brand; + @NotNull + private String productName; + @NotNull + private Category category; + private String ingredient; + private String additional; + + public RegistrationRequestDto(String brand, String productName, Category category, String ingredient, String additional) { + this.brand = brand; + this.productName = productName; + this.category = category; + this.ingredient = ingredient; + this.additional = additional; + } +} diff --git a/src/main/java/kw/zeropick/registration/repository/RegistrationRepository.java b/src/main/java/kw/zeropick/registration/repository/RegistrationRepository.java new file mode 100644 index 0000000..bdbfc57 --- /dev/null +++ b/src/main/java/kw/zeropick/registration/repository/RegistrationRepository.java @@ -0,0 +1,11 @@ +package kw.zeropick.registration.repository; + +import kw.zeropick.member.domain.Member; +import kw.zeropick.registration.domain.Registration; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface RegistrationRepository extends JpaRepository { + List findByMember(Member member); +} diff --git a/src/main/java/kw/zeropick/registration/service/RegistrationService.java b/src/main/java/kw/zeropick/registration/service/RegistrationService.java new file mode 100644 index 0000000..193c33c --- /dev/null +++ b/src/main/java/kw/zeropick/registration/service/RegistrationService.java @@ -0,0 +1,67 @@ +package kw.zeropick.registration.service; + +import kw.zeropick.member.domain.Member; +import kw.zeropick.product.domain.Category; +import kw.zeropick.registration.controller.response.RegistrationResponse; +import kw.zeropick.registration.domain.Registration; +import kw.zeropick.registration.domain.RegistrationStatus; +import kw.zeropick.registration.dto.RegistrationRequestDto; +import kw.zeropick.registration.repository.RegistrationRepository; +import kw.zeropick.util.S3Util; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@Service +@RequiredArgsConstructor +public class RegistrationService { + + private final RegistrationRepository registrationRepository; + + private final S3Util s3Util; + @Transactional + public RegistrationResponse registerProduct(Member member, RegistrationRequestDto requestDto, List files) { + + List images = new ArrayList<>(); + + // 이미지 파일 처리 및 S3 업로드 + if (files != null && !files.isEmpty()) { + for (MultipartFile file : files) { + if (file != null && !file.isEmpty()) { + String imageUrl = s3Util.upload(file); + System.out.println(imageUrl); + images.add(imageUrl); + } + } + } + + Registration registration = Registration.builder() + .member(member) + .brand(requestDto.getBrand()) + .productName(requestDto.getProductName()) + .category(requestDto.getCategory()) + .ingredient(requestDto.getIngredient()) + .additional(requestDto.getAdditional()) + .registrationStatus(RegistrationStatus.PENDING) + .imageUrls(images) + .build(); + + Registration savedRegistration = registrationRepository.save(registration); + + return new RegistrationResponse(savedRegistration); + } + + @Transactional(readOnly = true) + public List getAllRegistrations(Member member) { + List registrations = registrationRepository.findByMember(member); + return registrations.stream() + .map(RegistrationResponse::new) + .collect(Collectors.toList()); + } + +}