145 lines
4.4 KiB
Rust
Raw Normal View History

//! 组织树 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<AppState>,
) -> Result<Json<Value>, AppError> {
auth::check_permission(&user, "device:view")?;
let db = &state.mysql;
// 根据角色过滤组织
let orgs: Vec<OrganizationRow> = 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<ProjectRow> = sqlx::query_as(
"SELECT id, organization_id, name FROM projects ORDER BY id"
)
.fetch_all(db)
.await?;
// 构建树(只到项目节点)
let tree: Vec<TreeNode> = orgs
.into_iter()
.map(|org| {
let org_projects: Vec<ProjectRow> = projects
.iter()
.filter(|p| p.organization_id == Some(org.id))
.cloned()
.collect();
let children: Vec<TreeNode> = 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<i64>,
pub project_id: Option<i64>,
}
/// 设备列表接口 — 根据组织/项目筛选
pub async fn filter_cabinets(
user: CurrentUser,
State(state): State<AppState>,
Query(params): Query<CabinetFilterParams>,
) -> Result<Json<Value>, 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)))
}