Browse Source

修改地图弹窗组件

yuhongzhe
王泽彦 11 months ago
parent
commit
bda87b248b
  1. 1
      admin/auto-imports.d.ts
  2. 1
      admin/components.d.ts
  3. 15
      admin/src/app/views/campus/components/campus-edit.vue
  4. 94
      admin/src/components/TencentMapPicker.vue

1
admin/auto-imports.d.ts

@ -1,5 +1,6 @@
// Generated by 'unplugin-auto-import'
export {}
declare global {
const ElMessage: typeof import('element-plus/es')['ElMessage']
const ElNotification: typeof import('element-plus/es')['ElNotification']
}

1
admin/components.d.ts

@ -21,6 +21,7 @@ declare module '@vue/runtime-core' {
ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDialog: typeof import('element-plus/es')['ElDialog']
ElDrawer: typeof import('element-plus/es')['ElDrawer']
ElDropdown: typeof import('element-plus/es')['ElDropdown']

15
admin/src/app/views/campus/components/campus-edit.vue

@ -37,7 +37,14 @@
</el-form-item>
<el-form-item :label="t('campusCoordinates')">
<TencentMapPicker v-model="formData.campus_coordinates" />
<el-button @click="showMapPicker">{{
t('campusCoordinatesPlaceholder')
}}</el-button>
<TencentMapPicker
ref="mapPickerRef"
v-model="formData.campus_coordinates"
v-model:visible="showMapPickerVisible"
/>
</el-form-item>
<el-form-item :label="t('campusIntroduction')">
@ -99,7 +106,11 @@ const initialFormData = {
const formData: Record<string, any> = reactive({ ...initialFormData })
const formRef = ref<FormInstance>()
const mapPickerRef = ref()
const showMapPickerVisible = ref(false)
const showMapPicker = () => {
showMapPickerVisible.value = true
}
//
const formRules = computed(() => {
return {

94
admin/src/components/TencentMapPicker.vue

@ -4,9 +4,18 @@
:title="t('mapPickerTitle')"
width="800px"
:before-close="handleClose"
:close-on-click-modal="false"
:close-on-press-escape="false"
:show-close="false"
>
<div class="map-container" id="container"></div>
<div class="map-container" id="container">
<div
v-if="!props.modelValue.lat || !props.modelValue.lng"
class="map-placeholder"
>
{{ props.placeholder }}
</div>
</div>
<div class="address-search">
<el-select
v-model="province"
@ -50,7 +59,12 @@
v-model="detailAddress"
:placeholder="t('detailAddressPlaceholder')"
/>
<el-button type="primary" @click="handleAddressSearch">{{ t('search') }}</el-button>
<el-button
type="primary"
@click="handleAddressSearch"
:disabled="!province || !city || !district"
>{{ t('search') }}</el-button
>
</div>
<template #footer>
<span class="dialog-footer">
@ -64,7 +78,7 @@
</template>
<script lang="ts" setup>
import { ref, onMounted, watch } from 'vue'
import { ref, onMounted, watch, computed } from 'vue'
import { getAreaListByPid, getAreaByCode } from '@/app/api/sys'
import { createMarker, latLngToAddress, addressToLatLng } from '@/utils/qqmap'
import { t } from '@/lang'
@ -78,21 +92,44 @@ const props = defineProps({
address: '',
}),
},
placeholder: {
type: String,
default: t('mapPickerPlaceholder'),
},
visible: {
type: Boolean,
default: false,
},
})
const emit = defineEmits(['update:modelValue', 'confirm'])
const emit = defineEmits(['update:visible', 'update:modelValue', 'confirm'])
const dialogVisible = ref(false)
const dialogVisible = computed({
get() {
return props.visible
},
set(value) {
emit('update:visible', value)
}
})
watch(dialogVisible, (newVal) => {
emit('update:modelValue', newVal)
})
const handleClose = (done: () => void) => {
done()
}
const handleConfirm = () => {
if (!props.modelValue.lat || !props.modelValue.lng) {
ElMessage.warning(t('mapPickerWarning'))
return
}
emit('confirm', {
lat: props.modelValue.lat,
lng: props.modelValue.lng,
address: detailAddress.value
address: detailAddress.value,
})
dialogVisible.value = false
}
@ -112,8 +149,11 @@ const cityList = ref<any[]>([])
const districtList = ref<any[]>([])
//
onMounted(() => {
const mapScript = document.createElement('script')
const initMapScript = () => {
const container = document.getElementById('container')
if (!container) return
mapScript = document.createElement('script')
mapKey.value = 'IZQBZ-3UHEU-WTCVD-2464U-I5N4V-ZFFU3'
mapScript.type = 'text/javascript'
mapScript.src =
@ -125,13 +165,35 @@ onMounted(() => {
}, 500)
}
//
mapScript.onerror = (error) => {
console.error('地图脚本加载失败:', error)
}
}
let mapScript: HTMLScriptElement | null = null
watch(dialogVisible, (newVal) => {
if (newVal) {
if (mapScript) {
document.body.removeChild(mapScript)
mapScript = null
}
initMapScript()
getAreaListByPid(0).then((res) => {
provinceList.value = res.data
})
})
} else {
if (mapScript) {
document.body.removeChild(mapScript)
mapScript = null
}
map = null
marker = null
}
}, { immediate: true })
const initMap = () => {
console.log('initMap')
const TMap = (window as any).TMap
const center = new TMap.LatLng(39.90403, 116.407526)
map = new TMap.Map('container', {
@ -239,6 +301,16 @@ watch(
height: 400px;
border: 1px solid #dcdfe6;
border-radius: 4px;
position: relative;
}
.map-placeholder {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
color: #909399;
font-size: 14px;
}
.address-search {

Loading…
Cancel
Save