This commit is contained in:
guochunsi
2026-01-19 18:01:21 +08:00
parent 083d9d5c13
commit 0063894c8e
8 changed files with 373 additions and 96 deletions

View File

@@ -4,22 +4,19 @@
append-to-body
:close-on-click-modal="false"
v-model="visible"
width="800">
width="90%">
<div>
<el-form :model="form" :rules="rules" ref="formRef" label-width="120px"
class="demo-ruleForm">
<el-form :model="form" :rules="rules" ref="formRef" class="demo-ruleForm">
<el-form-item label="住宿半径(米)" prop="raidus">
<el-input-number v-model="form.raidus" :min="0" style="width: 100%"></el-input-number>
</el-form-item>
</el-form>
<div id="container"></div>
</div>
<template #footer>
<div class="dialog-footer">
<el-button type="primary" @click="dataFormSubmit">确定</el-button>
<el-button @click="visible = false">取消</el-button>
<el-button type="primary" @click="dataFormSubmit">确定</el-button>
</div>
</template>
</el-dialog>
@@ -28,9 +25,10 @@
<script setup lang="ts">
import { ref, reactive, watch, nextTick } from 'vue'
import { useMessage, useMessageBox } from '/@/hooks/message'
import { BMPGL } from "@/api/recruit/recruitstudentsignup"
import { putItemObj } from "@/api/admin/dict"
import { getTypeValue } from "@/api/admin/dict"
import { loadTiandituMap } from "/@/api/recruit/recruitstudentsignup"
import { putItemObj } from "/@/api/admin/dict"
import { getDicts } from "/@/api/admin/dict"
import { TIANDITU_TOKEN } from '/@/config/map'
// 消息提示 hooks
const message = useMessage()
@@ -40,17 +38,16 @@ const messageBox = useMessageBox()
const formRef = ref()
// 响应式数据
const ak = "V0ooaf2RZyEGOkD8UzZB3gvw7pCb0Kx7" // 百度的地图密钥
const tk = TIANDITU_TOKEN // 天地图的token在 src/config/map.ts 中配置)
const visible = ref(false)
const canSubmit = ref(false)
const circleShow = ref(false)
const circle = ref<any>(null)
const map = ref<any>(null)
// 地址信息
const address = ref(null)
const center = reactive({ lng: 0, lat: 0 })
const dictId = ref("")
const circleArr = ref<any[]>([])
const form = reactive({
raidus: 0,
@@ -64,8 +61,39 @@ const rules = {
// 监听半径变化
watch(() => form.raidus, (newVal) => {
if (newVal != '' && newVal != undefined && circle.value) {
circle.value.setRadius(newVal) // 设置圆形覆盖物的半径
if (newVal !== 0 && newVal !== undefined && circle.value && map.value) {
// 移除旧圆形
map.value.removeOverLay(circle.value)
// 创建新圆形(确保数据类型正确)
// @ts-ignore
const newCircle = new window.T.Circle(
// @ts-ignore
new window.T.LngLat(
// @ts-ignore
parseFloat(center.lng),
// @ts-ignore
parseFloat(center.lat)
),
// @ts-ignore
parseFloat(newVal), // 确保半径是数字类型
{
color: '#FF0000', // 边框颜色:鲜红色
weight: 4, // 边框粗细4像素
opacity: 0.9, // 边框不透明度90%
fillColor: '#FF4444', // 填充颜色:亮红色
fillOpacity: 0.12 // 填充透明度12%
}
)
map.value.addOverLay(newCircle)
circle.value = newCircle
// 让新圆形也不拦截鼠标事件
setTimeout(() => {
const circleElements = document.querySelectorAll('.tdt-circle, [class*="circle"]')
circleElements.forEach((el: any) => {
el.style.pointerEvents = 'none'
})
}, 100)
}
})
@@ -75,7 +103,7 @@ const init = () => {
canSubmit.value = true
circleShow.value = true
nextTick(() => {
getTypeValue("dorm_jw").then((data: any) => {
getDicts("dorm_jw").then((data: any) => {
const arr = data.data
arr.forEach((e: any) => {
if (e.label == 'bj') {
@@ -87,25 +115,101 @@ const init = () => {
center.lat = e.value
}
})
BMPGL(ak).then((BMapGL: any) => {
// 创建地图实例
const map = new BMapGL.Map("container")
// 创建点坐标
const point = new BMapGL.Point(center.lng, center.lat)
// 初始化地图,设置中心点坐标和地图级别
map.centerAndZoom(point, 13)
// 开启鼠标滚轮缩放
map.enableScrollWheelZoom(true)
// 绘制圆
circle.value = new BMapGL.Circle(new BMapGL.Point(center.lng, center.lat), form.raidus, {
strokeColor: 'blue',
strokeWeight: 2,
strokeOpacity: 0.5,
enableEditing: false
// 等待对话框渲染完成后再加载地图
setTimeout(() => {
// 调试信息:打印配置数据
// eslint-disable-next-line no-console
console.log('地图配置:', { lng: center.lng, lat: center.lat, radius: form.raidus, token: tk })
loadTiandituMap(tk).then((T: any) => {
// eslint-disable-next-line no-console
console.log('天地图API加载成功', T)
// 清除之前的地图实例(如果存在)
if (map.value) {
map.value.clearOverLays()
}
// 创建地图实例
map.value = new T.Map("container")
// 创建点坐标(确保经纬度是数字类型)
// @ts-ignore
const point = new T.LngLat(
// @ts-ignore
parseFloat(center.lng),
// @ts-ignore
parseFloat(center.lat)
)
// 根据半径自动计算合适的缩放级别
// @ts-ignore
const radius = parseFloat(form.raidus)
let zoomLevel = 12 // 默认缩放级别
// 根据半径动态调整缩放级别
if (radius <= 1000) {
zoomLevel = 15 // 1公里以内 - 非常近
} else if (radius <= 3000) {
zoomLevel = 14 // 3公里以内 - 近距离
} else if (radius <= 5000) {
zoomLevel = 13 // 5公里以内 - 中等距离
} else if (radius <= 10000) {
zoomLevel = 12 // 10公里以内 - 较远
} else if (radius <= 20000) {
zoomLevel = 11 // 20公里以内 - 远距离
} else {
zoomLevel = 10 // 20公里以上 - 超远距离
}
// 初始化地图,设置中心点坐标和地图级别
map.value.centerAndZoom(point, zoomLevel)
// eslint-disable-next-line no-console
console.log('地图缩放级别:', zoomLevel, '(半径:', radius, '米)')
// 添加地图类型切换控件(让用户可以切换卫星图/普通图)
const ctrl = new T.Control.MapType()
map.value.addControl(ctrl)
// 默认使用矢量地图(普通地图),用户可通过右上角控件切换到卫星图
// 绘制圆形覆盖物(使用前面已计算好的 radius 变量)
// eslint-disable-next-line no-console
console.log('绘制圆形:', { center: point, radius: radius, radiusType: typeof radius })
circle.value = new T.Circle(point, radius, {
color: '#FF0000', // 边框颜色:鲜红色,更醒目
weight: 4, // 边框粗细4像素更明显
opacity: 0.9, // 边框不透明度90%,清晰可见
fillColor: '#FF4444', // 填充颜色:亮红色
fillOpacity: 0.12 // 填充透明度12%,轻盈不遮挡地图
})
map.value.addOverLay(circle.value)
// 让圆形不拦截鼠标事件,使地图可以在圆圈内拖拽
// 通过 CSS 设置 pointer-events 为 none
setTimeout(() => {
const circleElements = document.querySelectorAll('.tdt-circle, [class*="circle"]')
circleElements.forEach((el: any) => {
el.style.pointerEvents = 'none'
})
}, 100)
// 添加中心点标记(更明显地标识中心位置)
const marker = new T.Marker(point)
map.value.addOverLay(marker)
// eslint-disable-next-line no-console
console.log('地图初始化完成 - 圆形已添加')
}).catch((error: any) => {
// eslint-disable-next-line no-console
console.error('天地图加载失败:', error)
message.error('地图加载失败请检查网络连接或Token配置')
})
map.addOverlay(circle.value)
})
}, 200)
}).catch(() => {
message.error('获取地图配置失败')
})
})
}
@@ -141,9 +245,10 @@ defineExpose({
#container {
overflow: hidden;
width: 100%;
height: 500px;
height: 700px;
margin: 0;
font-family: "微软雅黑";
margin-top: 15px;
}
ul li {
@@ -154,3 +259,19 @@ ul li {
text-align: right;
}
</style>
<style>
/* 让地图上的圆形覆盖物不拦截鼠标事件,使地图可以拖拽 */
#container svg path[fill*="#FF"],
#container svg path[stroke*="#FF"],
#container svg circle,
#container canvas {
pointer-events: none !important;
}
/* 但保持标记点可点击 */
#container .tdt-marker,
#container img {
pointer-events: auto !important;
}
</style>