refactor: 拆分 gateway 单体为独立 crate,新增 systemd 部署方案

将 gateway 内部的 model-fetch、provider-transport、scheduler-core、
usage-runtime、video-tasks-core 模块提取为独立 crate;重构 gateway
内部模块结构(state/router/cache/data/query 等);移除大量遗留模块
文件;新增 systemd 二进制部署骨架及相关文档;更新前端 usage 相关
API 和组件。
This commit is contained in:
fawney19
2026-04-05 20:23:16 +08:00
parent cbc811f6ce
commit 763ff03a7b
777 changed files with 42654 additions and 21464 deletions
@@ -3,11 +3,13 @@ use super::{
build_admin_users_read_only_response, AdminCreateUserApiKeyRequest,
AdminToggleUserApiKeyLockRequest, AdminUpdateUserApiKeyRequest,
};
use crate::gateway::handlers::{
use crate::control::GatewayPublicRequestContext;
use crate::handlers::admin::misc_helpers::attach_admin_audit_response;
use crate::handlers::{
decrypt_catalog_secret_with_fallbacks, encrypt_catalog_secret_with_fallbacks,
query_param_optional_bool,
};
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
use crate::{AppState, GatewayError};
use axum::{
body::Body,
http,
@@ -355,17 +357,23 @@ pub(super) async fn build_admin_create_user_api_key_response(
created
};
Ok(Json(json!({
"id": created.api_key_id,
"key": plaintext_key,
"name": created.name,
"key_display": masked_user_api_key_display(state, created.key_encrypted.as_deref()),
"rate_limit": created.rate_limit,
"expires_at": format_optional_unix_secs_iso8601(created.expires_at_unix_secs),
"created_at": chrono::Utc::now().to_rfc3339(),
"message": "API Key创建成功,请妥善保存完整密钥",
}))
.into_response())
Ok(attach_admin_audit_response(
Json(json!({
"id": created.api_key_id,
"key": plaintext_key,
"name": created.name,
"key_display": masked_user_api_key_display(state, created.key_encrypted.as_deref()),
"rate_limit": created.rate_limit,
"expires_at": format_optional_unix_secs_iso8601(created.expires_at_unix_secs),
"created_at": chrono::Utc::now().to_rfc3339(),
"message": "API Key创建成功,请妥善保存完整密钥",
}))
.into_response(),
"admin_user_api_key_created",
"create_user_api_key",
"user_api_key",
&created.api_key_id,
))
}
pub(super) async fn build_admin_update_user_api_key_response(
@@ -445,7 +453,13 @@ pub(super) async fn build_admin_update_user_api_key_response(
.unwrap_or(false);
let mut payload = build_admin_user_api_key_detail_payload(state, &updated, is_locked);
payload["message"] = json!("API Key更新成功");
Ok(Json(payload).into_response())
Ok(attach_admin_audit_response(
Json(payload).into_response(),
"admin_user_api_key_updated",
"update_user_api_key",
"user_api_key",
&api_key_id,
))
}
pub(super) async fn build_admin_delete_user_api_key_response(
@@ -466,7 +480,13 @@ pub(super) async fn build_admin_delete_user_api_key_response(
};
match state.delete_user_api_key(&user_id, &api_key_id).await? {
true => Ok(Json(json!({ "message": "API Key已删除" })).into_response()),
true => Ok(attach_admin_audit_response(
Json(json!({ "message": "API Key已删除" })).into_response(),
"admin_user_api_key_deleted",
"delete_user_api_key",
"user_api_key",
&api_key_id,
)),
false => Ok((
http::StatusCode::NOT_FOUND,
Json(json!({ "detail": "API Key不存在或不属于该用户" })),
@@ -540,16 +560,22 @@ pub(super) async fn build_admin_toggle_user_api_key_lock_response(
.into_response());
}
Ok(Json(json!({
"id": api_key_id,
"is_locked": desired_is_locked,
"message": if desired_is_locked {
"API密钥已锁定"
} else {
"API密钥已解锁"
},
}))
.into_response())
Ok(attach_admin_audit_response(
Json(json!({
"id": api_key_id,
"is_locked": desired_is_locked,
"message": if desired_is_locked {
"API密钥已锁定"
} else {
"API密钥已解锁"
},
}))
.into_response(),
"admin_user_api_key_lock_toggled",
"toggle_user_api_key_lock",
"user_api_key",
&api_key_id,
))
}
pub(super) async fn build_admin_reveal_user_api_key_response(
@@ -601,5 +627,11 @@ pub(super) async fn build_admin_reveal_user_api_key_response(
.into_response());
};
Ok(Json(json!({ "key": full_key })).into_response())
Ok(attach_admin_audit_response(
Json(json!({ "key": full_key })).into_response(),
"admin_user_api_key_revealed",
"reveal_user_api_key",
"user_api_key",
&key_id,
))
}
@@ -6,8 +6,10 @@ use super::{
normalize_admin_username, validate_admin_user_password, AdminCreateUserRequest,
AdminUpdateUserFieldPresence, AdminUpdateUserRequest,
};
use crate::gateway::handlers::{query_param_optional_bool, query_param_value};
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
use crate::control::GatewayPublicRequestContext;
use crate::handlers::admin::misc_helpers::attach_admin_audit_response;
use crate::handlers::{query_param_optional_bool, query_param_value};
use crate::{AppState, GatewayError};
use axum::{
body::Body,
http,
@@ -185,7 +187,6 @@ pub(super) async fn build_admin_create_user_response(
request_context: &GatewayPublicRequestContext,
request_body: Option<&axum::body::Bytes>,
) -> Result<Response<Body>, GatewayError> {
let _ = request_context;
if !state.has_auth_user_write_capability() {
return Ok(build_admin_users_read_only_response(
"当前为只读模式,无法创建用户",
@@ -375,12 +376,18 @@ pub(super) async fn build_admin_create_user_response(
));
}
Ok(Json(build_admin_user_payload(
&user,
payload.rate_limit,
payload.unlimited,
Ok(attach_admin_audit_response(
Json(build_admin_user_payload(
&user,
payload.rate_limit,
payload.unlimited,
))
.into_response(),
"admin_user_created",
"create_user",
"user",
&user.id,
))
.into_response())
}
pub(super) async fn build_admin_update_user_response(
@@ -696,7 +703,13 @@ pub(super) async fn build_admin_update_user_response(
.and_then(|row| row.rate_limit)
.or(payload.rate_limit);
Ok(Json(build_admin_user_payload(&user, rate_limit, unlimited)).into_response())
Ok(attach_admin_audit_response(
Json(build_admin_user_payload(&user, rate_limit, unlimited)).into_response(),
"admin_user_updated",
"update_user",
"user",
&user_id,
))
}
pub(super) async fn build_admin_delete_user_response(
@@ -744,5 +757,11 @@ pub(super) async fn build_admin_delete_user_response(
.into_response());
}
Ok(Json(json!({ "message": "用户删除成功" })).into_response())
Ok(attach_admin_audit_response(
Json(json!({ "message": "用户删除成功" })).into_response(),
"admin_user_deleted",
"delete_user",
"user",
&user_id,
))
}
@@ -8,7 +8,8 @@ use super::{
build_admin_update_user_api_key_response, build_admin_update_user_response,
build_admin_users_data_unavailable_response,
};
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
use crate::control::GatewayPublicRequestContext;
use crate::{AppState, GatewayError};
use axum::{body::Body, http, response::Response};
fn is_admin_users_route(request_context: &GatewayPublicRequestContext) -> bool {
@@ -1,5 +1,7 @@
use super::{build_admin_users_bad_request_response, format_optional_datetime_iso8601};
use crate::gateway::{AppState, GatewayError, GatewayPublicRequestContext};
use crate::control::GatewayPublicRequestContext;
use crate::handlers::admin::misc_helpers::attach_admin_audit_response;
use crate::{AppState, GatewayError};
use axum::{
body::Body,
http,
@@ -33,7 +35,7 @@ fn admin_user_session_parts(request_path: &str) -> Option<(String, String)> {
}
fn format_required_session_datetime_iso8601(
session: &crate::gateway::gateway_data::StoredUserSessionRecord,
session: &crate::data::state::StoredUserSessionRecord,
) -> String {
session
.created_at
@@ -128,7 +130,13 @@ pub(super) async fn build_admin_delete_user_session_response(
)
.await?;
Ok(Json(json!({ "message": "用户设备已强制下线" })).into_response())
Ok(attach_admin_audit_response(
Json(json!({ "message": "用户设备已强制下线" })).into_response(),
"admin_user_session_deleted",
"delete_user_session",
"user_session",
&session_id,
))
}
pub(super) async fn build_admin_delete_user_sessions_response(
@@ -151,9 +159,15 @@ pub(super) async fn build_admin_delete_user_sessions_response(
.revoke_all_user_sessions(&user_id, chrono::Utc::now(), "admin_revoke_all_sessions")
.await?;
Ok(Json(json!({
"message": "已强制下线该用户所有设备",
"revoked_count": revoked_count,
}))
.into_response())
Ok(attach_admin_audit_response(
Json(json!({
"message": "已强制下线该用户所有设备",
"revoked_count": revoked_count,
}))
.into_response(),
"admin_user_sessions_deleted",
"delete_user_sessions",
"user",
&user_id,
))
}