| @@ -340,6 +340,7 @@ class AudioContentQueryRepositoryImpl(private val queryFactory: JPAQueryFactory) | |||||||
|                 ) |                 ) | ||||||
|             ) |             ) | ||||||
|             .from(audioContent) |             .from(audioContent) | ||||||
|  |             .innerJoin(audioContent.member, member) | ||||||
|             .where(where) |             .where(where) | ||||||
|             .orderBy(audioContent.id.desc()) |             .orderBy(audioContent.id.desc()) | ||||||
|             .fetch() |             .fetch() | ||||||
|   | |||||||
| @@ -0,0 +1,3 @@ | |||||||
|  | package kr.co.vividnext.sodalive.member | ||||||
|  |  | ||||||
|  | data class GetChangeNicknamePriceResponse(val price: Int) | ||||||
| @@ -22,6 +22,18 @@ import org.springframework.web.multipart.MultipartFile | |||||||
| @RestController | @RestController | ||||||
| @RequestMapping("/member") | @RequestMapping("/member") | ||||||
| class MemberController(private val service: MemberService) { | class MemberController(private val service: MemberService) { | ||||||
|  |     @GetMapping("/check/email") | ||||||
|  |     fun checkEmail(@RequestParam email: String) = service.duplicateCheckEmail(email) | ||||||
|  |  | ||||||
|  |     @GetMapping("/check/nickname") | ||||||
|  |     fun checkNickname(@RequestParam nickname: String) = service.duplicateCheckNickname(nickname) | ||||||
|  |  | ||||||
|  |     @PutMapping("/change/nickname") | ||||||
|  |     fun changeNickname( | ||||||
|  |         @RequestBody profileUpdateRequest: ProfileUpdateRequest, | ||||||
|  |         @AuthenticationPrincipal user: User | ||||||
|  |     ) = ApiResponse.ok(service.updateNickname(profileUpdateRequest, user)) | ||||||
|  |  | ||||||
|     @PostMapping("/signup") |     @PostMapping("/signup") | ||||||
|     fun signUp( |     fun signUp( | ||||||
|         @RequestPart("profileImage", required = false) profileImage: MultipartFile? = null, |         @RequestPart("profileImage", required = false) profileImage: MultipartFile? = null, | ||||||
| @@ -50,6 +62,16 @@ class MemberController(private val service: MemberService) { | |||||||
|         ApiResponse.ok(service.logoutAll(member.id!!)) |         ApiResponse.ok(service.logoutAll(member.id!!)) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     @GetMapping | ||||||
|  |     fun getMember( | ||||||
|  |         @RequestParam container: String, | ||||||
|  |         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||||
|  |     ) = run { | ||||||
|  |         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||||
|  |  | ||||||
|  |         ApiResponse.ok(service.getMember(member.id!!, container)) | ||||||
|  |     } | ||||||
|  |  | ||||||
|     @GetMapping("/info") |     @GetMapping("/info") | ||||||
|     fun getMemberInfo( |     fun getMemberInfo( | ||||||
|         @RequestParam container: String?, |         @RequestParam container: String?, | ||||||
| @@ -151,4 +173,24 @@ class MemberController(private val service: MemberService) { | |||||||
|         @RequestBody signOutRequest: SignOutRequest, |         @RequestBody signOutRequest: SignOutRequest, | ||||||
|         @AuthenticationPrincipal user: User |         @AuthenticationPrincipal user: User | ||||||
|     ) = ApiResponse.ok(service.signOut(signOutRequest, user), "정상적으로 탈퇴 처리되었습니다.") |     ) = ApiResponse.ok(service.signOut(signOutRequest, user), "정상적으로 탈퇴 처리되었습니다.") | ||||||
|  |  | ||||||
|  |     @GetMapping("/change/nickname/price") | ||||||
|  |     fun getChangeNicknamePrice( | ||||||
|  |         @AuthenticationPrincipal(expression = "#this == 'anonymousUser' ? null : member") member: Member? | ||||||
|  |     ) = run { | ||||||
|  |         if (member == null) throw SodaException("로그인 정보를 확인해주세요.") | ||||||
|  |         ApiResponse.ok(service.getChangeNicknamePrice(memberId = member.id!!)) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @PutMapping | ||||||
|  |     fun profileUpdate( | ||||||
|  |         @RequestBody profileUpdateRequest: ProfileUpdateRequest, | ||||||
|  |         @AuthenticationPrincipal user: User | ||||||
|  |     ) = ApiResponse.ok(service.profileUpdate(profileUpdateRequest, user)) | ||||||
|  |  | ||||||
|  |     @PostMapping("/image") | ||||||
|  |     fun profileImageUpdate( | ||||||
|  |         @RequestParam("image") multipartFile: MultipartFile, | ||||||
|  |         @AuthenticationPrincipal user: User | ||||||
|  |     ) = ApiResponse.ok(service.profileImageUpdate(multipartFile, user)) | ||||||
| } | } | ||||||
|   | |||||||
| @@ -7,6 +7,7 @@ import kr.co.vividnext.sodalive.member.QMember.member | |||||||
| import kr.co.vividnext.sodalive.member.auth.QAuth.auth | import kr.co.vividnext.sodalive.member.auth.QAuth.auth | ||||||
| import kr.co.vividnext.sodalive.member.block.BlockMemberRepository | import kr.co.vividnext.sodalive.member.block.BlockMemberRepository | ||||||
| import kr.co.vividnext.sodalive.member.following.QCreatorFollowing.creatorFollowing | import kr.co.vividnext.sodalive.member.following.QCreatorFollowing.creatorFollowing | ||||||
|  | import kr.co.vividnext.sodalive.member.nickname.QNicknameChangeLog.nicknameChangeLog | ||||||
| import kr.co.vividnext.sodalive.member.notification.QMemberNotification.memberNotification | import kr.co.vividnext.sodalive.member.notification.QMemberNotification.memberNotification | ||||||
| import kr.co.vividnext.sodalive.message.QMessage.message | import kr.co.vividnext.sodalive.message.QMessage.message | ||||||
| import org.springframework.data.jpa.repository.JpaRepository | import org.springframework.data.jpa.repository.JpaRepository | ||||||
| @@ -37,6 +38,7 @@ interface MemberQueryRepository { | |||||||
|  |  | ||||||
|     fun getMessageRecipientPushToken(messageId: Long): GetMessageRecipientPushTokenResponse |     fun getMessageRecipientPushToken(messageId: Long): GetMessageRecipientPushTokenResponse | ||||||
|     fun getIndividualRecipientPushTokens(recipients: List<Long>, isAuth: Boolean): Map<String, List<List<String>>> |     fun getIndividualRecipientPushTokens(recipients: List<Long>, isAuth: Boolean): Map<String, List<List<String>>> | ||||||
|  |     fun getChangeNicknamePrice(memberId: Long): GetChangeNicknamePriceResponse | ||||||
| } | } | ||||||
|  |  | ||||||
| @Repository | @Repository | ||||||
| @@ -210,4 +212,21 @@ class MemberQueryRepositoryImpl( | |||||||
|  |  | ||||||
|         return mapOf("aos" to aosPushTokens, "ios" to iosPushTokens) |         return mapOf("aos" to aosPushTokens, "ios" to iosPushTokens) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     override fun getChangeNicknamePrice(memberId: Long): GetChangeNicknamePriceResponse { | ||||||
|  |         val changeCount = queryFactory | ||||||
|  |             .select(nicknameChangeLog.id) | ||||||
|  |             .from(nicknameChangeLog) | ||||||
|  |             .where(nicknameChangeLog.member.id.eq(memberId)) | ||||||
|  |             .fetch() | ||||||
|  |             .count() | ||||||
|  |  | ||||||
|  |         return GetChangeNicknamePriceResponse( | ||||||
|  |             price = if (changeCount > 0) { | ||||||
|  |                 1000 | ||||||
|  |             } else { | ||||||
|  |                 0 | ||||||
|  |             } | ||||||
|  |         ) | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -3,6 +3,8 @@ package kr.co.vividnext.sodalive.member | |||||||
| import com.amazonaws.services.s3.model.ObjectMetadata | import com.amazonaws.services.s3.model.ObjectMetadata | ||||||
| import com.fasterxml.jackson.databind.ObjectMapper | import com.fasterxml.jackson.databind.ObjectMapper | ||||||
| import kr.co.vividnext.sodalive.aws.s3.S3Uploader | import kr.co.vividnext.sodalive.aws.s3.S3Uploader | ||||||
|  | import kr.co.vividnext.sodalive.can.payment.CanPaymentService | ||||||
|  | import kr.co.vividnext.sodalive.can.use.CanUsage | ||||||
| import kr.co.vividnext.sodalive.common.ApiResponse | import kr.co.vividnext.sodalive.common.ApiResponse | ||||||
| import kr.co.vividnext.sodalive.common.SodaException | import kr.co.vividnext.sodalive.common.SodaException | ||||||
| import kr.co.vividnext.sodalive.jwt.TokenProvider | import kr.co.vividnext.sodalive.jwt.TokenProvider | ||||||
| @@ -16,6 +18,8 @@ import kr.co.vividnext.sodalive.member.info.GetMemberInfoResponse | |||||||
| import kr.co.vividnext.sodalive.member.login.LoginRequest | import kr.co.vividnext.sodalive.member.login.LoginRequest | ||||||
| import kr.co.vividnext.sodalive.member.login.LoginResponse | import kr.co.vividnext.sodalive.member.login.LoginResponse | ||||||
| import kr.co.vividnext.sodalive.member.myPage.MyPageResponse | import kr.co.vividnext.sodalive.member.myPage.MyPageResponse | ||||||
|  | import kr.co.vividnext.sodalive.member.nickname.NicknameChangeLog | ||||||
|  | import kr.co.vividnext.sodalive.member.nickname.NicknameChangeLogRepository | ||||||
| import kr.co.vividnext.sodalive.member.notification.MemberNotificationService | import kr.co.vividnext.sodalive.member.notification.MemberNotificationService | ||||||
| import kr.co.vividnext.sodalive.member.notification.UpdateNotificationSettingRequest | import kr.co.vividnext.sodalive.member.notification.UpdateNotificationSettingRequest | ||||||
| import kr.co.vividnext.sodalive.member.signUp.SignUpRequest | import kr.co.vividnext.sodalive.member.signUp.SignUpRequest | ||||||
| @@ -25,6 +29,8 @@ import kr.co.vividnext.sodalive.member.stipulation.StipulationAgree | |||||||
| import kr.co.vividnext.sodalive.member.stipulation.StipulationAgreeRepository | import kr.co.vividnext.sodalive.member.stipulation.StipulationAgreeRepository | ||||||
| import kr.co.vividnext.sodalive.member.stipulation.StipulationIds | import kr.co.vividnext.sodalive.member.stipulation.StipulationIds | ||||||
| import kr.co.vividnext.sodalive.member.stipulation.StipulationRepository | import kr.co.vividnext.sodalive.member.stipulation.StipulationRepository | ||||||
|  | import kr.co.vividnext.sodalive.member.tag.MemberCreatorTag | ||||||
|  | import kr.co.vividnext.sodalive.member.tag.MemberTagRepository | ||||||
| import kr.co.vividnext.sodalive.member.token.MemberTokenRepository | import kr.co.vividnext.sodalive.member.token.MemberTokenRepository | ||||||
| import kr.co.vividnext.sodalive.utils.generateFileName | import kr.co.vividnext.sodalive.utils.generateFileName | ||||||
| import org.springframework.beans.factory.annotation.Value | import org.springframework.beans.factory.annotation.Value | ||||||
| @@ -53,7 +59,10 @@ class MemberService( | |||||||
|     private val creatorFollowingRepository: CreatorFollowingRepository, |     private val creatorFollowingRepository: CreatorFollowingRepository, | ||||||
|     private val blockMemberRepository: BlockMemberRepository, |     private val blockMemberRepository: BlockMemberRepository, | ||||||
|     private val signOutRepository: SignOutRepository, |     private val signOutRepository: SignOutRepository, | ||||||
|  |     private val nicknameChangeLogRepository: NicknameChangeLogRepository, | ||||||
|  |     private val memberTagRepository: MemberTagRepository, | ||||||
|  |  | ||||||
|  |     private val canPaymentService: CanPaymentService, | ||||||
|     private val memberNotificationService: MemberNotificationService, |     private val memberNotificationService: MemberNotificationService, | ||||||
|  |  | ||||||
|     private val s3Uploader: S3Uploader, |     private val s3Uploader: S3Uploader, | ||||||
| @@ -107,6 +116,13 @@ class MemberService( | |||||||
|         ) |         ) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     fun getMember(id: Long, container: String): ProfileResponse { | ||||||
|  |         val member = repository.findByIdOrNull(id) | ||||||
|  |             ?: throw SodaException("없는 사용자 입니다.") | ||||||
|  |  | ||||||
|  |         return ProfileResponse(member, cloudFrontHost, container) | ||||||
|  |     } | ||||||
|  |  | ||||||
|     fun getMemberInfo(member: Member, container: String): GetMemberInfoResponse { |     fun getMemberInfo(member: Member, container: String): GetMemberInfoResponse { | ||||||
|         return GetMemberInfoResponse( |         return GetMemberInfoResponse( | ||||||
|             can = member.getChargeCan(container) + member.getRewardCan(container), |             can = member.getChargeCan(container) + member.getRewardCan(container), | ||||||
| @@ -406,6 +422,130 @@ class MemberService( | |||||||
|         signOutRepository.save(signOut) |         signOutRepository.save(signOut) | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     fun getChangeNicknamePrice(memberId: Long): GetChangeNicknamePriceResponse { | ||||||
|  |         return repository.getChangeNicknamePrice(memberId = memberId) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Transactional | ||||||
|  |     fun updateNickname(profileUpdateRequest: ProfileUpdateRequest, user: User) { | ||||||
|  |         if (profileUpdateRequest.email != user.username) { | ||||||
|  |             throw SodaException("로그인 정보를 확인해 주세요.") | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         val member = repository.findByEmail(user.username) ?: throw SodaException("로그인 정보를 확인해주세요.") | ||||||
|  |  | ||||||
|  |         if (profileUpdateRequest.nickname != null) { | ||||||
|  |             validateNickname(profileUpdateRequest.nickname) | ||||||
|  |             repository.findByNickname(profileUpdateRequest.nickname) | ||||||
|  |                 ?.let { throw SodaException("이미 사용중인 닉네임 입니다.") } | ||||||
|  |  | ||||||
|  |             val price = repository.getChangeNicknamePrice(memberId = member.id!!).price | ||||||
|  |             if (price > 0) { | ||||||
|  |                 canPaymentService.spendCan( | ||||||
|  |                     memberId = member.id!!, | ||||||
|  |                     needCan = price, | ||||||
|  |                     canUsage = CanUsage.CHANGE_NICKNAME, | ||||||
|  |                     container = profileUpdateRequest.container | ||||||
|  |                 ) | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             val nicknameChangeLog = NicknameChangeLog(prevNickname = member.nickname) | ||||||
|  |             nicknameChangeLog.member = member | ||||||
|  |             nicknameChangeLogRepository.save(nicknameChangeLog) | ||||||
|  |  | ||||||
|  |             member.nickname = profileUpdateRequest.nickname | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Transactional | ||||||
|  |     fun profileUpdate(profileUpdateRequest: ProfileUpdateRequest, user: User): ProfileResponse { | ||||||
|  |         if (profileUpdateRequest.email != user.username) { | ||||||
|  |             throw SodaException("로그인 정보를 확인해 주세요.") | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         val member = repository.findByEmail(user.username) ?: throw SodaException("로그인 정보를 확인해주세요.") | ||||||
|  |  | ||||||
|  |         if (profileUpdateRequest.modifyPassword != null) { | ||||||
|  |             if (passwordEncoder.matches(profileUpdateRequest.password, member.password)) { | ||||||
|  |                 validatePassword(profileUpdateRequest.modifyPassword) | ||||||
|  |                 member.password = passwordEncoder.encode(profileUpdateRequest.modifyPassword) | ||||||
|  |             } else { | ||||||
|  |                 throw SodaException("비밀번호가 일치하지 않습니다.") | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (profileUpdateRequest.gender != null) { | ||||||
|  |             member.gender = profileUpdateRequest.gender | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (profileUpdateRequest.nickname != null) { | ||||||
|  |             validateNickname(profileUpdateRequest.nickname) | ||||||
|  |             repository.findByNickname(profileUpdateRequest.nickname) | ||||||
|  |                 ?.let { throw SodaException("이미 사용중인 닉네임 입니다.") } | ||||||
|  |             member.nickname = profileUpdateRequest.nickname | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         val tags = if (!profileUpdateRequest.removeTags.isNullOrEmpty()) { | ||||||
|  |             member.tags.filter { !profileUpdateRequest.removeTags.contains(it.tag.tag) } | ||||||
|  |         } else { | ||||||
|  |             member.tags | ||||||
|  |         }.toMutableList() | ||||||
|  |  | ||||||
|  |         if (!profileUpdateRequest.insertTags.isNullOrEmpty()) { | ||||||
|  |             val accountCounselorTags = memberTagRepository.findByMember(member).map { it.tag } | ||||||
|  |             profileUpdateRequest.insertTags.forEach { | ||||||
|  |                 val tag = memberTagRepository.findByTag(it) | ||||||
|  |                 if (tag != null && !accountCounselorTags.contains(tag)) { | ||||||
|  |                     tags.add(MemberCreatorTag(member, tag)) | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (tags != member.tags) { | ||||||
|  |             member.tags.clear() | ||||||
|  |             member.tags.addAll(tags) | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (profileUpdateRequest.introduce != null) { | ||||||
|  |             member.introduce = profileUpdateRequest.introduce | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (profileUpdateRequest.youtubeUrl != null) { | ||||||
|  |             member.youtubeUrl = profileUpdateRequest.youtubeUrl | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (profileUpdateRequest.instagramUrl != null) { | ||||||
|  |             member.instagramUrl = profileUpdateRequest.instagramUrl | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (profileUpdateRequest.websiteUrl != null) { | ||||||
|  |             member.websiteUrl = profileUpdateRequest.websiteUrl | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (profileUpdateRequest.blogUrl != null) { | ||||||
|  |             member.blogUrl = profileUpdateRequest.blogUrl | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         return ProfileResponse(member, cloudFrontHost, profileUpdateRequest.container) | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     @Transactional | ||||||
|  |     fun profileImageUpdate(multipartFile: MultipartFile, user: User): String { | ||||||
|  |         val member = repository.findByEmail(user.username) ?: throw SodaException("로그인 정보를 확인해주세요.") | ||||||
|  |  | ||||||
|  |         val metadata = ObjectMetadata() | ||||||
|  |         metadata.contentLength = multipartFile.size | ||||||
|  |  | ||||||
|  |         member.profileImage = s3Uploader.upload( | ||||||
|  |             inputStream = multipartFile.inputStream, | ||||||
|  |             bucket = s3Bucket, | ||||||
|  |             filePath = "profile/${member.id}/${generateFileName(prefix = "${member.id}-profile")}", | ||||||
|  |             metadata = metadata | ||||||
|  |         ) | ||||||
|  |  | ||||||
|  |         return "$cloudFrontHost/${member.profileImage!!}" | ||||||
|  |     } | ||||||
|  |  | ||||||
|     private fun getOrCreateLock(memberId: Long): ReentrantReadWriteLock { |     private fun getOrCreateLock(memberId: Long): ReentrantReadWriteLock { | ||||||
|         return tokenLocks.computeIfAbsent(memberId) { ReentrantReadWriteLock() } |         return tokenLocks.computeIfAbsent(memberId) { ReentrantReadWriteLock() } | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -0,0 +1,37 @@ | |||||||
|  | package kr.co.vividnext.sodalive.member | ||||||
|  |  | ||||||
|  | data class ProfileResponse( | ||||||
|  |     val userId: Long, | ||||||
|  |     val email: String, | ||||||
|  |     val nickname: String, | ||||||
|  |     val gender: Gender, | ||||||
|  |     val profileUrl: String, | ||||||
|  |     val chargeCan: Int, | ||||||
|  |     val rewardCan: Int, | ||||||
|  |     val youtubeUrl: String?, | ||||||
|  |     val instagramUrl: String?, | ||||||
|  |     val blogUrl: String?, | ||||||
|  |     val websiteUrl: String?, | ||||||
|  |     val introduce: String, | ||||||
|  |     val tags: List<String> | ||||||
|  | ) { | ||||||
|  |     constructor(member: Member, cloudFrontHost: String, container: String) : this( | ||||||
|  |         userId = member.id!!, | ||||||
|  |         email = member.email, | ||||||
|  |         nickname = member.nickname, | ||||||
|  |         gender = member.gender, | ||||||
|  |         profileUrl = if (member.profileImage != null) { | ||||||
|  |             "$cloudFrontHost/${member.profileImage}" | ||||||
|  |         } else { | ||||||
|  |             "$cloudFrontHost/profile/default-profile.png" | ||||||
|  |         }, | ||||||
|  |         chargeCan = member.getChargeCan(container), | ||||||
|  |         rewardCan = member.getRewardCan(container), | ||||||
|  |         youtubeUrl = member.youtubeUrl, | ||||||
|  |         instagramUrl = member.instagramUrl, | ||||||
|  |         websiteUrl = member.websiteUrl, | ||||||
|  |         blogUrl = member.blogUrl, | ||||||
|  |         introduce = member.introduce, | ||||||
|  |         tags = member.tags.asSequence().filter { it.tag.isActive }.map { it.tag.tag }.toList() | ||||||
|  |     ) | ||||||
|  | } | ||||||
| @@ -0,0 +1,17 @@ | |||||||
|  | package kr.co.vividnext.sodalive.member | ||||||
|  |  | ||||||
|  | data class ProfileUpdateRequest( | ||||||
|  |     val email: String, | ||||||
|  |     val password: String? = null, | ||||||
|  |     val modifyPassword: String? = null, | ||||||
|  |     val nickname: String? = null, | ||||||
|  |     val gender: Gender? = null, | ||||||
|  |     val insertTags: List<String>? = null, | ||||||
|  |     val removeTags: List<String>? = null, | ||||||
|  |     val introduce: String? = null, | ||||||
|  |     val youtubeUrl: String? = null, | ||||||
|  |     val instagramUrl: String? = null, | ||||||
|  |     val websiteUrl: String? = null, | ||||||
|  |     val blogUrl: String? = null, | ||||||
|  |     val container: String | ||||||
|  | ) | ||||||
| @@ -0,0 +1,30 @@ | |||||||
|  | package kr.co.vividnext.sodalive.member.nickname | ||||||
|  |  | ||||||
|  | import kr.co.vividnext.sodalive.member.Member | ||||||
|  | import java.time.LocalDateTime | ||||||
|  | import javax.persistence.Entity | ||||||
|  | import javax.persistence.FetchType | ||||||
|  | import javax.persistence.GeneratedValue | ||||||
|  | import javax.persistence.GenerationType | ||||||
|  | import javax.persistence.Id | ||||||
|  | import javax.persistence.JoinColumn | ||||||
|  | import javax.persistence.ManyToOne | ||||||
|  | import javax.persistence.PrePersist | ||||||
|  |  | ||||||
|  | @Entity | ||||||
|  | data class NicknameChangeLog( | ||||||
|  |     @Id | ||||||
|  |     @GeneratedValue(strategy = GenerationType.IDENTITY) | ||||||
|  |     var id: Long? = null, | ||||||
|  |     val prevNickname: String, | ||||||
|  |     var createdAt: LocalDateTime? = null | ||||||
|  | ) { | ||||||
|  |     @ManyToOne(fetch = FetchType.LAZY) | ||||||
|  |     @JoinColumn(name = "member_id", nullable = false) | ||||||
|  |     var member: Member? = null | ||||||
|  |  | ||||||
|  |     @PrePersist | ||||||
|  |     fun prePersist() { | ||||||
|  |         createdAt = LocalDateTime.now() | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -0,0 +1,7 @@ | |||||||
|  | package kr.co.vividnext.sodalive.member.nickname | ||||||
|  |  | ||||||
|  | import org.springframework.data.jpa.repository.JpaRepository | ||||||
|  | import org.springframework.stereotype.Repository | ||||||
|  |  | ||||||
|  | @Repository | ||||||
|  | interface NicknameChangeLogRepository : JpaRepository<NicknameChangeLog, Long> | ||||||
| @@ -1,7 +1,9 @@ | |||||||
| package kr.co.vividnext.sodalive.member.tag | package kr.co.vividnext.sodalive.member.tag | ||||||
|  |  | ||||||
| import com.querydsl.jpa.impl.JPAQueryFactory | import com.querydsl.jpa.impl.JPAQueryFactory | ||||||
|  | import kr.co.vividnext.sodalive.member.Member | ||||||
| import kr.co.vividnext.sodalive.member.tag.QCreatorTag.creatorTag | import kr.co.vividnext.sodalive.member.tag.QCreatorTag.creatorTag | ||||||
|  | import kr.co.vividnext.sodalive.member.tag.QMemberCreatorTag.memberCreatorTag | ||||||
| import org.springframework.beans.factory.annotation.Value | import org.springframework.beans.factory.annotation.Value | ||||||
| import org.springframework.data.jpa.repository.JpaRepository | import org.springframework.data.jpa.repository.JpaRepository | ||||||
|  |  | ||||||
| @@ -11,6 +13,7 @@ interface MemberTagRepository : JpaRepository<CreatorTag, Long>, MemberTagQueryR | |||||||
|  |  | ||||||
| interface MemberTagQueryRepository { | interface MemberTagQueryRepository { | ||||||
|     fun getTags(): List<GetMemberTagResponse> |     fun getTags(): List<GetMemberTagResponse> | ||||||
|  |     fun findByMember(member: Member): List<MemberCreatorTag> | ||||||
| } | } | ||||||
|  |  | ||||||
| class MemberTagQueryRepositoryImpl( | class MemberTagQueryRepositoryImpl( | ||||||
| @@ -33,4 +36,11 @@ class MemberTagQueryRepositoryImpl( | |||||||
|             .orderBy(creatorTag.orders.asc()) |             .orderBy(creatorTag.orders.asc()) | ||||||
|             .fetch() |             .fetch() | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     override fun findByMember(member: Member): List<MemberCreatorTag> { | ||||||
|  |         return queryFactory | ||||||
|  |             .selectFrom(memberCreatorTag) | ||||||
|  |             .where(memberCreatorTag.member.id.eq(member.id)) | ||||||
|  |             .fetch() | ||||||
|  |     } | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user