mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-12 12:09:50 +08:00
feat: 统计数据优化 - 支持细粒度时间范围和多维度分析
- 新增 StatsHourly/StatsDaily 预聚合表,支持任意时区的精确统计 - 实现 UTC datetime 范围查询策略,边界数据实时聚合 - 新增统计 API:用户/API Key 维度、成本分析、性能百分位、错误分类 - 新增前端页面:成本分析、性能分析、用户统计 - 新增 TimeRangePicker 组件和统计可视化组件 - 优化 Dashboard 和 Usage 页面支持时间范围筛选 Close #135
This commit is contained in:
@@ -393,6 +393,14 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 趋势图表筛选 -->
|
||||
<div class="flex flex-wrap items-center justify-between gap-3">
|
||||
<h3 class="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
||||
统计周期
|
||||
</h3>
|
||||
<TimeRangePicker v-model="dailyTimeRange" :allow-hourly="true" />
|
||||
</div>
|
||||
|
||||
<!-- 趋势图表区域 -->
|
||||
<div class="grid grid-cols-1 gap-6 lg:grid-cols-2">
|
||||
<!-- 每日使用趋势(折线图)- 普通用户可见 -->
|
||||
@@ -784,6 +792,8 @@
|
||||
import { ref, onMounted, computed, onBeforeUnmount, nextTick, watch } from 'vue'
|
||||
import { useAuthStore } from '@/stores/auth'
|
||||
import { dashboardApi, type DashboardStat, type DailyStat, type ProviderSummary } from '@/api/dashboard'
|
||||
import { getDateRangeFromPeriod } from '@/features/usage/composables'
|
||||
import type { DateRangeParams } from '@/features/usage/types'
|
||||
import { announcementApi, type Announcement } from '@/api/announcements'
|
||||
import {
|
||||
Card,
|
||||
@@ -798,6 +808,7 @@ import {
|
||||
TableHead,
|
||||
TableCell,
|
||||
} from '@/components/ui'
|
||||
import { TimeRangePicker } from '@/components/common'
|
||||
import BarChart from '@/components/charts/BarChart.vue'
|
||||
import DoughnutChart from '@/components/charts/DoughnutChart.vue'
|
||||
import LineChart from '@/components/charts/LineChart.vue'
|
||||
@@ -972,7 +983,8 @@ const tokenBreakdown = ref<{
|
||||
const activeUsers = ref(0)
|
||||
const dailyStats = ref<DailyStat[]>([])
|
||||
const providerSummary = ref<ProviderSummary[]>([])
|
||||
const selectedDays = ref(7)
|
||||
const dailyTimeRange = ref<DateRangeParams>(getDateRangeFromPeriod('last7days'))
|
||||
// 统计周期
|
||||
const loadingDaily = ref(false)
|
||||
const loading = ref(false)
|
||||
|
||||
@@ -1317,7 +1329,7 @@ async function loadDashboardData() {
|
||||
async function loadDailyStats() {
|
||||
loadingDaily.value = true
|
||||
try {
|
||||
const response = await dashboardApi.getDailyStats(selectedDays.value)
|
||||
const response = await dashboardApi.getDailyStats(dailyTimeRange.value)
|
||||
dailyStats.value = response.daily_stats
|
||||
providerSummary.value = response.provider_summary || []
|
||||
} catch {
|
||||
@@ -1328,6 +1340,10 @@ async function loadDailyStats() {
|
||||
}
|
||||
}
|
||||
|
||||
watch(dailyTimeRange, async () => {
|
||||
await loadDailyStats()
|
||||
}, { deep: true })
|
||||
|
||||
function formatDate(dateString: string): string {
|
||||
const date = new Date(dateString)
|
||||
const today = new Date()
|
||||
|
||||
Reference in New Issue
Block a user