Bläddra i källkod

fix: 物候期分布,农服管理

lxf 6 dagar sedan
förälder
incheckning
b26230b681

+ 267 - 0
src/views/warningHome/components/serviceList.vue

@@ -0,0 +1,267 @@
+<template>
+    <div class="service-list">
+        <div class="chart-title">
+            <div class="name">
+                <img src="@/assets/images/common/chart-icon.png" alt="" />
+                <span>农服管理</span>
+            </div>
+        </div>
+        <div class="service-content">
+            <div class="service-item"
+                v-for="(item, index) in serviceList"
+                @click="handleServiceClick(item, index)"
+                :class="{ active: activeService === index }"
+                :key="index">
+                <div class="service-header">
+                    <div class="service-image">
+                        <img :src="item.image || 'https://birdseye-img.sysuimars.com/dinggou-mini/defalut-icon.png'" alt="" />
+                    </div>
+                    <div class="service-info">
+                        <div class="service-title-row">
+                            <div class="service-title">{{ item.name }}</div>
+                            <div class="service-tags">
+                                <span class="tag" v-for="(tag, tagIndex) in item.tags" :key="tagIndex">{{ tag }}</span>
+                            </div>
+                        </div>
+                        <div class="service-location">
+                            <div class="location-item">
+                                <span class="location-label">主体位置:</span>
+                                <span class="location-value">{{ item.mainLocation }}</span>
+                            </div>
+                            <div class="location-item">
+                                <span class="location-label">农场位置:</span>
+                                <span class="location-value">{{ item.farmLocation }}</span>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+                <div class="service-stats">
+                    <div class="stat-box">
+                        <div class="stat-value"><span class="stat-value-num">{{ item.serviceArea }}</span><span class="stat-unit">亩</span></div>
+                        <div class="stat-label">服务亩数</div>
+                    </div>
+                    <div class="stat-box">
+                        <div class="stat-value"><span class="stat-value-num">{{ item.deviceCount }}</span><span class="stat-unit">个</span></div>
+                        <div class="stat-label">设备数量</div>
+                    </div>
+                    <div class="stat-box">
+                        <div class="stat-value"><span class="stat-value-num">{{ item.teamMembers }}</span><span class="stat-unit">人</span></div>
+                        <div class="stat-label">团队成员</div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { ref } from "vue";
+
+// 默认图片
+const defaultImage = "https://via.placeholder.com/120x120";
+
+// 服务列表数据
+const serviceList = ref([
+    {
+        name: "农资名称名称农资名称名称农资名称名称",
+        tags: ["荔枝", "井岗红糯"],
+        mainLocation: "广东省广州市荔湾区开发大道",
+        farmLocation: "广东省广州市荔湾区",
+        serviceArea: "1585",
+        deviceCount: "1585",
+        teamMembers: "500",
+    },
+    {
+        name: "农资名称名称",
+        tags: ["荔枝", "井岗红糯"],
+        mainLocation: "广东省广州市***",
+        farmLocation: "广东省广州市***",
+        serviceArea: "1585",
+        deviceCount: "1585",
+        teamMembers: "500",
+    },
+    {
+        name: "农资名称名称",
+        tags: ["荔枝", "井岗红糯"],
+        mainLocation: "广东省广州市***",
+        farmLocation: "广东省广州市***",
+        serviceArea: "1585",
+        deviceCount: "1585",
+        teamMembers: "500",
+    },
+]);
+
+const activeService = ref(null);
+const handleServiceClick = (item, index) => {
+    activeService.value = index;
+};
+</script>
+
+<style lang="scss" scoped>
+.service-list {
+    width: 100%;
+    height: 100%;
+    background: #232323;
+    border-radius: 4px;
+    box-sizing: border-box;
+    border: 1px solid #444444;
+    display: flex;
+    flex-direction: column;
+    overflow: hidden;
+
+    .chart-title {
+        width: 100%;
+        height: 38px;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        background: rgba(255, 255, 255, 0.05);
+        padding-right: 12px;
+        box-sizing: border-box;
+        flex: none;
+        .name {
+            display: flex;
+            align-items: center;
+            padding: 0 12px;
+            span {
+                font-size: 18px;
+                margin-left: 6px;
+                font-family: "SOURCEHANTIFINE";
+                margin-right: 8px;
+            }
+        }
+    }
+
+    .service-content {
+        flex: 1;
+        overflow-y: auto;
+        padding: 10px;
+        box-sizing: border-box;
+
+        .service-item {
+            border: 0.3px solid rgba(239, 239, 239, 0.2);
+            border-radius: 5px;
+            margin-bottom: 12px;
+            padding: 10px;
+            box-sizing: border-box;
+            cursor: pointer;
+            &.active {
+                background: rgba(23, 15, 0, 0.55);
+                border-color: #FFD489;
+                .service-stats .stat-box {
+                    border-color: #FFD489;
+                }
+            }
+
+            &:last-child {
+                margin-bottom: 0;
+            }
+
+            .service-header {
+                display: flex;
+                margin-bottom: 12px;
+
+                .service-image {
+                    width: 64px;
+                    height: 64px;
+                    flex-shrink: 0;
+                    border-radius: 6px;
+                    margin-right: 12px;
+
+                    img {
+                        width: 100%;
+                        height: 100%;
+                        border-radius: 6px;
+                        object-fit: cover;
+                    }
+                }
+
+                .service-info {
+                    flex: 1;
+                    display: flex;
+                    flex-direction: column;
+                    justify-content: space-between;
+
+                    .service-title-row {
+                        display: flex;
+                        align-items: center;
+                        margin-bottom: 4px;
+
+                        .service-title {
+                            font-size: 16px;
+                            font-weight: 500;
+                            color: #fff;
+                            flex: 1;
+                            padding-right: 8px;
+                            word-wrap: break-word;
+                            word-break: break-all;
+                            line-height: 1.4;
+                        }
+
+                        .service-tags {
+                            display: flex;
+                            gap: 4px;
+
+                            .tag {
+                                padding: 1px 6px;
+                                border: 0.2px solid #FFD489;
+                                border-radius: 2px;
+                                font-size: 12px;
+                                color: #FFD489;
+                            }
+                        }
+                    }
+
+                    .service-location {
+                        display: flex;
+                        flex-direction: column;
+                        color: #9F9F9F;
+
+                        .location-item {
+                            font-size: 12px;
+
+                            .location-label {
+                                margin-right: 8px;
+                            }
+                        }
+                    }
+                }
+            }
+
+            .service-stats {
+                display: flex;
+                gap: 12px;
+
+                .stat-box {
+                    flex: 1;
+                    background: rgba(255, 255, 255, 0.05);
+                    border: 0.3px solid rgba(255, 212, 137, 0.1);
+                    border-radius: 2px;
+                    padding: 8px 4px;
+                    text-align: center;
+                    box-sizing: border-box;
+
+                    .stat-value {
+                        color: #fff;
+                        margin-bottom: 2px;
+                        .stat-value-num {
+                            font-size: 20px;
+                            font-family: "PangMenZhengDao";
+                            color: #fff;
+                        }
+                        .stat-unit {
+                            font-size: 12px;
+                            padding-left: 2px;
+                        }
+                    }
+
+                    .stat-label {
+                        font-size: 12px;
+                        color: rgba(255, 255, 255, 0.7);
+                    }
+                }
+            }
+        }
+    }
+}
+</style>

