| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200 |
- "use client"
- import {useState} from "react"
- import {
- App,
- Badge,
- Button,
- Card,
- Col,
- Form,
- Input,
- Modal,
- Row,
- Select,
- Space,
- Statistic,
- Table,
- Tag,
- Upload,
- } from "antd"
- import {
- ArrowDownOutlined,
- ArrowUpOutlined,
- CheckCircleOutlined,
- CloseCircleOutlined,
- EditOutlined,
- ExclamationCircleOutlined,
- ExportOutlined,
- EyeOutlined,
- PlusOutlined,
- SyncOutlined,
- UploadOutlined,
- } from "@ant-design/icons"
- import EChart from "@/components/echarts"
- import WaterMap from "./components/water-map"
- import AdminLayout from "./components/admin-layout"
- import type {EChartsCoreOption} from "echarts/core"
- import globalMessage from "@/app/_modules/globalMessage";
- const { Search } = Input
- const { Option } = Select
- export default function WaterSupplyMonitoring() {
- const [activeTab, setActiveTab] = useState("dashboard")
- const [modalVisible, setModalVisible] = useState(false)
- const [facilityDetailModal, setFacilityDetailModal] = useState(false)
- const [deviceDetailModal, setDeviceDetailModal] = useState(false)
- const [thresholdModal, setThresholdModal] = useState(false)
- const [exportModal, setExportModal] = useState(false)
- const [selectedRecord, setSelectedRecord] = useState<any>(null)
- const [loading, setLoading] = useState(false)
- const [form] = Form.useForm()
- const [thresholdForm] = Form.useForm()
- // 模拟数据
- const facilitiesData = [
- { key: "1", name: "湘江水源地", type: "水源地", location: "长沙市岳麓区", status: "正常", capacity: "10000m³/d" },
- { key: "2", name: "长沙第一水厂", type: "水厂", location: "长沙市芙蓉区", status: "正常", capacity: "50000m³/d" },
- { key: "3", name: "岳麓区增压泵站", type: "泵站", location: "长沙市岳麓区", status: "预警", capacity: "20000m³/d" },
- { key: "4", name: "五一大道主管网", type: "管网", location: "长沙市芙蓉区", status: "正常", length: "15km" },
- { key: "5", name: "中南大学", type: "大用户", location: "长沙市岳麓区", status: "报警", usage: "500m³/d" },
- ]
- const devicesData = [
- { key: "1", name: "流量计001", type: "流量计", location: "泵站A", status: "正常", lastMaintenance: "2024-01-15" },
- {
- key: "2",
- name: "压力计002",
- type: "压力计",
- location: "管网节点1",
- status: "故障",
- lastMaintenance: "2024-01-10",
- },
- {
- key: "3",
- name: "声波监测003",
- type: "漏失监测",
- location: "主管线",
- status: "正常",
- lastMaintenance: "2024-01-20",
- },
- {
- key: "4",
- name: "流量计004",
- type: "流量计",
- location: "水厂出口",
- status: "维修中",
- lastMaintenance: "2024-01-12",
- },
- ]
- const monitoringData = [
- { key: "1", point: "监测点001", type: "流量", value: "125.6 m³/h", status: "正常", time: "2024-01-25 14:30" },
- { key: "2", point: "监测点002", type: "压力", value: "0.45 MPa", status: "正常", time: "2024-01-25 14:30" },
- { key: "3", point: "监测点003", type: "漏失", value: "检测到异常", status: "报警", time: "2024-01-25 14:25" },
- { key: "4", point: "监测点004", type: "流量", value: "89.2 m³/h", status: "预警", time: "2024-01-25 14:30" },
- ]
- const alarmsData = [
- { key: "1", location: "增压泵站A", type: "压力异常", level: "中级", status: "待处理", time: "2024-01-25 14:25" },
- { key: "2", location: "大用户A", type: "流量超限", level: "高级", status: "处理中", time: "2024-01-25 14:20" },
- { key: "3", location: "主管网节点", type: "设备故障", level: "低级", status: "已处理", time: "2024-01-25 14:15" },
- ]
- // 图表配置
- const flowChartOption: EChartsCoreOption = {
- title: {
- text: "长沙市供水流量趋势",
- left: "center",
- textStyle: { fontSize: 16, fontWeight: "bold" },
- },
- tooltip: {
- trigger: "axis",
- backgroundColor: "rgba(0,0,0,0.8)",
- borderColor: "#1890ff",
- textStyle: { color: "#fff" },
- },
- legend: { data: ["湘江取水量", "供水总量", "用水需求"], bottom: 0 },
- xAxis: {
- type: "category",
- data: ["00:00", "04:00", "08:00", "12:00", "16:00", "20:00", "24:00"],
- axisLine: { lineStyle: { color: "#d9d9d9" } },
- },
- yAxis: {
- type: "value",
- name: "流量(万m³/h)",
- axisLine: { lineStyle: { color: "#d9d9d9" } },
- },
- series: [
- {
- name: "湘江取水量",
- type: "line",
- data: [120, 132, 101, 134, 90, 230, 210],
- smooth: true,
- itemStyle: { color: "#1890ff" },
- areaStyle: { opacity: 0.3 },
- animationDelay: 0,
- },
- {
- name: "供水总量",
- type: "line",
- data: [110, 125, 95, 128, 85, 220, 200],
- smooth: true,
- itemStyle: { color: "#52c41a" },
- areaStyle: { opacity: 0.3 },
- animationDelay: 300,
- },
- {
- name: "用水需求",
- type: "line",
- data: [100, 120, 90, 125, 80, 215, 195],
- smooth: true,
- itemStyle: { color: "#faad14" },
- areaStyle: { opacity: 0.3 },
- animationDelay: 600,
- },
- ],
- animationDuration: 2000,
- animationEasing: "cubicOut",
- }
- const pressureChartOption: EChartsCoreOption = {
- title: {
- text: "长沙市管网压力分布",
- left: "center",
- textStyle: { fontSize: 16, fontWeight: "bold" },
- },
- tooltip: {
- trigger: "item",
- formatter: "{a} <br/>{b}: {c} ({d}%)",
- },
- series: [
- {
- name: "压力分布",
- type: "pie",
- radius: ["40%", "70%"],
- center: ["50%", "60%"],
- data: [
- { value: 45, name: "正常压力", itemStyle: { color: "#52c41a" } },
- { value: 25, name: "低压预警", itemStyle: { color: "#faad14" } },
- { value: 15, name: "高压预警", itemStyle: { color: "#ff7a45" } },
- { value: 15, name: "压力异常", itemStyle: { color: "#ff4d4f" } },
- ],
- emphasis: {
- itemStyle: {
- shadowBlur: 10,
- shadowOffsetX: 0,
- shadowColor: "rgba(0, 0, 0, 0.5)",
- },
- },
- animationType: "scale",
- animationEasing: "elasticOut",
- animationDelay: (idx: number) => Math.random() * 200,
- },
- ],
- }
- const alarmTrendOption: EChartsCoreOption = {
- title: {
- text: "长沙市供水报警趋势统计",
- left: "center",
- textStyle: { fontSize: 16, fontWeight: "bold" },
- },
- tooltip: {
- trigger: "axis",
- backgroundColor: "rgba(0,0,0,0.8)",
- borderColor: "#1890ff",
- },
- legend: { data: ["高级报警", "中级报警", "低级报警"], bottom: 0 },
- xAxis: {
- type: "category",
- data: ["周一", "周二", "周三", "周四", "周五", "周六", "周日"],
- },
- yAxis: { type: "value", name: "报警次数" },
- series: [
- {
- name: "高级报警",
- type: "bar",
- data: [2, 1, 3, 2, 1, 0, 1],
- itemStyle: { color: "#ff4d4f" },
- animationDelay: (idx: number) => idx * 100,
- },
- {
- name: "中级报警",
- type: "bar",
- data: [5, 3, 4, 6, 3, 2, 4],
- itemStyle: { color: "#faad14" },
- animationDelay: (idx: number) => idx * 100 + 300,
- },
- {
- name: "低级报警",
- type: "bar",
- data: [8, 6, 7, 9, 5, 4, 6],
- itemStyle: { color: "#1890ff" },
- animationDelay: (idx: number) => idx * 100 + 600,
- },
- ],
- animationDuration: 1500,
- }
- // 实时监控仪表盘配置
- const gaugeOption: EChartsCoreOption = {
- series: [
- {
- name: "供水压力",
- type: "gauge",
- progress: {
- show: true,
- width: 18,
- },
- axisLine: {
- lineStyle: {
- width: 18,
- },
- },
- axisTick: {
- show: false,
- },
- splitLine: {
- length: 15,
- lineStyle: {
- width: 2,
- color: "#999",
- },
- },
- axisLabel: {
- distance: 25,
- color: "#999",
- fontSize: 12,
- },
- anchor: {
- show: true,
- showAbove: true,
- size: 25,
- itemStyle: {
- borderWidth: 10,
- },
- },
- title: {
- show: false,
- },
- detail: {
- valueAnimation: true,
- fontSize: 20,
- offsetCenter: [0, "70%"],
- },
- data: [
- {
- value: 0.65,
- name: "MPa",
- },
- ],
- },
- ],
- }
- // 仪表盘数据
- const dashboardStats = {
- totalFacilities: 156,
- normalFacilities: 142,
- warningFacilities: 8,
- alarmFacilities: 6,
- totalDevices: 324,
- onlineDevices: 298,
- offlineDevices: 26,
- todayAlarms: 12,
- processedAlarms: 9,
- pendingAlarms: 3,
- }
- const handleExport = (type: string) => {
- setLoading(true)
- setTimeout(() => {
- globalMessage.success(`${type}数据导出成功!`)
- setLoading(false)
- setExportModal(false)
- }, 2000)
- }
- const handleRefresh = () => {
- setLoading(true)
- setTimeout(() => {
- globalMessage.success("数据刷新成功!")
- setLoading(false)
- }, 1500)
- }
- const handleViewDetail = (record: any, type: string) => {
- setSelectedRecord(record)
- if (type === "facility") {
- setFacilityDetailModal(true)
- } else if (type === "device") {
- setDeviceDetailModal(true)
- }
- }
- const handleProcessAlarm = (record: any) => {
- setSelectedRecord(record)
- setModalVisible(true)
- }
- const handleThresholdSetting = () => {
- setThresholdModal(true)
- }
- const renderDashboard = () => (
- <div className="space-y-6">
- {/* 系统概览仪表盘 */}
- <Row gutter={[16, 16]}>
- <Col xs={24} sm={12} md={6}>
- <Card className="hover:shadow-lg transition-shadow duration-300">
- <Statistic
- title="供水设施总数"
- value={dashboardStats.totalFacilities}
- prefix={<CheckCircleOutlined style={{ color: "#1890ff" }} />}
- suffix="个"
- valueStyle={{ color: "#1890ff", fontSize: "24px", fontWeight: "bold" }}
- />
- </Card>
- </Col>
- <Col xs={24} sm={12} md={6}>
- <Card className="hover:shadow-lg transition-shadow duration-300">
- <Statistic
- title="正常运行"
- value={dashboardStats.normalFacilities}
- prefix={<CheckCircleOutlined style={{ color: "#52c41a" }} />}
- suffix="个"
- valueStyle={{ color: "#52c41a", fontSize: "24px", fontWeight: "bold" }}
- />
- </Card>
- </Col>
- <Col xs={24} sm={12} md={6}>
- <Card className="hover:shadow-lg transition-shadow duration-300">
- <Statistic
- title="预警设施"
- value={dashboardStats.warningFacilities}
- prefix={<ExclamationCircleOutlined style={{ color: "#faad14" }} />}
- suffix="个"
- valueStyle={{ color: "#faad14", fontSize: "24px", fontWeight: "bold" }}
- />
- </Card>
- </Col>
- <Col xs={24} sm={12} md={6}>
- <Card className="hover:shadow-lg transition-shadow duration-300">
- <Statistic
- title="报警设施"
- value={dashboardStats.alarmFacilities}
- prefix={<CloseCircleOutlined style={{ color: "#ff4d4f" }} />}
- suffix="个"
- valueStyle={{ color: "#ff4d4f", fontSize: "24px", fontWeight: "bold" }}
- />
- </Card>
- </Col>
- </Row>
- {/* 实时监控数据 */}
- <Row gutter={[16, 16]}>
- <Col xs={24} lg={16}>
- <Card title="长沙市供水管网实时监控地图" className="hover:shadow-lg transition-shadow duration-300">
- <div className="h-96">
- <WaterMap />
- </div>
- </Card>
- </Col>
- <Col xs={24} lg={8}>
- <Card title="实时供水压力" className="hover:shadow-lg transition-shadow duration-300">
- <EChart option={gaugeOption} style={{ height: 300 }} />
- </Card>
- </Col>
- </Row>
- {/* 图表展示 */}
- <Row gutter={[16, 16]}>
- <Col xs={24} lg={12}>
- <Card title="供水流量趋势" className="hover:shadow-lg transition-shadow duration-300">
- <EChart option={flowChartOption} />
- </Card>
- </Col>
- <Col xs={24} lg={12}>
- <Card title="管网压力分布" className="hover:shadow-lg transition-shadow duration-300">
- <EChart option={pressureChartOption} />
- </Card>
- </Col>
- </Row>
- <Card title="报警趋势统计" className="hover:shadow-lg transition-shadow duration-300">
- <EChart option={alarmTrendOption} />
- </Card>
- </div>
- )
- const renderContent = () => {
- switch (activeTab) {
- case "dashboard":
- return renderDashboard()
- case "facilities":
- return (
- <div className="space-y-6">
- {/* 统计卡片 */}
- <Row gutter={[16, 16]}>
- <Col xs={24} sm={12} md={6}>
- <Card className="hover:shadow-lg transition-all duration-300 hover:scale-105">
- <Statistic
- title="供水设施总数"
- value={25}
- prefix={<CheckCircleOutlined style={{ color: "#1890ff" }} />}
- valueStyle={{ color: "#1890ff" }}
- />
- </Card>
- </Col>
- <Col xs={24} sm={12} md={6}>
- <Card className="hover:shadow-lg transition-all duration-300 hover:scale-105">
- <Statistic
- title="正常运行"
- value={22}
- prefix={<ArrowUpOutlined />}
- valueStyle={{ color: "#52c41a" }}
- />
- </Card>
- </Col>
- <Col xs={24} sm={12} md={6}>
- <Card className="hover:shadow-lg transition-all duration-300 hover:scale-105">
- <Statistic
- title="预警状态"
- value={2}
- prefix={<ExclamationCircleOutlined />}
- valueStyle={{ color: "#faad14" }}
- />
- </Card>
- </Col>
- <Col xs={24} sm={12} md={6}>
- <Card className="hover:shadow-lg transition-all duration-300 hover:scale-105">
- <Statistic
- title="报警状态"
- value={1}
- prefix={<ArrowDownOutlined />}
- valueStyle={{ color: "#ff4d4f" }}
- />
- </Card>
- </Col>
- </Row>
- {/* 图表展示 */}
- <Row gutter={[16, 16]}>
- <Col xs={24} lg={12}>
- <Card title="供水流量趋势" className="hover:shadow-lg transition-shadow duration-300">
- <EChart option={flowChartOption} />
- </Card>
- </Col>
- <Col xs={24} lg={12}>
- <Card title="管网压力分布" className="hover:shadow-lg transition-shadow duration-300">
- <EChart option={pressureChartOption} />
- </Card>
- </Col>
- </Row>
- {/* 供水设施管理表格 */}
- <Card
- title="供水设施管理"
- className="hover:shadow-lg transition-shadow duration-300"
- extra={
- <Space>
- <Search placeholder="搜索设施" style={{ width: 200 }} />
- <Select defaultValue="all" style={{ width: 120 }}>
- <Option value="all">全部类型</Option>
- <Option value="水源地">水源地</Option>
- <Option value="水厂">水厂</Option>
- <Option value="泵站">泵站</Option>
- <Option value="管网">管网</Option>
- <Option value="大用户">大用户</Option>
- </Select>
- <Button
- type="primary"
- icon={<ExportOutlined />}
- onClick={() => setExportModal(true)}
- className="hover:scale-105 transition-transform duration-200"
- >
- 批量导出
- </Button>
- <Button
- icon={<SyncOutlined />}
- onClick={handleRefresh}
- loading={loading}
- className="hover:scale-105 transition-transform duration-200"
- >
- 刷新数据
- </Button>
- </Space>
- }
- >
- <Table
- columns={[
- { title: "设施名称", dataIndex: "name", key: "name" },
- { title: "设施类型", dataIndex: "type", key: "type" },
- { title: "位置", dataIndex: "location", key: "location" },
- {
- title: "运行状态",
- dataIndex: "status",
- key: "status",
- render: (status: string) => (
- <Badge
- status={status === "正常" ? "success" : status === "预警" ? "warning" : "error"}
- text={status}
- />
- ),
- },
- { title: "容量/长度", dataIndex: "capacity", key: "capacity" },
- {
- title: "操作",
- key: "action",
- render: (_, record) => (
- <Space>
- <Button
- size="small"
- icon={<EyeOutlined />}
- onClick={() => handleViewDetail(record, "facility")}
- className="hover:scale-110 transition-transform duration-200"
- >
- 详情
- </Button>
- <Button
- size="small"
- icon={<EditOutlined />}
- onClick={() => globalMessage.info("编辑功能开发中...")}
- className="hover:scale-110 transition-transform duration-200"
- >
- 编辑
- </Button>
- </Space>
- ),
- },
- ]}
- dataSource={facilitiesData}
- pagination={{ pageSize: 10 }}
- loading={loading}
- />
- </Card>
- {/* GIS一图展示 */}
- <Card title="供水设施一图展示" className="hover:shadow-lg transition-shadow duration-300">
- <div className="h-96">
- <WaterMap />
- </div>
- </Card>
- </div>
- )
- case "devices":
- return (
- <div className="space-y-6">
- {/* 设备统计 */}
- <Row gutter={[16, 16]}>
- <Col xs={24} sm={12} md={6}>
- <Card className="hover:shadow-lg transition-all duration-300 hover:scale-105">
- <Statistic
- title="监测设备总数"
- value={dashboardStats.totalDevices}
- prefix={<CheckCircleOutlined style={{ color: "#1890ff" }} />}
- valueStyle={{ color: "#1890ff" }}
- />
- </Card>
- </Col>
- <Col xs={24} sm={12} md={6}>
- <Card className="hover:shadow-lg transition-all duration-300 hover:scale-105">
- <Statistic
- title="在线设备"
- value={dashboardStats.onlineDevices}
- prefix={<CheckCircleOutlined style={{ color: "#52c41a" }} />}
- valueStyle={{ color: "#52c41a" }}
- />
- </Card>
- </Col>
- <Col xs={24} sm={12} md={6}>
- <Card className="hover:shadow-lg transition-all duration-300 hover:scale-105">
- <Statistic
- title="离线设备"
- value={dashboardStats.offlineDevices}
- prefix={<CloseCircleOutlined style={{ color: "#ff4d4f" }} />}
- valueStyle={{ color: "#ff4d4f" }}
- />
- </Card>
- </Col>
- <Col xs={24} sm={12} md={6}>
- <Card className="hover:shadow-lg transition-all duration-300 hover:scale-105">
- <Statistic
- title="故障设备"
- value={8}
- prefix={<ExclamationCircleOutlined style={{ color: "#faad14" }} />}
- valueStyle={{ color: "#faad14" }}
- />
- </Card>
- </Col>
- </Row>
- {/* 监测设备管理表格 */}
- <Card
- title="监测设备管理"
- className="hover:shadow-lg transition-shadow duration-300"
- extra={
- <Space>
- <Search placeholder="搜索设备" style={{ width: 200 }} />
- <Select defaultValue="all" style={{ width: 120 }}>
- <Option value="all">全部类型</Option>
- <Option value="流量计">流量计</Option>
- <Option value="压力计">压力计</Option>
- <Option value="漏失监测">漏失监测</Option>
- </Select>
- <Button
- type="primary"
- icon={<PlusOutlined />}
- onClick={() => globalMessage.info("添加设备功能开发中...")}
- className="hover:scale-105 transition-transform duration-200"
- >
- 添加设备
- </Button>
- <Button
- icon={<ExportOutlined />}
- onClick={() => setExportModal(true)}
- className="hover:scale-105 transition-transform duration-200"
- >
- 导出
- </Button>
- </Space>
- }
- >
- <Table
- columns={[
- { title: "设备名称", dataIndex: "name", key: "name" },
- { title: "设备类型", dataIndex: "type", key: "type" },
- { title: "安装位置", dataIndex: "location", key: "location" },
- {
- title: "运行状态",
- dataIndex: "status",
- key: "status",
- render: (status: string) => (
- <Badge
- status={
- status === "正常"
- ? "success"
- : status === "故障"
- ? "error"
- : status === "维修中"
- ? "processing"
- : "default"
- }
- text={status}
- />
- ),
- },
- { title: "最后维护", dataIndex: "lastMaintenance", key: "lastMaintenance" },
- {
- title: "操作",
- key: "action",
- render: (_, record) => (
- <Space>
- <Button
- size="small"
- icon={<EyeOutlined />}
- onClick={() => handleViewDetail(record, "device")}
- className="hover:scale-110 transition-transform duration-200"
- >
- 详情
- </Button>
- {record.status === "故障" && (
- <Button
- size="small"
- type="primary"
- onClick={() => globalMessage.success("维修派单已生成!")}
- className="hover:scale-110 transition-transform duration-200"
- >
- 派单
- </Button>
- )}
- </Space>
- ),
- },
- ]}
- dataSource={devicesData}
- pagination={{ pageSize: 10 }}
- loading={loading}
- />
- </Card>
- </div>
- )
- case "monitoring":
- return (
- <div className="space-y-6">
- {/* 运行监测表格 */}
- <Card
- title="运行监测数据"
- className="hover:shadow-lg transition-shadow duration-300"
- extra={
- <Space>
- <Search placeholder="搜索监测点" style={{ width: 200 }} />
- <Select defaultValue="all" style={{ width: 120 }}>
- <Option value="all">全部类型</Option>
- <Option value="流量">流量</Option>
- <Option value="压力">压力</Option>
- <Option value="漏失">漏失</Option>
- </Select>
- <Button
- icon={<SyncOutlined />}
- onClick={handleRefresh}
- loading={loading}
- className="hover:scale-105 transition-transform duration-200"
- >
- 实时刷新
- </Button>
- <Button
- icon={<ExportOutlined />}
- onClick={() => setExportModal(true)}
- className="hover:scale-105 transition-transform duration-200"
- >
- 导出数据
- </Button>
- </Space>
- }
- >
- <Table
- columns={[
- { title: "监测点位", dataIndex: "point", key: "point" },
- { title: "监测类型", dataIndex: "type", key: "type" },
- { title: "监测值", dataIndex: "value", key: "value" },
- {
- title: "状态",
- dataIndex: "status",
- key: "status",
- render: (status: string) => (
- <Badge
- status={status === "正常" ? "success" : status === "预警" ? "warning" : "error"}
- text={status}
- />
- ),
- },
- { title: "更新时间", dataIndex: "time", key: "time" },
- {
- title: "操作",
- key: "action",
- render: (_, record) => (
- <Space>
- <Button
- size="small"
- icon={<EyeOutlined />}
- onClick={() => globalMessage.info(`查看${record.point}历史数据`)}
- className="hover:scale-110 transition-transform duration-200"
- >
- 历史
- </Button>
- <Button
- size="small"
- onClick={() => globalMessage.info(`定位到${record.point}`)}
- className="hover:scale-110 transition-transform duration-200"
- >
- 定位
- </Button>
- </Space>
- ),
- },
- ]}
- dataSource={monitoringData}
- pagination={{ pageSize: 10 }}
- loading={loading}
- />
- </Card>
- </div>
- )
- case "alarms":
- return (
- <div className="space-y-6">
- {/* 报警统计 */}
- <Row gutter={[16, 16]}>
- <Col xs={24} sm={12} md={6}>
- <Card className="hover:shadow-lg transition-all duration-300 hover:scale-105">
- <Statistic
- title="今日报警总数"
- value={dashboardStats.todayAlarms}
- prefix={<CloseCircleOutlined style={{ color: "#ff4d4f" }} />}
- valueStyle={{ color: "#ff4d4f" }}
- />
- </Card>
- </Col>
- <Col xs={24} sm={12} md={6}>
- <Card className="hover:shadow-lg transition-all duration-300 hover:scale-105">
- <Statistic
- title="高级报警"
- value={dashboardStats.processedAlarms}
- prefix={<CloseCircleOutlined style={{ color: "#ff4d4f" }} />}
- valueStyle={{ color: "#ff4d4f" }}
- />
- </Card>
- </Col>
- <Col xs={24} sm={12} md={6}>
- <Card className="hover:shadow-lg transition-all duration-300 hover:scale-105">
- <Statistic
- title="中级报警"
- value={dashboardStats.pendingAlarms}
- prefix={<ExclamationCircleOutlined style={{ color: "#faad14" }} />}
- valueStyle={{ color: "#faad14" }}
- />
- </Card>
- </Col>
- <Col xs={24} sm={12} md={6}>
- <Card className="hover:shadow-lg transition-all duration-300 hover:scale-105">
- <Statistic
- title="低级报警"
- value={3} // 假设低级报警数量为3
- prefix={<CheckCircleOutlined style={{ color: "#1890ff" }} />}
- valueStyle={{ color: "#1890ff" }}
- />
- </Card>
- </Col>
- </Row>
- {/* 报警趋势图 */}
- <Card title="报警趋势统计" className="hover:shadow-lg transition-shadow duration-300">
- <EChart option={alarmTrendOption} />
- </Card>
- {/* 报警管理表格 */}
- <Card
- title="报警事件管理"
- className="hover:shadow-lg transition-shadow duration-300"
- extra={
- <Space>
- <Search placeholder="搜索报警" style={{ width: 200 }} />
- <Select defaultValue="all" style={{ width: 120 }}>
- <Option value="all">全部级别</Option>
- <Option value="high">高级</Option>
- <Option value="medium">中级</Option>
- <Option value="low">低级</Option>
- </Select>
- <Button
- type="primary"
- onClick={() => globalMessage.info("批量处理功能开发中...")}
- className="hover:scale-105 transition-transform duration-200"
- >
- 批量处理
- </Button>
- <Button
- onClick={handleThresholdSetting}
- className="hover:scale-105 transition-transform duration-200"
- >
- 阈值设置
- </Button>
- </Space>
- }
- >
- <Table
- columns={[
- { title: "报警位置", dataIndex: "location", key: "location" },
- { title: "报警类型", dataIndex: "type", key: "type" },
- {
- title: "报警级别",
- dataIndex: "level",
- key: "level",
- render: (level: string) => (
- <Tag color={level === "高级" ? "red" : level === "中级" ? "orange" : "blue"}>{level}</Tag>
- ),
- },
- {
- title: "处理状态",
- dataIndex: "status",
- key: "status",
- render: (status: string) => (
- <Badge
- status={status === "已处理" ? "success" : status === "处理中" ? "processing" : "default"}
- text={status}
- />
- ),
- },
- { title: "报警时间", dataIndex: "time", key: "time" },
- {
- title: "操作",
- key: "action",
- render: (_, record) => (
- <Space>
- <Button
- size="small"
- type="primary"
- onClick={() => handleProcessAlarm(record)}
- disabled={record.status === "已处理"}
- className="hover:scale-110 transition-transform duration-200"
- >
- 处理
- </Button>
- <Button
- size="small"
- onClick={() => handleViewDetail(record, "alarm")}
- className="hover:scale-110 transition-transform duration-200"
- >
- 详情
- </Button>
- </Space>
- ),
- },
- ]}
- dataSource={alarmsData}
- pagination={{ pageSize: 10 }}
- loading={loading}
- />
- </Card>
- {/* 报警一张图 */}
- <Card title="监测报警一张图" className="hover:shadow-lg transition-shadow duration-300">
- <div className="h-96">
- <WaterMap
- alarms={[
- { id: "1", position: [39.9242, 116.4274], level: "medium", message: "压力异常" },
- { id: "2", position: [39.9442, 116.4474], level: "high", message: "流量超限" },
- ]}
- />
- </div>
- </Card>
- </div>
- )
- default:
- return <div className="text-center py-20 text-gray-500">功能开发中...</div>
- }
- }
- return (
- <App className={'h-min-[100vh]'}>
- <AdminLayout activeKey={activeTab} onMenuSelect={setActiveTab}>
- {renderContent()}
- <Modal
- title="设施详细信息"
- open={facilityDetailModal}
- onCancel={() => setFacilityDetailModal(false)}
- footer={[
- <Button key="close" onClick={() => setFacilityDetailModal(false)}>
- 关闭
- </Button>,
- ]}
- width={600}
- >
- {selectedRecord && (
- <div className="space-y-4">
- <Row gutter={[16, 16]}>
- <Col span={12}>
- <div>
- <strong>设施名称:</strong>
- {selectedRecord.name}
- </div>
- </Col>
- <Col span={12}>
- <div>
- <strong>设施类型:</strong>
- {selectedRecord.type}
- </div>
- </Col>
- <Col span={12}>
- <div>
- <strong>位置:</strong>
- {selectedRecord.location}
- </div>
- </Col>
- <Col span={12}>
- <div>
- <strong>运行状态:</strong>
- <Badge
- status={
- selectedRecord.status === "正常"
- ? "success"
- : selectedRecord.status === "预警"
- ? "warning"
- : "error"
- }
- text={selectedRecord.status}
- />
- </div>
- </Col>
- <Col span={24}>
- <div>
- <strong>容量/规模:</strong>
- {selectedRecord.capacity || selectedRecord.length || selectedRecord.usage}
- </div>
- </Col>
- </Row>
- </div>
- )}
- </Modal>
- <Modal
- title="设备详细信息"
- open={deviceDetailModal}
- onCancel={() => setDeviceDetailModal(false)}
- footer={[
- <Button key="close" onClick={() => setDeviceDetailModal(false)}>
- 关闭
- </Button>,
- ]}
- width={600}
- >
- {selectedRecord && (
- <div className="space-y-4">
- <Row gutter={[16, 16]}>
- <Col span={12}>
- <div>
- <strong>设备名称:</strong>
- {selectedRecord.name}
- </div>
- </Col>
- <Col span={12}>
- <div>
- <strong>设备类型:</strong>
- {selectedRecord.type}
- </div>
- </Col>
- <Col span={12}>
- <div>
- <strong>安装位置:</strong>
- {selectedRecord.location}
- </div>
- </Col>
- <Col span={12}>
- <div>
- <strong>运行状态:</strong>
- <Badge
- status={
- selectedRecord.status === "正常"
- ? "success"
- : selectedRecord.status === "故障"
- ? "error"
- : selectedRecord.status === "维修中"
- ? "processing"
- : "default"
- }
- text={selectedRecord.status}
- />
- </div>
- </Col>
- <Col span={24}>
- <div>
- <strong>最后维护时间:</strong>
- {selectedRecord.lastMaintenance}
- </div>
- </Col>
- </Row>
- </div>
- )}
- </Modal>
- <Modal
- title="阈值设置"
- open={thresholdModal}
- onOk={() => {
- thresholdForm.validateFields().then(() => {
- globalMessage.success("阈值设置成功")
- setThresholdModal(false)
- thresholdForm.resetFields()
- })
- }}
- onCancel={() => {
- setThresholdModal(false)
- thresholdForm.resetFields()
- }}
- width={600}
- >
- <Form form={thresholdForm} layout="vertical">
- <Form.Item label="监测类型" name="type" rules={[{ required: true }]}>
- <Select>
- <Option value="flow">流量监测</Option>
- <Option value="pressure">压力监测</Option>
- <Option value="leak">漏失监测</Option>
- </Select>
- </Form.Item>
- <Row gutter={16}>
- <Col span={12}>
- <Form.Item label="预警阈值" name="warningThreshold" rules={[{ required: true }]}>
- <Input placeholder="请输入预警阈值" />
- </Form.Item>
- </Col>
- <Col span={12}>
- <Form.Item label="报警阈值" name="alarmThreshold" rules={[{ required: true }]}>
- <Input placeholder="请输入报警阈值" />
- </Form.Item>
- </Col>
- </Row>
- <Form.Item label="生效时间段" name="timeRange">
- <Select>
- <Option value="all">全天</Option>
- <Option value="peak">高峰时段</Option>
- <Option value="normal">正常时段</Option>
- </Select>
- </Form.Item>
- </Form>
- </Modal>
- <Modal
- title="数据导出"
- open={exportModal}
- onCancel={() => setExportModal(false)}
- footer={[
- <Button key="cancel" onClick={() => setExportModal(false)}>
- 取消
- </Button>,
- <Button key="export" type="primary" loading={loading} onClick={() => handleExport("当前页面")}>
- 确认导出
- </Button>,
- ]}
- >
- <div className="space-y-4">
- <div>
- <strong>导出格式:</strong>
- <Select defaultValue="excel" style={{ width: 120, marginLeft: 8 }}>
- <Option value="excel">Excel</Option>
- <Option value="csv">CSV</Option>
- <Option value="pdf">PDF</Option>
- </Select>
- </div>
- <div>
- <strong>导出范围:</strong>
- <Select defaultValue="current" style={{ width: 150, marginLeft: 8 }}>
- <Option value="current">当前页面</Option>
- <Option value="all">全部数据</Option>
- <Option value="selected">选中数据</Option>
- </Select>
- </div>
- </div>
- </Modal>
- {/* 处理报警模态框 */}
- <Modal
- title="处理报警事件"
- open={modalVisible}
- onOk={() => {
- form.validateFields().then(() => {
- globalMessage.success("报警处理成功")
- setModalVisible(false)
- form.resetFields()
- })
- }}
- onCancel={() => {
- setModalVisible(false)
- form.resetFields()
- }}
- className="hover:shadow-2xl transition-shadow duration-300"
- >
- <Form form={form} layout="vertical">
- <Form.Item label="处理结果" name="result" rules={[{ required: true }]}>
- <Select>
- <Option value="resolved">已解决</Option>
- <Option value="false_alarm">误报</Option>
- <Option value="pending">待进一步处理</Option>
- </Select>
- </Form.Item>
- <Form.Item label="处理意见" name="comment">
- <Input.TextArea rows={4} placeholder="请输入处理意见..." />
- </Form.Item>
- <Form.Item label="附件上传" name="attachment">
- <Upload>
- <Button icon={<UploadOutlined />}>上传附件</Button>
- </Upload>
- </Form.Item>
- </Form>
- </Modal>
- </AdminLayout>
- </App>
- )
- }
|