Files
web-Iot/src/pages/Devices.tsx
2026-05-11 16:34:44 +08:00

121 lines
3.8 KiB
TypeScript

import React, { useState, useEffect } from 'react';
import { Layout, Typography, Menu } from 'antd';
import { AimOutlined, AppstoreOutlined, SettingOutlined } from '@ant-design/icons';
import DeviceOverviewPage from '../components/devices/DeviceOverviewPage';
import DeviceStatusPage from '../components/devices/DeviceStatusPage';
import { getDeviceListApi, getPlaneDeviceList } from '../api/device';
import { useSelector } from 'react-redux';
import { RootState } from '../store';
import WayLinePage from '../components/devices/WayLinePage';
const { Header, Content } = Layout;
const { Text } = Typography;
const DeviceStatusSettingPage = ({ serialNumber }) => (
<div style={{ padding: 20 }}>
<h2>设置状态页面</h2>
<p>当前查看设备序列号: <span style={{ fontWeight: 'bold', color: '#1890ff' }}>{serialNumber || '未选择设备'}</span></p>
{/* 这里后续可以根据 serialNumber 加载具体的设备状态详情 */}
</div>
);
export default function DeviceIndexPage() {
const [activeTab, setActiveTab] = useState('overview');
const [selectedSn, setSelectedSn] = useState(null);
const { userInfo } = useSelector((state: RootState) => state.user);
const [devices, setDevices] = useState([]);
const [planedevices, setPlaneDevices] = useState([]);
const [devicesAll, setDevicesAll] = useState([]);
const tabs = [
{ key: 'overview', label: '装备总览', icon: <AppstoreOutlined /> },
{ key: 'status', label: '设备状态', icon: <SettingOutlined /> },
{ key: 'wayLineTask', label: '航线任务', icon: <AimOutlined /> },
];
// 👇 核心修复:同时请求 + 同时合并
const fetchAllData = async () => {
if (!userInfo?.username) return;
try {
// 1. 同时发请求
const [deviceRes, planeRes] = await Promise.all([
getDeviceListApi({ tenantName: userInfo.username, deptId: 1 }),
getPlaneDeviceList(),
]);
// 2. 处理设备数据
const devData = deviceRes?.code === 200 ? (deviceRes.data || []) : [];
const planeData = planeRes?.code === 200 ? (planeRes.data?.detail || []) : [];
setDevices(devData);
setPlaneDevices(planeData);
setDevicesAll([...devData, ...planeData]);
} catch (err) {
console.error('数据请求失败', err);
}
};
useEffect(() => {
fetchAllData();
}, [userInfo]);
const handleViewStatus = (sn) => {
setSelectedSn(sn);
setActiveTab('status');
};
const renderContent = () => {
if (activeTab === 'overview') {
return <DeviceOverviewPage
devices={devices}
planedevices={planedevices}
devicesAll={devicesAll}
onViewStatus={handleViewStatus}
/>;
}
if (activeTab === 'status') {
return <DeviceStatusPage
devicesAll={devicesAll}
serialNumber={selectedSn}
onDeviceChange={(sn) => setSelectedSn(sn)}
/>;
}
if (activeTab === 'wayLineTask') return <WayLinePage />;
return null;
};
return (
<Layout style={{ minHeight: '100vh', background: '#fff', overflow: 'hidden', scrollbarWidth: "thin", scrollbarColor: '#ccc transparent' }}>
<div style={{ display: 'flex', paddingBottom: "12px" }}>
<div style={{ padding: '20px 24px 0', flexShrink: 0 }}>
<Typography.Title level={4} style={{ margin: 0 }}>装备控制</Typography.Title>
<Text type="secondary"> 装备总览、状态监控与参数配置</Text>
</div>
<Header style={{ flex: 1, background: '#fff', padding: 0, borderBottom: '1px solid #f0f0f0' }}>
<Menu
mode="horizontal"
selectedKeys={[activeTab]}
onClick={({ key }) => setActiveTab(key)}
items={tabs}
style={{ border: 0, height: 64, lineHeight: '64px' }}
/>
</Header>
</div>
<Content style={{
maxHeight: 'calc(100vh - 64px)',
overflowY: 'auto',
background: '#f5f7fa',
padding: '20px',
scrollbarWidth: "thin"
}}>
{renderContent()}
</Content>
</Layout>
);
}