Browse Source

feat:修改首页UI

wangsisi 4 months ago
parent
commit
4bbd449f7a

+ 24 - 0
src/api/modules/image.js

@@ -1,5 +1,9 @@
 const config = require("../config")
 
+const DataFetcher = require("../data/DataFetcher");
+
+const dataFetcher = new DataFetcher("https://mock.feiniaotech.com/shuichan");
+
 module.exports = {
     list: {
         url: config.base_dev_url + "image/list?key="+config.mini_key,
@@ -17,4 +21,24 @@ module.exports = {
         url: config.base_dev_url + "lz_weather7d/findSuitabilityByPoint/{farmId}/{date}?key="+config.mini_key,
         type: "get",
     },
+    //图片列表
+    fetchGardenImgs: {
+        url: config.base_url + "adm/images/{organId}/{areaId}",
+        type: "get",
+    },
+    fetchRegionList: {
+        url: config.base_url + "adm/regionList",
+        type: "post",
+    },
+    //视频列表
+    videoList: {
+        url: config.base_dev_url + "",
+        type: "get",
+        mockCondition: (p)=>{
+            return true;
+        },mockFun:function(p){
+            if(!p.date){p.date = "2025-05"}
+            return dataFetcher.fetchData(90975,`video/${p.date}`)
+        }
+    },
 }

BIN
src/assets/images/home/play.png


BIN
src/assets/images/home/table-btn-sk.png


+ 280 - 0
src/views/home/components/leftComponents/leftFly.vue

@@ -0,0 +1,280 @@
+<template>
+    <div class="fly-photo">
+        <div class="tabs">
+            <div class="tab-item" :class="{ active: activeTab === 0 }" @click="handleTab(0)">照片</div>
+            <div class="tab-item" :class="{ active: activeTab === 1 }" @click="handleTab(1)">视频</div>
+        </div>
+        <div class="select-group">
+            <el-date-picker
+                class="date-picker"
+                v-model="dateTime"
+                @change="changeDate"
+                size="large"
+                type="date"
+                format="YYYY年MM月DD日"
+                value-format="YYYY-MM-DD"
+                :style="{ width: activeTab ? '100%' : 'calc(100% - 145px)' }"
+            />
+            <el-select v-if="activeTab === 0" class="select" v-model="areaValue" size="large">
+                <el-option v-for="item in areaOptions" :key="item.value" :label="item.name" :value="item.id" />
+            </el-select>
+        </div>
+        <div div class="photo-list" v-show="activeTab === 0">
+            <div
+                class="photo-item"
+                v-for="(item, index) in imageList"
+                :class="{ 'm-l-10': index % 2 !== 0 }"
+                :key="index"
+            >
+                <album-carousel-item
+                    lbum-carousel-item
+                    :key="index"
+                    :name="item.code"
+                    :farmId="766"
+                    :images="[item]"
+                    :lock="false"
+                ></album-carousel-item>
+            </div>
+            <div class="no-photo" v-show="!imageList.length">暂无数据</div>
+        </div>
+        <div class="pagination-wrap">
+            <el-pagination
+                background
+                :page-size="pageSize"
+                :pagerCount="5"
+                v-model:current-page="currentPage"
+                @current-change="geImgaeList"
+                layout="prev, pager, next"
+                :total="totalVal"
+            />
+        </div>
+        <div class="video-list" v-show="activeTab === 1">
+            <div class="video-item" v-for="(item, index) in videoList" :key="item.id">
+                <video ref="myVideo" class="mp4" loop muted :controls="item.isPlay">
+                    <source :src="item.url" type="video/mp4" />
+                </video>
+                <img
+                    v-show="!item.isPlay"
+                    class="play"
+                    @click="handlePlay(index)"
+                    src="@/assets/images/home/play.png"
+                    alt=""
+                />
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { onMounted, onUnmounted, ref } from "vue";
+import albumCarouselItem from "../../album_compoents/albumCarouselItem.vue";
+import config from "@/api/config";
+const resize = "?imageView/1/w/240/h/240";
+
+const activeTab = ref(0);
+const handleTab = (index) => {
+    activeTab.value = index;
+    changeDate()
+};
+
+function getCurrentMonth() {
+    const now = new Date();
+    const formattedDate = now.toISOString().slice(0, 10);
+    return formattedDate;
+}
+
+const dateTime = ref(getCurrentMonth());
+const changeDate = () => {
+    if (activeTab.value) {
+        getVideoList();
+    } else {
+        geImgaeList();
+    }
+};
+const areaValue = ref(2); // 默认区域ID
+
+const areaOptions = ref([]);
+const currentPage = ref(1);
+const pageSize = ref(10); // 每页显示20条数据
+const totalVal = ref(0);
+
+const imageList = ref([]);
+const geImgaeList = () => {
+    VE_API.image.fetchGardenImgs({ date: dateTime.value, organId: 766, areaId: areaValue.value, limit: pageSize.value, page: currentPage.value }).then((res) => {
+        imageList.value = res.data;
+        totalVal.value = res.count;
+    });
+};
+
+function changeArea() {
+    currentPage.value = 1; // 重置页码
+    geImgaeList();
+}
+
+const videoList = ref([]);
+const getVideoList = () => {
+    VE_API.image.videoList({ date: dateTime.value }).then((res) => {
+        videoList.value = res.data || [];
+    });
+};
+
+const myVideo = ref(null);
+const currentPlaying = ref(null);
+const handlePlay = (index) => {
+    myVideo.value[index].play();
+    videoList.value[index].isPlay = true;
+};
+
+onMounted(() => {
+    geImgaeList();
+    getBlueRegionList()
+});
+
+function getBlueRegionList() {
+    VE_API.image.fetchRegionList({ farmId: 766 }).then(({ data }) => {
+        areaOptions.value = data;
+    });
+}
+
+// 提取前6位并转换为日期格式
+function formatDatePart(originalStr) {
+    // 提取前6位数字
+    const datePart = originalStr.substring(0, 6);
+
+    // 解析为日期格式
+    const year = "20" + datePart.substring(0, 2); // 前两位是年份,加上20前缀
+    const month = datePart.substring(2, 4); // 中间两位是月份
+    const day = datePart.substring(4, 6); // 最后两位是日
+
+    // 组合成YYYY-MM-DD格式
+    const formattedDate = `${year}-${month}-${day}`;
+    // 返回新字符串(不改变原字符串)
+    return formattedDate;
+}
+</script>
+
+<style lang="scss" scoped>
+.fly-photo {
+    width: calc(100% - 54px - 10px);
+    height: 100%;
+    padding: 8px 8px 8px 0;
+    box-sizing: border-box;
+    .tabs {
+        width: 100%;
+        display: flex;
+        .tab-item {
+            font-size: 16px;
+            padding: 8px;
+            cursor: pointer;
+            text-align: center;
+            border-radius: 5px;
+            flex: 1;
+            background: rgba(255, 255, 255, 0.07);
+            &.active {
+                background-color: #ffd489;
+                color: #000;
+            }
+        }
+        .tab-item + .tab-item {
+            margin-left: 5px;
+        }
+    }
+    .select-group {
+        display: flex;
+        margin: 10px 0;
+        .select {
+            width: 140px;
+            margin-left: 5px;
+        }
+        ::v-deep {
+            .el-select__wrapper {
+                background: rgba(255, 255, 255, 0.07);
+                box-shadow: none;
+            }
+            .el-select__placeholder,
+            .el-select__caret,
+            .el-input__prefix {
+                color: #fff;
+                text-align: center;
+            }
+            .el-input__wrapper {
+                background: #323232;
+                box-shadow: none;
+            }
+            .el-input__inner {
+                color: #fff;
+            }
+        }
+    }
+    .photo-list {
+        display: flex;
+        flex-direction: row;
+        flex-wrap: wrap;
+        overflow: auto;
+        width: 100%;
+        height: calc(100% - 100px - 42px);
+        .photo-item {
+            width: calc(50% - 5px);
+            margin-bottom: 10px;
+            .img {
+                width: 100%;
+                height: 100%;
+                object-fit: cover;
+                border-radius: 4px;
+            }
+            ::v-deep {
+                .carousel-item .tag-box.leftTop {
+                    display: none;
+                }
+                .carousel-item img {
+                    border-radius: 4px;
+                }
+            }
+        }
+        .m-l-10 {
+            margin-left: 10px;
+        }
+        .no-photo {
+            color: #fff;
+            width: 100%;
+            text-align: center;
+            padding-top: 20px;
+        }
+    }
+    .pagination-wrap {
+        padding-top: 10px;
+        ::v-deep {
+            .el-pagination {
+                justify-content: center;
+            }
+        }
+    }
+    .video-list {
+        width: 100%;
+        height: calc(100% - 100px);
+        overflow: auto;
+        .video-item {
+            width: 100%;
+            height: 172px;
+            position: relative;
+            .mp4 {
+                width: 100%;
+                height: 100%;
+                object-fit: cover;
+                border-radius: 5px;
+            }
+            .play {
+                width: 62px;
+                height: 62px;
+                position: absolute;
+                left: calc(50% - 31px);
+                top: calc(50% - 31px);
+                cursor: pointer;
+            }
+        }
+        .video-item + .video-item {
+            margin-top: 10px;
+        }
+    }
+}
+</style>

+ 243 - 0
src/views/home/components/leftComponents/leftStation.vue

@@ -0,0 +1,243 @@
+<template>
+    <div class="chart-list" v-loading="isLoading" element-loading-background="rgba(0, 0, 0, 0.6)" element-loading-text="数据加载中...">
+        <div class="chart-item">
+            <chart-box name="气温">
+                <one-line-chart
+                    class="line-chart"
+                    :class="{'all': !text}"
+                    :name="riskKeys[0]"
+                    :key="1"
+                    :yData="yData"
+                    :minData="[]"
+                    :chartDate="chartDate"
+                    :customVal="{min: -1, max: 1}"
+                ></one-line-chart>
+                <div class="box-bg tips" v-if="text">
+                    <div class="text">
+                        {{ text }}
+                    </div>
+                </div>
+            </chart-box>
+        </div>
+        <div class="chart-item">
+            <chart-box name="湿度">
+                <one-line-chart
+                    class="line-chart"
+                    :class="{'all': !text1}"
+                    key="tr"
+                    :name="riskKeys[1]"
+                    :yData="yData1"
+                    :minData="[]"
+                    :chartDate="chartDate1"
+                    :customVal="{min: -1, max: 2}"
+                ></one-line-chart>
+                <div class="box-bg tips" v-if="text1">
+                    <div class="text">
+                        {{ text1 }}
+                    </div>
+                </div>
+            </chart-box>
+        </div>
+        <div class="chart-item">
+            <chart-box name="水质">
+                <one-line-chart
+                    class="line-chart"
+                    :class="{'all': !text2}"
+                    key="js"
+                    :name="riskKeys[2]"
+                    :yData="yData2"
+                    :minData="[]"
+                    :chartDate="chartDate2"
+                    :customVal="{min: -1, max: 1}"
+                ></one-line-chart>
+                <div class="box-bg tips" v-if="text2">
+                    <div class="text">
+                        {{ text2 }}
+                    </div>
+                </div>
+            </chart-box>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import chartBox from "@/components/chartBox.vue";
+import oneLineChart from "@/components/charts/oneLineChart.vue";
+import { onMounted, ref, onUnmounted } from "vue";
+import eventBus from "@/api/eventBus";
+import weatherChart from "../weatherChart.vue";
+
+const riskKeys = ref([]);
+
+const yData = ref([]);
+const yData1 = ref([]);
+const yData2 = ref([]);
+const yData3 = ref([]);
+
+const chartDate = ref([]);
+const chartDate1 = ref([]);
+const chartDate2 = ref([]);
+const chartDate3 = ref([]);
+
+const text = ref(null);
+const text1 = ref(null);
+const text2 = ref(null);
+
+const isLoading = ref(false)
+
+const baseData = ref({});
+
+const organId = ref(sessionStorage.getItem("farmId"));
+
+// onMounted(() => {
+//     // getList();
+//     getBaseData();
+//     getTimeIndex();
+//     eventBus.on("area:id", changeAreaId);
+//     eventBus.on("selectedPointVal", changeSelectedPoint);
+// });
+onUnmounted(() => {
+    eventBus.off("area:id", changeAreaId);
+    eventBus.off("selectedPointVal", changeSelectedPoint);
+});
+
+function changeAreaId({ farmId }) {
+    organId.value = farmId;
+    // getList();
+    getBaseData();
+    getTimeIndex();
+}
+
+function changeSelectedPoint(coordinate) {
+    // getList(coordinate);
+}
+
+function getList(coordinate) {
+    isLoading.value = true
+    riskKeys.value = [];
+    yData.value.value = [];
+    yData1.value.value = [];
+    yData2.value.value = [];
+    chartDate.value.value = [];
+    chartDate1.value.value = [];
+    chartDate2.value.value = [];
+    VE_API.python.indexCalculation({lon: coordinate ? coordinate[0] : 110.2011,lat: coordinate ? coordinate[1] : 21.0446}, {Global: false}).then((res) => {
+      riskKeys.value = ["TSI","CHLA","FAI"]
+      yData.value = res.data[riskKeys.value[0]].map((item) => parseFloat(item.value.toFixed(2)));
+      yData1.value = res.data[riskKeys.value[1]].map((item) => parseFloat(item.value.toFixed(2)));
+      yData2.value = res.data[riskKeys.value[2]].map((item) => parseFloat(item.value.toFixed(2)));
+
+      chartDate.value = res.data[riskKeys.value[0]].map((item) => item.name);
+      chartDate1.value = res.data[riskKeys.value[1]].map((item) => item.name);
+      chartDate2.value = res.data[riskKeys.value[2]].map((item) => item.name);
+      isLoading.value = false
+
+      // text.value = res.data[riskKeys.value[0]].text;
+      // text1.value = res.data[riskKeys.value[1]].text;
+      // text2.value = res.data[riskKeys.value[2]].text;
+    })
+}
+
+function formattedDates(dates) {
+    return dates.map((date) => {
+        const [year, month, day] = date.split("-");
+        return `${month}-${day}`; // 使用模板字符串格式化为 MM/DD
+    });
+}
+
+const getBaseData = () => {
+    const point = sessionStorage.getItem("point");
+    // 获取气象图表数据
+    VE_API.mini_farm.weather_warning_land_check({ farmId: organId.value, point }).then((res) => {
+        baseData.value = res.data || {};
+    });
+};
+
+const getTimeIndex = () => {
+    VE_API.farm.getTimeIndex({ farmId: organId.value }).then(({ data }) => {
+        chartDate3.value = formattedDates(data.map((item) => item.date));
+        yData3.value = data.map((item) => parseFloat(item.value.toFixed(3)));
+    });
+};
+</script>
+
+<style lang="scss" scoped>
+.chart-list {
+    width: calc(100% - 54px - 10px);
+    height: calc(100%);
+    overflow: auto;
+    padding: 8px 8px 0 0;
+    box-sizing: border-box;
+    .chart-item {
+        width: 100%;
+        // height: 240px;
+        box-sizing: border-box;
+        margin-bottom: 10px;
+        height: calc(33% - 10px);
+        .line-chart {
+            width: 100%;
+            height: calc(100% - 70px);
+            &.all {
+                height: calc(100% - 10px);
+            }
+        }
+
+        &.weather-item {
+            height: 266px;
+        }
+
+        .base-wrap {
+            width: 100%;
+            height: 56px;
+            margin-top: 4px;
+            display: flex;
+            justify-content: space-evenly;
+            .base-item {
+                width: 110px;
+                height: 100%;
+                font-size: 12px;
+                text-align: center;
+                box-sizing: border-box;
+                color: #f3c11d;
+                display: flex;
+                flex-direction: column;
+                align-items: center;
+                margin: 0 12px;
+                background: url("@/assets/images/home/scale-bg.png") no-repeat center center / 100% 100%;
+                .label {
+                    width: 85px;
+                    height: 16px;
+                    line-height: 16px;
+                    color: #fff;
+                    background: url("@/assets/images/home/label-bg.png") no-repeat center center / 100% 100%;
+                }
+                .value {
+                    font-size: 18px;
+                    font-family: "PangMenZhengDao";
+                    span {
+                        font-size: 12px;
+                    }
+                }
+            }
+        }
+
+        .box-bg {
+            margin-top: 8px;
+            border-radius: 2px 2px 0 0;
+            font-size: 12px;
+            padding: 3px 6px;
+            box-sizing: border-box;
+            font-family: Arial, Helvetica, sans-serif;
+            overflow-y: auto;
+            background: linear-gradient(180deg, rgb(85, 85, 85, 0.4) 0%, rgb(35, 35, 35, 1) 100%);
+            .text {
+                position: relative;
+                span {
+                    color: rgba(255, 255, 255, 0.4);
+                    line-height: 1.7;
+                }
+            }
+        }
+    }
+}
+</style>

+ 226 - 0
src/views/home/components/leftComponents/leftWeather.vue

@@ -0,0 +1,226 @@
+<template>
+    <div class="chart-list">
+        <div class="chart-item weather-item">
+            <chart-box name="气象风险">
+                <!-- <template #title-right>
+                    <div class="button" @click="gybg">果园报告</div>
+                </template> -->
+                <div class="base-wrap">
+                    <div class="base-item" v-for="(item, index) in baseData.labels" :key="index">
+                        <div class="label">{{ item }}风险</div>
+                        <div class="value">{{ baseData.valueMaxList[index].toFixed(0) }}<span>%</span></div>
+                    </div>
+                </div>
+                <weatherChart class="line-chart"></weatherChart>
+            </chart-box>
+        </div>
+        <div class="chart-item">
+            <chart-box :name="riskKeys[1]">
+                <template #title-right>
+                  <div class="import">导入</div>
+                </template>
+                <one-line-chart class="line-chart" key="tr" :name="riskKeys[1]" :yData="yData1" :minData="[]" :chartDate="chartDate1"></one-line-chart>
+                <div class="box-bg tips">
+                    <div class="text">
+                        {{ text1 }}
+                    </div>
+                </div>
+            </chart-box>
+        </div>
+        <div class="chart-item">
+            <chart-box name="阴雨渍水">
+                <template #title-right>
+                  <div class="import">导入</div>
+                </template>
+                <one-line-chart class="line-chart" :name="riskKeys[0]" :key="1" :yData="yData" :minData="[]" :chartDate="chartDate"></one-line-chart>
+                <div class="box-bg tips">
+                    <div class="text">
+                        {{ text }}
+                    </div>
+                </div>
+            </chart-box>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import chartBox from "@/components/chartBox.vue";
+import oneLineChart from "@/components/charts/oneLineChart.vue";
+import { onMounted, ref, onUnmounted } from "vue";
+import eventBus from "@/api/eventBus";
+import weatherChart from "../weatherChart.vue";
+
+const riskKeys = ref([])
+
+const yData = ref([]);
+const yData1 = ref([]);
+const yData2 = ref([]);
+const yData3 = ref([]);
+
+const chartDate = ref([])
+const chartDate1 = ref([])
+const chartDate2 = ref([])
+const chartDate3 = ref([])
+
+const text = ref(null)
+const text1 = ref(null)
+const text2 = ref(null)
+
+const baseData = ref({});
+
+const organId = ref(sessionStorage.getItem('farmId'));
+
+// onMounted(() => {
+//   getList()
+//   getBaseData()
+//   getTimeIndex()
+//   eventBus.on("area:id", changeAreaId);
+// });
+onUnmounted(()=>{
+  eventBus.off("area:id", changeAreaId);
+})
+
+function changeAreaId({farmId}){
+    organId.value = farmId
+    getList()
+    getBaseData()
+    getTimeIndex()
+}
+
+function getList() {
+    riskKeys.value = []
+    yData.value.value = []
+    yData1.value.value = []
+    yData2.value.value = []
+    chartDate.value.value = []
+    chartDate1.value.value = []
+    chartDate2.value.value = []
+    VE_API.farm.getFarmReport({ farmId: organId.value, type: "气象风险" }).then((res) => {
+        // if (res.data["物候进程"]) {}
+        // 使用 Object.keys() 提取对象中的键
+        riskKeys.value = Object.keys(res.data);
+        yData.value = res.data[riskKeys.value[0]].list.map((item) => parseFloat(item.value.toFixed(1)))
+        yData1.value = res.data[riskKeys.value[1]].list.map((item) => parseFloat(item.value.toFixed(1)))
+        yData2.value = res.data[riskKeys.value[2]].list.map((item) => parseFloat(item.value.toFixed(1)))
+
+        chartDate.value = formattedDates(res.data[riskKeys.value[0]].list.map((item) => item.name))
+        chartDate1.value = formattedDates(res.data[riskKeys.value[1]].list.map((item) => item.name))
+        chartDate2.value = formattedDates(res.data[riskKeys.value[2]].list.map((item) => item.name))
+
+        text.value = res.data[riskKeys.value[0]].text
+        text1.value = res.data[riskKeys.value[1]].text
+        text2.value = res.data[riskKeys.value[2]].text
+    })
+}
+
+
+
+function formattedDates(dates) {
+      return dates.map(date => {
+        const [year, month, day] = date.split('-');
+        return `${month}-${day}`; // 使用模板字符串格式化为 MM/DD
+      });
+}
+
+
+const getBaseData = () => {
+    const point = sessionStorage.getItem("point");
+    // 获取气象图表数据
+    VE_API.mini_farm.weather_warning_land_check({ farmId: organId.value, point }).then((res) => {
+        baseData.value = res.data || {};
+    });
+};
+
+const getTimeIndex = () => {
+  VE_API.farm.getTimeIndex({ farmId: organId.value }).then(({data}) =>{
+      chartDate3.value = formattedDates(data.map((item) => item.date))
+      yData3.value = data.map((item) => parseFloat(item.value.toFixed(3)))
+  })
+}
+
+</script>
+
+<style lang="scss" scoped>
+.chart-list {
+    width: calc(100% - 54px - 10px);
+    height: 100%;
+    overflow: auto;
+    padding: 8px 8px 0;
+    box-sizing: border-box;
+    .chart-item {
+        width: 100%;
+        // height: 240px;
+        box-sizing: border-box;
+        margin-bottom: 10px;
+        height: calc((100% - 276px) / 2 - 10px);
+        .import{
+          font-size: 12px;
+          background: rgba(255, 255, 255, 0.2);
+          border-radius: 4px;
+          padding: 5px 13px;
+          cursor: pointer;
+        }
+        .line-chart {
+            width: 100%;
+            height: calc(100% - 70px);
+        }
+
+        &.weather-item {
+            height: 266px;
+        }
+
+        .base-wrap {
+            width: 100%;
+            height: 56px;
+            margin-top: 4px;
+            display: flex;
+            justify-content: space-evenly;
+            .base-item {
+                width: 110px;
+                height: 100%;
+                font-size: 12px;
+                text-align: center;
+                box-sizing: border-box;
+                color: #f3c11d;
+                display: flex;
+                flex-direction: column;
+                align-items: center;
+                margin: 0 12px;
+                background: url("@/assets/images/home/scale-bg.png") no-repeat center center / 100% 100%;
+                .label {
+                    width: 85px;
+                    height: 16px;
+                    line-height: 16px;
+                    color: #fff;
+                    background: url("@/assets/images/home/label-bg.png") no-repeat center center / 100% 100%;
+                }
+                .value {
+                    font-size: 18px;
+                    font-family: "PangMenZhengDao";
+                    span {
+                        font-size: 12px;
+                    }
+                }
+            }
+        }
+
+        .box-bg {
+          margin-top: 8px;
+            border-radius: 2px 2px 0 0;
+            font-size: 12px;
+            padding: 3px 6px;
+            box-sizing: border-box;
+            font-family: Arial, Helvetica, sans-serif;
+            overflow-y: auto;
+            background: linear-gradient(180deg, rgb(85, 85, 85, 0.4) 0%, rgb(35, 35, 35, 1) 100%);
+            .text {
+                position: relative;
+                span {
+                    color: rgba(255, 255, 255, 0.4);
+                    line-height: 1.7;
+                }
+            }
+        }
+    }
+}
+</style>

+ 162 - 61
src/views/home/index.vue

@@ -3,28 +3,33 @@
         <fnHeader showDate></fnHeader>
         <div class="content">
             <navigation style="margin-left: 50px" @handleTab="handleTab"></navigation>
-            <div class="left yes-events">
-                <tool-list direction="left" :list="leftToolList" @handleActive="handleActiveLeft"></tool-list>
+            <div class="left yes-events" :class="{ 'collapsed-left': isLeftShrink }">
+                <div class="home-btn">
+                    <div class="btn" @click="changeLeftComponent(0)" :class="{active: activeBtn === 0}">实时感知</div>
+                    <div class="btn" @click="changeLeftComponent(1)" :class="{active: activeBtn === 1}">诊断识别</div>
+                </div>
+                <tool-list direction="left" ref="leftTool" :list="leftToolList[activeBtn]" @handleActive="handleActiveLeft"></tool-list>
                 <component :is="components[currentComponent]" />
                 <!-- 箭头 -->
                 <div class="arrow" @click="handleShrink('left')">
-                    <el-icon class="icon" color="#141414"><DArrowLeft /></el-icon>
+                    <el-icon class="icon" :class="{ 'arrow-left': isLeftShrink }" color="#141414"><DArrowLeft /></el-icon>
                 </div>
             </div>
             <div class="home-bottom">
-                <div class="garden-file" :class="{ isShrink: isShrink }">
+                <img class="img yes-events" @click="handlePage" src="@/assets/images/home/table-btn-sk.png" alt="">
+                <!-- <div class="garden-file" :class="{ isShrink: isShrink }">
                     <home-file></home-file>
-                </div>
+                </div> -->
             </div>
-            <div class="right yes-events">
+            <div class="right yes-events" :class="{ 'collapsed-right': isRightShrink }">
+                <div class="home-btn">
+                    <div class="btn" @click="changeRightComponent(0)" :class="{active: activeRightBtn === 0}">精细农事</div>
+                    <div class="btn" @click="changeRightComponent(1)" :class="{active: activeRightBtn === 1}">人机执行</div>
+                </div>
                 <div class="list album-r">
                     <chart-box name="农事列表" arrow="arrow-left" :class="{ 'list-wrap': rightIndex === 0 }">
                         <template v-if="rightIndex === 0">
                             <album></album>
-                            <!-- <img class="tabs" src="@/assets/images/home/ns-tabs.png" alt="">
-              <div class="img-box">
-                <img @click="handleAct(item)" v-for="item in 2" :key="item" :src="require(`@/assets/images/home/0${act<=2&&act==item?item+'-act':item}.png`)" alt="">
-              </div> -->
                         </template>
                         <template v-if="rightIndex === 1">
                             <div class="img-box1">
@@ -32,29 +37,13 @@
                                 <img src="@/assets/images/home/fh02.png" alt="" />
                             </div>
                         </template>
-                        <template v-if="rightIndex === 2">
-                            <div class="btn-wrap">
-                                <div :class="{ active: btnIndex === 0 }" @click="handleBtn(0)">
-                                    {{ btnIndex === 0 && btnName != "" ? "采样分区:" + btnName : "选择采样分区" }}
-                                </div>
-                                <div :class="{ active: btnIndex === 1 }" @click="handleBtn(1)">
-                                    {{ btnIndex === 1 && btnName != "" ? "单树编号:" + btnName : "选择树" }}
-                                </div>
-                            </div>
-                            <div class="img-box2" v-show="showPoint">
-                                <img v-if="showType === 'point'" src="@/assets/images/home/line-chart.png" alt="" />
-                                <img v-else src="@/assets/images/home/line-chart2.png" alt="" />
-                                <img src="@/assets/images/home/fh01.png" alt="" />
-                            </div>
-                            <div class="img-box2" v-show="!showPoint">
-                                <img v-if="showType === 'point'" src="@/assets/images/home/line-chart1.png" alt="" />
-                                <img v-else src="@/assets/images/home/line-chart3.png" alt="" />
-                                <img src="@/assets/images/home/fh02.png" alt="" />
-                            </div>
-                        </template>
                     </chart-box>
                 </div>
-                <tool-list direction="right" :list="rightToolList" @handleActive="handleActiveRight"></tool-list>
+                <tool-list direction="right" ref="rightTool" :list="rightToolList[activeRightBtn]" @handleActive="handleActiveRight"></tool-list>
+                <!-- 箭头 -->
+                <!-- <div class="arrow" @click="handleShrink('right')">
+                    <el-icon class="icon" :class="{ 'arrow-right': isRightShrink }" color="#141414"><DArrowRight /></el-icon>
+                </div> -->
             </div>
 
             <!-- 图例 -->
@@ -174,9 +163,37 @@ import album from "./album/index.vue";
 import PdfDialog from "../../components/PdfDialog";
 import StaticMapLayers from "@/components/static_map_change/Layers.js"
 import FarmFightTask from "./components/farmFightTask";
+import leftFly from "./components/leftComponents/leftFly.vue";
+import leftWeather from "./components/leftComponents/leftWeather.vue";
+import leftStation from "./components/leftComponents/leftStation.vue";
+
+const activeBtn = ref(0)
+const leftTool = ref(null)
+function changeLeftComponent(i) {
+    activeBtn.value = i
+    handleActiveLeft(leftToolList[i][0])
+    // if(i){
+    //     isDisable.value = false
+    // }else{
+    //     isDisable.value = true
+    // }
+    leftTool.value.resetActive(0)
+}
+
+const rightTool = ref(null)
+const activeRightBtn = ref(0)
+function changeRightComponent(i) {
+    activeRightBtn.value = i
+    handleActiveRight(rightToolList[i][0])
+    rightTool.value.resetActive(0)
+}
+
 
 let store = useStore();
 const components = {
+    leftFly,
+    leftWeather,
+    leftStation,
     homePage,
     weatherPage,
     phenologyPage,
@@ -533,33 +550,51 @@ eventBus.on("click:updateArea", (e) => {
     //getFarmLog()
 });
 
-const currentComponent = ref("homePage");
+const currentComponent = ref("leftFly");
 const handleActiveLeft = (e) => {
     currentComponent.value = e.componentName;
-    if (e.title === "首页") {
-        router.push("/warningHome");
-    }
 };
-const leftToolList = [
-    {
-        title: "首页",
-        name: "home",
-        componentName: "homePage",
+const leftToolList = [[
+        {
+        title: "飞巡感知",
+        componentName: "leftFly",
     },
     {
-        title: "气象预警",
-        componentName: "weatherPage",
+        title: "气象感知",
+        componentName: "leftWeather"
     },
     {
-        title: "物候调节",
+        title: "人工感知",
         componentName: "phenologyPage",
     },
     {
-        title: "病虫测报",
-    },
-    {
-        title: "营养评估",
+        title: "站点感知",
+        componentName: "leftStation",
     },
+    ],
+    [
+        {
+            title: "首页",
+            name:'home',
+            componentName: "homePage"
+        },
+        {
+            title: "气象预警",
+            componentName: "weatherPage"
+        },
+        {
+            title: "物候调节",
+            componentName: "phenologyPage"
+        },
+        {
+            title: "病虫指标",
+            componentName: "rightWeather"
+        },
+        {
+            title: "营养评估",
+            componentName: "rightWeather"
+        },
+    ]
 ];
 
 const rightIndex = ref(0);
@@ -578,19 +613,35 @@ const hanleRightIndex = (num) => {
     rightIndex.value = num;
     eventBus.emit("tool:updateAct", num);
 };
-const rightToolList = [
-    {
-        title: "农事列表",
-        index: 0,
-    },
-    {
-        title: "处方分析",
-        index: 2,
-    },
-    {
-        title: "复核对比",
-        index: 1,
-    },
+const rightToolList = [[
+        {
+            title: "农事列表",
+            componentName: "leftFly",
+            index: 0,
+        },
+        {
+            title: "认证评估",
+            componentName: "leftFly",
+            index: 1,
+        },
+    ],
+    [
+        {
+            title: "无人机",
+            componentName: "leftFly",
+            index: 2,
+        },
+        {
+            title: "农机设备",
+            componentName: "leftFly",
+            index: 2,
+        },
+        {
+            title: "人工巡园",
+            componentName: "leftFly",
+            index: 2,
+        },
+    ]
 ];
 
 // 跳转果园档案
@@ -656,10 +707,43 @@ const photoList = ref([
 
     .content {
         width: 100%;
-        height: calc(100% - 74px - 48px);
+        height: calc(100% - 74px - 48px - 54px);
         display: flex;
         justify-content: space-between;
         box-sizing: border-box;
+        margin-top: 60px;
+        .home-btn {
+            position: absolute;
+            top: -60px;
+            left: 0;
+            height: 54px;
+            display: flex;
+            border: 1px solid #444444;
+            background: #101010;
+            border-radius: 0 8px 8px 0;
+            padding: 8px;
+            box-sizing: border-box;
+            width: 429px;
+            .btn {
+                flex: 1;
+                background: rgba(79, 79, 79, 0.6);
+                border-radius: 4px;
+                font-size: 20px;
+                font-family: "PangMenZhengDao";
+                color: #fff;
+                text-align: center;
+                height: 38px;
+                line-height: 38px;
+                cursor: pointer;
+                &.active {
+                    background: linear-gradient(180deg, #FFD887, #ED9E1E);
+                    color: #1D1D1D;
+                }
+            }
+            .btn + .btn {
+                margin-left: 8px;
+            }
+        }
         .left,
         .right {
             width: calc(376px + 54px);
@@ -668,6 +752,16 @@ const photoList = ref([
             box-sizing: border-box;
             display: flex;
             position: relative;
+            transition: transform 0.3s;
+        }
+        .collapsed-left{
+            transform: translateX(-430px);
+        }
+        .collapsed-right{
+            transform: translateX(430px);
+        }
+        .arrow-left{
+            transform: rotate(180deg);
         }
         .left {
             background: #101010;
@@ -684,6 +778,7 @@ const photoList = ref([
                 border-radius: 0 5px 5px 0;
                 text-align: center;
                 cursor: pointer;
+                transition: transform 0.3s;
             }
         }
         .right {
@@ -764,6 +859,12 @@ const photoList = ref([
             width: calc(100% - 20px - 430px * 2);
             height: 152px;
             align-self: flex-end;
+            justify-content: center;
+            .img{
+                width: 268px;
+                height: 66px;
+                cursor: pointer;
+            }
             .time-wrap {
                 height: 85px;
             }