//! 组织树 API //! //! 两个独立接口: //! 1. /api/organization-tree — 只返回组织->项目树(不含设备) //! 2. /api/cabinets/filter — 根据组织/项目筛选设备列表 use axum::extract::{State, Query}; use axum::Json; use serde::Deserialize; use serde_json::{json, Value}; use super::organizations::{CabinetRow, OrganizationRow, ProjectRow, TreeNode}; use crate::error::AppError; use crate::middleware::auth::{self, CurrentUser}; use crate::commands::AppState; /// 组织树接口 — 只返回组织->项目(不含设备) pub async fn organization_tree( user: CurrentUser, State(state): State, ) -> Result, AppError> { auth::check_permission(&user, "device:view")?; let db = &state.mysql; // 根据角色过滤组织 let orgs: Vec = if user.role_level >= 2 { sqlx::query_as("SELECT id, name FROM organizations ORDER BY id") .fetch_all(db) .await? } else if let Some(org_id) = user.organization_id { sqlx::query_as("SELECT id, name FROM organizations WHERE id = ? ORDER BY id") .bind(org_id) .fetch_all(db) .await? } else { return Ok(Json(json!([]))); }; // 获取所有项目 let projects: Vec = sqlx::query_as( "SELECT id, organization_id, name FROM projects ORDER BY id" ) .fetch_all(db) .await?; // 构建树(只到项目节点) let tree: Vec = orgs .into_iter() .map(|org| { let org_projects: Vec = projects .iter() .filter(|p| p.organization_id == Some(org.id)) .cloned() .collect(); let children: Vec = org_projects .into_iter() .map(|proj| TreeNode { id: proj.id, name: proj.name, children: None, abstract_id: None, imei: None, status: None, }) .collect(); TreeNode { id: org.id, name: org.name, children: Some(children), abstract_id: None, imei: None, status: None, } }) .collect(); Ok(Json(json!(tree))) } /// 设备列表筛选参数 #[derive(Deserialize)] pub struct CabinetFilterParams { pub organization_id: Option, pub project_id: Option, } /// 设备列表接口 — 根据组织/项目筛选 pub async fn filter_cabinets( user: CurrentUser, State(state): State, Query(params): Query, ) -> Result, AppError> { auth::check_permission(&user, "device:view")?; let db = &state.mysql; let rows = if let Some(proj_id) = params.project_id { // 按项目筛选 sqlx::query_as::<_, CabinetRow>( "SELECT id, project_id, abstract_id, imei, iccid, name, address, status FROM cabinets WHERE project_id = ? ORDER BY id" ) .bind(proj_id) .fetch_all(db) .await? } else if let Some(org_id) = params.organization_id { // 按组织筛选(通过项目关联) sqlx::query_as::<_, CabinetRow>( "SELECT c.id, c.project_id, c.abstract_id, c.imei, c.iccid, c.name, c.address, c.status FROM cabinets c JOIN projects p ON c.project_id = p.id WHERE p.organization_id = ? ORDER BY c.id" ) .bind(org_id) .fetch_all(db) .await? } else if user.role_level >= 2 { // 总管理员看所有 sqlx::query_as::<_, CabinetRow>( "SELECT id, project_id, abstract_id, imei, iccid, name, address, status FROM cabinets ORDER BY id" ) .fetch_all(db) .await? } else if let Some(org_id) = user.organization_id { // 企业管理员只看本组织 sqlx::query_as::<_, CabinetRow>( "SELECT c.id, c.project_id, c.abstract_id, c.imei, c.iccid, c.name, c.address, c.status FROM cabinets c JOIN projects p ON c.project_id = p.id WHERE p.organization_id = ? ORDER BY c.id" ) .bind(org_id) .fetch_all(db) .await? } else { vec![] }; Ok(Json(json!(rows))) }