Browse Source

feat: 驿站地图查询站点人员

zhangying 9 months ago
parent
commit
4f10cf0da6

+ 9 - 3
src/main/java/com/hz/employmentsite/controller/baseSettings/SiteUserController.java

@@ -5,14 +5,13 @@ import com.hz.employmentsite.filter.exception.BaseErrorEnum;
 import com.hz.employmentsite.filter.exception.BaseException;
 import com.hz.employmentsite.filter.exception.BaseResponse;
 import com.hz.employmentsite.filter.exception.RespGenerstor;
-import com.hz.employmentsite.mapper.PcDotaskUserMapper;
-import com.hz.employmentsite.mapper.PcDoworkMapper;
-import com.hz.employmentsite.model.*;
+import com.hz.employmentsite.model.SelectProps;
 import com.hz.employmentsite.services.service.AccountService;
 import com.hz.employmentsite.services.service.baseSettings.SiteUserService;
 import com.hz.employmentsite.util.ExcelHelper;
 import com.hz.employmentsite.util.StringUtils;
 import com.hz.employmentsite.vo.baseSettings.SiteUserVo;
+import com.hz.employmentsite.vo.dataMap.SiteUserMapVo;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.web.bind.annotation.*;
 
@@ -150,5 +149,12 @@ public class SiteUserController {
         return RespGenerstor.success(result);
     }
 
+    @GetMapping("/dataMap")
+    public BaseResponse<PageInfo<SiteUserMapVo>> getDataMapList(@RequestParam int pageIndex, @RequestParam int pageSize,
+                                                             @RequestParam(required = false) String siteUserName, @RequestParam(required = false) String regionCode,
+                                                             @RequestParam(required = false) String streetCode, @RequestParam(required = false) String siteID){
+        PageInfo<SiteUserMapVo> result = userInfoService.getDataMapList(pageIndex, pageSize, siteUserName, regionCode, streetCode, siteID);
+        return RespGenerstor.success(result);
+    }
 
 }

+ 12 - 0
src/main/java/com/hz/employmentsite/mapper/cquery/UserInfoCQuery.java

@@ -1,6 +1,7 @@
 package com.hz.employmentsite.mapper.cquery;
 
 import com.hz.employmentsite.vo.baseSettings.SiteUserVo;
+import com.hz.employmentsite.vo.dataMap.SiteUserMapVo;
 import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
@@ -20,4 +21,15 @@ public interface UserInfoCQuery {
     List<SiteUserVo> getListBySiteID(@Param("siteID") String siteID);
 
     List<SiteUserVo> selectListForAddUser();
+
+    /**
+     * 驿站站点数据地图查询驿站人员
+     * @param siteUserName 人员名称
+     * @param regionCode 所属县区
+     * @param streetCode 所属街道
+     * @param siteID 所属驿站
+     * @return 驿站人员列表
+     */
+    List<SiteUserMapVo> getDataMapList(@Param("siteUserName") String siteUserName, @Param("regionCode") String regionCode,
+                                       @Param("streetCode") String streetCode, @Param("siteID") String siteID);
 }

+ 12 - 0
src/main/java/com/hz/employmentsite/services/impl/baseSettings/SiteUserImpl.java

@@ -13,6 +13,7 @@ import com.hz.employmentsite.services.service.system.DictionaryService;
 import com.hz.employmentsite.util.DateUtils;
 import com.hz.employmentsite.util.StringUtils;
 import com.hz.employmentsite.vo.baseSettings.SiteUserVo;
+import com.hz.employmentsite.vo.dataMap.SiteUserMapVo;
 import net.sourceforge.pinyin4j.PinyinHelper;
 import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
 import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
@@ -508,4 +509,15 @@ public class SiteUserImpl implements SiteUserService {
     public List<SiteUserVo> getListForAddUser(){
         return userInfoCQuery.selectListForAddUser();
     }
+
+    /**
+     * 驿站站点数据地图查询驿站人员
+     */
+    @Override
+    public PageInfo<SiteUserMapVo> getDataMapList(int pageIndex, int pageSize, String siteUserName, String regionCode, String streetCode, String siteID) {
+        PageHelper.startPage(pageIndex, pageSize);
+        List<SiteUserMapVo> dataMapList = userInfoCQuery.getDataMapList(siteUserName, regionCode, streetCode, siteID);
+        PageInfo<SiteUserMapVo> result = new PageInfo(dataMapList);
+        return result;
+    }
 }

