소스 검색

Merge branch 'farmer' of http://www.sysuimars.cn:3000/feiniao/feiniao-farm-h5 into farmer

lxf 1 주 전
부모
커밋
d423c86d23

+ 1 - 1
src/components/upload.vue

@@ -165,7 +165,7 @@ watch(
     eventBus.emit('upload:changeArr', imgArr.value);
     emit('handleUpload', { imgArr: imgArr.value, fileList: fileArr.value });
   },
-  { immediate: true }
+  { immediate: true ,deep: true}
 );
 
 function uploadReset() {

+ 2 - 0
src/router/globalRoutes.js

@@ -437,12 +437,14 @@ export default [
     {
         path: "/interaction_list",
         name: "InteractionList",
+        meta: { keepAlive: true },
         component: () => import("@/views/old_mini/interactionList/index.vue"),
     },
     // 勾画发生区域
     {
         path: "/draw_region",
         name: "DrawRegion",
+        meta: { keepAlive: true },
         component: () => import("@/views/old_mini/interactionList/drawRegion.vue"),
     },
 ];

+ 3 - 4
src/views/old_mini/interactionList/drawRegion.vue

@@ -24,12 +24,10 @@ import { ref, onMounted, onActivated, onDeactivated } from "vue";
 import DrawRegionMap from "./map/drawRegionMap.js";
 import { useRouter, useRoute } from "vue-router";
 import { convertPointToArray } from "@/utils/index";
-import { useStore } from "vuex";
 import { ElMessage, ElMessageBox } from "element-plus";
 
 const router = useRouter();
 const route = useRoute();
-const store = useStore();
 const mapContainer = ref(null);
 const drawRegionMap = new DrawRegionMap();
 
@@ -44,9 +42,10 @@ onActivated(() => {
     const point = route.query.mapCenter || "POINT (113.6142086995688 23.585836479509055)"
     
     // 先绘制地块
-    const polygonData = store.state.home.polygonData;
+    const polygonData = route.query.polygonData;
+
     if (polygonData) {
-        drawRegionMap.setAreaGeometry(polygonData?.geometryArr);
+        drawRegionMap.setAreaGeometry(JSON.parse(polygonData)?.geometryArr);
     }
     
     // 再设置地图中心位置,确保视图在 mapCenter

+ 94 - 22
src/views/old_mini/interactionList/index.vue

@@ -32,7 +32,7 @@
             <!-- 未上传状态内容 -->
             <div class="uploaded-content" v-show="item.isConfirmed == null">
                 <div class="content-wrapper">
-                    <div class="item-desc">{{ item.question }}</div>
+                    <div class="item-desc">{{ item.reason }}</div>
                     <div class="example-wrapper">
                         <div class="example-header">
                             <div>示例照片</div>
@@ -106,24 +106,34 @@
             <span>照片上传进度</span>
             <el-progress class="upload-progress" :percentage="50" :stroke-width="10" :format="format" />
         </div>
-        <div class="upload-wrap">
+        <div class="upload-box">
             <!-- 把已经上传成功的图片传给 upload 组件做回显,同时保持原有上传事件不变 -->
-            <upload :maxCount="10" :initImgArr="imgArr" @handleUpload="handleUploadSuccess">
+            <upload :maxCount="10" :initImgArr="initImgArr" @handleUpload="handleUploadSuccess">
             </upload>
         </div>
-        <el-input v-model="uploadProgressText" placeholder="请输入您咨询的问题" clearable />
+        <div class="input-box">
+            <div class="input-item">
+                <span class="label-text">长势异常的果园占比</span>
+                <el-input v-model="uploadFormData.num" placeholder="请输入" type="number">
+                    <template #suffix>
+                        <span class="unit">%</span>
+                    </template>
+                </el-input>
+            </div>
+            <el-input class="input-item" v-model="uploadFormData.text" placeholder="请输入您咨询的问题" clearable />
+        </div>
         <div class="region-tips">勾画新发生区域,精准匹配专属农事方案</div>
-        <div class="region-map">
-            <div class="region-map-text" @click="handleDrawRegion">点击勾画新发生区域</div>
+        <div class="region-map" ref="mapContainer" @click="handleDrawRegion">
+            <div class="region-map-text">点击勾画新发生区域</div>
         </div>
-        <div class="confirm-btn">确认上传</div>
+        <div class="confirm-btn" @click="handleConfirmUpload">确认上传</div>
     </popup>
 
     <!-- 查看更多弹窗 -->
     <more-popup ref="morePopupRef" />
 </template>
 <script setup>
-import { ref, onMounted } from "vue";
+import { ref, onMounted, onActivated } from "vue";
 import { ElMessage } from "element-plus";
 import { Uploader, Popup } from "vant";
 import customHeader from "@/components/customHeader.vue";
@@ -132,6 +142,7 @@ import FarmInfoPopup from "@/components/popup/farmInfoPopup.vue";
 import ExamplePopup from "./components/examplePopup.vue";
 import { useRouter, useRoute } from "vue-router";
 import { base_img_url2 } from "@/api/config";
+import DrawRegionMap from "./map/drawRegionMap.js";
 import UploadFile from "@/utils/upliadFile";
 import { getFileExt } from "@/utils/util";
 import MorePopup from "./components/morePopup.vue";
@@ -145,13 +156,40 @@ const query = ref(useRoute().query);
 const morePopupRef = ref(null);
 //照片上传进度
 const showUploadProgressPopup = ref(false);
-const uploadProgressText = ref('');
+const uploadFormData = ref({
+    num: '',
+    text: ''
+});
 const format = (percentage) => (percentage === 100 ? '上传完成' : `5/10`)
 
+const drawRegionMap = new DrawRegionMap();
+const mapContainer = ref(null);
+
+// 从 sessionStorage 中回显已勾画的区域
+const renderRegionFromSession = () => {
+    const polygonStr = sessionStorage.getItem("drawRegionPolygonData");
+    console.log("polygonStr", polygonStr);
+    if (!polygonStr) return;
+    try {
+        const polygonData = JSON.parse(polygonStr);
+        if (polygonData && Array.isArray(polygonData.geometryArr) && polygonData.geometryArr.length > 0) {
+            // 先清空原有图层,再回显
+            drawRegionMap.clearLayer && drawRegionMap.clearLayer();
+            // needFitView 设为 true,让视图适配当前地块;同时传入面积用于只读模式展示“XX亩”
+            drawRegionMap.setAreaGeometry(polygonData.geometryArr, true, polygonData.mianji);
+        }
+    } catch (e) {
+        console.error("解析 drawRegionPolygonData 失败:", e);
+    }
+};
+
 const uploadFileObj = new UploadFile();
-const imgArr = ref([]);
+const initImgArr = ref([]);
 const miniUserId = localStorage.getItem("MINI_USER_ID");
 const afterReadUpload = async (data) => {
+    initImgArr.value = [];
+    drawRegionMap.clearLayer && drawRegionMap.clearLayer();
+    // sessionStorage.removeItem("drawRegionPolygonData");
     if (!Array.isArray(data)) {
         data = [data];
     }
@@ -166,7 +204,7 @@ const afterReadUpload = async (data) => {
         file.status = "done";
         file.message = "";
         if (resFilename) {
-            imgArr.value.push(resFilename)
+            initImgArr.value.push(resFilename)
         } else {
             file.status = 'failed';
             file.message = '上传失败';
@@ -174,8 +212,11 @@ const afterReadUpload = async (data) => {
         }
     }
     // 所有文件上传结束后再打开进度弹窗,此时 imgArr 已包含全部图片
-    if (imgArr.value.length > 0) {
+    if (initImgArr.value.length > 0) {
         showUploadProgressPopup.value = true;
+        setTimeout(() => {
+            drawRegionMap.initMap("POINT (113.6142086995688 23.585836479509055)", mapContainer.value, false, false,false);
+        }, 100);
     }
 };
 // 示例照片轮播
@@ -270,7 +311,6 @@ const handleConfirm = async (item) => {
     const { code, msg } = await VE_API.home.uploadAnswer(parmas);
     if (code === 0) {
         ElMessage.success("上传成功");
-        sessionStorage.removeItem("drawRegionPolygonData");
         // 清空上传数据
         uploadData.value = [];
         // 刷新列表
@@ -280,20 +320,30 @@ const handleConfirm = async (item) => {
     }
 };
 
+const handleConfirmUpload = () => {
+    console.log("确认上传", uploadFormData.value);
+    showUploadProgressPopup.value = false;
+    sessionStorage.removeItem("drawRegionPolygonData");
+};
+
 // 切换展开/收起
 const toggleExpand = (item) => {
     item.expanded = !item.expanded;
 };
 
 const handleDrawRegion = (item) => {
-    router.push(`/draw_region`)
-    // router.push('/edit_map?type=edit')
+    console.log("勾画发生区域", item);
+    const polygonData = sessionStorage.getItem("drawRegionPolygonData");
+    if(polygonData){
+        router.push(`/draw_region?polygonData=${polygonData}`);
+    }else{
+        router.push(`/draw_region`);
+    }
 };
 
 const uploadData = ref([]);
 const handleUploadSuccess = (data) => {
     uploadData.value = data.imgArr;
-    imgArr.value = [];
 };
 
 const openMorePopup = (images) => {
@@ -308,6 +358,12 @@ onMounted(() => {
     loadData();
 });
 
+// 页面从勾画页返回时,如果组件被 keep-alive 缓存,则会触发 onActivated,在此再做一次回显
+onActivated(() => {
+    console.log("onActivated");
+    renderRegionFromSession();
+});
+
 const getFarmList = async () => {
     const { data } = await VE_API.farm.userFarmSelectOption();
     if (data && data.length === 0) {
@@ -616,10 +672,25 @@ const getFarmList = async () => {
         }
     }
 
-    .upload-wrap {
+    .upload-box {
         margin-bottom: 12px;
     }
 
+    .input-box {
+        .input-item {
+            display: flex;
+            align-items: center;
+            gap: 6px;
+            .label-text{
+                width: 220px;
+            }
+        }
+
+        .input-item+.input-item {
+            margin-top: 6px;
+        }
+    }
+
     .region-tips {
         color: #2199F8;
         padding: 5px;
@@ -632,17 +703,18 @@ const getFarmList = async () => {
     .region-map {
         width: 100%;
         height: 168px;
-        background: red;
-        border-radius: 5px;
-        display: flex;
-        align-items: center;
-        justify-content: center;
+        clip-path: inset(0px round 5px);
+        position: relative;
 
         .region-map-text {
+            position: absolute;
+            bottom: 0;
+            right: 0;
             color: #FFFFFF;
             padding: 5px 20px;
             border-radius: 5px;
             background: rgba(0, 0, 0, 0.6);
+            z-index: 1;
         }
     }
 

+ 86 - 10
src/views/old_mini/interactionList/map/drawRegionMap.js

@@ -3,6 +3,7 @@ import * as util from "@/common/ol_common.js";
 import config from "@/api/config.js";
 import Style from "ol/style/Style";
 import Icon from "ol/style/Icon";
+import { Fill, Stroke, Text } from "ol/style.js";
 import { Point } from 'ol/geom';
 import Feature from "ol/Feature";
 import * as proj from "ol/proj";
@@ -21,6 +22,8 @@ class DrawRegionMap {
         let that = this;
         let vectorStyle = new KMap.VectorStyle();
         this.vectorStyle = vectorStyle;
+        // 是否允许编辑(勾画页 true,小弹窗回显页 false)
+        this.editable = true;
 
         // 位置图标
         this.clickPointLayer = new KMap.VectorLayer("clickPointLayer", 9999, {
@@ -36,26 +39,66 @@ class DrawRegionMap {
         });
     }
 
-    initMap(location, target) {
+    /**
+     * 初始化地图
+     * @param {string} location WKT 点位
+     * @param {HTMLElement|string} target 地图容器
+     * @param {boolean} editable 是否允许绘制/编辑地块
+     * @param {boolean} movable 是否允许拖动/缩放地图
+     * @param {boolean} showPoint 是否显示初始点位图标
+     */
+    initMap(location, target, editable = true, movable = true, showPoint = true) {
         let level = 16;
         let coordinate = util.wktCastGeom(location).getFirstCoordinate();
         this.kmap = new KMap.Map(target, level, coordinate[0], coordinate[1], null, 8, 22);
+        // 记录当前地图是否可编辑,供样式控制使用
+        this.editable = editable;
         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.clickPointLayer.layer);
-        this.setMapPoint(coordinate)
+        // 根据 showPoint 决定是否在初始化时落下点位图标
+        if (showPoint) {
+            this.setMapPoint(coordinate);
+        } else {
+            this.clickPointLayer.source.clear();
+        }
 
-        this.kmap.initDraw((e) => {
-            // drawend事件:绘制结束后的处理(支持绘制多个地块)
-        })
+        // 仅在 editable 为 true 时开启绘制/编辑能力(用于勾画页面)
+        if (editable) {
+            this.kmap.initDraw((e) => {
+                // drawend事件:绘制结束后的处理(支持绘制多个地块)
+            })
+            this.kmap.startDraw()
+            this.kmap.modifyDraw()
+        }
 
-        this.kmap.startDraw()
-        this.kmap.modifyDraw()
+        // movable 为 false 时,禁用地图拖动、缩放等交互(用于小弹窗只看不动)
+        if (!movable && this.kmap && this.kmap.setStates) {
+            this.kmap.setStates({
+                DoubleClickZoom: false,
+                DragAndDrop: false,
+                MouseWheelZoom: false,
+            });
+        }
     }
 
-    setAreaGeometry(geometryArr, needFitView = false) {
-        let that = this
+    /**
+     * 回显地块
+     * @param {string[]} geometryArr 多边形 WKT 数组
+     * @param {boolean} needFitView 是否自动缩放视图
+     * @param {string|number} areaText 显示的面积(单位:亩),可选
+     */
+    setAreaGeometry(geometryArr, needFitView = false, areaText) {
+        console.log("geometryArr", geometryArr);
+        // 兜底保护:geometryArr 可能为 undefined/null 或空数组
+        if (!Array.isArray(geometryArr) || geometryArr.length === 0) return;
+        // 地图实例或图层尚未初始化时也直接返回,避免报错
+        if (!this.kmap || !this.kmap.polygonLayer || !this.kmap.polygonLayer.source) return;
+        console.log("this.kmap");
+
+        let that = this;
         geometryArr.map(item => {
+            console.log("item", item);
             // 不使用 setLayerWkt,而是手动添加要素,避免自动缩放视图
             const format = new WKT()
             const mapProjection = that.kmap.map.getView().getProjection()
@@ -64,6 +107,37 @@ class DrawRegionMap {
                 featureProjection: mapProjection
             })
             let f = new Feature({ geometry: geometry })
+            // 只读模式下,为多边形单独设置样式:仅填充+边框 + 面积文本,不显示可拖动的顶点小圆点
+            if (!this.editable) {
+                const styles = [
+                    new Style({
+                        fill: new Fill({
+                            color: "rgba(0, 0, 0, 0.5)",
+                        }),
+                        stroke: new Stroke({
+                            color: "#2199F8",
+                            width: 2,
+                        }),
+                    }),
+                ];
+                // 面积文本(如:24亩),优先使用传入的 areaText
+                const textValue = areaText != null && areaText !== ""
+                    ? `${areaText}亩`
+                    : "";
+                if (textValue) {
+                    styles.push(
+                        new Style({
+                            text: new Text({
+                                text: textValue,
+                                font: "15px sans-serif",
+                                fill: new Fill({ color: "#ffffff" }),
+                            }),
+                        })
+                    );
+                }
+                f.setStyle(styles);
+            }
+            console.log("f", f);
             that.kmap.polygonLayer.source.addFeature(f)
         })
         // 根据参数决定是否需要自适应地块范围
@@ -81,7 +155,9 @@ class DrawRegionMap {
 
     clearLayer() {
         // this.kmap.removeLayer(this.clickPointLayer.layer)
-        this.kmap.polygonLayer.source.clear();
+        if (this.kmap && this.kmap.polygonLayer) {
+            this.kmap.polygonLayer.source.clear();
+        }
     }
 
     getAreaGeometry() {