|
|
@@ -1,284 +1,146 @@
|
|
|
<template>
|
|
|
<div class="growth-report-page" :style="{ height: `calc(100vh - ${tabBarHeight}px)` }">
|
|
|
- <!-- 天气遮罩 -->
|
|
|
- <div class="weather-mask" v-show="isExpanded" @click="handleMaskClick"></div>
|
|
|
- <!-- 头部 -->
|
|
|
- <div
|
|
|
- class="growth-report-header"
|
|
|
- :style="activeGardenTab === 'current' ? headerMotionStyle : undefined"
|
|
|
- >
|
|
|
- <weather-info ref="weatherInfoRef" :hasWeather="false" from="growth_report" class="weather-info"
|
|
|
- @weatherExpanded="weatherExpanded" @changeGarden="changeGarden" @changeGardenTab="changeGardenTab"
|
|
|
- @reportTabClick="handleReportTabClick" :isGarden="true" :gardenId="defaultGardenId" />
|
|
|
+ <div class="report-content">
|
|
|
+ <div class="map-container" ref="mapContainer"></div>
|
|
|
</div>
|
|
|
- <!-- 农场列表 -->
|
|
|
- <div v-show="activeGardenTab === 'list'">
|
|
|
- <garden-list ref="gardenListRef" :garden-id="selectedGardenId" @loaded="handleGardenLoaded"
|
|
|
- @selectGarden="handleGardenSelected" />
|
|
|
+
|
|
|
+ <!-- 左上角:位置切换 -->
|
|
|
+ <div class="location-bar" @click="handleSwitchLocation">
|
|
|
+ <el-icon class="location-bar__icon"><LocationFilled /></el-icon>
|
|
|
+ <span class="location-bar__name van-ellipsis">{{ locationName }}</span>
|
|
|
+ <span class="location-bar__action">切换位置</span>
|
|
|
</div>
|
|
|
- <div class="report-content" v-show="activeGardenTab === 'current'">
|
|
|
- <div class="map-legend" :class="{ 'map-legend--en': locale === 'en' }">
|
|
|
- <div
|
|
|
- v-for="item in mapLegendItems"
|
|
|
- :key="item.key"
|
|
|
- class="map-legend__item"
|
|
|
- >
|
|
|
- <span class="map-legend__pill" :class="item.pillClass"></span>
|
|
|
- <span class="map-legend__text">{{ item.label }}</span>
|
|
|
+
|
|
|
+ <!-- 左侧:胁迫图层菜单 -->
|
|
|
+ <div class="side-menu side-menu--left">
|
|
|
+ <div
|
|
|
+ v-for="item in stressMenuItems"
|
|
|
+ :key="item.key"
|
|
|
+ class="side-menu__item"
|
|
|
+ :class="{ active: activeStressKey === item.key }"
|
|
|
+ @click="activeStressKey = item.key"
|
|
|
+ >
|
|
|
+ <img class="side-menu__icon" :src="item.icon" alt="" />
|
|
|
+ <div class="side-menu__text">
|
|
|
+ <span>{{ item.line1 }}</span>
|
|
|
+ <span>{{ item.line2 }}</span>
|
|
|
</div>
|
|
|
</div>
|
|
|
- <div class="map-container" ref="mapContainer"></div>
|
|
|
</div>
|
|
|
- <div class="invite-group">
|
|
|
- <div class="invite-btn" @click="handleInvite('farmer')">
|
|
|
- <img class="invite-icon" src="@/assets/img/home/user-icon.png" alt="">
|
|
|
- 邀请农服</div>
|
|
|
- <div class="invite-btn">
|
|
|
- <img class="invite-icon" src="@/assets/img/home/user-icon.png" alt="">
|
|
|
- 邀请农户</div>
|
|
|
+
|
|
|
+ <!-- 右侧:图层菜单 -->
|
|
|
+ <div class="side-menu side-menu--right">
|
|
|
+ <div
|
|
|
+ v-for="item in layerMenuItems"
|
|
|
+ :key="item.key"
|
|
|
+ class="side-menu__item"
|
|
|
+ :class="{ active: activeLayerKey === item.key }"
|
|
|
+ @click="activeLayerKey = item.key"
|
|
|
+ >
|
|
|
+ <img class="side-menu__icon" :src="item.icon" alt="" />
|
|
|
+ <div class="side-menu__text">
|
|
|
+ <span>{{ item.line1 }}</span>
|
|
|
+ <span>{{ item.line2 }}</span>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
</div>
|
|
|
|
|
|
- <risk-report-panel
|
|
|
- v-show="activeGardenTab === 'current'"
|
|
|
- :view-type="panelViewType"
|
|
|
- :plot-detail="plotDetail"
|
|
|
- @expand-progress="panelExpandProgress = $event"
|
|
|
- @close-plot-detail="handleClosePlotDetail"
|
|
|
+ <crop-alert-panel
|
|
|
+ :crop-name="currentCropName"
|
|
|
+ @switch-category="handleSwitchCategory"
|
|
|
+ @view-detail="handleViewDetail"
|
|
|
+ @patrol-tip="handlePatrolTip"
|
|
|
/>
|
|
|
</div>
|
|
|
</template>
|
|
|
|
|
|
<script setup>
|
|
|
-import { computed, nextTick, onActivated, ref } from "vue";
|
|
|
-import { useRoute, useRouter } from "vue-router";
|
|
|
+import { computed, nextTick, onActivated, onMounted, ref } from "vue";
|
|
|
import { useStore } from "vuex";
|
|
|
-import { useI18n } from "@/i18n";
|
|
|
-import weatherInfo from "@/components/weatherInfo.vue";
|
|
|
-import gardenList from "@/components/gardenList.vue";
|
|
|
+import { ElMessage } from "element-plus";
|
|
|
+import { LocationFilled } from "@element-plus/icons-vue";
|
|
|
+import { convertPointToArray } from "@/utils/index";
|
|
|
import GrowthReportMap from "./growthReportMap.js";
|
|
|
-import RiskReportPanel from "./components/RiskReportPanel.vue";
|
|
|
-import * as util from "@/common/ol_common.js";
|
|
|
-import wx from "weixin-js-sdk";
|
|
|
-
|
|
|
-const DEFAULT_FARM_POINT = "POINT(113.6142086995688 23.585836479509055)";
|
|
|
-
|
|
|
-function isPointWkt(value) {
|
|
|
- return typeof value === "string" && /^POINT\s*\(/i.test(value.trim());
|
|
|
-}
|
|
|
-
|
|
|
-function isPolygonWkt(value) {
|
|
|
- return typeof value === "string" && /^(MULTI)?POLYGON\s*\(/i.test(value.trim());
|
|
|
-}
|
|
|
-
|
|
|
-function resolveFarmPolygonWkt(farm) {
|
|
|
- if (!farm || typeof farm === "string") return null;
|
|
|
- const polygon = farm.farm_polygon;
|
|
|
- return isPolygonWkt(polygon) ? polygon : null;
|
|
|
-}
|
|
|
+import CropAlertPanel from "./components/CropAlertPanel.vue";
|
|
|
|
|
|
-function resolveFarmLocationWkt(farm, polygonWkt) {
|
|
|
- if (typeof farm === "string" && isPointWkt(farm)) return farm;
|
|
|
- if (!farm || typeof farm === "string") return null;
|
|
|
+const DEFAULT_MAP_POINT = "POINT(113.6142086995688 23.585836479509055)";
|
|
|
+const MAP_KEY = "CZLBZ-LJICQ-R4A5J-BN62X-YXCRJ-GNBUT";
|
|
|
|
|
|
- const candidates = [farm.wkt, farm.geom_wkt, farm.farm_location];
|
|
|
- for (const candidate of candidates) {
|
|
|
- if (isPointWkt(candidate)) return candidate;
|
|
|
- }
|
|
|
-
|
|
|
- if (polygonWkt) {
|
|
|
- const geom = util.wktCastGeom(polygonWkt);
|
|
|
- const extent = geom.getExtent();
|
|
|
- return `POINT(${(extent[0] + extent[2]) / 2} ${(extent[1] + extent[3]) / 2})`;
|
|
|
- }
|
|
|
-
|
|
|
- return null;
|
|
|
-}
|
|
|
+const menuIcon = require("@/assets/img/common/farm-active.png");
|
|
|
|
|
|
const store = useStore();
|
|
|
-const { t, locale } = useI18n();
|
|
|
-const route = useRoute();
|
|
|
-const router = useRouter();
|
|
|
const tabBarHeight = computed(() => store.state.home.tabBarHeight);
|
|
|
|
|
|
-const isExpanded = ref(false);
|
|
|
-const weatherInfoRef = ref(null);
|
|
|
-const defaultGardenId = ref(null);
|
|
|
-const selectedGardenId = ref(null);
|
|
|
-const gardenListRef = ref(null);
|
|
|
-const activeGardenTab = ref("current");
|
|
|
-const panelExpandProgress = ref(0);
|
|
|
-const panelViewType = ref("risk");
|
|
|
-const plotDetail = ref(createDefaultPlotDetail());
|
|
|
-
|
|
|
-const HEADER_FADE_START = 0.68;
|
|
|
-
|
|
|
-function createDefaultPlotDetail() {
|
|
|
- const defaultImage = require("@/assets/img/home/banner.png");
|
|
|
- return {
|
|
|
- name: "地块名称",
|
|
|
- area: "289亩",
|
|
|
- categories: "荔枝、水稻",
|
|
|
- startTime: "2026/06/05",
|
|
|
- harvestTime: "2026/06/05",
|
|
|
- description: "当前处于物候期,有什么风险,做了什么农事,或者正在执行中,当前处于物候期,有什么风险",
|
|
|
- images: [defaultImage, defaultImage, defaultImage, defaultImage],
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
-function buildPlotDetailByTab(item) {
|
|
|
- const tabLabelMap = {
|
|
|
- soilImprovement: "土壤改良地块",
|
|
|
- rotationAdvice: "轮作建议地块",
|
|
|
- };
|
|
|
- return {
|
|
|
- ...createDefaultPlotDetail(),
|
|
|
- name: tabLabelMap[item.key] || "地块名称",
|
|
|
- };
|
|
|
-}
|
|
|
-
|
|
|
-const handleClosePlotDetail = () => {
|
|
|
- panelViewType.value = "risk";
|
|
|
-};
|
|
|
-
|
|
|
-const headerMotionStyle = computed(() => {
|
|
|
- const progress = panelExpandProgress.value;
|
|
|
- const fade = progress <= HEADER_FADE_START
|
|
|
- ? 0
|
|
|
- : (progress - HEADER_FADE_START) / (1 - HEADER_FADE_START);
|
|
|
- const opacity = 1 - fade;
|
|
|
- return {
|
|
|
- opacity,
|
|
|
- transform: `translateY(${-14 * fade}px) scale(${1 - fade * 0.04})`,
|
|
|
- pointerEvents: opacity < 0.15 ? "none" : "auto",
|
|
|
- };
|
|
|
-});
|
|
|
-
|
|
|
-const currentFarmName = ref("");
|
|
|
-const currentFarmVariety = ref(null);
|
|
|
const mapContainer = ref(null);
|
|
|
const growthReportMap = new GrowthReportMap();
|
|
|
+const locationName = ref("");
|
|
|
+const currentCropName = ref("水稻");
|
|
|
+const activeStressKey = ref("hot-drought-2");
|
|
|
+const activeLayerKey = ref("growth");
|
|
|
+
|
|
|
+const stressMenuItems = [
|
|
|
+ { key: "stress", line1: "胁迫", line2: "胁迫", icon: menuIcon },
|
|
|
+ { key: "hot-drought-1", line1: "高温", line2: "干旱", icon: menuIcon },
|
|
|
+ { key: "hot-drought-2", line1: "高温", line2: "干旱", icon: menuIcon },
|
|
|
+ { key: "hot-drought-3", line1: "高温", line2: "干旱", icon: menuIcon },
|
|
|
+];
|
|
|
+
|
|
|
+const layerMenuItems = [
|
|
|
+ { key: "growth", line1: "作物", line2: "长势", icon: menuIcon },
|
|
|
+ { key: "phenology", line1: "物候", line2: "进程", icon: menuIcon },
|
|
|
+];
|
|
|
+
|
|
|
+function getLocationName() {
|
|
|
+ const locationPoint = localStorage.getItem("selectedFarmPoint") || store.state.home.miniUserLocationPoint;
|
|
|
+ if (!locationPoint) return;
|
|
|
+ const farmLocation = convertPointToArray(locationPoint);
|
|
|
+ if (!farmLocation?.length) return;
|
|
|
+ const params = {
|
|
|
+ key: MAP_KEY,
|
|
|
+ location: `${farmLocation[1]},${farmLocation[0]}`,
|
|
|
+ };
|
|
|
+ VE_API.old_mini_map.location(params).then(({ result }) => {
|
|
|
+ locationName.value = result?.address_component
|
|
|
+ ? result.address_component.city + result.address_component.district
|
|
|
+ : result?.address + "";
|
|
|
+ });
|
|
|
+}
|
|
|
|
|
|
-const syncMapByFarm = async (farm) => {
|
|
|
- const polygonWkt = resolveFarmPolygonWkt(farm);
|
|
|
- const location = resolveFarmLocationWkt(farm, polygonWkt) || DEFAULT_FARM_POINT;
|
|
|
-
|
|
|
+const initMap = async () => {
|
|
|
await nextTick();
|
|
|
if (!mapContainer.value) return;
|
|
|
-
|
|
|
if (growthReportMap.kmap) {
|
|
|
growthReportMap.kmap.map?.updateSize?.();
|
|
|
- if (polygonWkt) {
|
|
|
- growthReportMap.setAreaGeometry([polygonWkt]);
|
|
|
- const coordinate = util.wktCastGeom(location).getFirstCoordinate();
|
|
|
- growthReportMap.setMapPoint(coordinate);
|
|
|
- growthReportMap.scheduleFitView();
|
|
|
- } else {
|
|
|
- growthReportMap.clearLayer();
|
|
|
- const coordinate = util.wktCastGeom(location).getFirstCoordinate();
|
|
|
- growthReportMap.setMapPosition(coordinate);
|
|
|
- }
|
|
|
return;
|
|
|
}
|
|
|
-
|
|
|
+ const location = store.state.home.miniUserLocationPoint || DEFAULT_MAP_POINT;
|
|
|
growthReportMap.initMap(location, mapContainer.value);
|
|
|
- if (polygonWkt) {
|
|
|
- growthReportMap.setAreaGeometry([polygonWkt]);
|
|
|
- growthReportMap.scheduleFitView();
|
|
|
- }
|
|
|
};
|
|
|
|
|
|
-const initGrowthReportMap = async () => {
|
|
|
- await syncMapByFarm();
|
|
|
+const handleSwitchLocation = () => {
|
|
|
+ ElMessage.info("切换位置功能即将开放");
|
|
|
};
|
|
|
|
|
|
-const mapLegendItems = computed(() => [
|
|
|
- { key: "zone", label: t("agriFile.legendZone"), pillClass: "map-legend__pill--zone" },
|
|
|
- { key: "growth", label: t("agriFile.legendGrowth"), pillClass: "map-legend__pill--growth" },
|
|
|
- { key: "pest", label: t("agriFile.legendPest"), pillClass: "map-legend__pill--pest" },
|
|
|
-]);
|
|
|
-
|
|
|
-const handleReportTabClick = (item) => {
|
|
|
- if (item.key === "historyRisk") {
|
|
|
- router.push(
|
|
|
- `/history_risk_report?farmVariety=${currentFarmVariety.value ?? ""}¤tFarmName=${currentFarmName.value ?? ""}`
|
|
|
- );
|
|
|
- return;
|
|
|
- }
|
|
|
- plotDetail.value = buildPlotDetailByTab(item);
|
|
|
- panelViewType.value = "plot";
|
|
|
+const handleSwitchCategory = (cropName) => {
|
|
|
+ if (!cropName) return;
|
|
|
+ currentCropName.value = cropName;
|
|
|
};
|
|
|
|
|
|
-const weatherExpanded = (isExpandedValue) => {
|
|
|
- isExpanded.value = isExpandedValue;
|
|
|
+const handleViewDetail = () => {
|
|
|
+ ElMessage.info("详情功能即将开放");
|
|
|
};
|
|
|
|
|
|
-const handleMaskClick = () => {
|
|
|
- if (weatherInfoRef.value?.toggleExpand) {
|
|
|
- weatherInfoRef.value.toggleExpand();
|
|
|
- }
|
|
|
+const handlePatrolTip = () => {
|
|
|
+ ElMessage.info("巡园要点功能即将开放");
|
|
|
};
|
|
|
|
|
|
-const changeGardenTab = (tab) => {
|
|
|
- activeGardenTab.value = tab;
|
|
|
- if (tab !== "current") {
|
|
|
- panelExpandProgress.value = 0;
|
|
|
- panelViewType.value = "risk";
|
|
|
- return;
|
|
|
- }
|
|
|
- nextTick(() => {
|
|
|
- growthReportMap.kmap?.map?.updateSize?.();
|
|
|
- growthReportMap.scheduleFitView?.();
|
|
|
- });
|
|
|
-};
|
|
|
-
|
|
|
-const handleGardenLoaded = ({ hasFarm }) => {
|
|
|
- weatherInfoRef.value?.setGardenLoaded?.(hasFarm);
|
|
|
-};
|
|
|
-
|
|
|
-const handleGardenSelected = (garden) => {
|
|
|
- selectedGardenId.value = garden?.id ?? null;
|
|
|
- syncMapByFarm(garden);
|
|
|
- weatherInfoRef.value?.setSelectedGarden?.(garden);
|
|
|
-};
|
|
|
-
|
|
|
-const changeGarden = (data) => {
|
|
|
- if (!data?.id) return;
|
|
|
- store.commit("home/SET_GARDEN_ID", data.id);
|
|
|
- selectedGardenId.value = data.id;
|
|
|
- currentFarmName.value = data.name ?? "";
|
|
|
- currentFarmVariety.value = data.farm_variety ?? null;
|
|
|
- syncMapByFarm(data);
|
|
|
-};
|
|
|
-
|
|
|
-
|
|
|
-const handleInvite = (item) => {
|
|
|
- let inviteName = "好友";
|
|
|
- try {
|
|
|
- const userInfo = JSON.parse(localStorage.getItem("localUserInfo") || "{}");
|
|
|
- inviteName = userInfo.nickName || userInfo.userName || userInfo.name || inviteName;
|
|
|
- } catch {
|
|
|
- // ignore
|
|
|
- }
|
|
|
- const query = {
|
|
|
- askInfo: { title: "邀请完善信息", content: "是否分享该邀请给好友" },
|
|
|
- shareText: "邀请您完善地块种植信息",
|
|
|
- targetUrl: `entry_information`,
|
|
|
- paramsPage: JSON.stringify({ inviteName }),
|
|
|
- imageUrl: 'https://birdseye-img.sysuimars.com/temp/field.png',
|
|
|
- };
|
|
|
- wx.miniProgram.navigateTo({
|
|
|
- url: `/pages/subPages/share_page/index?pageParams=${JSON.stringify(query)}&type=sharePage`,
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
-onActivated(async () => {
|
|
|
- if (route.query?.farmId) {
|
|
|
- defaultGardenId.value = route.query.farmId;
|
|
|
- }
|
|
|
- const savedFarmId = localStorage.getItem("selectedFarmId");
|
|
|
- selectedGardenId.value = savedFarmId ? Number(savedFarmId) : null;
|
|
|
- gardenListRef.value?.refreshFarmList?.();
|
|
|
- await initGrowthReportMap();
|
|
|
+onMounted(() => {
|
|
|
+ getLocationName();
|
|
|
+ initMap();
|
|
|
+});
|
|
|
+onActivated(() => {
|
|
|
+ getLocationName();
|
|
|
+ initMap();
|
|
|
});
|
|
|
</script>
|
|
|
|
|
|
@@ -286,144 +148,105 @@ onActivated(async () => {
|
|
|
.growth-report-page {
|
|
|
width: 100%;
|
|
|
height: 100%;
|
|
|
- background: #F5F7FB;
|
|
|
+ background: #f5f7fb;
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
- .weather-mask {
|
|
|
+ .location-bar {
|
|
|
position: fixed;
|
|
|
- top: 0;
|
|
|
- left: 0;
|
|
|
- width: 100%;
|
|
|
- height: 100%;
|
|
|
- background-color: rgba(0, 0, 0, 0.52);
|
|
|
- z-index: 11;
|
|
|
- }
|
|
|
-
|
|
|
- .growth-report-header {
|
|
|
- position: absolute;
|
|
|
- z-index: 12;
|
|
|
- left: 10px;
|
|
|
top: 12px;
|
|
|
- width: calc(100% - 20px);
|
|
|
- will-change: transform, opacity;
|
|
|
- transform-origin: center top;
|
|
|
+ left: 12px;
|
|
|
+ z-index: 16;
|
|
|
+ display: inline-flex;
|
|
|
+ align-items: center;
|
|
|
+ gap: 4px;
|
|
|
+ max-width: calc(100% - 24px);
|
|
|
+ height: 32px;
|
|
|
+ padding: 0 12px;
|
|
|
+ border-radius: 16px;
|
|
|
+ background: rgba(0, 0, 0, 0.4);
|
|
|
+ backdrop-filter: blur(4px);
|
|
|
+ color: #fff;
|
|
|
+ font-size: 14px;
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
|
- .weather-info {
|
|
|
- width: 100%;
|
|
|
- position: relative;
|
|
|
- left: auto;
|
|
|
- top: auto;
|
|
|
-
|
|
|
- :deep(.garden-tabs) {
|
|
|
- .garden-item.left-item.active .current-name {
|
|
|
- color: #2199F8;
|
|
|
- font-weight: 600;
|
|
|
- }
|
|
|
- }
|
|
|
+ &__icon {
|
|
|
+ font-size: 16px;
|
|
|
+ flex-shrink: 0;
|
|
|
}
|
|
|
- }
|
|
|
- .invite-group {
|
|
|
- position: fixed;
|
|
|
- bottom: 300px;
|
|
|
- right: 16px;
|
|
|
- z-index: 10;
|
|
|
- pointer-events: none;
|
|
|
- .invite-btn {
|
|
|
- pointer-events: auto;
|
|
|
- height: 32px;
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- justify-content: center;
|
|
|
- border-radius: 5px;
|
|
|
- background: #fff;
|
|
|
- box-shadow: 0px 1px 1px 0px rgba(0, 0, 0, 0.1);
|
|
|
- gap: 4px;
|
|
|
- padding: 0 8px;
|
|
|
- color: #2199F8;
|
|
|
- font-weight: 500;
|
|
|
- font-size: 12px;
|
|
|
- .invite-icon {
|
|
|
- width: 16px;
|
|
|
- }
|
|
|
+
|
|
|
+ &__name {
|
|
|
+ max-width: calc(100vw - 80px);
|
|
|
}
|
|
|
- .invite-btn + .invite-btn {
|
|
|
- margin-top: 10px;
|
|
|
+
|
|
|
+ &__action {
|
|
|
+ flex-shrink: 0;
|
|
|
+ color: #2199f8;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- .report-content {
|
|
|
- position: relative;
|
|
|
- height: 100%;
|
|
|
+ .side-menu {
|
|
|
+ position: fixed;
|
|
|
+ top: 58px;
|
|
|
+ z-index: 15;
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ gap: 12px;
|
|
|
+ padding: 10px 6px;
|
|
|
+ border-radius: 6px;
|
|
|
+ background: #fff;
|
|
|
+ box-shadow: 0px 2px 4px 0px rgba(0, 0, 0, 0.1);
|
|
|
box-sizing: border-box;
|
|
|
|
|
|
- .map-legend {
|
|
|
- position: absolute;
|
|
|
- top: 110px;
|
|
|
+ &--left {
|
|
|
+ left: 10px;
|
|
|
+ }
|
|
|
+
|
|
|
+ &--right {
|
|
|
right: 10px;
|
|
|
- z-index: 15;
|
|
|
+ }
|
|
|
+
|
|
|
+ &__item {
|
|
|
display: flex;
|
|
|
+ flex-direction: column;
|
|
|
align-items: center;
|
|
|
- gap: 10px;
|
|
|
- padding: 4px 10px;
|
|
|
- background: rgba(0, 0, 0, 0.46);
|
|
|
- backdrop-filter: blur(4px);
|
|
|
- border-radius: 4px;
|
|
|
- box-sizing: border-box;
|
|
|
-
|
|
|
- &--en {
|
|
|
- flex-direction: column;
|
|
|
- align-items: flex-start;
|
|
|
- gap: 6px;
|
|
|
- padding: 8px 10px;
|
|
|
- background: rgba(0, 0, 0, 0.72);
|
|
|
- border-radius: 6px;
|
|
|
-
|
|
|
- .map-legend__item {
|
|
|
- gap: 6px;
|
|
|
- }
|
|
|
+ gap: 4px;
|
|
|
+ width: 26px;
|
|
|
+ color: #8a8a8a;
|
|
|
+ cursor: pointer;
|
|
|
|
|
|
- .map-legend__pill {
|
|
|
- width: 18px;
|
|
|
- height: 4px;
|
|
|
- flex-shrink: 0;
|
|
|
- }
|
|
|
+ &.active {
|
|
|
+ color: #2199f8;
|
|
|
|
|
|
- .map-legend__text {
|
|
|
- font-size: 11px;
|
|
|
- line-height: 1.2;
|
|
|
- white-space: nowrap;
|
|
|
+ .side-menu__icon {
|
|
|
+ opacity: 1;
|
|
|
+ filter: brightness(0) saturate(100%) invert(48%) sepia(98%) saturate(1805%) hue-rotate(178deg) brightness(98%) contrast(97%);
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
|
|
|
- &__item {
|
|
|
- display: flex;
|
|
|
- align-items: center;
|
|
|
- gap: 5px;
|
|
|
- }
|
|
|
-
|
|
|
- &__pill {
|
|
|
- width: 16px;
|
|
|
- height: 5px;
|
|
|
- border-radius: 10px;
|
|
|
-
|
|
|
- &--zone {
|
|
|
- background: #13a27f;
|
|
|
- }
|
|
|
-
|
|
|
- &--growth {
|
|
|
- background: #ff9138;
|
|
|
- }
|
|
|
-
|
|
|
- &--pest {
|
|
|
- background: #e62e2d;
|
|
|
- }
|
|
|
- }
|
|
|
+ &__icon {
|
|
|
+ width: 16px;
|
|
|
+ height: 16px;
|
|
|
+ object-fit: contain;
|
|
|
+ opacity: 0.55;
|
|
|
+ filter: grayscale(1);
|
|
|
+ }
|
|
|
|
|
|
- &__text {
|
|
|
- font-size: 12px;
|
|
|
- color: #fff;
|
|
|
- }
|
|
|
+ &__text {
|
|
|
+ display: flex;
|
|
|
+ flex-direction: column;
|
|
|
+ align-items: center;
|
|
|
+ font-size: 12px;
|
|
|
+ line-height: 14px;
|
|
|
+ text-align: center;
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ .report-content {
|
|
|
+ position: relative;
|
|
|
+ height: 100%;
|
|
|
+ box-sizing: border-box;
|
|
|
|
|
|
.map-container {
|
|
|
width: 100%;
|