feat(admin): 将用户管理的用量统计改为全量累计口径 (#314)

- 新增按用户 ID 批量汇总 usage 的后端查询
- 在 /api/admin/users 中返回 request_count 和 total_tokens
- 移除用户管理页面额外的 usage 聚合请求
- 为管理端用户列表补充累计统计回归测试
This commit is contained in:
AAEE86
2026-04-19 01:26:22 +08:00
committed by GitHub
parent ab54881eb0
commit 6666992d01
12 changed files with 273 additions and 71 deletions

View File

@@ -568,6 +568,14 @@ impl<'a> AdminAppState<'a> {
.await
}
pub(crate) async fn summarize_usage_totals_by_user_ids(
&self,
user_ids: &[String],
) -> Result<Vec<aether_data_contracts::repository::usage::StoredUsageUserTotals>, GatewayError>
{
self.app.summarize_usage_totals_by_user_ids(user_ids).await
}
pub(crate) async fn list_non_admin_export_users(
&self,
) -> Result<Vec<aether_data::repository::users::StoredUserExportRow>, GatewayError> {

View File

@@ -54,6 +54,12 @@ pub(in super::super) async fn build_admin_list_users_response(
.into_iter()
.filter_map(|wallet| wallet.user_id.clone().map(|user_id| (user_id, wallet)))
.collect::<BTreeMap<_, _>>();
let usage_totals_by_user_id = state
.summarize_usage_totals_by_user_ids(&user_ids)
.await?
.into_iter()
.map(|item| (item.user_id.clone(), item))
.collect::<BTreeMap<_, _>>();
let mut payload = Vec::with_capacity(paged_rows.len());
for row in paged_rows {
@@ -61,6 +67,7 @@ pub(in super::super) async fn build_admin_list_users_response(
let unlimited = wallet_by_user_id
.get(&row.id)
.is_some_and(|wallet| wallet.limit_mode.eq_ignore_ascii_case("unlimited"));
let usage_totals = usage_totals_by_user_id.get(&row.id);
payload.push(json!({
"id": row.id,
"email": row.email,
@@ -77,6 +84,8 @@ pub(in super::super) async fn build_admin_list_users_response(
"last_login_at": format_optional_datetime_iso8601(
auth.as_ref().and_then(|user| user.last_login_at),
),
"request_count": usage_totals.map(|item| item.request_count).unwrap_or_default(),
"total_tokens": usage_totals.map(|item| item.total_tokens).unwrap_or_default(),
}));
}