瀏覽代碼

feat: 菜单和锚点

lxf 2 周之前
父節點
當前提交
04e7872754

+ 16 - 1
package-lock.json

@@ -43,7 +43,8 @@
         "vue3-openlayers": "^0.1.74",
         "vue3-photo-preview": "^0.3.0",
         "vuex": "^4.0.2",
-        "weixin-js-sdk": "^1.6.5"
+        "weixin-js-sdk": "^1.6.5",
+        "yarn": "^1.22.22"
       },
       "devDependencies": {
         "@babel/core": "^7.12.16",
@@ -21449,6 +21450,20 @@
         "node": ">=10"
       }
     },
+    "node_modules/yarn": {
+      "version": "1.22.22",
+      "resolved": "https://registry.npmjs.org/yarn/-/yarn-1.22.22.tgz",
+      "integrity": "sha512-prL3kGtyG7o9Z9Sv8IPfBNrWTDmXB4Qbes8A9rEzt6wkJV8mUvoirjU0Mp3GGAU06Y0XQyA3/2/RQFVuK7MTfg==",
+      "hasInstallScript": true,
+      "license": "BSD-2-Clause",
+      "bin": {
+        "yarn": "bin/yarn.js",
+        "yarnpkg": "bin/yarn.js"
+      },
+      "engines": {
+        "node": ">=4.0.0"
+      }
+    },
     "node_modules/yocto-queue": {
       "version": "0.1.0",
       "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",

+ 2 - 1
package.json

@@ -46,7 +46,8 @@
     "vue3-openlayers": "^0.1.74",
     "vue3-photo-preview": "^0.3.0",
     "vuex": "^4.0.2",
-    "weixin-js-sdk": "^1.6.5"
+    "weixin-js-sdk": "^1.6.5",
+    "yarn": "^1.22.22"
   },
   "devDependencies": {
     "@babel/core": "^7.12.16",

+ 1 - 1
src/App.vue

@@ -33,7 +33,7 @@
               />
           </template>
       </tabbar-item>
-      <tabbar-item replace to="/message">
+      <tabbar-item replace to="/plan">
           <span>农事方案</span>
           <template #icon="props">
               <img

二進制
src/assets/img/gallery/icon-0.png


二進制
src/assets/img/gallery/icon-1.png


二進制
src/assets/img/gallery/icon-10.png


二進制
src/assets/img/gallery/icon-11.png


二進制
src/assets/img/gallery/icon-12.png


二進制
src/assets/img/gallery/icon-2.png


二進制
src/assets/img/gallery/icon-3.png


二進制
src/assets/img/gallery/icon-4.png


二進制
src/assets/img/gallery/icon-5.png


二進制
src/assets/img/gallery/icon-6.png


二進制
src/assets/img/gallery/icon-7.png


二進制
src/assets/img/gallery/icon-8.png


二進制
src/assets/img/gallery/icon-9.png


+ 3 - 3
src/router/globalRoutes.js

@@ -86,10 +86,10 @@ export default [
     },
     // 我的消息
     {
-        path: "/message",
-        name: "Message",
+        path: "/plan",
+        name: "Plan",
         meta: { showTabbar: true },
-        component: () => import("@/views/old_mini/message/index.vue"),
+        component: () => import("@/views/old_mini/plan/index.vue"),
     },
     // 我的消息 详情
     {

+ 4 - 6
src/views/old_mini/home/index.vue

@@ -1,8 +1,7 @@
 <template>
     <div class="home-index" :style="{ height: `calc(100vh - ${tabBarHeight}px)` }">
         <!-- 地图 -->
-        <div class="map-container" id="map-container">
-        </div>
+        <div class="map-container" ref="mapContainer"></div>
         <!-- <home-floating-panel></home-floating-panel> -->
         <!-- <adopt-popup></adopt-popup> -->
     </div>
@@ -10,7 +9,7 @@
 
 <script setup>
 import IndexMap from "./map/index.js";
-import { onMounted, computed } from "vue";
+import { onMounted, computed, ref } from "vue";
 import { useStore } from "vuex";
 import { useRouter } from "vue-router";
 // import homeFloatingPanel from "./components/homeFloatingPanel.vue"
@@ -21,11 +20,10 @@ const router = useRouter();
 const store = useStore();
 const tabBarHeight = computed(() => store.state.home.tabBarHeight);
 
-
 const farmMap = new IndexMap();
-
+const mapContainer = ref(null);
 onMounted(() => {
-    farmMap.initMap("POINT (113.61702297075017 23.584863449735067)", "map-container");
+    farmMap.initMap("POINT (113.61702297075017 23.584863449735067)", mapContainer);
     // eventBus.on('map:clickPoint',mapClickPoint)
     // getGardenList()
 });

+ 483 - 0
src/views/old_mini/plan/index.vue

@@ -0,0 +1,483 @@
+<template>
+    <div class="plan-page">
+        <div class="plan-title">
+            <!-- <el-tabs v-model="activeName" class="demo-tabs">
+                <el-tab-pane label="专家处方" name="1"></el-tab-pane>
+                <el-tab-pane label="我的处方" name="2"></el-tab-pane>
+            </el-tabs> -->
+            <div class="tabs">
+                <div class="tab" :class="{ active: activeTab === 'left' }" @click="setActiveTab('left')">专家处方</div>
+                <div class="tab" :class="{ active: activeTab === 'right' }" @click="setActiveTab('right')">
+                    我的处方
+                    <span class="badge-dot">2</span>
+                </div>
+                <div class="slider" :style="sliderStyle"></div>
+            </div>
+        </div>
+        <div class="plan-content">
+            <div class="filter-wrap">
+                <div class="filter-item type-cascader">
+                    <el-cascader v-model="typeVal" :options="typeOptions"></el-cascader>
+                </div>
+                <div class="filter-item">
+                    <el-select v-model="proviceVal" style="width: 76px">
+                        <el-option
+                            v-for="item in proviceOptions"
+                            :key="item.value"
+                            :label="item.label"
+                            :value="item.value"
+                        />
+                    </el-select>
+                </div>
+                <div class="filter-item">
+                    <el-select v-model="expertVal" placeholder="推荐专家" style="width: 86px">
+                        <el-option
+                            v-for="item in expertOptions"
+                            :key="item.value"
+                            :label="item.label"
+                            :value="item.value"
+                        />
+                    </el-select>
+                </div>
+                <div class="filter-item">
+                    <el-select v-model="filterVal" placeholder="筛选" style="width: 68px">
+                        <el-option
+                            v-for="item in filterOptions"
+                            :key="item.value"
+                            :label="item.label"
+                            :value="item.value"
+                        />
+                    </el-select>
+                </div>
+            </div>
+            <div v-if="activeName === '1'" class="expert-prescription">
+                <div class="plan-menu">
+                    <el-anchor :container="containerRef" direction="vertical" type="default" @click="handleClick">
+                        <el-menu default-active="1" class="el-menu-vertical-demo">
+                            <el-sub-menu index="1">
+                                <template #title>
+                                    <img class="menu-icon" src="@/assets/img/gallery/icon-0.png" alt="">
+                                    <span class="menu-text">秋梢期</span>
+                                </template>
+                                <el-menu-item index="1-1"><el-anchor-link href="#part1" title="巡园农事" /></el-menu-item>
+                                <el-menu-item index="1-2">
+                                    <el-anchor-link href="#part2" title="梢期防虫" />
+                                </el-menu-item>
+                                <el-menu-item index="1-3">
+                                    <el-anchor-link href="#part3" title="梢期营养" />
+                                </el-menu-item>
+                            </el-sub-menu>
+                            <el-sub-menu index="2">
+                                <template #title>
+                                    <img class="menu-icon" src="@/assets/img/gallery/icon-1.png" alt="">
+                                    <span class="menu-text">开花期</span>
+                                </template>
+                                <el-menu-item index="2-1">
+                                    <el-anchor-link href="#part2-1" title="巡园农事" />
+                                </el-menu-item>
+                                <el-menu-item index="2-2">
+                                    <el-anchor-link href="#part2-2" title="摇花吹花" />
+                                </el-menu-item>
+                                <el-menu-item index="2-3">
+                                    <el-anchor-link href="#part2-3" title="花期防治" />
+                                </el-menu-item>
+                            </el-sub-menu>
+                        </el-menu>
+                    </el-anchor>
+                </div>
+                <div class="expert-content" ref="containerRef">
+                    <div id="part1" style="height: 300px; background: rgba(255, 0, 0, 0.02)">part1</div>
+                    <div id="part2" style="height: 300px; background: rgba(0, 255, 0, 0.02); margin-top: 30px">
+                        part2
+                    </div>
+                    <div id="part3" style="height: 300px; background: rgba(0, 0, 255, 0.02); margin-top: 30px">
+                        part3
+                    </div>
+                    <div id="part4" style="height: 300px; background: rgba(0, 0, 255, 0.02); margin-top: 30px">
+                        part4
+                    </div>
+                </div>
+            </div>
+            <div v-if="activeName === '2'" class="my-prescription">我的</div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import { computed, ref } from "vue";
+
+const activeName = ref("1");
+const containerRef = ref(null);
+const handleClick = (e) => {
+    e.preventDefault();
+};
+const activeTab = ref("left");
+// const tabBarHeight = computed(() => store.state.home.tabBarHeight);
+const sliderStyle = computed(() => {
+    // 根据当前激活的选项卡计算滑动条位置
+    const position = activeTab.value === "left" ? "25%" : "75%";
+    return {
+        left: `calc(${position} - 12px)`, // 减去滑动条宽度的一半以实现居中
+    };
+});
+function setActiveTab(tab) {
+    activeTab.value = tab;
+}
+const typeVal = ref([1, 3]);
+
+const typeOptions = ref([
+    {
+        value: 1,
+        label: "荔枝",
+        children: [
+            {
+                value: 2,
+                label: "井岗红糯",
+            },
+            {
+                value: 3,
+                label: "桂味",
+            },
+            {
+                value: 4,
+                label: "妃子笑",
+            },
+            {
+                value: 5,
+                label: "黑叶",
+            },
+        ],
+    },
+    {
+        value: 6,
+        label: "龙眼",
+        children: [
+            {
+                value: 7,
+                label: "龙眼1",
+            },
+            {
+                value: 8,
+                label: "龙眼2",
+            },
+            {
+                value: 9,
+                label: "龙眼3",
+            },
+            {
+                value: 10,
+                label: "龙眼4",
+            },
+        ],
+    },
+    {
+        value: 11,
+        label: "琵琶",
+        children: [
+            {
+                value: 12,
+                label: "琵琶1",
+            },
+            {
+                value: 13,
+                label: "琵琶2",
+            },
+            {
+                value: 14,
+                label: "琵琶3",
+            },
+            {
+                value: 15,
+                label: "琵琶4",
+            },
+        ],
+    },
+]);
+
+const proviceVal = ref("广东");
+const proviceOptions = ref([
+    {
+        value: "广东",
+        label: "广东省",
+    },
+    {
+        value: "广西",
+        label: "广西省",
+    },
+    {
+        value: "福建",
+        label: "福建省",
+    },
+    {
+        value: "海南",
+        label: "海南省",
+    },
+]);
+
+const expertVal = ref("");
+const expertOptions = ref([
+    {
+        value: "1",
+        label: "韦帮稳",
+    },
+    {
+        value: "2",
+        label: "冼继东",
+    },
+    {
+        value: "3",
+        label: "专家3",
+    },
+    {
+        value: "4",
+        label: "专家4",
+    },
+]);
+
+const filterVal = ref("");
+const filterOptions = ref([
+    {
+        value: "1",
+        label: "最新",
+    },
+    {
+        value: "3",
+        label: "好评",
+    },
+]);
+</script>
+
+<style lang="scss" scoped>
+.plan-page {
+    .plan-title {
+        width: 158px;
+        margin: 0 auto;
+        padding: 6px 0;
+        .tabs {
+            display: flex;
+            position: relative;
+            height: 36px;
+            line-height: 36px;
+            .tab {
+                flex: 1;
+                text-align: center;
+                cursor: pointer;
+                color: rgba(0, 0, 0, 0.5);
+                z-index: 2;
+                transition: color 0.3s ease;
+                position: relative;
+                &.active {
+                    color: #000000;
+                    font-weight: bold;
+                }
+                .badge-dot {
+                    position: absolute;
+                    top: 0;
+                    right: -6px;
+                    width: 16px;
+                    height: 16px;
+                    background-color: #ff0000;
+                    border-radius: 50%;
+                    font-size: 12px;
+                    line-height: 16px;
+                    color: #fff;
+                }
+            }
+            .slider {
+                position: absolute;
+                height: 4px;
+                width: 24px;
+                background: #2199f8;
+                border-radius: 16px;
+                bottom: 0;
+                left: calc(25% - 12px); /* 初始位置在第一个选项卡中间 */
+                transition: all 0.3s cubic-bezier(0.645, 0.045, 0.355, 1);
+            }
+        }
+
+        .content {
+            padding: 20px;
+            background: #f8f9fa;
+            border-radius: 8px;
+            min-height: 200px;
+        }
+
+        .content-section {
+            display: none;
+            animation: fadeIn 0.5s ease;
+        }
+
+        .content-section.active {
+            display: block;
+        }
+
+        @keyframes fadeIn {
+            from {
+                opacity: 0;
+                transform: translateY(10px);
+            }
+            to {
+                opacity: 1;
+                transform: translateY(0);
+            }
+        }
+
+        .code-example {
+            margin-top: 30px;
+            background: #2d3748;
+            color: #e2e8f0;
+            padding: 20px;
+            border-radius: 8px;
+            font-family: "Fira Code", monospace;
+            overflow-x: auto;
+        }
+
+        .code-example h3 {
+            color: #81e6d9;
+            margin-bottom: 15px;
+        }
+
+        .explanation {
+            margin-top: 25px;
+            padding: 15px;
+            background: #f1f8ff;
+            border-left: 4px solid #4361ee;
+            border-radius: 4px;
+        }
+    }
+    .plan-content {
+        background: #f5f7fb;
+        .filter-wrap {
+            padding: 10px 0;
+            width: 100%;
+            display: flex;
+            align-items: center;
+            justify-content: space-between;
+            .type-cascader {
+                flex: 1;
+                text-align: center;
+                ::v-deep {
+                    .el-input__inner {
+                        width: 80px;
+                    }
+                }
+            }
+            .filter-item {
+                width: fit-content;
+                ::v-deep {
+                    .el-input__wrapper {
+                        background: none;
+                        box-shadow: none;
+                    }
+                    .el-input__inner {
+                        font-size: 14px;
+                        color: rgba(0, 0, 0, 0.5);
+                    }
+                    .el-select__wrapper {
+                        background: none;
+                        box-shadow: none;
+                        gap: 2px;
+                        padding: 4px 2px;
+                        justify-content: center;
+                    }
+                    .el-select__selection {
+                        flex: none;
+                        width: fit-content;
+                    }
+                    .el-select__placeholder {
+                        color: rgba(0, 0, 0, 0.5);
+                        position: static;
+                        transform: none;
+                        width: fit-content;
+                    }
+                }
+            }
+        }
+    }
+    .expert-prescription {
+        display: flex;
+        width: 100%;
+        height: calc(100vh - 52px - 48px - 50px);
+        .plan-menu {
+            width: 100px;
+            height: 100%;
+            padding: 10px 0;
+            box-sizing: border-box;
+            background: #fff;
+            border-radius: 0 10px 10px 0;
+            .menu-icon {
+                width: 13px;
+            }
+            .menu-text {
+                padding: 0 4px;
+            }
+            ::v-deep {
+                .el-anchor {
+                    height: 100%;
+                    background: none;
+                }
+                .el-anchor__marker {
+                    display: none;
+                }
+                .el-menu {
+                    background: none;
+                    border: none;
+                    .el-sub-menu__title {
+                        background: none;
+                        padding: 0 2px;
+                        justify-content: center;
+                    }
+                    .el-sub-menu__title {
+                        height: 32px;
+                    }
+                    .el-sub-menu .el-sub-menu__icon-arrow {
+                        position: static;
+                        padding-top: 6px;
+                    }
+                    .el-sub-menu {
+                        margin-bottom: 16px;
+                        &.is-opened {
+                            .el-sub-menu__icon-arrow {
+                                padding-bottom: 6px;
+                                padding-top: 0;
+                            }
+                        }
+                        .el-menu-item {
+                            height: 32px;
+                            line-height: 32px;
+                            margin: 4px 8px;
+                            padding: 0 2px;
+                            justify-content: center;
+                            background: none;
+                        }
+                        .el-menu-item.is-active {
+                            background: none;
+                            color: #fff;
+                        }
+                        .el-anchor__item {
+                            width: 100%;
+                            text-align: center;
+                        }
+                        .el-anchor__link {
+                            color: #666666;
+                        }
+                        .el-anchor__link.is-active {
+                            background: linear-gradient(180deg, #70BFFE, #2199F8);
+                            border-radius: 20px;
+                            color: #fff;
+                        }
+                    }
+                }
+                .el-anchor__list {
+                    padding-left: 0;
+                }
+            }
+        }
+        .expert-content {
+            width: calc(100% - 100px);
+            height: calc(100vh - 100px);
+            overflow: auto;
+        }
+    }
+}
+</style>

+ 8 - 8
yarn.lock

@@ -1365,10 +1365,10 @@
     read-package-json-fast "^3.0.0"
     which "^3.0.0"
 
-"@parcel/watcher-darwin-arm64@2.5.1":
+"@parcel/watcher-win32-x64@2.5.1":
   version "2.5.1"
-  resolved "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.5.1.tgz"
-  integrity sha512-eAzPv5osDmZyBhou8PoF4i6RQXAfeKL9tjb3QzYuccXFMQU0ruIc/POh30ePnaOyD1UXdlKguHBmsTs53tVoPw==
+  resolved "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.5.1.tgz"
+  integrity sha512-9lHBdJITeNR++EvSQVUcaZoWupyHfXe1jZvGZ06O/5MflPcuPLtEphScIBL+AiCWBO46tDSHzWyD0uDmmZqsgA==
 
 "@parcel/watcher@^2.4.1":
   version "2.5.1"
@@ -6156,11 +6156,6 @@ fs.realpath@^1.0.0:
   resolved "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz"
   integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8= sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==
 
-fsevents@~2.3.2:
-  version "2.3.3"
-  resolved "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz"
-  integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==
-
 function-bind@^1.1.1, function-bind@^1.1.2:
   version "1.1.2"
   resolved "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz"
@@ -11232,6 +11227,11 @@ yargs@^16.0.0:
     y18n "^5.0.5"
     yargs-parser "^20.2.2"
 
+yarn@^1.22.22:
+  version "1.22.22"
+  resolved "https://registry.npmjs.org/yarn/-/yarn-1.22.22.tgz"
+  integrity sha512-prL3kGtyG7o9Z9Sv8IPfBNrWTDmXB4Qbes8A9rEzt6wkJV8mUvoirjU0Mp3GGAU06Y0XQyA3/2/RQFVuK7MTfg==
+
 yocto-queue@^0.1.0:
   version "0.1.0"
   resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz"