@@ -3,28 +3,23 @@ mod handlers;
33mod utils;
44
55use actix_cors:: Cors ;
6- use actix_files :: NamedFile ;
6+ use fern ;
77use log;
8+ use rust_embed:: RustEmbed ;
89use std:: env;
10+ use std:: path:: Path ;
911use std:: path:: PathBuf ;
10- // 引入嵌入资源模块
11- use crate :: utils:: embedded:: { Assets } ;
12+ use crate :: utils:: database:: establish_connection_pool;
13+
14+ // 嵌入静态资源
15+ #[ derive( RustEmbed ) ]
16+ #[ folder = "static/" ]
17+ struct Assets ;
1218
1319// 引入数据库连接相关类型
1420use file_classification_core:: utils:: database:: { establish_connection, run_pending_migrations} ;
15- use crate :: utils:: database:: establish_connection_pool;
16- // 引入环境变量加载工具
1721use file_classification_common:: env_loader:: load_env_file;
1822
19- // 创建 CORS 中间件
20- fn create_cors ( ) -> Cors {
21- Cors :: default ( )
22- . allow_any_origin ( )
23- . allow_any_method ( )
24- . allow_any_header ( )
25- . supports_credentials ( )
26- }
27-
2823// 处理嵌入的文件资源
2924fn handle_embedded_file ( path : & str ) -> HttpResponse {
3025 match Assets :: get ( path) {
@@ -35,7 +30,7 @@ fn handle_embedded_file(path: &str) -> HttpResponse {
3530 . body ( content. data )
3631 }
3732 None => {
38- // 避免递归调用,直接获取 index.html
33+ // Avoid recursive call by directly getting index.html
3934 if path == "index.html" {
4035 return HttpResponse :: NotFound ( ) . body ( "404 Not Found" ) ;
4136 }
@@ -50,7 +45,7 @@ fn find_static_directory() -> std::io::Result<PathBuf> {
5045 if let Ok ( exe_path) = std:: env:: current_exe ( ) {
5146 if let Some ( exe_dir) = exe_path. parent ( ) {
5247 let static_dir = exe_dir. join ( "static" ) ;
53- if PathBuf :: from ( & static_dir) . exists ( ) {
48+ if Path :: new ( & static_dir) . exists ( ) {
5449 log:: info!( "找到静态资源目录: {:?}" , static_dir) ;
5550 return Ok ( static_dir) ;
5651 }
@@ -60,14 +55,14 @@ fn find_static_directory() -> std::io::Result<PathBuf> {
6055 // 然后尝试从当前工作目录查找
6156 if let Ok ( current_dir) = std:: env:: current_dir ( ) {
6257 let static_dir = current_dir. join ( "static" ) ;
63- if PathBuf :: from ( & static_dir) . exists ( ) {
58+ if Path :: new ( & static_dir) . exists ( ) {
6459 log:: info!( "找到静态资源目录: {:?}" , static_dir) ;
6560 return Ok ( static_dir) ;
6661 }
6762
6863 // 尝试从当前工作目录的子目录 file_classification_webapi 中查找
6964 let static_dir = current_dir. join ( "file_classification_webapi" ) . join ( "static" ) ;
70- if PathBuf :: from ( & static_dir) . exists ( ) {
65+ if Path :: new ( & static_dir) . exists ( ) {
7166 log:: info!( "找到静态资源目录: {:?}" , static_dir) ;
7267 return Ok ( static_dir) ;
7368 }
@@ -84,7 +79,6 @@ fn find_static_directory() -> std::io::Result<PathBuf> {
8479 }
8580}
8681
87- // 静态文件服务处理器
8882async fn index_handler ( ) -> HttpResponse {
8983 // 首先尝试从物理目录提供文件
9084 match find_static_directory ( ) {
@@ -108,7 +102,6 @@ async fn index_handler() -> HttpResponse {
108102 handle_embedded_file ( "index.html" )
109103}
110104
111- // 静态资源处理器
112105async fn static_handler ( path : web:: Path < String > ) -> HttpResponse {
113106 let path = path. into_inner ( ) ;
114107
@@ -154,10 +147,99 @@ async fn static_handler(path: web::Path<String>) -> HttpResponse {
154147 handle_embedded_file ( & path)
155148}
156149
150+ /// 初始化日志系统,同时输出到终端和文件
151+ fn setup_logger ( ) -> Result < ( ) , fern:: InitError > {
152+ // 加载环境变量文件
153+ if let Err ( e) = load_env_file ( ) {
154+ log:: error!( "加载环境变量文件失败: {}" , e) ;
155+ }
156+
157+ // 创建 logs 目录(如果不存在)
158+ std:: fs:: create_dir_all ( "logs" ) ?;
159+
160+ // 获取当前日期时间作为日志文件名
161+ let local_time = chrono:: Local :: now ( ) ;
162+ let date_str = local_time. format ( "%Y-%m-%d" ) . to_string ( ) ;
163+ let log_file_path = format ! ( "logs/{}.log" , date_str) ;
164+
165+ // 获取终端日志等级
166+ let console_log_level = env:: var ( "RUST_LOG" )
167+ . ok ( )
168+ . and_then ( |s| s. parse ( ) . ok ( ) )
169+ . unwrap_or ( log:: LevelFilter :: Info ) ;
170+
171+ // 文件日志等级默认为 Debug
172+ let file_log_level = env:: var ( "RUST_LOG_FILE" )
173+ . ok ( )
174+ . and_then ( |s| s. parse ( ) . ok ( ) )
175+ . unwrap_or ( log:: LevelFilter :: Debug ) ;
176+
177+ // 创建日志分发器
178+ let dispatch = fern:: Dispatch :: new ( )
179+ . format ( |out, message, record| {
180+ out. finish ( format_args ! (
181+ "[{}][{}][{}] {}" ,
182+ chrono:: Local :: now( ) . format( "%Y-%m-%d %H:%M:%S" ) ,
183+ record. level( ) ,
184+ record. target( ) ,
185+ message
186+ ) )
187+ } ) ;
188+
189+ // 添加控制台输出
190+ let dispatch = dispatch. chain (
191+ fern:: Dispatch :: new ( )
192+ . level ( console_log_level)
193+ . chain ( std:: io:: stdout ( ) )
194+ ) ;
195+
196+ // 添加文件输出
197+ let dispatch = dispatch. chain (
198+ fern:: Dispatch :: new ( )
199+ . level ( file_log_level)
200+ . chain ( fern:: log_file ( log_file_path) ?)
201+ ) ;
202+
203+ dispatch. apply ( ) ?;
204+
205+ Ok ( ( ) )
206+ }
207+
208+ /// 创建 CORS 配置
209+ fn create_cors ( ) -> Cors {
210+ // 从环境变量获取 CORS 配置
211+ let cors_enabled = env:: var ( "CORS_ENABLED" )
212+ . ok ( )
213+ . and_then ( |s| s. parse :: < bool > ( ) . ok ( ) )
214+ . unwrap_or ( true ) ; // 默认启用 CORS
215+
216+ let cors_origin = env:: var ( "CORS_ORIGIN" )
217+ . ok ( )
218+ . unwrap_or_else ( || "http://localhost:8082" . to_string ( ) ) ;
219+
220+ if cors_enabled {
221+ log:: info!( "CORS 已启用,允许来源: {}" , cors_origin) ;
222+ Cors :: default ( )
223+ . allowed_origin ( & cors_origin)
224+ . allowed_origin ( "http://127.0.0.1:8082" )
225+ . allowed_methods ( vec ! [ "GET" , "POST" , "PUT" , "DELETE" ] )
226+ . allowed_headers ( vec ! [
227+ actix_web:: http:: header:: AUTHORIZATION ,
228+ actix_web:: http:: header:: ACCEPT ,
229+ actix_web:: http:: header:: CONTENT_TYPE ,
230+ ] )
231+ . supports_credentials ( )
232+ . max_age ( 3600 )
233+ } else {
234+ log:: info!( "CORS 已禁用" ) ;
235+ Cors :: default ( )
236+ }
237+ }
238+
157239#[ actix_web:: main]
158240async fn main ( ) -> std:: io:: Result < ( ) > {
159- // 初始化日志系统
160- env_logger :: init_from_env ( env_logger :: Env :: new ( ) . default_filter_or ( "info" ) ) ;
241+ // 初始化日志记录器
242+ setup_logger ( ) . expect ( "日志系统初始化失败" ) ;
161243
162244 // 输出日志等级信息
163245 let console_log_level = env:: var ( "RUST_LOG" ) . unwrap_or_else ( |_| "info" . to_string ( ) ) ;
0 commit comments