/** * 统计时间快捷范围(Phase 3 Task 4 仪表盘;Task 8 统计分析复用) * * 口径事实源:app/platform/routes/stats_routes.py 的 from/to 解析 * (data_routes._parse_dt)——前端只传本地日期串 YYYY-MM-DD: * - 日期-only 的 to 后端视为含当日全天(23:59:59.999999,边界含); * - 边界是 naive UTC(与库内 created_at 同一对比空间),前端不做时区换算; * - "近 N 天" = 含今天往回共 N 天(今天 / 近7天 / 近30天)。 */ export type StatsQuickRange = 'today' | 'last7' | 'last30' /** 快捷范围清单(顺序即切换器展示序) */ export const STATS_QUICK_RANGES: Array<{ value: StatsQuickRange label: string /** 窗口天数(含今天) */ days: number }> = [ { value: 'today', label: '今天', days: 1 }, { value: 'last7', label: '近7天', days: 7 }, { value: 'last30', label: '近30天', days: 30 } ] /** Date → 本地日期串 YYYY-MM-DD(月/日两位补零) */ function toDateKey(date: Date): string { const month = String(date.getMonth() + 1).padStart(2, '0') const day = String(date.getDate()).padStart(2, '0') return `${date.getFullYear()}-${month}-${day}` } /** 快捷范围 → {from, to} 查询参数(本地日期;now 可注入便于测试) */ export function rangeToParams( range: StatsQuickRange, now: Date = new Date() ): { from: string; to: string } { const days = STATS_QUICK_RANGES.find((item) => item.value === range)?.days ?? 1 return { from: toDateKey(new Date(now.getFullYear(), now.getMonth(), now.getDate() - (days - 1))), to: toDateKey(now) } } // ---- 自定义区间扩展(Phase 3 Task 8 统计分析页) ---------------------------------- /** 时间筛选状态:快捷档 + 自定义(统计分析页;仪表盘只用快捷档) */ export type StatsRangeFilter = StatsQuickRange | 'custom' /** 筛选档位清单(顺序即切换器展示序;自定义档配合日期区间选择器) */ export const STATS_RANGE_OPTIONS: Array<{ value: StatsRangeFilter; label: string }> = [ ...STATS_QUICK_RANGES.map(({ value, label }) => ({ value, label })), { value: 'custom', label: '自定义' } ] /** * 筛选状态 → {from, to} 查询参数(custom 需完整且起≤止的区间) * * 返回 null = 区间不完整/非法(自定义只选了一半、起>止)——调用方不发请求, * 等 ElDatePicker 补全;快速档永不为 null。 */ export function resolveStatsRange( filter: StatsRangeFilter, custom: [string, string] | null | undefined, now: Date = new Date() ): { from: string; to: string } | null { if (filter !== 'custom') return rangeToParams(filter, now) if (!custom || !custom[0] || !custom[1]) return null const [from, to] = custom if (from > to) return null // ISO 日期串字典序即时间序 return { from, to } }