178 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
			
		
		
	
	
			178 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Vue
		
	
	
	
	
	
| <template>
 | ||
|   <section class="locateDialog">
 | ||
|     <ai-dialog :visible.sync="dialog" title="标绘" @closed="$emit('visible',false),selected={}"
 | ||
|                @opened="$nextTick(()=>initMap())"
 | ||
|                @onConfirm="handleConfirm">
 | ||
|       <ai-t-map :map.sync="map" :lib.sync="TMap"/>
 | ||
|       <div class="poi">
 | ||
|         <el-autocomplete ref="poiInput" v-model="search" size="small" clearable :fetch-suggestions="handleSearch"
 | ||
|                          placeholder="请输入地点" @select="handleSelect" :trigger-on-focus="false">
 | ||
|           <template slot-scope="{item}">
 | ||
|             <span style="direction: rtl" v-text="`${item.title}(${item.address})`"/>
 | ||
|           </template>
 | ||
|         </el-autocomplete>
 | ||
|       </div>
 | ||
|       <el-form class="selected" v-if="!!selected.location" id="result" size="mini" label-suffix=":"
 | ||
|                label-position="left">
 | ||
|         <div class="header">
 | ||
|           <i class="iconfont iconLocation"/>
 | ||
|           <span v-html="[selected.location.lng, selected.location.lat].join(',')"/>
 | ||
|         </div>
 | ||
|         <el-form-item label="地点">{{ selected.name || "未知地名" }}</el-form-item>
 | ||
|         <el-form-item label="类型" v-if="!!selected.type">{{ selected.type }}</el-form-item>
 | ||
|         <el-form-item label="地址" v-if="!!selected.address">{{ selected.address }}</el-form-item>
 | ||
|       </el-form>
 | ||
|     </ai-dialog>
 | ||
|   </section>
 | ||
| </template>
 | ||
| 
 | ||
| <script>
 | ||
| import {mapState} from "vuex";
 | ||
| 
 | ||
| export default {
 | ||
|   name: "locateDialog",
 | ||
|   model: {
 | ||
|     prop: "visible",
 | ||
|     event: "visible",
 | ||
|   },
 | ||
|   props: ['latlng', 'visible'],
 | ||
|   data() {
 | ||
|     return {
 | ||
|       dialog: false,
 | ||
|       search: "",
 | ||
|       map: null,
 | ||
|       selected: {},
 | ||
|       TMap: null
 | ||
|     }
 | ||
|   },
 | ||
|   computed: {
 | ||
|     ...mapState(['user'])
 | ||
|   },
 | ||
|   watch: {
 | ||
|     visible(v) {
 | ||
|       this.dialog = v
 | ||
|     }
 | ||
|   },
 | ||
|   methods: {
 | ||
|     initMap(count = 0) {
 | ||
|       let {map, TMap} = this
 | ||
|       if (map) {
 | ||
|         if (!!this.latlng?.lat) {
 | ||
|           let position = new TMap.LatLng(this.latlng.lat, this.latlng.lng)
 | ||
|           map.setCenter(position)
 | ||
|           this.selected.marker = new TMap.MultiMarker({map, geometries: [{position}]})
 | ||
|         }
 | ||
|         map.on('click', res => {
 | ||
|           let {poi, latLng: location} = res, name = poi?.name || ""
 | ||
|           this.selected.marker?.setMap(null)
 | ||
|           this.selected = {location, name}
 | ||
|           this.selected.marker = new TMap.MultiMarker({map, geometries: [{position: location}]})
 | ||
|         })
 | ||
|       } else {
 | ||
|         if (count < 5) {
 | ||
|           count++
 | ||
|           setTimeout(() => this.initMap(count), 500)
 | ||
|         } else {
 | ||
|           console.error("地图渲染失败")
 | ||
|         }
 | ||
|       }
 | ||
|     },
 | ||
|     handleSearch(keyword, cb) {
 | ||
|       let {TMap} = this
 | ||
|       if (keyword && TMap) {
 | ||
|         let poi = new TMap.service.Search({pageSize: 10})
 | ||
|         poi.searchRegion({
 | ||
|           keyword, radius: 5000, cityName: this.user.info?.areaId?.substring(0, 6) || ""
 | ||
|         }).then(res => {
 | ||
|           if (res?.data?.length > 0) {
 | ||
|             cb(res.data)
 | ||
|           } else this.$message.error("未查到有效地点")
 | ||
|         })
 | ||
|       }
 | ||
|     },
 | ||
|     handleConfirm() {
 | ||
|       if (this.selected?.location) {
 | ||
|         this.$emit('confirm', this.selected)
 | ||
|       } else {
 | ||
|         this.$message.error('请先选择坐标位置')
 | ||
|       }
 | ||
|     },
 | ||
|     handleSelect(res) {
 | ||
|       let {map, TMap} = this
 | ||
|       if (map) {
 | ||
|         let {title: name, location} = res
 | ||
|         this.selected.marker?.setMap(null)
 | ||
|         this.selected = {location, name}
 | ||
|         this.selected.marker = new TMap.MultiMarker({map, geometries: [{position: location}]})
 | ||
|         map.setCenter(location)
 | ||
|       }
 | ||
|     }
 | ||
|   },
 | ||
|   created() {
 | ||
|     this.dialog = this.visible
 | ||
|   }
 | ||
| }
 | ||
| </script>
 | ||
| 
 | ||
| <style lang="scss" scoped>
 | ||
| .locateDialog {
 | ||
|   .color-999 {
 | ||
|     color: #999;
 | ||
|   }
 | ||
| 
 | ||
|   :deep( .el-dialog__body ){
 | ||
|     padding: 0;
 | ||
|     height: 480px;
 | ||
|     position: relative;
 | ||
| 
 | ||
|     .ai-dialog__content--wrapper {
 | ||
|       padding: 0 !important;
 | ||
|     }
 | ||
| 
 | ||
|     .poi {
 | ||
|       position: absolute;
 | ||
|       left: 10px;
 | ||
|       top: 10px;
 | ||
|       display: flex;
 | ||
|       height: 32px;
 | ||
|       flex-direction: column;
 | ||
|       z-index: 202203281016;
 | ||
|       width: 400px;
 | ||
| 
 | ||
|       div {
 | ||
|         flex-shrink: 0;
 | ||
|       }
 | ||
|     }
 | ||
| 
 | ||
|     .selected {
 | ||
|       position: absolute;
 | ||
|       right: 16px;
 | ||
|       top: 16px;
 | ||
|       background: #fff;
 | ||
|       min-width: 200px;
 | ||
|       box-sizing: border-box;
 | ||
|       box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
 | ||
| 
 | ||
|       .header {
 | ||
|         color: #fff;
 | ||
|         background: #26f;
 | ||
|         text-align: center;
 | ||
|         display: flex;
 | ||
|         align-items: center;
 | ||
|         height: 32px;
 | ||
|         font-size: 14px;
 | ||
|         gap: 4px;
 | ||
|         padding: 0 8px;
 | ||
|       }
 | ||
| 
 | ||
|       .el-form-item {
 | ||
|         padding: 0 8px;
 | ||
|         margin: 0;
 | ||
|       }
 | ||
|     }
 | ||
|   }
 | ||
| }
 | ||
| 
 | ||
| 
 | ||
| </style>
 |