Browse Source

feat:添加农事方案页面

wangsisi 1 day ago
parent
commit
44bc4b77f7

+ 22 - 6
src/components/pageComponents/PlanList.vue

@@ -23,7 +23,7 @@
             </el-anchor>
         </div>
         <div class="expert-content" ref="containerRef">
-            <slot>
+            <slot :menuData="menuData">
                 <div v-for="(section, index) in menuData" :key="index" class="content-section">
                     <div
                         class="section-item"
@@ -36,7 +36,6 @@
                                 <div class="box-title">
                                     <div class="title-l">
                                         {{ sub.farmWorkDetail?.name }}
-                                        1111
                                         <span class="parent-text">{{ section.name }}</span>
                                     </div>
                                 </div>
@@ -50,13 +49,17 @@
 </template>
 
 <script setup>
-import { ref } from "vue";
+import { ref, onMounted } from "vue";
 import recordItem from "@/components/recordItem.vue";
 
 const props = defineProps({
-    menuData: {
-        type: Array,
-        default: () => [],
+    farmId: {
+        type: [Number, String],
+        required: true,
+    },
+    containerId: {
+        type: [Number, String],
+        default: 2,
     },
     defaultActive: {
         type: String,
@@ -64,8 +67,21 @@ const props = defineProps({
     },
 });
 
+const menuData = ref([]);
 const containerRef = ref(null);
 
+function getPlanWorkList() {
+    VE_API.home
+        .getPhenologyFarmWorkList({ farmId: props.farmId, containerId: props.containerId })
+        .then(({ data }) => {
+            menuData.value = data;
+        });
+}
+
+onMounted(() => {
+    getPlanWorkList();
+});
+
 const handleClick = (e) => {
     e.preventDefault();
 };

+ 6 - 0
src/router/globalRoutes.js

@@ -308,4 +308,10 @@ export default [
         name: "FarmDetails",
         component: () => import("@/views/old_mini/user/farmDetails.vue"),
     },
+    // 编辑农事方案
+    {
+        path: "/edit_plan",
+        name: "EditPlan",
+        component: () => import("@/views/old_mini/plan/editPlan.vue"),
+    },
 ];

+ 25 - 8
src/views/old_mini/mine/index.vue

@@ -14,10 +14,15 @@
                     </div>
                     <div class="user-day">这是您使用飞鸟有味的第15天</div>
                 </div>
+                
             </div>
             <div class="code-icon" v-if="curRole === 1">
                 <img src="@/assets/img/mine/code-icon.png" alt="" />
             </div>
+            <div class="switch-role-btn" v-if="curRole === 2">
+                <span>切换身份</span>
+                <el-icon><Switch /></el-icon>
+            </div>
         </div>
         <div class="mine-content">
             <div class="garden-info" v-if="curRole !== 0">
@@ -51,7 +56,7 @@ import { useRouter } from "vue-router";
 const router = useRouter();
 
 // 0: 农户, 1: 专家, 2:农资农服
-const curRole = ref(2)
+const curRole = ref(2);
 
 // 网格项数据
 const gridItems = ref([]);
@@ -133,9 +138,13 @@ const cellItems = computed(() => {
         ];
     } else {
         return [
-        {
+            {
+                title: "我的消息",
+                path: "/message_list",
+            },
+            {
                 title: "农事方案",
-                path: "/service_records",
+                path: "/agricultural_plan",
             },
             {
                 title: "服务记录",
@@ -149,10 +158,6 @@ const cellItems = computed(() => {
                 title: "服务维护",
                 path: "/service_manage?identity=NZ&role=2",
             },
-            {
-                title: "退出登录",
-                path: "/logout",
-            },
         ];
     }
 });
@@ -198,7 +203,7 @@ const handleCellClick = (item) => {
         justify-content: space-between;
         .user-info-box {
             display: flex;
-            align-items: center;
+            align-items: center;     
             .avatar {
                 border: 1px solid #fff;
                 margin-right: 12px;
@@ -230,6 +235,18 @@ const handleCellClick = (item) => {
                 height: 100%;
             }
         }
+        .switch-role-btn{
+            margin-right: -16px;
+            display: flex;
+            align-items: center;
+            justify-content: center;
+            padding: 5px 10px 6px 12px;
+            color: #fff;
+            background: #2199F8;
+            border-radius: 25px 0 0 25px;
+            gap: 5px;
+            font-size: 13px;
+        }
     }
     .mine-content {
         margin-top: 20px;

+ 25 - 4
src/views/old_mini/modify_work/index.vue

@@ -1,8 +1,8 @@
 <template>
     <div class="new-farming-page">
-        <custom-header :name="isAdd ? '新增农事' : '农事详情'"></custom-header>
+        <custom-header :name="isAdd ? '新增农事' : isEdit ? '编辑报价' : '农事详情'"></custom-header>
         <div class="new-farming-content">
-            <div v-if="!isAdd">
+            <div v-if="!isAdd && !isEdit">
                 <div class="step-wrap">
                     <farm-steps :currentStep="0" />
                 </div>
@@ -361,7 +361,12 @@
                         </div>
                     </div>
                 </div>
-                <div class="submit-btn" v-if="!isAdd">
+
+                <div class="submit-btn" v-if="isEdit">
+                    <div class="btn second" @click.prevent="cancelEdit">取消编辑</div>
+                    <div class="btn" @click.prevent="submitForm(formRef)">保存报价</div>
+                </div>
+                <div class="submit-btn" v-if="!isAdd && !isEdit">
                     <div class="btn second">忽略</div>
                     <div class="btn" @click.prevent="submitForm(formRef)">下发农事</div>
                 </div>
@@ -380,7 +385,7 @@
 <script setup>
 import { onActivated, ref, reactive, onDeactivated, computed, onMounted } from "vue";
 import { useRouter, useRoute } from "vue-router";
-import { ElMessage } from "element-plus";
+import { ElMessage ,ElMessageBox} from "element-plus";
 import customHeader from "@/components/customHeader.vue";
 import NewFarmMap from "./newFarmMap";
 import { useStore } from "vuex";
@@ -397,7 +402,9 @@ const curRole = 0
 const gardenId = ref(null);
 const actionType = ref([]);
 const isAdd = ref(false)
+const isEdit = ref(false)
 isAdd.value = route.query.isAdd ? true : false
+isEdit.value = route.query.isEdit ? true : false
 onMounted(() => {
     window.scrollTo(0, 0);
     getFarmWorkNameList();
@@ -446,6 +453,20 @@ const resetForm = (formEl) => {
     regionId.value = null;
 };
 
+const cancelEdit = () => {
+    ElMessageBox.confirm("确认要取消编辑吗?", "提示", {
+        confirmButtonText: "确认",
+        cancelButtonText: "取消",
+        type: "warning",
+    })
+        .then(() => {
+            router.back();
+        })
+        .catch(() => {
+            console.log("取消编辑");
+        });
+};
+
 // 表单
 const formRef = ref();
 const dynamicValidateForm = reactive({

+ 147 - 0
src/views/old_mini/plan/editPlan.vue

@@ -0,0 +1,147 @@
+<template>
+    <div class="edit-plan">
+        <custom-header name="查看详情"></custom-header>
+        <div class="edit-plan-content">
+            <record-item :record-item-data="contentData" title-mode="default" class="recipe-item" />
+            <prescription-table> </prescription-table>
+        </div>
+        <div class="custom-bottom-fixed-btns">
+            <div class="bottom-btn secondary-btn" @click="deletePrescription">删除处方</div>
+            <div class="bottom-btn primary-btn" @click="editPrice">编辑报价</div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import customHeader from "@/components/customHeader.vue";
+import recordItem from "@/components/recordItem.vue";
+import prescriptionTable from "@/views/old_mini/agri_work/components/prescriptionTable.vue";
+import { ref } from "vue";
+import { ElMessageBox } from "element-plus";
+import { useRouter } from "vue-router";
+
+const router = useRouter();
+const deletePrescription = () => {
+    ElMessageBox.confirm("确认要删除该处方吗?", "提示", {
+        confirmButtonText: "确认",
+        cancelButtonText: "取消",
+        type: "warning",
+    })
+        .then(() => {
+            console.log("删除成功");
+        })
+        .catch(() => {
+            console.log("取消删除");
+        });
+};
+const editPrice = () => {
+    router.push({
+        path: "/modify_work",
+        query: { data: JSON.stringify(["生长异常"]), gardenId: 766, isEdit: true },
+    });
+};
+
+const contentData = ref({
+    title: "巡园农事",
+    parentTitle: "秋梢期",
+    reCheckText: "通过精准农业技术的应用,作物产量实现了两位数的增长,病虫害的发生率大幅下降,土壤肥力的提升",
+    beforeImage: "https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png",
+    afterImage: "https://cube.elemecdn.com/0/88/03b0d39583f48206768a7534e55bcpng.png",
+    expert: 91356,
+    orderStatus: 3,
+    activeStatus: 0,
+    regionId: 2,
+    speciesId: "1",
+    speciesName: "荔枝",
+    farmWorkId: "699343457474318336",
+    farmWorkLibId: "699343457474318336",
+    farmWorkLibName: "梢期防虫",
+    farmWorkName: "梢期防虫",
+    expertIcon:
+        "https://birdseye-img.sysuimars.com/birdseye-look-vue/%E5%BE%AE%E4%BF%A1%E5%9B%BE%E7%89%87_20250411150343.png",
+    expertName: "韦帮稳",
+    attention: "daskdjakjd",
+    beforeExecuteDate: "2025-08-01",
+    executeDate: "2025-08-15",
+    code: "BZ-BC-04-SQFC-20",
+    expertPrescription: "",
+    condition: "单树嫩叶率大于20.0%",
+    defaultFarmWork: 0,
+    farmWorkType: 3,
+    farmWorkTypeName: "病虫",
+    usageMode: "叶面施",
+    serviceMain: "广州泽秾丰农资有限公司",
+    updateDate6: null,
+    confirmPicture: [],
+    executeMain: "广州泽秾丰农资有限公司",
+    storeShortName: "泽秾丰",
+    serviceRegion: "广州市从化区荔枝博览园",
+    prescriptionList: [
+        {
+            name: "营养",
+            pesticideFertilizerList: [
+                {
+                    defaultDroneRatio: null,
+                    defaultName: "尿素",
+                    defaultRatio: 0,
+                    id: null,
+                    muPrice: null,
+                    muUsage: 15000.0,
+                    muUsage2: 15000.0,
+                    ratio: 0,
+                    ratio2: 0,
+                    remark: "",
+                    usageMode: "",
+                    usageModeList: ["叶面施、根部施"],
+                    orderId: null,
+                    pesticideFertilizerCode: "1001",
+                    pesticideFertilizerId: "1",
+                    pesticideFertilizerName: "尿素",
+                    brand: "山东联盟",
+                    typeName: "营养",
+                    price: 132,
+                    unit: "g",
+                    executeStyle: null,
+                },
+                {
+                    defaultDroneRatio: null,
+                    defaultName: "15-15-15复合肥",
+                    defaultRatio: 0,
+                    id: null,
+                    muPrice: null,
+                    muUsage: 45000.0,
+                    muUsage2: 45000.0,
+                    ratio: 0,
+                    ratio2: 0,
+                    remark: "",
+                    usageMode: "",
+                    usageModeList: ["根部施"],
+                    orderId: null,
+                    pesticideFertilizerCode: "1002",
+                    pesticideFertilizerId: "2",
+                    pesticideFertilizerName: "15-15-15复合肥",
+                    brand: "金正大",
+                    typeName: "营养",
+                    price: 220,
+                    unit: "g",
+                    executeStyle: null,
+                },
+            ],
+        },
+    ],
+});
+</script>
+
+<style scoped lang="scss">
+.edit-plan {
+    width: 100%;
+    height: 100vh;
+    background: #f2f3f5;
+    .edit-plan-content {
+        padding: 12px;
+        .record-item {
+            margin: 0;
+        }
+    }
+}
+</style>

+ 40 - 161
src/views/old_mini/plan/index.vue

@@ -2,30 +2,8 @@
     <div class="farm-card-page">
         <custom-header name="农事方案"></custom-header>
         <div class="farm-card-content">
-            <div class="expert-prescription">
-                <div class="plan-menu">
-                    <el-anchor :container="containerRef" direction="vertical" type="default" @click="handleClick">
-                        <el-menu :default-active="defaultActive" class="el-menu-vertical-demo">
-                            <el-sub-menu v-for="(menu, index) in menuData" :key="index" :index="String(menu.id)">
-                                <template #title>
-                                    <img class="menu-icon" :src="require(`@/assets/img/gallery/icon-${index}.png`)" />
-                                    <span class="menu-text">{{ menu.name }}</span>
-                                </template>
-                                <el-menu-item
-                                    v-for="item in menu.farmWorkArrangeList"
-                                    :key="item.id"
-                                    :index="`${menu.id}-${item.id}`"
-                                >
-                                    <el-anchor-link
-                                        :href="'#' + menu.name + item.farmWorkDetail?.name"
-                                        :title="item.farmWorkDetail?.name || '摇花落花'"
-                                    />
-                                </el-menu-item>
-                            </el-sub-menu>
-                        </el-menu>
-                    </el-anchor>
-                </div>
-                <div class="expert-content" ref="containerRef">
+            <PlanList :farm-id="93301" :container-id="route.query.containerId || 2" :default-active="defaultActive">
+                <template #default="{ menuData }">
                     <div v-for="(section, index) in menuData" :key="index" class="content-section">
                         <div
                             class="section-item"
@@ -33,51 +11,45 @@
                             :key="index + '-' + subI"
                         >
                             <div class="section-id" :id="section.name + sub.farmWorkDetail?.name"></div>
-                            <record-item :record-item-data="sub">
+                            <record-item :record-item-data="sub" @click="handleClick(sub)">
                                 <template #title>
                                     <div class="box-title">
                                         <div class="title-l">
                                             {{ sub.farmWorkDetail?.name }}
                                             <span class="parent-text">{{ section.name }}</span>
                                         </div>
+                                        <div class="title-r" v-if="curRole === 2">
+                                            <el-icon color="#2199F8" size="16"><Edit /></el-icon>
+                                        </div>
                                     </div>
                                 </template>
                             </record-item>
                         </div>
                     </div>
-                </div>
-            </div>
+                </template>
+            </PlanList>
         </div>
     </div>
 </template>
 
 <script setup>
 import customHeader from "@/components/customHeader.vue";
-import { ref, onMounted } from "vue";
-import { useRoute } from "vue-router";
+import { ref } from "vue";
+import { useRoute, useRouter } from "vue-router";
 import recordItem from "@/components/recordItem.vue";
+import PlanList from "@/components/pageComponents/PlanList.vue";
 
+const curRole = ref(localStorage.getItem("curRole") || 0);
 const route = useRoute();
-const containerRef = ref(null);
-const handleClick = (e) => {
-    e.preventDefault();
-};
+const router = useRouter();
 // 菜单
 const defaultActive = ref("1-1");
 
-const menuData = ref([]);
-
-function getWorkList() {
-    VE_API.home
-        .getPhenologyFarmWorkList({ farmId: 93301, containerId: route.query.containerId || 2 })
-        .then(({ data }) => {
-            menuData.value = data;
-        });
-}
-
-onMounted(() => {
-    getWorkList();
-});
+const handleClick = (sub) => {
+    if (curRole.value === 2) {
+        router.push(`/edit_plan?id=${sub.id}`);
+    }
+};
 </script>
 
 <style scoped lang="scss">
@@ -87,125 +59,32 @@ onMounted(() => {
     background: #f5f7fb;
     .farm-card-content {
         width: 100%;
-        height: 100%;
-        .expert-prescription {
-            display: flex;
-            width: 100%;
-            height: calc(100vh - 40px);
-            padding-top: 10px;
+        height: calc(100vh - 40px);
+        padding-top: 10px;
+        ::v-deep .expert-prescription {
+            height: 100%;
             .plan-menu {
-                width: 100px;
-                height: 100%;
-                overflow: auto;
                 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: rgba(33, 153, 248, 0.1);
-                                border-radius: 20px;
-                                color: #2199f8;
-                                border: 1px solid #2199f8;
-                            }
-                        }
-                    }
-                    .el-anchor__list {
-                        padding-left: 0;
-                    }
-                }
             }
-            .expert-content {
-                width: calc(100% - 100px);
-                height: 100%;
-                overflow: auto;
-                box-sizing: border-box;
-                .content-section {
-                    position: relative;
-                    .section-item {
-                        position: relative;
-                    }
-                    .section-id {
-                        position: absolute;
-                        // top: -6px;
-                        top: 0;
-                        width: 100%;
-                        height: 1px;
-                    }
-                }
-                .box-title {
-                    display: flex;
-                    align-items: center;
-                    padding-bottom: 8px;
-                    border-bottom: 1px solid #f5f5f5;
-                    margin-bottom: 8px;
-                    .title-l {
-                        font-size: 16px;
-                        font-weight: 600;
-                        color: #000;
-                        .parent-text {
-                            margin-left: 5px;
-                            font-size: 12px;
-                            font-weight: normal;
-                            padding: 4px 6px;
-                            border-radius: 14px;
-                            background: rgba(119, 119, 119, 0.1);
-                        }
+            .box-title {
+                display: flex;
+                align-items: center;
+                justify-content: space-between;
+                padding-bottom: 8px;
+                border-bottom: 1px solid #f5f5f5;
+                margin-bottom: 8px;
+                .title-l {
+                    font-size: 16px;
+                    font-weight: 600;
+                    color: #000;
+                    .parent-text {
+                        margin-left: 5px;
+                        font-size: 12px;
+                        font-weight: normal;
+                        padding: 4px 6px;
+                        border-radius: 14px;
+                        background: rgba(119, 119, 119, 0.1);
                     }
                 }
             }

+ 2 - 16
src/views/old_mini/user/farmDetails.vue

@@ -82,7 +82,7 @@
                         <template #right>
                             <span>查看更多</span>
                         </template>
-                        <plan-list :menu-data="planMenuData" class="plan-list-wrapper" />
+                        <plan-list :farm-id="93301" :container-id="route.query.containerId || 2" class="plan-list-wrapper" />
                     </common-box>
                 </tab>
             </tabs>
@@ -95,7 +95,7 @@
 </template>
 
 <script setup>
-import { ref, onMounted } from "vue";
+import { ref } from "vue";
 import { useRoute } from "vue-router";
 import { Tab, Tabs } from "vant";
 import customHeader from "@/components/customHeader.vue";
@@ -109,20 +109,6 @@ import PlanList from "@/components/pageComponents/PlanList.vue";
 const route = useRoute();
 const activeTab = ref(0);
 
-const planMenuData = ref([]);
-
-function getPlanWorkList() {
-    VE_API.home
-        .getPhenologyFarmWorkList({ farmId: 93301, containerId: route.query.containerId || 2 })
-        .then(({ data }) => {
-            planMenuData.value = data;
-        });
-}
-
-onMounted(() => {
-    getPlanWorkList();
-});
-
 const farmServiceTabs = ["过往服务", "未来服务"];
 const farmServiceActiveTab = ref(0);