Procházet zdrojové kódy

feat:修改首页

wangsisi před 4 dny
rodič
revize
c972b5c873

+ 1 - 208
src/App.vue

@@ -1,17 +1,4 @@
-<!--
- * @Author: your name
- * @Date: 2021-01-07 09:49:29
- * @LastEditTime: 2021-11-01 14:08:55
- * @LastEditors: Please set LastEditors
- * @Description: In User Settings Edit
- * @FilePath: \vue3-element-admin\src\App.vue
--->
 <template>
-    <!-- <router-view v-slot="{ Component }">
-  <keep-alive exclude="GardenReport">
-    <component :is="Component" />
-  </keep-alive>
-</router-view> -->
     <router-view v-slot="{ Component }">
         <keep-alive v-if="route.meta && route.meta.keepAlive">
             <component :is="Component" />
@@ -20,208 +7,14 @@
         <component v-else :is="Component" />
     </router-view>
 
-
-    <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>
-                <template #icon="props">
-                    <img
-                        :src="
-                            props.active
-                                ? require('@/assets/img/tab_bar/home-active.png')
-                                : require('@/assets/img/tab_bar/home.png')
-                        "
-                    />
-                </template>
-            </tabbar-item>
-            <tabbar-item replace to="/monitor">
-                <span>作物档案</span>
-                <template #icon="props">
-                    <img
-                        :src="
-                            props.active
-                                ? require('@/assets/img/tab_bar/tree-active.png')
-                                : require('@/assets/img/tab_bar/tree.png')
-                        "
-                    />
-                </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> -->
-
-        <!-- 普通农户:首页、农事服务、用户管理、个人中心(保留原逻辑) -->
-        <!-- <template v-else-if="userType == 1">
-            <tabbar-item replace to="/home" v-if="curRole == 0 || curRole == 2">
-                <span>首页</span>
-                <template #icon="props">
-                    <img
-                        :src="
-                            props.active
-                                ? require('@/assets/img/tab_bar/home-active.png')
-                                : require('@/assets/img/tab_bar/home.png')
-                        "
-                    />
-                </template>
-            </tabbar-item>
-            <tabbar-item replace to="/task_condition">
-                <span>农事服务</span>
-                <template #icon="props">
-                    <img
-                        :src="
-                            props.active
-                                ? require('@/assets/img/tab_bar/service-active.png')
-                                : require('@/assets/img/tab_bar/service.png')
-                        "
-                    />
-                </template>
-            </tabbar-item>
-            <tabbar-item replace to="/user">
-                <span>用户管理</span>
-                <template #icon="props">
-                    <img
-                        :src="
-                            props.active
-                                ? require('@/assets/img/tab_bar/user-active.png')
-                                : require('@/assets/img/tab_bar/user.png')
-                        "
-                    />
-                </template>
-            </tabbar-item>
-            <tabbar-item replace to="/mine">
-                <span>个人中心</span>
-                <template #icon="props">
-                    <img
-                        :src="
-                            props.active
-                                ? require('@/assets/img/tab_bar/mine-active.png')
-                                : require('@/assets/img/tab_bar/mine.png')
-                        "
-                    />
-                </template>
-            </tabbar-item>
-        </template> -->
-    </Tabbar>
-
     <!-- 开启底部安全区适配 -->
     <number-keyboard safe-area-inset-bottom />
 </template>
 
 <script setup>
 import { NumberKeyboard } from "vant";
-import { Tabbar, TabbarItem } from "vant";
-import { nextTick, watch, onMounted, ref, computed } from "vue";
-import { useRoute, useRouter } from "vue-router";
-import { useStore } from "vuex";
-import { NH, NZ, EXPERT } from "@/common/user_role";
-const store = useStore();
+import { useRoute } from "vue-router";
 const route = useRoute();
-const router = useRouter();
-
-// 首页loading加载完才显示底部导航栏
-const showTab = ref(false);
-// 0: 农户, 1: 专家, 2:农资农服
-const curRole = ref(0);
-// USER_TYPE: 1 普通农户,2 托管农户
-const userType = ref("2");
-
-// 获取用户是否为托管农户,并缓存 USER_TYPE(与 dev_login.vue 逻辑一致)
-const fetchUserType = async () => {
-    
-    userType.value = "2";
-    localStorage.setItem("USER_TYPE", "2");
-
-    // // 检查是否有 token,没有 token 则不调用接口
-    // const token = store.state.app.token || localStorage.getItem("token");
-    // if (!token) {
-    //     // 没有 token 时使用缓存的值
-    //     userType.value = localStorage.getItem("USER_TYPE") || "1";
-    //     return;
-    // }
-
-    // try {
-    //     const { data } = await VE_API.farm.userFarmSelectOption({ userType: 2 });
-    //     if (Array.isArray(data) && data.length > 0) {
-    //         // 有托管农户数据
-    //         userType.value = "2";
-    //         localStorage.setItem("USER_TYPE", "2");
-    //     } else {
-    //         userType.value = "1";
-    //         localStorage.setItem("USER_TYPE", "1");
-    //     }
-    // } catch (error) {
-    //     // 请求失败时保留默认值
-    //     userType.value = localStorage.getItem("USER_TYPE") || "1";
-    // }
-};
-
-let tabBarHeight = 0;
-
-// 监听 token 变化,当有 token 时调用接口获取用户类型
-watch(
-    () => store.state.app.token,
-    (newToken) => {
-        if (newToken) {
-            fetchUserType();
-        }
-    },
-    { immediate: true }
-);
-
-onMounted(() => {
-    setTimeout(() => {
-        curRole.value = store.state.app.curRole;
-        if (route.meta.showTabbar) {
-            showTab.value = true;
-        }
-        nextTick(() => {
-            const tabBarElement = document.querySelector(".van-tabbar");
-            if (tabBarElement) {
-                tabBarHeight = tabBarElement.offsetHeight;
-                localStorage.setItem("tabBarHeight", tabBarHeight);
-                store.commit("home/SET_TAB_BAR_HEIGHT", tabBarHeight);
-            }
-        });
-    }, 500);
-});
-
-watch(
-    () => route.name,
-    (newName, oldName) => {
-        // 在这里执行你的自定义逻辑
-        showTab.value = false;
-        if (route.meta.showTabbar) {
-            showTab.value = true;
-        }
-        nextTick(() => {
-            const tabBarElement = document.querySelector(".van-tabbar");
-            if (tabBarElement) {
-                tabBarHeight = tabBarElement.offsetHeight;
-                localStorage.setItem("tabBarHeight", tabBarHeight);
-                store.commit("home/SET_TAB_BAR_HEIGHT", tabBarHeight);
-            }
-            curRole.value = store.state.app.curRole
-        });
-    },
-    { immediate: false }
-);
 </script>
 <style lang="scss" scoped>
-.tabbar {
-    position: fixed;
-    pointer-events: all;
-    z-index: 9999;
-}
 </style>

+ 0 - 1
src/router/globalRoutes.js

