com-qq-map.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257
  1. <?php
  2. $config = Yii::$app->services->setting->platform->get('map');
  3. $key = $config['qq_jsapi_key'] ? $config['qq_jsapi_key'] : '2DZBZ-34CWX-5CH45-7TY7A-FNPAJ-SIBDC';
  4. ?>
  5. <template id="com-qq-map">
  6. <div class="com-qq-map">
  7. <el-dialog
  8. :title="title ? title : '地图展示'"
  9. :visible.sync="dialogVisible"
  10. @opened="dialogOpened"
  11. @close="closeDialog"
  12. :close-on-click-modal="false"
  13. :append-to-body="appendToBody"
  14. >
  15. <el-form label-width="80px" size="small">
  16. <el-row>
  17. <el-col :span="12">
  18. <el-form-item label="地址搜索">
  19. <el-input placeholder="请输入具体地址(地址需要精准到门牌号)" v-model="mapKeyword">
  20. <el-button @keyup.enter.native="mapSearch" :loading="searchLoading" @click="mapSearch" slot="append"
  21. icon="el-icon-search"></el-button>
  22. </el-input>
  23. </el-form-item>
  24. </el-col>
  25. </el-row>
  26. <el-row>
  27. <el-col :span="12">
  28. <el-form-item label="地址">
  29. <el-input disabled v-model="newAddress"></el-input>
  30. </el-form-item>
  31. </el-col>
  32. <el-col :span="12">
  33. <el-form-item label="纬度|经度">
  34. <el-input disabled v-model="lat_long"></el-input>
  35. </el-form-item>
  36. </el-col>
  37. </el-row>
  38. </el-form>
  39. <div class="com-qq-map" id="container" :style="style"></div>
  40. <div slot="footer" class="dialog-footer">
  41. <el-button type="primary" plain :loading="confirmLoading" @click="confirm">确认地址</el-button>
  42. <el-button type="primary" @click="submit">提 交</el-button>
  43. </div>
  44. </el-dialog>
  45. <div @click="dialogVisible = !dialogVisible" style="display: inline-block">
  46. <slot></slot>
  47. </div>
  48. </div>
  49. </template>
  50. <script charset="utf-8" src="https://map.qq.com/api/gljs?v=1.exp&key=<?php echo $key;?>"></script>
  51. <script>
  52. Vue.component('com-qq-map', {
  53. template: '#com-qq-map',
  54. props: {
  55. width: String,
  56. height: String,
  57. lat: [String, Number],
  58. long: [String, Number],
  59. address: {
  60. type: String,
  61. default: '',
  62. },
  63. title: String,
  64. appendToBody: {
  65. type: Boolean,
  66. default: false,
  67. },
  68. },
  69. data() {
  70. return {
  71. longitude: 116.40717, // 经度(大)默认北京
  72. latitude: 39.90469,// 纬度(小)默认北京
  73. lat_long: '',
  74. mapService: {},// 地图服务
  75. markerLayer: {},// 地图标注
  76. mapKeyword: '',
  77. dialogVisible: false,
  78. newAddress: '',
  79. address_component: '',
  80. confirmLoading: false,
  81. searchLoading: false,
  82. data: {},
  83. };
  84. },
  85. created() {
  86. },
  87. computed: {
  88. style() {
  89. let width = '100%';
  90. let height = '400px';
  91. if (this.width) {
  92. width = this.width + (isNaN(this.width) ? '' : 'px');
  93. }
  94. if (this.height) {
  95. height = this.height + (isNaN(this.height) ? '' : 'px');
  96. }
  97. return `width:${width};height:${height};`;
  98. },
  99. },
  100. methods: {
  101. dialogOpened() {
  102. console.log(this.lat,this.long,this.address,'=======')
  103. this.initMap();
  104. },
  105. // 初始化地图
  106. initMap() {
  107. let self = this;
  108. if (self.lat && self.long) {
  109. self.latitude = parseFloat(self.lat).toFixed(6);
  110. self.longitude = parseFloat(self.long).toFixed(6);
  111. self.lat_long = self.latitude + ',' + self.longitude
  112. }
  113. if (self.address) self.mapKeyword = self.address.replace(/\//g,'');
  114. //定义地图中心点坐标
  115. let center = new TMap.LatLng(self.latitude, self.longitude);
  116. //定义map变量,调用 TMap.Map() 构造函数创建地图
  117. self.mapService = new TMap.Map(document.getElementById('container'), {
  118. center: center,//设置地图中心点坐标
  119. zoom: 17.2, //设置地图缩放级别
  120. offset: { // 中心点偏移
  121. x: 0,
  122. y: 0,
  123. }
  124. });
  125. var markerGeo = {
  126. id: 'center',
  127. position: self.mapService.getCenter(),
  128. };
  129. // 创建一个位于地图中心点的marker
  130. let markerLayer = new TMap.MultiMarker({
  131. map: self.mapService,
  132. geometries: [
  133. markerGeo
  134. ]
  135. });
  136. // 监听中心点变化事件,更新marker的位置
  137. self.mapService.on('center_changed', () => {
  138. markerGeo.position = this.mapService.getCenter();
  139. let lat = markerGeo.position.lat.toFixed(6);
  140. let lng = markerGeo.position.lng.toFixed(6);
  141. self.lat_long = lat + ',' + lng
  142. self.longitude = lng
  143. self.latitude = lat
  144. markerLayer.updateGeometries([markerGeo]);
  145. });
  146. },
  147. // 地址搜索
  148. mapSearch() {
  149. if (isEmpty(this.mapKeyword)) {
  150. alert("请输入详细地址");
  151. return false;
  152. }
  153. this.searchLoading = true;
  154. request({
  155. params: {
  156. r: 'common/qq-map/geocoder',
  157. },
  158. data: {
  159. address: this.mapKeyword
  160. },
  161. method: 'post'
  162. }).then(e => {
  163. if (e.data.code === 0) {
  164. let data = e.data.data;
  165. this.longitude = data.location.lng; // 经度(大)
  166. this.latitude = data.location.lat;// 纬度(小)
  167. // this.newAddress = data.address_components.province + data.address_components.city + data.address_components.district + data.title;
  168. // 修改地图中心点
  169. this.mapService.setCenter(new TMap.LatLng(this.latitude,this.longitude));
  170. this.searchLoading = false;
  171. } else {
  172. this.$message({
  173. message: e.data.msg,
  174. type: 'error'
  175. });
  176. this.searchLoading = false;
  177. }
  178. }).catch(e => {
  179. this.$message({
  180. message: '请求详细地址报错',
  181. type: 'error'
  182. });
  183. this.searchLoading = false;
  184. });
  185. },
  186. // 确认地址
  187. confirm() {
  188. this.confirmLoading = true;
  189. if (isEmpty(this.longitude) || isEmpty(this.latitude)) {
  190. alert("经纬度不能为空");
  191. return false;
  192. }
  193. request({
  194. params: {
  195. r: 'common/qq-map/reverse-geocoder',
  196. },
  197. data: {
  198. longitude: this.longitude,
  199. latitude: this.latitude
  200. },
  201. method: 'post'
  202. }).then(e => {
  203. if (e.data.code === 0) {
  204. this.confirmLoading = false;
  205. let data = e.data.data;
  206. this.data = data
  207. this.longitude = data.location.lng; // 经度(大)
  208. this.latitude = data.location.lat;// 纬度(小)
  209. console.log(data,'确认地址')
  210. this.newAddress = data.formatted_addresses.standard_address;
  211. this.address_component = data.address_component;
  212. this.$message({
  213. message: '获取地址”'+ data.formatted_addresses.standard_address +'“成功',
  214. type: 'success'
  215. });
  216. } else {
  217. this.$message({
  218. message: e.data.msg,
  219. type: 'error'
  220. });
  221. this.confirmLoading = false;
  222. }
  223. }).catch(e => {
  224. this.$message({
  225. message: '确认地址请求报错',
  226. type: 'error'
  227. });
  228. this.confirmLoading = false;
  229. });
  230. },
  231. submit() {
  232. if (isEmpty(this.newAddress)) {
  233. alert("请点击确认地址按钮");
  234. return false;
  235. }
  236. this.$emit('map-submit', {...this.data, ...{
  237. lat: this.latitude,
  238. long: this.longitude,
  239. address: this.newAddress,
  240. address_component: this.address_component,
  241. }});
  242. this.dialogVisible = false;
  243. this.closeDialog();
  244. },
  245. closeDialog() {
  246. this.mapService.destroy();
  247. }
  248. },
  249. });
  250. </script>