use axum::http::{Uri, header};
use axum::response::{IntoResponse, Response};
use rust_embed::RustEmbed;
#[derive(RustEmbed)]
#[folder = "web/dist/"]
struct Assets;
pub async fn static_handler(uri: Uri) -> Response {
let path = uri.path().trim_start_matches('/');
if path.starts_with("api/") {
return (
axum::http::StatusCode::NOT_FOUND,
axum::Json(serde_json::json!({ "error": "接口不存在" })),
)
.into_response();
}
let candidate = if path.is_empty() { "index.html" } else { path };
if let Some(file) = Assets::get(candidate) {
return serve(candidate, file);
}
if let Some(index) = Assets::get("index.html") {
return serve("index.html", index);
}
(
axum::http::StatusCode::NOT_FOUND,
"前端未构建:请先在 web/ 目录执行 pnpm install && pnpm build",
)
.into_response()
}
fn serve(path: &str, file: rust_embed::EmbeddedFile) -> Response {
let mime = mime_guess::from_path(path).first_or_octet_stream();
let cache = if path == "index.html" || path == "sw.js" {
"no-cache"
} else {
"public, max-age=31536000, immutable"
};
(
[
(header::CONTENT_TYPE, mime.as_ref().to_string()),
(header::CACHE_CONTROL, cache.to_string()),
],
file.data,
)
.into_response()
}