Skip to content

Commit

Permalink
Merge pull request #95 from nhnacademy-be5-T3Team/feature/point_details
Browse files Browse the repository at this point in the history
Feature/point details 회원 포인트 사용/적립 내역 기능
  • Loading branch information
parkjonggyeong18 authored May 13, 2024
2 parents c506059 + c292964 commit da3ab35
Show file tree
Hide file tree
Showing 6 changed files with 223 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.t3t.frontserver.pointdetail.client;

import com.t3t.frontserver.model.response.BaseResponse;
import com.t3t.frontserver.pointdetail.model.response.PointDetailResponse;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
* 포인트 사용/적립 내역 API 호출을 위한 Feign Client
* @author hydraitonn(박수화)
*/
@FeignClient(name = "UserPointDetailApiClient", url = "${t3t.feignClient.url}")
public interface UserPointDetailApiClient {

/**
* 회원의 포인트 타입에 따른 포인트 사용/적립 내역 조회 API 호출
* @param pointDetailType 조회할 포인트 타입(사용/적립)
* @author hydrationn(박수화)
*/
@GetMapping("/t3t/bookstore/members/point-details")
public ResponseEntity<BaseResponse<List<PointDetailResponse>>> getPointDetailByPointDetailType(@RequestParam(name = "pointDetailType", required = false) String pointDetailType);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
package com.t3t.frontserver.pointdetail.controller;

import com.t3t.frontserver.auth.util.SecurityContextUtils;
import com.t3t.frontserver.model.response.BaseResponse;
import com.t3t.frontserver.pointdetail.client.UserPointDetailApiClient;
import com.t3t.frontserver.pointdetail.model.response.PointDetailResponse;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Controller
@RequiredArgsConstructor
public class UserPointDetailController {
private final UserPointDetailApiClient userPointDetailApiClient;

/**
* 회원 포인트 사용/적립 내역 페이지 뷰 반환
* @return 포인트 사용/적립 내역 뷰
* @author hydrationn(박수화)
*/
@GetMapping("/member/point-details")
public String pointDetailView(Model model, @Valid @RequestParam(value = "pointDetailType", required = false) String pointDetailType) {

// 로그인 정보가 없으면 로그인 페이지로 이동
if(!SecurityContextUtils.isLoggedIn()){
return "redirect:/login";
}

ResponseEntity<BaseResponse<List<PointDetailResponse>>> response = userPointDetailApiClient.getPointDetailByPointDetailType(pointDetailType); // 모든 내역을 가져오는 API 호출

List<PointDetailResponse> pointDetails;

if (pointDetailType == null) {
// parameter가 null인 경우 모든 내역 반환
pointDetails = Objects.requireNonNull(response.getBody()).getData();
} else {
// pointDetailType(used, saved)에 해당하는 내역만 반환
pointDetails = Objects.requireNonNull(response.getBody()).getData()
.stream()
.filter(pointDetail -> pointDetail.getPointDetailType().equals(pointDetailType))
.collect(Collectors.toList());
}

model.addAttribute("pointDetails", pointDetails);

return "main/pointdetails/pointdetail";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.t3t.frontserver.pointdetail.model.dto;

import com.t3t.frontserver.member.model.dto.MemberDto;
import lombok.*;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
* PointDetail Entity에 대한 DTO 클래스
* @author hydrationn(박수화)
*/
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class PointDetailDto {
private Long pointDetailId;
private MemberDto member;
private String content;
private String pointDetailType;
private LocalDateTime pointDetailDate;
private BigDecimal pointAmount;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.t3t.frontserver.pointdetail.model.request;

import lombok.*;
import org.springframework.format.annotation.DateTimeFormat;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Pattern;
import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
* 포인트 사용/정립 내역 생성 정보를 담기 위한 클래스
* @author hydrationn(박수화)
*/
@Getter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@ToString
@Setter
public class CreatePointDetailRequest {

// 포인트 상세 내용
@NotBlank(message = "포인트 상세 내용이 누락되었습니다.")
private String content;

// 포인트 사용/적립 구분
@NotBlank(message = "포인트 사용/적립 구분이 명시되지 않았습니다.")
@Pattern(regexp = "^(사용|적립)$", message = "포인트 상세 유형은'사용' 또는'적립'만 가능합니다.")
private String pointDetailType;

// 사용/적립 내역 일자
@NotNull(message = "포인트 사용/적립 일자가 누락되었습니다.")
@DateTimeFormat(pattern = "yyyy-MM-dd'T'HH:mm:ss")
private LocalDateTime pointDetailDate;

// 포인트 양
@NotNull(message = "포인트 양이 누락되었습니다.")
private BigDecimal pointAmount;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package com.t3t.frontserver.pointdetail.model.response;

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.math.BigDecimal;
import java.time.LocalDateTime;

/**
* 회원 포인트 사용/적립 내역 조회 요청을 성공적으로 처리한 경우 응답 정보를 담기 위한 클래스
* @author hydrationn(박수화)
*/
@Data
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class PointDetailResponse {

private String content;

private String pointDetailType;

private LocalDateTime pointDetailDate;

private BigDecimal pointAmount;
}
50 changes: 50 additions & 0 deletions src/main/resources/templates/main/pointdetails/pointdetail.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout(categoryList)"
xmlns:sec="http://www.thymeleaf.org/thymeleaf-extras-springsecurity5"
layout:decorate="main/layout/layout">

<th:block layout:fragment="content">
<div class="container">
<div class="row justify-content-center">
<div class="col-md-10">
<h2 class="text-center mb-5">회원 포인트 내역 조회</h2>
<div class="d-flex justify-content-end mb-3">
<a href="/member/point-details" class="btn btn-primary mx-1">전체</a>
<a href="/member/point-details?pointDetailType=used" class="btn btn-primary mx-1">사용</a>
<a href="/member/point-details?pointDetailType=saved" class="btn btn-primary mx-1">적립</a>
</div>
<div class="text-center mb-5">
<table id="pointDetailTable" class="table table-bordered table-striped centered-table">
<thread>
<tr>
<td>No</td>
<td>날짜 및 시간</td>
<td>포인트</td>
<td>구분</td>
<td>내용</td>
</tr>
</thread>
<tbody>
<!-- Thymeleaf를 사용하여 반복문 처리 -->
<tr th:each="pointDetail, no : ${pointDetails}">
<td th:text="${no.index + 1}"></td>
<td th:text="${#temporals.format(pointDetail.pointDetailDate, 'yyyy-MM-dd HH:mm:ss')}"></td>
<td th:text="${pointDetail.pointAmount}"></td>
<td th:switch="${pointDetail.pointDetailType}">
<span th:case="used" th:text="사용"></span>
<span th:case="saved" th:text="적립"></span>
</td>
<td th:text="${pointDetail.content}"></td>
</tr>
</tbody>

</table>
<a href="/" class="btn btn-secondary">메인 화면 바로가기</a>
<p></p>
</div>
</div>
</div>
</div>
</th:block>
</html>

0 comments on commit da3ab35

Please sign in to comment.