From ec5421d0f2b8a9403086367e5c9a89d0dd42b213 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E2=80=9Chyeonggkim=E2=80=9D?=
<“hyeonggkim@smilegate.com”>
Date: Wed, 3 Dec 2025 21:02:23 +0900
Subject: [PATCH] =?UTF-8?q?fix:=20[PWT-163]=20[front]=20Footer=20>=20JA=20?=
=?UTF-8?q?=ED=91=B8=ED=84=B0=20=EC=9E=90=EA=B8=88=20=EA=B2=B0=EC=A0=9C?=
=?UTF-8?q?=EB=B2=95=20URL=20=EC=84=A4=EC=A0=95=20=EC=98=A4=EB=A5=98?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
layers/components/blocks/Button/Home.vue | 2 +-
layers/components/layouts/Footer.vue | 25 ++++++++++-
layers/components/layouts/Header.vue | 4 +-
layers/middleware/pageData.global.ts | 54 ++++++++++++++++++++++++
layers/server/middleware/gameData.ts | 54 ++++++++++++++++++++++--
5 files changed, 131 insertions(+), 8 deletions(-)
diff --git a/layers/components/blocks/Button/Home.vue b/layers/components/blocks/Button/Home.vue
index 86e20ec..294b4e4 100644
--- a/layers/components/blocks/Button/Home.vue
+++ b/layers/components/blocks/Button/Home.vue
@@ -1,7 +1,7 @@
-
+
diff --git a/layers/components/layouts/Footer.vue b/layers/components/layouts/Footer.vue
index 1fd33b8..2629ea3 100644
--- a/layers/components/layouts/Footer.vue
+++ b/layers/components/layouts/Footer.vue
@@ -264,7 +264,30 @@ const { gameData } = storeToRefs(gameDataStore)
// 공통다국어 data
const footerLinks = computed((): FooterMenuItem[] => {
const menu = (tm as any)('Footer_Menu')
- return Array.isArray(menu) ? (menu as FooterMenuItem[]) : []
+ const menuItems = Array.isArray(menu) ? (menu as FooterMenuItem[]) : []
+
+ // ja일 때 fund_display_yn에 따라 4번째 항목 처리
+ if (locale.value === 'ja') {
+ const fundDisplayYn = footerData.value?.fund_display_yn
+ const fundDisplayUrl = footerData.value?.fund_display_url
+
+ // fund_display_yn이 'y'가 아니면 4번째 항목 제거
+ if (fundDisplayYn !== 'y') {
+ return menuItems.filter((_, index) => index !== 3)
+ }
+
+ // fund_display_yn이 'y'이면 4번째 항목의 url 설정
+ if (fundDisplayYn === 'y' && menuItems[3]) {
+ const updatedMenuItems = [...menuItems]
+ updatedMenuItems[3] = {
+ ...updatedMenuItems[3],
+ url: fundDisplayUrl || updatedMenuItems[3].url
+ }
+ return updatedMenuItems
+ }
+ }
+
+ return menuItems
})
const footerData = ref(gameData.value?.footer_json as unknown as FooterData)
const setDevCi = ref({
diff --git a/layers/components/layouts/Header.vue b/layers/components/layouts/Header.vue
index 3ea429b..955cf4e 100644
--- a/layers/components/layouts/Header.vue
+++ b/layers/components/layouts/Header.vue
@@ -230,7 +230,7 @@ onMounted(() => {
v-if="gnbData"
:class="['game-wrap', { 'is-fixed': isPassedStoveGnb }]"
>
-
+
{
>
-
+
{
const pageUrl = getPathAfterLanguage(to.path)
+ // 루트 경로(언어 코드만 있는 경로)로 접근할 때만 intro.page_url로 리다이렉트
+ const isRootPath = !pageUrl || pageUrl === '' || pageUrl === '/' || pageUrl === `/${langCode}/`
+
+ 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 ||
@@ -38,6 +91,7 @@ export default defineNuxtRouteMiddleware(async (to, _from) => {
pageUrl === '/' ||
pageUrl === `/${langCode}/`
) {
+ console.log("🚀 ~ pageData.global /home 리다이렉트")
return navigateTo(`/${langCode}/home`, { external: false })
}
diff --git a/layers/server/middleware/gameData.ts b/layers/server/middleware/gameData.ts
index e904e5e..1cba1be 100644
--- a/layers/server/middleware/gameData.ts
+++ b/layers/server/middleware/gameData.ts
@@ -377,6 +377,7 @@ export default defineEventHandler(async event => {
'',
'/',
//, ...Object.values(DEFAULT_LOCALE_COVERAGES).flatMap((locale) => [`/${locale}`, `/${locale}/`])
+ console.log("🚀 ~ isHomePath: 여기야??", fullPath)
].includes(fullPath)
if (isHomePath) {
@@ -398,22 +399,67 @@ export default defineEventHandler(async event => {
}
}
// -------------------------------------------------------------------------------
- // [Root Path Redirect to /home]
- // 언어 코드만 있는 경로(예: /ko, /ko/)를 /home 리다이렉트
+ // [Root Path Redirect to /home or intro.page_url]
+ // 언어 코드만 있는 경로(예: /ko, /ko/)를 /home 또는 intro.page_url로 리다이렉트
// -------------------------------------------------------------------------------
const normalizedPath = fullPath.endsWith('/')
? fullPath.slice(0, -1)
: fullPath
const localePath = `/${finalLocale}`
if (normalizedPath === localePath) {
- const defaultPath = `/${finalLocale}/home`
+ // intro.page_url이 있으면 해당 값 사용, 없으면 /home 사용
+ const introPageUrl = response.value?.intro?.page_url
+ let defaultPath = `/${finalLocale}/home`
+
+ if (introPageUrl && introPageUrl.trim() !== '') {
+ // 외부 URL인지 확인
+ const isExternalUrl = introPageUrl.startsWith('http://') || introPageUrl.startsWith('https://')
+
+ if (isExternalUrl) {
+ // 외부 URL인 경우 그대로 사용
+ defaultPath = introPageUrl
+ } else {
+ // 내부 경로인 경우 언어 코드 패턴 확인
+ const normalizedIntroUrl = introPageUrl.split('?')[0] // 쿼리스트링 제외
+ const languagePattern = /^\/[a-z]{2}(-[a-z]{2})?(\/|$)/
+ const hasLanguageCode = languagePattern.test(normalizedIntroUrl)
+
+ if (hasLanguageCode) {
+ // 이미 언어 코드가 있으면 그대로 사용
+ defaultPath = introPageUrl
+ } else {
+ // 언어 코드가 없으면 추가
+ const pathWithSlash = normalizedIntroUrl.startsWith('/')
+ ? normalizedIntroUrl
+ : `/${normalizedIntroUrl}`
+ defaultPath = `/${finalLocale}${pathWithSlash}`
+
+ // 쿼리스트링이 있으면 다시 추가
+ if (introPageUrl.includes('?')) {
+ defaultPath += '?' + introPageUrl.split('?')[1]
+ }
+ }
+ }
+ }
+
const queryString = event?.node.req.url?.includes('?')
? '?' + event.node.req.url.split('?')[1]
: ''
if (!event.node.res.headersSent && !event.node.res.writableEnded) {
+ // 쿼리스트링 처리
+ let redirectUrl = defaultPath
+ if (queryString) {
+ // defaultPath에 이미 쿼리스트링이 있는지 확인
+ if (defaultPath.includes('?')) {
+ redirectUrl = `${defaultPath}&${queryString.substring(1)}`
+ } else {
+ redirectUrl = `${defaultPath}${queryString}`
+ }
+ }
+
event.node.res.statusCode = 302
- event.node.res.setHeader('Location', defaultPath + queryString)
+ event.node.res.setHeader('Location', redirectUrl)
event.node.res.end()
return
}