2024-11-18 19:14:37 +08:00
|
|
|
|
// File path: /d:/data/echoes/backend/src/main.rs
|
2024-11-09 00:05:18 +08:00
|
|
|
|
|
2024-11-11 19:31:40 +08:00
|
|
|
|
/**
|
|
|
|
|
* 主程序入口,提供数据库连接和相关API接口。
|
2024-11-18 19:14:37 +08:00
|
|
|
|
*
|
2024-11-11 19:31:40 +08:00
|
|
|
|
* 接口:
|
|
|
|
|
* - GET /api/install: 测试数据库连接
|
|
|
|
|
* - GET /api/sql: 执行SQL查询并返回结果
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
mod config; // 配置模块
|
2024-11-18 19:14:37 +08:00
|
|
|
|
mod database; // 数据库模块
|
|
|
|
|
mod secret; // 密钥模块
|
|
|
|
|
|
|
|
|
|
use chrono::Duration; // 引入时间持续时间
|
2024-11-12 20:25:43 +08:00
|
|
|
|
use database::relational; // 引入关系型数据库
|
2024-11-11 19:31:40 +08:00
|
|
|
|
use once_cell::sync::Lazy; // 用于延迟初始化
|
2024-11-18 19:14:37 +08:00
|
|
|
|
use rocket::{get, post, http::Status, launch, response::status, routes, serde::json::Json}; // 引入Rocket框架相关功能
|
|
|
|
|
use std::sync::Arc; // 引入Arc用于线程安全的引用计数
|
2024-11-11 19:31:40 +08:00
|
|
|
|
use tokio::sync::Mutex; // 引入Mutex用于异步锁
|
|
|
|
|
|
|
|
|
|
// 全局数据库连接变量
|
2024-11-18 19:14:37 +08:00
|
|
|
|
static SQL: Lazy<Arc<Mutex<Option<relational::Database>>>> =
|
|
|
|
|
Lazy::new(|| Arc::new(Mutex::new(None)));
|
2024-11-09 00:05:18 +08:00
|
|
|
|
|
2024-11-11 19:31:40 +08:00
|
|
|
|
/**
|
|
|
|
|
* 初始化数据库连接
|
2024-11-18 19:14:37 +08:00
|
|
|
|
*
|
|
|
|
|
* # 参数
|
|
|
|
|
* - `database`: 数据库配置
|
|
|
|
|
*
|
|
|
|
|
* # 返回
|
|
|
|
|
* - `Result<(), Box<dyn std::error::Error>>`: 初始化结果
|
2024-11-11 19:31:40 +08:00
|
|
|
|
*/
|
2024-11-18 19:14:37 +08:00
|
|
|
|
async fn init_sql(database: config::SqlConfig) -> Result<(), Box<dyn std::error::Error>> {
|
|
|
|
|
let database = relational::Database::link(database).await?; // 初始化数据库
|
|
|
|
|
*SQL.lock().await = Some(database); // 保存数据库实例
|
2024-11-11 01:38:58 +08:00
|
|
|
|
Ok(())
|
2024-11-09 00:05:18 +08:00
|
|
|
|
}
|
2024-11-11 19:31:40 +08:00
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 获取数据库的引用
|
2024-11-18 19:14:37 +08:00
|
|
|
|
*
|
|
|
|
|
* # 返回
|
|
|
|
|
* - `Result<relational::Database, Box<dyn std::error::Error>>`: 数据库引用或错误信息
|
2024-11-11 19:31:40 +08:00
|
|
|
|
*/
|
2024-11-18 19:14:37 +08:00
|
|
|
|
async fn get_sql() -> Result<relational::Database, Box<dyn std::error::Error>> {
|
|
|
|
|
SQL.lock()
|
2024-11-11 13:45:02 +08:00
|
|
|
|
.await
|
|
|
|
|
.clone()
|
2024-11-11 19:31:40 +08:00
|
|
|
|
.ok_or_else(|| "Database not initialized".into()) // 返回错误信息
|
2024-11-09 00:05:18 +08:00
|
|
|
|
}
|
2024-11-11 19:31:40 +08:00
|
|
|
|
|
|
|
|
|
/**
|
2024-11-18 19:14:37 +08:00
|
|
|
|
* 数据库安装接口
|
|
|
|
|
*
|
|
|
|
|
* # 参数
|
|
|
|
|
* - `data`: 数据库配置
|
|
|
|
|
*
|
|
|
|
|
* # 返回
|
|
|
|
|
* - `Result<status::Custom<String>, status::Custom<String>>`: 安装结果
|
|
|
|
|
*/
|
|
|
|
|
#[post("/install", format = "json", data = "<data>")]
|
|
|
|
|
async fn install(data: Json<config::SqlConfig>) -> Result<status::Custom<String>, status::Custom<String>> {
|
|
|
|
|
relational::Database::initial_setup(data.into_inner()).await.map_err(|e| {
|
2024-11-11 13:45:02 +08:00
|
|
|
|
status::Custom(
|
|
|
|
|
Status::InternalServerError,
|
2024-11-18 19:14:37 +08:00
|
|
|
|
format!("Database initialization failed: {}", e), // 连接失败信息
|
2024-11-11 13:45:02 +08:00
|
|
|
|
)
|
2024-11-11 01:38:58 +08:00
|
|
|
|
})?;
|
2024-11-18 19:14:37 +08:00
|
|
|
|
|
|
|
|
|
Ok(status::Custom(
|
|
|
|
|
Status::Ok,
|
|
|
|
|
format!("Initialization successful"),
|
|
|
|
|
))
|
2024-11-09 00:05:18 +08:00
|
|
|
|
}
|
2024-11-11 19:31:40 +08:00
|
|
|
|
|
|
|
|
|
/**
|
2024-11-18 19:14:37 +08:00
|
|
|
|
* 生成系统JWT接口
|
|
|
|
|
*
|
|
|
|
|
* # 返回
|
|
|
|
|
* - `Result<status::Custom<String>, status::Custom<String>>`: JWT令牌或错误信息
|
2024-11-11 19:31:40 +08:00
|
|
|
|
*/
|
2024-11-18 01:09:28 +08:00
|
|
|
|
#[get("/system")]
|
|
|
|
|
async fn token_system() -> Result<status::Custom<String>, status::Custom<String>> {
|
|
|
|
|
// 创建 Claims
|
|
|
|
|
let claims = secret::CustomClaims {
|
2024-11-18 19:14:37 +08:00
|
|
|
|
user_id: String::from("system"), // 用户ID
|
|
|
|
|
device_ua: String::from("system"), // 设备用户代理
|
2024-11-18 01:09:28 +08:00
|
|
|
|
};
|
|
|
|
|
// 生成JWT
|
2024-11-18 19:14:37 +08:00
|
|
|
|
let token = secret::generate_jwt(claims, Duration::seconds(1)).map_err(|e| {
|
|
|
|
|
status::Custom(
|
|
|
|
|
Status::InternalServerError,
|
|
|
|
|
format!("JWT generation failed: {}", e), // JWT生成失败信息
|
|
|
|
|
)
|
|
|
|
|
})?;
|
|
|
|
|
|
|
|
|
|
Ok(status::Custom(Status::Ok, token)) // 返回JWT令牌
|
2024-11-18 01:09:28 +08:00
|
|
|
|
}
|
|
|
|
|
|
2024-11-11 19:31:40 +08:00
|
|
|
|
/**
|
|
|
|
|
* 启动Rocket应用
|
2024-11-18 19:14:37 +08:00
|
|
|
|
*
|
|
|
|
|
* # 返回
|
|
|
|
|
* - `rocket::Rocket`: Rocket应用实例
|
2024-11-11 19:31:40 +08:00
|
|
|
|
*/
|
2024-11-09 00:05:18 +08:00
|
|
|
|
#[launch]
|
|
|
|
|
async fn rocket() -> _ {
|
2024-11-12 20:25:43 +08:00
|
|
|
|
let config = config::Config::read().expect("Failed to read config"); // 读取配置
|
2024-11-18 19:14:37 +08:00
|
|
|
|
|
|
|
|
|
if config.info.install {
|
|
|
|
|
init_sql(config.sql_config)
|
2024-11-11 13:45:02 +08:00
|
|
|
|
.await
|
2024-11-11 19:31:40 +08:00
|
|
|
|
.expect("Failed to connect to database"); // 初始化数据库连接
|
2024-11-18 19:14:37 +08:00
|
|
|
|
rocket::build()
|
|
|
|
|
.mount("/auth/token", routes![token_system])
|
|
|
|
|
} else {
|
|
|
|
|
rocket::build()
|
|
|
|
|
.mount("/", routes![install]) // 挂载API路由
|
|
|
|
|
}
|
2024-11-11 13:45:02 +08:00
|
|
|
|
}
|