1. 이전 포스팅

 

https://growingsaja.tistory.com/975

 

 

 

 

 

2. 목표

 

username, email 없이 fromip로 고유한 username을 대체하는 이용자 User 시스템 기능 구현

login 관련 정보 등을 추가해 정보 저장

로그인 시도시, 없는 계정이면 해당 fromIp 기준으로 계정 생성

 

 

 

 

 

3. 소스코드 수정

 

// vim entities/User.kt

package com.example.practicekopring.entities

import org.springframework.data.annotation.Id
import org.springframework.data.mongodb.core.mapping.Document
import java.time.LocalDateTime

@Document(collection = "users")
data class User(
    @Id
    val id: String? = null,
    var lastUpdatedAt_KST: String? = null,  // 데이터 최종 편집 일시 추가
    var lastUpdatedAt: LocalDateTime? = null,
    var createdAt_KST: String? = null,  // 데이터 초기 생성 일시 추가
    var createdAt: LocalDateTime? = null,
    var lastLoginAt_KST: String? = null,  // 최근 로그인 일시 추가
    var lastLoginAt: LocalDateTime? = null,
    var fromIp: String? = null, // 접속 ip : ip가 고유한 user name 역할을 합니다.
    val fromDevice_first: String? = null, // 첫 접속 디바이스
    var fromDevice_last: String? = null, // 최근 접속 디바이스
    val fromChannel_first: String? = null, // 첫 접속 채널
    var fromChannel_last: String? = null // 최근 접속 채널
)

data class UpdateUserInfo(
    val id: String? = null,
    val fromIp: String? = null
)

 

// vim repositories/UserRepository.kt

package com.example.practicekopring.repositories

import com.example.practicekopring.entities.User
import org.springframework.data.mongodb.repository.MongoRepository

// UserRepository 인터페이스는 User 엔터티와 관련된 데이터베이스 작업을 위한 Repository입니다.
interface UserRepository : MongoRepository<User, String> {
    fun findByFromIp(fromIp: String): User?
    fun findAllByOrderByFromIpAsc(): List<User>
    fun findByFromIpContaining(keyword: String): List<User>
}

 

// vim services/UserService.kt

package com.example.practicekopring.services

import com.example.practicekopring.entities.User
import com.example.practicekopring.entities.UpdateUserInfo
import com.example.practicekopring.repositories.UserRepository
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Pageable
import org.springframework.stereotype.Service
import java.time.LocalDateTime
import java.time.ZoneId

@Service
class UserService(private val userRepository: UserRepository) {

    // 1. 모든 사용자 조회
    fun getAllUsers(): List<User> {
        return userRepository.findAll()
    }

    // 2. 사용자 로그인 또는 생성
    fun loginUser(fromIp: String, fromDevice: String, fromChannel: String): User? {
        // 현재 일시 가져오기
        val currentTime = LocalDateTime.now()
        val currenctTime_KST = currentTime.atZone(ZoneId.of("Asia/Seoul")).toString().substring(0, 19).replace("T", " ")  // 데이터 최종 편집 일시 설정
        val userByFromIp = userRepository.findByFromIp(fromIp)

        if (userByFromIp == null) {
            // 로그인 실패시 회원가입 진행
            val user = User(fromIp = fromIp, fromDevice_first = fromDevice, fromChannel_first = fromChannel, fromDevice_last = fromDevice, fromChannel_last = fromChannel)
            user.createdAt = currentTime
            user.createdAt_KST = currenctTime_KST
            user.lastLoginAt = currentTime
            user.lastLoginAt_KST = currenctTime_KST
            return userRepository.save(user)
        } else {
            // 로그인 성공
            val id: String? = userByFromIp.id
            val existingUser = id?.let { userRepository.findById(it) }
            if (existingUser != null) {
                if (existingUser.isPresent) {
                    val userToUpdate = existingUser.get()
                    userToUpdate.fromIp = fromIp
                    // 작업 임시 저장
                    userToUpdate.lastLoginAt = currentTime
                    userToUpdate.lastLoginAt_KST = currenctTime_KST
                    userToUpdate.fromDevice_last = fromDevice
                    userToUpdate.fromChannel_last = fromChannel
                    return userRepository.save(userToUpdate)
                }
            } else {
                println("[ERROR] Login Fail. Not exist user.")
            }
            return null
        }
    }

    // 3. 사용자 업데이트
    fun updateUser(id: String, fromIp: String): User? {
        val existingUser = userRepository.findById(id)
        if (existingUser.isPresent) {
            val userToUpdate = existingUser.get()
            userToUpdate.fromIp = fromIp
            // 작업 일시 저장
            val currentTime = LocalDateTime.now()
            val currentTime_KST = currentTime.atZone(ZoneId.of("Asia/Seoul")).toString().substring(0, 19).replace("T", " ")  // 데이터 최종 편집 일시 설정
            // 한국 일시 저장
            userToUpdate.lastUpdatedAt = currentTime
            userToUpdate.lastUpdatedAt_KST = currentTime_KST
            return userRepository.save(userToUpdate)
        }
        return null
    }

