|
|
@@ -7,7 +7,6 @@
|
|
|
<div class="top-l yes-events">
|
|
|
<div>
|
|
|
<el-cascader
|
|
|
- ref="cascaderRef"
|
|
|
style="width: 184px"
|
|
|
:show-all-levels="false"
|
|
|
v-model="areaVal"
|
|
|
@@ -17,78 +16,20 @@
|
|
|
/>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="top-r yes-events" v-show="activeBaseTab !== '作物分布'">
|
|
|
- <div class="data-box" :class="{ active: activeBoxName === '面积' }">
|
|
|
- <div class="data-value">
|
|
|
- <span>{{ regionCropData.plantArea }}</span
|
|
|
- >亩
|
|
|
- </div>
|
|
|
- <div class="data-name">种植面积</div>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- class="data-box"
|
|
|
- v-if="areaVal.includes('3186')"
|
|
|
- :class="{ active: activeBoxName === '从化荔枝' }"
|
|
|
- >
|
|
|
- <div class="data-value"><span>11.9</span>万亩</div>
|
|
|
- <div class="data-name">疑似失管面积</div>
|
|
|
- </div>
|
|
|
- <div class="data-box" :class="{ active: activeBoxName === '产量' }">
|
|
|
- <div class="data-value">
|
|
|
- <span>{{ regionCropData.expectYield }}</span
|
|
|
- >吨
|
|
|
- </div>
|
|
|
- <div class="data-name">预估产量</div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class="warning-alarm yes-events" v-show="activeBaseTab === '预警分布'">
|
|
|
- <alarm-list></alarm-list>
|
|
|
</div>
|
|
|
- <div v-show="activeBaseTab !== '农服管理' && activeBaseTab !== '农场分布'" class="time-wrap yes-events">
|
|
|
+ <div class="time-wrap yes-events">
|
|
|
<time-line></time-line>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="action-legend" v-if="activeBaseTab !== '农服管理'">
|
|
|
- <el-tree
|
|
|
- ref="treeRef"
|
|
|
- class="yes-events"
|
|
|
- style="max-width: 250px"
|
|
|
- :data="treeActionData"
|
|
|
- show-checkbox
|
|
|
- node-key="id"
|
|
|
- :default-expanded-keys="defaultExpandedKeys"
|
|
|
- :default-checked-keys="defaultCheckedKeys"
|
|
|
- :props="defaultProps"
|
|
|
- @check="getTreeChecks"
|
|
|
- >
|
|
|
- <template #default="{ node, data }">
|
|
|
- <div class="custom-tree-node">
|
|
|
- <span>{{ node.label }}</span>
|
|
|
- <div v-if="node.level === 1" class="level-legend">
|
|
|
- <span class="legend-dot" :style="{ backgroundColor: data.color }"></span>
|
|
|
- <span class="legend-text" :style="{ color: data.color }">图例</span>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </template>
|
|
|
- </el-tree>
|
|
|
- </div>
|
|
|
- <div v-if="panelType === 0" class="warning-r right chart-wrap yes-events">
|
|
|
+ <div class="warning-r right chart-wrap yes-events">
|
|
|
<chart-list
|
|
|
:activeBaseTab="activeBaseTab"
|
|
|
:areaCode="selectedAreaCode"
|
|
|
:areaName="selectedAreaName"
|
|
|
></chart-list>
|
|
|
- <!-- <farmInfoGroup></farmInfoGroup> -->
|
|
|
- </div>
|
|
|
- <div v-if="panelType === 1" class="warning-r right yes-events">
|
|
|
- <farmInfoGroup :farmList="farmList"></farmInfoGroup>
|
|
|
- </div>
|
|
|
- <div v-if="panelType === 2" class="warning-r right yes-events">
|
|
|
- <service-list></service-list>
|
|
|
</div>
|
|
|
<!-- 地图图例 -->
|
|
|
- <map-legend :type="activeBaseTab"></map-legend>
|
|
|
+ <!-- <map-legend :type="activeBaseTab"></map-legend> -->
|
|
|
<!-- 地图搜索 -->
|
|
|
<div class="warning-search yes-events">
|
|
|
<el-select
|
|
|
@@ -118,17 +59,6 @@
|
|
|
</el-option>
|
|
|
</el-select>
|
|
|
</div>
|
|
|
- <div class="base-tabs yes-events">
|
|
|
- <div
|
|
|
- v-for="item in baseTabs"
|
|
|
- :key="item"
|
|
|
- class="tab-item"
|
|
|
- :class="{ active: item === activeBaseTab }"
|
|
|
- @click="handleTabClick(item)"
|
|
|
- >
|
|
|
- {{ item }}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div ref="mapRef" class="bottom-map"></div>
|
|
|
@@ -145,14 +75,10 @@ import WarningMap from "./warningMap";
|
|
|
import AlarmLayer from "./map/alarmLayer";
|
|
|
import DistributionLayer from "./map/distributionLayer";
|
|
|
import trackDialog from "./components/trackDialog.vue";
|
|
|
-import alarmList from "./components/alarmList.vue";
|
|
|
import timeLine from "./components/timeLine.vue";
|
|
|
import eventBus from "@/api/eventBus";
|
|
|
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();
|
|
|
|
|
|
@@ -163,24 +89,8 @@ let staticMapPointLayers = null;
|
|
|
let distributionLayer = null;
|
|
|
const areaVal = ref([]);
|
|
|
const mapRef = ref(null);
|
|
|
-// 0:图表(作物分布,物候期分布,预警分布),1:农场分布,2:农服管理
|
|
|
-const panelType = ref(0);
|
|
|
const treeRef = ref(null);
|
|
|
|
|
|
-// 区域作物面积和产量数据
|
|
|
-const regionCropData = ref({
|
|
|
- plantArea: 0, // 种植面积(亩)
|
|
|
- expectYield: 0, // 预估产量(吨)
|
|
|
-});
|
|
|
-const defaultProps = {
|
|
|
- children: "items",
|
|
|
- label: "name",
|
|
|
-};
|
|
|
-
|
|
|
-// 冷链冷库、加工厂图标(与图例保持一致)
|
|
|
-import coldChainIcon from "@/assets/images/common/legend-icon-1.png";
|
|
|
-import factoryIcon from "@/assets/images/common/legend-icon-2.png";
|
|
|
-
|
|
|
const treeActionData = ref([]);
|
|
|
// 保存原始数据,用于恢复
|
|
|
const originalTreeData = ref([]);
|
|
|
@@ -192,28 +102,40 @@ const activePhenologySecondId = ref(null);
|
|
|
const currentYear = ref(2025);
|
|
|
const currentQuarter = ref(1);
|
|
|
|
|
|
-// 树的默认展开与默认选中(展开/选中第一个“果类”及其子节点)
|
|
|
-const defaultExpandedKeys = ref();
|
|
|
-const defaultCheckedKeys = ref();
|
|
|
-
|
|
|
// 顶部基础 tabs
|
|
|
-const baseTabs = ["作物分布", "物候期分布", "预警分布", "农场分布", "农服管理"];
|
|
|
const activeBaseTab = ref("作物分布");
|
|
|
|
|
|
-const legendImg = ref("");
|
|
|
const warningLayers = ref({});
|
|
|
|
|
|
onMounted(async () => {
|
|
|
+ // 使用 nextTick 确保 DOM 已经渲染完成,地图容器有正确的尺寸
|
|
|
+ await nextTick();
|
|
|
+
|
|
|
warningMap.initMap(store.getters.userinfo.location, mapRef.value);
|
|
|
+
|
|
|
+ // 地图初始化后,更新地图尺寸以确保正确渲染
|
|
|
+ if (warningMap.kmap && warningMap.kmap.map) {
|
|
|
+ // 使用 setTimeout 确保地图容器尺寸已计算
|
|
|
+ setTimeout(() => {
|
|
|
+ warningMap.kmap.map.updateSize();
|
|
|
+ }, 0);
|
|
|
+ }
|
|
|
+
|
|
|
alarmLayer = new AlarmLayer(warningMap.kmap);
|
|
|
staticMapLayers = new StaticMapLayers(warningMap.kmap);
|
|
|
staticMapPointLayers = new StaticMapPointLayers(warningMap.kmap);
|
|
|
distributionLayer = new DistributionLayer(warningMap.kmap);
|
|
|
await getSpeciesListData();
|
|
|
// 作物分布默认选中
|
|
|
- handleDistributionTreeDefault();
|
|
|
await handleDistributionLayer();
|
|
|
|
|
|
+ // 数据加载完成后,再次更新地图尺寸以确保正确渲染
|
|
|
+ if (warningMap.kmap && warningMap.kmap.map) {
|
|
|
+ setTimeout(() => {
|
|
|
+ warningMap.kmap.map.updateSize();
|
|
|
+ }, 100);
|
|
|
+ }
|
|
|
+
|
|
|
eventBus.emit("warningMap:init", warningMap.kmap);
|
|
|
|
|
|
// 图例数据
|
|
|
@@ -227,15 +149,12 @@ onMounted(async () => {
|
|
|
// 这里保持一致:只有在该 tab 下才显示地图图层,否则直接隐藏
|
|
|
if (activeBaseTab.value !== "预警分布") {
|
|
|
staticMapLayers && staticMapLayers.hideAll();
|
|
|
- legendImg.value = "";
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
if (legendUrl) {
|
|
|
- legendImg.value = legendUrl;
|
|
|
staticMapLayers && staticMapLayers.showSingle(name, true);
|
|
|
} else {
|
|
|
- legendImg.value = warningLayers.value[`${name}图例`];
|
|
|
let text = "";
|
|
|
if (name === "日间温度") {
|
|
|
text = "从化地块日温";
|
|
|
@@ -258,6 +177,19 @@ onMounted(async () => {
|
|
|
|
|
|
// 初始化区域选择器的默认值
|
|
|
initAreaDefaultValue();
|
|
|
+
|
|
|
+ // 窗口大小改变时更新地图尺寸
|
|
|
+ const handleResize = () => {
|
|
|
+ if (warningMap.kmap && warningMap.kmap.map) {
|
|
|
+ warningMap.kmap.map.updateSize();
|
|
|
+ }
|
|
|
+ };
|
|
|
+ window.addEventListener('resize', handleResize);
|
|
|
+
|
|
|
+ // 在组件卸载时清理
|
|
|
+ onUnmounted(() => {
|
|
|
+ window.removeEventListener('resize', handleResize);
|
|
|
+ });
|
|
|
});
|
|
|
|
|
|
// 时间轴
|
|
|
@@ -282,23 +214,6 @@ const handleTimeChange = (index, year, quarter) => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-const getRegionCropAreaYield = async () => {
|
|
|
- if (activeBaseTab.value === "作物分布") return;
|
|
|
- const res = await VE_API.warning.fetchRegionCropAreaYield({
|
|
|
- adminCode: selectedAreaCode.value,
|
|
|
- speciesId: 1,
|
|
|
- year: "",
|
|
|
- quarter: "",
|
|
|
- });
|
|
|
- if (res.code === 0 && res.data) {
|
|
|
- // 更新区域作物数据
|
|
|
- regionCropData.value = {
|
|
|
- plantArea: (res.data.plantArea && Number(res.data.plantArea).toFixed(2)) || 0, // 种植面积(亩)
|
|
|
- expectYield: (res.data.expectYield && Number(res.data.expectYield).toFixed(2)) || 0, // 预估产量(吨)
|
|
|
- };
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
// 初始化区域选择器的默认值
|
|
|
const initAreaDefaultValue = async () => {
|
|
|
try {
|
|
|
@@ -329,102 +244,65 @@ onUnmounted(() => {
|
|
|
// 作物分布默认选中并展开第一个节点,在地图上显示对应分布图层
|
|
|
const handleDistributionLayer = async () => {
|
|
|
// 默认选中并展开第一个"果类"节点,在地图上显示对应分布图层
|
|
|
+ if (!treeActionData.value || treeActionData.value.length === 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
const firstCategory = treeActionData.value[0];
|
|
|
- getCommonMapData(firstCategory);
|
|
|
-};
|
|
|
-
|
|
|
-// 作物分布树形结构默认展开与默认选中
|
|
|
-const handleDistributionTreeDefault = () => {
|
|
|
- defaultExpandedKeys.value = [treeActionData.value[0]?.id];
|
|
|
- defaultCheckedKeys.value = [
|
|
|
- treeActionData.value[0]?.id,
|
|
|
- ...(treeActionData.value[0]?.children?.map((c) => c.id) || []),
|
|
|
- ];
|
|
|
-};
|
|
|
-
|
|
|
-// 物候期分布默认选中并展开第一个节点,在地图上显示对应分布图层
|
|
|
-const handlePhenologyLayer = async () => {
|
|
|
- const firstCategory = treeActionData.value[0].items[0];
|
|
|
- getCommonMapData(firstCategory);
|
|
|
-};
|
|
|
-
|
|
|
-// 物候期分布树形结构默认展开与默认选中
|
|
|
-const handlePhenologyTreeDefault = () => {
|
|
|
- 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].items[0];
|
|
|
- getCommonMapData(firstCategory);
|
|
|
-};
|
|
|
-
|
|
|
-// 预警分布树形结构默认展开与默认选中
|
|
|
-const handleAlarmTreeDefault = () => {
|
|
|
- defaultCheckedKeys.value = [treeActionData.value[0]?.items[0]?.id];
|
|
|
- defaultExpandedKeys.value = [treeActionData.value[0]?.id];
|
|
|
+ if (firstCategory) {
|
|
|
+ getCommonMapData(firstCategory);
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
// 处理公共获取最后一级的节点数据
|
|
|
const getCommonMapData = async (firstCategory) => {
|
|
|
- if (firstCategory) {
|
|
|
- // 递归查找最后一层的节点(没有子节点的叶子节点)
|
|
|
- const getLastLevelNodes = (node) => {
|
|
|
- const lastLevelNodes = [];
|
|
|
- if ((!node.items || node.items.length === 0) && (!node.children || node.children.length === 0)) {
|
|
|
- lastLevelNodes.push(node);
|
|
|
- } else {
|
|
|
- const children = node.items || node.children || [];
|
|
|
- children.forEach((child) => {
|
|
|
- lastLevelNodes.push(...getLastLevelNodes(child));
|
|
|
- });
|
|
|
- }
|
|
|
- return lastLevelNodes;
|
|
|
- };
|
|
|
+ if (!firstCategory || !distributionLayer) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 递归查找最后一层的节点(没有子节点的叶子节点)
|
|
|
+ const getLastLevelNodes = (node) => {
|
|
|
+ const lastLevelNodes = [];
|
|
|
+ if ((!node.items || node.items.length === 0) && (!node.children || node.children.length === 0)) {
|
|
|
+ lastLevelNodes.push(node);
|
|
|
+ } else {
|
|
|
+ const children = node.items || node.children || [];
|
|
|
+ children.forEach((child) => {
|
|
|
+ lastLevelNodes.push(...getLastLevelNodes(child));
|
|
|
+ });
|
|
|
+ }
|
|
|
+ return lastLevelNodes;
|
|
|
+ };
|
|
|
|
|
|
- const lastLevelNodes = getLastLevelNodes(firstCategory);
|
|
|
- if (activeBaseTab.value === "物候期分布") {
|
|
|
- // 等待接口返回数据
|
|
|
- const lastLevelIds = lastLevelNodes.map((n) => n.originalId);
|
|
|
- const phenologyData = await getDistributionData(null, lastLevelIds);
|
|
|
+ const lastLevelNodes = getLastLevelNodes(firstCategory);
|
|
|
+ if (lastLevelNodes.length === 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (activeBaseTab.value === "物候期分布") {
|
|
|
+ // 等待接口返回数据
|
|
|
+ const lastLevelIds = lastLevelNodes.map((n) => n.originalId);
|
|
|
+ const phenologyData = await getDistributionData(null, lastLevelIds);
|
|
|
+ if (distributionLayer) {
|
|
|
distributionLayer.initData(phenologyData, "phenologyName");
|
|
|
- return;
|
|
|
- }
|
|
|
- if (activeBaseTab.value === "农场分布") {
|
|
|
- const lastLevelIds = lastLevelNodes.map((n) => n.originalId);
|
|
|
- await fetchFarmList(lastLevelIds);
|
|
|
- return;
|
|
|
}
|
|
|
- const lastLevelIds = lastLevelNodes.map((n) => n.id);
|
|
|
- // 并发请求所有数据
|
|
|
- const promises = lastLevelIds.map((id) => getDistributionData(id));
|
|
|
- const results = await Promise.all(promises);
|
|
|
- const finalMapData = results.flat();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (activeBaseTab.value === "农场分布") {
|
|
|
+ const lastLevelIds = lastLevelNodes.map((n) => n.originalId);
|
|
|
+ await fetchFarmList(lastLevelIds);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const lastLevelIds = lastLevelNodes.map((n) => n.id);
|
|
|
+ // 并发请求所有数据
|
|
|
+ const promises = lastLevelIds.map((id) => getDistributionData(id));
|
|
|
+ const results = await Promise.all(promises);
|
|
|
+ const finalMapData = results.flat();
|
|
|
+ if (distributionLayer) {
|
|
|
distributionLayer.initData(finalMapData);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
// ai与地图交互
|
|
|
-const hideChatMapLayer = ref(true);
|
|
|
const handleMapLayer = ({ mapName, isHome }) => {
|
|
|
- if (!isHome) {
|
|
|
- hideChatMapLayer.value = false;
|
|
|
- }
|
|
|
staticMapPointLayers.hidePoint();
|
|
|
staticMapLayers.hideAll();
|
|
|
|
|
|
@@ -443,133 +321,6 @@ const handleMapLayer = ({ mapName, isHome }) => {
|
|
|
}
|
|
|
};
|
|
|
|
|
|
-const toggleChatMapLayer = () => {
|
|
|
- hideChatMapLayer.value = true;
|
|
|
- eventBus.emit("chat:hideMapLayer");
|
|
|
- staticMapLayers.hideAll();
|
|
|
-};
|
|
|
-
|
|
|
-const destroyPopup = () => {
|
|
|
- eventBus.emit("map:destroyPopup");
|
|
|
-};
|
|
|
-
|
|
|
-const handleTabClick = (item) => {
|
|
|
- activeBaseTab.value = item;
|
|
|
- getRegionCropAreaYield();
|
|
|
-
|
|
|
- // 切换 Tab 时,先清空农场分布图层上的旧数据
|
|
|
- if (distributionLayer) {
|
|
|
- distributionLayer.clear();
|
|
|
- }
|
|
|
- panelType.value = 0;
|
|
|
- // 所有操作前,先清空图层和选中项
|
|
|
- legendImg.value = "";
|
|
|
- staticMapLayers && staticMapLayers.hideAll();
|
|
|
- // 通知预警列表组件清空默认选中项
|
|
|
- eventBus.emit("warningHome:clearAlarm");
|
|
|
- // 使用 nextTick 确保树组件数据更新后再设置选中状态
|
|
|
- if (treeRef.value) {
|
|
|
- defaultCheckedKeys.value = [];
|
|
|
- defaultExpandedKeys.value = [];
|
|
|
- // 先清空所有选中项
|
|
|
- treeRef.value.setCheckedKeys([]);
|
|
|
- }
|
|
|
-
|
|
|
- switch (item) {
|
|
|
- case "作物分布":
|
|
|
- // 禁用农场分布点击处理
|
|
|
- if (distributionLayer) {
|
|
|
- distributionLayer.setFarmClickEnabled(false);
|
|
|
- }
|
|
|
- // 恢复原始数据
|
|
|
- if (originalTreeData.value.length > 0) {
|
|
|
- treeActionData.value = JSON.parse(JSON.stringify(originalTreeData.value));
|
|
|
- }
|
|
|
- handleDistributionTreeDefault();
|
|
|
- handleDistributionLayer();
|
|
|
- break;
|
|
|
- case "物候期分布":
|
|
|
- handleDefaultDistributionLayer(false);
|
|
|
- break;
|
|
|
- case "预警分布":
|
|
|
- // 禁用农场分布点击处理
|
|
|
- if (distributionLayer) {
|
|
|
- distributionLayer.setFarmClickEnabled(false);
|
|
|
- }
|
|
|
- handleAlarmTreeDefault();
|
|
|
- handleAlarmLayer();
|
|
|
- // 通知预警列表组件默认选中第一个(因子)项
|
|
|
- eventBus.emit("warningHome:activeFirstAlarmFactor");
|
|
|
- break;
|
|
|
- case "农场分布":
|
|
|
- panelType.value = 1;
|
|
|
- handleDefaultDistributionLayer(true);
|
|
|
- // // 设施图层测试数据
|
|
|
- // const facilityData = [
|
|
|
- // {
|
|
|
- // id: 201,
|
|
|
- // label: "冷链冷库",
|
|
|
- // imgName: coldChainIcon,
|
|
|
- // wktArr: ["POINT(113.35 23.10)"],
|
|
|
- // },
|
|
|
- // {
|
|
|
- // id: 202,
|
|
|
- // label: "加工厂",
|
|
|
- // imgName: factoryIcon,
|
|
|
- // wktArr: ["POINT(113.25 23.02)"],
|
|
|
- // },
|
|
|
- // ];
|
|
|
-
|
|
|
- // distributionLayer.initFacilityData(facilityData);
|
|
|
- break;
|
|
|
- case "农服管理":
|
|
|
- // 禁用农场分布点击处理
|
|
|
- if (distributionLayer) {
|
|
|
- distributionLayer.setFarmClickEnabled(false);
|
|
|
- }
|
|
|
- panelType.value = 2;
|
|
|
- break;
|
|
|
- default:
|
|
|
- break;
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-const handleDefaultDistributionLayer = (isFarmClickEnabled) => {
|
|
|
- // 启用农场分布点击处理
|
|
|
- if (distributionLayer) {
|
|
|
- distributionLayer.setFarmClickEnabled(isFarmClickEnabled);
|
|
|
- }
|
|
|
- // 先恢复原始数据,再修改第二级 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;
|
|
|
- });
|
|
|
- handlePhenologyTreeDefault();
|
|
|
- handlePhenologyLayer();
|
|
|
-};
|
|
|
-
|
|
|
const getSpeciesListData = async () => {
|
|
|
const res = await VE_API.species.speciesList();
|
|
|
treeActionData.value = res.data;
|
|
|
@@ -579,7 +330,8 @@ const getSpeciesListData = async () => {
|
|
|
|
|
|
const getDistributionData = async (speciesId, phenologyIds) => {
|
|
|
const { data } = await VE_API.agri_land_crop.queryDistribution({
|
|
|
- year: currentYear.value,
|
|
|
+ // year: currentYear.value,
|
|
|
+ year: 2025,
|
|
|
quarter: currentQuarter.value,
|
|
|
speciesId,
|
|
|
phenologyIds: phenologyIds || [],
|
|
|
@@ -615,8 +367,6 @@ const props1 = {
|
|
|
areaVal.value = [firstProvinceCode];
|
|
|
selectedAreaCode.value = firstProvinceCode;
|
|
|
selectedAreaName.value = nodes[0].label;
|
|
|
- // 使用第一个省的code初始化数据
|
|
|
- getRegionCropAreaYield();
|
|
|
}
|
|
|
resolve(nodes);
|
|
|
} else {
|
|
|
@@ -684,7 +434,6 @@ const props1 = {
|
|
|
},
|
|
|
};
|
|
|
|
|
|
-const farmList = ref([]);
|
|
|
const fetchFarmList = (phenologyIds) => {
|
|
|
const params = {
|
|
|
year: currentYear.value,
|
|
|
@@ -713,7 +462,6 @@ const fetchFarmList = (phenologyIds) => {
|
|
|
|
|
|
// 渲染作物数据到地图
|
|
|
distributionLayer.initData(cropData, "label");
|
|
|
- farmList.value = cropData;
|
|
|
resolve(cropData);
|
|
|
} else {
|
|
|
// 接口返回空数据时,清空地图
|
|
|
@@ -731,13 +479,11 @@ const fetchFarmList = (phenologyIds) => {
|
|
|
|
|
|
const selectedAreaCode = ref(null);
|
|
|
const selectedAreaName = ref(null);
|
|
|
-const cascaderRef = ref(null);
|
|
|
|
|
|
// 保存 code 到 name 的映射关系
|
|
|
const areaCodeNameMap = ref(new Map());
|
|
|
|
|
|
const toggleArea = (v) => {
|
|
|
- activeBoxName.value = null;
|
|
|
// 获取选中的最后一个值(即最终的code)
|
|
|
const selectedCode = v && v.length > 0 ? v[v.length - 1] : null;
|
|
|
selectedAreaCode.value = selectedCode;
|
|
|
@@ -748,18 +494,6 @@ const toggleArea = (v) => {
|
|
|
} else {
|
|
|
selectedAreaName.value = null;
|
|
|
}
|
|
|
-
|
|
|
- if (selectedCode) {
|
|
|
- // 调用接口更新区域作物数据
|
|
|
- getRegionCropAreaYield();
|
|
|
- }
|
|
|
-};
|
|
|
-
|
|
|
-const activeBoxName = ref(null);
|
|
|
-const toggleBox = (name) => {
|
|
|
- activeBoxName.value = name;
|
|
|
- legendImg.value = warningLayers.value[`${name}图例`];
|
|
|
- eventBus.emit("warningHome:toggleMapLayer", name);
|
|
|
};
|
|
|
|
|
|
// 搜索
|
|
|
@@ -924,12 +658,6 @@ const getTreeChecks = async (nodeData, data) => {
|
|
|
box-sizing: border-box;
|
|
|
z-index: 1;
|
|
|
|
|
|
- ::v-deep {
|
|
|
- .focus-farm {
|
|
|
- top: 42px;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
.content {
|
|
|
width: 100%;
|
|
|
height: calc(100% - 74px - 48px);
|
|
|
@@ -960,109 +688,12 @@ const getTreeChecks = async (nodeData, data) => {
|
|
|
background: #101010;
|
|
|
border: 1px solid #444444;
|
|
|
}
|
|
|
- .action-legend {
|
|
|
- flex: 1;
|
|
|
- padding: 0 13px;
|
|
|
- display: flex;
|
|
|
- justify-content: flex-end;
|
|
|
- align-items: baseline;
|
|
|
- ::v-deep {
|
|
|
- .el-tree {
|
|
|
- max-height: 400px;
|
|
|
- overflow: auto;
|
|
|
- background: #232323;
|
|
|
- border: 1px solid #444444;
|
|
|
- border-radius: 5px;
|
|
|
- padding: 10px 0;
|
|
|
- --el-tree-node-content-height: 34px;
|
|
|
- --el-tree-node-hover-bg-color: rgba(255, 212, 137, 0.05);
|
|
|
- --el-tree-text-color: #ffd489;
|
|
|
- --el-tree-expand-icon-color: #ffd489;
|
|
|
-
|
|
|
- .el-checkbox {
|
|
|
- --el-checkbox-bg-color: transparent;
|
|
|
- --el-checkbox-input-border: 1px solid #ffd489;
|
|
|
- --el-checkbox-checked-input-border-color: #ffd489;
|
|
|
- --el-checkbox-checked-bg-color: #ffd489;
|
|
|
- --el-checkbox-checked-icon-color: #000;
|
|
|
- --el-checkbox-input-border-color-hover: #ffd489;
|
|
|
- }
|
|
|
- }
|
|
|
- .el-tree-node__content {
|
|
|
- padding-right: 30px;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- .custom-tree-node {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: space-between;
|
|
|
- gap: 8px;
|
|
|
- }
|
|
|
- .level-legend {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- gap: 4px;
|
|
|
- padding: 0 5px;
|
|
|
- height: 17px;
|
|
|
- background: rgba(255, 255, 255, 0.1);
|
|
|
- border-radius: 2px;
|
|
|
- font-size: 10px;
|
|
|
- .legend-dot {
|
|
|
- width: 4px;
|
|
|
- height: 4px;
|
|
|
- border-radius: 50%;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- .warning-r {
|
|
|
- .map-legend {
|
|
|
- position: absolute;
|
|
|
- bottom: -33px;
|
|
|
- left: -360px;
|
|
|
- width: 340px;
|
|
|
- img {
|
|
|
- width: 340px;
|
|
|
- opacity: 0.6;
|
|
|
- }
|
|
|
- }
|
|
|
- .chat-legend {
|
|
|
- bottom: -12px;
|
|
|
- }
|
|
|
- }
|
|
|
- .base-tabs {
|
|
|
- position: fixed;
|
|
|
- top: 32px;
|
|
|
- left: 390px;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- .tab-item {
|
|
|
- padding: 7px 12px 9px;
|
|
|
- margin-right: 28px;
|
|
|
- text-align: center;
|
|
|
- font-family: "PangMenZhengDao";
|
|
|
- font-size: 16px;
|
|
|
- color: #fff;
|
|
|
- background: rgba(28, 36, 41, 0.8);
|
|
|
- border-radius: 4px;
|
|
|
- cursor: pointer;
|
|
|
- border: 1px solid transparent;
|
|
|
- &.active {
|
|
|
- color: #ffdf9a;
|
|
|
- background: rgba(19, 22, 16, 0.8);
|
|
|
- border: 1px solid #ffd489;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
.warning-search {
|
|
|
position: fixed;
|
|
|
right: 207px;
|
|
|
top: 28px;
|
|
|
display: flex;
|
|
|
align-items: center;
|
|
|
- .focus-farm {
|
|
|
- padding-left: 15px;
|
|
|
- }
|
|
|
::v-deep {
|
|
|
.el-select__wrapper {
|
|
|
background: #1d1d1d;
|
|
|
@@ -1138,52 +769,6 @@ const getTreeChecks = async (nodeData, data) => {
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- .top-r {
|
|
|
- display: flex;
|
|
|
- .data-box {
|
|
|
- cursor: pointer;
|
|
|
- margin-left: 20px;
|
|
|
- width: 200px;
|
|
|
- height: 104px;
|
|
|
- background: url("@/assets/images/warningHome/box-bg.png") no-repeat center center / 100% 100%;
|
|
|
- display: flex;
|
|
|
- flex-direction: column;
|
|
|
- align-items: center;
|
|
|
- &.active {
|
|
|
- position: relative;
|
|
|
- &::before {
|
|
|
- content: "";
|
|
|
- position: absolute;
|
|
|
- bottom: -26px;
|
|
|
- left: 0;
|
|
|
- right: 0;
|
|
|
- width: 35px;
|
|
|
- height: 17px;
|
|
|
- margin: 0 auto;
|
|
|
- background: url("@/assets/images/warningHome/triangle.png") no-repeat center center / cover;
|
|
|
- }
|
|
|
- }
|
|
|
- .data-value {
|
|
|
- padding-top: 15px;
|
|
|
- font-size: 20px;
|
|
|
- color: rgba(255, 212, 137, 0.4);
|
|
|
- font-family: "PangMenZhengDao";
|
|
|
- span {
|
|
|
- font-size: 38px;
|
|
|
- color: #f7be5a;
|
|
|
- padding-right: 2px;
|
|
|
- }
|
|
|
- }
|
|
|
- .data-name {
|
|
|
- color: #cecece;
|
|
|
- font-size: 16px;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- .warning-alarm {
|
|
|
- width: 88px;
|
|
|
- padding-top: 14px;
|
|
|
}
|
|
|
.time-wrap {
|
|
|
position: fixed;
|