zjk
2026-02-09 5467ab10a5ace3f6ed66573213db97d77c97ae5b
feat: 添加地图key配置
2个文件已修改
297 ■■■■■ 已修改文件
.env 3 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/views/operationsManagement/geofenceManagement/detail.vue 294 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
.env
@@ -25,3 +25,6 @@
# 默认多语言 enUS | zhCN
VITE_DEFAULT_LANG = zhCN
# 地图Key
VITE_MAP_KEY = 85e62187c6f8e51c797c87b1f36f787a
src/views/operationsManagement/geofenceManagement/detail.vue
@@ -1,147 +1,126 @@
<script setup lang="tsx">
import { ref, onMounted } from 'vue'
import { useScriptTag } from '@vueuse/core'
import { NButton, NSpace, NTag } from 'naive-ui'
import { NButton, NSpace, useMessage } from 'naive-ui'
// 添加更好的错误处理和调试
const { load } = useScriptTag('https://webapi.amap.com/maps?v=2.0&key=85e62187c6f8e51c797c87b1f36f787a')
const message = useMessage()
const domRef = ref<HTMLDivElement>()
const map = ref(null)
const mapError = ref('')
const { VITE_MAP_KEY } = import.meta.env
const formDefault: any = {
  name: '',
  remark: '',
  effectiveTime: 1,
  expireTime: 1,
  effectiveTimeTimestamp: null,
  expireTimeTimestamp: null
}
const formModel = ref({ ...formDefault })
const groupList = ref<any[]>([
  {
    name: `策略组1`,
    type: 1,
    timeList: [],
    edit: false,
    customTime: [],
    id: 1
  }
])
const { load } = useScriptTag(
  `https://webapi.amap.com/maps?v=2.0&key=${VITE_MAP_KEY}`
)
const showDrawer = ref(true)
const domRef = ref<HTMLDivElement | null>(null)
const map = ref<any>(null)
const rules = {
  name: {
    required: true,
    message: '请输入围栏名称',
    trigger: 'blur',
  },
}
// ==================== 电子围栏相关 ====================
const maxPoint = 16
const fencePath = ref<any[]>([])
const fencePolygon = ref<any>(null)
let drawing = false
const dateOptions = [
  {
    label: '工作日',
    value: 1,
  },
  {
    label: '非工作日',
    value: 2,
  },
  {
    label: '法定节假日',
    value: 3,
  },
  {
    label: '自定义',
    value: 4,
  }
]
const weekOptions = [
  {
    label: '周一',
    value: 1,
  },
  {
    label: '周二',
    value: 2,
  },
  {
    label: '周三',
    value: 3,
  },
  {
    label: '周四',
    value: 4,
  },
  {
    label: '周五',
    value: 5,
  },
  {
    label: '周六',
    value: 6,
  },
  {
    label: '周日',
    value: 7,
  },
]
const addStrategyGroup = () => {
  groupList.value.push({
    name: `策略组${groupList.value.length + 1}`,
    type: 1,
    timeList: [],
    edit: false,
    customTime: [],
    id: groupList.value.length + 1
  })
}
const addTimeRange = (item: any) => {
  console.log(item)
  groupList.value.forEach((group) => {
    if (group.id === item.id) {
      group.timeList.push({
        startTime: 0,
        endTime: 0,
        id: group.timeList.length + 1
      })
    }
  })
}
const removeTimePeriod = (item: any) => {
  groupList.value.forEach((group) => {
    if (group.id === item.id) {
      group.timeList = group.timeList.filter((sub: any) => sub.id !== item.id)
    }
  })
}
// ==================== 初始化地图 ====================
async function initMap() {
  try {
    if (!domRef.value) {
      return
    }
    await load()
    if (typeof AMap === 'undefined') {
      console.error('AMap未定义')
      return
    }
    map.value = new AMap.Map(domRef.value, {
      zoom: 10,
      center: [113.264499, 23.130061],
      mapStyle: 'amap://styles/yuanshandai'
    })
  if (!domRef.value) return
    console.log('地图初始化成功:', map.value)
  } catch (err) {
    mapError.value = '地图初始化失败: ' + (err as Error).message
    console.error('地图初始化错误:', err)
  await load()
  if (typeof (window as any).AMap === 'undefined') {
    message.error('AMap 加载失败')
    return
  }
  map.value = new AMap.Map(domRef.value, {
    zoom: 11,
    center: [113.264499, 23.130061],
    mapStyle: 'amap://styles/whitesmoke'
  })
  // 禁用双击缩放(否则会和闭合冲突)
  map.value.setStatus({ doubleClickZoom: false })
  console.log('地图初始化成功')
}
// ==================== 开始绘制围栏 ====================
const startDrawFence = () => {
  if (!map.value) return
  clearFence()
  fencePath.value = []
  drawing = true
  message.info('单击添加顶点,双击完成绘制(最多16个点)')
  map.value.on('click', onMapClick)
  map.value.on('dblclick', onMapDblClick)
}
// ==================== 单击加点 ====================
const onMapClick = (e: any) => {
  if (!drawing) return
  if (fencePath.value.length >= maxPoint) {
    message.warning('单个围栏最多支持 16 个顶点')
    return
  }
  fencePath.value.push(e.lnglat)
  drawPreview()
}
// ==================== 双击闭合 ====================
const onMapDblClick = (e: any) => {
  e.preventDefault()
  if (fencePath.value.length < 3) {
    message.error('至少需要 3 个点才能形成围栏')
    return
  }
  finishDrawFence()
}
// ==================== 实时预览 ====================
const drawPreview = () => {
  if (fencePolygon.value) {
    map.value.remove(fencePolygon.value)
  }
  fencePolygon.value = new AMap.Polygon({
    path: fencePath.value,
    strokeColor: '#0068FF',
    strokeWeight: 2,
    fillColor: '#0068FF',
    fillOpacity: 0.3
  })
  map.value.add(fencePolygon.value)
}
// ==================== 完成绘制 ====================
const finishDrawFence = () => {
  drawing = false
  map.value.off('click', onMapClick)
  map.value.off('dblclick', onMapDblClick)
  message.success('电子围栏绘制完成')
  // 这里就是最终围栏坐标(可直接给后端)
  console.log(
    '围栏坐标:',
    fencePath.value.map((p) => [p.lng, p.lat])
  )
}
// ==================== 清除围栏 ====================
const clearFence = () => {
  if (fencePolygon.value) {
    map.value.remove(fencePolygon.value)
    fencePolygon.value = null
  }
}
@@ -151,13 +130,42 @@
</script>
<template>
  <div class="w-full h-full">
    <!-- 地图区域 -->
    <div class="w-full h-[60%]" id="mapBox">
      <div id="map" ref="domRef" class="w-full h-full" style="position: relative;" />
  <div class="w-full h-full" style="position: relative">
    <!-- 地图容器 -->
    <div ref="domRef" class="w-full h-full" />
    <!-- 提示 -->
    <div class="tips">
      请在地图上【非运营区域】绘制多边形区域,双击闭合
    </div>
  </div>
</template>
    <div class="flex-1 info">
<style lang="scss" scoped>
.tips {
  position: absolute;
  top: 24px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 99;
  padding: 7px 16px;
  border-radius: 100px;
  background: #171F26;
  font-family: PingFang SC;
  font-size: 13px;
  font-weight: normal;
  line-height: 18px;
  letter-spacing: normal;
  color: #FFFFFF;
}
</style>
<style lang="scss">
.robotaxi-content {
  padding: 0 !important;
}
</style>
<!-- <div class="flex-1 info">
      <div class="text-[16px] font-bold my-4">新建围栏</div>
      <n-card :segmented="{
        content: true,
@@ -261,12 +269,4 @@
          </n-tabs>
        </n-form>
      </n-card>
    </div>
  </div>
</template>
<style lang="scss">
.robotaxi-content {
  padding: 0 !important;
}
</style>
    </div> -->