+ 103 - 212
src/views/warningHome/index.vue

@@ -72,13 +72,16 @@
                     </template>
                 </el-tree>
             </div>
-            <div v-if="!showDetail" class="warning-r right chart-wrap yes-events">
+            <div v-if="panelType === 0" class="warning-r right chart-wrap yes-events">
                 <chart-list :activeBaseTab="activeBaseTab"></chart-list>
                 <!-- <farmInfoGroup></farmInfoGroup> -->
             </div>
-            <div v-else class="warning-r right yes-events">
+            <div v-if="panelType === 1" class="warning-r right yes-events">
                 <farmInfoGroup></farmInfoGroup>
             </div>
+            <div v-if="panelType === 2" class="warning-r right yes-events">
+                <service-list></service-list>
+            </div>
             <!-- 地图图例 -->
             <map-legend :type="activeBaseTab"></map-legend>
             <!-- 地图搜索 -->
@@ -144,6 +147,7 @@ import { useStore } from "vuex";
 import farmInfoGroup from "./components/farmInfoGroup.vue";
 import mapLegend from "./components/mapLegend.vue";
 import chartList from "./components/chart_components/chartList.vue";
+import serviceList from "./components/serviceList.vue";
 
 let store = useStore();
 
@@ -154,7 +158,8 @@ let staticMapPointLayers = null;
 let distributionLayer = null;
 const areaVal = ref([]);
 const mapRef = ref(null);
