瀏覽代碼

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

wangsisi 6 小時之前
父節點
當前提交
b43bdb86ad

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

@@ -12,6 +12,11 @@ module.exports = {
         url: url + "/save",
         url: url + "/save",
         type: "post",
         type: "post",
     },
     },
+    // 自己创建农场基于专家
+    saveBasicFarmInfoByExpert: {
+        url: config.base_dev_url + "v2/farm/selfCreateFarmByExpert",
+        type: "post",
+    },
     // 保存草稿
     // 保存草稿
     saveDraft: {
     saveDraft: {
         url: url + "/saveDraft",
         url: url + "/saveDraft",

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

@@ -89,4 +89,9 @@ module.exports = {
         url: url + "/resultReport",
         url: url + "/resultReport",
         type: "get",
         type: "get",
     },
     },
+    // 农事详情
+    getDetailById: {
+        url: url + "/detail",
+        type: "get",
+    },
 }
 }

+ 12 - 1
src/components/popup/farmInfoPopup.vue

@@ -226,7 +226,7 @@ const phenologyData = ref({});
 const specieList = ref([]);
 const specieList = ref([]);
 const fruitsList = ref([]);
 const fruitsList = ref([]);
 
 
-// 规范化多选品种 typeId(支持字符串/数组)
+// 规范化多选品种 typeId(支持字符串/数组),确保最终一定是数组
 const normalizeTypeId = (value) => {
 const normalizeTypeId = (value) => {
     if (Array.isArray(value)) return value;
     if (Array.isArray(value)) return value;
     if (value === null || value === undefined || value === "") return [];
     if (value === null || value === undefined || value === "") return [];
@@ -285,6 +285,17 @@ watch(
     { immediate: true, deep: true }
     { immediate: true, deep: true }
 );
 );
 
 
+// 无论选择几个品类,始终保证 formData.typeIds 为数组
+watch(
+    () => formData.value.typeIds,
+    (newVal) => {
+        // 仅在不是数组时进行规范化,避免死循环
+        if (!Array.isArray(newVal)) {
+            formData.value.typeIds = normalizeTypeId(newVal);
+        }
+    }
+);
+
 // 监听弹窗显示状态,重置表单
 // 监听弹窗显示状态,重置表单
 watch(
 watch(
     () => props.show,
     () => props.show,

+ 7 - 1
src/components/popup/tipPopup.vue

@@ -8,6 +8,7 @@
         teleport="body"
         teleport="body"
         :close-on-click-overlay="closeOnClickOverlay"
         :close-on-click-overlay="closeOnClickOverlay"
         @click-overlay="handleClickOverlay"
         @click-overlay="handleClickOverlay"
+        @@closed="handleClosed"
         :z-index="zIndex"
         :z-index="zIndex"
     >
     >
         <template v-if="type === 'create'">
         <template v-if="type === 'create'">
@@ -18,6 +19,7 @@
         </template>
         </template>
         <template v-else-if="type === 'success'">
         <template v-else-if="type === 'success'">
             <img class="tip-icon success-icon" src="@/assets/img/home/right.png" alt="" />
             <img class="tip-icon success-icon" src="@/assets/img/home/right.png" alt="" />
+            <slot name="default"></slot>
             <div class="tip-text success-text" :class="{pmzd:font}">{{ text }} <span class="highlight-text">{{ highlightText }}</span></div>
             <div class="tip-text success-text" :class="{pmzd:font}">{{ text }} <span class="highlight-text">{{ highlightText }}</span></div>
         </template>
         </template>
         <template v-else>
         <template v-else>
@@ -91,7 +93,7 @@ const props = defineProps({
     }
     }
 });
 });
 
 
