From 9bc8d6f68faf11ed97855e4895f81c547bfc262a Mon Sep 17 00:00:00 2001 From: "opacity@t-win.kr" Date: Fri, 22 Aug 2025 10:14:53 +0900 Subject: [PATCH] =?UTF-8?q?deeplink=20debug=20=EC=BD=94=EB=93=9C=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- com.twin.app.shoptime/src/App/App.js | 106 ++++++-- .../src/App/deepLinkHandler.js | 64 +++++ .../src/actions/commonActions.js | 109 +++++--- com.twin.app.shoptime/src/api/TAxios.js | 245 +++++++++++------- com.twin.app.shoptime/src/lunaSend/common.js | 29 ++- .../src/utils/helperMethods.js | 35 +++ .../src/views/HomePanel/HomePanel.jsx | 2 +- .../src/views/MainView/MainView.jsx | 207 ++++++++++++++- 8 files changed, 633 insertions(+), 164 deletions(-) diff --git a/com.twin.app.shoptime/src/App/App.js b/com.twin.app.shoptime/src/App/App.js index cbeceb2c..bcc6ddc6 100644 --- a/com.twin.app.shoptime/src/App/App.js +++ b/com.twin.app.shoptime/src/App/App.js @@ -71,8 +71,6 @@ import { sendLogTotalRecommend } from "../actions/logActions"; // } from "../utils/focus-monitor"; // import { PanelHoc } from "../components/TPanel/TPanel"; - - let foreGroundChangeTimer = null; // 기존 콘솔 메서드를 백업 @@ -149,15 +147,15 @@ function AppBase(props) { (state) => state.common.appStatus.cursorVisible ); const introTermsAgree = useSelector((state) => state.common.introTermsAgree); - const deviceRegistered = useSelector((state) => state.common.deviceRegistered); + const deviceRegistered = useSelector( + (state) => state.common.deviceRegistered + ); // const optionalTermsAgree = useSelector((state) => state.common.optionalTermsAgree); const termsLoading = useSelector((state) => state.common.termsLoading); // termsFlag 전체 상태 확인 // const termsFlag = useSelector((state) => state.common.termsFlag); const termsData = useSelector((state) => state.home.termsData); - - useEffect(() => { // Chromium68 호환성을 위해 Optional Chaining 제거 if (termsData && termsData.data && termsData.data.terms) { @@ -173,7 +171,8 @@ function AppBase(props) { // const macAddress = useSelector((state) => state.common.macAddress); // Chromium68 호환성을 위해 Optional Chaining 제거 - const deviceCountryCode = httpHeader && httpHeader["X-Device-Country"] || ""; + const deviceCountryCode = + (httpHeader && httpHeader["X-Device-Country"]) || ""; useEffect(() => { if (!cursorVisible && !Spotlight.getCurrent()) { @@ -220,32 +219,67 @@ function AppBase(props) { // }, [dispatch]); // called by [receive httpHeader, launch, relaunch] + const initService = useCallback( - (haveyInit = true) => { - // console.log( // "<<<<<<<<<<<<< appinfo >>>>>>>>>>>>{heavyInit, appinfo} ", // haveyInit, // appinfo // ); + console.log("[DEBUG] httpHeaderRef.current:", httpHeaderRef.current); + console.log("[DEBUG] httpHeader state:", httpHeader); console.log( "[App.js] initService,httpHeaderRef.current", httpHeaderRef.current ); console.log("[App.js] haveyInit", haveyInit); + // 🔍 DEEPLINK DEBUG: HTTP Header 상태 상세 확인 + console.log("🔍 [DEEPLINK DEBUG] ===== HTTP Header 상태 ====="); + console.log( + "🔍 [DEEPLINK DEBUG] httpHeaderRef.current:", + httpHeaderRef.current + ); + console.log("🔍 [DEEPLINK DEBUG] httpHeader state:", httpHeader); + console.log("🔍 [DEEPLINK DEBUG] deviceCountryCode:", deviceCountryCode); + console.log( + "🔍 [DEEPLINK DEBUG] httpHeader null 여부:", + httpHeaderRef.current === null + ); + + if (httpHeaderRef.current) { + console.log( + "🔍 [DEEPLINK DEBUG] ✅ httpHeaderRef.current 존재 - 딥링크 실행 가능" + ); + console.log( + "🔍 [DEEPLINK DEBUG] Country Code:", + httpHeaderRef.current["X-Device-Country"] + ); + console.log( + "🔍 [DEEPLINK DEBUG] Language Code:", + httpHeaderRef.current["X-Device-Language"] + ); + } else { + console.log( + "🔍 [DEEPLINK DEBUG] ❌ httpHeaderRef.current가 null - 딥링크 실행 불가" + ); + } + if (httpHeaderRef.current) { if (haveyInit) { dispatch(changeAppStatus({ connectionFailed: false })); if (typeof window === "object" && window.PalmSystem) { - dispatch( - changeAppStatus({ - // Chromium68 호환성을 위해 Optional Chaining 제거 - cursorVisible: window.PalmSystem && window.PalmSystem.cursor && window.PalmSystem.cursor.visibility, - }) - ); + dispatch( + changeAppStatus({ + // Chromium68 호환성을 위해 Optional Chaining 제거 + cursorVisible: + window.PalmSystem && + window.PalmSystem.cursor && + window.PalmSystem.cursor.visibility, + }) + ); } dispatch(getHomeMenu()); dispatch(getMyRecommandedKeyword()); @@ -260,14 +294,38 @@ function AppBase(props) { JSON.stringify(launchParams) ); + // 🔍 DEEPLINK DEBUG: Launch Parameters 상세 확인 + console.log("🔍 [DEEPLINK DEBUG] ===== Launch Parameters 상태 ====="); + console.log("🔍 [DEEPLINK DEBUG] launchParams:", launchParams); + console.log( + "🔍 [DEEPLINK DEBUG] contentTarget:", + launchParams?.contentTarget + ); + console.log("🔍 [DEEPLINK DEBUG] bypass:", launchParams?.bypass); + console.log( + "🔍 [DEEPLINK DEBUG] contentTarget 존재 여부:", + !!launchParams?.contentTarget + ); + // pyh TODO: edit or delete later (line 196 ~ 198) // Chromium68 호환성을 위해 Optional Chaining 제거 if (launchParams && launchParams.bypass) { + console.log( + "🔍 [DEEPLINK DEBUG] ✅ Bypass 링크 실행:", + launchParams.bypass + ); dispatch(handleBypassLink(launchParams.bypass)); } if (launchParams && launchParams.contentTarget) { + console.log( + "🔍 [DEEPLINK DEBUG] ✅ 딥링크 실행:", + launchParams.contentTarget + ); dispatch(handleDeepLink(launchParams.contentTarget)); } else { + console.log( + "🔍 [DEEPLINK DEBUG] ❌ contentTarget 없음 - 딥링크 실행하지 않음" + ); dispatch( sendLogTotalRecommend({ contextName: Config.LOG_CONTEXT_NAME.ENTRY, @@ -311,11 +369,15 @@ function AppBase(props) { // set foreground flag using delay time. clearTimeout(foreGroundChangeTimer); foreGroundChangeTimer = setTimeout(() => { - console.log( - "visibility changed !!! ==> set to foreground cursorVisible", - // Chromium68 호환성을 위해 Optional Chaining 제거 - JSON.stringify(window.PalmSystem && window.PalmSystem.cursor && window.PalmSystem.cursor.visibility) - ); // eslint-disable-line no-console + console.log( + "visibility changed !!! ==> set to foreground cursorVisible", + // Chromium68 호환성을 위해 Optional Chaining 제거 + JSON.stringify( + window.PalmSystem && + window.PalmSystem.cursor && + window.PalmSystem.cursor.visibility + ) + ); // eslint-disable-line no-console if (platform.platformName !== "webos") { //for debug dispatch( @@ -329,7 +391,10 @@ function AppBase(props) { changeAppStatus({ isAppForeground: true, // Chromium68 호환성을 위해 Optional Chaining 제거 - cursorVisible: window.PalmSystem && window.PalmSystem.cursor && window.PalmSystem.cursor.visibility, + cursorVisible: + window.PalmSystem && + window.PalmSystem.cursor && + window.PalmSystem.cursor.visibility, }) ); } @@ -458,6 +523,7 @@ function AppBase(props) { ? launchParmas.contentTarget.split("_")[1] || "" : "1000"; + console.log("###launchParmas.contentTarget", launchParmas.contentTarget); if (launchParmas.contentTarget) { dispatch( setDeepLink({ diff --git a/com.twin.app.shoptime/src/App/deepLinkHandler.js b/com.twin.app.shoptime/src/App/deepLinkHandler.js index 8c7eaa94..d1bfcecb 100644 --- a/com.twin.app.shoptime/src/App/deepLinkHandler.js +++ b/com.twin.app.shoptime/src/App/deepLinkHandler.js @@ -13,6 +13,16 @@ import { sendLogTotalRecommend } from "../actions/logActions"; //V2_진입경로코드_진입경로명_MT_노출순번 export const handleDeepLink = (contentTarget) => (dispatch, getState) => { console.log("[handleDeepLink] ~ contentTarget: ", contentTarget); + + // 🔍 DEEPLINK DEBUG: 딥링크 핸들러 시작 + console.log("🔍 [DEEPLINK DEBUG] ===== handleDeepLink 실행 ====="); + console.log("🔍 [DEEPLINK DEBUG] contentTarget:", contentTarget); + console.log("🔍 [DEEPLINK DEBUG] contentTarget 타입:", typeof contentTarget); + console.log( + "🔍 [DEEPLINK DEBUG] contentTarget null/undefined 여부:", + contentTarget === null || contentTarget === undefined + ); + let linkTpCd; // 진입경로코드 let linkTpNm; // 진입경로명 let type; // 링크 타입 @@ -29,11 +39,22 @@ export const handleDeepLink = (contentTarget) => (dispatch, getState) => { let tabType; // 카테고리 탭명 if (contentTarget === null || contentTarget === undefined) { + console.log( + "🔍 [DEEPLINK DEBUG] ⚠️ contentTarget이 null/undefined - 기본값 설정" + ); linkTpCd = "1000"; linkTpNm = LOG_MENU.APP; } else { + console.log("🔍 [DEEPLINK DEBUG] ✅ contentTarget 존재 - 파싱 시작"); const tokens = contentTarget.split("_"); + console.log("🔍 [DEEPLINK DEBUG] 토큰 분리 결과:", tokens); + console.log("🔍 [DEEPLINK DEBUG] 버전:", tokens[0]); + console.log("🔍 [DEEPLINK DEBUG] 진입경로코드:", tokens[1]); + console.log("🔍 [DEEPLINK DEBUG] 진입경로명:", tokens[2]); + console.log("🔍 [DEEPLINK DEBUG] 타입:", tokens[3]); + if (tokens[0] === "V2" || tokens[0] === "V3") { + console.log("🔍 [DEEPLINK DEBUG] ✅ 유효한 딥링크 버전:", tokens[0]); linkTpCd = tokens[1]; linkTpNm = tokens[2]; type = tokens[3]; @@ -43,19 +64,34 @@ export const handleDeepLink = (contentTarget) => (dispatch, getState) => { let panelInfo = {}; if (tokens[0] === "V2") { + console.log( + "🔍 [DEEPLINK DEBUG] ⚠️ V2 버전 - HOME_PANEL로 이동 후 종료" + ); panelName = panel_names.HOME_PANEL; return; } + console.log("🔍 [DEEPLINK DEBUG] V3 버전 - 타입별 처리 시작"); + if (parseInt(linkTpCd) < 2000 || parseInt(linkTpCd) > 8999) { + console.log( + "🔍 [DEEPLINK DEBUG] ⚠️ 유효하지 않은 진입경로코드:", + linkTpCd, + "-> 9999로 변경" + ); linkTpCd = "9999"; linkTpNm = LOG_MENU.UNKNOWN; } + console.log("🔍 [DEEPLINK DEBUG] 최종 linkTpCd:", linkTpCd); + console.log("🔍 [DEEPLINK DEBUG] 최종 linkTpNm:", linkTpNm); + console.log("🔍 [DEEPLINK DEBUG] 처리할 타입:", type); + switch (type) { case "MT": // "MT": Main TOP // V3_진입경로코드_진입경로명_MT_노출순번 + console.log("🔍 [DEEPLINK DEBUG] ✅ MT 타입: Main TOP 처리"); panelName = panel_names.HOME_PANEL; deeplinkPanel = "Main TOP"; break; @@ -269,17 +305,45 @@ export const handleDeepLink = (contentTarget) => (dispatch, getState) => { }) ); + // 🔍 DEEPLINK DEBUG: 패널 이동 처리 + console.log("🔍 [DEEPLINK DEBUG] ===== 패널 이동 처리 ====="); + console.log("🔍 [DEEPLINK DEBUG] panelName:", panelName); + console.log("🔍 [DEEPLINK DEBUG] deeplinkPanel:", deeplinkPanel); + console.log("🔍 [DEEPLINK DEBUG] panelInfo:", panelInfo); + if (panelName) { + console.log("🔍 [DEEPLINK DEBUG] ✅ 패널 이동 실행"); const action = panelName === panel_names.HOME_PANEL ? updateHomeInfo : pushPanel; + console.log( + "🔍 [DEEPLINK DEBUG] 사용할 액션:", + panelName === panel_names.HOME_PANEL ? "updateHomeInfo" : "pushPanel" + ); + console.log("🔍 [DEEPLINK DEBUG] 최종 액션 파라미터:", { + name: panelName, + panelInfo: { ...panelInfo, linkTpCd }, + }); + dispatch( action({ name: panelName, panelInfo: { ...panelInfo, linkTpCd }, }) ); + console.log("🔍 [DEEPLINK DEBUG] ✅ 패널 이동 디스패치 완료"); + } else { + console.log( + "🔍 [DEEPLINK DEBUG] ❌ panelName이 없음 - 패널 이동하지 않음" + ); } + } else { + console.log( + "🔍 [DEEPLINK DEBUG] ❌ 유효하지 않은 딥링크 버전:", + tokens[0] + ); } } + + console.log("🔍 [DEEPLINK DEBUG] ===== handleDeepLink 종료 ====="); }; diff --git a/com.twin.app.shoptime/src/actions/commonActions.js b/com.twin.app.shoptime/src/actions/commonActions.js index 84f1f9b1..8d70ba65 100644 --- a/com.twin.app.shoptime/src/actions/commonActions.js +++ b/com.twin.app.shoptime/src/actions/commonActions.js @@ -32,7 +32,7 @@ export const gnbOpened = (status) => ({ }); export const setShowPopup = (config) => { - const payload = typeof config === 'string' ? { activePopup: config } : config; + const payload = typeof config === "string" ? { activePopup: config } : config; return { type: types.SET_SHOW_POPUP, payload, @@ -193,44 +193,80 @@ export const getHttpHeaderForServiceRequest = convertedRes["os_ver"] = version; convertedRes["dvc_auth"] = res["X-Authentication"]; + // 🔍 DEEPLINK DEBUG: 국가 코드 설정 상세 확인 + console.log("🔍 [DEEPLINK DEBUG] ===== 국가 코드 설정 ====="); + console.log("🔍 [DEEPLINK DEBUG] serverType:", serverType); + console.log("🔍 [DEEPLINK DEBUG] ricCodeSetting:", ricCodeSetting); + console.log("🔍 [DEEPLINK DEBUG] languageSetting:", languageSetting); + console.log( + "🔍 [DEEPLINK DEBUG] 원본 X-Device-Country:", + res["X-Device-Country"] + ); + if (serverType !== "system") { if (ricCodeSetting === "eic") { + console.log("🔍 [DEEPLINK DEBUG] EIC 지역 설정 중..."); if (languageSetting === "GB") { + console.log("🔍 [DEEPLINK DEBUG] ✅ GB 설정 적용"); convertedRes["cntry_cd"] = "GB"; convertedRes["X-Device-Country"] = "GB"; res["HOST"] = "GB.nextlgsdp.com"; } if (languageSetting === "DE") { + console.log("🔍 [DEEPLINK DEBUG] ✅ DE 설정 적용"); convertedRes["cntry_cd"] = "DE"; convertedRes["X-Device-Country"] = "DE"; res["HOST"] = "DE.nextlgsdp.com"; } } if (ricCodeSetting === "aic") { + console.log("🔍 [DEEPLINK DEBUG] ✅ AIC 지역 설정 중... US 적용"); convertedRes["cntry_cd"] = "US"; convertedRes["X-Device-Country"] = "US"; res["HOST"] = "US.nextlgsdp.com"; } if (ricCodeSetting === "ruc") { + console.log("🔍 [DEEPLINK DEBUG] ✅ RUC 지역 설정 중... RU 적용"); convertedRes["cntry_cd"] = "RU"; convertedRes["X-Device-Country"] = "RU"; res["HOST"] = "RU.nextlgsdp.com"; } + } else { + console.log( + "🔍 [DEEPLINK DEBUG] ⚠️ serverType이 system - 국가 설정 변경 안함" + ); } + // 🔍 DEEPLINK DEBUG: 언어 코드 설정 확인 + console.log("🔍 [DEEPLINK DEBUG] ===== 언어 코드 설정 ====="); + console.log( + "🔍 [DEEPLINK DEBUG] 최종 cntry_cd:", + convertedRes["cntry_cd"] + ); + if (convertedRes["cntry_cd"] === "US") { convertedRes["lang_cd"] = "en-US"; + console.log("🔍 [DEEPLINK DEBUG] ✅ US 언어 설정: en-US"); } if (convertedRes["cntry_cd"] === "DE") { convertedRes["lang_cd"] = "de-DE"; + console.log("🔍 [DEEPLINK DEBUG] ✅ DE 언어 설정: de-DE"); } if (convertedRes["cntry_cd"] === "GB") { convertedRes["lang_cd"] = "en-GB"; + console.log("🔍 [DEEPLINK DEBUG] ✅ GB 언어 설정: en-GB"); } if (convertedRes["cntry_cd"] === "RU") { convertedRes["lang_cd"] = "ru-RU"; + console.log("🔍 [DEEPLINK DEBUG] ✅ RU 언어 설정: ru-RU"); } + console.log( + "🔍 [DEEPLINK DEBUG] 최종 lang_cd:", + convertedRes["lang_cd"] + ); + console.log("🔍 [DEEPLINK DEBUG] 최종 HOST:", res["HOST"]); + dispatch({ type: types.GET_HTTP_HEADER, payload: convertedRes }); dispatch( changeAppStatus({ @@ -289,25 +325,28 @@ export const getDeviceId = (onComplete) => (dispatch, getState) => { export const getTermsAgreeYn = () => (dispatch, getState) => { dispatch({ type: types.GET_TERMS_AGREE_YN_START }); - + try { const { terms } = getState().home.termsData.data; - console.log("getTermsAgreeYn", terms.map(term => ({ - trmsId: term.trmsId, - trmsTpCd: term.trmsTpCd, - trmsAgrFlag: term.trmsAgrFlag, - trmsPopFlag: term.trmsPopFlag, - }))); + console.log( + "getTermsAgreeYn", + terms.map((term) => ({ + trmsId: term.trmsId, + trmsTpCd: term.trmsTpCd, + trmsAgrFlag: term.trmsAgrFlag, + trmsPopFlag: term.trmsPopFlag, + })) + ); // MST00405 선택약관 정보만 따로 출력 - const optionalTerm = terms.find(term => term.trmsTpCd === 'MST00405'); + const optionalTerm = terms.find((term) => term.trmsTpCd === "MST00405"); if (optionalTerm) { console.log("getTermsAgreeYn MST00405 선택약관:", { trmsId: optionalTerm.trmsId, trmsTpCd: optionalTerm.trmsTpCd, trmsAgrFlag: optionalTerm.trmsAgrFlag, - trmsPopFlag: optionalTerm.trmsPopFlag + trmsPopFlag: optionalTerm.trmsPopFlag, }); } else { console.log("getTermsAgreeYn MST00405 선택약관을 찾을 수 없습니다."); @@ -334,7 +373,7 @@ export const getTermsAgreeYn = () => (dispatch, getState) => { break; } return acc; - }, {}); + }, {}); dispatch({ type: types.GET_TERMS_AGREE_YN_SUCCESS, @@ -758,35 +797,37 @@ export const resetOptionalTermsSession = () => ({ // 선택약관 동의 처리를 위한 헬퍼 함수 export const handleOptionalTermsAgree = () => (dispatch) => { - console.log('[CommonActions] 선택약관 동의 처리'); - dispatch(setOptionalTermsUserDecision('agreed')); + console.log("[CommonActions] 선택약관 동의 처리"); + dispatch(setOptionalTermsUserDecision("agreed")); dispatch(setOptionalTermsPopupShown(true)); }; // 선택약관 거절 처리를 위한 헬퍼 함수 export const handleOptionalTermsDecline = () => (dispatch) => { - console.log('[CommonActions] 선택약관 거절 처리'); - dispatch(setOptionalTermsUserDecision('declined')); + console.log("[CommonActions] 선택약관 거절 처리"); + dispatch(setOptionalTermsUserDecision("declined")); dispatch(setOptionalTermsPopupShown(true)); }; // 선택약관 상태 통합 업데이트 (TV 환경 최적화 - API 호출 없이 즉시 반영) -export const updateOptionalTermsAgreement = (agreed = true) => (dispatch) => { - console.log(`[CommonActions] 선택약관 통합 상태 업데이트: ${agreed}`); - - // 1. optionalTermsPopupFlow 업데이트 (TV 환경용) - dispatch(setOptionalTermsUserDecision(agreed ? 'agreed' : 'declined')); - dispatch(setOptionalTermsPopupShown(true)); - - // 2. 기본 optionalTermsAgree 상태 직접 업데이트 (API 호출 없이) - dispatch({ - type: types.UPDATE_OPTIONAL_TERMS_AGREE_DIRECT, - payload: agreed - }); - - // 3. termsAgreementStatus도 동기화 - dispatch({ - type: types.UPDATE_TERMS_AGREEMENT_STATUS_DIRECT, - payload: { MST00405: agreed } - }); -}; +export const updateOptionalTermsAgreement = + (agreed = true) => + (dispatch) => { + console.log(`[CommonActions] 선택약관 통합 상태 업데이트: ${agreed}`); + + // 1. optionalTermsPopupFlow 업데이트 (TV 환경용) + dispatch(setOptionalTermsUserDecision(agreed ? "agreed" : "declined")); + dispatch(setOptionalTermsPopupShown(true)); + + // 2. 기본 optionalTermsAgree 상태 직접 업데이트 (API 호출 없이) + dispatch({ + type: types.UPDATE_OPTIONAL_TERMS_AGREE_DIRECT, + payload: agreed, + }); + + // 3. termsAgreementStatus도 동기화 + dispatch({ + type: types.UPDATE_TERMS_AGREEMENT_STATUS_DIRECT, + payload: { MST00405: agreed }, + }); + }; diff --git a/com.twin.app.shoptime/src/api/TAxios.js b/com.twin.app.shoptime/src/api/TAxios.js index f288da42..203e8739 100644 --- a/com.twin.app.shoptime/src/api/TAxios.js +++ b/com.twin.app.shoptime/src/api/TAxios.js @@ -1,11 +1,11 @@ -import axios from 'axios'; +import axios from "axios"; -import Spotlight from '@enact/spotlight'; -import { useDispatch } from 'react-redux'; -import { useState } from 'react'; -import { fetchCurrentUserHomeTermsSafe } from '../actions/homeActions'; +import Spotlight from "@enact/spotlight"; +import { useDispatch } from "react-redux"; +import { useState } from "react"; +import { fetchCurrentUserHomeTermsSafe } from "../actions/homeActions"; -import { types } from '../actions/actionTypes'; +import { types } from "../actions/actionTypes"; import { changeAppStatus, changeLocalSettings, @@ -13,22 +13,16 @@ import { setSystemNotice, setSystemTermination, showError, -} from '../actions/commonActions'; +} from "../actions/commonActions"; import { getAuthenticationCode, getReAuthenticationCode, -} from '../actions/deviceActions'; -import { - pushPanel, - resetPanels, -} from '../actions/panelActions'; -import * as Config from '../utils/Config'; -import { ACTIVE_POPUP } from '../utils/Config'; -import * as HelperMethods from '../utils/helperMethods'; -import { - getUrl, - URLS, -} from './apiConfig'; +} from "../actions/deviceActions"; +import { pushPanel, resetPanels } from "../actions/panelActions"; +import * as Config from "../utils/Config"; +import { ACTIVE_POPUP } from "../utils/Config"; +import * as HelperMethods from "../utils/helperMethods"; +import { getUrl, URLS } from "./apiConfig"; let tokenRefreshing = false; const axiosQueue = []; @@ -207,8 +201,23 @@ export const TAxios = ( if (onFail) onFail(res); return; } + // 🔍 DEEPLINK DEBUG: API 에러 코드 확인 + if ( + res?.data?.retCode === 602 || + res?.data?.retCode === 603 || + res?.data?.retCode === 604 + ) { + console.log("🔍 [DEEPLINK DEBUG] ===== API 에러 발생 ====="); + console.log("🔍 [DEEPLINK DEBUG] 에러 코드:", res?.data?.retCode); + console.log("🔍 [DEEPLINK DEBUG] API URL:", url); + console.log("🔍 [DEEPLINK DEBUG] 응답 데이터:", res?.data); + } + // 602 요청 국가 불일치 if (res?.data?.retCode === 602) { + console.log( + "🔍 [DEEPLINK DEBUG] ❌ 602 에러: 요청 국가 불일치 - 국가 변경 팝업 표시" + ); dispatch( setShowPopup(ACTIVE_POPUP.changeCountyPopup, { data: res.data.retCode, @@ -218,6 +227,9 @@ export const TAxios = ( } // 603 서비스 국가 아님 if (res?.data?.retCode === 603) { + console.log( + "🔍 [DEEPLINK DEBUG] ❌ 603 에러: 서비스 지원 안하는 국가 - 지원 안함 팝업 표시" + ); dispatch( setShowPopup(ACTIVE_POPUP.unSupportedCountryPopup, { data: res.data.retCode, @@ -227,6 +239,9 @@ export const TAxios = ( } if (res?.data?.retCode === 604) { + console.log( + "🔍 [DEEPLINK DEBUG] ❌ 604 에러: 서비스 지원 안하는 언어" + ); //todo "NotServiceLanguage" return; } @@ -276,7 +291,7 @@ export const TAxiosPromise = ( success: true, data: response.data, response: response, - error: null + error: null, }); }, // onFail - 에러도 resolve로 처리하여 throw 방지 @@ -286,7 +301,7 @@ export const TAxiosPromise = ( success: false, data: null, response: null, - error: error + error: error, }); }, noTokenRefresh @@ -318,10 +333,14 @@ export const TAxiosAdvancedPromise = ( const attemptRequest = () => { attempts++; - console.log(`TAxiosPromise attempt ${attempts}/${maxAttempts} for ${baseUrl}`); + console.log( + `TAxiosPromise attempt ${attempts}/${maxAttempts} for ${baseUrl}` + ); const timeoutId = setTimeout(() => { - const timeoutError = new Error(`Request timeout after ${timeout}ms for ${baseUrl}`); + const timeoutError = new Error( + `Request timeout after ${timeout}ms for ${baseUrl}` + ); if (throwOnError) { reject(timeoutError); } else { @@ -329,7 +348,7 @@ export const TAxiosAdvancedPromise = ( success: false, data: null, response: null, - error: timeoutError + error: timeoutError, }); } }, timeout); @@ -344,22 +363,29 @@ export const TAxiosAdvancedPromise = ( // onSuccess (response) => { clearTimeout(timeoutId); - console.log(`TAxiosPromise success on attempt ${attempts} for ${baseUrl}`); + console.log( + `TAxiosPromise success on attempt ${attempts} for ${baseUrl}` + ); resolve({ success: true, data: response.data, response: response, - error: null + error: null, }); }, // onFail (error) => { clearTimeout(timeoutId); - console.error(`TAxiosPromise error on attempt ${attempts} for ${baseUrl}:`, error); - + console.error( + `TAxiosPromise error on attempt ${attempts} for ${baseUrl}:`, + error + ); + // 재시도 로직 if (attempts < maxAttempts) { - console.log(`Retrying in ${retryDelay}ms... (${attempts}/${maxAttempts})`); + console.log( + `Retrying in ${retryDelay}ms... (${attempts}/${maxAttempts})` + ); setTimeout(() => { attemptRequest(); }, retryDelay); @@ -372,7 +398,7 @@ export const TAxiosAdvancedPromise = ( success: false, data: null, response: null, - error: error + error: error, }); } } @@ -386,23 +412,51 @@ export const TAxiosAdvancedPromise = ( }; // HTTP 메소드별 편의 함수들 (안전한 버전) -export const TAxiosGet = async (dispatch, getState, baseUrl, urlParams = {}, options = {}) => { - return await TAxiosPromise(dispatch, getState, 'get', baseUrl, urlParams, {}, options.noTokenRefresh); +export const TAxiosGet = async ( + dispatch, + getState, + baseUrl, + urlParams = {}, + options = {} +) => { + return await TAxiosPromise( + dispatch, + getState, + "get", + baseUrl, + urlParams, + {}, + options.noTokenRefresh + ); }; -export const TAxiosPost = async (dispatch, getState, baseUrl, params = {}, options = {}) => { - return await TAxiosPromise(dispatch, getState, 'post', baseUrl, {}, params, options.noTokenRefresh); +export const TAxiosPost = async ( + dispatch, + getState, + baseUrl, + params = {}, + options = {} +) => { + return await TAxiosPromise( + dispatch, + getState, + "post", + baseUrl, + {}, + params, + options.noTokenRefresh + ); }; // 안전한 다중 요청 처리 export const TAxiosAll = async (requests) => { try { const results = await Promise.all(requests); - + // 모든 결과를 안전하게 처리 const successResults = []; const failedResults = []; - + results.forEach((result, index) => { if (result.success) { successResults.push({ index, result: result.data }); @@ -410,20 +464,20 @@ export const TAxiosAll = async (requests) => { failedResults.push({ index, error: result.error }); } }); - + return { success: failedResults.length === 0, successResults, failedResults, - allResults: results + allResults: results, }; } catch (error) { - console.error('TAxiosAll unexpected error:', error); + console.error("TAxiosAll unexpected error:", error); return { success: false, successResults: [], failedResults: [{ index: -1, error }], - allResults: [] + allResults: [], }; } }; @@ -432,7 +486,7 @@ export const TAxiosAll = async (requests) => { export const TAxiosSequential = async (requests) => { const results = []; const errors = []; - + for (let i = 0; i < requests.length; i++) { try { const result = await requests[i]; @@ -444,33 +498,37 @@ export const TAxiosSequential = async (requests) => { } } catch (error) { errors.push({ index: i, error }); - console.error(`TAxiosSequential unexpected error at request ${i}:`, error); + console.error( + `TAxiosSequential unexpected error at request ${i}:`, + error + ); } } - + return { success: errors.length === 0, results, - errors + errors, }; }; // 안전한 Redux Thunk 헬퍼 export const createSafeApiThunk = (apiCall) => { - return (...args) => async (dispatch, getState) => { - try { - const result = await apiCall(dispatch, getState, ...args); - return result; // 이미 안전한 형태로 반환됨 - } catch (error) { - console.error('API thunk unexpected error:', error); - return { - success: false, - data: null, - response: null, - error - }; - } - }; + return (...args) => + async (dispatch, getState) => { + try { + const result = await apiCall(dispatch, getState, ...args); + return result; // 이미 안전한 형태로 반환됨 + } catch (error) { + console.error("API thunk unexpected error:", error); + return { + success: false, + data: null, + response: null, + error, + }; + } + }; }; // 실제 사용 예시들 (안전한 버전) @@ -480,16 +538,16 @@ export const safeUsageExamples = { const result = await TAxiosPromise( dispatch, getState, - 'get', + "get", URLS.GET_HOME_TERMS, { trmsTpCdList: "MST00401, MST00402", mbrNo: "12345" } ); - + if (result.success) { - console.log('Success:', result.data); + console.log("Success:", result.data); return result.data; } else { - console.error('API call failed:', result.error); + console.error("API call failed:", result.error); // 에러를 throw하지 않고 기본값 반환하거나 사용자에게 안내 return null; } @@ -497,26 +555,24 @@ export const safeUsageExamples = { // 2. retCode 체크를 포함한 안전한 처리 safeWithRetCodeCheck: async (dispatch, getState) => { - const result = await TAxiosGet( - dispatch, - getState, - URLS.GET_HOME_TERMS, - { trmsTpCdList: "MST00401, MST00402", mbrNo: "12345" } - ); - + const result = await TAxiosGet(dispatch, getState, URLS.GET_HOME_TERMS, { + trmsTpCdList: "MST00401, MST00402", + mbrNo: "12345", + }); + if (!result.success) { - console.error('Network error:', result.error); - return { success: false, message: '네트워크 오류가 발생했습니다.' }; + console.error("Network error:", result.error); + return { success: false, message: "네트워크 오류가 발생했습니다." }; } - + if (result.data.retCode !== 0) { - console.error('API error:', result.data.retCode, result.data.retMsg); - return { - success: false, - message: result.data.retMsg || 'API 오류가 발생했습니다.' + console.error("API error:", result.data.retCode, result.data.retMsg); + return { + success: false, + message: result.data.retMsg || "API 오류가 발생했습니다.", }; } - + return { success: true, data: result.data }; }, @@ -525,40 +581,41 @@ export const safeUsageExamples = { const requests = [ TAxiosGet(dispatch, getState, URLS.GET_HOME_TERMS, { mbrNo: "12345" }), TAxiosGet(dispatch, getState, URLS.GET_USER_INFO, { mbrNo: "12345" }), - TAxiosPost(dispatch, getState, URLS.UPDATE_SETTINGS, { setting: "value" }) + TAxiosPost(dispatch, getState, URLS.UPDATE_SETTINGS, { + setting: "value", + }), ]; - + const result = await TAxiosAll(requests); - + if (result.success) { - console.log('All requests succeeded'); - return result.successResults.map(item => item.result); + console.log("All requests succeeded"); + return result.successResults.map((item) => item.result); } else { - console.error('Some requests failed:', result.failedResults); + console.error("Some requests failed:", result.failedResults); // 부분적 성공도 처리 가능 return { - successData: result.successResults.map(item => item.result), - errors: result.failedResults + successData: result.successResults.map((item) => item.result), + errors: result.failedResults, }; } - } + }, }; - // 컴포넌트에서의 안전한 사용법 export const ComponentUsageExample = () => { const dispatch = useDispatch(); const [loading, setLoading] = useState(false); const [error, setError] = useState(null); - + const handleFetchTerms = async () => { setLoading(true); setError(null); - + const result = await dispatch(fetchCurrentUserHomeTermsSafe()); - + setLoading(false); - + if (result.success) { console.log("Terms fetched successfully"); // 성공 처리 (예: 성공 토스트 표시) @@ -568,13 +625,13 @@ export const ComponentUsageExample = () => { // 에러 처리 (예: 에러 토스트 표시) } }; - + return (
{error &&
{error}
}
); -}; \ No newline at end of file +}; diff --git a/com.twin.app.shoptime/src/lunaSend/common.js b/com.twin.app.shoptime/src/lunaSend/common.js index 65a3db16..b8960a48 100644 --- a/com.twin.app.shoptime/src/lunaSend/common.js +++ b/com.twin.app.shoptime/src/lunaSend/common.js @@ -167,22 +167,29 @@ export const getSystemSettings = ( }; export function checkValidCountry(ricCode, country) { + // 🔍 DEEPLINK DEBUG: 국가 유효성 검사 + console.log("🔍 [DEEPLINK DEBUG] ===== checkValidCountry 실행 ====="); + console.log("🔍 [DEEPLINK DEBUG] ricCode:", ricCode); + console.log("🔍 [DEEPLINK DEBUG] country:", country); + + let result = false; + if (ricCode === "aic") { - if (country === "US") return true; - else return false; + result = country === "US"; + console.log("🔍 [DEEPLINK DEBUG] AIC 지역 - US 검사 결과:", result); } else if (ricCode === "eic") { - if (country === "GB" || country === "DE") return true; - else return false; + result = country === "GB" || country === "DE"; + console.log("🔍 [DEEPLINK DEBUG] EIC 지역 - GB/DE 검사 결과:", result); } else if (ricCode === "ruc") { - if (country === "RU") return true; - else return false; + result = country === "RU"; + console.log("🔍 [DEEPLINK DEBUG] RUC 지역 - RU 검사 결과:", result); } else { - if (country === "US") { - return true; - } else { - return false; - } + result = country === "US"; + console.log("🔍 [DEEPLINK DEBUG] 기타 지역 - US 기본값 검사 결과:", result); } + + console.log("🔍 [DEEPLINK DEBUG] 최종 유효성 검사 결과:", result); + return result; } // 3.0 ~ 4.5 diff --git a/com.twin.app.shoptime/src/utils/helperMethods.js b/com.twin.app.shoptime/src/utils/helperMethods.js index 704fe362..e30828a8 100644 --- a/com.twin.app.shoptime/src/utils/helperMethods.js +++ b/com.twin.app.shoptime/src/utils/helperMethods.js @@ -150,21 +150,56 @@ let localLaunchParams = { export const getLaunchParams = () => { let params = {}; + // 🔍 DEEPLINK DEBUG: Launch Parameters 파싱 과정 확인 + console.log("🔍 [DEEPLINK DEBUG] ===== getLaunchParams 실행 ====="); + console.log( + "🔍 [DEEPLINK DEBUG] window 객체 존재:", + typeof window === "object" + ); + console.log( + "🔍 [DEEPLINK DEBUG] PalmSystem 존재:", + !!(typeof window === "object" && window.PalmSystem) + ); + console.log( + "🔍 [DEEPLINK DEBUG] launchParams 존재:", + !!( + typeof window === "object" && + window.PalmSystem && + window.PalmSystem.launchParams + ) + ); + if ( typeof window === "object" && window.PalmSystem && window.PalmSystem.launchParams ) { + console.log( + "🔍 [DEEPLINK DEBUG] 원본 launchParams:", + window.PalmSystem.launchParams + ); try { params = JSON.parse(window.PalmSystem.launchParams); + console.log("🔍 [DEEPLINK DEBUG] JSON 파싱 성공:", params); + if (params["x-webos-app-container-launch"] === true) { + console.log( + "🔍 [DEEPLINK DEBUG] x-webos-app-container-launch 감지 - details 사용" + ); params = params.details; + console.log("🔍 [DEEPLINK DEBUG] details 파라미터:", params); } } catch (e) { + console.log("🔍 [DEEPLINK DEBUG] ❌ JSON 파싱 실패:", e); params = {}; } + console.log("🔍 [DEEPLINK DEBUG] ✅ 최종 params:", params); return params; } else { + console.log( + "🔍 [DEEPLINK DEBUG] ⚠️ PalmSystem 없음 - localLaunchParams 사용" + ); + console.log("🔍 [DEEPLINK DEBUG] localLaunchParams:", localLaunchParams); return localLaunchParams; } }; diff --git a/com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx b/com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx index 220d6de7..b428cdd4 100644 --- a/com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx +++ b/com.twin.app.shoptime/src/views/HomePanel/HomePanel.jsx @@ -499,7 +499,7 @@ const HomePanel = ({ isOnTop }) => { ); dispatch(getTop20Show()); dispatch(getBestSeller(bestSellerLoaded)); - + console.log("###isDeepLink", isDeepLink); if (isDeepLink) { dispatch(setDeepLink({ contentTarget: "", isDeepLink: false })); } diff --git a/com.twin.app.shoptime/src/views/MainView/MainView.jsx b/com.twin.app.shoptime/src/views/MainView/MainView.jsx index 3d25c49f..c2283f20 100644 --- a/com.twin.app.shoptime/src/views/MainView/MainView.jsx +++ b/com.twin.app.shoptime/src/views/MainView/MainView.jsx @@ -170,6 +170,15 @@ export default function MainView({ className, initService }) { (state) => state.common.appStatus.isInternetConnected ); + // 🔍 DEEPLINK DEBUG: 딥링크 디버깅을 위한 추가 상태들 + const contentTarget = useSelector( + (state) => state.common.deepLink?.contentTarget + ); + const introTermsAgree = useSelector((state) => state.common.introTermsAgree); + const deviceRegistered = useSelector( + (state) => state.common.deviceRegistered + ); + const deviceCountryCode = httpHeader?.["X-Device-Country"] || ""; const isLogSentRef = useRef(false); const watchRecord = useSelector((state) => state.localSettings?.watchRecord); @@ -181,6 +190,23 @@ export default function MainView({ className, initService }) { const topPanel = panels[panels.length - 1]; + // 🔍 DEEPLINK DEBUG: 딥링크 관련 상태 변화 추적 + useEffect(() => { + console.log("🔍 [DEEPLINK DEBUG] ===== MainView 상태 변화 ====="); + console.log("🔍 [DEEPLINK DEBUG] contentTarget:", contentTarget); + console.log("🔍 [DEEPLINK DEBUG] httpHeader 존재:", !!httpHeader); + console.log("🔍 [DEEPLINK DEBUG] deviceRegistered:", deviceRegistered); + console.log("🔍 [DEEPLINK DEBUG] introTermsAgree:", introTermsAgree); + console.log( + "🔍 [DEEPLINK DEBUG] 현재 패널:", + panels[panels.length - 1]?.name + ); + console.log( + "🔍 [DEEPLINK DEBUG] 딥링크 실행 가능:", + !!(contentTarget && httpHeader && deviceRegistered && introTermsAgree) + ); + }, [contentTarget, httpHeader, deviceRegistered, introTermsAgree, panels]); + useEffect(() => { console.log("🔍 MainView 팝업 상태 변경:", { popupVisible, @@ -829,7 +855,7 @@ export default function MainView({ className, initService }) { /> )} */} {/* /딥링크 테스트 */} - {/*
- deepLinkInfo -

{contentTarget}

-
*/} +
+

