cs.vue 10 KB

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