-const emit = defineEmits(["update:show", "confirm", "handleClickOverlay"]);
+const emit = defineEmits(["update:show", "confirm", "handleClickOverlay", "closedPopup"]);
 
 
 // 处理v-model双向绑定
 // 处理v-model双向绑定
 const showValue = computed({
 const showValue = computed({
@@ -123,6 +125,10 @@ const handleClickOverlay = () => {
         emit("update:show", false);
         emit("update:show", false);
     }
     }
 };
 };
+
+const handleClosed = () => {
+    emit("closedPopup");
+};
 </script>
 </script>
 
 
 <style scoped lang="scss">
 <style scoped lang="scss">

+ 66 - 162
src/views/old_mini/agri_record/subPages/statusDetail.vue

@@ -5,34 +5,29 @@
         <div class="detail-content" :class="{ 'has-group': isLocked }">
         <div class="detail-content" :class="{ 'has-group': isLocked }">
             <!-- 橙色状态头部 -->
             <!-- 橙色状态头部 -->
             <div class="status-header" :class="'status-' + status">
             <div class="status-header" :class="'status-' + status">
-                <div class="status-left" v-show="status === 0">
+                <!-- <div class="status-left" v-if="status === -1">
                     <div class="status-text">
                     <div class="status-text">
-                        <!-- <div class="status-icon">
-                            <el-icon :size="24" color="#fff">
-                                <Warning />
-                            </el-icon>
-                        </div> -->
                         <span>未执行</span>
                         <span>未执行</span>
                     </div>
                     </div>
                     <div class="status-sub-text">执行时间已过去 7 天</div>
                     <div class="status-sub-text">执行时间已过去 7 天</div>
-                </div>
-                <div class="status-left" v-show="status === 1">
+                </div> -->
+                <div class="status-left" v-if="status === 1">
                     <div class="status-text">
                     <div class="status-text">
                         <span>已激活</span>
                         <span>已激活</span>
                     </div>
                     </div>
                     <div class="status-sub-text">距离执行时间还差 一 天</div>
                     <div class="status-sub-text">距离执行时间还差 一 天</div>
                 </div>
                 </div>
-                <div class="status-left" v-show="status === 2">
+                <div class="status-left" v-else-if="status === 5">
                     <div class="status-text">
                     <div class="status-text">
                         <span>已完成</span>
                         <span>已完成</span>
                     </div>
                     </div>
-                    <div class="status-sub-text">执行时间:2025.05.06</div>
+                    <div class="status-sub-text">执行时间:{{ detailData?.detail?.executeTime }}</div>
                 </div>
                 </div>
-                <div class="status-left" v-show="status === 3">
+                <div class="status-left" v-else-if="status === 0 || !status">
                     <div class="status-text">
                     <div class="status-text">
                         <span>未激活</span>
                         <span>未激活</span>
                     </div>
                     </div>
-                    <div class="status-sub-text">预计激活时间 2025.06.07</div>
+                    <div class="status-sub-text">预计激活时间 {{ detailData?.detail?.activateTime }}</div>
                 </div>
                 </div>
             </div>
             </div>
 
 
@@ -41,8 +36,8 @@
                 <div class="card-box content-card">
                 <div class="card-box content-card">
                     <div class="card-header">
                     <div class="card-header">
                         <div class="card-title-wrap">
                         <div class="card-title-wrap">
-                            <div class="card-title">{{ prescriptionData.title }}</div>
-                            <div class="type-tag">{{ prescriptionData.type }}</div>
+                            <div class="card-title">{{ detailData?.detail?.farmWorkName }}</div>
+                            <div class="type-tag">{{ typeMap[detailData?.detail?.farmWorkType || 1] }}</div>
                         </div>
                         </div>
                         <!-- <div class="forward-link" @click="handleForward">转发处方</div> -->
                         <!-- <div class="forward-link" @click="handleForward">转发处方</div> -->
                     </div>
                     </div>
@@ -50,15 +45,15 @@
                     <div class="card-info">
                     <div class="card-info">
                         <div class="info-item">
                         <div class="info-item">
                             <span class="info-label">下发专家</span>
                             <span class="info-label">下发专家</span>
-                            <span class="info-value">{{ prescriptionData.expert }}</span>
+                            <span class="info-value">{{ detailData?.expertNameFromFarmBasicInfo }}</span>
                         </div>
                         </div>
                         <div class="info-item">
                         <div class="info-item">
                             <span class="info-label">执行时间</span>
                             <span class="info-label">执行时间</span>
-                            <span class="info-value">{{ prescriptionData.executeTime }}</span>
+                            <span class="info-value">{{ detailData?.detail?.executeTime }}</span>
                         </div>
                         </div>
                         <div class="info-item">
                         <div class="info-item">
                             <span class="info-label">农事建议</span>
                             <span class="info-label">农事建议</span>
-                            <span class="info-value">{{ prescriptionData.advice }}</span>
+                            <span class="info-value">{{ detailData?.detail?.purpose }}</span>
                         </div>
                         </div>
                     </div>
                     </div>
 
 
@@ -76,11 +71,11 @@
                     <transition name="prescription-slide">
                     <transition name="prescription-slide">
                         <div class="new-wrap"
                         <div class="new-wrap"
                             :class="{'has-lock': isLocked}"
                             :class="{'has-lock': isLocked}"
-                            v-show="showPrescription && detailData?.prescriptionList?.length && detailData?.prescriptionList[0]?.pesticideFertilizerList?.length > 0">
+                            v-show="showPrescription && detailData?.detail?.prescriptionList?.length && detailData?.detail?.prescriptionList[0]?.pesticideFertilizerList?.length > 0">
                             
                             
                             <div class="info-item pb-8">
                             <div class="info-item pb-8">
                                 <span class="info-label">施用方式</span>
                                 <span class="info-label">施用方式</span>
-                                <span class="info-value">{{ prescriptionData.applyMethod }}</span>
+                                <span class="info-value">{{ detailData?.detail?.usageMode }}</span>
                             </div>
                             </div>
 
 
                             <div class="new-wrap-inner">
                             <div class="new-wrap-inner">
@@ -99,7 +94,7 @@
                                     </div>
                                     </div>
                                 </div>
                                 </div>
                                 <div class="new-table-wrap"
                                 <div class="new-table-wrap"
-                                    v-for="(prescriptionItem, prescriptionI) in detailData?.prescriptionList"
+                                    v-for="(prescriptionItem, prescriptionI) in detailData?.detail?.prescriptionList"
                                     :key="prescriptionI">
                                     :key="prescriptionI">
                                     <div class="new-prescription"
                                     <div class="new-prescription"
                                         v-for="(subP, subI) in prescriptionItem.pesticideFertilizerList" :key="subI">
                                         v-for="(subP, subI) in prescriptionItem.pesticideFertilizerList" :key="subI">
@@ -111,9 +106,9 @@
                                             </div>
                                             </div>
                                             <div class="line-r">
                                             <div class="line-r">
                                                 <div class="line-3">
                                                 <div class="line-3">
-                                                    <div class="sub-line title-4">{{ quotationData.executionMethod === 1 ?
+                                                    <div class="sub-line title-4">{{ detailData?.detail?.executionMethod === 1 ?
                                                         subP.ratio2 : subP.ratio }}倍</div>
                                                         subP.ratio2 : subP.ratio }}倍</div>
-                                                    <div class="sub-line title-5">{{ quotationData.executionMethod === 1 ?
+                                                    <div class="sub-line title-5">{{ detailData?.detail?.executionMethod === 1 ?
                                                         subP.muUsage2 : subP.muUsage }}{{ subP.unit }}</div>
                                                         subP.muUsage2 : subP.muUsage }}{{ subP.unit }}</div>
                                                 </div>
                                                 </div>
                                             </div>
                                             </div>
@@ -148,16 +143,19 @@
                         <!-- <div class="forward-link" @click="handleForward">转发操作指南</div> -->
                         <!-- <div class="forward-link" @click="handleForward">转发操作指南</div> -->
                     </div>
                     </div>
                     <div class="video-wrap">
                     <div class="video-wrap">
-                        <photo-provider :photo-closable="true">
+                        <photo-provider :photo-closable="true" v-if="guideSrc">
                             <photo-consumer
                             <photo-consumer
                                 :src="guideSrc"
                                 :src="guideSrc"
                             >
                             >
                             <img class="video-img" :src="guideSrc" alt="">
                             <img class="video-img" :src="guideSrc" alt="">
                             </photo-consumer>
                             </photo-consumer>
                         </photo-provider>
                         </photo-provider>
-                        <div class="video-play-icon van-multi-ellipsis--l2">
-                            内膛喷施内膛喷施内膛喷施内膛喷施内膛喷施内膛喷施内膛喷施内膛喷施内膛喷施内膛喷施内膛喷施内膛喷施内膛喷施...
-                            <span class="expand-text">展开详细操作指南</span>
+                        <div class="video-play-icon">
+                            <div
+                                class="html-ellipsis"
+                                v-html="detailData?.post?.content"
+                            ></div>
+                            <!-- <span class="expand-text">展开详细操作指南</span> -->
                         </div>
                         </div>
                         <!-- <video src="https://birdseye-img-ali-cdn.sysuimars.com/bbs_post/video/1767872309467.mp4"
                         <!-- <video src="https://birdseye-img-ali-cdn.sysuimars.com/bbs_post/video/1767872309467.mp4"
                             controls style="width: 100%; max-width: 100%; height: auto; border-radius: 8px"
                             controls style="width: 100%; max-width: 100%; height: auto; border-radius: 8px"
@@ -219,9 +217,9 @@
              </div>
              </div>
 
 
              <!-- 我已执行 -->
              <!-- 我已执行 -->
-             <div class="bottom-btn-wrap">
+             <!-- <div class="bottom-btn-wrap">
                 <div class="bottom-btn" @click="selectExecuteTime">我已执行</div>
                 <div class="bottom-btn" @click="selectExecuteTime">我已执行</div>
-             </div>
+             </div> -->
         </div>
         </div>
 
 
         <!-- 二维码弹窗 -->
         <!-- 二维码弹窗 -->
@@ -259,7 +257,7 @@
 import { useRouter, useRoute } from "vue-router";
 import { useRouter, useRoute } from "vue-router";
 import { showSuccessToast } from 'vant';
 import { showSuccessToast } from 'vant';
 import { ElMessage } from "element-plus";
 import { ElMessage } from "element-plus";
-import { ref } from "vue";
+import { ref, onActivated } from "vue";
 import customHeader from "@/components/customHeader.vue";
 import customHeader from "@/components/customHeader.vue";
 import { Warning } from "@element-plus/icons-vue";
 import { Warning } from "@element-plus/icons-vue";
 import upload from "@/components/upload";
 import upload from "@/components/upload";
@@ -271,7 +269,7 @@ import { formatDate } from "@/common/commonFun";
 const router = useRouter();
 const router = useRouter();
 const route = useRoute();
 const route = useRoute();
 
 
-const status = ref(3);
+const status = ref(null);
 
 
 // 处方数据(可以从接口获取或从路由参数获取)
 // 处方数据(可以从接口获取或从路由参数获取)
 const prescriptionData = ref({
 const prescriptionData = ref({
@@ -284,11 +282,18 @@ const prescriptionData = ref({
     applyMethod: "内膛喷施",
     applyMethod: "内膛喷施",
 });
 });
 
 
+const typeMap = ref({
+    0: "预警农事",
+    1: "标准农事",
+    2: "建议农事",
+    3: "自建农事",
+});
+
 const handleClose = () => {
 const handleClose = () => {
     router.go(-1);
     router.go(-1);
 };
 };
 
 
-const guideSrc = ref("https://birdseye-img-ali-cdn.sysuimars.com/2d75eb9c-822a-46e1-a5da-8ac0823619bb/a9e5dcdf-ab88-4098-8a1a-51873c9afe2d/DJI_202511290800_001_a9e5dcdf-ab88-4098-8a1a-51873c9afe2d/DJI_20251129081259_0112_V_code-ws0gefzht1u7.jpeg?x-oss-process=image/resize,p_50/format,webp/quality,q_50");
+const guideSrc = ref(null);
 const groupSrc = ref(require("@/assets/img/home/qrcode.png"));
 const groupSrc = ref(require("@/assets/img/home/qrcode.png"));
 
 
 const showCalendar = ref(false);
 const showCalendar = ref(false);
@@ -343,134 +348,8 @@ const handleViewPrescription = () => {
 // 控制执行区域地图展开/收起
 // 控制执行区域地图展开/收起
 const showMapArea = ref(false);
 const showMapArea = ref(false);
 
 
-const detailData = ref(
-    {
-        "consequenceText": "",
-        "id": "280962",
-        "reCheckText": "",
-        "orderId": "801082980008202240",
-        "farmWorkArrangeId": "11272",
-        "farmName": "荔枝博览园",
-        "farmPoint": "POINT(113.61702297075017 23.584863449735067)",
-        "area": 300,
-        "expert": "739294587868155904",
-        "orderStatus": 0,
-        "activeStatus": null,
-        "flowStatus": 5,
-        "farmId": 766,
-        "regionId": null,
-        "farmMiniUserId": 90739,
-        "farmMiniUserName": "",
-        "speciesId": "1",
-        "speciesName": "荔枝",
-        "agriculturalId": 214,
-        "agriculturalIcon": "",
-        "farmWorkId": "801074109092990976",
-        "farmWorkLibId": "801074109092990976",
-        "farmWorkLibName": "冬季防治(地面)",
-        "farmWorkName": "冬季防治(地面)",
-        "expertName": "飞鸟种植助手",
-        "expertUserName": "飞鸟种植助手",
-        "expertIcon": "https://birdseye-img-ali-cdn.sysuimars.com//expert/1757473957076.png",
-        "expertUserIcon": "https://birdseye-img-ali-cdn.sysuimars.com//expert/1757473957076.png",
-        "icon": null,
-        "indexName": "",
-        "indexChart": [],
-        "executeDate": "2026-01-19",
-        "executeDeadlineDate": "2026-01-19",
-        "expectedExecuteDate": "2026-01-19",
-        "finishDate": null,
-        "checkDate": null,
-        "beforeExecuteDate": null,
-        "indexJson": "",
-        "expertPrescription": "",
-        "code": "801074109080408065",
-        "condition": "",
-        "solarName": "",
-        "reCheck": 1,
-        "menu": 1,
-        "num": null,
-        "purpose": "",
-        "type": 1,
-        "farmWorkType": 3,
-        "farmWorkTypeName": "病虫",
-        "execute": 3,
-        "updateDate0": "2026-01-19",
-        "updateDate1": null,
-        "updateDate2": null,
-        "updateDate3": null,
-        "updateDate4": null,
-        "updateDate5": null,
-        "updateDate6": null,
-        "confirmPicture": [],
-        "executeEvidence": [
-            "birdseye-look-mini/94379/1768801082504.png",
-            "birdseye-look-mini/94379/1768801086136.png"
-        ],
-        "reviewImage": [],
-        "reviewImage2": [],
-        "reviewDate": null,
-        "reviewDate2": null,
-        "serviceRegion": "广州市从化区荔枝博览园",
-        "usageMode": "地面喷施",
-        "serviceMain": "数域行",
-        "executeMain": "数域行",
-        "storeShortName": "",
-        "weatherWarningMsg": "",
-        "userEvaluation": null,
-        "executeBlueZones": [],
-        "isMaster": null,
-        "isEdit": 0,
-        "selfExec": null,
-        "defaultFarmWork": 1,
-        "isPublic": 0,
-        "prescriptionList": [
-            {
-                "name": "病虫",
-                "pesticideFertilizerList": [
-                    {
-                        "defaultName": "",
-                        "id": null,
-                        "muPrice": 1,
-                        "muUsage": 20,
-                        "muUsage2": 20,
-                        "price": "",
-                        "ratio": 1000,
-                        "ratio2": 100,
-                        "remark": "",
-                        "usageMode": "",
-                        "usageModeList": [
-                            "叶面施"
-                        ],
-                        "pesticideFertilizerCode": "1522",
-                        "pesticideFertilizerId": "776945747475042304",
-                        "pesticideFertilizerName": "5%高氯·甲维盐微乳剂",
-                        "brand": "默认品牌",
-                        "typeName": "胃毒性",
-                        "unit": "ml"
-                    }
-                ]
-            }
-        ],
-        "needReview": 0,
-        "conditionList": [],
-        "actualAgriculturalInput": null,
-        "actualFarmServiceInput": null,
-        "actualTotalInput": 996,
-        "executeName": "张扬",
-        "executorIcon": "https://birdseye-img.sysuimars.com/dinggou-mini/defalut-icon.png",
-        "executorUserId": 94379
-    }
-);
-
+const detailData = ref({});
 
 
-const quotationData = ref(
-    {
-        "executionMethodName": "地面喷施",
-        "executionMethod": 1,
-    }
-);
-// TODO: 根据实际数据来源设置 farmId,比如从接口详情或路由参数中获取
 const farmId = ref(94500);
 const farmId = ref(94500);
 
 
 const handleViewArea = () => {
 const handleViewArea = () => {
@@ -500,6 +379,20 @@ const handleShowQrCodePopup = (type) => {
 };
 };
 
 
 const isLocked = ref(false);
 const isLocked = ref(false);
+
+onActivated(() => {
+    const id = route.query.miniJson ? JSON.parse(route.query.miniJson).id : null;
+    if (id) {
+        getDetail(281571);
+    }
+});
+
+const getDetail = async (id) => {
+    const { data } = await VE_API.z_farm_work_record.getDetailById({ id });
+    detailData.value = data;
+    status.value = data.detail?.flowStatus;
+    guideSrc.value = data?.post?.media ? JSON.parse(data?.post?.media)[0] : null;
+};
 </script>
 </script>
 
 
 <style lang="scss" scoped>
 <style lang="scss" scoped>
@@ -541,7 +434,7 @@ const isLocked = ref(false);
 
 
     &.status-0 {
     &.status-0 {
         &::after {
         &::after {
-            background: #ff6666;
+            background: #C7C7C7;
         }
         }
     }
     }
 
 
@@ -551,7 +444,7 @@ const isLocked = ref(false);
         }
         }
     }
     }
 
 
-    &.status-2 {
+    &.status-5 {
         &::after {
         &::after {
             background: #2199f8;
             background: #2199f8;
         }
         }
@@ -559,7 +452,7 @@ const isLocked = ref(false);
 
 
     &.status-3 {
     &.status-3 {
         &::after {
         &::after {
-            background: #C7C7C7;
+            background: #ff6666;
         }
         }
     }
     }
 
 
@@ -630,6 +523,7 @@ const isLocked = ref(false);
 
 
 .card-wrap {
 .card-wrap {
     padding: 0 12px;
     padding: 0 12px;
+    // padding-bottom: 58px;
 }
 }
 
 
 .content-card {
 .content-card {
@@ -733,7 +627,7 @@ const isLocked = ref(false);
         display: flex;
         display: flex;
         color: #767676;
         color: #767676;
         // justify-content: space-around;
         // justify-content: space-around;
-        padding: 5px 6px;
+        padding: 5px 0px;
         font-size: 12px;
         font-size: 12px;
 
 
         .table-name {
         .table-name {
@@ -850,6 +744,15 @@ const isLocked = ref(false);
         .video-play-icon {
         .video-play-icon {
             padding-top: 12px;
             padding-top: 12px;
             font-size: 14px;
             font-size: 14px;
+                .html-ellipsis {
+                    display: -webkit-box;
+                    -webkit-box-orient: vertical;
+                    -webkit-line-clamp: 2;
+                    overflow: hidden;
+                    word-break: break-word;
+                    line-height: 20px;
+                    color: #4e5969;
+                }
             .expand-text {
             .expand-text {
                 color: #2199f8;
                 color: #2199f8;
             }
             }
@@ -889,6 +792,7 @@ const isLocked = ref(false);
 
 
 .bottom-btn-wrap {
 .bottom-btn-wrap {
     position: fixed;
     position: fixed;
+    z-index: 2;
     bottom: 0;
     bottom: 0;
     left: 0;
     left: 0;
     width: 100%;
     width: 100%;

+ 17 - 2
src/views/old_mini/create_farm/index.vue

@@ -251,8 +251,8 @@ onMounted(() => {
     hasDefaultPolygon.value = false; // 初始化时没有默认地块
     hasDefaultPolygon.value = false; // 初始化时没有默认地块
 
 
     centerPoint.value = store.state.home.miniUserLocationPoint;
     centerPoint.value = store.state.home.miniUserLocationPoint;
-    const arr = convertPointToArray(centerPoint.value);
-    getLocationName(`${arr[1]},${arr[0]}`);
+    // const arr = convertPointToArray(centerPoint.value);
+    // getLocationName(`${arr[1]},${arr[0]}`);
     indexMap.initMap(centerPoint.value, mapContainer.value);
     indexMap.initMap(centerPoint.value, mapContainer.value);
 
 
     // 不再初始化时绘制默认地块,等待用户点击"新增地块"按钮
     // 不再初始化时绘制默认地块,等待用户点击"新增地块"按钮
@@ -276,6 +276,10 @@ const polygonArr = ref(null);
 const paramsType = ref(null);
 const paramsType = ref(null);
 onActivated(() => {
 onActivated(() => {
     paramsType.value = route.query.type;
     paramsType.value = route.query.type;
+
+    centerPoint.value = store.state.home.miniUserLocationPoint;
+    const arr = convertPointToArray(centerPoint.value);
+    getLocationName(`${arr[1]},${arr[0]}`);
     // 仅在携带 isReload 标记、且不是编辑/小程序回流场景时,认为是一次全新创建,重置表单和地块,
     // 仅在携带 isReload 标记、且不是编辑/小程序回流场景时,认为是一次全新创建,重置表单和地块,
     // 避免破坏原有自动生成农场名称等逻辑
     // 避免破坏原有自动生成农场名称等逻辑
     if (route.query.isReload && paramsType.value !== "edit" && !route.query.miniJson) {
     if (route.query.isReload && paramsType.value !== "edit" && !route.query.miniJson) {
@@ -530,7 +534,18 @@ const submitForm = (formEl) => {
                 if (Array.isArray(queryParams.geom)) {
                 if (Array.isArray(queryParams.geom)) {
                     queryParams.geom = JSON.stringify(queryParams.geom);
                     queryParams.geom = JSON.stringify(queryParams.geom);
                 }
                 }
+                delete queryParams.speciesItem;
                 queryParams.speciesName = ruleForm.speciesItem?.name;
                 queryParams.speciesName = ruleForm.speciesItem?.name;
+                // 根据 typeIds 获取对应的名字
+                if (ruleForm.typeIds && ruleForm.typeIds.length > 0 && fruitsList.value.length > 0) {
+                    queryParams.typeNames = JSON.stringify(ruleForm.typeIds
+                        .map(id => {
+                            const typeItem = fruitsList.value.find(item => item.id === id);
+                            return typeItem ? typeItem.name : null;
+                        })
+                        .filter(name => name !== null));
+                }
+                console.log('queryParams', queryParams.typeNames)
 
 
                 router.push({
                 router.push({
                     path: "/prescription",
                     path: "/prescription",

+ 8 - 2
src/views/old_mini/home/components/farmInfoPopup.vue

@@ -33,10 +33,10 @@
                     <field v-model="farmInfo.tel" readonly label="联系电话" />
                     <field v-model="farmInfo.tel" readonly label="联系电话" />
                     <field class="address-field" v-model="farmInfo.address" readonly label="农场位置" />
                     <field class="address-field" v-model="farmInfo.address" readonly label="农场位置" />
                     
                     
-                    <field v-model="farmInfo.baseType" readonly label="基地类">
+                    <field v-model="farmInfo.baseType" readonly label="基地类">
                         <template #input>
                         <template #input>
                             <!-- <span>{{ userTypeMap[farmInfo.userType] }}</span> -->
                             <!-- <span>{{ userTypeMap[farmInfo.userType] }}</span> -->
-                            <span>{{ farmInfo?.baseType }}</span>
+                            <span>{{ baseTypeMap[farmInfo?.baseType] }}</span>
                         </template>
                         </template>
                     </field>
                     </field>
                     <checkbox
                     <checkbox
@@ -70,6 +70,12 @@ const userTypeMap = {
     3: "优质客户",
     3: "优质客户",
 };
 };
 
 
+const baseTypeMap = {
+    1: "农民专业合作组织",
+    2: "农业企业",
+    3: "家庭农场",
+}
+
 const props = defineProps({
 const props = defineProps({
     farmId: {
     farmId: {
         type: [Number, String],
         type: [Number, String],

+ 5 - 4
src/views/old_mini/home/components/knowledgeCard.vue

@@ -8,9 +8,9 @@
                 <div class="title-item" :class="{ active: activeKnowledgeId === 6 }" @click="handleKnowledgeClick(6)">
                 <div class="title-item" :class="{ active: activeKnowledgeId === 6 }" @click="handleKnowledgeClick(6)">
                     种植精华
                     种植精华
                 </div>
                 </div>
-                <div class="title-item" :class="{ active: activeKnowledgeId === 7 }" @click="handleKnowledgeClick(7)">
+                <!-- <div class="title-item" :class="{ active: activeKnowledgeId === 7 }" @click="handleKnowledgeClick(7)">
                     实战操作
                     实战操作
-                </div>
+                </div> -->
             </div>
             </div>
             <div class="more-text" @click="handleMoreClick">
             <div class="more-text" @click="handleMoreClick">
                 更多<el-icon class="more-icon"><ArrowRight /></el-icon>
                 更多<el-icon class="more-icon"><ArrowRight /></el-icon>
@@ -28,8 +28,8 @@
                     <div class="title van-ellipsis">{{ item.title }}</div>
                     <div class="title van-ellipsis">{{ item.title }}</div>
                     <div class="focus-expert">
                     <div class="focus-expert">
                         <div class="expert-name">
                         <div class="expert-name">
-                            <el-avatar :size="22" :src="item.icon" />
-                            {{ item.name || '专家' }}
+                            <el-avatar :size="22" :src="item.expertAvatar+resize_300" />
+                            {{ item.expertName || '专家' }}
                             <span class="expert-text">发表了回复,点击查看</span>
                             <span class="expert-text">发表了回复,点击查看</span>
                         </div>
                         </div>
                         <div class="date">{{ formatDate(item.createTime) }}</div>
                         <div class="date">{{ formatDate(item.createTime) }}</div>
@@ -66,6 +66,7 @@
 import { onMounted, ref, watch } from "vue";
 import { onMounted, ref, watch } from "vue";
 import { useRouter } from "vue-router";
 import { useRouter } from "vue-router";
 import { useStore } from "vuex";
 import { useStore } from "vuex";
+import { resize_300 } from "@/api/config";
 
 
 const router = useRouter();
 const router = useRouter();
 const store = useStore();
 const store = useStore();

+ 0 - 1
src/views/old_mini/home/index.vue

@@ -120,7 +120,6 @@ const handleAgriLater = () => {
 };
 };
 
 
 const handleAgriExecuted = () => {
 const handleAgriExecuted = () => {
-    console.log("我已执行111", agriExecuteData.value);
     if (agriExecuteData.value.executedButtonText === '开始采集') {
     if (agriExecuteData.value.executedButtonText === '开始采集') {
         router.push("/interaction_list?expertMiniUserId=81881&oldUser=true");
         router.push("/interaction_list?expertMiniUserId=81881&oldUser=true");
     } else {
     } else {

+ 526 - 38
src/views/old_mini/home/subPages/prescriptionPage.vue

@@ -73,25 +73,34 @@
                 </div>
                 </div>
                 <div class="farm-scale-form">
                 <div class="farm-scale-form">
                     <div class="farm-scale-item">
                     <div class="farm-scale-item">
-                        <label class="farm-scale-label">一般长工人数</label>
+                        <div class="farm-scale-label">
+                            农场固定长工
+                            <div class="sub-label">(会操作各种小型农机)</div>
+                        </div>
                         <el-input v-model="farmScale.regularWorkerCount" placeholder="请输入人数" class="farm-scale-input">
                         <el-input v-model="farmScale.regularWorkerCount" placeholder="请输入人数" class="farm-scale-input">
                             <template #append>人</template>
                             <template #append>人</template>
                         </el-input>
                         </el-input>
                     </div>
                     </div>
                     <div class="farm-scale-item">
                     <div class="farm-scale-item">
-                        <label class="farm-scale-label">植保技能人数</label>
+                        <label class="farm-scale-label">无人机植保人员</label>
                         <el-input v-model="farmScale.plantProtectionWorkerCount" placeholder="请输入人数" class="farm-scale-input">
                         <el-input v-model="farmScale.plantProtectionWorkerCount" placeholder="请输入人数" class="farm-scale-input">
                             <template #append>人</template>
                             <template #append>人</template>
                         </el-input>
                         </el-input>
                     </div>
                     </div>
                     <div class="farm-scale-item">
                     <div class="farm-scale-item">
-                        <label class="farm-scale-label">剪枝技能人数</label>
+                        <label class="farm-scale-label">专业树形修剪人员</label>
+                        <el-input v-model="farmScale.pruningWorkerCount" placeholder="请输入人数" class="farm-scale-input">
+                            <template #append>人</template>
+                        </el-input>
+                    </div>
+                    <div class="farm-scale-item">
+                        <label class="farm-scale-label">专业嫁接换种人员</label>
                         <el-input v-model="farmScale.pruningWorkerCount" placeholder="请输入人数" class="farm-scale-input">
                         <el-input v-model="farmScale.pruningWorkerCount" placeholder="请输入人数" class="farm-scale-input">
                             <template #append>人</template>
                             <template #append>人</template>
                         </el-input>
                         </el-input>
                     </div>
                     </div>
                     <div class="farm-scale-item">
                     <div class="farm-scale-item">
-                        <label class="farm-scale-label">农忙时可调度人数</label>
+                        <label class="farm-scale-label">农忙可调度人员</label>
                         <el-input v-model="farmScale.tempDispatchWorkerCount" placeholder="请输入人数" class="farm-scale-input">
                         <el-input v-model="farmScale.tempDispatchWorkerCount" placeholder="请输入人数" class="farm-scale-input">
                             <template #append>人</template>
                             <template #append>人</template>
                         </el-input>
                         </el-input>
@@ -129,7 +138,7 @@
                                 <span class="text">{{ item.name }}</span>
                                 <span class="text">{{ item.name }}</span>
                             </div>
                             </div>
                         </div> -->
                         </div> -->
-                            <el-radio-group v-model="basicForm.expertOptions">
+                            <el-radio-group v-model="basicForm.expertCode">
                                 <el-radio-button v-for="(item, index) in basicFarmFormData.expertOptions" :key="index"
                                 <el-radio-button v-for="(item, index) in basicFarmFormData.expertOptions" :key="index"
                                     :label="item.name" :value="item.code" />
                                     :label="item.name" :value="item.code" />
                             </el-radio-group>
                             </el-radio-group>
@@ -161,24 +170,79 @@
                 <span class="ml-2">数量</span>
                 <span class="ml-2">数量</span>
             </div>
             </div>
             <el-input class="popup-input" v-model="popupInputNum" :placeholder="'请输入' + formNameObj[addTypeKey]+'数量'" size="large">
             <el-input class="popup-input" v-model="popupInputNum" :placeholder="'请输入' + formNameObj[addTypeKey]+'数量'" size="large">
-                <template #append>{{ machineryUnit || '辆/架' }}</template>
+                <template #append>{{ machineryUnit || '辆' }}</template>
             </el-input>
             </el-input>
         </div>
         </div>
         <div class="popup-button">
         <div class="popup-button">
-            <div class="delete" v-if="isEditPopup" @click="handleDelete">删除</div>
+            <div class="delete" v-if="isEditPopup && isMachineSelf" @click="handleDelete">删除</div>
+            <div class="delete" v-else-if="isEditPopup && !isMachineSelf" @click="handleCancelSelect">取消选中</div>
             <div class="cancel" v-else @click="showAddPopup = false">取消</div>
             <div class="cancel" v-else @click="showAddPopup = false">取消</div>
             <div @click="handleConfirm">确认</div>
             <div @click="handleConfirm">确认</div>
         </div>
         </div>
     </popup>
     </popup>
+
+    <!-- 物候期信息 -->
+    <popup class="period-popup" round v-model:show="showPeriodPopup">
+        <div class="period-header">为了{{ basicForm?.expertInfo?.name }}专家的处方体系适用于您的果园管理,请完善基本物候信息</div>
+        <div class="period-content">
+            <div class="period-item" v-for="(item, i) in phenologyList" :key="i">
+                <div class="period-item-name">{{ item.typeName }}</div>
+                <div class="period-item-label">
+                    <div class="label-item-group">
+                        <div class="label-item">当下物候期</div>
+                        <div class="label-item-value period-display">{{ item.phenologyName }}</div>
+                    </div>
+                    <div class="label-item-group">
+                        <div class="label-item">{{ item.startDateLabel || '起始时间' }}</div>
+                        <div class="label-item-value">
+                            <el-date-picker
+                                v-model="item.phenologyStartDate"
+                                type="date"
+                                :default-value="new Date(2026, 1, 1)"
+                                placeholder="选择时间"
+                                :disabled-date="disabledDate"
+                                :clearable="false"
+                                format="YYYY-MM-DD"
+                                value-format="YYYY-MM-DD"
+                                style="width: 100%"
+                            />
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+        <div class="period-footer">
+            <div class="period-footer-btn" @click="handlePeriodConfirm">确认信息</div>
+        </div>
+    </popup>
+
+    <tip-popup
+        v-model:show="showSuccessPopup"
+        type="success"
+        text="专属处方已经生成"
+        buttonText="点击查看"
+        @closedPopup="handleSuccessConfirm"
+        @confirm="handleSuccessConfirm"
+    >
+        <template #default>
+            <div class="expert-info">
+                <img class="expert-img" src="@/assets/img/home/zj-1.png" alt="">
+                {{ basicForm?.expertInfo?.name }}  专家的
+            </div>
+        </template>
+    </tip-popup>
 </template>
 </template>
 
 
 <script setup>
 <script setup>
-import { ref, onActivated } from "vue";
+import { ref, onActivated, onBeforeUnmount, onDeactivated, onMounted } from "vue";
 import { ElMessage } from "element-plus";
 import { ElMessage } from "element-plus";
 import { useRouter, useRoute } from "vue-router";
 import { useRouter, useRoute } from "vue-router";
+import tipPopup from "@/components/popup/tipPopup.vue";
 import { Popup } from "vant";
 import { Popup } from "vant";
+import { useStore } from "vuex";
 const router = useRouter();
 const router = useRouter();
 const route = useRoute();
 const route = useRoute();
+const store = useStore();
 
 
 const outputList = ref([
 const outputList = ref([
     { name: "低温冻害" },
     { name: "低温冻害" },
@@ -203,20 +267,79 @@ onActivated(() => {
     // 为 productList 的每个 group 设置默认选中第一项
     // 为 productList 的每个 group 设置默认选中第一项
 });
 });
 
 
+onMounted(() => {
+    getCurrentAndNextPhenology();
+});
+
 const basicForm = ref({
 const basicForm = ref({
     soilTypes: "",
     soilTypes: "",
     irrigationMethods: [],
     irrigationMethods: [],
     machineryWithQuantity: [],
     machineryWithQuantity: [],
     improvementAreas: [],
     improvementAreas: [],
+    expertCode: "",
+    expertInfo: {},
 });
 });
 
 
 const basicFarmFormData = ref({});
 const basicFarmFormData = ref({});
 const getBasicFarmFormData = () => {
 const getBasicFarmFormData = () => {
-    VE_API.basic_farm.fetchBasicFarmFormData({ farmId: 766 }).then(({ data }) => {
+    VE_API.basic_farm.fetchBasicFarmFormData().then(({ data }) => {
         basicFarmFormData.value = data;
         basicFarmFormData.value = data;
+        
+        // 根据返回的数据进行默认赋值
+        // 1. 土壤类型 - 找到 selected: true 的项
+        if (data.soilTypes && Array.isArray(data.soilTypes)) {
+            const selectedSoilType = data.soilTypes.find(item => item.selected);
+            if (selectedSoilType) {
+                basicForm.value.soilTypes = selectedSoilType.code;
+            }
+        }
+        
+        // 2. 专家选项 - 找到 selected: true 的项
+        if (data.expertOptions && Array.isArray(data.expertOptions)) {
+            const selectedExpert = data.expertOptions.find(item => item.selected);
+            if (selectedExpert) {
+                basicForm.value.expertCode = selectedExpert.code;
+                basicForm.value.expertInfo = selectedExpert;
+            }
+        }
+        
+        // 3. 农场规模数据
+        if (data.farmScale) {
+            farmScale.value = {
+                regularWorkerCount: data.farmScale.regularWorkerCount || "",
+                plantProtectionWorkerCount: data.farmScale.plantProtectionWorkerCount || "",
+                pruningWorkerCount: data.farmScale.pruningWorkerCount || "",
+                tempDispatchWorkerCount: data.farmScale.tempDispatchWorkerCount || "",
+            };
+        }
+        
+        // 4. irrigationMethods, improvementAreas, machinery 的 selected 状态已经在 data 中设置好了
+        // 这些数据会直接显示在页面上,因为页面是通过 basicFarmFormData 来渲染的
     });
     });
 }
 }
 
 
+// 收集表单数据并保存草稿
+const saveDraft = async () => {
+    try {
+        const draftData = handleSubmit();
+
+        // 调用保存草稿接口
+        await VE_API.basic_farm.saveDraft(draftData);
+    } catch (error) {
+        console.error("保存草稿失败:", error);
+        // 静默失败,不显示错误提示
+    }
+};
+
+// 离开页面时保存草稿
+onBeforeUnmount(() => {
+    // saveDraft();
+});
+
+onDeactivated(() => {
+    saveDraft();
+});
+
 const formNameObj = ref({
 const formNameObj = ref({
     irrigationMethods: '灌溉方式',
     irrigationMethods: '灌溉方式',
     crops: '作物',
     crops: '作物',
@@ -246,6 +369,7 @@ function handleMachineryAdd(type) {
 }
 }
 
 
 function handleSelect(type, index, custom) {
 function handleSelect(type, index, custom) {
+    isMachineSelf.value = custom;
     if (custom === true) {
     if (custom === true) {
         showAddPopup.value = true;
         showAddPopup.value = true;
         isEditPopup.value = true;
         isEditPopup.value = true;
@@ -278,12 +402,16 @@ function handleConfirm() {
             
             
             saveCustomOption(popupInputVal.value);
             saveCustomOption(popupInputVal.value);
         } else {
         } else {
-            basicFarmFormData.value[addTypeKey.value][currentEditIndex.value].name = popupInputVal.value;
-            basicFarmFormData.value[addTypeKey.value][currentEditIndex.value].quantity = popupInputNum.value;
-            basicFarmFormData.value[addTypeKey.value][currentEditIndex.value].selected = true;
+            const option = basicFarmFormData.value[addTypeKey.value][currentEditIndex.value]
+            option.name = popupInputVal.value;
+            option.quantity = popupInputNum.value;
+            option.selected = true;
             // 更新名称
             // 更新名称
             console.log('更新名称', basicFarmFormData.value[addTypeKey.value][currentEditIndex.value]);
             console.log('更新名称', basicFarmFormData.value[addTypeKey.value][currentEditIndex.value]);
-            updateCustomOption(popupInputVal.value, basicFarmFormData.value[addTypeKey.value][currentEditIndex.value].id);
+            if (option.custom) {
+                // updateCustomOption(popupInputVal.value, option.id || option.code);
+                updateCustomOption(popupInputVal.value, basicFarmFormData.value[addTypeKey.value][currentEditIndex.value].id);
+            }
         }
         }
         currentEditIndex.value = -1;
         currentEditIndex.value = -1;
         isEditPopup.value = false;
         isEditPopup.value = false;
@@ -294,14 +422,15 @@ function handleConfirm() {
         return;
         return;
     }
     }
     if (isEditPopup.value) {
     if (isEditPopup.value) {
-        basicFarmFormData.value[addTypeKey.value][currentEditIndex.value].name = popupInputVal.value;
+        const option = basicFarmFormData.value[addTypeKey.value][currentEditIndex.value]
+        option.name = popupInputVal.value;
         currentEditIndex.value = -1;
         currentEditIndex.value = -1;
         isEditPopup.value = false;
         isEditPopup.value = false;
         showAddPopup.value = false;
         showAddPopup.value = false;
-        updateCustomOption(popupInputVal.value, basicFarmFormData.value[addTypeKey.value][currentEditIndex.value].id);
+        updateCustomOption(popupInputVal.value, option.id || option.code);
         return;
         return;
     }
     }
-    basicFarmFormData.value[addTypeKey.value].push({ name: popupInputVal.value, code: popupInputVal.value, selected: true, custom: true });
+    // basicFarmFormData.value[addTypeKey.value].push({ name: popupInputVal.value, code: popupInputVal.value, selected: true, custom: true });
     saveCustomOption(popupInputVal.value);
     saveCustomOption(popupInputVal.value);
 
 
     showAddPopup.value = false;
     showAddPopup.value = false;
@@ -336,39 +465,276 @@ function handleDelete() {
     });
     });
 }
 }
 
 
+function handleCancelSelect() {
+    const option = basicFarmFormData.value[addTypeKey.value][currentEditIndex.value]
+    option.selected = false;
+    option.quantity = null;
+    currentEditIndex.value = -1;
+    showAddPopup.value = false;
+}
+
 const goBack = () => {
 const goBack = () => {
+    // saveDraft();
     // router.go(-1);
     // router.go(-1);
     router.replace(`/create_farm?from=${route.query.from}&type=${route.query.type}`)
     router.replace(`/create_farm?from=${route.query.from}&type=${route.query.type}`)
 };
 };
 
 
-const handlePage = () => {
+function handleSubmit() {
+    // 收集土壤类型(转换为数组)
+    const soilTypes = basicForm.value.soilTypes 
+        ? (Array.isArray(basicForm.value.soilTypes) ? basicForm.value.soilTypes : [basicForm.value.soilTypes])
+        : [];
+
+    // 收集灌溉方式(获取选中的 code)
+    const irrigationMethods = (basicFarmFormData.value.irrigationMethods || [])
+        .filter(item => item.selected)
+        .map(item => item.code || item.id);
+
+    // 收集农机设备(包含 code 和 quantity)
+    const machineryWithQuantity = (basicFarmFormData.value.machinery || [])
+        .filter(item => item.selected && item.quantity)
+        .map(item => ({
+            code: item.code || item.id,
+            quantity: Number(item.quantity) || 0
+        }));
+
+    // 收集希望专家帮助解决的种植难题(获取选中的 code)
+    const improvementAreas = (basicFarmFormData.value.improvementAreas || [])
+        .filter(item => item.selected)
+        .map(item => item.code || item.id);
+
+    // 收集农场规模数据
+    const draftData = {
+        soilTypes: soilTypes.map(code => Number(code)),
+        irrigationMethods: irrigationMethods.map(code => Number(code)),
+        machineryWithQuantity: machineryWithQuantity.map(item => ({
+            code: Number(item.code),
+            quantity: item.quantity
+        })),
+        regularWorkerCount: Number(farmScale.value.regularWorkerCount) || 0,
+        plantProtectionWorkerCount: Number(farmScale.value.plantProtectionWorkerCount) || 0,
+        pruningWorkerCount: Number(farmScale.value.pruningWorkerCount) || 0,
+        tempDispatchWorkerCount: Number(farmScale.value.tempDispatchWorkerCount) || 0,
+        improvementAreas: improvementAreas.map(code => Number(code)),
+    };
 
 
-    if (route.query.type === 'farmer') {
-        router.push('/agri_record')
-        return
+    // 如果有选择的专家,添加 preferredExpertCode
+    if (basicForm.value.expertCode) {
+        draftData.preferredExpertCode = Number(basicForm.value.expertCode);
     }
     }
 
 
-    // 获取所有需要传递的参数,包括 from 参数
-    const queryParams = {
-        containerId: route.query.containerId,
-    };
+    return draftData;
+}
+
+// 校验必填项
+function validateForm() {
+    // 校验土壤类型
+    if (!basicForm.value.soilTypes) {
+        ElMessage.warning('请选择您的果园土壤类型');
+        return false;
+    }
+
+    // 校验灌溉方式
+    const irrigationMethods = (basicFarmFormData.value.irrigationMethods || [])
+        .filter(item => item.selected);
+    if (irrigationMethods.length === 0) {
+        ElMessage.warning('请选择您的灌溉方式');
+        return false;
+    }
 
 
-    // 如果存在 from 参数,继续传递
-    if (route.query.from) {
-        queryParams.from = route.query.from;
+    // 校验农机设备
+    const machineryWithQuantity = (basicFarmFormData.value.machinery || [])
+        .filter(item => item.selected && item.quantity);
+    if (machineryWithQuantity.length === 0) {
+        ElMessage.warning('请选择您的农机设备并填写数量');
+        return false;
     }
     }
 
 
-    // 传递所有农场相关的参数,以便在 agricultural_plan 页面创建农场
-    const farmParams = ['wkt', 'speciesId', 'containerId', 'agriculturalCreate', 'geom', 'address', 'mu', 'name', 'fzr', 'tel', 'defaultFarm', 'typeId', 'speciesName', 'userType'];
-    farmParams.forEach(key => {
-        if (route.query[key] !== undefined) {
-            queryParams[key] = route.query[key];
+    // 校验希望专家帮助解决的种植难题
+    const improvementAreas = (basicFarmFormData.value.improvementAreas || [])
+        .filter(item => item.selected);
+    if (improvementAreas.length === 0) {
+        ElMessage.warning('请选择希望专家帮助解决的种植难题');
+        return false;
+    }
+
+    // 校验专家选项
+    if (!basicForm.value.expertCode) {
+        ElMessage.warning('请选择您最希望得到哪位荔枝专家的农事处方');
+        return false;
+    }
+
+    return true;
+}
+const showSuccessPopup = ref(false);
+const handleSuccessConfirm = () => {
+    router.push('/agri_record');
+}
+async function submit() {
+    try {
+        // 正式提交
+        const draftData = handleSubmit();
+        const params = {
+            ...route.query,
+            phenologyId: phenologyList.value[0].phenologyId,
+            phenologyStartDate: phenologyList.value[0].phenologyStartDate,
+            basicInfo: draftData,
+            expertMiniUserId: '81881',
         }
         }
-    });
-    router.push({
-        path: '/agricultural_plan',
-        query: queryParams
-    });
+        const res = await VE_API.basic_farm.saveBasicFarmInfoByExpert(params);
+        
+        if (res.code === 0) {
+            showSuccessPopup.value = true;
+            return true;
+        } else {
+            ElMessage.error(res.msg || '提交失败,请重试');
+            return false;
+        }
+    } catch (error) {
+        console.error('提交失败:', error);
+        ElMessage.error('提交失败,请重试');
+        return false;
+    }
+}
+
+const showPeriodPopup = ref(false);
+const phenologyList = ref([]);
+const disabledDate = (time) => {
+    // 获取今天的开始时间(00:00:00)
+    const today = new Date();
+    today.setHours(0, 0, 0, 0);
+    
+    // 获取明天的开始时间(00:00:00)
+    const tomorrow = new Date(today);
+    tomorrow.setDate(tomorrow.getDate() + 1);
+    
+    // 设置最小日期为 2025-01-01
+    const minDate = new Date(2025, 0, 1); // 月份从0开始,0表示1月
+    minDate.setHours(0, 0, 0, 0);
+    
+    // 如果时间 < 2025-01-01 或 >= 明天的开始时间,则禁用
+    // 只能选择 2025-01-01 到今天的日期范围
+    return time.getTime() < minDate.getTime() || time.getTime() >= tomorrow.getTime();
+}
+const handlePage = async () => {
+    // 先进行校验
+    if (!validateForm()) {
+        return;
+    }
+    const typeNames = JSON.parse(route.query.typeNames);
+    phenologyList.value = typeNames.map(item => ({
+        typeName: item,
+        phenologyId: firstPhenology.value.phenologyId,
+        startDateLabel: firstPhenology.value.startDateLabel,
+        phenologyName: firstPhenology.value.phenologyName,
+        phenologyStartDate: '2026-01-01',
+    }));
+    // 如果有选择的专家,添加 preferredExpertCode
+    if (basicForm.value.expertCode) {
+        const selectedExpert = basicFarmFormData.value.expertOptions.find(item => item.code === basicForm.value.expertCode);
+        if (selectedExpert) {
+            basicForm.value.expertInfo = selectedExpert;
+        }
+    }
+    console.log('basicForm.value', basicForm.value)
+    showPeriodPopup.value = true;
+    // // 获取所有需要传递的参数,包括 from 参数
+    // const queryParams = {
+    //     containerId: route.query.containerId,
+    // };
+
+    // // 如果存在 from 参数,继续传递
+    // if (route.query.from) {
+    //     queryParams.from = route.query.from;
+    // }
+
+    // // 传递所有农场相关的参数,以便在 agricultural_plan 页面创建农场
+    // const farmParams = ['wkt', 'speciesId', 'containerId', 'agriculturalCreate', 'geom', 'address', 'mu', 'name', 'fzr', 'tel', 'defaultFarm', 'typeId', 'speciesName', 'userType'];
+    // farmParams.forEach(key => {
+    //     if (route.query[key] !== undefined) {
+    //         queryParams[key] = route.query[key];
+    //     }
+    // });
+    // router.push({
+    //     path: '/agricultural_plan',
+    //     query: queryParams
+    // });
+};
+
+
+// 获取当前日期(YYYY-MM-DD格式)
+const getTodayDate = () => {
+    const today = new Date();
+    const year = today.getFullYear();
+    const month = String(today.getMonth() + 1).padStart(2, "0");
+    const day = String(today.getDate()).padStart(2, "0");
+    return `${year}-${month}-${day}`;
+};
+
+const firstPhenology = ref({});
+const phenologyData = ref({});
+// 获取当前和下一个物候期
+const getCurrentAndNextPhenology = async () => {
+    try {
+        const { data } = await VE_API.home.getCurrentAndNextPhenology({ 
+            expertMiniUserId: '81881',
+            containerId: route.query.containerId,
+        });
+        if (data && Array.isArray(data)) {
+            // 初始化物候期表单数据,日期使用第一个物候期的 startDate
+            firstPhenology.value = data[0];
+        }
+    } catch (error) {
+        console.error("获取物候期数据失败", error);
+        ElMessage.error("获取物候期数据失败");
+    }
+};
+
+// 确认物候期信息
+const handlePeriodConfirm = async () => {
+    // 校验所有物候期信息是否填写完整
+    const hasEmptyDate = phenologyList.value.some(item => !item.phenologyStartDate);
+    if (hasEmptyDate) {
+        ElMessage.warning('请选择时间');
+        return;
+    }
+    
+    // 关闭弹窗并提交表单
+    showPeriodPopup.value = false;
+    
+    // 正式提交
+    const success = await submit();
+    if (!success) {
+        return;
+    }
+    
+    // 提交成功后跳转
+    // if (route.query.type === 'farmer') {
+    //     router.push('/agri_record')
+    //     return
+    // }
+
+    // // 获取所有需要传递的参数,包括 from 参数
+    // const queryParams = {
+    //     containerId: route.query.containerId,
+    // };
+
+    // // 如果存在 from 参数,继续传递
+    // if (route.query.from) {
+    //     queryParams.from = route.query.from;
+    // }
+
+    // // 传递所有农场相关的参数,以便在 agricultural_plan 页面创建农场
+    // const farmParams = ['wkt', 'speciesId', 'containerId', 'agriculturalCreate', 'geom', 'address', 'mu', 'name', 'fzr', 'tel', 'defaultFarm', 'typeId', 'speciesName', 'userType'];
+    // farmParams.forEach(key => {
+    //     if (route.query[key] !== undefined) {
+    //         queryParams[key] = route.query[key];
+    //     }
+    // });
+    // router.push({
+    //     path: '/agricultural_plan',
+    //     query: queryParams
+    // });
 };
 };
 </script>
 </script>
 
 
@@ -695,8 +1061,13 @@ const handlePage = () => {
                     width: 116px;
                     width: 116px;
                     font-size: 14px;
                     font-size: 14px;
                     color: rgba(0, 0, 0, 0.9);
                     color: rgba(0, 0, 0, 0.9);
-                    text-align: right;
+                    // text-align: right;
                     margin-right: 10px;
                     margin-right: 10px;
+                    .sub-label {
+                        font-size: 10px;
+                        color: rgba(0, 0, 0, 0.4);
+                        line-height: 15px;
+                    }
                 }
                 }
 
 
                 .farm-scale-input {
                 .farm-scale-input {
@@ -785,4 +1156,121 @@ const handlePage = () => {
         }
         }
     }
     }
 }
 }
+.period-popup {
+    width: 90%;
+    padding: 24px 16px 20px 16px;
+    background: linear-gradient(360deg, #FFFFFF 74.2%, #D1EBFF 100%);
+    
+    .period-header {
+        font-size: 16px;
+        font-weight: 400;
+        margin-bottom: 16px;
+        color: #121212;
+        line-height: 22px;
+    }
+    
+    .period-content {
+        margin-bottom: 16px;
+        
+        .period-item {
+            background: rgba(33, 153, 248, 0.05);
+            border: 1px solid rgba(33, 153, 248, 0.2);
+            border-radius: 5px;
+            padding: 10px;
+            margin-bottom: 16px;
+            position: relative;
+            
+            &:last-child {
+                margin-bottom: 0;
+            }
+            
+            .period-item-name {
+                background: rgba(33, 153, 248, 0.1);
+                font-size: 12px;
+                color: #2199F8;
+                padding: 2px 10px;
+                border-radius: 2px;
+                font-weight: 400;
+                width: fit-content;
+            }
+            
+            .period-item-label {
+                margin-top: 10px;
+                
+                .label-item-group {
+                    display: flex;
+                    align-items: center;
+                    margin-bottom: 12px;
+                    
+                    &:last-child {
+                        margin-bottom: 0;
+                    }
+                    
+                    .label-item {
+                        font-size: 14px;
+                        color: #1D2129;
+                        min-width: 100px;
+                        flex-shrink: 0;
+                        padding-right: 10px;
+                    }
+                    
+                    .label-item-value {
+                        border-radius: 2px;
+                        flex: 1;
+                        font-size: 14px;
+                        color: #1D2129;
+                        min-height: 31px;
+                        line-height: 31px;
+                        display: flex;
+                        align-items: center;
+                        &.period-display {
+                            background: #FFFFFF;
+                            border: 0.5px solid rgba(0, 0, 0, 0.2);
+                            padding: 0 8px;
+                        }
+                    }
+                }
+            }
+        }
+    }
+    
+    .period-footer {
+        .period-footer-btn {
+            width: 100%;
+            background: #2199F8;
+            color: #ffffff;
+            font-size: 16px;
+            text-align: center;
+            height: 40px;
+            line-height: 40px;
+            border-radius: 4px;
+            cursor: pointer;
+            font-weight: 500;
+            
+            &:active {
+                opacity: 0.8;
+            }
+        }
+    }
+}
+.expert-info {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 20px;
+    line-height: 36px;
+    .expert-img {
+        width: 26px;
+        height: 26px;
+        border-radius: 50%;
+        object-fit: cover;
+        margin-right: 5px;
+    }
+}
+</style>
+
+<style lang="scss">
+.el-message--warning .el-message__content {
+    line-height: 20px;
+}
 </style>
 </style>

+ 2 - 2
src/views/old_mini/home/subPages/warningDetail.vue

@@ -46,9 +46,9 @@
 
 
             <div class="article-summary" v-if="warningDetail.summary">
             <div class="article-summary" v-if="warningDetail.summary">
                 <div class="summary-writer">
                 <div class="summary-writer">
-                    <el-avatar :size="36" :src="warningDetail.icon" />
+                    <el-avatar :size="36" :src="warningDetail.expertAvatar" />
                     <div class="writer-info">
                     <div class="writer-info">
-                        <span class="writer-name">{{ warningDetail.name }}</span>
+                        <span class="writer-name">{{ warningDetail.expertName }}</span>
                         <div class="belong-enterprise">{{ warningDetail.belongEnterprise }}</div>
                         <div class="belong-enterprise">{{ warningDetail.belongEnterprise }}</div>
                     </div>
                     </div>
                 </div>
                 </div>