[Practice] 관리자 API 만들기 (6)

2021. 4. 15. 14:40Spring/Practice

1. 문제

  • 사용자가 로그인을 했을 때 이에 대한 접속 이력이 저장된다고 한다면, 이에 대한 접속 이력을 조회하는 API
  • 접속 이력 정보가 있다는 가정하에 API 작성
  • UserLoginHistory 엔터티를 통해 구현

 

 

2. 풀이

- schema.sql

DROP TABLE IF EXISTS USER;
DROP TABLE IF EXISTS NOTICE;

create table USER (
    ID          BIGINT auto_increment primary key,
    EMAIL       VARCHAR(255),
    NAME        VARCHAR(255),
    PASSWORD    VARCHAR(255),
    PHONE       VARCHAR(255),
    REG_DATE    TIMESTAMP,
    UPDATE_DATE TIMESTAMP,
    STATUS      INTEGER
);

create table NOTICE (
    ID          BIGINT auto_increment primary key,
    TITLE       VARCHAR(255),
    CONTENTS    VARCHAR(255),

    HITS        INTEGER,
    LIKES       INTEGER,

    REG_DATE    TIMESTAMP,
    UPDATE_DATE TIMESTAMP,
    DELETED     BOOLEAN DEFAULT FALSE,
    DELETED_DATE    TIMESTAMP,

    USER_ID     BIGINT,
    constraint FK_NOTICE_USER_ID foreign key(USER_ID) references USER(ID)
);

create table NOTICE_LIKE (
    ID          BIGINT auto_increment primary key,

    NOTICE_ID   BIGINT,
    constraint FK_NOTICE_LIKE_NOTICE_ID foreign key(NOTICE_ID) references NOTICE(ID),

    USER_ID     BIGINT,
    constraint FK_NOTICE_LIKE_USER_ID foreign key(USER_ID) references USER(ID)
);

create table USER_LOGIN_HISTORY (
    ID          BIGINT auto_increment primary key,
    USER_ID     BIGINT,
    EMAIL       VARCHAR(255),
    NAME        VARCHAR(255),
    LOGIN_DATE  TIMESTAMP,
    IP_ADDR     VARCHAR(255)
);

- UserLoginHistory.java

package com.example.jpa.sample.user.entity;

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

import javax.persistence.*;
import java.time.LocalDateTime;

@AllArgsConstructor
@NoArgsConstructor
@Builder
@Data
@Entity
public class UserLoginHistory {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private long userId;

    @Column
    private String email;

    @Column
    private String name;

    @Column
    private LocalDateTime loginDate;

    @Column
    private String ipAddr;
}

- ApiAdminUserController.java

package com.example.jpa.sample.user.controller;

import com.example.jpa.sample.notice.repository.NoticeRepository;
import com.example.jpa.sample.user.entity.User;
import com.example.jpa.sample.user.entity.UserLoginHistory;
import com.example.jpa.sample.user.exception.UserNotFoundException;
import com.example.jpa.sample.user.model.ResponseMessage;
import com.example.jpa.sample.user.model.UserSearch;
import com.example.jpa.sample.user.model.UserStatusInput;
import com.example.jpa.sample.user.repository.UserLoginHistoryRepository;
import com.example.jpa.sample.user.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Optional;

@RequiredArgsConstructor
@RestController
public class ApiAdminUserController {

    private final UserRepository userRepository;
    private final NoticeRepository noticeRepository;
    private final UserLoginHistoryRepository userLoginHistoryRepository;

    /*
    // 문제 1
    @GetMapping("/api/admin/user")
    public ResponseMessage userList() {

        Long totalUserCount = userRepository.count();
        List<User> userList = userRepository.findAll();

        return ResponseMessage.builder()
                .totalCount(totalUserCount)
                .data(userList)
                .build();
    }
     */

    // 문제 2
    @GetMapping("/api/admin/user/{id}")
    public ResponseEntity<?> userDetail(@PathVariable Long id) {

        Optional<User> user = userRepository.findById(id);
        if(!user.isPresent()) {
            return new ResponseEntity<>(ResponseMessage.fail("사용자 정보가 존재하지 않습니다."), HttpStatus.BAD_REQUEST);
        }

        return ResponseEntity.ok().body(ResponseMessage.success(user));
    }

    // 문제 3
    @GetMapping("/api/admin/user/search")
    public ResponseEntity<?> findUser(@RequestBody UserSearch userSearch) {
        List<User> userList = userRepository.findByEmailContainsOrPhoneContainsOrNameContains(userSearch.getEmail(), userSearch.getPhone(), userSearch.getName());

        return ResponseEntity.ok().body(ResponseMessage.success(userList));
    }

    // 문제 4
    @PatchMapping("/api/admin/user/{id}/status")
    public ResponseEntity<?> userStatus(@PathVariable Long id, @RequestBody UserStatusInput userStatusInput) {

        Optional<User> optionalUser = userRepository.findById(id);
        if(!optionalUser.isPresent()) {
            return new ResponseEntity<>(ResponseMessage.fail("사용자 정보가 존재하지 않습니다."), HttpStatus.BAD_REQUEST);
        }
        User user = optionalUser.get();

        user.setStatus(userStatusInput.getStatus());
        userRepository.save(user);

        return ResponseEntity.ok().build();
    }

    // 문제 5
    @DeleteMapping("/api/admin/user/{id}")
    public ResponseEntity<?> deleteUser(@PathVariable Long id) {
        Optional<User> optionalUser = userRepository.findById(id);
        if(!optionalUser.isPresent()) {
            return new ResponseEntity<>(ResponseMessage.fail("사용자 정보가 존재하지 않습니다."), HttpStatus.BAD_REQUEST);
        }
        User user = optionalUser.get();

        if(noticeRepository.coundByUser(user) > 0) {
            return new ResponseEntity<>(ResponseMessage.fail("사용자가 작성한 공지사항이 있습니다."), HttpStatus.BAD_REQUEST);
        }

        userRepository.delete(user);
        return ResponseEntity.ok().build();
    }

    // 문제 6
    @GetMapping("/api/admin/user/login/history")
    public ResponseEntity<?> userLoginHistory() {
        List<UserLoginHistory> userLoginHistoryList = userLoginHistoryRepository.findAll();

        return ResponseEntity.ok().body(userLoginHistoryList);
    }

}
728x90