208 lines
5.8 KiB
TypeScript
208 lines
5.8 KiB
TypeScript
/**
|
|
* 데이터 유틸리티 함수
|
|
* @description gameData, pageData 처리에 필요한 유틸리티 함수를 제공합니다.
|
|
*/
|
|
|
|
import type { OsType, PlatformType } from '#layers/types/api/gameData'
|
|
import type {
|
|
PageDataValue,
|
|
PageDataResourceContainer,
|
|
PageDataTemplateComponents,
|
|
PageDataResourceGroup,
|
|
PageDataResourceGroupType,
|
|
} from '#layers/types/api/pageData'
|
|
import type { OperateComponents } from '#layers/types/api/operateResources'
|
|
|
|
const OS_TYPE_MAP: Record<string, string[]> = {
|
|
'1': ['google_play'],
|
|
'2': ['app_store'],
|
|
'3': ['google_play', 'app_store'],
|
|
}
|
|
|
|
/**
|
|
* OS 타입에 따라 가능한 플랫폼 목록을 반환합니다.
|
|
*/
|
|
export const getSupportedPlatforms = (
|
|
osType: OsType,
|
|
platformType: PlatformType
|
|
): string[] => {
|
|
const storePlatforms = OS_TYPE_MAP[osType] ?? []
|
|
|
|
switch (platformType) {
|
|
case '1': // PC 전용
|
|
return ['pc']
|
|
|
|
case '2': // 모바일 스토어 전용
|
|
return storePlatforms
|
|
|
|
default:
|
|
case '3': // PC + 모바일 스토어 모두
|
|
return ['pc', ...storePlatforms]
|
|
}
|
|
}
|
|
|
|
/**
|
|
* 페이지 데이터를 기반으로 레이아웃 타입을 결정합니다.
|
|
* @param pageData 페이지 데이터
|
|
* @returns 레이아웃 타입 ('default' | 'promotion')
|
|
*/
|
|
export const getLayoutType = (
|
|
pageData: PageDataValue | null
|
|
): 'default' | 'promotion' => {
|
|
return pageData?.page_type === 2 ? 'promotion' : 'default'
|
|
}
|
|
|
|
/**
|
|
* 이미지 타입인지 확인합니다.
|
|
* @param type 리소스 그룹 타입
|
|
* @returns 이미지 타입 여부
|
|
*/
|
|
export const isTypeImage = (type: PageDataResourceGroupType): boolean => {
|
|
return (
|
|
type === 'IMG_COMM' ||
|
|
type === 'IMG_LANG' ||
|
|
type === 'IMG_COMM_GLOBAL' ||
|
|
type === 'IMG'
|
|
)
|
|
}
|
|
|
|
/**
|
|
* 비디오 타입인지 확인합니다.
|
|
* @param type 리소스 그룹 타입
|
|
* @returns 비디오 타입 여부
|
|
*/
|
|
export const isTypeVideo = (type: PageDataResourceGroupType): boolean => {
|
|
return type === 'VID'
|
|
}
|
|
|
|
/**
|
|
* 텍스트 타입인지 확인합니다.
|
|
* @param type 리소스 그룹 타입
|
|
* @returns 텍스트 타입 여부
|
|
*/
|
|
export const isTypeText = (type: PageDataResourceGroupType): boolean => {
|
|
return type === 'TXT'
|
|
}
|
|
|
|
/**
|
|
* 버튼 타입인지 확인합니다.
|
|
* @param type 리소스 그룹 타입
|
|
* @returns 버튼 타입 여부
|
|
*/
|
|
export const isTypeButton = (type: PageDataResourceGroupType): boolean => {
|
|
return type === 'BTN'
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 그룹에 데이터가 존재하는지 확인합니다.
|
|
* @param components props.components 또는 group 객체
|
|
* @param componentName 컴포넌트 이름
|
|
* @returns 데이터 존재 여부
|
|
*/
|
|
export const hasComponentGroup = (
|
|
components: PageDataTemplateComponents,
|
|
componentName: string
|
|
): boolean => {
|
|
if (!components) return false
|
|
|
|
const component = components[componentName] as PageDataResourceContainer
|
|
return component?.groups && component.groups.length > 0
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 컨테이너를 반환합니다.
|
|
* @param components props.components
|
|
* @param componentName 컴포넌트 이름
|
|
* @param options 옵션
|
|
* - isGroup: groups 속성에서 데이터 가져오기 (기본값: false)
|
|
* - maxLength: 최대 길이 제한
|
|
* - minLength: 최소 길이 보장 (데이터 반복)
|
|
* @returns 컴포넌트 컨테이너 배열
|
|
*/
|
|
export const getComponentContainer = (
|
|
components: PageDataTemplateComponents | OperateComponents,
|
|
componentName: string,
|
|
options: { isGroup?: boolean; maxLength?: number; minLength?: number } = {}
|
|
) => {
|
|
if (!components) return []
|
|
|
|
const { isGroup = false, maxLength, minLength } = options
|
|
|
|
// 1. 초기 컨테이너 가져오기
|
|
const component = components[componentName]
|
|
if (!component) return []
|
|
|
|
let result = isGroup && 'groups' in component ? component.groups : component
|
|
|
|
// 2. 최소 길이 보장 (데이터 복제)
|
|
if (minLength && result.length > 1 && result.length < minLength) {
|
|
const repeatTimes = Math.ceil(minLength / result.length)
|
|
result = Array(repeatTimes).fill(result).flat()
|
|
}
|
|
|
|
// 3. 최대 길이 제한
|
|
if (maxLength && result.length > maxLength) {
|
|
return result.slice(0, maxLength)
|
|
}
|
|
|
|
return result
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 그룹의 모든 데이터를 반환합니다.
|
|
* @param components props.components 또는 group 객체
|
|
* @param componentName 컴포넌트 이름
|
|
* @returns 그룹 배열 데이터
|
|
*/
|
|
export const getComponentGroupAry = (
|
|
components: PageDataTemplateComponents | OperateComponents,
|
|
componentName: string
|
|
) => {
|
|
if (!components) return []
|
|
|
|
return components[componentName]?.groups || []
|
|
}
|
|
|
|
/**
|
|
* 컴포넌트 그룹의 첫 번째 데이터를 반환합니다.
|
|
* @param components props.components 또는 group 객체
|
|
* @param componentName 컴포넌트 이름
|
|
* @returns 첫 번째 그룹 데이터 또는 null
|
|
*/
|
|
export const getComponentGroup = (
|
|
components: PageDataTemplateComponents | OperateComponents,
|
|
componentName: string
|
|
) => {
|
|
if (!components) return null
|
|
|
|
return components[componentName]?.groups?.[0] || null
|
|
}
|
|
|
|
/**
|
|
* 리소스 데이터를 기반으로 리소스 경로를 반환합니다.
|
|
* @param resourcesData 리소스 데이터
|
|
* @param resourcesType 리소스 타입
|
|
* - IMG: 이미지
|
|
* - VID: 비디오
|
|
* @returns 리소스 경로 객체 (pc: PC 버전, mo: 모바일 버전) 또는 null
|
|
*/
|
|
export const getResourceSrc = (
|
|
resourcesData: PageDataResourceGroup,
|
|
resourcesType?: 'IMG' | 'VID'
|
|
) => {
|
|
if (!resourcesData) return null
|
|
const resPath = resourcesData?.res_path
|
|
const resType = resourcesType || resourcesData?.resource_type
|
|
|
|
const pcField = isTypeVideo(resType) ? 'path_vid_pc' : 'path_pc'
|
|
const mobileField = isTypeVideo(resType) ? 'path_vid_mo' : 'path_mo'
|
|
|
|
const pcPath = resPath?.[pcField] || resPath?.[mobileField] || ''
|
|
const mobilePath = resPath?.[mobileField] || resPath?.[pcField] || ''
|
|
|
|
return {
|
|
pc: pcPath,
|
|
mo: mobilePath,
|
|
}
|
|
}
|