/** * 统计分析 API(Phase 3 Task 4 实装调用函数;类型与端点 Task 3 建立) * * 端点事实源:app/platform/routes/stats_routes.py + app/platform/stats.py * (平台合并统计 / 单租户统计,?from/&to= 闭区间)。 * * 指标口径事实源:app/platform/stats.py 模块 docstring 的口径表—— * 会话数不要求有消息 / 线索=留资三选一(phone/whatsapp/email)任一非空 / * 高意向=评估 interested / 推送成功率 success/(success+failed)(分母 0 → * null,前端展示"—")。Task 8(统计分析页)复用本组函数。 */ import { http } from './client' /** 指标卡(None 项为 null——如无推送时成功率无定义) */ export interface StatsCards { conversations: number leads: number high_intent: number push_success_rate: number | null } /** 漏斗计数 */ export interface StatsFunnel { conversations: number leads: number evaluated: number push_succeeded: number } /** 按日趋势行 */ export interface StatsTrendPoint { date: string conversations: number leads: number } /** 分布视图(intent 按枚举键、source/site 计数表、country Top 数组) */ export interface StatsDistributions { intent: Record source: Record site: Record country: Array<{ country: string; count: number }> } /** 推送健康计数 */ export interface PushHealth { pending: number success: number failed: number skipped: number duplicated: number } /** 统计响应(平台合并与单租户同构) */ export interface StatsResponse { cards: StatsCards funnel: StatsFunnel trend: StatsTrendPoint[] distributions: StatsDistributions push_health: PushHealth } /** 统计查询参数(from/to 闭区间,ISO 日期) */ export interface StatsParams { from?: string to?: string } /** 统计端点(platform 合并版仅超管;单租户版超管或本租户管理员) */ export const STATS_ENDPOINTS = { platform: '/api/platform/stats', tenant: (slug: string) => `/api/platform/tenants/${slug}/stats` } as const /** 平台合并统计查询参数(?tenant= 单租户下钻,未知 slug 404) */ export interface PlatformStatsParams extends StatsParams { tenant?: string } /** * 平台统计(仅超管):缺省全部租户合并(逐库查询应用层合并); * tenant=slug 单租户下钻——仪表盘租户卡片墙逐租户调用即此形态。 * options.showErrorMessage: false 关全局错误提示(卡片墙 N 连发的失败 * toast 改由调用方逐卡内联展示) */ export function fetchPlatformStats( params?: PlatformStatsParams, options?: { showErrorMessage?: boolean } ): Promise { return http.get(STATS_ENDPOINTS.platform, { params, ...options }) } /** * 单租户统计(本租户管理员或超管):租户管理员的"自己指标卡"走这里, * slug 取登录态 tenant_slug(auth store) */ export function fetchTenantStats(slug: string, params?: StatsParams): Promise { return http.get(STATS_ENDPOINTS.tenant(slug), { params }) }