use axum::{ routing::{get, post, delete, put}, Router, }; use tower_http::cors::{CorsLayer, Any}; use std::net::SocketAddr; use tracing_subscriber; use dotenv::dotenv; use std::env; mod auth; mod database; mod models; mod routes; #[tokio::main] async fn main() { // Load environment variables dotenv().ok(); // Initialize tracing tracing_subscriber::fmt::init(); // Initialize database let db = database::init().await; // Build the application with routes let app = Router::new() .route("/", get(root)) .route("/api/attendees", post(routes::create_attendee)) .route("/api/attendees", get(routes::get_attendees)) .route("/api/attendees/{id}", get(routes::get_attendee)) .route("/api/attendees/{id}/checkin", post(routes::checkin_attendee)) .route("/api/attendees/batch-delete", delete(routes::batch_delete_attendees)) .route("/api/attendees/batch-reset-checkin", post(routes::batch_reset_checkin)) .route("/api/attendees/import", post(routes::import_attendees_from_excel)) .route("/api/attendees/export", get(routes::export_attendees_to_excel)) .route("/api/auth/register", post(routes::register_user)) .route("/api/auth/login", post(routes::login_user)) .route("/api/config", get(routes::get_configs)) .route("/api/config/{key}", get(routes::get_config)) .route("/api/config/{key}", put(routes::update_config)) .layer(CorsLayer::new().allow_origin(Any).allow_methods(Any).allow_headers(Any)) .with_state(db); // Run the server let addr = env::var("SERVER_ADDR").unwrap_or("127.0.0.1:3001".to_string()); let socket_addr: SocketAddr = addr.parse().expect("Invalid server address"); tracing::info!("Server running on {}", socket_addr); // 兼容 axum >= 0.7 的启动方式 let listener = tokio::net::TcpListener::bind(socket_addr).await.unwrap(); axum::serve(listener, app).await.unwrap(); } async fn root() -> &'static str { "签到系统 API Server" }