//! 会话处理器 use axum::{ extract::{Path, Query, State}, http::StatusCode, response::IntoResponse, Json, }; use std::sync::Arc; use crate::models::{ApiResponse, HistoryResponse, PaginatedResponse, PaginationParams, SessionResponse}; use crate::services::{ device::DeviceRepository, session::{HistoryRepository, SessionRepository}, AppState, }; use super::{api_error, AuthUser}; /// 获取活跃会话列表 pub async fn list_sessions( State(state): State>, user: AuthUser, ) -> impl IntoResponse { let session_repo = SessionRepository::new(&state.db); let device_repo = DeviceRepository::new(&state.db); // 获取用户的设备 let devices = match device_repo.find_by_user(&user.user_id).await { Ok(devices) => devices, Err(e) => return api_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), }; let device_ids: Vec<&str> = devices.iter().map(|d| d.device_id.as_str()).collect(); // 获取活跃会话 match session_repo.find_active().await { Ok(sessions) => { // 过滤出与用户设备相关的会话 let filtered: Vec = sessions .into_iter() .filter(|s| { device_ids.contains(&s.controller_device_id.as_str()) || device_ids.contains(&s.controlled_device_id.as_str()) }) .map(Into::into) .collect(); (StatusCode::OK, Json(ApiResponse::ok(filtered))).into_response() } Err(e) => api_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), } } /// 获取控制历史记录 pub async fn get_history( State(state): State>, user: AuthUser, Query(params): Query, ) -> impl IntoResponse { let repo = HistoryRepository::new(&state.db); match repo.find_by_user(&user.user_id, params.offset(), params.limit()).await { Ok((history, total)) => { let items: Vec = history.into_iter().map(Into::into).collect(); let total_pages = ((total as f64) / (params.limit() as f64)).ceil() as u32; let response = PaginatedResponse { items, total, page: params.page.unwrap_or(1), limit: params.limit(), total_pages, }; (StatusCode::OK, Json(ApiResponse::ok(response))).into_response() } Err(e) => api_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), } } /// 获取单个会话 pub async fn get_session( State(state): State>, Path(session_id): Path, _user: AuthUser, ) -> impl IntoResponse { let repo = SessionRepository::new(&state.db); match repo.find_by_id(&session_id).await { Ok(session) => { let response: SessionResponse = session.into(); (StatusCode::OK, Json(ApiResponse::ok(response))).into_response() } Err(_) => api_error(StatusCode::NOT_FOUND, "会话不存在"), } } /// 结束会话 pub async fn end_session( State(state): State>, Path(session_id): Path, user: AuthUser, ) -> impl IntoResponse { let session_repo = SessionRepository::new(&state.db); let device_repo = DeviceRepository::new(&state.db); // 获取会话 let session = match session_repo.find_by_id(&session_id).await { Ok(session) => session, Err(_) => return api_error(StatusCode::NOT_FOUND, "会话不存在"), }; // 验证用户有权结束会话 let user_devices = match device_repo.find_by_user(&user.user_id).await { Ok(devices) => devices, Err(e) => return api_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), }; let device_ids: Vec<&str> = user_devices.iter().map(|d| d.device_id.as_str()).collect(); let is_owner = device_ids.contains(&session.controller_device_id.as_str()) || device_ids.contains(&session.controlled_device_id.as_str()); if !is_owner && user.role != "admin" { return api_error(StatusCode::FORBIDDEN, "无权结束此会话"); } // 发送断开连接消息 let message = serde_json::json!({ "type": "session_end", "session_id": session_id, }); state.send_to_device(&session.controller_device_id, &message.to_string()).await; state.send_to_device(&session.controlled_device_id, &message.to_string()).await; // 更新会话状态 match session_repo.end_session(&session_id).await { Ok(_) => (StatusCode::OK, Json(ApiResponse::ok("会话已结束"))).into_response(), Err(e) => api_error(StatusCode::INTERNAL_SERVER_ERROR, e.to_string()), } }