Browse Source

fix: 果园档案页面

lxf 5 months ago
parent
commit
a787d7fe7d

+ 163 - 0
src/components/fileBar.vue

@@ -0,0 +1,163 @@
+<template>
+  <div class="file-chart">
+    <div v-for="(item, index) in fileData" :key="index" class="item-container">
+      <div class="file-label">{{ item.name }}</div>
+      <div class="file-bar">
+        <div
+          v-for="(value, subIndex) in item.data"
+          :key="subIndex"
+          class="bar-block"
+          :style="{ width: computedWidths[index][subIndex] + 'px' }"
+        >
+          <div class="block-bg" :class="'bg-' + value.level">
+            <el-tooltip
+              class="tooltip-item"
+              effect="light"
+              :content="value.tag"
+              placement="top"
+            >
+              <div class="cursor-pointer">{{ value.tag }}</div>
+            </el-tooltip>
+          </div>
+        </div>
+      </div>
+    </div>
+    <slot></slot>
+  </div>
+</template>
+
+<script setup>
+import { onMounted, ref, computed } from "vue";
+const fileData = ref([
+  {
+    name: "高产级",
+    data: [
+      { value: 325, level: 4, tag: "325棵" },
+      { value: 325, level: 3, tag: "325棵" },
+      { value: 325, level: 2, tag: "325棵" },
+      { value: 325, level: 1, tag: "325棵" },
+    ],
+  },
+  {
+    name: "稳产级",
+    data: [
+      { value: 260, level: 4, tag: "260棵" },
+      { value: 270, level: 3, tag: "270棵" },
+      { value: 270, level: 2, tag: "270棵" },
+      { value: 270, level: 1, tag: "270棵" },
+    ],
+  },
+  {
+    name: "休养-幼树",
+    data: [
+      { value: 380, level: 0, tag: "新嫁接1年 380棵" },
+      { value: 330, level: 0, tag: "2年 330棵" },
+      { value: 200, level: 0, tag: "3年 200棵" },
+    ],
+  },
+  {
+    name: "休养-病虫",
+    data: [
+      { value: 380, level: 3, tag: "蒂蛀虫 380棵" },
+      { value: 380, level: 1, tag: "其他病 380棵" },
+    ],
+  },
+  {
+    name: "休养-生长",
+    data: [
+      { value: 400, level: 2, tag: "花芽 400棵" },
+      { value: 380, level: 2, tag: "花穗 380棵" },
+      { value: 420, level: 2, tag: "小果 420棵" },
+    ],
+  },
+]);
+// 计算所有 data 中 value 属性的总和最大值
+const maxSum = computed(() => {
+  return Math.max(
+    ...fileData.value.map((item) =>
+      item.data.reduce((sum, dataPoint) => sum + dataPoint.value, 0)
+    )
+  );
+});
+
+// 计算每个 dataPoint 的值在所有 data 中 value 总和最大值中所占的百分比
+const computedWidths = computed(() => {
+  const max = maxSum.value;
+  return fileData.value.map((item) => {
+    // 258是右侧容器总宽度
+    return item.data.map((dataPoint) =>
+      ((dataPoint.value / max) * 240).toFixed(0)
+    ); // 保留两位小数
+  });
+});
+</script>
+
+<style lang="scss" scoped>
+.file-chart {
+  padding: 0 6px;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+  align-items: center;
+  justify-content: center;
+  position: relative;
+  .item-container {
+    display: flex;
+    width: 100%;
+    color: #ffffff;
+    margin-bottom: 12px;
+    .file-label {
+      width: 60px;
+      text-align: right;
+      font-size: 12px;
+    }
+    .file-bar {
+      width: calc(100% - 56px);
+      display: flex;
+      padding-left: 6px;
+      height: 18px;
+      font-size: 10px;
+      div {
+        white-space: nowrap;
+        overflow: hidden;
+        text-overflow: ellipsis;
+      }
+      .bar-block {
+        text-align: center;
+        border-radius: 0px 4px 4px 0px;
+        padding: 1px;
+        background-image: linear-gradient(
+          to right,
+          rgba(255, 223, 223, 0),
+          rgba(234, 232, 232, 1)
+        );
+        .block-bg {
+          padding-left: 2px;
+          border-radius: 0px 4px 4px 0px;
+          box-sizing: border-box;
+          width: 100%;
+          height: 100%;
+          white-space: nowrap;
+          overflow: hidden;
+          text-overflow: ellipsis;
+        }
+      }
+      .bg-0 {
+        background-image: linear-gradient(to right, #042921, #0cba93);
+      }
+      .bg-1 {
+        background: linear-gradient( 90deg, #2E2424 0%, #F86A01 100%);
+      }
+      .bg-2 {
+        background: linear-gradient( 90deg, #2E2424 0%, #F29501 100%);
+      }
+      .bg-3 {
+        background: linear-gradient( 90deg, #2E2424 0%, #E33C3C 100%);
+      }
+      .bg-4 {
+        background: linear-gradient( 270deg, #665E55 0%, #232323 100%);
+      }
+    }
+  }
+}
+</style>

+ 5 - 0
src/router/mainRoutes.js

@@ -13,6 +13,11 @@ export default [
         component: () => import("@/views/home/index.vue"),
     },
     {
+        path: "/garden-file",
+        name: "GardenFile",
+        component: () => import("@/views/file/index.vue"),
+    },
+    {
         path: "/regionalInformation",
         name: "RegionalInformation",
         component: () => import("@/views/regionalInformation/index.vue"),

+ 28 - 0
src/views/file/fileMap.js

@@ -0,0 +1,28 @@
+import config from "@/api/config.js";
+import * as KMap from "@/utils/ol-map/KMap";
+import * as util from "@/common/ol_common.js";
+import Point from "ol/geom/Point.js";
+import Feature from "ol/Feature";
+import VectorLayer from "ol/layer/Vector.js";
+import WKT from "ol/format/WKT.js";
+import ScaleLine from "ol/control/ScaleLine";
+import { useRouter } from "vue-router";
+
+/**
+ * @description 地图层对象
+ */
+class FileMap {
+  constructor() {
+    let that = this;
+    let vectorStyle = new KMap.VectorStyle();
+    this.vectorStyle = vectorStyle;
+  }
+
+  initMap(location, target) {
+    let level = 16;
+    let coordinate = util.wktCastGeom(location).getFirstCoordinate();
+    this.kmap = new KMap.Map(target, level, coordinate[0], coordinate[1], null, 6, 22);
+  }
+}
+
+export default FileMap;

+ 294 - 0
src/views/file/index.vue

@@ -0,0 +1,294 @@
+<template>
+  <div class="base-container no-events">
+    <fnHeader></fnHeader>
+    <div class="content">
+      <!-- <div class="top"></div> -->
+      <div class="left yes-events">
+        <div class="chart-list">
+          <div class="chart-item">
+            <chart-box name="地形风险" arrow="left">
+              <template #title-right>
+                <div>
+                  <el-select
+                    v-model="topographicValue"
+                    placeholder="请选择"
+                    style="width: 86px"
+                  >
+                    <el-option
+                      v-for="item in topographicOptions"
+                      :key="item.value"
+                      :label="item.label"
+                      :value="item.value"
+                    />
+                  </el-select>
+                </div>
+              </template>
+              <div class="topographic-content">
+                <bar-chart
+                  styleName="styleName1"
+                  :xData="evaluateXData"
+                  :yData="evaluateYData"
+                ></bar-chart>
+                <div class="text-list box-bg">
+                    <div class="text-item" v-for="item in 3" :key="item">
+                    <div class="circle"></div>
+                    <div class="txt">
+                        高温Ⅰ级<span>26</span>棵
+                    </div>
+                    </div>
+                </div>
+              </div>
+            </chart-box>
+          </div>
+          <div class="chart-item">
+            <chart-box name="气象预警" arrow="left">
+                <div class="topographic-content">
+                <bar-chart
+                  styleName="styleName1"
+                  :xData="evaluateXData"
+                  :yData="evaluateYData"
+                ></bar-chart>
+                <div class="text-list box-bg">
+                    <div class="text-item" v-for="item in 3" :key="item">
+                    <div class="circle"></div>
+                    <div class="txt">
+                        桂味<span>15626</span>棵(树龄3.5年)
+                    </div>
+                    </div>
+                </div>
+              </div>
+            </chart-box>
+          </div>
+          <div class="chart-item">
+            <chart-box name="气象预警" arrow="left"></chart-box>
+          </div>
+          <div class="chart-item">
+            <chart-box name="气象预警" arrow="left"></chart-box>
+          </div>
+        </div>
+      </div>
+      <div class="home-bottom">
+        <div class="file-box yes-events">
+          <chart-box name="果园档案">
+            <template #title-right>
+              <el-icon class="arrow-icon cursor-pointer" color="#141414"
+                ><DArrowLeft
+              /></el-icon>
+              <div class="edit-btn cursor-pointer" @click="goBack">返回</div>
+            </template>
+            <file-bar>
+              <div class="btn-list">
+                <div class="btn-item">新增</div>
+                <div class="btn-item">筛选</div>
+                <div class="btn-item">撤销</div>
+                <div class="btn-item">保存</div>
+              </div>
+            </file-bar>
+          </chart-box>
+        </div>
+      </div>
+      <div class="right yes-events">
+        <div class="chart-list">
+          <div class="chart-item">
+            <chart-box name="气象预警" arrow="arrow-left"></chart-box>
+          </div>
+          <div class="chart-item">
+            <chart-box name="气象预警" arrow="arrow-left"></chart-box>
+          </div>
+          <div class="chart-item">
+            <chart-box name="气象预警" arrow="arrow-left"></chart-box>
+          </div>
+          <div class="chart-item">
+            <chart-box name="气象预警" arrow="arrow-left"></chart-box>
+          </div>
+        </div>
+      </div>
+    </div>
+  </div>
+  <div ref="mapRef" class="bottom-map"></div>
+</template>
+
+<script setup>
+import { onMounted, ref } from "vue";
+import fnHeader from "@/components/fnHeader.vue";
+import chartBox from "@/components/chartBox.vue";
+import fileBar from "@/components/fileBar.vue";
+import barChart from "@/components/charts/barChart.vue";
+import FileMap from "./fileMap";
+import router from "@/router";
+
+let fileMap = new FileMap();
+const mapRef = ref();
+const topographicValue = ref("高温风险");
+const topographicOptions = ref([
+  { label: "高温风险", value: "高温风险" },
+  { label: "病害风险", value: "病害风险" },
+  { label: "虫害风险", value: "虫害风险" },
+  { label: "阴雨寡照", value: "阴雨寡照" },
+]);
+
+// 地形风险
+const evaluateXData = ["Ⅰ级", "Ⅱ级", "Ⅲ级"];
+const evaluateYData = [33, 41, 43];
+
+onMounted(() => {
+  let location = "POINT (113.78049350268851 23.419886891845312)";
+  fileMap.initMap(location, mapRef.value);
+});
+
+// 返回
+const goBack = () => {
+  router.replace("/home");
+};
+</script>
+
+<style lang="scss" scoped>
+.base-container {
+  width: 100%;
+  height: 100vh;
+  color: #fff;
+  position: absolute;
+  box-sizing: border-box;
+  z-index: 1;
+
+  .content {
+    width: 100%;
+    height: calc(100% - 74px - 48px);
+    display: flex;
+    justify-content: space-between;
+    box-sizing: border-box;
+    .left,
+    .right {
+      width: 375px;
+      height: 100%;
+      padding-top: 10px;
+      box-sizing: border-box;
+      display: flex;
+      padding-left: 15px;
+      .chart-list {
+        width: 100%;
+        height: 100%;
+        display: flex;
+        flex-direction: column;
+        justify-content: space-between;
+        .chart-item {
+          width: 100%;
+          height: calc(100% / 4);
+          box-sizing: border-box;
+          margin-bottom: 10px;
+          &.chart-item:last-child {
+            margin: 0;
+          }
+        }
+      }
+      .topographic-content {
+        width: 100%;
+        height: calc(100% - 10px);
+        display: flex;
+        align-items: center;
+        justify-content: space-between;
+        margin-bottom: 10px;
+        .text {
+          font-weight: 400;
+          padding: 8px 0 4px 5px;
+          text-indent: 2em;
+          margin-left: 8px;
+          span {
+            color: #69bdff;
+          }
+        }
+        .box-bg {
+          border-radius: 2px 2px 0 0;
+          font-size: 12px;
+          padding: 8px 6px;
+          box-sizing: border-box;
+          background: linear-gradient(
+            180deg,
+            rgb(85, 85, 85, 0.4) 0%,
+            rgb(35, 35, 35, 1) 100%
+          );
+        }
+    }
+    .text-list {
+        flex: none;
+        margin: 0 16px;
+      .text-item {
+        display: flex;
+        align-items: center;
+        margin-bottom: 5px;
+        .circle {
+          width: 4px;
+          height: 4px;
+          background: rgba(255, 255, 255, 0.44);
+          border-radius: 50%;
+          margin-right: 6px;
+        }
+        .txt {
+          font-size: 12px;
+          span{
+            margin: 0 2px 0 6px;
+            color: #E8BA52;
+            }
+        }
+      }
+    }
+    }
+    .right {
+      .list {
+        width: 100%;
+        height: 100%;
+      }
+    }
+    .home-bottom {
+      display: flex;
+      align-items: flex-end;
+      width: calc(100% - 375px - 375px - 72px);
+      height: 100%;
+      justify-content: flex-end;
+      .file-box {
+        height: 25%;
+        min-height: 210px;
+        width: 422px;
+        position: relative;
+        box-shadow: 0 0 3px 3px #2199f8;
+        .arrow-icon {
+          top: -32px;
+          left: 50%;
+          position: absolute;
+          background: #fff;
+          width: 16px;
+          height: 80px;
+          line-height: 80px;
+          border-radius: 5px 0 0 5px;
+          text-align: center;
+          transform: translateX(-50%) rotate(270deg);
+        }
+        .edit-btn {
+          padding: 2px 24px;
+          background: #2199f8;
+          border-radius: 4px;
+        }
+        .btn-list {
+          position: absolute;
+          right: 4px;
+          .btn-item {
+            background: #4f4f4f;
+            border-radius: 4px;
+            padding: 2px 24px;
+            margin-bottom: 16px;
+            &:last-child {
+              margin-bottom: 0;
+            }
+          }
+        }
+      }
+    }
+  }
+}
+.bottom-map {
+  width: 100%;
+  height: 100vh;
+  position: absolute;
+  z-index: 0;
+}
+</style>

+ 2 - 2
src/views/home/homeMap.js

@@ -11,7 +11,7 @@ import { useRouter } from "vue-router";
 /**
  * @description 地图层对象
  */
-class GardenMap {
+class HomeMap {
   constructor() {
     let that = this;
     let vectorStyle = new KMap.VectorStyle();
@@ -25,4 +25,4 @@ class GardenMap {
   }
 }
 
-export default GardenMap;
+export default HomeMap;

+ 10 - 119
src/views/home/index.vue

@@ -21,35 +21,9 @@
               <el-icon class="arrow-icon cursor-pointer" color="#141414"
                 ><DArrowLeft
               /></el-icon>
-              <div class="edit-btn cursor-pointer">编辑</div>
+              <div class="edit-btn cursor-pointer" @click="toFilePage">编辑</div>
             </template>
-            <div class="file-chart">
-              <div
-                v-for="(item, index) in fileData"
-                :key="index"
-                class="item-container"
-              >
-                <div class="file-label">{{ item.name }}</div>
-                <div class="file-bar">
-                  <div
-                    v-for="(value, subIndex) in item.data"
-                    :key="subIndex"
-                    class="bar-block"
-                    :class="'bg-'+value.level"
-                    :style="{ width: computedWidths[index][subIndex] + 'px' }"
-                  >
-                  <el-tooltip
-                    class="tooltip-item"
-                    effect="light"
-                    :content="value.tag"
-                    placement="top"
-                  >
-                    <div class="cursor-pointer">{{ value.tag }}</div>
-                  </el-tooltip>
-                  </div>
-                </div>
-              </div>
-            </div>
+            <file-bar></file-bar>
           </chart-box>
         </div>
       </div>
@@ -65,14 +39,16 @@
 </template>
 
 <script setup>
-import { onMounted, ref, computed } from "vue";
+import { onMounted, ref } from "vue";
 import fnHeader from "@/components/fnHeader.vue";
 import chartBox from "@/components/chartBox.vue";
 import toolList from "@/components/toolList.vue";
+import fileBar from "@/components/fileBar.vue";
 import HomeMap from "./homeMap";
 import homePage from "./components/homePage.vue";
 import weatherPage from "./components/weatherPage.vue";
 import phenologyPage from "./components/phenologyPage.vue";
+import { useRouter } from "vue-router";
 const components = {
   homePage,
   weatherPage,
@@ -80,6 +56,7 @@ const components = {
 };
 
 let homeMap = new HomeMap();
+const router = useRouter();
 const mapRef = ref();
 onMounted(() => {
   let location = "POINT (113.78049350268851 23.419886891845312)";
@@ -124,48 +101,10 @@ const rightToolList = [
   },
 ];
 
-const fileData = ref([
-  { name: '高产级', data: [
-    { value: 325, level: 4, tag: '325棵' },
-    { value: 325, level: 3, tag: '325棵' },
-    { value: 325, level: 2, tag: '325棵' },
-    { value: 325, level: 1, tag: '325棵' },
-  ]},
-  { name: '稳产级', data: [
-    { value: 160, level: 4, tag: '160棵' },
-    { value: 170, level: 3, tag: '170棵' },
-    { value: 170, level: 2, tag: '170棵' },
-    { value: 170, level: 1, tag: '170棵' },
-  ]},
-  { name: '休养-幼树', data: [
-    { value: 380, level: 0, tag: '新嫁接1年 380棵' },
-    { value: 330, level: 0, tag: '2年 330棵' },
-    { value: 200, level: 0, tag: '3年 200棵' },
-  ]},
-  { name: '休养-病虫', data: [
-    { value: 350, level: 3, tag: '蒂蛀虫 350棵' },
-    { value: 350, level: 1, tag: '其他病 350棵' },
-  ]},
-  { name: '休养-生长', data: [
-    { value: 300, level: 2, tag: '花芽 300棵' },
-    { value: 280, level: 2, tag: '花穗 280棵' },
-    { value: 320, level: 2, tag: '小果 320棵' },
-  ]},
-]);
-// 计算所有 data 中 value 属性的总和最大值
-const maxSum = computed(() => {
-  return Math.max(...fileData.value.map(item => item.data.reduce((sum, dataPoint) => sum + dataPoint.value, 0)));
-});
- 
-// 计算每个 dataPoint 的值在所有 data 中 value 总和最大值中所占的百分比
-const computedWidths = computed(() => {
-  const max = maxSum.value;
-  return fileData.value.map(item => {
-    // 258是右侧容器总宽度
-    return item.data.map(dataPoint => ((dataPoint.value / max) * 258).toFixed(0)); // 保留两位小数
-  });
-});
- 
+// 跳转果园档案
+const toFilePage = () => {
+  router.push('/garden-file')
+}
 </script>
 
 <style lang="scss" scoped>
@@ -231,54 +170,6 @@ const computedWidths = computed(() => {
           background: #2199f8;
           border-radius: 4px;
         }
-        .file-chart {
-          padding: 0 6px;
-          height: 100%;
-          display: flex;
-          flex-direction: column;
-          align-items: center;
-          justify-content: center;
-          .item-container {
-            display: flex;
-            width: 100%;
-            color: #FFFFFF;
-            margin-bottom: 12px;
-            .file-label {
-              width: 60px;
-              text-align: right;
-              font-size: 12px;
-            }
-            .file-bar {
-              width: calc(100% - 56px);
-              display: flex;
-              padding-left: 6px;
-              height: 18px;
-              font-size: 10px;
-              .bar-block {
-                text-align: center;
-                border-radius: 0px 4px 4px 0px;
-                // border-image: linear-gradient(90deg, rgba(255, 223, 223, 0), rgba(234, 232, 232, 1)) 1 1;
-                white-space: nowrap;
-                overflow: hidden;
-                text-overflow: ellipsis;
-                &::before {
-                  content: "";
-                  position: absolute;
-                  top: -2px; /* 边框宽度的一半,且方向相反 */
-                  left: -2px; /* 边框宽度的一半,且方向相反 */
-                  right: -2px; /* 边框宽度的一半,且方向相反 */
-                  bottom: -2px; /* 边框宽度的一半,且方向相反 */
-                  background-image: linear-gradient(to right, rgba(255, 223, 223, 0), rgba(234, 232, 232, 1)); /* 渐变背景 */
-                  border-radius: 0px 4px 4px 0px; /* 继承容器的圆角半径 */
-                  z-index: -1; /* 放在容器内容之下 */
-                }
-              }
-              .bg-0 {
-                background-image: linear-gradient(to right, #042921, #0CBA93);
-              }
-            }
-          }
-        }
       }
     }
   }