diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt index e92fdc3a..d6868bd0 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/member/MemberService.kt @@ -130,7 +130,7 @@ class MemberService( duplicateCheckEmail(request.email) validatePassword(request.password) - val nickname = nicknameGenerateService.generateUniqueNickname() + val nickname = nicknameGenerateService.generateUniqueNickname(langContext.lang) val member = Member( email = request.email, password = passwordEncoder.encode(request.password), @@ -850,7 +850,7 @@ class MemberService( val email = googleUserInfo.email checkEmail(email) - val nickname = nicknameGenerateService.generateUniqueNickname() + val nickname = nicknameGenerateService.generateUniqueNickname(langContext.lang) val member = Member( googleId = googleUserInfo.sub, email = email, @@ -907,7 +907,7 @@ class MemberService( val email = kakaoUserInfo.email checkEmail(email) - val nickname = nicknameGenerateService.generateUniqueNickname() + val nickname = nicknameGenerateService.generateUniqueNickname(langContext.lang) val member = Member( kakaoId = kakaoUserInfo.id, email = email, @@ -964,7 +964,7 @@ class MemberService( val email = appleUserInfo.email checkEmail(email) - val nickname = nicknameGenerateService.generateUniqueNickname() + val nickname = nicknameGenerateService.generateUniqueNickname(langContext.lang) val member = Member( appleId = appleUserInfo.sub, email = email, @@ -1021,7 +1021,7 @@ class MemberService( val email = lineUserInfo.email checkEmail(email) - val nickname = nicknameGenerateService.generateUniqueNickname() + val nickname = nicknameGenerateService.generateUniqueNickname(langContext.lang) val member = Member( lineId = lineUserInfo.sub, email = email, diff --git a/src/main/kotlin/kr/co/vividnext/sodalive/member/nickname/NicknameGenerateService.kt b/src/main/kotlin/kr/co/vividnext/sodalive/member/nickname/NicknameGenerateService.kt index 963a8d40..1a0e90e1 100644 --- a/src/main/kotlin/kr/co/vividnext/sodalive/member/nickname/NicknameGenerateService.kt +++ b/src/main/kotlin/kr/co/vividnext/sodalive/member/nickname/NicknameGenerateService.kt @@ -1,6 +1,7 @@ package kr.co.vividnext.sodalive.member.nickname import kr.co.vividnext.sodalive.common.SodaException +import kr.co.vividnext.sodalive.i18n.Lang import kr.co.vividnext.sodalive.member.MemberRepository import org.springframework.stereotype.Service import kotlin.random.Random @@ -44,23 +45,85 @@ class NicknameGenerateService(private val repository: MemberRepository) { "천혜향", "레드향", "금귤", "모과", "비파", "대추", "밤", "호두", "잣", "은행" ) - private fun generateRandomNickname(): String { + private val jaAdjectives = listOf( + "元気な", "明るい", "優しい", "強い", "賢い", "穏やかな", "爽やかな", "楽しい", + "勇敢な", "素敵な", "可愛い", "美しい", "清らかな", "温かい", "輝く", "華やかな", + "凛とした", "朗らかな", "逞しい", "麗しい", "雅な", "粋な", "健やかな", "晴れやかな", + "鮮やかな", "煌めく", "微笑む", "誠実な", "丁寧な", "真っ直ぐな", "気高い", "聡明な", + "快活な", "軽やかな", "しなやかな", "伸びやかな", "瑞々しい", "初々しい", "艶やかな", "柔らかな", + "澄んだ", "静かな", "豊かな", "深い", "広い", "高い", "清い", "涼しい", + "眩しい", "暖かな", "和やかな", "安らかな", "のどかな", "ほがらかな", "すこやかな", "たくましい", + "ひたむきな", "まめな", "きらきらな", "ふわふわな", "にこにこな", "わくわくな", "すくすくな", "のびのびな", + "きりっとした", "はきはきな", "てきぱきな", "しっかりな", "どっしりな", "ゆったりな", "さっぱりな", "すっきりな", + "ぴかぴかな", "つやつやな", "さらさらな", "もちもちな", "ぷるぷるな", "ころころな", "ぽかぽかな", "そよそよな", + "堅実な", "勤勉な", "忠実な", "素直な", "謙虚な", "大胆な", "情熱的な", "積極的な", + "独創的な", "繊細な", "壮大な", "格調高い", "品のある", "風格ある", "趣のある", "奥深い", + "颯爽とした", "堂々とした", "悠々とした", "泰然とした", "毅然とした", "端正な", "清楚な", "典雅な", + "俊敏な", "機敏な", "敏捷な", "軽快な", "活発な", "溌剌とした", "生き生きな", "伸び伸びな", + "揺るぎない", "確かな", "頼もしい", "心強い", "力強い", "逞しき", "雄々しい", "凜々しい", + "慈しみの", "思いやりの", "気配りの", "心優しい", "情け深い", "懐の深い", "器の大きい", "包容力の" + ) + + private val jaNouns = listOf( + "うさぎ", "ねこ", "いぬ", "たぬき", "きつね", "しか", "りす", "ふくろう", + "つばめ", "すずめ", "ひばり", "うぐいす", "めじろ", "つる", "はと", "かもめ", + "いるか", "くじら", "らっこ", "ペンギン", "コアラ", "パンダ", "アルパカ", "ハムスター", + "かめ", "かえる", "ほたる", "ちょう", "とんぼ", "てんとう", "こねこ", "こいぬ", + "ひよこ", "こじか", "こぐま", "こうさぎ", "こりす", "こだぬき", "こぎつね", "こばと", + "さくら", "うめ", "もみじ", "つばき", "すみれ", "たんぽぽ", "ひまわり", "あじさい", + "コスモス", "ラベンダー", "チューリップ", "カーネーション", "バラ", "ユリ", "ダリア", "マーガレット", + "なでしこ", "あやめ", "ききょう", "はぎ", "ふじ", "ぼたん", "しゃくやく", "れんげ", + "ルビー", "サファイア", "エメラルド", "アメジスト", "パール", "オパール", "トパーズ", "ガーネット", + "ひかり", "そら", "うみ", "かぜ", "つき", "ほし", "にじ", "ゆめ", + "あかね", "みずき", "はるか", "あおい", "ひなた", "こはる", "いろは", "かなで", + "しずく", "つゆ", "あられ", "みぞれ", "こはく", "あかり", "ともしび", "かがやき", + "やまと", "みやび", "まこと", "ちはや", "あさひ", "ゆうひ", "あけぼの", "たそがれ", + "わかば", "あおば", "もえぎ", "ときわ", "さつき", "やよい", "きさらぎ", "むつき", + "抹茶", "桜餅", "団子", "大福", "最中", "羊羹", "煎餅", "饅頭", + "柚子", "梅干し", "味噌", "醤油", "わさび", "生姜", "山椒", "昆布", + "風鈴", "提灯", "扇子", "千鶴", "折鶴", "手毬", "万華鏡", "花火", + "雪うさぎ", "だるま", "こけし", "招き猫", "風車", "独楽", "竹とんぼ", "紙風船", + "朝露", "夕凪", "木漏れ日", "花吹雪", "月明かり", "星空", "天の川", "春風", + "小春日和", "花曇り", "薄紅", "若草", "深緑", "紺碧", "茜色", "藤色" + ) + + private fun getAdjectives(lang: Lang): List = when (lang) { + Lang.JA -> jaAdjectives + else -> adjectives + } + + private fun getNouns(lang: Lang): List = when (lang) { + Lang.JA -> jaNouns + else -> nouns + } + + private fun getParticle(lang: Lang): String = when (lang) { + Lang.JA -> "の" + else -> "의" + } + + private fun generateRandomNickname(lang: Lang): String { + val adj = getAdjectives(lang) + val noun = getNouns(lang) + val particle = getParticle(lang) val formatType = Random.nextInt(3) return when (formatType) { - 0 -> "${adjectives.random()}${nouns.random()}" - 1 -> "${nouns.random()}의${nouns.random()}" - else -> "${adjectives.random()}${nouns.random()}의${nouns.random()}" + 0 -> "${adj.random()}${noun.random()}" + 1 -> "${noun.random()}${particle}${noun.random()}" + else -> "${adj.random()}${noun.random()}${particle}${noun.random()}" } } - private fun generateNonConflictingNickname(usedNicknames: Set): String { - val usedNicknameSet = HashSet(usedNicknames) // 해시셋으로 변환 (O(1) 조회 가능) + private fun generateNonConflictingNickname(usedNicknames: Set, lang: Lang): String { + val usedNicknameSet = HashSet(usedNicknames) val availableNumbers = (1000..9999).shuffled() + val adj = getAdjectives(lang) + val noun = getNouns(lang) - for (num in availableNumbers) { // 숫자를 먼저 결정 (무작위) - for (adj in adjectives.shuffled()) { // 형용사 순서 랜덤화 - for (noun in nouns.shuffled()) { // 명사 순서 랜덤화 - val candidate = "$adj$noun$num" + for (num in availableNumbers) { + for (a in adj.shuffled()) { + for (n in noun.shuffled()) { + val candidate = "$a$n$num" if (!usedNicknameSet.contains(candidate)) { return candidate } @@ -70,13 +133,13 @@ class NicknameGenerateService(private val repository: MemberRepository) { throw SodaException(messageKey = "member.signup.failed_retry") } - fun generateUniqueNickname(): String { + fun generateUniqueNickname(lang: Lang = Lang.KO): String { repeat(5) { - val candidates = (1..10).map { generateRandomNickname() } + val candidates = (1..10).map { generateRandomNickname(lang) } val available = candidates.firstOrNull { !repository.existsByNickname(it) } if (available != null) return available } - return generateNonConflictingNickname(repository.findNicknamesWithPrefix("").toSet()) + return generateNonConflictingNickname(repository.findNicknamesWithPrefix("").toSet(), lang) } }