Parcourir la source

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

lxf il y a 2 semaines
Parent
commit
8c4fd22c04

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


BIN
src/assets/img/home/photo-icon.png


+ 291 - 140
src/views/old_mini/home/components/homeFloatingPanel.vue

@@ -1,101 +1,140 @@
 <template>
-    <floating-panel class="floating-panel" :class="{ 'background-panel': isBackground }" v-model:height="height" :anchors="anchors" :content-draggable="false" @height-change="handleHeightChange">
-        <template #header>
-            <div class="floating-panel-header">
-                <div class="tabs">
-                    <div
-                        :class="['tab-item', activeTab === index ? 'active' : '']"
-                        v-for="(tab, index) in tabs"
-                        :key="tab"
-                        @click="handleTabClick(index)"
-                    >
-                        {{ tab }}
-                    </div>
-                </div>
-                <div class="file-header" v-if="activeTab === 1">
-                    <div class="select-group">
-                        <div class="select-item">
-                            <div class="select-item-title">123</div>
+    <div class="home-floating-panel">
+        <floating-panel
+            class="floating-panel"
+            :class="{ 'background-panel': isBackground }"
+            v-model:height="height"
+            :anchors="anchors"
+            :content-draggable="false"
+            @height-change="handleHeightChange"
+        >
+            <template #header>
+                <div class="floating-panel-header" :class="{ 'file-header-active': activeTab === 0 }">
+                    <div class="tabs">
+                        <div
+                            :class="['tab-item', activeTab === index ? 'active' : '']"
+                            v-for="(tab, index) in tabs"
+                            :key="tab"
+                            @click="handleTabClick(index)"
+                        >
+                            {{ tab }}
                         </div>
                     </div>
-                    <el-anchor
-                        :container="containerRef"
-                        class="tabs-content-group"
-                        direction="horizontal"
-                        type="default"
-                        :offset="0"
-                        @click="handleClick"
+                    <div class="file-header" v-if="activeTab === 1">
+                        <div class="select-group">
+                            <el-select class="select-item" v-model="dateValue" placeholder="Select">
+                                <el-option
+                                    v-for="item in dateOptions"
+                                    :key="item.value"
+                                    :label="item.label"
+                                    :value="item.value"
+                                />
+                            </el-select>
+                            <el-select class="select-item" v-model="areaValue" placeholder="Select">
+                                <el-option
+                                    v-for="item in areaOptions"
+                                    :key="item.value"
+                                    :label="item.label"
+                                    :value="item.value"
+                                />
+                            </el-select>
+                        </div>
+                        <el-anchor
+                            :container="containerRef"
+                            class="tabs-content-group"
+                            direction="horizontal"
+                            type="default"
+                            :offset="0"
+                            @click="handleClick"
                         >
-                        <el-anchor-link class="tabs-content-item" v-for="(tab,index) in tabsContent" :key="tab" @click="handleTabsContentClick(index)" :href="'#part' + (index + 1)" :title="tab"></el-anchor-link>
-                    </el-anchor>
-                </div>
-            </div>
-        </template>
-        <div class="floating-panel-content" v-show="activeTab === 0">
-            <record-task></record-task>
-        </div>
-        <div class="floating-panel-content" v-show="activeTab === 1">
-                <!-- <div class="select-group">
-                    <div class="select-item">
-                        <div class="select-item-title">123</div>
+                            <el-anchor-link
+                                class="tabs-content-item"
+                                v-for="(tab, index) in tabsContent"
+                                :key="tab"
+                                @click="handleTabsContentClick(index)"
+                                :href="'#part' + (index + 1)"
+                                :title="tab"
+                            ></el-anchor-link>
+                        </el-anchor>
                     </div>
                 </div>
