From 3774b6e5c4ca89bc540b6f8e00b403ab9e258aba Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Fri, 22 Nov 2024 21:56:30 +0900 Subject: [PATCH 01/17] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor[#25]:=20?= =?UTF-8?q?=EB=8F=84=EC=8B=9C=EB=AA=85=EC=9C=BC=EB=A1=9C=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 --- .../groom/swipo/global/common/enums/Area.java | 45 ++++++++++--------- 1 file changed, 25 insertions(+), 20 deletions(-) diff --git a/src/main/java/com/groom/swipo/global/common/enums/Area.java b/src/main/java/com/groom/swipo/global/common/enums/Area.java index 6f518f0..0e1afa5 100644 --- a/src/main/java/com/groom/swipo/global/common/enums/Area.java +++ b/src/main/java/com/groom/swipo/global/common/enums/Area.java @@ -1,32 +1,37 @@ package com.groom.swipo.global.common.enums; public enum Area { - CODE_02("02"), // 서울 - CODE_05("05"), // 경남 - CODE_031("031"), // 경기도 - CODE_032("032"), // 인천 - CODE_033("033"), // 강원 - CODE_041("041"), // 충남 - CODE_042("042"), // 대전 - CODE_043("043"), // 충북 - CODE_044("044"), // 세종 - CODE_051("051"), // 부산 - CODE_052("052"), // 울산 - CODE_053("053"), // 대구 - CODE_054("054"), // 경북 - CODE_061("061"), // 전남 - CODE_062("062"), // 광주 - CODE_063("063"), // 전북 - CODE_064("064"); // 제주 - + CODE_02("02", "서울"), + CODE_031("031", "경기도"), + CODE_032("032", "인천"), + CODE_033("033", "강원"), + CODE_041("041", "충남"), + CODE_042("042", "대전"), + CODE_043("043", "충북"), + CODE_044("044", "세종"), + CODE_051("051", "부산"), + CODE_052("052", "울산"), + CODE_053("053", "대구"), + CODE_054("054", "경북"), + CODE_055("055", "경남"), + CODE_061("061", "전남"), + CODE_062("062", "광주"), + CODE_063("063", "전북"), + CODE_064("064", "제주"); private final String code; + private final String regionName; // 지역명 추가 - Area(String code) { + Area(String code, String regionName) { this.code = code; + this.regionName = regionName; } public String getCode() { return code; } -} \ No newline at end of file + + public String getRegionName() { // 지역명을 반환하는 메서드 + return regionName; + } +} From 33f238e94762a293a9c569d1de21a2edf94ec7b4 Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Fri, 22 Nov 2024 22:01:03 +0900 Subject: [PATCH 02/17] =?UTF-8?q?=E2=9C=A8=20=EC=8A=A4=EC=9C=95=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=20=ED=99=88=20Dto=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../swipo/domain/payment/dto/PaylistInfo.java | 25 ++++++++++++++++++ .../swipo/domain/point/dto/CardInfo.java | 22 ++++++++++++++++ .../point/dto/Response/PointHomeResponse.java | 26 +++++++++++++++++++ 3 files changed, 73 insertions(+) create mode 100644 src/main/java/com/groom/swipo/domain/payment/dto/PaylistInfo.java create mode 100644 src/main/java/com/groom/swipo/domain/point/dto/CardInfo.java create mode 100644 src/main/java/com/groom/swipo/domain/point/dto/Response/PointHomeResponse.java diff --git a/src/main/java/com/groom/swipo/domain/payment/dto/PaylistInfo.java b/src/main/java/com/groom/swipo/domain/payment/dto/PaylistInfo.java new file mode 100644 index 0000000..28aa915 --- /dev/null +++ b/src/main/java/com/groom/swipo/domain/payment/dto/PaylistInfo.java @@ -0,0 +1,25 @@ +package com.groom.swipo.domain.payment.dto; + +import java.time.LocalDateTime; + +import com.groom.swipo.domain.payment.entity.Paylist; +import com.groom.swipo.domain.store.entity.Store; + +import lombok.Builder; + +@Builder +public record PaylistInfo( + String paylistId, + Integer amount, + String storeName, + LocalDateTime createAt +) { + public static PaylistInfo of(Paylist paylist, Store store){ + return PaylistInfo.builder() + .paylistId(String.valueOf(paylist.getId())) + .amount((int)paylist.getValue()) + .amount(Integer.valueOf(store.getName())) + .createAt(paylist.getCreatedAt()) + .build(); + } +} diff --git a/src/main/java/com/groom/swipo/domain/point/dto/CardInfo.java b/src/main/java/com/groom/swipo/domain/point/dto/CardInfo.java new file mode 100644 index 0000000..7ed37fa --- /dev/null +++ b/src/main/java/com/groom/swipo/domain/point/dto/CardInfo.java @@ -0,0 +1,22 @@ +package com.groom.swipo.domain.point.dto; + +import com.groom.swipo.domain.point.entity.Card; + +import lombok.Builder; + +@Builder +public record CardInfo( + String cardId, + String region, + Integer point, + String customImage +) { + public static CardInfo of(Card card) { + return CardInfo.builder() + .cardId(String.valueOf(card.getId())) + .region(card.getArea().getRegionName()) + .point(card.getTotalPoint()) + .customImage(card.getCustomeImage()) + .build(); + } +} diff --git a/src/main/java/com/groom/swipo/domain/point/dto/Response/PointHomeResponse.java b/src/main/java/com/groom/swipo/domain/point/dto/Response/PointHomeResponse.java new file mode 100644 index 0000000..a0fc12e --- /dev/null +++ b/src/main/java/com/groom/swipo/domain/point/dto/Response/PointHomeResponse.java @@ -0,0 +1,26 @@ +package com.groom.swipo.domain.point.dto.Response; + +import java.util.List; + +import com.groom.swipo.domain.payment.dto.PaylistInfo; +import com.groom.swipo.domain.payment.entity.Pay; +import com.groom.swipo.domain.point.dto.CardInfo; + +import lombok.Builder; + +@Builder +public record PointHomeResponse( + Integer balance, // 페이잔액 + Integer totalCards, //사용자가 보유한 모든 지역 카드 수 + List cards, + List paylistInfos +) { + public static PointHomeResponse of(Pay pay, Integer totalCards, List cards, List paylistInfos){ + return PointHomeResponse.builder() + .balance(pay.getTotalPay()) + .totalCards(totalCards) + .cards(cards) + .paylistInfos(paylistInfos) + .build(); + } +} From f2d67486ff6219db15b6c03427016db4a3ab5aed Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Fri, 22 Nov 2024 22:02:22 +0900 Subject: [PATCH 03/17] =?UTF-8?q?=E2=9C=A8=20Feat[#25]:=20=ED=8E=98?= =?UTF-8?q?=EC=9D=B4=20=EC=97=90=EB=9F=AC=20=ED=95=B8=EB=93=A4=EB=A7=81=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 --- .../payment/exception/PayNotFoundException.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/main/java/com/groom/swipo/domain/payment/exception/PayNotFoundException.java diff --git a/src/main/java/com/groom/swipo/domain/payment/exception/PayNotFoundException.java b/src/main/java/com/groom/swipo/domain/payment/exception/PayNotFoundException.java new file mode 100644 index 0000000..f202a05 --- /dev/null +++ b/src/main/java/com/groom/swipo/domain/payment/exception/PayNotFoundException.java @@ -0,0 +1,13 @@ +package com.groom.swipo.domain.payment.exception; + +import com.groom.swipo.global.error.exception.NotFoundGroupException; + +public class PayNotFoundException extends NotFoundGroupException { + public PayNotFoundException(String message) { + super(message); + } + + public PayNotFoundException() { + super("Pay not found for user."); + } +} From 068ce96f737a0f99014f8ccf3b906bbe55b07d6b Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Fri, 22 Nov 2024 22:03:33 +0900 Subject: [PATCH 04/17] =?UTF-8?q?=E2=9C=A8=20Feat[#25]:=20=EC=8A=A4?= =?UTF-8?q?=EC=9C=95=ED=8E=98=EC=9D=B4=20=ED=99=88=20API=EB=A5=BC=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20Repository=20=EC=84=A4=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../groom/swipo/domain/payment/repository/PayRepository.java | 4 ++++ .../swipo/domain/payment/repository/PaylistRepository.java | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/src/main/java/com/groom/swipo/domain/payment/repository/PayRepository.java b/src/main/java/com/groom/swipo/domain/payment/repository/PayRepository.java index ad55f2e..4baa244 100644 --- a/src/main/java/com/groom/swipo/domain/payment/repository/PayRepository.java +++ b/src/main/java/com/groom/swipo/domain/payment/repository/PayRepository.java @@ -1,10 +1,14 @@ package com.groom.swipo.domain.payment.repository; +import java.util.Optional; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import com.groom.swipo.domain.payment.entity.Pay; +import com.groom.swipo.domain.user.entity.User; @Repository public interface PayRepository extends JpaRepository { + Optional findByUser(User user); } diff --git a/src/main/java/com/groom/swipo/domain/payment/repository/PaylistRepository.java b/src/main/java/com/groom/swipo/domain/payment/repository/PaylistRepository.java index bacd003..92e0d97 100644 --- a/src/main/java/com/groom/swipo/domain/payment/repository/PaylistRepository.java +++ b/src/main/java/com/groom/swipo/domain/payment/repository/PaylistRepository.java @@ -1,10 +1,14 @@ package com.groom.swipo.domain.payment.repository; +import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import com.groom.swipo.domain.payment.entity.Pay; import com.groom.swipo.domain.payment.entity.Paylist; @Repository public interface PaylistRepository extends JpaRepository { + List findTop5ByPayOrderByCreatedAtDesc(Pay pay); } From ac1cbd358f255554cc121ddda238d2441966f7bd Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Fri, 22 Nov 2024 22:04:38 +0900 Subject: [PATCH 05/17] =?UTF-8?q?=E2=9C=A8=20Feat[#25]:=20=EC=8A=A4?= =?UTF-8?q?=EC=9C=95=ED=8E=98=EC=9D=B4=20=ED=99=88=20API=EB=A5=BC=20?= =?UTF-8?q?=EC=9C=84=ED=95=9C=20Repository=20=EC=84=A4=EC=A0=95=20-=202?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../groom/swipo/domain/point/repository/CardRepository.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/java/com/groom/swipo/domain/point/repository/CardRepository.java b/src/main/java/com/groom/swipo/domain/point/repository/CardRepository.java index 7b22aba..f6ec06b 100644 --- a/src/main/java/com/groom/swipo/domain/point/repository/CardRepository.java +++ b/src/main/java/com/groom/swipo/domain/point/repository/CardRepository.java @@ -1,10 +1,14 @@ package com.groom.swipo.domain.point.repository; +import java.util.List; + import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import com.groom.swipo.domain.point.entity.Card; +import com.groom.swipo.domain.user.entity.User; @Repository public interface CardRepository extends JpaRepository { + List findAllByUser(User user); } From fe28c576d2d38ebc266516fd8df9494b0a7ba495 Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Fri, 22 Nov 2024 22:05:01 +0900 Subject: [PATCH 06/17] =?UTF-8?q?=E2=9C=A8=20Feat[#25]:=20=EC=8A=A4?= =?UTF-8?q?=EC=9C=95=ED=8E=98=EC=9D=B4=20=ED=99=88=20API=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../point/controller/PointController.java | 19 +++++++++++ .../domain/point/service/PointService.java | 32 +++++++++++++++++++ 2 files changed, 51 insertions(+) diff --git a/src/main/java/com/groom/swipo/domain/point/controller/PointController.java b/src/main/java/com/groom/swipo/domain/point/controller/PointController.java index 869e35b..94ced42 100644 --- a/src/main/java/com/groom/swipo/domain/point/controller/PointController.java +++ b/src/main/java/com/groom/swipo/domain/point/controller/PointController.java @@ -10,6 +10,7 @@ import org.springframework.web.bind.annotation.RestController; import com.groom.swipo.domain.point.dto.Request.SwipstoneSwapRequest; +import com.groom.swipo.domain.point.dto.Response.PointHomeResponse; import com.groom.swipo.domain.point.dto.Response.SwipstoneResponse; import com.groom.swipo.domain.point.dto.Response.SwipstoneSwapResponse; import com.groom.swipo.domain.point.service.PointService; @@ -27,6 +28,24 @@ public class PointController { private final PointService pointService; + @GetMapping("/home") + @Operation( + summary = "스윕페이/포인트 홈 조회", + description = "상단 스웹페이 탭 클릭시 조회되는 정보 제공", + security = {}, + responses = { + @ApiResponse(responseCode = "200", description = "조회 성공"), + @ApiResponse(responseCode = "400", description = "잘못된 요청"), + @ApiResponse(responseCode = "401", description = "인증되지 않은 요청"), + @ApiResponse(responseCode = "500", description = "서버 오류") + } + ) + public ResTemplate getHome(Principal principal) { + PointHomeResponse data = pointService.getHome(principal); + return new ResTemplate<>(HttpStatus.OK, "조회 성공", data); + } + + @GetMapping("/swipstone") @Operation( summary = "스윕스톤 조회", diff --git a/src/main/java/com/groom/swipo/domain/point/service/PointService.java b/src/main/java/com/groom/swipo/domain/point/service/PointService.java index 162ddcb..03f2a8a 100644 --- a/src/main/java/com/groom/swipo/domain/point/service/PointService.java +++ b/src/main/java/com/groom/swipo/domain/point/service/PointService.java @@ -6,17 +6,25 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import com.groom.swipo.domain.payment.dto.PaylistInfo; import com.groom.swipo.domain.payment.entity.Pay; +import com.groom.swipo.domain.payment.entity.Paylist; import com.groom.swipo.domain.payment.repository.PayRepository; +import com.groom.swipo.domain.payment.repository.PaylistRepository; import com.groom.swipo.domain.point.dto.PieceInfo; import com.groom.swipo.domain.point.dto.Request.SwipstoneSwapRequest; +import com.groom.swipo.domain.point.dto.Response.PointHomeResponse; import com.groom.swipo.domain.point.dto.Response.SwipstoneResponse; import com.groom.swipo.domain.point.dto.Response.SwipstoneSwapResponse; +import com.groom.swipo.domain.point.entity.Card; import com.groom.swipo.domain.point.entity.MyPiece; import com.groom.swipo.domain.point.exception.PiecesNotFoundException; +import com.groom.swipo.domain.point.repository.CardRepository; import com.groom.swipo.domain.point.repository.MyPieceRepository; +import com.groom.swipo.domain.point.dto.CardInfo; import com.groom.swipo.domain.user.entity.User; import com.groom.swipo.domain.user.exception.UserNotFoundException; +import com.groom.swipo.domain.payment.exception.PayNotFoundException; import com.groom.swipo.domain.user.repository.UserRepository; import lombok.RequiredArgsConstructor; @@ -28,6 +36,30 @@ public class PointService { private final UserRepository userRepository; private final MyPieceRepository myPieceRepository; private final PayRepository payRepository; + private final CardRepository cardRepository; + private final PaylistRepository paylistRepository; + + public PointHomeResponse getHome(Principal principal) { + Long userId = Long.parseLong(principal.getName()); + User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); + + // 사용자 Pay 정보 조회 + Pay pay = payRepository.findByUser(user).orElseThrow(PayNotFoundException::new); + + // 사용자 카드 정보 조회 + List cards = cardRepository.findAllByUser(user); + List cardInfos = cards.stream() + .map(CardInfo::of) + .toList(); + + // 최근 페이 거래 내역 조회 (최대 5개) + List recentPaylists = paylistRepository.findTop5ByPayOrderByCreatedAtDesc(pay); + List paylistInfos = recentPaylists.stream() + .map(paylist -> PaylistInfo.of(paylist, paylist.getStore())) + .toList(); + + return PointHomeResponse.of(pay, cardInfos.size(), cardInfos, paylistInfos); + } public SwipstoneResponse getSwipstone(Principal principal) { Long userId = Long.parseLong(principal.getName()); From df232373e85bb37a92e9608be028d1e1220c40c0 Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Fri, 22 Nov 2024 23:02:29 +0900 Subject: [PATCH 07/17] =?UTF-8?q?=E2=9E=95=20Add[#25]:=20cloud-starter-aws?= =?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 --- build.gradle | 3 +++ 1 file changed, 3 insertions(+) diff --git a/build.gradle b/build.gradle index 88f7b9d..62b51a3 100644 --- a/build.gradle +++ b/build.gradle @@ -51,6 +51,9 @@ dependencies { // 휴대폰 인증 API (nurigo) implementation 'net.nurigo:sdk:4.3.0' + + // S3 + implementation 'io.awspring.cloud:spring-cloud-starter-aws:2.4.4' } // iamport From cf657658039064d3a21fcd529a0b1058d712462f Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Sat, 23 Nov 2024 00:51:26 +0900 Subject: [PATCH 08/17] =?UTF-8?q?=E2=9C=A8=20Feat[#25]:=20S3=20yml=20?= =?UTF-8?q?=EC=84=B8=ED=8C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/resources/application.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index b91b737..d5de416 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -56,3 +56,15 @@ sms: app: local-url: ${app.local-url} prod-url: ${app.prod-url} + +cloud: + aws: + credentials: + accessKey: ${cloud.aws.credentials.accessKey} + secretKey: ${cloud.aws.credentials.secretKey} + region: + static: ${cloud.aws.region.static} + stack: + auto: false + s3: + bucket: ${cloud.s3.bucket} \ No newline at end of file From 3c15e3313dfaf0b214b0bd614fc96a25f9db2d17 Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Sat, 23 Nov 2024 00:53:00 +0900 Subject: [PATCH 09/17] =?UTF-8?q?=E2=9C=A8=20Feat[#25]:=20S3=20Config,=20S?= =?UTF-8?q?ervice=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../swipo/domain/auth/service/S3Service.java | 48 +++++++++++++++++++ .../swipo/global/config/S3ClientConfig.java | 32 +++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 src/main/java/com/groom/swipo/domain/auth/service/S3Service.java create mode 100644 src/main/java/com/groom/swipo/global/config/S3ClientConfig.java diff --git a/src/main/java/com/groom/swipo/domain/auth/service/S3Service.java b/src/main/java/com/groom/swipo/domain/auth/service/S3Service.java new file mode 100644 index 0000000..f4e8801 --- /dev/null +++ b/src/main/java/com/groom/swipo/domain/auth/service/S3Service.java @@ -0,0 +1,48 @@ +package com.groom.swipo.domain.auth.service; + +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.model.CannedAccessControlList; +import com.amazonaws.services.s3.model.PutObjectRequest; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.io.InputStream; +import java.util.UUID; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.model.ObjectMetadata; +import com.amazonaws.services.s3.model.PutObjectRequest; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Service; +import org.springframework.web.multipart.MultipartFile; + +import java.io.IOException; +import java.io.InputStream; +import java.util.UUID; + +@Service +public class S3Service { + + private final AmazonS3 amazonS3; + + @Value("${cloud.s3.bucket}") + private String bucketName; + + public S3Service(AmazonS3 amazonS3) { + this.amazonS3 = amazonS3; + } + + public String uploadImage(MultipartFile image) { + String fileName = UUID.randomUUID().toString() + "-" + image.getOriginalFilename(); + try (InputStream inputStream = image.getInputStream()) { + ObjectMetadata metadata = new ObjectMetadata(); // 콘텐츠 길이 지정 + metadata.setContentLength(image.getSize()); + + amazonS3.putObject(new PutObjectRequest(bucketName, fileName, inputStream, metadata)); + return amazonS3.getUrl(bucketName, fileName).toString(); + } catch (IOException e) { + throw new RuntimeException("이미지 업로드 중 오류가 발생했습니다.", e); + } + } +} diff --git a/src/main/java/com/groom/swipo/global/config/S3ClientConfig.java b/src/main/java/com/groom/swipo/global/config/S3ClientConfig.java new file mode 100644 index 0000000..3fe6dc3 --- /dev/null +++ b/src/main/java/com/groom/swipo/global/config/S3ClientConfig.java @@ -0,0 +1,32 @@ +package com.groom.swipo.global.config; + +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +import com.amazonaws.auth.AWSStaticCredentialsProvider; +import com.amazonaws.auth.BasicAWSCredentials; +import com.amazonaws.services.s3.AmazonS3; +import com.amazonaws.services.s3.AmazonS3ClientBuilder; + +@Configuration +public class S3ClientConfig { + + @Value("${cloud.aws.credentials.access-key}") + private String accessKey; + + @Value("${cloud.aws.credentials.secret-key}") + private String secretKey; + + @Value("${cloud.aws.region.static}") + private String region; + + @Bean + public AmazonS3 amazonS3() { + BasicAWSCredentials awsCredentials = new BasicAWSCredentials(accessKey, secretKey); + return AmazonS3ClientBuilder.standard() + .withRegion(region) + .withCredentials(new AWSStaticCredentialsProvider(awsCredentials)) + .build(); + } +} \ No newline at end of file From c02f1842e505e7c56f00f832dc23b2fb9ae39e80 Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Sat, 23 Nov 2024 00:54:49 +0900 Subject: [PATCH 10/17] =?UTF-8?q?=E2=99=BB=EF=B8=8F=20Refactor[#25]:=20num?= =?UTF-8?q?ber=20=EC=A0=9C=EA=B1=B0=20=EB=B0=8F=20=EC=98=A4=ED=83=80=20?= =?UTF-8?q?=EC=88=98=EC=A0=95,=20builder=20=EC=B5=9C=EC=A0=81=ED=99=94?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../groom/swipo/domain/point/entity/Card.java | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/src/main/java/com/groom/swipo/domain/point/entity/Card.java b/src/main/java/com/groom/swipo/domain/point/entity/Card.java index 7468f4c..5c0d627 100644 --- a/src/main/java/com/groom/swipo/domain/point/entity/Card.java +++ b/src/main/java/com/groom/swipo/domain/point/entity/Card.java @@ -35,17 +35,14 @@ public class Card extends BaseEntity { @Column(name = "card_id") private Long id; - @Column(nullable = false) - private String number; - private String contents; @Column(nullable = false) @ColumnDefault("0") - private Integer totalPoint; + private Integer totalPoint = 0; @Column(nullable = false) - private String customeImage; + private String customImage; @Enumerated(EnumType.STRING) @Column(nullable = false) @@ -61,11 +58,11 @@ public class Card extends BaseEntity { private List cardlists = new ArrayList<>(); @Builder - private Card(String number, String contents, Integer totalPoint, String customeImage, Area area) { - this.number = number; - this.contents = contents; - this.totalPoint = totalPoint; - this.customeImage = customeImage; + private Card(User user, String customImage, Area area) { + this.user = user; + this.contents = ""; + this.totalPoint = 0; // 생성자에서 명시적으로 기본값 설정 + this.customImage = customImage; this.area = area; } From b0b800582f1ef53b3301c4a49e48ae0efe562760 Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Sat, 23 Nov 2024 00:56:57 +0900 Subject: [PATCH 11/17] =?UTF-8?q?=F0=9F=8E=A8=20Style[#25]:=20=EC=98=A4?= =?UTF-8?q?=ED=83=80=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/java/com/groom/swipo/domain/point/dto/CardInfo.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/com/groom/swipo/domain/point/dto/CardInfo.java b/src/main/java/com/groom/swipo/domain/point/dto/CardInfo.java index 7ed37fa..fee2e9b 100644 --- a/src/main/java/com/groom/swipo/domain/point/dto/CardInfo.java +++ b/src/main/java/com/groom/swipo/domain/point/dto/CardInfo.java @@ -16,7 +16,7 @@ public static CardInfo of(Card card) { .cardId(String.valueOf(card.getId())) .region(card.getArea().getRegionName()) .point(card.getTotalPoint()) - .customImage(card.getCustomeImage()) + .customImage(card.getCustomImage()) .build(); } } From 05c2089a12ef0af7108cd4391c700e090e1f0fb4 Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Sat, 23 Nov 2024 00:58:16 +0900 Subject: [PATCH 12/17] =?UTF-8?q?=E2=9C=A8=20Feat[#25]:=20InvalidRegionExc?= =?UTF-8?q?eption=20=EC=98=88=EC=99=B8=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../point/exception/DuplicateCardException.java | 12 ++++++++++++ .../point/exception/InvalidRegionException.java | 13 +++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/main/java/com/groom/swipo/domain/point/exception/DuplicateCardException.java create mode 100644 src/main/java/com/groom/swipo/domain/point/exception/InvalidRegionException.java diff --git a/src/main/java/com/groom/swipo/domain/point/exception/DuplicateCardException.java b/src/main/java/com/groom/swipo/domain/point/exception/DuplicateCardException.java new file mode 100644 index 0000000..81babf7 --- /dev/null +++ b/src/main/java/com/groom/swipo/domain/point/exception/DuplicateCardException.java @@ -0,0 +1,12 @@ +package com.groom.swipo.domain.point.exception; + +import com.groom.swipo.global.error.exception.ConflictGroupException; + +public class DuplicateCardException extends ConflictGroupException { + public DuplicateCardException(String message) { + super(message); + } + public DuplicateCardException(){ + this("이미 해당 지역카드가 존재합니다."); + } +} diff --git a/src/main/java/com/groom/swipo/domain/point/exception/InvalidRegionException.java b/src/main/java/com/groom/swipo/domain/point/exception/InvalidRegionException.java new file mode 100644 index 0000000..32d29ce --- /dev/null +++ b/src/main/java/com/groom/swipo/domain/point/exception/InvalidRegionException.java @@ -0,0 +1,13 @@ +package com.groom.swipo.domain.point.exception; + +import com.groom.swipo.global.error.exception.InvalidGroupException; + +public class InvalidRegionException extends InvalidGroupException { + + public InvalidRegionException(String message) { + super(message); + } + public InvalidRegionException(){ + this("지역명을 잘못 작성하였거나 유효하지 않는 지역입니다."); + } +} From 92a95b8c35d54e917af79d3c0000b98da9628d8e Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Sat, 23 Nov 2024 00:58:50 +0900 Subject: [PATCH 13/17] =?UTF-8?q?=E2=9C=A8=20Feat[#25]:=20=EC=A7=80?= =?UTF-8?q?=EC=97=AD=20=EA=B2=80=EC=A6=9D=20=EC=BD=94=EB=93=9C=20=EB=B0=8F?= =?UTF-8?q?=20=EC=98=88=EC=99=B8=EC=B2=98=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 --- .../groom/swipo/global/common/enums/Area.java | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/groom/swipo/global/common/enums/Area.java b/src/main/java/com/groom/swipo/global/common/enums/Area.java index 0e1afa5..d241ade 100644 --- a/src/main/java/com/groom/swipo/global/common/enums/Area.java +++ b/src/main/java/com/groom/swipo/global/common/enums/Area.java @@ -1,5 +1,8 @@ package com.groom.swipo.global.common.enums; +import java.util.Arrays; +import com.groom.swipo.domain.point.exception.InvalidRegionException; + public enum Area { CODE_02("02", "서울"), CODE_031("031", "경기도"), @@ -20,7 +23,7 @@ public enum Area { CODE_064("064", "제주"); private final String code; - private final String regionName; // 지역명 추가 + private final String regionName; Area(String code, String regionName) { this.code = code; @@ -31,7 +34,15 @@ public String getCode() { return code; } - public String getRegionName() { // 지역명을 반환하는 메서드 + public String getRegionName() { return regionName; } -} + + // 지역명을 기준으로 Area 반환 + public static Area fromRegionName(String regionName) { + return Arrays.stream(values()) + .filter(area -> area.getRegionName().equals(regionName)) + .findFirst() + .orElseThrow(InvalidRegionException::new); // 여기서 에러 핸들링하는게 맞겠죠..? 클린하겠죠? ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ + } +} \ No newline at end of file From d0588a5a26b3c83520f00429a7dd1595571eb0c0 Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Sat, 23 Nov 2024 00:59:52 +0900 Subject: [PATCH 14/17] =?UTF-8?q?=E2=9C=A8=20Feat[#25]:=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C=20=EC=9C=A0=EB=AC=B4=20=EC=97=AC=EB=B6=80=20=ED=99=95?= =?UTF-8?q?=EC=9D=B8=20=EC=BD=94=EB=93=9C=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/groom/swipo/domain/point/repository/CardRepository.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/com/groom/swipo/domain/point/repository/CardRepository.java b/src/main/java/com/groom/swipo/domain/point/repository/CardRepository.java index f6ec06b..3467405 100644 --- a/src/main/java/com/groom/swipo/domain/point/repository/CardRepository.java +++ b/src/main/java/com/groom/swipo/domain/point/repository/CardRepository.java @@ -7,8 +7,10 @@ import com.groom.swipo.domain.point.entity.Card; import com.groom.swipo.domain.user.entity.User; +import com.groom.swipo.global.common.enums.Area; @Repository public interface CardRepository extends JpaRepository { List findAllByUser(User user); + boolean existsByUserAndArea(User user, Area area); } From ddf4dc0be06e2a5e2914b5af709680d14fea8d0b Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Sat, 23 Nov 2024 01:00:38 +0900 Subject: [PATCH 15/17] =?UTF-8?q?=E2=9C=A8=20Feat[#25]:=20=EC=B9=B4?= =?UTF-8?q?=EB=93=9C=20=EB=93=B1=EB=A1=9D=20API=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../point/controller/PointController.java | 25 ++++++++++++++ .../domain/point/service/PointService.java | 33 +++++++++++++++++++ 2 files changed, 58 insertions(+) diff --git a/src/main/java/com/groom/swipo/domain/point/controller/PointController.java b/src/main/java/com/groom/swipo/domain/point/controller/PointController.java index 94ced42..2a3b3b7 100644 --- a/src/main/java/com/groom/swipo/domain/point/controller/PointController.java +++ b/src/main/java/com/groom/swipo/domain/point/controller/PointController.java @@ -7,7 +7,9 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestPart; import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.multipart.MultipartFile; import com.groom.swipo.domain.point.dto.Request.SwipstoneSwapRequest; import com.groom.swipo.domain.point.dto.Response.PointHomeResponse; @@ -45,6 +47,29 @@ public ResTemplate getHome(Principal principal) { return new ResTemplate<>(HttpStatus.OK, "조회 성공", data); } + @PostMapping("/card-register") + @Operation( + summary = "포인트 카드 등록", + description = "지역 정보와 이미지 파일을 사용하여 포인트 카드를 등록합니다.", + security = {}, + responses = { + @ApiResponse(responseCode = "201", description = "카드 등록 성공"), + @ApiResponse(responseCode = "400", description = "잘못된 요청"), + @ApiResponse(responseCode = "401", description = "유효하지 않은 인증 토큰"), + @ApiResponse(responseCode = "403", description = "동네 인증이 안된 경우"), + @ApiResponse(responseCode = "409", description = "중복 카드 등록"), + @ApiResponse(responseCode = "500", description = "서버 오류") + } + ) + public ResTemplate registerCard( + @RequestPart("region") String region, + @RequestPart(value = "custom_image", required = false) MultipartFile customImage, + Principal principal) { + + pointService.registerCard(region, customImage, principal); + return new ResTemplate<>(HttpStatus.CREATED, "카드 등록 성공"); + } + @GetMapping("/swipstone") @Operation( diff --git a/src/main/java/com/groom/swipo/domain/point/service/PointService.java b/src/main/java/com/groom/swipo/domain/point/service/PointService.java index e27c9f9..64f5373 100644 --- a/src/main/java/com/groom/swipo/domain/point/service/PointService.java +++ b/src/main/java/com/groom/swipo/domain/point/service/PointService.java @@ -5,7 +5,9 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +import org.springframework.web.multipart.MultipartFile; +import com.groom.swipo.domain.auth.service.S3Service; import com.groom.swipo.domain.payment.dto.PaylistInfo; import com.groom.swipo.domain.payment.entity.Pay; import com.groom.swipo.domain.payment.entity.Paylist; @@ -18,6 +20,7 @@ import com.groom.swipo.domain.point.dto.Response.SwipstoneSwapResponse; import com.groom.swipo.domain.point.entity.Card; import com.groom.swipo.domain.point.entity.MyPiece; +import com.groom.swipo.domain.point.exception.DuplicateCardException; import com.groom.swipo.domain.point.exception.PiecesNotFoundException; import com.groom.swipo.domain.point.repository.CardRepository; import com.groom.swipo.domain.point.repository.MyPieceRepository; @@ -26,6 +29,7 @@ import com.groom.swipo.domain.user.exception.UserNotFoundException; import com.groom.swipo.domain.payment.exception.PayNotFoundException; import com.groom.swipo.domain.user.repository.UserRepository; +import com.groom.swipo.global.common.enums.Area; import lombok.RequiredArgsConstructor; @@ -38,6 +42,7 @@ public class PointService { private final PayRepository payRepository; private final CardRepository cardRepository; private final PaylistRepository paylistRepository; + private final S3Service s3Service; public PointHomeResponse getHome(Principal principal) { Long userId = Long.parseLong(principal.getName()); @@ -61,6 +66,34 @@ public PointHomeResponse getHome(Principal principal) { return PointHomeResponse.of(pay, cardInfos.size(), cardInfos, paylistInfos); } + @Transactional + public void registerCard(String region, MultipartFile customImage, Principal principal) { + Long userId = Long.parseLong(principal.getName()); + User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); + + // 지역 확인 + Area area = Area.fromRegionName(region); + + // 중복 카드 확인 + if (cardRepository.existsByUserAndArea(user, area)) { + throw new DuplicateCardException(); + } + + // 이미지 저장 로직 + String imageUrl = null; + if (customImage != null && !customImage.isEmpty()) { + imageUrl = s3Service.uploadImage(customImage); + } + + // 카드 등록 + Card card = Card.builder() + .user(user) + .area(area) + .customImage(imageUrl != null ? imageUrl : "default") // 없으면 default + .build(); + cardRepository.save(card); + } + public SwipstoneResponse getSwipstone(Principal principal) { Long userId = Long.parseLong(principal.getName()); User user = userRepository.findById(userId).orElseThrow(UserNotFoundException::new); From 4ec0150b13a8ff25832d430dc28b0030e6dfe52d Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Sat, 23 Nov 2024 01:14:16 +0900 Subject: [PATCH 16/17] =?UTF-8?q?=F0=9F=8E=A8=20Style[#25]:=20Swagger=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 --- .../groom/swipo/domain/point/controller/PointController.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/main/java/com/groom/swipo/domain/point/controller/PointController.java b/src/main/java/com/groom/swipo/domain/point/controller/PointController.java index 2a3b3b7..a72d1b9 100644 --- a/src/main/java/com/groom/swipo/domain/point/controller/PointController.java +++ b/src/main/java/com/groom/swipo/domain/point/controller/PointController.java @@ -54,9 +54,8 @@ public ResTemplate getHome(Principal principal) { security = {}, responses = { @ApiResponse(responseCode = "201", description = "카드 등록 성공"), - @ApiResponse(responseCode = "400", description = "잘못된 요청"), + @ApiResponse(responseCode = "400", description = "유효하지 않은 동네"), @ApiResponse(responseCode = "401", description = "유효하지 않은 인증 토큰"), - @ApiResponse(responseCode = "403", description = "동네 인증이 안된 경우"), @ApiResponse(responseCode = "409", description = "중복 카드 등록"), @ApiResponse(responseCode = "500", description = "서버 오류") } From 80bec94f1f4511dd20fc5d618df160868f1b75f5 Mon Sep 17 00:00:00 2001 From: Junho Yu <95111999+ryuwon2407@users.noreply.github.com> Date: Sat, 23 Nov 2024 02:13:36 +0900 Subject: [PATCH 17/17] =?UTF-8?q?=F0=9F=8E=A8=20Style[#28]:=20=EC=BD=94?= =?UTF-8?q?=EB=A9=98=ED=8A=B8=20=EB=B0=98=EC=98=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/groom/swipo/domain/payment/dto/PaylistInfo.java | 2 +- .../swipo/domain/payment/exception/PayNotFoundException.java | 2 +- src/main/java/com/groom/swipo/domain/point/dto/CardInfo.java | 2 +- src/main/java/com/groom/swipo/domain/point/entity/Card.java | 4 ++-- .../com/groom/swipo/domain/point/service/PointService.java | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/main/java/com/groom/swipo/domain/payment/dto/PaylistInfo.java b/src/main/java/com/groom/swipo/domain/payment/dto/PaylistInfo.java index 28aa915..e59f442 100644 --- a/src/main/java/com/groom/swipo/domain/payment/dto/PaylistInfo.java +++ b/src/main/java/com/groom/swipo/domain/payment/dto/PaylistInfo.java @@ -18,7 +18,7 @@ public static PaylistInfo of(Paylist paylist, Store store){ return PaylistInfo.builder() .paylistId(String.valueOf(paylist.getId())) .amount((int)paylist.getValue()) - .amount(Integer.valueOf(store.getName())) + .storeName(store.getName()) .createAt(paylist.getCreatedAt()) .build(); } diff --git a/src/main/java/com/groom/swipo/domain/payment/exception/PayNotFoundException.java b/src/main/java/com/groom/swipo/domain/payment/exception/PayNotFoundException.java index f202a05..69d9666 100644 --- a/src/main/java/com/groom/swipo/domain/payment/exception/PayNotFoundException.java +++ b/src/main/java/com/groom/swipo/domain/payment/exception/PayNotFoundException.java @@ -8,6 +8,6 @@ public PayNotFoundException(String message) { } public PayNotFoundException() { - super("Pay not found for user."); + super("해당 페이를 찾지 못했습니다."); } } diff --git a/src/main/java/com/groom/swipo/domain/point/dto/CardInfo.java b/src/main/java/com/groom/swipo/domain/point/dto/CardInfo.java index fee2e9b..a2d4d9c 100644 --- a/src/main/java/com/groom/swipo/domain/point/dto/CardInfo.java +++ b/src/main/java/com/groom/swipo/domain/point/dto/CardInfo.java @@ -11,7 +11,7 @@ public record CardInfo( Integer point, String customImage ) { - public static CardInfo of(Card card) { + public static CardInfo from(Card card) { return CardInfo.builder() .cardId(String.valueOf(card.getId())) .region(card.getArea().getRegionName()) diff --git a/src/main/java/com/groom/swipo/domain/point/entity/Card.java b/src/main/java/com/groom/swipo/domain/point/entity/Card.java index 5c0d627..f37a728 100644 --- a/src/main/java/com/groom/swipo/domain/point/entity/Card.java +++ b/src/main/java/com/groom/swipo/domain/point/entity/Card.java @@ -39,7 +39,7 @@ public class Card extends BaseEntity { @Column(nullable = false) @ColumnDefault("0") - private Integer totalPoint = 0; + private Integer totalPoint; @Column(nullable = false) private String customImage; @@ -61,7 +61,7 @@ public class Card extends BaseEntity { private Card(User user, String customImage, Area area) { this.user = user; this.contents = ""; - this.totalPoint = 0; // 생성자에서 명시적으로 기본값 설정 + this.totalPoint = 0; //default 0 this.customImage = customImage; this.area = area; } diff --git a/src/main/java/com/groom/swipo/domain/point/service/PointService.java b/src/main/java/com/groom/swipo/domain/point/service/PointService.java index 64f5373..502f8d2 100644 --- a/src/main/java/com/groom/swipo/domain/point/service/PointService.java +++ b/src/main/java/com/groom/swipo/domain/point/service/PointService.java @@ -54,7 +54,7 @@ public PointHomeResponse getHome(Principal principal) { // 사용자 카드 정보 조회 List cards = cardRepository.findAllByUser(user); List cardInfos = cards.stream() - .map(CardInfo::of) + .map(CardInfo::from) .toList(); // 최근 페이 거래 내역 조회 (최대 5개)