fix. 사전등록 로직 수정

This commit is contained in:
clkim
2025-11-07 16:29:44 +09:00
parent b5f723397b
commit bcbc7e9c6d
5 changed files with 500 additions and 582 deletions

View File

@@ -11,20 +11,24 @@ import { countryDialingCodes } from '#layers/assets/data/countryData'
/**
* 프로모션 - 사전등록
*/
const PREREGIST_ERROR_CODE = {
SUCCESS: 0,
NO_DATA: -1, // 조회된 데이터가 없습니다 (최초)
NOT_PERIOD: -90002, // 사전 등록 기간이 아닙니다
REQUIRED_TERMS: -90000, // 필수 약관을 모두 선택해 주세요
// BIRTH_DATE_REQUIRED: -90018, // 생년 월일을 입력해 주세요
AGE_RESTRICTION: -90022, // 사전 등록 가능한 연령이 아닙니다
ALREADY_REGISTERED: -90023, // 이미 사전 등록이 완료된 계정입니다
LOGIN_REQUIRED: -90028, // 로그인 후 이용하실 수 있습니다
// MAINTENANCE: -90003, // 점검 진행 중
UNKNOWN: -99999, // 알 수 없는 오류
} as const
const usePreregist = () => {
const preregistDate = ref(Date.now()) // 사전 등록일
const preregistDate = ref(Date.now())
// [Setter] 사전등록 - 사전 등록일 세팅
const setPreregistDate = (newPreregistDate: number) => {
preregistDate.value = newPreregistDate
}
// 국가 번호 조회
const countryDialingCode = computed(() => {
return countryDialingCodes[countryCode.value.toUpperCase()]
})
// 사전 등록 - 특정 국가 여부 조회 (IP 기반)
// GDS composable
const {
isKorea,
isTaiwanHongKongMacau,
@@ -33,14 +37,54 @@ const usePreregist = () => {
checkCountryByIp,
} = useGds()
// 사전 등록 - (등록 여부) 조회
const getPreregist = async (req: ReqPreorderSelectEvent) => {
let res: ResPreorderSelectEvent = {} as ResPreorderSelectEvent
// 국가 번호 조회
const countryDialingCode = computed(() => {
const code = countryCode.value?.toUpperCase()
return code ? countryDialingCodes[code] : undefined
})
/**
* 사전 등록일 세팅 (숫자 검증)
*/
const setPreregistDate = (dateValue: number | string | undefined) => {
if (dateValue && isNumeric(String(dateValue))) {
preregistDate.value = Number(dateValue)
} else {
preregistDate.value = Date.now()
}
}
/**
* 에러 응답 생성
*/
const createErrorResponse = <T extends { code: number; message: string }>(
code: number,
message: string = ''
): T => {
return { code, message } as T
}
/**
* 401 에러를 LOGIN_REQUIRED로 정규화
*/
const normalizeAuthError = (code: number): number => {
return String(code).startsWith('401')
? PREREGIST_ERROR_CODE.LOGIN_REQUIRED
: code
}
/**
* 사전 등록 - 조회 (등록 여부)
*/
const getPreregist = async (
req: ReqPreorderSelectEvent
): Promise<ResPreorderSelectEvent> => {
try {
const runtimeConfig = useRuntimeConfig()
const stoveApiBaseUrl = runtimeConfig.public.stoveApiUrl
const stoveApiBaseUrl = runtimeConfig.public.stoveApiUrl
const url = `${stoveApiBaseUrl}/pub-comm/v1.0/Preorder/SelectEvent`
const headers = {
Authorization: `Bearer ${req.accessToken}`,
}
@@ -49,59 +93,69 @@ const usePreregist = () => {
lang: req.lang || DEFAULT_LOCALE_CODE,
terms_type: req.terms_type,
}
res = (await commonFetch('POST', url, {
const res = (await commonFetch('POST', url, {
headers,
body,
})) as ResPreorderSelectEvent
if (res != null) {
if (res.code === 0) {
setPreregistDate(res.value?.terms_time_long || Date.now())
} else if (res.code === -1) {
//= 조회 된 데이터가 없습니다. -> 최초
} else if (res.code === -90002) {
//= 사전 등록 기간이 아닙니다.
} else if (`${res.code}`.startsWith('401')) {
//= [01] 로그인 후 이용하실 수 있습니다.
res = { code: -90028, message: res.message || '' } // 401은 -90028로 처리
} else if (res.code === -90028) {
//= [01] 로그인 후 이용하실 수 있습니다.
} else {
// [-90003] 점검 진행 중
res = { code: res.code, message: res.message || '' }
console.log(
'[Failure] /composables/promotion/usePreregist.getPreregist: ',
res
)
res.code = -99999 // else 알럿 띄우기 용 세팅
}
} else {
res = { code: -99999, message: '' }
console.log(
'[Failure] /composables/promotion/usePreregist.getPreregist: ',
res
)
res.code = -99999 // else 알럿 띄우기 용 세팅
// 응답 검증
if (!res) {
// eslint-disable-next-line no-console
console.error('[usePreregist].getPreregist: Empty response')
return createErrorResponse(PREREGIST_ERROR_CODE.UNKNOWN)
}
} catch (e) {
console.error(
'[Exception] /composables/promotion/usePreregist.getPreregist: ',
e
// 정규화된 에러 코드
const normalizedCode = normalizeAuthError(res.code)
// 성공 케이스
if (normalizedCode === PREREGIST_ERROR_CODE.SUCCESS) {
setPreregistDate(res.value?.terms_time_long ?? Date.now())
return res
}
// 예상된 에러 케이스 (NO_DATA, NOT_PERIOD, LOGIN_REQUIRED)
const expectedErrors: number[] = [
PREREGIST_ERROR_CODE.NO_DATA,
PREREGIST_ERROR_CODE.NOT_PERIOD,
PREREGIST_ERROR_CODE.LOGIN_REQUIRED,
]
if (expectedErrors.includes(normalizedCode)) {
return createErrorResponse(normalizedCode, res.message)
}
// 예상치 못한 에러
if (import.meta.dev) {
// eslint-disable-next-line no-console
console.error('[usePreregist].getPreregist: Unexpected error', res)
}
return createErrorResponse(PREREGIST_ERROR_CODE.UNKNOWN, res.message)
} catch (error) {
// eslint-disable-next-line no-console
console.error('[usePreregist].getPreregist: Exception', error)
return createErrorResponse(
PREREGIST_ERROR_CODE.UNKNOWN,
error instanceof Error ? error.message : String(error)
)
res = {
code: -99999,
message: `${e}`,
}
}
return res
}
// 사전 등록 - 저장
const setPreregist = async (req: ReqPreorderReserveDataUpdate) => {
let res: ResPreorderReserveDataUpdate = {} as ResPreorderReserveDataUpdate
/**
* 사전 등록 - 저장
*/
const setPreregist = async (
req: ReqPreorderReserveDataUpdate
): Promise<ResPreorderReserveDataUpdate> => {
try {
const runtimeConfig = useRuntimeConfig()
const stoveApiBaseUrl = runtimeConfig.public.stoveApiUrl
if (!stoveApiBaseUrl) {
throw new Error('stoveApiUrl is not configured')
}
const url = `${stoveApiBaseUrl}/pub-comm/v1.0/Preorder/ReserveDataUpdate`
const headers = {
Authorization: `Bearer ${req.accessToken}`,
@@ -116,104 +170,93 @@ const usePreregist = () => {
lang_code: req.lang_code,
hp: req.hp,
email: req.email,
metric_seq: req.metric_seq, //= mcode
metric_seq: req.metric_seq,
g_server: req.g_server,
world_id: req.world_id,
game_unique_num: req.game_unique_num,
event_info1: req.event_info1, // 각 이벤트 필요할때 사용
event_info2: req.event_info2, // 각 이벤트 필요할때 사용
event_info3: req.event_info3, // 각 이벤트 필요할때 사용
event_info4: req.event_info4, // 각 이벤트 필요할때 사용
under14_terms: req.under14_terms, // 14세미만 진행 하는 구분값
device_type: req.device_type, // 접속 기기 pc / mobile
event_info1: req.event_info1,
event_info2: req.event_info2,
event_info3: req.event_info3,
event_info4: req.event_info4,
under14_terms: req.under14_terms,
device_type: req.device_type,
country_code: req.country_code,
country_dialing_code: req.country_dialing_code, // 국가 번호
birth_date: req.birth_date, // 생년월일 - 북미(미국, 캐나다)의 경우
country_dialing_code: req.country_dialing_code,
birth_date: req.birth_date,
}
res = (await commonFetch('POST', url, {
const res = (await commonFetch('POST', url, {
headers,
body,
})) as ResPreorderReserveDataUpdate
if (res != null) {
if (res.code === 0) {
//= [08] [사전 등록 완료 레이어] 노출
if (
res.message != null &&
res.message !== '' &&
isNumeric(res.message)
) {
// 사전 등록일이 숫자면 날짜로 변환
setPreregistDate(Number(res.message))
} else {
setPreregistDate(Date.now())
}
} else if (`${res.code}`.startsWith('401')) {
//= [01] 로그인 후 이용하실 수 있습니다.
res = { code: -90028, message: res.message || '' } // 401은 -90028로 처리
} else if (res.code === -90028) {
//= [01] 로그인 후 이용하실 수 있습니다.
} else if (res.code === -90002) {
//= [02] 사전 등록 기간이 아닙니다.
} else if (res.code === -90018) {
//= [04] 생년 월일을 입력해 주세요.
} else if (res.code === -90022) {
//= [05] 사전 등록 가능한 연령이 아닙니다.
} else if (res.code === -90000) {
//= [06] 필수 약관을 모두 선택해 주세요.
} else if (res.code === -90023) {
//= [07] 이미 사전 등록이 완료된 계정입니다.
if (
res.message != null &&
res.message !== '' &&
isNumeric(res.message)
) {
// 사전 등록일이 숫자면 날짜로 변환
setPreregistDate(Number(res.message))
} else {
setPreregistDate(Date.now())
}
} else {
//= [03] 오류가 발생했습니다.\n계속 오류가 발생하면 고객센터로 문의해 주세요.
res = { code: res.code, message: res.message || '' }
console.log(
'[Failure] /composables/promotion/usePreregist.setPreregist: ',
res
)
res.code = -99999 // else 알럿 띄우기 용 세팅
}
} else {
res = { code: -99999, message: '' }
console.log(
'[Failure] /composables/promotion/usePreregist.setPreregist: ',
res
)
// 응답 검증
if (!res) {
// eslint-disable-next-line no-console
console.error('[usePreregist].setPreregist: Empty response')
return createErrorResponse(PREREGIST_ERROR_CODE.UNKNOWN)
}
} catch (e) {
console.error(
'[Exception] /composables/promotion/usePreregist.setPreregist: ',
e
// 정규화된 에러 코드
const normalizedCode = normalizeAuthError(res.code)
// 성공 케이스
if (normalizedCode === PREREGIST_ERROR_CODE.SUCCESS) {
setPreregistDate(res.message ? Number(res.message) : Date.now())
return res
}
// 이미 등록된 경우 (날짜 업데이트)
if (normalizedCode === PREREGIST_ERROR_CODE.ALREADY_REGISTERED) {
setPreregistDate(res.message ? Number(res.message) : Date.now())
return createErrorResponse(normalizedCode, res.message)
}
// 예상된 에러 케이스
const expectedErrors: number[] = [
PREREGIST_ERROR_CODE.LOGIN_REQUIRED,
PREREGIST_ERROR_CODE.NOT_PERIOD,
// PREREGIST_ERROR_CODE.BIRTH_DATE_REQUIRED,
PREREGIST_ERROR_CODE.AGE_RESTRICTION,
PREREGIST_ERROR_CODE.REQUIRED_TERMS,
]
if (expectedErrors.includes(normalizedCode)) {
return createErrorResponse(normalizedCode, res.message)
}
// 예상치 못한 에러
if (import.meta.dev) {
// eslint-disable-next-line no-console
console.error('[usePreregist].setPreregist: Unexpected error', res)
}
return createErrorResponse(PREREGIST_ERROR_CODE.UNKNOWN, res.message)
} catch (error) {
// eslint-disable-next-line no-console
console.error('[usePreregist].setPreregist: Exception', error)
return createErrorResponse(
PREREGIST_ERROR_CODE.UNKNOWN,
error instanceof Error ? error.message : String(error)
)
res = {
code: -99999,
message: `${e}`,
}
}
return res
}
return {
// GDS state & methods
isKorea,
isTaiwanHongKongMacau,
isNorthAmerica,
countryCode,
countryDialingCode,
preregistDate,
checkCountryByIp,
// Preregist state & computed
countryDialingCode,
preregistDate: readonly(preregistDate),
// Preregist methods
getPreregist,
setPreregist,
}
}
export { usePreregist }
export { usePreregist, PREREGIST_ERROR_CODE }