+ 7 - 0
src/main/java/com/hz/employmentsite/services/service/baseSettings/SiteUserService.java

@@ -2,6 +2,7 @@ package com.hz.employmentsite.services.service.baseSettings;
 import com.github.pagehelper.PageInfo;
 import com.hz.employmentsite.model.SelectProps;
 import com.hz.employmentsite.vo.baseSettings.SiteUserVo;
+import com.hz.employmentsite.vo.dataMap.SiteUserMapVo;
 
 import java.util.List;
 
@@ -32,4 +33,10 @@ public interface SiteUserService {
     List<SiteUserVo> importSiteUser(List<SiteUserVo> dataList, String loginUserId);
 
     List<SiteUserVo> getListForAddUser();
+
+    /**
+     * 驿站站点数据地图查询驿站人员
+     */
+    PageInfo<SiteUserMapVo> getDataMapList(int pageIndex, int pageSize, String siteUserName,
+                                           String regionCode, String streetCode, String siteID);
 }

+ 26 - 0
src/main/java/com/hz/employmentsite/vo/dataMap/SiteUserMapVo.java

@@ -0,0 +1,26 @@
+package com.hz.employmentsite.vo.dataMap;
+
+import lombok.Data;
+
+@Data
+public class SiteUserMapVo {
+    private String siteUserID;
+
+    private String siteUserName;
+
+    private String userNo;
+
+    private String mobile;
+
+    private String siteID;
+
+    private String siteName;
+
+    private String siteLongitude;
+
+    private String siteLatitude;
+
+    private String longitude;
+
+    private String latitude;
+}

+ 42 - 0
src/main/resources/mapping/cquery/SiteUserCQuery.xml

@@ -88,4 +88,46 @@
         where siteUser.userId is null
         order by site.siteName
     </select>
+
+    <select id="getDataMapList" resultType="com.hz.employmentsite.vo.dataMap.SiteUserMapVo">
+        SELECT
+            siteUser.SiteUserID,
+            siteUser.SiteUserName,
+            siteUser.UserNo,
+            siteUser.Mobile,
+            site.SiteID,
+            site.SiteName,
+            site.SiteLongitude,
+            site.SiteLatitude,
+            lnglat.Longitude,
+            lnglat.Latitude
+        FROM
+            pc_site_user siteUser
+            LEFT JOIN pc_site site ON siteUser.SiteID = site.SiteID
+            LEFT JOIN (
+                SELECT
+                    lonlat1.UserID,
+                    lonlat1.Longitude,
+                    lonlat1.Latitude
+                FROM
+                    pc_longitude_latitude lonlat1
+                        INNER JOIN ( SELECT UserID, MAX( Time ) AS MaxTime FROM pc_longitude_latitude WHERE DATE( Time ) = CURDATE() GROUP BY UserID ) lonlat2 ON lonlat1.UserID = lonlat2.UserID
+                AND lonlat1.Time = lonlat2.MaxTime
+                WHERE
+                    DATE( lonlat1.Time ) = CURDATE()
+            ) lnglat ON lnglat.UserID = siteUser.UserID
+        WHERE 1=1
+        <if test="siteUserName!='' and siteUserName!=null">
+            and siteUser.siteUserName like Concat('%', #{siteUserName}, '%')
+        </if>
+        <if test="siteID!='' and siteID!=null">
+            and siteUser.siteID = #{siteID}
+        </if>
+        <if test="regionCode!='' and regionCode!=null">
+            and site.regionCode = #{regionCode}
+        </if>
+        <if test="streetCode!='' and streetCode!=null">
+            and site.streetCode = #{streetCode}
+        </if>
+    </select>
 </mapper>

+ 13 - 0
vue/src/api/baseSettings/userInfo.ts

@@ -96,3 +96,16 @@ export function getListForAddUser(params: any) {
   );
 }
 
