"use client"; import React, { useCallback, useEffect, useState } from "react"; import { Box, Drawer, Tabs, Tab, Typography, IconButton, Tooltip, CircularProgress, } from "@mui/material"; import { ChevronRight, ChevronLeft, Sensors as SensorsIcon, Analytics as AnalyticsIcon, Search as SearchIcon, TableView as TableIcon, } from "@mui/icons-material"; import OptimizationParameters, { createOptimizationParametersState, type OptimizationParametersState, } from "./OptimizationParameters"; import SchemeQuery, { createMonitoringSchemeQueryState, type MonitoringSchemeQueryState, } from "./SchemeQuery"; import SchemeEditor from "./SchemeEditor"; import { getSensorPlacementScheme } from "./schemeApi"; import type { SchemeRecord, SensorPlacementScheme } from "./types"; import { NETWORK_NAME } from "@/config/config"; import { useNotification } from "@refinedev/core"; import PanelEmptyState from "@components/olmap/common/PanelEmptyState"; interface TabPanelProps { children?: React.ReactNode; index: number; value: number; } const TabPanel: React.FC = ({ children, value, index }) => { return ( ); }; const PANEL_MOTION_DURATION_MS = 280; const PANEL_MOTION_EASING = "cubic-bezier(0.4, 0, 0.2, 1)"; export const getTabIndicatorTransform = (tabIndex: number) => `translateX(${tabIndex * 100}%)`; export const getTabIndicatorSx = (tabIndex: number) => ({ backgroundColor: "#257DD4", left: "0 !important", width: "33.333333% !important", transform: getTabIndicatorTransform(tabIndex), transition: `transform ${PANEL_MOTION_DURATION_MS}ms ${PANEL_MOTION_EASING}`, "@media (prefers-reduced-motion: reduce)": { transition: "none", }, }); interface PreparedSchemeEditorProps extends React.ComponentProps { onReady?: () => void; } const PreparedSchemeEditor: React.FC = ({ onReady, ...props }) => { useEffect(() => { onReady?.(); }, [onReady]); return ; }; interface MonitoringPlaceOptimizationPanelProps { open?: boolean; onToggle?: () => void; } const MonitoringPlaceOptimizationPanel: React.FC< MonitoringPlaceOptimizationPanelProps > = ({ open: controlledOpen, onToggle }) => { const [internalOpen, setInternalOpen] = useState(true); const [currentTab, setCurrentTab] = useState(0); const [activeScheme, setActiveScheme] = useState(null); const [loadingScheme, setLoadingScheme] = useState(false); const [pendingOpenSchemeId, setPendingOpenSchemeId] = useState( null, ); const { open: notify } = useNotification(); // 持久化方案查询结果 const [schemes, setSchemes] = useState([]); const [optimizationState, setOptimizationState] = useState(createOptimizationParametersState); const [queryState, setQueryState] = useState( createMonitoringSchemeQueryState, ); // 使用受控或非受控状态 const isOpen = controlledOpen !== undefined ? controlledOpen : internalOpen; const handleToggle = () => { if (onToggle) { onToggle(); } else { setInternalOpen(!internalOpen); } }; const handleTabChange = (_event: React.SyntheticEvent, newValue: number) => { setCurrentTab(newValue); }; const drawerWidth = currentTab === 1 ? 820 : 520; const handleSchemeEditorReady = useCallback(() => { setCurrentTab(1); setPendingOpenSchemeId(null); }, []); const handleOpenScheme = async (schemeId: number) => { setLoadingScheme(true); try { const scheme = await getSensorPlacementScheme(schemeId); setActiveScheme(scheme); setLoadingScheme(false); setPendingOpenSchemeId(scheme.id); } catch (error) { const detail = (error as { response?: { data?: { detail?: string } } }).response?.data ?.detail || "无法读取方案详情"; notify?.({ type: "error", message: "方案加载失败", description: detail, }); setLoadingScheme(false); } }; const handleSchemeSaved = (scheme: SensorPlacementScheme) => { setActiveScheme(scheme); setSchemes((current) => current.map((record) => record.id === scheme.id ? { ...record, sensorNumber: scheme.sensor_number, sensorLocation: scheme.sensor_location, } : record, ), ); }; return ( <> {/* 收起时的触发按钮 */} {!isOpen && ( 监测点优化 )} {/* 主面板 */} {/* 头部 */} 监测点优化 {/* Tabs 导航 */} } iconPosition="start" label="优化要件" /> } iconPosition="start" label="结果编辑" /> } iconPosition="start" label="方案查询" /> {/* Tab 内容 */} { setActiveScheme(scheme); setCurrentTab(1); setSchemes((current) => [ ...current, { id: scheme.id, schemeName: scheme.scheme_name, sensorNumber: scheme.sensor_number, minDiameter: scheme.min_diameter, username: scheme.username, create_time: scheme.create_time, sensorLocation: scheme.sensor_location, }, ]); }} /> {loadingScheme ? ( ) : activeScheme ? ( ) : ( } title="暂无可编辑结果" description="请先在“优化要件”中创建方案,或在“方案查询”中打开已有方案。" /> )} ); }; export default MonitoringPlaceOptimizationPanel;