121 lines
3.8 KiB
TypeScript
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>
|
|
);
|
|
}
|