Kaynağa Gözat

fix: 农情互动

lxf 1 hafta önce
ebeveyn
işleme
923bf4ec45

+ 14 - 2
src/App.vue

@@ -24,8 +24,8 @@
     <Tabbar class="tabbar" route fixed v-show="showTab" active-color="#2199F8" inactive-color="#898989">
         <!-- 托管农户:首页、作物档案、农事记录 -->
         <!-- <template v-if="userType == 2"> -->
-            <tabbar-item replace to="/home">
-                <span>首页</span>
+            <tabbar-item replace to="/growth_report">
+                <span>长势报告</span>
                 <template #icon="props">
                     <img
                         :src="
@@ -60,6 +60,18 @@
                     />
                 </template>
             </tabbar-item>
+            <tabbar-item replace to="/agri_record">
+                <span>有味溯源</span>
+                <template #icon="props">
+                    <img
+                        :src="
+                            props.active
+                                ? require('@/assets/img/tab_bar/task-active.png')
+                                : require('@/assets/img/tab_bar/task.png')
+                        "
+                    />
+                </template>
+            </tabbar-item>
         <!-- </template> -->
 
         <!-- 普通农户:首页、农事服务、用户管理、个人中心(保留原逻辑) -->

BIN
src/assets/img/home/point.png


BIN
src/assets/img/home/report.png


+ 1 - 1
src/router/globalRoutes.js