+export function getSiteUserDataMapList(params: any) {
+  return request<object>(
+    {
+      url: "userInfo/dataMap",
+      method: 'get',
+      params: params,
+    },
+    {
+      isNew: true,
+    },
+  );
+}
+

+ 229 - 49
vue/src/views/dataMap/siteDataMap.vue

@@ -9,22 +9,29 @@
       <div class="site-search-data-box">
         <!-- 查询表单区域 -->
         <div class="search-input-box">
+          <a-select
+            v-model:value="searchType"
+            @change="searchTypeChange"
+          >
+            <a-select-option value="site">找驿站</a-select-option>
+            <a-select-option value="siteUser">找人员</a-select-option>
+          </a-select>
           <a-input-search
             v-model:value="siteSearchParam.siteName"
-            placeholder="请输入站点名称"
+            :placeholder="searchType == 'site' ? '请输入站点名称' : '请输入人员名称'"
             enter-button
             :loading="searchLoading"
-            style="width: 100%"
+            style="width: 77%"
             @search="onSearch"
           />
         </div>
         <!-- 数据列表 -->
         <div class="select-data-box">
           <div class="select-input-box">
-            <span class="cursor-pointer" style="width: 28%;padding: 0 7px;text-align: center"
+            <span class="cursor-pointer" style="width: 35px;padding: 7px 0;text-align: center"
                   @click="searchAll">全部</span>
             <a-select
-                style="width: 36%;"
+              style="width: 30%;"
                 v-model:value="siteSearchParam.regionCode"
                 :allow-clear="true"
                 :options="regionList"
@@ -35,7 +42,7 @@
             >
             </a-select>
             <a-select
-                style="width: 36%;"
+              style="width: 30%;"
                 v-model:value="siteSearchParam.streetCode"
                 :options="streetList"
                 :field-names="{ label: 'name', value: 'code' }"
@@ -44,9 +51,20 @@
                 placeholder="所属街道"
             >
             </a-select>
+            <a-select
+              style="width: 30%;"
+              v-model:value="siteSearchParam.siteID"
+              :options="siteDicList"
+              :field-names="{ label: 'siteName', value: 'siteID' }"
+              :allow-clear="true"
+              :bordered="false"
+              :disabled="searchType == 'site'"
+              placeholder="所属驿站"
+            >
+            </a-select>
           </div>
           <div class="list-box">
-            <div v-if="siteList.length > 0" class="site-data"
+            <div v-if="searchType == 'site' && 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"
@@ -58,7 +76,7 @@
                 {{ site.siteName }}
               </p>
               <p class="label-text">
-                驿站编号{{ site.siteCode }}
+                驿站编号{{ site.siteCode }}
               </p>
               <p class="label-text">
                 地点:{{ site.detailAddress }}
@@ -67,14 +85,37 @@
                 站点工作人员:{{ site.siteUsers.length }}
               </p>
             </div>
-            <div v-else class="empty-box">
+            <div v-if="searchType == 'siteUser' && siteUserList.length > 0" class="site-data"
+                 :class="{'check-site':nowCheckSiteUser.siteUserID == siteUser.siteUserID || nowMouseenterSiteUser.siteUserID == siteUser.siteUserID}"
+                 v-for="(siteUser,siteIndex) in siteUserList"
+                 :key="siteIndex"
+                 @click="checkSiteUser(siteUser)"
+                 @mouseenter="siteUserMouseenter(siteUser)"
+                 @mouseleave="siteUserMouseenter({siteUserID:-1})"
+            >
+              <p class="site-name">
+                {{ siteUser.siteUserName }}
+              </p>
+              <p class="label-text">
+                工号:{{ siteUser.userNo }}
+              </p>
+              <p class="label-text">
+                联系电话:{{ siteUser.mobile }}
+              </p>
+              <p class="label-text">
+                所属驿站:{{ siteUser.siteName }}
+              </p>
+            </div>
+            <div
+              v-if="(searchType == 'site' && siteList.length  == 0) || (searchType == 'siteUser' && siteUserList.length == 0)"
+              class="empty-box">
               <a-empty/>
             </div>
           </div>
         </div>
         <!-- 分页控件 -->
         <div class="pagination-box">
