"use client"; import React, { useMemo, useState } from "react"; import { Box, Button, Card, CardContent, Chip, Collapse, FormControlLabel, Checkbox, IconButton, Tooltip, Typography, } from "@mui/material"; import { Info as InfoIcon } from "@mui/icons-material"; import { DatePicker } from "@mui/x-date-pickers/DatePicker"; import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider"; import { AdapterDayjs } from "@mui/x-date-pickers/AdapterDayjs"; import "dayjs/locale/zh-cn"; import dayjs, { Dayjs } from "dayjs"; import { useNotification } from "@refinedev/core"; import { api } from "@/lib/api"; import { NETWORK_NAME, config } from "@config/config"; import { useControllableObjectState } from "@components/olmap/core/useControllableState"; import { LeakageResultDetail, LeakageSchemeRecord } from "./types"; import { FLOW_DISPLAY_UNIT, toM3h } from "@utils/units"; interface Props { onViewResult: (result: LeakageResultDetail) => void; schemes?: LeakageSchemeRecord[]; onSchemesChange?: (schemes: LeakageSchemeRecord[]) => void; state?: DMALeakSchemeQueryState; onStateChange?: (state: DMALeakSchemeQueryState) => void; } export interface DMALeakSchemeQueryState { queryAll: boolean; queryDate: Dayjs | null; expandedId: number | null; } export const createDMALeakSchemeQueryState = (): DMALeakSchemeQueryState => ({ queryAll: true, queryDate: dayjs(), expandedId: null, }); const SchemeQuery: React.FC = ({ onViewResult, schemes: externalSchemes, onSchemesChange, state, onStateChange, }) => { const { open } = useNotification(); const [queryState, , setQueryField] = useControllableObjectState( state, onStateChange, createDMALeakSchemeQueryState(), ); const { queryAll, queryDate, expandedId } = queryState; const [internalSchemes, setInternalSchemes] = useState([]); const [loading, setLoading] = useState(false); const schemes = externalSchemes !== undefined ? externalSchemes : internalSchemes; const setSchemes = onSchemesChange || setInternalSchemes; const sortedSchemes = useMemo( () => schemes .slice() .sort( (a, b) => dayjs(b.create_time).valueOf() - dayjs(a.create_time).valueOf(), ), [schemes], ); const handleQuery = async () => { setLoading(true); try { const params: Record = { network: NETWORK_NAME }; if (!queryAll && queryDate) { params.query_date = queryDate.startOf("day").toISOString(); } const response = await api.get(`${config.BACKEND_URL}/api/v1/leakage/schemes/`, { params, }); const nextSchemes = response.data as LeakageSchemeRecord[]; setSchemes(nextSchemes); if (nextSchemes.length === 0) { open?.({ type: "error", message: "查询结果", description: queryAll ? "没有找到任何方案" : `${queryDate?.format("YYYY-MM-DD")} 没有找到相关方案`, }); } else { open?.({ type: "success", message: "查询成功", description: `共找到 ${nextSchemes.length} 条方案记录`, }); } } catch (error: any) { open?.({ type: "error", message: "查询失败", description: error?.response?.data?.detail ?? "无法获取方案列表", }); } finally { setLoading(false); } }; const handleViewSchemeResult = async (schemeName: string) => { try { const response = await api.get( `${config.BACKEND_URL}/api/v1/leakage/schemes/${encodeURIComponent(schemeName)}`, { params: { network: NETWORK_NAME } }, ); onViewResult(response.data as LeakageResultDetail); } catch (error: any) { open?.({ type: "error", message: "查看详情失败", description: error?.response?.data?.detail ?? "无法获取方案详情", }); } }; return ( setQueryField("queryAll", e.target.checked)} /> } label={查询全部} className="m-0" /> setQueryField("queryDate", value)} disabled={queryAll} format="YYYY-MM-DD" slotProps={{ textField: { size: "small", sx: { width: 200 } } }} /> {sortedSchemes.length === 0 ? ( 总共 0 条 No data ) : ( 共 {sortedSchemes.length} 条记录 {sortedSchemes.map((scheme) => ( {scheme.scheme_name} ID: {scheme.scheme_id} · 日期: {dayjs(scheme.create_time).format("MM-DD")} setQueryField( "expandedId", expandedId === scheme.scheme_id ? null : scheme.scheme_id, ) } color="primary" className="p-1" > 分区数量: {String((scheme.scheme_detail as any)?.result_summary?.area_count ?? "-")} 用户: {scheme.username || "-"} 最大漏损: {(() => { const value = Number((scheme.scheme_detail as any)?.result_summary?.max_leakage); const maxLeakageM3h = toM3h(value, "m3/s"); return Number.isFinite(maxLeakageM3h) ? `${maxLeakageM3h.toFixed(3)} ${FLOW_DISPLAY_UNIT}` : "-"; })()} 总漏损流量: {(() => { const value = Number((scheme.scheme_detail as any)?.algorithm_params?.q_sum); const unit = String( (scheme.scheme_detail as any)?.algorithm_params?.q_sum_unit || "m3/s", ); const qSumM3h = toM3h(value, unit); return Number.isFinite(qSumM3h) ? `${qSumM3h.toFixed(3)} ${FLOW_DISPLAY_UNIT}` : "-"; })()} 方案时间: {dayjs(scheme.scheme_start_time || scheme.create_time).format("YYYY-MM-DD HH:mm")} ))} )} ); }; export default SchemeQuery;