262 lines
7.7 KiB
TypeScript
262 lines
7.7 KiB
TypeScript
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 = <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 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<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}`,
|
|
}
|
|
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 }
|