-          <a-pagination v-model:current="siteSearchParam.pageIndex" :total="siteTotal"
+          <a-pagination v-model:current="siteSearchParam.pageIndex" :total="paginationTotal"
                         v-model:pageSize="siteSearchParam.pageSize"
                         show-less-items @change="onSearch" simple :show-size-changer="false"/>
         </div>
@@ -91,6 +132,7 @@ 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/blueTh.png"
+import {getSiteUserDataMapList} from "@/api/baseSettings/userInfo";
 
 const T = (window as any).T;
 const zoom = 9;
@@ -99,29 +141,41 @@ let map = null;
 const centerLngLat = new T.LngLat(114.416110, 23.111582);
 // 地图标记点
 let markerList = ref<Array<any>>([]);
+let labelList = ref<Array<any>>([]);
 
+// 查询类型
+const searchType = ref("site")
 // 驿站查询数据
 const siteSearchParam = reactive({
   pageIndex: 1,
-  pageSize: 50,
+  pageSize: 100,
   siteName: "",
   regionCode: null,
   streetCode: null,
+  siteID: null,
 });
 // 驿站数据
 const siteList = ref<Array<any>>([])
+// 驿站人员数据
+const siteUserList = ref<Array<any>>([]);
 // 查询动画
 const searchLoading = ref(false);
 // 驿站总条数
-const siteTotal = ref(0)
+const paginationTotal = ref(0)
 // 县区数据
 const regionList = ref<SelectProps['options']>();
 // 街道数据
 const streetList = ref<SelectProps['options']>();
+// 驿站下拉框数据
+const siteDicList = ref<any>([]);
 // 选中的站点
 const nowCheckSite = ref<any>({})
 // 鼠标经过的站点
 const nowMouseenterSite = ref<any>({});
+// 选中的站点
+const nowCheckSiteUser = ref<any>({})
+// 鼠标经过的站点
+const nowMouseenterSiteUser = ref<any>({});
 
 // 地图初始化
 const initMap = () => {
@@ -141,6 +195,12 @@ const initMap = () => {
         item.getIcon().setIconAnchor(sizeData.iconAnchor);
         (map as any).addOverLay(item);
       })
+      labelList.value.forEach((item: any) => {
+        (map as any).removeOverLay(item);
+        item.setOffset(sizeData.labelOffset);
+        item.setFontSize(sizeData.fontSize);
+        (map as any).addOverLay(item);
+      })
     });
   }
   // 设置城市边界
