feat: 树节点显示设备数量,如 无锡艾动 (15)
This commit is contained in:
parent
8a2e2ffc2b
commit
3607701c26
@ -14,7 +14,7 @@ use crate::error::AppError;
|
|||||||
use crate::middleware::auth::{self, CurrentUser};
|
use crate::middleware::auth::{self, CurrentUser};
|
||||||
use crate::commands::AppState;
|
use crate::commands::AppState;
|
||||||
|
|
||||||
/// 组织树接口 — 返回多级组织->项目树
|
/// 组织树接口 — 返回多级组织->项目树(含设备数量)
|
||||||
pub async fn organization_tree(
|
pub async fn organization_tree(
|
||||||
user: CurrentUser,
|
user: CurrentUser,
|
||||||
State(state): State<AppState>,
|
State(state): State<AppState>,
|
||||||
@ -23,7 +23,7 @@ pub async fn organization_tree(
|
|||||||
|
|
||||||
let db = &state.mysql;
|
let db = &state.mysql;
|
||||||
|
|
||||||
// 获取所有组织(带parent_id)
|
// 获取所有组织
|
||||||
let orgs: Vec<OrganizationRow> = sqlx::query_as(
|
let orgs: Vec<OrganizationRow> = sqlx::query_as(
|
||||||
"SELECT id, name, parent_id FROM organizations ORDER BY id"
|
"SELECT id, name, parent_id FROM organizations ORDER BY id"
|
||||||
)
|
)
|
||||||
@ -37,10 +37,19 @@ pub async fn organization_tree(
|
|||||||
.fetch_all(db)
|
.fetch_all(db)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
// 获取每个项目的设备数量
|
||||||
|
let project_counts: Vec<(i64, i64)> = sqlx::query_as(
|
||||||
|
"SELECT project_id, COUNT(*) as cnt FROM cabinets GROUP BY project_id"
|
||||||
|
)
|
||||||
|
.fetch_all(db)
|
||||||
|
.await?;
|
||||||
|
let project_count_map: std::collections::HashMap<i64, i64> = project_counts.into_iter().collect();
|
||||||
|
|
||||||
// 递归构建树
|
// 递归构建树
|
||||||
fn build_tree(
|
fn build_tree(
|
||||||
orgs: &[OrganizationRow],
|
orgs: &[OrganizationRow],
|
||||||
projects: &[ProjectRow],
|
projects: &[ProjectRow],
|
||||||
|
project_count_map: &std::collections::HashMap<i64, i64>,
|
||||||
parent_id: Option<i64>,
|
parent_id: Option<i64>,
|
||||||
) -> Vec<TreeNode> {
|
) -> Vec<TreeNode> {
|
||||||
orgs
|
orgs
|
||||||
@ -48,19 +57,22 @@ pub async fn organization_tree(
|
|||||||
.filter(|o| o.parent_id == parent_id)
|
.filter(|o| o.parent_id == parent_id)
|
||||||
.map(|org| {
|
.map(|org| {
|
||||||
// 递归获取子组织
|
// 递归获取子组织
|
||||||
let children = build_tree(orgs, projects, Some(org.id));
|
let children = build_tree(orgs, projects, project_count_map, Some(org.id));
|
||||||
|
|
||||||
// 获取该组织下的项目
|
// 获取该组织下的项目
|
||||||
let org_projects: Vec<TreeNode> = projects
|
let org_projects: Vec<TreeNode> = projects
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|p| p.organization_id == Some(org.id))
|
.filter(|p| p.organization_id == Some(org.id))
|
||||||
.map(|p| TreeNode {
|
.map(|p| {
|
||||||
|
let count = project_count_map.get(&p.id).copied().unwrap_or(0);
|
||||||
|
TreeNode {
|
||||||
id: p.id,
|
id: p.id,
|
||||||
name: p.name.clone(),
|
name: format!("{} ({})", p.name, count),
|
||||||
children: None,
|
children: None,
|
||||||
abstract_id: None,
|
abstract_id: None,
|
||||||
imei: None,
|
imei: None,
|
||||||
status: None,
|
status: None,
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -68,9 +80,21 @@ pub async fn organization_tree(
|
|||||||
let mut all_children = children;
|
let mut all_children = children;
|
||||||
all_children.extend(org_projects);
|
all_children.extend(org_projects);
|
||||||
|
|
||||||
|
// 计算本组织下的总设备数量
|
||||||
|
let total_count: i64 = all_children.iter()
|
||||||
|
.map(|c| {
|
||||||
|
// 从项目名称中提取数量
|
||||||
|
if let Some(start) = c.name.rfind('(') {
|
||||||
|
if let Some(end) = c.name.rfind(')') {
|
||||||
|
c.name[start+1..end].parse().unwrap_or(0)
|
||||||
|
} else { 0 }
|
||||||
|
} else { 0 }
|
||||||
|
})
|
||||||
|
.sum();
|
||||||
|
|
||||||
TreeNode {
|
TreeNode {
|
||||||
id: org.id,
|
id: org.id,
|
||||||
name: org.name.clone(),
|
name: format!("{} ({})", org.name, total_count),
|
||||||
children: if all_children.is_empty() { None } else { Some(all_children) },
|
children: if all_children.is_empty() { None } else { Some(all_children) },
|
||||||
abstract_id: None,
|
abstract_id: None,
|
||||||
imei: None,
|
imei: None,
|
||||||
@ -80,7 +104,7 @@ pub async fn organization_tree(
|
|||||||
.collect()
|
.collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
let tree = build_tree(&orgs, &projects, None);
|
let tree = build_tree(&orgs, &projects, &project_count_map, None);
|
||||||
|
|
||||||
Ok(Json(json!(tree)))
|
Ok(Json(json!(tree)))
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user