-                <el-anchor
-                    :container="containerRef"
-                    direction="horizontal"
-                    type="default"
-                    :offset="0"
-                    @click="handleClick"
-                    >
-                    <el-anchor-link v-for="(tab,index) in tabsContent" :key="tab" @click="handleTabsContentClick(index)" :href="'#part' + (index + 1)" :title="tab"></el-anchor-link>
-                </el-anchor> -->
-                <!-- <div class="tabs-content-group">
-                    <div :class="['tabs-content-item',activeTabsContent === index ? 'active' : '']" v-for="(tab,index) in tabsContent" :key="tab" @click="handleTabsContentClick(index)">
-                        {{ tab }}
-                    </div>
-                </div> -->
-            <div class="card-content-group" ref="containerRef">
-                <div class="card-content-item" id="part1">
-                    <div class="card-content-item-title">果园总览</div>
-                    <div class="card-content-item-content">
-                        <div class="card-text">果园面积共XX亩,共有XX棵生产树。</div>
-                        <div class="card-text">本次飞巡拍摄了XX张照片,包括了XX棵树,目前为施用根部有机肥阶段,根据树体冠幅大小,果园预计施用有机肥XXkg。</div>
-                        <div class="card-text">目前XX%的树体暂未萌动新梢,需要进行剪枝农事,提高树体光合效率与通风效率。</div>
-                    </div>
-                </div>
-                <div class="card-content-item" id="part2">
-                    <div class="card-content-item-title">整体园相</div>
-                    <div class="card-content-item-content">
-                        <div class="card-name">透光率</div>
-                        <div class="card-value">透光率体现树体自身郁闭程度,当前XX%的树体透光性较差,可能造成整体减产XX%,需立即执行剪枝农事;XX%的树体透光正常,建议继续保持现有管理措施并及时巡园。</div>
+            </template>
+            <div class="floating-panel-content" v-show="activeTab === 0">
+                <record-task></record-task>
+            </div>
+            <div class="floating-panel-content" ref="cardContentRef" v-show="activeTab === 1">
+                <div class="card-content-group" ref="containerRef" :style="{ height: `${cardContentHeight}px` }">
+                    <div class="card-content-item" id="part1">
+                        <div class="card-content-item-title">果园总览</div>
+                        <div class="card-content-item-content">
+                            <div class="card-text">果园面积共XX亩,共有XX棵生产树。</div>
+                            <div class="card-text">
+                                本次飞巡拍摄了XX张照片,包括了XX棵树,目前为施用根部有机肥阶段,根据树体冠幅大小,果园预计施用有机肥XXkg。
+                            </div>
+                            <div class="card-text">
+                                目前XX%的树体暂未萌动新梢,需要进行剪枝农事,提高树体光合效率与通风效率。
+                            </div>
+                        </div>
                     </div>
-                    <div class="card-content-item-content">
-                        <div class="card-name">通风率</div>
-                        <div class="card-value">透光率体现树体自身郁闭程度,当前XX%的树体透光性较差,可能造成整体减产XX%,需立即执行剪枝农事;XX%的树体透光正常,建议继续保持现有管理措施并及时巡园。</div>
+                    <div class="card-content-item" id="part2">
+                        <div class="card-content-item-title">整体园相</div>
+                        <div class="card-content-item-content">
+                            <div class="card-name">透光率</div>
+                            <div class="card-value">
+                                透光率体现树体自身郁闭程度,当前XX%的树体透光性较差,可能造成整体减产XX%,需立即执行剪枝农事;XX%的树体透光正常,建议继续保持现有管理措施并及时巡园。
+                            </div>
+                        </div>
+                        <div class="card-content-item-content">
+                            <div class="card-name">通风率</div>
+                            <div class="card-value">
+                                透光率体现树体自身郁闭程度,当前XX%的树体透光性较差,可能造成整体减产XX%,需立即执行剪枝农事;XX%的树体透光正常,建议继续保持现有管理措施并及时巡园。
+                            </div>
+                            <div class="map-wrap">
+                                <img class="map-img" src="@/assets/img/home/map.png" alt="" />
+                                <div class="map-text">剪枝农事地图</div>
+                            </div>
+                        </div>
                     </div>