@@ -150,31 +210,59 @@ const initMap = () => {
 // 查询驿站
 function onSearch() {
   searchLoading.value = true;
-  getSiteList(siteSearchParam).then((result: any) => {
-    siteList.value = result.list;
-    siteList.value.forEach((site: any) => {
-      if (site.siteUsers) {
-        site.siteUsers = site.siteUsers.split(',');
-      } else {
-        site.siteUsers = []
-      }
+  if (searchType.value == "site") {
+    getSiteList(siteSearchParam).then((result: any) => {
+      siteList.value = result.list;
+      siteList.value.forEach((site: any) => {
+        if (site.siteUsers) {
+          site.siteUsers = site.siteUsers.split(',');
+        } else {
+          site.siteUsers = []
+        }
+      })
+      paginationTotal.value = result.total;
+      // 地图绘制
+      setSiteMarker()
+    }).finally(() => {
+      searchLoading.value = false;
     })
-    siteTotal.value = result.total;
-    // 地图绘制
-    setSiteMarker()
-  }).finally(() => {
-    searchLoading.value = false;
-  })
+  } else {
+    let params = {
+      pageIndex: siteSearchParam.pageIndex,
+      pageSize: 100,
+      siteUserName: siteSearchParam.siteName,
+      regionCode: siteSearchParam.regionCode,
+      streetCode: siteSearchParam.streetCode,
+      siteID: siteSearchParam.siteID
+    }
+    getSiteUserDataMapList(params).then((result: any) => {
+      siteUserList.value = result.list;
+      paginationTotal.value = result.total;
+      // 地图绘制
+      setSiteMarker();
+    }).finally(() => {
+      searchLoading.value = false;
+    })
+  }
+
 }
 
 // 查询全部
 function searchAll() {
-  siteSearchParam.pageIndex = 1
-  siteSearchParam.pageSize = 50
-  siteSearchParam.siteName = ""
-  siteSearchParam.regionCode = null
-  siteSearchParam.streetCode = null
+  siteSearchParam.pageIndex = 1;
+  siteSearchParam.pageSize = 100;
+  siteSearchParam.siteName = "";
+  siteSearchParam.regionCode = null;
+  siteSearchParam.streetCode = null;
+  siteSearchParam.siteID = null;
+  onSearch();
+}
+
+// 查询类型切换事件
+function searchTypeChange() {
+  // 清空数据
   onSearch();
+  delMapInfo();
 }
 
 // 查询县区
@@ -187,15 +275,15 @@ const changeRegion = async function () {
     streetList.value = await getStreetCodeList(siteSearchParam.regionCode);
   }
 }
+// 查询驿站
+const getAllSites = () => {
+  getSiteList({pageIndex: 1, pageSize: 9999}).then((result: any) => {
+    siteDicList.value = result.list;
+  })
+}
 
 function setSiteMarker() {
-  // 删除已有标点
-  if (markerList.value.length > 0) {
-    for (let i = 0; i < markerList.value.length; i++) {
-      (map as any).removeOverLay(markerList.value[i]);
-    }
-    markerList.value = []
-  }
+  delMapInfo();
 
   // 设置中心点
   (map as any).centerAndZoom(centerLngLat, zoom);
@@ -210,18 +298,81 @@ function setSiteMarker() {
       iconSize: new T.Point(sizeData.iconSize, sizeData.iconSize),
       iconAnchor: sizeData.iconAnchor
     })
-    // 解析站点数据,在地图中标记
-    siteList.value.forEach((item: any) => {
-      if (item.siteLongitude && item.siteLatitude) {
-        const point = new T.LngLat(item.siteLongitude, item.siteLatitude)
-        const marker = new T.Marker(point, {icon: icon}); // 创建标注
-        (map as any).addOverLay(marker);// 将标注添加到地图中
-        markerList.value.push(marker);
-      }
-    })
+    if (searchType.value == "site") {
+      // 解析站点数据,在地图中标记
+      siteList.value.forEach((item: any) => {
+        if (item.siteLongitude && item.siteLatitude) {
+          const point = new T.LngLat(item.siteLongitude, item.siteLatitude)
+          const marker = new T.Marker(point, {icon: icon}); // 创建标注
+          // 添加点击事件
+          marker.addEventListener('click', () => {
+            checkSite(item);
+          });
+          (map as any).addOverLay(marker);// 将标注添加到地图中
+          markerList.value.push(marker);
+        }
+      })
+    } else {
+      // 解析人员数据
+      siteUserList.value.forEach((item: any) => {
+        if (item.longitude && item.latitude) {
+          const point = new T.LngLat(item.longitude, item.latitude)
+          const marker = new T.Marker(point, {icon: icon}); // 创建标注
+          // 添加点击事件
+          marker.addEventListener('click', () => {
+            checkSiteUser(item);
+          });
+          let label = new T.Label({
+            text: item.siteUserName, //文本标注的内容
+            position: new T.LngLat(item.longitude, item.latitude), //文本标注的地理位置
+            offset: sizeData.labelOffset, //文本标注的位置偏移值
+          });
+          label.setBorderLine(0);
+          label.setFontSize(sizeData.fontSize);
+          (map as any).addOverLay(marker);// 将标注添加到地图中
+          markerList.value.push(marker);
+          // (map as any).addOverLay(label);// 将标注添加到地图中
+          // labelList.value.push(label);
+        } else if (item.siteLongitude && item.siteLatitude) {
+          const point = new T.LngLat(item.siteLongitude, item.siteLatitude);
+          const marker = new T.Marker(point, {icon: icon}); // 创建标注
+          // 添加点击事件
+          marker.addEventListener('click', () => {
+            checkSiteUser(item);
+          });
+          let label = new T.Label({
+            text: item.siteUserName, //文本标注的内容
+            position: new T.LngLat(item.siteLongitude, item.siteLatitude), //文本标注的地理位置
+            offset: sizeData.labelOffset, //文本标注的位置偏移值
+          });
+          label.setBorderLine(0);
+          label.setFontSize(sizeData.fontSize);
+          (map as any).addOverLay(marker);// 将标注添加到地图中
+          markerList.value.push(marker);
+          // (map as any).addOverLay(label);// 将标注添加到地图中
+          // labelList.value.push(label);
+        }
+      })
+    }
   }
 }
 
