| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031 |
- "use client"
- // 在文件顶部导入 useMemo
- import {useState} from "react"
- import {
- Badge,
- Button,
- Card,
- Col,
- Form,
- Input,
- Layout,
- Menu,
- message,
- Modal,
- Row,
- Select,
- Space,
- Statistic,
- Table,
- Tabs,
- Tag,
- } from "antd"
- import {
- AlertOutlined,
- BarChartOutlined,
- DashboardOutlined,
- DatabaseOutlined,
- EditOutlined,
- EyeOutlined,
- HomeOutlined,
- PlusOutlined,
- SettingOutlined
- } from "@ant-design/icons"
- import dynamic from "next/dynamic"
- import EChart from "@/components/echarts"
- import GisMapBaidu from "@/components/gisMapBaidu";
- import GisMapJinggai from "@/components/GISModule/gisMapJinggai";
- import PicEcharts from "@/components/GISModule/PicEcharts";
- import BarChart from "@/components/GISModule/eqClassIficationEcharts";
- import Dtxxdata from "@/components/GISModule/Dtxxdata";
- import Sbledata from "@/components/GISModule/Sbledata";
- import DbgdData from "@/components/GISModule/DbgdData";
- import SbqyxxData from "@/components/GISModule/SbqyxxData";
- //实时监测-实时监测一张图
- import RTMMGis from "@/components/realTimeMontorModule/RTMMGis";
- const {Header, Sider, Content} = Layout
- const {TabPane} = Tabs
- const {Option} = Select
- // 动态导入地图组件避免SSR问题
- const MapView = dynamic(() => import("./components/map-view"), {ssr: false})
- export default function ManholeMonitoringSystem() {
- const [selectedMenu, setSelectedMenu] = useState("home")
- const [deviceModalVisible, setDeviceModalVisible] = useState(false)
- const [selectedDevice, setSelectedDevice] = useState(null)
- const [addDeviceModalVisible, setAddDeviceModalVisible] = useState(false)
- const [editDeviceModalVisible, setEditDeviceModalVisible] = useState(false)
- const [editingDevice, setEditingDevice] = useState(null)
- const [devices, setDevices] = useState([
- {
- id: 1,
- name: "设备001",
- type: "智能井盖",
- status: "normal",
- location: "朝阳区建国路",
- lat: 39.9042,
- lng: 116.4074,
- battery: 85,
- signal: 90,
- },
- {
- id: 2,
- name: "设备002",
- type: "智能井盖",
- status: "warning",
- location: "海淀区中关村",
- lat: 39.9826,
- lng: 116.3186,
- battery: 45,
- signal: 75,
- },
- {
- id: 3,
- name: "设备003",
- type: "智能井盖",
- status: "error",
- location: "西城区金融街",
- lat: 39.926,
- lng: 116.3663,
- battery: 20,
- signal: 60,
- },
- {
- id: 4,
- name: "设备004",
- type: "智能井盖",
- status: "normal",
- location: "东城区王府井",
- lat: 39.9097,
- lng: 116.4109,
- battery: 92,
- signal: 95,
- },
- {
- id: 5,
- name: "设备005",
- type: "智能井盖",
- status: "maintenance",
- location: "丰台区丽泽",
- lat: 39.8584,
- lng: 116.3135,
- battery: 78,
- signal: 80,
- },
- ])
- const [alerts, setAlerts] = useState([
- {
- id: 1,
- deviceName: "设备002",
- type: "位移异常",
- level: "warning",
- time: "2024-01-15 14:30:25",
- location: "海淀区中关村",
- status: "pending", // pending, processed, ignored
- },
- {
- id: 2,
- deviceName: "设备003",
- type: "电池电压低",
- level: "error",
- time: "2024-01-15 14:25:10",
- location: "西城区金融街",
- status: "pending",
- },
- {
- id: 3,
- deviceName: "设备001",
- type: "震动异常",
- level: "info",
- time: "2024-01-15 14:20:15",
- location: "朝阳区建国路",
- status: "processed",
- },
- ])
- const [addDeviceForm] = Form.useForm()
- const [editDeviceForm] = Form.useForm()
- const handleAddDevice = (values: any) => {
- const newDevice = {
- id: devices.length + 1,
- name: values.name,
- type: values.type,
- status: values.status,
- location: values.location,
- lat: Number.parseFloat(values.lat),
- lng: Number.parseFloat(values.lng),
- battery: Number.parseInt(values.battery),
- signal: Number.parseInt(values.signal),
- }
- setDevices([...devices, newDevice])
- setAddDeviceModalVisible(false)
- addDeviceForm.resetFields()
- message.success("设备添加成功!")
- }
- const handleEditDevice = (values: any) => {
- const updatedDevices = devices.map((device) =>
- device.id === editingDevice.id
- ? {
- ...device,
- ...values,
- lat: Number.parseFloat(values.lat),
- lng: Number.parseFloat(values.lng),
- battery: Number.parseInt(values.battery),
- signal: Number.parseInt(values.signal),
- }
- : device,
- )
- setDevices(updatedDevices)
- setEditDeviceModalVisible(false)
- setEditingDevice(null)
- editDeviceForm.resetFields()
- message.success("设备信息更新成功!")
- }
- const openEditModal = (device: any) => {
- setEditingDevice(device)
- editDeviceForm.setFieldsValue(device)
- setEditDeviceModalVisible(true)
- }
- const handleProcessAlert = (alertId: number) => {
- const updatedAlerts = alerts.map((alert) => (alert.id === alertId ? {...alert, status: "processed"} : alert))
- setAlerts(updatedAlerts)
- message.success("报警已处理!")
- }
- const handleIgnoreAlert = (alertId: number) => {
- const updatedAlerts = alerts.map((alert) => (alert.id === alertId ? {...alert, status: "ignored"} : alert))
- setAlerts(updatedAlerts)
- message.success("报警已忽略!")
- }
- // 设备状态统计
- const deviceStats = {
- total: devices.length,
- normal: devices.filter((d) => d.status === "normal").length,
- warning: devices.filter((d) => d.status === "warning").length,
- error: devices.filter((d) => d.status === "error").length,
- maintenance: devices.filter((d) => d.status === "maintenance").length,
- }
- // 区域分布图表配置
- const regionChartOption = {
- title: {text: "设备区域分布", left: "center"},
- tooltip: {trigger: "item"},
- series: [
- {
- type: "pie",
- radius: "50%",
- data: [
- {value: 1, name: "朝阳区"},
- {value: 1, name: "海淀区"},
- {value: 1, name: "西城区"},
- {value: 1, name: "东城区"},
- {value: 1, name: "丰台区"},
- ],
- },
- ],
- }
- // 设备状态分布图表配置
- const statusChartOption = {
- title: {text: "设备状态分布", left: "center"},
- tooltip: {trigger: "item"},
- series: [
- {
- type: "pie",
- radius: "50%",
- data: [
- {value: deviceStats.normal, name: "正常", itemStyle: {color: "#52c41a"}},
- {value: deviceStats.warning, name: "告警", itemStyle: {color: "#faad14"}},
- {value: deviceStats.error, name: "故障", itemStyle: {color: "#f5222d"}},
- {value: deviceStats.maintenance, name: "维修中", itemStyle: {color: "#722ed1"}},
- ],
- },
- ],
- }
- // 实时监测数据图表配置
- const monitoringChartOption = {
- title: {text: "实时监测数据趋势", left: "center"},
- tooltip: {trigger: "axis"},
- legend: {data: ["倾斜角度", "位移距离", "震动强度"], top: 30},
- xAxis: {
- type: "category",
- data: ["00:00", "04:00", "08:00", "12:00", "16:00", "20:00"],
- },
- yAxis: {type: "value"},
- series: [
- {
- name: "倾斜角度",
- type: "line",
- data: [2.1, 2.3, 2.0, 2.5, 2.8, 2.4],
- itemStyle: {color: "#1890ff"},
- },
- {
- name: "位移距离",
- type: "line",
- data: [0.5, 0.7, 0.4, 0.9, 1.2, 0.8],
- itemStyle: {color: "#52c41a"},
- },
- {
- name: "震动强度",
- type: "line",
- data: [15, 18, 12, 22, 28, 20],
- itemStyle: {color: "#faad14"},
- },
- ],
- }
- const deviceColumns = [
- {title: "设备编号", dataIndex: "name", key: "name"},
- {title: "设备类型", dataIndex: "type", key: "type"},
- {
- title: "运维状态",
- dataIndex: "status",
- key: "status",
- render: (status: string) => {
- const statusMap = {
- normal: {color: "success", text: "正常"},
- warning: {color: "warning", text: "告警"},
- error: {color: "error", text: "故障"},
- maintenance: {color: "processing", text: "维修中"},
- }
- const config = statusMap[status as keyof typeof statusMap]
- return <Badge status={config.color as any} text={config.text}/>
- },
- },
- {title: "所在位置", dataIndex: "location", key: "location"},
- {
- title: "电池电量",
- dataIndex: "battery",
- key: "battery",
- render: (battery: number) => `${battery}%`,
- },
- {
- title: "信号强度",
- dataIndex: "signal",
- key: "signal",
- render: (signal: number) => `${signal}%`,
- },
- {
- title: "操作",
- key: "action",
- render: (_, record: any) => (
- <Space>
- <Button
- type="link"
- icon={<EyeOutlined/>}
- onClick={() => {
- setSelectedDevice(record)
- setDeviceModalVisible(true)
- }}
- >
- 查看
- </Button>
- <Button type="link" icon={<EditOutlined/>} onClick={() => openEditModal(record)}>
- 编辑
- </Button>
- </Space>
- ),
- },
- ]
- const alertColumns = [
- {title: "设备名称", dataIndex: "deviceName", key: "deviceName"},
- {title: "报警类型", dataIndex: "type", key: "type"},
- {
- title: "报警级别",
- dataIndex: "level",
- key: "level",
- render: (level: string) => {
- const levelMap = {
- info: {color: "blue", text: "信息"},
- warning: {color: "orange", text: "警告"},
- error: {color: "red", text: "严重"},
- }
- const config = levelMap[level as keyof typeof levelMap]
- return <Tag color={config.color}>{config.text}</Tag>
- },
- },
- {title: "报警时间", dataIndex: "time", key: "time"},
- {title: "设备位置", dataIndex: "location", key: "location"},
- {
- title: "状态",
- dataIndex: "status",
- key: "status",
- render: (status: string) => {
- const statusMap = {
- pending: {color: "orange", text: "待处理"},
- processed: {color: "green", text: "已处理"},
- ignored: {color: "gray", text: "已忽略"},
- }
- const config = statusMap[status as keyof typeof statusMap]
- return <Tag color={config.color}>{config.text}</Tag>
- },
- },
- {
- title: "操作",
- key: "action",
- render: (_, record: any) => (
- <Space>
- {record.status === "pending" && (
- <>
- <Button type="link" onClick={() => handleProcessAlert(record.id)}>
- 处理
- </Button>
- <Button type="link" onClick={() => handleIgnoreAlert(record.id)}>
- 忽略
- </Button>
- </>
- )}
- {record.status !== "pending" && <span className="text-gray-400">已处理</span>}
- </Space>
- ),
- },
- ]
- const renderContent = () => {
- switch (selectedMenu) {
- case "home":
- return (
- <div>
- <div className="space-y-6" style={{height: '93vh', backgroundColor: '#3a3899'}}>
- <div className="flex m-0" style={{height: '70%'}}>
- <div className="" style={{width: '25%'}}>
- <div className='' style={{height: '50%'}}>
- <div style={{
- height: '12%',
- backgroundImage: 'url(/boxTitle.png)',
- backgroundSize: '100% 100%',
- textAlign: 'left',
- color: 'white',
- fontSize: '18px',
- fontWeight: 'bold',
- paddingLeft: '20px'
- }}>
- 待办工单
- </div>
- <div className='' style={{
- height: '88%',
- backgroundImage: 'url(/eject.PNG)',
- backgroundSize: '100% 100%',
- padding: '10px'
- }}>
- <DbgdData></DbgdData>
- </div>
- </div>
- <div className='' style={{height: '50%'}}>
- <div style={{
- height: '12%',
- backgroundImage: 'url(/boxTitle.png)',
- backgroundSize: '100% 100%',
- textAlign: 'left',
- color: 'white',
- fontSize: '18px',
- fontWeight: 'bold',
- paddingLeft: '20px'
- }}>
- 告警类型统计(15天内)
- </div>
- <div className='' style={{
- height: '88%',
- backgroundImage: 'url(/eject.PNG)',
- backgroundSize: '100% 100%'
- }}>
- <PicEcharts
- // title="告警类型统计"
- data={[
- {value: 335, name: '位移告警'},
- {value: 310, name: '倾斜告警'},
- {value: 234, name: '水位告警'},
- {value: 135, name: '电压告警'},
- {value: 1548, name: '温度告警'}
- ]}
- style={{height: '100%', width: '100%'}}
- />
- </div>
- </div>
- </div>
- <div className="" style={{width: '70%'}}>
- <GisMapJinggai height={'65'}/>
- </div>
- <div className="" style={{width: '25%'}}>
- <div className='' style={{height: '100%'}}>
- <div style={{
- height: '6%',
- backgroundImage: 'url(/boxTitle.png)',
- backgroundSize: '100% 100%',
- textAlign: 'left',
- color: 'white',
- fontSize: '18px',
- fontWeight: 'bold',
- paddingLeft: '20px'
- }}>
- 设备列表
- </div>
- {/* 修改表格容器样式,添加背景色覆盖白色区域 */}
- <div className='' style={{
- height: '94%',
- backgroundImage: 'url(/eject.PNG)',
- backgroundSize: '100% 100%',
- padding: '40px 20px 40px 20px',
- boxSizing: 'border-box',
- overflowY: 'hidden',
- backgroundColor: '#3a3899' // 添加与页面主色调一致的背景色
- }}>
- <div style={{height: '100%',}}>
- <Sbledata></Sbledata>
- </div>
- </div>
- </div>
- </div>
- </div>
- <div className="flex m-0" style={{height: '30%', justifyContent: 'space-evenly'}}>
- <div style={{width: '33%'}}>
- <div style={{
- height: '12%',
- backgroundImage: 'url(/boxTitle.png)',
- backgroundSize: '100% 100%',
- textAlign: 'left',
- color: 'white',
- fontSize: '18px',
- fontWeight: 'bold',
- paddingLeft: '30px'
- }}>
- 设备区域信息
- </div>
- <div className='' style={{
- height: '88%',
- backgroundImage: 'url(/eject.PNG)',
- backgroundSize: '100% 100%'
- }}>
- <SbqyxxData
- data={[
- {value: 81, name: '太安社区'},
- {value: 85, name: '桃花岭社区'},
- {value: 60, name: '龙泉山社区'},
- {value: 45, name: '鸳鸯山社区'},
- {value: 50, name: '龙兴社区'},
- {value: 55, name: '胜利门社区'},
- {value: 88, name: '鹤鸣山社区'},
- {value: 25, name: '教场坪社区'},
- {value: 45, name: '荷花池社区'},
- {value: 22, name: '廻龙山社区'},
- {value: 35, name: '凤鸣塔社区'},
- {value: 35, name: '望圣坡社区'},
- {value: 22, name: '凤凰山社区'},
- {value: 58, name: '苦藤铺社区'},
- {value: 75, name: '黄草尾社区'},
- {value: 65, name: '老鸦溪社区'},
- {value: 66, name: '渔家巷社区'}
- ]}
- style={{height: '99%', width: '100%'}}
- />
- </div>
- </div>
- <div style={{width: '33%'}}>
- <div style={{
- height: '12%',
- backgroundImage: 'url(/boxTitle.png)',
- backgroundSize: '100% 100%',
- textAlign: 'left',
- color: 'white',
- fontSize: '18px',
- fontWeight: 'bold',
- paddingLeft: '30px'
- }}>
- 设备分类
- </div>
- <div className='' style={{
- height: '88%',
- backgroundImage: 'url(/eject.PNG)',
- backgroundSize: '100% 100%'
- }}>
- <BarChart
- data={[
- {value: 120, name: '电用井盖'},
- {value: 85, name: '供水井盖'},
- {value: 60, name: '通信井盖'},
- {value: 45, name: '燃气井盖'},
- {value: 30, name: '污水井盖'},
- {value: 30, name: '雨水井盖'},
- {value: 30, name: '路灯井盖'},
- {value: 30, name: '网络井盖'},
- {value: 30, name: '电缆井盖'},
- {value: 30, name: '园林井盖'},
- {value: 30, name: '化粪池井盖'}
- ]}
- style={{height: '99%', width: '100%'}}
- />
- </div>
- </div>
- <div style={{width: '33%'}}>
- <div style={{
- height: '12%',
- backgroundImage: 'url(/boxTitle.png)',
- backgroundSize: '100% 100%',
- textAlign: 'left',
- color: 'white',
- fontSize: '18px',
- fontWeight: 'bold',
- paddingLeft: '30px'
- }}>
- 动态信息
- </div>
- <div className='' style={{
- height: '88%',
- backgroundImage: 'url(/eject.PNG)',
- backgroundSize: '100% 100%',
- padding: '20px'
- }}>
- <Dtxxdata height={'100%'} width={'100%'}/>
- </div>
- </div>
- </div>
- </div>
- {/*<div>*/}
- {/* <GisMapJinggai height={'100'}/>*/}
- {/*</div>*/}
- </div>
- )
- case "dashboard":
- return (
- <div className="space-y-6">
- {/* 统计卡片 */}
- <Row gutter={16}>
- <Col span={6}>
- <Card>
- <Statistic title="设备总数" value={deviceStats.total} valueStyle={{color: "#1890ff"}}/>
- </Card>
- </Col>
- <Col span={6}>
- <Card>
- <Statistic title="正常设备" value={deviceStats.normal} valueStyle={{color: "#52c41a"}}/>
- </Card>
- </Col>
- <Col span={6}>
- <Card>
- <Statistic title="告警设备" value={deviceStats.warning}
- valueStyle={{color: "#faad14"}}/>
- </Card>
- </Col>
- <Col span={6}>
- <Card>
- <Statistic title="故障设备" value={deviceStats.error} valueStyle={{color: "#f5222d"}}/>
- </Card>
- </Col>
- </Row>
- {/* 图表展示 */}
- <Row gutter={16}>
- <Col span={12}>
- <Card title="设备区域分布">
- <EChart option={regionChartOption}/>
- </Card>
- </Col>
- <Col span={12}>
- <Card title="设备状态分布">
- <EChart option={statusChartOption}/>
- </Card>
- </Col>
- </Row>
- {/* 实时监测趋势 */}
- <Card title="实时监测数据趋势">
- <EChart option={monitoringChartOption}/>
- </Card>
- </div>
- )
- case "devices":
- return (
- <div className="space-y-6">
- <Card
- title="监测设备台账"
- extra={
- <Button type="primary" icon={<PlusOutlined/>}
- onClick={() => setAddDeviceModalVisible(true)}>
- 添加设备
- </Button>
- }
- >
- <Table columns={deviceColumns} dataSource={devices} rowKey="id"
- pagination={{pageSize: 10}}/>
- </Card>
- </div>
- )
- case "map":
- return (
- <div className="space-y-6">
- <Card title="监测设备 GIS 一张图">
- <div style={{height: "600px"}}>
- <GisMapBaidu height={'50'}/>
- </div>
- </Card>
- </div>
- )
- case "monitoring":
- return (
- <div className="space-y-6" style={{paddingLeft:'10px'}}>
- <Tabs defaultActiveKey="realtime">
- <TabPane tab="实时监测" key="realtime">
- <RTMMGis height={'86.2'}></RTMMGis>
- </TabPane>
- <TabPane tab="窨井状态监测" key="data">
- <Card title="窨井状态监测">
- <EChart option={monitoringChartOption}/>
- </Card>
- </TabPane>
- </Tabs>
- </div>
- )
- case "alerts":
- return (
- <div className="space-y-6">
- <Row gutter={16}>
- <Col span={6}>
- <Card>
- <Statistic title="今日告警" value={alerts.length} valueStyle={{color: "#f5222d"}}/>
- </Card>
- </Col>
- <Col span={6}>
- <Card>
- <Statistic
- title="待处理"
- value={alerts.filter((a) => a.status === "pending").length}
- valueStyle={{color: "#faad14"}}
- />
- </Card>
- </Col>
- <Col span={6}>
- <Card>
- <Statistic
- title="已处理"
- value={alerts.filter((a) => a.status === "processed").length}
- valueStyle={{color: "#52c41a"}}
- />
- </Card>
- </Col>
- <Col span={6}>
- <Card>
- <Statistic
- title="已忽略"
- value={alerts.filter((a) => a.status === "ignored").length}
- valueStyle={{color: "#d9d9d9"}}
- />
- </Card>
- </Col>
- </Row>
- <Card title="监测报警记录">
- <Table columns={alertColumns} dataSource={alerts} rowKey="id" pagination={{pageSize: 10}}/>
- </Card>
- </div>
- )
- case "settlement":
- return (
- <div className="space-y-6 p-2">
- <Tabs defaultActiveKey="realtime">
- <TabPane tab="案件流转管理" key="realtime">
- <Row gutter={16}>
- <Col span={24}>
- <Card title="案件流转管理">
- <div style={{height: "500px"}}>
- <MapView devices={devices} showRealTimeData/>
- </div>
- </Card>
- </Col>
- </Row>
- </TabPane>
- <TabPane tab="工单处置管理" key="data">
- <Card title="工单处置管理">
- <EChart option={monitoringChartOption}/>
- </Card>
- </TabPane>
- <TabPane tab="经办工单" key="data1">
- <Card title="经办工单">
- <EChart option={monitoringChartOption}/>
- </Card>
- </TabPane>
- <TabPane tab="办结工单" key="data2">
- <Card title="办结工单">
- <EChart option={monitoringChartOption}/>
- </Card>
- </TabPane>
- </Tabs>
- </div>
- )
- default:
- return <div>页面开发中...</div>
- }
- }
- return (
- <Layout className="min-h-screen">
- <Header className="bg-blue-600 text-white" style={{backgroundColor: 'white'}}>
- <div className="flex items-center justify-between">
- <h1 className="text-xl font-bold">窨井盖安全运行监测子系统</h1>
- <div className="text-sm">当前时间: {new Date().toLocaleString("zh-CN")}</div>
- </div>
- </Header>
- <Layout>
- <Sider width={200} className="bg-white">
- <Menu
- mode="inline"
- selectedKeys={[selectedMenu]}
- onClick={({key}) => setSelectedMenu(key)}
- className="h-full border-r"
- >
- <Menu.Item key="home" icon={<HomeOutlined/>}>
- GIS地图
- </Menu.Item>
- <Menu.Item key="dashboard" icon={<DashboardOutlined/>}>
- 监控面板
- </Menu.Item>
- <Menu.Item key="devices" icon={<SettingOutlined/>}>
- 设备管理
- </Menu.Item>
- {/*<Menu.Item key="map" icon={<EnvironmentOutlined/>}>*/}
- {/* GIS地图*/}
- {/*</Menu.Item>*/}
- <Menu.Item key="monitoring" icon={<BarChartOutlined/>}>
- 实时监测
- </Menu.Item>
- <Menu.Item key="alerts" icon={<AlertOutlined/>}>
- 报警管理
- </Menu.Item>
- <Menu.Item key="settlement" icon={<DatabaseOutlined/>}>
- 案件办结
- </Menu.Item>
- </Menu>
- </Sider>
- <Layout>
- <Content className="bg-gray-50 min-h-full">{renderContent()}</Content>
- </Layout>
- </Layout>
- {/* 设备详情弹窗 */}
- <Modal
- title="设备详情"
- open={deviceModalVisible}
- onCancel={() => setDeviceModalVisible(false)}
- footer={null}
- width={600}
- >
- {selectedDevice && (
- <div className="space-y-4">
- <Row gutter={16}>
- <Col span={12}>
- <div>
- <strong>设备编号:</strong> {selectedDevice.name}
- </div>
- </Col>
- <Col span={12}>
- <div>
- <strong>设备类型:</strong> {selectedDevice.type}
- </div>
- </Col>
- </Row>
- <Row gutter={16}>
- <Col span={12}>
- <div>
- <strong>所在位置:</strong> {selectedDevice.location}
- </div>
- </Col>
- <Col span={12}>
- <div>
- <strong>运维状态:</strong>
- <Badge
- status={selectedDevice.status === "normal" ? "success" : "error"}
- text={selectedDevice.status === "normal" ? "正常" : "异常"}
- />
- </div>
- </Col>
- </Row>
- <Row gutter={16}>
- <Col span={12}>
- <div>
- <strong>电池电量:</strong> {selectedDevice.battery}%
- </div>
- </Col>
- <Col span={12}>
- <div>
- <strong>信号强度:</strong> {selectedDevice.signal}%
- </div>
- </Col>
- </Row>
- </div>
- )}
- </Modal>
- {/* 添加设备弹窗 */}
- <Modal
- title="添加设备"
- open={addDeviceModalVisible}
- onCancel={() => {
- setAddDeviceModalVisible(false)
- addDeviceForm.resetFields()
- }}
- onOk={() => addDeviceForm.submit()}
- width={600}
- >
- <Form form={addDeviceForm} layout="vertical" onFinish={handleAddDevice}>
- <Row gutter={16}>
- <Col span={12}>
- <Form.Item name="name" label="设备编号" rules={[{required: true, message: "请输入设备编号"}]}>
- <Input placeholder="请输入设备编号"/>
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item name="type" label="设备类型" rules={[{required: true, message: "请选择设备类型"}]}>
- <Select placeholder="请选择设备类型">
- <Option value="智能井盖">智能井盖</Option>
- <Option value="传感器">传感器</Option>
- <Option value="监控设备">监控设备</Option>
- </Select>
- </Form.Item>
- </Col>
- </Row>
- <Row gutter={16}>
- <Col span={12}>
- <Form.Item name="status" label="运维状态" rules={[{required: true, message: "请选择运维状态"}]}>
- <Select placeholder="请选择运维状态">
- <Option value="normal">正常</Option>
- <Option value="warning">告警</Option>
- <Option value="error">故障</Option>
- <Option value="maintenance">维修中</Option>
- </Select>
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item name="location" label="所在位置" rules={[{required: true, message: "请输入所在位置"}]}>
- <Input placeholder="请输入所在位置"/>
- </Form.Item>
- </Col>
- </Row>
- <Row gutter={16}>
- <Col span={12}>
- <Form.Item name="lat" label="纬度" rules={[{required: true, message: "请输入纬度"}]}>
- <Input placeholder="请输入纬度" type="number" step="0.000001"/>
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item name="lng" label="经度" rules={[{required: true, message: "请输入经度"}]}>
- <Input placeholder="请输入经度" type="number" step="0.000001"/>
- </Form.Item>
- </Col>
- </Row>
- <Row gutter={16}>
- <Col span={12}>
- <Form.Item name="battery" label="电池电量(%)" rules={[{required: true, message: "请输入电池电量"}]}>
- <Input placeholder="请输入电池电量" type="number" min="0" max="100"/>
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item name="signal" label="信号强度(%)" rules={[{required: true, message: "请输入信号强度"}]}>
- <Input placeholder="请输入信号强度" type="number" min="0" max="100"/>
- </Form.Item>
- </Col>
- </Row>
- </Form>
- </Modal>
- {/* 编辑设备弹窗 */}
- <Modal
- title="编辑设备"
- open={editDeviceModalVisible}
- onCancel={() => {
- setEditDeviceModalVisible(false)
- setEditingDevice(null)
- editDeviceForm.resetFields()
- }}
- onOk={() => editDeviceForm.submit()}
- width={600}
- >
- <Form form={editDeviceForm} layout="vertical" onFinish={handleEditDevice}>
- <Row gutter={16}>
- <Col span={12}>
- <Form.Item name="name" label="设备编号" rules={[{required: true, message: "请输入设备编号"}]}>
- <Input placeholder="请输入设备编号"/>
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item name="type" label="设备类型" rules={[{required: true, message: "请选择设备类型"}]}>
- <Select placeholder="请选择设备类型">
- <Option value="智能井盖">智能井盖</Option>
- <Option value="传感器">传感器</Option>
- <Option value="监控设备">监控设备</Option>
- </Select>
- </Form.Item>
- </Col>
- </Row>
- <Row gutter={16}>
- <Col span={12}>
- <Form.Item name="status" label="运维状态" rules={[{required: true, message: "请选择运维状态"}]}>
- <Select placeholder="请选择运维状态">
- <Option value="normal">正常</Option>
- <Option value="warning">告警</Option>
- <Option value="error">故障</Option>
- <Option value="maintenance">维修中</Option>
- </Select>
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item name="location" label="所在位置" rules={[{required: true, message: "请输入所在位置"}]}>
- <Input placeholder="请输入所在位置"/>
- </Form.Item>
- </Col>
- </Row>
- <Row gutter={16}>
- <Col span={12}>
- <Form.Item name="lat" label="纬度" rules={[{required: true, message: "请输入纬度"}]}>
- <Input placeholder="请输入纬度" type="number" step="0.000001"/>
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item name="lng" label="经度" rules={[{required: true, message: "请输入经度"}]}>
- <Input placeholder="请输入经度" type="number" step="0.000001"/>
- </Form.Item>
- </Col>
- </Row>
- <Row gutter={16}>
- <Col span={12}>
- <Form.Item name="battery" label="电池电量(%)" rules={[{required: true, message: "请输入电池电量"}]}>
- <Input placeholder="请输入电池电量" type="number" min="0" max="100"/>
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item name="signal" label="信号强度(%)" rules={[{required: true, message: "请输入信号强度"}]}>
- <Input placeholder="请输入信号强度" type="number" min="0" max="100"/>
- </Form.Item>
- </Col>
- </Row>
- </Form>
- </Modal>
- </Layout>
- )
- }
|