index.vue 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472
  1. <template>
  2. <view class="map-box">
  3. <search ref="searchRef" @handleSearch="handleSearch" v-if="showMap" />
  4. <tiandituMap ref="tiandituMapRefs" @handleSearch="$refs.searchRef.handleSearch()" @clickMap="handleClickMap"
  5. @moveMap="moveMapSearch" @onLoadTianDiTu="initMaps" @onSelect="selectPoint" :apiKey="apiKey"
  6. @handleMapSite="handleMapSite">
  7. </tiandituMap>
  8. <!-- <Touchbox ref="TouchboxRef" :zIndex="1001"
  9. :minHeight="0.35" :maxHeight="0.8" :touchHeight="64" @currentHeight="setTouchHeight"
  10. @maxtHeight="setScrollMaxHeight">
  11. </Touchbox> -->
  12. <Touchbox ref="TouchboxRef" :maxHeight="0.8" v-if="showMap && siteListArr && siteListArr.length > 0" :zIndex="1001" @currentHeight="e => TouchHeight = e">
  13. <scroll-view :style="{'height':TouchHeight - 15 +'px' }" scroll-y="true" :show-scrollbar="false">
  14. <template v-for="item in siteListArr">
  15. <siteListModel :info="item" @checkSiteDetails="checkSiteDetails" />
  16. </template>
  17. </scroll-view>
  18. </Touchbox>
  19. <siteDetails ref="siteDetailsRef" />
  20. </view>
  21. </template>
  22. <script>
  23. import tools from '@/components/tiandituMap/tools.js'
  24. import search from "./model/search.vue"
  25. import siteListModel from "./model/siteList.vue";
  26. import { getMapCenterPoint_Api, getMapList_Api } from "@/api/map.js"
  27. import siteDetails from "./model/siteDetails.vue"
  28. import $config from "@/config/index.js"
  29. import { EventBus } from "@/utils/vueBus.js"
  30. import { getLocation, throttle } from "@/utils/tool.js"
  31. let mapThat = this;
  32. export default {
  33. name: 'tdtmap',
  34. components: {
  35. search,
  36. siteListModel,
  37. siteDetails
  38. },
  39. data() {
  40. return {
  41. mapThat: this,
  42. showMap: false,
  43. longitude: undefined,
  44. latitude: undefined,
  45. apiKey: $config.tianKey,
  46. winWidth: 0,
  47. winHeight: 0,
  48. winTop: 0,
  49. datalist: [],
  50. startY: 0,
  51. selectItem: {},
  52. iStatusBarHeight: 0,
  53. siteListArr: [],
  54. TouchHeight: 0,
  55. }
  56. },
  57. created() {
  58. mapThat = this;
  59. getLocation();
  60. this.getMapCenterPoint()
  61. },
  62. mounted() {
  63. this.disableScroll()
  64. },
  65. beforeDestroy() {
  66. try {
  67. document.removeEventListener('touchmove');
  68. document.body.removeEventListener('mousewheel');
  69. document.body.removeEventListener('DOMMouseScroll');
  70. document.removeEventListener('onmousewheel', function() {
  71. window.event.returnValue = false;
  72. });
  73. } catch (error) {
  74. //TODO handle the exception
  75. }
  76. },
  77. watch: {
  78. siteListArr: {
  79. handler(newArr) {
  80. try {
  81. this.$refs.tiandituMapRefs.clearIcon().then(res => {
  82. this.$nextTick(() => {
  83. (newArr || []).forEach((el, index) => {
  84. const { longitude, latitude, mapTypeIcon } = el
  85. this.$refs.tiandituMapRefs.setIcon(longitude, latitude, false,
  86. mapTypeIcon,
  87. el);
  88. })
  89. })
  90. });
  91. } catch (error) {}
  92. },
  93. deep: true
  94. }
  95. },
  96. methods: {
  97. disableScroll() {
  98. if (typeof window.addEventListener === 'function') {
  99. document.addEventListener('touchmove', function(e) {
  100. e.preventDefault();
  101. }, { passive: false });
  102. document.body.addEventListener('mousewheel', function(e) {
  103. e.preventDefault();
  104. });
  105. document.body.addEventListener('DOMMouseScroll', function(e) {
  106. e.preventDefault();
  107. });
  108. } else {
  109. document.attachEvent('onmousewheel', function() {
  110. window.event.returnValue = false;
  111. });
  112. }
  113. },
  114. // 点击地图
  115. handleClickMap() {
  116. if (this.$refs.TouchboxRef) {
  117. this.$refs.TouchboxRef.concealList()
  118. }
  119. },
  120. // 点击地图标注点位
  121. handleMapSite(parmas = {}) {
  122. const { Lng, Lat } = parmas;
  123. const item = (this.siteListArr || []).find(el => el.longitude == Lng && el.latitude == Lat);
  124. this.checkSiteDetails(item)
  125. },
  126. // 查看点位详情
  127. checkSiteDetails(info) {
  128. if (info) {
  129. this.$refs.tiandituMapRefs.Trenderjs.SelectedDot(info)
  130. // EventBus.$emit('TianDiTuSite', info)
  131. this.handleClickMap();
  132. this.$refs.siteDetailsRef.openDetails(info)
  133. }
  134. },
  135. // 获取地图中心点
  136. getMapCenterPoint() {
  137. uni.showLoading()
  138. this.showMap = false;
  139. getMapCenterPoint_Api().then(res => {
  140. const { longitude, latitude, mapTypeIcon } = res || {};
  141. this.longitude = longitude;
  142. this.latitude = latitude;
  143. this.open(longitude, latitude, mapTypeIcon);
  144. }).catch(err => { this.open(null, null) }).finally(() => {
  145. uni.hideLoading()
  146. })
  147. },
  148. moveMapSearch(parms) {
  149. const { Lng, Lat } = parms;
  150. this.longitude = Lng;
  151. this.latitude = Lat;
  152. this.$refs.searchRef.handleSearch()
  153. // console.log("moveMapSearch", Lng, Lat)
  154. },
  155. handleSearch(val = {}) {
  156. const parms = {
  157. ...val,
  158. longitude: this.longitude,
  159. latitude: this.latitude,
  160. radius: 5000
  161. };
  162. getMapList_Api(parms).then(res => {
  163. if (!res || res.length === 0) {
  164. uni.showToast({
  165. title: "当前区域无办理点位",
  166. icon: 'none'
  167. })
  168. }
  169. this.siteListArr = res || [];
  170. }).catch(err => {
  171. this.siteListArr = [];
  172. }).finally(() => {
  173. clearTimeout(this.SearchTimeout)
  174. this.SearchTimeout = null;
  175. })
  176. },
  177. // //普通搜索
  178. // handleSearch(val = {}) {
  179. // const parms = {
  180. // ...val,
  181. // longitude: this.longitude,
  182. // latitude: this.latitude,
  183. // radius: 5000
  184. // };
  185. // getMapList_Api(parms).then(res => {
  186. // if (!res || res.length === 0) {
  187. // uni.showToast({
  188. // title: "当前区域无办理点位",
  189. // icon: 'none'
  190. // })
  191. // }
  192. // this.siteListArr = res || [];
  193. // }).catch(err => {
  194. // this.siteListArr = [];
  195. // })
  196. // },
  197. open(lon, lat, mapTypeIcon) {
  198. if (lon && lat) {
  199. this.$nextTick(() => {
  200. this.$refs.tiandituMapRefs.initCharts(lon, lat, mapTypeIcon)
  201. this.showMap = true;
  202. })
  203. } else {
  204. uni.showModal({
  205. title: '提示',
  206. content: '地图中心点获取错误,请联系管理员!',
  207. success: res => {
  208. // console.log("showModal == ", res)
  209. if (res.confirm) {}
  210. }
  211. })
  212. }
  213. },
  214. close() {
  215. this.visible = false
  216. },
  217. onConfirm() {
  218. if (Object.keys(this.selectItem).length) {
  219. this.visible = false
  220. this.$emit('onSelect', this.selectItem)
  221. } else {
  222. tools.createMessage('请选择位置')
  223. }
  224. },
  225. upDateLonLat(lon, lat) {
  226. if (lon && lat) {
  227. this.$refs.tiandituMapRefs.upDataCharts(lon, lat)
  228. } else {
  229. console.error('请传入lon, lat')
  230. }
  231. },
  232. tianidtuSearch(value) {
  233. if (value.city) {
  234. this.cityInfoSearch(value)
  235. } else {
  236. this.infoSearch(value)
  237. }
  238. },
  239. async infoSearch(value) { // 地理编码查询
  240. let params = {
  241. ds: {
  242. "keyWord": value.keyword,
  243. },
  244. tk: this.apiKey,
  245. }
  246. let resData = await tools.createRequest('https://api.tianditu.gov.cn/geocoder', params, true)
  247. if (resData.status === '0') {
  248. const location = resData.location
  249. const formateOne = tools.formatterAdressLocation(resData, 3)
  250. this.datalist = [formateOne]
  251. this.selectItem = datalist
  252. this.$refs.tiandituMapRefs.upDataCharts(location.lon, location.lat)
  253. }
  254. },
  255. async cityInfoSearch(value) { // 地名搜索2.0
  256. let params = {
  257. postStr: {
  258. "keyWord": value.keyword,
  259. "queryType": 12,
  260. "start": 0,
  261. "count": 10,
  262. "specify": value.city.value
  263. },
  264. type: 'query',
  265. tk: this.apiKey,
  266. }
  267. let resData = await tools.createRequest('https://api.tianditu.gov.cn/v2/search', params, true)
  268. if (resData.status.infocode === 1000) {
  269. const {
  270. pois: aPoints,
  271. count
  272. } = resData
  273. if (count === '0' || !aPoints || !aPoints.length) {
  274. return tools.createMessage('没有找到该地址')
  275. }
  276. const {
  277. pois,
  278. keyWord,
  279. lonlat
  280. } = aPoints[0]
  281. const formateData = aPoints.map((item) => tools.formatterAdressLocation(item, 2))
  282. this.datalist = formateData
  283. this.selectItem = formateData[0]
  284. const [lon, lat] = lonlat.split(',')
  285. this.$refs.tiandituMapRefs.upDataCharts(lon, lat)
  286. } else {
  287. tools.createMessage('数据异常', 1000, false, 'error')
  288. }
  289. },
  290. selectListItem(item) {
  291. this.$refs.tiandituMapRefs.upDataCharts(item.location.lon, item.location.lat)
  292. },
  293. selectPoint(e) {
  294. this.domMinHeight = '0vh'
  295. this.datalist = [e]
  296. this.selectItem = e
  297. },
  298. initMaps() {
  299. console.warn('--------天地图加载完成--------');
  300. this.$emit('onLoad')
  301. },
  302. // start(e) {
  303. // const clientY = e.changedTouches[0].clientY
  304. // this.startY = clientY
  305. // },
  306. // end(e) {
  307. // const transformY = e.changedTouches[0].clientY - this.startY;
  308. // switch (true) {
  309. // case transformY > 50:
  310. // console.log('下划')
  311. // this.domMaxHeight = '20vh'
  312. // this.domMinHeight = '0vh'
  313. // break;
  314. // case transformY < -50:
  315. // console.log('上划')
  316. // this.domMaxHeight = '50vh'
  317. // this.domMinHeight = '50vh'
  318. // break;
  319. // default:
  320. // break;
  321. // }
  322. // },
  323. selectCard(item) {
  324. this.domMaxHeight = '20vh'
  325. this.domMinHeight = '0vh'
  326. this.selectItem = item
  327. this.selectListItem(item)
  328. },
  329. setTouchHeight(val) {
  330. // console.log('setScrollHeight = ', val)
  331. // 实时返回的滑动组件高度
  332. this.TouchHeight = val;
  333. },
  334. setScrollMaxHeight(val) {
  335. //最大高度
  336. this.scrollMaxHeight = val;
  337. },
  338. }
  339. }
  340. </script>
  341. <style scope>
  342. .map-box {
  343. width: 100vw;
  344. height: 100vh;
  345. /* position: fixed;
  346. left: 0;
  347. top:0;
  348. right: 0;
  349. bottom: 0; */
  350. }
  351. .mask {
  352. /* overflow: hidden; */
  353. position: fixed;
  354. left: 0;
  355. background-color: #FFFFFF;
  356. z-index: 399;
  357. }
  358. /* footer */
  359. .list-boxd {
  360. position: absolute;
  361. bottom: 0;
  362. left: 0;
  363. z-index: 401;
  364. right: 0;
  365. border-radius: 14px 14px 0 0;
  366. background: #FFFFFF;
  367. transition: all 1s;
  368. }
  369. .list-header {
  370. height: 20px;
  371. position: relative;
  372. border-bottom: 1px solid #f3f4f6;
  373. cursor: pointer;
  374. }
  375. .list-header::after {
  376. position: absolute;
  377. left: 50%;
  378. top: 50%;
  379. transform: translate(-50%, -50%);
  380. content: '';
  381. height: 6px;
  382. width: 60px;
  383. border-top: 1px solid #e8e8e8;
  384. border-bottom: 1px solid #e8e8e8;
  385. }
  386. .list-content {
  387. max-height: 50vh;
  388. overflow-y: scroll;
  389. }
  390. .card {
  391. min-height: 44px;
  392. padding: 12px;
  393. position: relative;
  394. display: flex;
  395. justify-content: space-between;
  396. align-items: center;
  397. }
  398. .card-left {
  399. display: flex;
  400. flex-direction: column;
  401. justify-content: center;
  402. }
  403. .card-right {
  404. padding-right: 10px;
  405. }
  406. .arrow {
  407. border-top: 2px solid #666666;
  408. border-right: 2px solid #666666;
  409. width: 10px;
  410. height: 10px;
  411. transform: rotate(45deg);
  412. }
  413. .card:active {
  414. background-color: #f3f4f6;
  415. }
  416. .card::after {
  417. position: absolute;
  418. content: '';
  419. bottom: 0;
  420. height: 1px;
  421. background-color: #e8e8e8;
  422. width: 90%;
  423. }
  424. .card:last-child::after {
  425. height: 0;
  426. background-color: #FFFFFF;
  427. }
  428. .card-title {
  429. font-size: 18px;
  430. }
  431. .card-text {
  432. color: #e8e8e8;
  433. font-size: 13px;
  434. }
  435. </style>