-                </div>
-                <div class="card-content-item" id="part3">
-                    <div class="card-content-item-title">营养管理</div>
-                    <div class="card-content-item-content">
-                        营养管理
+                    <div class="card-content-item" id="part3">
+                        <div class="card-content-item-title">营养管理</div>
+                        <div class="card-content-item-content">
+                            <div class="card-name">根肥</div>
+                            <div class="card-value">
+                                生产树中,树体冠幅平均表面积XX平方米,预计需要使用有机肥XXkg(或者平衡肥+尿素XXkg)用来培养健壮秋梢。如遭遇持续阴雨,可配合芸苔素增强光合作用。
+                            </div>
+                            <div class="map-wrap">
+                                <img class="map-img" src="@/assets/img/home/map.png" alt="" />
+                                <div class="map-text">根肥农事地图</div>
+                            </div>
+                        </div>
                     </div>
-                </div>
-                <div class="card-content-item" id="part4">
-                    <div class="card-content-item-title">病虫管理</div>
-                    <div class="card-content-item-content">
-                        病虫管理
+                    <div class="card-content-item" id="part4">
+                        <div class="card-content-item-title">病虫管理</div>
+                        <div class="card-content-item-content">
+                            <div class="card-value">
+                                在以萌动新梢的树体中,2%的树体新梢小叶变为红黄色,长度10-15cm,极易被病虫啃食,预计XX月XX日果园进入虫害爆发高峰期,需要做好虫害预防工作。
+                            </div>
+                            <div class="map-wrap">
+                                <img class="map-img" src="@/assets/img/home/map.png" alt="" />
+                                <div class="map-text">防虫农事地图</div>
+                            </div>
+                        </div>
                     </div>
-                </div>
-                <div class="card-content-item" id="part5">
-                    <div class="card-content-item-title">农事记录</div>
-                    <div class="card-content-item-content">
-                        农事记录
+                    <div class="card-content-item" id="part5">
+                        <div class="card-content-item-title">农事记录</div>
+                        <div class="card-content-item-content">农事记录</div>
                     </div>
                 </div>
             </div>
+        </floating-panel>
+        <div class="expand-btn-wrap" v-show="height === defalutHeight">
+            <span>农事任务/农事档案</span>
+            <div class="expand-btn" @click="handleExpandBtnClick">
+                <span>展开</span>
+                <el-icon><ArrowUpBold /></el-icon>
+            </div>
         </div>
-    </floating-panel>
-    <!-- <div></div> -->
+    </div>
 </template>
 
 <script setup>
@@ -108,22 +147,38 @@ const store = useStore();
 // const tabBarHeight = computed(() => store.state.home.tabBarHeight);
 const tabBarHeight = ref(localStorage.getItem("tabBarHeight") * 1 || 50);
 
-const defalutHeight = ref(tabBarHeight.value + 32);
+const defalutHeight = ref(0);
 const anchors = ref([defalutHeight.value, 310 + tabBarHeight.value, Math.round(1 * window.innerHeight)]);
 const height = ref(anchors.value[1]);
 
 const containerRef = ref(null);
 const handleClick = (e) => {
-  e.preventDefault()
-}
+    e.preventDefault();
+};
 
-const activeTab = ref(0);
+const activeTab = ref(1);
 const tabs = ref(["农事任务", "农场档案"]);
 
 const handleTabClick = (index) => {
     activeTab.value = index;
 };
 
+const dateValue = ref("2025-08-28");
+const dateOptions = [
+    {
+        value: "2025-08-28",
+        label: "2025-08-28",
+    },
+];
+
+const areaValue = ref("1");
+const areaOptions = [
+    {
+        value: "1",
+        label: "全部区域",
+    },
+];
+
 const tabsContent = ref(["果园总览", "整体园相", "营养管理", "病虫管理", "农事记录"]);
 
 const activeTabsContent = ref(0);
@@ -131,35 +186,56 @@ const handleTabsContentClick = (index) => {
     activeTabsContent.value = index;
 };
 
-const emit = defineEmits(['heightChange'])
+const emit = defineEmits(["heightChange"]);
+
+const cardContentRef = ref(null);
+const isBackground = ref(false);
 
