Browse Source

feat: 驿站站点可视化地图样式调整

zhangying 10 months ago
parent
commit
4abfa10aed
2 changed files with 157 additions and 81 deletions
  1. 9 11
      vue/src/views/dataMap/companyDataMap.vue
  2. 148 70
      vue/src/views/dataMap/siteDataMap.vue

+ 9 - 11
vue/src/views/dataMap/companyDataMap.vue

@@ -445,13 +445,11 @@ const initMap = () => {
 
     // 地图缩放监听事件
     (map as any).addEventListener("zoomend", function () {
-      let zoomLevel = map.getZoom();
-      console.log(zoomLevel);
+      let zoomLevel = (map as any).getZoom();
       // 计算新的icon大小
-      let newSize = Math.min(30, Math.max(15, (zoomLevel - 10) * 3 + 15));
-      console.log(newSize);
+      let newSize = Math.min(Math.max(zoomLevel * 3, 15), 45);
       // 计算新的icon锚点位置
-      let iconAnchor = new T.Point(15 * (newSize / 30), 30 * (newSize / 30));
+      let iconAnchor = new T.Point(15 * (newSize / 45), 30 * (newSize / 45));
       markerList.value.forEach((item: any) => {
         (map as any).removeOverLay(item);
         item.getIcon().setIconSize(new T.Point(newSize, newSize));
@@ -460,8 +458,8 @@ const initMap = () => {
       })
       // 更新 label 的偏移量
       // 计算新的偏移量,保持 label 居中且不超过初始值
-      let offsetX = -30 + ((newSize - 30) / 2);
-      let offsetY = 15 + ((newSize - 30) / 2);
+      let offsetX = -30 + ((newSize - 45) / 2);
+      let offsetY = 15 + ((newSize - 45) / 2);
       // 确保偏移量不超过初始值
       offsetX = Math.max(offsetX, -25);
       offsetY = Math.min(offsetY, 10);
@@ -496,11 +494,11 @@ function setLoginLocation() {
     }
   }).finally(() => {
     // 设置中心点
-    (map as any).centerAndZoom(new T.LngLat(companySearchParam.longitude, companySearchParam.latitude), 12);
+    (map as any).centerAndZoom(new T.LngLat(companySearchParam.longitude, companySearchParam.latitude), 10);
     const icon = new T.Icon({
       iconUrl: redThIcon,
-      iconSize: new T.Point(50, 50),
-      iconAnchor: new T.Point(25, 50)
+      iconSize: new T.Point(30, 30),
+      iconAnchor: new T.Point(15, 30)
     })
     const point = new T.LngLat(companySearchParam.longitude, companySearchParam.latitude)
     // 创建标注
@@ -600,7 +598,7 @@ async function checkCompanyChange(company: any) {
   // 设置中心点到企业位置
   if (company.longitude && company.latitude) {
     // 设置中心点
-    (map as any).centerAndZoom(new T.LngLat(company.longitude, company.latitude), 16);
+    (map as any).centerAndZoom(new T.LngLat(company.longitude, company.latitude), 14);
   }
   await findPostList();
 }

+ 148 - 70
vue/src/views/dataMap/siteDataMap.vue

@@ -8,59 +8,66 @@
       <!-- 驿站查询与展示 -->
       <div class="site-search-data-box">
         <!-- 查询表单区域 -->
-        <div class="search-box">
+        <div class="search-input-box">
           <a-input-search
             v-model:value="siteSearchParam.siteName"
             placeholder="请输入站点名称"
-            enter-button="查询"
+            enter-button
             :loading="searchLoading"
             style="width: 100%"
             @search="onSearch"
           />
-          <div style="width: 100%">
+        </div>
+        <!-- 数据列表 -->
+        <div class="select-data-box">
+          <div class="select-input-box">
+            <span class="cursor-pointer" style="width: 28%;padding: 0 7px;text-align: center"
+                  @click="searchAll">全部</span>
             <a-select
-              style="width: 36%;"
-              v-model:value="siteSearchParam.regionCode"
-              :allow-clear="true"
-              :options="regionList"
-              :field-names="{ label: 'name', value: 'code' }"
-              placeholder="所属县区"
-              @change="changeRegion"
+                style="width: 36%;"
+                v-model:value="siteSearchParam.regionCode"
+                :allow-clear="true"
+                :options="regionList"
+                :field-names="{ label: 'name', value: 'code' }"
+                placeholder="所属县区"
+                @change="changeRegion"
             >
             </a-select>
             <a-select
-              style="width: 36%;"
-              v-model:value="siteSearchParam.streetCode"
-              :options="streetList"
-              :field-names="{ label: 'name', value: 'code' }"
-              :allow-clear="true"
-              placeholder="所属街道"
+                style="width: 36%;"
+                v-model:value="siteSearchParam.streetCode"
+                :options="streetList"
+                :field-names="{ label: 'name', value: 'code' }"
+                :allow-clear="true"
+                placeholder="所属街道"
             >
             </a-select>
-            <a-button style="width: 28%" @click="searchAll">全部</a-button>
-          </div>
-        </div>
-        <!-- 数据列表 -->
-        <div class="list-box">
-          <div v-if="siteList.length > 0" class="site-data"
-               :class="{'check-site':nowCheckSite.siteID == site.siteID}" v-for="(site,siteIndex) in siteList"
-               :key="siteIndex"
-               @click="checkSite(site)">
-            <p class="site-name">
-              {{ site.siteName }}
-            </p>
-            <p class="label-text">
-              驿站编号{{ site.siteCode }}
-            </p>
-            <p class="label-text">
-              地点:{{ site.detailAddress }}
-            </p>
-            <p class="label-text">
-              站点工作人员:{{ site.siteUsers.length }}
-            </p>
           </div>
-          <div v-else class="empty-box">
-            <a-empty/>
+          <div class="list-box">
+            <div v-if="siteList.length > 0" class="site-data"
+                 :class="{'check-site':nowCheckSite.siteID == site.siteID || nowMouseenterSite.siteID == site.siteID}"
+                 v-for="(site,siteIndex) in siteList"
+                 :key="siteIndex"
+                 @click="checkSite(site)"
+                 @mouseenter="siteMouseenter(site)"
+                 @mouseleave="siteMouseenter({siteID:-1})"
+            >
+              <p class="site-name">
+                {{ site.siteName }}
+              </p>
+              <p class="label-text">
+                驿站编号{{ site.siteCode }}
+              </p>
+              <p class="label-text">
+                地点:{{ site.detailAddress }}
+              </p>
+              <p class="label-text">
+                站点工作人员:{{ site.siteUsers.length }}
+              </p>
+            </div>
+            <div v-else class="empty-box">
+              <a-empty/>
+            </div>
           </div>
         </div>
         <!-- 分页控件 -->
@@ -81,13 +88,13 @@ import {onMounted, reactive, ref} from "vue";
 import type {SelectProps} from "ant-design-vue";
 import {getRegionCodeList, getStreetCodeList} from "@/api/system/area/index";
 import {getSiteList} from "@/api/baseSettings/siteInfo";
-import thIcon from "@/assets/images/redTh.png"
+import thIcon from "@/assets/images/blueTh.png"
 
 const T = (window as any).T;
-const zoom = 11;
+const zoom = 10;
 let map = null;
 // 地图标记点
-let markerList = new Array<any>([]);
+let markerList = ref<Array<any>>([]);
 
 // 驿站查询数据
 const siteSearchParam = reactive({
@@ -108,7 +115,9 @@ const regionList = ref<SelectProps['options']>();
 // 街道数据
 const streetList = ref<SelectProps['options']>();
 // 选中的站点
-const nowCheckSite = ref({})
+const nowCheckSite = ref<any>({})
+// 鼠标经过的站点
+const nowMouseenterSite = ref<any>({});
 
 // 地图初始化
 const initMap = () => {
@@ -117,6 +126,21 @@ const initMap = () => {
   if (map != null) {
     // 设置地图显示中心点为惠州市人民政府
     (map as any).centerAndZoom(new T.LngLat(114.416110, 23.111582), zoom);
+
+    // 地图缩放监听事件
+    (map as any).addEventListener("zoomend", function () {
+      let zoomLevel = (map as any).getZoom();
+      // 计算新的icon大小
+      let newIconSize = Math.min(Math.max(zoomLevel * 3, 15), 35);
+      // 计算新的icon锚点位置
+      let iconAnchor = new T.Point(15 * (newIconSize / 35), 30 * (newIconSize / 35));
+      markerList.value.forEach((item: any) => {
+        (map as any).removeOverLay(item);
+        item.getIcon().setIconSize(new T.Point(newIconSize, newIconSize));
+        item.getIcon().setIconAnchor(iconAnchor);
+        (map as any).addOverLay(item);
+      })
+    });
   }
   // 设置城市边界
   setBoundary(map, T, huiZhouGeoJSON);
@@ -165,10 +189,11 @@ const changeRegion = async function () {
 
 function setSiteMarker() {
   // 删除已有标点
-  if (markerList.length > 0) {
-    for (let i = 0; i < markerList.length; i++) {
+  if (markerList.value.length > 0) {
+    for (let i = 0; i < markerList.value.length; i++) {
       (map as any).removeOverLay(markerList[i]);
     }
+    markerList.value = []
   }
 
   // 设置中心点
@@ -202,7 +227,7 @@ function setSiteMarker() {
           // (map as any).openInfoWindow(infoWindow, point);
         });
         (map as any).addOverLay(marker);// 将标注添加到地图中
-        markerList.push(marker);
+        markerList.value.push(marker);
       }
     })
   }
@@ -217,6 +242,11 @@ function checkSite(site: any) {
   }
 }
 
+// 鼠标经过事件
+function siteMouseenter(site: any) {
+  nowMouseenterSite.value = site;
+}
+
 onMounted(() => {
   initMap();
   getRegionList();
@@ -231,7 +261,7 @@ export default {
 }
 </script>
 
-<style lang="less" scoped>
+<style lang="less">
 .map-box {
   width: 100%;
   height: calc(100vh - 235px);
@@ -248,36 +278,65 @@ export default {
 
   .site-search-data-box {
     width: 300px;
-    height: 100%;
     position: absolute;
-    top: 0;
-    bottom: 0;
-    left: 0;
+    top: 15px;
+    bottom: 15px;
+    left: 15px;
     right: 330px;
-    background-color: white;
-    border-right: 1px solid rgba(173, 173, 173, 0.8);
     z-index: 110;
 
-    .list-box {
-      max-height: calc(100% - 110px);
+    .search-input-box {
+      width: 100%;
+      margin-bottom: 10px;
+    }
+
+    .select-data-box {
+      height: calc(100% - 95px);
+      background-color: #F8F8F8;
       margin-bottom: 10px;
-      overflow: hidden;
-      overflow-y: auto;
+      border-radius: 10px;
+      padding: 10px;
+
+      .select-input-box {
+        width: 100%;
+        display: flex;
+        align-items: center;
+        background-color: white;
+        padding: 8px 5px;
+        margin-bottom: 10px;
+        border-radius: 10px;
+      }
+
+      .list-box {
+        max-height: calc(100% - 60px);
+        overflow: hidden;
+        overflow-y: auto;
+
+        .site-data {
+          background-color: white;
+          border-radius: 10px;
+          padding: 8px;
+          cursor: pointer;
+          margin-bottom: 10px;
+          box-shadow: 0 5px 5px -5px rgba(0, 0, 0, 0.3);
+          box-sizing: border-box;
+          border: 1px solid white;
 
-      .site-data {
-        padding: 8px;
-        border-bottom: 1px solid rgba(173, 173, 173, 0.8);
-        cursor: pointer;
+          .site-name {
+            font-size: 14px;
+            font-weight: 600;
+            margin-bottom: 8px;
+          }
 
-        .site-name {
-          font-size: 14px;
-          font-weight: 700;
+          .label-text {
+            font-size: 12px;
+            color: #737373;
+            margin-bottom: 3px;
+          }
         }
 
-        .label-text {
-          font-size: 12px;
-          color: #737373;
-          margin-bottom: 3px;
+        .check-site {
+          border-color: #007EFF;
         }
       }
     }
@@ -286,6 +345,9 @@ export default {
   .pagination-box {
     display: flex;
     justify-content: center;
+    padding: 10px 10px;
+    background-color: #F8F8F8;
+    border-radius: 10px;
   }
 
   .empty-box {
@@ -297,8 +359,24 @@ export default {
     border-right: 1px solid rgba(173, 173, 173, 0.8);
   }
 
-  .check-site {
-    background-color: #dadada;
+  .ant-btn, .ant-input {
+    border: none !important;
+  }
+
+  input {
+    height: 32px;
+  }
+
+  .ant-select:not(.ant-select-customize-input) .ant-select-selector,
+  .ant-select:not(.ant-select-customize-input) .ant-select-selector,
+  .ant-input-affix-wrapper, .ant-select-selector {
+    border: none !important;
+    box-shadow: none !important;
+  }
+
+  .ant-select:not(.ant-select-disabled).ant-select:not(.ant-select-customize-input) > .ant-select-selector {
+    border-color: transparent;
+    box-shadow: none;
   }
 }
 </style>