siteDataMap.vue 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793
  1. <template>
  2. <div>
  3. <div class="map-box">
  4. <!-- 地图 -->
  5. <div
  6. id="mapDiv"
  7. ></div>
  8. <!-- 驿站查询与展示 -->
  9. <div class="site-search-data-box">
  10. <!-- 查询表单区域 -->
  11. <div class="search-input-box">
  12. <a-select
  13. v-model:value="searchType"
  14. @change="searchTypeChange"
  15. >
  16. <a-select-option value="site">找驿站</a-select-option>
  17. <a-select-option value="siteUser">找人员</a-select-option>
  18. </a-select>
  19. <a-input-search
  20. v-model:value="siteSearchParam.siteName"
  21. :placeholder="searchType == 'site' ? '请输入站点名称' : '请输入人员名称'"
  22. enter-button
  23. :loading="searchLoading"
  24. style="width: 77%"
  25. @search="onSearch"
  26. />
  27. </div>
  28. <!-- 数据列表 -->
  29. <div class="select-data-box">
  30. <!-- 下拉框查询部分 -->
  31. <div class="select-input-box">
  32. <span class="cursor-pointer" style="width: 35px;padding: 7px 0;text-align: center"
  33. @click="searchAll">全部</span>
  34. <a-select
  35. style="width: 30%;"
  36. v-model:value="siteSearchParam.regionCode"
  37. :allow-clear="true"
  38. :options="regionList"
  39. :field-names="{ label: 'name', value: 'code' }"
  40. :bordered="false"
  41. placeholder="所属县区"
  42. @change="changeRegion"
  43. >
  44. </a-select>
  45. <a-select
  46. style="width: 30%;"
  47. v-model:value="siteSearchParam.streetCode"
  48. :options="streetList"
  49. :field-names="{ label: 'name', value: 'code' }"
  50. :allow-clear="true"
  51. :bordered="false"
  52. placeholder="所属街道"
  53. @change="onSearch"
  54. >
  55. </a-select>
  56. <a-select
  57. style="width: 30%;"
  58. v-model:value="siteSearchParam.siteID"
  59. :options="siteDicList"
  60. :field-names="{ label: 'siteName', value: 'siteID' }"
  61. :allow-clear="true"
  62. :bordered="false"
  63. :disabled="searchType == 'site'"
  64. placeholder="所属驿站"
  65. @change="onSearch"
  66. >
  67. </a-select>
  68. </div>
  69. <div class="list-box">
  70. <!-- 驿站数据 -->
  71. <div v-if="searchType == 'site' && siteList.length > 0" class="site-data"
  72. :class="{'check-site':nowCheckSite.siteID == site.siteID || nowMouseenterSite.siteID == site.siteID}"
  73. v-for="(site,siteIndex) in siteList"
  74. :key="siteIndex"
  75. @click="checkSite(site)"
  76. @mouseenter="siteMouseenter(site)"
  77. @mouseleave="siteMouseenter({siteID:null})"
  78. >
  79. <p class="site-name">
  80. {{ site.siteName }}
  81. </p>
  82. <p class="label-text">
  83. 驿站编号:{{ site.siteCode }}
  84. </p>
  85. <p class="label-text">
  86. 所属县区:{{ site.regionName }}
  87. </p>
  88. </div>
  89. <!-- 驿站人员数据 -->
  90. <div v-if="searchType == 'siteUser' && siteUserList.length > 0" class="site-data"
  91. :class="{'check-site':nowCheckSiteUser.siteUserID == siteUser.siteUserID || nowMouseenterSiteUser.siteUserID == siteUser.siteUserID}"
  92. v-for="(siteUser,siteIndex) in siteUserList"
  93. :key="siteIndex"
  94. @click="checkSiteUser(siteUser)"
  95. @mouseenter="siteUserMouseenter(siteUser)"
  96. @mouseleave="siteUserMouseenter({siteUserID:null})"
  97. >
  98. <p class="site-name">
  99. {{ siteUser.siteUserName }}
  100. </p>
  101. <p class="label-text">
  102. 工号:{{ siteUser.userNo }}
  103. </p>
  104. <p class="label-text">
  105. 联系电话:{{ siteUser.mobile }}
  106. </p>
  107. <p class="label-text">
  108. 所属驿站:{{ siteUser.siteName }}
  109. </p>
  110. </div>
  111. <div
  112. v-if="(searchType == 'site' && siteList.length == 0) || (searchType == 'siteUser' && siteUserList.length == 0)"
  113. class="empty-box">
  114. <a-empty/>
  115. </div>
  116. </div>
  117. </div>
  118. <!-- 分页控件 -->
  119. <div class="pagination-box">
  120. <span>共{{ paginationTotal }}{{ searchType == 'site' ? '个' : '人' }}</span>
  121. <a-pagination v-model:current="siteSearchParam.pageIndex" :total="paginationTotal"
  122. v-model:pageSize="siteSearchParam.pageSize" :disabled="searchLoading"
  123. show-less-items @change="onSearch" simple :show-size-changer="false"/>
  124. </div>
  125. </div>
  126. <!-- 驿站详情 -->
  127. <div class="site-info-box" v-if="searchType == 'site' && nowCheckSite.siteID != null">
  128. <p class="font-size-16 font-weight-600 margin-bottom-10 text-align-center">
  129. {{ nowCheckSite.siteName }}
  130. ({{ nowCheckSite.siteCode }})
  131. </p>
  132. <div class="w-full flex-box items-start margin-bottom-3">
  133. <img :src="th" alt="" style="width: 23px; height: 20px;" class="margin-right-3"/>
  134. <span class="font-size-14 white-space-normal">{{ nowCheckSite.detailAddress }}</span>
  135. </div>
  136. <div class="avt-info margin-top-10">
  137. <img :src="avtO1" alt="">
  138. <div>
  139. <p>{{ nowCheckSite.fzrName }}(站长)</p>
  140. <p>{{ nowCheckSite.fzrMobile }}</p>
  141. </div>
  142. </div>
  143. <a-divider></a-divider>
  144. <div class="w-full flex-box font-weight-800">
  145. <div class="left-item-flag"></div>
  146. 建站以来累计
  147. </div>
  148. <div class="w-full margin-bottom-10 grid-cols-2 text-align-center padding-top-10 gap-y-1">
  149. <div>
  150. <p class="font-size-18 font-weight-700 ">{{ siteDataCount.allCount.companyCount }}</p>
  151. <p class="font-size-12 font-weight-500">服务企业</p>
  152. </div>
  153. <div>
  154. <p class="font-size-18 font-weight-700 ">{{ siteDataCount.allCount.postCount }}</p>
  155. <p class="font-size-12 font-weight-500">收集岗位</p>
  156. </div>
  157. <div>
  158. <p class="font-size-18 font-weight-700 ">{{ siteDataCount.allCount.jobUserCount }}</p>
  159. <p class="font-size-12 font-weight-500">服务求职人员(人次)</p>
  160. </div>
  161. <div>
  162. <p class="font-size-18 font-weight-700 ">{{ siteDataCount.allCount.jobFairsCount }}</p>
  163. <p class="font-size-12 font-weight-500">开展公共就业服务活动(场)</p>
  164. </div>
  165. </div>
  166. <div class="w-full flex-box font-weight-800">
  167. <div class="left-item-flag"></div>
  168. 本年以来累计
  169. </div>
  170. <div class="w-full margin-bottom-10 grid-cols-2 text-align-center padding-top-10 gap-y-1">
  171. <div>
  172. <p class="font-size-18 font-weight-700 ">{{ siteDataCount.yearCount.companyCount }}</p>
  173. <p class="font-size-12 font-weight-500">服务企业</p>
  174. </div>
  175. <div>
  176. <p class="font-size-18 font-weight-700 ">{{ siteDataCount.yearCount.postCount }}</p>
  177. <p class="font-size-12 font-weight-500">收集岗位</p>
  178. </div>
  179. <div>
  180. <p class="font-size-18 font-weight-700 ">{{ siteDataCount.yearCount.jobUserCount }}</p>
  181. <p class="font-size-12 font-weight-500">服务求职人员(人次)</p>
  182. </div>
  183. <div>
  184. <p class="font-size-18 font-weight-700 ">{{ siteDataCount.yearCount.jobFairsCount }}</p>
  185. <p class="font-size-12 font-weight-500">开展公共就业服务活动(场)</p>
  186. </div>
  187. </div>
  188. <div class="w-full flex-box font-weight-800">
  189. <div class="left-item-flag"></div>
  190. 本月以来累计
  191. </div>
  192. <div class="w-full margin-bottom-10 grid-cols-2 text-align-center padding-top-10 gap-y-1">
  193. <div>
  194. <p class="font-size-18 font-weight-700 ">{{ siteDataCount.monthCount.companyCount }}</p>
  195. <p class="font-size-12 font-weight-500">服务企业</p>
  196. </div>
  197. <div>
  198. <p class="font-size-18 font-weight-700 ">{{ siteDataCount.monthCount.postCount }}</p>
  199. <p class="font-size-12 font-weight-500">收集岗位</p>
  200. </div>
  201. <div>
  202. <p class="font-size-18 font-weight-700 ">{{ siteDataCount.monthCount.jobUserCount }}</p>
  203. <p class="font-size-12 font-weight-500">服务求职人员(人次)</p>
  204. </div>
  205. <div>
  206. <p class="font-size-18 font-weight-700 ">{{ siteDataCount.monthCount.jobFairsCount }}</p>
  207. <p class="font-size-12 font-weight-500">开展公共就业服务活动(场)</p>
  208. </div>
  209. </div>
  210. </div>
  211. <!-- 驿站人员信息详情 -->
  212. <div class="site-user-info-box" v-if="searchType == 'siteUser' && nowCheckSiteUser.siteUserID != null">
  213. <div class="user-info-box margin-bottom-10">
  214. <p class="font-size-18 margin-bottom-8" style="font-weight: 600">
  215. {{ nowCheckSiteUser.siteUserName }}
  216. </p>
  217. <p class="label-text font-size-14 margin-bottom-3">
  218. 工号:{{ nowCheckSiteUser.userNo }}
  219. </p>
  220. <p class="label-text font-size-14 margin-bottom-3">
  221. 联系电话:{{ nowCheckSiteUser.mobile }}
  222. </p>
  223. <p class="label-text font-size-14 margin-bottom-3">
  224. 所属驿站:{{ nowCheckSiteUser.siteName }}
  225. </p>
  226. </div>
  227. <div class="data-count-box">
  228. <p class="font-size-18 margin-bottom-8" style="font-weight: 600">
  229. 工作情况
  230. </p>
  231. <p class="label-text font-size-14 margin-bottom-3">
  232. 企业登记数:{{ siteUserDataCount.companyCount }}家
  233. </p>
  234. <p class="label-text font-size-14 margin-bottom-3">
  235. 岗位登记数:{{ siteUserDataCount.postCount }}个
  236. </p>
  237. <p class="label-text font-size-14 margin-bottom-3">
  238. 求职人员登记数:{{ siteUserDataCount.jobUserCount }}人
  239. </p>
  240. </div>
  241. </div>
  242. </div>
  243. </div>
  244. </template>
  245. <script setup lang="ts">
  246. import huiZhouGeoJSON from "./geo"
  247. import {setBoundary} from "@/utils/position";
  248. import {onMounted, reactive, ref} from "vue";
  249. import type {SelectProps} from "ant-design-vue";
  250. import {getRegionCodeList, getStreetCodeList} from "@/api/system/area/index";
  251. import {findSiteDataCount, getDataMapList, getSiteList} from "@/api/baseSettings/siteInfo";
  252. import thIcon from "@/assets/images/blueTh1.png"
  253. import {findUserDataCount, getSiteUserDataMapList} from "@/api/baseSettings/userInfo";
  254. import avtO1 from "@/assets/images/avt01.png";
  255. import th from "@/assets/images/th1.png";
  256. import dayjs from "dayjs";
  257. const T = (window as any).T;
  258. const zoom = 9;
  259. let map = null;
  260. // 天地图默认中心点坐标
  261. const centerLngLat = new T.LngLat(114.416110, 23.111582);
  262. // 地图标记点
  263. let markerList = ref<Array<any>>([]);
  264. let labelList = ref<Array<any>>([]);
  265. // 查询类型
  266. const searchType = ref("site")
  267. // 驿站查询数据
  268. const siteSearchParam = reactive({
  269. pageIndex: 1,
  270. pageSize: 100,
  271. siteName: "",
  272. regionCode: null,
  273. streetCode: null,
  274. siteID: null,
  275. });
  276. // 驿站数据
  277. const siteList = ref<Array<any>>([])
  278. // 驿站人员数据
  279. const siteUserList = ref<Array<any>>([]);
  280. // 查询动画
  281. const searchLoading = ref(false);
  282. // 驿站总条数
  283. const paginationTotal = ref(0)
  284. // 县区数据
  285. const regionList = ref<SelectProps['options']>();
  286. // 街道数据
  287. const streetList = ref<SelectProps['options']>();
  288. // 驿站下拉框数据
  289. const siteDicList = ref<any>([]);
  290. // 选中的站点
  291. const nowCheckSite = ref<any>({siteID: null})
  292. // 鼠标经过的站点
  293. const nowMouseenterSite = ref<any>({siteID: null});
  294. // 驿站的业务数据
  295. const siteDataCount = reactive({
  296. allCount: {
  297. companyCount: 0,
  298. postCount: 0,
  299. jobUserCount: 0,
  300. jobFairsCount: 0,
  301. },
  302. yearCount: {
  303. companyCount: 0,
  304. postCount: 0,
  305. jobUserCount: 0,
  306. jobFairsCount: 0,
  307. },
  308. monthCount: {
  309. companyCount: 0,
  310. postCount: 0,
  311. jobUserCount: 0,
  312. jobFairsCount: 0,
  313. }
  314. })
  315. // 选中的站点
  316. const nowCheckSiteUser = ref<any>({siteUserID: null})
  317. // 鼠标经过的站点
  318. const nowMouseenterSiteUser = ref<any>({siteUserID: null});
  319. // 驿站人员的业务数据
  320. const siteUserDataCount = ref<any>({})
  321. // 地图初始化
  322. const initMap = () => {
  323. // 初始化容器
  324. map = new T.Map('mapDiv');
  325. if (map != null) {
  326. // 设置地图显示中心点为惠州市人民政府
  327. (map as any).centerAndZoom(centerLngLat, zoom);
  328. (map as any).setMinZoom(5);
  329. (map as any).setMaxZoom(14);
  330. // 地图缩放监听事件
  331. (map as any).addEventListener("zoomend", function () {
  332. setSiteMarker(false);
  333. });
  334. }
  335. // 设置城市边界
  336. setBoundary(map, T, huiZhouGeoJSON);
  337. };
  338. // 查询驿站
  339. function onSearch() {
  340. searchLoading.value = true;
  341. if (searchType.value == "site") {
  342. getDataMapList(siteSearchParam).then((result: any) => {
  343. siteList.value = result.list;
  344. siteList.value.forEach((site: any) => {
  345. if (site.siteUsers) {
  346. site.siteUsers = site.siteUsers.split(',');
  347. } else {
  348. site.siteUsers = []
  349. }
  350. })
  351. paginationTotal.value = result.total;
  352. // 地图绘制
  353. setSiteMarker(true)
  354. }).finally(() => {
  355. searchLoading.value = false;
  356. })
  357. } else {
  358. let params = {
  359. pageIndex: siteSearchParam.pageIndex,
  360. pageSize: 100,
  361. siteUserName: siteSearchParam.siteName,
  362. regionCode: siteSearchParam.regionCode,
  363. streetCode: siteSearchParam.streetCode,
  364. siteID: siteSearchParam.siteID
  365. }
  366. getSiteUserDataMapList(params).then((result: any) => {
  367. siteUserList.value = result.list;
  368. paginationTotal.value = result.total;
  369. // 地图绘制
  370. setSiteMarker(true);
  371. }).finally(() => {
  372. searchLoading.value = false;
  373. })
  374. }
  375. }
  376. // 查询全部
  377. function searchAll() {
  378. siteSearchParam.pageIndex = 1;
  379. siteSearchParam.pageSize = 100;
  380. siteSearchParam.siteName = "";
  381. siteSearchParam.regionCode = null;
  382. siteSearchParam.streetCode = null;
  383. siteSearchParam.siteID = null;
  384. onSearch();
  385. }
  386. // 查询类型切换事件
  387. function searchTypeChange() {
  388. // 清空数据
  389. nowCheckSite.value = {siteID: null};
  390. nowCheckSiteUser.value = {siteUserID: null};
  391. onSearch();
  392. delMapInfo();
  393. }
  394. // 查询县区
  395. const getRegionList = async function () {
  396. regionList.value = await getRegionCodeList();
  397. }
  398. // 县区变更事件-查询街道数据
  399. const changeRegion = async function () {
  400. if (siteSearchParam.regionCode) {
  401. streetList.value = await getStreetCodeList(siteSearchParam.regionCode);
  402. getSiteList({pageIndex: 1, pageSize: 9999, regionCode: siteSearchParam.regionCode}).then((result: any) => {
  403. siteDicList.value = result.list;
  404. })
  405. } else {
  406. siteDicList.value = [];
  407. streetList.value = [];
  408. }
  409. onSearch();
  410. }
  411. function setSiteMarker(setCenter: boolean) {
  412. delMapInfo();
  413. if (setCenter) {
  414. // 设置中心点
  415. (map as any).centerAndZoom(centerLngLat, zoom);
  416. }
  417. if (siteList.value.length > 0 || siteUserList.value.length > 0) {
  418. let zoomLevel = (map as any).getZoom();
  419. const sizeData = computeMarkerSize(zoomLevel);
  420. // 设置图标
  421. const icon = new T.Icon({
  422. iconUrl: thIcon,
  423. iconSize: new T.Point(sizeData.iconSize, sizeData.iconSize),
  424. iconAnchor: sizeData.iconAnchor
  425. })
  426. if (searchType.value == "site") {
  427. // 解析站点数据,在地图中标记
  428. siteList.value.forEach((item: any) => {
  429. if (item.siteLongitude && item.siteLatitude) {
  430. const point = new T.LngLat(item.siteLongitude, item.siteLatitude)
  431. const marker = new T.Marker(point, {icon: icon}); // 创建标注
  432. // 添加点击事件
  433. marker.addEventListener('click', () => {
  434. checkSite(item);
  435. // marker.openInfoWindow(markerInfoWin);
  436. });
  437. let winHtml = `
  438. <div >
  439. <p style="line-height: 12px; font-size: 14px; font-weight: 600">${item.siteName}(${item.siteCode})</p>
  440. <span style="line-height: 12px;">所属区县:${item.regionName}</span>
  441. <br>
  442. <span style="line-height: 12px;">运营公司:${item.institutionName}</span>
  443. <br>
  444. <span style="line-height: 12px;">运营公司地址:${item.institutionAddress}</span>
  445. <br>
  446. <span style="line-height: 12px;">联系人:${item.institutionFzrName}</span>
  447. <br>
  448. <span style="line-height: 12px;">联系电话:${item.institutionFzrMobile}</span>
  449. </div>
  450. `;
  451. let markerInfoWin = new T.InfoWindow(winHtml, {autoPan: true, offset: new T.Point(3, 7)});
  452. // 添加鼠标经过事件
  453. marker.addEventListener('mouseover', () => {
  454. marker.openInfoWindow(markerInfoWin);
  455. });
  456. marker.addEventListener('mouseout', () => {
  457. marker.closeInfoWindow();
  458. });
  459. (map as any).addOverLay(marker);// 将标注添加到地图中
  460. markerList.value.push(marker);
  461. }
  462. })
  463. } else {
  464. // 解析人员数据
  465. siteUserList.value.forEach((item: any) => {
  466. if (item.longitude && item.latitude) {
  467. const point = new T.LngLat(item.longitude, item.latitude)
  468. const marker = new T.Marker(point, {icon: icon}); // 创建标注
  469. // 添加点击事件
  470. marker.addEventListener('click', () => {
  471. checkSiteUser(item);
  472. });
  473. (map as any).addOverLay(marker);// 将标注添加到地图中
  474. markerList.value.push(marker);
  475. } else if (item.siteLongitude && item.siteLatitude) {
  476. const point = new T.LngLat(item.siteLongitude, item.siteLatitude);
  477. const marker = new T.Marker(point, {icon: icon}); // 创建标注
  478. // 添加点击事件
  479. marker.addEventListener('click', () => {
  480. checkSiteUser(item);
  481. });
  482. (map as any).addOverLay(marker);// 将标注添加到地图中
  483. markerList.value.push(marker);
  484. }
  485. })
  486. }
  487. }
  488. }
  489. // 清空地图标点
  490. function delMapInfo() {
  491. // 删除已有标点
  492. if (markerList.value.length > 0) {
  493. for (let i = 0; i < markerList.value.length; i++) {
  494. (map as any).removeOverLay(markerList.value[i]);
  495. }
  496. markerList.value = [];
  497. }
  498. if (labelList.value.length > 0) {
  499. for (let i = 0; i < labelList.value.length; i++) {
  500. (map as any).removeOverLay(labelList.value[i]);
  501. }
  502. labelList.value = [];
  503. }
  504. (map as any).closeInfoWindow();
  505. }
  506. // 天地图按缩放基本计算图标与文本的大小与锚点偏移值
  507. function computeMarkerSize(zoomLevel: any) {
  508. // 计算新的icon大小
  509. let newIconSize = Math.min(Math.max(zoomLevel * 2, 10), 15);
  510. // 计算新的icon锚点位置
  511. let iconAnchor = new T.Point(10 * (newIconSize / 30), 20 * (newIconSize / 45));
  512. // 计算新的偏移量,保持 label 居中且不超过初始值
  513. let offsetX = -20 + ((newIconSize - 15) / 2);
  514. let offsetY = 28 + ((newIconSize - 15) / 2);
  515. // 确保偏移量不超过初始值
  516. offsetX = Math.max(offsetX, -20);
  517. offsetY = Math.min(offsetY, 28);
  518. // 更新 label 的偏移量
  519. let newOffset = new T.Point(offsetX, offsetY);
  520. let fontSize = Math.min(8, Math.max(6, 10 - (15 - newIconSize) / 2))
  521. return {
  522. iconSize: newIconSize,
  523. iconAnchor,
  524. labelOffset: newOffset,
  525. fontSize
  526. }
  527. }
  528. // 选择站点
  529. function checkSite(site: any) {
  530. // 查询业务数据数量
  531. let year = dayjs().format("YYYY");
  532. let month = dayjs().format("MM");
  533. // 全部
  534. findSiteDataCount(site.siteID, null, null).then((result: any) => {
  535. siteDataCount.allCount = result;
  536. })
  537. // 当年
  538. findSiteDataCount(site.siteID, year, null).then((result: any) => {
  539. siteDataCount.yearCount = result;
  540. })
  541. // 当月
  542. findSiteDataCount(site.siteID, year, month).then((result: any) => {
  543. siteDataCount.monthCount = result;
  544. })
  545. nowCheckSite.value = JSON.parse(JSON.stringify(site));
  546. // 关闭地图上的其他信息弹窗
  547. (map as any).closeInfoWindow();
  548. if (site.siteLongitude && site.siteLatitude) {
  549. // 设置地图中心点
  550. (map as any).centerAndZoom(new T.LngLat(site.siteLongitude, site.siteLatitude), (map as any).getZoom());
  551. if (searchType.value == 'site') {
  552. let winHtml = `
  553. <div >
  554. <p style="line-height: 12px; font-size: 14px; font-weight: 600">${site.siteName}(${site.siteCode})</p>
  555. <span style="line-height: 12px;">所属区县:${site.regionName}</span>
  556. <br>
  557. <span style="line-height: 12px;">运营公司:${site.institutionName}</span>
  558. <br>
  559. <span style="line-height: 12px;">运营公司地址:${site.institutionAddress}</span>
  560. <br>
  561. <span style="line-height: 12px;">联系人:${site.institutionFzrName}</span>
  562. <br>
  563. <span style="line-height: 12px;">联系电话:${site.institutionFzrMobile}</span>
  564. </div>
  565. `;
  566. (map as any).openInfoWindow(winHtml, new T.LngLat(site.siteLongitude, site.siteLatitude), {
  567. autoPan: true,
  568. maxHeight: 300,
  569. maxWidth: 400,
  570. offset: new T.Point(5, 0)
  571. });
  572. }
  573. }
  574. }
  575. // 鼠标经过事件
  576. function siteMouseenter(site: any) {
  577. nowMouseenterSite.value = site;
  578. }
  579. // 选择站点人员
  580. async function checkSiteUser(siteUser: any) {
  581. await findUserDataCount(siteUser.userID).then((result: any) => {
  582. siteUserDataCount.value = result;
  583. })
  584. nowCheckSiteUser.value = JSON.parse(JSON.stringify(siteUser))
  585. if (siteUser.longitude && siteUser.latitude) {
  586. // 设置地图中心点
  587. (map as any).centerAndZoom(new T.LngLat(siteUser.longitude, siteUser.latitude), (map as any).getZoom());
  588. } else if (siteUser.siteLongitude && siteUser.siteLatitude) {
  589. // 设置地图中心点
  590. (map as any).centerAndZoom(new T.LngLat(siteUser.siteLongitude, siteUser.siteLatitude), (map as any).getZoom());
  591. }
  592. }
  593. // 鼠标经过事件
  594. function siteUserMouseenter(siteUser: any) {
  595. nowMouseenterSite.value = siteUser;
  596. }
  597. onMounted(() => {
  598. initMap();
  599. getRegionList();
  600. onSearch();
  601. })
  602. </script>
  603. <script lang="ts">
  604. // 设置页面名称进行组件缓存
  605. export default {
  606. name: "SiteDataMap"
  607. }
  608. </script>
  609. <style lang="less">
  610. .map-box {
  611. width: 100vw;
  612. height: 100vh;
  613. position: relative;
  614. border: 1px rgba(173, 173, 173, 0.8) solid;
  615. box-sizing: border-box;
  616. #mapDiv {
  617. position: absolute;
  618. width: 100%;
  619. height: 100%;
  620. z-index: 100;
  621. }
  622. .site-search-data-box {
  623. width: 360px;
  624. position: absolute;
  625. top: 15px;
  626. bottom: 5px;
  627. left: 15px;
  628. right: 390px;
  629. z-index: 110;
  630. .search-input-box {
  631. width: 100%;
  632. margin-bottom: 10px;
  633. }
  634. .select-data-box {
  635. height: calc(100% - 95px);
  636. background-color: #F8F8F8;
  637. border-radius: 10px 10px 0 0;
  638. padding: 10px;
  639. .select-input-box {
  640. width: 100%;
  641. display: flex;
  642. align-items: center;
  643. background-color: white;
  644. padding: 5px;
  645. margin-bottom: 10px;
  646. border-radius: 10px;
  647. }
  648. .list-box {
  649. max-height: calc(100% - 60px);
  650. overflow: hidden;
  651. overflow-y: auto;
  652. .site-data {
  653. background-color: white;
  654. border-radius: 10px;
  655. padding: 8px;
  656. cursor: pointer;
  657. margin-bottom: 10px;
  658. box-shadow: 0 5px 5px -5px rgba(0, 0, 0, 0.3);
  659. box-sizing: border-box;
  660. border: 1px solid white;
  661. }
  662. .check-site {
  663. border-color: #007EFF;
  664. }
  665. }
  666. }
  667. }
  668. .site-info-box, .site-user-info-box {
  669. width: 300px;
  670. position: absolute;
  671. top: 15px;
  672. left: calc(100% - 330px);
  673. right: 15px;
  674. bottom: 15px;
  675. z-index: 110;
  676. border-radius: 10px;
  677. background-color: white;
  678. padding: 15px;
  679. }
  680. .pagination-box {
  681. display: flex;
  682. justify-content: center;
  683. align-items: center;
  684. padding: 10px 10px;
  685. background-color: #F8F8F8;
  686. border-radius: 0 0 10px 10px;
  687. }
  688. .empty-box {
  689. width: 100%;
  690. height: 450px;
  691. display: flex;
  692. justify-content: center;
  693. align-items: center;
  694. }
  695. .site-name {
  696. font-size: 14px;
  697. font-weight: 600;
  698. margin-bottom: 8px;
  699. }
  700. .label-text {
  701. font-size: 12px;
  702. color: #737373;
  703. margin-bottom: 3px;
  704. }
  705. .avt-info {
  706. display: flex;
  707. align-items: center;
  708. img {
  709. width: 36px;
  710. height: 36px;
  711. margin-right: 10px;
  712. }
  713. .contact-name {
  714. font-size: 14px;
  715. color: #292934;
  716. }
  717. .contact-mobile {
  718. font-size: 12px;
  719. color: #6A6F75;
  720. }
  721. }
  722. .left-item-flag {
  723. height: 20px;
  724. width: 3px;
  725. border-radius: 8px;
  726. margin-right: 7px;
  727. background: linear-gradient(180deg, #fff, #0094ff);
  728. }
  729. .ant-btn, .ant-input {
  730. border: none !important;
  731. }
  732. input {
  733. height: 32px;
  734. }
  735. .ant-select:not(.ant-select-customize-input) .ant-select-selector,
  736. .ant-select:not(.ant-select-customize-input) .ant-select-selector,
  737. .ant-input-affix-wrapper, .ant-select-selector {
  738. border: none !important;
  739. box-shadow: none !important;
  740. }
  741. .ant-select:not(.ant-select-disabled).ant-select:not(.ant-select-customize-input) > .ant-select-selector {
  742. border-color: transparent;
  743. box-shadow: none;
  744. }
  745. }
  746. </style>