Kaynağa Gözat

feat:对接新建农场和编辑农场接口

wangsisi 1 gün önce
ebeveyn
işleme
b853f4eedb

+ 5 - 0
src/api/modules/basic_farm.js

@@ -42,4 +42,9 @@ module.exports = {
         url: url + "/option/update",
         type: "post",
     },
+    // 查询农场主体详情
+    fetchFarmSubjectDetail: {
+        url: config.base_dev_url + "farm_subject/getSubjectDetail",
+        type: "get",
+    },
 }

+ 17 - 2
src/components/popup/saveRegionSuccessPopup.vue

@@ -5,9 +5,11 @@
         <div class="title">
             {{ title }}
         </div>
-        <div class="actions">
+        <div class="actions" :class="{ 'single-btn': !hasNext }">
             <div class="btn btn-ghost" @click="handleKnow">我知道了</div>
-            <div class="btn btn-primary" @click="handleNext">勾选下一个品种</div>
+            <div v-if="hasNext" class="btn btn-primary" @click="handleNext">
+                勾选下一个品种
+            </div>
         </div>
     </popup>
 </template>
@@ -26,6 +28,11 @@ const props = defineProps({
         type: String,
         default: "区域已保存成功",
     },
+    /** 是否还有下一个品种,用于控制“勾选下一个品种”按钮显示 */
+    hasNext: {
+        type: Boolean,
+        default: true,
+    },
 });
 
 const emit = defineEmits(["update:show", "know", "next"]);
@@ -89,6 +96,14 @@ const handleNext = () => {
             border: 1px solid #2199f8;
             width: calc(100% - 110px);
         }
+
+        &.single-btn {
+            justify-content: center;
+
+            .btn-ghost {
+                width: 70%;
+            }
+        }
     }
 }
 </style>

+ 1 - 1
src/components/weatherInfo.vue

