Explorar o código

fix: 农事方案底部,创建农场

lxf hai 2 semanas
pai
achega
e30252f618

+ 28 - 0
src/api/modules/old_mini_map.js

@@ -0,0 +1,28 @@
+const config = require("../config")
+
+module.exports = {
+    treePoint: {
+        url: config.base_dev_url + "lz_tree/listByPoint",
+        type: "post",
+    },
+    location: {
+        url: "/ws/geocoder/v1",
+        type: "get"
+    },
+    getAltitude: {
+        url: "/v3/elevation/point",
+        type: "get"
+    },
+    search: {
+        url: "/ws/place/v1/suggestion",
+        type: "get"
+    },
+    division: {
+        url: "/ws/district/v1/list",
+        type: "get"
+    },
+    getCtiyList: {
+        url: config.base_dev_url + "poi/city",
+        type: "get",
+    }
+}

BIN=BIN
src/assets/img/home/create-icon.png


BIN=BIN
src/assets/img/home/garden-point.png


BIN=BIN
src/assets/img/home/search.png


+ 42 - 2
src/components/recordItem.vue

@@ -20,7 +20,29 @@
                 巡园提醒:
                 <span class="info-val">{{ recordItemData?.attention }}</span>
             </div>
-            <div class="info-item" v-if="recordItemData?.prescriptionList && recordItemData?.prescriptionList.length">
+            <div class="info-item recipe-name" v-if="onlyRecipeName && recordItemData?.prescriptionList && recordItemData?.prescriptionList.length">
+                <span class="name-text">药物处方:</span>
+                <div class="rescription info-val">
+                        <span
+                            v-for="(
+                                fertilizer, fertilizerI
+                            ) in recordItemData.prescriptionList"
+                            :key="fertilizerI"
+                        >
+                            <span v-for="(pest, pestI) in fertilizer.pesticideFertilizerList" :key="'sub' + pestI">
+                                {{ pest.defaultName }}
+                                <span
+                                    v-if="
+                                        (pestI !== fertilizer.pesticideFertilizerList.length - 1) || (fertilizerI !== recordItemData.prescriptionList.length - 1)
+                                    "
+                                >
+                                    +
+                                </span>
+                            </span>
+                        </span>
+                    </div>
+            </div>
+            <div class="info-item" v-if="!onlyRecipeName && recordItemData?.prescriptionList && recordItemData?.prescriptionList.length">
                 药物处方
                 <div class="info-table">
                     <div class="table">
@@ -48,11 +70,16 @@
                 </div>
             </div>
         </div>
