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>
|