+ 🔍 딥링크 디버깅 정보 +

+ + {/* 딥링크 실행 상태 종합 판단 */} +
+ 🎯 딥링크 실행 가능 여부:
+ + {contentTarget && + httpHeader && + deviceRegistered && + introTermsAgree + ? "✅ 실행 가능" + : "❌ 실행 불가"} + +
+ +
+ 📱 contentTarget:
+ + {contentTarget || "❌ 없음"} + +
+ +
+ 🌍 HTTP Header: + + {httpHeader ? "✅" : "❌"} + + {httpHeader && ( +
+ • {httpHeader["X-Device-Country"] || "국가미설정"} /{" "} + {httpHeader["X-Device-Language"] || "언어미설정"} +
+ )} +
+ +
+ 🔧 현재 패널: + + {panels?.length > 0 + ? panels[panels.length - 1]?.name || "이름없음" + : "없음"} + + + (총 {panels?.length || 0}개) + +
+ +
+ ⚙️ 필수 조건:
+
+ • webOS: {webOSVersion || "❓"} + = 4 + ? "#00ff00" + : "#ff0000", + marginLeft: "4px", + }} + > + {webOSVersion && Number(webOSVersion) >= 4 ? "✅" : "❌"} + {" "} +
• 디바이스: + + {deviceRegistered ? "✅" : "❌"} + {" "} +
• 약관동의: + + {introTermsAgree ? "✅" : "❌"} + +
+
+ +
+ 🚨 에러: + + {errorCode ? `❌ ${errorCode}` : "✅ 정상"} + +
+ +
+ 🌐 연결상태: + + {isInternetConnected ? "✅ 연결됨" : "❌ 연결안됨"} + +
+ +
+ 💡 콘솔에서 "🔍 [DEEPLINK DEBUG]" 로그를 확인하세요
+ 🕒 {new Date().toLocaleTimeString()} +
+
+ ); }