+        <slot name="footer"></slot>
     </div>
 </template>
 
 <script setup>
 const props = defineProps({
+    onlyRecipeName: {
+        type: Boolean,
+        default: false,
+    },
     recordItemData: {
         type: Object,
         default: () => ({}),
@@ -65,7 +92,7 @@ const props = defineProps({
     background: #ffffff;
     border-radius: 8px;
     padding: 12px;
-    margin: 0 12px 12px;
+    margin: 0 10px 10px;
     .record-title {
         font-size: 16px;
         color: #333333;
@@ -79,6 +106,19 @@ const props = defineProps({
                 color: #666666;
             }
         }
+        .recipe-name {
+            display: flex;
+            .name-text {
+                flex: none;
+            }
+            
+            .rescription {
+                max-width: 100%;
+                white-space: nowrap;
+                overflow: hidden;
+                text-overflow: ellipsis;
+            }
+        }
         .info-table {
             margin-top: 8px;
 

+ 6 - 0
src/router/globalRoutes.js

@@ -72,4 +72,10 @@ export default [
         name: "MessageDetail",
         component: () => import("@/views/old_mini/message/detail.vue"),
     },
+    // 创建农场
+    {
+        path: "/create_farm",
+        name: "CreateFarm",
+        component: () => import("@/views/old_mini/create_farm/index.vue"),
+    },
 ];

+ 219 - 0
src/views/old_mini/create_farm/index.vue

@@ -0,0 +1,219 @@
+<template>
+    <div class="create-farm">
+        <custom-header name="创建农场"></custom-header
+        ><!-- 地图 -->
+        <div class="map-container" ref="mapContainer"></div>
+        <div class="farm-content">
+            <div class="farm-filter">
+                <el-select
+                    v-model="locationVal"
+                    filterable
+                    remote
+                    reserve-keyword
+                    placeholder="搜索位置"
+                    :remote-method="remoteMethod"
+                    :loading="loading"
+                    @change="handleSearchRes"
+                    popper-class="location-search-popper"
+                >
+                    <el-option
+                        v-for="(item, index) in locationOptions.list"
+                        :key="index"
+                        :label="item.title"
+                        :value="item.point"
+                    >
+                        <span>{{ item.title }}</span>
+                        <span class="sub-title">{{ item.province }}{{ item.city }}{{ item.district }}</span>
+                    </el-option>
+                </el-select>
+            </div>
+
+            <!-- 创建 -->
+            <div class="create-box">
+                <div class="create-title">
+                    <img class="title-icon" src="@/assets/img/home/create-icon.png" alt="" />
+                    创建农场
+                </div>
+                <div class="create-content">
+                    <div class="create-from">
+
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</template>
+
+<script setup>
+import customHeader from "@/components/customHeader.vue";
+import IndexMap from "./map/index.js";
+import { useRoute } from "vue-router";
+import { onMounted, ref, reactive } from "vue";
+const route = useRoute();
+
+const indexMap = new IndexMap();
+const mapContainer = ref(null);
+onMounted(() => {
+    indexMap.initMap("POINT (113.61702297075017 23.584863449735067)", mapContainer.value);
+});
+
+// 搜索
+const MAP_KEY = "CZLBZ-LJICQ-R4A5J-BN62X-YXCRJ-GNBUT";
+
+const locationVal = ref(null);
+const locationOptions = reactive({
+    list: [],
+});
+const loading = ref(false);
+const remoteMethod = async (keyword) => {
+    if (keyword) {
+        locationOptions.list = [];
+        // setTimeout(() => {
+        loading.value = true;
+        const params = {
+            key: MAP_KEY,
+            keyword,
+            location: route.query.userLocation || "113.61702297075017,23.584863449735067",
+            // region: "广东",
+            // region_fix: 1
+            // filter: 'category<>271013',
+            // filter:'category=261400,111100,160000,220000,261400'
+        };
+        await VE_API.old_mini_map.getCtiyList({ word: keyword }).then(({ data }) => {
+            if (data && data.length) {
+                data.forEach((item) => {
+                    item.point = item.location.lat + "," + item.location.lng;
+                    locationOptions.list.push(item);
+                });
+            }
+        });
+        VE_API.old_mini_map.search(params).then(({ data }) => {
+            loading.value = false;
+            data.forEach((item) => {
+                item.point = item.location.lat + "," + item.location.lng;
+                locationOptions.list.push(item);
+            });
+        });
+        // }, 1000);
+    } else {
+        locationOptions.list = [];
+    }
+};
+
+const handleSearchRes = (v) => {
+    console.log("resssss", v);
+    indexMap.setMapPosition([113.32446, 23.10647])
+};
+</script>
+
+<style lang="scss" scoped>
+.create-farm {
+    position: relative;
+    width: 100%;
+    height: 100vh;
+    overflow: hidden;
+    .map-container {
+        width: 100%;
+        height: 100%;
+    }
+    .farm-content {
+        position: absolute;
+        top: 40px;
+        left: 0;
+        width: 100%;
+        height: calc(100% - 40px);
+        pointer-events: none;
+        z-index: 2;
+    }
+    .farm-filter {
+        pointer-events: all;
+        margin: 12px;
+        position: relative;
+        background: rgba(0, 0, 0, 0.3);
+        border-radius: 20px;
+        border: 1px solid rgba(255, 255, 255, 0.4);
+        &::before {
+            content: "";
+            position: absolute;
+            left: 12px;
+            top: 9px;
+            width: 14px;
+            height: 14px;
+            background: url("@/assets/img/home/search.png") no-repeat center center / 100% 100%;
+        }
+
+        ::v-deep {
+            .el-select__wrapper {
+                background: none;
+                box-shadow: none;
+                padding-left: 34px;
+                font-size: 12px;
+                .el-select__selected-item,
+                .el-select__placeholder,
+                .el-select__input {
+                    color: rgba(255, 255, 255, 0.6);
+                    &.is-transparent {
+                        color: #ccc;
+                        font-size: 12px;
+                    }
+                }
+            }
+            .el-select {
+                transition: all 0.3s;
+                .el-input.is-focus .el-input__wrapper {
+                    box-shadow: none !important;
+                }
+            }
+            .el-input {
+                .el-input__wrapper {
+                    background: none;
+                    box-shadow: none;
+                    padding-left: 18px;
+                    font-size: 11px;
+                    .el-input__inner {
+                        color: rgba(255, 255, 255, 0.6);
+                    }
+                    &.is-focus {
+                        .el-input__inner {
+                            color: #ccc;
+                            font-size: 11px;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    .create-box {
+        position: absolute;
+        bottom: 10px;
+        left: 12px;
+        width: calc(100% - 24px);
+        background: #E0F1FE;
+        border-radius: 14px;
+        .create-title {
+            display: flex;
+            align-items: center;
+            padding: 12px 6px 12px 12px;
+            .title-icon {
+                width: 18px;
+                padding-right: 10px;
+            }
+        }
+    }
+}
+</style>
+
+<style lang="scss">
+.location-search-popper {
+    .el-select-dropdown__list {
+        max-width: 96vw;
+        overflow-x: auto;
+    }
+    .sub-title {
+        padding-left: 6px;
+        font-size: 12px;
+        color: #ccc;
+    }
+}
+</style>

+ 58 - 0
src/views/old_mini/create_farm/map/index.js

@@ -0,0 +1,58 @@
+import * as KMap from "@/utils/ol-map/KMap";
+import * as util from "@/common/ol_common.js";
+import config from "@/api/config.js";
+import Style from "ol/style/Style";
+import Icon from "ol/style/Icon";
+import { Point } from 'ol/geom';
+import Feature from "ol/Feature";
+
+/**
+ * @description 地图层对象
+ */
+class IndexMap {
+  constructor() {
+    let that = this;
+    let vectorStyle = new KMap.VectorStyle();
+    this.vectorStyle = vectorStyle;
+
+    // 位置图标
+    this.clickPointLayer = new KMap.VectorLayer("clickPointLayer", 9999, {
+      style: (f) => {
+        return new Style({
+          image: new Icon({
+            src: require("@/assets/img/home/garden-point.png"),
+            scale: 0.5,
+            anchor: [0.5, 1],
+          }),
+        });
+      },
+    });
+  }
+
+  initMap(location, target) {
+    let level = 16;
+    let coordinate = util.wktCastGeom(location).getFirstCoordinate();
+    this.kmap = new KMap.Map(target, level, coordinate[0], coordinate[1], null, 8, 22);
+    let xyz2 = config.base_img_url3 + "map/lby/{z}/{x}/{y}.png";
+    this.kmap.addXYZLayer(xyz2, { minZoom: 8, maxZoom: 22 }, 2);
+    this.kmap.addLayer(this.clickPointLayer.layer);
+    this.setMapPoint(coordinate)
+  }
+
+  setMapPosition(center) {
+    this.kmap.getView().animate({
+      center,
+      zoom: 16,
+      duration: 500,
+    });
+    this.setMapPoint(center)
+  }
+
+  setMapPoint(coordinate) {
+    this.clickPointLayer.source.clear()
+    let point = new Feature(new Point(coordinate))
+    this.clickPointLayer.addFeature(point)
+  }
+}
+
+export default IndexMap;

+ 83 - 12
src/views/old_mini/home/components/recordTask.vue

@@ -68,15 +68,33 @@
                 <div class="expert-content" ref="containerRef">
                     <div v-for="(section, index) in contentData" :key="index" class="content-section">
                         <div class="section-id" :id="section.targetId"></div>
-                        <record-item :record-item-data="section">
+                        <record-item :record-item-data="section" :onlyRecipeName="true" class="recipe-item">
                             <template #title>
                                 <div class="box-title">
                                     <div class="title-l">
                                         {{ section.title }}
                                         <span class="parent-text">{{ section.parentTitle || "秋梢期" }}</span>
                                     </div>
-                                    <div class="title-btn" @click="addToMyPlan">
-                                        <el-icon color="#fff" size="14"><Plus /></el-icon>
+                                    <div class="title-r">
+                                        <span class="r-dot"></span>
+                                        2区
+                                    </div>
+                                </div>
+                            </template>
+                            <template #footer>
+                                <div class="action-group">
+                                    <div class="action-l">查看详情</div>
+                                    <div class="action-r" v-if="section.orderStatus === 0">
+                                        <div class="action-item second-item">拍照识别</div>
+                                        <div class="action-item primary-item">去确认</div>
+                                    </div>
+                                    <div class="action-r" v-if="section.orderStatus === 1">
+                                        <div class="action-item warning-item">发起需求</div>
+                                        <div class="action-item primary-item">确认完成</div>
+                                    </div>
+                                    <div class="action-r" v-if="section.orderStatus === 2">
+                                        <div class="action-item warning-item">发起需求</div>
+                                        <div class="action-item primary-item">去复核</div>
                                     </div>
                                 </div>
                             </template>
@@ -167,7 +185,7 @@ const contentData = ref([
         parentTitle: "秋梢期",
         reCheckText: "本次农事复核成效优异,作物产量潜力实现大幅增长,虫害风险控制优异,未发现虫害风险",
         expert: 91356,
-        orderStatus: 4,
+        orderStatus: 0,
         activeStatus: 0,
         regionId: 2,
         speciesId: "1",
@@ -209,7 +227,7 @@ const contentData = ref([
         orderId: "745923632567422976",
         area: 2.719998598098755,
         expert: 91356,
-        orderStatus: 4,
+        orderStatus: 1,
         activeStatus: 0,
         farmId: 766,
         regionId: 2,
@@ -379,7 +397,7 @@ const contentData = ref([
         orderId: "745923697054846976",
         area: 2.719998598098755,
         expert: 91356,
-        orderStatus: 4,
+        orderStatus: 2,
         activeStatus: 0,
         farmId: 766,
         regionId: 2,
@@ -620,7 +638,7 @@ const contentData = ref([
         orderId: "745923690209742848",
         area: 2.719998598098755,
         expert: 91356,
-        orderStatus: 4,
+        orderStatus: 3,
         activeStatus: 0,
         farmId: 766,
         regionId: 2,
@@ -1184,8 +1202,9 @@ const contentData = ref([
     .task-content {
         display: flex;
         padding-top: 10px;
+        height: calc(100% - 140px);
         .plan-menu {
-            width: 100px;
+            width: 90px;
             height: 100%;
             padding: 10px 0;
             box-sizing: border-box;
@@ -1260,10 +1279,10 @@ const contentData = ref([
             }
         }
         .expert-content {
-            width: calc(100% - 100px);
+            width: calc(100% - 90px);
             height: 100%;
             overflow: auto;
-            padding-bottom: 80px;
+            padding-bottom: 10px;
             box-sizing: border-box;
             .content-section {
                 position: relative;
@@ -1274,14 +1293,15 @@ const contentData = ref([
                     width: 100%;
                     height: 1px;
                 }
+                .recipe-item {
+                    margin-right: 0;
+                }
             }
             .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;
@@ -1304,6 +1324,57 @@ const contentData = ref([
                     align-items: center;
                     justify-content: center;
                 }
+                .title-r {
+                    display: flex;
+                    align-items: center;
+                    color: #FF8A2A;
+                    font-size: 12px;
+                    .r-dot {
+                        width: 6px;
+                        height: 6px;
+                        border-radius: 50%;
+                        background: #FF8A2A;
+                        margin-right: 5px;
+                    }
+                }
+            }
+
+            .action-group {
+                display: flex;
+                align-items: center;
+                justify-content: space-between;
+                padding-top: 8px;
+                margin-top: 8px;
+                border-top: 1px solid #F5F5F5;
+                .action-l {
+                    font-size: 12px;
+                }
+                .action-r {
+                    display: flex;
+                    align-items: center;
+                    .action-item {
+                        padding: 0 11px;
+                        height: 30px;
+                        line-height: 30px;
+                        border-radius: 14px;
+                        font-size: 12px;
+                        &.second-item {
+                            border: 1px solid #2199F8;
+                            color: #2199F8;
+                        }
+                        &.primary-item {
+                            background: #2199F8;
+                            color: #fff;
+                        }
+                        &.warning-item {
+                            background: rgba(255, 131, 29, 0.1);
+                            color: #FF831D;
+                        }
+                    }
+                    .action-item + .action-item {
+                        margin-left: 5px;
+                    }
+                }
             }
         }
     }

+ 7 - 1
src/views/old_mini/home/index.vue

@@ -3,7 +3,7 @@
         <!-- 地图 -->
         <div class="map-container" ref="mapContainer"></div>
         <!-- 按钮 -->
-         <div class="add-button">
+         <div class="add-button" @click="toSubPage">
             <el-icon class="add-button-icon"><CircleCloseFilled /></el-icon>
             <span>创建我的农场</span>
          </div>
@@ -47,6 +47,12 @@ const heightChange = (height) => {
         zIndex.value = 3
     }
 }
+
+function toSubPage() {
+    router.push({
+        path: "/create_farm",
+    });
+}
 </script>
 
 <style lang="scss" scoped>

+ 5 - 0
vue.config.js

@@ -38,6 +38,11 @@ module.exports = {
                 target: 'https://apis.map.qq.com',
                 changeOrigin: true,
                 ws: false,
+            },
+            '/v3/elevation': {
+                target: 'https://restapi.amap.com',
+                changeOrigin: true,
+                ws: false,
             }
         },
         //这里的ip和端口是前端项目的;下面为需要跨域访问后端项目