    // 4. 사용자 업데이트 with body
    fun updateUserWithBody(user: UpdateUserInfo): User? {
        val existingUser = userRepository.findById(user.id ?: "")
        val userToUpdate = existingUser.get()
        userToUpdate.fromIp = user.fromIp ?: userToUpdate.fromIp
        // 작업 일시 저장
        val currentTime = LocalDateTime.now()
        userToUpdate.lastUpdatedAt = currentTime
        // 한국 일시 string 저장
        userToUpdate.lastUpdatedAt_KST = currentTime.atZone(ZoneId.of("Asia/Seoul")).toString().substring(0, 19).replace("T", " ")  // 데이터 최종 편집 일시 설정  // 데이터 최종 편집 일시 설정
        return userRepository.save(userToUpdate)
    }

    // 5. fromip로 검색
    fun searchUsersByFromIp(keyword: String): List<User> {
        return userRepository.findByFromIpContaining(keyword)
    }

    // 6. 사용자 삭제
    fun deleteUser(id: String) {
        userRepository.deleteById(id)
    }

    // 7. 사용자 카운트 조회
    fun getUserCount(): Long {
        return userRepository.count()
    }

    // 10. 사용자 정렬 조회 (예: 이름 오름차순)
    fun getUsersSortedByFromIp(): List<User> {
        return userRepository.findAllByOrderByFromIpAsc()
    }

    // 11. 특정 페이지의 사용자 조회 (페이징)
    fun getUsersByPage(page: Int, size: Int): Page<User> {
        val pageable: Pageable = PageRequest.of(page, size)
        return userRepository.findAll(pageable)
    }
}

 

// vim controllers/UserController.kt

package com.example.practicekopring.controllers

import com.example.practicekopring.entities.User
import com.example.practicekopring.entities.UpdateUserInfo
import com.example.practicekopring.services.UserService
import org.springframework.data.domain.Page
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.PutMapping
import org.springframework.web.bind.annotation.DeleteMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.bind.annotation.PathVariable


@RestController
@RequestMapping("/api/v1/users")
class UserController(private val userService: UserService) {

    // 1. 모든 사용자 조회
    @GetMapping("/")
    fun getAllUsers(): List<User> {
        return userService.getAllUsers()
    }

    // 2. 사용자 생성
    @PostMapping("/loginUser")
    fun loginUser(
        @RequestParam fromIp: String,
        @RequestParam fromDevice: String,
        @RequestParam fromChannel: String
    ): User? {
        return userService.loginUser(fromIp, fromDevice, fromChannel)
    }

    // 3. 사용자 업데이트
    @PutMapping("/{id}/update")
    fun updateUser(
        @PathVariable id: String,
        @RequestParam fromIp: String
    ): User? {
        val updatedUser = userService.updateUser(id, fromIp)
        return updatedUser
    }

    // 4. 사용자 업데이트 body 버전
    @PostMapping("/update-with-body")
    fun updateUserWithBody(
        @RequestBody user: UpdateUserInfo
    ): User? {
        val updatedUser = userService.updateUserWithBody(user)
        return updatedUser
    }

    // 5. 사용자 검색
    @PostMapping("/search-user-by-fromip")
    fun searchUsersByFromIp(
        @RequestParam keyword: String
    ): List<User> {
        return userService.searchUsersByFromIp(keyword)
    }


    // 6. 사용자 삭제
    @DeleteMapping("/{id}/delete")
    fun deleteUser(
        @PathVariable id: String
    ) {
        userService.deleteUser(id)
    }

    // 7. 사용자 카운트 조회
    @GetMapping("/count")
    fun getUserCount(): Long {
        return userService.getUserCount()
    }

    // 10. 사용자 정렬 조회 (예: 이름 오름차순)
    @GetMapping("/sorted")
    fun getUsersSortedByName(): List<User> {
        return userService.getUsersSortedByFromIp()
    }

    // 11. 특정 페이지의 사용자 조회 (페이징)
    @GetMapping("/paged")
    fun getUsersByPage(
        @RequestParam page: Int,
        @RequestParam size: Int
    ): Page<User> {
        return userService.getUsersByPage(page, size)
    }
}

 

 

 

 

 

4. 없는 계정으로 로그인 시도

 

 = 회원가입 처리 진행 정상적으로 되는거 확인

 

 

 

 

 

 

 

5. 있는 계정으로 로그인 시도

 

있는 계정이므로, 있는 해당 데이터의 일부를 수정합니다.

 

 

 

 

 

+ Recent posts