import { computeDateRange, toDateOnly } from './dateRange.uts' import { rpcOrEmptyArray, rpcOrNull } from './rpc.uts' // --- Type Definitions --- export type UserKpis = { total_users: number user_growth: number new_users: number new_user_growth: number active_users: number // DAU active_growth: number paid_users: number paid_growth: number new_user_conversion_rate: number repurchase_rate: number } export type UserGrowthTrend = { dates: Array newUsers: Array activeUsers: Array } export type UserActivity = { dau: number wau: number mau: number } export type UserRetention = { days: Array // e.g., '次日', '3日', '7日', '14日', '30日' rates: Array } export type NewVsOldComparison = { categories: Array // e.g., 'GMV', '订单数', '客单价' newUserData: Array oldUserData: Array } // --- Helper --- function safeNumber(v: any): number { const n = Number(v) return isFinite(n) ? n : 0 } // --- Service Functions --- export async function fetchUserKpis(period: string): Promise { const { startIso, endIso } = computeDateRange(period) const row = await rpcOrNull('rpc_analytics_user_kpis', { p_start_date: toDateOnly(startIso), p_end_date: toDateOnly(endIso) } as any) const obj: any = row != null ? row : ({} as any) return { total_users: safeNumber(obj.getAny?.('total_users') ?? 0), user_growth: safeNumber(obj.getAny?.('user_growth') ?? 0), new_users: safeNumber(obj.getAny?.('new_users') ?? 0), new_user_growth: safeNumber(obj.getAny?.('new_user_growth') ?? 0), active_users: safeNumber(obj.getAny?.('active_users') ?? 0), active_growth: safeNumber(obj.getAny?.('active_growth') ?? 0), paid_users: safeNumber(obj.getAny?.('paid_users') ?? 0), // Placeholder paid_growth: safeNumber(obj.getAny?.('paid_growth') ?? 0), // Placeholder new_user_conversion_rate: safeNumber(obj.getAny?.('new_user_conversion_rate') ?? 0), // Placeholder repurchase_rate: safeNumber(obj.getAny?.('repurchase_rate') ?? 0) } } export async function fetchUserGrowthTrend(period: string): Promise { const { startIso, endIso } = computeDateRange(period) const rows = await rpcOrEmptyArray('rpc_analytics_user_growth_trend', { p_start_date: toDateOnly(startIso), p_end_date: toDateOnly(endIso) } as any) const dates: Array = [] const newUsers: Array = [] const activeUsers: Array = [] for (let i = 0; i < rows.length; i++) { const r: any = rows[i] const d = `${r.getAny?.('date') ?? ''}` dates.push(d.length >= 10 ? d.slice(5) : d) newUsers.push(safeNumber(r.getAny?.('new_users') ?? 0)) activeUsers.push(safeNumber(r.getAny?.('active_users') ?? 0)) } return { dates, newUsers, activeUsers } } // Placeholder for functions that need new RPCs export async function fetchUserActivity(period: string): Promise { console.warn('fetchUserActivity needs rpc_analytics_user_activity RPC') return { dau: 0, wau: 0, mau: 0 } } export async function fetchUserRetention(period: string): Promise { console.warn('fetchUserRetention needs rpc_analytics_user_retention RPC') return { days: ['次日', '3日', '7日', '14日', '30日'], rates: [0, 0, 0, 0, 0] } } export async function fetchNewVsOldComparison(period: string): Promise { console.warn('fetchNewVsOldComparison needs rpc_analytics_new_vs_old_users RPC') return { categories: ['GMV', '订单数', '客单价'], newUserData: [0, 0, 0], oldUserData: [0, 0, 0] } } export async function fetchConversionFunnel(period: string): Promise> { console.warn('fetchConversionFunnel needs rpc_analytics_conversion_funnel RPC') return [ { step: '访问', value: 0 }, { step: '详情页', value: 0 }, { step: '加购', value: 0 }, { step: '下单', value: 0 }, { step: '支付', value: 0 } ] }