From 40531f9363394f86044431d2f8d7c1b5044873a7 Mon Sep 17 00:00:00 2001 From: tangshaojian <63377964@qq.com> Date: Tue, 21 Jan 2025 14:05:40 +0800 Subject: [PATCH] =?UTF-8?q?tsj:=20=E7=AE=A1=E5=BB=8A-main-PipeMap=20?= =?UTF-8?q?=E5=9C=B0=E5=9B=BE=EF=BC=9B=E8=A7=A3=E5=86=B3=E5=9C=B0=E5=9B=BE?= =?UTF-8?q?=E5=9B=BE=E4=BE=8B=E5=9B=BE=E5=B1=82=E7=9A=84=E6=8E=A7=E5=88=B6?= =?UTF-8?q?=EF=BC=8C=E4=BA=8C=E7=BA=A7=E5=9B=BE=E4=BE=8B=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E5=8D=95=E7=8B=AC=E6=8E=A7=E5=88=B6=E5=B1=95=E7=A4=BA\?= =?UTF-8?q?=E9=9A=90=E8=97=8F=EF=BC=9B=E4=BF=AE=E6=94=B9=E5=8F=B3=E4=BE=A7?= =?UTF-8?q?=E5=88=97=E8=A1=A8=E4=B8=8D=E8=83=BD=E6=BB=9A=E5=8A=A8=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=88=E5=8E=BB=E6=8E=89container=E7=9A=84?= =?UTF-8?q?overflow:=20hidden=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/assets/images/location.png | Bin 264 -> 1170 bytes .../modals/PipelinePassage/PipeMap/index.less | 73 ++-- .../modals/PipelinePassage/PipeMap/index.tsx | 413 +++++++++++++----- 3 files changed, 333 insertions(+), 153 deletions(-) diff --git a/src/assets/images/location.png b/src/assets/images/location.png index 064c05034a28571a91968c270482f9d2494c66c0..c678a7c66feed9b6d70aae9626b51c929d4c718a 100644 GIT binary patch literal 1170 zcmeAS@N?(olHy`uVBq!ia0y~yV9)_!4mJh`2Dz3fMg|53mSQK*5DpFwjv9`X4h9Am zPfr)ekcif+Gtc@@ahEx6zhCo<%Pa}emF>q^qHlNYF=4&5B&NbpXzeYNw@X7i6>>x` znT3Av7l`6_d+NHy^hVqlr^`~jPP0U+1sXR^SrE`^=Bp#t_Yp)J0Ei zVjM&zm%g9sy~}=DV#tF}mv3>*@sSA2nOpO7lbM_G2iAL4Uj2)&sL#_}_Ud~1%fkH! zI}SwqzZ7h}^~CV#grME~qWfK>qL}{p&Azt4L}k9#t}B-&++1tg{aZYwGk5JQW}cm4 z4J;v?@zS+@cWxgQnwJ`5aF}hM$E_)>Q}t4+nD%UTEnhgrwsz5rprvn?%H1`+?KjiB zz~F}b*5!LjPDC^BeEGp`*L8CP*5=C#9A2M&u#uII>A75edwFze`_>Y+$ZSi=fQ=`c zdzbyo%-GF&{XKj1^ROE~-8a^xGhF$UI6-~=iMHgW8xtAt#jw83cYbkIVWz{8?+di8}i2ER6^=0{WN%Ga46{-{;I^tVp;gj@lm$Nu)qZ^=Jg z`#GS3@s|7I+gAGACrr4qV{M8Sg|w`9OZc#UXW4I!mby>d%UQ!x*D{9fuz2bc$(Qan z?HjMp&)e)X9*P?J%XEv*EAg8YAo;*?QB!D|?%UOMckloERr_3oKZxa>)|#kw?(PzO zzjV6yM#fE)pTpF>eff>=v+8xi69nHaTi~N`T0i%pr^Ku;`ngl37Z%OjIO}-fUdfpT z9Ebh%9NIS@58B$Z`}Yc?oHb8pt$ut#h39Uuzs2fnh8dFF4>ES91zo?Oe5hyj`}Ej@ z3w|$WKE!3LpK>8tuSTI?#EQA)!Da1t7eejXPqH{Xf8kb{!f@n6?gfqcC5QD-H@utQ zRvX@&#u(cF@nn99`{uUL6MR*>Y{Op3PFBiHIMv+y*u?Hnb?1`Y<18zTXeKuLiYWm|~+9Z+iEZPHA0p zp!tXCtClcYOej#Pm;I63?Xve(Z{?#MF{)>e1t>VpxoWbiYHff)oZi`uJafCw8GpW& my>Z@5@$T-g^?P>x2#`e_^F4$H(+|8QB|8xcM6SR!KE-*qjzl zU<_*zaC-H2t;;GcD>tve;At|8Y~T9%pSl%v)^NShcBh?=8s#o`h1HKA-0#F#!GG;o z;GI`2SLbbK3B4M(^HON*)^w%+f43)|+aSF2*S5sU3GA}g+|MTEX}%Yn!Ta#n+AP@~ z=^w6gfBEG8$%^mxIV+^TH0fJy$SbL~U@fa%3H%;!XS8i86Q0KLHpQQ77yR0 T&v?VYz`)??>gTe~DWM4f^%`ag diff --git a/src/pages/GlobalModalServices/modals/PipelinePassage/PipeMap/index.less b/src/pages/GlobalModalServices/modals/PipelinePassage/PipeMap/index.less index 6ab7db41..04c1b037 100644 --- a/src/pages/GlobalModalServices/modals/PipelinePassage/PipeMap/index.less +++ b/src/pages/GlobalModalServices/modals/PipelinePassage/PipeMap/index.less @@ -3,7 +3,6 @@ width: 1346px; height: 723px; border-radius: 20px; - overflow: hidden; // position: relative; .mapTitle { @@ -166,7 +165,7 @@ margin-bottom: 8px; background: rgba(67, 177, 255, 0.08); border-radius: 18px; - overflow: hidden; + // overflow: hidden; .listItem { display: flex; @@ -233,41 +232,33 @@ margin-bottom: 12px; } - .layerGroup { - display: flex; - flex-direction: column; - gap: 12px; - } + :global { + .ant-tree { + background: transparent; + color: #CBEDFF; - .layerItem { - .subLayers { - margin-left: 12px; - margin-top: 8px; - display: flex; - flex-direction: column; - gap: 8px; - - .subLayerImg{ - width: 14px; - height: 16px; + .ant-tree-switcher { + display: none !important; // 添加此属性,隐藏展开/折叠按钮 } - } - .subLayer { - display: flex; - align-items: center; - gap: 8px; - color: rgb(203, 227, 240); - font-size: 16px; - font-weight: 400; - line-height: 21px; + .ant-tree-node-content-wrapper { + color: #CBEDFF; + } + + .ant-tree-checkbox { + .ant-tree-checkbox-inner { + background-color: transparent; + border-color: #CBEDFF; + } + } - .dot { - width: 8px; - height: 8px; - border-radius: 50%; + .ant-tree-checkbox-checked { + .ant-tree-checkbox-inner { + background-color: #1890ff; + border-color: #1890ff; + } } - } + } } } } @@ -383,4 +374,22 @@ } } +.subLayer { + display: flex; + align-items: center; + gap: 8px; + cursor: pointer; + + .dot { + width: 18px; + height: 18px; + border-radius: 50%; + } + + .subLayerImg { + width: 14px; + height: 16px; + } +} + diff --git a/src/pages/GlobalModalServices/modals/PipelinePassage/PipeMap/index.tsx b/src/pages/GlobalModalServices/modals/PipelinePassage/PipeMap/index.tsx index e2cd3e72..4e95f877 100644 --- a/src/pages/GlobalModalServices/modals/PipelinePassage/PipeMap/index.tsx +++ b/src/pages/GlobalModalServices/modals/PipelinePassage/PipeMap/index.tsx @@ -1,6 +1,6 @@ import CooglMap from '@/components/CooglMap'; import services from '@/services'; -import { Checkbox, } from 'antd'; +import { Checkbox, Tree } from 'antd'; import React, { useEffect, useRef, useState } from 'react'; import locationIcon from '@/assets/images/location.png'; import pipeMapDetail from '@/assets/images/pipe-map-detail.png'; @@ -11,6 +11,7 @@ import pipeMapCenter1 from '@/assets/images/pipe-map-center-1.png'; import pipeMapCenter2 from '@/assets/images/pipe-map-center-2.png'; import styles from './index.less'; import type { TabsProps } from 'antd'; +import type { DataNode } from 'antd/es/tree'; // 添加类型定义 interface PipelineType { @@ -35,6 +36,110 @@ const Map: React.FC = () => { // 修改默认展开状态为空数组(都收起) const [expandedTypes, setExpandedTypes] = useState([]); + // 修改状态结构,记录每个类型的显示状态 + // const [selectedSubLayers, setSelectedSubLayers] = useState>({ + // '干线': true, + // '支线': true, + // '小型': true, + // '缆线': true + // }); + + // 修改为使用 Tree 的选中状态管理 + const [checkedKeys, setCheckedKeys] = useState([ + 'pipeline', 'monitor', 'pipeline-干线', 'pipeline-支线', 'pipeline-小型', 'pipeline-缆线' + ]); + + // 将管廊数据按类型分组 + const groupedPipelines = pipelineData.reduce((acc: any, cur: any) => { + const type = cur.lx || '其他'; + if (!acc[type]) { + acc[type] = []; + } + acc[type].push({ + id: cur.id, + name: cur.mc, + ...cur + }); + return acc; + }, {}); + + // 修改 pipelineTypes 的定义,添加数量显示 + const pipelineTypes: PipelineType[] = [ + { + type: '干线', + name: '干线', + items: groupedPipelines['干线'] || [], + expanded: expandedTypes.includes('干线'), + count: groupedPipelines['干线']?.length || 0 + }, + { + type: '支线', + name: '支线', + items: groupedPipelines['支线'] || [], + expanded: expandedTypes.includes('支线'), + count: groupedPipelines['支线']?.length || 0 + }, + { + type: '小型', + name: '小型', + items: groupedPipelines['小型'] || [], + expanded: expandedTypes.includes('小型'), + count: groupedPipelines['小型']?.length || 0 + }, + { + type: '缆线', + name: '缆线', + items: groupedPipelines['缆线'] || [], + expanded: expandedTypes.includes('缆线'), + count: groupedPipelines['缆线']?.length || 0 + } + ]; + + // 构建 Tree 的数据结构 + const treeData: DataNode[] = [ + { + title: '管廊', + key: 'pipeline', + children: pipelineTypes.map(type => ({ + title: ( +
+ + {type.name} +
+ ), + key: `pipeline-${type.type}`, + })), + }, + { + title: '监控中心', + key: 'monitor', + children: [ + { + title: ( +
+ + 总控中心 +
+ ), + key: 'monitor-总控', + }, + { + title: ( +
+ + 分控中心 +
+ ), + key: 'monitor-分控', + }, + ], + }, + ]; + // 获取管廊基本信息 const getPipelineData = async (lx?: string) => { try { @@ -109,7 +214,6 @@ const Map: React.FC = () => { getPipelineData(); getPipelineCoords(); }, []); - // 绘制管廊路线 const drawPipelines = () => { @@ -122,16 +226,44 @@ const Map: React.FC = () => { if (!item.processedCoordinates?.length) return; // 使用CooglMap的Polyline组件绘制线 - return ( - handlePipelineClick(item)} - /> - ); + // return ( + // handlePipelineClick(item)} + // /> + // ); + return drawPipelinesFromCoord(item); }); }; + + // 绘制管廊路线 + const drawPipelinesFromCoord = (item: any) => { + + // 找到对应的管廊基本信息 + const pipelineInfo = pipelineData.find(p => p.mc === item.gridName); + const type = pipelineInfo?.lx; + + // 只渲染有类型且类型被选中的线路 + if (!type || !checkedKeys.includes(`pipeline-${type}`)) { + return null; + } + + return ( + handlePipelineClick(item)} + /> + ); + }; // 监听选中图层变化时重新绘制 useEffect(() => { @@ -181,15 +313,53 @@ const Map: React.FC = () => { } }; - // 处理图层切换 - const handleLayerChange = (values: string[]) => { - setSelectedLayers(values); - }; + // 处理子图层选择变化 + // const handleSubLayerChange = (type: string, checked: boolean) => { + // setSelectedSubLayers(prev => ({ + // ...prev, + // [type]: checked + // })); + + // // 根据类型筛选显示管廊 + // if (mapRef.current) { + // pipelineCoords.forEach((item: any) => { + // const layerName = `pipeline-${item.id}`; + // const layer = mapRef.current.getLayer(layerName); + // if (layer && item.lx === type) { + // layer.setVisible(checked); + // } + // }); + // } + // }; + + // 处理一级图层选择变化 + // const handleLayerChange = (checkedValues: string[]) => { + // setSelectedLayers(checkedValues); + + // // 如果取消选中管廊,则隐藏所有子图层 + // if (!checkedValues.includes('pipeline')) { + // setSelectedSubLayers(prev => + // Object.keys(prev).reduce((acc, key) => ({ + // ...acc, + // [key]: false + // }), {}) + // ); + // } + // // 如果选中管廊,则显示所有子图层 + // else if (checkedValues.includes('pipeline')) { + // setSelectedSubLayers(prev => + // Object.keys(prev).reduce((acc, key) => ({ + // ...acc, + // [key]: true + // }), {}) + // ); + // } + // }; // 处理图例点击 - const handleLegendClick = (type: string) => { - getPipelineData(type); - }; + // const handleLegendClick = (type: string) => { + // getPipelineData(type); + // }; // 处理详情点击 const handleDetailClick = (item: any) => { @@ -203,52 +373,6 @@ const Map: React.FC = () => { // TODO: 打开详情弹窗 }; - // 将管廊数据按类型分组 - const groupedPipelines = pipelineData.reduce((acc: any, cur: any) => { - const type = cur.lx || '其他'; - if (!acc[type]) { - acc[type] = []; - } - acc[type].push({ - id: cur.id, - name: cur.mc, - ...cur - }); - return acc; - }, {}); - - // 修改 pipelineTypes 的定义,添加数量显示 - const pipelineTypes: PipelineType[] = [ - { - type: '干线', - name: '干线', - items: groupedPipelines['干线'] || [], - expanded: expandedTypes.includes('干线'), - count: groupedPipelines['干线']?.length || 0 - }, - { - type: '支线', - name: '支线', - items: groupedPipelines['支线'] || [], - expanded: expandedTypes.includes('支线'), - count: groupedPipelines['支线']?.length || 0 - }, - { - type: '小型', - name: '小型', - items: groupedPipelines['小型'] || [], - expanded: expandedTypes.includes('小型'), - count: groupedPipelines['小型']?.length || 0 - }, - { - type: '缆线', - name: '缆线', - items: groupedPipelines['缆线'] || [], - expanded: expandedTypes.includes('缆线'), - count: groupedPipelines['缆线']?.length || 0 - } - ]; - // 处理类型展开/收起 const toggleTypeExpand = (type: string) => { setExpandedTypes(prev => @@ -282,12 +406,59 @@ const Map: React.FC = () => { handleLocationClick(item); }; + // 处理 Tree 选中变化 + const onCheck = (checked: any) => { + // console.log('==>checked', checked); + + // 如果取消选中管廊总图层,同时取消所有子图层 + if (selectedLayers.includes('pipeline') && !checked.includes('pipeline')) { + const newChecked = checked.filter((key: string) => !key.startsWith('pipeline')); + setCheckedKeys(newChecked); + setSelectedLayers(newChecked); + return; + } + + // 如果选中管廊总图层,同时选中所有子图层 + if (!selectedLayers.includes('pipeline') && checked.includes('pipeline')) { + const allPipelineKeys = pipelineTypes.map(type => `pipeline-${type.type}`); + setCheckedKeys([...checked, ...allPipelineKeys]); + setSelectedLayers(checked.filter((key: string) => !key.includes('-'))); + return; + } + + // 正常更新选中状态 + setCheckedKeys(checked); + setSelectedLayers(checked.filter((key: string) => !key.includes('-'))); + }; + + // 过滤需要显示的管廊数据 + const filteredPipelineCoords = pipelineCoords.filter(item => { + // 首先检查是否选中了管廊图层 + if (!selectedLayers.includes('pipeline')) return false; + + // 找到对应的管廊基本信息来获取类型 + const pipelineInfo = pipelineData.find(p => p.mc === item.gridName); + const type = pipelineInfo?.lx; + + // 检查该类型是否被选中 + const typeKey = `pipeline-${type}`; + // console.log('==>item', { + // gridName: item.gridName, + // type, + // typeKey, + // isChecked: checkedKeys.includes(typeKey), + // checkedKeys + // }); + + // 只有当类型存在且该类型被选中时才显示 + return type && checkedKeys.includes(typeKey); + }); + return (
@@ -295,30 +466,56 @@ const Map: React.FC = () => {
管廊分布
{/* 管廊路线图层 */} - {selectedLayers.includes('pipeline') && pipelineCoords?.map((item: any, index: number) => { - if (!item?.processedCoordinates?.length) return null; - + {filteredPipelineCoords.map((item: any) => { // 找到对应的管廊基本信息 - const pipelineInfo = pipelineData.find(p => p.mc === item.gridName); - const type = pipelineInfo?.lx; - // const type = pipelineInfo?.lx || '其他'; + // const pipelineInfo = pipelineData.find(p => p.mc === item.gridName); + // const type = pipelineInfo?.lx; - // 根据类型设置不同颜色 - const color = type === '干线' ? '#AD6BFF' : - type === '支线' ? '#FDFFC6' : - type === '小型' ? '#6FDCFF' : '#4874FF'; - - return ( - handlePipelineClick(item)} - /> - ); + // // 只渲染有类型且类型被选中的线路 + // if (!type || !checkedKeys.includes(`pipeline-${type}`)) { + // return null; + // } + + // return ( + // handlePipelineClick(item)} + // /> + // ); + return drawPipelinesFromCoord(item); })} + {/* 监控中心图层 */} + {selectedLayers.includes('monitor') && ( + <> + {/* {checkedKeys.includes('monitor-总控') && ( + + )} + {checkedKeys.includes('monitor-分控') && ( + + )} */} + + )} + {/* 选中管廊的信息展示 */} {selectedPipeline && ( { {/* 图层控制 */}
图层图例
- -
-
- 管廊 -
- {pipelineTypes.map(type => ( -
handleLegendClick(type.type)} - style={{ cursor: 'pointer' }} - > - - {type.name} -
- ))} -
-
-
- 监控中心 -
-
- - 总控中心 -
-
- - 分控中心 -
-
-
-
-
+ onCheck(checked.checked)} + // onCheck={checked => onCheck(checked.checked)} + treeData={treeData} + defaultExpandAll + // showLine={false} // 添加此属性,隐藏展开/折叠按钮 + // switcherIcon={
} // 添加此属性,隐藏展开/折叠按钮 -- 自定义树节点的展开/折叠图标(带有默认 rotate 角度样式) + />
{/* 右侧列表 */} -- GitLab