Skip to content

v0.0.17 ​

✨ New Features ​

Go backend ​

  • New admin dashboard aggregate layer (model/admin_dashboard.go, issue #15):
    • GetAdminDashboardOverview(rawRange): one-shot KPI aggregation — users (total / today / 7d / 30d / active / disabled / deleted / today-ratio), resources (tokens / channels / plans / redemptions / subscriptions with enabled/active counts), quota (today / 7d / 30d / total), revenue (total / top-up / subscription / refund). Six sections in one round-trip; one SQL per section, no N+1.
    • GetAdminTopUsers(rawRange, limit): active-user leaderboard (consumed logs in window + request_count > 0, sorted by request count desc then quota desc); current plan names batch-embedded via a single WHERE IN.
    • GetAdminModelDistribution(rawRange, topN) + AdminModelDistribution: whole-site top-N models by quota + 7-day series for stacked bar (later superseded by /charts; see 🔧 Refactor).
    • GetAdminUsageDetails(rawRange, topN) + AdminUsageDetails: top-N model × per-day breakdown for the "usage details" table (later superseded by /charts).
    • ParseAdminDashboardRange / ParseAdminChartsRange: unified range preset parsing (today/7d/30d/all); the latter emits a day-aligned window and caps all to the last 30 days to keep responses bounded.
    • SearchAdminLogsByDayAndModel(start, end): whole-site day × model aggregate. Structurally identical to model.SearchLogsByDayAndModel (used by /api/user/dashboard) but without the user_id filter — the frontend can reuse the same chart-building logic.
  • New /api/admin/dashboard/charts endpoint (controller/admin/dashboard.go::GetCharts, router/api.go, AdminAuth):
    • Returns []*model.LogStatistic with fields Day / ModelName / RequestCount / Quota / PromptTokens / CompletionTokens — byte-for-byte the same shape as /api/user/dashboard.
    • One payload powers every chart on the admin page: requests/quota/tokens line charts, stacked model-distribution bar, and usage-details table.
  • Dashboard test suite (model/admin_dashboard_test.go):
    • TestParseAdminDashboardRange: covers the four range boundaries.
    • TestParseAdminChartsRange: validates day-aligned windows and day counts.
    • TestGetAdminDashboardOverview_Smoke: covers all six aggregate sections + active_7d.
    • TestGetAdminTopUsers: request_count > 0 filter + sorting + plan-name embedding.
    • TestSearchAdminLogsByDayAndModel: []LogStatistic shape + multi-user merging + field completeness.
    • Earlier TestGetAdminModelDistribution / TestGetAdminUsageDetails removed along with the API refactor.

Frontend (web/default-pro/) ​

  • New admin operations dashboard page views/admin/AdminDashboard.vue (issue #15):
    • Top welcome bar: title "运营数据" + subtitle "全站 KPI · 趋势 · 排行 — YYYY-MM-DD" + right-aligned range radios (today / 7d / 30d / all) + last-refresh label + refresh button.
    • Left column (16/24) — six panels:
      • User KPIs: 8 stat cards (total / today / 7d / 30d / 7d-active / disabled / deleted / today-ratio) with arco icon + palette.
      • Revenue (moved above Resources): 4 cards (total / top-up / subscription / refund) with footers.
      • Resources / Usage: 5 clickable cards (tokens / channels / plans → /setting/plan / redemptions → /redemption / subscriptions).
      • Token / Request Consumption + three line charts: 4 quota cards + divider + Requests / Quota / Tokens three 160px line charts (vue-echarts), Dashboard-style.
      • Model Distribution (last 7 days): standalone full-width panel, stacked bar (top-8 models × 7 days) with scrollable bottom legend.
      • Usage Details: table paginated 8 rows (date / model / requests / quota / tokens), dash-table styling.
    • Right column (8/24):
      • Ad placeholder: gradient blue→purple "AD" card.
      • User Ranking: card-style (rank badge + username/email + requests/quota stats + plan tag), radio switches today/week/month.
      • Announcements: 3-entry list.
      • Changelog: 3-entry log.
      • Resources: external links (docs + GitHub).
    • Styling: all panel/grid/trend-cell/dash-table styles mirror Dashboard.vue (line-height / spacing / font-size consistent).
  • New sidebar "数据" menu (layouts/AdminLayout.vue, admin only):
    • Positioned above Channels, icon icon-bar-chart, alongside Channels/Orders/Redemption/Users/Subscriptions/Settings.
    • Route /admin/dashboard registered in router/index.js; isAdminRoute allow-list extended with AdminDashboard so non-admins are redirected back to /dashboard.
  • New frontend API module src/api/admin.js:
    • adminApi.overview(range) → GET /api/admin/dashboard/overview.
    • adminApi.topUsers(range, limit) → GET /api/admin/dashboard/top-users.
    • adminApi.charts(range) → GET /api/admin/dashboard/charts (unified chart endpoint).
    • adminApi.modelDistribution / adminApi.usageDetails removed in the refactor (replaced by charts).
  • New i18n keys (src/i18n/locales.js, admin.* namespace, zh/en):
    • Page title pageTitle: '运营数据' / 'Overview'.
    • 5 section titles: sectionUsers / sectionRevenue / sectionResources / sectionQuota / sectionLeaderboard.
    • ~40 card labels (users / revenue / resources / quota / etc.).
    • Range labels: todayLabel: '今日' / 'Today', weekLabel: '本周' / 'This Week', monthLabel: '本月' / 'This Month', plus rangeToday/7d/30d/all.
    • Leaderboard: sectionLeaderboard: '用户排行' and columns colUsername/colRequestCount/colQuota/colBalance/colPlan.
    • Chart titles trimmed: chartRequests: '请求量', chartQuota: '额度', chartTokens: 'Token', chartModelDist: '模型分布(近 7 日)'.
    • Announcement / changelog / resources / ad helper strings.
  • Dynamic page titles:
    • Landing default title becomes ONE-API-PRO—企业级AI API 网关 (web/default-pro/index.html).
    • A router.afterEach hook appends {menu}—ONE-API-PRO per-route, e.g. 控制台—ONE-API-PRO.

🐛 Bug Fixes ​

  • /api/* NoRoute no longer returns the misleading OpenAI invalid_request_error (router/web.go):
    • Previously both /v1/* and /api/* fell through to RelayNotFound, which produced an OpenAI-style 404 that looked like a relay routing issue.
    • Now only /v1/* keeps the OpenAI error (relay clients rely on it); unmatched /api/* returns the standard {success:false, message:"接口不存在: METHOD PATH"} 404 envelope.
  • Fixed GORM column-inference mismatch on admin dashboard structs (model/admin_dashboard.go):
    • AdminDashboardUsers / AdminDashboardResources / AdminDashboardTopUserRow were letting GORM infer the column as snake_case (New7d → new7d), which didn't match the SQL aliases (new_7d), so aggregates silently returned 0.
    • Explicit gorm:"column:..." tags added; caught and fixed by TestGetAdminDashboardOverview_Smoke.
  • Fixed Vue <style scoped> not crossing component files: AdminDashboard referenced Dashboard.vue's .panel / .stat-grid / .trend-cell / .dash-table styles, but scoped CSS hashes are per-component. Inlined the actually-used styles into AdminDashboard's <style scoped> and removed the redundant .admin-dashboard { padding: … }, switching to .dashboard { display: flex; flex-direction: column; gap: 16px } to match Dashboard.vue.
  • Fixed invisible line on all-zero data: yAxis.min = 0 + max = maxV > 0 ? undefined : 1 (old code had max = undefined so auto-scale flattened the line); areaStyle opacity 02 → 30; symbolSize = 6 + itemStyle.borderWidth = 2 to emphasize points.
  • Fixed 09-11 label clipped at the right edge: grid.right: 16 + xAxis.axisLabel.margin: 8 + hideOverlap: false.
  • Fixed "today" missing from line charts: AdminTrendPoint used omitempty, so days without data returned only {day} and the frontend read undefined. Replaced by a single []LogStatistic payload with a frontend-built N-day series that always includes today.
  • Fixed leftover IconHistogram / IconRollback references in AdminDashboard: npm run build did not surface the issue (it crashed at runtime); replaced with the in-set names IconBarChart / IconArrowFall.
  • Fixed UTC ↔ CST day-boundary drift: Go's todayStart = now - (now%daySec) is UTC-aligned and SQLite strftime is UTC, so logs created around 00:00–08:00 CST fell into the previous UTC day. Tests now use todayStart + 100s to align both representations on today.

🔧 Refactor ​

Go backend ​

  • Chart data split out of the overview response:
    • Removed AdminTrendPoint / AdminDashboardTrends / aggregateTrends.
    • AdminDashboardOverview no longer carries Trends (charts data moved to /charts).
    • Removed AdminModelDistribution* / GetAdminModelDistribution and AdminUsageDetails* / GetAdminUsageDetails, plus their controller handlers and routes (/api/admin/dashboard/model-distribution, /api/admin/dashboard/usage-details).
    • model/admin_dashboard.go shrinks by ~320 lines; unused sort / time imports dropped.
  • Unified response shape: a single /charts endpoint returns the same []LogStatistic as /api/user/dashboard, so the frontend no longer needs three separate calls to assemble chart data.

Frontend ​

  • AdminDashboard fully refactored: the model-distribution chart moved out of the trend row into its own full-width panel; the three line charts are now Requests / Quota / Tokens (matching Dashboard.vue).
  • adminApi.modelDistribution / adminApi.usageDetails removed; adminApi.charts is the single source.
  • AdminDashboard.vue adds four new computeds — chartData / daySeries / distModels / usageRows — that build the day series client-side and aggregate Top 8 models in JS.
  • lineOption now reads from chartData ([{date, value}]) instead of overview.trends.
  • modelBarOption now reads from distModels (client-side Top-N sort).
  • Usage-details table now reads from usageRows (flat day×model rows, day desc + quota desc).

🚀 Performance / Ops ​

  • Fixed release-docker workflow arm64 emulated npm install SIGILL (Dockerfile + .github/workflows/release-docker.yml):
    • Pre-build web/build/ in the release-docker job so docker build never runs npm install under QEMU emulation (which was crashing on Node.js native binaries).
    • See ci(release-docker): 预构建 web/build,避免 arm64 emulated npm install 触发 SIGILL.

⚠️ Upgrade Notes ​

  • Zero database migration: all new admin-dashboard fields are aggregate-response fields or new endpoints; no schema changes.
  • Backend route changes (router/api.go, admin route group):
    • Added GET /api/admin/dashboard/charts (AdminAuth).
    • Removed GET /api/admin/dashboard/model-distribution and GET /api/admin/dashboard/usage-details (replaced by /charts).
    • Any external monitor / script still hitting the old routes should switch to /charts + the frontend aggregation logic (or use /api/admin/dashboard/overview for KPIs).
  • Backend binary must be restarted: /charts is a new route and only takes effect after the binary is rebuilt and the process restarted.
  • Frontend chunk cache: hard-refresh (Cmd+Shift+R) to load the new AdminDashboard chunk; the old chunk may still call /usage-details and produce a 404.
  • Unmatched /api/* error format change: after the upgrade, missing routes return {success:false, message:"接口不存在: GET /api/..."} (HTTP 404) instead of the OpenAI-style error — easier to localize.
  • Build & test:
    • go build ./... passes.
    • go test ./model/ ./controller/ ./middleware/ all green (3 new admin-dashboard tests plus existing coverage).
    • Frontend: cd web/default-pro && npm run build passes.
  • Page title changes: browser tab titles change from One Api Pro——企业级 API 网关 to ONE-API-PRO—企业级AI API 网关, and admin pages show {menu}—ONE-API-PRO dynamically. If any external monitor depends on the old title string, please update.