@@ -302,7 +302,7 @@ function getLocationName() {
 const myFarmInfoRef = ref(null);
 const handleFarmInfo = () => {
     // myFarmInfoRef.value.handleShow();
-    router.push(`/farm_info`);
+    router.push(`/farm_info?subjectId=${farmId.value}`);
 }
 const handleAddFarm = () => {
     router.push(`/create_farm?type=farmer&expertMiniUserId=81881&isReload=true`);

+ 23 - 6
src/views/old_mini/create_farm/index.vue

@@ -503,7 +503,7 @@ const submitForm = (formEl) => {
 
             // 如果是编辑模式,添加农场ID
             if (route.query.type === "edit" && route.query.farmId) {
-                params.farmId = route.query.farmId;
+                params.id = route.query.farmId;
             }
 
             let pageData = null;
@@ -539,7 +539,7 @@ const submitForm = (formEl) => {
                 return;
             }
 
-            const apiCall = route.query.type === "edit" ? VE_API.farm.updateFarm(params) : VE_API.farm.saveFarm(params);
+            const apiCall = route.query.type === "edit" ? VE_API.basic_farm.saveBasicFarmInfoByExpertV3({...params, expertMiniUserId: '81881'}) : VE_API.farm.saveFarm(params);
 
             apiCall.then((res) => {
                 if (res.code === 0) {
@@ -581,7 +581,7 @@ const submitForm = (formEl) => {
                                     }
                                 });
                         } else {
-                            router.replace(`/home`);
+                            router.replace(`/growth_report`);
                         }
                     }
                 } else {
@@ -848,9 +848,26 @@ function populateEditData() {
         isFromEditMap.value = true; // 编辑模式下锁定面积输入
     }
 
-    // 处理作物数据
-    if (editData.speciesId && editData.speciesName) {
-        // 设置品类 - 需要匹配模板中的数据结构(多选:用数组包一层)
+    // 处理作物数据(兼容多选)
+    if (Array.isArray(editData.cropList) && editData.cropList.length > 0) {
+        // editData.cropList 中带有 speciesId,根据 speciesId 去匹配当前 specieList 里的 id
+        const selected = [];
+        editData.cropList.forEach((crop) => {
+            const targetId = crop.speciesId ?? crop.id;
+            if (targetId == null) return;
+            const match = specieList.value.find((s) => String(s.id) === String(targetId));
+            if (match) {
+                selected.push({
+                    value: match.id,
+                    ...match,
+                });
+            }
+        });
+        if (selected.length > 0) {
+            ruleForm.speciesItem = selected;
+        }
+    } else if (editData.speciesId && editData.speciesName) {
+        // 兼容旧数据:只有单个品类字段时,按原逻辑回显一个
         const species = {
             value: editData.speciesId,
             id: editData.speciesId,

+ 5 - 1
src/views/old_mini/home/subPages/prescriptionPage.vue

@@ -460,7 +460,11 @@ function handleCancelSelect() {
 const goBack = () => {
     // saveDraft();
     // router.go(-1);
-    router.replace(`/create_farm?from=${route.query.from}&type=${route.query.type}`)
+    if (route.query.subjectId) {
+        router.go(-1);
+    } else {
+        router.replace(`/create_farm?from=${route.query.from}&type=${route.query.type}`);
+    }
 };
 
 function handleSubmit() {

+ 1 - 1
src/views/old_mini/interactionList/map/drawRegionMap.js

@@ -32,7 +32,7 @@ class DrawRegionMap {
                     image: new Icon({
                         src: require("@/assets/img/home/garden-point.png"),
                         scale: 0.5,
-                        anchor: [0.5, 1],
+                        anchor: [0.5, 0.5],
                     }),
                 });
             },

+ 10 - 16
src/views/old_mini/monitor/subPages/agriculturalDetail.vue

@@ -37,10 +37,7 @@
 import { useRouter, useRoute } from "vue-router";
 import { ref } from "vue";
 import customHeader from "@/components/customHeader.vue";
-
-import { Popup } from "vant";
-import AlbumCarousel from "@/components/album_compoents/albumCarousel";
-import { base_img_url2 } from "@/api/config";
+import { showImagePreview } from 'vant';
 
 const router = useRouter();
 const route = useRoute();
@@ -75,18 +72,15 @@ const imageList = ref([]);
 const currentImageData = ref({});
 
 const handlePhotoClick = (photo) => {
-    // 暂时使用当前页面的假数据 URL,直接传给轮播组件
-    // imageList.value = photoList.value.map((p) => p.url);
-    // imgType.value = "";
-    // currentImageData.value = {
-    //     executeName: "",
-    //     executeDate: samplingTime.value,
-    //     farmName: "",
-    //     prescriptionList: [],
-    //     farmWorkName: "农情照片",
-    //     droneDate: "",
-    // };
-    // showImagePopup.value = true;
+    const images = photoList.value.map((item) => item.url);
+    const startIndex = photoList.value.findIndex((item) => item.id === photo.id);
+
+    showImagePreview({
+        images,
+        startPosition: startIndex > -1 ? startIndex : 0,
+        closeable: true,
+        showIndex: true,
+    });
 };
 
 </script>

+ 42 - 7
src/views/old_mini/monitor/subPages/darwArea.vue

@@ -19,10 +19,11 @@
                 <div class="footer-back" @click="goBack">
                     <img class="back-icon" src="@/assets/img/home/go-back.png" alt="" />
                 </div>
-                <div class="edit-map-footer-btn confirm-btn-box" v-if="!viewOnly">
-                    <!-- <div class="btn-reset" @click="resetPolygon">重置区域</div>
-                    <div class="btn-confirm" @click="confirm">确认</div> -->
-                    <div class="btn-confirm" @click="confirm">编辑区域</div>
+                <div class="edit-map-footer-btn" v-if="!viewOnly">
+                <!-- <div class="edit-map-footer-btn confirm-btn-box" v-if="!viewOnly"> -->
+                    <div class="btn-reset" @click="resetPolygon">重置区域</div>
+                    <div class="btn-confirm" @click="confirm">确认</div>
+                    <!-- <div class="btn-confirm" @click="confirm">编辑区域</div> -->
                 </div>
             </div>
         </div>
@@ -30,6 +31,7 @@
             v-if="!viewOnly"
             v-model:show="showSuccessPopup"
             :title="`${activeVarietyName} 区域已保存成功`"
+            :has-next="varietyTabs.length > 0 && activeVariety < varietyTabs.length - 1"
             @know="handleKnow"
             @next="handleSelectNextVariety"
         />
@@ -53,6 +55,8 @@ const mapContainer = ref(null);
 const drawRegionMap = new DrawRegionMap();
 
 const showSuccessPopup = ref(false);
+// 是否从第一个品种开始的引导流程(需要全部品种都确认后再退出)
+const isGuidedFlow = ref(false);
 
 const type = ref(null);
 const varietyTabs = ref([]);
@@ -169,6 +173,7 @@ onActivated(() => {
 });
 
 onDeactivated(() => {
+    activeVariety.value = 0;
     drawRegionMap.clearLayer()
 })
 const goBack = () => {
@@ -214,11 +219,37 @@ const resetPolygon = () => {
 const confirm = () => {
     // const polygonData = drawRegionMap.getAreaGeometry();
     // sessionStorage.setItem("drawRegionPolygonData", JSON.stringify(polygonData));
-    showSuccessPopup.value = true;
+
+    // 如果当前是第一个品种,则开启完整引导流程:每次确认都弹成功提示,直到最后一个才退出
+    if (activeVariety.value === 0) {
+        isGuidedFlow.value = true;
+        showSuccessPopup.value = true;
+        return;
+    }
+
+    // 已经在引导流程中(从第一个品种开始勾选),后续品种确认也只弹成功提示,不直接跳走
+    if (isGuidedFlow.value) {
+        showSuccessPopup.value = true;
+        return;
+    }
+
+    // 非引导流程(例如直接编辑单个非第一个品种),确认后直接返回上一页
+    router.back();
 };
 
 const handleKnow = () => {
     showSuccessPopup.value = false;
+
+    const isLastVariety =
+        varietyTabs.value.length > 0 && activeVariety.value === varietyTabs.value.length - 1;
+
+    // 在引导流程中且还没到最后一个品种时,“我知道了”只关闭弹窗,不跳走
+    if (isGuidedFlow.value && !isLastVariety) {
+        return;
+    }
+
+    // 到达最后一个品种或本身就不是引导流程,才真正完成并返回
+    isGuidedFlow.value = false;
     router.back();
 };
 
@@ -230,10 +261,14 @@ const handleSelectNextVariety = () => {
     const nextIndex = activeVariety.value + 1;
     if (nextIndex < varietyTabs.value.length) {
         const nextTab = varietyTabs.value[nextIndex];
+
+        // 勾画当前品种完成后,先用统一的 clearLayer 方法重置图层,再切换到下一个品种
+        if (drawRegionMap && typeof drawRegionMap.clearLayer === "function") {
+            drawRegionMap.clearLayer();
+        }
+
         handleVarietyClick(nextTab, nextIndex);
         showSuccessPopup.value = false;
-        // 可根据业务需要在这里重置绘制区域
-        // drawRegionMap.clearLayer();
     } else {
         // 如果已经是最后一个品种,则直接返回上一页
         handleKnow();

+ 109 - 33
src/views/old_mini/monitor/subPages/farmInfo.vue

@@ -2,7 +2,7 @@
     <custom-header name="农场信息" bgColor="#f2f3f5"></custom-header>
     <div class="farm-details-page">
         <div class="farm-info">
-            <div class="map"></div>
+            <div class="map-area" ref="mapContainer"></div>
             <div class="info-box">
                 <div class="section-header">
                     <div class="line-title">基本信息</div>
@@ -11,27 +11,27 @@
                 <div class="info-list">
                     <div class="info-row">
                         <span class="info-label">农场名称:</span>
-                        <span class="info-value">{{ farmInfo.name }}</span>
+                        <span class="info-value">{{ farmInfo.subjectName }}</span>
                     </div>
                     <div class="info-row">
                         <span class="info-label">联系人:</span>
-                        <span class="info-value">{{ farmInfo.contact }}</span>
+                        <span class="info-value">{{ farmInfo.contactName }}</span>
                     </div>
                     <div class="info-row">
                         <span class="info-label">联系电话:</span>
-                        <span class="info-value">{{ farmInfo.phone }}</span>
+                        <span class="info-value">{{ farmInfo.contactPhone }}</span>
                     </div>
                     <div class="info-row">
                         <span class="info-label">种植作物:</span>
                         <div class="info-value crop-tags">
-                            <span v-for="crop in farmInfo.crops" :key="crop" class="crop-tag">
-                                {{ crop }}
+                            <span v-for="crop in farmInfo.cropList" :key="crop.id" class="crop-tag">
+                                {{ crop.name }}
                             </span>
                         </div>
                     </div>
                     <div class="info-row">
                         <span class="info-label">农场位置:</span>
-                        <span class="info-value">{{ farmInfo.location }}</span>
+                        <span class="info-value">{{ farmInfo.farmAddress }}</span>
                     </div>
                 </div>
             </div>
@@ -39,7 +39,7 @@
             <div class="info-box">
                 <div class="section-header">
                     <div class="line-title">农场设施</div>
-                    <div class="edit-btn" @click="handleEditFarmInfo">点击编辑</div>
+                    <div class="edit-btn" @click="handleEditFarmFacility">点击编辑</div>
                 </div>
                 <div class="info-list">
                     <div class="info-row">
@@ -49,8 +49,8 @@
                     <div class="info-row">
                         <span class="info-label">灌溉方式:</span>
                         <div class="info-value crop-tags">
-                            <span v-for="crop in farmInfo.crops" :key="crop" class="crop-tag">
-                                {{ crop }}
+                            <span v-for="crop in farmInfo.cropList" :key="crop.id" class="crop-tag">
+                                {{ crop.name }}
                             </span>
                         </div>
                     </div>
@@ -58,11 +58,7 @@
                         <span class="info-label">农机设备:</span>
                         <div class="info-value">
                             <div class="device-box">
-                                <div
-                                    class="device-item"
-                                    v-for="device in farmDevices"
-                                    :key="device.id"
-                                >
+                                <div class="device-item" v-for="device in farmDevices" :key="device.id">
                                     <span class="device-name">{{ device.name }}</span>
                                     <span class="device-count">{{ device.count }}架</span>
                                 </div>
@@ -72,11 +68,7 @@
                     <div class="info-row info-row-column">
                         <span class="info-label">希望改善问题:</span>
                         <div class="info-value problem-tags">
-                            <span
-                                v-for="item in improveProblems"
-                                :key="item"
-                                class="problem-tag"
-                            >
+                            <span v-for="item in improveProblems" :key="item" class="problem-tag">
                                 {{ item }}
                             </span>
                         </div>
@@ -88,19 +80,72 @@
 </template>
 
 <script setup>
-import { ref, onMounted } from "vue";
+import { ref, onMounted, onBeforeUnmount, nextTick } from "vue";
 import customHeader from "@/components/customHeader.vue";
-import { useRouter } from "vue-router";
+import { useRouter, useRoute } from "vue-router";
+import DrawRegionMap from "@/views/old_mini/interactionList/map/drawRegionMap.js";
+import * as util from "@/common/ol_common.js";
+import { useStore } from "vuex";
 
 const router = useRouter();
-const farmInfo = {
-    name: "从化荔博园",
-    contact: "张扬",
-    phone: "19871533125",
-    crops: ["桂味", "糯米糍", "井岗红糯"],
-    location: "广东省广州市从化区某某街道",
+const route = useRoute();
+const store = useStore();
+const farmInfo = ref({});
+const mapContainer = ref(null);
+const drawRegionMap = new DrawRegionMap();
+
+const initMap = () => {
+    if (!mapContainer.value) return;
+    if (drawRegionMap.kmap) return;
+
+    const info = farmInfo.value || {};
+
+    drawRegionMap.initMap(info.farmLocation, mapContainer.value, false, false, false);
+
+    // 回显农场区域,多边形 WKT 数组(有就画,没有就不画)
+    let geometryArr = [];
+    if (Array.isArray(info.geometryArr) && info.geometryArr.length > 0) {
+        geometryArr = info.geometryArr;
+    } else if (Array.isArray(info.areaGeometryArr) && info.areaGeometryArr.length > 0) {
+        geometryArr = info.areaGeometryArr;
+    }
+
+    if (geometryArr.length) {
+        // 这里不做自适应缩放,保持以中心点为主,避免点位偏上
+        drawRegionMap.setAreaGeometry(geometryArr, false, info.areaText || "");
+    }
+
+    // 在区域中心落一个点位(使用与勾画页相同的图标)
+    try {
+        const geom = util.wktCastGeom(info.farmLocation);
+        if (geom && typeof geom.getFirstCoordinate === "function") {
+            const coord = geom.getFirstCoordinate();
+            drawRegionMap.setMapPoint(coord);
+        }
+    } catch (e) {
+        // 解析失败则忽略点位
+    }
 };
 
+const destroyMap = () => {
+    if (drawRegionMap && drawRegionMap.kmap && drawRegionMap.destroyMap) {
+        drawRegionMap.destroyMap();
+    }
+};
+
+onMounted(() => {
+    fetchFarmSubjectDetail();
+});
+
+function fetchFarmSubjectDetail() {
+    VE_API.basic_farm.fetchFarmSubjectDetail({ subjectId: route.query.subjectId }).then(({ data }) => {
+        farmInfo.value = data || {};
+        nextTick(() => {
+            destroyMap();
+            initMap();
+        });
+    });
+}
 const farmDevices = [
     { id: 1, name: "植保无人机", count: 10 },
     { id: 2, name: "植保无人机", count: 10 },
@@ -113,8 +158,36 @@ const farmDevices = [
 const improveProblems = ["土壤改良", "树势增强", "品质提升"];
 
 const handleEditFarmInfo = () => {
-    console.log("点击编辑基本信息");
-    router.push(`/create_farm?type=edit&farmId=766&from=farm_info`);
+    // // 回显地块:存到 polygonData,创建页会优先使用这里的数据
+    // if (data.geomWkt) {
+    //     const polygonData = {
+    //         geometryArr: [data.geomWkt],
+    //         mianji: data.mianji,
+    //         isConfirmed: true,
+    //     };
+    //     store.commit("home/SET_FARM_POLYGON", polygonData);
+    // } else {
+    //     store.commit("home/SET_FARM_POLYGON", null);
+    // }
+
+    const params = {
+        ...farmInfo.value,
+        name: farmInfo.value.subjectName,
+        fzr: farmInfo.value.contactName,
+        tel: farmInfo.value.contactPhone,
+        mianji: farmInfo.value.farmArea,
+        address: farmInfo.value.farmAddress,
+    };
+
+    // 回显其他表单字段
+    store.commit("home/SET_EDIT_FARM_DATA", params);
+
+    // 带上 from=details,创建页提交/取消后能正确返回
+    router.push(`/create_farm?type=edit&farmId=${route.query.subjectId}&from=details`);
+};
+
+const handleEditFarmFacility = () => {
+    router.push(`/prescription?subjectId=${route.query.subjectId}`);
 };
 </script>
 
@@ -147,11 +220,10 @@ const handleEditFarmInfo = () => {
         border-radius: 8px;
         padding: 10px;
 
-        .map {
+        .map-area {
             width: 100%;
             height: 142px;
-            background: red;
-            border-radius: 5px;
+            clip-path: inset(0px round 5px);
         }
 
         .info-box {
@@ -204,6 +276,7 @@ const handleEditFarmInfo = () => {
                         display: flex;
                         flex-wrap: wrap;
                         gap: 6px;
+
                         .problem-tag {
                             padding: 2px 8px;
                             background: rgba(58, 173, 148, 0.1);
@@ -220,12 +293,14 @@ const handleEditFarmInfo = () => {
                         display: flex;
                         flex-wrap: wrap;
                         justify-content: space-between;
+
                         .device-item {
                             display: flex;
                             padding: 4px 0;
                             gap: 15px;
                             font-size: 13px;
                             color: #1D2129;
+
                             .device-count {
                                 padding: 2px 8px;
                                 background: #E8F3FF;
@@ -235,6 +310,7 @@ const handleEditFarmInfo = () => {
                         }
                     }
                 }
+
                 .info-row-column {
                     display: flex;
                     flex-direction: column;