Skip to content

v0.0.17 — 管理员运营仪表盘与图表数据统一重构 ​

为管理员引入全新的「数据」运营仪表盘:全站 KPI(用户/资源/营收/配额/收入)+ 7 日请求量/额度/Token 三张趋势折线 + 模型用量分布堆叠柱图 + 使用明细表 + 活跃用户排行榜;图表数据统一由 /api/admin/dashboard/charts 一份接口驱动,结构与 /api/user/dashboard 完全一致([]LogStatistic),方便前后端共享聚合逻辑。同时修复 /api/* 未匹配路由误返回 OpenAI 风格错误的问题。

中文 ​

✨ 新增功能 ​

后端(Go) ​

  • 新增管理员仪表盘聚合层(model/admin_dashboard.go,issue #15):
    • GetAdminDashboardOverview(rawRange):一次性聚合 KPI — 用户(总数/今日新增/7 日/30 日/活跃/禁用/已删/今日占比)、资源(令牌/渠道/套餐/兑换码/订阅 各自总数 + 启用/活跃)、配额(今日/7 日/30 日/总)、收入(总营收/充值/订阅/退款),6 段聚合单次往返,每段单条 SQL 避免 N+1。
    • GetAdminTopUsers(rawRange, limit):活跃用户排行榜(近 range 内有 consume 日志 + request_count > 0,按请求数 desc、quota desc 排序),一次性 WHERE IN 批量补齐当前套餐名(batchTopActivePlanNames)。
    • GetAdminModelDistribution(rawRange, topN) + AdminModelDistribution:全站按 quota 降序的 Top N 模型 + 7 日 day 序列,供堆叠柱图渲染(此接口随后被 /charts 取代,详见 🔧 重构)。
    • GetAdminUsageDetails(rawRange, topN) + AdminUsageDetails:Top N 模型 × 每日的「透视前」明细行,供「使用明细」表渲染(此接口随后被 /charts 取代)。
    • ParseAdminDashboardRange / ParseAdminChartsRange:统一的 range 预设解析(today/7d/30d/all),后者输出 day 对齐的窗口(all 收敛为近 30 天避免全量响应过大)。
    • SearchAdminLogsByDayAndModel(start, end):全站 day × model 聚合,结构与 model.SearchLogsByDayAndModel(api/user/dashboard 用)完全一致,但不过滤 user_id;前端可直接复用同一套图表构建逻辑。
  • 新增 /api/admin/dashboard/charts 接口(controller/admin/dashboard.go::GetCharts,router/api.go,AdminAuth):
    • 返回 []*model.LogStatistic,字段 Day / ModelName / RequestCount / Quota / PromptTokens / CompletionTokens,与 /api/user/dashboard 完全一致。
    • 一份数据驱动前端全部图表:请求量/额度/Token 三张折线 + 模型分布堆叠柱 + 使用明细表。
  • 运营仪表盘配套测试(model/admin_dashboard_test.go):
    • TestParseAdminDashboardRange:覆盖 4 种 range 边界。
    • TestParseAdminChartsRange:验证 day 对齐窗口与天数。
    • TestGetAdminDashboardOverview_Smoke:覆盖 6 段聚合与 active_7d。
    • TestGetAdminTopUsers:覆盖 request_count > 0 过滤 + 排序 + 套餐名嵌入。
    • TestSearchAdminLogsByDayAndModel:覆盖 []LogStatistic 结构 + 多用户合并 + 字段齐全。
    • 早期 TestGetAdminModelDistribution / TestGetAdminUsageDetails 随 API 重构移除。

前端(web/default-pro/) ​

  • 新增管理员仪表盘页面 views/admin/AdminDashboard.vue(issue #15):
    • 顶部欢迎条:标题「运营数据」+ 副标题「全站 KPI · 趋势 · 排行 — YYYY-MM-DD」+ 右侧 range 单选(今日/7 日/30 日/全部)+ 最后刷新时间 + 刷新按钮。
    • 左侧 16/24 主栏(6 个 panel):
      • 用户 KPI:8 张统计卡(总用户/今日新增/7 日/30 日/7 日活跃/禁用/已删/今日占比),带 arco icon + 调色板。
      • 营收:总营收/充值/订阅/退款 4 张卡(带「营收」脚注),移至资源上方。
      • 资源 / 用量:令牌/渠道/套餐(→/setting/plan)/兑换码(→/redemption)/订阅 5 张可点击卡。
      • Token / 请求消耗 + 三张折线:4 张配额卡 + 分隔条 + 请求量/额度/Token 三张 160px 折线图(vue-echarts),样式与仪表盘一致。
      • 模型分布(近 7 日):独立全宽 panel,堆叠柱图(Top 8 模型 × 7 天),legend 底部滚动。
      • 使用明细:表格分页 8 行(日期 / 模型 / 请求数 / 消耗 / Token),dash-table 样式与仪表盘一致。
    • 右侧 8/24 栏:
      • 广告位占位:渐变蓝紫 AD 卡片。
      • 用户排行:卡片式(rank 徽章 + 用户名/邮箱 + 请求/消耗双列 + 套餐 tag),radio 切换今日/本周/本月。
      • 系统公告:3 条公告列表。
      • 更新日志:3 条 changelog 条目。
      • 资源:官方文档 + GitHub 外链。
    • 样式:所有 panel/grid/trend-cell/dash-table 样式与 Dashboard.vue 同构(行高/间距/字号一致)。
  • 新增侧边栏「数据」菜单(layouts/AdminLayout.vue,admin only):
    • 位置:渠道之上,icon icon-bar-chart,与「渠道/订单/兑换码/用户/订阅/设置」并列。
    • 路由 /admin/dashboard 由 router/index.js 注册,isAdminRoute allow-list 加入 AdminDashboard,非管理员访问被重定向到 /dashboard。
  • 新增前端 API 模块 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(统一图表接口)。
    • adminApi.modelDistribution / adminApi.usageDetails 在重构后移除(被 charts 取代)。
  • 新增 i18n 文案(zh/en,src/i18n/locales.js,admin.* 命名空间):
    • 页面标题 pageTitle: '运营数据' / 'Overview'。
    • 5 个分区标题:sectionUsers / sectionRevenue / sectionResources / sectionQuota / sectionLeaderboard。
    • 卡片 label:用户 KPI、营收、资源、Token/请求消耗 等约 40 个 key。
    • 时间筛选 label:todayLabel: '今日' / 'Today'、weekLabel: '本周' / 'This Week'、monthLabel: '本月' / 'This Month'、rangeToday/7d/30d/all。
    • 排行榜 tag:sectionLeaderboard: '用户排行'、列名 colUsername/colRequestCount/colQuota/colBalance/colPlan。
    • 图表标题精简:chartRequests: '请求量'、chartQuota: '额度'、chartTokens: 'Token'、chartModelDist: '模型分布(近 7 日)'。
    • 公告/更新日志/资源/广告位等辅助文案。
  • 网页 Title 动态化:
    • 落地页默认 Title 改为 ONE-API-PRO—企业级AI API 网关(web/default-pro/index.html)。
    • 路由切换时 router.afterEach 钩子按 meta.title 拼接 {菜单名}—ONE-API-PRO,如「控制台—ONE-API-PRO」。

🐛 问题修复 ​

  • 修复 /api/* 未匹配路由误返回 OpenAI 风格 invalid_request_error 误导排查(router/web.go):
    • 原来 NoRoute 对 /v1/* 与 /api/* 都返回 RelayNotFound(OpenAI invalid_request_error),导致缺失的管理接口被误判为 relay 路由问题。
    • 现仅 /v1/* 保留 OpenAI 错误(relay 客户端需要兼容),/api/* 未匹配返回标准 {success:false, message:"接口不存在: METHOD PATH"} 404 信封,便于定位路由缺失。
  • 修复 admin_dashboard 结构体 GORM column 推断错位(model/admin_dashboard.go):
    • AdminDashboardUsers / AdminDashboardResources / AdminDashboardTopUserRow 等聚合行结构体默认按 GORM 字段名 snake_case 推断列名(New7d → new7d),与 SQL 别名 new_7d 不匹配,导致聚合全部填充 0。
    • 显式补齐 gorm:"column:..." 标签后正常。
    • 由 TestGetAdminDashboardOverview_Smoke 触发并修复。
  • 修复 Vue <style scoped> 跨组件不生效:AdminDashboard 引用的 .panel / .stat-grid / .trend-cell / .dash-table 等与 Dashboard.vue 同名样式,因 scoped hash 不同不会跨文件共享;将 AdminDashboard 实际用到的样式全部内联到本组件的 <style scoped>,并去除 .admin-dashboard 容器多余 padding,改用 .dashboard { display: flex; flex-direction: column; gap: 16px } 与 Dashboard.vue 布局一致。
  • 修复 admin 折线图无数据时全 0 看不见线:yAxis.min = 0 + max = maxV > 0 ? undefined : 1(旧版在 0 数据时 max = undefined 导致 auto-scale 把线压成一条不可见线);areaStyle 透明度由 02 提到 30;symbolSize = 6 + itemStyle.borderWidth = 2 强化折线点。
  • 修复 admin 折线图「9-11 标签被右边界裁切」:grid.right: 16 + xAxis.axisLabel.margin: 8 + hideOverlap: false,确保最新日期可见。
  • 修复 admin 折线图缺今日:AdminTrendPoint / aggregateTrends 在某日无数据时只回 {day}(因 omitempty)导致前端 undefined;改用 []LogStatistic 一致结构 + 前端本地补全 N 天日期序列(含今天),彻底解决「9-11 今天的没显示」。
  • 修复 AdminDashboard 残留 IconHistogram / IconRollback 引用:npm run build 不报错(运行时才崩),统一替换为 arco icon set 内可用名称 IconBarChart / IconArrowFall。
  • 修复 9-11 类型 UTC 对齐:Go todayStart = now - (now%daySec) 按 UTC 边界 + SQLite strftime UTC + CST 本地 9:00 之间偏差 1 天的隐患,统一在测试日志时间戳 +100s 保证 UTC 与本地对齐。

🔧 重构 ​

后端(Go) ​

  • 图表数据从 overview 拆分独立:
    • 移除 AdminTrendPoint / AdminDashboardTrends / aggregateTrends 三个旧结构/函数。
    • AdminDashboardOverview 移除 Trends 字段,专注 KPI。
    • 移除 AdminModelDistribution* / GetAdminModelDistribution 与 AdminUsageDetails* / GetAdminUsageDetails,由 /charts 统一驱动。
    • 移除对应 controller handlers + router 路由(/api/admin/dashboard/model-distribution、/api/admin/dashboard/usage-details)。
    • model/admin_dashboard.go 总行数减少 ~320 行;删除 sort / time 等不再需要的 import。
  • 响应结构统一:单一 /charts 接口返回与 /api/user/dashboard 同构的 []LogStatistic,前端无需分别请求 3 个端点拼装数据。

前端 ​

  • AdminDashboard 全面重构:从 trend row 内嵌模型分布改为独立全宽模型分布 panel;折线图数量从「请求量/Quota/模型分布」改为「请求量/额度/Token」3 张折线(与 Dashboard.vue 一致)。
  • adminApi.modelDistribution / adminApi.usageDetails 移除,统一为 adminApi.charts 一份接口。
  • AdminDashboard.vue 新增 chartData / daySeries / distModels / usageRows 四个 computed,本地构建日期序列 + 客户端聚合 Top 8 模型,避免依赖后端预聚合。
  • lineOption 从 overview.trends 改读 chartData([{date, value}])。
  • modelBarOption 从 distDays + distItems 改读 distModels(前端 Top N 排序)。
  • 使用明细表从 usageDetails 改读 usageRows(扁平 day×model,日期 desc + 消耗 desc 排序)。

🚀 性能 ​

  • 修复 release-docker workflow arm64 emulated npm install 触发 SIGILL(Dockerfile + .github/workflows/release-docker.yml):
    • 改为在 release-docker job 中预构建 web/build,docker build 不再 npm install,避免 QEMU 模拟的 Node.js 二进制崩溃。
    • 详见 ci(release-docker): 预构建 web/build,避免 arm64 emulated npm install 触发 SIGILL。

⚠️ 升级注意事项 ​

  • 零数据库迁移:所有 admin dashboard 新增字段都是聚合响应或新接口,无表结构变更。
  • 后端路由变更(router/api.go,admin 路由组):
    • 新增 GET /api/admin/dashboard/charts(AdminAuth)。
    • 移除 GET /api/admin/dashboard/model-distribution、GET /api/admin/dashboard/usage-details(被 /charts 取代)。
    • 如有外部监控/脚本调用旧路由,请改用 /charts + 前端聚合逻辑(或直接用 /api/admin/dashboard/overview)。
  • 后端二进制必须重启:/charts 是新路由,编译进二进制后才生效。升级后必须重启 one-api-pro 进程。
  • 前端 chunk 缓存:浏览器需要硬刷(Cmd+Shift+R)以加载新 AdminDashboard chunk;旧的 AdminDashboard-*.js chunk 仍可能引用 /usage-details 导致 404。
  • 未匹配 /api/* 错误格式变化:升级后若遗漏注册路由,前端会收到 {success:false, message:"接口不存在: GET /api/..."}(HTTP 404)而非 OpenAI 风格错误,更易定位。
  • 后端构建与测试:
    • go build ./... 通过。
    • go test ./model/ ./controller/ ./middleware/ 全绿(含 3 个新增 admin_dashboard 测试 + 已有测试)。
    • 前端:cd web/default-pro && npm run build 通过。
  • 页面标题变更:浏览器 tab 标题从「One Api Pro——企业级 API 网关」变为 ONE-API-PRO—企业级AI API 网关,后台路由切换时动态显示「{菜单名}—ONE-API-PRO」。如有外部监控依赖旧标题文案请知悉。