Skip to content

Commit

Permalink
Merge pull request #26 from lotteon2/feat/auction-history
Browse files Browse the repository at this point in the history
Feat/auction history
  • Loading branch information
ssjy4974 authored Jan 16, 2024
2 parents e19781a + b24716a commit 5536377
Show file tree
Hide file tree
Showing 9 changed files with 402 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import com.amazonaws.services.dynamodbv2.model.ProvisionedThroughput;
import com.amazonaws.services.dynamodbv2.util.TableUtils;
import com.dailyon.auctionservice.document.Auction;
import com.dailyon.auctionservice.document.AuctionHistory;
import com.dailyon.auctionservice.document.BidHistory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
Expand Down Expand Up @@ -46,23 +47,39 @@ public void setDynamoDB() {
// TableUtils.deleteTableIfExists(
// dynamoDB, dynamoDBMapper.generateDeleteTableRequest(BidHistory.class));

CreateTableRequest createTableRequest =
TableUtils.deleteTableIfExists(
dynamoDB, dynamoDBMapper.generateDeleteTableRequest(AuctionHistory.class));

CreateTableRequest createAuction =
dynamoDBMapper
.generateCreateTableRequest(Auction.class)
.withProvisionedThroughput(new ProvisionedThroughput(10L, 10L));

CreateTableRequest createTableRequest2 =
CreateTableRequest createBidHistory =
dynamoDBMapper
.generateCreateTableRequest(BidHistory.class)
.withProvisionedThroughput(new ProvisionedThroughput(1L, 1L));

createTableRequest2
CreateTableRequest createAuctionHistory = dynamoDBMapper
.generateCreateTableRequest(AuctionHistory.class)
.withProvisionedThroughput(new ProvisionedThroughput(1L, 1L));

createBidHistory
.getGlobalSecondaryIndexes()
.forEach(
idx ->
idx.withProvisionedThroughput(new ProvisionedThroughput(1L, 1L))
.withProjection(new Projection().withProjectionType("ALL")));
TableUtils.createTableIfNotExists(dynamoDB, createTableRequest);
TableUtils.createTableIfNotExists(dynamoDB, createTableRequest2);
.forEach(idx -> idx
.withProvisionedThroughput(new ProvisionedThroughput(1L, 1L))
.withProjection(new Projection().withProjectionType("ALL"))
);

createAuctionHistory
.getGlobalSecondaryIndexes()
.forEach(idx -> idx
.withProvisionedThroughput(new ProvisionedThroughput(1L, 1L))
.withProjection(new Projection().withProjectionType("ALL"))
);

TableUtils.createTableIfNotExists(dynamoDB, createAuction);
TableUtils.createTableIfNotExists(dynamoDB, createBidHistory);
TableUtils.createTableIfNotExists(dynamoDB, createAuctionHistory);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.dailyon.auctionservice.controller;

import com.dailyon.auctionservice.dto.response.ReadAuctionHistoryPageResponse;
import com.dailyon.auctionservice.facade.AuctionHistoryFacade;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

@CrossOrigin("*")
@RestController
@RequiredArgsConstructor
@RequestMapping("/auctions/history")
public class AuctionHistoryController {
private final AuctionHistoryFacade auctionHistoryFacade;

@GetMapping
Mono<ReadAuctionHistoryPageResponse> readAuctionHistory(
@RequestHeader(name = "memberId") String memberId,
@RequestParam(name = "page") int page, @RequestParam(name = "size") int size
) {
return Mono.just(auctionHistoryFacade.readAuctionHistories(memberId, PageRequest.of(page, size)));
}
}
109 changes: 109 additions & 0 deletions src/main/java/com/dailyon/auctionservice/document/AuctionHistory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
package com.dailyon.auctionservice.document;

import com.amazonaws.services.dynamodbv2.datamodeling.*;
import com.dailyon.auctionservice.config.DynamoDbConfig;
import lombok.*;
import org.jetbrains.annotations.NotNull;
import org.springframework.data.annotation.Id;

import java.time.LocalDateTime;

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@DynamoDBTable(tableName = "auction_history")
public class AuctionHistory implements Comparable<AuctionHistory> {
@Id @DynamoDBHashKey
@DynamoDBAutoGeneratedKey
private String id;

@DynamoDBIndexHashKey(
attributeName = "member_id",
globalSecondaryIndexName = "memberAuctionHistoryIdx"
)
private String memberId;

@DynamoDBIndexRangeKey(
attributeName = "auction_id",
globalSecondaryIndexName = "memberAuctionHistoryIdx"
)
private String auctionId;

@DynamoDBAttribute(attributeName = "auction_product_id")
private Long auctionProductId;

@DynamoDBAttribute(attributeName = "auction_product_img")
private String auctionProductImg;

@DynamoDBAttribute(attributeName = "auction_product_name")
private String auctionProductName;

@DynamoDBAttribute(attributeName = "auction_product_size_id")
private Long auctionProductSizeId;

@DynamoDBAttribute(attributeName = "auction_product_size_name")
private String auctionProductSizeName;

// 유저의 낙찰 여부
@DynamoDBTyped(DynamoDBMapperFieldModel.DynamoDBAttributeType.BOOL)
@DynamoDBAttribute(attributeName = "is_winner")
private boolean isWinner;

// 낙찰된 유저가 나머지 95% 결제했는지
@DynamoDBTyped(DynamoDBMapperFieldModel.DynamoDBAttributeType.BOOL)
@DynamoDBAttribute(attributeName = "is_paid")
@Builder.Default
private boolean isPaid = false;

// 결제해야 할 95%에 해당하는 금액
@DynamoDBAttribute(attributeName = "amount_to_pay")
private Long amountToPay;

// 유저의 최대 bid 금액
@DynamoDBAttribute(attributeName = "member_highest_bid")
private Long memberHighestBid;

// 낙찰 bid 금액
@DynamoDBAttribute(attributeName = "auction_winner_bid")
private Long auctionWinnerBid;

@DynamoDBAttribute(attributeName = "created_at")
@DynamoDBTypeConverted(converter = DynamoDbConfig.LocalDateTimeConverter.class)
@Builder.Default
private LocalDateTime createdAt = LocalDateTime.now();

public static AuctionHistory create(
String memberId,
String auctionId,
Long auctionProductId,
String auctionProductImg,
String auctionProductName,
Long auctionProductSizeId,
String auctionProductSizeName,
boolean isWinner,
Long amountToPay,
Long memberHighestBid,
Long auctionWinnerBid
) {
return AuctionHistory.builder()
.memberId(memberId)
.auctionId(auctionId)
.auctionProductId(auctionProductId)
.auctionProductImg(auctionProductImg)
.auctionProductName(auctionProductName)
.auctionProductSizeId(auctionProductSizeId)
.auctionProductSizeName(auctionProductSizeName)
.isWinner(isWinner)
.amountToPay(amountToPay)
.memberHighestBid(memberHighestBid)
.auctionWinnerBid(auctionWinnerBid)
.build();
}

@Override
public int compareTo(AuctionHistory o) {
return o.createdAt.compareTo(this.createdAt);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
package com.dailyon.auctionservice.dto.response;

import com.dailyon.auctionservice.document.AuctionHistory;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.springframework.data.domain.Page;

import java.util.List;
import java.util.stream.Collectors;

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class ReadAuctionHistoryPageResponse {
private long totalElements;
private int totalPages;
private List<ReadAuctionHistoryResponse> responses;

public static ReadAuctionHistoryPageResponse of(Page<AuctionHistory> histories) {
return ReadAuctionHistoryPageResponse.builder()
.totalPages(histories.getTotalPages())
.totalPages(histories.getTotalPages())
.responses(histories.stream()
.map(ReadAuctionHistoryResponse::of)
.collect(Collectors.toList()))
.build();
}

@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public static class ReadAuctionHistoryResponse {
private String id;
private String auctionId;
private Long auctionProductId;
private String auctionProductImg;
private String auctionProductName;
private Long auctionProductSizeId;
private String auctionProductSizeName;
private boolean isWinner;
private boolean isPaid;
private Long amountToPay;
private Long memberHighestBid;
private Long auctionWinnerBid;

public static ReadAuctionHistoryResponse of(AuctionHistory auctionHistory) {
return ReadAuctionHistoryResponse.builder()
.id(auctionHistory.getId())
.auctionId(auctionHistory.getAuctionId())
.auctionProductId(auctionHistory.getAuctionProductId())
.auctionProductImg(auctionHistory.getAuctionProductImg())
.auctionProductName(auctionHistory.getAuctionProductName())
.auctionProductSizeId(auctionHistory.getAuctionProductSizeId())
.auctionProductSizeName(auctionHistory.getAuctionProductSizeName())
.isWinner(auctionHistory.isWinner())
.isPaid(auctionHistory.isPaid())
.amountToPay(auctionHistory.getAmountToPay())
.memberHighestBid(auctionHistory.getMemberHighestBid())
.auctionWinnerBid(auctionHistory.getAuctionWinnerBid())
.build();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.dailyon.auctionservice.facade;

import com.dailyon.auctionservice.document.AuctionHistory;
import com.dailyon.auctionservice.dto.response.ReadAuctionHistoryPageResponse;
import com.dailyon.auctionservice.service.AuctionHistoryService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;

@Component
@RequiredArgsConstructor
public class AuctionHistoryFacade {
private final AuctionHistoryService auctionHistoryService;

public ReadAuctionHistoryPageResponse readAuctionHistories(String memberId, Pageable pageable) {
return ReadAuctionHistoryPageResponse.of(auctionHistoryService.readAuctionHistories(memberId, pageable));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.dailyon.auctionservice.repository;

import com.dailyon.auctionservice.document.AuctionHistory;
import org.socialsignin.spring.data.dynamodb.repository.EnableScan;
import org.socialsignin.spring.data.dynamodb.repository.EnableScanCount;
import org.springframework.data.repository.CrudRepository;

import java.util.List;

@EnableScan
@EnableScanCount
public interface AuctionHistoryRepository extends CrudRepository<AuctionHistory, String> {
List<AuctionHistory> findByMemberId(String memberId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.dailyon.auctionservice.document.BidHistory;
import com.dailyon.auctionservice.dto.request.CreateBidRequest;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Profile;
import org.springframework.data.domain.Range;
import org.springframework.data.redis.core.ReactiveRedisTemplate;
import org.springframework.data.redis.core.ReactiveZSetOperations;
Expand All @@ -12,6 +13,7 @@

import java.time.Duration;

@Profile("!test")
@Repository
public class ReactiveRedisRepository {
private static final String AUCTION_KEY = "auction_id:";
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.dailyon.auctionservice.service;

import com.dailyon.auctionservice.document.AuctionHistory;
import com.dailyon.auctionservice.repository.AuctionHistoryRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class AuctionHistoryService {
private final AuctionHistoryRepository auctionHistoryRepository;

public Page<AuctionHistory> readAuctionHistories(String memberId, Pageable pageable) {
int currentPage = pageable.getPageNumber();
int pageSize = pageable.getPageSize();

int startIdx = currentPage * pageSize;
int endIdx = startIdx + pageSize;

List<AuctionHistory> auctionHistories = auctionHistoryRepository.findByMemberId(memberId);
if(auctionHistories.isEmpty()) {
return new PageImpl<>(new ArrayList<>(), pageable, 0);
}
int totalSize = auctionHistories.size();

List<AuctionHistory> sorted = auctionHistories.stream()
.sorted(AuctionHistory::compareTo)
.collect(Collectors.toList())
.subList(startIdx, Math.min(endIdx, totalSize));

return new PageImpl<>(sorted, pageable, totalSize);
}
}
Loading

0 comments on commit 5536377

Please sign in to comment.