From e03851e23f05face3a0a368941984058cb40bb8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=93=9D=E8=8A=B7=E6=80=A1?= Date: Wed, 28 Oct 2026 18:55:57 +0800 Subject: [PATCH] fix(dashboard): show notes below API key accounts (#545) * fix(dashboard): show notes below API key accounts Co-authored-by: Codex * fix(frontend): complete dashboard theme preview account notes Co-authored-by: Codex --------- Co-authored-by: Codex --- backend/crates/gateway-admin/src/model/observability.rs | 1 + .../gateway-admin/tests/use_case/observability/mod.rs | 1 + .../gateway-api/src/admin/observability/presenter.rs | 1 + .../crates/gateway-api/src/admin/observability/wire.rs | 1 + .../gateway-api/tests/admin/observability/response.rs | 2 ++ .../gateway-store/src/postgres/observability/mapping.rs | 1 + .../gateway-store/src/postgres/observability/model.rs | 1 + .../src/postgres/observability/queries/accounts.rs | 1 + docs/api.md | 2 ++ frontend/src/api/modules/dashboard.ts | 1 + .../dashboard/components/DashboardAccountIdentity.vue | 8 ++++++-- frontend/src/views/theme/fixtures/dashboard.ts | 3 +++ 12 files changed, 21 insertions(+), 2 deletions(-) diff --git a/backend/crates/gateway-admin/src/model/observability.rs b/backend/crates/gateway-admin/src/model/observability.rs index 0970e8149..cf9eeb732 100644 --- a/backend/crates/gateway-admin/src/model/observability.rs +++ b/backend/crates/gateway-admin/src/model/observability.rs @@ -653,6 +653,7 @@ pub struct DashboardAccountUsage { pub authentication_kind: String, pub name: String, pub email: Option, + pub notes: Option, pub plan_type: Option, /// Admin 按 Provider 补齐的套餐展示名称 pub plan_type_display: Option, diff --git a/backend/crates/gateway-admin/tests/use_case/observability/mod.rs b/backend/crates/gateway-admin/tests/use_case/observability/mod.rs index 997b86784..1d3f6bf96 100644 --- a/backend/crates/gateway-admin/tests/use_case/observability/mod.rs +++ b/backend/crates/gateway-admin/tests/use_case/observability/mod.rs @@ -1000,6 +1000,7 @@ async fn dashboard_should_preserve_provider_plan_names() { authentication_kind: "oauth".to_owned(), name: (*plan).to_owned(), email: None, + notes: None, plan_type: Some((*plan).to_owned()), plan_type_display: None, request_count: 0, diff --git a/backend/crates/gateway-api/src/admin/observability/presenter.rs b/backend/crates/gateway-api/src/admin/observability/presenter.rs index ed4235d4f..e78ead335 100644 --- a/backend/crates/gateway-api/src/admin/observability/presenter.rs +++ b/backend/crates/gateway-api/src/admin/observability/presenter.rs @@ -926,6 +926,7 @@ pub(crate) fn dashboard_view( .email .clone() .unwrap_or_else(|| credential.name.clone()), + notes: credential.notes, plan_type: credential.plan_type.clone(), plan_type_display: credential .plan_type_display diff --git a/backend/crates/gateway-api/src/admin/observability/wire.rs b/backend/crates/gateway-api/src/admin/observability/wire.rs index ceb49536d..2ab7d710f 100644 --- a/backend/crates/gateway-api/src/admin/observability/wire.rs +++ b/backend/crates/gateway-api/src/admin/observability/wire.rs @@ -406,6 +406,7 @@ pub struct DashboardAccountUsageView { pub provider: String, pub authentication_kind: String, pub email: String, + pub notes: Option, pub plan_type: Option, pub plan_type_display: String, pub tokens: String, diff --git a/backend/crates/gateway-api/tests/admin/observability/response.rs b/backend/crates/gateway-api/tests/admin/observability/response.rs index caa5f883f..fbbe3b14e 100644 --- a/backend/crates/gateway-api/tests/admin/observability/response.rs +++ b/backend/crates/gateway-api/tests/admin/observability/response.rs @@ -1607,6 +1607,7 @@ async fn dashboard_summary_should_identify_metrics_without_localized_labels() { authentication_kind: "oauth".to_owned(), name: account_id.clone(), email: None, + notes: None, plan_type: None, plan_type_display: None, request_count: 10, @@ -1805,6 +1806,7 @@ async fn dashboard_relative_time_preserves_server_anchor_boundaries_and_deployme authentication_kind: "oauth".to_owned(), name: "Relative time fixture".to_owned(), email: None, + notes: None, plan_type: None, plan_type_display: None, request_count: 1, diff --git a/backend/crates/gateway-store/src/postgres/observability/mapping.rs b/backend/crates/gateway-store/src/postgres/observability/mapping.rs index 8a4c3492e..9b4b0bee3 100644 --- a/backend/crates/gateway-store/src/postgres/observability/mapping.rs +++ b/backend/crates/gateway-store/src/postgres/observability/mapping.rs @@ -138,6 +138,7 @@ pub(crate) fn admin_dashboard_account_usage( authentication_kind: usage.authentication_kind, name: usage.name, email: usage.email, + notes: usage.notes, plan_type: usage.plan_type, plan_type_display: None, request_count: usage.request_count, diff --git a/backend/crates/gateway-store/src/postgres/observability/model.rs b/backend/crates/gateway-store/src/postgres/observability/model.rs index a1feb501f..a4ce35e3a 100644 --- a/backend/crates/gateway-store/src/postgres/observability/model.rs +++ b/backend/crates/gateway-store/src/postgres/observability/model.rs @@ -227,6 +227,7 @@ pub struct ProviderAccountUsageObservation { pub authentication_kind: String, pub name: String, pub email: Option, + pub notes: Option, pub plan_type: Option, pub request_count: u64, pub success_count: u64, diff --git a/backend/crates/gateway-store/src/postgres/observability/queries/accounts.rs b/backend/crates/gateway-store/src/postgres/observability/queries/accounts.rs index eb60c2a6d..3cbe69c62 100644 --- a/backend/crates/gateway-store/src/postgres/observability/queries/accounts.rs +++ b/backend/crates/gateway-store/src/postgres/observability/queries/accounts.rs @@ -87,6 +87,7 @@ pub(crate) async fn provider_account_usage( authentication_kind: get(&row, "authentication_kind")?, name: get(&row, "name")?, email: get(&row, "email")?, + notes: get(&row, "notes")?, plan_type: get(&row, "plan_type")?, request_count: state.count("completed_request_count"), success_count: state.count("completed_request_count"), diff --git a/docs/api.md b/docs/api.md index 878a77571..fe429d063 100644 --- a/docs/api.md +++ b/docs/api.md @@ -2148,6 +2148,8 @@ Dashboard 的 `accountUsage[]` 返回稳定指标 `metric=requests|tokens`、可 `requests` 使用代表性额度窗口的本地请求数,`tokens` 使用今日 Token;未知数值为 `null`,零值保留 `0`。 `metricLabel`、`metricValue` 和 `lastUsed` 保留给兼容调用方,当前管理端不解析或显示这些字段 +`accountUsage[].notes` 为账号当前备注,无备注时为 `null` + `usageWindow` 复用账号额度窗口合同,缺失额度事实时为 `null`;窗口标签、百分比、触顶状态、重置时间 和本地用量由 Provider/Admin 投影。套餐缺失不表示免费套餐,显示时舍入的百分比不用于判断触顶 diff --git a/frontend/src/api/modules/dashboard.ts b/frontend/src/api/modules/dashboard.ts index 7bfd49658..dce7bc1e9 100644 --- a/frontend/src/api/modules/dashboard.ts +++ b/frontend/src/api/modules/dashboard.ts @@ -145,6 +145,7 @@ export interface DashboardAccountUsage { provider: string authenticationKind: string email: string + notes: string | null planType: string | null planTypeDisplay: string tokens: string diff --git a/frontend/src/views/dashboard/components/DashboardAccountIdentity.vue b/frontend/src/views/dashboard/components/DashboardAccountIdentity.vue index 1c8d62e5d..be77553f1 100644 --- a/frontend/src/views/dashboard/components/DashboardAccountIdentity.vue +++ b/frontend/src/views/dashboard/components/DashboardAccountIdentity.vue @@ -19,6 +19,9 @@ type DashboardAccount = DashboardSnapshot['accountUsage'][number] const email = computed(() => props.account.email?.trim() || String(props.account.id)) const displayTitle = computed(() => email.value.split('@')[0] || email.value) +const secondaryText = computed(() => props.account.authenticationKind === 'api_key' + ? props.account.notes + : email.value) const normalizedProvider = computed(() => props.account.provider?.trim().toLowerCase() || '') const providerIconComponent = computed(() => normalizedProvider.value ? providerIcon(normalizedProvider.value) @@ -64,10 +67,11 @@ const avatarToneClass = computed(() => - {{ email }} + {{ secondaryText }} diff --git a/frontend/src/views/theme/fixtures/dashboard.ts b/frontend/src/views/theme/fixtures/dashboard.ts index 4fc3eaf00..e9f143aef 100644 --- a/frontend/src/views/theme/fixtures/dashboard.ts +++ b/frontend/src/views/theme/fixtures/dashboard.ts @@ -341,6 +341,7 @@ export const themeDashboardSummary = computed(() => ({ provider: 'openai', authenticationKind: 'oauth', email: 'relay@example.com', + notes: null, planType: 'team', planTypeDisplay: 'Business', tokens: '926K', @@ -374,6 +375,7 @@ export const themeDashboardSummary = computed(() => ({ provider: 'xai', authenticationKind: 'oauth', email: 'gateway@example.com', + notes: null, planType: 'free', planTypeDisplay: 'Free', tokens: '684K', @@ -428,6 +430,7 @@ export const themeDashboardSummary = computed(() => ({ provider: 'openai', authenticationKind: 'oauth', email: 'control@example.com', + notes: null, planType: 'pro', planTypeDisplay: 'Pro', tokens: '512K',