import type { ReqPreorderSelectEvent, ResPreorderSelectEvent, ReqPreorderReserveDataUpdate, ResPreorderReserveDataUpdate, } from '#layers/types/PreregistType' import { DEFAULT_LOCALE_CODE } from '@/i18n.config' 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()) // GDS composable const { isKorea, isTaiwanHongKongMacau, isNorthAmerica, countryCode, checkCountryByIp, } = useGds() // 국가 번호 조회 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 = ( 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 => { try { const runtimeConfig = useRuntimeConfig() const stoveApiBaseUrl = runtimeConfig.public.stoveApiUrl const url = `${stoveApiBaseUrl}/pub-comm/v1.0/Preorder/SelectEvent` const headers = { Authorization: `Bearer ${req.accessToken}`, } const body = { event_code: req.event_code, lang: req.lang || DEFAULT_LOCALE_CODE, terms_type: req.terms_type, } const res = (await commonFetch('POST', url, { headers, body, })) as ResPreorderSelectEvent // 응답 검증 if (!res) { // eslint-disable-next-line no-console console.error('[usePreregist].getPreregist: Empty response') return createErrorResponse(PREREGIST_ERROR_CODE.UNKNOWN) } // 정규화된 에러 코드 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) ) } } /** * 사전 등록 - 저장 */ const setPreregist = async ( req: ReqPreorderReserveDataUpdate ): Promise => { 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}`, } const body = { necessary_consent1: req.necessary_consent1, necessary_consent2: req.necessary_consent2, necessary_consent3: req.necessary_consent3, event_code: req.event_code, terms_type: req.terms_type, c_num: req.c_num, lang_code: req.lang_code, hp: req.hp, email: req.email, 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, device_type: req.device_type, country_code: req.country_code, country_dialing_code: req.country_dialing_code, birth_date: req.birth_date, } const res = (await commonFetch('POST', url, { headers, body, })) as ResPreorderReserveDataUpdate // 응답 검증 if (!res) { // eslint-disable-next-line no-console console.error('[usePreregist].setPreregist: Empty response') return createErrorResponse(PREREGIST_ERROR_CODE.UNKNOWN) } // 정규화된 에러 코드 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) ) } } return { // GDS state & methods isKorea, isTaiwanHongKongMacau, isNorthAmerica, countryCode, checkCountryByIp, // Preregist state & computed countryDialingCode, preregistDate: readonly(preregistDate), // Preregist methods getPreregist, setPreregist, } } export { usePreregist, PREREGIST_ERROR_CODE }