Commit f7230966155a0b8981c2a248a1d2626e4a25548b

Authored by ly525
Committed by 小小鲁班
1 parent b982753a

feat(component): add map component; !#zh: 添加地图组件

front-end/h5/src/components/plugins/lbp-qq-map/README.md 0 → 100644
  1 +# lbp-qq-map
  2 +> luban-h5-plugin-qq-map
  3 +
  4 +为鲁班H5提供腾讯地图支持(https://lbs.qq.com/)
0 \ No newline at end of file 5 \ No newline at end of file
front-end/h5/src/components/plugins/lbp-qq-map/src/Map.js 0 → 100644
  1 +function isScriptLoaded (src) {
  2 + return !!document.querySelector('script[src="' + src + '"]')
  3 +}
  4 +export default {
  5 + map: null,
  6 + load: function (key) {
  7 + return new Promise(function (resolve, reject) {
  8 + const src = 'http://map.qq.com/api/js?v=2.exp&libraries=place&callback=init&key=' + key
  9 + if (isScriptLoaded(src)) {
  10 + resolve(window.qq)
  11 + return
  12 + }
  13 + window.init = function () {
  14 + resolve(window.qq)// 注意这里
  15 + }
  16 + var script = document.createElement('script')
  17 + script.type = 'text/javascript'
  18 + script.src = src
  19 + script.onerror = reject
  20 + document.head.appendChild(script)
  21 + })
  22 + },
  23 + getPosition ({ lat, lng }) {
  24 + return new window.qq.maps.LatLng(lat, lng) // 地图的中心地理坐标
  25 + }
  26 +}
front-end/h5/src/components/plugins/lbp-qq-map/src/index.vue 0 → 100644
  1 +<template>
  2 + <div>
  3 + <div id="qq-map-container" ref="mapElement" style="height: 100%;width: 100%"></div>
  4 + </div>
  5 +</template>
  6 +<script>
  7 +import PropTypes from '@luban-h5/plugin-common-props'
  8 +import Map from './Map'
  9 +import MapMixin from './mixin'
  10 +
  11 +export default {
  12 + // extra.defaultStyle:组件的额外自定义配置,以拖拽组件到画布上为例
  13 + // 按钮默认的样式可能是: { width: 100px, height: 40px }
  14 + // 但地图可能是希望更大一些的默认样式,比如:{ width: 320px, height: 180px }
  15 + // 就可以通过 extra.defaultStyle 来实现自定义样式需求
  16 + extra: {
  17 + defaultStyle: {
  18 + width: 320,
  19 + height: 180
  20 + }
  21 + },
  22 + name: 'lbp-qq-map',
  23 + mixins: [MapMixin], // loadMap、setMarker
  24 + props: {
  25 + labelContent: PropTypes.string({ label: '地址名称', defaultValue: '' }), // 标签内容
  26 + zoomLevel: PropTypes.number({ label: '缩放层级', defaultValue: 12, visible: false }),
  27 + // https://lbs.qq.com/dev/console/key/manage
  28 + qqMapKey: PropTypes.string({
  29 + label: '腾讯地图Key',
  30 + defaultValue: 'GENBZ-G5S3J-7OLFW-FLBX4-WVEMK-SOBL4',
  31 + component: 'a-textarea',
  32 + extra: (h) => {
  33 + return <div>
  34 + <div>1. 请填入自己的腾讯地图开发密钥,<a href="https://lbs.qq.com/dev/console/key/manage" target="_blank">前往申请&gt;&gt;</a></div>
  35 + <div>2. 鲁班的 Demo Key 随时可能失效;失效提示: 鉴权失败,请传入正确的key</div>
  36 + </div>
  37 + }
  38 + }),
  39 + poi: {
  40 + type: Object,
  41 + default: () => ({
  42 + 'latLng': {
  43 + 'lat': 39.90469,
  44 + 'lng': 116.40717
  45 + },
  46 + 'name': '北京市',
  47 + 'type': 4
  48 + }),
  49 + editor: {
  50 + custom: true
  51 + }
  52 + }
  53 + },
  54 + watch: {
  55 + poi: {
  56 + handler (poi) {
  57 + if (!this.checkMapAvailable()) return
  58 + this.setMarker(poi)
  59 + },
  60 + deep: true
  61 + },
  62 + labelContent (labelContent) {
  63 + if (!this.checkMapAvailable()) return
  64 + this.setLabel(labelContent)
  65 + },
  66 + zoomLevel (zoomLevel) {
  67 + if (!this.checkMapAvailable()) return
  68 + this.setZoomLevel(zoomLevel)
  69 + }
  70 + },
  71 + methods: {
  72 + checkMapAvailable () {
  73 + return window.qq && window.qq.maps
  74 + },
  75 + onSearch (value) {
  76 + console.log(value)
  77 + },
  78 + setLabel (labelContent) {
  79 + const center = Map.getPosition(this.poi.latLng) // 地图的中心地理坐标
  80 + this.label = this.label || new window.qq.maps.Label({
  81 + position: center,
  82 + map: this.map,
  83 + content: ''
  84 + })
  85 + if (labelContent.trim()) {
  86 + // https://lbs.qq.com/webDemoCenter/javascriptV2/marker/label
  87 + this.label.setVisible(true)
  88 + this.label.setContent(labelContent || '')
  89 + this.label.setPosition(center)
  90 + } else {
  91 + this.label.setVisible(false)
  92 + }
  93 + },
  94 + setZoomLevel (zoomLevel) {
  95 + this.map.zoomTo(zoomLevel)
  96 + },
  97 + init () {
  98 + const { poi, qqMapKey } = this
  99 + this.loadMap(qqMapKey).then(qq => {
  100 + this.initMap(poi)
  101 + this.setLabel(this.labelContent)
  102 + this.setMarker(poi)
  103 + })
  104 + },
  105 + initMap (poi) {
  106 + const el = this.$refs.mapElement
  107 + const center = Map.getPosition(poi.latLng) // 地图的中心地理坐标
  108 + this.map = new window.qq.maps.Map(el, {
  109 + center,
  110 + zoom: this.zoomLevel, // 设置地图的缩放级别
  111 + disableDefaultUI: true, // 禁止所有控件
  112 + draggable: false, // 设置是否可以拖拽
  113 + scrollwheel: false, // 设置是否可以滚动
  114 + disableDoubleClickZoom: true // 设置是否可以双击放大
  115 + // 设置地图样式详情参见MapType
  116 + })
  117 + }
  118 + },
  119 + mounted () {
  120 + this.init()
  121 + }
  122 +}
  123 +</script>
front-end/h5/src/components/plugins/lbp-qq-map/src/mixin.js 0 → 100644
  1 +import Map from './Map'
  2 +
  3 +function getPosition ({ lat, lng }) {
  4 + return new window.qq.maps.LatLng(lat, lng) // 地图的中心地理坐标
  5 +}
  6 +
  7 +export default {
  8 + methods: {
  9 + loadMap (key) {
  10 + return Map.load(key)
  11 + },
  12 + setMarker (poi) {
  13 + const map = this.map
  14 + const center = getPosition(poi.latLng) // 地图的中心地理坐标
  15 + if (this.marker) {
  16 + this.marker.setMap(null)
  17 + this.marker = new window.qq.maps.Marker({ map, position: poi.latLng })
  18 + map.panTo(center)
  19 + } else {
  20 + this.marker = new window.qq.maps.Marker({ map, position: center })
  21 + }
  22 + }
  23 + }
  24 +}
front-end/h5/src/components/plugins/lbp-qq-map__editor.js 0 → 100644
  1 +import Map from './lbp-qq-map/src/Map'
  2 +import MapMixin from './lbp-qq-map/src/mixin'
  3 +
  4 +export default {
  5 + name: 'lbp-qq-map__editor',
  6 + mixins: [MapMixin], // loadMap、setMarker
  7 + props: {
  8 + // 地图的props 集合
  9 + elementProps: {
  10 + type: Object,
  11 + default: () => ({
  12 + labelContent: '',
  13 + zoomLevel: 12
  14 + })
  15 + }
  16 + },
  17 + methods: {
  18 + /**
  19 + * 更新组件的 poi prop
  20 + * @param {Object} poi 参考 lbp-qq-map 的 poi prop,用来表示坐标点信息
  21 + */
  22 + setPoi (poi) {
  23 + this.elementProps.poi = poi
  24 + },
  25 + // https://lbs.qq.com/webDemoCenter/javascriptV2/libraries/placeLibrary
  26 + initSearch () {
  27 + const self = this
  28 + let keyword = ''
  29 +
  30 + // 调用Poi检索类。用于进行本地检索、周边检索等服务。
  31 + const searchService = new window.qq.maps.SearchService({
  32 + complete: results => {
  33 + if (results.type === 'CITY_LIST') {
  34 + searchService.setLocation(results.detail.cities[0].cityName)
  35 + searchService.search(keyword)
  36 + return
  37 + }
  38 + const poi = results.detail.pois[0]
  39 + self.setMarker(poi)
  40 + self.setPoi(poi)
  41 + }
  42 + })
  43 + // 添加监听事件
  44 + const qqMapSearchElement = document.getElementById('editor__qq-map-search')
  45 + const ap = new window.qq.maps.place.Autocomplete(qqMapSearchElement)
  46 +
  47 + window.qq.maps.event.addListener(ap, 'confirm', function (res) {
  48 + keyword = res.value
  49 + searchService.search(keyword)
  50 + })
  51 + },
  52 + /**
  53 + * 监听地图 缩小/放大
  54 + */
  55 + listenZoom () {
  56 + window.qq.maps.event.addListener(this.map, 'zoom_changed', () => {
  57 + this.elementProps.zoomLevel = this.map.getZoom()
  58 + })
  59 + },
  60 + initMap (poi) {
  61 + const center = Map.getPosition(poi.latLng) // 地图的中心地理坐标
  62 + const el = document.getElementById('editor__qq-map-container')
  63 + this.map = new window.qq.maps.Map(el, {
  64 + center,
  65 + zoom: 8, // 设置地图的缩放级别
  66 + disableDefaultUI: true // 禁止所有控件
  67 + // 设置地图样式详情参见MapType
  68 + })
  69 + },
  70 + init () {
  71 + const { poi, qqMapKey } = this.elementProps
  72 + this.loadMap(qqMapKey).then(qq => {
  73 + this.initMap(poi)
  74 + this.setMarker(poi)
  75 + this.initSearch()
  76 + this.listenZoom()
  77 + })
  78 + }
  79 + },
  80 + mounted () {
  81 + this.init()
  82 + },
  83 + render () {
  84 + return (
  85 + <div style="margin: 12px;">
  86 + <input ref="search" id="editor__qq-map-search" placeholder="请输入地名" style="width: 100%;margin-bottom: 20px;" />
  87 + <div id="editor__qq-map-container" style="padding-bottom: 60%;width: 100%"></div>
  88 + </div>
  89 + )
  90 + }
  91 +}
front-end/h5/src/mixins/load-plugins.js
@@ -13,6 +13,7 @@ import LbpSlide from &#39;../components/plugins/lbp-slide&#39; @@ -13,6 +13,7 @@ import LbpSlide from &#39;../components/plugins/lbp-slide&#39;
13 import LbpBgMusic from '../components/plugins/lbp-bg-music' 13 import LbpBgMusic from '../components/plugins/lbp-bg-music'
14 import LbpNoticeBar from '../components/plugins/lbp-notice-bar' 14 import LbpNoticeBar from '../components/plugins/lbp-notice-bar'
15 import LbpRate from '../components/plugins/lbp-rate' 15 import LbpRate from '../components/plugins/lbp-rate'
  16 +import LbpQQMap from '../components/plugins/lbp-qq-map/src'
16 // import LbpTabs from '../components/plugins/lbp-tabs' 17 // import LbpTabs from '../components/plugins/lbp-tabs'
17 18
18 export const pluginsList = [ 19 export const pluginsList = [
@@ -101,10 +102,10 @@ export const pluginsList = [ @@ -101,10 +102,10 @@ export const pluginsList = [
101 }, 102 },
102 title: '地图', 103 title: '地图',
103 icon: 'map-o', 104 icon: 'map-o',
104 - component: LbpFormRadioGroup, 105 + component: LbpQQMap,
105 visible: true, 106 visible: true,
106 - name: LbpFormRadioGroup.name,  
107 - disabled: true 107 + name: LbpQQMap.name
  108 + // disabled: true
108 }, 109 },
109 { 110 {
110 i18nTitle: { 111 i18nTitle: {