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. 100
      admin/src/components/TencentMapPicker.vue

1
admin/auto-imports.d.ts

@ -1,5 +1,6 @@
// Generated by 'unplugin-auto-import' // Generated by 'unplugin-auto-import'
export {} export {}
declare global { declare global {
const ElMessage: typeof import('element-plus/es')['ElMessage']
const ElNotification: typeof import('element-plus/es')['ElNotification'] 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'] ElColorPicker: typeof import('element-plus/es')['ElColorPicker']
ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider'] ElConfigProvider: typeof import('element-plus/es')['ElConfigProvider']
ElContainer: typeof import('element-plus/es')['ElContainer'] ElContainer: typeof import('element-plus/es')['ElContainer']
ElDatePicker: typeof import('element-plus/es')['ElDatePicker']
ElDialog: typeof import('element-plus/es')['ElDialog'] ElDialog: typeof import('element-plus/es')['ElDialog']
ElDrawer: typeof import('element-plus/es')['ElDrawer'] ElDrawer: typeof import('element-plus/es')['ElDrawer']
ElDropdown: typeof import('element-plus/es')['ElDropdown'] 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>
<el-form-item :label="t('campusCoordinates')"> <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>
<el-form-item :label="t('campusIntroduction')"> <el-form-item :label="t('campusIntroduction')">
@ -99,7 +106,11 @@ const initialFormData = {
const formData: Record<string, any> = reactive({ ...initialFormData }) const formData: Record<string, any> = reactive({ ...initialFormData })
const formRef = ref<FormInstance>() const formRef = ref<FormInstance>()
const mapPickerRef = ref()
const showMapPickerVisible = ref(false)
const showMapPicker = () => {
showMapPickerVisible.value = true
}
// //
const formRules = computed(() => { const formRules = computed(() => {
return { return {

100
admin/src/components/TencentMapPicker.vue

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

Loading…
Cancel
Save