-const showDetail = ref(false);
+// 0:图表(作物分布,物候期分布,预警分布),1:农场分布,2:农服管理
+const panelType = ref(0);
 const treeRef = ref(null);
 
 // 区域作物面积和产量数据
@@ -177,198 +182,10 @@ 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 phenologyData = [
-    {
-        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: 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: 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([]);
+// 保存原始数据,用于恢复
+const originalTreeData = ref([]);
 
 // 物候期分布下,当前激活的“二级”节点(只允许一个)
 const activePhenologySecondId = ref(null);
@@ -436,6 +253,11 @@ onMounted(async () => {
     // ai与地图交互
     eventBus.off("chat:showMapLayer", handleMapLayer);
     eventBus.on("chat:showMapLayer", handleMapLayer);
+    
+    // 时间轴
+    eventBus.on("weatherTime:changeTime", ({index}) => {
+        handleTimeChange(index)
+    })
 
     // 注意:getRegionCropAreaYield 会在省级列表加载完成后自动调用(在 lazyLoad 中)
     // 如果 areaVal 已经有值,则立即调用
@@ -444,6 +266,10 @@ onMounted(async () => {
     }
 });
 
+const handleTimeChange = (index) => {
+    console.log('index', index);
+}
+
 const getRegionCropAreaYield = async (adminCode) => {
     const code = adminCode || (areaVal.value && areaVal.value.length > 0 ? areaVal.value[areaVal.value.length - 1] : '156440000');
     
@@ -485,29 +311,40 @@ const handleDistributionTreeDefault = () => {
 
 // 物候期分布默认选中并展开第一个节点,在地图上显示对应分布图层
 const handlePhenologyLayer = async () => {
-    const firstCategory = treeActionData.value[0].children[0];
+    const firstCategory = treeActionData.value[0].items[0];
     getCommonMapData(firstCategory);
 };
 
 // 物候期分布树形结构默认展开与默认选中
 const handlePhenologyTreeDefault = () => {
-    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];
+    const firstSecondLevel = treeActionData.value[0]?.items?.[0];
+    if (!firstSecondLevel) return;
+    
+    const secondLevelId = firstSecondLevel.id;
+    const thirdLevelIds = firstSecondLevel.items?.map((c) => c.id) || [];
+    
+    defaultCheckedKeys.value = [secondLevelId, ...thirdLevelIds];
+    defaultExpandedKeys.value = [firstSecondLevel.items[0].id];
+    
+    // 手动设置选中和展开状态
+    nextTick(() => {
+        if (treeRef.value) {
+            // 设置选中(包括第二级和所有第三级)
+            treeRef.value.setCheckedKeys([secondLevelId, ...thirdLevelIds]);
+        }
+    });
 };
 
 // 预警分布默认选中并展开第一个节点,在地图上显示对应分布图层
 const handleAlarmLayer = async () => {
-    const firstCategory = treeActionData.value[0].children[0];
+    const firstCategory = treeActionData.value[0].items[0];
     getCommonMapData(firstCategory);
 };
 
 // 预警分布树形结构默认展开与默认选中
 const handleAlarmTreeDefault = () => {
     defaultCheckedKeys.value = [
-        treeActionData.value[0]?.children[0]?.id
+        treeActionData.value[0]?.items[0]?.id
     ];
     defaultExpandedKeys.value = [treeActionData.value[0]?.id];
 };
@@ -530,8 +367,14 @@ const getCommonMapData = async (firstCategory) => {
         };
         
         const lastLevelNodes = getLastLevelNodes(firstCategory);
+        if (activeBaseTab.value === "物候期分布") {
+            // 等待接口返回数据
+            const lastLevelIds = lastLevelNodes.map((n) => n.originalId);
+            const phenologyData = await getDistributionData(null, lastLevelIds);
+            distributionLayer.initData(phenologyData, 'phenologyName');
+            return;
+        }
         const lastLevelIds = lastLevelNodes.map((n) => n.id);
-        
         // 并发请求所有数据
         const promises = lastLevelIds.map((id) => getDistributionData(id));
         const results = await Promise.all(promises);
@@ -582,29 +425,59 @@ const handleTabClick = (item) => {
     if (distributionLayer) {
         distributionLayer.clear();
     }
+    panelType.value = 0;
     // 所有操作前,先清空图层和选中项
     legendImg.value = "";
     staticMapLayers && staticMapLayers.hideAll();
     // 通知预警列表组件清空默认选中项
     eventBus.emit("warningHome:clearAlarm");
     // 使用 nextTick 确保树组件数据更新后再设置选中状态
-    nextTick(() => {
         if (treeRef.value) {
+            defaultCheckedKeys.value = [];
+            defaultExpandedKeys.value = [];
             // 先清空所有选中项
             treeRef.value.setCheckedKeys([]);
-            // 再设置新的选中项
-            treeRef.value.setCheckedKeys(defaultCheckedKeys.value);
         }
-    });
 
     switch (item) {
         case "作物分布":
+            // 恢复原始数据
+            if (originalTreeData.value.length > 0) {
+                treeActionData.value = JSON.parse(JSON.stringify(originalTreeData.value));
+            }
             handleDistributionTreeDefault();
             handleDistributionLayer();
             break;
         case "物候期分布":
-            treeActionData.value = phenologyData;
-            handlePhenologyTreeDefault()
+            // 先恢复原始数据,再修改第二级 children 的 items 字段为 phenologies
+            if (originalTreeData.value.length > 0) {
+                treeActionData.value = JSON.parse(JSON.stringify(originalTreeData.value));
+            }
+            // 修改第二级 children 的 items 字段为 phenologies,不修改其他项
+            treeActionData.value = treeActionData.value.map((firstLevel) => {
+                if (firstLevel.items && Array.isArray(firstLevel.items)) {
+                    return {
+                        ...firstLevel,
+                        items: firstLevel.items.map((secondLevel) => {
+                            // 如果第二级有 phenologies 字段,将其设置为 items
+                            if (secondLevel.phenologies) {
+                                secondLevel.phenologies.forEach((phenology) => {
+                                    phenology.originalId = phenology.id;
+                                    phenology.id = 'phenology_' + phenology.id;
+                                });
+                                return {
+                                    ...secondLevel,
+                                    items: secondLevel.phenologies,
+                                };
+                            }
+                            return secondLevel;
+                        }),
+                    };
+                }
+                return firstLevel;
+            });
+            console.log('222222222222treeActionData.value', treeActionData.value);
+            handlePhenologyTreeDefault();
             handlePhenologyLayer();
             break;
         case "预警分布":
@@ -614,6 +487,7 @@ const handleTabClick = (item) => {
             eventBus.emit("warningHome:activeFirstAlarmFactor");
             break;
         case "农场分布":
+            panelType.value = 1;
             const cropData = [
                 {
                     id: 4,
@@ -661,6 +535,9 @@ const handleTabClick = (item) => {
             distributionLayer.initData(cropData);
             distributionLayer.initFacilityData(facilityData);
             break;
+        case "农服管理":
+            panelType.value = 2;
+            break;
         default:
             break;
     }
@@ -669,13 +546,16 @@ const handleTabClick = (item) => {
 const getSpeciesListData = async () => {
     const res = await VE_API.species.speciesList();
     treeActionData.value = res.data;
+    // 保存原始数据副本(深拷贝)
+    originalTreeData.value = JSON.parse(JSON.stringify(res.data));
 };
 
-const getDistributionData = async (speciesId) => {
+const getDistributionData = async (speciesId, phenologyIds) => {
     const {data} = await VE_API.agri_land_crop.queryDistribution({
         year: 2025,
         quarter: 1,
-        speciesId
+        speciesId,
+        phenologyIds: phenologyIds || []
     });
     return data;
 };
@@ -880,10 +760,19 @@ const getTreeChecks = async (nodeData, data) => {
 
     // 任意 tab 下,最终都用当前选中的节点驱动地图渲染
     // 提取最后一级节点的 id 到数组(没有子节点的叶子节点)
+    const field = activeBaseTab.value === "物候期分布" ? "originalId" : "id";
     const lastLevelIds = finalCheckedNodes
         .filter((n) => (!n.items || n.items.length === 0) && (!n.children || n.children.length === 0))
-        .map((n) => n.id);
-    
+        .map((n) => n[field]);
+    if (lastLevelIds && lastLevelIds.length === 0) {
+        distributionLayer.initData([]);
+        return;
+    }
+    if (activeBaseTab.value === "物候期分布") {
+        const phenologyData = await getDistributionData(null, lastLevelIds);
+        distributionLayer.initData(phenologyData, 'phenologyName');
+        return;
+    }
     // 并发请求所有数据,等待所有 Promise 完成
     const promises = lastLevelIds.map((id) => {
         const node = finalCheckedNodes.find((n) => n.id === id);
@@ -954,6 +843,8 @@ const getTreeChecks = async (nodeData, data) => {
             align-items: baseline;
             ::v-deep {
                 .el-tree {
+                    max-height: 400px;
+                    overflow: auto;
                     background: #232323;
                     border: 1px solid #444444;
                     border-radius: 5px;

+ 7 - 6
src/views/warningHome/map/distributionLayer.js

@@ -16,7 +16,7 @@ class DistributionLayer {
         this.distributionLayer = new KMap.VectorLayer("distributionLayer", 99, {
             source: new VectorSource({}),
             style: function (f) {
-                let style2 = vectorStyle.getPolygonStyle(f.get("fillColor"), f.get("color"), 2)
+                let style2 = vectorStyle.getPolygonStyle(f.get("color")+'4d', f.get("color"), 2)
                 return [style2]
             }
         });
@@ -25,7 +25,7 @@ class DistributionLayer {
         this.distributionPointLayer = new KMap.VectorLayer("distributionPointLayer", 99, {
             source: new VectorSource({}),
             style: function (f) {
-                const label = f.get("speciesName") || "";
+                const label = f.get("label") || "";
                 const baseColor = f.get("color") || "#2199F8";
                 const farmName = f.get("farmName") || "";
                 const imgName = f.get("imgName") || "";
@@ -141,20 +141,21 @@ class DistributionLayer {
         }
     }
 
-    initData(data) {
+    initData(data, field = 'speciesName') {
         // 每次加载前先清空旧数据(多用于“作物分布 / 物候期分布 / 农场分布”)
         this.clear();
+        if(!data || data.length === 0) return;
 
         for (let item of data) {
             // 面数据(区域多边形)
             if (item.geom) {
-                item.color = item.color || "#2199F8";
-                item.fillColor = item.fillColor || "rgba(0, 69, 4, 0.5)";
+                item.color = item.speciesColor || "#2199F8";
                 this.distributionLayer.source.addFeature(newPolymerFeature(item));
             }
             if (item.centerPoint) {
-                item.color = item.color || "#2199F8";
+                item.color = item.speciesColor || "#2199F8";
                 item.wkt = item.centerPoint;
+                item.label = item[field] || "";
                 this.distributionPointLayer.source.addFeature(newPoint(item));
             }
         }