@@ -423,7 +423,7 @@ export default [
     {
         path: "/growth_report",
         name: "GrowthReport",
-        meta: { keepAlive: true },
+        meta: { showTabbar: true, keepAlive: true },
         component: () => import("@/views/old_mini/growth_report/index.vue"),
     },
     // 咨询专家

+ 274 - 87
src/views/old_mini/growth_report/index.vue

@@ -1,92 +1,125 @@
 <template>
-    <div class="achievement-report-page">
-        <custom-header name="报告详情"></custom-header>
+    <div class="achievement-report-page" :style="{ height: `calc(100vh - ${tabBarHeight}px)` }">
+        <!-- 天气遮罩 -->
+        <div class="weather-mask" v-show="isExpanded" @click="handleMaskClick"></div>
+        <!-- 组件:天气 -->
+        <weather-info ref="weatherInfoRef" class="weather-info" @weatherExpanded="weatherExpanded"
+            @changeGarden="changeGarden" :isGarden="true"></weather-info>
         <div class="report-content-wrap" v-loading="loading">
-            <div class="report-content" ref="reportDom">
-                <!-- <img src="@/assets/img/home/qrcode.png" alt="" class="code-icon" /> -->
-                    <img class="header-img" src="@/assets/img/home/report.png" alt="" />
-                <div class="report-header">
-                    <!-- <img class="header-book" src="@/assets/img/home/book.png" alt="" /> -->
-                    <div class="time-tag">{{ workItem?.reportDate }}</div>
-                    <div class="report-title">长势报告</div>
-                    <div class="report-info">
-                        <div class="info-item">
-                            <img class="info-icon" src="@/assets/img/home/farm.png" alt="" />
-                            <span class="info-text">{{ workItem?.orchardName }}</span>
-                        </div>
-                    </div>
-                </div>
+            <swipe class="my-swipe" :loop="false" indicator-color="white">
+                <swipe-item v-for="(item, index) in 4" :key="index">
+                    <div class="report-content">
+                        <!-- <img src="@/assets/img/home/qrcode.png" alt="" class="code-icon" /> -->
+                        <img class="header-img" src="@/assets/img/home/report.png" alt="" />
+                        <div class="report-header">
+                            <!-- <img class="header-book" src="@/assets/img/home/book.png" alt="" /> -->
+                            <div class="time-tag">{{ workItem?.reportDate }}</div>
+                            <div class="report-title">长势报告</div>
+                            <div class="report-info">
+                                <div class="info-item">
+                                    <img class="info-icon" src="@/assets/img/home/farm.png" alt="" />
+                                    <span class="info-text">{{ workItem?.orchardName }}</span>
+                                </div>
+                            </div>
 
-                <div class="report-box">
-                    <div class="box-title">农情总结</div>
-                    <div class="box-text">
-                        {{ workItem?.summaryAgricultural || "--" }}
-                    </div>
-                </div>
-
-                <div class="report-box">
-                    <div class="box-title">物候与长势</div>
-                    <div class="box-text">
-                        <div class="box-bg">
-                            <span class="box-subtitle">背景描述:</span>
-                            <div v-html="workItem?.phenologyBackground"></div>
-                        </div>
-                        <div class="box-advice">
-                            <span class="box-subtitle">对策建议:</span>
-                            <div v-html="workItem?.phenologySuggestion"></div>
+                            <!-- 左滑查看更多 -->
+                            <div class="swipe-more-tag">
+                                左滑查看更多
+                            </div>
                         </div>
-                        <div class="box-sum" v-html="workItem?.phenologySummary"></div>
-                    </div>
-                </div>
-
-                <div class="report-box">
-                    <div class="box-title">病虫害问题</div>
-                    <div class="box-text">
-                        <div class="box-bg">
-                            <span class="box-subtitle">背景描述:</span>
-                            <div v-html="workItem?.pestBackground"></div>
+
+                        <div class="report-box">
+                            <div class="box-title">农情总结</div>
+                            <div class="box-text">
+                                {{ workItem?.summaryAgricultural || "--" }}
+                            </div>
                         </div>
-                        <div class="box-advice">
-                            <span class="box-subtitle">对策建议:</span>
-                            <div v-html="workItem?.pestSuggestion"></div>
+
+                        <div class="report-box">
+                            <div class="box-title">物候与长势</div>
+                            <div class="box-text">
+                                <div class="box-bg">
+                                    <span class="box-subtitle">背景描述:</span>
+                                    <div v-html="workItem?.phenologyBackground"></div>
+                                </div>
+                                <div class="box-advice">
+                                    <span class="box-subtitle">对策建议:</span>
+                                    <div v-html="workItem?.phenologySuggestion"></div>
+                                </div>
+                                <div class="box-sum" v-html="workItem?.phenologySummary"></div>
+                            </div>
                         </div>
-                        <div class="box-sum">
-                            <div v-html="workItem?.pestSummary"></div>
+
+                        <div class="report-box">
+                            <div class="box-title">病虫害问题</div>
+                            <div class="box-text">
+                                <div class="box-bg">
+                                    <span class="box-subtitle">背景描述:</span>
+                                    <div v-html="workItem?.pestBackground"></div>
+                                </div>
+                                <div class="box-advice">
+                                    <span class="box-subtitle">对策建议:</span>
+                                    <div v-html="workItem?.pestSuggestion"></div>
+                                </div>
+                                <div class="box-sum">
+                                    <div v-html="workItem?.pestSummary"></div>
+                                </div>
+                            </div>
                         </div>
-                    </div>
-                </div>
-
-                <div class="report-box">
-                    <div class="box-title">未来预测</div>
-                    <div class="box-text">
-                        <div class="box-bg">
-                            <span class="box-subtitle">背景描述:</span>
-                            <div v-html="workItem?.forecastBackground"></div>
+
+                        <div class="report-box">
+                            <div class="box-title">今日巡园重点</div>
+                            <div class="box-text">
+                                {{ workItem?.summaryAgricultural || "--" }}
+                            </div>
                         </div>
-                        <div class="box-advice">
-                            <span class="box-subtitle">对策建议:</span>
-                            <div v-html="workItem?.forecastSuggestion"></div>
+
+                        <div class="report-box">
+                            <div class="box-title">未来预测</div>
+                            <div class="box-text">
+                                <div class="box-bg">
+                                    <span class="box-subtitle">背景描述:</span>
+                                    <div v-html="workItem?.forecastBackground"></div>
+                                </div>
+                                <div class="box-advice">
+                                    <span class="box-subtitle">对策建议:</span>
+                                    <div v-html="workItem?.forecastSuggestion"></div>
+                                </div>
+                            </div>
                         </div>
-                    </div>
-                </div>
 
-                <div class="report-box">
-                    <div class="box-text next-info">
-                        <div class="box-bg">
-                            <span class="box-subtitle">下一次农情互动预告:</span>
-                            <div v-html="workItem?.nextInteractionPreview"></div>
+                        <div class="report-box">
+                            <div class="box-text next-info">
+                                <div class="box-bg">
+                                    <span class="box-subtitle">下一次农情互动预告:</span>
+                                    <div v-html="workItem?.nextInteractionPreview"></div>
+                                </div>
+                            </div>
                         </div>
                     </div>
-                </div>
+                </swipe-item>
+            </swipe>
+        </div>
+
+        <!-- 首次进入页面的左滑查看提示遮罩 -->
+        <div class="swipe-guide-mask" v-if="showSwipeGuide" @click="closeSwipeGuide">
+            <div class="swipe-guide-content">
+                <img class="swipe-guide-icon" src="@/assets/img/home/point.png" alt="swipe" />
+                <div class="swipe-guide-text">左滑查看其它品种报告</div>
             </div>
         </div>
     </div>
 </template>
 
 <script setup>
-import CustomHeader from "@/components/customHeader.vue";
-import { ref, onActivated, onDeactivated, onUnmounted } from "vue";
+import weatherInfo from "@/components/weatherInfo.vue";
+import { ref, onActivated, onDeactivated, onUnmounted, computed } from "vue";
 import { useRoute } from "vue-router";
+import { useStore } from "vuex";
+import { Swipe, SwipeItem } from 'vant';
+
+const store = useStore();
+const tabBarHeight = computed(() => store.state.home.tabBarHeight);
 
 const route = useRoute();
 const loading = ref(false);
@@ -112,16 +145,54 @@ function formatArea(val) {
     return Number.isInteger(num) ? num : num.toFixed(2) + "亩";
 }
 const paramsPage = ref({});
+// 天气组件相关
+const isExpanded = ref(false);
+const weatherInfoRef = ref(null);
+
+// 首次进入页面的左滑提示遮罩
+const showSwipeGuide = ref(false);
+
+const weatherExpanded = (isExpandedValue) => {
+    isExpanded.value = isExpandedValue;
+};
+
+// 点击遮罩时收起天气
+const handleMaskClick = () => {
+    if (weatherInfoRef.value && weatherInfoRef.value.toggleExpand) {
+        weatherInfoRef.value.toggleExpand();
+    }
+};
+
+// 切换农场时,更新报告数据
+const changeGarden = ({ id }) => {
+    if (!id) return;
+    paramsPage.value = {
+        ...(paramsPage.value || {}),
+        farmId: id,
+    };
+    getDetail();
+};
+
 onActivated(() => {
     window.scrollTo(0, 0);
-    paramsPage.value = route.query || {};
-    getDetail();
+    // paramsPage.value = route.query || {};
+    // 首次进入时显示左滑提示(本地仅展示一次)
+    const guideKey = "GROWTH_REPORT_SWIPE_GUIDE_SHOWN";
+    if (!localStorage.getItem(guideKey)) {
+        showSwipeGuide.value = true;
+        localStorage.setItem(guideKey, "1");
+    }
     // getResultReport();
 });
 
+// 关闭左滑提示遮罩
+const closeSwipeGuide = () => {
+    showSwipeGuide.value = false;
+};
+
 
 const setReadStatus = (id) => {
-    VE_API.farm.readReportByFarm({ id,isRead:1 }).then(({ data }) => {
+    VE_API.farm.readReportByFarm({ id, isRead: 1 }).then(({ data }) => {
         console.log(data);
     });
 }
@@ -131,8 +202,9 @@ const getDetail = () => {
     VE_API.farm
         .growthReportBySubject({ subjectId: paramsPage.value.farmId, limit: 20 })
         .then(({ data }) => {
-            workItem.value = data[0];
-            setReadStatus(data[0].id);
+            console.log('data', data);
+            workItem.value = data?.[0] || {};
+            data?.[0]?.id && setReadStatus(data[0]?.id);
         })
         .finally(() => {
             loading.value = false;
@@ -162,12 +234,31 @@ onUnmounted(() => {
     background: linear-gradient(195.35deg, #d4e4ff 16.34%, rgba(93, 189, 255, 0) 50.3%),
         linear-gradient(156.64deg, rgba(255, 255, 255, 0.16) 27.7%, rgba(255, 255, 255, 0) 72.82%);
 
+    .weather-mask {
+        position: fixed;
+        top: 0;
+        left: 0;
+        width: 100%;
+        height: 100%;
+        background-color: rgba(0, 0, 0, 0.52);
+        z-index: 11;
+    }
+
+    .weather-info {
+        width: calc(100% - 20px);
+        position: absolute;
+        z-index: 12;
+        left: 10px;
+        top: 12px;
+    }
+
     .report-content-wrap {
-        height: calc(100% - 40px);
+        height: 100%;
         // padding-bottom: 60px;
         overflow: auto;
         box-sizing: border-box;
         position: relative;
+
         .bottom-btn {
             z-index: 2;
             position: fixed;
@@ -182,16 +273,19 @@ onUnmounted(() => {
             padding: 0 12px;
             box-sizing: border-box;
             box-shadow: 2px 2px 4.5px 0px rgba(0, 0, 0, 0.4);
+
             .btn-item {
                 height: 40px;
                 line-height: 40px;
                 padding: 0 24px;
                 border-radius: 20px;
                 font-size: 14px;
+
                 &.second {
                     color: #666666;
                     border: 1px solid rgba(153, 153, 153, 0.5);
                 }
+
                 &.primay {
                     padding: 0 34px;
                     background: linear-gradient(180deg, #76c3ff, #2199f8);
@@ -201,30 +295,69 @@ onUnmounted(() => {
         }
     }
 
+    // 首次进入页面左滑提示遮罩
+    .swipe-guide-mask {
+        position: fixed;
+        left: 0;
+        top: 0;
+        width: 100%;
+        height: 100%;
+        background: rgba(0, 0, 0, 0.6);
+        z-index: 99999;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+
+        .swipe-guide-content {
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            justify-content: center;
+            color: #ffffff;
+            text-align: center;
+        }
+
+        .swipe-guide-icon {
+            width: 71px;
+            height: 79px;
+            object-fit: contain;
+            margin-bottom: 23px;
+        }
+
+        .swipe-guide-text {
+            font-size: 20px;
+        }
+    }
+
     .code-icon {
         position: absolute;
         right: 10px;
         top: 12px;
         width: 48px;
     }
+
     .report-content {
         // background: url("@/assets/img/home/report_bg.png") no-repeat center center;
         background: linear-gradient(0deg, #9BCCFF, #9BCCFF),
-        linear-gradient(160deg, rgba(255, 255, 255, 0.16) 30%, rgba(255, 255, 255, 0) 72%);
+            linear-gradient(160deg, rgba(255, 255, 255, 0.16) 30%, rgba(255, 255, 255, 0) 72%);
         background-size: 100% auto;
         background-position: top center;
-        padding: 24px 16px 16px;
+        padding: 0 16px 26px 16px;
         box-sizing: border-box;
         position: relative;
         min-height: 100%;
+
         .header-img {
             position: absolute;
             top: 0;
             left: 0;
             width: 100%;
         }
+
         .report-header {
             position: relative;
+            padding-top: 112px;
+
             .header-book {
                 position: absolute;
                 right: 0;
@@ -232,6 +365,7 @@ onUnmounted(() => {
                 height: 88px;
                 z-index: 10;
             }
+
             .time-tag {
                 background: linear-gradient(137.86deg, #9fd5ff 5.87%, #2199f8 82.98%);
                 border-radius: 5px 0 5px 0;
@@ -243,14 +377,17 @@ onUnmounted(() => {
                 padding: 0 9px;
                 width: fit-content;
             }
+
             .report-title {
                 font-family: "PangMenZhengDao";
                 font-size: 34px;
                 line-height: 38px;
                 color: #000000;
             }
+
             .report-info {
-                padding: 10px 0 16px 0;
+                padding: 12px 0 28px 0;
+
                 .info-item {
                     width: fit-content;
                     display: flex;
@@ -261,21 +398,45 @@ onUnmounted(() => {
                     border-radius: 20px;
                     border: 0.5px solid rgba(33, 153, 248, 0.35);
                     gap: 6px;
+
                     .info-icon {
                         width: 26px;
                         height: 26px;
                         object-fit: cover;
                         border-radius: 50%;
                     }
+
                     .info-text {
                         font-size: 14px;
                         color: #2199f8;
                     }
                 }
-                .info-item + .info-item {
+
+                .info-item+.info-item {
                     margin-top: 5px;
                 }
             }
+
+            // 左滑查看更多标签
+            .swipe-more-tag {
+                position: absolute;
+                top: 50%;
+                right: -16px;
+                box-sizing: border-box;
+                width: 36px;
+                height: 116px;
+                padding: 10px 10px 2px 0;
+                background: rgba(0, 0, 0, 0.7);
+                border-radius: 16px 0 0 16px;
+                letter-spacing: 2px;
+                color: #ffffff;
+                font-size: 14px;
+                font-weight: 500;
+                text-align: center;
+                line-height: 20px;
+                writing-mode: vertical-rl;
+                text-orientation: mixed;
+            }
         }
 
         .report-box {
@@ -287,6 +448,7 @@ onUnmounted(() => {
             border-radius: 8px;
             gap: 5px;
             position: relative;
+
             .report-box-item {
                 flex: 1;
                 background: rgba(33, 153, 248, 0.1);
@@ -297,11 +459,13 @@ onUnmounted(() => {
                 display: flex;
                 flex-direction: column;
                 justify-content: center;
+
                 .item-content {
                     color: #2199f8;
                     font-size: 14px;
                     text-align: center;
                 }
+
                 .item-title {
                     color: #000000;
                     font-size: 10px;
@@ -322,21 +486,26 @@ onUnmounted(() => {
                 color: #ffffff;
                 background: url("@/assets/img/home/title-bg.png") no-repeat center center / 100% 100%;
             }
+
             .box-text {
                 padding: 22px 0 8px 0;
                 font-weight: 350;
                 line-height: 21px;
+
                 .box-subtitle {
                     color: #000;
                 }
+
                 .box-bg {
                     font-weight: 400;
                     color: rgba(0, 0, 0, 0.5);
                 }
+
                 .box-advice {
                     color: rgba(0, 0, 0, 0.5);
                     padding-top: 10px;
                 }
+
                 .box-sum {
                     margin-top: 10px;
                     background: rgba(33, 153, 248, 0.1);
@@ -345,17 +514,21 @@ onUnmounted(() => {
                     line-height: 20px;
                     color: #2199F8;
                 }
+
                 &.next-info {
                     padding: 8px 0 8px 0;
                 }
             }
         }
-        .report-box + .report-box {
+
+        .report-box+.report-box {
             margin-top: 20px;
         }
+
         .report-excute {
             position: relative;
             margin-top: 12px;
+
             .tag-label {
                 position: absolute;
                 top: 0;
@@ -367,6 +540,7 @@ onUnmounted(() => {
                 border-radius: 8px 0 8px 0;
                 z-index: 1;
             }
+
             ::v-deep {
                 .carousel-container .carousel-wrapper .carousel-img {
                     min-width: calc(100vw - 32px);
@@ -375,6 +549,7 @@ onUnmounted(() => {
             }
         }
     }
+
     .download-btn {
         position: fixed;
         bottom: 20px;
@@ -403,6 +578,7 @@ onUnmounted(() => {
         margin: 12px;
         background: #fff;
         border-radius: 8px;
+
         .review-mask {
             z-index: 1;
             pointer-events: none;
@@ -412,12 +588,10 @@ onUnmounted(() => {
             width: 100%;
             height: 100%;
             border-radius: 8px;
-            background: linear-gradient(
-                360deg,
-                rgba(0, 0, 0, 0.78) 0%,
-                rgba(0, 0, 0, 0.437208) 19.87%,
-                rgba(0, 0, 0, 0) 33.99%
-            );
+            background: linear-gradient(360deg,
+                    rgba(0, 0, 0, 0.78) 0%,
+                    rgba(0, 0, 0, 0.437208) 19.87%,
+                    rgba(0, 0, 0, 0) 33.99%);
             display: flex;
             flex-direction: column;
             align-items: baseline;
@@ -425,16 +599,19 @@ onUnmounted(() => {
             padding: 12px;
             box-sizing: border-box;
             color: #fff;
+
             .review-text {
                 font-family: "PangMenZhengDao";
                 font-size: 16px;
                 margin-bottom: 1px;
             }
+
             .review-content {
                 font-size: 10px;
                 line-height: 15px;
             }
         }
+
         .vs-wrap {
             position: absolute;
             left: 50%;
@@ -443,15 +620,18 @@ onUnmounted(() => {
             width: 40px;
             height: 40px;
             z-index: 10;
+
             img {
                 width: 100%;
                 height: 100%;
                 object-fit: cover;
             }
         }
+
         .review-image-item {
             position: relative;
             flex: 1;
+
             .review-image-item-title {
                 position: absolute;
                 top: 0;
@@ -463,6 +643,7 @@ onUnmounted(() => {
                 font-size: 12px;
                 color: #fff;
             }
+
             // .review-image-item-img {
             //     width: 100%;
             //     height: 250px;
@@ -474,9 +655,11 @@ onUnmounted(() => {
                 object-fit: cover;
                 object-position: center;
             }
+
             .left-img {
                 border-radius: 8px 0 0 8px;
             }
+
             .right-img {
                 border-radius: 0 8px 8px 0;
             }
@@ -495,11 +678,13 @@ onUnmounted(() => {
     display: flex;
     flex-direction: column;
     backdrop-filter: 4px;
+
     .cavans-content {
         text-align: center;
         padding: 0 12px;
         height: fit-content;
         overflow: auto;
+
         .current-img {
             width: 100%;
         }
@@ -519,6 +704,7 @@ onUnmounted(() => {
                 flex-direction: column;
                 align-items: center;
                 cursor: pointer;
+
                 &.text-btn {
                     font-size: 12px;
                     color: rgba(255, 255, 255, 0.7);
@@ -537,6 +723,7 @@ onUnmounted(() => {
                     .el-icon {
                         color: #fff;
                     }
+
                     img {
                         width: 50px;
                     }

+ 509 - 0
src/views/old_mini/interaction/index.vue

@@ -0,0 +1,509 @@
+<template>
+    <div class="interaction-page">
+        <custom-header name="农情互动" bgColor="#f2f4f5" :isClose="true" :showClose="false" />
+        <div class="interaction-content">
+            <!-- 顶部说明 -->
+            <div class="intro-card">
+                完善作物品种以及物候信息,精准匹配种植方案,实现精细化管理
+            </div>
+
+            <!-- 作物块(每个农场一块) -->
+            <div v-for="(crop, cropIndex) in farmData" :key="cropIndex" class="crop-section">
+                <div class="crop-header">
+                    <div class="crop-tag">{{ crop.speciesName }}</div>
+                    <div class="add-btn" @click="addVariety(crop)">+ 新增品种</div>
+                </div>
+
+                <div v-for="(region, regionIndex) in crop.regions" :key="regionIndex" class="variety-card">
+                    <div class="field-row">
+                        <div class="field-value">
+                            <el-select 
+                                v-model="region.regionId" 
+                                class="variety-input" 
+                                placeholder="选择品种"
+                            >
+                                <el-option v-for="(item, index) in crop.typeIdItems" :key="index" :label="item.name"
+                                    :value="item.id" />
+                                    <template #footer>
+                                        <el-button text bg @click="onAddOption(region)">
+                                            + 增加品种
+                                        </el-button>
+                                    </template>
+                            </el-select>
+                        </div>
+                    </div>
+
+                    <div class="field-row">
+                        <div class="field-label">当下物候期</div>
+                        <div class="field-value">
+                            <el-select
+                                v-model="region.phenologyId"
+                                class="select-input"
+                                placeholder="选择物候期"
+                            >
+                                <el-option v-for="(item, index) in crop.phenologyOptions" :key="index" :label="item.phenologyName"
+                                    :value="item.phenologyId" />
+                            </el-select>
+                        </div>
+                    </div>
+
+                    <div class="field-row" v-if="region.phenologyId">
+                        <div class="field-label">{{ getPhenologyLabel(crop, region.phenologyId) }}</div>
+                        <div class="field-value">
+                            <el-date-picker
+                                :editable="false"
+                                style="width: 100%"
+                                v-model="region.phenologyStartDate"
+                                class="date-picker"
+                                type="date"
+                                placeholder="选择时间" format="YYYY-MM-DD" value-format="YYYY-MM-DD" />
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+
+        <!-- 底部按钮 -->
+        <div class="fixed-btn-wrap">
+            <div class="fixed-btn" @click="handleConfirm">
+                确认信息
+            </div>
+        </div>
+    </div>
+
+    <tip-popup v-model:show="showTipPopup" type="success" text="您的作物信息已完善" />
+
+
+    <popup class="add-tag-popup" :z-index="2500" round v-model:show="showAddPopup" @update:show="handlePopupClose">
+        <div class="tag-item">
+            <div class="popup-title">新增品种名称</div>
+            <el-input autofocus class="popup-input" v-model="newVarietyName" placeholder="请输入品种名称" size="large" />
+        </div>
+        <div class="popup-button">
+            <div class="cancel" @click="handleCancelAdd">取消</div>
+            <div @click="handleAddVariety">确认</div>
+        </div>
+    </popup>
+</template>
+
+<script setup>
+import { ref, nextTick, onActivated } from "vue";
+import { ElMessage } from "element-plus";
+import { Popup } from "vant";
+import customHeader from "@/components/customHeader.vue";
+import { useRoute } from "vue-router";
+import tipPopup from "@/components/popup/tipPopup.vue";
+
+const route = useRoute();
+
+onActivated(() => {
+    const subjectId = route.query.subjectId;
+    getPhenologyInitOrConfirmStatus(subjectId);
+});
+
+const farmData = ref([])
+const getPhenologyInitOrConfirmStatus = async (subjectId) => {
+    const {data} = await VE_API.farm_v3.phenologyInitOrConfirmStatus({subjectId});
+    farmData.value = data.farms;
+    farmData.value.forEach(item => {
+        addVariety(item);
+    });
+}
+
+const addVariety = (crop) => {
+    if (!Array.isArray(crop.regions)) {
+        crop.regions = [];
+    }
+    crop.regions.push({
+        regionId: null,
+        phenologyId: null,
+        phenologyStartDate: "",
+    });
+};
+
+// 获取物候期对应的时间标签
+const getPhenologyLabel = (farm, phenologyId) => {
+    if (!farm?.phenologyOptions) return "选择时间";
+    const found = farm.phenologyOptions.find(
+        (item) => item.id === phenologyId || item.phenologyId === phenologyId
+    );
+    return found?.startDateLabel || "选择时间";
+};
+
+const showTipPopup = ref(false);
+
+const handleConfirm = async () => {
+    // 组装为 initFarmData 接口所需的 farmDataList 结构
+    const farmDataList = farmData.value
+        .map((farm) => {
+            const typeIdItems = (farm.regions || [])
+                .filter(
+                    (r) => r.regionId && r.phenologyId && r.phenologyStartDate
+                )
+                .map((r) => {
+                    const origin =
+                        (farm.typeIdItems || []).find(
+                            (t) => String(t.id) === String(r.regionId)
+                        ) || {};
+                    return {
+                        id: r.regionId,
+                        name: origin.name || "",
+                        phenologyId: r.phenologyId,
+                        phenologyStartDate: r.phenologyStartDate,
+                    };
+                })
+                .filter((item) => item.id);
+
+            return {
+                farmId: farm.farmId,
+                speciesId: farm.speciesId,
+                typeIdItems,
+            };
+        })
+        .filter((item) => item.typeIdItems.length > 0);
+
+    if (!farmDataList.length) {
+        ElMessage.warning("请先选择品种、物候期和时间");
+        return;
+    }
+
+    const params = {
+        expertMiniUserId: 81881,
+        farmDataList,
+    };
+    console.log("params", params);
+
+    const { code, msg } = await VE_API.farm_v3.initFarmData(params);
+    if (code === 0) {
+        showTipPopup.value = true;
+    } else {
+        ElMessage.error(msg || "提交失败");
+    }
+
+    // 大物候期转换所需参数// 组装为后端所需的 farmDataList 结构
+    // const farmDataList = farmData.value
+    //     .map((farm) => {
+    //         const regionPhenologyItems = (farm.regions || [])
+    //             .filter(
+    //                 (r) => r.regionId && r.phenologyId && r.phenologyStartDate
+    //             )
+    //             .map((r) => ({
+    //                 regionId: r.regionId,
+    //                 phenologyId: r.phenologyId,
+    //                 phenologyStartDate: r.phenologyStartDate,
+    //             }));
+
+    //         return {
+    //             farmId: farm.farmId,
+    //             regionPhenologyItems,
+    //         };
+    //     })
+    //     .filter((item) => item.regionPhenologyItems.length > 0);
+
+    // console.log("farmDataList", farmDataList);
+    
+    // const params = {
+    //     farmDataList,
+    //     expertMiniUserId: 81881,
+    // }
+    // const {code, msg} = await VE_API.farm_v3.confirmReproductivePhenology(params);
+    // if(code === 0) {
+    //     qrCodePopupRef.value.showPopup();
+    // } else {
+    //     ElMessage.error(msg);
+    // }
+};
+
+const showAddPopup = ref(false);
+const newVarietyName = ref("");
+const currentVariety = ref(null); // 记录当前正在添加品种的 variety 对象
+
+const handleAddVariety = () => {
+    if (!newVarietyName.value.trim()) {
+        return;
+    }
+    
+    // 如果当前有正在添加品种的 variety,则自动选中新增的品种
+    if (currentVariety.value) {
+        currentVariety.value.variety = newVarietyName.value;
+    }
+    
+    newVarietyName.value = "";
+    showAddPopup.value = false;
+    currentVariety.value = null;
+}
+
+const onAddOption = async (region) => {
+    // 先关闭下拉菜单
+    if (document.activeElement) {
+        document.activeElement.blur();
+    }
+    
+    // 等待下拉菜单关闭后再显示弹窗
+    await nextTick();
+    
+    // 记录当前 region
+    currentVariety.value = region;
+    showAddPopup.value = true;
+}
+
+const handleCancelAdd = () => {
+    newVarietyName.value = "";
+    showAddPopup.value = false;
+    currentVariety.value = null;
+}
+
+const handlePopupClose = (show) => {
+    if (!show) {
+        // 弹窗关闭时清空状态
+        newVarietyName.value = "";
+        currentVariety.value = null;
+    }
+}
+</script>
+
+<style lang="scss" scoped>
+.interaction-page {
+    height: 100vh;
+    box-sizing: border-box;
+    background: #F2F4F5;
+    font-size: 14px;
+    color: #1d2129;
+}
+
+.interaction-content {
+    height: calc(100% - 40px);
+    overflow: auto;
+    padding: 12px 10px 70px 10px;
+    box-sizing: border-box;
+}
+
+.intro-card {
+    padding: 10px;
+    border-radius: 6px;
+    background: #ffffff;
+    color: #666666;
+    box-shadow: 0 2px 8px rgba(15, 35, 52, 0.06);
+    margin-bottom: 12px;
+    line-height: 17px;
+}
+
+.crop-section {
+    background: #ffffff;
+    border-radius: 6px;
+    padding: 10px;
+    box-shadow: 0 2px 8px rgba(15, 35, 52, 0.04);
+    margin-bottom: 10px;
+}
+
+.crop-header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-bottom: 10px;
+
+    .crop-tag {
+        padding: 0 16px;
+        border-radius: 2px;
+        background: #2199F8;
+        color: #ffffff;
+        font-size: 14px;
+        height: 26px;
+        line-height: 26px;
+    }
+
+    .add-btn {
+        padding: 0 12px;
+        border-radius: 4px;
+        height: 26px;
+        line-height: 26px;
+        box-sizing: border-box;
+        border: 0.5px solid rgba(33, 153, 248, 0.5);
+        color: #0B84E4;
+    }
+}
+
+.variety-card {
+    margin-top: 8px;
+    padding: 10px;
+    border-radius: 5px;
+    background: rgba(33, 153, 248, 0.05);
+    border: 1px solid rgba(33, 153, 248, 0.2);
+}
+
+.field-row {
+    display: flex;
+    align-items: center;
+    margin-bottom: 10px;
+
+    &:last-child {
+        margin-bottom: 0;
+    }
+}
+
+.field-label {
+    width: 118px;
+    flex: none;
+    font-size: 14px;
+    color: #1D2129;
+}
+
+.field-value {
+    flex: 1;
+}
+
+.select-input,
+.date-picker {
+    width: 100%;
+}
+
+.variety-input {
+    width: 110px;
+    ::v-deep {
+        .el-select__wrapper {
+            box-shadow: none;
+            background-color: rgba(33, 153, 248, 0.1);
+            // box-shadow: 0 0 0 1px var(--el-border-color) inset;
+        }
+        .el-select__placeholder {
+            color: #2199F8;
+        }
+        .el-select__caret {
+            color: #2199F8;
+        }
+    }
+}
+
+.fake-select {
+    height: 32px;
+    border-radius: 4px;
+    border: 1px solid rgba(0, 0, 0, 0.08);
+    background: #ffffff;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    padding: 0 8px;
+    box-sizing: border-box;
+
+    .text {
+        color: #1d2129;
+        font-size: 14px;
+    }
+
+    .arrow {
+        font-size: 10px;
+        color: #c0c4cc;
+    }
+
+    &.fake-select--plain {
+        background: #ffffff;
+    }
+}
+
+
+.fixed-btn-wrap {
+    display: flex;
+    justify-content: center;
+    position: fixed;
+    bottom: 0px;
+    left: 0;
+    right: 0;
+    background: #fff;
+    padding: 10px 12px;
+    box-sizing: border-box;
+    // box-shadow: 0 -2px 8px rgba(15, 35, 52, 0.06);
+    box-shadow: 2px 2px 4.5px 0px #00000066;
+
+    .fixed-btn {
+        min-width: 110px;
+        height: 40px;
+        line-height: 40px;
+        text-align: center;
+        border-radius: 20px;
+        background: linear-gradient(180deg, #70bffe, #2199f8);
+        color: #ffffff;
+        font-size: 14px;
+    }
+}
+
+.date-input {
+    height: 32px;
+    border-radius: 4px;
+    border: 1px dashed rgba(33, 153, 248, 0.6);
+    background: #ffffff;
+    display: flex;
+    align-items: center;
+    padding: 0 8px;
+    box-sizing: border-box;
+    color: #c0c4cc;
+    font-size: 14px;
+}
+
+.success-text {
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    font-size: 24px;
+    color: #000;
+    .success-icon {
+        width: 28px;
+        height: 28px;
+        margin-right: 5px;
+    }
+}
+
+
+.add-tag-popup {
+    width: 90%;
+    padding: 24px 16px 20px 16px;
+    background: linear-gradient(360deg, #FFFFFF 74.2%, #D1EBFF 100%);
+
+    .popup-title {
+        font-size: 16px;
+        font-weight: 400;
+        margin-bottom: 12px;
+        color: #000000;
+        .name-text{
+            font-weight: 500;
+            color: #2199F8;
+            padding: 0 2px;
+        }
+    }
+
+    .ml-2 {
+        margin-left: 3px;
+    }
+
+    .popup-input {
+        margin-bottom: 24px;
+    }
+
+    .popup-button {
+        display: flex;
+
+        div {
+            flex: 1;
+            font-size: 16px;
+            padding: 9px;
+            border-radius: 20px;
+            background: #2199F8;
+            color: #fff;
+            text-align: center;
+            cursor: pointer;
+        }
+
+        .cancel {
+            margin-right: 13px;
+            color: #000;
+            background: #fff;
+            border: 1px solid #999999;
+        }
+        .delete {
+            margin-right: 13px;
+            color: #FF3D3D;
+            background: #fff;
+            border: 1px solid rgba(255, 61, 61, 0.4);
+        }
+    }
+}
+</style>