소스 검색

feat:添加品种确权页面

wangsisi 1 개월 전
부모
커밋
f20f691bc3

+ 2 - 1
src/components/fnHeader.vue

@@ -13,6 +13,7 @@
             popper-class="focus-farm-select"
             @change="toggleFarm"
         >
+            <!-- <el-option label="我的关注农场" :value="0" /> -->
             <el-option label="荔博园" :value="1" />
             <el-option label="井冈红糯基地" :value="2" />
         </el-select>
@@ -54,7 +55,7 @@ const props = defineProps({
   }
 })
 
-const farmVal = ref(sessionStorage.getItem('farmId')*1)
+const farmVal = ref(sessionStorage.getItem('farmId')*1 || '')
 const toggleFarm = (val) => {
     sessionStorage.setItem('farmId',farmVal.value)
     router.push({ name: "Home" });

+ 7 - 1
src/router/mainRoutes.js

@@ -24,7 +24,7 @@ export default [
         name: "GardenFile",
         component: () => import("@/views/file/index.vue"),
     },
-    //确权
+    //地块确权页面
     {
         path: "/authentic",
         name: "Authentic",
@@ -48,4 +48,10 @@ export default [
         name: "WorkCompleted",
         component: () => import("@/views/workDetail/completed.vue"),
     },
+    // 品种确权页面
+    {
+        path: "/variety_map",
+        name: "VarietyMap",
+        component: () => import("@/views/varietyMap/index.vue"),
+    },
 ];

+ 8 - 2
src/views/home/components/homePage.vue

@@ -26,7 +26,7 @@
         <div class="box-flex">
           <div class="box-card">
             <div class="box-desc">当前分区无品种信息,请确权</div>
-            <div class="box-button">立即确权</div>
+            <div class="box-button" @click="handlePage">立即确权</div>
           </div>
         </div>
       </chart-box>
@@ -100,7 +100,13 @@ import barChart from "@/components/charts/barChart.vue";
 import oneLineChart from "@/components/charts/oneLineChart.vue";
 import eventBus from "@/api/eventBus";
 import {useStore} from "vuex";
-let store = useStore()
+import { useRouter } from "vue-router";
+const store = useStore()
+const router = useRouter()
+
+const handlePage = () =>{
+  router.push('/variety_map')
+}
 
 //基本指标
 const btnGroup = ["树高","冠幅"]

+ 336 - 0
src/views/varietyMap/index.vue

@@ -0,0 +1,336 @@
+<template>
+    <div class="base-container">
+        <fnHeader :hideSwitch="true" :hideShadow="true" showDate></fnHeader>
+        <div class="content">
+            <div class="content-left">
+                <div class="btn" @click="goBack">
+                    <img src="@/assets/images/common/back-icon.png" alt="" />
+                    返回
+                </div>
+                <chart-box class="left-cont" name="品种列表" color="yellow">
+                    <div class="box">
+                        <div class="add-cont">
+                            <div>暂无数据</div>
+                            <div class="tips-text">请先添加品种,再框选右侧区域,进行品种确权</div>
+                            <div class="button" @click="handleAdd">
+                                <el-icon class="icon"><Plus /></el-icon>
+                                添加品种
+                            </div>
+                        </div>
+                    </div>
+                </chart-box>
+            </div>
+            <div class="content-right">
+                <div class="map-header">
+                    <div class="title">
+                        <img src="@/assets/images/common/area-icon.png" alt="" />
+                        品种确权
+                    </div>
+                </div>
+                <div ref="mapRef" class="map">
+                    <div class="checkbox-list">
+                        <span class="text">全部设置为</span>
+                        <el-checkbox-group class="checkbox" v-model="checkedCities" @change="handleCheckedCitiesChange">
+                            <el-checkbox v-for="city in cities" :key="city" :label="city.label" :value="city.value">
+                                {{ city.label }}
+                            </el-checkbox>
+                        </el-checkbox-group>
+                        <div class="add">
+                            <el-icon class="icon"><Plus /></el-icon>
+                            添加品种
+                        </div>
+                    </div>
+                    <div class="footer-btn">
+                        <div class="cancel">取消</div>
+                        <div>保存</div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+    <!-- 添加品种弹窗 -->
+    <el-dialog
+        v-model="dialogVisible"
+        body-class="custom-dialog"
+        title="添加品种"
+        width="500"
+        align-center
+        :before-close="handleClose"
+    >
+        <el-input class="input" size="large" v-model="input" placeholder="请输入品种名称" />
+        <template #footer>
+            <div class="dialog-footer">
+                <div class="btn" @click="dialogVisible = false">取消</div>
+                <div @click="dialogVisible = false">确定</div>
+            </div>
+        </template>
+    </el-dialog>
+</template>
+
+<script setup>
+import { onMounted, ref } from "vue";
+import { ElMessage } from "element-plus";
+import fnHeader from "@/components/fnHeader.vue";
+import VarietyMap from "./varietyMap";
+import chartBox from "@/components/chartBox.vue";
+import { useRouter, useRoute } from "vue-router";
+import { useStore } from "vuex";
+const store = useStore();
+const varietyMap = new VarietyMap();
+
+const router = useRouter();
+const route = useRoute();
+const mapRef = ref();
+onMounted(() => {
+    getList();
+    varietyMap.initMap("POINT(113.61448114737868 23.585550924763083)", mapRef.value);
+});
+
+const getList = () => {
+    console.log("000");
+};
+
+const checkedCities = ref(["0"]);
+const cities = [
+    {
+        label:"品种1",
+        value:"0"
+    },
+    {
+        label:"品种2",
+        value:"1"
+    }
+];
+const handleCheckedCitiesChange = (value) => {
+};
+
+const goBack = () => {
+    router.go(-1);
+};
+
+//添加品种弹窗
+const dialogVisible = ref(false);
+const input = ref("");
+const handleAdd = () => {
+    dialogVisible.value = true;
+};
+
+const handleClose = () => {
+    dialogVisible.value = false;
+    input.value = "";
+};
+</script>
+
+<style lang="scss" scoped>
+.base-container {
+    width: 100%;
+    height: 100vh;
+    color: #fff;
+    position: relative;
+    box-sizing: border-box;
+    z-index: 1;
+    background: #000;
+
+    .content {
+        width: 100%;
+        height: calc(100% - 74px);
+        display: flex;
+        justify-content: space-between;
+        box-sizing: border-box;
+        padding: 20px;
+        .content-left {
+            width: 473px;
+            height: 100%;
+            box-sizing: border-box;
+            .btn {
+                display: flex;
+                align-items: center;
+                justify-content: center;
+                border: 1px solid rgba(255, 255, 255, 0.78);
+                border-radius: 4px;
+                padding: 9px;
+                margin-bottom: 13px;
+                width: 104px;
+                cursor: pointer;
+                img {
+                    width: 14px;
+                    margin-right: 5px;
+                }
+            }
+            .left-cont {
+                width: 100%;
+                height: calc(100% - 48px - 4px);
+                .box {
+                    width: 100%;
+                    height: calc(100% - 58px);
+                    padding: 16px 12px;
+                    box-sizing: border-box;
+                    overflow-y: auto;
+                    .add-cont {
+                        display: flex;
+                        flex-direction: column;
+                        align-items: center;
+                        font-size: 16px;
+                        .tips-text {
+                            width: 220px;
+                            text-align: center;
+                            color: #9f9f9f;
+                            font-size: 15px;
+                            margin: 8px 0 24px 0;
+                        }
+                        .button {
+                            color: #ffd489;
+                            display: flex;
+                            align-items: center;
+                            border-radius: 8px;
+                            border: 1px solid #ffd489;
+                            padding: 8px 16px;
+                            background: rgba(255, 212, 137, 0.1);
+                            cursor: pointer;
+                            .icon {
+                                margin-right: 4px;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+        .content-right {
+            width: calc(100% - 473px - 18px);
+            margin-left: 18px;
+            height: 100%;
+            background: #191919;
+            border: 0.6px solid #444444;
+            padding: 20px;
+            box-sizing: border-box;
+            border-radius: 8px;
+            .map-header {
+                display: flex;
+                justify-content: space-between;
+                .title {
+                    font-size: 22px;
+                    display: flex;
+                    align-items: flex-end;
+                    font-family: "PangMenZhengDao";
+                    margin-bottom: 16px;
+                    img {
+                        margin-right: 8px;
+                    }
+                }
+            }
+            .map {
+                width: 100%;
+                clip-path: inset(0px round 4px);
+                height: calc(100% - 31px - 16px);
+                position: relative;
+                .checkbox-list{
+                    position: absolute;
+                    z-index: 2;
+                    right: 42px;
+                    bottom: 150px;
+                    background: rgba(0, 0, 0, 0.8);
+                    border-radius: 8px;
+                    display: flex;
+                    flex-direction: column;
+                    padding: 20px;
+                    .text{
+                        color: #9f9f9f;
+                        margin-bottom: 12px;
+                        font-size: 16px;
+                    }
+                    .checkbox{
+                        display: flex;
+                        flex-direction: column;
+                        ::v-deep{
+                            .el-checkbox__label{
+                                color: #fff;
+                                font-size: 16px;
+                            }
+                            .el-checkbox__inner{
+                                width: 18px;
+                                height: 18px;
+                            }
+                            .el-checkbox__input.is-checked .el-checkbox__inner{
+                                background: #FFD489;
+                                border-color: #FFD489;
+                                &::after{
+                                    border-color: #000;
+                                    height: 10px;
+                                    left: 4px;
+                                    width: 5px;
+                                    top: 0;
+                                    border: 2px solid transparent;
+                                }
+                            }
+                        }
+                    }
+                    .add{
+                        margin-top: 12px;
+                        border: 1px solid #fff;
+                        border-radius: 4px;
+                        background: rgba(255, 255, 255, 0.2);
+                        display: flex;
+                        align-items: center;
+                        padding: 8px;
+                        .icon{
+                            margin-right: 4px;
+                        }
+                    }
+                }
+                .footer-btn {
+                    position: absolute;
+                    right: 42px;
+                    bottom: 28px;
+                    z-index: 2;
+                    display: flex;
+                    width: 520px;
+                    div {
+                        text-align: center;
+                        width: calc(100% - 20px - 200px);
+                        font-size: 20px;
+                        color: #1d1d1d;
+                        background: #f7be5a;
+                        border-radius: 8px;
+                        border: 2px solid #fff;
+                        padding: 13px;
+                        cursor: pointer;
+                    }
+                    .cancel {
+                        margin-right: 20px;
+                        width: 200px;
+                        background: rgba(0, 0, 0, 0.6);
+                        color: #fff;
+                    }
+                }
+            }
+        }
+    }
+}
+
+.custom-dialog {
+    .el-dialog__body {
+        margin-top: 10px;
+    }
+    .input {
+        width: 100%;
+    }
+}
+.dialog-footer {
+    display: flex;
+    width: 100%;
+    margin-top: 25px;
+    div {
+        flex: 1;
+        padding: 10px;
+        background: #ffd489;
+        border-radius: 5px;
+        color: #1d1d1d;
+        text-align: center;
+    }
+    .btn {
+        border: 1px solid #9f9f9f;
+        background: #fff;
+        margin-right: 14px;
+    }
+}
+</style>

+ 80 - 0
src/views/varietyMap/varietyMap.js

@@ -0,0 +1,80 @@
+import { getCenter } from 'ol/extent';
+import config from "@/api/config.js";
+import * as KMap from "@/utils/ol-map/KMap";
+import Stroke from "ol/style/Stroke";
+import * as util from "@/common/ol_common.js";
+import VectorSource from 'ol/source/Vector';
+import {Point } from 'ol/geom';
+import Feature from "ol/Feature";
+import Draw from 'ol/interaction/Draw';
+import VectorLayer from 'ol/layer/Vector';
+import { Circle as CircleStyle, Fill, Style } from 'ol/style';
+
+/**
+ * @description
+ */
+class VarietyMap {
+  constructor() {
+    let that = this;
+    let vectorStyle = new KMap.VectorStyle();
+    this.vectorStyle = vectorStyle;
+
+    // 添加矢量图层用于显示框选结果
+    this.vectorLayer = new VectorLayer({
+      source: this.vectorSource,
+      style: new Style({
+        fill: new Fill({
+          color: 'rgba(255, 255, 255, 0.2)',
+        }),
+        stroke: new Stroke({
+          color: '#ffcc33',
+          width: 2,
+        }),
+        image: new CircleStyle({
+          radius: 7,
+          fill: new Fill({
+            color: '#ffcc33',
+          }),
+        }),
+      }),
+    });
+
+  }
+
+  initMap(location, target) {
+    let level = 16;
+    let coordinate = util.wktCastGeom(location).getFirstCoordinate();
+    this.kmap = new KMap.Map( target, level, coordinate[0], coordinate[1], null, 1, 22 ,"vec", true, true);
+    this.kmap.addLayer(this.vectorLayer);
+    // 初始化框选交互
+    // this.draw = new Draw({
+    //   source: this.vectorSource,
+    //   type: 'box', // 框选类型
+    // });
+
+    // // 添加框选交互到地图
+    // this.kmap.addInteraction(this.draw);
+
+    // // 监听drawend事件,获取框选范围
+    // this.draw.on('drawend', (event) => {
+    //   const feature = event.feature;
+    //   const geometry = feature.getGeometry();
+    //   const extent = geometry.getExtent();
+    //   console.log('Selected extent:', extent);
+    //   console.log('Center of selected area:', getCenter(extent));
+    // });
+  }
+
+  // 重新渲染地图
+  updateMap() {
+    setTimeout(() => {
+      this.kmap.map.updateSize()
+    }, 1000);
+  }
+
+  fit(geomOrExtent, padding) {
+    this.kmap.fit(geomOrExtent, padding);
+  }
+}
+
+export default VarietyMap;

+ 5 - 4
src/views/workDetail/components/prescriptionBox.vue

@@ -73,7 +73,8 @@
                     果园照片,自动预测物候期可以确定.
                     <!-- {{ prescriptioData?.expertPrescription }} -->
                 </div>
-                <div class="prescription-item" v-if="prescriptioData?.progress === 0 && ROLETYPE == '3'">
+                <!-- v-if="prescriptioData?.progress === 0 && ROLETYPE == '3'" -->
+                <div class="prescription-item">
                     <div class="recipe-box">
                         <div class="recipe-title">
                             <div class="recipe-name">药物处方</div>
@@ -81,7 +82,7 @@
                                 <el-icon class="icon"><Plus /></el-icon>新增药物
                             </div>
                         </div>
-                        <custom-table type="0" @handleDelete="removeDomain" isEdit :tableHeader="tableHeader" :tableData="dynamicValidateForm.domains"></custom-table>
+                        <custom-table type="0" @handleDelete="removeDomain" :tableHeader="tableHeader" :tableData="dynamicValidateForm.domains"></custom-table>
                         <!-- <div class="recipe-item">
                             <div class="recipe-form">
                                 <el-form
@@ -218,13 +219,13 @@
                         </div> -->
                     </div>
                 </div>
-                <div class="prescription-item">
+                <!-- <div class="prescription-item" v-else>
                     <div class="sub-title">
                         <div class="sub-name">药物处方</div>
                         <div class="sub-name"><span>施用方式:</span>根部施</div>
                     </div>
                     <custom-table type="0" :tableHeader="tableHeader" :tableData="tableData"></custom-table>
-                </div>
+                </div> -->
                 <div class="prescription-item" v-if="prescriptioData?.progress === 0">
                     <div class="sub-title">
                         <div class="sub-line"></div>

+ 1 - 1
src/views/workDetail/components/table.vue

@@ -17,7 +17,7 @@
                     <span v-if="!isEdit">{{ item[ele.props] }}</span>
                     <template v-else>
                         <span v-if="ele.name==='执行方式'">人工</span>
-                        <el-select v-else class="select" v-model="item[ele.props]">
+                        <el-select remote-show-suffix v-else class="select" v-model="item[ele.props]">
                             <el-option v-for="optionItem in item.list" :key="optionItem.name" :label="optionItem.name" :value="optionItem.name" />
                         </el-select>
                     </template>