Skip to content

Commit

Permalink
✨ feat(admin): add user static and user detail (#208)
Browse files Browse the repository at this point in the history
  • Loading branch information
seonghun-dev authored Jul 14, 2023
1 parent 3fb5e95 commit 24772b1
Show file tree
Hide file tree
Showing 23 changed files with 653 additions and 119 deletions.
Original file line number Diff line number Diff line change
@@ -1,14 +1,20 @@
package com.depromeet.apis.item.repository;

import com.depromeet.item.Item;
import com.depromeet.user.User;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;

import java.util.List;

public interface ItemRepository extends JpaRepository<Item, Long> {

@Query(value = "select i from Item i join fetch i.song s join fetch s.album a join fetch a.artist ar join fetch i.itemLocation il join fetch il.villageArea va join fetch i.user u",
countQuery = "select count(i) from Item i")
Page<Item> findAll(Pageable pageable);

@Query(value = "select i from Item i join fetch i.song s join fetch s.album a join fetch a.artist ar join fetch i.itemLocation il join fetch il.villageArea va join fetch i.user u where u = :user order by i.createdAt desc ")
List<Item> findByUser(User user);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,35 +3,39 @@

import com.depromeet.apis.user.dto.ResponseDto;
import com.depromeet.apis.user.dto.UserAllResponseDto;
import com.depromeet.apis.user.dto.UserCountResponseDto;
import com.depromeet.apis.user.dto.UserDetailResponseDto;
import com.depromeet.apis.user.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.web.PageableDefault;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
private final UserService userService;

@GetMapping
public ResponseEntity<UserAllResponseDto> getAllUsers(
@PageableDefault(size = 20, page = 0, sort = "createdAt",
direction = Sort.Direction.DESC) Pageable pageable
) {
var response = userService.getAllUsers(pageable);
return ResponseDto.ok(response);
}

@GetMapping("/users")
public ResponseEntity<UserAllResponseDto> getUsers(
@PageableDefault(size = 20, page = 0, sort = "createdAt",
direction = Sort.Direction.DESC) Pageable pageable
) {
var response = userService.searchAllUsers(pageable);
return ResponseDto.ok(response);
}

@GetMapping("/users/count")
public ResponseEntity<List<UserCountResponseDto>> getUsersCount() {
var response= userService.countUsersByCreatedAt();
return ResponseEntity.ok(response);
}
@GetMapping("/{userId}")
public ResponseEntity<UserDetailResponseDto> getUserDetail(
@PathVariable("userId") Long userId
) {
var response = userService.getUserDetail(userId);
return ResponseDto.ok(response);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.depromeet.apis.user.controller;

import com.depromeet.apis.user.dto.UserAllStaticCountDto;
import com.depromeet.apis.user.dto.UserSignUpCountRequestDto;
import com.depromeet.apis.user.dto.UserSignUpCountResponseDto;
import com.depromeet.apis.user.service.UserStaticService;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/users/statical")
@RequiredArgsConstructor
public class UserStaticalController {

private final UserStaticService userService;

@GetMapping("/signup/count")
public ResponseEntity<List<UserSignUpCountResponseDto>> getUserSignUpCount(
UserSignUpCountRequestDto userSignUpCountRequestDto
) {
var response = userService.getUserSignUpCount(userSignUpCountRequestDto);
return ResponseEntity.ok(response);
}

@GetMapping("/all/count")
public ResponseEntity<UserAllStaticCountDto> getAllUserCount() {
var response = userService.getAllUserCount();
return ResponseEntity.ok(response);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.depromeet.apis.user.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
@Getter
public class UserActivityResponseDto {
private String title;
private String content;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.depromeet.apis.user.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@AllArgsConstructor
@NoArgsConstructor
@Getter
public class UserAllStaticCountDto {
private Long allUserCount;
private int todayUserCount;
private int dropUserCount;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.depromeet.apis.user.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.time.LocalDateTime;

@NoArgsConstructor
@AllArgsConstructor
@Getter
public class UserBasicInfoResponseDto {
private Long id;
private String nickname;
private String idfv;
private LocalDateTime createdAt;
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.depromeet.apis.user.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@AllArgsConstructor
@Getter
public class UserDetailInfoResponseDto {
private int allDropCount;
private String mainDropLocation;
private String dropLocations;
private String interestGenre;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package com.depromeet.apis.user.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@NoArgsConstructor
@AllArgsConstructor
@Getter
public class UserDetailResponseDto {
private UserBasicInfoResponseDto userBasicInfo;
private UserDetailInfoResponseDto userDetailInfo;
private List<UserActivityResponseDto> userActivity;
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,5 @@ public class UserResponseDto {
private Long id;
private String nickname;
private String idfv;

public UserResponseDto(User user){
this.id = user.getId();
this.nickname = user.getNickname();
this.idfv = user.getIdfv();
}
private String createdAt;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package com.depromeet.apis.user.dto;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

import java.time.LocalDateTime;

@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
public class UserSignUpCountRequestDto {
private LocalDateTime startDate = LocalDateTime.now().minusDays(7);
private LocalDateTime endDate = LocalDateTime.now();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.depromeet.apis.user.dto;

public record UserSignUpCountResponseDto(String date, Long count) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,30 @@
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.time.LocalDateTime;
import java.util.List;

public interface UserRepository extends JpaRepository<User, Long> {

Page<User> findAll(Pageable pageable);
Page<User> findAll(Pageable pageable);

@Query(value = "SELECT DATE_FORMAT(u.createdAt, '%m.%d') AS joinDate, COUNT(u.id) AS joinCount FROM User u WHERE u.createdAt BETWEEN :startDate AND :endDate GROUP BY joinDate")
List<Object[]> countUserByCreatedAt(@Param("startDate") LocalDateTime startDate, @Param("endDate") LocalDateTime endDate);

@Query(value = "SELECT COUNT(DISTINCT u.id) AS dropped_users_count FROM User u JOIN Item i ON u.id = i.user.id")
int countUserByDropCountIsNotNull();


@Query(value = "SELECT village_area.village_name, COUNT(item.item_id) AS item_count FROM users " +
"JOIN item ON users.user_id = item.user_id JOIN item_location ON item_location.item_id = item.item_id " +
"JOIN village_area ON village_area.village_id = item_location.village_id " +
"WHERE users.user_id = :userId " +
"GROUP BY users.user_id, village_area.village_name " +
"ORDER BY item_count DESC",
nativeQuery = true
)
List<Object[]> countUserDropItemByVillage(@Param("userId") Long userId);

@Query(value = "SELECT DATE_FORMAT(u.createdAt, '%m.%d') AS joinDate, COUNT(u.id) AS joinCount FROM User u GROUP BY joinDate")
List<Object[]> countUserByCreatedAt();
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
package com.depromeet.apis.user.service;

import com.depromeet.apis.common.dto.PageMetaData;
import com.depromeet.apis.user.dto.UserAllResponseDto;
import com.depromeet.apis.user.dto.UserCountResponseDto;
import com.depromeet.apis.user.dto.UserResponseDto;
import com.depromeet.apis.item.repository.ItemRepository;
import com.depromeet.apis.user.dto.*;
import com.depromeet.apis.user.repository.UserRepository;
import com.depromeet.user.User;
import lombok.RequiredArgsConstructor;
Expand All @@ -12,41 +11,64 @@
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;

@Transactional(readOnly = true)
public UserAllResponseDto searchAllUsers(Pageable pageable) {
Page<User> user = userRepository.findAll(pageable);
PageMetaData pageMetaData = new PageMetaData(
user.getNumber(),
user.getSize(),
(int) user.getTotalElements(),
user.getTotalPages()
);
List<UserResponseDto> users = user.getContent()
.stream()
.map(UserResponseDto::new)
.toList();
return new UserAllResponseDto(users, pageMetaData);
}

@Transactional
public List<UserCountResponseDto> countUsersByCreatedAt() {
List<Object[]> result = userRepository.countUserByCreatedAt();
List<UserCountResponseDto> userCountResponseDtos = new ArrayList<>();

for (Object[] row : result) {
String joinDate = (String) row[0];
Long count = (Long) row[1];
UserCountResponseDto userCountResponseDto = new UserCountResponseDto(joinDate, count);
userCountResponseDtos.add(userCountResponseDto);
}
return userCountResponseDtos;
}
private final UserRepository userRepository;
private final ItemRepository itemRepository;

@Transactional(readOnly = true)
public UserAllResponseDto getAllUsers(Pageable pageable) {
Page<User> user = userRepository.findAll(pageable);
PageMetaData pageMetaData = new PageMetaData(
user.getNumber(),
user.getSize(),
(int) user.getTotalElements(),
user.getTotalPages()
);
List<UserResponseDto> users = user.getContent()
.stream()
.map(
u -> new UserResponseDto(
u.getId(),
u.getNickname(),
u.getIdfv(),
u.getCreatedAt().toString()
)
)
.toList();
return new UserAllResponseDto(users, pageMetaData);
}


@Transactional(readOnly = true)
public UserDetailResponseDto getUserDetail(Long userId) {

User user = userRepository.findById(userId).orElseThrow();
var userBasicInfoResponseDto = new UserBasicInfoResponseDto(user.getId(), user.getNickname(), user.getIdfv(), user.getCreatedAt());

List<Object[]> result = userRepository.countUserDropItemByVillage(userId);

String mainDropLocation = result.isEmpty() ? "현재 드랍한 아이템이 없습니다." : result.get(0)[0].toString();
StringBuilder dropLocations = new StringBuilder(result.isEmpty() ? "현재 드랍한 아이템이 없습니다." : "");
int allDropCount = 0;

for (Object[] row : result) {
dropLocations.append(row[0].toString()).append("[").append(row[1].toString()).append("]").append(", ");
allDropCount += Integer.parseInt(row[1].toString());
}
var userDetailInfoResponseDto = new UserDetailInfoResponseDto(allDropCount, mainDropLocation, dropLocations.toString(), "지원 예정");

var userActivityResponseDtoList = itemRepository.findByUser(user).stream().map(
item -> {
String title = "'" + item.getItemLocation().getName() + "'" + " 에 아이템을 드랍했습니다.";
String content = "'" + item.getSong().getName() + "' 곡을 '" + item.getContent() + "' 의 내용을 드랍했습니다.";
return new UserActivityResponseDto(title, content);
}
).toList();

return new UserDetailResponseDto(userBasicInfoResponseDto, userDetailInfoResponseDto, userActivityResponseDtoList);
}
}
Loading

0 comments on commit 24772b1

Please sign in to comment.