mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 17:30:23 +08:00
fix: correct API key expiry and dashboard savings (#361)
This commit is contained in:
@@ -45,8 +45,8 @@ pub(super) fn build_admin_user_api_key_detail_payload(
|
||||
"rate_limit": record.rate_limit,
|
||||
"concurrent_limit": record.concurrent_limit,
|
||||
"expires_at": format_optional_unix_secs_iso8601(record.expires_at_unix_secs),
|
||||
"last_used_at": serde_json::Value::Null,
|
||||
"created_at": serde_json::Value::Null,
|
||||
"last_used_at": format_optional_unix_secs_iso8601(record.last_used_at_unix_secs),
|
||||
"created_at": format_optional_unix_secs_iso8601(record.created_at_unix_secs),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -171,7 +171,8 @@ pub(crate) async fn build_admin_create_user_api_key_response(
|
||||
"rate_limit": created.rate_limit,
|
||||
"concurrent_limit": created.concurrent_limit,
|
||||
"expires_at": format_optional_unix_secs_iso8601(created.expires_at_unix_secs),
|
||||
"created_at": chrono::Utc::now().to_rfc3339(),
|
||||
"last_used_at": format_optional_unix_secs_iso8601(created.last_used_at_unix_secs),
|
||||
"created_at": format_optional_unix_secs_iso8601(created.created_at_unix_secs),
|
||||
"message": "API Key创建成功,请妥善保存完整密钥",
|
||||
}))
|
||||
.into_response(),
|
||||
|
||||
@@ -64,8 +64,8 @@ pub(crate) async fn build_admin_list_user_api_keys_response(
|
||||
"rate_limit": record.rate_limit,
|
||||
"concurrent_limit": record.concurrent_limit,
|
||||
"expires_at": format_optional_unix_secs_iso8601(record.expires_at_unix_secs),
|
||||
"last_used_at": serde_json::Value::Null,
|
||||
"created_at": serde_json::Value::Null,
|
||||
"last_used_at": format_optional_unix_secs_iso8601(record.last_used_at_unix_secs),
|
||||
"created_at": format_optional_unix_secs_iso8601(record.created_at_unix_secs),
|
||||
})
|
||||
})
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
@@ -3,8 +3,9 @@ use super::{
|
||||
GatewayError, GatewayPublicRequestContext,
|
||||
};
|
||||
use aether_data_contracts::repository::usage::{
|
||||
StoredUsageDashboardDailyBreakdownRow, StoredUsageDashboardSummary,
|
||||
UsageAuditAggregationGroupBy, UsageAuditAggregationQuery, UsageDashboardDailyBreakdownQuery,
|
||||
StoredUsageCostSavingsSummary, StoredUsageDashboardDailyBreakdownRow,
|
||||
StoredUsageDashboardSummary, UsageAuditAggregationGroupBy, UsageAuditAggregationQuery,
|
||||
UsageCostSavingsSummaryQuery, UsageDashboardDailyBreakdownQuery,
|
||||
UsageDashboardProviderCountsQuery, UsageDashboardSummaryQuery,
|
||||
};
|
||||
use axum::{
|
||||
@@ -428,7 +429,10 @@ fn dashboard_parse_daily_range(query: Option<&str>) -> Result<DashboardDateRange
|
||||
fn dashboard_range_bounds_unix(range: DashboardDateRange) -> Option<(u64, u64)> {
|
||||
let offset = chrono::Duration::minutes(i64::from(range.tz_offset_minutes));
|
||||
let start_local = range.start_date.and_hms_opt(0, 0, 0)?;
|
||||
let end_local = range.end_date.and_hms_opt(23, 59, 59)?;
|
||||
let end_local = range
|
||||
.end_date
|
||||
.checked_add_signed(chrono::Duration::days(1))?
|
||||
.and_hms_opt(0, 0, 0)?;
|
||||
let start_utc = (start_local - offset).and_utc().timestamp();
|
||||
let end_utc = (end_local - offset).and_utc().timestamp();
|
||||
Some((start_utc.max(0) as u64, end_utc.max(0) as u64))
|
||||
@@ -1501,6 +1505,41 @@ async fn dashboard_load_user_counts(
|
||||
Ok((count, count))
|
||||
}
|
||||
|
||||
fn dashboard_cache_savings_usd(summary: &StoredUsageCostSavingsSummary) -> f64 {
|
||||
let estimated_full_cost =
|
||||
if summary.estimated_full_cost_usd <= 0.0 && summary.cache_read_cost_usd > 0.0 {
|
||||
summary.cache_read_cost_usd * 10.0
|
||||
} else {
|
||||
summary.estimated_full_cost_usd
|
||||
};
|
||||
dashboard_round_f64(
|
||||
(estimated_full_cost - summary.cache_read_cost_usd).max(0.0),
|
||||
4,
|
||||
)
|
||||
}
|
||||
|
||||
async fn dashboard_load_cache_savings(
|
||||
state: &AppState,
|
||||
range: DashboardDateRange,
|
||||
user_id: Option<&str>,
|
||||
) -> Result<f64, GatewayError> {
|
||||
let Some((created_from_unix_secs, created_until_unix_secs)) =
|
||||
dashboard_range_bounds_unix(range)
|
||||
else {
|
||||
return Ok(0.0);
|
||||
};
|
||||
let summary = state
|
||||
.summarize_usage_cost_savings(&UsageCostSavingsSummaryQuery {
|
||||
created_from_unix_secs,
|
||||
created_until_unix_secs,
|
||||
user_id: user_id.map(ToOwned::to_owned),
|
||||
provider_name: None,
|
||||
model: None,
|
||||
})
|
||||
.await?;
|
||||
Ok(dashboard_cache_savings_usd(&summary))
|
||||
}
|
||||
|
||||
pub(super) async fn handle_dashboard_stats_get(
|
||||
state: &AppState,
|
||||
request_context: &GatewayPublicRequestContext,
|
||||
@@ -1630,10 +1669,17 @@ pub(super) async fn handle_dashboard_stats_get(
|
||||
/ today_totals.requests as f64
|
||||
* 100.0
|
||||
};
|
||||
let cost_savings = dashboard_round_f64(
|
||||
period_totals.total_cost_usd - period_totals.actual_total_cost_usd,
|
||||
4,
|
||||
);
|
||||
let cost_savings =
|
||||
match dashboard_load_cache_savings(state, summary_range, user_filter).await {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
return build_auth_error_response(
|
||||
http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
format!("dashboard cache savings lookup failed: {err:?}"),
|
||||
false,
|
||||
);
|
||||
}
|
||||
};
|
||||
let stats = json!([
|
||||
{
|
||||
"name": "今日请求",
|
||||
|
||||
@@ -148,8 +148,8 @@ fn build_users_me_api_key_list_payload(
|
||||
"key_display": users_me_masked_api_key_display(state, record.key_encrypted.as_deref()),
|
||||
"is_active": record.is_active,
|
||||
"is_locked": is_locked,
|
||||
"last_used_at": serde_json::Value::Null,
|
||||
"created_at": serde_json::Value::Null,
|
||||
"last_used_at": format_users_me_optional_unix_secs_iso8601(record.last_used_at_unix_secs),
|
||||
"created_at": format_users_me_optional_unix_secs_iso8601(record.created_at_unix_secs),
|
||||
"total_requests": record.total_requests,
|
||||
"total_cost_usd": record.total_cost_usd,
|
||||
"rate_limit": record.rate_limit,
|
||||
@@ -174,9 +174,9 @@ fn build_users_me_api_key_detail_payload(
|
||||
"force_capabilities": record.force_capabilities,
|
||||
"rate_limit": record.rate_limit,
|
||||
"concurrent_limit": record.concurrent_limit,
|
||||
"last_used_at": serde_json::Value::Null,
|
||||
"last_used_at": format_users_me_optional_unix_secs_iso8601(record.last_used_at_unix_secs),
|
||||
"expires_at": format_users_me_optional_unix_secs_iso8601(record.expires_at_unix_secs),
|
||||
"created_at": serde_json::Value::Null,
|
||||
"created_at": format_users_me_optional_unix_secs_iso8601(record.created_at_unix_secs),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -575,8 +575,14 @@ pub(super) async fn handle_users_me_api_key_create(
|
||||
"name": created.name,
|
||||
"key": plaintext_key,
|
||||
"key_display": users_me_masked_api_key_display(state, created.key_encrypted.as_deref()),
|
||||
"is_active": created.is_active,
|
||||
"is_locked": false,
|
||||
"rate_limit": created.rate_limit,
|
||||
"concurrent_limit": created.concurrent_limit,
|
||||
"last_used_at": format_users_me_optional_unix_secs_iso8601(created.last_used_at_unix_secs),
|
||||
"created_at": format_users_me_optional_unix_secs_iso8601(created.created_at_unix_secs),
|
||||
"total_requests": created.total_requests,
|
||||
"total_cost_usd": created.total_cost_usd,
|
||||
"message": "API密钥创建成功",
|
||||
}))
|
||||
.into_response()
|
||||
|
||||
Reference in New Issue
Block a user