Parcourir la source

faet:对接农事档案接口

wangsisi il y a 6 jours
Parent
commit
6f47e5e7f7

BIN
src/assets/img/map/tool-1.png


BIN
src/assets/img/map/tool-2.png


BIN
src/assets/img/map/tool-3.png


BIN
src/assets/img/map/tool-4.png


BIN
src/assets/img/map/tool-5.png


BIN
src/assets/img/map/tool-6.png


+ 1 - 0
src/components/gardenList.vue

@@ -109,6 +109,7 @@ function saveSelectedFarm(farm) {
 
 function emitSelectedFarm(farm) {
     emit("selectGarden", {
+        ...farm,
         id: Number(farm.id),
         name: farm.name || "",
         wkt: farm.wkt || "",

+ 20 - 1
src/components/pageComponents/ArchivesFarmTimeLine.vue

@@ -30,6 +30,7 @@
                                             <div class="left-date">{{ formatDate(fw.createTime) }}</div>
                                             <div class="text">
                                                 <span class="van-ellipsis">{{ fw.title }}</span>
+                                                <div class="text-status">{{ farmWorkTypeObj[fw.farm_work_type] }}</div>
                                                 <el-icon>
                                                     <ArrowRight />
                                                 </el-icon>
@@ -381,6 +382,17 @@ const isPhenologyBarGrayByWorkStatus = (phenology) => {
     return all.every((fw) => Number(fw?.work_status) === 3);
 };
 
+const farmWorkTypeObj = {
+    1: "标准农事",
+    2: "机动农事",
+    3: "气象预警农事",
+    4: "气象恢复农事",
+    5: "异常农事",
+    6: "标准施肥类",
+    7: "标准防治类",
+    8: "标准调节类",
+}
+
 // 获取农事规划数据
 const getFarmWorkPlan = () => {
     resetTimelineData();
@@ -709,6 +721,13 @@ onBeforeRouteLeave(() => {
                                     color: rgba(0, 0, 0, 0.4);
                                     width: calc(100% - 90px);
                                 }
+                                .text-status {
+                                    background: rgba(144, 144, 144, 0.1);
+                                    color: #515151;
+                                    border-radius: 2px;
+                                    padding: 2px 5px;
+                                    font-size: 10px;
+                                }
                             }
 
                             .title-text {
@@ -789,7 +808,7 @@ onBeforeRouteLeave(() => {
 
                 // 未激活等:灰色描边卡片
                 .arrange-card.future-card {
-                    @include arrange-card-status(rgba(187, 187, 187, 0.6), null, rgba(187, 187, 187, 0.6), #fff, rgba(187, 187, 187, 0.6));
+                    @include arrange-card-status(rgba(184, 182, 182, 0.9), null, rgba(184, 182, 182, 0.9), #fff, rgba(184, 182, 182, 0.9));
                 }
 
             }

+ 1 - 1
src/components/weatherInfo.vue

@@ -186,7 +186,7 @@ function setSelectedGarden(payload) {
     farmName.value = payload.name || "";
     getLocationName();
     getWeatherData();
-    emit('changeGarden', { id: farmId.value, name: farmName.value });
+    emit('changeGarden', payload);
 }
 
 const handleFarmInfo = () => {

+ 3 - 3
src/views/old_mini/agri_file/components/fileFloat.vue

@@ -98,7 +98,7 @@ const anchors = [
 ];
 const height = ref(anchors[0]);
 
-const AGRI_SUB_TAB_KEYS = ["phenology", "abnormal", "farming"];
+const AGRI_SUB_TAB_KEYS = ["phenology", "farming", "abnormal"];
 
 const floatTabLabels = computed(() => [
     { title: t("agriFile.tabAgriRecord"), value: "agriRecord" },
@@ -107,8 +107,8 @@ const floatTabLabels = computed(() => [
 
 const agriSubTabLabels = computed(() => [
     { title: t("agriFile.tabPhenology"), value: "phenology" },
-    { title: t("agriFile.tabAbnormal"), value: "abnormal" },
     { title: t("agriFile.tabFarming"), value: "farming" },
+    { title: t("agriFile.tabAbnormal"), value: "abnormal" },
 ]);
 
 const currentList = ref([]);
@@ -341,7 +341,7 @@ watch(() => props.activeSubTab, () => {
                 height: 21px;
                 line-height: 21px;
                 padding: 0 6px;
-                min-width: 46px;
+                min-width: fit-content;
                 box-sizing: border-box;
             }
 

+ 181 - 118
src/views/old_mini/agri_file/fileMap.js

@@ -2,163 +2,226 @@ import * as KMap from "@/utils/ol-map/KMap";
 import * as util from "@/common/ol_common.js";
 import config from "@/api/config.js";
 import { Vector as VectorSource } from "ol/source.js";
-import { newAreaFeature, newPoint } from "@/utils/map";
 import Style from "ol/style/Style";
-import Icon from "ol/style/Icon";
 import Text from "ol/style/Text";
 import { Fill, Stroke } from "ol/style";
-import { createEmpty, extend as extendExtent, isEmpty as isEmptyExtent } from "ol/extent";
-
-/** @param {string|string[]|undefined|null} wkt */
-function normalizePolygonWktList(wkt) {
-    if (wkt == null) return [];
-    if (typeof wkt === "string") {
-        const s = wkt.trim();
-        return s ? [s] : [];
-    }
-    if (Array.isArray(wkt)) {
-        return wkt.map((x) => (typeof x === "string" ? x.trim() : "")).filter(Boolean);
-    }
-    return [];
+import { WKT } from "ol/format";
+import Feature from "ol/Feature";
+import {
+    createEmpty,
+    extend as extendExtent,
+    isEmpty as isEmptyExtent,
+    buffer as bufferExtent,
+    getWidth,
+    getHeight,
+} from "ol/extent";
+
+const WKT_FORMAT = new WKT();
+
+const RECORD_TYPE_STYLE = {
+    zone: { fill: "rgba(28, 158, 128, 0.45)", stroke: "#1c9e80" },
+    growth: { fill: "rgba(255, 120, 0, 0.5)", stroke: "#cc5500" },
+    pest: { fill: "rgba(224, 49, 49, 0.45)", stroke: "#e03131" },
+};
+
+/** 物候→管理分区,农事→长势异常,异常→病虫害异常 */
+const TAB_STYLE_TYPE = {
+    phenology: "zone",
+    farming: "growth",
+    abnormal: "pest",
+};
+
+export const RECORD_TAB_KEYS = ["phenology", "farming", "abnormal"];
+
+const DEFAULT_CENTER = "POINT(113.6142086995688 23.585836479509055)";
+
+function getItemPolygon(item) {
+    const wkt = item?.polygon ?? item?.geom ?? item?.geomWkt;
+    return typeof wkt === "string" ? wkt.trim() : "";
 }
 
-function getRecordPointWkt(item) {
-    if (!item || typeof item !== "object") return null;
-    const candidates = [item.pointWkt, item.point_wkt, item.positionWkt, item.position_wkt];
-    for (const v of candidates) {
-        if (v && typeof v === "string" && v.trim().toUpperCase().startsWith("POINT")) {
-            return v.trim();
-        }
+function readPolygonGeometry(wkt, projection) {
+    return WKT_FORMAT.readGeometry(wkt, {
+        dataProjection: "EPSG:4326",
+        featureProjection: projection,
+    });
+}
+
+function createRecordFeature(wkt, item, projection, tabKey) {
+    const feature = new Feature({
+        geometry: readPolygonGeometry(wkt, projection),
+    });
+    feature.set("zone_name", item.zone_name);
+    feature.set("styleType", TAB_STYLE_TYPE[tabKey] || "zone");
+    return feature;
+}
+
+function getUniqueExtents(features) {
+    const seen = new Set();
+    const extents = [];
+    features.forEach((f) => {
+        const e = f.getGeometry()?.getExtent();
+        if (!e || !Number.isFinite(e[0])) return;
+        const key = e.map((v) => v.toFixed(6)).join(",");
+        if (seen.has(key)) return;
+        seen.add(key);
+        extents.push(e);
+    });
+    return extents;
+}
+
+function resolveFitExtent(features) {
+    const extents = getUniqueExtents(features);
+    if (!extents.length) return null;
+
+    const fitOne = (e) => {
+        const span = Math.max(getWidth(e), getHeight(e), 0.00001);
+        return bufferExtent(e, span * 0.35);
+    };
+
+    if (extents.length === 1) return fitOne(extents[0]);
+
+    const union = createEmpty();
+    extents.forEach((e) => extendExtent(union, e));
+    if (getWidth(union) > 0.15 || getHeight(union) > 0.15) {
+        return fitOne(extents[0]);
     }
-    const w = item.wkt;
-    if (w && typeof w === "string" && w.trim().toUpperCase().startsWith("POINT")) {
-        return w.trim();
+    return bufferExtent(union, Math.max(getWidth(union), getHeight(union), 0.00001) * 0.12);
+}
+
+export function recordsToCenterPoint(records) {
+    const wkt = getItemPolygon(records?.[0]);
+    if (!wkt) return null;
+    try {
+        const c = util.wktCastGeom(wkt).getFirstCoordinate();
+        return `POINT(${c[0]} ${c[1]})`;
+    } catch {
+        return null;
     }
-    return null;
 }
 
-/**
- *
- */
 class FileMap {
     constructor() {
-        /** @type {{ polygonWkt: string|string[]|undefined, pointItems: object[] } | null} */
-        this._pendingFarmRecordOverlay = null;
+        this._pending = null;
+        this._fitTimer = null;
+        this._renderToken = 0;
         const vectorStyle = new KMap.VectorStyle();
-        this.gardenPolygonLayer = new KMap.VectorLayer("gardenPolygonLayer", 999, {
-            minZoom: 8,
-            maxZoom: 22,
-            source: new VectorSource({}),
-            style: function () {
-                return [vectorStyle.getPolygonStyle("rgba(24, 170, 139, 0.25)", "#18AA8B", 2)];
-            },
-        });
 
-        this.recordPointLayer = new KMap.VectorLayer("fileRecordPointLayer", 1000, {
+        this.recordPolygonLayer = new KMap.VectorLayer("fileRecordPolygonLayer", 1000, {
             minZoom: 8,
             maxZoom: 22,
             source: new VectorSource({}),
             style: (f) => {
-                const pointIcon = new Style({
-                    image: new Icon({
-                        src: require("@/assets/img/home/garden-point.png"),
-                        scale: 0.5,
-                        anchor: [0.5, 1],
+                const colors = RECORD_TYPE_STYLE[f.get("styleType")] || RECORD_TYPE_STYLE.zone;
+                const polygonStyle = vectorStyle.getPolygonStyle(colors.fill, colors.stroke, 3);
+                const label = f.get("zone_name");
+                if (!label) return [polygonStyle];
+                return [
+                    polygonStyle,
+                    new Style({
+                        text: new Text({
+                            font: "12px sans-serif",
+                            text: label,
+                            fill: new Fill({ color: "#fff" }),
+                            stroke: new Stroke({ color: "#000", width: 0.5 }),
+                        }),
                     }),
-                });
-                const label = f.get("labelText");
-                const nameText = label
-                    ? new Style({
-                          text: new Text({
-                              font: "12px sans-serif",
-                              text: label,
-                              offsetY: -28,
-                              fill: new Fill({ color: "#fff" }),
-                              stroke: new Stroke({ color: "#000", width: 0.5 }),
-                          }),
-                      })
-                    : null;
-                return nameText ? [pointIcon, nameText] : [pointIcon];
+                ];
             },
         });
     }
 
-    initMap(location, target) {
-        let level = 16;
-        let coordinate = util.wktCastGeom(location).getFirstCoordinate();
-        this.kmap = new KMap.Map(target, level, coordinate[0], coordinate[1], null, 8, 22);
-        let xyz2 = config.base_img_url3 + "map/lby/{z}/{x}/{y}.png";
-        this.kmap.addXYZLayer(xyz2, { minZoom: 8, maxZoom: 22 }, 2);
-        this.kmap.addLayer(this.gardenPolygonLayer.layer);
-        this.kmap.addLayer(this.recordPointLayer.layer);
-        if (this._pendingFarmRecordOverlay) {
-            const p = this._pendingFarmRecordOverlay;
-            this._pendingFarmRecordOverlay = null;
-            this.setFarmRecordOverlay(p.polygonWkt, p.pointItems);
+    initMap(centerWkt, target) {
+        if (!target) return;
+
+        const center = util.wktCastGeom(centerWkt || DEFAULT_CENTER).getFirstCoordinate();
+
+        if (this.kmap?.map) {
+            this.kmap.map.setTarget(target);
+            this.kmap.map.updateSize();
+            if (this._pending) {
+                const pending = this._pending;
+                this._pending = null;
+                this.setRecordPolygons(pending.records, pending.tabKey);
+            }
+            return;
+        }
+
+        this.kmap = new KMap.Map(target, 16, center[0], center[1], null, 8, 22);
+        this.kmap.addXYZLayer(config.base_img_url3 + "map/lby/{z}/{x}/{y}.png", { minZoom: 8, maxZoom: 22 }, 2);
+        this.kmap.addLayer(this.recordPolygonLayer.layer);
+
+        if (this._pending) {
+            const pending = this._pending;
+            this._pending = null;
+            this.setRecordPolygons(pending.records, pending.tabKey);
         }
     }
 
-    /**
-     * 农情档案:地块边界 + 记录点位(带 pointWkt / wkt 等)
-     * @param {string|string[]} polygonWkt 地块 MULTIPOLYGON / POLYGON WKT,可为多条
-     * @param {Array<object>} pointItems 当前 Tab 下列表项
-     */
-    setFarmRecordOverlay(polygonWkt, pointItems) {
+    setRecordPolygons(records, tabKey = "phenology") {
         if (!this.kmap) {
-            this._pendingFarmRecordOverlay = { polygonWkt, pointItems };
+            this._pending = { records, tabKey };
             return;
         }
 
-        this.gardenPolygonLayer.source.clear();
-        this.recordPointLayer.source.clear();
+        if (this._fitTimer) {
+            clearTimeout(this._fitTimer);
+            this._fitTimer = null;
+        }
+        const renderToken = ++this._renderToken;
 
-        const wktList = normalizePolygonWktList(polygonWkt);
-        wktList.forEach((w, idx) => {
-            try {
-                const f = newAreaFeature(
-                    { id: `farm-record-boundary-${idx}`, geomWkt: w },
-                    "geomWkt"
-                );
-                this.gardenPolygonLayer.source.addFeature(f);
-            } catch (e) {
-                console.warn("[FileMap] polygon WKT parse failed", e);
-            }
-        });
+        const projection = this.kmap.map.getView().getProjection();
+        const source = this.recordPolygonLayer.source;
+        source.clear(true);
+
+        const list = Array.isArray(records) ? records : [];
+        const seenWkt = new Set();
 
-        const list = Array.isArray(pointItems) ? pointItems : [];
-        list.forEach((item, idx) => {
-            const ptWkt = getRecordPointWkt(item);
-            if (!ptWkt) return;
+        list.forEach((item) => {
+            const wkt = getItemPolygon(item);
+            if (!wkt || seenWkt.has(wkt)) return;
+            seenWkt.add(wkt);
             try {
-                const row = { ...item, id: item.id ?? `record-pt-${idx}`, pointWkt: ptWkt };
-                const f = newPoint(row, "pointWkt");
-                const labelText = [item.time, item.record].filter(Boolean).join(" ");
-                f.set("labelText", labelText || String(item.record ?? ""));
-                this.recordPointLayer.source.addFeature(f);
+                source.addFeature(createRecordFeature(wkt, item, projection, tabKey));
             } catch (e) {
-                console.warn("[FileMap] record point WKT parse failed", e);
+                console.warn("[FileMap] polygon parse failed", e);
             }
         });
 
-        this.fitView();
+        this.recordPolygonLayer.layer.changed();
+        source.changed();
+        this.fitView(renderToken);
     }
 
-    /**
-     * 调整地图视图以适应地块与点位范围
-     */
-    fitView() {
-        if (!this.kmap) return;
-        let extent = createEmpty();
-        const polyFeats = this.gardenPolygonLayer.source.getFeatures().length;
-        const ptFeats = this.recordPointLayer.source.getFeatures().length;
-        if (polyFeats) {
-            extendExtent(extent, this.gardenPolygonLayer.source.getExtent());
-        }
-        if (ptFeats) {
-            extendExtent(extent, this.recordPointLayer.source.getExtent());
+    fitView(renderToken) {
+        if (!this.kmap?.map) return;
+        if (renderToken != null && renderToken !== this._renderToken) return;
+
+        const map = this.kmap.map;
+        map.updateSize();
+
+        const features = this.recordPolygonLayer.source.getFeatures();
+        const extent = resolveFitExtent(features);
+        if (!extent || isEmptyExtent(extent)) return;
+
+        const size = map.getSize();
+        if (!size || size[0] < 4 || size[1] < 4) {
+            this._fitTimer = setTimeout(() => this.fitView(renderToken), 120);
+            return;
         }
-        if (!isEmptyExtent(extent)) {
-            this.kmap.getView().fit(extent, { duration: 50, padding: [80, 80, 80, 80] });
+
+        const view = this.kmap.getView();
+        view.cancelAnimations?.();
+
+        // Tab 切换时不用动画,避免连续 fit 互相打断导致视图停在上一 Tab 区域
+        view.fit(extent, {
+            size,
+            duration: 0,
+            padding: [100, 40, 40, 40],
+            maxZoom: 19,
+        });
+        if ((view.getZoom() ?? 0) < 16) {
+            view.setZoom(16);
         }
     }
 }

+ 50 - 45
src/views/old_mini/agri_file/index.vue

@@ -8,8 +8,8 @@
             :isGarden="true" :gardenId="defaultGardenId">
             <template #types-content>
                 <div class="type-tabs">
-                    <div class="type-item" @click="changeType('荔枝')"
-                        :class="{ 'type-item-active': activeType === '荔枝' }">{{ $t('荔枝') }}</div>
+                    <div class="type-item" @click="changeType(farmVarietyName)"
+                        :class="{ 'type-item-active': activeType === farmVarietyName }">{{ farmVarietyName }}</div>
                     <!-- <div class="type-item" @click="changeType('水稻')" :class="{ 'type-item-active': activeType === '水稻' }">{{ $t('水稻') }}</div> -->
                     <!-- <div class="type-item" @click="changeType('柑橘')" :class="{ 'type-item-active': activeType === '柑橘' }">{{ $t('柑橘') }}</div> -->
                     <!-- <div class="type-item" @click="changeType('小麦')" :class="{ 'type-item-active': activeType === '小麦' }">{{ $t('小麦') }}</div> -->
@@ -72,13 +72,13 @@
 </template>
 
 <script setup>
-import { computed, onActivated, ref, watch } from "vue";
+import { computed, nextTick, onActivated, ref, watch } from "vue";
 import { useRoute } from "vue-router";
 import { useStore } from "vuex";
 import weatherInfo from "@/components/weatherInfo.vue";
 import gardenList from "@/components/gardenList.vue";
 import fileFloat from "./components/fileFloat.vue";
-import FileMap from "./fileMap.js";
+import FileMap, { RECORD_TAB_KEYS, recordsToCenterPoint } from "./fileMap.js";
 import { useI18n } from "@/i18n";
 
 const { t, locale } = useI18n();
@@ -92,7 +92,7 @@ const defaultGardenId = ref(null);
 const selectedGardenId = ref(null);
 const gardenListRef = ref(null);
 const activeGardenTab = ref("current");
-const activeType = ref("荔枝");
+const activeType = ref(null);
 
 const MAP_LEGEND_CONFIG = [
     { key: "zone", labelKey: "agriFile.legendZone", type: "zone" },
@@ -117,6 +117,7 @@ const mapLegendItems = computed(() =>
 const growthScaleLabels = computed(() => GROWTH_SCALE_LABEL_KEYS.map((key) => t(key)));
 
 const MAP_TOOL_ITEMS = [
+    { key: "all", label: "底图" },
     { key: "habitat", label: "生境" },
     { key: "light", label: "光照" },
     { key: "water", label: "水源" },
@@ -125,7 +126,7 @@ const MAP_TOOL_ITEMS = [
 ];
 
 const mapToolItems = MAP_TOOL_ITEMS;
-const activeMapTool = ref(1);
+const activeMapTool = ref(0);
 
 const fileMap = new FileMap();
 
@@ -143,26 +144,41 @@ const REMOTE_SENSING_MOCK_POINTS = [
 ];
 
 const remoteSensingChartData = ref(REMOTE_SENSING_MOCK_POINTS);
-const mapPolygonWkt = ref([]);
 const activeRecordTab = ref(0);
 const activeRecordSubTab = ref(0);
 
-const RECORD_SUB_TAB_KEYS = ["phenology", "abnormal", "farming"];
+const getActiveTabKey = () =>
+    RECORD_TAB_KEYS[activeRecordSubTab.value] || RECORD_TAB_KEYS[0];
+
+const getActiveRecords = () => farmRecordData.value[getActiveTabKey()] || [];
 
 const syncFarmRecordMap = () => {
-    if (activeRecordTab.value !== 0) return;
-    const tabKey = RECORD_SUB_TAB_KEYS[activeRecordSubTab.value] || RECORD_SUB_TAB_KEYS[0];
-    const records = farmRecordData.value?.[tabKey] || [];
-    // fileMap.setFarmRecordOverlay?.(mapPolygonWkt.value, records);
+    if (activeGardenTab.value !== "current") return;
+    nextTick(() => {
+        fileMap.setRecordPolygons(getActiveRecords(), getActiveTabKey());
+    });
+};
+
+const initAgriFileMap = async () => {
+    await nextTick();
+    if (!mapContainer.value) return;
+    fileMap.initMap(recordsToCenterPoint(getActiveRecords()), mapContainer.value);
 };
 
 const getFarmRecord = async () => {
     farmRecordLoading.value = true;
     try {
-        const res = await VE_API.monitor.getFarmRecord();
+        const farmData = JSON.parse(localStorage.getItem("selectedFarmData"));
+        const res = await VE_API.monitor.getFarmRecord({
+            farm_id: selectedGardenId.value,
+            variety_code: farmData.farm_variety,
+        });
         if (res.code === 200) {
-            mapPolygonWkt.value = res.data?.polygon ?? [];
-            farmRecordData.value = res.data || {};
+            farmRecordData.value = {
+                phenology: res.data?.phenology ?? [],
+                abnormal: res.data?.abnormal ?? [],
+                farming: res.data?.farming ?? [],
+            };
             syncFarmRecordMap();
         }
     } finally {
@@ -170,9 +186,8 @@ const getFarmRecord = async () => {
     }
 };
 
-watch(activeRecordTab, syncFarmRecordMap);
 watch(activeRecordSubTab, syncFarmRecordMap);
-watch(locale, syncFarmRecordMap);
+watch(activeGardenTab, syncFarmRecordMap);
 
 const weatherExpanded = (isExpandedValue) => {
     isExpanded.value = isExpandedValue;
@@ -200,39 +215,25 @@ const handleGardenSelected = (garden) => {
     weatherInfoRef.value?.setSelectedGarden?.(garden);
 };
 
+const farmVarietyName = ref(null);
 const changeGarden = (data) => {
     if (!data?.id) return;
     store.commit("home/SET_GARDEN_ID", data.id);
-    let polygonWkt = [];
-    if (data.name === '张振国荔枝农场') {
-        polygonWkt = [
-            "MULTIPOLYGON (((113.62275100940235 23.592983531854543, 113.62303908281478 23.593107898349786, 113.62303654472305 23.59310536025788, 113.62322182542005 23.59321069106511, 113.62339568470429 23.5933375956522, 113.62374594136429 23.593581252459103, 113.62388680545587 23.593600288147172, 113.62413173130858 23.593640897614932, 113.62429163108823 23.593765264110345, 113.6245467093081 23.59392643293569, 113.62459493305118 23.594147246916975, 113.6247459495097 23.594177704018023, 113.6249451897113 23.594144708825297, 113.6250822466651 23.59428684196274, 113.62527387259149 23.594512732127612, 113.6254680366095 23.594555879687107, 113.62552641271952 23.59457110823763, 113.62586524796677 23.594163744513367, 113.62598200018681 23.59397465667871, 113.62583352182014 23.59375130460569, 113.62568504345325 23.593663740440718, 113.62542742714174 23.593586328642687, 113.62523326312373 23.593450540734636, 113.62500229677528 23.593279219542012, 113.62484874222514 23.593208152973375, 113.6244819879687 23.593156122092807, 113.62425736684986 23.593066019835987, 113.62352132024535 23.59286677963439, 113.6231900992733 23.592803327341016, 113.62298070670477 23.59279190592821, 113.62262283576945 23.59266246324944, 113.62275100940235 23.592983531854543)))"
-        ]
-    } else if (data.name === '湛江荔枝先生基地') {
-        polygonWkt = [
-            "MULTIPOLYGON (((110.48938292603424 21.417825047316228, 110.4899730323636 21.417990023279287, 110.49068052543606 21.417796493784067, 110.49084867401376 21.41706679240906, 110.49043306149144 21.415388479246303, 110.48927822974991 21.415515383833224, 110.48873888525532 21.416276811355146, 110.48938292603424 21.417825047316228)))",
-            "MULTIPOLYGON (((110.48996192821238 21.41538768609246, 110.49012614274784 21.415411734511736, 110.4903759544273 21.415328199567455, 110.4905258604706 21.415064079395847, 110.4906400745989 21.41417654044062, 110.49084470824545 21.413217617655164, 110.49126349338252 21.41276314060309, 110.49141339942582 21.412484743665402, 110.49060914160583 21.412625131864786, 110.49000713797136 21.41311768029294, 110.48996192821238 21.41538768609246)))",
-            "MULTIPOLYGON (((110.49144762747073 21.417923243516555, 110.49146967053326 21.417909231135127, 110.49165526849174 21.41746823769546, 110.49183769383541 21.416946342581525, 110.49196777103703 21.416824196916536, 110.49210815923641 21.416644944187453, 110.4923865561741 21.416283266114533, 110.49282437699918 21.415975522491067, 110.49311308493458 21.415770095690846, 110.49327568143673 21.415638432181936, 110.49335023788149 21.41553373589761, 110.49344541632172 21.41515064267577, 110.49345255470479 21.414922214419164, 110.49277207842925 21.414636431237852, 110.49198459250442 21.414455575677493, 110.49168240095673 21.414377846617867, 110.49167605572734 21.414614206411272, 110.49148411253958 21.414625310562485, 110.4913199297302 21.414685590241334, 110.4913104118861 21.414970332408416, 110.49127789258574 21.415159896135265, 110.49120730190918 21.415339148864177, 110.49111212346895 21.41546288083657, 110.49093366389366 21.415717483164258, 110.49088924728812 21.415978430721168, 110.49090193774674 21.416193375365253, 110.49094714750589 21.41630679633994, 110.49102963548751 21.41653443144287, 110.49111767554473 21.4168675559838, 110.49114940169142 21.41712136515764, 110.49114860853774 21.41767498641832, 110.4913286544205 21.41780585677361, 110.49144762747073 21.417923243516555)))",
-        ]
-    }else{
-        polygonWkt = [
-            "MULTIPOLYGON (((110.90593903331239 21.434002814106975, 110.9064263469266 21.434169059115845, 110.90677533454084 21.43419444003331, 110.90846570363959 21.433921595171228, 110.90870756263126 21.43381885533256, 110.90895121943839 21.433709400126418, 110.90860746663844 21.43293924791419, 110.90861063925314 21.432114368098723, 110.9085186334276 21.43114989323766, 110.90719248049368 21.4311023040176, 110.90606620228414 21.431260934751265, 110.90511124526722 21.4317558626405, 110.90499068590952 21.43247287355689, 110.90494944191869 21.433569011927034, 110.90593903331239 21.434002814106975)))"
-        ];
-    }
-    fileMap.setFarmRecordOverlay?.(polygonWkt, []);
+    getFarmRecord();
+    activeType.value = data.variety_name;
+    farmVarietyName.value = data.variety_name;
 };
 
 const mapContainer = ref(null);
-onActivated(() => {
+onActivated(async () => {
     if (route.query?.farmId) {
         defaultGardenId.value = route.query.farmId;
+        await getFarmRecord();
     }
     const savedFarmId = localStorage.getItem("selectedFarmId");
     selectedGardenId.value = savedFarmId ? Number(savedFarmId) : null;
     gardenListRef.value?.refreshFarmList?.();
-
-    fileMap.initMap("POINT(114.31 30.57)", mapContainer.value);
-    getFarmRecord();
+    await initAgriFileMap();
 });
 </script>
 
@@ -374,16 +375,20 @@ onActivated(() => {
                 padding: 10px 5px;
                 color: #C1C1C1;
 
+                .map-tool-bar__icon {
+                    width: 18px;
+                    height: 16px;
+                    margin-bottom: 3px;
+                    filter: grayscale(1);
+                }
+
                 &--active {
                     color: #2199f8;
-                }
-            }
 
-            &__icon {
-                width: 18px;
-                height: 16px;
-                margin-bottom: 3px;
-                // filter: grayscale(0);
+                    .map-tool-bar__icon {
+                        filter: grayscale(0);
+                    }
+                }
             }
 
             &__label {

+ 4 - 1
src/views/old_mini/agri_record/index.vue

@@ -29,7 +29,7 @@
                         <div class="question-tag">{{ item?.first_work?.interaction_issue }}</div>
                     </div>
                     <div class="record-list">
-                        <div class="record-item" v-for="(record, recordIndex) in item.list" :key="recordIndex">
+                        <div class="record-item" v-for="(record, recordIndex) in item.list?.slice(0, 3)" :key="recordIndex">
                             <span v-if="record?.category_name">({{ record.time }}){{ record.category_name }}</span>
                             <span v-else>{{ record }}</span>
                         </div>
@@ -318,6 +318,9 @@ const handleTrendMonitorCardClick = (item) => {
                 font-size: 12px;
                 color: #626262;
 
+                .reason-text{
+                    width: stretch;
+                }
                 .question-tag {
                     background: #2b9af6;
                     color: #ffffff;

+ 12 - 8
src/views/old_mini/youwei_trace/index.vue

@@ -1,11 +1,13 @@
 <template>
     <div class="youwei-trace-page" :style="{ height: `calc(100vh - ${tabBarHeight}px)` }">
-        <!-- <empty
+        <empty
+            v-if="!showTraceImg"
             image="https://birdseye-img.sysuimars.com/birdseye-look-mini/custom-empty-image.png"
             image-size="80"
-            description="该页面正在升级,敬请期待..."
-        /> -->
-        <img class="yw-trace-img" :src="traceImgSrc" alt="">
+            description="暂无报告"
+            class="trace-empty"
+        />
+        <img v-else class="yw-trace-img" :src="traceImgSrc" alt="">
     </div>
 </template>
 
@@ -21,6 +23,7 @@ const store = useStore();
 const { locale } = useI18n();
 const tabBarHeight = computed(() => store.state.home.tabBarHeight);
 const traceImgSrc = computed(() => (locale.value === "en" ? ywEnImg : ywImg));
+const showTraceImg = computed(() => String(store.state.home.gardenId) === "314");
 </script>
 
 <style scoped lang="scss">
@@ -28,10 +31,11 @@ const traceImgSrc = computed(() => (locale.value === "en" ? ywEnImg : ywImg));
     width: 100%;
     height: 100%;
     overflow: auto;
-    // display: flex;
-    // align-items: center;
-    // justify-content: center;
-    // box-sizing: border-box;
+    box-sizing: border-box;
+
+    .trace-empty {
+        padding-top: 120px;
+    }
 }
 .yw-trace-img {
     width: 100%;