Skip to content

Commit

Permalink
Merge pull request #65 from ClothingStoreService/feature/member-finda…
Browse files Browse the repository at this point in the history
…ll-paging

Feature/member findall paging
  • Loading branch information
hjj4060 authored Jul 5, 2024
2 parents 25fb021 + e215994 commit e6bfe14
Show file tree
Hide file tree
Showing 12 changed files with 329 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,15 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
.requestMatchers("/", "/login", "/userPage", "/sellerPage", "/adminPage", "/main"
, "/v1/members/login", "/signup", "/v1/members/email/**", "/v1/access",
"/v1/categories/**", "/v1/products/**", "/v1/productLines/**", "/v2/productLines/**",
"/v1/orderdetails", "/v1/orders",
"/v1/orderdetails", "/v1/orders", "membersPagingOffset", "membersPagingSlice",
"/v1/seller/orders/**", "/v1/seller/orders", "/v1/orders/**",
"/swagger-resources/**", "/swagger-ui/**", "/v3/api-docs/**", "/v1/members/auth/**"
).permitAll()
.requestMatchers(HttpMethod.POST, "/v1/members").permitAll()
.requestMatchers(HttpMethod.POST, "/v1/sellers/**").authenticated()
.requestMatchers("/seller/**", "/v1/sellers/**").hasRole("SELLER")
.requestMatchers("/admin/**", "/v1/admin/**").hasRole("ADMIN")
.requestMatchers("v2/members", "v3/members").hasRole("ADMIN")
.requestMatchers(HttpMethod.GET, "/v1/members").hasRole("ADMIN")
.anyRequest().authenticated()
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ public class SwaggerConfig {
public GroupedOpenApi groupedAllOpenApi() {
return GroupedOpenApi.builder()
.group("All")
.pathsToMatch("/v1/**", "/v2/**")
.pathsToMatch("/v1/**", "/v2/**", "/v3/**")
.build();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package org.store.clothstar.member.application;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.stereotype.Service;
import org.store.clothstar.member.dto.request.CreateMemberRequest;
import org.store.clothstar.member.dto.request.ModifyMemberRequest;
import org.store.clothstar.member.dto.response.MemberResponse;
import org.store.clothstar.member.service.MemberService;

import java.util.List;

@Service
@Slf4j
public class MemberServiceApplication {
Expand All @@ -18,8 +19,12 @@ public MemberServiceApplication(MemberService memberService) {
this.memberService = memberService;
}

public List<MemberResponse> getAllMember() {
return memberService.findAll();
public Page<MemberResponse> getAllMemberOffsetPaging(Pageable pageable) {
return memberService.getAllMemberOffsetPaging(pageable);
}

public Slice<MemberResponse> getAllMemberSlicePaging(Pageable pageable) {
return memberService.getAllMemberSlicePaging(pageable);
}

public MemberResponse getMemberById(Long memberId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
Expand All @@ -15,20 +19,27 @@
import org.store.clothstar.member.dto.request.ModifyPasswordRequest;
import org.store.clothstar.member.dto.response.MemberResponse;

import java.util.List;

@Tag(name = "Member", description = "회원 정보 관리에 대한 API 입니다.")
@RestController
@RequiredArgsConstructor
@Slf4j
public class MemberController {
private final MemberServiceApplication memberServiceApplication;

@Operation(summary = "전체 회원 조회", description = "전체 회원 리스트를 가져온다.")
@Operation(summary = "전체 회원 조회 offset 페이징", description = "전체 회원 리스트를 offset 페이징 형식으로 가져온다.")
@GetMapping("/v1/members")
public ResponseEntity<List<MemberResponse>> getAllMember() {
List<MemberResponse> memberList = memberServiceApplication.getAllMember();
return ResponseEntity.ok(memberList);
public ResponseEntity<Page<MemberResponse>> getAllMemberOffsetPaging(
@PageableDefault(size = 18) Pageable pageable) {
Page<MemberResponse> memberPages = memberServiceApplication.getAllMemberOffsetPaging(pageable);
return ResponseEntity.ok(memberPages);
}

@Operation(summary = "전체 회원 조회 slice 페이징", description = "전체 회원 리스트를 slice 페이징 형식으로 가져온다.")
@GetMapping("/v2/members")
public ResponseEntity<Slice<MemberResponse>> getAllMemberSlicePaging(
@PageableDefault(size = 18) Pageable pageable) {
Slice<MemberResponse> memberPages = memberServiceApplication.getAllMemberSlicePaging(pageable);
return ResponseEntity.ok(memberPages);
}

@Operation(summary = "회원 상세정보 조회", description = "회원 한 명에 대한 상세 정보를 가져온다.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,16 @@ public String main() {
return "index";
}

@GetMapping("/membersPagingOffset")
public String membersPagingOffset() {
return "memberOffsetList";
}

@GetMapping("/membersPagingSlice")
public String membersPagingSlice() {
return "memberSliceList";
}

@GetMapping("/signup")
public String signup() {
return "signup";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
package org.store.clothstar.member.repository;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.store.clothstar.member.entity.MemberEntity;

import java.util.Optional;

public interface MemberJpaRepository extends JpaRepository<MemberEntity, Long>, MemberRepository {
Optional<MemberEntity> findByEmail(String email);

@Query(value = "select m from member m where m.deletedAt is null order by m.createdAt desc",
countQuery = "select count(m) from member m")
Page<MemberEntity> findAllOffsetPaging(Pageable pageable);

@Query(value = "select m from member m where m.deletedAt is null order by m.createdAt desc",
countQuery = "select count(m) from member m")
Slice<MemberEntity> findAllSlicePaging(Pageable pageable);
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
package org.store.clothstar.member.repository;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.store.clothstar.member.entity.MemberEntity;

import java.util.List;
Expand All @@ -8,6 +11,10 @@
public interface MemberRepository {
List<MemberEntity> findAll();

Page<MemberEntity> findAllOffsetPaging(Pageable pageable);

Slice<MemberEntity> findAllSlicePaging(Pageable pageable);

Optional<MemberEntity> findById(Long memberId);

Optional<MemberEntity> findByEmail(String email);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
package org.store.clothstar.member.service;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.store.clothstar.member.dto.request.CreateMemberRequest;
import org.store.clothstar.member.dto.request.ModifyMemberRequest;
import org.store.clothstar.member.dto.response.MemberResponse;

import java.util.List;

public interface MemberService {
List<MemberResponse> findAll();
Page<MemberResponse> getAllMemberOffsetPaging(Pageable pageable);

Slice<MemberResponse> getAllMemberSlicePaging(Pageable pageable);

MemberResponse getMemberById(Long memberId);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import jakarta.transaction.Transactional;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.store.clothstar.common.error.ErrorCode;
Expand All @@ -17,9 +20,6 @@
import org.store.clothstar.member.entity.MemberEntity;
import org.store.clothstar.member.repository.MemberRepository;

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

/**
* 기존 Mybatis기능과 Jpa기능이 같이 있는 서비스 로직을 구현한 클래스
* - memberJpaRepositoryAdapter클래스가 Jpa 기능으로 구현한 클래스
Expand All @@ -37,10 +37,15 @@ public class MemberServiceImpl implements MemberService {
private final RedisUtil redisUtil;

@Override
public List<MemberResponse> findAll() {
return memberRepository.findAll().stream()
.map(MemberResponse::new)
.collect(Collectors.toList());
public Page<MemberResponse> getAllMemberOffsetPaging(Pageable pageable) {
return memberRepository.findAllOffsetPaging(pageable)
.map(MemberResponse::new);
}

@Override
public Slice<MemberResponse> getAllMemberSlicePaging(Pageable pageable) {
return memberRepository.findAllSlicePaging(pageable)
.map(MemberResponse::new);
}

@Override
Expand Down
133 changes: 133 additions & 0 deletions src/main/resources/templates/memberOffsetList.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
<!DOCTYPE html>
<html>
<head>
<title>Members List</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<style>
.pagination {
justify-content: center;
margin-top: 20px;
}

.pagination .page-item.active .page-link {
z-index: 3;
color: #fff;
background-color: #007bff;
border-color: #007bff;
}
</style>
</head>
<body>
<div class="container">
<h1>Members List</h1>
<table class="table">
<thead class="thead-dark">
<tr>
<th>ID</th>
<th>Name</th>
<th>Created At</th>
</tr>
</thead>
<tbody id="members-table-body">
<!-- JavaScript로 데이터 로드 -->
</tbody>
</table>
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center" id="pagination-links">
<!-- 페이징 버튼이 여기에 추가됩니다. -->
</ul>
</nav>
</div>

<script>
document.addEventListener('DOMContentLoaded', function () {
loadMembers();
});

function loadMembers(page = 0) {
const url = `/v1/members?page=${page}`;
const accessToken = localStorage.getItem("ACCESS_TOKEN");
let headersObj = new Object();
headersObj["Content-Type"] = "application/json";

if (accessToken) {
headersObj["Authorization"] = accessToken;
}

fetch(url, {
method: "GET",
headers: headersObj,
}).then(response => response.json())
.then(data => {
const tableBody = document.getElementById('members-table-body');
tableBody.innerHTML = ''; // 기존 내용을 지웁니다.
data.content.forEach(member => {
const row = `
<tr>
<td>${member.memberId}</td>
<td>${member.name}</td>
<td>${member.createdAt}</td>
</tr>
`;
tableBody.innerHTML += row;
});

// 페이징 링크 업데이트
updatePagination(data);
})
.catch(error => {
console.error('Error fetching member data:', error);
});
}

function updatePagination(data) {
const paginationElement = document.getElementById('pagination-links');
paginationElement.innerHTML = '';

const totalPages = data.totalPages;
const currentPage = data.number;

const pagesToShow = 10; // 한 번에 보일 페이지 수

// 시작 페이지와 끝 페이지 계산
let startPage = Math.max(0, currentPage - Math.floor(pagesToShow / 2));
let endPage = Math.min(totalPages - 1, startPage + pagesToShow - 1);

if (endPage - startPage + 1 < pagesToShow) {
startPage = Math.max(0, endPage - pagesToShow + 1);
}

if (startPage > 0) {
addPaginationLink('Previous', currentPage - 1);
}

for (let i = startPage; i <= endPage; i++) {
addPaginationLink(i + 1, i, currentPage);
}

if (endPage < totalPages - 1) {
addPaginationLink('Next', currentPage + 1);
}
}

function addPaginationLink(text, page, currentPage) {
const paginationElement = document.getElementById('pagination-links');
const li = document.createElement('li');
li.classList.add('page-item');
if (page === currentPage) {
li.classList.add('active');
}
const pageLink = document.createElement('a');
pageLink.classList.add('page-link');
pageLink.href = '#';
pageLink.textContent = text;
pageLink.addEventListener('click', function (event) {
event.preventDefault();
loadMembers(page);
});
li.appendChild(pageLink);
paginationElement.appendChild(li);
}
</script>
</body>
</html>
Loading

0 comments on commit e6bfe14

Please sign in to comment.