관리자 - 회원리스트 API
This commit is contained in:
parent
9b4e2fd192
commit
cbcc63dc71
|
@ -0,0 +1,23 @@
|
|||
package kr.co.vividnext.sodalive.admin.member
|
||||
|
||||
import kr.co.vividnext.sodalive.common.ApiResponse
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.security.access.prepost.PreAuthorize
|
||||
import org.springframework.web.bind.annotation.GetMapping
|
||||
import org.springframework.web.bind.annotation.RequestMapping
|
||||
import org.springframework.web.bind.annotation.RequestParam
|
||||
import org.springframework.web.bind.annotation.RestController
|
||||
|
||||
@RestController
|
||||
@RequestMapping("/admin/member")
|
||||
class AdminMemberController(private val service: AdminMemberService) {
|
||||
@GetMapping("/list")
|
||||
@PreAuthorize("hasRole('ADMIN')")
|
||||
fun getMemberList(pageable: Pageable) = ApiResponse.ok(service.getMemberList(pageable))
|
||||
|
||||
@GetMapping("/search")
|
||||
fun searchMember(
|
||||
@RequestParam(value = "search_word") searchWord: String,
|
||||
pageable: Pageable
|
||||
) = ApiResponse.ok(service.searchMember(searchWord, pageable))
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
package kr.co.vividnext.sodalive.admin.member
|
||||
|
||||
import com.querydsl.jpa.impl.JPAQueryFactory
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.member.MemberRole
|
||||
import kr.co.vividnext.sodalive.member.QMember.member
|
||||
import org.springframework.data.jpa.repository.JpaRepository
|
||||
|
||||
interface AdminMemberRepository : JpaRepository<Member, Long>, AdminMemberQueryRepository
|
||||
|
||||
interface AdminMemberQueryRepository {
|
||||
fun getMemberTotalCount(role: MemberRole? = null): Int
|
||||
fun getMemberList(offset: Long, limit: Long, role: MemberRole? = null): List<Member>
|
||||
fun searchMember(searchWord: String, offset: Long, limit: Long, role: MemberRole? = null): List<Member>
|
||||
|
||||
fun searchMemberTotalCount(searchWord: String, role: MemberRole? = null): Int
|
||||
}
|
||||
|
||||
class AdminMemberQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) : AdminMemberQueryRepository {
|
||||
override fun getMemberList(offset: Long, limit: Long, role: MemberRole?): List<Member> {
|
||||
return queryFactory
|
||||
.selectFrom(member)
|
||||
.where(
|
||||
member.role.ne(MemberRole.ADMIN)
|
||||
.and(
|
||||
if (role != null) {
|
||||
member.role.eq(role)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
)
|
||||
)
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
.orderBy(member.id.desc())
|
||||
.fetch()
|
||||
}
|
||||
|
||||
override fun getMemberTotalCount(role: MemberRole?): Int {
|
||||
return queryFactory
|
||||
.select(member.id)
|
||||
.from(member)
|
||||
.where(
|
||||
member.id.gt(1)
|
||||
.and(
|
||||
if (role != null) {
|
||||
member.role.eq(role)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
)
|
||||
)
|
||||
.fetch()
|
||||
.size
|
||||
}
|
||||
|
||||
override fun searchMember(searchWord: String, offset: Long, limit: Long, role: MemberRole?): List<Member> {
|
||||
return queryFactory
|
||||
.selectFrom(member)
|
||||
.where(
|
||||
member.nickname.contains(searchWord)
|
||||
.or(member.email.contains(searchWord))
|
||||
.and(
|
||||
if (role != null) {
|
||||
member.role.eq(role)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
)
|
||||
)
|
||||
.offset(offset)
|
||||
.limit(limit)
|
||||
.orderBy(member.id.desc())
|
||||
.fetch()
|
||||
}
|
||||
|
||||
override fun searchMemberTotalCount(searchWord: String, role: MemberRole?): Int {
|
||||
return queryFactory
|
||||
.select(member.id)
|
||||
.from(member)
|
||||
.where(
|
||||
member.nickname.contains(searchWord)
|
||||
.or(member.email.contains(searchWord))
|
||||
.and(
|
||||
if (role != null) {
|
||||
member.role.eq(role)
|
||||
} else {
|
||||
null
|
||||
}
|
||||
)
|
||||
)
|
||||
.fetch()
|
||||
.size
|
||||
}
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
package kr.co.vividnext.sodalive.admin.member
|
||||
|
||||
import kr.co.vividnext.sodalive.common.SodaException
|
||||
import kr.co.vividnext.sodalive.member.Member
|
||||
import kr.co.vividnext.sodalive.member.MemberRole
|
||||
import org.springframework.beans.factory.annotation.Value
|
||||
import org.springframework.data.domain.Pageable
|
||||
import org.springframework.stereotype.Service
|
||||
import java.time.ZoneId
|
||||
import java.time.format.DateTimeFormatter
|
||||
|
||||
@Service
|
||||
class AdminMemberService(
|
||||
private val repository: AdminMemberRepository,
|
||||
|
||||
@Value("\${cloud.aws.cloud-front.host}")
|
||||
private val cloudFrontHost: String
|
||||
) {
|
||||
fun getMemberList(pageable: Pageable): GetAdminMemberListResponse {
|
||||
val totalCount = repository.getMemberTotalCount()
|
||||
val memberList = processMemberListToGetAdminMemberListResponseItemList(
|
||||
memberList = repository.getMemberList(
|
||||
offset = pageable.offset,
|
||||
limit = pageable.pageSize.toLong()
|
||||
)
|
||||
)
|
||||
|
||||
return GetAdminMemberListResponse(totalCount, memberList)
|
||||
}
|
||||
|
||||
fun searchMember(searchWord: String, pageable: Pageable): GetAdminMemberListResponse {
|
||||
if (searchWord.length < 2) throw SodaException("2글자 이상 입력하세요.")
|
||||
val totalCount = repository.searchMemberTotalCount(searchWord = searchWord)
|
||||
val memberList = processMemberListToGetAdminMemberListResponseItemList(
|
||||
memberList = repository.searchMember(
|
||||
searchWord = searchWord,
|
||||
offset = pageable.offset,
|
||||
limit = pageable.pageSize.toLong()
|
||||
)
|
||||
)
|
||||
|
||||
return GetAdminMemberListResponse(totalCount, memberList)
|
||||
}
|
||||
|
||||
private fun processMemberListToGetAdminMemberListResponseItemList(
|
||||
memberList: List<Member>
|
||||
): List<GetAdminMemberListResponseItem> {
|
||||
return memberList
|
||||
.asSequence()
|
||||
.map {
|
||||
val userType = when (it.role) {
|
||||
MemberRole.ADMIN -> "관리자"
|
||||
MemberRole.USER -> "일반회원"
|
||||
MemberRole.CREATOR -> "요즘친구"
|
||||
MemberRole.AGENT -> "에이전트"
|
||||
MemberRole.BOT -> "봇"
|
||||
}
|
||||
|
||||
val signUpDate = it.createdAt!!
|
||||
.atZone(ZoneId.of("UTC"))
|
||||
.withZoneSameInstant(ZoneId.of("Asia/Seoul"))
|
||||
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
|
||||
|
||||
val signOutDate = if (it.signOutReasons.isNotEmpty()) {
|
||||
it.signOutReasons.last().createdAt!!
|
||||
.atZone(ZoneId.of("UTC"))
|
||||
.withZoneSameInstant(ZoneId.of("Asia/Seoul"))
|
||||
.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"))
|
||||
} else {
|
||||
""
|
||||
}
|
||||
|
||||
GetAdminMemberListResponseItem(
|
||||
id = it.id!!,
|
||||
email = it.email,
|
||||
nickname = it.nickname,
|
||||
profileUrl = if (it.profileImage != null) {
|
||||
"$cloudFrontHost/${it.profileImage}"
|
||||
} else {
|
||||
"$cloudFrontHost/profile/default-profile.png"
|
||||
},
|
||||
userType = userType,
|
||||
container = it.container,
|
||||
auth = it.auth != null,
|
||||
signUpDate = signUpDate,
|
||||
signOutDate = signOutDate,
|
||||
isActive = it.isActive
|
||||
)
|
||||
}
|
||||
.toList()
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package kr.co.vividnext.sodalive.admin.member
|
||||
|
||||
data class GetAdminMemberListResponse(
|
||||
val totalCount: Int,
|
||||
val items: List<GetAdminMemberListResponseItem>
|
||||
)
|
||||
|
||||
data class GetAdminMemberListResponseItem(
|
||||
val id: Long,
|
||||
val email: String,
|
||||
val nickname: String,
|
||||
val profileUrl: String,
|
||||
val userType: String,
|
||||
val container: String,
|
||||
val auth: Boolean,
|
||||
val signUpDate: String,
|
||||
val signOutDate: String,
|
||||
val isActive: Boolean
|
||||
)
|
Loading…
Reference in New Issue