feat: 卡片显示真实通道状态统计(空闲/充电/充满/故障)
This commit is contained in:
parent
3607701c26
commit
7290da8eae
@ -126,44 +126,57 @@ pub async fn filter_cabinets(
|
|||||||
|
|
||||||
let db = &state.mysql;
|
let db = &state.mysql;
|
||||||
|
|
||||||
|
// 基础SQL:联表查询获取通道状态统计
|
||||||
|
let base_sql = "
|
||||||
|
SELECT
|
||||||
|
c.id, c.project_id, c.abstract_id, c.imei, c.iccid, c.name, c.address, c.status,
|
||||||
|
(SELECT COUNT(*) FROM cabin_boards cb WHERE cb.cabinet_id = c.id) as board_count,
|
||||||
|
(SELECT COUNT(*) FROM cabin_boards cb2
|
||||||
|
JOIN compartments comp ON comp.cabin_board_id = cb2.id
|
||||||
|
WHERE cb2.cabinet_id = c.id) as channel_count,
|
||||||
|
(SELECT COUNT(*) FROM cabin_boards cb3
|
||||||
|
JOIN compartments comp2 ON comp2.cabin_board_id = cb3.id
|
||||||
|
WHERE cb3.cabinet_id = c.id AND comp2.status = 0) as idle_count,
|
||||||
|
(SELECT COUNT(*) FROM cabin_boards cb4
|
||||||
|
JOIN compartments comp3 ON comp3.cabin_board_id = cb4.id
|
||||||
|
WHERE cb4.cabinet_id = c.id AND comp3.status = 1) as charging_count,
|
||||||
|
(SELECT COUNT(*) FROM cabin_boards cb5
|
||||||
|
JOIN compartments comp4 ON comp4.cabin_board_id = cb5.id
|
||||||
|
WHERE cb5.cabinet_id = c.id AND comp4.status = 2) as full_count,
|
||||||
|
(SELECT COUNT(*) FROM cabin_boards cb6
|
||||||
|
JOIN compartments comp5 ON comp5.cabin_board_id = cb6.id
|
||||||
|
WHERE cb6.cabinet_id = c.id AND comp5.status = 3) as fault_count
|
||||||
|
FROM cabinets c
|
||||||
|
";
|
||||||
|
|
||||||
let rows = if let Some(proj_id) = params.project_id {
|
let rows = if let Some(proj_id) = params.project_id {
|
||||||
// 按项目筛选
|
|
||||||
sqlx::query_as::<_, CabinetRow>(
|
sqlx::query_as::<_, CabinetRow>(
|
||||||
"SELECT id, project_id, abstract_id, imei, iccid, name, address, status
|
&format!("{} WHERE c.project_id = ? ORDER BY c.id", base_sql)
|
||||||
FROM cabinets WHERE project_id = ? ORDER BY id"
|
|
||||||
)
|
)
|
||||||
.bind(proj_id)
|
.bind(proj_id)
|
||||||
.fetch_all(db)
|
.fetch_all(db)
|
||||||
.await?
|
.await?
|
||||||
} else if let Some(org_id) = params.organization_id {
|
} else if let Some(org_id) = params.organization_id {
|
||||||
// 按组织筛选(包括下级组织)
|
|
||||||
sqlx::query_as::<_, CabinetRow>(
|
sqlx::query_as::<_, CabinetRow>(
|
||||||
"SELECT c.id, c.project_id, c.abstract_id, c.imei, c.iccid, c.name, c.address, c.status
|
&format!("{} JOIN projects p ON c.project_id = p.id
|
||||||
FROM cabinets c
|
|
||||||
JOIN projects p ON c.project_id = p.id
|
|
||||||
WHERE p.organization_id IN (
|
WHERE p.organization_id IN (
|
||||||
SELECT id FROM organizations WHERE id = ? OR parent_id = ?
|
SELECT id FROM organizations WHERE id = ? OR parent_id = ?
|
||||||
) ORDER BY c.id"
|
) ORDER BY c.id", base_sql)
|
||||||
)
|
)
|
||||||
.bind(org_id)
|
.bind(org_id)
|
||||||
.bind(org_id)
|
.bind(org_id)
|
||||||
.fetch_all(db)
|
.fetch_all(db)
|
||||||
.await?
|
.await?
|
||||||
} else if user.role_level >= 2 {
|
} else if user.role_level >= 2 {
|
||||||
// 总管理员看所有
|
|
||||||
sqlx::query_as::<_, CabinetRow>(
|
sqlx::query_as::<_, CabinetRow>(
|
||||||
"SELECT id, project_id, abstract_id, imei, iccid, name, address, status
|
&format!("{} ORDER BY c.id", base_sql)
|
||||||
FROM cabinets ORDER BY id"
|
|
||||||
)
|
)
|
||||||
.fetch_all(db)
|
.fetch_all(db)
|
||||||
.await?
|
.await?
|
||||||
} else if let Some(org_id) = user.organization_id {
|
} else if let Some(org_id) = user.organization_id {
|
||||||
// 企业管理员只看本组织
|
|
||||||
sqlx::query_as::<_, CabinetRow>(
|
sqlx::query_as::<_, CabinetRow>(
|
||||||
"SELECT c.id, c.project_id, c.abstract_id, c.imei, c.iccid, c.name, c.address, c.status
|
&format!("{} JOIN projects p ON c.project_id = p.id
|
||||||
FROM cabinets c
|
WHERE p.organization_id = ? ORDER BY c.id", base_sql)
|
||||||
JOIN projects p ON c.project_id = p.id
|
|
||||||
WHERE p.organization_id = ? ORDER BY c.id"
|
|
||||||
)
|
)
|
||||||
.bind(org_id)
|
.bind(org_id)
|
||||||
.fetch_all(db)
|
.fetch_all(db)
|
||||||
|
|||||||
@ -72,6 +72,18 @@ pub struct CabinetRow {
|
|||||||
#[serde(skip_serializing_if = "Option::is_none")]
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
pub address: Option<String>,
|
pub address: Option<String>,
|
||||||
pub status: i8,
|
pub status: i8,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub board_count: Option<i64>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub channel_count: Option<i64>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub idle_count: Option<i64>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub charging_count: Option<i64>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub full_count: Option<i64>,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
pub fault_count: Option<i64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 树节点
|
/// 树节点
|
||||||
|
|||||||
@ -25,6 +25,12 @@ export interface Cabinet {
|
|||||||
name?: string;
|
name?: string;
|
||||||
address?: string;
|
address?: string;
|
||||||
status: number;
|
status: number;
|
||||||
|
board_count?: number;
|
||||||
|
channel_count?: number;
|
||||||
|
idle_count?: number;
|
||||||
|
charging_count?: number;
|
||||||
|
full_count?: number;
|
||||||
|
fault_count?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Compartment {
|
export interface Compartment {
|
||||||
|
|||||||
@ -66,10 +66,12 @@ export default function CabinetGrid({ cabinets, loading }: CabinetGridProps) {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 通道状态 */}
|
{/* 通道状态 */}
|
||||||
<div style={{ display: 'flex', gap: 12, fontSize: 12, borderTop: '1px solid var(--color-border)', paddingTop: 8 }}>
|
<div style={{ display: 'flex', flexWrap: 'wrap', gap: 8, fontSize: 12, borderTop: '1px solid var(--color-border)', paddingTop: 8 }}>
|
||||||
<span style={{ color: 'var(--color-text-3)' }}>空闲: <b style={{ color: 'var(--color-text-1)' }}>30</b></span>
|
<span style={{ color: 'var(--color-text-3)' }}>通道: <b style={{ color: 'var(--color-text-1)' }}>{cab.channel_count || 36}</b></span>
|
||||||
<span style={{ color: 'var(--color-text-3)' }}>充电: <b style={{ color: '#165dff' }}>5</b></span>
|
<span style={{ color: 'var(--color-text-3)' }}>空闲: <b style={{ color: 'var(--color-text-1)' }}>{cab.idle_count || 0}</b></span>
|
||||||
<span style={{ color: 'var(--color-text-3)' }}>故障: <b style={{ color: '#f53f3f' }}>1</b></span>
|
<span style={{ color: 'var(--color-text-3)' }}>充电: <b style={{ color: '#165dff' }}>{cab.charging_count || 0}</b></span>
|
||||||
|
<span style={{ color: 'var(--color-text-3)' }}>充满: <b style={{ color: '#00b42a' }}>{cab.full_count || 0}</b></span>
|
||||||
|
<span style={{ color: 'var(--color-text-3)' }}>故障: <b style={{ color: '#f53f3f' }}>{cab.fault_count || 0}</b></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 地址 */}
|
{/* 地址 */}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user