|
|
|
|
|
import { Button, Col, Drawer, Form, Input, Menu, Pagination, Row, Select, Space, Switch, Table, Tag, Tree } from "antd";
|
|
|
|
|
|
import { useEffect, useRef, useState } from "react";
|
|
|
|
|
|
import styles from './InspectionTaskPlan.less'
|
|
|
|
|
|
import { Title } from "@/pages/inspectiontasks/InspectionTasks";
|
|
|
|
|
|
import btnImg1 from '@/assets/img/planBtn1.png'
|
|
|
|
|
|
import btnImg2 from '@/assets/img/planBtn2.png'
|
|
|
|
|
|
import btnImg3 from '@/assets/img/planBtn3.png'
|
|
|
|
|
|
import menuInactiveBg from '@/assets/img/3de08b72a292633bddad28950ba6c6d7fa084a23.png'
|
|
|
|
|
|
import activeBgImage from '@/assets/img/de55b2b9c8dab34462ff1b044a5a5c9668b11aa4.png'
|
|
|
|
|
|
import thermalImage from '@/assets/img/03ba6681098742e33bea38c40e3c23f16847dc1f.png'
|
|
|
|
|
|
|
|
|
|
|
|
import paibanBg from '@/assets/img/paiban.png'
|
|
|
|
|
|
import inspectionBg from '@/assets/img/Rectangle 34624130.svg'
|
|
|
|
|
|
import taskPlanBg from '@/assets/img/image 674 1.svg'
|
|
|
|
|
|
import {
|
|
|
|
|
|
DeleteOutlined,
|
|
|
|
|
|
DownOutlined,
|
|
|
|
|
|
EditOutlined,
|
|
|
|
|
|
ExportOutlined,
|
|
|
|
|
|
EyeOutlined,
|
|
|
|
|
|
PlusOutlined,
|
|
|
|
|
|
RedoOutlined
|
|
|
|
|
|
} from "@ant-design/icons";
|
|
|
|
|
|
const { Search } = Input
|
|
|
|
|
|
export const MenuBg = (props) => {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div className={styles["parallelogram-container"]}>
|
|
|
|
|
|
<span className={styles["text-content"]}>{props.text}</span>
|
|
|
|
|
|
<span className={styles["text-content"]} style={{ margin: '0' }}>{props.icon}</span>
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
//抽屉
|
|
|
|
|
|
const Drawers = (props) => {
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Drawer
|
|
|
|
|
|
title='详情'
|
|
|
|
|
|
closable={{ 'aria-label': 'Close Button' }}
|
|
|
|
|
|
onClose={props.onClose}
|
|
|
|
|
|
open={props.open}
|
|
|
|
|
|
width={500}
|
|
|
|
|
|
className={styles['customDrawer']}
|
|
|
|
|
|
>
|
|
|
|
|
|
<div style={{ padding: '20px' }}>
|
|
|
|
|
|
<Title title={'基本信息'} ></Title>
|
|
|
|
|
|
<Row style={{ margin: '20px 0' }}>
|
|
|
|
|
|
<Col span={12}>
|
|
|
|
|
|
<Row style={{ marginBottom: '20px' }}>
|
|
|
|
|
|
<Col span={8} className={styles['font1']}>所属班次</Col>
|
|
|
|
|
|
<Col span={16}>{props.row?.shifts}</Col>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Row>
|
|
|
|
|
|
<Col span={8} className={styles['font1']}>路线名称</Col>
|
|
|
|
|
|
<Col span={16}>{props.row?.name}</Col>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
<Col span={12}>
|
|
|
|
|
|
<Row style={{ marginBottom: '20px' }}>
|
|
|
|
|
|
<Col span={8} className={styles['font1']}>所属专业</Col>
|
|
|
|
|
|
<Col span={16}>{props.row?.affiliation}</Col>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Row>
|
|
|
|
|
|
<Col span={8} className={styles['font1']}>创建时间</Col>
|
|
|
|
|
|
<Col span={16}>{props.row?.time}</Col>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Title title={'巡检设备范围'}></Title>
|
|
|
|
|
|
<div className={styles['box']}>
|
|
|
|
|
|
<Tag className={styles['tag']} color="magenta">发电机</Tag>
|
|
|
|
|
|
<Tag className={styles['tag']} color="red">中水处区</Tag>
|
|
|
|
|
|
<Tag className={styles['tag']} color="volcano">1#增压风机变频器</Tag>
|
|
|
|
|
|
<Tag className={styles['tag']} color="orange">1#炉右上炉膛温度</Tag>
|
|
|
|
|
|
<Tag className={styles['tag']} color="gold">1#冷干机</Tag>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<Title title={'巡视项详情'}></Title>
|
|
|
|
|
|
<Row style={{ margin: '20px 0 10px 0' }}>
|
|
|
|
|
|
<Tag className={styles['tag']} color="magenta">发电机</Tag>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Row style={{ margin: '0 0 20px 0' }}>
|
|
|
|
|
|
<ul className={styles['ul']}>
|
|
|
|
|
|
<li>外观检查:有无破损、油污 </li>
|
|
|
|
|
|
<li>温度检测:轴承温度≤70℃,定子温度≤105℃</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Row style={{ margin: '20px 0 10px 0' }}>
|
|
|
|
|
|
<Tag className={styles['tag']} color="volcano">1#增压风机变频器</Tag>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Row style={{ margin: '0 0 20px 0' }}>
|
|
|
|
|
|
<ul className={styles['ul']}>
|
|
|
|
|
|
<li>运行指示灯:是否正常亮起 </li>
|
|
|
|
|
|
<li>散热风扇:是否正常转动</li>
|
|
|
|
|
|
<li>输出电压:380V±5%</li>
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Drawer>
|
|
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
// 员工表格组件
|
|
|
|
|
|
const EmployeeTable = () => {
|
|
|
|
|
|
// 状态管理
|
|
|
|
|
|
const [dataSource, setDataSource] = useState([]); // 表格数据
|
|
|
|
|
|
const [loading, setLoading] = useState(false); // 加载状态
|
|
|
|
|
|
const [total, setTotal] = useState(0); // 总条数
|
|
|
|
|
|
const [currentPage, setCurrentPage] = useState(1); // 当前页码
|
|
|
|
|
|
const [pageSize, setPageSize] = useState(10); // 每页条数
|
|
|
|
|
|
const [selectedRowKeys, setSelectedRowKeys] = useState([]); // 选中的行ID
|
|
|
|
|
|
|
|
|
|
|
|
// 表格列配置
|
|
|
|
|
|
const columns = [
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '序号',
|
|
|
|
|
|
dataIndex: 'index',
|
|
|
|
|
|
key: 'index',
|
|
|
|
|
|
width: 100,
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
render: (text, record, index) => (index + 1) + (currentPage - 1) * pageSize
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '工号',
|
|
|
|
|
|
dataIndex: 'employeeId',
|
|
|
|
|
|
key: 'employeeId',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '姓名',
|
|
|
|
|
|
dataIndex: 'name',
|
|
|
|
|
|
key: 'name',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '性别',
|
|
|
|
|
|
dataIndex: 'gender',
|
|
|
|
|
|
key: 'gender',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '所属部门',
|
|
|
|
|
|
dataIndex: 'department',
|
|
|
|
|
|
key: 'department',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '岗位',
|
|
|
|
|
|
dataIndex: 'position',
|
|
|
|
|
|
key: 'position',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '手机号码',
|
|
|
|
|
|
dataIndex: 'phone',
|
|
|
|
|
|
key: 'phone',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '状态',
|
|
|
|
|
|
dataIndex: 'status',
|
|
|
|
|
|
key: 'status',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
render: (status) => (
|
|
|
|
|
|
<Switch checked={status} />
|
|
|
|
|
|
)
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '入职时间',
|
|
|
|
|
|
dataIndex: 'hireDate',
|
|
|
|
|
|
key: 'hireDate',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '操作',
|
|
|
|
|
|
key: 'action',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
|
<Space size="small">
|
|
|
|
|
|
<a onClick={() => handleView(record)} style={{ color: '#2C9E9D' }}>
|
|
|
|
|
|
<EyeOutlined /> 查看详情
|
|
|
|
|
|
</a>
|
|
|
|
|
|
<a onClick={() => handleEdit(record)} style={{ color: '#2C9E9D' }}>
|
|
|
|
|
|
<EditOutlined /> 编辑
|
|
|
|
|
|
</a>
|
|
|
|
|
|
<a onClick={() => handleDelete(record)} style={{ color: '#ff4d4f' }}>
|
|
|
|
|
|
<DeleteOutlined /> 删除
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</Space>
|
|
|
|
|
|
),
|
|
|
|
|
|
},
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
// 选择框配置
|
|
|
|
|
|
const rowSelection = {
|
|
|
|
|
|
selectedRowKeys,
|
|
|
|
|
|
onChange: (newSelectedRowKeys) => {
|
|
|
|
|
|
setSelectedRowKeys(newSelectedRowKeys);
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 获取表格数据
|
|
|
|
|
|
const fetchTableData = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
setLoading(true);
|
|
|
|
|
|
// 这里是预留的接口调用位置
|
|
|
|
|
|
// 实际项目中替换为真实接口请求
|
|
|
|
|
|
// const response = await api.getEmployeeList({
|
|
|
|
|
|
// page: currentPage,
|
|
|
|
|
|
// pageSize: pageSize
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟数据 - 实际项目中删除
|
|
|
|
|
|
const mockData = [
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '1',
|
|
|
|
|
|
employeeId: 'GH001',
|
|
|
|
|
|
name: '钱佳仪',
|
|
|
|
|
|
gender: '女',
|
|
|
|
|
|
department: '运行部',
|
|
|
|
|
|
position: '巡检员',
|
|
|
|
|
|
phone: '189 7731 3118',
|
|
|
|
|
|
status: true,
|
|
|
|
|
|
hireDate: '2025-09-13'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '2',
|
|
|
|
|
|
employeeId: 'GH002',
|
|
|
|
|
|
name: '孙兆洪',
|
|
|
|
|
|
gender: '女',
|
|
|
|
|
|
department: '安保部',
|
|
|
|
|
|
position: '安全员',
|
|
|
|
|
|
phone: '156 9747 2741',
|
|
|
|
|
|
status: true,
|
|
|
|
|
|
hireDate: '2025-09-12'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '3',
|
|
|
|
|
|
employeeId: 'GH003',
|
|
|
|
|
|
name: '季丹',
|
|
|
|
|
|
gender: '男',
|
|
|
|
|
|
department: '设备部',
|
|
|
|
|
|
position: '维修工',
|
|
|
|
|
|
phone: '151 4456 8916',
|
|
|
|
|
|
status: true,
|
|
|
|
|
|
hireDate: '2025-08-16'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '4',
|
|
|
|
|
|
employeeId: 'GH004',
|
|
|
|
|
|
name: '赵晓辉',
|
|
|
|
|
|
gender: '男',
|
|
|
|
|
|
department: '调度室',
|
|
|
|
|
|
position: '调度员',
|
|
|
|
|
|
phone: '181 8511 3486',
|
|
|
|
|
|
status: true,
|
|
|
|
|
|
hireDate: '2025-08-15'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '5',
|
|
|
|
|
|
employeeId: 'GH005',
|
|
|
|
|
|
name: '何扑金',
|
|
|
|
|
|
gender: '女',
|
|
|
|
|
|
department: '消防班',
|
|
|
|
|
|
position: '消防员',
|
|
|
|
|
|
phone: '183 3220 4078',
|
|
|
|
|
|
status: true,
|
|
|
|
|
|
hireDate: '2025-07-20'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '6',
|
|
|
|
|
|
employeeId: 'GH006',
|
|
|
|
|
|
name: '吴国立',
|
|
|
|
|
|
gender: '男',
|
|
|
|
|
|
department: '综合部',
|
|
|
|
|
|
position: '文员',
|
|
|
|
|
|
phone: '187 5703 5618',
|
|
|
|
|
|
status: false,
|
|
|
|
|
|
hireDate: '2025-07-17'
|
|
|
|
|
|
}
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟接口返回 - 实际项目中使用接口数据
|
|
|
|
|
|
setDataSource(mockData);
|
|
|
|
|
|
setTotal(85); // 总条数,实际项目中从接口获取
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取员工数据失败:', error);
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
setLoading(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 初始加载和分页变化时重新获取数据
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
fetchTableData();
|
|
|
|
|
|
}, [currentPage, pageSize]);
|
|
|
|
|
|
|
|
|
|
|
|
// 处理查看详情
|
|
|
|
|
|
const handleView = (record) => {
|
|
|
|
|
|
// 预留查看详情逻辑
|
|
|
|
|
|
console.log('查看详情:', record);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理编辑
|
|
|
|
|
|
const handleEdit = (record) => {
|
|
|
|
|
|
// 预留编辑逻辑
|
|
|
|
|
|
console.log('编辑:', record);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理删除
|
|
|
|
|
|
const handleDelete = (record) => {
|
|
|
|
|
|
// 预留删除逻辑
|
|
|
|
|
|
console.log('删除:', record);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 渲染表格
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Table
|
|
|
|
|
|
rowSelection={{
|
|
|
|
|
|
type: 'checkbox',
|
|
|
|
|
|
...rowSelection,
|
|
|
|
|
|
}}
|
|
|
|
|
|
columns={columns}
|
|
|
|
|
|
dataSource={dataSource}
|
|
|
|
|
|
loading={loading}
|
|
|
|
|
|
pagination={false} // 关闭表格自带分页,使用外部分页组件
|
|
|
|
|
|
rowKey="key"
|
|
|
|
|
|
style={{ width: '100%', }}
|
|
|
|
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
const GroupTable = () => {
|
|
|
|
|
|
//状态管理
|
|
|
|
|
|
const [dataSource, setDataSource] = useState([]) //表格数据
|
|
|
|
|
|
const [loading, setLoading] = useState(false) //加载状态
|
|
|
|
|
|
const [total, setTotal] = useState(0)
|
|
|
|
|
|
const [currentPage, setCurrentPage] = useState(1)
|
|
|
|
|
|
const [pageSize, setPageSize] = useState(10)
|
|
|
|
|
|
const [selectedRowKeys, setSelectedRowKeys] = useState([])//选中行的id
|
|
|
|
|
|
|
|
|
|
|
|
const columns = [
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '序号',
|
|
|
|
|
|
dataIndex: 'index',
|
|
|
|
|
|
key: 'index',
|
|
|
|
|
|
width: 100,
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
render: (text, record, index) => (index + 1) + (currentPage - 1) * pageSize
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '班组编号',
|
|
|
|
|
|
dataIndex: 'groupId',
|
|
|
|
|
|
key: 'groundId',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '班组姓名',
|
|
|
|
|
|
dataIndex: 'groupName',
|
|
|
|
|
|
key: 'groupName',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '班组长',
|
|
|
|
|
|
dataIndex: 'groupHeader',
|
|
|
|
|
|
key: 'groupHeader',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '成员数量',
|
|
|
|
|
|
dataIndex: 'num',
|
|
|
|
|
|
key: 'num',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '负责区域',
|
|
|
|
|
|
dataIndex: 'position',
|
|
|
|
|
|
key: 'position',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '联系电话',
|
|
|
|
|
|
dataIndex: 'phone',
|
|
|
|
|
|
key: 'phone',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '班组状态',
|
|
|
|
|
|
dataIndex: 'status',
|
|
|
|
|
|
key: 'status',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
render: (status) => (
|
|
|
|
|
|
<Switch checked={status} />
|
|
|
|
|
|
)
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '创建时间',
|
|
|
|
|
|
dataIndex: 'createTime',
|
|
|
|
|
|
key: 'createTime',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '备注',
|
|
|
|
|
|
dataIndex: 'remarks',
|
|
|
|
|
|
key: 'remarks',
|
|
|
|
|
|
align: 'center'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '操作',
|
|
|
|
|
|
key: 'action',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
|
<Space size="small">
|
|
|
|
|
|
<a onClick={() => handleView(record)} style={{ color: '#2C9E9D' }}>
|
|
|
|
|
|
<EyeOutlined /> 查看详情
|
|
|
|
|
|
</a>
|
|
|
|
|
|
<a onClick={() => handleEdit(record)} style={{ color: '#2C9E9D' }}>
|
|
|
|
|
|
<EditOutlined /> 编辑
|
|
|
|
|
|
</a>
|
|
|
|
|
|
<a onClick={() => handleDelete(record)} style={{ color: '#ff4d4f' }}>
|
|
|
|
|
|
<DeleteOutlined /> 删除
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</Space>
|
|
|
|
|
|
),
|
|
|
|
|
|
},
|
|
|
|
|
|
]
|
|
|
|
|
|
// 选择框配置
|
|
|
|
|
|
const rowSelection = {
|
|
|
|
|
|
selectedRowKeys,
|
|
|
|
|
|
onChange: (newSelectedRowKeys) => {
|
|
|
|
|
|
setSelectedRowKeys(newSelectedRowKeys);
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
|
|
|
|
|
const fetchTableData = () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
setLoading(true)
|
|
|
|
|
|
const mockData = [
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '1',
|
|
|
|
|
|
groupId: 'GH001',
|
|
|
|
|
|
groupName: '输油运行一班',
|
|
|
|
|
|
groupHeader: '钱佳仪',
|
|
|
|
|
|
num: '8',
|
|
|
|
|
|
position: '油罐储存区 A、B 区',
|
|
|
|
|
|
phone: '189 7731 3118',
|
|
|
|
|
|
status: true,
|
|
|
|
|
|
createTime: '2025-09-13',
|
|
|
|
|
|
remarks: '负责日常输油设备巡检与操作',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '2',
|
|
|
|
|
|
groupId: 'GH002',
|
|
|
|
|
|
groupName: '消防应急班组',
|
|
|
|
|
|
groupHeader: '何颖颀',
|
|
|
|
|
|
num: '6',
|
|
|
|
|
|
position: '全厂区消防系统',
|
|
|
|
|
|
phone: '156 9747 2741',
|
|
|
|
|
|
status: true,
|
|
|
|
|
|
createTime: '2025-09-12',
|
|
|
|
|
|
remarks: '含2 名持证消防设施操作员',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '3',
|
|
|
|
|
|
groupId: 'GH003',
|
|
|
|
|
|
groupName: '设备维保班组',
|
|
|
|
|
|
groupHeader: '周遵武',
|
|
|
|
|
|
num: '10',
|
|
|
|
|
|
position: '泵房、工艺设备区',
|
|
|
|
|
|
phone: '151 4456 8916',
|
|
|
|
|
|
status: true,
|
|
|
|
|
|
createTime: '2025-08-16',
|
|
|
|
|
|
remarks: '擅长油泵、输油管道维护',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '4',
|
|
|
|
|
|
groupId: 'GH004',
|
|
|
|
|
|
groupName: '装卸作业班组',
|
|
|
|
|
|
groupHeader: '钱博西',
|
|
|
|
|
|
num: '7',
|
|
|
|
|
|
position: '油品装卸区站台',
|
|
|
|
|
|
phone: '181 8511 3486',
|
|
|
|
|
|
status: true,
|
|
|
|
|
|
createTime: '2025-08-15',
|
|
|
|
|
|
remarks: '专注装卸作业安全监护',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '5',
|
|
|
|
|
|
groupId: 'GH005',
|
|
|
|
|
|
groupName: '工艺调和班组',
|
|
|
|
|
|
groupHeader: '周缙绅',
|
|
|
|
|
|
num: '9',
|
|
|
|
|
|
position: '调和工艺区 1-3 号罐',
|
|
|
|
|
|
phone: '183 3220 4078',
|
|
|
|
|
|
status: true,
|
|
|
|
|
|
createTime: '2025-07-20',
|
|
|
|
|
|
remarks: '负责油品调和工艺参数管控',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '6',
|
|
|
|
|
|
groupId: 'GH006',
|
|
|
|
|
|
groupName: '临时支援班组',
|
|
|
|
|
|
groupHeader: '周江',
|
|
|
|
|
|
num: '4',
|
|
|
|
|
|
position: '全厂区(机动)',
|
|
|
|
|
|
phone: '187 5703 5618',
|
|
|
|
|
|
status: false,
|
|
|
|
|
|
createTime: '2025-07-17',
|
|
|
|
|
|
remarks: '项目结束,暂停用待复用',
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
setDataSource(mockData)
|
|
|
|
|
|
setTotal(85)
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error(error)
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
setLoading(false)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// 初始加载和分页变化时重新获取数据
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
fetchTableData();
|
|
|
|
|
|
}, [currentPage, pageSize]);
|
|
|
|
|
|
// 处理查看详情
|
|
|
|
|
|
const handleView = (record) => {
|
|
|
|
|
|
// 预留查看详情逻辑
|
|
|
|
|
|
console.log('查看详情:', record);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理编辑
|
|
|
|
|
|
const handleEdit = (record) => {
|
|
|
|
|
|
// 预留编辑逻辑
|
|
|
|
|
|
console.log('编辑:', record);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理删除
|
|
|
|
|
|
const handleDelete = (record) => {
|
|
|
|
|
|
// 预留删除逻辑
|
|
|
|
|
|
console.log('删除:', record);
|
|
|
|
|
|
};
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Table
|
|
|
|
|
|
rowSelection={{
|
|
|
|
|
|
type: 'checkbox',
|
|
|
|
|
|
...rowSelection,
|
|
|
|
|
|
}}
|
|
|
|
|
|
columns={columns}
|
|
|
|
|
|
dataSource={dataSource}
|
|
|
|
|
|
loading={loading}
|
|
|
|
|
|
pagination={false} // 关闭表格自带分页,使用外部分页组件
|
|
|
|
|
|
rowKey="key"
|
|
|
|
|
|
style={{ width: '100%', }}
|
|
|
|
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
const TimeTable = () => {
|
|
|
|
|
|
//状态管理
|
|
|
|
|
|
const [dataSource, setDataSource] = useState([]) //表格数据
|
|
|
|
|
|
const [loading, setLoading] = useState(false) //加载状态
|
|
|
|
|
|
const [total, setTotal] = useState(0)
|
|
|
|
|
|
const [currentPage, setCurrentPage] = useState(1)
|
|
|
|
|
|
const [pageSize, setPageSize] = useState(10)
|
|
|
|
|
|
const [selectedRowKeys, setSelectedRowKeys] = useState([])//选中行的id
|
|
|
|
|
|
const [open, setOpen] = useState(false)
|
|
|
|
|
|
const [row, setRow] = useState(null)
|
|
|
|
|
|
const columns = [
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '序号',
|
|
|
|
|
|
dataIndex: 'index',
|
|
|
|
|
|
key: 'index',
|
|
|
|
|
|
width: 100,
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
render: (text, record, index) => (index + 1) + (currentPage - 1) * pageSize
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '线路ID',
|
|
|
|
|
|
dataIndex: 'id',
|
|
|
|
|
|
key: 'id',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '线路名称',
|
|
|
|
|
|
dataIndex: 'name',
|
|
|
|
|
|
key: 'name',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '所属班次',
|
|
|
|
|
|
dataIndex: 'shifts',
|
|
|
|
|
|
key: 'shifts',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '所属专业',
|
|
|
|
|
|
dataIndex: 'affiliation',
|
|
|
|
|
|
key: 'affiliation',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '涉及区域',
|
|
|
|
|
|
dataIndex: 'position',
|
|
|
|
|
|
key: 'position',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '设备数量',
|
|
|
|
|
|
dataIndex: 'deviceNum',
|
|
|
|
|
|
key: 'deviceNum',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '巡视项数量',
|
|
|
|
|
|
dataIndex: 'lookNum',
|
|
|
|
|
|
key: 'lookNum',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '状态',
|
|
|
|
|
|
dataIndex: 'status',
|
|
|
|
|
|
key: 'status',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
render: (status) => (
|
|
|
|
|
|
<Switch checked={status} />
|
|
|
|
|
|
)
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '操作',
|
|
|
|
|
|
key: 'action',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
|
<Space size="small">
|
|
|
|
|
|
<a onClick={() => handleView(record)} style={{ color: '#2C9E9D' }}>
|
|
|
|
|
|
<EyeOutlined /> 查看详情
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</Space>
|
|
|
|
|
|
),
|
|
|
|
|
|
},
|
|
|
|
|
|
]
|
|
|
|
|
|
const fetchTableData = () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
setLoading(true)
|
|
|
|
|
|
const mockData = [
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '1',
|
|
|
|
|
|
id: 'GH001',
|
|
|
|
|
|
name: '白班电气巡检线 1',
|
|
|
|
|
|
shifts: '白班',
|
|
|
|
|
|
affiliation: '电气专业',
|
|
|
|
|
|
position: '发电机、中水处区',
|
|
|
|
|
|
deviceNum: '22',
|
|
|
|
|
|
lookNum: 3,
|
|
|
|
|
|
status: 'true',
|
|
|
|
|
|
time: '2025-03-31'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '2',
|
|
|
|
|
|
id: 'GH001',
|
|
|
|
|
|
name: '白班电气巡检线 1',
|
|
|
|
|
|
shifts: '白班',
|
|
|
|
|
|
affiliation: '电气专业',
|
|
|
|
|
|
position: '发电机、中水处区',
|
|
|
|
|
|
deviceNum: '22',
|
|
|
|
|
|
lookNum: 3,
|
|
|
|
|
|
status: 'true',
|
|
|
|
|
|
time: '2025-05-31'
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
]
|
|
|
|
|
|
setDataSource(mockData)
|
|
|
|
|
|
setTotal(85)
|
|
|
|
|
|
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error(error)
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
setLoading(false)
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
// 初始加载和分页变化时重新获取数据
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
fetchTableData();
|
|
|
|
|
|
}, [currentPage, pageSize]);
|
|
|
|
|
|
// 处理查看详情
|
|
|
|
|
|
const handleView = (record) => {
|
|
|
|
|
|
console.log('查看详情:', record);
|
|
|
|
|
|
setRow(record)
|
|
|
|
|
|
setOpen(true)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<>
|
|
|
|
|
|
<Table
|
|
|
|
|
|
columns={columns}
|
|
|
|
|
|
dataSource={dataSource}
|
|
|
|
|
|
loading={loading}
|
|
|
|
|
|
pagination={false} // 关闭表格自带分页,使用外部分页组件
|
|
|
|
|
|
rowKey="key"
|
|
|
|
|
|
style={{ width: '100%', }}
|
|
|
|
|
|
/>
|
|
|
|
|
|
<Drawers
|
|
|
|
|
|
open={open}
|
|
|
|
|
|
onClose={() => setOpen(false)}
|
|
|
|
|
|
row={row}
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
</Drawers>
|
|
|
|
|
|
</>
|
|
|
|
|
|
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
const StandardTable = () => {
|
|
|
|
|
|
// 状态管理
|
|
|
|
|
|
const [dataSource, setDataSource] = useState([]); // 表格数据
|
|
|
|
|
|
const [loading, setLoading] = useState(false); // 加载状态
|
|
|
|
|
|
const [total, setTotal] = useState(0); // 总条数
|
|
|
|
|
|
const [currentPage, setCurrentPage] = useState(1); // 当前页码
|
|
|
|
|
|
const [pageSize, setPageSize] = useState(10); // 每页条数
|
|
|
|
|
|
const [selectedRowKeys, setSelectedRowKeys] = useState([]); // 选中的行ID
|
|
|
|
|
|
|
|
|
|
|
|
// 表格列配置
|
|
|
|
|
|
const columns = [
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '序号',
|
|
|
|
|
|
dataIndex: 'index',
|
|
|
|
|
|
key: 'index',
|
|
|
|
|
|
width: 100,
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
render: (text, record, index) => (index + 1) + (currentPage - 1) * pageSize
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '方案名称',
|
|
|
|
|
|
dataIndex: 'name',
|
|
|
|
|
|
key: 'name',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '版本',
|
|
|
|
|
|
dataIndex: 'version',
|
|
|
|
|
|
key: 'version',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '状态',
|
|
|
|
|
|
dataIndex: 'status',
|
|
|
|
|
|
key: 'status',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
render: (status) => (
|
|
|
|
|
|
<Switch checked={status} />
|
|
|
|
|
|
)
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '最后更新时间',
|
|
|
|
|
|
dataIndex: 'time',
|
|
|
|
|
|
key: 'time',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '操作',
|
|
|
|
|
|
key: 'action',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
|
<Space size="small">
|
|
|
|
|
|
<a onClick={() => handleView(record)} style={{ color: '#2C9E9D' }}>
|
|
|
|
|
|
<EyeOutlined /> 查看详情
|
|
|
|
|
|
</a>
|
|
|
|
|
|
<a onClick={() => handleEdit(record)} style={{ color: '#2C9E9D' }}>
|
|
|
|
|
|
<EditOutlined /> 编辑
|
|
|
|
|
|
</a>
|
|
|
|
|
|
<a onClick={() => handleDelete(record)} style={{ color: '#ff4d4f' }}>
|
|
|
|
|
|
<DeleteOutlined /> 删除
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</Space>
|
|
|
|
|
|
),
|
|
|
|
|
|
},
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
// 选择框配置
|
|
|
|
|
|
const rowSelection = {
|
|
|
|
|
|
selectedRowKeys,
|
|
|
|
|
|
onChange: (newSelectedRowKeys) => {
|
|
|
|
|
|
setSelectedRowKeys(newSelectedRowKeys);
|
|
|
|
|
|
},
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 获取表格数据
|
|
|
|
|
|
const fetchTableData = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
setLoading(true);
|
|
|
|
|
|
// 这里是预留的接口调用位置
|
|
|
|
|
|
// 实际项目中替换为真实接口请求
|
|
|
|
|
|
// const response = await api.getEmployeeList({
|
|
|
|
|
|
// page: currentPage,
|
|
|
|
|
|
// pageSize: pageSize
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟数据 - 实际项目中删除
|
|
|
|
|
|
const mockData = [
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '1',
|
|
|
|
|
|
name: '输油设备巡检标准',
|
|
|
|
|
|
version: 'V2.0',
|
|
|
|
|
|
status: true,
|
|
|
|
|
|
time: '2025-09-13'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '2',
|
|
|
|
|
|
name: '消防系统巡检标准',
|
|
|
|
|
|
version: 'V1.1',
|
|
|
|
|
|
status: true,
|
|
|
|
|
|
time: '2025-09-13'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '3',
|
|
|
|
|
|
name: '电气设备巡检标准',
|
|
|
|
|
|
version: 'V1.0',
|
|
|
|
|
|
status: true,
|
|
|
|
|
|
time: '2025-09-13'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '4',
|
|
|
|
|
|
name: '输油设备巡检标准',
|
|
|
|
|
|
version: 'V2.0',
|
|
|
|
|
|
status: true,
|
|
|
|
|
|
time: '2025-09-13'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '5',
|
|
|
|
|
|
name: '消防系统巡检标准',
|
|
|
|
|
|
version: 'V1.1',
|
|
|
|
|
|
status: true,
|
|
|
|
|
|
time: '2025-09-13'
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '6',
|
|
|
|
|
|
name: '电气设备巡检标准',
|
|
|
|
|
|
version: 'V1.0',
|
|
|
|
|
|
status: true,
|
|
|
|
|
|
time: '2025-09-13'
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟接口返回 - 实际项目中使用接口数据
|
|
|
|
|
|
setDataSource(mockData);
|
|
|
|
|
|
setTotal(85); // 总条数,实际项目中从接口获取
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取员工数据失败:', error);
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
setLoading(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 初始加载和分页变化时重新获取数据
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
fetchTableData();
|
|
|
|
|
|
}, [currentPage, pageSize]);
|
|
|
|
|
|
|
|
|
|
|
|
// 处理查看详情
|
|
|
|
|
|
const handleView = (record) => {
|
|
|
|
|
|
// 预留查看详情逻辑
|
|
|
|
|
|
console.log('查看详情:', record);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理编辑
|
|
|
|
|
|
const handleEdit = (record) => {
|
|
|
|
|
|
// 预留编辑逻辑
|
|
|
|
|
|
console.log('编辑:', record);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理删除
|
|
|
|
|
|
const handleDelete = (record) => {
|
|
|
|
|
|
// 预留删除逻辑
|
|
|
|
|
|
console.log('删除:', record);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 渲染表格
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Table
|
|
|
|
|
|
rowSelection={{
|
|
|
|
|
|
type: 'checkbox',
|
|
|
|
|
|
...rowSelection,
|
|
|
|
|
|
}}
|
|
|
|
|
|
columns={columns}
|
|
|
|
|
|
dataSource={dataSource}
|
|
|
|
|
|
loading={loading}
|
|
|
|
|
|
pagination={false} // 关闭表格自带分页,使用外部分页组件
|
|
|
|
|
|
rowKey="key"
|
|
|
|
|
|
style={{ width: '100%', }}
|
|
|
|
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
const DeviceAttribute = () => {
|
|
|
|
|
|
// 状态管理
|
|
|
|
|
|
const [dataSource, setDataSource] = useState([]); // 表格数据
|
|
|
|
|
|
const [loading, setLoading] = useState(false); // 加载状态
|
|
|
|
|
|
const [total, setTotal] = useState(0); // 总条数
|
|
|
|
|
|
const [currentPage, setCurrentPage] = useState(1); // 当前页码
|
|
|
|
|
|
const [pageSize, setPageSize] = useState(10); // 每页条数
|
|
|
|
|
|
const [selectedRowKeys, setSelectedRowKeys] = useState([]); // 选中的行ID
|
|
|
|
|
|
|
|
|
|
|
|
// 表格列配置
|
|
|
|
|
|
const columns = [
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '属性名称',
|
|
|
|
|
|
dataIndex: 'attribute',
|
|
|
|
|
|
key: 'attribute',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '属性内容',
|
|
|
|
|
|
dataIndex: 'content',
|
|
|
|
|
|
key: 'content',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '属性分类',
|
|
|
|
|
|
dataIndex: 'class',
|
|
|
|
|
|
key: 'class',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '阈值内容',
|
|
|
|
|
|
dataIndex: 'threshold',
|
|
|
|
|
|
key: 'threshold',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
render: (value) => {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={{ textAlign: 'left', width: '100px', margin: 'auto' }}>
|
|
|
|
|
|
<div>上限:{value['上限']}</div>
|
|
|
|
|
|
<div>下限:{value['下限']}</div>
|
|
|
|
|
|
<div>单位:{value['单位']}</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '测点名称',
|
|
|
|
|
|
dataIndex: 'point',
|
|
|
|
|
|
key: 'point',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '操作',
|
|
|
|
|
|
key: 'action',
|
|
|
|
|
|
align: 'center',
|
|
|
|
|
|
render: (_, record) => (
|
|
|
|
|
|
<Space size="small">
|
|
|
|
|
|
<a onClick={() => handleEdit(record)} style={{ color: '#2C9E9D' }}>
|
|
|
|
|
|
<EditOutlined /> 编辑
|
|
|
|
|
|
</a>
|
|
|
|
|
|
<a onClick={() => handleDelete(record)} style={{ color: '#ff4d4f' }}>
|
|
|
|
|
|
<DeleteOutlined /> 删除
|
|
|
|
|
|
</a>
|
|
|
|
|
|
</Space>
|
|
|
|
|
|
),
|
|
|
|
|
|
},
|
|
|
|
|
|
]
|
|
|
|
|
|
// 获取表格数据
|
|
|
|
|
|
const fetchTableData = async () => {
|
|
|
|
|
|
try {
|
|
|
|
|
|
setLoading(true);
|
|
|
|
|
|
// 这里是预留的接口调用位置
|
|
|
|
|
|
// 实际项目中替换为真实接口请求
|
|
|
|
|
|
// const response = await api.getEmployeeList({
|
|
|
|
|
|
// page: currentPage,
|
|
|
|
|
|
// pageSize: pageSize
|
|
|
|
|
|
// });
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟数据 - 实际项目中删除
|
|
|
|
|
|
const mockData = [
|
|
|
|
|
|
{
|
|
|
|
|
|
key: '1',
|
|
|
|
|
|
attribute: '震动',
|
|
|
|
|
|
content: '加速度',
|
|
|
|
|
|
class: '阈值',
|
|
|
|
|
|
threshold: { '上限': 4000, '下限': 0, '单位': 'mm/s²' },
|
|
|
|
|
|
point: '测点2',
|
|
|
|
|
|
}, {
|
|
|
|
|
|
key: '2',
|
|
|
|
|
|
attribute: '震动',
|
|
|
|
|
|
content: '加速度',
|
|
|
|
|
|
class: '阈值',
|
|
|
|
|
|
threshold: { '上限': 4000, '下限': 0, '单位': 'mm/s²' },
|
|
|
|
|
|
point: '测点2',
|
|
|
|
|
|
}, {
|
|
|
|
|
|
key: '3',
|
|
|
|
|
|
attribute: '震动',
|
|
|
|
|
|
content: '加速度',
|
|
|
|
|
|
class: '阈值',
|
|
|
|
|
|
threshold: { '上限': '', '下限': '', '单位': '' },
|
|
|
|
|
|
point: '测点2',
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
// 模拟接口返回 - 实际项目中使用接口数据
|
|
|
|
|
|
setDataSource(mockData);
|
|
|
|
|
|
setTotal(85); // 总条数,实际项目中从接口获取
|
|
|
|
|
|
} catch (error) {
|
|
|
|
|
|
console.error('获取员工数据失败:', error);
|
|
|
|
|
|
} finally {
|
|
|
|
|
|
setLoading(false);
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 初始加载和分页变化时重新获取数据
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
fetchTableData();
|
|
|
|
|
|
}, [currentPage, pageSize]);
|
|
|
|
|
|
|
|
|
|
|
|
// 处理编辑
|
|
|
|
|
|
const handleEdit = (record) => {
|
|
|
|
|
|
// 预留编辑逻辑
|
|
|
|
|
|
console.log('编辑:', record);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理删除
|
|
|
|
|
|
const handleDelete = (record) => {
|
|
|
|
|
|
// 预留删除逻辑
|
|
|
|
|
|
console.log('删除:', record);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 渲染表格
|
|
|
|
|
|
return (
|
|
|
|
|
|
<Table
|
|
|
|
|
|
columns={columns}
|
|
|
|
|
|
dataSource={dataSource}
|
|
|
|
|
|
loading={loading}
|
|
|
|
|
|
pagination={false} // 关闭表格自带分页,使用外部分页组件
|
|
|
|
|
|
rowKey="key"
|
|
|
|
|
|
style={{ width: '100%', }}
|
|
|
|
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
);
|
|
|
|
|
|
}
|
|
|
|
|
|
// 分页组件
|
|
|
|
|
|
export const TablePagination = ({ currentPage, pageSize, total, onPageChange, onPageSizeChange }) => {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={{ textAlign: 'right', marginTop: 16, width: '100%' }}>
|
|
|
|
|
|
<Pagination
|
|
|
|
|
|
current={currentPage}
|
|
|
|
|
|
pageSize={pageSize}
|
|
|
|
|
|
total={total}
|
|
|
|
|
|
onChange={onPageChange}
|
|
|
|
|
|
onShowSizeChange={onPageSizeChange}
|
|
|
|
|
|
showSizeChanger
|
|
|
|
|
|
showQuickJumper
|
|
|
|
|
|
showTotal={(total) => `共 ${total} 条`}
|
|
|
|
|
|
pageSizeOptions={['10', '20', '50', '100']}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
const PeopleMange = () => {
|
|
|
|
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
|
|
|
|
const [pageSize, setPageSize] = useState(10);
|
|
|
|
|
|
const [total, setTotal] = useState(85); // 总条数,实际项目中从接口获取
|
|
|
|
|
|
|
|
|
|
|
|
// 处理页码变化
|
|
|
|
|
|
const handlePageChange = (page, pageSize) => {
|
|
|
|
|
|
setCurrentPage(page);
|
|
|
|
|
|
setPageSize(pageSize);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理每页条数变化
|
|
|
|
|
|
const handlePageSizeChange = (current, size) => {
|
|
|
|
|
|
setPageSize(size);
|
|
|
|
|
|
setCurrentPage(1); // 重置到第一页
|
|
|
|
|
|
};
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={{ backgroundColor: '#fff', padding: '20px' }}>
|
|
|
|
|
|
<Title title={'人员管理'}></Title>
|
|
|
|
|
|
<Row style={{ marginTop: '20px' }}>
|
|
|
|
|
|
<Button icon={<PlusOutlined />} className={styles['addBtn']} style={{ backgroundImage: `url(${btnImg1})`, marginRight: '50px' }}>新增</Button>
|
|
|
|
|
|
<Button className={styles['delBtn']} style={{ backgroundImage: `url(${btnImg2})` }}>删除</Button>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Row style={{ marginTop: '20px' }}>
|
|
|
|
|
|
<EmployeeTable
|
|
|
|
|
|
currentPage={currentPage}
|
|
|
|
|
|
pageSize={pageSize}
|
|
|
|
|
|
setTotal={setTotal}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Row style={{ marginTop: '20px' }}>
|
|
|
|
|
|
<TablePagination
|
|
|
|
|
|
currentPage={currentPage}
|
|
|
|
|
|
pageSize={pageSize}
|
|
|
|
|
|
total={total}
|
|
|
|
|
|
onPageChange={handlePageChange}
|
|
|
|
|
|
onPageSizeChange={handlePageSizeChange}
|
|
|
|
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
const ClassMange = () => {
|
|
|
|
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
|
|
|
|
const [pageSize, setPageSize] = useState(10);
|
|
|
|
|
|
const [total, setTotal] = useState(85); // 总条数,实际项目中从接口获取
|
|
|
|
|
|
|
|
|
|
|
|
// 处理页码变化
|
|
|
|
|
|
const handlePageChange = (page, pageSize) => {
|
|
|
|
|
|
setCurrentPage(page);
|
|
|
|
|
|
setPageSize(pageSize);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理每页条数变化
|
|
|
|
|
|
const handlePageSizeChange = (current, size) => {
|
|
|
|
|
|
setPageSize(size);
|
|
|
|
|
|
setCurrentPage(1); // 重置到第一页
|
|
|
|
|
|
};
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={{ backgroundColor: '#fff', padding: '20px' }}>
|
|
|
|
|
|
<Title title={'班组管理'}></Title>
|
|
|
|
|
|
<Row style={{ marginTop: '20px' }}>
|
|
|
|
|
|
<Button icon={<PlusOutlined />} className={styles['addBtn']} style={{ backgroundImage: `url(${btnImg1})`, marginRight: '50px' }}>新增</Button>
|
|
|
|
|
|
<Button className={styles['delBtn']} style={{ backgroundImage: `url(${btnImg2})` }}>删除</Button>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Row style={{ marginTop: '20px' }}>
|
|
|
|
|
|
<GroupTable></GroupTable>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Row style={{ marginTop: '20px' }}>
|
|
|
|
|
|
<TablePagination
|
|
|
|
|
|
currentPage={currentPage}
|
|
|
|
|
|
pageSize={pageSize}
|
|
|
|
|
|
total={total}
|
|
|
|
|
|
onPageChange={handlePageChange}
|
|
|
|
|
|
onPageSizeChange={handlePageSizeChange}
|
|
|
|
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
const TimeMange = () => {
|
|
|
|
|
|
const [viewState, setViewState] = useState('view0')
|
|
|
|
|
|
const view0 = useRef(null)
|
|
|
|
|
|
const view1 = useRef(null)
|
|
|
|
|
|
const checkView = (viewState) => {
|
|
|
|
|
|
setViewState(viewState)
|
|
|
|
|
|
}
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
view0.current.classList.remove('view-active')
|
|
|
|
|
|
view1.current.classList.remove('view-active')
|
|
|
|
|
|
if (viewState === 'view0') {
|
|
|
|
|
|
view0.current.style.backgroundColor = '#045F5E80'
|
|
|
|
|
|
view1.current.style.backgroundColor = '#B7E5D533'
|
|
|
|
|
|
view0.current.style.color = '#fff'
|
|
|
|
|
|
view1.current.style.color = '#000'
|
|
|
|
|
|
} else {
|
|
|
|
|
|
view0.current.style.backgroundColor = '#B7E5D533'
|
|
|
|
|
|
view1.current.style.backgroundColor = '#045F5E80'
|
|
|
|
|
|
view0.current.style.color = '#000'
|
|
|
|
|
|
view1.current.style.color = '#fff'
|
|
|
|
|
|
}
|
|
|
|
|
|
}, [viewState])
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={{ backgroundColor: '#fff', padding: '20px' }}>
|
|
|
|
|
|
<Title title={'排班管理'}></Title>
|
|
|
|
|
|
<Row style={{ marginTop: '20px' }}>
|
|
|
|
|
|
<Col span={4}></Col>
|
|
|
|
|
|
<Col span={16} style={{ textAlign: 'center' }}>
|
|
|
|
|
|
<div style={{ color: '#006665', fontSize: '20px', fontWeight: '400' }}>
|
|
|
|
|
|
<span style={{ cursor: 'pointer' }}><</span>
|
|
|
|
|
|
<span style={{ margin: '10px', }}>2025年8月</span>
|
|
|
|
|
|
<span style={{ cursor: 'pointer' }}>></span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div style={{ color: '#999999', fontSize: '14px' }}>
|
|
|
|
|
|
<span>上次编辑:</span>
|
|
|
|
|
|
<span>李朔 </span>
|
|
|
|
|
|
<span>2025-7-22 09:34</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
<Col span={4} style={{ display: "flex", alignItems: 'center', justifyContent: 'end' }}>
|
|
|
|
|
|
<Button icon={<ExportOutlined />} className={styles['exportBtn']} style={{ backgroundImage: `url(${btnImg1})` }}>导出</Button>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Row style={{ borderRadius: '4px', width: '100%', marginTop: '20px' }}>
|
|
|
|
|
|
<Row style={{ backgroundColor: '#F0F7F7', width: '100%', padding: '10px 30px' }}>
|
|
|
|
|
|
<Col span={18}>
|
|
|
|
|
|
<Row>
|
|
|
|
|
|
{/*<Button ref={view0} className={`${styles['view']} ${styles['view-active']}`} onClick={()=>checkView('view0')}>人员视角</Button>*/}
|
|
|
|
|
|
<Button ref={view0} className={styles['view']} onClick={() => checkView('view0')}>人员视角</Button>
|
|
|
|
|
|
<Button ref={view1} className={styles['view']} onClick={() => checkView('view1')}>班组视角</Button>
|
|
|
|
|
|
<Form
|
|
|
|
|
|
layout={'inline'}
|
|
|
|
|
|
>
|
|
|
|
|
|
<Form.Item
|
|
|
|
|
|
label={<label>岗位类型</label>}
|
|
|
|
|
|
name="type"
|
|
|
|
|
|
>
|
|
|
|
|
|
<Select
|
|
|
|
|
|
defaultValue={'全部'}
|
|
|
|
|
|
style={{ width: '132px', height: 40 }}
|
|
|
|
|
|
></Select>
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
<Form.Item
|
|
|
|
|
|
label={<label>姓名</label>}
|
|
|
|
|
|
name="type1"
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
<Input
|
|
|
|
|
|
placeholder={'请输入姓名'}
|
|
|
|
|
|
style={{ width: '200px' }}
|
|
|
|
|
|
></Input>
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
<Form.Item
|
|
|
|
|
|
label={<label>班组</label>}
|
|
|
|
|
|
name="type2"
|
|
|
|
|
|
|
|
|
|
|
|
>
|
|
|
|
|
|
<Select
|
|
|
|
|
|
defaultValue={'全部'}
|
|
|
|
|
|
style={{ width: '132px' }}
|
|
|
|
|
|
></Select>
|
|
|
|
|
|
</Form.Item>
|
|
|
|
|
|
</Form>
|
|
|
|
|
|
<Button icon={<RedoOutlined />} className={styles['resetBtn']} style={{ backgroundImage: `url(${btnImg3})` }}>重置</Button>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
<Col span={6} style={{ textAlign: 'right' }}>
|
|
|
|
|
|
<Button icon={<PlusOutlined />} className={styles['addBtn']} style={{ backgroundImage: `url(${btnImg1})`, }}>新增</Button>
|
|
|
|
|
|
<Button icon={<RedoOutlined />} className={styles['resetBtn']} style={{ backgroundImage: `url(${btnImg3})`, margin: '0 20px' }}>编辑</Button>
|
|
|
|
|
|
<Button className={styles['delBtn']} style={{ backgroundImage: `url(${btnImg2})` }}>删除</Button>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<div className={styles['paibanBg']} style={{ backgroundImage: `url(${paibanBg})` }}>
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
const PatrolRouteQuery = () => {
|
|
|
|
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
|
|
|
|
const [pageSize, setPageSize] = useState(10);
|
|
|
|
|
|
const [total, setTotal] = useState(85); // 总条数,实际项目中从接口获取
|
|
|
|
|
|
|
|
|
|
|
|
// 处理页码变化
|
|
|
|
|
|
const handlePageChange = (page, pageSize) => {
|
|
|
|
|
|
setCurrentPage(page);
|
|
|
|
|
|
setPageSize(pageSize);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理每页条数变化
|
|
|
|
|
|
const handlePageSizeChange = (current, size) => {
|
|
|
|
|
|
setPageSize(size);
|
|
|
|
|
|
setCurrentPage(1); // 重置到第一页
|
|
|
|
|
|
};
|
|
|
|
|
|
const treeData = [
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '班次',
|
|
|
|
|
|
key: '班次',
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{ title: '白班', key: '白班', },
|
|
|
|
|
|
{ title: '中班', key: '中班', },
|
|
|
|
|
|
{ title: '夜班', key: '夜班', },
|
|
|
|
|
|
{ title: '中班巡检', key: '中班巡检', },
|
|
|
|
|
|
{ title: '夜班二巡检', key: '夜班二巡检', },
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '专业',
|
|
|
|
|
|
key: '专业',
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{ title: '电器专业', key: '电器专业', },
|
|
|
|
|
|
{ title: '水处理', key: '水处理', },
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '区域',
|
|
|
|
|
|
key: '区域',
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{ title: '发电机区域', key: '发电机区域', },
|
|
|
|
|
|
{ title: '中水处区', key: '中水处区', },
|
|
|
|
|
|
{ title: '除盐水区域', key: '除盐水区域', },
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={{ backgroundColor: '#fff', padding: '20px' }}>
|
|
|
|
|
|
<Row>
|
|
|
|
|
|
<Col span={3} style={{ backgroundColor: '#E7F2ED', padding: '10px 20px' }}>
|
|
|
|
|
|
|
|
|
|
|
|
<Title title={'巡视线路'} ></Title>
|
|
|
|
|
|
<div style={{ marginTop: '20px' }}>
|
|
|
|
|
|
<Tree
|
|
|
|
|
|
treeData={treeData}
|
|
|
|
|
|
checkable
|
|
|
|
|
|
showLine
|
|
|
|
|
|
defaultExpandParent={true}
|
|
|
|
|
|
defaultExpandedKeys={['班次', '专业', '区域']}
|
|
|
|
|
|
className={styles['tree']}
|
|
|
|
|
|
>
|
|
|
|
|
|
</Tree>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
<Col span={21} style={{ padding: '0 20px' }}>
|
|
|
|
|
|
<Title title={'巡视线路'}></Title>
|
|
|
|
|
|
<Row style={{ marginTop: '20px' }}>
|
|
|
|
|
|
<Button className={styles['addBtn']} style={{ backgroundImage: `url(${btnImg1})` }}>
|
|
|
|
|
|
重新选择
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Row style={{ marginTop: '20px', minHeight: '550px' }}>
|
|
|
|
|
|
<TimeTable>
|
|
|
|
|
|
|
|
|
|
|
|
</TimeTable>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Row style={{ marginTop: '20px' }}>
|
|
|
|
|
|
<TablePagination
|
|
|
|
|
|
currentPage={currentPage}
|
|
|
|
|
|
pageSize={pageSize}
|
|
|
|
|
|
total={total}
|
|
|
|
|
|
onPageChange={handlePageChange}
|
|
|
|
|
|
onPageSizeChange={handlePageSizeChange}
|
|
|
|
|
|
|
|
|
|
|
|
/>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
const SmartInspectionRange = () => {
|
|
|
|
|
|
// 巡检范围树形数据,根据参考图更新
|
|
|
|
|
|
const treeData = [
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '核心环控路径',
|
|
|
|
|
|
key: 'core-path',
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{ title: '指挥调度中心', key: 'command-center' },
|
|
|
|
|
|
{ title: '罐区集群', key: 'tank-cluster' },
|
|
|
|
|
|
{ title: '泵房集群', key: 'pump-cluster' },
|
|
|
|
|
|
{ title: '管线网络', key: 'pipeline-network' },
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '罐区',
|
|
|
|
|
|
key: 'tank-area',
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '高危罐区',
|
|
|
|
|
|
key: 'high-risk-tank',
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{ title: '顶源罐区', key: 'top-tank-area' },
|
|
|
|
|
|
{ title: '拱顶罐区', key: 'dome-top-tank' },
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '常规罐区',
|
|
|
|
|
|
key: 'normal-tank',
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{ title: '浮顶罐区', key: 'floating-top-tank' },
|
|
|
|
|
|
{ title: '拱顶罐区', key: 'normal-dome-tank' },
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '泵房',
|
|
|
|
|
|
key: 'pump-house',
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '运行中泵房',
|
|
|
|
|
|
key: 'running-pump',
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{ title: '1#泵房', key: 'pump-1' },
|
|
|
|
|
|
{ title: '2#泵房', key: 'pump-2' },
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{ title: '备用泵房', key: 'spare-pump' },
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '3#泵房',
|
|
|
|
|
|
key: 'pump-3',
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{ title: '4#泵房', key: 'pump-4' },
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
{ title: '智能网格', key: 'smart-grid' },
|
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={{ backgroundColor: '#fff', padding: '20px', minHeight: '631px', borderRadius: '10px' }}>
|
|
|
|
|
|
<Row gutter={[16, 16]}>
|
|
|
|
|
|
{/* 左侧树形结构 */}
|
|
|
|
|
|
<Col span={6}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
backgroundColor: '#E7F2ED',
|
|
|
|
|
|
borderRadius: '10px',
|
|
|
|
|
|
padding: '15px',
|
|
|
|
|
|
height: '100%',
|
|
|
|
|
|
border: '1px solid rgba(0, 102, 101, 0.2)'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
fontSize: '16px',
|
|
|
|
|
|
fontWeight: 'bold',
|
|
|
|
|
|
color: '#006665',
|
|
|
|
|
|
marginBottom: '15px',
|
|
|
|
|
|
paddingBottom: '10px',
|
|
|
|
|
|
borderBottom: '2px solid #006665'
|
|
|
|
|
|
}}>| 巡检范围</div>
|
|
|
|
|
|
<Tree
|
|
|
|
|
|
className={styles['tree']}
|
|
|
|
|
|
defaultExpandAll
|
|
|
|
|
|
treeData={treeData}
|
|
|
|
|
|
checkable
|
|
|
|
|
|
style={{ fontSize: '14px', color: '#006665' }}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
{/* 右侧背景图和内容 */}
|
|
|
|
|
|
<Col span={18}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
position: 'relative',
|
|
|
|
|
|
height: '631px',
|
|
|
|
|
|
borderRadius: '10px',
|
|
|
|
|
|
overflow: 'hidden',
|
|
|
|
|
|
border: '1px solid rgba(0, 102, 101, 0.2)'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
{/* 背景图 */}
|
|
|
|
|
|
<img
|
|
|
|
|
|
src={inspectionBg}
|
|
|
|
|
|
alt="智能巡检范围监控"
|
|
|
|
|
|
style={{
|
|
|
|
|
|
width: '100%',
|
|
|
|
|
|
height: '100%',
|
|
|
|
|
|
objectFit: 'cover'
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 区域基础信息框 */}
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
|
top: '20%',
|
|
|
|
|
|
left: '30%',
|
|
|
|
|
|
backgroundColor: 'rgba(255, 255, 255, 0.9)',
|
|
|
|
|
|
padding: '15px',
|
|
|
|
|
|
borderRadius: '8px',
|
|
|
|
|
|
border: '1px solid #006665',
|
|
|
|
|
|
width: '200px'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<div style={{ fontSize: '14px', fontWeight: 'bold', color: '#006665', marginBottom: '8px' }}>区域基础信息</div>
|
|
|
|
|
|
<div style={{ fontSize: '12px', color: '#333', lineHeight: '1.5' }}>
|
|
|
|
|
|
<div>区域名称:高危罐区 - 3#-9#罐组</div>
|
|
|
|
|
|
<div>区域编号:第2节点 (指挥中心→高危罐区)</div>
|
|
|
|
|
|
<div>巡检状态:正在巡检</div>
|
|
|
|
|
|
<div>完成进度:设备4/30台</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 巡检覆盖清单框 */}
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
|
top: '10%',
|
|
|
|
|
|
right: '10%',
|
|
|
|
|
|
backgroundColor: 'rgba(255, 255, 255, 0.9)',
|
|
|
|
|
|
padding: '15px',
|
|
|
|
|
|
borderRadius: '8px',
|
|
|
|
|
|
border: '1px solid #006665',
|
|
|
|
|
|
width: '220px'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<div style={{ fontSize: '14px', fontWeight: 'bold', color: '#006665', marginBottom: '8px' }}>巡检覆盖清单</div>
|
|
|
|
|
|
<div style={{ fontSize: '12px', color: '#333', lineHeight: '1.5' }}>
|
|
|
|
|
|
<div style={{ fontWeight: 'bold', marginBottom: '5px' }}>覆盖主体</div>
|
|
|
|
|
|
<div>重点设备:储罐×8、3#-9#罐组、罐前付转装置</div>
|
|
|
|
|
|
<div>检测方式:红外检测、视觉识别</div>
|
|
|
|
|
|
<div>环境监控:声噪、消防水池监测</div>
|
|
|
|
|
|
<div>管控单位:3#罐区特种管控部门</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 机器人图标 */}
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
|
bottom: '20%',
|
|
|
|
|
|
right: '25%',
|
|
|
|
|
|
textAlign: 'center'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<div style={{ fontSize: '48px', color: '#006665', marginBottom: '5px' }}>🤖</div>
|
|
|
|
|
|
<div style={{ backgroundColor: 'rgba(0, 102, 101, 0.8)', color: 'white', padding: '5px 10px', borderRadius: '15px', fontSize: '12px' }}>机器人实时位置</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 绿色圆点标记 */}
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
|
bottom: '35%',
|
|
|
|
|
|
left: '45%',
|
|
|
|
|
|
textAlign: 'center'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
width: '20px',
|
|
|
|
|
|
height: '20px',
|
|
|
|
|
|
borderRadius: '50%',
|
|
|
|
|
|
backgroundColor: 'green',
|
|
|
|
|
|
border: '2px solid white',
|
|
|
|
|
|
boxShadow: '0 0 10px green',
|
|
|
|
|
|
margin: '0 auto 5px'
|
|
|
|
|
|
}}></div>
|
|
|
|
|
|
<div style={{ backgroundColor: 'rgba(0, 128, 0, 0.8)', color: 'white', padding: '3px 8px', borderRadius: '15px', fontSize: '11px' }}>高危罐区</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
|
bottom: '30%',
|
|
|
|
|
|
right: '15%',
|
|
|
|
|
|
textAlign: 'center'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
width: '20px',
|
|
|
|
|
|
height: '20px',
|
|
|
|
|
|
borderRadius: '50%',
|
|
|
|
|
|
backgroundColor: 'green',
|
|
|
|
|
|
border: '2px solid white',
|
|
|
|
|
|
boxShadow: '0 0 10px green',
|
|
|
|
|
|
margin: '0 auto 5px'
|
|
|
|
|
|
}}></div>
|
|
|
|
|
|
<div style={{ backgroundColor: 'rgba(0, 128, 0, 0.8)', color: 'white', padding: '3px 8px', borderRadius: '15px', fontSize: '11px' }}>常规罐区</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 智能巡检内容监控中心组件
|
|
|
|
|
|
const SmartInspectionContent = () => {
|
|
|
|
|
|
const [activeTab, setActiveTab] = useState('温度异常检测');
|
|
|
|
|
|
const [currentPage, setCurrentPage] = useState(6);
|
|
|
|
|
|
|
|
|
|
|
|
const handleTabClick = (tab) => {
|
|
|
|
|
|
setActiveTab(tab);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const handlePageChange = (page) => {
|
|
|
|
|
|
setCurrentPage(page);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
const renderContent = () => {
|
|
|
|
|
|
switch (activeTab) {
|
|
|
|
|
|
case '温度异常检测':
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={{ padding: 20 }}>
|
|
|
|
|
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}>
|
|
|
|
|
|
<h2 style={{ margin: 0, color: '#1890ff' }}>实时监测区</h2>
|
|
|
|
|
|
{/* <div style={{ display: 'flex', gap: 10 }}>
|
|
|
|
|
|
<button style={{
|
|
|
|
|
|
backgroundColor: '#52c41a',
|
|
|
|
|
|
color: 'white',
|
|
|
|
|
|
border: 'none',
|
|
|
|
|
|
padding: '8px 16px',
|
|
|
|
|
|
borderRadius: 4,
|
|
|
|
|
|
cursor: 'pointer',
|
|
|
|
|
|
fontWeight: 'bold'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
实时刷新
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button style={{
|
|
|
|
|
|
backgroundColor: '#1890ff',
|
|
|
|
|
|
color: 'white',
|
|
|
|
|
|
border: 'none',
|
|
|
|
|
|
padding: '8px 16px',
|
|
|
|
|
|
borderRadius: 4,
|
|
|
|
|
|
cursor: 'pointer'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
导出检测报告
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button style={{
|
|
|
|
|
|
backgroundColor: '#722ed1',
|
|
|
|
|
|
color: 'white',
|
|
|
|
|
|
border: 'none',
|
|
|
|
|
|
padding: '8px 16px',
|
|
|
|
|
|
borderRadius: 4,
|
|
|
|
|
|
cursor: 'pointer'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
报警设置
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div> */}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div style={{ display: 'flex', gap: 20 }}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
border: '1px solid #f0f0f0',
|
|
|
|
|
|
borderRadius: 8,
|
|
|
|
|
|
padding: 16,
|
|
|
|
|
|
width: '35%',
|
|
|
|
|
|
backgroundColor: '#fafafa'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<div style={{ position: 'relative' }}>
|
|
|
|
|
|
<img
|
|
|
|
|
|
src={thermalImage}
|
|
|
|
|
|
alt="红外热成像图"
|
|
|
|
|
|
style={{ width: '100%', height: 'auto', borderRadius: 4 }}
|
|
|
|
|
|
/>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
|
top: 10,
|
|
|
|
|
|
right: 10,
|
|
|
|
|
|
backgroundColor: 'rgba(0,0,0,0.7)',
|
|
|
|
|
|
color: 'white',
|
|
|
|
|
|
padding: '4px 8px',
|
|
|
|
|
|
borderRadius: 4,
|
|
|
|
|
|
fontSize: 12
|
|
|
|
|
|
}}>
|
|
|
|
|
|
当前最高温: 89°C
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div style={{ marginTop: 12 }}>
|
|
|
|
|
|
<p style={{ margin: '8px 0', fontSize: 14 }}>实时温度: <span style={{ color: '#ff4d4f', fontWeight: 'bold' }}>89°C</span></p>
|
|
|
|
|
|
<p style={{ margin: '8px 0', fontSize: 14 }}>高温异常: <span style={{ color: '#ff4d4f', fontWeight: 'bold' }}>80°C</span></p>
|
|
|
|
|
|
<p style={{ margin: '8px 0', fontSize: 14, color: '#666' }}>当前监测区域: 罐区管道连接处检测</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div style={{ width: '65%', padding: 16 }}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
border: '1px solid #f0f0f0',
|
|
|
|
|
|
borderRadius: 8,
|
|
|
|
|
|
padding: 16,
|
|
|
|
|
|
marginBottom: 20,
|
|
|
|
|
|
backgroundColor: '#fafafa'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<h3 style={{ margin: '0 0 12px 0', fontSize: 16 }}>检测原理说明</h3>
|
|
|
|
|
|
<p style={{
|
|
|
|
|
|
margin: 0,
|
|
|
|
|
|
lineHeight: 1.6,
|
|
|
|
|
|
color: '#333',
|
|
|
|
|
|
backgroundColor: 'white',
|
|
|
|
|
|
padding: 12,
|
|
|
|
|
|
borderRadius: 4,
|
|
|
|
|
|
border: '1px solid #e8e8e8'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
"搭载红外热成像测温仪,覆盖电缆、胶管、设备高温点;温度达到阈值时自动上报故障,同步录制热成像/可见光视频,为故障分析提供数据支撑。"
|
|
|
|
|
|
</p>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
border: '1px solid #f0f0f0',
|
|
|
|
|
|
borderRadius: 8,
|
|
|
|
|
|
padding: 16,
|
|
|
|
|
|
backgroundColor: '#fafafa'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<h3 style={{ margin: '0 0 12px 0', fontSize: 16 }}>异常历史记录</h3>
|
|
|
|
|
|
<div style={{ overflowX: 'auto' }}>
|
|
|
|
|
|
<table style={{ width: '100%', borderCollapse: 'collapse', backgroundColor: 'white' }}>
|
|
|
|
|
|
<thead>
|
|
|
|
|
|
<tr style={{ backgroundColor: '#fafafa' }}>
|
|
|
|
|
|
<th style={{ padding: '10px', border: '1px solid #e8e8e8', textAlign: 'left' }}>序号</th>
|
|
|
|
|
|
<th style={{ padding: '10px', border: '1px solid #e8e8e8', textAlign: 'left' }}>故障时间</th>
|
|
|
|
|
|
<th style={{ padding: '10px', border: '1px solid #e8e8e8', textAlign: 'left' }}>检测区域</th>
|
|
|
|
|
|
<th style={{ padding: '10px', border: '1px solid #e8e8e8', textAlign: 'left' }}>异常温度</th>
|
|
|
|
|
|
<th style={{ padding: '10px', border: '1px solid #e8e8e8', textAlign: 'left' }}>处理状态</th>
|
|
|
|
|
|
<th style={{ padding: '10px', border: '1px solid #e8e8e8', textAlign: 'left' }}>操作</th>
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
</thead>
|
|
|
|
|
|
<tbody>
|
|
|
|
|
|
<tr>
|
|
|
|
|
|
<td style={{ padding: '10px', border: '1px solid #e8e8e8' }}>1</td>
|
|
|
|
|
|
<td style={{ padding: '10px', border: '1px solid #e8e8e8' }}>2025-10-16 14:20</td>
|
|
|
|
|
|
<td style={{ padding: '10px', border: '1px solid #e8e8e8' }}>1# 泵房电机</td>
|
|
|
|
|
|
<td style={{ padding: '10px', border: '1px solid #e8e8e8' }}>92°C</td>
|
|
|
|
|
|
<td style={{ padding: '10px', border: '1px solid #e8e8e8' }}>已处理</td>
|
|
|
|
|
|
<td style={{ padding: '10px', border: '1px solid #e8e8e8' }}>
|
|
|
|
|
|
<button style={{
|
|
|
|
|
|
color: '#1890ff',
|
|
|
|
|
|
border: 'none',
|
|
|
|
|
|
backgroundColor: 'transparent',
|
|
|
|
|
|
cursor: 'pointer',
|
|
|
|
|
|
textDecoration: 'underline'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
查看详情
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</td>
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
<tr>
|
|
|
|
|
|
<td style={{ padding: '10px', border: '1px solid #e8e8e8' }}>2</td>
|
|
|
|
|
|
<td style={{ padding: '10px', border: '1px solid #e8e8e8' }}>2025-10-16 14:20</td>
|
|
|
|
|
|
<td style={{ padding: '10px', border: '1px solid #e8e8e8' }}>1# 泵房电机</td>
|
|
|
|
|
|
<td style={{ padding: '10px', border: '1px solid #e8e8e8' }}>92°C</td>
|
|
|
|
|
|
<td style={{ padding: '10px', border: '1px solid #e8e8e8' }}>已处理</td>
|
|
|
|
|
|
<td style={{ padding: '10px', border: '1px solid #e8e8e8' }}>
|
|
|
|
|
|
<button style={{
|
|
|
|
|
|
color: '#1890ff',
|
|
|
|
|
|
border: 'none',
|
|
|
|
|
|
backgroundColor: 'transparent',
|
|
|
|
|
|
cursor: 'pointer',
|
|
|
|
|
|
textDecoration: 'underline'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
查看详情
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</td>
|
|
|
|
|
|
</tr>
|
|
|
|
|
|
</tbody>
|
|
|
|
|
|
</table>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginTop: 16 }}>
|
|
|
|
|
|
<span style={{ fontSize: 14, color: '#666' }}>共 85 条</span>
|
|
|
|
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
|
|
|
|
|
<span style={{ fontSize: 14 }}>10 / page</span>
|
|
|
|
|
|
<button style={{
|
|
|
|
|
|
padding: '4px 8px',
|
|
|
|
|
|
border: '1px solid #d9d9d9',
|
|
|
|
|
|
backgroundColor: 'white',
|
|
|
|
|
|
cursor: 'pointer'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
‹
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button style={{
|
|
|
|
|
|
padding: '4px 8px',
|
|
|
|
|
|
border: '1px solid #d9d9d9',
|
|
|
|
|
|
backgroundColor: 'white',
|
|
|
|
|
|
cursor: 'pointer'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
1
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<span>...</span>
|
|
|
|
|
|
<button style={{
|
|
|
|
|
|
padding: '4px 8px',
|
|
|
|
|
|
border: '1px solid #d9d9d9',
|
|
|
|
|
|
backgroundColor: 'white',
|
|
|
|
|
|
cursor: 'pointer'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
4
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button style={{
|
|
|
|
|
|
padding: '4px 8px',
|
|
|
|
|
|
border: '1px solid #d9d9d9',
|
|
|
|
|
|
backgroundColor: 'white',
|
|
|
|
|
|
cursor: 'pointer'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
5
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button style={{
|
|
|
|
|
|
padding: '4px 8px',
|
|
|
|
|
|
border: '1px solid #1890ff',
|
|
|
|
|
|
backgroundColor: '#1890ff',
|
|
|
|
|
|
color: 'white',
|
|
|
|
|
|
cursor: 'pointer'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
6
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button style={{
|
|
|
|
|
|
padding: '4px 8px',
|
|
|
|
|
|
border: '1px solid #d9d9d9',
|
|
|
|
|
|
backgroundColor: 'white',
|
|
|
|
|
|
cursor: 'pointer'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
7
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button style={{
|
|
|
|
|
|
padding: '4px 8px',
|
|
|
|
|
|
border: '1px solid #d9d9d9',
|
|
|
|
|
|
backgroundColor: 'white',
|
|
|
|
|
|
cursor: 'pointer'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
8
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<span>...</span>
|
|
|
|
|
|
<button style={{
|
|
|
|
|
|
padding: '4px 8px',
|
|
|
|
|
|
border: '1px solid #d9d9d9',
|
|
|
|
|
|
backgroundColor: 'white',
|
|
|
|
|
|
cursor: 'pointer'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
50
|
|
|
|
|
|
</button>
|
|
|
|
|
|
<button style={{
|
|
|
|
|
|
padding: '4px 8px',
|
|
|
|
|
|
border: '1px solid #d9d9d9',
|
|
|
|
|
|
backgroundColor: 'white',
|
|
|
|
|
|
cursor: 'pointer'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
›
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
case '温湿度检测':
|
|
|
|
|
|
// 创建一个React兼容的ECharts组件
|
|
|
|
|
|
const EChartsGauge = ({ id, option, height, width }) => {
|
|
|
|
|
|
const chartRef = useRef(null);
|
|
|
|
|
|
const chartInstanceRef = useRef(null);
|
|
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
|
// 确保在浏览器环境中运行
|
|
|
|
|
|
if (typeof window !== 'undefined' && chartRef.current) {
|
|
|
|
|
|
const echarts = require('echarts');
|
|
|
|
|
|
|
|
|
|
|
|
// 初始化图表
|
|
|
|
|
|
if (!chartInstanceRef.current) {
|
|
|
|
|
|
chartInstanceRef.current = echarts.init(chartRef.current);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 设置配置
|
|
|
|
|
|
chartInstanceRef.current.setOption(option);
|
|
|
|
|
|
|
|
|
|
|
|
// 响应窗口大小变化
|
|
|
|
|
|
const handleResize = () => {
|
|
|
|
|
|
if (chartInstanceRef.current) {
|
|
|
|
|
|
chartInstanceRef.current.resize();
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
window.addEventListener('resize', handleResize);
|
|
|
|
|
|
|
|
|
|
|
|
// 清理函数
|
|
|
|
|
|
return () => {
|
|
|
|
|
|
window.removeEventListener('resize', handleResize);
|
|
|
|
|
|
if (chartInstanceRef.current) {
|
|
|
|
|
|
chartInstanceRef.current.dispose();
|
|
|
|
|
|
chartInstanceRef.current = null;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
}, [option]);
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div
|
|
|
|
|
|
ref={chartRef}
|
|
|
|
|
|
id={id}
|
|
|
|
|
|
style={{ width, height }}
|
|
|
|
|
|
/>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 温度仪表盘配置
|
|
|
|
|
|
const temperatureOption = {
|
|
|
|
|
|
series: [
|
|
|
|
|
|
{
|
|
|
|
|
|
type: 'gauge',
|
|
|
|
|
|
startAngle: 180,
|
|
|
|
|
|
endAngle: 0,
|
|
|
|
|
|
min: 0,
|
|
|
|
|
|
max: 100,
|
|
|
|
|
|
splitNumber: 10,
|
|
|
|
|
|
itemStyle: {
|
|
|
|
|
|
color: 'rgba(4, 95, 94, 0.5)',
|
|
|
|
|
|
shadowColor: 'rgba(4, 95, 94, 0.7)',
|
|
|
|
|
|
shadowBlur: 10,
|
|
|
|
|
|
shadowOffsetX: 2,
|
|
|
|
|
|
shadowOffsetY: 2
|
|
|
|
|
|
},
|
|
|
|
|
|
progress: {
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
roundCap: true,
|
|
|
|
|
|
width: 18,
|
|
|
|
|
|
itemStyle: {
|
|
|
|
|
|
color: 'rgba(4, 95, 94, 0.5)'
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
pointer: {
|
|
|
|
|
|
icon: 'path://M2090.36389,615.30999 L2090.36389,615.30999 C2091.48372,615.30999 2092.40383,616.194028 2092.44859,617.312956 L2096.90698,728.755929 C2097.05155,732.369577 2094.2393,735.416212 2090.62566,735.56078 C2090.53845,735.564269 2090.45117,735.566014 2090.36389,735.566014 L2090.36389,735.566014 C2086.74736,735.566014 2083.81557,732.63423 2083.81557,729.017692 C2083.81557,728.930412 2083.81732,728.84314 2083.82081,728.755929 L2088.2792,617.312956 C2088.32396,616.194028 2089.24407,615.30999 2090.36389,615.30999 Z',
|
|
|
|
|
|
length: '75%',
|
|
|
|
|
|
width: 16,
|
|
|
|
|
|
offsetCenter: [0, '5%'],
|
|
|
|
|
|
itemStyle: {
|
|
|
|
|
|
color: 'rgba(4, 95, 94, 1)'
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
axisLine: {
|
|
|
|
|
|
roundCap: true,
|
|
|
|
|
|
lineStyle: {
|
|
|
|
|
|
width: 18,
|
|
|
|
|
|
color: [
|
|
|
|
|
|
[1, 'rgba(4, 95, 94, 0.5)']
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
axisTick: {
|
|
|
|
|
|
splitNumber: 2,
|
|
|
|
|
|
lineStyle: {
|
|
|
|
|
|
width: 2,
|
|
|
|
|
|
color: '#999'
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
splitLine: {
|
|
|
|
|
|
length: 12,
|
|
|
|
|
|
lineStyle: {
|
|
|
|
|
|
width: 3,
|
|
|
|
|
|
color: 'rgba(4, 95, 94, 0.8)'
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
axisLabel: {
|
|
|
|
|
|
distance: 30,
|
|
|
|
|
|
color: 'rgba(4, 95, 94, 0.8)',
|
|
|
|
|
|
fontSize: 20
|
|
|
|
|
|
},
|
|
|
|
|
|
title: {
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
offsetCenter: [0, '10%'],
|
|
|
|
|
|
fontSize: 18,
|
|
|
|
|
|
color: 'rgba(4, 95, 94, 0.8)'
|
|
|
|
|
|
},
|
|
|
|
|
|
detail: {
|
|
|
|
|
|
backgroundColor: 'rgba(4, 95, 94, 0.2)',
|
|
|
|
|
|
borderColor: 'rgba(4, 95, 94, 0.5)',
|
|
|
|
|
|
borderWidth: 2,
|
|
|
|
|
|
width: '60%',
|
|
|
|
|
|
lineHeight: 40,
|
|
|
|
|
|
height: 40,
|
|
|
|
|
|
borderRadius: 8,
|
|
|
|
|
|
offsetCenter: [0, '35%'],
|
|
|
|
|
|
valueAnimation: true,
|
|
|
|
|
|
formatter: function (value) {
|
|
|
|
|
|
return '{value|' + value.toFixed(0) + '}{unit|°C}';
|
|
|
|
|
|
},
|
|
|
|
|
|
rich: {
|
|
|
|
|
|
value: {
|
|
|
|
|
|
fontSize: 20,
|
|
|
|
|
|
fontWeight: 'bolder',
|
|
|
|
|
|
color: 'rgba(4, 95, 94, 1)'
|
|
|
|
|
|
},
|
|
|
|
|
|
unit: {
|
|
|
|
|
|
fontSize: 20,
|
|
|
|
|
|
color: 'rgba(4, 95, 94, 0.8)',
|
|
|
|
|
|
padding: [0, 0, -20, 10]
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
data: [
|
|
|
|
|
|
{
|
|
|
|
|
|
value: 28,
|
|
|
|
|
|
name: '温度'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 湿度仪表盘配置
|
|
|
|
|
|
const humidityOption = {
|
|
|
|
|
|
series: [
|
|
|
|
|
|
{
|
|
|
|
|
|
type: 'gauge',
|
|
|
|
|
|
startAngle: 180,
|
|
|
|
|
|
endAngle: 0,
|
|
|
|
|
|
min: 0,
|
|
|
|
|
|
max: 100,
|
|
|
|
|
|
splitNumber: 10,
|
|
|
|
|
|
itemStyle: {
|
|
|
|
|
|
color: 'rgba(4, 95, 94, 0.5)',
|
|
|
|
|
|
shadowColor: 'rgba(4, 95, 94, 0.7)',
|
|
|
|
|
|
shadowBlur: 10,
|
|
|
|
|
|
shadowOffsetX: 2,
|
|
|
|
|
|
shadowOffsetY: 2
|
|
|
|
|
|
},
|
|
|
|
|
|
progress: {
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
roundCap: true,
|
|
|
|
|
|
width: 18,
|
|
|
|
|
|
itemStyle: {
|
|
|
|
|
|
color: 'rgba(4, 95, 94, 0.5)'
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
pointer: {
|
|
|
|
|
|
icon: 'path://M2090.36389,615.30999 L2090.36389,615.30999 C2091.48372,615.30999 2092.40383,616.194028 2092.44859,617.312956 L2096.90698,728.755929 C2097.05155,732.369577 2094.2393,735.416212 2090.62566,735.56078 C2090.53845,735.564269 2090.45117,735.566014 2090.36389,735.566014 L2090.36389,735.566014 C2086.74736,735.566014 2083.81557,732.63423 2083.81557,729.017692 C2083.81557,728.930412 2083.81732,728.84314 2083.82081,728.755929 L2088.2792,617.312956 C2088.32396,616.194028 2089.24407,615.30999 2090.36389,615.30999 Z',
|
|
|
|
|
|
length: '75%',
|
|
|
|
|
|
width: 16,
|
|
|
|
|
|
offsetCenter: [0, '5%'],
|
|
|
|
|
|
itemStyle: {
|
|
|
|
|
|
color: 'rgba(4, 95, 94, 1)'
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
axisLine: {
|
|
|
|
|
|
roundCap: true,
|
|
|
|
|
|
lineStyle: {
|
|
|
|
|
|
width: 18,
|
|
|
|
|
|
color: [
|
|
|
|
|
|
[1, 'rgba(4, 95, 94, 0.5)']
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
axisTick: {
|
|
|
|
|
|
splitNumber: 2,
|
|
|
|
|
|
lineStyle: {
|
|
|
|
|
|
width: 2,
|
|
|
|
|
|
color: '#999'
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
splitLine: {
|
|
|
|
|
|
length: 12,
|
|
|
|
|
|
lineStyle: {
|
|
|
|
|
|
width: 3,
|
|
|
|
|
|
color: 'rgba(4, 95, 94, 0.8)'
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
axisLabel: {
|
|
|
|
|
|
distance: 30,
|
|
|
|
|
|
color: 'rgba(4, 95, 94, 0.8)',
|
|
|
|
|
|
fontSize: 20
|
|
|
|
|
|
},
|
|
|
|
|
|
title: {
|
|
|
|
|
|
show: true,
|
|
|
|
|
|
offsetCenter: [0, '10%'],
|
|
|
|
|
|
fontSize: 18,
|
|
|
|
|
|
color: 'rgba(4, 95, 94, 0.8)'
|
|
|
|
|
|
},
|
|
|
|
|
|
detail: {
|
|
|
|
|
|
backgroundColor: 'rgba(4, 95, 94, 0.2)',
|
|
|
|
|
|
borderColor: 'rgba(4, 95, 94, 0.5)',
|
|
|
|
|
|
borderWidth: 2,
|
|
|
|
|
|
width: '60%',
|
|
|
|
|
|
lineHeight: 40,
|
|
|
|
|
|
height: 40,
|
|
|
|
|
|
borderRadius: 8,
|
|
|
|
|
|
offsetCenter: [0, '35%'],
|
|
|
|
|
|
valueAnimation: true,
|
|
|
|
|
|
formatter: function (value) {
|
|
|
|
|
|
return '{value|' + value.toFixed(0) + '}{unit|%}';
|
|
|
|
|
|
},
|
|
|
|
|
|
rich: {
|
|
|
|
|
|
value: {
|
|
|
|
|
|
fontSize: 20,
|
|
|
|
|
|
fontWeight: 'bolder',
|
|
|
|
|
|
color: 'rgba(4, 95, 94, 1)'
|
|
|
|
|
|
},
|
|
|
|
|
|
unit: {
|
|
|
|
|
|
fontSize: 20,
|
|
|
|
|
|
color: 'rgba(4, 95, 94, 0.8)',
|
|
|
|
|
|
padding: [0, 0, -20, 10]
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
},
|
|
|
|
|
|
data: [
|
|
|
|
|
|
{
|
|
|
|
|
|
value: 55,
|
|
|
|
|
|
name: '湿度'
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
}
|
|
|
|
|
|
]
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={{ padding: 20 }}>
|
|
|
|
|
|
<div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: 20 }}>
|
|
|
|
|
|
<h2 style={{ margin: 0, color: 'black' }}>| 温湿度检测</h2>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div style={{ display: 'flex', gap: 20 }}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
// border: '1px solid #f0f0f0',
|
|
|
|
|
|
// borderRadius: 8,
|
|
|
|
|
|
// padding: 16,
|
|
|
|
|
|
width: '40%',
|
|
|
|
|
|
// backgroundColor: '#fafafa'
|
|
|
|
|
|
gap: 20
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<div className={styles.dashboardContainer} style={{ width: '100%', height: 700 }}>
|
|
|
|
|
|
<h3 style={{ margin: '16px', fontSize: 16 }}>实时仪表盘</h3>
|
|
|
|
|
|
{/* 温度仪表盘 - 使用React兼容的ECharts组件 */}
|
|
|
|
|
|
<div style={{ marginBottom: 0 }}>
|
|
|
|
|
|
<EChartsGauge id="temperatureGauge" option={temperatureOption} width={450} height={350} />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 湿度仪表盘 - 使用React兼容的ECharts组件 */}
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<EChartsGauge id="humidityGauge" option={humidityOption} width={450} height={350} />
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div className={styles.thresholdConfigContainer} style={{ marginTop: 20, padding: 16 }}>
|
|
|
|
|
|
<h3 style={{ margin: '0 0 16px 0', fontSize: 16 }}>阈值配置区</h3>
|
|
|
|
|
|
<Button className={styles['resetBtn']} style={{ backgroundImage: `url(${btnImg3})`, margin: '0 0px', width: 120 }}>保存配置</Button>
|
|
|
|
|
|
<div style={{ backgroundColor: 'white', padding: 16, borderRadius: 4 }}>
|
|
|
|
|
|
<div style={{ marginBottom: 12 }}>
|
|
|
|
|
|
<label style={{ display: 'inline-block', width: 120, fontSize: 14 }}>低温预警阈值:</label>
|
|
|
|
|
|
<input
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
value="5°C"
|
|
|
|
|
|
style={{
|
|
|
|
|
|
padding: '4px 8px',
|
|
|
|
|
|
border: '1px solid #d9d9d9',
|
|
|
|
|
|
borderRadius: 4,
|
|
|
|
|
|
width: 120
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div style={{ marginBottom: 12 }}>
|
|
|
|
|
|
<label style={{ display: 'inline-block', width: 120, fontSize: 14 }}>高温预警阈值:</label>
|
|
|
|
|
|
<input
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
value="30°C"
|
|
|
|
|
|
style={{
|
|
|
|
|
|
padding: '4px 8px',
|
|
|
|
|
|
border: '1px solid #d9d9d9',
|
|
|
|
|
|
borderRadius: 4,
|
|
|
|
|
|
width: 120
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div style={{ marginBottom: 12 }}>
|
|
|
|
|
|
<label style={{ display: 'inline-block', width: 120, fontSize: 14 }}>湿度预警阈值:</label>
|
|
|
|
|
|
<input
|
|
|
|
|
|
type="text"
|
|
|
|
|
|
value="90%RH"
|
|
|
|
|
|
style={{
|
|
|
|
|
|
padding: '4px 8px',
|
|
|
|
|
|
border: '1px solid #d9d9d9',
|
|
|
|
|
|
borderRadius: 4,
|
|
|
|
|
|
width: 120
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div className={styles.chartContainer} style={{ width: '65%' }}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
border: '1px solid #f0f0f0',
|
|
|
|
|
|
borderRadius: 8,
|
|
|
|
|
|
padding: 16,
|
|
|
|
|
|
backgroundColor: '#fafafa',
|
|
|
|
|
|
height: '100%'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<h3 style={{ margin: '0 0 16px 0', fontSize: 16 }}>历史趋势图</h3>
|
|
|
|
|
|
<div style={{ backgroundColor: 'white', padding: 16, borderRadius: 4 }}>
|
|
|
|
|
|
<div style={{ display: 'flex', gap: 20, marginBottom: 16 }}>
|
|
|
|
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
|
|
|
|
|
<span style={{ display: 'inline-block', width: 16, height: 3, backgroundColor: '#1890ff' }}></span>
|
|
|
|
|
|
<span style={{ fontSize: 14, color: '#333' }}>温度(°C)</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
|
|
|
|
|
|
<span style={{ display: 'inline-block', width: 16, height: 3, backgroundColor: '#52c41a' }}></span>
|
|
|
|
|
|
<span style={{ fontSize: 14, color: '#333' }}>湿度(%RH)</span>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div style={{ height: 400, position: 'relative' }}>
|
|
|
|
|
|
{/* 模拟趋势图 */}
|
|
|
|
|
|
<svg width="100%" height="100%" viewBox="0 0 800 400">
|
|
|
|
|
|
{/* 网格线 */}
|
|
|
|
|
|
{[0, 25, 50, 75, 100].map((val, index) => (
|
|
|
|
|
|
<g key={index}>
|
|
|
|
|
|
<line
|
|
|
|
|
|
x1="50"
|
|
|
|
|
|
y1={400 - val * 4}
|
|
|
|
|
|
x2="750"
|
|
|
|
|
|
y2={400 - val * 4}
|
|
|
|
|
|
stroke="#f0f0f0"
|
|
|
|
|
|
strokeWidth="1"
|
|
|
|
|
|
/>
|
|
|
|
|
|
<text x="30" y={400 - val * 4 + 5} fontSize="12" fill="#666" textAnchor="end">
|
|
|
|
|
|
{val}
|
|
|
|
|
|
</text>
|
|
|
|
|
|
</g>
|
|
|
|
|
|
))}
|
|
|
|
|
|
{/* 时间标签 */}
|
|
|
|
|
|
{['00:00', '03:00', '06:00', '09:00', '12:00', '15:00', '18:00', '21:00', '24:00'].map((time, index) => (
|
|
|
|
|
|
<text
|
|
|
|
|
|
key={index}
|
|
|
|
|
|
x={50 + index * 90}
|
|
|
|
|
|
y={390}
|
|
|
|
|
|
fontSize="12"
|
|
|
|
|
|
fill="#666"
|
|
|
|
|
|
textAnchor="middle"
|
|
|
|
|
|
>
|
|
|
|
|
|
{time}
|
|
|
|
|
|
</text>
|
|
|
|
|
|
))}
|
|
|
|
|
|
{/* 温度曲线 */}
|
|
|
|
|
|
<path
|
|
|
|
|
|
d="M50,200 L140,160 L230,180 L320,120 L410,160 L500,140 L590,120 L680,140 L750,100"
|
|
|
|
|
|
stroke="#1890ff"
|
|
|
|
|
|
strokeWidth="2"
|
|
|
|
|
|
fill="none"
|
|
|
|
|
|
/>
|
|
|
|
|
|
{/* 温度数据点 */}
|
|
|
|
|
|
{[50, 140, 230, 320, 410, 500, 590, 680, 750].map((x, index) => (
|
|
|
|
|
|
<circle
|
|
|
|
|
|
key={`temp-${index}`}
|
|
|
|
|
|
cx={x}
|
|
|
|
|
|
cy={[200, 160, 180, 120, 160, 140, 120, 140, 100][index]}
|
|
|
|
|
|
r="4"
|
|
|
|
|
|
fill="#1890ff"
|
|
|
|
|
|
/>
|
|
|
|
|
|
))}
|
|
|
|
|
|
{/* 湿度曲线 */}
|
|
|
|
|
|
<path
|
|
|
|
|
|
d="M50,100 L140,140 L230,120 L320,160 L410,150 L500,180 L590,170 L680,140 L750,130"
|
|
|
|
|
|
stroke="#52c41a"
|
|
|
|
|
|
strokeWidth="2"
|
|
|
|
|
|
fill="none"
|
|
|
|
|
|
/>
|
|
|
|
|
|
{/* 湿度数据点 */}
|
|
|
|
|
|
{[50, 140, 230, 320, 410, 500, 590, 680, 750].map((x, index) => (
|
|
|
|
|
|
<circle
|
|
|
|
|
|
key={`humi-${index}`}
|
|
|
|
|
|
cx={x}
|
|
|
|
|
|
cy={[100, 140, 120, 160, 150, 180, 170, 140, 130][index]}
|
|
|
|
|
|
r="4"
|
|
|
|
|
|
fill="#52c41a"
|
|
|
|
|
|
/>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</svg>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div >
|
|
|
|
|
|
);
|
|
|
|
|
|
case '跑冒滴漏检测':
|
|
|
|
|
|
case '仪器仪表采集':
|
|
|
|
|
|
case '环境监测':
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={{ padding: 40, textAlign: 'center', color: '#666' }}>
|
|
|
|
|
|
<h3>该模块正在开发中...</h3>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
default:
|
|
|
|
|
|
return null;
|
|
|
|
|
|
}
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={{ minHeight: '98vh', backgroundColor: '#fff', borderRadius: 10 }}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
display: 'flex',
|
|
|
|
|
|
justifyContent: 'space-between',
|
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
|
backgroundColor: '#fff',
|
|
|
|
|
|
padding: '16px 24px',
|
|
|
|
|
|
color: 'black',
|
|
|
|
|
|
fontWeight: '400',
|
|
|
|
|
|
fontSize: 18
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
| 智能巡检内容监控中心
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<Button className={styles['addBtn']} style={{ backgroundImage: `url(${btnImg1})`, }}>实时刷新</Button>
|
|
|
|
|
|
<Button className={styles['resetBtn']} style={{ backgroundImage: `url(${btnImg3})`, margin: '0 20px', width: 120 }}>导出巡检报告</Button>
|
|
|
|
|
|
<Button className={styles['delBtn']} style={{ backgroundImage: `url(${btnImg2})` }}>报警设置</Button>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div style={{ display: 'flex' }}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
width: 240,
|
|
|
|
|
|
backgroundColor: '#fff',
|
|
|
|
|
|
minHeight: 'calc(100vh - 60px)',
|
|
|
|
|
|
padding: 16
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<nav>
|
|
|
|
|
|
<ul style={{ listStyle: 'none', padding: 0, margin: 0 }}>
|
|
|
|
|
|
{['温度异常检测', '温湿度检测', '跑冒滴漏检测', '仪器仪表采集', '环境监测'].map((tab) => (
|
|
|
|
|
|
<li key={tab} style={{ marginBottom: 22 }}>
|
|
|
|
|
|
<button
|
|
|
|
|
|
onClick={() => handleTabClick(tab)}
|
|
|
|
|
|
style={{
|
|
|
|
|
|
width: 200,
|
|
|
|
|
|
height: 80,
|
|
|
|
|
|
display: 'flex',
|
|
|
|
|
|
alignItems: 'center',
|
|
|
|
|
|
justifyContent: 'center',
|
|
|
|
|
|
textAlign: 'center',
|
|
|
|
|
|
border: 'none',
|
|
|
|
|
|
// backgroundColor: activeTab === tab ? '#1890ff' : 'transparent',
|
|
|
|
|
|
color: activeTab === tab ? 'white' : 'black',
|
|
|
|
|
|
cursor: 'pointer',
|
|
|
|
|
|
borderRadius: 4,
|
|
|
|
|
|
fontSize: 24,
|
|
|
|
|
|
fontWeight: 400,
|
|
|
|
|
|
transition: 'all 0.3s',
|
|
|
|
|
|
backgroundImage: activeTab === tab ? `url(${activeBgImage})` : `url(${menuInactiveBg})`,
|
|
|
|
|
|
backgroundSize: 'cover',
|
|
|
|
|
|
backgroundPosition: 'center',
|
|
|
|
|
|
backgroundRepeat: 'no-repeat'
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
{tab}
|
|
|
|
|
|
</button>
|
|
|
|
|
|
</li>
|
|
|
|
|
|
))}
|
|
|
|
|
|
</ul>
|
|
|
|
|
|
</nav>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div style={{ flex: 1 }}>
|
|
|
|
|
|
{renderContent()}
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 任务规划与执行流程组件
|
|
|
|
|
|
const TaskPlanningFlow = () => {
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={{ backgroundColor: '#fff', padding: '20px', minHeight: '631px', borderRadius: '10px' }}>
|
|
|
|
|
|
{/* 顶部标题 */}
|
|
|
|
|
|
<div style={{ display: 'flex', flexDirection: 'row', textAlign: 'center', lineHeight: '31.43px', gap: '10px' }}>
|
|
|
|
|
|
<div style={{ fontSize: '20px', fontWeight: 'bold', color: '#006665', marginBottom: '20px' }}>
|
|
|
|
|
|
接班班组签到
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<div style={{ marginRight: '10px', fontSize: '14px', color: 'rgba(153, 153, 153, 1)' }}>当前多机协作任务完成时间较单机缩短 62%</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
{/* 顶部控制区域 */}
|
|
|
|
|
|
<Row gutter={[16, 16]} style={{ marginBottom: '20px' }}>
|
|
|
|
|
|
{/* 左侧任务状态选择框 */}
|
|
|
|
|
|
<Col span={6}>
|
|
|
|
|
|
<div style={{ display: 'flex', alignItems: 'center' }}>
|
|
|
|
|
|
<span style={{ marginRight: '10px', fontSize: '14px', color: '#333' }}>任务状态:</span>
|
|
|
|
|
|
<Select
|
|
|
|
|
|
defaultValue="全部"
|
|
|
|
|
|
style={{ width: 220 }}
|
|
|
|
|
|
options={[
|
|
|
|
|
|
{ value: '全部', label: '全部' },
|
|
|
|
|
|
{ value: '运行中', label: '运行中' },
|
|
|
|
|
|
{ value: '待充电', label: '待充电' },
|
|
|
|
|
|
{ value: '已完成', label: '已完成' },
|
|
|
|
|
|
]}
|
|
|
|
|
|
/>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 右侧按钮组 */}
|
|
|
|
|
|
<Col span={18} style={{ display: 'flex', justifyContent: 'flex-end' }}>
|
|
|
|
|
|
<Space size="16px" style={{ gap: '20px' }}>
|
|
|
|
|
|
<Button
|
|
|
|
|
|
style={{
|
|
|
|
|
|
width: '120px',
|
|
|
|
|
|
height: '40px',
|
|
|
|
|
|
fontSize: '14px',
|
|
|
|
|
|
fontWeight: '400',
|
|
|
|
|
|
color: 'white',
|
|
|
|
|
|
backgroundImage: `url(${btnImg1})`,
|
|
|
|
|
|
backgroundSize: '100% 100%',
|
|
|
|
|
|
border: 'none',
|
|
|
|
|
|
borderRadius: '5px'
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
新建任务
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
|
style={{
|
|
|
|
|
|
width: '120px',
|
|
|
|
|
|
height: '40px',
|
|
|
|
|
|
fontSize: '14px',
|
|
|
|
|
|
fontWeight: '400',
|
|
|
|
|
|
color: 'black',
|
|
|
|
|
|
backgroundImage: `url(${btnImg2})`,
|
|
|
|
|
|
backgroundSize: '100% 100%',
|
|
|
|
|
|
border: 'none',
|
|
|
|
|
|
borderRadius: '5px'
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
暂停所有任务
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
|
|
|
|
|
|
<Button
|
|
|
|
|
|
style={{
|
|
|
|
|
|
width: '120px',
|
|
|
|
|
|
height: '40px',
|
|
|
|
|
|
fontSize: '14px',
|
|
|
|
|
|
fontWeight: '400',
|
|
|
|
|
|
color: 'white',
|
|
|
|
|
|
backgroundImage: `url(${btnImg3})`,
|
|
|
|
|
|
backgroundSize: '100% 100%',
|
|
|
|
|
|
border: 'none',
|
|
|
|
|
|
borderRadius: '5px'
|
|
|
|
|
|
}}
|
|
|
|
|
|
>
|
|
|
|
|
|
刷新状态
|
|
|
|
|
|
</Button>
|
|
|
|
|
|
</Space>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 主要内容区域 - 左右布局 */}
|
|
|
|
|
|
<Row gutter={[16, 16]} style={{}}>
|
|
|
|
|
|
{/* 左侧实时监控信息区域 */}
|
|
|
|
|
|
<Col span={6}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
height: '100%',
|
|
|
|
|
|
background: '#e8f1ec',
|
|
|
|
|
|
padding: '15px',
|
|
|
|
|
|
borderRadius: '8px',
|
|
|
|
|
|
// border: '1px solid #006665',
|
|
|
|
|
|
overflow: 'auto'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
{/* 自主导航规则 */}
|
|
|
|
|
|
<div style={{ fontSize: '16px', fontWeight: 'bold', color: '#006665', marginBottom: '10px', borderBottom: '1px solid #006665', paddingBottom: '5px' }}>自主导航规则</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div style={{ fontSize: '14px', fontWeight: 'bold', color: '#006665', marginBottom: '8px' }}>罐区高级规则:</div>
|
|
|
|
|
|
<div style={{ fontSize: '12px', color: '#333', lineHeight: '1.6', paddingLeft: '10px', marginBottom: '15px' }}>
|
|
|
|
|
|
<div>• 陌生区域:基于罐区坐标生成"宇"字形环绕路径</div>
|
|
|
|
|
|
<div>• 高度 ≤ 10m 的罐体:距离罐体0.5m环绕</div>
|
|
|
|
|
|
<div>• 高度 {'>'} 10m 的罐体:距离罐体2m环绕</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div style={{ fontSize: '14px', fontWeight: 'bold', color: '#006665', marginBottom: '8px' }}>障碍物规则:</div>
|
|
|
|
|
|
<div style={{ fontSize: '12px', color: '#333', lineHeight: '1.6', paddingLeft: '10px', marginBottom: '15px' }}>
|
|
|
|
|
|
<div>• 距离障碍物 {'>'} 1.5m:继续沿当前路径行驶</div>
|
|
|
|
|
|
<div>• 距离障碍物 ≤ 1.5m:触发停止并执行路径重规划</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div style={{ fontSize: '14px', fontWeight: 'bold', color: '#006665', marginBottom: '8px' }}>示例配置:</div>
|
|
|
|
|
|
<div style={{ fontSize: '12px', color: '#333', lineHeight: '1.6', paddingLeft: '10px' }}>
|
|
|
|
|
|
<div>• 罐区A:优先级高,检查点15个</div>
|
|
|
|
|
|
<div>• 罐区B:优先级中,检查点10个</div>
|
|
|
|
|
|
<div>• 罐区C:优先级低,检查点8个</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 右侧背景图和监控信息区域 */}
|
|
|
|
|
|
<Col span={18}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
position: 'relative',
|
|
|
|
|
|
width: '100%',
|
|
|
|
|
|
height: '100%',
|
|
|
|
|
|
borderRadius: '10px',
|
|
|
|
|
|
overflow: 'hidden',
|
|
|
|
|
|
border: '1px solid rgba(0, 102, 101, 0.2)'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
{/* 背景图 */}
|
|
|
|
|
|
<img
|
|
|
|
|
|
src={taskPlanBg}
|
|
|
|
|
|
alt="任务规划与执行流程"
|
|
|
|
|
|
style={{
|
|
|
|
|
|
width: '100%',
|
|
|
|
|
|
height: '100%',
|
|
|
|
|
|
objectFit: 'cover'
|
|
|
|
|
|
}}
|
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 多级实时监控信息 - 右上角 */}
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
|
top: '20px',
|
|
|
|
|
|
right: '20px',
|
|
|
|
|
|
backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
|
|
|
|
|
padding: '15px',
|
|
|
|
|
|
borderRadius: '8px',
|
|
|
|
|
|
border: '1px solid #006665',
|
|
|
|
|
|
width: '300px',
|
|
|
|
|
|
boxShadow: '0 2px 8px rgba(0,0,0,0.1)'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<div style={{ fontSize: '16px', fontWeight: 'bold', color: '#006665', marginBottom: '10px', borderBottom: '1px solid #006665', paddingBottom: '5px' }}>多级实时监控</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 一级监控信息 */}
|
|
|
|
|
|
<div style={{ marginBottom: '15px' }}>
|
|
|
|
|
|
<div style={{ fontSize: '14px', fontWeight: 'bold', color: '#006665', marginBottom: '8px' }}>1. 高危罐区监控</div>
|
|
|
|
|
|
<div style={{ fontSize: '12px', color: '#333', lineHeight: '1.6', paddingLeft: '10px' }}>
|
|
|
|
|
|
<div>• 罐区A - 红外检测正常,压力稳定</div>
|
|
|
|
|
|
<div>• 罐区B - 温度监测中,运行状态良好</div>
|
|
|
|
|
|
<div>• 泄漏检测系统 - 无异常信号</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 二级监控信息 */}
|
|
|
|
|
|
<div style={{ marginBottom: '15px' }}>
|
|
|
|
|
|
<div style={{ fontSize: '14px', fontWeight: 'bold', color: '#006665', marginBottom: '8px' }}>2. 机器人状态监控</div>
|
|
|
|
|
|
<div style={{ fontSize: '12px', color: '#333', lineHeight: '1.6', paddingLeft: '10px' }}>
|
|
|
|
|
|
<div>• ROB-001 - 高危罐区A,电量85%,运行中</div>
|
|
|
|
|
|
<div>• ROB-002 - 高危罐区B,电量72%,运行中</div>
|
|
|
|
|
|
<div>• ROB-003 - 泵房区域,电量15%,待充电</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 三级监控信息 */}
|
|
|
|
|
|
<div>
|
|
|
|
|
|
<div style={{ fontSize: '14px', fontWeight: 'bold', color: '#006665', marginBottom: '8px' }}>3. 环境参数监控</div>
|
|
|
|
|
|
<div style={{ fontSize: '12px', color: '#333', lineHeight: '1.6', paddingLeft: '10px' }}>
|
|
|
|
|
|
<div>• 温度 - 26°C,湿度 - 58%</div>
|
|
|
|
|
|
<div>• 风速 - 2.3m/s,风向 - 东北</div>
|
|
|
|
|
|
<div>• 气体浓度 - 正常范围</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 浮动标签 */}
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
|
top: '30%',
|
|
|
|
|
|
left: '20%',
|
|
|
|
|
|
backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
|
|
|
|
|
padding: '8px 12px',
|
|
|
|
|
|
borderRadius: '15px',
|
|
|
|
|
|
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
|
|
|
|
|
|
fontSize: '12px',
|
|
|
|
|
|
color: '#006665'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
📦 更多功能
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
|
bottom: '40%',
|
|
|
|
|
|
left: '40%',
|
|
|
|
|
|
backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
|
|
|
|
|
padding: '8px 12px',
|
|
|
|
|
|
borderRadius: '15px',
|
|
|
|
|
|
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
|
|
|
|
|
|
fontSize: '12px',
|
|
|
|
|
|
color: '#006665'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
📋 调拨出库
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
|
bottom: '25%',
|
|
|
|
|
|
right: '35%',
|
|
|
|
|
|
backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
|
|
|
|
|
padding: '8px 12px',
|
|
|
|
|
|
borderRadius: '15px',
|
|
|
|
|
|
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
|
|
|
|
|
|
fontSize: '12px',
|
|
|
|
|
|
color: '#006665'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
📥 生产入库
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
|
bottom: '15%',
|
|
|
|
|
|
right: '15%',
|
|
|
|
|
|
backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
|
|
|
|
|
padding: '8px 12px',
|
|
|
|
|
|
borderRadius: '15px',
|
|
|
|
|
|
boxShadow: '0 2px 8px rgba(0,0,0,0.1)',
|
|
|
|
|
|
fontSize: '12px',
|
|
|
|
|
|
color: '#006665'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
📦 其他入库
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
{/* 机器人位置标记 */}
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
|
bottom: '35%',
|
|
|
|
|
|
left: '45%',
|
|
|
|
|
|
textAlign: 'center'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
width: '15px',
|
|
|
|
|
|
height: '15px',
|
|
|
|
|
|
borderRadius: '50%',
|
|
|
|
|
|
backgroundColor: '#52c41a',
|
|
|
|
|
|
border: '2px solid white',
|
|
|
|
|
|
boxShadow: '0 0 10px #52c41a',
|
|
|
|
|
|
margin: '0 auto 5px'
|
|
|
|
|
|
}}></div>
|
|
|
|
|
|
<div style={{ backgroundColor: 'rgba(82, 196, 26, 0.8)', color: 'white', padding: '3px 8px', borderRadius: '15px', fontSize: '11px' }}>ROB-001</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
position: 'absolute',
|
|
|
|
|
|
bottom: '30%',
|
|
|
|
|
|
right: '15%',
|
|
|
|
|
|
textAlign: 'center'
|
|
|
|
|
|
}}>
|
|
|
|
|
|
<div style={{
|
|
|
|
|
|
width: '15px',
|
|
|
|
|
|
height: '15px',
|
|
|
|
|
|
borderRadius: '50%',
|
|
|
|
|
|
backgroundColor: '#52c41a',
|
|
|
|
|
|
border: '2px solid white',
|
|
|
|
|
|
boxShadow: '0 0 10px #52c41a',
|
|
|
|
|
|
margin: '0 auto 5px'
|
|
|
|
|
|
}}></div>
|
|
|
|
|
|
<div style={{ backgroundColor: 'rgba(82, 196, 26, 0.8)', color: 'white', padding: '3px 8px', borderRadius: '15px', fontSize: '11px' }}>ROB-002</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
);
|
|
|
|
|
|
};
|
|
|
|
|
|
const StandardManagement = () => {
|
|
|
|
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
|
|
|
|
const [pageSize, setPageSize] = useState(10);
|
|
|
|
|
|
const [total, setTotal] = useState(85); // 总条数,实际项目中从接口获取
|
|
|
|
|
|
|
|
|
|
|
|
// 处理页码变化
|
|
|
|
|
|
const handlePageChange = (page, pageSize) => {
|
|
|
|
|
|
setCurrentPage(page);
|
|
|
|
|
|
setPageSize(pageSize);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理每页条数变化
|
|
|
|
|
|
const handlePageSizeChange = (current, size) => {
|
|
|
|
|
|
setPageSize(size);
|
|
|
|
|
|
setCurrentPage(1); // 重置到第一页
|
|
|
|
|
|
};
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={{ backgroundColor: '#fff', padding: '20px', borderBottomLeftRadius: '10px', }}>
|
|
|
|
|
|
<Title title={'巡检标准管理'}></Title>
|
|
|
|
|
|
<Row style={{ marginTop: '20px' }}>
|
|
|
|
|
|
<Button icon={<PlusOutlined />} className={styles['addBtn']} style={{ backgroundImage: `url(${btnImg1})`, marginRight: '30px' }}>新建方案</Button>
|
|
|
|
|
|
<Button className={styles['delBtn']} style={{ backgroundImage: `url(${btnImg2})` }}>删除</Button>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Row style={{ marginTop: '20px', minHeight: '450px' }}>
|
|
|
|
|
|
<StandardTable></StandardTable>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Row style={{ marginTop: '20px' }}>
|
|
|
|
|
|
<TablePagination
|
|
|
|
|
|
currentPage={currentPage}
|
|
|
|
|
|
pageSize={pageSize}
|
|
|
|
|
|
total={total}
|
|
|
|
|
|
onPageChange={handlePageChange}
|
|
|
|
|
|
onPageSizeChange={handlePageSizeChange}
|
|
|
|
|
|
></TablePagination>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
const DeviceAttributeSettings = () => {
|
|
|
|
|
|
const [currentPage, setCurrentPage] = useState(1);
|
|
|
|
|
|
const [pageSize, setPageSize] = useState(10);
|
|
|
|
|
|
const [total, setTotal] = useState(85); // 总条数,实际项目中从接口获取
|
|
|
|
|
|
const treeData = [
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '发电机区域',
|
|
|
|
|
|
key: '发电机区域',
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{ title: '#1 发电机', key: '#1发电机', },
|
|
|
|
|
|
{ title: '#2 发电机', key: '#2发电机', },
|
|
|
|
|
|
{ title: '#3 发电机', key: '#3发电机', },
|
|
|
|
|
|
{ title: '#4 发电机', key: '#4发电机', },
|
|
|
|
|
|
{ title: '#5 发电机', key: '#5发电机', },
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '中水处理区',
|
|
|
|
|
|
key: '中水处理区',
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{ title: '中水过滤装置A', key: '中水过滤装置A', },
|
|
|
|
|
|
{ title: '中水过滤装置B', key: '中水过滤装置B', },
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
title: '除盐水区',
|
|
|
|
|
|
key: '除盐水区',
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{ title: '除盐水泵1', key: '除盐水泵1', },
|
|
|
|
|
|
{ title: '除盐水泵2', key: '除盐水泵2', },
|
|
|
|
|
|
{ title: '除盐水泵3', key: '除盐水泵3', },
|
|
|
|
|
|
]
|
|
|
|
|
|
}]
|
|
|
|
|
|
// 处理页码变化
|
|
|
|
|
|
const handlePageChange = (page, pageSize) => {
|
|
|
|
|
|
setCurrentPage(page);
|
|
|
|
|
|
setPageSize(pageSize);
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
// 处理每页条数变化
|
|
|
|
|
|
const handlePageSizeChange = (current, size) => {
|
|
|
|
|
|
setPageSize(size);
|
|
|
|
|
|
setCurrentPage(1); // 重置到第一页
|
|
|
|
|
|
};
|
|
|
|
|
|
return (
|
|
|
|
|
|
<div style={{ backgroundColor: '#fff', padding: '20px' }}>
|
|
|
|
|
|
<Row>
|
|
|
|
|
|
<Col span={4} style={{ backgroundColor: 'rgb(231, 242, 237)', padding: '20px' }}>
|
|
|
|
|
|
<Title title={'巡检区域&设备'}></Title>
|
|
|
|
|
|
<Search style={{ margin: '20px 0' }}
|
|
|
|
|
|
placeholder={'搜索节点'}
|
|
|
|
|
|
></Search>
|
|
|
|
|
|
<Tree
|
|
|
|
|
|
treeData={treeData}
|
|
|
|
|
|
className={styles['tree']}
|
|
|
|
|
|
checkable
|
|
|
|
|
|
showLine
|
|
|
|
|
|
defaultExpandParent={true}
|
|
|
|
|
|
defaultExpandedKeys={['发电机区域', '中水处理区', '除盐水区',]}
|
|
|
|
|
|
>
|
|
|
|
|
|
|
|
|
|
|
|
</Tree>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
<Col span={20} style={{ padding: '10px' }}>
|
|
|
|
|
|
<Row style={{ marginBottom: '20px' }}>
|
|
|
|
|
|
<Button className={styles['addBtn']} style={{ backgroundImage: `url(${btnImg1})` }}>重新选择</Button>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Title title={'#1 发电机'}></Title>
|
|
|
|
|
|
<Row style={{ marginTop: '20px', minHeight: '450px' }}>
|
|
|
|
|
|
<DeviceAttribute></DeviceAttribute>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
<Row style={{ marginTop: '20px' }}>
|
|
|
|
|
|
<TablePagination
|
|
|
|
|
|
currentPage={currentPage}
|
|
|
|
|
|
pageSize={pageSize}
|
|
|
|
|
|
total={total}
|
|
|
|
|
|
onPageChange={handlePageChange}
|
|
|
|
|
|
onPageSizeChange={handlePageSizeChange}
|
|
|
|
|
|
></TablePagination>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
</Col>
|
|
|
|
|
|
</Row>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
const items = [
|
|
|
|
|
|
{
|
|
|
|
|
|
label: <MenuBg text={'人员管理'} icon={<DownOutlined style={{ fontSize: 16 }} />}></MenuBg>,
|
|
|
|
|
|
key: '人员管理',
|
|
|
|
|
|
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{ label: '人员管理', key: '人员管理' },
|
|
|
|
|
|
{ label: '班组管理', key: '班组管理' },
|
|
|
|
|
|
],
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: <MenuBg text={'排班管理'}></MenuBg>,
|
|
|
|
|
|
key: '排班管理',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: <MenuBg text={'巡检路线管理'} icon={<DownOutlined style={{ fontSize: 16 }} />}></MenuBg>,
|
|
|
|
|
|
key: '巡检路线管理',
|
|
|
|
|
|
children: [
|
|
|
|
|
|
{ label: '巡视路线查询', key: '巡视路线查询' },
|
|
|
|
|
|
{ label: '巡检标准管理', key: '巡检标准管理' },
|
|
|
|
|
|
{ label: '设备属性设置', key: '设备属性设置' },
|
|
|
|
|
|
]
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: <MenuBg text={'智能巡检范围监控'}></MenuBg>,
|
|
|
|
|
|
key: '智能巡检范围监控',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: <MenuBg text={'巡检内容'}></MenuBg>,
|
|
|
|
|
|
key: '巡检内容',
|
|
|
|
|
|
},
|
|
|
|
|
|
{
|
|
|
|
|
|
label: <MenuBg text={'任务规划与执行流程'}></MenuBg>,
|
|
|
|
|
|
key: '任务规划与执行流程',
|
|
|
|
|
|
},
|
|
|
|
|
|
]
|
|
|
|
|
|
const list = {
|
|
|
|
|
|
'人员管理': <PeopleMange />,
|
|
|
|
|
|
'班组管理': <ClassMange />,
|
|
|
|
|
|
'排班管理': <TimeMange />,
|
|
|
|
|
|
'巡视路线查询': <PatrolRouteQuery />,
|
|
|
|
|
|
'巡检标准管理': <StandardManagement />,
|
|
|
|
|
|
'设备属性设置': <DeviceAttributeSettings />,
|
|
|
|
|
|
'智能巡检范围监控': <SmartInspectionRange />,
|
|
|
|
|
|
'巡检内容': <SmartInspectionContent />,
|
|
|
|
|
|
'任务规划与执行流程': <TaskPlanningFlow />,
|
|
|
|
|
|
}
|
|
|
|
|
|
const InspectionTaskPlan = () => {
|
|
|
|
|
|
const [current, setCurrent] = useState('人员管理')
|
|
|
|
|
|
const onclick = (e) => {
|
|
|
|
|
|
console.log(e.key)
|
|
|
|
|
|
setCurrent(e.key)
|
|
|
|
|
|
}
|
|
|
|
|
|
return (
|
|
|
|
|
|
<>
|
|
|
|
|
|
<div className={styles['header']}>
|
|
|
|
|
|
<div className={styles['logo']}>
|
|
|
|
|
|
<span style={{ marginLeft: '-20px' }}> 当前: {current}</span>
|
|
|
|
|
|
|
|
|
|
|
|
</div>
|
|
|
|
|
|
<Menu
|
|
|
|
|
|
onClick={onclick}
|
|
|
|
|
|
items={items}
|
|
|
|
|
|
selectedKeys={[current]}
|
|
|
|
|
|
mode={'horizontal'}
|
|
|
|
|
|
style={{ flex: '1' }}
|
|
|
|
|
|
className={styles['menu']}
|
|
|
|
|
|
>
|
|
|
|
|
|
</Menu>
|
|
|
|
|
|
</div>
|
|
|
|
|
|
{list[current]}
|
|
|
|
|
|
|
|
|
|
|
|
</>
|
|
|
|
|
|
)
|
|
|
|
|
|
}
|
|
|
|
|
|
export default InspectionTaskPlan
|