-const isBackground = ref(false)
-const handleHeightChange = (data) => {
-    isBackground.value = false
-    if(data.height > anchors.value[1]){
-        isBackground.value = true
+const handleHeightChange = ({ height }) => {
+    isBackground.value = false;
+    if (height > anchors.value[1]) {
+        isBackground.value = true;
     }
-    emit('heightChange',data.height)
+    if (height === anchors.value[1]) {
+        cardContentHeight.value = 180;
+        cardContentRef.value.scrollTo({ top: 0, behavior: "smooth" });
+    } else if (height === anchors.value[2]) {
+        cardContentHeight.value = Math.round(1 * window.innerHeight) - (tabBarHeight.value - 40) - 180;
+    }
+    emit("heightChange", height);
+};
+
+const cardContentHeight = ref(180);
+const handleExpandBtnClick = () => {
+    cardContentHeight.value = 180;
+    height.value = anchors.value[1];
+    cardContentRef.value.scrollTo({ top: 0, behavior: "smooth" });
+    emit("heightChange", anchors.value[1]);
 };
 </script>
 
 <style lang="scss" scoped>
-.van-floating-panel{
+.van-floating-panel {
     border-radius: 0;
 }
 .floating-panel {
     width: 100%;
-    background: linear-gradient(180deg, transparent 0%, #F5F7FB 14%);
+    background: linear-gradient(180deg, transparent 0%, #f5f7fb 14%);
     ::v-deep {
         .van-floating-panel__content {
             background: transparent;
+            overflow: hidden;
         }
     }
     .floating-panel-header {
         width: calc(100% - 24px);
-        border-radius: 14px 14px 0 0;
-        margin: 0 auto;
+        border-radius: 14px;
+        margin: 0 auto 10px;
         background: #fff;
+        &.file-header-active{
+            border-radius: 14px 14px 0 0;
+            margin-bottom: 0;
+        }
         .tabs {
             display: flex;
             .tab-item {
@@ -176,58 +252,92 @@ const handleHeightChange = (data) => {
                 }
             }
         }
-        .tabs-content-group{
-            display: flex;
-            justify-content: space-evenly;
-            padding: 5px 0;
-            border-radius: 0 0 14px 14px;
-            background: #fff;
-            .tabs-content-item{
-                font-size: 14px;
-                color: rgba(0, 0, 0, 0.5);
-                font-weight: 500;
-                padding: 4px 12px;
-                border-radius: 14px;
-                text-align: center;
-                &.active{
-                    color: #2199f8;
+        .file-header {
+            .select-group {
+                display: flex;
+                justify-content: center;
+                padding-top: 5px;
+                .select-item {
+                    width: 115px;
+                    ::v-deep {
+                        .el-select__wrapper {
+                            text-align: center;
+                            gap: 2px;
+                            box-shadow: none;
+                            justify-content: center;
+                        }
+                        .el-select__selection {
+                            flex: none;
+                            width: fit-content;
+                        }
+                        .el-select__placeholder {
+                            position: static;
+                            transform: none;
+                            width: fit-content;
+                            color: #000;
+                        }
+                        .el-select__caret {
+                            color: #000;
+                        }
+                    }
+                }
+                .select-item:first-child {
+                    margin-right: 10px;
+                }
+            }
+            ::v-deep{
+                .el-anchor{
+                    --el-anchor-line-height: auto;
+                }
+                .el-anchor__marker{
+                    height: 0;
+                }
+                .el-anchor.el-anchor--horizontal .el-anchor__list{
+                    width: 100%;
+                }
+                .el-anchor__link.is-active{
                     background: rgba(33, 153, 248, 0.2);
                 }
             }
+            .tabs-content-group {
+                display: flex;
+                justify-content: space-evenly;
+                padding: 5px 8px;
+                background-color: transparent;
+                .tabs-content-item {
+                    flex: 1;
+                    font-size: 14px;
+                    color: rgba(0, 0, 0, 0.5);
+                    font-weight: 500;
+                    padding: 1px 0;
+                    border-radius: 14px;
+                    text-align: center;
+                }
+            }
         }
     }
     .floating-panel-content {
         width: calc(100% - 24px);
         height: 100%;
         margin: 0 auto;
-        .select-group {
-            padding-top: 5px;
-            background: #fff;
-            .select-item {
-                .select-item-title {
-                    font-size: 16px;
-                }
-            }
-        }
-        
-        .card-content-group{
-            padding: 12px 0;
-            height: 800px;
-            overflow-y: auto;
-            .card-content-item{
-                margin-top: 10px;
+        .card-content-group {
+            padding-bottom: 12px;
+            height: 100%;
+            box-sizing: border-box;
+            overflow: auto;
+            .card-content-item {
                 border-radius: 14px;
                 padding: 12px;
                 background: #fff;
                 color: #171717;
 
-                .card-content-item-title{
+                .card-content-item-title {
                     font-size: 16px;
                     font-weight: 500;
                     text-align: center;
                     position: relative;
-                    &::before{
-                        content: '';
+                    &::before {
+                        content: "";
                         position: absolute;
                         left: 50%;
                         transform: translateX(-50%);
@@ -238,31 +348,72 @@ const handleHeightChange = (data) => {
                         border-radius: 4px;
                     }
                 }
-                .card-content-item-content{
+                .card-content-item-content {
                     margin-top: 12px;
                     border-radius: 8px;
                     background: rgba(238, 238, 238, 0.3);
                     padding: 10px;
                     line-height: 21px;
-                    .card-name{
+                    .card-name {
                         font-weight: 500;
                     }
-                    .card-value{
+                    .card-value {
                         font-size: 12px;
                         color: rgba(23, 23, 23, 0.6);
                     }
-                    .card-text + .card-text{
+                    .map-wrap {
+                        margin-top: 10px;
+                        .map-img {
+                            width: 100%;
+                            height: 137px;
+                        }
+                        .map-text {
+                            font-size: 12px;
+                            color: rgba(23, 23, 23, 0.6);
+                            text-align: center;
+                            margin-top: 5px;
+                        }
+                    }
+                    .card-text + .card-text {
                         margin-top: 5px;
                     }
                 }
             }
-        }   
+
+            .card-content-item + .card-content-item {
+                margin-top: 10px;
+            }
+        }
     }
-    &.background-panel{
-        background: #F5F7FB;
+    &.background-panel {
+        background: #f5f7fb;
         .floating-panel-header {
             margin-top: 12px;
         }
     }
 }
+
+.expand-btn-wrap{
+    position: absolute;
+    bottom: 62px;
+    left: 12px;
+    width: calc(100% - 24px);
+    background-image: linear-gradient(180deg, #d7eafc 0%, #ffffff 100%);
+    border-radius: 14px;
+    padding: 15px 12px;
+    box-sizing: border-box;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    font-weight: 500;
+    font-size: 15px;
+    .expand-btn{
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        gap: 4px;
+        font-size: 13px;
+        color: #2199f8;
+    }
+}
 </style>

+ 91 - 18
src/views/old_mini/home/index.vue

@@ -2,17 +2,38 @@
     <div class="home-index" :style="{ height: `calc(100vh - ${tabBarHeight}px)` }">
         <!-- 地图 -->
         <div class="map-container" ref="mapContainer"></div>
-        <!-- 按钮 -->
-         <div class="add-button" @click="toSubPage">
+        <!-- 新建按钮 -->
+        <div class="add-button" v-show="showAddButton" @click="toSubPage">
             <el-icon class="add-button-icon"><CircleCloseFilled /></el-icon>
             <span>创建我的农场</span>
-         </div>
+        </div>
         <!-- 天气遮罩 -->
         <div class="weather-mask" v-show="isExpanded"></div>
         <!-- 天气 -->
         <weather-info class="weather-info" @weatherExpanded="weatherExpanded"></weather-info>
+        <!-- 操作按钮 -->
+        <div class="operation-button">
+            <div class="button-group">
+                <div class="button-item">
+                    <img class="button-icon" src="@/assets/img/tab_bar/home-active.png" alt="">
+                    <span>基本信息</span>
+                </div>
+                <div class="button-item">
+                    <img class="button-icon" src="@/assets/img/home/photo-icon.png" alt="">
+                    <span>农场相册</span>
+                </div>
+            </div>
+            <div class="add-farm-button">
+                <el-icon class="icon"><CircleCloseFilled /></el-icon>
+                <span>新增农场</span>
+            </div>
+        </div>
         <!-- 浮动面板 -->
-        <home-floating-panel class="home-floating-panel" :style="{ zIndex: zIndex}" @heightChange="heightChange"></home-floating-panel>
+        <home-floating-panel
+            class="home-floating-panel"
+            :style="{ zIndex: zIndex }"
+            @heightChange="heightChange"
+        ></home-floating-panel>
     </div>
 </template>
 
@@ -28,7 +49,6 @@ const router = useRouter();
 const store = useStore();
 const tabBarHeight = computed(() => store.state.home.tabBarHeight);
 
-
 const indexMap = new IndexMap();
 const mapContainer = ref(null);
 onMounted(() => {
@@ -38,15 +58,19 @@ onMounted(() => {
 const isExpanded = ref(false);
 const weatherExpanded = (isExpandedValue) => {
     isExpanded.value = isExpandedValue;
-}
+};
 
-const zIndex = ref(1)
+const zIndex = ref(1);
+const showAddButton = ref(false);
 const heightChange = (height) => {
-    zIndex.value = 1
-    if(height > 310 + tabBarHeight.value){
-        zIndex.value = 3
+    zIndex.value = 1;
+    showAddButton.value = true;
+    if (height === 0) {
+        showAddButton.value = false;
+    } else if (height > 310 + tabBarHeight.value) {
+        zIndex.value = 3;
     }
-}
+};
 
 function toSubPage() {
     router.push({
@@ -65,7 +89,7 @@ function toSubPage() {
         width: 100%;
         height: 100%;
     }
-    .add-button{
+    .add-button {
         position: absolute;
         bottom: 20px;
         left: 50%;
@@ -75,17 +99,17 @@ function toSubPage() {
         align-items: center;
         justify-content: center;
         color: #fff;
-        background-image: linear-gradient(180deg, #70BFFE 0%, #2199F8 100%);
+        background-image: linear-gradient(180deg, #70bffe 0%, #2199f8 100%);
         border-radius: 25px;
         padding: 12px 0;
         width: 187px;
-        .add-button-icon{
+        .add-button-icon {
             font-size: 20px;
             margin-right: 5px;
             transform: rotate(45deg);
         }
     }
-    .weather-mask{
+    .weather-mask {
         position: absolute;
         top: 0;
         left: 0;
@@ -101,7 +125,57 @@ function toSubPage() {
         width: calc(100% - 24px);
         z-index: 2;
     }
-    .home-floating-panel{
+    .operation-button{
+        position: absolute;
+        top: 117px;
+        left: 12px;
+        width: calc(100% - 24px);
+        z-index: 1;
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        font-size: 12px;
+        font-weight: 500;
+        .button-group{
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            .button-item{
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                gap: 4px;
+                color: rgba(0, 0, 0, 0.8);
+                background-color: #fff;
+                .button-icon{
+                    width: 13px;
+                    height: 13px;
+                }
+            }
+            .button-item:first-child{
+                margin-right: 10px;
+            }
+        }
+        .add-farm-button{
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            gap: 4px;
+            background: rgba(0, 0, 0, 0.5);
+            border: 1px solid rgba(255, 255, 255, 0.5);
+            color: #fff;
+            .icon{
+                font-size: 16px;
+                transform: rotate(45deg);
+            }
+        }
+        .button-item,
+        .add-farm-button{
+            border-radius: 25px;
+            padding: 8px 12px;
+        }
+    }
+    .home-floating-panel {
         position: fixed;
         bottom: 0;
         left: 0;
@@ -109,5 +183,4 @@ function toSubPage() {
         z-index: 1;
     }
 }
-
-</style>
+</style>