Skip to content

Commit

Permalink
Merge pull request #113 from feature/order 결제, 주문 및 장바구니
Browse files Browse the repository at this point in the history
  • Loading branch information
woody35545 authored May 16, 2024
2 parents 04a0c75 + 3eb5a1b commit f49dea5
Show file tree
Hide file tree
Showing 38 changed files with 2,054 additions and 231 deletions.
12 changes: 5 additions & 7 deletions src/main/java/com/t3t/frontserver/FrontServerApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,14 @@

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;

@EnableDiscoveryClient
@ConfigurationPropertiesScan
@SpringBootApplication
public class FrontServerApplication {

public static void main(String[] args) {
SpringApplication.run(FrontServerApplication.class, args);
}
public static void main(String[] args) {
SpringApplication.run(FrontServerApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package com.t3t.frontserver.book.exception;

/**
* BookApiClient 로 도서 관련 API 호출 실패시 발생하는 예외
*
* @author woody35545(구건모)
*/
public class BookApiClientException extends RuntimeException {
public BookApiClientException(String message) {
super(message);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,26 +10,25 @@

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import java.util.Optional;

@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
/**
* 예외 발생 시 예외에 대한 정보를 제공하는 핸들러
*
* @author 구건모(woody35545)
*/
@ExceptionHandler(Exception.class)
public String handleException(RedirectAttributes redirectAttributes, Exception e) {
redirectAttributes.addAttribute("message", e.getMessage());

redirectAttributes.addAttribute("message",
Optional.ofNullable(e.getMessage()).orElse("오류가 발생하였습니다. 잠시 후 다시 시도해주세요."));

return "redirect:/message";
}

/* @ExceptionHandler(RestApiClientException.class)
public String handleUnAuthorizedException(Model model, RestApiClientException e, HttpServletResponse response) {
Cookie cookie = new Cookie("t3t", null);
cookie.setMaxAge(0);
cookie.setPath("/");
SecurityContextHolder.clearContext();
response.addCookie(cookie);
return "redirect:/login";
}*/

@ExceptionHandler(FeignException.Unauthorized.class)
public String handleLogoutException(Model model, FeignException.Unauthorized e, HttpServletResponse response) {
Cookie cookie = new Cookie("t3t", null);
Expand Down
48 changes: 48 additions & 0 deletions src/main/java/com/t3t/frontserver/config/RedisConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
package com.t3t.frontserver.config;

import com.t3t.frontserver.property.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import org.springframework.data.redis.serializer.StringRedisSerializer;


@Configuration
@EnableRedisRepositories
public class RedisConfig {

/**
* RedisConnectionFactory 빈 설정
*
* @author woody35545(구건모)
*/
@Bean
public RedisConnectionFactory redisConnectionFactory(RedisProperties redisProperties) {
RedisStandaloneConfiguration redisStandaloneConfiguration = new RedisStandaloneConfiguration();
redisStandaloneConfiguration.setHostName(redisProperties.getRedisServerIpAddress());
redisStandaloneConfiguration.setPort(Integer.parseInt(redisProperties.getRedisServerPort()));
redisStandaloneConfiguration.setPassword(redisProperties.getRedisServerPassword());
redisStandaloneConfiguration.setDatabase(redisProperties.getRedisDatabase());
System.out.println("redisProperties.getRedisServerIpAddress() = " + redisProperties.getRedisServerIpAddress());
return new LettuceConnectionFactory(redisStandaloneConfiguration);
}

/**
* RedisTemplate 빈 설정
*
* @author woody35545(구건모)
*/
@Bean
public RedisTemplate<String, String> redisTemplate(RedisProperties redisProperties) {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory(redisProperties));
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
return redisTemplate;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,29 @@
import com.t3t.frontserver.member.model.dto.MyPageInfoViewDto;
import com.t3t.frontserver.member.model.response.MemberInfoResponse;
import com.t3t.frontserver.member.service.MemberService;
import com.t3t.frontserver.model.response.PageResponse;
import com.t3t.frontserver.order.model.response.OrderInfoResponse;
import com.t3t.frontserver.order.service.OrderService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
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.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Controller
@RequiredArgsConstructor
public class MyPageController {

private final MemberService memberService;
private final OrderService orderService;

/**
* 마이페이지 - 회원 기본 정보 관리 뷰
Expand Down Expand Up @@ -155,11 +165,39 @@ public String gradeView(Model model) {

/**
* 마이페이지 - 회원 주문 페이지 뷰
*
* @author woody35545(구건모)
*/
@GetMapping("/mypage/order")
public String orderView() {
public String orderView(Model model,
@RequestParam(value = "pageNo", defaultValue = "0", required = false) int pageNo,
@RequestParam(value = "pageSize", defaultValue = "3", required = false) int pageSize) {

if (!SecurityContextUtils.isLoggedIn()) {
return "redirect:/login";
}

PageResponse<OrderInfoResponse> orderInfoResponsePageResponse =
orderService.getMemberOrderInfoListByMemberId(SecurityContextUtils.getMemberId(),
Pageable.ofSize(pageSize).withPage(pageNo));

List<OrderInfoResponse> orderInfoResponseList = new ArrayList<>();

if (orderInfoResponsePageResponse != null) {
orderInfoResponseList = orderInfoResponsePageResponse.getContent();

int blockLimit = 5;
int nextPage = orderInfoResponsePageResponse.getPageNo() + 1;
int startPage = Math.max(nextPage - blockLimit, 1);
int endPage = Math.min(nextPage + blockLimit, orderInfoResponsePageResponse.getTotalPages());

model.addAttribute("nextPage", nextPage);
model.addAttribute("startPage", startPage);
model.addAttribute("endPage", endPage);
}

model.addAttribute("orderInfoResponseList", orderInfoResponseList);

return "main/page/mypageOrder";
}

}
69 changes: 69 additions & 0 deletions src/main/java/com/t3t/frontserver/order/adaptor/OrderAdaptor.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package com.t3t.frontserver.order.adaptor;

import com.t3t.frontserver.model.response.BaseResponse;
import com.t3t.frontserver.model.response.PageResponse;
import com.t3t.frontserver.order.client.OrderApiClient;
import com.t3t.frontserver.order.exception.OrderApiClientException;
import com.t3t.frontserver.order.model.request.MemberOrderPreparationRequest;
import com.t3t.frontserver.order.model.request.OrderConfirmRequest;
import com.t3t.frontserver.order.model.response.MemberOrderPreparationResponse;
import com.t3t.frontserver.order.model.response.OrderInfoResponse;
import com.t3t.frontserver.util.FeignClientUtils;
import feign.FeignException;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Component;

import java.util.Optional;

@Slf4j
@Component
@RequiredArgsConstructor
public class OrderAdaptor {
private final OrderApiClient orderApiClient;

/**
* 회원 주문 생성
* 결제 대기 상태의 주문을 생성한다.
*
* @author woody35545(구건모)
*/
public MemberOrderPreparationResponse createMemberOrder(MemberOrderPreparationRequest request) {
try {
return Optional.ofNullable(orderApiClient.createMemberOrder(request).getBody())
.map(BaseResponse::getData)
.orElseThrow(RuntimeException::new);
} catch (FeignException e) {
throw new OrderApiClientException("주문 생성에 실패하였습니다. " + FeignClientUtils.getMessageFromFeignException(e));
}
}

/**
* 주문에 대한 결제 검증 및 주문 승인
*
* @author woody35545(구건모)
*/
public void confirmOrder(OrderConfirmRequest request) {
try {
orderApiClient.confirmOrder(request);
} catch (FeignException e) {
throw new OrderApiClientException("주문에 대한 결제 검증에 실패하였습니다. " + FeignClientUtils.getMessageFromFeignException(e));
}
}

/**
* 특정 회원의 모든 주문 관련 정보를 페이징을 통해 조회
*
* @author woody35545(구건모)
*/
public PageResponse<OrderInfoResponse> getMemberOrderInfoListByMemberId(Long memberId, Pageable pageable) {
try {
return Optional.ofNullable(orderApiClient.getMemberOrderInfoListByMemberId(memberId, pageable).getBody())
.map(BaseResponse::getData)
.orElseThrow(RuntimeException::new);
} catch (FeignException e) {
throw new OrderApiClientException("주문 정보 조회에 실패하였습니다. " + FeignClientUtils.getMessageFromFeignException(e));
}
}
}
44 changes: 44 additions & 0 deletions src/main/java/com/t3t/frontserver/order/client/OrderApiClient.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.t3t.frontserver.order.client;

import com.t3t.frontserver.model.response.BaseResponse;
import com.t3t.frontserver.model.response.PageResponse;
import com.t3t.frontserver.order.model.request.MemberOrderPreparationRequest;
import com.t3t.frontserver.order.model.request.OrderConfirmRequest;
import com.t3t.frontserver.order.model.response.MemberOrderPreparationResponse;
import com.t3t.frontserver.order.model.response.OrderInfoResponse;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@FeignClient(name = "OrderApiClient", url = "${t3t.feignClient.url}")
public interface OrderApiClient {

/**
* 회원 주문 생성 API<br>
* 결제 대기 상태의 주문을 생성한다.
*
* @author woody35545(구건모)
*/
@PostMapping(value = "/t3t/bookstore/orders/member")
ResponseEntity<BaseResponse<MemberOrderPreparationResponse>> createMemberOrder(@RequestBody MemberOrderPreparationRequest memberOrderPreparationRequest);


/**
* 주문에 대한 결제 검증 및 주문 승인 API
*
* @author woody35545(구건모)
*/
@PostMapping("/t3t/bookstore/orders/confirm")
ResponseEntity<BaseResponse<Void>> confirmOrder(@RequestBody OrderConfirmRequest orderConfirmRequest);

/**
* 특정 회원의 모든 주문 관련 정보를 페이징을 통해 조회
*
* @author woody35545(구건모)
*/
@GetMapping("/t3t/bookstore/members/{memberId}/orders")
ResponseEntity<BaseResponse<PageResponse<OrderInfoResponse>>> getMemberOrderInfoListByMemberId(@PathVariable("memberId") Long memberId, Pageable pageable);
}
Loading

0 comments on commit f49dea5

Please sign in to comment.