import { getSiteSettings } from '../repositories/content-repository' import { getAnalyticsSummary } from '../repositories/analytics-repository' import { getPublicBlogStatistics } from '../repositories/blog-statistics-repository' /** * 초 단위 체류 시간을 짧은 한국어 문자열로 변환한다. * @param {number} seconds - 초 단위 시간 * @returns {string} 표시 문자열 */ const formatDuration = (seconds) => { const safeSeconds = Math.max(0, Math.round(Number(seconds) || 0)) if (safeSeconds < 60) { return `${safeSeconds}초` } const minutes = Math.floor(safeSeconds / 60) const restSeconds = safeSeconds % 60 return restSeconds > 0 ? `${minutes}분 ${restSeconds}초` : `${minutes}분` } /** * 숫자를 한국어 단위 문자열로 변환한다. * @param {number} value - 숫자 값 * @param {string} unit - 단위 * @returns {string} 표시 문자열 */ const formatNumberLabel = (value, unit) => `${Number(value || 0).toLocaleString('ko-KR')}${unit}` /** * gethomepage 커스텀 API용 사이트 요약 위젯 데이터를 반환한다. * @returns {Promise} 위젯 데이터 */ export default defineEventHandler(async () => { const [settings, summary, statistics] = await Promise.all([ getSiteSettings(), getAnalyticsSummary({ days: 1 }), getPublicBlogStatistics() ]) const avgEngagedSeconds = summary.todayAvgEngagedSeconds || summary.avgEngagedSeconds || 0 return { title: settings.title || 'sori.studio', updatedAt: new Date().toISOString(), todayVisitors: summary.todayVisitors, totalVisitors: statistics.totalVisitors, todayPageViews: summary.todayPageViews, totalPageViews: statistics.totalPageViews, onlineNow: summary.onlineNow, loggedInNow: summary.loggedInNow, avgEngagedSeconds, visitorsLast7Days: summary.visitorsLast7Days, visitorsLast30Days: summary.visitorsLast30Days, visitorsLast180Days: summary.visitorsLast180Days, visitorsLast365Days: summary.visitorsLast365Days, pageViewsLast30Days: summary.pageViewsLast30Days, totalPosts: statistics.totalPosts, totalComments: statistics.totalComments, totalPages: statistics.totalPages, totalTags: statistics.totalTags, totalMembers: statistics.totalMembers, items: [ { name: '오늘 방문자', label: formatNumberLabel(summary.todayVisitors, '명'), value: summary.todayVisitors }, { name: '오늘 페이지뷰', label: formatNumberLabel(summary.todayPageViews, '회'), value: summary.todayPageViews }, { name: '최근 7일 방문자', label: formatNumberLabel(summary.visitorsLast7Days, '명'), value: summary.visitorsLast7Days }, { name: '최근 30일 방문자', label: formatNumberLabel(summary.visitorsLast30Days, '명'), value: summary.visitorsLast30Days }, { name: '최근 6개월 방문자', label: formatNumberLabel(summary.visitorsLast180Days, '명'), value: summary.visitorsLast180Days }, { name: '최근 1년 방문자', label: formatNumberLabel(summary.visitorsLast365Days, '명'), value: summary.visitorsLast365Days }, { name: '현재 접속자', label: formatNumberLabel(summary.onlineNow, '명'), value: summary.onlineNow }, { name: '평균 체류', label: formatDuration(avgEngagedSeconds), value: avgEngagedSeconds }, { name: '누적 방문자', label: formatNumberLabel(statistics.totalVisitors, '명'), value: statistics.totalVisitors }, { name: '전체 게시글', label: formatNumberLabel(statistics.totalPosts, '개'), value: statistics.totalPosts }, { name: '전체 댓글', label: formatNumberLabel(statistics.totalComments, '개'), value: statistics.totalComments } ] } })