Files
web-temp/layers/utils/dataUtil.ts
2025-10-20 13:15:54 +09:00

186 lines
5.4 KiB
TypeScript

/**
* 데이터 유틸리티 함수
* @description gameData, pageData 처리에 필요한 유틸리티 함수를 제공합니다.
*/
import type {
PageDataValue,
PageDataResourceContainer,
PageDataTemplateComponents,
PageDataTemplateComponentSet,
PageDataResourceGroupType,
} from '#layers/types/api/pageData'
import type {
OperateComponents,
OperateGroupItem,
} from '#layers/types/api/resourcesData'
/**
* 페이지 데이터를 기반으로 레이아웃 타입을 결정합니다.
* @param pageData 페이지 데이터
* @returns 레이아웃 타입 ('default' | 'promotion')
*/
export const getLayoutType = (
pageData: PageDataValue | null
): 'default' | 'promotion' => {
return pageData?.page_type === 1 ? 'default' : 'promotion'
}
/**
* 이미지 타입인지 확인합니다.
* @param type 리소스 그룹 타입
* @returns 이미지 타입 여부
*/
export const isTypeImage = (type: PageDataResourceGroupType): boolean => {
return (
type === 'IMG_COMM' || type === 'IMG_LANG' || type === 'IMG_COMM_GLOBAL'
)
}
/**
* 비디오 타입인지 확인합니다.
* @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
* @param componentName 컴포넌트 이름
* @param options 옵션 (maxLength: 최대 길이)
* @returns 컴포넌트 컨테이너
*/
export const getComponentContainer = (
components: PageDataTemplateComponents | OperateComponents,
componentName: string,
{ maxLength }: { maxLength?: number } = {}
) => {
if (!components) return []
const container = components[componentName] || []
return maxLength ? container.slice(0, maxLength) : container
}
/**
* 컴포넌트 그룹에 데이터가 존재하는지 확인합니다.
* @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 또는 group 객체
* @param componentName 컴포넌트 이름
* @returns 첫 번째 그룹 데이터 또는 null
*/
export const getComponentGroup = (
components: PageDataTemplateComponents | OperateComponents,
componentName: string
) => {
if (!components) return null
return components[componentName]?.groups?.[0] || null
}
/**
* 컴포넌트 그룹의 모든 데이터를 반환합니다.
* @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 원본 데이터 배열 또는 객체
* @param minCount 최소 보장할 개수 (기본값: 3)
* @returns 최소 개수가 보장된 데이터 배열
*/
export const ensureMinimumSlideData = (
components: PageDataTemplateComponents,
minCount: number = 4
): PageDataTemplateComponentSet[] => {
if (!components) return []
const arrayData = Array.isArray(components.group_sets)
? components.group_sets
: []
// 빈 배열이거나 이미 최소 개수를 만족하면 그대로 반환
if (arrayData.length <= 1 || arrayData.length >= minCount) {
return arrayData
}
// 최소 개수를 보장하기 위해 데이터 반복
const repeatTimes = Math.ceil(minCount / arrayData.length)
return Array(repeatTimes).fill(arrayData).flat()
}
/**
* 슬라이드 데이터를 최소 개수로 보장합니다. (운영 그룹용)
* @param data 원본 데이터 배열
* @param minCount 최소 보장할 개수 (기본값: 3)
* @returns 최소 개수가 보장된 데이터 배열
*/
export const ensureMinimumSlideOperateData = (
data: OperateGroupItem[],
minCount: number = 4
): OperateGroupItem[] => {
// 빈 배열이거나 이미 최소 개수를 만족하면 그대로 반환
if (data.length <= 1 || data.length >= minCount) {
return data
}
// 최소 개수를 보장하기 위해 데이터 반복
const repeatTimes = Math.ceil(minCount / data.length)
return Array(repeatTimes).fill(data).flat()
}
/**
* 현재 시간의 타임스탬프를 반환합니다.
* @param unit 단위 ('ms' | 's') - 밀리초 또는 초
* @returns 타임스탬프
*/
export const getCurrentTimestamp = (unit: 'ms' | 's' = 'ms'): number => {
const now = Date.now()
return unit === 's' ? Math.floor(now / 1000) : now
}