+// 清空地图标点
+function delMapInfo() {
+  // 删除已有标点
+  if (markerList.value.length > 0) {
+    for (let i = 0; i < markerList.value.length; i++) {
+      (map as any).removeOverLay(markerList.value[i]);
+    }
+    markerList.value = [];
+  }
+  if (labelList.value.length > 0) {
+    for (let i = 0; i < labelList.value.length; i++) {
+      (map as any).removeOverLay(labelList.value[i]);
+    }
+    labelList.value = [];
+  }
+}
 
 // 天地图按缩放基本计算图标与文本的大小与锚点偏移值
 function computeMarkerSize(zoomLevel: any) {
@@ -229,10 +380,21 @@ function computeMarkerSize(zoomLevel: any) {
   let newIconSize = Math.min(Math.max(zoomLevel * 3, 15), 45);
   // 计算新的icon锚点位置
   let iconAnchor = new T.Point(15 * (newIconSize / 45), 30 * (newIconSize / 45));
+// 计算新的偏移量,保持 label 居中且不超过初始值
+  let offsetX = -30 + ((newIconSize - 45) / 3);
+  let offsetY = 30 + ((newIconSize - 45) / 3);
+  // 确保偏移量不超过初始值
+  offsetX = Math.max(offsetX, -30);
+  offsetY = Math.min(offsetY, 30);
+  // 更新 label 的偏移量
+  let newOffset = new T.Point(offsetX, offsetY);
+  let fontSize = Math.min(12, Math.max(8, 12 - (45 - newIconSize) / 3))
 
   return {
     iconSize: newIconSize,
     iconAnchor,
+    labelOffset: newOffset,
+    fontSize
   }
 }
 
@@ -250,10 +412,28 @@ function siteMouseenter(site: any) {
   nowMouseenterSite.value = site;
 }
 
+// 选择站点人员
+function checkSiteUser(siteUser: any) {
+  nowCheckSiteUser.value = JSON.parse(JSON.stringify(siteUser))
+  if (siteUser.longitude && siteUser.latitude) {
+    // 设置地图中心点
+    (map as any).centerAndZoom(new T.LngLat(siteUser.longitude, siteUser.latitude), 14);
+  } else if (siteUser.siteLongitude && siteUser.siteLatitude) {
+    // 设置地图中心点
+    (map as any).centerAndZoom(new T.LngLat(siteUser.siteLongitude, siteUser.siteLatitude), 14);
+  }
+}
+
+// 鼠标经过事件
+function siteUserMouseenter(siteUser: any) {
+  nowMouseenterSite.value = siteUser;
+}
+
 onMounted(() => {
   initMap();
   getRegionList();
   onSearch();
+  getAllSites();
 })
 </script>
 
@@ -280,12 +460,12 @@ export default {
   }
 
   .site-search-data-box {
-    width: 300px;
+    width: 360px;
     position: absolute;
     top: 15px;
     bottom: 15px;
     left: 15px;
-    right: 330px;
+    right: 390px;
     z-index: 110;
 
     .search-input-box {
@@ -305,7 +485,7 @@ export default {
         display: flex;
         align-items: center;
         background-color: white;
-        padding: 8px 5px;
+        padding: 5px;
         margin-bottom: 10px;
         border-radius: 10px;
       }