@@ -15,7 +15,6 @@ export default [
     {
         path: "/home",
         name: "Home",
-        meta: { showTabbar: true, keepAlive: true },
         component: () => import("@/views/old_mini/home/index.vue"),
     },
     {

+ 0 - 345
src/views/old_mini/home/index copy.vue

@@ -1,345 +0,0 @@
-<template>
-    <div class="home-index" :style="{ height: `calc(100vh - ${tabBarHeight}px)` }">
-        <div class="banner-wrap">
-            <img class="banner-img" @click="handleBannerClick" :src="bannerObj?.media?.[0]" alt="" />
-            <div class="banner-title">
-                <span class="van-multi-ellipsis--l2">{{ bannerObj?.title }}</span>
-            </div>
-        </div>
-        <!-- 天气遮罩 -->
-        <div class="weather-mask" v-show="isExpanded" @click="handleMaskClick"></div>
-        <!-- 天气 -->
-        <weather-info
-            ref="weatherInfoRef"
-            class="weather-info"
-            @weatherExpanded="weatherExpanded"
-            :isGarden="false"
-            @changeGarden="changeGarden"
-        ></weather-info>
-        <div class="farm-monitor-container" :class="{ 'container-role': curRole == 2 }">
-            <div class="farm-monitor-left" @click="handleCardClick(monitorCards.left)">
-                <div class="title">
-                    <span>{{ monitorCards.left.title }}</span>
-                    <el-icon v-if="curRole == 2" class="icon"><ArrowRightBold /></el-icon>
-                </div>
-                <div class="content">{{ monitorCards.left.content }}</div>
-                <div class="arrow" v-if="curRole != 2">
-                    <el-icon class="icon"><ArrowRightBold /></el-icon>
-                </div>
-            </div>
-            <div class="farm-monitor-right">
-                <div
-                    v-for="(item, index) in monitorCards.right"
-                    :key="index"
-                    class="right-item"
-                    :class="{ expert: index === 1 }"
-                    @click="handleCardClick(item)"
-                >
-                    <div class="title">
-                        <span>{{ item.title }}</span>
-                        <el-icon class="icon"><ArrowRightBold /></el-icon>
-                    </div>
-                    <div class="content">{{ item.content }}</div>
-                </div>
-            </div>
-        </div>
-        <AgriculturalDynamics />
-    </div>
-    <!-- 创建农场弹窗 -->
-    <tip-popup
-        v-model:show="showFarmPopup"
-        :type="farmPopupType"
-        :text="farmPopupType === 'create' ? ['您当前还没有农场', '请先创建农场'] : '农场创建成功'"
-        @confirm="handleBtn"
-    />
-    <!-- 问题提醒 -->
-    <problem-reminder></problem-reminder>
-</template>
-
-<script setup>
-import { ref, computed, onActivated } from "vue";
-import { useStore } from "vuex";
-import weatherInfo from "@/components/weatherInfo.vue";
-import AgriculturalDynamics from "./components/AgriculturalDynamics.vue";
-import { useRouter, useRoute } from "vue-router";
-import wx from "weixin-js-sdk";
-import problemReminder from "./components/problemReminder.vue";
-import { ElMessage } from "element-plus";
-import tipPopup from "@/components/popup/tipPopup.vue";
-
-const curRole = localStorage.getItem("SET_USER_CUR_ROLE");
-const store = useStore();
-const tabBarHeight = computed(() => store.state.home.tabBarHeight);
-const router = useRouter();
-const route = useRoute();
-
-const showFarmPopup = ref(false);
-const farmPopupType = ref("create");
-
-const gardenId = ref(null);
-
-const isGarden = ref(false);
-const changeGarden = ({ id }) => {
-    gardenId.value = id;
-    getExpertByFarmId();
-};
-
-const expertInfo = ref({});
-const getExpertByFarmId = () => {
-    VE_API.home.getExpertByFarmId({ farmId: gardenId.value }).then(({ data }) => {
-        expertInfo.value = data || {};
-        sessionStorage.setItem("expertId", data.appUserId);
-    });
-};
-
-// 监测卡片数据
-const monitorCards = ref({
-    left: {
-        title: "农场监测",
-        content: "实时监测农场状态",
-        route: "/monitor",
-    },
-    right: [
-        {
-            title: "病虫识别",
-            content: "精准识别病虫",
-            route: "/pest",
-        },
-        {
-            title: "专家咨询",
-            content: "专家多年经验指导",
-            route: "/chat_frame",
-        },
-    ],
-});
-
-// 卡片点击事件
-const handleCardClick = (card) => {
-    if (curRole == 0) {
-        if (!isGarden.value) {
-            showFarmPopup.value = true;
-            return;
-        }
-    }
-    if (card.route === "/pest") {
-        // ElMessage.warning("该功能正在升级中,敬请期待");
-        // if (curRole == 2) {
-        //     ElMessage.warning("该功能正在升级中,敬请期待");
-        // } else {
-            const dropdownGardenItem = ref({
-                organId: 766,
-                periodId: 1,
-                wktVal: "wktVal",
-                address: "address",
-                district: "district",
-                name: "荔博园",
-            });
-            wx.miniProgram.navigateTo({
-                url: `/pages/subPages/new_recognize/index?gardenData=${JSON.stringify(dropdownGardenItem.value)}`,
-            });
-        // }
-    } else {
-        if (card.route === "/chat_frame") {
-            router.push("/agri_services?active=1");
-            // router.push(`/chat_frame?userId=${expertInfo.value.appUserId}`);
-        } else {
-            router.push(card.route);
-        }
-    }
-};
-
-const handleBtn = () => {
-    if (farmPopupType.value === "create") {
-        router.push("/create_farm?isReload=true&from=home");
-    }
-};
-
-onActivated(() => {
-    getBannerList();
-    isGarden.value = Boolean(localStorage.getItem("isGarden"));
-    // 检测是否从创建农场页面成功返回
-    if (route.query.showSuccess === "true") {
-        farmPopupType.value = "success";
-        showFarmPopup.value = true;
-
-        // 清除URL参数,避免刷新页面时再次显示弹窗
-        router.replace({
-            path: "/home",
-            query: { reload: route.query.reload },
-        });
-    }
-    if (curRole == 2) {
-        monitorCards.value.left = {
-            title: "新增客户",
-            content: "实时监测农场状态",
-            route: "/create_farm?type=client&isReload=true&from=home",
-        };
-        monitorCards.value.right = [
-            {
-                title: "病虫识别",
-                content: "精准识别病虫",
-                route: "/pest",
-            },
-        ];
-    }
-});
-
-const bannerObj = ref({});
-const getBannerList = () => {
-    const params = {
-        page: 1,
-        limit: 1,
-        topicId: 5,
-    };
-    VE_API.home.warningPageList(params).then(({ data }) => {
-        bannerObj.value = data[0] || {};
-    });
-};
-
-const isExpanded = ref(false);
-const weatherInfoRef = ref(null);
-const weatherExpanded = (isExpandedValue) => {
-    isExpanded.value = isExpandedValue;
-};
-
-// 点击遮罩时收起天气
-const handleMaskClick = () => {
-    if (weatherInfoRef.value && weatherInfoRef.value.toggleExpand) {
-        weatherInfoRef.value.toggleExpand();
-    }
-};
-
-const handleBannerClick = () => {
-    router.push(`/warning_detail?id=${bannerObj.value.id}`);
-};
-</script>
-
-<style scoped lang="scss">
-.home-index {
-    width: 100%;
-    height: 100vh;
-    overflow: auto;
-    position: relative;
-    .banner-wrap {
-        width: 100%;
-        height: 200px;
-        position: relative;
-        z-index: 1;
-        .banner-img {
-            width: 100%;
-            height: 100%;
-            object-fit: cover;
-        }
-        .banner-title {
-            position: absolute;
-            bottom: 0;
-            left: 0;
-            width: 100%;
-            padding: 10px 12px 34px 12px;
-            box-sizing: border-box;
-            background: linear-gradient(
-                180deg,
-                rgba(102, 102, 102, 0) -64.3%,
-                rgba(0, 0, 0, 0.0074) -1.43%,
-                rgba(0, 0, 0, 0.684747) 39.67%,
-                rgba(0, 0, 0, 0.74) 40.09%,
-                rgba(0, 0, 0, 0.74) 83.2%
-            );
-            color: #fff;
-            font-weight: bold;
-            backdrop-filter: blur(2px);
-        }
-    }
-    .weather-mask {
-        position: fixed;
-        top: 0;
-        left: 0;
-        width: 100%;
-        height: 100%;
-        background-color: rgba(0, 0, 0, 0.52);
-        z-index: 2;
-    }
-    .weather-info {
-        width: calc(100% - 20px);
-        position: absolute;
-        top: calc(200px - 28px);
-        left: 10px;
-        z-index: 3;
-    }
-    .farm-monitor-container {
-        padding-top: 60px;
-        display: flex;
-        align-items: center;
-        gap: 7px;
-        margin: 10px;
-        height: 170px;
-        .farm-monitor-left,
-        .farm-monitor-right {
-            .title {
-                font-size: 16px;
-                color: #1d2129;
-                font-weight: 500;
-                .icon {
-                    font-size: 12px;
-                    margin-left: 2px;
-                }
-            }
-            .content {
-                margin-top: 6px;
-                font-size: 12px;
-                color: rgba(29, 33, 41, 0.5);
-                line-height: 1.5;
-            }
-            .arrow {
-                border-radius: 5px;
-                background: #fff;
-                display: flex;
-                align-items: center;
-                justify-content: center;
-                width: 34px;
-                height: 25px;
-                margin-top: 10px;
-                font-size: 11px;
-            }
-        }
-        .farm-monitor-left {
-            flex: 1;
-            height: 100%;
-            padding: 25px 10px;
-            box-sizing: border-box;
-            background: url("@/assets/img/home/farm-bg-1.png") no-repeat center center / 100% 100%;
-        }
-        .farm-monitor-right {
-            flex: 1;
-            height: 100%;
-            display: flex;
-            flex-direction: column;
-            gap: 7px;
-            .right-item {
-                padding: 10px;
-                box-sizing: border-box;
-                display: flex;
-                flex-direction: column;
-                justify-content: center;
-                flex: 1;
-                background: url("@/assets/img/home/farm-bg-2.png") no-repeat center center / 100% 100%;
-            }
-            .expert {
-                background: url("@/assets/img/home/farm-bg-3.png") no-repeat center center / 100% 100%;
-            }
-        }
-
-        &.container-role {
-            height: 104px;
-            .farm-monitor-left {
-                background: url("@/assets/img/home/farm-bg-4.png") no-repeat center center / 100% 100%;
-            }
-            .farm-monitor-right {
-                .right-item {
-                    background: url("@/assets/img/home/farm-bg-5.png") no-repeat center center / 100% 100%;
-                }
-            }
-        }
-    }
-}
-</style>

+ 268 - 463
src/views/old_mini/home/index.vue

@@ -1,525 +1,330 @@
 <template>
-    <div class="home-index" :style="{ height: `calc(100vh - ${tabBarHeight}px)` }">
-        <!-- <div class="banner-wrap" @click="handleBannerClick">
-            <img class="banner-img" :src="bannerObj?.media?.[0]" alt="" />
-            <div class="banner-title">  
-                <span class="van-multi-ellipsis--l2">{{ bannerObj?.title }}</span>
+    <div class="home-index">
+        <!-- 顶部:左侧搜索 + 右侧筛选 -->
+        <div class="top-row">
+            <div class="search-bar">
+                <input class="search-input" placeholder="搜索农场" />
             </div>
-        </div> -->
-        <!-- 天气遮罩 -->
-        <div class="weather-mask" v-show="isExpanded" @click="handleMaskClick"></div>
-        <!-- 天气 -->
-        <weather-info ref="weatherInfoRef" class="weather-info" @weatherExpanded="weatherExpanded" :isGarden="false"
-            @changeGarden="changeGarden"></weather-info>
-        <div class="expert-home">
-            <div class="expert-banner" @click="handleExpertBannerClick">
-                <img class="expert-banner-img" src="@/assets/img/home/banner.png" alt="">
-                <div class="expert-desc">
-                    <img class="expert-desc-icon" src="@/assets/img/home/expert-text.png" alt="">
-                    <!-- <div class="desc-text"><span class="dotted"></span>您有一条长势报告,请查看</div> -->
-                    <div class="desc-text"><span class="dotted"></span>点击查看农情互动采集</div>
-                </div>
+            <div class="filter-row">
+                <button class="filter-btn">选择地区</button>
+                <button class="filter-btn">选择品类</button>
             </div>
         </div>
 
-        <!-- <div class="task-list">
-            <div class="task-title">待办任务</div>
-            <div class="bottom-tag">
-                <div class="tag-card">
-                    <div class="card-content">
-                        <div class="card-main-text">干旱风险</div>
-                        <div class="card-sub-text">
-                            气象风险
+        <!-- 农场信息卡片 -->
+        <div class="farm-card">
+            <div class="farm-header">
+                <div class="farm-header-left">
+                    <div class="farm-title">
+                        <span>{{ farmInfo.name }}</span>
+                        <div class="title-tags">
+                            <div class="title-tag">桂味</div>
+                            <div class="title-tag tag-danger">
+                                <span>干旱预警</span>
+                                <el-icon>
+                                    <ArrowRight />
+                                </el-icon>
+                            </div>
                         </div>
                     </div>
+                    <div class="farm-subtitle">{{ farmInfo.address }}</div>
                 </div>
-                <div class="tag-card active">
-                    <div class="card-content">
-                        <div class="card-main-text">当天</div>
-                        <div class="card-sub-text">新梢长势评估</div>
+                <div class="farm-more">详情</div>
+            </div>
+
+            <div class="content-grid">
+                <div class="label-column">
+                    <div class="label-cell" v-for="row in rows" :key="row.label">
+                        {{ row.label }}
                     </div>
                 </div>
-                <div class="tag-card">
-                    <div class="card-content">
-                        <div class="card-main-text">3天后</div>
-                        <div class="card-sub-text">白点催醒</div>
+                <div class="main-grid">
+                    <div class="row" v-for="row in rows" :key="row.label">
+                        <div v-for="card in row.cards" :key="card.id" class="status-card" :class="card.type"
+                            @click="handleBlockClick(card)">
+                            <div class="status-title">
+                                {{ card.title }}
+                                <span v-if="card.badge" class="badge-dot" />
+                            </div>
+                            <div class="status-sub" v-if="card.sub">
+                                {{ card.sub }}
+                            </div>
+                        </div>
                     </div>
                 </div>
             </div>
-        </div> -->
-
-        <knowledge-card />
-        <!-- <template v-if="userType == 2">
-        </template> -->
-        <!-- <template v-else>
-            <AgriculturalDynamics />
-        </template> -->
+        </div>
     </div>
-    <tip-popup v-model:show="showTipPopup" type="warning" text="请设置" highlightText="种植方案" buttonText="去设置"
-        @confirm="handleBtn" :closeOnClickOverlay="false" :zIndex="9999" />
-
-    <tip-popup v-model:show="showDronePhotoPopup" font type="success" text="无人机照片已上传完毕请您确认" buttonText="去确认"
-        @confirm="hanldeDrone" :zIndex="9999" />
-
-    <!-- 农事执行弹窗 -->
-    <agri-execute-popup v-model:show="showAgriExecutePopup" :popupData="agriExecuteData" @later="handleAgriLater"
-        @executed="handleAgriExecuted" />
-
-    <!-- 提醒时间选择弹窗 -->
-    <reminder-time-popup v-model:show="showReminderTimePopup" @confirm="handleReminderTimeConfirm" />
-
-    <!-- 执行轨迹弹窗 -->
-    <execute-trace-popup v-model:show="showExecuteTracePopup" @later="handleTraceLater" @confirm="handleTraceConfirm" />
-
-    <tip-popup v-model:show="showReportPopup" type="success" text="请查看" buttonText="去查看" @confirm="handleReportBtn"
-        :zIndex="9999">
-        <template #default>
-            <div class="report-text">您的农情报告已生成</div>
-        </template>
-    </tip-popup>
 </template>
 
 <script setup>
-import { ref, computed, onActivated, onMounted } from "vue";
-import { useStore } from "vuex";
-import weatherInfo from "@/components/weatherInfo.vue";
-import AgriculturalDynamics from "./components/AgriculturalDynamics.vue";
-import { useRouter, useRoute } from "vue-router";
-import wx from "weixin-js-sdk";
-import tipPopup from "@/components/popup/tipPopup.vue";
-import agriExecutePopup from "@/components/popup/agriExecutePopup.vue";
-import reminderTimePopup from "@/components/popup/reminderTimePopup.vue";
-import executeTracePopup from "@/components/popup/executeTracePopup.vue";
-import knowledgeCard from "./components/knowledgeCard.vue";
-
-const store = useStore();
-const tabBarHeight = computed(() => store.state.home.tabBarHeight);
-const router = useRouter();
-const route = useRoute();
-
-const showDronePhotoPopup = ref(false)
-const hanldeDrone = () => {
-    console.log('111')
-}
-
-const showTipPopup = ref(false);
-const handleBtn = () => {
-    router.push("/plan?pageType=plant&headerTitle=请设置您的种植方案");
-};
-
-const handleReportBtn = () => {
-    router.push({
-        path: "/growth_report",
-        query: { farmId: gardenId.value },
-    });
-}
+import { ref } from "vue";
 
-// 农事执行弹窗相关
-const showAgriExecutePopup = ref(false); // 农事执行弹窗
-const agriExecuteData = ref({
-    expertName: "韦帮稳",
-    title: "梢期杀虫 农事执行",
-    abnormalText: "由于***异常的出现,由于***异常的出现,由于***异常的出现,由于***异常的出现,",
-    imageUrl: "",
-    laterBtn: true,
+const farmInfo = ref({
+    name: "从化荔博园合作社",
+    address: "广东省广州市从化区某某街道",
 });
 
-// 农事执行弹窗相关方法
-const handleAgriLater = () => {
-    console.log("稍后执行");
-    // 可以在这里添加稍后执行的逻辑
-    // 关闭当前弹窗
-    showAgriExecutePopup.value = false;
-    // 显示提醒时间选择弹窗
-    showReminderTimePopup.value = true;
-};
-
-const handleAgriExecuted = () => {
-    if (agriExecuteData.value.executedButtonText === '开始采集') {
-        router.push("/interaction_list?expertMiniUserId=81881&oldUser=true");
-    } else {
-        // 显示执行轨迹弹窗
-        showExecuteTracePopup.value = true;
-    }
-    // 关闭当前弹窗
-    showAgriExecutePopup.value = false;
-};
-
-// 提醒时间选择弹窗相关
-const showReminderTimePopup = ref(false);
-
-// 确认提醒时间
-const handleReminderTimeConfirm = (time) => {
-    console.log("选择的提醒时间:", time);
-    // 可以在这里添加提交提醒时间的逻辑
-};
-
-// 执行轨迹弹窗相关
-const showExecuteTracePopup = ref(false);
-
-// 稍后上传
-const handleTraceLater = () => {
-    console.log("稍后上传");
-    // 可以在这里添加稍后上传的逻辑
-};
-
-// 确认上传
-const handleTraceConfirm = () => {
-    console.log("确认上传");
-    // 可以在这里添加确认上传的逻辑
-};
-
-//判断是否存在可用方案
-async function checkExistsEnabledScheme() {
-    const { data } = await VE_API.home.existsEnabledScheme({ containerId: null });
-    if (!data && localStorage.getItem("SET_USER_CUR_ROLE") == 2) {
-        showTipPopup.value = true;
-    }
-}
-
-const gardenId = ref(null);
-const changeGarden = ({ id }) => {
-    gardenId.value = id;
-    getExpertByFarmId();
-    getReport();
-};
-
-const expertInfo = ref({});
-const getExpertByFarmId = () => {
-    VE_API.home.getExpertByFarmId({ farmId: gardenId.value }).then(({ data }) => {
-        expertInfo.value = data || {};
-        sessionStorage.setItem("expertId", data.appUserId);
-    });
-};
-
-const showReportPopup = ref(false);
-const getReport = () => {
-    if (!gardenId.value) return;
-    VE_API.farm.growthReportByFarm({ farmId: gardenId.value, limit: 20, isRead: 0 ,generateStatus:1}).then(({ data }) => {
-        if (data && data.length > 0) {
-            showReportPopup.value = true;
-        } else {
-            showReportPopup.value = false;
-        }
-    });
-}
-
-// 监测卡片数据
-const monitorCards = ref({
-    left: {
-        title: "农情采集",
-        content: "精准监测  科学决策",
-        route: "/pest",
+const rows = ref([
+    {
+        label: "农情",
+        cards: [
+            {
+                id: 1,
+                title: "新梢萌动",
+                sub: "预计3天后进入",
+                type: "risk-strong",
+            },
+            {
+                id: 2,
+                title: "冲楸异常",
+                sub: "占比3%",
+                type: "normal",
+                badge: true,
+            },
+            {
+                id: 3,
+                title: "病虫风险",
+                sub: "一级风险",
+                type: "danger",
+            },
+        ],
     },
-    right: [
-        {
-            title: "病虫识别",
-            content: "智能识别  快速诊断",
-            route: "/pest",
-        },
-        // {
-        //     title: "新增客户",
-        //     content: "农情先知  高效管理",
-        //     route: "/create_farm?type=client&isReload=true&from=home",
-        // },
-    ],
-});
-
-// 卡片点击事件
-const handleCardClick = (card) => {
-    const dropdownGardenItem = ref({
-        organId: 766,
-        periodId: 1,
-        name: "荔博园",
-    });
-    if (card.title === "农情采集") {
-        dropdownGardenItem.value.page = "create_farm";
-        wx.miniProgram.navigateTo({
-            url: `/pages/subPages/new_recognize/index?gardenData=${JSON.stringify(dropdownGardenItem.value)}`,
-        });
-    } else if (card.title === "病虫识别") {
-        dropdownGardenItem.value.page = "album_recognize";
-        wx.miniProgram.navigateTo({
-            url: `/pages/subPages/new_recognize/index?gardenData=${JSON.stringify(dropdownGardenItem.value)}`,
-        });
-    } else {
-        router.push(card.route);
-    }
-};
-
-onActivated(() => {
-    getManagerList();
-    // if (userType.value != 2) {
-    //     checkExistsEnabledScheme()
-    // }
-    getBannerList();
-    // 检测是否从创建农场页面成功返回
-    if (route.query.showSuccess === "true") {
-        // 清除URL参数,避免刷新页面时再次显示弹窗
-        router.replace({
-            path: "/home",
-            query: { reload: route.query.reload },
-        });
-    }
-    sessionStorage.removeItem('interactionListScrollTop');
-});
-
-const userType = ref(localStorage.getItem("USER_TYPE"));
-onMounted(() => {
-    if (userType.value != 2) {
-        monitorCards.value.right.push({
-            title: "新增客户",
-            content: "农情先知  高效管理",
-            route: "/create_farm?type=client&isReload=true&from=home",
-        });
-    }
-});
-
-// 查询当前农资店的成员列表(只保留有"任务接单"权限的成员)
-const getManagerList = async () => {
-    const { data } = await VE_API.mine.listManagerList({ onlyExecutor: true });
-    if (data && data.length > 0) {
-        // 过滤 permissionList 中包含"任务接单"的成员,并过滤掉超管(role为1)
-        const executorList = data.filter((item) => item.role !== 1);
-        sessionStorage.setItem("executorList", JSON.stringify(executorList));
-    }
-};
-
-const bannerObj = ref({});
-const getBannerList = () => {
-    const params = {
-        page: 1,
-        limit: 1,
-        topicId: 5,
-    };
-    VE_API.home.warningPageList(params).then(({ data }) => {
-        bannerObj.value = data[0] || {};
-    });
-};
-
-const isExpanded = ref(false);
-const weatherInfoRef = ref(null);
-const weatherExpanded = (isExpandedValue) => {
-    isExpanded.value = isExpandedValue;
-};
-
-// 点击遮罩时收起天气
-const handleMaskClick = () => {
-    if (weatherInfoRef.value && weatherInfoRef.value.toggleExpand) {
-        weatherInfoRef.value.toggleExpand();
-    }
-};
+    {
+        label: "农事",
+        cards: [
+            {
+                id: 4,
+                title: "第一段防治",
+                sub: "待完成",
+                type: "risk-strong",
+            },
+            {
+                id: 5,
+                title: "控梢",
+                sub: "待触发",
+                type: "normal",
+            },
+            {
+                id: 6,
+                title: "无",
+                sub: "",
+                type: "disabled",
+            },
+        ],
+    },
+]);
 
-const handleExpertBannerClick = () => {
-    // router.push("/consult?userId=81881");
-    router.push("/interaction_list?expertMiniUserId=81881");
-};
 
-const handleBannerClick = () => {
-    router.push(`/warning_detail?id=${bannerObj.value.id}`);
+const handleBlockClick = (block) => {
+    // 预留点击跳转/弹窗逻辑
+    console.log("点击卡片:", block);
 };
 </script>
 
 <style scoped lang="scss">
 .home-index {
     width: 100%;
-    height: 100vh;
-    overflow: auto;
-    position: relative;
-    // background: linear-gradient(180deg, #f4f9fd 0%, #f9f9f9 100%);
-    background: linear-gradient(180deg, #F9F9F9 0%, #F0F8FF 31.47%, #F9F9F9 46.81%, #F9F9F9 100%);
+    min-height: 100vh;
+    box-sizing: border-box;
+    padding: 12px 12px 24px;
+    background: #f5f7fa;
+}
 
-    .banner-wrap {
-        width: 100%;
-        height: 200px;
-        position: relative;
-        z-index: 1;
-
-        .banner-img {
-            width: 100%;
-            height: 100%;
-            object-fit: cover;
-        }
+.top-row {
+    display: flex;
+    align-items: center;
+    gap: 8px;
+    margin-bottom: 12px;
+}
 
-        .banner-title {
-            position: absolute;
-            bottom: 0;
-            left: 0;
-            width: 100%;
-            padding: 10px 12px 34px 12px;
-            box-sizing: border-box;
-            background: linear-gradient(180deg,
-                    rgba(102, 102, 102, 0) -64.3%,
-                    rgba(0, 0, 0, 0.0074) -1.43%,
-                    rgba(0, 0, 0, 0.684747) 39.67%,
-                    rgba(0, 0, 0, 0.74) 40.09%,
-                    rgba(0, 0, 0, 0.74) 83.2%);
-            color: #fff;
-            font-weight: bold;
-            backdrop-filter: blur(2px);
-        }
-    }
+.search-bar {
+    flex: 1;
 
-    .weather-mask {
-        position: fixed;
-        top: 0;
-        left: 0;
+    .search-input {
         width: 100%;
-        height: 100%;
-        background-color: rgba(0, 0, 0, 0.52);
-        z-index: 2;
+        height: 32px;
+        border-radius: 16px;
+        border: none;
+        padding: 0 12px;
+        box-sizing: border-box;
+        font-size: 14px;
+        background: #ffffff;
+        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
     }
+}
 
-    .weather-info {
-        width: calc(100% - 20px);
-        position: absolute;
-        // top: calc(200px - 28px);
-        top: 8px;
-        left: 10px;
-        z-index: 3;
+.filter-row {
+    display: flex;
+    gap: 8px;
+
+    .filter-btn {
+        width: 72px;
+        height: 30px;
+        border-radius: 15px;
+        border: none;
+        background: #ffffff;
+        font-size: 13px;
+        color: #4e5969;
+        box-shadow: 0 2px 6px rgba(0, 0, 0, 0.04);
     }
+}
 
-    .expert-home {
-        padding: 90px 10px 10px 10px;
-
-        .expert-banner {
-            position: relative;
-
-            .expert-banner-img {
-                width: 100%;
-            }
-
-            .expert-desc {
-                position: absolute;
-                bottom: 0;
-                left: 0;
-                width: 100%;
-                border-radius: 0 0 8px 8px;
-                padding: 6px 8px;
-                box-sizing: border-box;
-                background: rgba(0, 0, 0, 0.5);
-                color: #fff;
-                backdrop-filter: blur(4px);
+.farm-card {
+    background: #ffffff;
+    border-radius: 8px;
+    padding: 10px 12px;
+    border: 0.5px solid rgba(0, 0, 0, 0.2);
+
+    .farm-header {
+        display: flex;
+        justify-content: space-between;
+        align-items: center;
+        padding-bottom: 10px;
+        border-bottom: 0.5px solid rgba(0, 0, 0, 0.1);
+        margin-bottom: 10px;
+
+        .farm-header-left {
+            .farm-title {
                 display: flex;
                 align-items: center;
-                justify-content: space-between;
+                gap: 10px;
+                font-size: 16px;
+                color: #1D2129;
+                margin-bottom: 4px;
 
-                .expert-desc-icon {
-                    width: 91px;
-                }
-
-                .desc-text {
-                    font-family: "PangMenZhengDao";
-                    font-size: 14px;
-                    color: #fff;
+                .title-tags {
                     display: flex;
                     align-items: center;
-                    justify-content: center;
-                    gap: 6px;
-
-                    .dotted {
-                        width: 5px;
-                        height: 5px;
-                        background: #fff;
-                        border-radius: 50%;
+                    gap: 4px;
+
+                    .title-tag {
+                        font-size: 13px;
+                        padding: 2px 8px;
+                        border-radius: 2px;
+                        background: #E8F3FF;
+                        color: #2199F8;
+                        display: flex;
+                        align-items: center;
+                        gap: 2px;
+
+                        &.tag-danger {
+                            background: rgba(255, 149, 61, 0.2);
+                            color: #FF953D;
+                        }
                     }
                 }
             }
-        }
-    }
 
-    .task-list {
-        padding: 0 10px 10px;
-
-        .task-title {
-            color: #000;
-            margin: 6px 0 14px 0;
-            font-weight: 500;
-            font-size: 16px;
-            line-height: 22px;
-            position: relative;
-            padding-left: 9px;
-
-            &::after {
-                content: "";
-                position: absolute;
-                left: 0;
-                top: 50%;
-                transform: translateY(-50%);
-                width: 3px;
-                height: 15px;
-                background: #2199f8;
-                border-radius: 20px;
+            .farm-subtitle {
+                font-size: 12px;
+                color: rgba(32, 32, 32, 0.4);
             }
         }
 
-        .bottom-tag {
+        .farm-more {
+            font-size: 12px;
+            color: rgba(37, 47, 56, 0.5);
+        }
+    }
+}
+
+.content-grid {
+    display: flex;
+    gap: 8px;
+    .label-column {
+        // display: flex;
+        // flex-direction: column;
+        // justify-content: space-between;
+        padding: 6px 0;
+        padding-right: 4px;
+    
+        .label-cell {
+            width: 28px;
+            height: 64px;
+            border-radius: 8px;
+            background: #f5f5f5;
+            color: #86909c;
+            font-size: 12px;
             display: flex;
-            gap: 4px;
+            align-items: center;
+            justify-content: center;
+            writing-mode: vertical-rl;
+        }
+    }
+}
 
-            .tag-card {
-                flex: 1;
-                border-radius: 6px;
-                padding: 8px 4px;
-                box-sizing: border-box;
-                background: rgba(201, 201, 201, 0.1);
-                border: 0.5px solid transparent;
 
-                .card-content {
-                    display: flex;
-                    flex-direction: column;
-                    align-items: center;
-                    justify-content: center;
-                    text-align: center;
-                    height: 100%;
-
-                    .card-main-text {
-                        font-size: 18px;
-                        line-height: 28px;
-                        font-weight: 400;
-                        color: #1D2129;
-                        margin-bottom: 2px;
-                    }
+.main-grid {
+    flex: 1;
+}
 
-                    .card-sub-text {
-                        font-size: 14px;
-                        line-height: 22px;
-                        color: #4E5969;
-                        display: flex;
-                        align-items: center;
-                        gap: 4px;
-
-                        .card-icon {
-                            display: inline-flex;
-                            align-items: center;
-                            justify-content: center;
-                            width: 12px;
-                            height: 12px;
-                            color: #2199f8;
-                        }
-                    }
-                }
+.row {
+    display: grid;
+    grid-template-columns: repeat(3, 1fr);
+    gap: 6px;
+    margin-bottom: 6px;
+}
 
-                &.active {
-                    background: rgba(33, 153, 248, 0.1);
-                    border-color: #2199f8;
+.status-card {
+    border-radius: 10px;
+    padding: 8px 8px;
+    box-sizing: border-box;
+    background: #ffffff;
+    border: 0.5px solid #e5e6eb;
+
+    .status-title {
+        font-size: 14px;
+        font-weight: 500;
+        display: flex;
+        align-items: center;
+        gap: 4px;
+        margin-bottom: 2px;
+    }
 
-                    .card-content {
-                        .card-main-text {
-                            color: #2199f8;
-                        }
+    .status-sub {
+        font-size: 11px;
+        color: #86909c;
+    }
 
-                        .card-sub-text {
-                            color: #2199f8;
-                        }
-                    }
-                }
-            }
+    &.risk-strong {
+        background: #FF6A6A;
+        border-color: #FF6A6A;
+
+        .status-title,
+        .status-sub {
+            color: #ffffff;
+        }
+    }
+
+    &.danger {
+        background: #ffecec;
+        border-color: #ff8e8e;
+
+        .status-title {
+            color: #ff4d4f;
+        }
+
+        .status-sub {
+            color: #ff7d4d;
+        }
+    }
+
+    &.disabled {
+        background: #f5f5f5;
+        border-color: #e5e6eb;
+
+        .status-title,
+        .status-sub {
+            color: #c0c4cc;
         }
     }
 }
 
-.report-text {
-    font-size: 20px;
+.badge-dot {
+    width: 6px;
+    height: 6px;
+    border-radius: 50%;
+    background: #ff4d4f;
 }
 </style>

+ 0 - 1
supplies

@@ -1 +0,0 @@
-supplies