201 lines
7.2 KiB
TypeScript
201 lines
7.2 KiB
TypeScript
import { commonFetch } from '#layers/utils/apiUtil'
|
|
import { usePageDataStore } from '#layers/stores/usePageDataStore'
|
|
import { useLoadingStore } from '#layers/stores/useLoadingStore'
|
|
import { useGetGameDomain } from '#layers/composables/useGetGameDomain'
|
|
import { usePathResolver } from '#layers/composables/usePathResolver'
|
|
import type { PageDataResponse } from '#layers/types/api/pageData'
|
|
|
|
export default defineNuxtRouteMiddleware(async (to, _from) => {
|
|
// client에서만 동작되도록 처리
|
|
if (!import.meta.client) return
|
|
|
|
const runtimeConfig = useRuntimeConfig()
|
|
const stoveApiBaseUrl = runtimeConfig.public.stoveApiUrl
|
|
const apiUrl = `${stoveApiBaseUrl}/pub-comm/v2.0/template/page`
|
|
|
|
const gameDomain = useGetGameDomain()
|
|
const gameDataStore = useGameDataStore()
|
|
const { gameData } = storeToRefs(gameDataStore)
|
|
console.log("🚀 ~ gameData:", gameData.value)
|
|
const pageDataStore = usePageDataStore()
|
|
const loadingStore = useLoadingStore()
|
|
const { getPathAfterLanguage } = usePathResolver()
|
|
|
|
const langCode = csrGetFinalLocale(to.path, gameData.value?.lang_codes)
|
|
|
|
try {
|
|
if (to.path.includes('inspection')) {
|
|
console.log('🚀 ~ 점검페이지 접근 pageData.global')
|
|
return
|
|
}
|
|
|
|
const pageUrl = getPathAfterLanguage(to.path)
|
|
|
|
// 루트 경로(언어 코드만 있는 경로)로 접근할 때만 intro.page_url로 리다이렉트
|
|
const isRootPath = !pageUrl || pageUrl === '' || pageUrl === '/' || pageUrl === `/${langCode}/`
|
|
console.log("🚀 ~ isRootPath:", isRootPath)
|
|
|
|
if (isRootPath) {
|
|
// gameData.intro.page_url이 있으면 해당 URL로 리다이렉트
|
|
const introPageUrl = gameData.value?.intro?.page_url
|
|
if (introPageUrl && introPageUrl.trim() !== '') {
|
|
// 외부 URL인지 확인
|
|
const isExternalUrl = introPageUrl.startsWith('http://') || introPageUrl.startsWith('https://')
|
|
|
|
// 내부 경로인 경우 언어 코드 추가
|
|
let finalIntroUrl = introPageUrl
|
|
if (!isExternalUrl) {
|
|
const normalizedIntroUrl = introPageUrl.split('?')[0] // 쿼리스트링 제외
|
|
|
|
// 언어 코드 패턴 확인 (예: /ko, /en, /zh-tw 등)
|
|
const languagePattern = /^\/[a-z]{2}(-[a-z]{2})?(\/|$)/
|
|
const hasLanguageCode = languagePattern.test(normalizedIntroUrl)
|
|
|
|
// 언어 코드가 없으면 추가
|
|
if (!hasLanguageCode) {
|
|
// 경로가 /로 시작하지 않으면 / 추가
|
|
const pathWithSlash = normalizedIntroUrl.startsWith('/')
|
|
? normalizedIntroUrl
|
|
: `/${normalizedIntroUrl}`
|
|
finalIntroUrl = `/${langCode}${pathWithSlash}`
|
|
|
|
// 쿼리스트링이 있으면 다시 추가
|
|
if (introPageUrl.includes('?')) {
|
|
finalIntroUrl += '?' + introPageUrl.split('?')[1]
|
|
}
|
|
}
|
|
}
|
|
|
|
// 무한 리다이렉트 방지: 현재 경로와 리다이렉트할 URL 비교
|
|
const normalizedFinalUrl = finalIntroUrl.split('?')[0] // 쿼리스트링 제외
|
|
const currentPath = to.path
|
|
const isSamePath = !isExternalUrl && (currentPath === normalizedFinalUrl)
|
|
|
|
if (!isSamePath) {
|
|
// 다른 경로에서 접근한 경우에만 리다이렉트
|
|
const queryString = to.fullPath.includes('?')
|
|
? '?' + to.fullPath.split('?')[1]
|
|
: ''
|
|
const redirectUrl = queryString && !finalIntroUrl.includes('?')
|
|
? `${finalIntroUrl}${queryString}`
|
|
: finalIntroUrl
|
|
console.log("🚀 ~ pageData.global redirectUrl:", redirectUrl)
|
|
return navigateTo(redirectUrl, { external: isExternalUrl })
|
|
}
|
|
}
|
|
}
|
|
|
|
// pageUrl이 빈값이거나 null이면 /home로 리다이렉트
|
|
if (
|
|
!pageUrl ||
|
|
pageUrl === '' ||
|
|
pageUrl === '/' ||
|
|
pageUrl === `/${langCode}/`
|
|
) {
|
|
console.log("🚀 ~ pageData.global /home 리다이렉트")
|
|
return navigateTo(`/${langCode}/home`, { external: false })
|
|
}
|
|
|
|
// error 페이지는 API 호출하지 않음
|
|
if (pageUrl === '/error' || to.path.includes('/error')) return
|
|
|
|
// 페이지 이동 시 로딩 상태 시작
|
|
loadingStore.startFullLoading()
|
|
|
|
const accessToken = csrGetAccessToken()
|
|
|
|
const headers = {
|
|
Authorization: `Bearer ${accessToken}`,
|
|
}
|
|
|
|
// 쿼리스트링에서 f 파라미터 값 추출 (CSR용)
|
|
// const fValue = (to.query.f as string) || ''
|
|
|
|
// // 미리보기 API 호출 처리
|
|
// let finalGameDomain = gameDomain
|
|
// if (fValue === 'preview') {
|
|
// finalGameDomain = 'samplegame.onstove.com'
|
|
// }
|
|
|
|
const queryParams: Record<string, string> = {
|
|
game_domain: gameDomain,
|
|
lang_code: langCode,
|
|
page_url: pageUrl,
|
|
_t: Date.now().toString(), // 캐시 무효화를 위한 타임스탬프
|
|
}
|
|
|
|
const response = (await commonFetch('GET', apiUrl, {
|
|
headers,
|
|
query: queryParams,
|
|
})) as PageDataResponse | null
|
|
console.log('🚀 ~ pageData.global response:', response.value)
|
|
|
|
// 페이지 접근 권한 설정(로그인 유무)
|
|
if (response?.value?.is_login_required === 1 && !accessToken) {
|
|
// 로그인 레이어 팝업 띄워주기
|
|
const nuxtApp = useNuxtApp()
|
|
const modalStore = useModalStore()
|
|
const $i18n = nuxtApp.$i18n as any
|
|
const { tm } = $i18n
|
|
modalStore.handleOpenConfirm({
|
|
contentText: tm('Alert_StoveLogin'),
|
|
confirmButtonText: tm('Text_StoveLogin'),
|
|
confirmButtonEvent: () => {
|
|
csrGoStoveLogin()
|
|
},
|
|
})
|
|
}
|
|
|
|
if (response?.code === 91002 && response?.message === 'Invalid LangCode') {
|
|
//클릭한 주소는 주소표시줄에 표시하도록 수정
|
|
if (import.meta.client) {
|
|
window.history.replaceState({}, '', to.path)
|
|
}
|
|
// 뒤로가기 이동 시 이전 페이지로 이동되도록 수정
|
|
showError(
|
|
createError({
|
|
statusCode: 404,
|
|
statusMessage: '페이지를 찾을 수 없어요.',
|
|
fatal: false, // 즉시 에러 페이지로
|
|
data: { reason: 'post-not-found Invalid LangCode' },
|
|
})
|
|
)
|
|
}
|
|
|
|
if (response?.code === 91003) {
|
|
// return navigateTo(`/${langCode}/error`, { external: false })
|
|
//클릭한 주소는 주소표시줄에 표시하도록 수정
|
|
if (import.meta.client) {
|
|
window.history.replaceState({}, '', to.path)
|
|
}
|
|
// 뒤로가기 이동 시 이전 페이지로 이동되도록 수정
|
|
showError(
|
|
createError({
|
|
statusCode: 404,
|
|
statusMessage: '페이지를 찾을 수 없어요.',
|
|
fatal: false, // 즉시 에러 페이지로
|
|
data: { reason: 'post-not-found' },
|
|
})
|
|
)
|
|
}
|
|
|
|
if (response?.code === 0 && 'value' in response) {
|
|
pageDataStore.setPageData(response.value)
|
|
} else {
|
|
pageDataStore.clearPageData()
|
|
}
|
|
} catch (error) {
|
|
console.error(error)
|
|
pageDataStore.clearPageData()
|
|
|
|
showError(
|
|
createError({
|
|
statusCode: error.statusCode,
|
|
statusMessage: error.message,
|
|
fatal: false, // 즉시 에러 페이지로
|
|
data: { reason: 'post-not-found' },
|
|
})
|
|
)
|
|
}
|
|
})
|