浏览代码

fix: 物候期分布选中显示

lxf 1 周之前
父节点
当前提交
f3011c57a1
共有 2 个文件被更改,包括 327 次插入50 次删除
  1. 281 16
      src/views/warningHome/index.vue
  2. 46 34
      src/views/warningHome/map/distributionLayer.js

+ 281 - 16
src/views/warningHome/index.vue

@@ -52,6 +52,7 @@
             </div>
             <div class="action-legend">
                 <el-tree
+                    ref="treeRef"
                     class="yes-events"
                     style="max-width: 250px"
                     :data="treeActionData"
@@ -169,6 +170,7 @@ let distributionLayer = null;
 const areaVal = ref(["3"]);
 const mapRef = ref(null);
 const showDetail = ref(false);
+const treeRef = ref(null);
 const defaultProps = {
     children: "children",
     label: "label",
@@ -184,7 +186,7 @@ import lb from "@/assets/images/map/type/小麦.png";
 import coldChainIcon from "@/assets/images/common/legend-icon-1.png";
 import factoryIcon from "@/assets/images/common/legend-icon-2.png";
 
-const treeActionData = ref([
+const originTreeData = [
     {
         id: 1,
         label: "果类",
@@ -287,24 +289,204 @@ const treeActionData = ref([
             },
         ],
     },
-]);
+];
 
-// 物候期分布下,“水稻”节点的阶段子节点配置
-const phenologyChildren = [
+const phenologyData = [
     {
-        id: 10,
-        label: "拔节期",
+        id: 1,
+        label: "果类",
+        color: "#51B2FF",
+        fillColor: "rgba(5, 49, 84, 0.5)",
+        geom: "MULTIPOLYGON (((113.58668302396221 23.244659822289524, 113.32095411231998 23.24298858095617, 112.99338890476295 23.002328435946534, 113.13878785387456 22.604570799124076, 113.59503930394511 22.86862839611681, 113.58668302396221 23.244659822289524)))",
+        children: [
+            {
+                id: 4,
+                label: "荔枝",
+                color: "#2199F8",
+                imgUrl: "https://birdseye-img.sysuimars.com/temp/pz/%E8%8D%94%E6%9E%9D.png",
+                imgName: lz,
+                children: [
+                    {
+                        id: 13,
+                        label: "秋梢期",
+                        color: "#58B5FF",
+                        imgName: lz,
+                        wktArr: [
+                            "POINT(113.33722309500006 23.204074978290652)",
+                            "POINT(113.53593237057355 23.188789823486065)",
+                        ],
+                    },
+                    {
+                        id: 14,
+                        label: "膨果期",
+                        color: "#1688E3",
+                        imgName: lz,
+                        wktArr: [
+                            "POINT(113.32095411231998 23.24298858095617)",
+                        ],
+                    },
+                    {
+                        id: 15,
+                        label: "成熟期",
+                        color: "#3D8CCB",
+                        imgName: lz,
+                        wktArr: [
+                            "POINT(113.36970447853234 23.064596505297875)",
+                        ],
+                    },
+                ],
+            },
+            {
+                id: 55,
+                label: "龙眼",
+                color: "#2199F8",
+                imgUrl: "https://birdseye-img.sysuimars.com/temp/pz/%E7%99%BD%E7%B3%96.png",
+                imgName: ly,
+                children: [
+                    {
+                        id: 16,
+                        label: "秋梢期",
+                        color: "#5986AA",
+                        imgName: ly,
+                        wktArr: [
+                            "POINT(113.29900983080294 22.949956545068478)",
+                            "POINT(113.10412186488536 22.800924630297875)",
+                        ],
+                    },
+                    {
+                        id: 17,
+                        label: "膨果期",
+                        color: "#79ABD3",
+                        imgName: ly,
+                        wktArr: [
+                            "POINT(113.32384842738536 22.776086033715462)",
+                            "POINT(113.22640444442656 22.90983245840535)",
+                        ],
+                    },
+                ],
+            },
+        ],
     },
     {
-        id: 11,
-        label: "孕穗期",
+        id: 2,
+        label: "粮食",
+        color: "#FF8E1C",
+        fillColor: "rgba(83, 46, 8, 0.5)",
+        geom: "MULTIPOLYGON (((112.42256410334443 23.14863707066071, 112.09584019992684 22.842930537988664, 112.25060416300033 22.62511471413565, 112.80278650958275 22.749307864685775, 112.75119857777094 23.13144100957107, 112.42256410334443 23.14863707066071)))",
+        children: [
+            {
+                id: 5,
+                label: "水稻",
+                color: "#FAA53D",
+                imgUrl: "https://birdseye-img.sysuimars.com/temp/pz/%E6%8C%82%E7%BB%BF.png",
+                imgName: sd,
+                children: [
+                    {
+                        id: 10,
+                        label: "拔节期",
+                        color: "#985400",
+                        imgName: sd,
+                        wktArr: [
+                            "POINT(112.36777193304151 22.73892833157863)",
+                        ],
+                    },
+                    {
+                        id: 11,
+                        label: "孕穗期",
+                        color: "#512D00",
+                        imgName: sd,
+                        wktArr: [
+                            "POINT(112.26684873669083 22.71150357559281)",
+                        ],
+                    },
+                    {
+                        id: 12,
+                        label: "抽穗期",
+                        color: "#DD871D",
+                        imgName: sd,
+                        wktArr: [
+                            "POINT(112.65408646638161 22.84862740364581)",
+                        ],
+                    },
+                ],
+            },
+            {
+                id: 6,
+                label: "小麦",
+                color: "#FAA53D",
+                imgUrl: "https://birdseye-img.sysuimars.com/temp/pz/%E6%97%A0%E6%A0%B8.png",
+                imgName: xm,
+                children: [
+                    {
+                        id: 18,
+                        label: "拔节期",
+                        color: "#FAA53D",
+                        imgName: xm,
+                        wktArr: [
+                            "POINT(112.36777193304151 22.73892833157863)",
+                        ],
+                    },
+                ],
+            },
+        ],
     },
     {
-        id: 12,
-        label: "抽穗期",
+        id: 3,
+        label: "蔬菜",
+        color: "#25BC07",
+        fillColor: "rgba(0, 69, 4, 0.5)",
+        children: [
+            {
+                id: 7,
+                label: "白菜",
+                color: "#7ABB00",
+                imgUrl: "https://birdseye-img.sysuimars.com/temp/pz/%E7%99%BD%E8%8F%9C.png",
+                imgName: bc,
+                children: [
+                    {
+                        id: 19,
+                        label: "拔节期",
+                        color: "#7ABB00",
+                        imgName: bc,
+                        wktArr: [
+                            "POINT(110.34100329503417 21.516399336978793)",
+                            "POINT(113.89499662443995 22.653799122199416)",
+                            "POINT(113.9329988323152 22.653600638732314)",
+                            "POINT(113.94400024786592 22.614900553599)",
+                        ],
+                    },
+                ],
+            },
+            {
+                id: 8,
+                label: "萝卜",
+                color: "#7ABB00",
+                imgUrl: "https://birdseye-img.sysuimars.com/temp/pz/%E8%90%9D%E8%8F%9C.png",
+                imgName: lb,
+                children: [
+                    {
+                        id: 20,
+                        label: "拔节期",
+                        color: "#7ABB00",
+                        imgName: lb,
+                        wktArr: [
+                            "POINT(110.34100329503417 21.516399336978793)",
+                            "POINT(113.89499662443995 22.653799122199416)",
+                            "POINT(113.9329988323152 22.653600638732314)",
+                            "POINT(113.94400024786592 22.614900553599)",
+                        ],
+                    },
+                ],
+            },
+        ],
     },
 ];
 
+const treeActionData = ref(originTreeData);
+
+// 物候期分布下,当前激活的“二级”节点(只允许一个)
+const activePhenologySecondId = ref(null);
+
 // 树的默认展开与默认选中(展开/选中第一个“果类”及其子节点)
 const defaultExpandedKeys = ref([treeActionData.value[0]?.id]);
 const defaultCheckedKeys = ref([
@@ -387,6 +569,15 @@ const handleDistributionLayer = () => {
     }
 };
 
+// 物候期分布默认选中并展开第一个节点,在地图上显示对应分布图层
+const handlePhenologyLayer = () => {
+    const firstCategory = treeActionData.value[0].children[0];
+    if (firstCategory) {
+        const defaultNodes = [firstCategory, ...(firstCategory.children[0]?.children || [])];
+        distributionLayer.initData(defaultNodes);
+    }
+};
+
 // ai与地图交互
 const hideChatMapLayer = ref(true);
 const handleMapLayer = ({ mapName, isHome }) => {
@@ -434,16 +625,20 @@ const handleTabClick = (item) => {
     staticMapLayers && staticMapLayers.hideAll();
     // 通知预警列表组件清空默认选中项
     eventBus.emit("warningHome:clearAlarm");
+    treeActionData.value = originTreeData;
 
     switch (item) {
         case "作物分布":
             handleDistributionLayer();
             break;
         case "物候期分布":
-            treeActionData.value[1].children[0] = {
-                ...treeActionData.value[1].children[0],
-                children: phenologyChildren,
-            };
+            defaultCheckedKeys.value = [
+                treeActionData.value[0]?.children[0]?.id,
+                ...(treeActionData.value[0]?.children[0]?.children?.map((c) => c.id) || []),
+            ];
+            defaultExpandedKeys.value = [treeActionData.value[0]?.children[0]?.id];
+            treeActionData.value = phenologyData;
+            handlePhenologyLayer();
             break;
         case "预警分布":
             // 通知预警列表组件默认选中第一个(因子)项
@@ -564,8 +759,78 @@ const remoteMethod = async (keyword) => {
     }
 };
 
-const getTreeChecks = (node, data) => {
-    distributionLayer.initData(data.checkedNodes);
+// 根据节点 id 在当前树数据中计算其层级(1/2/3)及所属的二级节点 id
+const getNodeLevelInfo = (id) => {
+    const roots = treeActionData.value || [];
+    for (const root of roots) {
+        if (root.id === id) {
+            return { level: 1, secondId: null };
+        }
+        if (root.children) {
+            for (const second of root.children) {
+                if (second.id === id) {
+                    return { level: 2, secondId: second.id };
+                }
+                if (second.children) {
+                    for (const third of second.children) {
+                        if (third.id === id) {
+                            return { level: 3, secondId: second.id };
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return { level: 0, secondId: null };
+};
+
+const getTreeChecks = (nodeData, data) => {
+    const { checkedNodes } = data;
+    let finalCheckedNodes = checkedNodes;
+
+    // 物候期分布:限制“二级只能选一个,三级不限个数”
+    if (activeBaseTab.value === "物候期分布" && treeRef.value) {
+        const tree = treeRef.value;
+        const { level, secondId } = getNodeLevelInfo(nodeData.id);
+
+        if (level === 2 || level === 3) {
+            const currentSecondId = secondId;
+
+            // 判断当前这个二级分支下,是否还有被选中的节点(包含二级自己或其子级)
+            const hasAnyCheckedInCurrentSecond = checkedNodes.some((n) => {
+                const info = getNodeLevelInfo(n.id);
+                return info.secondId === currentSecondId || (info.level === 2 && n.id === currentSecondId);
+            });
+
+            if (hasAnyCheckedInCurrentSecond) {
+                // 仍有节点被选中 → 保证只有当前这个二级分支被选中,其它分支全部取消
+                activePhenologySecondId.value = currentSecondId;
+
+                const roots = treeActionData.value || [];
+                roots.forEach((root) => {
+                    (root.children || []).forEach((second) => {
+                        if (second.id !== currentSecondId) {
+                            // 取消其它二级及其所有子级勾选
+                            tree.setChecked(second.id, false, true);
+                        } else {
+                            // 保持当前二级选中,子级按用户选择
+                            tree.setChecked(second.id, true, false);
+                        }
+                    });
+                });
+            } else {
+                // 当前二级分支已经被全部取消勾选 → 清空激活记录,允许“全部不选”
+                activePhenologySecondId.value = null;
+            }
+        }
+        // 对树进行了 setChecked 操作后,重新从树组件拿一次最新的选中节点列表
+        // 这里只需要最后一层(叶子节点 / 有 wktArr 的节点),不用父级节点
+        const allCheckedNodes = treeRef.value.getCheckedNodes(false, true);
+        finalCheckedNodes = allCheckedNodes.filter((n) => !n.children || n.children.length === 0 || n.wktArr);
+    }
+
+    // 任意 tab 下,最终都用当前选中的节点驱动地图渲染
+    distributionLayer.initData(finalCheckedNodes);
 };
 </script>
 

+ 46 - 34
src/views/warningHome/map/distributionLayer.js

@@ -144,45 +144,57 @@ class DistributionLayer {
   }
 
   initData(data) {
-    let that = this;
-    // 每次加载前先清空旧数据(多用于“作物分布”)
+    // 每次加载前先清空旧数据(多用于“作物分布 / 物候期分布 / 农场分布”)
     this.clear();
-        for (let item of data) {
-            if (item.geom) {
-                const f = new Feature({
-                    geometry: new WKT().readGeometry(item.geom),
-                });
-                f.set("color", item.color);
-                f.set("fillColor", item.fillColor);
-                this.distributionLayer.source.addFeature(f);
-            }
 
-            if (item.wktArr) {
-                for (let wkt of item.wktArr) {
-                    const f = new Feature({
-                        geometry: new WKT().readGeometry(wkt),
-                    });
-                    f.set("imgUrl", item.imgUrl);
-                    f.set("imgName", item.imgName);
-                    f.set("label", item.label);
-                    f.set("color", item.color);
-                    // 农场名称,用于点位下方显示
-                    if (item.farmName) {
-                        f.set("farmName", item.farmName);
-                    }
-                    this.distributionPointLayer.source.addFeature(f);
-                }
-            }
+    const addPointFeaturesFromNode = (node) => {
+      // 如果当前节点本身有 wktArr,则直接用当前节点的数据画点
+      if (node.wktArr) {
+        for (let wkt of node.wktArr) {
+          const f = new Feature({
+            geometry: new WKT().readGeometry(wkt),
+          });
+          f.set("imgName", node.imgName);
+          f.set("label", node.label);
+          f.set("color", node.color);
+          if (node.farmName) {
+            f.set("farmName", node.farmName);
+          }
+          this.distributionPointLayer.source.addFeature(f);
         }
+      }
 
-        // 所有点位添加完成后,地图范围自适应到包含 distributionPointLayer 的所有点
-        const pointExtent = this.distributionPointLayer.source.getExtent();
-        if (pointExtent && !isNaN(pointExtent[0])) {
-            this.kmap.map.getView().fit(pointExtent, {
-                padding: [280, 400, 200, 150],
-                duration: 500,
-            });
+      // 否则如果有 children,就在 children 这一层继续找
+      if (node.children) {
+        for (let child of node.children) {
+          addPointFeaturesFromNode(child);
         }
+      }
+    };
+
+    for (let item of data) {
+      // 面数据(区域多边形)
+      if (item.geom) {
+        const f = new Feature({
+          geometry: new WKT().readGeometry(item.geom),
+        });
+        f.set("color", item.color);
+        f.set("fillColor", item.fillColor);
+        this.distributionLayer.source.addFeature(f);
+      }
+
+      // 点数据:根据是否有 children / wktArr 递归查找
+      addPointFeaturesFromNode(item);
+    }
+
+    // 所有点位添加完成后,地图范围自适应到包含 distributionPointLayer 的所有点
+    const pointExtent = this.distributionPointLayer.source.getExtent();
+    if (pointExtent && !isNaN(pointExtent[0])) {
+      this.kmap.map.getView().fit(pointExtent, {
+        padding: [280, 400, 200, 150],
+        duration: 500,
+      });
+    }
   }
 
   /**